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); }
/** * Unset a state by its name * @arg neigh neighbour to change * @arg name state name to unset */ void rtnl_neigh_unset_state_name(struct rtnl_neigh *neigh, const char *name) { int state = rtnl_neigh_str2state(name); if (state >= 0) rtnl_neigh_unset_state(neigh, state); }