mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-07 11:25:41 +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/if_netlink.h"
|
||||||
#include "zebra/zebra_errors.h"
|
#include "zebra/zebra_errors.h"
|
||||||
#include "zebra/zebra_vxlan.h"
|
#include "zebra/zebra_vxlan.h"
|
||||||
|
#include "zebra/zebra_evpn_mh.h"
|
||||||
|
|
||||||
extern struct zebra_privs_t zserv_privs;
|
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,
|
static void netlink_determine_zebra_iftype(const char *kind,
|
||||||
zebra_iftype_t *zif_type)
|
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,
|
static int netlink_bridge_interface(struct nlmsghdr *h, int len, ns_id_t ns_id,
|
||||||
int startup)
|
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 ifinfomsg *ifi;
|
||||||
struct rtattr *tb[IFLA_MAX + 1];
|
struct rtattr *tb[IFLA_MAX + 1];
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
struct rtattr *aftb[IFLA_BRIDGE_MAX + 1];
|
struct zebra_if *zif;
|
||||||
struct {
|
struct rtattr *af_spec;
|
||||||
uint16_t flags;
|
|
||||||
uint16_t vid;
|
|
||||||
} * vinfo;
|
|
||||||
vlanid_t access_vlan;
|
|
||||||
|
|
||||||
/* Fetch name and ifindex */
|
/* Fetch name and ifindex */
|
||||||
ifi = NLMSG_DATA(h);
|
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);
|
ifi->ifi_index);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!IS_ZEBRA_IF_VXLAN(ifp))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* We are only interested in the access VLAN i.e., AF_SPEC */
|
/* We are only interested in the access VLAN i.e., AF_SPEC */
|
||||||
if (!tb[IFLA_AF_SPEC])
|
af_spec = tb[IFLA_AF_SPEC];
|
||||||
return 0;
|
if (!af_spec)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* There is a 1-to-1 mapping of VLAN to VxLAN - hence
|
if (IS_ZEBRA_IF_VXLAN(ifp))
|
||||||
* only 1 access VLAN is accepted.
|
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));
|
zif = (struct zebra_if *)ifp->info;
|
||||||
parse_rtattr_nested(aftb, IFLA_BRIDGE_MAX, tb[IFLA_AF_SPEC]);
|
if (bf_is_inited(zif->vlan_bitmap))
|
||||||
if (!aftb[IFLA_BRIDGE_VLAN_INFO])
|
netlink_bridge_vlan_update(ifp, af_spec);
|
||||||
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,
|
|
||||||
name, ifi->ifi_index);
|
|
||||||
zebra_l2_vxlanif_update_access_vlan(ifp, access_vlan);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user