static void mac_create(switchlink_mac_addr_t mac_addr, switchlink_handle_t bridge_h, switchlink_handle_t intf_h) { switchlink_handle_t old_intf_h; switchlink_db_status_t status; status = switchlink_db_mac_get_intf(mac_addr, bridge_h, &old_intf_h); if (status == SWITCHLINK_DB_STATUS_SUCCESS) { if (old_intf_h != intf_h) { switchlink_mac_update(mac_addr, bridge_h, intf_h); switchlink_db_mac_set_intf(mac_addr, bridge_h, intf_h); return; } } switchlink_mac_create(mac_addr, bridge_h, intf_h); switchlink_db_mac_add(mac_addr, bridge_h, intf_h); }
void switchlink_linux_mac_update(switchlink_mac_addr_t mac_addr, switchlink_handle_t bridge_h, switchlink_handle_t intf_h, bool create) { switchlink_db_status_t status; uint32_t ifindex; if (!create) { status = switchlink_db_mac_get_intf(mac_addr, bridge_h, &intf_h); if (status != SWITCHLINK_DB_STATUS_SUCCESS) { assert(false); return; } } status = switchlink_db_interface_get_ifindex(intf_h, &ifindex); if (status != SWITCHLINK_DB_STATUS_SUCCESS) { assert(false); return; } struct nl_sock *nlsk = switchlink_get_nl_sock(); if (!nlsk) { return; } struct nl_addr *nl_addr = nl_addr_build(AF_LLC, mac_addr, ETH_ALEN); struct rtnl_neigh *rtnl_neigh = rtnl_neigh_alloc(); rtnl_neigh_set_ifindex(rtnl_neigh, ifindex); rtnl_neigh_set_lladdr(rtnl_neigh, nl_addr); rtnl_neigh_set_state(rtnl_neigh, rtnl_neigh_str2state("permanent")); rtnl_neigh_set_family(rtnl_neigh, AF_BRIDGE); if (create) { status = switchlink_db_mac_add(mac_addr, bridge_h, intf_h); assert(status == SWITCHLINK_DB_STATUS_SUCCESS); rtnl_neigh_add(nlsk, rtnl_neigh, NLM_F_CREATE|NLM_F_REPLACE); } else { status = switchlink_db_mac_delete(mac_addr, bridge_h); assert(status == SWITCHLINK_DB_STATUS_SUCCESS); rtnl_neigh_delete(nlsk, rtnl_neigh, 0); } rtnl_neigh_put(rtnl_neigh); nl_addr_put(nl_addr); }
static void mac_create(switchlink_mac_addr_t mac_addr, switchlink_handle_t bridge_h, switchlink_handle_t intf_h) { switchlink_handle_t old_intf_h; switchlink_db_status_t status; status = switchlink_db_mac_get_intf(mac_addr, bridge_h, &old_intf_h); if (status == SWITCHLINK_DB_STATUS_SUCCESS) { if (old_intf_h == intf_h) { // no change return; } else { // update handled as delete followed by add mac_delete(mac_addr, bridge_h); } } switchlink_mac_create(mac_addr, bridge_h, intf_h); switchlink_db_mac_add(mac_addr, bridge_h, intf_h); }