mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-03 10:31:09 +00:00
zebra: triggers for maintaining a list of access vlans per-ES
The linux kernel sends the VLAN list per-access port as bitmap. This needs to be translated into a per-ES VNI list for generation of EAD-EVI routes. Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
This commit is contained in:
parent
ce5160c081
commit
42b5663925
@ -70,6 +70,7 @@
|
||||
#include "zebra/if_netlink.h"
|
||||
#include "zebra/zebra_errors.h"
|
||||
#include "zebra/zebra_vxlan.h"
|
||||
#include "zebra/zebra_evpn_mh.h"
|
||||
|
||||
extern struct zebra_privs_t zserv_privs;
|
||||
|
||||
@ -245,6 +246,26 @@ static enum zebra_link_type netlink_to_zebra_link_type(unsigned int hwt)
|
||||
}
|
||||
}
|
||||
|
||||
static inline void zebra_if_set_ziftype(struct interface *ifp,
|
||||
zebra_iftype_t zif_type,
|
||||
zebra_slave_iftype_t 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 netlink_determine_zebra_iftype(const char *kind,
|
||||
zebra_iftype_t *zif_type)
|
||||
{
|
||||
@ -557,6 +578,74 @@ static void netlink_interface_update_l2info(struct interface *ifp,
|
||||
}
|
||||
}
|
||||
|
||||
static int netlink_bridge_vxlan_update(struct interface *ifp,
|
||||
struct rtattr *af_spec)
|
||||
{
|
||||
struct rtattr *aftb[IFLA_BRIDGE_MAX + 1];
|
||||
struct bridge_vlan_info *vinfo;
|
||||
vlanid_t access_vlan;
|
||||
|
||||
/* There is a 1-to-1 mapping of VLAN to VxLAN - hence
|
||||
* only 1 access VLAN is accepted.
|
||||
*/
|
||||
memset(aftb, 0, sizeof(aftb));
|
||||
parse_rtattr_nested(aftb, IFLA_BRIDGE_MAX, af_spec);
|
||||
if (!aftb[IFLA_BRIDGE_VLAN_INFO])
|
||||
return 0;
|
||||
|
||||
vinfo = RTA_DATA(aftb[IFLA_BRIDGE_VLAN_INFO]);
|
||||
if (!(vinfo->flags & BRIDGE_VLAN_INFO_PVID))
|
||||
return 0;
|
||||
|
||||
access_vlan = (vlanid_t)vinfo->vid;
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug("Access VLAN %u for VxLAN IF %s(%u)", access_vlan,
|
||||
ifp->name, ifp->ifindex);
|
||||
zebra_l2_vxlanif_update_access_vlan(ifp, access_vlan);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void netlink_bridge_vlan_update(struct interface *ifp,
|
||||
struct rtattr *af_spec)
|
||||
{
|
||||
struct rtattr *i;
|
||||
int rem;
|
||||
uint16_t vid_range_start = 0;
|
||||
struct zebra_if *zif;
|
||||
bitfield_t old_vlan_bitmap;
|
||||
struct bridge_vlan_info *vinfo;
|
||||
|
||||
zif = (struct zebra_if *)ifp->info;
|
||||
|
||||
/* 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);
|
||||
|
||||
for (i = RTA_DATA(af_spec), rem = RTA_PAYLOAD(af_spec);
|
||||
RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
|
||||
|
||||
if (i->rta_type != IFLA_BRIDGE_VLAN_INFO)
|
||||
continue;
|
||||
|
||||
vinfo = RTA_DATA(i);
|
||||
|
||||
if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) {
|
||||
vid_range_start = vinfo->vid;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(vinfo->flags & BRIDGE_VLAN_INFO_RANGE_END))
|
||||
vid_range_start = vinfo->vid;
|
||||
|
||||
zebra_vlan_bitmap_compute(ifp, vid_range_start, vinfo->vid);
|
||||
}
|
||||
|
||||
zebra_vlan_mbr_re_eval(ifp, old_vlan_bitmap);
|
||||
|
||||
bf_free(old_vlan_bitmap);
|
||||
}
|
||||
|
||||
static int netlink_bridge_interface(struct nlmsghdr *h, int len, ns_id_t ns_id,
|
||||
int startup)
|
||||
{
|
||||
@ -564,12 +653,8 @@ static int netlink_bridge_interface(struct nlmsghdr *h, int len, ns_id_t ns_id,
|
||||
struct ifinfomsg *ifi;
|
||||
struct rtattr *tb[IFLA_MAX + 1];
|
||||
struct interface *ifp;
|
||||
struct rtattr *aftb[IFLA_BRIDGE_MAX + 1];
|
||||
struct {
|
||||
uint16_t flags;
|
||||
uint16_t vid;
|
||||
} * vinfo;
|
||||
vlanid_t access_vlan;
|
||||
struct zebra_if *zif;
|
||||
struct rtattr *af_spec;
|
||||
|
||||
/* Fetch name and ifindex */
|
||||
ifi = NLMSG_DATA(h);
|
||||
@ -587,30 +672,22 @@ static int netlink_bridge_interface(struct nlmsghdr *h, int len, ns_id_t ns_id,
|
||||
ifi->ifi_index);
|
||||
return 0;
|
||||
}
|
||||
if (!IS_ZEBRA_IF_VXLAN(ifp))
|
||||
return 0;
|
||||
|
||||
/* We are only interested in the access VLAN i.e., AF_SPEC */
|
||||
if (!tb[IFLA_AF_SPEC])
|
||||
return 0;
|
||||
af_spec = tb[IFLA_AF_SPEC];
|
||||
if (!af_spec)
|
||||
return 0;
|
||||
|
||||
/* There is a 1-to-1 mapping of VLAN to VxLAN - hence
|
||||
* only 1 access VLAN is accepted.
|
||||
if (IS_ZEBRA_IF_VXLAN(ifp))
|
||||
return netlink_bridge_vxlan_update(ifp, af_spec);
|
||||
|
||||
/* build vlan bitmap associated with this interface if that
|
||||
* device type is interested in the vlans
|
||||
*/
|
||||
memset(aftb, 0, sizeof(aftb));
|
||||
parse_rtattr_nested(aftb, IFLA_BRIDGE_MAX, tb[IFLA_AF_SPEC]);
|
||||
if (!aftb[IFLA_BRIDGE_VLAN_INFO])
|
||||
return 0;
|
||||
zif = (struct zebra_if *)ifp->info;
|
||||
if (bf_is_inited(zif->vlan_bitmap))
|
||||
netlink_bridge_vlan_update(ifp, af_spec);
|
||||
|
||||
vinfo = RTA_DATA(aftb[IFLA_BRIDGE_VLAN_INFO]);
|
||||
if (!(vinfo->flags & BRIDGE_VLAN_INFO_PVID))
|
||||
return 0;
|
||||
|
||||
access_vlan = (vlanid_t)vinfo->vid;
|
||||
if (IS_ZEBRA_DEBUG_KERNEL)
|
||||
zlog_debug("Access VLAN %u for VxLAN IF %s(%u)", access_vlan,
|
||||
name, ifi->ifi_index);
|
||||
zebra_l2_vxlanif_update_access_vlan(ifp, access_vlan);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user