From bdb397ed10fb7c7d71fcf1bed2d919680f60889d Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Wed, 8 May 2019 19:43:21 +0530 Subject: [PATCH] networkd: bridge FDB support more NTF_* flags Add support to configure NTF_ROUTER and NTF_USE --- man/systemd.network.xml | 13 ++++ src/network/networkd-fdb.c | 70 +++++++++++++++---- src/network/networkd-fdb.h | 16 +++++ src/network/networkd-network-gperf.gperf | 1 + .../fuzz-network-parser/directives.network | 1 + 5 files changed, 87 insertions(+), 14 deletions(-) diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 3ff1a036ff..ca82f33bb4 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -1985,6 +1985,19 @@ Defaults to unset. + + AssociatedWith= + + Specifies where the address is associated with. Takes one of use, + self, master or router. + use means the address is in use. User space can use this option to + indicate to the kernel that the fdb entry is in use. self means + the address is associated with the port drivers fdb. Usually hardware. master + means the address is associated with master devices fdb. router means + the destination address is associated with a router. Note that it's valid if the referenced + device is a VXLAN type device and has route shortcircuit enabled. Defaults to self. + + diff --git a/src/network/networkd-fdb.c b/src/network/networkd-fdb.c index fdac574d74..4ae511fc7a 100644 --- a/src/network/networkd-fdb.c +++ b/src/network/networkd-fdb.c @@ -15,11 +15,21 @@ #include "networkd-manager.h" #include "parse-util.h" #include "string-util.h" +#include "string-table.h" #include "util.h" #include "vlan-util.h" #define STATIC_FDB_ENTRIES_PER_NETWORK_MAX 1024U +static const char* const fdb_ntf_flags_table[_NEIGHBOR_CACHE_ENTRY_FLAGS_MAX] = { + [NEIGHBOR_CACHE_ENTRY_FLAGS_USE] = "use", + [NEIGHBOR_CACHE_ENTRY_FLAGS_SELF] = "self", + [NEIGHBOR_CACHE_ENTRY_FLAGS_MASTER] = "master", + [NEIGHBOR_CACHE_ENTRY_FLAGS_ROUTER] = "router", +}; + +DEFINE_STRING_TABLE_LOOKUP(fdb_ntf_flags, NeighborCacheEntryFlags); + /* create a new FDB entry or get an existing one. */ static int fdb_entry_new_static( Network *network, @@ -68,6 +78,7 @@ static int fdb_entry_new_static( .network = network, .mac_addr = TAKE_PTR(mac_addr), .vni = VXLAN_VID_MAX + 1, + .fdb_ntf_flags = NEIGHBOR_CACHE_ENTRY_FLAGS_SELF, }; LIST_PREPEND(static_fdb_entries, network->static_fdb_entries, fdb_entry); @@ -106,9 +117,6 @@ static int set_fdb_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) /* send a request to the kernel to add a FDB entry in its static MAC table. */ int fdb_entry_configure(Link *link, FdbEntry *fdb_entry) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL; - sd_netlink *rtnl; - Bridge *bridge; - uint8_t flags; int r; assert(link); @@ -116,20 +124,12 @@ int fdb_entry_configure(Link *link, FdbEntry *fdb_entry) { assert(link->manager); assert(fdb_entry); - rtnl = link->manager->rtnl; - bridge = BRIDGE(link->network->bridge); - /* create new RTM message */ - r = sd_rtnl_message_new_neigh(rtnl, &req, RTM_NEWNEIGH, link->ifindex, PF_BRIDGE); + r = sd_rtnl_message_new_neigh(link->manager->rtnl, &req, RTM_NEWNEIGH, link->ifindex, PF_BRIDGE); if (r < 0) return rtnl_log_create_error(r); - if (bridge) - flags = NTF_MASTER; - else - flags = NTF_SELF; - - r = sd_rtnl_message_neigh_set_flags(req, flags); + r = sd_rtnl_message_neigh_set_flags(req, fdb_entry->fdb_ntf_flags); if (r < 0) return rtnl_log_create_error(r); @@ -162,7 +162,7 @@ int fdb_entry_configure(Link *link, FdbEntry *fdb_entry) { } /* send message to the kernel to update its internal static MAC table. */ - r = netlink_call_async(rtnl, NULL, req, set_fdb_handler, + r = netlink_call_async(link->manager->rtnl, NULL, req, set_fdb_handler, link_netlink_destroy_callback, link); if (r < 0) return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); @@ -359,3 +359,45 @@ int config_parse_fdb_vxlan_vni( return 0; } + + +int config_parse_fdb_ntf_flags( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + _cleanup_(fdb_entry_free_or_set_invalidp) FdbEntry *fdb_entry = NULL; + Network *network = userdata; + NeighborCacheEntryFlags f; + int r; + + assert(filename); + assert(section); + assert(lvalue); + assert(rvalue); + assert(data); + + r = fdb_entry_new_static(network, filename, section_line, &fdb_entry); + if (r < 0) + return log_oom(); + + f = fdb_ntf_flags_from_string(rvalue); + if (f < 0) { + log_syntax(unit, LOG_ERR, filename, line, 0, + "FDB failed to parse AssociatedWith=, ignoring assignment: %s", + rvalue); + return 0; + } + + fdb_entry->fdb_ntf_flags = f; + fdb_entry = NULL; + + return 0; +} diff --git a/src/network/networkd-fdb.h b/src/network/networkd-fdb.h index 6954e555fa..bcdd8ce3cb 100644 --- a/src/network/networkd-fdb.h +++ b/src/network/networkd-fdb.h @@ -5,6 +5,8 @@ Copyright © 2014 Intel Corporation. All rights reserved. ***/ +#include + #include "conf-parser.h" #include "list.h" #include "macro.h" @@ -15,6 +17,15 @@ typedef struct FdbEntry FdbEntry; typedef struct Link Link; typedef struct NetworkConfigSection NetworkConfigSection; +typedef enum NeighborCacheEntryFlags { + NEIGHBOR_CACHE_ENTRY_FLAGS_USE = NTF_USE, + NEIGHBOR_CACHE_ENTRY_FLAGS_SELF = NTF_SELF, + NEIGHBOR_CACHE_ENTRY_FLAGS_MASTER = NTF_MASTER, + NEIGHBOR_CACHE_ENTRY_FLAGS_ROUTER = NTF_ROUTER, + _NEIGHBOR_CACHE_ENTRY_FLAGS_MAX, + _NEIGHBOR_CACHE_ENTRY_FLAGS_INVALID = -1, +} NeighborCacheEntryFlags; + struct FdbEntry { Network *network; NetworkConfigSection *section; @@ -26,6 +37,7 @@ struct FdbEntry { struct ether_addr *mac_addr; union in_addr_union destination_addr; + NeighborCacheEntryFlags fdb_ntf_flags; LIST_FIELDS(FdbEntry, static_fdb_entries); }; @@ -35,7 +47,11 @@ int fdb_entry_configure(Link *link, FdbEntry *fdb_entry); DEFINE_NETWORK_SECTION_FUNCTIONS(FdbEntry, fdb_entry_free); +const char* fdb_ntf_flags_to_string(NeighborCacheEntryFlags i) _const_; +NeighborCacheEntryFlags fdb_ntf_flags_from_string(const char *s) _pure_; + CONFIG_PARSER_PROTOTYPE(config_parse_fdb_hwaddr); CONFIG_PARSER_PROTOTYPE(config_parse_fdb_vlan_id); CONFIG_PARSER_PROTOTYPE(config_parse_fdb_destination); CONFIG_PARSER_PROTOTYPE(config_parse_fdb_vxlan_vni); +CONFIG_PARSER_PROTOTYPE(config_parse_fdb_ntf_flags); diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index c6036e29fa..a57d9395f6 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -186,6 +186,7 @@ BridgeFDB.MACAddress, config_parse_fdb_hwaddr, BridgeFDB.VLANId, config_parse_fdb_vlan_id, 0, 0 BridgeFDB.Destination, config_parse_fdb_destination, 0, 0 BridgeFDB.VNI, config_parse_fdb_vxlan_vni, 0, 0 +BridgeFDB.AssociatedWith, config_parse_fdb_ntf_flags, 0, 0 BridgeVLAN.PVID, config_parse_brvlan_pvid, 0, 0 BridgeVLAN.VLAN, config_parse_brvlan_vlan, 0, 0 BridgeVLAN.EgressUntagged, config_parse_brvlan_untagged, 0, 0 diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network index 97e8e4a580..5d48f0825b 100644 --- a/test/fuzz/fuzz-network-parser/directives.network +++ b/test/fuzz/fuzz-network-parser/directives.network @@ -37,6 +37,7 @@ VLANId= MACAddress= Destination= VNI= +AssociatedWith= [DHCP] UseDomains= UseRoutes=