diff options
Diffstat (limited to 'zebra/if_netlink.c')
| -rw-r--r-- | zebra/if_netlink.c | 1969 | 
1 files changed, 996 insertions, 973 deletions
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index d0907a2670..acec2db526 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);  }  | 
