summaryrefslogtreecommitdiffstats
path: root/zebra/if_netlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/if_netlink.c')
-rw-r--r--zebra/if_netlink.c1969
1 files changed, 996 insertions, 973 deletions
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c
index d0907a267..acec2db52 100644
--- a/zebra/if_netlink.c
+++ b/zebra/if_netlink.c
@@ -66,143 +66,192 @@
/* Note: on netlink systems, there should be a 1-to-1 mapping between interface
names and ifindex values. */
-static void
-set_ifindex(struct interface *ifp, ifindex_t ifi_index, struct zebra_ns *zns)
+static void set_ifindex(struct interface *ifp, ifindex_t ifi_index,
+ struct zebra_ns *zns)
{
- struct interface *oifp;
-
- if (((oifp = if_lookup_by_index_per_ns (zns, ifi_index)) != NULL) && (oifp != ifp))
- {
- if (ifi_index == IFINDEX_INTERNAL)
- zlog_err("Netlink is setting interface %s ifindex to reserved "
- "internal value %u", ifp->name, ifi_index);
- else
- {
- if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug("interface index %d was renamed from %s to %s",
- ifi_index, oifp->name, ifp->name);
- if (if_is_up(oifp))
- zlog_err("interface rename detected on up interface: index %d "
- "was renamed from %s to %s, results are uncertain!",
- ifi_index, oifp->name, ifp->name);
- if_delete_update(oifp);
- }
- }
- ifp->ifindex = ifi_index;
+ struct interface *oifp;
+
+ if (((oifp = if_lookup_by_index_per_ns(zns, ifi_index)) != NULL)
+ && (oifp != ifp)) {
+ if (ifi_index == IFINDEX_INTERNAL)
+ zlog_err(
+ "Netlink is setting interface %s ifindex to reserved "
+ "internal value %u",
+ ifp->name, ifi_index);
+ else {
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug(
+ "interface index %d was renamed from %s to %s",
+ ifi_index, oifp->name, ifp->name);
+ if (if_is_up(oifp))
+ zlog_err(
+ "interface rename detected on up interface: index %d "
+ "was renamed from %s to %s, results are uncertain!",
+ ifi_index, oifp->name, ifp->name);
+ if_delete_update(oifp);
+ }
+ }
+ ifp->ifindex = ifi_index;
}
/* Utility function to parse hardware link-layer address and update ifp */
-static void
-netlink_interface_update_hw_addr (struct rtattr **tb, struct interface *ifp)
+static void netlink_interface_update_hw_addr(struct rtattr **tb,
+ struct interface *ifp)
{
- int i;
-
- if (tb[IFLA_ADDRESS])
- {
- int hw_addr_len;
-
- hw_addr_len = RTA_PAYLOAD (tb[IFLA_ADDRESS]);
-
- if (hw_addr_len > INTERFACE_HWADDR_MAX)
- zlog_warn ("Hardware address is too large: %d", hw_addr_len);
- else
- {
- ifp->hw_addr_len = hw_addr_len;
- memcpy (ifp->hw_addr, RTA_DATA (tb[IFLA_ADDRESS]), hw_addr_len);
-
- for (i = 0; i < hw_addr_len; i++)
- if (ifp->hw_addr[i] != 0)
- break;
-
- if (i == hw_addr_len)
- ifp->hw_addr_len = 0;
- else
- ifp->hw_addr_len = hw_addr_len;
- }
- }
+ int i;
+
+ if (tb[IFLA_ADDRESS]) {
+ int hw_addr_len;
+
+ hw_addr_len = RTA_PAYLOAD(tb[IFLA_ADDRESS]);
+
+ if (hw_addr_len > INTERFACE_HWADDR_MAX)
+ zlog_warn("Hardware address is too large: %d",
+ hw_addr_len);
+ else {
+ ifp->hw_addr_len = hw_addr_len;
+ memcpy(ifp->hw_addr, RTA_DATA(tb[IFLA_ADDRESS]),
+ hw_addr_len);
+
+ for (i = 0; i < hw_addr_len; i++)
+ if (ifp->hw_addr[i] != 0)
+ break;
+
+ if (i == hw_addr_len)
+ ifp->hw_addr_len = 0;
+ else
+ ifp->hw_addr_len = hw_addr_len;
+ }
+ }
}
-static enum zebra_link_type
-netlink_to_zebra_link_type (unsigned int hwt)
+static enum zebra_link_type netlink_to_zebra_link_type(unsigned int hwt)
{
- switch (hwt)
- {
- case ARPHRD_ETHER: return ZEBRA_LLT_ETHER;
- case ARPHRD_EETHER: return ZEBRA_LLT_EETHER;
- case ARPHRD_AX25: return ZEBRA_LLT_AX25;
- case ARPHRD_PRONET: return ZEBRA_LLT_PRONET;
- case ARPHRD_IEEE802: return ZEBRA_LLT_IEEE802;
- case ARPHRD_ARCNET: return ZEBRA_LLT_ARCNET;
- case ARPHRD_APPLETLK: return ZEBRA_LLT_APPLETLK;
- case ARPHRD_DLCI: return ZEBRA_LLT_DLCI;
- case ARPHRD_ATM: return ZEBRA_LLT_ATM;
- case ARPHRD_METRICOM: return ZEBRA_LLT_METRICOM;
- case ARPHRD_IEEE1394: return ZEBRA_LLT_IEEE1394;
- case ARPHRD_EUI64: return ZEBRA_LLT_EUI64;
- case ARPHRD_INFINIBAND: return ZEBRA_LLT_INFINIBAND;
- case ARPHRD_SLIP: return ZEBRA_LLT_SLIP;
- case ARPHRD_CSLIP: return ZEBRA_LLT_CSLIP;
- case ARPHRD_SLIP6: return ZEBRA_LLT_SLIP6;
- case ARPHRD_CSLIP6: return ZEBRA_LLT_CSLIP6;
- case ARPHRD_RSRVD: return ZEBRA_LLT_RSRVD;
- case ARPHRD_ADAPT: return ZEBRA_LLT_ADAPT;
- case ARPHRD_ROSE: return ZEBRA_LLT_ROSE;
- case ARPHRD_X25: return ZEBRA_LLT_X25;
- case ARPHRD_PPP: return ZEBRA_LLT_PPP;
- case ARPHRD_CISCO: return ZEBRA_LLT_CHDLC;
- case ARPHRD_LAPB: return ZEBRA_LLT_LAPB;
- case ARPHRD_RAWHDLC: return ZEBRA_LLT_RAWHDLC;
- case ARPHRD_TUNNEL: return ZEBRA_LLT_IPIP;
- case ARPHRD_TUNNEL6: return ZEBRA_LLT_IPIP6;
- case ARPHRD_FRAD: return ZEBRA_LLT_FRAD;
- case ARPHRD_SKIP: return ZEBRA_LLT_SKIP;
- case ARPHRD_LOOPBACK: return ZEBRA_LLT_LOOPBACK;
- case ARPHRD_LOCALTLK: return ZEBRA_LLT_LOCALTLK;
- case ARPHRD_FDDI: return ZEBRA_LLT_FDDI;
- case ARPHRD_SIT: return ZEBRA_LLT_SIT;
- case ARPHRD_IPDDP: return ZEBRA_LLT_IPDDP;
- case ARPHRD_IPGRE: return ZEBRA_LLT_IPGRE;
- case ARPHRD_PIMREG: return ZEBRA_LLT_PIMREG;
- case ARPHRD_HIPPI: return ZEBRA_LLT_HIPPI;
- case ARPHRD_ECONET: return ZEBRA_LLT_ECONET;
- case ARPHRD_IRDA: return ZEBRA_LLT_IRDA;
- case ARPHRD_FCPP: return ZEBRA_LLT_FCPP;
- case ARPHRD_FCAL: return ZEBRA_LLT_FCAL;
- case ARPHRD_FCPL: return ZEBRA_LLT_FCPL;
- case ARPHRD_FCFABRIC: return ZEBRA_LLT_FCFABRIC;
- case ARPHRD_IEEE802_TR: return ZEBRA_LLT_IEEE802_TR;
- case ARPHRD_IEEE80211: return ZEBRA_LLT_IEEE80211;
- case ARPHRD_IEEE802154: return ZEBRA_LLT_IEEE802154;
+ switch (hwt) {
+ case ARPHRD_ETHER:
+ return ZEBRA_LLT_ETHER;
+ case ARPHRD_EETHER:
+ return ZEBRA_LLT_EETHER;
+ case ARPHRD_AX25:
+ return ZEBRA_LLT_AX25;
+ case ARPHRD_PRONET:
+ return ZEBRA_LLT_PRONET;
+ case ARPHRD_IEEE802:
+ return ZEBRA_LLT_IEEE802;
+ case ARPHRD_ARCNET:
+ return ZEBRA_LLT_ARCNET;
+ case ARPHRD_APPLETLK:
+ return ZEBRA_LLT_APPLETLK;
+ case ARPHRD_DLCI:
+ return ZEBRA_LLT_DLCI;
+ case ARPHRD_ATM:
+ return ZEBRA_LLT_ATM;
+ case ARPHRD_METRICOM:
+ return ZEBRA_LLT_METRICOM;
+ case ARPHRD_IEEE1394:
+ return ZEBRA_LLT_IEEE1394;
+ case ARPHRD_EUI64:
+ return ZEBRA_LLT_EUI64;
+ case ARPHRD_INFINIBAND:
+ return ZEBRA_LLT_INFINIBAND;
+ case ARPHRD_SLIP:
+ return ZEBRA_LLT_SLIP;
+ case ARPHRD_CSLIP:
+ return ZEBRA_LLT_CSLIP;
+ case ARPHRD_SLIP6:
+ return ZEBRA_LLT_SLIP6;
+ case ARPHRD_CSLIP6:
+ return ZEBRA_LLT_CSLIP6;
+ case ARPHRD_RSRVD:
+ return ZEBRA_LLT_RSRVD;
+ case ARPHRD_ADAPT:
+ return ZEBRA_LLT_ADAPT;
+ case ARPHRD_ROSE:
+ return ZEBRA_LLT_ROSE;
+ case ARPHRD_X25:
+ return ZEBRA_LLT_X25;
+ case ARPHRD_PPP:
+ return ZEBRA_LLT_PPP;
+ case ARPHRD_CISCO:
+ return ZEBRA_LLT_CHDLC;
+ case ARPHRD_LAPB:
+ return ZEBRA_LLT_LAPB;
+ case ARPHRD_RAWHDLC:
+ return ZEBRA_LLT_RAWHDLC;
+ case ARPHRD_TUNNEL:
+ return ZEBRA_LLT_IPIP;
+ case ARPHRD_TUNNEL6:
+ return ZEBRA_LLT_IPIP6;
+ case ARPHRD_FRAD:
+ return ZEBRA_LLT_FRAD;
+ case ARPHRD_SKIP:
+ return ZEBRA_LLT_SKIP;
+ case ARPHRD_LOOPBACK:
+ return ZEBRA_LLT_LOOPBACK;
+ case ARPHRD_LOCALTLK:
+ return ZEBRA_LLT_LOCALTLK;
+ case ARPHRD_FDDI:
+ return ZEBRA_LLT_FDDI;
+ case ARPHRD_SIT:
+ return ZEBRA_LLT_SIT;
+ case ARPHRD_IPDDP:
+ return ZEBRA_LLT_IPDDP;
+ case ARPHRD_IPGRE:
+ return ZEBRA_LLT_IPGRE;
+ case ARPHRD_PIMREG:
+ return ZEBRA_LLT_PIMREG;
+ case ARPHRD_HIPPI:
+ return ZEBRA_LLT_HIPPI;
+ case ARPHRD_ECONET:
+ return ZEBRA_LLT_ECONET;
+ case ARPHRD_IRDA:
+ return ZEBRA_LLT_IRDA;
+ case ARPHRD_FCPP:
+ return ZEBRA_LLT_FCPP;
+ case ARPHRD_FCAL:
+ return ZEBRA_LLT_FCAL;
+ case ARPHRD_FCPL:
+ return ZEBRA_LLT_FCPL;
+ case ARPHRD_FCFABRIC:
+ return ZEBRA_LLT_FCFABRIC;
+ case ARPHRD_IEEE802_TR:
+ return ZEBRA_LLT_IEEE802_TR;
+ case ARPHRD_IEEE80211:
+ return ZEBRA_LLT_IEEE80211;
+ case ARPHRD_IEEE802154:
+ return ZEBRA_LLT_IEEE802154;
#ifdef ARPHRD_IP6GRE
- case ARPHRD_IP6GRE: return ZEBRA_LLT_IP6GRE;
+ case ARPHRD_IP6GRE:
+ return ZEBRA_LLT_IP6GRE;
#endif
#ifdef ARPHRD_IEEE802154_PHY
- case ARPHRD_IEEE802154_PHY: return ZEBRA_LLT_IEEE802154_PHY;
+ case ARPHRD_IEEE802154_PHY:
+ return ZEBRA_LLT_IEEE802154_PHY;
#endif
- default: return ZEBRA_LLT_UNKNOWN;
- }
+ default:
+ return ZEBRA_LLT_UNKNOWN;
+ }
}
-static void
-netlink_determine_zebra_iftype (char *kind, zebra_iftype_t *zif_type)
+static void netlink_determine_zebra_iftype(char *kind, zebra_iftype_t *zif_type)
{
- *zif_type = ZEBRA_IF_OTHER;
-
- if (!kind)
- return;
-
- if (strcmp(kind, "vrf") == 0)
- *zif_type = ZEBRA_IF_VRF;
- else if (strcmp(kind, "bridge") == 0)
- *zif_type = ZEBRA_IF_BRIDGE;
- else if (strcmp(kind, "vlan") == 0)
- *zif_type = ZEBRA_IF_VLAN;
- else if (strcmp(kind, "vxlan") == 0)
- *zif_type = ZEBRA_IF_VXLAN;
+ *zif_type = ZEBRA_IF_OTHER;
+
+ if (!kind)
+ return;
+
+ if (strcmp(kind, "vrf") == 0)
+ *zif_type = ZEBRA_IF_VRF;
+ else if (strcmp(kind, "bridge") == 0)
+ *zif_type = ZEBRA_IF_BRIDGE;
+ else if (strcmp(kind, "vlan") == 0)
+ *zif_type = ZEBRA_IF_VLAN;
+ else if (strcmp(kind, "vxlan") == 0)
+ *zif_type = ZEBRA_IF_VXLAN;
}
-//Temporary Assignments to compile on older platforms.
+// Temporary Assignments to compile on older platforms.
#ifndef IFLA_BR_MAX
#define IFLA_BR_MAX 39
#endif
@@ -243,198 +292,196 @@ netlink_determine_zebra_iftype (char *kind, zebra_iftype_t *zif_type)
#define IFLA_BR_VLAN_FILTERING 7
#endif
-#define parse_rtattr_nested(tb, max, rta) \
- netlink_parse_rtattr((tb), (max), RTA_DATA(rta), RTA_PAYLOAD(rta))
+#define parse_rtattr_nested(tb, max, rta) \
+ netlink_parse_rtattr((tb), (max), RTA_DATA(rta), RTA_PAYLOAD(rta))
-static void
-netlink_vrf_change (struct nlmsghdr *h, struct rtattr *tb, const char *name)
+static void netlink_vrf_change(struct nlmsghdr *h, struct rtattr *tb,
+ const char *name)
{
- struct ifinfomsg *ifi;
- struct rtattr *linkinfo[IFLA_INFO_MAX+1];
- struct rtattr *attr[IFLA_VRF_MAX+1];
- struct vrf *vrf;
- struct zebra_vrf *zvrf;
- u_int32_t nl_table_id;
-
- ifi = NLMSG_DATA (h);
-
- memset (linkinfo, 0, sizeof linkinfo);
- parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb);
-
- if (!linkinfo[IFLA_INFO_DATA]) {
- if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug ("%s: IFLA_INFO_DATA missing from VRF message: %s", __func__, name);
- return;
- }
-
- memset (attr, 0, sizeof attr);
- parse_rtattr_nested(attr, IFLA_VRF_MAX, linkinfo[IFLA_INFO_DATA]);
- if (!attr[IFLA_VRF_TABLE]) {
- if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug ("%s: IFLA_VRF_TABLE missing from VRF message: %s", __func__, name);
- return;
- }
-
- nl_table_id = *(u_int32_t *)RTA_DATA(attr[IFLA_VRF_TABLE]);
-
- if (h->nlmsg_type == RTM_NEWLINK)
- {
- if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug ("RTM_NEWLINK for VRF %s(%u) table %u",
- name, ifi->ifi_index, nl_table_id);
-
- /*
- * vrf_get is implied creation if it does not exist
- */
- vrf = vrf_get((vrf_id_t)ifi->ifi_index, name); // It would create vrf
- if (!vrf)
- {
- zlog_err ("VRF %s id %u not created", name, ifi->ifi_index);
- return;
- }
-
- /* Enable the created VRF. */
- if (!vrf_enable (vrf))
- {
- zlog_err ("Failed to enable VRF %s id %u", name, ifi->ifi_index);
- return;
- }
-
- /*
- * This is the only place that we get the actual kernel table_id
- * being used. We need it to set the table_id of the routes
- * we are passing to the kernel.... And to throw some totally
- * awesome parties. that too.
- */
- zvrf = (struct zebra_vrf *)vrf->info;
- zvrf->table_id = nl_table_id;
- }
- else //h->nlmsg_type == RTM_DELLINK
- {
- if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug ("RTM_DELLINK for VRF %s(%u)", name, ifi->ifi_index);
-
- vrf = vrf_lookup_by_id ((vrf_id_t)ifi->ifi_index);
-
- if (!vrf)
- {
- zlog_warn ("%s: vrf not found", __func__);
- return;
+ struct ifinfomsg *ifi;
+ struct rtattr *linkinfo[IFLA_INFO_MAX + 1];
+ struct rtattr *attr[IFLA_VRF_MAX + 1];
+ struct vrf *vrf;
+ struct zebra_vrf *zvrf;
+ u_int32_t nl_table_id;
+
+ ifi = NLMSG_DATA(h);
+
+ memset(linkinfo, 0, sizeof linkinfo);
+ parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb);
+
+ if (!linkinfo[IFLA_INFO_DATA]) {
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug(
+ "%s: IFLA_INFO_DATA missing from VRF message: %s",
+ __func__, name);
+ return;
+ }
+
+ memset(attr, 0, sizeof attr);
+ parse_rtattr_nested(attr, IFLA_VRF_MAX, linkinfo[IFLA_INFO_DATA]);
+ if (!attr[IFLA_VRF_TABLE]) {
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug(
+ "%s: IFLA_VRF_TABLE missing from VRF message: %s",
+ __func__, name);
+ return;
}
- vrf_delete (vrf);
- }
+ nl_table_id = *(u_int32_t *)RTA_DATA(attr[IFLA_VRF_TABLE]);
+
+ if (h->nlmsg_type == RTM_NEWLINK) {
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug("RTM_NEWLINK for VRF %s(%u) table %u", name,
+ ifi->ifi_index, nl_table_id);
+
+ /*
+ * vrf_get is implied creation if it does not exist
+ */
+ vrf = vrf_get((vrf_id_t)ifi->ifi_index,
+ name); // It would create vrf
+ if (!vrf) {
+ zlog_err("VRF %s id %u not created", name,
+ ifi->ifi_index);
+ return;
+ }
+
+ /* Enable the created VRF. */
+ if (!vrf_enable(vrf)) {
+ zlog_err("Failed to enable VRF %s id %u", name,
+ ifi->ifi_index);
+ return;
+ }
+
+ /*
+ * This is the only place that we get the actual kernel table_id
+ * being used. We need it to set the table_id of the routes
+ * we are passing to the kernel.... And to throw some totally
+ * awesome parties. that too.
+ */
+ zvrf = (struct zebra_vrf *)vrf->info;
+ zvrf->table_id = nl_table_id;
+ } else // h->nlmsg_type == RTM_DELLINK
+ {
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug("RTM_DELLINK for VRF %s(%u)", name,
+ ifi->ifi_index);
+
+ vrf = vrf_lookup_by_id((vrf_id_t)ifi->ifi_index);
+
+ if (!vrf) {
+ zlog_warn("%s: vrf not found", __func__);
+ return;
+ }
+
+ vrf_delete(vrf);
+ }
}
-static int
-get_iflink_speed (const char *ifname)
+static int get_iflink_speed(const char *ifname)
{
- struct ifreq ifdata;
- struct ethtool_cmd ecmd;
- int sd;
- int rc;
-
- /* initialize struct */
- memset(&ifdata, 0, sizeof(ifdata));
-
- /* set interface name */
- strcpy(ifdata.ifr_name, ifname);
-
- /* initialize ethtool interface */
- memset(&ecmd, 0, sizeof(ecmd));
- ecmd.cmd = ETHTOOL_GSET; /* ETHTOOL_GLINK */
- ifdata.ifr_data = (__caddr_t) &ecmd;
-
- /* use ioctl to get IP address of an interface */
- sd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
- if(sd < 0) {
- zlog_debug ("Failure to read interface %s speed: %d %s",
- ifname, errno, safe_strerror(errno));
- return 0;
- }
-
- /* Get the current link state for the interface */
- rc = ioctl(sd, SIOCETHTOOL, (char *)&ifdata);
- if(rc < 0) {
- zlog_debug("IOCTL failure to read interface %s speed: %d %s",
- ifname, errno, safe_strerror(errno));
- ecmd.speed_hi = 0;
- ecmd.speed = 0;
- }
-
- close(sd);
-
- return (ecmd.speed_hi << 16 ) | ecmd.speed;
+ struct ifreq ifdata;
+ struct ethtool_cmd ecmd;
+ int sd;
+ int rc;
+
+ /* initialize struct */
+ memset(&ifdata, 0, sizeof(ifdata));
+
+ /* set interface name */
+ strcpy(ifdata.ifr_name, ifname);
+
+ /* initialize ethtool interface */
+ memset(&ecmd, 0, sizeof(ecmd));
+ ecmd.cmd = ETHTOOL_GSET; /* ETHTOOL_GLINK */
+ ifdata.ifr_data = (__caddr_t)&ecmd;
+
+ /* use ioctl to get IP address of an interface */
+ sd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
+ if (sd < 0) {
+ zlog_debug("Failure to read interface %s speed: %d %s", ifname,
+ errno, safe_strerror(errno));
+ return 0;
+ }
+
+ /* Get the current link state for the interface */
+ rc = ioctl(sd, SIOCETHTOOL, (char *)&ifdata);
+ if (rc < 0) {
+ zlog_debug("IOCTL failure to read interface %s speed: %d %s",
+ ifname, errno, safe_strerror(errno));
+ ecmd.speed_hi = 0;
+ ecmd.speed = 0;
+ }
+
+ close(sd);
+
+ return (ecmd.speed_hi << 16) | ecmd.speed;
}
-static int
-netlink_extract_bridge_info (struct rtattr *link_data,
- struct zebra_l2info_bridge *bridge_info)
+static int netlink_extract_bridge_info(struct rtattr *link_data,
+ struct zebra_l2info_bridge *bridge_info)
{
- struct rtattr *attr[IFLA_BR_MAX+1];
-
- memset (bridge_info, 0, sizeof (*bridge_info));
- memset (attr, 0, sizeof attr);
- parse_rtattr_nested(attr, IFLA_BR_MAX, link_data);
- if (attr[IFLA_BR_VLAN_FILTERING])
- bridge_info->vlan_aware = *(u_char *)RTA_DATA(attr[IFLA_BR_VLAN_FILTERING]);
- return 0;
+ struct rtattr *attr[IFLA_BR_MAX + 1];
+
+ memset(bridge_info, 0, sizeof(*bridge_info));
+ memset(attr, 0, sizeof attr);
+ parse_rtattr_nested(attr, IFLA_BR_MAX, link_data);
+ if (attr[IFLA_BR_VLAN_FILTERING])
+ bridge_info->vlan_aware =
+ *(u_char *)RTA_DATA(attr[IFLA_BR_VLAN_FILTERING]);
+ return 0;
}
-static int
-netlink_extract_vlan_info (struct rtattr *link_data,
- struct zebra_l2info_vlan *vlan_info)
+static int netlink_extract_vlan_info(struct rtattr *link_data,
+ struct zebra_l2info_vlan *vlan_info)
{
- struct rtattr *attr[IFLA_VLAN_MAX+1];
- vlanid_t vid_in_msg;
-
- memset (vlan_info, 0, sizeof (*vlan_info));
- memset (attr, 0, sizeof attr);
- parse_rtattr_nested(attr, IFLA_VLAN_MAX, link_data);
- if (!attr[IFLA_VLAN_ID])
- {
- if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug ("IFLA_VLAN_ID missing from VLAN IF message");
- return -1;
- }
-
- vid_in_msg = *(vlanid_t *)RTA_DATA(attr[IFLA_VLAN_ID]);
- vlan_info->vid = vid_in_msg;
- return 0;
+ struct rtattr *attr[IFLA_VLAN_MAX + 1];
+ vlanid_t vid_in_msg;
+
+ memset(vlan_info, 0, sizeof(*vlan_info));
+ memset(attr, 0, sizeof attr);
+ parse_rtattr_nested(attr, IFLA_VLAN_MAX, link_data);
+ if (!attr[IFLA_VLAN_ID]) {
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug("IFLA_VLAN_ID missing from VLAN IF message");
+ return -1;
+ }
+
+ vid_in_msg = *(vlanid_t *)RTA_DATA(attr[IFLA_VLAN_ID]);
+ vlan_info->vid = vid_in_msg;
+ return 0;
}
-static int
-netlink_extract_vxlan_info (struct rtattr *link_data,
- struct zebra_l2info_vxlan *vxl_info)
+static int netlink_extract_vxlan_info(struct rtattr *link_data,
+ struct zebra_l2info_vxlan *vxl_info)
{
- struct rtattr *attr[IFLA_VXLAN_MAX+1];
- vni_t vni_in_msg;
- struct in_addr vtep_ip_in_msg;
-
- memset (vxl_info, 0, sizeof (*vxl_info));
- memset (attr, 0, sizeof attr);
- parse_rtattr_nested(attr, IFLA_VXLAN_MAX, link_data);
- if (!attr[IFLA_VXLAN_ID])
- {
- if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug ("IFLA_VXLAN_ID missing from VXLAN IF message");
- return -1;
- }
-
- vni_in_msg = *(vni_t *)RTA_DATA(attr[IFLA_VXLAN_ID]);
- vxl_info->vni = vni_in_msg;
- if (!attr[IFLA_VXLAN_LOCAL])
- {
- if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug ("IFLA_VXLAN_LOCAL missing from VXLAN IF message");
- }
- else
- {
- vtep_ip_in_msg = *(struct in_addr *)RTA_DATA(attr[IFLA_VXLAN_LOCAL]);
- vxl_info->vtep_ip = vtep_ip_in_msg;
- }
-
- return 0;
+ struct rtattr *attr[IFLA_VXLAN_MAX + 1];
+ vni_t vni_in_msg;
+ struct in_addr vtep_ip_in_msg;
+
+ memset(vxl_info, 0, sizeof(*vxl_info));
+ memset(attr, 0, sizeof attr);
+ parse_rtattr_nested(attr, IFLA_VXLAN_MAX, link_data);
+ if (!attr[IFLA_VXLAN_ID]) {
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug(
+ "IFLA_VXLAN_ID missing from VXLAN IF message");
+ return -1;
+ }
+
+ vni_in_msg = *(vni_t *)RTA_DATA(attr[IFLA_VXLAN_ID]);
+ vxl_info->vni = vni_in_msg;
+ if (!attr[IFLA_VXLAN_LOCAL]) {
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug(
+ "IFLA_VXLAN_LOCAL missing from VXLAN IF message");
+ } else {
+ vtep_ip_in_msg =
+ *(struct in_addr *)RTA_DATA(attr[IFLA_VXLAN_LOCAL]);
+ vxl_info->vtep_ip = vtep_ip_in_msg;
+ }
+
+ return 0;
}
/*
@@ -442,756 +489,732 @@ netlink_extract_vxlan_info (struct rtattr *link_data,
* bridge interface is added or updated, take further actions to map
* its members. Likewise, for VxLAN interface.
*/
-static void
-netlink_interface_update_l2info (struct interface *ifp,
- struct rtattr *link_data,
- int add)
+static void netlink_interface_update_l2info(struct interface *ifp,
+ struct rtattr *link_data, int add)
{
- if (!link_data)
- return;
-
- if (IS_ZEBRA_IF_BRIDGE(ifp))
- {
- struct zebra_l2info_bridge bridge_info;
-
- netlink_extract_bridge_info (link_data, &bridge_info);
- zebra_l2_bridge_add_update (ifp, &bridge_info, add);
- }
- else if (IS_ZEBRA_IF_VLAN(ifp))
- {
- struct zebra_l2info_vlan vlan_info;
-
- netlink_extract_vlan_info (link_data, &vlan_info);
- zebra_l2_vlanif_update (ifp, &vlan_info);
- }
- else if (IS_ZEBRA_IF_VXLAN(ifp))
- {
- struct zebra_l2info_vxlan vxlan_info;
-
- netlink_extract_vxlan_info (link_data, &vxlan_info);
- zebra_l2_vxlanif_add_update (ifp, &vxlan_info, add);
- }
+ if (!link_data)
+ return;
+
+ if (IS_ZEBRA_IF_BRIDGE(ifp)) {
+ struct zebra_l2info_bridge bridge_info;
+
+ netlink_extract_bridge_info(link_data, &bridge_info);
+ zebra_l2_bridge_add_update(ifp, &bridge_info, add);
+ } else if (IS_ZEBRA_IF_VLAN(ifp)) {
+ struct zebra_l2info_vlan vlan_info;
+
+ netlink_extract_vlan_info(link_data, &vlan_info);
+ zebra_l2_vlanif_update(ifp, &vlan_info);
+ } else if (IS_ZEBRA_IF_VXLAN(ifp)) {
+ struct zebra_l2info_vxlan vxlan_info;
+
+ netlink_extract_vxlan_info(link_data, &vxlan_info);
+ zebra_l2_vxlanif_add_update(ifp, &vxlan_info, add);
+ }
}
-static int
-netlink_bridge_interface (struct nlmsghdr *h, int len,
- ns_id_t ns_id, int startup)
+static int netlink_bridge_interface(struct nlmsghdr *h, int len, ns_id_t ns_id,
+ int startup)
{
- char *name = NULL;
- struct ifinfomsg *ifi;
- struct rtattr *tb[IFLA_MAX + 1];
- struct interface *ifp;
- struct rtattr *aftb[IFLA_BRIDGE_MAX + 1];
- struct
- {
- u_int16_t flags;
- u_int16_t vid;
- } *vinfo;
- vlanid_t access_vlan;
-
- /* Fetch name and ifindex */
- ifi = NLMSG_DATA (h);
- memset (tb, 0, sizeof tb);
- netlink_parse_rtattr (tb, IFLA_MAX, IFLA_RTA (ifi), len);
-
- if (tb[IFLA_IFNAME] == NULL)
- return -1;
- name = (char *) RTA_DATA (tb[IFLA_IFNAME]);
-
- /* The interface should already be known, if not discard. */
- ifp = if_lookup_by_index_per_ns (zebra_ns_lookup (ns_id),
- ifi->ifi_index);
- if (!ifp)
- {
- zlog_warn ("Cannot find bridge IF %s(%u)",
- name, 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;
-
- /* 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, tb[IFLA_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, name, ifi->ifi_index);
- zebra_l2_vxlanif_update_access_vlan (ifp, access_vlan);
- return 0;
+ char *name = NULL;
+ struct ifinfomsg *ifi;
+ struct rtattr *tb[IFLA_MAX + 1];
+ struct interface *ifp;
+ struct rtattr *aftb[IFLA_BRIDGE_MAX + 1];
+ struct {
+ u_int16_t flags;
+ u_int16_t vid;
+ } * vinfo;
+ vlanid_t access_vlan;
+
+ /* Fetch name and ifindex */
+ ifi = NLMSG_DATA(h);
+ memset(tb, 0, sizeof tb);
+ netlink_parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
+
+ if (tb[IFLA_IFNAME] == NULL)
+ return -1;
+ name = (char *)RTA_DATA(tb[IFLA_IFNAME]);
+
+ /* The interface should already be known, if not discard. */
+ ifp = if_lookup_by_index_per_ns(zebra_ns_lookup(ns_id), ifi->ifi_index);
+ if (!ifp) {
+ zlog_warn("Cannot find bridge IF %s(%u)", name, 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;
+
+ /* 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, tb[IFLA_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,
+ name, ifi->ifi_index);
+ zebra_l2_vxlanif_update_access_vlan(ifp, access_vlan);
+ return 0;
}
/* Called from interface_lookup_netlink(). This function is only used
during bootstrap. */
-static int
-netlink_interface (struct sockaddr_nl *snl, struct nlmsghdr *h,
- ns_id_t ns_id, int startup)
+static int netlink_interface(struct sockaddr_nl *snl, 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 *slave_kind = NULL;
- struct zebra_ns *zns;
- vrf_id_t vrf_id = VRF_DEFAULT;
- zebra_iftype_t zif_type = ZEBRA_IF_OTHER;
- zebra_slave_iftype_t zif_slave_type = ZEBRA_IF_SLAVE_NONE;
- ifindex_t bridge_ifindex = IFINDEX_INTERNAL;
- ifindex_t link_ifindex = IFINDEX_INTERNAL;
-
- 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)
- 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 (tb, 0, sizeof tb);
- memset (linkinfo, 0, sizeof linkinfo);
- netlink_parse_rtattr (tb, IFLA_MAX, IFLA_RTA (ifi), len);
+ 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 *slave_kind = NULL;
+ struct zebra_ns *zns;
+ vrf_id_t vrf_id = VRF_DEFAULT;
+ zebra_iftype_t zif_type = ZEBRA_IF_OTHER;
+ zebra_slave_iftype_t zif_slave_type = ZEBRA_IF_SLAVE_NONE;
+ ifindex_t bridge_ifindex = IFINDEX_INTERNAL;
+ ifindex_t link_ifindex = IFINDEX_INTERNAL;
+
+ 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)
+ 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(tb, 0, sizeof tb);
+ memset(linkinfo, 0, sizeof linkinfo);
+ netlink_parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
#ifdef IFLA_WIRELESS
- /* 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;
- }
+ /* 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;
+ }
#endif /* IFLA_WIRELESS */
- if (tb[IFLA_IFNAME] == NULL)
- return -1;
- name = (char *) RTA_DATA (tb[IFLA_IFNAME]);
+ if (tb[IFLA_IFNAME] == NULL)
+ return -1;
+ name = (char *)RTA_DATA(tb[IFLA_IFNAME]);
- if (tb[IFLA_LINKINFO])
- {
- parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb[IFLA_LINKINFO]);
+ if (tb[IFLA_LINKINFO]) {
+ 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_KIND])
+ kind = RTA_DATA(linkinfo[IFLA_INFO_KIND]);
#if HAVE_DECL_IFLA_INFO_SLAVE_KIND
- if (linkinfo[IFLA_INFO_SLAVE_KIND])
- slave_kind = RTA_DATA(linkinfo[IFLA_INFO_SLAVE_KIND]);
+ if (linkinfo[IFLA_INFO_SLAVE_KIND])
+ slave_kind = RTA_DATA(linkinfo[IFLA_INFO_SLAVE_KIND]);
#endif
- netlink_determine_zebra_iftype (kind, &zif_type);
- }
-
- /* If VRF, create the VRF structure itself. */
- if (zif_type == ZEBRA_IF_VRF)
- {
- netlink_vrf_change(h, tb[IFLA_LINKINFO], name);
- vrf_id = (vrf_id_t)ifi->ifi_index;
- }
-
- if (tb[IFLA_MASTER])
- {
- if (slave_kind && (strcmp(slave_kind, "vrf") == 0))
- {
- zif_slave_type = ZEBRA_IF_SLAVE_VRF;
- vrf_id = *(u_int32_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
- zif_slave_type = ZEBRA_IF_SLAVE_OTHER;
- }
-
- /* If linking to another interface, note it. */
- if (tb[IFLA_LINK])
- link_ifindex = *(ifindex_t *)RTA_DATA(tb[IFLA_LINK]);
-
- /* Add interface. */
- ifp = if_get_by_name (name, vrf_id);
- set_ifindex(ifp, ifi->ifi_index, zns);
- ifp->flags = ifi->ifi_flags & 0x0000fffff;
- if (IS_ZEBRA_IF_VRF(ifp))
- SET_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK);
- ifp->mtu6 = ifp->mtu = *(uint32_t *) RTA_DATA (tb[IFLA_MTU]);
- ifp->metric = 0;
- ifp->speed = get_iflink_speed (name);
- ifp->ptm_status = ZEBRA_PTM_STATUS_UNKNOWN;
-
- /* Set zebra interface type */
- zebra_if_set_ziftype (ifp, zif_type, zif_slave_type);
-
- /* Update link. */
- zebra_if_update_link (ifp, link_ifindex);
-
- /* 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);
- if (IS_ZEBRA_IF_BRIDGE_SLAVE (ifp))
- zebra_l2if_update_bridge_slave (ifp, bridge_ifindex);
-
- return 0;
+ netlink_determine_zebra_iftype(kind, &zif_type);
+ }
+
+ /* If VRF, create the VRF structure itself. */
+ if (zif_type == ZEBRA_IF_VRF) {
+ netlink_vrf_change(h, tb[IFLA_LINKINFO], name);
+ vrf_id = (vrf_id_t)ifi->ifi_index;
+ }
+
+ if (tb[IFLA_MASTER]) {
+ if (slave_kind && (strcmp(slave_kind, "vrf") == 0)) {
+ zif_slave_type = ZEBRA_IF_SLAVE_VRF;
+ vrf_id = *(u_int32_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
+ zif_slave_type = ZEBRA_IF_SLAVE_OTHER;
+ }
+
+ /* If linking to another interface, note it. */
+ if (tb[IFLA_LINK])
+ link_ifindex = *(ifindex_t *)RTA_DATA(tb[IFLA_LINK]);
+
+ /* Add interface. */
+ ifp = if_get_by_name(name, vrf_id);
+ set_ifindex(ifp, ifi->ifi_index, zns);
+ ifp->flags = ifi->ifi_flags & 0x0000fffff;
+ if (IS_ZEBRA_IF_VRF(ifp))
+ SET_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK);
+ ifp->mtu6 = ifp->mtu = *(uint32_t *)RTA_DATA(tb[IFLA_MTU]);
+ ifp->metric = 0;
+ ifp->speed = get_iflink_speed(name);
+ ifp->ptm_status = ZEBRA_PTM_STATUS_UNKNOWN;
+
+ /* Set zebra interface type */
+ zebra_if_set_ziftype(ifp, zif_type, zif_slave_type);
+
+ /* Update link. */
+ zebra_if_update_link(ifp, link_ifindex);
+
+ /* 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);
+ if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp))
+ zebra_l2if_update_bridge_slave(ifp, bridge_ifindex);
+
+ return 0;
}
/* Request for specific interface or address information from the kernel */
-static int
-netlink_request_intf_addr (struct zebra_ns *zns,
- int family, int type,
- u_int32_t filter_mask)
+static int netlink_request_intf_addr(struct zebra_ns *zns, int family, int type,
+ u_int32_t filter_mask)
{
- struct
- {
- struct nlmsghdr n;
- struct ifinfomsg ifm;
- char buf[256];
- } req;
-
- /* Form the request, specifying filter (rtattr) if needed. */
- memset (&req, 0, sizeof (req));
- req.n.nlmsg_type = type;
- req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
- req.ifm.ifi_family = family;
-
- /* Include filter, if specified. */
- if (filter_mask)
- addattr32 (&req.n, sizeof(req), IFLA_EXT_MASK, filter_mask);
-
- return netlink_request (&zns->netlink_cmd, &req.n);
+ struct {
+ struct nlmsghdr n;
+ struct ifinfomsg ifm;
+ char buf[256];
+ } req;
+
+ /* Form the request, specifying filter (rtattr) if needed. */
+ memset(&req, 0, sizeof(req));
+ req.n.nlmsg_type = type;
+ req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+ req.ifm.ifi_family = family;
+
+ /* Include filter, if specified. */
+ if (filter_mask)
+ addattr32(&req.n, sizeof(req), IFLA_EXT_MASK, filter_mask);
+
+ return netlink_request(&zns->netlink_cmd, &req.n);
}
/* Interface lookup by netlink socket. */
-int
-interface_lookup_netlink (struct zebra_ns *zns)
+int interface_lookup_netlink(struct zebra_ns *zns)
{
- int ret;
-
- /* Get interface information. */
- ret = netlink_request_intf_addr (zns, AF_PACKET, RTM_GETLINK, 0);
- if (ret < 0)
- return ret;
- ret = netlink_parse_info (netlink_interface, &zns->netlink_cmd, zns, 0, 1);
- if (ret < 0)
- return ret;
-
- /* Get interface information - for bridge interfaces. */
- ret = netlink_request_intf_addr (zns, AF_BRIDGE, RTM_GETLINK,
- RTEXT_FILTER_BRVLAN);
- if (ret < 0)
- return ret;
- ret = netlink_parse_info (netlink_interface, &zns->netlink_cmd, zns, 0, 0);
- if (ret < 0)
- return ret;
-
- /* Get interface information - for bridge interfaces. */
- ret = netlink_request_intf_addr (zns, AF_BRIDGE, RTM_GETLINK,
- RTEXT_FILTER_BRVLAN);
- if (ret < 0)
- return ret;
- ret = netlink_parse_info (netlink_interface, &zns->netlink_cmd, zns, 0, 0);
- if (ret < 0)
- return ret;
-
- /* Get IPv4 address of the interfaces. */
- ret = netlink_request_intf_addr (zns, AF_INET, RTM_GETADDR, 0);
- if (ret < 0)
- return ret;
- ret = netlink_parse_info (netlink_interface_addr, &zns->netlink_cmd, zns, 0, 1);
- if (ret < 0)
- return ret;
-
- /* Get IPv6 address of the interfaces. */
- ret = netlink_request_intf_addr (zns, AF_INET6, RTM_GETADDR, 0);
- if (ret < 0)
- return ret;
- ret = netlink_parse_info (netlink_interface_addr, &zns->netlink_cmd, zns, 0, 1);
- if (ret < 0)
- return ret;
-
- return 0;
+ int ret;
+
+ /* Get interface information. */
+ ret = netlink_request_intf_addr(zns, AF_PACKET, RTM_GETLINK, 0);
+ if (ret < 0)
+ return ret;
+ ret = netlink_parse_info(netlink_interface, &zns->netlink_cmd, zns, 0,
+ 1);
+ if (ret < 0)
+ return ret;
+
+ /* Get interface information - for bridge interfaces. */
+ ret = netlink_request_intf_addr(zns, AF_BRIDGE, RTM_GETLINK,
+ RTEXT_FILTER_BRVLAN);
+ if (ret < 0)
+ return ret;
+ ret = netlink_parse_info(netlink_interface, &zns->netlink_cmd, zns, 0,
+ 0);
+ if (ret < 0)
+ return ret;
+
+ /* Get interface information - for bridge interfaces. */
+ ret = netlink_request_intf_addr(zns, AF_BRIDGE, RTM_GETLINK,
+ RTEXT_FILTER_BRVLAN);
+ if (ret < 0)
+ return ret;
+ ret = netlink_parse_info(netlink_interface, &zns->netlink_cmd, zns, 0,
+ 0);
+ if (ret < 0)
+ return ret;
+
+ /* Get IPv4 address of the interfaces. */
+ ret = netlink_request_intf_addr(zns, AF_INET, RTM_GETADDR, 0);
+ if (ret < 0)
+ return ret;
+ ret = netlink_parse_info(netlink_interface_addr, &zns->netlink_cmd, zns,
+ 0, 1);
+ if (ret < 0)
+ return ret;
+
+ /* Get IPv6 address of the interfaces. */
+ ret = netlink_request_intf_addr(zns, AF_INET6, RTM_GETADDR, 0);
+ if (ret < 0)
+ return ret;
+ ret = netlink_parse_info(netlink_interface_addr, &zns->netlink_cmd, zns,
+ 0, 1);
+ if (ret < 0)
+ return ret;
+
+ return 0;
}
/* Interface address modification. */
-static int
-netlink_address (int cmd, int family, struct interface *ifp,
- struct connected *ifc)
+static int netlink_address(int cmd, int family, struct interface *ifp,
+ struct connected *ifc)
{
- int bytelen;
- struct prefix *p;
+ int bytelen;
+ struct prefix *p;
- struct
- {
- struct nlmsghdr n;
- struct ifaddrmsg ifa;
- char buf[NL_PKT_BUF_SIZE];
- } req;
+ struct {
+ struct nlmsghdr n;
+ struct ifaddrmsg ifa;
+ char buf[NL_PKT_BUF_SIZE];
+ } req;
- struct zebra_ns *zns = zebra_ns_lookup (NS_DEFAULT);
+ struct zebra_ns *zns = zebra_ns_lookup(NS_DEFAULT);
- p = ifc->address;
- memset (&req, 0, sizeof req - NL_PKT_BUF_SIZE);
+ p = ifc->address;
+ memset(&req, 0, sizeof req - NL_PKT_BUF_SIZE);
- bytelen = (family == AF_INET ? 4 : 16);
+ bytelen = (family == AF_INET ? 4 : 16);
- req.n.nlmsg_len = NLMSG_LENGTH (sizeof (struct ifaddrmsg));
- req.n.nlmsg_flags = NLM_F_REQUEST;
- req.n.nlmsg_type = cmd;
- req.n.nlmsg_pid = zns->netlink_cmd.snl.nl_pid;
+ req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
+ req.n.nlmsg_flags = NLM_F_REQUEST;
+ req.n.nlmsg_type = cmd;
+ req.n.nlmsg_pid = zns->netlink_cmd.snl.nl_pid;
- req.ifa.ifa_family = family;
+ req.ifa.ifa_family = family;
- req.ifa.ifa_index = ifp->ifindex;
- req.ifa.ifa_prefixlen = p->prefixlen;
+ req.ifa.ifa_index = ifp->ifindex;
+ req.ifa.ifa_prefixlen = p->prefixlen;
- addattr_l (&req.n, sizeof req, IFA_LOCAL, &p->u.prefix, bytelen);
+ addattr_l(&req.n, sizeof req, IFA_LOCAL, &p->u.prefix, bytelen);
- if (family == AF_INET && cmd == RTM_NEWADDR)
- {
- if (!CONNECTED_PEER(ifc) && ifc->destination)
- {
- p = ifc->destination;
- addattr_l (&req.n, sizeof req, IFA_BROADCAST, &p->u.prefix,
- bytelen);
- }
- }
+ if (family == AF_INET && cmd == RTM_NEWADDR) {
+ if (!CONNECTED_PEER(ifc) && ifc->destination) {
+ p = ifc->destination;
+ addattr_l(&req.n, sizeof req, IFA_BROADCAST,
+ &p->u.prefix, bytelen);
+ }
+ }
- if (CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
- SET_FLAG (req.ifa.ifa_flags, IFA_F_SECONDARY);
+ if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY))
+ SET_FLAG(req.ifa.ifa_flags, IFA_F_SECONDARY);
- if (ifc->label)
- addattr_l (&req.n, sizeof req, IFA_LABEL, ifc->label,
- strlen (ifc->label) + 1);
+ if (ifc->label)
+ addattr_l(&req.n, sizeof req, IFA_LABEL, ifc->label,
+ strlen(ifc->label) + 1);
- return netlink_talk (netlink_talk_filter, &req.n, &zns->netlink_cmd, zns, 0);
+ return netlink_talk(netlink_talk_filter, &req.n, &zns->netlink_cmd, zns,
+ 0);
}
-int
-kernel_address_add_ipv4 (struct interface *ifp, struct connected *ifc)
+int kernel_address_add_ipv4(struct interface *ifp, struct connected *ifc)
{
- return netlink_address (RTM_NEWADDR, AF_INET, ifp, ifc);
+ return netlink_address(RTM_NEWADDR, AF_INET, ifp, ifc);
}
-int
-kernel_address_delete_ipv4 (struct interface *ifp, struct connected *ifc)
+int kernel_address_delete_ipv4(struct interface *ifp, struct connected *ifc)
{
- return netlink_address (RTM_DELADDR, AF_INET, ifp, ifc);
+ return netlink_address(RTM_DELADDR, AF_INET, ifp, ifc);
}
-int
-netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h,
- ns_id_t ns_id, int startup)
+int netlink_interface_addr(struct sockaddr_nl *snl, struct nlmsghdr *h,
+ ns_id_t ns_id, int startup)
{
- int len;
- struct ifaddrmsg *ifa;
- struct rtattr *tb[IFA_MAX + 1];
- struct interface *ifp;
- void *addr;
- void *broad;
- u_char flags = 0;
- char *label = NULL;
- struct zebra_ns *zns;
-
- zns = zebra_ns_lookup (ns_id);
- ifa = NLMSG_DATA (h);
-
- if (ifa->ifa_family != AF_INET && ifa->ifa_family != AF_INET6)
- return 0;
-
- if (h->nlmsg_type != RTM_NEWADDR && h->nlmsg_type != RTM_DELADDR)
- return 0;
-
- len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct ifaddrmsg));
- if (len < 0)
- return -1;
-
- memset (tb, 0, sizeof tb);
- netlink_parse_rtattr (tb, IFA_MAX, IFA_RTA (ifa), len);
-
- ifp = if_lookup_by_index_per_ns (zns, ifa->ifa_index);
- if (ifp == NULL)
- {
- zlog_err ("netlink_interface_addr can't find interface by index %d",
- ifa->ifa_index);
- return -1;
- }
-
- if (IS_ZEBRA_DEBUG_KERNEL) /* remove this line to see initial ifcfg */
- {
- char buf[BUFSIZ];
- zlog_debug ("netlink_interface_addr %s %s flags 0x%x:",
- nl_msg_type_to_str (h->nlmsg_type), ifp->name,
- ifa->ifa_flags);
- if (tb[IFA_LOCAL])
- zlog_debug (" IFA_LOCAL %s/%d",
- inet_ntop (ifa->ifa_family, RTA_DATA (tb[IFA_LOCAL]),
- buf, BUFSIZ), ifa->ifa_prefixlen);
- if (tb[IFA_ADDRESS])
- zlog_debug (" IFA_ADDRESS %s/%d",
- inet_ntop (ifa->ifa_family, RTA_DATA (tb[IFA_ADDRESS]),
- buf, BUFSIZ), ifa->ifa_prefixlen);
- if (tb[IFA_BROADCAST])
- zlog_debug (" IFA_BROADCAST %s/%d",
- inet_ntop (ifa->ifa_family, RTA_DATA (tb[IFA_BROADCAST]),
- buf, BUFSIZ), ifa->ifa_prefixlen);
- if (tb[IFA_LABEL] && strcmp (ifp->name, RTA_DATA (tb[IFA_LABEL])))
- zlog_debug (" IFA_LABEL %s", (char *)RTA_DATA (tb[IFA_LABEL]));
-
- if (tb[IFA_CACHEINFO])
- {
- struct ifa_cacheinfo *ci = RTA_DATA (tb[IFA_CACHEINFO]);
- zlog_debug (" IFA_CACHEINFO pref %d, valid %d",
- ci->ifa_prefered, ci->ifa_valid);
- }
- }
-
- /* logic copied from iproute2/ip/ipaddress.c:print_addrinfo() */
- if (tb[IFA_LOCAL] == NULL)
- tb[IFA_LOCAL] = tb[IFA_ADDRESS];
- if (tb[IFA_ADDRESS] == NULL)
- tb[IFA_ADDRESS] = tb[IFA_LOCAL];
-
- /* local interface address */
- addr = (tb[IFA_LOCAL] ? RTA_DATA(tb[IFA_LOCAL]) : NULL);
-
- /* is there a peer address? */
- if (tb[IFA_ADDRESS] &&
- memcmp(RTA_DATA(tb[IFA_ADDRESS]), RTA_DATA(tb[IFA_LOCAL]), RTA_PAYLOAD(tb[IFA_ADDRESS])))
- {
- broad = RTA_DATA(tb[IFA_ADDRESS]);
- SET_FLAG (flags, ZEBRA_IFA_PEER);
- }
- else
- /* seeking a broadcast address */
- broad = (tb[IFA_BROADCAST] ? RTA_DATA(tb[IFA_BROADCAST]) : NULL);
-
- /* addr is primary key, SOL if we don't have one */
- if (addr == NULL)
- {
- zlog_debug ("%s: NULL address", __func__);
- return -1;
- }
-
- /* Flags. */
- if (ifa->ifa_flags & IFA_F_SECONDARY)
- SET_FLAG (flags, ZEBRA_IFA_SECONDARY);
-
- /* Label */
- if (tb[IFA_LABEL])
- label = (char *) RTA_DATA (tb[IFA_LABEL]);
-
- if (ifp && label && strcmp (ifp->name, label) == 0)
- label = NULL;
-
- /* Register interface address to the interface. */
- if (ifa->ifa_family == AF_INET)
- {
- if (h->nlmsg_type == RTM_NEWADDR)
- connected_add_ipv4 (ifp, flags,
- (struct in_addr *) addr, ifa->ifa_prefixlen,
- (struct in_addr *) broad, label);
- else
- connected_delete_ipv4 (ifp, flags,
- (struct in_addr *) addr, ifa->ifa_prefixlen,
- (struct in_addr *) broad);
- }
- if (ifa->ifa_family == AF_INET6)
- {
- if (h->nlmsg_type == RTM_NEWADDR)
- {
- /* Only consider valid addresses; we'll not get a notification from
- * the kernel till IPv6 DAD has completed, but at init time, Quagga
- * does query for and will receive all addresses.
- */
- if (!(ifa->ifa_flags & (IFA_F_DADFAILED | IFA_F_TENTATIVE)))
- connected_add_ipv6 (ifp, flags, (struct in6_addr *) addr,
- ifa->ifa_prefixlen, (struct in6_addr *) broad, label);
- }
- else
- connected_delete_ipv6 (ifp,
- (struct in6_addr *) addr, ifa->ifa_prefixlen,
- (struct in6_addr *) broad);
- }
-
- return 0;
+ int len;
+ struct ifaddrmsg *ifa;
+ struct rtattr *tb[IFA_MAX + 1];
+ struct interface *ifp;
+ void *addr;
+ void *broad;
+ u_char flags = 0;
+ char *label = NULL;
+ struct zebra_ns *zns;
+
+ zns = zebra_ns_lookup(ns_id);
+ ifa = NLMSG_DATA(h);
+
+ if (ifa->ifa_family != AF_INET && ifa->ifa_family != AF_INET6)
+ return 0;
+
+ if (h->nlmsg_type != RTM_NEWADDR && h->nlmsg_type != RTM_DELADDR)
+ return 0;
+
+ len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifaddrmsg));
+ if (len < 0)
+ return -1;
+
+ memset(tb, 0, sizeof tb);
+ netlink_parse_rtattr(tb, IFA_MAX, IFA_RTA(ifa), len);
+
+ ifp = if_lookup_by_index_per_ns(zns, ifa->ifa_index);
+ if (ifp == NULL) {
+ zlog_err(
+ "netlink_interface_addr can't find interface by index %d",
+ ifa->ifa_index);
+ return -1;
+ }
+
+ if (IS_ZEBRA_DEBUG_KERNEL) /* remove this line to see initial ifcfg */
+ {
+ char buf[BUFSIZ];
+ zlog_debug("netlink_interface_addr %s %s flags 0x%x:",
+ nl_msg_type_to_str(h->nlmsg_type), ifp->name,
+ ifa->ifa_flags);
+ if (tb[IFA_LOCAL])
+ zlog_debug(" IFA_LOCAL %s/%d",
+ inet_ntop(ifa->ifa_family,
+ RTA_DATA(tb[IFA_LOCAL]), buf,
+ BUFSIZ),
+ ifa->ifa_prefixlen);
+ if (tb[IFA_ADDRESS])
+ zlog_debug(" IFA_ADDRESS %s/%d",
+ inet_ntop(ifa->ifa_family,
+ RTA_DATA(tb[IFA_ADDRESS]), buf,
+ BUFSIZ),
+ ifa->ifa_prefixlen);
+ if (tb[IFA_BROADCAST])
+ zlog_debug(" IFA_BROADCAST %s/%d",
+ inet_ntop(ifa->ifa_family,
+ RTA_DATA(tb[IFA_BROADCAST]), buf,
+ BUFSIZ),
+ ifa->ifa_prefixlen);
+ if (tb[IFA_LABEL] && strcmp(ifp->name, RTA_DATA(tb[IFA_LABEL])))
+ zlog_debug(" IFA_LABEL %s",
+ (char *)RTA_DATA(tb[IFA_LABEL]));
+
+ if (tb[IFA_CACHEINFO]) {
+ struct ifa_cacheinfo *ci = RTA_DATA(tb[IFA_CACHEINFO]);
+ zlog_debug(" IFA_CACHEINFO pref %d, valid %d",
+ ci->ifa_prefered, ci->ifa_valid);
+ }
+ }
+
+ /* logic copied from iproute2/ip/ipaddress.c:print_addrinfo() */
+ if (tb[IFA_LOCAL] == NULL)
+ tb[IFA_LOCAL] = tb[IFA_ADDRESS];
+ if (tb[IFA_ADDRESS] == NULL)
+ tb[IFA_ADDRESS] = tb[IFA_LOCAL];
+
+ /* local interface address */
+ addr = (tb[IFA_LOCAL] ? RTA_DATA(tb[IFA_LOCAL]) : NULL);
+
+ /* is there a peer address? */
+ if (tb[IFA_ADDRESS]
+ && memcmp(RTA_DATA(tb[IFA_ADDRESS]), RTA_DATA(tb[IFA_LOCAL]),
+ RTA_PAYLOAD(tb[IFA_ADDRESS]))) {
+ broad = RTA_DATA(tb[IFA_ADDRESS]);
+ SET_FLAG(flags, ZEBRA_IFA_PEER);
+ } else
+ /* seeking a broadcast address */
+ broad = (tb[IFA_BROADCAST] ? RTA_DATA(tb[IFA_BROADCAST])
+ : NULL);
+
+ /* addr is primary key, SOL if we don't have one */
+ if (addr == NULL) {
+ zlog_debug("%s: NULL address", __func__);
+ return -1;
+ }
+
+ /* Flags. */
+ if (ifa->ifa_flags & IFA_F_SECONDARY)
+ SET_FLAG(flags, ZEBRA_IFA_SECONDARY);
+
+ /* Label */
+ if (tb[IFA_LABEL])
+ label = (char *)RTA_DATA(tb[IFA_LABEL]);
+
+ if (ifp && label && strcmp(ifp->name, label) == 0)
+ label = NULL;
+
+ /* Register interface address to the interface. */
+ if (ifa->ifa_family == AF_INET) {
+ if (h->nlmsg_type == RTM_NEWADDR)
+ connected_add_ipv4(ifp, flags, (struct in_addr *)addr,
+ ifa->ifa_prefixlen,
+ (struct in_addr *)broad, label);
+ else
+ connected_delete_ipv4(
+ ifp, flags, (struct in_addr *)addr,
+ ifa->ifa_prefixlen, (struct in_addr *)broad);
+ }
+ if (ifa->ifa_family == AF_INET6) {
+ if (h->nlmsg_type == RTM_NEWADDR) {
+ /* Only consider valid addresses; we'll not get a
+ * notification from
+ * the kernel till IPv6 DAD has completed, but at init
+ * time, Quagga
+ * does query for and will receive all addresses.
+ */
+ if (!(ifa->ifa_flags
+ & (IFA_F_DADFAILED | IFA_F_TENTATIVE)))
+ connected_add_ipv6(
+ ifp, flags, (struct in6_addr *)addr,
+ ifa->ifa_prefixlen,
+ (struct in6_addr *)broad, label);
+ } else
+ connected_delete_ipv6(ifp, (struct in6_addr *)addr,
+ ifa->ifa_prefixlen,
+ (struct in6_addr *)broad);
+ }
+
+ return 0;
}
-int
-netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
- ns_id_t ns_id, int startup)
+int netlink_link_change(struct sockaddr_nl *snl, 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 *slave_kind = NULL;
- struct zebra_ns *zns;
- vrf_id_t vrf_id = VRF_DEFAULT;
- zebra_iftype_t zif_type = ZEBRA_IF_OTHER;
- zebra_slave_iftype_t zif_slave_type = ZEBRA_IF_SLAVE_NONE;
- ifindex_t bridge_ifindex = IFINDEX_INTERNAL;
- ifindex_t link_ifindex = IFINDEX_INTERNAL;
-
-
- zns = zebra_ns_lookup (ns_id);
- ifi = NLMSG_DATA (h);
-
- if (!(h->nlmsg_type == RTM_NEWLINK || h->nlmsg_type == RTM_DELLINK))
- {
- /* If this is not link add/delete message so print warning. */
- zlog_warn ("netlink_link_change: wrong kernel message %d",
- h->nlmsg_type);
- return 0;
- }
-
- len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct ifinfomsg));
- if (len < 0)
- 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 (tb, 0, sizeof tb);
- memset (linkinfo, 0, sizeof linkinfo);
- netlink_parse_rtattr (tb, IFLA_MAX, IFLA_RTA (ifi), len);
+ 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 *slave_kind = NULL;
+ struct zebra_ns *zns;
+ vrf_id_t vrf_id = VRF_DEFAULT;
+ zebra_iftype_t zif_type = ZEBRA_IF_OTHER;
+ zebra_slave_iftype_t zif_slave_type = ZEBRA_IF_SLAVE_NONE;
+ ifindex_t bridge_ifindex = IFINDEX_INTERNAL;
+ ifindex_t link_ifindex = IFINDEX_INTERNAL;
+
+
+ zns = zebra_ns_lookup(ns_id);
+ ifi = NLMSG_DATA(h);
+
+ if (!(h->nlmsg_type == RTM_NEWLINK || h->nlmsg_type == RTM_DELLINK)) {
+ /* If this is not link add/delete message so print warning. */
+ zlog_warn("netlink_link_change: wrong kernel message %d",
+ h->nlmsg_type);
+ return 0;
+ }
+
+ len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifinfomsg));
+ if (len < 0)
+ 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(tb, 0, sizeof tb);
+ memset(linkinfo, 0, sizeof linkinfo);
+ netlink_parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
#ifdef IFLA_WIRELESS
- /* 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;
- }
+ /* 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;
+ }
#endif /* IFLA_WIRELESS */
- if (tb[IFLA_IFNAME] == NULL)
- return -1;
- name = (char *) RTA_DATA (tb[IFLA_IFNAME]);
+ if (tb[IFLA_IFNAME] == NULL)
+ return -1;
+ name = (char *)RTA_DATA(tb[IFLA_IFNAME]);
- if (tb[IFLA_LINKINFO])
- {
- parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb[IFLA_LINKINFO]);
+ if (tb[IFLA_LINKINFO]) {
+ 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_KIND])
+ kind = RTA_DATA(linkinfo[IFLA_INFO_KIND]);
#if HAVE_DECL_IFLA_INFO_SLAVE_KIND
- if (linkinfo[IFLA_INFO_SLAVE_KIND])
- slave_kind = RTA_DATA(linkinfo[IFLA_INFO_SLAVE_KIND]);
+ if (linkinfo[IFLA_INFO_SLAVE_KIND])
+ slave_kind = RTA_DATA(linkinfo[IFLA_INFO_SLAVE_KIND]);
#endif
- netlink_determine_zebra_iftype (kind, &zif_type);
- }
-
- /* If linking to another interface, note it. */
- if (tb[IFLA_LINK])
- link_ifindex = *(ifindex_t *)RTA_DATA(tb[IFLA_LINK]);
+ netlink_determine_zebra_iftype(kind, &zif_type);
+ }
- /* If VRF, create or update the VRF structure itself. */
- if (zif_type == ZEBRA_IF_VRF)
- {
- netlink_vrf_change(h, tb[IFLA_LINKINFO], name);
- vrf_id = (vrf_id_t)ifi->ifi_index;
- }
+ /* If linking to another interface, note it. */
+ if (tb[IFLA_LINK])
+ link_ifindex = *(ifindex_t *)RTA_DATA(tb[IFLA_LINK]);
- /* See if interface is present. */
- ifp = if_lookup_by_name_per_ns (zns, name);
+ /* If VRF, create or update the VRF structure itself. */
+ if (zif_type == ZEBRA_IF_VRF) {
+ netlink_vrf_change(h, tb[IFLA_LINKINFO], name);
+ vrf_id = (vrf_id_t)ifi->ifi_index;
+ }
- if (h->nlmsg_type == RTM_NEWLINK)
- {
- if (tb[IFLA_MASTER])
- {
- if (slave_kind && (strcmp(slave_kind, "vrf") == 0))
- {
- zif_slave_type = ZEBRA_IF_SLAVE_VRF;
- vrf_id = *(u_int32_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
- zif_slave_type = ZEBRA_IF_SLAVE_OTHER;
+ /* See if interface is present. */
+ ifp = if_lookup_by_name_per_ns(zns, name);
+
+ if (h->nlmsg_type == RTM_NEWLINK) {
+ if (tb[IFLA_MASTER]) {
+ if (slave_kind && (strcmp(slave_kind, "vrf") == 0)) {
+ zif_slave_type = ZEBRA_IF_SLAVE_VRF;
+ vrf_id =
+ *(u_int32_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
+ zif_slave_type = ZEBRA_IF_SLAVE_OTHER;
+ }
+
+ if (ifp == NULL
+ || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
+ /* Add interface notification from kernel */
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug(
+ "RTM_NEWLINK ADD for %s(%u) vrf_id %u type %d "
+ "sl_type %d master %u flags 0x%x",
+ name, ifi->ifi_index, vrf_id, zif_type,
+ zif_slave_type, bridge_ifindex,
+ ifi->ifi_flags);
+
+ if (ifp == NULL) {
+ /* unknown interface */
+ ifp = if_get_by_name(name, vrf_id);
+ } else {
+ /* pre-configured interface, learnt now */
+ if (ifp->vrf_id != vrf_id)
+ if_update_to_new_vrf(ifp, vrf_id);
+ }
+
+ /* Update interface information. */
+ set_ifindex(ifp, ifi->ifi_index, zns);
+ ifp->flags = ifi->ifi_flags & 0x0000fffff;
+ if (IS_ZEBRA_IF_VRF(ifp))
+ SET_FLAG(ifp->status,
+ ZEBRA_INTERFACE_VRF_LOOPBACK);
+ ifp->mtu6 = ifp->mtu = *(int *)RTA_DATA(tb[IFLA_MTU]);
+ ifp->metric = 0;
+ ifp->ptm_status = ZEBRA_PTM_STATUS_UNKNOWN;
+
+ /* Set interface type */
+ zebra_if_set_ziftype(ifp, zif_type, zif_slave_type);
+
+ /* Update link. */
+ zebra_if_update_link(ifp, link_ifindex);
+
+ netlink_interface_update_hw_addr(tb, ifp);
+
+ /* Inform clients, install any configured addresses. */
+ if_add_update(ifp);
+
+ /* Extract and save L2 interface information, take
+ * additional actions. */
+ netlink_interface_update_l2info(
+ ifp, linkinfo[IFLA_INFO_DATA], 1);
+ if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp))
+ zebra_l2if_update_bridge_slave(ifp,
+ bridge_ifindex);
+ } else if (ifp->vrf_id != vrf_id) {
+ /* VRF change for an interface. */
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug(
+ "RTM_NEWLINK vrf-change for %s(%u) "
+ "vrf_id %u -> %u flags 0x%x",
+ name, ifp->ifindex, ifp->vrf_id, vrf_id,
+ ifi->ifi_flags);
+
+ if_handle_vrf_change(ifp, vrf_id);
+ } else {
+ int was_bridge_slave;
+
+ /* Interface update. */
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug(
+ "RTM_NEWLINK update for %s(%u) "
+ "sl_type %d master %u flags 0x%x",
+ name, ifp->ifindex, zif_slave_type,
+ bridge_ifindex, ifi->ifi_flags);
+
+ set_ifindex(ifp, ifi->ifi_index, zns);
+ ifp->mtu6 = ifp->mtu = *(int *)RTA_DATA(tb[IFLA_MTU]);
+ ifp->metric = 0;
+
+ /* Update interface type - NOTE: Only slave_type can
+ * change. */
+ was_bridge_slave = IS_ZEBRA_IF_BRIDGE_SLAVE(ifp);
+ zebra_if_set_ziftype(ifp, zif_type, zif_slave_type);
+
+ netlink_interface_update_hw_addr(tb, ifp);
+
+ if (if_is_no_ptm_operative(ifp)) {
+ ifp->flags = ifi->ifi_flags & 0x0000fffff;
+ if (!if_is_no_ptm_operative(ifp)) {
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug(
+ "Intf %s(%u) has gone DOWN",
+ name, ifp->ifindex);
+ if_down(ifp);
+ } else if (if_is_operative(ifp)) {
+ /* Must notify client daemons of new
+ * interface status. */
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug(
+ "Intf %s(%u) PTM up, notifying clients",
+ name, ifp->ifindex);
+ zebra_interface_up_update(ifp);
+ }
+ } else {
+ ifp->flags = ifi->ifi_flags & 0x0000fffff;
+ if (if_is_operative(ifp)) {
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug(
+ "Intf %s(%u) has come UP",
+ name, ifp->ifindex);
+ if_up(ifp);
+ }
+ }
+
+ /* Extract and save L2 interface information, take
+ * additional actions. */
+ netlink_interface_update_l2info(
+ ifp, linkinfo[IFLA_INFO_DATA], 0);
+ if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp) || was_bridge_slave)
+ zebra_l2if_update_bridge_slave(ifp,
+ bridge_ifindex);
+ }
+ } else {
+ /* Delete interface notification from kernel */
+ if (ifp == NULL) {
+ zlog_warn("RTM_DELLINK for unknown interface %s(%u)",
+ name, ifi->ifi_index);
+ return 0;
+ }
+
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug("RTM_DELLINK for %s(%u)", name,
+ ifp->ifindex);
+
+ UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK);
+
+ /* Special handling for bridge or VxLAN interfaces. */
+ if (IS_ZEBRA_IF_BRIDGE(ifp))
+ zebra_l2_bridge_del(ifp);
+ else if (IS_ZEBRA_IF_VXLAN(ifp))
+ zebra_l2_vxlanif_del(ifp);
+
+ if (!IS_ZEBRA_IF_VRF(ifp))
+ if_delete_update(ifp);
}
- if (ifp == NULL || !CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
- {
- /* Add interface notification from kernel */
- if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug ("RTM_NEWLINK ADD for %s(%u) vrf_id %u type %d "
- "sl_type %d master %u flags 0x%x",
- name, ifi->ifi_index, vrf_id, zif_type, zif_slave_type,
- bridge_ifindex, ifi->ifi_flags);
-
- if (ifp == NULL)
- {
- /* unknown interface */
- ifp = if_get_by_name (name, vrf_id);
- }
- else
- {
- /* pre-configured interface, learnt now */
- if (ifp->vrf_id != vrf_id)
- if_update_to_new_vrf (ifp, vrf_id);
- }
-
- /* Update interface information. */
- set_ifindex(ifp, ifi->ifi_index, zns);
- ifp->flags = ifi->ifi_flags & 0x0000fffff;
- if (IS_ZEBRA_IF_VRF(ifp))
- SET_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK);
- ifp->mtu6 = ifp->mtu = *(int *) RTA_DATA (tb[IFLA_MTU]);
- ifp->metric = 0;
- ifp->ptm_status = ZEBRA_PTM_STATUS_UNKNOWN;
-
- /* Set interface type */
- zebra_if_set_ziftype (ifp, zif_type, zif_slave_type);
-
- /* Update link. */
- zebra_if_update_link (ifp, link_ifindex);
-
- netlink_interface_update_hw_addr (tb, ifp);
-
- /* Inform clients, install any configured addresses. */
- if_add_update (ifp);
-
- /* Extract and save L2 interface information, take additional actions. */
- netlink_interface_update_l2info (ifp, linkinfo[IFLA_INFO_DATA], 1);
- if (IS_ZEBRA_IF_BRIDGE_SLAVE (ifp))
- zebra_l2if_update_bridge_slave (ifp, bridge_ifindex);
- }
- else if (ifp->vrf_id != vrf_id)
- {
- /* VRF change for an interface. */
- if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug ("RTM_NEWLINK vrf-change for %s(%u) "
- "vrf_id %u -> %u flags 0x%x",
- name, ifp->ifindex, ifp->vrf_id,
- vrf_id, ifi->ifi_flags);
-
- if_handle_vrf_change (ifp, vrf_id);
- }
- else
- {
- int was_bridge_slave;
-
- /* Interface update. */
- if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug ("RTM_NEWLINK update for %s(%u) "
- "sl_type %d master %u flags 0x%x",
- name, ifp->ifindex, zif_slave_type,
- bridge_ifindex, ifi->ifi_flags);
-
- set_ifindex(ifp, ifi->ifi_index, zns);
- ifp->mtu6 = ifp->mtu = *(int *) RTA_DATA (tb[IFLA_MTU]);
- ifp->metric = 0;
-
- /* Update interface type - NOTE: Only slave_type can change. */
- was_bridge_slave = IS_ZEBRA_IF_BRIDGE_SLAVE (ifp);
- zebra_if_set_ziftype (ifp, zif_type, zif_slave_type);
-
- netlink_interface_update_hw_addr (tb, ifp);
-
- if (if_is_no_ptm_operative (ifp))
- {
- ifp->flags = ifi->ifi_flags & 0x0000fffff;
- if (!if_is_no_ptm_operative (ifp))
- {
- if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug ("Intf %s(%u) has gone DOWN",
- name, ifp->ifindex);
- if_down (ifp);
- }
- else if (if_is_operative (ifp))
- {
- /* Must notify client daemons of new interface status. */
- if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug ("Intf %s(%u) PTM up, notifying clients",
- name, ifp->ifindex);
- zebra_interface_up_update (ifp);
- }
- }
- else
- {
- ifp->flags = ifi->ifi_flags & 0x0000fffff;
- if (if_is_operative (ifp))
- {
- if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug ("Intf %s(%u) has come UP", name, ifp->ifindex);
- if_up (ifp);
- }
- }
-
- /* Extract and save L2 interface information, take additional actions. */
- netlink_interface_update_l2info (ifp, linkinfo[IFLA_INFO_DATA], 0);
- if (IS_ZEBRA_IF_BRIDGE_SLAVE (ifp) || was_bridge_slave)
- zebra_l2if_update_bridge_slave (ifp, bridge_ifindex);
- }
- }
- else
- {
- /* Delete interface notification from kernel */
- if (ifp == NULL)
- {
- zlog_warn ("RTM_DELLINK for unknown interface %s(%u)",
- name, ifi->ifi_index);
- return 0;
- }
-
- if (IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug ("RTM_DELLINK for %s(%u)", name, ifp->ifindex);
-
- UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK);
-
- /* Special handling for bridge or VxLAN interfaces. */
- if (IS_ZEBRA_IF_BRIDGE (ifp))
- zebra_l2_bridge_del (ifp);
- else if (IS_ZEBRA_IF_VXLAN (ifp))
- zebra_l2_vxlanif_del (ifp);
-
- if (!IS_ZEBRA_IF_VRF(ifp))
- if_delete_update (ifp);
- }
-
- return 0;
+ return 0;
}
/* Interface information read by netlink. */
-void
-interface_list (struct zebra_ns *zns)
+void interface_list(struct zebra_ns *zns)
{
- interface_lookup_netlink (zns);
+ interface_lookup_netlink(zns);
}