mirror of
https://github.com/FRRouting/frr.git
synced 2025-04-30 13:37:17 +02:00
zebra: Use zebra dplane for RTM link and addr
a) Move the reads of link and address information into the dplane b) Move the startup read of data into the dplane as well. c) Break up startup reading of the linux kernel data into multiple phases. As that we have implied ordering of data that must be read first and if the dplane has taken over some data reading then we must delay initial read-in of other data. Fixes: #13288 Signed-off-by: Donald Sharp <sharpd@nvidia.com>
This commit is contained in:
parent
a014450441
commit
605df8d44f
File diff suppressed because it is too large
Load diff
|
@ -1294,6 +1294,9 @@ static void zebra_if_addr_update_ctx(struct zebra_dplane_ctx *ctx,
|
|||
const struct prefix *addr, *dest = NULL;
|
||||
enum dplane_op_e op;
|
||||
|
||||
if (!ifp)
|
||||
return;
|
||||
|
||||
op = dplane_ctx_get_op(ctx);
|
||||
addr = dplane_ctx_get_intf_addr(ctx);
|
||||
|
||||
|
@ -1412,6 +1415,13 @@ static void zebra_if_netconf_update_ctx(struct zebra_dplane_ctx *ctx,
|
|||
enum dplane_netconf_status_e mpls, mcast_on, linkdown;
|
||||
bool *mcast_set, *linkdown_set;
|
||||
|
||||
if (!ifp && ifindex != -1 && ifindex != -2) {
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug("%s: Can't find ifp(%u)", __func__, ifindex);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
afi = dplane_ctx_get_afi(ctx);
|
||||
mpls = dplane_ctx_get_netconf_mpls(ctx);
|
||||
linkdown = dplane_ctx_get_netconf_linkdown(ctx);
|
||||
|
@ -1481,6 +1491,753 @@ static void zebra_if_netconf_update_ctx(struct zebra_dplane_ctx *ctx,
|
|||
(*linkdown_set ? "ON" : "OFF"));
|
||||
}
|
||||
|
||||
static void interface_vrf_change(enum dplane_op_e op, ifindex_t ifindex,
|
||||
const char *name, uint32_t tableid,
|
||||
ns_id_t ns_id)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct zebra_vrf *zvrf = NULL;
|
||||
|
||||
if (op == DPLANE_OP_INTF_DELETE) {
|
||||
if (IS_ZEBRA_DEBUG_DPLANE)
|
||||
zlog_debug("DPLANE_OP_INTF_DELETE for VRF %s(%u)", name,
|
||||
ifindex);
|
||||
|
||||
vrf = vrf_lookup_by_id((vrf_id_t)ifindex);
|
||||
if (!vrf) {
|
||||
flog_warn(EC_ZEBRA_VRF_NOT_FOUND,
|
||||
"%s(%u): vrf not found", name, ifindex);
|
||||
return;
|
||||
}
|
||||
|
||||
vrf_delete(vrf);
|
||||
} else {
|
||||
if (IS_ZEBRA_DEBUG_DPLANE)
|
||||
zlog_debug(
|
||||
"DPLANE_OP_INTF_UPDATE for VRF %s(%u) table %u",
|
||||
name, ifindex, tableid);
|
||||
|
||||
if (!vrf_lookup_by_id((vrf_id_t)ifindex)) {
|
||||
vrf_id_t exist_id;
|
||||
|
||||
exist_id = zebra_vrf_lookup_by_table(tableid, ns_id);
|
||||
if (exist_id != VRF_DEFAULT) {
|
||||
vrf = vrf_lookup_by_id(exist_id);
|
||||
|
||||
flog_err(
|
||||
EC_ZEBRA_VRF_MISCONFIGURED,
|
||||
"VRF %s id %u table id overlaps existing vrf %s(%d), misconfiguration exiting",
|
||||
name, ifindex, vrf->name, vrf->vrf_id);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
vrf = vrf_update((vrf_id_t)ifindex, name);
|
||||
if (!vrf) {
|
||||
flog_err(EC_LIB_INTERFACE, "VRF %s id %u not created",
|
||||
name, ifindex);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the only place that we get the actual kernel table_id
|
||||
* being used. We need it to set the table_id of the routes
|
||||
* we are passing to the kernel.... And to throw some totally
|
||||
* awesome parties. that too.
|
||||
*
|
||||
* At this point we *must* have a zvrf because the vrf_create
|
||||
* callback creates one. We *must* set the table id
|
||||
* before the vrf_enable because of( at the very least )
|
||||
* static routes being delayed for installation until
|
||||
* during the vrf_enable callbacks.
|
||||
*/
|
||||
zvrf = (struct zebra_vrf *)vrf->info;
|
||||
zvrf->table_id = tableid;
|
||||
|
||||
/* Enable the created VRF. */
|
||||
if (!vrf_enable(vrf)) {
|
||||
flog_err(EC_LIB_INTERFACE,
|
||||
"Failed to enable VRF %s id %u", name,
|
||||
ifindex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: on netlink systems, there should be a 1-to-1 mapping
|
||||
* between interface names and ifindex values.
|
||||
*/
|
||||
static void set_ifindex(struct interface *ifp, ifindex_t ifi_index,
|
||||
struct zebra_ns *zns)
|
||||
{
|
||||
struct interface *oifp;
|
||||
|
||||
oifp = if_lookup_by_index_per_ns(zns, ifi_index);
|
||||
if ((oifp != NULL) && (oifp != ifp)) {
|
||||
if (ifi_index == IFINDEX_INTERNAL)
|
||||
flog_err(
|
||||
EC_LIB_INTERFACE,
|
||||
"Netlink is setting interface %s ifindex to reserved internal value %u",
|
||||
ifp->name, ifi_index);
|
||||
else {
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug(
|
||||
"interface index %d was renamed from %s to %s",
|
||||
ifi_index, oifp->name, ifp->name);
|
||||
if (if_is_up(oifp))
|
||||
flog_err(
|
||||
EC_LIB_INTERFACE,
|
||||
"interface rename detected on up interface: index %d was renamed from %s to %s, results are uncertain!",
|
||||
ifi_index, oifp->name, ifp->name);
|
||||
if_delete_update(&oifp);
|
||||
}
|
||||
}
|
||||
if_set_index(ifp, ifi_index);
|
||||
}
|
||||
|
||||
static inline void zebra_if_set_ziftype(struct interface *ifp,
|
||||
enum zebra_iftype zif_type,
|
||||
enum zebra_slave_iftype zif_slave_type)
|
||||
{
|
||||
struct zebra_if *zif;
|
||||
|
||||
zif = (struct zebra_if *)ifp->info;
|
||||
zif->zif_slave_type = zif_slave_type;
|
||||
|
||||
if (zif->zif_type != zif_type) {
|
||||
zif->zif_type = zif_type;
|
||||
/* If the if_type has been set to bond initialize ES info
|
||||
* against it. XXX - note that we don't handle the case where
|
||||
* a zif changes from bond to non-bond; it is really
|
||||
* an unexpected/error condition.
|
||||
*/
|
||||
zebra_evpn_if_init(zif);
|
||||
}
|
||||
}
|
||||
|
||||
static void interface_update_hw_addr(struct zebra_dplane_ctx *ctx,
|
||||
struct interface *ifp)
|
||||
{
|
||||
int i;
|
||||
|
||||
ifp->hw_addr_len = dplane_ctx_get_ifp_hw_addr_len(ctx);
|
||||
memcpy(ifp->hw_addr, dplane_ctx_get_ifp_hw_addr(ctx), ifp->hw_addr_len);
|
||||
|
||||
for (i = 0; i < ifp->hw_addr_len; i++)
|
||||
if (ifp->hw_addr[i] != 0)
|
||||
break;
|
||||
|
||||
if (i == ifp->hw_addr_len)
|
||||
ifp->hw_addr_len = 0;
|
||||
}
|
||||
|
||||
static void interface_update_l2info(struct zebra_dplane_ctx *ctx,
|
||||
struct interface *ifp,
|
||||
enum zebra_iftype zif_type, int add,
|
||||
ns_id_t link_nsid)
|
||||
{
|
||||
const struct zebra_l2info_vxlan *vxlan_info;
|
||||
const struct zebra_l2info_gre *gre_info;
|
||||
|
||||
switch (zif_type) {
|
||||
case ZEBRA_IF_BRIDGE:
|
||||
zebra_l2_bridge_add_update(ifp,
|
||||
dplane_ctx_get_ifp_bridge_info(ctx));
|
||||
break;
|
||||
case ZEBRA_IF_VLAN:
|
||||
zebra_l2_vlanif_update(ifp, dplane_ctx_get_ifp_vlan_info(ctx));
|
||||
zebra_evpn_acc_bd_svi_set(ifp->info, NULL,
|
||||
!!if_is_operative(ifp));
|
||||
break;
|
||||
case ZEBRA_IF_VXLAN:
|
||||
vxlan_info = dplane_ctx_get_ifp_vxlan_info(ctx);
|
||||
zebra_l2_vxlanif_add_update(ifp, vxlan_info, add);
|
||||
if (link_nsid != NS_UNKNOWN && vxlan_info->ifindex_link)
|
||||
zebra_if_update_link(ifp, vxlan_info->ifindex_link,
|
||||
link_nsid);
|
||||
break;
|
||||
case ZEBRA_IF_GRE:
|
||||
gre_info = dplane_ctx_get_ifp_gre_info(ctx);
|
||||
zebra_l2_greif_add_update(ifp, gre_info, add);
|
||||
if (link_nsid != NS_UNKNOWN && gre_info->ifindex_link)
|
||||
zebra_if_update_link(ifp, gre_info->ifindex_link,
|
||||
link_nsid);
|
||||
break;
|
||||
case ZEBRA_IF_OTHER:
|
||||
case ZEBRA_IF_VRF:
|
||||
case ZEBRA_IF_MACVLAN:
|
||||
case ZEBRA_IF_VETH:
|
||||
case ZEBRA_IF_BOND:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static bool is_if_protodown_reason_only_frr(uint32_t rc_bitfield)
|
||||
{
|
||||
uint8_t frr_protodown_r_bit = if_netlink_get_frr_protodown_r_bit();
|
||||
|
||||
return (rc_bitfield == (((uint32_t)1) << frr_protodown_r_bit));
|
||||
}
|
||||
|
||||
static void interface_if_protodown(struct interface *ifp, bool protodown,
|
||||
uint32_t rc_bitfield)
|
||||
{
|
||||
struct zebra_if *zif = ifp->info;
|
||||
bool old_protodown;
|
||||
|
||||
/*
|
||||
* Set our reason code to note it wasn't us.
|
||||
* If the reason we got from the kernel is ONLY frr though, don't
|
||||
* set it.
|
||||
*/
|
||||
COND_FLAG(zif->protodown_rc, ZEBRA_PROTODOWN_EXTERNAL,
|
||||
protodown && rc_bitfield &&
|
||||
!is_if_protodown_reason_only_frr(rc_bitfield));
|
||||
|
||||
|
||||
old_protodown = !!ZEBRA_IF_IS_PROTODOWN(zif);
|
||||
if (protodown == old_protodown)
|
||||
return;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_DPLANE)
|
||||
zlog_debug("interface %s dplane change, protodown %s",
|
||||
ifp->name, protodown ? "on" : "off");
|
||||
|
||||
/* Set protodown, respectively */
|
||||
COND_FLAG(zif->flags, ZIF_FLAG_PROTODOWN, protodown);
|
||||
|
||||
if (zebra_evpn_is_es_bond_member(ifp)) {
|
||||
/* Check it's not already being sent to the dplane first */
|
||||
if (protodown &&
|
||||
CHECK_FLAG(zif->flags, ZIF_FLAG_SET_PROTODOWN)) {
|
||||
if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug(
|
||||
"bond mbr %s protodown on recv'd but already sent protodown on to the dplane",
|
||||
ifp->name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!protodown &&
|
||||
CHECK_FLAG(zif->flags, ZIF_FLAG_UNSET_PROTODOWN)) {
|
||||
if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug(
|
||||
"bond mbr %s protodown off recv'd but already sent protodown off to the dplane",
|
||||
ifp->name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug(
|
||||
"bond mbr %s reinstate protodown %s in the dplane",
|
||||
ifp->name, old_protodown ? "on" : "off");
|
||||
|
||||
if (old_protodown)
|
||||
SET_FLAG(zif->flags, ZIF_FLAG_SET_PROTODOWN);
|
||||
else
|
||||
SET_FLAG(zif->flags, ZIF_FLAG_UNSET_PROTODOWN);
|
||||
|
||||
dplane_intf_update(zif->ifp);
|
||||
}
|
||||
}
|
||||
|
||||
static void if_sweep_protodown(struct zebra_if *zif)
|
||||
{
|
||||
bool protodown;
|
||||
|
||||
protodown = !!ZEBRA_IF_IS_PROTODOWN(zif);
|
||||
|
||||
if (!protodown)
|
||||
return;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug("interface %s sweeping protodown %s reason 0x%x",
|
||||
zif->ifp->name, protodown ? "on" : "off",
|
||||
zif->protodown_rc);
|
||||
|
||||
/* Only clear our reason codes, leave external if it was set */
|
||||
UNSET_FLAG(zif->protodown_rc, ZEBRA_PROTODOWN_ALL);
|
||||
dplane_intf_update(zif->ifp);
|
||||
}
|
||||
|
||||
static void
|
||||
interface_bridge_vxlan_vlan_vni_map_update(struct zebra_dplane_ctx *ctx,
|
||||
struct interface *ifp)
|
||||
{
|
||||
const struct zebra_vxlan_vni_array *vniarray =
|
||||
dplane_ctx_get_ifp_vxlan_vni_array(ctx);
|
||||
struct zebra_vxlan_vni vni_start, vni_end;
|
||||
struct hash *vni_table = NULL;
|
||||
struct zebra_vxlan_vni vni, *vnip;
|
||||
vni_t vni_id;
|
||||
vlanid_t vid;
|
||||
int i;
|
||||
|
||||
memset(&vni_start, 0, sizeof(vni_start));
|
||||
memset(&vni_end, 0, sizeof(vni_end));
|
||||
|
||||
for (i = 0; i < vniarray->count; i++) {
|
||||
uint16_t flags = vniarray->vnis[i].flags;
|
||||
|
||||
if (flags & DPLANE_BRIDGE_VLAN_INFO_RANGE_BEGIN) {
|
||||
vni_start = vniarray->vnis[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
if (flags & DPLANE_BRIDGE_VLAN_INFO_RANGE_END)
|
||||
vni_end = vniarray->vnis[i];
|
||||
|
||||
if (!(flags & DPLANE_BRIDGE_VLAN_INFO_RANGE_END)) {
|
||||
vni_start = vniarray->vnis[i];
|
||||
vni_end = vniarray->vnis[i];
|
||||
}
|
||||
|
||||
if (IS_ZEBRA_DEBUG_DPLANE)
|
||||
zlog_debug(
|
||||
"Vlan-Vni(%d:%d-%d:%d) update for VxLAN IF %s(%u)",
|
||||
vni_start.access_vlan, vni_end.access_vlan,
|
||||
vni_start.vni, vni_end.vni, ifp->name,
|
||||
ifp->ifindex);
|
||||
|
||||
if (!vni_table) {
|
||||
vni_table = zebra_vxlan_vni_table_create();
|
||||
if (!vni_table)
|
||||
return;
|
||||
}
|
||||
|
||||
for (vid = vni_start.access_vlan, vni_id = vni_start.vni;
|
||||
vid <= vni_end.access_vlan; vid++, vni_id++) {
|
||||
|
||||
memset(&vni, 0, sizeof(vni));
|
||||
vni.vni = vni_id;
|
||||
vni.access_vlan = vid;
|
||||
vnip = hash_get(vni_table, &vni, zebra_vxlan_vni_alloc);
|
||||
if (!vnip)
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&vni_start, 0, sizeof(vni_start));
|
||||
memset(&vni_end, 0, sizeof(vni_end));
|
||||
}
|
||||
|
||||
if (vni_table)
|
||||
zebra_vxlan_if_vni_table_add_update(ifp, vni_table);
|
||||
}
|
||||
|
||||
static void interface_bridge_vxlan_update(struct zebra_dplane_ctx *ctx,
|
||||
struct interface *ifp)
|
||||
{
|
||||
struct zebra_if *zif = ifp->info;
|
||||
const struct zebra_dplane_bridge_vlan_info *bvinfo;
|
||||
|
||||
if (IS_ZEBRA_VXLAN_IF_SVD(zif))
|
||||
interface_bridge_vxlan_vlan_vni_map_update(ctx, ifp);
|
||||
|
||||
bvinfo = dplane_ctx_get_ifp_bridge_vlan_info(ctx);
|
||||
|
||||
if (!(bvinfo->flags & DPLANE_BRIDGE_VLAN_INFO_PVID))
|
||||
return;
|
||||
|
||||
if (IS_ZEBRA_DEBUG_DPLANE)
|
||||
zlog_debug("Access VLAN %u for VxLAN IF %s(%u)", bvinfo->vid,
|
||||
ifp->name, ifp->ifindex);
|
||||
|
||||
zebra_l2_vxlanif_update_access_vlan(ifp, bvinfo->vid);
|
||||
}
|
||||
|
||||
static void interface_bridge_vlan_update(struct zebra_dplane_ctx *ctx,
|
||||
struct interface *ifp)
|
||||
{
|
||||
struct zebra_if *zif = ifp->info;
|
||||
const struct zebra_dplane_bridge_vlan_info_array *bvarray;
|
||||
struct zebra_dplane_bridge_vlan_info bvinfo;
|
||||
bitfield_t old_vlan_bitmap;
|
||||
uint16_t vid_range_start = 0;
|
||||
int32_t i;
|
||||
|
||||
/* cache the old bitmap addrs */
|
||||
old_vlan_bitmap = zif->vlan_bitmap;
|
||||
/* create a new bitmap space for re-eval */
|
||||
bf_init(zif->vlan_bitmap, IF_VLAN_BITMAP_MAX);
|
||||
|
||||
/* Could we have multiple bridge vlan infos? */
|
||||
bvarray = dplane_ctx_get_ifp_bridge_vlan_info_array(ctx);
|
||||
if (!bvarray)
|
||||
return;
|
||||
|
||||
for (i = 0; i < bvarray->count; i++) {
|
||||
bvinfo = bvarray->array[i];
|
||||
|
||||
if (bvinfo.flags & DPLANE_BRIDGE_VLAN_INFO_RANGE_BEGIN) {
|
||||
vid_range_start = bvinfo.vid;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(bvinfo.flags & DPLANE_BRIDGE_VLAN_INFO_RANGE_END))
|
||||
vid_range_start = bvinfo.vid;
|
||||
|
||||
zebra_vlan_bitmap_compute(ifp, vid_range_start, bvinfo.vid);
|
||||
}
|
||||
|
||||
zebra_vlan_mbr_re_eval(ifp, old_vlan_bitmap);
|
||||
bf_free(old_vlan_bitmap);
|
||||
}
|
||||
|
||||
static void interface_bridge_handling(struct zebra_dplane_ctx *ctx,
|
||||
struct interface *ifp,
|
||||
enum zebra_iftype zif_type)
|
||||
{
|
||||
struct zebra_if *zif;
|
||||
|
||||
if (!ifp) {
|
||||
zlog_warn("Cannot find bridge if %s(%u)",
|
||||
dplane_ctx_get_ifname(ctx),
|
||||
dplane_ctx_get_ifindex(ctx));
|
||||
return;
|
||||
}
|
||||
|
||||
if (IS_ZEBRA_IF_VXLAN(ifp))
|
||||
return interface_bridge_vxlan_update(ctx, ifp);
|
||||
|
||||
/*
|
||||
* build vlan bitmap associated with this interface if that
|
||||
* device type is interested in the vlans
|
||||
*/
|
||||
zif = ifp->info;
|
||||
if (bf_is_inited(zif->vlan_bitmap))
|
||||
interface_bridge_vlan_update(ctx, ifp);
|
||||
}
|
||||
|
||||
static void zebra_if_dplane_ifp_handling(struct zebra_dplane_ctx *ctx)
|
||||
{
|
||||
enum dplane_op_e op = dplane_ctx_get_op(ctx);
|
||||
const char *name = dplane_ctx_get_ifname(ctx);
|
||||
ns_id_t ns_id = dplane_ctx_get_ns_id(ctx);
|
||||
ifindex_t ifindex = dplane_ctx_get_ifindex(ctx);
|
||||
ifindex_t bond_ifindex = dplane_ctx_get_ifp_bond_ifindex(ctx);
|
||||
uint32_t tableid = dplane_ctx_get_ifp_table_id(ctx);
|
||||
enum zebra_iftype zif_type = dplane_ctx_get_ifp_zif_type(ctx);
|
||||
struct interface *ifp;
|
||||
struct zebra_ns *zns;
|
||||
|
||||
zns = zebra_ns_lookup(ns_id);
|
||||
if (!zns) {
|
||||
zlog_err("Where is our namespace?");
|
||||
return;
|
||||
}
|
||||
|
||||
if (IS_ZEBRA_DEBUG_DPLANE)
|
||||
zlog_debug("%s for %s(%u)", dplane_op2str(op), name, ifindex);
|
||||
|
||||
ifp = if_lookup_by_name_per_ns(zns, name);
|
||||
if (op == DPLANE_OP_INTF_DELETE) {
|
||||
/* Delete interface notification from kernel */
|
||||
if (ifp == NULL) {
|
||||
if (IS_ZEBRA_DEBUG_EVENT)
|
||||
zlog_debug(
|
||||
"Delete LINK received for unknown interface %s(%u)",
|
||||
name, ifindex);
|
||||
return;
|
||||
}
|
||||
|
||||
if (IS_ZEBRA_IF_BOND(ifp))
|
||||
zebra_l2if_update_bond(ifp, false);
|
||||
if (IS_ZEBRA_IF_BOND_SLAVE(ifp))
|
||||
zebra_l2if_update_bond_slave(ifp, bond_ifindex, false);
|
||||
/* Special handling for bridge or VxLAN interfaces. */
|
||||
if (IS_ZEBRA_IF_BRIDGE(ifp))
|
||||
zebra_l2_bridge_del(ifp);
|
||||
else if (IS_ZEBRA_IF_VXLAN(ifp))
|
||||
zebra_l2_vxlanif_del(ifp);
|
||||
|
||||
if_delete_update(&ifp);
|
||||
|
||||
if (zif_type == ZEBRA_IF_VRF && !vrf_is_backend_netns())
|
||||
interface_vrf_change(op, ifindex, name, tableid, ns_id);
|
||||
} else {
|
||||
ifindex_t master_ifindex, bridge_ifindex, bond_ifindex,
|
||||
link_ifindex;
|
||||
enum zebra_slave_iftype zif_slave_type;
|
||||
uint8_t bypass;
|
||||
uint64_t flags;
|
||||
vrf_id_t vrf_id;
|
||||
uint32_t mtu;
|
||||
ns_id_t link_nsid;
|
||||
struct zebra_if *zif;
|
||||
bool protodown, protodown_set, startup;
|
||||
uint32_t rc_bitfield;
|
||||
uint8_t old_hw_addr[INTERFACE_HWADDR_MAX];
|
||||
char *desc;
|
||||
uint8_t family;
|
||||
|
||||
/* If VRF, create or update the VRF structure itself. */
|
||||
if (zif_type == ZEBRA_IF_VRF && !vrf_is_backend_netns())
|
||||
interface_vrf_change(op, ifindex, name, tableid, ns_id);
|
||||
|
||||
master_ifindex = dplane_ctx_get_ifp_master_ifindex(ctx);
|
||||
zif_slave_type = dplane_ctx_get_ifp_zif_slave_type(ctx);
|
||||
bridge_ifindex = dplane_ctx_get_ifp_bridge_ifindex(ctx);
|
||||
bond_ifindex = dplane_ctx_get_ifp_bond_ifindex(ctx);
|
||||
bypass = dplane_ctx_get_ifp_bypass(ctx);
|
||||
flags = dplane_ctx_get_ifp_flags(ctx);
|
||||
vrf_id = dplane_ctx_get_ifp_vrf_id(ctx);
|
||||
mtu = dplane_ctx_get_ifp_mtu(ctx);
|
||||
link_ifindex = dplane_ctx_get_ifp_link_ifindex(ctx);
|
||||
link_nsid = dplane_ctx_get_ifp_link_nsid(ctx);
|
||||
protodown_set = dplane_ctx_get_ifp_protodown_set(ctx);
|
||||
protodown = dplane_ctx_get_ifp_protodown(ctx);
|
||||
rc_bitfield = dplane_ctx_get_ifp_rc_bitfield(ctx);
|
||||
startup = dplane_ctx_get_ifp_startup(ctx);
|
||||
desc = dplane_ctx_get_ifp_desc(ctx);
|
||||
family = dplane_ctx_get_ifp_family(ctx);
|
||||
|
||||
#ifndef AF_BRIDGE
|
||||
/*
|
||||
* Work around to make free bsd happy at the moment
|
||||
*/
|
||||
#define AF_BRIDGE 7
|
||||
#endif
|
||||
if (family == AF_BRIDGE)
|
||||
return interface_bridge_handling(ctx, ifp, zif_type);
|
||||
|
||||
if (ifp == NULL ||
|
||||
!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
|
||||
/* Add interface notification from kernel */
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug(
|
||||
"RTM_NEWLINK ADD for %s(%u) vrf_id %u type %d sl_type %d master %u",
|
||||
name, ifindex, vrf_id, zif_type,
|
||||
zif_slave_type, master_ifindex);
|
||||
|
||||
if (ifp == NULL) {
|
||||
/* unknown interface */
|
||||
ifp = if_get_by_name(name, vrf_id, NULL);
|
||||
} else {
|
||||
/* pre-configured interface, learnt now */
|
||||
if (ifp->vrf->vrf_id != vrf_id)
|
||||
if_update_to_new_vrf(ifp, vrf_id);
|
||||
}
|
||||
|
||||
/* Update interface information. */
|
||||
set_ifindex(ifp, ifindex, zns);
|
||||
ifp->flags = flags;
|
||||
ifp->mtu6 = ifp->mtu = mtu;
|
||||
ifp->metric = 0;
|
||||
ifp->speed = kernel_get_speed(ifp, NULL);
|
||||
ifp->ptm_status = ZEBRA_PTM_STATUS_UNKNOWN;
|
||||
|
||||
/* Set interface type */
|
||||
zebra_if_set_ziftype(ifp, zif_type, zif_slave_type);
|
||||
if (IS_ZEBRA_IF_VRF(ifp))
|
||||
SET_FLAG(ifp->status,
|
||||
ZEBRA_INTERFACE_VRF_LOOPBACK);
|
||||
|
||||
/* Update link. */
|
||||
zebra_if_update_link(ifp, link_ifindex, link_nsid);
|
||||
|
||||
/*
|
||||
* Just set the @link/lower-device ifindex. During
|
||||
* nldump interfaces are not ordered in any fashion so
|
||||
* we may end up getting upper devices before lower
|
||||
* devices. We will setup the real linkage once the dump
|
||||
* is complete.
|
||||
*/
|
||||
zif = (struct zebra_if *)ifp->info;
|
||||
zif->link_ifindex = link_ifindex;
|
||||
|
||||
ifp->ll_type = dplane_ctx_get_ifp_zltype(ctx);
|
||||
interface_update_hw_addr(ctx, ifp);
|
||||
|
||||
/* Inform clients, install any configured addresses. */
|
||||
if_add_update(ifp);
|
||||
|
||||
/*
|
||||
* Extract and save L2 interface information, take
|
||||
* additional actions.
|
||||
*/
|
||||
interface_update_l2info(ctx, ifp, zif_type, 1,
|
||||
link_nsid);
|
||||
if (IS_ZEBRA_IF_BOND(ifp))
|
||||
zebra_l2if_update_bond(ifp, true);
|
||||
if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp))
|
||||
zebra_l2if_update_bridge_slave(
|
||||
ifp, bridge_ifindex, ns_id,
|
||||
ZEBRA_BRIDGE_NO_ACTION);
|
||||
else if (IS_ZEBRA_IF_BOND_SLAVE(ifp))
|
||||
zebra_l2if_update_bond_slave(ifp, bond_ifindex,
|
||||
!!bypass);
|
||||
|
||||
if (protodown_set) {
|
||||
interface_if_protodown(ifp, protodown,
|
||||
rc_bitfield);
|
||||
if (startup)
|
||||
if_sweep_protodown(zif);
|
||||
}
|
||||
|
||||
if (IS_ZEBRA_IF_BRIDGE(ifp)) {
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug(
|
||||
"RTM_NEWLINK ADD for %s(%u), vlan-aware %d",
|
||||
name, ifp->ifindex,
|
||||
IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(
|
||||
zif));
|
||||
}
|
||||
} else if (ifp->vrf->vrf_id != vrf_id) {
|
||||
/* VRF change for an interface. */
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug(
|
||||
"RTM_NEWLINK vrf-change for %s(%u) vrf_id %u -> %u",
|
||||
name, ifp->ifindex, ifp->vrf->vrf_id,
|
||||
vrf_id);
|
||||
|
||||
if_handle_vrf_change(ifp, vrf_id);
|
||||
} else {
|
||||
bool was_bridge_slave, was_bond_slave;
|
||||
uint8_t chgflags = ZEBRA_BRIDGE_NO_ACTION;
|
||||
|
||||
zif = ifp->info;
|
||||
|
||||
/* Interface update. */
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug(
|
||||
"RTM_NEWLINK update for %s(%u) sl_type %d master %u",
|
||||
name, ifp->ifindex, zif_slave_type,
|
||||
master_ifindex);
|
||||
|
||||
set_ifindex(ifp, ifindex, zns);
|
||||
ifp->mtu6 = ifp->mtu = mtu;
|
||||
ifp->metric = 0;
|
||||
|
||||
/*
|
||||
* Update interface type - NOTE: Only slave_type can
|
||||
* change.
|
||||
*/
|
||||
was_bridge_slave = IS_ZEBRA_IF_BRIDGE_SLAVE(ifp);
|
||||
was_bond_slave = IS_ZEBRA_IF_BOND_SLAVE(ifp);
|
||||
zebra_if_set_ziftype(ifp, zif_type, zif_slave_type);
|
||||
|
||||
memcpy(old_hw_addr, ifp->hw_addr, INTERFACE_HWADDR_MAX);
|
||||
|
||||
/* Update link. */
|
||||
zebra_if_update_link(ifp, link_ifindex, link_nsid);
|
||||
|
||||
ifp->ll_type = dplane_ctx_get_ifp_zltype(ctx);
|
||||
interface_update_hw_addr(ctx, ifp);
|
||||
|
||||
if (protodown_set)
|
||||
interface_if_protodown(ifp, protodown,
|
||||
rc_bitfield);
|
||||
|
||||
if (if_is_no_ptm_operative(ifp)) {
|
||||
bool is_up = if_is_operative(ifp);
|
||||
|
||||
ifp->flags = flags;
|
||||
if (!if_is_no_ptm_operative(ifp) ||
|
||||
CHECK_FLAG(zif->flags,
|
||||
ZIF_FLAG_PROTODOWN)) {
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug(
|
||||
"Intf %s(%u) has gone DOWN",
|
||||
name, ifp->ifindex);
|
||||
if_down(ifp);
|
||||
rib_update(RIB_UPDATE_KERNEL);
|
||||
} else if (if_is_operative(ifp)) {
|
||||
bool mac_updated = false;
|
||||
|
||||
/*
|
||||
* Must notify client daemons of new
|
||||
* interface status.
|
||||
*/
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug(
|
||||
"Intf %s(%u) PTM up, notifying clients",
|
||||
name, ifp->ifindex);
|
||||
if_up(ifp, !is_up);
|
||||
|
||||
/*
|
||||
* Update EVPN VNI when SVI MAC change
|
||||
*/
|
||||
if (memcmp(old_hw_addr, ifp->hw_addr,
|
||||
INTERFACE_HWADDR_MAX))
|
||||
mac_updated = true;
|
||||
if (IS_ZEBRA_IF_VLAN(ifp) &&
|
||||
mac_updated) {
|
||||
struct interface *link_if;
|
||||
|
||||
link_if = if_lookup_by_index_per_ns(
|
||||
zebra_ns_lookup(
|
||||
NS_DEFAULT),
|
||||
link_ifindex);
|
||||
if (link_if)
|
||||
zebra_vxlan_svi_up(
|
||||
ifp, link_if);
|
||||
} else if (mac_updated &&
|
||||
IS_ZEBRA_IF_BRIDGE(ifp)) {
|
||||
zlog_debug(
|
||||
"Intf %s(%u) bridge changed MAC address",
|
||||
name, ifp->ifindex);
|
||||
chgflags =
|
||||
ZEBRA_BRIDGE_MASTER_MAC_CHANGE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ifp->flags = flags;
|
||||
if (if_is_operative(ifp) &&
|
||||
!CHECK_FLAG(zif->flags,
|
||||
ZIF_FLAG_PROTODOWN)) {
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug(
|
||||
"Intf %s(%u) has come UP",
|
||||
name, ifp->ifindex);
|
||||
if_up(ifp, true);
|
||||
if (IS_ZEBRA_IF_BRIDGE(ifp))
|
||||
chgflags =
|
||||
ZEBRA_BRIDGE_MASTER_UP;
|
||||
} else {
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug(
|
||||
"Intf %s(%u) has gone DOWN",
|
||||
name, ifp->ifindex);
|
||||
if_down(ifp);
|
||||
rib_update(RIB_UPDATE_KERNEL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract and save L2 interface information, take
|
||||
* additional actions.
|
||||
*/
|
||||
interface_update_l2info(ctx, ifp, zif_type, 0,
|
||||
link_nsid);
|
||||
if (IS_ZEBRA_IF_BRIDGE(ifp))
|
||||
zebra_l2if_update_bridge(ifp, chgflags);
|
||||
if (IS_ZEBRA_IF_BOND(ifp))
|
||||
zebra_l2if_update_bond(ifp, true);
|
||||
if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp) || was_bridge_slave)
|
||||
zebra_l2if_update_bridge_slave(
|
||||
ifp, bridge_ifindex, ns_id, chgflags);
|
||||
else if (IS_ZEBRA_IF_BOND_SLAVE(ifp) || was_bond_slave)
|
||||
zebra_l2if_update_bond_slave(ifp, bond_ifindex,
|
||||
!!bypass);
|
||||
if (IS_ZEBRA_IF_BRIDGE(ifp)) {
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug(
|
||||
"RTM_NEWLINK update for %s(%u), vlan-aware %d",
|
||||
name, ifp->ifindex,
|
||||
IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(
|
||||
zif));
|
||||
}
|
||||
}
|
||||
|
||||
zif = ifp->info;
|
||||
if (zif) {
|
||||
XFREE(MTYPE_ZIF_DESC, zif->desc);
|
||||
if (desc[0])
|
||||
zif->desc = XSTRDUP(MTYPE_ZIF_DESC, desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void zebra_if_dplane_result(struct zebra_dplane_ctx *ctx)
|
||||
{
|
||||
struct zebra_ns *zns;
|
||||
|
@ -1510,17 +2267,6 @@ void zebra_if_dplane_result(struct zebra_dplane_ctx *ctx)
|
|||
}
|
||||
|
||||
ifp = if_lookup_by_index_per_ns(zns, ifindex);
|
||||
if (ifp == NULL) {
|
||||
if (op != DPLANE_OP_INTF_NETCONFIG ||
|
||||
(ifindex != -1 && ifindex != -2)) {
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug(
|
||||
"%s: can't find ifp at nsid %u index %d",
|
||||
__func__, ns_id, ifindex);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch (op) {
|
||||
case DPLANE_OP_INTF_ADDR_ADD:
|
||||
|
@ -1531,7 +2277,15 @@ void zebra_if_dplane_result(struct zebra_dplane_ctx *ctx)
|
|||
case DPLANE_OP_INTF_INSTALL:
|
||||
case DPLANE_OP_INTF_UPDATE:
|
||||
case DPLANE_OP_INTF_DELETE:
|
||||
zebra_if_update_ctx(ctx, ifp);
|
||||
/*
|
||||
* Queued from the dplane means it is something
|
||||
* that we need to handle( create/delete the
|
||||
* interface as needed )
|
||||
*/
|
||||
if (dp_res == ZEBRA_DPLANE_REQUEST_QUEUED)
|
||||
zebra_if_dplane_ifp_handling(ctx);
|
||||
else
|
||||
zebra_if_update_ctx(ctx, ifp);
|
||||
break;
|
||||
|
||||
case DPLANE_OP_INTF_NETCONFIG:
|
||||
|
|
|
@ -398,7 +398,7 @@ static int netlink_information_fetch(struct nlmsghdr *h, ns_id_t ns_id,
|
|||
case RTM_NEWLINK:
|
||||
return netlink_link_change(h, ns_id, startup);
|
||||
case RTM_DELLINK:
|
||||
return netlink_link_change(h, ns_id, startup);
|
||||
return 0;
|
||||
case RTM_NEWNEIGH:
|
||||
case RTM_DELNEIGH:
|
||||
case RTM_GETNEIGH:
|
||||
|
@ -474,6 +474,7 @@ static int dplane_netlink_information_fetch(struct nlmsghdr *h, ns_id_t ns_id,
|
|||
|
||||
case RTM_NEWLINK:
|
||||
case RTM_DELLINK:
|
||||
return netlink_link_change(h, ns_id, startup);
|
||||
|
||||
default:
|
||||
break;
|
||||
|
@ -1169,7 +1170,6 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int),
|
|||
h->nlmsg_type, h->nlmsg_len,
|
||||
h->nlmsg_seq, h->nlmsg_pid);
|
||||
|
||||
|
||||
/*
|
||||
* Ignore messages that maybe sent from
|
||||
* other actors besides the kernel
|
||||
|
@ -1778,17 +1778,11 @@ void kernel_init(struct zebra_ns *zns)
|
|||
* groups are added further below after SOL_NETLINK is verified to
|
||||
* exist.
|
||||
*/
|
||||
groups = RTMGRP_LINK |
|
||||
RTMGRP_IPV4_ROUTE |
|
||||
RTMGRP_IPV4_IFADDR |
|
||||
RTMGRP_IPV6_ROUTE |
|
||||
RTMGRP_IPV6_IFADDR |
|
||||
RTMGRP_IPV4_MROUTE |
|
||||
RTMGRP_NEIGH |
|
||||
((uint32_t) 1 << (RTNLGRP_IPV4_RULE - 1)) |
|
||||
((uint32_t) 1 << (RTNLGRP_IPV6_RULE - 1)) |
|
||||
((uint32_t) 1 << (RTNLGRP_NEXTHOP - 1)) |
|
||||
((uint32_t) 1 << (RTNLGRP_TC - 1));
|
||||
groups = RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_ROUTE | RTMGRP_IPV4_MROUTE |
|
||||
RTMGRP_NEIGH | ((uint32_t)1 << (RTNLGRP_IPV4_RULE - 1)) |
|
||||
((uint32_t)1 << (RTNLGRP_IPV6_RULE - 1)) |
|
||||
((uint32_t)1 << (RTNLGRP_NEXTHOP - 1)) |
|
||||
((uint32_t)1 << (RTNLGRP_TC - 1));
|
||||
|
||||
dplane_groups = (RTMGRP_LINK |
|
||||
RTMGRP_IPV4_IFADDR |
|
||||
|
|
|
@ -1468,6 +1468,14 @@ static void routing_socket(struct zebra_ns *zns)
|
|||
event_add_read(zrouter.master, kernel_read, NULL, routing_sock, NULL);
|
||||
}
|
||||
|
||||
void interface_list_second(struct zebra_ns *zns)
|
||||
{
|
||||
}
|
||||
|
||||
void interface_list_tunneldump(struct zebra_ns *zns)
|
||||
{
|
||||
}
|
||||
|
||||
/* Exported interface function. This function simply calls
|
||||
routing_socket (). */
|
||||
void kernel_init(struct zebra_ns *zns)
|
||||
|
|
|
@ -84,6 +84,8 @@ extern int kernel_get_ipmr_sg_stats(struct zebra_vrf *zvrf, void *mroute);
|
|||
* state.
|
||||
*/
|
||||
extern void interface_list(struct zebra_ns *zns);
|
||||
extern void interface_list_tunneldump(struct zebra_ns *zns);
|
||||
extern void interface_list_second(struct zebra_ns *zns);
|
||||
extern void kernel_init(struct zebra_ns *zns);
|
||||
extern void kernel_terminate(struct zebra_ns *zns, bool complete);
|
||||
extern void macfdb_read(struct zebra_ns *zns);
|
||||
|
|
|
@ -400,6 +400,7 @@ int netlink_rules_read(struct zebra_ns *zns)
|
|||
|
||||
ret = netlink_parse_info(netlink_rule_change, &zns->netlink_cmd,
|
||||
&dp_info, 0, true);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -409,6 +409,19 @@ uint8_t dplane_ctx_get_ifp_family(const struct zebra_dplane_ctx *ctx);
|
|||
struct zebra_vxlan_vni_array;
|
||||
void dplane_ctx_set_ifp_vxlan_vni_array(struct zebra_dplane_ctx *ctx,
|
||||
struct zebra_vxlan_vni_array *vniarray);
|
||||
|
||||
/*
|
||||
* These defines mirror the values for bridge values in linux
|
||||
* at this point since we only have a linux implementation
|
||||
* we don't need to do any type of translation. Let's just
|
||||
* pass these through and use them
|
||||
*/
|
||||
#define DPLANE_BRIDGE_VLAN_INFO_PVID \
|
||||
(1 << 1) /* VLAN is PVID, ingress untagged */
|
||||
#define DPLANE_BRIDGE_VLAN_INFO_RANGE_BEGIN \
|
||||
(1 << 3) /* VLAN is start of vlan range */
|
||||
#define DPLANE_BRIDGE_VLAN_INFO_RANGE_END \
|
||||
(1 << 4) /* VLAN is end of vlan range */
|
||||
const struct zebra_vxlan_vni_array *
|
||||
dplane_ctx_get_ifp_vxlan_vni_array(const struct zebra_dplane_ctx *ctx);
|
||||
struct zebra_dplane_bridge_vlan_info {
|
||||
|
|
|
@ -244,7 +244,7 @@ void zebra_l2if_update_bond(struct interface *ifp, bool add)
|
|||
* map slaves (if any) to the bridge.
|
||||
*/
|
||||
void zebra_l2_bridge_add_update(struct interface *ifp,
|
||||
struct zebra_l2info_bridge *bridge_info)
|
||||
const struct zebra_l2info_bridge *bridge_info)
|
||||
{
|
||||
struct zebra_if *zif;
|
||||
struct zebra_l2_bridge_if *br;
|
||||
|
@ -283,7 +283,7 @@ void zebra_l2if_update_bridge(struct interface *ifp, uint8_t chgflags)
|
|||
* VLAN Id and this cannot change.
|
||||
*/
|
||||
void zebra_l2_vlanif_update(struct interface *ifp,
|
||||
struct zebra_l2info_vlan *vlan_info)
|
||||
const struct zebra_l2info_vlan *vlan_info)
|
||||
{
|
||||
struct zebra_if *zif;
|
||||
|
||||
|
@ -300,7 +300,7 @@ void zebra_l2_vlanif_update(struct interface *ifp,
|
|||
* clients about GRE information.
|
||||
*/
|
||||
void zebra_l2_greif_add_update(struct interface *ifp,
|
||||
struct zebra_l2info_gre *gre_info, int add)
|
||||
const struct zebra_l2info_gre *gre_info, int add)
|
||||
{
|
||||
struct zebra_if *zif;
|
||||
struct in_addr old_vtep_ip;
|
||||
|
@ -327,7 +327,8 @@ void zebra_l2_greif_add_update(struct interface *ifp,
|
|||
* IP and VLAN mapping, but the latter is handled separately.
|
||||
*/
|
||||
void zebra_l2_vxlanif_add_update(struct interface *ifp,
|
||||
struct zebra_l2info_vxlan *vxlan_info, int add)
|
||||
const struct zebra_l2info_vxlan *vxlan_info,
|
||||
int add)
|
||||
{
|
||||
struct zebra_if *zif;
|
||||
uint16_t chgflags = 0;
|
||||
|
|
|
@ -80,6 +80,12 @@ struct zebra_vxlan_vni {
|
|||
vni_t vni; /* VNI */
|
||||
vlanid_t access_vlan; /* Access VLAN - for VLAN-aware bridge. */
|
||||
struct in_addr mcast_grp;
|
||||
uint16_t flags;
|
||||
};
|
||||
|
||||
struct zebra_vxlan_vni_array {
|
||||
uint16_t count;
|
||||
struct zebra_vxlan_vni vnis[0];
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -159,17 +165,19 @@ extern void zebra_l2_map_slave_to_bridge(struct zebra_l2info_brslave *br_slave,
|
|||
struct zebra_ns *zns);
|
||||
extern void
|
||||
zebra_l2_unmap_slave_from_bridge(struct zebra_l2info_brslave *br_slave);
|
||||
extern void zebra_l2_bridge_add_update(struct interface *ifp,
|
||||
struct zebra_l2info_bridge *bridge_info);
|
||||
extern void
|
||||
zebra_l2_bridge_add_update(struct interface *ifp,
|
||||
const struct zebra_l2info_bridge *bridge_info);
|
||||
extern void zebra_l2_bridge_del(struct interface *ifp);
|
||||
extern void zebra_l2_vlanif_update(struct interface *ifp,
|
||||
struct zebra_l2info_vlan *vlan_info);
|
||||
const struct zebra_l2info_vlan *vlan_info);
|
||||
extern void zebra_l2_greif_add_update(struct interface *ifp,
|
||||
struct zebra_l2info_gre *vxlan_info,
|
||||
const struct zebra_l2info_gre *vxlan_info,
|
||||
int add);
|
||||
extern void zebra_l2_vxlanif_add_update(struct interface *ifp,
|
||||
struct zebra_l2info_vxlan *vxlan_info,
|
||||
int add);
|
||||
extern void
|
||||
zebra_l2_vxlanif_add_update(struct interface *ifp,
|
||||
const struct zebra_l2info_vxlan *vxlan_info,
|
||||
int add);
|
||||
extern void zebra_l2_vxlanif_update_access_vlan(struct interface *ifp,
|
||||
vlanid_t access_vlan);
|
||||
extern void zebra_l2_greif_del(struct interface *ifp);
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "rib.h"
|
||||
#include "table_manager.h"
|
||||
#include "zebra_errors.h"
|
||||
#include "zebra_dplane.h"
|
||||
|
||||
extern struct zebra_privs_t zserv_privs;
|
||||
|
||||
|
@ -101,6 +102,36 @@ int zebra_ns_disabled(struct ns *ns)
|
|||
return zebra_ns_disable_internal(zns, true);
|
||||
}
|
||||
|
||||
void zebra_ns_startup_continue(struct zebra_dplane_ctx *ctx)
|
||||
{
|
||||
struct zebra_ns *zns = zebra_ns_lookup(dplane_ctx_get_ns_id(ctx));
|
||||
enum zebra_dplane_startup_notifications spot;
|
||||
|
||||
if (!zns) {
|
||||
zlog_err("%s: No Namespace associated with %u", __func__,
|
||||
dplane_ctx_get_ns_id(ctx));
|
||||
return;
|
||||
}
|
||||
|
||||
spot = dplane_ctx_get_startup_spot(ctx);
|
||||
|
||||
switch (spot) {
|
||||
case ZEBRA_DPLANE_INTERFACES_READ:
|
||||
interface_list_tunneldump(zns);
|
||||
break;
|
||||
case ZEBRA_DPLANE_TUNNELS_READ:
|
||||
interface_list_second(zns);
|
||||
break;
|
||||
case ZEBRA_DPLANE_ADDRESSES_READ:
|
||||
route_read(zns);
|
||||
|
||||
vlan_read(zns);
|
||||
kernel_read_pbr_rules(zns);
|
||||
kernel_read_tc_qdisc(zns);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Do global enable actions - open sockets, read kernel config etc. */
|
||||
int zebra_ns_enable(ns_id_t ns_id, void **info)
|
||||
{
|
||||
|
@ -111,11 +142,6 @@ int zebra_ns_enable(ns_id_t ns_id, void **info)
|
|||
kernel_init(zns);
|
||||
zebra_dplane_ns_enable(zns, true);
|
||||
interface_list(zns);
|
||||
route_read(zns);
|
||||
|
||||
vlan_read(zns);
|
||||
kernel_read_pbr_rules(zns);
|
||||
kernel_read_tc_qdisc(zns);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -68,6 +68,8 @@ int zebra_ns_final_shutdown(struct ns *ns,
|
|||
void **param_out __attribute__((unused)));
|
||||
int zebra_ns_config_write(struct vty *vty, struct ns *ns);
|
||||
|
||||
void zebra_ns_startup_continue(struct zebra_dplane_ctx *ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -4862,7 +4862,9 @@ static void rib_process_dplane_results(struct event *thread)
|
|||
case DPLANE_OP_NEIGH_TABLE_UPDATE:
|
||||
case DPLANE_OP_GRE_SET:
|
||||
case DPLANE_OP_NONE:
|
||||
break;
|
||||
case DPLANE_OP_STARTUP_STAGE:
|
||||
zebra_ns_startup_continue(ctx);
|
||||
break;
|
||||
|
||||
} /* Dispatch by op code */
|
||||
|
|
Loading…
Reference in a new issue