zebra: across network namespace, vxlan remembers the link information

the link information of vxlan interface is populated in layer 2
information, as well as in layer 2 vxlan information. This information
will be used later to collect vnis that are in other network namespaces,
but where bgp evpn is enabled on main network namespaces, and those vnis
have the link information in that namespace.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
This commit is contained in:
Philippe Guibert 2019-09-24 10:44:58 +02:00
parent 0591d71e92
commit 14ddb3d9c4
3 changed files with 46 additions and 4 deletions

View File

@ -482,6 +482,7 @@ static int netlink_extract_vxlan_info(struct rtattr *link_data,
struct rtattr *attr[IFLA_VXLAN_MAX + 1];
vni_t vni_in_msg;
struct in_addr vtep_ip_in_msg;
ifindex_t ifindex_link;
memset(vxl_info, 0, sizeof(*vxl_info));
memset(attr, 0, sizeof(attr));
@ -510,6 +511,15 @@ static int netlink_extract_vxlan_info(struct rtattr *link_data,
*(struct in_addr *)RTA_DATA(attr[IFLA_VXLAN_GROUP]);
}
if (!attr[IFLA_VXLAN_LINK]) {
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug("IFLA_VXLAN_LINK missing "
"from VXLAN IF message");
} else {
ifindex_link =
*(ifindex_t *)RTA_DATA(attr[IFLA_VXLAN_LINK]);
vxl_info->ifindex_link = ifindex_link;
}
return 0;
}
@ -519,7 +529,8 @@ static int netlink_extract_vxlan_info(struct rtattr *link_data,
* its members. Likewise, for VxLAN interface.
*/
static void netlink_interface_update_l2info(struct interface *ifp,
struct rtattr *link_data, int add)
struct rtattr *link_data, int add,
ns_id_t link_nsid)
{
if (!link_data)
return;
@ -538,7 +549,12 @@ static void netlink_interface_update_l2info(struct interface *ifp,
struct zebra_l2info_vxlan vxlan_info;
netlink_extract_vxlan_info(link_data, &vxlan_info);
vxlan_info.link_nsid = link_nsid;
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);
}
}
@ -622,6 +638,7 @@ static int netlink_interface(struct nlmsghdr *h, ns_id_t ns_id, int startup)
ifindex_t link_ifindex = IFINDEX_INTERNAL;
ifindex_t bond_ifindex = IFINDEX_INTERNAL;
struct zebra_if *zif;
ns_id_t link_nsid = ns_id;
zns = zebra_ns_lookup(ns_id);
ifi = NLMSG_DATA(h);
@ -705,6 +722,9 @@ static int netlink_interface(struct nlmsghdr *h, ns_id_t ns_id, int startup)
if (tb[IFLA_LINK])
link_ifindex = *(ifindex_t *)RTA_DATA(tb[IFLA_LINK]);
if (tb[IFLA_LINK_NETNSID])
link_nsid = *(ns_id_t *)RTA_DATA(tb[IFLA_LINK_NETNSID]);
/* Add interface.
* We add by index first because in some cases such as the master
* interface, we have the index before we have the name. Fixing
@ -749,7 +769,8 @@ static int netlink_interface(struct nlmsghdr *h, ns_id_t ns_id, int startup)
/* Extract and save L2 interface information, take additional actions.
*/
netlink_interface_update_l2info(ifp, linkinfo[IFLA_INFO_DATA], 1);
netlink_interface_update_l2info(ifp, linkinfo[IFLA_INFO_DATA],
1, link_nsid);
if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp))
zebra_l2if_update_bridge_slave(ifp, bridge_ifindex);
else if (IS_ZEBRA_IF_BOND_SLAVE(ifp))
@ -1168,6 +1189,7 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
ifindex_t link_ifindex = IFINDEX_INTERNAL;
uint8_t old_hw_addr[INTERFACE_HWADDR_MAX];
struct zebra_if *zif;
ns_id_t link_nsid = ns_id;
zns = zebra_ns_lookup(ns_id);
ifi = NLMSG_DATA(h);
@ -1235,6 +1257,9 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
if (tb[IFLA_LINK])
link_ifindex = *(ifindex_t *)RTA_DATA(tb[IFLA_LINK]);
if (tb[IFLA_LINK_NETNSID])
link_nsid = *(ns_id_t *)RTA_DATA(tb[IFLA_LINK_NETNSID]);
if (tb[IFLA_IFALIAS]) {
desc = (char *)RTA_DATA(tb[IFLA_IFALIAS]);
}
@ -1319,7 +1344,8 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
/* Extract and save L2 interface information, take
* additional actions. */
netlink_interface_update_l2info(
ifp, linkinfo[IFLA_INFO_DATA], 1);
ifp, linkinfo[IFLA_INFO_DATA],
1, link_nsid);
if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp))
zebra_l2if_update_bridge_slave(ifp,
bridge_ifindex);
@ -1421,7 +1447,8 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
/* Extract and save L2 interface information, take
* additional actions. */
netlink_interface_update_l2info(
ifp, linkinfo[IFLA_INFO_DATA], 0);
ifp, linkinfo[IFLA_INFO_DATA],
0, link_nsid);
if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp) || was_bridge_slave)
zebra_l2if_update_bridge_slave(ifp,
bridge_ifindex);

View File

@ -1488,6 +1488,17 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp)
if (vxlan_info->mcast_grp.s_addr != INADDR_ANY)
vty_out(vty, " Mcast Group %s",
inet_ntoa(vxlan_info->mcast_grp));
if (vxlan_info->ifindex_link &&
(vxlan_info->link_nsid != NS_UNKNOWN)) {
struct interface *ifp;
ifp = if_lookup_by_index_per_ns(
zebra_ns_lookup(vxlan_info->link_nsid),
vxlan_info->ifindex_link);
vty_out(vty, " Link Interface %s",
ifp == NULL ? "Unknown" :
ifp->name);
}
vty_out(vty, "\n");
}

View File

@ -55,6 +55,10 @@ struct zebra_l2info_vxlan {
struct in_addr vtep_ip; /* Local tunnel IP */
vlanid_t access_vlan; /* Access VLAN - for VLAN-aware bridge. */
struct in_addr mcast_grp;
ifindex_t ifindex_link; /* Interface index of interface
* linked with VXLAN
*/
ns_id_t link_nsid;
};
struct zebra_l2info_bondslave {