diff options
Diffstat (limited to 'zebra/if_netlink.c')
| -rw-r--r-- | zebra/if_netlink.c | 136 |
1 files changed, 43 insertions, 93 deletions
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index 8beae125d2..62b665682f 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -1610,68 +1610,18 @@ int netlink_tunneldump_read(struct zebra_ns *zns) return 0; } -static const char *port_state2str(uint8_t state) +static uint8_t netlink_get_dplane_vlan_state(uint8_t state) { - switch (state) { - case BR_STATE_DISABLED: - return "DISABLED"; - case BR_STATE_LISTENING: - return "LISTENING"; - case BR_STATE_LEARNING: - return "LEARNING"; - case BR_STATE_FORWARDING: - return "FORWARDING"; - case BR_STATE_BLOCKING: - return "BLOCKING"; - } - - return "UNKNOWN"; -} - -static void vxlan_vni_state_change(struct zebra_if *zif, uint16_t id, - uint8_t state) -{ - struct zebra_vxlan_vni *vnip; - - vnip = zebra_vxlan_if_vlanid_vni_find(zif, id); - - if (!vnip) { - if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug( - "Cannot find VNI for VID (%u) IF %s for vlan state update", - id, zif->ifp->name); - - return; - } - - switch (state) { - case BR_STATE_FORWARDING: - zebra_vxlan_if_vni_up(zif->ifp, vnip); - break; - case BR_STATE_BLOCKING: - zebra_vxlan_if_vni_down(zif->ifp, vnip); - break; - case BR_STATE_DISABLED: - case BR_STATE_LISTENING: - case BR_STATE_LEARNING: - default: - /* Not used for anything at the moment */ - break; - } -} - -static void vlan_id_range_state_change(struct interface *ifp, uint16_t id_start, - uint16_t id_end, uint8_t state) -{ - struct zebra_if *zif; - - zif = (struct zebra_if *)ifp->info; - - if (!zif) - return; - - for (uint16_t i = id_start; i <= id_end; i++) - vxlan_vni_state_change(zif, i, state); + if (state == BR_STATE_LISTENING) + return ZEBRA_DPLANE_BR_STATE_LISTENING; + else if (state == BR_STATE_LEARNING) + return ZEBRA_DPLANE_BR_STATE_LEARNING; + else if (state == BR_STATE_FORWARDING) + return ZEBRA_DPLANE_BR_STATE_FORWARDING; + else if (state == BR_STATE_BLOCKING) + return ZEBRA_DPLANE_BR_STATE_BLOCKING; + + return ZEBRA_DPLANE_BR_STATE_DISABLED; } /** @@ -1686,7 +1636,6 @@ static void vlan_id_range_state_change(struct interface *ifp, uint16_t id_start, int netlink_vlan_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) { int len, rem; - struct interface *ifp; struct br_vlan_msg *bvm; struct bridge_vlan_info *vinfo; struct rtattr *vtb[BRIDGE_VLANDB_ENTRY_MAX + 1] = {}; @@ -1694,6 +1643,9 @@ int netlink_vlan_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) uint8_t state; uint32_t vrange; int type; + uint32_t count = 0; + struct zebra_dplane_ctx *ctx = NULL; + struct zebra_vxlan_vlan_array *vlan_array = NULL; /* We only care about state changes for now */ if (!(h->nlmsg_type == RTM_NEWVLAN)) @@ -1713,25 +1665,10 @@ int netlink_vlan_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) if (bvm->family != AF_BRIDGE) return 0; - ifp = if_lookup_by_index_per_ns(zebra_ns_lookup(ns_id), bvm->ifindex); - if (!ifp) { - zlog_debug("Cannot find bridge-vlan IF (%u) for vlan update", - bvm->ifindex); - return 0; - } - - if (!IS_ZEBRA_IF_VXLAN(ifp)) { - if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug("Ignoring non-vxlan IF (%s) for vlan update", - ifp->name); - - return 0; - } - - if (IS_ZEBRA_DEBUG_KERNEL || IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("%s %s IF %s NS %u", - nl_msg_type_to_str(h->nlmsg_type), - nl_family_to_str(bvm->family), ifp->name, ns_id); + ctx = dplane_ctx_alloc(); + dplane_ctx_set_ns_id(ctx, ns_id); + dplane_ctx_set_op(ctx, DPLANE_OP_VLAN_INSTALL); + dplane_ctx_set_vlan_ifindex(ctx, bvm->ifindex); /* Loop over "ALL" BRIDGE_VLANDB_ENTRY */ rem = len; @@ -1762,26 +1699,39 @@ int netlink_vlan_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) if (!vtb[BRIDGE_VLANDB_ENTRY_STATE]) continue; + count++; + vlan_array = + XREALLOC(MTYPE_VLAN_CHANGE_ARR, vlan_array, + sizeof(struct zebra_vxlan_vlan_array) + + count * sizeof(struct zebra_vxlan_vlan)); + + memset(&vlan_array->vlans[count - 1], 0, + sizeof(struct zebra_vxlan_vlan)); + state = *(uint8_t *)RTA_DATA(vtb[BRIDGE_VLANDB_ENTRY_STATE]); if (vtb[BRIDGE_VLANDB_ENTRY_RANGE]) vrange = *(uint32_t *)RTA_DATA( vtb[BRIDGE_VLANDB_ENTRY_RANGE]); - if (IS_ZEBRA_DEBUG_KERNEL || IS_ZEBRA_DEBUG_VXLAN) { - if (vrange) - zlog_debug("VLANDB_ENTRY: VID (%u-%u) state=%s", - vinfo->vid, vrange, - port_state2str(state)); - else - zlog_debug("VLANDB_ENTRY: VID (%u) state=%s", - vinfo->vid, port_state2str(state)); - } - - vlan_id_range_state_change( - ifp, vinfo->vid, (vrange ? vrange : vinfo->vid), state); + vlan_array->vlans[count - 1].state = + netlink_get_dplane_vlan_state(state); + vlan_array->vlans[count - 1].vid = vinfo->vid; + vlan_array->vlans[count - 1].vrange = vrange; } + if (count) { + vlan_array->count = count; + dplane_ctx_set_vxlan_vlan_array(ctx, vlan_array); + if (IS_ZEBRA_DEBUG_KERNEL || IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("RTM_NEWVLAN for ifindex %u NS %u, enqueuing for zebra main", + bvm->ifindex, ns_id); + + dplane_provider_enqueue_to_zebra(ctx); + } else + dplane_ctx_fini(&ctx); + + return 0; } |
