diff options
Diffstat (limited to 'src/network/networkd-fdb.c')
-rw-r--r-- | src/network/networkd-fdb.c | 66 |
1 files changed, 42 insertions, 24 deletions
diff --git a/src/network/networkd-fdb.c b/src/network/networkd-fdb.c index 0f2510e904..ed5a47589e 100644 --- a/src/network/networkd-fdb.c +++ b/src/network/networkd-fdb.c @@ -1,5 +1,3 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - /*** This file is part of systemd. @@ -19,25 +17,33 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <net/if.h> #include <net/ethernet.h> +#include <net/if.h> -#include "networkd.h" -#include "networkd-link.h" +#include "alloc-util.h" #include "conf-parser.h" +#include "netlink-util.h" +#include "networkd-fdb.h" +#include "networkd.h" #include "util.h" +#include "vlan-util.h" + +#define STATIC_FDB_ENTRIES_PER_NETWORK_MAX 1024U /* create a new FDB entry or get an existing one. */ -int fdb_entry_new_static(Network *const network, - const unsigned section, - FdbEntry **ret) { +int fdb_entry_new_static( + Network *network, + unsigned section, + FdbEntry **ret) { + _cleanup_fdbentry_free_ FdbEntry *fdb_entry = NULL; struct ether_addr *mac_addr = NULL; assert(network); + assert(ret); /* search entry in hashmap first. */ - if(section) { + if (section) { fdb_entry = hashmap_get(network->fdb_entries_by_section, UINT_TO_PTR(section)); if (fdb_entry) { *ret = fdb_entry; @@ -47,6 +53,9 @@ int fdb_entry_new_static(Network *const network, } } + if (network->n_static_fdb_entries >= STATIC_FDB_ENTRIES_PER_NETWORK_MAX) + return -E2BIG; + /* allocate space for MAC address. */ mac_addr = new0(struct ether_addr, 1); if (!mac_addr) @@ -54,7 +63,6 @@ int fdb_entry_new_static(Network *const network, /* allocate space for and FDB entry. */ fdb_entry = new0(FdbEntry, 1); - if (!fdb_entry) { /* free previously allocated space for mac_addr. */ free(mac_addr); @@ -66,6 +74,7 @@ int fdb_entry_new_static(Network *const network, fdb_entry->mac_addr = mac_addr; LIST_PREPEND(static_fdb_entries, network->static_fdb_entries, fdb_entry); + network->n_static_fdb_entries++; if (section) { fdb_entry->section = section; @@ -94,24 +103,32 @@ static int set_fdb_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userda } /* send a request to the kernel to add a FDB entry in its static MAC table. */ -int fdb_entry_configure(Link *const link, FdbEntry *const fdb_entry) { - _cleanup_netlink_message_unref_ sd_netlink_message *req = NULL; +int fdb_entry_configure(Link *link, FdbEntry *fdb_entry) { + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL; sd_netlink *rtnl; int r; + uint8_t flags; + Bridge *bridge; assert(link); + assert(link->network); 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); if (r < 0) return rtnl_log_create_error(r); - /* only NTF_SELF flag supported. */ - r = sd_rtnl_message_neigh_set_flags(req, NTF_SELF); + if (bridge) + flags = NTF_MASTER; + else + flags = NTF_SELF; + + r = sd_rtnl_message_neigh_set_flags(req, flags); if (r < 0) return rtnl_log_create_error(r); @@ -141,16 +158,17 @@ int fdb_entry_configure(Link *const link, FdbEntry *const fdb_entry) { /* remove and FDB entry. */ void fdb_entry_free(FdbEntry *fdb_entry) { - if(!fdb_entry) + if (!fdb_entry) return; - if(fdb_entry->network) { - LIST_REMOVE(static_fdb_entries, fdb_entry->network->static_fdb_entries, - fdb_entry); + if (fdb_entry->network) { + LIST_REMOVE(static_fdb_entries, fdb_entry->network->static_fdb_entries, fdb_entry); + + assert(fdb_entry->network->n_static_fdb_entries > 0); + fdb_entry->network->n_static_fdb_entries--; if (fdb_entry->section) - hashmap_remove(fdb_entry->network->fdb_entries_by_section, - UINT_TO_PTR(fdb_entry->section)); + hashmap_remove(fdb_entry->network->fdb_entries_by_section, UINT_TO_PTR(fdb_entry->section)); } free(fdb_entry->mac_addr); @@ -195,7 +213,7 @@ int config_parse_fdb_hwaddr( &fdb_entry->mac_addr->ether_addr_octet[5]); if (ETHER_ADDR_LEN != r) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Not a valid MAC address, ignoring assignment: %s", rvalue); + log_syntax(unit, LOG_ERR, filename, line, 0, "Not a valid MAC address, ignoring assignment: %s", rvalue); return 0; } @@ -231,9 +249,9 @@ int config_parse_fdb_vlan_id( if (r < 0) return log_oom(); - r = config_parse_unsigned(unit, filename, line, section, - section_line, lvalue, ltype, - rvalue, &fdb_entry->vlan_id, userdata); + r = config_parse_vlanid(unit, filename, line, section, + section_line, lvalue, ltype, + rvalue, &fdb_entry->vlan_id, userdata); if (r < 0) return r; |