summaryrefslogtreecommitdiff
path: root/zebra/if_netlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/if_netlink.c')
-rw-r--r--zebra/if_netlink.c136
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;
}