summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--zebra/if_netlink.c35
-rw-r--r--zebra/interface.c11
-rw-r--r--zebra/zebra_l2.h4
3 files changed, 46 insertions, 4 deletions
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c
index 429bb968a5..1f9a5db597 100644
--- a/zebra/if_netlink.c
+++ b/zebra/if_netlink.c
@@ -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);
diff --git a/zebra/interface.c b/zebra/interface.c
index 9a248ba5d1..b2a309be9e 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -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");
}
diff --git a/zebra/zebra_l2.h b/zebra/zebra_l2.h
index d9f0eec3f8..23875331f7 100644
--- a/zebra/zebra_l2.h
+++ b/zebra/zebra_l2.h
@@ -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 {