diff options
| author | Susant Sahani <ssahani@users.noreply.github.com> | 2016-08-04 19:30:58 +0530 | 
|---|---|---|
| committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2016-08-04 10:00:58 -0400 | 
| commit | 99d2baa2cab0706d89beff596f997d4e3a1c833f (patch) | |
| tree | 3f6497ff983a597804563d09b175bc48e7a8c64c | |
| parent | 3104883ddc2452ae210de3c70576c03023250a51 (diff) | |
networkd: add support to configure NOARP/ARP for interface (#3854)
https://lists.freedesktop.org/archives/systemd-devel/2016-August/037268.html
| -rw-r--r-- | man/systemd.network.xml | 11 | ||||
| -rw-r--r-- | src/network/networkd-link.c | 63 | ||||
| -rw-r--r-- | src/network/networkd-network-gperf.gperf | 1 | ||||
| -rw-r--r-- | src/network/networkd-network.c | 1 | ||||
| -rw-r--r-- | src/network/networkd-network.h | 1 | 
5 files changed, 77 insertions, 0 deletions
| diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 4541a55490..c332cd7bdc 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -212,6 +212,17 @@            below 1280 (the minimum MTU for IPv6) it will automatically be increased to this value.</para>          </listitem>        </varlistentry> +      <varlistentry> +        <term><varname>ARP=</varname></term> +        <listitem> +          <para> A boolean. Enables or disables the ARP (low-level Address Resolution Protocol) +          for this interface. Defaults to unset, which means that the kernel default will be used.</para> +          <para> For example, disabling ARP is useful when creating multiple MACVLAN or VLAN virtual +          interfaces atop a single lower-level physical interface, which will then only serve as a +          link/"bridge" device aggregating traffic to the same physical link and not participate in +          the network otherwise.</para> +        </listitem> +      </varlistentry>      </variablelist>    </refsect1> diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 99784b0ebe..3e10ab1e04 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -1314,6 +1314,65 @@ int link_set_mtu(Link *link, uint32_t mtu) {          return 0;  } +static int set_flags_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { +        _cleanup_link_unref_ Link *link = userdata; +        int r; + +        assert(m); +        assert(link); +        assert(link->ifname); + +        if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) +                return 1; + +        r = sd_netlink_message_get_errno(m); +        if (r < 0) +                log_link_warning_errno(link, r, "Could not set link flags: %m"); + +        return 1; +} + +static int link_set_flags(Link *link) { +        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL; +        unsigned ifi_change = 0; +        unsigned ifi_flags = 0; +        int r; + +        assert(link); +        assert(link->manager); +        assert(link->manager->rtnl); + +        if (link->flags & IFF_LOOPBACK) +                return 0; + +        if (!link->network) +                return 0; + +        if (link->network->arp < 0) +                return 0; + +        r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex); +        if (r < 0) +                return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m"); + +        if (link->network->arp >= 0) { +                ifi_change |= IFF_NOARP; +                ifi_flags |= IFF_NOARP; +        } + +        r = sd_rtnl_message_link_set_flags(req, ifi_flags, ifi_change); +        if (r < 0) +                return log_link_error_errno(link, r, "Could not set link flags: %m"); + +        r = sd_netlink_call_async(link->manager->rtnl, req, set_flags_handler, link, 0, NULL); +        if (r < 0) +                return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); + +        link_ref(link); + +        return 0; +} +  static int link_set_bridge(Link *link) {          _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;          int r; @@ -2411,6 +2470,10 @@ static int link_configure(Link *link) {          if (r < 0)                  return r; +        r = link_set_flags(link); +        if (r < 0) +                return r; +          if (link_ipv4ll_enabled(link)) {                  r = ipv4ll_configure(link);                  if (r < 0) diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 5172a7b5e9..19adac66b8 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -28,6 +28,7 @@ Match.KernelCommandLine,                config_parse_net_condition,  Match.Architecture,                     config_parse_net_condition,                     CONDITION_ARCHITECTURE,        offsetof(Network, match_arch)  Link.MACAddress,                        config_parse_hwaddr,                            0,                             offsetof(Network, mac)  Link.MTUBytes,                          config_parse_iec_size,                          0,                             offsetof(Network, mtu) +Link.ARP,                               config_parse_tristate,                          0,                             offsetof(Network, arp)  Network.Description,                    config_parse_string,                            0,                             offsetof(Network, description)  Network.Bridge,                         config_parse_netdev,                            0,                             offsetof(Network, bridge)  Network.Bond,                           config_parse_netdev,                            0,                             offsetof(Network, bond) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 2b764d4f24..17bbe5de9f 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -134,6 +134,7 @@ static int network_load_one(Manager *manager, const char *filename) {          network->ipv6_hop_limit = -1;          network->duid.type = _DUID_TYPE_INVALID;          network->proxy_arp = -1; +        network->arp = -1;          network->ipv6_accept_ra_use_dns = true;          r = config_parse(NULL, filename, file, diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 08ee939faa..7c0bdc1e4a 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -171,6 +171,7 @@ struct Network {          struct ether_addr *mac;          unsigned mtu; +        int arp;          uint32_t iaid;          DUID duid; | 
