Esempio n. 1
0
TError TNl::ProxyNeighbour(int ifindex, const TNlAddr &addr, bool add) {
    struct rtnl_neigh *neigh;
    int ret;

    neigh = rtnl_neigh_alloc();
    if (!neigh)
        return TError(EError::Unknown, "Cannot allocate neighbour");

    ret = rtnl_neigh_set_dst(neigh, addr.Addr);
    if (ret) {
        rtnl_neigh_put(neigh);
        return Error(ret, "Cannot set neighbour dst");
    }

    rtnl_neigh_set_flags(neigh, NTF_PROXY);
    rtnl_neigh_set_state(neigh, NUD_PERMANENT);
    rtnl_neigh_set_ifindex(neigh, ifindex);

    if (add) {
        Dump("add", neigh);
        ret = rtnl_neigh_add(Sock, neigh, NLM_F_CREATE | NLM_F_REPLACE);
    } else {
        Dump("del", neigh);
        ret = rtnl_neigh_delete(Sock, neigh, 0);

        if (ret == -NLE_OBJ_NOTFOUND)
            ret = 0;
    }
    rtnl_neigh_put(neigh);
    if (ret)
        return Error(ret, "Cannot modify neighbour for l3 network");

    return TError::Success();
}
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);
}