This repository has been archived on 2025-03-20. You can view files and clone it, but cannot push or open issues or pull requests.
sonic-buildimage/src/sonic-frr/patch/0016-zebra-Remove-duplicate-function-for-netlink-interfac.patch

302 lines
9.9 KiB
Diff

From e12ffa6871d33712b03fc2ca28de278913e95bce Mon Sep 17 00:00:00 2001
From: Donald Sharp <sharpd@nvidia.com>
Date: Thu, 13 Apr 2023 16:43:27 -0400
Subject: [PATCH] zebra: Remove duplicate function for netlink interface
changes
Turns out FRR has 2 functions one specifically for startup
and one for normal day to day operations. There were only
a couple of minor differences from what I could tell, and
where they were different the after startup functionality should
have been updated too. I cannot figure out why we have 2.
Non-startup handling of bonds appears to be incorrect
so let's fix that. Additionally the speed was not
properly being set in non-startup situations.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c
index e54fb09022..ed5b3c4a66 100644
--- a/zebra/if_netlink.c
+++ b/zebra/if_netlink.c
@@ -938,178 +938,6 @@ static void if_sweep_protodown(struct zebra_if *zif)
dplane_intf_update(zif->ifp);
}
-/*
- * Called from interface_lookup_netlink(). This function is only used
- * during bootstrap.
- */
-static int netlink_interface(struct nlmsghdr *h, ns_id_t ns_id, int startup)
-{
- int len;
- struct ifinfomsg *ifi;
- struct rtattr *tb[IFLA_MAX + 1];
- struct rtattr *linkinfo[IFLA_MAX + 1];
- struct interface *ifp;
- char *name = NULL;
- char *kind = NULL;
- char *desc = NULL;
- char *slave_kind = NULL;
- struct zebra_ns *zns = NULL;
- vrf_id_t vrf_id = VRF_DEFAULT;
- enum zebra_iftype zif_type = ZEBRA_IF_OTHER;
- enum zebra_slave_iftype zif_slave_type = ZEBRA_IF_SLAVE_NONE;
- ifindex_t bridge_ifindex = IFINDEX_INTERNAL;
- ifindex_t link_ifindex = IFINDEX_INTERNAL;
- ifindex_t bond_ifindex = IFINDEX_INTERNAL;
- struct zebra_if *zif;
- ns_id_t link_nsid = ns_id;
- uint8_t bypass = 0;
-
- frrtrace(3, frr_zebra, netlink_interface, h, ns_id, startup);
-
- zns = zebra_ns_lookup(ns_id);
- ifi = NLMSG_DATA(h);
-
- if (h->nlmsg_type != RTM_NEWLINK)
- return 0;
-
- len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifinfomsg));
- if (len < 0) {
- zlog_err(
- "%s: Message received from netlink is of a broken size: %d %zu",
- __func__, h->nlmsg_len,
- (size_t)NLMSG_LENGTH(sizeof(struct ifinfomsg)));
- return -1;
- }
-
- /* We are interested in some AF_BRIDGE notifications. */
- if (ifi->ifi_family == AF_BRIDGE)
- return netlink_bridge_interface(h, len, ns_id, startup);
-
- /* Looking up interface name. */
- memset(linkinfo, 0, sizeof(linkinfo));
- netlink_parse_rtattr_flags(tb, IFLA_MAX, IFLA_RTA(ifi), len,
- NLA_F_NESTED);
-
- /* check for wireless messages to ignore */
- if ((tb[IFLA_WIRELESS] != NULL) && (ifi->ifi_change == 0)) {
- if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug("%s: ignoring IFLA_WIRELESS message",
- __func__);
- return 0;
- }
-
- if (tb[IFLA_IFNAME] == NULL)
- return -1;
- name = (char *)RTA_DATA(tb[IFLA_IFNAME]);
-
- if (tb[IFLA_IFALIAS])
- desc = (char *)RTA_DATA(tb[IFLA_IFALIAS]);
-
- if (tb[IFLA_LINKINFO]) {
- netlink_parse_rtattr_nested(linkinfo, IFLA_INFO_MAX,
- tb[IFLA_LINKINFO]);
-
- if (linkinfo[IFLA_INFO_KIND])
- kind = RTA_DATA(linkinfo[IFLA_INFO_KIND]);
-
- if (linkinfo[IFLA_INFO_SLAVE_KIND])
- slave_kind = RTA_DATA(linkinfo[IFLA_INFO_SLAVE_KIND]);
-
- if ((slave_kind != NULL) && strcmp(slave_kind, "bond") == 0)
- netlink_determine_zebra_iftype("bond_slave", &zif_type);
- else
- netlink_determine_zebra_iftype(kind, &zif_type);
- }
-
- /* If VRF, create the VRF structure itself. */
- if (zif_type == ZEBRA_IF_VRF && !vrf_is_backend_netns()) {
- netlink_vrf_change(h, tb[IFLA_LINKINFO], ns_id, name);
- vrf_id = (vrf_id_t)ifi->ifi_index;
- }
-
- if (tb[IFLA_MASTER]) {
- if (slave_kind && (strcmp(slave_kind, "vrf") == 0)
- && !vrf_is_backend_netns()) {
- zif_slave_type = ZEBRA_IF_SLAVE_VRF;
- vrf_id = *(uint32_t *)RTA_DATA(tb[IFLA_MASTER]);
- } else if (slave_kind && (strcmp(slave_kind, "bridge") == 0)) {
- zif_slave_type = ZEBRA_IF_SLAVE_BRIDGE;
- bridge_ifindex =
- *(ifindex_t *)RTA_DATA(tb[IFLA_MASTER]);
- } else if (slave_kind && (strcmp(slave_kind, "bond") == 0)) {
- zif_slave_type = ZEBRA_IF_SLAVE_BOND;
- bond_ifindex = *(ifindex_t *)RTA_DATA(tb[IFLA_MASTER]);
- bypass = netlink_parse_lacp_bypass(linkinfo);
- } else
- zif_slave_type = ZEBRA_IF_SLAVE_OTHER;
- }
- if (vrf_is_backend_netns())
- vrf_id = (vrf_id_t)ns_id;
-
- /* If linking to another interface, note it. */
- 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]);
- link_nsid = ns_id_get_absolute(ns_id, link_nsid);
- }
-
- ifp = if_get_by_name(name, vrf_id, NULL);
- set_ifindex(ifp, ifi->ifi_index, zns); /* add it to ns struct */
-
- ifp->flags = ifi->ifi_flags & 0x0000fffff;
- ifp->mtu6 = ifp->mtu = *(uint32_t *)RTA_DATA(tb[IFLA_MTU]);
- ifp->metric = 0;
- ifp->speed = get_iflink_speed(ifp, NULL);
- ifp->ptm_status = ZEBRA_PTM_STATUS_UNKNOWN;
-
- /* Set zebra interface type */
- zebra_if_set_ziftype(ifp, zif_type, zif_slave_type);
- if (IS_ZEBRA_IF_VRF(ifp))
- SET_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK);
-
- /*
- * Just set the @link/lower-device ifindex. During nldump interfaces are
- * not ordered in any fashion so we may end up getting upper devices
- * before lower devices. We will setup the real linkage once the dump
- * is complete.
- */
- zif = (struct zebra_if *)ifp->info;
- zif->link_ifindex = link_ifindex;
-
- if (desc) {
- XFREE(MTYPE_ZIF_DESC, zif->desc);
- zif->desc = XSTRDUP(MTYPE_ZIF_DESC, desc);
- }
-
- /* Hardware type and address. */
- ifp->ll_type = netlink_to_zebra_link_type(ifi->ifi_type);
-
- netlink_interface_update_hw_addr(tb, ifp);
-
- if_add_update(ifp);
-
- /* Extract and save L2 interface information, take additional actions.
- */
- netlink_interface_update_l2info(ifp, linkinfo[IFLA_INFO_DATA],
- 1, link_nsid);
- if (IS_ZEBRA_IF_BOND(ifp))
- zebra_l2if_update_bond(ifp, true);
- if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp))
- zebra_l2if_update_bridge_slave(ifp, bridge_ifindex, ns_id,
- ZEBRA_BRIDGE_NO_ACTION);
- else if (IS_ZEBRA_IF_BOND_SLAVE(ifp))
- zebra_l2if_update_bond_slave(ifp, bond_ifindex, !!bypass);
-
- if (tb[IFLA_PROTO_DOWN]) {
- netlink_proc_dplane_if_protodown(zif, tb);
- if_sweep_protodown(zif);
- }
-
- return 0;
-}
-
/* Request for specific interface or address information from the kernel */
static int netlink_request_intf_addr(struct nlsock *netlink_cmd, int family,
int type, uint32_t filter_mask)
@@ -1165,7 +993,7 @@ int interface_lookup_netlink(struct zebra_ns *zns)
ret = netlink_request_intf_addr(netlink_cmd, AF_PACKET, RTM_GETLINK, 0);
if (ret < 0)
return ret;
- ret = netlink_parse_info(netlink_interface, netlink_cmd, &dp_info, 0,
+ ret = netlink_parse_info(netlink_link_change, netlink_cmd, &dp_info, 0,
true);
if (ret < 0)
return ret;
@@ -1175,7 +1003,7 @@ int interface_lookup_netlink(struct zebra_ns *zns)
RTEXT_FILTER_BRVLAN);
if (ret < 0)
return ret;
- ret = netlink_parse_info(netlink_interface, netlink_cmd, &dp_info, 0,
+ ret = netlink_parse_info(netlink_link_change, netlink_cmd, &dp_info, 0,
true);
if (ret < 0)
return ret;
@@ -1816,6 +1644,8 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
ifindex_t master_infindex = IFINDEX_INTERNAL;
uint8_t bypass = 0;
+ frrtrace(3, frr_zebra, netlink_interface, h, ns_id, startup);
+
zns = zebra_ns_lookup(ns_id);
ifi = NLMSG_DATA(h);
@@ -1884,7 +1714,10 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
if (linkinfo[IFLA_INFO_SLAVE_KIND])
slave_kind = RTA_DATA(linkinfo[IFLA_INFO_SLAVE_KIND]);
- netlink_determine_zebra_iftype(kind, &zif_type);
+ if ((slave_kind != NULL) && strcmp(slave_kind, "bond") == 0)
+ netlink_determine_zebra_iftype("bond_slave", &zif_type);
+ else
+ netlink_determine_zebra_iftype(kind, &zif_type);
}
/* If linking to another interface, note it. */
@@ -1961,6 +1794,7 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
}
ifp->mtu6 = ifp->mtu = *(int *)RTA_DATA(tb[IFLA_MTU]);
ifp->metric = 0;
+ ifp->speed = get_iflink_speed(ifp, NULL);
ifp->ptm_status = ZEBRA_PTM_STATUS_UNKNOWN;
/* Set interface type */
@@ -1972,6 +1806,16 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
/* Update link. */
zebra_if_update_link(ifp, link_ifindex, link_nsid);
+ /*
+ * Just set the @link/lower-device ifindex. During
+ * nldump interfaces are not ordered in any fashion so
+ * we may end up getting upper devices before lower
+ * devices. We will setup the real linkage once the dump
+ * is complete.
+ */
+ zif = (struct zebra_if *)ifp->info;
+ zif->link_ifindex = link_ifindex;
+
ifp->ll_type =
netlink_to_zebra_link_type(ifi->ifi_type);
netlink_interface_update_hw_addr(tb, ifp);
@@ -1984,6 +1828,8 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
netlink_interface_update_l2info(
ifp, linkinfo[IFLA_INFO_DATA],
1, link_nsid);
+ if (IS_ZEBRA_IF_BOND(ifp))
+ zebra_l2if_update_bond(ifp, true);
if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp))
zebra_l2if_update_bridge_slave(
ifp, bridge_ifindex, ns_id,
@@ -1992,10 +1838,12 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
zebra_l2if_update_bond_slave(ifp, bond_ifindex,
!!bypass);
- if (tb[IFLA_PROTO_DOWN])
+ if (tb[IFLA_PROTO_DOWN]) {
netlink_proc_dplane_if_protodown(ifp->info, tb);
+ if (startup)
+ if_sweep_protodown(zif);
+ }
if (IS_ZEBRA_IF_BRIDGE(ifp)) {
- zif = ifp->info;
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug(
"RTM_NEWLINK ADD for %s(%u), vlan-aware %d",
@@ -2329,7 +2177,7 @@ int netlink_tunneldump_read(struct zebra_ns *zns)
if (ret < 0)
return ret;
- ret = netlink_parse_info(netlink_interface, netlink_cmd,
+ ret = netlink_parse_info(netlink_link_change, netlink_cmd,
&dp_info, 0, true);
if (ret < 0)
--
2.17.1