summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSusant Sahani <ssahani@users.noreply.github.com>2016-04-14 15:26:57 +0530
committerLennart Poettering <lennart@poettering.net>2016-04-14 11:56:57 +0200
commit23d8b221c0490b1b00044072b329d3ab76d561e3 (patch)
tree78f31ab64f3f7f58c82ca94cfc19c1634957e902
parentd29030e593d19d3660ab425f0ff3d5cb025aa439 (diff)
downloadsystemd-23d8b221c0490b1b00044072b329d3ab76d561e3.tar.gz
networkd: Add support to configure proxy arp support to interfaces (#3020)
Fixes: #2889
-rw-r--r--man/systemd.network.xml11
-rw-r--r--src/network/networkd-link.c35
-rw-r--r--src/network/networkd-network-gperf.gperf1
-rw-r--r--src/network/networkd-network.c1
-rw-r--r--src/network/networkd-network.h1
5 files changed, 48 insertions, 1 deletions
diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index c9ef041004..d7947836e9 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -549,6 +549,15 @@
</para></listitem>
</varlistentry>
<varlistentry>
+ <term><varname>ProxyARP=</varname></term>
+ <listitem><para>A boolean. Configures proxy ARP. Proxy ARP is the technique in which one host,
+ usually a router, answers ARP requests intended for another machine. By "faking" its identity,
+ the router accepts responsibility for routing packets to the "real" destination. (see <ulink
+ url="https://tools.ietf.org/html/rfc1027">RFC 1027</ulink>.
+ Defaults to unset.
+ </para></listitem>
+ </varlistentry>
+ <varlistentry>
<term><varname>Bridge=</varname></term>
<listitem>
<para>The name of the bridge to add the link to.</para>
@@ -844,7 +853,7 @@
global DUID that may be specified in <citerefentry><refentrytitle>networkd.conf
</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
- <para>The configured DHCP DUID should conform to the specification in
+ <para>The configured DHCP DUID should conform to the specification in
<ulink url="http://tools.ietf.org/html/rfc3315#section-9">RFC 3315</ulink>,
<ulink url="http://tools.ietf.org/html/rfc6355">RFC 6355</ulink>.</para>
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 88b3cbe90a..9059a68fe3 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -165,6 +165,21 @@ static bool link_ipv6_forward_enabled(Link *link) {
return link->network->ip_forward & ADDRESS_FAMILY_IPV6;
}
+static bool link_proxy_arp_enabled(Link *link) {
+ assert(link);
+
+ if (link->flags & IFF_LOOPBACK)
+ return false;
+
+ if (!link->network)
+ return false;
+
+ if (link->network->proxy_arp < 0)
+ return false;
+
+ return true;
+}
+
static bool link_ipv6_accept_ra_enabled(Link *link) {
assert(link);
@@ -1039,6 +1054,22 @@ static int link_set_bridge_fdb(Link *const link) {
return r;
}
+static int link_set_proxy_arp(Link *const link) {
+ const char *p = NULL;
+ int r;
+
+ if (!link_proxy_arp_enabled(link))
+ return 0;
+
+ p = strjoina("/proc/sys/net/ipv4/conf/", link->ifname, "/proxy_arp");
+
+ r = write_string_file(p, one_zero(link->network->proxy_arp), WRITE_STRING_FILE_VERIFY_ON_FAILURE);
+ if (r < 0)
+ log_link_warning_errno(link, r, "Cannot configure proxy ARP for interface: %m");
+
+ return 0;
+}
+
static int link_set_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
_cleanup_link_unref_ Link *link = userdata;
int r;
@@ -2167,6 +2198,10 @@ static int link_configure(Link *link) {
if (r < 0)
return r;
+ r = link_set_proxy_arp(link);
+ if (r < 0)
+ return r;
+
r = link_set_ipv4_forward(link);
if (r < 0)
return r;
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index 9793938080..1da99cd5bc 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -61,6 +61,7 @@ Network.IPv6PrivacyExtensions, config_parse_ipv6_privacy_extensions,
Network.IPv6AcceptRouterAdvertisements, config_parse_tristate, 0, offsetof(Network, ipv6_accept_ra)
Network.IPv6DuplicateAddressDetection, config_parse_int, 0, offsetof(Network, ipv6_dad_transmits)
Network.IPv6HopLimit, config_parse_int, 0, offsetof(Network, ipv6_hop_limit)
+Network.ProxyARP, config_parse_tristate, 0, offsetof(Network, proxy_arp)
Network.BindCarrier, config_parse_strv, 0, offsetof(Network, bind_carrier)
Address.Address, config_parse_address, 0, 0
Address.Peer, config_parse_address, 0, 0
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index 5946ba18dc..1c7adf5180 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -132,6 +132,7 @@ static int network_load_one(Manager *manager, const char *filename) {
network->ipv6_dad_transmits = -1;
network->ipv6_hop_limit = -1;
network->duid_type = _DUID_TYPE_INVALID;
+ network->proxy_arp = -1;
r = config_parse(NULL, filename, file,
"Match\0"
diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h
index 5400a8bc9d..3d44113b05 100644
--- a/src/network/networkd-network.h
+++ b/src/network/networkd-network.h
@@ -139,6 +139,7 @@ struct Network {
int ipv6_accept_ra;
int ipv6_dad_transmits;
int ipv6_hop_limit;
+ int proxy_arp;
union in_addr_union ipv6_token;
IPv6PrivacyExtensions ipv6_privacy_extensions;