diff options
Diffstat (limited to 'zebra')
90 files changed, 28580 insertions, 29375 deletions
diff --git a/zebra/client_main.c b/zebra/client_main.c index 178184d463..063838d560 100644 --- a/zebra/client_main.c +++ b/zebra/client_main.c @@ -17,7 +17,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #include <zebra.h> @@ -39,188 +39,167 @@ struct zclient *zclient = NULL;  int sock;  /* IPv4 route add and delete test. */ -void -zebra_test_ipv4 (int command, int type, char *prefix, char *gateway, -		 u_char distance) +void zebra_test_ipv4(int command, int type, char *prefix, char *gateway, +		     u_char distance)  { -  struct zapi_ipv4 api; -  struct prefix_ipv4 p; -  struct in_addr gate; -  struct in_addr *gpnt; - -  str2prefix_ipv4 (prefix, &p); -  inet_aton (gateway, &gate); -  gpnt = &gate; - -  api.vrf_id = VRF_DEFAULT; -  api.type = type; -  api.flags = 0; - -  api.message = 0; -  SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); -  api.nexthop_num = 1; -  api.nexthop = &gpnt; -  api.ifindex_num = 0; -  if (distance) -    { -      SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE); -      api.distance = distance; -    } -   - -  switch (command) -    { -    case ZEBRA_IPV4_ROUTE_ADD: -      zapi_ipv4_add (zclient, &p, &api); -      break; -    case ZEBRA_IPV4_ROUTE_DELETE: -      zapi_ipv4_delete (zclient, &p, &api); -      break; -    } +	struct zapi_ipv4 api; +	struct prefix_ipv4 p; +	struct in_addr gate; +	struct in_addr *gpnt; + +	str2prefix_ipv4(prefix, &p); +	inet_aton(gateway, &gate); +	gpnt = &gate; + +	api.vrf_id = VRF_DEFAULT; +	api.type = type; +	api.flags = 0; + +	api.message = 0; +	SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); +	api.nexthop_num = 1; +	api.nexthop = &gpnt; +	api.ifindex_num = 0; +	if (distance) { +		SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE); +		api.distance = distance; +	} + + +	switch (command) { +	case ZEBRA_IPV4_ROUTE_ADD: +		zapi_ipv4_add(zclient, &p, &api); +		break; +	case ZEBRA_IPV4_ROUTE_DELETE: +		zapi_ipv4_delete(zclient, &p, &api); +		break; +	}  }  /* IPv6 route add and delete test. */ -void -zebra_test_v6 (int sock) +void zebra_test_v6(int sock)  { -  struct prefix_ipv6 p; -  struct in6_addr nexthop; +	struct prefix_ipv6 p; +	struct in6_addr nexthop; -  str2prefix_ipv6 ("3ffe:506::2/128", &p); -  inet_pton (AF_INET6, "::1", &nexthop); +	str2prefix_ipv6("3ffe:506::2/128", &p); +	inet_pton(AF_INET6, "::1", &nexthop); -  /* zebra_ipv6_add (sock, ZEBRA_ROUTE_STATIC, 0, &p, &nexthop, 1); */ +	/* zebra_ipv6_add (sock, ZEBRA_ROUTE_STATIC, 0, &p, &nexthop, 1); */ -  sleep (5); -  /* zebra_ipv6_delete (sock, ZEBRA_ROUTE_STATIC, 0, &p, &nexthop, 1); */ +	sleep(5); +	/* zebra_ipv6_delete (sock, ZEBRA_ROUTE_STATIC, 0, &p, &nexthop, 1); */  }  /* Print out usage and exit. */ -void -usage_exit () +void usage_exit()  { -  fprintf (stderr, "Usage: client filename\n"); -  exit (1); +	fprintf(stderr, "Usage: client filename\n"); +	exit(1);  } -struct zebra_info  -{ -  char *str; -  int type; -} zebra_type[] =  -{ -  { "static", ZEBRA_ROUTE_STATIC }, -  { "rip",    ZEBRA_ROUTE_RIP }, -  { "ripng",  ZEBRA_ROUTE_RIPNG }, -  { "ospf",   ZEBRA_ROUTE_OSPF }, -  { "ospf6",  ZEBRA_ROUTE_OSPF6 }, -  { "bgp",    ZEBRA_ROUTE_BGP }, -  { "nhrp",   ZEBRA_ROUTE_NHRP }, -  { NULL,     0 } -}; +struct zebra_info { +	char *str; +	int type; +} zebra_type[] = {{"static", ZEBRA_ROUTE_STATIC}, {"rip", ZEBRA_ROUTE_RIP}, +		  {"ripng", ZEBRA_ROUTE_RIPNG},   {"ospf", ZEBRA_ROUTE_OSPF}, +		  {"ospf6", ZEBRA_ROUTE_OSPF6},   {"bgp", ZEBRA_ROUTE_BGP}, +		  {"nhrp", ZEBRA_ROUTE_NHRP},     {NULL, 0}};  /* Zebra route simulator. */ -void -zebra_sim (FILE *fp) +void zebra_sim(FILE *fp)  { -  char buf[BUFSIZ]; -  char distance_str[BUFSIZ]; -  u_char distance; - -  while (fgets (buf, sizeof buf, fp)) -    { -      int i; -      int ret; -      int type; -      char str[BUFSIZ], command[BUFSIZ], prefix[BUFSIZ], gateway[BUFSIZ]; - -      distance = 0; - -      if (*buf == '#') -	continue; - -      type = ZEBRA_ROUTE_STATIC; - -      ret = sscanf (buf, "%s %s %s %s %s\n", command, str, prefix, gateway, -		    distance_str); - -      if (ret == 5) -	{ -	  distance = atoi (distance_str); -	} -      else -	{ -	  ret = sscanf (buf, "%s %s %s %s\n", command, str, prefix, gateway); - -	  if (ret != 4) -	    continue; -	} - -      for (i = 0; i < 10; i++) -	{ -	  if (!zebra_type[i].str) -	    break; -	  if (strcmp (zebra_type[i].str, str) == 0) -	    { -	      type = zebra_type[i].type; -	      break; -	    } -	} -       -      if (strcmp (command, "add") == 0) -	{ -	  zebra_test_ipv4 (ZEBRA_IPV4_ROUTE_ADD, type, prefix, gateway, -			   distance); -	  printf ("%s", buf); -	  continue; +	char buf[BUFSIZ]; +	char distance_str[BUFSIZ]; +	u_char distance; + +	while (fgets(buf, sizeof buf, fp)) { +		int i; +		int ret; +		int type; +		char str[BUFSIZ], command[BUFSIZ], prefix[BUFSIZ], +			gateway[BUFSIZ]; + +		distance = 0; + +		if (*buf == '#') +			continue; + +		type = ZEBRA_ROUTE_STATIC; + +		ret = sscanf(buf, "%s %s %s %s %s\n", command, str, prefix, +			     gateway, distance_str); + +		if (ret == 5) { +			distance = atoi(distance_str); +		} else { +			ret = sscanf(buf, "%s %s %s %s\n", command, str, prefix, +				     gateway); + +			if (ret != 4) +				continue; +		} + +		for (i = 0; i < 10; i++) { +			if (!zebra_type[i].str) +				break; +			if (strcmp(zebra_type[i].str, str) == 0) { +				type = zebra_type[i].type; +				break; +			} +		} + +		if (strcmp(command, "add") == 0) { +			zebra_test_ipv4(ZEBRA_IPV4_ROUTE_ADD, type, prefix, +					gateway, distance); +			printf("%s", buf); +			continue; +		} + +		if (strcmp(command, "del") == 0) { +			zebra_test_ipv4(ZEBRA_IPV4_ROUTE_DELETE, type, prefix, +					gateway, distance); +			printf("%s", buf); +			continue; +		}  	} - -      if (strcmp (command, "del") == 0) -	{ -	  zebra_test_ipv4 (ZEBRA_IPV4_ROUTE_DELETE, type, prefix, gateway, -			   distance); -	  printf ("%s", buf); -	  continue; -	} -    }  }  /* Test zebra client main routine. */ -int -main (int argc, char **argv) +int main(int argc, char **argv)  { -  struct thread_master *master; -  FILE *fp; +	struct thread_master *master; +	FILE *fp; -  if (argc == 1) -      usage_exit (); +	if (argc == 1) +		usage_exit(); -  master = thread_master_create(); -  /* Establish connection to zebra. */ -  zclient = zclient_new(master); -  zclient->enable = 1; +	master = thread_master_create(); +	/* Establish connection to zebra. */ +	zclient = zclient_new(master); +	zclient->enable = 1;  #ifdef HAVE_TCP_ZEBRA -  zclient->sock = zclient_socket (); +	zclient->sock = zclient_socket();  #else -  zclient->sock = zclient_socket_un (ZEBRA_SERV_PATH); +	zclient->sock = zclient_socket_un(ZEBRA_SERV_PATH);  #endif /* HAVE_TCP_ZEBRA */ -  /* Open simulation file. */ -  fp = fopen (argv[1], "r"); -  if (fp == NULL) -    { -      fprintf (stderr,"%% Can't open configuration file %s due to '%s'\n", -               argv[1], safe_strerror(errno)); -      exit (1); -    } +	/* Open simulation file. */ +	fp = fopen(argv[1], "r"); +	if (fp == NULL) { +		fprintf(stderr, +			"%% Can't open configuration file %s due to '%s'\n", +			argv[1], safe_strerror(errno)); +		exit(1); +	} -  /* Do main work. */ -  zebra_sim (fp); +	/* Do main work. */ +	zebra_sim(fp); -  sleep (100); +	sleep(100); -  fclose (fp); -  close (sock); +	fclose(fp); +	close(sock); -  return 0; +	return 0;  } diff --git a/zebra/connected.c b/zebra/connected.c index 0ceaddc8e3..322a93a556 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -17,7 +17,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #include <zebra.h> @@ -43,533 +43,528 @@  #include "zebra/debug.h"  /* communicate the withdrawal of a connected address */ -static void -connected_withdraw (struct connected *ifc) +static void connected_withdraw(struct connected *ifc)  { -  if (! ifc) -    return; +	if (!ifc) +		return; -  /* Update interface address information to protocol daemon. */ -  if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) -    { -      zebra_interface_address_delete_update (ifc->ifp, ifc); +	/* Update interface address information to protocol daemon. */ +	if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) { +		zebra_interface_address_delete_update(ifc->ifp, ifc); -      if (ifc->address->family == AF_INET) -        if_subnet_delete (ifc->ifp, ifc); +		if (ifc->address->family == AF_INET) +			if_subnet_delete(ifc->ifp, ifc); -      if (ifc->address->family == AF_INET) -        connected_down_ipv4 (ifc->ifp, ifc); -      else -        connected_down_ipv6 (ifc->ifp, ifc); +		if (ifc->address->family == AF_INET) +			connected_down_ipv4(ifc->ifp, ifc); +		else +			connected_down_ipv6(ifc->ifp, ifc); -      UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL); -    } +		UNSET_FLAG(ifc->conf, ZEBRA_IFC_REAL); +	} -  /* The address is not in the kernel anymore, so clear the flag */ -  UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED); +	/* The address is not in the kernel anymore, so clear the flag */ +	UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED); -  if (!CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)) -    { -      listnode_delete (ifc->ifp->connected, ifc); -      connected_free (ifc); -    } +	if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED)) { +		listnode_delete(ifc->ifp->connected, ifc); +		connected_free(ifc); +	}  } -static void -connected_announce (struct interface *ifp, struct connected *ifc) +static void connected_announce(struct interface *ifp, struct connected *ifc)  { -  if (!ifc) -    return; - -  if (!if_is_loopback(ifp) && ifc->address->family == AF_INET) -    { -      if (ifc->address->prefixlen == 32) -	  SET_FLAG (ifc->flags, ZEBRA_IFA_UNNUMBERED); -      else -	  UNSET_FLAG (ifc->flags, ZEBRA_IFA_UNNUMBERED); -    } - -  listnode_add (ifp->connected, ifc); - -  /* Update interface address information to protocol daemon. */ -  if (ifc->address->family == AF_INET) -    if_subnet_add (ifp, ifc); - -  zebra_interface_address_add_update (ifp, ifc); - -  if (if_is_operative(ifp)) -    { -      if (ifc->address->family == AF_INET) -        connected_up_ipv4 (ifp, ifc); -      else -        connected_up_ipv6 (ifp, ifc); -    } +	if (!ifc) +		return; + +	if (!if_is_loopback(ifp) && ifc->address->family == AF_INET) { +		if (ifc->address->prefixlen == 32) +			SET_FLAG(ifc->flags, ZEBRA_IFA_UNNUMBERED); +		else +			UNSET_FLAG(ifc->flags, ZEBRA_IFA_UNNUMBERED); +	} + +	listnode_add(ifp->connected, ifc); + +	/* Update interface address information to protocol daemon. */ +	if (ifc->address->family == AF_INET) +		if_subnet_add(ifp, ifc); + +	zebra_interface_address_add_update(ifp, ifc); + +	if (if_is_operative(ifp)) { +		if (ifc->address->family == AF_INET) +			connected_up_ipv4(ifp, ifc); +		else +			connected_up_ipv6(ifp, ifc); +	}  }  /* If same interface address is already exist... */ -struct connected * -connected_check (struct interface *ifp, struct prefix *p) +struct connected *connected_check(struct interface *ifp, struct prefix *p)  { -  struct connected *ifc; -  struct listnode *node; +	struct connected *ifc; +	struct listnode *node; -  for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, ifc)) -    if (prefix_same (ifc->address, p)) -      return ifc; +	for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) +		if (prefix_same(ifc->address, p)) +			return ifc; -  return NULL; +	return NULL;  }  /* Check if two ifc's describe the same address in the same state */ -static int -connected_same (struct connected *ifc1, struct connected *ifc2) +static int connected_same(struct connected *ifc1, struct connected *ifc2)  { -  if (ifc1->ifp != ifc2->ifp) -    return 0; -   -  if (ifc1->destination) -    if (!ifc2->destination) -      return 0; -  if (ifc2->destination) -    if (!ifc1->destination) -      return 0; -   -  if (ifc1->destination && ifc2->destination) -    if (!prefix_same (ifc1->destination, ifc2->destination)) -      return 0; - -  if (ifc1->flags != ifc2->flags) -    return 0; - -  if (ifc1->conf != ifc2->conf) -    return 0; -   -  return 1; +	if (ifc1->ifp != ifc2->ifp) +		return 0; + +	if (ifc1->destination) +		if (!ifc2->destination) +			return 0; +	if (ifc2->destination) +		if (!ifc1->destination) +			return 0; + +	if (ifc1->destination && ifc2->destination) +		if (!prefix_same(ifc1->destination, ifc2->destination)) +			return 0; + +	if (ifc1->flags != ifc2->flags) +		return 0; + +	if (ifc1->conf != ifc2->conf) +		return 0; + +	return 1;  }  /* Handle changes to addresses and send the neccesary announcements   * to clients. */ -static void -connected_update(struct interface *ifp, struct connected *ifc) +static void connected_update(struct interface *ifp, struct connected *ifc)  { -  struct connected *current; -   -  /* Check same connected route. */ -  if ((current = connected_check (ifp, (struct prefix *) ifc->address))) -    { -      if (CHECK_FLAG(current->conf, ZEBRA_IFC_CONFIGURED)) -        SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED); -	 -      /* Avoid spurious withdraws, this might be just the kernel 'reflecting' -       * back an address we have already added. -       */ -      if (connected_same (current, ifc)) -        { -          /* nothing to do */ -          connected_free (ifc); -          return; -        } - -      /* Clear the configured flag on the old ifc, so it will be freed by -       * connected withdraw. */ -      UNSET_FLAG(current->conf, ZEBRA_IFC_CONFIGURED); -      connected_withdraw (current); /* implicit withdraw - freebsd does this */ -    } - -  /* If the connected is new or has changed, announce it, if it is usable */ -  if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) -    connected_announce(ifp, ifc); +	struct connected *current; + +	/* Check same connected route. */ +	if ((current = connected_check(ifp, (struct prefix *)ifc->address))) { +		if (CHECK_FLAG(current->conf, ZEBRA_IFC_CONFIGURED)) +			SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED); + +		/* Avoid spurious withdraws, this might be just the kernel +		 * 'reflecting' +		 * back an address we have already added. +		 */ +		if (connected_same(current, ifc)) { +			/* nothing to do */ +			connected_free(ifc); +			return; +		} + +		/* Clear the configured flag on the old ifc, so it will be freed +		 * by +		 * connected withdraw. */ +		UNSET_FLAG(current->conf, ZEBRA_IFC_CONFIGURED); +		connected_withdraw( +			current); /* implicit withdraw - freebsd does this */ +	} + +	/* If the connected is new or has changed, announce it, if it is usable +	 */ +	if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) +		connected_announce(ifp, ifc);  }  /* Called from if_up(). */ -void -connected_up_ipv4 (struct interface *ifp, struct connected *ifc) +void connected_up_ipv4(struct interface *ifp, struct connected *ifc)  { -  struct prefix p; - -  if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) -    return; - -  PREFIX_COPY_IPV4((struct prefix_ipv4 *)&p, CONNECTED_PREFIX(ifc)); - -  /* Apply mask to the network. */ -  apply_mask (&p); - -  /* In case of connected address is 0.0.0.0/0 we treat it tunnel -     address. */ -  if (prefix_ipv4_any ((struct prefix_ipv4 *)&p)) -    return; - -  rib_add (AFI_IP, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, -	   0, 0, &p, NULL, NULL, NULL, ifp->ifindex, -	   RT_TABLE_MAIN, ifp->metric, 0, 0); - -  rib_add (AFI_IP, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, -	   0, 0, &p, NULL, NULL, NULL, ifp->ifindex, -	   RT_TABLE_MAIN, ifp->metric, 0, 0); - -  if (IS_ZEBRA_DEBUG_RIB_DETAILED) -    zlog_debug ("%u: IF %s IPv4 address add/up, scheduling RIB processing", -                ifp->vrf_id, ifp->name); -  rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE); - -  /* Schedule LSP forwarding entries for processing, if appropriate. */ -  if (ifp->vrf_id == VRF_DEFAULT) -    { -      if (IS_ZEBRA_DEBUG_MPLS) -        zlog_debug ("%u: IF %s IPv4 address add/up, scheduling MPLS processing", -                ifp->vrf_id, ifp->name); -      mpls_mark_lsps_for_processing (vrf_info_lookup(ifp->vrf_id)); -    } +	struct prefix p; + +	if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) +		return; + +	PREFIX_COPY_IPV4((struct prefix_ipv4 *)&p, CONNECTED_PREFIX(ifc)); + +	/* Apply mask to the network. */ +	apply_mask(&p); + +	/* In case of connected address is 0.0.0.0/0 we treat it tunnel +	   address. */ +	if (prefix_ipv4_any((struct prefix_ipv4 *)&p)) +		return; + +	rib_add(AFI_IP, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, +		&p, NULL, NULL, NULL, ifp->ifindex, RT_TABLE_MAIN, ifp->metric, +		0, 0); + +	rib_add(AFI_IP, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, +		&p, NULL, NULL, NULL, ifp->ifindex, RT_TABLE_MAIN, ifp->metric, +		0, 0); + +	if (IS_ZEBRA_DEBUG_RIB_DETAILED) +		zlog_debug( +			"%u: IF %s IPv4 address add/up, scheduling RIB processing", +			ifp->vrf_id, ifp->name); +	rib_update(ifp->vrf_id, RIB_UPDATE_IF_CHANGE); + +	/* Schedule LSP forwarding entries for processing, if appropriate. */ +	if (ifp->vrf_id == VRF_DEFAULT) { +		if (IS_ZEBRA_DEBUG_MPLS) +			zlog_debug( +				"%u: IF %s IPv4 address add/up, scheduling MPLS processing", +				ifp->vrf_id, ifp->name); +		mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id)); +	}  }  /* Add connected IPv4 route to the interface. */ -void -connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr,  -		    u_char prefixlen, struct in_addr *broad,  -		    const char *label) +void connected_add_ipv4(struct interface *ifp, int flags, struct in_addr *addr, +			u_char prefixlen, struct in_addr *broad, +			const char *label)  { -  struct prefix_ipv4 *p; -  struct connected *ifc; - -  if (ipv4_martian(addr)) -    return; - -  /* Make connected structure. */ -  ifc = connected_new (); -  ifc->ifp = ifp; -  ifc->flags = flags; -  /* If we get a notification from the kernel, -   * we can safely assume the address is known to the kernel */ -  SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED); - -  /* Allocate new connected address. */ -  p = prefix_ipv4_new (); -  p->family = AF_INET; -  p->prefix = *addr; -  p->prefixlen = prefixlen; -  ifc->address = (struct prefix *) p; -   -  /* If there is broadcast or peer address. */ -  if (broad) -    { -      p = prefix_ipv4_new (); -      p->family = AF_INET; -      p->prefix = *broad; -      p->prefixlen = prefixlen; -      ifc->destination = (struct prefix *) p; - -      /* validate the destination address */ -      if (CONNECTED_PEER(ifc)) -        { -	  if (IPV4_ADDR_SAME(addr,broad)) -	    zlog_warn("warning: interface %s has same local and peer " -		      "address %s, routing protocols may malfunction", -		      ifp->name,inet_ntoa(*addr)); -        } -      else -        { -	  if (broad->s_addr != ipv4_broadcast_addr(addr->s_addr,prefixlen)) -	    { -	      char buf[2][INET_ADDRSTRLEN]; -	      struct in_addr bcalc; -	      bcalc.s_addr = ipv4_broadcast_addr(addr->s_addr,prefixlen); -	      zlog_warn("warning: interface %s broadcast addr %s/%d != " -	       		"calculated %s, routing protocols may malfunction", -	    		ifp->name, -			inet_ntop (AF_INET, broad, buf[0], sizeof(buf[0])), -			prefixlen, -			inet_ntop (AF_INET, &bcalc, buf[1], sizeof(buf[1]))); -	    } -        } - -    } -  else -    { -      if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER)) -        { -	  zlog_warn("warning: %s called for interface %s " -		    "with peer flag set, but no peer address supplied", -		    __func__, ifp->name); -	  UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER); +	struct prefix_ipv4 *p; +	struct connected *ifc; + +	if (ipv4_martian(addr)) +		return; + +	/* Make connected structure. */ +	ifc = connected_new(); +	ifc->ifp = ifp; +	ifc->flags = flags; +	/* If we get a notification from the kernel, +	 * we can safely assume the address is known to the kernel */ +	SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED); + +	/* Allocate new connected address. */ +	p = prefix_ipv4_new(); +	p->family = AF_INET; +	p->prefix = *addr; +	p->prefixlen = prefixlen; +	ifc->address = (struct prefix *)p; + +	/* If there is broadcast or peer address. */ +	if (broad) { +		p = prefix_ipv4_new(); +		p->family = AF_INET; +		p->prefix = *broad; +		p->prefixlen = prefixlen; +		ifc->destination = (struct prefix *)p; + +		/* validate the destination address */ +		if (CONNECTED_PEER(ifc)) { +			if (IPV4_ADDR_SAME(addr, broad)) +				zlog_warn( +					"warning: interface %s has same local and peer " +					"address %s, routing protocols may malfunction", +					ifp->name, inet_ntoa(*addr)); +		} else { +			if (broad->s_addr +			    != ipv4_broadcast_addr(addr->s_addr, prefixlen)) { +				char buf[2][INET_ADDRSTRLEN]; +				struct in_addr bcalc; +				bcalc.s_addr = ipv4_broadcast_addr(addr->s_addr, +								   prefixlen); +				zlog_warn( +					"warning: interface %s broadcast addr %s/%d != " +					"calculated %s, routing protocols may malfunction", +					ifp->name, +					inet_ntop(AF_INET, broad, buf[0], +						  sizeof(buf[0])), +					prefixlen, +					inet_ntop(AF_INET, &bcalc, buf[1], +						  sizeof(buf[1]))); +			} +		} + +	} else { +		if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER)) { +			zlog_warn( +				"warning: %s called for interface %s " +				"with peer flag set, but no peer address supplied", +				__func__, ifp->name); +			UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER); +		} + +		/* no broadcast or destination address was supplied */ +		if ((prefixlen == IPV4_MAX_PREFIXLEN) && if_is_pointopoint(ifp)) +			zlog_warn( +				"warning: PtP interface %s with addr %s/%d needs a " +				"peer address", +				ifp->name, inet_ntoa(*addr), prefixlen);  	} -      /* no broadcast or destination address was supplied */ -      if ((prefixlen == IPV4_MAX_PREFIXLEN) && if_is_pointopoint(ifp)) -	zlog_warn("warning: PtP interface %s with addr %s/%d needs a " -		  "peer address",ifp->name,inet_ntoa(*addr),prefixlen); -    } +	/* Label of this address. */ +	if (label) +		ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label); -  /* Label of this address. */ -  if (label) -    ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label); +	/* For all that I know an IPv4 address is always ready when we receive +	 * the notification. So it should be safe to set the REAL flag here. */ +	SET_FLAG(ifc->conf, ZEBRA_IFC_REAL); -  /* For all that I know an IPv4 address is always ready when we receive -   * the notification. So it should be safe to set the REAL flag here. */ -  SET_FLAG(ifc->conf, ZEBRA_IFC_REAL); - -  connected_update(ifp, ifc); +	connected_update(ifp, ifc);  } -void -connected_down_ipv4 (struct interface *ifp, struct connected *ifc) +void connected_down_ipv4(struct interface *ifp, struct connected *ifc)  { -  struct prefix p; +	struct prefix p; -  if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) -    return; +	if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) +		return; -  PREFIX_COPY_IPV4(&p, CONNECTED_PREFIX(ifc)); +	PREFIX_COPY_IPV4(&p, CONNECTED_PREFIX(ifc)); -  /* Apply mask to the network. */ -  apply_mask (&p); +	/* Apply mask to the network. */ +	apply_mask(&p); -  /* In case of connected address is 0.0.0.0/0 we treat it tunnel -     address. */ -  if (prefix_ipv4_any ((struct prefix_ipv4 *)&p)) -    return; +	/* In case of connected address is 0.0.0.0/0 we treat it tunnel +	   address. */ +	if (prefix_ipv4_any((struct prefix_ipv4 *)&p)) +		return; -  /* Same logic as for connected_up_ipv4(): push the changes into the head. */ -  rib_delete (AFI_IP, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, -	      0, 0, &p, NULL, NULL, ifp->ifindex, 0); +	/* Same logic as for connected_up_ipv4(): push the changes into the +	 * head. */ +	rib_delete(AFI_IP, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, +		   &p, NULL, NULL, ifp->ifindex, 0); -  rib_delete (AFI_IP, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, -	      0, 0, &p, NULL, NULL, ifp->ifindex, 0); +	rib_delete(AFI_IP, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, +		   0, &p, NULL, NULL, ifp->ifindex, 0); -  if (IS_ZEBRA_DEBUG_RIB_DETAILED) -    zlog_debug ("%u: IF %s IPv4 address down, scheduling RIB processing", -                ifp->vrf_id, ifp->name); +	if (IS_ZEBRA_DEBUG_RIB_DETAILED) +		zlog_debug( +			"%u: IF %s IPv4 address down, scheduling RIB processing", +			ifp->vrf_id, ifp->name); -  rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE); +	rib_update(ifp->vrf_id, RIB_UPDATE_IF_CHANGE); -  /* Schedule LSP forwarding entries for processing, if appropriate. */ -  if (ifp->vrf_id == VRF_DEFAULT) -    { -      if (IS_ZEBRA_DEBUG_MPLS) -        zlog_debug ("%u: IF %s IPv4 address add/up, scheduling MPLS processing", -                ifp->vrf_id, ifp->name); -      mpls_mark_lsps_for_processing (vrf_info_lookup(ifp->vrf_id)); -    } +	/* Schedule LSP forwarding entries for processing, if appropriate. */ +	if (ifp->vrf_id == VRF_DEFAULT) { +		if (IS_ZEBRA_DEBUG_MPLS) +			zlog_debug( +				"%u: IF %s IPv4 address add/up, scheduling MPLS processing", +				ifp->vrf_id, ifp->name); +		mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id)); +	}  }  /* Delete connected IPv4 route to the interface. */ -void -connected_delete_ipv4 (struct interface *ifp, int flags, struct in_addr *addr, -		       u_char prefixlen, struct in_addr *broad) +void connected_delete_ipv4(struct interface *ifp, int flags, +			   struct in_addr *addr, u_char prefixlen, +			   struct in_addr *broad)  { -  struct prefix_ipv4 p; -  struct connected *ifc; - -  memset (&p, 0, sizeof (struct prefix_ipv4)); -  p.family = AF_INET; -  p.prefix = *addr; -  p.prefixlen = prefixlen; - -  ifc = connected_check (ifp, (struct prefix *) &p); -  if (! ifc) -    return; - -  connected_withdraw (ifc); - -  if (IS_ZEBRA_DEBUG_RIB_DETAILED) -    zlog_debug ("%u: IF %s IPv4 address del, scheduling RIB processing", -                ifp->vrf_id, ifp->name); - -  rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE); - -  /* Schedule LSP forwarding entries for processing, if appropriate. */ -  if (ifp->vrf_id == VRF_DEFAULT) -    { -      if (IS_ZEBRA_DEBUG_MPLS) -        zlog_debug ("%u: IF %s IPv4 address add/up, scheduling MPLS processing", -                ifp->vrf_id, ifp->name); -      mpls_mark_lsps_for_processing (vrf_info_lookup(ifp->vrf_id)); -    } +	struct prefix_ipv4 p; +	struct connected *ifc; + +	memset(&p, 0, sizeof(struct prefix_ipv4)); +	p.family = AF_INET; +	p.prefix = *addr; +	p.prefixlen = prefixlen; + +	ifc = connected_check(ifp, (struct prefix *)&p); +	if (!ifc) +		return; + +	connected_withdraw(ifc); + +	if (IS_ZEBRA_DEBUG_RIB_DETAILED) +		zlog_debug( +			"%u: IF %s IPv4 address del, scheduling RIB processing", +			ifp->vrf_id, ifp->name); + +	rib_update(ifp->vrf_id, RIB_UPDATE_IF_CHANGE); + +	/* Schedule LSP forwarding entries for processing, if appropriate. */ +	if (ifp->vrf_id == VRF_DEFAULT) { +		if (IS_ZEBRA_DEBUG_MPLS) +			zlog_debug( +				"%u: IF %s IPv4 address add/up, scheduling MPLS processing", +				ifp->vrf_id, ifp->name); +		mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id)); +	}  } -void -connected_up_ipv6 (struct interface *ifp, struct connected *ifc) +void connected_up_ipv6(struct interface *ifp, struct connected *ifc)  { -  struct prefix p; +	struct prefix p; -  if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) -    return; +	if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) +		return; -  PREFIX_COPY_IPV6((struct prefix_ipv6 *)&p, CONNECTED_PREFIX(ifc)); +	PREFIX_COPY_IPV6((struct prefix_ipv6 *)&p, CONNECTED_PREFIX(ifc)); -  /* Apply mask to the network. */ -  apply_mask (&p); +	/* Apply mask to the network. */ +	apply_mask(&p);  #ifndef LINUX -  /* XXX: It is already done by rib_bogus_ipv6 within rib_add */ -  if (IN6_IS_ADDR_UNSPECIFIED (&p.u.prefix6)) -    return; +	/* XXX: It is already done by rib_bogus_ipv6 within rib_add */ +	if (IN6_IS_ADDR_UNSPECIFIED(&p.u.prefix6)) +		return;  #endif -  rib_add (AFI_IP6, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, -	   0, 0, &p, NULL, NULL, NULL, ifp->ifindex, -	   RT_TABLE_MAIN, ifp->metric, 0, 0); +	rib_add(AFI_IP6, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, +		&p, NULL, NULL, NULL, ifp->ifindex, RT_TABLE_MAIN, ifp->metric, +		0, 0); -  if (IS_ZEBRA_DEBUG_RIB_DETAILED) -    zlog_debug ("%u: IF %s IPv6 address down, scheduling RIB processing", -                ifp->vrf_id, ifp->name); +	if (IS_ZEBRA_DEBUG_RIB_DETAILED) +		zlog_debug( +			"%u: IF %s IPv6 address down, scheduling RIB processing", +			ifp->vrf_id, ifp->name); -  rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE); +	rib_update(ifp->vrf_id, RIB_UPDATE_IF_CHANGE); -  /* Schedule LSP forwarding entries for processing, if appropriate. */ -  if (ifp->vrf_id == VRF_DEFAULT) -    { -      if (IS_ZEBRA_DEBUG_MPLS) -        zlog_debug ("%u: IF %s IPv4 address add/up, scheduling MPLS processing", -                ifp->vrf_id, ifp->name); -      mpls_mark_lsps_for_processing (vrf_info_lookup(ifp->vrf_id)); -    } +	/* Schedule LSP forwarding entries for processing, if appropriate. */ +	if (ifp->vrf_id == VRF_DEFAULT) { +		if (IS_ZEBRA_DEBUG_MPLS) +			zlog_debug( +				"%u: IF %s IPv4 address add/up, scheduling MPLS processing", +				ifp->vrf_id, ifp->name); +		mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id)); +	}  }  /* Add connected IPv6 route to the interface. */ -void -connected_add_ipv6 (struct interface *ifp, int flags, struct in6_addr *addr, -		    u_char prefixlen, struct in6_addr *broad, -		    const char *label) +void connected_add_ipv6(struct interface *ifp, int flags, struct in6_addr *addr, +			u_char prefixlen, struct in6_addr *broad, +			const char *label)  { -  struct prefix_ipv6 *p; -  struct connected *ifc; - -  if (ipv6_martian(addr)) -    return; - -  /* Make connected structure. */ -  ifc = connected_new (); -  ifc->ifp = ifp; -  ifc->flags = flags; -  /* If we get a notification from the kernel, -   * we can safely assume the address is known to the kernel */ -  SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED); - -  /* Allocate new connected address. */ -  p = prefix_ipv6_new (); -  p->family = AF_INET6; -  IPV6_ADDR_COPY (&p->prefix, addr); -  p->prefixlen = prefixlen; -  ifc->address = (struct prefix *) p; - -  /* If there is broadcast or peer address. */ -  if (broad) -    { -      if (IN6_IS_ADDR_UNSPECIFIED(broad)) -	zlog_warn("warning: %s called for interface %s with unspecified " -		  "destination address; ignoring!", __func__, ifp->name); -      else -	{ -	  p = prefix_ipv6_new (); -	  p->family = AF_INET6; -	  IPV6_ADDR_COPY (&p->prefix, broad); -	  p->prefixlen = prefixlen; -	  ifc->destination = (struct prefix *) p; +	struct prefix_ipv6 *p; +	struct connected *ifc; + +	if (ipv6_martian(addr)) +		return; + +	/* Make connected structure. */ +	ifc = connected_new(); +	ifc->ifp = ifp; +	ifc->flags = flags; +	/* If we get a notification from the kernel, +	 * we can safely assume the address is known to the kernel */ +	SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED); + +	/* Allocate new connected address. */ +	p = prefix_ipv6_new(); +	p->family = AF_INET6; +	IPV6_ADDR_COPY(&p->prefix, addr); +	p->prefixlen = prefixlen; +	ifc->address = (struct prefix *)p; + +	/* If there is broadcast or peer address. */ +	if (broad) { +		if (IN6_IS_ADDR_UNSPECIFIED(broad)) +			zlog_warn( +				"warning: %s called for interface %s with unspecified " +				"destination address; ignoring!", +				__func__, ifp->name); +		else { +			p = prefix_ipv6_new(); +			p->family = AF_INET6; +			IPV6_ADDR_COPY(&p->prefix, broad); +			p->prefixlen = prefixlen; +			ifc->destination = (struct prefix *)p; +		} +	} +	if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER) && !ifc->destination) { +		zlog_warn( +			"warning: %s called for interface %s " +			"with peer flag set, but no peer address supplied", +			__func__, ifp->name); +		UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);  	} -    } -  if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER) && !ifc->destination) -    { -      zlog_warn("warning: %s called for interface %s " -		"with peer flag set, but no peer address supplied", -		__func__, ifp->name); -      UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER); -    } - -  /* Label of this address. */ -  if (label) -    ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label); - -  /* On Linux, we only get here when DAD is complete, therefore we can set -   * ZEBRA_IFC_REAL. -   * -   * On BSD, there currently doesn't seem to be a way to check for completion of -   * DAD, so we replicate the old behaviour and set ZEBRA_IFC_REAL, although DAD -   * might still be running. -   */ -  SET_FLAG(ifc->conf, ZEBRA_IFC_REAL); -  connected_update(ifp, ifc); + +	/* Label of this address. */ +	if (label) +		ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label); + +	/* On Linux, we only get here when DAD is complete, therefore we can set +	 * ZEBRA_IFC_REAL. +	 * +	 * On BSD, there currently doesn't seem to be a way to check for +	 * completion of +	 * DAD, so we replicate the old behaviour and set ZEBRA_IFC_REAL, +	 * although DAD +	 * might still be running. +	 */ +	SET_FLAG(ifc->conf, ZEBRA_IFC_REAL); +	connected_update(ifp, ifc);  } -void -connected_down_ipv6 (struct interface *ifp, struct connected *ifc) +void connected_down_ipv6(struct interface *ifp, struct connected *ifc)  { -  struct prefix p; +	struct prefix p; -  if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) -    return; +	if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) +		return; -  PREFIX_COPY_IPV6(&p, CONNECTED_PREFIX(ifc)); +	PREFIX_COPY_IPV6(&p, CONNECTED_PREFIX(ifc)); -  apply_mask (&p); +	apply_mask(&p); -  if (IN6_IS_ADDR_UNSPECIFIED (&p.u.prefix6)) -    return; +	if (IN6_IS_ADDR_UNSPECIFIED(&p.u.prefix6)) +		return; -  rib_delete (AFI_IP6, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, -	      0, 0, &p, NULL, NULL, ifp->ifindex, 0); +	rib_delete(AFI_IP6, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, +		   0, &p, NULL, NULL, ifp->ifindex, 0); -  if (IS_ZEBRA_DEBUG_RIB_DETAILED) -    zlog_debug ("%u: IF %s IPv6 address down, scheduling RIB processing", -                ifp->vrf_id, ifp->name); +	if (IS_ZEBRA_DEBUG_RIB_DETAILED) +		zlog_debug( +			"%u: IF %s IPv6 address down, scheduling RIB processing", +			ifp->vrf_id, ifp->name); -  rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE); +	rib_update(ifp->vrf_id, RIB_UPDATE_IF_CHANGE); -  /* Schedule LSP forwarding entries for processing, if appropriate. */ -  if (ifp->vrf_id == VRF_DEFAULT) -    { -      if (IS_ZEBRA_DEBUG_MPLS) -        zlog_debug ("%u: IF %s IPv4 address add/up, scheduling MPLS processing", -                ifp->vrf_id, ifp->name); -      mpls_mark_lsps_for_processing (vrf_info_lookup(ifp->vrf_id)); -    } +	/* Schedule LSP forwarding entries for processing, if appropriate. */ +	if (ifp->vrf_id == VRF_DEFAULT) { +		if (IS_ZEBRA_DEBUG_MPLS) +			zlog_debug( +				"%u: IF %s IPv4 address add/up, scheduling MPLS processing", +				ifp->vrf_id, ifp->name); +		mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id)); +	}  } -void -connected_delete_ipv6 (struct interface *ifp, struct in6_addr *address, -		       u_char prefixlen, struct in6_addr *broad) +void connected_delete_ipv6(struct interface *ifp, struct in6_addr *address, +			   u_char prefixlen, struct in6_addr *broad)  { -  struct prefix_ipv6 p; -  struct connected *ifc; -   -  memset (&p, 0, sizeof (struct prefix_ipv6)); -  p.family = AF_INET6; -  memcpy (&p.prefix, address, sizeof (struct in6_addr)); -  p.prefixlen = prefixlen; - -  ifc = connected_check (ifp, (struct prefix *) &p); -  if (! ifc) -    return; - -  connected_withdraw (ifc); - -  if (IS_ZEBRA_DEBUG_RIB_DETAILED) -    zlog_debug ("%u: IF %s IPv6 address del, scheduling RIB processing", -                ifp->vrf_id, ifp->name); - -  rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE); - -  /* Schedule LSP forwarding entries for processing, if appropriate. */ -  if (ifp->vrf_id == VRF_DEFAULT) -    { -      if (IS_ZEBRA_DEBUG_MPLS) -        zlog_debug ("%u: IF %s IPv4 address add/up, scheduling MPLS processing", -                ifp->vrf_id, ifp->name); -      mpls_mark_lsps_for_processing (vrf_info_lookup(ifp->vrf_id)); -    } +	struct prefix_ipv6 p; +	struct connected *ifc; + +	memset(&p, 0, sizeof(struct prefix_ipv6)); +	p.family = AF_INET6; +	memcpy(&p.prefix, address, sizeof(struct in6_addr)); +	p.prefixlen = prefixlen; + +	ifc = connected_check(ifp, (struct prefix *)&p); +	if (!ifc) +		return; + +	connected_withdraw(ifc); + +	if (IS_ZEBRA_DEBUG_RIB_DETAILED) +		zlog_debug( +			"%u: IF %s IPv6 address del, scheduling RIB processing", +			ifp->vrf_id, ifp->name); + +	rib_update(ifp->vrf_id, RIB_UPDATE_IF_CHANGE); + +	/* Schedule LSP forwarding entries for processing, if appropriate. */ +	if (ifp->vrf_id == VRF_DEFAULT) { +		if (IS_ZEBRA_DEBUG_MPLS) +			zlog_debug( +				"%u: IF %s IPv4 address add/up, scheduling MPLS processing", +				ifp->vrf_id, ifp->name); +		mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id)); +	}  } -int -connected_is_unnumbered (struct interface *ifp) +int connected_is_unnumbered(struct interface *ifp)  { -  struct connected *connected; -  struct listnode *node; - -  for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected)) -    { -      if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) && -	  connected->address->family == AF_INET) -	return CHECK_FLAG(connected->flags, ZEBRA_IFA_UNNUMBERED); -    } -  return 0; +	struct connected *connected; +	struct listnode *node; + +	for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) { +		if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL) +		    && connected->address->family == AF_INET) +			return CHECK_FLAG(connected->flags, +					  ZEBRA_IFA_UNNUMBERED); +	} +	return 0;  } diff --git a/zebra/connected.h b/zebra/connected.h index bdcf6085e4..94e4de41ca 100644 --- a/zebra/connected.h +++ b/zebra/connected.h @@ -17,41 +17,38 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #ifndef _ZEBRA_CONNECTED_H  #define _ZEBRA_CONNECTED_H -extern struct connected * -connected_check (struct interface *ifp, struct prefix *p); +extern struct connected *connected_check(struct interface *ifp, +					 struct prefix *p); -extern void -connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr,  -		    u_char prefixlen, struct in_addr *broad,  -		    const char *label); +extern void connected_add_ipv4(struct interface *ifp, int flags, +			       struct in_addr *addr, u_char prefixlen, +			       struct in_addr *broad, const char *label); -extern void -connected_delete_ipv4 (struct interface *ifp, int flags, struct in_addr *addr, -		       u_char prefixlen, struct in_addr *broad); +extern void connected_delete_ipv4(struct interface *ifp, int flags, +				  struct in_addr *addr, u_char prefixlen, +				  struct in_addr *broad); -extern void -connected_delete_ipv4_unnumbered (struct connected *ifc); +extern void connected_delete_ipv4_unnumbered(struct connected *ifc); -extern void connected_up_ipv4 (struct interface *, struct connected *); -extern void connected_down_ipv4 (struct interface *, struct connected *); +extern void connected_up_ipv4(struct interface *, struct connected *); +extern void connected_down_ipv4(struct interface *, struct connected *); -extern void -connected_add_ipv6 (struct interface *ifp, int flags, struct in6_addr *address, -		    u_char prefixlen, struct in6_addr *broad, -		    const char *label); -extern void -connected_delete_ipv6 (struct interface *ifp, struct in6_addr *address, -		       u_char prefixlen, struct in6_addr *broad); +extern void connected_add_ipv6(struct interface *ifp, int flags, +			       struct in6_addr *address, u_char prefixlen, +			       struct in6_addr *broad, const char *label); +extern void connected_delete_ipv6(struct interface *ifp, +				  struct in6_addr *address, u_char prefixlen, +				  struct in6_addr *broad); -extern void connected_up_ipv6 (struct interface *, struct connected *); -extern void connected_down_ipv6 (struct interface *ifp, struct connected *); +extern void connected_up_ipv6(struct interface *, struct connected *); +extern void connected_down_ipv6(struct interface *ifp, struct connected *); -extern int connected_is_unnumbered (struct interface *); +extern int connected_is_unnumbered(struct interface *);  #endif /*_ZEBRA_CONNECTED_H */ diff --git a/zebra/debug.c b/zebra/debug.c index 6f59dc0ac2..67c9d16746 100644 --- a/zebra/debug.c +++ b/zebra/debug.c @@ -15,9 +15,9 @@   * General Public License for more details.   *   * You should have received a copy of the GNU General Public License - * along with GNU Zebra; see the file COPYING.  If not, write to the  - * Free Software Foundation, Inc., 59 Temple Place - Suite 330,  - * Boston, MA 02111-1307, USA.   + * along with GNU Zebra; see the file COPYING.  If not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA.   */  #include <zebra.h> @@ -41,55 +41,60 @@ DEFUN (show_debugging_zebra,         "Debugging information\n"         "Zebra configuration\n")  { -  vty_out (vty, "Zebra debugging status:%s", VTY_NEWLINE); - -  if (IS_ZEBRA_DEBUG_EVENT) -    vty_out (vty, "  Zebra event debugging is on%s", VTY_NEWLINE); - -  if (IS_ZEBRA_DEBUG_PACKET) -    { -      if (IS_ZEBRA_DEBUG_SEND && IS_ZEBRA_DEBUG_RECV) -	{ -	  vty_out (vty, "  Zebra packet%s debugging is on%s", -		   IS_ZEBRA_DEBUG_DETAIL ? " detail" : "", -		   VTY_NEWLINE); +	vty_out(vty, "Zebra debugging status:%s", VTY_NEWLINE); + +	if (IS_ZEBRA_DEBUG_EVENT) +		vty_out(vty, "  Zebra event debugging is on%s", VTY_NEWLINE); + +	if (IS_ZEBRA_DEBUG_PACKET) { +		if (IS_ZEBRA_DEBUG_SEND && IS_ZEBRA_DEBUG_RECV) { +			vty_out(vty, "  Zebra packet%s debugging is on%s", +				IS_ZEBRA_DEBUG_DETAIL ? " detail" : "", +				VTY_NEWLINE); +		} else { +			if (IS_ZEBRA_DEBUG_SEND) +				vty_out(vty, +					"  Zebra packet send%s debugging is on%s", +					IS_ZEBRA_DEBUG_DETAIL ? " detail" : "", +					VTY_NEWLINE); +			else +				vty_out(vty, +					"  Zebra packet receive%s debugging is on%s", +					IS_ZEBRA_DEBUG_DETAIL ? " detail" : "", +					VTY_NEWLINE); +		}  	} -      else -	{ -	  if (IS_ZEBRA_DEBUG_SEND) -	    vty_out (vty, "  Zebra packet send%s debugging is on%s", -		     IS_ZEBRA_DEBUG_DETAIL ? " detail" : "", -		     VTY_NEWLINE); -	  else -	    vty_out (vty, "  Zebra packet receive%s debugging is on%s", -		     IS_ZEBRA_DEBUG_DETAIL ? " detail" : "", -		     VTY_NEWLINE); -	} -    } - -  if (IS_ZEBRA_DEBUG_KERNEL) -    vty_out (vty, "  Zebra kernel debugging is on%s", VTY_NEWLINE); -  if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND) -    vty_out (vty, "  Zebra kernel netlink message dumps (send) are on%s", VTY_NEWLINE); -  if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV) -    vty_out (vty, "  Zebra kernel netlink message dumps (recv) are on%s", VTY_NEWLINE); - -  /* Check here using flags as the 'macro' does an OR */ -  if (CHECK_FLAG (zebra_debug_rib, ZEBRA_DEBUG_RIB)) -    vty_out (vty, "  Zebra RIB debugging is on%s", VTY_NEWLINE); -  if (CHECK_FLAG (zebra_debug_rib, ZEBRA_DEBUG_RIB_DETAILED)) -    vty_out (vty, "  Zebra RIB detailed debugging is on%s", VTY_NEWLINE); - -  if (IS_ZEBRA_DEBUG_FPM) -    vty_out (vty, "  Zebra FPM debugging is on%s", VTY_NEWLINE); -  if (IS_ZEBRA_DEBUG_NHT) -    vty_out (vty, "  Zebra next-hop tracking debugging is on%s", VTY_NEWLINE); -  if (IS_ZEBRA_DEBUG_MPLS) -    vty_out (vty, "  Zebra MPLS debugging is on%s", VTY_NEWLINE); -  if (IS_ZEBRA_DEBUG_PW) -    vty_out (vty, "  Zebra pseudowire debugging is on%s", VTY_NEWLINE); - -  return CMD_SUCCESS; + +	if (IS_ZEBRA_DEBUG_KERNEL) +		vty_out(vty, "  Zebra kernel debugging is on%s", VTY_NEWLINE); +	if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND) +		vty_out(vty, +			"  Zebra kernel netlink message dumps (send) are on%s", +			VTY_NEWLINE); +	if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV) +		vty_out(vty, +			"  Zebra kernel netlink message dumps (recv) are on%s", +			VTY_NEWLINE); + +	/* Check here using flags as the 'macro' does an OR */ +	if (CHECK_FLAG(zebra_debug_rib, ZEBRA_DEBUG_RIB)) +		vty_out(vty, "  Zebra RIB debugging is on%s", VTY_NEWLINE); +	if (CHECK_FLAG(zebra_debug_rib, ZEBRA_DEBUG_RIB_DETAILED)) +		vty_out(vty, "  Zebra RIB detailed debugging is on%s", +			VTY_NEWLINE); + +	if (IS_ZEBRA_DEBUG_FPM) +		vty_out(vty, "  Zebra FPM debugging is on%s", VTY_NEWLINE); +	if (IS_ZEBRA_DEBUG_NHT) +		vty_out(vty, "  Zebra next-hop tracking debugging is on%s", +			VTY_NEWLINE); +	if (IS_ZEBRA_DEBUG_MPLS) +		vty_out(vty, "  Zebra MPLS debugging is on%s", VTY_NEWLINE); +	if (IS_ZEBRA_DEBUG_PW) +		vty_out(vty, "  Zebra pseudowire debugging is on%s", +			VTY_NEWLINE); + +	return CMD_SUCCESS;  }  DEFUN (debug_zebra_events, @@ -99,8 +104,8 @@ DEFUN (debug_zebra_events,         "Zebra configuration\n"         "Debug option set for zebra events\n")  { -  zebra_debug_event = ZEBRA_DEBUG_EVENT; -  return CMD_WARNING; +	zebra_debug_event = ZEBRA_DEBUG_EVENT; +	return CMD_WARNING;  }  DEFUN (debug_zebra_nht, @@ -110,8 +115,8 @@ DEFUN (debug_zebra_nht,         "Zebra configuration\n"         "Debug option set for zebra next hop tracking\n")  { -  zebra_debug_nht = ZEBRA_DEBUG_NHT; -  return CMD_WARNING; +	zebra_debug_nht = ZEBRA_DEBUG_NHT; +	return CMD_WARNING;  }  DEFUN (debug_zebra_mpls, @@ -121,8 +126,8 @@ DEFUN (debug_zebra_mpls,         "Zebra configuration\n"         "Debug option set for zebra MPLS LSPs\n")  { -  zebra_debug_mpls = ZEBRA_DEBUG_MPLS; -  return CMD_WARNING; +	zebra_debug_mpls = ZEBRA_DEBUG_MPLS; +	return CMD_WARNING;  }  DEFUN (debug_zebra_pw, @@ -133,11 +138,11 @@ DEFUN (debug_zebra_pw,         "Zebra configuration\n"         "Debug option set for zebra pseudowires\n")  { -  if (strmatch (argv[0]->text, "no")) -    UNSET_FLAG (zebra_debug_pw, ZEBRA_DEBUG_PW); -  else -    SET_FLAG (zebra_debug_pw, ZEBRA_DEBUG_PW); -  return CMD_WARNING; +	if (strmatch(argv[0]->text, "no")) +		UNSET_FLAG(zebra_debug_pw, ZEBRA_DEBUG_PW); +	else +		SET_FLAG(zebra_debug_pw, ZEBRA_DEBUG_PW); +	return CMD_WARNING;  }  DEFUN (debug_zebra_packet, @@ -150,24 +155,23 @@ DEFUN (debug_zebra_packet,         "Debug option set for send packet\n"         "Debug option set for detailed info\n")  { -  int idx = 0; -  zebra_debug_packet = ZEBRA_DEBUG_PACKET; - -  if (argv_find (argv, argc, "send", &idx)) -    SET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_SEND); -  idx = 0; -  if (argv_find (argv, argc, "recv", &idx)) -    SET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_RECV); -  idx = 0; -  if (argv_find (argv, argc, "detail", &idx)) -    SET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_DETAIL); - -  if (!(zebra_debug_packet & ZEBRA_DEBUG_SEND & ZEBRA_DEBUG_RECV)) -  { -    SET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_SEND); -    SET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_RECV); -  } -  return CMD_SUCCESS; +	int idx = 0; +	zebra_debug_packet = ZEBRA_DEBUG_PACKET; + +	if (argv_find(argv, argc, "send", &idx)) +		SET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_SEND); +	idx = 0; +	if (argv_find(argv, argc, "recv", &idx)) +		SET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_RECV); +	idx = 0; +	if (argv_find(argv, argc, "detail", &idx)) +		SET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_DETAIL); + +	if (!(zebra_debug_packet & ZEBRA_DEBUG_SEND & ZEBRA_DEBUG_RECV)) { +		SET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_SEND); +		SET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_RECV); +	} +	return CMD_SUCCESS;  }  DEFUN (debug_zebra_kernel, @@ -177,8 +181,8 @@ DEFUN (debug_zebra_kernel,         "Zebra configuration\n"         "Debug option set for zebra between kernel interface\n")  { -  SET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL); -  return CMD_SUCCESS; +	SET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL); +	return CMD_SUCCESS;  }  DEFUN (debug_zebra_kernel_msgdump, @@ -191,13 +195,13 @@ DEFUN (debug_zebra_kernel_msgdump,         "Dump raw netlink messages received\n"         "Dump raw netlink messages sent\n")  { -  int idx = 0; -  if (argc == 4 || argv_find (argv, argc, "recv", &idx)) -    SET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV); -  if (argc == 4 || argv_find (argv, argc, "send", &idx)) -    SET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND); +	int idx = 0; +	if (argc == 4 || argv_find(argv, argc, "recv", &idx)) +		SET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV); +	if (argc == 4 || argv_find(argv, argc, "send", &idx)) +		SET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (debug_zebra_rib, @@ -207,8 +211,8 @@ DEFUN (debug_zebra_rib,         "Zebra configuration\n"         "Debug RIB events\n")  { -  SET_FLAG (zebra_debug_rib, ZEBRA_DEBUG_RIB); -  return CMD_SUCCESS; +	SET_FLAG(zebra_debug_rib, ZEBRA_DEBUG_RIB); +	return CMD_SUCCESS;  }  DEFUN (debug_zebra_rib_detailed, @@ -219,8 +223,8 @@ DEFUN (debug_zebra_rib_detailed,         "Debug RIB events\n"         "Detailed debugs\n")  { -  SET_FLAG (zebra_debug_rib, ZEBRA_DEBUG_RIB_DETAILED); -  return CMD_SUCCESS; +	SET_FLAG(zebra_debug_rib, ZEBRA_DEBUG_RIB_DETAILED); +	return CMD_SUCCESS;  }  DEFUN (debug_zebra_fpm, @@ -230,8 +234,8 @@ DEFUN (debug_zebra_fpm,         "Zebra configuration\n"         "Debug zebra FPM events\n")  { -  SET_FLAG (zebra_debug_fpm, ZEBRA_DEBUG_FPM); -  return CMD_SUCCESS; +	SET_FLAG(zebra_debug_fpm, ZEBRA_DEBUG_FPM); +	return CMD_SUCCESS;  }  DEFUN (no_debug_zebra_events, @@ -242,8 +246,8 @@ DEFUN (no_debug_zebra_events,         "Zebra configuration\n"         "Debug option set for zebra events\n")  { -  zebra_debug_event = 0; -  return CMD_SUCCESS; +	zebra_debug_event = 0; +	return CMD_SUCCESS;  }  DEFUN (no_debug_zebra_nht, @@ -254,8 +258,8 @@ DEFUN (no_debug_zebra_nht,         "Zebra configuration\n"         "Debug option set for zebra next hop tracking\n")  { -  zebra_debug_nht = 0; -  return CMD_SUCCESS; +	zebra_debug_nht = 0; +	return CMD_SUCCESS;  }  DEFUN (no_debug_zebra_mpls, @@ -266,8 +270,8 @@ DEFUN (no_debug_zebra_mpls,         "Zebra configuration\n"         "Debug option set for zebra MPLS LSPs\n")  { -  zebra_debug_mpls = 0; -  return CMD_SUCCESS; +	zebra_debug_mpls = 0; +	return CMD_SUCCESS;  }  DEFUN (no_debug_zebra_packet, @@ -280,12 +284,12 @@ DEFUN (no_debug_zebra_packet,         "Debug option set for receive packet\n"         "Debug option set for send packet\n")  { -  int idx = 0; -  if (argc == 4 || argv_find (argv, argc, "send", &idx)) -    UNSET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_SEND); -  if (argc == 4 || argv_find (argv, argc, "recv", &idx)) -    UNSET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_RECV); -  return CMD_SUCCESS; +	int idx = 0; +	if (argc == 4 || argv_find(argv, argc, "send", &idx)) +		UNSET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_SEND); +	if (argc == 4 || argv_find(argv, argc, "recv", &idx)) +		UNSET_FLAG(zebra_debug_packet, ZEBRA_DEBUG_RECV); +	return CMD_SUCCESS;  }  DEFUN (no_debug_zebra_kernel, @@ -296,8 +300,8 @@ DEFUN (no_debug_zebra_kernel,         "Zebra configuration\n"         "Debug option set for zebra between kernel interface\n")  { -  UNSET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL); -  return CMD_SUCCESS; +	UNSET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL); +	return CMD_SUCCESS;  }  DEFUN (no_debug_zebra_kernel_msgdump, @@ -311,13 +315,13 @@ DEFUN (no_debug_zebra_kernel_msgdump,         "Dump raw netlink messages received\n"         "Dump raw netlink messages sent\n")  { -  int idx = 0; -  if (argc == 5 || argv_find (argv, argc, "recv", &idx)) -    UNSET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV); -  if (argc == 5 || argv_find (argv, argc, "send", &idx)) -    UNSET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND); +	int idx = 0; +	if (argc == 5 || argv_find(argv, argc, "recv", &idx)) +		UNSET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV); +	if (argc == 5 || argv_find(argv, argc, "send", &idx)) +		UNSET_FLAG(zebra_debug_kernel, ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (no_debug_zebra_rib, @@ -328,8 +332,8 @@ DEFUN (no_debug_zebra_rib,         "Zebra configuration\n"         "Debug zebra RIB\n")  { -  zebra_debug_rib = 0; -  return CMD_SUCCESS; +	zebra_debug_rib = 0; +	return CMD_SUCCESS;  }  DEFUN (no_debug_zebra_rib_detailed, @@ -341,8 +345,8 @@ DEFUN (no_debug_zebra_rib_detailed,         "Debug zebra RIB\n"         "Detailed debugs\n")  { -  UNSET_FLAG (zebra_debug_rib, ZEBRA_DEBUG_RIB_DETAILED); -  return CMD_SUCCESS; +	UNSET_FLAG(zebra_debug_rib, ZEBRA_DEBUG_RIB_DETAILED); +	return CMD_SUCCESS;  }  DEFUN (no_debug_zebra_fpm, @@ -353,141 +357,123 @@ DEFUN (no_debug_zebra_fpm,         "Zebra configuration\n"         "Debug zebra FPM events\n")  { -  zebra_debug_fpm = 0; -  return CMD_SUCCESS; +	zebra_debug_fpm = 0; +	return CMD_SUCCESS;  }  /* Debug node. */ -struct cmd_node debug_node = -{ -  DEBUG_NODE, -  "",				/* Debug node has no interface. */ -  1 -}; +struct cmd_node debug_node = {DEBUG_NODE, "", /* Debug node has no interface. */ +			      1}; -static int -config_write_debug (struct vty *vty) +static int config_write_debug(struct vty *vty)  { -  int write = 0; - -  if (IS_ZEBRA_DEBUG_EVENT) -    { -      vty_out (vty, "debug zebra events%s", VTY_NEWLINE); -      write++; -    } -  if (IS_ZEBRA_DEBUG_PACKET) -    { -      if (IS_ZEBRA_DEBUG_SEND && IS_ZEBRA_DEBUG_RECV) -	{ -	  vty_out (vty, "debug zebra packet%s%s", -		   IS_ZEBRA_DEBUG_DETAIL ? " detail" : "", -		   VTY_NEWLINE); -	  write++; +	int write = 0; + +	if (IS_ZEBRA_DEBUG_EVENT) { +		vty_out(vty, "debug zebra events%s", VTY_NEWLINE); +		write++; +	} +	if (IS_ZEBRA_DEBUG_PACKET) { +		if (IS_ZEBRA_DEBUG_SEND && IS_ZEBRA_DEBUG_RECV) { +			vty_out(vty, "debug zebra packet%s%s", +				IS_ZEBRA_DEBUG_DETAIL ? " detail" : "", +				VTY_NEWLINE); +			write++; +		} else { +			if (IS_ZEBRA_DEBUG_SEND) +				vty_out(vty, "debug zebra packet send%s%s", +					IS_ZEBRA_DEBUG_DETAIL ? " detail" : "", +					VTY_NEWLINE); +			else +				vty_out(vty, "debug zebra packet recv%s%s", +					IS_ZEBRA_DEBUG_DETAIL ? " detail" : "", +					VTY_NEWLINE); +			write++; +		} +	} +	if (IS_ZEBRA_DEBUG_KERNEL) { +		vty_out(vty, "debug zebra kernel%s", VTY_NEWLINE); +		write++; +	} +	/* Check here using flags as the 'macro' does an OR */ +	if (CHECK_FLAG(zebra_debug_rib, ZEBRA_DEBUG_RIB)) { +		vty_out(vty, "debug zebra rib%s", VTY_NEWLINE); +		write++; +	} +	if (CHECK_FLAG(zebra_debug_rib, ZEBRA_DEBUG_RIB_DETAILED)) { +		vty_out(vty, "debug zebra rib detailed%s", VTY_NEWLINE); +		write++; +	} +	if (IS_ZEBRA_DEBUG_FPM) { +		vty_out(vty, "debug zebra fpm%s", VTY_NEWLINE); +		write++; +	} +	if (IS_ZEBRA_DEBUG_NHT) { +		vty_out(vty, "debug zebra nht%s", VTY_NEWLINE); +		write++; +	} +	if (IS_ZEBRA_DEBUG_MPLS) { +		vty_out(vty, "debug zebra mpls%s", VTY_NEWLINE); +		write++;  	} -      else -	{ -	  if (IS_ZEBRA_DEBUG_SEND) -	    vty_out (vty, "debug zebra packet send%s%s", -		     IS_ZEBRA_DEBUG_DETAIL ? " detail" : "", -		     VTY_NEWLINE); -	  else -	    vty_out (vty, "debug zebra packet recv%s%s", -		     IS_ZEBRA_DEBUG_DETAIL ? " detail" : "", -		     VTY_NEWLINE); -	  write++; +	if (IS_ZEBRA_DEBUG_PW) { +		vty_out(vty, "debug zebra pseudowires%s", VTY_NEWLINE); +		write++;  	} -    } -  if (IS_ZEBRA_DEBUG_KERNEL) -    { -      vty_out (vty, "debug zebra kernel%s", VTY_NEWLINE); -      write++; -    } -  /* Check here using flags as the 'macro' does an OR */ -  if (CHECK_FLAG (zebra_debug_rib, ZEBRA_DEBUG_RIB)) -    { -      vty_out (vty, "debug zebra rib%s", VTY_NEWLINE); -      write++; -    } -  if (CHECK_FLAG (zebra_debug_rib, ZEBRA_DEBUG_RIB_DETAILED)) -    { -      vty_out (vty, "debug zebra rib detailed%s", VTY_NEWLINE); -      write++; -    } -  if (IS_ZEBRA_DEBUG_FPM) -    { -      vty_out (vty, "debug zebra fpm%s", VTY_NEWLINE); -      write++; -    } -  if (IS_ZEBRA_DEBUG_NHT) -    { -      vty_out (vty, "debug zebra nht%s", VTY_NEWLINE); -      write++; -    } -  if (IS_ZEBRA_DEBUG_MPLS) -    { -      vty_out (vty, "debug zebra mpls%s", VTY_NEWLINE); -      write++; -    } -  if (IS_ZEBRA_DEBUG_PW) -    { -      vty_out (vty, "debug zebra pseudowires%s", VTY_NEWLINE); -      write++; -    } -  return write; +	return write;  } -void -zebra_debug_init (void) +void zebra_debug_init(void)  { -  zebra_debug_event = 0; -  zebra_debug_packet = 0; -  zebra_debug_kernel = 0; -  zebra_debug_rib = 0; -  zebra_debug_fpm = 0; -  zebra_debug_mpls = 0; -  zebra_debug_pw = 0; - -  install_node (&debug_node, config_write_debug); - -  install_element (VIEW_NODE, &show_debugging_zebra_cmd); - -  install_element (ENABLE_NODE, &debug_zebra_events_cmd); -  install_element (ENABLE_NODE, &debug_zebra_nht_cmd); -  install_element (ENABLE_NODE, &debug_zebra_mpls_cmd); -  install_element (ENABLE_NODE, &debug_zebra_pw_cmd); -  install_element (ENABLE_NODE, &debug_zebra_packet_cmd); -  install_element (ENABLE_NODE, &debug_zebra_kernel_cmd); -  install_element (ENABLE_NODE, &debug_zebra_kernel_msgdump_cmd); -  install_element (ENABLE_NODE, &debug_zebra_rib_cmd); -  install_element (ENABLE_NODE, &debug_zebra_rib_detailed_cmd); -  install_element (ENABLE_NODE, &debug_zebra_fpm_cmd); -  install_element (ENABLE_NODE, &no_debug_zebra_events_cmd); -  install_element (ENABLE_NODE, &no_debug_zebra_nht_cmd); -  install_element (ENABLE_NODE, &no_debug_zebra_mpls_cmd); -  install_element (ENABLE_NODE, &no_debug_zebra_packet_cmd); -  install_element (ENABLE_NODE, &no_debug_zebra_kernel_cmd); -  install_element (ENABLE_NODE, &no_debug_zebra_kernel_msgdump_cmd); -  install_element (ENABLE_NODE, &no_debug_zebra_rib_cmd); -  install_element (ENABLE_NODE, &no_debug_zebra_rib_detailed_cmd); -  install_element (ENABLE_NODE, &no_debug_zebra_fpm_cmd); - -  install_element (CONFIG_NODE, &debug_zebra_events_cmd); -  install_element (CONFIG_NODE, &debug_zebra_nht_cmd); -  install_element (CONFIG_NODE, &debug_zebra_mpls_cmd); -  install_element (CONFIG_NODE, &debug_zebra_pw_cmd); -  install_element (CONFIG_NODE, &debug_zebra_packet_cmd); -  install_element (CONFIG_NODE, &debug_zebra_kernel_cmd); -  install_element (CONFIG_NODE, &debug_zebra_kernel_msgdump_cmd); -  install_element (CONFIG_NODE, &debug_zebra_rib_cmd); -  install_element (CONFIG_NODE, &debug_zebra_rib_detailed_cmd); -  install_element (CONFIG_NODE, &debug_zebra_fpm_cmd); -  install_element (CONFIG_NODE, &no_debug_zebra_events_cmd); -  install_element (CONFIG_NODE, &no_debug_zebra_nht_cmd); -  install_element (CONFIG_NODE, &no_debug_zebra_mpls_cmd); -  install_element (CONFIG_NODE, &no_debug_zebra_packet_cmd); -  install_element (CONFIG_NODE, &no_debug_zebra_kernel_cmd); -  install_element (CONFIG_NODE, &no_debug_zebra_kernel_msgdump_cmd); -  install_element (CONFIG_NODE, &no_debug_zebra_rib_cmd); -  install_element (CONFIG_NODE, &no_debug_zebra_rib_detailed_cmd); -  install_element (CONFIG_NODE, &no_debug_zebra_fpm_cmd); +	zebra_debug_event = 0; +	zebra_debug_packet = 0; +	zebra_debug_kernel = 0; +	zebra_debug_rib = 0; +	zebra_debug_fpm = 0; +	zebra_debug_mpls = 0; +	zebra_debug_pw = 0; + +	install_node(&debug_node, config_write_debug); + +	install_element(VIEW_NODE, &show_debugging_zebra_cmd); + +	install_element(ENABLE_NODE, &debug_zebra_events_cmd); +	install_element(ENABLE_NODE, &debug_zebra_nht_cmd); +	install_element(ENABLE_NODE, &debug_zebra_mpls_cmd); +	install_element(ENABLE_NODE, &debug_zebra_pw_cmd); +	install_element(ENABLE_NODE, &debug_zebra_packet_cmd); +	install_element(ENABLE_NODE, &debug_zebra_kernel_cmd); +	install_element(ENABLE_NODE, &debug_zebra_kernel_msgdump_cmd); +	install_element(ENABLE_NODE, &debug_zebra_rib_cmd); +	install_element(ENABLE_NODE, &debug_zebra_rib_detailed_cmd); +	install_element(ENABLE_NODE, &debug_zebra_fpm_cmd); +	install_element(ENABLE_NODE, &no_debug_zebra_events_cmd); +	install_element(ENABLE_NODE, &no_debug_zebra_nht_cmd); +	install_element(ENABLE_NODE, &no_debug_zebra_mpls_cmd); +	install_element(ENABLE_NODE, &no_debug_zebra_packet_cmd); +	install_element(ENABLE_NODE, &no_debug_zebra_kernel_cmd); +	install_element(ENABLE_NODE, &no_debug_zebra_kernel_msgdump_cmd); +	install_element(ENABLE_NODE, &no_debug_zebra_rib_cmd); +	install_element(ENABLE_NODE, &no_debug_zebra_rib_detailed_cmd); +	install_element(ENABLE_NODE, &no_debug_zebra_fpm_cmd); + +	install_element(CONFIG_NODE, &debug_zebra_events_cmd); +	install_element(CONFIG_NODE, &debug_zebra_nht_cmd); +	install_element(CONFIG_NODE, &debug_zebra_mpls_cmd); +	install_element(CONFIG_NODE, &debug_zebra_pw_cmd); +	install_element(CONFIG_NODE, &debug_zebra_packet_cmd); +	install_element(CONFIG_NODE, &debug_zebra_kernel_cmd); +	install_element(CONFIG_NODE, &debug_zebra_kernel_msgdump_cmd); +	install_element(CONFIG_NODE, &debug_zebra_rib_cmd); +	install_element(CONFIG_NODE, &debug_zebra_rib_detailed_cmd); +	install_element(CONFIG_NODE, &debug_zebra_fpm_cmd); +	install_element(CONFIG_NODE, &no_debug_zebra_events_cmd); +	install_element(CONFIG_NODE, &no_debug_zebra_nht_cmd); +	install_element(CONFIG_NODE, &no_debug_zebra_mpls_cmd); +	install_element(CONFIG_NODE, &no_debug_zebra_packet_cmd); +	install_element(CONFIG_NODE, &no_debug_zebra_kernel_cmd); +	install_element(CONFIG_NODE, &no_debug_zebra_kernel_msgdump_cmd); +	install_element(CONFIG_NODE, &no_debug_zebra_rib_cmd); +	install_element(CONFIG_NODE, &no_debug_zebra_rib_detailed_cmd); +	install_element(CONFIG_NODE, &no_debug_zebra_fpm_cmd);  } diff --git a/zebra/debug.h b/zebra/debug.h index 9a196d2f34..194c945fd8 100644 --- a/zebra/debug.h +++ b/zebra/debug.h @@ -15,9 +15,9 @@   * General Public License for more details.   *   * You should have received a copy of the GNU General Public License - * along with GNU Zebra; see the file COPYING.  If not, write to the  - * Free Software Foundation, Inc., 59 Temple Place - Suite 330,  - * Boston, MA 02111-1307, USA.   + * along with GNU Zebra; see the file COPYING.  If not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA.   */  #ifndef _ZEBRA_DEBUG_H @@ -54,13 +54,13 @@  #define IS_ZEBRA_DEBUG_DETAIL (zebra_debug_packet & ZEBRA_DEBUG_DETAIL)  #define IS_ZEBRA_DEBUG_KERNEL (zebra_debug_kernel & ZEBRA_DEBUG_KERNEL) -#define IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND \ -        (zebra_debug_kernel & ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND) -#define IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV \ -        (zebra_debug_kernel & ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV) +#define IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND                                     \ +	(zebra_debug_kernel & ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND) +#define IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV                                     \ +	(zebra_debug_kernel & ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV) -#define IS_ZEBRA_DEBUG_RIB \ -        (zebra_debug_rib & (ZEBRA_DEBUG_RIB | ZEBRA_DEBUG_RIB_DETAILED)) +#define IS_ZEBRA_DEBUG_RIB                                                     \ +	(zebra_debug_rib & (ZEBRA_DEBUG_RIB | ZEBRA_DEBUG_RIB_DETAILED))  #define IS_ZEBRA_DEBUG_RIB_DETAILED  (zebra_debug_rib & ZEBRA_DEBUG_RIB_DETAILED)  #define IS_ZEBRA_DEBUG_FPM (zebra_debug_fpm & ZEBRA_DEBUG_FPM) @@ -77,6 +77,6 @@ extern unsigned long zebra_debug_nht;  extern unsigned long zebra_debug_mpls;  extern unsigned long zebra_debug_pw; -extern void zebra_debug_init (void); +extern void zebra_debug_init(void);  #endif /* _ZEBRA_DEBUG_H */ diff --git a/zebra/if_ioctl.c b/zebra/if_ioctl.c index 5333f0331e..9c0732d47a 100644 --- a/zebra/if_ioctl.c +++ b/zebra/if_ioctl.c @@ -17,7 +17,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #include <zebra.h> @@ -39,306 +39,293 @@  #include <ifaddrs.h>  /* Interface looking up using infamous SIOCGIFCONF. */ -static int -interface_list_ioctl (void) +static int interface_list_ioctl(void)  { -  int ret; -  int sock; +	int ret; +	int sock;  #define IFNUM_BASE 32 -  int ifnum; -  struct ifreq *ifreq; -  struct ifconf ifconf; -  struct interface *ifp; -  int n; -  int lastlen; - -  /* Normally SIOCGIFCONF works with AF_INET socket. */ -  sock = socket (AF_INET, SOCK_DGRAM, 0); -  if (sock < 0)  -    { -      zlog_warn ("Can't make AF_INET socket stream: %s", safe_strerror (errno)); -      return -1; -    } - -  /* Set initial ifreq count.  This will be double when SIOCGIFCONF -     fail.  Solaris has SIOCGIFNUM. */ +	int ifnum; +	struct ifreq *ifreq; +	struct ifconf ifconf; +	struct interface *ifp; +	int n; +	int lastlen; + +	/* Normally SIOCGIFCONF works with AF_INET socket. */ +	sock = socket(AF_INET, SOCK_DGRAM, 0); +	if (sock < 0) { +		zlog_warn("Can't make AF_INET socket stream: %s", +			  safe_strerror(errno)); +		return -1; +	} + +/* Set initial ifreq count.  This will be double when SIOCGIFCONF +   fail.  Solaris has SIOCGIFNUM. */  #ifdef SIOCGIFNUM -  ret = ioctl (sock, SIOCGIFNUM, &ifnum); -  if (ret < 0) -    ifnum = IFNUM_BASE; -  else -    ifnum++; +	ret = ioctl(sock, SIOCGIFNUM, &ifnum); +	if (ret < 0) +		ifnum = IFNUM_BASE; +	else +		ifnum++;  #else -  ifnum = IFNUM_BASE; +	ifnum = IFNUM_BASE;  #endif /* SIOCGIFNUM */ -  ifconf.ifc_buf = NULL; - -  lastlen = 0; -  /* Loop until SIOCGIFCONF success. */ -  for (;;)  -    { -      ifconf.ifc_len = sizeof (struct ifreq) * ifnum; -      ifconf.ifc_buf = XREALLOC(MTYPE_TMP, ifconf.ifc_buf, ifconf.ifc_len); - -      ret = ioctl(sock, SIOCGIFCONF, &ifconf); - -      if (ret < 0)  -	{ -	  zlog_warn ("SIOCGIFCONF: %s", safe_strerror(errno)); -	  goto end; -	} -      /* Repeatedly get info til buffer fails to grow. */ -      if (ifconf.ifc_len > lastlen) -	{ -          lastlen = ifconf.ifc_len; -	  ifnum += 10; -	  continue; +	ifconf.ifc_buf = NULL; + +	lastlen = 0; +	/* Loop until SIOCGIFCONF success. */ +	for (;;) { +		ifconf.ifc_len = sizeof(struct ifreq) * ifnum; +		ifconf.ifc_buf = +			XREALLOC(MTYPE_TMP, ifconf.ifc_buf, ifconf.ifc_len); + +		ret = ioctl(sock, SIOCGIFCONF, &ifconf); + +		if (ret < 0) { +			zlog_warn("SIOCGIFCONF: %s", safe_strerror(errno)); +			goto end; +		} +		/* Repeatedly get info til buffer fails to grow. */ +		if (ifconf.ifc_len > lastlen) { +			lastlen = ifconf.ifc_len; +			ifnum += 10; +			continue; +		} +		/* Success. */ +		break;  	} -      /* Success. */ -      break; -    } -  /* Allocate interface. */ -  ifreq = ifconf.ifc_req; +	/* Allocate interface. */ +	ifreq = ifconf.ifc_req;  #ifdef OPEN_BSD -  for (n = 0; n < ifconf.ifc_len; ) -    { -      unsigned int size; - -      ifreq = (struct ifreq *)((caddr_t) ifconf.ifc_req + n); -      ifp = if_get_by_name_len(ifreq->ifr_name, -			       strnlen(ifreq->ifr_name, -				       sizeof(ifreq->ifr_name)), -                               VRF_DEFAULT, 0); -      if_add_update (ifp); -      size = ifreq->ifr_addr.sa_len; -      if (size < sizeof (ifreq->ifr_addr)) -	size = sizeof (ifreq->ifr_addr); -      size += sizeof (ifreq->ifr_name); -      n += size; -    } +	for (n = 0; n < ifconf.ifc_len;) { +		unsigned int size; + +		ifreq = (struct ifreq *)((caddr_t)ifconf.ifc_req + n); +		ifp = if_get_by_name_len( +			ifreq->ifr_name, +			strnlen(ifreq->ifr_name, sizeof(ifreq->ifr_name)), +			VRF_DEFAULT, 0); +		if_add_update(ifp); +		size = ifreq->ifr_addr.sa_len; +		if (size < sizeof(ifreq->ifr_addr)) +			size = sizeof(ifreq->ifr_addr); +		size += sizeof(ifreq->ifr_name); +		n += size; +	}  #else -  for (n = 0; n < ifconf.ifc_len; n += sizeof(struct ifreq)) -    { -      ifp = if_get_by_name_len(ifreq->ifr_name, -			       strnlen(ifreq->ifr_name, -				       sizeof(ifreq->ifr_name)), -                               VRF_DEFAULT, 0); -      if_add_update (ifp); -      ifreq++; -    } +	for (n = 0; n < ifconf.ifc_len; n += sizeof(struct ifreq)) { +		ifp = if_get_by_name_len( +			ifreq->ifr_name, +			strnlen(ifreq->ifr_name, sizeof(ifreq->ifr_name)), +			VRF_DEFAULT, 0); +		if_add_update(ifp); +		ifreq++; +	}  #endif /* OPEN_BSD */ - end: -  close (sock); -  XFREE (MTYPE_TMP, ifconf.ifc_buf); +end: +	close(sock); +	XFREE(MTYPE_TMP, ifconf.ifc_buf); -  return ret; +	return ret;  }  /* Get interface's index by ioctl. */ -static int -if_get_index (struct interface *ifp) +static int if_get_index(struct interface *ifp)  { -  ifp->ifindex = if_nametoindex(ifp->name); -  return ifp->ifindex; +	ifp->ifindex = if_nametoindex(ifp->name); +	return ifp->ifindex;  }  #ifdef SIOCGIFHWADDR -static int -if_get_hwaddr (struct interface *ifp) +static int if_get_hwaddr(struct interface *ifp)  { -  int ret; -  struct ifreq ifreq; -  int i; - -  strncpy (ifreq.ifr_name, ifp->name, IFNAMSIZ); -  ifreq.ifr_addr.sa_family = AF_INET; - -  /* Fetch Hardware address if available. */ -  ret = if_ioctl (SIOCGIFHWADDR, (caddr_t) &ifreq); -  if (ret < 0) -    ifp->hw_addr_len = 0; -  else -    { -      memcpy (ifp->hw_addr, ifreq.ifr_hwaddr.sa_data, 6); - -      for (i = 0; i < 6; i++) -	if (ifp->hw_addr[i] != 0) -	  break; - -      if (i == 6) -	ifp->hw_addr_len = 0; -      else -	ifp->hw_addr_len = 6; -    } -  return 0; +	int ret; +	struct ifreq ifreq; +	int i; + +	strncpy(ifreq.ifr_name, ifp->name, IFNAMSIZ); +	ifreq.ifr_addr.sa_family = AF_INET; + +	/* Fetch Hardware address if available. */ +	ret = if_ioctl(SIOCGIFHWADDR, (caddr_t)&ifreq); +	if (ret < 0) +		ifp->hw_addr_len = 0; +	else { +		memcpy(ifp->hw_addr, ifreq.ifr_hwaddr.sa_data, 6); + +		for (i = 0; i < 6; i++) +			if (ifp->hw_addr[i] != 0) +				break; + +		if (i == 6) +			ifp->hw_addr_len = 0; +		else +			ifp->hw_addr_len = 6; +	} +	return 0;  }  #endif /* SIOCGIFHWADDR */ -static int -if_getaddrs (void) +static int if_getaddrs(void)  { -  int ret; -  struct ifaddrs *ifap; -  struct ifaddrs *ifapfree; -  struct interface *ifp; -  int prefixlen; - -  ret = getifaddrs (&ifap);  -  if (ret != 0) -    { -      zlog_err ("getifaddrs(): %s", safe_strerror (errno)); -      return -1; -    } - -  for (ifapfree = ifap; ifap; ifap = ifap->ifa_next) -    { -      if (ifap->ifa_addr == NULL) -        { -          zlog_err ("%s: nonsensical ifaddr with NULL ifa_addr, ifname %s", -                    __func__, (ifap->ifa_name ? ifap->ifa_name : "(null)")); -          continue; -        } -        -      ifp = if_lookup_by_name (ifap->ifa_name, VRF_DEFAULT); -      if (ifp == NULL) -	{ -	  zlog_err ("if_getaddrs(): Can't lookup interface %s\n", -		    ifap->ifa_name); -	  continue; +	int ret; +	struct ifaddrs *ifap; +	struct ifaddrs *ifapfree; +	struct interface *ifp; +	int prefixlen; + +	ret = getifaddrs(&ifap); +	if (ret != 0) { +		zlog_err("getifaddrs(): %s", safe_strerror(errno)); +		return -1;  	} -      if (ifap->ifa_addr->sa_family == AF_INET) -	{ -	  struct sockaddr_in *addr; -	  struct sockaddr_in *mask; -	  struct sockaddr_in *dest; -	  struct in_addr *dest_pnt; -	  int flags = 0; - -	  addr = (struct sockaddr_in *) ifap->ifa_addr; -	  mask = (struct sockaddr_in *) ifap->ifa_netmask; -	  prefixlen = ip_masklen (mask->sin_addr); - -	  dest_pnt = NULL; - -	  if (ifap->ifa_dstaddr && -	      !IPV4_ADDR_SAME(&addr->sin_addr, -			      &((struct sockaddr_in *) -			      	ifap->ifa_dstaddr)->sin_addr)) -	    { -	      dest = (struct sockaddr_in *) ifap->ifa_dstaddr; -	      dest_pnt = &dest->sin_addr; -	      flags = ZEBRA_IFA_PEER; -	    } -	  else if (ifap->ifa_broadaddr && -		   !IPV4_ADDR_SAME(&addr->sin_addr, -				   &((struct sockaddr_in *) -				     ifap->ifa_broadaddr)->sin_addr)) -	    { -	      dest = (struct sockaddr_in *) ifap->ifa_broadaddr; -	      dest_pnt = &dest->sin_addr; -	    } - -	  connected_add_ipv4 (ifp, flags, &addr->sin_addr, -			      prefixlen, dest_pnt, NULL); -	} -      if (ifap->ifa_addr->sa_family == AF_INET6) -	{ -	  struct sockaddr_in6 *addr; -	  struct sockaddr_in6 *mask; -	  struct sockaddr_in6 *dest; -	  struct in6_addr *dest_pnt; -	  int flags = 0; - -	  addr = (struct sockaddr_in6 *) ifap->ifa_addr; -	  mask = (struct sockaddr_in6 *) ifap->ifa_netmask; -	  prefixlen = ip6_masklen (mask->sin6_addr); - -	  dest_pnt = NULL; - -	  if (ifap->ifa_dstaddr && -	      !IPV6_ADDR_SAME(&addr->sin6_addr, -			      &((struct sockaddr_in6 *) -			      	ifap->ifa_dstaddr)->sin6_addr)) -	    { -	      dest = (struct sockaddr_in6 *) ifap->ifa_dstaddr; -	      dest_pnt = &dest->sin6_addr; -	      flags = ZEBRA_IFA_PEER; -	    } -	  else if (ifap->ifa_broadaddr && -		   !IPV6_ADDR_SAME(&addr->sin6_addr, -				   &((struct sockaddr_in6 *) -				     ifap->ifa_broadaddr)->sin6_addr)) -	    { -	      dest = (struct sockaddr_in6 *) ifap->ifa_broadaddr; -	      dest_pnt = &dest->sin6_addr; -	    } +	for (ifapfree = ifap; ifap; ifap = ifap->ifa_next) { +		if (ifap->ifa_addr == NULL) { +			zlog_err( +				"%s: nonsensical ifaddr with NULL ifa_addr, ifname %s", +				__func__, +				(ifap->ifa_name ? ifap->ifa_name : "(null)")); +			continue; +		} + +		ifp = if_lookup_by_name(ifap->ifa_name, VRF_DEFAULT); +		if (ifp == NULL) { +			zlog_err("if_getaddrs(): Can't lookup interface %s\n", +				 ifap->ifa_name); +			continue; +		} + +		if (ifap->ifa_addr->sa_family == AF_INET) { +			struct sockaddr_in *addr; +			struct sockaddr_in *mask; +			struct sockaddr_in *dest; +			struct in_addr *dest_pnt; +			int flags = 0; + +			addr = (struct sockaddr_in *)ifap->ifa_addr; +			mask = (struct sockaddr_in *)ifap->ifa_netmask; +			prefixlen = ip_masklen(mask->sin_addr); + +			dest_pnt = NULL; + +			if (ifap->ifa_dstaddr +			    && !IPV4_ADDR_SAME(&addr->sin_addr, +					       &((struct sockaddr_in *) +							 ifap->ifa_dstaddr) +							->sin_addr)) { +				dest = (struct sockaddr_in *)ifap->ifa_dstaddr; +				dest_pnt = &dest->sin_addr; +				flags = ZEBRA_IFA_PEER; +			} else if (ifap->ifa_broadaddr +				   && !IPV4_ADDR_SAME( +					      &addr->sin_addr, +					      &((struct sockaddr_in *) +							ifap->ifa_broadaddr) +						       ->sin_addr)) { +				dest = (struct sockaddr_in *) +					       ifap->ifa_broadaddr; +				dest_pnt = &dest->sin_addr; +			} + +			connected_add_ipv4(ifp, flags, &addr->sin_addr, +					   prefixlen, dest_pnt, NULL); +		} +		if (ifap->ifa_addr->sa_family == AF_INET6) { +			struct sockaddr_in6 *addr; +			struct sockaddr_in6 *mask; +			struct sockaddr_in6 *dest; +			struct in6_addr *dest_pnt; +			int flags = 0; + +			addr = (struct sockaddr_in6 *)ifap->ifa_addr; +			mask = (struct sockaddr_in6 *)ifap->ifa_netmask; +			prefixlen = ip6_masklen(mask->sin6_addr); + +			dest_pnt = NULL; + +			if (ifap->ifa_dstaddr +			    && !IPV6_ADDR_SAME(&addr->sin6_addr, +					       &((struct sockaddr_in6 *) +							 ifap->ifa_dstaddr) +							->sin6_addr)) { +				dest = (struct sockaddr_in6 *)ifap->ifa_dstaddr; +				dest_pnt = &dest->sin6_addr; +				flags = ZEBRA_IFA_PEER; +			} else if (ifap->ifa_broadaddr +				   && !IPV6_ADDR_SAME( +					      &addr->sin6_addr, +					      &((struct sockaddr_in6 *) +							ifap->ifa_broadaddr) +						       ->sin6_addr)) { +				dest = (struct sockaddr_in6 *) +					       ifap->ifa_broadaddr; +				dest_pnt = &dest->sin6_addr; +			}  #if defined(KAME) -	  if (IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr))  -	    { -	      addr->sin6_scope_id = -			ntohs(*(u_int16_t *)&addr->sin6_addr.s6_addr[2]); -	      addr->sin6_addr.s6_addr[2] = addr->sin6_addr.s6_addr[3] = 0; -	    }	 -#endif           - -	  connected_add_ipv6 (ifp, flags, &addr->sin6_addr, prefixlen,  -	                      dest_pnt, NULL); +			if (IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr)) { +				addr->sin6_scope_id = +					ntohs(*(u_int16_t *)&addr->sin6_addr +						       .s6_addr[2]); +				addr->sin6_addr.s6_addr[2] = +					addr->sin6_addr.s6_addr[3] = 0; +			} +#endif + +			connected_add_ipv6(ifp, flags, &addr->sin6_addr, +					   prefixlen, dest_pnt, NULL); +		}  	} -    } -  freeifaddrs (ifapfree); +	freeifaddrs(ifapfree); -  return 0;  +	return 0;  }  /* Fetch interface information via ioctl(). */ -static void -interface_info_ioctl () +static void interface_info_ioctl()  { -  struct listnode *node, *nnode; -  struct interface *ifp; -   -  for (ALL_LIST_ELEMENTS (vrf_iflist (VRF_DEFAULT), node, nnode, ifp)) -    { -      if_get_index (ifp); +	struct listnode *node, *nnode; +	struct interface *ifp; + +	for (ALL_LIST_ELEMENTS(vrf_iflist(VRF_DEFAULT), node, nnode, ifp)) { +		if_get_index(ifp);  #ifdef SIOCGIFHWADDR -      if_get_hwaddr (ifp); +		if_get_hwaddr(ifp);  #endif /* SIOCGIFHWADDR */ -      if_get_flags (ifp); -      if_get_mtu (ifp); -      if_get_metric (ifp); -    } +		if_get_flags(ifp); +		if_get_mtu(ifp); +		if_get_metric(ifp); +	}  }  /* Lookup all interface information. */ -void -interface_list (struct zebra_ns *zns) +void interface_list(struct zebra_ns *zns)  { -  zlog_info ("interface_list: NS %u", zns->ns_id); +	zlog_info("interface_list: NS %u", zns->ns_id); -  /* Linux can do both proc & ioctl, ioctl is the only way to get -     interface aliases in 2.2 series kernels. */ +/* Linux can do both proc & ioctl, ioctl is the only way to get +   interface aliases in 2.2 series kernels. */  #ifdef HAVE_PROC_NET_DEV -  interface_list_proc (); +	interface_list_proc();  #endif /* HAVE_PROC_NET_DEV */ -  interface_list_ioctl (); +	interface_list_ioctl(); -  /* After listing is done, get index, address, flags and other -     interface's information. */ -  interface_info_ioctl (); +	/* After listing is done, get index, address, flags and other +	   interface's information. */ +	interface_info_ioctl(); -  if_getaddrs (); +	if_getaddrs();  #if defined(HAVE_PROC_NET_IF_INET6) -  /* Linux provides interface's IPv6 address via -     /proc/net/if_inet6. */ -  ifaddr_proc_ipv6 (); +	/* Linux provides interface's IPv6 address via +	   /proc/net/if_inet6. */ +	ifaddr_proc_ipv6();  #endif /* HAVE_PROC_NET_IF_INET6 */  } diff --git a/zebra/if_ioctl_solaris.c b/zebra/if_ioctl_solaris.c index dbc4109913..905ac619c6 100644 --- a/zebra/if_ioctl_solaris.c +++ b/zebra/if_ioctl_solaris.c @@ -17,7 +17,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #include <zebra.h> @@ -38,338 +38,324 @@  #include "zebra/ioctl_solaris.h"  #include "zebra/rib.h" -static int if_get_addr (struct interface *, struct sockaddr *, const char *); -static void interface_info_ioctl (struct interface *); +static int if_get_addr(struct interface *, struct sockaddr *, const char *); +static void interface_info_ioctl(struct interface *);  extern struct zebra_privs_t zserv_privs; -static int -interface_list_ioctl (int af) +static int interface_list_ioctl(int af)  { -  int ret; -  int sock; +	int ret; +	int sock;  #define IFNUM_BASE 32 -  struct lifnum lifn; -  int ifnum; -  struct lifreq *lifreq; -  struct lifconf lifconf; -  struct interface *ifp; -  int n; -  int save_errno; -  size_t needed, lastneeded = 0; -  char *buf = NULL; - -  if (zserv_privs.change(ZPRIVS_RAISE)) -    zlog_err("Can't raise privileges"); -   -  sock = socket (af, SOCK_DGRAM, 0); -  if (sock < 0) -    { -      zlog_warn ("Can't make %s socket stream: %s", -                 (af == AF_INET ? "AF_INET" : "AF_INET6"), safe_strerror (errno)); -                  -      if (zserv_privs.change(ZPRIVS_LOWER)) -        zlog_err("Can't lower privileges"); -         -      return -1; -    } - -calculate_lifc_len:     /* must hold privileges to enter here */ -  lifn.lifn_family = af; -  lifn.lifn_flags = LIFC_NOXMIT; /* we want NOXMIT interfaces too */ -  ret = ioctl (sock, SIOCGLIFNUM, &lifn); -  save_errno = errno; -   -  if (zserv_privs.change(ZPRIVS_LOWER)) -    zlog_err("Can't lower privileges"); -  -  if (ret < 0) -    { -      zlog_warn ("interface_list_ioctl: SIOCGLIFNUM failed %s", -                 safe_strerror (save_errno)); -      close (sock); -      return -1; -    } -  ifnum = lifn.lifn_count; - -  /* -   * When calculating the buffer size needed, add a small number -   * of interfaces to those we counted.  We do this to capture -   * the interface status of potential interfaces which may have -   * been plumbed between the SIOCGLIFNUM and the SIOCGLIFCONF. -   */ -  needed = (ifnum + 4) * sizeof (struct lifreq); -  if (needed > lastneeded || needed < lastneeded / 2) -    { -      if (buf != NULL) -        XFREE (MTYPE_TMP, buf); -      if ((buf = XMALLOC (MTYPE_TMP, needed)) == NULL) -        { -          zlog_warn ("interface_list_ioctl: malloc failed"); -          close (sock); -          return -1; -        } -    } -  lastneeded = needed; - -  lifconf.lifc_family = af; -  lifconf.lifc_flags = LIFC_NOXMIT; -  lifconf.lifc_len = needed; -  lifconf.lifc_buf = buf; - -  if (zserv_privs.change(ZPRIVS_RAISE)) -    zlog_err("Can't raise privileges"); -     -  ret = ioctl (sock, SIOCGLIFCONF, &lifconf); - -  if (ret < 0) -    { -      if (errno == EINVAL) -        goto calculate_lifc_len; /* deliberately hold privileges */ - -      zlog_warn ("SIOCGLIFCONF: %s", safe_strerror (errno)); - -      if (zserv_privs.change(ZPRIVS_LOWER)) -        zlog_err("Can't lower privileges"); - -      goto end; -    } - -  if (zserv_privs.change(ZPRIVS_LOWER)) -    zlog_err("Can't lower privileges"); -     -  /* Allocate interface. */ -  lifreq = lifconf.lifc_req; - -  for (n = 0; n < lifconf.lifc_len; n += sizeof (struct lifreq)) -    { -      /* we treat Solaris logical interfaces as addresses, because that is -       * how PF_ROUTE on Solaris treats them. Hence we can not directly use -       * the lifreq_name to get the ifp.  We need to normalise the name -       * before attempting get. -       * -       * Solaris logical interface names are in the form of: -       * <interface name>:<logical interface id> -       */ -      unsigned int normallen = 0; -      uint64_t lifflags; -       -      /* We should exclude ~IFF_UP interfaces, as we'll find out about them -       * coming up later through RTM_NEWADDR message on the route socket. -       */ -      if (if_get_flags_direct (lifreq->lifr_name, &lifflags, -                           lifreq->lifr_addr.ss_family) -          || !CHECK_FLAG (lifflags, IFF_UP)) -        { -          lifreq++; -          continue; -        } -       -      /* Find the normalised name */ -      while ( (normallen < sizeof(lifreq->lifr_name)) -             && ( *(lifreq->lifr_name + normallen) != '\0') -             && ( *(lifreq->lifr_name + normallen) != ':') ) -        normallen++; -       -      ifp = if_get_by_name_len(lifreq->lifr_name, normallen, VRF_DEFAULT, 0); - -      if (lifreq->lifr_addr.ss_family == AF_INET) -        ifp->flags |= IFF_IPV4; - -      if (lifreq->lifr_addr.ss_family == AF_INET6) -        { -          ifp->flags |= IFF_IPV6; -        } -         -      if_add_update (ifp); - -      interface_info_ioctl (ifp); -       -      /* If a logical interface pass the full name so it can be -       * as a label on the address -       */ -      if ( *(lifreq->lifr_name + normallen) != '\0') -        if_get_addr (ifp, (struct sockaddr *) &lifreq->lifr_addr, -                     lifreq->lifr_name); -      else -        if_get_addr (ifp, (struct sockaddr *) &lifreq->lifr_addr, NULL); -         -      /* Poke the interface flags. Lets IFF_UP mangling kick in */ -      if_flags_update (ifp, ifp->flags); -       -      lifreq++; -    } +	struct lifnum lifn; +	int ifnum; +	struct lifreq *lifreq; +	struct lifconf lifconf; +	struct interface *ifp; +	int n; +	int save_errno; +	size_t needed, lastneeded = 0; +	char *buf = NULL; + +	if (zserv_privs.change(ZPRIVS_RAISE)) +		zlog_err("Can't raise privileges"); + +	sock = socket(af, SOCK_DGRAM, 0); +	if (sock < 0) { +		zlog_warn("Can't make %s socket stream: %s", +			  (af == AF_INET ? "AF_INET" : "AF_INET6"), +			  safe_strerror(errno)); + +		if (zserv_privs.change(ZPRIVS_LOWER)) +			zlog_err("Can't lower privileges"); + +		return -1; +	} + +calculate_lifc_len: /* must hold privileges to enter here */ +	lifn.lifn_family = af; +	lifn.lifn_flags = LIFC_NOXMIT; /* we want NOXMIT interfaces too */ +	ret = ioctl(sock, SIOCGLIFNUM, &lifn); +	save_errno = errno; + +	if (zserv_privs.change(ZPRIVS_LOWER)) +		zlog_err("Can't lower privileges"); + +	if (ret < 0) { +		zlog_warn("interface_list_ioctl: SIOCGLIFNUM failed %s", +			  safe_strerror(save_errno)); +		close(sock); +		return -1; +	} +	ifnum = lifn.lifn_count; + +	/* +	 * When calculating the buffer size needed, add a small number +	 * of interfaces to those we counted.  We do this to capture +	 * the interface status of potential interfaces which may have +	 * been plumbed between the SIOCGLIFNUM and the SIOCGLIFCONF. +	 */ +	needed = (ifnum + 4) * sizeof(struct lifreq); +	if (needed > lastneeded || needed < lastneeded / 2) { +		if (buf != NULL) +			XFREE(MTYPE_TMP, buf); +		if ((buf = XMALLOC(MTYPE_TMP, needed)) == NULL) { +			zlog_warn("interface_list_ioctl: malloc failed"); +			close(sock); +			return -1; +		} +	} +	lastneeded = needed; + +	lifconf.lifc_family = af; +	lifconf.lifc_flags = LIFC_NOXMIT; +	lifconf.lifc_len = needed; +	lifconf.lifc_buf = buf; + +	if (zserv_privs.change(ZPRIVS_RAISE)) +		zlog_err("Can't raise privileges"); + +	ret = ioctl(sock, SIOCGLIFCONF, &lifconf); + +	if (ret < 0) { +		if (errno == EINVAL) +			goto calculate_lifc_len; /* deliberately hold privileges +						    */ + +		zlog_warn("SIOCGLIFCONF: %s", safe_strerror(errno)); + +		if (zserv_privs.change(ZPRIVS_LOWER)) +			zlog_err("Can't lower privileges"); + +		goto end; +	} + +	if (zserv_privs.change(ZPRIVS_LOWER)) +		zlog_err("Can't lower privileges"); + +	/* Allocate interface. */ +	lifreq = lifconf.lifc_req; + +	for (n = 0; n < lifconf.lifc_len; n += sizeof(struct lifreq)) { +		/* we treat Solaris logical interfaces as addresses, because +		 * that is +		 * how PF_ROUTE on Solaris treats them. Hence we can not +		 * directly use +		 * the lifreq_name to get the ifp.  We need to normalise the +		 * name +		 * before attempting get. +		 * +		 * Solaris logical interface names are in the form of: +		 * <interface name>:<logical interface id> +		 */ +		unsigned int normallen = 0; +		uint64_t lifflags; + +		/* We should exclude ~IFF_UP interfaces, as we'll find out about +		 * them +		 * coming up later through RTM_NEWADDR message on the route +		 * socket. +		 */ +		if (if_get_flags_direct(lifreq->lifr_name, &lifflags, +					lifreq->lifr_addr.ss_family) +		    || !CHECK_FLAG(lifflags, IFF_UP)) { +			lifreq++; +			continue; +		} + +		/* Find the normalised name */ +		while ((normallen < sizeof(lifreq->lifr_name)) +		       && (*(lifreq->lifr_name + normallen) != '\0') +		       && (*(lifreq->lifr_name + normallen) != ':')) +			normallen++; + +		ifp = if_get_by_name_len(lifreq->lifr_name, normallen, +					 VRF_DEFAULT, 0); + +		if (lifreq->lifr_addr.ss_family == AF_INET) +			ifp->flags |= IFF_IPV4; + +		if (lifreq->lifr_addr.ss_family == AF_INET6) { +			ifp->flags |= IFF_IPV6; +		} + +		if_add_update(ifp); + +		interface_info_ioctl(ifp); + +		/* If a logical interface pass the full name so it can be +		 * as a label on the address +		 */ +		if (*(lifreq->lifr_name + normallen) != '\0') +			if_get_addr(ifp, (struct sockaddr *)&lifreq->lifr_addr, +				    lifreq->lifr_name); +		else +			if_get_addr(ifp, (struct sockaddr *)&lifreq->lifr_addr, +				    NULL); + +		/* Poke the interface flags. Lets IFF_UP mangling kick in */ +		if_flags_update(ifp, ifp->flags); + +		lifreq++; +	}  end: -  close (sock); -  XFREE (MTYPE_TMP, lifconf.lifc_buf); -  return ret; +	close(sock); +	XFREE(MTYPE_TMP, lifconf.lifc_buf); +	return ret;  }  /* Get interface's index by ioctl. */ -static int -if_get_index (struct interface *ifp) +static int if_get_index(struct interface *ifp)  { -  int ret; -  struct lifreq lifreq; +	int ret; +	struct lifreq lifreq; -  lifreq_set_name (&lifreq, ifp->name); +	lifreq_set_name(&lifreq, ifp->name); -  if (ifp->flags & IFF_IPV4) -    ret = AF_IOCTL (AF_INET, SIOCGLIFINDEX, (caddr_t) & lifreq); -  else if (ifp->flags & IFF_IPV6) -    ret = AF_IOCTL (AF_INET6, SIOCGLIFINDEX, (caddr_t) & lifreq); -  else -    ret = -1; +	if (ifp->flags & IFF_IPV4) +		ret = AF_IOCTL(AF_INET, SIOCGLIFINDEX, (caddr_t)&lifreq); +	else if (ifp->flags & IFF_IPV6) +		ret = AF_IOCTL(AF_INET6, SIOCGLIFINDEX, (caddr_t)&lifreq); +	else +		ret = -1; -  if (ret < 0) -    { -      zlog_warn ("SIOCGLIFINDEX(%s) failed", ifp->name); -      return ret; -    } +	if (ret < 0) { +		zlog_warn("SIOCGLIFINDEX(%s) failed", ifp->name); +		return ret; +	} -  /* OK we got interface index. */ +/* OK we got interface index. */  #ifdef ifr_ifindex -  ifp->ifindex = lifreq.lifr_ifindex; +	ifp->ifindex = lifreq.lifr_ifindex;  #else -  ifp->ifindex = lifreq.lifr_index; +	ifp->ifindex = lifreq.lifr_index;  #endif -  return ifp->ifindex; - +	return ifp->ifindex;  }  /* Interface address lookup by ioctl.  This function only looks up     IPv4 address. */ -#define ADDRLEN(sa) (((sa)->sa_family == AF_INET ?  \ -                sizeof (struct sockaddr_in) : sizeof (struct sockaddr_in6))) +#define ADDRLEN(sa)                                                            \ +	(((sa)->sa_family == AF_INET ? sizeof(struct sockaddr_in)              \ +				     : sizeof(struct sockaddr_in6)))  #define SIN(s) ((struct sockaddr_in *)(s))  #define SIN6(s) ((struct sockaddr_in6 *)(s))  /* Retrieve address information for the given ifp */ -static int -if_get_addr (struct interface *ifp, struct sockaddr *addr, const char *label) +static int if_get_addr(struct interface *ifp, struct sockaddr *addr, +		       const char *label)  { -  int ret; -  struct lifreq lifreq; -  struct sockaddr_storage mask, dest; -  char *dest_pnt = NULL; -  u_char prefixlen = 0; -  afi_t af; -  int flags = 0; - -  /* Interface's name and address family. -   * We need to use the logical interface name / label, if we've been -   * given one, in order to get the right address -   */ -  strncpy (lifreq.lifr_name, (label ? label : ifp->name), IFNAMSIZ); - -  /* Interface's address. */ -  memcpy (&lifreq.lifr_addr, addr, ADDRLEN (addr)); -  af = addr->sa_family; - -  /* Point to point or broad cast address pointer init. */ -  dest_pnt = NULL; - -  if (AF_IOCTL (af, SIOCGLIFDSTADDR, (caddr_t) & lifreq) >= 0) -    { -      memcpy (&dest, &lifreq.lifr_dstaddr, ADDRLEN (addr)); -      if (af == AF_INET) -        dest_pnt = (char *) &(SIN (&dest)->sin_addr); -      else -        dest_pnt = (char *) &(SIN6 (&dest)->sin6_addr); -      flags = ZEBRA_IFA_PEER; -    } - -  if (af == AF_INET) -    { -      ret = if_ioctl (SIOCGLIFNETMASK, (caddr_t) & lifreq); -       -      if (ret < 0) -        { -          if (errno != EADDRNOTAVAIL) -            { -              zlog_warn ("SIOCGLIFNETMASK (%s) fail: %s", ifp->name, -                         safe_strerror (errno)); -              return ret; -            } -          return 0; -        } -      memcpy (&mask, &lifreq.lifr_addr, ADDRLEN (addr)); - -      prefixlen = ip_masklen (SIN (&mask)->sin_addr); -      if (!dest_pnt && (if_ioctl (SIOCGLIFBRDADDR, (caddr_t) & lifreq) >= 0)) -	{ -          memcpy (&dest, &lifreq.lifr_broadaddr, sizeof (struct sockaddr_in)); -          dest_pnt = (char *) &SIN (&dest)->sin_addr; -        } -    } -  else if (af == AF_INET6) -    { -      if (if_ioctl_ipv6 (SIOCGLIFSUBNET, (caddr_t) & lifreq) < 0) -	{ -	  if (ifp->flags & IFF_POINTOPOINT) -	    prefixlen = IPV6_MAX_BITLEN; -	  else -	    zlog_warn ("SIOCGLIFSUBNET (%s) fail: %s", -		       ifp->name, safe_strerror (errno)); +	int ret; +	struct lifreq lifreq; +	struct sockaddr_storage mask, dest; +	char *dest_pnt = NULL; +	u_char prefixlen = 0; +	afi_t af; +	int flags = 0; + +	/* Interface's name and address family. +	 * We need to use the logical interface name / label, if we've been +	 * given one, in order to get the right address +	 */ +	strncpy(lifreq.lifr_name, (label ? label : ifp->name), IFNAMSIZ); + +	/* Interface's address. */ +	memcpy(&lifreq.lifr_addr, addr, ADDRLEN(addr)); +	af = addr->sa_family; + +	/* Point to point or broad cast address pointer init. */ +	dest_pnt = NULL; + +	if (AF_IOCTL(af, SIOCGLIFDSTADDR, (caddr_t)&lifreq) >= 0) { +		memcpy(&dest, &lifreq.lifr_dstaddr, ADDRLEN(addr)); +		if (af == AF_INET) +			dest_pnt = (char *)&(SIN(&dest)->sin_addr); +		else +			dest_pnt = (char *)&(SIN6(&dest)->sin6_addr); +		flags = ZEBRA_IFA_PEER;  	} -      else -	{ -	  prefixlen = lifreq.lifr_addrlen; + +	if (af == AF_INET) { +		ret = if_ioctl(SIOCGLIFNETMASK, (caddr_t)&lifreq); + +		if (ret < 0) { +			if (errno != EADDRNOTAVAIL) { +				zlog_warn("SIOCGLIFNETMASK (%s) fail: %s", +					  ifp->name, safe_strerror(errno)); +				return ret; +			} +			return 0; +		} +		memcpy(&mask, &lifreq.lifr_addr, ADDRLEN(addr)); + +		prefixlen = ip_masklen(SIN(&mask)->sin_addr); +		if (!dest_pnt +		    && (if_ioctl(SIOCGLIFBRDADDR, (caddr_t)&lifreq) >= 0)) { +			memcpy(&dest, &lifreq.lifr_broadaddr, +			       sizeof(struct sockaddr_in)); +			dest_pnt = (char *)&SIN(&dest)->sin_addr; +		} +	} else if (af == AF_INET6) { +		if (if_ioctl_ipv6(SIOCGLIFSUBNET, (caddr_t)&lifreq) < 0) { +			if (ifp->flags & IFF_POINTOPOINT) +				prefixlen = IPV6_MAX_BITLEN; +			else +				zlog_warn("SIOCGLIFSUBNET (%s) fail: %s", +					  ifp->name, safe_strerror(errno)); +		} else { +			prefixlen = lifreq.lifr_addrlen; +		}  	} -    } -  /* Set address to the interface. */ -  if (af == AF_INET) -    connected_add_ipv4 (ifp, flags, &SIN (addr)->sin_addr, prefixlen, -                        (struct in_addr *) dest_pnt, label); -  else if (af == AF_INET6) -    connected_add_ipv6 (ifp, flags, &SIN6 (addr)->sin6_addr, prefixlen, -                        (struct in6_addr *) dest_pnt, label); +	/* Set address to the interface. */ +	if (af == AF_INET) +		connected_add_ipv4(ifp, flags, &SIN(addr)->sin_addr, prefixlen, +				   (struct in_addr *)dest_pnt, label); +	else if (af == AF_INET6) +		connected_add_ipv6(ifp, flags, &SIN6(addr)->sin6_addr, +				   prefixlen, (struct in6_addr *)dest_pnt, +				   label); -  return 0; +	return 0;  }  /* Fetch interface information via ioctl(). */ -static void -interface_info_ioctl (struct interface *ifp) +static void interface_info_ioctl(struct interface *ifp)  { -  if_get_index (ifp); -  if_get_flags (ifp); -  if_get_mtu (ifp); -  if_get_metric (ifp); +	if_get_index(ifp); +	if_get_flags(ifp); +	if_get_mtu(ifp); +	if_get_metric(ifp);  }  /* Lookup all interface information. */ -void -interface_list (struct zebra_ns *zns) +void interface_list(struct zebra_ns *zns)  { -  if (zns->ns_id != NS_DEFAULT) -    { -      zlog_warn ("interface_list: ignore NS %u", zns->ns_id); -      return; -    } -  interface_list_ioctl (AF_INET); -  interface_list_ioctl (AF_INET6); -  interface_list_ioctl (AF_UNSPEC); +	if (zns->ns_id != NS_DEFAULT) { +		zlog_warn("interface_list: ignore NS %u", zns->ns_id); +		return; +	} +	interface_list_ioctl(AF_INET); +	interface_list_ioctl(AF_INET6); +	interface_list_ioctl(AF_UNSPEC);  } -struct connected * -if_lookup_linklocal (struct interface *ifp) +struct connected *if_lookup_linklocal(struct interface *ifp)  { -  struct listnode *node; -  struct connected *ifc; +	struct listnode *node; +	struct connected *ifc; -  if (ifp == NULL) -    return NULL; +	if (ifp == NULL) +		return NULL; -  for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) -    { -      if ((ifc->address->family == AF_INET6) && -          (IN6_IS_ADDR_LINKLOCAL (&ifc->address->u.prefix6))) -        return ifc; -    } +	for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) { +		if ((ifc->address->family == AF_INET6) +		    && (IN6_IS_ADDR_LINKLOCAL(&ifc->address->u.prefix6))) +			return ifc; +	} -  return NULL; +	return NULL;  } diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index 006fcf16f4..c75d96ac76 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -17,7 +17,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #include <zebra.h> @@ -57,126 +57,176 @@  /* 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; +	}  } -//Temporary Assignments to compile on older platforms. +// Temporary Assignments to compile on older platforms.  #ifndef IFLA_BR_MAX  #define IFLA_BR_MAX   39  #endif @@ -217,644 +267,633 @@ netlink_to_zebra_link_type (unsigned int hwt)  #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;  	} -      vrf_delete (vrf); -    } +	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; +		} + +		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;  }  /* 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; -  int vrf_device = 0; -  struct zebra_ns *zns; -  vrf_id_t vrf_id = VRF_DEFAULT; - -  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; - -  if (ifi->ifi_family == AF_BRIDGE) -    return 0; - -  /* Looking up interface name. */ -  memset (tb, 0, sizeof tb); -  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; +	int vrf_device = 0; +	struct zebra_ns *zns; +	vrf_id_t vrf_id = VRF_DEFAULT; + +	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; + +	if (ifi->ifi_family == AF_BRIDGE) +		return 0; + +	/* Looking up interface name. */ +	memset(tb, 0, sizeof tb); +	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]) -    { -      memset (linkinfo, 0, sizeof linkinfo); -      parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb[IFLA_LINKINFO]); +	if (tb[IFLA_LINKINFO]) { +		memset(linkinfo, 0, sizeof 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 -      if (kind && strcmp(kind, "vrf") == 0) -        { -          vrf_device = 1; -          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)) -        vrf_id = *(u_int32_t *)RTA_DATA(tb[IFLA_MASTER]); -    } - -  /* Add interface. */ -  ifp = if_get_by_name (name, vrf_id); -  set_ifindex(ifp, ifi->ifi_index, zns); -  ifp->flags = ifi->ifi_flags & 0x0000fffff; -  if (vrf_device) -    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; - -  /* 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); - -  return 0; +		if (kind && strcmp(kind, "vrf") == 0) { +			vrf_device = 1; +			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)) +			vrf_id = *(u_int32_t *)RTA_DATA(tb[IFLA_MASTER]); +	} + +	/* Add interface. */ +	ifp = if_get_by_name(name, vrf_id); +	set_ifindex(ifp, ifi->ifi_index, zns); +	ifp->flags = ifi->ifi_flags & 0x0000fffff; +	if (vrf_device) +		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; + +	/* 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); + +	return 0;  }  /* 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 (AF_PACKET, RTM_GETLINK, &zns->netlink_cmd); -  if (ret < 0) -    return ret; -  ret = netlink_parse_info (netlink_interface, &zns->netlink_cmd, zns, 0, 1); -  if (ret < 0) -    return ret; - -  /* Get IPv4 address of the interfaces. */ -  ret = netlink_request (AF_INET, RTM_GETADDR, &zns->netlink_cmd); -  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 (AF_INET6, RTM_GETADDR, &zns->netlink_cmd); -  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(AF_PACKET, RTM_GETLINK, &zns->netlink_cmd); +	if (ret < 0) +		return ret; +	ret = netlink_parse_info(netlink_interface, &zns->netlink_cmd, zns, 0, +				 1); +	if (ret < 0) +		return ret; + +	/* Get IPv4 address of the interfaces. */ +	ret = netlink_request(AF_INET, RTM_GETADDR, &zns->netlink_cmd); +	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(AF_INET6, RTM_GETADDR, &zns->netlink_cmd); +	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.ifa.ifa_family = family; +	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); +	req.n.nlmsg_flags = NLM_F_REQUEST; +	req.n.nlmsg_type = cmd; +	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; -  int vrf_device = 0; -  struct zebra_ns *zns; -  vrf_id_t vrf_id = VRF_DEFAULT; - -  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; - -  if (ifi->ifi_family == AF_BRIDGE) -    return 0; - -  /* Looking up interface name. */ -  memset (tb, 0, sizeof tb); -  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; +	int vrf_device = 0; +	struct zebra_ns *zns; +	vrf_id_t vrf_id = VRF_DEFAULT; + +	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; + +	if (ifi->ifi_family == AF_BRIDGE) +		return 0; + +	/* Looking up interface name. */ +	memset(tb, 0, sizeof tb); +	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]) -    { -      memset (linkinfo, 0, sizeof linkinfo); -      parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb[IFLA_LINKINFO]); +	if (tb[IFLA_LINKINFO]) { +		memset(linkinfo, 0, sizeof 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 -      if (kind && strcmp(kind, "vrf") == 0) -        { -          vrf_device = 1; -          netlink_vrf_change(h, tb[IFLA_LINKINFO], name); -          vrf_id = (vrf_id_t)ifi->ifi_index; -        } -    } - -  /* See if interface is present. */ -  ifp = if_lookup_by_name_per_ns (zns, name); +		if (kind && strcmp(kind, "vrf") == 0) { +			vrf_device = 1; +			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)) -            vrf_id = *(u_int32_t *)RTA_DATA(tb[IFLA_MASTER]); +	/* 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)) +				vrf_id = +					*(u_int32_t *)RTA_DATA(tb[IFLA_MASTER]); +		} + +		if (ifp == NULL +		    || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) { +			/* Add interface notification from kernel */ +			if (IS_ZEBRA_DEBUG_KERNEL) +				zlog_debug( +					"RTM_NEWLINK for %s(%u) (ifp %p) vrf_id %u flags 0x%x", +					name, ifi->ifi_index, ifp, vrf_id, +					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(ifp, name, strlen(name), +						  vrf_id); +			} + +			/* Update interface information. */ +			set_ifindex(ifp, ifi->ifi_index, zns); +			ifp->flags = ifi->ifi_flags & 0x0000fffff; +			if (vrf_device) +				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; + +			netlink_interface_update_hw_addr(tb, ifp); + +			/* Inform clients, install any configured addresses. */ +			if_add_update(ifp); +		} 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 { +			/* Interface status change. */ +			if (IS_ZEBRA_DEBUG_KERNEL) +				zlog_debug( +					"RTM_NEWLINK status for %s(%u) flags 0x%x", +					name, ifp->ifindex, ifi->ifi_flags); + +			set_ifindex(ifp, ifi->ifi_index, zns); +			ifp->mtu6 = ifp->mtu = *(int *)RTA_DATA(tb[IFLA_MTU]); +			ifp->metric = 0; + +			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_down(ifp); +				else if (if_is_operative(ifp)) +					/* Must notify client daemons of new +					 * interface status. */ +					zebra_interface_up_update(ifp); +			} else { +				ifp->flags = ifi->ifi_flags & 0x0000fffff; +				if (if_is_operative(ifp)) +					if_up(ifp); +			} +		} +	} 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); + +		if (!vrf_device) +			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 for %s(%u) (ifp %p) vrf_id %u flags 0x%x", -                        name, ifi->ifi_index, ifp, vrf_id, 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 (ifp, name, strlen(name), vrf_id); -            } - -          /* Update interface information. */ -          set_ifindex(ifp, ifi->ifi_index, zns); -          ifp->flags = ifi->ifi_flags & 0x0000fffff; -          if (vrf_device) -            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; - -          netlink_interface_update_hw_addr (tb, ifp); - -          /* Inform clients, install any configured addresses. */ -          if_add_update (ifp); -        } -      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 -        { -          /* Interface status change. */ -          if (IS_ZEBRA_DEBUG_KERNEL) -             zlog_debug ("RTM_NEWLINK status for %s(%u) flags 0x%x", -                          name, ifp->ifindex, ifi->ifi_flags); - -          set_ifindex(ifp, ifi->ifi_index, zns); -          ifp->mtu6 = ifp->mtu = *(int *) RTA_DATA (tb[IFLA_MTU]); -          ifp->metric = 0; - -          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_down (ifp); -	      else if (if_is_operative (ifp)) -		/* Must notify client daemons of new interface status. */ -	        zebra_interface_up_update (ifp); -            } -          else -            { -              ifp->flags = ifi->ifi_flags & 0x0000fffff; -              if (if_is_operative (ifp)) -                if_up (ifp); -            } -        } -    } -  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); - -      if (!vrf_device) -        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);  } diff --git a/zebra/if_netlink.h b/zebra/if_netlink.h index 6fa39ccab2..a7454c8dd7 100644 --- a/zebra/if_netlink.h +++ b/zebra/if_netlink.h @@ -24,11 +24,11 @@  #ifdef HAVE_NETLINK -extern int netlink_interface_addr (struct sockaddr_nl *snl, -                                   struct nlmsghdr *h, ns_id_t ns_id, int startup); -extern int netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h, -                                ns_id_t ns_id, int startup); -extern int interface_lookup_netlink (struct zebra_ns *zns); +extern int netlink_interface_addr(struct sockaddr_nl *snl, struct nlmsghdr *h, +				  ns_id_t ns_id, int startup); +extern int netlink_link_change(struct sockaddr_nl *snl, struct nlmsghdr *h, +			       ns_id_t ns_id, int startup); +extern int interface_lookup_netlink(struct zebra_ns *zns);  #endif /* HAVE_NETLINK */ diff --git a/zebra/if_null.c b/zebra/if_null.c index 2ccea56c81..44eebcb216 100644 --- a/zebra/if_null.c +++ b/zebra/if_null.c @@ -28,5 +28,7 @@  #include <rtadv.h>  #include <zebra_ns.h> -void interface_list (struct zebra_ns *zns) -{ return; } +void interface_list(struct zebra_ns *zns) +{ +	return; +} diff --git a/zebra/if_sysctl.c b/zebra/if_sysctl.c index c62d9926a2..ebcade1747 100644 --- a/zebra/if_sysctl.c +++ b/zebra/if_sysctl.c @@ -17,7 +17,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #include <zebra.h> @@ -37,124 +37,101 @@  #include "zebra/kernel_socket.h"  #include "zebra/rib.h" -void -ifstat_update_sysctl (void) +void ifstat_update_sysctl(void)  { -  caddr_t ref, buf, end; -  size_t bufsiz; -  struct if_msghdr *ifm; -  struct interface *ifp; +	caddr_t ref, buf, end; +	size_t bufsiz; +	struct if_msghdr *ifm; +	struct interface *ifp;  #define MIBSIZ 6 -  int mib[MIBSIZ] = -  {  -    CTL_NET, -    PF_ROUTE, -    0, -    0, /*  AF_INET & AF_INET6 */ -    NET_RT_IFLIST, -    0  -  }; - -  /* Query buffer size. */ -  if (sysctl (mib, MIBSIZ, NULL, &bufsiz, NULL, 0) < 0)  -    { -      zlog_warn ("sysctl() error by %s", safe_strerror (errno)); -      return; -    } - -  /* We free this memory at the end of this function. */ -  ref = buf = XMALLOC (MTYPE_TMP, bufsiz); - -  /* Fetch interface informations into allocated buffer. */ -  if (sysctl (mib, MIBSIZ, buf, &bufsiz, NULL, 0) < 0)  -    { -      zlog_warn("sysctl error by %s", safe_strerror(errno)); -      XFREE(MTYPE_TMP, ref); -      return; -    } - -  /* Parse both interfaces and addresses. */ -  for (end = buf + bufsiz; buf < end; buf += ifm->ifm_msglen)  -    { -      ifm = (struct if_msghdr *) buf; -      if (ifm->ifm_type == RTM_IFINFO) -	{ -	  ifp = if_lookup_by_index (ifm->ifm_index, VRF_DEFAULT); -	  if (ifp) -	    ifp->stats = ifm->ifm_data; +	int mib[MIBSIZ] = { +		CTL_NET,       PF_ROUTE, 0, 0, /*  AF_INET & AF_INET6 */ +		NET_RT_IFLIST, 0}; + +	/* Query buffer size. */ +	if (sysctl(mib, MIBSIZ, NULL, &bufsiz, NULL, 0) < 0) { +		zlog_warn("sysctl() error by %s", safe_strerror(errno)); +		return;  	} -    } -  /* Free sysctl buffer. */ -  XFREE (MTYPE_TMP, ref); +	/* We free this memory at the end of this function. */ +	ref = buf = XMALLOC(MTYPE_TMP, bufsiz); -  return; +	/* Fetch interface informations into allocated buffer. */ +	if (sysctl(mib, MIBSIZ, buf, &bufsiz, NULL, 0) < 0) { +		zlog_warn("sysctl error by %s", safe_strerror(errno)); +		XFREE(MTYPE_TMP, ref); +		return; +	} + +	/* Parse both interfaces and addresses. */ +	for (end = buf + bufsiz; buf < end; buf += ifm->ifm_msglen) { +		ifm = (struct if_msghdr *)buf; +		if (ifm->ifm_type == RTM_IFINFO) { +			ifp = if_lookup_by_index(ifm->ifm_index, VRF_DEFAULT); +			if (ifp) +				ifp->stats = ifm->ifm_data; +		} +	} + +	/* Free sysctl buffer. */ +	XFREE(MTYPE_TMP, ref); + +	return;  }  /* Interface listing up function using sysctl(). */ -void -interface_list (struct zebra_ns *zns) +void interface_list(struct zebra_ns *zns)  { -  caddr_t ref, buf, end; -  size_t bufsiz; -  struct if_msghdr *ifm; +	caddr_t ref, buf, end; +	size_t bufsiz; +	struct if_msghdr *ifm;  #define MIBSIZ 6 -  int mib[MIBSIZ] = -  {  -    CTL_NET, -    PF_ROUTE, -    0, -    0, /*  AF_INET & AF_INET6 */ -    NET_RT_IFLIST, -    0  -  }; - -  if (zns->ns_id != NS_DEFAULT) -    { -      zlog_warn ("interface_list: ignore NS %u", zns->ns_id); -      return; -    } - -  /* Query buffer size. */ -  if (sysctl (mib, MIBSIZ, NULL, &bufsiz, NULL, 0) < 0)  -    { -      zlog_warn("sysctl() error by %s", safe_strerror(errno)); -      return; -    } - -  /* We free this memory at the end of this function. */ -  ref = buf = XMALLOC (MTYPE_TMP, bufsiz); - -  /* Fetch interface informations into allocated buffer. */ -  if (sysctl (mib, MIBSIZ, buf, &bufsiz, NULL, 0) < 0)  -    { -      zlog_warn("sysctl error by %s", safe_strerror(errno)); -      return; -    } - -  /* Parse both interfaces and addresses. */ -  for (end = buf + bufsiz; buf < end; buf += ifm->ifm_msglen)  -    { -      ifm = (struct if_msghdr *) buf; - -      switch (ifm->ifm_type)  -	{ -	case RTM_IFINFO: -	  ifm_read (ifm); -	  break; -	case RTM_NEWADDR: -	  ifam_read ((struct ifa_msghdr *) ifm); -	  break; -	default: -	  zlog_info ("interfaces_list(): unexpected message type"); -	  XFREE (MTYPE_TMP, ref); -	  return; -	  break; +	int mib[MIBSIZ] = { +		CTL_NET,       PF_ROUTE, 0, 0, /*  AF_INET & AF_INET6 */ +		NET_RT_IFLIST, 0}; + +	if (zns->ns_id != NS_DEFAULT) { +		zlog_warn("interface_list: ignore NS %u", zns->ns_id); +		return; +	} + +	/* Query buffer size. */ +	if (sysctl(mib, MIBSIZ, NULL, &bufsiz, NULL, 0) < 0) { +		zlog_warn("sysctl() error by %s", safe_strerror(errno)); +		return; +	} + +	/* We free this memory at the end of this function. */ +	ref = buf = XMALLOC(MTYPE_TMP, bufsiz); + +	/* Fetch interface informations into allocated buffer. */ +	if (sysctl(mib, MIBSIZ, buf, &bufsiz, NULL, 0) < 0) { +		zlog_warn("sysctl error by %s", safe_strerror(errno)); +		return; +	} + +	/* Parse both interfaces and addresses. */ +	for (end = buf + bufsiz; buf < end; buf += ifm->ifm_msglen) { +		ifm = (struct if_msghdr *)buf; + +		switch (ifm->ifm_type) { +		case RTM_IFINFO: +			ifm_read(ifm); +			break; +		case RTM_NEWADDR: +			ifam_read((struct ifa_msghdr *)ifm); +			break; +		default: +			zlog_info("interfaces_list(): unexpected message type"); +			XFREE(MTYPE_TMP, ref); +			return; +			break; +		}  	} -    } -  /* Free sysctl buffer. */ -  XFREE (MTYPE_TMP, ref); +	/* Free sysctl buffer. */ +	XFREE(MTYPE_TMP, ref);  } diff --git a/zebra/interface.c b/zebra/interface.c index c629dfb3f3..1e3844f6f4 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -17,7 +17,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #include <zebra.h> @@ -52,285 +52,278 @@  #define ZEBRA_PTM_SUPPORT -#if defined (HAVE_RTADV) +#if defined(HAVE_RTADV)  /* Order is intentional.  Matches RFC4191.  This array is also used for     command matching, so only modify with care. */ -const char *rtadv_pref_strs[] = { "medium", "high", "INVALID", "low", 0 }; +const char *rtadv_pref_strs[] = {"medium", "high", "INVALID", "low", 0};  #endif /* HAVE_RTADV */ -static void if_down_del_nbr_connected (struct interface *ifp); +static void if_down_del_nbr_connected(struct interface *ifp); -static void -zebra_if_node_destroy (route_table_delegate_t *delegate, -		       struct route_table *table, struct route_node *node) +static void zebra_if_node_destroy(route_table_delegate_t *delegate, +				  struct route_table *table, +				  struct route_node *node)  { -  if (node->info) -    list_delete (node->info); -  route_node_destroy (delegate, table, node); +	if (node->info) +		list_delete(node->info); +	route_node_destroy(delegate, table, node);  }  route_table_delegate_t zebra_if_table_delegate = { -  .create_node = route_node_create, -  .destroy_node = zebra_if_node_destroy -}; +	.create_node = route_node_create, +	.destroy_node = zebra_if_node_destroy};  /* Called when new interface is added. */ -static int -if_zebra_new_hook (struct interface *ifp) -{ -  struct zebra_if *zebra_if; - -  zebra_if = XCALLOC (MTYPE_TMP, sizeof (struct zebra_if)); - -  zebra_if->multicast = IF_ZEBRA_MULTICAST_UNSPEC; -  zebra_if->shutdown = IF_ZEBRA_SHUTDOWN_OFF; -  zebra_ptm_if_init(zebra_if); - -  ifp->ptm_enable = zebra_ptm_get_enable_state(); -#if defined (HAVE_RTADV) -  { -    /* Set default router advertise values. */ -    struct rtadvconf *rtadv; - -    rtadv = &zebra_if->rtadv; - -    rtadv->AdvSendAdvertisements = 0; -    rtadv->MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL; -    rtadv->MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL; -    rtadv->AdvIntervalTimer = 0; -    rtadv->AdvManagedFlag = 0; -    rtadv->AdvOtherConfigFlag = 0; -    rtadv->AdvHomeAgentFlag = 0; -    rtadv->AdvLinkMTU = 0; -    rtadv->AdvReachableTime = 0; -    rtadv->AdvRetransTimer = 0; -    rtadv->AdvCurHopLimit = 0; -    rtadv->AdvDefaultLifetime = -1; /* derive from MaxRtrAdvInterval */ -    rtadv->HomeAgentPreference = 0; -    rtadv->HomeAgentLifetime = -1; /* derive from AdvDefaultLifetime */ -    rtadv->AdvIntervalOption = 0; -    rtadv->DefaultPreference = RTADV_PREF_MEDIUM; - -    rtadv->AdvPrefixList = list_new (); -  }     +static int if_zebra_new_hook(struct interface *ifp) +{ +	struct zebra_if *zebra_if; + +	zebra_if = XCALLOC(MTYPE_TMP, sizeof(struct zebra_if)); + +	zebra_if->multicast = IF_ZEBRA_MULTICAST_UNSPEC; +	zebra_if->shutdown = IF_ZEBRA_SHUTDOWN_OFF; +	zebra_ptm_if_init(zebra_if); + +	ifp->ptm_enable = zebra_ptm_get_enable_state(); +#if defined(HAVE_RTADV) +	{ +		/* Set default router advertise values. */ +		struct rtadvconf *rtadv; + +		rtadv = &zebra_if->rtadv; + +		rtadv->AdvSendAdvertisements = 0; +		rtadv->MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL; +		rtadv->MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL; +		rtadv->AdvIntervalTimer = 0; +		rtadv->AdvManagedFlag = 0; +		rtadv->AdvOtherConfigFlag = 0; +		rtadv->AdvHomeAgentFlag = 0; +		rtadv->AdvLinkMTU = 0; +		rtadv->AdvReachableTime = 0; +		rtadv->AdvRetransTimer = 0; +		rtadv->AdvCurHopLimit = 0; +		rtadv->AdvDefaultLifetime = +			-1; /* derive from MaxRtrAdvInterval */ +		rtadv->HomeAgentPreference = 0; +		rtadv->HomeAgentLifetime = +			-1; /* derive from AdvDefaultLifetime */ +		rtadv->AdvIntervalOption = 0; +		rtadv->DefaultPreference = RTADV_PREF_MEDIUM; + +		rtadv->AdvPrefixList = list_new(); +	}  #endif /* HAVE_RTADV */ -  /* Initialize installed address chains tree. */ -  zebra_if->ipv4_subnets = route_table_init_with_delegate (&zebra_if_table_delegate); +	/* Initialize installed address chains tree. */ +	zebra_if->ipv4_subnets = +		route_table_init_with_delegate(&zebra_if_table_delegate); -  ifp->info = zebra_if; -  return 0; +	ifp->info = zebra_if; +	return 0;  }  /* Called when interface is deleted. */ -static int -if_zebra_delete_hook (struct interface *ifp) +static int if_zebra_delete_hook(struct interface *ifp)  { -  struct zebra_if *zebra_if; -   -  if (ifp->info) -    { -      zebra_if = ifp->info; +	struct zebra_if *zebra_if; -      /* Free installed address chains tree. */ -      if (zebra_if->ipv4_subnets) -	route_table_finish (zebra_if->ipv4_subnets); - #if defined (HAVE_RTADV) +	if (ifp->info) { +		zebra_if = ifp->info; -      struct rtadvconf *rtadv; +		/* Free installed address chains tree. */ +		if (zebra_if->ipv4_subnets) +			route_table_finish(zebra_if->ipv4_subnets); +#if defined(HAVE_RTADV) -      rtadv = &zebra_if->rtadv; -      list_free (rtadv->AdvPrefixList); - #endif /* HAVE_RTADV */ +		struct rtadvconf *rtadv; -      XFREE (MTYPE_TMP, zebra_if); -    } +		rtadv = &zebra_if->rtadv; +		list_free(rtadv->AdvPrefixList); +#endif /* HAVE_RTADV */ -  return 0; +		XFREE(MTYPE_TMP, zebra_if); +	} + +	return 0;  }  /* Build the table key */ -static void -if_build_key (u_int32_t ifindex, struct prefix *p) +static void if_build_key(u_int32_t ifindex, struct prefix *p)  { -  p->family = AF_INET; -  p->prefixlen = IPV4_MAX_BITLEN; -  p->u.prefix4.s_addr = ifindex; +	p->family = AF_INET; +	p->prefixlen = IPV4_MAX_BITLEN; +	p->u.prefix4.s_addr = ifindex;  }  /* Link an interface in a per NS interface tree */ -struct interface * -if_link_per_ns (struct zebra_ns *ns, struct interface *ifp) +struct interface *if_link_per_ns(struct zebra_ns *ns, struct interface *ifp)  { -  struct prefix p; -  struct route_node *rn; +	struct prefix p; +	struct route_node *rn; -  if (ifp->ifindex == IFINDEX_INTERNAL) -    return NULL; +	if (ifp->ifindex == IFINDEX_INTERNAL) +		return NULL; -  if_build_key (ifp->ifindex, &p); -  rn = route_node_get (ns->if_table, &p); -  if (rn->info) -    { -      ifp = (struct interface *)rn->info; -      route_unlock_node (rn); /* get */ -      return ifp; -    } +	if_build_key(ifp->ifindex, &p); +	rn = route_node_get(ns->if_table, &p); +	if (rn->info) { +		ifp = (struct interface *)rn->info; +		route_unlock_node(rn); /* get */ +		return ifp; +	} -  rn->info = ifp; -  ifp->node = rn; +	rn->info = ifp; +	ifp->node = rn; -  return ifp; +	return ifp;  }  /* Delete a VRF. This is called in vrf_terminate(). */ -void -if_unlink_per_ns (struct interface *ifp) +void if_unlink_per_ns(struct interface *ifp)  { -  ifp->node->info = NULL; -  route_unlock_node(ifp->node); -  ifp->node = NULL; +	ifp->node->info = NULL; +	route_unlock_node(ifp->node); +	ifp->node = NULL;  }  /* Look up an interface by identifier within a NS */ -struct interface * -if_lookup_by_index_per_ns (struct zebra_ns *ns, u_int32_t ifindex) -{ -  struct prefix p; -  struct route_node *rn; -  struct interface *ifp = NULL; - -  if_build_key (ifindex, &p); -  rn = route_node_lookup (ns->if_table, &p); -  if (rn) -    { -      ifp = (struct interface *)rn->info; -      route_unlock_node (rn); /* lookup */ -    } -  return ifp; +struct interface *if_lookup_by_index_per_ns(struct zebra_ns *ns, +					    u_int32_t ifindex) +{ +	struct prefix p; +	struct route_node *rn; +	struct interface *ifp = NULL; + +	if_build_key(ifindex, &p); +	rn = route_node_lookup(ns->if_table, &p); +	if (rn) { +		ifp = (struct interface *)rn->info; +		route_unlock_node(rn); /* lookup */ +	} +	return ifp;  }  /* Look up an interface by name within a NS */ -struct interface * -if_lookup_by_name_per_ns (struct zebra_ns *ns, const char *ifname) +struct interface *if_lookup_by_name_per_ns(struct zebra_ns *ns, +					   const char *ifname)  { -  struct route_node *rn; -  struct interface *ifp; +	struct route_node *rn; +	struct interface *ifp; -  for (rn = route_top (ns->if_table); rn; rn = route_next (rn)) -    { -      ifp = (struct interface *)rn->info; -      if (ifp && strcmp (ifp->name, ifname) == 0) -	return (ifp); -    } +	for (rn = route_top(ns->if_table); rn; rn = route_next(rn)) { +		ifp = (struct interface *)rn->info; +		if (ifp && strcmp(ifp->name, ifname) == 0) +			return (ifp); +	} -  return NULL; +	return NULL;  } -const char * -ifindex2ifname_per_ns (struct zebra_ns *zns, unsigned int ifindex) +const char *ifindex2ifname_per_ns(struct zebra_ns *zns, unsigned int ifindex)  { -  struct interface *ifp; +	struct interface *ifp; -  return ((ifp = if_lookup_by_index_per_ns (zns, ifindex)) != NULL) ? -  	 ifp->name : "unknown"; +	return ((ifp = if_lookup_by_index_per_ns(zns, ifindex)) != NULL) +		       ? ifp->name +		       : "unknown";  }  /* Tie an interface address to its derived subnet list of addresses. */ -int -if_subnet_add (struct interface *ifp, struct connected *ifc) -{ -  struct route_node *rn; -  struct zebra_if *zebra_if; -  struct prefix cp; -  struct list *addr_list; - -  assert (ifp && ifp->info && ifc); -  zebra_if = ifp->info; - -  /* Get address derived subnet node and associated address list, while marking -     address secondary attribute appropriately. */ -  cp = *ifc->address; -  apply_mask (&cp); -  rn = route_node_get (zebra_if->ipv4_subnets, &cp); - -  if ((addr_list = rn->info)) -    SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY); -  else -    { -      UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY); -      rn->info = addr_list = list_new (); -      route_lock_node (rn); -    } - -  /* Tie address at the tail of address list. */ -  listnode_add (addr_list, ifc); -   -  /* Return list element count. */ -  return (addr_list->count); +int if_subnet_add(struct interface *ifp, struct connected *ifc) +{ +	struct route_node *rn; +	struct zebra_if *zebra_if; +	struct prefix cp; +	struct list *addr_list; + +	assert(ifp && ifp->info && ifc); +	zebra_if = ifp->info; + +	/* Get address derived subnet node and associated address list, while +	   marking +	   address secondary attribute appropriately. */ +	cp = *ifc->address; +	apply_mask(&cp); +	rn = route_node_get(zebra_if->ipv4_subnets, &cp); + +	if ((addr_list = rn->info)) +		SET_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY); +	else { +		UNSET_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY); +		rn->info = addr_list = list_new(); +		route_lock_node(rn); +	} + +	/* Tie address at the tail of address list. */ +	listnode_add(addr_list, ifc); + +	/* Return list element count. */ +	return (addr_list->count);  }  /* Untie an interface address from its derived subnet list of addresses. */ -int -if_subnet_delete (struct interface *ifp, struct connected *ifc) -{ -  struct route_node *rn; -  struct zebra_if *zebra_if; -  struct list *addr_list; - -  assert (ifp && ifp->info && ifc); -  zebra_if = ifp->info; - -  /* Get address derived subnet node. */ -  rn = route_node_lookup (zebra_if->ipv4_subnets, ifc->address); -  if (! (rn && rn->info)) -    { -      zlog_warn("Trying to remove an address from an unknown subnet." -                " (please report this bug)"); -      return -1; -    } -  route_unlock_node (rn); -   -  /* Untie address from subnet's address list. */ -  addr_list = rn->info; - -  /* Deleting an address that is not registered is a bug. -   * In any case, we shouldn't decrement the lock counter if the address -   * is unknown. */ -  if (!listnode_lookup(addr_list, ifc)) -    { -      zlog_warn("Trying to remove an address from a subnet where it is not" -                " currently registered. (please report this bug)"); -      return -1; -    } - -  listnode_delete (addr_list, ifc); -  route_unlock_node (rn); - -  /* Return list element count, if not empty. */ -  if (addr_list->count) -    { -      /* If deleted address is primary, mark subsequent one as such and distribute. */ -      if (! CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY)) -	{ -	  ifc = listgetdata ((struct listnode *)listhead (addr_list)); -	  zebra_interface_address_delete_update (ifp, ifc); -	  UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY); -	  /* XXX: Linux kernel removes all the secondary addresses when the primary -	   * address is removed. We could try to work around that, though this is -	   * non-trivial. */ -	  zebra_interface_address_add_update (ifp, ifc); -	} -       -      return addr_list->count; -    } -   -  /* Otherwise, free list and route node. */ -  list_free (addr_list); -  rn->info = NULL; -  route_unlock_node (rn); - -  return 0; +int if_subnet_delete(struct interface *ifp, struct connected *ifc) +{ +	struct route_node *rn; +	struct zebra_if *zebra_if; +	struct list *addr_list; + +	assert(ifp && ifp->info && ifc); +	zebra_if = ifp->info; + +	/* Get address derived subnet node. */ +	rn = route_node_lookup(zebra_if->ipv4_subnets, ifc->address); +	if (!(rn && rn->info)) { +		zlog_warn( +			"Trying to remove an address from an unknown subnet." +			" (please report this bug)"); +		return -1; +	} +	route_unlock_node(rn); + +	/* Untie address from subnet's address list. */ +	addr_list = rn->info; + +	/* Deleting an address that is not registered is a bug. +	 * In any case, we shouldn't decrement the lock counter if the address +	 * is unknown. */ +	if (!listnode_lookup(addr_list, ifc)) { +		zlog_warn( +			"Trying to remove an address from a subnet where it is not" +			" currently registered. (please report this bug)"); +		return -1; +	} + +	listnode_delete(addr_list, ifc); +	route_unlock_node(rn); + +	/* Return list element count, if not empty. */ +	if (addr_list->count) { +		/* If deleted address is primary, mark subsequent one as such +		 * and distribute. */ +		if (!CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY)) { +			ifc = listgetdata( +				(struct listnode *)listhead(addr_list)); +			zebra_interface_address_delete_update(ifp, ifc); +			UNSET_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY); +			/* XXX: Linux kernel removes all the secondary addresses +			 * when the primary +			 * address is removed. We could try to work around that, +			 * though this is +			 * non-trivial. */ +			zebra_interface_address_add_update(ifp, ifc); +		} + +		return addr_list->count; +	} + +	/* Otherwise, free list and route node. */ +	list_free(addr_list); +	rn->info = NULL; +	route_unlock_node(rn); + +	return 0;  }  /* if_flags_mangle: A place for hacks that require mangling @@ -339,10 +332,10 @@ if_subnet_delete (struct interface *ifp, struct connected *ifc)   * ******************** Solaris flags hacks **************************   *   * Solaris IFF_UP flag reflects only the primary interface as the - * routing socket only sends IFINFO for the primary interface.  Hence   - * ~IFF_UP does not per se imply all the logical interfaces are also    + * routing socket only sends IFINFO for the primary interface.  Hence + * ~IFF_UP does not per se imply all the logical interfaces are also   * down - which we only know of as addresses. Instead we must determine - * whether the interface really is up or not according to how many    + * whether the interface really is up or not according to how many   * addresses are still attached. (Solaris always sends RTM_DELADDR if   * an interface, logical or not, goes ~IFF_UP).   * @@ -357,19 +350,18 @@ if_subnet_delete (struct interface *ifp, struct connected *ifc)   * interface will affect only the primary interface/address on Solaris.   ************************End Solaris flags hacks ***********************   */ -static void -if_flags_mangle (struct interface *ifp, uint64_t *newflags) +static void if_flags_mangle(struct interface *ifp, uint64_t *newflags)  {  #ifdef SUNOS_5 -  struct zebra_if *zif = ifp->info; -   -  zif->primary_state = *newflags & (IFF_UP & 0xff); -   -  if (CHECK_FLAG (zif->primary_state, IFF_UP) -      || listcount(ifp->connected) > 0) -    SET_FLAG (*newflags, IFF_UP); -  else -    UNSET_FLAG (*newflags, IFF_UP); +	struct zebra_if *zif = ifp->info; + +	zif->primary_state = *newflags & (IFF_UP & 0xff); + +	if (CHECK_FLAG(zif->primary_state, IFF_UP) +	    || listcount(ifp->connected) > 0) +		SET_FLAG(*newflags, IFF_UP); +	else +		UNSET_FLAG(*newflags, IFF_UP);  #endif /* SUNOS_5 */  } @@ -379,903 +371,897 @@ if_flags_mangle (struct interface *ifp, uint64_t *newflags)   *   * newflags should be the raw value, as obtained from the OS.   */ -void -if_flags_update (struct interface *ifp, uint64_t newflags) -{ -  if_flags_mangle (ifp, &newflags); -     -  if (if_is_no_ptm_operative (ifp)) -    { -      /* operative -> inoperative? */ -      ifp->flags = newflags; -      if (!if_is_operative (ifp)) -        if_down (ifp); -    } -  else -    { -      /* inoperative -> operative? */ -      ifp->flags = newflags; -      if (if_is_operative (ifp)) -        if_up (ifp); -    } +void if_flags_update(struct interface *ifp, uint64_t newflags) +{ +	if_flags_mangle(ifp, &newflags); + +	if (if_is_no_ptm_operative(ifp)) { +		/* operative -> inoperative? */ +		ifp->flags = newflags; +		if (!if_is_operative(ifp)) +			if_down(ifp); +	} else { +		/* inoperative -> operative? */ +		ifp->flags = newflags; +		if (if_is_operative(ifp)) +			if_up(ifp); +	}  }  /* Wake up configured address if it is not in current kernel     address. */ -static void -if_addr_wakeup (struct interface *ifp) -{ -  struct listnode *node, *nnode; -  struct connected *ifc; -  struct prefix *p; -  int ret; - -  for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, ifc)) -    { -      p = ifc->address; -	 -      if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED) -	  && ! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED)) -	{ -	  /* Address check. */ -	  if (p->family == AF_INET) -	    { -	      if (! if_is_up (ifp)) -		{ -		  /* Assume zebra is configured like following: -		   * -		   *   interface gre0 -		   *    ip addr 192.0.2.1/24 -		   *   ! -		   * -		   * As soon as zebra becomes first aware that gre0 exists in the -		   * kernel, it will set gre0 up and configure its addresses. -		   * -		   * (This may happen at startup when the interface already exists -		   * or during runtime when the interface is added to the kernel) -		   * -		   * XXX: IRDP code is calling here via if_add_update - this seems -		   * somewhat weird. -		   * XXX: RUNNING is not a settable flag on any system -		   * I (paulj) am aware of. -		  */ -		  if_set_flags (ifp, IFF_UP | IFF_RUNNING); -		  if_refresh (ifp); -		} - -	      ret = if_set_prefix (ifp, ifc); -	      if (ret < 0) -		{ -		  zlog_warn ("Can't set interface's address: %s",  -			     safe_strerror(errno)); -		  continue; -		} +static void if_addr_wakeup(struct interface *ifp) +{ +	struct listnode *node, *nnode; +	struct connected *ifc; +	struct prefix *p; +	int ret; -	      SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED); -	      /* The address will be advertised to zebra clients when the notification -	       * from the kernel has been received. -	       * It will also be added to the interface's subnet list then. */ -	    } -	  if (p->family == AF_INET6) -	    { -	      if (! if_is_up (ifp)) -		{ -		  /* See long comment above */ -		  if_set_flags (ifp, IFF_UP | IFF_RUNNING); -		  if_refresh (ifp); -		} +	for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, ifc)) { +		p = ifc->address; -	      ret = if_prefix_add_ipv6 (ifp, ifc); -	      if (ret < 0) -		{ -		  zlog_warn ("Can't set interface's address: %s",  -			     safe_strerror(errno)); -		  continue; +		if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED) +		    && !CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)) { +			/* Address check. */ +			if (p->family == AF_INET) { +				if (!if_is_up(ifp)) { +					/* Assume zebra is configured like +					 * following: +					 * +					 *   interface gre0 +					 *    ip addr 192.0.2.1/24 +					 *   ! +					 * +					 * As soon as zebra becomes first aware +					 * that gre0 exists in the +					 * kernel, it will set gre0 up and +					 * configure its addresses. +					 * +					 * (This may happen at startup when the +					 * interface already exists +					 * or during runtime when the interface +					 * is added to the kernel) +					 * +					 * XXX: IRDP code is calling here via +					 * if_add_update - this seems +					 * somewhat weird. +					 * XXX: RUNNING is not a settable flag +					 * on any system +					 * I (paulj) am aware of. +					*/ +					if_set_flags(ifp, IFF_UP | IFF_RUNNING); +					if_refresh(ifp); +				} + +				ret = if_set_prefix(ifp, ifc); +				if (ret < 0) { +					zlog_warn( +						"Can't set interface's address: %s", +						safe_strerror(errno)); +					continue; +				} + +				SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED); +				/* The address will be advertised to zebra +				 * clients when the notification +				 * from the kernel has been received. +				 * It will also be added to the interface's +				 * subnet list then. */ +			} +			if (p->family == AF_INET6) { +				if (!if_is_up(ifp)) { +					/* See long comment above */ +					if_set_flags(ifp, IFF_UP | IFF_RUNNING); +					if_refresh(ifp); +				} + +				ret = if_prefix_add_ipv6(ifp, ifc); +				if (ret < 0) { +					zlog_warn( +						"Can't set interface's address: %s", +						safe_strerror(errno)); +					continue; +				} + +				SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED); +				/* The address will be advertised to zebra +				 * clients when the notification +				 * from the kernel has been received. */ +			}  		} - -	      SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED); -	      /* The address will be advertised to zebra clients when the notification -	       * from the kernel has been received. */ -	    }  	} -    }  }  /* Handle interface addition */ -void -if_add_update (struct interface *ifp) +void if_add_update(struct interface *ifp)  { -  struct zebra_if *if_data; +	struct zebra_if *if_data; -  if_link_per_ns(zebra_ns_lookup (NS_DEFAULT), ifp); +	if_link_per_ns(zebra_ns_lookup(NS_DEFAULT), ifp); -  if_data = ifp->info; -  assert(if_data); +	if_data = ifp->info; +	assert(if_data); -  if (if_data->multicast == IF_ZEBRA_MULTICAST_ON) -    if_set_flags (ifp, IFF_MULTICAST); -  else if (if_data->multicast == IF_ZEBRA_MULTICAST_OFF) -    if_unset_flags (ifp, IFF_MULTICAST); +	if (if_data->multicast == IF_ZEBRA_MULTICAST_ON) +		if_set_flags(ifp, IFF_MULTICAST); +	else if (if_data->multicast == IF_ZEBRA_MULTICAST_OFF) +		if_unset_flags(ifp, IFF_MULTICAST); -  zebra_ptm_if_set_ptm_state(ifp, if_data); +	zebra_ptm_if_set_ptm_state(ifp, if_data); -  zebra_interface_add_update (ifp); +	zebra_interface_add_update(ifp); -  if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)) -    { -      SET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE); +	if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) { +		SET_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE); -      if (if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON) -	{ -	  if (IS_ZEBRA_DEBUG_KERNEL) -	    zlog_debug ("interface %s vrf %u index %d is shutdown. " -			"Won't wake it up.", -			ifp->name, ifp->vrf_id, ifp->ifindex); -	  return; -	} - -      if_addr_wakeup (ifp); +		if (if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON) { +			if (IS_ZEBRA_DEBUG_KERNEL) +				zlog_debug( +					"interface %s vrf %u index %d is shutdown. " +					"Won't wake it up.", +					ifp->name, ifp->vrf_id, ifp->ifindex); +			return; +		} -      if (IS_ZEBRA_DEBUG_KERNEL) -	zlog_debug ("interface %s vrf %u index %d becomes active.", -		    ifp->name, ifp->vrf_id, ifp->ifindex); -      static_ifindex_update(ifp, true); -    } -  else -    { -      if (IS_ZEBRA_DEBUG_KERNEL) -	zlog_debug ("interface %s vrf %u index %d is added.", -		    ifp->name, ifp->vrf_id, ifp->ifindex); -    } +		if_addr_wakeup(ifp); + +		if (IS_ZEBRA_DEBUG_KERNEL) +			zlog_debug( +				"interface %s vrf %u index %d becomes active.", +				ifp->name, ifp->vrf_id, ifp->ifindex); +		static_ifindex_update(ifp, true); +	} else { +		if (IS_ZEBRA_DEBUG_KERNEL) +			zlog_debug("interface %s vrf %u index %d is added.", +				   ifp->name, ifp->vrf_id, ifp->ifindex); +	}  }  /* Install connected routes corresponding to an interface. */ -static void -if_install_connected (struct interface *ifp) -{ -  struct listnode *node; -  struct listnode *next; -  struct connected *ifc; -  struct prefix *p; - -  if (ifp->connected) -    { -      for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc)) -	{ -	  if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) -	    zebra_interface_address_add_update (ifp, ifc); - -	  p = ifc->address; -	  if (p->family == AF_INET) -	    connected_up_ipv4 (ifp, ifc); -	  else if (p->family == AF_INET6) -	    connected_up_ipv6 (ifp, ifc); +static void if_install_connected(struct interface *ifp) +{ +	struct listnode *node; +	struct listnode *next; +	struct connected *ifc; +	struct prefix *p; + +	if (ifp->connected) { +		for (ALL_LIST_ELEMENTS(ifp->connected, node, next, ifc)) { +			if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) +				zebra_interface_address_add_update(ifp, ifc); + +			p = ifc->address; +			if (p->family == AF_INET) +				connected_up_ipv4(ifp, ifc); +			else if (p->family == AF_INET6) +				connected_up_ipv6(ifp, ifc); +		}  	} -    }  }  /* Uninstall connected routes corresponding to an interface. */ -static void -if_uninstall_connected (struct interface *ifp) -{ -  struct listnode *node; -  struct listnode *next; -  struct connected *ifc; -  struct prefix *p; - -  if (ifp->connected) -    { -      for (ALL_LIST_ELEMENTS (ifp->connected, node, next, ifc)) -	{ -	  p = ifc->address; -	  zebra_interface_address_delete_update (ifp, ifc); - -	  if (p->family == AF_INET) -	    connected_down_ipv4 (ifp, ifc); -	  else if (p->family == AF_INET6) -	    connected_down_ipv6 (ifp, ifc); +static void if_uninstall_connected(struct interface *ifp) +{ +	struct listnode *node; +	struct listnode *next; +	struct connected *ifc; +	struct prefix *p; + +	if (ifp->connected) { +		for (ALL_LIST_ELEMENTS(ifp->connected, node, next, ifc)) { +			p = ifc->address; +			zebra_interface_address_delete_update(ifp, ifc); + +			if (p->family == AF_INET) +				connected_down_ipv4(ifp, ifc); +			else if (p->family == AF_INET6) +				connected_down_ipv6(ifp, ifc); +		}  	} -    }  }  /* Uninstall and delete connected routes corresponding to an interface. */  /* TODO - Check why IPv4 handling here is different from install or if_down */ -static void -if_delete_connected (struct interface *ifp) -{ -  struct connected *ifc; -  struct prefix *p; -  struct route_node *rn; -  struct zebra_if *zebra_if; - -  zebra_if = ifp->info; - -  if (ifp->connected) -    { -      struct listnode *node; -      struct listnode *last = NULL; - -      while ((node = (last ? last->next : listhead (ifp->connected)))) -	{ -	  ifc = listgetdata (node); -	  p = ifc->address; -	   -	  if (p->family == AF_INET -	      && (rn = route_node_lookup (zebra_if->ipv4_subnets, p))) -	    { -	      struct listnode *anode; -	      struct listnode *next; -	      struct listnode *first; -	      struct list *addr_list; -	       -	      route_unlock_node (rn); -	      addr_list = (struct list *) rn->info; -	       -	      /* Remove addresses, secondaries first. */ -	      first = listhead (addr_list); -	      for (anode = first->next; anode || first; anode = next) -		{ -		  if (!anode) -		    { -		      anode = first; -		      first = NULL; -		    } -		  next = anode->next; - -		  ifc = listgetdata (anode); -		  connected_down_ipv4 (ifp, ifc); - -		  /* XXX: We have to send notifications here explicitly, because we destroy -		   * the ifc before receiving the notification about the address being deleted. -		   */ -		  zebra_interface_address_delete_update (ifp, ifc); - -		  UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL); -		  UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED); - -		  /* Remove from subnet chain. */ -		  list_delete_node (addr_list, anode); -		  route_unlock_node (rn); -		   -		  /* Remove from interface address list (unconditionally). */ -		  if (!CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)) -		    { -		      listnode_delete (ifp->connected, ifc); -		      connected_free (ifc); -                    } -                  else -                    last = node; +static void if_delete_connected(struct interface *ifp) +{ +	struct connected *ifc; +	struct prefix *p; +	struct route_node *rn; +	struct zebra_if *zebra_if; + +	zebra_if = ifp->info; + +	if (ifp->connected) { +		struct listnode *node; +		struct listnode *last = NULL; + +		while ((node = (last ? last->next +				     : listhead(ifp->connected)))) { +			ifc = listgetdata(node); +			p = ifc->address; + +			if (p->family == AF_INET +			    && (rn = route_node_lookup(zebra_if->ipv4_subnets, +						       p))) { +				struct listnode *anode; +				struct listnode *next; +				struct listnode *first; +				struct list *addr_list; + +				route_unlock_node(rn); +				addr_list = (struct list *)rn->info; + +				/* Remove addresses, secondaries first. */ +				first = listhead(addr_list); +				for (anode = first->next; anode || first; +				     anode = next) { +					if (!anode) { +						anode = first; +						first = NULL; +					} +					next = anode->next; + +					ifc = listgetdata(anode); +					connected_down_ipv4(ifp, ifc); + +					/* XXX: We have to send notifications +					 * here explicitly, because we destroy +					 * the ifc before receiving the +					 * notification about the address being +					 * deleted. +					 */ +					zebra_interface_address_delete_update( +						ifp, ifc); + +					UNSET_FLAG(ifc->conf, ZEBRA_IFC_REAL); +					UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED); + +					/* Remove from subnet chain. */ +					list_delete_node(addr_list, anode); +					route_unlock_node(rn); + +					/* Remove from interface address list +					 * (unconditionally). */ +					if (!CHECK_FLAG(ifc->conf, +							ZEBRA_IFC_CONFIGURED)) { +						listnode_delete(ifp->connected, +								ifc); +						connected_free(ifc); +					} else +						last = node; +				} + +				/* Free chain list and respective route node. */ +				list_delete(addr_list); +				rn->info = NULL; +				route_unlock_node(rn); +			} else if (p->family == AF_INET6) { +				connected_down_ipv6(ifp, ifc); + +				zebra_interface_address_delete_update(ifp, ifc); + +				UNSET_FLAG(ifc->conf, ZEBRA_IFC_REAL); +				UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED); + +				if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED)) +					last = node; +				else { +					listnode_delete(ifp->connected, ifc); +					connected_free(ifc); +				} +			} else { +				last = node; +			}  		} - -	      /* Free chain list and respective route node. */ -	      list_delete (addr_list); -	      rn->info = NULL; -	      route_unlock_node (rn); -	    } -	  else if (p->family == AF_INET6) -	    { -	      connected_down_ipv6 (ifp, ifc); - -	      zebra_interface_address_delete_update (ifp, ifc); - -	      UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL); -	      UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED); - -	      if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)) -		last = node; -	      else -		{ -		  listnode_delete (ifp->connected, ifc); -		  connected_free (ifc); -		} -	    } -	  else -	    { -	      last = node; -	    }  	} -    }  }  /* Handle an interface delete event */ -void -if_delete_update (struct interface *ifp) +void if_delete_update(struct interface *ifp)  { -  if (if_is_up(ifp)) -    { -      zlog_err ("interface %s vrf %u index %d is still up while being deleted.", -                ifp->name, ifp->vrf_id, ifp->ifindex); -      return; -    } +	if (if_is_up(ifp)) { +		zlog_err( +			"interface %s vrf %u index %d is still up while being deleted.", +			ifp->name, ifp->vrf_id, ifp->ifindex); +		return; +	} -  /* Mark interface as inactive */ -  UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE); +	/* Mark interface as inactive */ +	UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE); -  if (IS_ZEBRA_DEBUG_KERNEL) -    zlog_debug ("interface %s vrf %u index %d is now inactive.", -                ifp->name, ifp->vrf_id, ifp->ifindex); +	if (IS_ZEBRA_DEBUG_KERNEL) +		zlog_debug("interface %s vrf %u index %d is now inactive.", +			   ifp->name, ifp->vrf_id, ifp->ifindex); -  static_ifindex_update(ifp, false); +	static_ifindex_update(ifp, false); -  /* Delete connected routes from the kernel. */ -  if_delete_connected (ifp); +	/* Delete connected routes from the kernel. */ +	if_delete_connected(ifp); -  /* Send out notification on interface delete. */ -  zebra_interface_delete_update (ifp); +	/* Send out notification on interface delete. */ +	zebra_interface_delete_update(ifp); -  if_unlink_per_ns(ifp); +	if_unlink_per_ns(ifp); -  /* Update ifindex after distributing the delete message.  This is in -     case any client needs to have the old value of ifindex available -     while processing the deletion.  Each client daemon is responsible -     for setting ifindex to IFINDEX_INTERNAL after processing the -     interface deletion message. */ -  ifp->ifindex = IFINDEX_INTERNAL; +	/* Update ifindex after distributing the delete message.  This is in +	   case any client needs to have the old value of ifindex available +	   while processing the deletion.  Each client daemon is responsible +	   for setting ifindex to IFINDEX_INTERNAL after processing the +	   interface deletion message. */ +	ifp->ifindex = IFINDEX_INTERNAL; -  /* if the ifp is in a vrf, move it to default so vrf can be deleted if desired */ -  if (ifp->vrf_id) -    if_handle_vrf_change (ifp, VRF_DEFAULT); +	/* if the ifp is in a vrf, move it to default so vrf can be deleted if +	 * desired */ +	if (ifp->vrf_id) +		if_handle_vrf_change(ifp, VRF_DEFAULT);  }  /* VRF change for an interface */ -void -if_handle_vrf_change (struct interface *ifp, vrf_id_t vrf_id) +void if_handle_vrf_change(struct interface *ifp, vrf_id_t vrf_id)  { -  vrf_id_t old_vrf_id; +	vrf_id_t old_vrf_id; -  old_vrf_id = ifp->vrf_id; +	old_vrf_id = ifp->vrf_id; -  static_ifindex_update(ifp, false); +	static_ifindex_update(ifp, false); -  /* Uninstall connected routes. */ -  if_uninstall_connected (ifp); +	/* Uninstall connected routes. */ +	if_uninstall_connected(ifp); -  /* Delete any IPv4 neighbors created to implement RFC 5549 */ -  if_nbr_ipv6ll_to_ipv4ll_neigh_del_all (ifp); +	/* Delete any IPv4 neighbors created to implement RFC 5549 */ +	if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp); -  /* Delete all neighbor addresses learnt through IPv6 RA */ -  if_down_del_nbr_connected (ifp); +	/* Delete all neighbor addresses learnt through IPv6 RA */ +	if_down_del_nbr_connected(ifp); -  /* Send out notification on interface VRF change. */ -  /* This is to issue an UPDATE or a DELETE, as appropriate. */ -  zebra_interface_vrf_update_del (ifp, vrf_id); +	/* Send out notification on interface VRF change. */ +	/* This is to issue an UPDATE or a DELETE, as appropriate. */ +	zebra_interface_vrf_update_del(ifp, vrf_id); -  /* update VRF */ -  if_update (ifp, ifp->name, strlen (ifp->name), vrf_id); +	/* update VRF */ +	if_update(ifp, ifp->name, strlen(ifp->name), vrf_id); -  /* Send out notification on interface VRF change. */ -  /* This is to issue an ADD, if needed. */ -  zebra_interface_vrf_update_add (ifp, old_vrf_id); +	/* Send out notification on interface VRF change. */ +	/* This is to issue an ADD, if needed. */ +	zebra_interface_vrf_update_add(ifp, old_vrf_id); -  /* Install connected routes (in new VRF). */ -  if_install_connected (ifp); +	/* Install connected routes (in new VRF). */ +	if_install_connected(ifp); -  static_ifindex_update(ifp, true); +	static_ifindex_update(ifp, true); -  /* Due to connected route change, schedule RIB processing for both old -   * and new VRF. -   */ -  if (IS_ZEBRA_DEBUG_RIB_DETAILED) -    zlog_debug ("%u: IF %s VRF change, scheduling RIB processing", -                ifp->vrf_id, ifp->name); -  rib_update (old_vrf_id, RIB_UPDATE_IF_CHANGE); -  rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE); +	/* Due to connected route change, schedule RIB processing for both old +	 * and new VRF. +	 */ +	if (IS_ZEBRA_DEBUG_RIB_DETAILED) +		zlog_debug("%u: IF %s VRF change, scheduling RIB processing", +			   ifp->vrf_id, ifp->name); +	rib_update(old_vrf_id, RIB_UPDATE_IF_CHANGE); +	rib_update(ifp->vrf_id, RIB_UPDATE_IF_CHANGE);  } -static void -ipv6_ll_address_to_mac (struct in6_addr *address, u_char *mac) +static void ipv6_ll_address_to_mac(struct in6_addr *address, u_char *mac)  { -  mac[0] = address->s6_addr[8] ^ 0x02; -  mac[1] = address->s6_addr[9]; -  mac[2] = address->s6_addr[10]; -  mac[3] = address->s6_addr[13]; -  mac[4] = address->s6_addr[14]; -  mac[5] = address->s6_addr[15]; +	mac[0] = address->s6_addr[8] ^ 0x02; +	mac[1] = address->s6_addr[9]; +	mac[2] = address->s6_addr[10]; +	mac[3] = address->s6_addr[13]; +	mac[4] = address->s6_addr[14]; +	mac[5] = address->s6_addr[15];  } -void -if_nbr_ipv6ll_to_ipv4ll_neigh_update (struct interface *ifp, -                                      struct in6_addr *address, -                                      int add) +void if_nbr_ipv6ll_to_ipv4ll_neigh_update(struct interface *ifp, +					  struct in6_addr *address, int add)  { -  char buf[16] = "169.254.0.1"; -  struct in_addr ipv4_ll; -  char mac[6]; +	char buf[16] = "169.254.0.1"; +	struct in_addr ipv4_ll; +	char mac[6]; -  inet_pton (AF_INET, buf, &ipv4_ll); +	inet_pton(AF_INET, buf, &ipv4_ll); -  ipv6_ll_address_to_mac(address, (u_char *)mac); -  kernel_neigh_update (add, ifp->ifindex, ipv4_ll.s_addr, mac, 6); +	ipv6_ll_address_to_mac(address, (u_char *)mac); +	kernel_neigh_update(add, ifp->ifindex, ipv4_ll.s_addr, mac, 6);  } -static void -if_nbr_ipv6ll_to_ipv4ll_neigh_add_all (struct interface *ifp) +static void if_nbr_ipv6ll_to_ipv4ll_neigh_add_all(struct interface *ifp)  { -  if (listhead(ifp->nbr_connected)) -    { -      struct nbr_connected *nbr_connected; -      struct listnode *node; +	if (listhead(ifp->nbr_connected)) { +		struct nbr_connected *nbr_connected; +		struct listnode *node; -      for (ALL_LIST_ELEMENTS_RO (ifp->nbr_connected, node, nbr_connected)) -        if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp, -                                              &nbr_connected->address->u.prefix6, -                                              1); -    } +		for (ALL_LIST_ELEMENTS_RO(ifp->nbr_connected, node, +					  nbr_connected)) +			if_nbr_ipv6ll_to_ipv4ll_neigh_update( +				ifp, &nbr_connected->address->u.prefix6, 1); +	}  } -void -if_nbr_ipv6ll_to_ipv4ll_neigh_del_all (struct interface *ifp) +void if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(struct interface *ifp)  { -  if (listhead(ifp->nbr_connected)) -    { -      struct nbr_connected *nbr_connected; -      struct listnode *node; +	if (listhead(ifp->nbr_connected)) { +		struct nbr_connected *nbr_connected; +		struct listnode *node; -      for (ALL_LIST_ELEMENTS_RO (ifp->nbr_connected, node, nbr_connected)) -        if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp, -                                              &nbr_connected->address->u.prefix6, -                                              0); -    } +		for (ALL_LIST_ELEMENTS_RO(ifp->nbr_connected, node, +					  nbr_connected)) +			if_nbr_ipv6ll_to_ipv4ll_neigh_update( +				ifp, &nbr_connected->address->u.prefix6, 0); +	}  } -static void -if_down_del_nbr_connected (struct interface *ifp) +static void if_down_del_nbr_connected(struct interface *ifp)  { -  struct nbr_connected *nbr_connected; -  struct listnode *node, *nnode; +	struct nbr_connected *nbr_connected; +	struct listnode *node, *nnode; -  for (ALL_LIST_ELEMENTS (ifp->nbr_connected, node, nnode, nbr_connected)) -    { -      listnode_delete (ifp->nbr_connected, nbr_connected); -      nbr_connected_free (nbr_connected); -    } +	for (ALL_LIST_ELEMENTS(ifp->nbr_connected, node, nnode, +			       nbr_connected)) { +		listnode_delete(ifp->nbr_connected, nbr_connected); +		nbr_connected_free(nbr_connected); +	}  }  /* Interface is up. */ -void -if_up (struct interface *ifp) +void if_up(struct interface *ifp)  { -  struct zebra_if *zif; +	struct zebra_if *zif; -  zif = ifp->info; -  zif->up_count++; -  quagga_timestamp (2, zif->up_last, sizeof (zif->up_last)); +	zif = ifp->info; +	zif->up_count++; +	quagga_timestamp(2, zif->up_last, sizeof(zif->up_last)); -  /* Notify the protocol daemons. */ -  if (ifp->ptm_enable && (ifp->ptm_status == ZEBRA_PTM_STATUS_DOWN)) { -    zlog_warn("%s: interface %s hasn't passed ptm check\n", __func__, -	      ifp->name); -    return; -  } -  zebra_interface_up_update (ifp); +	/* Notify the protocol daemons. */ +	if (ifp->ptm_enable && (ifp->ptm_status == ZEBRA_PTM_STATUS_DOWN)) { +		zlog_warn("%s: interface %s hasn't passed ptm check\n", +			  __func__, ifp->name); +		return; +	} +	zebra_interface_up_update(ifp); -  if_nbr_ipv6ll_to_ipv4ll_neigh_add_all (ifp); +	if_nbr_ipv6ll_to_ipv4ll_neigh_add_all(ifp); -  /* Enable fast tx of RA if enabled && RA interval is not in msecs */ -  if (zif->rtadv.AdvSendAdvertisements && -      (zif->rtadv.MaxRtrAdvInterval >= 1000)) -    { -      zif->rtadv.inFastRexmit = 1; -      zif->rtadv.NumFastReXmitsRemain = RTADV_NUM_FAST_REXMITS; -    } +	/* Enable fast tx of RA if enabled && RA interval is not in msecs */ +	if (zif->rtadv.AdvSendAdvertisements +	    && (zif->rtadv.MaxRtrAdvInterval >= 1000)) { +		zif->rtadv.inFastRexmit = 1; +		zif->rtadv.NumFastReXmitsRemain = RTADV_NUM_FAST_REXMITS; +	} -  /* Install connected routes to the kernel. */ -  if_install_connected (ifp); +	/* Install connected routes to the kernel. */ +	if_install_connected(ifp); -  if (IS_ZEBRA_DEBUG_RIB_DETAILED) -    zlog_debug ("%u: IF %s up, scheduling RIB processing", -                ifp->vrf_id, ifp->name); -  rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE); +	if (IS_ZEBRA_DEBUG_RIB_DETAILED) +		zlog_debug("%u: IF %s up, scheduling RIB processing", +			   ifp->vrf_id, ifp->name); +	rib_update(ifp->vrf_id, RIB_UPDATE_IF_CHANGE);  }  /* Interface goes down.  We have to manage different behavior of based     OS. */ -void -if_down (struct interface *ifp) +void if_down(struct interface *ifp)  { -  struct zebra_if *zif; +	struct zebra_if *zif; -  zif = ifp->info; -  zif->down_count++; -  quagga_timestamp (2, zif->down_last, sizeof (zif->down_last)); +	zif = ifp->info; +	zif->down_count++; +	quagga_timestamp(2, zif->down_last, sizeof(zif->down_last)); -  /* Notify to the protocol daemons. */ -  zebra_interface_down_update (ifp); +	/* Notify to the protocol daemons. */ +	zebra_interface_down_update(ifp); -  /* Uninstall connected routes from the kernel. */ -  if_uninstall_connected (ifp); +	/* Uninstall connected routes from the kernel. */ +	if_uninstall_connected(ifp); -  if (IS_ZEBRA_DEBUG_RIB_DETAILED) -    zlog_debug ("%u: IF %s down, scheduling RIB processing", -                ifp->vrf_id, ifp->name); -  rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE); +	if (IS_ZEBRA_DEBUG_RIB_DETAILED) +		zlog_debug("%u: IF %s down, scheduling RIB processing", +			   ifp->vrf_id, ifp->name); +	rib_update(ifp->vrf_id, RIB_UPDATE_IF_CHANGE); -  if_nbr_ipv6ll_to_ipv4ll_neigh_del_all (ifp); +	if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp); -  /* Delete all neighbor addresses learnt through IPv6 RA */ -  if_down_del_nbr_connected (ifp); +	/* Delete all neighbor addresses learnt through IPv6 RA */ +	if_down_del_nbr_connected(ifp);  } -void -if_refresh (struct interface *ifp) +void if_refresh(struct interface *ifp)  { -  if_get_flags (ifp); +	if_get_flags(ifp);  }  /* Output prefix string to vty. */ -static int -prefix_vty_out (struct vty *vty, struct prefix *p) +static int prefix_vty_out(struct vty *vty, struct prefix *p)  { -  char str[INET6_ADDRSTRLEN]; +	char str[INET6_ADDRSTRLEN]; -  inet_ntop (p->family, &p->u.prefix, str, sizeof (str)); -  vty_out (vty, "%s", str); -  return strlen (str); +	inet_ntop(p->family, &p->u.prefix, str, sizeof(str)); +	vty_out(vty, "%s", str); +	return strlen(str);  }  /* Dump if address information to vty. */ -static void -connected_dump_vty (struct vty *vty, struct connected *connected) +static void connected_dump_vty(struct vty *vty, struct connected *connected)  { -  struct prefix *p; +	struct prefix *p; -  /* Print interface address. */ -  p = connected->address; -  vty_out (vty, "  %s ", prefix_family_str (p)); -  prefix_vty_out (vty, p); -  vty_out (vty, "/%d", p->prefixlen); +	/* Print interface address. */ +	p = connected->address; +	vty_out(vty, "  %s ", prefix_family_str(p)); +	prefix_vty_out(vty, p); +	vty_out(vty, "/%d", p->prefixlen); -  /* If there is destination address, print it. */ -  if (connected->destination) -    { -      vty_out (vty, (CONNECTED_PEER(connected) ? " peer " : " broadcast ")); -      prefix_vty_out (vty, connected->destination); -    } +	/* If there is destination address, print it. */ +	if (connected->destination) { +		vty_out(vty, +			(CONNECTED_PEER(connected) ? " peer " : " broadcast ")); +		prefix_vty_out(vty, connected->destination); +	} -  if (CHECK_FLAG (connected->flags, ZEBRA_IFA_SECONDARY)) -    vty_out (vty, " secondary"); +	if (CHECK_FLAG(connected->flags, ZEBRA_IFA_SECONDARY)) +		vty_out(vty, " secondary"); -  if (CHECK_FLAG (connected->flags, ZEBRA_IFA_UNNUMBERED)) -    vty_out (vty, " unnumbered"); +	if (CHECK_FLAG(connected->flags, ZEBRA_IFA_UNNUMBERED)) +		vty_out(vty, " unnumbered"); -  if (connected->label) -    vty_out (vty, " %s", connected->label); +	if (connected->label) +		vty_out(vty, " %s", connected->label); -  vty_out (vty, "%s", VTY_NEWLINE); +	vty_out(vty, "%s", VTY_NEWLINE);  }  /* Dump interface neighbor address information to vty. */ -static void -nbr_connected_dump_vty (struct vty *vty, struct nbr_connected *connected) +static void nbr_connected_dump_vty(struct vty *vty, +				   struct nbr_connected *connected)  { -  struct prefix *p; +	struct prefix *p; -  /* Print interface address. */ -  p = connected->address; -  vty_out (vty, "  %s ", prefix_family_str (p)); -  prefix_vty_out (vty, p); -  vty_out (vty, "/%d", p->prefixlen); +	/* Print interface address. */ +	p = connected->address; +	vty_out(vty, "  %s ", prefix_family_str(p)); +	prefix_vty_out(vty, p); +	vty_out(vty, "/%d", p->prefixlen); -  vty_out (vty, "%s", VTY_NEWLINE); +	vty_out(vty, "%s", VTY_NEWLINE);  } -#if defined (HAVE_RTADV) +#if defined(HAVE_RTADV)  /* Dump interface ND information to vty. */ -static void -nd_dump_vty (struct vty *vty, struct interface *ifp) -{ -  struct zebra_if *zif; -  struct rtadvconf *rtadv; -  int interval; - -  zif = (struct zebra_if *) ifp->info; -  rtadv = &zif->rtadv; - -  if (rtadv->AdvSendAdvertisements) -    { -      vty_out (vty, "  ND advertised reachable time is %d milliseconds%s", -	       rtadv->AdvReachableTime, VTY_NEWLINE); -      vty_out (vty, "  ND advertised retransmit interval is %d milliseconds%s", -	       rtadv->AdvRetransTimer, VTY_NEWLINE); -      vty_out (vty, "  ND router advertisements sent: %d rcvd: %d%s", -	       zif->ra_sent, zif->ra_rcvd, VTY_NEWLINE); -      interval = rtadv->MaxRtrAdvInterval; -      if (interval % 1000) -        vty_out (vty, "  ND router advertisements are sent every " -			"%d milliseconds%s", interval, -		 VTY_NEWLINE); -      else -        vty_out (vty, "  ND router advertisements are sent every " -			"%d seconds%s", interval / 1000, -		 VTY_NEWLINE); -      if (rtadv->AdvDefaultLifetime != -1) -	vty_out (vty, "  ND router advertisements live for %d seconds%s", -		 rtadv->AdvDefaultLifetime, VTY_NEWLINE); -      else -	vty_out (vty, "  ND router advertisements lifetime tracks ra-interval%s", -		 VTY_NEWLINE); -      vty_out (vty, "  ND router advertisement default router preference is " -			"%s%s", rtadv_pref_strs[rtadv->DefaultPreference], -		 VTY_NEWLINE); -      if (rtadv->AdvManagedFlag) -	vty_out (vty, "  Hosts use DHCP to obtain routable addresses.%s", -		 VTY_NEWLINE); -      else -	vty_out (vty, "  Hosts use stateless autoconfig for addresses.%s", -		 VTY_NEWLINE); -      if (rtadv->AdvHomeAgentFlag) -      { -      	vty_out (vty, "  ND router advertisements with " +static void nd_dump_vty(struct vty *vty, struct interface *ifp) +{ +	struct zebra_if *zif; +	struct rtadvconf *rtadv; +	int interval; + +	zif = (struct zebra_if *)ifp->info; +	rtadv = &zif->rtadv; + +	if (rtadv->AdvSendAdvertisements) { +		vty_out(vty, +			"  ND advertised reachable time is %d milliseconds%s", +			rtadv->AdvReachableTime, VTY_NEWLINE); +		vty_out(vty, +			"  ND advertised retransmit interval is %d milliseconds%s", +			rtadv->AdvRetransTimer, VTY_NEWLINE); +		vty_out(vty, "  ND router advertisements sent: %d rcvd: %d%s", +			zif->ra_sent, zif->ra_rcvd, VTY_NEWLINE); +		interval = rtadv->MaxRtrAdvInterval; +		if (interval % 1000) +			vty_out(vty, +				"  ND router advertisements are sent every " +				"%d milliseconds%s", +				interval, VTY_NEWLINE); +		else +			vty_out(vty, +				"  ND router advertisements are sent every " +				"%d seconds%s", +				interval / 1000, VTY_NEWLINE); +		if (rtadv->AdvDefaultLifetime != -1) +			vty_out(vty, +				"  ND router advertisements live for %d seconds%s", +				rtadv->AdvDefaultLifetime, VTY_NEWLINE); +		else +			vty_out(vty, +				"  ND router advertisements lifetime tracks ra-interval%s", +				VTY_NEWLINE); +		vty_out(vty, +			"  ND router advertisement default router preference is " +			"%s%s", +			rtadv_pref_strs[rtadv->DefaultPreference], VTY_NEWLINE); +		if (rtadv->AdvManagedFlag) +			vty_out(vty, +				"  Hosts use DHCP to obtain routable addresses.%s", +				VTY_NEWLINE); +		else +			vty_out(vty, +				"  Hosts use stateless autoconfig for addresses.%s", +				VTY_NEWLINE); +		if (rtadv->AdvHomeAgentFlag) { +			vty_out(vty, +				"  ND router advertisements with "  				"Home Agent flag bit set.%s", -		 VTY_NEWLINE); -	if (rtadv->HomeAgentLifetime != -1) -	  vty_out (vty, "  Home Agent lifetime is %u seconds%s", -	           rtadv->HomeAgentLifetime, VTY_NEWLINE); -	else -	  vty_out (vty, "  Home Agent lifetime tracks ra-lifetime%s", -	           VTY_NEWLINE); -	vty_out (vty, "  Home Agent preference is %u%s", -	         rtadv->HomeAgentPreference, VTY_NEWLINE); -      } -      if (rtadv->AdvIntervalOption) -      	vty_out (vty, "  ND router advertisements with Adv. Interval option.%s", -		 VTY_NEWLINE); -    } +				VTY_NEWLINE); +			if (rtadv->HomeAgentLifetime != -1) +				vty_out(vty, +					"  Home Agent lifetime is %u seconds%s", +					rtadv->HomeAgentLifetime, VTY_NEWLINE); +			else +				vty_out(vty, +					"  Home Agent lifetime tracks ra-lifetime%s", +					VTY_NEWLINE); +			vty_out(vty, "  Home Agent preference is %u%s", +				rtadv->HomeAgentPreference, VTY_NEWLINE); +		} +		if (rtadv->AdvIntervalOption) +			vty_out(vty, +				"  ND router advertisements with Adv. Interval option.%s", +				VTY_NEWLINE); +	}  }  #endif /* HAVE_RTADV */  /* Interface's information print out to vty interface. */ -static void -if_dump_vty (struct vty *vty, struct interface *ifp) -{ -  struct connected *connected; -  struct nbr_connected *nbr_connected; -  struct listnode *node; -  struct route_node *rn; -  struct zebra_if *zebra_if; -  struct vrf *vrf; - -  zebra_if = ifp->info; - -  vty_out (vty, "Interface %s is ", ifp->name); -  if (if_is_up(ifp)) { -    vty_out (vty, "up, line protocol "); -     -    if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) { -      if (if_is_running(ifp)) -       vty_out (vty, "is up%s", VTY_NEWLINE); -      else -	vty_out (vty, "is down%s", VTY_NEWLINE); -    } else { -      vty_out (vty, "detection is disabled%s", VTY_NEWLINE); -    } -  } else { -    vty_out (vty, "down%s", VTY_NEWLINE); -  } - -  vty_out (vty, "  Link ups:   %5u    last: %s%s", zebra_if->up_count, -           zebra_if->up_last[0] ? zebra_if->up_last : "(never)", VTY_NEWLINE); -  vty_out (vty, "  Link downs: %5u    last: %s%s", zebra_if->down_count, -           zebra_if->down_last[0] ? zebra_if->down_last : "(never)", VTY_NEWLINE); - -  zebra_ptm_show_status(vty, ifp); - -  vrf = vrf_lookup_by_id (ifp->vrf_id); -  vty_out (vty, "  vrf: %s%s", vrf->name, VTY_NEWLINE); - -  if (ifp->desc) -    vty_out (vty, "  Description: %s%s", ifp->desc, -	     VTY_NEWLINE); -  if (ifp->ifindex == IFINDEX_INTERNAL) -    { -      vty_out(vty, "  pseudo interface%s", VTY_NEWLINE); -      return; -    } -  else if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)) -    { -      vty_out(vty, "  index %d inactive interface%s",  -	      ifp->ifindex,  -	      VTY_NEWLINE); -      return; -    } - -  vty_out (vty, "  index %d metric %d mtu %d speed %u ", -	   ifp->ifindex, ifp->metric, ifp->mtu, ifp->speed); -  if (ifp->mtu6 != ifp->mtu) -    vty_out (vty, "mtu6 %d ", ifp->mtu6); -  vty_out (vty, "%s  flags: %s%s", VTY_NEWLINE, -           if_flag_dump (ifp->flags), VTY_NEWLINE); -   -  /* Hardware address. */ -  vty_out (vty, "  Type: %s%s", if_link_type_str (ifp->ll_type), VTY_NEWLINE); -  if (ifp->hw_addr_len != 0) -    { -      int i; - -      vty_out (vty, "  HWaddr: "); -      for (i = 0; i < ifp->hw_addr_len; i++) -	vty_out (vty, "%s%02x", i == 0 ? "" : ":", ifp->hw_addr[i]); -      vty_out (vty, "%s", VTY_NEWLINE); -    } -   -  /* Bandwidth in Mbps */ -  if (ifp->bandwidth != 0) -    { -      vty_out(vty, "  bandwidth %u Mbps", ifp->bandwidth); -      vty_out(vty, "%s", VTY_NEWLINE); -    } - -  for (rn = route_top (zebra_if->ipv4_subnets); rn; rn = route_next (rn)) -    { -      if (! rn->info) -	continue; - -      for (ALL_LIST_ELEMENTS_RO ((struct list *)rn->info, node, connected)) -        connected_dump_vty (vty, connected); -    } - -  for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected)) -    { -      if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) && -	  (connected->address->family == AF_INET6)) -	connected_dump_vty (vty, connected); -    } - -  if (HAS_LINK_PARAMS(ifp)) -    { -      int i; -      struct if_link_params *iflp = ifp->link_params; -      vty_out(vty, "  Traffic Engineering Link Parameters:%s", VTY_NEWLINE); -      if (IS_PARAM_SET(iflp, LP_TE_METRIC)) -        vty_out(vty, "    TE metric %u%s",iflp->te_metric, VTY_NEWLINE); -      if (IS_PARAM_SET(iflp, LP_MAX_BW)) -        vty_out(vty, "    Maximum Bandwidth %g (Byte/s)%s", iflp->max_bw, VTY_NEWLINE); -      if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW)) -        vty_out(vty, "    Maximum Reservable Bandwidth %g (Byte/s)%s", iflp->max_rsv_bw, VTY_NEWLINE); -      if (IS_PARAM_SET(iflp, LP_UNRSV_BW)) { -        vty_out(vty, "    Unreserved Bandwidth per Class Type in Byte/s:%s", VTY_NEWLINE); -        for (i = 0; i < MAX_CLASS_TYPE; i+=2) -          vty_out(vty, "      [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)%s", -                  i, iflp->unrsv_bw[i], i+1, iflp->unrsv_bw[i+1], VTY_NEWLINE); -      } - -      if (IS_PARAM_SET(iflp, LP_ADM_GRP)) -        vty_out(vty, "    Administrative Group:%u%s", iflp->admin_grp, VTY_NEWLINE); -      if (IS_PARAM_SET(iflp, LP_DELAY)) -        { -          vty_out(vty, "    Link Delay Average: %u (micro-sec.)", iflp->av_delay); -          if (IS_PARAM_SET(iflp, LP_MM_DELAY)) -            { -              vty_out(vty, " Min:  %u (micro-sec.)", iflp->min_delay); -              vty_out(vty, " Max:  %u (micro-sec.)", iflp->max_delay); -            } -          vty_out(vty, "%s", VTY_NEWLINE); -        } -      if (IS_PARAM_SET(iflp, LP_DELAY_VAR)) -        vty_out(vty, "    Link Delay Variation %u (micro-sec.)%s", iflp->delay_var, VTY_NEWLINE); -      if (IS_PARAM_SET(iflp, LP_PKT_LOSS)) -        vty_out(vty, "    Link Packet Loss %g (in %%)%s", iflp->pkt_loss, VTY_NEWLINE); -      if (IS_PARAM_SET(iflp, LP_AVA_BW)) -        vty_out(vty, "    Available Bandwidth %g (Byte/s)%s", iflp->ava_bw, VTY_NEWLINE); -      if (IS_PARAM_SET(iflp, LP_RES_BW)) -        vty_out(vty, "    Residual Bandwidth %g (Byte/s)%s", iflp->res_bw, VTY_NEWLINE); -      if (IS_PARAM_SET(iflp, LP_USE_BW)) -        vty_out(vty, "    Utilized Bandwidth %g (Byte/s)%s", iflp->use_bw, VTY_NEWLINE); -      if (IS_PARAM_SET(iflp, LP_RMT_AS)) -        vty_out(vty, "    Neighbor ASBR IP: %s AS: %u %s", inet_ntoa(iflp->rmt_ip), iflp->rmt_as, VTY_NEWLINE); -    } - - #ifdef RTADV -   nd_dump_vty (vty, ifp); - #endif /* RTADV */ -#if defined (HAVE_RTADV) -  nd_dump_vty (vty, ifp); +static void if_dump_vty(struct vty *vty, struct interface *ifp) +{ +	struct connected *connected; +	struct nbr_connected *nbr_connected; +	struct listnode *node; +	struct route_node *rn; +	struct zebra_if *zebra_if; +	struct vrf *vrf; + +	zebra_if = ifp->info; + +	vty_out(vty, "Interface %s is ", ifp->name); +	if (if_is_up(ifp)) { +		vty_out(vty, "up, line protocol "); + +		if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) { +			if (if_is_running(ifp)) +				vty_out(vty, "is up%s", VTY_NEWLINE); +			else +				vty_out(vty, "is down%s", VTY_NEWLINE); +		} else { +			vty_out(vty, "detection is disabled%s", VTY_NEWLINE); +		} +	} else { +		vty_out(vty, "down%s", VTY_NEWLINE); +	} + +	vty_out(vty, "  Link ups:   %5u    last: %s%s", zebra_if->up_count, +		zebra_if->up_last[0] ? zebra_if->up_last : "(never)", +		VTY_NEWLINE); +	vty_out(vty, "  Link downs: %5u    last: %s%s", zebra_if->down_count, +		zebra_if->down_last[0] ? zebra_if->down_last : "(never)", +		VTY_NEWLINE); + +	zebra_ptm_show_status(vty, ifp); + +	vrf = vrf_lookup_by_id(ifp->vrf_id); +	vty_out(vty, "  vrf: %s%s", vrf->name, VTY_NEWLINE); + +	if (ifp->desc) +		vty_out(vty, "  Description: %s%s", ifp->desc, VTY_NEWLINE); +	if (ifp->ifindex == IFINDEX_INTERNAL) { +		vty_out(vty, "  pseudo interface%s", VTY_NEWLINE); +		return; +	} else if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) { +		vty_out(vty, "  index %d inactive interface%s", ifp->ifindex, +			VTY_NEWLINE); +		return; +	} + +	vty_out(vty, "  index %d metric %d mtu %d speed %u ", ifp->ifindex, +		ifp->metric, ifp->mtu, ifp->speed); +	if (ifp->mtu6 != ifp->mtu) +		vty_out(vty, "mtu6 %d ", ifp->mtu6); +	vty_out(vty, "%s  flags: %s%s", VTY_NEWLINE, if_flag_dump(ifp->flags), +		VTY_NEWLINE); + +	/* Hardware address. */ +	vty_out(vty, "  Type: %s%s", if_link_type_str(ifp->ll_type), +		VTY_NEWLINE); +	if (ifp->hw_addr_len != 0) { +		int i; + +		vty_out(vty, "  HWaddr: "); +		for (i = 0; i < ifp->hw_addr_len; i++) +			vty_out(vty, "%s%02x", i == 0 ? "" : ":", +				ifp->hw_addr[i]); +		vty_out(vty, "%s", VTY_NEWLINE); +	} + +	/* Bandwidth in Mbps */ +	if (ifp->bandwidth != 0) { +		vty_out(vty, "  bandwidth %u Mbps", ifp->bandwidth); +		vty_out(vty, "%s", VTY_NEWLINE); +	} + +	for (rn = route_top(zebra_if->ipv4_subnets); rn; rn = route_next(rn)) { +		if (!rn->info) +			continue; + +		for (ALL_LIST_ELEMENTS_RO((struct list *)rn->info, node, +					  connected)) +			connected_dump_vty(vty, connected); +	} + +	for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) { +		if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL) +		    && (connected->address->family == AF_INET6)) +			connected_dump_vty(vty, connected); +	} + +	if (HAS_LINK_PARAMS(ifp)) { +		int i; +		struct if_link_params *iflp = ifp->link_params; +		vty_out(vty, "  Traffic Engineering Link Parameters:%s", +			VTY_NEWLINE); +		if (IS_PARAM_SET(iflp, LP_TE_METRIC)) +			vty_out(vty, "    TE metric %u%s", iflp->te_metric, +				VTY_NEWLINE); +		if (IS_PARAM_SET(iflp, LP_MAX_BW)) +			vty_out(vty, "    Maximum Bandwidth %g (Byte/s)%s", +				iflp->max_bw, VTY_NEWLINE); +		if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW)) +			vty_out(vty, +				"    Maximum Reservable Bandwidth %g (Byte/s)%s", +				iflp->max_rsv_bw, VTY_NEWLINE); +		if (IS_PARAM_SET(iflp, LP_UNRSV_BW)) { +			vty_out(vty, +				"    Unreserved Bandwidth per Class Type in Byte/s:%s", +				VTY_NEWLINE); +			for (i = 0; i < MAX_CLASS_TYPE; i += 2) +				vty_out(vty, +					"      [%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)%s", +					i, iflp->unrsv_bw[i], i + 1, +					iflp->unrsv_bw[i + 1], VTY_NEWLINE); +		} + +		if (IS_PARAM_SET(iflp, LP_ADM_GRP)) +			vty_out(vty, "    Administrative Group:%u%s", +				iflp->admin_grp, VTY_NEWLINE); +		if (IS_PARAM_SET(iflp, LP_DELAY)) { +			vty_out(vty, "    Link Delay Average: %u (micro-sec.)", +				iflp->av_delay); +			if (IS_PARAM_SET(iflp, LP_MM_DELAY)) { +				vty_out(vty, " Min:  %u (micro-sec.)", +					iflp->min_delay); +				vty_out(vty, " Max:  %u (micro-sec.)", +					iflp->max_delay); +			} +			vty_out(vty, "%s", VTY_NEWLINE); +		} +		if (IS_PARAM_SET(iflp, LP_DELAY_VAR)) +			vty_out(vty, +				"    Link Delay Variation %u (micro-sec.)%s", +				iflp->delay_var, VTY_NEWLINE); +		if (IS_PARAM_SET(iflp, LP_PKT_LOSS)) +			vty_out(vty, "    Link Packet Loss %g (in %%)%s", +				iflp->pkt_loss, VTY_NEWLINE); +		if (IS_PARAM_SET(iflp, LP_AVA_BW)) +			vty_out(vty, "    Available Bandwidth %g (Byte/s)%s", +				iflp->ava_bw, VTY_NEWLINE); +		if (IS_PARAM_SET(iflp, LP_RES_BW)) +			vty_out(vty, "    Residual Bandwidth %g (Byte/s)%s", +				iflp->res_bw, VTY_NEWLINE); +		if (IS_PARAM_SET(iflp, LP_USE_BW)) +			vty_out(vty, "    Utilized Bandwidth %g (Byte/s)%s", +				iflp->use_bw, VTY_NEWLINE); +		if (IS_PARAM_SET(iflp, LP_RMT_AS)) +			vty_out(vty, "    Neighbor ASBR IP: %s AS: %u %s", +				inet_ntoa(iflp->rmt_ip), iflp->rmt_as, +				VTY_NEWLINE); +	} + +#ifdef RTADV +	nd_dump_vty(vty, ifp); +#endif /* RTADV */ +#if defined(HAVE_RTADV) +	nd_dump_vty(vty, ifp);  #endif /* HAVE_RTADV */ -  if (listhead(ifp->nbr_connected)) -    vty_out (vty, "  Neighbor address(s):%s", VTY_NEWLINE); -  for (ALL_LIST_ELEMENTS_RO (ifp->nbr_connected, node, nbr_connected)) -    nbr_connected_dump_vty (vty, nbr_connected); +	if (listhead(ifp->nbr_connected)) +		vty_out(vty, "  Neighbor address(s):%s", VTY_NEWLINE); +	for (ALL_LIST_ELEMENTS_RO(ifp->nbr_connected, node, nbr_connected)) +		nbr_connected_dump_vty(vty, nbr_connected);  #ifdef HAVE_PROC_NET_DEV -  /* Statistics print out using proc file system. */ -  vty_out (vty, "    %lu input packets (%lu multicast), %lu bytes, " -	   "%lu dropped%s", -	   ifp->stats.rx_packets, ifp->stats.rx_multicast, -	   ifp->stats.rx_bytes, ifp->stats.rx_dropped, VTY_NEWLINE); - -  vty_out (vty, "    %lu input errors, %lu length, %lu overrun," -	   " %lu CRC, %lu frame%s", -	   ifp->stats.rx_errors, ifp->stats.rx_length_errors, -	   ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors, -	   ifp->stats.rx_frame_errors, VTY_NEWLINE); - -  vty_out (vty, "    %lu fifo, %lu missed%s", ifp->stats.rx_fifo_errors, -	   ifp->stats.rx_missed_errors, VTY_NEWLINE); - -  vty_out (vty, "    %lu output packets, %lu bytes, %lu dropped%s", -	   ifp->stats.tx_packets, ifp->stats.tx_bytes, -	   ifp->stats.tx_dropped, VTY_NEWLINE); - -  vty_out (vty, "    %lu output errors, %lu aborted, %lu carrier," -	   " %lu fifo, %lu heartbeat%s", -	   ifp->stats.tx_errors, ifp->stats.tx_aborted_errors, -	   ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors, -	   ifp->stats.tx_heartbeat_errors, VTY_NEWLINE); - -  vty_out (vty, "    %lu window, %lu collisions%s", -	   ifp->stats.tx_window_errors, ifp->stats.collisions, VTY_NEWLINE); +	/* Statistics print out using proc file system. */ +	vty_out(vty, +		"    %lu input packets (%lu multicast), %lu bytes, " +		"%lu dropped%s", +		ifp->stats.rx_packets, ifp->stats.rx_multicast, +		ifp->stats.rx_bytes, ifp->stats.rx_dropped, VTY_NEWLINE); + +	vty_out(vty, +		"    %lu input errors, %lu length, %lu overrun," +		" %lu CRC, %lu frame%s", +		ifp->stats.rx_errors, ifp->stats.rx_length_errors, +		ifp->stats.rx_over_errors, ifp->stats.rx_crc_errors, +		ifp->stats.rx_frame_errors, VTY_NEWLINE); + +	vty_out(vty, "    %lu fifo, %lu missed%s", ifp->stats.rx_fifo_errors, +		ifp->stats.rx_missed_errors, VTY_NEWLINE); + +	vty_out(vty, "    %lu output packets, %lu bytes, %lu dropped%s", +		ifp->stats.tx_packets, ifp->stats.tx_bytes, +		ifp->stats.tx_dropped, VTY_NEWLINE); + +	vty_out(vty, +		"    %lu output errors, %lu aborted, %lu carrier," +		" %lu fifo, %lu heartbeat%s", +		ifp->stats.tx_errors, ifp->stats.tx_aborted_errors, +		ifp->stats.tx_carrier_errors, ifp->stats.tx_fifo_errors, +		ifp->stats.tx_heartbeat_errors, VTY_NEWLINE); + +	vty_out(vty, "    %lu window, %lu collisions%s", +		ifp->stats.tx_window_errors, ifp->stats.collisions, +		VTY_NEWLINE);  #endif /* HAVE_PROC_NET_DEV */  #ifdef HAVE_NET_RT_IFLIST -#if defined (__bsdi__) || defined (__NetBSD__) -  /* Statistics print out using sysctl (). */ -  vty_out (vty, "    input packets %llu, bytes %llu, dropped %llu," -           " multicast packets %llu%s", -           (unsigned long long)ifp->stats.ifi_ipackets, -           (unsigned long long)ifp->stats.ifi_ibytes, -           (unsigned long long)ifp->stats.ifi_iqdrops, -           (unsigned long long)ifp->stats.ifi_imcasts, -           VTY_NEWLINE); - -  vty_out (vty, "    input errors %llu%s", -           (unsigned long long)ifp->stats.ifi_ierrors, VTY_NEWLINE); - -  vty_out (vty, "    output packets %llu, bytes %llu," -           " multicast packets %llu%s", -           (unsigned long long)ifp->stats.ifi_opackets, -           (unsigned long long)ifp->stats.ifi_obytes, -           (unsigned long long)ifp->stats.ifi_omcasts, -           VTY_NEWLINE); - -  vty_out (vty, "    output errors %llu%s", -           (unsigned long long)ifp->stats.ifi_oerrors, VTY_NEWLINE); - -  vty_out (vty, "    collisions %llu%s", -           (unsigned long long)ifp->stats.ifi_collisions, VTY_NEWLINE); +#if defined(__bsdi__) || defined(__NetBSD__) +	/* Statistics print out using sysctl (). */ +	vty_out(vty, +		"    input packets %llu, bytes %llu, dropped %llu," +		" multicast packets %llu%s", +		(unsigned long long)ifp->stats.ifi_ipackets, +		(unsigned long long)ifp->stats.ifi_ibytes, +		(unsigned long long)ifp->stats.ifi_iqdrops, +		(unsigned long long)ifp->stats.ifi_imcasts, VTY_NEWLINE); + +	vty_out(vty, "    input errors %llu%s", +		(unsigned long long)ifp->stats.ifi_ierrors, VTY_NEWLINE); + +	vty_out(vty, +		"    output packets %llu, bytes %llu," +		" multicast packets %llu%s", +		(unsigned long long)ifp->stats.ifi_opackets, +		(unsigned long long)ifp->stats.ifi_obytes, +		(unsigned long long)ifp->stats.ifi_omcasts, VTY_NEWLINE); + +	vty_out(vty, "    output errors %llu%s", +		(unsigned long long)ifp->stats.ifi_oerrors, VTY_NEWLINE); + +	vty_out(vty, "    collisions %llu%s", +		(unsigned long long)ifp->stats.ifi_collisions, VTY_NEWLINE);  #else -  /* Statistics print out using sysctl (). */ -  vty_out (vty, "    input packets %lu, bytes %lu, dropped %lu," -	   " multicast packets %lu%s", -	   ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes, -	   ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts, -	   VTY_NEWLINE); - -  vty_out (vty, "    input errors %lu%s", -	   ifp->stats.ifi_ierrors, VTY_NEWLINE); - -  vty_out (vty, "    output packets %lu, bytes %lu, multicast packets %lu%s", -	   ifp->stats.ifi_opackets, ifp->stats.ifi_obytes, -	   ifp->stats.ifi_omcasts, VTY_NEWLINE); - -  vty_out (vty, "    output errors %lu%s", -	   ifp->stats.ifi_oerrors, VTY_NEWLINE); - -  vty_out (vty, "    collisions %lu%s", -	   ifp->stats.ifi_collisions, VTY_NEWLINE); +	/* Statistics print out using sysctl (). */ +	vty_out(vty, +		"    input packets %lu, bytes %lu, dropped %lu," +		" multicast packets %lu%s", +		ifp->stats.ifi_ipackets, ifp->stats.ifi_ibytes, +		ifp->stats.ifi_iqdrops, ifp->stats.ifi_imcasts, VTY_NEWLINE); + +	vty_out(vty, "    input errors %lu%s", ifp->stats.ifi_ierrors, +		VTY_NEWLINE); + +	vty_out(vty, +		"    output packets %lu, bytes %lu, multicast packets %lu%s", +		ifp->stats.ifi_opackets, ifp->stats.ifi_obytes, +		ifp->stats.ifi_omcasts, VTY_NEWLINE); + +	vty_out(vty, "    output errors %lu%s", ifp->stats.ifi_oerrors, +		VTY_NEWLINE); + +	vty_out(vty, "    collisions %lu%s", ifp->stats.ifi_collisions, +		VTY_NEWLINE);  #endif /* __bsdi__ || __NetBSD__ */  #endif /* HAVE_NET_RT_IFLIST */  } -static void -interface_update_stats (void) +static void interface_update_stats(void)  {  #ifdef HAVE_PROC_NET_DEV -  /* If system has interface statistics via proc file system, update -     statistics. */ -  ifstat_update_proc (); +	/* If system has interface statistics via proc file system, update +	   statistics. */ +	ifstat_update_proc();  #endif /* HAVE_PROC_NET_DEV */  #ifdef HAVE_NET_RT_IFLIST -  ifstat_update_sysctl (); +	ifstat_update_sysctl();  #endif /* HAVE_NET_RT_IFLIST */  } -struct cmd_node interface_node = -{ -  INTERFACE_NODE, -  "%s(config-if)# ", -  1 -}; +struct cmd_node interface_node = {INTERFACE_NODE, "%s(config-if)# ", 1};  /* Show all interfaces to vty. */  DEFUN (show_interface, @@ -1285,20 +1271,20 @@ DEFUN (show_interface,         "Interface status and configuration\n"         VRF_CMD_HELP_STR)  { -  struct listnode *node; -  struct interface *ifp; -  vrf_id_t vrf_id = VRF_DEFAULT; +	struct listnode *node; +	struct interface *ifp; +	vrf_id_t vrf_id = VRF_DEFAULT; -  interface_update_stats (); +	interface_update_stats(); -  if (argc > 2) -    VRF_GET_ID (vrf_id, argv[3]->arg); +	if (argc > 2) +		VRF_GET_ID(vrf_id, argv[3]->arg); -  /* All interface print. */ -  for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp)) -    if_dump_vty (vty, ifp); +	/* All interface print. */ +	for (ALL_LIST_ELEMENTS_RO(vrf_iflist(vrf_id), node, ifp)) +		if_dump_vty(vty, ifp); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  } @@ -1310,18 +1296,18 @@ DEFUN (show_interface_vrf_all,         "Interface status and configuration\n"         VRF_ALL_CMD_HELP_STR)  { -  struct vrf *vrf; -  struct listnode *node; -  struct interface *ifp; +	struct vrf *vrf; +	struct listnode *node; +	struct interface *ifp; -  interface_update_stats (); +	interface_update_stats(); -  /* All interface print. */ -  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) -    for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp)) -      if_dump_vty (vty, ifp); +	/* All interface print. */ +	RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) +	for (ALL_LIST_ELEMENTS_RO(vrf->iflist, node, ifp)) +		if_dump_vty(vty, ifp); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  /* Show specified interface to vty. */ @@ -1334,26 +1320,25 @@ DEFUN (show_interface_name_vrf,         "Interface name\n"         VRF_CMD_HELP_STR)  { -  int idx_ifname = 2; -  int idx_name = 4; -  struct interface *ifp; -  vrf_id_t vrf_id = VRF_DEFAULT; +	int idx_ifname = 2; +	int idx_name = 4; +	struct interface *ifp; +	vrf_id_t vrf_id = VRF_DEFAULT; -  interface_update_stats (); +	interface_update_stats(); -  VRF_GET_ID (vrf_id, argv[idx_name]->arg); +	VRF_GET_ID(vrf_id, argv[idx_name]->arg); -  /* Specified interface print. */ -  ifp = if_lookup_by_name (argv[idx_ifname]->arg, vrf_id); -  if (ifp == NULL) -    { -      vty_out (vty, "%% Can't find interface %s%s", argv[idx_ifname]->arg, -               VTY_NEWLINE); -      return CMD_WARNING; -    } -  if_dump_vty (vty, ifp); +	/* Specified interface print. */ +	ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf_id); +	if (ifp == NULL) { +		vty_out(vty, "%% Can't find interface %s%s", +			argv[idx_ifname]->arg, VTY_NEWLINE); +		return CMD_WARNING; +	} +	if_dump_vty(vty, ifp); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  /* Show specified interface to vty. */ @@ -1365,73 +1350,66 @@ DEFUN (show_interface_name_vrf_all,         "Interface name\n"         VRF_ALL_CMD_HELP_STR)  { -  int idx_ifname = 2; -  struct vrf *vrf; -  struct interface *ifp; -  int found = 0; +	int idx_ifname = 2; +	struct vrf *vrf; +	struct interface *ifp; +	int found = 0; -  interface_update_stats (); +	interface_update_stats(); -  /* All interface print. */ -  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) -    { -      /* Specified interface print. */ -      ifp = if_lookup_by_name (argv[idx_ifname]->arg, vrf->vrf_id); -      if (ifp) -        { -          if_dump_vty (vty, ifp); -          found++; -        } -    } +	/* All interface print. */ +	RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) +	{ +		/* Specified interface print. */ +		ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf->vrf_id); +		if (ifp) { +			if_dump_vty(vty, ifp); +			found++; +		} +	} -  if (!found) -    { -      vty_out (vty, "%% Can't find interface %s%s", argv[idx_ifname]->arg, VTY_NEWLINE); -      return CMD_WARNING; -    } +	if (!found) { +		vty_out(vty, "%% Can't find interface %s%s", +			argv[idx_ifname]->arg, VTY_NEWLINE); +		return CMD_WARNING; +	} -  return CMD_SUCCESS; +	return CMD_SUCCESS;  } -static void -if_show_description (struct vty *vty, vrf_id_t vrf_id) +static void if_show_description(struct vty *vty, vrf_id_t vrf_id)  { -  struct listnode *node; -  struct interface *ifp; +	struct listnode *node; +	struct interface *ifp; -  vty_out (vty, "Interface       Status  Protocol  Description%s", VTY_NEWLINE); -  for (ALL_LIST_ELEMENTS_RO (vrf_iflist (vrf_id), node, ifp)) -    { -      int len; +	vty_out(vty, "Interface       Status  Protocol  Description%s", +		VTY_NEWLINE); +	for (ALL_LIST_ELEMENTS_RO(vrf_iflist(vrf_id), node, ifp)) { +		int len; -      len = vty_out (vty, "%s", ifp->name); -      vty_out (vty, "%*s", (16 - len), " "); -       -      if (if_is_up(ifp)) -	{ -	  vty_out (vty, "up      "); -	  if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) -	    { -	      if (if_is_running(ifp)) -		vty_out (vty, "up        "); -	      else -		vty_out (vty, "down      "); -	    } -	  else -	    { -	      vty_out (vty, "unknown   "); -	    } -	} -      else -	{ -	  vty_out (vty, "down    down      "); -	} +		len = vty_out(vty, "%s", ifp->name); +		vty_out(vty, "%*s", (16 - len), " "); + +		if (if_is_up(ifp)) { +			vty_out(vty, "up      "); +			if (CHECK_FLAG(ifp->status, +				       ZEBRA_INTERFACE_LINKDETECTION)) { +				if (if_is_running(ifp)) +					vty_out(vty, "up        "); +				else +					vty_out(vty, "down      "); +			} else { +				vty_out(vty, "unknown   "); +			} +		} else { +			vty_out(vty, "down    down      "); +		} -      if (ifp->desc) -	vty_out (vty, "%s", ifp->desc); -      vty_out (vty, "%s", VTY_NEWLINE); -    } +		if (ifp->desc) +			vty_out(vty, "%s", ifp->desc); +		vty_out(vty, "%s", VTY_NEWLINE); +	}  }  DEFUN (show_interface_desc, @@ -1442,14 +1420,14 @@ DEFUN (show_interface_desc,         "Interface description\n"         VRF_CMD_HELP_STR)  { -  vrf_id_t vrf_id = VRF_DEFAULT; +	vrf_id_t vrf_id = VRF_DEFAULT; -  if (argc > 3) -    VRF_GET_ID (vrf_id, argv[4]->arg); +	if (argc > 3) +		VRF_GET_ID(vrf_id, argv[4]->arg); -  if_show_description (vty, vrf_id); +	if_show_description(vty, vrf_id); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  } @@ -1461,17 +1439,16 @@ DEFUN (show_interface_desc_vrf_all,         "Interface description\n"         VRF_ALL_CMD_HELP_STR)  { -  struct vrf *vrf; +	struct vrf *vrf; -  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) -    if (!list_isempty (vrf->iflist)) -      { -        vty_out (vty, "%s\tVRF %u%s%s", VTY_NEWLINE, vrf->vrf_id, -		 VTY_NEWLINE, VTY_NEWLINE); -        if_show_description (vty, vrf->vrf_id); -      } +	RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) +	if (!list_isempty(vrf->iflist)) { +		vty_out(vty, "%s\tVRF %u%s%s", VTY_NEWLINE, vrf->vrf_id, +			VTY_NEWLINE, VTY_NEWLINE); +		if_show_description(vty, vrf->vrf_id); +	} -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (multicast, @@ -1479,24 +1456,22 @@ DEFUN (multicast,         "multicast",         "Set multicast flag to interface\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); -  int ret; -  struct zebra_if *if_data; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	int ret; +	struct zebra_if *if_data; -  if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)) -    { -      ret = if_set_flags (ifp, IFF_MULTICAST); -      if (ret < 0) -	{ -	  vty_out (vty, "Can't set multicast flag%s", VTY_NEWLINE); -	  return CMD_WARNING; +	if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) { +		ret = if_set_flags(ifp, IFF_MULTICAST); +		if (ret < 0) { +			vty_out(vty, "Can't set multicast flag%s", VTY_NEWLINE); +			return CMD_WARNING; +		} +		if_refresh(ifp);  	} -      if_refresh (ifp); -    } -  if_data = ifp->info; -  if_data->multicast = IF_ZEBRA_MULTICAST_ON; +	if_data = ifp->info; +	if_data->multicast = IF_ZEBRA_MULTICAST_ON; -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (no_multicast, @@ -1505,24 +1480,23 @@ DEFUN (no_multicast,         NO_STR         "Unset multicast flag to interface\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); -  int ret; -  struct zebra_if *if_data; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	int ret; +	struct zebra_if *if_data; -  if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)) -    { -      ret = if_unset_flags (ifp, IFF_MULTICAST); -      if (ret < 0) -	{ -	  vty_out (vty, "Can't unset multicast flag%s", VTY_NEWLINE); -	  return CMD_WARNING; +	if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) { +		ret = if_unset_flags(ifp, IFF_MULTICAST); +		if (ret < 0) { +			vty_out(vty, "Can't unset multicast flag%s", +				VTY_NEWLINE); +			return CMD_WARNING; +		} +		if_refresh(ifp);  	} -      if_refresh (ifp); -    } -  if_data = ifp->info; -  if_data->multicast = IF_ZEBRA_MULTICAST_OFF; +	if_data = ifp->info; +	if_data->multicast = IF_ZEBRA_MULTICAST_OFF; -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (linkdetect, @@ -1530,19 +1504,20 @@ DEFUN (linkdetect,         "link-detect",         "Enable link detection on interface\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); -  int if_was_operative; -   -  if_was_operative = if_is_no_ptm_operative(ifp); -  SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION); +	VTY_DECLVAR_CONTEXT(interface, ifp); +	int if_was_operative; + +	if_was_operative = if_is_no_ptm_operative(ifp); +	SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION); -  /* When linkdetection is enabled, if might come down */ -  if (!if_is_no_ptm_operative(ifp) && if_was_operative) if_down(ifp); +	/* When linkdetection is enabled, if might come down */ +	if (!if_is_no_ptm_operative(ifp) && if_was_operative) +		if_down(ifp); -  /* FIXME: Will defer status change forwarding if interface -     does not come down! */ +	/* FIXME: Will defer status change forwarding if interface +	   does not come down! */ -  return CMD_SUCCESS; +	return CMD_SUCCESS;  } @@ -1552,18 +1527,19 @@ DEFUN (no_linkdetect,         NO_STR         "Disable link detection on interface\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); -  int if_was_operative; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	int if_was_operative; -  if_was_operative = if_is_no_ptm_operative(ifp); -  UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION); -   -  /* Interface may come up after disabling link detection */ -  if (if_is_operative(ifp) && !if_was_operative) if_up(ifp); +	if_was_operative = if_is_no_ptm_operative(ifp); +	UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION); -  /* FIXME: see linkdetect_cmd */ +	/* Interface may come up after disabling link detection */ +	if (if_is_operative(ifp) && !if_was_operative) +		if_up(ifp); -  return CMD_SUCCESS; +	/* FIXME: see linkdetect_cmd */ + +	return CMD_SUCCESS;  }  DEFUN (shutdown_if, @@ -1571,24 +1547,22 @@ DEFUN (shutdown_if,         "shutdown",         "Shutdown the selected interface\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); -  int ret; -  struct zebra_if *if_data; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	int ret; +	struct zebra_if *if_data; -  if (ifp->ifindex != IFINDEX_INTERNAL) -    { -        ret = if_unset_flags (ifp, IFF_UP); -        if (ret < 0) -          { -            vty_out (vty, "Can't shutdown interface%s", VTY_NEWLINE); -            return CMD_WARNING; -          } -        if_refresh (ifp); -    } -  if_data = ifp->info; -  if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON; +	if (ifp->ifindex != IFINDEX_INTERNAL) { +		ret = if_unset_flags(ifp, IFF_UP); +		if (ret < 0) { +			vty_out(vty, "Can't shutdown interface%s", VTY_NEWLINE); +			return CMD_WARNING; +		} +		if_refresh(ifp); +	} +	if_data = ifp->info; +	if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON; -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (no_shutdown_if, @@ -1597,30 +1571,29 @@ DEFUN (no_shutdown_if,         NO_STR         "Shutdown the selected interface\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); -  int ret; -  struct zebra_if *if_data; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	int ret; +	struct zebra_if *if_data; -  if (ifp->ifindex != IFINDEX_INTERNAL) -    { -      ret = if_set_flags (ifp, IFF_UP | IFF_RUNNING); -      if (ret < 0) -	{ -	  vty_out (vty, "Can't up interface%s", VTY_NEWLINE); -	  return CMD_WARNING; -	} -      if_refresh (ifp); +	if (ifp->ifindex != IFINDEX_INTERNAL) { +		ret = if_set_flags(ifp, IFF_UP | IFF_RUNNING); +		if (ret < 0) { +			vty_out(vty, "Can't up interface%s", VTY_NEWLINE); +			return CMD_WARNING; +		} +		if_refresh(ifp); -      /* Some addresses (in particular, IPv6 addresses on Linux) get -       * removed when the interface goes down. They need to be readded. -       */ -      if_addr_wakeup(ifp); -    } +		/* Some addresses (in particular, IPv6 addresses on Linux) get +		 * removed when the interface goes down. They need to be +		 * readded. +		 */ +		if_addr_wakeup(ifp); +	} -  if_data = ifp->info; -  if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF; +	if_data = ifp->info; +	if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF; -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (bandwidth_if, @@ -1629,26 +1602,25 @@ DEFUN (bandwidth_if,         "Set bandwidth informational parameter\n"         "Bandwidth in megabits\n")  { -  int idx_number = 1; -  VTY_DECLVAR_CONTEXT (interface, ifp); -  unsigned int bandwidth; -   -  bandwidth = strtol(argv[idx_number]->arg, NULL, 10); +	int idx_number = 1; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	unsigned int bandwidth; + +	bandwidth = strtol(argv[idx_number]->arg, NULL, 10); + +	/* bandwidth range is <1-100000> */ +	if (bandwidth < 1 || bandwidth > 100000) { +		vty_out(vty, "Bandwidth is invalid%s", VTY_NEWLINE); +		return CMD_WARNING; +	} + +	ifp->bandwidth = bandwidth; -  /* bandwidth range is <1-100000> */ -  if (bandwidth < 1 || bandwidth > 100000) -    { -      vty_out (vty, "Bandwidth is invalid%s", VTY_NEWLINE); -      return CMD_WARNING; -    } -   -  ifp->bandwidth = bandwidth; +	/* force protocols to recalculate routes due to cost change */ +	if (if_is_operative(ifp)) +		zebra_interface_up_update(ifp); -  /* force protocols to recalculate routes due to cost change */ -  if (if_is_operative (ifp)) -    zebra_interface_up_update (ifp); -   -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (no_bandwidth_if, @@ -1658,69 +1630,63 @@ DEFUN (no_bandwidth_if,         "Set bandwidth informational parameter\n"         "Bandwidth in megabits\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); +	VTY_DECLVAR_CONTEXT(interface, ifp); -  ifp->bandwidth = 0; -   -  /* force protocols to recalculate routes due to cost change */ -  if (if_is_operative (ifp)) -    zebra_interface_up_update (ifp); +	ifp->bandwidth = 0; -  return CMD_SUCCESS; +	/* force protocols to recalculate routes due to cost change */ +	if (if_is_operative(ifp)) +		zebra_interface_up_update(ifp); + +	return CMD_SUCCESS;  } -struct cmd_node link_params_node = -{ -  LINK_PARAMS_NODE, -  "%s(config-link-params)# ", -  1, +struct cmd_node link_params_node = { +	LINK_PARAMS_NODE, "%s(config-link-params)# ", 1,  }; -static void -link_param_cmd_set_uint32 (struct interface *ifp, uint32_t *field, -                           uint32_t type, uint32_t value) +static void link_param_cmd_set_uint32(struct interface *ifp, uint32_t *field, +				      uint32_t type, uint32_t value)  { -  /* Update field as needed */ -  if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value) -    { -      *field = value; -      SET_PARAM(ifp->link_params, type); +	/* Update field as needed */ +	if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value) { +		*field = value; +		SET_PARAM(ifp->link_params, type); -      /* force protocols to update LINK STATE due to parameters change */ -      if (if_is_operative (ifp)) -        zebra_interface_parameters_update (ifp); -    } +		/* force protocols to update LINK STATE due to parameters change +		 */ +		if (if_is_operative(ifp)) +			zebra_interface_parameters_update(ifp); +	}  } -static void -link_param_cmd_set_float (struct interface *ifp, float *field, -                          uint32_t type, float value) +static void link_param_cmd_set_float(struct interface *ifp, float *field, +				     uint32_t type, float value)  { -  /* Update field as needed */ -  if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value) -    { -      *field = value; -      SET_PARAM(ifp->link_params, type); +	/* Update field as needed */ +	if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value) { +		*field = value; +		SET_PARAM(ifp->link_params, type); -      /* force protocols to update LINK STATE due to parameters change */ -      if (if_is_operative (ifp)) -        zebra_interface_parameters_update (ifp); -    } +		/* force protocols to update LINK STATE due to parameters change +		 */ +		if (if_is_operative(ifp)) +			zebra_interface_parameters_update(ifp); +	}  } -static void -link_param_cmd_unset (struct interface *ifp, uint32_t type) +static void link_param_cmd_unset(struct interface *ifp, uint32_t type)  { -  if (ifp->link_params == NULL) -    return; +	if (ifp->link_params == NULL) +		return; -  /* Unset field */ -  UNSET_PARAM(ifp->link_params, type); +	/* Unset field */ +	UNSET_PARAM(ifp->link_params, type); -  /* force protocols to update LINK STATE due to parameters change */ -  if (if_is_operative (ifp)) -    zebra_interface_parameters_update (ifp); +	/* force protocols to update LINK STATE due to parameters change */ +	if (if_is_operative(ifp)) +		zebra_interface_parameters_update(ifp);  }  DEFUN_NOSH (link_params, @@ -1728,10 +1694,10 @@ DEFUN_NOSH (link_params,         "link-params",         LINK_PARAMS_STR)  { -  /* vty->qobj_index stays the same @ interface pointer */ -  vty->node = LINK_PARAMS_NODE; +	/* vty->qobj_index stays the same @ interface pointer */ +	vty->node = LINK_PARAMS_NODE; -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN_NOSH (exit_link_params, @@ -1739,9 +1705,9 @@ DEFUN_NOSH (exit_link_params,         "exit-link-params",         "Exit from Link Params configuration mode\n")  { -  if (vty->node == LINK_PARAMS_NODE) -    vty->node = INTERFACE_NODE; -  return CMD_SUCCESS; +	if (vty->node == LINK_PARAMS_NODE) +		vty->node = INTERFACE_NODE; +	return CMD_SUCCESS;  }  /* Specific Traffic Engineering parameters commands */ @@ -1750,27 +1716,30 @@ DEFUN (link_params_enable,         "enable",         "Activate link parameters on this interface\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); +	VTY_DECLVAR_CONTEXT(interface, ifp); -  /* This command could be issue at startup, when activate MPLS TE */ -  /* on a new interface or after a ON / OFF / ON toggle */ -  /* In all case, TE parameters are reset to their default factory */ -  if (IS_ZEBRA_DEBUG_EVENT) -    zlog_debug ("Link-params: enable TE link parameters on interface %s", ifp->name); +	/* This command could be issue at startup, when activate MPLS TE */ +	/* on a new interface or after a ON / OFF / ON toggle */ +	/* In all case, TE parameters are reset to their default factory */ +	if (IS_ZEBRA_DEBUG_EVENT) +		zlog_debug( +			"Link-params: enable TE link parameters on interface %s", +			ifp->name); -  if (!if_link_params_get (ifp)) -    { -      if (IS_ZEBRA_DEBUG_EVENT) -        zlog_debug ("Link-params: failed to init TE link parameters  %s", ifp->name); +	if (!if_link_params_get(ifp)) { +		if (IS_ZEBRA_DEBUG_EVENT) +			zlog_debug( +				"Link-params: failed to init TE link parameters  %s", +				ifp->name); -      return CMD_WARNING; -    } +		return CMD_WARNING; +	} -  /* force protocols to update LINK STATE due to parameters change */ -  if (if_is_operative (ifp)) -    zebra_interface_parameters_update (ifp); +	/* force protocols to update LINK STATE due to parameters change */ +	if (if_is_operative(ifp)) +		zebra_interface_parameters_update(ifp); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (no_link_params_enable, @@ -1779,17 +1748,18 @@ DEFUN (no_link_params_enable,         NO_STR         "Disable link parameters on this interface\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); +	VTY_DECLVAR_CONTEXT(interface, ifp); -  zlog_debug ("MPLS-TE: disable TE link parameters on interface %s", ifp->name); +	zlog_debug("MPLS-TE: disable TE link parameters on interface %s", +		   ifp->name); -  if_link_params_free (ifp); +	if_link_params_free(ifp); -  /* force protocols to update LINK STATE due to parameters change */ -  if (if_is_operative (ifp)) -    zebra_interface_parameters_update (ifp); +	/* force protocols to update LINK STATE due to parameters change */ +	if (if_is_operative(ifp)) +		zebra_interface_parameters_update(ifp); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  /* STANDARD TE metrics */ @@ -1799,17 +1769,17 @@ DEFUN (link_params_metric,         "Link metric for MPLS-TE purpose\n"         "Metric value in decimal\n")  { -  int idx_number = 1; -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct if_link_params *iflp = if_link_params_get (ifp); -  u_int32_t metric; +	int idx_number = 1; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct if_link_params *iflp = if_link_params_get(ifp); +	u_int32_t metric; -  VTY_GET_ULONG("metric", metric, argv[idx_number]->arg); +	VTY_GET_ULONG("metric", metric, argv[idx_number]->arg); -  /* Update TE metric if needed */ -  link_param_cmd_set_uint32 (ifp, &iflp->te_metric, LP_TE_METRIC, metric); +	/* Update TE metric if needed */ +	link_param_cmd_set_uint32(ifp, &iflp->te_metric, LP_TE_METRIC, metric); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (no_link_params_metric, @@ -1818,12 +1788,12 @@ DEFUN (no_link_params_metric,         NO_STR         "Disable Link Metric on this interface\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); +	VTY_DECLVAR_CONTEXT(interface, ifp); -  /* Unset TE Metric */ -  link_param_cmd_unset(ifp, LP_TE_METRIC); +	/* Unset TE Metric */ +	link_param_cmd_unset(ifp, LP_TE_METRIC); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (link_params_maxbw, @@ -1832,43 +1802,36 @@ DEFUN (link_params_maxbw,         "Maximum bandwidth that can be used\n"         "Bytes/second (IEEE floating point format)\n")  { -  int idx_bandwidth = 1; -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct if_link_params *iflp = if_link_params_get (ifp); - -  float bw; - -  if (sscanf (argv[idx_bandwidth]->arg, "%g", &bw) != 1) -    { -      vty_out (vty, "link_params_maxbw: fscanf: %s%s", safe_strerror (errno), -               VTY_NEWLINE); -      return CMD_WARNING; -    } - -  /* Check that Maximum bandwidth is not lower than other bandwidth parameters */ -  if ((bw <= iflp->max_rsv_bw) -      || (bw <= iflp->unrsv_bw[0]) -      || (bw <= iflp->unrsv_bw[1]) -      || (bw <= iflp->unrsv_bw[2]) -      || (bw <= iflp->unrsv_bw[3]) -      || (bw <= iflp->unrsv_bw[4]) -      || (bw <= iflp->unrsv_bw[5]) -      || (bw <= iflp->unrsv_bw[6]) -      || (bw <= iflp->unrsv_bw[7]) -      || (bw <= iflp->ava_bw) -      || (bw <= iflp->res_bw) -      || (bw <= iflp->use_bw)) -    { -      vty_out (vty, -               "Maximum Bandwidth could not be lower than others bandwidth%s", -               VTY_NEWLINE); -      return CMD_WARNING; -    } - -  /* Update Maximum Bandwidth if needed */ -  link_param_cmd_set_float (ifp, &iflp->max_bw, LP_MAX_BW, bw); - -  return CMD_SUCCESS; +	int idx_bandwidth = 1; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct if_link_params *iflp = if_link_params_get(ifp); + +	float bw; + +	if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) { +		vty_out(vty, "link_params_maxbw: fscanf: %s%s", +			safe_strerror(errno), VTY_NEWLINE); +		return CMD_WARNING; +	} + +	/* Check that Maximum bandwidth is not lower than other bandwidth +	 * parameters */ +	if ((bw <= iflp->max_rsv_bw) || (bw <= iflp->unrsv_bw[0]) +	    || (bw <= iflp->unrsv_bw[1]) || (bw <= iflp->unrsv_bw[2]) +	    || (bw <= iflp->unrsv_bw[3]) || (bw <= iflp->unrsv_bw[4]) +	    || (bw <= iflp->unrsv_bw[5]) || (bw <= iflp->unrsv_bw[6]) +	    || (bw <= iflp->unrsv_bw[7]) || (bw <= iflp->ava_bw) +	    || (bw <= iflp->res_bw) || (bw <= iflp->use_bw)) { +		vty_out(vty, +			"Maximum Bandwidth could not be lower than others bandwidth%s", +			VTY_NEWLINE); +		return CMD_WARNING; +	} + +	/* Update Maximum Bandwidth if needed */ +	link_param_cmd_set_float(ifp, &iflp->max_bw, LP_MAX_BW, bw); + +	return CMD_SUCCESS;  }  DEFUN (link_params_max_rsv_bw, @@ -1877,31 +1840,30 @@ DEFUN (link_params_max_rsv_bw,         "Maximum bandwidth that may be reserved\n"         "Bytes/second (IEEE floating point format)\n")  { -  int idx_bandwidth = 1; -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct if_link_params *iflp = if_link_params_get (ifp); -  float bw; +	int idx_bandwidth = 1; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct if_link_params *iflp = if_link_params_get(ifp); +	float bw; -  if (sscanf (argv[idx_bandwidth]->arg, "%g", &bw) != 1) -    { -      vty_out (vty, "link_params_max_rsv_bw: fscanf: %s%s", safe_strerror (errno), -               VTY_NEWLINE); -      return CMD_WARNING; -    } +	if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) { +		vty_out(vty, "link_params_max_rsv_bw: fscanf: %s%s", +			safe_strerror(errno), VTY_NEWLINE); +		return CMD_WARNING; +	} -  /* Check that bandwidth is not greater than maximum bandwidth parameter */ -  if (bw > iflp->max_bw) -    { -      vty_out (vty, -               "Maximum Reservable Bandwidth could not be greater than Maximum Bandwidth (%g)%s", -               iflp->max_bw, VTY_NEWLINE); -      return CMD_WARNING; -    } +	/* Check that bandwidth is not greater than maximum bandwidth parameter +	 */ +	if (bw > iflp->max_bw) { +		vty_out(vty, +			"Maximum Reservable Bandwidth could not be greater than Maximum Bandwidth (%g)%s", +			iflp->max_bw, VTY_NEWLINE); +		return CMD_WARNING; +	} -  /* Update Maximum Reservable Bandwidth if needed */ -  link_param_cmd_set_float (ifp, &iflp->max_rsv_bw, LP_MAX_RSV_BW, bw); +	/* Update Maximum Reservable Bandwidth if needed */ +	link_param_cmd_set_float(ifp, &iflp->max_rsv_bw, LP_MAX_RSV_BW, bw); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (link_params_unrsv_bw, @@ -1911,41 +1873,40 @@ DEFUN (link_params_unrsv_bw,         "Priority\n"         "Bytes/second (IEEE floating point format)\n")  { -  int idx_number = 1; -  int idx_bandwidth = 2; -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct if_link_params *iflp = if_link_params_get (ifp); -  int priority; -  float bw; - -  /* We don't have to consider about range check here. */ -  if (sscanf (argv[idx_number]->arg, "%d", &priority) != 1) -    { -      vty_out (vty, "link_params_unrsv_bw: fscanf: %s%s", safe_strerror (errno), -               VTY_NEWLINE); -      return CMD_WARNING; -    } - -  if (sscanf (argv[idx_bandwidth]->arg, "%g", &bw) != 1) -    { -      vty_out (vty, "link_params_unrsv_bw: fscanf: %s%s", safe_strerror (errno), -               VTY_NEWLINE); -      return CMD_WARNING; -    } - -  /* Check that bandwidth is not greater than maximum bandwidth parameter */ -  if (bw > iflp->max_bw) -    { -      vty_out (vty, -               "UnReserved Bandwidth could not be greater than Maximum Bandwidth (%g)%s", -               iflp->max_bw, VTY_NEWLINE); -      return CMD_WARNING; -    } - -  /* Update Unreserved Bandwidth if needed */ -  link_param_cmd_set_float (ifp, &iflp->unrsv_bw[priority], LP_UNRSV_BW, bw); - -  return CMD_SUCCESS; +	int idx_number = 1; +	int idx_bandwidth = 2; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct if_link_params *iflp = if_link_params_get(ifp); +	int priority; +	float bw; + +	/* We don't have to consider about range check here. */ +	if (sscanf(argv[idx_number]->arg, "%d", &priority) != 1) { +		vty_out(vty, "link_params_unrsv_bw: fscanf: %s%s", +			safe_strerror(errno), VTY_NEWLINE); +		return CMD_WARNING; +	} + +	if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) { +		vty_out(vty, "link_params_unrsv_bw: fscanf: %s%s", +			safe_strerror(errno), VTY_NEWLINE); +		return CMD_WARNING; +	} + +	/* Check that bandwidth is not greater than maximum bandwidth parameter +	 */ +	if (bw > iflp->max_bw) { +		vty_out(vty, +			"UnReserved Bandwidth could not be greater than Maximum Bandwidth (%g)%s", +			iflp->max_bw, VTY_NEWLINE); +		return CMD_WARNING; +	} + +	/* Update Unreserved Bandwidth if needed */ +	link_param_cmd_set_float(ifp, &iflp->unrsv_bw[priority], LP_UNRSV_BW, +				 bw); + +	return CMD_SUCCESS;  }  DEFUN (link_params_admin_grp, @@ -1954,22 +1915,21 @@ DEFUN (link_params_admin_grp,         "Administrative group membership\n"         "32-bit Hexadecimal value (e.g. 0xa1)\n")  { -  int idx_bitpattern = 1; -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct if_link_params *iflp = if_link_params_get (ifp); -  unsigned long value; +	int idx_bitpattern = 1; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct if_link_params *iflp = if_link_params_get(ifp); +	unsigned long value; -  if (sscanf (argv[idx_bitpattern]->arg, "0x%lx", &value) != 1) -    { -      vty_out (vty, "link_params_admin_grp: fscanf: %s%s", -               safe_strerror (errno), VTY_NEWLINE); -      return CMD_WARNING; -    } +	if (sscanf(argv[idx_bitpattern]->arg, "0x%lx", &value) != 1) { +		vty_out(vty, "link_params_admin_grp: fscanf: %s%s", +			safe_strerror(errno), VTY_NEWLINE); +		return CMD_WARNING; +	} -  /* Update Administrative Group if needed */ -  link_param_cmd_set_uint32 (ifp, &iflp->admin_grp, LP_ADM_GRP, value); +	/* Update Administrative Group if needed */ +	link_param_cmd_set_uint32(ifp, &iflp->admin_grp, LP_ADM_GRP, value); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (no_link_params_admin_grp, @@ -1978,12 +1938,12 @@ DEFUN (no_link_params_admin_grp,         NO_STR         "Disable Administrative group membership on this interface\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); +	VTY_DECLVAR_CONTEXT(interface, ifp); -  /* Unset Admin Group */ -  link_param_cmd_unset(ifp, LP_ADM_GRP); +	/* Unset Admin Group */ +	link_param_cmd_unset(ifp, LP_ADM_GRP); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  /* RFC5392 & RFC5316: INTER-AS */ @@ -1995,37 +1955,36 @@ DEFUN (link_params_inter_as,         "Remote AS number\n"         "AS number in the range <1-4294967295>\n")  { -  int idx_ipv4 = 1; -  int idx_number = 3; +	int idx_ipv4 = 1; +	int idx_number = 3; -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct if_link_params *iflp = if_link_params_get (ifp); -  struct in_addr addr; -  u_int32_t as; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct if_link_params *iflp = if_link_params_get(ifp); +	struct in_addr addr; +	u_int32_t as; -  if (!inet_aton (argv[idx_ipv4]->arg, &addr)) -    { -      vty_out (vty, "Please specify Router-Addr by A.B.C.D%s", VTY_NEWLINE); -      return CMD_WARNING; -    } +	if (!inet_aton(argv[idx_ipv4]->arg, &addr)) { +		vty_out(vty, "Please specify Router-Addr by A.B.C.D%s", +			VTY_NEWLINE); +		return CMD_WARNING; +	} -  VTY_GET_ULONG("AS number", as, argv[idx_number]->arg); +	VTY_GET_ULONG("AS number", as, argv[idx_number]->arg); -  /* Update Remote IP and Remote AS fields if needed */ -  if (IS_PARAM_UNSET(iflp, LP_RMT_AS) -      || iflp->rmt_as != as -      || iflp->rmt_ip.s_addr != addr.s_addr) -    { +	/* Update Remote IP and Remote AS fields if needed */ +	if (IS_PARAM_UNSET(iflp, LP_RMT_AS) || iflp->rmt_as != as +	    || iflp->rmt_ip.s_addr != addr.s_addr) { -      iflp->rmt_as = as; -      iflp->rmt_ip.s_addr = addr.s_addr; -      SET_PARAM(iflp, LP_RMT_AS); +		iflp->rmt_as = as; +		iflp->rmt_ip.s_addr = addr.s_addr; +		SET_PARAM(iflp, LP_RMT_AS); -      /* force protocols to update LINK STATE due to parameters change */ -      if (if_is_operative (ifp)) -        zebra_interface_parameters_update (ifp); -    } -  return CMD_SUCCESS; +		/* force protocols to update LINK STATE due to parameters change +		 */ +		if (if_is_operative(ifp)) +			zebra_interface_parameters_update(ifp); +	} +	return CMD_SUCCESS;  }  DEFUN (no_link_params_inter_as, @@ -2034,22 +1993,23 @@ DEFUN (no_link_params_inter_as,         NO_STR         "Remove Neighbor IP address and AS number for Inter-AS TE\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct if_link_params *iflp = if_link_params_get (ifp); +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct if_link_params *iflp = if_link_params_get(ifp); -  /* Reset Remote IP and AS neighbor */ -  iflp->rmt_as = 0; -  iflp->rmt_ip.s_addr = 0; -  UNSET_PARAM(iflp, LP_RMT_AS); +	/* Reset Remote IP and AS neighbor */ +	iflp->rmt_as = 0; +	iflp->rmt_ip.s_addr = 0; +	UNSET_PARAM(iflp, LP_RMT_AS); -  /* force protocols to update LINK STATE due to parameters change */ -  if (if_is_operative (ifp)) -    zebra_interface_parameters_update (ifp); +	/* force protocols to update LINK STATE due to parameters change */ +	if (if_is_operative(ifp)) +		zebra_interface_parameters_update(ifp); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  } -/* RFC7471: OSPF Traffic Engineering (TE) Metric extensions & draft-ietf-isis-metric-extensions-07.txt */ +/* RFC7471: OSPF Traffic Engineering (TE) Metric extensions & + * draft-ietf-isis-metric-extensions-07.txt */  DEFUN (link_params_delay,         link_params_delay_cmd,         "delay (0-16777215) [min (0-16777215) max (0-16777215)]", @@ -2060,75 +2020,68 @@ DEFUN (link_params_delay,         "Maximum delay\n"         "Maximum delay in micro-second as decimal (0...16777215)\n")  { -  /* Get and Check new delay values */ -  u_int32_t delay = 0, low = 0, high = 0; -  VTY_GET_ULONG("delay", delay, argv[1]->arg); -  if (argc == 6) -  { -    VTY_GET_ULONG("minimum delay", low, argv[3]->arg); -    VTY_GET_ULONG("maximum delay", high, argv[5]->arg); -  } - -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct if_link_params *iflp = if_link_params_get (ifp); -  u_int8_t update = 0; - -  if (argc == 2) -  { -    /* Check new delay value against old Min and Max delays if set */ -    if (IS_PARAM_SET(iflp, LP_MM_DELAY) -        && (delay <= iflp->min_delay || delay >= iflp->max_delay)) -      { -        vty_out (vty, "Average delay should be comprise between Min (%d) and Max (%d) delay%s", -                 iflp->min_delay, iflp->max_delay, VTY_NEWLINE); -        return CMD_WARNING; -      } -    /* Update delay if value is not set or change */ -    if (IS_PARAM_UNSET(iflp, LP_DELAY)|| iflp->av_delay != delay) -      { -        iflp->av_delay = delay; -        SET_PARAM(iflp, LP_DELAY); -        update = 1; -      } -    /* Unset Min and Max delays if already set */ -    if (IS_PARAM_SET(iflp, LP_MM_DELAY)) -      { -        iflp->min_delay = 0; -        iflp->max_delay = 0; -        UNSET_PARAM(iflp, LP_MM_DELAY); -        update = 1; -      } -  } -  else -  { -    /* Check new delays value coherency */ -    if (delay <= low || delay >= high) -      { -        vty_out (vty, "Average delay should be comprise between Min (%d) and Max (%d) delay%s", -                 low, high, VTY_NEWLINE); -        return CMD_WARNING; -      } -    /* Update Delays if needed */ -    if (IS_PARAM_UNSET(iflp, LP_DELAY) -        || IS_PARAM_UNSET(iflp, LP_MM_DELAY) -        || iflp->av_delay != delay -        || iflp->min_delay != low -        || iflp->max_delay != high) -      { -        iflp->av_delay = delay; -        SET_PARAM(iflp, LP_DELAY); -        iflp->min_delay = low; -        iflp->max_delay = high; -        SET_PARAM(iflp, LP_MM_DELAY); -        update = 1; -      } -  } - -  /* force protocols to update LINK STATE due to parameters change */ -  if (update == 1 && if_is_operative (ifp)) -    zebra_interface_parameters_update (ifp); - -  return CMD_SUCCESS; +	/* Get and Check new delay values */ +	u_int32_t delay = 0, low = 0, high = 0; +	VTY_GET_ULONG("delay", delay, argv[1]->arg); +	if (argc == 6) { +		VTY_GET_ULONG("minimum delay", low, argv[3]->arg); +		VTY_GET_ULONG("maximum delay", high, argv[5]->arg); +	} + +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct if_link_params *iflp = if_link_params_get(ifp); +	u_int8_t update = 0; + +	if (argc == 2) { +		/* Check new delay value against old Min and Max delays if set +		 */ +		if (IS_PARAM_SET(iflp, LP_MM_DELAY) +		    && (delay <= iflp->min_delay || delay >= iflp->max_delay)) { +			vty_out(vty, +				"Average delay should be comprise between Min (%d) and Max (%d) delay%s", +				iflp->min_delay, iflp->max_delay, VTY_NEWLINE); +			return CMD_WARNING; +		} +		/* Update delay if value is not set or change */ +		if (IS_PARAM_UNSET(iflp, LP_DELAY) || iflp->av_delay != delay) { +			iflp->av_delay = delay; +			SET_PARAM(iflp, LP_DELAY); +			update = 1; +		} +		/* Unset Min and Max delays if already set */ +		if (IS_PARAM_SET(iflp, LP_MM_DELAY)) { +			iflp->min_delay = 0; +			iflp->max_delay = 0; +			UNSET_PARAM(iflp, LP_MM_DELAY); +			update = 1; +		} +	} else { +		/* Check new delays value coherency */ +		if (delay <= low || delay >= high) { +			vty_out(vty, +				"Average delay should be comprise between Min (%d) and Max (%d) delay%s", +				low, high, VTY_NEWLINE); +			return CMD_WARNING; +		} +		/* Update Delays if needed */ +		if (IS_PARAM_UNSET(iflp, LP_DELAY) +		    || IS_PARAM_UNSET(iflp, LP_MM_DELAY) +		    || iflp->av_delay != delay || iflp->min_delay != low +		    || iflp->max_delay != high) { +			iflp->av_delay = delay; +			SET_PARAM(iflp, LP_DELAY); +			iflp->min_delay = low; +			iflp->max_delay = high; +			SET_PARAM(iflp, LP_MM_DELAY); +			update = 1; +		} +	} + +	/* force protocols to update LINK STATE due to parameters change */ +	if (update == 1 && if_is_operative(ifp)) +		zebra_interface_parameters_update(ifp); + +	return CMD_SUCCESS;  }  DEFUN (no_link_params_delay, @@ -2137,21 +2090,21 @@ DEFUN (no_link_params_delay,         NO_STR         "Disable Unidirectional Average, Min & Max Link Delay on this interface\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct if_link_params *iflp = if_link_params_get (ifp); +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct if_link_params *iflp = if_link_params_get(ifp); -  /* Unset Delays */ -  iflp->av_delay = 0; -  UNSET_PARAM(iflp, LP_DELAY); -  iflp->min_delay = 0; -  iflp->max_delay = 0; -  UNSET_PARAM(iflp, LP_MM_DELAY); +	/* Unset Delays */ +	iflp->av_delay = 0; +	UNSET_PARAM(iflp, LP_DELAY); +	iflp->min_delay = 0; +	iflp->max_delay = 0; +	UNSET_PARAM(iflp, LP_MM_DELAY); -  /* force protocols to update LINK STATE due to parameters change */ -  if (if_is_operative (ifp)) -    zebra_interface_parameters_update (ifp); +	/* force protocols to update LINK STATE due to parameters change */ +	if (if_is_operative(ifp)) +		zebra_interface_parameters_update(ifp); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (link_params_delay_var, @@ -2160,17 +2113,17 @@ DEFUN (link_params_delay_var,         "Unidirectional Link Delay Variation\n"         "delay variation in micro-second as decimal (0...16777215)\n")  { -  int idx_number = 1; -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct if_link_params *iflp = if_link_params_get (ifp); -  u_int32_t value; +	int idx_number = 1; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct if_link_params *iflp = if_link_params_get(ifp); +	u_int32_t value; -  VTY_GET_ULONG("delay variation", value, argv[idx_number]->arg); +	VTY_GET_ULONG("delay variation", value, argv[idx_number]->arg); -  /* Update Delay Variation if needed */ -  link_param_cmd_set_uint32 (ifp, &iflp->delay_var, LP_DELAY_VAR, value); +	/* Update Delay Variation if needed */ +	link_param_cmd_set_uint32(ifp, &iflp->delay_var, LP_DELAY_VAR, value); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (no_link_params_delay_var, @@ -2179,12 +2132,12 @@ DEFUN (no_link_params_delay_var,         NO_STR         "Disable Unidirectional Delay Variation on this interface\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); +	VTY_DECLVAR_CONTEXT(interface, ifp); -  /* Unset Delay Variation */ -  link_param_cmd_unset(ifp, LP_DELAY_VAR); +	/* Unset Delay Variation */ +	link_param_cmd_unset(ifp, LP_DELAY_VAR); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (link_params_pkt_loss, @@ -2193,25 +2146,24 @@ DEFUN (link_params_pkt_loss,         "Unidirectional Link Packet Loss\n"         "percentage of total traffic by 0.000003% step and less than 50.331642%\n")  { -  int idx_percentage = 1; -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct if_link_params *iflp = if_link_params_get (ifp); -  float fval; +	int idx_percentage = 1; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct if_link_params *iflp = if_link_params_get(ifp); +	float fval; -  if (sscanf (argv[idx_percentage]->arg, "%g", &fval) != 1) -    { -      vty_out (vty, "link_params_pkt_loss: fscanf: %s%s", safe_strerror (errno), -               VTY_NEWLINE); -      return CMD_WARNING; -    } +	if (sscanf(argv[idx_percentage]->arg, "%g", &fval) != 1) { +		vty_out(vty, "link_params_pkt_loss: fscanf: %s%s", +			safe_strerror(errno), VTY_NEWLINE); +		return CMD_WARNING; +	} -  if (fval > MAX_PKT_LOSS) -    fval = MAX_PKT_LOSS; +	if (fval > MAX_PKT_LOSS) +		fval = MAX_PKT_LOSS; -  /* Update Packet Loss if needed */ -  link_param_cmd_set_float (ifp, &iflp->pkt_loss, LP_PKT_LOSS, fval); +	/* Update Packet Loss if needed */ +	link_param_cmd_set_float(ifp, &iflp->pkt_loss, LP_PKT_LOSS, fval); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (no_link_params_pkt_loss, @@ -2220,12 +2172,12 @@ DEFUN (no_link_params_pkt_loss,         NO_STR         "Disable Unidirectional Link Packet Loss on this interface\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); +	VTY_DECLVAR_CONTEXT(interface, ifp); -  /* Unset Packet Loss */ -  link_param_cmd_unset(ifp, LP_PKT_LOSS); +	/* Unset Packet Loss */ +	link_param_cmd_unset(ifp, LP_PKT_LOSS); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (link_params_res_bw, @@ -2234,31 +2186,30 @@ DEFUN (link_params_res_bw,         "Unidirectional Residual Bandwidth\n"         "Bytes/second (IEEE floating point format)\n")  { -  int idx_bandwidth = 1; -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct if_link_params *iflp = if_link_params_get (ifp); -  float bw; +	int idx_bandwidth = 1; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct if_link_params *iflp = if_link_params_get(ifp); +	float bw; -  if (sscanf (argv[idx_bandwidth]->arg, "%g", &bw) != 1) -    { -      vty_out (vty, "link_params_res_bw: fscanf: %s%s", safe_strerror (errno), -               VTY_NEWLINE); -      return CMD_WARNING; -    } +	if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) { +		vty_out(vty, "link_params_res_bw: fscanf: %s%s", +			safe_strerror(errno), VTY_NEWLINE); +		return CMD_WARNING; +	} -  /* Check that bandwidth is not greater than maximum bandwidth parameter */ -  if (bw > iflp->max_bw) -    { -      vty_out (vty, -               "Residual Bandwidth could not be greater than Maximum Bandwidth (%g)%s", -               iflp->max_bw, VTY_NEWLINE); -      return CMD_WARNING; -    } +	/* Check that bandwidth is not greater than maximum bandwidth parameter +	 */ +	if (bw > iflp->max_bw) { +		vty_out(vty, +			"Residual Bandwidth could not be greater than Maximum Bandwidth (%g)%s", +			iflp->max_bw, VTY_NEWLINE); +		return CMD_WARNING; +	} -  /* Update Residual Bandwidth if needed */ -  link_param_cmd_set_float (ifp, &iflp->res_bw, LP_RES_BW, bw); +	/* Update Residual Bandwidth if needed */ +	link_param_cmd_set_float(ifp, &iflp->res_bw, LP_RES_BW, bw); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (no_link_params_res_bw, @@ -2267,12 +2218,12 @@ DEFUN (no_link_params_res_bw,         NO_STR         "Disable Unidirectional Residual Bandwidth on this interface\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); +	VTY_DECLVAR_CONTEXT(interface, ifp); -  /* Unset Residual Bandwidth */ -  link_param_cmd_unset(ifp, LP_RES_BW); +	/* Unset Residual Bandwidth */ +	link_param_cmd_unset(ifp, LP_RES_BW); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (link_params_ava_bw, @@ -2281,31 +2232,30 @@ DEFUN (link_params_ava_bw,         "Unidirectional Available Bandwidth\n"         "Bytes/second (IEEE floating point format)\n")  { -  int idx_bandwidth = 1; -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct if_link_params *iflp = if_link_params_get (ifp); -  float bw; +	int idx_bandwidth = 1; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct if_link_params *iflp = if_link_params_get(ifp); +	float bw; -  if (sscanf (argv[idx_bandwidth]->arg, "%g", &bw) != 1) -    { -      vty_out (vty, "link_params_ava_bw: fscanf: %s%s", safe_strerror (errno), -               VTY_NEWLINE); -      return CMD_WARNING; -    } +	if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) { +		vty_out(vty, "link_params_ava_bw: fscanf: %s%s", +			safe_strerror(errno), VTY_NEWLINE); +		return CMD_WARNING; +	} -  /* Check that bandwidth is not greater than maximum bandwidth parameter */ -  if (bw > iflp->max_bw) -    { -      vty_out (vty, -               "Available Bandwidth could not be greater than Maximum Bandwidth (%g)%s", -               iflp->max_bw, VTY_NEWLINE); -      return CMD_WARNING; -    } +	/* Check that bandwidth is not greater than maximum bandwidth parameter +	 */ +	if (bw > iflp->max_bw) { +		vty_out(vty, +			"Available Bandwidth could not be greater than Maximum Bandwidth (%g)%s", +			iflp->max_bw, VTY_NEWLINE); +		return CMD_WARNING; +	} -  /* Update Residual Bandwidth if needed */ -  link_param_cmd_set_float (ifp, &iflp->ava_bw, LP_AVA_BW, bw); +	/* Update Residual Bandwidth if needed */ +	link_param_cmd_set_float(ifp, &iflp->ava_bw, LP_AVA_BW, bw); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (no_link_params_ava_bw, @@ -2314,12 +2264,12 @@ DEFUN (no_link_params_ava_bw,         NO_STR         "Disable Unidirectional Available Bandwidth on this interface\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); +	VTY_DECLVAR_CONTEXT(interface, ifp); -  /* Unset Available Bandwidth */ -  link_param_cmd_unset(ifp, LP_AVA_BW); +	/* Unset Available Bandwidth */ +	link_param_cmd_unset(ifp, LP_AVA_BW); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (link_params_use_bw, @@ -2328,31 +2278,30 @@ DEFUN (link_params_use_bw,         "Unidirectional Utilised Bandwidth\n"         "Bytes/second (IEEE floating point format)\n")  { -  int idx_bandwidth = 1; -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct if_link_params *iflp = if_link_params_get (ifp); -  float bw; +	int idx_bandwidth = 1; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct if_link_params *iflp = if_link_params_get(ifp); +	float bw; -  if (sscanf (argv[idx_bandwidth]->arg, "%g", &bw) != 1) -    { -      vty_out (vty, "link_params_use_bw: fscanf: %s%s", safe_strerror (errno), -               VTY_NEWLINE); -      return CMD_WARNING; -    } +	if (sscanf(argv[idx_bandwidth]->arg, "%g", &bw) != 1) { +		vty_out(vty, "link_params_use_bw: fscanf: %s%s", +			safe_strerror(errno), VTY_NEWLINE); +		return CMD_WARNING; +	} -  /* Check that bandwidth is not greater than maximum bandwidth parameter */ -  if (bw > iflp->max_bw) -    { -      vty_out (vty, -               "Utilised Bandwidth could not be greater than Maximum Bandwidth (%g)%s", -               iflp->max_bw, VTY_NEWLINE); -      return CMD_WARNING; -    } +	/* Check that bandwidth is not greater than maximum bandwidth parameter +	 */ +	if (bw > iflp->max_bw) { +		vty_out(vty, +			"Utilised Bandwidth could not be greater than Maximum Bandwidth (%g)%s", +			iflp->max_bw, VTY_NEWLINE); +		return CMD_WARNING; +	} -  /* Update Utilized Bandwidth if needed */ -  link_param_cmd_set_float (ifp, &iflp->use_bw, LP_USE_BW, bw); +	/* Update Utilized Bandwidth if needed */ +	link_param_cmd_set_float(ifp, &iflp->use_bw, LP_USE_BW, bw); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (no_link_params_use_bw, @@ -2361,153 +2310,142 @@ DEFUN (no_link_params_use_bw,         NO_STR         "Disable Unidirectional Utilised Bandwidth on this interface\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); +	VTY_DECLVAR_CONTEXT(interface, ifp); -  /* Unset Utilised Bandwidth */ -  link_param_cmd_unset(ifp, LP_USE_BW); +	/* Unset Utilised Bandwidth */ +	link_param_cmd_unset(ifp, LP_USE_BW); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  } -static int -ip_address_install (struct vty *vty, struct interface *ifp, -		    const char *addr_str, const char *peer_str, -		    const char *label) +static int ip_address_install(struct vty *vty, struct interface *ifp, +			      const char *addr_str, const char *peer_str, +			      const char *label)  { -  struct zebra_if *if_data; -  struct prefix_ipv4 cp; -  struct connected *ifc; -  struct prefix_ipv4 *p; -  int ret; +	struct zebra_if *if_data; +	struct prefix_ipv4 cp; +	struct connected *ifc; +	struct prefix_ipv4 *p; +	int ret; -  if_data = ifp->info; +	if_data = ifp->info; -  ret = str2prefix_ipv4 (addr_str, &cp); -  if (ret <= 0) -    { -      vty_out (vty, "%% Malformed address %s", VTY_NEWLINE); -      return CMD_WARNING; -    } +	ret = str2prefix_ipv4(addr_str, &cp); +	if (ret <= 0) { +		vty_out(vty, "%% Malformed address %s", VTY_NEWLINE); +		return CMD_WARNING; +	} -  if (ipv4_martian(&cp.prefix)) -    { -      vty_out (vty, "%% Invalid address%s", VTY_NEWLINE); -      return CMD_WARNING; -    } +	if (ipv4_martian(&cp.prefix)) { +		vty_out(vty, "%% Invalid address%s", VTY_NEWLINE); +		return CMD_WARNING; +	} -  ifc = connected_check (ifp, (struct prefix *) &cp); -  if (! ifc) -    { -      ifc = connected_new (); -      ifc->ifp = ifp; +	ifc = connected_check(ifp, (struct prefix *)&cp); +	if (!ifc) { +		ifc = connected_new(); +		ifc->ifp = ifp; + +		/* Address. */ +		p = prefix_ipv4_new(); +		*p = cp; +		ifc->address = (struct prefix *)p; + +		/* Broadcast. */ +		if (p->prefixlen <= IPV4_MAX_PREFIXLEN - 2) { +			p = prefix_ipv4_new(); +			*p = cp; +			p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr, +							       p->prefixlen); +			ifc->destination = (struct prefix *)p; +		} -      /* Address. */ -      p = prefix_ipv4_new (); -      *p = cp; -      ifc->address = (struct prefix *) p; +		/* Label. */ +		if (label) +			ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label); -      /* Broadcast. */ -      if (p->prefixlen <= IPV4_MAX_PREFIXLEN-2) -	{ -	  p = prefix_ipv4_new (); -	  *p = cp; -	  p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr,p->prefixlen); -	  ifc->destination = (struct prefix *) p; -	} - -      /* Label. */ -      if (label) -	ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label); - -      /* Add to linked list. */ -      listnode_add (ifp->connected, ifc); -    } - -  /* This address is configured from zebra. */ -  if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)) -    SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED); - -  /* In case of this route need to install kernel. */ -  if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED) -      && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE) -      && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)) -    { -      /* Some system need to up the interface to set IP address. */ -      if (! if_is_up (ifp)) -	{ -	  if_set_flags (ifp, IFF_UP | IFF_RUNNING); -	  if_refresh (ifp); +		/* Add to linked list. */ +		listnode_add(ifp->connected, ifc);  	} -      ret = if_set_prefix (ifp, ifc); -      if (ret < 0) -	{ -	  vty_out (vty, "%% Can't set interface IP address: %s.%s",  -		   safe_strerror(errno), VTY_NEWLINE); -	  return CMD_WARNING; -	} - -      SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED); -      /* The address will be advertised to zebra clients when the notification -       * from the kernel has been received. -       * It will also be added to the subnet chain list, then. */ -    } - -  return CMD_SUCCESS; -} - -static int -ip_address_uninstall (struct vty *vty, struct interface *ifp, -		      const char *addr_str, const char *peer_str, -		      const char *label) -{ -  struct prefix_ipv4 cp; -  struct connected *ifc; -  int ret; - -  /* Convert to prefix structure. */ -  ret = str2prefix_ipv4 (addr_str, &cp); -  if (ret <= 0) -    { -      vty_out (vty, "%% Malformed address %s", VTY_NEWLINE); -      return CMD_WARNING; -    } - -  /* Check current interface address. */ -  ifc = connected_check (ifp, (struct prefix *) &cp); -  if (! ifc) -    { -      vty_out (vty, "%% Can't find address%s", VTY_NEWLINE); -      return CMD_WARNING; -    } - -  /* This is not configured address. */ -  if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)) -    return CMD_WARNING; - -  UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED); -   -  /* This is not real address or interface is not active. */ -  if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED) -      || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)) -    { -      listnode_delete (ifp->connected, ifc); -      connected_free (ifc); -      return CMD_WARNING; -    } - -  /* This is real route. */ -  ret = if_unset_prefix (ifp, ifc); -  if (ret < 0) -    { -      vty_out (vty, "%% Can't unset interface IP address: %s.%s",  -	       safe_strerror(errno), VTY_NEWLINE); -      return CMD_WARNING; -    } -  UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED); -  /* we will receive a kernel notification about this route being removed. -   * this will trigger its removal from the connected list. */ -  return CMD_SUCCESS; +	/* This address is configured from zebra. */ +	if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED)) +		SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED); + +	/* In case of this route need to install kernel. */ +	if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED) +	    && CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE) +	    && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)) { +		/* Some system need to up the interface to set IP address. */ +		if (!if_is_up(ifp)) { +			if_set_flags(ifp, IFF_UP | IFF_RUNNING); +			if_refresh(ifp); +		} + +		ret = if_set_prefix(ifp, ifc); +		if (ret < 0) { +			vty_out(vty, "%% Can't set interface IP address: %s.%s", +				safe_strerror(errno), VTY_NEWLINE); +			return CMD_WARNING; +		} + +		SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED); +		/* The address will be advertised to zebra clients when the +		 * notification +		 * from the kernel has been received. +		 * It will also be added to the subnet chain list, then. */ +	} + +	return CMD_SUCCESS; +} + +static int ip_address_uninstall(struct vty *vty, struct interface *ifp, +				const char *addr_str, const char *peer_str, +				const char *label) +{ +	struct prefix_ipv4 cp; +	struct connected *ifc; +	int ret; + +	/* Convert to prefix structure. */ +	ret = str2prefix_ipv4(addr_str, &cp); +	if (ret <= 0) { +		vty_out(vty, "%% Malformed address %s", VTY_NEWLINE); +		return CMD_WARNING; +	} + +	/* Check current interface address. */ +	ifc = connected_check(ifp, (struct prefix *)&cp); +	if (!ifc) { +		vty_out(vty, "%% Can't find address%s", VTY_NEWLINE); +		return CMD_WARNING; +	} + +	/* This is not configured address. */ +	if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED)) +		return CMD_WARNING; + +	UNSET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED); + +	/* This is not real address or interface is not active. */ +	if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED) +	    || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) { +		listnode_delete(ifp->connected, ifc); +		connected_free(ifc); +		return CMD_WARNING; +	} + +	/* This is real route. */ +	ret = if_unset_prefix(ifp, ifc); +	if (ret < 0) { +		vty_out(vty, "%% Can't unset interface IP address: %s.%s", +			safe_strerror(errno), VTY_NEWLINE); +		return CMD_WARNING; +	} +	UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED); +	/* we will receive a kernel notification about this route being removed. +	 * this will trigger its removal from the connected list. */ +	return CMD_SUCCESS;  }  DEFUN (ip_address, @@ -2517,9 +2455,10 @@ DEFUN (ip_address,         "Set the IP address of an interface\n"         "IP address (e.g. 10.0.0.1/8)\n")  { -  int idx_ipv4_prefixlen = 2; -  VTY_DECLVAR_CONTEXT (interface, ifp); -  return ip_address_install (vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL, NULL); +	int idx_ipv4_prefixlen = 2; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	return ip_address_install(vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL, +				  NULL);  }  DEFUN (no_ip_address, @@ -2530,9 +2469,10 @@ DEFUN (no_ip_address,         "Set the IP address of an interface\n"         "IP Address (e.g. 10.0.0.1/8)")  { -  int idx_ipv4_prefixlen = 3; -  VTY_DECLVAR_CONTEXT (interface, ifp); -  return ip_address_uninstall (vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL, NULL); +	int idx_ipv4_prefixlen = 3; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	return ip_address_uninstall(vty, ifp, argv[idx_ipv4_prefixlen]->arg, +				    NULL, NULL);  } @@ -2546,10 +2486,11 @@ DEFUN (ip_address_label,         "Label of this address\n"         "Label\n")  { -  int idx_ipv4_prefixlen = 2; -  int idx_line = 4; -  VTY_DECLVAR_CONTEXT (interface, ifp); -  return ip_address_install (vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL, argv[idx_line]->arg); +	int idx_ipv4_prefixlen = 2; +	int idx_line = 4; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	return ip_address_install(vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL, +				  argv[idx_line]->arg);  }  DEFUN (no_ip_address_label, @@ -2562,162 +2503,152 @@ DEFUN (no_ip_address_label,         "Label of this address\n"         "Label\n")  { -  int idx_ipv4_prefixlen = 3; -  int idx_line = 5; -  VTY_DECLVAR_CONTEXT (interface, ifp); -  return ip_address_uninstall (vty, ifp, argv[idx_ipv4_prefixlen]->arg, NULL, argv[idx_line]->arg); +	int idx_ipv4_prefixlen = 3; +	int idx_line = 5; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	return ip_address_uninstall(vty, ifp, argv[idx_ipv4_prefixlen]->arg, +				    NULL, argv[idx_line]->arg);  }  #endif /* HAVE_NETLINK */ -static int -ipv6_address_install (struct vty *vty, struct interface *ifp, -		      const char *addr_str, const char *peer_str, -		      const char *label, int secondary) -{ -  struct zebra_if *if_data; -  struct prefix_ipv6 cp; -  struct connected *ifc; -  struct prefix_ipv6 *p; -  int ret; - -  if_data = ifp->info; - -  ret = str2prefix_ipv6 (addr_str, &cp); -  if (ret <= 0) -    { -      vty_out (vty, "%% Malformed address %s", VTY_NEWLINE); -      return CMD_WARNING; -    } - -  if (ipv6_martian(&cp.prefix)) -    { -      vty_out (vty, "%% Invalid address%s", VTY_NEWLINE); -      return CMD_WARNING; -    } - -  ifc = connected_check (ifp, (struct prefix *) &cp); -  if (! ifc) -    { -      ifc = connected_new (); -      ifc->ifp = ifp; - -      /* Address. */ -      p = prefix_ipv6_new (); -      *p = cp; -      ifc->address = (struct prefix *) p; - -      /* Secondary. */ -      if (secondary) -	SET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY); - -      /* Label. */ -      if (label) -	ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label); - -      /* Add to linked list. */ -      listnode_add (ifp->connected, ifc); -    } - -  /* This address is configured from zebra. */ -  if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)) -    SET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED); - -  /* In case of this route need to install kernel. */ -  if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED) -      && CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE) -      && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)) -    { -      /* Some system need to up the interface to set IP address. */ -      if (! if_is_up (ifp)) -	{ -	  if_set_flags (ifp, IFF_UP | IFF_RUNNING); -	  if_refresh (ifp); +static int ipv6_address_install(struct vty *vty, struct interface *ifp, +				const char *addr_str, const char *peer_str, +				const char *label, int secondary) +{ +	struct zebra_if *if_data; +	struct prefix_ipv6 cp; +	struct connected *ifc; +	struct prefix_ipv6 *p; +	int ret; + +	if_data = ifp->info; + +	ret = str2prefix_ipv6(addr_str, &cp); +	if (ret <= 0) { +		vty_out(vty, "%% Malformed address %s", VTY_NEWLINE); +		return CMD_WARNING; +	} + +	if (ipv6_martian(&cp.prefix)) { +		vty_out(vty, "%% Invalid address%s", VTY_NEWLINE); +		return CMD_WARNING;  	} -      ret = if_prefix_add_ipv6 (ifp, ifc); +	ifc = connected_check(ifp, (struct prefix *)&cp); +	if (!ifc) { +		ifc = connected_new(); +		ifc->ifp = ifp; -      if (ret < 0) -	{ -	  vty_out (vty, "%% Can't set interface IP address: %s.%s",  -		   safe_strerror(errno), VTY_NEWLINE); -	  return CMD_WARNING; +		/* Address. */ +		p = prefix_ipv6_new(); +		*p = cp; +		ifc->address = (struct prefix *)p; + +		/* Secondary. */ +		if (secondary) +			SET_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY); + +		/* Label. */ +		if (label) +			ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label); + +		/* Add to linked list. */ +		listnode_add(ifp->connected, ifc);  	} -      SET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED); -      /* The address will be advertised to zebra clients when the notification -       * from the kernel has been received. */ -    } +	/* This address is configured from zebra. */ +	if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED)) +		SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED); + +	/* In case of this route need to install kernel. */ +	if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED) +	    && CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE) +	    && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)) { +		/* Some system need to up the interface to set IP address. */ +		if (!if_is_up(ifp)) { +			if_set_flags(ifp, IFF_UP | IFF_RUNNING); +			if_refresh(ifp); +		} -  return CMD_SUCCESS; +		ret = if_prefix_add_ipv6(ifp, ifc); + +		if (ret < 0) { +			vty_out(vty, "%% Can't set interface IP address: %s.%s", +				safe_strerror(errno), VTY_NEWLINE); +			return CMD_WARNING; +		} + +		SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED); +		/* The address will be advertised to zebra clients when the +		 * notification +		 * from the kernel has been received. */ +	} + +	return CMD_SUCCESS;  }  /* Return true if an ipv6 address is configured on ifp */ -int -ipv6_address_configured (struct interface *ifp) -{ -  struct connected *connected; -  struct listnode *node; - -  for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected)) -    if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) && (connected->address->family == AF_INET6)) -      return 1; - -  return 0; -} - -static int -ipv6_address_uninstall (struct vty *vty, struct interface *ifp, -			const char *addr_str, const char *peer_str, -			const char *label, int secondry) -{ -  struct prefix_ipv6 cp; -  struct connected *ifc; -  int ret; - -  /* Convert to prefix structure. */ -  ret = str2prefix_ipv6 (addr_str, &cp); -  if (ret <= 0) -    { -      vty_out (vty, "%% Malformed address %s", VTY_NEWLINE); -      return CMD_WARNING; -    } - -  /* Check current interface address. */ -  ifc = connected_check (ifp, (struct prefix *) &cp); -  if (! ifc) -    { -      vty_out (vty, "%% Can't find address%s", VTY_NEWLINE); -      return CMD_WARNING; -    } - -  /* This is not configured address. */ -  if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)) -    return CMD_WARNING; - -  UNSET_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED); - -  /* This is not real address or interface is not active. */ -  if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_QUEUED) -      || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)) -    { -      listnode_delete (ifp->connected, ifc); -      connected_free (ifc); -      return CMD_WARNING; -    } - -  /* This is real route. */ -  ret = if_prefix_delete_ipv6 (ifp, ifc); -  if (ret < 0) -    { -      vty_out (vty, "%% Can't unset interface IP address: %s.%s",  -	       safe_strerror(errno), VTY_NEWLINE); -      return CMD_WARNING; -    } - -  UNSET_FLAG (ifc->conf, ZEBRA_IFC_QUEUED); -  /* This information will be propagated to the zclients when the -   * kernel notification is received. */ -  return CMD_SUCCESS; +int ipv6_address_configured(struct interface *ifp) +{ +	struct connected *connected; +	struct listnode *node; + +	for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) +		if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL) +		    && (connected->address->family == AF_INET6)) +			return 1; + +	return 0; +} + +static int ipv6_address_uninstall(struct vty *vty, struct interface *ifp, +				  const char *addr_str, const char *peer_str, +				  const char *label, int secondry) +{ +	struct prefix_ipv6 cp; +	struct connected *ifc; +	int ret; + +	/* Convert to prefix structure. */ +	ret = str2prefix_ipv6(addr_str, &cp); +	if (ret <= 0) { +		vty_out(vty, "%% Malformed address %s", VTY_NEWLINE); +		return CMD_WARNING; +	} + +	/* Check current interface address. */ +	ifc = connected_check(ifp, (struct prefix *)&cp); +	if (!ifc) { +		vty_out(vty, "%% Can't find address%s", VTY_NEWLINE); +		return CMD_WARNING; +	} + +	/* This is not configured address. */ +	if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED)) +		return CMD_WARNING; + +	UNSET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED); + +	/* This is not real address or interface is not active. */ +	if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED) +	    || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) { +		listnode_delete(ifp->connected, ifc); +		connected_free(ifc); +		return CMD_WARNING; +	} + +	/* This is real route. */ +	ret = if_prefix_delete_ipv6(ifp, ifc); +	if (ret < 0) { +		vty_out(vty, "%% Can't unset interface IP address: %s.%s", +			safe_strerror(errno), VTY_NEWLINE); +		return CMD_WARNING; +	} + +	UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED); +	/* This information will be propagated to the zclients when the +	 * kernel notification is received. */ +	return CMD_SUCCESS;  }  DEFUN (ipv6_address, @@ -2727,9 +2658,10 @@ DEFUN (ipv6_address,         "Set the IP address of an interface\n"         "IPv6 address (e.g. 3ffe:506::1/48)\n")  { -  int idx_ipv6_prefixlen = 2; -  VTY_DECLVAR_CONTEXT (interface, ifp); -  return ipv6_address_install (vty, ifp, argv[idx_ipv6_prefixlen]->arg, NULL, NULL, 0); +	int idx_ipv6_prefixlen = 2; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	return ipv6_address_install(vty, ifp, argv[idx_ipv6_prefixlen]->arg, +				    NULL, NULL, 0);  }  DEFUN (no_ipv6_address, @@ -2740,212 +2672,210 @@ DEFUN (no_ipv6_address,         "Set the IP address of an interface\n"         "IPv6 address (e.g. 3ffe:506::1/48)\n")  { -  int idx_ipv6_prefixlen = 3; -  VTY_DECLVAR_CONTEXT (interface, ifp); -  return ipv6_address_uninstall (vty, ifp, argv[idx_ipv6_prefixlen]->arg, NULL, NULL, 0); -} - -static int -link_params_config_write (struct vty *vty, struct interface *ifp) -{ -  int i; - -  if ((ifp == NULL) || !HAS_LINK_PARAMS(ifp)) -    return -1; - -  struct if_link_params *iflp = ifp->link_params; - -  vty_out (vty, " link-params%s", VTY_NEWLINE); -  vty_out(vty, "  enable%s", VTY_NEWLINE); -  if (IS_PARAM_SET(iflp, LP_TE_METRIC) && iflp->te_metric != ifp->metric) -    vty_out(vty, "  metric %u%s",iflp->te_metric, VTY_NEWLINE); -  if (IS_PARAM_SET(iflp, LP_MAX_BW) && iflp->max_bw != iflp->default_bw) -    vty_out(vty, "  max-bw %g%s", iflp->max_bw, VTY_NEWLINE); -  if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW) && iflp->max_rsv_bw != iflp->default_bw) -    vty_out(vty, "  max-rsv-bw %g%s", iflp->max_rsv_bw, VTY_NEWLINE); -  if (IS_PARAM_SET(iflp, LP_UNRSV_BW)) -    { -      for (i = 0; i < 8; i++) -	if (iflp->unrsv_bw[i] != iflp->default_bw) -	  vty_out(vty, "  unrsv-bw %d %g%s", -		  i, iflp->unrsv_bw[i], VTY_NEWLINE); -    } -  if (IS_PARAM_SET(iflp, LP_ADM_GRP)) -    vty_out(vty, "  admin-grp 0x%x%s", iflp->admin_grp, VTY_NEWLINE); -  if (IS_PARAM_SET(iflp, LP_DELAY)) -    { -      vty_out(vty, "  delay %u", iflp->av_delay); -      if (IS_PARAM_SET(iflp, LP_MM_DELAY)) -        { -          vty_out(vty, " min %u", iflp->min_delay); -          vty_out(vty, " max %u", iflp->max_delay); -        } -      vty_out(vty, "%s", VTY_NEWLINE); -    } -  if (IS_PARAM_SET(iflp, LP_DELAY_VAR)) -    vty_out(vty, "  delay-variation %u%s", iflp->delay_var, VTY_NEWLINE); -  if (IS_PARAM_SET(iflp, LP_PKT_LOSS)) -    vty_out(vty, "  packet-loss %g%s", iflp->pkt_loss, VTY_NEWLINE); -  if (IS_PARAM_SET(iflp, LP_AVA_BW)) -    vty_out(vty, "  ava-bw %g%s", iflp->ava_bw, VTY_NEWLINE); -  if (IS_PARAM_SET(iflp, LP_RES_BW)) -    vty_out(vty, "  res-bw %g%s", iflp->res_bw, VTY_NEWLINE); -  if (IS_PARAM_SET(iflp, LP_USE_BW)) -    vty_out(vty, "  use-bw %g%s", iflp->use_bw, VTY_NEWLINE); -  if (IS_PARAM_SET(iflp, LP_RMT_AS)) -    vty_out(vty, "  neighbor %s as %u%s", inet_ntoa(iflp->rmt_ip), -        iflp->rmt_as, VTY_NEWLINE); -  vty_out(vty, "  exit-link-params%s", VTY_NEWLINE); -  return 0; -} - -static int -if_config_write (struct vty *vty) -{ -  struct vrf *vrf; -  struct listnode *node; -  struct interface *ifp; - -  zebra_ptm_write (vty); - -  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) -  for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp)) -    { -      struct zebra_if *if_data; -      struct listnode *addrnode; -      struct connected *ifc; -      struct prefix *p; -      struct vrf *vrf; - -      if_data = ifp->info; -      vrf = vrf_lookup_by_id (ifp->vrf_id); - -      if (ifp->vrf_id == VRF_DEFAULT) -        vty_out (vty, "interface %s%s", ifp->name, VTY_NEWLINE); -      else -        vty_out (vty, "interface %s vrf %s%s", ifp->name, vrf->name, -                 VTY_NEWLINE); - -      if (if_data) -	{ -	  if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON) -	    vty_out (vty, " shutdown%s", VTY_NEWLINE); +	int idx_ipv6_prefixlen = 3; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	return ipv6_address_uninstall(vty, ifp, argv[idx_ipv6_prefixlen]->arg, +				      NULL, NULL, 0); +} + +static int link_params_config_write(struct vty *vty, struct interface *ifp) +{ +	int i; -          zebra_ptm_if_write(vty, if_data); +	if ((ifp == NULL) || !HAS_LINK_PARAMS(ifp)) +		return -1; + +	struct if_link_params *iflp = ifp->link_params; + +	vty_out(vty, " link-params%s", VTY_NEWLINE); +	vty_out(vty, "  enable%s", VTY_NEWLINE); +	if (IS_PARAM_SET(iflp, LP_TE_METRIC) && iflp->te_metric != ifp->metric) +		vty_out(vty, "  metric %u%s", iflp->te_metric, VTY_NEWLINE); +	if (IS_PARAM_SET(iflp, LP_MAX_BW) && iflp->max_bw != iflp->default_bw) +		vty_out(vty, "  max-bw %g%s", iflp->max_bw, VTY_NEWLINE); +	if (IS_PARAM_SET(iflp, LP_MAX_RSV_BW) +	    && iflp->max_rsv_bw != iflp->default_bw) +		vty_out(vty, "  max-rsv-bw %g%s", iflp->max_rsv_bw, +			VTY_NEWLINE); +	if (IS_PARAM_SET(iflp, LP_UNRSV_BW)) { +		for (i = 0; i < 8; i++) +			if (iflp->unrsv_bw[i] != iflp->default_bw) +				vty_out(vty, "  unrsv-bw %d %g%s", i, +					iflp->unrsv_bw[i], VTY_NEWLINE); +	} +	if (IS_PARAM_SET(iflp, LP_ADM_GRP)) +		vty_out(vty, "  admin-grp 0x%x%s", iflp->admin_grp, +			VTY_NEWLINE); +	if (IS_PARAM_SET(iflp, LP_DELAY)) { +		vty_out(vty, "  delay %u", iflp->av_delay); +		if (IS_PARAM_SET(iflp, LP_MM_DELAY)) { +			vty_out(vty, " min %u", iflp->min_delay); +			vty_out(vty, " max %u", iflp->max_delay); +		} +		vty_out(vty, "%s", VTY_NEWLINE);  	} +	if (IS_PARAM_SET(iflp, LP_DELAY_VAR)) +		vty_out(vty, "  delay-variation %u%s", iflp->delay_var, +			VTY_NEWLINE); +	if (IS_PARAM_SET(iflp, LP_PKT_LOSS)) +		vty_out(vty, "  packet-loss %g%s", iflp->pkt_loss, VTY_NEWLINE); +	if (IS_PARAM_SET(iflp, LP_AVA_BW)) +		vty_out(vty, "  ava-bw %g%s", iflp->ava_bw, VTY_NEWLINE); +	if (IS_PARAM_SET(iflp, LP_RES_BW)) +		vty_out(vty, "  res-bw %g%s", iflp->res_bw, VTY_NEWLINE); +	if (IS_PARAM_SET(iflp, LP_USE_BW)) +		vty_out(vty, "  use-bw %g%s", iflp->use_bw, VTY_NEWLINE); +	if (IS_PARAM_SET(iflp, LP_RMT_AS)) +		vty_out(vty, "  neighbor %s as %u%s", inet_ntoa(iflp->rmt_ip), +			iflp->rmt_as, VTY_NEWLINE); +	vty_out(vty, "  exit-link-params%s", VTY_NEWLINE); +	return 0; +} + +static int if_config_write(struct vty *vty) +{ +	struct vrf *vrf; +	struct listnode *node; +	struct interface *ifp; + +	zebra_ptm_write(vty); + +	RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) +	for (ALL_LIST_ELEMENTS_RO(vrf->iflist, node, ifp)) { +		struct zebra_if *if_data; +		struct listnode *addrnode; +		struct connected *ifc; +		struct prefix *p; +		struct vrf *vrf; + +		if_data = ifp->info; +		vrf = vrf_lookup_by_id(ifp->vrf_id); + +		if (ifp->vrf_id == VRF_DEFAULT) +			vty_out(vty, "interface %s%s", ifp->name, VTY_NEWLINE); +		else +			vty_out(vty, "interface %s vrf %s%s", ifp->name, +				vrf->name, VTY_NEWLINE); + +		if (if_data) { +			if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON) +				vty_out(vty, " shutdown%s", VTY_NEWLINE); + +			zebra_ptm_if_write(vty, if_data); +		} -      if (ifp->desc) -	vty_out (vty, " description %s%s", ifp->desc, -		 VTY_NEWLINE); +		if (ifp->desc) +			vty_out(vty, " description %s%s", ifp->desc, +				VTY_NEWLINE); -      /* Assign bandwidth here to avoid unnecessary interface flap -	 while processing config script */ -      if (ifp->bandwidth != 0) -	vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE);  +		/* Assign bandwidth here to avoid unnecessary interface flap +		   while processing config script */ +		if (ifp->bandwidth != 0) +			vty_out(vty, " bandwidth %u%s", ifp->bandwidth, +				VTY_NEWLINE); -      if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) -        vty_out(vty, " no link-detect%s", VTY_NEWLINE); +		if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) +			vty_out(vty, " no link-detect%s", VTY_NEWLINE); -      for (ALL_LIST_ELEMENTS_RO (ifp->connected, addrnode, ifc)) -	  { -	    if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED)) -	      { -		char buf[INET6_ADDRSTRLEN]; -		p = ifc->address; -		vty_out (vty, " ip%s address %s", -			 p->family == AF_INET ? "" : "v6", -			 prefix2str (p, buf, sizeof(buf))); +		for (ALL_LIST_ELEMENTS_RO(ifp->connected, addrnode, ifc)) { +			if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED)) { +				char buf[INET6_ADDRSTRLEN]; +				p = ifc->address; +				vty_out(vty, " ip%s address %s", +					p->family == AF_INET ? "" : "v6", +					prefix2str(p, buf, sizeof(buf))); -		if (ifc->label) -		  vty_out (vty, " label %s", ifc->label); +				if (ifc->label) +					vty_out(vty, " label %s", ifc->label); -		vty_out (vty, "%s", VTY_NEWLINE); -	      } -	  } +				vty_out(vty, "%s", VTY_NEWLINE); +			} +		} -      if (if_data) -	{ -	  if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC) -	    vty_out (vty, " %smulticast%s", -		     if_data->multicast == IF_ZEBRA_MULTICAST_ON ? "" : "no ", -		     VTY_NEWLINE); -	} +		if (if_data) { +			if (if_data->multicast != IF_ZEBRA_MULTICAST_UNSPEC) +				vty_out(vty, " %smulticast%s", +					if_data->multicast +							== IF_ZEBRA_MULTICAST_ON +						? "" +						: "no ", +					VTY_NEWLINE); +		} -#if defined (HAVE_RTADV) -      rtadv_config_write (vty, ifp); +#if defined(HAVE_RTADV) +		rtadv_config_write(vty, ifp);  #endif /* HAVE_RTADV */  #ifdef HAVE_IRDP -      irdp_config_write (vty, ifp); +		irdp_config_write(vty, ifp);  #endif /* IRDP */ -      link_params_config_write (vty, ifp); +		link_params_config_write(vty, ifp); -      vty_out (vty, "!%s", VTY_NEWLINE); -    } -  return 0; +		vty_out(vty, "!%s", VTY_NEWLINE); +	} +	return 0;  }  /* Allocate and initialize interface vector. */ -void -zebra_if_init (void) -{ -  /* Initialize interface and new hook. */ -  if_add_hook (IF_NEW_HOOK, if_zebra_new_hook); -  if_add_hook (IF_DELETE_HOOK, if_zebra_delete_hook); -   -  /* Install configuration write function. */ -  install_node (&interface_node, if_config_write); -  install_node (&link_params_node, NULL); -  if_cmd_init (); - -  install_element (VIEW_NODE, &show_interface_cmd); -  install_element (VIEW_NODE, &show_interface_vrf_all_cmd); -  install_element (VIEW_NODE, &show_interface_name_vrf_cmd); -  install_element (VIEW_NODE, &show_interface_name_vrf_all_cmd); - -  install_element (ENABLE_NODE, &show_interface_desc_cmd); -  install_element (ENABLE_NODE, &show_interface_desc_vrf_all_cmd); -  install_element (INTERFACE_NODE, &multicast_cmd); -  install_element (INTERFACE_NODE, &no_multicast_cmd); -  install_element (INTERFACE_NODE, &linkdetect_cmd); -  install_element (INTERFACE_NODE, &no_linkdetect_cmd); -  install_element (INTERFACE_NODE, &shutdown_if_cmd); -  install_element (INTERFACE_NODE, &no_shutdown_if_cmd); -  install_element (INTERFACE_NODE, &bandwidth_if_cmd); -  install_element (INTERFACE_NODE, &no_bandwidth_if_cmd); -  install_element (INTERFACE_NODE, &ip_address_cmd); -  install_element (INTERFACE_NODE, &no_ip_address_cmd); -  install_element (INTERFACE_NODE, &ipv6_address_cmd); -  install_element (INTERFACE_NODE, &no_ipv6_address_cmd); +void zebra_if_init(void) +{ +	/* Initialize interface and new hook. */ +	if_add_hook(IF_NEW_HOOK, if_zebra_new_hook); +	if_add_hook(IF_DELETE_HOOK, if_zebra_delete_hook); + +	/* Install configuration write function. */ +	install_node(&interface_node, if_config_write); +	install_node(&link_params_node, NULL); +	if_cmd_init(); + +	install_element(VIEW_NODE, &show_interface_cmd); +	install_element(VIEW_NODE, &show_interface_vrf_all_cmd); +	install_element(VIEW_NODE, &show_interface_name_vrf_cmd); +	install_element(VIEW_NODE, &show_interface_name_vrf_all_cmd); + +	install_element(ENABLE_NODE, &show_interface_desc_cmd); +	install_element(ENABLE_NODE, &show_interface_desc_vrf_all_cmd); +	install_element(INTERFACE_NODE, &multicast_cmd); +	install_element(INTERFACE_NODE, &no_multicast_cmd); +	install_element(INTERFACE_NODE, &linkdetect_cmd); +	install_element(INTERFACE_NODE, &no_linkdetect_cmd); +	install_element(INTERFACE_NODE, &shutdown_if_cmd); +	install_element(INTERFACE_NODE, &no_shutdown_if_cmd); +	install_element(INTERFACE_NODE, &bandwidth_if_cmd); +	install_element(INTERFACE_NODE, &no_bandwidth_if_cmd); +	install_element(INTERFACE_NODE, &ip_address_cmd); +	install_element(INTERFACE_NODE, &no_ip_address_cmd); +	install_element(INTERFACE_NODE, &ipv6_address_cmd); +	install_element(INTERFACE_NODE, &no_ipv6_address_cmd);  #ifdef HAVE_NETLINK -  install_element (INTERFACE_NODE, &ip_address_label_cmd); -  install_element (INTERFACE_NODE, &no_ip_address_label_cmd); +	install_element(INTERFACE_NODE, &ip_address_label_cmd); +	install_element(INTERFACE_NODE, &no_ip_address_label_cmd);  #endif /* HAVE_NETLINK */ -  install_element(INTERFACE_NODE, &link_params_cmd); -  install_default(LINK_PARAMS_NODE); -  install_element(LINK_PARAMS_NODE, &link_params_enable_cmd); -  install_element(LINK_PARAMS_NODE, &no_link_params_enable_cmd); -  install_element(LINK_PARAMS_NODE, &link_params_metric_cmd); -  install_element(LINK_PARAMS_NODE, &no_link_params_metric_cmd); -  install_element(LINK_PARAMS_NODE, &link_params_maxbw_cmd); -  install_element(LINK_PARAMS_NODE, &link_params_max_rsv_bw_cmd); -  install_element(LINK_PARAMS_NODE, &link_params_unrsv_bw_cmd); -  install_element(LINK_PARAMS_NODE, &link_params_admin_grp_cmd); -  install_element(LINK_PARAMS_NODE, &no_link_params_admin_grp_cmd); -  install_element(LINK_PARAMS_NODE, &link_params_inter_as_cmd); -  install_element(LINK_PARAMS_NODE, &no_link_params_inter_as_cmd); -  install_element(LINK_PARAMS_NODE, &link_params_delay_cmd); -  install_element(LINK_PARAMS_NODE, &no_link_params_delay_cmd); -  install_element(LINK_PARAMS_NODE, &link_params_delay_var_cmd); -  install_element(LINK_PARAMS_NODE, &no_link_params_delay_var_cmd); -  install_element(LINK_PARAMS_NODE, &link_params_pkt_loss_cmd); -  install_element(LINK_PARAMS_NODE, &no_link_params_pkt_loss_cmd); -  install_element(LINK_PARAMS_NODE, &link_params_ava_bw_cmd); -  install_element(LINK_PARAMS_NODE, &no_link_params_ava_bw_cmd); -  install_element(LINK_PARAMS_NODE, &link_params_res_bw_cmd); -  install_element(LINK_PARAMS_NODE, &no_link_params_res_bw_cmd); -  install_element(LINK_PARAMS_NODE, &link_params_use_bw_cmd); -  install_element(LINK_PARAMS_NODE, &no_link_params_use_bw_cmd); -  install_element(LINK_PARAMS_NODE, &exit_link_params_cmd); +	install_element(INTERFACE_NODE, &link_params_cmd); +	install_default(LINK_PARAMS_NODE); +	install_element(LINK_PARAMS_NODE, &link_params_enable_cmd); +	install_element(LINK_PARAMS_NODE, &no_link_params_enable_cmd); +	install_element(LINK_PARAMS_NODE, &link_params_metric_cmd); +	install_element(LINK_PARAMS_NODE, &no_link_params_metric_cmd); +	install_element(LINK_PARAMS_NODE, &link_params_maxbw_cmd); +	install_element(LINK_PARAMS_NODE, &link_params_max_rsv_bw_cmd); +	install_element(LINK_PARAMS_NODE, &link_params_unrsv_bw_cmd); +	install_element(LINK_PARAMS_NODE, &link_params_admin_grp_cmd); +	install_element(LINK_PARAMS_NODE, &no_link_params_admin_grp_cmd); +	install_element(LINK_PARAMS_NODE, &link_params_inter_as_cmd); +	install_element(LINK_PARAMS_NODE, &no_link_params_inter_as_cmd); +	install_element(LINK_PARAMS_NODE, &link_params_delay_cmd); +	install_element(LINK_PARAMS_NODE, &no_link_params_delay_cmd); +	install_element(LINK_PARAMS_NODE, &link_params_delay_var_cmd); +	install_element(LINK_PARAMS_NODE, &no_link_params_delay_var_cmd); +	install_element(LINK_PARAMS_NODE, &link_params_pkt_loss_cmd); +	install_element(LINK_PARAMS_NODE, &no_link_params_pkt_loss_cmd); +	install_element(LINK_PARAMS_NODE, &link_params_ava_bw_cmd); +	install_element(LINK_PARAMS_NODE, &no_link_params_ava_bw_cmd); +	install_element(LINK_PARAMS_NODE, &link_params_res_bw_cmd); +	install_element(LINK_PARAMS_NODE, &no_link_params_res_bw_cmd); +	install_element(LINK_PARAMS_NODE, &link_params_use_bw_cmd); +	install_element(LINK_PARAMS_NODE, &no_link_params_use_bw_cmd); +	install_element(LINK_PARAMS_NODE, &exit_link_params_cmd);  } diff --git a/zebra/interface.h b/zebra/interface.h index 9f108760d6..9bcaf1423c 100644 --- a/zebra/interface.h +++ b/zebra/interface.h @@ -16,7 +16,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #ifndef _ZEBRA_INTERFACE_H @@ -38,142 +38,144 @@  #define IF_ZEBRA_SHUTDOWN_OFF    0  #define IF_ZEBRA_SHUTDOWN_ON     1 -#if defined (HAVE_RTADV) +#if defined(HAVE_RTADV)  /* Router advertisement parameter.  From RFC4861, RFC6275 and RFC4191. */ -struct rtadvconf -{ -  /* A flag indicating whether or not the router sends periodic Router -     Advertisements and responds to Router Solicitations. -     Default: FALSE */ -  int AdvSendAdvertisements; - -  /* The maximum time allowed between sending unsolicited multicast -     Router Advertisements from the interface, in milliseconds. -     MUST be no less than 70 ms [RFC6275 7.5] and no greater -     than 1800000 ms [RFC4861 6.2.1]. - -     Default: 600000 milliseconds */ -  int MaxRtrAdvInterval; +struct rtadvconf { +	/* A flag indicating whether or not the router sends periodic Router +	   Advertisements and responds to Router Solicitations. +	   Default: FALSE */ +	int AdvSendAdvertisements; + +	/* The maximum time allowed between sending unsolicited multicast +	   Router Advertisements from the interface, in milliseconds. +	   MUST be no less than 70 ms [RFC6275 7.5] and no greater +	   than 1800000 ms [RFC4861 6.2.1]. + +	   Default: 600000 milliseconds */ +	int MaxRtrAdvInterval;  #define RTADV_MAX_RTR_ADV_INTERVAL 600000 -  /* The minimum time allowed between sending unsolicited multicast -     Router Advertisements from the interface, in milliseconds. -     MUST be no less than 30 ms [RFC6275 7.5]. -     MUST be no greater than .75 * MaxRtrAdvInterval. +	/* The minimum time allowed between sending unsolicited multicast +	   Router Advertisements from the interface, in milliseconds. +	   MUST be no less than 30 ms [RFC6275 7.5]. +	   MUST be no greater than .75 * MaxRtrAdvInterval. -     Default: 0.33 * MaxRtrAdvInterval */ -  int MinRtrAdvInterval; /* This field is currently unused. */ +	   Default: 0.33 * MaxRtrAdvInterval */ +	int MinRtrAdvInterval; /* This field is currently unused. */ +			       /* $FRR indent$ */ +			       /* clang-format off */  #define RTADV_MIN_RTR_ADV_INTERVAL (0.33 * RTADV_MAX_RTR_ADV_INTERVAL) -  /* Unsolicited Router Advertisements' interval timer. */ -  int AdvIntervalTimer; +	/* Unsolicited Router Advertisements' interval timer. */ +	int AdvIntervalTimer; -  /* The TRUE/FALSE value to be placed in the "Managed address -     configuration" flag field in the Router Advertisement.  See -     [ADDRCONF]. -  -     Default: FALSE */ -  int AdvManagedFlag; +	/* The TRUE/FALSE value to be placed in the "Managed address +	   configuration" flag field in the Router Advertisement.  See +	   [ADDRCONF]. +	   Default: FALSE */ +	int AdvManagedFlag; -  /* The TRUE/FALSE value to be placed in the "Other stateful -     configuration" flag field in the Router Advertisement.  See -     [ADDRCONF]. -     Default: FALSE */ -  int AdvOtherConfigFlag; +	/* The TRUE/FALSE value to be placed in the "Other stateful +	   configuration" flag field in the Router Advertisement.  See +	   [ADDRCONF]. -  /* The value to be placed in MTU options sent by the router.  A -     value of zero indicates that no MTU options are sent. +	   Default: FALSE */ +	int AdvOtherConfigFlag; -     Default: 0 */ -  int AdvLinkMTU; +	/* The value to be placed in MTU options sent by the router.  A +	   value of zero indicates that no MTU options are sent. +	   Default: 0 */ +	int AdvLinkMTU; -  /* The value to be placed in the Reachable Time field in the Router -     Advertisement messages sent by the router.  The value zero means -     unspecified (by this router).  MUST be no greater than 3,600,000 -     milliseconds (1 hour). -     Default: 0 */ -  u_int32_t AdvReachableTime; -#define RTADV_MAX_REACHABLE_TIME 3600000 +	/* The value to be placed in the Reachable Time field in the Router +	   Advertisement messages sent by the router.  The value zero means +	   unspecified (by this router).  MUST be no greater than 3,600,000 +	   milliseconds (1 hour). +	   Default: 0 */ +	u_int32_t AdvReachableTime; +#define RTADV_MAX_REACHABLE_TIME 3600000 -  /* The value to be placed in the Retrans Timer field in the Router -     Advertisement messages sent by the router.  The value zero means -     unspecified (by this router). +	/* The value to be placed in the Retrans Timer field in the Router +	   Advertisement messages sent by the router.  The value zero means +	   unspecified (by this router). -     Default: 0 */ -  int AdvRetransTimer; +	   Default: 0 */ +	int AdvRetransTimer; -  /* The default value to be placed in the Cur Hop Limit field in the -     Router Advertisement messages sent by the router.  The value -     should be set to that current diameter of the Internet.  The -     value zero means unspecified (by this router). +	/* The default value to be placed in the Cur Hop Limit field in the +	   Router Advertisement messages sent by the router.  The value +	   should be set to that current diameter of the Internet.  The +	   value zero means unspecified (by this router). -     Default: The value specified in the "Assigned Numbers" RFC -     [ASSIGNED] that was in effect at the time of implementation. */ -  int AdvCurHopLimit; +	   Default: The value specified in the "Assigned Numbers" RFC +	   [ASSIGNED] that was in effect at the time of implementation. */ +	int AdvCurHopLimit; -  /* The value to be placed in the Router Lifetime field of Router -     Advertisements sent from the interface, in seconds.  MUST be -     either zero or between MaxRtrAdvInterval and 9000 seconds.  A -     value of zero indicates that the router is not to be used as a -     default router. +	/* The value to be placed in the Router Lifetime field of Router +	   Advertisements sent from the interface, in seconds.  MUST be +	   either zero or between MaxRtrAdvInterval and 9000 seconds.  A +	   value of zero indicates that the router is not to be used as a +	   default router. -     Default: 3 * MaxRtrAdvInterval */ -  int AdvDefaultLifetime; +	   Default: 3 * MaxRtrAdvInterval */ +	int AdvDefaultLifetime;  #define RTADV_MAX_RTRLIFETIME 9000 /* 2.5 hours */ -  /* A list of prefixes to be placed in Prefix Information options in -     Router Advertisement messages sent from the interface. +	/* A list of prefixes to be placed in Prefix Information options in +	   Router Advertisement messages sent from the interface. -     Default: all prefixes that the router advertises via routing -     protocols as being on-link for the interface from which the -     advertisement is sent. The link-local prefix SHOULD NOT be -     included in the list of advertised prefixes. */ -  struct list *AdvPrefixList; +	   Default: all prefixes that the router advertises via routing +	   protocols as being on-link for the interface from which the +	   advertisement is sent. The link-local prefix SHOULD NOT be +	   included in the list of advertised prefixes. */ +	struct list *AdvPrefixList; -  /* The TRUE/FALSE value to be placed in the "Home agent" -     flag field in the Router Advertisement.  See [RFC6275 7.1]. +	/* The TRUE/FALSE value to be placed in the "Home agent" +	   flag field in the Router Advertisement.  See [RFC6275 7.1]. -     Default: FALSE */ -  int AdvHomeAgentFlag; +	   Default: FALSE */ +	int AdvHomeAgentFlag;  #ifndef ND_RA_FLAG_HOME_AGENT  #define ND_RA_FLAG_HOME_AGENT 	0x20  #endif -  /* The value to be placed in Home Agent Information option if Home  -     Flag is set. -     Default: 0 */ -  int HomeAgentPreference; - -  /* The value to be placed in Home Agent Information option if Home  -     Flag is set. Lifetime (seconds) MUST not be greater than 18.2  -     hours.  -     The value 0 has special meaning: use of AdvDefaultLifetime value. -      -     Default: 0 */ -  int HomeAgentLifetime; +	/* The value to be placed in Home Agent Information option if Home +	   Flag is set. +	   Default: 0 */ +	int HomeAgentPreference; + +	/* The value to be placed in Home Agent Information option if Home +	   Flag is set. Lifetime (seconds) MUST not be greater than 18.2 +	   hours. +	   The value 0 has special meaning: use of AdvDefaultLifetime value. + +	   Default: 0 */ +	int HomeAgentLifetime;  #define RTADV_MAX_HALIFETIME 65520 /* 18.2 hours */ -  /* The TRUE/FALSE value to insert or not an Advertisement Interval -     option. See [RFC 6275 7.3] +	/* The TRUE/FALSE value to insert or not an Advertisement Interval +	   option. See [RFC 6275 7.3] -     Default: FALSE */ -  int AdvIntervalOption; +	   Default: FALSE */ +	int AdvIntervalOption; -  /* The value to be placed in the Default Router Preference field of -     a router advertisement. See [RFC 4191 2.1 & 2.2] +	/* The value to be placed in the Default Router Preference field of +	   a router advertisement. See [RFC 4191 2.1 & 2.2] -     Default: 0 (medium) */ -  int DefaultPreference; +	   Default: 0 (medium) */ +	int DefaultPreference;  #define RTADV_PREF_MEDIUM 0x0 /* Per RFC4191. */ -  u_char inFastRexmit;          /* True if we're rexmits faster than usual */ -  u_char configured;            /* Has operator configured RA? */ -  int NumFastReXmitsRemain;     /* Loaded first with number of fast rexmits to do */ +	u_char inFastRexmit; /* True if we're rexmits faster than usual */ +	u_char configured;   /* Has operator configured RA? */ +	int +		NumFastReXmitsRemain; /* Loaded first with number of fast +					 rexmits to do */  #define RTADV_FAST_REXMIT_PERIOD 1 /* 1 sec */  #define RTADV_NUM_FAST_REXMITS   4 /* Fast Rexmit RA 4 times on certain events */ @@ -182,93 +184,97 @@ struct rtadvconf  #endif /* HAVE_RTADV */  /* `zebra' daemon local interface structure. */ -struct zebra_if -{ -  /* Shutdown configuration. */ -  u_char shutdown; +struct zebra_if { +	/* Shutdown configuration. */ +	u_char shutdown; -  /* Multicast configuration. */ -  u_char multicast; +	/* Multicast configuration. */ +	u_char multicast; -  /* Router advertise configuration. */ -  u_char rtadv_enable; +	/* Router advertise configuration. */ +	u_char rtadv_enable; -  /* Installed addresses chains tree. */ -  struct route_table *ipv4_subnets; +	/* Installed addresses chains tree. */ +	struct route_table *ipv4_subnets; -  /* Information about up/down changes */ -  unsigned int up_count; -  char up_last[QUAGGA_TIMESTAMP_LEN]; -  unsigned int down_count; -  char down_last[QUAGGA_TIMESTAMP_LEN]; +	/* Information about up/down changes */ +	unsigned int up_count; +	char up_last[QUAGGA_TIMESTAMP_LEN]; +	unsigned int down_count; +	char down_last[QUAGGA_TIMESTAMP_LEN];  #if defined(HAVE_RTADV) -  struct rtadvconf rtadv; -  unsigned int ra_sent, ra_rcvd; +	struct rtadvconf rtadv; +	unsigned int ra_sent, ra_rcvd;  #endif /* HAVE_RTADV */  #ifdef HAVE_IRDP -  struct irdp_interface irdp; +	struct irdp_interface irdp;  #endif  #ifdef HAVE_STRUCT_SOCKADDR_DL -  union { -    /* note that sdl_storage is never accessed, it only exists to make space. -     * all actual uses refer to sdl - but use sizeof(sdl_storage)!  this fits -     * best with C aliasing rules. */ -    struct sockaddr_dl sdl; -    struct sockaddr_storage sdl_storage; -  }; +	union { +		/* note that sdl_storage is never accessed, it only exists to +		 * make space. +		 * all actual uses refer to sdl - but use sizeof(sdl_storage)! +		 * this fits +		 * best with C aliasing rules. */ +		struct sockaddr_dl sdl; +		struct sockaddr_storage sdl_storage; +	};  #endif  #ifdef SUNOS_5 -  /* the real IFF_UP state of the primary interface. -   * need this to differentiate between all interfaces being -   * down (but primary still plumbed) and primary having gone -   * ~IFF_UP, and all addresses gone. -   */ -  u_char primary_state; +	/* the real IFF_UP state of the primary interface. +	 * need this to differentiate between all interfaces being +	 * down (but primary still plumbed) and primary having gone +	 * ~IFF_UP, and all addresses gone. +	 */ +	u_char primary_state;  #endif /* SUNOS_5 */ -  /* ptm enable configuration */ -  u_char ptm_enable; +	/* ptm enable configuration */ +	u_char ptm_enable;  }; -extern struct interface *if_lookup_by_index_per_ns (struct zebra_ns *, u_int32_t); -extern struct interface *if_lookup_by_name_per_ns (struct zebra_ns *, const char *); -extern struct interface *if_link_per_ns (struct zebra_ns *, struct interface *); -extern const char *ifindex2ifname_per_ns (struct zebra_ns *, unsigned int); - -extern void if_unlink_per_ns (struct interface *); -extern void if_nbr_ipv6ll_to_ipv4ll_neigh_update (struct interface *ifp, -                                                  struct in6_addr *address, int add); -extern void if_nbr_ipv6ll_to_ipv4ll_neigh_del_all (struct interface *ifp); -extern void if_delete_update (struct interface *ifp); -extern void if_add_update (struct interface *ifp); -extern void if_up (struct interface *); -extern void if_down (struct interface *); -extern void if_refresh (struct interface *); -extern void if_flags_update (struct interface *, uint64_t); -extern int if_subnet_add (struct interface *, struct connected *); -extern int if_subnet_delete (struct interface *, struct connected *); -extern int ipv6_address_configured (struct interface *ifp); -extern void if_handle_vrf_change (struct interface *ifp, vrf_id_t vrf_id); - -extern void vrf_add_update (struct vrf *vrfp); +extern struct interface *if_lookup_by_index_per_ns(struct zebra_ns *, +						   u_int32_t); +extern struct interface *if_lookup_by_name_per_ns(struct zebra_ns *, +						  const char *); +extern struct interface *if_link_per_ns(struct zebra_ns *, struct interface *); +extern const char *ifindex2ifname_per_ns(struct zebra_ns *, unsigned int); + +extern void if_unlink_per_ns(struct interface *); +extern void if_nbr_ipv6ll_to_ipv4ll_neigh_update(struct interface *ifp, +						 struct in6_addr *address, +						 int add); +extern void if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(struct interface *ifp); +extern void if_delete_update(struct interface *ifp); +extern void if_add_update(struct interface *ifp); +extern void if_up(struct interface *); +extern void if_down(struct interface *); +extern void if_refresh(struct interface *); +extern void if_flags_update(struct interface *, uint64_t); +extern int if_subnet_add(struct interface *, struct connected *); +extern int if_subnet_delete(struct interface *, struct connected *); +extern int ipv6_address_configured(struct interface *ifp); +extern void if_handle_vrf_change(struct interface *ifp, vrf_id_t vrf_id); + +extern void vrf_add_update(struct vrf *vrfp);  #ifdef HAVE_PROC_NET_DEV -extern void ifstat_update_proc (void); +extern void ifstat_update_proc(void);  #endif /* HAVE_PROC_NET_DEV */  #ifdef HAVE_NET_RT_IFLIST -extern void ifstat_update_sysctl (void); +extern void ifstat_update_sysctl(void);  #endif /* HAVE_NET_RT_IFLIST */  #ifdef HAVE_PROC_NET_DEV -extern int interface_list_proc (void); +extern int interface_list_proc(void);  #endif /* HAVE_PROC_NET_DEV */  #ifdef HAVE_PROC_NET_IF_INET6 -extern int ifaddr_proc_ipv6 (void); +extern int ifaddr_proc_ipv6(void);  #endif /* HAVE_PROC_NET_IF_INET6 */  #endif /* _ZEBRA_INTERFACE_H */ diff --git a/zebra/ioctl.c b/zebra/ioctl.c index dfd69300f9..0f61968f4f 100644 --- a/zebra/ioctl.c +++ b/zebra/ioctl.c @@ -17,7 +17,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #include <zebra.h> @@ -41,551 +41,525 @@  extern struct zebra_privs_t zserv_privs;  /* clear and set interface name string */ -void -ifreq_set_name (struct ifreq *ifreq, struct interface *ifp) +void ifreq_set_name(struct ifreq *ifreq, struct interface *ifp)  { -  strncpy (ifreq->ifr_name, ifp->name, IFNAMSIZ); +	strncpy(ifreq->ifr_name, ifp->name, IFNAMSIZ);  }  /* call ioctl system call */ -int -if_ioctl (u_long request, caddr_t buffer) +int if_ioctl(u_long request, caddr_t buffer)  { -  int sock; -  int ret; -  int err = 0; - -  if (zserv_privs.change(ZPRIVS_RAISE)) -    zlog_err("Can't raise privileges"); -  sock = socket (AF_INET, SOCK_DGRAM, 0); -  if (sock < 0) -    { -      int save_errno = errno; -      if (zserv_privs.change(ZPRIVS_LOWER)) -        zlog_err("Can't lower privileges"); -      zlog_err("Cannot create UDP socket: %s", safe_strerror(save_errno)); -      exit (1); -    } -  if ((ret = ioctl (sock, request, buffer)) < 0) -    err = errno; -  if (zserv_privs.change(ZPRIVS_LOWER)) -    zlog_err("Can't lower privileges"); -  close (sock); -   -  if (ret < 0)  -    { -      errno = err; -      return ret; -    } -  return 0; +	int sock; +	int ret; +	int err = 0; + +	if (zserv_privs.change(ZPRIVS_RAISE)) +		zlog_err("Can't raise privileges"); +	sock = socket(AF_INET, SOCK_DGRAM, 0); +	if (sock < 0) { +		int save_errno = errno; +		if (zserv_privs.change(ZPRIVS_LOWER)) +			zlog_err("Can't lower privileges"); +		zlog_err("Cannot create UDP socket: %s", +			 safe_strerror(save_errno)); +		exit(1); +	} +	if ((ret = ioctl(sock, request, buffer)) < 0) +		err = errno; +	if (zserv_privs.change(ZPRIVS_LOWER)) +		zlog_err("Can't lower privileges"); +	close(sock); + +	if (ret < 0) { +		errno = err; +		return ret; +	} +	return 0;  } -static int -if_ioctl_ipv6 (u_long request, caddr_t buffer) +static int if_ioctl_ipv6(u_long request, caddr_t buffer)  { -  int sock; -  int ret; -  int err = 0; - -  if (zserv_privs.change(ZPRIVS_RAISE)) -    zlog_err("Can't raise privileges"); -  sock = socket (AF_INET6, SOCK_DGRAM, 0); -  if (sock < 0) -    { -      int save_errno = errno; -      if (zserv_privs.change(ZPRIVS_LOWER)) -        zlog_err("Can't lower privileges"); -      zlog_err("Cannot create IPv6 datagram socket: %s", -	       safe_strerror(save_errno)); -      exit (1); -    } - -  if ((ret = ioctl (sock, request, buffer)) < 0) -    err = errno; -  if (zserv_privs.change(ZPRIVS_LOWER)) -    zlog_err("Can't lower privileges"); -  close (sock); -   -  if (ret < 0)  -    { -      errno = err; -      return ret; -    } -  return 0; +	int sock; +	int ret; +	int err = 0; + +	if (zserv_privs.change(ZPRIVS_RAISE)) +		zlog_err("Can't raise privileges"); +	sock = socket(AF_INET6, SOCK_DGRAM, 0); +	if (sock < 0) { +		int save_errno = errno; +		if (zserv_privs.change(ZPRIVS_LOWER)) +			zlog_err("Can't lower privileges"); +		zlog_err("Cannot create IPv6 datagram socket: %s", +			 safe_strerror(save_errno)); +		exit(1); +	} + +	if ((ret = ioctl(sock, request, buffer)) < 0) +		err = errno; +	if (zserv_privs.change(ZPRIVS_LOWER)) +		zlog_err("Can't lower privileges"); +	close(sock); + +	if (ret < 0) { +		errno = err; +		return ret; +	} +	return 0;  }  /*   * get interface metric   *   -- if value is not avaliable set -1   */ -void -if_get_metric (struct interface *ifp) +void if_get_metric(struct interface *ifp)  {  #ifdef SIOCGIFMETRIC -  struct ifreq ifreq; +	struct ifreq ifreq; -  ifreq_set_name (&ifreq, ifp); +	ifreq_set_name(&ifreq, ifp); -  if (if_ioctl (SIOCGIFMETRIC, (caddr_t) &ifreq) < 0)  -    return; -  ifp->metric = ifreq.ifr_metric; -  if (ifp->metric == 0) -    ifp->metric = 1; -#else /* SIOCGIFMETRIC */ -  ifp->metric = -1; +	if (if_ioctl(SIOCGIFMETRIC, (caddr_t)&ifreq) < 0) +		return; +	ifp->metric = ifreq.ifr_metric; +	if (ifp->metric == 0) +		ifp->metric = 1; +#else  /* SIOCGIFMETRIC */ +	ifp->metric = -1;  #endif /* SIOCGIFMETRIC */  }  /* get interface MTU */ -void -if_get_mtu (struct interface *ifp) +void if_get_mtu(struct interface *ifp)  { -  struct ifreq ifreq; +	struct ifreq ifreq; -  ifreq_set_name (&ifreq, ifp); +	ifreq_set_name(&ifreq, ifp);  #if defined(SIOCGIFMTU) -  if (if_ioctl (SIOCGIFMTU, (caddr_t) & ifreq) < 0)  -    { -      zlog_info ("Can't lookup mtu by ioctl(SIOCGIFMTU)"); -      ifp->mtu6 = ifp->mtu = -1; -      return; -    } +	if (if_ioctl(SIOCGIFMTU, (caddr_t)&ifreq) < 0) { +		zlog_info("Can't lookup mtu by ioctl(SIOCGIFMTU)"); +		ifp->mtu6 = ifp->mtu = -1; +		return; +	}  #ifdef SUNOS_5 -  ifp->mtu6 = ifp->mtu = ifreq.ifr_metric; +	ifp->mtu6 = ifp->mtu = ifreq.ifr_metric;  #else -  ifp->mtu6 = ifp->mtu = ifreq.ifr_mtu; +	ifp->mtu6 = ifp->mtu = ifreq.ifr_mtu;  #endif /* SUNOS_5 */ -  /* propogate */ -  zebra_interface_up_update(ifp); +	/* propogate */ +	zebra_interface_up_update(ifp);  #else -  zlog_info("Can't lookup mtu on this system"); -  ifp->mtu6 = ifp->mtu = -1; +	zlog_info("Can't lookup mtu on this system"); +	ifp->mtu6 = ifp->mtu = -1;  #endif  }  #ifdef HAVE_NETLINK  /* Interface address setting via netlink interface. */ -int -if_set_prefix (struct interface *ifp, struct connected *ifc) +int if_set_prefix(struct interface *ifp, struct connected *ifc)  { -  return kernel_address_add_ipv4 (ifp, ifc); +	return kernel_address_add_ipv4(ifp, ifc);  }  /* Interface address is removed using netlink interface. */ -int -if_unset_prefix (struct interface *ifp, struct connected *ifc) +int if_unset_prefix(struct interface *ifp, struct connected *ifc)  { -  return kernel_address_delete_ipv4 (ifp, ifc); +	return kernel_address_delete_ipv4(ifp, ifc);  }  #else /* ! HAVE_NETLINK */  #ifdef HAVE_STRUCT_IFALIASREQ  /* Set up interface's IP address, netmask (and broadcas? ).  *BSD may     has ifaliasreq structure.  */ -int -if_set_prefix (struct interface *ifp, struct connected *ifc) +int if_set_prefix(struct interface *ifp, struct connected *ifc)  { -  int ret; -  struct ifaliasreq addreq; -  struct sockaddr_in addr; -  struct sockaddr_in mask; -  struct prefix_ipv4 *p; +	int ret; +	struct ifaliasreq addreq; +	struct sockaddr_in addr; +	struct sockaddr_in mask; +	struct prefix_ipv4 *p; -  p = (struct prefix_ipv4 *) ifc->address; -  rib_lookup_and_pushup (p, ifp->vrf_id); +	p = (struct prefix_ipv4 *)ifc->address; +	rib_lookup_and_pushup(p, ifp->vrf_id); -  memset (&addreq, 0, sizeof addreq); -  strncpy ((char *)&addreq.ifra_name, ifp->name, sizeof addreq.ifra_name); +	memset(&addreq, 0, sizeof addreq); +	strncpy((char *)&addreq.ifra_name, ifp->name, sizeof addreq.ifra_name); -  memset (&addr, 0, sizeof (struct sockaddr_in)); -  addr.sin_addr = p->prefix; -  addr.sin_family = p->family; +	memset(&addr, 0, sizeof(struct sockaddr_in)); +	addr.sin_addr = p->prefix; +	addr.sin_family = p->family;  #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN -  addr.sin_len = sizeof (struct sockaddr_in); +	addr.sin_len = sizeof(struct sockaddr_in);  #endif -  memcpy (&addreq.ifra_addr, &addr, sizeof (struct sockaddr_in)); +	memcpy(&addreq.ifra_addr, &addr, sizeof(struct sockaddr_in)); -  memset (&mask, 0, sizeof (struct sockaddr_in)); -  masklen2ip (p->prefixlen, &mask.sin_addr); -  mask.sin_family = p->family; +	memset(&mask, 0, sizeof(struct sockaddr_in)); +	masklen2ip(p->prefixlen, &mask.sin_addr); +	mask.sin_family = p->family;  #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN -  mask.sin_len = sizeof (struct sockaddr_in); +	mask.sin_len = sizeof(struct sockaddr_in);  #endif -  memcpy (&addreq.ifra_mask, &mask, sizeof (struct sockaddr_in)); -   -  ret = if_ioctl (SIOCAIFADDR, (caddr_t) &addreq); -  if (ret < 0) -    return ret; -  return 0; +	memcpy(&addreq.ifra_mask, &mask, sizeof(struct sockaddr_in)); + +	ret = if_ioctl(SIOCAIFADDR, (caddr_t)&addreq); +	if (ret < 0) +		return ret; +	return 0;  }  /* Set up interface's IP address, netmask (and broadcas? ).  *BSD may     has ifaliasreq structure.  */ -int -if_unset_prefix (struct interface *ifp, struct connected *ifc) +int if_unset_prefix(struct interface *ifp, struct connected *ifc)  { -  int ret; -  struct ifaliasreq addreq; -  struct sockaddr_in addr; -  struct sockaddr_in mask; -  struct prefix_ipv4 *p; +	int ret; +	struct ifaliasreq addreq; +	struct sockaddr_in addr; +	struct sockaddr_in mask; +	struct prefix_ipv4 *p; -  p = (struct prefix_ipv4 *)ifc->address; +	p = (struct prefix_ipv4 *)ifc->address; -  memset (&addreq, 0, sizeof addreq); -  strncpy ((char *)&addreq.ifra_name, ifp->name, sizeof addreq.ifra_name); +	memset(&addreq, 0, sizeof addreq); +	strncpy((char *)&addreq.ifra_name, ifp->name, sizeof addreq.ifra_name); -  memset (&addr, 0, sizeof (struct sockaddr_in)); -  addr.sin_addr = p->prefix; -  addr.sin_family = p->family; +	memset(&addr, 0, sizeof(struct sockaddr_in)); +	addr.sin_addr = p->prefix; +	addr.sin_family = p->family;  #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN -  addr.sin_len = sizeof (struct sockaddr_in); +	addr.sin_len = sizeof(struct sockaddr_in);  #endif -  memcpy (&addreq.ifra_addr, &addr, sizeof (struct sockaddr_in)); +	memcpy(&addreq.ifra_addr, &addr, sizeof(struct sockaddr_in)); -  memset (&mask, 0, sizeof (struct sockaddr_in)); -  masklen2ip (p->prefixlen, &mask.sin_addr); -  mask.sin_family = p->family; +	memset(&mask, 0, sizeof(struct sockaddr_in)); +	masklen2ip(p->prefixlen, &mask.sin_addr); +	mask.sin_family = p->family;  #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN -  mask.sin_len = sizeof (struct sockaddr_in); +	mask.sin_len = sizeof(struct sockaddr_in);  #endif -  memcpy (&addreq.ifra_mask, &mask, sizeof (struct sockaddr_in)); -   -  ret = if_ioctl (SIOCDIFADDR, (caddr_t) &addreq); -  if (ret < 0) -    return ret; -  return 0; +	memcpy(&addreq.ifra_mask, &mask, sizeof(struct sockaddr_in)); + +	ret = if_ioctl(SIOCDIFADDR, (caddr_t)&addreq); +	if (ret < 0) +		return ret; +	return 0;  }  #else  /* Set up interface's address, netmask (and broadcas? ).  Linux or     Solaris uses ifname:number semantics to set IP address aliases. */ -int -if_set_prefix (struct interface *ifp, struct connected *ifc) +int if_set_prefix(struct interface *ifp, struct connected *ifc)  { -  int ret; -  struct ifreq ifreq; -  struct sockaddr_in addr; -  struct sockaddr_in broad; -  struct sockaddr_in mask; -  struct prefix_ipv4 ifaddr; -  struct prefix_ipv4 *p; - -  p = (struct prefix_ipv4 *) ifc->address; - -  ifaddr = *p; - -  ifreq_set_name (&ifreq, ifp); - -  addr.sin_addr = p->prefix; -  addr.sin_family = p->family; -  memcpy (&ifreq.ifr_addr, &addr, sizeof (struct sockaddr_in)); -  ret = if_ioctl (SIOCSIFADDR, (caddr_t) &ifreq); -  if (ret < 0) -    return ret; -   -  /* We need mask for make broadcast addr. */ -  masklen2ip (p->prefixlen, &mask.sin_addr); - -  if (if_is_broadcast (ifp)) -    { -      apply_mask_ipv4 (&ifaddr); -      addr.sin_addr = ifaddr.prefix; - -      broad.sin_addr.s_addr = (addr.sin_addr.s_addr | ~mask.sin_addr.s_addr); -      broad.sin_family = p->family; - -      memcpy (&ifreq.ifr_broadaddr, &broad, sizeof (struct sockaddr_in)); -      ret = if_ioctl (SIOCSIFBRDADDR, (caddr_t) &ifreq); -      if (ret < 0) -	return ret; -    } - -  mask.sin_family = p->family; +	int ret; +	struct ifreq ifreq; +	struct sockaddr_in addr; +	struct sockaddr_in broad; +	struct sockaddr_in mask; +	struct prefix_ipv4 ifaddr; +	struct prefix_ipv4 *p; + +	p = (struct prefix_ipv4 *)ifc->address; + +	ifaddr = *p; + +	ifreq_set_name(&ifreq, ifp); + +	addr.sin_addr = p->prefix; +	addr.sin_family = p->family; +	memcpy(&ifreq.ifr_addr, &addr, sizeof(struct sockaddr_in)); +	ret = if_ioctl(SIOCSIFADDR, (caddr_t)&ifreq); +	if (ret < 0) +		return ret; + +	/* We need mask for make broadcast addr. */ +	masklen2ip(p->prefixlen, &mask.sin_addr); + +	if (if_is_broadcast(ifp)) { +		apply_mask_ipv4(&ifaddr); +		addr.sin_addr = ifaddr.prefix; + +		broad.sin_addr.s_addr = +			(addr.sin_addr.s_addr | ~mask.sin_addr.s_addr); +		broad.sin_family = p->family; + +		memcpy(&ifreq.ifr_broadaddr, &broad, +		       sizeof(struct sockaddr_in)); +		ret = if_ioctl(SIOCSIFBRDADDR, (caddr_t)&ifreq); +		if (ret < 0) +			return ret; +	} + +	mask.sin_family = p->family;  #ifdef SUNOS_5 -  memcpy (&mask, &ifreq.ifr_addr, sizeof (mask)); +	memcpy(&mask, &ifreq.ifr_addr, sizeof(mask));  #else -  memcpy (&ifreq.ifr_netmask, &mask, sizeof (struct sockaddr_in)); +	memcpy(&ifreq.ifr_netmask, &mask, sizeof(struct sockaddr_in));  #endif /* SUNOS5 */ -  ret = if_ioctl (SIOCSIFNETMASK, (caddr_t) &ifreq); -  if (ret < 0) -    return ret; +	ret = if_ioctl(SIOCSIFNETMASK, (caddr_t)&ifreq); +	if (ret < 0) +		return ret; -  return 0; +	return 0;  }  /* Set up interface's address, netmask (and broadcas? ).  Linux or     Solaris uses ifname:number semantics to set IP address aliases. */ -int -if_unset_prefix (struct interface *ifp, struct connected *ifc) +int if_unset_prefix(struct interface *ifp, struct connected *ifc)  { -  int ret; -  struct ifreq ifreq; -  struct sockaddr_in addr; -  struct prefix_ipv4 *p; +	int ret; +	struct ifreq ifreq; +	struct sockaddr_in addr; +	struct prefix_ipv4 *p; -  p = (struct prefix_ipv4 *) ifc->address; +	p = (struct prefix_ipv4 *)ifc->address; -  ifreq_set_name (&ifreq, ifp); +	ifreq_set_name(&ifreq, ifp); -  memset (&addr, 0, sizeof (struct sockaddr_in)); -  addr.sin_family = p->family; -  memcpy (&ifreq.ifr_addr, &addr, sizeof (struct sockaddr_in)); -  ret = if_ioctl (SIOCSIFADDR, (caddr_t) &ifreq); -  if (ret < 0) -    return ret; +	memset(&addr, 0, sizeof(struct sockaddr_in)); +	addr.sin_family = p->family; +	memcpy(&ifreq.ifr_addr, &addr, sizeof(struct sockaddr_in)); +	ret = if_ioctl(SIOCSIFADDR, (caddr_t)&ifreq); +	if (ret < 0) +		return ret; -  return 0; +	return 0;  }  #endif /* HAVE_STRUCT_IFALIASREQ */  #endif /* HAVE_NETLINK */  /* get interface flags */ -void -if_get_flags (struct interface *ifp) +void if_get_flags(struct interface *ifp)  { -  int ret; -  struct ifreq ifreq; +	int ret; +	struct ifreq ifreq;  #ifdef HAVE_BSD_LINK_DETECT -  struct ifmediareq ifmr; +	struct ifmediareq ifmr;  #endif /* HAVE_BSD_LINK_DETECT */ -  ifreq_set_name (&ifreq, ifp); +	ifreq_set_name(&ifreq, ifp); -  ret = if_ioctl (SIOCGIFFLAGS, (caddr_t) &ifreq); -  if (ret < 0)  -    { -      zlog_err("if_ioctl(SIOCGIFFLAGS) failed: %s", safe_strerror(errno)); -      return; -    } +	ret = if_ioctl(SIOCGIFFLAGS, (caddr_t)&ifreq); +	if (ret < 0) { +		zlog_err("if_ioctl(SIOCGIFFLAGS) failed: %s", +			 safe_strerror(errno)); +		return; +	}  #ifdef HAVE_BSD_LINK_DETECT /* Detect BSD link-state at start-up */ -  /* Per-default, IFF_RUNNING is held high, unless link-detect says -   * otherwise - we abuse IFF_RUNNING inside zebra as a link-state flag, -   * following practice on Linux and Solaris kernels -   */ -  SET_FLAG(ifreq.ifr_flags, IFF_RUNNING); -   -  if (CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) -    { -      (void) memset(&ifmr, 0, sizeof(ifmr)); -      strncpy (ifmr.ifm_name, ifp->name, IFNAMSIZ); -       -      /* Seems not all interfaces implement this ioctl */ -      if (if_ioctl(SIOCGIFMEDIA, (caddr_t) &ifmr) < 0) -        zlog_err("if_ioctl(SIOCGIFMEDIA) failed: %s", safe_strerror(errno)); -      else if (ifmr.ifm_status & IFM_AVALID) /* Link state is valid */ -        { -          if (ifmr.ifm_status & IFM_ACTIVE) -            SET_FLAG(ifreq.ifr_flags, IFF_RUNNING); -          else -            UNSET_FLAG(ifreq.ifr_flags, IFF_RUNNING); -        } -  } +	/* Per-default, IFF_RUNNING is held high, unless link-detect says +	 * otherwise - we abuse IFF_RUNNING inside zebra as a link-state flag, +	 * following practice on Linux and Solaris kernels +	 */ +	SET_FLAG(ifreq.ifr_flags, IFF_RUNNING); + +	if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) { +		(void)memset(&ifmr, 0, sizeof(ifmr)); +		strncpy(ifmr.ifm_name, ifp->name, IFNAMSIZ); + +		/* Seems not all interfaces implement this ioctl */ +		if (if_ioctl(SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) +			zlog_err("if_ioctl(SIOCGIFMEDIA) failed: %s", +				 safe_strerror(errno)); +		else if (ifmr.ifm_status & IFM_AVALID) /* Link state is valid */ +		{ +			if (ifmr.ifm_status & IFM_ACTIVE) +				SET_FLAG(ifreq.ifr_flags, IFF_RUNNING); +			else +				UNSET_FLAG(ifreq.ifr_flags, IFF_RUNNING); +		} +	}  #endif /* HAVE_BSD_LINK_DETECT */ -  if_flags_update (ifp, (ifreq.ifr_flags & 0x0000ffff)); +	if_flags_update(ifp, (ifreq.ifr_flags & 0x0000ffff));  }  /* Set interface flags */ -int -if_set_flags (struct interface *ifp, uint64_t flags) +int if_set_flags(struct interface *ifp, uint64_t flags)  { -  int ret; -  struct ifreq ifreq; +	int ret; +	struct ifreq ifreq; -  memset (&ifreq, 0, sizeof(struct ifreq)); -  ifreq_set_name (&ifreq, ifp); +	memset(&ifreq, 0, sizeof(struct ifreq)); +	ifreq_set_name(&ifreq, ifp); -  ifreq.ifr_flags = ifp->flags; -  ifreq.ifr_flags |= flags; +	ifreq.ifr_flags = ifp->flags; +	ifreq.ifr_flags |= flags; -  ret = if_ioctl (SIOCSIFFLAGS, (caddr_t) &ifreq); +	ret = if_ioctl(SIOCSIFFLAGS, (caddr_t)&ifreq); -  if (ret < 0) -    { -      zlog_info ("can't set interface flags"); -      return ret; -    } -  return 0; +	if (ret < 0) { +		zlog_info("can't set interface flags"); +		return ret; +	} +	return 0;  }  /* Unset interface's flag. */ -int -if_unset_flags (struct interface *ifp, uint64_t flags) +int if_unset_flags(struct interface *ifp, uint64_t flags)  { -  int ret; -  struct ifreq ifreq; +	int ret; +	struct ifreq ifreq; -  memset (&ifreq, 0, sizeof(struct ifreq)); -  ifreq_set_name (&ifreq, ifp); +	memset(&ifreq, 0, sizeof(struct ifreq)); +	ifreq_set_name(&ifreq, ifp); -  ifreq.ifr_flags = ifp->flags; -  ifreq.ifr_flags &= ~flags; +	ifreq.ifr_flags = ifp->flags; +	ifreq.ifr_flags &= ~flags; -  ret = if_ioctl (SIOCSIFFLAGS, (caddr_t) &ifreq); +	ret = if_ioctl(SIOCSIFFLAGS, (caddr_t)&ifreq); -  if (ret < 0) -    { -      zlog_info ("can't unset interface flags"); -      return ret; -    } -  return 0; +	if (ret < 0) { +		zlog_info("can't unset interface flags"); +		return ret; +	} +	return 0;  }  #ifdef LINUX_IPV6  #ifndef _LINUX_IN6_H  /* linux/include/net/ipv6.h */ -struct in6_ifreq  -{ -  struct in6_addr ifr6_addr; -  u_int32_t ifr6_prefixlen; -  int ifr6_ifindex; +struct in6_ifreq { +	struct in6_addr ifr6_addr; +	u_int32_t ifr6_prefixlen; +	int ifr6_ifindex;  };  #endif /* _LINUX_IN6_H */  /* Interface's address add/delete functions. */ -int -if_prefix_add_ipv6 (struct interface *ifp, struct connected *ifc) +int if_prefix_add_ipv6(struct interface *ifp, struct connected *ifc)  { -  int ret; -  struct prefix_ipv6 *p; -  struct in6_ifreq ifreq; +	int ret; +	struct prefix_ipv6 *p; +	struct in6_ifreq ifreq; -  p = (struct prefix_ipv6 *) ifc->address; +	p = (struct prefix_ipv6 *)ifc->address; -  memset (&ifreq, 0, sizeof (struct in6_ifreq)); +	memset(&ifreq, 0, sizeof(struct in6_ifreq)); -  memcpy (&ifreq.ifr6_addr, &p->prefix, sizeof (struct in6_addr)); -  ifreq.ifr6_ifindex = ifp->ifindex; -  ifreq.ifr6_prefixlen = p->prefixlen; +	memcpy(&ifreq.ifr6_addr, &p->prefix, sizeof(struct in6_addr)); +	ifreq.ifr6_ifindex = ifp->ifindex; +	ifreq.ifr6_prefixlen = p->prefixlen; -  ret = if_ioctl_ipv6 (SIOCSIFADDR, (caddr_t) &ifreq); +	ret = if_ioctl_ipv6(SIOCSIFADDR, (caddr_t)&ifreq); -  return ret; +	return ret;  } -int -if_prefix_delete_ipv6 (struct interface *ifp, struct connected *ifc) +int if_prefix_delete_ipv6(struct interface *ifp, struct connected *ifc)  { -  int ret; -  struct prefix_ipv6 *p; -  struct in6_ifreq ifreq; +	int ret; +	struct prefix_ipv6 *p; +	struct in6_ifreq ifreq; -  p = (struct prefix_ipv6 *) ifc->address; +	p = (struct prefix_ipv6 *)ifc->address; -  memset (&ifreq, 0, sizeof (struct in6_ifreq)); +	memset(&ifreq, 0, sizeof(struct in6_ifreq)); -  memcpy (&ifreq.ifr6_addr, &p->prefix, sizeof (struct in6_addr)); -  ifreq.ifr6_ifindex = ifp->ifindex; -  ifreq.ifr6_prefixlen = p->prefixlen; +	memcpy(&ifreq.ifr6_addr, &p->prefix, sizeof(struct in6_addr)); +	ifreq.ifr6_ifindex = ifp->ifindex; +	ifreq.ifr6_prefixlen = p->prefixlen; -  ret = if_ioctl_ipv6 (SIOCDIFADDR, (caddr_t) &ifreq); +	ret = if_ioctl_ipv6(SIOCDIFADDR, (caddr_t)&ifreq); -  return ret; +	return ret;  }  #else /* LINUX_IPV6 */  #ifdef HAVE_STRUCT_IN6_ALIASREQ  #ifndef ND6_INFINITE_LIFETIME  #define ND6_INFINITE_LIFETIME 0xffffffffL  #endif /* ND6_INFINITE_LIFETIME */ -int -if_prefix_add_ipv6 (struct interface *ifp, struct connected *ifc) +int if_prefix_add_ipv6(struct interface *ifp, struct connected *ifc)  { -  int ret; -  struct in6_aliasreq addreq; -  struct sockaddr_in6 addr; -  struct sockaddr_in6 mask; -  struct prefix_ipv6 *p; +	int ret; +	struct in6_aliasreq addreq; +	struct sockaddr_in6 addr; +	struct sockaddr_in6 mask; +	struct prefix_ipv6 *p; -  p = (struct prefix_ipv6 * ) ifc->address; +	p = (struct prefix_ipv6 *)ifc->address; -  memset (&addreq, 0, sizeof addreq); -  strncpy ((char *)&addreq.ifra_name, ifp->name, sizeof addreq.ifra_name); +	memset(&addreq, 0, sizeof addreq); +	strncpy((char *)&addreq.ifra_name, ifp->name, sizeof addreq.ifra_name); -  memset (&addr, 0, sizeof (struct sockaddr_in6)); -  addr.sin6_addr = p->prefix; -  addr.sin6_family = p->family; +	memset(&addr, 0, sizeof(struct sockaddr_in6)); +	addr.sin6_addr = p->prefix; +	addr.sin6_family = p->family;  #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN -  addr.sin6_len = sizeof (struct sockaddr_in6); +	addr.sin6_len = sizeof(struct sockaddr_in6);  #endif -  memcpy (&addreq.ifra_addr, &addr, sizeof (struct sockaddr_in6)); +	memcpy(&addreq.ifra_addr, &addr, sizeof(struct sockaddr_in6)); -  memset (&mask, 0, sizeof (struct sockaddr_in6)); -  masklen2ip6 (p->prefixlen, &mask.sin6_addr); -  mask.sin6_family = p->family; +	memset(&mask, 0, sizeof(struct sockaddr_in6)); +	masklen2ip6(p->prefixlen, &mask.sin6_addr); +	mask.sin6_family = p->family;  #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN -  mask.sin6_len = sizeof (struct sockaddr_in6); +	mask.sin6_len = sizeof(struct sockaddr_in6);  #endif -  memcpy (&addreq.ifra_prefixmask, &mask, sizeof (struct sockaddr_in6)); - -  addreq.ifra_lifetime.ia6t_vltime = 0xffffffff; -  addreq.ifra_lifetime.ia6t_pltime = 0xffffffff; -   -#ifdef HAVE_STRUCT_IF6_ALIASREQ_IFRA_LIFETIME  -  addreq.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;  -  addreq.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;  +	memcpy(&addreq.ifra_prefixmask, &mask, sizeof(struct sockaddr_in6)); + +	addreq.ifra_lifetime.ia6t_vltime = 0xffffffff; +	addreq.ifra_lifetime.ia6t_pltime = 0xffffffff; + +#ifdef HAVE_STRUCT_IF6_ALIASREQ_IFRA_LIFETIME +	addreq.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME; +	addreq.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;  #endif -  ret = if_ioctl_ipv6 (SIOCAIFADDR_IN6, (caddr_t) &addreq); -  if (ret < 0) -    return ret; -  return 0; +	ret = if_ioctl_ipv6(SIOCAIFADDR_IN6, (caddr_t)&addreq); +	if (ret < 0) +		return ret; +	return 0;  } -int -if_prefix_delete_ipv6 (struct interface *ifp, struct connected *ifc) +int if_prefix_delete_ipv6(struct interface *ifp, struct connected *ifc)  { -  int ret; -  struct in6_aliasreq addreq; -  struct sockaddr_in6 addr; -  struct sockaddr_in6 mask; -  struct prefix_ipv6 *p; +	int ret; +	struct in6_aliasreq addreq; +	struct sockaddr_in6 addr; +	struct sockaddr_in6 mask; +	struct prefix_ipv6 *p; -  p = (struct prefix_ipv6 *) ifc->address; +	p = (struct prefix_ipv6 *)ifc->address; -  memset (&addreq, 0, sizeof addreq); -  strncpy ((char *)&addreq.ifra_name, ifp->name, sizeof addreq.ifra_name); +	memset(&addreq, 0, sizeof addreq); +	strncpy((char *)&addreq.ifra_name, ifp->name, sizeof addreq.ifra_name); -  memset (&addr, 0, sizeof (struct sockaddr_in6)); -  addr.sin6_addr = p->prefix; -  addr.sin6_family = p->family; +	memset(&addr, 0, sizeof(struct sockaddr_in6)); +	addr.sin6_addr = p->prefix; +	addr.sin6_family = p->family;  #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN -  addr.sin6_len = sizeof (struct sockaddr_in6); +	addr.sin6_len = sizeof(struct sockaddr_in6);  #endif -  memcpy (&addreq.ifra_addr, &addr, sizeof (struct sockaddr_in6)); +	memcpy(&addreq.ifra_addr, &addr, sizeof(struct sockaddr_in6)); -  memset (&mask, 0, sizeof (struct sockaddr_in6)); -  masklen2ip6 (p->prefixlen, &mask.sin6_addr); -  mask.sin6_family = p->family; +	memset(&mask, 0, sizeof(struct sockaddr_in6)); +	masklen2ip6(p->prefixlen, &mask.sin6_addr); +	mask.sin6_family = p->family;  #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN -  mask.sin6_len = sizeof (struct sockaddr_in6); +	mask.sin6_len = sizeof(struct sockaddr_in6);  #endif -  memcpy (&addreq.ifra_prefixmask, &mask, sizeof (struct sockaddr_in6)); +	memcpy(&addreq.ifra_prefixmask, &mask, sizeof(struct sockaddr_in6));  #ifdef HAVE_STRUCT_IF6_ALIASREQ_IFRA_LIFETIME -  addreq.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;  -  addreq.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;  +	addreq.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME; +	addreq.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;  #endif -  ret = if_ioctl_ipv6 (SIOCDIFADDR_IN6, (caddr_t) &addreq); -  if (ret < 0) -    return ret; -  return 0; +	ret = if_ioctl_ipv6(SIOCDIFADDR_IN6, (caddr_t)&addreq); +	if (ret < 0) +		return ret; +	return 0;  }  #else -int -if_prefix_add_ipv6 (struct interface *ifp, struct connected *ifc) +int if_prefix_add_ipv6(struct interface *ifp, struct connected *ifc)  { -  return 0; +	return 0;  } -int -if_prefix_delete_ipv6 (struct interface *ifp, struct connected *ifc) +int if_prefix_delete_ipv6(struct interface *ifp, struct connected *ifc)  { -  return 0; +	return 0;  }  #endif /* HAVE_STRUCT_IN6_ALIASREQ */ diff --git a/zebra/ioctl.h b/zebra/ioctl.h index 9e3fd5b3fb..e78af3044e 100644 --- a/zebra/ioctl.h +++ b/zebra/ioctl.h @@ -17,37 +17,37 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #ifndef _ZEBRA_IOCTL_H  #define _ZEBRA_IOCTL_H  /* Prototypes. */ -extern void ifreq_set_name (struct ifreq *, struct interface *); -extern int if_ioctl (u_long, caddr_t); +extern void ifreq_set_name(struct ifreq *, struct interface *); +extern int if_ioctl(u_long, caddr_t); -extern int if_set_flags (struct interface *, uint64_t); -extern int if_unset_flags (struct interface *, uint64_t); -extern void if_get_flags (struct interface *); +extern int if_set_flags(struct interface *, uint64_t); +extern int if_unset_flags(struct interface *, uint64_t); +extern void if_get_flags(struct interface *); -extern int if_set_prefix (struct interface *, struct connected *); -extern int if_unset_prefix (struct interface *, struct connected *); +extern int if_set_prefix(struct interface *, struct connected *); +extern int if_unset_prefix(struct interface *, struct connected *); -extern void if_get_metric (struct interface *); -extern void if_get_mtu (struct interface *); +extern void if_get_metric(struct interface *); +extern void if_get_mtu(struct interface *); -extern int if_prefix_add_ipv6 (struct interface *, struct connected *); -extern int if_prefix_delete_ipv6 (struct interface *, struct connected *); +extern int if_prefix_add_ipv6(struct interface *, struct connected *); +extern int if_prefix_delete_ipv6(struct interface *, struct connected *);  #ifdef SOLARIS_IPV6  extern int if_ioctl_ipv6(u_long, caddr_t); -extern struct connected *if_lookup_linklocal( struct interface *); +extern struct connected *if_lookup_linklocal(struct interface *); -#define AF_IOCTL(af, request, buffer) \ -        ((af) == AF_INET? if_ioctl(request, buffer) : \ -                          if_ioctl_ipv6(request, buffer)) -#else /* SOLARIS_IPV6 */ +#define AF_IOCTL(af, request, buffer)                                          \ +	((af) == AF_INET ? if_ioctl(request, buffer)                           \ +			 : if_ioctl_ipv6(request, buffer)) +#else  /* SOLARIS_IPV6 */  #define AF_IOCTL(af, request, buffer)  if_ioctl(request, buffer) diff --git a/zebra/ioctl_null.c b/zebra/ioctl_null.c index c2060e90a1..0013de20ef 100644 --- a/zebra/ioctl_null.c +++ b/zebra/ioctl_null.c @@ -1,4 +1,4 @@ -/*  +/*   * Copyright (C) 2006 Sun Microsystems, Inc.   *   * This file is part of Quagga. @@ -16,7 +16,7 @@   * You should have received a copy of the GNU General Public License   * along with Quagga; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #include <zebra.h> @@ -25,38 +25,62 @@  #include "zebra/rt.h"  #include "zebra/ioctl.h" -void ifreq_set_name (struct ifreq *a, struct interface *b) { return; } +void ifreq_set_name(struct ifreq *a, struct interface *b) +{ +	return; +} -int if_set_prefix (struct interface *a, struct connected *b) -{  -  kernel_address_add_ipv4 (a, b); -  return 0; +int if_set_prefix(struct interface *a, struct connected *b) +{ +	kernel_address_add_ipv4(a, b); +	return 0;  } -int if_unset_prefix (struct interface *a, struct connected *b) -{  -  kernel_address_delete_ipv4 (a, b); -  return 0; +int if_unset_prefix(struct interface *a, struct connected *b) +{ +	kernel_address_delete_ipv4(a, b); +	return 0;  } -int if_prefix_add_ipv6 (struct interface *a, struct connected *b) { return 0; } -int if_prefix_delete_ipv6 (struct interface *a, struct connected *b) { return 0; } +int if_prefix_add_ipv6(struct interface *a, struct connected *b) +{ +	return 0; +} +int if_prefix_delete_ipv6(struct interface *a, struct connected *b) +{ +	return 0; +} -int if_ioctl (u_long a, caddr_t b) { return 0; } +int if_ioctl(u_long a, caddr_t b) +{ +	return 0; +} -int if_set_flags (struct interface *a, uint64_t b) { return 0; } -int if_unset_flags (struct interface *a, uint64_t b) { return 0; } +int if_set_flags(struct interface *a, uint64_t b) +{ +	return 0; +} +int if_unset_flags(struct interface *a, uint64_t b) +{ +	return 0; +} -void if_get_flags (struct interface *a) { return; } +void if_get_flags(struct interface *a) +{ +	return; +}  #ifdef SOLARIS_IPV6  #pragma weak if_ioctl_ipv6 = if_ioctl -struct connected *if_lookup_linklocal(struct interface *a) { return 0; } +struct connected *if_lookup_linklocal(struct interface *a) +{ +	return 0; +} -#define AF_IOCTL(af, request, buffer) \ -        ((af) == AF_INET? if_ioctl(request, buffer) : \ -                          if_ioctl_ipv6(request, buffer)) -#else /* SOLARIS_IPV6 */ +#define AF_IOCTL(af, request, buffer)                                          \ +	((af) == AF_INET ? if_ioctl(request, buffer)                           \ +			 : if_ioctl_ipv6(request, buffer)) +#else  /* SOLARIS_IPV6 */  #define AF_IOCTL(af, request, buffer)  if_ioctl(request, buffer) diff --git a/zebra/ioctl_solaris.c b/zebra/ioctl_solaris.c index 78796a8a28..ac27b477e5 100644 --- a/zebra/ioctl_solaris.c +++ b/zebra/ioctl_solaris.c @@ -17,7 +17,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #include <zebra.h> @@ -38,245 +38,231 @@  extern struct zebra_privs_t zserv_privs;  /* clear and set interface name string */ -void -lifreq_set_name (struct lifreq *lifreq, const char *ifname) +void lifreq_set_name(struct lifreq *lifreq, const char *ifname)  { -  strncpy (lifreq->lifr_name, ifname, IFNAMSIZ); +	strncpy(lifreq->lifr_name, ifname, IFNAMSIZ);  }  /* call ioctl system call */ -int -if_ioctl (u_long request, caddr_t buffer) +int if_ioctl(u_long request, caddr_t buffer)  { -  int sock; -  int ret; -  int err; - -  if (zserv_privs.change(ZPRIVS_RAISE)) -    zlog_err("Can't raise privileges"); -     -  sock = socket (AF_INET, SOCK_DGRAM, 0); -  if (sock < 0) -    { -      int save_errno = errno; -      if (zserv_privs.change(ZPRIVS_LOWER)) -        zlog_err("Can't lower privileges"); -      zlog_err("Cannot create UDP socket: %s", safe_strerror(save_errno)); -      exit (1); -    } - -  if ((ret = ioctl (sock, request, buffer)) < 0) -    err = errno; -   -  if (zserv_privs.change(ZPRIVS_LOWER)) -    zlog_err("Can't lower privileges"); - -  close (sock); - -  if (ret < 0) -    { -      errno = err; -      return ret; -    } -  return 0; +	int sock; +	int ret; +	int err; + +	if (zserv_privs.change(ZPRIVS_RAISE)) +		zlog_err("Can't raise privileges"); + +	sock = socket(AF_INET, SOCK_DGRAM, 0); +	if (sock < 0) { +		int save_errno = errno; +		if (zserv_privs.change(ZPRIVS_LOWER)) +			zlog_err("Can't lower privileges"); +		zlog_err("Cannot create UDP socket: %s", +			 safe_strerror(save_errno)); +		exit(1); +	} + +	if ((ret = ioctl(sock, request, buffer)) < 0) +		err = errno; + +	if (zserv_privs.change(ZPRIVS_LOWER)) +		zlog_err("Can't lower privileges"); + +	close(sock); + +	if (ret < 0) { +		errno = err; +		return ret; +	} +	return 0;  } -int -if_ioctl_ipv6 (u_long request, caddr_t buffer) +int if_ioctl_ipv6(u_long request, caddr_t buffer)  { -  int sock; -  int ret; -  int err; - -  if (zserv_privs.change(ZPRIVS_RAISE)) -    zlog_err("Can't raise privileges"); - -  sock = socket (AF_INET6, SOCK_DGRAM, 0); -  if (sock < 0) -    { -      int save_errno = errno; -      if (zserv_privs.change(ZPRIVS_LOWER)) -        zlog_err("Can't lower privileges"); -      zlog_err("Cannot create IPv6 datagram socket: %s", -	       safe_strerror(save_errno)); -      exit (1); -    } - -  if ((ret = ioctl (sock, request, buffer)) < 0) -    err = errno; - -  if (zserv_privs.change(ZPRIVS_LOWER)) -    zlog_err("Can't lower privileges"); - -  close (sock); - -  if (ret < 0) -    { -      errno = err; -      return ret; -    } - -  return 0; +	int sock; +	int ret; +	int err; + +	if (zserv_privs.change(ZPRIVS_RAISE)) +		zlog_err("Can't raise privileges"); + +	sock = socket(AF_INET6, SOCK_DGRAM, 0); +	if (sock < 0) { +		int save_errno = errno; +		if (zserv_privs.change(ZPRIVS_LOWER)) +			zlog_err("Can't lower privileges"); +		zlog_err("Cannot create IPv6 datagram socket: %s", +			 safe_strerror(save_errno)); +		exit(1); +	} + +	if ((ret = ioctl(sock, request, buffer)) < 0) +		err = errno; + +	if (zserv_privs.change(ZPRIVS_LOWER)) +		zlog_err("Can't lower privileges"); + +	close(sock); + +	if (ret < 0) { +		errno = err; +		return ret; +	} + +	return 0;  }  /*   * get interface metric   *   -- if value is not avaliable set -1   */ -void -if_get_metric (struct interface *ifp) +void if_get_metric(struct interface *ifp)  { -  struct lifreq lifreq; -  int ret; +	struct lifreq lifreq; +	int ret; -  lifreq_set_name (&lifreq, ifp->name); +	lifreq_set_name(&lifreq, ifp->name); -  if (ifp->flags & IFF_IPV4) -    ret = AF_IOCTL (AF_INET, SIOCGLIFMETRIC, (caddr_t) & lifreq); +	if (ifp->flags & IFF_IPV4) +		ret = AF_IOCTL(AF_INET, SIOCGLIFMETRIC, (caddr_t)&lifreq);  #ifdef SOLARIS_IPV6 -  else if (ifp->flags & IFF_IPV6) -    ret = AF_IOCTL (AF_INET6, SIOCGLIFMETRIC, (caddr_t) & lifreq); +	else if (ifp->flags & IFF_IPV6) +		ret = AF_IOCTL(AF_INET6, SIOCGLIFMETRIC, (caddr_t)&lifreq);  #endif /* SOLARIS_IPV6 */ -  else -    ret = -1; -     -  if (ret < 0) -    return; +	else +		ret = -1; -  ifp->metric = lifreq.lifr_metric; +	if (ret < 0) +		return; -  if (ifp->metric == 0) -    ifp->metric = 1; +	ifp->metric = lifreq.lifr_metric; + +	if (ifp->metric == 0) +		ifp->metric = 1;  }  /* get interface MTU */ -void -if_get_mtu (struct interface *ifp) +void if_get_mtu(struct interface *ifp)  { -  struct lifreq lifreq; -  int ret; -  u_char changed = 0; -   -  if (ifp->flags & IFF_IPV4) -    { -      lifreq_set_name (&lifreq, ifp->name); -      ret = AF_IOCTL (AF_INET, SIOCGLIFMTU, (caddr_t) & lifreq); -      if (ret < 0) -        { -          zlog_info ("Can't lookup mtu on %s by ioctl(SIOCGLIFMTU)", -                     ifp->name); -          ifp->mtu = -1; -        } -      else -        { -          ifp->mtu = lifreq.lifr_metric; -          changed = 1; -        } -    } - -  if (ifp->flags & IFF_IPV6) -  { -    memset(&lifreq, 0, sizeof(lifreq)); -    lifreq_set_name (&lifreq, ifp->name); - -    ret = AF_IOCTL (AF_INET6, SIOCGLIFMTU, (caddr_t) & lifreq); -    if (ret < 0) -    { -      zlog_info ("Can't lookup mtu6 on %s by ioctl(SIOCGIFMTU)", ifp->name); -      ifp->mtu6 = -1; -    } -    else -    { -      ifp->mtu6 = lifreq.lifr_metric; -      changed = 1; -    } -  } - -  if (changed) -    zebra_interface_up_update(ifp); +	struct lifreq lifreq; +	int ret; +	u_char changed = 0; + +	if (ifp->flags & IFF_IPV4) { +		lifreq_set_name(&lifreq, ifp->name); +		ret = AF_IOCTL(AF_INET, SIOCGLIFMTU, (caddr_t)&lifreq); +		if (ret < 0) { +			zlog_info( +				"Can't lookup mtu on %s by ioctl(SIOCGLIFMTU)", +				ifp->name); +			ifp->mtu = -1; +		} else { +			ifp->mtu = lifreq.lifr_metric; +			changed = 1; +		} +	} + +	if (ifp->flags & IFF_IPV6) { +		memset(&lifreq, 0, sizeof(lifreq)); +		lifreq_set_name(&lifreq, ifp->name); + +		ret = AF_IOCTL(AF_INET6, SIOCGLIFMTU, (caddr_t)&lifreq); +		if (ret < 0) { +			zlog_info( +				"Can't lookup mtu6 on %s by ioctl(SIOCGIFMTU)", +				ifp->name); +			ifp->mtu6 = -1; +		} else { +			ifp->mtu6 = lifreq.lifr_metric; +			changed = 1; +		} +	} + +	if (changed) +		zebra_interface_up_update(ifp);  }  /* Set up interface's address, netmask (and broadcast? ).     Solaris uses ifname:number semantics to set IP address aliases. */ -int -if_set_prefix (struct interface *ifp, struct connected *ifc) +int if_set_prefix(struct interface *ifp, struct connected *ifc)  { -  int ret; -  struct ifreq ifreq; -  struct sockaddr_in addr; -  struct sockaddr_in broad; -  struct sockaddr_in mask; -  struct prefix_ipv4 ifaddr; -  struct prefix_ipv4 *p; +	int ret; +	struct ifreq ifreq; +	struct sockaddr_in addr; +	struct sockaddr_in broad; +	struct sockaddr_in mask; +	struct prefix_ipv4 ifaddr; +	struct prefix_ipv4 *p; -  p = (struct prefix_ipv4 *) ifc->address; +	p = (struct prefix_ipv4 *)ifc->address; -  ifaddr = *p; +	ifaddr = *p; -  strncpy (ifreq.ifr_name, ifp->name, IFNAMSIZ); +	strncpy(ifreq.ifr_name, ifp->name, IFNAMSIZ); -  addr.sin_addr = p->prefix; -  addr.sin_family = p->family; -  memcpy (&ifreq.ifr_addr, &addr, sizeof (struct sockaddr_in)); +	addr.sin_addr = p->prefix; +	addr.sin_family = p->family; +	memcpy(&ifreq.ifr_addr, &addr, sizeof(struct sockaddr_in)); -  ret = if_ioctl (SIOCSIFADDR, (caddr_t) & ifreq); +	ret = if_ioctl(SIOCSIFADDR, (caddr_t)&ifreq); -  if (ret < 0) -    return ret; +	if (ret < 0) +		return ret; -  /* We need mask for make broadcast addr. */ -  masklen2ip (p->prefixlen, &mask.sin_addr); +	/* We need mask for make broadcast addr. */ +	masklen2ip(p->prefixlen, &mask.sin_addr); -  if (if_is_broadcast (ifp)) -    { -      apply_mask_ipv4 (&ifaddr); -      addr.sin_addr = ifaddr.prefix; +	if (if_is_broadcast(ifp)) { +		apply_mask_ipv4(&ifaddr); +		addr.sin_addr = ifaddr.prefix; -      broad.sin_addr.s_addr = (addr.sin_addr.s_addr | ~mask.sin_addr.s_addr); -      broad.sin_family = p->family; +		broad.sin_addr.s_addr = +			(addr.sin_addr.s_addr | ~mask.sin_addr.s_addr); +		broad.sin_family = p->family; -      memcpy (&ifreq.ifr_broadaddr, &broad, sizeof (struct sockaddr_in)); -      ret = if_ioctl (SIOCSIFBRDADDR, (caddr_t) & ifreq); -      if (ret < 0) -        return ret; -    } +		memcpy(&ifreq.ifr_broadaddr, &broad, +		       sizeof(struct sockaddr_in)); +		ret = if_ioctl(SIOCSIFBRDADDR, (caddr_t)&ifreq); +		if (ret < 0) +			return ret; +	} -  mask.sin_family = p->family; +	mask.sin_family = p->family;  #ifdef SUNOS_5 -  memcpy (&mask, &ifreq.ifr_addr, sizeof (mask)); +	memcpy(&mask, &ifreq.ifr_addr, sizeof(mask));  #else -  memcpy (&ifreq.ifr_netmask, &mask, sizeof (struct sockaddr_in)); +	memcpy(&ifreq.ifr_netmask, &mask, sizeof(struct sockaddr_in));  #endif /* SUNOS_5 */ -  ret = if_ioctl (SIOCSIFNETMASK, (caddr_t) & ifreq); +	ret = if_ioctl(SIOCSIFNETMASK, (caddr_t)&ifreq); -  return ((ret < 0) ? ret : 0); +	return ((ret < 0) ? ret : 0);  }  /* Set up interface's address, netmask (and broadcast).     Solaris uses ifname:number semantics to set IP address aliases. */ -int -if_unset_prefix (struct interface *ifp, struct connected *ifc) +int if_unset_prefix(struct interface *ifp, struct connected *ifc)  { -  int ret; -  struct ifreq ifreq; -  struct sockaddr_in addr; -  struct prefix_ipv4 *p; +	int ret; +	struct ifreq ifreq; +	struct sockaddr_in addr; +	struct prefix_ipv4 *p; + +	p = (struct prefix_ipv4 *)ifc->address; -  p = (struct prefix_ipv4 *) ifc->address; +	strncpy(ifreq.ifr_name, ifp->name, IFNAMSIZ); -  strncpy (ifreq.ifr_name, ifp->name, IFNAMSIZ); +	memset(&addr, 0, sizeof(struct sockaddr_in)); +	addr.sin_family = p->family; +	memcpy(&ifreq.ifr_addr, &addr, sizeof(struct sockaddr_in)); -  memset (&addr, 0, sizeof (struct sockaddr_in)); -  addr.sin_family = p->family; -  memcpy (&ifreq.ifr_addr, &addr, sizeof (struct sockaddr_in)); +	ret = if_ioctl(SIOCSIFADDR, (caddr_t)&ifreq); -  ret = if_ioctl (SIOCSIFADDR, (caddr_t) & ifreq); -   -  if (ret < 0) -    return ret; +	if (ret < 0) +		return ret; -  return 0; +	return 0;  }  /* Get just the flags for the given name. @@ -284,144 +270,132 @@ if_unset_prefix (struct interface *ifp, struct connected *ifc)   * as the bootup interface-list code, which has to peek at per-address   * flags in order to figure out which ones should be ignored..   */ -int -if_get_flags_direct (const char *ifname, uint64_t *flags, unsigned int af) +int if_get_flags_direct(const char *ifname, uint64_t *flags, unsigned int af)  { -  struct lifreq lifreq; -  int ret; -     -  lifreq_set_name (&lifreq, ifname); -   -  ret = AF_IOCTL (af, SIOCGLIFFLAGS, (caddr_t) &lifreq); -   -  if (ret) -    zlog_debug ("%s: ifname %s, error %s (%d)", -                __func__, ifname, safe_strerror (errno), errno); -   -  *flags = lifreq.lifr_flags; -   -  return ret; +	struct lifreq lifreq; +	int ret; + +	lifreq_set_name(&lifreq, ifname); + +	ret = AF_IOCTL(af, SIOCGLIFFLAGS, (caddr_t)&lifreq); + +	if (ret) +		zlog_debug("%s: ifname %s, error %s (%d)", __func__, ifname, +			   safe_strerror(errno), errno); + +	*flags = lifreq.lifr_flags; + +	return ret;  }  /* get interface flags */ -void -if_get_flags (struct interface *ifp) +void if_get_flags(struct interface *ifp)  { -  int ret4 = 0, ret6 = 0; -  uint64_t newflags = 0; -  uint64_t tmpflags; - -  if (ifp->flags & IFF_IPV4) -    { -      ret4 = if_get_flags_direct (ifp->name, &tmpflags, AF_INET); -       -      if (!ret4) -        newflags |= tmpflags; -      else if (errno == ENXIO) -        { -          /* it's gone */ -          UNSET_FLAG (ifp->flags, IFF_UP); -          if_flags_update (ifp, ifp->flags); -        } -    } - -  if (ifp->flags & IFF_IPV6) -    { -      ret6 = if_get_flags_direct (ifp->name, &tmpflags, AF_INET6); -       -      if (!ret6) -        newflags |= tmpflags; -      else if (errno == ENXIO) -        { -          /* it's gone */ -          UNSET_FLAG (ifp->flags, IFF_UP); -          if_flags_update (ifp, ifp->flags); -        } -    } -   -  /* only update flags if one of above succeeded */ -  if ( !(ret4 && ret6) ) -    if_flags_update (ifp, newflags); +	int ret4 = 0, ret6 = 0; +	uint64_t newflags = 0; +	uint64_t tmpflags; + +	if (ifp->flags & IFF_IPV4) { +		ret4 = if_get_flags_direct(ifp->name, &tmpflags, AF_INET); + +		if (!ret4) +			newflags |= tmpflags; +		else if (errno == ENXIO) { +			/* it's gone */ +			UNSET_FLAG(ifp->flags, IFF_UP); +			if_flags_update(ifp, ifp->flags); +		} +	} + +	if (ifp->flags & IFF_IPV6) { +		ret6 = if_get_flags_direct(ifp->name, &tmpflags, AF_INET6); + +		if (!ret6) +			newflags |= tmpflags; +		else if (errno == ENXIO) { +			/* it's gone */ +			UNSET_FLAG(ifp->flags, IFF_UP); +			if_flags_update(ifp, ifp->flags); +		} +	} + +	/* only update flags if one of above succeeded */ +	if (!(ret4 && ret6)) +		if_flags_update(ifp, newflags);  }  /* Set interface flags */ -int -if_set_flags (struct interface *ifp, uint64_t flags) +int if_set_flags(struct interface *ifp, uint64_t flags)  { -  int ret; -  struct lifreq lifreq; - -  lifreq_set_name (&lifreq, ifp->name); - -  lifreq.lifr_flags = ifp->flags; -  lifreq.lifr_flags |= flags; - -  if (ifp->flags & IFF_IPV4) -    ret = AF_IOCTL (AF_INET, SIOCSLIFFLAGS, (caddr_t) & lifreq); -  else if (ifp->flags & IFF_IPV6) -    ret = AF_IOCTL (AF_INET6, SIOCSLIFFLAGS, (caddr_t) & lifreq); -  else -    ret = -1; - -  if (ret < 0) -    zlog_info ("can't set interface flags on %s: %s", ifp->name, -               safe_strerror (errno)); -  else -    ret = 0; -     -  return ret; +	int ret; +	struct lifreq lifreq; + +	lifreq_set_name(&lifreq, ifp->name); + +	lifreq.lifr_flags = ifp->flags; +	lifreq.lifr_flags |= flags; + +	if (ifp->flags & IFF_IPV4) +		ret = AF_IOCTL(AF_INET, SIOCSLIFFLAGS, (caddr_t)&lifreq); +	else if (ifp->flags & IFF_IPV6) +		ret = AF_IOCTL(AF_INET6, SIOCSLIFFLAGS, (caddr_t)&lifreq); +	else +		ret = -1; + +	if (ret < 0) +		zlog_info("can't set interface flags on %s: %s", ifp->name, +			  safe_strerror(errno)); +	else +		ret = 0; + +	return ret;  }  /* Unset interface's flag. */ -int -if_unset_flags (struct interface *ifp, uint64_t flags) +int if_unset_flags(struct interface *ifp, uint64_t flags)  { -  int ret; -  struct lifreq lifreq; - -  lifreq_set_name (&lifreq, ifp->name); - -  lifreq.lifr_flags = ifp->flags; -  lifreq.lifr_flags &= ~flags; - -  if (ifp->flags & IFF_IPV4) -    ret = AF_IOCTL (AF_INET, SIOCSLIFFLAGS, (caddr_t) & lifreq); -  else if (ifp->flags & IFF_IPV6) -    ret = AF_IOCTL (AF_INET6, SIOCSLIFFLAGS, (caddr_t) & lifreq); -  else -    ret = -1; - -  if (ret < 0) -    zlog_info ("can't unset interface flags"); -  else -    ret = 0; -   -  return ret; +	int ret; +	struct lifreq lifreq; + +	lifreq_set_name(&lifreq, ifp->name); + +	lifreq.lifr_flags = ifp->flags; +	lifreq.lifr_flags &= ~flags; + +	if (ifp->flags & IFF_IPV4) +		ret = AF_IOCTL(AF_INET, SIOCSLIFFLAGS, (caddr_t)&lifreq); +	else if (ifp->flags & IFF_IPV6) +		ret = AF_IOCTL(AF_INET6, SIOCSLIFFLAGS, (caddr_t)&lifreq); +	else +		ret = -1; + +	if (ret < 0) +		zlog_info("can't unset interface flags"); +	else +		ret = 0; + +	return ret;  }  /* Interface's address add/delete functions. */ -int -if_prefix_add_ipv6 (struct interface *ifp, struct connected *ifc) +int if_prefix_add_ipv6(struct interface *ifp, struct connected *ifc)  { -  char addrbuf[PREFIX_STRLEN]; - -  zlog_warn ("Can't set %s on interface %s", -             prefix2str(ifc->address, addrbuf, sizeof(addrbuf)), -             ifp->name); +	char addrbuf[PREFIX_STRLEN]; -  return 0; +	zlog_warn("Can't set %s on interface %s", +		  prefix2str(ifc->address, addrbuf, sizeof(addrbuf)), +		  ifp->name); +	return 0;  } -int -if_prefix_delete_ipv6 (struct interface *ifp, struct connected *ifc) +int if_prefix_delete_ipv6(struct interface *ifp, struct connected *ifc)  { -  char addrbuf[PREFIX_STRLEN]; - -  zlog_warn ("Can't delete %s on interface %s", -             prefix2str(ifc->address, addrbuf, sizeof(addrbuf)), -             ifp->name); +	char addrbuf[PREFIX_STRLEN]; -  return 0; +	zlog_warn("Can't delete %s on interface %s", +		  prefix2str(ifc->address, addrbuf, sizeof(addrbuf)), +		  ifp->name); +	return 0;  } diff --git a/zebra/ioctl_solaris.h b/zebra/ioctl_solaris.h index 188986be16..cb3d745d79 100644 --- a/zebra/ioctl_solaris.h +++ b/zebra/ioctl_solaris.h @@ -23,7 +23,7 @@  #ifndef _ZEBRA_IF_IOCTL_SOLARIS_H  #define _ZEBRA_IF_IOCTL_SOLARIS_H -void lifreq_set_name (struct lifreq *, const char *); -int if_get_flags_direct (const char *, uint64_t *, unsigned int af); +void lifreq_set_name(struct lifreq *, const char *); +int if_get_flags_direct(const char *, uint64_t *, unsigned int af);  #endif /* _ZEBRA_IF_IOCTL_SOLARIS_H */ diff --git a/zebra/ipforward.h b/zebra/ipforward.h index a75073cb36..aa916d47dd 100644 --- a/zebra/ipforward.h +++ b/zebra/ipforward.h @@ -14,20 +14,20 @@   * General Public License for more details.   *   * You should have received a copy of the GNU General Public License - * along with GNU Zebra; see the file COPYING.  If not, write to the  - * Free Software Foundation, Inc., 59 Temple Place - Suite 330,  - * Boston, MA 02111-1307, USA.   + * along with GNU Zebra; see the file COPYING.  If not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA.   */  #ifndef _ZEBRA_IPFORWARD_H  #define _ZEBRA_IPFORWARD_H -extern int ipforward (void); -extern int ipforward_on (void); -extern int ipforward_off (void); +extern int ipforward(void); +extern int ipforward_on(void); +extern int ipforward_off(void); -extern int ipforward_ipv6 (void); -extern int ipforward_ipv6_on (void); -extern int ipforward_ipv6_off (void); +extern int ipforward_ipv6(void); +extern int ipforward_ipv6_on(void); +extern int ipforward_ipv6_off(void);  #endif /* _ZEBRA_IPFORWARD_H */ diff --git a/zebra/ipforward_proc.c b/zebra/ipforward_proc.c index 910fd61d06..558bad1f54 100644 --- a/zebra/ipforward_proc.c +++ b/zebra/ipforward_proc.c @@ -17,7 +17,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #include <zebra.h> @@ -31,169 +31,166 @@ extern struct zebra_privs_t zserv_privs;  char proc_net_snmp[] = "/proc/net/snmp"; -static void -dropline (FILE *fp) +static void dropline(FILE *fp)  { -  int c; +	int c; -  while ((c = getc (fp)) != '\n') -    ; +	while ((c = getc(fp)) != '\n') +		;  } -int -ipforward (void) +int ipforward(void)  { -  FILE *fp; -  int ipforwarding = 0; -  char buf[10]; - -  fp = fopen (proc_net_snmp, "r"); - -  if (fp == NULL) -    return -1; - -  /* We don't care about the first line. */ -  dropline (fp); -   -  /* Get ip_statistics.IpForwarding :  -     1 => ip forwarding enabled  -     2 => ip forwarding off. */ -  if (fgets (buf, 6, fp)) -    sscanf (buf, "Ip: %d", &ipforwarding); - -  fclose(fp); -   -  if (ipforwarding == 1) -    return 1; - -  return 0; +	FILE *fp; +	int ipforwarding = 0; +	char buf[10]; + +	fp = fopen(proc_net_snmp, "r"); + +	if (fp == NULL) +		return -1; + +	/* We don't care about the first line. */ +	dropline(fp); + +	/* Get ip_statistics.IpForwarding : +	   1 => ip forwarding enabled +	   2 => ip forwarding off. */ +	if (fgets(buf, 6, fp)) +		sscanf(buf, "Ip: %d", &ipforwarding); + +	fclose(fp); + +	if (ipforwarding == 1) +		return 1; + +	return 0;  }  /* char proc_ipv4_forwarding[] = "/proc/sys/net/ipv4/conf/all/forwarding"; */  char proc_ipv4_forwarding[] = "/proc/sys/net/ipv4/ip_forward"; -int -ipforward_on (void) +int ipforward_on(void)  { -  FILE *fp; -   -  if ( zserv_privs.change(ZPRIVS_RAISE) ) -  	zlog_err ("Can't raise privileges, %s", safe_strerror (errno) ); +	FILE *fp; + +	if (zserv_privs.change(ZPRIVS_RAISE)) +		zlog_err("Can't raise privileges, %s", safe_strerror(errno)); -  fp = fopen (proc_ipv4_forwarding, "w"); +	fp = fopen(proc_ipv4_forwarding, "w"); -  if (fp == NULL) { -    if ( zserv_privs.change(ZPRIVS_LOWER) ) -      zlog_err ("Can't lower privileges, %s", safe_strerror (errno)); -    return -1; -  } +	if (fp == NULL) { +		if (zserv_privs.change(ZPRIVS_LOWER)) +			zlog_err("Can't lower privileges, %s", +				 safe_strerror(errno)); +		return -1; +	} -  fprintf (fp, "1\n"); +	fprintf(fp, "1\n"); -  fclose (fp); +	fclose(fp); -  if ( zserv_privs.change(ZPRIVS_LOWER) ) -    zlog_err ("Can't lower privileges, %s", safe_strerror (errno)); +	if (zserv_privs.change(ZPRIVS_LOWER)) +		zlog_err("Can't lower privileges, %s", safe_strerror(errno)); -  return ipforward (); +	return ipforward();  } -int -ipforward_off (void) +int ipforward_off(void)  { -  FILE *fp; +	FILE *fp; -  if ( zserv_privs.change(ZPRIVS_RAISE) ) -  	zlog_err ("Can't raise privileges, %s", safe_strerror (errno)); +	if (zserv_privs.change(ZPRIVS_RAISE)) +		zlog_err("Can't raise privileges, %s", safe_strerror(errno)); -  fp = fopen (proc_ipv4_forwarding, "w"); +	fp = fopen(proc_ipv4_forwarding, "w"); -  if (fp == NULL) { -    if ( zserv_privs.change(ZPRIVS_LOWER) ) -      zlog_err ("Can't lower privileges, %s", safe_strerror (errno)); -    return -1; -  } +	if (fp == NULL) { +		if (zserv_privs.change(ZPRIVS_LOWER)) +			zlog_err("Can't lower privileges, %s", +				 safe_strerror(errno)); +		return -1; +	} -  fprintf (fp, "0\n"); +	fprintf(fp, "0\n"); -  fclose (fp); +	fclose(fp); -  if ( zserv_privs.change(ZPRIVS_LOWER) ) -    zlog_err ("Can't lower privileges, %s", safe_strerror (errno)); +	if (zserv_privs.change(ZPRIVS_LOWER)) +		zlog_err("Can't lower privileges, %s", safe_strerror(errno)); -  return ipforward (); +	return ipforward();  }  char proc_ipv6_forwarding[] = "/proc/sys/net/ipv6/conf/all/forwarding"; -int -ipforward_ipv6 (void) +int ipforward_ipv6(void)  { -  FILE *fp; -  char buf[5]; -  int ipforwarding = 0; +	FILE *fp; +	char buf[5]; +	int ipforwarding = 0; -  fp = fopen (proc_ipv6_forwarding, "r"); +	fp = fopen(proc_ipv6_forwarding, "r"); -  if (fp == NULL) -    return -1; +	if (fp == NULL) +		return -1; -  if (fgets (buf, 2, fp)) -    sscanf (buf, "%d", &ipforwarding); +	if (fgets(buf, 2, fp)) +		sscanf(buf, "%d", &ipforwarding); -  fclose (fp); -  return ipforwarding; +	fclose(fp); +	return ipforwarding;  } -int -ipforward_ipv6_on (void) +int ipforward_ipv6_on(void)  { -  FILE *fp; +	FILE *fp; -  if ( zserv_privs.change(ZPRIVS_RAISE) ) -       zlog_err ("Can't raise privileges, %s", safe_strerror (errno)); +	if (zserv_privs.change(ZPRIVS_RAISE)) +		zlog_err("Can't raise privileges, %s", safe_strerror(errno)); -  fp = fopen (proc_ipv6_forwarding, "w"); +	fp = fopen(proc_ipv6_forwarding, "w"); -  if (fp == NULL) { -    if ( zserv_privs.change(ZPRIVS_LOWER) ) -      zlog_err ("Can't lower privileges, %s", safe_strerror (errno)); -    return -1; -  } +	if (fp == NULL) { +		if (zserv_privs.change(ZPRIVS_LOWER)) +			zlog_err("Can't lower privileges, %s", +				 safe_strerror(errno)); +		return -1; +	} -  fprintf (fp, "1\n"); +	fprintf(fp, "1\n"); -  fclose (fp); +	fclose(fp); -  if ( zserv_privs.change(ZPRIVS_LOWER) ) -    zlog_err ("Can't lower privileges, %s", safe_strerror (errno)); +	if (zserv_privs.change(ZPRIVS_LOWER)) +		zlog_err("Can't lower privileges, %s", safe_strerror(errno)); -  return ipforward_ipv6 (); +	return ipforward_ipv6();  } -int -ipforward_ipv6_off (void) +int ipforward_ipv6_off(void)  { -  FILE *fp; +	FILE *fp; -  if ( zserv_privs.change(ZPRIVS_RAISE) ) -       zlog_err ("Can't raise privileges, %s", safe_strerror (errno)); +	if (zserv_privs.change(ZPRIVS_RAISE)) +		zlog_err("Can't raise privileges, %s", safe_strerror(errno)); -  fp = fopen (proc_ipv6_forwarding, "w"); +	fp = fopen(proc_ipv6_forwarding, "w"); -  if (fp == NULL) { -    if ( zserv_privs.change(ZPRIVS_LOWER) ) -      zlog_err ("Can't lower privileges, %s", safe_strerror (errno)); -    return -1; -  } +	if (fp == NULL) { +		if (zserv_privs.change(ZPRIVS_LOWER)) +			zlog_err("Can't lower privileges, %s", +				 safe_strerror(errno)); +		return -1; +	} -  fprintf (fp, "0\n"); +	fprintf(fp, "0\n"); -  fclose (fp); +	fclose(fp); -  if ( zserv_privs.change(ZPRIVS_LOWER) ) -    zlog_err ("Can't lower privileges, %s", safe_strerror (errno)); +	if (zserv_privs.change(ZPRIVS_LOWER)) +		zlog_err("Can't lower privileges, %s", safe_strerror(errno)); -  return ipforward_ipv6 (); +	return ipforward_ipv6();  } diff --git a/zebra/ipforward_solaris.c b/zebra/ipforward_solaris.c index 8eccfe133c..88a3bb79bf 100644 --- a/zebra/ipforward_solaris.c +++ b/zebra/ipforward_solaris.c @@ -17,7 +17,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #include <zebra.h> @@ -47,117 +47,110 @@ extern struct zebra_privs_t zserv_privs;  ** name of the parameter being referenced.  */ -static int -solaris_nd(const int cmd, const char* parameter, const int value) +static int solaris_nd(const int cmd, const char *parameter, const int value)  {  #define ND_BUFFER_SIZE 1024 -  int fd; -  char nd_buf[ND_BUFFER_SIZE]; -  struct strioctl strioctl; -  const char* device = IP_DEV_NAME; -  int retval; -  memset(nd_buf, '\0', ND_BUFFER_SIZE); -  /* -  ** ND_SET takes a NULL delimited list of strings further terminated -  ** buy a NULL.  ND_GET returns a list in a similar layout, although -  ** here we only use the first result. -  */ -  if (cmd == ND_SET) -    snprintf(nd_buf, ND_BUFFER_SIZE, "%s%c%d%c", parameter, '\0', value,'\0'); -  else if (cmd == ND_GET) -    snprintf(nd_buf, ND_BUFFER_SIZE, "%s", parameter); -  else { -    zlog_err("internal error - inappropriate command given to " -             "solaris_nd()%s:%d", __FILE__, __LINE__); -    return -1; -  } +	int fd; +	char nd_buf[ND_BUFFER_SIZE]; +	struct strioctl strioctl; +	const char *device = IP_DEV_NAME; +	int retval; +	memset(nd_buf, '\0', ND_BUFFER_SIZE); +	/* +	** ND_SET takes a NULL delimited list of strings further terminated +	** buy a NULL.  ND_GET returns a list in a similar layout, although +	** here we only use the first result. +	*/ +	if (cmd == ND_SET) +		snprintf(nd_buf, ND_BUFFER_SIZE, "%s%c%d%c", parameter, '\0', +			 value, '\0'); +	else if (cmd == ND_GET) +		snprintf(nd_buf, ND_BUFFER_SIZE, "%s", parameter); +	else { +		zlog_err( +			"internal error - inappropriate command given to " +			"solaris_nd()%s:%d", +			__FILE__, __LINE__); +		return -1; +	} -  strioctl.ic_cmd = cmd; -  strioctl.ic_timout = 0; -  strioctl.ic_len = ND_BUFFER_SIZE; -  strioctl.ic_dp = nd_buf; -   -  if ( zserv_privs.change (ZPRIVS_RAISE) ) -       zlog_err ("solaris_nd: Can't raise privileges"); -  if ((fd = open (device, O_RDWR)) < 0)  -    { -      zlog_warn("failed to open device %s - %s", device, safe_strerror(errno)); -      if ( zserv_privs.change (ZPRIVS_LOWER) ) -        zlog_err ("solaris_nd: Can't lower privileges"); -      return -1; -    } -  if (ioctl (fd, I_STR, &strioctl) < 0)  -    { -      int save_errno = errno; -      if ( zserv_privs.change (ZPRIVS_LOWER) ) -        zlog_err ("solaris_nd: Can't lower privileges"); -      close (fd); -      zlog_warn("ioctl I_STR failed on device %s - %s", -      		device, safe_strerror(save_errno)); -      return -1; -    } -  close(fd); -  if ( zserv_privs.change (ZPRIVS_LOWER) ) -         zlog_err ("solaris_nd: Can't lower privileges"); -   -  if (cmd == ND_GET)  -    { -      errno = 0; -      retval = atoi(nd_buf); -      if (errno)  -        { -          zlog_warn("failed to convert returned value to integer - %s", -                    safe_strerror(errno)); -          retval = -1; -        } -    }  -  else  -    { -      retval = 0; -    } -  return retval; +	strioctl.ic_cmd = cmd; +	strioctl.ic_timout = 0; +	strioctl.ic_len = ND_BUFFER_SIZE; +	strioctl.ic_dp = nd_buf; + +	if (zserv_privs.change(ZPRIVS_RAISE)) +		zlog_err("solaris_nd: Can't raise privileges"); +	if ((fd = open(device, O_RDWR)) < 0) { +		zlog_warn("failed to open device %s - %s", device, +			  safe_strerror(errno)); +		if (zserv_privs.change(ZPRIVS_LOWER)) +			zlog_err("solaris_nd: Can't lower privileges"); +		return -1; +	} +	if (ioctl(fd, I_STR, &strioctl) < 0) { +		int save_errno = errno; +		if (zserv_privs.change(ZPRIVS_LOWER)) +			zlog_err("solaris_nd: Can't lower privileges"); +		close(fd); +		zlog_warn("ioctl I_STR failed on device %s - %s", device, +			  safe_strerror(save_errno)); +		return -1; +	} +	close(fd); +	if (zserv_privs.change(ZPRIVS_LOWER)) +		zlog_err("solaris_nd: Can't lower privileges"); + +	if (cmd == ND_GET) { +		errno = 0; +		retval = atoi(nd_buf); +		if (errno) { +			zlog_warn( +				"failed to convert returned value to integer - %s", +				safe_strerror(errno)); +			retval = -1; +		} +	} else { +		retval = 0; +	} +	return retval;  } -static int -solaris_nd_set(const char* parameter, const int value) { -  return solaris_nd(ND_SET, parameter, value); +static int solaris_nd_set(const char *parameter, const int value) +{ +	return solaris_nd(ND_SET, parameter, value);  } -static int -solaris_nd_get(const char* parameter) { -  return solaris_nd(ND_GET, parameter, 0); +static int solaris_nd_get(const char *parameter) +{ +	return solaris_nd(ND_GET, parameter, 0);  } -int -ipforward(void) +int ipforward(void)  { -  return solaris_nd_get("ip_forwarding"); +	return solaris_nd_get("ip_forwarding");  } -int -ipforward_on (void) +int ipforward_on(void)  { -  (void) solaris_nd_set("ip_forwarding", 1); -  return ipforward(); +	(void)solaris_nd_set("ip_forwarding", 1); +	return ipforward();  } -int -ipforward_off (void) +int ipforward_off(void)  { -  (void) solaris_nd_set("ip_forwarding", 0); -  return ipforward(); +	(void)solaris_nd_set("ip_forwarding", 0); +	return ipforward();  }  int ipforward_ipv6(void)  { -  return solaris_nd_get("ip6_forwarding"); +	return solaris_nd_get("ip6_forwarding");  } -int -ipforward_ipv6_on (void) +int ipforward_ipv6_on(void)  { -  (void) solaris_nd_set("ip6_forwarding", 1); -  return ipforward_ipv6(); +	(void)solaris_nd_set("ip6_forwarding", 1); +	return ipforward_ipv6();  } -int -ipforward_ipv6_off (void) +int ipforward_ipv6_off(void)  { -  (void) solaris_nd_set("ip6_forwarding", 0); -  return ipforward_ipv6(); +	(void)solaris_nd_set("ip6_forwarding", 0); +	return ipforward_ipv6();  } diff --git a/zebra/ipforward_sysctl.c b/zebra/ipforward_sysctl.c index 28894f4e0a..651046d269 100644 --- a/zebra/ipforward_sysctl.c +++ b/zebra/ipforward_sysctl.c @@ -16,7 +16,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #include <zebra.h> @@ -30,144 +30,121 @@  extern struct zebra_privs_t zserv_privs;  /* IPv4 forwarding control MIB. */ -int mib[MIB_SIZ] = -{ -  CTL_NET, -  PF_INET, -  IPPROTO_IP, -  IPCTL_FORWARDING -}; +int mib[MIB_SIZ] = {CTL_NET, PF_INET, IPPROTO_IP, IPCTL_FORWARDING}; -int -ipforward (void) +int ipforward(void)  { -  size_t len; -  int ipforwarding = 0; - -  len = sizeof ipforwarding; -  if (sysctl (mib, MIB_SIZ, &ipforwarding, &len, 0, 0) < 0)  -    { -      zlog_warn ("Can't get ipforwarding value"); -      return -1; -    } -  return ipforwarding; +	size_t len; +	int ipforwarding = 0; + +	len = sizeof ipforwarding; +	if (sysctl(mib, MIB_SIZ, &ipforwarding, &len, 0, 0) < 0) { +		zlog_warn("Can't get ipforwarding value"); +		return -1; +	} +	return ipforwarding;  } -int -ipforward_on (void) +int ipforward_on(void)  { -  size_t len; -  int ipforwarding = 1; - -  len = sizeof ipforwarding; -  if (zserv_privs.change(ZPRIVS_RAISE)) -    zlog_err("Can't raise privileges"); -  if (sysctl (mib, MIB_SIZ, NULL, NULL, &ipforwarding, len) < 0) -    { -      if (zserv_privs.change(ZPRIVS_LOWER)) -        zlog_err("Can't lower privileges"); -      zlog_warn ("Can't set ipforwarding on"); -      return -1; -    } -  if (zserv_privs.change(ZPRIVS_LOWER)) -    zlog_err("Can't lower privileges"); -  return ipforwarding; +	size_t len; +	int ipforwarding = 1; + +	len = sizeof ipforwarding; +	if (zserv_privs.change(ZPRIVS_RAISE)) +		zlog_err("Can't raise privileges"); +	if (sysctl(mib, MIB_SIZ, NULL, NULL, &ipforwarding, len) < 0) { +		if (zserv_privs.change(ZPRIVS_LOWER)) +			zlog_err("Can't lower privileges"); +		zlog_warn("Can't set ipforwarding on"); +		return -1; +	} +	if (zserv_privs.change(ZPRIVS_LOWER)) +		zlog_err("Can't lower privileges"); +	return ipforwarding;  } -int -ipforward_off (void) +int ipforward_off(void)  { -  size_t len; -  int ipforwarding = 0; - -  len = sizeof ipforwarding; -  if (zserv_privs.change(ZPRIVS_RAISE)) -    zlog_err("Can't raise privileges"); -  if (sysctl (mib, MIB_SIZ, NULL, NULL, &ipforwarding, len) < 0) -    { -      if (zserv_privs.change(ZPRIVS_LOWER)) -        zlog_err("Can't lower privileges"); -      zlog_warn ("Can't set ipforwarding on"); -      return -1; -    } -  if (zserv_privs.change(ZPRIVS_LOWER)) -    zlog_err("Can't lower privileges"); -  return ipforwarding; +	size_t len; +	int ipforwarding = 0; + +	len = sizeof ipforwarding; +	if (zserv_privs.change(ZPRIVS_RAISE)) +		zlog_err("Can't raise privileges"); +	if (sysctl(mib, MIB_SIZ, NULL, NULL, &ipforwarding, len) < 0) { +		if (zserv_privs.change(ZPRIVS_LOWER)) +			zlog_err("Can't lower privileges"); +		zlog_warn("Can't set ipforwarding on"); +		return -1; +	} +	if (zserv_privs.change(ZPRIVS_LOWER)) +		zlog_err("Can't lower privileges"); +	return ipforwarding;  }  /* IPv6 forwarding control MIB. */ -int mib_ipv6[MIB_SIZ] =  -{ -  CTL_NET, -  PF_INET6, +int mib_ipv6[MIB_SIZ] = {CTL_NET, PF_INET6,  #if defined(KAME) -  IPPROTO_IPV6, -  IPV6CTL_FORWARDING -#else /* NOT KAME */ -  IPPROTO_IP, -  IP6CTL_FORWARDING +			 IPPROTO_IPV6, IPV6CTL_FORWARDING +#else  /* NOT KAME */ +			 IPPROTO_IP, IP6CTL_FORWARDING  #endif /* KAME */ -};  +}; -int -ipforward_ipv6 (void) +int ipforward_ipv6(void)  { -  size_t len; -  int ip6forwarding = 0; - -  len = sizeof ip6forwarding; -  if (zserv_privs.change(ZPRIVS_RAISE)) -    zlog_err("Can't raise privileges"); -  if (sysctl (mib_ipv6, MIB_SIZ, &ip6forwarding, &len, 0, 0) < 0) -    { -     if (zserv_privs.change(ZPRIVS_LOWER)) -        zlog_err("Can't lower privileges"); -      zlog_warn ("can't get ip6forwarding value"); -      return -1; -    } -  if (zserv_privs.change(ZPRIVS_LOWER)) -    zlog_err("Can't lower privileges"); -  return ip6forwarding; +	size_t len; +	int ip6forwarding = 0; + +	len = sizeof ip6forwarding; +	if (zserv_privs.change(ZPRIVS_RAISE)) +		zlog_err("Can't raise privileges"); +	if (sysctl(mib_ipv6, MIB_SIZ, &ip6forwarding, &len, 0, 0) < 0) { +		if (zserv_privs.change(ZPRIVS_LOWER)) +			zlog_err("Can't lower privileges"); +		zlog_warn("can't get ip6forwarding value"); +		return -1; +	} +	if (zserv_privs.change(ZPRIVS_LOWER)) +		zlog_err("Can't lower privileges"); +	return ip6forwarding;  } -int -ipforward_ipv6_on (void) +int ipforward_ipv6_on(void)  { -  size_t len; -  int ip6forwarding = 1; - -  len = sizeof ip6forwarding; -  if (zserv_privs.change(ZPRIVS_RAISE)) -    zlog_err("Can't raise privileges"); -  if (sysctl (mib_ipv6, MIB_SIZ, NULL, NULL, &ip6forwarding, len) < 0) -    { -     if (zserv_privs.change(ZPRIVS_LOWER)) -        zlog_err("Can't lower privileges"); -      zlog_warn ("can't get ip6forwarding value"); -      return -1; -    } -  if (zserv_privs.change(ZPRIVS_LOWER)) -    zlog_err("Can't lower privileges"); -  return ip6forwarding; +	size_t len; +	int ip6forwarding = 1; + +	len = sizeof ip6forwarding; +	if (zserv_privs.change(ZPRIVS_RAISE)) +		zlog_err("Can't raise privileges"); +	if (sysctl(mib_ipv6, MIB_SIZ, NULL, NULL, &ip6forwarding, len) < 0) { +		if (zserv_privs.change(ZPRIVS_LOWER)) +			zlog_err("Can't lower privileges"); +		zlog_warn("can't get ip6forwarding value"); +		return -1; +	} +	if (zserv_privs.change(ZPRIVS_LOWER)) +		zlog_err("Can't lower privileges"); +	return ip6forwarding;  } -int -ipforward_ipv6_off (void) +int ipforward_ipv6_off(void)  { -  size_t len; -  int ip6forwarding = 0; - -  len = sizeof ip6forwarding; -  if (zserv_privs.change(ZPRIVS_RAISE)) -    zlog_err("Can't raise privileges"); -  if (sysctl (mib_ipv6, MIB_SIZ, NULL, NULL, &ip6forwarding, len) < 0) -    { -      if (zserv_privs.change(ZPRIVS_LOWER)) -        zlog_err("Can't lower privileges"); -      zlog_warn ("can't get ip6forwarding value"); -      return -1; -    } -  if (zserv_privs.change(ZPRIVS_LOWER)) -    zlog_err("Can't lower privileges"); -  return ip6forwarding; +	size_t len; +	int ip6forwarding = 0; + +	len = sizeof ip6forwarding; +	if (zserv_privs.change(ZPRIVS_RAISE)) +		zlog_err("Can't raise privileges"); +	if (sysctl(mib_ipv6, MIB_SIZ, NULL, NULL, &ip6forwarding, len) < 0) { +		if (zserv_privs.change(ZPRIVS_LOWER)) +			zlog_err("Can't lower privileges"); +		zlog_warn("can't get ip6forwarding value"); +		return -1; +	} +	if (zserv_privs.change(ZPRIVS_LOWER)) +		zlog_err("Can't lower privileges"); +	return ip6forwarding;  } diff --git a/zebra/irdp.h b/zebra/irdp.h index 9ce55e5876..20cbbc08d0 100644 --- a/zebra/irdp.h +++ b/zebra/irdp.h @@ -16,10 +16,10 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */ -/*  +/*   * This file is modified and completed for the Zebra IRDP implementation   * by Robert Olsson, Swedish University of Agricultural Sciences   */ @@ -69,8 +69,8 @@  #define IRDP_RX_BUF 1500 -/*  -     Comments comes from RFC1256 ICMP Router Discovery Messages.  +/* +     Comments comes from RFC1256 ICMP Router Discovery Messages.       The IP destination address to be used for multicast Router       Advertisements sent from the interface.  The only permissible @@ -80,26 +80,26 @@       all listening hosts support IP multicast.)       Default: 224.0.0.1 if the router supports IP multicast on the -     interface, else 255.255.255.255  +     interface, else 255.255.255.255       The maximum time allowed between sending multicast Router       Advertisements from the interface, in seconds.  Must be no less       than 4 seconds and no greater than 1800 seconds. -     Default: 600 seconds  +     Default: 600 seconds       The minimum time allowed between sending unsolicited multicast       Router Advertisements from the interface, in seconds.  Must be no       less than 3 seconds and no greater than MaxAdvertisementInterval. -     Default: 0.75 * MaxAdvertisementInterval  +     Default: 0.75 * MaxAdvertisementInterval       The value to be placed in the Lifetime field of Router       Advertisements sent from the interface, in seconds.  Must be no       less than MaxAdvertisementInterval and no greater than 9000       seconds. -     Default: 3 * MaxAdvertisementInterval  +     Default: 3 * MaxAdvertisementInterval       The preferability of the address as a default router address,       relative to other router addresses on the same subnet.  A 32-bit, @@ -108,16 +108,15 @@       that the address, even though it may be advertised, is not to be       used by neighboring hosts as a default router address. -     Default: 0  +     Default: 0  */ -struct irdp_interface  -{ -  unsigned long MaxAdvertInterval; -  unsigned long MinAdvertInterval; -  unsigned long Preference; +struct irdp_interface { +	unsigned long MaxAdvertInterval; +	unsigned long MinAdvertInterval; +	unsigned long Preference; -  u_int32_t flags; +	u_int32_t flags;  #define IF_ACTIVE               (1<<0) /* ICMP Active */  #define IF_BROADCAST            (1<<1) /* 255.255.255.255 */ @@ -127,31 +126,29 @@ struct irdp_interface  #define IF_DEBUG_MISC           (1<<5)   #define IF_SHUTDOWN             (1<<6)  -  struct interface *ifp; -  struct thread *t_advertise; -  unsigned long irdp_sent; -  u_int16_t Lifetime; - - struct list *AdvPrefList; +	struct interface *ifp; +	struct thread *t_advertise; +	unsigned long irdp_sent; +	u_int16_t Lifetime; +	struct list *AdvPrefList;  }; -struct Adv  -{ -  struct in_addr ip; -  int pref; +struct Adv { +	struct in_addr ip; +	int pref;  };  extern void irdp_init(void);  extern int irdp_sock_init(void);  extern void irdp_finish(void); -extern void irdp_config_write (struct vty *, struct interface *); +extern void irdp_config_write(struct vty *, struct interface *);  extern int irdp_send_thread(struct thread *t_advert);  extern void irdp_advert_off(struct interface *ifp); -extern void process_solicit (struct interface *ifp); +extern void process_solicit(struct interface *ifp);  extern int irdp_read_raw(struct thread *r); -extern void send_packet(struct interface *ifp, struct stream *s, -			u_int32_t dst, struct prefix *p, u_int32_t ttl); +extern void send_packet(struct interface *ifp, struct stream *s, u_int32_t dst, +			struct prefix *p, u_int32_t ttl);  #endif /* _IRDP_H */ diff --git a/zebra/irdp_interface.c b/zebra/irdp_interface.c index 407738d80f..84165dee61 100644 --- a/zebra/irdp_interface.c +++ b/zebra/irdp_interface.c @@ -64,313 +64,293 @@  extern int irdp_sock; -static const char * -inet_2a(u_int32_t a, char *b) +static const char *inet_2a(u_int32_t a, char *b)  { -  sprintf(b, "%u.%u.%u.%u", -          (a    ) & 0xFF, -          (a>> 8) & 0xFF, -          (a>>16) & 0xFF, -          (a>>24) & 0xFF); -  return  b; +	sprintf(b, "%u.%u.%u.%u", (a)&0xFF, (a >> 8) & 0xFF, (a >> 16) & 0xFF, +		(a >> 24) & 0xFF); +	return b;  } -static struct prefix * -irdp_get_prefix(struct interface *ifp) +static struct prefix *irdp_get_prefix(struct interface *ifp)  { -  struct listnode *node; -  struct connected *ifc; +	struct listnode *node; +	struct connected *ifc; -  if (ifp->connected) -    for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, ifc)) -      return ifc->address; +	if (ifp->connected) +		for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) +			return ifc->address; -  return NULL; +	return NULL;  }  /* Join to the add/leave multicast group. */ -static int -if_group (struct interface *ifp, -	  int sock, -	  u_int32_t group, -	  int add_leave) +static int if_group(struct interface *ifp, int sock, u_int32_t group, +		    int add_leave)  { -  struct ip_mreq m; -  struct prefix *p; -  int ret; -  char b1[INET_ADDRSTRLEN]; - -  memset (&m, 0, sizeof (m)); -  m.imr_multiaddr.s_addr = htonl (group); -  p = irdp_get_prefix(ifp); - -  if(!p) { -        zlog_warn ("IRDP: can't get address for %s", ifp->name); -	return 1; -  } - -  m.imr_interface = p->u.prefix4; - -  ret = setsockopt (sock, IPPROTO_IP, add_leave, -		    (char *) &m, sizeof (struct ip_mreq)); -  if (ret < 0) -    zlog_warn ("IRDP: %s can't setsockopt %s: %s", -	       add_leave == IP_ADD_MEMBERSHIP? "join group":"leave group", -	       inet_2a(group, b1), -	       safe_strerror (errno)); - -  return ret; +	struct ip_mreq m; +	struct prefix *p; +	int ret; +	char b1[INET_ADDRSTRLEN]; + +	memset(&m, 0, sizeof(m)); +	m.imr_multiaddr.s_addr = htonl(group); +	p = irdp_get_prefix(ifp); + +	if (!p) { +		zlog_warn("IRDP: can't get address for %s", ifp->name); +		return 1; +	} + +	m.imr_interface = p->u.prefix4; + +	ret = setsockopt(sock, IPPROTO_IP, add_leave, (char *)&m, +			 sizeof(struct ip_mreq)); +	if (ret < 0) +		zlog_warn("IRDP: %s can't setsockopt %s: %s", +			  add_leave == IP_ADD_MEMBERSHIP ? "join group" +							 : "leave group", +			  inet_2a(group, b1), safe_strerror(errno)); + +	return ret;  } -static int -if_add_group (struct interface *ifp) +static int if_add_group(struct interface *ifp)  { -  struct zebra_if *zi= ifp->info; -  struct irdp_interface *irdp = &zi->irdp; -  int ret; -  char b1[INET_ADDRSTRLEN]; - -  ret = if_group (ifp, irdp_sock, INADDR_ALLRTRS_GROUP, IP_ADD_MEMBERSHIP); -  if (ret < 0) { -    return ret; -  } - -  if(irdp->flags & IF_DEBUG_MISC ) -    zlog_debug("IRDP: Adding group %s for %s", -	       inet_2a(htonl(INADDR_ALLRTRS_GROUP), b1), -	       ifp->name); -  return 0; +	struct zebra_if *zi = ifp->info; +	struct irdp_interface *irdp = &zi->irdp; +	int ret; +	char b1[INET_ADDRSTRLEN]; + +	ret = if_group(ifp, irdp_sock, INADDR_ALLRTRS_GROUP, IP_ADD_MEMBERSHIP); +	if (ret < 0) { +		return ret; +	} + +	if (irdp->flags & IF_DEBUG_MISC) +		zlog_debug("IRDP: Adding group %s for %s", +			   inet_2a(htonl(INADDR_ALLRTRS_GROUP), b1), ifp->name); +	return 0;  } -static int -if_drop_group (struct interface *ifp) +static int if_drop_group(struct interface *ifp)  { -  struct zebra_if *zi= ifp->info; -  struct irdp_interface *irdp = &zi->irdp; -  int ret; -  char b1[INET_ADDRSTRLEN]; - -  ret = if_group (ifp, irdp_sock, INADDR_ALLRTRS_GROUP, IP_DROP_MEMBERSHIP); -  if (ret < 0) -    return ret; - -  if(irdp->flags & IF_DEBUG_MISC) -    zlog_debug("IRDP: Leaving group %s for %s", -	       inet_2a(htonl(INADDR_ALLRTRS_GROUP), b1), -	       ifp->name); -  return 0; +	struct zebra_if *zi = ifp->info; +	struct irdp_interface *irdp = &zi->irdp; +	int ret; +	char b1[INET_ADDRSTRLEN]; + +	ret = if_group(ifp, irdp_sock, INADDR_ALLRTRS_GROUP, +		       IP_DROP_MEMBERSHIP); +	if (ret < 0) +		return ret; + +	if (irdp->flags & IF_DEBUG_MISC) +		zlog_debug("IRDP: Leaving group %s for %s", +			   inet_2a(htonl(INADDR_ALLRTRS_GROUP), b1), ifp->name); +	return 0;  } -static void -if_set_defaults(struct interface *ifp) +static void if_set_defaults(struct interface *ifp)  { -  struct zebra_if *zi=ifp->info; -  struct irdp_interface *irdp=&zi->irdp; +	struct zebra_if *zi = ifp->info; +	struct irdp_interface *irdp = &zi->irdp; -  irdp->MaxAdvertInterval = IRDP_MAXADVERTINTERVAL; -  irdp->MinAdvertInterval = IRDP_MINADVERTINTERVAL; -  irdp->Preference = IRDP_PREFERENCE; -  irdp->Lifetime = IRDP_LIFETIME; +	irdp->MaxAdvertInterval = IRDP_MAXADVERTINTERVAL; +	irdp->MinAdvertInterval = IRDP_MINADVERTINTERVAL; +	irdp->Preference = IRDP_PREFERENCE; +	irdp->Lifetime = IRDP_LIFETIME;  } -static struct Adv *Adv_new (void) +static struct Adv *Adv_new(void)  { -  return XCALLOC (MTYPE_TMP, sizeof (struct Adv)); +	return XCALLOC(MTYPE_TMP, sizeof(struct Adv));  } -static void -Adv_free (struct Adv *adv) +static void Adv_free(struct Adv *adv)  { -  XFREE (MTYPE_TMP, adv); +	XFREE(MTYPE_TMP, adv);  } -static void -irdp_if_start(struct interface *ifp, int multicast, int set_defaults) +static void irdp_if_start(struct interface *ifp, int multicast, +			  int set_defaults)  { -  struct zebra_if *zi= ifp->info; -  struct irdp_interface *irdp = &zi->irdp; -  struct listnode *node; -  struct connected *ifc; -  u_int32_t timer, seed; +	struct zebra_if *zi = ifp->info; +	struct irdp_interface *irdp = &zi->irdp; +	struct listnode *node; +	struct connected *ifc; +	u_int32_t timer, seed; -  if (irdp->flags & IF_ACTIVE ) { -    zlog_warn("IRDP: Interface is already active %s", ifp->name); -    return; -  } -  if ((irdp_sock < 0) && ((irdp_sock = irdp_sock_init()) < 0)) { -    zlog_warn("IRDP: Cannot activate interface %s (cannot create " -	      "IRDP socket)", ifp->name); -    return; -  } -  irdp->flags |= IF_ACTIVE; +	if (irdp->flags & IF_ACTIVE) { +		zlog_warn("IRDP: Interface is already active %s", ifp->name); +		return; +	} +	if ((irdp_sock < 0) && ((irdp_sock = irdp_sock_init()) < 0)) { +		zlog_warn( +			"IRDP: Cannot activate interface %s (cannot create " +			"IRDP socket)", +			ifp->name); +		return; +	} +	irdp->flags |= IF_ACTIVE; -  if(!multicast) -    irdp->flags |= IF_BROADCAST; +	if (!multicast) +		irdp->flags |= IF_BROADCAST; -  if_add_update(ifp); +	if_add_update(ifp); -  if (! (ifp->flags & IFF_UP)) { -    zlog_warn("IRDP: Interface is down %s", ifp->name); -  } +	if (!(ifp->flags & IFF_UP)) { +		zlog_warn("IRDP: Interface is down %s", ifp->name); +	} -  /* Shall we cancel if_start if if_add_group fails? */ +	/* Shall we cancel if_start if if_add_group fails? */ -  if( multicast) { -    if_add_group(ifp); +	if (multicast) { +		if_add_group(ifp); -    if (! (ifp->flags & (IFF_MULTICAST|IFF_ALLMULTI))) { -      zlog_warn("IRDP: Interface not multicast enabled %s", ifp->name); -    } -  } +		if (!(ifp->flags & (IFF_MULTICAST | IFF_ALLMULTI))) { +			zlog_warn("IRDP: Interface not multicast enabled %s", +				  ifp->name); +		} +	} -  if(set_defaults) -    if_set_defaults(ifp); +	if (set_defaults) +		if_set_defaults(ifp); -  irdp->irdp_sent = 0; +	irdp->irdp_sent = 0; -  /* The spec suggests this for randomness */ +	/* The spec suggests this for randomness */ -  seed = 0; -  if( ifp->connected) -    for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, ifc)) -      { -        seed = ifc->address->u.prefix4.s_addr; -        break; -      } +	seed = 0; +	if (ifp->connected) +		for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) { +			seed = ifc->address->u.prefix4.s_addr; +			break; +		} -  srandom(seed); -  timer =  (random () % IRDP_DEFAULT_INTERVAL) + 1; +	srandom(seed); +	timer = (random() % IRDP_DEFAULT_INTERVAL) + 1; -  irdp->AdvPrefList = list_new(); -  irdp->AdvPrefList->del =  (void (*)(void *)) Adv_free; /* Destructor */ +	irdp->AdvPrefList = list_new(); +	irdp->AdvPrefList->del = (void (*)(void *))Adv_free; /* Destructor */ -  /* And this for startup. Speed limit from 1991 :-). But it's OK*/ +	/* And this for startup. Speed limit from 1991 :-). But it's OK*/ -  if(irdp->irdp_sent < MAX_INITIAL_ADVERTISEMENTS && -     timer > MAX_INITIAL_ADVERT_INTERVAL ) -	  timer= MAX_INITIAL_ADVERT_INTERVAL; +	if (irdp->irdp_sent < MAX_INITIAL_ADVERTISEMENTS +	    && timer > MAX_INITIAL_ADVERT_INTERVAL) +		timer = MAX_INITIAL_ADVERT_INTERVAL; -  if(irdp->flags & IF_DEBUG_MISC) -    zlog_debug("IRDP: Init timer for %s set to %u", -	       ifp->name, -	       timer); +	if (irdp->flags & IF_DEBUG_MISC) +		zlog_debug("IRDP: Init timer for %s set to %u", ifp->name, +			   timer); -  irdp->t_advertise = thread_add_timer(zebrad.master, -				       irdp_send_thread, -				       ifp, -				       timer); +	irdp->t_advertise = +		thread_add_timer(zebrad.master, irdp_send_thread, ifp, timer);  } -static void -irdp_if_stop(struct interface *ifp) +static void irdp_if_stop(struct interface *ifp)  { -  struct zebra_if *zi=ifp->info; -  struct irdp_interface *irdp=&zi->irdp; +	struct zebra_if *zi = ifp->info; +	struct irdp_interface *irdp = &zi->irdp; -  if (irdp == NULL) { -    zlog_warn ("Interface %s structure is NULL", ifp->name); -    return; -  } +	if (irdp == NULL) { +		zlog_warn("Interface %s structure is NULL", ifp->name); +		return; +	} -  if (! (irdp->flags & IF_ACTIVE )) { -    zlog_warn("Interface is not active %s", ifp->name); -    return; -  } +	if (!(irdp->flags & IF_ACTIVE)) { +		zlog_warn("Interface is not active %s", ifp->name); +		return; +	} -  if(! (irdp->flags & IF_BROADCAST)) -    if_drop_group(ifp); +	if (!(irdp->flags & IF_BROADCAST)) +		if_drop_group(ifp); -  irdp_advert_off(ifp); +	irdp_advert_off(ifp); -  list_delete(irdp->AdvPrefList); -  irdp->AdvPrefList=NULL; +	list_delete(irdp->AdvPrefList); +	irdp->AdvPrefList = NULL; -  irdp->flags = 0; +	irdp->flags = 0;  } -static void -irdp_if_shutdown(struct interface *ifp) +static void irdp_if_shutdown(struct interface *ifp)  { -  struct zebra_if *zi= ifp->info; -  struct irdp_interface *irdp = &zi->irdp; +	struct zebra_if *zi = ifp->info; +	struct irdp_interface *irdp = &zi->irdp; -  if (irdp->flags & IF_SHUTDOWN ) { -    zlog_warn("IRDP: Interface is already shutdown %s", ifp->name); -    return; -  } +	if (irdp->flags & IF_SHUTDOWN) { +		zlog_warn("IRDP: Interface is already shutdown %s", ifp->name); +		return; +	} -  irdp->flags |= IF_SHUTDOWN; -  irdp->flags &= ~IF_ACTIVE; +	irdp->flags |= IF_SHUTDOWN; +	irdp->flags &= ~IF_ACTIVE; -  if(! (irdp->flags & IF_BROADCAST)) -    if_drop_group(ifp); +	if (!(irdp->flags & IF_BROADCAST)) +		if_drop_group(ifp); -  /* Tell the hosts we are out of service */ -  irdp_advert_off(ifp); +	/* Tell the hosts we are out of service */ +	irdp_advert_off(ifp);  } -static void -irdp_if_no_shutdown(struct interface *ifp) +static void irdp_if_no_shutdown(struct interface *ifp)  { -  struct zebra_if *zi= ifp->info; -  struct irdp_interface *irdp = &zi->irdp; +	struct zebra_if *zi = ifp->info; +	struct irdp_interface *irdp = &zi->irdp; -  if (! (irdp->flags & IF_SHUTDOWN )) { -    zlog_warn("IRDP: Interface is not shutdown %s", ifp->name); -    return; -  } +	if (!(irdp->flags & IF_SHUTDOWN)) { +		zlog_warn("IRDP: Interface is not shutdown %s", ifp->name); +		return; +	} -  irdp->flags &= ~IF_SHUTDOWN; - -  irdp_if_start(ifp, irdp->flags & IF_BROADCAST? FALSE : TRUE, FALSE); +	irdp->flags &= ~IF_SHUTDOWN; +	irdp_if_start(ifp, irdp->flags & IF_BROADCAST ? FALSE : TRUE, FALSE);  }  /* Write configuration to user */ -void irdp_config_write (struct vty *vty, struct interface *ifp) +void irdp_config_write(struct vty *vty, struct interface *ifp)  { -  struct zebra_if *zi=ifp->info; -  struct irdp_interface *irdp=&zi->irdp; -  struct Adv *adv; -  struct listnode *node; -  char b1[INET_ADDRSTRLEN]; - -  if(irdp->flags & IF_ACTIVE || irdp->flags & IF_SHUTDOWN) { +	struct zebra_if *zi = ifp->info; +	struct irdp_interface *irdp = &zi->irdp; +	struct Adv *adv; +	struct listnode *node; +	char b1[INET_ADDRSTRLEN]; -    if( irdp->flags & IF_SHUTDOWN) -      vty_out (vty, " ip irdp shutdown %s",  VTY_NEWLINE); +	if (irdp->flags & IF_ACTIVE || irdp->flags & IF_SHUTDOWN) { -    if( irdp->flags & IF_BROADCAST) -      vty_out (vty, " ip irdp broadcast%s",  VTY_NEWLINE); -    else -      vty_out (vty, " ip irdp multicast%s",  VTY_NEWLINE); +		if (irdp->flags & IF_SHUTDOWN) +			vty_out(vty, " ip irdp shutdown %s", VTY_NEWLINE); -    vty_out (vty, " ip irdp preference %ld%s", -	     irdp->Preference, VTY_NEWLINE); +		if (irdp->flags & IF_BROADCAST) +			vty_out(vty, " ip irdp broadcast%s", VTY_NEWLINE); +		else +			vty_out(vty, " ip irdp multicast%s", VTY_NEWLINE); -    for (ALL_LIST_ELEMENTS_RO (irdp->AdvPrefList, node, adv)) -      vty_out (vty, " ip irdp address %s preference %d%s", -                    inet_2a(adv->ip.s_addr, b1), -                    adv->pref, -                    VTY_NEWLINE); +		vty_out(vty, " ip irdp preference %ld%s", irdp->Preference, +			VTY_NEWLINE); -    vty_out (vty, " ip irdp holdtime %d%s", -	     irdp->Lifetime, VTY_NEWLINE); +		for (ALL_LIST_ELEMENTS_RO(irdp->AdvPrefList, node, adv)) +			vty_out(vty, " ip irdp address %s preference %d%s", +				inet_2a(adv->ip.s_addr, b1), adv->pref, +				VTY_NEWLINE); -    vty_out (vty, " ip irdp minadvertinterval %ld%s", -	     irdp->MinAdvertInterval, VTY_NEWLINE); +		vty_out(vty, " ip irdp holdtime %d%s", irdp->Lifetime, +			VTY_NEWLINE); -    vty_out (vty, " ip irdp maxadvertinterval %ld%s", -	     irdp->MaxAdvertInterval, VTY_NEWLINE); +		vty_out(vty, " ip irdp minadvertinterval %ld%s", +			irdp->MinAdvertInterval, VTY_NEWLINE); -  } +		vty_out(vty, " ip irdp maxadvertinterval %ld%s", +			irdp->MaxAdvertInterval, VTY_NEWLINE); +	}  } @@ -381,10 +361,10 @@ DEFUN (ip_irdp_multicast,         "ICMP Router discovery on this interface\n"         "Use multicast mode\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); +	VTY_DECLVAR_CONTEXT(interface, ifp); -  irdp_if_start(ifp, TRUE, TRUE); -  return CMD_SUCCESS; +	irdp_if_start(ifp, TRUE, TRUE); +	return CMD_SUCCESS;  }  DEFUN (ip_irdp_broadcast, @@ -394,10 +374,10 @@ DEFUN (ip_irdp_broadcast,         "ICMP Router discovery on this interface\n"         "Use broadcast mode\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); +	VTY_DECLVAR_CONTEXT(interface, ifp); -  irdp_if_start(ifp, FALSE, TRUE); -  return CMD_SUCCESS; +	irdp_if_start(ifp, FALSE, TRUE); +	return CMD_SUCCESS;  }  DEFUN (no_ip_irdp, @@ -407,10 +387,10 @@ DEFUN (no_ip_irdp,         IP_STR         "Disable ICMP Router discovery on this interface\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); +	VTY_DECLVAR_CONTEXT(interface, ifp); -  irdp_if_stop(ifp); -  return CMD_SUCCESS; +	irdp_if_stop(ifp); +	return CMD_SUCCESS;  }  DEFUN (ip_irdp_shutdown, @@ -420,10 +400,10 @@ DEFUN (ip_irdp_shutdown,         "ICMP Router discovery on this interface\n"         "ICMP Router discovery shutdown on this interface\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); +	VTY_DECLVAR_CONTEXT(interface, ifp); -  irdp_if_shutdown(ifp); -  return CMD_SUCCESS; +	irdp_if_shutdown(ifp); +	return CMD_SUCCESS;  }  DEFUN (no_ip_irdp_shutdown, @@ -434,10 +414,10 @@ DEFUN (no_ip_irdp_shutdown,         "ICMP Router discovery on this interface\n"         "ICMP Router discovery no shutdown on this interface\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); +	VTY_DECLVAR_CONTEXT(interface, ifp); -  irdp_if_no_shutdown(ifp); -  return CMD_SUCCESS; +	irdp_if_no_shutdown(ifp); +	return CMD_SUCCESS;  }  DEFUN (ip_irdp_holdtime, @@ -448,16 +428,16 @@ DEFUN (ip_irdp_holdtime,         "Set holdtime value\n"         "Holdtime value in seconds. Default is 1800 seconds\n")  { -  int idx_number = 3; -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zi; -  struct irdp_interface *irdp; +	int idx_number = 3; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zi; +	struct irdp_interface *irdp; -  zi=ifp->info; -  irdp=&zi->irdp; +	zi = ifp->info; +	irdp = &zi->irdp; -  irdp->Lifetime = atoi(argv[idx_number]->arg); -  return CMD_SUCCESS; +	irdp->Lifetime = atoi(argv[idx_number]->arg); +	return CMD_SUCCESS;  }  DEFUN (ip_irdp_minadvertinterval, @@ -468,23 +448,24 @@ DEFUN (ip_irdp_minadvertinterval,         "Set minimum time between advertisement\n"         "Minimum advertisement interval in seconds\n")  { -  int idx_number = 3; -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zi; -  struct irdp_interface *irdp; - -  zi=ifp->info; -  irdp=&zi->irdp; - -  if((unsigned) atoi(argv[idx_number]->arg) <= irdp->MaxAdvertInterval) { -      irdp->MinAdvertInterval = atoi(argv[idx_number]->arg); -      return CMD_SUCCESS; -  } -  else { -      vty_out (vty, "%% MinAdvertInterval must be less than or equal to " -                    "MaxAdvertInterval%s", VTY_NEWLINE); -      return CMD_WARNING; -  } +	int idx_number = 3; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zi; +	struct irdp_interface *irdp; + +	zi = ifp->info; +	irdp = &zi->irdp; + +	if ((unsigned)atoi(argv[idx_number]->arg) <= irdp->MaxAdvertInterval) { +		irdp->MinAdvertInterval = atoi(argv[idx_number]->arg); +		return CMD_SUCCESS; +	} else { +		vty_out(vty, +			"%% MinAdvertInterval must be less than or equal to " +			"MaxAdvertInterval%s", +			VTY_NEWLINE); +		return CMD_WARNING; +	}  }  DEFUN (ip_irdp_maxadvertinterval, @@ -495,23 +476,24 @@ DEFUN (ip_irdp_maxadvertinterval,         "Set maximum time between advertisement\n"         "Maximum advertisement interval in seconds\n")  { -  int idx_number = 3; -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zi; -  struct irdp_interface *irdp; - -  zi=ifp->info; -  irdp=&zi->irdp; - -  if(irdp->MinAdvertInterval <= (unsigned) atoi(argv[idx_number]->arg)) { -      irdp->MaxAdvertInterval = atoi(argv[idx_number]->arg); -      return CMD_SUCCESS; -  } -  else { -      vty_out (vty, "%% MaxAdvertInterval must be greater than or equal to " -                    "MinAdvertInterval%s", VTY_NEWLINE); -      return CMD_WARNING; -  } +	int idx_number = 3; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zi; +	struct irdp_interface *irdp; + +	zi = ifp->info; +	irdp = &zi->irdp; + +	if (irdp->MinAdvertInterval <= (unsigned)atoi(argv[idx_number]->arg)) { +		irdp->MaxAdvertInterval = atoi(argv[idx_number]->arg); +		return CMD_SUCCESS; +	} else { +		vty_out(vty, +			"%% MaxAdvertInterval must be greater than or equal to " +			"MinAdvertInterval%s", +			VTY_NEWLINE); +		return CMD_WARNING; +	}  }  /* DEFUN needs to be fixed for negative ranages... @@ -527,16 +509,16 @@ DEFUN (ip_irdp_preference,         "Set default preference level for this interface\n"         "Preference level\n")  { -  int idx_number = 3; -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zi; -  struct irdp_interface *irdp; +	int idx_number = 3; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zi; +	struct irdp_interface *irdp; -  zi=ifp->info; -  irdp=&zi->irdp; +	zi = ifp->info; +	irdp = &zi->irdp; -  irdp->Preference = atoi(argv[idx_number]->arg); -  return CMD_SUCCESS; +	irdp->Preference = atoi(argv[idx_number]->arg); +	return CMD_SUCCESS;  }  DEFUN (ip_irdp_address_preference, @@ -549,36 +531,36 @@ DEFUN (ip_irdp_address_preference,         "Specify IRDP non-default preference to advertise\n"         "Preference level\n")  { -  int idx_ipv4 = 3; -  int idx_number = 5; -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct listnode *node; -  struct in_addr ip; -  int pref; -  int ret; -  struct zebra_if *zi; -  struct irdp_interface *irdp; -  struct Adv *adv; - -  zi=ifp->info; -  irdp=&zi->irdp; - -  ret = inet_aton(argv[idx_ipv4]->arg, &ip); -  if(!ret) return CMD_WARNING; - -  pref = atoi(argv[idx_number]->arg); - -  for (ALL_LIST_ELEMENTS_RO (irdp->AdvPrefList, node, adv)) -    if(adv->ip.s_addr == ip.s_addr) -      return CMD_SUCCESS; - -  adv = Adv_new(); -  adv->ip = ip; -  adv->pref = pref; -  listnode_add(irdp->AdvPrefList, adv); - -  return CMD_SUCCESS; - +	int idx_ipv4 = 3; +	int idx_number = 5; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct listnode *node; +	struct in_addr ip; +	int pref; +	int ret; +	struct zebra_if *zi; +	struct irdp_interface *irdp; +	struct Adv *adv; + +	zi = ifp->info; +	irdp = &zi->irdp; + +	ret = inet_aton(argv[idx_ipv4]->arg, &ip); +	if (!ret) +		return CMD_WARNING; + +	pref = atoi(argv[idx_number]->arg); + +	for (ALL_LIST_ELEMENTS_RO(irdp->AdvPrefList, node, adv)) +		if (adv->ip.s_addr == ip.s_addr) +			return CMD_SUCCESS; + +	adv = Adv_new(); +	adv->ip = ip; +	adv->pref = pref; +	listnode_add(irdp->AdvPrefList, adv); + +	return CMD_SUCCESS;  }  DEFUN (no_ip_irdp_address_preference, @@ -592,32 +574,30 @@ DEFUN (no_ip_irdp_address_preference,         "Reset ICMP Router discovery preference on this interface\n"         "Old preference level\n")  { -  int idx_ipv4 = 4; -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct listnode *node, *nnode; -  struct in_addr ip; -  int ret; -  struct zebra_if *zi; -  struct irdp_interface *irdp; -  struct Adv *adv; - -  zi=ifp->info; -  irdp=&zi->irdp; - -  ret = inet_aton(argv[idx_ipv4]->arg, &ip); -  if (!ret) -    return CMD_WARNING; - -  for (ALL_LIST_ELEMENTS (irdp->AdvPrefList, node, nnode, adv)) -    { -      if(adv->ip.s_addr == ip.s_addr ) -        { -          listnode_delete(irdp->AdvPrefList, adv); -          break; -        } -    } - -  return CMD_SUCCESS; +	int idx_ipv4 = 4; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct listnode *node, *nnode; +	struct in_addr ip; +	int ret; +	struct zebra_if *zi; +	struct irdp_interface *irdp; +	struct Adv *adv; + +	zi = ifp->info; +	irdp = &zi->irdp; + +	ret = inet_aton(argv[idx_ipv4]->arg, &ip); +	if (!ret) +		return CMD_WARNING; + +	for (ALL_LIST_ELEMENTS(irdp->AdvPrefList, node, nnode, adv)) { +		if (adv->ip.s_addr == ip.s_addr) { +			listnode_delete(irdp->AdvPrefList, adv); +			break; +		} +	} + +	return CMD_SUCCESS;  }  DEFUN (ip_irdp_debug_messages, @@ -628,16 +608,16 @@ DEFUN (ip_irdp_debug_messages,         "IRDP debugging options\n"         "Enable debugging for IRDP messages\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zi; -  struct irdp_interface *irdp; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zi; +	struct irdp_interface *irdp; -  zi=ifp->info; -  irdp=&zi->irdp; +	zi = ifp->info; +	irdp = &zi->irdp; -  irdp->flags |= IF_DEBUG_MESSAGES; +	irdp->flags |= IF_DEBUG_MESSAGES; -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (ip_irdp_debug_misc, @@ -648,16 +628,16 @@ DEFUN (ip_irdp_debug_misc,         "IRDP debugging options\n"         "Enable debugging for miscellaneous IRDP events\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zi; -  struct irdp_interface *irdp; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zi; +	struct irdp_interface *irdp; -  zi=ifp->info; -  irdp=&zi->irdp; +	zi = ifp->info; +	irdp = &zi->irdp; -  irdp->flags |= IF_DEBUG_MISC; +	irdp->flags |= IF_DEBUG_MISC; -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (ip_irdp_debug_packet, @@ -668,16 +648,16 @@ DEFUN (ip_irdp_debug_packet,         "IRDP debugging options\n"         "Enable debugging for IRDP packets\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zi; -  struct irdp_interface *irdp; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zi; +	struct irdp_interface *irdp; -  zi=ifp->info; -  irdp=&zi->irdp; +	zi = ifp->info; +	irdp = &zi->irdp; -  irdp->flags |= IF_DEBUG_PACKET; +	irdp->flags |= IF_DEBUG_PACKET; -  return CMD_SUCCESS; +	return CMD_SUCCESS;  } @@ -689,39 +669,38 @@ DEFUN (ip_irdp_debug_disable,         "IRDP debugging options\n"         "Disable debugging for all IRDP events\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zi; -  struct irdp_interface *irdp; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zi; +	struct irdp_interface *irdp; -  zi=ifp->info; -  irdp=&zi->irdp; +	zi = ifp->info; +	irdp = &zi->irdp; -  irdp->flags &= ~IF_DEBUG_PACKET; -  irdp->flags &= ~IF_DEBUG_MESSAGES; -  irdp->flags &= ~IF_DEBUG_MISC; +	irdp->flags &= ~IF_DEBUG_PACKET; +	irdp->flags &= ~IF_DEBUG_MESSAGES; +	irdp->flags &= ~IF_DEBUG_MISC; -  return CMD_SUCCESS; +	return CMD_SUCCESS;  } -void -irdp_init () +void irdp_init()  { -  install_element (INTERFACE_NODE, &ip_irdp_broadcast_cmd); -  install_element (INTERFACE_NODE, &ip_irdp_multicast_cmd); -  install_element (INTERFACE_NODE, &no_ip_irdp_cmd); -  install_element (INTERFACE_NODE, &ip_irdp_shutdown_cmd); -  install_element (INTERFACE_NODE, &no_ip_irdp_shutdown_cmd); -  install_element (INTERFACE_NODE, &ip_irdp_holdtime_cmd); -  install_element (INTERFACE_NODE, &ip_irdp_maxadvertinterval_cmd); -  install_element (INTERFACE_NODE, &ip_irdp_minadvertinterval_cmd); -  install_element (INTERFACE_NODE, &ip_irdp_preference_cmd); -  install_element (INTERFACE_NODE, &ip_irdp_address_preference_cmd); -  install_element (INTERFACE_NODE, &no_ip_irdp_address_preference_cmd); - -  install_element (INTERFACE_NODE, &ip_irdp_debug_messages_cmd); -  install_element (INTERFACE_NODE, &ip_irdp_debug_misc_cmd); -  install_element (INTERFACE_NODE, &ip_irdp_debug_packet_cmd); -  install_element (INTERFACE_NODE, &ip_irdp_debug_disable_cmd); +	install_element(INTERFACE_NODE, &ip_irdp_broadcast_cmd); +	install_element(INTERFACE_NODE, &ip_irdp_multicast_cmd); +	install_element(INTERFACE_NODE, &no_ip_irdp_cmd); +	install_element(INTERFACE_NODE, &ip_irdp_shutdown_cmd); +	install_element(INTERFACE_NODE, &no_ip_irdp_shutdown_cmd); +	install_element(INTERFACE_NODE, &ip_irdp_holdtime_cmd); +	install_element(INTERFACE_NODE, &ip_irdp_maxadvertinterval_cmd); +	install_element(INTERFACE_NODE, &ip_irdp_minadvertinterval_cmd); +	install_element(INTERFACE_NODE, &ip_irdp_preference_cmd); +	install_element(INTERFACE_NODE, &ip_irdp_address_preference_cmd); +	install_element(INTERFACE_NODE, &no_ip_irdp_address_preference_cmd); + +	install_element(INTERFACE_NODE, &ip_irdp_debug_messages_cmd); +	install_element(INTERFACE_NODE, &ip_irdp_debug_misc_cmd); +	install_element(INTERFACE_NODE, &ip_irdp_debug_packet_cmd); +	install_element(INTERFACE_NODE, &ip_irdp_debug_disable_cmd);  }  #endif /* HAVE_IRDP */ diff --git a/zebra/irdp_main.c b/zebra/irdp_main.c index 6965dca3e4..1a035aa3d8 100644 --- a/zebra/irdp_main.c +++ b/zebra/irdp_main.c @@ -18,17 +18,17 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */ -/*  +/*   * This work includes work with the following copywrite:   *   * Copyright (C) 1997, 2000 Kunihiro Ishiguro   *   */ -/*  +/*   * Thanks to Jens Låås at Swedish University of Agricultural Sciences   * for reviewing and tests.   */ @@ -75,260 +75,255 @@ struct thread *t_irdp_raw;  /* Timer interval of irdp. */  int irdp_timer_interval = IRDP_DEFAULT_INTERVAL; -int -irdp_sock_init (void) +int irdp_sock_init(void)  { -  int ret, i; -  int save_errno; -  int sock; - -  if ( zserv_privs.change (ZPRIVS_RAISE) ) -       zlog_err ("irdp_sock_init: could not raise privs, %s", -                  safe_strerror (errno) ); - -  sock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); -  save_errno = errno; - -  if ( zserv_privs.change (ZPRIVS_LOWER) ) -       zlog_err ("irdp_sock_init: could not lower privs, %s", -             safe_strerror (errno) ); - -  if (sock < 0) { -    zlog_warn ("IRDP: can't create irdp socket %s", safe_strerror(save_errno)); -    return sock; -  }; -   -  i = 1; -  ret = setsockopt (sock, IPPROTO_IP, IP_TTL,  -                        (void *) &i, sizeof (i)); -  if (ret < 0) { -    zlog_warn ("IRDP: can't do irdp sockopt %s", safe_strerror(errno)); -    close(sock); -    return ret; -  }; -   -  ret = setsockopt_ifindex (AF_INET, sock, 1); -  if (ret < 0) { -    zlog_warn ("IRDP: can't do irdp sockopt %s", safe_strerror(errno)); -    close(sock); -    return ret; -  }; - -  t_irdp_raw = thread_add_read (zebrad.master, irdp_read_raw, NULL, sock);  - -  return sock; +	int ret, i; +	int save_errno; +	int sock; + +	if (zserv_privs.change(ZPRIVS_RAISE)) +		zlog_err("irdp_sock_init: could not raise privs, %s", +			 safe_strerror(errno)); + +	sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); +	save_errno = errno; + +	if (zserv_privs.change(ZPRIVS_LOWER)) +		zlog_err("irdp_sock_init: could not lower privs, %s", +			 safe_strerror(errno)); + +	if (sock < 0) { +		zlog_warn("IRDP: can't create irdp socket %s", +			  safe_strerror(save_errno)); +		return sock; +	}; + +	i = 1; +	ret = setsockopt(sock, IPPROTO_IP, IP_TTL, (void *)&i, sizeof(i)); +	if (ret < 0) { +		zlog_warn("IRDP: can't do irdp sockopt %s", +			  safe_strerror(errno)); +		close(sock); +		return ret; +	}; + +	ret = setsockopt_ifindex(AF_INET, sock, 1); +	if (ret < 0) { +		zlog_warn("IRDP: can't do irdp sockopt %s", +			  safe_strerror(errno)); +		close(sock); +		return ret; +	}; + +	t_irdp_raw = thread_add_read(zebrad.master, irdp_read_raw, NULL, sock); + +	return sock;  } -static int -get_pref(struct irdp_interface *irdp, struct prefix *p) +static int get_pref(struct irdp_interface *irdp, struct prefix *p)  { -  struct listnode *node; -  struct Adv *adv; - -  /* Use default preference or use the override pref */ -   -  if( irdp->AdvPrefList == NULL ) -    return irdp->Preference; -   -  for (ALL_LIST_ELEMENTS_RO (irdp->AdvPrefList, node, adv)) -    if( p->u.prefix4.s_addr == adv->ip.s_addr ) -      return adv->pref; - -  return irdp->Preference; +	struct listnode *node; +	struct Adv *adv; + +	/* Use default preference or use the override pref */ + +	if (irdp->AdvPrefList == NULL) +		return irdp->Preference; + +	for (ALL_LIST_ELEMENTS_RO(irdp->AdvPrefList, node, adv)) +		if (p->u.prefix4.s_addr == adv->ip.s_addr) +			return adv->pref; + +	return irdp->Preference;  }  /* Make ICMP Router Advertisement Message. */ -static int -make_advertisement_packet (struct interface *ifp,  -			   struct prefix *p, -			   struct stream *s) +static int make_advertisement_packet(struct interface *ifp, struct prefix *p, +				     struct stream *s)  { -  struct zebra_if *zi=ifp->info; -  struct irdp_interface *irdp=&zi->irdp; -  int size; -  int pref; -  u_int16_t checksum; - -  pref =  get_pref(irdp, p); - -  stream_putc (s, ICMP_ROUTERADVERT); /* Type. */ -  stream_putc (s, 0);		/* Code. */ -  stream_putw (s, 0);		/* Checksum. */ -  stream_putc (s, 1);		/* Num address. */ -  stream_putc (s, 2);		/* Address Entry Size. */ - -  if(irdp->flags & IF_SHUTDOWN)   -    stream_putw (s, 0); -  else  -    stream_putw (s, irdp->Lifetime); - -  stream_putl (s, htonl(p->u.prefix4.s_addr)); /* Router address. */ -  stream_putl (s, pref); - -  /* in_cksum return network byte order value */ -  size = 16; -  checksum = in_cksum (s->data, size); -  stream_putw_at (s, 2, htons(checksum)); - -  return size; +	struct zebra_if *zi = ifp->info; +	struct irdp_interface *irdp = &zi->irdp; +	int size; +	int pref; +	u_int16_t checksum; + +	pref = get_pref(irdp, p); + +	stream_putc(s, ICMP_ROUTERADVERT); /* Type. */ +	stream_putc(s, 0);		   /* Code. */ +	stream_putw(s, 0);		   /* Checksum. */ +	stream_putc(s, 1);		   /* Num address. */ +	stream_putc(s, 2);		   /* Address Entry Size. */ + +	if (irdp->flags & IF_SHUTDOWN) +		stream_putw(s, 0); +	else +		stream_putw(s, irdp->Lifetime); + +	stream_putl(s, htonl(p->u.prefix4.s_addr)); /* Router address. */ +	stream_putl(s, pref); + +	/* in_cksum return network byte order value */ +	size = 16; +	checksum = in_cksum(s->data, size); +	stream_putw_at(s, 2, htons(checksum)); + +	return size;  } -static void -irdp_send(struct interface *ifp, struct prefix *p, struct stream *s) +static void irdp_send(struct interface *ifp, struct prefix *p, struct stream *s)  { -  struct zebra_if *zi=ifp->info; -  struct irdp_interface *irdp=&zi->irdp; -  char buf[PREFIX_STRLEN]; -  u_int32_t dst; -  u_int32_t ttl=1; - -  if (! (ifp->flags & IFF_UP)) return;  - -  if (irdp->flags & IF_BROADCAST)  -    dst =INADDR_BROADCAST ; -  else  -    dst = htonl(INADDR_ALLHOSTS_GROUP); - -  if(irdp->flags & IF_DEBUG_MESSAGES)  -    zlog_debug("IRDP: TX Advert on %s %s Holdtime=%d Preference=%d", -	      ifp->name, -	      prefix2str(p, buf, sizeof buf), -	      irdp->flags & IF_SHUTDOWN? 0 : irdp->Lifetime, -	      get_pref(irdp, p)); - -  send_packet (ifp, s, dst, p, ttl); +	struct zebra_if *zi = ifp->info; +	struct irdp_interface *irdp = &zi->irdp; +	char buf[PREFIX_STRLEN]; +	u_int32_t dst; +	u_int32_t ttl = 1; + +	if (!(ifp->flags & IFF_UP)) +		return; + +	if (irdp->flags & IF_BROADCAST) +		dst = INADDR_BROADCAST; +	else +		dst = htonl(INADDR_ALLHOSTS_GROUP); + +	if (irdp->flags & IF_DEBUG_MESSAGES) +		zlog_debug("IRDP: TX Advert on %s %s Holdtime=%d Preference=%d", +			   ifp->name, prefix2str(p, buf, sizeof buf), +			   irdp->flags & IF_SHUTDOWN ? 0 : irdp->Lifetime, +			   get_pref(irdp, p)); + +	send_packet(ifp, s, dst, p, ttl);  } -static void irdp_advertisement (struct interface *ifp, struct prefix *p) +static void irdp_advertisement(struct interface *ifp, struct prefix *p)  { -  struct stream *s; -  s = stream_new (128); -  make_advertisement_packet (ifp, p, s); -  irdp_send(ifp, p, s); -  stream_free (s); +	struct stream *s; +	s = stream_new(128); +	make_advertisement_packet(ifp, p, s); +	irdp_send(ifp, p, s); +	stream_free(s);  }  int irdp_send_thread(struct thread *t_advert)  { -  u_int32_t timer, tmp; -  struct interface *ifp = THREAD_ARG (t_advert); -  struct zebra_if *zi=ifp->info; -  struct irdp_interface *irdp=&zi->irdp; -  struct prefix *p; -  struct listnode *node, *nnode; -  struct connected *ifc; - -  irdp->flags &= ~IF_SOLICIT; - -  if(ifp->connected)  -    for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, ifc)) -      { -        p = ifc->address; -         -        if (p->family != AF_INET) -          continue; -         -        irdp_advertisement(ifp, p); -        irdp->irdp_sent++; -      } - -  tmp = irdp->MaxAdvertInterval-irdp->MinAdvertInterval; -  timer = random () % (tmp + 1); -  timer = irdp->MinAdvertInterval + timer; - -  if(irdp->irdp_sent <  MAX_INITIAL_ADVERTISEMENTS && -     timer > MAX_INITIAL_ADVERT_INTERVAL )  -	  timer= MAX_INITIAL_ADVERT_INTERVAL; - -  if(irdp->flags & IF_DEBUG_MISC) -    zlog_debug("IRDP: New timer for %s set to %u\n", ifp->name, timer); - -  irdp->t_advertise = thread_add_timer(zebrad.master, irdp_send_thread, ifp, timer); -  return 0; +	u_int32_t timer, tmp; +	struct interface *ifp = THREAD_ARG(t_advert); +	struct zebra_if *zi = ifp->info; +	struct irdp_interface *irdp = &zi->irdp; +	struct prefix *p; +	struct listnode *node, *nnode; +	struct connected *ifc; + +	irdp->flags &= ~IF_SOLICIT; + +	if (ifp->connected) +		for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, ifc)) { +			p = ifc->address; + +			if (p->family != AF_INET) +				continue; + +			irdp_advertisement(ifp, p); +			irdp->irdp_sent++; +		} + +	tmp = irdp->MaxAdvertInterval - irdp->MinAdvertInterval; +	timer = random() % (tmp + 1); +	timer = irdp->MinAdvertInterval + timer; + +	if (irdp->irdp_sent < MAX_INITIAL_ADVERTISEMENTS +	    && timer > MAX_INITIAL_ADVERT_INTERVAL) +		timer = MAX_INITIAL_ADVERT_INTERVAL; + +	if (irdp->flags & IF_DEBUG_MISC) +		zlog_debug("IRDP: New timer for %s set to %u\n", ifp->name, +			   timer); + +	irdp->t_advertise = +		thread_add_timer(zebrad.master, irdp_send_thread, ifp, timer); +	return 0;  }  void irdp_advert_off(struct interface *ifp)  { -  struct zebra_if *zi=ifp->info; -  struct irdp_interface *irdp=&zi->irdp; -  struct listnode *node, *nnode; -  int i; -  struct connected *ifc; -  struct prefix *p; - -  if(irdp->t_advertise)  thread_cancel(irdp->t_advertise); -  irdp->t_advertise = NULL; -   -  if(ifp->connected)  -    for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, ifc)) -      { -        p = ifc->address; - -        /* Output some packets with Lifetime 0  -           we should add a wait... -        */ - -        for(i=0; i< IRDP_LAST_ADVERT_MESSAGES; i++)  -          { -            irdp->irdp_sent++; -            irdp_advertisement(ifp, p); -          } -      } +	struct zebra_if *zi = ifp->info; +	struct irdp_interface *irdp = &zi->irdp; +	struct listnode *node, *nnode; +	int i; +	struct connected *ifc; +	struct prefix *p; + +	if (irdp->t_advertise) +		thread_cancel(irdp->t_advertise); +	irdp->t_advertise = NULL; + +	if (ifp->connected) +		for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, ifc)) { +			p = ifc->address; + +			/* Output some packets with Lifetime 0 +			   we should add a wait... +			*/ + +			for (i = 0; i < IRDP_LAST_ADVERT_MESSAGES; i++) { +				irdp->irdp_sent++; +				irdp_advertisement(ifp, p); +			} +		}  } -void process_solicit (struct interface *ifp) +void process_solicit(struct interface *ifp)  { -  struct zebra_if *zi=ifp->info; -  struct irdp_interface *irdp=&zi->irdp; -  u_int32_t timer; +	struct zebra_if *zi = ifp->info; +	struct irdp_interface *irdp = &zi->irdp; +	u_int32_t timer; -  /* When SOLICIT is active we reject further incoming solicits  -     this keeps down the answering rate so we don't have think -     about DoS attacks here. */ +	/* When SOLICIT is active we reject further incoming solicits +	   this keeps down the answering rate so we don't have think +	   about DoS attacks here. */ -  if( irdp->flags & IF_SOLICIT) return; +	if (irdp->flags & IF_SOLICIT) +		return; -  irdp->flags |= IF_SOLICIT; -  if(irdp->t_advertise)  thread_cancel(irdp->t_advertise); -  irdp->t_advertise = NULL; +	irdp->flags |= IF_SOLICIT; +	if (irdp->t_advertise) +		thread_cancel(irdp->t_advertise); +	irdp->t_advertise = NULL; -  timer =  (random () % MAX_RESPONSE_DELAY) + 1; +	timer = (random() % MAX_RESPONSE_DELAY) + 1; -  irdp->t_advertise = thread_add_timer(zebrad.master,  -				       irdp_send_thread,  -				       ifp,  -				       timer); +	irdp->t_advertise = +		thread_add_timer(zebrad.master, irdp_send_thread, ifp, timer);  }  void irdp_finish()  { -  struct vrf *vrf; -  struct listnode *node, *nnode; -  struct interface *ifp; -  struct zebra_if *zi; -  struct irdp_interface *irdp; - -  zlog_info("IRDP: Received shutdown notification."); -  -  RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) -    for (ALL_LIST_ELEMENTS (vrf->iflist, node, nnode, ifp)) -      { -        zi = ifp->info; - -        if (!zi)  -          continue; -        irdp = &zi->irdp; -        if (!irdp)  -          continue; - -        if (irdp->flags & IF_ACTIVE )  -          { -	    irdp->flags |= IF_SHUTDOWN; -	    irdp_advert_off(ifp); -          } -      } +	struct vrf *vrf; +	struct listnode *node, *nnode; +	struct interface *ifp; +	struct zebra_if *zi; +	struct irdp_interface *irdp; + +	zlog_info("IRDP: Received shutdown notification."); + +	RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id) +	for (ALL_LIST_ELEMENTS(vrf->iflist, node, nnode, ifp)) { +		zi = ifp->info; + +		if (!zi) +			continue; +		irdp = &zi->irdp; +		if (!irdp) +			continue; + +		if (irdp->flags & IF_ACTIVE) { +			irdp->flags |= IF_SHUTDOWN; +			irdp_advert_off(ifp); +		} +	}  }  #endif /* HAVE_IRDP */ diff --git a/zebra/irdp_packet.c b/zebra/irdp_packet.c index 4c58b6b35d..c03b37a34b 100644 --- a/zebra/irdp_packet.c +++ b/zebra/irdp_packet.c @@ -18,17 +18,17 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */ -/*  +/*   * This work includes work with the following copywrite:   *   * Copyright (C) 1997, 2000 Kunihiro Ishiguro   *   */ -/*  +/*   * Thanks to Jens Låås at Swedish University of Agricultural Sciences   * for reviewing and tests.   */ @@ -72,293 +72,287 @@ int irdp_sock = -1;  extern struct thread *t_irdp_raw; -static void -parse_irdp_packet(char *p,  -		  int len,  -		  struct interface *ifp) +static void parse_irdp_packet(char *p, int len, struct interface *ifp)  { -  struct ip *ip = (struct ip *)p ; -  struct icmphdr *icmp; -  struct in_addr src; -  int ip_hlen, iplen, datalen; -  struct zebra_if *zi; -  struct irdp_interface *irdp; - -  zi = ifp->info; -  if (!zi)  -    return; - -  irdp = &zi->irdp; -  if (!irdp)  -    return; - -  ip_hlen = ip->ip_hl << 2; -   -  sockopt_iphdrincl_swab_systoh (ip); -   -  iplen = ip->ip_len; -  datalen = len - ip_hlen; -  src = ip->ip_src; - -  if (len != iplen) -    { -      zlog_err ("IRDP: RX length doesnt match IP length"); -      return; -    } - -  if (iplen < ICMP_MINLEN)  -    { -      zlog_err ("IRDP: RX ICMP packet too short from %s\n", -  	      inet_ntoa (src)); -      return; -    } -     -  /* XXX: RAW doesnt receive link-layer, surely? ??? */ -  /* Check so we don't checksum packets longer than oure RX_BUF - (ethlen + -   len of IP-header) 14+20 */ -  if (iplen > IRDP_RX_BUF-34)  -    { -      zlog_err ("IRDP: RX ICMP packet too long from %s\n", -	        inet_ntoa (src)); -      return; -    } - -  icmp = (struct icmphdr *) (p+ip_hlen); - -  /* check icmp checksum */     -  if (in_cksum (icmp, datalen) != icmp->checksum)  -    { -      zlog_warn ("IRDP: RX ICMP packet from %s. Bad checksum, silently ignored", -                 inet_ntoa (src)); -      return; -    } -   -  /* Handle just only IRDP */ -  if (!(icmp->type == ICMP_ROUTERADVERT -        || icmp->type == ICMP_ROUTERSOLICIT)) -    return; -   -  if (icmp->code != 0)  -    { -      zlog_warn ("IRDP: RX packet type %d from %s. Bad ICMP type code," -                 " silently ignored", -                 icmp->type, inet_ntoa (src)); -      return; -    } - -  if (! ((ntohl (ip->ip_dst.s_addr) == INADDR_BROADCAST) -         && (irdp->flags & IF_BROADCAST)) -        || -        (ntohl (ip->ip_dst.s_addr) == INADDR_ALLRTRS_GROUP -         && !(irdp->flags & IF_BROADCAST))) -    { -      zlog_warn ("IRDP: RX illegal from %s to %s while %s operates in %s\n", -                 inet_ntoa (src), -                 ntohl (ip->ip_dst.s_addr) == INADDR_ALLRTRS_GROUP ? -                 "multicast" : inet_ntoa (ip->ip_dst), -                 ifp->name, -                 irdp->flags & IF_BROADCAST ? "broadcast" : "multicast"); - -      zlog_warn ("IRDP: Please correct settings\n"); -      return; -    } - -  switch (icmp->type)  -    { -    case ICMP_ROUTERADVERT: -      break; - -    case ICMP_ROUTERSOLICIT: - -      if(irdp->flags & IF_DEBUG_MESSAGES)  -	zlog_debug ("IRDP: RX Solicit on %s from %s\n", -		    ifp->name, -		    inet_ntoa (src)); - -      process_solicit(ifp); -      break; - -    default: -      zlog_warn ("IRDP: RX type %d from %s. Bad ICMP type, silently ignored", -		 icmp->type, -		 inet_ntoa (src)); -    } +	struct ip *ip = (struct ip *)p; +	struct icmphdr *icmp; +	struct in_addr src; +	int ip_hlen, iplen, datalen; +	struct zebra_if *zi; +	struct irdp_interface *irdp; + +	zi = ifp->info; +	if (!zi) +		return; + +	irdp = &zi->irdp; +	if (!irdp) +		return; + +	ip_hlen = ip->ip_hl << 2; + +	sockopt_iphdrincl_swab_systoh(ip); + +	iplen = ip->ip_len; +	datalen = len - ip_hlen; +	src = ip->ip_src; + +	if (len != iplen) { +		zlog_err("IRDP: RX length doesnt match IP length"); +		return; +	} + +	if (iplen < ICMP_MINLEN) { +		zlog_err("IRDP: RX ICMP packet too short from %s\n", +			 inet_ntoa(src)); +		return; +	} + +	/* XXX: RAW doesnt receive link-layer, surely? ??? */ +	/* Check so we don't checksum packets longer than oure RX_BUF - (ethlen +	 + +	 len of IP-header) 14+20 */ +	if (iplen > IRDP_RX_BUF - 34) { +		zlog_err("IRDP: RX ICMP packet too long from %s\n", +			 inet_ntoa(src)); +		return; +	} + +	icmp = (struct icmphdr *)(p + ip_hlen); + +	/* check icmp checksum */ +	if (in_cksum(icmp, datalen) != icmp->checksum) { +		zlog_warn( +			"IRDP: RX ICMP packet from %s. Bad checksum, silently ignored", +			inet_ntoa(src)); +		return; +	} + +	/* Handle just only IRDP */ +	if (!(icmp->type == ICMP_ROUTERADVERT +	      || icmp->type == ICMP_ROUTERSOLICIT)) +		return; + +	if (icmp->code != 0) { +		zlog_warn( +			"IRDP: RX packet type %d from %s. Bad ICMP type code," +			" silently ignored", +			icmp->type, inet_ntoa(src)); +		return; +	} + +	if (!((ntohl(ip->ip_dst.s_addr) == INADDR_BROADCAST) +	      && (irdp->flags & IF_BROADCAST)) +	    || (ntohl(ip->ip_dst.s_addr) == INADDR_ALLRTRS_GROUP +		&& !(irdp->flags & IF_BROADCAST))) { +		zlog_warn( +			"IRDP: RX illegal from %s to %s while %s operates in %s\n", +			inet_ntoa(src), +			ntohl(ip->ip_dst.s_addr) == INADDR_ALLRTRS_GROUP +				? "multicast" +				: inet_ntoa(ip->ip_dst), +			ifp->name, +			irdp->flags & IF_BROADCAST ? "broadcast" : "multicast"); + +		zlog_warn("IRDP: Please correct settings\n"); +		return; +	} + +	switch (icmp->type) { +	case ICMP_ROUTERADVERT: +		break; + +	case ICMP_ROUTERSOLICIT: + +		if (irdp->flags & IF_DEBUG_MESSAGES) +			zlog_debug("IRDP: RX Solicit on %s from %s\n", +				   ifp->name, inet_ntoa(src)); + +		process_solicit(ifp); +		break; + +	default: +		zlog_warn( +			"IRDP: RX type %d from %s. Bad ICMP type, silently ignored", +			icmp->type, inet_ntoa(src)); +	}  } -static int -irdp_recvmsg (int sock, u_char *buf, int size, int *ifindex) +static int irdp_recvmsg(int sock, u_char *buf, int size, int *ifindex)  { -  struct msghdr msg; -  struct iovec iov; -  char adata[CMSG_SPACE( SOPT_SIZE_CMSG_PKTINFO_IPV4() )]; -  int ret; - -  msg.msg_name = (void *)0; -  msg.msg_namelen = 0; -  msg.msg_iov = &iov; -  msg.msg_iovlen = 1; -  msg.msg_control = (void *) adata; -  msg.msg_controllen = sizeof adata; - -  iov.iov_base = buf; -  iov.iov_len = size; - -  ret = recvmsg (sock, &msg, 0); -  if (ret < 0) { -    zlog_warn("IRDP: recvmsg: read error %s", safe_strerror(errno)); -    return ret; -  } - -  if (msg.msg_flags & MSG_TRUNC) { -    zlog_warn("IRDP: recvmsg: truncated message"); -    return ret; -  } -  if (msg.msg_flags & MSG_CTRUNC) { -    zlog_warn("IRDP: recvmsg: truncated control message"); -    return ret; -  } - -  *ifindex = getsockopt_ifindex (AF_INET, &msg); - -  return ret; +	struct msghdr msg; +	struct iovec iov; +	char adata[CMSG_SPACE(SOPT_SIZE_CMSG_PKTINFO_IPV4())]; +	int ret; + +	msg.msg_name = (void *)0; +	msg.msg_namelen = 0; +	msg.msg_iov = &iov; +	msg.msg_iovlen = 1; +	msg.msg_control = (void *)adata; +	msg.msg_controllen = sizeof adata; + +	iov.iov_base = buf; +	iov.iov_len = size; + +	ret = recvmsg(sock, &msg, 0); +	if (ret < 0) { +		zlog_warn("IRDP: recvmsg: read error %s", safe_strerror(errno)); +		return ret; +	} + +	if (msg.msg_flags & MSG_TRUNC) { +		zlog_warn("IRDP: recvmsg: truncated message"); +		return ret; +	} +	if (msg.msg_flags & MSG_CTRUNC) { +		zlog_warn("IRDP: recvmsg: truncated control message"); +		return ret; +	} + +	*ifindex = getsockopt_ifindex(AF_INET, &msg); + +	return ret;  }  int irdp_read_raw(struct thread *r)  { -  struct interface *ifp; -  struct zebra_if *zi; -  struct irdp_interface *irdp; -  char buf[IRDP_RX_BUF]; -  int ret, ifindex = 0; -   -  int irdp_sock = THREAD_FD (r); -  t_irdp_raw = thread_add_read (zebrad.master, irdp_read_raw, NULL, irdp_sock); -   -  ret = irdp_recvmsg (irdp_sock, (u_char *) buf, IRDP_RX_BUF,  &ifindex); -  -  if (ret < 0) zlog_warn ("IRDP: RX Error length = %d", ret); - -  ifp = if_lookup_by_index(ifindex, VRF_DEFAULT); -  if(! ifp ) return ret; - -  zi= ifp->info; -  if(! zi ) return ret; - -  irdp = &zi->irdp; -  if(! irdp ) return ret; - -  if(! (irdp->flags & IF_ACTIVE)) { - -    if(irdp->flags & IF_DEBUG_MISC)  -      zlog_debug("IRDP: RX ICMP for disabled interface %s\n", ifp->name); -    return 0; -  } - -  if(irdp->flags & IF_DEBUG_PACKET) { -    int i; -    zlog_debug("IRDP: RX (idx %d) ", ifindex); -    for(i=0; i < ret; i++) zlog_debug( "IRDP: RX %x ", buf[i]&0xFF); -  } - -  parse_irdp_packet(buf, ret, ifp); - -  return ret; +	struct interface *ifp; +	struct zebra_if *zi; +	struct irdp_interface *irdp; +	char buf[IRDP_RX_BUF]; +	int ret, ifindex = 0; + +	int irdp_sock = THREAD_FD(r); +	t_irdp_raw = +		thread_add_read(zebrad.master, irdp_read_raw, NULL, irdp_sock); + +	ret = irdp_recvmsg(irdp_sock, (u_char *)buf, IRDP_RX_BUF, &ifindex); + +	if (ret < 0) +		zlog_warn("IRDP: RX Error length = %d", ret); + +	ifp = if_lookup_by_index(ifindex, VRF_DEFAULT); +	if (!ifp) +		return ret; + +	zi = ifp->info; +	if (!zi) +		return ret; + +	irdp = &zi->irdp; +	if (!irdp) +		return ret; + +	if (!(irdp->flags & IF_ACTIVE)) { + +		if (irdp->flags & IF_DEBUG_MISC) +			zlog_debug("IRDP: RX ICMP for disabled interface %s\n", +				   ifp->name); +		return 0; +	} + +	if (irdp->flags & IF_DEBUG_PACKET) { +		int i; +		zlog_debug("IRDP: RX (idx %d) ", ifindex); +		for (i = 0; i < ret; i++) +			zlog_debug("IRDP: RX %x ", buf[i] & 0xFF); +	} + +	parse_irdp_packet(buf, ret, ifp); + +	return ret;  } -void  -send_packet(struct interface *ifp,  -	    struct stream *s, -	    u_int32_t dst, -	    struct prefix *p, -	    u_int32_t ttl) +void send_packet(struct interface *ifp, struct stream *s, u_int32_t dst, +		 struct prefix *p, u_int32_t ttl)  { -  static struct sockaddr_in sockdst = {AF_INET}; -  struct ip *ip; -  struct icmphdr *icmp; -  struct msghdr *msg; -  struct cmsghdr *cmsg; -  struct iovec iovector; -  char msgbuf[256]; -  char buf[256]; -  struct in_pktinfo *pktinfo; -  u_long src; -  u_char on; -  -  if (!(ifp->flags & IFF_UP)) -    return; - -  if (p) -    src = ntohl(p->u.prefix4.s_addr); -  else  -    src = 0; /* Is filled in */ -   -  ip = (struct ip *) buf; -  ip->ip_hl = sizeof(struct ip) >> 2; -  ip->ip_v = IPVERSION; -  ip->ip_tos = 0xC0; -  ip->ip_off = 0L; -  ip->ip_p = 1;       /* IP_ICMP */ -  ip->ip_ttl = ttl; -  ip->ip_src.s_addr = src; -  ip->ip_dst.s_addr = dst; -  icmp = (struct icmphdr *) (buf + sizeof (struct ip)); - -  /* Merge IP header with icmp packet */ -  assert (stream_get_endp(s) < (sizeof (buf) - sizeof (struct ip))); -  stream_get(icmp, s, stream_get_endp(s)); - -  /* icmp->checksum is already calculated */ -  ip->ip_len  = sizeof(struct ip) + stream_get_endp(s); - -  on = 1; -  if (setsockopt(irdp_sock, IPPROTO_IP, IP_HDRINCL, -		 (char *) &on, sizeof(on)) < 0) -    zlog_warn("sendto %s", safe_strerror (errno)); - - -  if(dst == INADDR_BROADCAST ) { -    on = 1; -    if (setsockopt(irdp_sock, SOL_SOCKET, SO_BROADCAST, -		   (char *) &on, sizeof(on)) < 0) -      zlog_warn("sendto %s", safe_strerror (errno)); -  } - -  if(dst !=  INADDR_BROADCAST) -    setsockopt_ipv4_multicast_loop (irdp_sock, 0); - -  memset(&sockdst,0,sizeof(sockdst)); -  sockdst.sin_family=AF_INET; -  sockdst.sin_addr.s_addr = dst; - -  cmsg = (struct cmsghdr *) (msgbuf + sizeof(struct msghdr)); -  cmsg->cmsg_len = sizeof(struct cmsghdr) + sizeof(struct in_pktinfo); -  cmsg->cmsg_level = SOL_IP; -  cmsg->cmsg_type = IP_PKTINFO; -  pktinfo = (struct in_pktinfo *) CMSG_DATA(cmsg); -  pktinfo->ipi_ifindex = ifp->ifindex; -  pktinfo->ipi_spec_dst.s_addr = src; -  pktinfo->ipi_addr.s_addr = src; -  -  iovector.iov_base = (void *) buf; -  iovector.iov_len = ip->ip_len;  -  msg = (struct msghdr *) msgbuf; -  msg->msg_name = &sockdst; -  msg->msg_namelen = sizeof(sockdst); -  msg->msg_iov = &iovector; -  msg->msg_iovlen = 1; -  msg->msg_control = cmsg; -  msg->msg_controllen = cmsg->cmsg_len; -  -  sockopt_iphdrincl_swab_htosys (ip); -   -  if (sendmsg(irdp_sock, msg, 0) < 0) { -    zlog_warn("sendto %s", safe_strerror (errno)); -  } -  /*   printf("TX on %s idx %d\n", ifp->name, ifp->ifindex); */ +	static struct sockaddr_in sockdst = {AF_INET}; +	struct ip *ip; +	struct icmphdr *icmp; +	struct msghdr *msg; +	struct cmsghdr *cmsg; +	struct iovec iovector; +	char msgbuf[256]; +	char buf[256]; +	struct in_pktinfo *pktinfo; +	u_long src; +	u_char on; + +	if (!(ifp->flags & IFF_UP)) +		return; + +	if (p) +		src = ntohl(p->u.prefix4.s_addr); +	else +		src = 0; /* Is filled in */ + +	ip = (struct ip *)buf; +	ip->ip_hl = sizeof(struct ip) >> 2; +	ip->ip_v = IPVERSION; +	ip->ip_tos = 0xC0; +	ip->ip_off = 0L; +	ip->ip_p = 1; /* IP_ICMP */ +	ip->ip_ttl = ttl; +	ip->ip_src.s_addr = src; +	ip->ip_dst.s_addr = dst; +	icmp = (struct icmphdr *)(buf + sizeof(struct ip)); + +	/* Merge IP header with icmp packet */ +	assert(stream_get_endp(s) < (sizeof(buf) - sizeof(struct ip))); +	stream_get(icmp, s, stream_get_endp(s)); + +	/* icmp->checksum is already calculated */ +	ip->ip_len = sizeof(struct ip) + stream_get_endp(s); + +	on = 1; +	if (setsockopt(irdp_sock, IPPROTO_IP, IP_HDRINCL, (char *)&on, +		       sizeof(on)) +	    < 0) +		zlog_warn("sendto %s", safe_strerror(errno)); + + +	if (dst == INADDR_BROADCAST) { +		on = 1; +		if (setsockopt(irdp_sock, SOL_SOCKET, SO_BROADCAST, (char *)&on, +			       sizeof(on)) +		    < 0) +			zlog_warn("sendto %s", safe_strerror(errno)); +	} + +	if (dst != INADDR_BROADCAST) +		setsockopt_ipv4_multicast_loop(irdp_sock, 0); + +	memset(&sockdst, 0, sizeof(sockdst)); +	sockdst.sin_family = AF_INET; +	sockdst.sin_addr.s_addr = dst; + +	cmsg = (struct cmsghdr *)(msgbuf + sizeof(struct msghdr)); +	cmsg->cmsg_len = sizeof(struct cmsghdr) + sizeof(struct in_pktinfo); +	cmsg->cmsg_level = SOL_IP; +	cmsg->cmsg_type = IP_PKTINFO; +	pktinfo = (struct in_pktinfo *)CMSG_DATA(cmsg); +	pktinfo->ipi_ifindex = ifp->ifindex; +	pktinfo->ipi_spec_dst.s_addr = src; +	pktinfo->ipi_addr.s_addr = src; + +	iovector.iov_base = (void *)buf; +	iovector.iov_len = ip->ip_len; +	msg = (struct msghdr *)msgbuf; +	msg->msg_name = &sockdst; +	msg->msg_namelen = sizeof(sockdst); +	msg->msg_iov = &iovector; +	msg->msg_iovlen = 1; +	msg->msg_control = cmsg; +	msg->msg_controllen = cmsg->cmsg_len; + +	sockopt_iphdrincl_swab_htosys(ip); + +	if (sendmsg(irdp_sock, msg, 0) < 0) { +		zlog_warn("sendto %s", safe_strerror(errno)); +	} +	/*   printf("TX on %s idx %d\n", ifp->name, ifp->ifindex); */  }  #endif /* HAVE_IRDP */ - - - diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index 9faf925522..f3ca12abf3 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -16,7 +16,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #include <zebra.h> @@ -54,13 +54,13 @@  #endif /* MSG_TRUNC */  #ifndef NLMSG_TAIL -#define NLMSG_TAIL(nmsg) \ -        ((struct rtattr *) (((u_char *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len))) +#define NLMSG_TAIL(nmsg)                                                       \ +	((struct rtattr *)(((u_char *)(nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))  #endif  #ifndef RTA_TAIL -#define RTA_TAIL(rta) \ -        ((struct rtattr *) (((u_char *) (rta)) + RTA_ALIGN((rta)->rta_len))) +#define RTA_TAIL(rta)                                                          \ +	((struct rtattr *)(((u_char *)(rta)) + RTA_ALIGN((rta)->rta_len)))  #endif  #ifndef RTNL_FAMILY_IP6MR @@ -71,374 +71,342 @@  #define RTPROT_MROUTED 17  #endif -static const struct message nlmsg_str[] = { -  {RTM_NEWROUTE, "RTM_NEWROUTE"}, -  {RTM_DELROUTE, "RTM_DELROUTE"}, -  {RTM_GETROUTE, "RTM_GETROUTE"}, -  {RTM_NEWLINK,  "RTM_NEWLINK"}, -  {RTM_DELLINK,  "RTM_DELLINK"}, -  {RTM_GETLINK,  "RTM_GETLINK"}, -  {RTM_NEWADDR,  "RTM_NEWADDR"}, -  {RTM_DELADDR,  "RTM_DELADDR"}, -  {RTM_GETADDR,  "RTM_GETADDR"}, -  {RTM_NEWNEIGH, "RTM_NEWNEIGH"}, -  {RTM_DELNEIGH, "RTM_DELNEIGH"}, -  {RTM_GETNEIGH, "RTM_GETNEIGH"}, -  { 0 } -}; +static const struct message nlmsg_str[] = {{RTM_NEWROUTE, "RTM_NEWROUTE"}, +					   {RTM_DELROUTE, "RTM_DELROUTE"}, +					   {RTM_GETROUTE, "RTM_GETROUTE"}, +					   {RTM_NEWLINK, "RTM_NEWLINK"}, +					   {RTM_DELLINK, "RTM_DELLINK"}, +					   {RTM_GETLINK, "RTM_GETLINK"}, +					   {RTM_NEWADDR, "RTM_NEWADDR"}, +					   {RTM_DELADDR, "RTM_DELADDR"}, +					   {RTM_GETADDR, "RTM_GETADDR"}, +					   {RTM_NEWNEIGH, "RTM_NEWNEIGH"}, +					   {RTM_DELNEIGH, "RTM_DELNEIGH"}, +					   {RTM_GETNEIGH, "RTM_GETNEIGH"}, +					   {0}};  static const struct message rtproto_str[] = { -  {RTPROT_REDIRECT, "redirect"}, -  {RTPROT_KERNEL,   "kernel"}, -  {RTPROT_BOOT,     "boot"}, -  {RTPROT_STATIC,   "static"}, -  {RTPROT_GATED,    "GateD"}, -  {RTPROT_RA,       "router advertisement"}, -  {RTPROT_MRT,      "MRT"}, -  {RTPROT_ZEBRA,    "Zebra"}, +	{RTPROT_REDIRECT, "redirect"}, {RTPROT_KERNEL, "kernel"}, +	{RTPROT_BOOT, "boot"},	 {RTPROT_STATIC, "static"}, +	{RTPROT_GATED, "GateD"},       {RTPROT_RA, "router advertisement"}, +	{RTPROT_MRT, "MRT"},	   {RTPROT_ZEBRA, "Zebra"},  #ifdef RTPROT_BIRD -  {RTPROT_BIRD,     "BIRD"}, +	{RTPROT_BIRD, "BIRD"},  #endif /* RTPROT_BIRD */ -  {RTPROT_MROUTED,  "mroute"}, -  { 0 } -}; - -static const struct message family_str[] = { -  {AF_INET,           "ipv4"}, -  {AF_INET6,          "ipv6"}, -  {AF_BRIDGE,         "bridge"}, -  {RTNL_FAMILY_IPMR,  "ipv4MR"}, -  {RTNL_FAMILY_IP6MR, "ipv6MR"}, -  { 0 } -}; - -static const struct message rttype_str[] = { -  {RTN_UNICAST,   "unicast"}, -  {RTN_MULTICAST, "multicast"}, -  { 0 } -}; +	{RTPROT_MROUTED, "mroute"},    {0}}; + +static const struct message family_str[] = {{AF_INET, "ipv4"}, +					    {AF_INET6, "ipv6"}, +					    {AF_BRIDGE, "bridge"}, +					    {RTNL_FAMILY_IPMR, "ipv4MR"}, +					    {RTNL_FAMILY_IP6MR, "ipv6MR"}, +					    {0}}; + +static const struct message rttype_str[] = {{RTN_UNICAST, "unicast"}, +					    {RTN_MULTICAST, "multicast"}, +					    {0}};  extern struct thread_master *master;  extern u_int32_t nl_rcvbufsize;  extern struct zebra_privs_t zserv_privs; -int -netlink_talk_filter (struct sockaddr_nl *snl, struct nlmsghdr *h, -                     ns_id_t ns_id, int startup) +int netlink_talk_filter(struct sockaddr_nl *snl, struct nlmsghdr *h, +			ns_id_t ns_id, int startup)  { -  zlog_warn ("netlink_talk: ignoring message type 0x%04x NS %u", h->nlmsg_type, -             ns_id); -  return 0; +	zlog_warn("netlink_talk: ignoring message type 0x%04x NS %u", +		  h->nlmsg_type, ns_id); +	return 0;  } -static int -netlink_recvbuf (struct nlsock *nl, uint32_t newsize) +static int netlink_recvbuf(struct nlsock *nl, uint32_t newsize)  { -  u_int32_t oldsize; -  socklen_t newlen = sizeof(newsize); -  socklen_t oldlen = sizeof(oldsize); -  int ret; - -  ret = getsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &oldsize, &oldlen); -  if (ret < 0) -    { -      zlog_err("Can't get %s receive buffer size: %s", nl->name, -               safe_strerror(errno)); -      return -1; -    } - -  /* Try force option (linux >= 2.6.14) and fall back to normal set */ -  if ( zserv_privs.change (ZPRIVS_RAISE) ) -    zlog_err ("routing_socket: Can't raise privileges"); -  ret = setsockopt(nl->sock, SOL_SOCKET, SO_RCVBUFFORCE, &nl_rcvbufsize, -		   sizeof(nl_rcvbufsize)); -  if ( zserv_privs.change (ZPRIVS_LOWER) ) -    zlog_err ("routing_socket: Can't lower privileges"); -  if (ret < 0) -     ret = setsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &nl_rcvbufsize, -		      sizeof(nl_rcvbufsize)); -  if (ret < 0) -    { -      zlog_err("Can't set %s receive buffer size: %s", nl->name, -               safe_strerror(errno)); -      return -1; -    } - -  ret = getsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &newsize, &newlen); -  if (ret < 0) -    { -      zlog_err("Can't get %s receive buffer size: %s", nl->name, -               safe_strerror(errno)); -      return -1; -    } - -  zlog_info("Setting netlink socket receive buffer size: %u -> %u", oldsize, -            newsize); -  return 0; +	u_int32_t oldsize; +	socklen_t newlen = sizeof(newsize); +	socklen_t oldlen = sizeof(oldsize); +	int ret; + +	ret = getsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &oldsize, &oldlen); +	if (ret < 0) { +		zlog_err("Can't get %s receive buffer size: %s", nl->name, +			 safe_strerror(errno)); +		return -1; +	} + +	/* Try force option (linux >= 2.6.14) and fall back to normal set */ +	if (zserv_privs.change(ZPRIVS_RAISE)) +		zlog_err("routing_socket: Can't raise privileges"); +	ret = setsockopt(nl->sock, SOL_SOCKET, SO_RCVBUFFORCE, &nl_rcvbufsize, +			 sizeof(nl_rcvbufsize)); +	if (zserv_privs.change(ZPRIVS_LOWER)) +		zlog_err("routing_socket: Can't lower privileges"); +	if (ret < 0) +		ret = setsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, +				 &nl_rcvbufsize, sizeof(nl_rcvbufsize)); +	if (ret < 0) { +		zlog_err("Can't set %s receive buffer size: %s", nl->name, +			 safe_strerror(errno)); +		return -1; +	} + +	ret = getsockopt(nl->sock, SOL_SOCKET, SO_RCVBUF, &newsize, &newlen); +	if (ret < 0) { +		zlog_err("Can't get %s receive buffer size: %s", nl->name, +			 safe_strerror(errno)); +		return -1; +	} + +	zlog_info("Setting netlink socket receive buffer size: %u -> %u", +		  oldsize, newsize); +	return 0;  }  /* Make socket for Linux netlink interface. */ -static int -netlink_socket (struct nlsock *nl, unsigned long groups, ns_id_t ns_id) +static int netlink_socket(struct nlsock *nl, unsigned long groups, +			  ns_id_t ns_id)  { -  int ret; -  struct sockaddr_nl snl; -  int sock; -  int namelen; -  int save_errno; - -  if (zserv_privs.change (ZPRIVS_RAISE)) -    { -      zlog_err("Can't raise privileges"); -      return -1; -    } - -  sock = socket (AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); -  if (sock < 0) -    { -      zlog_err("Can't open %s socket: %s", nl->name, safe_strerror(errno)); -      return -1; -    } - -  memset (&snl, 0, sizeof snl); -  snl.nl_family = AF_NETLINK; -  snl.nl_groups = groups; - -  /* Bind the socket to the netlink structure for anything. */ -  ret = bind (sock, (struct sockaddr *) &snl, sizeof snl); -  save_errno = errno; -  if (zserv_privs.change (ZPRIVS_LOWER)) -    zlog_err("Can't lower privileges"); - -  if (ret < 0) -    { -      zlog_err("Can't bind %s socket to group 0x%x: %s", nl->name, -               snl.nl_groups, safe_strerror(save_errno)); -      close (sock); -      return -1; -    } - -  /* multiple netlink sockets will have different nl_pid */ -  namelen = sizeof snl; -  ret = getsockname (sock, (struct sockaddr *) &snl, (socklen_t *) &namelen); -  if (ret < 0 || namelen != sizeof snl) -    { -      zlog_err("Can't get %s socket name: %s", nl->name, safe_strerror(errno)); -      close (sock); -      return -1; -    } - -  nl->snl = snl; -  nl->sock = sock; -  return ret; +	int ret; +	struct sockaddr_nl snl; +	int sock; +	int namelen; +	int save_errno; + +	if (zserv_privs.change(ZPRIVS_RAISE)) { +		zlog_err("Can't raise privileges"); +		return -1; +	} + +	sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); +	if (sock < 0) { +		zlog_err("Can't open %s socket: %s", nl->name, +			 safe_strerror(errno)); +		return -1; +	} + +	memset(&snl, 0, sizeof snl); +	snl.nl_family = AF_NETLINK; +	snl.nl_groups = groups; + +	/* Bind the socket to the netlink structure for anything. */ +	ret = bind(sock, (struct sockaddr *)&snl, sizeof snl); +	save_errno = errno; +	if (zserv_privs.change(ZPRIVS_LOWER)) +		zlog_err("Can't lower privileges"); + +	if (ret < 0) { +		zlog_err("Can't bind %s socket to group 0x%x: %s", nl->name, +			 snl.nl_groups, safe_strerror(save_errno)); +		close(sock); +		return -1; +	} + +	/* multiple netlink sockets will have different nl_pid */ +	namelen = sizeof snl; +	ret = getsockname(sock, (struct sockaddr *)&snl, (socklen_t *)&namelen); +	if (ret < 0 || namelen != sizeof snl) { +		zlog_err("Can't get %s socket name: %s", nl->name, +			 safe_strerror(errno)); +		close(sock); +		return -1; +	} + +	nl->snl = snl; +	nl->sock = sock; +	return ret;  } -static int -netlink_information_fetch (struct sockaddr_nl *snl, struct nlmsghdr *h, -                           ns_id_t ns_id, int startup) +static int netlink_information_fetch(struct sockaddr_nl *snl, +				     struct nlmsghdr *h, ns_id_t ns_id, +				     int startup)  { -  /* JF: Ignore messages that aren't from the kernel */ -  if ( snl->nl_pid != 0 ) -    { -      zlog_err("Ignoring message from pid %u", snl->nl_pid); -      return 0; -    } - -  switch (h->nlmsg_type) -    { -    case RTM_NEWROUTE: -      return netlink_route_change (snl, h, ns_id, startup); -      break; -    case RTM_DELROUTE: -      return netlink_route_change (snl, h, ns_id, startup); -      break; -    case RTM_NEWLINK: -      return netlink_link_change (snl, h, ns_id, startup); -      break; -    case RTM_DELLINK: -      return netlink_link_change (snl, h, ns_id, startup); -      break; -    case RTM_NEWADDR: -      return netlink_interface_addr (snl, h, ns_id, startup); -      break; -    case RTM_DELADDR: -      return netlink_interface_addr (snl, h, ns_id, startup); -      break; -    default: -      zlog_warn ("Unknown netlink nlmsg_type %d vrf %u\n", h->nlmsg_type, -                 ns_id); -      break; -    } -  return 0; +	/* JF: Ignore messages that aren't from the kernel */ +	if (snl->nl_pid != 0) { +		zlog_err("Ignoring message from pid %u", snl->nl_pid); +		return 0; +	} + +	switch (h->nlmsg_type) { +	case RTM_NEWROUTE: +		return netlink_route_change(snl, h, ns_id, startup); +		break; +	case RTM_DELROUTE: +		return netlink_route_change(snl, h, ns_id, startup); +		break; +	case RTM_NEWLINK: +		return netlink_link_change(snl, h, ns_id, startup); +		break; +	case RTM_DELLINK: +		return netlink_link_change(snl, h, ns_id, startup); +		break; +	case RTM_NEWADDR: +		return netlink_interface_addr(snl, h, ns_id, startup); +		break; +	case RTM_DELADDR: +		return netlink_interface_addr(snl, h, ns_id, startup); +		break; +	default: +		zlog_warn("Unknown netlink nlmsg_type %d vrf %u\n", +			  h->nlmsg_type, ns_id); +		break; +	} +	return 0;  } -static int -kernel_read (struct thread *thread) +static int kernel_read(struct thread *thread)  { -  struct zebra_ns *zns = (struct zebra_ns *)THREAD_ARG (thread); -  netlink_parse_info (netlink_information_fetch, &zns->netlink, zns, 5, 0); -  zns->t_netlink = thread_add_read (zebrad.master, kernel_read, zns, -                                     zns->netlink.sock); +	struct zebra_ns *zns = (struct zebra_ns *)THREAD_ARG(thread); +	netlink_parse_info(netlink_information_fetch, &zns->netlink, zns, 5, 0); +	zns->t_netlink = thread_add_read(zebrad.master, kernel_read, zns, +					 zns->netlink.sock); -  return 0; +	return 0;  }  /* Filter out messages from self that occur on listener socket,   * caused by our actions on the command socket   */ -static void netlink_install_filter (int sock, __u32 pid) +static void netlink_install_filter(int sock, __u32 pid)  { -  struct sock_filter filter[] = { -    /* 0: ldh [4]	          */ -    BPF_STMT(BPF_LD|BPF_ABS|BPF_H, offsetof(struct nlmsghdr, nlmsg_type)), -    /* 1: jeq 0x18 jt 3 jf 6  */ -    BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htons(RTM_NEWROUTE), 1, 0), -    /* 2: jeq 0x19 jt 3 jf 6  */ -    BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htons(RTM_DELROUTE), 0, 3), -    /* 3: ldw [12]		  */ -    BPF_STMT(BPF_LD|BPF_ABS|BPF_W, offsetof(struct nlmsghdr, nlmsg_pid)), -    /* 4: jeq XX  jt 5 jf 6   */ -    BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, htonl(pid), 0, 1), -    /* 5: ret 0    (skip)     */ -    BPF_STMT(BPF_RET|BPF_K, 0), -    /* 6: ret 0xffff (keep)   */ -    BPF_STMT(BPF_RET|BPF_K, 0xffff), -  }; - -  struct sock_fprog prog = { -    .len = array_size(filter), -    .filter = filter, -  }; - -  if (setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &prog, sizeof(prog)) < 0) -    zlog_warn ("Can't install socket filter: %s\n", safe_strerror(errno)); +	struct sock_filter filter[] = { +		/* 0: ldh [4]	          */ +		BPF_STMT(BPF_LD | BPF_ABS | BPF_H, +			 offsetof(struct nlmsghdr, nlmsg_type)), +		/* 1: jeq 0x18 jt 3 jf 6  */ +		BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, htons(RTM_NEWROUTE), 1, 0), +		/* 2: jeq 0x19 jt 3 jf 6  */ +		BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, htons(RTM_DELROUTE), 0, 3), +		/* 3: ldw [12]		  */ +		BPF_STMT(BPF_LD | BPF_ABS | BPF_W, +			 offsetof(struct nlmsghdr, nlmsg_pid)), +		/* 4: jeq XX  jt 5 jf 6   */ +		BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, htonl(pid), 0, 1), +		/* 5: ret 0    (skip)     */ +		BPF_STMT(BPF_RET | BPF_K, 0), +		/* 6: ret 0xffff (keep)   */ +		BPF_STMT(BPF_RET | BPF_K, 0xffff), +	}; + +	struct sock_fprog prog = { +		.len = array_size(filter), .filter = filter, +	}; + +	if (setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &prog, sizeof(prog)) +	    < 0) +		zlog_warn("Can't install socket filter: %s\n", +			  safe_strerror(errno));  } -void -netlink_parse_rtattr (struct rtattr **tb, int max, struct rtattr *rta, -                      int len) +void netlink_parse_rtattr(struct rtattr **tb, int max, struct rtattr *rta, +			  int len)  { -  while (RTA_OK (rta, len)) -    { -      if (rta->rta_type <= max) -        tb[rta->rta_type] = rta; -      rta = RTA_NEXT (rta, len); -    } +	while (RTA_OK(rta, len)) { +		if (rta->rta_type <= max) +			tb[rta->rta_type] = rta; +		rta = RTA_NEXT(rta, len); +	}  } -int -addattr_l (struct nlmsghdr *n, unsigned int maxlen, int type, -	   void *data, unsigned int alen) +int addattr_l(struct nlmsghdr *n, unsigned int maxlen, int type, void *data, +	      unsigned int alen)  { -  int len; -  struct rtattr *rta; +	int len; +	struct rtattr *rta; -  len = RTA_LENGTH (alen); +	len = RTA_LENGTH(alen); -  if (NLMSG_ALIGN (n->nlmsg_len) + RTA_ALIGN (len) > maxlen) -    return -1; +	if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) +		return -1; -  rta = (struct rtattr *) (((char *) n) + NLMSG_ALIGN (n->nlmsg_len)); -  rta->rta_type = type; -  rta->rta_len = len; +	rta = (struct rtattr *)(((char *)n) + NLMSG_ALIGN(n->nlmsg_len)); +	rta->rta_type = type; +	rta->rta_len = len; -  if (data) -    memcpy (RTA_DATA (rta), data, alen); -  else -    assert (alen == 0); +	if (data) +		memcpy(RTA_DATA(rta), data, alen); +	else +		assert(alen == 0); -  n->nlmsg_len = NLMSG_ALIGN (n->nlmsg_len) + RTA_ALIGN (len); +	n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len); -  return 0; +	return 0;  } -int -rta_addattr_l (struct rtattr *rta, unsigned int maxlen, int type, -	       void *data, unsigned int alen) +int rta_addattr_l(struct rtattr *rta, unsigned int maxlen, int type, void *data, +		  unsigned int alen)  { -  unsigned int len; -  struct rtattr *subrta; +	unsigned int len; +	struct rtattr *subrta; -  len = RTA_LENGTH (alen); +	len = RTA_LENGTH(alen); -  if (RTA_ALIGN (rta->rta_len) + RTA_ALIGN (len) > maxlen) -    return -1; +	if (RTA_ALIGN(rta->rta_len) + RTA_ALIGN(len) > maxlen) +		return -1; -  subrta = (struct rtattr *) (((char *) rta) + RTA_ALIGN (rta->rta_len)); -  subrta->rta_type = type; -  subrta->rta_len = len; +	subrta = (struct rtattr *)(((char *)rta) + RTA_ALIGN(rta->rta_len)); +	subrta->rta_type = type; +	subrta->rta_len = len; -  if (data) -    memcpy (RTA_DATA (subrta), data, alen); -  else -    assert (alen == 0); +	if (data) +		memcpy(RTA_DATA(subrta), data, alen); +	else +		assert(alen == 0); -  rta->rta_len = NLMSG_ALIGN (rta->rta_len) + RTA_ALIGN (len); +	rta->rta_len = NLMSG_ALIGN(rta->rta_len) + RTA_ALIGN(len); -  return 0; +	return 0;  } -int -addattr32 (struct nlmsghdr *n, unsigned int maxlen, int type, int data) +int addattr32(struct nlmsghdr *n, unsigned int maxlen, int type, int data)  { -  return addattr_l(n, maxlen, type, &data, sizeof(u_int32_t)); +	return addattr_l(n, maxlen, type, &data, sizeof(u_int32_t));  } -struct rtattr * -addattr_nest(struct nlmsghdr *n, int maxlen, int type) +struct rtattr *addattr_nest(struct nlmsghdr *n, int maxlen, int type)  { -  struct rtattr *nest = NLMSG_TAIL(n); +	struct rtattr *nest = NLMSG_TAIL(n); -  addattr_l(n, maxlen, type, NULL, 0); -  return nest; +	addattr_l(n, maxlen, type, NULL, 0); +	return nest;  } -int -addattr_nest_end(struct nlmsghdr *n, struct rtattr *nest) +int addattr_nest_end(struct nlmsghdr *n, struct rtattr *nest)  { -  nest->rta_len = (u_char *)NLMSG_TAIL(n) - (u_char *)nest; -  return n->nlmsg_len; +	nest->rta_len = (u_char *)NLMSG_TAIL(n) - (u_char *)nest; +	return n->nlmsg_len;  } -struct rtattr * -rta_nest(struct rtattr *rta, int maxlen, int type) +struct rtattr *rta_nest(struct rtattr *rta, int maxlen, int type)  { -  struct rtattr *nest = RTA_TAIL(rta); +	struct rtattr *nest = RTA_TAIL(rta); -  rta_addattr_l(rta, maxlen, type, NULL, 0); -  return nest; +	rta_addattr_l(rta, maxlen, type, NULL, 0); +	return nest;  } -int -rta_nest_end(struct rtattr *rta, struct rtattr *nest) +int rta_nest_end(struct rtattr *rta, struct rtattr *nest)  { -  nest->rta_len = (u_char *)RTA_TAIL(rta) - (u_char *)nest; -  return rta->rta_len; +	nest->rta_len = (u_char *)RTA_TAIL(rta) - (u_char *)nest; +	return rta->rta_len;  } -const char * -nl_msg_type_to_str (uint16_t msg_type) +const char *nl_msg_type_to_str(uint16_t msg_type)  { -  return lookup_msg (nlmsg_str, msg_type, ""); +	return lookup_msg(nlmsg_str, msg_type, "");  } -const char * -nl_rtproto_to_str (u_char rtproto) +const char *nl_rtproto_to_str(u_char rtproto)  { -  return lookup_msg (rtproto_str, rtproto, ""); +	return lookup_msg(rtproto_str, rtproto, "");  } -const char * -nl_family_to_str (u_char family) +const char *nl_family_to_str(u_char family)  { -  return lookup_msg (family_str, family, ""); +	return lookup_msg(family_str, family, "");  } -const char * -nl_rttype_to_str (u_char rttype) +const char *nl_rttype_to_str(u_char rttype)  { -  return lookup_msg (rttype_str, rttype, ""); +	return lookup_msg(rttype_str, rttype, "");  }  /* @@ -454,192 +422,210 @@ nl_rttype_to_str (u_char rttype)   * startup -> Are we reading in under startup conditions? passed to   *            the filter.   */ -int -netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *, -                                   ns_id_t, int), -                    struct nlsock *nl, struct zebra_ns *zns, int count, int startup) +int netlink_parse_info(int (*filter)(struct sockaddr_nl *, struct nlmsghdr *, +				     ns_id_t, int), +		       struct nlsock *nl, struct zebra_ns *zns, int count, +		       int startup)  { -  int status; -  int ret = 0; -  int error; -  int read_in = 0; - -  while (1) -    { -      char buf[NL_PKT_BUF_SIZE]; -      struct iovec iov = { -        .iov_base = buf, -        .iov_len = sizeof buf -      }; -      struct sockaddr_nl snl; -      struct msghdr msg = { -        .msg_name = (void *) &snl, -        .msg_namelen = sizeof snl, -        .msg_iov = &iov, -        .msg_iovlen = 1 -      }; -      struct nlmsghdr *h; - -      if (count && read_in >= count) -        return 0; - -      status = recvmsg (nl->sock, &msg, 0); -      if (status < 0) -        { -          if (errno == EINTR) -            continue; -          if (errno == EWOULDBLOCK || errno == EAGAIN) -            break; -          zlog_err("%s recvmsg overrun: %s", nl->name, safe_strerror(errno)); -          /* -           *  In this case we are screwed. -           *  There is no good way to -           *  recover zebra at this point. -           */ -          exit (-1); -          continue; -        } - -      if (status == 0) -        { -          zlog_err("%s EOF", nl->name); -          return -1; -        } - -      if (msg.msg_namelen != sizeof snl) -        { -          zlog_err("%s sender address length error: length %d", nl->name, -                   msg.msg_namelen); -          return -1; -        } - -      if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV) -        { -          zlog_debug("%s: << netlink message dump [recv]", __func__); -          zlog_hexdump(&msg, sizeof(msg)); -        } - -      read_in++; -      for (h = (struct nlmsghdr *) buf; NLMSG_OK (h, (unsigned int) status); -           h = NLMSG_NEXT (h, status)) -        { -          /* Finish of reading. */ -          if (h->nlmsg_type == NLMSG_DONE) -            return ret; - -          /* Error handling. */ -          if (h->nlmsg_type == NLMSG_ERROR) -            { -              struct nlmsgerr *err = (struct nlmsgerr *) NLMSG_DATA (h); -	      int errnum = err->error; -	      int msg_type = err->msg.nlmsg_type; - -              /* If the error field is zero, then this is an ACK */ -              if (err->error == 0) -                { -                  if (IS_ZEBRA_DEBUG_KERNEL) -                    { -                      zlog_debug ("%s: %s ACK: type=%s(%u), seq=%u, pid=%u", -                                 __FUNCTION__, nl->name, -		                 nl_msg_type_to_str (err->msg.nlmsg_type), -                                 err->msg.nlmsg_type, err->msg.nlmsg_seq, -                                 err->msg.nlmsg_pid); -                    } - -                  /* return if not a multipart message, otherwise continue */ -                  if (!(h->nlmsg_flags & NLM_F_MULTI)) -                    return 0; -                  continue; -                } - -              if (h->nlmsg_len < NLMSG_LENGTH (sizeof (struct nlmsgerr))) -                { -                  zlog_err("%s error: message truncated", nl->name); -                  return -1; -                } - -              /* Deal with errors that occur because of races in link handling */ -	      if (nl == &zns->netlink_cmd -		  && ((msg_type == RTM_DELROUTE && -		       (-errnum == ENODEV || -errnum == ESRCH)) -		      || (msg_type == RTM_NEWROUTE && -			  (-errnum == ENETDOWN || -errnum == EEXIST)))) -		{ -		  if (IS_ZEBRA_DEBUG_KERNEL) -		    zlog_debug ("%s: error: %s type=%s(%u), seq=%u, pid=%u", -				nl->name, safe_strerror (-errnum), -				nl_msg_type_to_str (msg_type), -				msg_type, err->msg.nlmsg_seq, err->msg.nlmsg_pid); -		  return 0; +	int status; +	int ret = 0; +	int error; +	int read_in = 0; + +	while (1) { +		char buf[NL_PKT_BUF_SIZE]; +		struct iovec iov = {.iov_base = buf, .iov_len = sizeof buf}; +		struct sockaddr_nl snl; +		struct msghdr msg = {.msg_name = (void *)&snl, +				     .msg_namelen = sizeof snl, +				     .msg_iov = &iov, +				     .msg_iovlen = 1}; +		struct nlmsghdr *h; + +		if (count && read_in >= count) +			return 0; + +		status = recvmsg(nl->sock, &msg, 0); +		if (status < 0) { +			if (errno == EINTR) +				continue; +			if (errno == EWOULDBLOCK || errno == EAGAIN) +				break; +			zlog_err("%s recvmsg overrun: %s", nl->name, +				 safe_strerror(errno)); +			/* +			 *  In this case we are screwed. +			 *  There is no good way to +			 *  recover zebra at this point. +			 */ +			exit(-1); +			continue; +		} + +		if (status == 0) { +			zlog_err("%s EOF", nl->name); +			return -1; +		} + +		if (msg.msg_namelen != sizeof snl) { +			zlog_err("%s sender address length error: length %d", +				 nl->name, msg.msg_namelen); +			return -1; +		} + +		if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV) { +			zlog_debug("%s: << netlink message dump [recv]", +				   __func__); +			zlog_hexdump(&msg, sizeof(msg)); +		} + +		read_in++; +		for (h = (struct nlmsghdr *)buf; +		     NLMSG_OK(h, (unsigned int)status); +		     h = NLMSG_NEXT(h, status)) { +			/* Finish of reading. */ +			if (h->nlmsg_type == NLMSG_DONE) +				return ret; + +			/* Error handling. */ +			if (h->nlmsg_type == NLMSG_ERROR) { +				struct nlmsgerr *err = +					(struct nlmsgerr *)NLMSG_DATA(h); +				int errnum = err->error; +				int msg_type = err->msg.nlmsg_type; + +				/* If the error field is zero, then this is an +				 * ACK */ +				if (err->error == 0) { +					if (IS_ZEBRA_DEBUG_KERNEL) { +						zlog_debug( +							"%s: %s ACK: type=%s(%u), seq=%u, pid=%u", +							__FUNCTION__, nl->name, +							nl_msg_type_to_str( +								err->msg.nlmsg_type), +							err->msg.nlmsg_type, +							err->msg.nlmsg_seq, +							err->msg.nlmsg_pid); +					} + +					/* return if not a multipart message, +					 * otherwise continue */ +					if (!(h->nlmsg_flags & NLM_F_MULTI)) +						return 0; +					continue; +				} + +				if (h->nlmsg_len +				    < NLMSG_LENGTH(sizeof(struct nlmsgerr))) { +					zlog_err("%s error: message truncated", +						 nl->name); +					return -1; +				} + +				/* Deal with errors that occur because of races +				 * in link handling */ +				if (nl == &zns->netlink_cmd +				    && ((msg_type == RTM_DELROUTE +					 && (-errnum == ENODEV +					     || -errnum == ESRCH)) +					|| (msg_type == RTM_NEWROUTE +					    && (-errnum == ENETDOWN +						|| -errnum == EEXIST)))) { +					if (IS_ZEBRA_DEBUG_KERNEL) +						zlog_debug( +							"%s: error: %s type=%s(%u), seq=%u, pid=%u", +							nl->name, +							safe_strerror(-errnum), +							nl_msg_type_to_str( +								msg_type), +							msg_type, +							err->msg.nlmsg_seq, +							err->msg.nlmsg_pid); +					return 0; +				} + +				/* We see RTM_DELNEIGH when shutting down an +				 * interface with an IPv4 +				 * link-local.  The kernel should have already +				 * deleted the neighbor +				 * so do not log these as an error. +				 */ +				if (msg_type == RTM_DELNEIGH +				    || (nl == &zns->netlink_cmd +					&& msg_type == RTM_NEWROUTE +					&& (-errnum == ESRCH +					    || -errnum == ENETUNREACH))) { +					/* This is known to happen in some +					 * situations, don't log +					 * as error. +					 */ +					if (IS_ZEBRA_DEBUG_KERNEL) +						zlog_debug( +							"%s error: %s, type=%s(%u), seq=%u, pid=%u", +							nl->name, +							safe_strerror(-errnum), +							nl_msg_type_to_str( +								msg_type), +							msg_type, +							err->msg.nlmsg_seq, +							err->msg.nlmsg_pid); +				} else +					zlog_err( +						"%s error: %s, type=%s(%u), seq=%u, pid=%u", +						nl->name, +						safe_strerror(-errnum), +						nl_msg_type_to_str(msg_type), +						msg_type, err->msg.nlmsg_seq, +						err->msg.nlmsg_pid); + +				return -1; +			} + +			/* OK we got netlink message. */ +			if (IS_ZEBRA_DEBUG_KERNEL) +				zlog_debug( +					"netlink_parse_info: %s type %s(%u), len=%d, seq=%u, pid=%u", +					nl->name, +					nl_msg_type_to_str(h->nlmsg_type), +					h->nlmsg_type, h->nlmsg_len, +					h->nlmsg_seq, h->nlmsg_pid); + +			/* skip unsolicited messages originating from command +			 * socket +			 * linux sets the originators port-id for {NEW|DEL}ADDR +			 * messages, +			 * so this has to be checked here. */ +			if (nl != &zns->netlink_cmd +			    && h->nlmsg_pid == zns->netlink_cmd.snl.nl_pid +			    && (h->nlmsg_type != RTM_NEWADDR +				&& h->nlmsg_type != RTM_DELADDR)) { +				if (IS_ZEBRA_DEBUG_KERNEL) +					zlog_debug( +						"netlink_parse_info: %s packet comes from %s", +						zns->netlink_cmd.name, +						nl->name); +				continue; +			} + +			error = (*filter)(&snl, h, zns->ns_id, startup); +			if (error < 0) { +				zlog_err("%s filter function error", nl->name); +				ret = error; +			}  		} -              /* We see RTM_DELNEIGH when shutting down an interface with an IPv4 -               * link-local.  The kernel should have already deleted the neighbor -               * so do not log these as an error. -               */ -              if (msg_type == RTM_DELNEIGH || -                  (nl == &zns->netlink_cmd && msg_type == RTM_NEWROUTE && -                   (-errnum == ESRCH || -errnum == ENETUNREACH))) -		{ -                  /* This is known to happen in some situations, don't log -                   * as error. -                   */ -		  if (IS_ZEBRA_DEBUG_KERNEL) -	            zlog_debug ("%s error: %s, type=%s(%u), seq=%u, pid=%u", -                                nl->name, safe_strerror (-errnum), -                                nl_msg_type_to_str (msg_type), -                                msg_type, err->msg.nlmsg_seq, err->msg.nlmsg_pid); -                } -              else -	        zlog_err ("%s error: %s, type=%s(%u), seq=%u, pid=%u", -			nl->name, safe_strerror (-errnum), -                        nl_msg_type_to_str (msg_type), -			msg_type, err->msg.nlmsg_seq, err->msg.nlmsg_pid); - -              return -1; -            } - -          /* OK we got netlink message. */ -          if (IS_ZEBRA_DEBUG_KERNEL) -            zlog_debug ("netlink_parse_info: %s type %s(%u), len=%d, seq=%u, pid=%u", -                       nl->name, -                       nl_msg_type_to_str (h->nlmsg_type), h->nlmsg_type, -                       h->nlmsg_len, h->nlmsg_seq, h->nlmsg_pid); - -          /* skip unsolicited messages originating from command socket -           * linux sets the originators port-id for {NEW|DEL}ADDR messages, -           * so this has to be checked here. */ -          if (nl != &zns->netlink_cmd -              && h->nlmsg_pid == zns->netlink_cmd.snl.nl_pid -              && (h->nlmsg_type != RTM_NEWADDR && h->nlmsg_type != RTM_DELADDR)) -            { -              if (IS_ZEBRA_DEBUG_KERNEL) -                zlog_debug ("netlink_parse_info: %s packet comes from %s", -                            zns->netlink_cmd.name, nl->name); -              continue; -            } - -          error = (*filter) (&snl, h, zns->ns_id, startup); -          if (error < 0) -            { -              zlog_err("%s filter function error", nl->name); -              ret = error; -            } -        } - -      /* After error care. */ -      if (msg.msg_flags & MSG_TRUNC) -        { -          zlog_err("%s error: message truncated", nl->name); -          continue; -        } -      if (status) -        { -          zlog_err("%s error: data remnant size %d", nl->name, status); -          return -1; -        } -    } -  return ret; +		/* After error care. */ +		if (msg.msg_flags & MSG_TRUNC) { +			zlog_err("%s error: message truncated", nl->name); +			continue; +		} +		if (status) { +			zlog_err("%s error: data remnant size %d", nl->name, +				 status); +			return -1; +		} +	} +	return ret;  }  /* @@ -655,178 +641,166 @@ netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *,   * startup  -> Are we reading in under startup conditions   *             This is passed through eventually to filter.   */ -int -netlink_talk (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *, -                             ns_id_t, int startup), -              struct nlmsghdr *n, struct nlsock *nl, struct zebra_ns *zns, int startup) +int netlink_talk(int (*filter)(struct sockaddr_nl *, struct nlmsghdr *, ns_id_t, +			       int startup), +		 struct nlmsghdr *n, struct nlsock *nl, struct zebra_ns *zns, +		 int startup)  { -  int status; -  struct sockaddr_nl snl; -  struct iovec iov = { -    .iov_base = (void *) n, -    .iov_len = n->nlmsg_len -  }; -  struct msghdr msg = { -    .msg_name = (void *) &snl, -    .msg_namelen = sizeof snl, -    .msg_iov = &iov, -    .msg_iovlen = 1, -  }; -  int save_errno; - -  memset (&snl, 0, sizeof snl); -  snl.nl_family = AF_NETLINK; - -  n->nlmsg_seq = ++nl->seq; - -  /* Request an acknowledgement by setting NLM_F_ACK */ -  n->nlmsg_flags |= NLM_F_ACK; - -  if (IS_ZEBRA_DEBUG_KERNEL) -    zlog_debug ("netlink_talk: %s type %s(%u), len=%d seq=%u flags 0x%x", -               nl->name, -               nl_msg_type_to_str (n->nlmsg_type), n->nlmsg_type, -               n->nlmsg_len, n->nlmsg_seq, n->nlmsg_flags); - -  /* Send message to netlink interface. */ -  if (zserv_privs.change (ZPRIVS_RAISE)) -    zlog_err("Can't raise privileges"); -  status = sendmsg (nl->sock, &msg, 0); -  save_errno = errno; -  if (zserv_privs.change (ZPRIVS_LOWER)) -    zlog_err("Can't lower privileges"); - -  if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND) -    { -      zlog_debug("%s: >> netlink message dump [sent]", __func__); -      zlog_hexdump(&msg, sizeof(msg)); -    } - -  if (status < 0) -    { -      zlog_err("netlink_talk sendmsg() error: %s", safe_strerror(save_errno)); -      return -1; -    } - - -  /* -   * Get reply from netlink socket. -   * The reply should either be an acknowlegement or an error. -   */ -  return netlink_parse_info (filter, nl, zns, 0, startup); +	int status; +	struct sockaddr_nl snl; +	struct iovec iov = {.iov_base = (void *)n, .iov_len = n->nlmsg_len}; +	struct msghdr msg = { +		.msg_name = (void *)&snl, +		.msg_namelen = sizeof snl, +		.msg_iov = &iov, +		.msg_iovlen = 1, +	}; +	int save_errno; + +	memset(&snl, 0, sizeof snl); +	snl.nl_family = AF_NETLINK; + +	n->nlmsg_seq = ++nl->seq; + +	/* Request an acknowledgement by setting NLM_F_ACK */ +	n->nlmsg_flags |= NLM_F_ACK; + +	if (IS_ZEBRA_DEBUG_KERNEL) +		zlog_debug( +			"netlink_talk: %s type %s(%u), len=%d seq=%u flags 0x%x", +			nl->name, nl_msg_type_to_str(n->nlmsg_type), +			n->nlmsg_type, n->nlmsg_len, n->nlmsg_seq, +			n->nlmsg_flags); + +	/* Send message to netlink interface. */ +	if (zserv_privs.change(ZPRIVS_RAISE)) +		zlog_err("Can't raise privileges"); +	status = sendmsg(nl->sock, &msg, 0); +	save_errno = errno; +	if (zserv_privs.change(ZPRIVS_LOWER)) +		zlog_err("Can't lower privileges"); + +	if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_SEND) { +		zlog_debug("%s: >> netlink message dump [sent]", __func__); +		zlog_hexdump(&msg, sizeof(msg)); +	} + +	if (status < 0) { +		zlog_err("netlink_talk sendmsg() error: %s", +			 safe_strerror(save_errno)); +		return -1; +	} + + +	/* +	 * Get reply from netlink socket. +	 * The reply should either be an acknowlegement or an error. +	 */ +	return netlink_parse_info(filter, nl, zns, 0, startup);  }  /* Get type specified information from netlink. */ -int -netlink_request (int family, int type, struct nlsock *nl) +int netlink_request(int family, int type, struct nlsock *nl)  { -  int ret; -  struct sockaddr_nl snl; -  int save_errno; - -  struct -  { -    struct nlmsghdr nlh; -    struct rtgenmsg g; -  } req; - -  /* Check netlink socket. */ -  if (nl->sock < 0) -    { -      zlog_err("%s socket isn't active.", nl->name); -      return -1; -    } - -  memset (&snl, 0, sizeof snl); -  snl.nl_family = AF_NETLINK; - -  memset (&req, 0, sizeof req); -  req.nlh.nlmsg_len = sizeof req; -  req.nlh.nlmsg_type = type; -  req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST; -  req.nlh.nlmsg_pid = nl->snl.nl_pid; -  req.nlh.nlmsg_seq = ++nl->seq; -  req.g.rtgen_family = family; - -  /* linux appears to check capabilities on every message -   * have to raise caps for every message sent -   */ -  if (zserv_privs.change (ZPRIVS_RAISE)) -    { -      zlog_err("Can't raise privileges"); -      return -1; -    } - -  ret = sendto (nl->sock, (void *) &req, sizeof req, 0, -		(struct sockaddr *) &snl, sizeof snl); -  save_errno = errno; - -  if (zserv_privs.change (ZPRIVS_LOWER)) -    zlog_err("Can't lower privileges"); - -  if (ret < 0) -    { -      zlog_err("%s sendto failed: %s", nl->name, safe_strerror(save_errno)); -      return -1; -    } - -  return 0; +	int ret; +	struct sockaddr_nl snl; +	int save_errno; + +	struct { +		struct nlmsghdr nlh; +		struct rtgenmsg g; +	} req; + +	/* Check netlink socket. */ +	if (nl->sock < 0) { +		zlog_err("%s socket isn't active.", nl->name); +		return -1; +	} + +	memset(&snl, 0, sizeof snl); +	snl.nl_family = AF_NETLINK; + +	memset(&req, 0, sizeof req); +	req.nlh.nlmsg_len = sizeof req; +	req.nlh.nlmsg_type = type; +	req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST; +	req.nlh.nlmsg_pid = nl->snl.nl_pid; +	req.nlh.nlmsg_seq = ++nl->seq; +	req.g.rtgen_family = family; + +	/* linux appears to check capabilities on every message +	 * have to raise caps for every message sent +	 */ +	if (zserv_privs.change(ZPRIVS_RAISE)) { +		zlog_err("Can't raise privileges"); +		return -1; +	} + +	ret = sendto(nl->sock, (void *)&req, sizeof req, 0, +		     (struct sockaddr *)&snl, sizeof snl); +	save_errno = errno; + +	if (zserv_privs.change(ZPRIVS_LOWER)) +		zlog_err("Can't lower privileges"); + +	if (ret < 0) { +		zlog_err("%s sendto failed: %s", nl->name, +			 safe_strerror(save_errno)); +		return -1; +	} + +	return 0;  }  /* Exported interface function.  This function simply calls     netlink_socket (). */ -void -kernel_init (struct zebra_ns *zns) +void kernel_init(struct zebra_ns *zns)  { -  unsigned long groups; - -  /* Initialize netlink sockets */ -  groups = RTMGRP_LINK | RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_IFADDR | -    RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFADDR | -    RTMGRP_IPV4_MROUTE; - -  snprintf (zns->netlink.name, sizeof (zns->netlink.name), -	    "netlink-listen (NS %u)", zns->ns_id); -  zns->netlink.sock = -1; -  netlink_socket (&zns->netlink, groups, zns->ns_id); - -  snprintf (zns->netlink_cmd.name, sizeof (zns->netlink_cmd.name), -	    "netlink-cmd (NS %u)", zns->ns_id); -  zns->netlink_cmd.sock = -1; -  netlink_socket (&zns->netlink_cmd, 0, zns->ns_id); - -  /* Register kernel socket. */ -  if (zns->netlink.sock > 0) -    { -      /* Only want non-blocking on the netlink event socket */ -      if (fcntl (zns->netlink.sock, F_SETFL, O_NONBLOCK) < 0) -        zlog_err ("Can't set %s socket flags: %s", zns->netlink.name, -                  safe_strerror (errno)); - -      /* Set receive buffer size if it's set from command line */ -      if (nl_rcvbufsize) -        netlink_recvbuf (&zns->netlink, nl_rcvbufsize); - -      netlink_install_filter (zns->netlink.sock, zns->netlink_cmd.snl.nl_pid); -      zns->t_netlink = thread_add_read (zebrad.master, kernel_read, zns, -                                         zns->netlink.sock); -    } +	unsigned long groups; + +	/* Initialize netlink sockets */ +	groups = RTMGRP_LINK | RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_IFADDR +		 | RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFADDR | RTMGRP_IPV4_MROUTE; + +	snprintf(zns->netlink.name, sizeof(zns->netlink.name), +		 "netlink-listen (NS %u)", zns->ns_id); +	zns->netlink.sock = -1; +	netlink_socket(&zns->netlink, groups, zns->ns_id); + +	snprintf(zns->netlink_cmd.name, sizeof(zns->netlink_cmd.name), +		 "netlink-cmd (NS %u)", zns->ns_id); +	zns->netlink_cmd.sock = -1; +	netlink_socket(&zns->netlink_cmd, 0, zns->ns_id); + +	/* Register kernel socket. */ +	if (zns->netlink.sock > 0) { +		/* Only want non-blocking on the netlink event socket */ +		if (fcntl(zns->netlink.sock, F_SETFL, O_NONBLOCK) < 0) +			zlog_err("Can't set %s socket flags: %s", +				 zns->netlink.name, safe_strerror(errno)); + +		/* Set receive buffer size if it's set from command line */ +		if (nl_rcvbufsize) +			netlink_recvbuf(&zns->netlink, nl_rcvbufsize); + +		netlink_install_filter(zns->netlink.sock, +				       zns->netlink_cmd.snl.nl_pid); +		zns->t_netlink = thread_add_read(zebrad.master, kernel_read, +						 zns, zns->netlink.sock); +	}  } -void -kernel_terminate (struct zebra_ns *zns) +void kernel_terminate(struct zebra_ns *zns)  { -  THREAD_READ_OFF (zns->t_netlink); - -  if (zns->netlink.sock >= 0) -    { -      close (zns->netlink.sock); -      zns->netlink.sock = -1; -    } - -  if (zns->netlink_cmd.sock >= 0) -    { -      close (zns->netlink_cmd.sock); -      zns->netlink_cmd.sock = -1; -    } +	THREAD_READ_OFF(zns->t_netlink); + +	if (zns->netlink.sock >= 0) { +		close(zns->netlink.sock); +		zns->netlink.sock = -1; +	} + +	if (zns->netlink_cmd.sock >= 0) { +		close(zns->netlink_cmd.sock); +		zns->netlink_cmd.sock = -1; +	}  } diff --git a/zebra/kernel_netlink.h b/zebra/kernel_netlink.h index adbcf71f63..7f8816fb37 100644 --- a/zebra/kernel_netlink.h +++ b/zebra/kernel_netlink.h @@ -16,7 +16,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #ifndef _ZEBRA_KERNEL_NETLINK_H @@ -26,34 +26,34 @@  #define NL_PKT_BUF_SIZE         8192 -extern void netlink_parse_rtattr (struct rtattr **tb, int max, -                                  struct rtattr *rta, int len); -extern int addattr_l (struct nlmsghdr *n, unsigned int maxlen, -                      int type, void *data, unsigned int alen); -extern int rta_addattr_l (struct rtattr *rta, unsigned int maxlen, -                          int type, void *data, unsigned int alen); -extern int addattr32 (struct nlmsghdr *n, unsigned int maxlen, -                      int type, int data); +extern void netlink_parse_rtattr(struct rtattr **tb, int max, +				 struct rtattr *rta, int len); +extern int addattr_l(struct nlmsghdr *n, unsigned int maxlen, int type, +		     void *data, unsigned int alen); +extern int rta_addattr_l(struct rtattr *rta, unsigned int maxlen, int type, +			 void *data, unsigned int alen); +extern int addattr32(struct nlmsghdr *n, unsigned int maxlen, int type, +		     int data);  extern struct rtattr *addattr_nest(struct nlmsghdr *n, int maxlen, int type);  extern int addattr_nest_end(struct nlmsghdr *n, struct rtattr *nest); -extern struct rtattr * rta_nest(struct rtattr *rta, int maxlen, int type); +extern struct rtattr *rta_nest(struct rtattr *rta, int maxlen, int type);  extern int rta_nest_end(struct rtattr *rta, struct rtattr *nest); -extern const char * nl_msg_type_to_str (uint16_t msg_type); -extern const char * nl_rtproto_to_str (u_char rtproto); -extern const char * nl_family_to_str (u_char family); -extern const char * nl_rttype_to_str (u_char rttype); +extern const char *nl_msg_type_to_str(uint16_t msg_type); +extern const char *nl_rtproto_to_str(u_char rtproto); +extern const char *nl_family_to_str(u_char family); +extern const char *nl_rttype_to_str(u_char rttype); -extern int netlink_parse_info (int (*filter) (struct sockaddr_nl *, -                                              struct nlmsghdr *, ns_id_t, int), -                               struct nlsock *nl, struct zebra_ns *zns, -                               int count, int startup); -extern int netlink_talk_filter (struct sockaddr_nl *, struct nlmsghdr *, -				ns_id_t, int startup); -extern int netlink_talk (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *, -					ns_id_t, int startup), -			 struct nlmsghdr *n, struct nlsock *nl, -                         struct zebra_ns *zns, int startup); -extern int netlink_request (int family, int type, struct nlsock *nl); +extern int netlink_parse_info(int (*filter)(struct sockaddr_nl *, +					    struct nlmsghdr *, ns_id_t, int), +			      struct nlsock *nl, struct zebra_ns *zns, +			      int count, int startup); +extern int netlink_talk_filter(struct sockaddr_nl *, struct nlmsghdr *, ns_id_t, +			       int startup); +extern int netlink_talk(int (*filter)(struct sockaddr_nl *, struct nlmsghdr *, +				      ns_id_t, int startup), +			struct nlmsghdr *n, struct nlsock *nl, +			struct zebra_ns *zns, int startup); +extern int netlink_request(int family, int type, struct nlsock *nl);  #endif /* HAVE_NETLINK */ diff --git a/zebra/kernel_null.c b/zebra/kernel_null.c index fea79ffe8c..43a014f271 100644 --- a/zebra/kernel_null.c +++ b/zebra/kernel_null.c @@ -1,6 +1,6 @@  /* NULL kernel methods for testing. */ -/*  +/*   * Copyright (C) 2006 Sun Microsystems, Inc.   *   * This file is part of Quagga. @@ -18,7 +18,7 @@   * You should have received a copy of the GNU General Public License   * along with Quagga; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #include <zebra.h> @@ -32,34 +32,50 @@  #include "zebra/rt_netlink.h"  #include "zebra/rib.h" -int kernel_route_rib (struct prefix *a, struct prefix *b, -                      struct rib *old, struct rib *new) { return 0; } +int kernel_route_rib(struct prefix *a, struct prefix *b, struct rib *old, +		     struct rib *new) +{ +	return 0; +} -int kernel_address_add_ipv4 (struct interface *a, struct connected *b) +int kernel_address_add_ipv4(struct interface *a, struct connected *b)  { -  zlog_debug ("%s", __func__); -  SET_FLAG (b->conf, ZEBRA_IFC_REAL); -  connected_add_ipv4 (a, 0, &b->address->u.prefix4, b->address->prefixlen,  -                      (b->destination ? &b->destination->u.prefix4 : NULL),  -                      NULL); -  return 0; +	zlog_debug("%s", __func__); +	SET_FLAG(b->conf, ZEBRA_IFC_REAL); +	connected_add_ipv4(a, 0, &b->address->u.prefix4, b->address->prefixlen, +			   (b->destination ? &b->destination->u.prefix4 : NULL), +			   NULL); +	return 0;  } -int kernel_address_delete_ipv4 (struct interface *a, struct connected *b) +int kernel_address_delete_ipv4(struct interface *a, struct connected *b)  { -  zlog_debug ("%s", __func__); -  connected_delete_ipv4 (a, 0, &b->address->u.prefix4, b->address->prefixlen,  -                         (b->destination ? &b->destination->u.prefix4 : NULL)); -  return 0; +	zlog_debug("%s", __func__); +	connected_delete_ipv4( +		a, 0, &b->address->u.prefix4, b->address->prefixlen, +		(b->destination ? &b->destination->u.prefix4 : NULL)); +	return 0;  } -int kernel_neigh_update (int a, int b, uint32_t c, char *d, int e) +int kernel_neigh_update(int a, int b, uint32_t c, char *d, int e)  { -  return 0; +	return 0;  } -void kernel_init (struct zebra_ns *zns) { return; } -void kernel_terminate (struct zebra_ns *zns) { return; } -void route_read (struct zebra_ns *zns) { return; } +void kernel_init(struct zebra_ns *zns) +{ +	return; +} +void kernel_terminate(struct zebra_ns *zns) +{ +	return; +} +void route_read(struct zebra_ns *zns) +{ +	return; +} -int kernel_get_ipmr_sg_stats (void *m) { return 0; } +int kernel_get_ipmr_sg_stats(void *m) +{ +	return 0; +} diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index 70effade27..efe33c8389 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -16,7 +16,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #include <zebra.h> @@ -91,7 +91,8 @@ extern struct zebra_privs_t zserv_privs;   * intentional, to provoke filing bug reports with operating systems   * that don't define RT_ROUNDUP or equivalent.   */ -#warning "net/route.h does not define RT_ROUNDUP; making unwarranted assumptions!" +#warning                                                                       \ +	"net/route.h does not define RT_ROUNDUP; making unwarranted assumptions!"  /* OS X (Xcode as of 2014-12) is known not to define RT_ROUNDUP */  #ifdef __APPLE__ @@ -100,8 +101,9 @@ extern struct zebra_privs_t zserv_privs;  #define ROUNDUP_TYPE	long  #endif -#define ROUNDUP(a) \ -  ((a) > 0 ? (1 + (((a) - 1) | (sizeof(ROUNDUP_TYPE) - 1))) : sizeof(ROUNDUP_TYPE)) +#define ROUNDUP(a)                                                             \ +	((a) > 0 ? (1 + (((a)-1) | (sizeof(ROUNDUP_TYPE) - 1)))                \ +		 : sizeof(ROUNDUP_TYPE))  #endif /* defined(ROUNDUP) */ @@ -116,13 +118,14 @@ extern struct zebra_privs_t zserv_privs;   * One would hope all fixed-size structure definitions are aligned,   * but round them up nonetheless.   */ -#define SAROUNDUP(X) \ -    (((struct sockaddr *)(X))->sa_family == AF_INET ?   \ -      ROUNDUP(sizeof(struct sockaddr_in)):\ -      (((struct sockaddr *)(X))->sa_family == AF_INET6 ? \ -       ROUNDUP(sizeof(struct sockaddr_in6)) :  \ -       (((struct sockaddr *)(X))->sa_family == AF_LINK ? \ -         ROUNDUP(sizeof(struct sockaddr_dl)) : sizeof(struct sockaddr)))) +#define SAROUNDUP(X)                                                           \ +	(((struct sockaddr *)(X))->sa_family == AF_INET                        \ +		 ? ROUNDUP(sizeof(struct sockaddr_in))                         \ +		 : (((struct sockaddr *)(X))->sa_family == AF_INET6            \ +			    ? ROUNDUP(sizeof(struct sockaddr_in6))             \ +			    : (((struct sockaddr *)(X))->sa_family == AF_LINK  \ +				       ? ROUNDUP(sizeof(struct sockaddr_dl))   \ +				       : sizeof(struct sockaddr))))  #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */  #endif /* !SA_SIZE */ @@ -134,152 +137,140 @@ extern struct zebra_privs_t zserv_privs;   * 2. So the compiler doesn't complain when DEST is NULL, which is only true   *    when we are skipping the copy and incrementing to the next SA   */ -static inline void -rta_copy (union sockunion *dest, caddr_t src) { -  int len; -  if (!dest) -    return; +static inline void rta_copy(union sockunion *dest, caddr_t src) +{ +	int len; +	if (!dest) +		return;  #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN -  len = (((struct sockaddr *)src)->sa_len > sizeof (*dest)) ? -            sizeof (*dest) : ((struct sockaddr *)src)->sa_len ; +	len = (((struct sockaddr *)src)->sa_len > sizeof(*dest)) +		      ? sizeof(*dest) +		      : ((struct sockaddr *)src)->sa_len;  #else -  len = (SAROUNDUP (src) > sizeof (*dest)) ? -            sizeof (*dest) : SAROUNDUP (src) ; +	len = (SAROUNDUP(src) > sizeof(*dest)) ? sizeof(*dest) : SAROUNDUP(src);  #endif -  memcpy (dest, src, len); +	memcpy(dest, src, len);  } -#define RTA_ADDR_GET(DEST, RTA, RTMADDRS, PNT) \ -  if ((RTMADDRS) & (RTA)) \ -    { \ -      int len = SAROUNDUP ((PNT)); \ -      if (af_check (((struct sockaddr *)(PNT))->sa_family)) \ -        rta_copy((DEST), (PNT)); \ -      (PNT) += len; \ -    } -#define RTA_ATTR_GET(DEST, RTA, RTMADDRS, PNT) \ -  if ((RTMADDRS) & (RTA)) \ -    { \ -      int len = SAROUNDUP ((PNT)); \ -      rta_copy((DEST), (PNT)); \ -      (PNT) += len; \ -    } - -#define RTA_NAME_GET(DEST, RTA, RTMADDRS, PNT, LEN) \ -  if ((RTMADDRS) & (RTA)) \ -    { \ -      u_char *pdest = (u_char *) (DEST); \ -      int len = SAROUNDUP ((PNT)); \ -      struct sockaddr_dl *sdl = (struct sockaddr_dl *)(PNT); \ -      if (IS_ZEBRA_DEBUG_KERNEL) \ -        zlog_debug ("%s: RTA_SDL_GET nlen %d, alen %d", \ -                    __func__, sdl->sdl_nlen, sdl->sdl_alen); \ -      if ( ((DEST) != NULL) && (sdl->sdl_family == AF_LINK) \ -           && (sdl->sdl_nlen < IFNAMSIZ) && (sdl->sdl_nlen <= len) ) \ -        { \ -          memcpy (pdest, sdl->sdl_data, sdl->sdl_nlen); \ -          pdest[sdl->sdl_nlen] = '\0'; \ -          (LEN) = sdl->sdl_nlen; \ -        } \ -      (PNT) += len; \ -    } \ -  else \ -    { \ -      (LEN) = 0; \ -    } +#define RTA_ADDR_GET(DEST, RTA, RTMADDRS, PNT)                                 \ +	if ((RTMADDRS) & (RTA)) {                                              \ +		int len = SAROUNDUP((PNT));                                    \ +		if (af_check(((struct sockaddr *)(PNT))->sa_family))           \ +			rta_copy((DEST), (PNT));                               \ +		(PNT) += len;                                                  \ +	} +#define RTA_ATTR_GET(DEST, RTA, RTMADDRS, PNT)                                 \ +	if ((RTMADDRS) & (RTA)) {                                              \ +		int len = SAROUNDUP((PNT));                                    \ +		rta_copy((DEST), (PNT));                                       \ +		(PNT) += len;                                                  \ +	} + +#define RTA_NAME_GET(DEST, RTA, RTMADDRS, PNT, LEN)                            \ +	if ((RTMADDRS) & (RTA)) {                                              \ +		u_char *pdest = (u_char *)(DEST);                              \ +		int len = SAROUNDUP((PNT));                                    \ +		struct sockaddr_dl *sdl = (struct sockaddr_dl *)(PNT);         \ +		if (IS_ZEBRA_DEBUG_KERNEL)                                     \ +			zlog_debug("%s: RTA_SDL_GET nlen %d, alen %d",         \ +				   __func__, sdl->sdl_nlen, sdl->sdl_alen);    \ +		if (((DEST) != NULL) && (sdl->sdl_family == AF_LINK)           \ +		    && (sdl->sdl_nlen < IFNAMSIZ) && (sdl->sdl_nlen <= len)) { \ +			memcpy(pdest, sdl->sdl_data, sdl->sdl_nlen);           \ +			pdest[sdl->sdl_nlen] = '\0';                           \ +			(LEN) = sdl->sdl_nlen;                                 \ +		}                                                              \ +		(PNT) += len;                                                  \ +	} else {                                                               \ +		(LEN) = 0;                                                     \ +	}  /* Routing socket message types. */ -const struct message rtm_type_str[] = -{ -  {RTM_ADD,      "RTM_ADD"}, -  {RTM_DELETE,   "RTM_DELETE"}, -  {RTM_CHANGE,   "RTM_CHANGE"}, -  {RTM_GET,      "RTM_GET"}, -  {RTM_LOSING,   "RTM_LOSING"}, -  {RTM_REDIRECT, "RTM_REDIRECT"}, -  {RTM_MISS,     "RTM_MISS"}, -  {RTM_LOCK,     "RTM_LOCK"}, +const struct message rtm_type_str[] = {{RTM_ADD, "RTM_ADD"}, +				       {RTM_DELETE, "RTM_DELETE"}, +				       {RTM_CHANGE, "RTM_CHANGE"}, +				       {RTM_GET, "RTM_GET"}, +				       {RTM_LOSING, "RTM_LOSING"}, +				       {RTM_REDIRECT, "RTM_REDIRECT"}, +				       {RTM_MISS, "RTM_MISS"}, +				       {RTM_LOCK, "RTM_LOCK"},  #ifdef OLDADD -  {RTM_OLDADD,   "RTM_OLDADD"}, +				       {RTM_OLDADD, "RTM_OLDADD"},  #endif /* RTM_OLDADD */  #ifdef RTM_OLDDEL -  {RTM_OLDDEL,   "RTM_OLDDEL"}, +				       {RTM_OLDDEL, "RTM_OLDDEL"},  #endif /* RTM_OLDDEL */ -  {RTM_RESOLVE,  "RTM_RESOLVE"}, -  {RTM_NEWADDR,  "RTM_NEWADDR"}, -  {RTM_DELADDR,  "RTM_DELADDR"}, -  {RTM_IFINFO,   "RTM_IFINFO"}, +				       {RTM_RESOLVE, "RTM_RESOLVE"}, +				       {RTM_NEWADDR, "RTM_NEWADDR"}, +				       {RTM_DELADDR, "RTM_DELADDR"}, +				       {RTM_IFINFO, "RTM_IFINFO"},  #ifdef RTM_OIFINFO -  {RTM_OIFINFO,   "RTM_OIFINFO"}, +				       {RTM_OIFINFO, "RTM_OIFINFO"},  #endif /* RTM_OIFINFO */  #ifdef RTM_NEWMADDR -  {RTM_NEWMADDR, "RTM_NEWMADDR"}, +				       {RTM_NEWMADDR, "RTM_NEWMADDR"},  #endif /* RTM_NEWMADDR */  #ifdef RTM_DELMADDR -  {RTM_DELMADDR, "RTM_DELMADDR"}, +				       {RTM_DELMADDR, "RTM_DELMADDR"},  #endif /* RTM_DELMADDR */  #ifdef RTM_IFANNOUNCE -  {RTM_IFANNOUNCE, "RTM_IFANNOUNCE"}, +				       {RTM_IFANNOUNCE, "RTM_IFANNOUNCE"},  #endif /* RTM_IFANNOUNCE */ -  { 0 } -}; - -static const struct message rtm_flag_str[] = -{ -  {RTF_UP,        "UP"}, -  {RTF_GATEWAY,   "GATEWAY"}, -  {RTF_HOST,      "HOST"}, -  {RTF_REJECT,    "REJECT"}, -  {RTF_DYNAMIC,   "DYNAMIC"}, -  {RTF_MODIFIED,  "MODIFIED"}, -  {RTF_DONE,      "DONE"}, +				       {0}}; + +static const struct message rtm_flag_str[] = {{RTF_UP, "UP"}, +					      {RTF_GATEWAY, "GATEWAY"}, +					      {RTF_HOST, "HOST"}, +					      {RTF_REJECT, "REJECT"}, +					      {RTF_DYNAMIC, "DYNAMIC"}, +					      {RTF_MODIFIED, "MODIFIED"}, +					      {RTF_DONE, "DONE"},  #ifdef RTF_MASK -  {RTF_MASK,      "MASK"}, +					      {RTF_MASK, "MASK"},  #endif /* RTF_MASK */  #ifdef RTF_CLONING -  {RTF_CLONING,   "CLONING"}, +					      {RTF_CLONING, "CLONING"},  #endif /* RTF_CLONING */  #ifdef RTF_XRESOLVE -  {RTF_XRESOLVE,  "XRESOLVE"}, +					      {RTF_XRESOLVE, "XRESOLVE"},  #endif /* RTF_XRESOLVE */  #ifdef RTF_LLINFO -  {RTF_LLINFO,    "LLINFO"}, +					      {RTF_LLINFO, "LLINFO"},  #endif /* RTF_LLINFO */ -  {RTF_STATIC,    "STATIC"}, -  {RTF_BLACKHOLE, "BLACKHOLE"}, +					      {RTF_STATIC, "STATIC"}, +					      {RTF_BLACKHOLE, "BLACKHOLE"},  #ifdef RTF_PRIVATE -  {RTF_PRIVATE,	  "PRIVATE"}, +					      {RTF_PRIVATE, "PRIVATE"},  #endif /* RTF_PRIVATE */ -  {RTF_PROTO1,    "PROTO1"}, -  {RTF_PROTO2,    "PROTO2"}, +					      {RTF_PROTO1, "PROTO1"}, +					      {RTF_PROTO2, "PROTO2"},  #ifdef RTF_PRCLONING -  {RTF_PRCLONING, "PRCLONING"}, +					      {RTF_PRCLONING, "PRCLONING"},  #endif /* RTF_PRCLONING */  #ifdef RTF_WASCLONED -  {RTF_WASCLONED, "WASCLONED"}, +					      {RTF_WASCLONED, "WASCLONED"},  #endif /* RTF_WASCLONED */  #ifdef RTF_PROTO3 -  {RTF_PROTO3,    "PROTO3"}, +					      {RTF_PROTO3, "PROTO3"},  #endif /* RTF_PROTO3 */  #ifdef RTF_PINNED -  {RTF_PINNED,    "PINNED"}, +					      {RTF_PINNED, "PINNED"},  #endif /* RTF_PINNED */  #ifdef RTF_LOCAL -  {RTF_LOCAL,    "LOCAL"}, +					      {RTF_LOCAL, "LOCAL"},  #endif /* RTF_LOCAL */  #ifdef RTF_BROADCAST -  {RTF_BROADCAST, "BROADCAST"}, +					      {RTF_BROADCAST, "BROADCAST"},  #endif /* RTF_BROADCAST */  #ifdef RTF_MULTICAST -  {RTF_MULTICAST, "MULTICAST"}, +					      {RTF_MULTICAST, "MULTICAST"},  #endif /* RTF_MULTICAST */  #ifdef RTF_MULTIRT -  {RTF_MULTIRT,   "MULTIRT"}, +					      {RTF_MULTIRT, "MULTIRT"},  #endif /* RTF_MULTIRT */  #ifdef RTF_SETSRC -  {RTF_SETSRC,    "SETSRC"}, +					      {RTF_SETSRC, "SETSRC"},  #endif /* RTF_SETSRC */ -  { 0 } -}; +					      {0}};  /* Kernel routing update socket. */  int routing_sock = -1; @@ -288,115 +279,117 @@ int routing_sock = -1;  /* #define DEBUG */  /* Supported address family check. */ -static inline int -af_check (int family) +static inline int af_check(int family)  { -  if (family == AF_INET) -    return 1; -  if (family == AF_INET6) -    return 1; -  return 0; +	if (family == AF_INET) +		return 1; +	if (family == AF_INET6) +		return 1; +	return 0;  }  /* Dump routing table flag for debug purpose. */ -static void -rtm_flag_dump (int flag) +static void rtm_flag_dump(int flag)  { -  const struct message *mes; -  static char buf[BUFSIZ]; - -  buf[0] = '\0'; -  for (mes = rtm_flag_str; mes->key != 0; mes++) -    { -      if (mes->key & flag) -	{ -	  strlcat (buf, mes->str, BUFSIZ); -	  strlcat (buf, " ", BUFSIZ); +	const struct message *mes; +	static char buf[BUFSIZ]; + +	buf[0] = '\0'; +	for (mes = rtm_flag_str; mes->key != 0; mes++) { +		if (mes->key & flag) { +			strlcat(buf, mes->str, BUFSIZ); +			strlcat(buf, " ", BUFSIZ); +		}  	} -    } -  zlog_debug ("Kernel: %s", buf); +	zlog_debug("Kernel: %s", buf);  }  #ifdef RTM_IFANNOUNCE  /* Interface adding function */ -static int -ifan_read (struct if_announcemsghdr *ifan) +static int ifan_read(struct if_announcemsghdr *ifan)  { -  struct interface *ifp; -   -  ifp = if_lookup_by_index (ifan->ifan_index, VRF_DEFAULT); -   -  if (ifp) -    assert ( (ifp->ifindex == ifan->ifan_index)  -             || (ifp->ifindex == IFINDEX_INTERNAL) ); - -  if ( (ifp == NULL)  -      || ((ifp->ifindex == IFINDEX_INTERNAL) -          && (ifan->ifan_what == IFAN_ARRIVAL)) ) -    { -      if (IS_ZEBRA_DEBUG_KERNEL) -        zlog_debug ("%s: creating interface for ifindex %d, name %s", -                    __func__, ifan->ifan_index, ifan->ifan_name); -       -      /* Create Interface */ -      ifp = if_get_by_name_len(ifan->ifan_name, -			       strnlen(ifan->ifan_name, -				       sizeof(ifan->ifan_name)), -                               VRF_DEFAULT, 0); -      ifp->ifindex = ifan->ifan_index; - -      if_get_metric (ifp); -      if_add_update (ifp); -    } -  else if (ifp != NULL && ifan->ifan_what == IFAN_DEPARTURE) -    if_delete_update (ifp); - -  if_get_flags (ifp); -  if_get_mtu (ifp); -  if_get_metric (ifp); - -  if (IS_ZEBRA_DEBUG_KERNEL) -    zlog_debug ("%s: interface %s index %d",  -                __func__, ifan->ifan_name, ifan->ifan_index); - -  return 0; +	struct interface *ifp; + +	ifp = if_lookup_by_index(ifan->ifan_index, VRF_DEFAULT); + +	if (ifp) +		assert((ifp->ifindex == ifan->ifan_index) +		       || (ifp->ifindex == IFINDEX_INTERNAL)); + +	if ((ifp == NULL) || ((ifp->ifindex == IFINDEX_INTERNAL) +			      && (ifan->ifan_what == IFAN_ARRIVAL))) { +		if (IS_ZEBRA_DEBUG_KERNEL) +			zlog_debug( +				"%s: creating interface for ifindex %d, name %s", +				__func__, ifan->ifan_index, ifan->ifan_name); + +		/* Create Interface */ +		ifp = if_get_by_name_len( +			ifan->ifan_name, +			strnlen(ifan->ifan_name, sizeof(ifan->ifan_name)), +			VRF_DEFAULT, 0); +		ifp->ifindex = ifan->ifan_index; + +		if_get_metric(ifp); +		if_add_update(ifp); +	} else if (ifp != NULL && ifan->ifan_what == IFAN_DEPARTURE) +		if_delete_update(ifp); + +	if_get_flags(ifp); +	if_get_mtu(ifp); +	if_get_metric(ifp); + +	if (IS_ZEBRA_DEBUG_KERNEL) +		zlog_debug("%s: interface %s index %d", __func__, +			   ifan->ifan_name, ifan->ifan_index); + +	return 0;  }  #endif /* RTM_IFANNOUNCE */  #ifdef HAVE_BSD_IFI_LINK_STATE  /* BSD link detect translation */ -static void -bsd_linkdetect_translate (struct if_msghdr *ifm) +static void bsd_linkdetect_translate(struct if_msghdr *ifm)  { -  if ((ifm->ifm_data.ifi_link_state >= LINK_STATE_UP) || -      (ifm->ifm_data.ifi_link_state == LINK_STATE_UNKNOWN)) -    SET_FLAG(ifm->ifm_flags, IFF_RUNNING); -  else -    UNSET_FLAG(ifm->ifm_flags, IFF_RUNNING); +	if ((ifm->ifm_data.ifi_link_state >= LINK_STATE_UP) +	    || (ifm->ifm_data.ifi_link_state == LINK_STATE_UNKNOWN)) +		SET_FLAG(ifm->ifm_flags, IFF_RUNNING); +	else +		UNSET_FLAG(ifm->ifm_flags, IFF_RUNNING);  }  #endif /* HAVE_BSD_IFI_LINK_STATE */ -static enum zebra_link_type -sdl_to_zebra_link_type (unsigned int sdlt) +static enum zebra_link_type sdl_to_zebra_link_type(unsigned int sdlt)  { -  switch (sdlt) -  { -    case IFT_ETHER: return ZEBRA_LLT_ETHER; -    case IFT_X25: return ZEBRA_LLT_X25; -    case IFT_FDDI: return ZEBRA_LLT_FDDI; -    case IFT_PPP: return ZEBRA_LLT_PPP; -    case IFT_LOOP: return ZEBRA_LLT_LOOPBACK; -    case IFT_SLIP: return ZEBRA_LLT_SLIP; -    case IFT_ARCNET: return ZEBRA_LLT_ARCNET; -    case IFT_ATM: return ZEBRA_LLT_ATM; -    case IFT_LOCALTALK: return ZEBRA_LLT_LOCALTLK; -    case IFT_HIPPI: return ZEBRA_LLT_HIPPI; +	switch (sdlt) { +	case IFT_ETHER: +		return ZEBRA_LLT_ETHER; +	case IFT_X25: +		return ZEBRA_LLT_X25; +	case IFT_FDDI: +		return ZEBRA_LLT_FDDI; +	case IFT_PPP: +		return ZEBRA_LLT_PPP; +	case IFT_LOOP: +		return ZEBRA_LLT_LOOPBACK; +	case IFT_SLIP: +		return ZEBRA_LLT_SLIP; +	case IFT_ARCNET: +		return ZEBRA_LLT_ARCNET; +	case IFT_ATM: +		return ZEBRA_LLT_ATM; +	case IFT_LOCALTALK: +		return ZEBRA_LLT_LOCALTLK; +	case IFT_HIPPI: +		return ZEBRA_LLT_HIPPI;  #ifdef IFT_IEEE1394 -    case IFT_IEEE1394: return ZEBRA_LLT_IEEE1394; +	case IFT_IEEE1394: +		return ZEBRA_LLT_IEEE1394;  #endif -    default: return ZEBRA_LLT_UNKNOWN; -  } +	default: +		return ZEBRA_LLT_UNKNOWN; +	}  }  /* @@ -404,342 +397,339 @@ sdl_to_zebra_link_type (unsigned int sdlt)   * sysctl (from interface_list).  There may or may not be sockaddrs   * present after the header.   */ -int -ifm_read (struct if_msghdr *ifm) +int ifm_read(struct if_msghdr *ifm)  { -  struct interface *ifp = NULL; -  struct sockaddr_dl *sdl; -  char ifname[IFNAMSIZ]; -  short ifnlen = 0; -  caddr_t cp; -   -  /* terminate ifname at head (for strnlen) and tail (for safety) */ -  ifname[IFNAMSIZ - 1] = '\0'; -   -  /* paranoia: sanity check structure */ -  if (ifm->ifm_msglen < sizeof(struct if_msghdr)) -    { -      zlog_err ("ifm_read: ifm->ifm_msglen %d too short\n", -		ifm->ifm_msglen); -      return -1; -    } - -  /* -   * Check for a sockaddr_dl following the message.  First, point to -   * where a socakddr might be if one follows the message. -   */ -  cp = (void *)(ifm + 1); +	struct interface *ifp = NULL; +	struct sockaddr_dl *sdl; +	char ifname[IFNAMSIZ]; +	short ifnlen = 0; +	caddr_t cp; + +	/* terminate ifname at head (for strnlen) and tail (for safety) */ +	ifname[IFNAMSIZ - 1] = '\0'; + +	/* paranoia: sanity check structure */ +	if (ifm->ifm_msglen < sizeof(struct if_msghdr)) { +		zlog_err("ifm_read: ifm->ifm_msglen %d too short\n", +			 ifm->ifm_msglen); +		return -1; +	} + +	/* +	 * Check for a sockaddr_dl following the message.  First, point to +	 * where a socakddr might be if one follows the message. +	 */ +	cp = (void *)(ifm + 1);  #ifdef SUNOS_5 -  /*  -   * XXX This behavior should be narrowed to only the kernel versions -   * for which the structures returned do not match the headers. -   * -   * if_msghdr_t on 64 bit kernels in Solaris 9 and earlier versions -   * is 12 bytes larger than the 32 bit version. -   */ -  if (((struct sockaddr *) cp)->sa_family == AF_UNSPEC) -  	cp = cp + 12; +	/* +	 * XXX This behavior should be narrowed to only the kernel versions +	 * for which the structures returned do not match the headers. +	 * +	 * if_msghdr_t on 64 bit kernels in Solaris 9 and earlier versions +	 * is 12 bytes larger than the 32 bit version. +	 */ +	if (((struct sockaddr *)cp)->sa_family == AF_UNSPEC) +		cp = cp + 12;  #endif -  RTA_ADDR_GET (NULL, RTA_DST, ifm->ifm_addrs, cp); -  RTA_ADDR_GET (NULL, RTA_GATEWAY, ifm->ifm_addrs, cp); -  RTA_ATTR_GET (NULL, RTA_NETMASK, ifm->ifm_addrs, cp); -  RTA_ADDR_GET (NULL, RTA_GENMASK, ifm->ifm_addrs, cp); -  sdl = (struct sockaddr_dl *)cp; -  RTA_NAME_GET (ifname, RTA_IFP, ifm->ifm_addrs, cp, ifnlen); -  RTA_ADDR_GET (NULL, RTA_IFA, ifm->ifm_addrs, cp); -  RTA_ADDR_GET (NULL, RTA_AUTHOR, ifm->ifm_addrs, cp); -  RTA_ADDR_GET (NULL, RTA_BRD, ifm->ifm_addrs, cp); -   -  if (IS_ZEBRA_DEBUG_KERNEL) -    zlog_debug ("%s: sdl ifname %s", __func__, (ifnlen ? ifname : "(nil)")); -   -  /*  -   * Look up on ifindex first, because ifindices are the primary handle for -   * interfaces across the user/kernel boundary, for most systems.  (Some -   * messages, such as up/down status changes on NetBSD, do not include a -   * sockaddr_dl). -   */ -  if ( (ifp = if_lookup_by_index (ifm->ifm_index, VRF_DEFAULT)) != NULL ) -    { -      /* we have an ifp, verify that the name matches as some systems, -       * eg Solaris, have a 1:many association of ifindex:ifname -       * if they dont match, we dont have the correct ifp and should -       * set it back to NULL to let next check do lookup by name -       */ -      if (ifnlen && (strncmp (ifp->name, ifname, IFNAMSIZ) != 0) ) -        { -          if (IS_ZEBRA_DEBUG_KERNEL) -            zlog_debug ("%s: ifp name %s doesnt match sdl name %s", -                        __func__, ifp->name, ifname); -          ifp = NULL; -        } -    } -   -  /*  -   * If we dont have an ifp, try looking up by name.  Particularly as some -   * systems (Solaris) have a 1:many mapping of ifindex:ifname - the ifname -   * is therefore our unique handle to that interface. -   * -   * Interfaces specified in the configuration file for which the ifindex -   * has not been determined will have ifindex == IFINDEX_INTERNAL, and such -   * interfaces are found by this search, and then their ifindex values can -   * be filled in. -   */ -  if ( (ifp == NULL) && ifnlen) -    ifp = if_lookup_by_name (ifname, VRF_DEFAULT); - -  /* -   * If ifp still does not exist or has an invalid index (IFINDEX_INTERNAL), -   * create or fill in an interface. -   */ -  if ((ifp == NULL) || (ifp->ifindex == IFINDEX_INTERNAL)) -    { -      /* -       * To create or fill in an interface, a sockaddr_dl (via -       * RTA_IFP) is required. -       */ -      if (!ifnlen) -	{ -	  zlog_warn ("Interface index %d (new) missing ifname\n", -		     ifm->ifm_index); -	  return -1; +	RTA_ADDR_GET(NULL, RTA_DST, ifm->ifm_addrs, cp); +	RTA_ADDR_GET(NULL, RTA_GATEWAY, ifm->ifm_addrs, cp); +	RTA_ATTR_GET(NULL, RTA_NETMASK, ifm->ifm_addrs, cp); +	RTA_ADDR_GET(NULL, RTA_GENMASK, ifm->ifm_addrs, cp); +	sdl = (struct sockaddr_dl *)cp; +	RTA_NAME_GET(ifname, RTA_IFP, ifm->ifm_addrs, cp, ifnlen); +	RTA_ADDR_GET(NULL, RTA_IFA, ifm->ifm_addrs, cp); +	RTA_ADDR_GET(NULL, RTA_AUTHOR, ifm->ifm_addrs, cp); +	RTA_ADDR_GET(NULL, RTA_BRD, ifm->ifm_addrs, cp); + +	if (IS_ZEBRA_DEBUG_KERNEL) +		zlog_debug("%s: sdl ifname %s", __func__, +			   (ifnlen ? ifname : "(nil)")); + +	/* +	 * Look up on ifindex first, because ifindices are the primary handle +	 * for +	 * interfaces across the user/kernel boundary, for most systems.  (Some +	 * messages, such as up/down status changes on NetBSD, do not include a +	 * sockaddr_dl). +	 */ +	if ((ifp = if_lookup_by_index(ifm->ifm_index, VRF_DEFAULT)) != NULL) { +		/* we have an ifp, verify that the name matches as some systems, +		 * eg Solaris, have a 1:many association of ifindex:ifname +		 * if they dont match, we dont have the correct ifp and should +		 * set it back to NULL to let next check do lookup by name +		 */ +		if (ifnlen && (strncmp(ifp->name, ifname, IFNAMSIZ) != 0)) { +			if (IS_ZEBRA_DEBUG_KERNEL) +				zlog_debug( +					"%s: ifp name %s doesnt match sdl name %s", +					__func__, ifp->name, ifname); +			ifp = NULL; +		}  	} +	/* +	 * If we dont have an ifp, try looking up by name.  Particularly as some +	 * systems (Solaris) have a 1:many mapping of ifindex:ifname - the +	 * ifname +	 * is therefore our unique handle to that interface. +	 * +	 * Interfaces specified in the configuration file for which the ifindex +	 * has not been determined will have ifindex == IFINDEX_INTERNAL, and +	 * such +	 * interfaces are found by this search, and then their ifindex values +	 * can +	 * be filled in. +	 */ +	if ((ifp == NULL) && ifnlen) +		ifp = if_lookup_by_name(ifname, VRF_DEFAULT); + +	/* +	 * If ifp still does not exist or has an invalid index +	 * (IFINDEX_INTERNAL), +	 * create or fill in an interface. +	 */ +	if ((ifp == NULL) || (ifp->ifindex == IFINDEX_INTERNAL)) { +		/* +		 * To create or fill in an interface, a sockaddr_dl (via +		 * RTA_IFP) is required. +		 */ +		if (!ifnlen) { +			zlog_warn("Interface index %d (new) missing ifname\n", +				  ifm->ifm_index); +			return -1; +		} +  #ifndef RTM_IFANNOUNCE -      /* Down->Down interface should be ignored here. -       * See further comment below. -       */ -      if (!CHECK_FLAG (ifm->ifm_flags, IFF_UP)) -        return 0; +		/* Down->Down interface should be ignored here. +		 * See further comment below. +		 */ +		if (!CHECK_FLAG(ifm->ifm_flags, IFF_UP)) +			return 0;  #endif /* !RTM_IFANNOUNCE */ -       -      if (ifp == NULL) -        { -	  /* Interface that zebra was not previously aware of, so create. */  -	  ifp = if_create (ifname, ifnlen, VRF_DEFAULT); -	  if (IS_ZEBRA_DEBUG_KERNEL) -	    zlog_debug ("%s: creating ifp for ifindex %d",  -	                __func__, ifm->ifm_index); -        } - -      if (IS_ZEBRA_DEBUG_KERNEL) -        zlog_debug ("%s: updated/created ifp, ifname %s, ifindex %d", -                    __func__, ifp->name, ifp->ifindex); -      /*  -       * Fill in newly created interface structure, or larval -       * structure with ifindex IFINDEX_INTERNAL. -       */ -      ifp->ifindex = ifm->ifm_index; -       + +		if (ifp == NULL) { +			/* Interface that zebra was not previously aware of, so +			 * create. */ +			ifp = if_create(ifname, ifnlen, VRF_DEFAULT); +			if (IS_ZEBRA_DEBUG_KERNEL) +				zlog_debug("%s: creating ifp for ifindex %d", +					   __func__, ifm->ifm_index); +		} + +		if (IS_ZEBRA_DEBUG_KERNEL) +			zlog_debug( +				"%s: updated/created ifp, ifname %s, ifindex %d", +				__func__, ifp->name, ifp->ifindex); +		/* +		 * Fill in newly created interface structure, or larval +		 * structure with ifindex IFINDEX_INTERNAL. +		 */ +		ifp->ifindex = ifm->ifm_index; +  #ifdef HAVE_BSD_IFI_LINK_STATE /* translate BSD kernel msg for link-state */ -      bsd_linkdetect_translate(ifm); +		bsd_linkdetect_translate(ifm);  #endif /* HAVE_BSD_IFI_LINK_STATE */ -      if_flags_update (ifp, ifm->ifm_flags); +		if_flags_update(ifp, ifm->ifm_flags);  #if defined(__bsdi__) -      if_kvm_get_mtu (ifp); +		if_kvm_get_mtu(ifp);  #else -      if_get_mtu (ifp); +		if_get_mtu(ifp);  #endif /* __bsdi__ */ -      if_get_metric (ifp); - -      /* -       * XXX sockaddr_dl contents can be larger than the structure -       * definition.  There are 2 big families here: -       *  - BSD has sdl_len + sdl_data[16] + overruns sdl_data -       *    we MUST use sdl_len here or we'll truncate data. -       *  - Solaris has no sdl_len, but sdl_data[244] -       *    presumably, it's not going to run past that, so sizeof() -       *    is fine here. -       * a nonzero ifnlen from RTA_NAME_GET() means sdl is valid -       */ -      ifp->ll_type = ZEBRA_LLT_UNKNOWN; -      ifp->hw_addr_len = 0; -      if (ifnlen) -        { +		if_get_metric(ifp); + +		/* +		 * XXX sockaddr_dl contents can be larger than the structure +		 * definition.  There are 2 big families here: +		 *  - BSD has sdl_len + sdl_data[16] + overruns sdl_data +		 *    we MUST use sdl_len here or we'll truncate data. +		 *  - Solaris has no sdl_len, but sdl_data[244] +		 *    presumably, it's not going to run past that, so sizeof() +		 *    is fine here. +		 * a nonzero ifnlen from RTA_NAME_GET() means sdl is valid +		 */ +		ifp->ll_type = ZEBRA_LLT_UNKNOWN; +		ifp->hw_addr_len = 0; +		if (ifnlen) {  #ifdef HAVE_STRUCT_SOCKADDR_DL_SDL_LEN -          memcpy (&((struct zebra_if *)ifp->info)->sdl, sdl, sdl->sdl_len); +			memcpy(&((struct zebra_if *)ifp->info)->sdl, sdl, +			       sdl->sdl_len);  #else -          memcpy (&((struct zebra_if *)ifp->info)->sdl, sdl, sizeof (struct sockaddr_dl)); +			memcpy(&((struct zebra_if *)ifp->info)->sdl, sdl, +			       sizeof(struct sockaddr_dl));  #endif /* HAVE_STRUCT_SOCKADDR_DL_SDL_LEN */ -          ifp->ll_type = sdl_to_zebra_link_type (sdl->sdl_type); -          if (sdl->sdl_alen <= sizeof(ifp->hw_addr)) -            { -              memcpy (ifp->hw_addr, LLADDR(sdl), sdl->sdl_alen); -              ifp->hw_addr_len = sdl->sdl_alen; -            } -        } - -      if_add_update (ifp); -    } -  else -    /* -     * Interface structure exists.  Adjust stored flags from -     * notification.  If interface has up->down or down->up -     * transition, call state change routines (to adjust routes, -     * notify routing daemons, etc.).  (Other flag changes are stored -     * but apparently do not trigger action.) -     */ -    { -      if (ifp->ifindex != ifm->ifm_index) -        { -          zlog_warn ("%s: index mismatch, ifname %s, ifp index %d, " -                     "ifm index %d",  -                     __func__, ifp->name, ifp->ifindex, ifm->ifm_index); -          return -1; -        } -       +			ifp->ll_type = sdl_to_zebra_link_type(sdl->sdl_type); +			if (sdl->sdl_alen <= sizeof(ifp->hw_addr)) { +				memcpy(ifp->hw_addr, LLADDR(sdl), +				       sdl->sdl_alen); +				ifp->hw_addr_len = sdl->sdl_alen; +			} +		} + +		if_add_update(ifp); +	} else +	/* +	 * Interface structure exists.  Adjust stored flags from +	 * notification.  If interface has up->down or down->up +	 * transition, call state change routines (to adjust routes, +	 * notify routing daemons, etc.).  (Other flag changes are stored +	 * but apparently do not trigger action.) +	 */ +	{ +		if (ifp->ifindex != ifm->ifm_index) { +			zlog_warn( +				"%s: index mismatch, ifname %s, ifp index %d, " +				"ifm index %d", +				__func__, ifp->name, ifp->ifindex, +				ifm->ifm_index); +			return -1; +		} +  #ifdef HAVE_BSD_IFI_LINK_STATE /* translate BSD kernel msg for link-state */ -      bsd_linkdetect_translate(ifm); +		bsd_linkdetect_translate(ifm);  #endif /* HAVE_BSD_IFI_LINK_STATE */ -      /* update flags and handle operative->inoperative transition, if any */ -      if_flags_update (ifp, ifm->ifm_flags); -       +		/* update flags and handle operative->inoperative transition, if +		 * any */ +		if_flags_update(ifp, ifm->ifm_flags); +  #ifndef RTM_IFANNOUNCE -      if (!if_is_up (ifp)) -          { -            /* No RTM_IFANNOUNCE on this platform, so we can never -             * distinguish between ~IFF_UP and delete. We must presume -             * it has been deleted. -             * Eg, Solaris will not notify us of unplumb. -             * -             * XXX: Fixme - this should be runtime detected -             * So that a binary compiled on a system with IFANNOUNCE -             * will still behave correctly if run on a platform without -             */ -            if_delete_update (ifp); -          } +		if (!if_is_up(ifp)) { +			/* No RTM_IFANNOUNCE on this platform, so we can never +			 * distinguish between ~IFF_UP and delete. We must +			 * presume +			 * it has been deleted. +			 * Eg, Solaris will not notify us of unplumb. +			 * +			 * XXX: Fixme - this should be runtime detected +			 * So that a binary compiled on a system with IFANNOUNCE +			 * will still behave correctly if run on a platform +			 * without +			 */ +			if_delete_update(ifp); +		}  #endif /* RTM_IFANNOUNCE */ -      if (if_is_up (ifp)) -      { +		if (if_is_up(ifp)) {  #if defined(__bsdi__) -        if_kvm_get_mtu (ifp); +			if_kvm_get_mtu(ifp);  #else -        if_get_mtu (ifp); +			if_get_mtu(ifp);  #endif /* __bsdi__ */ -        if_get_metric (ifp); -      } -    } +			if_get_metric(ifp); +		} +	}  #ifdef HAVE_NET_RT_IFLIST -  ifp->stats = ifm->ifm_data; +	ifp->stats = ifm->ifm_data;  #endif /* HAVE_NET_RT_IFLIST */ -  ifp->speed = ifm->ifm_data.ifi_baudrate / 1000000; +	ifp->speed = ifm->ifm_data.ifi_baudrate / 1000000; -  if (IS_ZEBRA_DEBUG_KERNEL) -    zlog_debug ("%s: interface %s index %d",  -                __func__, ifp->name, ifp->ifindex); +	if (IS_ZEBRA_DEBUG_KERNEL) +		zlog_debug("%s: interface %s index %d", __func__, ifp->name, +			   ifp->ifindex); -  return 0; +	return 0;  }  /* Address read from struct ifa_msghdr. */ -static void -ifam_read_mesg (struct ifa_msghdr *ifm, -		union sockunion *addr, -		union sockunion *mask, -		union sockunion *brd, -		char *ifname, -		short *ifnlen) +static void ifam_read_mesg(struct ifa_msghdr *ifm, union sockunion *addr, +			   union sockunion *mask, union sockunion *brd, +			   char *ifname, short *ifnlen)  { -  caddr_t pnt, end; -  union sockunion dst; -  union sockunion gateway; - -  pnt = (caddr_t)(ifm + 1); -  end = ((caddr_t)ifm) + ifm->ifam_msglen; - -  /* Be sure structure is cleared */ -  memset (mask, 0, sizeof (union sockunion)); -  memset (addr, 0, sizeof (union sockunion)); -  memset (brd, 0, sizeof (union sockunion)); -  memset (&dst, 0, sizeof (union sockunion)); -  memset (&gateway, 0, sizeof (union sockunion)); - -  /* We fetch each socket variable into sockunion. */ -  RTA_ADDR_GET (&dst, RTA_DST, ifm->ifam_addrs, pnt); -  RTA_ADDR_GET (&gateway, RTA_GATEWAY, ifm->ifam_addrs, pnt); -  RTA_ATTR_GET (mask, RTA_NETMASK, ifm->ifam_addrs, pnt); -  RTA_ADDR_GET (NULL, RTA_GENMASK, ifm->ifam_addrs, pnt); -  RTA_NAME_GET (ifname, RTA_IFP, ifm->ifam_addrs, pnt, *ifnlen); -  RTA_ADDR_GET (addr, RTA_IFA, ifm->ifam_addrs, pnt); -  RTA_ADDR_GET (NULL, RTA_AUTHOR, ifm->ifam_addrs, pnt); -  RTA_ADDR_GET (brd, RTA_BRD, ifm->ifam_addrs, pnt); - -  if (IS_ZEBRA_DEBUG_KERNEL) -    { -      int family = sockunion_family(addr); -      switch (family) -        { -	case AF_INET: -	case AF_INET6: -	  { -	    char buf[4][INET6_ADDRSTRLEN]; -	    zlog_debug ("%s: ifindex %d, ifname %s, ifam_addrs 0x%x, " -			"ifam_flags 0x%x, addr %s/%d broad %s dst %s " -			"gateway %s", -			__func__, ifm->ifam_index, -			(ifnlen ? ifname : "(nil)"), ifm->ifam_addrs, -			ifm->ifam_flags, -			inet_ntop(family,&addr->sin.sin_addr, -			          buf[0],sizeof(buf[0])), -			ip_masklen(mask->sin.sin_addr), -			inet_ntop(family,&brd->sin.sin_addr, -			          buf[1],sizeof(buf[1])), -			inet_ntop(family,&dst.sin.sin_addr, -			          buf[2],sizeof(buf[2])), -			inet_ntop(family,&gateway.sin.sin_addr, -			          buf[3],sizeof(buf[3]))); -	  } -	  break; -        default: -	  zlog_debug ("%s: ifindex %d, ifname %s, ifam_addrs 0x%x", -		      __func__, ifm->ifam_index,  -		      (ifnlen ? ifname : "(nil)"), ifm->ifam_addrs); -	  break; -        } -    } - -  /* Assert read up end point matches to end point */ -  if (pnt != end) -    zlog_warn ("ifam_read() doesn't read all socket data"); +	caddr_t pnt, end; +	union sockunion dst; +	union sockunion gateway; + +	pnt = (caddr_t)(ifm + 1); +	end = ((caddr_t)ifm) + ifm->ifam_msglen; + +	/* Be sure structure is cleared */ +	memset(mask, 0, sizeof(union sockunion)); +	memset(addr, 0, sizeof(union sockunion)); +	memset(brd, 0, sizeof(union sockunion)); +	memset(&dst, 0, sizeof(union sockunion)); +	memset(&gateway, 0, sizeof(union sockunion)); + +	/* We fetch each socket variable into sockunion. */ +	RTA_ADDR_GET(&dst, RTA_DST, ifm->ifam_addrs, pnt); +	RTA_ADDR_GET(&gateway, RTA_GATEWAY, ifm->ifam_addrs, pnt); +	RTA_ATTR_GET(mask, RTA_NETMASK, ifm->ifam_addrs, pnt); +	RTA_ADDR_GET(NULL, RTA_GENMASK, ifm->ifam_addrs, pnt); +	RTA_NAME_GET(ifname, RTA_IFP, ifm->ifam_addrs, pnt, *ifnlen); +	RTA_ADDR_GET(addr, RTA_IFA, ifm->ifam_addrs, pnt); +	RTA_ADDR_GET(NULL, RTA_AUTHOR, ifm->ifam_addrs, pnt); +	RTA_ADDR_GET(brd, RTA_BRD, ifm->ifam_addrs, pnt); + +	if (IS_ZEBRA_DEBUG_KERNEL) { +		int family = sockunion_family(addr); +		switch (family) { +		case AF_INET: +		case AF_INET6: { +			char buf[4][INET6_ADDRSTRLEN]; +			zlog_debug( +				"%s: ifindex %d, ifname %s, ifam_addrs 0x%x, " +				"ifam_flags 0x%x, addr %s/%d broad %s dst %s " +				"gateway %s", +				__func__, ifm->ifam_index, +				(ifnlen ? ifname : "(nil)"), ifm->ifam_addrs, +				ifm->ifam_flags, +				inet_ntop(family, &addr->sin.sin_addr, buf[0], +					  sizeof(buf[0])), +				ip_masklen(mask->sin.sin_addr), +				inet_ntop(family, &brd->sin.sin_addr, buf[1], +					  sizeof(buf[1])), +				inet_ntop(family, &dst.sin.sin_addr, buf[2], +					  sizeof(buf[2])), +				inet_ntop(family, &gateway.sin.sin_addr, buf[3], +					  sizeof(buf[3]))); +		} break; +		default: +			zlog_debug("%s: ifindex %d, ifname %s, ifam_addrs 0x%x", +				   __func__, ifm->ifam_index, +				   (ifnlen ? ifname : "(nil)"), +				   ifm->ifam_addrs); +			break; +		} +	} + +	/* Assert read up end point matches to end point */ +	if (pnt != end) +		zlog_warn("ifam_read() doesn't read all socket data");  }  /* Interface's address information get. */ -int -ifam_read (struct ifa_msghdr *ifam) +int ifam_read(struct ifa_msghdr *ifam)  { -  struct interface *ifp = NULL; -  union sockunion addr, mask, brd; -  char ifname[INTERFACE_NAMSIZ]; -  short ifnlen = 0; -  char isalias = 0; -  int flags = 0; -   -  ifname[0] = ifname[INTERFACE_NAMSIZ - 1] = '\0'; -   -  /* Allocate and read address information. */ -  ifam_read_mesg (ifam, &addr, &mask, &brd, ifname, &ifnlen); -   -  if ((ifp = if_lookup_by_index(ifam->ifam_index, VRF_DEFAULT)) == NULL) -    { -      zlog_warn ("%s: no interface for ifname %s, index %d",  -                 __func__, ifname, ifam->ifam_index); -      return -1; -    } -   -  if (ifnlen && strncmp (ifp->name, ifname, INTERFACE_NAMSIZ)) -    isalias = 1; -   -  /* N.B. The info in ifa_msghdr does not tell us whether the RTA_BRD -     field contains a broadcast address or a peer address, so we are forced to -     rely upon the interface type. */ -  if (if_is_pointopoint(ifp)) -    SET_FLAG(flags, ZEBRA_IFA_PEER); +	struct interface *ifp = NULL; +	union sockunion addr, mask, brd; +	char ifname[INTERFACE_NAMSIZ]; +	short ifnlen = 0; +	char isalias = 0; +	int flags = 0; + +	ifname[0] = ifname[INTERFACE_NAMSIZ - 1] = '\0'; + +	/* Allocate and read address information. */ +	ifam_read_mesg(ifam, &addr, &mask, &brd, ifname, &ifnlen); + +	if ((ifp = if_lookup_by_index(ifam->ifam_index, VRF_DEFAULT)) == NULL) { +		zlog_warn("%s: no interface for ifname %s, index %d", __func__, +			  ifname, ifam->ifam_index); +		return -1; +	} + +	if (ifnlen && strncmp(ifp->name, ifname, INTERFACE_NAMSIZ)) +		isalias = 1; + +	/* N.B. The info in ifa_msghdr does not tell us whether the RTA_BRD +	   field contains a broadcast address or a peer address, so we are +	   forced to +	   rely upon the interface type. */ +	if (if_is_pointopoint(ifp)) +		SET_FLAG(flags, ZEBRA_IFA_PEER);  #if 0    /* it might seem cute to grab the interface metric here, however @@ -750,450 +740,477 @@ ifam_read (struct ifa_msghdr *ifam)    ifp->metric = ifam->ifam_metric;  #endif -  /* Add connected address. */ -  switch (sockunion_family (&addr)) -    { -    case AF_INET: -      if (ifam->ifam_type == RTM_NEWADDR) -	connected_add_ipv4 (ifp, flags, &addr.sin.sin_addr,  -			    ip_masklen (mask.sin.sin_addr), -			    &brd.sin.sin_addr, -			    (isalias ? ifname : NULL)); -      else -	connected_delete_ipv4 (ifp, flags, &addr.sin.sin_addr,  -			       ip_masklen (mask.sin.sin_addr), -			       &brd.sin.sin_addr); -      break; -    case AF_INET6: -      /* Unset interface index from link-local address when IPv6 stack -	 is KAME. */ -      if (IN6_IS_ADDR_LINKLOCAL (&addr.sin6.sin6_addr)) -        { -          SET_IN6_LINKLOCAL_IFINDEX (addr.sin6.sin6_addr, 0); -        } - -      if (ifam->ifam_type == RTM_NEWADDR) -	connected_add_ipv6 (ifp, flags, &addr.sin6.sin6_addr,  -			    ip6_masklen (mask.sin6.sin6_addr), -			    &brd.sin6.sin6_addr, -			    (isalias ? ifname : NULL)); -      else -	connected_delete_ipv6 (ifp, -			       &addr.sin6.sin6_addr,  -			       ip6_masklen (mask.sin6.sin6_addr), -			       &brd.sin6.sin6_addr); -      break; -    default: -      /* Unsupported family silently ignore... */ -      break; -    } -   -  /* Check interface flag for implicit up of the interface. */ -  if_refresh (ifp); +	/* Add connected address. */ +	switch (sockunion_family(&addr)) { +	case AF_INET: +		if (ifam->ifam_type == RTM_NEWADDR) +			connected_add_ipv4(ifp, flags, &addr.sin.sin_addr, +					   ip_masklen(mask.sin.sin_addr), +					   &brd.sin.sin_addr, +					   (isalias ? ifname : NULL)); +		else +			connected_delete_ipv4(ifp, flags, &addr.sin.sin_addr, +					      ip_masklen(mask.sin.sin_addr), +					      &brd.sin.sin_addr); +		break; +	case AF_INET6: +		/* Unset interface index from link-local address when IPv6 stack +		   is KAME. */ +		if (IN6_IS_ADDR_LINKLOCAL(&addr.sin6.sin6_addr)) { +			SET_IN6_LINKLOCAL_IFINDEX(addr.sin6.sin6_addr, 0); +		} + +		if (ifam->ifam_type == RTM_NEWADDR) +			connected_add_ipv6(ifp, flags, &addr.sin6.sin6_addr, +					   ip6_masklen(mask.sin6.sin6_addr), +					   &brd.sin6.sin6_addr, +					   (isalias ? ifname : NULL)); +		else +			connected_delete_ipv6(ifp, &addr.sin6.sin6_addr, +					      ip6_masklen(mask.sin6.sin6_addr), +					      &brd.sin6.sin6_addr); +		break; +	default: +		/* Unsupported family silently ignore... */ +		break; +	} + +	/* Check interface flag for implicit up of the interface. */ +	if_refresh(ifp);  #ifdef SUNOS_5 -  /* In addition to lacking IFANNOUNCE, on SUNOS IFF_UP is strange.  -   * See comments for SUNOS_5 in interface.c::if_flags_mangle. -   *  -   * Here we take care of case where the real IFF_UP was previously -   * unset (as kept in struct zebra_if.primary_state) and the mangled -   * IFF_UP (ie IFF_UP set || listcount(connected) has now transitioned -   * to unset due to the lost non-primary address having DELADDR'd. -   * -   * we must delete the interface, because in between here and next -   * event for this interface-name the administrator could unplumb -   * and replumb the interface. -   */ -  if (!if_is_up (ifp)) -    if_delete_update (ifp); +	/* In addition to lacking IFANNOUNCE, on SUNOS IFF_UP is strange. +	 * See comments for SUNOS_5 in interface.c::if_flags_mangle. +	 * +	 * Here we take care of case where the real IFF_UP was previously +	 * unset (as kept in struct zebra_if.primary_state) and the mangled +	 * IFF_UP (ie IFF_UP set || listcount(connected) has now transitioned +	 * to unset due to the lost non-primary address having DELADDR'd. +	 * +	 * we must delete the interface, because in between here and next +	 * event for this interface-name the administrator could unplumb +	 * and replumb the interface. +	 */ +	if (!if_is_up(ifp)) +		if_delete_update(ifp);  #endif /* SUNOS_5 */ -   -  return 0; + +	return 0;  }  /* Interface function for reading kernel routing table information. */ -static int -rtm_read_mesg (struct rt_msghdr *rtm, -	       union sockunion *dest, -	       union sockunion *mask, -	       union sockunion *gate, -	       char *ifname, -	       short *ifnlen) +static int rtm_read_mesg(struct rt_msghdr *rtm, union sockunion *dest, +			 union sockunion *mask, union sockunion *gate, +			 char *ifname, short *ifnlen)  { -  caddr_t pnt, end; - -  /* Pnt points out socket data start point. */ -  pnt = (caddr_t)(rtm + 1); -  end = ((caddr_t)rtm) + rtm->rtm_msglen; - -  /* rt_msghdr version check. */ -  if (rtm->rtm_version != RTM_VERSION)  -      zlog_warn("Routing message version different %d should be %d." "This may cause problem\n", -                rtm->rtm_version, RTM_VERSION); -   -  /* Be sure structure is cleared */ -  memset (dest, 0, sizeof (union sockunion)); -  memset (gate, 0, sizeof (union sockunion)); -  memset (mask, 0, sizeof (union sockunion)); - -  /* We fetch each socket variable into sockunion. */ -  RTA_ADDR_GET (dest, RTA_DST, rtm->rtm_addrs, pnt); -  RTA_ADDR_GET (gate, RTA_GATEWAY, rtm->rtm_addrs, pnt); -  RTA_ATTR_GET (mask, RTA_NETMASK, rtm->rtm_addrs, pnt); -  RTA_ADDR_GET (NULL, RTA_GENMASK, rtm->rtm_addrs, pnt); -  RTA_NAME_GET (ifname, RTA_IFP, rtm->rtm_addrs, pnt, *ifnlen); -  RTA_ADDR_GET (NULL, RTA_IFA, rtm->rtm_addrs, pnt); -  RTA_ADDR_GET (NULL, RTA_AUTHOR, rtm->rtm_addrs, pnt); -  RTA_ADDR_GET (NULL, RTA_BRD, rtm->rtm_addrs, pnt); - -  /* If there is netmask information set it's family same as -     destination family*/ -  if (rtm->rtm_addrs & RTA_NETMASK) -    mask->sa.sa_family = dest->sa.sa_family; - -  /* Assert read up to the end of pointer. */ -  if (pnt != end)  -      zlog_warn("rtm_read() doesn't read all socket data."); - -  return rtm->rtm_flags; +	caddr_t pnt, end; + +	/* Pnt points out socket data start point. */ +	pnt = (caddr_t)(rtm + 1); +	end = ((caddr_t)rtm) + rtm->rtm_msglen; + +	/* rt_msghdr version check. */ +	if (rtm->rtm_version != RTM_VERSION) +		zlog_warn( +			"Routing message version different %d should be %d." +			"This may cause problem\n", +			rtm->rtm_version, RTM_VERSION); + +	/* Be sure structure is cleared */ +	memset(dest, 0, sizeof(union sockunion)); +	memset(gate, 0, sizeof(union sockunion)); +	memset(mask, 0, sizeof(union sockunion)); + +	/* We fetch each socket variable into sockunion. */ +	RTA_ADDR_GET(dest, RTA_DST, rtm->rtm_addrs, pnt); +	RTA_ADDR_GET(gate, RTA_GATEWAY, rtm->rtm_addrs, pnt); +	RTA_ATTR_GET(mask, RTA_NETMASK, rtm->rtm_addrs, pnt); +	RTA_ADDR_GET(NULL, RTA_GENMASK, rtm->rtm_addrs, pnt); +	RTA_NAME_GET(ifname, RTA_IFP, rtm->rtm_addrs, pnt, *ifnlen); +	RTA_ADDR_GET(NULL, RTA_IFA, rtm->rtm_addrs, pnt); +	RTA_ADDR_GET(NULL, RTA_AUTHOR, rtm->rtm_addrs, pnt); +	RTA_ADDR_GET(NULL, RTA_BRD, rtm->rtm_addrs, pnt); + +	/* If there is netmask information set it's family same as +	   destination family*/ +	if (rtm->rtm_addrs & RTA_NETMASK) +		mask->sa.sa_family = dest->sa.sa_family; + +	/* Assert read up to the end of pointer. */ +	if (pnt != end) +		zlog_warn("rtm_read() doesn't read all socket data."); + +	return rtm->rtm_flags;  } -void -rtm_read (struct rt_msghdr *rtm) +void rtm_read(struct rt_msghdr *rtm)  { -  int flags; -  u_char zebra_flags; -  union sockunion dest, mask, gate; -  char ifname[INTERFACE_NAMSIZ + 1]; -  short ifnlen = 0; - -  zebra_flags = 0; - -  /* Read destination and netmask and gateway from rtm message -     structure. */ -  flags = rtm_read_mesg (rtm, &dest, &mask, &gate, ifname, &ifnlen); -  if (!(flags & RTF_DONE)) -    return; -  if (IS_ZEBRA_DEBUG_KERNEL) -    zlog_debug ("%s: got rtm of type %d (%s)", __func__, rtm->rtm_type, -      lookup_msg(rtm_type_str, rtm->rtm_type, NULL)); - -#ifdef RTF_CLONED	/*bsdi, netbsd 1.6*/ -  if (flags & RTF_CLONED) -    return; +	int flags; +	u_char zebra_flags; +	union sockunion dest, mask, gate; +	char ifname[INTERFACE_NAMSIZ + 1]; +	short ifnlen = 0; + +	zebra_flags = 0; + +	/* Read destination and netmask and gateway from rtm message +	   structure. */ +	flags = rtm_read_mesg(rtm, &dest, &mask, &gate, ifname, &ifnlen); +	if (!(flags & RTF_DONE)) +		return; +	if (IS_ZEBRA_DEBUG_KERNEL) +		zlog_debug("%s: got rtm of type %d (%s)", __func__, +			   rtm->rtm_type, +			   lookup_msg(rtm_type_str, rtm->rtm_type, NULL)); + +#ifdef RTF_CLONED /*bsdi, netbsd 1.6*/ +	if (flags & RTF_CLONED) +		return;  #endif -#ifdef RTF_WASCLONED	/*freebsd*/ -  if (flags & RTF_WASCLONED) -    return; +#ifdef RTF_WASCLONED /*freebsd*/ +	if (flags & RTF_WASCLONED) +		return;  #endif -  if ((rtm->rtm_type == RTM_ADD || rtm->rtm_type == RTM_CHANGE) && ! (flags & RTF_UP)) -    return; - -  /* This is connected route. */ -  if (! (flags & RTF_GATEWAY)) -      return; - -  if (flags & RTF_PROTO1) -    SET_FLAG (zebra_flags, ZEBRA_FLAG_SELFROUTE); - -  /* This is persistent route. */ -  if (flags & RTF_STATIC) -    SET_FLAG (zebra_flags, ZEBRA_FLAG_STATIC); - -  /* This is a reject or blackhole route */ -  if (flags & RTF_REJECT) -    SET_FLAG (zebra_flags, ZEBRA_FLAG_REJECT); -  if (flags & RTF_BLACKHOLE) -    SET_FLAG (zebra_flags, ZEBRA_FLAG_BLACKHOLE); - -  if (dest.sa.sa_family == AF_INET) -    { -      struct prefix p; - -      p.family = AF_INET; -      p.u.prefix4 = dest.sin.sin_addr; -      if (flags & RTF_HOST) -	p.prefixlen = IPV4_MAX_PREFIXLEN; -      else -	p.prefixlen = ip_masklen (mask.sin.sin_addr); -       -      /* Catch self originated messages and match them against our current RIB. -       * At the same time, ignore unconfirmed messages, they should be tracked -       * by rtm_write() and kernel_rtm_ipv4(). -       */ -      if (rtm->rtm_type != RTM_GET && rtm->rtm_pid == pid) -      { -        char buf[PREFIX_STRLEN], gate_buf[INET_ADDRSTRLEN]; -        int ret; -        if (! IS_ZEBRA_DEBUG_RIB) -          return; -        ret = rib_lookup_ipv4_route ((struct prefix_ipv4 *)&p, &gate, VRF_DEFAULT); -        prefix2str (&p, buf, sizeof(buf)); -        switch (rtm->rtm_type) -        { -          case RTM_ADD: -          case RTM_GET: -          case RTM_CHANGE: -            /* The kernel notifies us about a new route in FIB created by us. -               Do we have a correspondent entry in our RIB? */ -            switch (ret) -            { -              case ZEBRA_RIB_NOTFOUND: -                zlog_debug ("%s: %s %s: desync: RR isn't yet in RIB, while already in FIB", -                  __func__, lookup_msg(rtm_type_str, rtm->rtm_type, NULL), buf); -                break; -              case ZEBRA_RIB_FOUND_CONNECTED: -              case ZEBRA_RIB_FOUND_NOGATE: -                inet_ntop (AF_INET, &gate.sin.sin_addr, gate_buf, INET_ADDRSTRLEN); -                zlog_debug ("%s: %s %s: desync: RR is in RIB, but gate differs (ours is %s)", -                  __func__, lookup_msg(rtm_type_str, rtm->rtm_type, NULL), buf, gate_buf); -                break; -              case ZEBRA_RIB_FOUND_EXACT: /* RIB RR == FIB RR */ -                zlog_debug ("%s: %s %s: done Ok", -                  __func__, lookup_msg(rtm_type_str, rtm->rtm_type, NULL), buf); -                rib_lookup_and_dump ((struct prefix_ipv4 *)&p, VRF_DEFAULT); -                return; -                break; -            } -            break; -          case RTM_DELETE: -            /* The kernel notifies us about a route deleted by us. Do we still -               have it in the RIB? Do we have anything instead? */ -            switch (ret) -            { -              case ZEBRA_RIB_FOUND_EXACT: -                zlog_debug ("%s: %s %s: desync: RR is still in RIB, while already not in FIB", -                  __func__, lookup_msg(rtm_type_str, rtm->rtm_type, NULL), buf); -                rib_lookup_and_dump ((struct prefix_ipv4 *)&p, VRF_DEFAULT); -                break; -              case ZEBRA_RIB_FOUND_CONNECTED: -              case ZEBRA_RIB_FOUND_NOGATE: -                zlog_debug ("%s: %s %s: desync: RR is still in RIB, plus gate differs", -                  __func__, lookup_msg(rtm_type_str, rtm->rtm_type, NULL), buf); -                rib_lookup_and_dump ((struct prefix_ipv4 *)&p, VRF_DEFAULT); -                break; -              case ZEBRA_RIB_NOTFOUND: /* RIB RR == FIB RR */ -                zlog_debug ("%s: %s %s: done Ok", -                  __func__, lookup_msg(rtm_type_str, rtm->rtm_type, NULL), buf); -                rib_lookup_and_dump ((struct prefix_ipv4 *)&p, VRF_DEFAULT); -                return; -                break; -            } -            break; -          default: -            zlog_debug ("%s: %s: warning: loopback RTM of type %s received", -              __func__, buf, lookup_msg(rtm_type_str, rtm->rtm_type, NULL)); -        } -        return; -      } - -      /* Change, delete the old prefix, we have no further information -       * to specify the route really -       */ -      if (rtm->rtm_type == RTM_CHANGE) -        rib_delete (AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, -		    0, zebra_flags, &p, NULL, NULL, 0, 0); -       -      union g_addr ggate = { .ipv4 = gate.sin.sin_addr }; -      if (rtm->rtm_type == RTM_GET  -          || rtm->rtm_type == RTM_ADD -          || rtm->rtm_type == RTM_CHANGE) -	rib_add (AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, zebra_flags, -		 &p, NULL, &ggate, NULL, 0, 0, 0, 0, 0); -      else -	rib_delete (AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, -		    0, zebra_flags, &p, NULL, &ggate, 0, 0); -    } -  if (dest.sa.sa_family == AF_INET6) -    { -      /* One day we might have a debug section here like one in the -       * IPv4 case above. Just ignore own messages at the moment. -       */ -      if (rtm->rtm_type != RTM_GET && rtm->rtm_pid == pid) -        return; -      struct prefix p; -      ifindex_t ifindex = 0; - -      p.family = AF_INET6; -      p.u.prefix6 = dest.sin6.sin6_addr; -      if (flags & RTF_HOST) -	p.prefixlen = IPV6_MAX_PREFIXLEN; -      else -	p.prefixlen = ip6_masklen (mask.sin6.sin6_addr); +	if ((rtm->rtm_type == RTM_ADD || rtm->rtm_type == RTM_CHANGE) +	    && !(flags & RTF_UP)) +		return; + +	/* This is connected route. */ +	if (!(flags & RTF_GATEWAY)) +		return; + +	if (flags & RTF_PROTO1) +		SET_FLAG(zebra_flags, ZEBRA_FLAG_SELFROUTE); + +	/* This is persistent route. */ +	if (flags & RTF_STATIC) +		SET_FLAG(zebra_flags, ZEBRA_FLAG_STATIC); + +	/* This is a reject or blackhole route */ +	if (flags & RTF_REJECT) +		SET_FLAG(zebra_flags, ZEBRA_FLAG_REJECT); +	if (flags & RTF_BLACKHOLE) +		SET_FLAG(zebra_flags, ZEBRA_FLAG_BLACKHOLE); + +	if (dest.sa.sa_family == AF_INET) { +		struct prefix p; + +		p.family = AF_INET; +		p.u.prefix4 = dest.sin.sin_addr; +		if (flags & RTF_HOST) +			p.prefixlen = IPV4_MAX_PREFIXLEN; +		else +			p.prefixlen = ip_masklen(mask.sin.sin_addr); + +		/* Catch self originated messages and match them against our +		 * current RIB. +		 * At the same time, ignore unconfirmed messages, they should be +		 * tracked +		 * by rtm_write() and kernel_rtm_ipv4(). +		 */ +		if (rtm->rtm_type != RTM_GET && rtm->rtm_pid == pid) { +			char buf[PREFIX_STRLEN], gate_buf[INET_ADDRSTRLEN]; +			int ret; +			if (!IS_ZEBRA_DEBUG_RIB) +				return; +			ret = rib_lookup_ipv4_route((struct prefix_ipv4 *)&p, +						    &gate, VRF_DEFAULT); +			prefix2str(&p, buf, sizeof(buf)); +			switch (rtm->rtm_type) { +			case RTM_ADD: +			case RTM_GET: +			case RTM_CHANGE: +				/* The kernel notifies us about a new route in +				   FIB created by us. +				   Do we have a correspondent entry in our RIB? +				   */ +				switch (ret) { +				case ZEBRA_RIB_NOTFOUND: +					zlog_debug( +						"%s: %s %s: desync: RR isn't yet in RIB, while already in FIB", +						__func__, +						lookup_msg(rtm_type_str, +							   rtm->rtm_type, NULL), +						buf); +					break; +				case ZEBRA_RIB_FOUND_CONNECTED: +				case ZEBRA_RIB_FOUND_NOGATE: +					inet_ntop(AF_INET, &gate.sin.sin_addr, +						  gate_buf, INET_ADDRSTRLEN); +					zlog_debug( +						"%s: %s %s: desync: RR is in RIB, but gate differs (ours is %s)", +						__func__, +						lookup_msg(rtm_type_str, +							   rtm->rtm_type, NULL), +						buf, gate_buf); +					break; +				case ZEBRA_RIB_FOUND_EXACT: /* RIB RR == FIB RR +							       */ +					zlog_debug( +						"%s: %s %s: done Ok", __func__, +						lookup_msg(rtm_type_str, +							   rtm->rtm_type, NULL), +						buf); +					rib_lookup_and_dump( +						(struct prefix_ipv4 *)&p, +						VRF_DEFAULT); +					return; +					break; +				} +				break; +			case RTM_DELETE: +				/* The kernel notifies us about a route deleted +				   by us. Do we still +				   have it in the RIB? Do we have anything +				   instead? */ +				switch (ret) { +				case ZEBRA_RIB_FOUND_EXACT: +					zlog_debug( +						"%s: %s %s: desync: RR is still in RIB, while already not in FIB", +						__func__, +						lookup_msg(rtm_type_str, +							   rtm->rtm_type, NULL), +						buf); +					rib_lookup_and_dump( +						(struct prefix_ipv4 *)&p, +						VRF_DEFAULT); +					break; +				case ZEBRA_RIB_FOUND_CONNECTED: +				case ZEBRA_RIB_FOUND_NOGATE: +					zlog_debug( +						"%s: %s %s: desync: RR is still in RIB, plus gate differs", +						__func__, +						lookup_msg(rtm_type_str, +							   rtm->rtm_type, NULL), +						buf); +					rib_lookup_and_dump( +						(struct prefix_ipv4 *)&p, +						VRF_DEFAULT); +					break; +				case ZEBRA_RIB_NOTFOUND: /* RIB RR == FIB RR */ +					zlog_debug( +						"%s: %s %s: done Ok", __func__, +						lookup_msg(rtm_type_str, +							   rtm->rtm_type, NULL), +						buf); +					rib_lookup_and_dump( +						(struct prefix_ipv4 *)&p, +						VRF_DEFAULT); +					return; +					break; +				} +				break; +			default: +				zlog_debug( +					"%s: %s: warning: loopback RTM of type %s received", +					__func__, buf, +					lookup_msg(rtm_type_str, rtm->rtm_type, +						   NULL)); +			} +			return; +		} + +		/* Change, delete the old prefix, we have no further information +		 * to specify the route really +		 */ +		if (rtm->rtm_type == RTM_CHANGE) +			rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, +				   ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, +				   NULL, 0, 0); + +		union g_addr ggate = {.ipv4 = gate.sin.sin_addr}; +		if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD +		    || rtm->rtm_type == RTM_CHANGE) +			rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, +				ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, +				&ggate, NULL, 0, 0, 0, 0, 0); +		else +			rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, +				   ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, +				   &ggate, 0, 0); +	} +	if (dest.sa.sa_family == AF_INET6) { +		/* One day we might have a debug section here like one in the +		 * IPv4 case above. Just ignore own messages at the moment. +		 */ +		if (rtm->rtm_type != RTM_GET && rtm->rtm_pid == pid) +			return; +		struct prefix p; +		ifindex_t ifindex = 0; + +		p.family = AF_INET6; +		p.u.prefix6 = dest.sin6.sin6_addr; +		if (flags & RTF_HOST) +			p.prefixlen = IPV6_MAX_PREFIXLEN; +		else +			p.prefixlen = ip6_masklen(mask.sin6.sin6_addr);  #ifdef KAME -      if (IN6_IS_ADDR_LINKLOCAL (&gate.sin6.sin6_addr)) -	{ -	  ifindex = IN6_LINKLOCAL_IFINDEX (gate.sin6.sin6_addr); -	  SET_IN6_LINKLOCAL_IFINDEX (gate.sin6.sin6_addr, 0); -	} +		if (IN6_IS_ADDR_LINKLOCAL(&gate.sin6.sin6_addr)) { +			ifindex = IN6_LINKLOCAL_IFINDEX(gate.sin6.sin6_addr); +			SET_IN6_LINKLOCAL_IFINDEX(gate.sin6.sin6_addr, 0); +		}  #endif /* KAME */ -      /* CHANGE: delete the old prefix, we have no further information -       * to specify the route really -       */ -      if (rtm->rtm_type == RTM_CHANGE) -        rib_delete (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, -		    0, zebra_flags, &p, NULL, NULL, 0, 0); - -      union g_addr ggate = { .ipv6 = gate.sin6.sin6_addr }; -      if (rtm->rtm_type == RTM_GET  -          || rtm->rtm_type == RTM_ADD -          || rtm->rtm_type == RTM_CHANGE) -	rib_add (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, -		 0, zebra_flags, &p, NULL, &ggate, NULL, ifindex, -		 0, 0, 0, 0); -      else -	rib_delete (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, -		    0, zebra_flags, &p, NULL, &ggate, ifindex, 0); -    } +		/* CHANGE: delete the old prefix, we have no further information +		 * to specify the route really +		 */ +		if (rtm->rtm_type == RTM_CHANGE) +			rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, +				   ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, +				   NULL, 0, 0); + +		union g_addr ggate = {.ipv6 = gate.sin6.sin6_addr}; +		if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD +		    || rtm->rtm_type == RTM_CHANGE) +			rib_add(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, +				ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, +				&ggate, NULL, ifindex, 0, 0, 0, 0); +		else +			rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, +				   ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, +				   &ggate, ifindex, 0); +	}  }  /* Interface function for the kernel routing table updates.  Support   * for RTM_CHANGE will be needed.   * Exported only for rt_socket.c   */ -int -rtm_write (int message, -	   union sockunion *dest, -	   union sockunion *mask, -	   union sockunion *gate, -	   union sockunion *mpls, -	   unsigned int index, -	   int zebra_flags, -	   int metric) +int rtm_write(int message, union sockunion *dest, union sockunion *mask, +	      union sockunion *gate, union sockunion *mpls, unsigned int index, +	      int zebra_flags, int metric)  { -  int ret; -  caddr_t pnt; -  struct interface *ifp; - -  /* Sequencial number of routing message. */ -  static int msg_seq = 0; - -  /* Struct of rt_msghdr and buffer for storing socket's data. */ -  struct  -  { -    struct rt_msghdr rtm; -    char buf[512]; -  } msg; -   -  if (routing_sock < 0) -    return ZEBRA_ERR_EPERM; - -  /* Clear and set rt_msghdr values */ -  memset (&msg, 0, sizeof (struct rt_msghdr)); -  msg.rtm.rtm_version = RTM_VERSION; -  msg.rtm.rtm_type = message; -  msg.rtm.rtm_seq = msg_seq++; -  msg.rtm.rtm_addrs = RTA_DST; -  msg.rtm.rtm_addrs |= RTA_GATEWAY; -  msg.rtm.rtm_flags = RTF_UP; +	int ret; +	caddr_t pnt; +	struct interface *ifp; + +	/* Sequencial number of routing message. */ +	static int msg_seq = 0; + +	/* Struct of rt_msghdr and buffer for storing socket's data. */ +	struct { +		struct rt_msghdr rtm; +		char buf[512]; +	} msg; + +	if (routing_sock < 0) +		return ZEBRA_ERR_EPERM; + +	/* Clear and set rt_msghdr values */ +	memset(&msg, 0, sizeof(struct rt_msghdr)); +	msg.rtm.rtm_version = RTM_VERSION; +	msg.rtm.rtm_type = message; +	msg.rtm.rtm_seq = msg_seq++; +	msg.rtm.rtm_addrs = RTA_DST; +	msg.rtm.rtm_addrs |= RTA_GATEWAY; +	msg.rtm.rtm_flags = RTF_UP;  #ifdef __OpenBSD__ -  msg.rtm.rtm_flags |= RTF_MPATH; -  msg.rtm.rtm_fmask = RTF_MPLS; +	msg.rtm.rtm_flags |= RTF_MPATH; +	msg.rtm.rtm_fmask = RTF_MPLS;  #endif -  msg.rtm.rtm_index = index; +	msg.rtm.rtm_index = index; -  if (metric != 0) -    { -      msg.rtm.rtm_rmx.rmx_hopcount = metric; -      msg.rtm.rtm_inits |= RTV_HOPCOUNT; -    } +	if (metric != 0) { +		msg.rtm.rtm_rmx.rmx_hopcount = metric; +		msg.rtm.rtm_inits |= RTV_HOPCOUNT; +	} -  ifp = if_lookup_by_index (index, VRF_DEFAULT); +	ifp = if_lookup_by_index(index, VRF_DEFAULT); -  if (gate && (message == RTM_ADD || message == RTM_CHANGE)) -    msg.rtm.rtm_flags |= RTF_GATEWAY; +	if (gate && (message == RTM_ADD || message == RTM_CHANGE)) +		msg.rtm.rtm_flags |= RTF_GATEWAY; -  /* When RTF_CLONING is unavailable on BSD, should we set some -   * other flag instead? -   */ +/* When RTF_CLONING is unavailable on BSD, should we set some + * other flag instead? + */  #ifdef RTF_CLONING -  if (! gate && (message == RTM_ADD || message == RTM_CHANGE) && ifp && -      (ifp->flags & IFF_POINTOPOINT) == 0) -    msg.rtm.rtm_flags |= RTF_CLONING; +	if (!gate && (message == RTM_ADD || message == RTM_CHANGE) && ifp +	    && (ifp->flags & IFF_POINTOPOINT) == 0) +		msg.rtm.rtm_flags |= RTF_CLONING;  #endif /* RTF_CLONING */ -  /* If no protocol specific gateway is specified, use link -     address for gateway. */ -  if (! gate) -    { -      if (!ifp) -        { -          char dest_buf[INET_ADDRSTRLEN] = "NULL", mask_buf[INET_ADDRSTRLEN] = "255.255.255.255"; -          if (dest) -            inet_ntop (AF_INET, &dest->sin.sin_addr, dest_buf, INET_ADDRSTRLEN); -          if (mask) -            inet_ntop (AF_INET, &mask->sin.sin_addr, mask_buf, INET_ADDRSTRLEN); -          zlog_warn ("%s: %s/%s: gate == NULL and no gateway found for ifindex %d", -            __func__, dest_buf, mask_buf, index); -          return -1; -        } -      gate = (union sockunion *) &((struct zebra_if *)ifp->info)->sdl; -    } - -  if (mask) -    msg.rtm.rtm_addrs |= RTA_NETMASK; -  else if (message == RTM_ADD || message == RTM_CHANGE) -    msg.rtm.rtm_flags |= RTF_HOST; +	/* If no protocol specific gateway is specified, use link +	   address for gateway. */ +	if (!gate) { +		if (!ifp) { +			char dest_buf[INET_ADDRSTRLEN] = "NULL", +			     mask_buf[INET_ADDRSTRLEN] = "255.255.255.255"; +			if (dest) +				inet_ntop(AF_INET, &dest->sin.sin_addr, +					  dest_buf, INET_ADDRSTRLEN); +			if (mask) +				inet_ntop(AF_INET, &mask->sin.sin_addr, +					  mask_buf, INET_ADDRSTRLEN); +			zlog_warn( +				"%s: %s/%s: gate == NULL and no gateway found for ifindex %d", +				__func__, dest_buf, mask_buf, index); +			return -1; +		} +		gate = (union sockunion *)&((struct zebra_if *)ifp->info)->sdl; +	} + +	if (mask) +		msg.rtm.rtm_addrs |= RTA_NETMASK; +	else if (message == RTM_ADD || message == RTM_CHANGE) +		msg.rtm.rtm_flags |= RTF_HOST;  #ifdef __OpenBSD__ -  if (mpls) -    { -      msg.rtm.rtm_addrs |= RTA_SRC; -      msg.rtm.rtm_flags |= RTF_MPLS; - -      if (mpls->smpls.smpls_label != htonl (MPLS_IMP_NULL_LABEL << MPLS_LABEL_OFFSET)) -	msg.rtm.rtm_mpls = MPLS_OP_PUSH; -    } +	if (mpls) { +		msg.rtm.rtm_addrs |= RTA_SRC; +		msg.rtm.rtm_flags |= RTF_MPLS; + +		if (mpls->smpls.smpls_label +		    != htonl(MPLS_IMP_NULL_LABEL << MPLS_LABEL_OFFSET)) +			msg.rtm.rtm_mpls = MPLS_OP_PUSH; +	}  #endif -  /* Tagging route with flags */ -  msg.rtm.rtm_flags |= (RTF_PROTO1); +	/* Tagging route with flags */ +	msg.rtm.rtm_flags |= (RTF_PROTO1); -  /* Additional flags. */ -  if (zebra_flags & ZEBRA_FLAG_BLACKHOLE) -    msg.rtm.rtm_flags |= RTF_BLACKHOLE; -  if (zebra_flags & ZEBRA_FLAG_REJECT) -    msg.rtm.rtm_flags |= RTF_REJECT; +	/* Additional flags. */ +	if (zebra_flags & ZEBRA_FLAG_BLACKHOLE) +		msg.rtm.rtm_flags |= RTF_BLACKHOLE; +	if (zebra_flags & ZEBRA_FLAG_REJECT) +		msg.rtm.rtm_flags |= RTF_REJECT; -#define SOCKADDRSET(X,R) \ -  if (msg.rtm.rtm_addrs & (R)) \ -    { \ -      int len = SAROUNDUP (X); \ -      memcpy (pnt, (caddr_t)(X), len); \ -      pnt += len; \ -    } +#define SOCKADDRSET(X, R)                                                      \ +	if (msg.rtm.rtm_addrs & (R)) {                                         \ +		int len = SAROUNDUP(X);                                        \ +		memcpy(pnt, (caddr_t)(X), len);                                \ +		pnt += len;                                                    \ +	} -  pnt = (caddr_t) msg.buf; +	pnt = (caddr_t)msg.buf; -  /* Write each socket data into rtm message buffer */ -  SOCKADDRSET (dest, RTA_DST); -  SOCKADDRSET (gate, RTA_GATEWAY); -  SOCKADDRSET (mask, RTA_NETMASK); +	/* Write each socket data into rtm message buffer */ +	SOCKADDRSET(dest, RTA_DST); +	SOCKADDRSET(gate, RTA_GATEWAY); +	SOCKADDRSET(mask, RTA_NETMASK);  #ifdef __OpenBSD__ -  SOCKADDRSET (mpls, RTA_SRC); +	SOCKADDRSET(mpls, RTA_SRC);  #endif -  msg.rtm.rtm_msglen = pnt - (caddr_t) &msg; - -  ret = write (routing_sock, &msg, msg.rtm.rtm_msglen); - -  if (ret != msg.rtm.rtm_msglen)  -    { -      if (errno == EEXIST)  -	return ZEBRA_ERR_RTEXIST; -      if (errno == ENETUNREACH) -	return ZEBRA_ERR_RTUNREACH; -      if (errno == ESRCH) -	return ZEBRA_ERR_RTNOEXIST; -       -      zlog_warn ("%s: write : %s (%d)", __func__, safe_strerror (errno), errno); -      return ZEBRA_ERR_KERNEL; -    } -  return ZEBRA_ERR_NOERROR; +	msg.rtm.rtm_msglen = pnt - (caddr_t)&msg; + +	ret = write(routing_sock, &msg, msg.rtm.rtm_msglen); + +	if (ret != msg.rtm.rtm_msglen) { +		if (errno == EEXIST) +			return ZEBRA_ERR_RTEXIST; +		if (errno == ENETUNREACH) +			return ZEBRA_ERR_RTUNREACH; +		if (errno == ESRCH) +			return ZEBRA_ERR_RTNOEXIST; + +		zlog_warn("%s: write : %s (%d)", __func__, safe_strerror(errno), +			  errno); +		return ZEBRA_ERR_KERNEL; +	} +	return ZEBRA_ERR_NOERROR;  } @@ -1201,14 +1218,14 @@ rtm_write (int message,  #include "zebra/zserv.h"  /* For debug purpose. */ -static void -rtmsg_debug (struct rt_msghdr *rtm) +static void rtmsg_debug(struct rt_msghdr *rtm)  { -  zlog_debug ("Kernel: Len: %d Type: %s", rtm->rtm_msglen, lookup_msg(rtm_type_str, rtm->rtm_type, NULL)); -  rtm_flag_dump (rtm->rtm_flags); -  zlog_debug ("Kernel: message seq %d", rtm->rtm_seq); -  zlog_debug ("Kernel: pid %lld, rtm_addrs 0x%x", -              (long long)rtm->rtm_pid, rtm->rtm_addrs); +	zlog_debug("Kernel: Len: %d Type: %s", rtm->rtm_msglen, +		   lookup_msg(rtm_type_str, rtm->rtm_type, NULL)); +	rtm_flag_dump(rtm->rtm_flags); +	zlog_debug("Kernel: message seq %d", rtm->rtm_seq); +	zlog_debug("Kernel: pid %lld, rtm_addrs 0x%x", (long long)rtm->rtm_pid, +		   rtm->rtm_addrs);  }  /* This is pretty gross, better suggestions welcome -- mhandler */ @@ -1221,154 +1238,143 @@ rtmsg_debug (struct rt_msghdr *rtm)  #endif /* RTAX_MAX */  /* Kernel routing table and interface updates via routing socket. */ -static int -kernel_read (struct thread *thread) +static int kernel_read(struct thread *thread)  { -  int sock; -  int nbytes; -  struct rt_msghdr *rtm; - -  /* -   * This must be big enough for any message the kernel might send. -   * Rather than determining how many sockaddrs of what size might be -   * in each particular message, just use RTAX_MAX of sockaddr_storage -   * for each.  Note that the sockaddrs must be after each message -   * definition, or rather after whichever happens to be the largest, -   * since the buffer needs to be big enough for a message and the -   * sockaddrs together. -   */ -  union  -  { -    /* Routing information. */ -    struct  -    { -      struct rt_msghdr rtm; -      struct sockaddr_storage addr[RTAX_MAX]; -    } r; - -    /* Interface information. */ -    struct -    { -      struct if_msghdr ifm; -      struct sockaddr_storage addr[RTAX_MAX]; -    } im; - -    /* Interface address information. */ -    struct -    { -      struct ifa_msghdr ifa; -      struct sockaddr_storage addr[RTAX_MAX]; -    } ia; +	int sock; +	int nbytes; +	struct rt_msghdr *rtm; + +	/* +	 * This must be big enough for any message the kernel might send. +	 * Rather than determining how many sockaddrs of what size might be +	 * in each particular message, just use RTAX_MAX of sockaddr_storage +	 * for each.  Note that the sockaddrs must be after each message +	 * definition, or rather after whichever happens to be the largest, +	 * since the buffer needs to be big enough for a message and the +	 * sockaddrs together. +	 */ +	union { +		/* Routing information. */ +		struct { +			struct rt_msghdr rtm; +			struct sockaddr_storage addr[RTAX_MAX]; +		} r; + +		/* Interface information. */ +		struct { +			struct if_msghdr ifm; +			struct sockaddr_storage addr[RTAX_MAX]; +		} im; + +		/* Interface address information. */ +		struct { +			struct ifa_msghdr ifa; +			struct sockaddr_storage addr[RTAX_MAX]; +		} ia;  #ifdef RTM_IFANNOUNCE -    /* Interface arrival/departure */ -    struct -    { -      struct if_announcemsghdr ifan; -      struct sockaddr_storage addr[RTAX_MAX]; -    } ian; +		/* Interface arrival/departure */ +		struct { +			struct if_announcemsghdr ifan; +			struct sockaddr_storage addr[RTAX_MAX]; +		} ian;  #endif /* RTM_IFANNOUNCE */ -  } buf; +	} buf; -  /* Fetch routing socket. */ -  sock = THREAD_FD (thread); +	/* Fetch routing socket. */ +	sock = THREAD_FD(thread); -  nbytes= read (sock, &buf, sizeof buf); +	nbytes = read(sock, &buf, sizeof buf); -  if (nbytes <= 0) -    { -      if (nbytes < 0 && errno != EWOULDBLOCK && errno != EAGAIN) -	zlog_warn ("routing socket error: %s", safe_strerror (errno)); -      return 0; -    } +	if (nbytes <= 0) { +		if (nbytes < 0 && errno != EWOULDBLOCK && errno != EAGAIN) +			zlog_warn("routing socket error: %s", +				  safe_strerror(errno)); +		return 0; +	} -  thread_add_read (zebrad.master, kernel_read, NULL, sock); +	thread_add_read(zebrad.master, kernel_read, NULL, sock); -  if (IS_ZEBRA_DEBUG_KERNEL) -    rtmsg_debug (&buf.r.rtm); +	if (IS_ZEBRA_DEBUG_KERNEL) +		rtmsg_debug(&buf.r.rtm); -  rtm = &buf.r.rtm; +	rtm = &buf.r.rtm; -  /* -   * Ensure that we didn't drop any data, so that processing routines -   * can assume they have the whole message. -   */ -  if (rtm->rtm_msglen != nbytes) -    { -      zlog_warn ("kernel_read: rtm->rtm_msglen %d, nbytes %d, type %d\n", -		 rtm->rtm_msglen, nbytes, rtm->rtm_type); -      return -1; -    } - -  switch (rtm->rtm_type) -    { -    case RTM_ADD: -    case RTM_DELETE: -    case RTM_CHANGE: -      rtm_read (rtm); -      break; -    case RTM_IFINFO: -      ifm_read (&buf.im.ifm); -      break; -    case RTM_NEWADDR: -    case RTM_DELADDR: -      ifam_read (&buf.ia.ifa); -      break; +	/* +	 * Ensure that we didn't drop any data, so that processing routines +	 * can assume they have the whole message. +	 */ +	if (rtm->rtm_msglen != nbytes) { +		zlog_warn( +			"kernel_read: rtm->rtm_msglen %d, nbytes %d, type %d\n", +			rtm->rtm_msglen, nbytes, rtm->rtm_type); +		return -1; +	} + +	switch (rtm->rtm_type) { +	case RTM_ADD: +	case RTM_DELETE: +	case RTM_CHANGE: +		rtm_read(rtm); +		break; +	case RTM_IFINFO: +		ifm_read(&buf.im.ifm); +		break; +	case RTM_NEWADDR: +	case RTM_DELADDR: +		ifam_read(&buf.ia.ifa); +		break;  #ifdef RTM_IFANNOUNCE -    case RTM_IFANNOUNCE: -      ifan_read (&buf.ian.ifan); -      break; +	case RTM_IFANNOUNCE: +		ifan_read(&buf.ian.ifan); +		break;  #endif /* RTM_IFANNOUNCE */ -    default: -      if (IS_ZEBRA_DEBUG_KERNEL) -        zlog_debug("Unprocessed RTM_type: %d", rtm->rtm_type); -      break; -    } -  return 0; +	default: +		if (IS_ZEBRA_DEBUG_KERNEL) +			zlog_debug("Unprocessed RTM_type: %d", rtm->rtm_type); +		break; +	} +	return 0;  }  /* Make routing socket. */ -static void -routing_socket (struct zebra_ns *zns) +static void routing_socket(struct zebra_ns *zns)  { -  if ( zserv_privs.change (ZPRIVS_RAISE) ) -    zlog_err ("routing_socket: Can't raise privileges"); - -  routing_sock = socket (AF_ROUTE, SOCK_RAW, 0); - -  if (routing_sock < 0)  -    { -      if ( zserv_privs.change (ZPRIVS_LOWER) ) -        zlog_err ("routing_socket: Can't lower privileges"); -      zlog_warn ("Can't init kernel routing socket"); -      return; -    } - -  /* XXX: Socket should be NONBLOCK, however as we currently  -   * discard failed writes, this will lead to inconsistencies. -   * For now, socket must be blocking. -   */ -  /*if (fcntl (routing_sock, F_SETFL, O_NONBLOCK) < 0)  -    zlog_warn ("Can't set O_NONBLOCK to routing socket");*/ -     -  if ( zserv_privs.change (ZPRIVS_LOWER) ) -    zlog_err ("routing_socket: Can't lower privileges"); - -  /* kernel_read needs rewrite. */ -  thread_add_read (zebrad.master, kernel_read, NULL, routing_sock); +	if (zserv_privs.change(ZPRIVS_RAISE)) +		zlog_err("routing_socket: Can't raise privileges"); + +	routing_sock = socket(AF_ROUTE, SOCK_RAW, 0); + +	if (routing_sock < 0) { +		if (zserv_privs.change(ZPRIVS_LOWER)) +			zlog_err("routing_socket: Can't lower privileges"); +		zlog_warn("Can't init kernel routing socket"); +		return; +	} + +	/* XXX: Socket should be NONBLOCK, however as we currently +	 * discard failed writes, this will lead to inconsistencies. +	 * For now, socket must be blocking. +	 */ +	/*if (fcntl (routing_sock, F_SETFL, O_NONBLOCK) < 0) +	  zlog_warn ("Can't set O_NONBLOCK to routing socket");*/ + +	if (zserv_privs.change(ZPRIVS_LOWER)) +		zlog_err("routing_socket: Can't lower privileges"); + +	/* kernel_read needs rewrite. */ +	thread_add_read(zebrad.master, kernel_read, NULL, routing_sock);  }  /* Exported interface function.  This function simply calls     routing_socket (). */ -void -kernel_init (struct zebra_ns *zns) +void kernel_init(struct zebra_ns *zns)  { -  routing_socket (zns); +	routing_socket(zns);  } -void -kernel_terminate (struct zebra_ns *zns) +void kernel_terminate(struct zebra_ns *zns)  { -  return; +	return;  } diff --git a/zebra/kernel_socket.h b/zebra/kernel_socket.h index 04e3054312..4d6d54a63a 100644 --- a/zebra/kernel_socket.h +++ b/zebra/kernel_socket.h @@ -17,7 +17,7 @@   * You should have received a copy of the GNU General Public License   * along with Quagga; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #ifndef __ZEBRA_KERNEL_SOCKET_H @@ -31,12 +31,12 @@  #define ZEBRA_ERR_RTNOEXIST             -4  #define ZEBRA_ERR_KERNEL                -5 -extern void rtm_read (struct rt_msghdr *); -extern int ifam_read (struct ifa_msghdr *); -extern int ifm_read (struct if_msghdr *); -extern int rtm_write (int, union sockunion *, union sockunion *, -                      union sockunion *, union sockunion *, -                      unsigned int, int, int); +extern void rtm_read(struct rt_msghdr *); +extern int ifam_read(struct ifa_msghdr *); +extern int ifm_read(struct if_msghdr *); +extern int rtm_write(int, union sockunion *, union sockunion *, +		     union sockunion *, union sockunion *, unsigned int, int, +		     int);  extern const struct message rtm_type_str[];  #endif /* __ZEBRA_KERNEL_SOCKET_H */ diff --git a/zebra/label_manager.c b/zebra/label_manager.c index 08f3c3cfe9..ac1967a902 100644 --- a/zebra/label_manager.c +++ b/zebra/label_manager.c @@ -72,14 +72,14 @@ static int relay_response_back(struct zserv *zserv)  	stream_reset(src);  	ret = zclient_read_header(src, zclient->sock, &size, &marker, &version, -							  &vrf_id, &resp_cmd); +				  &vrf_id, &resp_cmd);  	if (ret < 0 && errno != EAGAIN) { -		zlog_err("%s: Error reading Label Manager response: %s", __func__, -				 strerror(errno)); +		zlog_err("%s: Error reading Label Manager response: %s", +			 __func__, strerror(errno));  		return -1;  	}  	zlog_debug("%s: Label Manager response received, %d bytes", __func__, -			   size); +		   size);  	if (size == 0)  		return -1; @@ -88,11 +88,11 @@ static int relay_response_back(struct zserv *zserv)  	ret = writen(zserv->sock, dst->data, stream_get_endp(dst));  	if (ret <= 0) {  		zlog_err("%s: Error sending Label Manager response back: %s", -				 __func__, strerror(errno)); +			 __func__, strerror(errno));  		return -1;  	}  	zlog_debug("%s: Label Manager response (%d bytes) sent back", __func__, -			   ret); +		   ret);  	return 0;  } @@ -112,23 +112,22 @@ static int lm_zclient_read(struct thread *t)  	return ret;  } -static int reply_error (int cmd, struct zserv *zserv, vrf_id_t vrf_id) +static int reply_error(int cmd, struct zserv *zserv, vrf_id_t vrf_id)  {  	struct stream *s;  	s = zserv->obuf; -	stream_reset (s); +	stream_reset(s); -	zserv_create_header (s, cmd, vrf_id); +	zserv_create_header(s, cmd, vrf_id);  	/* result */ -	stream_putc (s, 1); +	stream_putc(s, 1);  	/* Write packet size. */ -	stream_putw_at (s, 0, stream_get_endp (s)); - -	return writen (zserv->sock, s->data, stream_get_endp (s)); +	stream_putw_at(s, 0, stream_get_endp(s)); +	return writen(zserv->sock, s->data, stream_get_endp(s));  }  /**   * Receive a request to get or release a label chunk and forward it to external @@ -141,15 +140,17 @@ static int reply_error (int cmd, struct zserv *zserv, vrf_id_t vrf_id)   * @param zserv   * @return 0 on success, -1 otherwise   */ -int zread_relay_label_manager_request(int cmd, struct zserv *zserv, vrf_id_t vrf_id) +int zread_relay_label_manager_request(int cmd, struct zserv *zserv, +				      vrf_id_t vrf_id)  {  	struct stream *src, *dst;  	int ret = 0;  	if (zclient->sock < 0) { -		zlog_err("%s: Error relaying label chunk request: no zclient socket", -				 __func__); -		reply_error (cmd, zserv, vrf_id); +		zlog_err( +			"%s: Error relaying label chunk request: no zclient socket", +			__func__); +		reply_error(cmd, zserv, vrf_id);  		return -1;  	} @@ -167,7 +168,7 @@ int zread_relay_label_manager_request(int cmd, struct zserv *zserv, vrf_id_t vrf  	if (ret <= 0) {  		zlog_err("%s: Error relaying label chunk request: %s", __func__,  			 strerror(errno)); -		reply_error (cmd, zserv, vrf_id); +		reply_error(cmd, zserv, vrf_id);  		return -1;  	}  	zlog_debug("%s: Label chunk request relayed. %d bytes sent", __func__, @@ -179,8 +180,8 @@ int zread_relay_label_manager_request(int cmd, struct zserv *zserv, vrf_id_t vrf  	/* make sure we listen to the response */  	if (!zclient->t_read) -		zclient->t_read = -			thread_add_read(zclient->master, lm_zclient_read, zserv, zclient->sock); +		zclient->t_read = thread_add_read( +			zclient->master, lm_zclient_read, zserv, zclient->sock);  	return 0;  } @@ -195,14 +196,14 @@ static int lm_zclient_connect(struct thread *t)  	if (zclient_socket_connect(zclient) < 0) {  		zlog_err("Error connecting synchronous zclient!");  		THREAD_TIMER_ON(zebrad.master, zclient->t_connect, -						lm_zclient_connect, -						zclient, CONNECTION_DELAY); +				lm_zclient_connect, zclient, CONNECTION_DELAY);  		return -1;  	}  	/* make socket non-blocking */  	if (set_nonblocking(zclient->sock) < 0) -		zlog_warn("%s: set_nonblocking(%d) failed", __func__, zclient->sock); +		zlog_warn("%s: set_nonblocking(%d) failed", __func__, +			  zclient->sock);  	return 0;  } @@ -236,7 +237,7 @@ void label_manager_init(char *lm_zserv_path)  		lm_is_external = false;  		lbl_mgr.lc_list = list_new();  		lbl_mgr.lc_list->del = delete_label_chunk; -	} else {		/* it's acting just as a proxy */ +	} else { /* it's acting just as a proxy */  		zlog_debug("Initializing external label manager at %s",  			   lm_zserv_path);  		lm_is_external = true; @@ -264,7 +265,8 @@ struct label_manager_chunk *assign_label_chunk(u_char proto, u_short instance,  	/* first check if there's one available */  	for (ALL_LIST_ELEMENTS_RO(lbl_mgr.lc_list, node, lmc)) { -		if (lmc->proto == NO_PROTO && lmc->end - lmc->start + 1 == size) { +		if (lmc->proto == NO_PROTO +		    && lmc->end - lmc->start + 1 == size) {  			lmc->proto = proto;  			lmc->instance = instance;  			lmc->keep = keep; @@ -279,12 +281,14 @@ struct label_manager_chunk *assign_label_chunk(u_char proto, u_short instance,  	if (list_isempty(lbl_mgr.lc_list))  		lmc->start = MPLS_MIN_UNRESERVED_LABEL;  	else -		lmc->start = ((struct label_manager_chunk *) -			      listgetdata(listtail(lbl_mgr.lc_list)))->end + 1; +		lmc->start = ((struct label_manager_chunk *)listgetdata( +				      listtail(lbl_mgr.lc_list))) +				     ->end +			     + 1;  	if (lmc->start > MPLS_MAX_UNRESERVED_LABEL - size + 1) {  		zlog_err("Reached max labels. Start: %u, size: %u", lmc->start,  			 size); -                XFREE(MTYPE_LM_CHUNK, lmc); +		XFREE(MTYPE_LM_CHUNK, lmc);  		return NULL;  	}  	lmc->end = lmc->start + size - 1; @@ -305,9 +309,8 @@ struct label_manager_chunk *assign_label_chunk(u_char proto, u_short instance,   * @param end Last label of the chunk   * @return 0 on success, -1 otherwise   */ -int -release_label_chunk(u_char proto, u_short instance, uint32_t start, -		    uint32_t end) +int release_label_chunk(u_char proto, u_short instance, uint32_t start, +			uint32_t end)  {  	struct listnode *node;  	struct label_manager_chunk *lmc; @@ -357,9 +360,8 @@ int release_daemon_chunks(u_char proto, u_short instance)  	for (ALL_LIST_ELEMENTS_RO(lbl_mgr.lc_list, node, lmc)) {  		if (lmc->proto == proto && lmc->instance == instance  		    && lmc->keep == 0) { -			ret = -			    release_label_chunk(lmc->proto, lmc->instance, -						lmc->start, lmc->end); +			ret = release_label_chunk(lmc->proto, lmc->instance, +						  lmc->start, lmc->end);  			if (ret == 0)  				count++;  		} diff --git a/zebra/label_manager.h b/zebra/label_manager.h index fd0b3b549b..295575cd8c 100644 --- a/zebra/label_manager.h +++ b/zebra/label_manager.h @@ -48,8 +48,8 @@ struct label_manager_chunk {  	u_char proto;  	u_short instance;  	u_char keep; -	uint32_t start;		/* First label of the chunk */ -	uint32_t end;		/* Last label of the chunk */ +	uint32_t start; /* First label of the chunk */ +	uint32_t end;   /* Last label of the chunk */  };  /* @@ -62,7 +62,8 @@ struct label_manager {  bool lm_is_external; -int zread_relay_label_manager_request(int cmd, struct zserv *zserv, vrf_id_t vrf_id); +int zread_relay_label_manager_request(int cmd, struct zserv *zserv, +				      vrf_id_t vrf_id);  void label_manager_init(char *lm_zserv_path);  struct label_manager_chunk *assign_label_chunk(u_char proto, u_short instance,  					       u_char keep, uint32_t size); @@ -71,4 +72,4 @@ int release_label_chunk(u_char proto, u_short instance, uint32_t start,  int release_daemon_chunks(u_char proto, u_short instance);  void label_manager_close(void); -#endif				/* _LABEL_MANAGER_H */ +#endif /* _LABEL_MANAGER_H */ diff --git a/zebra/main.c b/zebra/main.c index 84d71c33b9..792eb20f6a 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -52,9 +52,8 @@  #define ZEBRA_PTM_SUPPORT  /* Zebra instance */ -struct zebra_t zebrad = -{ -  .rtm_table_default = 0, +struct zebra_t zebrad = { +	.rtm_table_default = 0,  };  /* process id. */ @@ -78,284 +77,272 @@ u_int32_t nl_rcvbufsize = 4194304;  #endif /* HAVE_NETLINK */  /* Command line options. */ -struct option longopts[] = -{ -  { "batch",        no_argument,       NULL, 'b'}, -  { "allow_delete", no_argument,       NULL, 'a'}, -  { "keep_kernel",  no_argument,       NULL, 'k'}, -  { "socket",       required_argument, NULL, 'z'}, -  { "ecmp",         required_argument, NULL, 'e'}, -  { "label_socket", no_argument,       NULL, 'l'}, -  { "retain",       no_argument,       NULL, 'r'}, +struct option longopts[] = {{"batch", no_argument, NULL, 'b'}, +			    {"allow_delete", no_argument, NULL, 'a'}, +			    {"keep_kernel", no_argument, NULL, 'k'}, +			    {"socket", required_argument, NULL, 'z'}, +			    {"ecmp", required_argument, NULL, 'e'}, +			    {"label_socket", no_argument, NULL, 'l'}, +			    {"retain", no_argument, NULL, 'r'},  #ifdef HAVE_NETLINK -  { "nl-bufsize",   required_argument, NULL, 's'}, +			    {"nl-bufsize", required_argument, NULL, 's'},  #endif /* HAVE_NETLINK */ -  { 0 } -}; +			    {0}}; -zebra_capabilities_t _caps_p [] = -{ -  ZCAP_NET_ADMIN, -  ZCAP_SYS_ADMIN, -  ZCAP_NET_RAW, +zebra_capabilities_t _caps_p[] = { +	ZCAP_NET_ADMIN, ZCAP_SYS_ADMIN, ZCAP_NET_RAW,  };  /* zebra privileges to run with */ -struct zebra_privs_t zserv_privs = -{ +struct zebra_privs_t zserv_privs = {  #if defined(FRR_USER) && defined(FRR_GROUP) -  .user = FRR_USER, -  .group = FRR_GROUP, +	.user = FRR_USER, +	.group = FRR_GROUP,  #endif  #ifdef VTY_GROUP -  .vty_group = VTY_GROUP, +	.vty_group = VTY_GROUP,  #endif -  .caps_p = _caps_p, -  .cap_num_p = array_size(_caps_p), -  .cap_num_i = 0 -}; +	.caps_p = _caps_p, +	.cap_num_p = array_size(_caps_p), +	.cap_num_i = 0};  unsigned int multipath_num = MULTIPATH_NUM;  /* SIGHUP handler. */ -static void -sighup (void) +static void sighup(void)  { -  zlog_info ("SIGHUP received"); +	zlog_info("SIGHUP received"); -  /* Reload of config file. */ -  ; +	/* Reload of config file. */ +	;  }  /* SIGINT handler. */ -static void -sigint (void) +static void sigint(void)  { -  struct vrf *vrf; -  struct zebra_vrf *zvrf; -  struct zebra_ns *zns; +	struct vrf *vrf; +	struct zebra_vrf *zvrf; +	struct zebra_ns *zns; -  zlog_notice ("Terminating on signal"); +	zlog_notice("Terminating on signal");  #ifdef HAVE_IRDP -  irdp_finish(); +	irdp_finish();  #endif -  zebra_ptm_finish(); -  list_delete_all_node (zebrad.client_list); - -  if (retain_mode) -    RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) -      { -	zvrf = vrf->info; -	if (zvrf) -	  SET_FLAG (zvrf->flags, ZEBRA_VRF_RETAIN); -      } -  vrf_terminate (); - -  zns = zebra_ns_lookup (NS_DEFAULT); -  zebra_ns_disable (0, (void **)&zns); - -  access_list_reset (); -  prefix_list_reset (); -  route_map_finish (); -  cmd_terminate (); -  vty_terminate (); -  zprivs_terminate (&zserv_privs); -  list_delete (zebrad.client_list); -  work_queue_free (zebrad.ribq); -  if (zebrad.lsp_process_q) -    work_queue_free (zebrad.lsp_process_q); -  meta_queue_free (zebrad.mq); -  thread_master_free (zebrad.master); -  closezlog (); - -  exit (0); +	zebra_ptm_finish(); +	list_delete_all_node(zebrad.client_list); + +	if (retain_mode) +		RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) +		{ +			zvrf = vrf->info; +			if (zvrf) +				SET_FLAG(zvrf->flags, ZEBRA_VRF_RETAIN); +		} +	vrf_terminate(); + +	zns = zebra_ns_lookup(NS_DEFAULT); +	zebra_ns_disable(0, (void **)&zns); + +	access_list_reset(); +	prefix_list_reset(); +	route_map_finish(); +	cmd_terminate(); +	vty_terminate(); +	zprivs_terminate(&zserv_privs); +	list_delete(zebrad.client_list); +	work_queue_free(zebrad.ribq); +	if (zebrad.lsp_process_q) +		work_queue_free(zebrad.lsp_process_q); +	meta_queue_free(zebrad.mq); +	thread_master_free(zebrad.master); +	closezlog(); + +	exit(0);  }  /* SIGUSR1 handler. */ -static void -sigusr1 (void) +static void sigusr1(void)  { -  zlog_rotate(); +	zlog_rotate();  } -struct quagga_signal_t zebra_signals[] = -{ -  { -    .signal = SIGHUP, -    .handler = &sighup, -  }, -  { -    .signal = SIGUSR1, -    .handler = &sigusr1, -  }, -  { -    .signal = SIGINT, -    .handler = &sigint, -  }, -  { -    .signal = SIGTERM, -    .handler = &sigint, -  }, +struct quagga_signal_t zebra_signals[] = { +	{ +		.signal = SIGHUP, +		.handler = &sighup, +	}, +	{ +		.signal = SIGUSR1, +		.handler = &sigusr1, +	}, +	{ +		.signal = SIGINT, +		.handler = &sigint, +	}, +	{ +		.signal = SIGTERM, +		.handler = &sigint, +	},  }; -FRR_DAEMON_INFO(zebra, ZEBRA, -	.vty_port = ZEBRA_VTY_PORT, -	.flags = FRR_NO_ZCLIENT, +FRR_DAEMON_INFO( +	zebra, ZEBRA, .vty_port = ZEBRA_VTY_PORT, .flags = FRR_NO_ZCLIENT, -	.proghelp = "Daemon which manages kernel routing table management " +	.proghelp = +		"Daemon which manages kernel routing table management "  		"and\nredistribution between different routing protocols.", -	.signals = zebra_signals, -	.n_signals = array_size(zebra_signals), +	.signals = zebra_signals, .n_signals = array_size(zebra_signals), -	.privs = &zserv_privs, -) +	.privs = &zserv_privs, )  /* Main startup routine. */ -int -main (int argc, char **argv) +int main(int argc, char **argv)  { -  // int batch_mode = 0; -  char *zserv_path = NULL; -  /* Socket to external label manager */ -  char *lblmgr_path = NULL; +	// int batch_mode = 0; +	char *zserv_path = NULL; +	/* Socket to external label manager */ +	char *lblmgr_path = NULL; -  frr_preinit(&zebra_di, argc, argv); +	frr_preinit(&zebra_di, argc, argv); -  frr_opt_add("bakz:e:l:r" +	frr_opt_add( +		"bakz:e:l:r"  #ifdef HAVE_NETLINK -	"s:" +		"s:"  #endif -	, longopts, -	"  -b, --batch        Runs in batch mode\n" -	"  -a, --allow_delete Allow other processes to delete zebra routes\n" -	"  -z, --socket       Set path of zebra socket\n" -	"  -e, --ecmp         Specify ECMP to use.\n" -	"  -l, --label_socket Socket to external label manager\n"\ -	"  -k, --keep_kernel  Don't delete old routes which installed by zebra.\n" -	"  -r, --retain       When program terminates, retain added route by zebra.\n" +		, +		longopts, +		"  -b, --batch        Runs in batch mode\n" +		"  -a, --allow_delete Allow other processes to delete zebra routes\n" +		"  -z, --socket       Set path of zebra socket\n" +		"  -e, --ecmp         Specify ECMP to use.\n" +		"  -l, --label_socket Socket to external label manager\n" +		"  -k, --keep_kernel  Don't delete old routes which installed by zebra.\n" +		"  -r, --retain       When program terminates, retain added route by zebra.\n"  #ifdef HAVE_NETLINK -	"  -s, --nl-bufsize   Set netlink receive buffer size\n" +		"  -s, --nl-bufsize   Set netlink receive buffer size\n"  #endif /* HAVE_NETLINK */ -	); - -  while (1) -    { -      int opt = frr_getopt(argc, argv, NULL); - -      if (opt == EOF) -	break; - -      switch (opt) -	{ -	case 0: -	  break; -	case 'b': -	  // batch_mode = 1; -	  break; -	case 'a': -	  allow_delete = 1; -	  break; -	case 'k': -	  keep_kernel_mode = 1; -	  break; -        case 'e': -          multipath_num = atoi (optarg); -          if (multipath_num > MULTIPATH_NUM || multipath_num <= 0) -            { -              zlog_err ("Multipath Number specified must be less than %d and greater than 0", MULTIPATH_NUM); -              return 1; -            } -          break; -	case 'z': -	  zserv_path = optarg; -	  break; -	case 'l': -	  lblmgr_path = optarg; -	  break; -	case 'r': -	  retain_mode = 1; -	  break; +		); + +	while (1) { +		int opt = frr_getopt(argc, argv, NULL); + +		if (opt == EOF) +			break; + +		switch (opt) { +		case 0: +			break; +		case 'b': +			// batch_mode = 1; +			break; +		case 'a': +			allow_delete = 1; +			break; +		case 'k': +			keep_kernel_mode = 1; +			break; +		case 'e': +			multipath_num = atoi(optarg); +			if (multipath_num > MULTIPATH_NUM +			    || multipath_num <= 0) { +				zlog_err( +					"Multipath Number specified must be less than %d and greater than 0", +					MULTIPATH_NUM); +				return 1; +			} +			break; +		case 'z': +			zserv_path = optarg; +			break; +		case 'l': +			lblmgr_path = optarg; +			break; +		case 'r': +			retain_mode = 1; +			break;  #ifdef HAVE_NETLINK -	case 's': -	  nl_rcvbufsize = atoi (optarg); -	  break; +		case 's': +			nl_rcvbufsize = atoi(optarg); +			break;  #endif /* HAVE_NETLINK */ -	default: -	  frr_help_exit (1); -	  break; +		default: +			frr_help_exit(1); +			break; +		}  	} -    } - -  vty_config_lockless (); -  zebrad.master = frr_init(); - -  /* Zebra related initialize. */ -  zebra_init (); -  rib_init (); -  zebra_if_init (); -  zebra_debug_init (); -  router_id_cmd_init (); -  zebra_vty_init (); -  access_list_init (); -  prefix_list_init (); -#if defined (HAVE_RTADV) -  rtadv_cmd_init (); + +	vty_config_lockless(); +	zebrad.master = frr_init(); + +	/* Zebra related initialize. */ +	zebra_init(); +	rib_init(); +	zebra_if_init(); +	zebra_debug_init(); +	router_id_cmd_init(); +	zebra_vty_init(); +	access_list_init(); +	prefix_list_init(); +#if defined(HAVE_RTADV) +	rtadv_cmd_init();  #endif  #ifdef HAVE_IRDP -  irdp_init(); +	irdp_init();  #endif -  /* PTM socket */ +/* PTM socket */  #ifdef ZEBRA_PTM_SUPPORT -  zebra_ptm_init(); +	zebra_ptm_init();  #endif -  zebra_mpls_init (); -  zebra_mpls_vty_init (); -  zebra_pw_vty_init (); - -  /* For debug purpose. */ -  /* SET_FLAG (zebra_debug_event, ZEBRA_DEBUG_EVENT); */ - -  /* Initialize NS( and implicitly the VRF module), and make kernel routing socket. */ -  zebra_ns_init (); - -  /* Process the configuration file. Among other configuration -  *  directives we can meet those installing static routes. Such -  *  requests will not be executed immediately, but queued in -  *  zebra->ribq structure until we enter the main execution loop. -  *  The notifications from kernel will show originating PID equal -  *  to that after daemon() completes (if ever called). -  */ -  frr_config_fork(); - -  /* Clean up rib -- before fork (?) */ -  /* rib_weed_tables (); */ - -  /* After we have successfully acquired the pidfile, we can be sure -  *  about being the only copy of zebra process, which is submitting -  *  changes to the FIB. -  *  Clean up zebra-originated routes. The requests will be sent to OS -  *  immediately, so originating PID in notifications from kernel -  *  will be equal to the current getpid(). To know about such routes, -  * we have to have route_read() called before. -  */ -  if (! keep_kernel_mode) -    rib_sweep_route (); - -  /* Needed for BSD routing socket. */ -  pid = getpid (); - -  /* This must be done only after locking pidfile (bug #403). */ -  zebra_zserv_socket_init (zserv_path); - -  /* Init label manager */ -  label_manager_init (lblmgr_path); - -  frr_run (zebrad.master); - -  /* Not reached... */ -  return 0; +	zebra_mpls_init(); +	zebra_mpls_vty_init(); +	zebra_pw_vty_init(); + +	/* For debug purpose. */ +	/* SET_FLAG (zebra_debug_event, ZEBRA_DEBUG_EVENT); */ + +	/* Initialize NS( and implicitly the VRF module), and make kernel +	 * routing socket. */ +	zebra_ns_init(); + +	/* Process the configuration file. Among other configuration +	*  directives we can meet those installing static routes. Such +	*  requests will not be executed immediately, but queued in +	*  zebra->ribq structure until we enter the main execution loop. +	*  The notifications from kernel will show originating PID equal +	*  to that after daemon() completes (if ever called). +	*/ +	frr_config_fork(); + +	/* Clean up rib -- before fork (?) */ +	/* rib_weed_tables (); */ + +	/* After we have successfully acquired the pidfile, we can be sure +	*  about being the only copy of zebra process, which is submitting +	*  changes to the FIB. +	*  Clean up zebra-originated routes. The requests will be sent to OS +	*  immediately, so originating PID in notifications from kernel +	*  will be equal to the current getpid(). To know about such routes, +	* we have to have route_read() called before. +	*/ +	if (!keep_kernel_mode) +		rib_sweep_route(); + +	/* Needed for BSD routing socket. */ +	pid = getpid(); + +	/* This must be done only after locking pidfile (bug #403). */ +	zebra_zserv_socket_init(zserv_path); + +	/* Init label manager */ +	label_manager_init(lblmgr_path); + +	frr_run(zebrad.master); + +	/* Not reached... */ +	return 0;  } diff --git a/zebra/misc_null.c b/zebra/misc_null.c index 49cb92bd7d..50a4114111 100644 --- a/zebra/misc_null.c +++ b/zebra/misc_null.c @@ -1,4 +1,4 @@ -/*  +/*   * Copyright (C) 2006 Sun Microsystems, Inc.   *   * This file is part of Quagga. @@ -16,7 +16,7 @@   * You should have received a copy of the GNU General Public License   * along with Quagga; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #include <zebra.h> @@ -26,11 +26,23 @@  #include "zebra/irdp.h"  #include "zebra/interface.h" -void rtadv_config_write (struct vty *vty, struct interface *ifp) { return; } -void irdp_config_write (struct vty *vty, struct interface *ifp) { return; } +void rtadv_config_write(struct vty *vty, struct interface *ifp) +{ +	return; +} +void irdp_config_write(struct vty *vty, struct interface *ifp) +{ +	return; +}  #ifdef HAVE_PROC_NET_DEV -void ifstat_update_proc (void) { return; } +void ifstat_update_proc(void) +{ +	return; +}  #endif  #ifdef HAVE_NET_RT_IFLIST -void ifstat_update_sysctl (void) { return; } +void ifstat_update_sysctl(void) +{ +	return; +}  #endif diff --git a/zebra/redistribute.c b/zebra/redistribute.c index e1ec22463a..b614bc5e7e 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -16,7 +16,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #include <zebra.h> @@ -50,709 +50,701 @@  static int zebra_import_table_used[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX];  static u_int32_t zebra_import_table_distance[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; -int -is_zebra_import_table_enabled(afi_t afi, u_int32_t table_id) +int is_zebra_import_table_enabled(afi_t afi, u_int32_t table_id)  { -  if (is_zebra_valid_kernel_table(table_id)) -    return zebra_import_table_used[afi][table_id]; -  return 0; +	if (is_zebra_valid_kernel_table(table_id)) +		return zebra_import_table_used[afi][table_id]; +	return 0;  } -int -is_default (struct prefix *p) +int is_default(struct prefix *p)  { -  if (p->family == AF_INET) -    if (p->u.prefix4.s_addr == 0 && p->prefixlen == 0) -      return 1; -#if 0  /* IPv6 default separation is now pending until protocol daemon -          can handle that. */ +	if (p->family == AF_INET) +		if (p->u.prefix4.s_addr == 0 && p->prefixlen == 0) +			return 1; +#if 0  /* IPv6 default separation is now pending until protocol daemon         \ +	  can handle that. */    if (p->family == AF_INET6)      if (IN6_IS_ADDR_UNSPECIFIED (&p->u.prefix6) && p->prefixlen == 0)        return 1;  #endif /* 0 */ -  return 0; +	return 0;  } -static void -zebra_redistribute_default (struct zserv *client, vrf_id_t vrf_id) +static void zebra_redistribute_default(struct zserv *client, vrf_id_t vrf_id)  { -  int afi; -  struct prefix p; -  struct route_table *table; -  struct route_node *rn; -  struct rib *newrib; - -  for (afi = AFI_IP; afi <= AFI_IP6; afi++) -    { -      /* Lookup table.  */ -      table = zebra_vrf_table (afi, SAFI_UNICAST, vrf_id); -      if (! table) -	continue; - -      /* Lookup default route. */ -      memset (&p, 0, sizeof (p)); -      p.family = afi2family (afi); -      rn = route_node_lookup (table, &p); -      if (! rn) -	continue; - -      RNODE_FOREACH_RIB (rn, newrib) -	if (CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED) -	    && newrib->distance != DISTANCE_INFINITY) -	  zsend_redistribute_route (1, client, &rn->p, NULL, newrib); - -      route_unlock_node (rn); -    } +	int afi; +	struct prefix p; +	struct route_table *table; +	struct route_node *rn; +	struct rib *newrib; + +	for (afi = AFI_IP; afi <= AFI_IP6; afi++) { +		/* Lookup table.  */ +		table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id); +		if (!table) +			continue; + +		/* Lookup default route. */ +		memset(&p, 0, sizeof(p)); +		p.family = afi2family(afi); +		rn = route_node_lookup(table, &p); +		if (!rn) +			continue; + +		RNODE_FOREACH_RIB(rn, newrib) +		if (CHECK_FLAG(newrib->flags, ZEBRA_FLAG_SELECTED) +		    && newrib->distance != DISTANCE_INFINITY) +			zsend_redistribute_route(1, client, &rn->p, NULL, +						 newrib); + +		route_unlock_node(rn); +	}  }  /* Redistribute routes. */ -static void -zebra_redistribute (struct zserv *client, int type, u_short instance, vrf_id_t vrf_id, int afi) +static void zebra_redistribute(struct zserv *client, int type, u_short instance, +			       vrf_id_t vrf_id, int afi)  { -  struct rib *newrib; -  struct route_table *table; -  struct route_node *rn; - -  table = zebra_vrf_table (afi, SAFI_UNICAST, vrf_id); -  if (! table) -    return; - -  for (rn = route_top (table); rn; rn = route_next (rn)) -    RNODE_FOREACH_RIB (rn, newrib) -      { -        struct prefix *dst_p, *src_p; -        srcdest_rnode_prefixes(rn, &dst_p, &src_p); - -        if (IS_ZEBRA_DEBUG_EVENT) -          zlog_debug("%s: checking: selected=%d, type=%d, distance=%d, " -                 "zebra_check_addr=%d", __func__, -                 CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED), -                 newrib->type, newrib->distance, -                 zebra_check_addr (dst_p)); - -        if (! CHECK_FLAG (newrib->flags, ZEBRA_FLAG_SELECTED)) -          continue; -        if ((type != ZEBRA_ROUTE_ALL && -         (newrib->type != type || newrib->instance != instance))) -          continue; -        if (newrib->distance == DISTANCE_INFINITY) -          continue; -        if (! zebra_check_addr (dst_p)) -          continue; - -        zsend_redistribute_route (1, client, dst_p, src_p, newrib); -      } +	struct rib *newrib; +	struct route_table *table; +	struct route_node *rn; + +	table = zebra_vrf_table(afi, SAFI_UNICAST, vrf_id); +	if (!table) +		return; + +	for (rn = route_top(table); rn; rn = route_next(rn)) +		RNODE_FOREACH_RIB(rn, newrib) +		{ +			struct prefix *dst_p, *src_p; +			srcdest_rnode_prefixes(rn, &dst_p, &src_p); + +			if (IS_ZEBRA_DEBUG_EVENT) +				zlog_debug( +					"%s: checking: selected=%d, type=%d, distance=%d, " +					"zebra_check_addr=%d", +					__func__, +					CHECK_FLAG(newrib->flags, +						   ZEBRA_FLAG_SELECTED), +					newrib->type, newrib->distance, +					zebra_check_addr(dst_p)); + +			if (!CHECK_FLAG(newrib->flags, ZEBRA_FLAG_SELECTED)) +				continue; +			if ((type != ZEBRA_ROUTE_ALL +			     && (newrib->type != type +				 || newrib->instance != instance))) +				continue; +			if (newrib->distance == DISTANCE_INFINITY) +				continue; +			if (!zebra_check_addr(dst_p)) +				continue; + +			zsend_redistribute_route(1, client, dst_p, src_p, +						 newrib); +		}  }  /* Either advertise a route for redistribution to registered clients or */  /* withdraw redistribution if add cannot be done for client */ -void -redistribute_update (struct prefix *p, struct prefix *src_p, -                     struct rib *rib, struct rib *prev_rib) +void redistribute_update(struct prefix *p, struct prefix *src_p, +			 struct rib *rib, struct rib *prev_rib)  { -  struct listnode *node, *nnode; -  struct zserv *client; -  int send_redistribute; -  int afi; -  char buf[INET6_ADDRSTRLEN]; - -  if (IS_ZEBRA_DEBUG_RIB) -    { -      inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN); -      zlog_debug ("%u:%s/%d: Redist update rib %p (type %d), old %p (type %d)", -                  rib->vrf_id, buf, p->prefixlen, rib, rib->type, -                  prev_rib, prev_rib ? prev_rib->type : -1); -    } - -  afi = family2afi(p->family); -  if (!afi) -    { -      zlog_warn("%s: Unknown AFI/SAFI prefix received\n", __FUNCTION__); -      return; -    } - -  for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) -    { -      send_redistribute = 0; - -      if (is_default (p) && vrf_bitmap_check (client->redist_default, rib->vrf_id)) -	send_redistribute = 1; -      else if (vrf_bitmap_check (client->redist[afi][ZEBRA_ROUTE_ALL], rib->vrf_id)) -	send_redistribute = 1; -      else if (rib->instance && redist_check_instance (&client->mi_redist[afi][rib->type], -						       rib->instance)) -	send_redistribute = 1; -      else if (vrf_bitmap_check (client->redist[afi][rib->type], rib->vrf_id)) -	send_redistribute = 1; - -      if (send_redistribute) -	{ -	  zsend_redistribute_route (1, client, p, src_p, rib); +	struct listnode *node, *nnode; +	struct zserv *client; +	int send_redistribute; +	int afi; +	char buf[INET6_ADDRSTRLEN]; + +	if (IS_ZEBRA_DEBUG_RIB) { +		inet_ntop(p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN); +		zlog_debug( +			"%u:%s/%d: Redist update rib %p (type %d), old %p (type %d)", +			rib->vrf_id, buf, p->prefixlen, rib, rib->type, +			prev_rib, prev_rib ? prev_rib->type : -1); +	} + +	afi = family2afi(p->family); +	if (!afi) { +		zlog_warn("%s: Unknown AFI/SAFI prefix received\n", +			  __FUNCTION__); +		return;  	} -      else if (prev_rib && -	       ((rib->instance && -                redist_check_instance(&client->mi_redist[afi][prev_rib->type], -                                      rib->instance)) || -                vrf_bitmap_check (client->redist[afi][prev_rib->type], rib->vrf_id)))  -	{ -	  zsend_redistribute_route (0, client, p, src_p, prev_rib); + +	for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) { +		send_redistribute = 0; + +		if (is_default(p) +		    && vrf_bitmap_check(client->redist_default, rib->vrf_id)) +			send_redistribute = 1; +		else if (vrf_bitmap_check(client->redist[afi][ZEBRA_ROUTE_ALL], +					  rib->vrf_id)) +			send_redistribute = 1; +		else if (rib->instance +			 && redist_check_instance( +				    &client->mi_redist[afi][rib->type], +				    rib->instance)) +			send_redistribute = 1; +		else if (vrf_bitmap_check(client->redist[afi][rib->type], +					  rib->vrf_id)) +			send_redistribute = 1; + +		if (send_redistribute) { +			zsend_redistribute_route(1, client, p, src_p, rib); +		} else if (prev_rib +			   && ((rib->instance +				&& redist_check_instance( +					   &client->mi_redist[afi] +							     [prev_rib->type], +					   rib->instance)) +			       || vrf_bitmap_check( +					  client->redist[afi][prev_rib->type], +					  rib->vrf_id))) { +			zsend_redistribute_route(0, client, p, src_p, prev_rib); +		}  	} -    }  } -void -redistribute_delete (struct prefix *p, struct prefix *src_p, struct rib *rib) +void redistribute_delete(struct prefix *p, struct prefix *src_p, +			 struct rib *rib)  { -  struct listnode *node, *nnode; -  struct zserv *client; -  char buf[INET6_ADDRSTRLEN]; -  int afi; - -  if (IS_ZEBRA_DEBUG_RIB) -    { -      inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN); -      zlog_debug ("%u:%s/%d: Redist delete rib %p (type %d)", -                  rib->vrf_id, buf, p->prefixlen, rib, rib->type); -    } - -  /* Add DISTANCE_INFINITY check. */ -  if (rib->distance == DISTANCE_INFINITY) -    return; - -  afi = family2afi(p->family); -  if (!afi) -    { -      zlog_warn("%s: Unknown AFI/SAFI prefix received\n", __FUNCTION__); -      return; -    } - -  for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) -    { -      if ((is_default (p) && -           vrf_bitmap_check (client->redist_default, rib->vrf_id)) || -	  vrf_bitmap_check (client->redist[afi][ZEBRA_ROUTE_ALL], rib->vrf_id) || -          (rib->instance && -           redist_check_instance(&client->mi_redist[afi][rib->type], -                                 rib->instance)) || -          vrf_bitmap_check (client->redist[afi][rib->type], rib->vrf_id)) -	{ -	  zsend_redistribute_route (0, client, p, src_p, rib); +	struct listnode *node, *nnode; +	struct zserv *client; +	char buf[INET6_ADDRSTRLEN]; +	int afi; + +	if (IS_ZEBRA_DEBUG_RIB) { +		inet_ntop(p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN); +		zlog_debug("%u:%s/%d: Redist delete rib %p (type %d)", +			   rib->vrf_id, buf, p->prefixlen, rib, rib->type); +	} + +	/* Add DISTANCE_INFINITY check. */ +	if (rib->distance == DISTANCE_INFINITY) +		return; + +	afi = family2afi(p->family); +	if (!afi) { +		zlog_warn("%s: Unknown AFI/SAFI prefix received\n", +			  __FUNCTION__); +		return; +	} + +	for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) { +		if ((is_default(p) +		     && vrf_bitmap_check(client->redist_default, rib->vrf_id)) +		    || vrf_bitmap_check(client->redist[afi][ZEBRA_ROUTE_ALL], +					rib->vrf_id) +		    || (rib->instance +			&& redist_check_instance( +				   &client->mi_redist[afi][rib->type], +				   rib->instance)) +		    || vrf_bitmap_check(client->redist[afi][rib->type], +					rib->vrf_id)) { +			zsend_redistribute_route(0, client, p, src_p, rib); +		}  	} -    }  } -void -zebra_redistribute_add (int command, struct zserv *client, int length, -			struct zebra_vrf *zvrf) +void zebra_redistribute_add(int command, struct zserv *client, int length, +			    struct zebra_vrf *zvrf)  { -  afi_t afi; -  int type; -  u_short instance; - -  afi = stream_getc (client->ibuf); -  type = stream_getc (client->ibuf); -  instance = stream_getw (client->ibuf); - -  if (type == 0 || type >= ZEBRA_ROUTE_MAX) -    return; - -  if (instance) -    { -      if (! redist_check_instance (&client->mi_redist[afi][type], instance)) -	{ -	  redist_add_instance (&client->mi_redist[afi][type], instance); -	  zebra_redistribute (client, type, instance, zvrf_id (zvrf), afi); +	afi_t afi; +	int type; +	u_short instance; + +	afi = stream_getc(client->ibuf); +	type = stream_getc(client->ibuf); +	instance = stream_getw(client->ibuf); + +	if (type == 0 || type >= ZEBRA_ROUTE_MAX) +		return; + +	if (instance) { +		if (!redist_check_instance(&client->mi_redist[afi][type], +					   instance)) { +			redist_add_instance(&client->mi_redist[afi][type], +					    instance); +			zebra_redistribute(client, type, instance, +					   zvrf_id(zvrf), afi); +		} +	} else { +		if (!vrf_bitmap_check(client->redist[afi][type], +				      zvrf_id(zvrf))) { +			vrf_bitmap_set(client->redist[afi][type], +				       zvrf_id(zvrf)); +			zebra_redistribute(client, type, 0, zvrf_id(zvrf), afi); +		}  	} -    } else { -	if (! vrf_bitmap_check (client->redist[afi][type], zvrf_id (zvrf))) -	  { -	    vrf_bitmap_set (client->redist[afi][type], zvrf_id (zvrf)); -	    zebra_redistribute (client, type, 0, zvrf_id (zvrf), afi); -	  } -    }  } -void -zebra_redistribute_delete (int command, struct zserv *client, int length, -			   struct zebra_vrf *zvrf) +void zebra_redistribute_delete(int command, struct zserv *client, int length, +			       struct zebra_vrf *zvrf)  { -  afi_t afi; -  int type; -  u_short instance; - -  afi = stream_getc (client->ibuf); -  type = stream_getc (client->ibuf); -  instance = stream_getw (client->ibuf); - -  if (type == 0 || type >= ZEBRA_ROUTE_MAX) -    return; - -  /* -   * NOTE: no need to withdraw the previously advertised routes. The clients -   * themselves should keep track of the received routes from zebra and -   * withdraw them when necessary. -   */ -  if (instance) -    redist_del_instance (&client->mi_redist[afi][type], instance); -  else -    vrf_bitmap_unset (client->redist[afi][type], zvrf_id (zvrf)); +	afi_t afi; +	int type; +	u_short instance; + +	afi = stream_getc(client->ibuf); +	type = stream_getc(client->ibuf); +	instance = stream_getw(client->ibuf); + +	if (type == 0 || type >= ZEBRA_ROUTE_MAX) +		return; + +	/* +	 * NOTE: no need to withdraw the previously advertised routes. The +	 * clients +	 * themselves should keep track of the received routes from zebra and +	 * withdraw them when necessary. +	 */ +	if (instance) +		redist_del_instance(&client->mi_redist[afi][type], instance); +	else +		vrf_bitmap_unset(client->redist[afi][type], zvrf_id(zvrf));  } -void -zebra_redistribute_default_add (int command, struct zserv *client, int length, -				struct zebra_vrf *zvrf) +void zebra_redistribute_default_add(int command, struct zserv *client, +				    int length, struct zebra_vrf *zvrf)  { -  vrf_bitmap_set (client->redist_default, zvrf_id (zvrf)); -  zebra_redistribute_default (client, zvrf_id (zvrf)); -}      +	vrf_bitmap_set(client->redist_default, zvrf_id(zvrf)); +	zebra_redistribute_default(client, zvrf_id(zvrf)); +} -void -zebra_redistribute_default_delete (int command, struct zserv *client, -				   int length, struct zebra_vrf *zvrf) +void zebra_redistribute_default_delete(int command, struct zserv *client, +				       int length, struct zebra_vrf *zvrf)  { -  vrf_bitmap_unset (client->redist_default, zvrf_id (zvrf)); -}      +	vrf_bitmap_unset(client->redist_default, zvrf_id(zvrf)); +}  /* Interface up information. */ -void -zebra_interface_up_update (struct interface *ifp) +void zebra_interface_up_update(struct interface *ifp)  { -  struct listnode *node, *nnode; -  struct zserv *client; - -  if (IS_ZEBRA_DEBUG_EVENT) -    zlog_debug ("MESSAGE: ZEBRA_INTERFACE_UP %s", ifp->name); - -  if (ifp->ptm_status || !ifp->ptm_enable) { -    for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) -      if (client->ifinfo) -	{ -	  zsend_interface_update (ZEBRA_INTERFACE_UP, client, ifp); -	  zsend_interface_link_params (client, ifp); +	struct listnode *node, *nnode; +	struct zserv *client; + +	if (IS_ZEBRA_DEBUG_EVENT) +		zlog_debug("MESSAGE: ZEBRA_INTERFACE_UP %s", ifp->name); + +	if (ifp->ptm_status || !ifp->ptm_enable) { +		for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) +			if (client->ifinfo) { +				zsend_interface_update(ZEBRA_INTERFACE_UP, +						       client, ifp); +				zsend_interface_link_params(client, ifp); +			}  	} -  }  }  /* Interface down information. */ -void -zebra_interface_down_update (struct interface *ifp) +void zebra_interface_down_update(struct interface *ifp)  { -  struct listnode *node, *nnode; -  struct zserv *client; +	struct listnode *node, *nnode; +	struct zserv *client; -  if (IS_ZEBRA_DEBUG_EVENT) -    zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DOWN %s", ifp->name); +	if (IS_ZEBRA_DEBUG_EVENT) +		zlog_debug("MESSAGE: ZEBRA_INTERFACE_DOWN %s", ifp->name); -  for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) -    { -      zsend_interface_update (ZEBRA_INTERFACE_DOWN, client, ifp); -    } +	for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) { +		zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp); +	}  }  /* Interface information update. */ -void -zebra_interface_add_update (struct interface *ifp) +void zebra_interface_add_update(struct interface *ifp)  { -  struct listnode *node, *nnode; -  struct zserv *client; - -  if (IS_ZEBRA_DEBUG_EVENT) -    zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADD %s[%d]", ifp->name, ifp->vrf_id); -     -  for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) -    if (client->ifinfo) -      { -	client->ifadd_cnt++; -	zsend_interface_add (client, ifp); -        zsend_interface_link_params (client, ifp); -      } +	struct listnode *node, *nnode; +	struct zserv *client; + +	if (IS_ZEBRA_DEBUG_EVENT) +		zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADD %s[%d]", ifp->name, +			   ifp->vrf_id); + +	for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) +		if (client->ifinfo) { +			client->ifadd_cnt++; +			zsend_interface_add(client, ifp); +			zsend_interface_link_params(client, ifp); +		}  } -void -zebra_interface_delete_update (struct interface *ifp) +void zebra_interface_delete_update(struct interface *ifp)  { -  struct listnode *node, *nnode; -  struct zserv *client; +	struct listnode *node, *nnode; +	struct zserv *client; -  if (IS_ZEBRA_DEBUG_EVENT) -    zlog_debug ("MESSAGE: ZEBRA_INTERFACE_DELETE %s", ifp->name); +	if (IS_ZEBRA_DEBUG_EVENT) +		zlog_debug("MESSAGE: ZEBRA_INTERFACE_DELETE %s", ifp->name); -  for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) -    { -      client->ifdel_cnt++; -      zsend_interface_delete (client, ifp); -    } +	for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) { +		client->ifdel_cnt++; +		zsend_interface_delete(client, ifp); +	}  }  /* Interface address addition. */ -void -zebra_interface_address_add_update (struct interface *ifp, -				    struct connected *ifc) +void zebra_interface_address_add_update(struct interface *ifp, +					struct connected *ifc)  { -  struct listnode *node, *nnode; -  struct zserv *client; -  struct prefix *p; - -  if (IS_ZEBRA_DEBUG_EVENT) -    { -      char buf[PREFIX_STRLEN]; - -      p = ifc->address; -      zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s on %s", -		  prefix2str (p, buf, sizeof(buf)), -		  ifc->ifp->name); -    } - -  if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) -    zlog_warn("WARNING: advertising address to clients that is not yet usable."); - -  router_id_add_address(ifc); - -  for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) -    if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) -      { -	client->connected_rt_add_cnt++; -	zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client, ifp, ifc); -      } +	struct listnode *node, *nnode; +	struct zserv *client; +	struct prefix *p; + +	if (IS_ZEBRA_DEBUG_EVENT) { +		char buf[PREFIX_STRLEN]; + +		p = ifc->address; +		zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s on %s", +			   prefix2str(p, buf, sizeof(buf)), ifc->ifp->name); +	} + +	if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) +		zlog_warn( +			"WARNING: advertising address to clients that is not yet usable."); + +	router_id_add_address(ifc); + +	for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) +		if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) { +			client->connected_rt_add_cnt++; +			zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_ADD, +						client, ifp, ifc); +		}  }  /* Interface address deletion. */ -void -zebra_interface_address_delete_update (struct interface *ifp, -				       struct connected *ifc) +void zebra_interface_address_delete_update(struct interface *ifp, +					   struct connected *ifc)  { -  struct listnode *node, *nnode; -  struct zserv *client; -  struct prefix *p; - -  if (IS_ZEBRA_DEBUG_EVENT) -    { -      char buf[PREFIX_STRLEN]; - -      p = ifc->address; -      zlog_debug ("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s on %s", -		  prefix2str (p, buf, sizeof(buf)), -		  ifc->ifp->name); -    } - -  router_id_del_address(ifc); - -  for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) -    if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL)) -      { -	client->connected_rt_del_cnt++; -	zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_DELETE, client, ifp, ifc); -      } +	struct listnode *node, *nnode; +	struct zserv *client; +	struct prefix *p; + +	if (IS_ZEBRA_DEBUG_EVENT) { +		char buf[PREFIX_STRLEN]; + +		p = ifc->address; +		zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s on %s", +			   prefix2str(p, buf, sizeof(buf)), ifc->ifp->name); +	} + +	router_id_del_address(ifc); + +	for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) +		if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) { +			client->connected_rt_del_cnt++; +			zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_DELETE, +						client, ifp, ifc); +		}  }  /* Interface VRF change. May need to delete from clients not interested in   * the new VRF. Note that this function is invoked *prior* to the VRF change.   */ -void -zebra_interface_vrf_update_del (struct interface *ifp, vrf_id_t new_vrf_id) +void zebra_interface_vrf_update_del(struct interface *ifp, vrf_id_t new_vrf_id)  { -  struct listnode *node, *nnode; -  struct zserv *client; - -  if (IS_ZEBRA_DEBUG_EVENT) -    zlog_debug ("MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/DEL %s VRF Id %u -> %u", -                ifp->name, ifp->vrf_id, new_vrf_id); - -  for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) -    { -      /* Need to delete if the client is not interested in the new VRF. */ -      zsend_interface_update (ZEBRA_INTERFACE_DOWN, client, ifp); -      client->ifdel_cnt++; -      zsend_interface_delete (client, ifp); -      zsend_interface_vrf_update (client, ifp, new_vrf_id); -    } +	struct listnode *node, *nnode; +	struct zserv *client; + +	if (IS_ZEBRA_DEBUG_EVENT) +		zlog_debug( +			"MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/DEL %s VRF Id %u -> %u", +			ifp->name, ifp->vrf_id, new_vrf_id); + +	for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) { +		/* Need to delete if the client is not interested in the new +		 * VRF. */ +		zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp); +		client->ifdel_cnt++; +		zsend_interface_delete(client, ifp); +		zsend_interface_vrf_update(client, ifp, new_vrf_id); +	}  }  /* Interface VRF change. This function is invoked *post* VRF change and sends an   * add to clients who are interested in the new VRF but not in the old VRF.   */ -void -zebra_interface_vrf_update_add (struct interface *ifp, vrf_id_t old_vrf_id) +void zebra_interface_vrf_update_add(struct interface *ifp, vrf_id_t old_vrf_id)  { -  struct listnode *node, *nnode; -  struct zserv *client; - -  if (IS_ZEBRA_DEBUG_EVENT) -    zlog_debug ("MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/ADD %s VRF Id %u -> %u", -                ifp->name, old_vrf_id, ifp->vrf_id); - -  for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) -    { -      /* Need to add if the client is interested in the new VRF. */ -      client->ifadd_cnt++; -      zsend_interface_add (client, ifp); -      zsend_interface_addresses (client, ifp); -    } +	struct listnode *node, *nnode; +	struct zserv *client; + +	if (IS_ZEBRA_DEBUG_EVENT) +		zlog_debug( +			"MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/ADD %s VRF Id %u -> %u", +			ifp->name, old_vrf_id, ifp->vrf_id); + +	for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) { +		/* Need to add if the client is interested in the new VRF. */ +		client->ifadd_cnt++; +		zsend_interface_add(client, ifp); +		zsend_interface_addresses(client, ifp); +	}  } -int -zebra_add_import_table_entry (struct route_node *rn, struct rib *rib, const char *rmap_name) +int zebra_add_import_table_entry(struct route_node *rn, struct rib *rib, +				 const char *rmap_name)  { -  struct rib *newrib; -  struct prefix p; -  struct nexthop *nhop; -  union g_addr *gate; -  route_map_result_t ret = RMAP_MATCH; - -  if (rmap_name) -    ret = zebra_import_table_route_map_check (AFI_IP, rib->type, &rn->p, rib->nexthop, rib->vrf_id, -                                              rib->tag, rmap_name); - -  if (ret == RMAP_MATCH) -    { -      if (rn->p.family == AF_INET) -        { -          p.family = AF_INET; -          p.prefixlen = rn->p.prefixlen; -          p.u.prefix4 = rn->p.u.prefix4; - -          if (rib->nexthop_num == 1) -	    { -	      nhop = rib->nexthop; -	      if (nhop->type == NEXTHOP_TYPE_IFINDEX) -	        gate = NULL; -	      else -	        gate = (union g_addr *)&nhop->gate.ipv4; - -	      rib_add (AFI_IP, SAFI_UNICAST, rib->vrf_id, ZEBRA_ROUTE_TABLE, -		       rib->table, 0, &p, NULL, gate, (union g_addr *)&nhop->src.ipv4, -		       nhop->ifindex, zebrad.rtm_table_default, -		       rib->metric, rib->mtu, -		       zebra_import_table_distance[AFI_IP][rib->table]); -	    } -          else if (rib->nexthop_num > 1) -	    { -	      newrib = XCALLOC (MTYPE_RIB, sizeof (struct rib)); -	      newrib->type = ZEBRA_ROUTE_TABLE; -	      newrib->distance = zebra_import_table_distance[AFI_IP][rib->table]; -	      newrib->flags = rib->flags; -	      newrib->metric = rib->metric; -	      newrib->mtu = rib->mtu; -	      newrib->table = zebrad.rtm_table_default; -	      newrib->nexthop_num = 0; -	      newrib->uptime = time(NULL); -	      newrib->instance = rib->table; - -	      /* Assuming these routes are never recursive */ -	      for (nhop = rib->nexthop; nhop; nhop = nhop->next) -	        rib_copy_nexthops(newrib, nhop); - -	      rib_add_multipath(AFI_IP, SAFI_UNICAST, &p, NULL, newrib); -	    } -        } -    } -  else -    { -      zebra_del_import_table_entry (rn, rib); -    } -  /* DD: Add IPv6 code */ -  return 0; +	struct rib *newrib; +	struct prefix p; +	struct nexthop *nhop; +	union g_addr *gate; +	route_map_result_t ret = RMAP_MATCH; + +	if (rmap_name) +		ret = zebra_import_table_route_map_check( +			AFI_IP, rib->type, &rn->p, rib->nexthop, rib->vrf_id, +			rib->tag, rmap_name); + +	if (ret == RMAP_MATCH) { +		if (rn->p.family == AF_INET) { +			p.family = AF_INET; +			p.prefixlen = rn->p.prefixlen; +			p.u.prefix4 = rn->p.u.prefix4; + +			if (rib->nexthop_num == 1) { +				nhop = rib->nexthop; +				if (nhop->type == NEXTHOP_TYPE_IFINDEX) +					gate = NULL; +				else +					gate = (union g_addr *)&nhop->gate.ipv4; + +				rib_add(AFI_IP, SAFI_UNICAST, rib->vrf_id, +					ZEBRA_ROUTE_TABLE, rib->table, 0, &p, +					NULL, gate, +					(union g_addr *)&nhop->src.ipv4, +					nhop->ifindex, zebrad.rtm_table_default, +					rib->metric, rib->mtu, +					zebra_import_table_distance +						[AFI_IP][rib->table]); +			} else if (rib->nexthop_num > 1) { +				newrib = XCALLOC(MTYPE_RIB, sizeof(struct rib)); +				newrib->type = ZEBRA_ROUTE_TABLE; +				newrib->distance = +					zebra_import_table_distance[AFI_IP] +								   [rib->table]; +				newrib->flags = rib->flags; +				newrib->metric = rib->metric; +				newrib->mtu = rib->mtu; +				newrib->table = zebrad.rtm_table_default; +				newrib->nexthop_num = 0; +				newrib->uptime = time(NULL); +				newrib->instance = rib->table; + +				/* Assuming these routes are never recursive */ +				for (nhop = rib->nexthop; nhop; +				     nhop = nhop->next) +					rib_copy_nexthops(newrib, nhop); + +				rib_add_multipath(AFI_IP, SAFI_UNICAST, &p, +						  NULL, newrib); +			} +		} +	} else { +		zebra_del_import_table_entry(rn, rib); +	} +	/* DD: Add IPv6 code */ +	return 0;  } -int -zebra_del_import_table_entry (struct route_node *rn, struct rib *rib) +int zebra_del_import_table_entry(struct route_node *rn, struct rib *rib)  { -  struct prefix p; +	struct prefix p; -  if (rn->p.family == AF_INET) -    { -      p.family = AF_INET; -      p.prefixlen = rn->p.prefixlen; -      p.u.prefix4 = rn->p.u.prefix4; +	if (rn->p.family == AF_INET) { +		p.family = AF_INET; +		p.prefixlen = rn->p.prefixlen; +		p.u.prefix4 = rn->p.u.prefix4; -      rib_delete (AFI_IP, SAFI_UNICAST, rib->vrf_id, ZEBRA_ROUTE_TABLE, -		  rib->table, rib->flags, &p, NULL, NULL, -		  0, zebrad.rtm_table_default); -    } -  /* DD: Add IPv6 code */ +		rib_delete(AFI_IP, SAFI_UNICAST, rib->vrf_id, ZEBRA_ROUTE_TABLE, +			   rib->table, rib->flags, &p, NULL, NULL, 0, +			   zebrad.rtm_table_default); +	} +	/* DD: Add IPv6 code */ -  return 0; +	return 0;  }  /* Assuming no one calls this with the main routing table */ -int -zebra_import_table (afi_t afi, u_int32_t table_id, u_int32_t distance, const char *rmap_name, int add) +int zebra_import_table(afi_t afi, u_int32_t table_id, u_int32_t distance, +		       const char *rmap_name, int add)  { -  struct route_table *table; -  struct rib *rib; -  struct route_node *rn; - -  if (!is_zebra_valid_kernel_table(table_id) || -      ((table_id == RT_TABLE_MAIN) || (table_id == zebrad.rtm_table_default))) -    return (-1); - -  if (afi >= AFI_MAX) -    return (-1); - -  table = zebra_vrf_other_route_table(afi, table_id, VRF_DEFAULT); -  if (table == NULL) -    { -      return 0; -    } -  else if (IS_ZEBRA_DEBUG_RIB) -    { -      zlog_debug ("%s routes from table %d", -		  add ? "Importing" : "Unimporting", table_id); -    } - -  if (add) -    { -      if (rmap_name) -        zebra_add_import_table_route_map (afi, rmap_name, table_id); -      else -        { -          rmap_name = zebra_get_import_table_route_map (afi, table_id); -          if (rmap_name) -            zebra_del_import_table_route_map (afi, table_id); -        } - -      zebra_import_table_used[afi][table_id] = 1; -      zebra_import_table_distance[afi][table_id] = distance; -    } -  else -    { -      zebra_import_table_used[afi][table_id] = 0; -      zebra_import_table_distance[afi][table_id] = ZEBRA_TABLE_DISTANCE_DEFAULT; - -      rmap_name = zebra_get_import_table_route_map (afi, table_id); -      if (rmap_name) -        zebra_del_import_table_route_map (afi, table_id); -    } - -  for (rn = route_top(table); rn; rn = route_next(rn)) -    { -      /* For each entry in the non-default routing table, -       * add the entry in the main table -       */ -      if (!rn->info) -	continue; - -      RNODE_FOREACH_RIB (rn, rib) -	{ -	  if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) -	    continue; -	  break; +	struct route_table *table; +	struct rib *rib; +	struct route_node *rn; + +	if (!is_zebra_valid_kernel_table(table_id) +	    || ((table_id == RT_TABLE_MAIN) +		|| (table_id == zebrad.rtm_table_default))) +		return (-1); + +	if (afi >= AFI_MAX) +		return (-1); + +	table = zebra_vrf_other_route_table(afi, table_id, VRF_DEFAULT); +	if (table == NULL) { +		return 0; +	} else if (IS_ZEBRA_DEBUG_RIB) { +		zlog_debug("%s routes from table %d", +			   add ? "Importing" : "Unimporting", table_id);  	} -      if (!rib) -	continue; +	if (add) { +		if (rmap_name) +			zebra_add_import_table_route_map(afi, rmap_name, +							 table_id); +		else { +			rmap_name = +				zebra_get_import_table_route_map(afi, table_id); +			if (rmap_name) +				zebra_del_import_table_route_map(afi, table_id); +		} -      if (((afi == AFI_IP) && (rn->p.family == AF_INET)) || -	  ((afi == AFI_IP6) && (rn->p.family == AF_INET6))) -	{ -	  if (add) -	    zebra_add_import_table_entry (rn, rib, rmap_name); -	  else -	    zebra_del_import_table_entry (rn, rib); +		zebra_import_table_used[afi][table_id] = 1; +		zebra_import_table_distance[afi][table_id] = distance; +	} else { +		zebra_import_table_used[afi][table_id] = 0; +		zebra_import_table_distance[afi][table_id] = +			ZEBRA_TABLE_DISTANCE_DEFAULT; + +		rmap_name = zebra_get_import_table_route_map(afi, table_id); +		if (rmap_name) +			zebra_del_import_table_route_map(afi, table_id);  	} -    } -  return 0; -} -int -zebra_import_table_config (struct vty *vty) -{ -  int i; -  afi_t afi; -  int write = 0; -  char afi_str[AFI_MAX][10] = {"", "ip", "ipv6", "ethernet"}; -  const char *rmap_name; - -  for (afi = AFI_IP; afi < AFI_MAX; afi++) -    { -      for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) -	{ -	  if (is_zebra_import_table_enabled(afi, i)) -	    { -	      if (zebra_import_table_distance[afi][i] != ZEBRA_TABLE_DISTANCE_DEFAULT) -		{ -		  vty_out(vty, "%s import-table %d distance %d", afi_str[afi], -			  i, zebra_import_table_distance[afi][i]); -		} -	      else +	for (rn = route_top(table); rn; rn = route_next(rn)) { +		/* For each entry in the non-default routing table, +		 * add the entry in the main table +		 */ +		if (!rn->info) +			continue; + +		RNODE_FOREACH_RIB(rn, rib)  		{ -		  vty_out(vty, "%s import-table %d", afi_str[afi], i); +			if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED)) +				continue; +			break;  		} -	      rmap_name = zebra_get_import_table_route_map (afi, i); -              if (rmap_name) -	        vty_out(vty, " route-map %s", rmap_name); +		if (!rib) +			continue; -	      vty_out(vty, "%s", VTY_NEWLINE); -	      write = 1; -	    } +		if (((afi == AFI_IP) && (rn->p.family == AF_INET)) +		    || ((afi == AFI_IP6) && (rn->p.family == AF_INET6))) { +			if (add) +				zebra_add_import_table_entry(rn, rib, +							     rmap_name); +			else +				zebra_del_import_table_entry(rn, rib); +		} +	} +	return 0; +} + +int zebra_import_table_config(struct vty *vty) +{ +	int i; +	afi_t afi; +	int write = 0; +	char afi_str[AFI_MAX][10] = {"", "ip", "ipv6", "ethernet"}; +	const char *rmap_name; + +	for (afi = AFI_IP; afi < AFI_MAX; afi++) { +		for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) { +			if (is_zebra_import_table_enabled(afi, i)) { +				if (zebra_import_table_distance[afi][i] +				    != ZEBRA_TABLE_DISTANCE_DEFAULT) { +					vty_out(vty, +						"%s import-table %d distance %d", +						afi_str[afi], i, +						zebra_import_table_distance[afi] +									   [i]); +				} else { +					vty_out(vty, "%s import-table %d", +						afi_str[afi], i); +				} + +				rmap_name = zebra_get_import_table_route_map( +					afi, i); +				if (rmap_name) +					vty_out(vty, " route-map %s", +						rmap_name); + +				vty_out(vty, "%s", VTY_NEWLINE); +				write = 1; +			} +		}  	} -    } -  return write; +	return write;  } -void -zebra_import_table_rm_update () +void zebra_import_table_rm_update()  { -  afi_t afi; -  int i; -  struct route_table *table; -  struct rib *rib; -  struct route_node *rn; -  const char *rmap_name; - -  for (afi = AFI_IP; afi < AFI_MAX; afi++) -    { -      for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) -	{ -	  if (is_zebra_import_table_enabled(afi, i)) -	    { -              rmap_name = zebra_get_import_table_route_map (afi, i); -              if (!rmap_name) -                return; - -              table = zebra_vrf_other_route_table(afi, i, VRF_DEFAULT); -              for (rn = route_top(table); rn; rn = route_next(rn)) -                { -                  /* For each entry in the non-default routing table, -                   * add the entry in the main table -                   */ -                  if (!rn->info) -                    continue; - -                  RNODE_FOREACH_RIB (rn, rib) -                    { -                      if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) -                        continue; -                      break; -                    } - -                 if (!rib) -                   continue; - -                 if (((afi == AFI_IP) && (rn->p.family == AF_INET)) || -                   ((afi == AFI_IP6) && (rn->p.family == AF_INET6))) -                   zebra_add_import_table_entry (rn, rib, rmap_name); -                } -	    } +	afi_t afi; +	int i; +	struct route_table *table; +	struct rib *rib; +	struct route_node *rn; +	const char *rmap_name; + +	for (afi = AFI_IP; afi < AFI_MAX; afi++) { +		for (i = 1; i < ZEBRA_KERNEL_TABLE_MAX; i++) { +			if (is_zebra_import_table_enabled(afi, i)) { +				rmap_name = zebra_get_import_table_route_map( +					afi, i); +				if (!rmap_name) +					return; + +				table = zebra_vrf_other_route_table( +					afi, i, VRF_DEFAULT); +				for (rn = route_top(table); rn; +				     rn = route_next(rn)) { +					/* For each entry in the non-default +					 * routing table, +					 * add the entry in the main table +					 */ +					if (!rn->info) +						continue; + +					RNODE_FOREACH_RIB(rn, rib) +					{ +						if (CHECK_FLAG( +							    rib->status, +							    RIB_ENTRY_REMOVED)) +							continue; +						break; +					} + +					if (!rib) +						continue; + +					if (((afi == AFI_IP) +					     && (rn->p.family == AF_INET)) +					    || ((afi == AFI_IP6) +						&& (rn->p.family == AF_INET6))) +						zebra_add_import_table_entry( +							rn, rib, rmap_name); +				} +			} +		}  	} -    } -  return; +	return;  }  /* Interface parameters update */ -void -zebra_interface_parameters_update (struct interface *ifp) +void zebra_interface_parameters_update(struct interface *ifp)  { -  struct listnode *node, *nnode; -  struct zserv *client; +	struct listnode *node, *nnode; +	struct zserv *client; -  if (IS_ZEBRA_DEBUG_EVENT) -    zlog_debug ("MESSAGE: ZEBRA_INTERFACE_LINK_PARAMS %s", ifp->name); +	if (IS_ZEBRA_DEBUG_EVENT) +		zlog_debug("MESSAGE: ZEBRA_INTERFACE_LINK_PARAMS %s", +			   ifp->name); -  for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) -    if (client->ifinfo) -      zsend_interface_link_params (client, ifp); +	for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) +		if (client->ifinfo) +			zsend_interface_link_params(client, ifp);  } diff --git a/zebra/redistribute.h b/zebra/redistribute.h index 06afc726d1..11b2949c87 100644 --- a/zebra/redistribute.h +++ b/zebra/redistribute.h @@ -17,7 +17,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #ifndef _ZEBRA_REDISTRIBUTE_H @@ -28,46 +28,48 @@  #include "vty.h"  #include "vrf.h" -extern void zebra_redistribute_add (int, struct zserv *, int, struct zebra_vrf *zvrf); -extern void zebra_redistribute_delete (int, struct zserv *, int, struct zebra_vrf *zvrf); +extern void zebra_redistribute_add(int, struct zserv *, int, +				   struct zebra_vrf *zvrf); +extern void zebra_redistribute_delete(int, struct zserv *, int, +				      struct zebra_vrf *zvrf); -extern void zebra_redistribute_default_add (int, struct zserv *, int, -					    struct zebra_vrf *zvrf); -extern void zebra_redistribute_default_delete (int, struct zserv *, int, -					       struct zebra_vrf *zvrf); +extern void zebra_redistribute_default_add(int, struct zserv *, int, +					   struct zebra_vrf *zvrf); +extern void zebra_redistribute_default_delete(int, struct zserv *, int, +					      struct zebra_vrf *zvrf); -extern void redistribute_update (struct prefix *, struct prefix *, -                                 struct rib *, struct rib *); -extern void redistribute_delete (struct prefix *, struct prefix *, struct rib *); +extern void redistribute_update(struct prefix *, struct prefix *, struct rib *, +				struct rib *); +extern void redistribute_delete(struct prefix *, struct prefix *, struct rib *); -extern void zebra_interface_up_update (struct interface *); -extern void zebra_interface_down_update (struct interface *); +extern void zebra_interface_up_update(struct interface *); +extern void zebra_interface_down_update(struct interface *); -extern void zebra_interface_add_update (struct interface *); -extern void zebra_interface_delete_update (struct interface *); +extern void zebra_interface_add_update(struct interface *); +extern void zebra_interface_delete_update(struct interface *); -extern void zebra_interface_address_add_update (struct interface *, -					 	struct connected *); -extern void zebra_interface_address_delete_update (struct interface *, -						   struct connected *c); -extern void zebra_interface_parameters_update (struct interface *); -extern void zebra_interface_vrf_update_del (struct interface *, vrf_id_t new_vrf_id); -extern void zebra_interface_vrf_update_add (struct interface *, vrf_id_t old_vrf_id); +extern void zebra_interface_address_add_update(struct interface *, +					       struct connected *); +extern void zebra_interface_address_delete_update(struct interface *, +						  struct connected *c); +extern void zebra_interface_parameters_update(struct interface *); +extern void zebra_interface_vrf_update_del(struct interface *, +					   vrf_id_t new_vrf_id); +extern void zebra_interface_vrf_update_add(struct interface *, +					   vrf_id_t old_vrf_id); -extern int zebra_import_table (afi_t afi, u_int32_t table_id, -			       u_int32_t distance, const char *rmap_name, int add); +extern int zebra_import_table(afi_t afi, u_int32_t table_id, u_int32_t distance, +			      const char *rmap_name, int add); -extern int zebra_add_import_table_entry (struct route_node *rn, -					 struct rib *rib, const char *rmap_name); -extern int zebra_del_import_table_entry (struct route_node *rn, -					 struct rib *rib); +extern int zebra_add_import_table_entry(struct route_node *rn, struct rib *rib, +					const char *rmap_name); +extern int zebra_del_import_table_entry(struct route_node *rn, struct rib *rib);  extern int is_zebra_import_table_enabled(afi_t, u_int32_t table_id);  extern int zebra_import_table_config(struct vty *);  extern void zebra_import_table_rm_update(void); -extern int is_default (struct prefix *); +extern int is_default(struct prefix *);  #endif /* _ZEBRA_REDISTRIBUTE_H */ - diff --git a/zebra/redistribute_null.c b/zebra/redistribute_null.c index ffde8ed773..d72e99600e 100644 --- a/zebra/redistribute_null.c +++ b/zebra/redistribute_null.c @@ -1,4 +1,4 @@ -/*  +/*   * Copyright (C) 2006 Sun Microsystems, Inc.   *   * This file is part of Quagga. @@ -16,7 +16,7 @@   * You should have received a copy of the GNU General Public License   * along with Quagga; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #include <zebra.h> @@ -26,67 +26,110 @@  #include "zebra/redistribute.h" -void zebra_redistribute_add (int a, struct zserv *b, int c, -			     struct zebra_vrf *zvrf) -{ return; } -void zebra_redistribute_delete  (int a, struct zserv *b, int c, -				 struct zebra_vrf *zvrf) -{ return; } -void zebra_redistribute_default_add (int a, struct zserv *b, int c, -				     struct zebra_vrf *zvrf) -{ return; } -void zebra_redistribute_default_delete (int a, struct zserv *b, int c, -					struct zebra_vrf *zvrf) -{ return; } - -void redistribute_update (struct prefix *a, struct prefix *b, -                          struct rib *c, struct rib *d) -{ return; } -void redistribute_delete (struct prefix *a, struct prefix *b, struct rib *c) -{ return; } - -void zebra_interface_up_update (struct interface *a) -{ return; } -void zebra_interface_down_update  (struct interface *a) -{ return; } -void zebra_interface_add_update (struct interface *a) -{ return; } -void zebra_interface_delete_update (struct interface *a) -{ return; } - - -void zebra_interface_address_add_update (struct interface *a, -					 	struct connected *b) -{ return; } -void zebra_interface_address_delete_update (struct interface *a, -                                                struct connected *b) -{ return; } +void zebra_redistribute_add(int a, struct zserv *b, int c, +			    struct zebra_vrf *zvrf) +{ +	return; +} +void zebra_redistribute_delete(int a, struct zserv *b, int c, +			       struct zebra_vrf *zvrf) +{ +	return; +} +void zebra_redistribute_default_add(int a, struct zserv *b, int c, +				    struct zebra_vrf *zvrf) +{ +	return; +} +void zebra_redistribute_default_delete(int a, struct zserv *b, int c, +				       struct zebra_vrf *zvrf) +{ +	return; +} + +void redistribute_update(struct prefix *a, struct prefix *b, struct rib *c, +			 struct rib *d) +{ +	return; +} +void redistribute_delete(struct prefix *a, struct prefix *b, struct rib *c) +{ +	return; +} + +void zebra_interface_up_update(struct interface *a) +{ +	return; +} +void zebra_interface_down_update(struct interface *a) +{ +	return; +} +void zebra_interface_add_update(struct interface *a) +{ +	return; +} +void zebra_interface_delete_update(struct interface *a) +{ +	return; +} + + +void zebra_interface_address_add_update(struct interface *a, +					struct connected *b) +{ +	return; +} +void zebra_interface_address_delete_update(struct interface *a, +					   struct connected *b) +{ +	return; +}  /* Interface parameters update */ -void zebra_interface_parameters_update (struct interface *ifp) -{ return; }; - -void zebra_interface_vrf_update_del (struct interface *a, vrf_id_t new_vrf_id) -{ return; } - -void zebra_interface_vrf_update_add (struct interface *a, vrf_id_t old_vrf_id) -{ return; } - -int zebra_import_table (afi_t afi, u_int32_t table_id, u_int32_t distance, -			const char *rmap_name, int add) -{ return 0; } - -int zebra_add_import_table_entry (struct route_node *rn, struct rib *rib, const char *rmap_name) -{ return 0; } - -int zebra_del_import_table_entry (struct route_node *rn, struct rib *rib) -{ return 0; } +void zebra_interface_parameters_update(struct interface *ifp) +{ +	return; +}; + +void zebra_interface_vrf_update_del(struct interface *a, vrf_id_t new_vrf_id) +{ +	return; +} + +void zebra_interface_vrf_update_add(struct interface *a, vrf_id_t old_vrf_id) +{ +	return; +} + +int zebra_import_table(afi_t afi, u_int32_t table_id, u_int32_t distance, +		       const char *rmap_name, int add) +{ +	return 0; +} + +int zebra_add_import_table_entry(struct route_node *rn, struct rib *rib, +				 const char *rmap_name) +{ +	return 0; +} + +int zebra_del_import_table_entry(struct route_node *rn, struct rib *rib) +{ +	return 0; +}  int is_zebra_import_table_enabled(afi_t afi, u_int32_t table_id) -{ return 0; } +{ +	return 0; +}  int zebra_import_table_config(struct vty *vty) -{ return 0; } +{ +	return 0; +}  void zebra_import_table_rm_update() -{ return; } +{ +	return; +} diff --git a/zebra/rib.h b/zebra/rib.h index e910facb44..7319478f4f 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -17,7 +17,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #ifndef _ZEBRA_RIB_H @@ -38,64 +38,63 @@  #define DISTANCE_INFINITY  255  #define ZEBRA_KERNEL_TABLE_MAX 252 /* support for no more than this rt tables */ -struct rib -{ -  /* Link list. */ -  struct rib *next; -  struct rib *prev; -   -  /* Nexthop structure */ -  struct nexthop *nexthop; -   -  /* Refrence count. */ -  unsigned long refcnt; -   -  /* Tag */ -  route_tag_t tag; - -  /* Uptime. */ -  time_t uptime; - -  /* Type fo this route. */ -  int type; - -  /* Source protocol instance */ -  u_short instance; - -  /* VRF identifier. */ -  vrf_id_t vrf_id; - -  /* Which routing table */ -  uint32_t table; - -  /* Metric */ -  u_int32_t metric; - -  /* MTU */ -  u_int32_t mtu; -  u_int32_t nexthop_mtu; - -  /* Distance. */ -  u_char distance; - -  /* Flags of this route. -   * This flag's definition is in lib/zebra.h ZEBRA_FLAG_* and is exposed -   * to clients via Zserv -   */ -  u_int32_t flags; - -  /* RIB internal status */ -  u_char status; +struct rib { +	/* Link list. */ +	struct rib *next; +	struct rib *prev; + +	/* Nexthop structure */ +	struct nexthop *nexthop; + +	/* Refrence count. */ +	unsigned long refcnt; + +	/* Tag */ +	route_tag_t tag; + +	/* Uptime. */ +	time_t uptime; + +	/* Type fo this route. */ +	int type; + +	/* Source protocol instance */ +	u_short instance; + +	/* VRF identifier. */ +	vrf_id_t vrf_id; + +	/* Which routing table */ +	uint32_t table; + +	/* Metric */ +	u_int32_t metric; + +	/* MTU */ +	u_int32_t mtu; +	u_int32_t nexthop_mtu; + +	/* Distance. */ +	u_char distance; + +	/* Flags of this route. +	 * This flag's definition is in lib/zebra.h ZEBRA_FLAG_* and is exposed +	 * to clients via Zserv +	 */ +	u_int32_t flags; + +	/* RIB internal status */ +	u_char status;  #define RIB_ENTRY_REMOVED	   0x1 -  /* to simplify NHT logic when NHs change, instead of doing a NH by NH cmp */ +/* to simplify NHT logic when NHs change, instead of doing a NH by NH cmp */  #define RIB_ENTRY_NEXTHOPS_CHANGED 0x2  #define RIB_ENTRY_CHANGED          0x4  #define RIB_ENTRY_SELECTED_FIB     0x8  #define RIB_ENTRY_LABELS_CHANGED   0x10 -  /* Nexthop information. */ -  u_char nexthop_num; -  u_char nexthop_active_num; +	/* Nexthop information. */ +	u_char nexthop_num; +	u_char nexthop_active_num;  };  /* meta-queue structure: @@ -106,38 +105,36 @@ struct rib   * sub-queue 4: any other origin (if any)   */  #define MQ_SIZE 5 -struct meta_queue -{ -  struct list *subq[MQ_SIZE]; -  u_int32_t size; /* sum of lengths of all subqueues */ +struct meta_queue { +	struct list *subq[MQ_SIZE]; +	u_int32_t size; /* sum of lengths of all subqueues */  };  /*   * Structure that represents a single destination (prefix).   */ -typedef struct rib_dest_t_ -{ +typedef struct rib_dest_t_ { -  /* -   * Back pointer to the route node for this destination. This helps -   * us get to the prefix that this structure is for. -   */ -  struct route_node *rnode; +	/* +	 * Back pointer to the route node for this destination. This helps +	 * us get to the prefix that this structure is for. +	 */ +	struct route_node *rnode; -  /* -   * Doubly-linked list of routes for this prefix. -   */ -  struct rib *routes; +	/* +	 * Doubly-linked list of routes for this prefix. +	 */ +	struct rib *routes; -  /* -   * Flags, see below. -   */ -  u_int32_t flags; +	/* +	 * Flags, see below. +	 */ +	u_int32_t flags; -  /* -   * Linkage to put dest on the FPM processing queue. -   */ -  TAILQ_ENTRY(rib_dest_t_) fpm_q_entries; +	/* +	 * Linkage to put dest on the FPM processing queue. +	 */ +	TAILQ_ENTRY(rib_dest_t_) fpm_q_entries;  } rib_dest_t; @@ -163,22 +160,21 @@ typedef struct rib_dest_t_  /*   * Macro to iterate over each route for a destination (prefix).   */ -#define RIB_DEST_FOREACH_ROUTE(dest, rib)				\ -  for ((rib) = (dest) ? (dest)->routes : NULL; (rib); (rib) = (rib)->next) +#define RIB_DEST_FOREACH_ROUTE(dest, rib)                                      \ +	for ((rib) = (dest) ? (dest)->routes : NULL; (rib); (rib) = (rib)->next)  /*   * Same as above, but allows the current node to be unlinked.   */ -#define RIB_DEST_FOREACH_ROUTE_SAFE(dest, rib, next)	\ -  for ((rib) = (dest) ? (dest)->routes : NULL;		\ -       (rib) && ((next) = (rib)->next, 1);		\ -       (rib) = (next)) +#define RIB_DEST_FOREACH_ROUTE_SAFE(dest, rib, next)                           \ +	for ((rib) = (dest) ? (dest)->routes : NULL;                           \ +	     (rib) && ((next) = (rib)->next, 1); (rib) = (next)) -#define RNODE_FOREACH_RIB(rn, rib)				\ -  RIB_DEST_FOREACH_ROUTE (rib_dest_from_rnode (rn), rib) +#define RNODE_FOREACH_RIB(rn, rib)                                             \ +	RIB_DEST_FOREACH_ROUTE(rib_dest_from_rnode(rn), rib) -#define RNODE_FOREACH_RIB_SAFE(rn, rib, next)				\ -  RIB_DEST_FOREACH_ROUTE_SAFE (rib_dest_from_rnode (rn), rib, next) +#define RNODE_FOREACH_RIB_SAFE(rn, rib, next)                                  \ +	RIB_DEST_FOREACH_ROUTE_SAFE(rib_dest_from_rnode(rn), rib, next)  /* The following for loop allows to iterate over the nexthop   * structure of routes. @@ -217,26 +213,29 @@ typedef struct rib_dest_t_   * to `tnexthop->next', progressing to the next position in the top-level   * chain and possibly to its end marked by NULL.   */ -#define ALL_NEXTHOPS_RO(head, nexthop, tnexthop, recursing) \ -  (tnexthop) = (nexthop) = (head), (recursing) = 0; \ -  (nexthop); \ -  (nexthop) = CHECK_FLAG((nexthop)->flags, NEXTHOP_FLAG_RECURSIVE) \ -    ? (((recursing) = 1), (nexthop)->resolved) \ -    : ((nexthop)->next ? ((recursing) ? (nexthop)->next \ -                                      : ((tnexthop) = (nexthop)->next)) \ -                       : (((recursing) = 0),((tnexthop) = (tnexthop)->next))) - -#if defined (HAVE_RTADV) +#define ALL_NEXTHOPS_RO(head, nexthop, tnexthop, recursing)                    \ +	(tnexthop) = (nexthop) = (head), (recursing) = 0;                      \ +	(nexthop);                                                             \ +	(nexthop) =                                                            \ +		CHECK_FLAG((nexthop)->flags, NEXTHOP_FLAG_RECURSIVE)           \ +			? (((recursing) = 1), (nexthop)->resolved)             \ +			: ((nexthop)->next                                     \ +				   ? ((recursing) ? (nexthop)->next            \ +						  : ((tnexthop) =              \ +							     (nexthop)->next)) \ +				   : (((recursing) = 0),                       \ +				      ((tnexthop) = (tnexthop)->next))) + +#if defined(HAVE_RTADV)  /* Structure which hold status of router advertisement. */ -struct rtadv -{ -  int sock; +struct rtadv { +	int sock; -  int adv_if_count; -  int adv_msec_if_count; +	int adv_if_count; +	int adv_msec_if_count; -  struct thread *ra_read; -  struct thread *ra_timer; +	struct thread *ra_read; +	struct thread *ra_timer;  };  #endif /* HAVE_RTADV */ @@ -246,139 +245,135 @@ struct rtadv   * Structure that is hung off of a route_table that holds information about   * the table.   */ -typedef struct rib_table_info_t_ -{ +typedef struct rib_table_info_t_ { -  /* -   * Back pointer to zebra_vrf. -   */ -  struct zebra_vrf *zvrf; -  afi_t afi; -  safi_t safi; +	/* +	 * Back pointer to zebra_vrf. +	 */ +	struct zebra_vrf *zvrf; +	afi_t afi; +	safi_t safi;  } rib_table_info_t; -typedef enum -{ -  RIB_TABLES_ITER_S_INIT, -  RIB_TABLES_ITER_S_ITERATING, -  RIB_TABLES_ITER_S_DONE +typedef enum { +	RIB_TABLES_ITER_S_INIT, +	RIB_TABLES_ITER_S_ITERATING, +	RIB_TABLES_ITER_S_DONE  } rib_tables_iter_state_t;  /*   * Structure that holds state for iterating over all tables in the   * Routing Information Base.   */ -typedef struct rib_tables_iter_t_ -{ -  vrf_id_t vrf_id; -  int afi_safi_ix; +typedef struct rib_tables_iter_t_ { +	vrf_id_t vrf_id; +	int afi_safi_ix; -  rib_tables_iter_state_t state; +	rib_tables_iter_state_t state;  } rib_tables_iter_t;  /* Events/reasons triggering a RIB update. */ -typedef enum -{ -  RIB_UPDATE_IF_CHANGE, -  RIB_UPDATE_RMAP_CHANGE, -  RIB_UPDATE_OTHER +typedef enum { +	RIB_UPDATE_IF_CHANGE, +	RIB_UPDATE_RMAP_CHANGE, +	RIB_UPDATE_OTHER  } rib_update_event_t; -extern struct nexthop *rib_nexthop_ifindex_add (struct rib *, ifindex_t); -extern struct nexthop *rib_nexthop_blackhole_add (struct rib *); -extern struct nexthop *rib_nexthop_ipv4_add (struct rib *, struct in_addr *, -					     struct in_addr *); -extern struct nexthop *rib_nexthop_ipv4_ifindex_add (struct rib *, -						     struct in_addr *, -						     struct in_addr *, -						     ifindex_t); -extern void rib_nexthop_add (struct rib *rib, struct nexthop *nexthop); -extern void rib_copy_nexthops (struct rib *rib, struct nexthop *nh); +extern struct nexthop *rib_nexthop_ifindex_add(struct rib *, ifindex_t); +extern struct nexthop *rib_nexthop_blackhole_add(struct rib *); +extern struct nexthop *rib_nexthop_ipv4_add(struct rib *, struct in_addr *, +					    struct in_addr *); +extern struct nexthop *rib_nexthop_ipv4_ifindex_add(struct rib *, +						    struct in_addr *, +						    struct in_addr *, +						    ifindex_t); +extern void rib_nexthop_add(struct rib *rib, struct nexthop *nexthop); +extern void rib_copy_nexthops(struct rib *rib, struct nexthop *nh);  /* RPF lookup behaviour */ -enum multicast_mode -{ -  MCAST_NO_CONFIG = 0,	/* MIX_MRIB_FIRST, but no show in config write */ -  MCAST_MRIB_ONLY,	/* MRIB only */ -  MCAST_URIB_ONLY,	/* URIB only */ -  MCAST_MIX_MRIB_FIRST,	/* MRIB, if nothing at all then URIB */ -  MCAST_MIX_DISTANCE,	/* MRIB & URIB, lower distance wins */ -  MCAST_MIX_PFXLEN,	/* MRIB & URIB, longer prefix wins */ -			/* on equal value, MRIB wins for last 2 */ +enum multicast_mode { +	MCAST_NO_CONFIG = 0,  /* MIX_MRIB_FIRST, but no show in config write */ +	MCAST_MRIB_ONLY,      /* MRIB only */ +	MCAST_URIB_ONLY,      /* URIB only */ +	MCAST_MIX_MRIB_FIRST, /* MRIB, if nothing at all then URIB */ +	MCAST_MIX_DISTANCE,   /* MRIB & URIB, lower distance wins */ +	MCAST_MIX_PFXLEN,     /* MRIB & URIB, longer prefix wins */ +			      /* on equal value, MRIB wins for last 2 */  }; -extern void multicast_mode_ipv4_set (enum multicast_mode mode); -extern enum multicast_mode multicast_mode_ipv4_get (void); +extern void multicast_mode_ipv4_set(enum multicast_mode mode); +extern enum multicast_mode multicast_mode_ipv4_get(void);  extern int nexthop_has_fib_child(struct nexthop *); -extern void rib_lookup_and_dump (struct prefix_ipv4 *, vrf_id_t); -extern void rib_lookup_and_pushup (struct prefix_ipv4 *, vrf_id_t); +extern void rib_lookup_and_dump(struct prefix_ipv4 *, vrf_id_t); +extern void rib_lookup_and_pushup(struct prefix_ipv4 *, vrf_id_t);  #define rib_dump(prefix, src, rib) _rib_dump(__func__, prefix, src, rib) -extern void _rib_dump (const char *, -		       union prefixconstptr, -		       union prefixconstptr, const struct rib *); -extern int rib_lookup_ipv4_route (struct prefix_ipv4 *, union sockunion *, -                                  vrf_id_t); +extern void _rib_dump(const char *, union prefixconstptr, union prefixconstptr, +		      const struct rib *); +extern int rib_lookup_ipv4_route(struct prefix_ipv4 *, union sockunion *, +				 vrf_id_t);  #define ZEBRA_RIB_LOOKUP_ERROR -1  #define ZEBRA_RIB_FOUND_EXACT 0  #define ZEBRA_RIB_FOUND_NOGATE 1  #define ZEBRA_RIB_FOUND_CONNECTED 2  #define ZEBRA_RIB_NOTFOUND 3 -extern void rib_nexthop_delete (struct rib *rib, struct nexthop *nexthop); -extern struct nexthop *rib_nexthop_ipv6_add (struct rib *, struct in6_addr *); -extern struct nexthop *rib_nexthop_ipv6_ifindex_add (struct rib *rib, -						     struct in6_addr *ipv6, -						     ifindex_t ifindex); +extern void rib_nexthop_delete(struct rib *rib, struct nexthop *nexthop); +extern struct nexthop *rib_nexthop_ipv6_add(struct rib *, struct in6_addr *); +extern struct nexthop *rib_nexthop_ipv6_ifindex_add(struct rib *rib, +						    struct in6_addr *ipv6, +						    ifindex_t ifindex);  extern int is_zebra_valid_kernel_table(u_int32_t table_id);  extern int is_zebra_main_routing_table(u_int32_t table_id); -extern int zebra_check_addr (struct prefix *p); +extern int zebra_check_addr(struct prefix *p); -extern void rib_addnode (struct route_node *rn, struct rib *rib, int process); -extern void rib_delnode (struct route_node *rn, struct rib *rib); -extern int rib_install_kernel (struct route_node *rn, struct rib *rib, struct rib *old); -extern int rib_uninstall_kernel (struct route_node *rn, struct rib *rib); +extern void rib_addnode(struct route_node *rn, struct rib *rib, int process); +extern void rib_delnode(struct route_node *rn, struct rib *rib); +extern int rib_install_kernel(struct route_node *rn, struct rib *rib, +			      struct rib *old); +extern int rib_uninstall_kernel(struct route_node *rn, struct rib *rib);  /* NOTE:   * All rib_add function will not just add prefix into RIB, but   * also implicitly withdraw equal prefix of same type. */ -extern int rib_add (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, -		    u_short instance, int flags, struct prefix *p, -		    struct prefix_ipv6 *src_p, union g_addr *gate, union g_addr *src, -		    ifindex_t ifindex, u_int32_t table_id, -		    u_int32_t, u_int32_t, u_char); - -extern int rib_add_multipath (afi_t afi, safi_t safi, struct prefix *, -			      struct prefix_ipv6 *src_p, struct rib *); - -extern void rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, -			u_short instance, int flags, struct prefix *p, -			struct prefix_ipv6 *src_p, union g_addr *gate, -			ifindex_t ifindex, u_int32_t table_id); - -extern struct rib *rib_match (afi_t afi, safi_t safi, vrf_id_t, union g_addr *, -			      struct route_node **rn_out); -extern struct rib *rib_match_ipv4_multicast (vrf_id_t vrf_id, struct in_addr addr, -					     struct route_node **rn_out); - -extern struct rib *rib_lookup_ipv4 (struct prefix_ipv4 *, vrf_id_t); - -extern void rib_update (vrf_id_t, rib_update_event_t); -extern void rib_weed_tables (void); -extern void rib_sweep_route (void); -extern void rib_close_table (struct route_table *); -extern void rib_init (void); -extern unsigned long rib_score_proto (u_char proto, u_short instance); -extern void rib_queue_add (struct route_node *rn); -extern void meta_queue_free (struct meta_queue *mq); +extern int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, +		   u_short instance, int flags, struct prefix *p, +		   struct prefix_ipv6 *src_p, union g_addr *gate, +		   union g_addr *src, ifindex_t ifindex, u_int32_t table_id, +		   u_int32_t, u_int32_t, u_char); + +extern int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *, +			     struct prefix_ipv6 *src_p, struct rib *); + +extern void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, +		       u_short instance, int flags, struct prefix *p, +		       struct prefix_ipv6 *src_p, union g_addr *gate, +		       ifindex_t ifindex, u_int32_t table_id); + +extern struct rib *rib_match(afi_t afi, safi_t safi, vrf_id_t, union g_addr *, +			     struct route_node **rn_out); +extern struct rib *rib_match_ipv4_multicast(vrf_id_t vrf_id, +					    struct in_addr addr, +					    struct route_node **rn_out); + +extern struct rib *rib_lookup_ipv4(struct prefix_ipv4 *, vrf_id_t); + +extern void rib_update(vrf_id_t, rib_update_event_t); +extern void rib_weed_tables(void); +extern void rib_sweep_route(void); +extern void rib_close_table(struct route_table *); +extern void rib_init(void); +extern unsigned long rib_score_proto(u_char proto, u_short instance); +extern void rib_queue_add(struct route_node *rn); +extern void meta_queue_free(struct meta_queue *mq);  extern struct route_table *rib_table_ipv6; -extern void rib_unlink (struct route_node *, struct rib *); -extern int rib_gc_dest (struct route_node *rn); -extern struct route_table *rib_tables_iter_next (rib_tables_iter_t *iter); +extern void rib_unlink(struct route_node *, struct rib *); +extern int rib_gc_dest(struct route_node *rn); +extern struct route_table *rib_tables_iter_next(rib_tables_iter_t *iter);  extern u_char route_distance(int type); @@ -389,19 +384,17 @@ extern u_char route_distance(int type);  /*   * rib_table_info   */ -static inline rib_table_info_t * -rib_table_info (struct route_table *table) +static inline rib_table_info_t *rib_table_info(struct route_table *table)  { -  return (rib_table_info_t *) table->info; +	return (rib_table_info_t *)table->info;  }  /*   * rib_dest_from_rnode   */ -static inline rib_dest_t * -rib_dest_from_rnode (struct route_node *rn) +static inline rib_dest_t *rib_dest_from_rnode(struct route_node *rn)  { -  return (rib_dest_t *) rn->info; +	return (rib_dest_t *)rn->info;  }  /* @@ -410,25 +403,23 @@ rib_dest_from_rnode (struct route_node *rn)   * Returns a pointer to the list of routes corresponding to the given   * route_node.   */ -static inline struct rib * -rnode_to_ribs (struct route_node *rn) +static inline struct rib *rnode_to_ribs(struct route_node *rn)  { -  rib_dest_t *dest; +	rib_dest_t *dest; -  dest = rib_dest_from_rnode (rn); -  if (!dest) -    return NULL; +	dest = rib_dest_from_rnode(rn); +	if (!dest) +		return NULL; -  return dest->routes; +	return dest->routes;  }  /*   * rib_dest_prefix   */ -static inline struct prefix * -rib_dest_prefix (rib_dest_t *dest) +static inline struct prefix *rib_dest_prefix(rib_dest_t *dest)  { -  return &dest->rnode->p; +	return &dest->rnode->p;  }  /* @@ -436,39 +427,35 @@ rib_dest_prefix (rib_dest_t *dest)   *   * Returns the address family that the destination is for.   */ -static inline u_char -rib_dest_af (rib_dest_t *dest) +static inline u_char rib_dest_af(rib_dest_t *dest)  { -  return dest->rnode->p.family; +	return dest->rnode->p.family;  }  /*   * rib_dest_table   */ -static inline struct route_table * -rib_dest_table (rib_dest_t *dest) +static inline struct route_table *rib_dest_table(rib_dest_t *dest)  { -  return srcdest_rnode_table(dest->rnode); +	return srcdest_rnode_table(dest->rnode);  }  /*   * rib_dest_vrf   */ -static inline struct zebra_vrf * -rib_dest_vrf (rib_dest_t *dest) +static inline struct zebra_vrf *rib_dest_vrf(rib_dest_t *dest)  { -  return rib_table_info (rib_dest_table (dest))->zvrf; +	return rib_table_info(rib_dest_table(dest))->zvrf;  }  /*   * rib_tables_iter_init   */ -static inline void -rib_tables_iter_init (rib_tables_iter_t *iter) +static inline void rib_tables_iter_init(rib_tables_iter_t *iter)  { -  memset (iter, 0, sizeof (*iter)); -  iter->state = RIB_TABLES_ITER_S_INIT; +	memset(iter, 0, sizeof(*iter)); +	iter->state = RIB_TABLES_ITER_S_INIT;  }  /* @@ -477,21 +464,20 @@ rib_tables_iter_init (rib_tables_iter_t *iter)   * Returns TRUE if this iterator has started iterating over the set of   * tables.   */ -static inline int -rib_tables_iter_started (rib_tables_iter_t *iter) +static inline int rib_tables_iter_started(rib_tables_iter_t *iter)  { -  return iter->state != RIB_TABLES_ITER_S_INIT; +	return iter->state != RIB_TABLES_ITER_S_INIT;  }  /*   * rib_tables_iter_cleanup   */ -static inline void -rib_tables_iter_cleanup (rib_tables_iter_t *iter) +static inline void rib_tables_iter_cleanup(rib_tables_iter_t *iter)  { -  iter->state = RIB_TABLES_ITER_S_DONE; +	iter->state = RIB_TABLES_ITER_S_DONE;  } -DECLARE_HOOK(rib_update, (struct route_node *rn, const char *reason), (rn, reason)) +DECLARE_HOOK(rib_update, (struct route_node * rn, const char *reason), +	     (rn, reason))  #endif /*_ZEBRA_RIB_H */ diff --git a/zebra/router-id.c b/zebra/router-id.c index b1e786d0c8..a031fc2043 100644 --- a/zebra/router-id.c +++ b/zebra/router-id.c @@ -1,7 +1,7 @@  /*   * Router ID for zebra daemon.   * - * Copyright (C) 2004 James R. Leu  + * Copyright (C) 2004 James R. Leu   *   * This file is part of Quagga routing suite.   * @@ -47,171 +47,161 @@  /* master zebra server structure */  extern struct zebra_t zebrad; -static struct connected * -router_id_find_node (struct list *l, struct connected *ifc) +static struct connected *router_id_find_node(struct list *l, +					     struct connected *ifc)  { -  struct listnode *node; -  struct connected *c; +	struct listnode *node; +	struct connected *c; -  for (ALL_LIST_ELEMENTS_RO (l, node, c)) -    if (prefix_same (ifc->address, c->address)) -      return c; +	for (ALL_LIST_ELEMENTS_RO(l, node, c)) +		if (prefix_same(ifc->address, c->address)) +			return c; -  return NULL; +	return NULL;  } -static int -router_id_bad_address (struct connected *ifc) +static int router_id_bad_address(struct connected *ifc)  { -  if (ifc->address->family != AF_INET) -    return 1; -   -  /* non-redistributable addresses shouldn't be used for RIDs either */ -  if (!zebra_check_addr (ifc->address)) -    return 1; -   -  return 0; +	if (ifc->address->family != AF_INET) +		return 1; + +	/* non-redistributable addresses shouldn't be used for RIDs either */ +	if (!zebra_check_addr(ifc->address)) +		return 1; + +	return 0;  } -void -router_id_get (struct prefix *p, vrf_id_t vrf_id) +void router_id_get(struct prefix *p, vrf_id_t vrf_id)  { -  struct listnode *node; -  struct connected *c; -  struct zebra_vrf *zvrf = vrf_info_get (vrf_id); - -  p->u.prefix4.s_addr = 0; -  p->family = AF_INET; -  p->prefixlen = 32; - -  if (zvrf->rid_user_assigned.u.prefix4.s_addr) -    p->u.prefix4.s_addr = zvrf->rid_user_assigned.u.prefix4.s_addr; -  else if (!list_isempty (zvrf->rid_lo_sorted_list)) -    { -      node = listtail (zvrf->rid_lo_sorted_list); -      c = listgetdata (node); -      p->u.prefix4.s_addr = c->address->u.prefix4.s_addr; -    } -  else if (!list_isempty (zvrf->rid_all_sorted_list)) -    { -      node = listtail (zvrf->rid_all_sorted_list); -      c = listgetdata (node); -      p->u.prefix4.s_addr = c->address->u.prefix4.s_addr; -    } +	struct listnode *node; +	struct connected *c; +	struct zebra_vrf *zvrf = vrf_info_get(vrf_id); + +	p->u.prefix4.s_addr = 0; +	p->family = AF_INET; +	p->prefixlen = 32; + +	if (zvrf->rid_user_assigned.u.prefix4.s_addr) +		p->u.prefix4.s_addr = zvrf->rid_user_assigned.u.prefix4.s_addr; +	else if (!list_isempty(zvrf->rid_lo_sorted_list)) { +		node = listtail(zvrf->rid_lo_sorted_list); +		c = listgetdata(node); +		p->u.prefix4.s_addr = c->address->u.prefix4.s_addr; +	} else if (!list_isempty(zvrf->rid_all_sorted_list)) { +		node = listtail(zvrf->rid_all_sorted_list); +		c = listgetdata(node); +		p->u.prefix4.s_addr = c->address->u.prefix4.s_addr; +	}  } -static void -router_id_set (struct prefix *p, vrf_id_t vrf_id) +static void router_id_set(struct prefix *p, vrf_id_t vrf_id)  { -  struct prefix p2; -  struct listnode *node; -  struct zserv *client; -  struct zebra_vrf *zvrf; - -  if (p->u.prefix4.s_addr == 0) /* unset */ -    { -      zvrf = vrf_info_lookup (vrf_id); -      if (! zvrf) -        return; -    } -  else /* set */ -    zvrf = vrf_info_get (vrf_id); - -  zvrf->rid_user_assigned.u.prefix4.s_addr = p->u.prefix4.s_addr; - -  router_id_get (&p2, vrf_id); - -  for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client)) -    zsend_router_id_update (client, &p2, vrf_id); +	struct prefix p2; +	struct listnode *node; +	struct zserv *client; +	struct zebra_vrf *zvrf; + +	if (p->u.prefix4.s_addr == 0) /* unset */ +	{ +		zvrf = vrf_info_lookup(vrf_id); +		if (!zvrf) +			return; +	} else /* set */ +		zvrf = vrf_info_get(vrf_id); + +	zvrf->rid_user_assigned.u.prefix4.s_addr = p->u.prefix4.s_addr; + +	router_id_get(&p2, vrf_id); + +	for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) +		zsend_router_id_update(client, &p2, vrf_id);  } -void -router_id_add_address (struct connected *ifc) +void router_id_add_address(struct connected *ifc)  { -  struct list *l = NULL; -  struct listnode *node; -  struct prefix before; -  struct prefix after; -  struct zserv *client; -  struct zebra_vrf *zvrf = vrf_info_get (ifc->ifp->vrf_id); - -  if (router_id_bad_address (ifc)) -    return; - -  router_id_get (&before, zvrf_id (zvrf)); - -  if (!strncmp (ifc->ifp->name, "lo", 2) -      || !strncmp (ifc->ifp->name, "dummy", 5)) -    l = zvrf->rid_lo_sorted_list; -  else -    l = zvrf->rid_all_sorted_list; -   -  if (!router_id_find_node (l, ifc)) -    listnode_add_sort (l, ifc); - -  router_id_get (&after, zvrf_id (zvrf)); - -  if (prefix_same (&before, &after)) -    return; - -  for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client)) -    zsend_router_id_update (client, &after, zvrf_id (zvrf)); +	struct list *l = NULL; +	struct listnode *node; +	struct prefix before; +	struct prefix after; +	struct zserv *client; +	struct zebra_vrf *zvrf = vrf_info_get(ifc->ifp->vrf_id); + +	if (router_id_bad_address(ifc)) +		return; + +	router_id_get(&before, zvrf_id(zvrf)); + +	if (!strncmp(ifc->ifp->name, "lo", 2) +	    || !strncmp(ifc->ifp->name, "dummy", 5)) +		l = zvrf->rid_lo_sorted_list; +	else +		l = zvrf->rid_all_sorted_list; + +	if (!router_id_find_node(l, ifc)) +		listnode_add_sort(l, ifc); + +	router_id_get(&after, zvrf_id(zvrf)); + +	if (prefix_same(&before, &after)) +		return; + +	for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) +		zsend_router_id_update(client, &after, zvrf_id(zvrf));  } -void -router_id_del_address (struct connected *ifc) +void router_id_del_address(struct connected *ifc)  { -  struct connected *c; -  struct list *l; -  struct prefix after; -  struct prefix before; -  struct listnode *node; -  struct zserv *client; -  struct zebra_vrf *zvrf = vrf_info_get (ifc->ifp->vrf_id); +	struct connected *c; +	struct list *l; +	struct prefix after; +	struct prefix before; +	struct listnode *node; +	struct zserv *client; +	struct zebra_vrf *zvrf = vrf_info_get(ifc->ifp->vrf_id); -  if (router_id_bad_address (ifc)) -    return; +	if (router_id_bad_address(ifc)) +		return; -  router_id_get (&before, zvrf_id (zvrf)); +	router_id_get(&before, zvrf_id(zvrf)); -  if (!strncmp (ifc->ifp->name, "lo", 2) -      || !strncmp (ifc->ifp->name, "dummy", 5)) -    l = zvrf->rid_lo_sorted_list; -  else -    l = zvrf->rid_all_sorted_list; +	if (!strncmp(ifc->ifp->name, "lo", 2) +	    || !strncmp(ifc->ifp->name, "dummy", 5)) +		l = zvrf->rid_lo_sorted_list; +	else +		l = zvrf->rid_all_sorted_list; -  if ((c = router_id_find_node (l, ifc))) -    listnode_delete (l, c); +	if ((c = router_id_find_node(l, ifc))) +		listnode_delete(l, c); -  router_id_get (&after, zvrf_id (zvrf)); +	router_id_get(&after, zvrf_id(zvrf)); -  if (prefix_same (&before, &after)) -    return; +	if (prefix_same(&before, &after)) +		return; -  for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client)) -    zsend_router_id_update (client, &after, zvrf_id (zvrf)); +	for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) +		zsend_router_id_update(client, &after, zvrf_id(zvrf));  } -void -router_id_write (struct vty *vty) +void router_id_write(struct vty *vty)  { -  struct vrf *vrf; -  struct zebra_vrf *zvrf; - -  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) -    if ((zvrf = vrf->info) != NULL) -      if (zvrf->rid_user_assigned.u.prefix4.s_addr) -        { -          if (zvrf_id (zvrf) == VRF_DEFAULT) -            vty_out (vty, "router-id %s%s", -                     inet_ntoa (zvrf->rid_user_assigned.u.prefix4), -                     VTY_NEWLINE); -          else -            vty_out (vty, "router-id %s vrf %s%s", -                     inet_ntoa (zvrf->rid_user_assigned.u.prefix4), -                     zvrf_name (zvrf), -                     VTY_NEWLINE); -        } +	struct vrf *vrf; +	struct zebra_vrf *zvrf; + +	RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) +	if ((zvrf = vrf->info) != NULL) +		if (zvrf->rid_user_assigned.u.prefix4.s_addr) { +			if (zvrf_id(zvrf) == VRF_DEFAULT) +				vty_out(vty, "router-id %s%s", +					inet_ntoa(zvrf->rid_user_assigned.u +							  .prefix4), +					VTY_NEWLINE); +			else +				vty_out(vty, "router-id %s vrf %s%s", +					inet_ntoa(zvrf->rid_user_assigned.u +							  .prefix4), +					zvrf_name(zvrf), VTY_NEWLINE); +		}  }  DEFUN (router_id, @@ -221,25 +211,25 @@ DEFUN (router_id,         "IP address to use for router-id\n"         VRF_CMD_HELP_STR)  { -  int idx_ipv4 = 1; -  int idx_name = 3; +	int idx_ipv4 = 1; +	int idx_name = 3; -  struct prefix rid; -  vrf_id_t vrf_id = VRF_DEFAULT; +	struct prefix rid; +	vrf_id_t vrf_id = VRF_DEFAULT; -  rid.u.prefix4.s_addr = inet_addr (argv[idx_ipv4]->arg); -  if (!rid.u.prefix4.s_addr) -    return CMD_WARNING; +	rid.u.prefix4.s_addr = inet_addr(argv[idx_ipv4]->arg); +	if (!rid.u.prefix4.s_addr) +		return CMD_WARNING; -  rid.prefixlen = 32; -  rid.family = AF_INET; +	rid.prefixlen = 32; +	rid.family = AF_INET; -  if (argc > 2) -    VRF_GET_ID (vrf_id, argv[idx_name]->arg); +	if (argc > 2) +		VRF_GET_ID(vrf_id, argv[idx_name]->arg); -  router_id_set (&rid, vrf_id); +	router_id_set(&rid, vrf_id); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (no_router_id, @@ -250,54 +240,52 @@ DEFUN (no_router_id,         "IP address to use for router-id\n"         VRF_CMD_HELP_STR)  { -  int idx_name = 4; +	int idx_name = 4; -  struct prefix rid; -  vrf_id_t vrf_id = VRF_DEFAULT; +	struct prefix rid; +	vrf_id_t vrf_id = VRF_DEFAULT; -  rid.u.prefix4.s_addr = 0; -  rid.prefixlen = 0; -  rid.family = AF_INET; +	rid.u.prefix4.s_addr = 0; +	rid.prefixlen = 0; +	rid.family = AF_INET; -  if (argc > 3) -    VRF_GET_ID (vrf_id, argv[idx_name]->arg); +	if (argc > 3) +		VRF_GET_ID(vrf_id, argv[idx_name]->arg); -  router_id_set (&rid, vrf_id); +	router_id_set(&rid, vrf_id); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  } - -static int -router_id_cmp (void *a, void *b) +static int router_id_cmp(void *a, void *b)  { -  const struct connected *ifa = (const struct connected *)a; -  const struct connected *ifb = (const struct connected *)b; +	const struct connected *ifa = (const struct connected *)a; +	const struct connected *ifb = (const struct connected *)b; -  return IPV4_ADDR_CMP(&ifa->address->u.prefix4.s_addr,&ifb->address->u.prefix4.s_addr); +	return IPV4_ADDR_CMP(&ifa->address->u.prefix4.s_addr, +			     &ifb->address->u.prefix4.s_addr);  } -void -router_id_cmd_init (void) +void router_id_cmd_init(void)  { -  install_element (CONFIG_NODE, &router_id_cmd); -  install_element (CONFIG_NODE, &no_router_id_cmd); +	install_element(CONFIG_NODE, &router_id_cmd); +	install_element(CONFIG_NODE, &no_router_id_cmd);  } -void -router_id_init (struct zebra_vrf *zvrf) +void router_id_init(struct zebra_vrf *zvrf)  { -  zvrf->rid_all_sorted_list = &zvrf->_rid_all_sorted_list; -  zvrf->rid_lo_sorted_list = &zvrf->_rid_lo_sorted_list; +	zvrf->rid_all_sorted_list = &zvrf->_rid_all_sorted_list; +	zvrf->rid_lo_sorted_list = &zvrf->_rid_lo_sorted_list; -  memset (zvrf->rid_all_sorted_list, 0, sizeof (zvrf->_rid_all_sorted_list)); -  memset (zvrf->rid_lo_sorted_list, 0, sizeof (zvrf->_rid_lo_sorted_list)); -  memset (&zvrf->rid_user_assigned, 0, sizeof (zvrf->rid_user_assigned)); +	memset(zvrf->rid_all_sorted_list, 0, +	       sizeof(zvrf->_rid_all_sorted_list)); +	memset(zvrf->rid_lo_sorted_list, 0, sizeof(zvrf->_rid_lo_sorted_list)); +	memset(&zvrf->rid_user_assigned, 0, sizeof(zvrf->rid_user_assigned)); -  zvrf->rid_all_sorted_list->cmp = router_id_cmp; -  zvrf->rid_lo_sorted_list->cmp = router_id_cmp; +	zvrf->rid_all_sorted_list->cmp = router_id_cmp; +	zvrf->rid_lo_sorted_list->cmp = router_id_cmp; -  zvrf->rid_user_assigned.family = AF_INET; -  zvrf->rid_user_assigned.prefixlen = 32; +	zvrf->rid_user_assigned.family = AF_INET; +	zvrf->rid_user_assigned.prefixlen = 32;  } diff --git a/zebra/rt.h b/zebra/rt.h index 75d234ce83..f51858aace 100644 --- a/zebra/rt.h +++ b/zebra/rt.h @@ -17,7 +17,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #ifndef _ZEBRA_RT_H @@ -29,17 +29,17 @@  #include "zebra/zebra_ns.h"  #include "zebra/zebra_mpls.h" -extern int kernel_route_rib (struct prefix *, struct prefix *, -                             struct rib *, struct rib *); +extern int kernel_route_rib(struct prefix *, struct prefix *, struct rib *, +			    struct rib *); -extern int kernel_address_add_ipv4 (struct interface *, struct connected *); -extern int kernel_address_delete_ipv4 (struct interface *, struct connected *); -extern int kernel_neigh_update (int, int, uint32_t, char *, int); +extern int kernel_address_add_ipv4(struct interface *, struct connected *); +extern int kernel_address_delete_ipv4(struct interface *, struct connected *); +extern int kernel_neigh_update(int, int, uint32_t, char *, int); -extern int kernel_add_lsp (zebra_lsp_t *); -extern int kernel_upd_lsp (zebra_lsp_t *); -extern int kernel_del_lsp (zebra_lsp_t *); -extern int mpls_kernel_init (void); +extern int kernel_add_lsp(zebra_lsp_t *); +extern int kernel_upd_lsp(zebra_lsp_t *); +extern int kernel_del_lsp(zebra_lsp_t *); +extern int mpls_kernel_init(void); -extern int kernel_get_ipmr_sg_stats (void *mroute); +extern int kernel_get_ipmr_sg_stats(void *mroute);  #endif /* _ZEBRA_RT_H */ diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index a544593dd6..80c7c09229 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -96,517 +96,507 @@  #endif  /* End of temporary definitions */ -struct gw_family_t -{ -  u_int16_t     filler; -  u_int16_t     family; -  union g_addr  gate; +struct gw_family_t { +	u_int16_t filler; +	u_int16_t family; +	union g_addr gate;  };  /*  Pending: create an efficient table_id (in a tree/hash) based lookup)   */ -static vrf_id_t -vrf_lookup_by_table (u_int32_t table_id) +static vrf_id_t vrf_lookup_by_table(u_int32_t table_id)  { -  struct vrf *vrf; -  struct zebra_vrf *zvrf; +	struct vrf *vrf; +	struct zebra_vrf *zvrf; -  RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) -    { -      if ((zvrf = vrf->info) == NULL || -          (zvrf->table_id != table_id)) -        continue; +	RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id) +	{ +		if ((zvrf = vrf->info) == NULL || (zvrf->table_id != table_id)) +			continue; -      return zvrf_id (zvrf); -    } +		return zvrf_id(zvrf); +	} -  return VRF_DEFAULT; +	return VRF_DEFAULT;  }  /* Looking up routing table by netlink interface. */ -static int -netlink_route_change_read_unicast (struct sockaddr_nl *snl, struct nlmsghdr *h, -                                   ns_id_t ns_id, int startup) +static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, +					     struct nlmsghdr *h, ns_id_t ns_id, +					     int startup)  { -  int len; -  struct rtmsg *rtm; -  struct rtattr *tb[RTA_MAX + 1]; -  u_char flags = 0; -  struct prefix p; -  struct prefix_ipv6 src_p; -  vrf_id_t vrf_id = VRF_DEFAULT; - -  char anyaddr[16] = { 0 }; - -  int index = 0; -  int table; -  int metric = 0; -  u_int32_t mtu = 0; - -  void *dest = NULL; -  void *gate = NULL; -  void *prefsrc = NULL;		/* IPv4 preferred source host address */ -  void *src = NULL;		/* IPv6 srcdest   source prefix */ - -  rtm = NLMSG_DATA (h); - -  if (startup && h->nlmsg_type != RTM_NEWROUTE) -    return 0; -  if (startup && rtm->rtm_type != RTN_UNICAST) -    return 0; - -  len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct rtmsg)); -  if (len < 0) -    return -1; - -  memset (tb, 0, sizeof tb); -  netlink_parse_rtattr (tb, RTA_MAX, RTM_RTA (rtm), len); - -  if (rtm->rtm_flags & RTM_F_CLONED) -    return 0; -  if (rtm->rtm_protocol == RTPROT_REDIRECT) -    return 0; -  if (rtm->rtm_protocol == RTPROT_KERNEL) -    return 0; - -  if (!startup && -      rtm->rtm_protocol == RTPROT_ZEBRA && -      h->nlmsg_type == RTM_NEWROUTE) -    return 0; - -  /* We don't care about change notifications for the MPLS table. */ -  /* TODO: Revisit this. */ -  if (rtm->rtm_family == AF_MPLS) -    return 0; - -  /* Table corresponding to route. */ -  if (tb[RTA_TABLE]) -    table = *(int *) RTA_DATA (tb[RTA_TABLE]); -  else -    table = rtm->rtm_table; - -  /* Map to VRF */ -  vrf_id = vrf_lookup_by_table(table); -  if (vrf_id == VRF_DEFAULT) -    { -      if (!is_zebra_valid_kernel_table(table) && -          !is_zebra_main_routing_table(table)) -        return 0; -    } - -  /* Route which inserted by Zebra. */ -  if (rtm->rtm_protocol == RTPROT_ZEBRA) -    flags |= ZEBRA_FLAG_SELFROUTE; - -  if (tb[RTA_OIF]) -    index = *(int *) RTA_DATA (tb[RTA_OIF]); - -  if (tb[RTA_DST]) -    dest = RTA_DATA (tb[RTA_DST]); -  else -    dest = anyaddr; - -  if (tb[RTA_SRC]) -    src = RTA_DATA (tb[RTA_SRC]); -  else -    src = anyaddr; - -  if (tb[RTA_PREFSRC]) -    prefsrc = RTA_DATA (tb[RTA_PREFSRC]); - -  if (tb[RTA_GATEWAY]) -    gate = RTA_DATA (tb[RTA_GATEWAY]); - -  if (h->nlmsg_type == RTM_NEWROUTE) -    { -      if (tb[RTA_PRIORITY]) -        metric = *(int *) RTA_DATA(tb[RTA_PRIORITY]); - -      if (tb[RTA_METRICS]) -        { -          struct rtattr *mxrta[RTAX_MAX+1]; - -          memset (mxrta, 0, sizeof mxrta); -          netlink_parse_rtattr (mxrta, RTAX_MAX, RTA_DATA(tb[RTA_METRICS]), -                                RTA_PAYLOAD(tb[RTA_METRICS])); - -          if (mxrta[RTAX_MTU]) -            mtu = *(u_int32_t *) RTA_DATA(mxrta[RTAX_MTU]); -        } -    } - -  if (rtm->rtm_family == AF_INET) -    { -      p.family = AF_INET; -      memcpy (&p.u.prefix4, dest, 4); -      p.prefixlen = rtm->rtm_dst_len; -    } -  else if (rtm->rtm_family == AF_INET6) -    { -      p.family = AF_INET6; -      memcpy (&p.u.prefix6, dest, 16); -      p.prefixlen = rtm->rtm_dst_len; - -      src_p.family = AF_INET6; -      memcpy (&src_p.prefix, src, 16); -      src_p.prefixlen = rtm->rtm_src_len; -    } - -  if (rtm->rtm_src_len != 0) -    { -      char buf[PREFIX_STRLEN]; -      zlog_warn ("unsupported IPv[4|6] sourcedest route (dest %s vrf %u)", -                 prefix2str (&p, buf, sizeof(buf)), vrf_id); -      return 0; -    } - -  if (IS_ZEBRA_DEBUG_KERNEL) -    { -      char buf[PREFIX_STRLEN]; -      char buf2[PREFIX_STRLEN]; -      zlog_debug ("%s %s%s%s vrf %u", -                  nl_msg_type_to_str (h->nlmsg_type), -                  prefix2str (&p, buf, sizeof(buf)), -                  src_p.prefixlen ? " from " : "", -                  src_p.prefixlen ? prefix2str(&src_p, buf2, sizeof(buf2)) : "", -                  vrf_id); -    } - -  afi_t afi = AFI_IP; -  if (rtm->rtm_family == AF_INET6) -    afi = AFI_IP6; - -  if (h->nlmsg_type == RTM_NEWROUTE) -    { -      if (!tb[RTA_MULTIPATH]) -        rib_add (afi, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL, -                 0, flags, &p, NULL, gate, prefsrc, index, -                 table, metric, mtu, 0); -      else -        { -          /* This is a multipath route */ - -          struct rib *rib; -          struct rtnexthop *rtnh = -            (struct rtnexthop *) RTA_DATA (tb[RTA_MULTIPATH]); - -          len = RTA_PAYLOAD (tb[RTA_MULTIPATH]); - -          rib = XCALLOC (MTYPE_RIB, sizeof (struct rib)); -          rib->type = ZEBRA_ROUTE_KERNEL; -          rib->distance = 0; -          rib->flags = flags; -          rib->metric = metric; -          rib->mtu = mtu; -          rib->vrf_id = vrf_id; -          rib->table = table; -          rib->nexthop_num = 0; -          rib->uptime = time (NULL); - -          for (;;) -            { -              if (len < (int) sizeof (*rtnh) || rtnh->rtnh_len > len) -                break; - -              index = rtnh->rtnh_ifindex; -              gate = 0; -              if (rtnh->rtnh_len > sizeof (*rtnh)) -                { -                  memset (tb, 0, sizeof (tb)); -                  netlink_parse_rtattr (tb, RTA_MAX, RTNH_DATA (rtnh), -                                        rtnh->rtnh_len - sizeof (*rtnh)); -                  if (tb[RTA_GATEWAY]) -                    gate = RTA_DATA (tb[RTA_GATEWAY]); -                } - -              if (gate) -                { -                  if (rtm->rtm_family == AF_INET) -                    { -                      if (index) -                        rib_nexthop_ipv4_ifindex_add (rib, gate, prefsrc, index); -                      else -                        rib_nexthop_ipv4_add (rib, gate, prefsrc); -                    } -                  else if (rtm->rtm_family == AF_INET6) -                    { -                      if (index) -                        rib_nexthop_ipv6_ifindex_add (rib, gate, index); -                      else -                        rib_nexthop_ipv6_add (rib,gate); -                    } -                } -              else -                rib_nexthop_ifindex_add (rib, index); - -              len -= NLMSG_ALIGN(rtnh->rtnh_len); -              rtnh = RTNH_NEXT(rtnh); -            } - -          zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, -                                 rib->nexthop_num); -          if (rib->nexthop_num == 0) -            XFREE (MTYPE_RIB, rib); -          else -            rib_add_multipath (AFI_IP, SAFI_UNICAST, &p, NULL, rib); -        } -    } -  else -    { -      if (!tb[RTA_MULTIPATH]) -        rib_delete (afi, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL, 0, flags, -                    &p, NULL, gate, index, table); -      else -        { -          struct rtnexthop *rtnh = -            (struct rtnexthop *) RTA_DATA (tb[RTA_MULTIPATH]); - -          len = RTA_PAYLOAD (tb[RTA_MULTIPATH]); - -          for (;;) -            { -              if (len < (int) sizeof (*rtnh) || rtnh->rtnh_len > len) -                break; - -              gate = NULL; -              if (rtnh->rtnh_len > sizeof (*rtnh)) -                { -                  memset (tb, 0, sizeof (tb)); -                  netlink_parse_rtattr (tb, RTA_MAX, RTNH_DATA (rtnh), -                                        rtnh->rtnh_len - sizeof (*rtnh)); -                  if (tb[RTA_GATEWAY]) -                    gate = RTA_DATA (tb[RTA_GATEWAY]); -                } - -              if (gate) -                rib_delete (afi, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL, 0, flags, -                            &p, NULL, gate, index, table); - -              len -= NLMSG_ALIGN(rtnh->rtnh_len); -              rtnh = RTNH_NEXT(rtnh); -            } -        } -    } - -  return 0; +	int len; +	struct rtmsg *rtm; +	struct rtattr *tb[RTA_MAX + 1]; +	u_char flags = 0; +	struct prefix p; +	struct prefix_ipv6 src_p; +	vrf_id_t vrf_id = VRF_DEFAULT; + +	char anyaddr[16] = {0}; + +	int index = 0; +	int table; +	int metric = 0; +	u_int32_t mtu = 0; + +	void *dest = NULL; +	void *gate = NULL; +	void *prefsrc = NULL; /* IPv4 preferred source host address */ +	void *src = NULL;     /* IPv6 srcdest   source prefix */ + +	rtm = NLMSG_DATA(h); + +	if (startup && h->nlmsg_type != RTM_NEWROUTE) +		return 0; +	if (startup && rtm->rtm_type != RTN_UNICAST) +		return 0; + +	len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct rtmsg)); +	if (len < 0) +		return -1; + +	memset(tb, 0, sizeof tb); +	netlink_parse_rtattr(tb, RTA_MAX, RTM_RTA(rtm), len); + +	if (rtm->rtm_flags & RTM_F_CLONED) +		return 0; +	if (rtm->rtm_protocol == RTPROT_REDIRECT) +		return 0; +	if (rtm->rtm_protocol == RTPROT_KERNEL) +		return 0; + +	if (!startup && rtm->rtm_protocol == RTPROT_ZEBRA +	    && h->nlmsg_type == RTM_NEWROUTE) +		return 0; + +	/* We don't care about change notifications for the MPLS table. */ +	/* TODO: Revisit this. */ +	if (rtm->rtm_family == AF_MPLS) +		return 0; + +	/* Table corresponding to route. */ +	if (tb[RTA_TABLE]) +		table = *(int *)RTA_DATA(tb[RTA_TABLE]); +	else +		table = rtm->rtm_table; + +	/* Map to VRF */ +	vrf_id = vrf_lookup_by_table(table); +	if (vrf_id == VRF_DEFAULT) { +		if (!is_zebra_valid_kernel_table(table) +		    && !is_zebra_main_routing_table(table)) +			return 0; +	} + +	/* Route which inserted by Zebra. */ +	if (rtm->rtm_protocol == RTPROT_ZEBRA) +		flags |= ZEBRA_FLAG_SELFROUTE; + +	if (tb[RTA_OIF]) +		index = *(int *)RTA_DATA(tb[RTA_OIF]); + +	if (tb[RTA_DST]) +		dest = RTA_DATA(tb[RTA_DST]); +	else +		dest = anyaddr; + +	if (tb[RTA_SRC]) +		src = RTA_DATA(tb[RTA_SRC]); +	else +		src = anyaddr; + +	if (tb[RTA_PREFSRC]) +		prefsrc = RTA_DATA(tb[RTA_PREFSRC]); + +	if (tb[RTA_GATEWAY]) +		gate = RTA_DATA(tb[RTA_GATEWAY]); + +	if (h->nlmsg_type == RTM_NEWROUTE) { +		if (tb[RTA_PRIORITY]) +			metric = *(int *)RTA_DATA(tb[RTA_PRIORITY]); + +		if (tb[RTA_METRICS]) { +			struct rtattr *mxrta[RTAX_MAX + 1]; + +			memset(mxrta, 0, sizeof mxrta); +			netlink_parse_rtattr(mxrta, RTAX_MAX, +					     RTA_DATA(tb[RTA_METRICS]), +					     RTA_PAYLOAD(tb[RTA_METRICS])); + +			if (mxrta[RTAX_MTU]) +				mtu = *(u_int32_t *)RTA_DATA(mxrta[RTAX_MTU]); +		} +	} + +	if (rtm->rtm_family == AF_INET) { +		p.family = AF_INET; +		memcpy(&p.u.prefix4, dest, 4); +		p.prefixlen = rtm->rtm_dst_len; +	} else if (rtm->rtm_family == AF_INET6) { +		p.family = AF_INET6; +		memcpy(&p.u.prefix6, dest, 16); +		p.prefixlen = rtm->rtm_dst_len; + +		src_p.family = AF_INET6; +		memcpy(&src_p.prefix, src, 16); +		src_p.prefixlen = rtm->rtm_src_len; +	} + +	if (rtm->rtm_src_len != 0) { +		char buf[PREFIX_STRLEN]; +		zlog_warn( +			"unsupported IPv[4|6] sourcedest route (dest %s vrf %u)", +			prefix2str(&p, buf, sizeof(buf)), vrf_id); +		return 0; +	} + +	if (IS_ZEBRA_DEBUG_KERNEL) { +		char buf[PREFIX_STRLEN]; +		char buf2[PREFIX_STRLEN]; +		zlog_debug( +			"%s %s%s%s vrf %u", nl_msg_type_to_str(h->nlmsg_type), +			prefix2str(&p, buf, sizeof(buf)), +			src_p.prefixlen ? " from " : "", +			src_p.prefixlen ? prefix2str(&src_p, buf2, sizeof(buf2)) +					: "", +			vrf_id); +	} + +	afi_t afi = AFI_IP; +	if (rtm->rtm_family == AF_INET6) +		afi = AFI_IP6; + +	if (h->nlmsg_type == RTM_NEWROUTE) { +		if (!tb[RTA_MULTIPATH]) +			rib_add(afi, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL, +				0, flags, &p, NULL, gate, prefsrc, index, table, +				metric, mtu, 0); +		else { +			/* This is a multipath route */ + +			struct rib *rib; +			struct rtnexthop *rtnh = +				(struct rtnexthop *)RTA_DATA(tb[RTA_MULTIPATH]); + +			len = RTA_PAYLOAD(tb[RTA_MULTIPATH]); + +			rib = XCALLOC(MTYPE_RIB, sizeof(struct rib)); +			rib->type = ZEBRA_ROUTE_KERNEL; +			rib->distance = 0; +			rib->flags = flags; +			rib->metric = metric; +			rib->mtu = mtu; +			rib->vrf_id = vrf_id; +			rib->table = table; +			rib->nexthop_num = 0; +			rib->uptime = time(NULL); + +			for (;;) { +				if (len < (int)sizeof(*rtnh) +				    || rtnh->rtnh_len > len) +					break; + +				index = rtnh->rtnh_ifindex; +				gate = 0; +				if (rtnh->rtnh_len > sizeof(*rtnh)) { +					memset(tb, 0, sizeof(tb)); +					netlink_parse_rtattr( +						tb, RTA_MAX, RTNH_DATA(rtnh), +						rtnh->rtnh_len - sizeof(*rtnh)); +					if (tb[RTA_GATEWAY]) +						gate = RTA_DATA( +							tb[RTA_GATEWAY]); +				} + +				if (gate) { +					if (rtm->rtm_family == AF_INET) { +						if (index) +							rib_nexthop_ipv4_ifindex_add( +								rib, gate, +								prefsrc, index); +						else +							rib_nexthop_ipv4_add( +								rib, gate, +								prefsrc); +					} else if (rtm->rtm_family +						   == AF_INET6) { +						if (index) +							rib_nexthop_ipv6_ifindex_add( +								rib, gate, +								index); +						else +							rib_nexthop_ipv6_add( +								rib, gate); +					} +				} else +					rib_nexthop_ifindex_add(rib, index); + +				len -= NLMSG_ALIGN(rtnh->rtnh_len); +				rtnh = RTNH_NEXT(rtnh); +			} + +			zserv_nexthop_num_warn(__func__, +					       (const struct prefix *)&p, +					       rib->nexthop_num); +			if (rib->nexthop_num == 0) +				XFREE(MTYPE_RIB, rib); +			else +				rib_add_multipath(AFI_IP, SAFI_UNICAST, &p, +						  NULL, rib); +		} +	} else { +		if (!tb[RTA_MULTIPATH]) +			rib_delete(afi, SAFI_UNICAST, vrf_id, +				   ZEBRA_ROUTE_KERNEL, 0, flags, &p, NULL, gate, +				   index, table); +		else { +			struct rtnexthop *rtnh = +				(struct rtnexthop *)RTA_DATA(tb[RTA_MULTIPATH]); + +			len = RTA_PAYLOAD(tb[RTA_MULTIPATH]); + +			for (;;) { +				if (len < (int)sizeof(*rtnh) +				    || rtnh->rtnh_len > len) +					break; + +				gate = NULL; +				if (rtnh->rtnh_len > sizeof(*rtnh)) { +					memset(tb, 0, sizeof(tb)); +					netlink_parse_rtattr( +						tb, RTA_MAX, RTNH_DATA(rtnh), +						rtnh->rtnh_len - sizeof(*rtnh)); +					if (tb[RTA_GATEWAY]) +						gate = RTA_DATA( +							tb[RTA_GATEWAY]); +				} + +				if (gate) +					rib_delete(afi, SAFI_UNICAST, vrf_id, +						   ZEBRA_ROUTE_KERNEL, 0, flags, +						   &p, NULL, gate, index, +						   table); + +				len -= NLMSG_ALIGN(rtnh->rtnh_len); +				rtnh = RTNH_NEXT(rtnh); +			} +		} +	} + +	return 0;  }  static struct mcast_route_data *mroute = NULL; -static int -netlink_route_change_read_multicast (struct sockaddr_nl *snl, struct nlmsghdr *h, -                                     ns_id_t ns_id, int startup) +static int netlink_route_change_read_multicast(struct sockaddr_nl *snl, +					       struct nlmsghdr *h, +					       ns_id_t ns_id, int startup)  { -  int len; -  struct rtmsg *rtm; -  struct rtattr *tb[RTA_MAX + 1]; -  struct mcast_route_data *m; -  struct mcast_route_data mr; -  int iif = 0; -  int count; -  int oif[256]; -  int oif_count = 0; -  char sbuf[40]; -  char gbuf[40]; -  char oif_list[256] = "\0"; -  vrf_id_t vrf = ns_id; - -  if (mroute) -    m = mroute; -  else -    { -      memset (&mr, 0, sizeof (mr)); -      m = &mr; -    } - -  rtm = NLMSG_DATA (h); - -  len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct rtmsg)); - -  memset (tb, 0, sizeof tb); -  netlink_parse_rtattr (tb, RTA_MAX, RTM_RTA (rtm), len); - -  if (tb[RTA_IIF]) -    iif = *(int *)RTA_DATA (tb[RTA_IIF]); - -  if (tb[RTA_SRC]) -    m->sg.src = *(struct in_addr *)RTA_DATA (tb[RTA_SRC]); - -  if (tb[RTA_DST]) -    m->sg.grp = *(struct in_addr *)RTA_DATA (tb[RTA_DST]); - -  if ((RTA_EXPIRES <= RTA_MAX) && tb[RTA_EXPIRES]) -    m->lastused = *(unsigned long long *)RTA_DATA (tb[RTA_EXPIRES]); - -  if (tb[RTA_MULTIPATH]) -    { -      struct rtnexthop *rtnh = -        (struct rtnexthop *)RTA_DATA (tb[RTA_MULTIPATH]); - -      len = RTA_PAYLOAD (tb[RTA_MULTIPATH]); -      for (;;) -        { -          if (len < (int) sizeof (*rtnh) || rtnh->rtnh_len > len) -	    break; - -	  oif[oif_count] = rtnh->rtnh_ifindex; -          oif_count++; - -	  len -= NLMSG_ALIGN (rtnh->rtnh_len); -	  rtnh = RTNH_NEXT (rtnh); -        } -    } - -  if (IS_ZEBRA_DEBUG_KERNEL) -    { -      struct interface *ifp; -      strcpy (sbuf, inet_ntoa (m->sg.src)); -      strcpy (gbuf, inet_ntoa (m->sg.grp)); -      for (count = 0; count < oif_count; count++) -	{ -	  ifp = if_lookup_by_index (oif[count], vrf); -	  char temp[256]; +	int len; +	struct rtmsg *rtm; +	struct rtattr *tb[RTA_MAX + 1]; +	struct mcast_route_data *m; +	struct mcast_route_data mr; +	int iif = 0; +	int count; +	int oif[256]; +	int oif_count = 0; +	char sbuf[40]; +	char gbuf[40]; +	char oif_list[256] = "\0"; +	vrf_id_t vrf = ns_id; + +	if (mroute) +		m = mroute; +	else { +		memset(&mr, 0, sizeof(mr)); +		m = &mr; +	} + +	rtm = NLMSG_DATA(h); -	  sprintf (temp, "%s ", ifp->name); -	  strcat (oif_list, temp); +	len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct rtmsg)); + +	memset(tb, 0, sizeof tb); +	netlink_parse_rtattr(tb, RTA_MAX, RTM_RTA(rtm), len); + +	if (tb[RTA_IIF]) +		iif = *(int *)RTA_DATA(tb[RTA_IIF]); + +	if (tb[RTA_SRC]) +		m->sg.src = *(struct in_addr *)RTA_DATA(tb[RTA_SRC]); + +	if (tb[RTA_DST]) +		m->sg.grp = *(struct in_addr *)RTA_DATA(tb[RTA_DST]); + +	if ((RTA_EXPIRES <= RTA_MAX) && tb[RTA_EXPIRES]) +		m->lastused = *(unsigned long long *)RTA_DATA(tb[RTA_EXPIRES]); + +	if (tb[RTA_MULTIPATH]) { +		struct rtnexthop *rtnh = +			(struct rtnexthop *)RTA_DATA(tb[RTA_MULTIPATH]); + +		len = RTA_PAYLOAD(tb[RTA_MULTIPATH]); +		for (;;) { +			if (len < (int)sizeof(*rtnh) || rtnh->rtnh_len > len) +				break; + +			oif[oif_count] = rtnh->rtnh_ifindex; +			oif_count++; + +			len -= NLMSG_ALIGN(rtnh->rtnh_len); +			rtnh = RTNH_NEXT(rtnh); +		}  	} -      ifp = if_lookup_by_index (iif, vrf); -      zlog_debug ("MCAST %s (%s,%s) IIF: %s OIF: %s jiffies: %lld", -		  nl_msg_type_to_str(h->nlmsg_type), sbuf, gbuf, ifp->name, oif_list, m->lastused); -    } -  return 0; + +	if (IS_ZEBRA_DEBUG_KERNEL) { +		struct interface *ifp; +		strcpy(sbuf, inet_ntoa(m->sg.src)); +		strcpy(gbuf, inet_ntoa(m->sg.grp)); +		for (count = 0; count < oif_count; count++) { +			ifp = if_lookup_by_index(oif[count], vrf); +			char temp[256]; + +			sprintf(temp, "%s ", ifp->name); +			strcat(oif_list, temp); +		} +		ifp = if_lookup_by_index(iif, vrf); +		zlog_debug("MCAST %s (%s,%s) IIF: %s OIF: %s jiffies: %lld", +			   nl_msg_type_to_str(h->nlmsg_type), sbuf, gbuf, +			   ifp->name, oif_list, m->lastused); +	} +	return 0;  } -int -netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h, -		      ns_id_t ns_id, int startup) +int netlink_route_change(struct sockaddr_nl *snl, struct nlmsghdr *h, +			 ns_id_t ns_id, int startup)  { -  int len; -  vrf_id_t vrf_id = ns_id; -  struct rtmsg *rtm; - -  rtm = NLMSG_DATA (h); - -  if (!(h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE)) -    { -      /* If this is not route add/delete message print warning. */ -      zlog_warn ("Kernel message: %d vrf %u\n", h->nlmsg_type, vrf_id); -      return 0; -    } - -  /* Connected route. */ -  if (IS_ZEBRA_DEBUG_KERNEL) -    zlog_debug ("%s %s %s proto %s vrf %u", -		nl_msg_type_to_str (h->nlmsg_type), -		nl_family_to_str (rtm->rtm_family), -		nl_rttype_to_str (rtm->rtm_type), -		nl_rtproto_to_str (rtm->rtm_protocol), -		vrf_id); - -  /* We don't care about change notifications for the MPLS table. */ -  /* TODO: Revisit this. */ -  if (rtm->rtm_family == AF_MPLS) -    return 0; - -  len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct rtmsg)); -  if (len < 0) -    return -1; - -  switch (rtm->rtm_type) -    { -    case RTN_UNICAST: -      netlink_route_change_read_unicast (snl, h, ns_id, startup); -      break; -    case RTN_MULTICAST: -      netlink_route_change_read_multicast (snl, h, ns_id, startup); -      break; -    default: -      return 0; -      break; -    } - -  return 0; +	int len; +	vrf_id_t vrf_id = ns_id; +	struct rtmsg *rtm; + +	rtm = NLMSG_DATA(h); + +	if (!(h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE)) { +		/* If this is not route add/delete message print warning. */ +		zlog_warn("Kernel message: %d vrf %u\n", h->nlmsg_type, vrf_id); +		return 0; +	} + +	/* Connected route. */ +	if (IS_ZEBRA_DEBUG_KERNEL) +		zlog_debug("%s %s %s proto %s vrf %u", +			   nl_msg_type_to_str(h->nlmsg_type), +			   nl_family_to_str(rtm->rtm_family), +			   nl_rttype_to_str(rtm->rtm_type), +			   nl_rtproto_to_str(rtm->rtm_protocol), vrf_id); + +	/* We don't care about change notifications for the MPLS table. */ +	/* TODO: Revisit this. */ +	if (rtm->rtm_family == AF_MPLS) +		return 0; + +	len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct rtmsg)); +	if (len < 0) +		return -1; + +	switch (rtm->rtm_type) { +	case RTN_UNICAST: +		netlink_route_change_read_unicast(snl, h, ns_id, startup); +		break; +	case RTN_MULTICAST: +		netlink_route_change_read_multicast(snl, h, ns_id, startup); +		break; +	default: +		return 0; +		break; +	} + +	return 0;  }  /* Routing table read function using netlink interface.  Only called     bootstrap time. */ -int -netlink_route_read (struct zebra_ns *zns) +int netlink_route_read(struct zebra_ns *zns)  { -  int ret; - -  /* Get IPv4 routing table. */ -  ret = netlink_request (AF_INET, RTM_GETROUTE, &zns->netlink_cmd); -  if (ret < 0) -    return ret; -  ret = netlink_parse_info (netlink_route_change_read_unicast, &zns->netlink_cmd, zns, 0, 1); -  if (ret < 0) -    return ret; - -  /* Get IPv6 routing table. */ -  ret = netlink_request (AF_INET6, RTM_GETROUTE, &zns->netlink_cmd); -  if (ret < 0) -    return ret; -  ret = netlink_parse_info (netlink_route_change_read_unicast, &zns->netlink_cmd, zns, 0, 1); -  if (ret < 0) -    return ret; - -  return 0; +	int ret; + +	/* Get IPv4 routing table. */ +	ret = netlink_request(AF_INET, RTM_GETROUTE, &zns->netlink_cmd); +	if (ret < 0) +		return ret; +	ret = netlink_parse_info(netlink_route_change_read_unicast, +				 &zns->netlink_cmd, zns, 0, 1); +	if (ret < 0) +		return ret; + +	/* Get IPv6 routing table. */ +	ret = netlink_request(AF_INET6, RTM_GETROUTE, &zns->netlink_cmd); +	if (ret < 0) +		return ret; +	ret = netlink_parse_info(netlink_route_change_read_unicast, +				 &zns->netlink_cmd, zns, 0, 1); +	if (ret < 0) +		return ret; + +	return 0;  } -static void -_netlink_route_nl_add_gateway_info (u_char route_family, u_char gw_family, -                                    struct nlmsghdr *nlmsg, -                                    size_t req_size, int bytelen, -                                    struct nexthop *nexthop) +static void _netlink_route_nl_add_gateway_info(u_char route_family, +					       u_char gw_family, +					       struct nlmsghdr *nlmsg, +					       size_t req_size, int bytelen, +					       struct nexthop *nexthop)  { -  if (route_family == AF_MPLS) -    { -      struct gw_family_t gw_fam; - -      gw_fam.family = gw_family; -      if (gw_family == AF_INET) -        memcpy (&gw_fam.gate.ipv4, &nexthop->gate.ipv4, bytelen); -      else -        memcpy (&gw_fam.gate.ipv6, &nexthop->gate.ipv6, bytelen); -      addattr_l (nlmsg, req_size, RTA_VIA, &gw_fam.family, bytelen+2); -    } -  else -    { -      if (gw_family == AF_INET) -        addattr_l (nlmsg, req_size, RTA_GATEWAY, &nexthop->gate.ipv4, bytelen); -      else -        addattr_l (nlmsg, req_size, RTA_GATEWAY, &nexthop->gate.ipv6, bytelen); -    } +	if (route_family == AF_MPLS) { +		struct gw_family_t gw_fam; + +		gw_fam.family = gw_family; +		if (gw_family == AF_INET) +			memcpy(&gw_fam.gate.ipv4, &nexthop->gate.ipv4, bytelen); +		else +			memcpy(&gw_fam.gate.ipv6, &nexthop->gate.ipv6, bytelen); +		addattr_l(nlmsg, req_size, RTA_VIA, &gw_fam.family, +			  bytelen + 2); +	} else { +		if (gw_family == AF_INET) +			addattr_l(nlmsg, req_size, RTA_GATEWAY, +				  &nexthop->gate.ipv4, bytelen); +		else +			addattr_l(nlmsg, req_size, RTA_GATEWAY, +				  &nexthop->gate.ipv6, bytelen); +	}  } -static void -_netlink_route_rta_add_gateway_info (u_char route_family, u_char gw_family, -                                     struct rtattr *rta, struct rtnexthop *rtnh, -                                     size_t req_size, int bytelen, -                                     struct nexthop *nexthop) +static void _netlink_route_rta_add_gateway_info(u_char route_family, +						u_char gw_family, +						struct rtattr *rta, +						struct rtnexthop *rtnh, +						size_t req_size, int bytelen, +						struct nexthop *nexthop)  { -  if (route_family == AF_MPLS) -    { -      struct gw_family_t gw_fam; - -      gw_fam.family = gw_family; -      if (gw_family == AF_INET) -        memcpy (&gw_fam.gate.ipv4, &nexthop->gate.ipv4, bytelen); -      else -        memcpy (&gw_fam.gate.ipv6, &nexthop->gate.ipv6, bytelen); -      rta_addattr_l (rta, req_size, RTA_VIA, &gw_fam.family, bytelen+2); -      rtnh->rtnh_len += RTA_LENGTH (bytelen + 2); -    } -  else -    { -      if (gw_family == AF_INET) -        rta_addattr_l (rta, req_size, RTA_GATEWAY, &nexthop->gate.ipv4, bytelen); -      else -        rta_addattr_l (rta, req_size, RTA_GATEWAY, &nexthop->gate.ipv6, bytelen); -      rtnh->rtnh_len += sizeof (struct rtattr) + bytelen; -    } +	if (route_family == AF_MPLS) { +		struct gw_family_t gw_fam; + +		gw_fam.family = gw_family; +		if (gw_family == AF_INET) +			memcpy(&gw_fam.gate.ipv4, &nexthop->gate.ipv4, bytelen); +		else +			memcpy(&gw_fam.gate.ipv6, &nexthop->gate.ipv6, bytelen); +		rta_addattr_l(rta, req_size, RTA_VIA, &gw_fam.family, +			      bytelen + 2); +		rtnh->rtnh_len += RTA_LENGTH(bytelen + 2); +	} else { +		if (gw_family == AF_INET) +			rta_addattr_l(rta, req_size, RTA_GATEWAY, +				      &nexthop->gate.ipv4, bytelen); +		else +			rta_addattr_l(rta, req_size, RTA_GATEWAY, +				      &nexthop->gate.ipv6, bytelen); +		rtnh->rtnh_len += sizeof(struct rtattr) + bytelen; +	}  }  /* This function takes a nexthop as argument and adds @@ -620,188 +610,180 @@ _netlink_route_rta_add_gateway_info (u_char route_family, u_char gw_family,   * @param nlmsg: nlmsghdr structure to fill in.   * @param req_size: The size allocated for the message.   */ -static void -_netlink_route_build_singlepath( -        const char *routedesc, -        int bytelen, -        struct nexthop *nexthop, -        struct nlmsghdr *nlmsg, -        struct rtmsg *rtmsg, -        size_t req_size, -	int cmd) +static void _netlink_route_build_singlepath(const char *routedesc, int bytelen, +					    struct nexthop *nexthop, +					    struct nlmsghdr *nlmsg, +					    struct rtmsg *rtmsg, +					    size_t req_size, int cmd)  { -  struct nexthop_label *nh_label; -  mpls_lse_t out_lse[MPLS_MAX_LABELS]; -  char label_buf[100]; - -  if (rtmsg->rtm_family == AF_INET && -      (nexthop->type == NEXTHOP_TYPE_IPV6 -      || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)) -    { -      char buf[16] = "169.254.0.1"; -      struct in_addr ipv4_ll; - -      inet_pton (AF_INET, buf, &ipv4_ll); -      rtmsg->rtm_flags |= RTNH_F_ONLINK; -      addattr_l (nlmsg, req_size, RTA_GATEWAY, &ipv4_ll, 4); -      addattr32 (nlmsg, req_size, RTA_OIF, nexthop->ifindex); - -      if (nexthop->rmap_src.ipv4.s_addr && (cmd == RTM_NEWROUTE)) -        addattr_l (nlmsg, req_size, RTA_PREFSRC, -                   &nexthop->rmap_src.ipv4, bytelen); -      else if (nexthop->src.ipv4.s_addr && (cmd == RTM_NEWROUTE)) -        addattr_l (nlmsg, req_size, RTA_PREFSRC, -                   &nexthop->src.ipv4, bytelen); - -      if (IS_ZEBRA_DEBUG_KERNEL) -        zlog_debug(" 5549: _netlink_route_build_singlepath() (%s): " -                   "nexthop via %s if %u", -                   routedesc, buf, nexthop->ifindex); -      return; -    } - -  label_buf[0] = '\0'; -  /* outgoing label - either as NEWDST (in the case of LSR) or as ENCAP -   * (in the case of LER) -   */ -  nh_label = nexthop->nh_label; -  if (rtmsg->rtm_family == AF_MPLS) -    { -      assert (nh_label); -      assert (nh_label->num_labels == 1); -    } - -  if (nh_label && nh_label->num_labels) -    { -      int i, num_labels = 0; -      u_int32_t bos; -      char label_buf1[20]; - -      for (i = 0; i < nh_label->num_labels; i++) -        { -          if (nh_label->label[i] != MPLS_IMP_NULL_LABEL) -            { -              bos = ((i == (nh_label->num_labels - 1)) ? 1 : 0); -              out_lse[i] = mpls_lse_encode (nh_label->label[i], 0, 0, bos); -              if (!num_labels) -                sprintf (label_buf, "label %d", nh_label->label[i]); -              else -                { -                  sprintf (label_buf1, "/%d", nh_label->label[i]); -                  strcat (label_buf, label_buf1); -                } -              num_labels++; -            } -        } -      if (num_labels) -        { -          if (rtmsg->rtm_family == AF_MPLS) -            addattr_l (nlmsg, req_size, RTA_NEWDST, -                       &out_lse, num_labels * sizeof(mpls_lse_t)); -          else -            { -              struct rtattr *nest; -              u_int16_t encap = LWTUNNEL_ENCAP_MPLS; - -              addattr_l(nlmsg, req_size, RTA_ENCAP_TYPE, -                        &encap, sizeof (u_int16_t)); -              nest = addattr_nest(nlmsg, req_size, RTA_ENCAP); -              addattr_l (nlmsg, req_size, MPLS_IPTUNNEL_DST, -                         &out_lse, num_labels * sizeof(mpls_lse_t)); -              addattr_nest_end(nlmsg, nest); -            } -        } -    } - -  if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK)) -    rtmsg->rtm_flags |= RTNH_F_ONLINK; - -  if (nexthop->type == NEXTHOP_TYPE_IPV4 -      || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) -    { -      /* Send deletes to the kernel without specifying the next-hop */ -      if (cmd != RTM_DELROUTE) -        _netlink_route_nl_add_gateway_info (rtmsg->rtm_family, AF_INET, nlmsg, -                                            req_size, bytelen, nexthop); - -      if (cmd == RTM_NEWROUTE) -	{ -	  if (nexthop->rmap_src.ipv4.s_addr) -	    addattr_l (nlmsg, req_size, RTA_PREFSRC, -		       &nexthop->rmap_src.ipv4, bytelen); -	  else if (nexthop->src.ipv4.s_addr) -	    addattr_l (nlmsg, req_size, RTA_PREFSRC, -		       &nexthop->src.ipv4, bytelen); +	struct nexthop_label *nh_label; +	mpls_lse_t out_lse[MPLS_MAX_LABELS]; +	char label_buf[100]; + +	if (rtmsg->rtm_family == AF_INET +	    && (nexthop->type == NEXTHOP_TYPE_IPV6 +		|| nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)) { +		char buf[16] = "169.254.0.1"; +		struct in_addr ipv4_ll; + +		inet_pton(AF_INET, buf, &ipv4_ll); +		rtmsg->rtm_flags |= RTNH_F_ONLINK; +		addattr_l(nlmsg, req_size, RTA_GATEWAY, &ipv4_ll, 4); +		addattr32(nlmsg, req_size, RTA_OIF, nexthop->ifindex); + +		if (nexthop->rmap_src.ipv4.s_addr && (cmd == RTM_NEWROUTE)) +			addattr_l(nlmsg, req_size, RTA_PREFSRC, +				  &nexthop->rmap_src.ipv4, bytelen); +		else if (nexthop->src.ipv4.s_addr && (cmd == RTM_NEWROUTE)) +			addattr_l(nlmsg, req_size, RTA_PREFSRC, +				  &nexthop->src.ipv4, bytelen); + +		if (IS_ZEBRA_DEBUG_KERNEL) +			zlog_debug( +				" 5549: _netlink_route_build_singlepath() (%s): " +				"nexthop via %s if %u", +				routedesc, buf, nexthop->ifindex); +		return;  	} -      if (IS_ZEBRA_DEBUG_KERNEL) -        zlog_debug("netlink_route_multipath() (%s): " -                   "nexthop via %s %s if %u", -                   routedesc, -                   inet_ntoa (nexthop->gate.ipv4), -                   label_buf, nexthop->ifindex); -    } -  if (nexthop->type == NEXTHOP_TYPE_IPV6 -      || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) -    { -      _netlink_route_nl_add_gateway_info (rtmsg->rtm_family, AF_INET6, nlmsg, -                                          req_size, bytelen, nexthop); - -      if (cmd == RTM_NEWROUTE) -	{ -	  if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->rmap_src.ipv6)) -	    addattr_l (nlmsg, req_size, RTA_PREFSRC, -		       &nexthop->rmap_src.ipv6, bytelen); -	  else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->src.ipv6)) -	    addattr_l (nlmsg, req_size, RTA_PREFSRC, -		       &nexthop->src.ipv6, bytelen); +	label_buf[0] = '\0'; +	/* outgoing label - either as NEWDST (in the case of LSR) or as ENCAP +	 * (in the case of LER) +	 */ +	nh_label = nexthop->nh_label; +	if (rtmsg->rtm_family == AF_MPLS) { +		assert(nh_label); +		assert(nh_label->num_labels == 1);  	} -      if (IS_ZEBRA_DEBUG_KERNEL) -        zlog_debug("netlink_route_multipath() (%s): " -                   "nexthop via %s %s if %u", -                   routedesc, -                   inet6_ntoa (nexthop->gate.ipv6), -                   label_buf, nexthop->ifindex); -    } -  if (nexthop->type == NEXTHOP_TYPE_IFINDEX -      || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) -    { -      addattr32 (nlmsg, req_size, RTA_OIF, nexthop->ifindex); - -      if (cmd == RTM_NEWROUTE) -	{ -	  if (nexthop->rmap_src.ipv4.s_addr) -	    addattr_l (nlmsg, req_size, RTA_PREFSRC, -		       &nexthop->rmap_src.ipv4, bytelen); -	  else if (nexthop->src.ipv4.s_addr) -	    addattr_l (nlmsg, req_size, RTA_PREFSRC, -		       &nexthop->src.ipv4, bytelen); +	if (nh_label && nh_label->num_labels) { +		int i, num_labels = 0; +		u_int32_t bos; +		char label_buf1[20]; + +		for (i = 0; i < nh_label->num_labels; i++) { +			if (nh_label->label[i] != MPLS_IMP_NULL_LABEL) { +				bos = ((i == (nh_label->num_labels - 1)) ? 1 +									 : 0); +				out_lse[i] = mpls_lse_encode(nh_label->label[i], +							     0, 0, bos); +				if (!num_labels) +					sprintf(label_buf, "label %d", +						nh_label->label[i]); +				else { +					sprintf(label_buf1, "/%d", +						nh_label->label[i]); +					strcat(label_buf, label_buf1); +				} +				num_labels++; +			} +		} +		if (num_labels) { +			if (rtmsg->rtm_family == AF_MPLS) +				addattr_l(nlmsg, req_size, RTA_NEWDST, &out_lse, +					  num_labels * sizeof(mpls_lse_t)); +			else { +				struct rtattr *nest; +				u_int16_t encap = LWTUNNEL_ENCAP_MPLS; + +				addattr_l(nlmsg, req_size, RTA_ENCAP_TYPE, +					  &encap, sizeof(u_int16_t)); +				nest = addattr_nest(nlmsg, req_size, RTA_ENCAP); +				addattr_l(nlmsg, req_size, MPLS_IPTUNNEL_DST, +					  &out_lse, +					  num_labels * sizeof(mpls_lse_t)); +				addattr_nest_end(nlmsg, nest); +			} +		}  	} -      if (IS_ZEBRA_DEBUG_KERNEL) -        zlog_debug("netlink_route_multipath() (%s): " -                   "nexthop via if %u", routedesc, nexthop->ifindex); -    } +	if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)) +		rtmsg->rtm_flags |= RTNH_F_ONLINK; + +	if (nexthop->type == NEXTHOP_TYPE_IPV4 +	    || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) { +		/* Send deletes to the kernel without specifying the next-hop */ +		if (cmd != RTM_DELROUTE) +			_netlink_route_nl_add_gateway_info( +				rtmsg->rtm_family, AF_INET, nlmsg, req_size, +				bytelen, nexthop); + +		if (cmd == RTM_NEWROUTE) { +			if (nexthop->rmap_src.ipv4.s_addr) +				addattr_l(nlmsg, req_size, RTA_PREFSRC, +					  &nexthop->rmap_src.ipv4, bytelen); +			else if (nexthop->src.ipv4.s_addr) +				addattr_l(nlmsg, req_size, RTA_PREFSRC, +					  &nexthop->src.ipv4, bytelen); +		} + +		if (IS_ZEBRA_DEBUG_KERNEL) +			zlog_debug( +				"netlink_route_multipath() (%s): " +				"nexthop via %s %s if %u", +				routedesc, inet_ntoa(nexthop->gate.ipv4), +				label_buf, nexthop->ifindex); +	} +	if (nexthop->type == NEXTHOP_TYPE_IPV6 +	    || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) { +		_netlink_route_nl_add_gateway_info(rtmsg->rtm_family, AF_INET6, +						   nlmsg, req_size, bytelen, +						   nexthop); + +		if (cmd == RTM_NEWROUTE) { +			if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->rmap_src.ipv6)) +				addattr_l(nlmsg, req_size, RTA_PREFSRC, +					  &nexthop->rmap_src.ipv6, bytelen); +			else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->src.ipv6)) +				addattr_l(nlmsg, req_size, RTA_PREFSRC, +					  &nexthop->src.ipv6, bytelen); +		} -  if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) -    { -      addattr32 (nlmsg, req_size, RTA_OIF, nexthop->ifindex); +		if (IS_ZEBRA_DEBUG_KERNEL) +			zlog_debug( +				"netlink_route_multipath() (%s): " +				"nexthop via %s %s if %u", +				routedesc, inet6_ntoa(nexthop->gate.ipv6), +				label_buf, nexthop->ifindex); +	} +	if (nexthop->type == NEXTHOP_TYPE_IFINDEX +	    || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) { +		addattr32(nlmsg, req_size, RTA_OIF, nexthop->ifindex); + +		if (cmd == RTM_NEWROUTE) { +			if (nexthop->rmap_src.ipv4.s_addr) +				addattr_l(nlmsg, req_size, RTA_PREFSRC, +					  &nexthop->rmap_src.ipv4, bytelen); +			else if (nexthop->src.ipv4.s_addr) +				addattr_l(nlmsg, req_size, RTA_PREFSRC, +					  &nexthop->src.ipv4, bytelen); +		} -      if (cmd == RTM_NEWROUTE) -	{ -	  if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->rmap_src.ipv6)) -	    addattr_l (nlmsg, req_size, RTA_PREFSRC, -		       &nexthop->rmap_src.ipv6, bytelen); -	  else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->src.ipv6)) -	    addattr_l (nlmsg, req_size, RTA_PREFSRC, -		       &nexthop->src.ipv6, bytelen); +		if (IS_ZEBRA_DEBUG_KERNEL) +			zlog_debug( +				"netlink_route_multipath() (%s): " +				"nexthop via if %u", +				routedesc, nexthop->ifindex);  	} -      if (IS_ZEBRA_DEBUG_KERNEL) -        zlog_debug("netlink_route_multipath() (%s): " -                   "nexthop via if %u", routedesc, nexthop->ifindex); -    } +	if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) { +		addattr32(nlmsg, req_size, RTA_OIF, nexthop->ifindex); + +		if (cmd == RTM_NEWROUTE) { +			if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->rmap_src.ipv6)) +				addattr_l(nlmsg, req_size, RTA_PREFSRC, +					  &nexthop->rmap_src.ipv6, bytelen); +			else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->src.ipv6)) +				addattr_l(nlmsg, req_size, RTA_PREFSRC, +					  &nexthop->src.ipv6, bytelen); +		} + +		if (IS_ZEBRA_DEBUG_KERNEL) +			zlog_debug( +				"netlink_route_multipath() (%s): " +				"nexthop via if %u", +				routedesc, nexthop->ifindex); +	}  }  /* This function takes a nexthop as argument and @@ -820,212 +802,201 @@ _netlink_route_build_singlepath(   * @param src: pointer pointing to a location where   *             the prefsrc should be stored.   */ -static void -_netlink_route_build_multipath( -        const char *routedesc, -        int bytelen, -        struct nexthop *nexthop, -        struct rtattr *rta, -        struct rtnexthop *rtnh, -        struct rtmsg *rtmsg, -        union g_addr **src) +static void _netlink_route_build_multipath(const char *routedesc, int bytelen, +					   struct nexthop *nexthop, +					   struct rtattr *rta, +					   struct rtnexthop *rtnh, +					   struct rtmsg *rtmsg, +					   union g_addr **src)  { -  struct nexthop_label *nh_label; -  mpls_lse_t out_lse[MPLS_MAX_LABELS]; -  char label_buf[100]; - -  rtnh->rtnh_len = sizeof (*rtnh); -  rtnh->rtnh_flags = 0; -  rtnh->rtnh_hops = 0; -  rta->rta_len += rtnh->rtnh_len; - -  if (rtmsg->rtm_family == AF_INET && -      (nexthop->type == NEXTHOP_TYPE_IPV6 -      || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)) -    { -      char buf[16] = "169.254.0.1"; -      struct in_addr ipv4_ll; - -      inet_pton (AF_INET, buf, &ipv4_ll); -      bytelen = 4; -      rtnh->rtnh_flags |= RTNH_F_ONLINK; -      rta_addattr_l (rta, NL_PKT_BUF_SIZE, RTA_GATEWAY, -                     &ipv4_ll, bytelen); -      rtnh->rtnh_len += sizeof (struct rtattr) + bytelen; -      rtnh->rtnh_ifindex = nexthop->ifindex; - -      if (nexthop->rmap_src.ipv4.s_addr) -        *src = &nexthop->rmap_src; -      else if (nexthop->src.ipv4.s_addr) -         *src = &nexthop->src; - -      if (IS_ZEBRA_DEBUG_KERNEL) -        zlog_debug(" 5549: netlink_route_build_multipath() (%s): " -                   "nexthop via %s if %u", -                   routedesc, buf, nexthop->ifindex); -      return; -    } - -  label_buf[0] = '\0'; -  /* outgoing label - either as NEWDST (in the case of LSR) or as ENCAP -   * (in the case of LER) -   */ -  nh_label = nexthop->nh_label; -  if (rtmsg->rtm_family == AF_MPLS) -    { -      assert (nh_label); -      assert (nh_label->num_labels == 1); -    } - -  if (nh_label && nh_label->num_labels) -    { -      int i, num_labels = 0; -      u_int32_t bos; -      char label_buf1[20]; - -      for (i = 0; i < nh_label->num_labels; i++) -        { -          if (nh_label->label[i] != MPLS_IMP_NULL_LABEL) -            { -              bos = ((i == (nh_label->num_labels - 1)) ? 1 : 0); -              out_lse[i] = mpls_lse_encode (nh_label->label[i], 0, 0, bos); -              if (!num_labels) -                sprintf (label_buf, "label %d", nh_label->label[i]); -              else -                { -                  sprintf (label_buf1, "/%d", nh_label->label[i]); -                  strcat (label_buf, label_buf1); -                } -              num_labels++; -            } -        } -      if (num_labels) -        { -          if (rtmsg->rtm_family == AF_MPLS) -            { -              rta_addattr_l (rta, NL_PKT_BUF_SIZE, RTA_NEWDST, -                             &out_lse, num_labels * sizeof(mpls_lse_t)); -              rtnh->rtnh_len += RTA_LENGTH (num_labels * sizeof(mpls_lse_t)); -            } -          else -            { -              struct rtattr *nest; -              u_int16_t encap = LWTUNNEL_ENCAP_MPLS; -              int len = rta->rta_len; - -              rta_addattr_l(rta, NL_PKT_BUF_SIZE, RTA_ENCAP_TYPE, -                            &encap, sizeof (u_int16_t)); -              nest = rta_nest(rta, NL_PKT_BUF_SIZE, RTA_ENCAP); -              rta_addattr_l (rta, NL_PKT_BUF_SIZE, MPLS_IPTUNNEL_DST, -                             &out_lse, num_labels * sizeof(mpls_lse_t)); -              rta_nest_end(rta, nest); -              rtnh->rtnh_len += rta->rta_len - len; -            } -        } -    } - -  if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK)) -    rtnh->rtnh_flags |= RTNH_F_ONLINK; - -  if (nexthop->type == NEXTHOP_TYPE_IPV4 -      || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) -    { -      _netlink_route_rta_add_gateway_info (rtmsg->rtm_family, AF_INET, rta, -                                     rtnh, NL_PKT_BUF_SIZE, bytelen, nexthop); -      if (nexthop->rmap_src.ipv4.s_addr) -        *src = &nexthop->rmap_src; -      else if (nexthop->src.ipv4.s_addr) -         *src = &nexthop->src; - -      if (IS_ZEBRA_DEBUG_KERNEL) -        zlog_debug("netlink_route_multipath() (%s): " -                   "nexthop via %s %s if %u", -                   routedesc, -                   inet_ntoa (nexthop->gate.ipv4), -                   label_buf, nexthop->ifindex); -    } -  if (nexthop->type == NEXTHOP_TYPE_IPV6 -      || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) -    { -      _netlink_route_rta_add_gateway_info (rtmsg->rtm_family, AF_INET6, rta, -                                       rtnh, NL_PKT_BUF_SIZE, bytelen, nexthop); - -      if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->rmap_src.ipv6)) -        *src = &nexthop->rmap_src; -      else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->src.ipv6)) -	*src = &nexthop->src; - -      if (IS_ZEBRA_DEBUG_KERNEL) -        zlog_debug("netlink_route_multipath() (%s): " -                   "nexthop via %s %s if %u", -                   routedesc, -                   inet6_ntoa (nexthop->gate.ipv6), -                   label_buf, nexthop->ifindex); -    } -  /* ifindex */ -  if (nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX -      || nexthop->type == NEXTHOP_TYPE_IFINDEX) -    { -      rtnh->rtnh_ifindex = nexthop->ifindex; - -      if (nexthop->rmap_src.ipv4.s_addr) -        *src = &nexthop->rmap_src; -      else if (nexthop->src.ipv4.s_addr) -        *src = &nexthop->src; - -      if (IS_ZEBRA_DEBUG_KERNEL) -        zlog_debug("netlink_route_multipath() (%s): " -                   "nexthop via if %u", routedesc, nexthop->ifindex); -    } -  else if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) -    { -      rtnh->rtnh_ifindex = nexthop->ifindex; - -      if (IS_ZEBRA_DEBUG_KERNEL) -        zlog_debug("netlink_route_multipath() (%s): " -                   "nexthop via if %u", routedesc, nexthop->ifindex); -    } -  else -    { -      rtnh->rtnh_ifindex = 0; -    } +	struct nexthop_label *nh_label; +	mpls_lse_t out_lse[MPLS_MAX_LABELS]; +	char label_buf[100]; + +	rtnh->rtnh_len = sizeof(*rtnh); +	rtnh->rtnh_flags = 0; +	rtnh->rtnh_hops = 0; +	rta->rta_len += rtnh->rtnh_len; + +	if (rtmsg->rtm_family == AF_INET +	    && (nexthop->type == NEXTHOP_TYPE_IPV6 +		|| nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)) { +		char buf[16] = "169.254.0.1"; +		struct in_addr ipv4_ll; + +		inet_pton(AF_INET, buf, &ipv4_ll); +		bytelen = 4; +		rtnh->rtnh_flags |= RTNH_F_ONLINK; +		rta_addattr_l(rta, NL_PKT_BUF_SIZE, RTA_GATEWAY, &ipv4_ll, +			      bytelen); +		rtnh->rtnh_len += sizeof(struct rtattr) + bytelen; +		rtnh->rtnh_ifindex = nexthop->ifindex; + +		if (nexthop->rmap_src.ipv4.s_addr) +			*src = &nexthop->rmap_src; +		else if (nexthop->src.ipv4.s_addr) +			*src = &nexthop->src; + +		if (IS_ZEBRA_DEBUG_KERNEL) +			zlog_debug( +				" 5549: netlink_route_build_multipath() (%s): " +				"nexthop via %s if %u", +				routedesc, buf, nexthop->ifindex); +		return; +	} + +	label_buf[0] = '\0'; +	/* outgoing label - either as NEWDST (in the case of LSR) or as ENCAP +	 * (in the case of LER) +	 */ +	nh_label = nexthop->nh_label; +	if (rtmsg->rtm_family == AF_MPLS) { +		assert(nh_label); +		assert(nh_label->num_labels == 1); +	} + +	if (nh_label && nh_label->num_labels) { +		int i, num_labels = 0; +		u_int32_t bos; +		char label_buf1[20]; + +		for (i = 0; i < nh_label->num_labels; i++) { +			if (nh_label->label[i] != MPLS_IMP_NULL_LABEL) { +				bos = ((i == (nh_label->num_labels - 1)) ? 1 +									 : 0); +				out_lse[i] = mpls_lse_encode(nh_label->label[i], +							     0, 0, bos); +				if (!num_labels) +					sprintf(label_buf, "label %d", +						nh_label->label[i]); +				else { +					sprintf(label_buf1, "/%d", +						nh_label->label[i]); +					strcat(label_buf, label_buf1); +				} +				num_labels++; +			} +		} +		if (num_labels) { +			if (rtmsg->rtm_family == AF_MPLS) { +				rta_addattr_l(rta, NL_PKT_BUF_SIZE, RTA_NEWDST, +					      &out_lse, +					      num_labels * sizeof(mpls_lse_t)); +				rtnh->rtnh_len += RTA_LENGTH( +					num_labels * sizeof(mpls_lse_t)); +			} else { +				struct rtattr *nest; +				u_int16_t encap = LWTUNNEL_ENCAP_MPLS; +				int len = rta->rta_len; + +				rta_addattr_l(rta, NL_PKT_BUF_SIZE, +					      RTA_ENCAP_TYPE, &encap, +					      sizeof(u_int16_t)); +				nest = rta_nest(rta, NL_PKT_BUF_SIZE, +						RTA_ENCAP); +				rta_addattr_l(rta, NL_PKT_BUF_SIZE, +					      MPLS_IPTUNNEL_DST, &out_lse, +					      num_labels * sizeof(mpls_lse_t)); +				rta_nest_end(rta, nest); +				rtnh->rtnh_len += rta->rta_len - len; +			} +		} +	} + +	if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)) +		rtnh->rtnh_flags |= RTNH_F_ONLINK; + +	if (nexthop->type == NEXTHOP_TYPE_IPV4 +	    || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) { +		_netlink_route_rta_add_gateway_info(rtmsg->rtm_family, AF_INET, +						    rta, rtnh, NL_PKT_BUF_SIZE, +						    bytelen, nexthop); +		if (nexthop->rmap_src.ipv4.s_addr) +			*src = &nexthop->rmap_src; +		else if (nexthop->src.ipv4.s_addr) +			*src = &nexthop->src; + +		if (IS_ZEBRA_DEBUG_KERNEL) +			zlog_debug( +				"netlink_route_multipath() (%s): " +				"nexthop via %s %s if %u", +				routedesc, inet_ntoa(nexthop->gate.ipv4), +				label_buf, nexthop->ifindex); +	} +	if (nexthop->type == NEXTHOP_TYPE_IPV6 +	    || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) { +		_netlink_route_rta_add_gateway_info(rtmsg->rtm_family, AF_INET6, +						    rta, rtnh, NL_PKT_BUF_SIZE, +						    bytelen, nexthop); + +		if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->rmap_src.ipv6)) +			*src = &nexthop->rmap_src; +		else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->src.ipv6)) +			*src = &nexthop->src; + +		if (IS_ZEBRA_DEBUG_KERNEL) +			zlog_debug( +				"netlink_route_multipath() (%s): " +				"nexthop via %s %s if %u", +				routedesc, inet6_ntoa(nexthop->gate.ipv6), +				label_buf, nexthop->ifindex); +	} +	/* ifindex */ +	if (nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX +	    || nexthop->type == NEXTHOP_TYPE_IFINDEX) { +		rtnh->rtnh_ifindex = nexthop->ifindex; + +		if (nexthop->rmap_src.ipv4.s_addr) +			*src = &nexthop->rmap_src; +		else if (nexthop->src.ipv4.s_addr) +			*src = &nexthop->src; + +		if (IS_ZEBRA_DEBUG_KERNEL) +			zlog_debug( +				"netlink_route_multipath() (%s): " +				"nexthop via if %u", +				routedesc, nexthop->ifindex); +	} else if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) { +		rtnh->rtnh_ifindex = nexthop->ifindex; + +		if (IS_ZEBRA_DEBUG_KERNEL) +			zlog_debug( +				"netlink_route_multipath() (%s): " +				"nexthop via if %u", +				routedesc, nexthop->ifindex); +	} else { +		rtnh->rtnh_ifindex = 0; +	}  } -static inline void -_netlink_mpls_build_singlepath( -        const char *routedesc, -        zebra_nhlfe_t *nhlfe, -        struct nlmsghdr *nlmsg, -        struct rtmsg *rtmsg, -        size_t req_size, -	int cmd) +static inline void _netlink_mpls_build_singlepath(const char *routedesc, +						  zebra_nhlfe_t *nhlfe, +						  struct nlmsghdr *nlmsg, +						  struct rtmsg *rtmsg, +						  size_t req_size, int cmd)  { -  int bytelen; -  u_char family; +	int bytelen; +	u_char family; -  family = NHLFE_FAMILY (nhlfe); -  bytelen = (family == AF_INET ? 4 : 16); -  _netlink_route_build_singlepath(routedesc, bytelen, nhlfe->nexthop, -                                  nlmsg, rtmsg, req_size, cmd); +	family = NHLFE_FAMILY(nhlfe); +	bytelen = (family == AF_INET ? 4 : 16); +	_netlink_route_build_singlepath(routedesc, bytelen, nhlfe->nexthop, +					nlmsg, rtmsg, req_size, cmd);  }  static inline void -_netlink_mpls_build_multipath( -        const char *routedesc, -        zebra_nhlfe_t *nhlfe, -        struct rtattr *rta, -        struct rtnexthop *rtnh, -        struct rtmsg *rtmsg, -        union g_addr **src) +_netlink_mpls_build_multipath(const char *routedesc, zebra_nhlfe_t *nhlfe, +			      struct rtattr *rta, struct rtnexthop *rtnh, +			      struct rtmsg *rtmsg, union g_addr **src)  { -  int bytelen; -  u_char family; +	int bytelen; +	u_char family; -  family = NHLFE_FAMILY (nhlfe); -  bytelen = (family == AF_INET ? 4 : 16); -  _netlink_route_build_multipath(routedesc, bytelen, nhlfe->nexthop, -                                 rta, rtnh, rtmsg, src); +	family = NHLFE_FAMILY(nhlfe); +	bytelen = (family == AF_INET ? 4 : 16); +	_netlink_route_build_multipath(routedesc, bytelen, nhlfe->nexthop, rta, +				       rtnh, rtmsg, src);  } @@ -1039,603 +1010,609 @@ _netlink_mpls_build_multipath(   *                     (recursive, multipath, etc.)   * @param family: Address family which the change concerns   */ -static void -_netlink_route_debug( -        int cmd, -        struct prefix *p, -        struct nexthop *nexthop, -        const char *routedesc, -        int family, -        struct zebra_vrf *zvrf) +static void _netlink_route_debug(int cmd, struct prefix *p, +				 struct nexthop *nexthop, const char *routedesc, +				 int family, struct zebra_vrf *zvrf)  { -  if (IS_ZEBRA_DEBUG_KERNEL) -    { -      char buf[PREFIX_STRLEN]; -      zlog_debug ("netlink_route_multipath() (%s): %s %s vrf %u type %s", -		  routedesc, -		  nl_msg_type_to_str (cmd), -		  prefix2str (p, buf, sizeof(buf)), zvrf_id (zvrf), -		  (nexthop) ? nexthop_type_to_str (nexthop->type) : "UNK"); -    } -    } - -static void -_netlink_mpls_debug( -        int cmd, -        u_int32_t label, -        const char *routedesc) -{ -  if (IS_ZEBRA_DEBUG_KERNEL) -    zlog_debug ("netlink_mpls_multipath() (%s): %s %u/20", -                routedesc, nl_msg_type_to_str (cmd), label); +	if (IS_ZEBRA_DEBUG_KERNEL) { +		char buf[PREFIX_STRLEN]; +		zlog_debug( +			"netlink_route_multipath() (%s): %s %s vrf %u type %s", +			routedesc, nl_msg_type_to_str(cmd), +			prefix2str(p, buf, sizeof(buf)), zvrf_id(zvrf), +			(nexthop) ? nexthop_type_to_str(nexthop->type) : "UNK"); +	}  } -static int -netlink_neigh_update (int cmd, int ifindex, uint32_t addr, char *lla, int llalen) +static void _netlink_mpls_debug(int cmd, u_int32_t label, const char *routedesc)  { -  struct { -      struct nlmsghdr         n; -      struct ndmsg            ndm; -      char                    buf[256]; -  } req; - -  struct zebra_ns *zns = zebra_ns_lookup (NS_DEFAULT); - -  memset(&req.n, 0, sizeof(req.n)); -  memset(&req.ndm, 0, sizeof(req.ndm)); - -  req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg)); -  req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST; -  req.n.nlmsg_type = cmd; //RTM_NEWNEIGH or RTM_DELNEIGH -  req.ndm.ndm_family = AF_INET; -  req.ndm.ndm_state = NUD_PERMANENT; -  req.ndm.ndm_ifindex = ifindex; -  req.ndm.ndm_type = RTN_UNICAST; - -  addattr_l(&req.n, sizeof(req), NDA_DST, &addr, 4); -  addattr_l(&req.n, sizeof(req), NDA_LLADDR, lla, llalen); +	if (IS_ZEBRA_DEBUG_KERNEL) +		zlog_debug("netlink_mpls_multipath() (%s): %s %u/20", routedesc, +			   nl_msg_type_to_str(cmd), label); +} -  return netlink_talk (netlink_talk_filter, &req.n, &zns->netlink_cmd, zns, 0); +static int netlink_neigh_update(int cmd, int ifindex, uint32_t addr, char *lla, +				int llalen) +{ +	struct { +		struct nlmsghdr n; +		struct ndmsg ndm; +		char buf[256]; +	} req; + +	struct zebra_ns *zns = zebra_ns_lookup(NS_DEFAULT); + +	memset(&req.n, 0, sizeof(req.n)); +	memset(&req.ndm, 0, sizeof(req.ndm)); + +	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg)); +	req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST; +	req.n.nlmsg_type = cmd; // RTM_NEWNEIGH or RTM_DELNEIGH +	req.ndm.ndm_family = AF_INET; +	req.ndm.ndm_state = NUD_PERMANENT; +	req.ndm.ndm_ifindex = ifindex; +	req.ndm.ndm_type = RTN_UNICAST; + +	addattr_l(&req.n, sizeof(req), NDA_DST, &addr, 4); +	addattr_l(&req.n, sizeof(req), NDA_LLADDR, lla, llalen); + +	return netlink_talk(netlink_talk_filter, &req.n, &zns->netlink_cmd, zns, +			    0);  }  /* Routing table change via netlink interface. */  /* Update flag indicates whether this is a "replace" or not. */ -static int -netlink_route_multipath (int cmd, struct prefix *p, struct prefix *src_p, -                         struct rib *rib, int update) +static int netlink_route_multipath(int cmd, struct prefix *p, +				   struct prefix *src_p, struct rib *rib, +				   int update)  { -  int bytelen; -  struct sockaddr_nl snl; -  struct nexthop *nexthop = NULL, *tnexthop; -  int recursing; -  unsigned int nexthop_num; -  int discard; -  int family = PREFIX_FAMILY(p); -  const char *routedesc; -  int setsrc = 0; -  union g_addr src; - -  struct -  { -    struct nlmsghdr n; -    struct rtmsg r; -    char buf[NL_PKT_BUF_SIZE]; -  } req; - -  struct zebra_ns *zns = zebra_ns_lookup (NS_DEFAULT); -  struct zebra_vrf *zvrf = vrf_info_lookup (rib->vrf_id); - -  memset (&req, 0, sizeof req - NL_PKT_BUF_SIZE); - -  bytelen = (family == AF_INET ? 4 : 16); - -  req.n.nlmsg_len = NLMSG_LENGTH (sizeof (struct rtmsg)); -  req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST; -  if ((cmd == RTM_NEWROUTE) && update) -    req.n.nlmsg_flags |= NLM_F_REPLACE; -  req.n.nlmsg_type = cmd; -  req.r.rtm_family = family; -  req.r.rtm_dst_len = p->prefixlen; -  req.r.rtm_src_len = src_p ? src_p->prefixlen : 0; -  req.r.rtm_protocol = RTPROT_ZEBRA; -  req.r.rtm_scope = RT_SCOPE_UNIVERSE; - -  if ((rib->flags & ZEBRA_FLAG_BLACKHOLE) || (rib->flags & ZEBRA_FLAG_REJECT)) -    discard = 1; -  else -    discard = 0; - -  if (cmd == RTM_NEWROUTE) -    { -      if (discard) -        { -          if (rib->flags & ZEBRA_FLAG_BLACKHOLE) -            req.r.rtm_type = RTN_BLACKHOLE; -          else if (rib->flags & ZEBRA_FLAG_REJECT) -            req.r.rtm_type = RTN_UNREACHABLE; -          else -            assert (RTN_BLACKHOLE != RTN_UNREACHABLE);  /* false */ -        } -      else -        req.r.rtm_type = RTN_UNICAST; -    } - -  addattr_l (&req.n, sizeof req, RTA_DST, &p->u.prefix, bytelen); -  if (src_p) -    addattr_l (&req.n, sizeof req, RTA_SRC, &src_p->u.prefix, bytelen); - -  /* Metric. */ -  /* Hardcode the metric for all routes coming from zebra. Metric isn't used -   * either by the kernel or by zebra. Its purely for calculating best path(s) -   * by the routing protocol and for communicating with protocol peers. -   */ -  addattr32 (&req.n, sizeof req, RTA_PRIORITY, NL_DEFAULT_ROUTE_METRIC); - -  /* Table corresponding to this route. */ -  if (rib->table < 256) -    req.r.rtm_table = rib->table; -  else -    { -      req.r.rtm_table = RT_TABLE_UNSPEC; -      addattr32(&req.n, sizeof req, RTA_TABLE, rib->table); -    } - -  if (rib->mtu || rib->nexthop_mtu) -    { -      char buf[NL_PKT_BUF_SIZE]; -      struct rtattr *rta = (void *) buf; -      u_int32_t mtu = rib->mtu; -      if (!mtu || (rib->nexthop_mtu && rib->nexthop_mtu < mtu)) -        mtu = rib->nexthop_mtu; -      rta->rta_type = RTA_METRICS; -      rta->rta_len = RTA_LENGTH(0); -      rta_addattr_l (rta, NL_PKT_BUF_SIZE, RTAX_MTU, &mtu, sizeof mtu); -      addattr_l (&req.n, NL_PKT_BUF_SIZE, RTA_METRICS, RTA_DATA (rta), -                 RTA_PAYLOAD (rta)); -    } - -  if (discard) -    { -      if (cmd == RTM_NEWROUTE) -        for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) -          { -            /* We shouldn't encounter recursive nexthops on discard routes, -             * but it is probably better to handle that case correctly anyway. -             */ -            if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) -              continue; -          } -      goto skip; -    } - -  /* Count overall nexthops so we can decide whether to use singlepath -   * or multipath case. */ -  nexthop_num = 0; -  for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) -    { -      if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) -        continue; -      if (cmd == RTM_NEWROUTE && !CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) -        continue; -      if (cmd == RTM_DELROUTE && !CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) -        continue; - -      nexthop_num++; -    } - -  /* Singlepath case. */ -  if (nexthop_num == 1 || multipath_num == 1) -    { -      nexthop_num = 0; -      for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) -        { -          if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) -            { -              if (!setsrc) -                 { -		   if (family == AF_INET) -		     { -		       if (nexthop->rmap_src.ipv4.s_addr != 0) -			 { -			   src.ipv4 = nexthop->rmap_src.ipv4; -			   setsrc = 1; -			 } -		       else if (nexthop->src.ipv4.s_addr != 0) -			 { -			   src.ipv4 = nexthop->src.ipv4; -			   setsrc = 1; -			 } -		     } -		   else if (family == AF_INET6) -		     { -		       if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->rmap_src.ipv6)) -			 { -			   src.ipv6 = nexthop->rmap_src.ipv6; -			   setsrc = 1; -			 } -		       else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->src.ipv6)) -			 { -			   src.ipv6 = nexthop->src.ipv6; -			   setsrc = 1; -			 } -		     } -                 } -              continue; -	    } - -          if ((cmd == RTM_NEWROUTE -               && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) -              || (cmd == RTM_DELROUTE -                  && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))) -            { -              routedesc = recursing ? "recursive, 1 hop" : "single hop"; - -              _netlink_route_debug(cmd, p, nexthop, routedesc, family, zvrf); -              _netlink_route_build_singlepath(routedesc, bytelen, -                                              nexthop, &req.n, &req.r, -                                              sizeof req, cmd); -              nexthop_num++; -              break; -            } -        } -      if (setsrc && (cmd == RTM_NEWROUTE)) -	{ -	  if (family == AF_INET) -	    addattr_l (&req.n, sizeof req, RTA_PREFSRC, &src.ipv4, bytelen); -	  else if (family == AF_INET6) -	    addattr_l (&req.n, sizeof req, RTA_PREFSRC, &src.ipv6, bytelen); +	int bytelen; +	struct sockaddr_nl snl; +	struct nexthop *nexthop = NULL, *tnexthop; +	int recursing; +	unsigned int nexthop_num; +	int discard; +	int family = PREFIX_FAMILY(p); +	const char *routedesc; +	int setsrc = 0; +	union g_addr src; + +	struct { +		struct nlmsghdr n; +		struct rtmsg r; +		char buf[NL_PKT_BUF_SIZE]; +	} req; + +	struct zebra_ns *zns = zebra_ns_lookup(NS_DEFAULT); +	struct zebra_vrf *zvrf = vrf_info_lookup(rib->vrf_id); + +	memset(&req, 0, sizeof req - NL_PKT_BUF_SIZE); + +	bytelen = (family == AF_INET ? 4 : 16); + +	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); +	req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST; +	if ((cmd == RTM_NEWROUTE) && update) +		req.n.nlmsg_flags |= NLM_F_REPLACE; +	req.n.nlmsg_type = cmd; +	req.r.rtm_family = family; +	req.r.rtm_dst_len = p->prefixlen; +	req.r.rtm_src_len = src_p ? src_p->prefixlen : 0; +	req.r.rtm_protocol = RTPROT_ZEBRA; +	req.r.rtm_scope = RT_SCOPE_UNIVERSE; + +	if ((rib->flags & ZEBRA_FLAG_BLACKHOLE) +	    || (rib->flags & ZEBRA_FLAG_REJECT)) +		discard = 1; +	else +		discard = 0; + +	if (cmd == RTM_NEWROUTE) { +		if (discard) { +			if (rib->flags & ZEBRA_FLAG_BLACKHOLE) +				req.r.rtm_type = RTN_BLACKHOLE; +			else if (rib->flags & ZEBRA_FLAG_REJECT) +				req.r.rtm_type = RTN_UNREACHABLE; +			else +				assert(RTN_BLACKHOLE +				       != RTN_UNREACHABLE); /* false */ +		} else +			req.r.rtm_type = RTN_UNICAST;  	} -    } -  else -    { -      char buf[NL_PKT_BUF_SIZE]; -      struct rtattr *rta = (void *) buf; -      struct rtnexthop *rtnh; -      union g_addr *src1 = NULL; - -      rta->rta_type = RTA_MULTIPATH; -      rta->rta_len = RTA_LENGTH (0); -      rtnh = RTA_DATA (rta); - -      nexthop_num = 0; -      for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) -        { -          if (nexthop_num >= multipath_num) -            break; - -          if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) -	    { -              /* This only works for IPv4 now */ -              if (!setsrc) -                 { -		   if (family == AF_INET) -		     { -		       if (nexthop->rmap_src.ipv4.s_addr != 0) -			 { -			   src.ipv4 = nexthop->rmap_src.ipv4; -			   setsrc = 1; -			 } -		       else if (nexthop->src.ipv4.s_addr != 0) -			 { -			   src.ipv4 = nexthop->src.ipv4; -			   setsrc = 1; -			 } -		     } -		   else if (family == AF_INET6) -		     { -		       if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->rmap_src.ipv6)) -			 { -			   src.ipv6 = nexthop->rmap_src.ipv6; -			   setsrc = 1; -			 } -		       else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->src.ipv6)) -			 { -			   src.ipv6 = nexthop->src.ipv6; -			   setsrc = 1; -			 } -		     } -                 } -	      continue; -	    } - -          if ((cmd == RTM_NEWROUTE -               && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) -              || (cmd == RTM_DELROUTE -                  && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))) -            { -              routedesc = recursing ? "recursive, multihop" : "multihop"; -              nexthop_num++; - -              _netlink_route_debug(cmd, p, nexthop, -                                   routedesc, family, zvrf); -              _netlink_route_build_multipath(routedesc, bytelen, -                                             nexthop, rta, rtnh, &req.r, &src1); -              rtnh = RTNH_NEXT (rtnh); - -	      if (!setsrc && src1) -		{ -		  if (family == AF_INET) -		    src.ipv4 = src1->ipv4; -		  else if (family == AF_INET6) -		    src.ipv6 = src1->ipv6; -		  setsrc = 1; -		} -            } -        } -      if (setsrc && (cmd == RTM_NEWROUTE)) -	{ -	  if (family == AF_INET) -	    addattr_l (&req.n, sizeof req, RTA_PREFSRC, &src.ipv4, bytelen); -	  else if (family == AF_INET6) -	    addattr_l (&req.n, sizeof req, RTA_PREFSRC, &src.ipv6, bytelen); -          if (IS_ZEBRA_DEBUG_KERNEL) -	    zlog_debug("Setting source"); +	addattr_l(&req.n, sizeof req, RTA_DST, &p->u.prefix, bytelen); +	if (src_p) +		addattr_l(&req.n, sizeof req, RTA_SRC, &src_p->u.prefix, +			  bytelen); + +	/* Metric. */ +	/* Hardcode the metric for all routes coming from zebra. Metric isn't +	 * used +	 * either by the kernel or by zebra. Its purely for calculating best +	 * path(s) +	 * by the routing protocol and for communicating with protocol peers. +	 */ +	addattr32(&req.n, sizeof req, RTA_PRIORITY, NL_DEFAULT_ROUTE_METRIC); + +	/* Table corresponding to this route. */ +	if (rib->table < 256) +		req.r.rtm_table = rib->table; +	else { +		req.r.rtm_table = RT_TABLE_UNSPEC; +		addattr32(&req.n, sizeof req, RTA_TABLE, rib->table); +	} + +	if (rib->mtu || rib->nexthop_mtu) { +		char buf[NL_PKT_BUF_SIZE]; +		struct rtattr *rta = (void *)buf; +		u_int32_t mtu = rib->mtu; +		if (!mtu || (rib->nexthop_mtu && rib->nexthop_mtu < mtu)) +			mtu = rib->nexthop_mtu; +		rta->rta_type = RTA_METRICS; +		rta->rta_len = RTA_LENGTH(0); +		rta_addattr_l(rta, NL_PKT_BUF_SIZE, RTAX_MTU, &mtu, sizeof mtu); +		addattr_l(&req.n, NL_PKT_BUF_SIZE, RTA_METRICS, RTA_DATA(rta), +			  RTA_PAYLOAD(rta));  	} -      if (rta->rta_len > RTA_LENGTH (0)) -        addattr_l (&req.n, NL_PKT_BUF_SIZE, RTA_MULTIPATH, RTA_DATA (rta), -                   RTA_PAYLOAD (rta)); -    } +	if (discard) { +		if (cmd == RTM_NEWROUTE) +			for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, +					     recursing)) { +				/* We shouldn't encounter recursive nexthops on +				 * discard routes, +				 * but it is probably better to handle that case +				 * correctly anyway. +				 */ +				if (CHECK_FLAG(nexthop->flags, +					       NEXTHOP_FLAG_RECURSIVE)) +					continue; +			} +		goto skip; +	} -  /* If there is no useful nexthop then return. */ -  if (nexthop_num == 0) -    { -      if (IS_ZEBRA_DEBUG_KERNEL) -        zlog_debug ("netlink_route_multipath(): No useful nexthop."); -      return 0; -    } +	/* Count overall nexthops so we can decide whether to use singlepath +	 * or multipath case. */ +	nexthop_num = 0; +	for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) { +		if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) +			continue; +		if (cmd == RTM_NEWROUTE +		    && !CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) +			continue; +		if (cmd == RTM_DELROUTE +		    && !CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)) +			continue; + +		nexthop_num++; +	} + +	/* Singlepath case. */ +	if (nexthop_num == 1 || multipath_num == 1) { +		nexthop_num = 0; +		for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, +				     recursing)) { +			if (CHECK_FLAG(nexthop->flags, +				       NEXTHOP_FLAG_RECURSIVE)) { +				if (!setsrc) { +					if (family == AF_INET) { +						if (nexthop->rmap_src.ipv4 +							    .s_addr +						    != 0) { +							src.ipv4 = +								nexthop->rmap_src +									.ipv4; +							setsrc = 1; +						} else if (nexthop->src.ipv4 +								   .s_addr +							   != 0) { +							src.ipv4 = +								nexthop->src +									.ipv4; +							setsrc = 1; +						} +					} else if (family == AF_INET6) { +						if (!IN6_IS_ADDR_UNSPECIFIED( +							    &nexthop->rmap_src +								     .ipv6)) { +							src.ipv6 = +								nexthop->rmap_src +									.ipv6; +							setsrc = 1; +						} else if ( +							!IN6_IS_ADDR_UNSPECIFIED( +								&nexthop->src +									 .ipv6)) { +							src.ipv6 = +								nexthop->src +									.ipv6; +							setsrc = 1; +						} +					} +				} +				continue; +			} + +			if ((cmd == RTM_NEWROUTE +			     && CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) +			    || (cmd == RTM_DELROUTE +				&& CHECK_FLAG(nexthop->flags, +					      NEXTHOP_FLAG_FIB))) { +				routedesc = recursing ? "recursive, 1 hop" +						      : "single hop"; + +				_netlink_route_debug(cmd, p, nexthop, routedesc, +						     family, zvrf); +				_netlink_route_build_singlepath( +					routedesc, bytelen, nexthop, &req.n, +					&req.r, sizeof req, cmd); +				nexthop_num++; +				break; +			} +		} +		if (setsrc && (cmd == RTM_NEWROUTE)) { +			if (family == AF_INET) +				addattr_l(&req.n, sizeof req, RTA_PREFSRC, +					  &src.ipv4, bytelen); +			else if (family == AF_INET6) +				addattr_l(&req.n, sizeof req, RTA_PREFSRC, +					  &src.ipv6, bytelen); +		} +	} else { +		char buf[NL_PKT_BUF_SIZE]; +		struct rtattr *rta = (void *)buf; +		struct rtnexthop *rtnh; +		union g_addr *src1 = NULL; + +		rta->rta_type = RTA_MULTIPATH; +		rta->rta_len = RTA_LENGTH(0); +		rtnh = RTA_DATA(rta); + +		nexthop_num = 0; +		for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, +				     recursing)) { +			if (nexthop_num >= multipath_num) +				break; + +			if (CHECK_FLAG(nexthop->flags, +				       NEXTHOP_FLAG_RECURSIVE)) { +				/* This only works for IPv4 now */ +				if (!setsrc) { +					if (family == AF_INET) { +						if (nexthop->rmap_src.ipv4 +							    .s_addr +						    != 0) { +							src.ipv4 = +								nexthop->rmap_src +									.ipv4; +							setsrc = 1; +						} else if (nexthop->src.ipv4 +								   .s_addr +							   != 0) { +							src.ipv4 = +								nexthop->src +									.ipv4; +							setsrc = 1; +						} +					} else if (family == AF_INET6) { +						if (!IN6_IS_ADDR_UNSPECIFIED( +							    &nexthop->rmap_src +								     .ipv6)) { +							src.ipv6 = +								nexthop->rmap_src +									.ipv6; +							setsrc = 1; +						} else if ( +							!IN6_IS_ADDR_UNSPECIFIED( +								&nexthop->src +									 .ipv6)) { +							src.ipv6 = +								nexthop->src +									.ipv6; +							setsrc = 1; +						} +					} +				} +				continue; +			} + +			if ((cmd == RTM_NEWROUTE +			     && CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) +			    || (cmd == RTM_DELROUTE +				&& CHECK_FLAG(nexthop->flags, +					      NEXTHOP_FLAG_FIB))) { +				routedesc = recursing ? "recursive, multihop" +						      : "multihop"; +				nexthop_num++; + +				_netlink_route_debug(cmd, p, nexthop, routedesc, +						     family, zvrf); +				_netlink_route_build_multipath( +					routedesc, bytelen, nexthop, rta, rtnh, +					&req.r, &src1); +				rtnh = RTNH_NEXT(rtnh); + +				if (!setsrc && src1) { +					if (family == AF_INET) +						src.ipv4 = src1->ipv4; +					else if (family == AF_INET6) +						src.ipv6 = src1->ipv6; + +					setsrc = 1; +				} +			} +		} +		if (setsrc && (cmd == RTM_NEWROUTE)) { +			if (family == AF_INET) +				addattr_l(&req.n, sizeof req, RTA_PREFSRC, +					  &src.ipv4, bytelen); +			else if (family == AF_INET6) +				addattr_l(&req.n, sizeof req, RTA_PREFSRC, +					  &src.ipv6, bytelen); +			if (IS_ZEBRA_DEBUG_KERNEL) +				zlog_debug("Setting source"); +		} + +		if (rta->rta_len > RTA_LENGTH(0)) +			addattr_l(&req.n, NL_PKT_BUF_SIZE, RTA_MULTIPATH, +				  RTA_DATA(rta), RTA_PAYLOAD(rta)); +	} + +	/* If there is no useful nexthop then return. */ +	if (nexthop_num == 0) { +		if (IS_ZEBRA_DEBUG_KERNEL) +			zlog_debug( +				"netlink_route_multipath(): No useful nexthop."); +		return 0; +	}  skip: -  /* Destination netlink address. */ -  memset (&snl, 0, sizeof snl); -  snl.nl_family = AF_NETLINK; +	/* Destination netlink address. */ +	memset(&snl, 0, sizeof snl); +	snl.nl_family = AF_NETLINK; -  /* Talk to netlink socket. */ -  return netlink_talk (netlink_talk_filter, &req.n, &zns->netlink_cmd, zns, 0); +	/* Talk to netlink socket. */ +	return netlink_talk(netlink_talk_filter, &req.n, &zns->netlink_cmd, zns, +			    0);  } -int -kernel_get_ipmr_sg_stats (void *in) +int kernel_get_ipmr_sg_stats(void *in)  { -  int suc = 0; -  struct mcast_route_data *mr = (struct mcast_route_data *)in; -  struct { -      struct nlmsghdr         n; -      struct ndmsg            ndm; -      char                    buf[256]; -  } req; - -  mroute = mr; -  struct zebra_ns *zns = zebra_ns_lookup (NS_DEFAULT); - -  memset(&req.n, 0, sizeof(req.n)); -  memset(&req.ndm, 0, sizeof(req.ndm)); - -  req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg)); -  req.n.nlmsg_flags = NLM_F_REQUEST; -  req.ndm.ndm_family = AF_INET; -  req.n.nlmsg_type = RTM_GETROUTE; - -  addattr_l (&req.n, sizeof (req), RTA_IIF, &mroute->ifindex, 4); -  addattr_l (&req.n, sizeof (req), RTA_OIF, &mroute->ifindex, 4); -  addattr_l (&req.n, sizeof (req), RTA_SRC, &mroute->sg.src.s_addr, 4); -  addattr_l (&req.n, sizeof (req), RTA_DST, &mroute->sg.grp.s_addr, 4); - -  suc = netlink_talk (netlink_route_change_read_multicast, &req.n, &zns->netlink_cmd, zns, 0); - -  mroute = NULL; -  return suc; +	int suc = 0; +	struct mcast_route_data *mr = (struct mcast_route_data *)in; +	struct { +		struct nlmsghdr n; +		struct ndmsg ndm; +		char buf[256]; +	} req; + +	mroute = mr; +	struct zebra_ns *zns = zebra_ns_lookup(NS_DEFAULT); + +	memset(&req.n, 0, sizeof(req.n)); +	memset(&req.ndm, 0, sizeof(req.ndm)); + +	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg)); +	req.n.nlmsg_flags = NLM_F_REQUEST; +	req.ndm.ndm_family = AF_INET; +	req.n.nlmsg_type = RTM_GETROUTE; + +	addattr_l(&req.n, sizeof(req), RTA_IIF, &mroute->ifindex, 4); +	addattr_l(&req.n, sizeof(req), RTA_OIF, &mroute->ifindex, 4); +	addattr_l(&req.n, sizeof(req), RTA_SRC, &mroute->sg.src.s_addr, 4); +	addattr_l(&req.n, sizeof(req), RTA_DST, &mroute->sg.grp.s_addr, 4); + +	suc = netlink_talk(netlink_route_change_read_multicast, &req.n, +			   &zns->netlink_cmd, zns, 0); + +	mroute = NULL; +	return suc;  } -int -kernel_route_rib (struct prefix *p, struct prefix *src_p, -                  struct rib *old, struct rib *new) +int kernel_route_rib(struct prefix *p, struct prefix *src_p, struct rib *old, +		     struct rib *new)  { -  if (!old && new) -    return netlink_route_multipath (RTM_NEWROUTE, p, src_p, new, 0); -  if (old && !new) -    return netlink_route_multipath (RTM_DELROUTE, p, src_p, old, 0); +	if (!old && new) +		return netlink_route_multipath(RTM_NEWROUTE, p, src_p, new, 0); +	if (old && !new) +		return netlink_route_multipath(RTM_DELROUTE, p, src_p, old, 0); -  return netlink_route_multipath (RTM_NEWROUTE, p, src_p, new, 1); +	return netlink_route_multipath(RTM_NEWROUTE, p, src_p, new, 1);  } -int -kernel_neigh_update (int add, int ifindex, uint32_t addr, char *lla, int llalen) +int kernel_neigh_update(int add, int ifindex, uint32_t addr, char *lla, +			int llalen)  { -  return netlink_neigh_update(add ? RTM_NEWNEIGH : RTM_DELNEIGH, ifindex, addr, -			      lla, llalen); +	return netlink_neigh_update(add ? RTM_NEWNEIGH : RTM_DELNEIGH, ifindex, +				    addr, lla, llalen);  }  /*   * MPLS label forwarding table change via netlink interface.   */ -int -netlink_mpls_multipath (int cmd, zebra_lsp_t *lsp) +int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp)  { -  mpls_lse_t lse; -  zebra_nhlfe_t *nhlfe; -  struct nexthop *nexthop = NULL; -  unsigned int nexthop_num; -  const char *routedesc; -  struct zebra_ns *zns = zebra_ns_lookup (NS_DEFAULT); - -  struct -  { -    struct nlmsghdr n; -    struct rtmsg r; -    char buf[NL_PKT_BUF_SIZE]; -  } req; - -  memset (&req, 0, sizeof req - NL_PKT_BUF_SIZE); - - -  /* -   * Count # nexthops so we can decide whether to use singlepath -   * or multipath case. -   */ -  nexthop_num = 0; -  for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) -    { -      nexthop = nhlfe->nexthop; -      if (!nexthop) -        continue; -      if (cmd == RTM_NEWROUTE) -        { -          /* Count all selected NHLFEs */ -          if (CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_SELECTED) && -              CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) -            nexthop_num++; -        } -      else /* DEL */ -        { -          /* Count all installed NHLFEs */ -          if (CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_INSTALLED) && -              CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) -            nexthop_num++; -        } -    } - -  if (nexthop_num == 0) // unexpected -    return 0; - -  req.n.nlmsg_len = NLMSG_LENGTH (sizeof (struct rtmsg)); -  req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST; -  req.n.nlmsg_type = cmd; -  req.r.rtm_family = AF_MPLS; -  req.r.rtm_table = RT_TABLE_MAIN; -  req.r.rtm_dst_len = MPLS_LABEL_LEN_BITS; -  req.r.rtm_protocol = RTPROT_ZEBRA; -  req.r.rtm_scope = RT_SCOPE_UNIVERSE; -  req.r.rtm_type = RTN_UNICAST; - -  if (cmd == RTM_NEWROUTE) -    /* We do a replace to handle update. */ -    req.n.nlmsg_flags |= NLM_F_REPLACE; - -  /* Fill destination */ -  lse = mpls_lse_encode (lsp->ile.in_label, 0, 0, 1); -  addattr_l (&req.n, sizeof req, RTA_DST, &lse, sizeof(mpls_lse_t)); - -  /* Fill nexthops (paths) based on single-path or multipath. The paths -   * chosen depend on the operation. -   */ -  if (nexthop_num == 1 || multipath_num == 1) -    { -      routedesc = "single hop"; -      _netlink_mpls_debug(cmd, lsp->ile.in_label, routedesc); - -      nexthop_num = 0; -      for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) -        { -          nexthop = nhlfe->nexthop; -          if (!nexthop) -            continue; - -          if ((cmd == RTM_NEWROUTE && -               (CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_SELECTED) && -                CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))) || -              (cmd == RTM_DELROUTE && -               (CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_INSTALLED) && -                CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)))) -            { -              /* Add the gateway */ -              _netlink_mpls_build_singlepath(routedesc, nhlfe, -                                             &req.n, &req.r, sizeof req, cmd); -              if (cmd == RTM_NEWROUTE) -                { -                  SET_FLAG (nhlfe->flags, NHLFE_FLAG_INSTALLED); -                  SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); -                } -              else -                { -                  UNSET_FLAG (nhlfe->flags, NHLFE_FLAG_INSTALLED); -                  UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); -                } -              nexthop_num++; -              break; -            } -        } -    } -  else /* Multipath case */ -    { -      char buf[NL_PKT_BUF_SIZE]; -      struct rtattr *rta = (void *) buf; -      struct rtnexthop *rtnh; -      union g_addr *src1 = NULL; - -      rta->rta_type = RTA_MULTIPATH; -      rta->rta_len = RTA_LENGTH (0); -      rtnh = RTA_DATA (rta); - -      routedesc = "multihop"; -      _netlink_mpls_debug(cmd, lsp->ile.in_label, routedesc); - -      nexthop_num = 0; -      for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) -        { -          nexthop = nhlfe->nexthop; -          if (!nexthop) -            continue; - -          if (nexthop_num >= multipath_num) -            break; - -          if ((cmd == RTM_NEWROUTE && -               (CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_SELECTED) && -                CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))) || -              (cmd == RTM_DELROUTE && -               (CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_INSTALLED) && -                CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)))) -            { -              nexthop_num++; - -              /* Build the multipath */ -              _netlink_mpls_build_multipath(routedesc, nhlfe, rta, -                                            rtnh, &req.r, &src1); -              rtnh = RTNH_NEXT (rtnh); - -              if (cmd == RTM_NEWROUTE) -                { -                  SET_FLAG (nhlfe->flags, NHLFE_FLAG_INSTALLED); -                  SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); -                } -              else -                { -                  UNSET_FLAG (nhlfe->flags, NHLFE_FLAG_INSTALLED); -                  UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); -                } - -            } -        } - -      /* Add the multipath */ -      if (rta->rta_len > RTA_LENGTH (0)) -        addattr_l (&req.n, NL_PKT_BUF_SIZE, RTA_MULTIPATH, RTA_DATA (rta), -                   RTA_PAYLOAD (rta)); -    } - -  /* Talk to netlink socket. */ -  return netlink_talk (netlink_talk_filter, &req.n, &zns->netlink_cmd, zns, 0); +	mpls_lse_t lse; +	zebra_nhlfe_t *nhlfe; +	struct nexthop *nexthop = NULL; +	unsigned int nexthop_num; +	const char *routedesc; +	struct zebra_ns *zns = zebra_ns_lookup(NS_DEFAULT); + +	struct { +		struct nlmsghdr n; +		struct rtmsg r; +		char buf[NL_PKT_BUF_SIZE]; +	} req; + +	memset(&req, 0, sizeof req - NL_PKT_BUF_SIZE); + + +	/* +	 * Count # nexthops so we can decide whether to use singlepath +	 * or multipath case. +	 */ +	nexthop_num = 0; +	for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) { +		nexthop = nhlfe->nexthop; +		if (!nexthop) +			continue; +		if (cmd == RTM_NEWROUTE) { +			/* Count all selected NHLFEs */ +			if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_SELECTED) +			    && CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) +				nexthop_num++; +		} else /* DEL */ +		{ +			/* Count all installed NHLFEs */ +			if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED) +			    && CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)) +				nexthop_num++; +		} +	} + +	if (nexthop_num == 0) // unexpected +		return 0; + +	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); +	req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST; +	req.n.nlmsg_type = cmd; +	req.r.rtm_family = AF_MPLS; +	req.r.rtm_table = RT_TABLE_MAIN; +	req.r.rtm_dst_len = MPLS_LABEL_LEN_BITS; +	req.r.rtm_protocol = RTPROT_ZEBRA; +	req.r.rtm_scope = RT_SCOPE_UNIVERSE; +	req.r.rtm_type = RTN_UNICAST; + +	if (cmd == RTM_NEWROUTE) +		/* We do a replace to handle update. */ +		req.n.nlmsg_flags |= NLM_F_REPLACE; + +	/* Fill destination */ +	lse = mpls_lse_encode(lsp->ile.in_label, 0, 0, 1); +	addattr_l(&req.n, sizeof req, RTA_DST, &lse, sizeof(mpls_lse_t)); + +	/* Fill nexthops (paths) based on single-path or multipath. The paths +	 * chosen depend on the operation. +	 */ +	if (nexthop_num == 1 || multipath_num == 1) { +		routedesc = "single hop"; +		_netlink_mpls_debug(cmd, lsp->ile.in_label, routedesc); + +		nexthop_num = 0; +		for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) { +			nexthop = nhlfe->nexthop; +			if (!nexthop) +				continue; + +			if ((cmd == RTM_NEWROUTE +			     && (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_SELECTED) +				 && CHECK_FLAG(nexthop->flags, +					       NEXTHOP_FLAG_ACTIVE))) +			    || (cmd == RTM_DELROUTE +				&& (CHECK_FLAG(nhlfe->flags, +					       NHLFE_FLAG_INSTALLED) +				    && CHECK_FLAG(nexthop->flags, +						  NEXTHOP_FLAG_FIB)))) { +				/* Add the gateway */ +				_netlink_mpls_build_singlepath(routedesc, nhlfe, +							       &req.n, &req.r, +							       sizeof req, cmd); +				if (cmd == RTM_NEWROUTE) { +					SET_FLAG(nhlfe->flags, +						 NHLFE_FLAG_INSTALLED); +					SET_FLAG(nexthop->flags, +						 NEXTHOP_FLAG_FIB); +				} else { +					UNSET_FLAG(nhlfe->flags, +						   NHLFE_FLAG_INSTALLED); +					UNSET_FLAG(nexthop->flags, +						   NEXTHOP_FLAG_FIB); +				} +				nexthop_num++; +				break; +			} +		} +	} else /* Multipath case */ +	{ +		char buf[NL_PKT_BUF_SIZE]; +		struct rtattr *rta = (void *)buf; +		struct rtnexthop *rtnh; +		union g_addr *src1 = NULL; + +		rta->rta_type = RTA_MULTIPATH; +		rta->rta_len = RTA_LENGTH(0); +		rtnh = RTA_DATA(rta); + +		routedesc = "multihop"; +		_netlink_mpls_debug(cmd, lsp->ile.in_label, routedesc); + +		nexthop_num = 0; +		for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) { +			nexthop = nhlfe->nexthop; +			if (!nexthop) +				continue; + +			if (nexthop_num >= multipath_num) +				break; + +			if ((cmd == RTM_NEWROUTE +			     && (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_SELECTED) +				 && CHECK_FLAG(nexthop->flags, +					       NEXTHOP_FLAG_ACTIVE))) +			    || (cmd == RTM_DELROUTE +				&& (CHECK_FLAG(nhlfe->flags, +					       NHLFE_FLAG_INSTALLED) +				    && CHECK_FLAG(nexthop->flags, +						  NEXTHOP_FLAG_FIB)))) { +				nexthop_num++; + +				/* Build the multipath */ +				_netlink_mpls_build_multipath(routedesc, nhlfe, +							      rta, rtnh, &req.r, +							      &src1); +				rtnh = RTNH_NEXT(rtnh); + +				if (cmd == RTM_NEWROUTE) { +					SET_FLAG(nhlfe->flags, +						 NHLFE_FLAG_INSTALLED); +					SET_FLAG(nexthop->flags, +						 NEXTHOP_FLAG_FIB); +				} else { +					UNSET_FLAG(nhlfe->flags, +						   NHLFE_FLAG_INSTALLED); +					UNSET_FLAG(nexthop->flags, +						   NEXTHOP_FLAG_FIB); +				} +			} +		} + +		/* Add the multipath */ +		if (rta->rta_len > RTA_LENGTH(0)) +			addattr_l(&req.n, NL_PKT_BUF_SIZE, RTA_MULTIPATH, +				  RTA_DATA(rta), RTA_PAYLOAD(rta)); +	} + +	/* Talk to netlink socket. */ +	return netlink_talk(netlink_talk_filter, &req.n, &zns->netlink_cmd, zns, +			    0);  }  /*   * Handle failure in LSP install, clear flags for NHLFE.   */ -void -clear_nhlfe_installed (zebra_lsp_t *lsp) +void clear_nhlfe_installed(zebra_lsp_t *lsp)  { -  zebra_nhlfe_t *nhlfe; -  struct nexthop *nexthop; - -  for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) -    { -      nexthop = nhlfe->nexthop; -      if (!nexthop) -        continue; - -      UNSET_FLAG (nhlfe->flags, NHLFE_FLAG_INSTALLED); -      UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); -    } +	zebra_nhlfe_t *nhlfe; +	struct nexthop *nexthop; + +	for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) { +		nexthop = nhlfe->nexthop; +		if (!nexthop) +			continue; + +		UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED); +		UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); +	}  } diff --git a/zebra/rt_netlink.h b/zebra/rt_netlink.h index 93ee622e35..8ac8069cd7 100644 --- a/zebra/rt_netlink.h +++ b/zebra/rt_netlink.h @@ -28,14 +28,12 @@  #define NL_DEFAULT_ROUTE_METRIC 20 -extern void -clear_nhlfe_installed (zebra_lsp_t *lsp); -extern int -netlink_mpls_multipath (int cmd, zebra_lsp_t *lsp); - -extern int netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h, -                                 ns_id_t ns_id, int startup); -extern int netlink_route_read (struct zebra_ns *zns); +extern void clear_nhlfe_installed(zebra_lsp_t *lsp); +extern int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp); + +extern int netlink_route_change(struct sockaddr_nl *snl, struct nlmsghdr *h, +				ns_id_t ns_id, int startup); +extern int netlink_route_read(struct zebra_ns *zns);  #endif /* HAVE_NETLINK */ diff --git a/zebra/rt_socket.c b/zebra/rt_socket.c index 647532761f..caf653b246 100644 --- a/zebra/rt_socket.c +++ b/zebra/rt_socket.c @@ -17,7 +17,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #include <zebra.h> @@ -40,318 +40,307 @@  extern struct zebra_privs_t zserv_privs;  /* kernel socket export */ -extern int rtm_write (int message, union sockunion *dest, -                      union sockunion *mask, union sockunion *gate, -                      union sockunion *mpls, unsigned int index, -                      int zebra_flags, int metric); +extern int rtm_write(int message, union sockunion *dest, union sockunion *mask, +		     union sockunion *gate, union sockunion *mpls, +		     unsigned int index, int zebra_flags, int metric);  #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN  /* Adjust netmask socket length. Return value is a adjusted sin_len     value. */ -static int -sin_masklen (struct in_addr mask) +static int sin_masklen(struct in_addr mask)  { -  char *p, *lim; -  int len; -  struct sockaddr_in sin; +	char *p, *lim; +	int len; +	struct sockaddr_in sin; -  if (mask.s_addr == 0)  -    return sizeof (long); +	if (mask.s_addr == 0) +		return sizeof(long); -  sin.sin_addr = mask; -  len = sizeof (struct sockaddr_in); +	sin.sin_addr = mask; +	len = sizeof(struct sockaddr_in); -  lim = (char *) &sin.sin_addr; -  p = lim + sizeof (sin.sin_addr); +	lim = (char *)&sin.sin_addr; +	p = lim + sizeof(sin.sin_addr); -  while (*--p == 0 && p >= lim)  -    len--; -  return len; +	while (*--p == 0 && p >= lim) +		len--; +	return len;  }  #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */  /* Interface between zebra message and rtm message. */ -static int -kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib *rib) +static int kernel_rtm_ipv4(int cmd, struct prefix *p, struct rib *rib)  { -  struct sockaddr_in *mask = NULL; -  struct sockaddr_in sin_dest, sin_mask, sin_gate; +	struct sockaddr_in *mask = NULL; +	struct sockaddr_in sin_dest, sin_mask, sin_gate;  #ifdef __OpenBSD__ -  struct sockaddr_mpls smpls; +	struct sockaddr_mpls smpls;  #endif -  union sockunion *smplsp = NULL; -  struct nexthop *nexthop, *tnexthop; -  int recursing; -  int nexthop_num = 0; -  ifindex_t ifindex = 0; -  int gate = 0; -  int error; -  char prefix_buf[PREFIX_STRLEN]; - -  if (IS_ZEBRA_DEBUG_RIB) -    prefix2str (p, prefix_buf, sizeof(prefix_buf)); -  memset (&sin_dest, 0, sizeof (struct sockaddr_in)); -  sin_dest.sin_family = AF_INET; +	union sockunion *smplsp = NULL; +	struct nexthop *nexthop, *tnexthop; +	int recursing; +	int nexthop_num = 0; +	ifindex_t ifindex = 0; +	int gate = 0; +	int error; +	char prefix_buf[PREFIX_STRLEN]; + +	if (IS_ZEBRA_DEBUG_RIB) +		prefix2str(p, prefix_buf, sizeof(prefix_buf)); +	memset(&sin_dest, 0, sizeof(struct sockaddr_in)); +	sin_dest.sin_family = AF_INET;  #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN -  sin_dest.sin_len = sizeof (struct sockaddr_in); +	sin_dest.sin_len = sizeof(struct sockaddr_in);  #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ -  sin_dest.sin_addr = p->u.prefix4; +	sin_dest.sin_addr = p->u.prefix4; -  memset (&sin_mask, 0, sizeof (struct sockaddr_in)); +	memset(&sin_mask, 0, sizeof(struct sockaddr_in)); -  memset (&sin_gate, 0, sizeof (struct sockaddr_in)); -  sin_gate.sin_family = AF_INET; +	memset(&sin_gate, 0, sizeof(struct sockaddr_in)); +	sin_gate.sin_family = AF_INET;  #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN -  sin_gate.sin_len = sizeof (struct sockaddr_in); +	sin_gate.sin_len = sizeof(struct sockaddr_in);  #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ -  /* Make gateway. */ -  for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) -    { -      if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) -        continue; - -      gate = 0; -      char gate_buf[INET_ADDRSTRLEN] = "NULL"; - -      /* -       * XXX We need to refrain from kernel operations in some cases, -       * but this if statement seems overly cautious - what about -       * other than ADD and DELETE? -       */ -      if ((cmd == RTM_ADD -	   && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) -	  || (cmd == RTM_DELETE -	      && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) -	      )) -	{ -	  if (nexthop->type == NEXTHOP_TYPE_IPV4 || -	      nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) -	    { -	      sin_gate.sin_addr = nexthop->gate.ipv4; -	      gate = 1; -	    } -	  if (nexthop->type == NEXTHOP_TYPE_IFINDEX -	      || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) -	    ifindex = nexthop->ifindex; -	  if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE) -	    { -	      struct in_addr loopback; -	      loopback.s_addr = htonl (INADDR_LOOPBACK); -	      sin_gate.sin_addr = loopback; -	      gate = 1; -	    } - -	  if (gate && p->prefixlen == 32) -	    mask = NULL; -	  else -	    { -	      masklen2ip (p->prefixlen, &sin_mask.sin_addr); -	      sin_mask.sin_family = AF_INET; +	/* Make gateway. */ +	for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) { +		if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) +			continue; + +		gate = 0; +		char gate_buf[INET_ADDRSTRLEN] = "NULL"; + +		/* +		 * XXX We need to refrain from kernel operations in some cases, +		 * but this if statement seems overly cautious - what about +		 * other than ADD and DELETE? +		 */ +		if ((cmd == RTM_ADD +		     && CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) +		    || (cmd == RTM_DELETE +			&& CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))) { +			if (nexthop->type == NEXTHOP_TYPE_IPV4 +			    || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) { +				sin_gate.sin_addr = nexthop->gate.ipv4; +				gate = 1; +			} +			if (nexthop->type == NEXTHOP_TYPE_IFINDEX +			    || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) +				ifindex = nexthop->ifindex; +			if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE) { +				struct in_addr loopback; +				loopback.s_addr = htonl(INADDR_LOOPBACK); +				sin_gate.sin_addr = loopback; +				gate = 1; +			} + +			if (gate && p->prefixlen == 32) +				mask = NULL; +			else { +				masklen2ip(p->prefixlen, &sin_mask.sin_addr); +				sin_mask.sin_family = AF_INET;  #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN -	      sin_mask.sin_len = sin_masklen (sin_mask.sin_addr); +				sin_mask.sin_len = +					sin_masklen(sin_mask.sin_addr);  #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ -	      mask = &sin_mask; -	    } +				mask = &sin_mask; +			}  #ifdef __OpenBSD__ -	  if (nexthop->nh_label) -	    { -	      memset (&smpls, 0, sizeof (smpls)); -	      smpls.smpls_len = sizeof (smpls); -	      smpls.smpls_family = AF_MPLS; -	      smpls.smpls_label = -		htonl (nexthop->nh_label->label[0] << MPLS_LABEL_OFFSET); -	      smplsp = (union sockunion *)&smpls; -	    } +			if (nexthop->nh_label) { +				memset(&smpls, 0, sizeof(smpls)); +				smpls.smpls_len = sizeof(smpls); +				smpls.smpls_family = AF_MPLS; +				smpls.smpls_label = +					htonl(nexthop->nh_label->label[0] +					      << MPLS_LABEL_OFFSET); +				smplsp = (union sockunion *)&smpls; +			}  #endif -	  error = rtm_write (cmd, -			     (union sockunion *)&sin_dest,  -			     (union sockunion *)mask,  -			     gate ? (union sockunion *)&sin_gate : NULL, -			     smplsp, -			     ifindex, -			     rib->flags, -			     rib->metric); - -           if (IS_ZEBRA_DEBUG_RIB) -           { -             if (!gate) -             { -               zlog_debug ("%s: %s: attention! gate not found for rib %p", -                 __func__, prefix_buf, rib); -               rib_dump (p, NULL, rib); -             } -             else -               inet_ntop (AF_INET, &sin_gate.sin_addr, gate_buf, INET_ADDRSTRLEN); -           } -  -           switch (error) -           { -             /* We only flag nexthops as being in FIB if rtm_write() did its work. */ -             case ZEBRA_ERR_NOERROR: -               nexthop_num++; -               if (IS_ZEBRA_DEBUG_RIB) -                 zlog_debug ("%s: %s: successfully did NH %s", -                   __func__, prefix_buf, gate_buf); -               if (cmd == RTM_ADD) -                 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); -               break; -  -             /* The only valid case for this error is kernel's failure to install -              * a multipath route, which is common for FreeBSD. This should be -              * ignored silently, but logged as an error otherwise. -              */ -             case ZEBRA_ERR_RTEXIST: -               if (cmd != RTM_ADD) -                 zlog_err ("%s: rtm_write() returned %d for command %d", -                   __func__, error, cmd); -               continue; -               break; -  -             /* Given that our NEXTHOP_FLAG_FIB matches real kernel FIB, it isn't -              * normal to get any other messages in ANY case. -              */ -             case ZEBRA_ERR_RTNOEXIST: -             case ZEBRA_ERR_RTUNREACH: -             default: -               zlog_err ("%s: %s: rtm_write() unexpectedly returned %d for command %s", -                 __func__, prefix2str(p, prefix_buf, sizeof(prefix_buf)), -                 error, lookup_msg(rtm_type_str, cmd, NULL)); -               break; -           } -         } /* if (cmd and flags make sense) */ -       else -         if (IS_ZEBRA_DEBUG_RIB) -           zlog_debug ("%s: odd command %s for flags %d", -             __func__, lookup_msg(rtm_type_str, cmd, NULL), nexthop->flags); -     } /* for (ALL_NEXTHOPS_RO(...))*/ -  -   /* If there was no useful nexthop, then complain. */ -   if (nexthop_num == 0 && IS_ZEBRA_DEBUG_KERNEL) -     zlog_debug ("%s: No useful nexthops were found in RIB entry %p", __func__, rib); - -  return 0; /*XXX*/ +			error = rtm_write( +				cmd, (union sockunion *)&sin_dest, +				(union sockunion *)mask, +				gate ? (union sockunion *)&sin_gate : NULL, +				smplsp, ifindex, rib->flags, rib->metric); + +			if (IS_ZEBRA_DEBUG_RIB) { +				if (!gate) { +					zlog_debug( +						"%s: %s: attention! gate not found for rib %p", +						__func__, prefix_buf, rib); +					rib_dump(p, NULL, rib); +				} else +					inet_ntop(AF_INET, &sin_gate.sin_addr, +						  gate_buf, INET_ADDRSTRLEN); +			} + +			switch (error) { +			/* We only flag nexthops as being in FIB if rtm_write() +			 * did its work. */ +			case ZEBRA_ERR_NOERROR: +				nexthop_num++; +				if (IS_ZEBRA_DEBUG_RIB) +					zlog_debug( +						"%s: %s: successfully did NH %s", +						__func__, prefix_buf, gate_buf); +				if (cmd == RTM_ADD) +					SET_FLAG(nexthop->flags, +						 NEXTHOP_FLAG_FIB); +				break; + +			/* The only valid case for this error is kernel's +			 * failure to install +			 * a multipath route, which is common for FreeBSD. This +			 * should be +			 * ignored silently, but logged as an error otherwise. +			 */ +			case ZEBRA_ERR_RTEXIST: +				if (cmd != RTM_ADD) +					zlog_err( +						"%s: rtm_write() returned %d for command %d", +						__func__, error, cmd); +				continue; +				break; + +			/* Given that our NEXTHOP_FLAG_FIB matches real kernel +			 * FIB, it isn't +			 * normal to get any other messages in ANY case. +			 */ +			case ZEBRA_ERR_RTNOEXIST: +			case ZEBRA_ERR_RTUNREACH: +			default: +				zlog_err( +					"%s: %s: rtm_write() unexpectedly returned %d for command %s", +					__func__, +					prefix2str(p, prefix_buf, +						   sizeof(prefix_buf)), +					error, +					lookup_msg(rtm_type_str, cmd, NULL)); +				break; +			} +		} /* if (cmd and flags make sense) */ +		else if (IS_ZEBRA_DEBUG_RIB) +			zlog_debug("%s: odd command %s for flags %d", __func__, +				   lookup_msg(rtm_type_str, cmd, NULL), +				   nexthop->flags); +	} /* for (ALL_NEXTHOPS_RO(...))*/ + +	/* If there was no useful nexthop, then complain. */ +	if (nexthop_num == 0 && IS_ZEBRA_DEBUG_KERNEL) +		zlog_debug("%s: No useful nexthops were found in RIB entry %p", +			   __func__, rib); + +	return 0; /*XXX*/  }  #ifdef SIN6_LEN  /* Calculate sin6_len value for netmask socket value. */ -static int -sin6_masklen (struct in6_addr mask) +static int sin6_masklen(struct in6_addr mask)  { -  struct sockaddr_in6 sin6; -  char *p, *lim; -  int len; +	struct sockaddr_in6 sin6; +	char *p, *lim; +	int len; -  if (IN6_IS_ADDR_UNSPECIFIED (&mask))  -    return sizeof (long); +	if (IN6_IS_ADDR_UNSPECIFIED(&mask)) +		return sizeof(long); -  sin6.sin6_addr = mask; -  len = sizeof (struct sockaddr_in6); +	sin6.sin6_addr = mask; +	len = sizeof(struct sockaddr_in6); -  lim = (char *) & sin6.sin6_addr; -  p = lim + sizeof (sin6.sin6_addr); +	lim = (char *)&sin6.sin6_addr; +	p = lim + sizeof(sin6.sin6_addr); -  while (*--p == 0 && p >= lim)  -    len--; +	while (*--p == 0 && p >= lim) +		len--; -  return len; +	return len;  }  #endif /* SIN6_LEN */  /* Interface between zebra message and rtm message. */ -static int -kernel_rtm_ipv6 (int cmd, struct prefix *p, struct rib *rib) +static int kernel_rtm_ipv6(int cmd, struct prefix *p, struct rib *rib)  { -  struct sockaddr_in6 *mask; -  struct sockaddr_in6 sin_dest, sin_mask, sin_gate; -  struct nexthop *nexthop, *tnexthop; -  int recursing; -  int nexthop_num = 0; -  ifindex_t ifindex = 0; -  int gate = 0; -  int error; - -  memset (&sin_dest, 0, sizeof (struct sockaddr_in6)); -  sin_dest.sin6_family = AF_INET6; +	struct sockaddr_in6 *mask; +	struct sockaddr_in6 sin_dest, sin_mask, sin_gate; +	struct nexthop *nexthop, *tnexthop; +	int recursing; +	int nexthop_num = 0; +	ifindex_t ifindex = 0; +	int gate = 0; +	int error; + +	memset(&sin_dest, 0, sizeof(struct sockaddr_in6)); +	sin_dest.sin6_family = AF_INET6;  #ifdef SIN6_LEN -  sin_dest.sin6_len = sizeof (struct sockaddr_in6); +	sin_dest.sin6_len = sizeof(struct sockaddr_in6);  #endif /* SIN6_LEN */ -  sin_dest.sin6_addr = p->u.prefix6; +	sin_dest.sin6_addr = p->u.prefix6; -  memset (&sin_mask, 0, sizeof (struct sockaddr_in6)); +	memset(&sin_mask, 0, sizeof(struct sockaddr_in6)); -  memset (&sin_gate, 0, sizeof (struct sockaddr_in6)); -  sin_gate.sin6_family = AF_INET6; +	memset(&sin_gate, 0, sizeof(struct sockaddr_in6)); +	sin_gate.sin6_family = AF_INET6;  #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN -  sin_gate.sin6_len = sizeof (struct sockaddr_in6); +	sin_gate.sin6_len = sizeof(struct sockaddr_in6);  #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ -  /* Make gateway. */ -  for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) -    { -      if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) -	continue; +	/* Make gateway. */ +	for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) { +		if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) +			continue; -      gate = 0; +		gate = 0; -      if ((cmd == RTM_ADD -	   && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) -	  || (cmd == RTM_DELETE +		if ((cmd == RTM_ADD +		     && CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) +		    || (cmd == RTM_DELETE  #if 0  	      && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)  #endif -	      )) -	{ -	  if (nexthop->type == NEXTHOP_TYPE_IPV6 -	      || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) -	    { -	      sin_gate.sin6_addr = nexthop->gate.ipv6; -	      gate = 1; -	    } -	  if (nexthop->type == NEXTHOP_TYPE_IFINDEX -	      || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) -	    ifindex = nexthop->ifindex; - -	  if (cmd == RTM_ADD) -	    SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); -	} - -      /* Under kame set interface index to link local address. */ +			)) { +			if (nexthop->type == NEXTHOP_TYPE_IPV6 +			    || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) { +				sin_gate.sin6_addr = nexthop->gate.ipv6; +				gate = 1; +			} +			if (nexthop->type == NEXTHOP_TYPE_IFINDEX +			    || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) +				ifindex = nexthop->ifindex; + +			if (cmd == RTM_ADD) +				SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); +		} + +/* Under kame set interface index to link local address. */  #ifdef KAME -#define SET_IN6_LINKLOCAL_IFINDEX(a, i) \ -      do { \ -	(a).s6_addr[2] = ((i) >> 8) & 0xff; \ -	(a).s6_addr[3] = (i) & 0xff; \ -      } while (0) +#define SET_IN6_LINKLOCAL_IFINDEX(a, i)                                        \ +	do {                                                                   \ +		(a).s6_addr[2] = ((i) >> 8) & 0xff;                            \ +		(a).s6_addr[3] = (i)&0xff;                                     \ +	} while (0) -      if (gate && IN6_IS_ADDR_LINKLOCAL(&sin_gate.sin6_addr)) -	SET_IN6_LINKLOCAL_IFINDEX (sin_gate.sin6_addr, ifindex); +		if (gate && IN6_IS_ADDR_LINKLOCAL(&sin_gate.sin6_addr)) +			SET_IN6_LINKLOCAL_IFINDEX(sin_gate.sin6_addr, ifindex);  #endif /* KAME */ -      if (gate && p->prefixlen == 128) -	mask = NULL; -      else -	{ -	  masklen2ip6 (p->prefixlen, &sin_mask.sin6_addr); -	  sin_mask.sin6_family = AF_INET6; +		if (gate && p->prefixlen == 128) +			mask = NULL; +		else { +			masklen2ip6(p->prefixlen, &sin_mask.sin6_addr); +			sin_mask.sin6_family = AF_INET6;  #ifdef SIN6_LEN -	  sin_mask.sin6_len = sin6_masklen (sin_mask.sin6_addr); +			sin_mask.sin6_len = sin6_masklen(sin_mask.sin6_addr);  #endif /* SIN6_LEN */ -	  mask = &sin_mask; -	} +			mask = &sin_mask; +		} -      error = rtm_write (cmd, -			(union sockunion *) &sin_dest, -			(union sockunion *) mask, -			gate ? (union sockunion *)&sin_gate : NULL, -			NULL, -			ifindex, -			rib->flags, -			rib->metric); +		error = rtm_write(cmd, (union sockunion *)&sin_dest, +				  (union sockunion *)mask, +				  gate ? (union sockunion *)&sin_gate : NULL, +				  NULL, ifindex, rib->flags, rib->metric);  #if 0        if (error) @@ -360,72 +349,66 @@ kernel_rtm_ipv6 (int cmd, struct prefix *p, struct rib *rib)  	    nexthop_num, error);  	}  #else -      (void)error; +		(void)error;  #endif -      nexthop_num++; -    } +		nexthop_num++; +	} -  /* If there is no useful nexthop then return. */ -  if (nexthop_num == 0) -    { -      if (IS_ZEBRA_DEBUG_KERNEL) -	zlog_debug ("kernel_rtm_ipv6(): No useful nexthop."); -      return 0; -    } +	/* If there is no useful nexthop then return. */ +	if (nexthop_num == 0) { +		if (IS_ZEBRA_DEBUG_KERNEL) +			zlog_debug("kernel_rtm_ipv6(): No useful nexthop."); +		return 0; +	} -  return 0; /*XXX*/ +	return 0; /*XXX*/  } -static int -kernel_rtm (int cmd, struct prefix *p, struct rib *rib) +static int kernel_rtm(int cmd, struct prefix *p, struct rib *rib)  { -  switch (PREFIX_FAMILY(p)) -    { -    case AF_INET: -      return kernel_rtm_ipv4 (cmd, p, rib); -    case AF_INET6: -      return kernel_rtm_ipv6 (cmd, p, rib); -    } -  return 0; +	switch (PREFIX_FAMILY(p)) { +	case AF_INET: +		return kernel_rtm_ipv4(cmd, p, rib); +	case AF_INET6: +		return kernel_rtm_ipv6(cmd, p, rib); +	} +	return 0;  } -int -kernel_route_rib (struct prefix *p, struct prefix *src_p, -                  struct rib *old, struct rib *new) +int kernel_route_rib(struct prefix *p, struct prefix *src_p, struct rib *old, +		     struct rib *new)  { -  int route = 0; +	int route = 0; -  if (src_p && src_p->prefixlen) -    { -      zlog_err ("route add: IPv6 sourcedest routes unsupported!"); -      return 1; -    } +	if (src_p && src_p->prefixlen) { +		zlog_err("route add: IPv6 sourcedest routes unsupported!"); +		return 1; +	} -  if (zserv_privs.change(ZPRIVS_RAISE)) -    zlog_err("Can't raise privileges"); +	if (zserv_privs.change(ZPRIVS_RAISE)) +		zlog_err("Can't raise privileges"); -  if (old) -    route |= kernel_rtm (RTM_DELETE, p, old); +	if (old) +		route |= kernel_rtm(RTM_DELETE, p, old); -  if (new) -    route |= kernel_rtm (RTM_ADD, p, new); +	if (new) +		route |= kernel_rtm(RTM_ADD, p, new); -  if (zserv_privs.change(ZPRIVS_LOWER)) -    zlog_err("Can't lower privileges"); +	if (zserv_privs.change(ZPRIVS_LOWER)) +		zlog_err("Can't lower privileges"); -  return route; +	return route;  } -int -kernel_neigh_update (int add, int ifindex, uint32_t addr, char *lla, int llalen) +int kernel_neigh_update(int add, int ifindex, uint32_t addr, char *lla, +			int llalen)  { -  /* TODO */ -  return 0; +	/* TODO */ +	return 0;  } -extern int -kernel_get_ipmr_sg_stats (void *mroute) +extern int kernel_get_ipmr_sg_stats(void *mroute)  { -  return 0; +	return 0;  } diff --git a/zebra/rtadv.c b/zebra/rtadv.c index 12e4873adf..9fb30ef1c4 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -18,7 +18,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #include <zebra.h> @@ -46,7 +46,7 @@  extern struct zebra_privs_t zserv_privs; -#if defined (HAVE_RTADV) +#if defined(HAVE_RTADV)  #ifdef OPEN_BSD  #include <netinet/icmp6.h> @@ -63,743 +63,722 @@ extern struct zebra_privs_t zserv_privs;  #define ALLNODE   "ff02::1"  #define ALLROUTER "ff02::2" -enum rtadv_event {RTADV_START, RTADV_STOP, RTADV_TIMER,  -		  RTADV_TIMER_MSEC, RTADV_READ}; +enum rtadv_event { +	RTADV_START, +	RTADV_STOP, +	RTADV_TIMER, +	RTADV_TIMER_MSEC, +	RTADV_READ +}; -static void rtadv_event (struct zebra_ns *, enum rtadv_event, int); +static void rtadv_event(struct zebra_ns *, enum rtadv_event, int); -static int if_join_all_router (int, struct interface *); -static int if_leave_all_router (int, struct interface *); +static int if_join_all_router(int, struct interface *); +static int if_leave_all_router(int, struct interface *); -static int -rtadv_increment_received(struct zebra_ns *zns, ifindex_t *ifindex) +static int rtadv_increment_received(struct zebra_ns *zns, ifindex_t *ifindex)  { -  int ret = -1; -  struct interface *iface; -  struct zebra_if *zif; - -  iface = if_lookup_by_index_per_ns (zns, *ifindex); -  if (iface && iface->info) -    { -      zif = iface->info; -      zif->ra_rcvd++; -      ret = 0; -    } -  return ret; +	int ret = -1; +	struct interface *iface; +	struct zebra_if *zif; + +	iface = if_lookup_by_index_per_ns(zns, *ifindex); +	if (iface && iface->info) { +		zif = iface->info; +		zif->ra_rcvd++; +		ret = 0; +	} +	return ret;  } -static int -rtadv_recv_packet (struct zebra_ns *zns, int sock, u_char *buf, int buflen, -		   struct sockaddr_in6 *from, ifindex_t *ifindex, -		   int *hoplimit) +static int rtadv_recv_packet(struct zebra_ns *zns, int sock, u_char *buf, +			     int buflen, struct sockaddr_in6 *from, +			     ifindex_t *ifindex, int *hoplimit)  { -  int ret; -  struct msghdr msg; -  struct iovec iov; -  struct cmsghdr  *cmsgptr; -  struct in6_addr dst; - -  char adata[1024]; - -  /* Fill in message and iovec. */ -  msg.msg_name = (void *) from; -  msg.msg_namelen = sizeof (struct sockaddr_in6); -  msg.msg_iov = &iov; -  msg.msg_iovlen = 1; -  msg.msg_control = (void *) adata; -  msg.msg_controllen = sizeof adata; -  iov.iov_base = buf; -  iov.iov_len = buflen; - -  /* If recvmsg fail return minus value. */ -  ret = recvmsg (sock, &msg, 0); -  if (ret < 0) -    return ret; - -  for (cmsgptr = ZCMSG_FIRSTHDR(&msg); cmsgptr != NULL; -       cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))  -    { -      /* I want interface index which this packet comes from. */ -      if (cmsgptr->cmsg_level == IPPROTO_IPV6 && -	  cmsgptr->cmsg_type == IPV6_PKTINFO)  -	{ -	  struct in6_pktinfo *ptr; -	   -	  ptr = (struct in6_pktinfo *) CMSG_DATA (cmsgptr); -	  *ifindex = ptr->ipi6_ifindex; -	  memcpy(&dst, &ptr->ipi6_addr, sizeof(ptr->ipi6_addr)); -        } - -      /* Incoming packet's hop limit. */ -      if (cmsgptr->cmsg_level == IPPROTO_IPV6 && -	  cmsgptr->cmsg_type == IPV6_HOPLIMIT) -	{ -	  int *hoptr = (int *) CMSG_DATA (cmsgptr); -	  *hoplimit = *hoptr; +	int ret; +	struct msghdr msg; +	struct iovec iov; +	struct cmsghdr *cmsgptr; +	struct in6_addr dst; + +	char adata[1024]; + +	/* Fill in message and iovec. */ +	msg.msg_name = (void *)from; +	msg.msg_namelen = sizeof(struct sockaddr_in6); +	msg.msg_iov = &iov; +	msg.msg_iovlen = 1; +	msg.msg_control = (void *)adata; +	msg.msg_controllen = sizeof adata; +	iov.iov_base = buf; +	iov.iov_len = buflen; + +	/* If recvmsg fail return minus value. */ +	ret = recvmsg(sock, &msg, 0); +	if (ret < 0) +		return ret; + +	for (cmsgptr = ZCMSG_FIRSTHDR(&msg); cmsgptr != NULL; +	     cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) { +		/* I want interface index which this packet comes from. */ +		if (cmsgptr->cmsg_level == IPPROTO_IPV6 +		    && cmsgptr->cmsg_type == IPV6_PKTINFO) { +			struct in6_pktinfo *ptr; + +			ptr = (struct in6_pktinfo *)CMSG_DATA(cmsgptr); +			*ifindex = ptr->ipi6_ifindex; +			memcpy(&dst, &ptr->ipi6_addr, sizeof(ptr->ipi6_addr)); +		} + +		/* Incoming packet's hop limit. */ +		if (cmsgptr->cmsg_level == IPPROTO_IPV6 +		    && cmsgptr->cmsg_type == IPV6_HOPLIMIT) { +			int *hoptr = (int *)CMSG_DATA(cmsgptr); +			*hoplimit = *hoptr; +		}  	} -    } -  rtadv_increment_received(zns, ifindex); -  return ret; +	rtadv_increment_received(zns, ifindex); +	return ret;  }  #define RTADV_MSG_SIZE 4096  /* Send router advertisement packet. */ -static void -rtadv_send_packet (int sock, struct interface *ifp) +static void rtadv_send_packet(int sock, struct interface *ifp)  { -  struct msghdr msg; -  struct iovec iov; -  struct cmsghdr  *cmsgptr; -  struct in6_pktinfo *pkt; -  struct sockaddr_in6 addr; -  static void *adata = NULL; -  unsigned char buf[RTADV_MSG_SIZE]; -  struct nd_router_advert *rtadv; -  int ret; -  int len = 0; -  struct zebra_if *zif; -  struct rtadv_prefix *rprefix; -  u_char all_nodes_addr[] = {0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; -  struct listnode *node; -  u_int16_t pkt_RouterLifetime; - -  /* -   * Allocate control message bufffer.  This is dynamic because -   * CMSG_SPACE is not guaranteed not to call a function.  Note that -   * the size will be different on different architectures due to -   * differing alignment rules. -   */ -  if (adata == NULL) -    { -      /* XXX Free on shutdown. */ -      adata = malloc(CMSG_SPACE(sizeof(struct in6_pktinfo))); -	    -      if (adata == NULL) -	zlog_err("rtadv_send_packet: can't malloc control data"); -    } - -  /* Logging of packet. */ -  if (IS_ZEBRA_DEBUG_PACKET) -    zlog_debug ("%s(%u): Tx RA, socket %u", -                ifp->name, ifp->ifindex, sock); - -  /* Fill in sockaddr_in6. */ -  memset (&addr, 0, sizeof (struct sockaddr_in6)); -  addr.sin6_family = AF_INET6; +	struct msghdr msg; +	struct iovec iov; +	struct cmsghdr *cmsgptr; +	struct in6_pktinfo *pkt; +	struct sockaddr_in6 addr; +	static void *adata = NULL; +	unsigned char buf[RTADV_MSG_SIZE]; +	struct nd_router_advert *rtadv; +	int ret; +	int len = 0; +	struct zebra_if *zif; +	struct rtadv_prefix *rprefix; +	u_char all_nodes_addr[] = {0xff, 0x02, 0, 0, 0, 0, 0, 0, +				   0,    0,    0, 0, 0, 0, 0, 1}; +	struct listnode *node; +	u_int16_t pkt_RouterLifetime; + +	/* +	 * Allocate control message bufffer.  This is dynamic because +	 * CMSG_SPACE is not guaranteed not to call a function.  Note that +	 * the size will be different on different architectures due to +	 * differing alignment rules. +	 */ +	if (adata == NULL) { +		/* XXX Free on shutdown. */ +		adata = malloc(CMSG_SPACE(sizeof(struct in6_pktinfo))); + +		if (adata == NULL) +			zlog_err( +				"rtadv_send_packet: can't malloc control data"); +	} + +	/* Logging of packet. */ +	if (IS_ZEBRA_DEBUG_PACKET) +		zlog_debug("%s(%u): Tx RA, socket %u", ifp->name, ifp->ifindex, +			   sock); + +	/* Fill in sockaddr_in6. */ +	memset(&addr, 0, sizeof(struct sockaddr_in6)); +	addr.sin6_family = AF_INET6;  #ifdef SIN6_LEN -  addr.sin6_len = sizeof (struct sockaddr_in6); +	addr.sin6_len = sizeof(struct sockaddr_in6);  #endif /* SIN6_LEN */ -  addr.sin6_port = htons (IPPROTO_ICMPV6); -  IPV6_ADDR_COPY (&addr.sin6_addr, all_nodes_addr); - -  /* Fetch interface information. */ -  zif = ifp->info; - -  /* Make router advertisement message. */ -  rtadv = (struct nd_router_advert *) buf; - -  rtadv->nd_ra_type = ND_ROUTER_ADVERT; -  rtadv->nd_ra_code = 0; -  rtadv->nd_ra_cksum = 0; - -  rtadv->nd_ra_curhoplimit = 64; - -  /* RFC4191: Default Router Preference is 0 if Router Lifetime is 0. */ -  rtadv->nd_ra_flags_reserved = -    zif->rtadv.AdvDefaultLifetime == 0 ? 0 : zif->rtadv.DefaultPreference; -  rtadv->nd_ra_flags_reserved <<= 3; - -  if (zif->rtadv.AdvManagedFlag) -    rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_MANAGED; -  if (zif->rtadv.AdvOtherConfigFlag) -    rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_OTHER; -  if (zif->rtadv.AdvHomeAgentFlag) -    rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_HOME_AGENT; -  /* Note that according to Neighbor Discovery (RFC 4861 [18]), -   * AdvDefaultLifetime is by default based on the value of -   * MaxRtrAdvInterval.  AdvDefaultLifetime is used in the Router Lifetime -   * field of Router Advertisements.  Given that this field is expressed -   * in seconds, a small MaxRtrAdvInterval value can result in a zero -   * value for this field.  To prevent this, routers SHOULD keep -   * AdvDefaultLifetime in at least one second, even if the use of -   * MaxRtrAdvInterval would result in a smaller value. -- RFC6275, 7.5 */ -  pkt_RouterLifetime = zif->rtadv.AdvDefaultLifetime != -1 ? -    zif->rtadv.AdvDefaultLifetime : -    MAX (1, 0.003 * zif->rtadv.MaxRtrAdvInterval); -  rtadv->nd_ra_router_lifetime = htons (pkt_RouterLifetime); -  rtadv->nd_ra_reachable = htonl (zif->rtadv.AdvReachableTime); -  rtadv->nd_ra_retransmit = htonl (0); - -  len = sizeof (struct nd_router_advert); - -  /* If both the Home Agent Preference and Home Agent Lifetime are set to -   * their default values specified above, this option SHOULD NOT be -   * included in the Router Advertisement messages sent by this home -   * agent. -- RFC6275, 7.4 */ -  if -  ( -    zif->rtadv.AdvHomeAgentFlag && -    (zif->rtadv.HomeAgentPreference || zif->rtadv.HomeAgentLifetime != -1) -  ) -    { -      struct nd_opt_homeagent_info *ndopt_hai =  -	(struct nd_opt_homeagent_info *)(buf + len); -      ndopt_hai->nd_opt_hai_type = ND_OPT_HA_INFORMATION; -      ndopt_hai->nd_opt_hai_len = 1; -      ndopt_hai->nd_opt_hai_reserved = 0; -      ndopt_hai->nd_opt_hai_preference = htons(zif->rtadv.HomeAgentPreference); -      /* 16-bit unsigned integer.  The lifetime associated with the home -       * agent in units of seconds.  The default value is the same as the -       * Router Lifetime, as specified in the main body of the Router -       * Advertisement.  The maximum value corresponds to 18.2 hours.  A -       * value of 0 MUST NOT be used. -- RFC6275, 7.5 */ -      ndopt_hai->nd_opt_hai_lifetime = htons -      ( -        zif->rtadv.HomeAgentLifetime != -1 ? -        zif->rtadv.HomeAgentLifetime : -        MAX (1, pkt_RouterLifetime) /* 0 is OK for RL, but not for HAL*/ -      ); -      len += sizeof(struct nd_opt_homeagent_info); -    } - -  if (zif->rtadv.AdvIntervalOption) -    { -      struct nd_opt_adv_interval *ndopt_adv =  -	(struct nd_opt_adv_interval *)(buf + len); -      ndopt_adv->nd_opt_ai_type = ND_OPT_ADV_INTERVAL; -      ndopt_adv->nd_opt_ai_len = 1; -      ndopt_adv->nd_opt_ai_reserved = 0; -      ndopt_adv->nd_opt_ai_interval = htonl(zif->rtadv.MaxRtrAdvInterval); -      len += sizeof(struct nd_opt_adv_interval); -    } - -  /* Fill in prefix. */ -  for (ALL_LIST_ELEMENTS_RO (zif->rtadv.AdvPrefixList, node, rprefix)) -    { -      struct nd_opt_prefix_info *pinfo; - -      pinfo = (struct nd_opt_prefix_info *) (buf + len); - -      pinfo->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION; -      pinfo->nd_opt_pi_len = 4; -      pinfo->nd_opt_pi_prefix_len = rprefix->prefix.prefixlen; - -      pinfo->nd_opt_pi_flags_reserved = 0; -      if (rprefix->AdvOnLinkFlag) -	pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_ONLINK; -      if (rprefix->AdvAutonomousFlag) -	pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_AUTO; -      if (rprefix->AdvRouterAddressFlag) -	pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_RADDR; - -      pinfo->nd_opt_pi_valid_time = htonl (rprefix->AdvValidLifetime); -      pinfo->nd_opt_pi_preferred_time = htonl (rprefix->AdvPreferredLifetime); -      pinfo->nd_opt_pi_reserved2 = 0; - -      IPV6_ADDR_COPY (&pinfo->nd_opt_pi_prefix, &rprefix->prefix.prefix); +	addr.sin6_port = htons(IPPROTO_ICMPV6); +	IPV6_ADDR_COPY(&addr.sin6_addr, all_nodes_addr); + +	/* Fetch interface information. */ +	zif = ifp->info; + +	/* Make router advertisement message. */ +	rtadv = (struct nd_router_advert *)buf; + +	rtadv->nd_ra_type = ND_ROUTER_ADVERT; +	rtadv->nd_ra_code = 0; +	rtadv->nd_ra_cksum = 0; + +	rtadv->nd_ra_curhoplimit = 64; + +	/* RFC4191: Default Router Preference is 0 if Router Lifetime is 0. */ +	rtadv->nd_ra_flags_reserved = zif->rtadv.AdvDefaultLifetime == 0 +					      ? 0 +					      : zif->rtadv.DefaultPreference; +	rtadv->nd_ra_flags_reserved <<= 3; + +	if (zif->rtadv.AdvManagedFlag) +		rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_MANAGED; +	if (zif->rtadv.AdvOtherConfigFlag) +		rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_OTHER; +	if (zif->rtadv.AdvHomeAgentFlag) +		rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_HOME_AGENT; +	/* Note that according to Neighbor Discovery (RFC 4861 [18]), +	 * AdvDefaultLifetime is by default based on the value of +	 * MaxRtrAdvInterval.  AdvDefaultLifetime is used in the Router Lifetime +	 * field of Router Advertisements.  Given that this field is expressed +	 * in seconds, a small MaxRtrAdvInterval value can result in a zero +	 * value for this field.  To prevent this, routers SHOULD keep +	 * AdvDefaultLifetime in at least one second, even if the use of +	 * MaxRtrAdvInterval would result in a smaller value. -- RFC6275, 7.5 */ +	pkt_RouterLifetime = +		zif->rtadv.AdvDefaultLifetime != -1 +			? zif->rtadv.AdvDefaultLifetime +			: MAX(1, 0.003 * zif->rtadv.MaxRtrAdvInterval); +	rtadv->nd_ra_router_lifetime = htons(pkt_RouterLifetime); +	rtadv->nd_ra_reachable = htonl(zif->rtadv.AdvReachableTime); +	rtadv->nd_ra_retransmit = htonl(0); + +	len = sizeof(struct nd_router_advert); + +	/* If both the Home Agent Preference and Home Agent Lifetime are set to +	 * their default values specified above, this option SHOULD NOT be +	 * included in the Router Advertisement messages sent by this home +	 * agent. -- RFC6275, 7.4 */ +	if (zif->rtadv.AdvHomeAgentFlag +	    && (zif->rtadv.HomeAgentPreference +		|| zif->rtadv.HomeAgentLifetime != -1)) { +		struct nd_opt_homeagent_info *ndopt_hai = +			(struct nd_opt_homeagent_info *)(buf + len); +		ndopt_hai->nd_opt_hai_type = ND_OPT_HA_INFORMATION; +		ndopt_hai->nd_opt_hai_len = 1; +		ndopt_hai->nd_opt_hai_reserved = 0; +		ndopt_hai->nd_opt_hai_preference = +			htons(zif->rtadv.HomeAgentPreference); +		/* 16-bit unsigned integer.  The lifetime associated with the +		 * home +		 * agent in units of seconds.  The default value is the same as +		 * the +		 * Router Lifetime, as specified in the main body of the Router +		 * Advertisement.  The maximum value corresponds to 18.2 hours. +		 * A +		 * value of 0 MUST NOT be used. -- RFC6275, 7.5 */ +		ndopt_hai->nd_opt_hai_lifetime = +			htons(zif->rtadv.HomeAgentLifetime != -1 +				      ? zif->rtadv.HomeAgentLifetime +				      : MAX(1, pkt_RouterLifetime) /* 0 is OK +								      for RL, +								      but not +								      for HAL*/ +			      ); +		len += sizeof(struct nd_opt_homeagent_info); +	} -#ifdef DEBUG -      { -	u_char buf[INET6_ADDRSTRLEN]; +	if (zif->rtadv.AdvIntervalOption) { +		struct nd_opt_adv_interval *ndopt_adv = +			(struct nd_opt_adv_interval *)(buf + len); +		ndopt_adv->nd_opt_ai_type = ND_OPT_ADV_INTERVAL; +		ndopt_adv->nd_opt_ai_len = 1; +		ndopt_adv->nd_opt_ai_reserved = 0; +		ndopt_adv->nd_opt_ai_interval = +			htonl(zif->rtadv.MaxRtrAdvInterval); +		len += sizeof(struct nd_opt_adv_interval); +	} + +	/* Fill in prefix. */ +	for (ALL_LIST_ELEMENTS_RO(zif->rtadv.AdvPrefixList, node, rprefix)) { +		struct nd_opt_prefix_info *pinfo; -	zlog_debug ("DEBUG %s", inet_ntop (AF_INET6, &pinfo->nd_opt_pi_prefix,  -	           buf, INET6_ADDRSTRLEN)); +		pinfo = (struct nd_opt_prefix_info *)(buf + len); -      } +		pinfo->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION; +		pinfo->nd_opt_pi_len = 4; +		pinfo->nd_opt_pi_prefix_len = rprefix->prefix.prefixlen; + +		pinfo->nd_opt_pi_flags_reserved = 0; +		if (rprefix->AdvOnLinkFlag) +			pinfo->nd_opt_pi_flags_reserved |= +				ND_OPT_PI_FLAG_ONLINK; +		if (rprefix->AdvAutonomousFlag) +			pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_AUTO; +		if (rprefix->AdvRouterAddressFlag) +			pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_RADDR; + +		pinfo->nd_opt_pi_valid_time = htonl(rprefix->AdvValidLifetime); +		pinfo->nd_opt_pi_preferred_time = +			htonl(rprefix->AdvPreferredLifetime); +		pinfo->nd_opt_pi_reserved2 = 0; + +		IPV6_ADDR_COPY(&pinfo->nd_opt_pi_prefix, +			       &rprefix->prefix.prefix); + +#ifdef DEBUG +		{ +			u_char buf[INET6_ADDRSTRLEN]; + +			zlog_debug("DEBUG %s", +				   inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix, +					     buf, INET6_ADDRSTRLEN)); +		}  #endif /* DEBUG */ -      len += sizeof (struct nd_opt_prefix_info); -    } - -  /* Hardware address. */ -  if (ifp->hw_addr_len != 0) -    { -      buf[len++] = ND_OPT_SOURCE_LINKADDR; - -      /* Option length should be rounded up to next octet if -         the link address does not end on an octet boundary. */ -      buf[len++] = (ifp->hw_addr_len + 9) >> 3; - -      memcpy (buf + len, ifp->hw_addr, ifp->hw_addr_len); -      len += ifp->hw_addr_len; - -      /* Pad option to end on an octet boundary. */ -      memset (buf + len, 0, -(ifp->hw_addr_len + 2) & 0x7); -      len += -(ifp->hw_addr_len + 2) & 0x7; -    } - -  /* MTU */ -  if (zif->rtadv.AdvLinkMTU) -    { -      struct nd_opt_mtu * opt = (struct nd_opt_mtu *) (buf + len); -      opt->nd_opt_mtu_type = ND_OPT_MTU; -      opt->nd_opt_mtu_len = 1; -      opt->nd_opt_mtu_reserved = 0; -      opt->nd_opt_mtu_mtu = htonl (zif->rtadv.AdvLinkMTU); -      len += sizeof (struct nd_opt_mtu); -    } - -  msg.msg_name = (void *) &addr; -  msg.msg_namelen = sizeof (struct sockaddr_in6); -  msg.msg_iov = &iov; -  msg.msg_iovlen = 1; -  msg.msg_control = (void *) adata; -  msg.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo)); -  msg.msg_flags = 0; -  iov.iov_base = buf; -  iov.iov_len = len; - -  cmsgptr = ZCMSG_FIRSTHDR(&msg); -  cmsgptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); -  cmsgptr->cmsg_level = IPPROTO_IPV6; -  cmsgptr->cmsg_type = IPV6_PKTINFO; - -  pkt = (struct in6_pktinfo *) CMSG_DATA (cmsgptr); -  memset (&pkt->ipi6_addr, 0, sizeof (struct in6_addr)); -  pkt->ipi6_ifindex = ifp->ifindex; - -  ret = sendmsg (sock, &msg, 0); -  if (ret < 0) -    { -      zlog_err ("%s(%u): Tx RA failed, socket %u error %d (%s)", -                ifp->name, ifp->ifindex, sock, errno, safe_strerror(errno)); -    } -  else -    zif->ra_sent++; +		len += sizeof(struct nd_opt_prefix_info); +	} + +	/* Hardware address. */ +	if (ifp->hw_addr_len != 0) { +		buf[len++] = ND_OPT_SOURCE_LINKADDR; + +		/* Option length should be rounded up to next octet if +		   the link address does not end on an octet boundary. */ +		buf[len++] = (ifp->hw_addr_len + 9) >> 3; + +		memcpy(buf + len, ifp->hw_addr, ifp->hw_addr_len); +		len += ifp->hw_addr_len; + +		/* Pad option to end on an octet boundary. */ +		memset(buf + len, 0, -(ifp->hw_addr_len + 2) & 0x7); +		len += -(ifp->hw_addr_len + 2) & 0x7; +	} + +	/* MTU */ +	if (zif->rtadv.AdvLinkMTU) { +		struct nd_opt_mtu *opt = (struct nd_opt_mtu *)(buf + len); +		opt->nd_opt_mtu_type = ND_OPT_MTU; +		opt->nd_opt_mtu_len = 1; +		opt->nd_opt_mtu_reserved = 0; +		opt->nd_opt_mtu_mtu = htonl(zif->rtadv.AdvLinkMTU); +		len += sizeof(struct nd_opt_mtu); +	} + +	msg.msg_name = (void *)&addr; +	msg.msg_namelen = sizeof(struct sockaddr_in6); +	msg.msg_iov = &iov; +	msg.msg_iovlen = 1; +	msg.msg_control = (void *)adata; +	msg.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo)); +	msg.msg_flags = 0; +	iov.iov_base = buf; +	iov.iov_len = len; + +	cmsgptr = ZCMSG_FIRSTHDR(&msg); +	cmsgptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); +	cmsgptr->cmsg_level = IPPROTO_IPV6; +	cmsgptr->cmsg_type = IPV6_PKTINFO; + +	pkt = (struct in6_pktinfo *)CMSG_DATA(cmsgptr); +	memset(&pkt->ipi6_addr, 0, sizeof(struct in6_addr)); +	pkt->ipi6_ifindex = ifp->ifindex; + +	ret = sendmsg(sock, &msg, 0); +	if (ret < 0) { +		zlog_err("%s(%u): Tx RA failed, socket %u error %d (%s)", +			 ifp->name, ifp->ifindex, sock, errno, +			 safe_strerror(errno)); +	} else +		zif->ra_sent++;  } -static int -rtadv_timer (struct thread *thread) +static int rtadv_timer(struct thread *thread)  { -  struct zebra_ns *zns = THREAD_ARG (thread); -  struct vrf *vrf; -  struct listnode *node, *nnode; -  struct interface *ifp; -  struct zebra_if *zif; -  int period; - -  zns->rtadv.ra_timer = NULL; -  if (zns->rtadv.adv_msec_if_count == 0) -    { -      period = 1000; /* 1 s */ -      rtadv_event (zns, RTADV_TIMER, 1 /* 1 s */); -    }  -  else -    { -      period = 10; /* 10 ms */ -      rtadv_event (zns, RTADV_TIMER_MSEC, 10 /* 10 ms */); -    } - -  RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) -    for (ALL_LIST_ELEMENTS (vrf->iflist, node, nnode, ifp)) -      { -        if (if_is_loopback (ifp) || -            CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK) || -            ! if_is_operative (ifp)) -          continue; - -        zif = ifp->info; - -        if (zif->rtadv.AdvSendAdvertisements) -          { -            if (zif->rtadv.inFastRexmit) -              { -                /* We assume we fast rexmit every sec so no additional vars */ -                if (--zif->rtadv.NumFastReXmitsRemain <= 0) -                  zif->rtadv.inFastRexmit = 0; - -                if (IS_ZEBRA_DEBUG_SEND) -                  zlog_debug("Fast RA Rexmit on interface %s", ifp->name); - -                rtadv_send_packet (zns->rtadv.sock, ifp); -              } -            else -              { -                zif->rtadv.AdvIntervalTimer -= period; -                if (zif->rtadv.AdvIntervalTimer <= 0) -                  { -                    /* FIXME: using MaxRtrAdvInterval each time isn't what section -                       6.2.4 of RFC4861 tells to do. */ -                    zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval; -                    rtadv_send_packet (zns->rtadv.sock, ifp); -                  } -              } -          } -      } - -  return 0; +	struct zebra_ns *zns = THREAD_ARG(thread); +	struct vrf *vrf; +	struct listnode *node, *nnode; +	struct interface *ifp; +	struct zebra_if *zif; +	int period; + +	zns->rtadv.ra_timer = NULL; +	if (zns->rtadv.adv_msec_if_count == 0) { +		period = 1000; /* 1 s */ +		rtadv_event(zns, RTADV_TIMER, 1 /* 1 s */); +	} else { +		period = 10; /* 10 ms */ +		rtadv_event(zns, RTADV_TIMER_MSEC, 10 /* 10 ms */); +	} + +	RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id) +	for (ALL_LIST_ELEMENTS(vrf->iflist, node, nnode, ifp)) { +		if (if_is_loopback(ifp) +		    || CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK) +		    || !if_is_operative(ifp)) +			continue; + +		zif = ifp->info; + +		if (zif->rtadv.AdvSendAdvertisements) { +			if (zif->rtadv.inFastRexmit) { +				/* We assume we fast rexmit every sec so no +				 * additional vars */ +				if (--zif->rtadv.NumFastReXmitsRemain <= 0) +					zif->rtadv.inFastRexmit = 0; + +				if (IS_ZEBRA_DEBUG_SEND) +					zlog_debug( +						"Fast RA Rexmit on interface %s", +						ifp->name); + +				rtadv_send_packet(zns->rtadv.sock, ifp); +			} else { +				zif->rtadv.AdvIntervalTimer -= period; +				if (zif->rtadv.AdvIntervalTimer <= 0) { +					/* FIXME: using MaxRtrAdvInterval each +					   time isn't what section +					   6.2.4 of RFC4861 tells to do. */ +					zif->rtadv.AdvIntervalTimer = +						zif->rtadv.MaxRtrAdvInterval; +					rtadv_send_packet(zns->rtadv.sock, ifp); +				} +			} +		} +	} + +	return 0;  } -static void -rtadv_process_solicit (struct interface *ifp) +static void rtadv_process_solicit(struct interface *ifp)  { -  struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id); -  struct zebra_ns *zns = zvrf->zns; +	struct zebra_vrf *zvrf = vrf_info_lookup(ifp->vrf_id); +	struct zebra_ns *zns = zvrf->zns; -  assert (zns); -  rtadv_send_packet (zns->rtadv.sock, ifp); +	assert(zns); +	rtadv_send_packet(zns->rtadv.sock, ifp);  } -static void -rtadv_process_advert (u_char *msg, unsigned int len, struct interface *ifp, -                      struct sockaddr_in6 *addr) +static void rtadv_process_advert(u_char *msg, unsigned int len, +				 struct interface *ifp, +				 struct sockaddr_in6 *addr)  { -  struct nd_router_advert *radvert; -  char addr_str[INET6_ADDRSTRLEN]; -  struct zebra_if *zif; -  struct prefix p; - -  zif = ifp->info; - -  inet_ntop (AF_INET6, &addr->sin6_addr, addr_str, INET6_ADDRSTRLEN); - -  if (len < sizeof(struct nd_router_advert)) { -      zlog_warn("%s(%u): Rx RA with invalid length %d from %s", -                ifp->name, ifp->ifindex, len, addr_str); -      return; -  } -  if (!IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr)) { -      zlog_warn("%s(%u): Rx RA with non-linklocal source address from %s", -                ifp->name, ifp->ifindex, addr_str); -      return; -  } - -  radvert = (struct nd_router_advert *) msg; - -  if ((radvert->nd_ra_curhoplimit && zif->rtadv.AdvCurHopLimit) && -      (radvert->nd_ra_curhoplimit != zif->rtadv.AdvCurHopLimit)) -    { -      zlog_warn("%s(%u): Rx RA - our AdvCurHopLimit doesn't agree with %s", -                ifp->name, ifp->ifindex, addr_str); -    } - -  if ((radvert->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) && -      !zif->rtadv.AdvManagedFlag) -    { -      zlog_warn("%s(%u): Rx RA - our AdvManagedFlag doesn't agree with %s", -                ifp->name, ifp->ifindex, addr_str); -    } - -  if ((radvert->nd_ra_flags_reserved & ND_RA_FLAG_OTHER) && -      !zif->rtadv.AdvOtherConfigFlag) -    { -      zlog_warn("%s(%u): Rx RA - our AdvOtherConfigFlag doesn't agree with %s", -                ifp->name, ifp->ifindex, addr_str); -    } - -  if ((radvert->nd_ra_reachable && zif->rtadv.AdvReachableTime) && -      (ntohl(radvert->nd_ra_reachable) != zif->rtadv.AdvReachableTime)) -    { -      zlog_warn("%s(%u): Rx RA - our AdvReachableTime doesn't agree with %s", -                ifp->name, ifp->ifindex, addr_str); -    } - -  if ((radvert->nd_ra_retransmit && zif->rtadv.AdvRetransTimer) && -      (ntohl(radvert->nd_ra_retransmit) != (unsigned int)zif->rtadv.AdvRetransTimer)) -    { -      zlog_warn("%s(%u): Rx RA - our AdvRetransTimer doesn't agree with %s", -                ifp->name, ifp->ifindex, addr_str); -    } - -  /* Create entry for neighbor if not known. */ -  p.family = AF_INET6; -  IPV6_ADDR_COPY (&p.u.prefix, &addr->sin6_addr); -  p.prefixlen = IPV6_MAX_PREFIXLEN; - -  if (!nbr_connected_check(ifp, &p)) -    nbr_connected_add_ipv6 (ifp, &addr->sin6_addr); -} +	struct nd_router_advert *radvert; +	char addr_str[INET6_ADDRSTRLEN]; +	struct zebra_if *zif; +	struct prefix p; +	zif = ifp->info; -static void -rtadv_process_packet (u_char *buf, unsigned int len, ifindex_t ifindex, int hoplimit, -                      struct sockaddr_in6 *from, struct zebra_ns *zns) -{ -  struct icmp6_hdr *icmph; -  struct interface *ifp; -  struct zebra_if *zif; -  char addr_str[INET6_ADDRSTRLEN]; - -  inet_ntop (AF_INET6, &from->sin6_addr, addr_str, INET6_ADDRSTRLEN); - -  /* Interface search. */ -  ifp = if_lookup_by_index_per_ns (zns, ifindex); -  if (ifp == NULL) -    { -      zlog_warn ("RA/RS received on unknown IF %u from %s", -                 ifindex, addr_str); -      return; -    } - -  if (IS_ZEBRA_DEBUG_PACKET) -    zlog_debug ("%s(%u): Rx RA/RS len %d from %s", -                ifp->name, ifp->ifindex, len, addr_str); - -  if (if_is_loopback (ifp) || -      CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK)) -    return; - -  /* Check interface configuration. */ -  zif = ifp->info; -  if (! zif->rtadv.AdvSendAdvertisements) -    return; - -  /* ICMP message length check. */ -  if (len < sizeof (struct icmp6_hdr)) -    { -      zlog_warn ("%s(%u): Rx RA with Invalid ICMPV6 packet length %d", -                 ifp->name, ifp->ifindex, len); -      return; -    } - -  icmph = (struct icmp6_hdr *) buf; - -  /* ICMP message type check. */ -  if (icmph->icmp6_type != ND_ROUTER_SOLICIT && -      icmph->icmp6_type != ND_ROUTER_ADVERT) -    { -      zlog_warn ("%s(%u): Rx RA - Unwanted ICMPV6 message type %d", -                 ifp->name, ifp->ifindex, icmph->icmp6_type); -      return; -    } - -  /* Hoplimit check. */ -  if (hoplimit >= 0 && hoplimit != 255) -    { -      zlog_warn ("%s(%u): Rx RA - Invalid hoplimit %d", -		 ifp->name, ifp->ifindex, hoplimit); -      return; -    } - -  /* Check ICMP message type. */ -  if (icmph->icmp6_type == ND_ROUTER_SOLICIT) -    rtadv_process_solicit (ifp); -  else if (icmph->icmp6_type == ND_ROUTER_ADVERT) -    rtadv_process_advert (buf, len, ifp, from); - -  return; +	inet_ntop(AF_INET6, &addr->sin6_addr, addr_str, INET6_ADDRSTRLEN); + +	if (len < sizeof(struct nd_router_advert)) { +		zlog_warn("%s(%u): Rx RA with invalid length %d from %s", +			  ifp->name, ifp->ifindex, len, addr_str); +		return; +	} +	if (!IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr)) { +		zlog_warn( +			"%s(%u): Rx RA with non-linklocal source address from %s", +			ifp->name, ifp->ifindex, addr_str); +		return; +	} + +	radvert = (struct nd_router_advert *)msg; + +	if ((radvert->nd_ra_curhoplimit && zif->rtadv.AdvCurHopLimit) +	    && (radvert->nd_ra_curhoplimit != zif->rtadv.AdvCurHopLimit)) { +		zlog_warn( +			"%s(%u): Rx RA - our AdvCurHopLimit doesn't agree with %s", +			ifp->name, ifp->ifindex, addr_str); +	} + +	if ((radvert->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) +	    && !zif->rtadv.AdvManagedFlag) { +		zlog_warn( +			"%s(%u): Rx RA - our AdvManagedFlag doesn't agree with %s", +			ifp->name, ifp->ifindex, addr_str); +	} + +	if ((radvert->nd_ra_flags_reserved & ND_RA_FLAG_OTHER) +	    && !zif->rtadv.AdvOtherConfigFlag) { +		zlog_warn( +			"%s(%u): Rx RA - our AdvOtherConfigFlag doesn't agree with %s", +			ifp->name, ifp->ifindex, addr_str); +	} + +	if ((radvert->nd_ra_reachable && zif->rtadv.AdvReachableTime) +	    && (ntohl(radvert->nd_ra_reachable) +		!= zif->rtadv.AdvReachableTime)) { +		zlog_warn( +			"%s(%u): Rx RA - our AdvReachableTime doesn't agree with %s", +			ifp->name, ifp->ifindex, addr_str); +	} + +	if ((radvert->nd_ra_retransmit && zif->rtadv.AdvRetransTimer) +	    && (ntohl(radvert->nd_ra_retransmit) +		!= (unsigned int)zif->rtadv.AdvRetransTimer)) { +		zlog_warn( +			"%s(%u): Rx RA - our AdvRetransTimer doesn't agree with %s", +			ifp->name, ifp->ifindex, addr_str); +	} + +	/* Create entry for neighbor if not known. */ +	p.family = AF_INET6; +	IPV6_ADDR_COPY(&p.u.prefix, &addr->sin6_addr); +	p.prefixlen = IPV6_MAX_PREFIXLEN; + +	if (!nbr_connected_check(ifp, &p)) +		nbr_connected_add_ipv6(ifp, &addr->sin6_addr);  } -static int -rtadv_read (struct thread *thread) + +static void rtadv_process_packet(u_char *buf, unsigned int len, +				 ifindex_t ifindex, int hoplimit, +				 struct sockaddr_in6 *from, +				 struct zebra_ns *zns)  { -  int sock; -  int len; -  u_char buf[RTADV_MSG_SIZE]; -  struct sockaddr_in6 from; -  ifindex_t ifindex = 0; -  int hoplimit = -1; -  struct zebra_ns *zns = THREAD_ARG (thread); +	struct icmp6_hdr *icmph; +	struct interface *ifp; +	struct zebra_if *zif; +	char addr_str[INET6_ADDRSTRLEN]; + +	inet_ntop(AF_INET6, &from->sin6_addr, addr_str, INET6_ADDRSTRLEN); + +	/* Interface search. */ +	ifp = if_lookup_by_index_per_ns(zns, ifindex); +	if (ifp == NULL) { +		zlog_warn("RA/RS received on unknown IF %u from %s", ifindex, +			  addr_str); +		return; +	} + +	if (IS_ZEBRA_DEBUG_PACKET) +		zlog_debug("%s(%u): Rx RA/RS len %d from %s", ifp->name, +			   ifp->ifindex, len, addr_str); + +	if (if_is_loopback(ifp) +	    || CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK)) +		return; -  sock = THREAD_FD (thread); -  zns->rtadv.ra_read = NULL; +	/* Check interface configuration. */ +	zif = ifp->info; +	if (!zif->rtadv.AdvSendAdvertisements) +		return; -  /* Register myself. */ -  rtadv_event (zns, RTADV_READ, sock); +	/* ICMP message length check. */ +	if (len < sizeof(struct icmp6_hdr)) { +		zlog_warn("%s(%u): Rx RA with Invalid ICMPV6 packet length %d", +			  ifp->name, ifp->ifindex, len); +		return; +	} + +	icmph = (struct icmp6_hdr *)buf; -  len = rtadv_recv_packet (zns, sock, buf, sizeof (buf), &from, &ifindex, &hoplimit); +	/* ICMP message type check. */ +	if (icmph->icmp6_type != ND_ROUTER_SOLICIT +	    && icmph->icmp6_type != ND_ROUTER_ADVERT) { +		zlog_warn("%s(%u): Rx RA - Unwanted ICMPV6 message type %d", +			  ifp->name, ifp->ifindex, icmph->icmp6_type); +		return; +	} -  if (len < 0)  -    { -      zlog_warn ("RA/RS recv failed, socket %u error %s", -                 sock, safe_strerror (errno)); -      return len; -    } +	/* Hoplimit check. */ +	if (hoplimit >= 0 && hoplimit != 255) { +		zlog_warn("%s(%u): Rx RA - Invalid hoplimit %d", ifp->name, +			  ifp->ifindex, hoplimit); +		return; +	} -  rtadv_process_packet (buf, (unsigned)len, ifindex, hoplimit, &from, zns); +	/* Check ICMP message type. */ +	if (icmph->icmp6_type == ND_ROUTER_SOLICIT) +		rtadv_process_solicit(ifp); +	else if (icmph->icmp6_type == ND_ROUTER_ADVERT) +		rtadv_process_advert(buf, len, ifp, from); -  return 0; +	return;  } -static int -rtadv_make_socket (void) +static int rtadv_read(struct thread *thread)  { -  int sock; -  int ret = 0; -  struct icmp6_filter filter; - -  if ( zserv_privs.change (ZPRIVS_RAISE) ) -       zlog_err ("rtadv_make_socket: could not raise privs, %s", -                  safe_strerror (errno) ); -                   -  sock = socket (AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); - -  if ( zserv_privs.change (ZPRIVS_LOWER) ) -       zlog_err ("rtadv_make_socket: could not lower privs, %s", -       			 safe_strerror (errno) ); - -  if (sock < 0) -    { -      close (sock); -      return -1; -    } - -  ret = setsockopt_ipv6_pktinfo (sock, 1); -  if (ret < 0) -    { -      close (sock); -      return ret; -    } -  ret = setsockopt_ipv6_multicast_loop (sock, 0); -  if (ret < 0) -    { -      close (sock); -      return ret; -    } -  ret = setsockopt_ipv6_unicast_hops (sock, 255); -  if (ret < 0) -    { -      close (sock); -      return ret; -    } -  ret = setsockopt_ipv6_multicast_hops (sock, 255); -  if (ret < 0) -    { -      close (sock); -      return ret; -    } -  ret = setsockopt_ipv6_hoplimit (sock, 1); -  if (ret < 0) -    { -      close (sock); -      return ret; -    } - -  ICMP6_FILTER_SETBLOCKALL(&filter); -  ICMP6_FILTER_SETPASS (ND_ROUTER_SOLICIT, &filter); -  ICMP6_FILTER_SETPASS (ND_ROUTER_ADVERT, &filter); - -  ret = setsockopt (sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filter, -		    sizeof (struct icmp6_filter)); -  if (ret < 0) -    { -      zlog_info ("ICMP6_FILTER set fail: %s", safe_strerror (errno)); -      return ret; -    } - -  return sock; +	int sock; +	int len; +	u_char buf[RTADV_MSG_SIZE]; +	struct sockaddr_in6 from; +	ifindex_t ifindex = 0; +	int hoplimit = -1; +	struct zebra_ns *zns = THREAD_ARG(thread); + +	sock = THREAD_FD(thread); +	zns->rtadv.ra_read = NULL; + +	/* Register myself. */ +	rtadv_event(zns, RTADV_READ, sock); + +	len = rtadv_recv_packet(zns, sock, buf, sizeof(buf), &from, &ifindex, +				&hoplimit); + +	if (len < 0) { +		zlog_warn("RA/RS recv failed, socket %u error %s", sock, +			  safe_strerror(errno)); +		return len; +	} + +	rtadv_process_packet(buf, (unsigned)len, ifindex, hoplimit, &from, zns); + +	return 0;  } -static struct rtadv_prefix * -rtadv_prefix_new (void) +static int rtadv_make_socket(void)  { -  return XCALLOC (MTYPE_RTADV_PREFIX, sizeof (struct rtadv_prefix)); +	int sock; +	int ret = 0; +	struct icmp6_filter filter; + +	if (zserv_privs.change(ZPRIVS_RAISE)) +		zlog_err("rtadv_make_socket: could not raise privs, %s", +			 safe_strerror(errno)); + +	sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); + +	if (zserv_privs.change(ZPRIVS_LOWER)) +		zlog_err("rtadv_make_socket: could not lower privs, %s", +			 safe_strerror(errno)); + +	if (sock < 0) { +		close(sock); +		return -1; +	} + +	ret = setsockopt_ipv6_pktinfo(sock, 1); +	if (ret < 0) { +		close(sock); +		return ret; +	} +	ret = setsockopt_ipv6_multicast_loop(sock, 0); +	if (ret < 0) { +		close(sock); +		return ret; +	} +	ret = setsockopt_ipv6_unicast_hops(sock, 255); +	if (ret < 0) { +		close(sock); +		return ret; +	} +	ret = setsockopt_ipv6_multicast_hops(sock, 255); +	if (ret < 0) { +		close(sock); +		return ret; +	} +	ret = setsockopt_ipv6_hoplimit(sock, 1); +	if (ret < 0) { +		close(sock); +		return ret; +	} + +	ICMP6_FILTER_SETBLOCKALL(&filter); +	ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filter); +	ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter); + +	ret = setsockopt(sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filter, +			 sizeof(struct icmp6_filter)); +	if (ret < 0) { +		zlog_info("ICMP6_FILTER set fail: %s", safe_strerror(errno)); +		return ret; +	} + +	return sock;  } -static void -rtadv_prefix_free (struct rtadv_prefix *rtadv_prefix) +static struct rtadv_prefix *rtadv_prefix_new(void)  { -  XFREE (MTYPE_RTADV_PREFIX, rtadv_prefix); +	return XCALLOC(MTYPE_RTADV_PREFIX, sizeof(struct rtadv_prefix));  } -static struct rtadv_prefix * -rtadv_prefix_lookup (struct list *rplist, struct prefix_ipv6 *p) +static void rtadv_prefix_free(struct rtadv_prefix *rtadv_prefix)  { -  struct listnode *node; -  struct rtadv_prefix *rprefix; +	XFREE(MTYPE_RTADV_PREFIX, rtadv_prefix); +} -  for (ALL_LIST_ELEMENTS_RO (rplist, node, rprefix)) -    if (prefix_same ((struct prefix *) &rprefix->prefix, (struct prefix *) p)) -      return rprefix; -  return NULL; +static struct rtadv_prefix *rtadv_prefix_lookup(struct list *rplist, +						struct prefix_ipv6 *p) +{ +	struct listnode *node; +	struct rtadv_prefix *rprefix; + +	for (ALL_LIST_ELEMENTS_RO(rplist, node, rprefix)) +		if (prefix_same((struct prefix *)&rprefix->prefix, +				(struct prefix *)p)) +			return rprefix; +	return NULL;  } -static struct rtadv_prefix * -rtadv_prefix_get (struct list *rplist, struct prefix_ipv6 *p) +static struct rtadv_prefix *rtadv_prefix_get(struct list *rplist, +					     struct prefix_ipv6 *p)  { -  struct rtadv_prefix *rprefix; -   -  rprefix = rtadv_prefix_lookup (rplist, p); -  if (rprefix) -    return rprefix; +	struct rtadv_prefix *rprefix; + +	rprefix = rtadv_prefix_lookup(rplist, p); +	if (rprefix) +		return rprefix; -  rprefix = rtadv_prefix_new (); -  memcpy (&rprefix->prefix, p, sizeof (struct prefix_ipv6)); -  listnode_add (rplist, rprefix); +	rprefix = rtadv_prefix_new(); +	memcpy(&rprefix->prefix, p, sizeof(struct prefix_ipv6)); +	listnode_add(rplist, rprefix); -  return rprefix; +	return rprefix;  } -static void -rtadv_prefix_set (struct zebra_if *zif, struct rtadv_prefix *rp) +static void rtadv_prefix_set(struct zebra_if *zif, struct rtadv_prefix *rp)  { -  struct rtadv_prefix *rprefix; -   -  rprefix = rtadv_prefix_get (zif->rtadv.AdvPrefixList, &rp->prefix); - -  /* Set parameters. */ -  rprefix->AdvValidLifetime = rp->AdvValidLifetime; -  rprefix->AdvPreferredLifetime = rp->AdvPreferredLifetime; -  rprefix->AdvOnLinkFlag = rp->AdvOnLinkFlag; -  rprefix->AdvAutonomousFlag = rp->AdvAutonomousFlag; -  rprefix->AdvRouterAddressFlag = rp->AdvRouterAddressFlag; +	struct rtadv_prefix *rprefix; + +	rprefix = rtadv_prefix_get(zif->rtadv.AdvPrefixList, &rp->prefix); + +	/* Set parameters. */ +	rprefix->AdvValidLifetime = rp->AdvValidLifetime; +	rprefix->AdvPreferredLifetime = rp->AdvPreferredLifetime; +	rprefix->AdvOnLinkFlag = rp->AdvOnLinkFlag; +	rprefix->AdvAutonomousFlag = rp->AdvAutonomousFlag; +	rprefix->AdvRouterAddressFlag = rp->AdvRouterAddressFlag;  } -static int -rtadv_prefix_reset (struct zebra_if *zif, struct rtadv_prefix *rp) +static int rtadv_prefix_reset(struct zebra_if *zif, struct rtadv_prefix *rp)  { -  struct rtadv_prefix *rprefix; -   -  rprefix = rtadv_prefix_lookup (zif->rtadv.AdvPrefixList, &rp->prefix); -  if (rprefix != NULL) -    { -      listnode_delete (zif->rtadv.AdvPrefixList, (void *) rprefix); -      rtadv_prefix_free (rprefix); -      return 1; -    } -  else -    return 0; +	struct rtadv_prefix *rprefix; + +	rprefix = rtadv_prefix_lookup(zif->rtadv.AdvPrefixList, &rp->prefix); +	if (rprefix != NULL) { +		listnode_delete(zif->rtadv.AdvPrefixList, (void *)rprefix); +		rtadv_prefix_free(rprefix); +		return 1; +	} else +		return 0;  } -static void -ipv6_nd_suppress_ra_set (struct interface *ifp, ipv6_nd_suppress_ra_status status) +static void ipv6_nd_suppress_ra_set(struct interface *ifp, +				    ipv6_nd_suppress_ra_status status)  { -  struct zebra_if *zif; -  struct zebra_vrf *zvrf; -  struct zebra_ns *zns; - -  zif = ifp->info; -  zvrf = vrf_info_lookup (ifp->vrf_id); -  zns = zvrf->zns; - -  if (status == RA_SUPPRESS) -    { -      /* RA is currently enabled */ -      if (zif->rtadv.AdvSendAdvertisements) -        { -          zif->rtadv.AdvSendAdvertisements = 0; -          zif->rtadv.AdvIntervalTimer = 0; -          zns->rtadv.adv_if_count--; - -          if_leave_all_router (zns->rtadv.sock, ifp); - -          if (zns->rtadv.adv_if_count == 0) -            rtadv_event (zns, RTADV_STOP, 0); -        } -    } -  else -    { -      if (! zif->rtadv.AdvSendAdvertisements) -        { -          zif->rtadv.AdvSendAdvertisements = 1; -          zif->rtadv.AdvIntervalTimer = 0; -          zns->rtadv.adv_if_count++; - -          if (zif->rtadv.MaxRtrAdvInterval >= 1000) -            { -              /* Enable Fast RA only when RA interval is in secs */ -              zif->rtadv.inFastRexmit = 1; -              zif->rtadv.NumFastReXmitsRemain = RTADV_NUM_FAST_REXMITS; -            } - -          if_join_all_router (zns->rtadv.sock, ifp); - -          if (zns->rtadv.adv_if_count == 1) -            rtadv_event (zns, RTADV_START, zns->rtadv.sock); -        } -    } +	struct zebra_if *zif; +	struct zebra_vrf *zvrf; +	struct zebra_ns *zns; + +	zif = ifp->info; +	zvrf = vrf_info_lookup(ifp->vrf_id); +	zns = zvrf->zns; + +	if (status == RA_SUPPRESS) { +		/* RA is currently enabled */ +		if (zif->rtadv.AdvSendAdvertisements) { +			zif->rtadv.AdvSendAdvertisements = 0; +			zif->rtadv.AdvIntervalTimer = 0; +			zns->rtadv.adv_if_count--; + +			if_leave_all_router(zns->rtadv.sock, ifp); + +			if (zns->rtadv.adv_if_count == 0) +				rtadv_event(zns, RTADV_STOP, 0); +		} +	} else { +		if (!zif->rtadv.AdvSendAdvertisements) { +			zif->rtadv.AdvSendAdvertisements = 1; +			zif->rtadv.AdvIntervalTimer = 0; +			zns->rtadv.adv_if_count++; + +			if (zif->rtadv.MaxRtrAdvInterval >= 1000) { +				/* Enable Fast RA only when RA interval is in +				 * secs */ +				zif->rtadv.inFastRexmit = 1; +				zif->rtadv.NumFastReXmitsRemain = +					RTADV_NUM_FAST_REXMITS; +			} + +			if_join_all_router(zns->rtadv.sock, ifp); + +			if (zns->rtadv.adv_if_count == 1) +				rtadv_event(zns, RTADV_START, zns->rtadv.sock); +		} +	}  }  /* @@ -809,60 +788,55 @@ ipv6_nd_suppress_ra_set (struct interface *ifp, ipv6_nd_suppress_ra_status statu   * if the operator has explicitly enabled RA. The enable request can also   * specify a RA interval (in seconds).   */ -void -zebra_interface_radv_set (struct zserv *client, int sock, u_short length, -                          struct zebra_vrf *zvrf, int enable) +void zebra_interface_radv_set(struct zserv *client, int sock, u_short length, +			      struct zebra_vrf *zvrf, int enable)  { -  struct stream *s; -  unsigned int ifindex; -  struct interface *ifp; -  struct zebra_if *zif; -  int ra_interval; - -  s = client->ibuf; - -  /* Get interface index and RA interval. */ -  ifindex = stream_getl (s); -  ra_interval = stream_getl (s); - -  if (IS_ZEBRA_DEBUG_EVENT) -    zlog_debug("%u: IF %u RA %s from client %s, interval %ds", -               zvrf_id (zvrf), ifindex, enable ? "enable" : "disable", -               zebra_route_string(client->proto), ra_interval); - -  /* Locate interface and check VRF match. */ -  ifp = if_lookup_by_index_per_ns (zebra_ns_lookup (NS_DEFAULT), ifindex); -  if (!ifp) -    { -      zlog_warn("%u: IF %u RA %s client %s - interface unknown", -               zvrf_id (zvrf), ifindex, enable ? "enable" : "disable", -               zebra_route_string(client->proto)); -      return; -    } -  if (ifp->vrf_id != zvrf_id (zvrf)) -    { -      zlog_warn("%u: IF %u RA %s client %s - VRF mismatch, IF VRF %u", -               zvrf_id (zvrf), ifindex, enable ? "enable" : "disable", -               zebra_route_string(client->proto), ifp->vrf_id); -      return; -    } - -  zif = ifp->info; -  if (enable) -    { -      ipv6_nd_suppress_ra_set (ifp, RA_ENABLE); -      if (ra_interval && -          (ra_interval * 1000) < zif->rtadv.MaxRtrAdvInterval) -        zif->rtadv.MaxRtrAdvInterval = ra_interval * 1000; -    } -  else -    { -      if (!zif->rtadv.configured) -        { -          zif->rtadv.MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL; -          ipv6_nd_suppress_ra_set (ifp, RA_SUPPRESS); -        } -    } +	struct stream *s; +	unsigned int ifindex; +	struct interface *ifp; +	struct zebra_if *zif; +	int ra_interval; + +	s = client->ibuf; + +	/* Get interface index and RA interval. */ +	ifindex = stream_getl(s); +	ra_interval = stream_getl(s); + +	if (IS_ZEBRA_DEBUG_EVENT) +		zlog_debug("%u: IF %u RA %s from client %s, interval %ds", +			   zvrf_id(zvrf), ifindex, +			   enable ? "enable" : "disable", +			   zebra_route_string(client->proto), ra_interval); + +	/* Locate interface and check VRF match. */ +	ifp = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT), ifindex); +	if (!ifp) { +		zlog_warn("%u: IF %u RA %s client %s - interface unknown", +			  zvrf_id(zvrf), ifindex, enable ? "enable" : "disable", +			  zebra_route_string(client->proto)); +		return; +	} +	if (ifp->vrf_id != zvrf_id(zvrf)) { +		zlog_warn("%u: IF %u RA %s client %s - VRF mismatch, IF VRF %u", +			  zvrf_id(zvrf), ifindex, enable ? "enable" : "disable", +			  zebra_route_string(client->proto), ifp->vrf_id); +		return; +	} + +	zif = ifp->info; +	if (enable) { +		ipv6_nd_suppress_ra_set(ifp, RA_ENABLE); +		if (ra_interval +		    && (ra_interval * 1000) < zif->rtadv.MaxRtrAdvInterval) +			zif->rtadv.MaxRtrAdvInterval = ra_interval * 1000; +	} else { +		if (!zif->rtadv.configured) { +			zif->rtadv.MaxRtrAdvInterval = +				RTADV_MAX_RTR_ADV_INTERVAL; +			ipv6_nd_suppress_ra_set(ifp, RA_SUPPRESS); +		} +	}  }  DEFUN (ipv6_nd_suppress_ra, @@ -872,19 +846,20 @@ DEFUN (ipv6_nd_suppress_ra,         "Neighbor discovery\n"         "Suppress Router Advertisement\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zif = ifp->info; - -  if (if_is_loopback (ifp) || -      CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK)) -    { -      vty_out (vty, "Cannot configure IPv6 Router Advertisements on this  interface%s", VTY_NEWLINE); -      return CMD_WARNING; -    } - -  ipv6_nd_suppress_ra_set (ifp, RA_SUPPRESS); -  zif->rtadv.configured = 0; -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zif = ifp->info; + +	if (if_is_loopback(ifp) +	    || CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK)) { +		vty_out(vty, +			"Cannot configure IPv6 Router Advertisements on this  interface%s", +			VTY_NEWLINE); +		return CMD_WARNING; +	} + +	ipv6_nd_suppress_ra_set(ifp, RA_SUPPRESS); +	zif->rtadv.configured = 0; +	return CMD_SUCCESS;  }  DEFUN (no_ipv6_nd_suppress_ra, @@ -895,19 +870,20 @@ DEFUN (no_ipv6_nd_suppress_ra,         "Neighbor discovery\n"         "Suppress Router Advertisement\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zif = ifp->info; - -  if (if_is_loopback (ifp) || -      CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK)) -    { -      vty_out (vty, "Cannot configure IPv6 Router Advertisements on this interface%s", VTY_NEWLINE); -      return CMD_WARNING; -    } - -  ipv6_nd_suppress_ra_set (ifp, RA_ENABLE); -  zif->rtadv.configured = 1; -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zif = ifp->info; + +	if (if_is_loopback(ifp) +	    || CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK)) { +		vty_out(vty, +			"Cannot configure IPv6 Router Advertisements on this interface%s", +			VTY_NEWLINE); +		return CMD_WARNING; +	} + +	ipv6_nd_suppress_ra_set(ifp, RA_ENABLE); +	zif->rtadv.configured = 1; +	return CMD_SUCCESS;  }  DEFUN (ipv6_nd_ra_interval_msec, @@ -919,32 +895,35 @@ DEFUN (ipv6_nd_ra_interval_msec,         "Router Advertisement interval in milliseconds\n"         "Router Advertisement interval in milliseconds\n")  { -  int idx_number = 4; -  VTY_DECLVAR_CONTEXT (interface, ifp); -  unsigned interval; -  struct zebra_if *zif = ifp->info; -  struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id); -  struct zebra_ns *zns; - -  zns = zvrf->zns; -  VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[idx_number]->arg, 70, 1800000); -  if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime * 1000)) -  { -    vty_out (vty, "This ra-interval would conflict with configured ra-lifetime!%s", VTY_NEWLINE); -    return CMD_WARNING; -  } - -  if (zif->rtadv.MaxRtrAdvInterval % 1000) -    zns->rtadv.adv_msec_if_count--; - -  if (interval % 1000) -    zns->rtadv.adv_msec_if_count++; -   -  zif->rtadv.MaxRtrAdvInterval = interval; -  zif->rtadv.MinRtrAdvInterval = 0.33 * interval; -  zif->rtadv.AdvIntervalTimer = 0; - -  return CMD_SUCCESS; +	int idx_number = 4; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	unsigned interval; +	struct zebra_if *zif = ifp->info; +	struct zebra_vrf *zvrf = vrf_info_lookup(ifp->vrf_id); +	struct zebra_ns *zns; + +	zns = zvrf->zns; +	VTY_GET_INTEGER_RANGE("router advertisement interval", interval, +			      argv[idx_number]->arg, 70, 1800000); +	if ((zif->rtadv.AdvDefaultLifetime != -1 +	     && interval > (unsigned)zif->rtadv.AdvDefaultLifetime * 1000)) { +		vty_out(vty, +			"This ra-interval would conflict with configured ra-lifetime!%s", +			VTY_NEWLINE); +		return CMD_WARNING; +	} + +	if (zif->rtadv.MaxRtrAdvInterval % 1000) +		zns->rtadv.adv_msec_if_count--; + +	if (interval % 1000) +		zns->rtadv.adv_msec_if_count++; + +	zif->rtadv.MaxRtrAdvInterval = interval; +	zif->rtadv.MinRtrAdvInterval = 0.33 * interval; +	zif->rtadv.AdvIntervalTimer = 0; + +	return CMD_SUCCESS;  }  DEFUN (ipv6_nd_ra_interval, @@ -955,32 +934,35 @@ DEFUN (ipv6_nd_ra_interval,         "Router Advertisement interval\n"         "Router Advertisement interval in seconds\n")  { -  int idx_number = 3; -  VTY_DECLVAR_CONTEXT (interface, ifp); -  unsigned interval; -  struct zebra_if *zif = ifp->info; -  struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id); -  struct zebra_ns *zns; - -  zns = zvrf->zns; -  VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[idx_number]->arg, 1, 1800); -  if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime)) -  { -    vty_out (vty, "This ra-interval would conflict with configured ra-lifetime!%s", VTY_NEWLINE); -    return CMD_WARNING; -  } - -  if (zif->rtadv.MaxRtrAdvInterval % 1000) -    zns->rtadv.adv_msec_if_count--; -	 -  /* convert to milliseconds */ -  interval = interval * 1000;  -	 -  zif->rtadv.MaxRtrAdvInterval = interval; -  zif->rtadv.MinRtrAdvInterval = 0.33 * interval; -  zif->rtadv.AdvIntervalTimer = 0; - -  return CMD_SUCCESS; +	int idx_number = 3; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	unsigned interval; +	struct zebra_if *zif = ifp->info; +	struct zebra_vrf *zvrf = vrf_info_lookup(ifp->vrf_id); +	struct zebra_ns *zns; + +	zns = zvrf->zns; +	VTY_GET_INTEGER_RANGE("router advertisement interval", interval, +			      argv[idx_number]->arg, 1, 1800); +	if ((zif->rtadv.AdvDefaultLifetime != -1 +	     && interval > (unsigned)zif->rtadv.AdvDefaultLifetime)) { +		vty_out(vty, +			"This ra-interval would conflict with configured ra-lifetime!%s", +			VTY_NEWLINE); +		return CMD_WARNING; +	} + +	if (zif->rtadv.MaxRtrAdvInterval % 1000) +		zns->rtadv.adv_msec_if_count--; + +	/* convert to milliseconds */ +	interval = interval * 1000; + +	zif->rtadv.MaxRtrAdvInterval = interval; +	zif->rtadv.MinRtrAdvInterval = 0.33 * interval; +	zif->rtadv.AdvIntervalTimer = 0; + +	return CMD_SUCCESS;  }  DEFUN (no_ipv6_nd_ra_interval, @@ -994,22 +976,22 @@ DEFUN (no_ipv6_nd_ra_interval,         "Specify millisecond router advertisement interval\n"         "Router Advertisement interval in milliseconds\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zif = ifp->info; -  struct zebra_vrf *zvrf; -  struct zebra_ns *zns; - -  zvrf = vrf_info_lookup (ifp->vrf_id); -  zns = zvrf->zns; - -  if (zif->rtadv.MaxRtrAdvInterval % 1000) -    zns->rtadv.adv_msec_if_count--; -   -  zif->rtadv.MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL; -  zif->rtadv.MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL; -  zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval; - -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zif = ifp->info; +	struct zebra_vrf *zvrf; +	struct zebra_ns *zns; + +	zvrf = vrf_info_lookup(ifp->vrf_id); +	zns = zvrf->zns; + +	if (zif->rtadv.MaxRtrAdvInterval % 1000) +		zns->rtadv.adv_msec_if_count--; + +	zif->rtadv.MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL; +	zif->rtadv.MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL; +	zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval; + +	return CMD_SUCCESS;  }  DEFUN (ipv6_nd_ra_lifetime, @@ -1020,26 +1002,28 @@ DEFUN (ipv6_nd_ra_lifetime,         "Router lifetime\n"         "Router lifetime in seconds (0 stands for a non-default gw)\n")  { -  int idx_number = 3; -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zif = ifp->info; -  int lifetime; - -  VTY_GET_INTEGER_RANGE ("router lifetime", lifetime, argv[idx_number]->arg, 0, 9000); - -  /* The value to be placed in the Router Lifetime field -   * of Router Advertisements sent from the interface, -   * in seconds.  MUST be either zero or between -   * MaxRtrAdvInterval and 9000 seconds. -- RFC4861, 6.2.1 */ -  if ((lifetime != 0 && lifetime * 1000 < zif->rtadv.MaxRtrAdvInterval)) -    { -      vty_out (vty, "This ra-lifetime would conflict with configured ra-interval%s", VTY_NEWLINE); -      return CMD_WARNING; -    } - -  zif->rtadv.AdvDefaultLifetime = lifetime; - -  return CMD_SUCCESS; +	int idx_number = 3; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zif = ifp->info; +	int lifetime; + +	VTY_GET_INTEGER_RANGE("router lifetime", lifetime, +			      argv[idx_number]->arg, 0, 9000); + +	/* The value to be placed in the Router Lifetime field +	 * of Router Advertisements sent from the interface, +	 * in seconds.  MUST be either zero or between +	 * MaxRtrAdvInterval and 9000 seconds. -- RFC4861, 6.2.1 */ +	if ((lifetime != 0 && lifetime * 1000 < zif->rtadv.MaxRtrAdvInterval)) { +		vty_out(vty, +			"This ra-lifetime would conflict with configured ra-interval%s", +			VTY_NEWLINE); +		return CMD_WARNING; +	} + +	zif->rtadv.AdvDefaultLifetime = lifetime; + +	return CMD_SUCCESS;  }  DEFUN (no_ipv6_nd_ra_lifetime, @@ -1051,12 +1035,12 @@ DEFUN (no_ipv6_nd_ra_lifetime,         "Router lifetime\n"         "Router lifetime in seconds (0 stands for a non-default gw)\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zif = ifp->info; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zif = ifp->info; -  zif->rtadv.AdvDefaultLifetime = -1; +	zif->rtadv.AdvDefaultLifetime = -1; -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (ipv6_nd_reachable_time, @@ -1067,11 +1051,13 @@ DEFUN (ipv6_nd_reachable_time,         "Reachable time\n"         "Reachable time in milliseconds\n")  { -  int idx_number = 3; -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zif = ifp->info; -  VTY_GET_INTEGER_RANGE ("reachable time", zif->rtadv.AdvReachableTime, argv[idx_number]->arg, 1, RTADV_MAX_REACHABLE_TIME); -  return CMD_SUCCESS; +	int idx_number = 3; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zif = ifp->info; +	VTY_GET_INTEGER_RANGE("reachable time", zif->rtadv.AdvReachableTime, +			      argv[idx_number]->arg, 1, +			      RTADV_MAX_REACHABLE_TIME); +	return CMD_SUCCESS;  }  DEFUN (no_ipv6_nd_reachable_time, @@ -1083,12 +1069,12 @@ DEFUN (no_ipv6_nd_reachable_time,         "Reachable time\n"         "Reachable time in milliseconds\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zif = ifp->info; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zif = ifp->info; -  zif->rtadv.AdvReachableTime = 0; +	zif->rtadv.AdvReachableTime = 0; -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (ipv6_nd_homeagent_preference, @@ -1099,11 +1085,13 @@ DEFUN (ipv6_nd_homeagent_preference,         "Home Agent preference\n"         "preference value (default is 0, least preferred)\n")  { -  int idx_number = 3; -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zif = ifp->info; -  VTY_GET_INTEGER_RANGE ("home agent preference", zif->rtadv.HomeAgentPreference, argv[idx_number]->arg, 0, 65535); -  return CMD_SUCCESS; +	int idx_number = 3; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zif = ifp->info; +	VTY_GET_INTEGER_RANGE("home agent preference", +			      zif->rtadv.HomeAgentPreference, +			      argv[idx_number]->arg, 0, 65535); +	return CMD_SUCCESS;  }  DEFUN (no_ipv6_nd_homeagent_preference, @@ -1115,12 +1103,12 @@ DEFUN (no_ipv6_nd_homeagent_preference,         "Home Agent preference\n"         "preference value (default is 0, least preferred)\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zif = ifp->info; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zif = ifp->info; -  zif->rtadv.HomeAgentPreference = 0; +	zif->rtadv.HomeAgentPreference = 0; -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (ipv6_nd_homeagent_lifetime, @@ -1131,11 +1119,13 @@ DEFUN (ipv6_nd_homeagent_lifetime,         "Home Agent lifetime\n"         "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")  { -  int idx_number = 3; -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zif = ifp->info; -  VTY_GET_INTEGER_RANGE ("home agent lifetime", zif->rtadv.HomeAgentLifetime, argv[idx_number]->arg, 0, RTADV_MAX_HALIFETIME); -  return CMD_SUCCESS; +	int idx_number = 3; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zif = ifp->info; +	VTY_GET_INTEGER_RANGE("home agent lifetime", +			      zif->rtadv.HomeAgentLifetime, +			      argv[idx_number]->arg, 0, RTADV_MAX_HALIFETIME); +	return CMD_SUCCESS;  }  DEFUN (no_ipv6_nd_homeagent_lifetime, @@ -1147,12 +1137,12 @@ DEFUN (no_ipv6_nd_homeagent_lifetime,         "Home Agent lifetime\n"         "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zif = ifp->info; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zif = ifp->info; -  zif->rtadv.HomeAgentLifetime = -1; +	zif->rtadv.HomeAgentLifetime = -1; -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (ipv6_nd_managed_config_flag, @@ -1162,12 +1152,12 @@ DEFUN (ipv6_nd_managed_config_flag,         "Neighbor discovery\n"         "Managed address configuration flag\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zif = ifp->info; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zif = ifp->info; -  zif->rtadv.AdvManagedFlag = 1; +	zif->rtadv.AdvManagedFlag = 1; -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (no_ipv6_nd_managed_config_flag, @@ -1178,12 +1168,12 @@ DEFUN (no_ipv6_nd_managed_config_flag,         "Neighbor discovery\n"         "Managed address configuration flag\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zif = ifp->info; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zif = ifp->info; -  zif->rtadv.AdvManagedFlag = 0; +	zif->rtadv.AdvManagedFlag = 0; -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (ipv6_nd_homeagent_config_flag, @@ -1193,12 +1183,12 @@ DEFUN (ipv6_nd_homeagent_config_flag,         "Neighbor discovery\n"         "Home Agent configuration flag\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zif = ifp->info; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zif = ifp->info; -  zif->rtadv.AdvHomeAgentFlag = 1; +	zif->rtadv.AdvHomeAgentFlag = 1; -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (no_ipv6_nd_homeagent_config_flag, @@ -1209,12 +1199,12 @@ DEFUN (no_ipv6_nd_homeagent_config_flag,         "Neighbor discovery\n"         "Home Agent configuration flag\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zif = ifp->info; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zif = ifp->info; -  zif->rtadv.AdvHomeAgentFlag = 0; +	zif->rtadv.AdvHomeAgentFlag = 0; -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (ipv6_nd_adv_interval_config_option, @@ -1224,12 +1214,12 @@ DEFUN (ipv6_nd_adv_interval_config_option,         "Neighbor discovery\n"         "Advertisement Interval Option\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zif = ifp->info; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zif = ifp->info; -  zif->rtadv.AdvIntervalOption = 1; +	zif->rtadv.AdvIntervalOption = 1; -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (no_ipv6_nd_adv_interval_config_option, @@ -1240,12 +1230,12 @@ DEFUN (no_ipv6_nd_adv_interval_config_option,         "Neighbor discovery\n"         "Advertisement Interval Option\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zif = ifp->info; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zif = ifp->info; -  zif->rtadv.AdvIntervalOption = 0; +	zif->rtadv.AdvIntervalOption = 0; -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (ipv6_nd_other_config_flag, @@ -1255,12 +1245,12 @@ DEFUN (ipv6_nd_other_config_flag,         "Neighbor discovery\n"         "Other statefull configuration flag\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zif = ifp->info; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zif = ifp->info; -  zif->rtadv.AdvOtherConfigFlag = 1; +	zif->rtadv.AdvOtherConfigFlag = 1; -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (no_ipv6_nd_other_config_flag, @@ -1271,12 +1261,12 @@ DEFUN (no_ipv6_nd_other_config_flag,         "Neighbor discovery\n"         "Other statefull configuration flag\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zif = ifp->info; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zif = ifp->info; -  zif->rtadv.AdvOtherConfigFlag = 0; +	zif->rtadv.AdvOtherConfigFlag = 0; -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (ipv6_nd_prefix, @@ -1296,63 +1286,71 @@ DEFUN (ipv6_nd_prefix,         "Do not use prefix for autoconfiguration\n"         "Do not use prefix for onlink determination\n")  { -  /* prelude */ -  char *prefix = argv[3]->arg; -  int lifetimes = (argc > 4) && (argv[4]->type == RANGE_TKN || strmatch (argv[4]->text, "infinite")); -  int routeropts = lifetimes ? argc > 6 : argc > 4; - -  int idx_routeropts = routeropts ? (lifetimes ? 6 : 4) : 0; - -  char *lifetime = NULL, *preflifetime = NULL; -  int routeraddr = 0, offlink = 0, noautoconf = 0; -  if (lifetimes) -  { -    lifetime     = argv[4]->type == RANGE_TKN ? argv[4]->arg : argv[4]->text; -    preflifetime = argv[5]->type == RANGE_TKN ? argv[5]->arg : argv[5]->text; -  } -  if (routeropts) -  { -    routeraddr = strmatch (argv[idx_routeropts]->text, "router-address"); -    if (!routeraddr) -    { -      offlink    = (argc > idx_routeropts + 1 || strmatch (argv[idx_routeropts]->text, "off-link")); -      noautoconf = (argc > idx_routeropts + 1 || strmatch (argv[idx_routeropts]->text, "no-autoconfig")); -    } -  } - -  /* business */ -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zebra_if = ifp->info; -  int ret; -  struct rtadv_prefix rp; - -  ret = str2prefix_ipv6 (prefix, &rp.prefix); -  if (!ret) -    { -      vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE); -      return CMD_WARNING; -    } -  apply_mask_ipv6 (&rp.prefix); /* RFC4861 4.6.2 */ -  rp.AdvOnLinkFlag = !offlink; -  rp.AdvAutonomousFlag = !noautoconf; -  rp.AdvRouterAddressFlag = routeraddr; -  rp.AdvValidLifetime = RTADV_VALID_LIFETIME; -  rp.AdvPreferredLifetime = RTADV_PREFERRED_LIFETIME; - -  if (lifetimes) -  { -    rp.AdvValidLifetime     = strmatch (lifetime, "infinite") ? UINT32_MAX : strtoll (lifetime, NULL, 10); -    rp.AdvPreferredLifetime = strmatch (preflifetime, "infinite") ? UINT32_MAX : strtoll (preflifetime, NULL, 10); -    if (rp.AdvPreferredLifetime > rp.AdvValidLifetime) -      { -        vty_out (vty, "Invalid preferred lifetime%s", VTY_NEWLINE); -        return CMD_WARNING; -      } -  } - -  rtadv_prefix_set (zebra_if, &rp); - -  return CMD_SUCCESS; +	/* prelude */ +	char *prefix = argv[3]->arg; +	int lifetimes = (argc > 4) && (argv[4]->type == RANGE_TKN +				       || strmatch(argv[4]->text, "infinite")); +	int routeropts = lifetimes ? argc > 6 : argc > 4; + +	int idx_routeropts = routeropts ? (lifetimes ? 6 : 4) : 0; + +	char *lifetime = NULL, *preflifetime = NULL; +	int routeraddr = 0, offlink = 0, noautoconf = 0; +	if (lifetimes) { +		lifetime = argv[4]->type == RANGE_TKN ? argv[4]->arg +						      : argv[4]->text; +		preflifetime = argv[5]->type == RANGE_TKN ? argv[5]->arg +							  : argv[5]->text; +	} +	if (routeropts) { +		routeraddr = +			strmatch(argv[idx_routeropts]->text, "router-address"); +		if (!routeraddr) { +			offlink = (argc > idx_routeropts + 1 +				   || strmatch(argv[idx_routeropts]->text, +					       "off-link")); +			noautoconf = (argc > idx_routeropts + 1 +				      || strmatch(argv[idx_routeropts]->text, +						  "no-autoconfig")); +		} +	} + +	/* business */ +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zebra_if = ifp->info; +	int ret; +	struct rtadv_prefix rp; + +	ret = str2prefix_ipv6(prefix, &rp.prefix); +	if (!ret) { +		vty_out(vty, "Malformed IPv6 prefix%s", VTY_NEWLINE); +		return CMD_WARNING; +	} +	apply_mask_ipv6(&rp.prefix); /* RFC4861 4.6.2 */ +	rp.AdvOnLinkFlag = !offlink; +	rp.AdvAutonomousFlag = !noautoconf; +	rp.AdvRouterAddressFlag = routeraddr; +	rp.AdvValidLifetime = RTADV_VALID_LIFETIME; +	rp.AdvPreferredLifetime = RTADV_PREFERRED_LIFETIME; + +	if (lifetimes) { +		rp.AdvValidLifetime = strmatch(lifetime, "infinite") +					      ? UINT32_MAX +					      : strtoll(lifetime, NULL, 10); +		rp.AdvPreferredLifetime = +			strmatch(preflifetime, "infinite") +				? UINT32_MAX +				: strtoll(preflifetime, NULL, 10); +		if (rp.AdvPreferredLifetime > rp.AdvValidLifetime) { +			vty_out(vty, "Invalid preferred lifetime%s", +				VTY_NEWLINE); +			return CMD_WARNING; +		} +	} + +	rtadv_prefix_set(zebra_if, &rp); + +	return CMD_SUCCESS;  }  DEFUN (no_ipv6_nd_prefix, @@ -1373,28 +1371,26 @@ DEFUN (no_ipv6_nd_prefix,         "Do not use prefix for autoconfiguration\n"         "Do not use prefix for onlink determination\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zebra_if = ifp->info; -  int ret; -  struct rtadv_prefix rp; -  char *prefix = argv[4]->arg; - -  ret = str2prefix_ipv6 (prefix, &rp.prefix); -  if (!ret) -    { -      vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE); -      return CMD_WARNING; -    } -  apply_mask_ipv6 (&rp.prefix); /* RFC4861 4.6.2 */ - -  ret = rtadv_prefix_reset (zebra_if, &rp); -  if (!ret) -    { -      vty_out (vty, "Non-existant IPv6 prefix%s", VTY_NEWLINE); -      return CMD_WARNING; -    } - -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zebra_if = ifp->info; +	int ret; +	struct rtadv_prefix rp; +	char *prefix = argv[4]->arg; + +	ret = str2prefix_ipv6(prefix, &rp.prefix); +	if (!ret) { +		vty_out(vty, "Malformed IPv6 prefix%s", VTY_NEWLINE); +		return CMD_WARNING; +	} +	apply_mask_ipv6(&rp.prefix); /* RFC4861 4.6.2 */ + +	ret = rtadv_prefix_reset(zebra_if, &rp); +	if (!ret) { +		vty_out(vty, "Non-existant IPv6 prefix%s", VTY_NEWLINE); +		return CMD_WARNING; +	} + +	return CMD_SUCCESS;  }  DEFUN (ipv6_nd_router_preference, @@ -1407,22 +1403,22 @@ DEFUN (ipv6_nd_router_preference,         "Low default router preference\n"         "Medium default router preference (default)\n")  { -  int idx_high_medium_low = 3; -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zif = ifp->info; -  int i = 0; - -  while (0 != rtadv_pref_strs[i]) -    { -      if (strncmp (argv[idx_high_medium_low]->arg, rtadv_pref_strs[i], 1) == 0) -	{ -	  zif->rtadv.DefaultPreference = i; -	  return CMD_SUCCESS; +	int idx_high_medium_low = 3; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zif = ifp->info; +	int i = 0; + +	while (0 != rtadv_pref_strs[i]) { +		if (strncmp(argv[idx_high_medium_low]->arg, rtadv_pref_strs[i], +			    1) +		    == 0) { +			zif->rtadv.DefaultPreference = i; +			return CMD_SUCCESS; +		} +		i++;  	} -      i++; -    } -  return CMD_ERR_NO_MATCH; +	return CMD_ERR_NO_MATCH;  }  DEFUN (no_ipv6_nd_router_preference, @@ -1436,12 +1432,13 @@ DEFUN (no_ipv6_nd_router_preference,         "Medium default router preference (default)\n"         "Low default router preference\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zif = ifp->info; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zif = ifp->info; -  zif->rtadv.DefaultPreference = RTADV_PREF_MEDIUM; /* Default per RFC4191. */ +	zif->rtadv.DefaultPreference = +		RTADV_PREF_MEDIUM; /* Default per RFC4191. */ -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (ipv6_nd_mtu, @@ -1452,11 +1449,12 @@ DEFUN (ipv6_nd_mtu,         "Advertised MTU\n"         "MTU in bytes\n")  { -  int idx_number = 3; -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zif = ifp->info; -  VTY_GET_INTEGER_RANGE ("MTU", zif->rtadv.AdvLinkMTU, argv[idx_number]->arg, 1, 65535); -  return CMD_SUCCESS; +	int idx_number = 3; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zif = ifp->info; +	VTY_GET_INTEGER_RANGE("MTU", zif->rtadv.AdvLinkMTU, +			      argv[idx_number]->arg, 1, 65535); +	return CMD_SUCCESS;  }  DEFUN (no_ipv6_nd_mtu, @@ -1468,264 +1466,255 @@ DEFUN (no_ipv6_nd_mtu,         "Advertised MTU\n"         "MTU in bytes\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *zif = ifp->info; -  zif->rtadv.AdvLinkMTU = 0; -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zif = ifp->info; +	zif->rtadv.AdvLinkMTU = 0; +	return CMD_SUCCESS;  }  /* Write configuration about router advertisement. */ -void -rtadv_config_write (struct vty *vty, struct interface *ifp) +void rtadv_config_write(struct vty *vty, struct interface *ifp)  { -  struct zebra_if *zif; -  struct listnode *node; -  struct rtadv_prefix *rprefix; -  char buf[PREFIX_STRLEN]; -  int interval; - -  zif = ifp->info; - -  if (!(if_is_loopback (ifp) || -        CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK))) -    { -      if (zif->rtadv.AdvSendAdvertisements) -        vty_out (vty, " no ipv6 nd suppress-ra%s", VTY_NEWLINE); -    } -   -  interval = zif->rtadv.MaxRtrAdvInterval; -  if (interval % 1000) -    vty_out (vty, " ipv6 nd ra-interval msec %d%s", interval, -	     VTY_NEWLINE); -  else -    if (interval != RTADV_MAX_RTR_ADV_INTERVAL) -      vty_out (vty, " ipv6 nd ra-interval %d%s", interval / 1000, -	     VTY_NEWLINE); - -  if (zif->rtadv.AdvIntervalOption) -    vty_out (vty, " ipv6 nd adv-interval-option%s", VTY_NEWLINE); - -  if (zif->rtadv.AdvDefaultLifetime != -1) -    vty_out (vty, " ipv6 nd ra-lifetime %d%s", zif->rtadv.AdvDefaultLifetime, -	     VTY_NEWLINE); - -  if (zif->rtadv.HomeAgentPreference) -    vty_out (vty, " ipv6 nd home-agent-preference %u%s", -	     zif->rtadv.HomeAgentPreference, VTY_NEWLINE); - -  if (zif->rtadv.HomeAgentLifetime != -1) -    vty_out (vty, " ipv6 nd home-agent-lifetime %u%s", -	     zif->rtadv.HomeAgentLifetime, VTY_NEWLINE); - -  if (zif->rtadv.AdvHomeAgentFlag) -    vty_out (vty, " ipv6 nd home-agent-config-flag%s", VTY_NEWLINE); - -  if (zif->rtadv.AdvReachableTime) -    vty_out (vty, " ipv6 nd reachable-time %d%s", zif->rtadv.AdvReachableTime, -	     VTY_NEWLINE); - -  if (zif->rtadv.AdvManagedFlag) -    vty_out (vty, " ipv6 nd managed-config-flag%s", VTY_NEWLINE); - -  if (zif->rtadv.AdvOtherConfigFlag) -    vty_out (vty, " ipv6 nd other-config-flag%s", VTY_NEWLINE); - -  if (zif->rtadv.DefaultPreference != RTADV_PREF_MEDIUM) -    vty_out (vty, " ipv6 nd router-preference %s%s", -	     rtadv_pref_strs[zif->rtadv.DefaultPreference], -	     VTY_NEWLINE); - -  if (zif->rtadv.AdvLinkMTU) -    vty_out (vty, " ipv6 nd mtu %d%s", zif->rtadv.AdvLinkMTU, VTY_NEWLINE); - -  for (ALL_LIST_ELEMENTS_RO (zif->rtadv.AdvPrefixList, node, rprefix)) -    { -      vty_out (vty, " ipv6 nd prefix %s", -               prefix2str (&rprefix->prefix, buf, sizeof(buf))); -      if ((rprefix->AdvValidLifetime != RTADV_VALID_LIFETIME) ||  -	  (rprefix->AdvPreferredLifetime != RTADV_PREFERRED_LIFETIME)) -	{ -	  if (rprefix->AdvValidLifetime == UINT32_MAX) -	    vty_out (vty, " infinite"); -	  else -	    vty_out (vty, " %u", rprefix->AdvValidLifetime); -	  if (rprefix->AdvPreferredLifetime == UINT32_MAX) -	    vty_out (vty, " infinite"); -	  else -	    vty_out (vty, " %u", rprefix->AdvPreferredLifetime); +	struct zebra_if *zif; +	struct listnode *node; +	struct rtadv_prefix *rprefix; +	char buf[PREFIX_STRLEN]; +	int interval; + +	zif = ifp->info; + +	if (!(if_is_loopback(ifp) +	      || CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK))) { +		if (zif->rtadv.AdvSendAdvertisements) +			vty_out(vty, " no ipv6 nd suppress-ra%s", VTY_NEWLINE); +	} + +	interval = zif->rtadv.MaxRtrAdvInterval; +	if (interval % 1000) +		vty_out(vty, " ipv6 nd ra-interval msec %d%s", interval, +			VTY_NEWLINE); +	else if (interval != RTADV_MAX_RTR_ADV_INTERVAL) +		vty_out(vty, " ipv6 nd ra-interval %d%s", interval / 1000, +			VTY_NEWLINE); + +	if (zif->rtadv.AdvIntervalOption) +		vty_out(vty, " ipv6 nd adv-interval-option%s", VTY_NEWLINE); + +	if (zif->rtadv.AdvDefaultLifetime != -1) +		vty_out(vty, " ipv6 nd ra-lifetime %d%s", +			zif->rtadv.AdvDefaultLifetime, VTY_NEWLINE); + +	if (zif->rtadv.HomeAgentPreference) +		vty_out(vty, " ipv6 nd home-agent-preference %u%s", +			zif->rtadv.HomeAgentPreference, VTY_NEWLINE); + +	if (zif->rtadv.HomeAgentLifetime != -1) +		vty_out(vty, " ipv6 nd home-agent-lifetime %u%s", +			zif->rtadv.HomeAgentLifetime, VTY_NEWLINE); + +	if (zif->rtadv.AdvHomeAgentFlag) +		vty_out(vty, " ipv6 nd home-agent-config-flag%s", VTY_NEWLINE); + +	if (zif->rtadv.AdvReachableTime) +		vty_out(vty, " ipv6 nd reachable-time %d%s", +			zif->rtadv.AdvReachableTime, VTY_NEWLINE); + +	if (zif->rtadv.AdvManagedFlag) +		vty_out(vty, " ipv6 nd managed-config-flag%s", VTY_NEWLINE); + +	if (zif->rtadv.AdvOtherConfigFlag) +		vty_out(vty, " ipv6 nd other-config-flag%s", VTY_NEWLINE); + +	if (zif->rtadv.DefaultPreference != RTADV_PREF_MEDIUM) +		vty_out(vty, " ipv6 nd router-preference %s%s", +			rtadv_pref_strs[zif->rtadv.DefaultPreference], +			VTY_NEWLINE); + +	if (zif->rtadv.AdvLinkMTU) +		vty_out(vty, " ipv6 nd mtu %d%s", zif->rtadv.AdvLinkMTU, +			VTY_NEWLINE); + +	for (ALL_LIST_ELEMENTS_RO(zif->rtadv.AdvPrefixList, node, rprefix)) { +		vty_out(vty, " ipv6 nd prefix %s", +			prefix2str(&rprefix->prefix, buf, sizeof(buf))); +		if ((rprefix->AdvValidLifetime != RTADV_VALID_LIFETIME) +		    || (rprefix->AdvPreferredLifetime +			!= RTADV_PREFERRED_LIFETIME)) { +			if (rprefix->AdvValidLifetime == UINT32_MAX) +				vty_out(vty, " infinite"); +			else +				vty_out(vty, " %u", rprefix->AdvValidLifetime); +			if (rprefix->AdvPreferredLifetime == UINT32_MAX) +				vty_out(vty, " infinite"); +			else +				vty_out(vty, " %u", +					rprefix->AdvPreferredLifetime); +		} +		if (!rprefix->AdvOnLinkFlag) +			vty_out(vty, " off-link"); +		if (!rprefix->AdvAutonomousFlag) +			vty_out(vty, " no-autoconfig"); +		if (rprefix->AdvRouterAddressFlag) +			vty_out(vty, " router-address"); +		vty_out(vty, "%s", VTY_NEWLINE);  	} -      if (!rprefix->AdvOnLinkFlag) -	vty_out (vty, " off-link"); -      if (!rprefix->AdvAutonomousFlag) -	vty_out (vty, " no-autoconfig"); -      if (rprefix->AdvRouterAddressFlag) -	vty_out (vty, " router-address"); -      vty_out (vty, "%s", VTY_NEWLINE); -    }  } -static void -rtadv_event (struct zebra_ns *zns, enum rtadv_event event, int val) +static void rtadv_event(struct zebra_ns *zns, enum rtadv_event event, int val)  { -  struct rtadv *rtadv = &zns->rtadv; - -  switch (event) -    { -    case RTADV_START: -      if (! rtadv->ra_read) -       rtadv->ra_read = thread_add_read (zebrad.master, rtadv_read, zns, val); -      if (! rtadv->ra_timer) -       rtadv->ra_timer = thread_add_event (zebrad.master, rtadv_timer, -                                           zns, 0); -      break; -    case RTADV_STOP: -      if (rtadv->ra_timer) -	{ -	  thread_cancel (rtadv->ra_timer); -	  rtadv->ra_timer = NULL; +	struct rtadv *rtadv = &zns->rtadv; + +	switch (event) { +	case RTADV_START: +		if (!rtadv->ra_read) +			rtadv->ra_read = thread_add_read(zebrad.master, +							 rtadv_read, zns, val); +		if (!rtadv->ra_timer) +			rtadv->ra_timer = thread_add_event(zebrad.master, +							   rtadv_timer, zns, 0); +		break; +	case RTADV_STOP: +		if (rtadv->ra_timer) { +			thread_cancel(rtadv->ra_timer); +			rtadv->ra_timer = NULL; +		} +		if (rtadv->ra_read) { +			thread_cancel(rtadv->ra_read); +			rtadv->ra_read = NULL; +		} +		break; +	case RTADV_TIMER: +		if (!rtadv->ra_timer) +			rtadv->ra_timer = thread_add_timer( +				zebrad.master, rtadv_timer, zns, val); +		break; +	case RTADV_TIMER_MSEC: +		if (!rtadv->ra_timer) +			rtadv->ra_timer = thread_add_timer_msec( +				zebrad.master, rtadv_timer, zns, val); +		break; +	case RTADV_READ: +		if (!rtadv->ra_read) +			rtadv->ra_read = thread_add_read(zebrad.master, +							 rtadv_read, zns, val); +		break; +	default: +		break;  	} -      if (rtadv->ra_read) -	{ -	  thread_cancel (rtadv->ra_read); -	  rtadv->ra_read = NULL; -	} -      break; -    case RTADV_TIMER: -      if (! rtadv->ra_timer) -	rtadv->ra_timer = thread_add_timer (zebrad.master, rtadv_timer, zns, -	                                    val); -      break; -    case RTADV_TIMER_MSEC: -      if (! rtadv->ra_timer) -	rtadv->ra_timer = thread_add_timer_msec (zebrad.master, rtadv_timer,  -					    zns, val); -      break; -    case RTADV_READ: -      if (! rtadv->ra_read) -	rtadv->ra_read = thread_add_read (zebrad.master, rtadv_read, zns, val); -      break; -    default: -      break; -    } -  return; +	return;  } -void -rtadv_init (struct zebra_ns *zns) +void rtadv_init(struct zebra_ns *zns)  { -  zns->rtadv.sock = rtadv_make_socket (); +	zns->rtadv.sock = rtadv_make_socket();  } -void -rtadv_terminate (struct zebra_ns *zns) +void rtadv_terminate(struct zebra_ns *zns)  { -  rtadv_event (zns, RTADV_STOP, 0); -  if (zns->rtadv.sock >= 0) -    { -      close (zns->rtadv.sock); -      zns->rtadv.sock = -1; -    } - -  zns->rtadv.adv_if_count = 0; -  zns->rtadv.adv_msec_if_count = 0; +	rtadv_event(zns, RTADV_STOP, 0); +	if (zns->rtadv.sock >= 0) { +		close(zns->rtadv.sock); +		zns->rtadv.sock = -1; +	} + +	zns->rtadv.adv_if_count = 0; +	zns->rtadv.adv_msec_if_count = 0;  } -void -rtadv_cmd_init (void) +void rtadv_cmd_init(void)  { -  install_element (INTERFACE_NODE, &ipv6_nd_suppress_ra_cmd); -  install_element (INTERFACE_NODE, &no_ipv6_nd_suppress_ra_cmd); -  install_element (INTERFACE_NODE, &ipv6_nd_ra_interval_cmd); -  install_element (INTERFACE_NODE, &ipv6_nd_ra_interval_msec_cmd); -  install_element (INTERFACE_NODE, &no_ipv6_nd_ra_interval_cmd); -  install_element (INTERFACE_NODE, &ipv6_nd_ra_lifetime_cmd); -  install_element (INTERFACE_NODE, &no_ipv6_nd_ra_lifetime_cmd); -  install_element (INTERFACE_NODE, &ipv6_nd_reachable_time_cmd); -  install_element (INTERFACE_NODE, &no_ipv6_nd_reachable_time_cmd); -  install_element (INTERFACE_NODE, &ipv6_nd_managed_config_flag_cmd); -  install_element (INTERFACE_NODE, &no_ipv6_nd_managed_config_flag_cmd); -  install_element (INTERFACE_NODE, &ipv6_nd_other_config_flag_cmd); -  install_element (INTERFACE_NODE, &no_ipv6_nd_other_config_flag_cmd); -  install_element (INTERFACE_NODE, &ipv6_nd_homeagent_config_flag_cmd); -  install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_config_flag_cmd); -  install_element (INTERFACE_NODE, &ipv6_nd_homeagent_preference_cmd); -  install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_preference_cmd); -  install_element (INTERFACE_NODE, &ipv6_nd_homeagent_lifetime_cmd); -  install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_lifetime_cmd); -  install_element (INTERFACE_NODE, &ipv6_nd_adv_interval_config_option_cmd); -  install_element (INTERFACE_NODE, &no_ipv6_nd_adv_interval_config_option_cmd); -  install_element (INTERFACE_NODE, &ipv6_nd_prefix_cmd); -  install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_cmd); -  install_element (INTERFACE_NODE, &ipv6_nd_router_preference_cmd); -  install_element (INTERFACE_NODE, &no_ipv6_nd_router_preference_cmd); -  install_element (INTERFACE_NODE, &ipv6_nd_mtu_cmd); -  install_element (INTERFACE_NODE, &no_ipv6_nd_mtu_cmd); +	install_element(INTERFACE_NODE, &ipv6_nd_suppress_ra_cmd); +	install_element(INTERFACE_NODE, &no_ipv6_nd_suppress_ra_cmd); +	install_element(INTERFACE_NODE, &ipv6_nd_ra_interval_cmd); +	install_element(INTERFACE_NODE, &ipv6_nd_ra_interval_msec_cmd); +	install_element(INTERFACE_NODE, &no_ipv6_nd_ra_interval_cmd); +	install_element(INTERFACE_NODE, &ipv6_nd_ra_lifetime_cmd); +	install_element(INTERFACE_NODE, &no_ipv6_nd_ra_lifetime_cmd); +	install_element(INTERFACE_NODE, &ipv6_nd_reachable_time_cmd); +	install_element(INTERFACE_NODE, &no_ipv6_nd_reachable_time_cmd); +	install_element(INTERFACE_NODE, &ipv6_nd_managed_config_flag_cmd); +	install_element(INTERFACE_NODE, &no_ipv6_nd_managed_config_flag_cmd); +	install_element(INTERFACE_NODE, &ipv6_nd_other_config_flag_cmd); +	install_element(INTERFACE_NODE, &no_ipv6_nd_other_config_flag_cmd); +	install_element(INTERFACE_NODE, &ipv6_nd_homeagent_config_flag_cmd); +	install_element(INTERFACE_NODE, &no_ipv6_nd_homeagent_config_flag_cmd); +	install_element(INTERFACE_NODE, &ipv6_nd_homeagent_preference_cmd); +	install_element(INTERFACE_NODE, &no_ipv6_nd_homeagent_preference_cmd); +	install_element(INTERFACE_NODE, &ipv6_nd_homeagent_lifetime_cmd); +	install_element(INTERFACE_NODE, &no_ipv6_nd_homeagent_lifetime_cmd); +	install_element(INTERFACE_NODE, +			&ipv6_nd_adv_interval_config_option_cmd); +	install_element(INTERFACE_NODE, +			&no_ipv6_nd_adv_interval_config_option_cmd); +	install_element(INTERFACE_NODE, &ipv6_nd_prefix_cmd); +	install_element(INTERFACE_NODE, &no_ipv6_nd_prefix_cmd); +	install_element(INTERFACE_NODE, &ipv6_nd_router_preference_cmd); +	install_element(INTERFACE_NODE, &no_ipv6_nd_router_preference_cmd); +	install_element(INTERFACE_NODE, &ipv6_nd_mtu_cmd); +	install_element(INTERFACE_NODE, &no_ipv6_nd_mtu_cmd);  } -static int -if_join_all_router (int sock, struct interface *ifp) +static int if_join_all_router(int sock, struct interface *ifp)  { -  int ret; +	int ret; -  struct ipv6_mreq mreq; +	struct ipv6_mreq mreq; -  memset (&mreq, 0, sizeof (struct ipv6_mreq)); -  inet_pton (AF_INET6, ALLROUTER, &mreq.ipv6mr_multiaddr); -  mreq.ipv6mr_interface = ifp->ifindex; +	memset(&mreq, 0, sizeof(struct ipv6_mreq)); +	inet_pton(AF_INET6, ALLROUTER, &mreq.ipv6mr_multiaddr); +	mreq.ipv6mr_interface = ifp->ifindex; -  ret = setsockopt (sock, IPPROTO_IPV6, IPV6_JOIN_GROUP,  -		    (char *) &mreq, sizeof mreq); -  if (ret < 0) -    zlog_warn ("%s(%u): Failed to join group, socket %u error %s", -               ifp->name, ifp->ifindex, sock, safe_strerror (errno)); +	ret = setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char *)&mreq, +			 sizeof mreq); +	if (ret < 0) +		zlog_warn("%s(%u): Failed to join group, socket %u error %s", +			  ifp->name, ifp->ifindex, sock, safe_strerror(errno)); -  if (IS_ZEBRA_DEBUG_EVENT) -    zlog_debug ("%s(%u): Join All-Routers multicast group, socket %u", -                ifp->name, ifp->ifindex, sock); +	if (IS_ZEBRA_DEBUG_EVENT) +		zlog_debug( +			"%s(%u): Join All-Routers multicast group, socket %u", +			ifp->name, ifp->ifindex, sock); -  return 0; +	return 0;  } -static int -if_leave_all_router (int sock, struct interface *ifp) +static int if_leave_all_router(int sock, struct interface *ifp)  { -  int ret; +	int ret; -  struct ipv6_mreq mreq; +	struct ipv6_mreq mreq; -  memset (&mreq, 0, sizeof (struct ipv6_mreq)); -  inet_pton (AF_INET6, ALLROUTER, &mreq.ipv6mr_multiaddr); -  mreq.ipv6mr_interface = ifp->ifindex; +	memset(&mreq, 0, sizeof(struct ipv6_mreq)); +	inet_pton(AF_INET6, ALLROUTER, &mreq.ipv6mr_multiaddr); +	mreq.ipv6mr_interface = ifp->ifindex; -  ret = setsockopt (sock, IPPROTO_IPV6, IPV6_LEAVE_GROUP,  -		    (char *) &mreq, sizeof mreq); -  if (ret < 0) -    zlog_warn ("%s(%u): Failed to leave group, socket %u error %s", -               ifp->name, ifp->ifindex, sock,safe_strerror (errno)); +	ret = setsockopt(sock, IPPROTO_IPV6, IPV6_LEAVE_GROUP, (char *)&mreq, +			 sizeof mreq); +	if (ret < 0) +		zlog_warn("%s(%u): Failed to leave group, socket %u error %s", +			  ifp->name, ifp->ifindex, sock, safe_strerror(errno)); -  if (IS_ZEBRA_DEBUG_EVENT) -    zlog_debug ("%s(%u): Leave All-Routers multicast group, socket %u", -                ifp->name, ifp->ifindex, sock); +	if (IS_ZEBRA_DEBUG_EVENT) +		zlog_debug( +			"%s(%u): Leave All-Routers multicast group, socket %u", +			ifp->name, ifp->ifindex, sock); -  return 0; +	return 0;  }  #else -void -rtadv_init (struct zebra_ns *zns) +void rtadv_init(struct zebra_ns *zns)  { -  /* Empty.*/; +	/* Empty.*/;  } -void -rtadv_terminate (struct zebra_ns *zns) +void rtadv_terminate(struct zebra_ns *zns)  { -  /* Empty.*/; +	/* Empty.*/;  } -void -rtadv_cmd_init (void) +void rtadv_cmd_init(void)  { -  /* Empty.*/; +	/* Empty.*/;  }  #endif /* HAVE_RTADV */ diff --git a/zebra/rtadv.h b/zebra/rtadv.h index e4c2c6b36d..e7fbd77b0d 100644 --- a/zebra/rtadv.h +++ b/zebra/rtadv.h @@ -17,7 +17,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #ifndef _ZEBRA_RTADV_H @@ -27,38 +27,36 @@  #include "zebra/interface.h"  /* NB: RTADV is defined in zebra/interface.h above */ -#if defined (HAVE_RTADV) +#if defined(HAVE_RTADV)  /* Router advertisement prefix. */ -struct rtadv_prefix -{ -  /* Prefix to be advertised. */ -  struct prefix_ipv6 prefix; -   -  /* The value to be placed in the Valid Lifetime in the Prefix */ -  u_int32_t AdvValidLifetime; +struct rtadv_prefix { +	/* Prefix to be advertised. */ +	struct prefix_ipv6 prefix; + +	/* The value to be placed in the Valid Lifetime in the Prefix */ +	u_int32_t AdvValidLifetime;  #define RTADV_VALID_LIFETIME 2592000 -  /* The value to be placed in the on-link flag */ -  int AdvOnLinkFlag; +	/* The value to be placed in the on-link flag */ +	int AdvOnLinkFlag; -  /* The value to be placed in the Preferred Lifetime in the Prefix -     Information option, in seconds.*/ -  u_int32_t AdvPreferredLifetime; +	/* The value to be placed in the Preferred Lifetime in the Prefix +	   Information option, in seconds.*/ +	u_int32_t AdvPreferredLifetime;  #define RTADV_PREFERRED_LIFETIME 604800 -  /* The value to be placed in the Autonomous Flag. */ -  int AdvAutonomousFlag; +	/* The value to be placed in the Autonomous Flag. */ +	int AdvAutonomousFlag; -  /* The value to be placed in the Router Address Flag [RFC6275 7.2]. */ -  int AdvRouterAddressFlag; +	/* The value to be placed in the Router Address Flag [RFC6275 7.2]. */ +	int AdvRouterAddressFlag;  #ifndef ND_OPT_PI_FLAG_RADDR  #define ND_OPT_PI_FLAG_RADDR         0x20  #endif -  }; -extern void rtadv_config_write (struct vty *, struct interface *); +extern void rtadv_config_write(struct vty *, struct interface *);  /* RFC4584 Extension to Sockets API for Mobile IPv6 */ @@ -70,11 +68,11 @@ extern void rtadv_config_write (struct vty *, struct interface *);  #endif  #ifndef HAVE_STRUCT_ND_OPT_ADV_INTERVAL -struct nd_opt_adv_interval {   /* Advertisement interval option */ -        uint8_t        nd_opt_ai_type; -        uint8_t        nd_opt_ai_len; -        uint16_t       nd_opt_ai_reserved; -        uint32_t       nd_opt_ai_interval; +struct nd_opt_adv_interval { /* Advertisement interval option */ +	uint8_t nd_opt_ai_type; +	uint8_t nd_opt_ai_len; +	uint16_t nd_opt_ai_reserved; +	uint32_t nd_opt_ai_interval;  } __attribute__((__packed__));  #else  #ifndef HAVE_STRUCT_ND_OPT_ADV_INTERVAL_ND_OPT_AI_TYPE @@ -87,12 +85,12 @@ struct nd_opt_adv_interval {   /* Advertisement interval option */  #endif  #ifndef HAVE_STRUCT_ND_OPT_HOMEAGENT_INFO -struct nd_opt_homeagent_info {  /* Home Agent info */ -        u_int8_t        nd_opt_hai_type; -        u_int8_t        nd_opt_hai_len; -        u_int16_t       nd_opt_hai_reserved; -        u_int16_t       nd_opt_hai_preference; -        u_int16_t       nd_opt_hai_lifetime; +struct nd_opt_homeagent_info { /* Home Agent info */ +	u_int8_t nd_opt_hai_type; +	u_int8_t nd_opt_hai_len; +	u_int16_t nd_opt_hai_reserved; +	u_int16_t nd_opt_hai_preference; +	u_int16_t nd_opt_hai_lifetime;  } __attribute__((__packed__));  #endif @@ -101,14 +99,15 @@ extern const char *rtadv_pref_strs[];  #endif /* HAVE_RTADV */  typedef enum { -  RA_ENABLE = 0, -  RA_SUPPRESS, +	RA_ENABLE = 0, +	RA_SUPPRESS,  } ipv6_nd_suppress_ra_status; -extern void rtadv_init (struct zebra_ns *); -extern void rtadv_terminate (struct zebra_ns *); -extern void rtadv_cmd_init (void); -extern void zebra_interface_radv_set (struct zserv *client, int sock, u_short length, -                          struct zebra_vrf *zvrf, int enable); +extern void rtadv_init(struct zebra_ns *); +extern void rtadv_terminate(struct zebra_ns *); +extern void rtadv_cmd_init(void); +extern void zebra_interface_radv_set(struct zserv *client, int sock, +				     u_short length, struct zebra_vrf *zvrf, +				     int enable);  #endif /* _ZEBRA_RTADV_H */ diff --git a/zebra/rtadv_null.c b/zebra/rtadv_null.c index ee6eda6bdd..7d1bcaf4a6 100644 --- a/zebra/rtadv_null.c +++ b/zebra/rtadv_null.c @@ -24,12 +24,18 @@  #include <rtadv.h>  #include <zebra_ns.h> -void zebra_interface_radv_set (struct zserv *client, int sock, u_short length, -                          struct zebra_vrf *zvrf, int enable) -{ return; } +void zebra_interface_radv_set(struct zserv *client, int sock, u_short length, +			      struct zebra_vrf *zvrf, int enable) +{ +	return; +} -void rtadv_init (struct zebra_ns *zns) -{ return; } +void rtadv_init(struct zebra_ns *zns) +{ +	return; +} -void rtadv_terminate (struct zebra_ns *zns) -{ return; } +void rtadv_terminate(struct zebra_ns *zns) +{ +	return; +} diff --git a/zebra/rtread_getmsg.c b/zebra/rtread_getmsg.c index 4d491f3200..703dd8d580 100644 --- a/zebra/rtread_getmsg.c +++ b/zebra/rtread_getmsg.c @@ -17,7 +17,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #include <zebra.h> @@ -51,8 +51,7 @@  #define IRE_HOST_REDIRECT       0x0200  /* Host route entry from redirects */  #endif /* IRE_HOST_REDIRECT */  #ifndef IRE_CACHETABLE -#define IRE_CACHETABLE          (IRE_CACHE | IRE_BROADCAST | IRE_LOCAL | \ -                                 IRE_LOOPBACK) +#define IRE_CACHETABLE (IRE_CACHE | IRE_BROADCAST | IRE_LOCAL | IRE_LOOPBACK)  #endif /* IRE_CACHETABLE */  #undef IPOPT_EOL  #undef IPOPT_NOP @@ -72,123 +71,124 @@  #define RT_BUFSIZ		8192 -static void  -handle_route_entry (mib2_ipRouteEntry_t *routeEntry) +static void handle_route_entry(mib2_ipRouteEntry_t *routeEntry)  { -  struct prefix	prefix; -  struct in_addr		tmpaddr, gateway; -  union g_addr *ggateway; -  u_char			zebra_flags = 0; +	struct prefix prefix; +	struct in_addr tmpaddr, gateway; +	union g_addr *ggateway; +	u_char zebra_flags = 0; -  if (routeEntry->ipRouteInfo.re_ire_type & IRE_CACHETABLE) -    return; +	if (routeEntry->ipRouteInfo.re_ire_type & IRE_CACHETABLE) +		return; -  if (routeEntry->ipRouteInfo.re_ire_type & IRE_HOST_REDIRECT) -    zebra_flags |= ZEBRA_FLAG_SELFROUTE; +	if (routeEntry->ipRouteInfo.re_ire_type & IRE_HOST_REDIRECT) +		zebra_flags |= ZEBRA_FLAG_SELFROUTE; -  prefix.family = AF_INET; +	prefix.family = AF_INET; -  tmpaddr.s_addr = routeEntry->ipRouteDest; -  prefix.u.prefix4 = tmpaddr; +	tmpaddr.s_addr = routeEntry->ipRouteDest; +	prefix.u.prefix4 = tmpaddr; -  tmpaddr.s_addr = routeEntry->ipRouteMask; -  prefix.prefixlen = ip_masklen (tmpaddr); +	tmpaddr.s_addr = routeEntry->ipRouteMask; +	prefix.prefixlen = ip_masklen(tmpaddr); -  gateway.s_addr = routeEntry->ipRouteNextHop; -  ggateway = (union g_addr *)&gateway; +	gateway.s_addr = routeEntry->ipRouteNextHop; +	ggateway = (union g_addr *)&gateway; -  rib_add (AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, -	   zebra_flags, &prefix, NULL, ggateway, NULL, 0, 0, 0, 0, 0); +	rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, +		zebra_flags, &prefix, NULL, ggateway, NULL, 0, 0, 0, 0, 0);  } -void -route_read (struct zebra_ns *zns) +void route_read(struct zebra_ns *zns)  { -	char 			storage[RT_BUFSIZ]; +	char storage[RT_BUFSIZ]; -	struct T_optmgmt_req	*TLIreq = (struct T_optmgmt_req *) storage; -	struct T_optmgmt_ack	*TLIack = (struct T_optmgmt_ack *) storage; -	struct T_error_ack	*TLIerr = (struct T_error_ack *) storage; +	struct T_optmgmt_req *TLIreq = (struct T_optmgmt_req *)storage; +	struct T_optmgmt_ack *TLIack = (struct T_optmgmt_ack *)storage; +	struct T_error_ack *TLIerr = (struct T_error_ack *)storage; -	struct opthdr		*MIB2hdr; +	struct opthdr *MIB2hdr; -	mib2_ipRouteEntry_t	*routeEntry, *lastRouteEntry; +	mib2_ipRouteEntry_t *routeEntry, *lastRouteEntry; -	struct strbuf		msgdata; -	int			flags, dev, retval, process; +	struct strbuf msgdata; +	int flags, dev, retval, process; -	if ((dev = open (_PATH_GETMSG_ROUTE, O_RDWR)) == -1) { -		zlog_warn ("can't open %s: %s", _PATH_GETMSG_ROUTE, -			safe_strerror (errno)); +	if ((dev = open(_PATH_GETMSG_ROUTE, O_RDWR)) == -1) { +		zlog_warn("can't open %s: %s", _PATH_GETMSG_ROUTE, +			  safe_strerror(errno));  		return;  	}  	TLIreq->PRIM_type = T_OPTMGMT_REQ; -	TLIreq->OPT_offset = sizeof (struct T_optmgmt_req); -	TLIreq->OPT_length = sizeof (struct opthdr); +	TLIreq->OPT_offset = sizeof(struct T_optmgmt_req); +	TLIreq->OPT_length = sizeof(struct opthdr);  	TLIreq->MGMT_flags = T_CURRENT; -	MIB2hdr = (struct opthdr *) &TLIreq[1]; +	MIB2hdr = (struct opthdr *)&TLIreq[1];  	MIB2hdr->level = MIB2_IP;  	MIB2hdr->name = 0;  	MIB2hdr->len = 0; -	 +  	msgdata.buf = storage; -	msgdata.len = sizeof (struct T_optmgmt_req) + sizeof (struct opthdr); +	msgdata.len = sizeof(struct T_optmgmt_req) + sizeof(struct opthdr);  	flags = 0; -	if (putmsg (dev, &msgdata, NULL, flags) == -1) { -		zlog_warn ("putmsg failed: %s", safe_strerror (errno)); +	if (putmsg(dev, &msgdata, NULL, flags) == -1) { +		zlog_warn("putmsg failed: %s", safe_strerror(errno));  		goto exit;  	} -	MIB2hdr = (struct opthdr *) &TLIack[1]; -	msgdata.maxlen = sizeof (storage); +	MIB2hdr = (struct opthdr *)&TLIack[1]; +	msgdata.maxlen = sizeof(storage);  	while (1) {  		flags = 0; -		retval = getmsg (dev, &msgdata, NULL, &flags); +		retval = getmsg(dev, &msgdata, NULL, &flags);  		if (retval == -1) { -			zlog_warn ("getmsg(ctl) failed: %s", safe_strerror (errno)); +			zlog_warn("getmsg(ctl) failed: %s", +				  safe_strerror(errno));  			goto exit;  		}  		/* This is normal loop termination */ -		if (retval == 0 && -			(size_t)msgdata.len >= sizeof (struct T_optmgmt_ack) && -			TLIack->PRIM_type == T_OPTMGMT_ACK && -			TLIack->MGMT_flags == T_SUCCESS && -			MIB2hdr->len == 0) +		if (retval == 0 +		    && (size_t)msgdata.len >= sizeof(struct T_optmgmt_ack) +		    && TLIack->PRIM_type == T_OPTMGMT_ACK +		    && TLIack->MGMT_flags == T_SUCCESS && MIB2hdr->len == 0)  			break; -		if ((size_t)msgdata.len >= sizeof (struct T_error_ack) && -			TLIerr->PRIM_type == T_ERROR_ACK) { -			zlog_warn ("getmsg(ctl) returned T_ERROR_ACK: %s", -				safe_strerror ((TLIerr->TLI_error == TSYSERR) -				? TLIerr->UNIX_error : EPROTO)); +		if ((size_t)msgdata.len >= sizeof(struct T_error_ack) +		    && TLIerr->PRIM_type == T_ERROR_ACK) { +			zlog_warn("getmsg(ctl) returned T_ERROR_ACK: %s", +				  safe_strerror((TLIerr->TLI_error == TSYSERR) +							? TLIerr->UNIX_error +							: EPROTO));  			break;  		}  		/* should dump more debugging info to the log statement,  		   like what GateD does in this instance, but not  		   critical yet. */ -		if (retval != MOREDATA || -			(size_t)msgdata.len < sizeof (struct T_optmgmt_ack) || -			TLIack->PRIM_type != T_OPTMGMT_ACK || -			TLIack->MGMT_flags != T_SUCCESS) { +		if (retval != MOREDATA +		    || (size_t)msgdata.len < sizeof(struct T_optmgmt_ack) +		    || TLIack->PRIM_type != T_OPTMGMT_ACK +		    || TLIack->MGMT_flags != T_SUCCESS) {  			errno = ENOMSG; -			zlog_warn ("getmsg(ctl) returned bizarreness"); +			zlog_warn("getmsg(ctl) returned bizarreness");  			break;  		}  		/* MIB2_IP_21 is the the pseudo-MIB2 ipRouteTable  		   entry, see <inet/mib2.h>. "This isn't the MIB data  		   you're looking for." */ -		process = (MIB2hdr->level == MIB2_IP && -			MIB2hdr->name == MIB2_IP_21) ? 1 : 0; +		process = (MIB2hdr->level == MIB2_IP +			   && MIB2hdr->name == MIB2_IP_21) +				  ? 1 +				  : 0;  		/* getmsg writes the data buffer out completely, not  		   to the closest smaller multiple. Unless reassembling @@ -196,45 +196,48 @@ route_read (struct zebra_ns *zns)  		   of a good time, set maxlen to the closest smaller  		   multiple of the size of the datastructure you're  		   retrieving. */ -		msgdata.maxlen = sizeof (storage) - (sizeof (storage) -			% sizeof (mib2_ipRouteEntry_t)); +		msgdata.maxlen = +			sizeof(storage) +			- (sizeof(storage) % sizeof(mib2_ipRouteEntry_t));  		msgdata.len = 0;  		flags = 0;  		do { -			retval = getmsg (dev, NULL, &msgdata, &flags); +			retval = getmsg(dev, NULL, &msgdata, &flags);  			if (retval == -1) { -				zlog_warn ("getmsg(data) failed: %s", -					safe_strerror (errno)); +				zlog_warn("getmsg(data) failed: %s", +					  safe_strerror(errno));  				goto exit;  			}  			if (!(retval == 0 || retval == MOREDATA)) { -				zlog_warn ("getmsg(data) returned %d", retval); +				zlog_warn("getmsg(data) returned %d", retval);  				goto exit;  			}  			if (process) { -				if (msgdata.len % -					sizeof (mib2_ipRouteEntry_t) != 0) { -					zlog_warn ("getmsg(data) returned " -"msgdata.len = %d (%% sizeof (mib2_ipRouteEntry_t) != 0)", msgdata.len); +				if (msgdata.len % sizeof(mib2_ipRouteEntry_t) +				    != 0) { +					zlog_warn( +						"getmsg(data) returned " +						"msgdata.len = %d (%% sizeof (mib2_ipRouteEntry_t) != 0)", +						msgdata.len);  					goto exit;  				} -				routeEntry = (mib2_ipRouteEntry_t *) -					msgdata.buf; -				lastRouteEntry = (mib2_ipRouteEntry_t *) -					(msgdata.buf + msgdata.len); +				routeEntry = (mib2_ipRouteEntry_t *)msgdata.buf; +				lastRouteEntry = +					(mib2_ipRouteEntry_t *)(msgdata.buf +								+ msgdata.len);  				do { -					handle_route_entry (routeEntry); +					handle_route_entry(routeEntry);  				} while (++routeEntry < lastRouteEntry);  			}  		} while (retval == MOREDATA);  	}  exit: -	close (dev); +	close(dev);  } diff --git a/zebra/rtread_netlink.c b/zebra/rtread_netlink.c index 1d41861bbd..c273e15a78 100644 --- a/zebra/rtread_netlink.c +++ b/zebra/rtread_netlink.c @@ -17,7 +17,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #include <zebra.h> @@ -26,7 +26,7 @@  #include "zebra/zserv.h"  #include "zebra/rt_netlink.h" -void route_read (struct zebra_ns *zns) +void route_read(struct zebra_ns *zns)  { -  netlink_route_read (zns); +	netlink_route_read(zns);  } diff --git a/zebra/rtread_sysctl.c b/zebra/rtread_sysctl.c index b68e1cb74a..32b6f74a1f 100644 --- a/zebra/rtread_sysctl.c +++ b/zebra/rtread_sysctl.c @@ -17,7 +17,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #include <zebra.h> @@ -32,55 +32,44 @@  #include "zebra/kernel_socket.h"  /* Kernel routing table read up by sysctl function. */ -void -route_read (struct zebra_ns *zns) +void route_read(struct zebra_ns *zns)  { -  caddr_t buf, end, ref; -  size_t bufsiz; -  struct rt_msghdr *rtm; -   +	caddr_t buf, end, ref; +	size_t bufsiz; +	struct rt_msghdr *rtm; +  #define MIBSIZ 6 -  int mib[MIBSIZ] =  -  { -    CTL_NET, -    PF_ROUTE, -    0, -    0, -    NET_RT_DUMP, -    0 -  }; +	int mib[MIBSIZ] = {CTL_NET, PF_ROUTE, 0, 0, NET_RT_DUMP, 0}; + +	if (zns->ns_id != NS_DEFAULT) +		return; -  if (zns->ns_id != NS_DEFAULT) -    return; +	/* Get buffer size. */ +	if (sysctl(mib, MIBSIZ, NULL, &bufsiz, NULL, 0) < 0) { +		zlog_warn("sysctl fail: %s", safe_strerror(errno)); +		return; +	} -  /* Get buffer size. */ -  if (sysctl (mib, MIBSIZ, NULL, &bufsiz, NULL, 0) < 0)  -    { -      zlog_warn ("sysctl fail: %s", safe_strerror (errno)); -      return; -    } +	/* Allocate buffer. */ +	ref = buf = XMALLOC(MTYPE_TMP, bufsiz); -  /* Allocate buffer. */ -  ref = buf = XMALLOC (MTYPE_TMP, bufsiz); -   -  /* Read routing table information by calling sysctl(). */ -  if (sysctl (mib, MIBSIZ, buf, &bufsiz, NULL, 0) < 0)  -    { -      zlog_warn ("sysctl() fail by %s", safe_strerror (errno)); -      XFREE(MTYPE_TMP, ref); -      return; -    } +	/* Read routing table information by calling sysctl(). */ +	if (sysctl(mib, MIBSIZ, buf, &bufsiz, NULL, 0) < 0) { +		zlog_warn("sysctl() fail by %s", safe_strerror(errno)); +		XFREE(MTYPE_TMP, ref); +		return; +	} -  for (end = buf + bufsiz; buf < end; buf += rtm->rtm_msglen)  -    { -      rtm = (struct rt_msghdr *) buf; -      /* We must set RTF_DONE here, so rtm_read() doesn't ignore the message. */ -      SET_FLAG (rtm->rtm_flags, RTF_DONE); -      rtm_read (rtm); -    } +	for (end = buf + bufsiz; buf < end; buf += rtm->rtm_msglen) { +		rtm = (struct rt_msghdr *)buf; +		/* We must set RTF_DONE here, so rtm_read() doesn't ignore the +		 * message. */ +		SET_FLAG(rtm->rtm_flags, RTF_DONE); +		rtm_read(rtm); +	} -  /* Free buffer. */ -  XFREE (MTYPE_TMP, ref); +	/* Free buffer. */ +	XFREE(MTYPE_TMP, ref); -  return; +	return;  } diff --git a/zebra/test_main.c b/zebra/test_main.c index f3ef3df96a..69fc5fd404 100644 --- a/zebra/test_main.c +++ b/zebra/test_main.c @@ -14,7 +14,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #include <zebra.h> @@ -42,9 +42,8 @@  #include "zebra/interface.h"  /* Zebra instance */ -struct zebra_t zebrad = -{ -  .rtm_table_default = 0, +struct zebra_t zebrad = { +	.rtm_table_default = 0,  };  /* process id. */ @@ -60,25 +59,19 @@ extern int rib_process_hold_time;  struct thread_master *master;  /* Command line options. */ -struct option longopts[] =  -{ -  { "batch",        no_argument,       NULL, 'b'}, -  { "daemon",       no_argument,       NULL, 'd'}, -  { "allow_delete", no_argument,       NULL, 'a'}, -  { "config_file",  required_argument, NULL, 'f'}, -  { "help",         no_argument,       NULL, 'h'}, -  { "vty_addr",     required_argument, NULL, 'A'}, -  { "vty_port",     required_argument, NULL, 'P'}, -  { "version",      no_argument,       NULL, 'v'}, -  { "rib_hold",     required_argument, NULL, 'r'}, -  { 0 } -}; - -zebra_capabilities_t _caps_p [] =  -{ -  ZCAP_NET_ADMIN, -  ZCAP_SYS_ADMIN, -  ZCAP_NET_RAW, +struct option longopts[] = {{"batch", no_argument, NULL, 'b'}, +			    {"daemon", no_argument, NULL, 'd'}, +			    {"allow_delete", no_argument, NULL, 'a'}, +			    {"config_file", required_argument, NULL, 'f'}, +			    {"help", no_argument, NULL, 'h'}, +			    {"vty_addr", required_argument, NULL, 'A'}, +			    {"vty_port", required_argument, NULL, 'P'}, +			    {"version", no_argument, NULL, 'v'}, +			    {"rib_hold", required_argument, NULL, 'r'}, +			    {0}}; + +zebra_capabilities_t _caps_p[] = { +	ZCAP_NET_ADMIN, ZCAP_SYS_ADMIN, ZCAP_NET_RAW,  };  /* Default configuration file path. */ @@ -88,30 +81,30 @@ char config_default[] = SYSCONFDIR DEFAULT_CONFIG_FILE;  const char *pid_file = "testzebra.pid";  /* Help information display. */ -static void -usage (char *progname, int status) +static void usage(char *progname, int status)  { -  if (status != 0) -    fprintf (stderr, "Try `%s --help' for more information.\n", progname); -  else -    {     -      printf ("Usage : %s [OPTION...]\n\n"\ -	      "Daemon which manages kernel routing table management and "\ -	      "redistribution between different routing protocols.\n\n"\ -	      "-b, --batch        Runs in batch mode\n"\ -	      "-d, --daemon       Runs in daemon mode\n"\ -	      "-a, --allow_delete Allow other processes to delete zebra routes\n" \ -	      "-f, --config_file  Set configuration file name\n"\ -	      "-A, --vty_addr     Set vty's bind address\n"\ -	      "-P, --vty_port     Set vty's port number\n"\ -	      "-r, --rib_hold	  Set rib-queue hold time\n"\ -              "-v, --version      Print program version\n"\ -	      "-h, --help         Display this help and exit\n"\ -	      "\n"\ -	      "Report bugs to %s\n", progname, FRR_BUG_ADDRESS); -    } - -  exit (status); +	if (status != 0) +		fprintf(stderr, "Try `%s --help' for more information.\n", +			progname); +	else { +		printf("Usage : %s [OPTION...]\n\n" +		       "Daemon which manages kernel routing table management and " +		       "redistribution between different routing protocols.\n\n" +		       "-b, --batch        Runs in batch mode\n" +		       "-d, --daemon       Runs in daemon mode\n" +		       "-a, --allow_delete Allow other processes to delete zebra routes\n" +		       "-f, --config_file  Set configuration file name\n" +		       "-A, --vty_addr     Set vty's bind address\n" +		       "-P, --vty_port     Set vty's port number\n" +		       "-r, --rib_hold	  Set rib-queue hold time\n" +		       "-v, --version      Print program version\n" +		       "-h, --help         Display this help and exit\n" +		       "\n" +		       "Report bugs to %s\n", +		       progname, FRR_BUG_ADDRESS); +	} + +	exit(status);  }  static ifindex_t test_ifindex = 0; @@ -124,217 +117,207 @@ DEFUN (test_interface_state,         "up\n"         "down\n")  { -  int idx_up_down = 1; -  VTY_DECLVAR_CONTEXT (interface, ifp); -   -  if (ifp->ifindex == IFINDEX_INTERNAL) -    { -      ifp->ifindex = ++test_ifindex; -      ifp->mtu = 1500; -      ifp->flags = IFF_BROADCAST|IFF_MULTICAST; -    } -   -  switch (argv[idx_up_down]->arg[0]) -    { -      case 'u': -        SET_FLAG (ifp->flags, IFF_UP); -        if_add_update (ifp); -        printf ("up\n"); -        break; -      case 'd': -        UNSET_FLAG (ifp->flags, IFF_UP); -        if_delete_update (ifp); -        printf ("down\n"); -        break; -      default: -        return CMD_WARNING; -    } -  return CMD_SUCCESS; +	int idx_up_down = 1; +	VTY_DECLVAR_CONTEXT(interface, ifp); + +	if (ifp->ifindex == IFINDEX_INTERNAL) { +		ifp->ifindex = ++test_ifindex; +		ifp->mtu = 1500; +		ifp->flags = IFF_BROADCAST | IFF_MULTICAST; +	} + +	switch (argv[idx_up_down]->arg[0]) { +	case 'u': +		SET_FLAG(ifp->flags, IFF_UP); +		if_add_update(ifp); +		printf("up\n"); +		break; +	case 'd': +		UNSET_FLAG(ifp->flags, IFF_UP); +		if_delete_update(ifp); +		printf("down\n"); +		break; +	default: +		return CMD_WARNING; +	} +	return CMD_SUCCESS;  } -static void -test_cmd_init (void) +static void test_cmd_init(void)  { -  install_element (INTERFACE_NODE, &test_interface_state_cmd); +	install_element(INTERFACE_NODE, &test_interface_state_cmd);  }  /* SIGHUP handler. */ -static void  -sighup (void) +static void sighup(void)  { -  zlog_info ("SIGHUP received"); +	zlog_info("SIGHUP received"); -  /* Reload of config file. */ -  ; +	/* Reload of config file. */ +	;  }  /* SIGINT handler. */ -static void -sigint (void) +static void sigint(void)  { -  zlog_notice ("Terminating on signal"); +	zlog_notice("Terminating on signal"); -  exit (0); +	exit(0);  }  /* SIGUSR1 handler. */ -static void -sigusr1 (void) +static void sigusr1(void)  { -  zlog_rotate(); +	zlog_rotate();  } -struct quagga_signal_t zebra_signals[] = -{ -  {  -    .signal = SIGHUP,  -    .handler = &sighup, -  }, -  { -    .signal = SIGUSR1, -    .handler = &sigusr1, -  }, -  { -    .signal = SIGINT, -    .handler = &sigint, -  }, -  { -    .signal = SIGTERM, -    .handler = &sigint, -  }, +struct quagga_signal_t zebra_signals[] = { +	{ +		.signal = SIGHUP, +		.handler = &sighup, +	}, +	{ +		.signal = SIGUSR1, +		.handler = &sigusr1, +	}, +	{ +		.signal = SIGINT, +		.handler = &sigint, +	}, +	{ +		.signal = SIGTERM, +		.handler = &sigint, +	},  };  /* Main startup routine. */ -int -main (int argc, char **argv) +int main(int argc, char **argv)  { -  char *p; -  char *vty_addr = NULL; -  int vty_port = 0; -  int batch_mode = 0; -  int daemon_mode = 0; -  char *config_file = NULL; -  char *progname; -  struct thread thread; +	char *p; +	char *vty_addr = NULL; +	int vty_port = 0; +	int batch_mode = 0; +	int daemon_mode = 0; +	char *config_file = NULL; +	char *progname; +	struct thread thread; + +	/* Set umask before anything for security */ +	umask(0027); + +	/* preserve my name */ +	progname = ((p = strrchr(argv[0], '/')) ? ++p : argv[0]); + +	openzlog(progname, "ZEBRA", 0, LOG_CONS | LOG_NDELAY | LOG_PID, +		 LOG_DAEMON); + +	while (1) { +		int opt; + +		opt = getopt_long(argc, argv, "bdaf:hA:P:r:v", longopts, 0); + +		if (opt == EOF) +			break; + +		switch (opt) { +		case 0: +			break; +		case 'b': +			batch_mode = 1; +		case 'd': +			daemon_mode = 1; +			break; +		case 'a': +			allow_delete = 1; +			break; +		case 'f': +			config_file = optarg; +			break; +		case 'A': +			vty_addr = optarg; +			break; +		case 'P': +			/* Deal with atoi() returning 0 on failure, and zebra +			   not +			   listening on zebra port... */ +			if (strcmp(optarg, "0") == 0) { +				vty_port = 0; +				break; +			} +			vty_port = atoi(optarg); +			break; +		case 'r': +			rib_process_hold_time = atoi(optarg); +			break; +		case 'v': +			print_version(progname); +			exit(0); +			break; +		case 'h': +			usage(progname, 0); +			break; +		default: +			usage(progname, 1); +			break; +		} +	} -  /* Set umask before anything for security */ -  umask (0027); +	/* port and conf file mandatory */ +	if (!vty_port || !config_file) { +		fprintf(stderr, +			"Error: --vty_port and --config_file arguments" +			" are both required\n"); +		usage(progname, 1); +	} -  /* preserve my name */ -  progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]); +	/* Make master thread emulator. */ +	zebrad.master = thread_master_create(); + +	/* Vty related initialize. */ +	signal_init(zebrad.master, array_size(zebra_signals), zebra_signals); +	cmd_init(1); +	vty_config_lockless(); +	vty_init(zebrad.master); +	memory_init(); +	zebra_debug_init(); +	zebra_if_init(); +	test_cmd_init(); + +	/* Zebra related initialize. */ +	rib_init(); +	access_list_init(); + +	/* Make kernel routing socket. */ +	zebra_vrf_init(); +	zebra_vty_init(); + +	/* Configuration file read*/ +	vty_read_config(config_file, config_default); + +	/* Clean up rib. */ +	rib_weed_tables(); + +	/* Exit when zebra is working in batch mode. */ +	if (batch_mode) +		exit(0); + +	/* Daemonize. */ +	if (daemon_mode && daemon(0, 0) < 0) { +		perror("daemon start failed"); +		exit(1); +	} -  openzlog(progname, "ZEBRA", 0, LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON); +	/* Needed for BSD routing socket. */ +	pid = getpid(); -  while (1)  -    { -      int opt; -   -      opt = getopt_long (argc, argv, "bdaf:hA:P:r:v", longopts, 0); +	/* Make vty server socket. */ +	vty_serv_sock(vty_addr, vty_port, "/tmp/test_zebra"); -      if (opt == EOF) -	break; +	/* Print banner. */ +	zlog_notice("Zebra %s starting: vty@%d", FRR_VERSION, vty_port); -      switch (opt)  -	{ -	case 0: -	  break; -	case 'b': -	  batch_mode = 1; -	case 'd': -	  daemon_mode = 1; -	  break; -	case 'a': -	  allow_delete =1; -	  break; -	case 'f': -	  config_file = optarg; -	  break; -	case 'A': -	  vty_addr = optarg; -	  break; -	case 'P': -	  /* Deal with atoi() returning 0 on failure, and zebra not -	     listening on zebra port... */ -	  if (strcmp(optarg, "0") == 0)  -	    { -	      vty_port = 0; -	      break; -	    }  -	  vty_port = atoi (optarg); -	  break; -	case 'r': -	  rib_process_hold_time = atoi(optarg); -	  break; -	case 'v': -	  print_version (progname); -	  exit (0); -	  break; -	case 'h': -	  usage (progname, 0); -	  break; -	default: -	  usage (progname, 1); -	  break; -	} -    } -   -  /* port and conf file mandatory */ -  if (!vty_port || !config_file) -    { -      fprintf (stderr, "Error: --vty_port and --config_file arguments" -                       " are both required\n"); -      usage (progname, 1); -    } -   -  /* Make master thread emulator. */ -  zebrad.master = thread_master_create (); - -  /* Vty related initialize. */ -  signal_init (zebrad.master, array_size(zebra_signals), zebra_signals); -  cmd_init (1); -  vty_config_lockless (); -  vty_init (zebrad.master); -  memory_init (); -  zebra_debug_init (); -  zebra_if_init (); -  test_cmd_init (); - -  /* Zebra related initialize. */ -  rib_init (); -  access_list_init (); - -  /* Make kernel routing socket. */ -  zebra_vrf_init (); -  zebra_vty_init(); - -  /* Configuration file read*/ -  vty_read_config (config_file, config_default); - -  /* Clean up rib. */ -  rib_weed_tables (); - -  /* Exit when zebra is working in batch mode. */ -  if (batch_mode) -    exit (0); - -  /* Daemonize. */ -  if (daemon_mode && daemon (0, 0) < 0) -    { -      perror("daemon start failed"); -      exit (1); -    } - -  /* Needed for BSD routing socket. */ -  pid = getpid (); - -  /* Make vty server socket. */ -  vty_serv_sock (vty_addr, vty_port, "/tmp/test_zebra"); - -  /* Print banner. */ -  zlog_notice ("Zebra %s starting: vty@%d", FRR_VERSION, vty_port); - -  while (thread_fetch (zebrad.master, &thread)) -    thread_call (&thread); - -  /* Not reached... */ -  return 0; +	while (thread_fetch(zebrad.master, &thread)) +		thread_call(&thread); + +	/* Not reached... */ +	return 0;  } diff --git a/zebra/zebra_fpm.c b/zebra/zebra_fpm.c index 405b2e9f79..c61589cd0e 100644 --- a/zebra/zebra_fpm.c +++ b/zebra/zebra_fpm.c @@ -67,47 +67,46 @@   * Structure that holds state for iterating over all route_node   * structures that are candidates for being communicated to the FPM.   */ -typedef struct zfpm_rnodes_iter_t_ -{ -  rib_tables_iter_t tables_iter; -  route_table_iter_t iter; +typedef struct zfpm_rnodes_iter_t_ { +	rib_tables_iter_t tables_iter; +	route_table_iter_t iter;  } zfpm_rnodes_iter_t;  /*   * Statistics.   */  typedef struct zfpm_stats_t_ { -  unsigned long connect_calls; -  unsigned long connect_no_sock; +	unsigned long connect_calls; +	unsigned long connect_no_sock; -  unsigned long read_cb_calls; +	unsigned long read_cb_calls; -  unsigned long write_cb_calls; -  unsigned long write_calls; -  unsigned long partial_writes; -  unsigned long max_writes_hit; -  unsigned long t_write_yields; +	unsigned long write_cb_calls; +	unsigned long write_calls; +	unsigned long partial_writes; +	unsigned long max_writes_hit; +	unsigned long t_write_yields; -  unsigned long nop_deletes_skipped; -  unsigned long route_adds; -  unsigned long route_dels; +	unsigned long nop_deletes_skipped; +	unsigned long route_adds; +	unsigned long route_dels; -  unsigned long updates_triggered; -  unsigned long redundant_triggers; -  unsigned long non_fpm_table_triggers; +	unsigned long updates_triggered; +	unsigned long redundant_triggers; +	unsigned long non_fpm_table_triggers; -  unsigned long dests_del_after_update; +	unsigned long dests_del_after_update; -  unsigned long t_conn_down_starts; -  unsigned long t_conn_down_dests_processed; -  unsigned long t_conn_down_yields; -  unsigned long t_conn_down_finishes; +	unsigned long t_conn_down_starts; +	unsigned long t_conn_down_dests_processed; +	unsigned long t_conn_down_yields; +	unsigned long t_conn_down_finishes; -  unsigned long t_conn_up_starts; -  unsigned long t_conn_up_dests_processed; -  unsigned long t_conn_up_yields; -  unsigned long t_conn_up_aborts; -  unsigned long t_conn_up_finishes; +	unsigned long t_conn_up_starts; +	unsigned long t_conn_up_dests_processed; +	unsigned long t_conn_up_yields; +	unsigned long t_conn_up_aborts; +	unsigned long t_conn_up_finishes;  } zfpm_stats_t; @@ -116,187 +115,182 @@ typedef struct zfpm_stats_t_ {   */  typedef enum { -  /* -   * In this state we are not yet ready to connect to the FPM. This -   * can happen when this module is disabled, or if we're cleaning up -   * after a connection has gone down. -   */ -  ZFPM_STATE_IDLE, - -  /* -   * Ready to talk to the FPM and periodically trying to connect to -   * it. -   */ -  ZFPM_STATE_ACTIVE, - -  /* -   * In the middle of bringing up a TCP connection. Specifically, -   * waiting for a connect() call to complete asynchronously. -   */ -  ZFPM_STATE_CONNECTING, - -  /* -   * TCP connection to the FPM is up. -   */ -  ZFPM_STATE_ESTABLISHED +	/* +	 * In this state we are not yet ready to connect to the FPM. This +	 * can happen when this module is disabled, or if we're cleaning up +	 * after a connection has gone down. +	 */ +	ZFPM_STATE_IDLE, + +	/* +	 * Ready to talk to the FPM and periodically trying to connect to +	 * it. +	 */ +	ZFPM_STATE_ACTIVE, + +	/* +	 * In the middle of bringing up a TCP connection. Specifically, +	 * waiting for a connect() call to complete asynchronously. +	 */ +	ZFPM_STATE_CONNECTING, + +	/* +	 * TCP connection to the FPM is up. +	 */ +	ZFPM_STATE_ESTABLISHED  } zfpm_state_t;  /*   * Message format to be used to communicate with the FPM.   */ -typedef enum -{ -  ZFPM_MSG_FORMAT_NONE, -  ZFPM_MSG_FORMAT_NETLINK, -  ZFPM_MSG_FORMAT_PROTOBUF, +typedef enum { +	ZFPM_MSG_FORMAT_NONE, +	ZFPM_MSG_FORMAT_NETLINK, +	ZFPM_MSG_FORMAT_PROTOBUF,  } zfpm_msg_format_e;  /*   * Globals.   */ -typedef struct zfpm_glob_t_ -{ - -  /* -   * True if the FPM module has been enabled. -   */ -  int enabled; - -  /* -   * Message format to be used to communicate with the fpm. -   */ -  zfpm_msg_format_e message_format; - -  struct thread_master *master; - -  zfpm_state_t state; - -  in_addr_t   fpm_server; -  /* -   * Port on which the FPM is running. -   */ -  int fpm_port; - -  /* -   * List of rib_dest_t structures to be processed -   */ -  TAILQ_HEAD (zfpm_dest_q, rib_dest_t_) dest_q; - -  /* -   * Stream socket to the FPM. -   */ -  int sock; - -  /* -   * Buffers for messages to/from the FPM. -   */ -  struct stream *obuf; -  struct stream *ibuf; - -  /* -   * Threads for I/O. -   */ -  struct thread *t_connect; -  struct thread *t_write; -  struct thread *t_read; - -  /* -   * Thread to clean up after the TCP connection to the FPM goes down -   * and the state that belongs to it. -   */ -  struct thread *t_conn_down; - -  struct { -    zfpm_rnodes_iter_t iter; -  } t_conn_down_state; - -  /* -   * Thread to take actions once the TCP conn to the FPM comes up, and -   * the state that belongs to it. -   */ -  struct thread *t_conn_up; - -  struct { -    zfpm_rnodes_iter_t iter; -  } t_conn_up_state; - -  unsigned long connect_calls; -  time_t last_connect_call_time; - -  /* -   * Stats from the start of the current statistics interval up to -   * now. These are the counters we typically update in the code. -   */ -  zfpm_stats_t stats; - -  /* -   * Statistics that were gathered in the last collection interval. -   */ -  zfpm_stats_t last_ivl_stats; - -  /* -   * Cumulative stats from the last clear to the start of the current -   * statistics interval. -   */ -  zfpm_stats_t cumulative_stats; - -  /* -   * Stats interval timer. -   */ -  struct thread *t_stats; - -  /* -   * If non-zero, the last time when statistics were cleared. -   */ -  time_t last_stats_clear_time; +typedef struct zfpm_glob_t_ { + +	/* +	 * True if the FPM module has been enabled. +	 */ +	int enabled; + +	/* +	 * Message format to be used to communicate with the fpm. +	 */ +	zfpm_msg_format_e message_format; + +	struct thread_master *master; + +	zfpm_state_t state; + +	in_addr_t fpm_server; +	/* +	 * Port on which the FPM is running. +	 */ +	int fpm_port; + +	/* +	 * List of rib_dest_t structures to be processed +	 */ +	TAILQ_HEAD(zfpm_dest_q, rib_dest_t_) dest_q; + +	/* +	 * Stream socket to the FPM. +	 */ +	int sock; + +	/* +	 * Buffers for messages to/from the FPM. +	 */ +	struct stream *obuf; +	struct stream *ibuf; + +	/* +	 * Threads for I/O. +	 */ +	struct thread *t_connect; +	struct thread *t_write; +	struct thread *t_read; + +	/* +	 * Thread to clean up after the TCP connection to the FPM goes down +	 * and the state that belongs to it. +	 */ +	struct thread *t_conn_down; + +	struct { +		zfpm_rnodes_iter_t iter; +	} t_conn_down_state; + +	/* +	 * Thread to take actions once the TCP conn to the FPM comes up, and +	 * the state that belongs to it. +	 */ +	struct thread *t_conn_up; + +	struct { +		zfpm_rnodes_iter_t iter; +	} t_conn_up_state; + +	unsigned long connect_calls; +	time_t last_connect_call_time; + +	/* +	 * Stats from the start of the current statistics interval up to +	 * now. These are the counters we typically update in the code. +	 */ +	zfpm_stats_t stats; + +	/* +	 * Statistics that were gathered in the last collection interval. +	 */ +	zfpm_stats_t last_ivl_stats; + +	/* +	 * Cumulative stats from the last clear to the start of the current +	 * statistics interval. +	 */ +	zfpm_stats_t cumulative_stats; + +	/* +	 * Stats interval timer. +	 */ +	struct thread *t_stats; + +	/* +	 * If non-zero, the last time when statistics were cleared. +	 */ +	time_t last_stats_clear_time;  } zfpm_glob_t;  static zfpm_glob_t zfpm_glob_space;  static zfpm_glob_t *zfpm_g = &zfpm_glob_space; -static int zfpm_trigger_update (struct route_node *rn, const char *reason); +static int zfpm_trigger_update(struct route_node *rn, const char *reason); -static int zfpm_read_cb (struct thread *thread); -static int zfpm_write_cb (struct thread *thread); +static int zfpm_read_cb(struct thread *thread); +static int zfpm_write_cb(struct thread *thread); -static void zfpm_set_state (zfpm_state_t state, const char *reason); -static void zfpm_start_connect_timer (const char *reason); -static void zfpm_start_stats_timer (void); +static void zfpm_set_state(zfpm_state_t state, const char *reason); +static void zfpm_start_connect_timer(const char *reason); +static void zfpm_start_stats_timer(void);  /*   * zfpm_thread_should_yield   */ -static inline int -zfpm_thread_should_yield (struct thread *t) +static inline int zfpm_thread_should_yield(struct thread *t)  { -  return thread_should_yield (t); +	return thread_should_yield(t);  }  /*   * zfpm_state_to_str   */ -static const char * -zfpm_state_to_str (zfpm_state_t state) +static const char *zfpm_state_to_str(zfpm_state_t state)  { -  switch (state) -    { +	switch (state) { -    case ZFPM_STATE_IDLE: -      return "idle"; +	case ZFPM_STATE_IDLE: +		return "idle"; -    case ZFPM_STATE_ACTIVE: -      return "active"; +	case ZFPM_STATE_ACTIVE: +		return "active"; -    case ZFPM_STATE_CONNECTING: -      return "connecting"; +	case ZFPM_STATE_CONNECTING: +		return "connecting"; -    case ZFPM_STATE_ESTABLISHED: -      return "established"; +	case ZFPM_STATE_ESTABLISHED: +		return "established"; -    default: -      return "unknown"; -    } +	default: +		return "unknown"; +	}  }  /* @@ -304,20 +298,18 @@ zfpm_state_to_str (zfpm_state_t state)   *   * Returns the time elapsed (in seconds) since the given time.   */ -static time_t -zfpm_get_elapsed_time (time_t reference) +static time_t zfpm_get_elapsed_time(time_t reference)  { -  time_t now; +	time_t now; -  now = monotime(NULL); +	now = monotime(NULL); -  if (now < reference) -    { -      assert (0); -      return 0; -    } +	if (now < reference) { +		assert(0); +		return 0; +	} -  return now - reference; +	return now - reference;  }  /* @@ -326,96 +318,89 @@ zfpm_get_elapsed_time (time_t reference)   * Returns TRUE if the the given table is to be communicated to the   * FPM.   */ -static inline int -zfpm_is_table_for_fpm (struct route_table *table) +static inline int zfpm_is_table_for_fpm(struct route_table *table)  { -  rib_table_info_t *info; +	rib_table_info_t *info; -  info = rib_table_info (table); +	info = rib_table_info(table); -  /* -   * We only send the unicast tables in the main instance to the FPM -   * at this point. -   */ -  if (zvrf_id (info->zvrf) != 0) -    return 0; +	/* +	 * We only send the unicast tables in the main instance to the FPM +	 * at this point. +	 */ +	if (zvrf_id(info->zvrf) != 0) +		return 0; -  if (info->safi != SAFI_UNICAST) -    return 0; +	if (info->safi != SAFI_UNICAST) +		return 0; -  return 1; +	return 1;  }  /*   * zfpm_rnodes_iter_init   */ -static inline void -zfpm_rnodes_iter_init (zfpm_rnodes_iter_t *iter) +static inline void zfpm_rnodes_iter_init(zfpm_rnodes_iter_t *iter)  { -  memset (iter, 0, sizeof (*iter)); -  rib_tables_iter_init (&iter->tables_iter); - -  /* -   * This is a hack, but it makes implementing 'next' easier by -   * ensuring that route_table_iter_next() will return NULL the first -   * time we call it. -   */ -  route_table_iter_init (&iter->iter, NULL); -  route_table_iter_cleanup (&iter->iter); +	memset(iter, 0, sizeof(*iter)); +	rib_tables_iter_init(&iter->tables_iter); + +	/* +	 * This is a hack, but it makes implementing 'next' easier by +	 * ensuring that route_table_iter_next() will return NULL the first +	 * time we call it. +	 */ +	route_table_iter_init(&iter->iter, NULL); +	route_table_iter_cleanup(&iter->iter);  }  /*   * zfpm_rnodes_iter_next   */ -static inline struct route_node * -zfpm_rnodes_iter_next (zfpm_rnodes_iter_t *iter) +static inline struct route_node *zfpm_rnodes_iter_next(zfpm_rnodes_iter_t *iter)  { -  struct route_node *rn; -  struct route_table *table; +	struct route_node *rn; +	struct route_table *table; -  while (1) -    { -      rn = route_table_iter_next (&iter->iter); -      if (rn) -	return rn; +	while (1) { +		rn = route_table_iter_next(&iter->iter); +		if (rn) +			return rn; -      /* -       * We've made our way through this table, go to the next one. -       */ -      route_table_iter_cleanup (&iter->iter); +		/* +		 * We've made our way through this table, go to the next one. +		 */ +		route_table_iter_cleanup(&iter->iter); -      while ((table = rib_tables_iter_next (&iter->tables_iter))) -	{ -	  if (zfpm_is_table_for_fpm (table)) -	    break; -	} +		while ((table = rib_tables_iter_next(&iter->tables_iter))) { +			if (zfpm_is_table_for_fpm(table)) +				break; +		} -      if (!table) -	return NULL; +		if (!table) +			return NULL; -      route_table_iter_init (&iter->iter, table); -    } +		route_table_iter_init(&iter->iter, table); +	} -  return NULL; +	return NULL;  }  /*   * zfpm_rnodes_iter_pause   */ -static inline void -zfpm_rnodes_iter_pause (zfpm_rnodes_iter_t *iter) +static inline void zfpm_rnodes_iter_pause(zfpm_rnodes_iter_t *iter)  { -  route_table_iter_pause (&iter->iter); +	route_table_iter_pause(&iter->iter);  }  /*   * zfpm_rnodes_iter_cleanup   */ -static inline void -zfpm_rnodes_iter_cleanup (zfpm_rnodes_iter_t *iter) +static inline void zfpm_rnodes_iter_cleanup(zfpm_rnodes_iter_t *iter)  { -  route_table_iter_cleanup (&iter->iter); -  rib_tables_iter_cleanup (&iter->tables_iter); +	route_table_iter_cleanup(&iter->iter); +	rib_tables_iter_cleanup(&iter->tables_iter);  }  /* @@ -423,28 +408,25 @@ zfpm_rnodes_iter_cleanup (zfpm_rnodes_iter_t *iter)   *   * Initialize a statistics block.   */ -static inline void -zfpm_stats_init (zfpm_stats_t *stats) +static inline void zfpm_stats_init(zfpm_stats_t *stats)  { -  memset (stats, 0, sizeof (*stats)); +	memset(stats, 0, sizeof(*stats));  }  /*   * zfpm_stats_reset   */ -static inline void -zfpm_stats_reset (zfpm_stats_t *stats) +static inline void zfpm_stats_reset(zfpm_stats_t *stats)  { -  zfpm_stats_init (stats); +	zfpm_stats_init(stats);  }  /*   * zfpm_stats_copy   */ -static inline void -zfpm_stats_copy (const zfpm_stats_t *src, zfpm_stats_t *dest) +static inline void zfpm_stats_copy(const zfpm_stats_t *src, zfpm_stats_t *dest)  { -  memcpy (dest, src, sizeof (*dest)); +	memcpy(dest, src, sizeof(*dest));  }  /* @@ -458,68 +440,62 @@ zfpm_stats_copy (const zfpm_stats_t *src, zfpm_stats_t *dest)   * structure is composed entirely of counters. This can easily be   * changed when necessary.   */ -static void -zfpm_stats_compose (const zfpm_stats_t *s1, const zfpm_stats_t *s2, -		    zfpm_stats_t *result) +static void zfpm_stats_compose(const zfpm_stats_t *s1, const zfpm_stats_t *s2, +			       zfpm_stats_t *result)  { -  const unsigned long *p1, *p2; -  unsigned long *result_p; -  int i, num_counters; +	const unsigned long *p1, *p2; +	unsigned long *result_p; +	int i, num_counters; -  p1 = (const unsigned long *) s1; -  p2 = (const unsigned long *) s2; -  result_p = (unsigned long *) result; +	p1 = (const unsigned long *)s1; +	p2 = (const unsigned long *)s2; +	result_p = (unsigned long *)result; -  num_counters = (sizeof (zfpm_stats_t) / sizeof (unsigned long)); +	num_counters = (sizeof(zfpm_stats_t) / sizeof(unsigned long)); -  for (i = 0; i < num_counters; i++) -    { -      result_p[i] = p1[i] + p2[i]; -    } +	for (i = 0; i < num_counters; i++) { +		result_p[i] = p1[i] + p2[i]; +	}  }  /*   * zfpm_read_on   */ -static inline void -zfpm_read_on (void) +static inline void zfpm_read_on(void)  { -  assert (!zfpm_g->t_read); -  assert (zfpm_g->sock >= 0); +	assert(!zfpm_g->t_read); +	assert(zfpm_g->sock >= 0); -  THREAD_READ_ON (zfpm_g->master, zfpm_g->t_read, zfpm_read_cb, 0, -		  zfpm_g->sock); +	THREAD_READ_ON(zfpm_g->master, zfpm_g->t_read, zfpm_read_cb, 0, +		       zfpm_g->sock);  }  /*   * zfpm_write_on   */ -static inline void -zfpm_write_on (void) +static inline void zfpm_write_on(void)  { -  assert (!zfpm_g->t_write); -  assert (zfpm_g->sock >= 0); +	assert(!zfpm_g->t_write); +	assert(zfpm_g->sock >= 0); -  THREAD_WRITE_ON (zfpm_g->master, zfpm_g->t_write, zfpm_write_cb, 0, -		   zfpm_g->sock); +	THREAD_WRITE_ON(zfpm_g->master, zfpm_g->t_write, zfpm_write_cb, 0, +			zfpm_g->sock);  }  /*   * zfpm_read_off   */ -static inline void -zfpm_read_off (void) +static inline void zfpm_read_off(void)  { -  THREAD_READ_OFF (zfpm_g->t_read); +	THREAD_READ_OFF(zfpm_g->t_read);  }  /*   * zfpm_write_off   */ -static inline void -zfpm_write_off (void) +static inline void zfpm_write_off(void)  { -  THREAD_WRITE_OFF (zfpm_g->t_write); +	THREAD_WRITE_OFF(zfpm_g->t_write);  }  /* @@ -528,54 +504,50 @@ zfpm_write_off (void)   * Callback for actions to be taken when the connection to the FPM   * comes up.   */ -static int -zfpm_conn_up_thread_cb (struct thread *thread) +static int zfpm_conn_up_thread_cb(struct thread *thread)  { -  struct route_node *rnode; -  zfpm_rnodes_iter_t *iter; -  rib_dest_t *dest; +	struct route_node *rnode; +	zfpm_rnodes_iter_t *iter; +	rib_dest_t *dest; -  assert (zfpm_g->t_conn_up); -  zfpm_g->t_conn_up = NULL; +	assert(zfpm_g->t_conn_up); +	zfpm_g->t_conn_up = NULL; -  iter = &zfpm_g->t_conn_up_state.iter; +	iter = &zfpm_g->t_conn_up_state.iter; -  if (zfpm_g->state != ZFPM_STATE_ESTABLISHED) -    { -      zfpm_debug ("Connection not up anymore, conn_up thread aborting"); -      zfpm_g->stats.t_conn_up_aborts++; -      goto done; -    } - -  while ((rnode = zfpm_rnodes_iter_next (iter))) -    { -      dest = rib_dest_from_rnode (rnode); +	if (zfpm_g->state != ZFPM_STATE_ESTABLISHED) { +		zfpm_debug( +			"Connection not up anymore, conn_up thread aborting"); +		zfpm_g->stats.t_conn_up_aborts++; +		goto done; +	} -      if (dest) -	{ -	  zfpm_g->stats.t_conn_up_dests_processed++; -	  zfpm_trigger_update (rnode, NULL); +	while ((rnode = zfpm_rnodes_iter_next(iter))) { +		dest = rib_dest_from_rnode(rnode); + +		if (dest) { +			zfpm_g->stats.t_conn_up_dests_processed++; +			zfpm_trigger_update(rnode, NULL); +		} + +		/* +		 * Yield if need be. +		 */ +		if (!zfpm_thread_should_yield(thread)) +			continue; + +		zfpm_g->stats.t_conn_up_yields++; +		zfpm_rnodes_iter_pause(iter); +		zfpm_g->t_conn_up = thread_add_background( +			zfpm_g->master, zfpm_conn_up_thread_cb, 0, 0); +		return 0;  	} -      /* -       * Yield if need be. -       */ -      if (!zfpm_thread_should_yield (thread)) -	continue; - -      zfpm_g->stats.t_conn_up_yields++; -      zfpm_rnodes_iter_pause (iter); -      zfpm_g->t_conn_up = thread_add_background (zfpm_g->master, -						 zfpm_conn_up_thread_cb, -						 0, 0); -      return 0; -    } - -  zfpm_g->stats.t_conn_up_finishes++; - - done: -  zfpm_rnodes_iter_cleanup (iter); -  return 0; +	zfpm_g->stats.t_conn_up_finishes++; + +done: +	zfpm_rnodes_iter_cleanup(iter); +	return 0;  }  /* @@ -583,25 +555,24 @@ zfpm_conn_up_thread_cb (struct thread *thread)   *   * Called when the connection to the FPM comes up.   */ -static void -zfpm_connection_up (const char *detail) +static void zfpm_connection_up(const char *detail)  { -  assert (zfpm_g->sock >= 0); -  zfpm_read_on (); -  zfpm_write_on (); -  zfpm_set_state (ZFPM_STATE_ESTABLISHED, detail); - -  /* -   * Start thread to push existing routes to the FPM. -   */ -  assert (!zfpm_g->t_conn_up); - -  zfpm_rnodes_iter_init (&zfpm_g->t_conn_up_state.iter); - -  zfpm_debug ("Starting conn_up thread"); -  zfpm_g->t_conn_up = thread_add_background (zfpm_g->master, -					     zfpm_conn_up_thread_cb, 0, 0); -  zfpm_g->stats.t_conn_up_starts++; +	assert(zfpm_g->sock >= 0); +	zfpm_read_on(); +	zfpm_write_on(); +	zfpm_set_state(ZFPM_STATE_ESTABLISHED, detail); + +	/* +	 * Start thread to push existing routes to the FPM. +	 */ +	assert(!zfpm_g->t_conn_up); + +	zfpm_rnodes_iter_init(&zfpm_g->t_conn_up_state.iter); + +	zfpm_debug("Starting conn_up thread"); +	zfpm_g->t_conn_up = thread_add_background(zfpm_g->master, +						  zfpm_conn_up_thread_cb, 0, 0); +	zfpm_g->stats.t_conn_up_starts++;  }  /* @@ -609,34 +580,32 @@ zfpm_connection_up (const char *detail)   *   * Check if an asynchronous connect() to the FPM is complete.   */ -static void -zfpm_connect_check (void) +static void zfpm_connect_check(void)  { -  int status; -  socklen_t slen; -  int ret; - -  zfpm_read_off (); -  zfpm_write_off (); - -  slen = sizeof (status); -  ret = getsockopt (zfpm_g->sock, SOL_SOCKET, SO_ERROR, (void *) &status, -		    &slen); - -  if (ret >= 0 && status == 0) -    { -      zfpm_connection_up ("async connect complete"); -      return; -    } - -  /* -   * getsockopt() failed or indicated an error on the socket. -   */ -  close (zfpm_g->sock); -  zfpm_g->sock = -1; - -  zfpm_start_connect_timer ("getsockopt() after async connect failed"); -  return; +	int status; +	socklen_t slen; +	int ret; + +	zfpm_read_off(); +	zfpm_write_off(); + +	slen = sizeof(status); +	ret = getsockopt(zfpm_g->sock, SOL_SOCKET, SO_ERROR, (void *)&status, +			 &slen); + +	if (ret >= 0 && status == 0) { +		zfpm_connection_up("async connect complete"); +		return; +	} + +	/* +	 * getsockopt() failed or indicated an error on the socket. +	 */ +	close(zfpm_g->sock); +	zfpm_g->sock = -1; + +	zfpm_start_connect_timer("getsockopt() after async connect failed"); +	return;  }  /* @@ -645,64 +614,60 @@ zfpm_connect_check (void)   * Callback that is invoked to clean up state after the TCP connection   * to the FPM goes down.   */ -static int -zfpm_conn_down_thread_cb (struct thread *thread) +static int zfpm_conn_down_thread_cb(struct thread *thread)  { -  struct route_node *rnode; -  zfpm_rnodes_iter_t *iter; -  rib_dest_t *dest; +	struct route_node *rnode; +	zfpm_rnodes_iter_t *iter; +	rib_dest_t *dest; -  assert (zfpm_g->state == ZFPM_STATE_IDLE); +	assert(zfpm_g->state == ZFPM_STATE_IDLE); -  assert (zfpm_g->t_conn_down); -  zfpm_g->t_conn_down = NULL; +	assert(zfpm_g->t_conn_down); +	zfpm_g->t_conn_down = NULL; -  iter = &zfpm_g->t_conn_down_state.iter; +	iter = &zfpm_g->t_conn_down_state.iter; -  while ((rnode = zfpm_rnodes_iter_next (iter))) -    { -      dest = rib_dest_from_rnode (rnode); +	while ((rnode = zfpm_rnodes_iter_next(iter))) { +		dest = rib_dest_from_rnode(rnode); -      if (dest) -	{ -	  if (CHECK_FLAG (dest->flags, RIB_DEST_UPDATE_FPM)) -	    { -	      TAILQ_REMOVE (&zfpm_g->dest_q, dest, fpm_q_entries); -	    } +		if (dest) { +			if (CHECK_FLAG(dest->flags, RIB_DEST_UPDATE_FPM)) { +				TAILQ_REMOVE(&zfpm_g->dest_q, dest, +					     fpm_q_entries); +			} + +			UNSET_FLAG(dest->flags, RIB_DEST_UPDATE_FPM); +			UNSET_FLAG(dest->flags, RIB_DEST_SENT_TO_FPM); -	  UNSET_FLAG (dest->flags, RIB_DEST_UPDATE_FPM); -	  UNSET_FLAG (dest->flags, RIB_DEST_SENT_TO_FPM); +			zfpm_g->stats.t_conn_down_dests_processed++; -	  zfpm_g->stats.t_conn_down_dests_processed++; +			/* +			 * Check if the dest should be deleted. +			 */ +			rib_gc_dest(rnode); +		} -	  /* -	   * Check if the dest should be deleted. -	   */ -	  rib_gc_dest(rnode); +		/* +		 * Yield if need be. +		 */ +		if (!zfpm_thread_should_yield(thread)) +			continue; + +		zfpm_g->stats.t_conn_down_yields++; +		zfpm_rnodes_iter_pause(iter); +		zfpm_g->t_conn_down = thread_add_background( +			zfpm_g->master, zfpm_conn_down_thread_cb, 0, 0); +		return 0;  	} -      /* -       * Yield if need be. -       */ -      if (!zfpm_thread_should_yield (thread)) -	continue; - -      zfpm_g->stats.t_conn_down_yields++; -      zfpm_rnodes_iter_pause (iter); -      zfpm_g->t_conn_down = thread_add_background (zfpm_g->master, -						   zfpm_conn_down_thread_cb, -						   0, 0); -      return 0; -    } - -  zfpm_g->stats.t_conn_down_finishes++; -  zfpm_rnodes_iter_cleanup (iter); - -  /* -   * Start the process of connecting to the FPM again. -   */ -  zfpm_start_connect_timer ("cleanup complete"); -  return 0; +	zfpm_g->stats.t_conn_down_finishes++; +	zfpm_rnodes_iter_cleanup(iter); + +	/* +	 * Start the process of connecting to the FPM again. +	 */ +	zfpm_start_connect_timer("cleanup complete"); +	return 0;  }  /* @@ -710,128 +675,121 @@ zfpm_conn_down_thread_cb (struct thread *thread)   *   * Called when the connection to the FPM has gone down.   */ -static void -zfpm_connection_down (const char *detail) +static void zfpm_connection_down(const char *detail)  { -  if (!detail) -    detail = "unknown"; +	if (!detail) +		detail = "unknown"; -  assert (zfpm_g->state == ZFPM_STATE_ESTABLISHED); +	assert(zfpm_g->state == ZFPM_STATE_ESTABLISHED); -  zlog_info ("connection to the FPM has gone down: %s", detail); +	zlog_info("connection to the FPM has gone down: %s", detail); -  zfpm_read_off (); -  zfpm_write_off (); +	zfpm_read_off(); +	zfpm_write_off(); -  stream_reset (zfpm_g->ibuf); -  stream_reset (zfpm_g->obuf); +	stream_reset(zfpm_g->ibuf); +	stream_reset(zfpm_g->obuf); -  if (zfpm_g->sock >= 0) { -    close (zfpm_g->sock); -    zfpm_g->sock = -1; -  } - -  /* -   * Start thread to clean up state after the connection goes down. -   */ -  assert (!zfpm_g->t_conn_down); -  zfpm_debug ("Starting conn_down thread"); -  zfpm_rnodes_iter_init (&zfpm_g->t_conn_down_state.iter); -  zfpm_g->t_conn_down = thread_add_background (zfpm_g->master, -					       zfpm_conn_down_thread_cb, 0, 0); -  zfpm_g->stats.t_conn_down_starts++; +	if (zfpm_g->sock >= 0) { +		close(zfpm_g->sock); +		zfpm_g->sock = -1; +	} -  zfpm_set_state (ZFPM_STATE_IDLE, detail); +	/* +	 * Start thread to clean up state after the connection goes down. +	 */ +	assert(!zfpm_g->t_conn_down); +	zfpm_debug("Starting conn_down thread"); +	zfpm_rnodes_iter_init(&zfpm_g->t_conn_down_state.iter); +	zfpm_g->t_conn_down = thread_add_background( +		zfpm_g->master, zfpm_conn_down_thread_cb, 0, 0); +	zfpm_g->stats.t_conn_down_starts++; + +	zfpm_set_state(ZFPM_STATE_IDLE, detail);  }  /*   * zfpm_read_cb   */ -static int -zfpm_read_cb (struct thread *thread) +static int zfpm_read_cb(struct thread *thread)  { -  size_t already; -  struct stream *ibuf; -  uint16_t msg_len; -  fpm_msg_hdr_t *hdr; - -  zfpm_g->stats.read_cb_calls++; -  assert (zfpm_g->t_read); -  zfpm_g->t_read = NULL; - -  /* -   * Check if async connect is now done. -   */ -  if (zfpm_g->state == ZFPM_STATE_CONNECTING) -    { -      zfpm_connect_check(); -      return 0; -    } - -  assert (zfpm_g->state == ZFPM_STATE_ESTABLISHED); -  assert (zfpm_g->sock >= 0); - -  ibuf = zfpm_g->ibuf; - -  already = stream_get_endp (ibuf); -  if (already < FPM_MSG_HDR_LEN) -    { -      ssize_t nbyte; - -      nbyte = stream_read_try (ibuf, zfpm_g->sock, FPM_MSG_HDR_LEN - already); -      if (nbyte == 0 || nbyte == -1) -	{ -	  zfpm_connection_down ("closed socket in read"); -	  return 0; +	size_t already; +	struct stream *ibuf; +	uint16_t msg_len; +	fpm_msg_hdr_t *hdr; + +	zfpm_g->stats.read_cb_calls++; +	assert(zfpm_g->t_read); +	zfpm_g->t_read = NULL; + +	/* +	 * Check if async connect is now done. +	 */ +	if (zfpm_g->state == ZFPM_STATE_CONNECTING) { +		zfpm_connect_check(); +		return 0;  	} -      if (nbyte != (ssize_t) (FPM_MSG_HDR_LEN - already)) -	goto done; +	assert(zfpm_g->state == ZFPM_STATE_ESTABLISHED); +	assert(zfpm_g->sock >= 0); -      already = FPM_MSG_HDR_LEN; -    } +	ibuf = zfpm_g->ibuf; -  stream_set_getp (ibuf, 0); +	already = stream_get_endp(ibuf); +	if (already < FPM_MSG_HDR_LEN) { +		ssize_t nbyte; -  hdr = (fpm_msg_hdr_t *) stream_pnt (ibuf); +		nbyte = stream_read_try(ibuf, zfpm_g->sock, +					FPM_MSG_HDR_LEN - already); +		if (nbyte == 0 || nbyte == -1) { +			zfpm_connection_down("closed socket in read"); +			return 0; +		} -  if (!fpm_msg_hdr_ok (hdr)) -    { -      zfpm_connection_down ("invalid message header"); -      return 0; -    } +		if (nbyte != (ssize_t)(FPM_MSG_HDR_LEN - already)) +			goto done; -  msg_len = fpm_msg_len (hdr); +		already = FPM_MSG_HDR_LEN; +	} -  /* -   * Read out the rest of the packet. -   */ -  if (already < msg_len) -    { -      ssize_t nbyte; +	stream_set_getp(ibuf, 0); -      nbyte = stream_read_try (ibuf, zfpm_g->sock, msg_len - already); +	hdr = (fpm_msg_hdr_t *)stream_pnt(ibuf); -      if (nbyte == 0 || nbyte == -1) -	{ -	  zfpm_connection_down ("failed to read message"); -	  return 0; +	if (!fpm_msg_hdr_ok(hdr)) { +		zfpm_connection_down("invalid message header"); +		return 0;  	} -      if (nbyte != (ssize_t) (msg_len - already)) -	goto done; -    } +	msg_len = fpm_msg_len(hdr); -  zfpm_debug ("Read out a full fpm message"); +	/* +	 * Read out the rest of the packet. +	 */ +	if (already < msg_len) { +		ssize_t nbyte; -  /* -   * Just throw it away for now. -   */ -  stream_reset (ibuf); +		nbyte = stream_read_try(ibuf, zfpm_g->sock, msg_len - already); - done: -  zfpm_read_on (); -  return 0; +		if (nbyte == 0 || nbyte == -1) { +			zfpm_connection_down("failed to read message"); +			return 0; +		} + +		if (nbyte != (ssize_t)(msg_len - already)) +			goto done; +	} + +	zfpm_debug("Read out a full fpm message"); + +	/* +	 * Just throw it away for now. +	 */ +	stream_reset(ibuf); + +done: +	zfpm_read_on(); +	return 0;  }  /* @@ -839,24 +797,23 @@ zfpm_read_cb (struct thread *thread)   *   * Returns TRUE if we may have something to write to the FPM.   */ -static int -zfpm_writes_pending (void) +static int zfpm_writes_pending(void)  { -  /* -   * Check if there is any data in the outbound buffer that has not -   * been written to the socket yet. -   */ -  if (stream_get_endp (zfpm_g->obuf) - stream_get_getp (zfpm_g->obuf)) -    return 1; +	/* +	 * Check if there is any data in the outbound buffer that has not +	 * been written to the socket yet. +	 */ +	if (stream_get_endp(zfpm_g->obuf) - stream_get_getp(zfpm_g->obuf)) +		return 1; -  /* -   * Check if there are any prefixes on the outbound queue. -   */ -  if (!TAILQ_EMPTY (&zfpm_g->dest_q)) -    return 1; +	/* +	 * Check if there are any prefixes on the outbound queue. +	 */ +	if (!TAILQ_EMPTY(&zfpm_g->dest_q)) +		return 1; -  return 0; +	return 0;  }  /* @@ -867,44 +824,44 @@ zfpm_writes_pending (void)   * Returns the number of bytes written to the buffer. 0 or a negative   * value indicates an error.   */ -static inline int -zfpm_encode_route (rib_dest_t *dest, struct rib *rib, char *in_buf, -		   size_t in_buf_len, fpm_msg_type_e *msg_type) +static inline int zfpm_encode_route(rib_dest_t *dest, struct rib *rib, +				    char *in_buf, size_t in_buf_len, +				    fpm_msg_type_e *msg_type)  { -  size_t len; +	size_t len;  #ifdef HAVE_NETLINK -  int cmd; +	int cmd;  #endif -  len = 0; +	len = 0; -  *msg_type = FPM_MSG_TYPE_NONE; +	*msg_type = FPM_MSG_TYPE_NONE; -  switch (zfpm_g->message_format) { +	switch (zfpm_g->message_format) { -  case ZFPM_MSG_FORMAT_PROTOBUF: +	case ZFPM_MSG_FORMAT_PROTOBUF:  #ifdef HAVE_PROTOBUF -    len = zfpm_protobuf_encode_route (dest, rib, (uint8_t *) in_buf, -				      in_buf_len); -    *msg_type = FPM_MSG_TYPE_PROTOBUF; +		len = zfpm_protobuf_encode_route(dest, rib, (uint8_t *)in_buf, +						 in_buf_len); +		*msg_type = FPM_MSG_TYPE_PROTOBUF;  #endif -    break; +		break; -  case ZFPM_MSG_FORMAT_NETLINK: +	case ZFPM_MSG_FORMAT_NETLINK:  #ifdef HAVE_NETLINK -    *msg_type = FPM_MSG_TYPE_NETLINK; -    cmd = rib ? RTM_NEWROUTE : RTM_DELROUTE; -    len = zfpm_netlink_encode_route (cmd, dest, rib, in_buf, in_buf_len); -    assert(fpm_msg_align(len) == len); -    *msg_type = FPM_MSG_TYPE_NETLINK; +		*msg_type = FPM_MSG_TYPE_NETLINK; +		cmd = rib ? RTM_NEWROUTE : RTM_DELROUTE; +		len = zfpm_netlink_encode_route(cmd, dest, rib, in_buf, +						in_buf_len); +		assert(fpm_msg_align(len) == len); +		*msg_type = FPM_MSG_TYPE_NETLINK;  #endif /* HAVE_NETLINK */ -    break; - -  default: -    break; -  } +		break; -  return len; +	default: +		break; +	} +	return len;  }  /* @@ -912,23 +869,22 @@ zfpm_encode_route (rib_dest_t *dest, struct rib *rib, char *in_buf,   *   * Returns the rib that is to be sent to the FPM for a given dest.   */ -struct rib * -zfpm_route_for_update (rib_dest_t *dest) +struct rib *zfpm_route_for_update(rib_dest_t *dest)  { -  struct rib *rib; +	struct rib *rib; -  RIB_DEST_FOREACH_ROUTE (dest, rib) -    { -      if (!CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB)) -	continue; +	RIB_DEST_FOREACH_ROUTE(dest, rib) +	{ +		if (!CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB)) +			continue; -      return rib; -    } +		return rib; +	} -  /* -   * We have no route for this destination. -   */ -  return NULL; +	/* +	 * We have no route for this destination. +	 */ +	return NULL;  }  /* @@ -937,264 +893,249 @@ zfpm_route_for_update (rib_dest_t *dest)   * Process the outgoing queue and write messages to the outbound   * buffer.   */ -static void -zfpm_build_updates (void) +static void zfpm_build_updates(void)  { -  struct stream *s; -  rib_dest_t *dest; -  unsigned char *buf, *data, *buf_end; -  size_t msg_len; -  size_t data_len; -  fpm_msg_hdr_t *hdr; -  struct rib *rib; -  int is_add, write_msg; -  fpm_msg_type_e msg_type; - -  s = zfpm_g->obuf; - -  assert (stream_empty (s)); - -  do { - -    /* -     * Make sure there is enough space to write another message. -     */ -    if (STREAM_WRITEABLE (s) < FPM_MAX_MSG_LEN) -      break; - -    buf = STREAM_DATA (s) + stream_get_endp (s); -    buf_end = buf + STREAM_WRITEABLE (s); - -    dest = TAILQ_FIRST (&zfpm_g->dest_q); -    if (!dest) -      break; - -    assert (CHECK_FLAG (dest->flags, RIB_DEST_UPDATE_FPM)); - -    hdr = (fpm_msg_hdr_t *) buf; -    hdr->version = FPM_PROTO_VERSION; - -    data = fpm_msg_data (hdr); - -    rib = zfpm_route_for_update (dest); -    is_add = rib ? 1 : 0; - -    write_msg = 1; - -    /* -     * If this is a route deletion, and we have not sent the route to -     * the FPM previously, skip it. -     */ -    if (!is_add && !CHECK_FLAG (dest->flags, RIB_DEST_SENT_TO_FPM)) -      { -	write_msg = 0; -	zfpm_g->stats.nop_deletes_skipped++; -      } - -    if (write_msg) { -      data_len = zfpm_encode_route (dest, rib, (char *) data, buf_end - data, -				    &msg_type); - -      assert (data_len); -      if (data_len) -	{ -	  hdr->msg_type = msg_type; -	  msg_len = fpm_data_len_to_msg_len (data_len); -	  hdr->msg_len = htons (msg_len); -	  stream_forward_endp (s, msg_len); - -	  if (is_add) -	    zfpm_g->stats.route_adds++; -	  else -	    zfpm_g->stats.route_dels++; -	} -    } - -    /* -     * Remove the dest from the queue, and reset the flag. -     */ -    UNSET_FLAG (dest->flags, RIB_DEST_UPDATE_FPM); -    TAILQ_REMOVE (&zfpm_g->dest_q, dest, fpm_q_entries); - -    if (is_add) -      { -	SET_FLAG (dest->flags, RIB_DEST_SENT_TO_FPM); -      } -    else -      { -	UNSET_FLAG (dest->flags, RIB_DEST_SENT_TO_FPM); -      } - -    /* -     * Delete the destination if necessary. -     */ -    if (rib_gc_dest (dest->rnode)) -      zfpm_g->stats.dests_del_after_update++; - -  } while (1); - +	struct stream *s; +	rib_dest_t *dest; +	unsigned char *buf, *data, *buf_end; +	size_t msg_len; +	size_t data_len; +	fpm_msg_hdr_t *hdr; +	struct rib *rib; +	int is_add, write_msg; +	fpm_msg_type_e msg_type; + +	s = zfpm_g->obuf; + +	assert(stream_empty(s)); + +	do { + +		/* +		 * Make sure there is enough space to write another message. +		 */ +		if (STREAM_WRITEABLE(s) < FPM_MAX_MSG_LEN) +			break; + +		buf = STREAM_DATA(s) + stream_get_endp(s); +		buf_end = buf + STREAM_WRITEABLE(s); + +		dest = TAILQ_FIRST(&zfpm_g->dest_q); +		if (!dest) +			break; + +		assert(CHECK_FLAG(dest->flags, RIB_DEST_UPDATE_FPM)); + +		hdr = (fpm_msg_hdr_t *)buf; +		hdr->version = FPM_PROTO_VERSION; + +		data = fpm_msg_data(hdr); + +		rib = zfpm_route_for_update(dest); +		is_add = rib ? 1 : 0; + +		write_msg = 1; + +		/* +		 * If this is a route deletion, and we have not sent the route +		 * to +		 * the FPM previously, skip it. +		 */ +		if (!is_add && !CHECK_FLAG(dest->flags, RIB_DEST_SENT_TO_FPM)) { +			write_msg = 0; +			zfpm_g->stats.nop_deletes_skipped++; +		} + +		if (write_msg) { +			data_len = zfpm_encode_route(dest, rib, (char *)data, +						     buf_end - data, &msg_type); + +			assert(data_len); +			if (data_len) { +				hdr->msg_type = msg_type; +				msg_len = fpm_data_len_to_msg_len(data_len); +				hdr->msg_len = htons(msg_len); +				stream_forward_endp(s, msg_len); + +				if (is_add) +					zfpm_g->stats.route_adds++; +				else +					zfpm_g->stats.route_dels++; +			} +		} + +		/* +		 * Remove the dest from the queue, and reset the flag. +		 */ +		UNSET_FLAG(dest->flags, RIB_DEST_UPDATE_FPM); +		TAILQ_REMOVE(&zfpm_g->dest_q, dest, fpm_q_entries); + +		if (is_add) { +			SET_FLAG(dest->flags, RIB_DEST_SENT_TO_FPM); +		} else { +			UNSET_FLAG(dest->flags, RIB_DEST_SENT_TO_FPM); +		} + +		/* +		 * Delete the destination if necessary. +		 */ +		if (rib_gc_dest(dest->rnode)) +			zfpm_g->stats.dests_del_after_update++; + +	} while (1);  }  /*   * zfpm_write_cb   */ -static int -zfpm_write_cb (struct thread *thread) +static int zfpm_write_cb(struct thread *thread)  { -  struct stream *s; -  int num_writes; +	struct stream *s; +	int num_writes; + +	zfpm_g->stats.write_cb_calls++; +	assert(zfpm_g->t_write); +	zfpm_g->t_write = NULL; + +	/* +	 * Check if async connect is now done. +	 */ +	if (zfpm_g->state == ZFPM_STATE_CONNECTING) { +		zfpm_connect_check(); +		return 0; +	} -  zfpm_g->stats.write_cb_calls++; -  assert (zfpm_g->t_write); -  zfpm_g->t_write = NULL; +	assert(zfpm_g->state == ZFPM_STATE_ESTABLISHED); +	assert(zfpm_g->sock >= 0); -  /* -   * Check if async connect is now done. -   */ -  if (zfpm_g->state == ZFPM_STATE_CONNECTING) -    { -      zfpm_connect_check (); -      return 0; -    } +	num_writes = 0; -  assert (zfpm_g->state == ZFPM_STATE_ESTABLISHED); -  assert (zfpm_g->sock >= 0); +	do { +		int bytes_to_write, bytes_written; -  num_writes = 0; +		s = zfpm_g->obuf; -  do -    { -      int bytes_to_write, bytes_written; +		/* +		 * If the stream is empty, try fill it up with data. +		 */ +		if (stream_empty(s)) { +			zfpm_build_updates(); +		} -      s = zfpm_g->obuf; +		bytes_to_write = stream_get_endp(s) - stream_get_getp(s); +		if (!bytes_to_write) +			break; -      /* -       * If the stream is empty, try fill it up with data. -       */ -      if (stream_empty (s)) -	{ -	  zfpm_build_updates (); -	} +		bytes_written = +			write(zfpm_g->sock, STREAM_PNT(s), bytes_to_write); +		zfpm_g->stats.write_calls++; +		num_writes++; -      bytes_to_write = stream_get_endp (s) - stream_get_getp (s); -      if (!bytes_to_write) -	break; +		if (bytes_written < 0) { +			if (ERRNO_IO_RETRY(errno)) +				break; -      bytes_written = write (zfpm_g->sock, STREAM_PNT (s), bytes_to_write); -      zfpm_g->stats.write_calls++; -      num_writes++; +			zfpm_connection_down("failed to write to socket"); +			return 0; +		} -      if (bytes_written < 0) -	{ -	  if (ERRNO_IO_RETRY (errno)) -	    break; +		if (bytes_written != bytes_to_write) { -	  zfpm_connection_down ("failed to write to socket"); -	  return 0; -	} - -      if (bytes_written != bytes_to_write) -	{ +			/* +			 * Partial write. +			 */ +			stream_forward_getp(s, bytes_written); +			zfpm_g->stats.partial_writes++; +			break; +		} -	  /* -	   * Partial write. -	   */ -	  stream_forward_getp (s, bytes_written); -	  zfpm_g->stats.partial_writes++; -	  break; -	} - -      /* -       * We've written out the entire contents of the stream. -       */ -      stream_reset (s); +		/* +		 * We've written out the entire contents of the stream. +		 */ +		stream_reset(s); -      if (num_writes >= ZFPM_MAX_WRITES_PER_RUN) -	{ -	  zfpm_g->stats.max_writes_hit++; -	  break; -	} +		if (num_writes >= ZFPM_MAX_WRITES_PER_RUN) { +			zfpm_g->stats.max_writes_hit++; +			break; +		} -      if (zfpm_thread_should_yield (thread)) -	{ -	  zfpm_g->stats.t_write_yields++; -	  break; -	} -    } while (1); +		if (zfpm_thread_should_yield(thread)) { +			zfpm_g->stats.t_write_yields++; +			break; +		} +	} while (1); -  if (zfpm_writes_pending ()) -      zfpm_write_on (); +	if (zfpm_writes_pending()) +		zfpm_write_on(); -  return 0; +	return 0;  }  /*   * zfpm_connect_cb   */ -static int -zfpm_connect_cb (struct thread *t) +static int zfpm_connect_cb(struct thread *t)  { -  int sock, ret; -  struct sockaddr_in serv; - -  assert (zfpm_g->t_connect); -  zfpm_g->t_connect = NULL; -  assert (zfpm_g->state == ZFPM_STATE_ACTIVE); - -  sock = socket (AF_INET, SOCK_STREAM, 0); -  if (sock < 0) -    { -      zfpm_debug ("Failed to create socket for connect(): %s", strerror(errno)); -      zfpm_g->stats.connect_no_sock++; -      return 0; -    } - -  set_nonblocking(sock); - -  /* Make server socket. */ -  memset (&serv, 0, sizeof (serv)); -  serv.sin_family = AF_INET; -  serv.sin_port = htons (zfpm_g->fpm_port); +	int sock, ret; +	struct sockaddr_in serv; + +	assert(zfpm_g->t_connect); +	zfpm_g->t_connect = NULL; +	assert(zfpm_g->state == ZFPM_STATE_ACTIVE); + +	sock = socket(AF_INET, SOCK_STREAM, 0); +	if (sock < 0) { +		zfpm_debug("Failed to create socket for connect(): %s", +			   strerror(errno)); +		zfpm_g->stats.connect_no_sock++; +		return 0; +	} + +	set_nonblocking(sock); + +	/* Make server socket. */ +	memset(&serv, 0, sizeof(serv)); +	serv.sin_family = AF_INET; +	serv.sin_port = htons(zfpm_g->fpm_port);  #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN -  serv.sin_len = sizeof (struct sockaddr_in); +	serv.sin_len = sizeof(struct sockaddr_in);  #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ -  if (!zfpm_g->fpm_server) -    serv.sin_addr.s_addr = htonl (INADDR_LOOPBACK); -  else  -    serv.sin_addr.s_addr = (zfpm_g->fpm_server); - -  /* -   * Connect to the FPM. -   */ -  zfpm_g->connect_calls++; -  zfpm_g->stats.connect_calls++; -  zfpm_g->last_connect_call_time = monotime(NULL); - -  ret = connect (sock, (struct sockaddr *) &serv, sizeof (serv)); -  if (ret >= 0) -    { -      zfpm_g->sock = sock; -      zfpm_connection_up ("connect succeeded"); -      return 1; -    } - -  if (errno == EINPROGRESS) -    { -      zfpm_g->sock = sock; -      zfpm_read_on (); -      zfpm_write_on (); -      zfpm_set_state (ZFPM_STATE_CONNECTING, "async connect in progress"); -      return 0; -    } - -  zlog_info ("can't connect to FPM %d: %s", sock, safe_strerror (errno)); -  close (sock); - -  /* -   * Restart timer for retrying connection. -   */ -  zfpm_start_connect_timer ("connect() failed"); -  return 0; +	if (!zfpm_g->fpm_server) +		serv.sin_addr.s_addr = htonl(INADDR_LOOPBACK); +	else +		serv.sin_addr.s_addr = (zfpm_g->fpm_server); + +	/* +	 * Connect to the FPM. +	 */ +	zfpm_g->connect_calls++; +	zfpm_g->stats.connect_calls++; +	zfpm_g->last_connect_call_time = monotime(NULL); + +	ret = connect(sock, (struct sockaddr *)&serv, sizeof(serv)); +	if (ret >= 0) { +		zfpm_g->sock = sock; +		zfpm_connection_up("connect succeeded"); +		return 1; +	} + +	if (errno == EINPROGRESS) { +		zfpm_g->sock = sock; +		zfpm_read_on(); +		zfpm_write_on(); +		zfpm_set_state(ZFPM_STATE_CONNECTING, +			       "async connect in progress"); +		return 0; +	} + +	zlog_info("can't connect to FPM %d: %s", sock, safe_strerror(errno)); +	close(sock); + +	/* +	 * Restart timer for retrying connection. +	 */ +	zfpm_start_connect_timer("connect() failed"); +	return 0;  }  /* @@ -1202,50 +1143,49 @@ zfpm_connect_cb (struct thread *t)   *   * Move state machine into the given state.   */ -static void -zfpm_set_state (zfpm_state_t state, const char *reason) +static void zfpm_set_state(zfpm_state_t state, const char *reason)  { -  zfpm_state_t cur_state = zfpm_g->state; - -  if (!reason) -    reason = "Unknown"; - -  if (state == cur_state) -    return; - -  zfpm_debug("beginning state transition %s -> %s. Reason: %s", -	     zfpm_state_to_str (cur_state), zfpm_state_to_str (state), -	     reason); - -  switch (state) { - -  case ZFPM_STATE_IDLE: -    assert (cur_state == ZFPM_STATE_ESTABLISHED); -    break; - -  case ZFPM_STATE_ACTIVE: -     assert (cur_state == ZFPM_STATE_IDLE || -	     cur_state == ZFPM_STATE_CONNECTING); -    assert (zfpm_g->t_connect); -    break; - -  case ZFPM_STATE_CONNECTING: -    assert (zfpm_g->sock); -    assert (cur_state == ZFPM_STATE_ACTIVE); -    assert (zfpm_g->t_read); -    assert (zfpm_g->t_write); -    break; - -  case ZFPM_STATE_ESTABLISHED: -    assert (cur_state == ZFPM_STATE_ACTIVE || -	    cur_state == ZFPM_STATE_CONNECTING); -    assert (zfpm_g->sock); -    assert (zfpm_g->t_read); -    assert (zfpm_g->t_write); -    break; -  } - -  zfpm_g->state = state; +	zfpm_state_t cur_state = zfpm_g->state; + +	if (!reason) +		reason = "Unknown"; + +	if (state == cur_state) +		return; + +	zfpm_debug("beginning state transition %s -> %s. Reason: %s", +		   zfpm_state_to_str(cur_state), zfpm_state_to_str(state), +		   reason); + +	switch (state) { + +	case ZFPM_STATE_IDLE: +		assert(cur_state == ZFPM_STATE_ESTABLISHED); +		break; + +	case ZFPM_STATE_ACTIVE: +		assert(cur_state == ZFPM_STATE_IDLE +		       || cur_state == ZFPM_STATE_CONNECTING); +		assert(zfpm_g->t_connect); +		break; + +	case ZFPM_STATE_CONNECTING: +		assert(zfpm_g->sock); +		assert(cur_state == ZFPM_STATE_ACTIVE); +		assert(zfpm_g->t_read); +		assert(zfpm_g->t_write); +		break; + +	case ZFPM_STATE_ESTABLISHED: +		assert(cur_state == ZFPM_STATE_ACTIVE +		       || cur_state == ZFPM_STATE_CONNECTING); +		assert(zfpm_g->sock); +		assert(zfpm_g->t_read); +		assert(zfpm_g->t_write); +		break; +	} + +	zfpm_g->state = state;  }  /* @@ -1254,49 +1194,46 @@ zfpm_set_state (zfpm_state_t state, const char *reason)   * Returns the number of seconds after which we should attempt to   * reconnect to the FPM.   */ -static long -zfpm_calc_connect_delay (void) +static long zfpm_calc_connect_delay(void)  { -  time_t elapsed; +	time_t elapsed; -  /* -   * Return 0 if this is our first attempt to connect. -   */ -  if (zfpm_g->connect_calls == 0) -    { -      return 0; -    } +	/* +	 * Return 0 if this is our first attempt to connect. +	 */ +	if (zfpm_g->connect_calls == 0) { +		return 0; +	} -  elapsed = zfpm_get_elapsed_time (zfpm_g->last_connect_call_time); +	elapsed = zfpm_get_elapsed_time(zfpm_g->last_connect_call_time); -  if (elapsed > ZFPM_CONNECT_RETRY_IVL) { -    return 0; -  } +	if (elapsed > ZFPM_CONNECT_RETRY_IVL) { +		return 0; +	} -  return ZFPM_CONNECT_RETRY_IVL - elapsed; +	return ZFPM_CONNECT_RETRY_IVL - elapsed;  }  /*   * zfpm_start_connect_timer   */ -static void -zfpm_start_connect_timer (const char *reason) +static void zfpm_start_connect_timer(const char *reason)  { -  long delay_secs; +	long delay_secs; -  assert (!zfpm_g->t_connect); -  assert (zfpm_g->sock < 0); +	assert(!zfpm_g->t_connect); +	assert(zfpm_g->sock < 0); -  assert(zfpm_g->state == ZFPM_STATE_IDLE || -	 zfpm_g->state == ZFPM_STATE_ACTIVE || -	 zfpm_g->state == ZFPM_STATE_CONNECTING); +	assert(zfpm_g->state == ZFPM_STATE_IDLE +	       || zfpm_g->state == ZFPM_STATE_ACTIVE +	       || zfpm_g->state == ZFPM_STATE_CONNECTING); -  delay_secs = zfpm_calc_connect_delay(); -  zfpm_debug ("scheduling connect in %ld seconds", delay_secs); +	delay_secs = zfpm_calc_connect_delay(); +	zfpm_debug("scheduling connect in %ld seconds", delay_secs); -  THREAD_TIMER_ON (zfpm_g->master, zfpm_g->t_connect, zfpm_connect_cb, 0, -		   delay_secs); -  zfpm_set_state (ZFPM_STATE_ACTIVE, reason); +	THREAD_TIMER_ON(zfpm_g->master, zfpm_g->t_connect, zfpm_connect_cb, 0, +			delay_secs); +	zfpm_set_state(ZFPM_STATE_ACTIVE, reason);  }  /* @@ -1304,10 +1241,9 @@ zfpm_start_connect_timer (const char *reason)   *   * Returns TRUE if the zebra FPM module has been enabled.   */ -static inline int -zfpm_is_enabled (void) +static inline int zfpm_is_enabled(void)  { -  return zfpm_g->enabled; +	return zfpm_g->enabled;  }  /* @@ -1315,15 +1251,14 @@ zfpm_is_enabled (void)   *   * Returns TRUE if the connection to the FPM is up.   */ -static inline int -zfpm_conn_is_up (void) +static inline int zfpm_conn_is_up(void)  { -  if (zfpm_g->state != ZFPM_STATE_ESTABLISHED) -    return 0; +	if (zfpm_g->state != ZFPM_STATE_ESTABLISHED) +		return 0; -  assert (zfpm_g->sock >= 0); +	assert(zfpm_g->sock >= 0); -  return 1; +	return 1;  }  /* @@ -1332,195 +1267,188 @@ zfpm_conn_is_up (void)   * The zebra code invokes this function to indicate that we should   * send an update to the FPM about the given route_node.   */ -static int -zfpm_trigger_update (struct route_node *rn, const char *reason) +static int zfpm_trigger_update(struct route_node *rn, const char *reason)  { -  rib_dest_t *dest; -  char buf[PREFIX_STRLEN]; - -  /* -   * Ignore if the connection is down. We will update the FPM about -   * all destinations once the connection comes up. -   */ -  if (!zfpm_conn_is_up ()) -    return 0; - -  dest = rib_dest_from_rnode (rn); - -  /* -   * Ignore the trigger if the dest is not in a table that we would -   * send to the FPM. -   */ -  if (!zfpm_is_table_for_fpm (rib_dest_table (dest))) -    { -      zfpm_g->stats.non_fpm_table_triggers++; -      return 0; -    } - -  if (CHECK_FLAG (dest->flags, RIB_DEST_UPDATE_FPM)) { -    zfpm_g->stats.redundant_triggers++; -    return 0; -  } - -  if (reason) -    { -      zfpm_debug ("%s triggering update to FPM - Reason: %s", -		  prefix2str (&rn->p, buf, sizeof(buf)), reason); -    } - -  SET_FLAG (dest->flags, RIB_DEST_UPDATE_FPM); -  TAILQ_INSERT_TAIL (&zfpm_g->dest_q, dest, fpm_q_entries); -  zfpm_g->stats.updates_triggered++; - -  /* -   * Make sure that writes are enabled. -   */ -  if (zfpm_g->t_write) -    return 0; - -  zfpm_write_on (); -  return 0; +	rib_dest_t *dest; +	char buf[PREFIX_STRLEN]; + +	/* +	 * Ignore if the connection is down. We will update the FPM about +	 * all destinations once the connection comes up. +	 */ +	if (!zfpm_conn_is_up()) +		return 0; + +	dest = rib_dest_from_rnode(rn); + +	/* +	 * Ignore the trigger if the dest is not in a table that we would +	 * send to the FPM. +	 */ +	if (!zfpm_is_table_for_fpm(rib_dest_table(dest))) { +		zfpm_g->stats.non_fpm_table_triggers++; +		return 0; +	} + +	if (CHECK_FLAG(dest->flags, RIB_DEST_UPDATE_FPM)) { +		zfpm_g->stats.redundant_triggers++; +		return 0; +	} + +	if (reason) { +		zfpm_debug("%s triggering update to FPM - Reason: %s", +			   prefix2str(&rn->p, buf, sizeof(buf)), reason); +	} + +	SET_FLAG(dest->flags, RIB_DEST_UPDATE_FPM); +	TAILQ_INSERT_TAIL(&zfpm_g->dest_q, dest, fpm_q_entries); +	zfpm_g->stats.updates_triggered++; + +	/* +	 * Make sure that writes are enabled. +	 */ +	if (zfpm_g->t_write) +		return 0; + +	zfpm_write_on(); +	return 0;  }  /*   * zfpm_stats_timer_cb   */ -static int -zfpm_stats_timer_cb (struct thread *t) +static int zfpm_stats_timer_cb(struct thread *t)  { -  assert (zfpm_g->t_stats); -  zfpm_g->t_stats = NULL; +	assert(zfpm_g->t_stats); +	zfpm_g->t_stats = NULL; -  /* -   * Remember the stats collected in the last interval for display -   * purposes. -   */ -  zfpm_stats_copy (&zfpm_g->stats, &zfpm_g->last_ivl_stats); +	/* +	 * Remember the stats collected in the last interval for display +	 * purposes. +	 */ +	zfpm_stats_copy(&zfpm_g->stats, &zfpm_g->last_ivl_stats); -  /* -   * Add the current set of stats into the cumulative statistics. -   */ -  zfpm_stats_compose (&zfpm_g->cumulative_stats, &zfpm_g->stats, -		      &zfpm_g->cumulative_stats); +	/* +	 * Add the current set of stats into the cumulative statistics. +	 */ +	zfpm_stats_compose(&zfpm_g->cumulative_stats, &zfpm_g->stats, +			   &zfpm_g->cumulative_stats); -  /* -   * Start collecting stats afresh over the next interval. -   */ -  zfpm_stats_reset (&zfpm_g->stats); +	/* +	 * Start collecting stats afresh over the next interval. +	 */ +	zfpm_stats_reset(&zfpm_g->stats); -  zfpm_start_stats_timer (); +	zfpm_start_stats_timer(); -  return 0; +	return 0;  }  /*   * zfpm_stop_stats_timer   */ -static void -zfpm_stop_stats_timer (void) +static void zfpm_stop_stats_timer(void)  { -  if (!zfpm_g->t_stats) -    return; +	if (!zfpm_g->t_stats) +		return; -  zfpm_debug ("Stopping existing stats timer"); -  THREAD_TIMER_OFF (zfpm_g->t_stats); +	zfpm_debug("Stopping existing stats timer"); +	THREAD_TIMER_OFF(zfpm_g->t_stats);  }  /*   * zfpm_start_stats_timer   */ -void -zfpm_start_stats_timer (void) +void zfpm_start_stats_timer(void)  { -  assert (!zfpm_g->t_stats); +	assert(!zfpm_g->t_stats); -  THREAD_TIMER_ON (zfpm_g->master, zfpm_g->t_stats, zfpm_stats_timer_cb, 0, -		   ZFPM_STATS_IVL_SECS); +	THREAD_TIMER_ON(zfpm_g->master, zfpm_g->t_stats, zfpm_stats_timer_cb, 0, +			ZFPM_STATS_IVL_SECS);  }  /*   * Helper macro for zfpm_show_stats() below.   */ -#define ZFPM_SHOW_STAT(counter)						\ -  do {									\ -    vty_out (vty, "%-40s %10lu %16lu%s", #counter, total_stats.counter,	\ -	     zfpm_g->last_ivl_stats.counter, VTY_NEWLINE);		\ -  } while (0) +#define ZFPM_SHOW_STAT(counter)                                                \ +	do {                                                                   \ +		vty_out(vty, "%-40s %10lu %16lu%s", #counter,                  \ +			total_stats.counter, zfpm_g->last_ivl_stats.counter,   \ +			VTY_NEWLINE);                                          \ +	} while (0)  /*   * zfpm_show_stats   */ -static void -zfpm_show_stats (struct vty *vty) +static void zfpm_show_stats(struct vty *vty)  { -  zfpm_stats_t total_stats; -  time_t elapsed; - -  vty_out (vty, "%s%-40s %10s     Last %2d secs%s%s", VTY_NEWLINE, "Counter", -	   "Total", ZFPM_STATS_IVL_SECS, VTY_NEWLINE, VTY_NEWLINE); - -  /* -   * Compute the total stats up to this instant. -   */ -  zfpm_stats_compose (&zfpm_g->cumulative_stats, &zfpm_g->stats, -		      &total_stats); - -  ZFPM_SHOW_STAT (connect_calls); -  ZFPM_SHOW_STAT (connect_no_sock); -  ZFPM_SHOW_STAT (read_cb_calls); -  ZFPM_SHOW_STAT (write_cb_calls); -  ZFPM_SHOW_STAT (write_calls); -  ZFPM_SHOW_STAT (partial_writes); -  ZFPM_SHOW_STAT (max_writes_hit); -  ZFPM_SHOW_STAT (t_write_yields); -  ZFPM_SHOW_STAT (nop_deletes_skipped); -  ZFPM_SHOW_STAT (route_adds); -  ZFPM_SHOW_STAT (route_dels); -  ZFPM_SHOW_STAT (updates_triggered); -  ZFPM_SHOW_STAT (non_fpm_table_triggers); -  ZFPM_SHOW_STAT (redundant_triggers); -  ZFPM_SHOW_STAT (dests_del_after_update); -  ZFPM_SHOW_STAT (t_conn_down_starts); -  ZFPM_SHOW_STAT (t_conn_down_dests_processed); -  ZFPM_SHOW_STAT (t_conn_down_yields); -  ZFPM_SHOW_STAT (t_conn_down_finishes); -  ZFPM_SHOW_STAT (t_conn_up_starts); -  ZFPM_SHOW_STAT (t_conn_up_dests_processed); -  ZFPM_SHOW_STAT (t_conn_up_yields); -  ZFPM_SHOW_STAT (t_conn_up_aborts); -  ZFPM_SHOW_STAT (t_conn_up_finishes); - -  if (!zfpm_g->last_stats_clear_time) -    return; - -  elapsed = zfpm_get_elapsed_time (zfpm_g->last_stats_clear_time); - -  vty_out (vty, "%sStats were cleared %lu seconds ago%s", VTY_NEWLINE, -	   (unsigned long) elapsed, VTY_NEWLINE); +	zfpm_stats_t total_stats; +	time_t elapsed; + +	vty_out(vty, "%s%-40s %10s     Last %2d secs%s%s", VTY_NEWLINE, +		"Counter", "Total", ZFPM_STATS_IVL_SECS, VTY_NEWLINE, +		VTY_NEWLINE); + +	/* +	 * Compute the total stats up to this instant. +	 */ +	zfpm_stats_compose(&zfpm_g->cumulative_stats, &zfpm_g->stats, +			   &total_stats); + +	ZFPM_SHOW_STAT(connect_calls); +	ZFPM_SHOW_STAT(connect_no_sock); +	ZFPM_SHOW_STAT(read_cb_calls); +	ZFPM_SHOW_STAT(write_cb_calls); +	ZFPM_SHOW_STAT(write_calls); +	ZFPM_SHOW_STAT(partial_writes); +	ZFPM_SHOW_STAT(max_writes_hit); +	ZFPM_SHOW_STAT(t_write_yields); +	ZFPM_SHOW_STAT(nop_deletes_skipped); +	ZFPM_SHOW_STAT(route_adds); +	ZFPM_SHOW_STAT(route_dels); +	ZFPM_SHOW_STAT(updates_triggered); +	ZFPM_SHOW_STAT(non_fpm_table_triggers); +	ZFPM_SHOW_STAT(redundant_triggers); +	ZFPM_SHOW_STAT(dests_del_after_update); +	ZFPM_SHOW_STAT(t_conn_down_starts); +	ZFPM_SHOW_STAT(t_conn_down_dests_processed); +	ZFPM_SHOW_STAT(t_conn_down_yields); +	ZFPM_SHOW_STAT(t_conn_down_finishes); +	ZFPM_SHOW_STAT(t_conn_up_starts); +	ZFPM_SHOW_STAT(t_conn_up_dests_processed); +	ZFPM_SHOW_STAT(t_conn_up_yields); +	ZFPM_SHOW_STAT(t_conn_up_aborts); +	ZFPM_SHOW_STAT(t_conn_up_finishes); + +	if (!zfpm_g->last_stats_clear_time) +		return; + +	elapsed = zfpm_get_elapsed_time(zfpm_g->last_stats_clear_time); + +	vty_out(vty, "%sStats were cleared %lu seconds ago%s", VTY_NEWLINE, +		(unsigned long)elapsed, VTY_NEWLINE);  }  /*   * zfpm_clear_stats   */ -static void -zfpm_clear_stats (struct vty *vty) +static void zfpm_clear_stats(struct vty *vty)  { -  if (!zfpm_is_enabled ()) -    { -      vty_out (vty, "The FPM module is not enabled...%s", VTY_NEWLINE); -      return; -    } +	if (!zfpm_is_enabled()) { +		vty_out(vty, "The FPM module is not enabled...%s", VTY_NEWLINE); +		return; +	} -  zfpm_stats_reset (&zfpm_g->stats); -  zfpm_stats_reset (&zfpm_g->last_ivl_stats); -  zfpm_stats_reset (&zfpm_g->cumulative_stats); +	zfpm_stats_reset(&zfpm_g->stats); +	zfpm_stats_reset(&zfpm_g->last_ivl_stats); +	zfpm_stats_reset(&zfpm_g->cumulative_stats); -  zfpm_stop_stats_timer (); -  zfpm_start_stats_timer (); +	zfpm_stop_stats_timer(); +	zfpm_start_stats_timer(); -  zfpm_g->last_stats_clear_time = monotime(NULL); +	zfpm_g->last_stats_clear_time = monotime(NULL); -  vty_out (vty, "Cleared FPM stats%s", VTY_NEWLINE); +	vty_out(vty, "Cleared FPM stats%s", VTY_NEWLINE);  }  /* @@ -1534,8 +1462,8 @@ DEFUN (show_zebra_fpm_stats,         "Forwarding Path Manager information\n"         "Statistics\n")  { -  zfpm_show_stats (vty); -  return CMD_SUCCESS; +	zfpm_show_stats(vty); +	return CMD_SUCCESS;  }  /* @@ -1549,12 +1477,12 @@ DEFUN (clear_zebra_fpm_stats,         "Clear Forwarding Path Manager information\n"         "Statistics\n")  { -  zfpm_clear_stats (vty); -  return CMD_SUCCESS; +	zfpm_clear_stats(vty); +	return CMD_SUCCESS;  }  /* - * update fpm connection information  + * update fpm connection information   */  DEFUN ( fpm_remote_ip,         fpm_remote_ip_cmd, @@ -1564,22 +1492,22 @@ DEFUN ( fpm_remote_ip,          "Enter ip ")  { -   in_addr_t fpm_server; -   uint32_t port_no; +	in_addr_t fpm_server; +	uint32_t port_no; -   fpm_server = inet_addr (argv[3]->arg); -   if (fpm_server == INADDR_NONE) -     return CMD_ERR_INCOMPLETE; +	fpm_server = inet_addr(argv[3]->arg); +	if (fpm_server == INADDR_NONE) +		return CMD_ERR_INCOMPLETE; -   port_no = atoi (argv[5]->arg); -   if (port_no < TCP_MIN_PORT || port_no > TCP_MAX_PORT) -     return CMD_ERR_INCOMPLETE; +	port_no = atoi(argv[5]->arg); +	if (port_no < TCP_MIN_PORT || port_no > TCP_MAX_PORT) +		return CMD_ERR_INCOMPLETE; -   zfpm_g->fpm_server = fpm_server; -   zfpm_g->fpm_port = port_no; +	zfpm_g->fpm_server = fpm_server; +	zfpm_g->fpm_port = port_no; -   return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN ( no_fpm_remote_ip, @@ -1590,105 +1518,93 @@ DEFUN ( no_fpm_remote_ip,          "Remote fpm server ip A.B.C.D\n"          "Enter ip ")  { -   if (zfpm_g->fpm_server != inet_addr (argv[4]->arg) ||  -              zfpm_g->fpm_port !=  atoi (argv[6]->arg)) -       return CMD_ERR_NO_MATCH; +	if (zfpm_g->fpm_server != inet_addr(argv[4]->arg) +	    || zfpm_g->fpm_port != atoi(argv[6]->arg)) +		return CMD_ERR_NO_MATCH; -   zfpm_g->fpm_server = FPM_DEFAULT_IP; -   zfpm_g->fpm_port = FPM_DEFAULT_PORT; +	zfpm_g->fpm_server = FPM_DEFAULT_IP; +	zfpm_g->fpm_port = FPM_DEFAULT_PORT; -   return CMD_SUCCESS; +	return CMD_SUCCESS;  }  /*   * zfpm_init_message_format   */ -static inline void -zfpm_init_message_format (const char *format) +static inline void zfpm_init_message_format(const char *format)  { -  int have_netlink, have_protobuf; +	int have_netlink, have_protobuf;  #ifdef HAVE_NETLINK -  have_netlink = 1; +	have_netlink = 1;  #else -  have_netlink = 0; +	have_netlink = 0;  #endif  #ifdef HAVE_PROTOBUF -  have_protobuf = 1; +	have_protobuf = 1;  #else -  have_protobuf = 0; +	have_protobuf = 0;  #endif -  zfpm_g->message_format = ZFPM_MSG_FORMAT_NONE; +	zfpm_g->message_format = ZFPM_MSG_FORMAT_NONE; -  if (!format) -    { -      if (have_netlink) -	{ -	  zfpm_g->message_format = ZFPM_MSG_FORMAT_NETLINK; -	} -      else if (have_protobuf) -	{ -	  zfpm_g->message_format = ZFPM_MSG_FORMAT_PROTOBUF; +	if (!format) { +		if (have_netlink) { +			zfpm_g->message_format = ZFPM_MSG_FORMAT_NETLINK; +		} else if (have_protobuf) { +			zfpm_g->message_format = ZFPM_MSG_FORMAT_PROTOBUF; +		} +		return;  	} -      return; -    } -  if (!strcmp ("netlink", format)) -    { -      if (!have_netlink) -	{ -	  zlog_err ("FPM netlink message format is not available"); -	  return; +	if (!strcmp("netlink", format)) { +		if (!have_netlink) { +			zlog_err("FPM netlink message format is not available"); +			return; +		} +		zfpm_g->message_format = ZFPM_MSG_FORMAT_NETLINK; +		return;  	} -      zfpm_g->message_format = ZFPM_MSG_FORMAT_NETLINK; -      return; -    } -  if (!strcmp ("protobuf", format)) -    { -      if (!have_protobuf) -	{ -	  zlog_err ("FPM protobuf message format is not available"); -	  return; +	if (!strcmp("protobuf", format)) { +		if (!have_protobuf) { +			zlog_err( +				"FPM protobuf message format is not available"); +			return; +		} +		zfpm_g->message_format = ZFPM_MSG_FORMAT_PROTOBUF; +		return;  	} -      zfpm_g->message_format = ZFPM_MSG_FORMAT_PROTOBUF; -      return; -    } -  zlog_warn ("Unknown fpm format '%s'", format); +	zlog_warn("Unknown fpm format '%s'", format);  }  /** - * fpm_remote_srv_write  + * fpm_remote_srv_write   * - * Module to write remote fpm connection  + * Module to write remote fpm connection   *   * Returns ZERO on success.   */ -static int fpm_remote_srv_write (struct vty *vty) +static int fpm_remote_srv_write(struct vty *vty)  { -   struct in_addr in; +	struct in_addr in; -   in.s_addr = zfpm_g->fpm_server; +	in.s_addr = zfpm_g->fpm_server; -   if (zfpm_g->fpm_server != FPM_DEFAULT_IP ||  -          zfpm_g->fpm_port != FPM_DEFAULT_PORT) -      vty_out (vty,"fpm connection ip %s port %d%s", inet_ntoa (in),zfpm_g->fpm_port,VTY_NEWLINE); +	if (zfpm_g->fpm_server != FPM_DEFAULT_IP +	    || zfpm_g->fpm_port != FPM_DEFAULT_PORT) +		vty_out(vty, "fpm connection ip %s port %d%s", inet_ntoa(in), +			zfpm_g->fpm_port, VTY_NEWLINE); -   return 0; +	return 0;  }  /* Zebra node  */ -static struct cmd_node zebra_node = -{ -  ZEBRA_NODE, -  "", -  1 -}; +static struct cmd_node zebra_node = {ZEBRA_NODE, "", 1};  /** @@ -1702,66 +1618,61 @@ static struct cmd_node zebra_node =   *   * Returns TRUE on success.   */ -static int -zfpm_init (struct thread_master *master) +static int zfpm_init(struct thread_master *master)  { -  int enable = 1; -  uint16_t port = 0; -  const char *format = THIS_MODULE->load_args; +	int enable = 1; +	uint16_t port = 0; +	const char *format = THIS_MODULE->load_args; -  memset (zfpm_g, 0, sizeof (*zfpm_g)); -  zfpm_g->master = master; -  TAILQ_INIT(&zfpm_g->dest_q); -  zfpm_g->sock = -1; -  zfpm_g->state = ZFPM_STATE_IDLE; +	memset(zfpm_g, 0, sizeof(*zfpm_g)); +	zfpm_g->master = master; +	TAILQ_INIT(&zfpm_g->dest_q); +	zfpm_g->sock = -1; +	zfpm_g->state = ZFPM_STATE_IDLE; -  zfpm_stats_init (&zfpm_g->stats); -  zfpm_stats_init (&zfpm_g->last_ivl_stats); -  zfpm_stats_init (&zfpm_g->cumulative_stats); +	zfpm_stats_init(&zfpm_g->stats); +	zfpm_stats_init(&zfpm_g->last_ivl_stats); +	zfpm_stats_init(&zfpm_g->cumulative_stats); -  install_node (&zebra_node, fpm_remote_srv_write); -  install_element (ENABLE_NODE, &show_zebra_fpm_stats_cmd); -  install_element (ENABLE_NODE, &clear_zebra_fpm_stats_cmd); -  install_element (CONFIG_NODE, &fpm_remote_ip_cmd); -  install_element (CONFIG_NODE, &no_fpm_remote_ip_cmd); +	install_node(&zebra_node, fpm_remote_srv_write); +	install_element(ENABLE_NODE, &show_zebra_fpm_stats_cmd); +	install_element(ENABLE_NODE, &clear_zebra_fpm_stats_cmd); +	install_element(CONFIG_NODE, &fpm_remote_ip_cmd); +	install_element(CONFIG_NODE, &no_fpm_remote_ip_cmd); -  zfpm_init_message_format(format); +	zfpm_init_message_format(format); -  /* -   * Disable FPM interface if no suitable format is available. -   */ -  if (zfpm_g->message_format == ZFPM_MSG_FORMAT_NONE) -      enable = 0; +	/* +	 * Disable FPM interface if no suitable format is available. +	 */ +	if (zfpm_g->message_format == ZFPM_MSG_FORMAT_NONE) +		enable = 0; -  zfpm_g->enabled = enable; +	zfpm_g->enabled = enable; -  if (!zfpm_g->fpm_server) -     zfpm_g->fpm_server = FPM_DEFAULT_IP; +	if (!zfpm_g->fpm_server) +		zfpm_g->fpm_server = FPM_DEFAULT_IP; -  if (!port) -    port = FPM_DEFAULT_PORT; +	if (!port) +		port = FPM_DEFAULT_PORT; -  zfpm_g->fpm_port = port; +	zfpm_g->fpm_port = port; -  zfpm_g->obuf = stream_new (ZFPM_OBUF_SIZE); -  zfpm_g->ibuf = stream_new (ZFPM_IBUF_SIZE); +	zfpm_g->obuf = stream_new(ZFPM_OBUF_SIZE); +	zfpm_g->ibuf = stream_new(ZFPM_IBUF_SIZE); -  zfpm_start_stats_timer (); -  zfpm_start_connect_timer ("initialized"); -  return 0; +	zfpm_start_stats_timer(); +	zfpm_start_connect_timer("initialized"); +	return 0;  } -static int -zebra_fpm_module_init (void) +static int zebra_fpm_module_init(void)  { -  hook_register(rib_update, zfpm_trigger_update); -  hook_register(frr_late_init, zfpm_init); -  return 0; +	hook_register(rib_update, zfpm_trigger_update); +	hook_register(frr_late_init, zfpm_init); +	return 0;  } -FRR_MODULE_SETUP( -	.name = "zebra_fpm", -	.version = FRR_VERSION, -	.description = "zebra FPM (Forwarding Plane Manager) module", -	.init = zebra_fpm_module_init, -) +FRR_MODULE_SETUP(.name = "zebra_fpm", .version = FRR_VERSION, +		 .description = "zebra FPM (Forwarding Plane Manager) module", +		 .init = zebra_fpm_module_init, ) diff --git a/zebra/zebra_fpm_dt.c b/zebra/zebra_fpm_dt.c index 7b4e1b90dc..f520fd156f 100644 --- a/zebra/zebra_fpm_dt.c +++ b/zebra/zebra_fpm_dt.c @@ -58,85 +58,83 @@  /*   * Externs.   */ -extern int zfpm_dt_benchmark_netlink_encode (int argc, const char **argv); -extern int zfpm_dt_benchmark_protobuf_encode (int argc, const char **argv); -extern int zfpm_dt_benchmark_protobuf_decode (int argc, const char **argv); +extern int zfpm_dt_benchmark_netlink_encode(int argc, const char **argv); +extern int zfpm_dt_benchmark_protobuf_encode(int argc, const char **argv); +extern int zfpm_dt_benchmark_protobuf_decode(int argc, const char **argv);  /*   * zfpm_dt_find_route   *   * Selects a suitable rib destination for fpm interface tests.   */ -static int -zfpm_dt_find_route (rib_dest_t **dest_p, struct rib **rib_p) +static int zfpm_dt_find_route(rib_dest_t **dest_p, struct rib **rib_p)  { -  struct route_node *rnode; -  route_table_iter_t iter; -  struct route_table *table; -  rib_dest_t *dest; -  struct rib *rib; -  int ret; - -  table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT); -  if (!table) -    return 0; - -  route_table_iter_init(&iter, table); -  while ((rnode = route_table_iter_next(&iter))) -    { -      dest = rib_dest_from_rnode (rnode); - -      if (!dest) -	  continue; - -      rib = zfpm_route_for_update(dest); -      if (!rib) -	continue; - -      if (rib->nexthop_active_num <= 0) -	continue; - -      *dest_p = dest; -      *rib_p = rib; -      ret = 1; -      goto done; -    } - -    ret = 0; - -  done: -    route_table_iter_cleanup(&iter); -    return ret; +	struct route_node *rnode; +	route_table_iter_t iter; +	struct route_table *table; +	rib_dest_t *dest; +	struct rib *rib; +	int ret; + +	table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, VRF_DEFAULT); +	if (!table) +		return 0; + +	route_table_iter_init(&iter, table); +	while ((rnode = route_table_iter_next(&iter))) { +		dest = rib_dest_from_rnode(rnode); + +		if (!dest) +			continue; + +		rib = zfpm_route_for_update(dest); +		if (!rib) +			continue; + +		if (rib->nexthop_active_num <= 0) +			continue; + +		*dest_p = dest; +		*rib_p = rib; +		ret = 1; +		goto done; +	} + +	ret = 0; + +done: +	route_table_iter_cleanup(&iter); +	return ret;  }  #ifdef HAVE_NETLINK  /*   * zfpm_dt_benchmark_netlink_encode   */ -int -zfpm_dt_benchmark_netlink_encode (int argc, const char **argv) +int zfpm_dt_benchmark_netlink_encode(int argc, const char **argv)  { -  int times, i, len; -  rib_dest_t *dest; -  struct rib *rib; -  char buf[4096]; - -  times = 100000; -  if (argc > 0) { -    times = atoi(argv[0]); -  } - -  if (!zfpm_dt_find_route(&dest, &rib)) { -    return 1; -  } - -  for (i = 0; i < times; i++) { -    len = zfpm_netlink_encode_route(RTM_NEWROUTE, dest, rib, buf, sizeof(buf)); -    if (len <= 0) { -      return 2; -    } -  } -  return 0; +	int times, i, len; +	rib_dest_t *dest; +	struct rib *rib; +	char buf[4096]; + +	times = 100000; +	if (argc > 0) { +		times = atoi(argv[0]); +	} + +	if (!zfpm_dt_find_route(&dest, &rib)) { +		return 1; +	} + +	for (i = 0; i < times; i++) { +		len = zfpm_netlink_encode_route(RTM_NEWROUTE, dest, rib, buf, +						sizeof(buf)); +		if (len <= 0) { +			return 2; +		} +	} +	return 0;  }  #endif /* HAVE_NETLINK */ @@ -146,134 +144,129 @@ zfpm_dt_benchmark_netlink_encode (int argc, const char **argv)  /*   * zfpm_dt_benchmark_protobuf_encode   */ -int -zfpm_dt_benchmark_protobuf_encode (int argc, const char **argv) +int zfpm_dt_benchmark_protobuf_encode(int argc, const char **argv)  { -  int times, i, len; -  rib_dest_t *dest; -  struct rib *rib; -  uint8_t buf[4096]; - -  times = 100000; -  if (argc > 0) { -    times = atoi(argv[0]); -  } - -  if (!zfpm_dt_find_route(&dest, &rib)) { -    return 1; -  } - -  for (i = 0; i < times; i++) { -    len = zfpm_protobuf_encode_route(dest, rib, buf, sizeof(buf)); -    if (len <= 0) { -      return 2; -    } -  } -  return 0; +	int times, i, len; +	rib_dest_t *dest; +	struct rib *rib; +	uint8_t buf[4096]; + +	times = 100000; +	if (argc > 0) { +		times = atoi(argv[0]); +	} + +	if (!zfpm_dt_find_route(&dest, &rib)) { +		return 1; +	} + +	for (i = 0; i < times; i++) { +		len = zfpm_protobuf_encode_route(dest, rib, buf, sizeof(buf)); +		if (len <= 0) { +			return 2; +		} +	} +	return 0;  }  /*   * zfpm_dt_log_fpm_message   */ -static void -zfpm_dt_log_fpm_message (Fpm__Message *msg) +static void zfpm_dt_log_fpm_message(Fpm__Message *msg)  { -  Fpm__AddRoute *add_route; -  Fpm__Nexthop *nexthop; -  struct prefix prefix; -  u_char family, nh_family; -  uint if_index; -  char *if_name; -  size_t i; -  char buf[INET6_ADDRSTRLEN]; -  union g_addr nh_addr; - -  if (msg->type != FPM__MESSAGE__TYPE__ADD_ROUTE) -    return; - -  zfpm_debug ("Add route message"); -  add_route = msg->add_route; - -  if (!qpb_address_family_get (add_route->address_family, &family)) -    return; - -  if (!qpb_l3_prefix_get (add_route->key->prefix, family, &prefix)) -    return; - -  zfpm_debug ("Vrf id: %d, Prefix: %s/%d, Metric: %d", add_route->vrf_id, -	      inet_ntop (family, &prefix.u.prefix, buf, sizeof (buf)), -	      prefix.prefixlen, add_route->metric); - -  /* -   * Go over nexthops. -   */ -  for (i = 0; i < add_route->n_nexthops; i++) -    { -      nexthop = add_route->nexthops[i]; -      if (!qpb_if_identifier_get (nexthop->if_id, &if_index, &if_name)) -	continue; - -      if (nexthop->address) -	qpb_l3_address_get (nexthop->address, &nh_family, &nh_addr); - -      zfpm_debug ("Nexthop - if_index: %d (%s), gateway: %s, ", if_index, -		  if_name ? if_name : "name not specified", -		  nexthop->address ? inet_ntoa (nh_addr.ipv4) : "None"); -    } +	Fpm__AddRoute *add_route; +	Fpm__Nexthop *nexthop; +	struct prefix prefix; +	u_char family, nh_family; +	uint if_index; +	char *if_name; +	size_t i; +	char buf[INET6_ADDRSTRLEN]; +	union g_addr nh_addr; + +	if (msg->type != FPM__MESSAGE__TYPE__ADD_ROUTE) +		return; + +	zfpm_debug("Add route message"); +	add_route = msg->add_route; + +	if (!qpb_address_family_get(add_route->address_family, &family)) +		return; + +	if (!qpb_l3_prefix_get(add_route->key->prefix, family, &prefix)) +		return; + +	zfpm_debug("Vrf id: %d, Prefix: %s/%d, Metric: %d", add_route->vrf_id, +		   inet_ntop(family, &prefix.u.prefix, buf, sizeof(buf)), +		   prefix.prefixlen, add_route->metric); + +	/* +	 * Go over nexthops. +	 */ +	for (i = 0; i < add_route->n_nexthops; i++) { +		nexthop = add_route->nexthops[i]; +		if (!qpb_if_identifier_get(nexthop->if_id, &if_index, &if_name)) +			continue; + +		if (nexthop->address) +			qpb_l3_address_get(nexthop->address, &nh_family, +					   &nh_addr); + +		zfpm_debug("Nexthop - if_index: %d (%s), gateway: %s, ", +			   if_index, if_name ? if_name : "name not specified", +			   nexthop->address ? inet_ntoa(nh_addr.ipv4) : "None"); +	}  }  /*   * zfpm_dt_benchmark_protobuf_decode   */ -int -zfpm_dt_benchmark_protobuf_decode (int argc, const char **argv) +int zfpm_dt_benchmark_protobuf_decode(int argc, const char **argv)  { -  int times, i, len; -  rib_dest_t *dest; -  struct rib *rib; -  uint8_t msg_buf[4096]; -  QPB_DECLARE_STACK_ALLOCATOR (allocator, 8192); -  Fpm__Message *fpm_msg; - -  QPB_INIT_STACK_ALLOCATOR (allocator); - -  times = 100000; -  if (argc > 0) -    times = atoi(argv[0]); - -  if (!zfpm_dt_find_route (&dest, &rib)) -    return 1; - -  /* -   * Encode the route into the message buffer once only. -   */ -  len = zfpm_protobuf_encode_route (dest, rib, msg_buf, sizeof (msg_buf)); -  if (len <= 0) -    return 2; - -  // Decode once, and display the decoded message -  fpm_msg = fpm__message__unpack(&allocator, len, msg_buf); - -  if (fpm_msg) -    { -      zfpm_dt_log_fpm_message(fpm_msg); -      QPB_RESET_STACK_ALLOCATOR (allocator); -    } - -  /* -   * Decode encoded message the specified number of times. -   */ -  for (i = 0; i < times; i++) -    { -      fpm_msg = fpm__message__unpack (&allocator, len, msg_buf); - -      if (!fpm_msg) -	return 3; - -      // fpm__message__free_unpacked(msg, NULL); -      QPB_RESET_STACK_ALLOCATOR (allocator); -  } -  return 0; +	int times, i, len; +	rib_dest_t *dest; +	struct rib *rib; +	uint8_t msg_buf[4096]; +	QPB_DECLARE_STACK_ALLOCATOR(allocator, 8192); +	Fpm__Message *fpm_msg; + +	QPB_INIT_STACK_ALLOCATOR(allocator); + +	times = 100000; +	if (argc > 0) +		times = atoi(argv[0]); + +	if (!zfpm_dt_find_route(&dest, &rib)) +		return 1; + +	/* +	 * Encode the route into the message buffer once only. +	 */ +	len = zfpm_protobuf_encode_route(dest, rib, msg_buf, sizeof(msg_buf)); +	if (len <= 0) +		return 2; + +	// Decode once, and display the decoded message +	fpm_msg = fpm__message__unpack(&allocator, len, msg_buf); + +	if (fpm_msg) { +		zfpm_dt_log_fpm_message(fpm_msg); +		QPB_RESET_STACK_ALLOCATOR(allocator); +	} + +	/* +	 * Decode encoded message the specified number of times. +	 */ +	for (i = 0; i < times; i++) { +		fpm_msg = fpm__message__unpack(&allocator, len, msg_buf); + +		if (!fpm_msg) +			return 3; + +		// fpm__message__free_unpacked(msg, NULL); +		QPB_RESET_STACK_ALLOCATOR(allocator); +	} +	return 0;  }  #endif /* HAVE_PROTOBUF */ diff --git a/zebra/zebra_fpm_netlink.c b/zebra/zebra_fpm_netlink.c index 92ab5df2c3..060cb693eb 100644 --- a/zebra/zebra_fpm_netlink.c +++ b/zebra/zebra_fpm_netlink.c @@ -44,25 +44,23 @@   *   * Returns string representation of an address of the given AF.   */ -static inline const char * -addr_to_a (u_char af, void *addr) +static inline const char *addr_to_a(u_char af, void *addr)  { -  if (!addr) -    return "<No address>"; - -  switch (af) -    { - -    case AF_INET: -      return inet_ntoa (*((struct in_addr *) addr)); -      break; -    case AF_INET6: -      return inet6_ntoa (*((struct in6_addr *) addr)); -      break; -    default: -      return "<Addr in unknown AF>"; -      break; -    } +	if (!addr) +		return "<No address>"; + +	switch (af) { + +	case AF_INET: +		return inet_ntoa(*((struct in_addr *)addr)); +		break; +	case AF_INET6: +		return inet6_ntoa(*((struct in6_addr *)addr)); +		break; +	default: +		return "<Addr in unknown AF>"; +		break; +	}  }  /* @@ -71,13 +69,12 @@ addr_to_a (u_char af, void *addr)   * Convience wrapper that returns a human-readable string for the   * address in a prefix.   */ -static const char * -prefix_addr_to_a (struct prefix *prefix) +static const char *prefix_addr_to_a(struct prefix *prefix)  { -  if (!prefix) -    return "<No address>"; +	if (!prefix) +		return "<No address>"; -  return addr_to_a (prefix->family, &prefix->u.prefix); +	return addr_to_a(prefix->family, &prefix->u.prefix);  }  /* @@ -85,22 +82,20 @@ prefix_addr_to_a (struct prefix *prefix)   *   * The size of an address in a given address family.   */ -static size_t -af_addr_size (u_char af) +static size_t af_addr_size(u_char af)  { -  switch (af) -    { - -    case AF_INET: -      return 4; -      break; -    case AF_INET6: -      return 16; -      break; -    default: -      assert(0); -      return 16; -    } +	switch (af) { + +	case AF_INET: +		return 4; +		break; +	case AF_INET6: +		return 16; +		break; +	default: +		assert(0); +		return 16; +	}  }  /* @@ -110,17 +105,16 @@ af_addr_size (u_char af)   * structures are transient and may contain pointers into rib   * data structures for convenience.   */ -typedef struct netlink_nh_info_t_ -{ -  uint32_t if_index; -  union g_addr *gateway; - -  /* -   * Information from the struct nexthop from which this nh was -   * derived. For debug purposes only. -   */ -  int recursive; -  enum nexthop_types_t type; +typedef struct netlink_nh_info_t_ { +	uint32_t if_index; +	union g_addr *gateway; + +	/* +	 * Information from the struct nexthop from which this nh was +	 * derived. For debug purposes only. +	 */ +	int recursive; +	enum nexthop_types_t type;  } netlink_nh_info_t;  /* @@ -128,22 +122,21 @@ typedef struct netlink_nh_info_t_   *   * A structure for holding information for a netlink route message.   */ -typedef struct netlink_route_info_t_ -{ -  uint16_t nlmsg_type; -  u_char rtm_type; -  uint32_t rtm_table; -  u_char rtm_protocol; -  u_char af; -  struct prefix *prefix; -  uint32_t *metric; -  unsigned int num_nhs; - -  /* -   * Nexthop structures -   */ -  netlink_nh_info_t nhs[MULTIPATH_NUM]; -  union g_addr *pref_src; +typedef struct netlink_route_info_t_ { +	uint16_t nlmsg_type; +	u_char rtm_type; +	uint32_t rtm_table; +	u_char rtm_protocol; +	u_char af; +	struct prefix *prefix; +	uint32_t *metric; +	unsigned int num_nhs; + +	/* +	 * Nexthop structures +	 */ +	netlink_nh_info_t nhs[MULTIPATH_NUM]; +	union g_addr *pref_src;  } netlink_route_info_t;  /* @@ -154,73 +147,67 @@ typedef struct netlink_route_info_t_   *   * Returns TRUE if a nexthop was added, FALSE otherwise.   */ -static int -netlink_route_info_add_nh (netlink_route_info_t *ri, struct nexthop *nexthop, -			   int recursive) +static int netlink_route_info_add_nh(netlink_route_info_t *ri, +				     struct nexthop *nexthop, int recursive)  { -  netlink_nh_info_t nhi; -  union g_addr *src; - -  memset (&nhi, 0, sizeof (nhi)); -  src = NULL; - -  if (ri->num_nhs >= (int) ZEBRA_NUM_OF (ri->nhs)) -    return 0; - -  nhi.recursive = recursive; -  nhi.type = nexthop->type; -  nhi.if_index = nexthop->ifindex; - -  if (nexthop->type == NEXTHOP_TYPE_IPV4 -      || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) -    { -      nhi.gateway = &nexthop->gate; -      if (nexthop->src.ipv4.s_addr) -	src = &nexthop->src; -    } - -  if (nexthop->type == NEXTHOP_TYPE_IPV6 -      || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) -    { -      nhi.gateway = &nexthop->gate; -    } - -  if (nexthop->type == NEXTHOP_TYPE_IFINDEX) -    { -      if (nexthop->src.ipv4.s_addr) -	src = &nexthop->src; -    } - -  if (!nhi.gateway && nhi.if_index == 0) -    return 0; - -  /* -   * We have a valid nhi. Copy the structure over to the route_info. -   */ -  ri->nhs[ri->num_nhs] = nhi; -  ri->num_nhs++; - -  if (src && !ri->pref_src) -    ri->pref_src = src; - -  return 1; +	netlink_nh_info_t nhi; +	union g_addr *src; + +	memset(&nhi, 0, sizeof(nhi)); +	src = NULL; + +	if (ri->num_nhs >= (int)ZEBRA_NUM_OF(ri->nhs)) +		return 0; + +	nhi.recursive = recursive; +	nhi.type = nexthop->type; +	nhi.if_index = nexthop->ifindex; + +	if (nexthop->type == NEXTHOP_TYPE_IPV4 +	    || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) { +		nhi.gateway = &nexthop->gate; +		if (nexthop->src.ipv4.s_addr) +			src = &nexthop->src; +	} + +	if (nexthop->type == NEXTHOP_TYPE_IPV6 +	    || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) { +		nhi.gateway = &nexthop->gate; +	} + +	if (nexthop->type == NEXTHOP_TYPE_IFINDEX) { +		if (nexthop->src.ipv4.s_addr) +			src = &nexthop->src; +	} + +	if (!nhi.gateway && nhi.if_index == 0) +		return 0; + +	/* +	 * We have a valid nhi. Copy the structure over to the route_info. +	 */ +	ri->nhs[ri->num_nhs] = nhi; +	ri->num_nhs++; + +	if (src && !ri->pref_src) +		ri->pref_src = src; + +	return 1;  }  /*   * netlink_proto_from_route_type   */ -static u_char -netlink_proto_from_route_type (int type) +static u_char netlink_proto_from_route_type(int type)  { -  switch (type) -    { -    case ZEBRA_ROUTE_KERNEL: -    case ZEBRA_ROUTE_CONNECT: -      return RTPROT_KERNEL; - -    default: -      return RTPROT_ZEBRA; -    } +	switch (type) { +	case ZEBRA_ROUTE_KERNEL: +	case ZEBRA_ROUTE_CONNECT: +		return RTPROT_KERNEL; + +	default: +		return RTPROT_ZEBRA; +	}  }  /* @@ -230,88 +217,82 @@ netlink_proto_from_route_type (int type)   *   * Returns TRUE on success and FALSE on failure.   */ -static int -netlink_route_info_fill (netlink_route_info_t *ri, int cmd, -			 rib_dest_t *dest, struct rib *rib) +static int netlink_route_info_fill(netlink_route_info_t *ri, int cmd, +				   rib_dest_t *dest, struct rib *rib)  { -  struct nexthop *nexthop, *tnexthop; -  int recursing; -  int discard; - -  memset (ri, 0, sizeof (*ri)); - -  ri->prefix = rib_dest_prefix (dest); -  ri->af = rib_dest_af (dest); - -  ri->nlmsg_type = cmd; -  ri->rtm_table = zvrf_id (rib_dest_vrf (dest)); -  ri->rtm_protocol = RTPROT_UNSPEC; - -  /* -   * An RTM_DELROUTE need not be accompanied by any nexthops, -   * particularly in our communication with the FPM. -   */ -  if (cmd == RTM_DELROUTE && !rib) -    return 1; - -  if (!rib) -    { -      zfpm_debug ("%s: Expected non-NULL rib pointer", __PRETTY_FUNCTION__); -      return 0; -    } - -  ri->rtm_protocol = netlink_proto_from_route_type (rib->type); - -  if ((rib->flags & ZEBRA_FLAG_BLACKHOLE) || (rib->flags & ZEBRA_FLAG_REJECT)) -    discard = 1; -  else -    discard = 0; - -  if (cmd == RTM_NEWROUTE) -    { -      if (discard) -        { -          if (rib->flags & ZEBRA_FLAG_BLACKHOLE) -            ri->rtm_type = RTN_BLACKHOLE; -          else if (rib->flags & ZEBRA_FLAG_REJECT) -            ri->rtm_type = RTN_UNREACHABLE; -          else -            assert (0); -        } -      else -        ri->rtm_type = RTN_UNICAST; -    } - -  ri->metric = &rib->metric; - -  if (discard) -    return 1; - -  for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) -    { -      if (ri->num_nhs >= multipath_num) -        break; - -      if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) -        continue; - -      if ((cmd == RTM_NEWROUTE -           && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) -          || (cmd == RTM_DELROUTE -              && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB))) -        { -          netlink_route_info_add_nh (ri, nexthop, recursing); -        } -    } - -  /* If there is no useful nexthop then return. */ -  if (ri->num_nhs == 0) -    { -      zfpm_debug ("netlink_encode_route(): No useful nexthop."); -      return 0; -    } - -  return 1; +	struct nexthop *nexthop, *tnexthop; +	int recursing; +	int discard; + +	memset(ri, 0, sizeof(*ri)); + +	ri->prefix = rib_dest_prefix(dest); +	ri->af = rib_dest_af(dest); + +	ri->nlmsg_type = cmd; +	ri->rtm_table = zvrf_id(rib_dest_vrf(dest)); +	ri->rtm_protocol = RTPROT_UNSPEC; + +	/* +	 * An RTM_DELROUTE need not be accompanied by any nexthops, +	 * particularly in our communication with the FPM. +	 */ +	if (cmd == RTM_DELROUTE && !rib) +		return 1; + +	if (!rib) { +		zfpm_debug("%s: Expected non-NULL rib pointer", +			   __PRETTY_FUNCTION__); +		return 0; +	} + +	ri->rtm_protocol = netlink_proto_from_route_type(rib->type); + +	if ((rib->flags & ZEBRA_FLAG_BLACKHOLE) +	    || (rib->flags & ZEBRA_FLAG_REJECT)) +		discard = 1; +	else +		discard = 0; + +	if (cmd == RTM_NEWROUTE) { +		if (discard) { +			if (rib->flags & ZEBRA_FLAG_BLACKHOLE) +				ri->rtm_type = RTN_BLACKHOLE; +			else if (rib->flags & ZEBRA_FLAG_REJECT) +				ri->rtm_type = RTN_UNREACHABLE; +			else +				assert(0); +		} else +			ri->rtm_type = RTN_UNICAST; +	} + +	ri->metric = &rib->metric; + +	if (discard) +		return 1; + +	for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) { +		if (ri->num_nhs >= multipath_num) +			break; + +		if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) +			continue; + +		if ((cmd == RTM_NEWROUTE +		     && CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) +		    || (cmd == RTM_DELROUTE +			&& CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))) { +			netlink_route_info_add_nh(ri, nexthop, recursing); +		} +	} + +	/* If there is no useful nexthop then return. */ +	if (ri->num_nhs == 0) { +		zfpm_debug("netlink_encode_route(): No useful nexthop."); +		return 0; +	} + +	return 1;  }  /* @@ -320,122 +301,114 @@ netlink_route_info_fill (netlink_route_info_t *ri, int cmd,   * Returns the number of bytes written to the buffer. 0 or a negative   * value indicates an error.   */ -static int -netlink_route_info_encode (netlink_route_info_t *ri, char *in_buf, -			   size_t in_buf_len) +static int netlink_route_info_encode(netlink_route_info_t *ri, char *in_buf, +				     size_t in_buf_len)  { -  size_t bytelen; -  unsigned int nexthop_num = 0; -  size_t buf_offset; -  netlink_nh_info_t *nhi; - -  struct -  { -    struct nlmsghdr n; -    struct rtmsg r; -    char buf[1]; -  } *req; - -  req = (void *) in_buf; +	size_t bytelen; +	unsigned int nexthop_num = 0; +	size_t buf_offset; +	netlink_nh_info_t *nhi; -  buf_offset = ((char *) req->buf) - ((char *) req); +	struct { +		struct nlmsghdr n; +		struct rtmsg r; +		char buf[1]; +	} * req; -  if (in_buf_len < buf_offset) { -    assert(0); -    return 0; -  } +	req = (void *)in_buf; -  memset (req, 0, buf_offset); +	buf_offset = ((char *)req->buf) - ((char *)req); -  bytelen = af_addr_size (ri->af); - -  req->n.nlmsg_len = NLMSG_LENGTH (sizeof (struct rtmsg)); -  req->n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST; -  req->n.nlmsg_type = ri->nlmsg_type; -  req->r.rtm_family = ri->af; -  req->r.rtm_table = ri->rtm_table; -  req->r.rtm_dst_len = ri->prefix->prefixlen; -  req->r.rtm_protocol = ri->rtm_protocol; -  req->r.rtm_scope = RT_SCOPE_UNIVERSE; - -  addattr_l (&req->n, in_buf_len, RTA_DST, &ri->prefix->u.prefix, bytelen); - -  req->r.rtm_type = ri->rtm_type; - -  /* Metric. */ -  if (ri->metric) -    addattr32 (&req->n, in_buf_len, RTA_PRIORITY, *ri->metric); +	if (in_buf_len < buf_offset) { +		assert(0); +		return 0; +	} -  if (ri->num_nhs == 0) -    goto done; +	memset(req, 0, buf_offset); -  if (ri->num_nhs == 1) -    { -      nhi = &ri->nhs[0]; +	bytelen = af_addr_size(ri->af); -      if (nhi->gateway) -	{ -	  addattr_l (&req->n, in_buf_len, RTA_GATEWAY, nhi->gateway, -		     bytelen); -	} +	req->n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); +	req->n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST; +	req->n.nlmsg_type = ri->nlmsg_type; +	req->r.rtm_family = ri->af; +	req->r.rtm_table = ri->rtm_table; +	req->r.rtm_dst_len = ri->prefix->prefixlen; +	req->r.rtm_protocol = ri->rtm_protocol; +	req->r.rtm_scope = RT_SCOPE_UNIVERSE; -      if (nhi->if_index) -	{ -	  addattr32 (&req->n, in_buf_len, RTA_OIF, nhi->if_index); -	} +	addattr_l(&req->n, in_buf_len, RTA_DST, &ri->prefix->u.prefix, bytelen); -      goto done; +	req->r.rtm_type = ri->rtm_type; -    } +	/* Metric. */ +	if (ri->metric) +		addattr32(&req->n, in_buf_len, RTA_PRIORITY, *ri->metric); -  /* -   * Multipath case. -   */ -  char buf[NL_PKT_BUF_SIZE]; -  struct rtattr *rta = (void *) buf; -  struct rtnexthop *rtnh; +	if (ri->num_nhs == 0) +		goto done; -  rta->rta_type = RTA_MULTIPATH; -  rta->rta_len = RTA_LENGTH (0); -  rtnh = RTA_DATA (rta); +	if (ri->num_nhs == 1) { +		nhi = &ri->nhs[0]; -  for (nexthop_num = 0; nexthop_num < ri->num_nhs; nexthop_num++) -    { -      nhi = &ri->nhs[nexthop_num]; +		if (nhi->gateway) { +			addattr_l(&req->n, in_buf_len, RTA_GATEWAY, +				  nhi->gateway, bytelen); +		} -      rtnh->rtnh_len = sizeof (*rtnh); -      rtnh->rtnh_flags = 0; -      rtnh->rtnh_hops = 0; -      rtnh->rtnh_ifindex = 0; -      rta->rta_len += rtnh->rtnh_len; +		if (nhi->if_index) { +			addattr32(&req->n, in_buf_len, RTA_OIF, nhi->if_index); +		} -      if (nhi->gateway) -	{ -	  rta_addattr_l (rta, sizeof (buf), RTA_GATEWAY, nhi->gateway, bytelen); -	  rtnh->rtnh_len += sizeof (struct rtattr) + bytelen; +		goto done;  	} -      if (nhi->if_index) -	{ -	  rtnh->rtnh_ifindex = nhi->if_index; +	/* +	 * Multipath case. +	 */ +	char buf[NL_PKT_BUF_SIZE]; +	struct rtattr *rta = (void *)buf; +	struct rtnexthop *rtnh; + +	rta->rta_type = RTA_MULTIPATH; +	rta->rta_len = RTA_LENGTH(0); +	rtnh = RTA_DATA(rta); + +	for (nexthop_num = 0; nexthop_num < ri->num_nhs; nexthop_num++) { +		nhi = &ri->nhs[nexthop_num]; + +		rtnh->rtnh_len = sizeof(*rtnh); +		rtnh->rtnh_flags = 0; +		rtnh->rtnh_hops = 0; +		rtnh->rtnh_ifindex = 0; +		rta->rta_len += rtnh->rtnh_len; + +		if (nhi->gateway) { +			rta_addattr_l(rta, sizeof(buf), RTA_GATEWAY, +				      nhi->gateway, bytelen); +			rtnh->rtnh_len += sizeof(struct rtattr) + bytelen; +		} + +		if (nhi->if_index) { +			rtnh->rtnh_ifindex = nhi->if_index; +		} + +		rtnh = RTNH_NEXT(rtnh);  	} -      rtnh = RTNH_NEXT (rtnh); -    } - -  assert (rta->rta_len > RTA_LENGTH (0)); -  addattr_l (&req->n, in_buf_len, RTA_MULTIPATH, RTA_DATA (rta), -	     RTA_PAYLOAD (rta)); +	assert(rta->rta_len > RTA_LENGTH(0)); +	addattr_l(&req->n, in_buf_len, RTA_MULTIPATH, RTA_DATA(rta), +		  RTA_PAYLOAD(rta));  done: -  if (ri->pref_src) -    { -      addattr_l (&req->n, in_buf_len, RTA_PREFSRC, &ri->pref_src, bytelen); -    } +	if (ri->pref_src) { +		addattr_l(&req->n, in_buf_len, RTA_PREFSRC, &ri->pref_src, +			  bytelen); +	} -  assert (req->n.nlmsg_len < in_buf_len); -  return req->n.nlmsg_len; +	assert(req->n.nlmsg_len < in_buf_len); +	return req->n.nlmsg_len;  }  /* @@ -443,26 +416,24 @@ done:   *   * Helper function to log the information in a route_info structure.   */ -static void -zfpm_log_route_info (netlink_route_info_t *ri, const char *label) +static void zfpm_log_route_info(netlink_route_info_t *ri, const char *label)  { -  netlink_nh_info_t *nhi; -  unsigned int i; - -  zfpm_debug ("%s : %s %s/%d, Proto: %s, Metric: %u", label, -	      nl_msg_type_to_str (ri->nlmsg_type), -	      prefix_addr_to_a (ri->prefix), ri->prefix->prefixlen, -	      nl_rtproto_to_str (ri->rtm_protocol), -	      ri->metric ? *ri->metric : 0); - -  for (i = 0; i < ri->num_nhs; i++) -    { -      nhi = &ri->nhs[i]; -      zfpm_debug("  Intf: %u, Gateway: %s, Recursive: %s, Type: %s", -		 nhi->if_index, addr_to_a (ri->af, nhi->gateway), -		 nhi->recursive ? "yes" : "no", -		 nexthop_type_to_str (nhi->type)); -    } +	netlink_nh_info_t *nhi; +	unsigned int i; + +	zfpm_debug("%s : %s %s/%d, Proto: %s, Metric: %u", label, +		   nl_msg_type_to_str(ri->nlmsg_type), +		   prefix_addr_to_a(ri->prefix), ri->prefix->prefixlen, +		   nl_rtproto_to_str(ri->rtm_protocol), +		   ri->metric ? *ri->metric : 0); + +	for (i = 0; i < ri->num_nhs; i++) { +		nhi = &ri->nhs[i]; +		zfpm_debug("  Intf: %u, Gateway: %s, Recursive: %s, Type: %s", +			   nhi->if_index, addr_to_a(ri->af, nhi->gateway), +			   nhi->recursive ? "yes" : "no", +			   nexthop_type_to_str(nhi->type)); +	}  }  /* @@ -474,18 +445,17 @@ zfpm_log_route_info (netlink_route_info_t *ri, const char *label)   * Returns the number of bytes written to the buffer. 0 or a negative   * value indicates an error.   */ -int -zfpm_netlink_encode_route (int cmd, rib_dest_t *dest, struct rib *rib, -			   char *in_buf, size_t in_buf_len) +int zfpm_netlink_encode_route(int cmd, rib_dest_t *dest, struct rib *rib, +			      char *in_buf, size_t in_buf_len)  { -  netlink_route_info_t ri_space, *ri; +	netlink_route_info_t ri_space, *ri; -  ri = &ri_space; +	ri = &ri_space; -  if (!netlink_route_info_fill (ri, cmd, dest, rib)) -    return 0; +	if (!netlink_route_info_fill(ri, cmd, dest, rib)) +		return 0; -  zfpm_log_route_info (ri, __FUNCTION__); +	zfpm_log_route_info(ri, __FUNCTION__); -  return netlink_route_info_encode (ri, in_buf, in_buf_len); +	return netlink_route_info_encode(ri, in_buf, in_buf_len);  } diff --git a/zebra/zebra_fpm_private.h b/zebra/zebra_fpm_private.h index 1c4fd4c22f..b9946ebf0b 100644 --- a/zebra/zebra_fpm_private.h +++ b/zebra/zebra_fpm_private.h @@ -29,33 +29,36 @@  #if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L -#define zfpm_debug(...)						\ -  do {								\ -    if (IS_ZEBRA_DEBUG_FPM) zlog_debug("FPM: " __VA_ARGS__);	\ -  } while(0) +#define zfpm_debug(...)                                                        \ +	do {                                                                   \ +		if (IS_ZEBRA_DEBUG_FPM)                                        \ +			zlog_debug("FPM: " __VA_ARGS__);                       \ +	} while (0)  #elif defined __GNUC__ -#define zfpm_debug(_args...)				\ -  do {							\ -    if (IS_ZEBRA_DEBUG_FPM) zlog_debug("FPM: " _args);	\ -  } while(0) +#define zfpm_debug(_args...)                                                   \ +	do {                                                                   \ +		if (IS_ZEBRA_DEBUG_FPM)                                        \ +			zlog_debug("FPM: " _args);                             \ +	} while (0)  #else -static inline void zfpm_debug(const char *format, ...) { return; } +static inline void zfpm_debug(const char *format, ...) +{ +	return; +}  #endif  /*   * Externs   */ -extern int -zfpm_netlink_encode_route (int cmd, rib_dest_t *dest, struct rib *rib, -			   char *in_buf, size_t in_buf_len); +extern int zfpm_netlink_encode_route(int cmd, rib_dest_t *dest, struct rib *rib, +				     char *in_buf, size_t in_buf_len); -extern int -zfpm_protobuf_encode_route (rib_dest_t *dest, struct rib *rib, -			    uint8_t *in_buf, size_t in_buf_len); +extern int zfpm_protobuf_encode_route(rib_dest_t *dest, struct rib *rib, +				      uint8_t *in_buf, size_t in_buf_len); -extern struct rib *zfpm_route_for_update (rib_dest_t *dest); +extern struct rib *zfpm_route_for_update(rib_dest_t *dest);  #endif /* _ZEBRA_FPM_PRIVATE_H */ diff --git a/zebra/zebra_fpm_protobuf.c b/zebra/zebra_fpm_protobuf.c index 11869d8a2b..9deed42f34 100644 --- a/zebra/zebra_fpm_protobuf.c +++ b/zebra/zebra_fpm_protobuf.c @@ -40,242 +40,237 @@  /*   * create_delete_route_message   */ -static Fpm__DeleteRoute * -create_delete_route_message (qpb_allocator_t *allocator, rib_dest_t *dest, -			     struct rib *rib) +static Fpm__DeleteRoute *create_delete_route_message(qpb_allocator_t *allocator, +						     rib_dest_t *dest, +						     struct rib *rib)  { -  Fpm__DeleteRoute *msg; - -  msg = QPB_ALLOC(allocator, typeof(*msg)); -  if (!msg) { -    assert(0); -    return NULL; -  } - -  fpm__delete_route__init(msg); -  msg->vrf_id = zvrf_id(rib_dest_vrf(dest)); - -  qpb_address_family_set(&msg->address_family, rib_dest_af(dest)); - -  /* -   * XXX Hardcode subaddress family for now. -   */ -  msg->sub_address_family = QPB__SUB_ADDRESS_FAMILY__UNICAST; -  msg->key = fpm_route_key_create (allocator, rib_dest_prefix(dest)); -  if (!msg->key) { -    assert(0); -    return NULL; -  } - -  return msg; +	Fpm__DeleteRoute *msg; + +	msg = QPB_ALLOC(allocator, typeof(*msg)); +	if (!msg) { +		assert(0); +		return NULL; +	} + +	fpm__delete_route__init(msg); +	msg->vrf_id = zvrf_id(rib_dest_vrf(dest)); + +	qpb_address_family_set(&msg->address_family, rib_dest_af(dest)); + +	/* +	 * XXX Hardcode subaddress family for now. +	 */ +	msg->sub_address_family = QPB__SUB_ADDRESS_FAMILY__UNICAST; +	msg->key = fpm_route_key_create(allocator, rib_dest_prefix(dest)); +	if (!msg->key) { +		assert(0); +		return NULL; +	} + +	return msg;  }  /*   * add_nexthop   */ -static inline int -add_nexthop (qpb_allocator_t *allocator, Fpm__AddRoute *msg, rib_dest_t *dest, -	     struct nexthop *nexthop) +static inline int add_nexthop(qpb_allocator_t *allocator, Fpm__AddRoute *msg, +			      rib_dest_t *dest, struct nexthop *nexthop)  { -  uint32_t if_index; -  union g_addr *gateway, *src; - -  gateway = src = NULL; - -  if_index = nexthop->ifindex; - -  if (nexthop->type == NEXTHOP_TYPE_IPV4 -      || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) -    { -      gateway = &nexthop->gate; -      if (nexthop->src.ipv4.s_addr) -	src = &nexthop->src; -    } - -  if (nexthop->type == NEXTHOP_TYPE_IPV6 -      || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) -    { -      gateway = &nexthop->gate; -    } - -  if (nexthop->type == NEXTHOP_TYPE_IFINDEX) -    { -      if (nexthop->src.ipv4.s_addr) -	src = &nexthop->src; -    } - -  if (!gateway && if_index == 0) -    return 0; - -  /* -   * We have a valid nexthop. -   */ -  { -    Fpm__Nexthop *pb_nh; -    pb_nh = QPB_ALLOC(allocator, typeof(*pb_nh)); -    if (!pb_nh) { -      assert(0); -      return 0; -    } - -    fpm__nexthop__init(pb_nh); - -    if (if_index != 0) { -      pb_nh->if_id = qpb_if_identifier_create (allocator, if_index); -    } - -    if (gateway) { -      pb_nh->address = qpb_l3_address_create (allocator, gateway, -					      rib_dest_af(dest)); -    } - -    msg->nexthops[msg->n_nexthops++] = pb_nh; -  } - -  // TODO: Use src. - -  return 1; +	uint32_t if_index; +	union g_addr *gateway, *src; + +	gateway = src = NULL; + +	if_index = nexthop->ifindex; + +	if (nexthop->type == NEXTHOP_TYPE_IPV4 +	    || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) { +		gateway = &nexthop->gate; +		if (nexthop->src.ipv4.s_addr) +			src = &nexthop->src; +	} + +	if (nexthop->type == NEXTHOP_TYPE_IPV6 +	    || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) { +		gateway = &nexthop->gate; +	} + +	if (nexthop->type == NEXTHOP_TYPE_IFINDEX) { +		if (nexthop->src.ipv4.s_addr) +			src = &nexthop->src; +	} + +	if (!gateway && if_index == 0) +		return 0; + +	/* +	 * We have a valid nexthop. +	 */ +	{ +		Fpm__Nexthop *pb_nh; +		pb_nh = QPB_ALLOC(allocator, typeof(*pb_nh)); +		if (!pb_nh) { +			assert(0); +			return 0; +		} + +		fpm__nexthop__init(pb_nh); + +		if (if_index != 0) { +			pb_nh->if_id = +				qpb_if_identifier_create(allocator, if_index); +		} + +		if (gateway) { +			pb_nh->address = qpb_l3_address_create( +				allocator, gateway, rib_dest_af(dest)); +		} + +		msg->nexthops[msg->n_nexthops++] = pb_nh; +	} + +	// TODO: Use src. + +	return 1;  }  /*   * create_add_route_message   */ -static Fpm__AddRoute * -create_add_route_message (qpb_allocator_t *allocator, rib_dest_t *dest, -			  struct rib *rib) +static Fpm__AddRoute *create_add_route_message(qpb_allocator_t *allocator, +					       rib_dest_t *dest, +					       struct rib *rib)  { -  Fpm__AddRoute *msg; -  int discard; -  struct nexthop *nexthop, *tnexthop; -  int recursing; -  uint num_nhs, u; -  struct nexthop *nexthops[MULTIPATH_NUM]; - -  msg = QPB_ALLOC(allocator, typeof(*msg)); -  if (!msg) { -    assert(0); -    return NULL; -  } - -  fpm__add_route__init(msg); - -  msg->vrf_id = zvrf_id(rib_dest_vrf(dest)); - -  qpb_address_family_set (&msg->address_family, rib_dest_af(dest)); - -  /* -   * XXX Hardcode subaddress family for now. -   */ -  msg->sub_address_family = QPB__SUB_ADDRESS_FAMILY__UNICAST; -  msg->key = fpm_route_key_create (allocator, rib_dest_prefix(dest)); -  qpb_protocol_set (&msg->protocol, rib->type); - -  if ((rib->flags & ZEBRA_FLAG_BLACKHOLE) || (rib->flags & ZEBRA_FLAG_REJECT)) -    discard = 1; -  else -    discard = 0; - -  if (discard) -    { -      if (rib->flags & ZEBRA_FLAG_BLACKHOLE) { -	msg->route_type = FPM__ROUTE_TYPE__BLACKHOLE; -      } else if (rib->flags & ZEBRA_FLAG_REJECT) { -	msg->route_type = FPM__ROUTE_TYPE__UNREACHABLE; -      } else { -	assert (0); -      } -      return msg; -    } -  else { -    msg->route_type = FPM__ROUTE_TYPE__NORMAL; -  } - -  msg->metric = rib->metric; - -  /* -   * Figure out the set of nexthops to be added to the message. -   */ -  num_nhs = 0; -  for (ALL_NEXTHOPS_RO (rib->nexthop, nexthop, tnexthop, recursing)) -    { -      if (num_nhs >= multipath_num) -        break; - -      if (num_nhs >= ZEBRA_NUM_OF(nexthops)) -	break; - -      if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) -        continue; - -      if (!CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) -	continue; - -      nexthops[num_nhs] = nexthop; -      num_nhs++; -    } - -  if (!num_nhs) { -    zfpm_debug ("netlink_encode_route(): No useful nexthop."); -    assert(0); -    return NULL; -  } - -  /* -   * And add them to the message. -   */ -  if (!(msg->nexthops = qpb_alloc_ptr_array(allocator, num_nhs))) { -    assert(0); -    return NULL; -  } - -  msg->n_nexthops = 0; -  for (u = 0; u < num_nhs; u++) { -    if (!add_nexthop(allocator, msg, dest, nexthops[u])) { -      assert(0); -      return NULL; -    } -  } - -  assert(msg->n_nexthops == num_nhs); - -  return msg; +	Fpm__AddRoute *msg; +	int discard; +	struct nexthop *nexthop, *tnexthop; +	int recursing; +	uint num_nhs, u; +	struct nexthop *nexthops[MULTIPATH_NUM]; + +	msg = QPB_ALLOC(allocator, typeof(*msg)); +	if (!msg) { +		assert(0); +		return NULL; +	} + +	fpm__add_route__init(msg); + +	msg->vrf_id = zvrf_id(rib_dest_vrf(dest)); + +	qpb_address_family_set(&msg->address_family, rib_dest_af(dest)); + +	/* +	 * XXX Hardcode subaddress family for now. +	 */ +	msg->sub_address_family = QPB__SUB_ADDRESS_FAMILY__UNICAST; +	msg->key = fpm_route_key_create(allocator, rib_dest_prefix(dest)); +	qpb_protocol_set(&msg->protocol, rib->type); + +	if ((rib->flags & ZEBRA_FLAG_BLACKHOLE) +	    || (rib->flags & ZEBRA_FLAG_REJECT)) +		discard = 1; +	else +		discard = 0; + +	if (discard) { +		if (rib->flags & ZEBRA_FLAG_BLACKHOLE) { +			msg->route_type = FPM__ROUTE_TYPE__BLACKHOLE; +		} else if (rib->flags & ZEBRA_FLAG_REJECT) { +			msg->route_type = FPM__ROUTE_TYPE__UNREACHABLE; +		} else { +			assert(0); +		} +		return msg; +	} else { +		msg->route_type = FPM__ROUTE_TYPE__NORMAL; +	} + +	msg->metric = rib->metric; + +	/* +	 * Figure out the set of nexthops to be added to the message. +	 */ +	num_nhs = 0; +	for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) { +		if (num_nhs >= multipath_num) +			break; + +		if (num_nhs >= ZEBRA_NUM_OF(nexthops)) +			break; + +		if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) +			continue; + +		if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) +			continue; + +		nexthops[num_nhs] = nexthop; +		num_nhs++; +	} + +	if (!num_nhs) { +		zfpm_debug("netlink_encode_route(): No useful nexthop."); +		assert(0); +		return NULL; +	} + +	/* +	 * And add them to the message. +	 */ +	if (!(msg->nexthops = qpb_alloc_ptr_array(allocator, num_nhs))) { +		assert(0); +		return NULL; +	} + +	msg->n_nexthops = 0; +	for (u = 0; u < num_nhs; u++) { +		if (!add_nexthop(allocator, msg, dest, nexthops[u])) { +			assert(0); +			return NULL; +		} +	} + +	assert(msg->n_nexthops == num_nhs); + +	return msg;  }  /*   * create_route_message   */ -static Fpm__Message * -create_route_message (qpb_allocator_t *allocator, rib_dest_t *dest, -		      struct rib *rib) +static Fpm__Message *create_route_message(qpb_allocator_t *allocator, +					  rib_dest_t *dest, struct rib *rib)  { -  Fpm__Message *msg; - -  msg = QPB_ALLOC(allocator, typeof(*msg)); -  if (!msg) { -    assert(0); -    return NULL; -  } - -  fpm__message__init(msg); - -  if (!rib) { -    msg->type = FPM__MESSAGE__TYPE__DELETE_ROUTE; -    msg->delete_route = create_delete_route_message(allocator, dest, rib); -    if (!msg->delete_route) { -      assert(0); -      return NULL; -    } -    return msg; -  } - -  msg->type = FPM__MESSAGE__TYPE__ADD_ROUTE; -  msg->add_route = create_add_route_message(allocator, dest, rib); -  if (!msg->add_route) { -    assert(0); -    return NULL; -  } - -  return msg; +	Fpm__Message *msg; + +	msg = QPB_ALLOC(allocator, typeof(*msg)); +	if (!msg) { +		assert(0); +		return NULL; +	} + +	fpm__message__init(msg); + +	if (!rib) { +		msg->type = FPM__MESSAGE__TYPE__DELETE_ROUTE; +		msg->delete_route = +			create_delete_route_message(allocator, dest, rib); +		if (!msg->delete_route) { +			assert(0); +			return NULL; +		} +		return msg; +	} + +	msg->type = FPM__MESSAGE__TYPE__ADD_ROUTE; +	msg->add_route = create_add_route_message(allocator, dest, rib); +	if (!msg->add_route) { +		assert(0); +		return NULL; +	} + +	return msg;  }  /* @@ -287,25 +282,24 @@ create_route_message (qpb_allocator_t *allocator, rib_dest_t *dest,   * Returns the number of bytes written to the buffer. 0 or a negative   * value indicates an error.   */ -int -zfpm_protobuf_encode_route (rib_dest_t *dest, struct rib *rib, -			    uint8_t *in_buf, size_t in_buf_len) +int zfpm_protobuf_encode_route(rib_dest_t *dest, struct rib *rib, +			       uint8_t *in_buf, size_t in_buf_len)  { -  Fpm__Message *msg; -  QPB_DECLARE_STACK_ALLOCATOR (allocator, 4096); -  size_t len; +	Fpm__Message *msg; +	QPB_DECLARE_STACK_ALLOCATOR(allocator, 4096); +	size_t len; -  QPB_INIT_STACK_ALLOCATOR (allocator); +	QPB_INIT_STACK_ALLOCATOR(allocator); -  msg = create_route_message(&allocator, dest, rib); -  if (!msg) { -    assert(0); -    return 0; -  } +	msg = create_route_message(&allocator, dest, rib); +	if (!msg) { +		assert(0); +		return 0; +	} -  len = fpm__message__pack(msg, (uint8_t *) in_buf); -  assert(len <= in_buf_len); +	len = fpm__message__pack(msg, (uint8_t *)in_buf); +	assert(len <= in_buf_len); -  QPB_RESET_STACK_ALLOCATOR (allocator); -  return len; +	QPB_RESET_STACK_ALLOCATOR(allocator); +	return len;  } diff --git a/zebra/zebra_memory.c b/zebra/zebra_memory.c index 728051c34b..dc2a580c6f 100644 --- a/zebra/zebra_memory.c +++ b/zebra/zebra_memory.c @@ -27,11 +27,11 @@  #include "zebra_memory.h"  DEFINE_MGROUP(ZEBRA, "zebra") -DEFINE_MTYPE(ZEBRA, RTADV_PREFIX,   "Router Advertisement Prefix") -DEFINE_MTYPE(ZEBRA, ZEBRA_VRF,      "ZEBRA VRF") -DEFINE_MTYPE(ZEBRA, RIB,            "RIB") -DEFINE_MTYPE(ZEBRA, RIB_QUEUE,      "RIB process work queue") -DEFINE_MTYPE(ZEBRA, STATIC_ROUTE,   "Static route") -DEFINE_MTYPE(ZEBRA, RIB_DEST,       "RIB destination") +DEFINE_MTYPE(ZEBRA, RTADV_PREFIX, "Router Advertisement Prefix") +DEFINE_MTYPE(ZEBRA, ZEBRA_VRF, "ZEBRA VRF") +DEFINE_MTYPE(ZEBRA, RIB, "RIB") +DEFINE_MTYPE(ZEBRA, RIB_QUEUE, "RIB process work queue") +DEFINE_MTYPE(ZEBRA, STATIC_ROUTE, "Static route") +DEFINE_MTYPE(ZEBRA, RIB_DEST, "RIB destination")  DEFINE_MTYPE(ZEBRA, RIB_TABLE_INFO, "RIB table info") -DEFINE_MTYPE(ZEBRA, RNH,            "Nexthop tracking object") +DEFINE_MTYPE(ZEBRA, RNH, "Nexthop tracking object") diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index ba500cac27..7e74edf333 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -46,11 +46,11 @@  #include "zebra/zebra_vrf.h"  #include "zebra/zebra_mpls.h" -DEFINE_MTYPE_STATIC(ZEBRA, LSP,			"MPLS LSP object") -DEFINE_MTYPE_STATIC(ZEBRA, SLSP,		"MPLS static LSP config") -DEFINE_MTYPE_STATIC(ZEBRA, NHLFE,		"MPLS nexthop object") -DEFINE_MTYPE_STATIC(ZEBRA, SNHLFE,		"MPLS static nexthop object") -DEFINE_MTYPE_STATIC(ZEBRA, SNHLFE_IFNAME,	"MPLS static nexthop ifname") +DEFINE_MTYPE_STATIC(ZEBRA, LSP, "MPLS LSP object") +DEFINE_MTYPE_STATIC(ZEBRA, SLSP, "MPLS static LSP config") +DEFINE_MTYPE_STATIC(ZEBRA, NHLFE, "MPLS nexthop object") +DEFINE_MTYPE_STATIC(ZEBRA, SNHLFE, "MPLS static nexthop object") +DEFINE_MTYPE_STATIC(ZEBRA, SNHLFE_IFNAME, "MPLS static nexthop ifname")  int mpls_enabled; @@ -58,78 +58,54 @@ int mpls_enabled;  extern struct zebra_t zebrad;  /* static function declarations */ -static unsigned int -label_hash (void *p); -static int -label_cmp (const void *p1, const void *p2); -static int -nhlfe_nexthop_active_ipv4 (zebra_nhlfe_t *nhlfe, struct nexthop *nexthop); -static int -nhlfe_nexthop_active_ipv6 (zebra_nhlfe_t *nhlfe, struct nexthop *nexthop); -static int -nhlfe_nexthop_active (zebra_nhlfe_t *nhlfe); -static void -lsp_select_best_nhlfe (zebra_lsp_t *lsp); -static void -lsp_uninstall_from_kernel (struct hash_backet *backet, void *ctxt); -static void -lsp_schedule (struct hash_backet *backet, void *ctxt); -static wq_item_status -lsp_process (struct work_queue *wq, void *data); -static void -lsp_processq_del (struct work_queue *wq, void *data); -static void -lsp_processq_complete (struct work_queue *wq); -static int -lsp_processq_add (zebra_lsp_t *lsp); -static void * -lsp_alloc (void *p); -static char * -nhlfe2str (zebra_nhlfe_t *nhlfe, char *buf, int size); -static int -nhlfe_nhop_match (zebra_nhlfe_t *nhlfe, enum nexthop_types_t gtype, -                  union g_addr *gate, char *ifname, ifindex_t ifindex); -static zebra_nhlfe_t * -nhlfe_find (zebra_lsp_t *lsp, enum lsp_types_t lsp_type, -            enum nexthop_types_t gtype, union g_addr *gate, -            char *ifname, ifindex_t ifindex); -static zebra_nhlfe_t * -nhlfe_add (zebra_lsp_t *lsp, enum lsp_types_t lsp_type, -           enum nexthop_types_t gtype, union g_addr *gate, -           char *ifname, ifindex_t ifindex, mpls_label_t out_label); -static int -nhlfe_del (zebra_nhlfe_t *snhlfe); -static int -mpls_lsp_uninstall_all (struct hash *lsp_table, zebra_lsp_t *lsp, -			enum lsp_types_t type); -static int -mpls_static_lsp_uninstall_all (struct zebra_vrf *zvrf, mpls_label_t in_label); -static void -nhlfe_print (zebra_nhlfe_t *nhlfe, struct vty *vty); -static void -lsp_print (zebra_lsp_t *lsp, void *ctxt); -static void * -slsp_alloc (void *p); -static int -snhlfe_match (zebra_snhlfe_t *snhlfe, enum nexthop_types_t gtype, -              union g_addr *gate, char *ifname, ifindex_t ifindex); -static zebra_snhlfe_t * -snhlfe_find (zebra_slsp_t *slsp, enum nexthop_types_t gtype, -             union g_addr *gate, char *ifname, ifindex_t ifindex); -static zebra_snhlfe_t * -snhlfe_add (zebra_slsp_t *slsp, enum nexthop_types_t gtype, -            union g_addr *gate, char *ifname, ifindex_t ifindex, -            mpls_label_t out_label); -static int -snhlfe_del (zebra_snhlfe_t *snhlfe); -static int -snhlfe_del_all (zebra_slsp_t *slsp); -static char * -snhlfe2str (zebra_snhlfe_t *snhlfe, char *buf, int size); -static void -mpls_processq_init (struct zebra_t *zebra); - - +static unsigned int label_hash(void *p); +static int label_cmp(const void *p1, const void *p2); +static int nhlfe_nexthop_active_ipv4(zebra_nhlfe_t *nhlfe, +				     struct nexthop *nexthop); +static int nhlfe_nexthop_active_ipv6(zebra_nhlfe_t *nhlfe, +				     struct nexthop *nexthop); +static int nhlfe_nexthop_active(zebra_nhlfe_t *nhlfe); +static void lsp_select_best_nhlfe(zebra_lsp_t *lsp); +static void lsp_uninstall_from_kernel(struct hash_backet *backet, void *ctxt); +static void lsp_schedule(struct hash_backet *backet, void *ctxt); +static wq_item_status lsp_process(struct work_queue *wq, void *data); +static void lsp_processq_del(struct work_queue *wq, void *data); +static void lsp_processq_complete(struct work_queue *wq); +static int lsp_processq_add(zebra_lsp_t *lsp); +static void *lsp_alloc(void *p); +static char *nhlfe2str(zebra_nhlfe_t *nhlfe, char *buf, int size); +static int nhlfe_nhop_match(zebra_nhlfe_t *nhlfe, enum nexthop_types_t gtype, +			    union g_addr *gate, char *ifname, +			    ifindex_t ifindex); +static zebra_nhlfe_t *nhlfe_find(zebra_lsp_t *lsp, enum lsp_types_t lsp_type, +				 enum nexthop_types_t gtype, union g_addr *gate, +				 char *ifname, ifindex_t ifindex); +static zebra_nhlfe_t *nhlfe_add(zebra_lsp_t *lsp, enum lsp_types_t lsp_type, +				enum nexthop_types_t gtype, union g_addr *gate, +				char *ifname, ifindex_t ifindex, +				mpls_label_t out_label); +static int nhlfe_del(zebra_nhlfe_t *snhlfe); +static int mpls_lsp_uninstall_all(struct hash *lsp_table, zebra_lsp_t *lsp, +				  enum lsp_types_t type); +static int mpls_static_lsp_uninstall_all(struct zebra_vrf *zvrf, +					 mpls_label_t in_label); +static void nhlfe_print(zebra_nhlfe_t *nhlfe, struct vty *vty); +static void lsp_print(zebra_lsp_t *lsp, void *ctxt); +static void *slsp_alloc(void *p); +static int snhlfe_match(zebra_snhlfe_t *snhlfe, enum nexthop_types_t gtype, +			union g_addr *gate, char *ifname, ifindex_t ifindex); +static zebra_snhlfe_t *snhlfe_find(zebra_slsp_t *slsp, +				   enum nexthop_types_t gtype, +				   union g_addr *gate, char *ifname, +				   ifindex_t ifindex); +static zebra_snhlfe_t *snhlfe_add(zebra_slsp_t *slsp, +				  enum nexthop_types_t gtype, +				  union g_addr *gate, char *ifname, +				  ifindex_t ifindex, mpls_label_t out_label); +static int snhlfe_del(zebra_snhlfe_t *snhlfe); +static int snhlfe_del_all(zebra_slsp_t *slsp); +static char *snhlfe2str(zebra_snhlfe_t *snhlfe, char *buf, int size); +static void mpls_processq_init(struct zebra_t *zebra);  /* Static functions */ @@ -137,24 +113,22 @@ mpls_processq_init (struct zebra_t *zebra);  /*   * Hash function for label.   */ -static unsigned int -label_hash (void *p) +static unsigned int label_hash(void *p)  { -  const zebra_ile_t *ile = p; +	const zebra_ile_t *ile = p; -  return (jhash_1word(ile->in_label, 0)); +	return (jhash_1word(ile->in_label, 0));  }  /*   * Compare 2 LSP hash entries based on in-label.   */ -static int -label_cmp (const void *p1, const void *p2) +static int label_cmp(const void *p1, const void *p2)  { -  const zebra_ile_t *ile1 = p1; -  const zebra_ile_t *ile2 = p2; +	const zebra_ile_t *ile1 = p1; +	const zebra_ile_t *ile2 = p2; -  return (ile1->in_label == ile2->in_label); +	return (ile1->in_label == ile2->in_label);  }  /* @@ -162,50 +136,49 @@ label_cmp (const void *p1, const void *p2)   * the passed flag.   * NOTE: Looking only for connected routes right now.   */ -static int -nhlfe_nexthop_active_ipv4 (zebra_nhlfe_t *nhlfe, struct nexthop *nexthop) +static int nhlfe_nexthop_active_ipv4(zebra_nhlfe_t *nhlfe, +				     struct nexthop *nexthop)  { -  struct route_table *table; -  struct prefix_ipv4 p; -  struct route_node *rn; -  struct rib *match; -  struct nexthop *match_nh; - -  table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT); -  if (!table) -    return 0; - -  /* Lookup nexthop in IPv4 routing table. */ -  memset (&p, 0, sizeof (struct prefix_ipv4)); -  p.family = AF_INET; -  p.prefixlen = IPV4_MAX_PREFIXLEN; -  p.prefix = nexthop->gate.ipv4; - -  rn = route_node_match (table, (struct prefix *) &p); -  if (!rn) -    return 0; - -  route_unlock_node (rn); - -  /* Locate a valid connected route. */ -  RNODE_FOREACH_RIB (rn, match) -    { -      if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED) || -	  !CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED)) -	continue; - -      for (match_nh = match->nexthop; match_nh; match_nh = match_nh->next) +	struct route_table *table; +	struct prefix_ipv4 p; +	struct route_node *rn; +	struct rib *match; +	struct nexthop *match_nh; + +	table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, VRF_DEFAULT); +	if (!table) +		return 0; + +	/* Lookup nexthop in IPv4 routing table. */ +	memset(&p, 0, sizeof(struct prefix_ipv4)); +	p.family = AF_INET; +	p.prefixlen = IPV4_MAX_PREFIXLEN; +	p.prefix = nexthop->gate.ipv4; + +	rn = route_node_match(table, (struct prefix *)&p); +	if (!rn) +		return 0; + +	route_unlock_node(rn); + +	/* Locate a valid connected route. */ +	RNODE_FOREACH_RIB(rn, match)  	{ -	  if (match->type == ZEBRA_ROUTE_CONNECT || -	      nexthop->ifindex == match_nh->ifindex) -	    { -	      nexthop->ifindex = match_nh->ifindex; -	      return 1; -	    } +		if (CHECK_FLAG(match->status, RIB_ENTRY_REMOVED) +		    || !CHECK_FLAG(match->flags, ZEBRA_FLAG_SELECTED)) +			continue; + +		for (match_nh = match->nexthop; match_nh; +		     match_nh = match_nh->next) { +			if (match->type == ZEBRA_ROUTE_CONNECT +			    || nexthop->ifindex == match_nh->ifindex) { +				nexthop->ifindex = match_nh->ifindex; +				return 1; +			} +		}  	} -    } -  return 0; +	return 0;  } @@ -214,44 +187,44 @@ nhlfe_nexthop_active_ipv4 (zebra_nhlfe_t *nhlfe, struct nexthop *nexthop)   * the passed flag.   * NOTE: Looking only for connected routes right now.   */ -static int -nhlfe_nexthop_active_ipv6 (zebra_nhlfe_t *nhlfe, struct nexthop *nexthop) +static int nhlfe_nexthop_active_ipv6(zebra_nhlfe_t *nhlfe, +				     struct nexthop *nexthop)  { -  struct route_table *table; -  struct prefix_ipv6 p; -  struct route_node *rn; -  struct rib *match; - -  table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, VRF_DEFAULT); -  if (!table) -    return 0; - -  /* Lookup nexthop in IPv6 routing table. */ -  memset (&p, 0, sizeof (struct prefix_ipv6)); -  p.family = AF_INET6; -  p.prefixlen = IPV6_MAX_PREFIXLEN; -  p.prefix = nexthop->gate.ipv6; - -  rn = route_node_match (table, (struct prefix *) &p); -  if (!rn) -    return 0; - -  route_unlock_node (rn); - -  /* Locate a valid connected route. */ -  RNODE_FOREACH_RIB (rn, match) -    { -      if ((match->type == ZEBRA_ROUTE_CONNECT) && -          !CHECK_FLAG (match->status, RIB_ENTRY_REMOVED) && -          CHECK_FLAG (match->flags, ZEBRA_FLAG_SELECTED)) -        break; -    } - -  if (!match || !match->nexthop) -    return 0; - -  nexthop->ifindex = match->nexthop->ifindex; -  return 1; +	struct route_table *table; +	struct prefix_ipv6 p; +	struct route_node *rn; +	struct rib *match; + +	table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT); +	if (!table) +		return 0; + +	/* Lookup nexthop in IPv6 routing table. */ +	memset(&p, 0, sizeof(struct prefix_ipv6)); +	p.family = AF_INET6; +	p.prefixlen = IPV6_MAX_PREFIXLEN; +	p.prefix = nexthop->gate.ipv6; + +	rn = route_node_match(table, (struct prefix *)&p); +	if (!rn) +		return 0; + +	route_unlock_node(rn); + +	/* Locate a valid connected route. */ +	RNODE_FOREACH_RIB(rn, match) +	{ +		if ((match->type == ZEBRA_ROUTE_CONNECT) +		    && !CHECK_FLAG(match->status, RIB_ENTRY_REMOVED) +		    && CHECK_FLAG(match->flags, ZEBRA_FLAG_SELECTED)) +			break; +	} + +	if (!match || !match->nexthop) +		return 0; + +	nexthop->ifindex = match->nexthop->ifindex; +	return 1;  } @@ -260,57 +233,52 @@ nhlfe_nexthop_active_ipv6 (zebra_nhlfe_t *nhlfe, struct nexthop *nexthop)   * or not.   * NOTE: Each NHLFE points to only 1 nexthop.   */ -static int -nhlfe_nexthop_active (zebra_nhlfe_t *nhlfe) +static int nhlfe_nexthop_active(zebra_nhlfe_t *nhlfe)  { -  struct nexthop *nexthop; -  struct interface *ifp; - -  nexthop = nhlfe->nexthop; -  if (!nexthop) // unexpected -    return 0; - -  /* Check on nexthop based on type. */ -  switch (nexthop->type) -    { -      case NEXTHOP_TYPE_IPV4: -      case NEXTHOP_TYPE_IPV4_IFINDEX: -        if (nhlfe_nexthop_active_ipv4 (nhlfe, nexthop)) -          SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); -        else -          UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); -        break; - -      case NEXTHOP_TYPE_IPV6: -        if (nhlfe_nexthop_active_ipv6 (nhlfe, nexthop)) -          SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); -        else -          UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); -        break; - -      case NEXTHOP_TYPE_IPV6_IFINDEX: -        if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6)) -          { -            ifp = if_lookup_by_index (nexthop->ifindex, VRF_DEFAULT); -            if (ifp && if_is_operative(ifp)) -              SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); -            else -              UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); -          } -        else -          { -            if (nhlfe_nexthop_active_ipv6 (nhlfe, nexthop)) -              SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); -            else -              UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); -          } -        break; - -    default: -      break; -    } - -  return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); +	struct nexthop *nexthop; +	struct interface *ifp; + +	nexthop = nhlfe->nexthop; +	if (!nexthop) // unexpected +		return 0; + +	/* Check on nexthop based on type. */ +	switch (nexthop->type) { +	case NEXTHOP_TYPE_IPV4: +	case NEXTHOP_TYPE_IPV4_IFINDEX: +		if (nhlfe_nexthop_active_ipv4(nhlfe, nexthop)) +			SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); +		else +			UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); +		break; + +	case NEXTHOP_TYPE_IPV6: +		if (nhlfe_nexthop_active_ipv6(nhlfe, nexthop)) +			SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); +		else +			UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); +		break; + +	case NEXTHOP_TYPE_IPV6_IFINDEX: +		if (IN6_IS_ADDR_LINKLOCAL(&nexthop->gate.ipv6)) { +			ifp = if_lookup_by_index(nexthop->ifindex, VRF_DEFAULT); +			if (ifp && if_is_operative(ifp)) +				SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); +			else +				UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); +		} else { +			if (nhlfe_nexthop_active_ipv6(nhlfe, nexthop)) +				SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); +			else +				UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); +		} +		break; + +	default: +		break; +	} + +	return CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);  }  /* @@ -319,759 +287,722 @@ nhlfe_nexthop_active (zebra_nhlfe_t *nhlfe)   * marked. This is invoked when an LSP scheduled for processing (due   * to some change) is examined.   */ -static void -lsp_select_best_nhlfe (zebra_lsp_t *lsp) +static void lsp_select_best_nhlfe(zebra_lsp_t *lsp)  { -  zebra_nhlfe_t *nhlfe; -  zebra_nhlfe_t *best; -  struct nexthop *nexthop; -  int changed = 0; - -  if (!lsp) -    return; - -  best = NULL; -  lsp->num_ecmp = 0; -  UNSET_FLAG (lsp->flags, LSP_FLAG_CHANGED); - -  /* -   * First compute the best path, after checking nexthop status. We are only -   * concerned with non-deleted NHLFEs. -   */ -  for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) -    { -      /* Clear selection flags. */ -      UNSET_FLAG (nhlfe->flags, -                  (NHLFE_FLAG_SELECTED | NHLFE_FLAG_MULTIPATH)); - -      if (!CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_DELETED) && -          nhlfe_nexthop_active (nhlfe)) -        { -          if (!best || (nhlfe->distance < best->distance)) -            best = nhlfe; -        } -    } - -  lsp->best_nhlfe = best; -  if (!lsp->best_nhlfe) -    return; - -  /* Mark best NHLFE as selected. */ -  SET_FLAG (lsp->best_nhlfe->flags, NHLFE_FLAG_SELECTED); - -  /* -   * If best path exists, see if there is ECMP. While doing this, note if a -   * new (uninstalled) NHLFE has been selected, an installed entry that is -   * still selected has a change or an installed entry is to be removed. -   */ -  for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) -    { -      int nh_chg, nh_sel, nh_inst; - -      nexthop = nhlfe->nexthop; -      if (!nexthop) // unexpected -        continue; - -      if (!CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_DELETED) && -          CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) && -          (nhlfe->distance == lsp->best_nhlfe->distance)) -        { -          SET_FLAG (nhlfe->flags, NHLFE_FLAG_SELECTED); -          SET_FLAG (nhlfe->flags, NHLFE_FLAG_MULTIPATH); -          lsp->num_ecmp++; -        } - -      if (CHECK_FLAG (lsp->flags, LSP_FLAG_INSTALLED) && -          !changed) -        { -          nh_chg = CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_CHANGED); -          nh_sel = CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_SELECTED); -          nh_inst = CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_INSTALLED); - -          if ((nh_sel && !nh_inst) || -              (nh_sel && nh_inst && nh_chg) || -              (nh_inst && !nh_sel)) -            changed = 1; -        } - -      /* We have finished examining, clear changed flag. */ -      UNSET_FLAG (nhlfe->flags, NHLFE_FLAG_CHANGED); -    } - -  if (changed) -    SET_FLAG (lsp->flags, LSP_FLAG_CHANGED); +	zebra_nhlfe_t *nhlfe; +	zebra_nhlfe_t *best; +	struct nexthop *nexthop; +	int changed = 0; + +	if (!lsp) +		return; + +	best = NULL; +	lsp->num_ecmp = 0; +	UNSET_FLAG(lsp->flags, LSP_FLAG_CHANGED); + +	/* +	 * First compute the best path, after checking nexthop status. We are +	 * only +	 * concerned with non-deleted NHLFEs. +	 */ +	for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) { +		/* Clear selection flags. */ +		UNSET_FLAG(nhlfe->flags, +			   (NHLFE_FLAG_SELECTED | NHLFE_FLAG_MULTIPATH)); + +		if (!CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_DELETED) +		    && nhlfe_nexthop_active(nhlfe)) { +			if (!best || (nhlfe->distance < best->distance)) +				best = nhlfe; +		} +	} + +	lsp->best_nhlfe = best; +	if (!lsp->best_nhlfe) +		return; + +	/* Mark best NHLFE as selected. */ +	SET_FLAG(lsp->best_nhlfe->flags, NHLFE_FLAG_SELECTED); + +	/* +	 * If best path exists, see if there is ECMP. While doing this, note if +	 * a +	 * new (uninstalled) NHLFE has been selected, an installed entry that is +	 * still selected has a change or an installed entry is to be removed. +	 */ +	for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) { +		int nh_chg, nh_sel, nh_inst; + +		nexthop = nhlfe->nexthop; +		if (!nexthop) // unexpected +			continue; + +		if (!CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_DELETED) +		    && CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE) +		    && (nhlfe->distance == lsp->best_nhlfe->distance)) { +			SET_FLAG(nhlfe->flags, NHLFE_FLAG_SELECTED); +			SET_FLAG(nhlfe->flags, NHLFE_FLAG_MULTIPATH); +			lsp->num_ecmp++; +		} + +		if (CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED) && !changed) { +			nh_chg = CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_CHANGED); +			nh_sel = CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_SELECTED); +			nh_inst = +				CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED); + +			if ((nh_sel && !nh_inst) +			    || (nh_sel && nh_inst && nh_chg) +			    || (nh_inst && !nh_sel)) +				changed = 1; +		} + +		/* We have finished examining, clear changed flag. */ +		UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_CHANGED); +	} + +	if (changed) +		SET_FLAG(lsp->flags, LSP_FLAG_CHANGED);  }  /*   * Delete LSP forwarding entry from kernel, if installed. Called upon   * process exit.   */ -static void -lsp_uninstall_from_kernel (struct hash_backet *backet, void *ctxt) +static void lsp_uninstall_from_kernel(struct hash_backet *backet, void *ctxt)  { -  zebra_lsp_t *lsp; +	zebra_lsp_t *lsp; -  lsp = (zebra_lsp_t *) backet->data; -  if (CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED)) -    kernel_del_lsp (lsp); +	lsp = (zebra_lsp_t *)backet->data; +	if (CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED)) +		kernel_del_lsp(lsp);  }  /*   * Schedule LSP forwarding entry for processing. Called upon changes   * that may impact LSPs such as nexthop / connected route changes.   */ -static void -lsp_schedule (struct hash_backet *backet, void *ctxt) +static void lsp_schedule(struct hash_backet *backet, void *ctxt)  { -  zebra_lsp_t *lsp; +	zebra_lsp_t *lsp; -  lsp = (zebra_lsp_t *) backet->data; -  lsp_processq_add (lsp); +	lsp = (zebra_lsp_t *)backet->data; +	lsp_processq_add(lsp);  }  /*   * Process a LSP entry that is in the queue. Recalculate best NHLFE and   * any multipaths and update or delete from the kernel, as needed.   */ -static wq_item_status -lsp_process (struct work_queue *wq, void *data) +static wq_item_status lsp_process(struct work_queue *wq, void *data)  { -  zebra_lsp_t *lsp; -  zebra_nhlfe_t *oldbest, *newbest; -  char buf[BUFSIZ], buf2[BUFSIZ]; - -  lsp = (zebra_lsp_t *)data; -  if (!lsp) // unexpected -    return WQ_SUCCESS; - -  oldbest = lsp->best_nhlfe; - -  /* Select best NHLFE(s) */ -  lsp_select_best_nhlfe (lsp); - -  newbest = lsp->best_nhlfe; - -  if (IS_ZEBRA_DEBUG_MPLS) -    { -      if (oldbest) -        nhlfe2str (oldbest, buf, BUFSIZ); -      if (newbest) -        nhlfe2str (newbest, buf2, BUFSIZ); -      zlog_debug ("Process LSP in-label %u oldbest %s newbest %s " -                  "flags 0x%x ecmp# %d", -                  lsp->ile.in_label, oldbest ? buf : "NULL", -                  newbest ? buf2 : "NULL", lsp->flags, lsp->num_ecmp); -    } - -  if (!CHECK_FLAG (lsp->flags, LSP_FLAG_INSTALLED)) -    { -      /* Not already installed */ -      if (newbest) -        kernel_add_lsp (lsp); -    } -  else -    { -      /* Installed, may need an update and/or delete. */ -      if (!newbest) -        kernel_del_lsp (lsp); -      else if (CHECK_FLAG (lsp->flags, LSP_FLAG_CHANGED)) -        kernel_upd_lsp (lsp); -    } - -  return WQ_SUCCESS; +	zebra_lsp_t *lsp; +	zebra_nhlfe_t *oldbest, *newbest; +	char buf[BUFSIZ], buf2[BUFSIZ]; + +	lsp = (zebra_lsp_t *)data; +	if (!lsp) // unexpected +		return WQ_SUCCESS; + +	oldbest = lsp->best_nhlfe; + +	/* Select best NHLFE(s) */ +	lsp_select_best_nhlfe(lsp); + +	newbest = lsp->best_nhlfe; + +	if (IS_ZEBRA_DEBUG_MPLS) { +		if (oldbest) +			nhlfe2str(oldbest, buf, BUFSIZ); +		if (newbest) +			nhlfe2str(newbest, buf2, BUFSIZ); +		zlog_debug( +			"Process LSP in-label %u oldbest %s newbest %s " +			"flags 0x%x ecmp# %d", +			lsp->ile.in_label, oldbest ? buf : "NULL", +			newbest ? buf2 : "NULL", lsp->flags, lsp->num_ecmp); +	} + +	if (!CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED)) { +		/* Not already installed */ +		if (newbest) +			kernel_add_lsp(lsp); +	} else { +		/* Installed, may need an update and/or delete. */ +		if (!newbest) +			kernel_del_lsp(lsp); +		else if (CHECK_FLAG(lsp->flags, LSP_FLAG_CHANGED)) +			kernel_upd_lsp(lsp); +	} + +	return WQ_SUCCESS;  }  /*   * Callback upon processing completion of a LSP forwarding entry.   */ -static void -lsp_processq_del (struct work_queue *wq, void *data) +static void lsp_processq_del(struct work_queue *wq, void *data)  { -  struct zebra_vrf *zvrf; -  zebra_lsp_t *lsp; -  struct hash *lsp_table; -  zebra_nhlfe_t *nhlfe, *nhlfe_next; - -  zvrf = vrf_info_lookup(VRF_DEFAULT); -  assert (zvrf); - -  lsp_table = zvrf->lsp_table; -  if (!lsp_table) // unexpected -    return; - -  lsp = (zebra_lsp_t *)data; -  if (!lsp) // unexpected -    return; - -  /* Clear flag, remove any NHLFEs marked for deletion. If no NHLFEs exist, -   * delete LSP entry also. -   */ -  UNSET_FLAG (lsp->flags, LSP_FLAG_SCHEDULED); - -  for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe_next) -    { -      nhlfe_next = nhlfe->next; -      if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_DELETED)) -        nhlfe_del (nhlfe); -    } - -  if (!lsp->nhlfe_list) -    { -      if (IS_ZEBRA_DEBUG_MPLS) -        zlog_debug ("Free LSP in-label %u flags 0x%x", -                    lsp->ile.in_label, lsp->flags); - -      lsp = hash_release(lsp_table, &lsp->ile); -      if (lsp) -        XFREE(MTYPE_LSP, lsp); -    } +	struct zebra_vrf *zvrf; +	zebra_lsp_t *lsp; +	struct hash *lsp_table; +	zebra_nhlfe_t *nhlfe, *nhlfe_next; + +	zvrf = vrf_info_lookup(VRF_DEFAULT); +	assert(zvrf); + +	lsp_table = zvrf->lsp_table; +	if (!lsp_table) // unexpected +		return; + +	lsp = (zebra_lsp_t *)data; +	if (!lsp) // unexpected +		return; + +	/* Clear flag, remove any NHLFEs marked for deletion. If no NHLFEs +	 * exist, +	 * delete LSP entry also. +	 */ +	UNSET_FLAG(lsp->flags, LSP_FLAG_SCHEDULED); + +	for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe_next) { +		nhlfe_next = nhlfe->next; +		if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_DELETED)) +			nhlfe_del(nhlfe); +	} + +	if (!lsp->nhlfe_list) { +		if (IS_ZEBRA_DEBUG_MPLS) +			zlog_debug("Free LSP in-label %u flags 0x%x", +				   lsp->ile.in_label, lsp->flags); + +		lsp = hash_release(lsp_table, &lsp->ile); +		if (lsp) +			XFREE(MTYPE_LSP, lsp); +	}  }  /*   * Callback upon finishing the processing of all scheduled   * LSP forwarding entries.   */ -static void -lsp_processq_complete (struct work_queue *wq) +static void lsp_processq_complete(struct work_queue *wq)  { -  /* Nothing to do for now. */ +	/* Nothing to do for now. */  }  /*   * Add LSP forwarding entry to queue for subsequent processing.   */ -static int -lsp_processq_add (zebra_lsp_t *lsp) +static int lsp_processq_add(zebra_lsp_t *lsp)  { -  /* If already scheduled, exit. */ -  if (CHECK_FLAG (lsp->flags, LSP_FLAG_SCHEDULED)) -    return 0; +	/* If already scheduled, exit. */ +	if (CHECK_FLAG(lsp->flags, LSP_FLAG_SCHEDULED)) +		return 0; -  work_queue_add (zebrad.lsp_process_q, lsp); -  SET_FLAG (lsp->flags, LSP_FLAG_SCHEDULED); -  return 0; +	work_queue_add(zebrad.lsp_process_q, lsp); +	SET_FLAG(lsp->flags, LSP_FLAG_SCHEDULED); +	return 0;  }  /*   * Callback to allocate LSP forwarding table entry.   */ -static void * -lsp_alloc (void *p) +static void *lsp_alloc(void *p)  { -  const zebra_ile_t *ile = p; -  zebra_lsp_t *lsp; +	const zebra_ile_t *ile = p; +	zebra_lsp_t *lsp; -  lsp = XCALLOC (MTYPE_LSP, sizeof(zebra_lsp_t)); -  lsp->ile = *ile; +	lsp = XCALLOC(MTYPE_LSP, sizeof(zebra_lsp_t)); +	lsp->ile = *ile; -  if (IS_ZEBRA_DEBUG_MPLS) -    zlog_debug ("Alloc LSP in-label %u", lsp->ile.in_label); +	if (IS_ZEBRA_DEBUG_MPLS) +		zlog_debug("Alloc LSP in-label %u", lsp->ile.in_label); -  return ((void *)lsp); +	return ((void *)lsp);  }  /*   * Create printable string for NHLFE entry.   */ -static char * -nhlfe2str (zebra_nhlfe_t *nhlfe, char *buf, int size) +static char *nhlfe2str(zebra_nhlfe_t *nhlfe, char *buf, int size)  { -  struct nexthop *nexthop; - -  buf[0] = '\0'; -  nexthop = nhlfe->nexthop; -  switch (nexthop->type) -    { -      case NEXTHOP_TYPE_IPV4: -      case NEXTHOP_TYPE_IPV4_IFINDEX: -        inet_ntop (AF_INET, &nexthop->gate.ipv4, buf, size); -        break; -      case NEXTHOP_TYPE_IPV6: -        inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, size); -        break; -      default: -        break; -    } - -  return buf; +	struct nexthop *nexthop; + +	buf[0] = '\0'; +	nexthop = nhlfe->nexthop; +	switch (nexthop->type) { +	case NEXTHOP_TYPE_IPV4: +	case NEXTHOP_TYPE_IPV4_IFINDEX: +		inet_ntop(AF_INET, &nexthop->gate.ipv4, buf, size); +		break; +	case NEXTHOP_TYPE_IPV6: +		inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf, size); +		break; +	default: +		break; +	} + +	return buf;  }  /*   * Check if NHLFE matches with search info passed.   */ -static int -nhlfe_nhop_match (zebra_nhlfe_t *nhlfe, enum nexthop_types_t gtype, -                  union g_addr *gate, char *ifname, ifindex_t ifindex) +static int nhlfe_nhop_match(zebra_nhlfe_t *nhlfe, enum nexthop_types_t gtype, +			    union g_addr *gate, char *ifname, ifindex_t ifindex)  { -  struct nexthop *nhop; -  int cmp = 1; - -  nhop = nhlfe->nexthop; -  if (!nhop) -    return 1; - -  if (nhop->type != gtype) -    return 1; - -  switch (nhop->type) -    { -    case NEXTHOP_TYPE_IPV4: -    case NEXTHOP_TYPE_IPV4_IFINDEX: -      cmp = memcmp(&(nhop->gate.ipv4), &(gate->ipv4), -                   sizeof(struct in_addr)); -      if (!cmp && nhop->type == NEXTHOP_TYPE_IPV4_IFINDEX) -        cmp = !(nhop->ifindex == ifindex); -      break; -    case NEXTHOP_TYPE_IPV6: -    case NEXTHOP_TYPE_IPV6_IFINDEX: -      cmp = memcmp(&(nhop->gate.ipv6), &(gate->ipv6), -		   sizeof(struct in6_addr)); -      if (!cmp && nhop->type == NEXTHOP_TYPE_IPV6_IFINDEX) -        cmp = !(nhop->ifindex == ifindex); -      break; -    default: -      break; -    } - -  return cmp; +	struct nexthop *nhop; +	int cmp = 1; + +	nhop = nhlfe->nexthop; +	if (!nhop) +		return 1; + +	if (nhop->type != gtype) +		return 1; + +	switch (nhop->type) { +	case NEXTHOP_TYPE_IPV4: +	case NEXTHOP_TYPE_IPV4_IFINDEX: +		cmp = memcmp(&(nhop->gate.ipv4), &(gate->ipv4), +			     sizeof(struct in_addr)); +		if (!cmp && nhop->type == NEXTHOP_TYPE_IPV4_IFINDEX) +			cmp = !(nhop->ifindex == ifindex); +		break; +	case NEXTHOP_TYPE_IPV6: +	case NEXTHOP_TYPE_IPV6_IFINDEX: +		cmp = memcmp(&(nhop->gate.ipv6), &(gate->ipv6), +			     sizeof(struct in6_addr)); +		if (!cmp && nhop->type == NEXTHOP_TYPE_IPV6_IFINDEX) +			cmp = !(nhop->ifindex == ifindex); +		break; +	default: +		break; +	} + +	return cmp;  }  /*   * Locate NHLFE that matches with passed info.   */ -static zebra_nhlfe_t * -nhlfe_find (zebra_lsp_t *lsp, enum lsp_types_t lsp_type, -            enum nexthop_types_t gtype, union g_addr *gate, -            char *ifname, ifindex_t ifindex) +static zebra_nhlfe_t *nhlfe_find(zebra_lsp_t *lsp, enum lsp_types_t lsp_type, +				 enum nexthop_types_t gtype, union g_addr *gate, +				 char *ifname, ifindex_t ifindex)  { -  zebra_nhlfe_t *nhlfe; +	zebra_nhlfe_t *nhlfe; -  if (!lsp) -    return NULL; +	if (!lsp) +		return NULL; -  for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) -    { -      if (nhlfe->type != lsp_type) -        continue; -      if (!nhlfe_nhop_match (nhlfe, gtype, gate, ifname, ifindex)) -        break; -    } +	for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) { +		if (nhlfe->type != lsp_type) +			continue; +		if (!nhlfe_nhop_match(nhlfe, gtype, gate, ifname, ifindex)) +			break; +	} -  return nhlfe; +	return nhlfe;  }  /*   * Add NHLFE. Base entry must have been created and duplicate   * check done.   */ -static zebra_nhlfe_t * -nhlfe_add (zebra_lsp_t *lsp, enum lsp_types_t lsp_type, -           enum nexthop_types_t gtype, union g_addr *gate, -           char *ifname, ifindex_t ifindex, mpls_label_t out_label) +static zebra_nhlfe_t *nhlfe_add(zebra_lsp_t *lsp, enum lsp_types_t lsp_type, +				enum nexthop_types_t gtype, union g_addr *gate, +				char *ifname, ifindex_t ifindex, +				mpls_label_t out_label)  { -  zebra_nhlfe_t *nhlfe; -  struct nexthop *nexthop; - -  if (!lsp) -    return NULL; - -  nhlfe = XCALLOC(MTYPE_NHLFE, sizeof(zebra_nhlfe_t)); -  if (!nhlfe) -    return NULL; - -  nhlfe->lsp = lsp; -  nhlfe->type = lsp_type; -  nhlfe->distance = lsp_distance (lsp_type); - -  nexthop = nexthop_new(); -  if (!nexthop) -    { -      XFREE (MTYPE_NHLFE, nhlfe); -      return NULL; -    } -  nexthop_add_labels (nexthop, lsp_type, 1, &out_label); - -  nexthop->type = gtype; -  switch (nexthop->type) -    { -    case NEXTHOP_TYPE_IPV4: -    case NEXTHOP_TYPE_IPV4_IFINDEX: -      nexthop->gate.ipv4 = gate->ipv4; -      if (ifindex) -        nexthop->ifindex = ifindex; -      break; -    case NEXTHOP_TYPE_IPV6: -    case NEXTHOP_TYPE_IPV6_IFINDEX: -      nexthop->gate.ipv6 = gate->ipv6; -      if (ifindex) -        nexthop->ifindex = ifindex; -      break; -    default: -      nexthop_free(nexthop); -      XFREE (MTYPE_NHLFE, nhlfe); -      return NULL; -      break; -    } - -  nhlfe->nexthop = nexthop; -  if (lsp->nhlfe_list) -    lsp->nhlfe_list->prev = nhlfe; -  nhlfe->next = lsp->nhlfe_list; -  lsp->nhlfe_list = nhlfe; - -  return nhlfe; +	zebra_nhlfe_t *nhlfe; +	struct nexthop *nexthop; + +	if (!lsp) +		return NULL; + +	nhlfe = XCALLOC(MTYPE_NHLFE, sizeof(zebra_nhlfe_t)); +	if (!nhlfe) +		return NULL; + +	nhlfe->lsp = lsp; +	nhlfe->type = lsp_type; +	nhlfe->distance = lsp_distance(lsp_type); + +	nexthop = nexthop_new(); +	if (!nexthop) { +		XFREE(MTYPE_NHLFE, nhlfe); +		return NULL; +	} +	nexthop_add_labels(nexthop, lsp_type, 1, &out_label); + +	nexthop->type = gtype; +	switch (nexthop->type) { +	case NEXTHOP_TYPE_IPV4: +	case NEXTHOP_TYPE_IPV4_IFINDEX: +		nexthop->gate.ipv4 = gate->ipv4; +		if (ifindex) +			nexthop->ifindex = ifindex; +		break; +	case NEXTHOP_TYPE_IPV6: +	case NEXTHOP_TYPE_IPV6_IFINDEX: +		nexthop->gate.ipv6 = gate->ipv6; +		if (ifindex) +			nexthop->ifindex = ifindex; +		break; +	default: +		nexthop_free(nexthop); +		XFREE(MTYPE_NHLFE, nhlfe); +		return NULL; +		break; +	} + +	nhlfe->nexthop = nexthop; +	if (lsp->nhlfe_list) +		lsp->nhlfe_list->prev = nhlfe; +	nhlfe->next = lsp->nhlfe_list; +	lsp->nhlfe_list = nhlfe; + +	return nhlfe;  }  /*   * Delete NHLFE. Entry must be present on list.   */ -static int -nhlfe_del (zebra_nhlfe_t *nhlfe) +static int nhlfe_del(zebra_nhlfe_t *nhlfe)  { -  zebra_lsp_t *lsp; +	zebra_lsp_t *lsp; -  if (!nhlfe) -    return -1; +	if (!nhlfe) +		return -1; -  lsp = nhlfe->lsp; -  if (!lsp) -    return -1; +	lsp = nhlfe->lsp; +	if (!lsp) +		return -1; -  /* Free nexthop. */ -  if (nhlfe->nexthop) -    nexthop_free(nhlfe->nexthop); +	/* Free nexthop. */ +	if (nhlfe->nexthop) +		nexthop_free(nhlfe->nexthop); -  /* Unlink from LSP */ -  if (nhlfe->next) -    nhlfe->next->prev = nhlfe->prev; -  if (nhlfe->prev) -    nhlfe->prev->next = nhlfe->next; -  else -    lsp->nhlfe_list = nhlfe->next; +	/* Unlink from LSP */ +	if (nhlfe->next) +		nhlfe->next->prev = nhlfe->prev; +	if (nhlfe->prev) +		nhlfe->prev->next = nhlfe->next; +	else +		lsp->nhlfe_list = nhlfe->next; -  if (nhlfe == lsp->best_nhlfe) -    lsp->best_nhlfe = NULL; +	if (nhlfe == lsp->best_nhlfe) +		lsp->best_nhlfe = NULL; -  XFREE (MTYPE_NHLFE, nhlfe); +	XFREE(MTYPE_NHLFE, nhlfe); -  return 0; +	return 0;  } -static int -mpls_lsp_uninstall_all (struct hash *lsp_table, zebra_lsp_t *lsp, -			enum lsp_types_t type) +static int mpls_lsp_uninstall_all(struct hash *lsp_table, zebra_lsp_t *lsp, +				  enum lsp_types_t type)  { -  zebra_nhlfe_t *nhlfe, *nhlfe_next; -  int schedule_lsp = 0; -  char buf[BUFSIZ]; - -  /* Mark NHLFEs for delete or directly delete, as appropriate. */ -  for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe_next) -    { -      nhlfe_next = nhlfe->next; - -      /* Skip non-static NHLFEs */ -      if (nhlfe->type != type) -        continue; - -      if (IS_ZEBRA_DEBUG_MPLS) -        { -          nhlfe2str (nhlfe, buf, BUFSIZ); -          zlog_debug ("Del LSP in-label %u type %d nexthop %s flags 0x%x", -                      lsp->ile.in_label, type, buf, nhlfe->flags); -        } - -      if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED)) -        { -          UNSET_FLAG (nhlfe->flags, NHLFE_FLAG_CHANGED); -          SET_FLAG (nhlfe->flags, NHLFE_FLAG_DELETED); -          schedule_lsp = 1; -        } -      else -        { -          nhlfe_del (nhlfe); -        } -    } - -  /* Queue LSP for processing, if needed, else delete. */ -  if (schedule_lsp) -    { -      if (lsp_processq_add (lsp)) -        return -1; -    } -  else if (!lsp->nhlfe_list && -           !CHECK_FLAG (lsp->flags, LSP_FLAG_SCHEDULED)) -    { -      if (IS_ZEBRA_DEBUG_MPLS) -        zlog_debug ("Free LSP in-label %u flags 0x%x", -                    lsp->ile.in_label, lsp->flags); - -      lsp = hash_release(lsp_table, &lsp->ile); -      if (lsp) -        XFREE(MTYPE_LSP, lsp); -    } - -  return 0; +	zebra_nhlfe_t *nhlfe, *nhlfe_next; +	int schedule_lsp = 0; +	char buf[BUFSIZ]; + +	/* Mark NHLFEs for delete or directly delete, as appropriate. */ +	for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe_next) { +		nhlfe_next = nhlfe->next; + +		/* Skip non-static NHLFEs */ +		if (nhlfe->type != type) +			continue; + +		if (IS_ZEBRA_DEBUG_MPLS) { +			nhlfe2str(nhlfe, buf, BUFSIZ); +			zlog_debug( +				"Del LSP in-label %u type %d nexthop %s flags 0x%x", +				lsp->ile.in_label, type, buf, nhlfe->flags); +		} + +		if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED)) { +			UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_CHANGED); +			SET_FLAG(nhlfe->flags, NHLFE_FLAG_DELETED); +			schedule_lsp = 1; +		} else { +			nhlfe_del(nhlfe); +		} +	} + +	/* Queue LSP for processing, if needed, else delete. */ +	if (schedule_lsp) { +		if (lsp_processq_add(lsp)) +			return -1; +	} else if (!lsp->nhlfe_list +		   && !CHECK_FLAG(lsp->flags, LSP_FLAG_SCHEDULED)) { +		if (IS_ZEBRA_DEBUG_MPLS) +			zlog_debug("Free LSP in-label %u flags 0x%x", +				   lsp->ile.in_label, lsp->flags); + +		lsp = hash_release(lsp_table, &lsp->ile); +		if (lsp) +			XFREE(MTYPE_LSP, lsp); +	} + +	return 0;  }  /*   * Uninstall all static NHLFEs for a particular LSP forwarding entry.   * If no other NHLFEs exist, the entry would be deleted.   */ -static int -mpls_static_lsp_uninstall_all (struct zebra_vrf *zvrf, mpls_label_t in_label) +static int mpls_static_lsp_uninstall_all(struct zebra_vrf *zvrf, +					 mpls_label_t in_label)  { -  struct hash *lsp_table; -  zebra_ile_t tmp_ile; -  zebra_lsp_t *lsp; - -  /* Lookup table. */ -  lsp_table = zvrf->lsp_table; -  if (!lsp_table) -    return -1; - -  /* If entry is not present, exit. */ -  tmp_ile.in_label = in_label; -  lsp = hash_lookup (lsp_table, &tmp_ile); -  if (!lsp || !lsp->nhlfe_list) -    return 0; - -  return mpls_lsp_uninstall_all (lsp_table, lsp, ZEBRA_LSP_STATIC); +	struct hash *lsp_table; +	zebra_ile_t tmp_ile; +	zebra_lsp_t *lsp; + +	/* Lookup table. */ +	lsp_table = zvrf->lsp_table; +	if (!lsp_table) +		return -1; + +	/* If entry is not present, exit. */ +	tmp_ile.in_label = in_label; +	lsp = hash_lookup(lsp_table, &tmp_ile); +	if (!lsp || !lsp->nhlfe_list) +		return 0; + +	return mpls_lsp_uninstall_all(lsp_table, lsp, ZEBRA_LSP_STATIC);  } -static json_object * -nhlfe_json (zebra_nhlfe_t *nhlfe) +static json_object *nhlfe_json(zebra_nhlfe_t *nhlfe)  { -  char buf[BUFSIZ]; -  json_object *json_nhlfe = NULL; -  struct nexthop *nexthop = nhlfe->nexthop; - -  json_nhlfe = json_object_new_object(); -  json_object_string_add(json_nhlfe, "type", nhlfe_type2str(nhlfe->type)); -  json_object_int_add(json_nhlfe, "outLabel", nexthop->nh_label->label[0]); -  json_object_int_add(json_nhlfe, "distance", nhlfe->distance); - -  if (CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_INSTALLED)) -    json_object_boolean_true_add(json_nhlfe, "installed"); - -  switch (nexthop->type) -    { -    case NEXTHOP_TYPE_IPV4: -    case NEXTHOP_TYPE_IPV4_IFINDEX: -      json_object_string_add(json_nhlfe, "nexthop", -                             inet_ntoa (nexthop->gate.ipv4)); -      break; -    case NEXTHOP_TYPE_IPV6: -    case NEXTHOP_TYPE_IPV6_IFINDEX: -      json_object_string_add(json_nhlfe, "nexthop", -                             inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ)); - -      if (nexthop->ifindex) -        json_object_string_add(json_nhlfe, "interface", ifindex2ifname (nexthop->ifindex, VRF_DEFAULT)); -      break; -    default: -      break; -    } -  return json_nhlfe; +	char buf[BUFSIZ]; +	json_object *json_nhlfe = NULL; +	struct nexthop *nexthop = nhlfe->nexthop; + +	json_nhlfe = json_object_new_object(); +	json_object_string_add(json_nhlfe, "type", nhlfe_type2str(nhlfe->type)); +	json_object_int_add(json_nhlfe, "outLabel", +			    nexthop->nh_label->label[0]); +	json_object_int_add(json_nhlfe, "distance", nhlfe->distance); + +	if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED)) +		json_object_boolean_true_add(json_nhlfe, "installed"); + +	switch (nexthop->type) { +	case NEXTHOP_TYPE_IPV4: +	case NEXTHOP_TYPE_IPV4_IFINDEX: +		json_object_string_add(json_nhlfe, "nexthop", +				       inet_ntoa(nexthop->gate.ipv4)); +		break; +	case NEXTHOP_TYPE_IPV6: +	case NEXTHOP_TYPE_IPV6_IFINDEX: +		json_object_string_add( +			json_nhlfe, "nexthop", +			inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ)); + +		if (nexthop->ifindex) +			json_object_string_add( +				json_nhlfe, "interface", +				ifindex2ifname(nexthop->ifindex, VRF_DEFAULT)); +		break; +	default: +		break; +	} +	return json_nhlfe;  }  /*   * Print the NHLFE for a LSP forwarding entry.   */ -static void -nhlfe_print (zebra_nhlfe_t *nhlfe, struct vty *vty) +static void nhlfe_print(zebra_nhlfe_t *nhlfe, struct vty *vty)  { -  struct nexthop *nexthop; -  char buf[BUFSIZ]; - -  nexthop = nhlfe->nexthop; -  if (!nexthop || !nexthop->nh_label) // unexpected -    return; - -  vty_out(vty, " type: %s remote label: %s distance: %d%s", -          nhlfe_type2str(nhlfe->type), -          label2str(nexthop->nh_label->label[0], buf, BUFSIZ), -          nhlfe->distance, VTY_NEWLINE); -  switch (nexthop->type) -    { -    case NEXTHOP_TYPE_IPV4: -    case NEXTHOP_TYPE_IPV4_IFINDEX: -      vty_out (vty, "  via %s", inet_ntoa (nexthop->gate.ipv4)); -      if (nexthop->ifindex) -        vty_out (vty, " dev %s", ifindex2ifname (nexthop->ifindex, VRF_DEFAULT)); -      break; -    case NEXTHOP_TYPE_IPV6: -    case NEXTHOP_TYPE_IPV6_IFINDEX: -      vty_out (vty, "  via %s", -               inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ)); -      if (nexthop->ifindex) -        vty_out (vty, " dev %s", ifindex2ifname (nexthop->ifindex, VRF_DEFAULT)); -      break; -    default: -      break; -    } -  vty_out(vty, "%s", CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_INSTALLED) ? -          " (installed)" : ""); -  vty_out(vty, "%s", VTY_NEWLINE); +	struct nexthop *nexthop; +	char buf[BUFSIZ]; + +	nexthop = nhlfe->nexthop; +	if (!nexthop || !nexthop->nh_label) // unexpected +		return; + +	vty_out(vty, " type: %s remote label: %s distance: %d%s", +		nhlfe_type2str(nhlfe->type), +		label2str(nexthop->nh_label->label[0], buf, BUFSIZ), +		nhlfe->distance, VTY_NEWLINE); +	switch (nexthop->type) { +	case NEXTHOP_TYPE_IPV4: +	case NEXTHOP_TYPE_IPV4_IFINDEX: +		vty_out(vty, "  via %s", inet_ntoa(nexthop->gate.ipv4)); +		if (nexthop->ifindex) +			vty_out(vty, " dev %s", +				ifindex2ifname(nexthop->ifindex, VRF_DEFAULT)); +		break; +	case NEXTHOP_TYPE_IPV6: +	case NEXTHOP_TYPE_IPV6_IFINDEX: +		vty_out(vty, "  via %s", +			inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ)); +		if (nexthop->ifindex) +			vty_out(vty, " dev %s", +				ifindex2ifname(nexthop->ifindex, VRF_DEFAULT)); +		break; +	default: +		break; +	} +	vty_out(vty, "%s", +		CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED) ? " (installed)" +							       : ""); +	vty_out(vty, "%s", VTY_NEWLINE);  }  /*   * Print an LSP forwarding entry.   */ -static void -lsp_print (zebra_lsp_t *lsp, void *ctxt) +static void lsp_print(zebra_lsp_t *lsp, void *ctxt)  { -  zebra_nhlfe_t *nhlfe; -  struct vty *vty; +	zebra_nhlfe_t *nhlfe; +	struct vty *vty; -  vty = (struct vty *) ctxt; +	vty = (struct vty *)ctxt; -  vty_out(vty, "Local label: %u%s%s", -          lsp->ile.in_label, -          CHECK_FLAG (lsp->flags, LSP_FLAG_INSTALLED) ? " (installed)" : "", -          VTY_NEWLINE); +	vty_out(vty, "Local label: %u%s%s", lsp->ile.in_label, +		CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED) ? " (installed)" +							   : "", +		VTY_NEWLINE); -  for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) -    nhlfe_print (nhlfe, vty); +	for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) +		nhlfe_print(nhlfe, vty);  }  /*   * JSON objects for an LSP forwarding entry.   */ -static json_object * -lsp_json (zebra_lsp_t *lsp) +static json_object *lsp_json(zebra_lsp_t *lsp)  { -  zebra_nhlfe_t *nhlfe = NULL; -  json_object *json = json_object_new_object(); -  json_object *json_nhlfe_list = json_object_new_array(); +	zebra_nhlfe_t *nhlfe = NULL; +	json_object *json = json_object_new_object(); +	json_object *json_nhlfe_list = json_object_new_array(); -  json_object_int_add(json, "inLabel", lsp->ile.in_label); +	json_object_int_add(json, "inLabel", lsp->ile.in_label); -  if (CHECK_FLAG (lsp->flags, LSP_FLAG_INSTALLED)) -    json_object_boolean_true_add(json, "installed"); +	if (CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED)) +		json_object_boolean_true_add(json, "installed"); -  for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) -    json_object_array_add(json_nhlfe_list, nhlfe_json(nhlfe)); +	for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) +		json_object_array_add(json_nhlfe_list, nhlfe_json(nhlfe)); -  json_object_object_add(json, "nexthops", json_nhlfe_list); -  return json; +	json_object_object_add(json, "nexthops", json_nhlfe_list); +	return json;  }  /* Return a sorted linked list of the hash contents */ -static struct list * -hash_get_sorted_list (struct hash *hash, void *cmp) +static struct list *hash_get_sorted_list(struct hash *hash, void *cmp)  { -  unsigned int i; -  struct hash_backet *hb; -  struct list *sorted_list = list_new(); +	unsigned int i; +	struct hash_backet *hb; +	struct list *sorted_list = list_new(); -  sorted_list->cmp = (int (*)(void *, void *)) cmp; +	sorted_list->cmp = (int (*)(void *, void *))cmp; -  for (i = 0; i < hash->size; i++) -    for (hb = hash->index[i]; hb; hb = hb->next) -        listnode_add_sort(sorted_list, hb->data); +	for (i = 0; i < hash->size; i++) +		for (hb = hash->index[i]; hb; hb = hb->next) +			listnode_add_sort(sorted_list, hb->data); -  return sorted_list; +	return sorted_list;  }  /*   * Compare two LSPs based on their label values.   */ -static int -lsp_cmp (zebra_lsp_t *lsp1, zebra_lsp_t *lsp2) +static int lsp_cmp(zebra_lsp_t *lsp1, zebra_lsp_t *lsp2)  { -  if (lsp1->ile.in_label < lsp2->ile.in_label) -    return -1; +	if (lsp1->ile.in_label < lsp2->ile.in_label) +		return -1; -  if (lsp1->ile.in_label > lsp2->ile.in_label) -    return 1; +	if (lsp1->ile.in_label > lsp2->ile.in_label) +		return 1; -  return 0; +	return 0;  }  /*   * Callback to allocate static LSP.   */ -static void * -slsp_alloc (void *p) +static void *slsp_alloc(void *p)  { -  const zebra_ile_t *ile = p; -  zebra_slsp_t *slsp; +	const zebra_ile_t *ile = p; +	zebra_slsp_t *slsp; -  slsp = XCALLOC (MTYPE_SLSP, sizeof(zebra_slsp_t)); -  slsp->ile = *ile; -  return ((void *)slsp); +	slsp = XCALLOC(MTYPE_SLSP, sizeof(zebra_slsp_t)); +	slsp->ile = *ile; +	return ((void *)slsp);  }  /*   * Compare two static LSPs based on their label values.   */ -static int -slsp_cmp (zebra_slsp_t *slsp1, zebra_slsp_t *slsp2) +static int slsp_cmp(zebra_slsp_t *slsp1, zebra_slsp_t *slsp2)  { -  if (slsp1->ile.in_label < slsp2->ile.in_label) -    return -1; +	if (slsp1->ile.in_label < slsp2->ile.in_label) +		return -1; -  if (slsp1->ile.in_label > slsp2->ile.in_label) -    return 1; +	if (slsp1->ile.in_label > slsp2->ile.in_label) +		return 1; -  return 0; +	return 0;  }  /*   * Check if static NHLFE matches with search info passed.   */ -static int -snhlfe_match (zebra_snhlfe_t *snhlfe, enum nexthop_types_t gtype, -              union g_addr *gate, char *ifname, ifindex_t ifindex) +static int snhlfe_match(zebra_snhlfe_t *snhlfe, enum nexthop_types_t gtype, +			union g_addr *gate, char *ifname, ifindex_t ifindex)  { -  int cmp = 1; - -  if (snhlfe->gtype != gtype) -    return 1; - -  switch (snhlfe->gtype) -    { -    case NEXTHOP_TYPE_IPV4: -      cmp = memcmp(&(snhlfe->gate.ipv4), &(gate->ipv4), -		   sizeof(struct in_addr)); -      break; -    case NEXTHOP_TYPE_IPV6: -    case NEXTHOP_TYPE_IPV6_IFINDEX: -      cmp = memcmp(&(snhlfe->gate.ipv6), &(gate->ipv6), -		   sizeof(struct in6_addr)); -      if (!cmp && snhlfe->gtype == NEXTHOP_TYPE_IPV6_IFINDEX) -        cmp = !(snhlfe->ifindex == ifindex); -      break; -    default: -      break; -    } - -  return cmp; +	int cmp = 1; + +	if (snhlfe->gtype != gtype) +		return 1; + +	switch (snhlfe->gtype) { +	case NEXTHOP_TYPE_IPV4: +		cmp = memcmp(&(snhlfe->gate.ipv4), &(gate->ipv4), +			     sizeof(struct in_addr)); +		break; +	case NEXTHOP_TYPE_IPV6: +	case NEXTHOP_TYPE_IPV6_IFINDEX: +		cmp = memcmp(&(snhlfe->gate.ipv6), &(gate->ipv6), +			     sizeof(struct in6_addr)); +		if (!cmp && snhlfe->gtype == NEXTHOP_TYPE_IPV6_IFINDEX) +			cmp = !(snhlfe->ifindex == ifindex); +		break; +	default: +		break; +	} + +	return cmp;  }  /*   * Locate static NHLFE that matches with passed info.   */ -static zebra_snhlfe_t * -snhlfe_find (zebra_slsp_t *slsp, enum nexthop_types_t gtype, -             union g_addr *gate, char *ifname, ifindex_t ifindex) +static zebra_snhlfe_t *snhlfe_find(zebra_slsp_t *slsp, +				   enum nexthop_types_t gtype, +				   union g_addr *gate, char *ifname, +				   ifindex_t ifindex)  { -  zebra_snhlfe_t *snhlfe; +	zebra_snhlfe_t *snhlfe; -  if (!slsp) -    return NULL; +	if (!slsp) +		return NULL; -  for (snhlfe = slsp->snhlfe_list; snhlfe; snhlfe = snhlfe->next) -    { -      if (!snhlfe_match (snhlfe, gtype, gate, ifname, ifindex)) -        break; -    } +	for (snhlfe = slsp->snhlfe_list; snhlfe; snhlfe = snhlfe->next) { +		if (!snhlfe_match(snhlfe, gtype, gate, ifname, ifindex)) +			break; +	} -  return snhlfe; +	return snhlfe;  } @@ -1079,140 +1010,132 @@ snhlfe_find (zebra_slsp_t *slsp, enum nexthop_types_t gtype,   * Add static NHLFE. Base LSP config entry must have been created   * and duplicate check done.   */ -static zebra_snhlfe_t * -snhlfe_add (zebra_slsp_t *slsp, enum nexthop_types_t gtype, -            union g_addr *gate, char *ifname, ifindex_t ifindex, -            mpls_label_t out_label) +static zebra_snhlfe_t *snhlfe_add(zebra_slsp_t *slsp, +				  enum nexthop_types_t gtype, +				  union g_addr *gate, char *ifname, +				  ifindex_t ifindex, mpls_label_t out_label)  { -  zebra_snhlfe_t *snhlfe; - -  if (!slsp) -    return NULL; - -  snhlfe = XCALLOC(MTYPE_SNHLFE, sizeof(zebra_snhlfe_t)); -  snhlfe->slsp = slsp; -  snhlfe->out_label = out_label; -  snhlfe->gtype = gtype; -  switch (gtype) -    { -    case NEXTHOP_TYPE_IPV4: -      snhlfe->gate.ipv4 = gate->ipv4; -      break; -    case NEXTHOP_TYPE_IPV6: -    case NEXTHOP_TYPE_IPV6_IFINDEX: -      snhlfe->gate.ipv6 = gate->ipv6; -      if (ifindex) -        snhlfe->ifindex = ifindex; -      break; -    default: -      XFREE (MTYPE_SNHLFE, snhlfe); -      return NULL; -    } - -  if (slsp->snhlfe_list) -    slsp->snhlfe_list->prev = snhlfe; -  snhlfe->next = slsp->snhlfe_list; -  slsp->snhlfe_list = snhlfe; - -  return snhlfe; +	zebra_snhlfe_t *snhlfe; + +	if (!slsp) +		return NULL; + +	snhlfe = XCALLOC(MTYPE_SNHLFE, sizeof(zebra_snhlfe_t)); +	snhlfe->slsp = slsp; +	snhlfe->out_label = out_label; +	snhlfe->gtype = gtype; +	switch (gtype) { +	case NEXTHOP_TYPE_IPV4: +		snhlfe->gate.ipv4 = gate->ipv4; +		break; +	case NEXTHOP_TYPE_IPV6: +	case NEXTHOP_TYPE_IPV6_IFINDEX: +		snhlfe->gate.ipv6 = gate->ipv6; +		if (ifindex) +			snhlfe->ifindex = ifindex; +		break; +	default: +		XFREE(MTYPE_SNHLFE, snhlfe); +		return NULL; +	} + +	if (slsp->snhlfe_list) +		slsp->snhlfe_list->prev = snhlfe; +	snhlfe->next = slsp->snhlfe_list; +	slsp->snhlfe_list = snhlfe; + +	return snhlfe;  }  /*   * Delete static NHLFE. Entry must be present on list.   */ -static int -snhlfe_del (zebra_snhlfe_t *snhlfe) +static int snhlfe_del(zebra_snhlfe_t *snhlfe)  { -  zebra_slsp_t *slsp; +	zebra_slsp_t *slsp; -  if (!snhlfe) -    return -1; +	if (!snhlfe) +		return -1; -  slsp = snhlfe->slsp; -  if (!slsp) -    return -1; +	slsp = snhlfe->slsp; +	if (!slsp) +		return -1; -  if (snhlfe->next) -    snhlfe->next->prev = snhlfe->prev; -  if (snhlfe->prev) -    snhlfe->prev->next = snhlfe->next; -  else -    slsp->snhlfe_list = snhlfe->next; +	if (snhlfe->next) +		snhlfe->next->prev = snhlfe->prev; +	if (snhlfe->prev) +		snhlfe->prev->next = snhlfe->next; +	else +		slsp->snhlfe_list = snhlfe->next; -  snhlfe->prev = snhlfe->next = NULL; -  if (snhlfe->ifname) -    XFREE (MTYPE_SNHLFE_IFNAME, snhlfe->ifname); -  XFREE (MTYPE_SNHLFE, snhlfe); +	snhlfe->prev = snhlfe->next = NULL; +	if (snhlfe->ifname) +		XFREE(MTYPE_SNHLFE_IFNAME, snhlfe->ifname); +	XFREE(MTYPE_SNHLFE, snhlfe); -  return 0; +	return 0;  }  /*   * Delete all static NHLFE entries for this LSP (in label).   */ -static int -snhlfe_del_all (zebra_slsp_t *slsp) +static int snhlfe_del_all(zebra_slsp_t *slsp)  { -  zebra_snhlfe_t *snhlfe, *snhlfe_next; +	zebra_snhlfe_t *snhlfe, *snhlfe_next; -  if (!slsp) -    return -1; +	if (!slsp) +		return -1; -  for (snhlfe = slsp->snhlfe_list; snhlfe; snhlfe = snhlfe_next) -    { -      snhlfe_next = snhlfe->next; -      snhlfe_del (snhlfe); -    } +	for (snhlfe = slsp->snhlfe_list; snhlfe; snhlfe = snhlfe_next) { +		snhlfe_next = snhlfe->next; +		snhlfe_del(snhlfe); +	} -  return 0; +	return 0;  }  /*   * Create printable string for NHLFE configuration.   */ -static char * -snhlfe2str (zebra_snhlfe_t *snhlfe, char *buf, int size) +static char *snhlfe2str(zebra_snhlfe_t *snhlfe, char *buf, int size)  { -  buf[0] = '\0'; -  switch (snhlfe->gtype) -    { -      case NEXTHOP_TYPE_IPV4: -        inet_ntop (AF_INET, &snhlfe->gate.ipv4, buf, size); -        break; -      case NEXTHOP_TYPE_IPV6: -      case NEXTHOP_TYPE_IPV6_IFINDEX: -        inet_ntop (AF_INET6, &snhlfe->gate.ipv6, buf, size); -        if (snhlfe->ifindex) -          strcat (buf, ifindex2ifname (snhlfe->ifindex, VRF_DEFAULT)); -        break; -      default: -        break; -    } - -  return buf; +	buf[0] = '\0'; +	switch (snhlfe->gtype) { +	case NEXTHOP_TYPE_IPV4: +		inet_ntop(AF_INET, &snhlfe->gate.ipv4, buf, size); +		break; +	case NEXTHOP_TYPE_IPV6: +	case NEXTHOP_TYPE_IPV6_IFINDEX: +		inet_ntop(AF_INET6, &snhlfe->gate.ipv6, buf, size); +		if (snhlfe->ifindex) +			strcat(buf, +			       ifindex2ifname(snhlfe->ifindex, VRF_DEFAULT)); +		break; +	default: +		break; +	} + +	return buf;  }  /*   * Initialize work queue for processing changed LSPs.   */ -static void -mpls_processq_init (struct zebra_t *zebra) +static void mpls_processq_init(struct zebra_t *zebra)  { -  zebra->lsp_process_q = work_queue_new (zebra->master, "LSP processing"); -  if (!zebra->lsp_process_q) -    { -      zlog_err ("%s: could not initialise work queue!", __func__); -      return; -    } - -  zebra->lsp_process_q->spec.workfunc = &lsp_process; -  zebra->lsp_process_q->spec.del_item_data = &lsp_processq_del; -  zebra->lsp_process_q->spec.errorfunc = NULL; -  zebra->lsp_process_q->spec.completion_func = &lsp_processq_complete; -  zebra->lsp_process_q->spec.max_retries = 0; -  zebra->lsp_process_q->spec.hold = 10; -} +	zebra->lsp_process_q = work_queue_new(zebra->master, "LSP processing"); +	if (!zebra->lsp_process_q) { +		zlog_err("%s: could not initialise work queue!", __func__); +		return; +	} +	zebra->lsp_process_q->spec.workfunc = &lsp_process; +	zebra->lsp_process_q->spec.del_item_data = &lsp_processq_del; +	zebra->lsp_process_q->spec.errorfunc = NULL; +	zebra->lsp_process_q->spec.completion_func = &lsp_processq_complete; +	zebra->lsp_process_q->spec.max_retries = 0; +	zebra->lsp_process_q->spec.hold = 10; +}  /* Public functions */ @@ -1220,136 +1143,132 @@ mpls_processq_init (struct zebra_t *zebra)  /*   * String to label conversion, labels separated by '/'.   */ -int -mpls_str2label (const char *label_str, u_int8_t *num_labels, -                mpls_label_t *labels) +int mpls_str2label(const char *label_str, u_int8_t *num_labels, +		   mpls_label_t *labels)  { -  char *endp; -  int i; +	char *endp; +	int i; -  *num_labels = 0; -  for (i = 0; i < MPLS_MAX_LABELS; i++) -    { -      u_int32_t label; +	*num_labels = 0; +	for (i = 0; i < MPLS_MAX_LABELS; i++) { +		u_int32_t label; -      label = strtoul(label_str, &endp, 0); +		label = strtoul(label_str, &endp, 0); -      /* validity checks */ -      if (endp == label_str) -        return -1; +		/* validity checks */ +		if (endp == label_str) +			return -1; -      if (!IS_MPLS_UNRESERVED_LABEL(label)) -        return -1; +		if (!IS_MPLS_UNRESERVED_LABEL(label)) +			return -1; -      labels[i] = label; -      if (*endp == '\0') -        { -          *num_labels = i + 1; -          return 0; -        } +		labels[i] = label; +		if (*endp == '\0') { +			*num_labels = i + 1; +			return 0; +		} -      /* Check separator. */ -      if (*endp != '/') -        return -1; +		/* Check separator. */ +		if (*endp != '/') +			return -1; -      label_str = endp + 1; -    } +		label_str = endp + 1; +	} -  /* Too many labels. */ -  return -1; +	/* Too many labels. */ +	return -1;  }  /*   * Label to string conversion, labels in string separated by '/'.   */ -char * -mpls_label2str (u_int8_t num_labels, mpls_label_t *labels, -                char *buf, int len) +char *mpls_label2str(u_int8_t num_labels, mpls_label_t *labels, char *buf, +		     int len)  { -  buf[0] = '\0'; -  if (num_labels == 1) -    snprintf (buf, len, "%u", labels[0]); -  else if (num_labels == 2) -    snprintf (buf, len, "%u/%u", labels[0], labels[1]); -  return buf; +	buf[0] = '\0'; +	if (num_labels == 1) +		snprintf(buf, len, "%u", labels[0]); +	else if (num_labels == 2) +		snprintf(buf, len, "%u/%u", labels[0], labels[1]); +	return buf;  }  /*   * Install/uninstall a FEC-To-NHLFE (FTN) binding.   */ -int -mpls_ftn_update (int add, struct zebra_vrf *zvrf, enum lsp_types_t type, -		 struct prefix *prefix, enum nexthop_types_t gtype, -		 union g_addr *gate, ifindex_t ifindex, u_int8_t distance, -		 mpls_label_t out_label) +int mpls_ftn_update(int add, struct zebra_vrf *zvrf, enum lsp_types_t type, +		    struct prefix *prefix, enum nexthop_types_t gtype, +		    union g_addr *gate, ifindex_t ifindex, u_int8_t distance, +		    mpls_label_t out_label)  { -  struct route_table *table; -  struct route_node *rn; -  struct rib *rib; -  struct nexthop *nexthop; - -  /* Lookup table.  */ -  table = zebra_vrf_table (family2afi(prefix->family), SAFI_UNICAST, zvrf_id (zvrf)); -  if (! table) -    return -1; - -  /* Lookup existing route */ -  rn = route_node_get (table, prefix); -  RNODE_FOREACH_RIB (rn, rib) -    { -       if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) -         continue; -       if (rib->distance == distance) -         break; -    } - -  if (rib == NULL) -    return -1; - -  for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) -    { -      switch (nexthop->type) +	struct route_table *table; +	struct route_node *rn; +	struct rib *rib; +	struct nexthop *nexthop; + +	/* Lookup table.  */ +	table = zebra_vrf_table(family2afi(prefix->family), SAFI_UNICAST, +				zvrf_id(zvrf)); +	if (!table) +		return -1; + +	/* Lookup existing route */ +	rn = route_node_get(table, prefix); +	RNODE_FOREACH_RIB(rn, rib)  	{ -	case NEXTHOP_TYPE_IPV4: -	case NEXTHOP_TYPE_IPV4_IFINDEX: -	  if (gtype != NEXTHOP_TYPE_IPV4 && gtype != NEXTHOP_TYPE_IPV4_IFINDEX) -	    continue; -	  if (! IPV4_ADDR_SAME (&nexthop->gate.ipv4, &gate->ipv4)) -	    continue; -	  if (nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX && -	      nexthop->ifindex != ifindex) -	    continue; -	  goto found; -	case NEXTHOP_TYPE_IPV6: -	case NEXTHOP_TYPE_IPV6_IFINDEX: -	  if (gtype != NEXTHOP_TYPE_IPV6 && gtype != NEXTHOP_TYPE_IPV6_IFINDEX) -	    continue; -	  if (! IPV6_ADDR_SAME (&nexthop->gate.ipv6, &gate->ipv6)) -	    continue; -	  if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX && -	      nexthop->ifindex != ifindex) -	    continue; -	  goto found; -	default: -	  break; +		if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED)) +			continue; +		if (rib->distance == distance) +			break;  	} -    } -  /* nexthop not found */ -  return -1; - - found: -  if (add && nexthop->nh_label_type == ZEBRA_LSP_NONE) -    nexthop_add_labels (nexthop, type, 1, &out_label); -  else if (!add && nexthop->nh_label_type == type) -    nexthop_del_labels (nexthop); -  else -    return 0; - -  SET_FLAG (rib->status, RIB_ENTRY_CHANGED); -  SET_FLAG (rib->status, RIB_ENTRY_LABELS_CHANGED); -  rib_queue_add (rn); - -  return 0; + +	if (rib == NULL) +		return -1; + +	for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) { +		switch (nexthop->type) { +		case NEXTHOP_TYPE_IPV4: +		case NEXTHOP_TYPE_IPV4_IFINDEX: +			if (gtype != NEXTHOP_TYPE_IPV4 +			    && gtype != NEXTHOP_TYPE_IPV4_IFINDEX) +				continue; +			if (!IPV4_ADDR_SAME(&nexthop->gate.ipv4, &gate->ipv4)) +				continue; +			if (nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX +			    && nexthop->ifindex != ifindex) +				continue; +			goto found; +		case NEXTHOP_TYPE_IPV6: +		case NEXTHOP_TYPE_IPV6_IFINDEX: +			if (gtype != NEXTHOP_TYPE_IPV6 +			    && gtype != NEXTHOP_TYPE_IPV6_IFINDEX) +				continue; +			if (!IPV6_ADDR_SAME(&nexthop->gate.ipv6, &gate->ipv6)) +				continue; +			if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX +			    && nexthop->ifindex != ifindex) +				continue; +			goto found; +		default: +			break; +		} +	} +	/* nexthop not found */ +	return -1; + +found: +	if (add && nexthop->nh_label_type == ZEBRA_LSP_NONE) +		nexthop_add_labels(nexthop, type, 1, &out_label); +	else if (!add && nexthop->nh_label_type == type) +		nexthop_del_labels(nexthop); +	else +		return 0; + +	SET_FLAG(rib->status, RIB_ENTRY_CHANGED); +	SET_FLAG(rib->status, RIB_ENTRY_LABELS_CHANGED); +	rib_queue_add(rn); + +	return 0;  }  /* @@ -1357,198 +1276,185 @@ mpls_ftn_update (int add, struct zebra_vrf *zvrf, enum lsp_types_t type,   * a new LSP entry or a new NHLFE for an existing in-label or an update of   * the out-label for an existing NHLFE (update case).   */ -int -mpls_lsp_install (struct zebra_vrf *zvrf, enum lsp_types_t type, -		  mpls_label_t in_label, mpls_label_t out_label, -		  enum nexthop_types_t gtype, union g_addr *gate, -		  char *ifname, ifindex_t ifindex) +int mpls_lsp_install(struct zebra_vrf *zvrf, enum lsp_types_t type, +		     mpls_label_t in_label, mpls_label_t out_label, +		     enum nexthop_types_t gtype, union g_addr *gate, +		     char *ifname, ifindex_t ifindex)  { -  struct hash *lsp_table; -  zebra_ile_t tmp_ile; -  zebra_lsp_t *lsp; -  zebra_nhlfe_t *nhlfe; -  char buf[BUFSIZ]; - -  /* Lookup table. */ -  lsp_table = zvrf->lsp_table; -  if (!lsp_table) -    return -1; - -  /* If entry is present, exit. */ -  tmp_ile.in_label = in_label; -  lsp = hash_get (lsp_table, &tmp_ile, lsp_alloc); -  if (!lsp) -    return -1; -  nhlfe = nhlfe_find (lsp, type, gtype, gate, ifname, ifindex); -  if (nhlfe) -    { -      struct nexthop *nh = nhlfe->nexthop; - -      assert (nh); -      assert (nh->nh_label); - -      /* Clear deleted flag (in case it was set) */ -      UNSET_FLAG (nhlfe->flags, NHLFE_FLAG_DELETED); -      if (nh->nh_label->label[0] == out_label) -        /* No change */ -        return 0; - -      if (IS_ZEBRA_DEBUG_MPLS) -        { -          nhlfe2str (nhlfe, buf, BUFSIZ); -          zlog_debug ("LSP in-label %u type %d nexthop %s " -                      "out-label changed to %u (old %u)", -                      in_label, type, buf, -                      out_label, nh->nh_label->label[0]); -        } - -      /* Update out label, trigger processing. */ -      nh->nh_label->label[0] = out_label; -    } -  else -    { -      /* Add LSP entry to this nexthop */ -      nhlfe = nhlfe_add (lsp, type, gtype, gate, -                         ifname, ifindex, out_label); -      if (!nhlfe) -        return -1; - -      if (IS_ZEBRA_DEBUG_MPLS) -        { -          nhlfe2str (nhlfe, buf, BUFSIZ); -          zlog_debug ("Add LSP in-label %u type %d nexthop %s " -                      "out-label %u", in_label, type, buf, out_label); -        } - -      lsp->addr_family = NHLFE_FAMILY (nhlfe); -    } - -  /* Mark NHLFE, queue LSP for processing. */ -  SET_FLAG(nhlfe->flags, NHLFE_FLAG_CHANGED); -  if (lsp_processq_add (lsp)) -    return -1; - -  return 0; +	struct hash *lsp_table; +	zebra_ile_t tmp_ile; +	zebra_lsp_t *lsp; +	zebra_nhlfe_t *nhlfe; +	char buf[BUFSIZ]; + +	/* Lookup table. */ +	lsp_table = zvrf->lsp_table; +	if (!lsp_table) +		return -1; + +	/* If entry is present, exit. */ +	tmp_ile.in_label = in_label; +	lsp = hash_get(lsp_table, &tmp_ile, lsp_alloc); +	if (!lsp) +		return -1; +	nhlfe = nhlfe_find(lsp, type, gtype, gate, ifname, ifindex); +	if (nhlfe) { +		struct nexthop *nh = nhlfe->nexthop; + +		assert(nh); +		assert(nh->nh_label); + +		/* Clear deleted flag (in case it was set) */ +		UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_DELETED); +		if (nh->nh_label->label[0] == out_label) +			/* No change */ +			return 0; + +		if (IS_ZEBRA_DEBUG_MPLS) { +			nhlfe2str(nhlfe, buf, BUFSIZ); +			zlog_debug( +				"LSP in-label %u type %d nexthop %s " +				"out-label changed to %u (old %u)", +				in_label, type, buf, out_label, +				nh->nh_label->label[0]); +		} + +		/* Update out label, trigger processing. */ +		nh->nh_label->label[0] = out_label; +	} else { +		/* Add LSP entry to this nexthop */ +		nhlfe = nhlfe_add(lsp, type, gtype, gate, ifname, ifindex, +				  out_label); +		if (!nhlfe) +			return -1; + +		if (IS_ZEBRA_DEBUG_MPLS) { +			nhlfe2str(nhlfe, buf, BUFSIZ); +			zlog_debug( +				"Add LSP in-label %u type %d nexthop %s " +				"out-label %u", +				in_label, type, buf, out_label); +		} + +		lsp->addr_family = NHLFE_FAMILY(nhlfe); +	} + +	/* Mark NHLFE, queue LSP for processing. */ +	SET_FLAG(nhlfe->flags, NHLFE_FLAG_CHANGED); +	if (lsp_processq_add(lsp)) +		return -1; + +	return 0;  }  /*   * Uninstall a particular NHLFE in the forwarding table. If this is   * the only NHLFE, the entire LSP forwarding entry has to be deleted.   */ -int -mpls_lsp_uninstall (struct zebra_vrf *zvrf, enum lsp_types_t type, -		    mpls_label_t in_label, enum nexthop_types_t gtype, -		    union g_addr *gate, char *ifname, ifindex_t ifindex) +int mpls_lsp_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type, +		       mpls_label_t in_label, enum nexthop_types_t gtype, +		       union g_addr *gate, char *ifname, ifindex_t ifindex)  { -  struct hash *lsp_table; -  zebra_ile_t tmp_ile; -  zebra_lsp_t *lsp; -  zebra_nhlfe_t *nhlfe; -  char buf[BUFSIZ]; - -  /* Lookup table. */ -  lsp_table = zvrf->lsp_table; -  if (!lsp_table) -    return -1; - -  /* If entry is not present, exit. */ -  tmp_ile.in_label = in_label; -  lsp = hash_lookup (lsp_table, &tmp_ile); -  if (!lsp) -    return 0; -  nhlfe = nhlfe_find (lsp, type, gtype, gate, ifname, ifindex); -  if (!nhlfe) -    return 0; - -  if (IS_ZEBRA_DEBUG_MPLS) -    { -      nhlfe2str (nhlfe, buf, BUFSIZ); -      zlog_debug ("Del LSP in-label %u type %d nexthop %s flags 0x%x", -                  in_label, type, buf, nhlfe->flags); -    } - -  /* Mark NHLFE for delete or directly delete, as appropriate. */ -  if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED)) -    { -      UNSET_FLAG (nhlfe->flags, NHLFE_FLAG_CHANGED); -      SET_FLAG (nhlfe->flags, NHLFE_FLAG_DELETED); -      if (lsp_processq_add (lsp)) -        return -1; -    } -  else -    { -      nhlfe_del (nhlfe); - -      /* Free LSP entry if no other NHLFEs and not scheduled. */ -      if (!lsp->nhlfe_list && -          !CHECK_FLAG (lsp->flags, LSP_FLAG_SCHEDULED)) -        { -          if (IS_ZEBRA_DEBUG_MPLS) -            zlog_debug ("Free LSP in-label %u flags 0x%x", -                        lsp->ile.in_label, lsp->flags); - -          lsp = hash_release(lsp_table, &lsp->ile); -          if (lsp) -            XFREE(MTYPE_LSP, lsp); -        } -    } -  return 0; +	struct hash *lsp_table; +	zebra_ile_t tmp_ile; +	zebra_lsp_t *lsp; +	zebra_nhlfe_t *nhlfe; +	char buf[BUFSIZ]; + +	/* Lookup table. */ +	lsp_table = zvrf->lsp_table; +	if (!lsp_table) +		return -1; + +	/* If entry is not present, exit. */ +	tmp_ile.in_label = in_label; +	lsp = hash_lookup(lsp_table, &tmp_ile); +	if (!lsp) +		return 0; +	nhlfe = nhlfe_find(lsp, type, gtype, gate, ifname, ifindex); +	if (!nhlfe) +		return 0; + +	if (IS_ZEBRA_DEBUG_MPLS) { +		nhlfe2str(nhlfe, buf, BUFSIZ); +		zlog_debug("Del LSP in-label %u type %d nexthop %s flags 0x%x", +			   in_label, type, buf, nhlfe->flags); +	} + +	/* Mark NHLFE for delete or directly delete, as appropriate. */ +	if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED)) { +		UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_CHANGED); +		SET_FLAG(nhlfe->flags, NHLFE_FLAG_DELETED); +		if (lsp_processq_add(lsp)) +			return -1; +	} else { +		nhlfe_del(nhlfe); + +		/* Free LSP entry if no other NHLFEs and not scheduled. */ +		if (!lsp->nhlfe_list +		    && !CHECK_FLAG(lsp->flags, LSP_FLAG_SCHEDULED)) { +			if (IS_ZEBRA_DEBUG_MPLS) +				zlog_debug("Free LSP in-label %u flags 0x%x", +					   lsp->ile.in_label, lsp->flags); + +			lsp = hash_release(lsp_table, &lsp->ile); +			if (lsp) +				XFREE(MTYPE_LSP, lsp); +		} +	} +	return 0;  }  /*   * Uninstall all LDP NHLFEs for a particular LSP forwarding entry.   * If no other NHLFEs exist, the entry would be deleted.   */ -void -mpls_ldp_lsp_uninstall_all (struct hash_backet *backet, void *ctxt) +void mpls_ldp_lsp_uninstall_all(struct hash_backet *backet, void *ctxt)  { -  zebra_lsp_t *lsp; -  struct hash *lsp_table; +	zebra_lsp_t *lsp; +	struct hash *lsp_table; -  lsp = (zebra_lsp_t *) backet->data; -  if (!lsp || !lsp->nhlfe_list) -    return; +	lsp = (zebra_lsp_t *)backet->data; +	if (!lsp || !lsp->nhlfe_list) +		return; -  lsp_table = ctxt; -  if (!lsp_table) -    return; +	lsp_table = ctxt; +	if (!lsp_table) +		return; -  mpls_lsp_uninstall_all (lsp_table, lsp, ZEBRA_LSP_LDP); +	mpls_lsp_uninstall_all(lsp_table, lsp, ZEBRA_LSP_LDP);  }  /*   * Uninstall all LDP FEC-To-NHLFE (FTN) bindings of the given address-family.   */ -void -mpls_ldp_ftn_uninstall_all (struct zebra_vrf *zvrf, int afi) +void mpls_ldp_ftn_uninstall_all(struct zebra_vrf *zvrf, int afi)  { -  struct route_table *table; -  struct route_node *rn; -  struct rib *rib; -  struct nexthop *nexthop; -  int update; - -  /* Process routes of interested address-families. */ -  table = zebra_vrf_table (afi, SAFI_UNICAST, zvrf_id (zvrf)); -  if (!table) -    return; - -  for (rn = route_top (table); rn; rn = route_next (rn)) -    { -      update = 0; -      RNODE_FOREACH_RIB (rn, rib) -	for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) -	  if (nexthop->nh_label_type == ZEBRA_LSP_LDP) -	    { -	      nexthop_del_labels (nexthop); -	      SET_FLAG (rib->status, RIB_ENTRY_CHANGED); -	      SET_FLAG (rib->status, RIB_ENTRY_LABELS_CHANGED); -	      update = 1; -	    } - -      if (update) -	rib_queue_add (rn); -    } +	struct route_table *table; +	struct route_node *rn; +	struct rib *rib; +	struct nexthop *nexthop; +	int update; + +	/* Process routes of interested address-families. */ +	table = zebra_vrf_table(afi, SAFI_UNICAST, zvrf_id(zvrf)); +	if (!table) +		return; + +	for (rn = route_top(table); rn; rn = route_next(rn)) { +		update = 0; +		RNODE_FOREACH_RIB(rn, rib) +		for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) +			if (nexthop->nh_label_type == ZEBRA_LSP_LDP) { +				nexthop_del_labels(nexthop); +				SET_FLAG(rib->status, RIB_ENTRY_CHANGED); +				SET_FLAG(rib->status, RIB_ENTRY_LABELS_CHANGED); +				update = 1; +			} + +		if (update) +			rib_queue_add(rn); +	}  }  #if defined(HAVE_CUMULUS) @@ -1558,54 +1464,52 @@ mpls_ldp_ftn_uninstall_all (struct zebra_vrf *zvrf, int afi)   * be consistent - i.e., all paths either do a swap or do PHP. This is due   * to current HW restrictions.   */ -int -zebra_mpls_lsp_label_consistent (struct zebra_vrf *zvrf, mpls_label_t in_label, -                     mpls_label_t out_label, enum nexthop_types_t gtype, -                     union g_addr *gate, char *ifname, ifindex_t ifindex) +int zebra_mpls_lsp_label_consistent(struct zebra_vrf *zvrf, +				    mpls_label_t in_label, +				    mpls_label_t out_label, +				    enum nexthop_types_t gtype, +				    union g_addr *gate, char *ifname, +				    ifindex_t ifindex)  { -  struct hash *slsp_table; -  zebra_ile_t tmp_ile; -  zebra_slsp_t *slsp; -  zebra_snhlfe_t *snhlfe; - -  /* Lookup table. */ -  slsp_table = zvrf->slsp_table; -  if (!slsp_table) -    return 0; - -  /* If entry is not present, exit. */ -  tmp_ile.in_label = in_label; -  slsp = hash_lookup (slsp_table, &tmp_ile); -  if (!slsp) -    return 1; - -  snhlfe = snhlfe_find (slsp, gtype, gate, ifname, ifindex); -  if (snhlfe) -    { -      if (snhlfe->out_label == out_label) -        return 1; - -      /* If not only NHLFE, cannot allow label change. */ -      if (snhlfe != slsp->snhlfe_list || -          snhlfe->next) -        return 0; -    } -  else -    { -      /* If other NHLFEs exist, label operation must match. */ -      if (slsp->snhlfe_list) -        { -          int cur_op, new_op; - -          cur_op = (slsp->snhlfe_list->out_label == MPLS_IMP_NULL_LABEL); -          new_op = (out_label == MPLS_IMP_NULL_LABEL); -          if (cur_op != new_op) -            return 0; -        } -    } - -  /* Label values are good. */ -  return 1; +	struct hash *slsp_table; +	zebra_ile_t tmp_ile; +	zebra_slsp_t *slsp; +	zebra_snhlfe_t *snhlfe; + +	/* Lookup table. */ +	slsp_table = zvrf->slsp_table; +	if (!slsp_table) +		return 0; + +	/* If entry is not present, exit. */ +	tmp_ile.in_label = in_label; +	slsp = hash_lookup(slsp_table, &tmp_ile); +	if (!slsp) +		return 1; + +	snhlfe = snhlfe_find(slsp, gtype, gate, ifname, ifindex); +	if (snhlfe) { +		if (snhlfe->out_label == out_label) +			return 1; + +		/* If not only NHLFE, cannot allow label change. */ +		if (snhlfe != slsp->snhlfe_list || snhlfe->next) +			return 0; +	} else { +		/* If other NHLFEs exist, label operation must match. */ +		if (slsp->snhlfe_list) { +			int cur_op, new_op; + +			cur_op = (slsp->snhlfe_list->out_label +				  == MPLS_IMP_NULL_LABEL); +			new_op = (out_label == MPLS_IMP_NULL_LABEL); +			if (cur_op != new_op) +				return 0; +		} +	} + +	/* Label values are good. */ +	return 1;  }  #endif /* HAVE_CUMULUS */ @@ -1616,64 +1520,62 @@ zebra_mpls_lsp_label_consistent (struct zebra_vrf *zvrf, mpls_label_t in_label,   * Note: The label operation (swap or PHP) is common for the LSP entry (all   * NHLFEs).   */ -int -zebra_mpls_static_lsp_add (struct zebra_vrf *zvrf, mpls_label_t in_label, -                     mpls_label_t out_label, enum nexthop_types_t gtype, -                     union g_addr *gate, char *ifname, ifindex_t ifindex) +int zebra_mpls_static_lsp_add(struct zebra_vrf *zvrf, mpls_label_t in_label, +			      mpls_label_t out_label, +			      enum nexthop_types_t gtype, union g_addr *gate, +			      char *ifname, ifindex_t ifindex)  { -  struct hash *slsp_table; -  zebra_ile_t tmp_ile; -  zebra_slsp_t *slsp; -  zebra_snhlfe_t *snhlfe; -  char buf[BUFSIZ]; - -  /* Lookup table. */ -  slsp_table = zvrf->slsp_table; -  if (!slsp_table) -    return -1; - -  /* If entry is present, exit. */ -  tmp_ile.in_label = in_label; -  slsp = hash_get (slsp_table, &tmp_ile, slsp_alloc); -  if (!slsp) -    return -1; -  snhlfe = snhlfe_find (slsp, gtype, gate, ifname, ifindex); -  if (snhlfe) -    { -      if (snhlfe->out_label == out_label) -        /* No change */ -        return 0; - -      if (IS_ZEBRA_DEBUG_MPLS) -        { -          snhlfe2str (snhlfe, buf, BUFSIZ); -          zlog_debug ("Upd static LSP in-label %u nexthop %s " -                      "out-label %u (old %u)", -                      in_label, buf, out_label, snhlfe->out_label); -        } -      snhlfe->out_label = out_label; -    } -  else -    { -      /* Add static LSP entry to this nexthop */ -      snhlfe = snhlfe_add (slsp, gtype, gate, ifname, ifindex, out_label); -      if (!snhlfe) -        return -1; - -      if (IS_ZEBRA_DEBUG_MPLS) -        { -          snhlfe2str (snhlfe, buf, BUFSIZ); -          zlog_debug ("Add static LSP in-label %u nexthop %s out-label %u", -                      in_label, buf, out_label); -        } -    } - -  /* (Re)Install LSP in the main table. */ -  if (mpls_lsp_install (zvrf, ZEBRA_LSP_STATIC, in_label, out_label, gtype, -      gate, ifname, ifindex)) -    return -1; - -  return 0; +	struct hash *slsp_table; +	zebra_ile_t tmp_ile; +	zebra_slsp_t *slsp; +	zebra_snhlfe_t *snhlfe; +	char buf[BUFSIZ]; + +	/* Lookup table. */ +	slsp_table = zvrf->slsp_table; +	if (!slsp_table) +		return -1; + +	/* If entry is present, exit. */ +	tmp_ile.in_label = in_label; +	slsp = hash_get(slsp_table, &tmp_ile, slsp_alloc); +	if (!slsp) +		return -1; +	snhlfe = snhlfe_find(slsp, gtype, gate, ifname, ifindex); +	if (snhlfe) { +		if (snhlfe->out_label == out_label) +			/* No change */ +			return 0; + +		if (IS_ZEBRA_DEBUG_MPLS) { +			snhlfe2str(snhlfe, buf, BUFSIZ); +			zlog_debug( +				"Upd static LSP in-label %u nexthop %s " +				"out-label %u (old %u)", +				in_label, buf, out_label, snhlfe->out_label); +		} +		snhlfe->out_label = out_label; +	} else { +		/* Add static LSP entry to this nexthop */ +		snhlfe = snhlfe_add(slsp, gtype, gate, ifname, ifindex, +				    out_label); +		if (!snhlfe) +			return -1; + +		if (IS_ZEBRA_DEBUG_MPLS) { +			snhlfe2str(snhlfe, buf, BUFSIZ); +			zlog_debug( +				"Add static LSP in-label %u nexthop %s out-label %u", +				in_label, buf, out_label); +		} +	} + +	/* (Re)Install LSP in the main table. */ +	if (mpls_lsp_install(zvrf, ZEBRA_LSP_STATIC, in_label, out_label, gtype, +			     gate, ifname, ifindex)) +		return -1; + +	return 0;  }  /* @@ -1683,71 +1585,66 @@ zebra_mpls_static_lsp_add (struct zebra_vrf *zvrf, mpls_label_t in_label,   * NOTE: Delete of the only NHLFE will also end up deleting the entire   * LSP configuration.   */ -int -zebra_mpls_static_lsp_del (struct zebra_vrf *zvrf, mpls_label_t in_label, -                           enum nexthop_types_t gtype, union g_addr *gate, -                           char *ifname, ifindex_t ifindex) +int zebra_mpls_static_lsp_del(struct zebra_vrf *zvrf, mpls_label_t in_label, +			      enum nexthop_types_t gtype, union g_addr *gate, +			      char *ifname, ifindex_t ifindex)  { -  struct hash *slsp_table; -  zebra_ile_t tmp_ile; -  zebra_slsp_t *slsp; -  zebra_snhlfe_t *snhlfe; - -  /* Lookup table. */ -  slsp_table = zvrf->slsp_table; -  if (!slsp_table) -    return -1; - -  /* If entry is not present, exit. */ -  tmp_ile.in_label = in_label; -  slsp = hash_lookup (slsp_table, &tmp_ile); -  if (!slsp) -    return 0; - -  /* Is it delete of entire LSP or a specific NHLFE? */ -  if (gtype == NEXTHOP_TYPE_BLACKHOLE) -    { -      if (IS_ZEBRA_DEBUG_MPLS) -        zlog_debug ("Del static LSP in-label %u", in_label); - -      /* Uninstall entire LSP from the main table. */ -      mpls_static_lsp_uninstall_all (zvrf, in_label); - -      /* Delete all static NHLFEs */ -      snhlfe_del_all (slsp); -    } -  else -    { -      /* Find specific NHLFE, exit if not found. */ -      snhlfe = snhlfe_find (slsp, gtype, gate, ifname, ifindex); -      if (!snhlfe) -        return 0; - -      if (IS_ZEBRA_DEBUG_MPLS) -        { -          char buf[BUFSIZ]; -          snhlfe2str (snhlfe, buf, BUFSIZ); -          zlog_debug ("Del static LSP in-label %u nexthop %s", -                      in_label, buf); -        } - -      /* Uninstall LSP from the main table. */ -      mpls_lsp_uninstall (zvrf, ZEBRA_LSP_STATIC, in_label, gtype, gate, -			  ifname, ifindex); - -      /* Delete static LSP NHLFE */ -      snhlfe_del (snhlfe); -    } - -  /* Remove entire static LSP entry if no NHLFE - valid in either case above. */ -  if (!slsp->snhlfe_list) -    { -      slsp = hash_release(slsp_table, &tmp_ile); -      if (slsp) -        XFREE(MTYPE_SLSP, slsp); -    } - -  return 0; +	struct hash *slsp_table; +	zebra_ile_t tmp_ile; +	zebra_slsp_t *slsp; +	zebra_snhlfe_t *snhlfe; + +	/* Lookup table. */ +	slsp_table = zvrf->slsp_table; +	if (!slsp_table) +		return -1; + +	/* If entry is not present, exit. */ +	tmp_ile.in_label = in_label; +	slsp = hash_lookup(slsp_table, &tmp_ile); +	if (!slsp) +		return 0; + +	/* Is it delete of entire LSP or a specific NHLFE? */ +	if (gtype == NEXTHOP_TYPE_BLACKHOLE) { +		if (IS_ZEBRA_DEBUG_MPLS) +			zlog_debug("Del static LSP in-label %u", in_label); + +		/* Uninstall entire LSP from the main table. */ +		mpls_static_lsp_uninstall_all(zvrf, in_label); + +		/* Delete all static NHLFEs */ +		snhlfe_del_all(slsp); +	} else { +		/* Find specific NHLFE, exit if not found. */ +		snhlfe = snhlfe_find(slsp, gtype, gate, ifname, ifindex); +		if (!snhlfe) +			return 0; + +		if (IS_ZEBRA_DEBUG_MPLS) { +			char buf[BUFSIZ]; +			snhlfe2str(snhlfe, buf, BUFSIZ); +			zlog_debug("Del static LSP in-label %u nexthop %s", +				   in_label, buf); +		} + +		/* Uninstall LSP from the main table. */ +		mpls_lsp_uninstall(zvrf, ZEBRA_LSP_STATIC, in_label, gtype, +				   gate, ifname, ifindex); + +		/* Delete static LSP NHLFE */ +		snhlfe_del(snhlfe); +	} + +	/* Remove entire static LSP entry if no NHLFE - valid in either case +	 * above. */ +	if (!slsp->snhlfe_list) { +		slsp = hash_release(slsp_table, &tmp_ile); +		if (slsp) +			XFREE(MTYPE_SLSP, slsp); +	} + +	return 0;  }  /* @@ -1755,150 +1652,154 @@ zebra_mpls_static_lsp_del (struct zebra_vrf *zvrf, mpls_label_t in_label,   * Called upon changes that may affect one or more of them such as   * interface or nexthop state changes.   */ -void -zebra_mpls_lsp_schedule (struct zebra_vrf *zvrf) +void zebra_mpls_lsp_schedule(struct zebra_vrf *zvrf)  { -  if (!zvrf) -    return; -  hash_iterate(zvrf->lsp_table, lsp_schedule, NULL); +	if (!zvrf) +		return; +	hash_iterate(zvrf->lsp_table, lsp_schedule, NULL);  }  /*   * Display MPLS label forwarding table for a specific LSP   * (VTY command handler).   */ -void -zebra_mpls_print_lsp (struct vty *vty, struct zebra_vrf *zvrf, mpls_label_t label, -                      u_char use_json) +void zebra_mpls_print_lsp(struct vty *vty, struct zebra_vrf *zvrf, +			  mpls_label_t label, u_char use_json)  { -  struct hash *lsp_table; -  zebra_lsp_t *lsp; -  zebra_ile_t tmp_ile; -  json_object *json = NULL; - -  /* Lookup table. */ -  lsp_table = zvrf->lsp_table; -  if (!lsp_table) -    return; - -  /* If entry is not present, exit. */ -  tmp_ile.in_label = label; -  lsp = hash_lookup (lsp_table, &tmp_ile); -  if (!lsp) -    return; - -  if (use_json) -    { -      json = lsp_json(lsp); -      vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE); -      json_object_free(json); -    } -  else -    lsp_print (lsp, (void *)vty); +	struct hash *lsp_table; +	zebra_lsp_t *lsp; +	zebra_ile_t tmp_ile; +	json_object *json = NULL; + +	/* Lookup table. */ +	lsp_table = zvrf->lsp_table; +	if (!lsp_table) +		return; + +	/* If entry is not present, exit. */ +	tmp_ile.in_label = label; +	lsp = hash_lookup(lsp_table, &tmp_ile); +	if (!lsp) +		return; + +	if (use_json) { +		json = lsp_json(lsp); +		vty_out(vty, "%s%s", json_object_to_json_string_ext( +					     json, JSON_C_TO_STRING_PRETTY), +			VTY_NEWLINE); +		json_object_free(json); +	} else +		lsp_print(lsp, (void *)vty);  }  /*   * Display MPLS label forwarding table (VTY command handler).   */ -void -zebra_mpls_print_lsp_table (struct vty *vty, struct zebra_vrf *zvrf, -                            u_char use_json) +void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf, +				u_char use_json)  { -  char buf[BUFSIZ]; -  json_object *json = NULL; -  zebra_lsp_t *lsp = NULL; -  zebra_nhlfe_t *nhlfe = NULL; -  struct nexthop *nexthop = NULL; -  struct listnode *node = NULL; -  struct list *lsp_list = hash_get_sorted_list(zvrf->lsp_table, lsp_cmp); - -  if (use_json) -    { -      json  = json_object_new_object(); - -      for (ALL_LIST_ELEMENTS_RO(lsp_list, node, lsp)) -        json_object_object_add(json, label2str(lsp->ile.in_label, buf, BUFSIZ), -                               lsp_json(lsp)); - -      vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE); -      json_object_free(json); -    } -  else -    { -      vty_out (vty, " Inbound                            Outbound%s", VTY_NEWLINE); -      vty_out (vty, "   Label     Type          Nexthop     Label%s", VTY_NEWLINE); -      vty_out (vty, "--------  -------  ---------------  --------%s", VTY_NEWLINE); - -      for (ALL_LIST_ELEMENTS_RO(lsp_list, node, lsp)) -        { -          for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) -            { -              vty_out (vty, "%8d  %7s  ", lsp->ile.in_label, nhlfe_type2str(nhlfe->type)); -              nexthop = nhlfe->nexthop; - -              switch (nexthop->type) -                { -                case NEXTHOP_TYPE_IPV4: -                case NEXTHOP_TYPE_IPV4_IFINDEX: -                  vty_out (vty, "%15s", inet_ntoa (nexthop->gate.ipv4)); -                  break; -                case NEXTHOP_TYPE_IPV6: -                case NEXTHOP_TYPE_IPV6_IFINDEX: -                  vty_out (vty, "%15s", inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ)); -                  break; -                default: -                  break; -                } - -              vty_out (vty, "  %8d%s", nexthop->nh_label->label[0], VTY_NEWLINE); -            } -        } - -      vty_out (vty, "%s", VTY_NEWLINE); -    } - -  list_delete (lsp_list); +	char buf[BUFSIZ]; +	json_object *json = NULL; +	zebra_lsp_t *lsp = NULL; +	zebra_nhlfe_t *nhlfe = NULL; +	struct nexthop *nexthop = NULL; +	struct listnode *node = NULL; +	struct list *lsp_list = hash_get_sorted_list(zvrf->lsp_table, lsp_cmp); + +	if (use_json) { +		json = json_object_new_object(); + +		for (ALL_LIST_ELEMENTS_RO(lsp_list, node, lsp)) +			json_object_object_add( +				json, label2str(lsp->ile.in_label, buf, BUFSIZ), +				lsp_json(lsp)); + +		vty_out(vty, "%s%s", json_object_to_json_string_ext( +					     json, JSON_C_TO_STRING_PRETTY), +			VTY_NEWLINE); +		json_object_free(json); +	} else { +		vty_out(vty, " Inbound                            Outbound%s", +			VTY_NEWLINE); +		vty_out(vty, "   Label     Type          Nexthop     Label%s", +			VTY_NEWLINE); +		vty_out(vty, "--------  -------  ---------------  --------%s", +			VTY_NEWLINE); + +		for (ALL_LIST_ELEMENTS_RO(lsp_list, node, lsp)) { +			for (nhlfe = lsp->nhlfe_list; nhlfe; +			     nhlfe = nhlfe->next) { +				vty_out(vty, "%8d  %7s  ", lsp->ile.in_label, +					nhlfe_type2str(nhlfe->type)); +				nexthop = nhlfe->nexthop; + +				switch (nexthop->type) { +				case NEXTHOP_TYPE_IPV4: +				case NEXTHOP_TYPE_IPV4_IFINDEX: +					vty_out(vty, "%15s", +						inet_ntoa(nexthop->gate.ipv4)); +					break; +				case NEXTHOP_TYPE_IPV6: +				case NEXTHOP_TYPE_IPV6_IFINDEX: +					vty_out(vty, "%15s", +						inet_ntop(AF_INET6, +							  &nexthop->gate.ipv6, +							  buf, BUFSIZ)); +					break; +				default: +					break; +				} + +				vty_out(vty, "  %8d%s", +					nexthop->nh_label->label[0], +					VTY_NEWLINE); +			} +		} + +		vty_out(vty, "%s", VTY_NEWLINE); +	} + +	list_delete(lsp_list);  }  /*   * Display MPLS LSP configuration of all static LSPs (VTY command handler).   */ -int -zebra_mpls_write_lsp_config (struct vty *vty, struct zebra_vrf *zvrf) +int zebra_mpls_write_lsp_config(struct vty *vty, struct zebra_vrf *zvrf)  { -  zebra_slsp_t *slsp; -  zebra_snhlfe_t *snhlfe; -  struct listnode *node; -  struct list *slsp_list = hash_get_sorted_list(zvrf->slsp_table, slsp_cmp); - -  for (ALL_LIST_ELEMENTS_RO(slsp_list, node, slsp)) -      { -        for (snhlfe = slsp->snhlfe_list; snhlfe; snhlfe = snhlfe->next) -          { -	    char buf[INET6_ADDRSTRLEN]; -            char lstr[30]; - -            snhlfe2str (snhlfe, buf, BUFSIZ); -	    switch (snhlfe->out_label) { -	      case MPLS_V4_EXP_NULL_LABEL: -	      case MPLS_V6_EXP_NULL_LABEL: -		strlcpy(lstr, "explicit-null", sizeof(lstr)); -		break; -	      case MPLS_IMP_NULL_LABEL: -		strlcpy(lstr, "implicit-null", sizeof(lstr)); -		break; -	      default: -		sprintf(lstr, "%u", snhlfe->out_label); -		break; -	    } - -            vty_out (vty, "mpls lsp %u %s %s%s", -                     slsp->ile.in_label, buf, lstr, VTY_NEWLINE); -          } -      } +	zebra_slsp_t *slsp; +	zebra_snhlfe_t *snhlfe; +	struct listnode *node; +	struct list *slsp_list = +		hash_get_sorted_list(zvrf->slsp_table, slsp_cmp); + +	for (ALL_LIST_ELEMENTS_RO(slsp_list, node, slsp)) { +		for (snhlfe = slsp->snhlfe_list; snhlfe; +		     snhlfe = snhlfe->next) { +			char buf[INET6_ADDRSTRLEN]; +			char lstr[30]; + +			snhlfe2str(snhlfe, buf, BUFSIZ); +			switch (snhlfe->out_label) { +			case MPLS_V4_EXP_NULL_LABEL: +			case MPLS_V6_EXP_NULL_LABEL: +				strlcpy(lstr, "explicit-null", sizeof(lstr)); +				break; +			case MPLS_IMP_NULL_LABEL: +				strlcpy(lstr, "implicit-null", sizeof(lstr)); +				break; +			default: +				sprintf(lstr, "%u", snhlfe->out_label); +				break; +			} + +			vty_out(vty, "mpls lsp %u %s %s%s", slsp->ile.in_label, +				buf, lstr, VTY_NEWLINE); +		} +	} -  list_delete (slsp_list); -  return (zvrf->slsp_table->count ? 1 : 0); +	list_delete(slsp_list); +	return (zvrf->slsp_table->count ? 1 : 0);  }  /* @@ -1906,42 +1807,38 @@ zebra_mpls_write_lsp_config (struct vty *vty, struct zebra_vrf *zvrf)   * entries from the kernel.   * NOTE: Currently supported only for default VRF.   */ -void -zebra_mpls_close_tables (struct zebra_vrf *zvrf) +void zebra_mpls_close_tables(struct zebra_vrf *zvrf)  { -  hash_iterate(zvrf->lsp_table, lsp_uninstall_from_kernel, NULL); -  hash_clean(zvrf->lsp_table, NULL); -  hash_free(zvrf->lsp_table); -  hash_clean(zvrf->slsp_table, NULL); -  hash_free(zvrf->slsp_table); +	hash_iterate(zvrf->lsp_table, lsp_uninstall_from_kernel, NULL); +	hash_clean(zvrf->lsp_table, NULL); +	hash_free(zvrf->lsp_table); +	hash_clean(zvrf->slsp_table, NULL); +	hash_free(zvrf->slsp_table);  }  /*   * Allocate MPLS tables for this VRF and do other initialization.   * NOTE: Currently supported only for default VRF.   */ -void -zebra_mpls_init_tables (struct zebra_vrf *zvrf) +void zebra_mpls_init_tables(struct zebra_vrf *zvrf)  { -  if (!zvrf) -    return; -  zvrf->slsp_table = hash_create(label_hash, label_cmp); -  zvrf->lsp_table = hash_create(label_hash, label_cmp); -  zvrf->mpls_flags = 0; +	if (!zvrf) +		return; +	zvrf->slsp_table = hash_create(label_hash, label_cmp); +	zvrf->lsp_table = hash_create(label_hash, label_cmp); +	zvrf->mpls_flags = 0;  }  /*   * Global MPLS initialization.   */ -void -zebra_mpls_init (void) +void zebra_mpls_init(void)  { -  if (mpls_kernel_init () < 0) -    { -      zlog_warn ("Disabling MPLS support (no kernel support)"); -      return; -    } - -  mpls_enabled = 1; -  mpls_processq_init (&zebrad); +	if (mpls_kernel_init() < 0) { +		zlog_warn("Disabling MPLS support (no kernel support)"); +		return; +	} + +	mpls_enabled = 1; +	mpls_processq_init(&zebrad);  } diff --git a/zebra/zebra_mpls.h b/zebra/zebra_mpls.h index a871fac651..6e45fb8649 100644 --- a/zebra/zebra_mpls.h +++ b/zebra/zebra_mpls.h @@ -40,9 +40,11 @@  #define MPLS_MAX_LABELS 2  /* Maximum # labels that can be pushed. */ -#define NHLFE_FAMILY(nhlfe)                        \ -  (((nhlfe)->nexthop->type == NEXTHOP_TYPE_IPV6 || \ -    (nhlfe)->nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) ? AF_INET6 : AF_INET) +#define NHLFE_FAMILY(nhlfe)                                                    \ +	(((nhlfe)->nexthop->type == NEXTHOP_TYPE_IPV6                          \ +	  || (nhlfe)->nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)              \ +		 ? AF_INET6                                                    \ +		 : AF_INET)  /* Typedefs */ @@ -56,95 +58,89 @@ typedef struct zebra_lsp_t_ zebra_lsp_t;  /*   * (Outgoing) nexthop label forwarding entry configuration   */ -struct zebra_snhlfe_t_ -{ -  /* Nexthop information */ -  enum nexthop_types_t gtype; -  union g_addr gate; -  char *ifname; -  ifindex_t ifindex; - -  /* Out label. */ -  mpls_label_t out_label; - -  /* Backpointer to base entry. */ -  zebra_slsp_t *slsp; - -  /* Pointers to more outgoing information for same in-label */ -  zebra_snhlfe_t *next; -  zebra_snhlfe_t *prev; +struct zebra_snhlfe_t_ { +	/* Nexthop information */ +	enum nexthop_types_t gtype; +	union g_addr gate; +	char *ifname; +	ifindex_t ifindex; + +	/* Out label. */ +	mpls_label_t out_label; + +	/* Backpointer to base entry. */ +	zebra_slsp_t *slsp; + +	/* Pointers to more outgoing information for same in-label */ +	zebra_snhlfe_t *next; +	zebra_snhlfe_t *prev;  };  /*   * (Outgoing) nexthop label forwarding entry   */ -struct zebra_nhlfe_t_ -{ -  /* Type of entry - static etc. */ -  enum lsp_types_t type; +struct zebra_nhlfe_t_ { +	/* Type of entry - static etc. */ +	enum lsp_types_t type; -  /* Nexthop information (with outgoing label) */ -  struct nexthop *nexthop; +	/* Nexthop information (with outgoing label) */ +	struct nexthop *nexthop; -  /* Backpointer to base entry. */ -  zebra_lsp_t *lsp; +	/* Backpointer to base entry. */ +	zebra_lsp_t *lsp; -  /* Runtime info - flags, pointers etc. */ -  u_int32_t flags; +	/* Runtime info - flags, pointers etc. */ +	u_int32_t flags;  #define NHLFE_FLAG_CHANGED     (1 << 0)  #define NHLFE_FLAG_SELECTED    (1 << 1)  #define NHLFE_FLAG_MULTIPATH   (1 << 2)  #define NHLFE_FLAG_DELETED     (1 << 3)  #define NHLFE_FLAG_INSTALLED   (1 << 4) -  zebra_nhlfe_t *next; -  zebra_nhlfe_t *prev; -  u_char distance; +	zebra_nhlfe_t *next; +	zebra_nhlfe_t *prev; +	u_char distance;  };  /*   * Incoming label entry   */ -struct zebra_ile_t_ -{ -  mpls_label_t in_label; +struct zebra_ile_t_ { +	mpls_label_t in_label;  };  /*   * Label swap entry static configuration.   */ -struct zebra_slsp_t_ -{ -  /* Incoming label */ -  zebra_ile_t ile; - -  /* List of outgoing nexthop static configuration */ -  zebra_snhlfe_t *snhlfe_list; +struct zebra_slsp_t_ { +	/* Incoming label */ +	zebra_ile_t ile; +	/* List of outgoing nexthop static configuration */ +	zebra_snhlfe_t *snhlfe_list;  };  /*   * Label swap entry (ile -> list of nhlfes)   */ -struct zebra_lsp_t_ -{ -  /* Incoming label */ -  zebra_ile_t ile; +struct zebra_lsp_t_ { +	/* Incoming label */ +	zebra_ile_t ile; -  /* List of NHLFE, pointer to best and num equal-cost. */ -  zebra_nhlfe_t *nhlfe_list; -  zebra_nhlfe_t *best_nhlfe; -  u_int32_t num_ecmp; +	/* List of NHLFE, pointer to best and num equal-cost. */ +	zebra_nhlfe_t *nhlfe_list; +	zebra_nhlfe_t *best_nhlfe; +	u_int32_t num_ecmp; -  /* Flags */ -  u_int32_t flags; +	/* Flags */ +	u_int32_t flags;  #define LSP_FLAG_SCHEDULED        (1 << 0)  #define LSP_FLAG_INSTALLED        (1 << 1)  #define LSP_FLAG_CHANGED          (1 << 2) -  /* Address-family of NHLFE - saved here for delete. All NHLFEs */ -  /* have to be of the same AF */ -  u_char addr_family; +	/* Address-family of NHLFE - saved here for delete. All NHLFEs */ +	/* have to be of the same AF */ +	u_char addr_family;  }; @@ -153,58 +149,51 @@ struct zebra_lsp_t_  /*   * String to label conversion, labels separated by '/'.   */ -int -mpls_str2label (const char *label_str, u_int8_t *num_labels, -                mpls_label_t *labels); +int mpls_str2label(const char *label_str, u_int8_t *num_labels, +		   mpls_label_t *labels);  /*   * Label to string conversion, labels in string separated by '/'.   */ -char * -mpls_label2str (u_int8_t num_labels, mpls_label_t *labels, -                char *buf, int len); +char *mpls_label2str(u_int8_t num_labels, mpls_label_t *labels, char *buf, +		     int len);  /*   * Install/uninstall a FEC-To-NHLFE (FTN) binding.   */ -int -mpls_ftn_update (int add, struct zebra_vrf *zvrf, enum lsp_types_t type, -		 struct prefix *prefix, enum nexthop_types_t gtype, -		 union g_addr *gate, ifindex_t ifindex, u_int8_t distance, -		 mpls_label_t out_label); +int mpls_ftn_update(int add, struct zebra_vrf *zvrf, enum lsp_types_t type, +		    struct prefix *prefix, enum nexthop_types_t gtype, +		    union g_addr *gate, ifindex_t ifindex, u_int8_t distance, +		    mpls_label_t out_label);  /*   * Install/update a NHLFE for an LSP in the forwarding table. This may be   * a new LSP entry or a new NHLFE for an existing in-label or an update of   * the out-label for an existing NHLFE (update case).   */ -int -mpls_lsp_install (struct zebra_vrf *zvrf, enum lsp_types_t type, -		  mpls_label_t in_label, mpls_label_t out_label, -		  enum nexthop_types_t gtype, union g_addr *gate, -		  char *ifname, ifindex_t ifindex); +int mpls_lsp_install(struct zebra_vrf *zvrf, enum lsp_types_t type, +		     mpls_label_t in_label, mpls_label_t out_label, +		     enum nexthop_types_t gtype, union g_addr *gate, +		     char *ifname, ifindex_t ifindex);  /*   * Uninstall a particular NHLFE in the forwarding table. If this is   * the only NHLFE, the entire LSP forwarding entry has to be deleted.   */ -int -mpls_lsp_uninstall (struct zebra_vrf *zvrf, enum lsp_types_t type, -		    mpls_label_t in_label, enum nexthop_types_t gtype, -		    union g_addr *gate, char *ifname, ifindex_t ifindex); +int mpls_lsp_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type, +		       mpls_label_t in_label, enum nexthop_types_t gtype, +		       union g_addr *gate, char *ifname, ifindex_t ifindex);  /*   * Uninstall all LDP NHLFEs for a particular LSP forwarding entry.   * If no other NHLFEs exist, the entry would be deleted.   */ -void -mpls_ldp_lsp_uninstall_all (struct hash_backet *backet, void *ctxt); +void mpls_ldp_lsp_uninstall_all(struct hash_backet *backet, void *ctxt);  /*   * Uninstall all LDP FEC-To-NHLFE (FTN) bindings of the given address-family.   */ -void -mpls_ldp_ftn_uninstall_all (struct zebra_vrf *zvrf, int afi); +void mpls_ldp_ftn_uninstall_all(struct zebra_vrf *zvrf, int afi);  #if defined(HAVE_CUMULUS)  /* @@ -213,10 +202,12 @@ mpls_ldp_ftn_uninstall_all (struct zebra_vrf *zvrf, int afi);   * be consistent - i.e., all paths either do a swap or do PHP. This is due   * to current HW restrictions.   */ -int -zebra_mpls_lsp_label_consistent (struct zebra_vrf *zvrf, mpls_label_t in_label, -                     mpls_label_t out_label, enum nexthop_types_t gtype, -                     union g_addr *gate, char *ifname, ifindex_t ifindex); +int zebra_mpls_lsp_label_consistent(struct zebra_vrf *zvrf, +				    mpls_label_t in_label, +				    mpls_label_t out_label, +				    enum nexthop_types_t gtype, +				    union g_addr *gate, char *ifname, +				    ifindex_t ifindex);  #endif /* HAVE_CUMULUS */  /* @@ -226,10 +217,10 @@ zebra_mpls_lsp_label_consistent (struct zebra_vrf *zvrf, mpls_label_t in_label,   * Note: The label operation (swap or PHP) is common for the LSP entry (all   * NHLFEs).   */ -int -zebra_mpls_static_lsp_add (struct zebra_vrf *zvrf, mpls_label_t in_label, -                     mpls_label_t out_label, enum nexthop_types_t gtype, -                     union g_addr *gate, char *ifname, ifindex_t ifindex); +int zebra_mpls_static_lsp_add(struct zebra_vrf *zvrf, mpls_label_t in_label, +			      mpls_label_t out_label, +			      enum nexthop_types_t gtype, union g_addr *gate, +			      char *ifname, ifindex_t ifindex);  /*   * Delete static LSP entry. This may be the delete of one particular @@ -238,137 +229,120 @@ zebra_mpls_static_lsp_add (struct zebra_vrf *zvrf, mpls_label_t in_label,   * NOTE: Delete of the only NHLFE will also end up deleting the entire   * LSP configuration.   */ -int -zebra_mpls_static_lsp_del (struct zebra_vrf *zvrf, mpls_label_t in_label, -                           enum nexthop_types_t gtype, union g_addr *gate, -                           char *ifname, ifindex_t ifindex); +int zebra_mpls_static_lsp_del(struct zebra_vrf *zvrf, mpls_label_t in_label, +			      enum nexthop_types_t gtype, union g_addr *gate, +			      char *ifname, ifindex_t ifindex);  /*   * Schedule all MPLS label forwarding entries for processing.   * Called upon changes that may affect one or more of them such as   * interface or nexthop state changes.   */ -void -zebra_mpls_lsp_schedule (struct zebra_vrf *zvrf); +void zebra_mpls_lsp_schedule(struct zebra_vrf *zvrf);  /*   * Display MPLS label forwarding table for a specific LSP   * (VTY command handler).   */ -void -zebra_mpls_print_lsp (struct vty *vty, struct zebra_vrf *zvrf, mpls_label_t label, -                      u_char use_json); +void zebra_mpls_print_lsp(struct vty *vty, struct zebra_vrf *zvrf, +			  mpls_label_t label, u_char use_json);  /*   * Display MPLS label forwarding table (VTY command handler).   */ -void -zebra_mpls_print_lsp_table (struct vty *vty, struct zebra_vrf *zvrf, -                            u_char use_json); +void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf, +				u_char use_json);  /*   * Display MPLS LSP configuration of all static LSPs (VTY command handler).   */ -int -zebra_mpls_write_lsp_config (struct vty *vty, struct zebra_vrf *zvrf); +int zebra_mpls_write_lsp_config(struct vty *vty, struct zebra_vrf *zvrf);  /*   * Called upon process exiting, need to delete LSP forwarding   * entries from the kernel.   * NOTE: Currently supported only for default VRF.   */ -void -zebra_mpls_close_tables (struct zebra_vrf *zvrf); +void zebra_mpls_close_tables(struct zebra_vrf *zvrf);  /*   * Allocate MPLS tables for this VRF.   * NOTE: Currently supported only for default VRF.   */ -void -zebra_mpls_init_tables (struct zebra_vrf *zvrf); +void zebra_mpls_init_tables(struct zebra_vrf *zvrf);  /*   * Global MPLS initialization.   */ -void -zebra_mpls_init (void); +void zebra_mpls_init(void);  /*   * MPLS VTY.   */ -void -zebra_mpls_vty_init (void); +void zebra_mpls_vty_init(void);  /* Inline functions. */  /*   * Distance (priority) definition for LSP NHLFE.   */ -static inline u_char -lsp_distance (enum lsp_types_t type) +static inline u_char lsp_distance(enum lsp_types_t type)  { -  if (type == ZEBRA_LSP_STATIC) -    return (route_distance (ZEBRA_ROUTE_STATIC)); +	if (type == ZEBRA_LSP_STATIC) +		return (route_distance(ZEBRA_ROUTE_STATIC)); -  return 150; +	return 150;  }  /*   * Map RIB type to LSP type. Used when labeled-routes from BGP   * are converted into LSPs.   */ -static inline enum lsp_types_t -lsp_type_from_rib_type (int rib_type) +static inline enum lsp_types_t lsp_type_from_rib_type(int rib_type)  { -  switch (rib_type) -    { -      case ZEBRA_ROUTE_STATIC: -        return ZEBRA_LSP_STATIC; -      default: -        return ZEBRA_LSP_NONE; -    } +	switch (rib_type) { +	case ZEBRA_ROUTE_STATIC: +		return ZEBRA_LSP_STATIC; +	default: +		return ZEBRA_LSP_NONE; +	}  }  /* NHLFE type as printable string. */ -static inline const char * -nhlfe_type2str(enum lsp_types_t lsp_type) +static inline const char *nhlfe_type2str(enum lsp_types_t lsp_type)  { -  switch (lsp_type) -    { -      case ZEBRA_LSP_STATIC: -        return "Static"; -      case ZEBRA_LSP_LDP: -        return "LDP"; -      default: -        return "Unknown"; -    } +	switch (lsp_type) { +	case ZEBRA_LSP_STATIC: +		return "Static"; +	case ZEBRA_LSP_LDP: +		return "LDP"; +	default: +		return "Unknown"; +	}  } -static inline void -mpls_mark_lsps_for_processing(struct zebra_vrf *zvrf) +static inline void mpls_mark_lsps_for_processing(struct zebra_vrf *zvrf)  { -  if (!zvrf) -    return; +	if (!zvrf) +		return; -  zvrf->mpls_flags |= MPLS_FLAG_SCHEDULE_LSPS; +	zvrf->mpls_flags |= MPLS_FLAG_SCHEDULE_LSPS;  } -static inline void -mpls_unmark_lsps_for_processing(struct zebra_vrf *zvrf) +static inline void mpls_unmark_lsps_for_processing(struct zebra_vrf *zvrf)  { -  if (!zvrf) -    return; +	if (!zvrf) +		return; -  zvrf->mpls_flags &= ~MPLS_FLAG_SCHEDULE_LSPS; +	zvrf->mpls_flags &= ~MPLS_FLAG_SCHEDULE_LSPS;  } -static inline int -mpls_should_lsps_be_processed(struct zebra_vrf *zvrf) +static inline int mpls_should_lsps_be_processed(struct zebra_vrf *zvrf)  { -  if (!zvrf) -    return 0; +	if (!zvrf) +		return 0; -  return ((zvrf->mpls_flags & MPLS_FLAG_SCHEDULE_LSPS) ? 1 : 0); +	return ((zvrf->mpls_flags & MPLS_FLAG_SCHEDULE_LSPS) ? 1 : 0);  }  /* Global variables. */ diff --git a/zebra/zebra_mpls_netlink.c b/zebra/zebra_mpls_netlink.c index 045bee2b91..faa44ca54f 100644 --- a/zebra/zebra_mpls_netlink.c +++ b/zebra/zebra_mpls_netlink.c @@ -27,22 +27,21 @@  /*   * Install Label Forwarding entry into the kernel.   */ -int -kernel_add_lsp (zebra_lsp_t *lsp) +int kernel_add_lsp(zebra_lsp_t *lsp)  { -  int ret; +	int ret; -  if (!lsp || !lsp->best_nhlfe) // unexpected -    return -1; +	if (!lsp || !lsp->best_nhlfe) // unexpected +		return -1; -  UNSET_FLAG (lsp->flags, LSP_FLAG_CHANGED); -  ret = netlink_mpls_multipath (RTM_NEWROUTE, lsp); -  if (!ret) -    SET_FLAG (lsp->flags, LSP_FLAG_INSTALLED); -  else -    clear_nhlfe_installed (lsp); +	UNSET_FLAG(lsp->flags, LSP_FLAG_CHANGED); +	ret = netlink_mpls_multipath(RTM_NEWROUTE, lsp); +	if (!ret) +		SET_FLAG(lsp->flags, LSP_FLAG_INSTALLED); +	else +		clear_nhlfe_installed(lsp); -  return ret; +	return ret;  }  /* @@ -56,58 +55,54 @@ kernel_add_lsp (zebra_lsp_t *lsp)   * through the metric field (before kernel-MPLS). This shouldn't be an issue   * any longer, so REPLACE can be reintroduced.   */ -int -kernel_upd_lsp (zebra_lsp_t *lsp) +int kernel_upd_lsp(zebra_lsp_t *lsp)  { -  int ret; +	int ret; -  if (!lsp || !lsp->best_nhlfe) // unexpected -    return -1; +	if (!lsp || !lsp->best_nhlfe) // unexpected +		return -1; -  UNSET_FLAG (lsp->flags, LSP_FLAG_CHANGED); +	UNSET_FLAG(lsp->flags, LSP_FLAG_CHANGED); -  /* First issue a DEL and clear the installed flag. */ -  netlink_mpls_multipath (RTM_DELROUTE, lsp); -  UNSET_FLAG (lsp->flags, LSP_FLAG_INSTALLED); +	/* First issue a DEL and clear the installed flag. */ +	netlink_mpls_multipath(RTM_DELROUTE, lsp); +	UNSET_FLAG(lsp->flags, LSP_FLAG_INSTALLED); -  /* Then issue an ADD. */ -  ret = netlink_mpls_multipath (RTM_NEWROUTE, lsp); -  if (!ret) -    SET_FLAG (lsp->flags, LSP_FLAG_INSTALLED); -  else -    clear_nhlfe_installed (lsp); +	/* Then issue an ADD. */ +	ret = netlink_mpls_multipath(RTM_NEWROUTE, lsp); +	if (!ret) +		SET_FLAG(lsp->flags, LSP_FLAG_INSTALLED); +	else +		clear_nhlfe_installed(lsp); -  return ret; +	return ret;  }  /*   * Delete Label Forwarding entry from the kernel.   */ -int -kernel_del_lsp (zebra_lsp_t *lsp) +int kernel_del_lsp(zebra_lsp_t *lsp)  { -  if (!lsp) // unexpected -    return -1; +	if (!lsp) // unexpected +		return -1; -  if (CHECK_FLAG (lsp->flags, LSP_FLAG_INSTALLED)) -    { -      netlink_mpls_multipath (RTM_DELROUTE, lsp); -      UNSET_FLAG (lsp->flags, LSP_FLAG_INSTALLED); -    } +	if (CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED)) { +		netlink_mpls_multipath(RTM_DELROUTE, lsp); +		UNSET_FLAG(lsp->flags, LSP_FLAG_INSTALLED); +	} -  return 0; +	return 0;  } -int -mpls_kernel_init (void) +int mpls_kernel_init(void)  { -  struct stat st; +	struct stat st; -  /* -   * Check if the MPLS module is loaded in the kernel. -   */ -  if (stat ("/proc/sys/net/mpls", &st) != 0) -    return -1; +	/* +	 * Check if the MPLS module is loaded in the kernel. +	 */ +	if (stat("/proc/sys/net/mpls", &st) != 0) +		return -1; -  return 0; +	return 0;  }; diff --git a/zebra/zebra_mpls_null.c b/zebra/zebra_mpls_null.c index 23f5e72956..91877000ee 100644 --- a/zebra/zebra_mpls_null.c +++ b/zebra/zebra_mpls_null.c @@ -23,7 +23,19 @@  #include "zebra/rt.h"  #include "zebra/zebra_mpls.h" -int kernel_add_lsp (zebra_lsp_t *lsp) { return 0; } -int kernel_upd_lsp (zebra_lsp_t *lsp) { return 0; } -int kernel_del_lsp (zebra_lsp_t *lsp) { return 0; } -int mpls_kernel_init (void) { return -1; }; +int kernel_add_lsp(zebra_lsp_t *lsp) +{ +	return 0; +} +int kernel_upd_lsp(zebra_lsp_t *lsp) +{ +	return 0; +} +int kernel_del_lsp(zebra_lsp_t *lsp) +{ +	return 0; +} +int mpls_kernel_init(void) +{ +	return -1; +}; diff --git a/zebra/zebra_mpls_openbsd.c b/zebra/zebra_mpls_openbsd.c index 0fcd28e0ee..23839fb2c2 100644 --- a/zebra/zebra_mpls_openbsd.c +++ b/zebra/zebra_mpls_openbsd.c @@ -33,432 +33,419 @@  extern struct zebra_privs_t zserv_privs;  struct { -  u_int32_t rtseq; -  int fd; -  int ioctl_fd; +	u_int32_t rtseq; +	int fd; +	int ioctl_fd;  } kr_state; -static int -kernel_send_rtmsg_v4 (int action, mpls_label_t in_label, zebra_nhlfe_t *nhlfe) +static int kernel_send_rtmsg_v4(int action, mpls_label_t in_label, +				zebra_nhlfe_t *nhlfe)  { -  struct iovec iov[5]; -  struct rt_msghdr hdr; -  struct sockaddr_mpls sa_label_in, sa_label_out; -  struct sockaddr_in nexthop; -  int iovcnt = 0; -  int ret; - -  if (IS_ZEBRA_DEBUG_KERNEL) -    zlog_debug ("%s: 0x%x, label=%u", __func__, action, in_label); - -  /* initialize header */ -  memset (&hdr, 0, sizeof (hdr)); -  hdr.rtm_version = RTM_VERSION; - -  hdr.rtm_type = action; -  hdr.rtm_flags = RTF_UP; -  hdr.rtm_fmask = RTF_MPLS; -  hdr.rtm_seq = kr_state.rtseq++;	/* overflow doesn't matter */ -  hdr.rtm_msglen = sizeof (hdr); -  hdr.rtm_hdrlen = sizeof (struct rt_msghdr); -  hdr.rtm_priority = 0; -  /* adjust iovec */ -  iov[iovcnt].iov_base = &hdr; -  iov[iovcnt++].iov_len = sizeof (hdr); - -  /* in label */ -  memset (&sa_label_in, 0, sizeof (sa_label_in)); -  sa_label_in.smpls_len = sizeof (sa_label_in); -  sa_label_in.smpls_family = AF_MPLS; -  sa_label_in.smpls_label = htonl(in_label << MPLS_LABEL_OFFSET); -  /* adjust header */ -  hdr.rtm_flags |= RTF_MPLS | RTF_MPATH; -  hdr.rtm_addrs |= RTA_DST; -  hdr.rtm_msglen += sizeof (sa_label_in); -  /* adjust iovec */ -  iov[iovcnt].iov_base = &sa_label_in; -  iov[iovcnt++].iov_len = sizeof (sa_label_in); - -  /* nexthop */ -  memset (&nexthop, 0, sizeof (nexthop)); -  nexthop.sin_len = sizeof (nexthop); -  nexthop.sin_family = AF_INET; -  nexthop.sin_addr = nhlfe->nexthop->gate.ipv4; -  /* adjust header */ -  hdr.rtm_flags |= RTF_GATEWAY; -  hdr.rtm_addrs |= RTA_GATEWAY; -  hdr.rtm_msglen += sizeof (nexthop); -  /* adjust iovec */ -  iov[iovcnt].iov_base = &nexthop; -  iov[iovcnt++].iov_len = sizeof (nexthop); - -  /* If action is RTM_DELETE we have to get rid of MPLS infos */ -  if (action != RTM_DELETE) -    { -      memset (&sa_label_out, 0, sizeof (sa_label_out)); -      sa_label_out.smpls_len = sizeof (sa_label_out); -      sa_label_out.smpls_family = AF_MPLS; -      sa_label_out.smpls_label = -	htonl(nhlfe->nexthop->nh_label->label[0] << MPLS_LABEL_OFFSET); -      /* adjust header */ -      hdr.rtm_addrs |= RTA_SRC; -      hdr.rtm_flags |= RTF_MPLS; -      hdr.rtm_msglen += sizeof (sa_label_out); -      /* adjust iovec */ -      iov[iovcnt].iov_base = &sa_label_out; -      iov[iovcnt++].iov_len = sizeof (sa_label_out); - -      if (nhlfe->nexthop->nh_label->label[0] == MPLS_LABEL_IMPLNULL) -	hdr.rtm_mpls = MPLS_OP_POP; -      else -	hdr.rtm_mpls = MPLS_OP_SWAP; -    } - -  if (zserv_privs.change(ZPRIVS_RAISE)) -    zlog_err ("Can't raise privileges"); -  ret = writev (kr_state.fd, iov, iovcnt); -  if (zserv_privs.change(ZPRIVS_LOWER)) -    zlog_err ("Can't lower privileges"); - -  if (ret == -1) -    zlog_err ("%s: %s", __func__, safe_strerror (errno)); - -  return ret; +	struct iovec iov[5]; +	struct rt_msghdr hdr; +	struct sockaddr_mpls sa_label_in, sa_label_out; +	struct sockaddr_in nexthop; +	int iovcnt = 0; +	int ret; + +	if (IS_ZEBRA_DEBUG_KERNEL) +		zlog_debug("%s: 0x%x, label=%u", __func__, action, in_label); + +	/* initialize header */ +	memset(&hdr, 0, sizeof(hdr)); +	hdr.rtm_version = RTM_VERSION; + +	hdr.rtm_type = action; +	hdr.rtm_flags = RTF_UP; +	hdr.rtm_fmask = RTF_MPLS; +	hdr.rtm_seq = kr_state.rtseq++; /* overflow doesn't matter */ +	hdr.rtm_msglen = sizeof(hdr); +	hdr.rtm_hdrlen = sizeof(struct rt_msghdr); +	hdr.rtm_priority = 0; +	/* adjust iovec */ +	iov[iovcnt].iov_base = &hdr; +	iov[iovcnt++].iov_len = sizeof(hdr); + +	/* in label */ +	memset(&sa_label_in, 0, sizeof(sa_label_in)); +	sa_label_in.smpls_len = sizeof(sa_label_in); +	sa_label_in.smpls_family = AF_MPLS; +	sa_label_in.smpls_label = htonl(in_label << MPLS_LABEL_OFFSET); +	/* adjust header */ +	hdr.rtm_flags |= RTF_MPLS | RTF_MPATH; +	hdr.rtm_addrs |= RTA_DST; +	hdr.rtm_msglen += sizeof(sa_label_in); +	/* adjust iovec */ +	iov[iovcnt].iov_base = &sa_label_in; +	iov[iovcnt++].iov_len = sizeof(sa_label_in); + +	/* nexthop */ +	memset(&nexthop, 0, sizeof(nexthop)); +	nexthop.sin_len = sizeof(nexthop); +	nexthop.sin_family = AF_INET; +	nexthop.sin_addr = nhlfe->nexthop->gate.ipv4; +	/* adjust header */ +	hdr.rtm_flags |= RTF_GATEWAY; +	hdr.rtm_addrs |= RTA_GATEWAY; +	hdr.rtm_msglen += sizeof(nexthop); +	/* adjust iovec */ +	iov[iovcnt].iov_base = &nexthop; +	iov[iovcnt++].iov_len = sizeof(nexthop); + +	/* If action is RTM_DELETE we have to get rid of MPLS infos */ +	if (action != RTM_DELETE) { +		memset(&sa_label_out, 0, sizeof(sa_label_out)); +		sa_label_out.smpls_len = sizeof(sa_label_out); +		sa_label_out.smpls_family = AF_MPLS; +		sa_label_out.smpls_label = +			htonl(nhlfe->nexthop->nh_label->label[0] +			      << MPLS_LABEL_OFFSET); +		/* adjust header */ +		hdr.rtm_addrs |= RTA_SRC; +		hdr.rtm_flags |= RTF_MPLS; +		hdr.rtm_msglen += sizeof(sa_label_out); +		/* adjust iovec */ +		iov[iovcnt].iov_base = &sa_label_out; +		iov[iovcnt++].iov_len = sizeof(sa_label_out); + +		if (nhlfe->nexthop->nh_label->label[0] == MPLS_LABEL_IMPLNULL) +			hdr.rtm_mpls = MPLS_OP_POP; +		else +			hdr.rtm_mpls = MPLS_OP_SWAP; +	} + +	if (zserv_privs.change(ZPRIVS_RAISE)) +		zlog_err("Can't raise privileges"); +	ret = writev(kr_state.fd, iov, iovcnt); +	if (zserv_privs.change(ZPRIVS_LOWER)) +		zlog_err("Can't lower privileges"); + +	if (ret == -1) +		zlog_err("%s: %s", __func__, safe_strerror(errno)); + +	return ret;  }  #if !defined(ROUNDUP) -#define	ROUNDUP(a)	\ -    (((a) & (sizeof(long) - 1)) ? (1 + ((a) | (sizeof(long) - 1))) : (a)) +#define ROUNDUP(a)                                                             \ +	(((a) & (sizeof(long) - 1)) ? (1 + ((a) | (sizeof(long) - 1))) : (a))  #endif -static int -kernel_send_rtmsg_v6 (int action, mpls_label_t in_label, zebra_nhlfe_t *nhlfe) +static int kernel_send_rtmsg_v6(int action, mpls_label_t in_label, +				zebra_nhlfe_t *nhlfe)  { -  struct iovec iov[5]; -  struct rt_msghdr hdr; -  struct sockaddr_mpls sa_label_in, sa_label_out; -  struct pad { -      struct sockaddr_in6	addr; -      char			pad[sizeof(long)]; /* thank you IPv6 */ -  } nexthop; -  int iovcnt = 0; -  int ret; - -  if (IS_ZEBRA_DEBUG_KERNEL) -    zlog_debug ("%s: 0x%x, label=%u", __func__, action, in_label); - -  /* initialize header */ -  memset (&hdr, 0, sizeof (hdr)); -  hdr.rtm_version = RTM_VERSION; - -  hdr.rtm_type = action; -  hdr.rtm_flags = RTF_UP; -  hdr.rtm_fmask = RTF_MPLS; -  hdr.rtm_seq = kr_state.rtseq++;	/* overflow doesn't matter */ -  hdr.rtm_msglen = sizeof (hdr); -  hdr.rtm_hdrlen = sizeof (struct rt_msghdr); -  hdr.rtm_priority = 0; -  /* adjust iovec */ -  iov[iovcnt].iov_base = &hdr; -  iov[iovcnt++].iov_len = sizeof (hdr); - -  /* in label */ -  memset (&sa_label_in, 0, sizeof (sa_label_in)); -  sa_label_in.smpls_len = sizeof (sa_label_in); -  sa_label_in.smpls_family = AF_MPLS; -  sa_label_in.smpls_label = htonl(in_label << MPLS_LABEL_OFFSET); -  /* adjust header */ -  hdr.rtm_flags |= RTF_MPLS | RTF_MPATH; -  hdr.rtm_addrs |= RTA_DST; -  hdr.rtm_msglen += sizeof (sa_label_in); -  /* adjust iovec */ -  iov[iovcnt].iov_base = &sa_label_in; -  iov[iovcnt++].iov_len = sizeof (sa_label_in); - -  /* nexthop */ -  memset (&nexthop, 0, sizeof (nexthop)); -  nexthop.addr.sin6_len = sizeof (struct sockaddr_in6); -  nexthop.addr.sin6_family = AF_INET6; -  nexthop.addr.sin6_addr = nhlfe->nexthop->gate.ipv6; -  if (IN6_IS_ADDR_LINKLOCAL (&nexthop.addr.sin6_addr)) -    { -      uint16_t			 tmp16; -      struct sockaddr_in6	*sin6 = &nexthop.addr; - -      nexthop.addr.sin6_scope_id = nhlfe->nexthop->ifindex; - -      memcpy (&tmp16, &sin6->sin6_addr.s6_addr[2], sizeof (tmp16)); -      tmp16 = htons (sin6->sin6_scope_id); -      memcpy (&sin6->sin6_addr.s6_addr[2], &tmp16, sizeof (tmp16)); -      sin6->sin6_scope_id = 0; -    } - -  /* adjust header */ -  hdr.rtm_flags |= RTF_GATEWAY; -  hdr.rtm_addrs |= RTA_GATEWAY; -  hdr.rtm_msglen += ROUNDUP (sizeof (struct sockaddr_in6)); -  /* adjust iovec */ -  iov[iovcnt].iov_base = &nexthop; -  iov[iovcnt++].iov_len = ROUNDUP (sizeof (struct sockaddr_in6)); - -  /* If action is RTM_DELETE we have to get rid of MPLS infos */ -  if (action != RTM_DELETE) -    { -      memset (&sa_label_out, 0, sizeof (sa_label_out)); -      sa_label_out.smpls_len = sizeof (sa_label_out); -      sa_label_out.smpls_family = AF_MPLS; -      sa_label_out.smpls_label = -	htonl(nhlfe->nexthop->nh_label->label[0] << MPLS_LABEL_OFFSET); -      /* adjust header */ -      hdr.rtm_addrs |= RTA_SRC; -      hdr.rtm_flags |= RTF_MPLS; -      hdr.rtm_msglen += sizeof (sa_label_out); -      /* adjust iovec */ -      iov[iovcnt].iov_base = &sa_label_out; -      iov[iovcnt++].iov_len = sizeof (sa_label_out); - -      if (nhlfe->nexthop->nh_label->label[0] == MPLS_LABEL_IMPLNULL) -	hdr.rtm_mpls = MPLS_OP_POP; -      else -	hdr.rtm_mpls = MPLS_OP_SWAP; -    } - -  if (zserv_privs.change(ZPRIVS_RAISE)) -    zlog_err ("Can't raise privileges"); -  ret = writev (kr_state.fd, iov, iovcnt); -  if (zserv_privs.change(ZPRIVS_LOWER)) -    zlog_err ("Can't lower privileges"); - -  if (ret == -1) -    zlog_err ("%s: %s", __func__, safe_strerror (errno)); - -  return ret; +	struct iovec iov[5]; +	struct rt_msghdr hdr; +	struct sockaddr_mpls sa_label_in, sa_label_out; +	struct pad { +		struct sockaddr_in6 addr; +		char pad[sizeof(long)]; /* thank you IPv6 */ +	} nexthop; +	int iovcnt = 0; +	int ret; + +	if (IS_ZEBRA_DEBUG_KERNEL) +		zlog_debug("%s: 0x%x, label=%u", __func__, action, in_label); + +	/* initialize header */ +	memset(&hdr, 0, sizeof(hdr)); +	hdr.rtm_version = RTM_VERSION; + +	hdr.rtm_type = action; +	hdr.rtm_flags = RTF_UP; +	hdr.rtm_fmask = RTF_MPLS; +	hdr.rtm_seq = kr_state.rtseq++; /* overflow doesn't matter */ +	hdr.rtm_msglen = sizeof(hdr); +	hdr.rtm_hdrlen = sizeof(struct rt_msghdr); +	hdr.rtm_priority = 0; +	/* adjust iovec */ +	iov[iovcnt].iov_base = &hdr; +	iov[iovcnt++].iov_len = sizeof(hdr); + +	/* in label */ +	memset(&sa_label_in, 0, sizeof(sa_label_in)); +	sa_label_in.smpls_len = sizeof(sa_label_in); +	sa_label_in.smpls_family = AF_MPLS; +	sa_label_in.smpls_label = htonl(in_label << MPLS_LABEL_OFFSET); +	/* adjust header */ +	hdr.rtm_flags |= RTF_MPLS | RTF_MPATH; +	hdr.rtm_addrs |= RTA_DST; +	hdr.rtm_msglen += sizeof(sa_label_in); +	/* adjust iovec */ +	iov[iovcnt].iov_base = &sa_label_in; +	iov[iovcnt++].iov_len = sizeof(sa_label_in); + +	/* nexthop */ +	memset(&nexthop, 0, sizeof(nexthop)); +	nexthop.addr.sin6_len = sizeof(struct sockaddr_in6); +	nexthop.addr.sin6_family = AF_INET6; +	nexthop.addr.sin6_addr = nhlfe->nexthop->gate.ipv6; +	if (IN6_IS_ADDR_LINKLOCAL(&nexthop.addr.sin6_addr)) { +		uint16_t tmp16; +		struct sockaddr_in6 *sin6 = &nexthop.addr; + +		nexthop.addr.sin6_scope_id = nhlfe->nexthop->ifindex; + +		memcpy(&tmp16, &sin6->sin6_addr.s6_addr[2], sizeof(tmp16)); +		tmp16 = htons(sin6->sin6_scope_id); +		memcpy(&sin6->sin6_addr.s6_addr[2], &tmp16, sizeof(tmp16)); +		sin6->sin6_scope_id = 0; +	} + +	/* adjust header */ +	hdr.rtm_flags |= RTF_GATEWAY; +	hdr.rtm_addrs |= RTA_GATEWAY; +	hdr.rtm_msglen += ROUNDUP(sizeof(struct sockaddr_in6)); +	/* adjust iovec */ +	iov[iovcnt].iov_base = &nexthop; +	iov[iovcnt++].iov_len = ROUNDUP(sizeof(struct sockaddr_in6)); + +	/* If action is RTM_DELETE we have to get rid of MPLS infos */ +	if (action != RTM_DELETE) { +		memset(&sa_label_out, 0, sizeof(sa_label_out)); +		sa_label_out.smpls_len = sizeof(sa_label_out); +		sa_label_out.smpls_family = AF_MPLS; +		sa_label_out.smpls_label = +			htonl(nhlfe->nexthop->nh_label->label[0] +			      << MPLS_LABEL_OFFSET); +		/* adjust header */ +		hdr.rtm_addrs |= RTA_SRC; +		hdr.rtm_flags |= RTF_MPLS; +		hdr.rtm_msglen += sizeof(sa_label_out); +		/* adjust iovec */ +		iov[iovcnt].iov_base = &sa_label_out; +		iov[iovcnt++].iov_len = sizeof(sa_label_out); + +		if (nhlfe->nexthop->nh_label->label[0] == MPLS_LABEL_IMPLNULL) +			hdr.rtm_mpls = MPLS_OP_POP; +		else +			hdr.rtm_mpls = MPLS_OP_SWAP; +	} + +	if (zserv_privs.change(ZPRIVS_RAISE)) +		zlog_err("Can't raise privileges"); +	ret = writev(kr_state.fd, iov, iovcnt); +	if (zserv_privs.change(ZPRIVS_LOWER)) +		zlog_err("Can't lower privileges"); + +	if (ret == -1) +		zlog_err("%s: %s", __func__, safe_strerror(errno)); + +	return ret;  } -static int -kernel_lsp_cmd (int action, zebra_lsp_t *lsp) +static int kernel_lsp_cmd(int action, zebra_lsp_t *lsp)  { -  zebra_nhlfe_t *nhlfe; -  struct nexthop *nexthop = NULL; -  unsigned int nexthop_num = 0; - -  for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) -    { -      nexthop = nhlfe->nexthop; -      if (!nexthop) -        continue; - -      if (nexthop_num >= multipath_num) -        break; - -      if (((action == RTM_ADD || action == RTM_CHANGE) && -           (CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_SELECTED) && -            CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))) || -          (action == RTM_DELETE && -           (CHECK_FLAG (nhlfe->flags, NHLFE_FLAG_INSTALLED) && -            CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)))) -        { -          nexthop_num++; - -	  switch (NHLFE_FAMILY(nhlfe)) -	    { -	    case AF_INET: -	      kernel_send_rtmsg_v4 (action, lsp->ile.in_label, nhlfe); -	      break; -	    case AF_INET6: -	      kernel_send_rtmsg_v6 (action, lsp->ile.in_label, nhlfe); -	      break; -	    default: -	      break; -	    } -          if (action == RTM_ADD || action == RTM_CHANGE) -            { -              SET_FLAG (nhlfe->flags, NHLFE_FLAG_INSTALLED); -              SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); -            } -          else -            { -              UNSET_FLAG (nhlfe->flags, NHLFE_FLAG_INSTALLED); -              UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); -            } -        } -    } - -  return (0); +	zebra_nhlfe_t *nhlfe; +	struct nexthop *nexthop = NULL; +	unsigned int nexthop_num = 0; + +	for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) { +		nexthop = nhlfe->nexthop; +		if (!nexthop) +			continue; + +		if (nexthop_num >= multipath_num) +			break; + +		if (((action == RTM_ADD || action == RTM_CHANGE) +		     && (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_SELECTED) +			 && CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))) +		    || (action == RTM_DELETE +			&& (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED) +			    && CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)))) { +			nexthop_num++; + +			switch (NHLFE_FAMILY(nhlfe)) { +			case AF_INET: +				kernel_send_rtmsg_v4(action, lsp->ile.in_label, +						     nhlfe); +				break; +			case AF_INET6: +				kernel_send_rtmsg_v6(action, lsp->ile.in_label, +						     nhlfe); +				break; +			default: +				break; +			} +			if (action == RTM_ADD || action == RTM_CHANGE) { +				SET_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED); +				SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); +			} else { +				UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED); +				UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); +			} +		} +	} + +	return (0);  } -int -kernel_add_lsp (zebra_lsp_t *lsp) +int kernel_add_lsp(zebra_lsp_t *lsp)  { -  int ret; +	int ret; -  if (!lsp || !lsp->best_nhlfe) // unexpected -    return -1; +	if (!lsp || !lsp->best_nhlfe) // unexpected +		return -1; -  UNSET_FLAG (lsp->flags, LSP_FLAG_CHANGED); -  ret = kernel_lsp_cmd (RTM_ADD, lsp); -  if (!ret) -    SET_FLAG (lsp->flags, LSP_FLAG_INSTALLED); +	UNSET_FLAG(lsp->flags, LSP_FLAG_CHANGED); +	ret = kernel_lsp_cmd(RTM_ADD, lsp); +	if (!ret) +		SET_FLAG(lsp->flags, LSP_FLAG_INSTALLED); -  return ret; +	return ret;  } -int -kernel_upd_lsp (zebra_lsp_t *lsp) +int kernel_upd_lsp(zebra_lsp_t *lsp)  { -  int ret; +	int ret; -  if (!lsp || !lsp->best_nhlfe) // unexpected -    return -1; +	if (!lsp || !lsp->best_nhlfe) // unexpected +		return -1; -  UNSET_FLAG (lsp->flags, LSP_FLAG_CHANGED); -  UNSET_FLAG (lsp->flags, LSP_FLAG_INSTALLED); -  ret = kernel_lsp_cmd (RTM_CHANGE, lsp); -  if (!ret) -    SET_FLAG (lsp->flags, LSP_FLAG_INSTALLED); +	UNSET_FLAG(lsp->flags, LSP_FLAG_CHANGED); +	UNSET_FLAG(lsp->flags, LSP_FLAG_INSTALLED); +	ret = kernel_lsp_cmd(RTM_CHANGE, lsp); +	if (!ret) +		SET_FLAG(lsp->flags, LSP_FLAG_INSTALLED); -  return ret; +	return ret;  } -int -kernel_del_lsp (zebra_lsp_t *lsp) +int kernel_del_lsp(zebra_lsp_t *lsp)  { -  int ret; +	int ret; -  if (!lsp) // unexpected -    return -1; +	if (!lsp) // unexpected +		return -1; -  if (! CHECK_FLAG (lsp->flags, LSP_FLAG_INSTALLED)) -    return -1; +	if (!CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED)) +		return -1; -  ret = kernel_lsp_cmd (RTM_DELETE, lsp); -  if (!ret) -    UNSET_FLAG (lsp->flags, LSP_FLAG_INSTALLED); +	ret = kernel_lsp_cmd(RTM_DELETE, lsp); +	if (!ret) +		UNSET_FLAG(lsp->flags, LSP_FLAG_INSTALLED); -  return ret; +	return ret;  } -static int -kmpw_install (struct zebra_pw *pw) +static int kmpw_install(struct zebra_pw *pw)  { -  struct ifreq ifr; -  struct ifmpwreq imr; -  struct sockaddr_storage ss; -  struct sockaddr_in *sa_in = (struct sockaddr_in *) &ss; -  struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *) &ss; - -  memset (&imr, 0, sizeof (imr)); -  switch (pw->type) -    { -    case PW_TYPE_ETHERNET: -      imr.imr_type = IMR_TYPE_ETHERNET; -      break; -    case PW_TYPE_ETHERNET_TAGGED: -      imr.imr_type = IMR_TYPE_ETHERNET_TAGGED; -      break; -    default: -      zlog_err ("%s: unhandled pseudowire type (%#X)", __func__, -                pw->type); -      return -1; -    } - -  if (pw->flags & F_PSEUDOWIRE_CWORD) -    imr.imr_flags |= IMR_FLAG_CONTROLWORD; - -  /* pseudowire nexthop */ -  memset (&ss, 0, sizeof (ss)); -  switch (pw->af) { -    case AF_INET: -      sa_in->sin_family = AF_INET; -      sa_in->sin_len = sizeof (struct sockaddr_in); -      sa_in->sin_addr = pw->nexthop.ipv4; -      break; -    case AF_INET6: -      sa_in6->sin6_family = AF_INET6; -      sa_in6->sin6_len = sizeof (struct sockaddr_in6); -      sa_in6->sin6_addr = pw->nexthop.ipv6; -      break; -    default: -      zlog_err ("%s: unhandled pseudowire address-family (%u)", __func__, -		pw->af); -      return -1; -  } -  memcpy (&imr.imr_nexthop, (struct sockaddr *) &ss, -	  sizeof (imr.imr_nexthop)); - -  /* pseudowire local/remote labels */ -  imr.imr_lshim.shim_label = pw->local_label; -  imr.imr_rshim.shim_label = pw->remote_label; - -  /* ioctl */ -  memset (&ifr, 0, sizeof (ifr)); -  strlcpy (ifr.ifr_name, pw->ifname, sizeof (ifr.ifr_name)); -  ifr.ifr_data = (caddr_t) &imr; -  if (ioctl (kr_state.ioctl_fd, SIOCSETMPWCFG, &ifr) == -1) -    { -      zlog_err ("ioctl SIOCSETMPWCFG: %s", safe_strerror (errno)); -      return -1; -    } - -  return 0; +	struct ifreq ifr; +	struct ifmpwreq imr; +	struct sockaddr_storage ss; +	struct sockaddr_in *sa_in = (struct sockaddr_in *)&ss; +	struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *)&ss; + +	memset(&imr, 0, sizeof(imr)); +	switch (pw->type) { +	case PW_TYPE_ETHERNET: +		imr.imr_type = IMR_TYPE_ETHERNET; +		break; +	case PW_TYPE_ETHERNET_TAGGED: +		imr.imr_type = IMR_TYPE_ETHERNET_TAGGED; +		break; +	default: +		zlog_err("%s: unhandled pseudowire type (%#X)", __func__, +			 pw->type); +		return -1; +	} + +	if (pw->flags & F_PSEUDOWIRE_CWORD) +		imr.imr_flags |= IMR_FLAG_CONTROLWORD; + +	/* pseudowire nexthop */ +	memset(&ss, 0, sizeof(ss)); +	switch (pw->af) { +	case AF_INET: +		sa_in->sin_family = AF_INET; +		sa_in->sin_len = sizeof(struct sockaddr_in); +		sa_in->sin_addr = pw->nexthop.ipv4; +		break; +	case AF_INET6: +		sa_in6->sin6_family = AF_INET6; +		sa_in6->sin6_len = sizeof(struct sockaddr_in6); +		sa_in6->sin6_addr = pw->nexthop.ipv6; +		break; +	default: +		zlog_err("%s: unhandled pseudowire address-family (%u)", +			 __func__, pw->af); +		return -1; +	} +	memcpy(&imr.imr_nexthop, (struct sockaddr *)&ss, +	       sizeof(imr.imr_nexthop)); + +	/* pseudowire local/remote labels */ +	imr.imr_lshim.shim_label = pw->local_label; +	imr.imr_rshim.shim_label = pw->remote_label; + +	/* ioctl */ +	memset(&ifr, 0, sizeof(ifr)); +	strlcpy(ifr.ifr_name, pw->ifname, sizeof(ifr.ifr_name)); +	ifr.ifr_data = (caddr_t)&imr; +	if (ioctl(kr_state.ioctl_fd, SIOCSETMPWCFG, &ifr) == -1) { +		zlog_err("ioctl SIOCSETMPWCFG: %s", safe_strerror(errno)); +		return -1; +	} + +	return 0;  } -static int -kmpw_uninstall (struct zebra_pw *pw) +static int kmpw_uninstall(struct zebra_pw *pw)  { -  struct ifreq ifr; -  struct ifmpwreq imr; - -  memset(&ifr, 0, sizeof (ifr)); -  memset(&imr, 0, sizeof (imr)); -  strlcpy (ifr.ifr_name, pw->ifname, sizeof (ifr.ifr_name)); -  ifr.ifr_data = (caddr_t) &imr; -  if (ioctl (kr_state.ioctl_fd, SIOCSETMPWCFG, &ifr) == -1) -    { -      zlog_err ("ioctl SIOCSETMPWCFG: %s", safe_strerror (errno)); -      return -1; -    } - -  return 0; +	struct ifreq ifr; +	struct ifmpwreq imr; + +	memset(&ifr, 0, sizeof(ifr)); +	memset(&imr, 0, sizeof(imr)); +	strlcpy(ifr.ifr_name, pw->ifname, sizeof(ifr.ifr_name)); +	ifr.ifr_data = (caddr_t)&imr; +	if (ioctl(kr_state.ioctl_fd, SIOCSETMPWCFG, &ifr) == -1) { +		zlog_err("ioctl SIOCSETMPWCFG: %s", safe_strerror(errno)); +		return -1; +	} + +	return 0;  }  #define MAX_RTSOCK_BUF	128 * 1024 -int -mpls_kernel_init (void) +int mpls_kernel_init(void)  { -  int		rcvbuf, default_rcvbuf; -  socklen_t	optlen; - -  if ((kr_state.fd = socket(AF_ROUTE, SOCK_RAW, 0)) == -1) -    { -      zlog_warn("%s: socket", __func__); -      return -1; -    } - -  if ((kr_state.ioctl_fd = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, 0)) == -1) -    { -      zlog_warn("%s: ioctl socket", __func__); -      return -1; -    } - -  /* grow receive buffer, don't wanna miss messages */ -  optlen = sizeof (default_rcvbuf); -  if (getsockopt(kr_state.fd, SOL_SOCKET, SO_RCVBUF, -		 &default_rcvbuf, &optlen) == -1) -    zlog_warn("kr_init getsockopt SOL_SOCKET SO_RCVBUF"); -  else -    for (rcvbuf = MAX_RTSOCK_BUF; -	 rcvbuf > default_rcvbuf && -	 setsockopt(kr_state.fd, SOL_SOCKET, SO_RCVBUF, -		    &rcvbuf, sizeof (rcvbuf)) == -1 && errno == ENOBUFS; -	 rcvbuf /= 2) -      ;	/* nothing */ - -  kr_state.rtseq = 1; - -  /* register hook to install/uninstall pseudowires */ -  hook_register (pw_install, kmpw_install); -  hook_register (pw_uninstall, kmpw_uninstall); - -  return 0; +	int rcvbuf, default_rcvbuf; +	socklen_t optlen; + +	if ((kr_state.fd = socket(AF_ROUTE, SOCK_RAW, 0)) == -1) { +		zlog_warn("%s: socket", __func__); +		return -1; +	} + +	if ((kr_state.ioctl_fd = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, 0)) +	    == -1) { +		zlog_warn("%s: ioctl socket", __func__); +		return -1; +	} + +	/* grow receive buffer, don't wanna miss messages */ +	optlen = sizeof(default_rcvbuf); +	if (getsockopt(kr_state.fd, SOL_SOCKET, SO_RCVBUF, &default_rcvbuf, +		       &optlen) +	    == -1) +		zlog_warn("kr_init getsockopt SOL_SOCKET SO_RCVBUF"); +	else +		for (rcvbuf = MAX_RTSOCK_BUF; +		     rcvbuf > default_rcvbuf +		     && setsockopt(kr_state.fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, +				   sizeof(rcvbuf)) +				== -1 +		     && errno == ENOBUFS; +		     rcvbuf /= 2) +			; /* nothing */ + +	kr_state.rtseq = 1; + +	/* register hook to install/uninstall pseudowires */ +	hook_register(pw_install, kmpw_install); +	hook_register(pw_uninstall, kmpw_uninstall); + +	return 0;  } diff --git a/zebra/zebra_mpls_vty.c b/zebra/zebra_mpls_vty.c index dd381723c5..a706c3da19 100644 --- a/zebra/zebra_mpls_vty.c +++ b/zebra/zebra_mpls_vty.c @@ -14,9 +14,9 @@   * General Public License for more details.   *   * You should have received a copy of the GNU General Public License - * along with GNU Zebra; see the file COPYING.  If not, write to the  - * Free Software Foundation, Inc., 59 Temple Place - Suite 330,  - * Boston, MA 02111-1307, USA.   + * along with GNU Zebra; see the file COPYING.  If not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA.   */  #include <zebra.h> @@ -40,121 +40,111 @@  #include "zebra/zebra_routemap.h"  #include "zebra/zebra_static.h" -static int -zebra_mpls_transit_lsp (struct vty *vty, int add_cmd, const char *inlabel_str, -		        const char *gate_str, const char *outlabel_str, -                        const char *flag_str) -{ -  struct zebra_vrf *zvrf; -  int ret; -  enum nexthop_types_t gtype; -  union g_addr gate; -  mpls_label_t label; -  mpls_label_t in_label, out_label; - -  if (!mpls_enabled) -    { -      vty_out (vty, "%% MPLS not turned on in kernel, ignoring command%s", -	       VTY_NEWLINE); -      return CMD_WARNING; -    } - -  zvrf = vrf_info_lookup(VRF_DEFAULT); -  if (!zvrf) -    { -      vty_out (vty, "%% Default VRF does not exist%s", VTY_NEWLINE); -      return CMD_WARNING; -    } - -  if (!inlabel_str) -    { -      vty_out (vty, "%% No Label Information%s", VTY_NEWLINE); -      return CMD_WARNING; -    } - -  out_label = MPLS_IMP_NULL_LABEL; /* as initialization */ -  label = atoi(inlabel_str); -  if (!IS_MPLS_UNRESERVED_LABEL(label)) -    { -      vty_out (vty, "%% Invalid label%s", VTY_NEWLINE); -      return CMD_WARNING; -    } - -  if (add_cmd) -    { -      if (!gate_str) -        { -          vty_out (vty, "%% No Nexthop Information%s", VTY_NEWLINE); -          return CMD_WARNING; -        } -      if (!outlabel_str) -        { -          vty_out (vty, "%% No Outgoing label Information%s", VTY_NEWLINE); -          return CMD_WARNING; -        } -    } - -  in_label = label; -  gtype = NEXTHOP_TYPE_BLACKHOLE; /* as initialization */ - -  if (gate_str) -    { -      /* Gateway is a IPv4 or IPv6 nexthop. */ -      ret = inet_pton (AF_INET6, gate_str, &gate.ipv6); -      if (ret) -        gtype = NEXTHOP_TYPE_IPV6; -      else -        { -          ret = inet_pton (AF_INET, gate_str, &gate.ipv4); -          if (ret) -            gtype = NEXTHOP_TYPE_IPV4; -          else -            { -              vty_out (vty, "%% Invalid nexthop%s", VTY_NEWLINE); -              return CMD_WARNING; -            } -        } -    } - -  if (outlabel_str) -    { -      if (outlabel_str[0] == 'i') -        out_label = MPLS_IMP_NULL_LABEL; -      else if (outlabel_str[0] == 'e' && gtype == NEXTHOP_TYPE_IPV4) -        out_label = MPLS_V4_EXP_NULL_LABEL; -      else if (outlabel_str[0] == 'e' && gtype == NEXTHOP_TYPE_IPV6) -        out_label = MPLS_V6_EXP_NULL_LABEL; -      else -        out_label = atoi(outlabel_str); -    } - -  if (add_cmd) -    { +static int zebra_mpls_transit_lsp(struct vty *vty, int add_cmd, +				  const char *inlabel_str, const char *gate_str, +				  const char *outlabel_str, +				  const char *flag_str) +{ +	struct zebra_vrf *zvrf; +	int ret; +	enum nexthop_types_t gtype; +	union g_addr gate; +	mpls_label_t label; +	mpls_label_t in_label, out_label; + +	if (!mpls_enabled) { +		vty_out(vty, +			"%% MPLS not turned on in kernel, ignoring command%s", +			VTY_NEWLINE); +		return CMD_WARNING; +	} + +	zvrf = vrf_info_lookup(VRF_DEFAULT); +	if (!zvrf) { +		vty_out(vty, "%% Default VRF does not exist%s", VTY_NEWLINE); +		return CMD_WARNING; +	} + +	if (!inlabel_str) { +		vty_out(vty, "%% No Label Information%s", VTY_NEWLINE); +		return CMD_WARNING; +	} + +	out_label = MPLS_IMP_NULL_LABEL; /* as initialization */ +	label = atoi(inlabel_str); +	if (!IS_MPLS_UNRESERVED_LABEL(label)) { +		vty_out(vty, "%% Invalid label%s", VTY_NEWLINE); +		return CMD_WARNING; +	} + +	if (add_cmd) { +		if (!gate_str) { +			vty_out(vty, "%% No Nexthop Information%s", +				VTY_NEWLINE); +			return CMD_WARNING; +		} +		if (!outlabel_str) { +			vty_out(vty, "%% No Outgoing label Information%s", +				VTY_NEWLINE); +			return CMD_WARNING; +		} +	} + +	in_label = label; +	gtype = NEXTHOP_TYPE_BLACKHOLE; /* as initialization */ + +	if (gate_str) { +		/* Gateway is a IPv4 or IPv6 nexthop. */ +		ret = inet_pton(AF_INET6, gate_str, &gate.ipv6); +		if (ret) +			gtype = NEXTHOP_TYPE_IPV6; +		else { +			ret = inet_pton(AF_INET, gate_str, &gate.ipv4); +			if (ret) +				gtype = NEXTHOP_TYPE_IPV4; +			else { +				vty_out(vty, "%% Invalid nexthop%s", +					VTY_NEWLINE); +				return CMD_WARNING; +			} +		} +	} + +	if (outlabel_str) { +		if (outlabel_str[0] == 'i') +			out_label = MPLS_IMP_NULL_LABEL; +		else if (outlabel_str[0] == 'e' && gtype == NEXTHOP_TYPE_IPV4) +			out_label = MPLS_V4_EXP_NULL_LABEL; +		else if (outlabel_str[0] == 'e' && gtype == NEXTHOP_TYPE_IPV6) +			out_label = MPLS_V6_EXP_NULL_LABEL; +		else +			out_label = atoi(outlabel_str); +	} + +	if (add_cmd) {  #if defined(HAVE_CUMULUS) -      /* Check that label value is consistent. */ -      if (!zebra_mpls_lsp_label_consistent (zvrf, in_label, out_label, gtype, -                                            &gate, NULL, 0)) -        { -          vty_out (vty, "%% Label value not consistent%s", -                   VTY_NEWLINE); -          return CMD_WARNING; -        } +		/* Check that label value is consistent. */ +		if (!zebra_mpls_lsp_label_consistent(zvrf, in_label, out_label, +						     gtype, &gate, NULL, 0)) { +			vty_out(vty, "%% Label value not consistent%s", +				VTY_NEWLINE); +			return CMD_WARNING; +		}  #endif /* HAVE_CUMULUS */ -      ret = zebra_mpls_static_lsp_add (zvrf, in_label, out_label, gtype, -                                       &gate, NULL, 0); -    } -  else -    ret = zebra_mpls_static_lsp_del (zvrf, in_label, gtype, &gate, NULL, 0); +		ret = zebra_mpls_static_lsp_add(zvrf, in_label, out_label, +						gtype, &gate, NULL, 0); +	} else +		ret = zebra_mpls_static_lsp_del(zvrf, in_label, gtype, &gate, +						NULL, 0); -  if (ret) -    { -      vty_out (vty, "%% LSP cannot be %s%s", -               add_cmd ? "added" : "deleted", VTY_NEWLINE); -      return CMD_WARNING; -    } +	if (ret) { +		vty_out(vty, "%% LSP cannot be %s%s", +			add_cmd ? "added" : "deleted", VTY_NEWLINE); +		return CMD_WARNING; +	} -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (mpls_transit_lsp, @@ -169,7 +159,8 @@ DEFUN (mpls_transit_lsp,         "Use Explicit-Null label\n"         "Use Implicit-Null label\n")  { -  return zebra_mpls_transit_lsp (vty, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL); +	return zebra_mpls_transit_lsp(vty, 1, argv[2]->arg, argv[3]->arg, +				      argv[4]->arg, NULL);  }  DEFUN (no_mpls_transit_lsp, @@ -182,22 +173,21 @@ DEFUN (no_mpls_transit_lsp,         "IPv4 gateway address\n"         "IPv6 gateway address\n")  { -  return zebra_mpls_transit_lsp (vty, 0, argv[3]->arg, argv[4]->arg, NULL, NULL); +	return zebra_mpls_transit_lsp(vty, 0, argv[3]->arg, argv[4]->arg, NULL, +				      NULL);  } -ALIAS (no_mpls_transit_lsp, -       no_mpls_transit_lsp_out_label_cmd, -       "no mpls lsp (16-1048575) <A.B.C.D|X:X::X:X> <(16-1048575)|explicit-null|implicit-null>", -       NO_STR -       MPLS_STR -       "Establish label switched path\n" -       "Incoming MPLS label\n" -       "IPv4 gateway address\n" -       "IPv6 gateway address\n" -       "Outgoing MPLS label\n" -       "Use Explicit-Null label\n" -       "Use Implicit-Null label\n") -  +ALIAS(no_mpls_transit_lsp, no_mpls_transit_lsp_out_label_cmd, +      "no mpls lsp (16-1048575) <A.B.C.D|X:X::X:X> <(16-1048575)|explicit-null|implicit-null>", +      NO_STR MPLS_STR +      "Establish label switched path\n" +      "Incoming MPLS label\n" +      "IPv4 gateway address\n" +      "IPv6 gateway address\n" +      "Outgoing MPLS label\n" +      "Use Explicit-Null label\n" +      "Use Implicit-Null label\n") +  DEFUN (no_mpls_transit_lsp_all,         no_mpls_transit_lsp_all_cmd,         "no mpls lsp (16-1048575)", @@ -206,7 +196,7 @@ DEFUN (no_mpls_transit_lsp_all,         "Establish label switched path\n"         "Incoming MPLS label\n")  { -  return zebra_mpls_transit_lsp (vty, 0, argv[3]->arg, NULL, NULL, NULL); +	return zebra_mpls_transit_lsp(vty, 0, argv[3]->arg, NULL, NULL, NULL);  }  /* Static route configuration.  */ @@ -222,8 +212,9 @@ DEFUN (ip_route_label,         "Specify label(s) for this route\n"         "One or more labels separated by '/'\n")  { -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL, -                            NULL, NULL, argv[5]->arg); +	return zebra_static_ipv4(vty, SAFI_UNICAST, 1, argv[2]->arg, NULL, +				 argv[3]->arg, NULL, NULL, NULL, NULL, +				 argv[5]->arg);  }  DEFUN (ip_route_tag_label, @@ -240,8 +231,9 @@ DEFUN (ip_route_tag_label,         "Specify label(s) for this route\n"         "One or more labels separated by '/'\n")  { -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, argv[5]->arg, -                            NULL, NULL, argv[7]->arg); +	return zebra_static_ipv4(vty, SAFI_UNICAST, 1, argv[2]->arg, NULL, +				 argv[3]->arg, NULL, argv[5]->arg, NULL, NULL, +				 argv[7]->arg);  }  /* Mask as A.B.C.D format.  */ @@ -258,8 +250,9 @@ DEFUN (ip_route_mask_label,         "Specify label(s) for this route\n"         "One or more labels separated by '/'\n")  { -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, NULL, -                            NULL, NULL, argv[6]->arg); +	return zebra_static_ipv4(vty, SAFI_UNICAST, 1, argv[2]->arg, +				 argv[3]->arg, argv[4]->arg, NULL, NULL, NULL, +				 NULL, argv[6]->arg);  }  DEFUN (ip_route_mask_tag_label, @@ -276,10 +269,10 @@ DEFUN (ip_route_mask_tag_label,         "Tag value\n"         "Specify label(s) for this route\n"         "One or more labels separated by '/'\n") -  { -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, argv[6]->arg, -                            NULL, NULL, argv[8]->arg); +	return zebra_static_ipv4(vty, SAFI_UNICAST, 1, argv[2]->arg, +				 argv[3]->arg, argv[4]->arg, NULL, argv[6]->arg, +				 NULL, NULL, argv[8]->arg);  }  /* Distance option value.  */ @@ -296,8 +289,9 @@ DEFUN (ip_route_distance_label,         "Specify label(s) for this route\n"         "One or more labels separated by '/'\n")  { -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL, -                            argv[4]->arg, NULL, argv[6]->arg); +	return zebra_static_ipv4(vty, SAFI_UNICAST, 1, argv[2]->arg, NULL, +				 argv[3]->arg, NULL, NULL, argv[4]->arg, NULL, +				 argv[6]->arg);  }  DEFUN (ip_route_tag_distance_label, @@ -314,10 +308,10 @@ DEFUN (ip_route_tag_distance_label,         "Distance value for this route\n"         "Specify label(s) for this route\n"         "One or more labels separated by '/'\n") -  { -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, argv[5]->arg, -                            argv[6]->arg, NULL, argv[8]->arg); +	return zebra_static_ipv4(vty, SAFI_UNICAST, 1, argv[2]->arg, NULL, +				 argv[3]->arg, NULL, argv[5]->arg, argv[6]->arg, +				 NULL, argv[8]->arg);  }  DEFUN (ip_route_mask_distance_label, @@ -334,8 +328,9 @@ DEFUN (ip_route_mask_distance_label,         "Specify label(s) for this route\n"         "One or more labels separated by '/'\n")  { -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, NULL, -                            argv[5]->arg, NULL, argv[7]->arg); +	return zebra_static_ipv4(vty, SAFI_UNICAST, 1, argv[2]->arg, +				 argv[3]->arg, argv[4]->arg, NULL, NULL, +				 argv[5]->arg, NULL, argv[7]->arg);  }  DEFUN (ip_route_mask_tag_distance_label, @@ -354,8 +349,9 @@ DEFUN (ip_route_mask_tag_distance_label,         "Specify label(s) for this route\n"         "One or more labels separated by '/'\n")  { -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, argv[2]->arg, argv[3]->arg, argv[4]->arg, NULL, argv[6]->arg, -                            argv[7]->arg, NULL, argv[9]->arg); +	return zebra_static_ipv4(vty, SAFI_UNICAST, 1, argv[2]->arg, +				 argv[3]->arg, argv[4]->arg, NULL, argv[6]->arg, +				 argv[7]->arg, NULL, argv[9]->arg);  }  DEFUN (no_ip_route_label, @@ -371,8 +367,9 @@ DEFUN (no_ip_route_label,         "Specify label(s) for this route\n"         "One or more labels separated by '/'\n")  { -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL, -                            NULL, NULL, argv[6]->arg); +	return zebra_static_ipv4(vty, SAFI_UNICAST, 0, argv[3]->arg, NULL, +				 argv[4]->arg, NULL, NULL, NULL, NULL, +				 argv[6]->arg);  }  DEFUN (no_ip_route_tag_label, @@ -390,8 +387,9 @@ DEFUN (no_ip_route_tag_label,         "Specify label(s) for this route\n"         "One or more labels separated by '/'\n")  { -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, argv[6]->arg, -                            NULL, NULL, argv[8]->arg); +	return zebra_static_ipv4(vty, SAFI_UNICAST, 0, argv[3]->arg, NULL, +				 argv[4]->arg, NULL, argv[6]->arg, NULL, NULL, +				 argv[8]->arg);  }  DEFUN (no_ip_route_mask_label, @@ -408,8 +406,9 @@ DEFUN (no_ip_route_mask_label,         "Specify label(s) for this route\n"         "One or more labels separated by '/'\n")  { -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, NULL, -                            NULL, NULL, argv[7]->arg); +	return zebra_static_ipv4(vty, SAFI_UNICAST, 0, argv[3]->arg, +				 argv[4]->arg, argv[5]->arg, NULL, NULL, NULL, +				 NULL, argv[7]->arg);  }  DEFUN (no_ip_route_mask_tag_label, @@ -428,8 +427,9 @@ DEFUN (no_ip_route_mask_tag_label,         "Specify label(s) for this route\n"         "One or more labels separated by '/'\n")  { -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, argv[7]->arg, -                            NULL, NULL, argv[9]->arg); +	return zebra_static_ipv4(vty, SAFI_UNICAST, 0, argv[3]->arg, +				 argv[4]->arg, argv[5]->arg, NULL, argv[7]->arg, +				 NULL, NULL, argv[9]->arg);  }  DEFUN (no_ip_route_distance_label, @@ -446,8 +446,9 @@ DEFUN (no_ip_route_distance_label,         "Specify label(s) for this route\n"         "One or more labels separated by '/'\n")  { -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL, -                            argv[5]->arg, NULL, argv[7]->arg); +	return zebra_static_ipv4(vty, SAFI_UNICAST, 0, argv[3]->arg, NULL, +				 argv[4]->arg, NULL, NULL, argv[5]->arg, NULL, +				 argv[7]->arg);  }  DEFUN (no_ip_route_tag_distance_label, @@ -466,8 +467,9 @@ DEFUN (no_ip_route_tag_distance_label,         "Specify label(s) for this route\n"         "One or more labels separated by '/'\n")  { -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, argv[6]->arg, -                            argv[7]->arg, NULL, argv[9]->arg); +	return zebra_static_ipv4(vty, SAFI_UNICAST, 0, argv[3]->arg, NULL, +				 argv[4]->arg, NULL, argv[6]->arg, argv[7]->arg, +				 NULL, argv[9]->arg);  }  DEFUN (no_ip_route_mask_distance_label, @@ -485,8 +487,9 @@ DEFUN (no_ip_route_mask_distance_label,         "Specify label(s) for this route\n"         "One or more labels separated by '/'\n")  { -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, NULL, -                            argv[6]->arg, NULL, argv[8]->arg); +	return zebra_static_ipv4(vty, SAFI_UNICAST, 0, argv[3]->arg, +				 argv[4]->arg, argv[5]->arg, NULL, NULL, +				 argv[6]->arg, NULL, argv[8]->arg);  }  DEFUN (no_ip_route_mask_tag_distance_label, @@ -506,8 +509,9 @@ DEFUN (no_ip_route_mask_tag_distance_label,         "Specify label(s) for this route\n"         "One or more labels separated by '/'\n")  { -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, argv[3]->arg, argv[4]->arg, argv[5]->arg, NULL, argv[7]->arg, -                            argv[8]->arg, NULL, argv[10]->arg); +	return zebra_static_ipv4(vty, SAFI_UNICAST, 0, argv[3]->arg, +				 argv[4]->arg, argv[5]->arg, NULL, argv[7]->arg, +				 argv[8]->arg, NULL, argv[10]->arg);  }  DEFUN (ipv6_route_label, @@ -521,7 +525,8 @@ DEFUN (ipv6_route_label,         "Specify label(s) for this route\n"         "One or more labels separated by '/'\n")  { -  return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL, NULL, NULL, NULL, argv[5]->arg); +	return static_ipv6_func(vty, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, +				NULL, NULL, NULL, NULL, argv[5]->arg);  }  DEFUN (ipv6_route_tag_label, @@ -537,7 +542,8 @@ DEFUN (ipv6_route_tag_label,         "Specify label(s) for this route\n"         "One or more labels separated by '/'\n")  { -  return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL, argv[5]->arg, NULL, NULL, argv[7]->arg); +	return static_ipv6_func(vty, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, +				NULL, argv[5]->arg, NULL, NULL, argv[7]->arg);  }  DEFUN (ipv6_route_ifname_label, @@ -551,7 +557,9 @@ DEFUN (ipv6_route_ifname_label,         "Specify label(s) for this route\n"         "One or more labels separated by '/'\n")  { -  return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, argv[4]->arg, NULL, NULL, NULL, NULL, argv[6]->arg); +	return static_ipv6_func(vty, 1, argv[2]->arg, NULL, argv[3]->arg, +				argv[4]->arg, NULL, NULL, NULL, NULL, +				argv[6]->arg);  }  DEFUN (ipv6_route_ifname_tag_label,         ipv6_route_ifname_tag_label_cmd, @@ -566,7 +574,9 @@ DEFUN (ipv6_route_ifname_tag_label,         "Specify label(s) for this route\n"         "One or more labels separated by '/'\n")  { -  return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, argv[4]->arg, NULL, argv[6]->arg, NULL, NULL, argv[8]->arg); +	return static_ipv6_func(vty, 1, argv[2]->arg, NULL, argv[3]->arg, +				argv[4]->arg, NULL, argv[6]->arg, NULL, NULL, +				argv[8]->arg);  }  DEFUN (ipv6_route_pref_label, @@ -581,7 +591,8 @@ DEFUN (ipv6_route_pref_label,         "Specify label(s) for this route\n"         "One or more labels separated by '/'\n")  { -  return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL, NULL, argv[4]->arg, NULL, argv[6]->arg); +	return static_ipv6_func(vty, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, +				NULL, NULL, argv[4]->arg, NULL, argv[6]->arg);  }  DEFUN (ipv6_route_pref_tag_label, @@ -598,7 +609,9 @@ DEFUN (ipv6_route_pref_tag_label,         "Specify label(s) for this route\n"         "One or more labels separated by '/'\n")  { -  return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, NULL, argv[5]->arg, argv[6]->arg, NULL, argv[8]->arg); +	return static_ipv6_func(vty, 1, argv[2]->arg, NULL, argv[3]->arg, NULL, +				NULL, argv[5]->arg, argv[6]->arg, NULL, +				argv[8]->arg);  }  DEFUN (ipv6_route_ifname_pref_label, @@ -613,7 +626,9 @@ DEFUN (ipv6_route_ifname_pref_label,         "Specify label(s) for this route\n"         "One or more labels separated by '/'\n")  { -  return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, argv[4]->arg, NULL, NULL, argv[5]->arg, NULL, argv[7]->arg); +	return static_ipv6_func(vty, 1, argv[2]->arg, NULL, argv[3]->arg, +				argv[4]->arg, NULL, NULL, argv[5]->arg, NULL, +				argv[7]->arg);  }  DEFUN (ipv6_route_ifname_pref_tag_label, @@ -630,7 +645,9 @@ DEFUN (ipv6_route_ifname_pref_tag_label,         "Specify label(s) for this route\n"         "One or more labels separated by '/'\n")  { -  return static_ipv6_func (vty, 1, argv[2]->arg, NULL, argv[3]->arg, argv[4]->arg, NULL, argv[6]->arg, argv[7]->arg, NULL, argv[9]->arg); +	return static_ipv6_func(vty, 1, argv[2]->arg, NULL, argv[3]->arg, +				argv[4]->arg, NULL, argv[6]->arg, argv[7]->arg, +				NULL, argv[9]->arg);  }  DEFUN (no_ipv6_route_label, @@ -645,7 +662,8 @@ DEFUN (no_ipv6_route_label,         "Specify label(s) for this route\n"         "One or more labels separated by '/'\n")  { -  return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL, NULL, NULL, NULL, argv[6]->arg); +	return static_ipv6_func(vty, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, +				NULL, NULL, NULL, NULL, argv[6]->arg);  }  DEFUN (no_ipv6_route_tag_label, @@ -662,7 +680,8 @@ DEFUN (no_ipv6_route_tag_label,         "Specify label(s) for this route\n"         "One or more labels separated by '/'\n")  { -  return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL, argv[6]->arg, NULL, NULL, argv[8]->arg); +	return static_ipv6_func(vty, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, +				NULL, argv[6]->arg, NULL, NULL, argv[8]->arg);  }  DEFUN (no_ipv6_route_ifname_label, @@ -677,7 +696,9 @@ DEFUN (no_ipv6_route_ifname_label,         "Specify label(s) for this route\n"         "One or more labels separated by '/'\n")  { -  return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, argv[5]->arg, NULL, NULL, NULL, NULL, argv[7]->arg); +	return static_ipv6_func(vty, 0, argv[3]->arg, NULL, argv[4]->arg, +				argv[5]->arg, NULL, NULL, NULL, NULL, +				argv[7]->arg);  }  DEFUN (no_ipv6_route_ifname_tag_label, @@ -694,7 +715,9 @@ DEFUN (no_ipv6_route_ifname_tag_label,         "Specify label(s) for this route\n"         "One or more labels separated by '/'\n")  { -  return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, argv[5]->arg, NULL, argv[7]->arg, NULL, NULL, argv[9]->arg); +	return static_ipv6_func(vty, 0, argv[3]->arg, NULL, argv[4]->arg, +				argv[5]->arg, NULL, argv[7]->arg, NULL, NULL, +				argv[9]->arg);  }  DEFUN (no_ipv6_route_pref_label, @@ -710,7 +733,8 @@ DEFUN (no_ipv6_route_pref_label,         "Specify label(s) for this route\n"         "One or more labels separated by '/'\n")  { -  return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL, NULL, argv[5]->arg, NULL, argv[7]->arg); +	return static_ipv6_func(vty, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, +				NULL, NULL, argv[5]->arg, NULL, argv[7]->arg);  }  DEFUN (no_ipv6_route_pref_tag_label, @@ -728,7 +752,9 @@ DEFUN (no_ipv6_route_pref_tag_label,         "Specify label(s) for this route\n"         "One or more labels separated by '/'\n")  { -  return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, NULL, argv[6]->arg, argv[7]->arg, NULL, argv[9]->arg); +	return static_ipv6_func(vty, 0, argv[3]->arg, NULL, argv[4]->arg, NULL, +				NULL, argv[6]->arg, argv[7]->arg, NULL, +				argv[9]->arg);  }  DEFUN (no_ipv6_route_ifname_pref_label, @@ -744,7 +770,9 @@ DEFUN (no_ipv6_route_ifname_pref_label,         "Specify label(s) for this route\n"         "One or more labels separated by '/'\n")  { -  return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, argv[5]->arg, NULL, NULL, argv[6]->arg, NULL, argv[8]->arg); +	return static_ipv6_func(vty, 0, argv[3]->arg, NULL, argv[4]->arg, +				argv[5]->arg, NULL, NULL, argv[6]->arg, NULL, +				argv[8]->arg);  }  DEFUN (no_ipv6_route_ifname_pref_tag_label, @@ -762,22 +790,23 @@ DEFUN (no_ipv6_route_ifname_pref_tag_label,         "Specify label(s) for this route\n"         "One or more labels separated by '/'\n")  { -  return static_ipv6_func (vty, 0, argv[3]->arg, NULL, argv[4]->arg, argv[5]->arg, NULL, argv[7]->arg, argv[8]->arg, NULL, argv[10]->arg); +	return static_ipv6_func(vty, 0, argv[3]->arg, NULL, argv[4]->arg, +				argv[5]->arg, NULL, argv[7]->arg, argv[8]->arg, +				NULL, argv[10]->arg);  }  /* MPLS LSP configuration write function. */ -static int -zebra_mpls_config (struct vty *vty) +static int zebra_mpls_config(struct vty *vty)  { -  int write = 0; -  struct zebra_vrf *zvrf; +	int write = 0; +	struct zebra_vrf *zvrf; -  zvrf = vrf_info_lookup(VRF_DEFAULT); -  if (!zvrf) -    return 0; +	zvrf = vrf_info_lookup(VRF_DEFAULT); +	if (!zvrf) +		return 0; -  write += zebra_mpls_write_lsp_config(vty, zvrf); -  return write; +	write += zebra_mpls_write_lsp_config(vty, zvrf); +	return write;  }  DEFUN (show_mpls_table, @@ -788,12 +817,12 @@ DEFUN (show_mpls_table,         "MPLS table\n"         JSON_STR)  { -  struct zebra_vrf *zvrf; -  u_char uj = use_json (argc, argv); +	struct zebra_vrf *zvrf; +	u_char uj = use_json(argc, argv); -  zvrf = vrf_info_lookup(VRF_DEFAULT); -  zebra_mpls_print_lsp_table(vty, zvrf, uj); -  return CMD_SUCCESS; +	zvrf = vrf_info_lookup(VRF_DEFAULT); +	zebra_mpls_print_lsp_table(vty, zvrf, uj); +	return CMD_SUCCESS;  }  DEFUN (show_mpls_table_lsp, @@ -805,14 +834,14 @@ DEFUN (show_mpls_table_lsp,         "LSP to display information about\n"         JSON_STR)  { -  u_int32_t label; -  struct zebra_vrf *zvrf; -  u_char uj = use_json (argc, argv); +	u_int32_t label; +	struct zebra_vrf *zvrf; +	u_char uj = use_json(argc, argv); -  zvrf = vrf_info_lookup(VRF_DEFAULT); -  label = atoi(argv[3]->arg); -  zebra_mpls_print_lsp (vty, zvrf, label, uj); -  return CMD_SUCCESS; +	zvrf = vrf_info_lookup(VRF_DEFAULT); +	label = atoi(argv[3]->arg); +	zebra_mpls_print_lsp(vty, zvrf, label, uj); +	return CMD_SUCCESS;  }  DEFUN (show_mpls_status, @@ -822,61 +851,62 @@ DEFUN (show_mpls_status,         "MPLS information\n"         "MPLS status\n")  { -  vty_out (vty, "MPLS support enabled: %s%s", (mpls_enabled) ? "yes" : -	   "no (mpls kernel extensions not detected)", VTY_NEWLINE); -  return CMD_SUCCESS; +	vty_out(vty, "MPLS support enabled: %s%s", +		(mpls_enabled) ? "yes" +			       : "no (mpls kernel extensions not detected)", +		VTY_NEWLINE); +	return CMD_SUCCESS;  }  /* MPLS node for MPLS LSP. */ -static struct cmd_node mpls_node = { MPLS_NODE,  "",  1 }; +static struct cmd_node mpls_node = {MPLS_NODE, "", 1};  /* MPLS VTY.  */ -void -zebra_mpls_vty_init (void) -{ -  install_element (VIEW_NODE, &show_mpls_status_cmd); - -  install_node (&mpls_node, zebra_mpls_config); - -  install_element (CONFIG_NODE, &ip_route_label_cmd); -  install_element (CONFIG_NODE, &ip_route_tag_label_cmd); -  install_element (CONFIG_NODE, &ip_route_mask_label_cmd); -  install_element (CONFIG_NODE, &ip_route_mask_tag_label_cmd); -  install_element (CONFIG_NODE, &no_ip_route_label_cmd); -  install_element (CONFIG_NODE, &no_ip_route_tag_label_cmd); -  install_element (CONFIG_NODE, &no_ip_route_mask_label_cmd); -  install_element (CONFIG_NODE, &no_ip_route_mask_tag_label_cmd); -  install_element (CONFIG_NODE, &ip_route_distance_label_cmd); -  install_element (CONFIG_NODE, &ip_route_tag_distance_label_cmd); -  install_element (CONFIG_NODE, &ip_route_mask_distance_label_cmd); -  install_element (CONFIG_NODE, &ip_route_mask_tag_distance_label_cmd); -  install_element (CONFIG_NODE, &no_ip_route_distance_label_cmd); -  install_element (CONFIG_NODE, &no_ip_route_tag_distance_label_cmd); -  install_element (CONFIG_NODE, &no_ip_route_mask_distance_label_cmd); -  install_element (CONFIG_NODE, &no_ip_route_mask_tag_distance_label_cmd); - -  install_element (CONFIG_NODE, &ipv6_route_label_cmd); -  install_element (CONFIG_NODE, &ipv6_route_ifname_label_cmd); -  install_element (CONFIG_NODE, &no_ipv6_route_label_cmd); -  install_element (CONFIG_NODE, &no_ipv6_route_ifname_label_cmd); -  install_element (CONFIG_NODE, &ipv6_route_pref_label_cmd); -  install_element (CONFIG_NODE, &ipv6_route_ifname_pref_label_cmd); -  install_element (CONFIG_NODE, &no_ipv6_route_pref_label_cmd); -  install_element (CONFIG_NODE, &no_ipv6_route_ifname_pref_label_cmd); -  install_element (CONFIG_NODE, &ipv6_route_tag_label_cmd); -  install_element (CONFIG_NODE, &ipv6_route_ifname_tag_label_cmd); -  install_element (CONFIG_NODE, &ipv6_route_pref_tag_label_cmd); -  install_element (CONFIG_NODE, &ipv6_route_ifname_pref_tag_label_cmd); -  install_element (CONFIG_NODE, &no_ipv6_route_tag_label_cmd); -  install_element (CONFIG_NODE, &no_ipv6_route_ifname_tag_label_cmd); -  install_element (CONFIG_NODE, &no_ipv6_route_pref_tag_label_cmd); -  install_element (CONFIG_NODE, &no_ipv6_route_ifname_pref_tag_label_cmd); - -  install_element (CONFIG_NODE, &mpls_transit_lsp_cmd); -  install_element (CONFIG_NODE, &no_mpls_transit_lsp_cmd); -  install_element (CONFIG_NODE, &no_mpls_transit_lsp_out_label_cmd); -  install_element (CONFIG_NODE, &no_mpls_transit_lsp_all_cmd); - -  install_element (VIEW_NODE, &show_mpls_table_cmd); -  install_element (VIEW_NODE, &show_mpls_table_lsp_cmd); +void zebra_mpls_vty_init(void) +{ +	install_element(VIEW_NODE, &show_mpls_status_cmd); + +	install_node(&mpls_node, zebra_mpls_config); + +	install_element(CONFIG_NODE, &ip_route_label_cmd); +	install_element(CONFIG_NODE, &ip_route_tag_label_cmd); +	install_element(CONFIG_NODE, &ip_route_mask_label_cmd); +	install_element(CONFIG_NODE, &ip_route_mask_tag_label_cmd); +	install_element(CONFIG_NODE, &no_ip_route_label_cmd); +	install_element(CONFIG_NODE, &no_ip_route_tag_label_cmd); +	install_element(CONFIG_NODE, &no_ip_route_mask_label_cmd); +	install_element(CONFIG_NODE, &no_ip_route_mask_tag_label_cmd); +	install_element(CONFIG_NODE, &ip_route_distance_label_cmd); +	install_element(CONFIG_NODE, &ip_route_tag_distance_label_cmd); +	install_element(CONFIG_NODE, &ip_route_mask_distance_label_cmd); +	install_element(CONFIG_NODE, &ip_route_mask_tag_distance_label_cmd); +	install_element(CONFIG_NODE, &no_ip_route_distance_label_cmd); +	install_element(CONFIG_NODE, &no_ip_route_tag_distance_label_cmd); +	install_element(CONFIG_NODE, &no_ip_route_mask_distance_label_cmd); +	install_element(CONFIG_NODE, &no_ip_route_mask_tag_distance_label_cmd); + +	install_element(CONFIG_NODE, &ipv6_route_label_cmd); +	install_element(CONFIG_NODE, &ipv6_route_ifname_label_cmd); +	install_element(CONFIG_NODE, &no_ipv6_route_label_cmd); +	install_element(CONFIG_NODE, &no_ipv6_route_ifname_label_cmd); +	install_element(CONFIG_NODE, &ipv6_route_pref_label_cmd); +	install_element(CONFIG_NODE, &ipv6_route_ifname_pref_label_cmd); +	install_element(CONFIG_NODE, &no_ipv6_route_pref_label_cmd); +	install_element(CONFIG_NODE, &no_ipv6_route_ifname_pref_label_cmd); +	install_element(CONFIG_NODE, &ipv6_route_tag_label_cmd); +	install_element(CONFIG_NODE, &ipv6_route_ifname_tag_label_cmd); +	install_element(CONFIG_NODE, &ipv6_route_pref_tag_label_cmd); +	install_element(CONFIG_NODE, &ipv6_route_ifname_pref_tag_label_cmd); +	install_element(CONFIG_NODE, &no_ipv6_route_tag_label_cmd); +	install_element(CONFIG_NODE, &no_ipv6_route_ifname_tag_label_cmd); +	install_element(CONFIG_NODE, &no_ipv6_route_pref_tag_label_cmd); +	install_element(CONFIG_NODE, &no_ipv6_route_ifname_pref_tag_label_cmd); + +	install_element(CONFIG_NODE, &mpls_transit_lsp_cmd); +	install_element(CONFIG_NODE, &no_mpls_transit_lsp_cmd); +	install_element(CONFIG_NODE, &no_mpls_transit_lsp_out_label_cmd); +	install_element(CONFIG_NODE, &no_mpls_transit_lsp_all_cmd); + +	install_element(VIEW_NODE, &show_mpls_table_cmd); +	install_element(VIEW_NODE, &show_mpls_table_lsp_cmd);  } diff --git a/zebra/zebra_mroute.c b/zebra/zebra_mroute.c index 86356104bd..42a10bb894 100644 --- a/zebra/zebra_mroute.c +++ b/zebra/zebra_mroute.c @@ -32,37 +32,37 @@  #include "zebra/zebra_mroute.h"  #include "zebra/rt.h" -int -zebra_ipmr_route_stats (struct zserv *client, int fd, u_short length, struct zebra_vrf *zvrf) +int zebra_ipmr_route_stats(struct zserv *client, int fd, u_short length, +			   struct zebra_vrf *zvrf)  { -  struct mcast_route_data mroute; -  struct stream *s; -  int suc; +	struct mcast_route_data mroute; +	struct stream *s; +	int suc; -  char sbuf[40]; -  char gbuf[40]; +	char sbuf[40]; +	char gbuf[40]; -  memset (&mroute, 0, sizeof (mroute)); -  stream_get (&mroute.sg.src, client->ibuf, 4); -  stream_get (&mroute.sg.grp, client->ibuf, 4); -  mroute.ifindex = stream_getl (client->ibuf); +	memset(&mroute, 0, sizeof(mroute)); +	stream_get(&mroute.sg.src, client->ibuf, 4); +	stream_get(&mroute.sg.grp, client->ibuf, 4); +	mroute.ifindex = stream_getl(client->ibuf); -  strcpy (sbuf, inet_ntoa (mroute.sg.src)); -  strcpy (gbuf, inet_ntoa (mroute.sg.grp)); +	strcpy(sbuf, inet_ntoa(mroute.sg.src)); +	strcpy(gbuf, inet_ntoa(mroute.sg.grp)); -  suc = kernel_get_ipmr_sg_stats (&mroute); +	suc = kernel_get_ipmr_sg_stats(&mroute); -  s = client->obuf; +	s = client->obuf; -  stream_reset (s); +	stream_reset(s); -  zserv_create_header (s, ZEBRA_IPMR_ROUTE_STATS, zvrf_id (zvrf)); -  stream_put_in_addr (s, &mroute.sg.src); -  stream_put_in_addr (s, &mroute.sg.grp); -  stream_put (s, &mroute.lastused, sizeof (mroute.lastused)); -  stream_putl (s, suc); +	zserv_create_header(s, ZEBRA_IPMR_ROUTE_STATS, zvrf_id(zvrf)); +	stream_put_in_addr(s, &mroute.sg.src); +	stream_put_in_addr(s, &mroute.sg.grp); +	stream_put(s, &mroute.lastused, sizeof(mroute.lastused)); +	stream_putl(s, suc); -  stream_putw_at (s, 0, stream_get_endp (s)); -  zebra_server_send_message (client); -  return 0; +	stream_putw_at(s, 0, stream_get_endp(s)); +	zebra_server_send_message(client); +	return 0;  } diff --git a/zebra/zebra_mroute.h b/zebra/zebra_mroute.h index c0bac43a81..b619d50864 100644 --- a/zebra/zebra_mroute.h +++ b/zebra/zebra_mroute.h @@ -24,12 +24,12 @@  #define __ZEBRA_MROUTE_H__  struct mcast_route_data { -  struct prefix_sg sg; -  unsigned int ifindex; -  unsigned long long lastused; +	struct prefix_sg sg; +	unsigned int ifindex; +	unsigned long long lastused;  }; -int zebra_ipmr_route_stats (struct zserv *client, int sock, u_short length, struct zebra_vrf *zvf); +int zebra_ipmr_route_stats(struct zserv *client, int sock, u_short length, +			   struct zebra_vrf *zvf);  #endif - diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c index 642d2700a4..8bab351b6e 100644 --- a/zebra/zebra_ns.c +++ b/zebra/zebra_ns.c @@ -31,58 +31,54 @@  #include "zebra_vrf.h"  #include "zebra_memory.h" -DEFINE_MTYPE(ZEBRA, ZEBRA_NS,       "Zebra Name Space") +DEFINE_MTYPE(ZEBRA, ZEBRA_NS, "Zebra Name Space")  struct zebra_ns *dzns; -struct zebra_ns * -zebra_ns_lookup (ns_id_t ns_id) +struct zebra_ns *zebra_ns_lookup(ns_id_t ns_id)  { -  return dzns; +	return dzns;  } -int -zebra_ns_enable (ns_id_t ns_id, void **info) +int zebra_ns_enable(ns_id_t ns_id, void **info)  { -  struct zebra_ns *zns = (struct zebra_ns *) (*info); +	struct zebra_ns *zns = (struct zebra_ns *)(*info); -#if defined (HAVE_RTADV) -  rtadv_init (zns); +#if defined(HAVE_RTADV) +	rtadv_init(zns);  #endif -  zns->if_table = route_table_init (); -  kernel_init (zns); -  interface_list (zns); -  route_read (zns); +	zns->if_table = route_table_init(); +	kernel_init(zns); +	interface_list(zns); +	route_read(zns); -  return 0; +	return 0;  } -int -zebra_ns_disable (ns_id_t ns_id, void **info) +int zebra_ns_disable(ns_id_t ns_id, void **info)  { -  struct zebra_ns *zns = (struct zebra_ns *) (*info); +	struct zebra_ns *zns = (struct zebra_ns *)(*info); -  route_table_finish (zns->if_table); -#if defined (HAVE_RTADV) -  rtadv_terminate (zns); +	route_table_finish(zns->if_table); +#if defined(HAVE_RTADV) +	rtadv_terminate(zns);  #endif -  kernel_terminate (zns); +	kernel_terminate(zns); -  return 0; +	return 0;  } -int -zebra_ns_init (void) +int zebra_ns_init(void)  { -  dzns = XCALLOC (MTYPE_ZEBRA_NS, sizeof (struct zebra_ns)); +	dzns = XCALLOC(MTYPE_ZEBRA_NS, sizeof(struct zebra_ns)); -  ns_init (); +	ns_init(); -  zebra_vrf_init (); +	zebra_vrf_init(); -  zebra_ns_enable (0, (void **)&dzns); +	zebra_ns_enable(0, (void **)&dzns); -  return 0; +	return 0;  } diff --git a/zebra/zebra_ns.h b/zebra/zebra_ns.h index c50f9249d2..a70095093c 100644 --- a/zebra/zebra_ns.h +++ b/zebra/zebra_ns.h @@ -27,42 +27,40 @@  #ifdef HAVE_NETLINK  /* Socket interface to kernel */ -struct nlsock -{ -  int sock; -  int seq; -  struct sockaddr_nl snl; -  char name[64]; +struct nlsock { +	int sock; +	int seq; +	struct sockaddr_nl snl; +	char name[64];  };  #endif -struct zebra_ns -{ -  /* net-ns name.  */ -  char name[VRF_NAMSIZ]; +struct zebra_ns { +	/* net-ns name.  */ +	char name[VRF_NAMSIZ]; -  /* Identifier. */ -  ns_id_t ns_id; +	/* Identifier. */ +	ns_id_t ns_id;  #ifdef HAVE_NETLINK -  struct nlsock netlink;     /* kernel messages */ -  struct nlsock netlink_cmd; /* command channel */ -  struct thread *t_netlink; +	struct nlsock netlink;     /* kernel messages */ +	struct nlsock netlink_cmd; /* command channel */ +	struct thread *t_netlink;  #endif -  struct route_table *if_table; +	struct route_table *if_table; -#if defined (HAVE_RTADV) -  struct rtadv rtadv; +#if defined(HAVE_RTADV) +	struct rtadv rtadv;  #endif /* HAVE_RTADV */  };  #define NS_DEFAULT 0  #define NS_UNKNOWN UINT16_MAX -struct zebra_ns *zebra_ns_lookup (ns_id_t ns_id); +struct zebra_ns *zebra_ns_lookup(ns_id_t ns_id); -int zebra_ns_init (void); -int zebra_ns_enable (ns_id_t ns_id, void **info); -int zebra_ns_disable (ns_id_t ns_id, void **info); +int zebra_ns_init(void); +int zebra_ns_enable(ns_id_t ns_id, void **info); +int zebra_ns_disable(ns_id_t ns_id, void **info);  #endif diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c index bc924842d4..5889ef49bd 100644 --- a/zebra/zebra_ptm.c +++ b/zebra/zebra_ptm.c @@ -20,7 +20,7 @@   */  #include <zebra.h> -#include <sys/un.h>		/* for sockaddr_un */ +#include <sys/un.h> /* for sockaddr_un */  #include <net/if.h>  #include "vty.h"  #include "zebra/zserv.h" @@ -87,171 +87,170 @@ struct zebra_ptm_cb ptm_cb;  static int zebra_ptm_socket_init(void);  int zebra_ptm_sock_read(struct thread *); -static void zebra_ptm_install_commands (void); +static void zebra_ptm_install_commands(void);  static int zebra_ptm_handle_msg_cb(void *arg, void *in_ctxt); -void zebra_bfd_peer_replay_req (void); +void zebra_bfd_peer_replay_req(void);  void zebra_ptm_send_status_req(void);  void zebra_ptm_reset_status(int ptm_disable);  const char ZEBRA_PTM_SOCK_NAME[] = "\0/var/run/ptmd.socket"; -void -zebra_ptm_init (void) +void zebra_ptm_init(void)  { -  char buf[64]; +	char buf[64]; -  memset(&ptm_cb, 0, sizeof(struct zebra_ptm_cb)); +	memset(&ptm_cb, 0, sizeof(struct zebra_ptm_cb)); -  ptm_cb.out_data = calloc(1, ZEBRA_PTM_SEND_MAX_SOCKBUF); -  if (!ptm_cb.out_data) -    { -      zlog_warn("%s: Allocation of send data failed", __func__); -      return; -    } +	ptm_cb.out_data = calloc(1, ZEBRA_PTM_SEND_MAX_SOCKBUF); +	if (!ptm_cb.out_data) { +		zlog_warn("%s: Allocation of send data failed", __func__); +		return; +	} -  ptm_cb.in_data = calloc(1, ZEBRA_PTM_MAX_SOCKBUF); -  if (!ptm_cb.in_data) -    { -      zlog_warn("%s: Allocation of recv data failed", __func__); -      free(ptm_cb.out_data); -      return; -    } +	ptm_cb.in_data = calloc(1, ZEBRA_PTM_MAX_SOCKBUF); +	if (!ptm_cb.in_data) { +		zlog_warn("%s: Allocation of recv data failed", __func__); +		free(ptm_cb.out_data); +		return; +	} -  ptm_cb.pid = getpid(); -  zebra_ptm_install_commands(); +	ptm_cb.pid = getpid(); +	zebra_ptm_install_commands(); -  sprintf(buf, "%s", FRR_PTM_NAME); -  ptm_hdl = ptm_lib_register(buf, NULL, zebra_ptm_handle_msg_cb, -                                    zebra_ptm_handle_msg_cb); -  ptm_cb.wb = buffer_new(0); +	sprintf(buf, "%s", FRR_PTM_NAME); +	ptm_hdl = ptm_lib_register(buf, NULL, zebra_ptm_handle_msg_cb, +				   zebra_ptm_handle_msg_cb); +	ptm_cb.wb = buffer_new(0); -  ptm_cb.reconnect_time = ZEBRA_PTM_RECONNECT_TIME_INITIAL; +	ptm_cb.reconnect_time = ZEBRA_PTM_RECONNECT_TIME_INITIAL; -  ptm_cb.ptm_sock = -1; +	ptm_cb.ptm_sock = -1;  } -void -zebra_ptm_finish(void) +void zebra_ptm_finish(void)  { -  int proto; +	int proto; -  for (proto = 0; proto < ZEBRA_ROUTE_MAX; proto++) -    if (CHECK_FLAG(ptm_cb.client_flags[proto], ZEBRA_PTM_BFD_CLIENT_FLAG_REG)) -      zebra_ptm_bfd_client_deregister(proto); +	for (proto = 0; proto < ZEBRA_ROUTE_MAX; proto++) +		if (CHECK_FLAG(ptm_cb.client_flags[proto], +			       ZEBRA_PTM_BFD_CLIENT_FLAG_REG)) +			zebra_ptm_bfd_client_deregister(proto); -  buffer_flush_all(ptm_cb.wb, ptm_cb.ptm_sock); +	buffer_flush_all(ptm_cb.wb, ptm_cb.ptm_sock); -  free (ptm_hdl); +	free(ptm_hdl); -  if (ptm_cb.out_data) -    free(ptm_cb.out_data); +	if (ptm_cb.out_data) +		free(ptm_cb.out_data); -  if (ptm_cb.in_data) -    free(ptm_cb.in_data); +	if (ptm_cb.in_data) +		free(ptm_cb.in_data); -  /* Release threads. */ -  if (ptm_cb.t_read) -    thread_cancel (ptm_cb.t_read); -  if (ptm_cb.t_write) -    thread_cancel (ptm_cb.t_write); -  if (ptm_cb.t_timer) -    thread_cancel (ptm_cb.t_timer); +	/* Release threads. */ +	if (ptm_cb.t_read) +		thread_cancel(ptm_cb.t_read); +	if (ptm_cb.t_write) +		thread_cancel(ptm_cb.t_write); +	if (ptm_cb.t_timer) +		thread_cancel(ptm_cb.t_timer); -  if (ptm_cb.wb) -    buffer_free(ptm_cb.wb); +	if (ptm_cb.wb) +		buffer_free(ptm_cb.wb); -  if (ptm_cb.ptm_sock != -1) -    close(ptm_cb.ptm_sock); +	if (ptm_cb.ptm_sock != -1) +		close(ptm_cb.ptm_sock);  } -static int -zebra_ptm_flush_messages (struct thread *thread) +static int zebra_ptm_flush_messages(struct thread *thread)  { -  ptm_cb.t_write = NULL; - -  if (ptm_cb.ptm_sock == -1) -    return -1; - -  errno = 0; - -  switch (buffer_flush_available(ptm_cb.wb, ptm_cb.ptm_sock)) -    { -    case BUFFER_ERROR: -      zlog_warn ("%s ptm socket error: %s", __func__, -                    safe_strerror (errno)); -      close(ptm_cb.ptm_sock); -      ptm_cb.ptm_sock = -1; -      zebra_ptm_reset_status(0); -      ptm_cb.t_timer = thread_add_timer (zebrad.master, zebra_ptm_connect, -                                            NULL, ptm_cb.reconnect_time); -      return (-1); -    case BUFFER_PENDING: -      ptm_cb.t_write = thread_add_write(zebrad.master, zebra_ptm_flush_messages, -                                        NULL, ptm_cb.ptm_sock); -      break; -    case BUFFER_EMPTY: -      break; -    } - -  return(0); +	ptm_cb.t_write = NULL; + +	if (ptm_cb.ptm_sock == -1) +		return -1; + +	errno = 0; + +	switch (buffer_flush_available(ptm_cb.wb, ptm_cb.ptm_sock)) { +	case BUFFER_ERROR: +		zlog_warn("%s ptm socket error: %s", __func__, +			  safe_strerror(errno)); +		close(ptm_cb.ptm_sock); +		ptm_cb.ptm_sock = -1; +		zebra_ptm_reset_status(0); +		ptm_cb.t_timer = +			thread_add_timer(zebrad.master, zebra_ptm_connect, NULL, +					 ptm_cb.reconnect_time); +		return (-1); +	case BUFFER_PENDING: +		ptm_cb.t_write = thread_add_write(zebrad.master, +						  zebra_ptm_flush_messages, +						  NULL, ptm_cb.ptm_sock); +		break; +	case BUFFER_EMPTY: +		break; +	} + +	return (0);  } -static int -zebra_ptm_send_message(char *data, int size) +static int zebra_ptm_send_message(char *data, int size)  { -  errno = 0; -  switch (buffer_write(ptm_cb.wb, ptm_cb.ptm_sock, data, size)) -    { -    case BUFFER_ERROR: -      zlog_warn ("%s ptm socket error: %s", __func__, safe_strerror (errno)); -      close(ptm_cb.ptm_sock); -      ptm_cb.ptm_sock = -1; -      zebra_ptm_reset_status(0); -      ptm_cb.t_timer = thread_add_timer (zebrad.master, zebra_ptm_connect, -                                            NULL, ptm_cb.reconnect_time); -      return -1; -    case BUFFER_EMPTY: -      THREAD_OFF(ptm_cb.t_write); -      break; -    case BUFFER_PENDING: -      THREAD_WRITE_ON(zebrad.master, ptm_cb.t_write, -		      zebra_ptm_flush_messages, NULL, ptm_cb.ptm_sock); -      break; -    } - -  return 0; +	errno = 0; +	switch (buffer_write(ptm_cb.wb, ptm_cb.ptm_sock, data, size)) { +	case BUFFER_ERROR: +		zlog_warn("%s ptm socket error: %s", __func__, +			  safe_strerror(errno)); +		close(ptm_cb.ptm_sock); +		ptm_cb.ptm_sock = -1; +		zebra_ptm_reset_status(0); +		ptm_cb.t_timer = +			thread_add_timer(zebrad.master, zebra_ptm_connect, NULL, +					 ptm_cb.reconnect_time); +		return -1; +	case BUFFER_EMPTY: +		THREAD_OFF(ptm_cb.t_write); +		break; +	case BUFFER_PENDING: +		THREAD_WRITE_ON(zebrad.master, ptm_cb.t_write, +				zebra_ptm_flush_messages, NULL, +				ptm_cb.ptm_sock); +		break; +	} + +	return 0;  } -int -zebra_ptm_connect (struct thread *t) +int zebra_ptm_connect(struct thread *t)  { -  int init = 0; - -  if (ptm_cb.ptm_sock == -1) { -    zebra_ptm_socket_init(); -    init = 1; -  } - -  if (ptm_cb.ptm_sock != -1) { -    if (init) { -      ptm_cb.t_read = thread_add_read (zebrad.master, zebra_ptm_sock_read, -                                      NULL, ptm_cb.ptm_sock); -      zebra_bfd_peer_replay_req(); -    } -    zebra_ptm_send_status_req(); -    ptm_cb.reconnect_time = ZEBRA_PTM_RECONNECT_TIME_INITIAL; -  } else if (ptm_cb.reconnect_time < ZEBRA_PTM_RECONNECT_TIME_MAX){ -    ptm_cb.reconnect_time *= 2; -    if (ptm_cb.reconnect_time > ZEBRA_PTM_RECONNECT_TIME_MAX) -      ptm_cb.reconnect_time = ZEBRA_PTM_RECONNECT_TIME_MAX; - -    ptm_cb.t_timer = thread_add_timer (zebrad.master, zebra_ptm_connect, NULL, +	int init = 0; + +	if (ptm_cb.ptm_sock == -1) { +		zebra_ptm_socket_init(); +		init = 1; +	} + +	if (ptm_cb.ptm_sock != -1) { +		if (init) { +			ptm_cb.t_read = thread_add_read(zebrad.master, +							zebra_ptm_sock_read, +							NULL, ptm_cb.ptm_sock); +			zebra_bfd_peer_replay_req(); +		} +		zebra_ptm_send_status_req(); +		ptm_cb.reconnect_time = ZEBRA_PTM_RECONNECT_TIME_INITIAL; +	} else if (ptm_cb.reconnect_time < ZEBRA_PTM_RECONNECT_TIME_MAX) { +		ptm_cb.reconnect_time *= 2; +		if (ptm_cb.reconnect_time > ZEBRA_PTM_RECONNECT_TIME_MAX) +			ptm_cb.reconnect_time = ZEBRA_PTM_RECONNECT_TIME_MAX; + +		ptm_cb.t_timer = +			thread_add_timer(zebrad.master, zebra_ptm_connect, NULL,  					 ptm_cb.reconnect_time); -  } else if (ptm_cb.reconnect_time >= ZEBRA_PTM_RECONNECT_TIME_MAX){ -    ptm_cb.reconnect_time = ZEBRA_PTM_RECONNECT_TIME_INITIAL; -  } +	} else if (ptm_cb.reconnect_time >= ZEBRA_PTM_RECONNECT_TIME_MAX) { +		ptm_cb.reconnect_time = ZEBRA_PTM_RECONNECT_TIME_INITIAL; +	} -  return(errno); +	return (errno);  }  DEFUN (zebra_ptm_enable, @@ -259,30 +258,28 @@ DEFUN (zebra_ptm_enable,         "ptm-enable",         "Enable neighbor check with specified topology\n")  { -  struct vrf *vrf; -  struct listnode *i; -  struct interface *ifp; -  struct zebra_if *if_data; - -  ptm_cb.ptm_enable = ZEBRA_IF_PTM_ENABLE_ON; - -  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) -    for (ALL_LIST_ELEMENTS_RO (vrf->iflist, i, ifp)) -      if (!ifp->ptm_enable) -        { -          if_data = (struct zebra_if *)ifp->info; -          if (if_data && -               (if_data->ptm_enable == ZEBRA_IF_PTM_ENABLE_UNSPEC)) -            { -              ifp->ptm_enable = ZEBRA_IF_PTM_ENABLE_ON; -            } -          /* Assign a default unknown status */ -          ifp->ptm_status = ZEBRA_PTM_STATUS_UNKNOWN; -        } - -  zebra_ptm_connect(NULL); - -  return CMD_SUCCESS; +	struct vrf *vrf; +	struct listnode *i; +	struct interface *ifp; +	struct zebra_if *if_data; + +	ptm_cb.ptm_enable = ZEBRA_IF_PTM_ENABLE_ON; + +	RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) +	for (ALL_LIST_ELEMENTS_RO(vrf->iflist, i, ifp)) +		if (!ifp->ptm_enable) { +			if_data = (struct zebra_if *)ifp->info; +			if (if_data && (if_data->ptm_enable +					== ZEBRA_IF_PTM_ENABLE_UNSPEC)) { +				ifp->ptm_enable = ZEBRA_IF_PTM_ENABLE_ON; +			} +			/* Assign a default unknown status */ +			ifp->ptm_status = ZEBRA_PTM_STATUS_UNKNOWN; +		} + +	zebra_ptm_connect(NULL); + +	return CMD_SUCCESS;  }  DEFUN (no_zebra_ptm_enable, @@ -291,9 +288,9 @@ DEFUN (no_zebra_ptm_enable,         NO_STR         "Enable neighbor check with specified topology\n")  { -  ptm_cb.ptm_enable = ZEBRA_IF_PTM_ENABLE_OFF; -  zebra_ptm_reset_status(1); -  return CMD_SUCCESS; +	ptm_cb.ptm_enable = ZEBRA_IF_PTM_ENABLE_OFF; +	zebra_ptm_reset_status(1); +	return CMD_SUCCESS;  }  DEFUN (zebra_ptm_enable_if, @@ -301,37 +298,34 @@ DEFUN (zebra_ptm_enable_if,         "ptm-enable",         "Enable neighbor check with specified topology\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); -  struct zebra_if *if_data; -  int old_ptm_enable; -  int send_linkdown = 0; - -  if (ifp->ifindex == IFINDEX_INTERNAL) -    { -      return CMD_SUCCESS; -    } - -  old_ptm_enable = ifp->ptm_enable; -  ifp->ptm_enable = ptm_cb.ptm_enable; - -  if (if_is_no_ptm_operative(ifp)) -    send_linkdown = 1; - -  if (!old_ptm_enable && ptm_cb.ptm_enable) -    { -      if (!if_is_operative (ifp) && send_linkdown) -        { -	  if (IS_ZEBRA_DEBUG_EVENT) -	    zlog_debug ("%s: Bringing down interface %s\n", __func__, -                    ifp->name); -          if_down (ifp); -        } -    } - -  if_data = ifp->info; -  if_data->ptm_enable = ZEBRA_IF_PTM_ENABLE_UNSPEC; - -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *if_data; +	int old_ptm_enable; +	int send_linkdown = 0; + +	if (ifp->ifindex == IFINDEX_INTERNAL) { +		return CMD_SUCCESS; +	} + +	old_ptm_enable = ifp->ptm_enable; +	ifp->ptm_enable = ptm_cb.ptm_enable; + +	if (if_is_no_ptm_operative(ifp)) +		send_linkdown = 1; + +	if (!old_ptm_enable && ptm_cb.ptm_enable) { +		if (!if_is_operative(ifp) && send_linkdown) { +			if (IS_ZEBRA_DEBUG_EVENT) +				zlog_debug("%s: Bringing down interface %s\n", +					   __func__, ifp->name); +			if_down(ifp); +		} +	} + +	if_data = ifp->info; +	if_data->ptm_enable = ZEBRA_IF_PTM_ENABLE_UNSPEC; + +	return CMD_SUCCESS;  }  DEFUN (no_zebra_ptm_enable_if, @@ -340,227 +334,224 @@ DEFUN (no_zebra_ptm_enable_if,         NO_STR         "Enable neighbor check with specified topology\n")  { -  VTY_DECLVAR_CONTEXT (interface, ifp); -  int send_linkup = 0; -  struct zebra_if *if_data; - -  if ((ifp->ifindex != IFINDEX_INTERNAL) && (ifp->ptm_enable)) -    { -      if (!if_is_operative(ifp)) -        send_linkup = 1; - -      ifp->ptm_enable = ZEBRA_IF_PTM_ENABLE_OFF; -      if (if_is_no_ptm_operative (ifp) && send_linkup) -        { -	  if (IS_ZEBRA_DEBUG_EVENT) -	    zlog_debug ("%s: Bringing up interface %s\n", __func__, -                    ifp->name); -          if_up (ifp); -        } -    } - -  if_data = ifp->info; -  if_data->ptm_enable = ZEBRA_IF_PTM_ENABLE_OFF; - -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(interface, ifp); +	int send_linkup = 0; +	struct zebra_if *if_data; + +	if ((ifp->ifindex != IFINDEX_INTERNAL) && (ifp->ptm_enable)) { +		if (!if_is_operative(ifp)) +			send_linkup = 1; + +		ifp->ptm_enable = ZEBRA_IF_PTM_ENABLE_OFF; +		if (if_is_no_ptm_operative(ifp) && send_linkup) { +			if (IS_ZEBRA_DEBUG_EVENT) +				zlog_debug("%s: Bringing up interface %s\n", +					   __func__, ifp->name); +			if_up(ifp); +		} +	} + +	if_data = ifp->info; +	if_data->ptm_enable = ZEBRA_IF_PTM_ENABLE_OFF; + +	return CMD_SUCCESS;  } -void -zebra_ptm_write (struct vty *vty) +void zebra_ptm_write(struct vty *vty)  { -  if (ptm_cb.ptm_enable) -    vty_out (vty, "ptm-enable%s", VTY_NEWLINE); +	if (ptm_cb.ptm_enable) +		vty_out(vty, "ptm-enable%s", VTY_NEWLINE); -  return; +	return;  } -static int -zebra_ptm_socket_init (void) +static int zebra_ptm_socket_init(void)  { -  int ret; -  int sock; -  struct sockaddr_un addr; - -  ptm_cb.ptm_sock = -1; - -  sock = socket (PF_UNIX, SOCK_STREAM, 0); -  if (sock < 0) -    return -1; -  if (set_nonblocking(sock) < 0) -    { -      if (IS_ZEBRA_DEBUG_EVENT) -        zlog_debug ("%s: Unable to set socket non blocking[%s]", -                    __PRETTY_FUNCTION__, safe_strerror (errno)); -      close (sock); -      return -1; -    } - -  /* Make server socket. */ -  memset (&addr, 0, sizeof (struct sockaddr_un)); -  addr.sun_family = AF_UNIX; -  memcpy (&addr.sun_path, ZEBRA_PTM_SOCK_NAME, -	  sizeof(ZEBRA_PTM_SOCK_NAME)); - -  ret = connect(sock, (struct sockaddr *) &addr, -                sizeof (addr.sun_family)+sizeof (ZEBRA_PTM_SOCK_NAME)-1); -  if (ret < 0) -    { -      if (IS_ZEBRA_DEBUG_EVENT) -        zlog_debug("%s: Unable to connect to socket %s [%s]", -	              __func__, ZEBRA_PTM_SOCK_NAME, safe_strerror(errno)); -      close (sock); -      return -1; -    } -  ptm_cb.ptm_sock = sock; -  return sock; +	int ret; +	int sock; +	struct sockaddr_un addr; + +	ptm_cb.ptm_sock = -1; + +	sock = socket(PF_UNIX, SOCK_STREAM, 0); +	if (sock < 0) +		return -1; +	if (set_nonblocking(sock) < 0) { +		if (IS_ZEBRA_DEBUG_EVENT) +			zlog_debug("%s: Unable to set socket non blocking[%s]", +				   __PRETTY_FUNCTION__, safe_strerror(errno)); +		close(sock); +		return -1; +	} + +	/* Make server socket. */ +	memset(&addr, 0, sizeof(struct sockaddr_un)); +	addr.sun_family = AF_UNIX; +	memcpy(&addr.sun_path, ZEBRA_PTM_SOCK_NAME, +	       sizeof(ZEBRA_PTM_SOCK_NAME)); + +	ret = connect(sock, (struct sockaddr *)&addr, +		      sizeof(addr.sun_family) + sizeof(ZEBRA_PTM_SOCK_NAME) +			      - 1); +	if (ret < 0) { +		if (IS_ZEBRA_DEBUG_EVENT) +			zlog_debug("%s: Unable to connect to socket %s [%s]", +				   __func__, ZEBRA_PTM_SOCK_NAME, +				   safe_strerror(errno)); +		close(sock); +		return -1; +	} +	ptm_cb.ptm_sock = sock; +	return sock;  } -static void -zebra_ptm_install_commands (void) +static void zebra_ptm_install_commands(void)  { -  install_element (CONFIG_NODE, &zebra_ptm_enable_cmd); -  install_element (CONFIG_NODE, &no_zebra_ptm_enable_cmd); -  install_element (INTERFACE_NODE, &zebra_ptm_enable_if_cmd); -  install_element (INTERFACE_NODE, &no_zebra_ptm_enable_if_cmd); +	install_element(CONFIG_NODE, &zebra_ptm_enable_cmd); +	install_element(CONFIG_NODE, &no_zebra_ptm_enable_cmd); +	install_element(INTERFACE_NODE, &zebra_ptm_enable_if_cmd); +	install_element(INTERFACE_NODE, &no_zebra_ptm_enable_if_cmd);  }  /* BFD session goes down, send message to the protocols. */ -static void -if_bfd_session_update (struct interface *ifp, struct prefix *dp, -                      struct prefix *sp, int status, vrf_id_t vrf_id) +static void if_bfd_session_update(struct interface *ifp, struct prefix *dp, +				  struct prefix *sp, int status, +				  vrf_id_t vrf_id)  { -  if (IS_ZEBRA_DEBUG_EVENT) -    { -      char buf[2][INET6_ADDRSTRLEN]; - -      if (ifp) -        { -          zlog_debug ("MESSAGE: ZEBRA_INTERFACE_BFD_DEST_UPDATE %s/%d on %s" -                      " %s event", -                        inet_ntop (dp->family, &dp->u.prefix, buf[0], -                              INET6_ADDRSTRLEN), dp->prefixlen, ifp->name, -                        bfd_get_status_str(status)); -        } -      else -        { -          zlog_debug ("MESSAGE: ZEBRA_INTERFACE_BFD_DEST_UPDATE %s/%d " -                      "with src %s/%d and vrf %d %s event", -                  inet_ntop (dp->family, &dp->u.prefix, buf[0], INET6_ADDRSTRLEN), -                  dp->prefixlen, -                  inet_ntop (sp->family, &sp->u.prefix, buf[1], INET6_ADDRSTRLEN), -                  sp->prefixlen, vrf_id, bfd_get_status_str(status)); -        } -    } - -  zebra_interface_bfd_update (ifp, dp, sp, status, vrf_id); +	if (IS_ZEBRA_DEBUG_EVENT) { +		char buf[2][INET6_ADDRSTRLEN]; + +		if (ifp) { +			zlog_debug( +				"MESSAGE: ZEBRA_INTERFACE_BFD_DEST_UPDATE %s/%d on %s" +				" %s event", +				inet_ntop(dp->family, &dp->u.prefix, buf[0], +					  INET6_ADDRSTRLEN), +				dp->prefixlen, ifp->name, +				bfd_get_status_str(status)); +		} else { +			zlog_debug( +				"MESSAGE: ZEBRA_INTERFACE_BFD_DEST_UPDATE %s/%d " +				"with src %s/%d and vrf %d %s event", +				inet_ntop(dp->family, &dp->u.prefix, buf[0], +					  INET6_ADDRSTRLEN), +				dp->prefixlen, +				inet_ntop(sp->family, &sp->u.prefix, buf[1], +					  INET6_ADDRSTRLEN), +				sp->prefixlen, vrf_id, +				bfd_get_status_str(status)); +		} +	} + +	zebra_interface_bfd_update(ifp, dp, sp, status, vrf_id);  } -static int -zebra_ptm_handle_bfd_msg(void *arg, void *in_ctxt, struct interface *ifp) +static int zebra_ptm_handle_bfd_msg(void *arg, void *in_ctxt, +				    struct interface *ifp)  { -  char bfdst_str[32]; -  char dest_str[64]; -  char src_str[64]; -  char vrf_str[64]; -  struct prefix dest_prefix; -  struct prefix src_prefix; -  vrf_id_t vrf_id; - -  ptm_lib_find_key_in_msg(in_ctxt, ZEBRA_PTM_BFDSTATUS_STR, bfdst_str); - -  if (bfdst_str[0] == '\0') { -    return -1; -  } - -  ptm_lib_find_key_in_msg(in_ctxt, ZEBRA_PTM_BFDDEST_STR, dest_str); - -  if (dest_str[0] == '\0') { -    zlog_debug("%s: Key %s not found in PTM msg", __func__, -               ZEBRA_PTM_BFDDEST_STR); -    return -1; -  } - -  ptm_lib_find_key_in_msg(in_ctxt, ZEBRA_PTM_BFDSRC_STR, src_str); - -  if (src_str[0] == '\0') { -    zlog_debug("%s: Key %s not found in PTM msg", __func__, -               ZEBRA_PTM_BFDSRC_STR); -    return -1; -  } - -  ptm_lib_find_key_in_msg(in_ctxt, ZEBRA_PTM_BFDVRF_STR, vrf_str); - -  if (vrf_str[0] == '\0') { -    zlog_debug("%s: Key %s not found in PTM msg", __func__, -               ZEBRA_PTM_BFDVRF_STR); -    return -1; -  } - -  if (IS_ZEBRA_DEBUG_EVENT) -    zlog_debug("%s: Recv Port [%s] bfd status [%s] vrf [%s]" -                  " peer [%s] local [%s]", -                  __func__, ifp ? ifp->name : "N/A", bfdst_str, -                  vrf_str, dest_str, src_str); - -  if (str2prefix(dest_str, &dest_prefix) == 0) { -      zlog_err("%s: Peer addr %s not found", __func__, -         dest_str); -      return -1; -  } - -  memset(&src_prefix, 0, sizeof(struct prefix)); -  if (strcmp(ZEBRA_PTM_INVALID_SRC_IP, src_str)) { -    if (str2prefix(src_str, &src_prefix) == 0) { -        zlog_err("%s: Local addr %s not found", __func__, -           src_str); -        return -1; -    } -  } - -  if (!strcmp(ZEBRA_PTM_INVALID_VRF, vrf_str) && ifp) { -    vrf_id = ifp->vrf_id; -  } else { -    vrf_id = vrf_name_to_id(vrf_str); -  } - -  if (!strcmp (bfdst_str, ZEBRA_PTM_BFDSTATUS_DOWN_STR)) { -    if_bfd_session_update(ifp, &dest_prefix, &src_prefix, BFD_STATUS_DOWN, -                            vrf_id); -  } else { -    if_bfd_session_update(ifp, &dest_prefix, &src_prefix, BFD_STATUS_UP, -                            vrf_id); -  } - -  return 0; +	char bfdst_str[32]; +	char dest_str[64]; +	char src_str[64]; +	char vrf_str[64]; +	struct prefix dest_prefix; +	struct prefix src_prefix; +	vrf_id_t vrf_id; + +	ptm_lib_find_key_in_msg(in_ctxt, ZEBRA_PTM_BFDSTATUS_STR, bfdst_str); + +	if (bfdst_str[0] == '\0') { +		return -1; +	} + +	ptm_lib_find_key_in_msg(in_ctxt, ZEBRA_PTM_BFDDEST_STR, dest_str); + +	if (dest_str[0] == '\0') { +		zlog_debug("%s: Key %s not found in PTM msg", __func__, +			   ZEBRA_PTM_BFDDEST_STR); +		return -1; +	} + +	ptm_lib_find_key_in_msg(in_ctxt, ZEBRA_PTM_BFDSRC_STR, src_str); + +	if (src_str[0] == '\0') { +		zlog_debug("%s: Key %s not found in PTM msg", __func__, +			   ZEBRA_PTM_BFDSRC_STR); +		return -1; +	} + +	ptm_lib_find_key_in_msg(in_ctxt, ZEBRA_PTM_BFDVRF_STR, vrf_str); + +	if (vrf_str[0] == '\0') { +		zlog_debug("%s: Key %s not found in PTM msg", __func__, +			   ZEBRA_PTM_BFDVRF_STR); +		return -1; +	} + +	if (IS_ZEBRA_DEBUG_EVENT) +		zlog_debug( +			"%s: Recv Port [%s] bfd status [%s] vrf [%s]" +			" peer [%s] local [%s]", +			__func__, ifp ? ifp->name : "N/A", bfdst_str, vrf_str, +			dest_str, src_str); + +	if (str2prefix(dest_str, &dest_prefix) == 0) { +		zlog_err("%s: Peer addr %s not found", __func__, dest_str); +		return -1; +	} + +	memset(&src_prefix, 0, sizeof(struct prefix)); +	if (strcmp(ZEBRA_PTM_INVALID_SRC_IP, src_str)) { +		if (str2prefix(src_str, &src_prefix) == 0) { +			zlog_err("%s: Local addr %s not found", __func__, +				 src_str); +			return -1; +		} +	} + +	if (!strcmp(ZEBRA_PTM_INVALID_VRF, vrf_str) && ifp) { +		vrf_id = ifp->vrf_id; +	} else { +		vrf_id = vrf_name_to_id(vrf_str); +	} + +	if (!strcmp(bfdst_str, ZEBRA_PTM_BFDSTATUS_DOWN_STR)) { +		if_bfd_session_update(ifp, &dest_prefix, &src_prefix, +				      BFD_STATUS_DOWN, vrf_id); +	} else { +		if_bfd_session_update(ifp, &dest_prefix, &src_prefix, +				      BFD_STATUS_UP, vrf_id); +	} + +	return 0;  } -static int -zebra_ptm_handle_cbl_msg(void *arg, void *in_ctxt, struct interface *ifp, -                         char *cbl_str) +static int zebra_ptm_handle_cbl_msg(void *arg, void *in_ctxt, +				    struct interface *ifp, char *cbl_str)  { -  int send_linkup = 0; - -  if (IS_ZEBRA_DEBUG_EVENT) -    zlog_debug("%s: Recv Port [%s] cbl status [%s]", __func__, -             ifp->name, cbl_str); - -  if (!strcmp(cbl_str, ZEBRA_PTM_PASS_STR) && -              (ifp->ptm_status != ZEBRA_PTM_STATUS_UP)) { - -    if (ifp->ptm_status == ZEBRA_PTM_STATUS_DOWN) -      send_linkup = 1; -    ifp->ptm_status = ZEBRA_PTM_STATUS_UP; -    if (ifp->ptm_enable && if_is_no_ptm_operative (ifp) && send_linkup) -      if_up (ifp); -  } else if (!strcmp (cbl_str, ZEBRA_PTM_FAIL_STR) && -              (ifp->ptm_status != ZEBRA_PTM_STATUS_DOWN)) { -    ifp->ptm_status = ZEBRA_PTM_STATUS_DOWN; -    if (ifp->ptm_enable && if_is_no_ptm_operative (ifp)) -      if_down (ifp); -  } - -  return 0; +	int send_linkup = 0; + +	if (IS_ZEBRA_DEBUG_EVENT) +		zlog_debug("%s: Recv Port [%s] cbl status [%s]", __func__, +			   ifp->name, cbl_str); + +	if (!strcmp(cbl_str, ZEBRA_PTM_PASS_STR) +	    && (ifp->ptm_status != ZEBRA_PTM_STATUS_UP)) { + +		if (ifp->ptm_status == ZEBRA_PTM_STATUS_DOWN) +			send_linkup = 1; +		ifp->ptm_status = ZEBRA_PTM_STATUS_UP; +		if (ifp->ptm_enable && if_is_no_ptm_operative(ifp) +		    && send_linkup) +			if_up(ifp); +	} else if (!strcmp(cbl_str, ZEBRA_PTM_FAIL_STR) +		   && (ifp->ptm_status != ZEBRA_PTM_STATUS_DOWN)) { +		ifp->ptm_status = ZEBRA_PTM_STATUS_DOWN; +		if (ifp->ptm_enable && if_is_no_ptm_operative(ifp)) +			if_down(ifp); +	} + +	return 0;  }  /* @@ -580,577 +571,562 @@ zebra_ptm_handle_cbl_msg(void *arg, void *in_ctxt, struct interface *ifp,   *  processing all the notifications from the PTM.   *   */ -static int -zebra_ptm_handle_msg_cb(void *arg, void *in_ctxt) +static int zebra_ptm_handle_msg_cb(void *arg, void *in_ctxt)  { -  struct interface *ifp = NULL; -  char port_str[128]; -  char cbl_str[32]; -  char cmd_status_str[32]; - -  ptm_lib_find_key_in_msg(in_ctxt, ZEBRA_PTM_CMD_STATUS_STR, cmd_status_str); - -  /* Drop command response messages */ -  if (cmd_status_str[0] != '\0') { -    return 0; -  } - -  ptm_lib_find_key_in_msg(in_ctxt, ZEBRA_PTM_PORT_STR, port_str); - -  if (port_str[0] == '\0') { -    zlog_debug("%s: Key %s not found in PTM msg", __func__, -               ZEBRA_PTM_PORT_STR); -    return -1; -  } - -  if (strcmp(ZEBRA_PTM_INVALID_PORT_NAME, port_str)) { -    ifp = if_lookup_by_name_all_vrf(port_str); - -    if (!ifp) { -      zlog_err("%s: %s not found in interface list", __func__, port_str); -      return -1; -    } -  } - -  ptm_lib_find_key_in_msg(in_ctxt, ZEBRA_PTM_CBL_STR, cbl_str); - -  if (cbl_str[0] == '\0') { -    return zebra_ptm_handle_bfd_msg(arg, in_ctxt, ifp); -  } else { -    if (ifp) { -      return zebra_ptm_handle_cbl_msg(arg, in_ctxt, ifp, cbl_str); -    } else { -      return -1; -    } -  } +	struct interface *ifp = NULL; +	char port_str[128]; +	char cbl_str[32]; +	char cmd_status_str[32]; + +	ptm_lib_find_key_in_msg(in_ctxt, ZEBRA_PTM_CMD_STATUS_STR, +				cmd_status_str); + +	/* Drop command response messages */ +	if (cmd_status_str[0] != '\0') { +		return 0; +	} + +	ptm_lib_find_key_in_msg(in_ctxt, ZEBRA_PTM_PORT_STR, port_str); + +	if (port_str[0] == '\0') { +		zlog_debug("%s: Key %s not found in PTM msg", __func__, +			   ZEBRA_PTM_PORT_STR); +		return -1; +	} + +	if (strcmp(ZEBRA_PTM_INVALID_PORT_NAME, port_str)) { +		ifp = if_lookup_by_name_all_vrf(port_str); + +		if (!ifp) { +			zlog_err("%s: %s not found in interface list", __func__, +				 port_str); +			return -1; +		} +	} + +	ptm_lib_find_key_in_msg(in_ctxt, ZEBRA_PTM_CBL_STR, cbl_str); + +	if (cbl_str[0] == '\0') { +		return zebra_ptm_handle_bfd_msg(arg, in_ctxt, ifp); +	} else { +		if (ifp) { +			return zebra_ptm_handle_cbl_msg(arg, in_ctxt, ifp, +							cbl_str); +		} else { +			return -1; +		} +	}  } -int -zebra_ptm_sock_read (struct thread *thread) +int zebra_ptm_sock_read(struct thread *thread)  { -  int sock, done = 0; -  int rc; - -  errno = 0; -  sock = THREAD_FD (thread); - -  if (sock == -1) -    return -1; - -  /* PTM communicates in CSV format */ -  while(!done) { -    rc = ptm_lib_process_msg(ptm_hdl, sock, ptm_cb.in_data, ZEBRA_PTM_MAX_SOCKBUF, -                                NULL); -    if (rc <= 0) -      break; -  } - -  if (rc <= 0) { -    if (((rc == 0) && !errno) || (errno  && (errno != EWOULDBLOCK) && (errno != EAGAIN))) { -      zlog_warn ("%s routing socket error: %s(%d) bytes %d", __func__, -                    safe_strerror (errno), errno, rc); - -      close (ptm_cb.ptm_sock); -      ptm_cb.ptm_sock = -1; -      zebra_ptm_reset_status(0); -      ptm_cb.t_timer = thread_add_timer (zebrad.master, zebra_ptm_connect, -                                         NULL, ptm_cb.reconnect_time); -      return (-1); -    } -  } - -  ptm_cb.t_read = thread_add_read (zebrad.master, zebra_ptm_sock_read, -                                  NULL, ptm_cb.ptm_sock); - -  return 0; +	int sock, done = 0; +	int rc; + +	errno = 0; +	sock = THREAD_FD(thread); + +	if (sock == -1) +		return -1; + +	/* PTM communicates in CSV format */ +	while (!done) { +		rc = ptm_lib_process_msg(ptm_hdl, sock, ptm_cb.in_data, +					 ZEBRA_PTM_MAX_SOCKBUF, NULL); +		if (rc <= 0) +			break; +	} + +	if (rc <= 0) { +		if (((rc == 0) && !errno) +		    || (errno && (errno != EWOULDBLOCK) && (errno != EAGAIN))) { +			zlog_warn("%s routing socket error: %s(%d) bytes %d", +				  __func__, safe_strerror(errno), errno, rc); + +			close(ptm_cb.ptm_sock); +			ptm_cb.ptm_sock = -1; +			zebra_ptm_reset_status(0); +			ptm_cb.t_timer = thread_add_timer( +				zebrad.master, zebra_ptm_connect, NULL, +				ptm_cb.reconnect_time); +			return (-1); +		} +	} + +	ptm_cb.t_read = thread_add_read(zebrad.master, zebra_ptm_sock_read, +					NULL, ptm_cb.ptm_sock); + +	return 0;  }  /* BFD peer/dst register/update */ -int -zebra_ptm_bfd_dst_register (struct zserv *client, int sock, u_short length, -			    int command, struct zebra_vrf *zvrf) +int zebra_ptm_bfd_dst_register(struct zserv *client, int sock, u_short length, +			       int command, struct zebra_vrf *zvrf)  { -  struct stream *s; -  struct prefix src_p; -  struct prefix dst_p; -  u_char multi_hop; -  u_char multi_hop_cnt; -  u_char detect_mul; -  unsigned int min_rx_timer; -  unsigned int min_tx_timer; -  char if_name[INTERFACE_NAMSIZ]; -  u_char len; -  void *out_ctxt; -  char buf[INET6_ADDRSTRLEN]; -  char tmp_buf[64]; -  int data_len = ZEBRA_PTM_SEND_MAX_SOCKBUF; -  unsigned int pid; - -  if (command == ZEBRA_BFD_DEST_UPDATE) -    client->bfd_peer_upd8_cnt++; -  else -    client->bfd_peer_add_cnt++; - -  if (IS_ZEBRA_DEBUG_EVENT) -    zlog_debug("bfd_dst_register msg from client %s: length=%d", -                zebra_route_string(client->proto), length); - -  if (ptm_cb.ptm_sock == -1) -    { -      ptm_cb.t_timer = thread_add_timer (zebrad.master, zebra_ptm_connect, -                                             NULL, ptm_cb.reconnect_time); -      return -1; -    } - -  ptm_lib_init_msg(ptm_hdl, 0, PTMLIB_MSG_TYPE_CMD, NULL, &out_ctxt); -  sprintf(tmp_buf, "%s", ZEBRA_PTM_BFD_START_CMD); -  ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_CMD_STR, tmp_buf); -  sprintf(tmp_buf, "%s", zebra_route_string(client->proto)); -  ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_CLIENT_FIELD, -                      tmp_buf); - -  s = client->ibuf; - -  pid = stream_getl(s); -  sprintf(tmp_buf, "%d", pid); -  ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_SEQID_FIELD, tmp_buf); - -  dst_p.family = stream_getw(s); - -  if (dst_p.family == AF_INET) -    dst_p.prefixlen = IPV4_MAX_BYTELEN; -  else -    dst_p.prefixlen = IPV6_MAX_BYTELEN; - -  stream_get(&dst_p.u.prefix, s, dst_p.prefixlen); -  if (dst_p.family == AF_INET) -    { -      inet_ntop(AF_INET, &dst_p.u.prefix4, buf, sizeof(buf)); -      ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_DST_IP_FIELD, buf); -    } -  else -    { -      inet_ntop(AF_INET6, &dst_p.u.prefix6, buf, sizeof(buf)); -      ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_DST_IP_FIELD, buf); -    } - -  min_rx_timer = stream_getl(s); -  sprintf(tmp_buf, "%d", min_rx_timer); -  ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_MIN_RX_FIELD, -                      tmp_buf); -  min_tx_timer = stream_getl(s); -  sprintf(tmp_buf, "%d", min_tx_timer); -  ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_MIN_TX_FIELD, -                      tmp_buf); -  detect_mul = stream_getc(s); -  sprintf(tmp_buf, "%d", detect_mul); -  ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_DETECT_MULT_FIELD, -                      tmp_buf); - -  multi_hop = stream_getc(s); -  if (multi_hop) -    { -      sprintf(tmp_buf, "%d", 1); -      ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_MULTI_HOP_FIELD, -                          tmp_buf); -      src_p.family = stream_getw(s); - -      if (src_p.family == AF_INET) -        src_p.prefixlen = IPV4_MAX_BYTELEN; -      else -        src_p.prefixlen = IPV6_MAX_BYTELEN; - -      stream_get(&src_p.u.prefix, s, src_p.prefixlen); -      if (src_p.family == AF_INET) -        { -          inet_ntop(AF_INET, &src_p.u.prefix4, buf, sizeof(buf)); -          ptm_lib_append_msg(ptm_hdl, out_ctxt, -                              ZEBRA_PTM_BFD_SRC_IP_FIELD, buf); -        } -      else -        { -          inet_ntop(AF_INET6, &src_p.u.prefix6, buf, sizeof(buf)); -          ptm_lib_append_msg(ptm_hdl, out_ctxt, -                              ZEBRA_PTM_BFD_SRC_IP_FIELD, buf); -        } - -      multi_hop_cnt = stream_getc(s); -      sprintf(tmp_buf, "%d", multi_hop_cnt); -      ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_MAX_HOP_CNT_FIELD, -                          tmp_buf); - -      if (zvrf_id (zvrf) != VRF_DEFAULT) -	ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_VRF_NAME_FIELD, -			   zvrf_name (zvrf)); -    } -  else -    { -      if (dst_p.family == AF_INET6) -        { -          src_p.family = stream_getw(s); - -          if (src_p.family == AF_INET) -            src_p.prefixlen = IPV4_MAX_BYTELEN; -          else -            src_p.prefixlen = IPV6_MAX_BYTELEN; - -          stream_get(&src_p.u.prefix, s, src_p.prefixlen); -          if (src_p.family == AF_INET) -            { -              inet_ntop(AF_INET, &src_p.u.prefix4, buf, sizeof(buf)); -              ptm_lib_append_msg(ptm_hdl, out_ctxt, -                                  ZEBRA_PTM_BFD_SRC_IP_FIELD, buf); -            } -          else -            { -              inet_ntop(AF_INET6, &src_p.u.prefix6, buf, sizeof(buf)); -              ptm_lib_append_msg(ptm_hdl, out_ctxt, -                                  ZEBRA_PTM_BFD_SRC_IP_FIELD, buf); -            } -        } -      len = stream_getc(s); -      stream_get(if_name, s, len); -      if_name[len] = '\0'; - -      ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_IFNAME_FIELD, -                          if_name); -    } - -  sprintf(tmp_buf, "%d", 1); -  ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_SEND_EVENT, -                      tmp_buf); - -  ptm_lib_complete_msg(ptm_hdl, out_ctxt, ptm_cb.out_data, &data_len); - -  if (IS_ZEBRA_DEBUG_SEND) -    zlog_debug ("%s: Sent message (%d) %s", __func__, data_len, -                  ptm_cb.out_data); -  zebra_ptm_send_message(ptm_cb.out_data, data_len); -  return 0; +	struct stream *s; +	struct prefix src_p; +	struct prefix dst_p; +	u_char multi_hop; +	u_char multi_hop_cnt; +	u_char detect_mul; +	unsigned int min_rx_timer; +	unsigned int min_tx_timer; +	char if_name[INTERFACE_NAMSIZ]; +	u_char len; +	void *out_ctxt; +	char buf[INET6_ADDRSTRLEN]; +	char tmp_buf[64]; +	int data_len = ZEBRA_PTM_SEND_MAX_SOCKBUF; +	unsigned int pid; + +	if (command == ZEBRA_BFD_DEST_UPDATE) +		client->bfd_peer_upd8_cnt++; +	else +		client->bfd_peer_add_cnt++; + +	if (IS_ZEBRA_DEBUG_EVENT) +		zlog_debug("bfd_dst_register msg from client %s: length=%d", +			   zebra_route_string(client->proto), length); + +	if (ptm_cb.ptm_sock == -1) { +		ptm_cb.t_timer = +			thread_add_timer(zebrad.master, zebra_ptm_connect, NULL, +					 ptm_cb.reconnect_time); +		return -1; +	} + +	ptm_lib_init_msg(ptm_hdl, 0, PTMLIB_MSG_TYPE_CMD, NULL, &out_ctxt); +	sprintf(tmp_buf, "%s", ZEBRA_PTM_BFD_START_CMD); +	ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_CMD_STR, tmp_buf); +	sprintf(tmp_buf, "%s", zebra_route_string(client->proto)); +	ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_CLIENT_FIELD, +			   tmp_buf); + +	s = client->ibuf; + +	pid = stream_getl(s); +	sprintf(tmp_buf, "%d", pid); +	ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_SEQID_FIELD, +			   tmp_buf); + +	dst_p.family = stream_getw(s); + +	if (dst_p.family == AF_INET) +		dst_p.prefixlen = IPV4_MAX_BYTELEN; +	else +		dst_p.prefixlen = IPV6_MAX_BYTELEN; + +	stream_get(&dst_p.u.prefix, s, dst_p.prefixlen); +	if (dst_p.family == AF_INET) { +		inet_ntop(AF_INET, &dst_p.u.prefix4, buf, sizeof(buf)); +		ptm_lib_append_msg(ptm_hdl, out_ctxt, +				   ZEBRA_PTM_BFD_DST_IP_FIELD, buf); +	} else { +		inet_ntop(AF_INET6, &dst_p.u.prefix6, buf, sizeof(buf)); +		ptm_lib_append_msg(ptm_hdl, out_ctxt, +				   ZEBRA_PTM_BFD_DST_IP_FIELD, buf); +	} + +	min_rx_timer = stream_getl(s); +	sprintf(tmp_buf, "%d", min_rx_timer); +	ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_MIN_RX_FIELD, +			   tmp_buf); +	min_tx_timer = stream_getl(s); +	sprintf(tmp_buf, "%d", min_tx_timer); +	ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_MIN_TX_FIELD, +			   tmp_buf); +	detect_mul = stream_getc(s); +	sprintf(tmp_buf, "%d", detect_mul); +	ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_DETECT_MULT_FIELD, +			   tmp_buf); + +	multi_hop = stream_getc(s); +	if (multi_hop) { +		sprintf(tmp_buf, "%d", 1); +		ptm_lib_append_msg(ptm_hdl, out_ctxt, +				   ZEBRA_PTM_BFD_MULTI_HOP_FIELD, tmp_buf); +		src_p.family = stream_getw(s); + +		if (src_p.family == AF_INET) +			src_p.prefixlen = IPV4_MAX_BYTELEN; +		else +			src_p.prefixlen = IPV6_MAX_BYTELEN; + +		stream_get(&src_p.u.prefix, s, src_p.prefixlen); +		if (src_p.family == AF_INET) { +			inet_ntop(AF_INET, &src_p.u.prefix4, buf, sizeof(buf)); +			ptm_lib_append_msg(ptm_hdl, out_ctxt, +					   ZEBRA_PTM_BFD_SRC_IP_FIELD, buf); +		} else { +			inet_ntop(AF_INET6, &src_p.u.prefix6, buf, sizeof(buf)); +			ptm_lib_append_msg(ptm_hdl, out_ctxt, +					   ZEBRA_PTM_BFD_SRC_IP_FIELD, buf); +		} + +		multi_hop_cnt = stream_getc(s); +		sprintf(tmp_buf, "%d", multi_hop_cnt); +		ptm_lib_append_msg(ptm_hdl, out_ctxt, +				   ZEBRA_PTM_BFD_MAX_HOP_CNT_FIELD, tmp_buf); + +		if (zvrf_id(zvrf) != VRF_DEFAULT) +			ptm_lib_append_msg(ptm_hdl, out_ctxt, +					   ZEBRA_PTM_BFD_VRF_NAME_FIELD, +					   zvrf_name(zvrf)); +	} else { +		if (dst_p.family == AF_INET6) { +			src_p.family = stream_getw(s); + +			if (src_p.family == AF_INET) +				src_p.prefixlen = IPV4_MAX_BYTELEN; +			else +				src_p.prefixlen = IPV6_MAX_BYTELEN; + +			stream_get(&src_p.u.prefix, s, src_p.prefixlen); +			if (src_p.family == AF_INET) { +				inet_ntop(AF_INET, &src_p.u.prefix4, buf, +					  sizeof(buf)); +				ptm_lib_append_msg(ptm_hdl, out_ctxt, +						   ZEBRA_PTM_BFD_SRC_IP_FIELD, +						   buf); +			} else { +				inet_ntop(AF_INET6, &src_p.u.prefix6, buf, +					  sizeof(buf)); +				ptm_lib_append_msg(ptm_hdl, out_ctxt, +						   ZEBRA_PTM_BFD_SRC_IP_FIELD, +						   buf); +			} +		} +		len = stream_getc(s); +		stream_get(if_name, s, len); +		if_name[len] = '\0'; + +		ptm_lib_append_msg(ptm_hdl, out_ctxt, +				   ZEBRA_PTM_BFD_IFNAME_FIELD, if_name); +	} + +	sprintf(tmp_buf, "%d", 1); +	ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_SEND_EVENT, +			   tmp_buf); + +	ptm_lib_complete_msg(ptm_hdl, out_ctxt, ptm_cb.out_data, &data_len); + +	if (IS_ZEBRA_DEBUG_SEND) +		zlog_debug("%s: Sent message (%d) %s", __func__, data_len, +			   ptm_cb.out_data); +	zebra_ptm_send_message(ptm_cb.out_data, data_len); +	return 0;  }  /* BFD peer/dst deregister */ -int -zebra_ptm_bfd_dst_deregister (struct zserv *client, int sock, u_short length, -                              struct zebra_vrf *zvrf) +int zebra_ptm_bfd_dst_deregister(struct zserv *client, int sock, u_short length, +				 struct zebra_vrf *zvrf)  { -  struct stream *s; -  struct prefix src_p; -  struct prefix dst_p; -  u_char multi_hop; -  char if_name[INTERFACE_NAMSIZ]; -  u_char len; -  char buf[INET6_ADDRSTRLEN]; -  char tmp_buf[64]; -  int data_len = ZEBRA_PTM_SEND_MAX_SOCKBUF; -  void *out_ctxt; -  unsigned int pid; - -  client->bfd_peer_del_cnt++; - -  if (IS_ZEBRA_DEBUG_EVENT) -    zlog_debug("bfd_dst_deregister msg from client %s: length=%d", -                zebra_route_string(client->proto), length); - -  if (ptm_cb.ptm_sock == -1) -    { -      ptm_cb.t_timer = thread_add_timer (zebrad.master, zebra_ptm_connect, -                                             NULL, ptm_cb.reconnect_time); -      return -1; -    } - -  ptm_lib_init_msg(ptm_hdl, 0, PTMLIB_MSG_TYPE_CMD, NULL, &out_ctxt); - -  sprintf(tmp_buf, "%s", ZEBRA_PTM_BFD_STOP_CMD); -  ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_CMD_STR, tmp_buf); - -  sprintf(tmp_buf, "%s", zebra_route_string(client->proto)); -  ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_CLIENT_FIELD, -                      tmp_buf); - -  s = client->ibuf; - -  pid = stream_getl(s); -  sprintf(tmp_buf, "%d", pid); -  ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_SEQID_FIELD, tmp_buf); - -  dst_p.family = stream_getw(s); - -  if (dst_p.family == AF_INET) -    dst_p.prefixlen = IPV4_MAX_BYTELEN; -  else -    dst_p.prefixlen = IPV6_MAX_BYTELEN; - -  stream_get(&dst_p.u.prefix, s, dst_p.prefixlen); -  if (dst_p.family == AF_INET) -    inet_ntop(AF_INET, &dst_p.u.prefix4, buf, sizeof(buf)); -  else -    inet_ntop(AF_INET6, &dst_p.u.prefix6, buf, sizeof(buf)); -  ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_DST_IP_FIELD, buf); - - -  multi_hop = stream_getc(s); -  if (multi_hop) -    { -      sprintf(tmp_buf, "%d", 1); -      ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_MULTI_HOP_FIELD, -                          tmp_buf); - -      src_p.family = stream_getw(s); - -      if (src_p.family == AF_INET) -        src_p.prefixlen = IPV4_MAX_BYTELEN; -      else -        src_p.prefixlen = IPV6_MAX_BYTELEN; - -      stream_get(&src_p.u.prefix, s, src_p.prefixlen); -      if (src_p.family == AF_INET) -	inet_ntop(AF_INET, &src_p.u.prefix4, buf, sizeof(buf)); -      else -	inet_ntop(AF_INET6, &src_p.u.prefix6, buf, sizeof(buf)); -      ptm_lib_append_msg(ptm_hdl, out_ctxt, -			 ZEBRA_PTM_BFD_SRC_IP_FIELD, buf); - -      if (zvrf_id (zvrf) != VRF_DEFAULT) -	ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_VRF_NAME_FIELD, -			   zvrf_name (zvrf)); -    } -  else -    { -      if (dst_p.family == AF_INET6) -        { -          src_p.family = stream_getw(s); - -          if (src_p.family == AF_INET) -            src_p.prefixlen = IPV4_MAX_BYTELEN; -          else -            src_p.prefixlen = IPV6_MAX_BYTELEN; - -          stream_get(&src_p.u.prefix, s, src_p.prefixlen); -          if (src_p.family == AF_INET) -            { -              inet_ntop(AF_INET, &src_p.u.prefix4, buf, sizeof(buf)); -              ptm_lib_append_msg(ptm_hdl, out_ctxt, -                                  ZEBRA_PTM_BFD_SRC_IP_FIELD, buf); -            } -          else -            { -              inet_ntop(AF_INET6, &src_p.u.prefix6, buf, sizeof(buf)); -              ptm_lib_append_msg(ptm_hdl, out_ctxt, -                                  ZEBRA_PTM_BFD_SRC_IP_FIELD, buf); -            } -        } - -      len = stream_getc(s); -      stream_get(if_name, s, len); -      if_name[len] = '\0'; - -      ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_IFNAME_FIELD, -                          if_name); -    } - -  ptm_lib_complete_msg(ptm_hdl, out_ctxt, ptm_cb.out_data, &data_len); -  if (IS_ZEBRA_DEBUG_SEND) -    zlog_debug ("%s: Sent message (%d) %s", __func__, data_len, -                  ptm_cb.out_data); - -  zebra_ptm_send_message(ptm_cb.out_data, data_len); -  return 0; +	struct stream *s; +	struct prefix src_p; +	struct prefix dst_p; +	u_char multi_hop; +	char if_name[INTERFACE_NAMSIZ]; +	u_char len; +	char buf[INET6_ADDRSTRLEN]; +	char tmp_buf[64]; +	int data_len = ZEBRA_PTM_SEND_MAX_SOCKBUF; +	void *out_ctxt; +	unsigned int pid; + +	client->bfd_peer_del_cnt++; + +	if (IS_ZEBRA_DEBUG_EVENT) +		zlog_debug("bfd_dst_deregister msg from client %s: length=%d", +			   zebra_route_string(client->proto), length); + +	if (ptm_cb.ptm_sock == -1) { +		ptm_cb.t_timer = +			thread_add_timer(zebrad.master, zebra_ptm_connect, NULL, +					 ptm_cb.reconnect_time); +		return -1; +	} + +	ptm_lib_init_msg(ptm_hdl, 0, PTMLIB_MSG_TYPE_CMD, NULL, &out_ctxt); + +	sprintf(tmp_buf, "%s", ZEBRA_PTM_BFD_STOP_CMD); +	ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_CMD_STR, tmp_buf); + +	sprintf(tmp_buf, "%s", zebra_route_string(client->proto)); +	ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_CLIENT_FIELD, +			   tmp_buf); + +	s = client->ibuf; + +	pid = stream_getl(s); +	sprintf(tmp_buf, "%d", pid); +	ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_SEQID_FIELD, +			   tmp_buf); + +	dst_p.family = stream_getw(s); + +	if (dst_p.family == AF_INET) +		dst_p.prefixlen = IPV4_MAX_BYTELEN; +	else +		dst_p.prefixlen = IPV6_MAX_BYTELEN; + +	stream_get(&dst_p.u.prefix, s, dst_p.prefixlen); +	if (dst_p.family == AF_INET) +		inet_ntop(AF_INET, &dst_p.u.prefix4, buf, sizeof(buf)); +	else +		inet_ntop(AF_INET6, &dst_p.u.prefix6, buf, sizeof(buf)); +	ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_DST_IP_FIELD, buf); + + +	multi_hop = stream_getc(s); +	if (multi_hop) { +		sprintf(tmp_buf, "%d", 1); +		ptm_lib_append_msg(ptm_hdl, out_ctxt, +				   ZEBRA_PTM_BFD_MULTI_HOP_FIELD, tmp_buf); + +		src_p.family = stream_getw(s); + +		if (src_p.family == AF_INET) +			src_p.prefixlen = IPV4_MAX_BYTELEN; +		else +			src_p.prefixlen = IPV6_MAX_BYTELEN; + +		stream_get(&src_p.u.prefix, s, src_p.prefixlen); +		if (src_p.family == AF_INET) +			inet_ntop(AF_INET, &src_p.u.prefix4, buf, sizeof(buf)); +		else +			inet_ntop(AF_INET6, &src_p.u.prefix6, buf, sizeof(buf)); +		ptm_lib_append_msg(ptm_hdl, out_ctxt, +				   ZEBRA_PTM_BFD_SRC_IP_FIELD, buf); + +		if (zvrf_id(zvrf) != VRF_DEFAULT) +			ptm_lib_append_msg(ptm_hdl, out_ctxt, +					   ZEBRA_PTM_BFD_VRF_NAME_FIELD, +					   zvrf_name(zvrf)); +	} else { +		if (dst_p.family == AF_INET6) { +			src_p.family = stream_getw(s); + +			if (src_p.family == AF_INET) +				src_p.prefixlen = IPV4_MAX_BYTELEN; +			else +				src_p.prefixlen = IPV6_MAX_BYTELEN; + +			stream_get(&src_p.u.prefix, s, src_p.prefixlen); +			if (src_p.family == AF_INET) { +				inet_ntop(AF_INET, &src_p.u.prefix4, buf, +					  sizeof(buf)); +				ptm_lib_append_msg(ptm_hdl, out_ctxt, +						   ZEBRA_PTM_BFD_SRC_IP_FIELD, +						   buf); +			} else { +				inet_ntop(AF_INET6, &src_p.u.prefix6, buf, +					  sizeof(buf)); +				ptm_lib_append_msg(ptm_hdl, out_ctxt, +						   ZEBRA_PTM_BFD_SRC_IP_FIELD, +						   buf); +			} +		} + +		len = stream_getc(s); +		stream_get(if_name, s, len); +		if_name[len] = '\0'; + +		ptm_lib_append_msg(ptm_hdl, out_ctxt, +				   ZEBRA_PTM_BFD_IFNAME_FIELD, if_name); +	} + +	ptm_lib_complete_msg(ptm_hdl, out_ctxt, ptm_cb.out_data, &data_len); +	if (IS_ZEBRA_DEBUG_SEND) +		zlog_debug("%s: Sent message (%d) %s", __func__, data_len, +			   ptm_cb.out_data); + +	zebra_ptm_send_message(ptm_cb.out_data, data_len); +	return 0;  }  /* BFD client register */ -int -zebra_ptm_bfd_client_register (struct zserv *client, int sock, u_short length) +int zebra_ptm_bfd_client_register(struct zserv *client, int sock, +				  u_short length)  { -  struct stream *s; -  unsigned int pid; -  void *out_ctxt; -  char tmp_buf[64]; -  int data_len = ZEBRA_PTM_SEND_MAX_SOCKBUF; +	struct stream *s; +	unsigned int pid; +	void *out_ctxt; +	char tmp_buf[64]; +	int data_len = ZEBRA_PTM_SEND_MAX_SOCKBUF; -  client->bfd_client_reg_cnt++; +	client->bfd_client_reg_cnt++; -  if (IS_ZEBRA_DEBUG_EVENT) -    zlog_debug("bfd_client_register msg from client %s: length=%d", -                zebra_route_string(client->proto), length); +	if (IS_ZEBRA_DEBUG_EVENT) +		zlog_debug("bfd_client_register msg from client %s: length=%d", +			   zebra_route_string(client->proto), length); -  if (ptm_cb.ptm_sock == -1) -    { -      ptm_cb.t_timer = thread_add_timer (zebrad.master, zebra_ptm_connect, -                                             NULL, ptm_cb.reconnect_time); -      return -1; -    } +	if (ptm_cb.ptm_sock == -1) { +		ptm_cb.t_timer = +			thread_add_timer(zebrad.master, zebra_ptm_connect, NULL, +					 ptm_cb.reconnect_time); +		return -1; +	} -  ptm_lib_init_msg(ptm_hdl, 0, PTMLIB_MSG_TYPE_CMD, NULL, &out_ctxt); +	ptm_lib_init_msg(ptm_hdl, 0, PTMLIB_MSG_TYPE_CMD, NULL, &out_ctxt); -  sprintf(tmp_buf, "%s", ZEBRA_PTM_BFD_CLIENT_REG_CMD); -  ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_CMD_STR, tmp_buf); +	sprintf(tmp_buf, "%s", ZEBRA_PTM_BFD_CLIENT_REG_CMD); +	ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_CMD_STR, tmp_buf); -  sprintf(tmp_buf, "%s", zebra_route_string(client->proto)); -  ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_CLIENT_FIELD, -                      tmp_buf); +	sprintf(tmp_buf, "%s", zebra_route_string(client->proto)); +	ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_CLIENT_FIELD, +			   tmp_buf); -  s = client->ibuf; +	s = client->ibuf; -  pid = stream_getl(s); -  sprintf(tmp_buf, "%d", pid); -  ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_SEQID_FIELD, -                      tmp_buf); +	pid = stream_getl(s); +	sprintf(tmp_buf, "%d", pid); +	ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_SEQID_FIELD, +			   tmp_buf); -  ptm_lib_complete_msg(ptm_hdl, out_ctxt, ptm_cb.out_data, &data_len); +	ptm_lib_complete_msg(ptm_hdl, out_ctxt, ptm_cb.out_data, &data_len); -  if (IS_ZEBRA_DEBUG_SEND) -    zlog_debug ("%s: Sent message (%d) %s", __func__, data_len, -                  ptm_cb.out_data); -  zebra_ptm_send_message(ptm_cb.out_data, data_len); +	if (IS_ZEBRA_DEBUG_SEND) +		zlog_debug("%s: Sent message (%d) %s", __func__, data_len, +			   ptm_cb.out_data); +	zebra_ptm_send_message(ptm_cb.out_data, data_len); -  SET_FLAG(ptm_cb.client_flags[client->proto], ZEBRA_PTM_BFD_CLIENT_FLAG_REG); -  return 0; +	SET_FLAG(ptm_cb.client_flags[client->proto], +		 ZEBRA_PTM_BFD_CLIENT_FLAG_REG); +	return 0;  }  /* BFD client deregister */ -void -zebra_ptm_bfd_client_deregister (int proto) +void zebra_ptm_bfd_client_deregister(int proto)  { -  void *out_ctxt; -  char tmp_buf[64]; -  int data_len = ZEBRA_PTM_SEND_MAX_SOCKBUF; +	void *out_ctxt; +	char tmp_buf[64]; +	int data_len = ZEBRA_PTM_SEND_MAX_SOCKBUF; -  if (proto != ZEBRA_ROUTE_OSPF && proto != ZEBRA_ROUTE_BGP -      && proto != ZEBRA_ROUTE_OSPF6) -    return; +	if (proto != ZEBRA_ROUTE_OSPF && proto != ZEBRA_ROUTE_BGP +	    && proto != ZEBRA_ROUTE_OSPF6) +		return; -  if (IS_ZEBRA_DEBUG_EVENT) -    zlog_err("bfd_client_deregister msg for client %s", -                zebra_route_string(proto)); +	if (IS_ZEBRA_DEBUG_EVENT) +		zlog_err("bfd_client_deregister msg for client %s", +			 zebra_route_string(proto)); -  if (ptm_cb.ptm_sock == -1) -    { -      ptm_cb.t_timer = thread_add_timer (zebrad.master, zebra_ptm_connect, -                                             NULL, ptm_cb.reconnect_time); -      return; -    } +	if (ptm_cb.ptm_sock == -1) { +		ptm_cb.t_timer = +			thread_add_timer(zebrad.master, zebra_ptm_connect, NULL, +					 ptm_cb.reconnect_time); +		return; +	} -  ptm_lib_init_msg(ptm_hdl, 0, PTMLIB_MSG_TYPE_CMD, NULL, &out_ctxt); +	ptm_lib_init_msg(ptm_hdl, 0, PTMLIB_MSG_TYPE_CMD, NULL, &out_ctxt); -  sprintf(tmp_buf, "%s", ZEBRA_PTM_BFD_CLIENT_DEREG_CMD); -  ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_CMD_STR, tmp_buf); +	sprintf(tmp_buf, "%s", ZEBRA_PTM_BFD_CLIENT_DEREG_CMD); +	ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_CMD_STR, tmp_buf); -  sprintf(tmp_buf, "%s", zebra_route_string(proto)); -  ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_CLIENT_FIELD, -                      tmp_buf); +	sprintf(tmp_buf, "%s", zebra_route_string(proto)); +	ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_CLIENT_FIELD, +			   tmp_buf); -  ptm_lib_complete_msg(ptm_hdl, out_ctxt, ptm_cb.out_data, &data_len); +	ptm_lib_complete_msg(ptm_hdl, out_ctxt, ptm_cb.out_data, &data_len); -  if (IS_ZEBRA_DEBUG_SEND) -    zlog_debug ("%s: Sent message (%d) %s", __func__, data_len, -                  ptm_cb.out_data); +	if (IS_ZEBRA_DEBUG_SEND) +		zlog_debug("%s: Sent message (%d) %s", __func__, data_len, +			   ptm_cb.out_data); -  zebra_ptm_send_message(ptm_cb.out_data, data_len); -  UNSET_FLAG(ptm_cb.client_flags[proto], ZEBRA_PTM_BFD_CLIENT_FLAG_REG); +	zebra_ptm_send_message(ptm_cb.out_data, data_len); +	UNSET_FLAG(ptm_cb.client_flags[proto], ZEBRA_PTM_BFD_CLIENT_FLAG_REG);  } -int -zebra_ptm_get_enable_state(void) +int zebra_ptm_get_enable_state(void)  { -  return ptm_cb.ptm_enable; +	return ptm_cb.ptm_enable;  }  /*   * zebra_ptm_get_status_str - Convert status to a display string.   */ -static const char * -zebra_ptm_get_status_str(int status) +static const char *zebra_ptm_get_status_str(int status)  { -  switch (status) -  { -    case ZEBRA_PTM_STATUS_DOWN: -      return "fail"; -    case ZEBRA_PTM_STATUS_UP: -      return "pass"; -    case ZEBRA_PTM_STATUS_UNKNOWN: -    default: -      return "n/a"; -  } +	switch (status) { +	case ZEBRA_PTM_STATUS_DOWN: +		return "fail"; +	case ZEBRA_PTM_STATUS_UP: +		return "pass"; +	case ZEBRA_PTM_STATUS_UNKNOWN: +	default: +		return "n/a"; +	}  } -void -zebra_ptm_show_status(struct vty *vty, struct interface *ifp) +void zebra_ptm_show_status(struct vty *vty, struct interface *ifp)  { -  vty_out (vty, "  PTM status: "); -  if (ifp->ptm_enable) { -    vty_out (vty, "%s%s", zebra_ptm_get_status_str (ifp->ptm_status), -                          VTY_NEWLINE); -  } else { -    vty_out (vty, "disabled%s", VTY_NEWLINE); -  } +	vty_out(vty, "  PTM status: "); +	if (ifp->ptm_enable) { +		vty_out(vty, "%s%s", zebra_ptm_get_status_str(ifp->ptm_status), +			VTY_NEWLINE); +	} else { +		vty_out(vty, "disabled%s", VTY_NEWLINE); +	}  } -void -zebra_ptm_send_status_req(void) +void zebra_ptm_send_status_req(void)  { -  void *out_ctxt; -  int len = ZEBRA_PTM_SEND_MAX_SOCKBUF; - -  if (ptm_cb.ptm_enable) -    { -      ptm_lib_init_msg(ptm_hdl, 0, PTMLIB_MSG_TYPE_CMD, NULL, &out_ctxt); -      ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_CMD_STR, -                          ZEBRA_PTM_GET_STATUS_CMD); -      ptm_lib_complete_msg(ptm_hdl, out_ctxt, ptm_cb.out_data, &len); - -      zebra_ptm_send_message(ptm_cb.out_data, len); -    } +	void *out_ctxt; +	int len = ZEBRA_PTM_SEND_MAX_SOCKBUF; + +	if (ptm_cb.ptm_enable) { +		ptm_lib_init_msg(ptm_hdl, 0, PTMLIB_MSG_TYPE_CMD, NULL, +				 &out_ctxt); +		ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_CMD_STR, +				   ZEBRA_PTM_GET_STATUS_CMD); +		ptm_lib_complete_msg(ptm_hdl, out_ctxt, ptm_cb.out_data, &len); + +		zebra_ptm_send_message(ptm_cb.out_data, len); +	}  } -void -zebra_ptm_reset_status(int ptm_disable) +void zebra_ptm_reset_status(int ptm_disable)  { -  struct vrf *vrf; -  struct listnode *i; -  struct interface *ifp; -  int send_linkup; - -  RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) -    for (ALL_LIST_ELEMENTS_RO (vrf->iflist, i, ifp)) -      { -        send_linkup = 0; -        if (ifp->ptm_enable) -          { -            if (!if_is_operative(ifp)) -              send_linkup = 1; - -            if (ptm_disable) -              ifp->ptm_enable = ZEBRA_IF_PTM_ENABLE_OFF; -            ifp->ptm_status = ZEBRA_PTM_STATUS_UNKNOWN; - -            if (if_is_operative (ifp) && send_linkup) -	      { -		if (IS_ZEBRA_DEBUG_EVENT) -		  zlog_debug ("%s: Bringing up interface %s", __func__, -				ifp->name); -		if_up (ifp); -	      } -          } -      } +	struct vrf *vrf; +	struct listnode *i; +	struct interface *ifp; +	int send_linkup; + +	RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id) +	for (ALL_LIST_ELEMENTS_RO(vrf->iflist, i, ifp)) { +		send_linkup = 0; +		if (ifp->ptm_enable) { +			if (!if_is_operative(ifp)) +				send_linkup = 1; + +			if (ptm_disable) +				ifp->ptm_enable = ZEBRA_IF_PTM_ENABLE_OFF; +			ifp->ptm_status = ZEBRA_PTM_STATUS_UNKNOWN; + +			if (if_is_operative(ifp) && send_linkup) { +				if (IS_ZEBRA_DEBUG_EVENT) +					zlog_debug( +						"%s: Bringing up interface %s", +						__func__, ifp->name); +				if_up(ifp); +			} +		} +	}  } -void -zebra_ptm_if_init(struct zebra_if *zebra_ifp) +void zebra_ptm_if_init(struct zebra_if *zebra_ifp)  { -  zebra_ifp->ptm_enable = ZEBRA_IF_PTM_ENABLE_UNSPEC; +	zebra_ifp->ptm_enable = ZEBRA_IF_PTM_ENABLE_UNSPEC;  } -void -zebra_ptm_if_set_ptm_state(struct interface *ifp, struct zebra_if *zebra_ifp) +void zebra_ptm_if_set_ptm_state(struct interface *ifp, +				struct zebra_if *zebra_ifp)  { -  if (zebra_ifp && zebra_ifp->ptm_enable != ZEBRA_IF_PTM_ENABLE_UNSPEC) -    ifp->ptm_enable = zebra_ifp->ptm_enable; +	if (zebra_ifp && zebra_ifp->ptm_enable != ZEBRA_IF_PTM_ENABLE_UNSPEC) +		ifp->ptm_enable = zebra_ifp->ptm_enable;  } -void -zebra_ptm_if_write (struct vty *vty, struct zebra_if *zebra_ifp) +void zebra_ptm_if_write(struct vty *vty, struct zebra_if *zebra_ifp)  { -  if (zebra_ifp->ptm_enable == ZEBRA_IF_PTM_ENABLE_OFF) -    vty_out (vty, " no ptm-enable%s", VTY_NEWLINE); +	if (zebra_ifp->ptm_enable == ZEBRA_IF_PTM_ENABLE_OFF) +		vty_out(vty, " no ptm-enable%s", VTY_NEWLINE);  } diff --git a/zebra/zebra_ptm.h b/zebra/zebra_ptm.h index 71c85d9094..252591ea6a 100644 --- a/zebra/zebra_ptm.h +++ b/zebra/zebra_ptm.h @@ -30,23 +30,22 @@ extern const char ZEBRA_PTM_SOCK_NAME[];  #define ZEBRA_PTM_BFD_CLIENT_FLAG_REG   (1 << 1) /* client registered with BFD */  /* Zebra ptm context block */ -struct zebra_ptm_cb -{ -  int ptm_sock; /* ptm file descriptor. */ +struct zebra_ptm_cb { +	int ptm_sock; /* ptm file descriptor. */ -  struct buffer *wb; /* Buffer of data waiting to be written to ptm. */ +	struct buffer *wb; /* Buffer of data waiting to be written to ptm. */ -  struct thread *t_read; /* Thread for read */ -  struct thread *t_write; /* Thread for write */ -  struct thread *t_timer; /* Thread for timer */ +	struct thread *t_read;  /* Thread for read */ +	struct thread *t_write; /* Thread for write */ +	struct thread *t_timer; /* Thread for timer */ -  char *out_data; -  char *in_data; -  int reconnect_time; +	char *out_data; +	char *in_data; +	int reconnect_time; -  int ptm_enable; -  int pid; -  u_int8_t client_flags[ZEBRA_ROUTE_MAX]; +	int ptm_enable; +	int pid; +	u_int8_t client_flags[ZEBRA_ROUTE_MAX];  };  #define ZEBRA_PTM_STATUS_DOWN 0 @@ -58,22 +57,22 @@ struct zebra_ptm_cb  #define ZEBRA_IF_PTM_ENABLE_ON     1  #define ZEBRA_IF_PTM_ENABLE_UNSPEC 2 -void zebra_ptm_init (void); +void zebra_ptm_init(void);  void zebra_ptm_finish(void); -int zebra_ptm_connect (struct thread *t); -void zebra_ptm_write (struct vty *vty); +int zebra_ptm_connect(struct thread *t); +void zebra_ptm_write(struct vty *vty);  int zebra_ptm_get_enable_state(void); -int zebra_ptm_bfd_dst_register (struct zserv *client, int sock, u_short length, -                                  int command, struct zebra_vrf *zvrf); -int zebra_ptm_bfd_dst_deregister (struct zserv *client, int sock, -                                  u_short length, struct zebra_vrf *zvrf); -void -zebra_ptm_show_status(struct vty *vty, struct interface *ifp); -int zebra_ptm_bfd_client_register (struct zserv *client, int sock, -                                    u_short length); +int zebra_ptm_bfd_dst_register(struct zserv *client, int sock, u_short length, +			       int command, struct zebra_vrf *zvrf); +int zebra_ptm_bfd_dst_deregister(struct zserv *client, int sock, u_short length, +				 struct zebra_vrf *zvrf); +void zebra_ptm_show_status(struct vty *vty, struct interface *ifp); +int zebra_ptm_bfd_client_register(struct zserv *client, int sock, +				  u_short length);  void zebra_ptm_if_init(struct zebra_if *zebra_ifp); -void zebra_ptm_if_set_ptm_state(struct interface *ifp, struct zebra_if *zebra_ifp); -void zebra_ptm_if_write (struct vty *vty, struct zebra_if *zebra_ifp); -void zebra_ptm_bfd_client_deregister (int proto); +void zebra_ptm_if_set_ptm_state(struct interface *ifp, +				struct zebra_if *zebra_ifp); +void zebra_ptm_if_write(struct vty *vty, struct zebra_if *zebra_ifp); +void zebra_ptm_bfd_client_deregister(int proto);  #endif diff --git a/zebra/zebra_ptm_null.c b/zebra/zebra_ptm_null.c index 4afa2ce522..1bda8868e6 100644 --- a/zebra/zebra_ptm_null.c +++ b/zebra/zebra_ptm_null.c @@ -23,9 +23,13 @@  #include "if.h"  #include "zebra_ptm_redistribute.h" -void zebra_interface_bfd_update (struct interface *a, struct prefix *dp, -                                 struct prefix *sp, int status, vrf_id_t vrf_id) -{ return; } +void zebra_interface_bfd_update(struct interface *a, struct prefix *dp, +				struct prefix *sp, int status, vrf_id_t vrf_id) +{ +	return; +} -void zebra_bfd_peer_replay_req (void) -{ return; } +void zebra_bfd_peer_replay_req(void) +{ +	return; +} diff --git a/zebra/zebra_ptm_redistribute.c b/zebra/zebra_ptm_redistribute.c index 396857bc1f..2dd1389a84 100644 --- a/zebra/zebra_ptm_redistribute.c +++ b/zebra/zebra_ptm_redistribute.c @@ -27,101 +27,98 @@  #include "zebra/zebra_ptm_redistribute.h"  #include "zebra/zebra_memory.h" -static int -zsend_interface_bfd_update (int cmd, struct zserv *client, -                            struct interface *ifp, struct prefix *dp, -                            struct prefix *sp, int status, vrf_id_t vrf_id) +static int zsend_interface_bfd_update(int cmd, struct zserv *client, +				      struct interface *ifp, struct prefix *dp, +				      struct prefix *sp, int status, +				      vrf_id_t vrf_id)  { -  int blen; -  struct stream *s; - -  /* Check this client need interface information. */ -  if (! client->ifinfo) -    return 0; - -  s = client->obuf; -  stream_reset (s); - -  zserv_create_header (s, cmd, vrf_id); -  if (ifp) -    stream_putl (s, ifp->ifindex); -  else -    stream_putl (s, 0); - -  /* BFD destination prefix information. */ -  stream_putc (s, dp->family); -  blen = prefix_blen (dp); -  stream_put (s, &dp->u.prefix, blen); -  stream_putc (s, dp->prefixlen); - -  /* BFD status */ -  stream_putl(s, status); - -  /* BFD source prefix information. */ -  stream_putc (s, sp->family); -  blen = prefix_blen (sp); -  stream_put (s, &sp->u.prefix, blen); -  stream_putc (s, sp->prefixlen); - -  /* Write packet size. */ -  stream_putw_at (s, 0, stream_get_endp (s)); - -  client->if_bfd_cnt++; -  return zebra_server_send_message(client); +	int blen; +	struct stream *s; + +	/* Check this client need interface information. */ +	if (!client->ifinfo) +		return 0; + +	s = client->obuf; +	stream_reset(s); + +	zserv_create_header(s, cmd, vrf_id); +	if (ifp) +		stream_putl(s, ifp->ifindex); +	else +		stream_putl(s, 0); + +	/* BFD destination prefix information. */ +	stream_putc(s, dp->family); +	blen = prefix_blen(dp); +	stream_put(s, &dp->u.prefix, blen); +	stream_putc(s, dp->prefixlen); + +	/* BFD status */ +	stream_putl(s, status); + +	/* BFD source prefix information. */ +	stream_putc(s, sp->family); +	blen = prefix_blen(sp); +	stream_put(s, &sp->u.prefix, blen); +	stream_putc(s, sp->prefixlen); + +	/* Write packet size. */ +	stream_putw_at(s, 0, stream_get_endp(s)); + +	client->if_bfd_cnt++; +	return zebra_server_send_message(client);  } -void -zebra_interface_bfd_update (struct interface *ifp, struct prefix *dp, -                            struct prefix *sp, int status, vrf_id_t vrf_id) +void zebra_interface_bfd_update(struct interface *ifp, struct prefix *dp, +				struct prefix *sp, int status, vrf_id_t vrf_id)  { -  struct listnode *node, *nnode; -  struct zserv *client; - -  for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) -    { -      /* Supporting for OSPF and BGP */ -      if (client->proto != ZEBRA_ROUTE_OSPF && client->proto != ZEBRA_ROUTE_BGP -          && client->proto != ZEBRA_ROUTE_OSPF6) -        continue; - -      /* Notify to the protocol daemons. */ -      zsend_interface_bfd_update (ZEBRA_INTERFACE_BFD_DEST_UPDATE, client, ifp, -                                    dp, sp, status, vrf_id); -    } +	struct listnode *node, *nnode; +	struct zserv *client; + +	for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) { +		/* Supporting for OSPF and BGP */ +		if (client->proto != ZEBRA_ROUTE_OSPF +		    && client->proto != ZEBRA_ROUTE_BGP +		    && client->proto != ZEBRA_ROUTE_OSPF6) +			continue; + +		/* Notify to the protocol daemons. */ +		zsend_interface_bfd_update(ZEBRA_INTERFACE_BFD_DEST_UPDATE, +					   client, ifp, dp, sp, status, vrf_id); +	}  } -static int -zsend_bfd_peer_replay (int cmd, struct zserv *client) +static int zsend_bfd_peer_replay(int cmd, struct zserv *client)  { -  struct stream *s; +	struct stream *s; -  s = client->obuf; -  stream_reset (s); +	s = client->obuf; +	stream_reset(s); -  zserv_create_header (s, cmd, VRF_DEFAULT); //Pending: adjust when multi-vrf bfd work +	zserv_create_header( +		s, cmd, VRF_DEFAULT); // Pending: adjust when multi-vrf bfd work -  /* Write packet size. */ -  stream_putw_at (s, 0, stream_get_endp (s)); +	/* Write packet size. */ +	stream_putw_at(s, 0, stream_get_endp(s)); -  client->bfd_peer_replay_cnt++; -  return zebra_server_send_message(client); +	client->bfd_peer_replay_cnt++; +	return zebra_server_send_message(client);  } -void -zebra_bfd_peer_replay_req (void) +void zebra_bfd_peer_replay_req(void)  { -  struct listnode *node, *nnode; -  struct zserv *client; - -  for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) -    { -      /* Supporting for BGP */ -      if ((client->proto != ZEBRA_ROUTE_BGP) && -          (client->proto != ZEBRA_ROUTE_OSPF) && -          (client->proto != ZEBRA_ROUTE_OSPF6)) -        continue; - -      /* Notify to the protocol daemons. */ -      zsend_bfd_peer_replay (ZEBRA_BFD_DEST_REPLAY, client); -    } +	struct listnode *node, *nnode; +	struct zserv *client; + +	for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) { +		/* Supporting for BGP */ +		if ((client->proto != ZEBRA_ROUTE_BGP) +		    && (client->proto != ZEBRA_ROUTE_OSPF) +		    && (client->proto != ZEBRA_ROUTE_OSPF6)) +			continue; + +		/* Notify to the protocol daemons. */ +		zsend_bfd_peer_replay(ZEBRA_BFD_DEST_REPLAY, client); +	}  } diff --git a/zebra/zebra_ptm_redistribute.h b/zebra/zebra_ptm_redistribute.h index d5aa37d5f8..02541ec2f3 100644 --- a/zebra/zebra_ptm_redistribute.h +++ b/zebra/zebra_ptm_redistribute.h @@ -22,7 +22,7 @@  #ifndef _ZEBRA_PTM_REDISTRIBUTE_H  #define _ZEBRA_PTM_REDISTRIBUTE_H -extern void zebra_interface_bfd_update (struct interface *, struct prefix *, -                                         struct prefix *, int, vrf_id_t); -extern void zebra_bfd_peer_replay_req (void); +extern void zebra_interface_bfd_update(struct interface *, struct prefix *, +				       struct prefix *, int, vrf_id_t); +extern void zebra_bfd_peer_replay_req(void);  #endif /* _ZEBRA_PTM_REDISTRIBUTE_H */ diff --git a/zebra/zebra_pw.c b/zebra/zebra_pw.c index 2164ddf6ee..21b6efd86f 100644 --- a/zebra/zebra_pw.c +++ b/zebra/zebra_pw.c @@ -36,8 +36,8 @@ DEFINE_MTYPE_STATIC(LIB, PW, "Pseudowire")  DEFINE_QOBJ_TYPE(zebra_pw) -DEFINE_HOOK(pw_install, (struct zebra_pw *pw), (pw)) -DEFINE_HOOK(pw_uninstall, (struct zebra_pw *pw), (pw)) +DEFINE_HOOK(pw_install, (struct zebra_pw * pw), (pw)) +DEFINE_HOOK(pw_uninstall, (struct zebra_pw * pw), (pw))  extern struct zebra_t zebrad; @@ -140,8 +140,7 @@ static int zebra_pw_enabled(struct zebra_pw *pw)  {  	if (pw->protocol == ZEBRA_ROUTE_STATIC) {  		if (pw->local_label == MPLS_NO_LABEL -		    || pw->remote_label == MPLS_NO_LABEL -		    || pw->af == AF_UNSPEC) +		    || pw->remote_label == MPLS_NO_LABEL || pw->af == AF_UNSPEC)  			return 0;  		return 1;  	} else @@ -204,15 +203,16 @@ static void zebra_pw_uninstall(struct zebra_pw *pw)  void zebra_pw_install_failure(struct zebra_pw *pw)  {  	if (IS_ZEBRA_DEBUG_PW) -		zlog_debug("%u: failed installing pseudowire %s, " -			   "scheduling retry in %u seconds", pw->vrf_id, -			   pw->ifname, PW_INSTALL_RETRY_INTERVAL); +		zlog_debug( +			"%u: failed installing pseudowire %s, " +			"scheduling retry in %u seconds", +			pw->vrf_id, pw->ifname, PW_INSTALL_RETRY_INTERVAL);  	/* schedule to retry later */  	THREAD_TIMER_OFF(pw->install_retry_timer);  	pw->install_retry_timer = -		thread_add_timer(zebrad.master, zebra_pw_install_retry, -		pw, PW_INSTALL_RETRY_INTERVAL); +		thread_add_timer(zebrad.master, zebra_pw_install_retry, pw, +				 PW_INSTALL_RETRY_INTERVAL);  	zebra_pw_update_status(pw, PW_STATUS_DOWN);  } @@ -268,16 +268,17 @@ static int zebra_pw_check_reachability(struct zebra_pw *pw)  	return 0;  } -void -zebra_pw_client_close(struct zserv *client) +void zebra_pw_client_close(struct zserv *client)  {  	struct vrf *vrf;  	struct zebra_vrf *zvrf;  	struct zebra_pw *pw, *tmp; -	RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id) { +	RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id) +	{  		zvrf = vrf->info; -		RB_FOREACH_SAFE(pw, zebra_pw_head, &zvrf->pseudowires, tmp) { +		RB_FOREACH_SAFE(pw, zebra_pw_head, &zvrf->pseudowires, tmp) +		{  			if (pw->client != client)  				continue;  			zebra_pw_del(zvrf, pw); @@ -444,11 +445,11 @@ DEFUN (show_pseudowires,  	if (!zvrf)  		return 0; -	vty_out(vty, "%-16s %-24s %-12s %-8s %-10s%s", -		"Interface", "Neighbor", "Labels", "Protocol", "Status", -		VTY_NEWLINE); +	vty_out(vty, "%-16s %-24s %-12s %-8s %-10s%s", "Interface", "Neighbor", +		"Labels", "Protocol", "Status", VTY_NEWLINE); -	RB_FOREACH(pw, zebra_pw_head, &zvrf->pseudowires) { +	RB_FOREACH(pw, zebra_pw_head, &zvrf->pseudowires) +	{  		char buf_nbr[INET6_ADDRSTRLEN];  		char buf_labels[64]; @@ -461,11 +462,13 @@ DEFUN (show_pseudowires,  		else  			snprintf(buf_labels, sizeof(buf_labels), "-"); -		vty_out(vty, "%-16s %-24s %-12s %-8s %-10s%s", -			pw->ifname, (pw->af != AF_UNSPEC) ? buf_nbr : "-", -			buf_labels, zebra_route_string(pw->protocol), -			(zebra_pw_enabled(pw) && pw->status == PW_STATUS_UP) ? -			"UP" : "DOWN", VTY_NEWLINE); +		vty_out(vty, "%-16s %-24s %-12s %-8s %-10s%s", pw->ifname, +			(pw->af != AF_UNSPEC) ? buf_nbr : "-", buf_labels, +			zebra_route_string(pw->protocol), +			(zebra_pw_enabled(pw) && pw->status == PW_STATUS_UP) +				? "UP" +				: "DOWN", +			VTY_NEWLINE);  	}  	return CMD_SUCCESS; @@ -482,24 +485,28 @@ static int zebra_pw_config(struct vty *vty)  	if (!zvrf)  		return 0; -	RB_FOREACH(pw, zebra_static_pw_head, &zvrf->static_pseudowires) { +	RB_FOREACH(pw, zebra_static_pw_head, &zvrf->static_pseudowires) +	{  		vty_out(vty, "pseudowire %s%s", pw->ifname, VTY_NEWLINE);  		if (pw->local_label != MPLS_NO_LABEL  		    && pw->remote_label != MPLS_NO_LABEL)  			vty_out(vty, " mpls label local %u remote %u%s", -				pw->local_label, pw->remote_label, -				VTY_NEWLINE); +				pw->local_label, pw->remote_label, VTY_NEWLINE);  		else -			vty_out(vty, " ! Incomplete config, specify the static " -				"MPLS labels%s", VTY_NEWLINE); +			vty_out(vty, +				" ! Incomplete config, specify the static " +				"MPLS labels%s", +				VTY_NEWLINE);  		if (pw->af != AF_UNSPEC) {  			char buf[INET6_ADDRSTRLEN];  			inet_ntop(pw->af, &pw->nexthop, buf, sizeof(buf));  			vty_out(vty, " neighbor %s%s", buf, VTY_NEWLINE);  		} else -			vty_out(vty, " ! Incomplete config, specify a neighbor " -				"address%s", VTY_NEWLINE); +			vty_out(vty, +				" ! Incomplete config, specify a neighbor " +				"address%s", +				VTY_NEWLINE);  		if (!(pw->flags & F_PSEUDOWIRE_CWORD))  			vty_out(vty, " control-word exclude%s", VTY_NEWLINE); @@ -511,11 +518,8 @@ static int zebra_pw_config(struct vty *vty)  	return write;  } -static struct cmd_node pw_node = -{ -	PW_NODE, -	"%s(config-pw)# ", -	1, +static struct cmd_node pw_node = { +	PW_NODE, "%s(config-pw)# ", 1,  };  void zebra_pw_vty_init(void) diff --git a/zebra/zebra_pw.h b/zebra/zebra_pw.h index b588bac0a2..417d26fe65 100644 --- a/zebra/zebra_pw.h +++ b/zebra/zebra_pw.h @@ -59,8 +59,8 @@ RB_PROTOTYPE(zebra_static_pw_head, zebra_pw, static_pw_entry, zebra_pw_compare);  DECLARE_HOOK(pw_install, (struct zebra_pw * pw), (pw))  DECLARE_HOOK(pw_uninstall, (struct zebra_pw * pw), (pw)) -struct zebra_pw *zebra_pw_add(struct zebra_vrf *, const char *, -			      uint8_t, struct zserv *); +struct zebra_pw *zebra_pw_add(struct zebra_vrf *, const char *, uint8_t, +			      struct zserv *);  void zebra_pw_del(struct zebra_vrf *, struct zebra_pw *);  void zebra_pw_change(struct zebra_pw *, ifindex_t, int, int, union g_addr *,  		     uint32_t, uint32_t, uint8_t, union pw_protocol_fields *); diff --git a/zebra/zebra_pw_null.c b/zebra/zebra_pw_null.c index d19d80b8c9..d9f6dc1301 100644 --- a/zebra/zebra_pw_null.c +++ b/zebra/zebra_pw_null.c @@ -25,5 +25,9 @@  #include "zebra/zserv.h"  #include "zebra/zebra_vrf.h" -void zebra_pw_init(struct zebra_vrf *zvrf) {} -void zebra_pw_exit(struct zebra_vrf *zvrf) {} +void zebra_pw_init(struct zebra_vrf *zvrf) +{ +} +void zebra_pw_exit(struct zebra_vrf *zvrf) +{ +} diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index b3e70e46fa..556f4504ec 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -16,7 +16,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #include <zebra.h> @@ -52,7 +52,8 @@  #include "zebra/interface.h"  #include "zebra/connected.h" -DEFINE_HOOK(rib_update, (struct route_node *rn, const char *reason), (rn, reason)) +DEFINE_HOOK(rib_update, (struct route_node * rn, const char *reason), +	    (rn, reason))  /* Should we allow non Quagga processes to delete our routes */  extern int allow_delete; @@ -64,768 +65,860 @@ extern int allow_delete;  int rib_process_hold_time = 10;  /* Each route type's string and default distance value. */ -static const struct -{   -  int key; -  int distance; -} route_info[ZEBRA_ROUTE_MAX] = -{ -  [ZEBRA_ROUTE_SYSTEM]  = {ZEBRA_ROUTE_SYSTEM,    0}, -  [ZEBRA_ROUTE_KERNEL]  = {ZEBRA_ROUTE_KERNEL,    0}, -  [ZEBRA_ROUTE_CONNECT] = {ZEBRA_ROUTE_CONNECT,   0}, -  [ZEBRA_ROUTE_STATIC]  = {ZEBRA_ROUTE_STATIC,    1}, -  [ZEBRA_ROUTE_RIP]     = {ZEBRA_ROUTE_RIP,     120}, -  [ZEBRA_ROUTE_RIPNG]   = {ZEBRA_ROUTE_RIPNG,   120}, -  [ZEBRA_ROUTE_OSPF]    = {ZEBRA_ROUTE_OSPF,    110}, -  [ZEBRA_ROUTE_OSPF6]   = {ZEBRA_ROUTE_OSPF6,   110}, -  [ZEBRA_ROUTE_ISIS]    = {ZEBRA_ROUTE_ISIS,    115}, -  [ZEBRA_ROUTE_BGP]     = {ZEBRA_ROUTE_BGP,      20  /* IBGP is 200. */}, -  [ZEBRA_ROUTE_NHRP]    = {ZEBRA_ROUTE_NHRP,     10}, -  /* no entry/default: 150 */ +static const struct { +	int key; +	int distance; +} route_info[ZEBRA_ROUTE_MAX] = { +		[ZEBRA_ROUTE_SYSTEM] = {ZEBRA_ROUTE_SYSTEM, 0}, +		[ZEBRA_ROUTE_KERNEL] = {ZEBRA_ROUTE_KERNEL, 0}, +		[ZEBRA_ROUTE_CONNECT] = {ZEBRA_ROUTE_CONNECT, 0}, +		[ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC, 1}, +		[ZEBRA_ROUTE_RIP] = {ZEBRA_ROUTE_RIP, 120}, +		[ZEBRA_ROUTE_RIPNG] = {ZEBRA_ROUTE_RIPNG, 120}, +		[ZEBRA_ROUTE_OSPF] = {ZEBRA_ROUTE_OSPF, 110}, +		[ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110}, +		[ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115}, +		[ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */}, +		[ZEBRA_ROUTE_NHRP] = {ZEBRA_ROUTE_NHRP, 10}, +	/* no entry/default: 150 */  };  /* RPF lookup behaviour */  static enum multicast_mode ipv4_multicast_mode = MCAST_NO_CONFIG; -static void __attribute__((format (printf, 5, 6))) -_rnode_zlog(const char *_func, vrf_id_t vrf_id, struct route_node *rn, int priority, -	    const char *msgfmt, ...) +static void __attribute__((format(printf, 5, 6))) +_rnode_zlog(const char *_func, vrf_id_t vrf_id, struct route_node *rn, +	    int priority, const char *msgfmt, ...)  { -  char buf[SRCDEST2STR_BUFFER + sizeof(" (MRIB)")]; -  char msgbuf[512]; -  va_list ap; +	char buf[SRCDEST2STR_BUFFER + sizeof(" (MRIB)")]; +	char msgbuf[512]; +	va_list ap; -  va_start(ap, msgfmt); -  vsnprintf(msgbuf, sizeof(msgbuf), msgfmt, ap); -  va_end(ap); +	va_start(ap, msgfmt); +	vsnprintf(msgbuf, sizeof(msgbuf), msgfmt, ap); +	va_end(ap); -  if (rn) -    { -      rib_table_info_t *info = srcdest_rnode_table_info (rn); -      srcdest_rnode2str(rn, buf, sizeof(buf)); +	if (rn) { +		rib_table_info_t *info = srcdest_rnode_table_info(rn); +		srcdest_rnode2str(rn, buf, sizeof(buf)); -      if (info->safi == SAFI_MULTICAST) -        strcat(buf, " (MRIB)"); -    } -  else -    { -      snprintf(buf, sizeof(buf), "{(route_node *) NULL}"); -    } +		if (info->safi == SAFI_MULTICAST) +			strcat(buf, " (MRIB)"); +	} else { +		snprintf(buf, sizeof(buf), "{(route_node *) NULL}"); +	} -  zlog (priority, "%s: %d:%s: %s", _func, vrf_id, buf, msgbuf); +	zlog(priority, "%s: %d:%s: %s", _func, vrf_id, buf, msgbuf);  } -#define rnode_debug(node, vrf_id, ...) \ +#define rnode_debug(node, vrf_id, ...)                                         \  	_rnode_zlog(__func__, vrf_id, node, LOG_DEBUG, __VA_ARGS__) -#define rnode_info(node, ...) \ +#define rnode_info(node, ...)                                                  \  	_rnode_zlog(__func__, vrf_id, node, LOG_INFO, __VA_ARGS__) -u_char -route_distance (int type) +u_char route_distance(int type)  { -  u_char distance; +	u_char distance; -  if ((unsigned)type >= array_size(route_info)) -    distance = 150; -  else -    distance = route_info[type].distance; +	if ((unsigned)type >= array_size(route_info)) +		distance = 150; +	else +		distance = route_info[type].distance; -  return distance; +	return distance;  } -int -is_zebra_valid_kernel_table(u_int32_t table_id) +int is_zebra_valid_kernel_table(u_int32_t table_id)  { -  if ((table_id > ZEBRA_KERNEL_TABLE_MAX)) -    return 0; +	if ((table_id > ZEBRA_KERNEL_TABLE_MAX)) +		return 0;  #ifdef linux -  if ((table_id == RT_TABLE_UNSPEC) || -      (table_id == RT_TABLE_LOCAL) || -      (table_id == RT_TABLE_COMPAT)) -    return 0; +	if ((table_id == RT_TABLE_UNSPEC) || (table_id == RT_TABLE_LOCAL) +	    || (table_id == RT_TABLE_COMPAT)) +		return 0;  #endif -  return 1; +	return 1;  } -int -is_zebra_main_routing_table(u_int32_t table_id) +int is_zebra_main_routing_table(u_int32_t table_id)  { -  if ((table_id == RT_TABLE_MAIN) || (table_id == zebrad.rtm_table_default)) -    return 1; -  return 0; +	if ((table_id == RT_TABLE_MAIN) +	    || (table_id == zebrad.rtm_table_default)) +		return 1; +	return 0;  } -int -zebra_check_addr (struct prefix *p) +int zebra_check_addr(struct prefix *p)  { -  if (p->family == AF_INET) -    { -      u_int32_t addr; +	if (p->family == AF_INET) { +		u_int32_t addr; -      addr = p->u.prefix4.s_addr; -      addr = ntohl (addr); +		addr = p->u.prefix4.s_addr; +		addr = ntohl(addr); -      if (IPV4_NET127 (addr) -          || IN_CLASSD (addr) -          || IPV4_LINKLOCAL(addr)) -	return 0; -    } -  if (p->family == AF_INET6) -    { -      if (IN6_IS_ADDR_LOOPBACK (&p->u.prefix6)) -	return 0; -      if (IN6_IS_ADDR_LINKLOCAL(&p->u.prefix6)) -	return 0; -    } -  return 1; +		if (IPV4_NET127(addr) || IN_CLASSD(addr) +		    || IPV4_LINKLOCAL(addr)) +			return 0; +	} +	if (p->family == AF_INET6) { +		if (IN6_IS_ADDR_LOOPBACK(&p->u.prefix6)) +			return 0; +		if (IN6_IS_ADDR_LINKLOCAL(&p->u.prefix6)) +			return 0; +	} +	return 1;  }  /* Add nexthop to the end of a rib node's nexthop list */ -void -rib_nexthop_add (struct rib *rib, struct nexthop *nexthop) +void rib_nexthop_add(struct rib *rib, struct nexthop *nexthop)  { -  nexthop_add(&rib->nexthop, nexthop); -  rib->nexthop_num++; +	nexthop_add(&rib->nexthop, nexthop); +	rib->nexthop_num++;  } -  /**   * copy_nexthop - copy a nexthop to the rib structure.   */ -void -rib_copy_nexthops (struct rib *rib, struct nexthop *nh) +void rib_copy_nexthops(struct rib *rib, struct nexthop *nh)  { -  struct nexthop *nexthop; +	struct nexthop *nexthop; -  nexthop = nexthop_new(); -  nexthop->flags = nh->flags; -  nexthop->type = nh->type; -  nexthop->ifindex = nh->ifindex; -  memcpy(&(nexthop->gate), &(nh->gate), sizeof(union g_addr)); -  memcpy(&(nexthop->src), &(nh->src), sizeof(union g_addr)); -  if (nh->nh_label) -    nexthop_add_labels (nexthop, nh->nh_label_type, nh->nh_label->num_labels, -                        &nh->nh_label->label[0]); -  rib_nexthop_add(rib, nexthop); -  if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_RECURSIVE)) -    copy_nexthops(&nexthop->resolved, nh->resolved); +	nexthop = nexthop_new(); +	nexthop->flags = nh->flags; +	nexthop->type = nh->type; +	nexthop->ifindex = nh->ifindex; +	memcpy(&(nexthop->gate), &(nh->gate), sizeof(union g_addr)); +	memcpy(&(nexthop->src), &(nh->src), sizeof(union g_addr)); +	if (nh->nh_label) +		nexthop_add_labels(nexthop, nh->nh_label_type, +				   nh->nh_label->num_labels, +				   &nh->nh_label->label[0]); +	rib_nexthop_add(rib, nexthop); +	if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_RECURSIVE)) +		copy_nexthops(&nexthop->resolved, nh->resolved);  }  /* Delete specified nexthop from the list. */ -void -rib_nexthop_delete (struct rib *rib, struct nexthop *nexthop) +void rib_nexthop_delete(struct rib *rib, struct nexthop *nexthop)  { -  if (nexthop->next) -    nexthop->next->prev = nexthop->prev; -  if (nexthop->prev) -    nexthop->prev->next = nexthop->next; -  else -    rib->nexthop = nexthop->next; -  rib->nexthop_num--; +	if (nexthop->next) +		nexthop->next->prev = nexthop->prev; +	if (nexthop->prev) +		nexthop->prev->next = nexthop->next; +	else +		rib->nexthop = nexthop->next; +	rib->nexthop_num--;  } - -struct nexthop * -rib_nexthop_ifindex_add (struct rib *rib, ifindex_t ifindex) +struct nexthop *rib_nexthop_ifindex_add(struct rib *rib, ifindex_t ifindex)  { -  struct nexthop *nexthop; +	struct nexthop *nexthop; -  nexthop = nexthop_new(); -  nexthop->type = NEXTHOP_TYPE_IFINDEX; -  nexthop->ifindex = ifindex; +	nexthop = nexthop_new(); +	nexthop->type = NEXTHOP_TYPE_IFINDEX; +	nexthop->ifindex = ifindex; -  rib_nexthop_add (rib, nexthop); +	rib_nexthop_add(rib, nexthop); -  return nexthop; +	return nexthop;  } -struct nexthop * -rib_nexthop_ipv4_add (struct rib *rib, struct in_addr *ipv4, struct in_addr *src) +struct nexthop *rib_nexthop_ipv4_add(struct rib *rib, struct in_addr *ipv4, +				     struct in_addr *src)  { -  struct nexthop *nexthop; +	struct nexthop *nexthop; -  nexthop = nexthop_new(); -  nexthop->type = NEXTHOP_TYPE_IPV4; -  nexthop->gate.ipv4 = *ipv4; -  if (src) -    nexthop->src.ipv4 = *src; +	nexthop = nexthop_new(); +	nexthop->type = NEXTHOP_TYPE_IPV4; +	nexthop->gate.ipv4 = *ipv4; +	if (src) +		nexthop->src.ipv4 = *src; -  rib_nexthop_add (rib, nexthop); +	rib_nexthop_add(rib, nexthop); -  return nexthop; +	return nexthop;  } -struct nexthop * -rib_nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4, -			      struct in_addr *src, ifindex_t ifindex) +struct nexthop *rib_nexthop_ipv4_ifindex_add(struct rib *rib, +					     struct in_addr *ipv4, +					     struct in_addr *src, +					     ifindex_t ifindex)  { -  struct nexthop *nexthop; -  struct interface *ifp; +	struct nexthop *nexthop; +	struct interface *ifp; -  nexthop = nexthop_new(); -  nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX; -  nexthop->gate.ipv4 = *ipv4; -  if (src) -    nexthop->src.ipv4 = *src; -  nexthop->ifindex = ifindex; -  ifp = if_lookup_by_index (nexthop->ifindex, VRF_DEFAULT); -  /*Pending: need to think if null ifp here is ok during bootup? -    There was a crash because ifp here was coming to be NULL */ -  if (ifp) -  if (connected_is_unnumbered(ifp)) { -    SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK); -   } +	nexthop = nexthop_new(); +	nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX; +	nexthop->gate.ipv4 = *ipv4; +	if (src) +		nexthop->src.ipv4 = *src; +	nexthop->ifindex = ifindex; +	ifp = if_lookup_by_index(nexthop->ifindex, VRF_DEFAULT); +	/*Pending: need to think if null ifp here is ok during bootup? +	  There was a crash because ifp here was coming to be NULL */ +	if (ifp) +		if (connected_is_unnumbered(ifp)) { +			SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK); +		} -  rib_nexthop_add (rib, nexthop); +	rib_nexthop_add(rib, nexthop); -  return nexthop; +	return nexthop;  } -struct nexthop * -rib_nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6) +struct nexthop *rib_nexthop_ipv6_add(struct rib *rib, struct in6_addr *ipv6)  { -  struct nexthop *nexthop; +	struct nexthop *nexthop; -  nexthop = nexthop_new(); -  nexthop->type = NEXTHOP_TYPE_IPV6; -  nexthop->gate.ipv6 = *ipv6; +	nexthop = nexthop_new(); +	nexthop->type = NEXTHOP_TYPE_IPV6; +	nexthop->gate.ipv6 = *ipv6; -  rib_nexthop_add (rib, nexthop); +	rib_nexthop_add(rib, nexthop); -  return nexthop; +	return nexthop;  } -struct nexthop * -rib_nexthop_ipv6_ifindex_add (struct rib *rib, struct in6_addr *ipv6, -			      ifindex_t ifindex) +struct nexthop *rib_nexthop_ipv6_ifindex_add(struct rib *rib, +					     struct in6_addr *ipv6, +					     ifindex_t ifindex)  { -  struct nexthop *nexthop; +	struct nexthop *nexthop; -  nexthop = nexthop_new(); -  nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX; -  nexthop->gate.ipv6 = *ipv6; -  nexthop->ifindex = ifindex; +	nexthop = nexthop_new(); +	nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX; +	nexthop->gate.ipv6 = *ipv6; +	nexthop->ifindex = ifindex; -  rib_nexthop_add (rib, nexthop); +	rib_nexthop_add(rib, nexthop); -  return nexthop; +	return nexthop;  } -struct nexthop * -rib_nexthop_blackhole_add (struct rib *rib) +struct nexthop *rib_nexthop_blackhole_add(struct rib *rib)  { -  struct nexthop *nexthop; +	struct nexthop *nexthop; -  nexthop = nexthop_new(); -  nexthop->type = NEXTHOP_TYPE_BLACKHOLE; -  SET_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE); +	nexthop = nexthop_new(); +	nexthop->type = NEXTHOP_TYPE_BLACKHOLE; +	SET_FLAG(rib->flags, ZEBRA_FLAG_BLACKHOLE); -  rib_nexthop_add (rib, nexthop); +	rib_nexthop_add(rib, nexthop); -  return nexthop; +	return nexthop;  }  /* This method checks whether a recursive nexthop has at   * least one resolved nexthop in the fib.   */ -int -nexthop_has_fib_child(struct nexthop *nexthop) +int nexthop_has_fib_child(struct nexthop *nexthop)  { -  struct nexthop *nh; +	struct nexthop *nh; -  if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) -    return 0; +	if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) +		return 0; -  for (nh = nexthop->resolved; nh; nh = nh->next) -    if (CHECK_FLAG (nh->flags, NEXTHOP_FLAG_FIB)) -      return 1; +	for (nh = nexthop->resolved; nh; nh = nh->next) +		if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_FIB)) +			return 1; -  return 0; +	return 0;  }  /* If force flag is not set, do not modify falgs at all for uninstall     the route from FIB. */ -static int -nexthop_active (afi_t afi, struct rib *rib, struct nexthop *nexthop, int set, -		struct route_node *top) -{ -  struct prefix p; -  struct route_table *table; -  struct route_node *rn; -  struct rib *match; -  int resolved; -  struct nexthop *newhop, *tnewhop; -  struct nexthop *resolved_hop; -  int recursing = 0; -  struct interface *ifp; - -  if ((nexthop->type == NEXTHOP_TYPE_IPV4) || nexthop->type == NEXTHOP_TYPE_IPV6) -    nexthop->ifindex = 0; - -  if (set) -    { -      UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE); -      zebra_deregister_rnh_static_nexthops(rib->vrf_id, nexthop->resolved, top); -      nexthops_free(nexthop->resolved); -      nexthop->resolved = NULL; -      rib->nexthop_mtu = 0; -    } - -  /* Skip nexthops that have been filtered out due to route-map */ -  /* The nexthops are specific to this route and so the same */ -  /* nexthop for a different route may not have this flag set */ -  if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FILTERED)) -    return 0; - -  /* -   * Check to see if we should trust the passed in information -   * for UNNUMBERED interfaces as that we won't find the GW -   * address in the routing table. -   */ -  if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)) -    { -      ifp = if_lookup_by_index (nexthop->ifindex, VRF_DEFAULT); -      if (ifp && connected_is_unnumbered(ifp)) -	{ -	  if (if_is_operative(ifp)) -	    return 1; -	  else -	    return 0; +static int nexthop_active(afi_t afi, struct rib *rib, struct nexthop *nexthop, +			  int set, struct route_node *top) +{ +	struct prefix p; +	struct route_table *table; +	struct route_node *rn; +	struct rib *match; +	int resolved; +	struct nexthop *newhop, *tnewhop; +	struct nexthop *resolved_hop; +	int recursing = 0; +	struct interface *ifp; + +	if ((nexthop->type == NEXTHOP_TYPE_IPV4) +	    || nexthop->type == NEXTHOP_TYPE_IPV6) +		nexthop->ifindex = 0; + +	if (set) { +		UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE); +		zebra_deregister_rnh_static_nexthops(rib->vrf_id, +						     nexthop->resolved, top); +		nexthops_free(nexthop->resolved); +		nexthop->resolved = NULL; +		rib->nexthop_mtu = 0;  	} -      else -	return 0; -    } - -  /* Make lookup prefix. */ -  memset (&p, 0, sizeof (struct prefix)); -  switch (afi) -    { -    case AFI_IP: -      p.family = AF_INET; -      p.prefixlen = IPV4_MAX_PREFIXLEN; -      p.u.prefix4 = nexthop->gate.ipv4; -      break; -    case AFI_IP6: -      p.family = AF_INET6; -      p.prefixlen = IPV6_MAX_PREFIXLEN; -      p.u.prefix6 = nexthop->gate.ipv6; -      break; -    default: -      assert (afi != AFI_IP && afi != AFI_IP6); -      break; -    } -  /* Lookup table.  */ -  table = zebra_vrf_table (afi, SAFI_UNICAST, rib->vrf_id); -  if (! table) -    return 0; - -  rn = route_node_match (table, (struct prefix *) &p); -  while (rn) -    { -      route_unlock_node (rn); -       -      /* If lookup self prefix return immediately. */ -      if (rn == top) -	return 0; - -      /* Pick up selected route. */ -      /* However, do not resolve over default route unless explicitly allowed. */ -      if (is_default_prefix (&rn->p) && -          !nh_resolve_via_default (p.family)) -        return 0; -      RNODE_FOREACH_RIB (rn, match) -	{ -	  if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED)) -	    continue; - -          /* if the next hop is imported from another table, skip it */ -          if (match->type == ZEBRA_ROUTE_TABLE) -            continue; -	  if (CHECK_FLAG (match->status, RIB_ENTRY_SELECTED_FIB)) -	    break; +	/* Skip nexthops that have been filtered out due to route-map */ +	/* The nexthops are specific to this route and so the same */ +	/* nexthop for a different route may not have this flag set */ +	if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FILTERED)) +		return 0; + +	/* +	 * Check to see if we should trust the passed in information +	 * for UNNUMBERED interfaces as that we won't find the GW +	 * address in the routing table. +	 */ +	if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)) { +		ifp = if_lookup_by_index(nexthop->ifindex, VRF_DEFAULT); +		if (ifp && connected_is_unnumbered(ifp)) { +			if (if_is_operative(ifp)) +				return 1; +			else +				return 0; +		} else +			return 0;  	} -      /* If there is no selected route or matched route is EGP, go up -         tree. */ -      if (! match) -	{ -	  do { -	    rn = rn->parent; -	  } while (rn && rn->info == NULL); -	  if (rn) -	    route_lock_node (rn); +	/* Make lookup prefix. */ +	memset(&p, 0, sizeof(struct prefix)); +	switch (afi) { +	case AFI_IP: +		p.family = AF_INET; +		p.prefixlen = IPV4_MAX_PREFIXLEN; +		p.u.prefix4 = nexthop->gate.ipv4; +		break; +	case AFI_IP6: +		p.family = AF_INET6; +		p.prefixlen = IPV6_MAX_PREFIXLEN; +		p.u.prefix6 = nexthop->gate.ipv6; +		break; +	default: +		assert(afi != AFI_IP && afi != AFI_IP6); +		break;  	} -      else -	{ -	  /* If the longest prefix match for the nexthop yields -	   * a blackhole, mark it as inactive. */ -	  if (CHECK_FLAG (match->flags, ZEBRA_FLAG_BLACKHOLE) -	      || CHECK_FLAG (match->flags, ZEBRA_FLAG_REJECT)) -	    return 0; - -	  if (match->type == ZEBRA_ROUTE_CONNECT) -	    { -	      /* Directly point connected route. */ -	      newhop = match->nexthop; -	      if (newhop) +	/* Lookup table.  */ +	table = zebra_vrf_table(afi, SAFI_UNICAST, rib->vrf_id); +	if (!table) +		return 0; + +	rn = route_node_match(table, (struct prefix *)&p); +	while (rn) { +		route_unlock_node(rn); + +		/* If lookup self prefix return immediately. */ +		if (rn == top) +			return 0; + +		/* Pick up selected route. */ +		/* However, do not resolve over default route unless explicitly +		 * allowed. */ +		if (is_default_prefix(&rn->p) +		    && !nh_resolve_via_default(p.family)) +			return 0; + +		RNODE_FOREACH_RIB(rn, match)  		{ -                  if (nexthop->type == NEXTHOP_TYPE_IPV4 || -                      nexthop->type == NEXTHOP_TYPE_IPV6) -                    nexthop->ifindex = newhop->ifindex; +			if (CHECK_FLAG(match->status, RIB_ENTRY_REMOVED)) +				continue; + +			/* if the next hop is imported from another table, skip +			 * it */ +			if (match->type == ZEBRA_ROUTE_TABLE) +				continue; +			if (CHECK_FLAG(match->status, RIB_ENTRY_SELECTED_FIB)) +				break;  		} -	      return 1; -	    } -	  else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL)) -	    { -	      resolved = 0; -	      for (newhop = match->nexthop; newhop; newhop = newhop->next) -		if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB) -		    && ! CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_RECURSIVE)) -		  { -		    if (set) -		      { -			SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE); -			SET_FLAG(rib->status, RIB_ENTRY_NEXTHOPS_CHANGED); -			resolved_hop = nexthop_new(); -			SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE); -			/* If the resolving route specifies a gateway, use it */ -			if (newhop->type == NEXTHOP_TYPE_IPV4 -			    || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX) -			  { -			    resolved_hop->type = newhop->type; -			    resolved_hop->gate.ipv4 = newhop->gate.ipv4; - -			    if (newhop->ifindex) -			      { -				resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX; -				resolved_hop->ifindex = newhop->ifindex; -				if (newhop->flags & NEXTHOP_FLAG_ONLINK) -				  resolved_hop->flags |= NEXTHOP_FLAG_ONLINK; -			      } -			  } -			if (newhop->type == NEXTHOP_TYPE_IPV6 -			    || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX) -			  { -			    resolved_hop->type = newhop->type; -			    resolved_hop->gate.ipv6 = newhop->gate.ipv6; - -			    if (newhop->ifindex) -			      { -				resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX; -				resolved_hop->ifindex = newhop->ifindex; -			      } -			  } - -			/* If the resolving route is an interface route, -			 * it means the gateway we are looking up is connected -			 * to that interface. (The actual network is _not_ onlink). -			 * Therefore, the resolved route should have the original -			 * gateway as nexthop as it is directly connected. -			 * -			 * On Linux, we have to set the onlink netlink flag because -			 * otherwise, the kernel won't accept the route. */ -			if (newhop->type == NEXTHOP_TYPE_IFINDEX) -			  { -			    resolved_hop->flags |= NEXTHOP_FLAG_ONLINK; -			    if (afi == AFI_IP) -			      { -				resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX; -				resolved_hop->gate.ipv4 = nexthop->gate.ipv4; -			      } -			    else if (afi == AFI_IP6) -			      { -				resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX; -				resolved_hop->gate.ipv6 = nexthop->gate.ipv6; -			      } -			    resolved_hop->ifindex = newhop->ifindex; -			  } - -			nexthop_add(&nexthop->resolved, resolved_hop); -		      } -		    resolved = 1; -		  } -	      return resolved; -	    } -	  else if (rib->type == ZEBRA_ROUTE_STATIC) -	    { -	      resolved = 0; -	      for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing)) -		if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)) -		  { -		    if (set) -		      { -			SET_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE); - -			resolved_hop = nexthop_new(); -			SET_FLAG (resolved_hop->flags, NEXTHOP_FLAG_ACTIVE); -			/* If the resolving route specifies a gateway, use it */ -			if (newhop->type == NEXTHOP_TYPE_IPV4 -			    || newhop->type == NEXTHOP_TYPE_IPV4_IFINDEX) -			  { -			    resolved_hop->type = newhop->type; -			    resolved_hop->gate.ipv4 = newhop->gate.ipv4; - -			    if (newhop->ifindex) -			      { -				resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX; -				resolved_hop->ifindex = newhop->ifindex; -				if (newhop->flags & NEXTHOP_FLAG_ONLINK) -				  resolved_hop->flags |= NEXTHOP_FLAG_ONLINK; -			      } -			  } -			if (newhop->type == NEXTHOP_TYPE_IPV6 -			    || newhop->type == NEXTHOP_TYPE_IPV6_IFINDEX) -			  { -			    resolved_hop->type = newhop->type; -			    resolved_hop->gate.ipv6 = newhop->gate.ipv6; - -			    if (newhop->ifindex) -			      { -				resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX; -				resolved_hop->ifindex = newhop->ifindex; -			      } -			  } - -			/* If the resolving route is an interface route, -			 * it means the gateway we are looking up is connected -			 * to that interface. (The actual network is _not_ onlink). -			 * Therefore, the resolved route should have the original -			 * gateway as nexthop as it is directly connected. -			 * -			 * On Linux, we have to set the onlink netlink flag because -			 * otherwise, the kernel won't accept the route. -			 */ -			if (newhop->type == NEXTHOP_TYPE_IFINDEX) -			  { -			    resolved_hop->flags |= NEXTHOP_FLAG_ONLINK; -			    if (afi == AFI_IP) -			      { -				resolved_hop->type = NEXTHOP_TYPE_IPV4_IFINDEX; -				resolved_hop->gate.ipv4 = nexthop->gate.ipv4; -			      } -			    else if (afi == AFI_IP6) -			      { -				resolved_hop->type = NEXTHOP_TYPE_IPV6_IFINDEX; -				resolved_hop->gate.ipv6 = nexthop->gate.ipv6; -			      } -			    resolved_hop->ifindex = newhop->ifindex; -			  } - -			nexthop_add(&nexthop->resolved, resolved_hop); -		      } -		    resolved = 1; -		  } -              if (resolved && set) -                rib->nexthop_mtu = match->mtu; -	      return resolved; -	    } -	  else -	    { -	      return 0; -	    } +		/* If there is no selected route or matched route is EGP, go up +		   tree. */ +		if (!match) { +			do { +				rn = rn->parent; +			} while (rn && rn->info == NULL); +			if (rn) +				route_lock_node(rn); +		} else { +			/* If the longest prefix match for the nexthop yields +			 * a blackhole, mark it as inactive. */ +			if (CHECK_FLAG(match->flags, ZEBRA_FLAG_BLACKHOLE) +			    || CHECK_FLAG(match->flags, ZEBRA_FLAG_REJECT)) +				return 0; + +			if (match->type == ZEBRA_ROUTE_CONNECT) { +				/* Directly point connected route. */ +				newhop = match->nexthop; +				if (newhop) { +					if (nexthop->type == NEXTHOP_TYPE_IPV4 +					    || nexthop->type +						       == NEXTHOP_TYPE_IPV6) +						nexthop->ifindex = +							newhop->ifindex; +				} +				return 1; +			} else if (CHECK_FLAG(rib->flags, +					      ZEBRA_FLAG_INTERNAL)) { +				resolved = 0; +				for (newhop = match->nexthop; newhop; +				     newhop = newhop->next) +					if (CHECK_FLAG(newhop->flags, +						       NEXTHOP_FLAG_FIB) +					    && !CHECK_FLAG( +						       newhop->flags, +						       NEXTHOP_FLAG_RECURSIVE)) { +						if (set) { +							SET_FLAG( +								nexthop->flags, +								NEXTHOP_FLAG_RECURSIVE); +							SET_FLAG( +								rib->status, +								RIB_ENTRY_NEXTHOPS_CHANGED); + +							resolved_hop = +								nexthop_new(); +							SET_FLAG( +								resolved_hop +									->flags, +								NEXTHOP_FLAG_ACTIVE); +							/* If the resolving +							 * route specifies a +							 * gateway, use it */ +							if (newhop->type +								    == NEXTHOP_TYPE_IPV4 +							    || newhop->type +								       == NEXTHOP_TYPE_IPV4_IFINDEX) { +								resolved_hop +									->type = +									newhop->type; +								resolved_hop +									->gate +									.ipv4 = +									newhop->gate +										.ipv4; + +								if (newhop->ifindex) { +									resolved_hop +										->type = +										NEXTHOP_TYPE_IPV4_IFINDEX; +									resolved_hop +										->ifindex = +										newhop->ifindex; +									if (newhop->flags +									    & NEXTHOP_FLAG_ONLINK) +										resolved_hop +											->flags |= +											NEXTHOP_FLAG_ONLINK; +								} +							} +							if (newhop->type +								    == NEXTHOP_TYPE_IPV6 +							    || newhop->type +								       == NEXTHOP_TYPE_IPV6_IFINDEX) { +								resolved_hop +									->type = +									newhop->type; +								resolved_hop +									->gate +									.ipv6 = +									newhop->gate +										.ipv6; + +								if (newhop->ifindex) { +									resolved_hop +										->type = +										NEXTHOP_TYPE_IPV6_IFINDEX; +									resolved_hop +										->ifindex = +										newhop->ifindex; +								} +							} + +							/* If the resolving +							 * route is an interface +							 * route, +							 * it means the gateway +							 * we are looking up is +							 * connected +							 * to that interface. +							 * (The actual network +							 * is _not_ onlink). +							 * Therefore, the +							 * resolved route should +							 * have the original +							 * gateway as nexthop as +							 * it is directly +							 * connected. +							 * +							 * On Linux, we have to +							 * set the onlink +							 * netlink flag because +							 * otherwise, the kernel +							 * won't accept the +							 * route. */ +							if (newhop->type +							    == NEXTHOP_TYPE_IFINDEX) { +								resolved_hop +									->flags |= +									NEXTHOP_FLAG_ONLINK; +								if (afi +								    == AFI_IP) { +									resolved_hop +										->type = +										NEXTHOP_TYPE_IPV4_IFINDEX; +									resolved_hop +										->gate +										.ipv4 = +										nexthop->gate +											.ipv4; +								} else if ( +									afi +									== AFI_IP6) { +									resolved_hop +										->type = +										NEXTHOP_TYPE_IPV6_IFINDEX; +									resolved_hop +										->gate +										.ipv6 = +										nexthop->gate +											.ipv6; +								} +								resolved_hop +									->ifindex = +									newhop->ifindex; +							} + +							nexthop_add( +								&nexthop->resolved, +								resolved_hop); +						} +						resolved = 1; +					} +				return resolved; +			} else if (rib->type == ZEBRA_ROUTE_STATIC) { +				resolved = 0; +				for (ALL_NEXTHOPS_RO(match->nexthop, newhop, +						     tnewhop, recursing)) +					if (CHECK_FLAG(newhop->flags, +						       NEXTHOP_FLAG_FIB)) { +						if (set) { +							SET_FLAG( +								nexthop->flags, +								NEXTHOP_FLAG_RECURSIVE); + +							resolved_hop = +								nexthop_new(); +							SET_FLAG( +								resolved_hop +									->flags, +								NEXTHOP_FLAG_ACTIVE); +							/* If the resolving +							 * route specifies a +							 * gateway, use it */ +							if (newhop->type +								    == NEXTHOP_TYPE_IPV4 +							    || newhop->type +								       == NEXTHOP_TYPE_IPV4_IFINDEX) { +								resolved_hop +									->type = +									newhop->type; +								resolved_hop +									->gate +									.ipv4 = +									newhop->gate +										.ipv4; + +								if (newhop->ifindex) { +									resolved_hop +										->type = +										NEXTHOP_TYPE_IPV4_IFINDEX; +									resolved_hop +										->ifindex = +										newhop->ifindex; +									if (newhop->flags +									    & NEXTHOP_FLAG_ONLINK) +										resolved_hop +											->flags |= +											NEXTHOP_FLAG_ONLINK; +								} +							} +							if (newhop->type +								    == NEXTHOP_TYPE_IPV6 +							    || newhop->type +								       == NEXTHOP_TYPE_IPV6_IFINDEX) { +								resolved_hop +									->type = +									newhop->type; +								resolved_hop +									->gate +									.ipv6 = +									newhop->gate +										.ipv6; + +								if (newhop->ifindex) { +									resolved_hop +										->type = +										NEXTHOP_TYPE_IPV6_IFINDEX; +									resolved_hop +										->ifindex = +										newhop->ifindex; +								} +							} + +							/* If the resolving +							 * route is an interface +							 * route, +							 * it means the gateway +							 * we are looking up is +							 * connected +							 * to that interface. +							 * (The actual network +							 * is _not_ onlink). +							 * Therefore, the +							 * resolved route should +							 * have the original +							 * gateway as nexthop as +							 * it is directly +							 * connected. +							 * +							 * On Linux, we have to +							 * set the onlink +							 * netlink flag because +							 * otherwise, the kernel +							 * won't accept the +							 * route. +							 */ +							if (newhop->type +							    == NEXTHOP_TYPE_IFINDEX) { +								resolved_hop +									->flags |= +									NEXTHOP_FLAG_ONLINK; +								if (afi +								    == AFI_IP) { +									resolved_hop +										->type = +										NEXTHOP_TYPE_IPV4_IFINDEX; +									resolved_hop +										->gate +										.ipv4 = +										nexthop->gate +											.ipv4; +								} else if ( +									afi +									== AFI_IP6) { +									resolved_hop +										->type = +										NEXTHOP_TYPE_IPV6_IFINDEX; +									resolved_hop +										->gate +										.ipv6 = +										nexthop->gate +											.ipv6; +								} +								resolved_hop +									->ifindex = +									newhop->ifindex; +							} + +							nexthop_add( +								&nexthop->resolved, +								resolved_hop); +						} +						resolved = 1; +					} +				if (resolved && set) +					rib->nexthop_mtu = match->mtu; +				return resolved; +			} else { +				return 0; +			} +		}  	} -    } -  return 0; +	return 0;  } -struct rib * -rib_match (afi_t afi, safi_t safi, vrf_id_t vrf_id, -	   union g_addr *addr, struct route_node **rn_out) -{ -  struct prefix p; -  struct route_table *table; -  struct route_node *rn; -  struct rib *match; -  struct nexthop *newhop, *tnewhop; -  int recursing; +struct rib *rib_match(afi_t afi, safi_t safi, vrf_id_t vrf_id, +		      union g_addr *addr, struct route_node **rn_out) +{ +	struct prefix p; +	struct route_table *table; +	struct route_node *rn; +	struct rib *match; +	struct nexthop *newhop, *tnewhop; +	int recursing; + +	/* Lookup table.  */ +	table = zebra_vrf_table(afi, safi, vrf_id); +	if (!table) +		return 0; + +	memset(&p, 0, sizeof(struct prefix)); +	p.family = afi; +	if (afi == AFI_IP) { +		p.u.prefix4 = addr->ipv4; +		p.prefixlen = IPV4_MAX_PREFIXLEN; +	} else { +		p.u.prefix6 = addr->ipv6; +		p.prefixlen = IPV6_MAX_PREFIXLEN; +	} -  /* Lookup table.  */ -  table = zebra_vrf_table (afi, safi, vrf_id); -  if (! table) -    return 0; +	rn = route_node_match(table, (struct prefix *)&p); -  memset (&p, 0, sizeof (struct prefix)); -  p.family = afi; -  if (afi == AFI_IP) -    { -      p.u.prefix4 = addr->ipv4; -      p.prefixlen = IPV4_MAX_PREFIXLEN; -    } -  else -    { -      p.u.prefix6 = addr->ipv6; -      p.prefixlen = IPV6_MAX_PREFIXLEN; -    } +	while (rn) { +		route_unlock_node(rn); -  rn = route_node_match (table, (struct prefix *) &p); +		/* Pick up selected route. */ +		RNODE_FOREACH_RIB(rn, match) +		{ +			if (CHECK_FLAG(match->status, RIB_ENTRY_REMOVED)) +				continue; +			if (CHECK_FLAG(match->status, RIB_ENTRY_SELECTED_FIB)) +				break; +		} -  while (rn) -    { -      route_unlock_node (rn); -       -      /* Pick up selected route. */ -      RNODE_FOREACH_RIB (rn, match) -	{ -	  if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED)) -	    continue; -	  if (CHECK_FLAG (match->status, RIB_ENTRY_SELECTED_FIB)) -	    break; +		/* If there is no selected route or matched route is EGP, go up +		   tree. */ +		if (!match) { +			do { +				rn = rn->parent; +			} while (rn && rn->info == NULL); +			if (rn) +				route_lock_node(rn); +		} else { +			if (match->type != ZEBRA_ROUTE_CONNECT) { +				int found = 0; +				for (ALL_NEXTHOPS_RO(match->nexthop, newhop, +						     tnewhop, recursing)) +					if (CHECK_FLAG(newhop->flags, +						       NEXTHOP_FLAG_FIB)) { +						found = 1; +						break; +					} +				if (!found) +					return NULL; +			} + +			if (rn_out) +				*rn_out = rn; +			return match; +		}  	} - -      /* If there is no selected route or matched route is EGP, go up -         tree. */ -      if (! match) -	{ -	  do { -	    rn = rn->parent; -	  } while (rn && rn->info == NULL); -	  if (rn) -	    route_lock_node (rn); +	return NULL; +} + +struct rib *rib_match_ipv4_multicast(vrf_id_t vrf_id, struct in_addr addr, +				     struct route_node **rn_out) +{ +	struct rib *rib = NULL, *mrib = NULL, *urib = NULL; +	struct route_node *m_rn = NULL, *u_rn = NULL; +	union g_addr gaddr = {.ipv4 = addr}; + +	switch (ipv4_multicast_mode) { +	case MCAST_MRIB_ONLY: +		return rib_match(AFI_IP, SAFI_MULTICAST, vrf_id, &gaddr, +				 rn_out); +	case MCAST_URIB_ONLY: +		return rib_match(AFI_IP, SAFI_UNICAST, vrf_id, &gaddr, rn_out); +	case MCAST_NO_CONFIG: +	case MCAST_MIX_MRIB_FIRST: +		rib = mrib = rib_match(AFI_IP, SAFI_MULTICAST, vrf_id, &gaddr, +				       &m_rn); +		if (!mrib) +			rib = urib = rib_match(AFI_IP, SAFI_UNICAST, vrf_id, +					       &gaddr, &u_rn); +		break; +	case MCAST_MIX_DISTANCE: +		mrib = rib_match(AFI_IP, SAFI_MULTICAST, vrf_id, &gaddr, &m_rn); +		urib = rib_match(AFI_IP, SAFI_UNICAST, vrf_id, &gaddr, &u_rn); +		if (mrib && urib) +			rib = urib->distance < mrib->distance ? urib : mrib; +		else if (mrib) +			rib = mrib; +		else if (urib) +			rib = urib; +		break; +	case MCAST_MIX_PFXLEN: +		mrib = rib_match(AFI_IP, SAFI_MULTICAST, vrf_id, &gaddr, &m_rn); +		urib = rib_match(AFI_IP, SAFI_UNICAST, vrf_id, &gaddr, &u_rn); +		if (mrib && urib) +			rib = u_rn->p.prefixlen > m_rn->p.prefixlen ? urib +								    : mrib; +		else if (mrib) +			rib = mrib; +		else if (urib) +			rib = urib; +		break;  	} -      else -	{ -	  if (match->type != ZEBRA_ROUTE_CONNECT) -	    { -	      int found = 0; -	      for (ALL_NEXTHOPS_RO(match->nexthop, newhop, tnewhop, recursing)) -		if (CHECK_FLAG (newhop->flags, NEXTHOP_FLAG_FIB)) -		  { -		    found = 1; -		    break; -		  } -	      if (!found) -		return NULL; -	    } -	  if (rn_out) -	    *rn_out = rn; -	  return match; -	} -    } -  return NULL; -} +	if (rn_out) +		*rn_out = (rib == mrib) ? m_rn : u_rn; -struct rib * -rib_match_ipv4_multicast (vrf_id_t vrf_id, struct in_addr addr, struct route_node **rn_out) -{ -  struct rib *rib = NULL, *mrib = NULL, *urib = NULL; -  struct route_node *m_rn = NULL, *u_rn = NULL; -  union g_addr gaddr = { .ipv4 = addr }; +	if (IS_ZEBRA_DEBUG_RIB) { +		char buf[BUFSIZ]; +		inet_ntop(AF_INET, &addr, buf, BUFSIZ); -  switch (ipv4_multicast_mode) -    { -    case MCAST_MRIB_ONLY: -      return rib_match (AFI_IP, SAFI_MULTICAST, vrf_id, &gaddr, rn_out); -    case MCAST_URIB_ONLY: -      return rib_match (AFI_IP, SAFI_UNICAST, vrf_id, &gaddr, rn_out); -    case MCAST_NO_CONFIG: -    case MCAST_MIX_MRIB_FIRST: -      rib = mrib = rib_match (AFI_IP, SAFI_MULTICAST, vrf_id, &gaddr, &m_rn); -      if (!mrib) -	rib = urib = rib_match (AFI_IP, SAFI_UNICAST, vrf_id, &gaddr, &u_rn); -      break; -    case MCAST_MIX_DISTANCE: -      mrib = rib_match (AFI_IP, SAFI_MULTICAST, vrf_id, &gaddr, &m_rn); -      urib = rib_match (AFI_IP, SAFI_UNICAST, vrf_id, &gaddr, &u_rn); -      if (mrib && urib) -	rib = urib->distance < mrib->distance ? urib : mrib; -      else if (mrib) -	rib = mrib; -      else if (urib) -	rib = urib; -      break; -    case MCAST_MIX_PFXLEN: -      mrib = rib_match (AFI_IP, SAFI_MULTICAST, vrf_id, &gaddr, &m_rn); -      urib = rib_match (AFI_IP, SAFI_UNICAST, vrf_id, &gaddr, &u_rn); -      if (mrib && urib) -	rib = u_rn->p.prefixlen > m_rn->p.prefixlen ? urib : mrib; -      else if (mrib) -	rib = mrib; -      else if (urib) -	rib = urib; -      break; -  } - -  if (rn_out) -    *rn_out = (rib == mrib) ? m_rn : u_rn; - -  if (IS_ZEBRA_DEBUG_RIB) -    { -      char buf[BUFSIZ]; -      inet_ntop (AF_INET, &addr, buf, BUFSIZ); - -      zlog_debug("%s: %s: found %s, using %s", -		 __func__, buf, -                 mrib ? (urib ? "MRIB+URIB" : "MRIB") : -                         urib ? "URIB" : "nothing", -		 rib == urib ? "URIB" : rib == mrib ? "MRIB" : "none"); -    } -  return rib; +		zlog_debug("%s: %s: found %s, using %s", __func__, buf, +			   mrib ? (urib ? "MRIB+URIB" : "MRIB") +				: urib ? "URIB" : "nothing", +			   rib == urib ? "URIB" +				       : rib == mrib ? "MRIB" : "none"); +	} +	return rib;  } -void -multicast_mode_ipv4_set (enum multicast_mode mode) +void multicast_mode_ipv4_set(enum multicast_mode mode)  { -  if (IS_ZEBRA_DEBUG_RIB) -    zlog_debug("%s: multicast lookup mode set (%d)", __func__, mode); -  ipv4_multicast_mode = mode; +	if (IS_ZEBRA_DEBUG_RIB) +		zlog_debug("%s: multicast lookup mode set (%d)", __func__, +			   mode); +	ipv4_multicast_mode = mode;  } -enum multicast_mode -multicast_mode_ipv4_get (void) +enum multicast_mode multicast_mode_ipv4_get(void)  { -  return ipv4_multicast_mode; +	return ipv4_multicast_mode;  } -struct rib * -rib_lookup_ipv4 (struct prefix_ipv4 *p, vrf_id_t vrf_id) +struct rib *rib_lookup_ipv4(struct prefix_ipv4 *p, vrf_id_t vrf_id)  { -  struct route_table *table; -  struct route_node *rn; -  struct rib *match; -  struct nexthop *nexthop, *tnexthop; -  int recursing; +	struct route_table *table; +	struct route_node *rn; +	struct rib *match; +	struct nexthop *nexthop, *tnexthop; +	int recursing; -  /* Lookup table.  */ -  table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id); -  if (! table) -    return 0; +	/* Lookup table.  */ +	table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id); +	if (!table) +		return 0; -  rn = route_node_lookup (table, (struct prefix *) p); +	rn = route_node_lookup(table, (struct prefix *)p); -  /* No route for this prefix. */ -  if (! rn) -    return NULL; +	/* No route for this prefix. */ +	if (!rn) +		return NULL; -  /* Unlock node. */ -  route_unlock_node (rn); +	/* Unlock node. */ +	route_unlock_node(rn); -  RNODE_FOREACH_RIB (rn, match) -    { -      if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED)) -	continue; -      if (CHECK_FLAG (match->status, RIB_ENTRY_SELECTED_FIB)) -	break; -    } +	RNODE_FOREACH_RIB(rn, match) +	{ +		if (CHECK_FLAG(match->status, RIB_ENTRY_REMOVED)) +			continue; +		if (CHECK_FLAG(match->status, RIB_ENTRY_SELECTED_FIB)) +			break; +	} + +	if (!match) +		return NULL; -  if (! match) -    return NULL; +	if (match->type == ZEBRA_ROUTE_CONNECT) +		return match; -  if (match->type == ZEBRA_ROUTE_CONNECT) -    return match; -   -  for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing)) -    if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) -      return match; +	for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing)) +		if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)) +			return match; -  return NULL; +	return NULL;  }  /* @@ -840,74 +933,77 @@ rib_lookup_ipv4 (struct prefix_ipv4 *p, vrf_id_t vrf_id)   * 2: connected route found   * 3: no matches found   */ -int -rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate, -    vrf_id_t vrf_id) -{ -  struct route_table *table; -  struct route_node *rn; -  struct rib *match; -  struct nexthop *nexthop, *tnexthop; -  int recursing; -  int nexthops_active; - -  /* Lookup table.  */ -  table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id); -  if (! table) -    return ZEBRA_RIB_LOOKUP_ERROR; - -  /* Scan the RIB table for exactly matching RIB entry. */ -  rn = route_node_lookup (table, (struct prefix *) p); - -  /* No route for this prefix. */ -  if (! rn) -    return ZEBRA_RIB_NOTFOUND; - -  /* Unlock node. */ -  route_unlock_node (rn); - -  /* Find out if a "selected" RR for the discovered RIB entry exists ever. */ -  RNODE_FOREACH_RIB (rn, match) -    { -      if (CHECK_FLAG (match->status, RIB_ENTRY_REMOVED)) -	continue; -      if (CHECK_FLAG (match->status, RIB_ENTRY_SELECTED_FIB)) -	break; -    } +int rib_lookup_ipv4_route(struct prefix_ipv4 *p, union sockunion *qgate, +			  vrf_id_t vrf_id) +{ +	struct route_table *table; +	struct route_node *rn; +	struct rib *match; +	struct nexthop *nexthop, *tnexthop; +	int recursing; +	int nexthops_active; + +	/* Lookup table.  */ +	table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id); +	if (!table) +		return ZEBRA_RIB_LOOKUP_ERROR; + +	/* Scan the RIB table for exactly matching RIB entry. */ +	rn = route_node_lookup(table, (struct prefix *)p); + +	/* No route for this prefix. */ +	if (!rn) +		return ZEBRA_RIB_NOTFOUND; + +	/* Unlock node. */ +	route_unlock_node(rn); + +	/* Find out if a "selected" RR for the discovered RIB entry exists ever. +	 */ +	RNODE_FOREACH_RIB(rn, match) +	{ +		if (CHECK_FLAG(match->status, RIB_ENTRY_REMOVED)) +			continue; +		if (CHECK_FLAG(match->status, RIB_ENTRY_SELECTED_FIB)) +			break; +	} + +	/* None such found :( */ +	if (!match) +		return ZEBRA_RIB_NOTFOUND; + +	if (match->type == ZEBRA_ROUTE_CONNECT) +		return ZEBRA_RIB_FOUND_CONNECTED; + +	/* Ok, we have a cood candidate, let's check it's nexthop list... */ +	nexthops_active = 0; +	for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing)) +		if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)) { +			nexthops_active = 1; +			if (nexthop->gate.ipv4.s_addr == sockunion2ip(qgate)) +				return ZEBRA_RIB_FOUND_EXACT; +			if (IS_ZEBRA_DEBUG_RIB) { +				char gate_buf[INET_ADDRSTRLEN], +					qgate_buf[INET_ADDRSTRLEN]; +				inet_ntop(AF_INET, &nexthop->gate.ipv4.s_addr, +					  gate_buf, INET_ADDRSTRLEN); +				inet_ntop(AF_INET, &sockunion2ip(qgate), +					  qgate_buf, INET_ADDRSTRLEN); +				zlog_debug("%s: qgate == %s, %s == %s", +					   __func__, qgate_buf, +					   recursing ? "rgate" : "gate", +					   gate_buf); +			} +		} + +	if (nexthops_active) +		return ZEBRA_RIB_FOUND_NOGATE; + +	return ZEBRA_RIB_NOTFOUND; +} -  /* None such found :( */ -  if (!match) -    return ZEBRA_RIB_NOTFOUND; - -  if (match->type == ZEBRA_ROUTE_CONNECT) -    return ZEBRA_RIB_FOUND_CONNECTED; -   -  /* Ok, we have a cood candidate, let's check it's nexthop list... */ -  nexthops_active = 0; -  for (ALL_NEXTHOPS_RO(match->nexthop, nexthop, tnexthop, recursing)) -    if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) -      { -        nexthops_active = 1; -        if (nexthop->gate.ipv4.s_addr == sockunion2ip (qgate)) -          return ZEBRA_RIB_FOUND_EXACT; -        if (IS_ZEBRA_DEBUG_RIB) -          { -            char gate_buf[INET_ADDRSTRLEN], qgate_buf[INET_ADDRSTRLEN]; -            inet_ntop (AF_INET, &nexthop->gate.ipv4.s_addr, gate_buf, INET_ADDRSTRLEN); -            inet_ntop (AF_INET, &sockunion2ip(qgate), qgate_buf, INET_ADDRSTRLEN); -            zlog_debug ("%s: qgate == %s, %s == %s", __func__, -                        qgate_buf, recursing ? "rgate" : "gate", gate_buf); -          } -      } - -  if (nexthops_active) -    return ZEBRA_RIB_FOUND_NOGATE; - -  return ZEBRA_RIB_NOTFOUND; -} - -#define RIB_SYSTEM_ROUTE(R) \ -        ((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT) +#define RIB_SYSTEM_ROUTE(R)                                                    \ +	((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)  /* This function verifies reachability of one given nexthop, which can be   * numbered or unnumbered, IPv4 or IPv6. The result is unconditionally stored @@ -919,114 +1015,106 @@ rib_lookup_ipv4_route (struct prefix_ipv4 *p, union sockunion * qgate,   * The return value is the final value of 'ACTIVE' flag.   */ -static unsigned -nexthop_active_check (struct route_node *rn, struct rib *rib, -		      struct nexthop *nexthop, int set) -{ -  struct interface *ifp; -  route_map_result_t ret = RMAP_MATCH; -  int family; -  char buf[SRCDEST2STR_BUFFER]; -  struct prefix *p, *src_p; -  srcdest_rnode_prefixes (rn, &p, &src_p); - -  if (rn->p.family == AF_INET) -    family = AFI_IP; -  else if (rn->p.family == AF_INET6) -    family = AFI_IP6; -  else -    family = 0; -  switch (nexthop->type) -    { -    case NEXTHOP_TYPE_IFINDEX: -      ifp = if_lookup_by_index (nexthop->ifindex, rib->vrf_id); -      if (ifp && if_is_operative(ifp)) -	SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); -      else -	UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); -      break; -    case NEXTHOP_TYPE_IPV4: -    case NEXTHOP_TYPE_IPV4_IFINDEX: -      family = AFI_IP; -      if (nexthop_active (AFI_IP, rib, nexthop, set, rn)) -	SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); -      else -	UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); -      break; -    case NEXTHOP_TYPE_IPV6: -      family = AFI_IP6; -      if (nexthop_active (AFI_IP6, rib, nexthop, set, rn)) -	SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); -      else -	UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); -      break; -    case NEXTHOP_TYPE_IPV6_IFINDEX: -      /* RFC 5549, v4 prefix with v6 NH */ -      if (rn->p.family != AF_INET) -	family = AFI_IP6; -      if (IN6_IS_ADDR_LINKLOCAL (&nexthop->gate.ipv6)) -	{ -	  ifp = if_lookup_by_index (nexthop->ifindex, rib->vrf_id); -	  if (ifp && if_is_operative(ifp)) -	    SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); -	  else -	    UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); +static unsigned nexthop_active_check(struct route_node *rn, struct rib *rib, +				     struct nexthop *nexthop, int set) +{ +	struct interface *ifp; +	route_map_result_t ret = RMAP_MATCH; +	int family; +	char buf[SRCDEST2STR_BUFFER]; +	struct prefix *p, *src_p; +	srcdest_rnode_prefixes(rn, &p, &src_p); + +	if (rn->p.family == AF_INET) +		family = AFI_IP; +	else if (rn->p.family == AF_INET6) +		family = AFI_IP6; +	else +		family = 0; +	switch (nexthop->type) { +	case NEXTHOP_TYPE_IFINDEX: +		ifp = if_lookup_by_index(nexthop->ifindex, rib->vrf_id); +		if (ifp && if_is_operative(ifp)) +			SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); +		else +			UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); +		break; +	case NEXTHOP_TYPE_IPV4: +	case NEXTHOP_TYPE_IPV4_IFINDEX: +		family = AFI_IP; +		if (nexthop_active(AFI_IP, rib, nexthop, set, rn)) +			SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); +		else +			UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); +		break; +	case NEXTHOP_TYPE_IPV6: +		family = AFI_IP6; +		if (nexthop_active(AFI_IP6, rib, nexthop, set, rn)) +			SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); +		else +			UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); +		break; +	case NEXTHOP_TYPE_IPV6_IFINDEX: +		/* RFC 5549, v4 prefix with v6 NH */ +		if (rn->p.family != AF_INET) +			family = AFI_IP6; +		if (IN6_IS_ADDR_LINKLOCAL(&nexthop->gate.ipv6)) { +			ifp = if_lookup_by_index(nexthop->ifindex, rib->vrf_id); +			if (ifp && if_is_operative(ifp)) +				SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); +			else +				UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); +		} else { +			if (nexthop_active(AFI_IP6, rib, nexthop, set, rn)) +				SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); +			else +				UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); +		} +		break; +	case NEXTHOP_TYPE_BLACKHOLE: +		SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); +		break; +	default: +		break; +	} +	if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) +		return 0; + +	/* XXX: What exactly do those checks do? Do we support +	 * e.g. IPv4 routes with IPv6 nexthops or vice versa? */ +	if (RIB_SYSTEM_ROUTE(rib) || (family == AFI_IP && p->family != AF_INET) +	    || (family == AFI_IP6 && p->family != AF_INET6)) +		return CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); + +	/* The original code didn't determine the family correctly +	 * e.g. for NEXTHOP_TYPE_IFINDEX. Retrieve the correct afi +	 * from the rib_table_info in those cases. +	 * Possibly it may be better to use only the rib_table_info +	 * in every case. +	 */ +	if (!family) { +		rib_table_info_t *info; + +		info = srcdest_rnode_table_info(rn); +		family = info->afi;  	} -      else -	{ -	  if (nexthop_active (AFI_IP6, rib, nexthop, set, rn)) -	    SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); -	  else -	    UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); -	} -      break; -    case NEXTHOP_TYPE_BLACKHOLE: -      SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); -      break; -    default: -      break; -    } -  if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) -    return 0; - -  /* XXX: What exactly do those checks do? Do we support -   * e.g. IPv4 routes with IPv6 nexthops or vice versa? */ -  if (RIB_SYSTEM_ROUTE(rib) || -      (family == AFI_IP && p->family != AF_INET) || -      (family == AFI_IP6 && p->family != AF_INET6)) -    return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); - -  /* The original code didn't determine the family correctly -   * e.g. for NEXTHOP_TYPE_IFINDEX. Retrieve the correct afi -   * from the rib_table_info in those cases. -   * Possibly it may be better to use only the rib_table_info -   * in every case. -   */ -  if (!family) -    { -      rib_table_info_t *info; - -      info = srcdest_rnode_table_info(rn); -      family = info->afi; -    } - -  memset(&nexthop->rmap_src.ipv6, 0, sizeof(union g_addr)); -  /* It'll get set if required inside */ -  ret = zebra_route_map_check(family, rib->type, p, nexthop, rib->vrf_id, -                              rib->tag); -  if (ret == RMAP_DENYMATCH) -    { -      if (IS_ZEBRA_DEBUG_RIB) -	{ -	  srcdest_rnode2str(rn, buf, sizeof(buf)); -	  zlog_debug("%u:%s: Filtering out with NH out %s due to route map", -		     rib->vrf_id, buf, -		     ifindex2ifname (nexthop->ifindex, rib->vrf_id)); +	memset(&nexthop->rmap_src.ipv6, 0, sizeof(union g_addr)); + +	/* It'll get set if required inside */ +	ret = zebra_route_map_check(family, rib->type, p, nexthop, rib->vrf_id, +				    rib->tag); +	if (ret == RMAP_DENYMATCH) { +		if (IS_ZEBRA_DEBUG_RIB) { +			srcdest_rnode2str(rn, buf, sizeof(buf)); +			zlog_debug( +				"%u:%s: Filtering out with NH out %s due to route map", +				rib->vrf_id, buf, +				ifindex2ifname(nexthop->ifindex, rib->vrf_id)); +		} +		UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);  	} -      UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); -    } -  return CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); +	return CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);  }  /* Iterate over all nexthops of the given RIB entry and refresh their @@ -1038,156 +1126,148 @@ nexthop_active_check (struct route_node *rn, struct rib *rib,   * Return value is the new number of active nexthops.   */ -static int -nexthop_active_update (struct route_node *rn, struct rib *rib, int set) -{ -  struct nexthop *nexthop; -  union g_addr prev_src; -  unsigned int prev_active, new_active, old_num_nh; -  ifindex_t prev_index; -  old_num_nh = rib->nexthop_active_num; - -  rib->nexthop_active_num = 0; -  UNSET_FLAG (rib->status, RIB_ENTRY_CHANGED); - -  for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) -  { -    /* No protocol daemon provides src and so we're skipping tracking it */ -    prev_src = nexthop->rmap_src; -    prev_active = CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); -    prev_index = nexthop->ifindex; -    if ((new_active = nexthop_active_check (rn, rib, nexthop, set))) -      rib->nexthop_active_num++; -    /* Don't allow src setting on IPv6 addr for now */ -    if (prev_active != new_active || -	prev_index != nexthop->ifindex || -	((nexthop->type >= NEXTHOP_TYPE_IFINDEX && -	  nexthop->type < NEXTHOP_TYPE_IPV6) && -	 prev_src.ipv4.s_addr != nexthop->rmap_src.ipv4.s_addr) || -	((nexthop->type >= NEXTHOP_TYPE_IPV6 && -	  nexthop->type < NEXTHOP_TYPE_BLACKHOLE) && -	 !(IPV6_ADDR_SAME (&prev_src.ipv6, &nexthop->rmap_src.ipv6)))) -      { -	SET_FLAG (rib->status, RIB_ENTRY_CHANGED); -	SET_FLAG (rib->status, RIB_ENTRY_NEXTHOPS_CHANGED); -      } -  } - -  if (old_num_nh != rib->nexthop_active_num) -    SET_FLAG (rib->status, RIB_ENTRY_CHANGED); - -  if (CHECK_FLAG (rib->status, RIB_ENTRY_CHANGED)) -    { -      SET_FLAG (rib->status, RIB_ENTRY_NEXTHOPS_CHANGED); -    } +static int nexthop_active_update(struct route_node *rn, struct rib *rib, +				 int set) +{ +	struct nexthop *nexthop; +	union g_addr prev_src; +	unsigned int prev_active, new_active, old_num_nh; +	ifindex_t prev_index; +	old_num_nh = rib->nexthop_active_num; + +	rib->nexthop_active_num = 0; +	UNSET_FLAG(rib->status, RIB_ENTRY_CHANGED); + +	for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) { +		/* No protocol daemon provides src and so we're skipping +		 * tracking it */ +		prev_src = nexthop->rmap_src; +		prev_active = CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); +		prev_index = nexthop->ifindex; +		if ((new_active = nexthop_active_check(rn, rib, nexthop, set))) +			rib->nexthop_active_num++; +		/* Don't allow src setting on IPv6 addr for now */ +		if (prev_active != new_active || prev_index != nexthop->ifindex +		    || ((nexthop->type >= NEXTHOP_TYPE_IFINDEX +			 && nexthop->type < NEXTHOP_TYPE_IPV6) +			&& prev_src.ipv4.s_addr +				   != nexthop->rmap_src.ipv4.s_addr) +		    || ((nexthop->type >= NEXTHOP_TYPE_IPV6 +			 && nexthop->type < NEXTHOP_TYPE_BLACKHOLE) +			&& !(IPV6_ADDR_SAME(&prev_src.ipv6, +					    &nexthop->rmap_src.ipv6)))) { +			SET_FLAG(rib->status, RIB_ENTRY_CHANGED); +			SET_FLAG(rib->status, RIB_ENTRY_NEXTHOPS_CHANGED); +		} +	} -  return rib->nexthop_active_num; -} +	if (old_num_nh != rib->nexthop_active_num) +		SET_FLAG(rib->status, RIB_ENTRY_CHANGED); + +	if (CHECK_FLAG(rib->status, RIB_ENTRY_CHANGED)) { +		SET_FLAG(rib->status, RIB_ENTRY_NEXTHOPS_CHANGED); +	} +	return rib->nexthop_active_num; +}  /* Update flag indicates whether this is a "replace" or not. Currently, this   * is only used for IPv4.   */ -int -rib_install_kernel (struct route_node *rn, struct rib *rib, struct rib *old) +int rib_install_kernel(struct route_node *rn, struct rib *rib, struct rib *old)  { -  int ret = 0; -  struct nexthop *nexthop, *tnexthop; -  rib_table_info_t *info = srcdest_rnode_table_info(rn); -  int recursing; -  struct prefix *p, *src_p; - -  srcdest_rnode_prefixes (rn, &p, &src_p); +	int ret = 0; +	struct nexthop *nexthop, *tnexthop; +	rib_table_info_t *info = srcdest_rnode_table_info(rn); +	int recursing; +	struct prefix *p, *src_p; -  if (info->safi != SAFI_UNICAST) -    { -      for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) -        SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); -      return ret; -    } +	srcdest_rnode_prefixes(rn, &p, &src_p); -  /* -   * Make sure we update the FPM any time we send new information to -   * the kernel. -   */ -  hook_call(rib_update, rn, "installing in kernel"); -  ret = kernel_route_rib (p, src_p, old, rib); +	if (info->safi != SAFI_UNICAST) { +		for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, +				     recursing)) +			SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); +		return ret; +	} -  /* If install succeeds, update FIB flag for nexthops. */ -  if (!ret) -    { -      for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) -        { -          if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) -            continue; - -          if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) -            SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); -          else -            UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); -        } -    } +	/* +	 * Make sure we update the FPM any time we send new information to +	 * the kernel. +	 */ +	hook_call(rib_update, rn, "installing in kernel"); +	ret = kernel_route_rib(p, src_p, old, rib); + +	/* If install succeeds, update FIB flag for nexthops. */ +	if (!ret) { +		for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, +				     recursing)) { +			if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) +				continue; + +			if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) +				SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); +			else +				UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); +		} +	} -  return ret; +	return ret;  }  /* Uninstall the route from kernel. */ -int -rib_uninstall_kernel (struct route_node *rn, struct rib *rib) +int rib_uninstall_kernel(struct route_node *rn, struct rib *rib)  { -  int ret = 0; -  struct nexthop *nexthop, *tnexthop; -  rib_table_info_t *info = srcdest_rnode_table_info(rn); -  int recursing; -  struct prefix *p, *src_p; +	int ret = 0; +	struct nexthop *nexthop, *tnexthop; +	rib_table_info_t *info = srcdest_rnode_table_info(rn); +	int recursing; +	struct prefix *p, *src_p; -  srcdest_rnode_prefixes (rn, &p, &src_p); +	srcdest_rnode_prefixes(rn, &p, &src_p); -  if (info->safi != SAFI_UNICAST) -    { -      for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) -        SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); -      return ret; -    } +	if (info->safi != SAFI_UNICAST) { +		for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, +				     recursing)) +			SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); +		return ret; +	} -  /* -   * Make sure we update the FPM any time we send new information to -   * the kernel. -   */ -  hook_call(rib_update, rn, "uninstalling from kernel"); -  ret = kernel_route_rib (p, src_p, rib, NULL); +	/* +	 * Make sure we update the FPM any time we send new information to +	 * the kernel. +	 */ +	hook_call(rib_update, rn, "uninstalling from kernel"); +	ret = kernel_route_rib(p, src_p, rib, NULL); -  for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) -    UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); +	for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) +		UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); -  return ret; +	return ret;  }  /* Uninstall the route from kernel. */ -static void -rib_uninstall (struct route_node *rn, struct rib *rib) +static void rib_uninstall(struct route_node *rn, struct rib *rib)  { -  rib_table_info_t *info = srcdest_rnode_table_info(rn); +	rib_table_info_t *info = srcdest_rnode_table_info(rn); -  if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB)) -    { -      if (info->safi == SAFI_UNICAST) -        hook_call(rib_update, rn, "rib_uninstall"); +	if (CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB)) { +		if (info->safi == SAFI_UNICAST) +			hook_call(rib_update, rn, "rib_uninstall"); -      if (! RIB_SYSTEM_ROUTE (rib)) -	rib_uninstall_kernel (rn, rib); -      UNSET_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB); -    } +		if (!RIB_SYSTEM_ROUTE(rib)) +			rib_uninstall_kernel(rn, rib); +		UNSET_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB); +	} -  if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) -    { -      struct prefix *p, *src_p; -      srcdest_rnode_prefixes (rn, &p, &src_p); +	if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED)) { +		struct prefix *p, *src_p; +		srcdest_rnode_prefixes(rn, &p, &src_p); -      redistribute_delete (p, src_p, rib); -      UNSET_FLAG (rib->flags, ZEBRA_FLAG_SELECTED); -    } +		redistribute_delete(p, src_p, rib); +		UNSET_FLAG(rib->flags, ZEBRA_FLAG_SELECTED); +	}  }  /* @@ -1195,23 +1275,21 @@ rib_uninstall (struct route_node *rn, struct rib *rib)   *   * Returns TRUE if the given dest can be deleted from the table.   */ -static int -rib_can_delete_dest (rib_dest_t *dest) +static int rib_can_delete_dest(rib_dest_t *dest)  { -  if (dest->routes) -    { -      return 0; -    } +	if (dest->routes) { +		return 0; +	} -  /* -   * Don't delete the dest if we have to update the FPM about this -   * prefix. -   */ -  if (CHECK_FLAG (dest->flags, RIB_DEST_UPDATE_FPM) || -      CHECK_FLAG (dest->flags, RIB_DEST_SENT_TO_FPM)) -    return 0; +	/* +	 * Don't delete the dest if we have to update the FPM about this +	 * prefix. +	 */ +	if (CHECK_FLAG(dest->flags, RIB_DEST_UPDATE_FPM) +	    || CHECK_FLAG(dest->flags, RIB_DEST_SENT_TO_FPM)) +		return 0; -  return 1; +	return 1;  }  /* @@ -1222,526 +1300,520 @@ rib_can_delete_dest (rib_dest_t *dest)   *   * Returns TRUE if the dest was deleted, FALSE otherwise.   */ -int -rib_gc_dest (struct route_node *rn) +int rib_gc_dest(struct route_node *rn)  { -  rib_dest_t *dest; -  struct zebra_vrf *zvrf; +	rib_dest_t *dest; +	struct zebra_vrf *zvrf; -  dest = rib_dest_from_rnode (rn); -  if (!dest) -    return 0; +	dest = rib_dest_from_rnode(rn); +	if (!dest) +		return 0; -  if (!rib_can_delete_dest (dest)) -    return 0; +	if (!rib_can_delete_dest(dest)) +		return 0; -  zvrf = rib_dest_vrf (dest); -  if (IS_ZEBRA_DEBUG_RIB) -    rnode_debug (rn, zvrf_id (zvrf), "removing dest from table"); +	zvrf = rib_dest_vrf(dest); +	if (IS_ZEBRA_DEBUG_RIB) +		rnode_debug(rn, zvrf_id(zvrf), "removing dest from table"); -  dest->rnode = NULL; -  XFREE (MTYPE_RIB_DEST, dest); -  rn->info = NULL; +	dest->rnode = NULL; +	XFREE(MTYPE_RIB_DEST, dest); +	rn->info = NULL; -  /* -   * Release the one reference that we keep on the route node. -   */ -  route_unlock_node (rn); -  return 1; +	/* +	 * Release the one reference that we keep on the route node. +	 */ +	route_unlock_node(rn); +	return 1;  } -static void -rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn, -                    struct rib *new) +static void rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn, +				struct rib *new)  { -  hook_call(rib_update, rn, "new route selected"); +	hook_call(rib_update, rn, "new route selected"); -  /* Update real nexthop. This may actually determine if nexthop is active or not. */ -  if (!nexthop_active_update (rn, new, 1)) -    { -      UNSET_FLAG(new->status, RIB_ENTRY_CHANGED); -      return; -    } +	/* Update real nexthop. This may actually determine if nexthop is active +	 * or not. */ +	if (!nexthop_active_update(rn, new, 1)) { +		UNSET_FLAG(new->status, RIB_ENTRY_CHANGED); +		return; +	} -  SET_FLAG (new->status, RIB_ENTRY_SELECTED_FIB); -  if (IS_ZEBRA_DEBUG_RIB) -    { -      char buf[SRCDEST2STR_BUFFER]; -      srcdest_rnode2str(rn, buf, sizeof(buf)); -      zlog_debug ("%u:%s: Adding route rn %p, rib %p (type %d)", -                   zvrf_id (zvrf), buf, rn, new, new->type); -    } +	SET_FLAG(new->status, RIB_ENTRY_SELECTED_FIB); +	if (IS_ZEBRA_DEBUG_RIB) { +		char buf[SRCDEST2STR_BUFFER]; +		srcdest_rnode2str(rn, buf, sizeof(buf)); +		zlog_debug("%u:%s: Adding route rn %p, rib %p (type %d)", +			   zvrf_id(zvrf), buf, rn, new, new->type); +	} -  if (!RIB_SYSTEM_ROUTE (new)) -    { -      if (rib_install_kernel (rn, new, NULL)) -        { -          char buf[SRCDEST2STR_BUFFER]; -          srcdest_rnode2str(rn, buf, sizeof(buf)); -          zlog_warn ("%u:%s: Route install failed", -                     zvrf_id (zvrf), buf); -        } -    } +	if (!RIB_SYSTEM_ROUTE(new)) { +		if (rib_install_kernel(rn, new, NULL)) { +			char buf[SRCDEST2STR_BUFFER]; +			srcdest_rnode2str(rn, buf, sizeof(buf)); +			zlog_warn("%u:%s: Route install failed", zvrf_id(zvrf), +				  buf); +		} +	} -  UNSET_FLAG(new->status, RIB_ENTRY_CHANGED); +	UNSET_FLAG(new->status, RIB_ENTRY_CHANGED);  } -static void -rib_process_del_fib(struct zebra_vrf *zvrf, struct route_node *rn, -                    struct rib *old) +static void rib_process_del_fib(struct zebra_vrf *zvrf, struct route_node *rn, +				struct rib *old)  { -  hook_call(rib_update, rn, "removing existing route"); +	hook_call(rib_update, rn, "removing existing route"); -  /* Uninstall from kernel. */ -  if (IS_ZEBRA_DEBUG_RIB) -    { -      char buf[SRCDEST2STR_BUFFER]; -      srcdest_rnode2str(rn, buf, sizeof(buf)); -      zlog_debug ("%u:%s: Deleting route rn %p, rib %p (type %d)", -                  zvrf_id (zvrf), buf, rn, old, old->type); -    } +	/* Uninstall from kernel. */ +	if (IS_ZEBRA_DEBUG_RIB) { +		char buf[SRCDEST2STR_BUFFER]; +		srcdest_rnode2str(rn, buf, sizeof(buf)); +		zlog_debug("%u:%s: Deleting route rn %p, rib %p (type %d)", +			   zvrf_id(zvrf), buf, rn, old, old->type); +	} + +	if (!RIB_SYSTEM_ROUTE(old)) +		rib_uninstall_kernel(rn, old); + +	UNSET_FLAG(old->status, RIB_ENTRY_SELECTED_FIB); + +	/* Update nexthop for route, reset changed flag. */ +	nexthop_active_update(rn, old, 1); +	UNSET_FLAG(old->status, RIB_ENTRY_CHANGED); +} + +static void rib_process_update_fib(struct zebra_vrf *zvrf, +				   struct route_node *rn, struct rib *old, +				   struct rib *new) +{ +	struct nexthop *nexthop = NULL, *tnexthop; +	int recursing; +	int nh_active = 0; +	int installed = 1; + +	/* +	 * We have to install or update if a new route has been selected or +	 * something has changed. +	 */ +	if (new != old || CHECK_FLAG(new->status, RIB_ENTRY_CHANGED)) { +		hook_call(rib_update, rn, "updating existing route"); + +		/* Update the nexthop; we could determine here that nexthop is +		 * inactive. */ +		if (nexthop_active_update(rn, new, 1)) +			nh_active = 1; + +		/* If nexthop is active, install the selected route, if +		 * appropriate. If +		 * the install succeeds, cleanup flags for prior route, if +		 * different from +		 * newly selected. +		 */ +		if (nh_active) { +			if (IS_ZEBRA_DEBUG_RIB) { +				char buf[SRCDEST2STR_BUFFER]; +				srcdest_rnode2str(rn, buf, sizeof(buf)); +				if (new != old) +					zlog_debug( +						"%u:%s: Updating route rn %p, rib %p (type %d) " +						"old %p (type %d)", +						zvrf_id(zvrf), buf, rn, new, +						new->type, old, old->type); +				else +					zlog_debug( +						"%u:%s: Updating route rn %p, rib %p (type %d)", +						zvrf_id(zvrf), buf, rn, new, +						new->type); +			} +			/* Non-system route should be installed. */ +			if (!RIB_SYSTEM_ROUTE(new)) { +				if (rib_install_kernel(rn, new, old)) { +					char buf[SRCDEST2STR_BUFFER]; +					srcdest_rnode2str(rn, buf, sizeof(buf)); +					installed = 0; +					zlog_warn("%u:%s: Route install failed", +						  zvrf_id(zvrf), buf); +				} +			} + +			/* If install succeeded or system route, cleanup flags +			 * for prior route. */ +			if (installed && new != old) { +				if (RIB_SYSTEM_ROUTE(new)) { +					if (!RIB_SYSTEM_ROUTE(old)) +						rib_uninstall_kernel(rn, old); +				} else { +					for (nexthop = old->nexthop; nexthop; +					     nexthop = nexthop->next) +						UNSET_FLAG(nexthop->flags, +							   NEXTHOP_FLAG_FIB); +				} +			} + +			/* Update for redistribution. */ +			if (installed) +				SET_FLAG(new->status, RIB_ENTRY_SELECTED_FIB); +		} -  if (!RIB_SYSTEM_ROUTE (old)) -    rib_uninstall_kernel (rn, old); +		/* +		 * If nexthop for selected route is not active or install +		 * failed, we +		 * may need to uninstall and delete for redistribution. +		 */ +		if (!nh_active || !installed) { +			if (IS_ZEBRA_DEBUG_RIB) { +				char buf[SRCDEST2STR_BUFFER]; +				srcdest_rnode2str(rn, buf, sizeof(buf)); +				if (new != old) +					zlog_debug( +						"%u:%s: Deleting route rn %p, rib %p (type %d) " +						"old %p (type %d) - %s", +						zvrf_id(zvrf), buf, rn, new, +						new->type, old, old->type, +						nh_active ? "install failed" +							  : "nexthop inactive"); +				else +					zlog_debug( +						"%u:%s: Deleting route rn %p, rib %p (type %d) - %s", +						zvrf_id(zvrf), buf, rn, new, +						new->type, +						nh_active ? "install failed" +							  : "nexthop inactive"); +			} + +			if (!RIB_SYSTEM_ROUTE(old)) +				rib_uninstall_kernel(rn, old); +			UNSET_FLAG(new->status, RIB_ENTRY_SELECTED_FIB); +		} +	} else { +		/* +		 * Same route selected; check if in the FIB and if not, +		 * re-install. This +		 * is housekeeping code to deal with race conditions in kernel +		 * with linux +		 * netlink reporting interface up before IPv4 or IPv6 protocol +		 * is ready +		 * to add routes. +		 */ +		if (!RIB_SYSTEM_ROUTE(new)) { +			int in_fib = 0; + +			for (ALL_NEXTHOPS_RO(new->nexthop, nexthop, tnexthop, +					     recursing)) +				if (CHECK_FLAG(nexthop->flags, +					       NEXTHOP_FLAG_FIB)) { +					in_fib = 1; +					break; +				} +			if (!in_fib) +				rib_install_kernel(rn, new, NULL); +		} +	} -  UNSET_FLAG (old->status, RIB_ENTRY_SELECTED_FIB); +	/* Update prior route. */ +	if (new != old) { +		UNSET_FLAG(old->status, RIB_ENTRY_SELECTED_FIB); -  /* Update nexthop for route, reset changed flag. */ -  nexthop_active_update (rn, old, 1); -  UNSET_FLAG(old->status, RIB_ENTRY_CHANGED); +		/* Set real nexthop. */ +		nexthop_active_update(rn, old, 1); +		UNSET_FLAG(old->status, RIB_ENTRY_CHANGED); +	} + +	/* Clear changed flag. */ +	UNSET_FLAG(new->status, RIB_ENTRY_CHANGED);  } -static void -rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn, -                        struct rib *old, struct rib *new) -{ -  struct nexthop *nexthop = NULL, *tnexthop; -  int recursing; -  int nh_active = 0; -  int installed = 1; +/* Check if 'alternate' RIB entry is better than 'current'. */ +static struct rib *rib_choose_best(struct rib *current, struct rib *alternate) +{ +	if (current == NULL) +		return alternate; + +	/* filter route selection in following order: +	 * - connected beats other types +	 * - lower distance beats higher +	 * - lower metric beats higher for equal distance +	 * - last, hence oldest, route wins tie break. +	 */ + +	/* Connected routes. Pick the last connected +	 * route of the set of lowest metric connected routes. +	 */ +	if (alternate->type == ZEBRA_ROUTE_CONNECT) { +		if (current->type != ZEBRA_ROUTE_CONNECT +		    || alternate->metric <= current->metric) +			return alternate; + +		return current; +	} -  /* -   * We have to install or update if a new route has been selected or -   * something has changed. -   */ -  if (new != old || -      CHECK_FLAG (new->status, RIB_ENTRY_CHANGED)) -    { -      hook_call(rib_update, rn, "updating existing route"); - -      /* Update the nexthop; we could determine here that nexthop is inactive. */ -      if (nexthop_active_update (rn, new, 1)) -        nh_active = 1; - -      /* If nexthop is active, install the selected route, if appropriate. If -       * the install succeeds, cleanup flags for prior route, if different from -       * newly selected. -       */ -      if (nh_active) -        { -          if (IS_ZEBRA_DEBUG_RIB) -            { -              char buf[SRCDEST2STR_BUFFER]; -              srcdest_rnode2str(rn, buf, sizeof(buf)); -              if (new != old) -                zlog_debug ("%u:%s: Updating route rn %p, rib %p (type %d) " -                            "old %p (type %d)", zvrf_id (zvrf), buf, -                            rn, new, new->type, old, old->type); -              else -                zlog_debug ("%u:%s: Updating route rn %p, rib %p (type %d)", -                            zvrf_id (zvrf), buf, rn, new, new->type); -            } -          /* Non-system route should be installed. */ -          if (!RIB_SYSTEM_ROUTE (new)) -            { -              if (rib_install_kernel (rn, new, old)) -                { -                  char buf[SRCDEST2STR_BUFFER]; -                  srcdest_rnode2str(rn, buf, sizeof(buf)); -                  installed = 0; -                  zlog_warn ("%u:%s: Route install failed", zvrf_id (zvrf), buf); -                } -            } - -          /* If install succeeded or system route, cleanup flags for prior route. */ -          if (installed && new != old) -            { -              if (RIB_SYSTEM_ROUTE(new)) -                { -                  if (!RIB_SYSTEM_ROUTE (old)) -                    rib_uninstall_kernel (rn, old); -                } -              else -                { -                  for (nexthop = old->nexthop; nexthop; nexthop = nexthop->next) -                    UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); -                } -            } - -          /* Update for redistribution. */ -          if (installed) -            SET_FLAG (new->status, RIB_ENTRY_SELECTED_FIB); -        } - -      /* -       * If nexthop for selected route is not active or install failed, we -       * may need to uninstall and delete for redistribution. -       */ -      if (!nh_active || !installed) -        { -          if (IS_ZEBRA_DEBUG_RIB) -            { -              char buf[SRCDEST2STR_BUFFER]; -              srcdest_rnode2str(rn, buf, sizeof(buf)); -              if (new != old) -                zlog_debug ("%u:%s: Deleting route rn %p, rib %p (type %d) " -                            "old %p (type %d) - %s", zvrf_id (zvrf), buf, -                            rn, new, new->type, old, old->type, -                            nh_active ? "install failed" : "nexthop inactive"); -              else -                zlog_debug ("%u:%s: Deleting route rn %p, rib %p (type %d) - %s", -                            zvrf_id (zvrf), buf, rn, new, new->type, -                            nh_active ? "install failed" : "nexthop inactive"); -            } - -          if (!RIB_SYSTEM_ROUTE (old)) -            rib_uninstall_kernel (rn, old); -          UNSET_FLAG (new->status, RIB_ENTRY_SELECTED_FIB); -        } -    } -  else -    { -      /* -       * Same route selected; check if in the FIB and if not, re-install. This -       * is housekeeping code to deal with race conditions in kernel with linux -       * netlink reporting interface up before IPv4 or IPv6 protocol is ready -       * to add routes. -       */ -      if (!RIB_SYSTEM_ROUTE (new)) -        { -          int in_fib = 0; - -          for (ALL_NEXTHOPS_RO(new->nexthop, nexthop, tnexthop, recursing)) -            if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) -              { -                in_fib = 1; -                break; -              } -          if (!in_fib) -            rib_install_kernel (rn, new, NULL); -        } -    } +	if (current->type == ZEBRA_ROUTE_CONNECT) +		return current; -  /* Update prior route. */ -  if (new != old) -    { -      UNSET_FLAG (old->status, RIB_ENTRY_SELECTED_FIB); +	/* higher distance loses */ +	if (alternate->distance < current->distance) +		return alternate; +	if (current->distance < alternate->distance) +		return current; -      /* Set real nexthop. */ -      nexthop_active_update (rn, old, 1); -      UNSET_FLAG(old->status, RIB_ENTRY_CHANGED); -    } +	/* metric tie-breaks equal distance */ +	if (alternate->metric <= current->metric) +		return alternate; -  /* Clear changed flag. */ -  UNSET_FLAG(new->status, RIB_ENTRY_CHANGED); +	return current;  } -/* Check if 'alternate' RIB entry is better than 'current'. */ -static struct rib * -rib_choose_best (struct rib *current, struct rib *alternate) -{ -  if (current == NULL) -    return alternate; - -  /* filter route selection in following order: -   * - connected beats other types -   * - lower distance beats higher -   * - lower metric beats higher for equal distance -   * - last, hence oldest, route wins tie break. -   */ - -  /* Connected routes. Pick the last connected -   * route of the set of lowest metric connected routes. -   */ -  if (alternate->type == ZEBRA_ROUTE_CONNECT) -    { -      if (current->type != ZEBRA_ROUTE_CONNECT -          || alternate->metric <= current->metric) -        return alternate; +/* Core function for processing routing information base. */ +static void rib_process(struct route_node *rn) +{ +	struct rib *rib; +	struct rib *next; +	struct rib *old_selected = NULL; +	struct rib *new_selected = NULL; +	struct rib *old_fib = NULL; +	struct rib *new_fib = NULL; +	struct rib *best = NULL; +	char buf[SRCDEST2STR_BUFFER]; +	rib_dest_t *dest; +	struct zebra_vrf *zvrf = NULL; +	struct prefix *p, *src_p; +	srcdest_rnode_prefixes(rn, &p, &src_p); +	vrf_id_t vrf_id = VRF_UNKNOWN; + +	assert(rn); + +	dest = rib_dest_from_rnode(rn); +	if (dest) { +		zvrf = rib_dest_vrf(dest); +		vrf_id = zvrf_id(zvrf); +	} -      return current; -    } +	if (IS_ZEBRA_DEBUG_RIB) +		srcdest_rnode2str(rn, buf, sizeof(buf)); -  if (current->type == ZEBRA_ROUTE_CONNECT) -    return current; +	if (IS_ZEBRA_DEBUG_RIB_DETAILED) +		zlog_debug("%u:%s: Processing rn %p", vrf_id, buf, rn); -  /* higher distance loses */ -  if (alternate->distance < current->distance) -    return alternate; -  if (current->distance < alternate->distance) -    return current; +	RNODE_FOREACH_RIB_SAFE(rn, rib, next) +	{ +		if (IS_ZEBRA_DEBUG_RIB_DETAILED) +			zlog_debug( +				"%u:%s: Examine rib %p (type %d) status %x flags %x " +				"dist %d metric %d", +				vrf_id, buf, rib, rib->type, rib->status, +				rib->flags, rib->distance, rib->metric); + +		UNSET_FLAG(rib->status, RIB_ENTRY_NEXTHOPS_CHANGED); + +		/* Currently selected rib. */ +		if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED)) { +			assert(old_selected == NULL); +			old_selected = rib; +		} +		/* Currently in fib */ +		if (CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB)) { +			assert(old_fib == NULL); +			old_fib = rib; +		} -  /* metric tie-breaks equal distance */ -  if (alternate->metric <= current->metric) -    return alternate; +		/* Skip deleted entries from selection */ +		if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED)) +			continue; + +		/* Skip unreachable nexthop. */ +		/* This first call to nexthop_active_update is merely to +		 * determine if +		 * there's any change to nexthops associated with this RIB +		 * entry. Now, +		 * rib_process() can be invoked due to an external event such as +		 * link +		 * down or due to next-hop-tracking evaluation. In the latter +		 * case, +		 * a decision has already been made that the NHs have changed. +		 * So, no +		 * need to invoke a potentially expensive call again. Further, +		 * since +		 * the change might be in a recursive NH which is not caught in +		 * the nexthop_active_update() code. Thus, we might miss changes +		 * to +		 * recursive NHs. +		 */ +		if (!CHECK_FLAG(rib->status, RIB_ENTRY_CHANGED) +		    && !nexthop_active_update(rn, rib, 0)) { +			if (rib->type == ZEBRA_ROUTE_TABLE) { +				/* XXX: HERE BE DRAGONS!!!!! +				 * In all honesty, I have not yet figured out +				 * what this part +				 * does or why the RIB_ENTRY_CHANGED test above +				 * is correct +				 * or why we need to delete a route here, and +				 * also not whether +				 * this concerns both selected and fib route, or +				 * only selected +				 * or only fib */ +				/* This entry was denied by the 'ip protocol +				 * table' route-map, we +				 * need to delete it */ +				if (rib != old_selected) { +					if (IS_ZEBRA_DEBUG_RIB) +						zlog_debug( +							"%s: %s: imported via import-table but denied " +							"by the ip protocol table route-map", +							__func__, buf); +					rib_unlink(rn, rib); +				} else +					SET_FLAG(rib->status, +						 RIB_ENTRY_REMOVED); +			} + +			continue; +		} -  return current; -} +		/* Infinite distance. */ +		if (rib->distance == DISTANCE_INFINITY) { +			UNSET_FLAG(rib->status, RIB_ENTRY_CHANGED); +			continue; +		} -/* Core function for processing routing information base. */ -static void -rib_process (struct route_node *rn) -{ -  struct rib *rib; -  struct rib *next; -  struct rib *old_selected = NULL; -  struct rib *new_selected = NULL; -  struct rib *old_fib = NULL; -  struct rib *new_fib = NULL; -  struct rib *best = NULL; -  char buf[SRCDEST2STR_BUFFER]; -  rib_dest_t *dest; -  struct zebra_vrf *zvrf = NULL; -  struct prefix *p, *src_p; -  srcdest_rnode_prefixes(rn, &p, &src_p); -  vrf_id_t vrf_id = VRF_UNKNOWN; - -  assert (rn); - -  dest = rib_dest_from_rnode (rn); -  if (dest) -    { -      zvrf = rib_dest_vrf (dest); -      vrf_id = zvrf_id (zvrf); -    } +		if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_FIB_OVERRIDE)) { +			best = rib_choose_best(new_fib, rib); +			if (new_fib && best != new_fib) +				UNSET_FLAG(new_fib->status, RIB_ENTRY_CHANGED); +			new_fib = best; +		} else { +			best = rib_choose_best(new_selected, rib); +			if (new_selected && best != new_selected) +				UNSET_FLAG(new_selected->status, +					   RIB_ENTRY_CHANGED); +			new_selected = best; +		} +		if (best != rib) +			UNSET_FLAG(rib->status, RIB_ENTRY_CHANGED); +	} /* RNODE_FOREACH_RIB */ + +	/* If no FIB override route, use the selected route also for FIB */ +	if (new_fib == NULL) +		new_fib = new_selected; + +	/* After the cycle is finished, the following pointers will be set: +	 * old_selected --- RIB entry currently having SELECTED +	 * new_selected --- RIB entry that is newly SELECTED +	 * old_fib      --- RIB entry currently in kernel FIB +	 * new_fib      --- RIB entry that is newly to be in kernel FIB +	 * +	 * new_selected will get SELECTED flag, and is going to be redistributed +	 * the zclients. new_fib (which can be new_selected) will be installed +	 * in kernel. +	 */ + +	if (IS_ZEBRA_DEBUG_RIB_DETAILED) { +		zlog_debug( +			"%u:%s: After processing: old_selected %p new_selected %p old_fib %p new_fib %p", +			vrf_id, buf, (void *)old_selected, (void *)new_selected, +			(void *)old_fib, (void *)new_fib); +	} -  if (IS_ZEBRA_DEBUG_RIB) -    srcdest_rnode2str(rn, buf, sizeof(buf)); +	/* Buffer RIB_ENTRY_CHANGED here, because it will get cleared if +	 * fib == selected */ +	bool selected_changed = new_selected && CHECK_FLAG(new_selected->status, +							   RIB_ENTRY_CHANGED); + +	/* Update fib according to selection results */ +	if (new_fib && old_fib) +		rib_process_update_fib(zvrf, rn, old_fib, new_fib); +	else if (new_fib) +		rib_process_add_fib(zvrf, rn, new_fib); +	else if (old_fib) +		rib_process_del_fib(zvrf, rn, old_fib); + +	/* Redistribute SELECTED entry */ +	if (old_selected != new_selected || selected_changed) { +		struct nexthop *nexthop, *tnexthop; +		int recursing; + +		/* Check if we have a FIB route for the destination, otherwise, +		 * don't redistribute it */ +		for (ALL_NEXTHOPS_RO(new_fib ? new_fib->nexthop : NULL, nexthop, +				     tnexthop, recursing)) { +			if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)) { +				break; +			} +		} +		if (!nexthop) +			new_selected = NULL; -  if (IS_ZEBRA_DEBUG_RIB_DETAILED) -    zlog_debug ("%u:%s: Processing rn %p", vrf_id, buf, rn); +		if (new_selected && new_selected != new_fib) { +			nexthop_active_update(rn, new_selected, 1); +			UNSET_FLAG(new_selected->status, RIB_ENTRY_CHANGED); +		} -  RNODE_FOREACH_RIB_SAFE (rn, rib, next) -    { -      if (IS_ZEBRA_DEBUG_RIB_DETAILED) -        zlog_debug ("%u:%s: Examine rib %p (type %d) status %x flags %x " -                    "dist %d metric %d", -                    vrf_id, buf, rib, rib->type, rib->status, -                    rib->flags, rib->distance, rib->metric); - -      UNSET_FLAG(rib->status, RIB_ENTRY_NEXTHOPS_CHANGED); - -      /* Currently selected rib. */ -      if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) -        { -          assert (old_selected == NULL); -          old_selected = rib; -        } -      /* Currently in fib */ -      if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB)) -        { -          assert (old_fib == NULL); -          old_fib = rib; -        } - -      /* Skip deleted entries from selection */ -      if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) -        continue; - -      /* Skip unreachable nexthop. */ -      /* This first call to nexthop_active_update is merely to determine if -       * there's any change to nexthops associated with this RIB entry. Now, -       * rib_process() can be invoked due to an external event such as link -       * down or due to next-hop-tracking evaluation. In the latter case, -       * a decision has already been made that the NHs have changed. So, no -       * need to invoke a potentially expensive call again. Further, since -       * the change might be in a recursive NH which is not caught in -       * the nexthop_active_update() code. Thus, we might miss changes to -       * recursive NHs. -       */ -      if (!CHECK_FLAG(rib->status, RIB_ENTRY_CHANGED) && -          ! nexthop_active_update (rn, rib, 0)) -        { -          if (rib->type == ZEBRA_ROUTE_TABLE) -            { -              /* XXX: HERE BE DRAGONS!!!!! -	       * In all honesty, I have not yet figured out what this part -	       * does or why the RIB_ENTRY_CHANGED test above is correct -	       * or why we need to delete a route here, and also not whether -	       * this concerns both selected and fib route, or only selected -	       * or only fib */ -              /* This entry was denied by the 'ip protocol table' route-map, we -               * need to delete it */ -	      if (rib != old_selected) -		{ -		  if (IS_ZEBRA_DEBUG_RIB) -		    zlog_debug ("%s: %s: imported via import-table but denied " -				"by the ip protocol table route-map", -				__func__, buf); -		  rib_unlink (rn, rib); +		if (old_selected) { +			if (!new_selected) +				redistribute_delete(p, src_p, old_selected); +			if (old_selected != new_selected) +				UNSET_FLAG(old_selected->flags, +					   ZEBRA_FLAG_SELECTED);  		} -	      else -		SET_FLAG (rib->status, RIB_ENTRY_REMOVED); -            } - -          continue; -        } - -      /* Infinite distance. */ -      if (rib->distance == DISTANCE_INFINITY) -        { -          UNSET_FLAG (rib->status, RIB_ENTRY_CHANGED); -          continue; -        } - -      if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_FIB_OVERRIDE)) -        { -          best = rib_choose_best(new_fib, rib); -          if (new_fib && best != new_fib) -            UNSET_FLAG (new_fib->status, RIB_ENTRY_CHANGED); -         new_fib = best; -        } -      else -        { -          best = rib_choose_best(new_selected, rib); -          if (new_selected && best != new_selected) -            UNSET_FLAG (new_selected->status, RIB_ENTRY_CHANGED); -          new_selected = best; -        } -      if (best != rib) -        UNSET_FLAG (rib->status, RIB_ENTRY_CHANGED); -    } /* RNODE_FOREACH_RIB */ - -  /* If no FIB override route, use the selected route also for FIB */ -  if (new_fib == NULL) -    new_fib = new_selected; - -  /* After the cycle is finished, the following pointers will be set: -   * old_selected --- RIB entry currently having SELECTED -   * new_selected --- RIB entry that is newly SELECTED -   * old_fib      --- RIB entry currently in kernel FIB -   * new_fib      --- RIB entry that is newly to be in kernel FIB -   * -   * new_selected will get SELECTED flag, and is going to be redistributed -   * the zclients. new_fib (which can be new_selected) will be installed in kernel. -   */ - -  if (IS_ZEBRA_DEBUG_RIB_DETAILED) -    { -    zlog_debug ("%u:%s: After processing: old_selected %p new_selected %p old_fib %p new_fib %p", -                vrf_id, buf, -                (void *)old_selected, -                (void *)new_selected, -                (void *)old_fib, -                (void *)new_fib); -    } -  /* Buffer RIB_ENTRY_CHANGED here, because it will get cleared if -   * fib == selected */ -  bool selected_changed = new_selected && CHECK_FLAG(new_selected->status, -                                                     RIB_ENTRY_CHANGED); - -  /* Update fib according to selection results */ -  if (new_fib && old_fib) -    rib_process_update_fib (zvrf, rn, old_fib, new_fib); -  else if (new_fib) -    rib_process_add_fib (zvrf, rn, new_fib); -  else if (old_fib) -    rib_process_del_fib (zvrf, rn, old_fib); - -  /* Redistribute SELECTED entry */ -  if (old_selected != new_selected || selected_changed) -    { -      struct nexthop *nexthop, *tnexthop; -      int recursing; - -      /* Check if we have a FIB route for the destination, otherwise, -       * don't redistribute it */ -      for (ALL_NEXTHOPS_RO(new_fib ? new_fib->nexthop : NULL, nexthop, -                           tnexthop, recursing)) -        { -          if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)) -            { -              break; -            } -        } -      if (!nexthop) -        new_selected = NULL; - -      if (new_selected && new_selected != new_fib) -        { -          nexthop_active_update(rn, new_selected, 1); -          UNSET_FLAG(new_selected->status, RIB_ENTRY_CHANGED); -        } - -      if (old_selected) -        { -          if (!new_selected) -            redistribute_delete(p, src_p, old_selected); -          if (old_selected != new_selected) -            UNSET_FLAG (old_selected->flags, ZEBRA_FLAG_SELECTED); -        } - -      if (new_selected) -        { -          /* Install new or replace existing redistributed entry */ -          SET_FLAG (new_selected->flags, ZEBRA_FLAG_SELECTED); -          redistribute_update (p, src_p, new_selected, old_selected); -        } -    } +		if (new_selected) { +			/* Install new or replace existing redistributed entry +			 */ +			SET_FLAG(new_selected->flags, ZEBRA_FLAG_SELECTED); +			redistribute_update(p, src_p, new_selected, +					    old_selected); +		} +	} -  /* Remove all RIB entries queued for removal */ -  RNODE_FOREACH_RIB_SAFE (rn, rib, next) -    { -      if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) -        { -          if (IS_ZEBRA_DEBUG_RIB) -            { -              rnode_debug (rn, vrf_id, "rn %p, removing rib %p", -                           (void *)rn, (void *)rib); -            } -          rib_unlink(rn, rib); -        } -    } +	/* Remove all RIB entries queued for removal */ +	RNODE_FOREACH_RIB_SAFE(rn, rib, next) +	{ +		if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED)) { +			if (IS_ZEBRA_DEBUG_RIB) { +				rnode_debug(rn, vrf_id, +					    "rn %p, removing rib %p", +					    (void *)rn, (void *)rib); +			} +			rib_unlink(rn, rib); +		} +	} -  /* -   * Check if the dest can be deleted now. -   */ -  rib_gc_dest (rn); +	/* +	 * Check if the dest can be deleted now. +	 */ +	rib_gc_dest(rn);  }  /* Take a list of route_node structs and return 1, if there was a record - * picked from it and processed by rib_process(). Don't process more,  + * picked from it and processed by rib_process(). Don't process more,   * than one RN record; operate only in the specified sub-queue.   */ -static unsigned int -process_subq (struct list * subq, u_char qindex) +static unsigned int process_subq(struct list *subq, u_char qindex)  { -  struct listnode *lnode  = listhead (subq); -  struct route_node *rnode; -  rib_dest_t *dest; -  struct zebra_vrf *zvrf = NULL; +	struct listnode *lnode = listhead(subq); +	struct route_node *rnode; +	rib_dest_t *dest; +	struct zebra_vrf *zvrf = NULL; -  if (!lnode) -    return 0; +	if (!lnode) +		return 0; -  rnode = listgetdata (lnode); -  dest = rib_dest_from_rnode (rnode); -  if (dest) -    zvrf = rib_dest_vrf (dest); +	rnode = listgetdata(lnode); +	dest = rib_dest_from_rnode(rnode); +	if (dest) +		zvrf = rib_dest_vrf(dest); -  rib_process (rnode); +	rib_process(rnode); -  if (IS_ZEBRA_DEBUG_RIB_DETAILED) -    { -      char buf[SRCDEST2STR_BUFFER]; -      srcdest_rnode2str(rnode, buf, sizeof(buf)); -      zlog_debug ("%u:%s: rn %p dequeued from sub-queue %u", -                  zvrf ? zvrf_id (zvrf) : 0, buf, rnode, qindex); -    } +	if (IS_ZEBRA_DEBUG_RIB_DETAILED) { +		char buf[SRCDEST2STR_BUFFER]; +		srcdest_rnode2str(rnode, buf, sizeof(buf)); +		zlog_debug("%u:%s: rn %p dequeued from sub-queue %u", +			   zvrf ? zvrf_id(zvrf) : 0, buf, rnode, qindex); +	} -  if (rnode->info) -    UNSET_FLAG (rib_dest_from_rnode (rnode)->flags, RIB_ROUTE_QUEUED (qindex)); +	if (rnode->info) +		UNSET_FLAG(rib_dest_from_rnode(rnode)->flags, +			   RIB_ROUTE_QUEUED(qindex));  #if 0    else @@ -1751,220 +1823,212 @@ process_subq (struct list * subq, u_char qindex)        zlog_backtrace(LOG_DEBUG);      }  #endif -  route_unlock_node (rnode); -  list_delete_node (subq, lnode); -  return 1; +	route_unlock_node(rnode); +	list_delete_node(subq, lnode); +	return 1;  }  /*   * All meta queues have been processed. Trigger next-hop evaluation.   */ -static void -meta_queue_process_complete (struct work_queue *dummy) +static void meta_queue_process_complete(struct work_queue *dummy)  { -  struct vrf *vrf; -  struct zebra_vrf *zvrf; +	struct vrf *vrf; +	struct zebra_vrf *zvrf; -  /* Evaluate nexthops for those VRFs which underwent route processing. This -   * should limit the evaluation to the necessary VRFs in most common -   * situations. -   */ -  RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) -    { -      zvrf = vrf->info; -      if (zvrf == NULL || !(zvrf->flags & ZEBRA_VRF_RIB_SCHEDULED)) -	continue; - -      zvrf->flags &= ~ZEBRA_VRF_RIB_SCHEDULED; -      zebra_evaluate_rnh(zvrf_id (zvrf), AF_INET, 0, RNH_NEXTHOP_TYPE, NULL); -      zebra_evaluate_rnh(zvrf_id (zvrf), AF_INET, 0, RNH_IMPORT_CHECK_TYPE, NULL); -      zebra_evaluate_rnh(zvrf_id (zvrf), AF_INET6, 0, RNH_NEXTHOP_TYPE, NULL); -      zebra_evaluate_rnh(zvrf_id (zvrf), AF_INET6, 0, RNH_IMPORT_CHECK_TYPE, NULL); -    } +	/* Evaluate nexthops for those VRFs which underwent route processing. +	 * This +	 * should limit the evaluation to the necessary VRFs in most common +	 * situations. +	 */ +	RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id) +	{ +		zvrf = vrf->info; +		if (zvrf == NULL || !(zvrf->flags & ZEBRA_VRF_RIB_SCHEDULED)) +			continue; + +		zvrf->flags &= ~ZEBRA_VRF_RIB_SCHEDULED; +		zebra_evaluate_rnh(zvrf_id(zvrf), AF_INET, 0, RNH_NEXTHOP_TYPE, +				   NULL); +		zebra_evaluate_rnh(zvrf_id(zvrf), AF_INET, 0, +				   RNH_IMPORT_CHECK_TYPE, NULL); +		zebra_evaluate_rnh(zvrf_id(zvrf), AF_INET6, 0, RNH_NEXTHOP_TYPE, +				   NULL); +		zebra_evaluate_rnh(zvrf_id(zvrf), AF_INET6, 0, +				   RNH_IMPORT_CHECK_TYPE, NULL); +	} -  /* Schedule LSPs for processing, if needed. */ -  zvrf = vrf_info_lookup(VRF_DEFAULT); -  if (mpls_should_lsps_be_processed(zvrf)) -    { -      if (IS_ZEBRA_DEBUG_MPLS) -        zlog_debug ("%u: Scheduling all LSPs upon RIB completion", zvrf_id (zvrf)); -      zebra_mpls_lsp_schedule (zvrf); -      mpls_unmark_lsps_for_processing(zvrf); -    } +	/* Schedule LSPs for processing, if needed. */ +	zvrf = vrf_info_lookup(VRF_DEFAULT); +	if (mpls_should_lsps_be_processed(zvrf)) { +		if (IS_ZEBRA_DEBUG_MPLS) +			zlog_debug( +				"%u: Scheduling all LSPs upon RIB completion", +				zvrf_id(zvrf)); +		zebra_mpls_lsp_schedule(zvrf); +		mpls_unmark_lsps_for_processing(zvrf); +	}  }  /* Dispatch the meta queue by picking, processing and unlocking the next RN from - * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and data + * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and + * data   * is pointed to the meta queue structure.   */ -static wq_item_status -meta_queue_process (struct work_queue *dummy, void *data) +static wq_item_status meta_queue_process(struct work_queue *dummy, void *data)  { -  struct meta_queue * mq = data; -  unsigned i; +	struct meta_queue *mq = data; +	unsigned i; -  for (i = 0; i < MQ_SIZE; i++) -    if (process_subq (mq->subq[i], i)) -      { -	mq->size--; -	break; -      } -  return mq->size ? WQ_REQUEUE : WQ_SUCCESS; +	for (i = 0; i < MQ_SIZE; i++) +		if (process_subq(mq->subq[i], i)) { +			mq->size--; +			break; +		} +	return mq->size ? WQ_REQUEUE : WQ_SUCCESS;  }  /*   * Map from rib types to queue type (priority) in meta queue   */  static const u_char meta_queue_map[ZEBRA_ROUTE_MAX] = { -  [ZEBRA_ROUTE_SYSTEM]  = 4, -  [ZEBRA_ROUTE_KERNEL]  = 0, -  [ZEBRA_ROUTE_CONNECT] = 0, -  [ZEBRA_ROUTE_STATIC]  = 1, -  [ZEBRA_ROUTE_RIP]     = 2, -  [ZEBRA_ROUTE_RIPNG]   = 2, -  [ZEBRA_ROUTE_OSPF]    = 2, -  [ZEBRA_ROUTE_OSPF6]   = 2, -  [ZEBRA_ROUTE_ISIS]    = 2, -  [ZEBRA_ROUTE_NHRP]    = 2, -  [ZEBRA_ROUTE_BGP]     = 3, -  [ZEBRA_ROUTE_HSLS]    = 4, -  [ZEBRA_ROUTE_TABLE]   = 1, +		[ZEBRA_ROUTE_SYSTEM] = 4,  [ZEBRA_ROUTE_KERNEL] = 0, +		[ZEBRA_ROUTE_CONNECT] = 0, [ZEBRA_ROUTE_STATIC] = 1, +		[ZEBRA_ROUTE_RIP] = 2,     [ZEBRA_ROUTE_RIPNG] = 2, +		[ZEBRA_ROUTE_OSPF] = 2,    [ZEBRA_ROUTE_OSPF6] = 2, +		[ZEBRA_ROUTE_ISIS] = 2,    [ZEBRA_ROUTE_NHRP] = 2, +		[ZEBRA_ROUTE_BGP] = 3,     [ZEBRA_ROUTE_HSLS] = 4, +		[ZEBRA_ROUTE_TABLE] = 1,  };  /* Look into the RN and queue it into one or more priority queues,   * increasing the size for each data push done.   */ -static void -rib_meta_queue_add (struct meta_queue *mq, struct route_node *rn) +static void rib_meta_queue_add(struct meta_queue *mq, struct route_node *rn)  { -  struct rib *rib; - -  RNODE_FOREACH_RIB (rn, rib) -    { -      u_char qindex = meta_queue_map[rib->type]; -      struct zebra_vrf *zvrf; +	struct rib *rib; -      /* Invariant: at this point we always have rn->info set. */ -      if (CHECK_FLAG (rib_dest_from_rnode (rn)->flags, -		      RIB_ROUTE_QUEUED (qindex))) +	RNODE_FOREACH_RIB(rn, rib)  	{ -	  if (IS_ZEBRA_DEBUG_RIB_DETAILED) -	    rnode_debug (rn, rib->vrf_id,  "rn %p is already queued in sub-queue %u", -			 (void *)rn, qindex); -	  continue; -	} +		u_char qindex = meta_queue_map[rib->type]; +		struct zebra_vrf *zvrf; + +		/* Invariant: at this point we always have rn->info set. */ +		if (CHECK_FLAG(rib_dest_from_rnode(rn)->flags, +			       RIB_ROUTE_QUEUED(qindex))) { +			if (IS_ZEBRA_DEBUG_RIB_DETAILED) +				rnode_debug( +					rn, rib->vrf_id, +					"rn %p is already queued in sub-queue %u", +					(void *)rn, qindex); +			continue; +		} -      SET_FLAG (rib_dest_from_rnode (rn)->flags, RIB_ROUTE_QUEUED (qindex)); -      listnode_add (mq->subq[qindex], rn); -      route_lock_node (rn); -      mq->size++; +		SET_FLAG(rib_dest_from_rnode(rn)->flags, +			 RIB_ROUTE_QUEUED(qindex)); +		listnode_add(mq->subq[qindex], rn); +		route_lock_node(rn); +		mq->size++; -      if (IS_ZEBRA_DEBUG_RIB_DETAILED) -	rnode_debug (rn, rib->vrf_id, "queued rn %p into sub-queue %u", -		     (void *)rn, qindex); +		if (IS_ZEBRA_DEBUG_RIB_DETAILED) +			rnode_debug(rn, rib->vrf_id, +				    "queued rn %p into sub-queue %u", +				    (void *)rn, qindex); -      zvrf = zebra_vrf_lookup_by_id (rib->vrf_id); -      if (zvrf) -          zvrf->flags |= ZEBRA_VRF_RIB_SCHEDULED; -    } +		zvrf = zebra_vrf_lookup_by_id(rib->vrf_id); +		if (zvrf) +			zvrf->flags |= ZEBRA_VRF_RIB_SCHEDULED; +	}  }  /* Add route_node to work queue and schedule processing */ -void -rib_queue_add (struct route_node *rn) +void rib_queue_add(struct route_node *rn)  { -  assert (rn); -   -  /* Pointless to queue a route_node with no RIB entries to add or remove */ -  if (!rnode_to_ribs (rn)) -    { -      zlog_debug ("%s: called for route_node (%p, %d) with no ribs", -                  __func__, (void *)rn, rn->lock); -      zlog_backtrace(LOG_DEBUG); -      return; -    } +	assert(rn); -  if (zebrad.ribq == NULL) -    { -      zlog_err ("%s: work_queue does not exist!", __func__); -      return; -    } +	/* Pointless to queue a route_node with no RIB entries to add or remove +	 */ +	if (!rnode_to_ribs(rn)) { +		zlog_debug("%s: called for route_node (%p, %d) with no ribs", +			   __func__, (void *)rn, rn->lock); +		zlog_backtrace(LOG_DEBUG); +		return; +	} + +	if (zebrad.ribq == NULL) { +		zlog_err("%s: work_queue does not exist!", __func__); +		return; +	} -  /* -   * The RIB queue should normally be either empty or holding the only -   * work_queue_item element. In the latter case this element would -   * hold a pointer to the meta queue structure, which must be used to -   * actually queue the route nodes to process. So create the MQ -   * holder, if necessary, then push the work into it in any case. -   * This semantics was introduced after 0.99.9 release. -   */ -  if (!zebrad.ribq->items->count) -    work_queue_add (zebrad.ribq, zebrad.mq); +	/* +	 * The RIB queue should normally be either empty or holding the only +	 * work_queue_item element. In the latter case this element would +	 * hold a pointer to the meta queue structure, which must be used to +	 * actually queue the route nodes to process. So create the MQ +	 * holder, if necessary, then push the work into it in any case. +	 * This semantics was introduced after 0.99.9 release. +	 */ +	if (!zebrad.ribq->items->count) +		work_queue_add(zebrad.ribq, zebrad.mq); -  rib_meta_queue_add (zebrad.mq, rn); +	rib_meta_queue_add(zebrad.mq, rn); -  return; +	return;  }  /* Create new meta queue.     A destructor function doesn't seem to be necessary here.   */ -static struct meta_queue * -meta_queue_new (void) +static struct meta_queue *meta_queue_new(void)  { -  struct meta_queue *new; -  unsigned i; +	struct meta_queue *new; +	unsigned i; -  new = XCALLOC (MTYPE_WORK_QUEUE, sizeof (struct meta_queue)); -  assert(new); +	new = XCALLOC(MTYPE_WORK_QUEUE, sizeof(struct meta_queue)); +	assert(new); -  for (i = 0; i < MQ_SIZE; i++) -    { -      new->subq[i] = list_new (); -      assert(new->subq[i]); -    } +	for (i = 0; i < MQ_SIZE; i++) { +		new->subq[i] = list_new(); +		assert(new->subq[i]); +	} -  return new; +	return new;  } -void -meta_queue_free (struct meta_queue *mq) +void meta_queue_free(struct meta_queue *mq)  { -  unsigned i; +	unsigned i; -  for (i = 0; i < MQ_SIZE; i++) -    list_delete (mq->subq[i]); +	for (i = 0; i < MQ_SIZE; i++) +		list_delete(mq->subq[i]); -  XFREE (MTYPE_WORK_QUEUE, mq); +	XFREE(MTYPE_WORK_QUEUE, mq);  }  /* initialise zebra rib work queue */ -static void -rib_queue_init (struct zebra_t *zebra) +static void rib_queue_init(struct zebra_t *zebra)  { -  assert (zebra); -   -  if (! (zebra->ribq = work_queue_new (zebra->master,  -                                       "route_node processing"))) -    { -      zlog_err ("%s: could not initialise work queue!", __func__); -      return; -    } +	assert(zebra); -  /* fill in the work queue spec */ -  zebra->ribq->spec.workfunc = &meta_queue_process; -  zebra->ribq->spec.errorfunc = NULL; -  zebra->ribq->spec.completion_func = &meta_queue_process_complete; -  /* XXX: TODO: These should be runtime configurable via vty */ -  zebra->ribq->spec.max_retries = 3; -  zebra->ribq->spec.hold = rib_process_hold_time; -   -  if (!(zebra->mq = meta_queue_new ())) -  { -    zlog_err ("%s: could not initialise meta queue!", __func__); -    return; -  } -  return; +	if (!(zebra->ribq = +		      work_queue_new(zebra->master, "route_node processing"))) { +		zlog_err("%s: could not initialise work queue!", __func__); +		return; +	} + +	/* fill in the work queue spec */ +	zebra->ribq->spec.workfunc = &meta_queue_process; +	zebra->ribq->spec.errorfunc = NULL; +	zebra->ribq->spec.completion_func = &meta_queue_process_complete; +	/* XXX: TODO: These should be runtime configurable via vty */ +	zebra->ribq->spec.max_retries = 3; +	zebra->ribq->spec.hold = rib_process_hold_time; + +	if (!(zebra->mq = meta_queue_new())) { +		zlog_err("%s: could not initialise meta queue!", __func__); +		return; +	} +	return;  }  /* RIB updates are processed via a queue of pointers to route_nodes. @@ -1993,7 +2057,7 @@ rib_queue_init (struct zebra_t *zebra)   * ('dest'). Queueing state for a route_node is kept on the dest. The   * dest is created on-demand by rib_link() and is kept around at least   * as long as there are ribs hanging off it (@see rib_gc_dest()). - *  + *   * Refcounting (aka "locking" throughout the GNU Zebra and Quagga code):   *   * - route_nodes: refcounted by: @@ -2003,65 +2067,59 @@ rib_queue_init (struct zebra_t *zebra)   *     - managed by: rib_addqueue, rib_process.   *   */ -  -/* Add RIB to head of the route node. */ -static void -rib_link (struct route_node *rn, struct rib *rib, int process) -{ -  struct rib *head; -  rib_dest_t *dest; -  afi_t afi; -  const char *rmap_name; - -  assert (rib && rn); -   -  dest = rib_dest_from_rnode (rn); -  if (!dest) -    { -      if (IS_ZEBRA_DEBUG_RIB_DETAILED) -        rnode_debug (rn, rib->vrf_id, "rn %p adding dest", rn); -      dest = XCALLOC (MTYPE_RIB_DEST, sizeof (rib_dest_t)); -      route_lock_node (rn); /* rn route table reference */ -      rn->info = dest; -      dest->rnode = rn; -    } +/* Add RIB to head of the route node. */ +static void rib_link(struct route_node *rn, struct rib *rib, int process) +{ +	struct rib *head; +	rib_dest_t *dest; +	afi_t afi; +	const char *rmap_name; -  head = dest->routes; -  if (head) -    { -      head->prev = rib; -    } -  rib->next = head; -  dest->routes = rib; +	assert(rib && rn); -  afi = (rn->p.family == AF_INET) ? AFI_IP : -    (rn->p.family == AF_INET6) ? AFI_IP6 : AFI_MAX; -  if (is_zebra_import_table_enabled (afi, rib->table)) -    { -      rmap_name = zebra_get_import_table_route_map (afi, rib->table); -      zebra_add_import_table_entry(rn, rib, rmap_name); -    } -  else -    if (process) -      rib_queue_add (rn); -} +	dest = rib_dest_from_rnode(rn); +	if (!dest) { +		if (IS_ZEBRA_DEBUG_RIB_DETAILED) +			rnode_debug(rn, rib->vrf_id, "rn %p adding dest", rn); -void -rib_addnode (struct route_node *rn, struct rib *rib, int process) -{ -  /* RIB node has been un-removed before route-node is processed.  -   * route_node must hence already be on the queue for processing..  -   */ -  if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) -    { -      if (IS_ZEBRA_DEBUG_RIB) -	  rnode_debug (rn, rib->vrf_id, "rn %p, un-removed rib %p", (void *)rn, (void *)rib); +		dest = XCALLOC(MTYPE_RIB_DEST, sizeof(rib_dest_t)); +		route_lock_node(rn); /* rn route table reference */ +		rn->info = dest; +		dest->rnode = rn; +	} -      UNSET_FLAG (rib->status, RIB_ENTRY_REMOVED); -      return; -    } -  rib_link (rn, rib, process); +	head = dest->routes; +	if (head) { +		head->prev = rib; +	} +	rib->next = head; +	dest->routes = rib; + +	afi = (rn->p.family == AF_INET) +		      ? AFI_IP +		      : (rn->p.family == AF_INET6) ? AFI_IP6 : AFI_MAX; +	if (is_zebra_import_table_enabled(afi, rib->table)) { +		rmap_name = zebra_get_import_table_route_map(afi, rib->table); +		zebra_add_import_table_entry(rn, rib, rmap_name); +	} else if (process) +		rib_queue_add(rn); +} + +void rib_addnode(struct route_node *rn, struct rib *rib, int process) +{ +	/* RIB node has been un-removed before route-node is processed. +	 * route_node must hence already be on the queue for processing.. +	 */ +	if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED)) { +		if (IS_ZEBRA_DEBUG_RIB) +			rnode_debug(rn, rib->vrf_id, "rn %p, un-removed rib %p", +				    (void *)rn, (void *)rib); + +		UNSET_FLAG(rib->status, RIB_ENTRY_REMOVED); +		return; +	} +	rib_link(rn, rib, process);  }  /* @@ -2073,64 +2131,60 @@ rib_addnode (struct route_node *rn, struct rib *rib, int process)   * rib_gc_dest() at some point. This allows a rib_dest_t that is no   * longer required to be deleted.   */ -void -rib_unlink (struct route_node *rn, struct rib *rib) +void rib_unlink(struct route_node *rn, struct rib *rib)  { -  rib_dest_t *dest; - -  assert (rn && rib); - -  if (IS_ZEBRA_DEBUG_RIB) -	  rnode_debug (rn, rib->vrf_id, "rn %p, rib %p", (void *)rn, (void *)rib); - -  dest = rib_dest_from_rnode (rn); +	rib_dest_t *dest; -  if (rib->next) -    rib->next->prev = rib->prev; +	assert(rn && rib); -  if (rib->prev) -    rib->prev->next = rib->next; -  else -    { -      dest->routes = rib->next; -    } +	if (IS_ZEBRA_DEBUG_RIB) +		rnode_debug(rn, rib->vrf_id, "rn %p, rib %p", (void *)rn, +			    (void *)rib); -  /* free RIB and nexthops */ -  zebra_deregister_rnh_static_nexthops (rib->vrf_id, rib->nexthop, rn); -  nexthops_free(rib->nexthop); -  XFREE (MTYPE_RIB, rib); +	dest = rib_dest_from_rnode(rn); -} +	if (rib->next) +		rib->next->prev = rib->prev; -void -rib_delnode (struct route_node *rn, struct rib *rib) -{ -  afi_t afi; +	if (rib->prev) +		rib->prev->next = rib->next; +	else { +		dest->routes = rib->next; +	} -  if (IS_ZEBRA_DEBUG_RIB) -    rnode_debug (rn, rib->vrf_id, "rn %p, rib %p, removing", (void *)rn, (void *)rib); -  SET_FLAG (rib->status, RIB_ENTRY_REMOVED); +	/* free RIB and nexthops */ +	zebra_deregister_rnh_static_nexthops(rib->vrf_id, rib->nexthop, rn); +	nexthops_free(rib->nexthop); +	XFREE(MTYPE_RIB, rib); +} + +void rib_delnode(struct route_node *rn, struct rib *rib) +{ +	afi_t afi; + +	if (IS_ZEBRA_DEBUG_RIB) +		rnode_debug(rn, rib->vrf_id, "rn %p, rib %p, removing", +			    (void *)rn, (void *)rib); +	SET_FLAG(rib->status, RIB_ENTRY_REMOVED); + +	afi = (rn->p.family == AF_INET) +		      ? AFI_IP +		      : (rn->p.family == AF_INET6) ? AFI_IP6 : AFI_MAX; +	if (is_zebra_import_table_enabled(afi, rib->table)) { +		zebra_del_import_table_entry(rn, rib); +		/* Just clean up if non main table */ +		if (IS_ZEBRA_DEBUG_RIB) { +			char buf[SRCDEST2STR_BUFFER]; +			srcdest_rnode2str(rn, buf, sizeof(buf)); +			zlog_debug( +				"%u:%s: Freeing route rn %p, rib %p (type %d)", +				rib->vrf_id, buf, rn, rib, rib->type); +		} -  afi = (rn->p.family == AF_INET) ? AFI_IP : -          (rn->p.family == AF_INET6) ? AFI_IP6 : AFI_MAX; -  if (is_zebra_import_table_enabled (afi, rib->table)) -    { -      zebra_del_import_table_entry(rn, rib); -      /* Just clean up if non main table */ -      if (IS_ZEBRA_DEBUG_RIB) -        { -          char buf[SRCDEST2STR_BUFFER]; -          srcdest_rnode2str(rn, buf, sizeof(buf)); -          zlog_debug ("%u:%s: Freeing route rn %p, rib %p (type %d)", -                      rib->vrf_id, buf, rn, rib, rib->type); -        } - -      rib_unlink(rn, rib); -    } -  else -    { -      rib_queue_add (rn); -    } +		rib_unlink(rn, rib); +	} else { +		rib_queue_add(rn); +	}  }  /* This function dumps the contents of a given RIB entry into @@ -2138,116 +2192,96 @@ rib_delnode (struct route_node *rn, struct rib *rib)   * question are passed as 1st and 2nd arguments.   */ -void _rib_dump (const char * func, -                union prefixconstptr pp, -                union prefixconstptr src_pp, -                const struct rib * rib) -{ -  const struct prefix *p = pp.p; -  const struct prefix *src_p = src_pp.p; -  bool is_srcdst = src_p && src_p->prefixlen; -  char straddr[PREFIX_STRLEN]; -  char srcaddr[PREFIX_STRLEN]; -  struct nexthop *nexthop, *tnexthop; -  int recursing; - -  zlog_debug ("%s: dumping RIB entry %p for %s%s%s vrf %u", func, (const void *)rib, -              prefix2str(pp, straddr, sizeof(straddr)), -              is_srcdst ? " from " : "", -              is_srcdst ? prefix2str(src_pp, srcaddr, sizeof(srcaddr)) : "", -              rib->vrf_id); -  zlog_debug -  ( -    "%s: refcnt == %lu, uptime == %lu, type == %u, instance == %d, table == %d", -    func, -    rib->refcnt, -    (unsigned long) rib->uptime, -    rib->type, -    rib->instance, -    rib->table -  ); -  zlog_debug -  ( -    "%s: metric == %u, mtu == %u, distance == %u, flags == %u, status == %u", -    func, -    rib->metric, -    rib->mtu, -    rib->distance, -    rib->flags, -    rib->status -  ); -  zlog_debug -  ( -    "%s: nexthop_num == %u, nexthop_active_num == %u", -    func, -    rib->nexthop_num, -    rib->nexthop_active_num -  ); - -  for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) -    { -      inet_ntop (p->family, &nexthop->gate, straddr, INET6_ADDRSTRLEN); -      zlog_debug -      ( -        "%s: %s %s with flags %s%s%s", -        func, -        (recursing ? "  NH" : "NH"), -        straddr, -        (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE) ? "ACTIVE " : ""), -        (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? "FIB " : ""), -        (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE) ? "RECURSIVE" : "") -      ); -    } -  zlog_debug ("%s: dump complete", func); +void _rib_dump(const char *func, union prefixconstptr pp, +	       union prefixconstptr src_pp, const struct rib *rib) +{ +	const struct prefix *p = pp.p; +	const struct prefix *src_p = src_pp.p; +	bool is_srcdst = src_p && src_p->prefixlen; +	char straddr[PREFIX_STRLEN]; +	char srcaddr[PREFIX_STRLEN]; +	struct nexthop *nexthop, *tnexthop; +	int recursing; + +	zlog_debug("%s: dumping RIB entry %p for %s%s%s vrf %u", func, +		   (const void *)rib, prefix2str(pp, straddr, sizeof(straddr)), +		   is_srcdst ? " from " : "", +		   is_srcdst ? prefix2str(src_pp, srcaddr, sizeof(srcaddr)) +			     : "", +		   rib->vrf_id); +	zlog_debug( +		"%s: refcnt == %lu, uptime == %lu, type == %u, instance == %d, table == %d", +		func, rib->refcnt, (unsigned long)rib->uptime, rib->type, +		rib->instance, rib->table); +	zlog_debug( +		"%s: metric == %u, mtu == %u, distance == %u, flags == %u, status == %u", +		func, rib->metric, rib->mtu, rib->distance, rib->flags, +		rib->status); +	zlog_debug("%s: nexthop_num == %u, nexthop_active_num == %u", func, +		   rib->nexthop_num, rib->nexthop_active_num); + +	for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) { +		inet_ntop(p->family, &nexthop->gate, straddr, INET6_ADDRSTRLEN); +		zlog_debug("%s: %s %s with flags %s%s%s", func, +			   (recursing ? "  NH" : "NH"), straddr, +			   (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE) +				    ? "ACTIVE " +				    : ""), +			   (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB) +				    ? "FIB " +				    : ""), +			   (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE) +				    ? "RECURSIVE" +				    : "")); +	} +	zlog_debug("%s: dump complete", func);  }  /* This is an exported helper to rtm_read() to dump the strange   * RIB entry found by rib_lookup_ipv4_route()   */ -void rib_lookup_and_dump (struct prefix_ipv4 * p, vrf_id_t vrf_id) -{ -  struct route_table *table; -  struct route_node *rn; -  struct rib *rib; -  char prefix_buf[INET_ADDRSTRLEN]; - -  /* Lookup table.  */ -  table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id); -  if (! table) -  { -    zlog_err ("%s: zebra_vrf_table() returned NULL", __func__); -    return; -  } - -  /* Scan the RIB table for exactly matching RIB entry. */ -  rn = route_node_lookup (table, (struct prefix *) p); - -  /* No route for this prefix. */ -  if (! rn) -  { -    zlog_debug ("%s: lookup failed for %s", __func__, -                prefix2str((struct prefix*) p, prefix_buf, sizeof(prefix_buf))); -    return; -  } - -  /* Unlock node. */ -  route_unlock_node (rn); - -  /* let's go */ -  RNODE_FOREACH_RIB (rn, rib) -  { -    zlog_debug -    ( -      "%s: rn %p, rib %p: %s, %s", -      __func__, -      (void *)rn, -      (void *)rib, -      (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED) ? "removed" : "NOT removed"), -      (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) ? "selected" : "NOT selected") -    ); -    rib_dump (p, NULL, rib); -  } +void rib_lookup_and_dump(struct prefix_ipv4 *p, vrf_id_t vrf_id) +{ +	struct route_table *table; +	struct route_node *rn; +	struct rib *rib; +	char prefix_buf[INET_ADDRSTRLEN]; + +	/* Lookup table.  */ +	table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id); +	if (!table) { +		zlog_err("%s: zebra_vrf_table() returned NULL", __func__); +		return; +	} + +	/* Scan the RIB table for exactly matching RIB entry. */ +	rn = route_node_lookup(table, (struct prefix *)p); + +	/* No route for this prefix. */ +	if (!rn) { +		zlog_debug("%s: lookup failed for %s", __func__, +			   prefix2str((struct prefix *)p, prefix_buf, +				      sizeof(prefix_buf))); +		return; +	} + +	/* Unlock node. */ +	route_unlock_node(rn); + +	/* let's go */ +	RNODE_FOREACH_RIB(rn, rib) +	{ +		zlog_debug("%s: rn %p, rib %p: %s, %s", __func__, (void *)rn, +			   (void *)rib, +			   (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED) +				    ? "removed" +				    : "NOT removed"), +			   (CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED) +				    ? "selected" +				    : "NOT selected")); +		rib_dump(p, NULL, rib); +	}  }  /* Check if requested address assignment will fail due to another @@ -2255,638 +2289,629 @@ void rib_lookup_and_dump (struct prefix_ipv4 * p, vrf_id_t vrf_id)   * actions, if needed: remove such a route from FIB and deSELECT   * corresponding RIB entry. Then put affected RN into RIBQ head.   */ -void rib_lookup_and_pushup (struct prefix_ipv4 * p, vrf_id_t vrf_id) -{ -  struct route_table *table; -  struct route_node *rn; -  struct rib *rib; -  unsigned changed = 0; - -  if (NULL == (table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id))) -  { -    zlog_err ("%s: zebra_vrf_table() returned NULL", __func__); -    return; -  } - -  /* No matches would be the simplest case. */ -  if (NULL == (rn = route_node_lookup (table, (struct prefix *) p))) -    return; - -  /* Unlock node. */ -  route_unlock_node (rn); - -  /* Check all RIB entries. In case any changes have to be done, requeue -   * the RN into RIBQ head. If the routing message about the new connected -   * route (generated by the IP address we are going to assign very soon) -   * comes before the RIBQ is processed, the new RIB entry will join -   * RIBQ record already on head. This is necessary for proper revalidation -   * of the rest of the RIB. -   */ -  RNODE_FOREACH_RIB (rn, rib) -  { -    if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB) && -      ! RIB_SYSTEM_ROUTE (rib)) -    { -      changed = 1; -      if (IS_ZEBRA_DEBUG_RIB) -      { -        char buf[PREFIX_STRLEN]; -        zlog_debug ("%u:%s: freeing way for connected prefix", -                    rib->vrf_id, prefix2str(&rn->p, buf, sizeof(buf))); -        rib_dump (&rn->p, NULL, rib); -      } -      rib_uninstall (rn, rib); -    } -  } -  if (changed) -    rib_queue_add (rn); +void rib_lookup_and_pushup(struct prefix_ipv4 *p, vrf_id_t vrf_id) +{ +	struct route_table *table; +	struct route_node *rn; +	struct rib *rib; +	unsigned changed = 0; + +	if (NULL == (table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id))) { +		zlog_err("%s: zebra_vrf_table() returned NULL", __func__); +		return; +	} + +	/* No matches would be the simplest case. */ +	if (NULL == (rn = route_node_lookup(table, (struct prefix *)p))) +		return; + +	/* Unlock node. */ +	route_unlock_node(rn); + +	/* Check all RIB entries. In case any changes have to be done, requeue +	 * the RN into RIBQ head. If the routing message about the new connected +	 * route (generated by the IP address we are going to assign very soon) +	 * comes before the RIBQ is processed, the new RIB entry will join +	 * RIBQ record already on head. This is necessary for proper +	 * revalidation +	 * of the rest of the RIB. +	 */ +	RNODE_FOREACH_RIB(rn, rib) +	{ +		if (CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB) +		    && !RIB_SYSTEM_ROUTE(rib)) { +			changed = 1; +			if (IS_ZEBRA_DEBUG_RIB) { +				char buf[PREFIX_STRLEN]; +				zlog_debug( +					"%u:%s: freeing way for connected prefix", +					rib->vrf_id, +					prefix2str(&rn->p, buf, sizeof(buf))); +				rib_dump(&rn->p, NULL, rib); +			} +			rib_uninstall(rn, rib); +		} +	} +	if (changed) +		rib_queue_add(rn);  } -int -rib_add_multipath (afi_t afi, safi_t safi, struct prefix *p, -		   struct prefix_ipv6 *src_p, struct rib *rib) +int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p, +		      struct prefix_ipv6 *src_p, struct rib *rib)  { -  struct route_table *table; -  struct route_node *rn; -  struct rib *same; -  struct nexthop *nexthop; -  int ret = 0; -  int family; +	struct route_table *table; +	struct route_node *rn; +	struct rib *same; +	struct nexthop *nexthop; +	int ret = 0; +	int family; -  if (!rib) -    return 0; +	if (!rib) +		return 0; -  if (p->family == AF_INET) -    family = AFI_IP; -  else -    family = AFI_IP6; +	if (p->family == AF_INET) +		family = AFI_IP; +	else +		family = AFI_IP6; -  assert(!src_p || family == AFI_IP6); +	assert(!src_p || family == AFI_IP6); -  /* Lookup table.  */ -  table = zebra_vrf_table_with_table_id (family, safi, rib->vrf_id, rib->table); -  if (! table) -    return 0; +	/* Lookup table.  */ +	table = zebra_vrf_table_with_table_id(family, safi, rib->vrf_id, +					      rib->table); +	if (!table) +		return 0; -  /* Make it sure prefixlen is applied to the prefix. */ -  apply_mask (p); -  if (src_p) -    apply_mask_ipv6 (src_p); +	/* Make it sure prefixlen is applied to the prefix. */ +	apply_mask(p); +	if (src_p) +		apply_mask_ipv6(src_p); -  /* Set default distance by route type. */ -  if (rib->distance == 0) -    { -      rib->distance = route_info[rib->type].distance; +	/* Set default distance by route type. */ +	if (rib->distance == 0) { +		rib->distance = route_info[rib->type].distance; -      /* iBGP distance is 200. */ -      if (rib->type == ZEBRA_ROUTE_BGP  -	  && CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP)) -	rib->distance = 200; -    } +		/* iBGP distance is 200. */ +		if (rib->type == ZEBRA_ROUTE_BGP +		    && CHECK_FLAG(rib->flags, ZEBRA_FLAG_IBGP)) +			rib->distance = 200; +	} -  /* Lookup route node.*/ -  rn = srcdest_rnode_get (table, p, src_p); +	/* Lookup route node.*/ +	rn = srcdest_rnode_get(table, p, src_p); -  /* If same type of route are installed, treat it as a implicit -     withdraw. */ -  RNODE_FOREACH_RIB (rn, same) -    { -      if (CHECK_FLAG (same->status, RIB_ENTRY_REMOVED)) -        continue; -       -      if (same->type == rib->type && same->instance == rib->instance -          && same->table == rib->table -	  && same->type != ZEBRA_ROUTE_CONNECT) -        break; -    } -   -  /* If this route is kernel route, set FIB flag to the route. */ -  if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT) -    for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) -      SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); - -  /* Link new rib to node.*/ -  if (IS_ZEBRA_DEBUG_RIB) -    { -      rnode_debug(rn, rib->vrf_id, "Inserting route rn %p, rib %p (type %d) existing %p", -                  (void *)rn, (void *)rib, rib->type, (void *)same); +	/* If same type of route are installed, treat it as a implicit +	   withdraw. */ +	RNODE_FOREACH_RIB(rn, same) +	{ +		if (CHECK_FLAG(same->status, RIB_ENTRY_REMOVED)) +			continue; -      if (IS_ZEBRA_DEBUG_RIB_DETAILED) -        rib_dump (p, src_p, rib); -    } -  rib_addnode (rn, rib, 1); -  ret = 1; +		if (same->type == rib->type && same->instance == rib->instance +		    && same->table == rib->table +		    && same->type != ZEBRA_ROUTE_CONNECT) +			break; +	} -  /* Free implicit route.*/ -  if (same) -    { -      rib_delnode (rn, same); -      ret = -1; -    } -   -  route_unlock_node (rn); -  return ret; -} +	/* If this route is kernel route, set FIB flag to the route. */ +	if (rib->type == ZEBRA_ROUTE_KERNEL || rib->type == ZEBRA_ROUTE_CONNECT) +		for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) +			SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); -void -rib_delete (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, -	    int flags, struct prefix *p, struct prefix_ipv6 *src_p, -	    union g_addr *gate, ifindex_t ifindex, u_int32_t table_id) -{ -  struct route_table *table; -  struct route_node *rn; -  struct rib *rib; -  struct rib *fib = NULL; -  struct rib *same = NULL; -  struct nexthop *nexthop, *tnexthop; -  int recursing; -  char buf2[INET6_ADDRSTRLEN]; - -  assert(!src_p || afi == AFI_IP6); - -  /* Lookup table.  */ -  table = zebra_vrf_table_with_table_id (afi, safi, vrf_id, table_id); -  if (! table) -    return; - -  /* Apply mask. */ -  apply_mask (p); -  if (src_p) -    apply_mask_ipv6 (src_p); - -  /* Lookup route node. */ -  rn = srcdest_rnode_lookup (table, p, src_p); -  if (! rn) -    { -      char dst_buf[PREFIX_STRLEN], src_buf[PREFIX_STRLEN]; - -      prefix2str(p, dst_buf, sizeof(dst_buf)); -      if (src_p && src_p->prefixlen) -        prefix2str(src_p, src_buf, sizeof(src_buf)); -      else -        src_buf[0] = '\0'; - -      if (IS_ZEBRA_DEBUG_RIB) -        zlog_debug ("%u:%s%s%s doesn't exist in rib", -                    vrf_id, dst_buf, -                    (src_buf[0] != '\0') ? " from " : "", -                    src_buf); -      return; -    } +	/* Link new rib to node.*/ +	if (IS_ZEBRA_DEBUG_RIB) { +		rnode_debug( +			rn, rib->vrf_id, +			"Inserting route rn %p, rib %p (type %d) existing %p", +			(void *)rn, (void *)rib, rib->type, (void *)same); -  /* Lookup same type route. */ -  RNODE_FOREACH_RIB (rn, rib) -    { -      if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) -        continue; - -      if (CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB)) -	fib = rib; - -      if (rib->type != type) -	continue; -      if (rib->instance != instance) -	continue; -      if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) && -	  nexthop->type == NEXTHOP_TYPE_IFINDEX) -	{ -	  if (nexthop->ifindex != ifindex) -	    continue; -	  if (rib->refcnt) -	    { -	      rib->refcnt--; -	      route_unlock_node (rn); -	      route_unlock_node (rn); -	      return; -	    } -	  same = rib; -	  break; -	} -      /* Make sure that the route found has the same gateway. */ -      else -        { -          if (gate == NULL) -            { -              same = rib; -              break; -            } -          for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) -            if (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate) || -	        IPV6_ADDR_SAME (&nexthop->gate.ipv6, gate)) -              { -                same = rib; -                break; -              } -          if (same) -            break; -        } -    } -  /* If same type of route can't be found and this message is from -     kernel. */ -  if (! same) -    { -      if (fib && type == ZEBRA_ROUTE_KERNEL && -          CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE)) -        { -          if (IS_ZEBRA_DEBUG_RIB) -            { -              rnode_debug (rn, vrf_id, "rn %p, rib %p (type %d) was deleted from kernel, adding", -                           rn, fib, fib->type); -            } -	  if (allow_delete) -	    { -	      /* Unset flags. */ -	      for (nexthop = fib->nexthop; nexthop; nexthop = nexthop->next) -		UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); - -	      UNSET_FLAG (fib->status, RIB_ENTRY_SELECTED_FIB); -	    } -	  else -	    { -	      /* This means someone else, other than Zebra, has deleted -	       * a Zebra router from the kernel. We will add it back */ -	      rib_install_kernel(rn, fib, NULL); -	    } -        } -      else -	{ -	  if (IS_ZEBRA_DEBUG_RIB) -	    { -	      if (gate) -		rnode_debug(rn, vrf_id, "via %s ifindex %d type %d " -			   "doesn't exist in rib", -			    inet_ntop (family2afi(afi), gate, buf2, INET_ADDRSTRLEN), /* FIXME */ -			    ifindex, -			    type); -	      else -		rnode_debug (rn, vrf_id, "ifindex %d type %d doesn't exist in rib", -			    ifindex, -			    type); -	    } -	  route_unlock_node (rn); -	  return; +		if (IS_ZEBRA_DEBUG_RIB_DETAILED) +			rib_dump(p, src_p, rib);  	} -    } -   -  if (same) -    rib_delnode (rn, same); -   -  route_unlock_node (rn); -  return; -} +	rib_addnode(rn, rib, 1); +	ret = 1; +	/* Free implicit route.*/ +	if (same) { +		rib_delnode(rn, same); +		ret = -1; +	} +	route_unlock_node(rn); +	return ret; +} + +void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, +		u_short instance, int flags, struct prefix *p, +		struct prefix_ipv6 *src_p, union g_addr *gate, +		ifindex_t ifindex, u_int32_t table_id) +{ +	struct route_table *table; +	struct route_node *rn; +	struct rib *rib; +	struct rib *fib = NULL; +	struct rib *same = NULL; +	struct nexthop *nexthop, *tnexthop; +	int recursing; +	char buf2[INET6_ADDRSTRLEN]; + +	assert(!src_p || afi == AFI_IP6); + +	/* Lookup table.  */ +	table = zebra_vrf_table_with_table_id(afi, safi, vrf_id, table_id); +	if (!table) +		return; + +	/* Apply mask. */ +	apply_mask(p); +	if (src_p) +		apply_mask_ipv6(src_p); + +	/* Lookup route node. */ +	rn = srcdest_rnode_lookup(table, p, src_p); +	if (!rn) { +		char dst_buf[PREFIX_STRLEN], src_buf[PREFIX_STRLEN]; + +		prefix2str(p, dst_buf, sizeof(dst_buf)); +		if (src_p && src_p->prefixlen) +			prefix2str(src_p, src_buf, sizeof(src_buf)); +		else +			src_buf[0] = '\0'; + +		if (IS_ZEBRA_DEBUG_RIB) +			zlog_debug("%u:%s%s%s doesn't exist in rib", vrf_id, +				   dst_buf, +				   (src_buf[0] != '\0') ? " from " : "", +				   src_buf); +		return; +	} -int -rib_add (afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, -	 u_short instance, int flags, struct prefix *p, -	 struct prefix_ipv6 *src_p, union g_addr *gate, -	 union g_addr *src, ifindex_t ifindex, -	 u_int32_t table_id, u_int32_t metric, u_int32_t mtu, -	 u_char distance) -{ -  struct rib *rib; -  struct rib *same = NULL; -  struct route_table *table; -  struct route_node *rn; -  struct nexthop *nexthop; +	/* Lookup same type route. */ +	RNODE_FOREACH_RIB(rn, rib) +	{ +		if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED)) +			continue; + +		if (CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB)) +			fib = rib; + +		if (rib->type != type) +			continue; +		if (rib->instance != instance) +			continue; +		if (rib->type == ZEBRA_ROUTE_CONNECT && (nexthop = rib->nexthop) +		    && nexthop->type == NEXTHOP_TYPE_IFINDEX) { +			if (nexthop->ifindex != ifindex) +				continue; +			if (rib->refcnt) { +				rib->refcnt--; +				route_unlock_node(rn); +				route_unlock_node(rn); +				return; +			} +			same = rib; +			break; +		} +		/* Make sure that the route found has the same gateway. */ +		else { +			if (gate == NULL) { +				same = rib; +				break; +			} +			for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, +					     recursing)) +				if (IPV4_ADDR_SAME(&nexthop->gate.ipv4, gate) +				    || IPV6_ADDR_SAME(&nexthop->gate.ipv6, +						      gate)) { +					same = rib; +					break; +				} +			if (same) +				break; +		} +	} +	/* If same type of route can't be found and this message is from +	   kernel. */ +	if (!same) { +		if (fib && type == ZEBRA_ROUTE_KERNEL +		    && CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE)) { +			if (IS_ZEBRA_DEBUG_RIB) { +				rnode_debug( +					rn, vrf_id, +					"rn %p, rib %p (type %d) was deleted from kernel, adding", +					rn, fib, fib->type); +			} +			if (allow_delete) { +				/* Unset flags. */ +				for (nexthop = fib->nexthop; nexthop; +				     nexthop = nexthop->next) +					UNSET_FLAG(nexthop->flags, +						   NEXTHOP_FLAG_FIB); + +				UNSET_FLAG(fib->status, RIB_ENTRY_SELECTED_FIB); +			} else { +				/* This means someone else, other than Zebra, +				 * has deleted +				 * a Zebra router from the kernel. We will add +				 * it back */ +				rib_install_kernel(rn, fib, NULL); +			} +		} else { +			if (IS_ZEBRA_DEBUG_RIB) { +				if (gate) +					rnode_debug( +						rn, vrf_id, +						"via %s ifindex %d type %d " +						"doesn't exist in rib", +						inet_ntop( +							family2afi(afi), gate, +							buf2, +							INET_ADDRSTRLEN), /* FIXME +									     */ +						ifindex, type); +				else +					rnode_debug( +						rn, vrf_id, +						"ifindex %d type %d doesn't exist in rib", +						ifindex, type); +			} +			route_unlock_node(rn); +			return; +		} +	} -  assert(!src_p || afi == AFI_IP6); +	if (same) +		rib_delnode(rn, same); -  /* Lookup table.  */ -  table = zebra_vrf_table_with_table_id (afi, safi, vrf_id, table_id); -  if (! table) -    return 0; +	route_unlock_node(rn); +	return; +} -  /* Make sure mask is applied. */ -  apply_mask (p); -  if (src_p) -    apply_mask_ipv6 (src_p); -  /* Set default distance by route type. */ -  if (distance == 0) -    { -      if ((unsigned)type >= array_size(route_info)) -	distance = 150; -      else -        distance = route_info[type].distance; - -      /* iBGP distance is 200. */ -      if (type == ZEBRA_ROUTE_BGP && CHECK_FLAG (flags, ZEBRA_FLAG_IBGP)) -	distance = 200; -    } +int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, +	    int flags, struct prefix *p, struct prefix_ipv6 *src_p, +	    union g_addr *gate, union g_addr *src, ifindex_t ifindex, +	    u_int32_t table_id, u_int32_t metric, u_int32_t mtu, +	    u_char distance) +{ +	struct rib *rib; +	struct rib *same = NULL; +	struct route_table *table; +	struct route_node *rn; +	struct nexthop *nexthop; + +	assert(!src_p || afi == AFI_IP6); + +	/* Lookup table.  */ +	table = zebra_vrf_table_with_table_id(afi, safi, vrf_id, table_id); +	if (!table) +		return 0; + +	/* Make sure mask is applied. */ +	apply_mask(p); +	if (src_p) +		apply_mask_ipv6(src_p); + +	/* Set default distance by route type. */ +	if (distance == 0) { +		if ((unsigned)type >= array_size(route_info)) +			distance = 150; +		else +			distance = route_info[type].distance; + +		/* iBGP distance is 200. */ +		if (type == ZEBRA_ROUTE_BGP +		    && CHECK_FLAG(flags, ZEBRA_FLAG_IBGP)) +			distance = 200; +	} -  /* Lookup route node.*/ -  rn = srcdest_rnode_get (table,  p, src_p); +	/* Lookup route node.*/ +	rn = srcdest_rnode_get(table, p, src_p); -  /* If same type of route are installed, treat it as a implicit -     withdraw. */ -  RNODE_FOREACH_RIB (rn, rib) -    { -      if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) -        continue; - -      if (rib->type != type) -	continue; -      if (rib->instance != instance) -	continue; -      if (rib->type != ZEBRA_ROUTE_CONNECT) -	{ -	  same = rib; -	  break; -	} -      /* Duplicate connected route comes in. */ -      else if ((nexthop = rib->nexthop) && -	       nexthop->type == NEXTHOP_TYPE_IFINDEX && -	       nexthop->ifindex == ifindex && -	       !CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) +	/* If same type of route are installed, treat it as a implicit +	   withdraw. */ +	RNODE_FOREACH_RIB(rn, rib)  	{ -	  rib->refcnt++; -	  return 0 ; +		if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED)) +			continue; + +		if (rib->type != type) +			continue; +		if (rib->instance != instance) +			continue; +		if (rib->type != ZEBRA_ROUTE_CONNECT) { +			same = rib; +			break; +		} +		/* Duplicate connected route comes in. */ +		else if ((nexthop = rib->nexthop) +			 && nexthop->type == NEXTHOP_TYPE_IFINDEX +			 && nexthop->ifindex == ifindex +			 && !CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED)) { +			rib->refcnt++; +			return 0; +		}  	} -    } -  /* Allocate new rib structure. */ -  rib = XCALLOC (MTYPE_RIB, sizeof (struct rib)); -   -  rib->type = type; -  rib->instance = instance; -  rib->distance = distance; -  rib->flags = flags; -  rib->metric = metric; -  rib->mtu = mtu; -  rib->table = table_id; -  rib->vrf_id = vrf_id; -  rib->nexthop_num = 0; -  rib->uptime = time (NULL); - -  /* Nexthop settings. */ -  if (gate) -    { -      if (afi == AFI_IP6) -	{ -	  if (ifindex) -	    rib_nexthop_ipv6_ifindex_add (rib, &gate->ipv6, ifindex); -	  else -	    rib_nexthop_ipv6_add (rib, &gate->ipv6); -	} -      else -	{ -	  if (ifindex) -	    rib_nexthop_ipv4_ifindex_add (rib, &gate->ipv4, &src->ipv4, ifindex); -	  else -	    rib_nexthop_ipv4_add (rib, &gate->ipv4, &src->ipv4); +	/* Allocate new rib structure. */ +	rib = XCALLOC(MTYPE_RIB, sizeof(struct rib)); + +	rib->type = type; +	rib->instance = instance; +	rib->distance = distance; +	rib->flags = flags; +	rib->metric = metric; +	rib->mtu = mtu; +	rib->table = table_id; +	rib->vrf_id = vrf_id; +	rib->nexthop_num = 0; +	rib->uptime = time(NULL); + +	/* Nexthop settings. */ +	if (gate) { +		if (afi == AFI_IP6) { +			if (ifindex) +				rib_nexthop_ipv6_ifindex_add(rib, &gate->ipv6, +							     ifindex); +			else +				rib_nexthop_ipv6_add(rib, &gate->ipv6); +		} else { +			if (ifindex) +				rib_nexthop_ipv4_ifindex_add( +					rib, &gate->ipv4, &src->ipv4, ifindex); +			else +				rib_nexthop_ipv4_add(rib, &gate->ipv4, +						     &src->ipv4); +		} +	} else +		rib_nexthop_ifindex_add(rib, ifindex); + +	/* If this route is kernel route, set FIB flag to the route. */ +	if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT) +		for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) +			SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); + +	/* Link new rib to node.*/ +	if (IS_ZEBRA_DEBUG_RIB) { +		rnode_debug( +			rn, vrf_id, +			"Inserting route rn %p, rib %p (type %d) existing %p", +			(void *)rn, (void *)rib, rib->type, (void *)same); + +		if (IS_ZEBRA_DEBUG_RIB_DETAILED) +			rib_dump(p, src_p, rib);  	} -    } -  else -    rib_nexthop_ifindex_add (rib, ifindex); +	rib_addnode(rn, rib, 1); -  /* If this route is kernel route, set FIB flag to the route. */ -  if (type == ZEBRA_ROUTE_KERNEL || type == ZEBRA_ROUTE_CONNECT) -    for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) -      SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB); +	/* Free implicit route.*/ +	if (same) +		rib_delnode(rn, same); -  /* Link new rib to node.*/ -  if (IS_ZEBRA_DEBUG_RIB) -    { -      rnode_debug (rn, vrf_id, "Inserting route rn %p, rib %p (type %d) existing %p", -                   (void *)rn, (void *)rib, rib->type, (void *)same); - -      if (IS_ZEBRA_DEBUG_RIB_DETAILED) -        rib_dump (p, src_p, rib); -    } -  rib_addnode (rn, rib, 1); - -  /* Free implicit route.*/ -  if (same) -    rib_delnode (rn, same); -   -  route_unlock_node (rn); -  return 0; +	route_unlock_node(rn); +	return 0;  }  /* Schedule routes of a particular table (address-family) based on event. */ -static void -rib_update_table (struct route_table *table, rib_update_event_t event) -{ -  struct route_node *rn; -  struct rib *rib, *next; +static void rib_update_table(struct route_table *table, +			     rib_update_event_t event) +{ +	struct route_node *rn; +	struct rib *rib, *next; + +	/* Walk all routes and queue for processing, if appropriate for +	 * the trigger event. +	 */ +	for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) { +		switch (event) { +		case RIB_UPDATE_IF_CHANGE: +			/* Examine all routes that won't get processed by the +			 * protocol or +			 * triggered by nexthop evaluation (NHT). This would be +			 * system, +			 * kernel and certain static routes. Note that NHT will +			 * get +			 * triggered upon an interface event as connected routes +			 * always +			 * get queued for processing. +			 */ +			RNODE_FOREACH_RIB_SAFE(rn, rib, next) +			{ +				if (rib->type == ZEBRA_ROUTE_OSPF +				    || rib->type == ZEBRA_ROUTE_OSPF6 +				    || rib->type == ZEBRA_ROUTE_BGP) +					continue; /* protocol will handle. */ +				else if (rib->type == ZEBRA_ROUTE_STATIC) { +					struct nexthop *nh; +					for (nh = rib->nexthop; nh; +					     nh = nh->next) +						if (!(nh->type +							      == NEXTHOP_TYPE_IPV4 +						      || nh->type +								 == NEXTHOP_TYPE_IPV6)) +							break; + +					/* If we only have nexthops to a +					 * gateway, NHT will +					 * take care. +					 */ +					if (nh) +						rib_queue_add(rn); +				} else +					rib_queue_add(rn); +			} +			break; + +		case RIB_UPDATE_RMAP_CHANGE: +		case RIB_UPDATE_OTHER: +			/* Right now, examine all routes. Can restrict to a +			 * protocol in +			 * some cases (TODO). +			 */ +			if (rnode_to_ribs(rn)) +				rib_queue_add(rn); +			break; -  /* Walk all routes and queue for processing, if appropriate for -   * the trigger event. -   */ -  for (rn = route_top (table); rn; rn = srcdest_route_next (rn)) -    { -      switch (event) -        { -        case RIB_UPDATE_IF_CHANGE: -          /* Examine all routes that won't get processed by the protocol or -           * triggered by nexthop evaluation (NHT). This would be system, -           * kernel and certain static routes. Note that NHT will get -           * triggered upon an interface event as connected routes always -           * get queued for processing. -           */ -          RNODE_FOREACH_RIB_SAFE (rn, rib, next) -            { -              if (rib->type == ZEBRA_ROUTE_OSPF || -                  rib->type == ZEBRA_ROUTE_OSPF6 || -                  rib->type == ZEBRA_ROUTE_BGP) -                continue; /* protocol will handle. */ -              else if (rib->type == ZEBRA_ROUTE_STATIC) -                { -                  struct nexthop *nh; -                  for (nh = rib->nexthop; nh; nh = nh->next) -                    if (!(nh->type == NEXTHOP_TYPE_IPV4 || -                        nh->type == NEXTHOP_TYPE_IPV6)) -                      break; - -                  /* If we only have nexthops to a gateway, NHT will -                   * take care. -                   */ -                  if (nh) -                    rib_queue_add (rn); -                } -              else -                  rib_queue_add (rn); -            } -          break; - -        case RIB_UPDATE_RMAP_CHANGE: -        case RIB_UPDATE_OTHER: -          /* Right now, examine all routes. Can restrict to a protocol in -           * some cases (TODO). -           */ -          if (rnode_to_ribs (rn)) -            rib_queue_add (rn); -          break; - -        default: -          break; -        } -    } +		default: +			break; +		} +	}  }  /* RIB update function. */ -void -rib_update (vrf_id_t vrf_id, rib_update_event_t event) +void rib_update(vrf_id_t vrf_id, rib_update_event_t event)  { -  struct route_table *table; +	struct route_table *table; -  /* Process routes of interested address-families. */ -  table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id); -  if (table) -    rib_update_table (table, event); +	/* Process routes of interested address-families. */ +	table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id); +	if (table) +		rib_update_table(table, event); -  table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id); -  if (table) -    rib_update_table (table, event); +	table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, vrf_id); +	if (table) +		rib_update_table(table, event);  }  /* Remove all routes which comes from non main table.  */ -static void -rib_weed_table (struct route_table *table) +static void rib_weed_table(struct route_table *table)  { -  struct route_node *rn; -  struct rib *rib; -  struct rib *next; +	struct route_node *rn; +	struct rib *rib; +	struct rib *next; -  if (table) -    for (rn = route_top (table); rn; rn = srcdest_route_next (rn)) -      RNODE_FOREACH_RIB_SAFE (rn, rib, next) -	{ -	  if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) -	    continue; +	if (table) +		for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) +			RNODE_FOREACH_RIB_SAFE(rn, rib, next) +			{ +				if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED)) +					continue; -	  if (rib->table != zebrad.rtm_table_default && -	      rib->table != RT_TABLE_MAIN) -            rib_delnode (rn, rib); -	} +				if (rib->table != zebrad.rtm_table_default +				    && rib->table != RT_TABLE_MAIN) +					rib_delnode(rn, rib); +			}  }  /* Delete all routes from non main table. */ -void -rib_weed_tables (void) +void rib_weed_tables(void)  { -  struct vrf *vrf; -  struct zebra_vrf *zvrf; +	struct vrf *vrf; +	struct zebra_vrf *zvrf; -  RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) -    if ((zvrf = vrf->info) != NULL) -      { -        rib_weed_table (zvrf->table[AFI_IP][SAFI_UNICAST]); -        rib_weed_table (zvrf->table[AFI_IP6][SAFI_UNICAST]); -      } +	RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id) +	if ((zvrf = vrf->info) != NULL) { +		rib_weed_table(zvrf->table[AFI_IP][SAFI_UNICAST]); +		rib_weed_table(zvrf->table[AFI_IP6][SAFI_UNICAST]); +	}  }  /* Delete self installed routes after zebra is relaunched.  */ -static void -rib_sweep_table (struct route_table *table) -{ -  struct route_node *rn; -  struct rib *rib; -  struct rib *next; -  int ret = 0; - -  if (table) -    for (rn = route_top (table); rn; rn = srcdest_route_next (rn)) -      RNODE_FOREACH_RIB_SAFE (rn, rib, next) -	{ -	  if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) -	    continue; - -	  if (rib->type == ZEBRA_ROUTE_KERNEL &&  -	      CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELFROUTE)) -	    { -	      ret = rib_uninstall_kernel (rn, rib); -	      if (! ret) -                rib_delnode (rn, rib); -	    } -	} +static void rib_sweep_table(struct route_table *table) +{ +	struct route_node *rn; +	struct rib *rib; +	struct rib *next; +	int ret = 0; + +	if (table) +		for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) +			RNODE_FOREACH_RIB_SAFE(rn, rib, next) +			{ +				if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED)) +					continue; + +				if (rib->type == ZEBRA_ROUTE_KERNEL +				    && CHECK_FLAG(rib->flags, +						  ZEBRA_FLAG_SELFROUTE)) { +					ret = rib_uninstall_kernel(rn, rib); +					if (!ret) +						rib_delnode(rn, rib); +				} +			}  }  /* Sweep all RIB tables.  */ -void -rib_sweep_route (void) +void rib_sweep_route(void)  { -  struct vrf *vrf; -  struct zebra_vrf *zvrf; +	struct vrf *vrf; +	struct zebra_vrf *zvrf; -  RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) -    if ((zvrf = vrf->info) != NULL) -      { -        rib_sweep_table (zvrf->table[AFI_IP][SAFI_UNICAST]); -        rib_sweep_table (zvrf->table[AFI_IP6][SAFI_UNICAST]); -      } +	RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id) +	if ((zvrf = vrf->info) != NULL) { +		rib_sweep_table(zvrf->table[AFI_IP][SAFI_UNICAST]); +		rib_sweep_table(zvrf->table[AFI_IP6][SAFI_UNICAST]); +	}  }  /* Remove specific by protocol routes from 'table'. */ -static unsigned long -rib_score_proto_table (u_char proto, u_short instance, struct route_table *table) -{ -  struct route_node *rn; -  struct rib *rib; -  struct rib *next; -  unsigned long n = 0; - -  if (table) -    for (rn = route_top (table); rn; rn = srcdest_route_next (rn)) -      RNODE_FOREACH_RIB_SAFE (rn, rib, next) -        { -          if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) -            continue; -          if (rib->type == proto && rib->instance == instance) -            { -              rib_delnode (rn, rib); -              n++; -            } -        } -  return n; +static unsigned long rib_score_proto_table(u_char proto, u_short instance, +					   struct route_table *table) +{ +	struct route_node *rn; +	struct rib *rib; +	struct rib *next; +	unsigned long n = 0; + +	if (table) +		for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) +			RNODE_FOREACH_RIB_SAFE(rn, rib, next) +			{ +				if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED)) +					continue; +				if (rib->type == proto +				    && rib->instance == instance) { +					rib_delnode(rn, rib); +					n++; +				} +			} +	return n;  }  /* Remove specific by protocol routes. */ -unsigned long -rib_score_proto (u_char proto, u_short instance) +unsigned long rib_score_proto(u_char proto, u_short instance)  { -  struct vrf *vrf; -  struct zebra_vrf *zvrf; -  unsigned long cnt = 0; +	struct vrf *vrf; +	struct zebra_vrf *zvrf; +	unsigned long cnt = 0; -  RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) -    if ((zvrf = vrf->info) != NULL) -      cnt += rib_score_proto_table (proto, instance, zvrf->table[AFI_IP][SAFI_UNICAST]) -            +rib_score_proto_table (proto, instance, zvrf->table[AFI_IP6][SAFI_UNICAST]); +	RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id) +	if ((zvrf = vrf->info) != NULL) +		cnt += rib_score_proto_table(proto, instance, +					     zvrf->table[AFI_IP][SAFI_UNICAST]) +		       + rib_score_proto_table( +				 proto, instance, +				 zvrf->table[AFI_IP6][SAFI_UNICAST]); -  return cnt; +	return cnt;  }  /* Close RIB and clean up kernel routes. */ -void -rib_close_table (struct route_table *table) +void rib_close_table(struct route_table *table)  { -  struct route_node *rn; -  rib_table_info_t *info = table->info; -  struct rib *rib; +	struct route_node *rn; +	rib_table_info_t *info = table->info; +	struct rib *rib; -  if (table) -    for (rn = route_top (table); rn; rn = srcdest_route_next (rn)) -      RNODE_FOREACH_RIB (rn, rib) -        { -          if (!CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB)) -	    continue; +	if (table) +		for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) +			RNODE_FOREACH_RIB(rn, rib) +			{ +				if (!CHECK_FLAG(rib->status, +						RIB_ENTRY_SELECTED_FIB)) +					continue; -          if (info->safi == SAFI_UNICAST) -            hook_call(rib_update, rn, NULL); +				if (info->safi == SAFI_UNICAST) +					hook_call(rib_update, rn, NULL); -	  if (! RIB_SYSTEM_ROUTE (rib)) -	    rib_uninstall_kernel (rn, rib); -        } +				if (!RIB_SYSTEM_ROUTE(rib)) +					rib_uninstall_kernel(rn, rib); +			}  }  /* Routing information base initialize. */ -void -rib_init (void) +void rib_init(void)  { -  rib_queue_init (&zebrad); +	rib_queue_init(&zebrad);  }  /* @@ -2896,22 +2921,20 @@ rib_init (void)   *   * Returns TRUE if a vrf id was found, FALSE otherwise.   */ -static inline int -vrf_id_get_next (vrf_id_t vrf_id, vrf_id_t *next_id_p) +static inline int vrf_id_get_next(vrf_id_t vrf_id, vrf_id_t *next_id_p)  { -  struct vrf *vrf; +	struct vrf *vrf; -  vrf = vrf_lookup_by_id (vrf_id); -  if (vrf) -    { -      vrf = RB_NEXT (vrf_id_head, &vrfs_by_id, vrf); -      if (vrf) { -	  *next_id_p = vrf->vrf_id; -	  return 1; -      } -    } +	vrf = vrf_lookup_by_id(vrf_id); +	if (vrf) { +		vrf = RB_NEXT(vrf_id_head, &vrfs_by_id, vrf); +		if (vrf) { +			*next_id_p = vrf->vrf_id; +			return 1; +		} +	} -  return 0; +	return 0;  }  /* @@ -2919,79 +2942,77 @@ vrf_id_get_next (vrf_id_t vrf_id, vrf_id_t *next_id_p)   *   * Returns the next table in the iteration.   */ -struct route_table * -rib_tables_iter_next (rib_tables_iter_t *iter) -{ -  struct route_table *table; - -  /* -   * Array that helps us go over all AFI/SAFI combinations via one -   * index. -   */ -  static struct { -    afi_t afi; -    safi_t safi; -  } afi_safis[] = { -    { AFI_IP, SAFI_UNICAST }, -    { AFI_IP, SAFI_MULTICAST }, -    { AFI_IP6, SAFI_UNICAST }, -    { AFI_IP6, SAFI_MULTICAST }, -  }; - -  table = NULL; - -  switch (iter->state) -    { - -    case RIB_TABLES_ITER_S_INIT: -      iter->vrf_id = VRF_DEFAULT; -      iter->afi_safi_ix = -1; +struct route_table *rib_tables_iter_next(rib_tables_iter_t *iter) +{ +	struct route_table *table; + +	/* +	 * Array that helps us go over all AFI/SAFI combinations via one +	 * index. +	 */ +	static struct { +		afi_t afi; +		safi_t safi; +	} afi_safis[] = { +		{AFI_IP, SAFI_UNICAST}, +		{AFI_IP, SAFI_MULTICAST}, +		{AFI_IP6, SAFI_UNICAST}, +		{AFI_IP6, SAFI_MULTICAST}, +	}; + +	table = NULL; + +	switch (iter->state) { + +	case RIB_TABLES_ITER_S_INIT: +		iter->vrf_id = VRF_DEFAULT; +		iter->afi_safi_ix = -1; + +	/* Fall through */ + +	case RIB_TABLES_ITER_S_ITERATING: +		iter->afi_safi_ix++; +		while (1) { + +			while (iter->afi_safi_ix +			       < (int)ZEBRA_NUM_OF(afi_safis)) { +				table = zebra_vrf_table( +					afi_safis[iter->afi_safi_ix].afi, +					afi_safis[iter->afi_safi_ix].safi, +					iter->vrf_id); +				if (table) +					break; + +				iter->afi_safi_ix++; +			} + +			/* +			 * Found another table in this vrf. +			 */ +			if (table) +				break; -      /* Fall through */ +			/* +			 * Done with all tables in the current vrf, go to the +			 * next +			 * one. +			 */ +			if (!vrf_id_get_next(iter->vrf_id, &iter->vrf_id)) +				break; -    case RIB_TABLES_ITER_S_ITERATING: -      iter->afi_safi_ix++; -      while (1) -	{ +			iter->afi_safi_ix = 0; +		} -	  while (iter->afi_safi_ix < (int) ZEBRA_NUM_OF (afi_safis)) -	    { -	      table = zebra_vrf_table (afi_safis[iter->afi_safi_ix].afi, -				 afi_safis[iter->afi_safi_ix].safi, -				 iter->vrf_id); -	      if (table)  		break; -	      iter->afi_safi_ix++; -	    } - -	  /* -	   * Found another table in this vrf. -	   */ -	  if (table) -	    break; - -	  /* -	   * Done with all tables in the current vrf, go to the next -	   * one. -	   */ -	  if (!vrf_id_get_next (iter->vrf_id, &iter->vrf_id)) -	    break; - -	  iter->afi_safi_ix = 0; +	case RIB_TABLES_ITER_S_DONE: +		return NULL;  	} -      break; +	if (table) +		iter->state = RIB_TABLES_ITER_S_ITERATING; +	else +		iter->state = RIB_TABLES_ITER_S_DONE; -    case RIB_TABLES_ITER_S_DONE: -      return NULL; -    } - -  if (table) -    iter->state = RIB_TABLES_ITER_S_ITERATING; -  else -    iter->state = RIB_TABLES_ITER_S_DONE; - -  return table; +	return table;  } - diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index d5ebbbc466..6762d6c3ab 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -50,21 +50,20 @@  #include "zebra/zebra_memory.h"  static void free_state(vrf_id_t vrf_id, struct rib *rib, struct route_node *rn); -static void copy_state(struct rnh *rnh, struct rib *rib, -		       struct route_node *rn); -#define lookup_rnh_table(v, f)		         \ -({						 \ -  struct zebra_vrf *zvrf;                        \ -  struct route_table *t = NULL;                  \ -  zvrf = zebra_vrf_lookup_by_id(v);              \ -  if (zvrf)                                      \ -    t = zvrf->rnh_table[family2afi(f)];	         \ -  t;                                             \ -}) +static void copy_state(struct rnh *rnh, struct rib *rib, struct route_node *rn); +#define lookup_rnh_table(v, f)                                                 \ +	({                                                                     \ +		struct zebra_vrf *zvrf;                                        \ +		struct route_table *t = NULL;                                  \ +		zvrf = zebra_vrf_lookup_by_id(v);                              \ +		if (zvrf)                                                      \ +			t = zvrf->rnh_table[family2afi(f)];                    \ +		t;                                                             \ +	})  static int compare_state(struct rib *r1, struct rib *r2);  static int send_client(struct rnh *rnh, struct zserv *client, rnh_type_t type, -                       vrf_id_t vrf_id); +		       vrf_id_t vrf_id);  static void print_rnh(struct route_node *rn, struct vty *vty);  int zebra_rnh_ip_default_route = 0; @@ -73,612 +72,592 @@ int zebra_rnh_ipv6_default_route = 0;  static inline struct route_table *get_rnh_table(vrf_id_t vrfid, int family,  						rnh_type_t type)  { -  struct zebra_vrf *zvrf; -  struct route_table *t = NULL; - -  zvrf = zebra_vrf_lookup_by_id(vrfid); -  if (zvrf) -    switch (type) -      { -      case RNH_NEXTHOP_TYPE: -	t = zvrf->rnh_table[family2afi(family)]; -	break; -      case RNH_IMPORT_CHECK_TYPE: -	t = zvrf->import_check_table[family2afi(family)]; -	break; -      } - -  return t; +	struct zebra_vrf *zvrf; +	struct route_table *t = NULL; + +	zvrf = zebra_vrf_lookup_by_id(vrfid); +	if (zvrf) +		switch (type) { +		case RNH_NEXTHOP_TYPE: +			t = zvrf->rnh_table[family2afi(family)]; +			break; +		case RNH_IMPORT_CHECK_TYPE: +			t = zvrf->import_check_table[family2afi(family)]; +			break; +		} + +	return t;  } -char *rnh_str (struct rnh *rnh, char *buf, int size) +char *rnh_str(struct rnh *rnh, char *buf, int size)  { -  prefix2str(&(rnh->node->p), buf, size); -  return buf; +	prefix2str(&(rnh->node->p), buf, size); +	return buf;  } -struct rnh * -zebra_add_rnh (struct prefix *p, vrf_id_t vrfid, rnh_type_t type) +struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, rnh_type_t type)  { -  struct route_table *table; -  struct route_node *rn; -  struct rnh *rnh = NULL; -  char buf[PREFIX2STR_BUFFER]; - -  if (IS_ZEBRA_DEBUG_NHT) -    { -      prefix2str(p, buf, sizeof (buf)); -      zlog_debug("%u: Add RNH %s type %d", vrfid, buf, type); -    } -  table = get_rnh_table(vrfid, PREFIX_FAMILY(p), type); -  if (!table) -    { -      prefix2str(p, buf, sizeof (buf)); -      zlog_warn("%u: Add RNH %s type %d - table not found", -                vrfid, buf, type); -      return NULL; -    } - -  /* Make it sure prefixlen is applied to the prefix. */ -  apply_mask (p); - -  /* Lookup (or add) route node.*/ -  rn = route_node_get (table, p); - -  if (!rn->info) -    { -      rnh = XCALLOC(MTYPE_RNH, sizeof(struct rnh)); -      rnh->client_list = list_new(); -      rnh->vrf_id = vrfid; -      rnh->zebra_static_route_list = list_new(); -      rnh->zebra_pseudowire_list = list_new(); -      route_lock_node (rn); -      rn->info = rnh; -      rnh->node = rn; -    } - -  route_unlock_node (rn); -  return (rn->info); +	struct route_table *table; +	struct route_node *rn; +	struct rnh *rnh = NULL; +	char buf[PREFIX2STR_BUFFER]; + +	if (IS_ZEBRA_DEBUG_NHT) { +		prefix2str(p, buf, sizeof(buf)); +		zlog_debug("%u: Add RNH %s type %d", vrfid, buf, type); +	} +	table = get_rnh_table(vrfid, PREFIX_FAMILY(p), type); +	if (!table) { +		prefix2str(p, buf, sizeof(buf)); +		zlog_warn("%u: Add RNH %s type %d - table not found", vrfid, +			  buf, type); +		return NULL; +	} + +	/* Make it sure prefixlen is applied to the prefix. */ +	apply_mask(p); + +	/* Lookup (or add) route node.*/ +	rn = route_node_get(table, p); + +	if (!rn->info) { +		rnh = XCALLOC(MTYPE_RNH, sizeof(struct rnh)); +		rnh->client_list = list_new(); +		rnh->vrf_id = vrfid; +		rnh->zebra_static_route_list = list_new(); +		rnh->zebra_pseudowire_list = list_new(); +		route_lock_node(rn); +		rn->info = rnh; +		rnh->node = rn; +	} + +	route_unlock_node(rn); +	return (rn->info);  } -struct rnh * -zebra_lookup_rnh (struct prefix *p, vrf_id_t vrfid, rnh_type_t type) +struct rnh *zebra_lookup_rnh(struct prefix *p, vrf_id_t vrfid, rnh_type_t type)  { -  struct route_table *table; -  struct route_node *rn; +	struct route_table *table; +	struct route_node *rn; -  table = get_rnh_table(vrfid, PREFIX_FAMILY(p), type); -  if (!table) -    return NULL; +	table = get_rnh_table(vrfid, PREFIX_FAMILY(p), type); +	if (!table) +		return NULL; -  /* Make it sure prefixlen is applied to the prefix. */ -  apply_mask (p); +	/* Make it sure prefixlen is applied to the prefix. */ +	apply_mask(p); -  /* Lookup route node.*/ -  rn = route_node_lookup (table, p); -  if (!rn) -    return NULL; +	/* Lookup route node.*/ +	rn = route_node_lookup(table, p); +	if (!rn) +		return NULL; -  route_unlock_node (rn); -  return (rn->info); +	route_unlock_node(rn); +	return (rn->info);  } -void -zebra_free_rnh (struct rnh *rnh) +void zebra_free_rnh(struct rnh *rnh)  { -  rnh->flags |= ZEBRA_NHT_DELETED; -  list_free (rnh->client_list); -  list_free (rnh->zebra_static_route_list); -  list_free (rnh->zebra_pseudowire_list); -  free_state (rnh->vrf_id, rnh->state, rnh->node); -  XFREE (MTYPE_RNH, rnh); +	rnh->flags |= ZEBRA_NHT_DELETED; +	list_free(rnh->client_list); +	list_free(rnh->zebra_static_route_list); +	list_free(rnh->zebra_pseudowire_list); +	free_state(rnh->vrf_id, rnh->state, rnh->node); +	XFREE(MTYPE_RNH, rnh);  } -void -zebra_delete_rnh (struct rnh *rnh, rnh_type_t type) +void zebra_delete_rnh(struct rnh *rnh, rnh_type_t type)  { -  struct route_node *rn; +	struct route_node *rn; -  if (!rnh || (rnh->flags & ZEBRA_NHT_DELETED) || !(rn = rnh->node)) -    return; +	if (!rnh || (rnh->flags & ZEBRA_NHT_DELETED) || !(rn = rnh->node)) +		return; -  if (IS_ZEBRA_DEBUG_NHT) -    { -      char buf[PREFIX2STR_BUFFER]; -      zlog_debug("%u: Del RNH %s type %d", -                 rnh->vrf_id, rnh_str(rnh, buf, sizeof (buf)), type); -    } +	if (IS_ZEBRA_DEBUG_NHT) { +		char buf[PREFIX2STR_BUFFER]; +		zlog_debug("%u: Del RNH %s type %d", rnh->vrf_id, +			   rnh_str(rnh, buf, sizeof(buf)), type); +	} -  zebra_free_rnh (rnh); -  rn->info = NULL; -  route_unlock_node (rn); +	zebra_free_rnh(rnh); +	rn->info = NULL; +	route_unlock_node(rn);  } -void -zebra_add_rnh_client (struct rnh *rnh, struct zserv *client, rnh_type_t type, -                      vrf_id_t vrf_id) +void zebra_add_rnh_client(struct rnh *rnh, struct zserv *client, +			  rnh_type_t type, vrf_id_t vrf_id)  { -  if (IS_ZEBRA_DEBUG_NHT) -    { -      char buf[PREFIX2STR_BUFFER]; -      zlog_debug("%u: Client %s registers for RNH %s type %d", -		 vrf_id, zebra_route_string(client->proto), -		 rnh_str(rnh, buf, sizeof (buf)), type); -    } -  if (!listnode_lookup(rnh->client_list, client)) -    { -      listnode_add(rnh->client_list, client); -      send_client(rnh, client, type, vrf_id); // Pending: check if its needed -    } +	if (IS_ZEBRA_DEBUG_NHT) { +		char buf[PREFIX2STR_BUFFER]; +		zlog_debug("%u: Client %s registers for RNH %s type %d", vrf_id, +			   zebra_route_string(client->proto), +			   rnh_str(rnh, buf, sizeof(buf)), type); +	} +	if (!listnode_lookup(rnh->client_list, client)) { +		listnode_add(rnh->client_list, client); +		send_client(rnh, client, type, +			    vrf_id); // Pending: check if its needed +	}  } -void -zebra_remove_rnh_client (struct rnh *rnh, struct zserv *client, rnh_type_t type) +void zebra_remove_rnh_client(struct rnh *rnh, struct zserv *client, +			     rnh_type_t type)  { -  if (IS_ZEBRA_DEBUG_NHT) -    { -      char buf[PREFIX2STR_BUFFER]; -      zlog_debug("Client %s unregisters for RNH %s type %d", -		 zebra_route_string(client->proto), -		 rnh_str(rnh, buf, sizeof (buf)), type); -    } -  listnode_delete(rnh->client_list, client); -  if (list_isempty(rnh->client_list) && -      list_isempty(rnh->zebra_static_route_list) && -      list_isempty(rnh->zebra_pseudowire_list)) -    zebra_delete_rnh(rnh, type); +	if (IS_ZEBRA_DEBUG_NHT) { +		char buf[PREFIX2STR_BUFFER]; +		zlog_debug("Client %s unregisters for RNH %s type %d", +			   zebra_route_string(client->proto), +			   rnh_str(rnh, buf, sizeof(buf)), type); +	} +	listnode_delete(rnh->client_list, client); +	if (list_isempty(rnh->client_list) +	    && list_isempty(rnh->zebra_static_route_list) +	    && list_isempty(rnh->zebra_pseudowire_list)) +		zebra_delete_rnh(rnh, type);  } -void -zebra_register_rnh_static_nh(vrf_id_t vrf_id, struct prefix *nh, -                             struct route_node *static_rn) +void zebra_register_rnh_static_nh(vrf_id_t vrf_id, struct prefix *nh, +				  struct route_node *static_rn)  { -  struct rnh *rnh; +	struct rnh *rnh; -  rnh = zebra_add_rnh(nh, vrf_id, RNH_NEXTHOP_TYPE); -  if (rnh && !listnode_lookup(rnh->zebra_static_route_list, static_rn)) -    { -      listnode_add(rnh->zebra_static_route_list, static_rn); -    } +	rnh = zebra_add_rnh(nh, vrf_id, RNH_NEXTHOP_TYPE); +	if (rnh && !listnode_lookup(rnh->zebra_static_route_list, static_rn)) { +		listnode_add(rnh->zebra_static_route_list, static_rn); +	}  } -void -zebra_deregister_rnh_static_nh(vrf_id_t vrf_id, struct prefix *nh, -                               struct route_node *static_rn) +void zebra_deregister_rnh_static_nh(vrf_id_t vrf_id, struct prefix *nh, +				    struct route_node *static_rn)  { -  struct rnh *rnh; +	struct rnh *rnh; -  rnh = zebra_lookup_rnh(nh, vrf_id, RNH_NEXTHOP_TYPE); -  if (!rnh || (rnh->flags & ZEBRA_NHT_DELETED)) -    return; +	rnh = zebra_lookup_rnh(nh, vrf_id, RNH_NEXTHOP_TYPE); +	if (!rnh || (rnh->flags & ZEBRA_NHT_DELETED)) +		return; -  listnode_delete(rnh->zebra_static_route_list, static_rn); +	listnode_delete(rnh->zebra_static_route_list, static_rn); -  if (list_isempty(rnh->client_list) && -      list_isempty(rnh->zebra_static_route_list) && -      list_isempty(rnh->zebra_pseudowire_list)) -    zebra_delete_rnh(rnh, RNH_NEXTHOP_TYPE); +	if (list_isempty(rnh->client_list) +	    && list_isempty(rnh->zebra_static_route_list) +	    && list_isempty(rnh->zebra_pseudowire_list)) +		zebra_delete_rnh(rnh, RNH_NEXTHOP_TYPE);  } -void -zebra_deregister_rnh_static_nexthops (vrf_id_t vrf_id, struct nexthop *nexthop, -                                      struct route_node *rn) +void zebra_deregister_rnh_static_nexthops(vrf_id_t vrf_id, +					  struct nexthop *nexthop, +					  struct route_node *rn)  { -  struct nexthop *nh; -  struct prefix nh_p; - -  for (nh = nexthop; nh ; nh = nh->next) -    { -      switch (nh->type) -      { -        case NEXTHOP_TYPE_IPV4: -        case NEXTHOP_TYPE_IPV4_IFINDEX: -          nh_p.family = AF_INET; -          nh_p.prefixlen = IPV4_MAX_BITLEN; -          nh_p.u.prefix4 = nh->gate.ipv4; -          break; -        case NEXTHOP_TYPE_IPV6: -        case NEXTHOP_TYPE_IPV6_IFINDEX: -          nh_p.family = AF_INET6; -          nh_p.prefixlen = IPV6_MAX_BITLEN; -          nh_p.u.prefix6 = nh->gate.ipv6; -          break; -        /* -         * Not sure what really to do here, we are not -         * supposed to have either of these for NHT -         * and the code has no way to know what prefix -         * to use.  So I'm going to just continue -         * for the moment, which is preferable to -         * what is currently happening which is a -         * CRASH and BURN. -         * Some simple testing shows that we -         * are not leaving slag around for these -         * skipped static routes.  Since -         * they don't appear to be installed -         */ -        case NEXTHOP_TYPE_IFINDEX: -        case NEXTHOP_TYPE_BLACKHOLE: -          continue; -          break; -      } -      zebra_deregister_rnh_static_nh(vrf_id, &nh_p, rn); -    } +	struct nexthop *nh; +	struct prefix nh_p; + +	for (nh = nexthop; nh; nh = nh->next) { +		switch (nh->type) { +		case NEXTHOP_TYPE_IPV4: +		case NEXTHOP_TYPE_IPV4_IFINDEX: +			nh_p.family = AF_INET; +			nh_p.prefixlen = IPV4_MAX_BITLEN; +			nh_p.u.prefix4 = nh->gate.ipv4; +			break; +		case NEXTHOP_TYPE_IPV6: +		case NEXTHOP_TYPE_IPV6_IFINDEX: +			nh_p.family = AF_INET6; +			nh_p.prefixlen = IPV6_MAX_BITLEN; +			nh_p.u.prefix6 = nh->gate.ipv6; +			break; +		/* +		 * Not sure what really to do here, we are not +		 * supposed to have either of these for NHT +		 * and the code has no way to know what prefix +		 * to use.  So I'm going to just continue +		 * for the moment, which is preferable to +		 * what is currently happening which is a +		 * CRASH and BURN. +		 * Some simple testing shows that we +		 * are not leaving slag around for these +		 * skipped static routes.  Since +		 * they don't appear to be installed +		 */ +		case NEXTHOP_TYPE_IFINDEX: +		case NEXTHOP_TYPE_BLACKHOLE: +			continue; +			break; +		} +		zebra_deregister_rnh_static_nh(vrf_id, &nh_p, rn); +	}  }  /* XXX move this utility function elsewhere? */ -static void -addr2hostprefix (int af, const union g_addr *addr, struct prefix *prefix) +static void addr2hostprefix(int af, const union g_addr *addr, +			    struct prefix *prefix)  { -  switch (af) -    { -    case AF_INET: -      prefix->family = AF_INET; -      prefix->prefixlen = IPV4_MAX_BITLEN; -      prefix->u.prefix4 = addr->ipv4; -      break; -    case AF_INET6: -      prefix->family = AF_INET6; -      prefix->prefixlen = IPV6_MAX_BITLEN; -      prefix->u.prefix6 = addr->ipv6; -      break; -    default: -      zlog_warn ("%s: unknown address family %d", __func__, af); -      break; -    } +	switch (af) { +	case AF_INET: +		prefix->family = AF_INET; +		prefix->prefixlen = IPV4_MAX_BITLEN; +		prefix->u.prefix4 = addr->ipv4; +		break; +	case AF_INET6: +		prefix->family = AF_INET6; +		prefix->prefixlen = IPV6_MAX_BITLEN; +		prefix->u.prefix6 = addr->ipv6; +		break; +	default: +		zlog_warn("%s: unknown address family %d", __func__, af); +		break; +	}  } -void -zebra_register_rnh_pseudowire (vrf_id_t vrf_id, struct zebra_pw *pw) +void zebra_register_rnh_pseudowire(vrf_id_t vrf_id, struct zebra_pw *pw)  { -  struct prefix nh; -  struct rnh *rnh; - -  addr2hostprefix (pw->af, &pw->nexthop, &nh); -  rnh = zebra_add_rnh (&nh, vrf_id, RNH_NEXTHOP_TYPE); -  if (rnh && !listnode_lookup (rnh->zebra_pseudowire_list, pw)) -    { -      listnode_add (rnh->zebra_pseudowire_list, pw); -      pw->rnh = rnh; -      zebra_evaluate_rnh (vrf_id, pw->af, 1, RNH_NEXTHOP_TYPE, &nh); -    } +	struct prefix nh; +	struct rnh *rnh; + +	addr2hostprefix(pw->af, &pw->nexthop, &nh); +	rnh = zebra_add_rnh(&nh, vrf_id, RNH_NEXTHOP_TYPE); +	if (rnh && !listnode_lookup(rnh->zebra_pseudowire_list, pw)) { +		listnode_add(rnh->zebra_pseudowire_list, pw); +		pw->rnh = rnh; +		zebra_evaluate_rnh(vrf_id, pw->af, 1, RNH_NEXTHOP_TYPE, &nh); +	}  } -void -zebra_deregister_rnh_pseudowire (vrf_id_t vrf_id, struct zebra_pw *pw) +void zebra_deregister_rnh_pseudowire(vrf_id_t vrf_id, struct zebra_pw *pw)  { -  struct rnh *rnh; +	struct rnh *rnh; -  rnh = pw->rnh; -  if (!rnh) -    return; +	rnh = pw->rnh; +	if (!rnh) +		return; -  listnode_delete (rnh->zebra_pseudowire_list, pw); -  pw->rnh = NULL; +	listnode_delete(rnh->zebra_pseudowire_list, pw); +	pw->rnh = NULL; -  if (list_isempty (rnh->client_list) && -      list_isempty (rnh->zebra_static_route_list) && -      list_isempty (rnh->zebra_pseudowire_list)) -    zebra_delete_rnh (rnh, RNH_NEXTHOP_TYPE); +	if (list_isempty(rnh->client_list) +	    && list_isempty(rnh->zebra_static_route_list) +	    && list_isempty(rnh->zebra_pseudowire_list)) +		zebra_delete_rnh(rnh, RNH_NEXTHOP_TYPE);  }  /* Apply the NHT route-map for a client to the route (and nexthops)   * resolving a NH.   */ -static int -zebra_rnh_apply_nht_rmap(int family, struct route_node *prn, -                         struct rib *rib, int proto) +static int zebra_rnh_apply_nht_rmap(int family, struct route_node *prn, +				    struct rib *rib, int proto)  { -  int at_least_one = 0; -  int rmap_family;	       /* Route map has diff AF family enum */ -  struct nexthop *nexthop; -  int ret; - -  rmap_family = (family == AF_INET) ? AFI_IP : AFI_IP6; - -  if (prn && rib) -    { -      for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) -	{ -	  ret = zebra_nht_route_map_check(rmap_family, proto, &prn->p, rib, -					  nexthop); -	  if (ret != RMAP_DENYMATCH) -	    { -	      SET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); -	      at_least_one++; /* at least one valid NH */ -	    } -	  else -	    { -	      UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE); -	    } +	int at_least_one = 0; +	int rmap_family; /* Route map has diff AF family enum */ +	struct nexthop *nexthop; +	int ret; + +	rmap_family = (family == AF_INET) ? AFI_IP : AFI_IP6; + +	if (prn && rib) { +		for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) { +			ret = zebra_nht_route_map_check(rmap_family, proto, +							&prn->p, rib, nexthop); +			if (ret != RMAP_DENYMATCH) { +				SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); +				at_least_one++; /* at least one valid NH */ +			} else { +				UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); +			} +		}  	} -    } -  return (at_least_one); +	return (at_least_one);  }  /*   * Determine appropriate route (RIB entry) resolving a tracked entry   * (nexthop or BGP route for import).   */ -static struct rib * -zebra_rnh_resolve_entry (vrf_id_t vrfid, int family, rnh_type_t type, -                         struct route_node *nrn, struct rnh *rnh, -                         struct route_node **prn) +static struct rib *zebra_rnh_resolve_entry(vrf_id_t vrfid, int family, +					   rnh_type_t type, +					   struct route_node *nrn, +					   struct rnh *rnh, +					   struct route_node **prn)  { -  struct route_table *route_table; -  struct route_node *rn; -  struct rib *rib; - -  *prn = NULL; - -  route_table = zebra_vrf_table(family2afi(family), SAFI_UNICAST, vrfid); -  if (!route_table) // unexpected -    return NULL; - -  rn = route_node_match(route_table, &nrn->p); -  if (!rn) -    return NULL; - -  /* When resolving nexthops, do not resolve via the default route unless -   * 'ip nht resolve-via-default' is configured. -   */ -  if ((type == RNH_NEXTHOP_TYPE) && -      (is_default_prefix (&rn->p) && -      !nh_resolve_via_default(rn->p.family))) -    rib = NULL; - else if ((type == RNH_IMPORT_CHECK_TYPE) && -          CHECK_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH) && -          !prefix_same(&nrn->p, &rn->p)) -   rib = NULL; -  else -    { -      /* Identify appropriate route entry. */ -      RNODE_FOREACH_RIB(rn, rib) -        { -          if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) -            continue; -          if (! CHECK_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB)) -            continue; - -          if (CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)) -            { -              if (rib->type == ZEBRA_ROUTE_CONNECT) -                break; -              if (rib->type == ZEBRA_ROUTE_NHRP) -                { -                  struct nexthop *nexthop; -                  for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) -                    if (nexthop->type == NEXTHOP_TYPE_IFINDEX) -                      break; -                  if (nexthop) -                    break; -                } -            } -          else if ((type == RNH_IMPORT_CHECK_TYPE) && -                   (rib->type == ZEBRA_ROUTE_BGP)) -            continue; -          else -            break; -        } -    } - -  /* Need to unlock route node */ -  route_unlock_node(rn); -  if (rib) -    *prn = rn; -  return rib; +	struct route_table *route_table; +	struct route_node *rn; +	struct rib *rib; + +	*prn = NULL; + +	route_table = zebra_vrf_table(family2afi(family), SAFI_UNICAST, vrfid); +	if (!route_table) // unexpected +		return NULL; + +	rn = route_node_match(route_table, &nrn->p); +	if (!rn) +		return NULL; + +	/* When resolving nexthops, do not resolve via the default route unless +	 * 'ip nht resolve-via-default' is configured. +	 */ +	if ((type == RNH_NEXTHOP_TYPE) +	    && (is_default_prefix(&rn->p) +		&& !nh_resolve_via_default(rn->p.family))) +		rib = NULL; +	else if ((type == RNH_IMPORT_CHECK_TYPE) +		 && CHECK_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH) +		 && !prefix_same(&nrn->p, &rn->p)) +		rib = NULL; +	else { +		/* Identify appropriate route entry. */ +		RNODE_FOREACH_RIB(rn, rib) +		{ +			if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED)) +				continue; +			if (!CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB)) +				continue; + +			if (CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)) { +				if (rib->type == ZEBRA_ROUTE_CONNECT) +					break; +				if (rib->type == ZEBRA_ROUTE_NHRP) { +					struct nexthop *nexthop; +					for (nexthop = rib->nexthop; nexthop; +					     nexthop = nexthop->next) +						if (nexthop->type +						    == NEXTHOP_TYPE_IFINDEX) +							break; +					if (nexthop) +						break; +				} +			} else if ((type == RNH_IMPORT_CHECK_TYPE) +				   && (rib->type == ZEBRA_ROUTE_BGP)) +				continue; +			else +				break; +		} +	} + +	/* Need to unlock route node */ +	route_unlock_node(rn); +	if (rib) +		*prn = rn; +	return rib;  }  /*   * See if a tracked route entry for import (by BGP) has undergone any   * change, and if so, notify the client.   */ -static void -zebra_rnh_eval_import_check_entry (vrf_id_t vrfid, int family, int force, -                                   struct route_node *nrn, struct rnh *rnh, -                                   struct rib *rib) +static void zebra_rnh_eval_import_check_entry(vrf_id_t vrfid, int family, +					      int force, struct route_node *nrn, +					      struct rnh *rnh, struct rib *rib)  { -  int state_changed = 0; -  struct zserv *client; -  char bufn[INET6_ADDRSTRLEN]; -  struct listnode *node; -  struct nexthop *nexthop, *tnexthop; -  int recursing; - -  if (rib && (rnh->state == NULL)) -    { -      for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) -        if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) -          { -            state_changed = 1; -            break; -          } -    } -  else if (!rib && (rnh->state != NULL)) -    state_changed = 1; - -  if (compare_state(rib, rnh->state)) -    copy_state(rnh, rib, nrn); - -  if (state_changed || force) -    { -      if (IS_ZEBRA_DEBUG_NHT) -        { -          prefix2str(&nrn->p, bufn, INET6_ADDRSTRLEN); -          zlog_debug("%u:%s: Route import check %s %s\n", -                     vrfid, bufn, rnh->state ? "passed" : "failed", -                     state_changed ? "(state changed)" : ""); -        } -      /* state changed, notify clients */ -      for (ALL_LIST_ELEMENTS_RO(rnh->client_list, node, client)) -        { -          send_client(rnh, client, RNH_IMPORT_CHECK_TYPE, vrfid); -        } -    } +	int state_changed = 0; +	struct zserv *client; +	char bufn[INET6_ADDRSTRLEN]; +	struct listnode *node; +	struct nexthop *nexthop, *tnexthop; +	int recursing; + +	if (rib && (rnh->state == NULL)) { +		for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, +				     recursing)) +			if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)) { +				state_changed = 1; +				break; +			} +	} else if (!rib && (rnh->state != NULL)) +		state_changed = 1; + +	if (compare_state(rib, rnh->state)) +		copy_state(rnh, rib, nrn); + +	if (state_changed || force) { +		if (IS_ZEBRA_DEBUG_NHT) { +			prefix2str(&nrn->p, bufn, INET6_ADDRSTRLEN); +			zlog_debug("%u:%s: Route import check %s %s\n", vrfid, +				   bufn, rnh->state ? "passed" : "failed", +				   state_changed ? "(state changed)" : ""); +		} +		/* state changed, notify clients */ +		for (ALL_LIST_ELEMENTS_RO(rnh->client_list, node, client)) { +			send_client(rnh, client, RNH_IMPORT_CHECK_TYPE, vrfid); +		} +	}  }  /*   * Notify clients registered for this nexthop about a change.   */ -static void -zebra_rnh_notify_protocol_clients (vrf_id_t vrfid, int family, -                                   struct route_node *nrn, struct rnh *rnh, -                                   struct route_node *prn, struct rib *rib) +static void zebra_rnh_notify_protocol_clients(vrf_id_t vrfid, int family, +					      struct route_node *nrn, +					      struct rnh *rnh, +					      struct route_node *prn, +					      struct rib *rib)  { -  struct listnode *node; -  struct zserv *client; -  char bufn[INET6_ADDRSTRLEN]; -  char bufp[INET6_ADDRSTRLEN]; -  int num_resolving_nh; - -  if (IS_ZEBRA_DEBUG_NHT) -    { -      prefix2str(&nrn->p, bufn, INET6_ADDRSTRLEN); -      if (prn && rib) -        { -          prefix2str(&prn->p, bufp, INET6_ADDRSTRLEN); -          zlog_debug("%u:%s: NH resolved over route %s", vrfid, bufn, bufp); -        } -      else -        zlog_debug("%u:%s: NH has become unresolved", vrfid, bufn); -    } - -  for (ALL_LIST_ELEMENTS_RO(rnh->client_list, node, client)) -    { -      if (prn && rib) -        { -          /* Apply route-map for this client to route resolving this -           * nexthop to see if it is filtered or not. -           */ -          num_resolving_nh = zebra_rnh_apply_nht_rmap(family, prn, rib, -                                                      client->proto); -          if (num_resolving_nh) -            rnh->filtered[client->proto] = 0; -          else -            rnh->filtered[client->proto] = 1; - -          if (IS_ZEBRA_DEBUG_NHT) -            zlog_debug("%u:%s: Notifying client %s about NH %s", -                       vrfid, bufn, zebra_route_string(client->proto), -                       num_resolving_nh ? "" : "(filtered by route-map)"); -        } -      else -        { -          rnh->filtered[client->proto] = 0; -          if (IS_ZEBRA_DEBUG_NHT) -            zlog_debug("%u:%s: Notifying client %s about NH (unreachable)", -                       vrfid, bufn, zebra_route_string(client->proto)); -        } - -      send_client(rnh, client, RNH_NEXTHOP_TYPE, vrfid); -    } +	struct listnode *node; +	struct zserv *client; +	char bufn[INET6_ADDRSTRLEN]; +	char bufp[INET6_ADDRSTRLEN]; +	int num_resolving_nh; + +	if (IS_ZEBRA_DEBUG_NHT) { +		prefix2str(&nrn->p, bufn, INET6_ADDRSTRLEN); +		if (prn && rib) { +			prefix2str(&prn->p, bufp, INET6_ADDRSTRLEN); +			zlog_debug("%u:%s: NH resolved over route %s", vrfid, +				   bufn, bufp); +		} else +			zlog_debug("%u:%s: NH has become unresolved", vrfid, +				   bufn); +	} + +	for (ALL_LIST_ELEMENTS_RO(rnh->client_list, node, client)) { +		if (prn && rib) { +			/* Apply route-map for this client to route resolving +			 * this +			 * nexthop to see if it is filtered or not. +			 */ +			num_resolving_nh = zebra_rnh_apply_nht_rmap( +				family, prn, rib, client->proto); +			if (num_resolving_nh) +				rnh->filtered[client->proto] = 0; +			else +				rnh->filtered[client->proto] = 1; + +			if (IS_ZEBRA_DEBUG_NHT) +				zlog_debug( +					"%u:%s: Notifying client %s about NH %s", +					vrfid, bufn, +					zebra_route_string(client->proto), +					num_resolving_nh +						? "" +						: "(filtered by route-map)"); +		} else { +			rnh->filtered[client->proto] = 0; +			if (IS_ZEBRA_DEBUG_NHT) +				zlog_debug( +					"%u:%s: Notifying client %s about NH (unreachable)", +					vrfid, bufn, +					zebra_route_string(client->proto)); +		} + +		send_client(rnh, client, RNH_NEXTHOP_TYPE, vrfid); +	}  } -static void -zebra_rnh_process_static_routes (vrf_id_t vrfid, int family, -                                 struct route_node *nrn, struct rnh *rnh, -                                 struct route_node *prn, struct rib *rib) +static void zebra_rnh_process_static_routes(vrf_id_t vrfid, int family, +					    struct route_node *nrn, +					    struct rnh *rnh, +					    struct route_node *prn, +					    struct rib *rib)  { -  struct listnode *node; -  int num_resolving_nh = 0; -  struct route_node *static_rn; -  struct rib *srib; -  struct nexthop *nexthop; -  char bufn[INET6_ADDRSTRLEN]; -  char bufp[INET6_ADDRSTRLEN]; -  char bufs[INET6_ADDRSTRLEN]; - -  if (IS_ZEBRA_DEBUG_NHT) -    { -      prefix2str(&nrn->p, bufn, INET6_ADDRSTRLEN); -      if (prn) -        prefix2str(&prn->p, bufp, INET6_ADDRSTRLEN); -    } - -  if (prn && rib) -    { -      /* Apply route-map for "static" to route resolving this -       * nexthop to see if it is filtered or not. -       */ -      num_resolving_nh = zebra_rnh_apply_nht_rmap(family, prn, rib, -                                                  ZEBRA_ROUTE_STATIC); -      if (num_resolving_nh) -        rnh->filtered[ZEBRA_ROUTE_STATIC] = 0; -      else -        rnh->filtered[ZEBRA_ROUTE_STATIC] = 1; -    } -  else -    rnh->filtered[ZEBRA_ROUTE_STATIC] = 0; - -  /* Evaluate each static route associated with this nexthop. */ -  for (ALL_LIST_ELEMENTS_RO(rnh->zebra_static_route_list, node, -                            static_rn)) -    { -      RNODE_FOREACH_RIB(static_rn, srib) -        { -          if (srib->type != ZEBRA_ROUTE_STATIC) -            continue; - -	  /* Set the filter flag for the correct nexthop - static route may -	   * be having multiple. We care here only about registered nexthops. -	   */ -	  for (nexthop = srib->nexthop; nexthop; nexthop = nexthop->next) -	    { -	      switch (nexthop->type) -		{ -		case NEXTHOP_TYPE_IPV4: -		case NEXTHOP_TYPE_IPV4_IFINDEX: -		  if (nexthop->gate.ipv4.s_addr == nrn->p.u.prefix4.s_addr) -		    { -		      if (num_resolving_nh) -			UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FILTERED); -		      else -			SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FILTERED); -		    } -		  break; -		case NEXTHOP_TYPE_IPV6: -		case NEXTHOP_TYPE_IPV6_IFINDEX: +	struct listnode *node; +	int num_resolving_nh = 0; +	struct route_node *static_rn; +	struct rib *srib; +	struct nexthop *nexthop; +	char bufn[INET6_ADDRSTRLEN]; +	char bufp[INET6_ADDRSTRLEN]; +	char bufs[INET6_ADDRSTRLEN]; + +	if (IS_ZEBRA_DEBUG_NHT) { +		prefix2str(&nrn->p, bufn, INET6_ADDRSTRLEN); +		if (prn) +			prefix2str(&prn->p, bufp, INET6_ADDRSTRLEN); +	} -              if (memcmp(&nexthop->gate.ipv6,&nrn->p.u.prefix6, 16) == 0) -                { -                  if (num_resolving_nh) -                    UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FILTERED); -                  else -                    SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FILTERED); -                } -              break; -            default: -              break; -            } -        } - -	  if (IS_ZEBRA_DEBUG_NHT) -	    { -	      prefix2str(&static_rn->p, bufs, INET6_ADDRSTRLEN); -	      if (prn && rib) -		zlog_debug("%u:%s: NH change %s, scheduling static route %s", -			   vrfid, bufn, num_resolving_nh ? -			   "" : "(filtered by route-map)", bufs); -	      else -		zlog_debug("%u:%s: NH unreachable, scheduling static route %s", -			   vrfid, bufn, bufs); -	    } - -          SET_FLAG(srib->status, RIB_ENTRY_CHANGED); -          SET_FLAG(srib->status, RIB_ENTRY_NEXTHOPS_CHANGED); -        } - -      rib_queue_add(static_rn); -    } +	if (prn && rib) { +		/* Apply route-map for "static" to route resolving this +		 * nexthop to see if it is filtered or not. +		 */ +		num_resolving_nh = zebra_rnh_apply_nht_rmap(family, prn, rib, +							    ZEBRA_ROUTE_STATIC); +		if (num_resolving_nh) +			rnh->filtered[ZEBRA_ROUTE_STATIC] = 0; +		else +			rnh->filtered[ZEBRA_ROUTE_STATIC] = 1; +	} else +		rnh->filtered[ZEBRA_ROUTE_STATIC] = 0; + +	/* Evaluate each static route associated with this nexthop. */ +	for (ALL_LIST_ELEMENTS_RO(rnh->zebra_static_route_list, node, +				  static_rn)) { +		RNODE_FOREACH_RIB(static_rn, srib) +		{ +			if (srib->type != ZEBRA_ROUTE_STATIC) +				continue; + +			/* Set the filter flag for the correct nexthop - static +			 * route may +			 * be having multiple. We care here only about +			 * registered nexthops. +			 */ +			for (nexthop = srib->nexthop; nexthop; +			     nexthop = nexthop->next) { +				switch (nexthop->type) { +				case NEXTHOP_TYPE_IPV4: +				case NEXTHOP_TYPE_IPV4_IFINDEX: +					if (nexthop->gate.ipv4.s_addr +					    == nrn->p.u.prefix4.s_addr) { +						if (num_resolving_nh) +							UNSET_FLAG( +								nexthop->flags, +								NEXTHOP_FLAG_FILTERED); +						else +							SET_FLAG( +								nexthop->flags, +								NEXTHOP_FLAG_FILTERED); +					} +					break; +				case NEXTHOP_TYPE_IPV6: +				case NEXTHOP_TYPE_IPV6_IFINDEX: + +					if (memcmp(&nexthop->gate.ipv6, +						   &nrn->p.u.prefix6, 16) +					    == 0) { +						if (num_resolving_nh) +							UNSET_FLAG( +								nexthop->flags, +								NEXTHOP_FLAG_FILTERED); +						else +							SET_FLAG( +								nexthop->flags, +								NEXTHOP_FLAG_FILTERED); +					} +					break; +				default: +					break; +				} +			} + +			if (IS_ZEBRA_DEBUG_NHT) { +				prefix2str(&static_rn->p, bufs, +					   INET6_ADDRSTRLEN); +				if (prn && rib) +					zlog_debug( +						"%u:%s: NH change %s, scheduling static route %s", +						vrfid, bufn, +						num_resolving_nh +							? "" +							: "(filtered by route-map)", +						bufs); +				else +					zlog_debug( +						"%u:%s: NH unreachable, scheduling static route %s", +						vrfid, bufn, bufs); +			} + +			SET_FLAG(srib->status, RIB_ENTRY_CHANGED); +			SET_FLAG(srib->status, RIB_ENTRY_NEXTHOPS_CHANGED); +		} + +		rib_queue_add(static_rn); +	}  } -static void -zebra_rnh_process_pseudowires (vrf_id_t vrfid, struct rnh *rnh) +static void zebra_rnh_process_pseudowires(vrf_id_t vrfid, struct rnh *rnh)  { -  struct zebra_pw *pw; -  struct listnode *node; +	struct zebra_pw *pw; +	struct listnode *node; -  for (ALL_LIST_ELEMENTS_RO (rnh->zebra_pseudowire_list, node, pw)) -    zebra_pw_update (pw); +	for (ALL_LIST_ELEMENTS_RO(rnh->zebra_pseudowire_list, node, pw)) +		zebra_pw_update(pw);  }  /* @@ -686,86 +665,81 @@ zebra_rnh_process_pseudowires (vrf_id_t vrfid, struct rnh *rnh)   * take appropriate action; this involves notifying any clients and/or   * scheduling dependent static routes for processing.   */ -static void -zebra_rnh_eval_nexthop_entry (vrf_id_t vrfid, int family, int force, -                              struct route_node *nrn, struct rnh *rnh, -                              struct route_node *prn, struct rib *rib) +static void zebra_rnh_eval_nexthop_entry(vrf_id_t vrfid, int family, int force, +					 struct route_node *nrn, +					 struct rnh *rnh, +					 struct route_node *prn, +					 struct rib *rib)  { -  int state_changed = 0; - -  /* If we're resolving over a different route, resolution has changed or -   * the resolving route has some change (e.g., metric), there is a state -   * change. -   */ -  if (!prefix_same(&rnh->resolved_route, &prn->p)) -    { -      if (prn) -        prefix_copy(&rnh->resolved_route, &prn->p); -      else -        memset(&rnh->resolved_route, 0, sizeof(struct prefix)); - -      copy_state(rnh, rib, nrn); -      state_changed = 1; -    } -  else if (compare_state(rib, rnh->state)) -    { -      copy_state(rnh, rib, nrn); -      state_changed = 1; -    } - -  if (state_changed || force) -    { -      /* NOTE: Use the "copy" of resolving route stored in 'rnh' i.e., -       * rnh->state. -       */ -      /* Notify registered protocol clients. */ -      zebra_rnh_notify_protocol_clients (vrfid, family, nrn, rnh, -                                         prn, rnh->state); - -      /* Process static routes attached to this nexthop */ -      zebra_rnh_process_static_routes (vrfid, family, nrn, rnh, -                                       prn, rnh->state); - -      /* Process pseudowires attached to this nexthop */ -      zebra_rnh_process_pseudowires (vrfid, rnh); -    } +	int state_changed = 0; + +	/* If we're resolving over a different route, resolution has changed or +	 * the resolving route has some change (e.g., metric), there is a state +	 * change. +	 */ +	if (!prefix_same(&rnh->resolved_route, &prn->p)) { +		if (prn) +			prefix_copy(&rnh->resolved_route, &prn->p); +		else +			memset(&rnh->resolved_route, 0, sizeof(struct prefix)); + +		copy_state(rnh, rib, nrn); +		state_changed = 1; +	} else if (compare_state(rib, rnh->state)) { +		copy_state(rnh, rib, nrn); +		state_changed = 1; +	} + +	if (state_changed || force) { +		/* NOTE: Use the "copy" of resolving route stored in 'rnh' i.e., +		 * rnh->state. +		 */ +		/* Notify registered protocol clients. */ +		zebra_rnh_notify_protocol_clients(vrfid, family, nrn, rnh, prn, +						  rnh->state); + +		/* Process static routes attached to this nexthop */ +		zebra_rnh_process_static_routes(vrfid, family, nrn, rnh, prn, +						rnh->state); + +		/* Process pseudowires attached to this nexthop */ +		zebra_rnh_process_pseudowires(vrfid, rnh); +	}  }  /* Evaluate one tracked entry */ -static void -zebra_rnh_evaluate_entry (vrf_id_t vrfid, int family, int force, rnh_type_t type, -                          struct route_node *nrn) +static void zebra_rnh_evaluate_entry(vrf_id_t vrfid, int family, int force, +				     rnh_type_t type, struct route_node *nrn)  { -  struct rnh *rnh; -  struct rib *rib; -  struct route_node *prn; -  char bufn[INET6_ADDRSTRLEN]; - -  if (IS_ZEBRA_DEBUG_NHT) -    { -      prefix2str(&nrn->p, bufn, INET6_ADDRSTRLEN); -      zlog_debug("%u:%s: Evaluate RNH, type %d %s", -                 vrfid, bufn, type, force ? "(force)" : ""); -    } - -  rnh = nrn->info; - -  /* Identify route entry (RIB) resolving this tracked entry. */ -  rib = zebra_rnh_resolve_entry (vrfid, family, type, nrn, rnh, &prn); - -  /* If the entry cannot be resolved and that is also the existing state, -   * there is nothing further to do. -   */ -  if (!rib && rnh->state == NULL && !force) -    return; - -  /* Process based on type of entry. */ -  if (type == RNH_IMPORT_CHECK_TYPE) -    zebra_rnh_eval_import_check_entry (vrfid, family, force, -                                       nrn, rnh, rib); -  else -    zebra_rnh_eval_nexthop_entry (vrfid, family, force, -                                  nrn, rnh, prn, rib); +	struct rnh *rnh; +	struct rib *rib; +	struct route_node *prn; +	char bufn[INET6_ADDRSTRLEN]; + +	if (IS_ZEBRA_DEBUG_NHT) { +		prefix2str(&nrn->p, bufn, INET6_ADDRSTRLEN); +		zlog_debug("%u:%s: Evaluate RNH, type %d %s", vrfid, bufn, type, +			   force ? "(force)" : ""); +	} + +	rnh = nrn->info; + +	/* Identify route entry (RIB) resolving this tracked entry. */ +	rib = zebra_rnh_resolve_entry(vrfid, family, type, nrn, rnh, &prn); + +	/* If the entry cannot be resolved and that is also the existing state, +	 * there is nothing further to do. +	 */ +	if (!rib && rnh->state == NULL && !force) +		return; + +	/* Process based on type of entry. */ +	if (type == RNH_IMPORT_CHECK_TYPE) +		zebra_rnh_eval_import_check_entry(vrfid, family, force, nrn, +						  rnh, rib); +	else +		zebra_rnh_eval_nexthop_entry(vrfid, family, force, nrn, rnh, +					     prn, rib);  }  /* @@ -777,338 +751,328 @@ zebra_rnh_evaluate_entry (vrf_id_t vrfid, int family, int force, rnh_type_t type   * we can have a situation where one rib entry   * covers multiple nexthops we are interested in.   */ -static void -zebra_rnh_clear_nhc_flag (vrf_id_t vrfid, int family, rnh_type_t type, -                          struct route_node *nrn) +static void zebra_rnh_clear_nhc_flag(vrf_id_t vrfid, int family, +				     rnh_type_t type, struct route_node *nrn)  { -  struct rnh *rnh; -  struct rib *rib; -  struct route_node *prn; +	struct rnh *rnh; +	struct rib *rib; +	struct route_node *prn; -  rnh = nrn->info; +	rnh = nrn->info; -  rib = zebra_rnh_resolve_entry (vrfid, family, type, nrn, rnh, &prn); +	rib = zebra_rnh_resolve_entry(vrfid, family, type, nrn, rnh, &prn); -  if (rib) -    { -      UNSET_FLAG (rib->status, RIB_ENTRY_NEXTHOPS_CHANGED); -      UNSET_FLAG (rib->status, RIB_ENTRY_LABELS_CHANGED); -    } +	if (rib) { +		UNSET_FLAG(rib->status, RIB_ENTRY_NEXTHOPS_CHANGED); +		UNSET_FLAG(rib->status, RIB_ENTRY_LABELS_CHANGED); +	}  }  /* Evaluate all tracked entries (nexthops or routes for import into BGP)   * of a particular VRF and address-family or a specific prefix.   */ -void -zebra_evaluate_rnh (vrf_id_t vrfid, int family, int force, rnh_type_t type, -                    struct prefix *p) +void zebra_evaluate_rnh(vrf_id_t vrfid, int family, int force, rnh_type_t type, +			struct prefix *p)  { -  struct route_table *rnh_table; -  struct route_node *nrn; - -  rnh_table = get_rnh_table(vrfid, family, type); -  if (!rnh_table) // unexpected -    return; - -  if (p) -    { -      /* Evaluating a specific entry, make sure it exists. */ -      nrn = route_node_lookup (rnh_table, p); -      if (nrn && nrn->info) -        zebra_rnh_evaluate_entry (vrfid, family, force, type, nrn); - -      if (nrn) -        route_unlock_node (nrn); -    } -  else -    { -      /* Evaluate entire table. */ -      nrn = route_top (rnh_table); -      while (nrn) -        { -          if (nrn->info) -            zebra_rnh_evaluate_entry (vrfid, family, force, type, nrn); -          nrn = route_next(nrn); /* this will also unlock nrn */ -        } -      nrn = route_top (rnh_table); -      while (nrn) -        { -          if (nrn->info) -            zebra_rnh_clear_nhc_flag (vrfid, family, type, nrn); -          nrn = route_next(nrn); /* this will also unlock nrn */ -        } -    } +	struct route_table *rnh_table; +	struct route_node *nrn; + +	rnh_table = get_rnh_table(vrfid, family, type); +	if (!rnh_table) // unexpected +		return; + +	if (p) { +		/* Evaluating a specific entry, make sure it exists. */ +		nrn = route_node_lookup(rnh_table, p); +		if (nrn && nrn->info) +			zebra_rnh_evaluate_entry(vrfid, family, force, type, +						 nrn); + +		if (nrn) +			route_unlock_node(nrn); +	} else { +		/* Evaluate entire table. */ +		nrn = route_top(rnh_table); +		while (nrn) { +			if (nrn->info) +				zebra_rnh_evaluate_entry(vrfid, family, force, +							 type, nrn); +			nrn = route_next(nrn); /* this will also unlock nrn */ +		} +		nrn = route_top(rnh_table); +		while (nrn) { +			if (nrn->info) +				zebra_rnh_clear_nhc_flag(vrfid, family, type, +							 nrn); +			nrn = route_next(nrn); /* this will also unlock nrn */ +		} +	}  } -void -zebra_print_rnh_table (vrf_id_t vrfid, int af, struct vty *vty, rnh_type_t type) +void zebra_print_rnh_table(vrf_id_t vrfid, int af, struct vty *vty, +			   rnh_type_t type)  { -  struct route_table *table; -  struct route_node *rn; - -  table = get_rnh_table(vrfid, af, type); -  if (!table) -    { -      zlog_debug("print_rnhs: rnh table not found\n"); -      return; -    } - -  for (rn = route_top(table); rn; rn = route_next(rn)) -      if (rn->info) -	print_rnh(rn, vty); +	struct route_table *table; +	struct route_node *rn; + +	table = get_rnh_table(vrfid, af, type); +	if (!table) { +		zlog_debug("print_rnhs: rnh table not found\n"); +		return; +	} + +	for (rn = route_top(table); rn; rn = route_next(rn)) +		if (rn->info) +			print_rnh(rn, vty);  } -int -zebra_cleanup_rnh_client (vrf_id_t vrf_id, int family, struct zserv *client, -			  rnh_type_t type) +int zebra_cleanup_rnh_client(vrf_id_t vrf_id, int family, struct zserv *client, +			     rnh_type_t type)  { -  struct route_table *ntable; -  struct route_node *nrn; -  struct rnh *rnh; - -  if (IS_ZEBRA_DEBUG_NHT) -    zlog_debug("%u: Client %s RNH cleanup for family %d type %d", -               vrf_id, zebra_route_string(client->proto), family, type); - -  ntable = get_rnh_table(vrf_id, family, type); -  if (!ntable) -    { -      zlog_debug("cleanup_rnh_client: rnh table not found\n"); -      return -1; -    } - -  for (nrn = route_top (ntable); nrn; nrn = route_next (nrn)) -    { -      if (!nrn->info) -	  continue; - -      rnh = nrn->info; -      zebra_remove_rnh_client(rnh, client, type); -    } -  return 1; +	struct route_table *ntable; +	struct route_node *nrn; +	struct rnh *rnh; + +	if (IS_ZEBRA_DEBUG_NHT) +		zlog_debug("%u: Client %s RNH cleanup for family %d type %d", +			   vrf_id, zebra_route_string(client->proto), family, +			   type); + +	ntable = get_rnh_table(vrf_id, family, type); +	if (!ntable) { +		zlog_debug("cleanup_rnh_client: rnh table not found\n"); +		return -1; +	} + +	for (nrn = route_top(ntable); nrn; nrn = route_next(nrn)) { +		if (!nrn->info) +			continue; + +		rnh = nrn->info; +		zebra_remove_rnh_client(rnh, client, type); +	} +	return 1;  }  /**   * free_state - free up the rib structure associated with the rnh.   */ -static void -free_state (vrf_id_t vrf_id, struct rib *rib, struct route_node *rn) +static void free_state(vrf_id_t vrf_id, struct rib *rib, struct route_node *rn)  { -  if (!rib) -    return; +	if (!rib) +		return; -  /* free RIB and nexthops */ -  zebra_deregister_rnh_static_nexthops (vrf_id, rib->nexthop, rn); -  nexthops_free(rib->nexthop); -  XFREE (MTYPE_RIB, rib); +	/* free RIB and nexthops */ +	zebra_deregister_rnh_static_nexthops(vrf_id, rib->nexthop, rn); +	nexthops_free(rib->nexthop); +	XFREE(MTYPE_RIB, rib);  } -static void -copy_state (struct rnh *rnh, struct rib *rib, struct route_node *rn) +static void copy_state(struct rnh *rnh, struct rib *rib, struct route_node *rn)  { -  struct rib *state; -  struct nexthop *nh; +	struct rib *state; +	struct nexthop *nh; -  if (rnh->state) -    { -      free_state(rnh->vrf_id, rnh->state, rn); -      rnh->state = NULL; -    } +	if (rnh->state) { +		free_state(rnh->vrf_id, rnh->state, rn); +		rnh->state = NULL; +	} -  if (!rib) -    return; +	if (!rib) +		return; -  state = XCALLOC (MTYPE_RIB, sizeof (struct rib)); -  state->type = rib->type; -  state->metric = rib->metric; +	state = XCALLOC(MTYPE_RIB, sizeof(struct rib)); +	state->type = rib->type; +	state->metric = rib->metric; -  for (nh = rib->nexthop; nh; nh = nh->next) -    rib_copy_nexthops(state, nh); -  rnh->state = state; +	for (nh = rib->nexthop; nh; nh = nh->next) +		rib_copy_nexthops(state, nh); +	rnh->state = state;  } -static int -compare_state (struct rib *r1, struct rib *r2) +static int compare_state(struct rib *r1, struct rib *r2)  { -  if (!r1 && !r2) -    return 0; +	if (!r1 && !r2) +		return 0; -  if ((!r1 && r2) || (r1 && !r2)) -      return 1; +	if ((!r1 && r2) || (r1 && !r2)) +		return 1; -  if (r1->metric != r2->metric) -      return 1; +	if (r1->metric != r2->metric) +		return 1; -  if (r1->nexthop_num != r2->nexthop_num) -      return 1; +	if (r1->nexthop_num != r2->nexthop_num) +		return 1; -  if (CHECK_FLAG(r1->status, RIB_ENTRY_NEXTHOPS_CHANGED) || -      CHECK_FLAG(r1->status, RIB_ENTRY_LABELS_CHANGED)) -    return 1; +	if (CHECK_FLAG(r1->status, RIB_ENTRY_NEXTHOPS_CHANGED) +	    || CHECK_FLAG(r1->status, RIB_ENTRY_LABELS_CHANGED)) +		return 1; -  return 0; +	return 0;  } -static int -send_client (struct rnh *rnh, struct zserv *client, rnh_type_t type, vrf_id_t vrf_id) +static int send_client(struct rnh *rnh, struct zserv *client, rnh_type_t type, +		       vrf_id_t vrf_id)  { -  struct stream *s; -  struct rib *rib; -  unsigned long nump; -  u_char num; -  struct nexthop *nexthop; -  struct route_node *rn; -  int cmd = (type == RNH_IMPORT_CHECK_TYPE) -    ? ZEBRA_IMPORT_CHECK_UPDATE : ZEBRA_NEXTHOP_UPDATE; - -  rn = rnh->node; -  rib = rnh->state; - -  /* Get output stream. */ -  s = client->obuf; -  stream_reset (s); - -  zserv_create_header (s, cmd, vrf_id); - -  stream_putw(s, rn->p.family); -  switch (rn->p.family) -    { -    case AF_INET: -      stream_putc(s, rn->p.prefixlen); -      stream_put_in_addr(s, &rn->p.u.prefix4); -      break; -    case AF_INET6: -      stream_putc(s, rn->p.prefixlen); -      stream_put(s, &rn->p.u.prefix6, IPV6_MAX_BYTELEN); -      break; -    default: -      zlog_err("%s: Unknown family (%d) notification attempted\n", -	       __FUNCTION__, rn->p.family); -      break; -    } -  if (rib) -    { -      stream_putc (s, rib->distance); -      stream_putl (s, rib->metric); -      num = 0; -      nump = stream_get_endp(s); -      stream_putc (s, 0); -      for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) -	if ((CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) || -             CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) && -	    CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) -	  { -	    stream_putc (s, nexthop->type); -	    switch (nexthop->type) -	      { -	      case NEXTHOP_TYPE_IPV4: -		stream_put_in_addr (s, &nexthop->gate.ipv4); -                stream_putl (s, nexthop->ifindex); +	struct stream *s; +	struct rib *rib; +	unsigned long nump; +	u_char num; +	struct nexthop *nexthop; +	struct route_node *rn; +	int cmd = (type == RNH_IMPORT_CHECK_TYPE) ? ZEBRA_IMPORT_CHECK_UPDATE +						  : ZEBRA_NEXTHOP_UPDATE; + +	rn = rnh->node; +	rib = rnh->state; + +	/* Get output stream. */ +	s = client->obuf; +	stream_reset(s); + +	zserv_create_header(s, cmd, vrf_id); + +	stream_putw(s, rn->p.family); +	switch (rn->p.family) { +	case AF_INET: +		stream_putc(s, rn->p.prefixlen); +		stream_put_in_addr(s, &rn->p.u.prefix4);  		break; -	      case NEXTHOP_TYPE_IFINDEX: -		stream_putl (s, nexthop->ifindex); +	case AF_INET6: +		stream_putc(s, rn->p.prefixlen); +		stream_put(s, &rn->p.u.prefix6, IPV6_MAX_BYTELEN);  		break; -	      case NEXTHOP_TYPE_IPV4_IFINDEX: -		stream_put_in_addr (s, &nexthop->gate.ipv4); -		stream_putl (s, nexthop->ifindex); +	default: +		zlog_err("%s: Unknown family (%d) notification attempted\n", +			 __FUNCTION__, rn->p.family);  		break; -	      case NEXTHOP_TYPE_IPV6: -		stream_put (s, &nexthop->gate.ipv6, 16); -                stream_putl (s, nexthop->ifindex); -		break; -	      case NEXTHOP_TYPE_IPV6_IFINDEX: -		stream_put (s, &nexthop->gate.ipv6, 16); -		stream_putl (s, nexthop->ifindex); -		break; -	      default: -                /* do nothing */ -		break; -	      } -	    num++; -	  } -      stream_putc_at (s, nump, num); -    } -  else -    { -      stream_putc (s, 0);  // distance -      stream_putl (s, 0);  // metric -      stream_putc (s, 0);  // nexthops -    } -  stream_putw_at (s, 0, stream_get_endp (s)); - -  client->nh_last_upd_time = monotime(NULL); -  client->last_write_cmd = cmd; -  return zebra_server_send_message(client); +	} +	if (rib) { +		stream_putc(s, rib->distance); +		stream_putl(s, rib->metric); +		num = 0; +		nump = stream_get_endp(s); +		stream_putc(s, 0); +		for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) +			if ((CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB) +			     || CHECK_FLAG(nexthop->flags, +					   NEXTHOP_FLAG_RECURSIVE)) +			    && CHECK_FLAG(nexthop->flags, +					  NEXTHOP_FLAG_ACTIVE)) { +				stream_putc(s, nexthop->type); +				switch (nexthop->type) { +				case NEXTHOP_TYPE_IPV4: +					stream_put_in_addr(s, +							   &nexthop->gate.ipv4); +					stream_putl(s, nexthop->ifindex); +					break; +				case NEXTHOP_TYPE_IFINDEX: +					stream_putl(s, nexthop->ifindex); +					break; +				case NEXTHOP_TYPE_IPV4_IFINDEX: +					stream_put_in_addr(s, +							   &nexthop->gate.ipv4); +					stream_putl(s, nexthop->ifindex); +					break; +				case NEXTHOP_TYPE_IPV6: +					stream_put(s, &nexthop->gate.ipv6, 16); +					stream_putl(s, nexthop->ifindex); +					break; +				case NEXTHOP_TYPE_IPV6_IFINDEX: +					stream_put(s, &nexthop->gate.ipv6, 16); +					stream_putl(s, nexthop->ifindex); +					break; +				default: +					/* do nothing */ +					break; +				} +				num++; +			} +		stream_putc_at(s, nump, num); +	} else { +		stream_putc(s, 0); // distance +		stream_putl(s, 0); // metric +		stream_putc(s, 0); // nexthops +	} +	stream_putw_at(s, 0, stream_get_endp(s)); + +	client->nh_last_upd_time = monotime(NULL); +	client->last_write_cmd = cmd; +	return zebra_server_send_message(client);  } -static void -print_nh (struct nexthop *nexthop, struct vty *vty) +static void print_nh(struct nexthop *nexthop, struct vty *vty)  { -  char buf[BUFSIZ]; -  struct zebra_ns *zns = zebra_ns_lookup (NS_DEFAULT); - -  switch (nexthop->type) -    { -    case NEXTHOP_TYPE_IPV4: -    case NEXTHOP_TYPE_IPV4_IFINDEX: -      vty_out (vty, " via %s", inet_ntoa (nexthop->gate.ipv4)); -      if (nexthop->ifindex) -	vty_out (vty, ", %s", ifindex2ifname_per_ns (zns, nexthop->ifindex)); -      break; -    case NEXTHOP_TYPE_IPV6: -    case NEXTHOP_TYPE_IPV6_IFINDEX: -      vty_out (vty, " %s", -	       inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ)); -      if (nexthop->ifindex) -	vty_out (vty, ", via %s", ifindex2ifname_per_ns (zns, nexthop->ifindex)); -      break; -    case NEXTHOP_TYPE_IFINDEX: -      vty_out (vty, " is directly connected, %s", -	       ifindex2ifname_per_ns (zns, nexthop->ifindex)); -      break; -    case NEXTHOP_TYPE_BLACKHOLE: -      vty_out (vty, " is directly connected, Null0"); -      break; -    default: -      break; -    } -  vty_out(vty, "%s", VTY_NEWLINE); +	char buf[BUFSIZ]; +	struct zebra_ns *zns = zebra_ns_lookup(NS_DEFAULT); + +	switch (nexthop->type) { +	case NEXTHOP_TYPE_IPV4: +	case NEXTHOP_TYPE_IPV4_IFINDEX: +		vty_out(vty, " via %s", inet_ntoa(nexthop->gate.ipv4)); +		if (nexthop->ifindex) +			vty_out(vty, ", %s", +				ifindex2ifname_per_ns(zns, nexthop->ifindex)); +		break; +	case NEXTHOP_TYPE_IPV6: +	case NEXTHOP_TYPE_IPV6_IFINDEX: +		vty_out(vty, " %s", +			inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ)); +		if (nexthop->ifindex) +			vty_out(vty, ", via %s", +				ifindex2ifname_per_ns(zns, nexthop->ifindex)); +		break; +	case NEXTHOP_TYPE_IFINDEX: +		vty_out(vty, " is directly connected, %s", +			ifindex2ifname_per_ns(zns, nexthop->ifindex)); +		break; +	case NEXTHOP_TYPE_BLACKHOLE: +		vty_out(vty, " is directly connected, Null0"); +		break; +	default: +		break; +	} +	vty_out(vty, "%s", VTY_NEWLINE);  } -static void -print_rnh (struct route_node *rn, struct vty *vty) +static void print_rnh(struct route_node *rn, struct vty *vty)  { -  struct rnh *rnh; -  struct nexthop *nexthop; -  struct listnode *node; -  struct zserv *client; -  char buf[BUFSIZ]; - -  rnh = rn->info; -  vty_out(vty, "%s%s%s", inet_ntop(rn->p.family, &rn->p.u.prefix, buf, BUFSIZ), -	  CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED) ? "(Connected)" : "", -	  VTY_NEWLINE); -  if (rnh->state) -    { -      vty_out(vty, " resolved via %s%s", -	      zebra_route_string(rnh->state->type), VTY_NEWLINE); -      for (nexthop = rnh->state->nexthop; nexthop; nexthop = nexthop->next) -	print_nh(nexthop, vty); -    } -  else -    vty_out(vty, " unresolved%s%s", -	    CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED) ? "(Connected)" : "", -	    VTY_NEWLINE); - -  vty_out(vty, " Client list:"); -  for (ALL_LIST_ELEMENTS_RO(rnh->client_list, node, client)) -    vty_out(vty, " %s(fd %d)%s", zebra_route_string(client->proto), -	    client->sock, rnh->filtered[client->proto] ? "(filtered)" : ""); -  if (!list_isempty(rnh->zebra_static_route_list)) -    vty_out(vty, " zebra[static routes]%s", rnh->filtered[ZEBRA_ROUTE_STATIC] ? "(filtered)" : ""); -  if (!list_isempty(rnh->zebra_pseudowire_list)) -    vty_out(vty, " zebra[pseudowires]"); -  vty_out(vty, "%s", VTY_NEWLINE); +	struct rnh *rnh; +	struct nexthop *nexthop; +	struct listnode *node; +	struct zserv *client; +	char buf[BUFSIZ]; + +	rnh = rn->info; +	vty_out(vty, "%s%s%s", +		inet_ntop(rn->p.family, &rn->p.u.prefix, buf, BUFSIZ), +		CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED) ? "(Connected)" +							    : "", +		VTY_NEWLINE); +	if (rnh->state) { +		vty_out(vty, " resolved via %s%s", +			zebra_route_string(rnh->state->type), VTY_NEWLINE); +		for (nexthop = rnh->state->nexthop; nexthop; +		     nexthop = nexthop->next) +			print_nh(nexthop, vty); +	} else +		vty_out(vty, " unresolved%s%s", +			CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED) +				? "(Connected)" +				: "", +			VTY_NEWLINE); + +	vty_out(vty, " Client list:"); +	for (ALL_LIST_ELEMENTS_RO(rnh->client_list, node, client)) +		vty_out(vty, " %s(fd %d)%s", zebra_route_string(client->proto), +			client->sock, +			rnh->filtered[client->proto] ? "(filtered)" : ""); +	if (!list_isempty(rnh->zebra_static_route_list)) +		vty_out(vty, " zebra[static routes]%s", +			rnh->filtered[ZEBRA_ROUTE_STATIC] ? "(filtered)" : ""); +	if (!list_isempty(rnh->zebra_pseudowire_list)) +		vty_out(vty, " zebra[pseudowires]"); +	vty_out(vty, "%s", VTY_NEWLINE);  } diff --git a/zebra/zebra_rnh.h b/zebra/zebra_rnh.h index 9da5138e93..cfcc751a9f 100644 --- a/zebra/zebra_rnh.h +++ b/zebra/zebra_rnh.h @@ -27,31 +27,30 @@  #include "vty.h"  /* Nexthop structure. */ -struct rnh -{ -  u_char flags; +struct rnh { +	u_char flags;  #define ZEBRA_NHT_CONNECTED  	0x1  #define ZEBRA_NHT_DELETED       0x2  #define ZEBRA_NHT_EXACT_MATCH   0x4 -  /* VRF identifier. */ -  vrf_id_t vrf_id; +	/* VRF identifier. */ +	vrf_id_t vrf_id; -  struct rib *state; -  struct prefix resolved_route; -  struct list *client_list; -  struct list *zebra_static_route_list; /* static routes dependent on this NH */ -  struct list *zebra_pseudowire_list; /* pseudowires dependent on this NH */ -  struct route_node *node; -  int filtered[ZEBRA_ROUTE_MAX]; /* if this has been filtered for client */ +	struct rib *state; +	struct prefix resolved_route; +	struct list *client_list; +	struct list * +		zebra_static_route_list; /* static routes dependent on this NH +					    */ +	struct list +		*zebra_pseudowire_list; /* pseudowires dependent on this NH */ +	struct route_node *node; +	int filtered[ZEBRA_ROUTE_MAX]; /* if this has been filtered for client +					  */  }; -typedef enum -  { -    RNH_NEXTHOP_TYPE, -    RNH_IMPORT_CHECK_TYPE -  } rnh_type_t; +typedef enum { RNH_NEXTHOP_TYPE, RNH_IMPORT_CHECK_TYPE } rnh_type_t;  extern int zebra_rnh_ip_default_route;  extern int zebra_rnh_ipv6_default_route; @@ -60,22 +59,26 @@ extern struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid,  				 rnh_type_t type);  extern struct rnh *zebra_lookup_rnh(struct prefix *p, vrf_id_t vrfid,  				    rnh_type_t type); -extern void zebra_free_rnh (struct rnh *rnh); +extern void zebra_free_rnh(struct rnh *rnh);  extern void zebra_delete_rnh(struct rnh *rnh, rnh_type_t type); -extern void zebra_add_rnh_client(struct rnh *rnh, struct zserv *client, rnh_type_t type, -                                 vrf_id_t vrfid); -extern void zebra_register_rnh_static_nh(vrf_id_t, struct prefix *, struct route_node *); -extern void zebra_deregister_rnh_static_nexthops (vrf_id_t, struct nexthop *nexthop, -                                                  struct route_node *rn); -extern void zebra_deregister_rnh_static_nh(vrf_id_t, struct prefix *, struct route_node *); -extern void zebra_register_rnh_pseudowire (vrf_id_t, struct zebra_pw *); -extern void zebra_deregister_rnh_pseudowire (vrf_id_t, struct zebra_pw *); +extern void zebra_add_rnh_client(struct rnh *rnh, struct zserv *client, +				 rnh_type_t type, vrf_id_t vrfid); +extern void zebra_register_rnh_static_nh(vrf_id_t, struct prefix *, +					 struct route_node *); +extern void zebra_deregister_rnh_static_nexthops(vrf_id_t, +						 struct nexthop *nexthop, +						 struct route_node *rn); +extern void zebra_deregister_rnh_static_nh(vrf_id_t, struct prefix *, +					   struct route_node *); +extern void zebra_register_rnh_pseudowire(vrf_id_t, struct zebra_pw *); +extern void zebra_deregister_rnh_pseudowire(vrf_id_t, struct zebra_pw *);  extern void zebra_remove_rnh_client(struct rnh *rnh, struct zserv *client,  				    rnh_type_t type); -extern void zebra_evaluate_rnh(vrf_id_t vrfid, int family, int force, rnh_type_t type, -			      struct prefix *p); -extern void zebra_print_rnh_table(vrf_id_t vrfid, int family, struct vty *vty, rnh_type_t); +extern void zebra_evaluate_rnh(vrf_id_t vrfid, int family, int force, +			       rnh_type_t type, struct prefix *p); +extern void zebra_print_rnh_table(vrf_id_t vrfid, int family, struct vty *vty, +				  rnh_type_t);  extern char *rnh_str(struct rnh *rnh, char *buf, int size); -extern int zebra_cleanup_rnh_client(vrf_id_t vrf, int family, struct zserv *client, -				    rnh_type_t type); +extern int zebra_cleanup_rnh_client(vrf_id_t vrf, int family, +				    struct zserv *client, rnh_type_t type);  #endif /*_ZEBRA_RNH_H */ diff --git a/zebra/zebra_rnh_null.c b/zebra/zebra_rnh_null.c index 286290a52b..267508a488 100644 --- a/zebra/zebra_rnh_null.c +++ b/zebra/zebra_rnh_null.c @@ -27,24 +27,32 @@  int zebra_rnh_ip_default_route = 0;  int zebra_rnh_ipv6_default_route = 0; -void -zebra_free_rnh (struct rnh *rnh) -{} +void zebra_free_rnh(struct rnh *rnh) +{ +} -void zebra_evaluate_rnh (vrf_id_t vrfid, int family, int force, rnh_type_t type, -		        struct prefix *p) -{} +void zebra_evaluate_rnh(vrf_id_t vrfid, int family, int force, rnh_type_t type, +			struct prefix *p) +{ +} -void zebra_print_rnh_table (vrf_id_t vrfid, int family, struct vty *vty, -			    rnh_type_t type) -{} +void zebra_print_rnh_table(vrf_id_t vrfid, int family, struct vty *vty, +			   rnh_type_t type) +{ +} -void zebra_register_rnh_static_nh(vrf_id_t vrfid, struct prefix *p, struct route_node *rn) -{} +void zebra_register_rnh_static_nh(vrf_id_t vrfid, struct prefix *p, +				  struct route_node *rn) +{ +} -void zebra_deregister_rnh_static_nh(vrf_id_t vrfid, struct prefix *p, struct route_node *rn) -{} +void zebra_deregister_rnh_static_nh(vrf_id_t vrfid, struct prefix *p, +				    struct route_node *rn) +{ +} -void zebra_deregister_rnh_static_nexthops (vrf_id_t vrfid, struct nexthop *nexthop, -                                           struct route_node *rn) -{} +void zebra_deregister_rnh_static_nexthops(vrf_id_t vrfid, +					  struct nexthop *nexthop, +					  struct route_node *rn) +{ +} diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index 847da52952..c17a4c10f2 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -16,7 +16,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #include <zebra.h> @@ -41,185 +41,165 @@  static u_int32_t zebra_rmap_update_timer = ZEBRA_RMAP_DEFAULT_UPDATE_TIMER;  static struct thread *zebra_t_rmap_update = NULL; -char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];	/* "any" == ZEBRA_ROUTE_MAX */ +char *proto_rm[AFI_MAX][ZEBRA_ROUTE_MAX + 1]; /* "any" == ZEBRA_ROUTE_MAX */  /* NH Tracking route map */ -char *nht_rm[AFI_MAX][ZEBRA_ROUTE_MAX+1];	/* "any" == ZEBRA_ROUTE_MAX */ +char *nht_rm[AFI_MAX][ZEBRA_ROUTE_MAX + 1]; /* "any" == ZEBRA_ROUTE_MAX */  char *zebra_import_table_routemap[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; -struct nh_rmap_obj -{ -  struct nexthop *nexthop; -  vrf_id_t vrf_id; -  u_int32_t source_protocol; -  int metric; -  route_tag_t tag; +struct nh_rmap_obj { +	struct nexthop *nexthop; +	vrf_id_t vrf_id; +	u_int32_t source_protocol; +	int metric; +	route_tag_t tag;  };  static void zebra_route_map_set_delay_timer(u_int32_t value); -  /* Add zebra route map rule */ -static int -zebra_route_match_add(struct vty *vty, -		      const char *command, const char *arg, -		      route_map_event_t type) -{ -  VTY_DECLVAR_CONTEXT (route_map_index, index); -  int ret; - -  ret = route_map_add_match (index, command, arg); -  if (ret) -    { -      switch (ret) -	{ -	case RMAP_RULE_MISSING: -	  vty_out (vty, "%% Zebra Can't find rule.%s", VTY_NEWLINE); -	  return CMD_WARNING; -	case RMAP_COMPILE_ERROR: -	  vty_out (vty, "%% Zebra Argument is malformed.%s", VTY_NEWLINE); -	  return CMD_WARNING; +static int zebra_route_match_add(struct vty *vty, const char *command, +				 const char *arg, route_map_event_t type) +{ +	VTY_DECLVAR_CONTEXT(route_map_index, index); +	int ret; + +	ret = route_map_add_match(index, command, arg); +	if (ret) { +		switch (ret) { +		case RMAP_RULE_MISSING: +			vty_out(vty, "%% Zebra Can't find rule.%s", +				VTY_NEWLINE); +			return CMD_WARNING; +		case RMAP_COMPILE_ERROR: +			vty_out(vty, "%% Zebra Argument is malformed.%s", +				VTY_NEWLINE); +			return CMD_WARNING; +		}  	} -    } -  if (type != RMAP_EVENT_MATCH_ADDED) -    { -      route_map_upd8_dependency (type, arg, index->map->name); -    } -  return CMD_SUCCESS; +	if (type != RMAP_EVENT_MATCH_ADDED) { +		route_map_upd8_dependency(type, arg, index->map->name); +	} +	return CMD_SUCCESS;  }  /* Delete zebra route map rule. */ -static int -zebra_route_match_delete (struct vty *vty, -			  const char *command, const char *arg, -			  route_map_event_t type) -{ -  VTY_DECLVAR_CONTEXT (route_map_index, index); -  int ret; -  char *dep_name = NULL; -  const char *tmpstr; -  char *rmap_name = NULL; - -  if (type != RMAP_EVENT_MATCH_DELETED) -    { -      /* ignore the mundane, the types without any dependency */ -      if (arg == NULL) -	{ -	  if ((tmpstr = route_map_get_match_arg(index, command)) != NULL) -	    dep_name = XSTRDUP(MTYPE_ROUTE_MAP_RULE, tmpstr); -	} -      else -	{ -	  dep_name = XSTRDUP(MTYPE_ROUTE_MAP_RULE, arg); +static int zebra_route_match_delete(struct vty *vty, const char *command, +				    const char *arg, route_map_event_t type) +{ +	VTY_DECLVAR_CONTEXT(route_map_index, index); +	int ret; +	char *dep_name = NULL; +	const char *tmpstr; +	char *rmap_name = NULL; + +	if (type != RMAP_EVENT_MATCH_DELETED) { +		/* ignore the mundane, the types without any dependency */ +		if (arg == NULL) { +			if ((tmpstr = route_map_get_match_arg(index, command)) +			    != NULL) +				dep_name = +					XSTRDUP(MTYPE_ROUTE_MAP_RULE, tmpstr); +		} else { +			dep_name = XSTRDUP(MTYPE_ROUTE_MAP_RULE, arg); +		} +		rmap_name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, index->map->name);  	} -      rmap_name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, index->map->name); -    } -  ret = route_map_delete_match (index, command, arg); -  if (ret) -    { -      switch (ret) -	{ -	case RMAP_RULE_MISSING: -	  vty_out (vty, "%% Zebra Can't find rule.%s", VTY_NEWLINE); -	  return CMD_WARNING; -	case RMAP_COMPILE_ERROR: -	  vty_out (vty, "%% Zebra Argument is malformed.%s", VTY_NEWLINE); -	  return CMD_WARNING; +	ret = route_map_delete_match(index, command, arg); +	if (ret) { +		switch (ret) { +		case RMAP_RULE_MISSING: +			vty_out(vty, "%% Zebra Can't find rule.%s", +				VTY_NEWLINE); +			return CMD_WARNING; +		case RMAP_COMPILE_ERROR: +			vty_out(vty, "%% Zebra Argument is malformed.%s", +				VTY_NEWLINE); +			return CMD_WARNING; +		}  	} -    } -  if (type != RMAP_EVENT_MATCH_DELETED && dep_name) -    route_map_upd8_dependency(type, dep_name, rmap_name); +	if (type != RMAP_EVENT_MATCH_DELETED && dep_name) +		route_map_upd8_dependency(type, dep_name, rmap_name); -  if (dep_name) -    XFREE(MTYPE_ROUTE_MAP_RULE, dep_name); -  if (rmap_name) -    XFREE(MTYPE_ROUTE_MAP_NAME, rmap_name); +	if (dep_name) +		XFREE(MTYPE_ROUTE_MAP_RULE, dep_name); +	if (rmap_name) +		XFREE(MTYPE_ROUTE_MAP_NAME, rmap_name); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  /* 'match tag TAG'   * Match function return 1 if match is success else return 0   */ -static route_map_result_t -route_match_tag (void *rule, struct prefix *prefix, -		 route_map_object_t type, void *object) +static route_map_result_t route_match_tag(void *rule, struct prefix *prefix, +					  route_map_object_t type, void *object)  { -  route_tag_t *tag; -  struct nh_rmap_obj *nh_data; +	route_tag_t *tag; +	struct nh_rmap_obj *nh_data; -  if (type == RMAP_ZEBRA) -    { -      tag = rule; -      nh_data = object; +	if (type == RMAP_ZEBRA) { +		tag = rule; +		nh_data = object; -      if (nh_data->tag == *tag) -	return RMAP_MATCH; -    } -  return RMAP_NOMATCH; +		if (nh_data->tag == *tag) +			return RMAP_MATCH; +	} +	return RMAP_NOMATCH;  }  /* Route map commands for tag matching */ -static struct route_map_rule_cmd route_match_tag_cmd = -{ -   "tag", -   route_match_tag, -  route_map_rule_tag_compile, -  route_map_rule_tag_free, +static struct route_map_rule_cmd route_match_tag_cmd = { +	"tag", route_match_tag, route_map_rule_tag_compile, +	route_map_rule_tag_free,  };  /* `match interface IFNAME' */  /* Match function return 1 if match is success else return zero. */ -static route_map_result_t -route_match_interface (void *rule, struct prefix *prefix, -		       route_map_object_t type, void *object) -{ -  struct nh_rmap_obj *nh_data; -  char *ifname = rule; -  ifindex_t ifindex; - -  if (type == RMAP_ZEBRA) -    { -      if (strcasecmp(ifname, "any") == 0) -	return RMAP_MATCH; -      nh_data = object; -      if (!nh_data || !nh_data->nexthop) -	return RMAP_NOMATCH; -      ifindex = ifname2ifindex (ifname, nh_data->vrf_id); -      if (ifindex == 0) +static route_map_result_t route_match_interface(void *rule, +						struct prefix *prefix, +						route_map_object_t type, +						void *object) +{ +	struct nh_rmap_obj *nh_data; +	char *ifname = rule; +	ifindex_t ifindex; + +	if (type == RMAP_ZEBRA) { +		if (strcasecmp(ifname, "any") == 0) +			return RMAP_MATCH; +		nh_data = object; +		if (!nh_data || !nh_data->nexthop) +			return RMAP_NOMATCH; +		ifindex = ifname2ifindex(ifname, nh_data->vrf_id); +		if (ifindex == 0) +			return RMAP_NOMATCH; +		if (nh_data->nexthop->ifindex == ifindex) +			return RMAP_MATCH; +	}  	return RMAP_NOMATCH; -      if (nh_data->nexthop->ifindex == ifindex) -	return RMAP_MATCH; -    } -  return RMAP_NOMATCH;  }  /* Route map `match interface' match statement. `arg' is IFNAME value */ -static void * -route_match_interface_compile (const char *arg) +static void *route_match_interface_compile(const char *arg)  { -  return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); +	return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);  }  /* Free route map's compiled `match interface' value. */ -static void -route_match_interface_free (void *rule) +static void route_match_interface_free(void *rule)  { -  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); +	XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);  }  /* Route map commands for interface matching */ -struct route_map_rule_cmd route_match_interface_cmd = -{ -   "interface", -   route_match_interface, -   route_match_interface_compile, -   route_match_interface_free -}; +struct route_map_rule_cmd route_match_interface_cmd = { +	"interface", route_match_interface, route_match_interface_compile, +	route_match_interface_free};  DEFUN (match_ip_address_prefix_len,         match_ip_address_prefix_len_cmd, @@ -230,8 +210,8 @@ DEFUN (match_ip_address_prefix_len,         "Match prefix length of ip address\n"         "Prefix length\n")  { -  return zebra_route_match_add (vty, "ip address prefix-len", -				argv[4]->arg, RMAP_EVENT_MATCH_ADDED); +	return zebra_route_match_add(vty, "ip address prefix-len", argv[4]->arg, +				     RMAP_EVENT_MATCH_ADDED);  }  DEFUN (no_match_ip_address_prefix_len, @@ -244,10 +224,9 @@ DEFUN (no_match_ip_address_prefix_len,         "Match prefix length of ip address\n"         "Prefix length\n")  { -  char *plen = (argc == 6) ? argv[5]->arg : NULL; -  return zebra_route_match_delete (vty, -				   "ip address prefix-len", plen, -				   RMAP_EVENT_MATCH_DELETED); +	char *plen = (argc == 6) ? argv[5]->arg : NULL; +	return zebra_route_match_delete(vty, "ip address prefix-len", plen, +					RMAP_EVENT_MATCH_DELETED);  } @@ -260,8 +239,8 @@ DEFUN (match_ip_nexthop_prefix_len,         "Match prefixlen of given nexthop\n"         "Prefix length\n")  { -  return zebra_route_match_add (vty, "ip next-hop prefix-len", -				argv[4]->arg, RMAP_EVENT_MATCH_ADDED); +	return zebra_route_match_add(vty, "ip next-hop prefix-len", +				     argv[4]->arg, RMAP_EVENT_MATCH_ADDED);  }  DEFUN (no_match_ip_nexthop_prefix_len, @@ -274,10 +253,9 @@ DEFUN (no_match_ip_nexthop_prefix_len,         "Match prefix length of nexthop\n"         "Prefix length\n")  { -  char *plen = (argc == 6) ? argv[5]->arg : NULL; -  return zebra_route_match_delete (vty, -				   "ip next-hop prefix-len", plen, -				   RMAP_EVENT_MATCH_DELETED); +	char *plen = (argc == 6) ? argv[5]->arg : NULL; +	return zebra_route_match_delete(vty, "ip next-hop prefix-len", plen, +					RMAP_EVENT_MATCH_DELETED);  } @@ -297,16 +275,17 @@ DEFUN (match_source_protocol,         "Routes from kernel\n"         "Statically configured routes\n")  { -  char *proto = argv[2]->text; -  int i; +	char *proto = argv[2]->text; +	int i; -  i = proto_name2num(proto); -  if (i < 0) -    { -      vty_out (vty, "invalid protocol name \"%s\"%s", proto, VTY_NEWLINE); -      return CMD_WARNING; -    } -  return zebra_route_match_add (vty, "source-protocol", proto, RMAP_EVENT_MATCH_ADDED); +	i = proto_name2num(proto); +	if (i < 0) { +		vty_out(vty, "invalid protocol name \"%s\"%s", proto, +			VTY_NEWLINE); +		return CMD_WARNING; +	} +	return zebra_route_match_add(vty, "source-protocol", proto, +				     RMAP_EVENT_MATCH_ADDED);  }  DEFUN (no_match_source_protocol, @@ -326,8 +305,9 @@ DEFUN (no_match_source_protocol,         "Routes from kernel\n"         "Statically configured routes\n")  { -  char *proto = (argc == 4) ? argv[3]->text : NULL; -  return zebra_route_match_delete (vty, "source-protocol", proto, RMAP_EVENT_MATCH_DELETED); +	char *proto = (argc == 4) ? argv[3]->text : NULL; +	return zebra_route_match_delete(vty, "source-protocol", proto, +					RMAP_EVENT_MATCH_DELETED);  }  /* set functions */ @@ -340,59 +320,55 @@ DEFUN (set_src,         "IPv4 src address\n"         "IPv6 src address\n")  { -  int idx_ip = 2; -  union g_addr src; -  struct interface *pif = NULL; -  int family; -  struct prefix p; -  struct vrf *vrf; +	int idx_ip = 2; +	union g_addr src; +	struct interface *pif = NULL; +	int family; +	struct prefix p; +	struct vrf *vrf; + +	if (inet_pton(AF_INET, argv[idx_ip]->arg, &src.ipv4) != 1) { +		if (inet_pton(AF_INET6, argv[idx_ip]->arg, &src.ipv6) != 1) { +			vty_out(vty, "%% not a valid IPv4/v6 address%s", +				VTY_NEWLINE); +			return CMD_WARNING; +		} + +		p.family = family = AF_INET6; +		p.u.prefix6 = src.ipv6; +		p.prefixlen = IPV6_MAX_BITLEN; +	} else { +		p.family = family = AF_INET; +		p.u.prefix4 = src.ipv4; +		p.prefixlen = IPV4_MAX_BITLEN; +	} + +	if (!zebra_check_addr(&p)) { +		vty_out(vty, "%% not a valid source IPv4/v6 address%s", +			VTY_NEWLINE); +		return CMD_WARNING; +	} -  if (inet_pton(AF_INET, argv[idx_ip]->arg, &src.ipv4) != 1) -    { -      if (inet_pton(AF_INET6, argv[idx_ip]->arg, &src.ipv6) != 1) +	RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id)  	{ -	  vty_out (vty, "%% not a valid IPv4/v6 address%s", VTY_NEWLINE); -	  return CMD_WARNING; +		if (family == AF_INET) +			pif = if_lookup_exact_address((void *)&src.ipv4, +						      AF_INET, vrf->vrf_id); +		else if (family == AF_INET6) +			pif = if_lookup_exact_address((void *)&src.ipv6, +						      AF_INET6, vrf->vrf_id); + +		if (pif != NULL) +			break;  	} -      p.family = family = AF_INET6; -      p.u.prefix6 = src.ipv6; -      p.prefixlen = IPV6_MAX_BITLEN; -    } -  else -    { -      p.family = family = AF_INET; -      p.u.prefix4 = src.ipv4; -      p.prefixlen = IPV4_MAX_BITLEN; -    } - -  if (!zebra_check_addr(&p)) -    { -      vty_out (vty, "%% not a valid source IPv4/v6 address%s", VTY_NEWLINE); -      return CMD_WARNING; -    } - -  RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) -    { -      if (family == AF_INET) -        pif = if_lookup_exact_address ((void *)&src.ipv4, AF_INET, -                                       vrf->vrf_id); -      else if (family == AF_INET6) -        pif = if_lookup_exact_address ((void *)&src.ipv6, AF_INET6, -                                       vrf->vrf_id); - -      if (pif != NULL) -        break; -    } - -  if (!pif) -    { -      vty_out (vty, "%% not a local address%s", VTY_NEWLINE); -      return CMD_WARNING; -    } - -  VTY_DECLVAR_CONTEXT (route_map_index, index); -  return generic_set_add (vty, index, "src", argv[idx_ip]->arg); +	if (!pif) { +		vty_out(vty, "%% not a local address%s", VTY_NEWLINE); +		return CMD_WARNING; +	} + +	VTY_DECLVAR_CONTEXT(route_map_index, index); +	return generic_set_add(vty, index, "src", argv[idx_ip]->arg);  }  DEFUN (no_set_src, @@ -404,9 +380,9 @@ DEFUN (no_set_src,         "IPv4 address\n"         "IPv6 address\n")  { -  char *ip = (argc == 4) ? argv[3]->arg : NULL; -  VTY_DECLVAR_CONTEXT (route_map_index, index); -  return generic_set_delete (vty, index, "src", ip); +	char *ip = (argc == 4) ? argv[3]->arg : NULL; +	VTY_DECLVAR_CONTEXT(route_map_index, index); +	return generic_set_delete(vty, index, "src", ip);  }  DEFUN (zebra_route_map_timer, @@ -417,13 +393,14 @@ DEFUN (zebra_route_map_timer,         "Time to wait before route-map updates are processed\n"         "0 means event-driven updates are disabled\n")  { -  int idx_number = 3; -  u_int32_t rmap_delay_timer; +	int idx_number = 3; +	u_int32_t rmap_delay_timer; -  VTY_GET_INTEGER_RANGE ("delay-timer", rmap_delay_timer, argv[idx_number]->arg, 0, 600); -  zebra_route_map_set_delay_timer(rmap_delay_timer); +	VTY_GET_INTEGER_RANGE("delay-timer", rmap_delay_timer, +			      argv[idx_number]->arg, 0, 600); +	zebra_route_map_set_delay_timer(rmap_delay_timer); -  return (CMD_SUCCESS); +	return (CMD_SUCCESS);  }  DEFUN (no_zebra_route_map_timer, @@ -435,9 +412,9 @@ DEFUN (no_zebra_route_map_timer,         "Reset delay-timer to default value, 30 secs\n"         "0 means event-driven updates are disabled\n")  { -  zebra_route_map_set_delay_timer(ZEBRA_RMAP_DEFAULT_UPDATE_TIMER); +	zebra_route_map_set_delay_timer(ZEBRA_RMAP_DEFAULT_UPDATE_TIMER); -  return (CMD_SUCCESS); +	return (CMD_SUCCESS);  } @@ -450,34 +427,34 @@ DEFUN (ip_protocol,         "Specify route-map\n"         "Route map name\n")  { -  char *proto = argv[2]->text; -  char *rmap = argv[4]->arg; -  int i; - -  if (strcasecmp(proto, "any") == 0) -    i = ZEBRA_ROUTE_MAX; -  else -    i = proto_name2num(proto); -  if (i < 0) -    { -      vty_out (vty, "invalid protocol name \"%s\"%s", proto, VTY_NEWLINE); -      return CMD_WARNING; -    } -  if (proto_rm[AFI_IP][i]) -    { -      if (strcmp(proto_rm[AFI_IP][i], rmap) == 0) -	return CMD_SUCCESS; +	char *proto = argv[2]->text; +	char *rmap = argv[4]->arg; +	int i; + +	if (strcasecmp(proto, "any") == 0) +		i = ZEBRA_ROUTE_MAX; +	else +		i = proto_name2num(proto); +	if (i < 0) { +		vty_out(vty, "invalid protocol name \"%s\"%s", proto, +			VTY_NEWLINE); +		return CMD_WARNING; +	} +	if (proto_rm[AFI_IP][i]) { +		if (strcmp(proto_rm[AFI_IP][i], rmap) == 0) +			return CMD_SUCCESS; -      XFREE (MTYPE_ROUTE_MAP_NAME, proto_rm[AFI_IP][i]); -    } -  proto_rm[AFI_IP][i] = XSTRDUP (MTYPE_ROUTE_MAP_NAME, rmap); +		XFREE(MTYPE_ROUTE_MAP_NAME, proto_rm[AFI_IP][i]); +	} +	proto_rm[AFI_IP][i] = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap); -  if (IS_ZEBRA_DEBUG_RIB_DETAILED) -    zlog_debug ("%u: IPv4 Routemap config for protocol %s, scheduling RIB processing", -                VRF_DEFAULT, proto); +	if (IS_ZEBRA_DEBUG_RIB_DETAILED) +		zlog_debug( +			"%u: IPv4 Routemap config for protocol %s, scheduling RIB processing", +			VRF_DEFAULT, proto); -  rib_update(VRF_DEFAULT, RIB_UPDATE_RMAP_CHANGE); -  return CMD_SUCCESS; +	rib_update(VRF_DEFAULT, RIB_UPDATE_RMAP_CHANGE); +	return CMD_SUCCESS;  }  DEFUN (no_ip_protocol, @@ -490,35 +467,35 @@ DEFUN (no_ip_protocol,         "Specify route map\n"         "Route map name\n")  { -  char *proto = argv[3]->text; -  char *rmap = (argc == 6) ? argv[5]->arg : NULL; -  int i; +	char *proto = argv[3]->text; +	char *rmap = (argc == 6) ? argv[5]->arg : NULL; +	int i; -  if (strcasecmp(proto, "any") == 0) -    i = ZEBRA_ROUTE_MAX; -  else -    i = proto_name2num(proto); +	if (strcasecmp(proto, "any") == 0) +		i = ZEBRA_ROUTE_MAX; +	else +		i = proto_name2num(proto); -  if (i < 0) -    { -      vty_out (vty, "invalid protocol name \"%s\"%s", proto, VTY_NEWLINE); -     return CMD_WARNING; -    } +	if (i < 0) { +		vty_out(vty, "invalid protocol name \"%s\"%s", proto, +			VTY_NEWLINE); +		return CMD_WARNING; +	} -  if (!proto_rm[AFI_IP][i]) -    return CMD_SUCCESS; +	if (!proto_rm[AFI_IP][i]) +		return CMD_SUCCESS; -  if (!rmap || strcmp (rmap, proto_rm[AFI_IP][i]) == 0) -    { -      XFREE (MTYPE_ROUTE_MAP_NAME, proto_rm[AFI_IP][i]); -      proto_rm[AFI_IP][i] = NULL; +	if (!rmap || strcmp(rmap, proto_rm[AFI_IP][i]) == 0) { +		XFREE(MTYPE_ROUTE_MAP_NAME, proto_rm[AFI_IP][i]); +		proto_rm[AFI_IP][i] = NULL; -      if (IS_ZEBRA_DEBUG_RIB_DETAILED) -        zlog_debug ("%u: IPv4 Routemap unconfig for protocol %s, scheduling RIB processing", -                    VRF_DEFAULT, proto); -      rib_update(VRF_DEFAULT, RIB_UPDATE_RMAP_CHANGE); -    } -  return CMD_SUCCESS; +		if (IS_ZEBRA_DEBUG_RIB_DETAILED) +			zlog_debug( +				"%u: IPv4 Routemap unconfig for protocol %s, scheduling RIB processing", +				VRF_DEFAULT, proto); +		rib_update(VRF_DEFAULT, RIB_UPDATE_RMAP_CHANGE); +	} +	return CMD_SUCCESS;  }  DEFUN (show_ip_protocol, @@ -528,26 +505,25 @@ DEFUN (show_ip_protocol,          IP_STR         "IP protocol filtering status\n")  { -    int i; - -    vty_out(vty, "Protocol    : route-map %s", VTY_NEWLINE); -    vty_out(vty, "------------------------%s", VTY_NEWLINE); -    for (i=0;i<ZEBRA_ROUTE_MAX;i++) -    { -        if (proto_rm[AFI_IP][i]) -          vty_out (vty, "%-10s  : %-10s%s", zebra_route_string(i), -					proto_rm[AFI_IP][i], -					VTY_NEWLINE); -        else -          vty_out (vty, "%-10s  : none%s", zebra_route_string(i), VTY_NEWLINE); -    } -    if (proto_rm[AFI_IP][i]) -      vty_out (vty, "%-10s  : %-10s%s", "any", proto_rm[AFI_IP][i], -					VTY_NEWLINE); -    else -      vty_out (vty, "%-10s  : none%s", "any", VTY_NEWLINE); +	int i; + +	vty_out(vty, "Protocol    : route-map %s", VTY_NEWLINE); +	vty_out(vty, "------------------------%s", VTY_NEWLINE); +	for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { +		if (proto_rm[AFI_IP][i]) +			vty_out(vty, "%-10s  : %-10s%s", zebra_route_string(i), +				proto_rm[AFI_IP][i], VTY_NEWLINE); +		else +			vty_out(vty, "%-10s  : none%s", zebra_route_string(i), +				VTY_NEWLINE); +	} +	if (proto_rm[AFI_IP][i]) +		vty_out(vty, "%-10s  : %-10s%s", "any", proto_rm[AFI_IP][i], +			VTY_NEWLINE); +	else +		vty_out(vty, "%-10s  : none%s", "any", VTY_NEWLINE); -    return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (ipv6_protocol, @@ -559,34 +535,34 @@ DEFUN (ipv6_protocol,         "Specify route map\n"         "Route map name\n")  { -  char *proto = argv[2]->text; -  char *rmap = argv[4]->arg; -  int i; - -  if (strcasecmp(proto, "any") == 0) -    i = ZEBRA_ROUTE_MAX; -  else -    i = proto_name2num(proto); -  if (i < 0) -    { -      vty_out (vty, "invalid protocol name \"%s\"%s", proto, VTY_NEWLINE); -      return CMD_WARNING; -    } -  if (proto_rm[AFI_IP6][i]) -    { -      if (strcmp(proto_rm[AFI_IP6][i], rmap) == 0) -	return CMD_SUCCESS; +	char *proto = argv[2]->text; +	char *rmap = argv[4]->arg; +	int i; + +	if (strcasecmp(proto, "any") == 0) +		i = ZEBRA_ROUTE_MAX; +	else +		i = proto_name2num(proto); +	if (i < 0) { +		vty_out(vty, "invalid protocol name \"%s\"%s", proto, +			VTY_NEWLINE); +		return CMD_WARNING; +	} +	if (proto_rm[AFI_IP6][i]) { +		if (strcmp(proto_rm[AFI_IP6][i], rmap) == 0) +			return CMD_SUCCESS; -      XFREE (MTYPE_ROUTE_MAP_NAME, proto_rm[AFI_IP6][i]); -    } -  proto_rm[AFI_IP6][i] = XSTRDUP (MTYPE_ROUTE_MAP_NAME, rmap); +		XFREE(MTYPE_ROUTE_MAP_NAME, proto_rm[AFI_IP6][i]); +	} +	proto_rm[AFI_IP6][i] = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap); -  if (IS_ZEBRA_DEBUG_RIB_DETAILED) -    zlog_debug ("%u: IPv6 Routemap config for protocol %s, scheduling RIB processing", -                VRF_DEFAULT, proto); +	if (IS_ZEBRA_DEBUG_RIB_DETAILED) +		zlog_debug( +			"%u: IPv6 Routemap config for protocol %s, scheduling RIB processing", +			VRF_DEFAULT, proto); -  rib_update(VRF_DEFAULT, RIB_UPDATE_RMAP_CHANGE); -  return CMD_SUCCESS; +	rib_update(VRF_DEFAULT, RIB_UPDATE_RMAP_CHANGE); +	return CMD_SUCCESS;  }  DEFUN (no_ipv6_protocol, @@ -599,34 +575,34 @@ DEFUN (no_ipv6_protocol,         "Specify route map\n"         "Route map name\n")  { -  const char *proto = argv[3]->text; -  const char *rmap = (argc == 6) ? argv[5]->arg : NULL; -  int i; - -  if (strcasecmp(proto, "any") == 0) -    i = ZEBRA_ROUTE_MAX; -  else -    i = proto_name2num(proto); -  if (i < 0) -    { -      vty_out (vty, "invalid protocol name \"%s\"%s", proto, VTY_NEWLINE); -     return CMD_WARNING; -    } -  if (!proto_rm[AFI_IP6][i]) -    return CMD_SUCCESS; +	const char *proto = argv[3]->text; +	const char *rmap = (argc == 6) ? argv[5]->arg : NULL; +	int i; + +	if (strcasecmp(proto, "any") == 0) +		i = ZEBRA_ROUTE_MAX; +	else +		i = proto_name2num(proto); +	if (i < 0) { +		vty_out(vty, "invalid protocol name \"%s\"%s", proto, +			VTY_NEWLINE); +		return CMD_WARNING; +	} +	if (!proto_rm[AFI_IP6][i]) +		return CMD_SUCCESS; -  if (!rmap || strcmp(rmap, proto_rm[AFI_IP6][i]) == 0) -    { -      XFREE (MTYPE_ROUTE_MAP_NAME, proto_rm[AFI_IP6][i]); -      proto_rm[AFI_IP6][i] = NULL; +	if (!rmap || strcmp(rmap, proto_rm[AFI_IP6][i]) == 0) { +		XFREE(MTYPE_ROUTE_MAP_NAME, proto_rm[AFI_IP6][i]); +		proto_rm[AFI_IP6][i] = NULL; -      if (IS_ZEBRA_DEBUG_RIB_DETAILED) -        zlog_debug ("%u: IPv6 Routemap unconfig for protocol %s, scheduling RIB processing", -                    VRF_DEFAULT, proto); +		if (IS_ZEBRA_DEBUG_RIB_DETAILED) +			zlog_debug( +				"%u: IPv6 Routemap unconfig for protocol %s, scheduling RIB processing", +				VRF_DEFAULT, proto); -      rib_update(VRF_DEFAULT, RIB_UPDATE_RMAP_CHANGE); -    } -  return CMD_SUCCESS; +		rib_update(VRF_DEFAULT, RIB_UPDATE_RMAP_CHANGE); +	} +	return CMD_SUCCESS;  }  DEFUN (show_ipv6_protocol, @@ -636,26 +612,25 @@ DEFUN (show_ipv6_protocol,          IP6_STR         "IPv6 protocol filtering status\n")  { -    int i; - -    vty_out(vty, "Protocol    : route-map %s", VTY_NEWLINE); -    vty_out(vty, "------------------------%s", VTY_NEWLINE); -    for (i=0;i<ZEBRA_ROUTE_MAX;i++) -    { -        if (proto_rm[AFI_IP6][i]) -          vty_out (vty, "%-10s  : %-10s%s", zebra_route_string(i), -					proto_rm[AFI_IP6][i], -					VTY_NEWLINE); -        else -          vty_out (vty, "%-10s  : none%s", zebra_route_string(i), VTY_NEWLINE); -    } -    if (proto_rm[AFI_IP6][i]) -      vty_out (vty, "%-10s  : %-10s%s", "any", proto_rm[AFI_IP6][i], -					VTY_NEWLINE); -    else -      vty_out (vty, "%-10s  : none%s", "any", VTY_NEWLINE); +	int i; + +	vty_out(vty, "Protocol    : route-map %s", VTY_NEWLINE); +	vty_out(vty, "------------------------%s", VTY_NEWLINE); +	for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { +		if (proto_rm[AFI_IP6][i]) +			vty_out(vty, "%-10s  : %-10s%s", zebra_route_string(i), +				proto_rm[AFI_IP6][i], VTY_NEWLINE); +		else +			vty_out(vty, "%-10s  : none%s", zebra_route_string(i), +				VTY_NEWLINE); +	} +	if (proto_rm[AFI_IP6][i]) +		vty_out(vty, "%-10s  : %-10s%s", "any", proto_rm[AFI_IP6][i], +			VTY_NEWLINE); +	else +		vty_out(vty, "%-10s  : none%s", "any", VTY_NEWLINE); -    return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (ip_protocol_nht_rmap, @@ -667,31 +642,30 @@ DEFUN (ip_protocol_nht_rmap,         "Specify route map\n"         "Route map name\n")  { -  char *proto = argv[2]->text; -  char *rmap = argv[4]->arg; -  int i; - -  if (strcasecmp(proto, "any") == 0) -    i = ZEBRA_ROUTE_MAX; -  else -    i = proto_name2num(proto); -  if (i < 0) -    { -      vty_out (vty, "invalid protocol name \"%s\"%s", proto, VTY_NEWLINE); -      return CMD_WARNING; -    } -  if (nht_rm[AFI_IP][i]) -    { -      if (strcmp(nht_rm[AFI_IP][i], rmap) == 0) -	return CMD_SUCCESS; +	char *proto = argv[2]->text; +	char *rmap = argv[4]->arg; +	int i; + +	if (strcasecmp(proto, "any") == 0) +		i = ZEBRA_ROUTE_MAX; +	else +		i = proto_name2num(proto); +	if (i < 0) { +		vty_out(vty, "invalid protocol name \"%s\"%s", proto, +			VTY_NEWLINE); +		return CMD_WARNING; +	} +	if (nht_rm[AFI_IP][i]) { +		if (strcmp(nht_rm[AFI_IP][i], rmap) == 0) +			return CMD_SUCCESS; -      XFREE (MTYPE_ROUTE_MAP_NAME, nht_rm[AFI_IP][i]); -    } +		XFREE(MTYPE_ROUTE_MAP_NAME, nht_rm[AFI_IP][i]); +	} -  nht_rm[AFI_IP][i] = XSTRDUP (MTYPE_ROUTE_MAP_NAME, rmap); -  zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL); +	nht_rm[AFI_IP][i] = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap); +	zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (no_ip_protocol_nht_rmap, @@ -704,28 +678,29 @@ DEFUN (no_ip_protocol_nht_rmap,         "Specify route map\n"         "Route map name\n")  { -  int idx = 0; -  char *proto = argv[3]->text; -  char *rmap = argv_find (argv, argc, "ROUTE-MAP", &idx) ? argv[idx]->arg : NULL; +	int idx = 0; +	char *proto = argv[3]->text; +	char *rmap = argv_find(argv, argc, "ROUTE-MAP", &idx) ? argv[idx]->arg +							      : NULL; -  int i = strmatch(proto, "any") ? ZEBRA_ROUTE_MAX : proto_name2num(proto); +	int i = strmatch(proto, "any") ? ZEBRA_ROUTE_MAX +				       : proto_name2num(proto); -  if (i < 0) -    { -      vty_out (vty, "invalid protocol name \"%s\"%s", proto, VTY_NEWLINE); -      return CMD_WARNING; -    } +	if (i < 0) { +		vty_out(vty, "invalid protocol name \"%s\"%s", proto, +			VTY_NEWLINE); +		return CMD_WARNING; +	} -  if (!nht_rm[AFI_IP][i]) -    return CMD_SUCCESS; +	if (!nht_rm[AFI_IP][i]) +		return CMD_SUCCESS; -  if (!rmap || strcmp(rmap, nht_rm[AFI_IP][i]) == 0) -    { -      XFREE (MTYPE_ROUTE_MAP_NAME, nht_rm[AFI_IP][i]); -      nht_rm[AFI_IP][i] = NULL; -      zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL); -    } -  return CMD_SUCCESS; +	if (!rmap || strcmp(rmap, nht_rm[AFI_IP][i]) == 0) { +		XFREE(MTYPE_ROUTE_MAP_NAME, nht_rm[AFI_IP][i]); +		nht_rm[AFI_IP][i] = NULL; +		zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL); +	} +	return CMD_SUCCESS;  }  DEFUN (show_ip_protocol_nht, @@ -736,26 +711,25 @@ DEFUN (show_ip_protocol_nht,         "IP nexthop tracking table\n"         "IP Next Hop tracking filtering status\n")  { -    int i; - -    vty_out(vty, "Protocol    : route-map %s", VTY_NEWLINE); -    vty_out(vty, "------------------------%s", VTY_NEWLINE); -    for (i=0;i<ZEBRA_ROUTE_MAX;i++) -    { -        if (nht_rm[AFI_IP][i]) -          vty_out (vty, "%-10s  : %-10s%s", zebra_route_string(i), -					nht_rm[AFI_IP][i], -					VTY_NEWLINE); -        else -          vty_out (vty, "%-10s  : none%s", zebra_route_string(i), VTY_NEWLINE); -    } -    if (nht_rm[AFI_IP][i]) -      vty_out (vty, "%-10s  : %-10s%s", "any", nht_rm[AFI_IP][i], -					VTY_NEWLINE); -    else -      vty_out (vty, "%-10s  : none%s", "any", VTY_NEWLINE); +	int i; + +	vty_out(vty, "Protocol    : route-map %s", VTY_NEWLINE); +	vty_out(vty, "------------------------%s", VTY_NEWLINE); +	for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { +		if (nht_rm[AFI_IP][i]) +			vty_out(vty, "%-10s  : %-10s%s", zebra_route_string(i), +				nht_rm[AFI_IP][i], VTY_NEWLINE); +		else +			vty_out(vty, "%-10s  : none%s", zebra_route_string(i), +				VTY_NEWLINE); +	} +	if (nht_rm[AFI_IP][i]) +		vty_out(vty, "%-10s  : %-10s%s", "any", nht_rm[AFI_IP][i], +			VTY_NEWLINE); +	else +		vty_out(vty, "%-10s  : none%s", "any", VTY_NEWLINE); -    return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (ipv6_protocol_nht_rmap, @@ -767,25 +741,25 @@ DEFUN (ipv6_protocol_nht_rmap,         "Specify route map\n"         "Route map name\n")  { -  char *proto = argv[2]->text; -  char *rmap = argv[4]->arg; -  int i; - -  if (strcasecmp(proto, "any") == 0) -    i = ZEBRA_ROUTE_MAX; -  else -    i = proto_name2num(proto); -  if (i < 0) -    { -      vty_out (vty, "invalid protocol name \"%s\"%s", proto, VTY_NEWLINE); -      return CMD_WARNING; -    } -  if (nht_rm[AFI_IP6][i]) -    XFREE (MTYPE_ROUTE_MAP_NAME, nht_rm[AFI_IP6][i]); -  nht_rm[AFI_IP6][i] = XSTRDUP (MTYPE_ROUTE_MAP_NAME, rmap); -  zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL); +	char *proto = argv[2]->text; +	char *rmap = argv[4]->arg; +	int i; + +	if (strcasecmp(proto, "any") == 0) +		i = ZEBRA_ROUTE_MAX; +	else +		i = proto_name2num(proto); +	if (i < 0) { +		vty_out(vty, "invalid protocol name \"%s\"%s", proto, +			VTY_NEWLINE); +		return CMD_WARNING; +	} +	if (nht_rm[AFI_IP6][i]) +		XFREE(MTYPE_ROUTE_MAP_NAME, nht_rm[AFI_IP6][i]); +	nht_rm[AFI_IP6][i] = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap); +	zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (no_ipv6_protocol_nht_rmap, @@ -798,35 +772,33 @@ DEFUN (no_ipv6_protocol_nht_rmap,         "Specify route map\n"         "Route map name\n")  { -  char *proto = argv[3]->text; -  char *rmap = (argc == 6) ? argv[5]->arg : NULL; -  int i; - -  if (strcasecmp(proto, "any") == 0) -    i = ZEBRA_ROUTE_MAX; -  else -    i = proto_name2num(proto); -  if (i < 0) -    { -      vty_out (vty, "invalid protocol name \"%s\"%s", proto, VTY_NEWLINE); -      return CMD_WARNING; -    } +	char *proto = argv[3]->text; +	char *rmap = (argc == 6) ? argv[5]->arg : NULL; +	int i; + +	if (strcasecmp(proto, "any") == 0) +		i = ZEBRA_ROUTE_MAX; +	else +		i = proto_name2num(proto); +	if (i < 0) { +		vty_out(vty, "invalid protocol name \"%s\"%s", proto, +			VTY_NEWLINE); +		return CMD_WARNING; +	} -  if (nht_rm[AFI_IP6][i] && rmap && strcmp(rmap, nht_rm[AFI_IP6][i])) -    { -      vty_out (vty, "invalid route-map \"%s\"%s", rmap, VTY_NEWLINE); -      return CMD_WARNING; -    } +	if (nht_rm[AFI_IP6][i] && rmap && strcmp(rmap, nht_rm[AFI_IP6][i])) { +		vty_out(vty, "invalid route-map \"%s\"%s", rmap, VTY_NEWLINE); +		return CMD_WARNING; +	} -  if (nht_rm[AFI_IP6][i]) -    { -      XFREE (MTYPE_ROUTE_MAP_NAME, nht_rm[AFI_IP6][i]); -      nht_rm[AFI_IP6][i] = NULL; -    } +	if (nht_rm[AFI_IP6][i]) { +		XFREE(MTYPE_ROUTE_MAP_NAME, nht_rm[AFI_IP6][i]); +		nht_rm[AFI_IP6][i] = NULL; +	} -  zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL); +	zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (show_ipv6_protocol_nht, @@ -837,26 +809,25 @@ DEFUN (show_ipv6_protocol_nht,         "Next Hop filtering status\n"         "Route-map\n")  { -    int i; - -    vty_out(vty, "Protocol    : route-map %s", VTY_NEWLINE); -    vty_out(vty, "------------------------%s", VTY_NEWLINE); -    for (i=0;i<ZEBRA_ROUTE_MAX;i++) -    { -        if (nht_rm[AFI_IP6][i]) -          vty_out (vty, "%-10s  : %-10s%s", zebra_route_string(i), -					nht_rm[AFI_IP6][i], -					VTY_NEWLINE); -        else -          vty_out (vty, "%-10s  : none%s", zebra_route_string(i), VTY_NEWLINE); -    } -    if (nht_rm[AFI_IP][i]) -      vty_out (vty, "%-10s  : %-10s%s", "any", nht_rm[AFI_IP6][i], -					VTY_NEWLINE); -    else -      vty_out (vty, "%-10s  : none%s", "any", VTY_NEWLINE); +	int i; + +	vty_out(vty, "Protocol    : route-map %s", VTY_NEWLINE); +	vty_out(vty, "------------------------%s", VTY_NEWLINE); +	for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { +		if (nht_rm[AFI_IP6][i]) +			vty_out(vty, "%-10s  : %-10s%s", zebra_route_string(i), +				nht_rm[AFI_IP6][i], VTY_NEWLINE); +		else +			vty_out(vty, "%-10s  : none%s", zebra_route_string(i), +				VTY_NEWLINE); +	} +	if (nht_rm[AFI_IP][i]) +		vty_out(vty, "%-10s  : %-10s%s", "any", nht_rm[AFI_IP6][i], +			VTY_NEWLINE); +	else +		vty_out(vty, "%-10s  : none%s", "any", VTY_NEWLINE); -    return CMD_SUCCESS; +	return CMD_SUCCESS;  }  /*XXXXXXXXXXXXXXXXXXXXXXXXXXXX*/ @@ -864,679 +835,635 @@ DEFUN (show_ipv6_protocol_nht,  /* `match ip next-hop IP_ACCESS_LIST' */  /* Match function return 1 if match is success else return zero. */ -static route_map_result_t -route_match_ip_next_hop (void *rule, struct prefix *prefix, -			route_map_object_t type, void *object) -{ -  struct access_list *alist; -  struct nh_rmap_obj *nh_data; -  struct prefix_ipv4 p; - -  if (type == RMAP_ZEBRA) -    { -      nh_data = object; -      if (!nh_data) -	return RMAP_DENYMATCH; - -      switch (nh_data->nexthop->type) { -      case NEXTHOP_TYPE_IFINDEX: -        /* Interface routes can't match ip next-hop */ -        return RMAP_NOMATCH; -      case NEXTHOP_TYPE_IPV4_IFINDEX: -      case NEXTHOP_TYPE_IPV4: -        p.family = AF_INET; -        p.prefix = nh_data->nexthop->gate.ipv4; -        p.prefixlen = IPV4_MAX_BITLEN; -        break; -      default: -        return RMAP_NOMATCH; -      } -      alist = access_list_lookup (AFI_IP, (char *) rule); -      if (alist == NULL) +static route_map_result_t route_match_ip_next_hop(void *rule, +						  struct prefix *prefix, +						  route_map_object_t type, +						  void *object) +{ +	struct access_list *alist; +	struct nh_rmap_obj *nh_data; +	struct prefix_ipv4 p; + +	if (type == RMAP_ZEBRA) { +		nh_data = object; +		if (!nh_data) +			return RMAP_DENYMATCH; + +		switch (nh_data->nexthop->type) { +		case NEXTHOP_TYPE_IFINDEX: +			/* Interface routes can't match ip next-hop */ +			return RMAP_NOMATCH; +		case NEXTHOP_TYPE_IPV4_IFINDEX: +		case NEXTHOP_TYPE_IPV4: +			p.family = AF_INET; +			p.prefix = nh_data->nexthop->gate.ipv4; +			p.prefixlen = IPV4_MAX_BITLEN; +			break; +		default: +			return RMAP_NOMATCH; +		} +		alist = access_list_lookup(AFI_IP, (char *)rule); +		if (alist == NULL) +			return RMAP_NOMATCH; + +		return (access_list_apply(alist, &p) == FILTER_DENY +				? RMAP_NOMATCH +				: RMAP_MATCH); +	}  	return RMAP_NOMATCH; - -      return (access_list_apply (alist, &p) == FILTER_DENY ? -	      RMAP_NOMATCH : RMAP_MATCH); -    } -  return RMAP_NOMATCH;  }  /* Route map `ip next-hop' match statement.  `arg' should be     access-list name. */ -static void * -route_match_ip_next_hop_compile (const char *arg) +static void *route_match_ip_next_hop_compile(const char *arg)  { -  return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); +	return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);  }  /* Free route map's compiled `. */ -static void -route_match_ip_next_hop_free (void *rule) +static void route_match_ip_next_hop_free(void *rule)  { -  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); +	XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);  }  /* Route map commands for ip next-hop matching. */ -static struct route_map_rule_cmd route_match_ip_next_hop_cmd = -{ -  "ip next-hop", -  route_match_ip_next_hop, -  route_match_ip_next_hop_compile, -  route_match_ip_next_hop_free -}; +static struct route_map_rule_cmd route_match_ip_next_hop_cmd = { +	"ip next-hop", route_match_ip_next_hop, route_match_ip_next_hop_compile, +	route_match_ip_next_hop_free};  /* `match ip next-hop prefix-list PREFIX_LIST' */  static route_map_result_t -route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix, -                                    route_map_object_t type, void *object) +route_match_ip_next_hop_prefix_list(void *rule, struct prefix *prefix, +				    route_map_object_t type, void *object)  { -  struct prefix_list *plist; -  struct nh_rmap_obj *nh_data; -  struct prefix_ipv4 p; - -  if (type == RMAP_ZEBRA) -    { -      nh_data = (struct nh_rmap_obj *)object; -      if (!nh_data) -	return RMAP_DENYMATCH; - -      switch (nh_data->nexthop->type) { -      case NEXTHOP_TYPE_IFINDEX: -        /* Interface routes can't match ip next-hop */ -        return RMAP_NOMATCH; -      case NEXTHOP_TYPE_IPV4_IFINDEX: -      case NEXTHOP_TYPE_IPV4: -        p.family = AF_INET; -        p.prefix = nh_data->nexthop->gate.ipv4; -        p.prefixlen = IPV4_MAX_BITLEN; -        break; -      default: -        return RMAP_NOMATCH; -      } -      plist = prefix_list_lookup (AFI_IP, (char *) rule); -      if (plist == NULL) -        return RMAP_NOMATCH; - -      return (prefix_list_apply (plist, &p) == PREFIX_DENY ? -              RMAP_NOMATCH : RMAP_MATCH); -    } -  return RMAP_NOMATCH; +	struct prefix_list *plist; +	struct nh_rmap_obj *nh_data; +	struct prefix_ipv4 p; + +	if (type == RMAP_ZEBRA) { +		nh_data = (struct nh_rmap_obj *)object; +		if (!nh_data) +			return RMAP_DENYMATCH; + +		switch (nh_data->nexthop->type) { +		case NEXTHOP_TYPE_IFINDEX: +			/* Interface routes can't match ip next-hop */ +			return RMAP_NOMATCH; +		case NEXTHOP_TYPE_IPV4_IFINDEX: +		case NEXTHOP_TYPE_IPV4: +			p.family = AF_INET; +			p.prefix = nh_data->nexthop->gate.ipv4; +			p.prefixlen = IPV4_MAX_BITLEN; +			break; +		default: +			return RMAP_NOMATCH; +		} +		plist = prefix_list_lookup(AFI_IP, (char *)rule); +		if (plist == NULL) +			return RMAP_NOMATCH; + +		return (prefix_list_apply(plist, &p) == PREFIX_DENY +				? RMAP_NOMATCH +				: RMAP_MATCH); +	} +	return RMAP_NOMATCH;  } -static void * -route_match_ip_next_hop_prefix_list_compile (const char *arg) +static void *route_match_ip_next_hop_prefix_list_compile(const char *arg)  { -  return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); +	return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);  } -static void -route_match_ip_next_hop_prefix_list_free (void *rule) +static void route_match_ip_next_hop_prefix_list_free(void *rule)  { -  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); +	XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);  } -static struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd = -{ -  "ip next-hop prefix-list", -  route_match_ip_next_hop_prefix_list, -  route_match_ip_next_hop_prefix_list_compile, -  route_match_ip_next_hop_prefix_list_free -}; +static struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd = { +	"ip next-hop prefix-list", route_match_ip_next_hop_prefix_list, +	route_match_ip_next_hop_prefix_list_compile, +	route_match_ip_next_hop_prefix_list_free};  /* `match ip address IP_ACCESS_LIST' */  /* Match function should return 1 if match is success else return     zero. */ -static route_map_result_t -route_match_ip_address (void *rule, struct prefix *prefix,  -			route_map_object_t type, void *object) +static route_map_result_t route_match_ip_address(void *rule, +						 struct prefix *prefix, +						 route_map_object_t type, +						 void *object)  { -  struct access_list *alist; +	struct access_list *alist; -  if (type == RMAP_ZEBRA) -    { -      alist = access_list_lookup (AFI_IP, (char *) rule); -      if (alist == NULL) +	if (type == RMAP_ZEBRA) { +		alist = access_list_lookup(AFI_IP, (char *)rule); +		if (alist == NULL) +			return RMAP_NOMATCH; + +		return (access_list_apply(alist, prefix) == FILTER_DENY +				? RMAP_NOMATCH +				: RMAP_MATCH); +	}  	return RMAP_NOMATCH; -     -      return (access_list_apply (alist, prefix) == FILTER_DENY ? -	      RMAP_NOMATCH : RMAP_MATCH); -    } -  return RMAP_NOMATCH;  }  /* Route map `ip address' match statement.  `arg' should be     access-list name. */ -static void * -route_match_ip_address_compile (const char *arg) +static void *route_match_ip_address_compile(const char *arg)  { -  return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); +	return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);  }  /* Free route map's compiled `ip address' value. */ -static void -route_match_ip_address_free (void *rule) +static void route_match_ip_address_free(void *rule)  { -  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); +	XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);  }  /* Route map commands for ip address matching. */ -static struct route_map_rule_cmd route_match_ip_address_cmd = -{ -  "ip address", -  route_match_ip_address, -  route_match_ip_address_compile, -  route_match_ip_address_free -}; +static struct route_map_rule_cmd route_match_ip_address_cmd = { +	"ip address", route_match_ip_address, route_match_ip_address_compile, +	route_match_ip_address_free};  /* `match ip address prefix-list PREFIX_LIST' */  static route_map_result_t -route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,  -				    route_map_object_t type, void *object) +route_match_ip_address_prefix_list(void *rule, struct prefix *prefix, +				   route_map_object_t type, void *object)  { -  struct prefix_list *plist; +	struct prefix_list *plist; -  if (type == RMAP_ZEBRA) -    { -      plist = prefix_list_lookup (AFI_IP, (char *) rule); -      if (plist == NULL) +	if (type == RMAP_ZEBRA) { +		plist = prefix_list_lookup(AFI_IP, (char *)rule); +		if (plist == NULL) +			return RMAP_NOMATCH; + +		return (prefix_list_apply(plist, prefix) == PREFIX_DENY +				? RMAP_NOMATCH +				: RMAP_MATCH); +	}  	return RMAP_NOMATCH; -     -      return (prefix_list_apply (plist, prefix) == PREFIX_DENY ? -	      RMAP_NOMATCH : RMAP_MATCH); -    } -  return RMAP_NOMATCH;  } -static void * -route_match_ip_address_prefix_list_compile (const char *arg) +static void *route_match_ip_address_prefix_list_compile(const char *arg)  { -  return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); +	return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);  } -static void -route_match_ip_address_prefix_list_free (void *rule) +static void route_match_ip_address_prefix_list_free(void *rule)  { -  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); +	XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);  } -static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd = -{ -  "ip address prefix-list", -  route_match_ip_address_prefix_list, -  route_match_ip_address_prefix_list_compile, -  route_match_ip_address_prefix_list_free -}; +static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd = { +	"ip address prefix-list", route_match_ip_address_prefix_list, +	route_match_ip_address_prefix_list_compile, +	route_match_ip_address_prefix_list_free};  /* `match ip address prefix-len PREFIXLEN' */  static route_map_result_t -route_match_ip_address_prefix_len (void *rule, struct prefix *prefix, -				    route_map_object_t type, void *object) +route_match_ip_address_prefix_len(void *rule, struct prefix *prefix, +				  route_map_object_t type, void *object)  { -  u_int32_t *prefixlen = (u_int32_t *)rule; +	u_int32_t *prefixlen = (u_int32_t *)rule; -  if (type == RMAP_ZEBRA) -    { -      return ((prefix->prefixlen == *prefixlen) ? RMAP_MATCH : RMAP_NOMATCH); -    } -  return RMAP_NOMATCH; +	if (type == RMAP_ZEBRA) { +		return ((prefix->prefixlen == *prefixlen) ? RMAP_MATCH +							  : RMAP_NOMATCH); +	} +	return RMAP_NOMATCH;  } -static void * -route_match_ip_address_prefix_len_compile (const char *arg) +static void *route_match_ip_address_prefix_len_compile(const char *arg)  { -  u_int32_t *prefix_len; -  char *endptr = NULL; -  unsigned long tmpval; +	u_int32_t *prefix_len; +	char *endptr = NULL; +	unsigned long tmpval; -  /* prefix len value shoud be integer. */ -  if (! all_digit (arg)) -    return NULL; +	/* prefix len value shoud be integer. */ +	if (!all_digit(arg)) +		return NULL; -  errno = 0; -  tmpval = strtoul (arg, &endptr, 10); -  if (*endptr != '\0' || errno || tmpval > UINT32_MAX) -    return NULL; +	errno = 0; +	tmpval = strtoul(arg, &endptr, 10); +	if (*endptr != '\0' || errno || tmpval > UINT32_MAX) +		return NULL; -  prefix_len = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t)); +	prefix_len = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(u_int32_t)); -  if (!prefix_len) -    return prefix_len; +	if (!prefix_len) +		return prefix_len; -  *prefix_len = tmpval; -  return prefix_len; +	*prefix_len = tmpval; +	return prefix_len;  } -static void -route_match_ip_address_prefix_len_free (void *rule) +static void route_match_ip_address_prefix_len_free(void *rule)  { -  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); +	XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);  } -static struct route_map_rule_cmd route_match_ip_address_prefix_len_cmd = -{ -  "ip address prefix-len", -  route_match_ip_address_prefix_len, -  route_match_ip_address_prefix_len_compile, -  route_match_ip_address_prefix_len_free -}; +static struct route_map_rule_cmd route_match_ip_address_prefix_len_cmd = { +	"ip address prefix-len", route_match_ip_address_prefix_len, +	route_match_ip_address_prefix_len_compile, +	route_match_ip_address_prefix_len_free};  /* `match ip nexthop prefix-len PREFIXLEN' */  static route_map_result_t -route_match_ip_nexthop_prefix_len (void *rule, struct prefix *prefix, -				   route_map_object_t type, void *object) -{ -  u_int32_t *prefixlen = (u_int32_t *)rule; -  struct nh_rmap_obj *nh_data; -  struct prefix_ipv4 p; - -  if (type == RMAP_ZEBRA) -    { -      nh_data = (struct nh_rmap_obj *)object; -      if (!nh_data || !nh_data->nexthop) -	return RMAP_DENYMATCH; - -      switch (nh_data->nexthop->type) { -      case NEXTHOP_TYPE_IFINDEX: -        /* Interface routes can't match ip next-hop */ -        return RMAP_NOMATCH; -      case NEXTHOP_TYPE_IPV4_IFINDEX: -      case NEXTHOP_TYPE_IPV4: -        p.family = AF_INET; -        p.prefix = nh_data->nexthop->gate.ipv4; -        p.prefixlen = IPV4_MAX_BITLEN; -        break; -      default: -        return RMAP_NOMATCH; -      } -      return ((p.prefixlen == *prefixlen) ? RMAP_MATCH : RMAP_NOMATCH); -    } -  return RMAP_NOMATCH; -} - -static struct route_map_rule_cmd route_match_ip_nexthop_prefix_len_cmd = -{ -  "ip next-hop prefix-len", -  route_match_ip_nexthop_prefix_len, -  route_match_ip_address_prefix_len_compile, /* reuse */ -  route_match_ip_address_prefix_len_free     /* reuse */ +route_match_ip_nexthop_prefix_len(void *rule, struct prefix *prefix, +				  route_map_object_t type, void *object) +{ +	u_int32_t *prefixlen = (u_int32_t *)rule; +	struct nh_rmap_obj *nh_data; +	struct prefix_ipv4 p; + +	if (type == RMAP_ZEBRA) { +		nh_data = (struct nh_rmap_obj *)object; +		if (!nh_data || !nh_data->nexthop) +			return RMAP_DENYMATCH; + +		switch (nh_data->nexthop->type) { +		case NEXTHOP_TYPE_IFINDEX: +			/* Interface routes can't match ip next-hop */ +			return RMAP_NOMATCH; +		case NEXTHOP_TYPE_IPV4_IFINDEX: +		case NEXTHOP_TYPE_IPV4: +			p.family = AF_INET; +			p.prefix = nh_data->nexthop->gate.ipv4; +			p.prefixlen = IPV4_MAX_BITLEN; +			break; +		default: +			return RMAP_NOMATCH; +		} +		return ((p.prefixlen == *prefixlen) ? RMAP_MATCH +						    : RMAP_NOMATCH); +	} +	return RMAP_NOMATCH; +} + +static struct route_map_rule_cmd route_match_ip_nexthop_prefix_len_cmd = { +	"ip next-hop prefix-len", route_match_ip_nexthop_prefix_len, +	route_match_ip_address_prefix_len_compile, /* reuse */ +	route_match_ip_address_prefix_len_free     /* reuse */  };  /* `match source-protocol PROTOCOL' */ -static route_map_result_t -route_match_source_protocol (void *rule, struct prefix *prefix, -			     route_map_object_t type, void *object) +static route_map_result_t route_match_source_protocol(void *rule, +						      struct prefix *prefix, +						      route_map_object_t type, +						      void *object)  { -  u_int32_t *rib_type = (u_int32_t *)rule; -  struct nh_rmap_obj *nh_data; +	u_int32_t *rib_type = (u_int32_t *)rule; +	struct nh_rmap_obj *nh_data; -  if (type == RMAP_ZEBRA) -    { -      nh_data = (struct nh_rmap_obj *)object; -      if (!nh_data) -	return RMAP_DENYMATCH; +	if (type == RMAP_ZEBRA) { +		nh_data = (struct nh_rmap_obj *)object; +		if (!nh_data) +			return RMAP_DENYMATCH; -      return ((nh_data->source_protocol == *rib_type) -	      ? RMAP_MATCH : RMAP_NOMATCH); -    } -  return RMAP_NOMATCH; +		return ((nh_data->source_protocol == *rib_type) ? RMAP_MATCH +								: RMAP_NOMATCH); +	} +	return RMAP_NOMATCH;  } -static void * -route_match_source_protocol_compile (const char *arg) +static void *route_match_source_protocol_compile(const char *arg)  { -  u_int32_t *rib_type; -  int i; +	u_int32_t *rib_type; +	int i; -  i = proto_name2num(arg); -  rib_type = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t)); +	i = proto_name2num(arg); +	rib_type = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(u_int32_t)); -  *rib_type = i; +	*rib_type = i; -  return rib_type; +	return rib_type;  } -static void -route_match_source_protocol_free (void *rule) +static void route_match_source_protocol_free(void *rule)  { -  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); +	XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);  } -static struct route_map_rule_cmd route_match_source_protocol_cmd = -{ -  "source-protocol", -  route_match_source_protocol, -  route_match_source_protocol_compile, -  route_match_source_protocol_free -}; +static struct route_map_rule_cmd route_match_source_protocol_cmd = { +	"source-protocol", route_match_source_protocol, +	route_match_source_protocol_compile, route_match_source_protocol_free};  /* `set src A.B.C.D' */  /* Set src. */ -static route_map_result_t -route_set_src (void *rule, struct prefix *prefix,  -		  route_map_object_t type, void *object) +static route_map_result_t route_set_src(void *rule, struct prefix *prefix, +					route_map_object_t type, void *object)  { -  struct nh_rmap_obj *nh_data; +	struct nh_rmap_obj *nh_data; -  if (type == RMAP_ZEBRA) -    { -      nh_data = (struct nh_rmap_obj *)object; -      nh_data->nexthop->rmap_src = *(union g_addr *)rule; -    } -  return RMAP_OKAY; +	if (type == RMAP_ZEBRA) { +		nh_data = (struct nh_rmap_obj *)object; +		nh_data->nexthop->rmap_src = *(union g_addr *)rule; +	} +	return RMAP_OKAY;  }  /* set src compilation. */ -static void * -route_set_src_compile (const char *arg) +static void *route_set_src_compile(const char *arg)  { -  union g_addr src, *psrc; +	union g_addr src, *psrc; -  if ((inet_pton(AF_INET6, arg, &src.ipv6) == 1) || -      (src.ipv4.s_addr && (inet_pton(AF_INET, arg, &src.ipv4) == 1))) -    { -      psrc = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union g_addr)); -      *psrc = src; -      return psrc; -    } -  return NULL; +	if ((inet_pton(AF_INET6, arg, &src.ipv6) == 1) +	    || (src.ipv4.s_addr && (inet_pton(AF_INET, arg, &src.ipv4) == 1))) { +		psrc = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(union g_addr)); +		*psrc = src; +		return psrc; +	} +	return NULL;  }  /* Free route map's compiled `set src' value. */ -static void -route_set_src_free (void *rule) +static void route_set_src_free(void *rule)  { -  XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); +	XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);  }  /* Set src rule structure. */ -static struct route_map_rule_cmd route_set_src_cmd =  -{ -  "src", -  route_set_src, -  route_set_src_compile, -  route_set_src_free, +static struct route_map_rule_cmd route_set_src_cmd = { +	"src", route_set_src, route_set_src_compile, route_set_src_free,  }; -static int -zebra_route_map_update_timer (struct thread *thread) +static int zebra_route_map_update_timer(struct thread *thread)  { -  zebra_t_rmap_update = NULL; +	zebra_t_rmap_update = NULL; -  if (IS_ZEBRA_DEBUG_EVENT) -    zlog_debug("Event driven route-map update triggered"); +	if (IS_ZEBRA_DEBUG_EVENT) +		zlog_debug("Event driven route-map update triggered"); -  if (IS_ZEBRA_DEBUG_RIB_DETAILED) -    zlog_debug ("%u: Routemap update-timer fired, scheduling RIB processing", -                VRF_DEFAULT); +	if (IS_ZEBRA_DEBUG_RIB_DETAILED) +		zlog_debug( +			"%u: Routemap update-timer fired, scheduling RIB processing", +			VRF_DEFAULT); -  zebra_import_table_rm_update (); -  rib_update(VRF_DEFAULT, RIB_UPDATE_RMAP_CHANGE); -  zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL); -  zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL); +	zebra_import_table_rm_update(); +	rib_update(VRF_DEFAULT, RIB_UPDATE_RMAP_CHANGE); +	zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL); +	zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL); -  return (0); +	return (0);  } -static void -zebra_route_map_set_delay_timer(u_int32_t value) +static void zebra_route_map_set_delay_timer(u_int32_t value)  { -  zebra_rmap_update_timer = value; -  if (!value && zebra_t_rmap_update) -    { -      /* Event driven route map updates is being disabled */ -      /* But there's a pending timer. Fire it off now */ -      thread_cancel(zebra_t_rmap_update); -      zebra_route_map_update_timer(zebra_t_rmap_update); -    } +	zebra_rmap_update_timer = value; +	if (!value && zebra_t_rmap_update) { +		/* Event driven route map updates is being disabled */ +		/* But there's a pending timer. Fire it off now */ +		thread_cancel(zebra_t_rmap_update); +		zebra_route_map_update_timer(zebra_t_rmap_update); +	}  } -void -zebra_route_map_write_delay_timer (struct vty *vty) +void zebra_route_map_write_delay_timer(struct vty *vty)  { -  if (vty && (zebra_rmap_update_timer != ZEBRA_RMAP_DEFAULT_UPDATE_TIMER)) -    vty_out (vty, "zebra route-map delay-timer %d%s", zebra_rmap_update_timer, -	     VTY_NEWLINE); -  return; +	if (vty && (zebra_rmap_update_timer != ZEBRA_RMAP_DEFAULT_UPDATE_TIMER)) +		vty_out(vty, "zebra route-map delay-timer %d%s", +			zebra_rmap_update_timer, VTY_NEWLINE); +	return;  } -route_map_result_t -zebra_route_map_check (int family, int rib_type, struct prefix *p, -		       struct nexthop *nexthop, vrf_id_t vrf_id, route_tag_t tag) +route_map_result_t zebra_route_map_check(int family, int rib_type, +					 struct prefix *p, +					 struct nexthop *nexthop, +					 vrf_id_t vrf_id, route_tag_t tag)  { -  struct route_map *rmap = NULL; -  route_map_result_t ret = RMAP_MATCH; -  struct nh_rmap_obj nh_obj; +	struct route_map *rmap = NULL; +	route_map_result_t ret = RMAP_MATCH; +	struct nh_rmap_obj nh_obj; -  nh_obj.nexthop = nexthop; -  nh_obj.vrf_id = vrf_id; -  nh_obj.source_protocol = rib_type; -  nh_obj.metric = 0; -  nh_obj.tag = tag; +	nh_obj.nexthop = nexthop; +	nh_obj.vrf_id = vrf_id; +	nh_obj.source_protocol = rib_type; +	nh_obj.metric = 0; +	nh_obj.tag = tag; -  if (rib_type >= 0 && rib_type < ZEBRA_ROUTE_MAX) -    rmap = route_map_lookup_by_name (proto_rm[family][rib_type]); -  if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX]) -    rmap = route_map_lookup_by_name (proto_rm[family][ZEBRA_ROUTE_MAX]); -  if (rmap) { -      ret = route_map_apply(rmap, p, RMAP_ZEBRA, &nh_obj); -  } +	if (rib_type >= 0 && rib_type < ZEBRA_ROUTE_MAX) +		rmap = route_map_lookup_by_name(proto_rm[family][rib_type]); +	if (!rmap && proto_rm[family][ZEBRA_ROUTE_MAX]) +		rmap = route_map_lookup_by_name( +			proto_rm[family][ZEBRA_ROUTE_MAX]); +	if (rmap) { +		ret = route_map_apply(rmap, p, RMAP_ZEBRA, &nh_obj); +	} -  return (ret); +	return (ret);  } -char * -zebra_get_import_table_route_map (afi_t afi, uint32_t table) +char *zebra_get_import_table_route_map(afi_t afi, uint32_t table)  { -  return zebra_import_table_routemap[afi][table]; +	return zebra_import_table_routemap[afi][table];  } -void -zebra_add_import_table_route_map (afi_t afi, const char *rmap_name, uint32_t table) +void zebra_add_import_table_route_map(afi_t afi, const char *rmap_name, +				      uint32_t table)  { -  zebra_import_table_routemap[afi][table] = XSTRDUP (MTYPE_ROUTE_MAP_NAME, rmap_name); +	zebra_import_table_routemap[afi][table] = +		XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);  } -void -zebra_del_import_table_route_map (afi_t afi, uint32_t table) +void zebra_del_import_table_route_map(afi_t afi, uint32_t table)  { -  XFREE (MTYPE_ROUTE_MAP_NAME, zebra_import_table_routemap[afi][table]); +	XFREE(MTYPE_ROUTE_MAP_NAME, zebra_import_table_routemap[afi][table]);  }  route_map_result_t -zebra_import_table_route_map_check (int family, int rib_type, struct prefix *p, -                struct nexthop *nexthop, vrf_id_t vrf_id, route_tag_t tag, const char *rmap_name) -{ -  struct route_map *rmap = NULL; -  route_map_result_t ret = RMAP_DENYMATCH; -  struct nh_rmap_obj nh_obj; - -  nh_obj.nexthop = nexthop; -  nh_obj.vrf_id = vrf_id; -  nh_obj.source_protocol = rib_type; -  nh_obj.metric = 0; -  nh_obj.tag = tag; - -  if (rib_type >= 0 && rib_type < ZEBRA_ROUTE_MAX) -    rmap = route_map_lookup_by_name (rmap_name); -  if (rmap) { -      ret = route_map_apply(rmap, p, RMAP_ZEBRA, &nh_obj); -  } +zebra_import_table_route_map_check(int family, int rib_type, struct prefix *p, +				   struct nexthop *nexthop, vrf_id_t vrf_id, +				   route_tag_t tag, const char *rmap_name) +{ +	struct route_map *rmap = NULL; +	route_map_result_t ret = RMAP_DENYMATCH; +	struct nh_rmap_obj nh_obj; + +	nh_obj.nexthop = nexthop; +	nh_obj.vrf_id = vrf_id; +	nh_obj.source_protocol = rib_type; +	nh_obj.metric = 0; +	nh_obj.tag = tag; + +	if (rib_type >= 0 && rib_type < ZEBRA_ROUTE_MAX) +		rmap = route_map_lookup_by_name(rmap_name); +	if (rmap) { +		ret = route_map_apply(rmap, p, RMAP_ZEBRA, &nh_obj); +	} -  return (ret); +	return (ret);  } -route_map_result_t -zebra_nht_route_map_check (int family, int client_proto, struct prefix *p, -			   struct rib * rib, struct nexthop *nexthop) +route_map_result_t zebra_nht_route_map_check(int family, int client_proto, +					     struct prefix *p, struct rib *rib, +					     struct nexthop *nexthop)  { -  struct route_map *rmap = NULL; -  route_map_result_t ret = RMAP_MATCH; -  struct nh_rmap_obj nh_obj; +	struct route_map *rmap = NULL; +	route_map_result_t ret = RMAP_MATCH; +	struct nh_rmap_obj nh_obj; -  nh_obj.nexthop = nexthop; -  nh_obj.vrf_id = rib->vrf_id; -  nh_obj.source_protocol = rib->type; -  nh_obj.metric = rib->metric; -  nh_obj.tag = rib->tag; +	nh_obj.nexthop = nexthop; +	nh_obj.vrf_id = rib->vrf_id; +	nh_obj.source_protocol = rib->type; +	nh_obj.metric = rib->metric; +	nh_obj.tag = rib->tag; -  if (client_proto >= 0 && client_proto < ZEBRA_ROUTE_MAX) -    rmap = route_map_lookup_by_name (nht_rm[family][client_proto]); -  if (!rmap && nht_rm[family][ZEBRA_ROUTE_MAX]) -    rmap = route_map_lookup_by_name (nht_rm[family][ZEBRA_ROUTE_MAX]); -  if (rmap) { -      ret = route_map_apply(rmap, p, RMAP_ZEBRA, &nh_obj); -  } +	if (client_proto >= 0 && client_proto < ZEBRA_ROUTE_MAX) +		rmap = route_map_lookup_by_name(nht_rm[family][client_proto]); +	if (!rmap && nht_rm[family][ZEBRA_ROUTE_MAX]) +		rmap = route_map_lookup_by_name( +			nht_rm[family][ZEBRA_ROUTE_MAX]); +	if (rmap) { +		ret = route_map_apply(rmap, p, RMAP_ZEBRA, &nh_obj); +	} -  return (ret); +	return (ret);  } -static void -zebra_route_map_mark_update (const char *rmap_name) +static void zebra_route_map_mark_update(const char *rmap_name)  { -  /* rmap_update_timer of 0 means don't do route updates */ -  if (zebra_rmap_update_timer && !zebra_t_rmap_update) -    zebra_t_rmap_update = -      thread_add_timer(zebrad.master, zebra_route_map_update_timer, NULL, -		       zebra_rmap_update_timer); +	/* rmap_update_timer of 0 means don't do route updates */ +	if (zebra_rmap_update_timer && !zebra_t_rmap_update) +		zebra_t_rmap_update = thread_add_timer( +			zebrad.master, zebra_route_map_update_timer, NULL, +			zebra_rmap_update_timer);  } -static void -zebra_route_map_add (const char *rmap_name) +static void zebra_route_map_add(const char *rmap_name)  { -  zebra_route_map_mark_update(rmap_name); -  route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_ADDED); +	zebra_route_map_mark_update(rmap_name); +	route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_ADDED);  } -static void -zebra_route_map_delete (const char *rmap_name) +static void zebra_route_map_delete(const char *rmap_name)  { -  zebra_route_map_mark_update(rmap_name); -  route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_DELETED); +	zebra_route_map_mark_update(rmap_name); +	route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_DELETED);  } -static void -zebra_route_map_event (route_map_event_t event, const char *rmap_name) +static void zebra_route_map_event(route_map_event_t event, +				  const char *rmap_name)  { -  zebra_route_map_mark_update(rmap_name); -  route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_ADDED); +	zebra_route_map_mark_update(rmap_name); +	route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_ADDED);  }  /* ip protocol configuration write function */ -void -zebra_routemap_config_write_protocol (struct vty *vty) -{ -  int i; - -  for (i=0;i<ZEBRA_ROUTE_MAX;i++) -    { -      if (proto_rm[AFI_IP][i]) -        vty_out (vty, "ip protocol %s route-map %s%s", zebra_route_string(i), -                 proto_rm[AFI_IP][i], VTY_NEWLINE); - -      if (proto_rm[AFI_IP6][i]) -        vty_out (vty, "ipv6 protocol %s route-map %s%s", zebra_route_string(i), -                 proto_rm[AFI_IP6][i], VTY_NEWLINE); - -      if (nht_rm[AFI_IP][i]) -        vty_out (vty, "ip nht %s route-map %s%s", zebra_route_string(i), -                 nht_rm[AFI_IP][i], VTY_NEWLINE); - -      if (nht_rm[AFI_IP6][i]) -        vty_out (vty, "ipv6 nht %s route-map %s%s", zebra_route_string(i), -                 nht_rm[AFI_IP6][i], VTY_NEWLINE); -    } - -  if (proto_rm[AFI_IP][ZEBRA_ROUTE_MAX]) -      vty_out (vty, "ip protocol %s route-map %s%s", "any", -               proto_rm[AFI_IP][ZEBRA_ROUTE_MAX], VTY_NEWLINE); - -  if (proto_rm[AFI_IP6][ZEBRA_ROUTE_MAX]) -      vty_out (vty, "ipv6 protocol %s route-map %s%s", "any", -               proto_rm[AFI_IP6][ZEBRA_ROUTE_MAX], VTY_NEWLINE); - -  if (nht_rm[AFI_IP][ZEBRA_ROUTE_MAX]) -      vty_out (vty, "ip nht %s route-map %s%s", "any", -               nht_rm[AFI_IP][ZEBRA_ROUTE_MAX], VTY_NEWLINE); - -  if (nht_rm[AFI_IP6][ZEBRA_ROUTE_MAX]) -      vty_out (vty, "ipv6 nht %s route-map %s%s", "any", -               nht_rm[AFI_IP6][ZEBRA_ROUTE_MAX], VTY_NEWLINE); - -  if (zebra_rmap_update_timer != ZEBRA_RMAP_DEFAULT_UPDATE_TIMER) -    vty_out (vty, "zebra route-map delay-timer %d%s", zebra_rmap_update_timer, -	     VTY_NEWLINE); -} - -void -zebra_route_map_init () -{ -  install_element (CONFIG_NODE, &ip_protocol_cmd); -  install_element (CONFIG_NODE, &no_ip_protocol_cmd); -  install_element (VIEW_NODE, &show_ip_protocol_cmd); -  install_element (CONFIG_NODE, &ipv6_protocol_cmd); -  install_element (CONFIG_NODE, &no_ipv6_protocol_cmd); -  install_element (VIEW_NODE, &show_ipv6_protocol_cmd); -  install_element (CONFIG_NODE, &ip_protocol_nht_rmap_cmd); -  install_element (CONFIG_NODE, &no_ip_protocol_nht_rmap_cmd); -  install_element (VIEW_NODE, &show_ip_protocol_nht_cmd); -  install_element (CONFIG_NODE, &ipv6_protocol_nht_rmap_cmd); -  install_element (CONFIG_NODE, &no_ipv6_protocol_nht_rmap_cmd); -  install_element (VIEW_NODE, &show_ipv6_protocol_nht_cmd); -  install_element (CONFIG_NODE, &zebra_route_map_timer_cmd); -  install_element (CONFIG_NODE, &no_zebra_route_map_timer_cmd); - -  route_map_init (); - -  route_map_add_hook (zebra_route_map_add); -  route_map_delete_hook (zebra_route_map_delete); -  route_map_event_hook (zebra_route_map_event); - -  route_map_match_interface_hook (generic_match_add); -  route_map_no_match_interface_hook (generic_match_delete); - -  route_map_match_ip_address_hook (generic_match_add); -  route_map_no_match_ip_address_hook (generic_match_delete); - -  route_map_match_ip_address_prefix_list_hook (generic_match_add); -  route_map_no_match_ip_address_prefix_list_hook (generic_match_delete); - -  route_map_match_ip_next_hop_hook (generic_match_add); -  route_map_no_match_ip_next_hop_hook (generic_match_delete); - -  route_map_match_ip_next_hop_prefix_list_hook (generic_match_add); -  route_map_no_match_ip_next_hop_prefix_list_hook (generic_match_delete); - -  route_map_match_tag_hook (generic_match_add); -  route_map_no_match_tag_hook (generic_match_delete); - -  route_map_install_match (&route_match_tag_cmd); -  route_map_install_match (&route_match_interface_cmd); -  route_map_install_match (&route_match_ip_next_hop_cmd); -  route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd); -  route_map_install_match (&route_match_ip_address_cmd); -  route_map_install_match (&route_match_ip_address_prefix_list_cmd); -  route_map_install_match (&route_match_ip_address_prefix_len_cmd); -  route_map_install_match (&route_match_ip_nexthop_prefix_len_cmd); -  route_map_install_match (&route_match_source_protocol_cmd); -/* */ -  route_map_install_set (&route_set_src_cmd); -/* */ -  install_element (RMAP_NODE, &match_ip_nexthop_prefix_len_cmd); -  install_element (RMAP_NODE, &no_match_ip_nexthop_prefix_len_cmd); -  install_element (RMAP_NODE, &match_ip_address_prefix_len_cmd); -  install_element (RMAP_NODE, &no_match_ip_address_prefix_len_cmd); -  install_element (RMAP_NODE, &match_source_protocol_cmd); -  install_element (RMAP_NODE, &no_match_source_protocol_cmd); - /* */ -  install_element (RMAP_NODE, &set_src_cmd); -  install_element (RMAP_NODE, &no_set_src_cmd); +void zebra_routemap_config_write_protocol(struct vty *vty) +{ +	int i; + +	for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { +		if (proto_rm[AFI_IP][i]) +			vty_out(vty, "ip protocol %s route-map %s%s", +				zebra_route_string(i), proto_rm[AFI_IP][i], +				VTY_NEWLINE); + +		if (proto_rm[AFI_IP6][i]) +			vty_out(vty, "ipv6 protocol %s route-map %s%s", +				zebra_route_string(i), proto_rm[AFI_IP6][i], +				VTY_NEWLINE); + +		if (nht_rm[AFI_IP][i]) +			vty_out(vty, "ip nht %s route-map %s%s", +				zebra_route_string(i), nht_rm[AFI_IP][i], +				VTY_NEWLINE); + +		if (nht_rm[AFI_IP6][i]) +			vty_out(vty, "ipv6 nht %s route-map %s%s", +				zebra_route_string(i), nht_rm[AFI_IP6][i], +				VTY_NEWLINE); +	} + +	if (proto_rm[AFI_IP][ZEBRA_ROUTE_MAX]) +		vty_out(vty, "ip protocol %s route-map %s%s", "any", +			proto_rm[AFI_IP][ZEBRA_ROUTE_MAX], VTY_NEWLINE); + +	if (proto_rm[AFI_IP6][ZEBRA_ROUTE_MAX]) +		vty_out(vty, "ipv6 protocol %s route-map %s%s", "any", +			proto_rm[AFI_IP6][ZEBRA_ROUTE_MAX], VTY_NEWLINE); + +	if (nht_rm[AFI_IP][ZEBRA_ROUTE_MAX]) +		vty_out(vty, "ip nht %s route-map %s%s", "any", +			nht_rm[AFI_IP][ZEBRA_ROUTE_MAX], VTY_NEWLINE); + +	if (nht_rm[AFI_IP6][ZEBRA_ROUTE_MAX]) +		vty_out(vty, "ipv6 nht %s route-map %s%s", "any", +			nht_rm[AFI_IP6][ZEBRA_ROUTE_MAX], VTY_NEWLINE); + +	if (zebra_rmap_update_timer != ZEBRA_RMAP_DEFAULT_UPDATE_TIMER) +		vty_out(vty, "zebra route-map delay-timer %d%s", +			zebra_rmap_update_timer, VTY_NEWLINE); +} + +void zebra_route_map_init() +{ +	install_element(CONFIG_NODE, &ip_protocol_cmd); +	install_element(CONFIG_NODE, &no_ip_protocol_cmd); +	install_element(VIEW_NODE, &show_ip_protocol_cmd); +	install_element(CONFIG_NODE, &ipv6_protocol_cmd); +	install_element(CONFIG_NODE, &no_ipv6_protocol_cmd); +	install_element(VIEW_NODE, &show_ipv6_protocol_cmd); +	install_element(CONFIG_NODE, &ip_protocol_nht_rmap_cmd); +	install_element(CONFIG_NODE, &no_ip_protocol_nht_rmap_cmd); +	install_element(VIEW_NODE, &show_ip_protocol_nht_cmd); +	install_element(CONFIG_NODE, &ipv6_protocol_nht_rmap_cmd); +	install_element(CONFIG_NODE, &no_ipv6_protocol_nht_rmap_cmd); +	install_element(VIEW_NODE, &show_ipv6_protocol_nht_cmd); +	install_element(CONFIG_NODE, &zebra_route_map_timer_cmd); +	install_element(CONFIG_NODE, &no_zebra_route_map_timer_cmd); + +	route_map_init(); + +	route_map_add_hook(zebra_route_map_add); +	route_map_delete_hook(zebra_route_map_delete); +	route_map_event_hook(zebra_route_map_event); + +	route_map_match_interface_hook(generic_match_add); +	route_map_no_match_interface_hook(generic_match_delete); + +	route_map_match_ip_address_hook(generic_match_add); +	route_map_no_match_ip_address_hook(generic_match_delete); + +	route_map_match_ip_address_prefix_list_hook(generic_match_add); +	route_map_no_match_ip_address_prefix_list_hook(generic_match_delete); + +	route_map_match_ip_next_hop_hook(generic_match_add); +	route_map_no_match_ip_next_hop_hook(generic_match_delete); + +	route_map_match_ip_next_hop_prefix_list_hook(generic_match_add); +	route_map_no_match_ip_next_hop_prefix_list_hook(generic_match_delete); + +	route_map_match_tag_hook(generic_match_add); +	route_map_no_match_tag_hook(generic_match_delete); + +	route_map_install_match(&route_match_tag_cmd); +	route_map_install_match(&route_match_interface_cmd); +	route_map_install_match(&route_match_ip_next_hop_cmd); +	route_map_install_match(&route_match_ip_next_hop_prefix_list_cmd); +	route_map_install_match(&route_match_ip_address_cmd); +	route_map_install_match(&route_match_ip_address_prefix_list_cmd); +	route_map_install_match(&route_match_ip_address_prefix_len_cmd); +	route_map_install_match(&route_match_ip_nexthop_prefix_len_cmd); +	route_map_install_match(&route_match_source_protocol_cmd); +	/* */ +	route_map_install_set(&route_set_src_cmd); +	/* */ +	install_element(RMAP_NODE, &match_ip_nexthop_prefix_len_cmd); +	install_element(RMAP_NODE, &no_match_ip_nexthop_prefix_len_cmd); +	install_element(RMAP_NODE, &match_ip_address_prefix_len_cmd); +	install_element(RMAP_NODE, &no_match_ip_address_prefix_len_cmd); +	install_element(RMAP_NODE, &match_source_protocol_cmd); +	install_element(RMAP_NODE, &no_match_source_protocol_cmd); +	/* */ +	install_element(RMAP_NODE, &set_src_cmd); +	install_element(RMAP_NODE, &no_set_src_cmd);  } diff --git a/zebra/zebra_routemap.h b/zebra/zebra_routemap.h index bf418ccacc..99b1b631c6 100644 --- a/zebra/zebra_routemap.h +++ b/zebra/zebra_routemap.h @@ -24,28 +24,25 @@  #define __ZEBRA_ROUTEMAP_H__  extern void zebra_routemap_config_write_protocol(struct vty *vty); -extern char *zebra_get_import_table_route_map (afi_t afi, uint32_t table); -extern void zebra_add_import_table_route_map (afi_t afi, const char *rmap_name, uint32_t table); -extern void zebra_del_import_table_route_map (afi_t afi, uint32_t table); +extern char *zebra_get_import_table_route_map(afi_t afi, uint32_t table); +extern void zebra_add_import_table_route_map(afi_t afi, const char *rmap_name, +					     uint32_t table); +extern void zebra_del_import_table_route_map(afi_t afi, uint32_t table);  extern void zebra_route_map_write_delay_timer(struct vty *); -extern route_map_result_t zebra_import_table_route_map_check (int family, int rib_type, -						 struct prefix *p, -						 struct nexthop *nexthop, -                                                 vrf_id_t vrf_id, -                                                 route_tag_t tag, -                                                 const char *rmap_name); -extern route_map_result_t zebra_route_map_check (int family, int rib_type, -						 struct prefix *p, -						 struct nexthop *nexthop, -                                                 vrf_id_t vrf_id, -                                                 route_tag_t tag); -extern route_map_result_t zebra_nht_route_map_check (int family, -						     int client_proto, -						     struct prefix *p, -						     struct rib *, -						     struct nexthop *nexthop); +extern route_map_result_t +zebra_import_table_route_map_check(int family, int rib_type, struct prefix *p, +				   struct nexthop *nexthop, vrf_id_t vrf_id, +				   route_tag_t tag, const char *rmap_name); +extern route_map_result_t zebra_route_map_check(int family, int rib_type, +						struct prefix *p, +						struct nexthop *nexthop, +						vrf_id_t vrf_id, +						route_tag_t tag); +extern route_map_result_t +zebra_nht_route_map_check(int family, int client_proto, struct prefix *p, +			  struct rib *, struct nexthop *nexthop);  #endif diff --git a/zebra/zebra_snmp.c b/zebra/zebra_snmp.c index 8adb8873dc..2c59d2e07b 100644 --- a/zebra/zebra_snmp.c +++ b/zebra/zebra_snmp.c @@ -16,7 +16,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  /* @@ -87,510 +87,497 @@  #define IPADDRESS ASN_IPADDRESS  #define OBJECTIDENTIFIER ASN_OBJECT_ID -static oid ipfw_oid [] = { IPFWMIB }; +static oid ipfw_oid[] = {IPFWMIB};  /* Hook functions. */ -static u_char * ipFwNumber (struct variable *, oid [], size_t *, -		     int, size_t *, WriteMethod **); -static u_char * ipFwTable (struct variable *, oid [], size_t *, -			   int, size_t *, WriteMethod **); -static u_char * ipCidrNumber (struct variable *, oid [], size_t *, -			      int, size_t *, WriteMethod **); -static u_char * ipCidrTable (struct variable *, oid [], size_t *, -			     int, size_t *, WriteMethod **); - -static struct variable zebra_variables[] = -  { -    {0, GAUGE32, RONLY, ipFwNumber, 1, {1}}, -    {IPFORWARDDEST, IPADDRESS, RONLY, ipFwTable, 3, {2, 1, 1}}, -    {IPFORWARDMASK, IPADDRESS, RONLY, ipFwTable, 3, {2, 1, 2}}, -    {IPFORWARDPOLICY, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 3}}, -    {IPFORWARDNEXTHOP, IPADDRESS, RONLY, ipFwTable, 3, {2, 1, 4}}, -    {IPFORWARDIFINDEX, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 5}}, -    {IPFORWARDTYPE, ENUMERATION, RONLY, ipFwTable, 3, {2, 1, 6}}, -    {IPFORWARDPROTO, ENUMERATION, RONLY, ipFwTable, 3, {2, 1, 7}}, -    {IPFORWARDAGE, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 8}}, -    {IPFORWARDINFO, OBJECTIDENTIFIER, RONLY, ipFwTable, 3, {2, 1, 9}}, -    {IPFORWARDNEXTHOPAS, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 10}}, -    {IPFORWARDMETRIC1, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 11}}, -    {IPFORWARDMETRIC2, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 12}}, -    {IPFORWARDMETRIC3, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 13}}, -    {IPFORWARDMETRIC4, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 14}}, -    {IPFORWARDMETRIC5, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 15}}, -    {0, GAUGE32, RONLY, ipCidrNumber, 1, {3}}, -    {IPCIDRROUTEDEST, IPADDRESS, RONLY, ipCidrTable, 3, {4, 1, 1}}, -    {IPCIDRROUTEMASK, IPADDRESS, RONLY, ipCidrTable, 3, {4, 1, 2}}, -    {IPCIDRROUTETOS, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 3}}, -    {IPCIDRROUTENEXTHOP, IPADDRESS, RONLY, ipCidrTable, 3, {4, 1, 4}}, -    {IPCIDRROUTEIFINDEX, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 5}}, -    {IPCIDRROUTETYPE, ENUMERATION, RONLY, ipCidrTable, 3, {4, 1, 6}}, -    {IPCIDRROUTEPROTO, ENUMERATION, RONLY, ipCidrTable, 3, {4, 1, 7}}, -    {IPCIDRROUTEAGE, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 8}}, -    {IPCIDRROUTEINFO, OBJECTIDENTIFIER, RONLY, ipCidrTable, 3, {4, 1, 9}}, -    {IPCIDRROUTENEXTHOPAS, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 10}}, -    {IPCIDRROUTEMETRIC1, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 11}}, -    {IPCIDRROUTEMETRIC2, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 12}}, -    {IPCIDRROUTEMETRIC3, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 13}}, -    {IPCIDRROUTEMETRIC4, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 14}}, -    {IPCIDRROUTEMETRIC5, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 15}}, -    {IPCIDRROUTESTATUS, ROWSTATUS, RONLY, ipCidrTable, 3, {4, 1, 16}} -  }; - - -static u_char * -ipFwNumber (struct variable *v, oid objid[], size_t *objid_len, -	    int exact, size_t *val_len, WriteMethod **write_method) +static u_char *ipFwNumber(struct variable *, oid[], size_t *, int, size_t *, +			  WriteMethod **); +static u_char *ipFwTable(struct variable *, oid[], size_t *, int, size_t *, +			 WriteMethod **); +static u_char *ipCidrNumber(struct variable *, oid[], size_t *, int, size_t *, +			    WriteMethod **); +static u_char *ipCidrTable(struct variable *, oid[], size_t *, int, size_t *, +			   WriteMethod **); + +static struct variable zebra_variables[] = { +	{0, GAUGE32, RONLY, ipFwNumber, 1, {1}}, +	{IPFORWARDDEST, IPADDRESS, RONLY, ipFwTable, 3, {2, 1, 1}}, +	{IPFORWARDMASK, IPADDRESS, RONLY, ipFwTable, 3, {2, 1, 2}}, +	{IPFORWARDPOLICY, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 3}}, +	{IPFORWARDNEXTHOP, IPADDRESS, RONLY, ipFwTable, 3, {2, 1, 4}}, +	{IPFORWARDIFINDEX, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 5}}, +	{IPFORWARDTYPE, ENUMERATION, RONLY, ipFwTable, 3, {2, 1, 6}}, +	{IPFORWARDPROTO, ENUMERATION, RONLY, ipFwTable, 3, {2, 1, 7}}, +	{IPFORWARDAGE, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 8}}, +	{IPFORWARDINFO, OBJECTIDENTIFIER, RONLY, ipFwTable, 3, {2, 1, 9}}, +	{IPFORWARDNEXTHOPAS, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 10}}, +	{IPFORWARDMETRIC1, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 11}}, +	{IPFORWARDMETRIC2, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 12}}, +	{IPFORWARDMETRIC3, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 13}}, +	{IPFORWARDMETRIC4, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 14}}, +	{IPFORWARDMETRIC5, INTEGER32, RONLY, ipFwTable, 3, {2, 1, 15}}, +	{0, GAUGE32, RONLY, ipCidrNumber, 1, {3}}, +	{IPCIDRROUTEDEST, IPADDRESS, RONLY, ipCidrTable, 3, {4, 1, 1}}, +	{IPCIDRROUTEMASK, IPADDRESS, RONLY, ipCidrTable, 3, {4, 1, 2}}, +	{IPCIDRROUTETOS, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 3}}, +	{IPCIDRROUTENEXTHOP, IPADDRESS, RONLY, ipCidrTable, 3, {4, 1, 4}}, +	{IPCIDRROUTEIFINDEX, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 5}}, +	{IPCIDRROUTETYPE, ENUMERATION, RONLY, ipCidrTable, 3, {4, 1, 6}}, +	{IPCIDRROUTEPROTO, ENUMERATION, RONLY, ipCidrTable, 3, {4, 1, 7}}, +	{IPCIDRROUTEAGE, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 8}}, +	{IPCIDRROUTEINFO, OBJECTIDENTIFIER, RONLY, ipCidrTable, 3, {4, 1, 9}}, +	{IPCIDRROUTENEXTHOPAS, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 10}}, +	{IPCIDRROUTEMETRIC1, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 11}}, +	{IPCIDRROUTEMETRIC2, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 12}}, +	{IPCIDRROUTEMETRIC3, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 13}}, +	{IPCIDRROUTEMETRIC4, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 14}}, +	{IPCIDRROUTEMETRIC5, INTEGER32, RONLY, ipCidrTable, 3, {4, 1, 15}}, +	{IPCIDRROUTESTATUS, ROWSTATUS, RONLY, ipCidrTable, 3, {4, 1, 16}}}; + + +static u_char *ipFwNumber(struct variable *v, oid objid[], size_t *objid_len, +			  int exact, size_t *val_len, +			  WriteMethod **write_method)  { -  static int result; -  struct route_table *table; -  struct route_node *rn; -  struct rib *rib; - -  if (smux_header_generic(v, objid, objid_len, exact, val_len, write_method) == MATCH_FAILED) -    return NULL; - -  table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT); -  if (! table) -    return NULL; - -  /* Return number of routing entries. */ -  result = 0; -  for (rn = route_top (table); rn; rn = route_next (rn)) -    RNODE_FOREACH_RIB (rn, rib) -      result++; - -  return (u_char *)&result; +	static int result; +	struct route_table *table; +	struct route_node *rn; +	struct rib *rib; + +	if (smux_header_generic(v, objid, objid_len, exact, val_len, +				write_method) +	    == MATCH_FAILED) +		return NULL; + +	table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, VRF_DEFAULT); +	if (!table) +		return NULL; + +	/* Return number of routing entries. */ +	result = 0; +	for (rn = route_top(table); rn; rn = route_next(rn)) +		RNODE_FOREACH_RIB(rn, rib) +	result++; + +	return (u_char *)&result;  } -static u_char * -ipCidrNumber (struct variable *v, oid objid[], size_t *objid_len, -	      int exact, size_t *val_len, WriteMethod **write_method) +static u_char *ipCidrNumber(struct variable *v, oid objid[], size_t *objid_len, +			    int exact, size_t *val_len, +			    WriteMethod **write_method)  { -  static int result; -  struct route_table *table; -  struct route_node *rn; -  struct rib *rib; - -  if (smux_header_generic(v, objid, objid_len, exact, val_len, write_method) == MATCH_FAILED) -    return NULL; - -  table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT); -  if (! table) -    return 0; - -  /* Return number of routing entries. */ -  result = 0; -  for (rn = route_top (table); rn; rn = route_next (rn)) -    RNODE_FOREACH_RIB (rn, rib) -      result++; - -  return (u_char *)&result; +	static int result; +	struct route_table *table; +	struct route_node *rn; +	struct rib *rib; + +	if (smux_header_generic(v, objid, objid_len, exact, val_len, +				write_method) +	    == MATCH_FAILED) +		return NULL; + +	table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, VRF_DEFAULT); +	if (!table) +		return 0; + +	/* Return number of routing entries. */ +	result = 0; +	for (rn = route_top(table); rn; rn = route_next(rn)) +		RNODE_FOREACH_RIB(rn, rib) +	result++; + +	return (u_char *)&result;  } -static int -in_addr_cmp(u_char *p1, u_char *p2) +static int in_addr_cmp(u_char *p1, u_char *p2)  { -  int i; - -  for (i=0; i<4; i++) -    { -      if (*p1 < *p2) -        return -1; -      if (*p1 > *p2) -        return 1; -      p1++; p2++; -    } -  return 0; +	int i; + +	for (i = 0; i < 4; i++) { +		if (*p1 < *p2) +			return -1; +		if (*p1 > *p2) +			return 1; +		p1++; +		p2++; +	} +	return 0;  } -static int  -in_addr_add(u_char *p, int num) +static int in_addr_add(u_char *p, int num)  { -  int i, ip0; - -  ip0 = *p; -  p += 4; -  for (i = 3; 0 <= i; i--) { -    p--; -    if (*p + num > 255) { -      *p += num; -      num = 1; -    } else { -      *p += num; -      return 1; -    } -  } -  if (ip0 > *p) { -    /* ip + num > 0xffffffff */ -    return 0; -  } -   -  return 1; -} +	int i, ip0; + +	ip0 = *p; +	p += 4; +	for (i = 3; 0 <= i; i--) { +		p--; +		if (*p + num > 255) { +			*p += num; +			num = 1; +		} else { +			*p += num; +			return 1; +		} +	} +	if (ip0 > *p) { +		/* ip + num > 0xffffffff */ +		return 0; +	} -static int -proto_trans(int type) -{ -  switch (type) -    { -    case ZEBRA_ROUTE_SYSTEM: -      return 1; /* other */ -    case ZEBRA_ROUTE_KERNEL: -      return 1; /* other */ -    case ZEBRA_ROUTE_CONNECT: -      return 2; /* local interface */ -    case ZEBRA_ROUTE_STATIC: -      return 3; /* static route */ -    case ZEBRA_ROUTE_RIP: -      return 8; /* rip */ -    case ZEBRA_ROUTE_RIPNG: -      return 1; /* shouldn't happen */ -    case ZEBRA_ROUTE_OSPF: -      return 13; /* ospf */ -    case ZEBRA_ROUTE_OSPF6: -      return 1; /* shouldn't happen */ -    case ZEBRA_ROUTE_BGP: -      return 14; /* bgp */ -    default: -      return 1; /* other */ -    } +	return 1;  } -static void -check_replace(struct route_node *np2, struct rib *rib2,  -              struct route_node **np, struct rib **rib) +static int proto_trans(int type)  { -  int proto, proto2; - -  if (!*np) -    { -      *np = np2; -      *rib = rib2; -      return; -    } - -  if (in_addr_cmp(&(*np)->p.u.prefix, &np2->p.u.prefix) < 0) -    return; -  if (in_addr_cmp(&(*np)->p.u.prefix, &np2->p.u.prefix) > 0) -    { -      *np = np2; -      *rib = rib2; -      return; -    } - -  proto = proto_trans((*rib)->type); -  proto2 = proto_trans(rib2->type); - -  if (proto2 > proto) -    return; -  if (proto2 < proto) -    { -      *np = np2; -      *rib = rib2; -      return; -    } - -  if (in_addr_cmp((u_char *)&(*rib)->nexthop->gate.ipv4,  -                  (u_char *)&rib2->nexthop->gate.ipv4) <= 0) -    return; - -  *np = np2; -  *rib = rib2; -  return; +	switch (type) { +	case ZEBRA_ROUTE_SYSTEM: +		return 1; /* other */ +	case ZEBRA_ROUTE_KERNEL: +		return 1; /* other */ +	case ZEBRA_ROUTE_CONNECT: +		return 2; /* local interface */ +	case ZEBRA_ROUTE_STATIC: +		return 3; /* static route */ +	case ZEBRA_ROUTE_RIP: +		return 8; /* rip */ +	case ZEBRA_ROUTE_RIPNG: +		return 1; /* shouldn't happen */ +	case ZEBRA_ROUTE_OSPF: +		return 13; /* ospf */ +	case ZEBRA_ROUTE_OSPF6: +		return 1; /* shouldn't happen */ +	case ZEBRA_ROUTE_BGP: +		return 14; /* bgp */ +	default: +		return 1; /* other */ +	}  } -static void -get_fwtable_route_node(struct variable *v, oid objid[], size_t *objid_len,  -		       int exact, struct route_node **np, struct rib **rib) +static void check_replace(struct route_node *np2, struct rib *rib2, +			  struct route_node **np, struct rib **rib)  { -  struct in_addr dest; -  struct route_table *table; -  struct route_node *np2; -  struct rib *rib2; -  int proto; -  int policy; -  struct in_addr nexthop; -  u_char *pnt; -  int i; +	int proto, proto2; -  /* Init index variables */ +	if (!*np) { +		*np = np2; +		*rib = rib2; +		return; +	} -  pnt = (u_char *) &dest; -  for (i = 0; i < 4; i++) -    *pnt++ = 0; +	if (in_addr_cmp(&(*np)->p.u.prefix, &np2->p.u.prefix) < 0) +		return; +	if (in_addr_cmp(&(*np)->p.u.prefix, &np2->p.u.prefix) > 0) { +		*np = np2; +		*rib = rib2; +		return; +	} -  pnt = (u_char *) &nexthop; -  for (i = 0; i < 4; i++) -    *pnt++ = 0; +	proto = proto_trans((*rib)->type); +	proto2 = proto_trans(rib2->type); -  proto = 0; -  policy = 0; -  -  /* Init return variables */ +	if (proto2 > proto) +		return; +	if (proto2 < proto) { +		*np = np2; +		*rib = rib2; +		return; +	} -  *np = NULL; -  *rib = NULL; +	if (in_addr_cmp((u_char *)&(*rib)->nexthop->gate.ipv4, +			(u_char *)&rib2->nexthop->gate.ipv4) +	    <= 0) +		return; -  /* Short circuit exact matches of wrong length */ +	*np = np2; +	*rib = rib2; +	return; +} -  if (exact && (*objid_len != (unsigned) v->namelen + 10)) -    return; +static void get_fwtable_route_node(struct variable *v, oid objid[], +				   size_t *objid_len, int exact, +				   struct route_node **np, struct rib **rib) +{ +	struct in_addr dest; +	struct route_table *table; +	struct route_node *np2; +	struct rib *rib2; +	int proto; +	int policy; +	struct in_addr nexthop; +	u_char *pnt; +	int i; + +	/* Init index variables */ + +	pnt = (u_char *)&dest; +	for (i = 0; i < 4; i++) +		*pnt++ = 0; -  table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT); -  if (! table) -    return; +	pnt = (u_char *)&nexthop; +	for (i = 0; i < 4; i++) +		*pnt++ = 0; -  /* Get INDEX information out of OID. -   * ipForwardDest, ipForwardProto, ipForwardPolicy, ipForwardNextHop -   */ +	proto = 0; +	policy = 0; -  if (*objid_len > (unsigned) v->namelen) -    oid2in_addr (objid + v->namelen, MIN(4U, *objid_len - v->namelen), &dest); +	/* Init return variables */ -  if (*objid_len > (unsigned) v->namelen + 4) -    proto = objid[v->namelen + 4]; +	*np = NULL; +	*rib = NULL; -  if (*objid_len > (unsigned) v->namelen + 5) -    policy = objid[v->namelen + 5]; +	/* Short circuit exact matches of wrong length */ -  if (*objid_len > (unsigned) v->namelen + 6) -    oid2in_addr (objid + v->namelen + 6, MIN(4U, *objid_len - v->namelen - 6), -		 &nexthop); +	if (exact && (*objid_len != (unsigned)v->namelen + 10)) +		return; -  /* Apply GETNEXT on not exact search */ +	table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, VRF_DEFAULT); +	if (!table) +		return; -  if (!exact && (*objid_len >= (unsigned) v->namelen + 10)) -    { -      if (! in_addr_add((u_char *) &nexthop, 1))  -        return; -    } +	/* Get INDEX information out of OID. +	 * ipForwardDest, ipForwardProto, ipForwardPolicy, ipForwardNextHop +	 */ -  /* For exact: search matching entry in rib table. */ +	if (*objid_len > (unsigned)v->namelen) +		oid2in_addr(objid + v->namelen, +			    MIN(4U, *objid_len - v->namelen), &dest); -  if (exact) -    { -      if (policy) /* Not supported (yet?) */ -        return; -      for (*np = route_top (table); *np; *np = route_next (*np)) -	{ -	  if (!in_addr_cmp(&(*np)->p.u.prefix, (u_char *)&dest)) -	    { -	      RNODE_FOREACH_RIB (*np, *rib) -	        { -		  if (!in_addr_cmp((u_char *)&(*rib)->nexthop->gate.ipv4, -				   (u_char *)&nexthop)) -		    if (proto == proto_trans((*rib)->type)) -		      return; +	if (*objid_len > (unsigned)v->namelen + 4) +		proto = objid[v->namelen + 4]; + +	if (*objid_len > (unsigned)v->namelen + 5) +		policy = objid[v->namelen + 5]; + +	if (*objid_len > (unsigned)v->namelen + 6) +		oid2in_addr(objid + v->namelen + 6, +			    MIN(4U, *objid_len - v->namelen - 6), &nexthop); + +	/* Apply GETNEXT on not exact search */ + +	if (!exact && (*objid_len >= (unsigned)v->namelen + 10)) { +		if (!in_addr_add((u_char *)&nexthop, 1)) +			return; +	} + +	/* For exact: search matching entry in rib table. */ + +	if (exact) { +		if (policy) /* Not supported (yet?) */ +			return; +		for (*np = route_top(table); *np; *np = route_next(*np)) { +			if (!in_addr_cmp(&(*np)->p.u.prefix, (u_char *)&dest)) { +				RNODE_FOREACH_RIB(*np, *rib) +				{ +					if (!in_addr_cmp((u_char *)&(*rib) +								 ->nexthop->gate +								 .ipv4, +							 (u_char *)&nexthop)) +						if (proto +						    == proto_trans( +							       (*rib)->type)) +							return; +				} +			}  		} -	    } +		return;  	} -      return; -    } - -  /* Search next best entry */ - -  for (np2 = route_top (table); np2; np2 = route_next (np2)) -    { - -      /* Check destination first */ -      if (in_addr_cmp(&np2->p.u.prefix, (u_char *)&dest) > 0) -	RNODE_FOREACH_RIB (np2, rib2) -	  check_replace(np2, rib2, np, rib); - -      if (in_addr_cmp(&np2->p.u.prefix, (u_char *)&dest) == 0) -        { /* have to look at each rib individually */ -	  RNODE_FOREACH_RIB (np2, rib2) -	    { -	      int proto2, policy2; - -	      proto2 = proto_trans(rib2->type); -	      policy2 = 0; - -	      if ((policy < policy2) -		  || ((policy == policy2) && (proto < proto2)) -		  || ((policy == policy2) && (proto == proto2) -		      && (in_addr_cmp((u_char *)&rib2->nexthop->gate.ipv4, -				      (u_char *) &nexthop) >= 0) -		      )) + +	/* Search next best entry */ + +	for (np2 = route_top(table); np2; np2 = route_next(np2)) { + +		/* Check destination first */ +		if (in_addr_cmp(&np2->p.u.prefix, (u_char *)&dest) > 0) +			RNODE_FOREACH_RIB(np2, rib2)  		check_replace(np2, rib2, np, rib); -	    } + +		if (in_addr_cmp(&np2->p.u.prefix, (u_char *)&dest) +		    == 0) { /* have to look at each rib individually */ +			RNODE_FOREACH_RIB(np2, rib2) +			{ +				int proto2, policy2; + +				proto2 = proto_trans(rib2->type); +				policy2 = 0; + +				if ((policy < policy2) +				    || ((policy == policy2) && (proto < proto2)) +				    || ((policy == policy2) && (proto == proto2) +					&& (in_addr_cmp((u_char *)&rib2->nexthop +								->gate.ipv4, +							(u_char *)&nexthop) +					    >= 0))) +					check_replace(np2, rib2, np, rib); +			} +		}  	} -    } -  if (!*rib) -    return; +	if (!*rib) +		return; -  policy = 0; -  proto = proto_trans((*rib)->type); +	policy = 0; +	proto = proto_trans((*rib)->type); -  *objid_len = v->namelen + 10; -  pnt = (u_char *) &(*np)->p.u.prefix; -  for (i = 0; i < 4; i++) -    objid[v->namelen + i] = *pnt++; +	*objid_len = v->namelen + 10; +	pnt = (u_char *)&(*np)->p.u.prefix; +	for (i = 0; i < 4; i++) +		objid[v->namelen + i] = *pnt++; -  objid[v->namelen + 4] = proto; -  objid[v->namelen + 5] = policy; +	objid[v->namelen + 4] = proto; +	objid[v->namelen + 5] = policy; -  { -    struct nexthop *nexthop; +	{ +		struct nexthop *nexthop; -    nexthop = (*rib)->nexthop; -    if (nexthop) -      { -	pnt = (u_char *) &nexthop->gate.ipv4; -	for (i = 0; i < 4; i++) -	  objid[i + v->namelen + 6] = *pnt++; -      } -  } +		nexthop = (*rib)->nexthop; +		if (nexthop) { +			pnt = (u_char *)&nexthop->gate.ipv4; +			for (i = 0; i < 4; i++) +				objid[i + v->namelen + 6] = *pnt++; +		} +	} -  return; +	return;  } -static u_char * -ipFwTable (struct variable *v, oid objid[], size_t *objid_len, -	   int exact, size_t *val_len, WriteMethod **write_method) +static u_char *ipFwTable(struct variable *v, oid objid[], size_t *objid_len, +			 int exact, size_t *val_len, WriteMethod **write_method)  { -  struct route_node *np; -  struct rib *rib; -  static int result; -  static int resarr[2]; -  static struct in_addr netmask; -  struct nexthop *nexthop; - -  if (smux_header_table(v, objid, objid_len, exact, val_len, write_method) -      == MATCH_FAILED) -    return NULL; - -  get_fwtable_route_node(v, objid, objid_len, exact, &np, &rib); -  if (!np) -    return NULL; - -  nexthop = rib->nexthop; -  if (! nexthop) -    return NULL; - -  switch (v->magic) -    { -    case IPFORWARDDEST: -      *val_len = 4; -      return &np->p.u.prefix; -      break; -    case IPFORWARDMASK: -      masklen2ip(np->p.prefixlen, &netmask); -      *val_len = 4; -      return (u_char *)&netmask; -      break; -    case IPFORWARDPOLICY: -      result = 0; -      *val_len  = sizeof(int); -      return (u_char *)&result; -      break; -    case IPFORWARDNEXTHOP: -      *val_len = 4; -      return (u_char *)&nexthop->gate.ipv4; -      break; -    case IPFORWARDIFINDEX: -      *val_len = sizeof(int); -      return (u_char *)&nexthop->ifindex; -      break; -    case IPFORWARDTYPE: -      if (nexthop->type == NEXTHOP_TYPE_IFINDEX) -        result = 3; -      else -        result = 4; -      *val_len  = sizeof(int); -      return (u_char *)&result; -      break; -    case IPFORWARDPROTO: -      result = proto_trans(rib->type); -      *val_len  = sizeof(int); -      return (u_char *)&result; -      break; -    case IPFORWARDAGE: -      result = 0; -      *val_len  = sizeof(int); -      return (u_char *)&result; -      break; -    case IPFORWARDINFO: -      resarr[0] = 0; -      resarr[1] = 0; -      *val_len  = 2 * sizeof(int); -      return (u_char *)resarr; -      break; -    case IPFORWARDNEXTHOPAS: -      result = -1; -      *val_len  = sizeof(int); -      return (u_char *)&result; -      break; -    case IPFORWARDMETRIC1: -      result = 0; -      *val_len  = sizeof(int); -      return (u_char *)&result; -      break; -    case IPFORWARDMETRIC2: -      result = 0; -      *val_len  = sizeof(int); -      return (u_char *)&result; -      break; -    case IPFORWARDMETRIC3: -      result = 0; -      *val_len  = sizeof(int); -      return (u_char *)&result; -      break; -    case IPFORWARDMETRIC4: -      result = 0; -      *val_len  = sizeof(int); -      return (u_char *)&result; -      break; -    case IPFORWARDMETRIC5: -      result = 0; -      *val_len  = sizeof(int); -      return (u_char *)&result; -      break; -    default: -      return NULL; -      break; -    }   -  return NULL; +	struct route_node *np; +	struct rib *rib; +	static int result; +	static int resarr[2]; +	static struct in_addr netmask; +	struct nexthop *nexthop; + +	if (smux_header_table(v, objid, objid_len, exact, val_len, write_method) +	    == MATCH_FAILED) +		return NULL; + +	get_fwtable_route_node(v, objid, objid_len, exact, &np, &rib); +	if (!np) +		return NULL; + +	nexthop = rib->nexthop; +	if (!nexthop) +		return NULL; + +	switch (v->magic) { +	case IPFORWARDDEST: +		*val_len = 4; +		return &np->p.u.prefix; +		break; +	case IPFORWARDMASK: +		masklen2ip(np->p.prefixlen, &netmask); +		*val_len = 4; +		return (u_char *)&netmask; +		break; +	case IPFORWARDPOLICY: +		result = 0; +		*val_len = sizeof(int); +		return (u_char *)&result; +		break; +	case IPFORWARDNEXTHOP: +		*val_len = 4; +		return (u_char *)&nexthop->gate.ipv4; +		break; +	case IPFORWARDIFINDEX: +		*val_len = sizeof(int); +		return (u_char *)&nexthop->ifindex; +		break; +	case IPFORWARDTYPE: +		if (nexthop->type == NEXTHOP_TYPE_IFINDEX) +			result = 3; +		else +			result = 4; +		*val_len = sizeof(int); +		return (u_char *)&result; +		break; +	case IPFORWARDPROTO: +		result = proto_trans(rib->type); +		*val_len = sizeof(int); +		return (u_char *)&result; +		break; +	case IPFORWARDAGE: +		result = 0; +		*val_len = sizeof(int); +		return (u_char *)&result; +		break; +	case IPFORWARDINFO: +		resarr[0] = 0; +		resarr[1] = 0; +		*val_len = 2 * sizeof(int); +		return (u_char *)resarr; +		break; +	case IPFORWARDNEXTHOPAS: +		result = -1; +		*val_len = sizeof(int); +		return (u_char *)&result; +		break; +	case IPFORWARDMETRIC1: +		result = 0; +		*val_len = sizeof(int); +		return (u_char *)&result; +		break; +	case IPFORWARDMETRIC2: +		result = 0; +		*val_len = sizeof(int); +		return (u_char *)&result; +		break; +	case IPFORWARDMETRIC3: +		result = 0; +		*val_len = sizeof(int); +		return (u_char *)&result; +		break; +	case IPFORWARDMETRIC4: +		result = 0; +		*val_len = sizeof(int); +		return (u_char *)&result; +		break; +	case IPFORWARDMETRIC5: +		result = 0; +		*val_len = sizeof(int); +		return (u_char *)&result; +		break; +	default: +		return NULL; +		break; +	} +	return NULL;  } -static u_char * -ipCidrTable (struct variable *v, oid objid[], size_t *objid_len, -	     int exact, size_t *val_len, WriteMethod **write_method) +static u_char *ipCidrTable(struct variable *v, oid objid[], size_t *objid_len, +			   int exact, size_t *val_len, +			   WriteMethod **write_method)  { -  if (smux_header_table(v, objid, objid_len, exact, val_len, write_method) -      == MATCH_FAILED) -    return NULL; - -  switch (v->magic) -    { -    case IPCIDRROUTEDEST: -      break; -    default: -      return NULL; -      break; -    }   -  return NULL; +	if (smux_header_table(v, objid, objid_len, exact, val_len, write_method) +	    == MATCH_FAILED) +		return NULL; + +	switch (v->magic) { +	case IPCIDRROUTEDEST: +		break; +	default: +		return NULL; +		break; +	} +	return NULL;  } -static int -zebra_snmp_init (struct thread_master *tm) +static int zebra_snmp_init(struct thread_master *tm)  { -  smux_init (tm); -  REGISTER_MIB("mibII/ipforward", zebra_variables, variable, ipfw_oid); -  return 0; +	smux_init(tm); +	REGISTER_MIB("mibII/ipforward", zebra_variables, variable, ipfw_oid); +	return 0;  } -static int -zebra_snmp_module_init (void) +static int zebra_snmp_module_init(void)  { -  hook_register(frr_late_init, zebra_snmp_init); -  return 0; +	hook_register(frr_late_init, zebra_snmp_init); +	return 0;  } -FRR_MODULE_SETUP( -	.name = "zebra_snmp", -	.version = FRR_VERSION, -	.description = "zebra AgentX SNMP module", -	.init = zebra_snmp_module_init, -) +FRR_MODULE_SETUP(.name = "zebra_snmp", .version = FRR_VERSION, +		 .description = "zebra AgentX SNMP module", +		 .init = zebra_snmp_module_init, ) diff --git a/zebra/zebra_static.c b/zebra/zebra_static.c index 169f1827e0..384e3671ba 100644 --- a/zebra/zebra_static.c +++ b/zebra/zebra_static.c @@ -38,551 +38,541 @@  #include "zebra/zebra_memory.h"  /* Install static route into rib. */ -void -static_install_route (afi_t afi, safi_t safi, struct prefix *p, -                      struct prefix_ipv6 *src_p, struct static_route *si) +void static_install_route(afi_t afi, safi_t safi, struct prefix *p, +			  struct prefix_ipv6 *src_p, struct static_route *si)  { -  struct rib *rib; -  struct route_node *rn; -  struct route_table *table; -  struct prefix nh_p; -  struct nexthop *nexthop = NULL; - -  /* Lookup table.  */ -  table = zebra_vrf_table (afi, safi, si->vrf_id); -  if (! table) -    return; - -  memset (&nh_p, 0, sizeof (nh_p)); - -  /* Lookup existing route */ -  rn = srcdest_rnode_get (table, p, src_p); -  RNODE_FOREACH_RIB (rn, rib) -    { -       if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) -         continue; - -       if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance) -         break; -    } - -  if (rib) -    { -      /* if tag value changed , update old value in RIB */ -      if (rib->tag != si->tag) -        rib->tag = si->tag; - -      /* Same distance static route is there.  Update it with new -         nexthop. */ -      route_unlock_node (rn); -      switch (si->type) -        { -	case STATIC_IPV4_GATEWAY: -	  nexthop = rib_nexthop_ipv4_add (rib, &si->addr.ipv4, NULL); -	  nh_p.family = AF_INET; -	  nh_p.prefixlen = IPV4_MAX_BITLEN; -	  nh_p.u.prefix4 = si->addr.ipv4; -	  zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn); -	  break; -	case STATIC_IFNAME: -	  nexthop = rib_nexthop_ifindex_add (rib, si->ifindex); -	  break; -	case STATIC_BLACKHOLE: -	  nexthop = rib_nexthop_blackhole_add (rib); -	  break; -	case STATIC_IPV6_GATEWAY: -	  nexthop = rib_nexthop_ipv6_add (rib, &si->addr.ipv6); -	  nh_p.family = AF_INET6; -	  nh_p.prefixlen = IPV6_MAX_BITLEN; -	  nh_p.u.prefix6 = si->addr.ipv6; -	  zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn); -	  break; -	case STATIC_IPV6_GATEWAY_IFNAME: -	  nexthop = rib_nexthop_ipv6_ifindex_add (rib, &si->addr.ipv6, -						  si->ifindex); -	  break; -        } -      /* Update label(s), if present. */ -      if (si->snh_label.num_labels) -	nexthop_add_labels (nexthop, ZEBRA_LSP_STATIC, si->snh_label.num_labels, -			    &si->snh_label.label[0]); - -      if (IS_ZEBRA_DEBUG_RIB) -        { -          char buf[INET6_ADDRSTRLEN]; -          if (IS_ZEBRA_DEBUG_RIB) -            { -              inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN); -              zlog_debug ("%u:%s/%d: Modifying route rn %p, rib %p (type %d)", -                          si->vrf_id, buf, p->prefixlen, rn, rib, rib->type); -            } -        } -      /* Schedule route for processing or invoke NHT, as appropriate. */ -      if (si->type == STATIC_IPV4_GATEWAY || -          si->type == STATIC_IPV6_GATEWAY) -        zebra_evaluate_rnh(si->vrf_id, nh_p.family, 1, RNH_NEXTHOP_TYPE, &nh_p); -      else -        rib_queue_add (rn); -    } -  else -    { -      /* This is new static route. */ -      rib = XCALLOC (MTYPE_RIB, sizeof (struct rib)); - -      rib->type = ZEBRA_ROUTE_STATIC; -      rib->instance = 0; -      rib->distance = si->distance; -      rib->metric = 0; -      rib->mtu = 0; -      rib->vrf_id = si->vrf_id; -      rib->table =  si->vrf_id ? (zebra_vrf_lookup_by_id(si->vrf_id))->table_id : zebrad.rtm_table_default; -      rib->nexthop_num = 0; -      rib->tag = si->tag; - -      switch (si->type) -        { -	case STATIC_IPV4_GATEWAY: -	  nexthop = rib_nexthop_ipv4_add (rib, &si->addr.ipv4, NULL); -	  nh_p.family = AF_INET; -	  nh_p.prefixlen = IPV4_MAX_BITLEN; -	  nh_p.u.prefix4 = si->addr.ipv4; -	  zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn); -	  break; -	case STATIC_IFNAME: -	  nexthop = rib_nexthop_ifindex_add (rib, si->ifindex); -	  break; -	case STATIC_BLACKHOLE: -	  nexthop = rib_nexthop_blackhole_add (rib); -	  break; -	case STATIC_IPV6_GATEWAY: -	  nexthop = rib_nexthop_ipv6_add (rib, &si->addr.ipv6); -	  nh_p.family = AF_INET6; -	  nh_p.prefixlen = IPV6_MAX_BITLEN; -	  nh_p.u.prefix6 = si->addr.ipv6; -	  zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn); -	  break; -	case STATIC_IPV6_GATEWAY_IFNAME: -	  nexthop = rib_nexthop_ipv6_ifindex_add (rib, &si->addr.ipv6, -						  si->ifindex); -	  break; -        } -      /* Update label(s), if present. */ -      if (si->snh_label.num_labels) -	nexthop_add_labels (nexthop, ZEBRA_LSP_STATIC, si->snh_label.num_labels, -			    &si->snh_label.label[0]); - -      /* Save the flags of this static routes (reject, blackhole) */ -      rib->flags = si->flags; - -      if (IS_ZEBRA_DEBUG_RIB) -        { -          char buf[INET6_ADDRSTRLEN]; -          if (IS_ZEBRA_DEBUG_RIB) -            { -              inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN); -              zlog_debug ("%u:%s/%d: Inserting route rn %p, rib %p (type %d)", -                          si->vrf_id, buf, p->prefixlen, rn, rib, rib->type); -            } -        } -      /* Link this rib to the tree. Schedule for processing or invoke NHT, -       * as appropriate. -       */ -      if (si->type == STATIC_IPV4_GATEWAY || -          si->type == STATIC_IPV6_GATEWAY) -        { -          rib_addnode (rn, rib, 0); -          zebra_evaluate_rnh(si->vrf_id, nh_p.family, 1, RNH_NEXTHOP_TYPE, &nh_p); -        } -      else -        rib_addnode (rn, rib, 1); -    } +	struct rib *rib; +	struct route_node *rn; +	struct route_table *table; +	struct prefix nh_p; +	struct nexthop *nexthop = NULL; + +	/* Lookup table.  */ +	table = zebra_vrf_table(afi, safi, si->vrf_id); +	if (!table) +		return; + +	memset(&nh_p, 0, sizeof(nh_p)); + +	/* Lookup existing route */ +	rn = srcdest_rnode_get(table, p, src_p); +	RNODE_FOREACH_RIB(rn, rib) +	{ +		if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED)) +			continue; + +		if (rib->type == ZEBRA_ROUTE_STATIC +		    && rib->distance == si->distance) +			break; +	} + +	if (rib) { +		/* if tag value changed , update old value in RIB */ +		if (rib->tag != si->tag) +			rib->tag = si->tag; + +		/* Same distance static route is there.  Update it with new +		   nexthop. */ +		route_unlock_node(rn); +		switch (si->type) { +		case STATIC_IPV4_GATEWAY: +			nexthop = +				rib_nexthop_ipv4_add(rib, &si->addr.ipv4, NULL); +			nh_p.family = AF_INET; +			nh_p.prefixlen = IPV4_MAX_BITLEN; +			nh_p.u.prefix4 = si->addr.ipv4; +			zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn); +			break; +		case STATIC_IFNAME: +			nexthop = rib_nexthop_ifindex_add(rib, si->ifindex); +			break; +		case STATIC_BLACKHOLE: +			nexthop = rib_nexthop_blackhole_add(rib); +			break; +		case STATIC_IPV6_GATEWAY: +			nexthop = rib_nexthop_ipv6_add(rib, &si->addr.ipv6); +			nh_p.family = AF_INET6; +			nh_p.prefixlen = IPV6_MAX_BITLEN; +			nh_p.u.prefix6 = si->addr.ipv6; +			zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn); +			break; +		case STATIC_IPV6_GATEWAY_IFNAME: +			nexthop = rib_nexthop_ipv6_ifindex_add( +				rib, &si->addr.ipv6, si->ifindex); +			break; +		} +		/* Update label(s), if present. */ +		if (si->snh_label.num_labels) +			nexthop_add_labels(nexthop, ZEBRA_LSP_STATIC, +					   si->snh_label.num_labels, +					   &si->snh_label.label[0]); + +		if (IS_ZEBRA_DEBUG_RIB) { +			char buf[INET6_ADDRSTRLEN]; +			if (IS_ZEBRA_DEBUG_RIB) { +				inet_ntop(p->family, &p->u.prefix, buf, +					  INET6_ADDRSTRLEN); +				zlog_debug( +					"%u:%s/%d: Modifying route rn %p, rib %p (type %d)", +					si->vrf_id, buf, p->prefixlen, rn, rib, +					rib->type); +			} +		} +		/* Schedule route for processing or invoke NHT, as appropriate. +		 */ +		if (si->type == STATIC_IPV4_GATEWAY +		    || si->type == STATIC_IPV6_GATEWAY) +			zebra_evaluate_rnh(si->vrf_id, nh_p.family, 1, +					   RNH_NEXTHOP_TYPE, &nh_p); +		else +			rib_queue_add(rn); +	} else { +		/* This is new static route. */ +		rib = XCALLOC(MTYPE_RIB, sizeof(struct rib)); + +		rib->type = ZEBRA_ROUTE_STATIC; +		rib->instance = 0; +		rib->distance = si->distance; +		rib->metric = 0; +		rib->mtu = 0; +		rib->vrf_id = si->vrf_id; +		rib->table = +			si->vrf_id +				? (zebra_vrf_lookup_by_id(si->vrf_id))->table_id +				: zebrad.rtm_table_default; +		rib->nexthop_num = 0; +		rib->tag = si->tag; + +		switch (si->type) { +		case STATIC_IPV4_GATEWAY: +			nexthop = +				rib_nexthop_ipv4_add(rib, &si->addr.ipv4, NULL); +			nh_p.family = AF_INET; +			nh_p.prefixlen = IPV4_MAX_BITLEN; +			nh_p.u.prefix4 = si->addr.ipv4; +			zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn); +			break; +		case STATIC_IFNAME: +			nexthop = rib_nexthop_ifindex_add(rib, si->ifindex); +			break; +		case STATIC_BLACKHOLE: +			nexthop = rib_nexthop_blackhole_add(rib); +			break; +		case STATIC_IPV6_GATEWAY: +			nexthop = rib_nexthop_ipv6_add(rib, &si->addr.ipv6); +			nh_p.family = AF_INET6; +			nh_p.prefixlen = IPV6_MAX_BITLEN; +			nh_p.u.prefix6 = si->addr.ipv6; +			zebra_register_rnh_static_nh(si->vrf_id, &nh_p, rn); +			break; +		case STATIC_IPV6_GATEWAY_IFNAME: +			nexthop = rib_nexthop_ipv6_ifindex_add( +				rib, &si->addr.ipv6, si->ifindex); +			break; +		} +		/* Update label(s), if present. */ +		if (si->snh_label.num_labels) +			nexthop_add_labels(nexthop, ZEBRA_LSP_STATIC, +					   si->snh_label.num_labels, +					   &si->snh_label.label[0]); + +		/* Save the flags of this static routes (reject, blackhole) */ +		rib->flags = si->flags; + +		if (IS_ZEBRA_DEBUG_RIB) { +			char buf[INET6_ADDRSTRLEN]; +			if (IS_ZEBRA_DEBUG_RIB) { +				inet_ntop(p->family, &p->u.prefix, buf, +					  INET6_ADDRSTRLEN); +				zlog_debug( +					"%u:%s/%d: Inserting route rn %p, rib %p (type %d)", +					si->vrf_id, buf, p->prefixlen, rn, rib, +					rib->type); +			} +		} +		/* Link this rib to the tree. Schedule for processing or invoke +		 * NHT, +		 * as appropriate. +		 */ +		if (si->type == STATIC_IPV4_GATEWAY +		    || si->type == STATIC_IPV6_GATEWAY) { +			rib_addnode(rn, rib, 0); +			zebra_evaluate_rnh(si->vrf_id, nh_p.family, 1, +					   RNH_NEXTHOP_TYPE, &nh_p); +		} else +			rib_addnode(rn, rib, 1); +	}  }  /* this works correctly with IFNAME<>IFINDEX because a static route on a   * non-active interface will have IFINDEX_INTERNAL and thus compare false   */ -static int -static_nexthop_same (struct nexthop *nexthop, struct static_route *si) +static int static_nexthop_same(struct nexthop *nexthop, struct static_route *si)  { -  if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE -      && si->type == STATIC_BLACKHOLE) -    return 1; - -  if (nexthop->type == NEXTHOP_TYPE_IPV4 -      && si->type == STATIC_IPV4_GATEWAY -      && IPV4_ADDR_SAME (&nexthop->gate.ipv4, &si->addr.ipv4)) -    return 1; -  else if (nexthop->type == NEXTHOP_TYPE_IFINDEX -      && si->type == STATIC_IFNAME -      && nexthop->ifindex == si->ifindex) -    return 1; -  else if (nexthop->type == NEXTHOP_TYPE_IPV6 -      && si->type == STATIC_IPV6_GATEWAY -      && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->addr.ipv6)) -    return 1; -  else if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX -      && si->type == STATIC_IPV6_GATEWAY_IFNAME -      && IPV6_ADDR_SAME (&nexthop->gate.ipv6, &si->addr.ipv6) -      && nexthop->ifindex == si->ifindex) -    return 1; - -  return 0; +	if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE +	    && si->type == STATIC_BLACKHOLE) +		return 1; + +	if (nexthop->type == NEXTHOP_TYPE_IPV4 +	    && si->type == STATIC_IPV4_GATEWAY +	    && IPV4_ADDR_SAME(&nexthop->gate.ipv4, &si->addr.ipv4)) +		return 1; +	else if (nexthop->type == NEXTHOP_TYPE_IFINDEX +		 && si->type == STATIC_IFNAME +		 && nexthop->ifindex == si->ifindex) +		return 1; +	else if (nexthop->type == NEXTHOP_TYPE_IPV6 +		 && si->type == STATIC_IPV6_GATEWAY +		 && IPV6_ADDR_SAME(&nexthop->gate.ipv6, &si->addr.ipv6)) +		return 1; +	else if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX +		 && si->type == STATIC_IPV6_GATEWAY_IFNAME +		 && IPV6_ADDR_SAME(&nexthop->gate.ipv6, &si->addr.ipv6) +		 && nexthop->ifindex == si->ifindex) +		return 1; + +	return 0;  }  /* Uninstall static route from RIB. */ -void -static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, -                        struct prefix_ipv6 *src_p, struct static_route *si) +void static_uninstall_route(afi_t afi, safi_t safi, struct prefix *p, +			    struct prefix_ipv6 *src_p, struct static_route *si)  { -  struct route_node *rn; -  struct rib *rib; -  struct nexthop *nexthop; -  struct route_table *table; -  struct prefix nh_p; - -  /* Lookup table.  */ -  table = zebra_vrf_table (afi, safi, si->vrf_id); -  if (! table) -    return; - -  /* Lookup existing route with type and distance. */ -  rn = srcdest_rnode_lookup (table, p, src_p); -  if (! rn) -    return; - -  RNODE_FOREACH_RIB (rn, rib) -    { -      if (CHECK_FLAG (rib->status, RIB_ENTRY_REMOVED)) -        continue; - -      if (rib->type == ZEBRA_ROUTE_STATIC && rib->distance == si->distance && -          rib->tag == si->tag) -        break; -    } - -  if (! rib) -    { -      route_unlock_node (rn); -      return; -    } - -  /* Lookup nexthop. */ -  for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) -    if (static_nexthop_same (nexthop, si)) -      break; - -  /* Can't find nexthop. */ -  if (! nexthop) -    { -      route_unlock_node (rn); -      return; -    } - -  /* Check nexthop. */ -  if (rib->nexthop_num == 1) -    rib_delnode (rn, rib); -  else -    { -      /* Mark this nexthop as inactive and reinstall the route. Then, delete -       * the nexthop. There is no need to re-evaluate the route for this -       * scenario. -       */ -      if (IS_ZEBRA_DEBUG_RIB) -        { -          char buf[INET6_ADDRSTRLEN]; -          if (IS_ZEBRA_DEBUG_RIB) -            { -              inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN); -              zlog_debug ("%u:%s/%d: Modifying route rn %p, rib %p (type %d)", -                          si->vrf_id, buf, p->prefixlen, rn, rib, rib->type); -            } -        } -      UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); -      if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) -        { -          /* If there are other active nexthops, do an update. */ -          if (rib->nexthop_active_num > 1) -            { -              /* Update route in kernel if it's in fib */ -              if (CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB)) -                rib_install_kernel (rn, rib, rib); -              /* Update redistribution if it's selected */ -              if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED)) -                redistribute_update (p, (struct prefix*)src_p, rib, NULL); -            } -          else -            { -              /* Remove from redistribute if selected route becomes inactive */ -              if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED)) -                redistribute_delete (p, (struct prefix*)src_p, rib); -              /* Remove from kernel if fib route becomes inactive */ -              if (CHECK_FLAG(rib->status, RIB_ENTRY_SELECTED_FIB)) -              rib_uninstall_kernel (rn, rib); -            } -        } - -      if (afi == AFI_IP) +	struct route_node *rn; +	struct rib *rib; +	struct nexthop *nexthop; +	struct route_table *table; +	struct prefix nh_p; + +	/* Lookup table.  */ +	table = zebra_vrf_table(afi, safi, si->vrf_id); +	if (!table) +		return; + +	/* Lookup existing route with type and distance. */ +	rn = srcdest_rnode_lookup(table, p, src_p); +	if (!rn) +		return; + +	RNODE_FOREACH_RIB(rn, rib)  	{ -	  /* Delete the nexthop and dereg from NHT */ -	  nh_p.family = AF_INET; -	  nh_p.prefixlen = IPV4_MAX_BITLEN; -	  nh_p.u.prefix4 = nexthop->gate.ipv4; +		if (CHECK_FLAG(rib->status, RIB_ENTRY_REMOVED)) +			continue; + +		if (rib->type == ZEBRA_ROUTE_STATIC +		    && rib->distance == si->distance && rib->tag == si->tag) +			break;  	} -      else -	{ -	  nh_p.family = AF_INET6; -	  nh_p.prefixlen = IPV6_MAX_BITLEN; -	  nh_p.u.prefix6 = nexthop->gate.ipv6; + +	if (!rib) { +		route_unlock_node(rn); +		return; +	} + +	/* Lookup nexthop. */ +	for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) +		if (static_nexthop_same(nexthop, si)) +			break; + +	/* Can't find nexthop. */ +	if (!nexthop) { +		route_unlock_node(rn); +		return; +	} + +	/* Check nexthop. */ +	if (rib->nexthop_num == 1) +		rib_delnode(rn, rib); +	else { +		/* Mark this nexthop as inactive and reinstall the route. Then, +		 * delete +		 * the nexthop. There is no need to re-evaluate the route for +		 * this +		 * scenario. +		 */ +		if (IS_ZEBRA_DEBUG_RIB) { +			char buf[INET6_ADDRSTRLEN]; +			if (IS_ZEBRA_DEBUG_RIB) { +				inet_ntop(p->family, &p->u.prefix, buf, +					  INET6_ADDRSTRLEN); +				zlog_debug( +					"%u:%s/%d: Modifying route rn %p, rib %p (type %d)", +					si->vrf_id, buf, p->prefixlen, rn, rib, +					rib->type); +			} +		} +		UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); +		if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)) { +			/* If there are other active nexthops, do an update. */ +			if (rib->nexthop_active_num > 1) { +				/* Update route in kernel if it's in fib */ +				if (CHECK_FLAG(rib->status, +					       RIB_ENTRY_SELECTED_FIB)) +					rib_install_kernel(rn, rib, rib); +				/* Update redistribution if it's selected */ +				if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED)) +					redistribute_update( +						p, (struct prefix *)src_p, rib, +						NULL); +			} else { +				/* Remove from redistribute if selected route +				 * becomes inactive */ +				if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED)) +					redistribute_delete( +						p, (struct prefix *)src_p, rib); +				/* Remove from kernel if fib route becomes +				 * inactive */ +				if (CHECK_FLAG(rib->status, +					       RIB_ENTRY_SELECTED_FIB)) +					rib_uninstall_kernel(rn, rib); +			} +		} + +		if (afi == AFI_IP) { +			/* Delete the nexthop and dereg from NHT */ +			nh_p.family = AF_INET; +			nh_p.prefixlen = IPV4_MAX_BITLEN; +			nh_p.u.prefix4 = nexthop->gate.ipv4; +		} else { +			nh_p.family = AF_INET6; +			nh_p.prefixlen = IPV6_MAX_BITLEN; +			nh_p.u.prefix6 = nexthop->gate.ipv6; +		} +		rib_nexthop_delete(rib, nexthop); +		zebra_deregister_rnh_static_nh(si->vrf_id, &nh_p, rn); +		nexthop_free(nexthop);  	} -      rib_nexthop_delete (rib, nexthop); -      zebra_deregister_rnh_static_nh(si->vrf_id, &nh_p, rn); -      nexthop_free (nexthop); -    } -  /* Unlock node. */ -  route_unlock_node (rn); +	/* Unlock node. */ +	route_unlock_node(rn);  } -int -static_add_route (afi_t afi, safi_t safi, u_char type, struct prefix *p, -		  struct prefix_ipv6 *src_p, union g_addr *gate, -		  const char *ifname, u_char flags, route_tag_t tag, -		  u_char distance, struct zebra_vrf *zvrf, -		  struct static_nh_label *snh_label) +int static_add_route(afi_t afi, safi_t safi, u_char type, struct prefix *p, +		     struct prefix_ipv6 *src_p, union g_addr *gate, +		     const char *ifname, u_char flags, route_tag_t tag, +		     u_char distance, struct zebra_vrf *zvrf, +		     struct static_nh_label *snh_label)  { -  struct route_node *rn; -  struct static_route *si; -  struct static_route *pp; -  struct static_route *cp; -  struct static_route *update = NULL; -  struct route_table *stable = zvrf->stable[afi][safi]; - -  if (! stable) -    return -1; - -  if (!gate && -      (type == STATIC_IPV4_GATEWAY || -       type == STATIC_IPV6_GATEWAY || -       type == STATIC_IPV6_GATEWAY_IFNAME)) -    return -1; - -  if (!ifname && -      (type == STATIC_IFNAME || -       type == STATIC_IPV6_GATEWAY_IFNAME)) -    return -1; - -  /* Lookup static route prefix. */ -  rn = srcdest_rnode_get (stable, p, src_p); - -  /* Do nothing if there is a same static route.  */ -  for (si = rn->info; si; si = si->next) -    { -      if (type == si->type -	  && (! gate || -	      ((afi == AFI_IP && IPV4_ADDR_SAME (gate, &si->addr.ipv4)) || -	       (afi == AFI_IP6 && IPV6_ADDR_SAME (gate, &si->addr.ipv6)))) -	  && (!strcmp (ifname ? ifname : "", si->ifname))) -	{ -	  if ((distance == si->distance) && (tag == si->tag) && -	      !memcmp (&si->snh_label, snh_label, sizeof (struct static_nh_label)) && -	      si->flags == flags) -	    { -	      route_unlock_node (rn); -	      return 0; -	    } -	  else -	    update = si; +	struct route_node *rn; +	struct static_route *si; +	struct static_route *pp; +	struct static_route *cp; +	struct static_route *update = NULL; +	struct route_table *stable = zvrf->stable[afi][safi]; + +	if (!stable) +		return -1; + +	if (!gate && (type == STATIC_IPV4_GATEWAY || type == STATIC_IPV6_GATEWAY +		      || type == STATIC_IPV6_GATEWAY_IFNAME)) +		return -1; + +	if (!ifname +	    && (type == STATIC_IFNAME || type == STATIC_IPV6_GATEWAY_IFNAME)) +		return -1; + +	/* Lookup static route prefix. */ +	rn = srcdest_rnode_get(stable, p, src_p); + +	/* Do nothing if there is a same static route.  */ +	for (si = rn->info; si; si = si->next) { +		if (type == si->type +		    && (!gate || ((afi == AFI_IP +				   && IPV4_ADDR_SAME(gate, &si->addr.ipv4)) +				  || (afi == AFI_IP6 +				      && IPV6_ADDR_SAME(gate, &si->addr.ipv6)))) +		    && (!strcmp(ifname ? ifname : "", si->ifname))) { +			if ((distance == si->distance) && (tag == si->tag) +			    && !memcmp(&si->snh_label, snh_label, +				       sizeof(struct static_nh_label)) +			    && si->flags == flags) { +				route_unlock_node(rn); +				return 0; +			} else +				update = si; +		}  	} -    } - -  /* Distance or tag or label changed, delete existing first. */ -  if (update) -    static_delete_route (afi, safi, type, p, src_p, gate, ifname, update->tag, -			 update->distance, zvrf, &update->snh_label); - -  /* Make new static route structure. */ -  si = XCALLOC (MTYPE_STATIC_ROUTE, sizeof (struct static_route)); - -  si->type = type; -  si->distance = distance; -  si->flags = flags; -  si->tag = tag; -  si->vrf_id = zvrf_id (zvrf); -  if (ifname) -    strlcpy(si->ifname, ifname, sizeof(si->ifname)); -  si->ifindex = IFINDEX_INTERNAL; - -  switch (type) -    { -    case STATIC_IPV4_GATEWAY: -      si->addr.ipv4 = gate->ipv4; -      break; -    case STATIC_IPV6_GATEWAY: -      si->addr.ipv6 = gate->ipv6; -      break; -    case STATIC_IPV6_GATEWAY_IFNAME: -      si->addr.ipv6 = gate->ipv6; -      break; -    case STATIC_IFNAME: -      break; -    } - -  /* Save labels, if any. */ -  memcpy (&si->snh_label, snh_label, sizeof (struct static_nh_label)); - -  /* Add new static route information to the tree with sort by -     distance value and gateway address. */ -  for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next) -    { -      if (si->distance < cp->distance) -	break; -      if (si->distance > cp->distance) -	continue; -      if (si->type == STATIC_IPV4_GATEWAY && cp->type == STATIC_IPV4_GATEWAY) -	{ -	  if (ntohl (si->addr.ipv4.s_addr) < ntohl (cp->addr.ipv4.s_addr)) -	    break; -	  if (ntohl (si->addr.ipv4.s_addr) > ntohl (cp->addr.ipv4.s_addr)) -	    continue; + +	/* Distance or tag or label changed, delete existing first. */ +	if (update) +		static_delete_route(afi, safi, type, p, src_p, gate, ifname, +				    update->tag, update->distance, zvrf, +				    &update->snh_label); + +	/* Make new static route structure. */ +	si = XCALLOC(MTYPE_STATIC_ROUTE, sizeof(struct static_route)); + +	si->type = type; +	si->distance = distance; +	si->flags = flags; +	si->tag = tag; +	si->vrf_id = zvrf_id(zvrf); +	if (ifname) +		strlcpy(si->ifname, ifname, sizeof(si->ifname)); +	si->ifindex = IFINDEX_INTERNAL; + +	switch (type) { +	case STATIC_IPV4_GATEWAY: +		si->addr.ipv4 = gate->ipv4; +		break; +	case STATIC_IPV6_GATEWAY: +		si->addr.ipv6 = gate->ipv6; +		break; +	case STATIC_IPV6_GATEWAY_IFNAME: +		si->addr.ipv6 = gate->ipv6; +		break; +	case STATIC_IFNAME: +		break;  	} -    } - -  /* Make linked list. */ -  if (pp) -    pp->next = si; -  else -    rn->info = si; -  if (cp) -    cp->prev = si; -  si->prev = pp; -  si->next = cp; - -  /* check whether interface exists in system & install if it does */ -  if (!ifname) -    static_install_route(afi, safi, p, src_p, si); -  else -    { -      struct interface *ifp; - -      ifp = if_lookup_by_name(ifname, zvrf_id(zvrf)); -      if (ifp && ifp->ifindex != IFINDEX_INTERNAL) -        { -          si->ifindex = ifp->ifindex; -          static_install_route (afi, safi, p, src_p, si); -        } -    } - -  return 1; + +	/* Save labels, if any. */ +	memcpy(&si->snh_label, snh_label, sizeof(struct static_nh_label)); + +	/* Add new static route information to the tree with sort by +	   distance value and gateway address. */ +	for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next) { +		if (si->distance < cp->distance) +			break; +		if (si->distance > cp->distance) +			continue; +		if (si->type == STATIC_IPV4_GATEWAY +		    && cp->type == STATIC_IPV4_GATEWAY) { +			if (ntohl(si->addr.ipv4.s_addr) +			    < ntohl(cp->addr.ipv4.s_addr)) +				break; +			if (ntohl(si->addr.ipv4.s_addr) +			    > ntohl(cp->addr.ipv4.s_addr)) +				continue; +		} +	} + +	/* Make linked list. */ +	if (pp) +		pp->next = si; +	else +		rn->info = si; +	if (cp) +		cp->prev = si; +	si->prev = pp; +	si->next = cp; + +	/* check whether interface exists in system & install if it does */ +	if (!ifname) +		static_install_route(afi, safi, p, src_p, si); +	else { +		struct interface *ifp; + +		ifp = if_lookup_by_name(ifname, zvrf_id(zvrf)); +		if (ifp && ifp->ifindex != IFINDEX_INTERNAL) { +			si->ifindex = ifp->ifindex; +			static_install_route(afi, safi, p, src_p, si); +		} +	} + +	return 1;  } -int -static_delete_route (afi_t afi, safi_t safi, u_char type, struct prefix *p, -		     struct prefix_ipv6 *src_p, -		     union g_addr *gate, const char *ifname, -		     route_tag_t tag, u_char distance, struct zebra_vrf *zvrf, -		     struct static_nh_label *snh_label) +int static_delete_route(afi_t afi, safi_t safi, u_char type, struct prefix *p, +			struct prefix_ipv6 *src_p, union g_addr *gate, +			const char *ifname, route_tag_t tag, u_char distance, +			struct zebra_vrf *zvrf, +			struct static_nh_label *snh_label)  { -  struct route_node *rn; -  struct static_route *si; -  struct route_table *stable; - -  /* Lookup table.  */ -  stable = zebra_vrf_static_table (afi, safi, zvrf); -  if (! stable) -    return -1; - -  /* Lookup static route prefix. */ -  rn = srcdest_rnode_lookup (stable, p, src_p); -  if (! rn) -    return 0; - -  /* Find same static route is the tree */ -  for (si = rn->info; si; si = si->next) -    if (type == si->type -	&& (! gate || ( -		       (afi == AFI_IP && IPV4_ADDR_SAME (gate, &si->addr.ipv4)) || -		       (afi == AFI_IP6 && IPV6_ADDR_SAME (gate, &si->addr.ipv6)))) -	&& (!strcmp(ifname ? ifname : "", si->ifname)) -	&& (! tag || (tag == si->tag)) -	&& (! snh_label->num_labels || -	    !memcmp (&si->snh_label, snh_label, sizeof (struct static_nh_label)))) -      break; - -  /* Can't find static route. */ -  if (! si) -    { -      route_unlock_node (rn); -      return 0; -    } - -  /* Uninstall from rib. */ -  if (!si->ifname[0] || si->ifindex != IFINDEX_INTERNAL) -    static_uninstall_route (afi, safi, p, src_p, si); - -  /* Unlink static route from linked list. */ -  if (si->prev) -    si->prev->next = si->next; -  else -    rn->info = si->next; -  if (si->next) -    si->next->prev = si->prev; -  route_unlock_node (rn); - -  /* Free static route configuration. */ -  XFREE (MTYPE_STATIC_ROUTE, si); - -  route_unlock_node (rn); - -  return 1; +	struct route_node *rn; +	struct static_route *si; +	struct route_table *stable; + +	/* Lookup table.  */ +	stable = zebra_vrf_static_table(afi, safi, zvrf); +	if (!stable) +		return -1; + +	/* Lookup static route prefix. */ +	rn = srcdest_rnode_lookup(stable, p, src_p); +	if (!rn) +		return 0; + +	/* Find same static route is the tree */ +	for (si = rn->info; si; si = si->next) +		if (type == si->type +		    && (!gate || ((afi == AFI_IP +				   && IPV4_ADDR_SAME(gate, &si->addr.ipv4)) +				  || (afi == AFI_IP6 +				      && IPV6_ADDR_SAME(gate, &si->addr.ipv6)))) +		    && (!strcmp(ifname ? ifname : "", si->ifname)) +		    && (!tag || (tag == si->tag)) +		    && (!snh_label->num_labels +			|| !memcmp(&si->snh_label, snh_label, +				   sizeof(struct static_nh_label)))) +			break; + +	/* Can't find static route. */ +	if (!si) { +		route_unlock_node(rn); +		return 0; +	} + +	/* Uninstall from rib. */ +	if (!si->ifname[0] || si->ifindex != IFINDEX_INTERNAL) +		static_uninstall_route(afi, safi, p, src_p, si); + +	/* Unlink static route from linked list. */ +	if (si->prev) +		si->prev->next = si->next; +	else +		rn->info = si->next; +	if (si->next) +		si->next->prev = si->prev; +	route_unlock_node(rn); + +	/* Free static route configuration. */ +	XFREE(MTYPE_STATIC_ROUTE, si); + +	route_unlock_node(rn); + +	return 1;  } -static void -static_ifindex_update_af(struct interface *ifp, bool up, -                         afi_t afi, safi_t safi) +static void static_ifindex_update_af(struct interface *ifp, bool up, afi_t afi, +				     safi_t safi)  { -  struct route_table *stable; -  struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(ifp->vrf_id); -  struct route_node *rn; -  struct static_route *si; -  struct prefix *p, *src_pp; -  struct prefix_ipv6 *src_p; - -  stable = zebra_vrf_static_table(afi, safi, zvrf); -  if (!stable) -    return; - -  for (rn = route_top(stable); rn; rn = srcdest_route_next(rn)) -    { -      srcdest_rnode_prefixes(rn, &p, &src_pp); -      src_p = (struct prefix_ipv6 *)src_pp; - -      for (si = rn->info; si; si = si->next) -        { -          if (!si->ifname[0]) -            continue; -          if (up) -            { -              if (strcmp(si->ifname, ifp->name)) -                continue; -              si->ifindex = ifp->ifindex; -              static_install_route(afi, safi, p, src_p, si); -            } -          else -            { -              if (si->ifindex != ifp->ifindex) -                continue; -              static_uninstall_route(afi, safi, p, src_p, si); -              si->ifindex = IFINDEX_INTERNAL; -          } -        } -    } +	struct route_table *stable; +	struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(ifp->vrf_id); +	struct route_node *rn; +	struct static_route *si; +	struct prefix *p, *src_pp; +	struct prefix_ipv6 *src_p; + +	stable = zebra_vrf_static_table(afi, safi, zvrf); +	if (!stable) +		return; + +	for (rn = route_top(stable); rn; rn = srcdest_route_next(rn)) { +		srcdest_rnode_prefixes(rn, &p, &src_pp); +		src_p = (struct prefix_ipv6 *)src_pp; + +		for (si = rn->info; si; si = si->next) { +			if (!si->ifname[0]) +				continue; +			if (up) { +				if (strcmp(si->ifname, ifp->name)) +					continue; +				si->ifindex = ifp->ifindex; +				static_install_route(afi, safi, p, src_p, si); +			} else { +				if (si->ifindex != ifp->ifindex) +					continue; +				static_uninstall_route(afi, safi, p, src_p, si); +				si->ifindex = IFINDEX_INTERNAL; +			} +		} +	}  }  /* called from if_{add,delete}_update, i.e. when ifindex becomes [in]valid */ -void -static_ifindex_update(struct interface *ifp, bool up) +void static_ifindex_update(struct interface *ifp, bool up)  { -  static_ifindex_update_af(ifp, up, AFI_IP, SAFI_UNICAST); -  static_ifindex_update_af(ifp, up, AFI_IP, SAFI_MULTICAST); -  static_ifindex_update_af(ifp, up, AFI_IP6, SAFI_UNICAST); -  static_ifindex_update_af(ifp, up, AFI_IP6, SAFI_MULTICAST); +	static_ifindex_update_af(ifp, up, AFI_IP, SAFI_UNICAST); +	static_ifindex_update_af(ifp, up, AFI_IP, SAFI_MULTICAST); +	static_ifindex_update_af(ifp, up, AFI_IP6, SAFI_UNICAST); +	static_ifindex_update_af(ifp, up, AFI_IP6, SAFI_MULTICAST);  } diff --git a/zebra/zebra_static.h b/zebra/zebra_static.h index 6d3bafa325..e5ceba914c 100644 --- a/zebra/zebra_static.h +++ b/zebra/zebra_static.h @@ -24,99 +24,93 @@  #define __ZEBRA_STATIC_H__  /* Static route label information */ -struct static_nh_label -{ -  u_int8_t num_labels; -  u_int8_t reserved[3]; -  mpls_label_t label[2]; +struct static_nh_label { +	u_int8_t num_labels; +	u_int8_t reserved[3]; +	mpls_label_t label[2];  };  typedef enum { -  STATIC_IFNAME, -  STATIC_IPV4_GATEWAY, -  STATIC_BLACKHOLE, -  STATIC_IPV6_GATEWAY, -  STATIC_IPV6_GATEWAY_IFNAME, +	STATIC_IFNAME, +	STATIC_IPV4_GATEWAY, +	STATIC_BLACKHOLE, +	STATIC_IPV6_GATEWAY, +	STATIC_IPV6_GATEWAY_IFNAME,  } zebra_static_types;  /* Static route information. */ -struct static_route -{ -  /* For linked list. */ -  struct static_route *prev; -  struct static_route *next; - -  /* VRF identifier. */ -  vrf_id_t vrf_id; - -  /* Administrative distance. */ -  u_char distance; - -  /* Tag */ -  route_tag_t tag; - -  /* Flag for this static route's type. */ -  zebra_static_types type; - -  /* -   * Nexthop value. -   * -   * Under IPv4 addr and ifindex are -   * used independentyly. -   * STATIC_IPV4_GATEWAY uses addr -   * STATIC_IFNAME uses ifindex -   */ -  union g_addr addr; -  ifindex_t ifindex; - -  char ifname[INTERFACE_NAMSIZ + 1]; - -  /* bit flags */ -  u_char flags; -/* - see ZEBRA_FLAG_REJECT -     ZEBRA_FLAG_BLACKHOLE - */ - -  /* Label information */ -  struct static_nh_label snh_label; +struct static_route { +	/* For linked list. */ +	struct static_route *prev; +	struct static_route *next; + +	/* VRF identifier. */ +	vrf_id_t vrf_id; + +	/* Administrative distance. */ +	u_char distance; + +	/* Tag */ +	route_tag_t tag; + +	/* Flag for this static route's type. */ +	zebra_static_types type; + +	/* +	 * Nexthop value. +	 * +	 * Under IPv4 addr and ifindex are +	 * used independentyly. +	 * STATIC_IPV4_GATEWAY uses addr +	 * STATIC_IFNAME uses ifindex +	 */ +	union g_addr addr; +	ifindex_t ifindex; + +	char ifname[INTERFACE_NAMSIZ + 1]; + +	/* bit flags */ +	u_char flags; +	/* +	 see ZEBRA_FLAG_REJECT +	     ZEBRA_FLAG_BLACKHOLE +	 */ + +	/* Label information */ +	struct static_nh_label snh_label;  }; -extern void -static_install_route (afi_t afi, safi_t safi, struct prefix *p, -                      struct prefix_ipv6 *src_p, struct static_route *si); -extern void -static_uninstall_route (afi_t afi, safi_t safi, struct prefix *p, -                        struct prefix_ipv6 *src_p, struct static_route *si); - -extern int -static_add_route (afi_t, safi_t safi, u_char type, struct prefix *p, -		  struct prefix_ipv6 *src_p, union g_addr *gate, -		  const char *ifname, u_char flags, route_tag_t tag, -		  u_char distance, struct zebra_vrf *zvrf, -		  struct static_nh_label *snh_label); - -extern int -static_delete_route (afi_t, safi_t safi, u_char type, struct prefix *p, -		     struct prefix_ipv6 *src_p, union g_addr *gate, -		     const char *ifname, route_tag_t tag, -		     u_char distance, struct zebra_vrf *zvrf, -		     struct static_nh_label *snh_label); - -int -zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd, -		   const char *dest_str, const char *mask_str, -		   const char *gate_str, const char *flag_str, -		   const char *tag_str, const char *distance_str, -		   const char *vrf_id_str, const char *label_str); - -int -static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str, -		  const char *src_str, -		  const char *gate_str, const char *ifname, -		  const char *flag_str, const char *tag_str, -                  const char *distance_str, const char *vrf_id_str, -		  const char *label_str); +extern void static_install_route(afi_t afi, safi_t safi, struct prefix *p, +				 struct prefix_ipv6 *src_p, +				 struct static_route *si); +extern void static_uninstall_route(afi_t afi, safi_t safi, struct prefix *p, +				   struct prefix_ipv6 *src_p, +				   struct static_route *si); + +extern int static_add_route(afi_t, safi_t safi, u_char type, struct prefix *p, +			    struct prefix_ipv6 *src_p, union g_addr *gate, +			    const char *ifname, u_char flags, route_tag_t tag, +			    u_char distance, struct zebra_vrf *zvrf, +			    struct static_nh_label *snh_label); + +extern int static_delete_route(afi_t, safi_t safi, u_char type, +			       struct prefix *p, struct prefix_ipv6 *src_p, +			       union g_addr *gate, const char *ifname, +			       route_tag_t tag, u_char distance, +			       struct zebra_vrf *zvrf, +			       struct static_nh_label *snh_label); + +int zebra_static_ipv4(struct vty *vty, safi_t safi, int add_cmd, +		      const char *dest_str, const char *mask_str, +		      const char *gate_str, const char *flag_str, +		      const char *tag_str, const char *distance_str, +		      const char *vrf_id_str, const char *label_str); + +int static_ipv6_func(struct vty *vty, int add_cmd, const char *dest_str, +		     const char *src_str, const char *gate_str, +		     const char *ifname, const char *flag_str, +		     const char *tag_str, const char *distance_str, +		     const char *vrf_id_str, const char *label_str);  extern void static_ifindex_update(struct interface *ifp, bool up); diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index 06d87a468e..aa040acf0f 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -42,463 +42,446 @@  extern struct zebra_t zebrad;  /* VRF information update. */ -static void -zebra_vrf_add_update (struct zebra_vrf *zvrf) +static void zebra_vrf_add_update(struct zebra_vrf *zvrf)  { -  struct listnode *node, *nnode; -  struct zserv *client; +	struct listnode *node, *nnode; +	struct zserv *client; -  if (IS_ZEBRA_DEBUG_EVENT) -    zlog_debug ("MESSAGE: ZEBRA_VRF_ADD %s", zvrf_name (zvrf)); +	if (IS_ZEBRA_DEBUG_EVENT) +		zlog_debug("MESSAGE: ZEBRA_VRF_ADD %s", zvrf_name(zvrf)); -  for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) -    zsend_vrf_add (client, zvrf); +	for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) +		zsend_vrf_add(client, zvrf);  } -static void -zebra_vrf_delete_update (struct zebra_vrf *zvrf) +static void zebra_vrf_delete_update(struct zebra_vrf *zvrf)  { -  struct listnode *node, *nnode; -  struct zserv *client; +	struct listnode *node, *nnode; +	struct zserv *client; -  if (IS_ZEBRA_DEBUG_EVENT) -    zlog_debug ("MESSAGE: ZEBRA_VRF_DELETE %s", zvrf_name (zvrf)); +	if (IS_ZEBRA_DEBUG_EVENT) +		zlog_debug("MESSAGE: ZEBRA_VRF_DELETE %s", zvrf_name(zvrf)); -  for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) -    zsend_vrf_delete (client, zvrf); +	for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) +		zsend_vrf_delete(client, zvrf);  } -void -zebra_vrf_update_all (struct zserv *client) +void zebra_vrf_update_all(struct zserv *client)  { -  struct vrf *vrf; +	struct vrf *vrf; -  RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) -    { -      if (vrf->vrf_id) -        zsend_vrf_add (client, vrf_info_lookup (vrf->vrf_id)); -    } +	RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id) +	{ +		if (vrf->vrf_id) +			zsend_vrf_add(client, vrf_info_lookup(vrf->vrf_id)); +	}  }  /* Callback upon creating a new VRF. */ -static int -zebra_vrf_new (struct vrf *vrf) +static int zebra_vrf_new(struct vrf *vrf)  { -  struct zebra_vrf *zvrf; +	struct zebra_vrf *zvrf; -  if (IS_ZEBRA_DEBUG_EVENT) -    zlog_info ("ZVRF %s with id %u", vrf->name, vrf->vrf_id); +	if (IS_ZEBRA_DEBUG_EVENT) +		zlog_info("ZVRF %s with id %u", vrf->name, vrf->vrf_id); -  zvrf = zebra_vrf_alloc (); -  zvrf->zns = zebra_ns_lookup (NS_DEFAULT); /* Point to the global (single) NS */ -  router_id_init (zvrf); -  vrf->info = zvrf; -  zvrf->vrf = vrf; +	zvrf = zebra_vrf_alloc(); +	zvrf->zns = zebra_ns_lookup( +		NS_DEFAULT); /* Point to the global (single) NS */ +	router_id_init(zvrf); +	vrf->info = zvrf; +	zvrf->vrf = vrf; -  return 0; +	return 0;  }  /* Callback upon enabling a VRF. */ -static int -zebra_vrf_enable (struct vrf *vrf) +static int zebra_vrf_enable(struct vrf *vrf)  { -  struct zebra_vrf *zvrf = vrf->info; -  struct route_table *stable; -  struct route_node *rn; -  struct static_route *si; -  struct interface *ifp; -  afi_t afi; -  safi_t safi; - -  assert (zvrf); - -  zebra_vrf_add_update (zvrf); - -  for (afi = AFI_IP; afi < AFI_MAX; afi++) -    for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) -      { -	stable = zvrf->stable[afi][safi]; -	if (! stable) -	  continue; - -	for (rn = route_top (stable); rn; rn = route_next (rn)) -	  for (si = rn->info; si; si = si->next) -	    { -	      si->vrf_id = vrf->vrf_id; -	      if (si->ifindex) -		{ -		  ifp = if_lookup_by_name (si->ifname, si->vrf_id); -		  if (ifp) -		    si->ifindex = ifp->ifindex; -		  else -		    continue; +	struct zebra_vrf *zvrf = vrf->info; +	struct route_table *stable; +	struct route_node *rn; +	struct static_route *si; +	struct interface *ifp; +	afi_t afi; +	safi_t safi; + +	assert(zvrf); + +	zebra_vrf_add_update(zvrf); + +	for (afi = AFI_IP; afi < AFI_MAX; afi++) +		for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) { +			stable = zvrf->stable[afi][safi]; +			if (!stable) +				continue; + +			for (rn = route_top(stable); rn; rn = route_next(rn)) +				for (si = rn->info; si; si = si->next) { +					si->vrf_id = vrf->vrf_id; +					if (si->ifindex) { +						ifp = if_lookup_by_name( +							si->ifname, si->vrf_id); +						if (ifp) +							si->ifindex = +								ifp->ifindex; +						else +							continue; +					} +					static_install_route(afi, safi, &rn->p, +							     NULL, si); +				}  		} -	      static_install_route (afi, safi, &rn->p, NULL, si); -	    } -      } -  return 0; +	return 0;  }  /* Callback upon disabling a VRF. */ -static int -zebra_vrf_disable (struct vrf *vrf) +static int zebra_vrf_disable(struct vrf *vrf)  { -  struct zebra_vrf *zvrf = vrf->info; -  struct route_table *stable; -  struct route_node *rn; -  struct static_route *si; -  afi_t afi; -  safi_t safi; - -  if (IS_ZEBRA_DEBUG_KERNEL) -    zlog_debug ("VRF %s id %u is now disabled.", -                zvrf_name (zvrf), zvrf_id (zvrf)); - -  for (afi = AFI_IP; afi < AFI_MAX; afi++) -    for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) -      { -	stable = zvrf->stable[afi][safi]; -	if (! stable) -	  continue; - -	for (rn = route_top (stable); rn; rn = route_next (rn)) -	  for (si = rn->info; si; si = si->next) -	    static_uninstall_route(afi, safi, &rn->p, NULL, si); -      } - -  return 0; +	struct zebra_vrf *zvrf = vrf->info; +	struct route_table *stable; +	struct route_node *rn; +	struct static_route *si; +	afi_t afi; +	safi_t safi; + +	if (IS_ZEBRA_DEBUG_KERNEL) +		zlog_debug("VRF %s id %u is now disabled.", zvrf_name(zvrf), +			   zvrf_id(zvrf)); + +	for (afi = AFI_IP; afi < AFI_MAX; afi++) +		for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) { +			stable = zvrf->stable[afi][safi]; +			if (!stable) +				continue; + +			for (rn = route_top(stable); rn; rn = route_next(rn)) +				for (si = rn->info; si; si = si->next) +					static_uninstall_route( +						afi, safi, &rn->p, NULL, si); +		} + +	return 0;  } -static int -zebra_vrf_delete (struct vrf *vrf) +static int zebra_vrf_delete(struct vrf *vrf)  { -  struct zebra_vrf *zvrf = vrf->info; -  struct route_table *table; -  u_int32_t table_id; -  afi_t afi; -  safi_t safi; -  unsigned i; - -  assert (zvrf); - -  zebra_vrf_delete_update (zvrf); - -  /* uninstall everything */ -  if (! CHECK_FLAG (zvrf->flags, ZEBRA_VRF_RETAIN)) -    { -      struct listnode *node; -      struct interface *ifp; +	struct zebra_vrf *zvrf = vrf->info; +	struct route_table *table; +	u_int32_t table_id; +	afi_t afi; +	safi_t safi; +	unsigned i; + +	assert(zvrf); + +	zebra_vrf_delete_update(zvrf); + +	/* uninstall everything */ +	if (!CHECK_FLAG(zvrf->flags, ZEBRA_VRF_RETAIN)) { +		struct listnode *node; +		struct interface *ifp; + +		for (afi = AFI_IP; afi <= AFI_IP6; afi++) { +			for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; +			     safi++) +				rib_close_table(zvrf->table[afi][safi]); + +			if (vrf->vrf_id == VRF_DEFAULT) +				for (table_id = 0; +				     table_id < ZEBRA_KERNEL_TABLE_MAX; +				     table_id++) +					if (zvrf->other_table[afi][table_id]) +						rib_close_table( +							zvrf->other_table +								[afi] +								[table_id]); +		} -      for (afi = AFI_IP; afi <= AFI_IP6; afi++) -	{ -	  for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) -	    rib_close_table (zvrf->table[afi][safi]); +		zebra_mpls_close_tables(zvrf); +		zebra_pw_exit(zvrf); -	  if (vrf->vrf_id == VRF_DEFAULT) -	    for (table_id = 0; table_id < ZEBRA_KERNEL_TABLE_MAX; table_id++) -	      if (zvrf->other_table[afi][table_id]) -		rib_close_table (zvrf->other_table[afi][table_id]); +		for (ALL_LIST_ELEMENTS_RO(vrf->iflist, node, ifp)) +			if_nbr_ipv6ll_to_ipv4ll_neigh_del_all(ifp);  	} -      zebra_mpls_close_tables (zvrf); -      zebra_pw_exit (zvrf); - -      for (ALL_LIST_ELEMENTS_RO (vrf->iflist, node, ifp)) -	if_nbr_ipv6ll_to_ipv4ll_neigh_del_all (ifp); -    } - -  /* clean-up work queues */ -  for (i = 0; i < MQ_SIZE; i++) -    { -      struct listnode *lnode, *nnode; -      struct route_node *rnode; -      rib_dest_t *dest; - -      for (ALL_LIST_ELEMENTS (zebrad.mq->subq[i], lnode, nnode, rnode)) -	{ -	  dest = rib_dest_from_rnode (rnode); -	  if (dest && rib_dest_vrf (dest) == zvrf) -	    { -	      route_unlock_node (rnode); -	      list_delete_node (zebrad.mq->subq[i], lnode); -	      zebrad.mq->size--; -	    } +	/* clean-up work queues */ +	for (i = 0; i < MQ_SIZE; i++) { +		struct listnode *lnode, *nnode; +		struct route_node *rnode; +		rib_dest_t *dest; + +		for (ALL_LIST_ELEMENTS(zebrad.mq->subq[i], lnode, nnode, +				       rnode)) { +			dest = rib_dest_from_rnode(rnode); +			if (dest && rib_dest_vrf(dest) == zvrf) { +				route_unlock_node(rnode); +				list_delete_node(zebrad.mq->subq[i], lnode); +				zebrad.mq->size--; +			} +		}  	} -    } -  /* release allocated memory */ -  for (afi = AFI_IP; afi <= AFI_IP6; afi++) -    { -      void *table_info; +	/* release allocated memory */ +	for (afi = AFI_IP; afi <= AFI_IP6; afi++) { +		void *table_info; -      for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) -	{ -	  table = zvrf->table[afi][safi]; -	  table_info = table->info; -	  route_table_finish (table); -	  XFREE (MTYPE_RIB_TABLE_INFO, table_info); +		for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) { +			table = zvrf->table[afi][safi]; +			table_info = table->info; +			route_table_finish(table); +			XFREE(MTYPE_RIB_TABLE_INFO, table_info); + +			table = zvrf->stable[afi][safi]; +			route_table_finish(table); +		} -	  table = zvrf->stable[afi][safi]; -	  route_table_finish (table); +		for (table_id = 0; table_id < ZEBRA_KERNEL_TABLE_MAX; +		     table_id++) +			if (zvrf->other_table[afi][table_id]) { +				table = zvrf->other_table[afi][table_id]; +				table_info = table->info; +				route_table_finish(table); +				XFREE(MTYPE_RIB_TABLE_INFO, table_info); +			} + +		route_table_finish(zvrf->rnh_table[afi]); +		route_table_finish(zvrf->import_check_table[afi]);  	} +	list_delete_all_node(zvrf->rid_all_sorted_list); +	list_delete_all_node(zvrf->rid_lo_sorted_list); +	XFREE(MTYPE_ZEBRA_VRF, zvrf); +	vrf->info = NULL; -      for (table_id = 0; table_id < ZEBRA_KERNEL_TABLE_MAX; table_id++) -	if (zvrf->other_table[afi][table_id]) -	  { -	    table = zvrf->other_table[afi][table_id]; -	    table_info = table->info; -	    route_table_finish (table); -	    XFREE (MTYPE_RIB_TABLE_INFO, table_info); -	  } - -      route_table_finish (zvrf->rnh_table[afi]); -      route_table_finish (zvrf->import_check_table[afi]); -    } -  list_delete_all_node (zvrf->rid_all_sorted_list); -  list_delete_all_node (zvrf->rid_lo_sorted_list); -  XFREE (MTYPE_ZEBRA_VRF, zvrf); -  vrf->info = NULL; - -  return 0; +	return 0;  }  /* Lookup the routing table in a VRF based on both VRF-Id and table-id.   * NOTE: Table-id is relevant only in the Default VRF.   */ -struct route_table * -zebra_vrf_table_with_table_id (afi_t afi, safi_t safi, -                               vrf_id_t vrf_id, u_int32_t table_id) +struct route_table *zebra_vrf_table_with_table_id(afi_t afi, safi_t safi, +						  vrf_id_t vrf_id, +						  u_int32_t table_id)  { -  struct route_table *table = NULL; - -  if (afi >= AFI_MAX || safi >= SAFI_MAX) -    return NULL; - -  if (vrf_id == VRF_DEFAULT) -    { -      if (table_id == RT_TABLE_MAIN || -          table_id == zebrad.rtm_table_default) -        table = zebra_vrf_table (afi, safi, vrf_id); -      else -        table = zebra_vrf_other_route_table (afi, table_id, vrf_id); -    } -  else -      table = zebra_vrf_table (afi, safi, vrf_id); - -  return table; +	struct route_table *table = NULL; + +	if (afi >= AFI_MAX || safi >= SAFI_MAX) +		return NULL; + +	if (vrf_id == VRF_DEFAULT) { +		if (table_id == RT_TABLE_MAIN +		    || table_id == zebrad.rtm_table_default) +			table = zebra_vrf_table(afi, safi, vrf_id); +		else +			table = zebra_vrf_other_route_table(afi, table_id, +							    vrf_id); +	} else +		table = zebra_vrf_table(afi, safi, vrf_id); + +	return table;  } -static void -zebra_rtable_node_cleanup (struct route_table *table, struct route_node *node) +static void zebra_rtable_node_cleanup(struct route_table *table, +				      struct route_node *node)  { -  struct rib *rib, *next; +	struct rib *rib, *next; -  RNODE_FOREACH_RIB_SAFE (node, rib, next) -    rib_unlink (node, rib); +	RNODE_FOREACH_RIB_SAFE(node, rib, next) +	rib_unlink(node, rib); -  if (node->info) -    XFREE (MTYPE_RIB_DEST, node->info); +	if (node->info) +		XFREE(MTYPE_RIB_DEST, node->info);  } -static void -zebra_stable_node_cleanup (struct route_table *table, struct route_node *node) +static void zebra_stable_node_cleanup(struct route_table *table, +				      struct route_node *node)  { -  struct static_route *si, *next; - -  if (node->info) -    for (si = node->info; si; si = next) -      { -	next = si->next; -	XFREE (MTYPE_STATIC_ROUTE, si); -      } +	struct static_route *si, *next; + +	if (node->info) +		for (si = node->info; si; si = next) { +			next = si->next; +			XFREE(MTYPE_STATIC_ROUTE, si); +		}  } -static void -zebra_rnhtable_node_cleanup (struct route_table *table, struct route_node *node) +static void zebra_rnhtable_node_cleanup(struct route_table *table, +					struct route_node *node)  { -  if (node->info) -    zebra_free_rnh (node->info); +	if (node->info) +		zebra_free_rnh(node->info);  }  /*   * Create a routing table for the specific AFI/SAFI in the given VRF.   */ -static void -zebra_vrf_table_create (struct zebra_vrf *zvrf, afi_t afi, safi_t safi) +static void zebra_vrf_table_create(struct zebra_vrf *zvrf, afi_t afi, +				   safi_t safi)  { -  rib_table_info_t *info; -  struct route_table *table; - -  assert (!zvrf->table[afi][safi]); - -  if (afi == AFI_IP6) -    table = srcdest_table_init(); -  else -    table = route_table_init(); -  table->cleanup = zebra_rtable_node_cleanup; -  zvrf->table[afi][safi] = table; - -  info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info)); -  info->zvrf = zvrf; -  info->afi = afi; -  info->safi = safi; -  table->info = info; +	rib_table_info_t *info; +	struct route_table *table; + +	assert(!zvrf->table[afi][safi]); + +	if (afi == AFI_IP6) +		table = srcdest_table_init(); +	else +		table = route_table_init(); +	table->cleanup = zebra_rtable_node_cleanup; +	zvrf->table[afi][safi] = table; + +	info = XCALLOC(MTYPE_RIB_TABLE_INFO, sizeof(*info)); +	info->zvrf = zvrf; +	info->afi = afi; +	info->safi = safi; +	table->info = info;  }  /* Allocate new zebra VRF. */ -struct zebra_vrf * -zebra_vrf_alloc (void) +struct zebra_vrf *zebra_vrf_alloc(void)  { -  struct zebra_vrf *zvrf; -  afi_t afi; -  safi_t safi; -  struct route_table *table; - -  zvrf = XCALLOC (MTYPE_ZEBRA_VRF, sizeof (struct zebra_vrf)); - -  for (afi = AFI_IP; afi <= AFI_IP6; afi++) -    { -      for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) -        { -          zebra_vrf_table_create (zvrf, afi, safi); -          if (afi == AFI_IP6) -            table = srcdest_table_init(); -          else -            table = route_table_init(); -          table->cleanup = zebra_stable_node_cleanup; -          zvrf->stable[afi][safi] = table; -        } - -      table = route_table_init(); -      table->cleanup = zebra_rnhtable_node_cleanup; -      zvrf->rnh_table[afi] = table; - -      table = route_table_init(); -      table->cleanup = zebra_rnhtable_node_cleanup; -      zvrf->import_check_table[afi] = table; -    } - -  zebra_mpls_init_tables (zvrf); -  zebra_pw_init (zvrf); - -  return zvrf; +	struct zebra_vrf *zvrf; +	afi_t afi; +	safi_t safi; +	struct route_table *table; + +	zvrf = XCALLOC(MTYPE_ZEBRA_VRF, sizeof(struct zebra_vrf)); + +	for (afi = AFI_IP; afi <= AFI_IP6; afi++) { +		for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) { +			zebra_vrf_table_create(zvrf, afi, safi); +			if (afi == AFI_IP6) +				table = srcdest_table_init(); +			else +				table = route_table_init(); +			table->cleanup = zebra_stable_node_cleanup; +			zvrf->stable[afi][safi] = table; +		} + +		table = route_table_init(); +		table->cleanup = zebra_rnhtable_node_cleanup; +		zvrf->rnh_table[afi] = table; + +		table = route_table_init(); +		table->cleanup = zebra_rnhtable_node_cleanup; +		zvrf->import_check_table[afi] = table; +	} + +	zebra_mpls_init_tables(zvrf); +	zebra_pw_init(zvrf); + +	return zvrf;  }  /* Lookup VRF by identifier.  */ -struct zebra_vrf * -zebra_vrf_lookup_by_id (vrf_id_t vrf_id) +struct zebra_vrf *zebra_vrf_lookup_by_id(vrf_id_t vrf_id)  { -  return vrf_info_lookup (vrf_id); +	return vrf_info_lookup(vrf_id);  }  /* Lookup VRF by name.  */ -struct zebra_vrf * -zebra_vrf_lookup_by_name (const char *name) +struct zebra_vrf *zebra_vrf_lookup_by_name(const char *name)  { -  struct vrf *vrf; +	struct vrf *vrf; -  if (!name) -    name = VRF_DEFAULT_NAME; +	if (!name) +		name = VRF_DEFAULT_NAME; -  vrf = vrf_lookup_by_name (name); -  if (vrf) -    return ((struct zebra_vrf *) vrf->info); +	vrf = vrf_lookup_by_name(name); +	if (vrf) +		return ((struct zebra_vrf *)vrf->info); -  return NULL; +	return NULL;  }  /* Lookup the routing table in an enabled VRF. */ -struct route_table * -zebra_vrf_table (afi_t afi, safi_t safi, vrf_id_t vrf_id) +struct route_table *zebra_vrf_table(afi_t afi, safi_t safi, vrf_id_t vrf_id)  { -  struct zebra_vrf *zvrf = vrf_info_lookup (vrf_id); +	struct zebra_vrf *zvrf = vrf_info_lookup(vrf_id); -  if (!zvrf) -    return NULL; +	if (!zvrf) +		return NULL; -  if (afi >= AFI_MAX || safi >= SAFI_MAX) -    return NULL; +	if (afi >= AFI_MAX || safi >= SAFI_MAX) +		return NULL; -  return zvrf->table[afi][safi]; +	return zvrf->table[afi][safi];  }  /* Lookup the static routing table in a VRF. */ -struct route_table * -zebra_vrf_static_table (afi_t afi, safi_t safi, struct zebra_vrf *zvrf) +struct route_table *zebra_vrf_static_table(afi_t afi, safi_t safi, +					   struct zebra_vrf *zvrf)  { -  if (!zvrf) -    return NULL; +	if (!zvrf) +		return NULL; -  if (afi >= AFI_MAX || safi >= SAFI_MAX) -    return NULL; +	if (afi >= AFI_MAX || safi >= SAFI_MAX) +		return NULL; -  return zvrf->stable[afi][safi]; +	return zvrf->stable[afi][safi];  } -struct route_table * -zebra_vrf_other_route_table (afi_t afi, u_int32_t table_id, vrf_id_t vrf_id) +struct route_table *zebra_vrf_other_route_table(afi_t afi, u_int32_t table_id, +						vrf_id_t vrf_id)  { -  struct zebra_vrf *zvrf; -  rib_table_info_t *info; -  struct route_table *table; - -  zvrf = vrf_info_lookup (vrf_id); -  if (! zvrf) -    return NULL; - -  if(afi >= AFI_MAX) -    return NULL; - -  if (table_id >= ZEBRA_KERNEL_TABLE_MAX) -    return NULL; - -  if ((vrf_id == VRF_DEFAULT) && (table_id != RT_TABLE_MAIN) && (table_id != zebrad.rtm_table_default)) -    { -      if (zvrf->other_table[afi][table_id] == NULL) -        { -          table = (afi == AFI_IP6) ? srcdest_table_init() : route_table_init(); -          info = XCALLOC (MTYPE_RIB_TABLE_INFO, sizeof (*info)); -          info->zvrf = zvrf; -          info->afi = afi; -          info->safi = SAFI_UNICAST; -          table->info = info; -          zvrf->other_table[afi][table_id] = table; -        } - -      return (zvrf->other_table[afi][table_id]); -    } - -  return zvrf->table[afi][SAFI_UNICAST]; +	struct zebra_vrf *zvrf; +	rib_table_info_t *info; +	struct route_table *table; + +	zvrf = vrf_info_lookup(vrf_id); +	if (!zvrf) +		return NULL; + +	if (afi >= AFI_MAX) +		return NULL; + +	if (table_id >= ZEBRA_KERNEL_TABLE_MAX) +		return NULL; + +	if ((vrf_id == VRF_DEFAULT) && (table_id != RT_TABLE_MAIN) +	    && (table_id != zebrad.rtm_table_default)) { +		if (zvrf->other_table[afi][table_id] == NULL) { +			table = (afi == AFI_IP6) ? srcdest_table_init() +						 : route_table_init(); +			info = XCALLOC(MTYPE_RIB_TABLE_INFO, sizeof(*info)); +			info->zvrf = zvrf; +			info->afi = afi; +			info->safi = SAFI_UNICAST; +			table->info = info; +			zvrf->other_table[afi][table_id] = table; +		} + +		return (zvrf->other_table[afi][table_id]); +	} + +	return zvrf->table[afi][SAFI_UNICAST];  } -static int -vrf_config_write (struct vty *vty) +static int vrf_config_write(struct vty *vty)  { -  struct vrf *vrf; -  struct zebra_vrf *zvrf; - -  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) -    { -      zvrf = vrf->info; -      if (! zvrf || strcmp (zvrf_name (zvrf), VRF_DEFAULT_NAME)) -        { -          vty_out (vty, "vrf %s%s", zvrf_name (zvrf), VTY_NEWLINE); -          vty_out (vty, "!%s", VTY_NEWLINE); -        } -    } -  return 0; +	struct vrf *vrf; +	struct zebra_vrf *zvrf; + +	RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) +	{ +		zvrf = vrf->info; +		if (!zvrf || strcmp(zvrf_name(zvrf), VRF_DEFAULT_NAME)) { +			vty_out(vty, "vrf %s%s", zvrf_name(zvrf), VTY_NEWLINE); +			vty_out(vty, "!%s", VTY_NEWLINE); +		} +	} +	return 0;  }  /* Zebra VRF initialization. */ -void -zebra_vrf_init (void) +void zebra_vrf_init(void)  { -  vrf_add_hook (VRF_NEW_HOOK, zebra_vrf_new); -  vrf_add_hook (VRF_ENABLE_HOOK, zebra_vrf_enable); -  vrf_add_hook (VRF_DISABLE_HOOK, zebra_vrf_disable); -  vrf_add_hook (VRF_DELETE_HOOK, zebra_vrf_delete); +	vrf_add_hook(VRF_NEW_HOOK, zebra_vrf_new); +	vrf_add_hook(VRF_ENABLE_HOOK, zebra_vrf_enable); +	vrf_add_hook(VRF_DISABLE_HOOK, zebra_vrf_disable); +	vrf_add_hook(VRF_DELETE_HOOK, zebra_vrf_delete); -  vrf_init (); -  vrf_cmd_init (vrf_config_write); +	vrf_init(); +	vrf_cmd_init(vrf_config_write);  } diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h index cfe7cde75c..44887643d6 100644 --- a/zebra/zebra_vrf.h +++ b/zebra/zebra_vrf.h @@ -27,91 +27,89 @@  #include <zebra/zebra_pw.h>  /* Routing table instance.  */ -struct zebra_vrf -{ -  /* Back pointer */ -  struct vrf *vrf; +struct zebra_vrf { +	/* Back pointer */ +	struct vrf *vrf; -  /* Description.  */ -  char *desc; +	/* Description.  */ +	char *desc; -  /* FIB identifier.  */ -  u_char fib_id; +	/* FIB identifier.  */ +	u_char fib_id; -  /* Flags. */ -  u_int16_t flags; +	/* Flags. */ +	u_int16_t flags;  #define ZEBRA_VRF_RIB_SCHEDULED   (1 << 0)  #define ZEBRA_VRF_RETAIN          (2 << 0) -  u_int32_t table_id; +	u_int32_t table_id; -  /* Routing table.  */ -  struct route_table *table[AFI_MAX][SAFI_MAX]; +	/* Routing table.  */ +	struct route_table *table[AFI_MAX][SAFI_MAX]; -  /* Static route configuration.  */ -  struct route_table *stable[AFI_MAX][SAFI_MAX]; +	/* Static route configuration.  */ +	struct route_table *stable[AFI_MAX][SAFI_MAX]; -  /* Recursive Nexthop table */ -  struct route_table *rnh_table[AFI_MAX]; +	/* Recursive Nexthop table */ +	struct route_table *rnh_table[AFI_MAX]; -  /* Import check table (used mostly by BGP */ -  struct route_table *import_check_table[AFI_MAX]; +	/* Import check table (used mostly by BGP */ +	struct route_table *import_check_table[AFI_MAX]; -  /* Routing tables off of main table for redistribute table */ -  struct route_table *other_table[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; +	/* Routing tables off of main table for redistribute table */ +	struct route_table *other_table[AFI_MAX][ZEBRA_KERNEL_TABLE_MAX]; -  /* 2nd pointer type used primarily to quell a warning on -   * ALL_LIST_ELEMENTS_RO -   */ -  struct list _rid_all_sorted_list; -  struct list _rid_lo_sorted_list; -  struct list *rid_all_sorted_list; -  struct list *rid_lo_sorted_list; -  struct prefix rid_user_assigned; +	/* 2nd pointer type used primarily to quell a warning on +	 * ALL_LIST_ELEMENTS_RO +	 */ +	struct list _rid_all_sorted_list; +	struct list _rid_lo_sorted_list; +	struct list *rid_all_sorted_list; +	struct list *rid_lo_sorted_list; +	struct prefix rid_user_assigned; -  /* -   * Back pointer to the owning namespace. -   */ -  struct zebra_ns *zns; +	/* +	 * Back pointer to the owning namespace. +	 */ +	struct zebra_ns *zns; -  /* MPLS static LSP config table */ -  struct hash *slsp_table; +	/* MPLS static LSP config table */ +	struct hash *slsp_table; -  /* MPLS label forwarding table */ -  struct hash *lsp_table; +	/* MPLS label forwarding table */ +	struct hash *lsp_table; -  /* Pseudowires. */ -  struct zebra_pw_head pseudowires; -  struct zebra_static_pw_head static_pseudowires; +	/* Pseudowires. */ +	struct zebra_pw_head pseudowires; +	struct zebra_static_pw_head static_pseudowires; -  /* MPLS processing flags */ -  u_int16_t mpls_flags; +	/* MPLS processing flags */ +	u_int16_t mpls_flags;  #define MPLS_FLAG_SCHEDULE_LSPS    (1 << 0)  }; -static inline vrf_id_t -zvrf_id (struct zebra_vrf *zvrf) +static inline vrf_id_t zvrf_id(struct zebra_vrf *zvrf)  { -  return zvrf->vrf->vrf_id; +	return zvrf->vrf->vrf_id;  } -static inline const char * -zvrf_name (struct zebra_vrf *zvrf) +static inline const char *zvrf_name(struct zebra_vrf *zvrf)  { -  return zvrf->vrf->name; +	return zvrf->vrf->name;  } -struct route_table * -zebra_vrf_table_with_table_id (afi_t afi, safi_t safi, -                               vrf_id_t vrf_id, u_int32_t table_id); - -extern void zebra_vrf_update_all (struct zserv *client); -extern struct zebra_vrf *zebra_vrf_lookup_by_id (vrf_id_t vrf_id); -extern struct zebra_vrf *zebra_vrf_lookup_by_name (const char *); -extern struct zebra_vrf *zebra_vrf_alloc (void); -extern struct route_table *zebra_vrf_table (afi_t, safi_t, vrf_id_t); -extern struct route_table *zebra_vrf_static_table (afi_t, safi_t, struct zebra_vrf *zvrf); -extern struct route_table *zebra_vrf_other_route_table (afi_t afi, u_int32_t table_id, -							vrf_id_t vrf_id); -extern void zebra_vrf_init (void); +struct route_table *zebra_vrf_table_with_table_id(afi_t afi, safi_t safi, +						  vrf_id_t vrf_id, +						  u_int32_t table_id); + +extern void zebra_vrf_update_all(struct zserv *client); +extern struct zebra_vrf *zebra_vrf_lookup_by_id(vrf_id_t vrf_id); +extern struct zebra_vrf *zebra_vrf_lookup_by_name(const char *); +extern struct zebra_vrf *zebra_vrf_alloc(void); +extern struct route_table *zebra_vrf_table(afi_t, safi_t, vrf_id_t); +extern struct route_table *zebra_vrf_static_table(afi_t, safi_t, +						  struct zebra_vrf *zvrf); +extern struct route_table * +zebra_vrf_other_route_table(afi_t afi, u_int32_t table_id, vrf_id_t vrf_id); +extern void zebra_vrf_init(void);  #endif diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index aeb01be070..9e27d7a43d 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -45,160 +45,156 @@  extern int allow_delete; -static int do_show_ip_route(struct vty *vty, const char *vrf_name, -                            safi_t safi, u_char use_json); -static void vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, -                                      int mcast); +static int do_show_ip_route(struct vty *vty, const char *vrf_name, safi_t safi, +			    u_char use_json); +static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn, +				     int mcast);  #define ONE_DAY_SECOND 60*60*24  #define ONE_WEEK_SECOND 60*60*24*7  /* General function for static route. */ -int -zebra_static_ipv4 (struct vty *vty, safi_t safi, int add_cmd, -		   const char *dest_str, const char *mask_str, -		   const char *gate_str, const char *flag_str, -		   const char *tag_str, const char *distance_str, -		   const char *vrf_id_str, const char *label_str) -{ -  int ret; -  u_char distance; -  struct prefix p; -  struct in_addr gate; -  struct in_addr mask; -  u_char flag = 0; -  route_tag_t tag = 0; -  struct zebra_vrf *zvrf = NULL; -  const char *ifname = NULL; -  u_char type = STATIC_BLACKHOLE; -  struct static_nh_label snh_label; - -  memset (&snh_label, 0, sizeof (struct static_nh_label)); -  ret = str2prefix (dest_str, &p); -  if (ret <= 0) -    { -      vty_out (vty, "%% Malformed address%s", VTY_NEWLINE); -      return CMD_WARNING; -    } - -  /* Cisco like mask notation. */ -  if (mask_str) -    { -      ret = inet_aton (mask_str, &mask); -      if (ret == 0) -        { -          vty_out (vty, "%% Malformed address%s", VTY_NEWLINE); -          return CMD_WARNING; -        } -      p.prefixlen = ip_masklen (mask); -    } - -  /* Apply mask for given prefix. */ -  apply_mask (&p); - -  /* Administrative distance. */ -  if (distance_str) -    distance = atoi (distance_str); -  else -    distance = ZEBRA_STATIC_DISTANCE_DEFAULT; - -  /* tag */ -  if (tag_str) -    VTY_GET_INTEGER_RANGE("tag", tag, tag_str, 0, 4294967295); - -  /* VRF id */ -  zvrf = zebra_vrf_lookup_by_name (vrf_id_str); - -  if (!zvrf) -    { -      vty_out (vty, "%% vrf %s is not defined%s", vrf_id_str, VTY_NEWLINE); -      return CMD_WARNING; -    } - -  /* Labels */ -  if (label_str) -    { -      if (!mpls_enabled) -	{ -	  vty_out (vty, "%% MPLS not turned on in kernel, ignoring command%s", -		   VTY_NEWLINE); -	  return CMD_WARNING; -	} -      if (mpls_str2label (label_str, &snh_label.num_labels, -                          snh_label.label)) -        { -          vty_out (vty, "%% Malformed label(s)%s", VTY_NEWLINE); -          return CMD_WARNING; -        } -    } - -  /* Null0 static route.  */ -  if ((gate_str != NULL) && (strncasecmp (gate_str, "Null0", strlen (gate_str)) == 0)) -    { -      if (flag_str) -        { -          vty_out (vty, "%% can not have flag %s with Null0%s", flag_str, VTY_NEWLINE); -          return CMD_WARNING; -        } -      if (add_cmd) -        static_add_route (AFI_IP, safi, type, &p, NULL, NULL, ifname, -			  ZEBRA_FLAG_BLACKHOLE, tag, distance, zvrf, &snh_label); -      else -        static_delete_route (AFI_IP, safi, type, &p, NULL, NULL, ifname, tag, -			     distance, zvrf, &snh_label); -      return CMD_SUCCESS; -    } - -  /* Route flags */ -  if (flag_str) { -    switch(flag_str[0]) { -      case 'r': -      case 'R': /* XXX */ -        SET_FLAG (flag, ZEBRA_FLAG_REJECT); -        break; -      case 'b': -      case 'B': /* XXX */ -        SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE); -        break; -      default: -        vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE); -        return CMD_WARNING; -    } -  } - -  if (gate_str == NULL) -  { -    if (add_cmd) -      static_add_route (AFI_IP, safi, type, &p, NULL, NULL, ifname, flag, -			tag, distance, zvrf, &snh_label); -    else -      static_delete_route (AFI_IP, safi, type, &p, NULL, NULL, ifname, tag, -			   distance, zvrf, &snh_label); - -    return CMD_SUCCESS; -  } - -  /* When gateway is A.B.C.D format, gate is treated as nexthop -     address other case gate is treated as interface name. */ -  ret = inet_aton (gate_str, &gate); -  if (!ret) -    { -      ifname = gate_str; -      type = STATIC_IFNAME; -    } -  else -    type = STATIC_IPV4_GATEWAY; - -  if (add_cmd) -    static_add_route (AFI_IP, safi, type, &p, NULL, -		      ret ? (union g_addr *)&gate : NULL, ifname, -		      flag, tag, distance, zvrf, &snh_label); -  else -    static_delete_route (AFI_IP, safi, type, &p, NULL, -			 ret ? (union g_addr *)&gate : NULL, ifname, tag, -			 distance, zvrf, &snh_label); - -  return CMD_SUCCESS; +int zebra_static_ipv4(struct vty *vty, safi_t safi, int add_cmd, +		      const char *dest_str, const char *mask_str, +		      const char *gate_str, const char *flag_str, +		      const char *tag_str, const char *distance_str, +		      const char *vrf_id_str, const char *label_str) +{ +	int ret; +	u_char distance; +	struct prefix p; +	struct in_addr gate; +	struct in_addr mask; +	u_char flag = 0; +	route_tag_t tag = 0; +	struct zebra_vrf *zvrf = NULL; +	const char *ifname = NULL; +	u_char type = STATIC_BLACKHOLE; +	struct static_nh_label snh_label; + +	memset(&snh_label, 0, sizeof(struct static_nh_label)); +	ret = str2prefix(dest_str, &p); +	if (ret <= 0) { +		vty_out(vty, "%% Malformed address%s", VTY_NEWLINE); +		return CMD_WARNING; +	} + +	/* Cisco like mask notation. */ +	if (mask_str) { +		ret = inet_aton(mask_str, &mask); +		if (ret == 0) { +			vty_out(vty, "%% Malformed address%s", VTY_NEWLINE); +			return CMD_WARNING; +		} +		p.prefixlen = ip_masklen(mask); +	} + +	/* Apply mask for given prefix. */ +	apply_mask(&p); + +	/* Administrative distance. */ +	if (distance_str) +		distance = atoi(distance_str); +	else +		distance = ZEBRA_STATIC_DISTANCE_DEFAULT; + +	/* tag */ +	if (tag_str) +		VTY_GET_INTEGER_RANGE("tag", tag, tag_str, 0, 4294967295); + +	/* VRF id */ +	zvrf = zebra_vrf_lookup_by_name(vrf_id_str); + +	if (!zvrf) { +		vty_out(vty, "%% vrf %s is not defined%s", vrf_id_str, +			VTY_NEWLINE); +		return CMD_WARNING; +	} + +	/* Labels */ +	if (label_str) { +		if (!mpls_enabled) { +			vty_out(vty, +				"%% MPLS not turned on in kernel, ignoring command%s", +				VTY_NEWLINE); +			return CMD_WARNING; +		} +		if (mpls_str2label(label_str, &snh_label.num_labels, +				   snh_label.label)) { +			vty_out(vty, "%% Malformed label(s)%s", VTY_NEWLINE); +			return CMD_WARNING; +		} +	} + +	/* Null0 static route.  */ +	if ((gate_str != NULL) +	    && (strncasecmp(gate_str, "Null0", strlen(gate_str)) == 0)) { +		if (flag_str) { +			vty_out(vty, "%% can not have flag %s with Null0%s", +				flag_str, VTY_NEWLINE); +			return CMD_WARNING; +		} +		if (add_cmd) +			static_add_route(AFI_IP, safi, type, &p, NULL, NULL, +					 ifname, ZEBRA_FLAG_BLACKHOLE, tag, +					 distance, zvrf, &snh_label); +		else +			static_delete_route(AFI_IP, safi, type, &p, NULL, NULL, +					    ifname, tag, distance, zvrf, +					    &snh_label); +		return CMD_SUCCESS; +	} + +	/* Route flags */ +	if (flag_str) { +		switch (flag_str[0]) { +		case 'r': +		case 'R': /* XXX */ +			SET_FLAG(flag, ZEBRA_FLAG_REJECT); +			break; +		case 'b': +		case 'B': /* XXX */ +			SET_FLAG(flag, ZEBRA_FLAG_BLACKHOLE); +			break; +		default: +			vty_out(vty, "%% Malformed flag %s %s", flag_str, +				VTY_NEWLINE); +			return CMD_WARNING; +		} +	} + +	if (gate_str == NULL) { +		if (add_cmd) +			static_add_route(AFI_IP, safi, type, &p, NULL, NULL, +					 ifname, flag, tag, distance, zvrf, +					 &snh_label); +		else +			static_delete_route(AFI_IP, safi, type, &p, NULL, NULL, +					    ifname, tag, distance, zvrf, +					    &snh_label); + +		return CMD_SUCCESS; +	} + +	/* When gateway is A.B.C.D format, gate is treated as nexthop +	   address other case gate is treated as interface name. */ +	ret = inet_aton(gate_str, &gate); +	if (!ret) { +		ifname = gate_str; +		type = STATIC_IFNAME; +	} else +		type = STATIC_IPV4_GATEWAY; + +	if (add_cmd) +		static_add_route(AFI_IP, safi, type, &p, NULL, +				 ret ? (union g_addr *)&gate : NULL, ifname, +				 flag, tag, distance, zvrf, &snh_label); +	else +		static_delete_route(AFI_IP, safi, type, &p, NULL, +				    ret ? (union g_addr *)&gate : NULL, ifname, +				    tag, distance, zvrf, &snh_label); + +	return CMD_SUCCESS;  }  /* Static unicast routes for multicast RPF lookup. */ @@ -212,11 +208,12 @@ DEFUN (ip_mroute_dist,         "Nexthop interface name\n"         "Distance\n")  { -  char *destprefix = argv[2]->arg; -  char *nexthop = argv[3]->arg; -  char *distance = (argc == 5) ? argv[4]->arg : NULL; +	char *destprefix = argv[2]->arg; +	char *nexthop = argv[3]->arg; +	char *distance = (argc == 5) ? argv[4]->arg : NULL; -  return zebra_static_ipv4 (vty, SAFI_MULTICAST, 1, destprefix, NULL, nexthop, NULL, NULL, distance, NULL, NULL); +	return zebra_static_ipv4(vty, SAFI_MULTICAST, 1, destprefix, NULL, +				 nexthop, NULL, NULL, distance, NULL, NULL);  }  DEFUN (no_ip_mroute_dist, @@ -230,11 +227,12 @@ DEFUN (no_ip_mroute_dist,         "Nexthop interface name\n"         "Distance\n")  { -  char *destprefix = argv[3]->arg; -  char *nexthop = argv[4]->arg; -  char *distance = (argc == 6) ? argv[5]->arg : NULL; +	char *destprefix = argv[3]->arg; +	char *nexthop = argv[4]->arg; +	char *distance = (argc == 6) ? argv[5]->arg : NULL; -  return zebra_static_ipv4 (vty, SAFI_MULTICAST, 0, destprefix, NULL, nexthop, NULL, NULL, distance, NULL, NULL); +	return zebra_static_ipv4(vty, SAFI_MULTICAST, 0, destprefix, NULL, +				 nexthop, NULL, NULL, distance, NULL, NULL);  }  DEFUN (ip_multicast_mode, @@ -249,25 +247,24 @@ DEFUN (ip_multicast_mode,         "Lookup both, use entry with lower distance\n"         "Lookup both, use entry with longer prefix\n")  { -  char *mode = argv[3]->text; - -  if (strmatch (mode, "urib-only")) -    multicast_mode_ipv4_set (MCAST_URIB_ONLY); -  else if (strmatch (mode, "mrib-only")) -    multicast_mode_ipv4_set (MCAST_MRIB_ONLY); -  else if (strmatch (mode, "mrib-then-urib")) -    multicast_mode_ipv4_set (MCAST_MIX_MRIB_FIRST); -  else if (strmatch (mode, "lower-distance")) -    multicast_mode_ipv4_set (MCAST_MIX_DISTANCE); -  else if (strmatch (mode, "longer-prefix")) -    multicast_mode_ipv4_set (MCAST_MIX_PFXLEN); -  else -    { -      vty_out (vty, "Invalid mode specified%s", VTY_NEWLINE); -      return CMD_WARNING; -    } +	char *mode = argv[3]->text; + +	if (strmatch(mode, "urib-only")) +		multicast_mode_ipv4_set(MCAST_URIB_ONLY); +	else if (strmatch(mode, "mrib-only")) +		multicast_mode_ipv4_set(MCAST_MRIB_ONLY); +	else if (strmatch(mode, "mrib-then-urib")) +		multicast_mode_ipv4_set(MCAST_MIX_MRIB_FIRST); +	else if (strmatch(mode, "lower-distance")) +		multicast_mode_ipv4_set(MCAST_MIX_DISTANCE); +	else if (strmatch(mode, "longer-prefix")) +		multicast_mode_ipv4_set(MCAST_MIX_PFXLEN); +	else { +		vty_out(vty, "Invalid mode specified%s", VTY_NEWLINE); +		return CMD_WARNING; +	} -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (no_ip_multicast_mode, @@ -283,8 +280,8 @@ DEFUN (no_ip_multicast_mode,         "Lookup both, use entry with lower distance\n"         "Lookup both, use entry with longer prefix\n")  { -  multicast_mode_ipv4_set (MCAST_NO_CONFIG); -  return CMD_SUCCESS; +	multicast_mode_ipv4_set(MCAST_NO_CONFIG); +	return CMD_SUCCESS;  } @@ -295,7 +292,7 @@ DEFUN (show_ip_rpf,         IP_STR         "Display RPF information for multicast source\n")  { -  return do_show_ip_route(vty, VRF_DEFAULT_NAME, SAFI_MULTICAST, 0); +	return do_show_ip_route(vty, VRF_DEFAULT_NAME, SAFI_MULTICAST, 0);  }  DEFUN (show_ip_rpf_addr, @@ -306,64 +303,55 @@ DEFUN (show_ip_rpf_addr,         "Display RPF information for multicast source\n"         "IP multicast source address (e.g. 10.0.0.0)\n")  { -  int idx_ipv4 = 3; -  struct in_addr addr; -  struct route_node *rn; -  struct rib *rib; -  int ret; - -  ret = inet_aton (argv[idx_ipv4]->arg, &addr); -  if (ret == 0) -    { -      vty_out (vty, "%% Malformed address%s", VTY_NEWLINE); -      return CMD_WARNING; -    } - -  rib = rib_match_ipv4_multicast (VRF_DEFAULT, addr, &rn); - -  if (rib) -    vty_show_ip_route_detail (vty, rn, 1); -  else -    vty_out (vty, "%% No match for RPF lookup%s", VTY_NEWLINE); - -  return CMD_SUCCESS; -} - -static void -zebra_vty_ip_route_tdv_helper (int argc, struct cmd_token *argv[], -			       int idx_curr, char **tag, -			       char **distance, char **vrf, char **labels) -{ -  *distance = NULL; -  while (idx_curr < argc) -  { -    if (strmatch (argv[idx_curr]->text, "tag")) -      { -        if (tag) -          *tag = argv[idx_curr+1]->arg; -        idx_curr += 2; -      } -    else if (strmatch (argv[idx_curr]->text, "vrf")) -      { -        if (vrf) -          *vrf = argv[idx_curr+1]->arg; -        idx_curr += 2; -      } -    else if (strmatch (argv[idx_curr]->text, "label")) -      { -        if (labels) -          *labels = argv[idx_curr+1]->arg; -        idx_curr += 2; -      } -    else -      { -        if (distance) -          *distance = argv[idx_curr]->arg; -        idx_curr++; -      } -  } - -  return; +	int idx_ipv4 = 3; +	struct in_addr addr; +	struct route_node *rn; +	struct rib *rib; +	int ret; + +	ret = inet_aton(argv[idx_ipv4]->arg, &addr); +	if (ret == 0) { +		vty_out(vty, "%% Malformed address%s", VTY_NEWLINE); +		return CMD_WARNING; +	} + +	rib = rib_match_ipv4_multicast(VRF_DEFAULT, addr, &rn); + +	if (rib) +		vty_show_ip_route_detail(vty, rn, 1); +	else +		vty_out(vty, "%% No match for RPF lookup%s", VTY_NEWLINE); + +	return CMD_SUCCESS; +} + +static void zebra_vty_ip_route_tdv_helper(int argc, struct cmd_token *argv[], +					  int idx_curr, char **tag, +					  char **distance, char **vrf, +					  char **labels) +{ +	*distance = NULL; +	while (idx_curr < argc) { +		if (strmatch(argv[idx_curr]->text, "tag")) { +			if (tag) +				*tag = argv[idx_curr + 1]->arg; +			idx_curr += 2; +		} else if (strmatch(argv[idx_curr]->text, "vrf")) { +			if (vrf) +				*vrf = argv[idx_curr + 1]->arg; +			idx_curr += 2; +		} else if (strmatch(argv[idx_curr]->text, "label")) { +			if (labels) +				*labels = argv[idx_curr + 1]->arg; +			idx_curr += 2; +		} else { +			if (distance) +				*distance = argv[idx_curr]->arg; +			idx_curr++; +		} +	} + +	return;  }  /* Static route configuration.  */ @@ -381,20 +369,19 @@ DEFUN (ip_route,         "Distance value for this route\n"         VRF_CMD_HELP_STR)  { -  int idx_ipv4_prefixlen = 2; -  int idx_ipv4_ifname_null = 3; -  int idx_curr = 4; -  char *tag, *distance, *vrf; +	int idx_ipv4_prefixlen = 2; +	int idx_ipv4_ifname_null = 3; +	int idx_curr = 4; +	char *tag, *distance, *vrf; -  tag = distance = vrf = NULL; -  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); +	tag = distance = vrf = NULL; +	zebra_vty_ip_route_tdv_helper(argc, argv, idx_curr, &tag, &distance, +				      &vrf, NULL); -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, -			    argv[idx_ipv4_prefixlen]->arg, -			    NULL, -			    argv[idx_ipv4_ifname_null]->arg, -			    NULL, -			    tag, distance, vrf, NULL); +	return zebra_static_ipv4(vty, SAFI_UNICAST, 1, +				 argv[idx_ipv4_prefixlen]->arg, NULL, +				 argv[idx_ipv4_ifname_null]->arg, NULL, tag, +				 distance, vrf, NULL);  }  DEFUN (ip_route_flags, @@ -412,20 +399,18 @@ DEFUN (ip_route_flags,         "Specify labels for this route\n"         "One or more labels separated by '/'\n")  { -  int idx_ipv4_prefixlen = 2; -  int idx_reject_blackhole = 3; -  int idx_curr = 4; -  char *tag, *distance, *vrf; +	int idx_ipv4_prefixlen = 2; +	int idx_reject_blackhole = 3; +	int idx_curr = 4; +	char *tag, *distance, *vrf; -  tag = distance = vrf = NULL; -  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); +	tag = distance = vrf = NULL; +	zebra_vty_ip_route_tdv_helper(argc, argv, idx_curr, &tag, &distance, +				      &vrf, NULL); -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, -			    argv[idx_ipv4_prefixlen]->arg, -			    NULL, -			    NULL, -			    argv[idx_reject_blackhole]->arg, -			    tag, distance, vrf, NULL); +	return zebra_static_ipv4( +		vty, SAFI_UNICAST, 1, argv[idx_ipv4_prefixlen]->arg, NULL, NULL, +		argv[idx_reject_blackhole]->arg, tag, distance, vrf, NULL);  }  /* Mask as A.B.C.D format.  */ @@ -446,20 +431,20 @@ DEFUN (ip_route_mask,         "Specify labels for this route\n"         "One or more labels separated by '/'\n")  { -  int idx_ipv4 = 2; -  int idx_ipv4_2 = 3; -  int idx_ipv4_ifname_null = 4; -  int idx_curr = 5; -  char *tag, *distance, *vrf; +	int idx_ipv4 = 2; +	int idx_ipv4_2 = 3; +	int idx_ipv4_ifname_null = 4; +	int idx_curr = 5; +	char *tag, *distance, *vrf; -  tag = distance = vrf = NULL; -  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); +	tag = distance = vrf = NULL; +	zebra_vty_ip_route_tdv_helper(argc, argv, idx_curr, &tag, &distance, +				      &vrf, NULL); -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, -			    argv[idx_ipv4]->arg, -			    argv[idx_ipv4_2]->arg, -			    argv[idx_ipv4_ifname_null]->arg, -			    NULL, tag, distance, vrf, NULL); +	return zebra_static_ipv4(vty, SAFI_UNICAST, 1, argv[idx_ipv4]->arg, +				 argv[idx_ipv4_2]->arg, +				 argv[idx_ipv4_ifname_null]->arg, NULL, tag, +				 distance, vrf, NULL);  }  DEFUN (ip_route_mask_flags, @@ -478,21 +463,20 @@ DEFUN (ip_route_mask_flags,         "Specify labels for this route\n"         "One or more labels separated by '/'\n")  { -  int idx_ipv4 = 2; -  int idx_ipv4_2 = 3; -  int idx_reject_blackhole = 4; -  int idx_curr = 5; -  char *tag, *distance, *vrf; +	int idx_ipv4 = 2; +	int idx_ipv4_2 = 3; +	int idx_reject_blackhole = 4; +	int idx_curr = 5; +	char *tag, *distance, *vrf; -  tag = distance = vrf = NULL; -  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); +	tag = distance = vrf = NULL; +	zebra_vty_ip_route_tdv_helper(argc, argv, idx_curr, &tag, &distance, +				      &vrf, NULL); -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 1, -			    argv[idx_ipv4]->arg, -			    argv[idx_ipv4_2]->arg, -			    NULL, -			    argv[idx_reject_blackhole]->arg, -			    tag, distance, vrf, NULL); +	return zebra_static_ipv4(vty, SAFI_UNICAST, 1, argv[idx_ipv4]->arg, +				 argv[idx_ipv4_2]->arg, NULL, +				 argv[idx_reject_blackhole]->arg, tag, distance, +				 vrf, NULL);  }  DEFUN (no_ip_route, @@ -512,20 +496,19 @@ DEFUN (no_ip_route,         "Specify labels for this route\n"         "One or more labels separated by '/'\n")  { -  int idx_ipv4_prefixlen = 3; -  int idx_ipv4_ifname_null = 4; -  int idx_curr = 5; -  char *tag, *distance, *vrf; +	int idx_ipv4_prefixlen = 3; +	int idx_ipv4_ifname_null = 4; +	int idx_curr = 5; +	char *tag, *distance, *vrf; -  tag = distance = vrf = NULL; -  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); +	tag = distance = vrf = NULL; +	zebra_vty_ip_route_tdv_helper(argc, argv, idx_curr, &tag, &distance, +				      &vrf, NULL); -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, -			    argv[idx_ipv4_prefixlen]->arg, -			    NULL, -			    argv[idx_ipv4_ifname_null]->arg, -			    NULL, -			    tag, distance, vrf, NULL); +	return zebra_static_ipv4(vty, SAFI_UNICAST, 0, +				 argv[idx_ipv4_prefixlen]->arg, NULL, +				 argv[idx_ipv4_ifname_null]->arg, NULL, tag, +				 distance, vrf, NULL);  }  DEFUN (no_ip_route_flags, @@ -544,17 +527,17 @@ DEFUN (no_ip_route_flags,         "Specify labels for this route\n"         "One or more labels separated by '/'\n")  { -  int idx_ipv4_prefixlen = 3; -  int idx_curr = 5; -  char *tag, *distance, *vrf; +	int idx_ipv4_prefixlen = 3; +	int idx_curr = 5; +	char *tag, *distance, *vrf; -  tag = distance = vrf = NULL; -  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); +	tag = distance = vrf = NULL; +	zebra_vty_ip_route_tdv_helper(argc, argv, idx_curr, &tag, &distance, +				      &vrf, NULL); -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, -			    argv[idx_ipv4_prefixlen]->arg, -			    NULL, NULL, NULL, -			    tag, distance, vrf, NULL); +	return zebra_static_ipv4(vty, SAFI_UNICAST, 0, +				 argv[idx_ipv4_prefixlen]->arg, NULL, NULL, +				 NULL, tag, distance, vrf, NULL);  }  DEFUN (no_ip_route_mask, @@ -575,21 +558,20 @@ DEFUN (no_ip_route_mask,         "Specify labels for this route\n"         "One or more labels separated by '/'\n")  { -  int idx_ipv4 = 3; -  int idx_ipv4_2 = 4; -  int idx_ipv4_ifname_null = 5; -  int idx_curr = 6; -  char *tag, *distance, *vrf; +	int idx_ipv4 = 3; +	int idx_ipv4_2 = 4; +	int idx_ipv4_ifname_null = 5; +	int idx_curr = 6; +	char *tag, *distance, *vrf; -  tag = distance = vrf = NULL; -  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); +	tag = distance = vrf = NULL; +	zebra_vty_ip_route_tdv_helper(argc, argv, idx_curr, &tag, &distance, +				      &vrf, NULL); -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, -			    argv[idx_ipv4]->arg, -			    argv[idx_ipv4_2]->arg, -			    argv[idx_ipv4_ifname_null]->arg, -			    NULL, -			    tag, distance, vrf, NULL); +	return zebra_static_ipv4(vty, SAFI_UNICAST, 0, argv[idx_ipv4]->arg, +				 argv[idx_ipv4_2]->arg, +				 argv[idx_ipv4_ifname_null]->arg, NULL, tag, +				 distance, vrf, NULL);  }  DEFUN (no_ip_route_mask_flags, @@ -609,462 +591,509 @@ DEFUN (no_ip_route_mask_flags,         "Specify labels for this route\n"         "One or more labels separated by '/'\n")  { -  int idx_ipv4 = 3; -  int idx_ipv4_2 = 4; -  int idx_curr = 6; -  char *tag, *distance, *vrf; +	int idx_ipv4 = 3; +	int idx_ipv4_2 = 4; +	int idx_curr = 6; +	char *tag, *distance, *vrf; -  tag = distance = vrf = NULL; -  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); +	tag = distance = vrf = NULL; +	zebra_vty_ip_route_tdv_helper(argc, argv, idx_curr, &tag, &distance, +				      &vrf, NULL); -  return zebra_static_ipv4 (vty, SAFI_UNICAST, 0, -			    argv[idx_ipv4]->arg, -			    argv[idx_ipv4_2]->arg, -			    NULL, NULL, -			    tag, distance, vrf, NULL); +	return zebra_static_ipv4(vty, SAFI_UNICAST, 0, argv[idx_ipv4]->arg, +				 argv[idx_ipv4_2]->arg, NULL, NULL, tag, +				 distance, vrf, NULL);  }  /* New RIB.  Detailed information for IPv4 route. */ -static void -vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast) -{ -  struct rib *rib; -  struct nexthop *nexthop, *tnexthop; -  int recursing; -  char buf[SRCDEST2STR_BUFFER]; -  struct zebra_vrf *zvrf; - -  RNODE_FOREACH_RIB (rn, rib) -    { -      const char *mcast_info = ""; -      if (mcast) -        { -          rib_table_info_t *info = srcdest_rnode_table_info(rn); -          mcast_info = (info->safi == SAFI_MULTICAST) -                       ? " using Multicast RIB" -                       : " using Unicast RIB"; -        } - -      vty_out (vty, "Routing entry for %s%s%s", -	       srcdest_rnode2str(rn, buf, sizeof(buf)), mcast_info, -	       VTY_NEWLINE); -      vty_out (vty, "  Known via \"%s", zebra_route_string (rib->type)); -      if (rib->instance) -        vty_out (vty, "[%d]", rib->instance); -      vty_out (vty, "\""); -      vty_out (vty, ", distance %u, metric %u", rib->distance, rib->metric); -      if (rib->tag) -	vty_out (vty, ", tag %d", rib->tag); -       if (rib->mtu) -        vty_out (vty, ", mtu %u", rib->mtu); -      if (rib->vrf_id != VRF_DEFAULT) -        { -          zvrf = vrf_info_lookup(rib->vrf_id); -          vty_out (vty, ", vrf %s", zvrf_name (zvrf)); -        } -      if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) -	vty_out (vty, ", best"); -      if (rib->refcnt) -	vty_out (vty, ", refcnt %ld", rib->refcnt); -      if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE)) -       vty_out (vty, ", blackhole"); -      if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT)) -       vty_out (vty, ", reject"); -      vty_out (vty, "%s", VTY_NEWLINE); - -      if (rib->type == ZEBRA_ROUTE_RIP -	  || rib->type == ZEBRA_ROUTE_OSPF -	  || rib->type == ZEBRA_ROUTE_ISIS -	  || rib->type == ZEBRA_ROUTE_NHRP -	  || rib->type == ZEBRA_ROUTE_TABLE -	  || rib->type == ZEBRA_ROUTE_BGP) -	{ -	  time_t uptime; -	  struct tm *tm; - -	  uptime = time (NULL); -	  uptime -= rib->uptime; -	  tm = gmtime (&uptime); - -	  vty_out (vty, "  Last update "); - -	  if (uptime < ONE_DAY_SECOND) -	    vty_out (vty,  "%02d:%02d:%02d", -		     tm->tm_hour, tm->tm_min, tm->tm_sec); -	  else if (uptime < ONE_WEEK_SECOND) -	    vty_out (vty, "%dd%02dh%02dm", -		     tm->tm_yday, tm->tm_hour, tm->tm_min); -	  else -	    vty_out (vty, "%02dw%dd%02dh", -		     tm->tm_yday/7, -		     tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour); -	  vty_out (vty, " ago%s", VTY_NEWLINE); -	} +static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn, +				     int mcast) +{ +	struct rib *rib; +	struct nexthop *nexthop, *tnexthop; +	int recursing; +	char buf[SRCDEST2STR_BUFFER]; +	struct zebra_vrf *zvrf; -      for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) -	{ -          char addrstr[32]; - -	  vty_out (vty, "  %c%s", -		   CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) ? '*' : ' ', -		   recursing ? "  " : ""); - -	  switch (nexthop->type) -	    { -	    case NEXTHOP_TYPE_IPV4: -	    case NEXTHOP_TYPE_IPV4_IFINDEX: -	      vty_out (vty, " %s", inet_ntoa (nexthop->gate.ipv4)); -	      if (nexthop->ifindex) -		vty_out (vty, ", via %s", -                         ifindex2ifname (nexthop->ifindex, rib->vrf_id)); -	      break; -	    case NEXTHOP_TYPE_IPV6: -	    case NEXTHOP_TYPE_IPV6_IFINDEX: -	      vty_out (vty, " %s", -		       inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ)); -	      if (nexthop->ifindex) -		vty_out (vty, ", via %s", -                         ifindex2ifname (nexthop->ifindex, rib->vrf_id)); -	      break; -	    case NEXTHOP_TYPE_IFINDEX: -	      vty_out (vty, " directly connected, %s", -		       ifindex2ifname (nexthop->ifindex, rib->vrf_id)); -	      break; -	    case NEXTHOP_TYPE_BLACKHOLE: -	      vty_out (vty, " directly connected, Null0"); -	      break; -	    default: -	      break; -	    } -	  if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) -	    vty_out (vty, " inactive"); - -	  if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK)) -	    vty_out (vty, " onlink"); - -	  if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) -	    vty_out (vty, " (recursive)"); - -	  switch (nexthop->type) -            { -            case NEXTHOP_TYPE_IPV4: -            case NEXTHOP_TYPE_IPV4_IFINDEX: -              if (nexthop->src.ipv4.s_addr) -                { -		  if (inet_ntop(AF_INET, &nexthop->src.ipv4, addrstr, -		      sizeof addrstr)) -                    vty_out (vty, ", src %s", addrstr); -                } -              break; -            case NEXTHOP_TYPE_IPV6: -            case NEXTHOP_TYPE_IPV6_IFINDEX: -              if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) -                { -		  if (inet_ntop(AF_INET6, &nexthop->src.ipv6, addrstr, -		      sizeof addrstr)) -                    vty_out (vty, ", src %s", addrstr); -                } -              break; -            default: -	       break; -            } - -          /* Label information */ -         if (nexthop->nh_label && nexthop->nh_label->num_labels) -           { -             vty_out (vty, " label %s", -                      mpls_label2str (nexthop->nh_label->num_labels, -                                      nexthop->nh_label->label, buf, BUFSIZ)); -           } - -	  vty_out (vty, "%s", VTY_NEWLINE); -	} -      vty_out (vty, "%s", VTY_NEWLINE); -    } -} - -static void -vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib, -                   json_object *json) -{ -  struct nexthop *nexthop, *tnexthop; -  int recursing; -  int len = 0; -  char buf[SRCDEST2STR_BUFFER]; -  json_object *json_nexthops = NULL; -  json_object *json_nexthop = NULL; -  json_object *json_route = NULL; - -  if (json) -    { -      json_route = json_object_new_object(); -      json_nexthops = json_object_new_array(); - -      json_object_string_add(json_route, "prefix", srcdest_rnode2str (rn, buf, sizeof buf)); -      json_object_string_add(json_route, "protocol", zebra_route_string(rib->type)); - -      if (rib->instance) -        json_object_int_add(json_route, "instance", rib->instance); - -      if (rib->vrf_id) -        json_object_int_add(json_route, "vrfId", rib->vrf_id); - -      if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) -        json_object_boolean_true_add(json_route, "selected"); - -      if (rib->type != ZEBRA_ROUTE_CONNECT && rib->type != ZEBRA_ROUTE_KERNEL) -        { -          json_object_int_add(json_route, "distance", rib->distance); -          json_object_int_add(json_route, "metric", rib->metric); -        } - -      if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE)) -        json_object_boolean_true_add(json_route, "blackhole"); - -      if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT)) -        json_object_boolean_true_add(json_route, "reject"); - -      if (rib->type == ZEBRA_ROUTE_RIP -          || rib->type == ZEBRA_ROUTE_OSPF -          || rib->type == ZEBRA_ROUTE_ISIS -	  || rib->type == ZEBRA_ROUTE_NHRP -          || rib->type == ZEBRA_ROUTE_TABLE -          || rib->type == ZEBRA_ROUTE_BGP) -        { -          time_t uptime; -          struct tm *tm; - -          uptime = time (NULL); -          uptime -= rib->uptime; -          tm = gmtime (&uptime); - -          if (uptime < ONE_DAY_SECOND) -            sprintf(buf, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec); -          else if (uptime < ONE_WEEK_SECOND) -            sprintf(buf, "%dd%02dh%02dm", tm->tm_yday, tm->tm_hour, tm->tm_min); -          else -            sprintf(buf, "%02dw%dd%02dh", tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour); - -          json_object_string_add(json_route, "uptime", buf); -        } - -      for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) -        { -          json_nexthop = json_object_new_object(); - -          if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) -            json_object_boolean_true_add(json_nexthop, "fib"); - -          switch (nexthop->type) -            { -            case NEXTHOP_TYPE_IPV4: -            case NEXTHOP_TYPE_IPV4_IFINDEX: -              json_object_string_add(json_nexthop, "ip", inet_ntoa (nexthop->gate.ipv4)); -              json_object_string_add(json_nexthop, "afi", "ipv4"); - -              if (nexthop->ifindex) -                { -                  json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex); -                  json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname (nexthop->ifindex, rib->vrf_id)); -                } -              break; -            case NEXTHOP_TYPE_IPV6: -            case NEXTHOP_TYPE_IPV6_IFINDEX: -              json_object_string_add(json_nexthop, "ip", inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ)); -              json_object_string_add(json_nexthop, "afi", "ipv6"); - -              if (nexthop->ifindex) -                { -                  json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex); -                  json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname (nexthop->ifindex, rib->vrf_id)); -                } -              break; - -            case NEXTHOP_TYPE_IFINDEX: -              json_object_boolean_true_add(json_nexthop, "directlyConnected"); -              json_object_int_add(json_nexthop, "interfaceIndex", nexthop->ifindex); -              json_object_string_add(json_nexthop, "interfaceName", ifindex2ifname (nexthop->ifindex, rib->vrf_id)); -              break; -            case NEXTHOP_TYPE_BLACKHOLE: -              json_object_boolean_true_add(json_nexthop, "blackhole"); -              break; -            default: -              break; -            } - -          if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) -            json_object_boolean_true_add(json_nexthop, "active"); - -          if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK)) -            json_object_boolean_true_add(json_nexthop, "onLink"); - -          if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) -            json_object_boolean_true_add(json_nexthop, "recursive"); - -          switch (nexthop->type) -            { -              case NEXTHOP_TYPE_IPV4: -              case NEXTHOP_TYPE_IPV4_IFINDEX: -                if (nexthop->src.ipv4.s_addr) -                  { -                    if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf)) -                      json_object_string_add(json_nexthop, "source", buf); -                  } -                break; -              case NEXTHOP_TYPE_IPV6: -              case NEXTHOP_TYPE_IPV6_IFINDEX: -                if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) -                  { -                    if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, sizeof buf)) -                      json_object_string_add(json_nexthop, "source", buf); -                  } -                break; -              default: -                break; -            } - -	  if (nexthop->nh_label && nexthop->nh_label->num_labels) -	    { -	      json_object_string_add(json_nexthop, "labels", -				     mpls_label2str (nexthop->nh_label->num_labels, -						     nexthop->nh_label->label, buf, BUFSIZ)); -	    } - -          json_object_array_add(json_nexthops, json_nexthop); -        } - -      json_object_object_add(json_route, "nexthops", json_nexthops); -      json_object_array_add(json, json_route); -      return; -    } - -  /* Nexthop information. */ -  for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) -    { -      if (nexthop == rib->nexthop) -	{ -	  /* Prefix information. */ -	  len = vty_out (vty, "%c", zebra_route_char (rib->type)); -          if (rib->instance) -	    len += vty_out (vty, "[%d]", rib->instance); -          len += vty_out (vty, "%c%c %s", -			  CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED) -			  ? '>' : ' ', -			  CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) -			  ? '*' : ' ', -			  srcdest_rnode2str (rn, buf, sizeof buf)); - -	  /* Distance and metric display. */ -	  if (rib->type != ZEBRA_ROUTE_CONNECT -	      && rib->type != ZEBRA_ROUTE_KERNEL) -	    len += vty_out (vty, " [%d/%d]", rib->distance, -			    rib->metric); -	} -      else -	vty_out (vty, "  %c%*c", -		 CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) -		 ? '*' : ' ', -		 len - 3 + (2 * recursing), ' '); - -      switch (nexthop->type) -	{ -	case NEXTHOP_TYPE_IPV4: -	case NEXTHOP_TYPE_IPV4_IFINDEX: -	  vty_out (vty, " via %s", inet_ntoa (nexthop->gate.ipv4)); -	  if (nexthop->ifindex) -	    vty_out (vty, ", %s", -                     ifindex2ifname (nexthop->ifindex, rib->vrf_id)); -	  break; -        case NEXTHOP_TYPE_IPV6: -	case NEXTHOP_TYPE_IPV6_IFINDEX: -	  vty_out (vty, " via %s", -		   inet_ntop (AF_INET6, &nexthop->gate.ipv6, buf, BUFSIZ)); -	  if (nexthop->ifindex) -	    vty_out (vty, ", %s", -                     ifindex2ifname (nexthop->ifindex, rib->vrf_id)); -	  break; - -	case NEXTHOP_TYPE_IFINDEX: -	  vty_out (vty, " is directly connected, %s", -		   ifindex2ifname (nexthop->ifindex, rib->vrf_id)); -	  break; -	case NEXTHOP_TYPE_BLACKHOLE: -	  vty_out (vty, " is directly connected, Null0"); -	  break; -	default: -	  break; -	} -      if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) -	vty_out (vty, " inactive"); - -      if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ONLINK)) -	vty_out (vty, " onlink"); - -      if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) -	vty_out (vty, " (recursive)"); - -      switch (nexthop->type) -        { -          case NEXTHOP_TYPE_IPV4: -          case NEXTHOP_TYPE_IPV4_IFINDEX: -            if (nexthop->src.ipv4.s_addr) -              { -		if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, sizeof buf)) -                  vty_out (vty, ", src %s", buf); -              } -            break; -          case NEXTHOP_TYPE_IPV6: -          case NEXTHOP_TYPE_IPV6_IFINDEX: -            if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) -              { -		if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, sizeof buf)) -                  vty_out (vty, ", src %s", buf); -              } -            break; -          default: -	    break; -        } - -      /* Label information */ -      if (nexthop->nh_label && nexthop->nh_label->num_labels) -       { -         vty_out (vty, " label %s", -                  mpls_label2str (nexthop->nh_label->num_labels, -                                  nexthop->nh_label->label, buf, BUFSIZ)); -       } - -      if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE)) -               vty_out (vty, ", bh"); -      if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT)) -               vty_out (vty, ", rej"); - -      if (rib->type == ZEBRA_ROUTE_RIP -	  || rib->type == ZEBRA_ROUTE_OSPF -	  || rib->type == ZEBRA_ROUTE_ISIS -	  || rib->type == ZEBRA_ROUTE_NHRP -	  || rib->type == ZEBRA_ROUTE_TABLE -	  || rib->type == ZEBRA_ROUTE_BGP) +	RNODE_FOREACH_RIB(rn, rib)  	{ -	  time_t uptime; -	  struct tm *tm; +		const char *mcast_info = ""; +		if (mcast) { +			rib_table_info_t *info = srcdest_rnode_table_info(rn); +			mcast_info = (info->safi == SAFI_MULTICAST) +					     ? " using Multicast RIB" +					     : " using Unicast RIB"; +		} + +		vty_out(vty, "Routing entry for %s%s%s", +			srcdest_rnode2str(rn, buf, sizeof(buf)), mcast_info, +			VTY_NEWLINE); +		vty_out(vty, "  Known via \"%s", zebra_route_string(rib->type)); +		if (rib->instance) +			vty_out(vty, "[%d]", rib->instance); +		vty_out(vty, "\""); +		vty_out(vty, ", distance %u, metric %u", rib->distance, +			rib->metric); +		if (rib->tag) +			vty_out(vty, ", tag %d", rib->tag); +		if (rib->mtu) +			vty_out(vty, ", mtu %u", rib->mtu); +		if (rib->vrf_id != VRF_DEFAULT) { +			zvrf = vrf_info_lookup(rib->vrf_id); +			vty_out(vty, ", vrf %s", zvrf_name(zvrf)); +		} +		if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED)) +			vty_out(vty, ", best"); +		if (rib->refcnt) +			vty_out(vty, ", refcnt %ld", rib->refcnt); +		if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_BLACKHOLE)) +			vty_out(vty, ", blackhole"); +		if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_REJECT)) +			vty_out(vty, ", reject"); +		vty_out(vty, "%s", VTY_NEWLINE); + +		if (rib->type == ZEBRA_ROUTE_RIP +		    || rib->type == ZEBRA_ROUTE_OSPF +		    || rib->type == ZEBRA_ROUTE_ISIS +		    || rib->type == ZEBRA_ROUTE_NHRP +		    || rib->type == ZEBRA_ROUTE_TABLE +		    || rib->type == ZEBRA_ROUTE_BGP) { +			time_t uptime; +			struct tm *tm; + +			uptime = time(NULL); +			uptime -= rib->uptime; +			tm = gmtime(&uptime); + +			vty_out(vty, "  Last update "); + +			if (uptime < ONE_DAY_SECOND) +				vty_out(vty, "%02d:%02d:%02d", tm->tm_hour, +					tm->tm_min, tm->tm_sec); +			else if (uptime < ONE_WEEK_SECOND) +				vty_out(vty, "%dd%02dh%02dm", tm->tm_yday, +					tm->tm_hour, tm->tm_min); +			else +				vty_out(vty, "%02dw%dd%02dh", tm->tm_yday / 7, +					tm->tm_yday - ((tm->tm_yday / 7) * 7), +					tm->tm_hour); +			vty_out(vty, " ago%s", VTY_NEWLINE); +		} + +		for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, +				     recursing)) { +			char addrstr[32]; + +			vty_out(vty, "  %c%s", +				CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB) +					? '*' +					: ' ', +				recursing ? "  " : ""); + +			switch (nexthop->type) { +			case NEXTHOP_TYPE_IPV4: +			case NEXTHOP_TYPE_IPV4_IFINDEX: +				vty_out(vty, " %s", +					inet_ntoa(nexthop->gate.ipv4)); +				if (nexthop->ifindex) +					vty_out(vty, ", via %s", +						ifindex2ifname(nexthop->ifindex, +							       rib->vrf_id)); +				break; +			case NEXTHOP_TYPE_IPV6: +			case NEXTHOP_TYPE_IPV6_IFINDEX: +				vty_out(vty, " %s", +					inet_ntop(AF_INET6, &nexthop->gate.ipv6, +						  buf, BUFSIZ)); +				if (nexthop->ifindex) +					vty_out(vty, ", via %s", +						ifindex2ifname(nexthop->ifindex, +							       rib->vrf_id)); +				break; +			case NEXTHOP_TYPE_IFINDEX: +				vty_out(vty, " directly connected, %s", +					ifindex2ifname(nexthop->ifindex, +						       rib->vrf_id)); +				break; +			case NEXTHOP_TYPE_BLACKHOLE: +				vty_out(vty, " directly connected, Null0"); +				break; +			default: +				break; +			} +			if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) +				vty_out(vty, " inactive"); + +			if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)) +				vty_out(vty, " onlink"); + +			if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) +				vty_out(vty, " (recursive)"); + +			switch (nexthop->type) { +			case NEXTHOP_TYPE_IPV4: +			case NEXTHOP_TYPE_IPV4_IFINDEX: +				if (nexthop->src.ipv4.s_addr) { +					if (inet_ntop(AF_INET, +						      &nexthop->src.ipv4, +						      addrstr, sizeof addrstr)) +						vty_out(vty, ", src %s", +							addrstr); +				} +				break; +			case NEXTHOP_TYPE_IPV6: +			case NEXTHOP_TYPE_IPV6_IFINDEX: +				if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, +						    &in6addr_any)) { +					if (inet_ntop(AF_INET6, +						      &nexthop->src.ipv6, +						      addrstr, sizeof addrstr)) +						vty_out(vty, ", src %s", +							addrstr); +				} +				break; +			default: +				break; +			} + +			/* Label information */ +			if (nexthop->nh_label +			    && nexthop->nh_label->num_labels) { +				vty_out(vty, " label %s", +					mpls_label2str( +						nexthop->nh_label->num_labels, +						nexthop->nh_label->label, buf, +						BUFSIZ)); +			} + +			vty_out(vty, "%s", VTY_NEWLINE); +		} +		vty_out(vty, "%s", VTY_NEWLINE); +	} +} -	  uptime = time (NULL); -	  uptime -= rib->uptime; -	  tm = gmtime (&uptime); +static void vty_show_ip_route(struct vty *vty, struct route_node *rn, +			      struct rib *rib, json_object *json) +{ +	struct nexthop *nexthop, *tnexthop; +	int recursing; +	int len = 0; +	char buf[SRCDEST2STR_BUFFER]; +	json_object *json_nexthops = NULL; +	json_object *json_nexthop = NULL; +	json_object *json_route = NULL; + +	if (json) { +		json_route = json_object_new_object(); +		json_nexthops = json_object_new_array(); + +		json_object_string_add(json_route, "prefix", +				       srcdest_rnode2str(rn, buf, sizeof buf)); +		json_object_string_add(json_route, "protocol", +				       zebra_route_string(rib->type)); + +		if (rib->instance) +			json_object_int_add(json_route, "instance", +					    rib->instance); + +		if (rib->vrf_id) +			json_object_int_add(json_route, "vrfId", rib->vrf_id); + +		if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED)) +			json_object_boolean_true_add(json_route, "selected"); + +		if (rib->type != ZEBRA_ROUTE_CONNECT +		    && rib->type != ZEBRA_ROUTE_KERNEL) { +			json_object_int_add(json_route, "distance", +					    rib->distance); +			json_object_int_add(json_route, "metric", rib->metric); +		} + +		if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_BLACKHOLE)) +			json_object_boolean_true_add(json_route, "blackhole"); + +		if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_REJECT)) +			json_object_boolean_true_add(json_route, "reject"); + +		if (rib->type == ZEBRA_ROUTE_RIP +		    || rib->type == ZEBRA_ROUTE_OSPF +		    || rib->type == ZEBRA_ROUTE_ISIS +		    || rib->type == ZEBRA_ROUTE_NHRP +		    || rib->type == ZEBRA_ROUTE_TABLE +		    || rib->type == ZEBRA_ROUTE_BGP) { +			time_t uptime; +			struct tm *tm; + +			uptime = time(NULL); +			uptime -= rib->uptime; +			tm = gmtime(&uptime); + +			if (uptime < ONE_DAY_SECOND) +				sprintf(buf, "%02d:%02d:%02d", tm->tm_hour, +					tm->tm_min, tm->tm_sec); +			else if (uptime < ONE_WEEK_SECOND) +				sprintf(buf, "%dd%02dh%02dm", tm->tm_yday, +					tm->tm_hour, tm->tm_min); +			else +				sprintf(buf, "%02dw%dd%02dh", tm->tm_yday / 7, +					tm->tm_yday - ((tm->tm_yday / 7) * 7), +					tm->tm_hour); + +			json_object_string_add(json_route, "uptime", buf); +		} + +		for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, +				     recursing)) { +			json_nexthop = json_object_new_object(); + +			if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)) +				json_object_boolean_true_add(json_nexthop, +							     "fib"); + +			switch (nexthop->type) { +			case NEXTHOP_TYPE_IPV4: +			case NEXTHOP_TYPE_IPV4_IFINDEX: +				json_object_string_add( +					json_nexthop, "ip", +					inet_ntoa(nexthop->gate.ipv4)); +				json_object_string_add(json_nexthop, "afi", +						       "ipv4"); + +				if (nexthop->ifindex) { +					json_object_int_add(json_nexthop, +							    "interfaceIndex", +							    nexthop->ifindex); +					json_object_string_add( +						json_nexthop, "interfaceName", +						ifindex2ifname(nexthop->ifindex, +							       rib->vrf_id)); +				} +				break; +			case NEXTHOP_TYPE_IPV6: +			case NEXTHOP_TYPE_IPV6_IFINDEX: +				json_object_string_add( +					json_nexthop, "ip", +					inet_ntop(AF_INET6, &nexthop->gate.ipv6, +						  buf, BUFSIZ)); +				json_object_string_add(json_nexthop, "afi", +						       "ipv6"); + +				if (nexthop->ifindex) { +					json_object_int_add(json_nexthop, +							    "interfaceIndex", +							    nexthop->ifindex); +					json_object_string_add( +						json_nexthop, "interfaceName", +						ifindex2ifname(nexthop->ifindex, +							       rib->vrf_id)); +				} +				break; + +			case NEXTHOP_TYPE_IFINDEX: +				json_object_boolean_true_add( +					json_nexthop, "directlyConnected"); +				json_object_int_add(json_nexthop, +						    "interfaceIndex", +						    nexthop->ifindex); +				json_object_string_add( +					json_nexthop, "interfaceName", +					ifindex2ifname(nexthop->ifindex, +						       rib->vrf_id)); +				break; +			case NEXTHOP_TYPE_BLACKHOLE: +				json_object_boolean_true_add(json_nexthop, +							     "blackhole"); +				break; +			default: +				break; +			} + +			if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) +				json_object_boolean_true_add(json_nexthop, +							     "active"); + +			if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)) +				json_object_boolean_true_add(json_nexthop, +							     "onLink"); + +			if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) +				json_object_boolean_true_add(json_nexthop, +							     "recursive"); + +			switch (nexthop->type) { +			case NEXTHOP_TYPE_IPV4: +			case NEXTHOP_TYPE_IPV4_IFINDEX: +				if (nexthop->src.ipv4.s_addr) { +					if (inet_ntop(AF_INET, +						      &nexthop->src.ipv4, buf, +						      sizeof buf)) +						json_object_string_add( +							json_nexthop, "source", +							buf); +				} +				break; +			case NEXTHOP_TYPE_IPV6: +			case NEXTHOP_TYPE_IPV6_IFINDEX: +				if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, +						    &in6addr_any)) { +					if (inet_ntop(AF_INET6, +						      &nexthop->src.ipv6, buf, +						      sizeof buf)) +						json_object_string_add( +							json_nexthop, "source", +							buf); +				} +				break; +			default: +				break; +			} + +			if (nexthop->nh_label +			    && nexthop->nh_label->num_labels) { +				json_object_string_add( +					json_nexthop, "labels", +					mpls_label2str( +						nexthop->nh_label->num_labels, +						nexthop->nh_label->label, buf, +						BUFSIZ)); +			} + +			json_object_array_add(json_nexthops, json_nexthop); +		} + +		json_object_object_add(json_route, "nexthops", json_nexthops); +		json_object_array_add(json, json_route); +		return; +	} -	  if (uptime < ONE_DAY_SECOND) -	    vty_out (vty,  ", %02d:%02d:%02d", -		     tm->tm_hour, tm->tm_min, tm->tm_sec); -	  else if (uptime < ONE_WEEK_SECOND) -	    vty_out (vty, ", %dd%02dh%02dm", -		     tm->tm_yday, tm->tm_hour, tm->tm_min); -	  else -	    vty_out (vty, ", %02dw%dd%02dh", -		     tm->tm_yday/7, -		     tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour); +	/* Nexthop information. */ +	for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) { +		if (nexthop == rib->nexthop) { +			/* Prefix information. */ +			len = vty_out(vty, "%c", zebra_route_char(rib->type)); +			if (rib->instance) +				len += vty_out(vty, "[%d]", rib->instance); +			len += vty_out( +				vty, "%c%c %s", +				CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED) +					? '>' +					: ' ', +				CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB) +					? '*' +					: ' ', +				srcdest_rnode2str(rn, buf, sizeof buf)); + +			/* Distance and metric display. */ +			if (rib->type != ZEBRA_ROUTE_CONNECT +			    && rib->type != ZEBRA_ROUTE_KERNEL) +				len += vty_out(vty, " [%d/%d]", rib->distance, +					       rib->metric); +		} else +			vty_out(vty, "  %c%*c", +				CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB) +					? '*' +					: ' ', +				len - 3 + (2 * recursing), ' '); + +		switch (nexthop->type) { +		case NEXTHOP_TYPE_IPV4: +		case NEXTHOP_TYPE_IPV4_IFINDEX: +			vty_out(vty, " via %s", inet_ntoa(nexthop->gate.ipv4)); +			if (nexthop->ifindex) +				vty_out(vty, ", %s", +					ifindex2ifname(nexthop->ifindex, +						       rib->vrf_id)); +			break; +		case NEXTHOP_TYPE_IPV6: +		case NEXTHOP_TYPE_IPV6_IFINDEX: +			vty_out(vty, " via %s", +				inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf, +					  BUFSIZ)); +			if (nexthop->ifindex) +				vty_out(vty, ", %s", +					ifindex2ifname(nexthop->ifindex, +						       rib->vrf_id)); +			break; + +		case NEXTHOP_TYPE_IFINDEX: +			vty_out(vty, " is directly connected, %s", +				ifindex2ifname(nexthop->ifindex, rib->vrf_id)); +			break; +		case NEXTHOP_TYPE_BLACKHOLE: +			vty_out(vty, " is directly connected, Null0"); +			break; +		default: +			break; +		} +		if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) +			vty_out(vty, " inactive"); + +		if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)) +			vty_out(vty, " onlink"); + +		if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) +			vty_out(vty, " (recursive)"); + +		switch (nexthop->type) { +		case NEXTHOP_TYPE_IPV4: +		case NEXTHOP_TYPE_IPV4_IFINDEX: +			if (nexthop->src.ipv4.s_addr) { +				if (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, +					      sizeof buf)) +					vty_out(vty, ", src %s", buf); +			} +			break; +		case NEXTHOP_TYPE_IPV6: +		case NEXTHOP_TYPE_IPV6_IFINDEX: +			if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) { +				if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, +					      sizeof buf)) +					vty_out(vty, ", src %s", buf); +			} +			break; +		default: +			break; +		} + +		/* Label information */ +		if (nexthop->nh_label && nexthop->nh_label->num_labels) { +			vty_out(vty, " label %s", +				mpls_label2str(nexthop->nh_label->num_labels, +					       nexthop->nh_label->label, buf, +					       BUFSIZ)); +		} + +		if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_BLACKHOLE)) +			vty_out(vty, ", bh"); +		if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_REJECT)) +			vty_out(vty, ", rej"); + +		if (rib->type == ZEBRA_ROUTE_RIP +		    || rib->type == ZEBRA_ROUTE_OSPF +		    || rib->type == ZEBRA_ROUTE_ISIS +		    || rib->type == ZEBRA_ROUTE_NHRP +		    || rib->type == ZEBRA_ROUTE_TABLE +		    || rib->type == ZEBRA_ROUTE_BGP) { +			time_t uptime; +			struct tm *tm; + +			uptime = time(NULL); +			uptime -= rib->uptime; +			tm = gmtime(&uptime); + +			if (uptime < ONE_DAY_SECOND) +				vty_out(vty, ", %02d:%02d:%02d", tm->tm_hour, +					tm->tm_min, tm->tm_sec); +			else if (uptime < ONE_WEEK_SECOND) +				vty_out(vty, ", %dd%02dh%02dm", tm->tm_yday, +					tm->tm_hour, tm->tm_min); +			else +				vty_out(vty, ", %02dw%dd%02dh", tm->tm_yday / 7, +					tm->tm_yday - ((tm->tm_yday / 7) * 7), +					tm->tm_hour); +		} +		vty_out(vty, "%s", VTY_NEWLINE);  	} -      vty_out (vty, "%s", VTY_NEWLINE); -    }  }  DEFUN (show_ip_route, @@ -1075,91 +1104,85 @@ DEFUN (show_ip_route,         "IP routing table\n"         JSON_STR)  { -  return do_show_ip_route (vty, VRF_DEFAULT_NAME, SAFI_UNICAST, use_json(argc, argv)); -} - -static int -do_show_ip_route (struct vty *vty, const char *vrf_name, safi_t safi, -                  u_char use_json) -{ -  struct route_table *table; -  struct route_node *rn; -  struct rib *rib; -  int first = 1; -  struct zebra_vrf *zvrf = NULL; -  char buf[BUFSIZ]; -  json_object *json = NULL; -  json_object *json_prefix = NULL; - -  if (!(zvrf = zebra_vrf_lookup_by_name (vrf_name))) -    { -      if (use_json) -        vty_out (vty, "{}%s", VTY_NEWLINE); -      else -        vty_out (vty, "vrf %s not defined%s", vrf_name, VTY_NEWLINE); -      return CMD_SUCCESS; -    } - -  if (zvrf_id (zvrf) == VRF_UNKNOWN) -    { -      if (use_json) -        vty_out (vty, "{}%s", VTY_NEWLINE); -      else -        vty_out (vty, "vrf %s inactive%s", vrf_name, VTY_NEWLINE); -      return CMD_SUCCESS; -    } - -  table = zebra_vrf_table (AFI_IP, safi, zvrf_id (zvrf)); -  if (! table) -    { -      if (use_json) -        vty_out (vty, "{}%s", VTY_NEWLINE); -      return CMD_SUCCESS; -    } - -  if (use_json) -    { -      json = json_object_new_object(); - -      /* Show all IPv4 routes. */ -      for (rn = route_top (table); rn; rn = route_next (rn)) -        { -          RNODE_FOREACH_RIB (rn, rib) -            { -              if (!json_prefix) -                json_prefix = json_object_new_array(); -              vty_show_ip_route (vty, rn, rib, json_prefix); -            } - -          if (json_prefix) -            { -              prefix2str (&rn->p, buf, sizeof buf); -              json_object_object_add(json, buf, json_prefix); -              json_prefix = NULL; -            } -        } - -      vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE); -      json_object_free(json); -    } -  else -    { -      /* Show all IPv4 routes. */ -      for (rn = route_top (table); rn; rn = route_next (rn)) -        { -          RNODE_FOREACH_RIB (rn, rib) -            { -              if (first) -                { -                  vty_out (vty, SHOW_ROUTE_V4_HEADER); -                  first = 0; -                } -              vty_show_ip_route (vty, rn, rib, NULL); -            } -        } -    } - -  return CMD_SUCCESS; +	return do_show_ip_route(vty, VRF_DEFAULT_NAME, SAFI_UNICAST, +				use_json(argc, argv)); +} + +static int do_show_ip_route(struct vty *vty, const char *vrf_name, safi_t safi, +			    u_char use_json) +{ +	struct route_table *table; +	struct route_node *rn; +	struct rib *rib; +	int first = 1; +	struct zebra_vrf *zvrf = NULL; +	char buf[BUFSIZ]; +	json_object *json = NULL; +	json_object *json_prefix = NULL; + +	if (!(zvrf = zebra_vrf_lookup_by_name(vrf_name))) { +		if (use_json) +			vty_out(vty, "{}%s", VTY_NEWLINE); +		else +			vty_out(vty, "vrf %s not defined%s", vrf_name, +				VTY_NEWLINE); +		return CMD_SUCCESS; +	} + +	if (zvrf_id(zvrf) == VRF_UNKNOWN) { +		if (use_json) +			vty_out(vty, "{}%s", VTY_NEWLINE); +		else +			vty_out(vty, "vrf %s inactive%s", vrf_name, +				VTY_NEWLINE); +		return CMD_SUCCESS; +	} + +	table = zebra_vrf_table(AFI_IP, safi, zvrf_id(zvrf)); +	if (!table) { +		if (use_json) +			vty_out(vty, "{}%s", VTY_NEWLINE); +		return CMD_SUCCESS; +	} + +	if (use_json) { +		json = json_object_new_object(); + +		/* Show all IPv4 routes. */ +		for (rn = route_top(table); rn; rn = route_next(rn)) { +			RNODE_FOREACH_RIB(rn, rib) +			{ +				if (!json_prefix) +					json_prefix = json_object_new_array(); +				vty_show_ip_route(vty, rn, rib, json_prefix); +			} + +			if (json_prefix) { +				prefix2str(&rn->p, buf, sizeof buf); +				json_object_object_add(json, buf, json_prefix); +				json_prefix = NULL; +			} +		} + +		vty_out(vty, "%s%s", json_object_to_json_string_ext( +					     json, JSON_C_TO_STRING_PRETTY), +			VTY_NEWLINE); +		json_object_free(json); +	} else { +		/* Show all IPv4 routes. */ +		for (rn = route_top(table); rn; rn = route_next(rn)) { +			RNODE_FOREACH_RIB(rn, rib) +			{ +				if (first) { +					vty_out(vty, SHOW_ROUTE_V4_HEADER); +					first = 0; +				} +				vty_show_ip_route(vty, rn, rib, NULL); +			} +		} +	} + +	return CMD_SUCCESS;  }  DEFUN (show_ip_route_vrf, @@ -1171,10 +1194,10 @@ DEFUN (show_ip_route_vrf,         VRF_CMD_HELP_STR         JSON_STR)  { -  int idx_vrf = 4; -  u_char uj = use_json(argc, argv); +	int idx_vrf = 4; +	u_char uj = use_json(argc, argv); -  return do_show_ip_route (vty, argv[idx_vrf]->arg, SAFI_UNICAST, uj); +	return do_show_ip_route(vty, argv[idx_vrf]->arg, SAFI_UNICAST, uj);  }  DEFUN (show_ip_nht, @@ -1185,14 +1208,14 @@ DEFUN (show_ip_nht,         "IP nexthop tracking table\n"         VRF_CMD_HELP_STR)  { -  int idx_vrf = 4; -  vrf_id_t vrf_id = VRF_DEFAULT; +	int idx_vrf = 4; +	vrf_id_t vrf_id = VRF_DEFAULT; -  if (argc == 5) -    VRF_GET_ID (vrf_id, argv[idx_vrf]->arg); +	if (argc == 5) +		VRF_GET_ID(vrf_id, argv[idx_vrf]->arg); -  zebra_print_rnh_table(vrf_id, AF_INET, vty, RNH_NEXTHOP_TYPE); -  return CMD_SUCCESS; +	zebra_print_rnh_table(vrf_id, AF_INET, vty, RNH_NEXTHOP_TYPE); +	return CMD_SUCCESS;  } @@ -1204,17 +1227,18 @@ DEFUN (show_ip_nht_vrf_all,         "IP nexthop tracking table\n"         VRF_ALL_CMD_HELP_STR)  { -  struct vrf *vrf; -  struct zebra_vrf *zvrf; +	struct vrf *vrf; +	struct zebra_vrf *zvrf; -  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) -    if ((zvrf = vrf->info) != NULL) -      { -        vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); -        zebra_print_rnh_table(zvrf_id (zvrf), AF_INET, vty, RNH_NEXTHOP_TYPE); -      } +	RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) +	if ((zvrf = vrf->info) != NULL) { +		vty_out(vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name(zvrf), +			VTY_NEWLINE); +		zebra_print_rnh_table(zvrf_id(zvrf), AF_INET, vty, +				      RNH_NEXTHOP_TYPE); +	} -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (show_ipv6_nht, @@ -1225,14 +1249,14 @@ DEFUN (show_ipv6_nht,         "IPv6 nexthop tracking table\n"         VRF_CMD_HELP_STR)  { -  int idx_vrf = 4; -  vrf_id_t vrf_id = VRF_DEFAULT; +	int idx_vrf = 4; +	vrf_id_t vrf_id = VRF_DEFAULT; -  if (argc == 5) -    VRF_GET_ID (vrf_id, argv[idx_vrf]->arg); +	if (argc == 5) +		VRF_GET_ID(vrf_id, argv[idx_vrf]->arg); -  zebra_print_rnh_table(vrf_id, AF_INET6, vty, RNH_NEXTHOP_TYPE); -  return CMD_SUCCESS; +	zebra_print_rnh_table(vrf_id, AF_INET6, vty, RNH_NEXTHOP_TYPE); +	return CMD_SUCCESS;  } @@ -1244,17 +1268,18 @@ DEFUN (show_ipv6_nht_vrf_all,         "IPv6 nexthop tracking table\n"         VRF_ALL_CMD_HELP_STR)  { -  struct vrf *vrf; -  struct zebra_vrf *zvrf; +	struct vrf *vrf; +	struct zebra_vrf *zvrf; -  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) -    if ((zvrf = vrf->info) != NULL) -      { -        vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); -        zebra_print_rnh_table(zvrf_id (zvrf), AF_INET6, vty, RNH_NEXTHOP_TYPE); -      } +	RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) +	if ((zvrf = vrf->info) != NULL) { +		vty_out(vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name(zvrf), +			VTY_NEWLINE); +		zebra_print_rnh_table(zvrf_id(zvrf), AF_INET6, vty, +				      RNH_NEXTHOP_TYPE); +	} -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (ip_nht_default_route, @@ -1264,12 +1289,12 @@ DEFUN (ip_nht_default_route,         "Filter Next Hop tracking route resolution\n"         "Resolve via default route\n")  { -  if (zebra_rnh_ip_default_route) -    return CMD_SUCCESS; +	if (zebra_rnh_ip_default_route) +		return CMD_SUCCESS; -  zebra_rnh_ip_default_route = 1; -  zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL); -  return CMD_SUCCESS; +	zebra_rnh_ip_default_route = 1; +	zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL); +	return CMD_SUCCESS;  }  DEFUN (no_ip_nht_default_route, @@ -1280,12 +1305,12 @@ DEFUN (no_ip_nht_default_route,         "Filter Next Hop tracking route resolution\n"         "Resolve via default route\n")  { -  if (!zebra_rnh_ip_default_route) -    return CMD_SUCCESS; +	if (!zebra_rnh_ip_default_route) +		return CMD_SUCCESS; -  zebra_rnh_ip_default_route = 0; -  zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL); -  return CMD_SUCCESS; +	zebra_rnh_ip_default_route = 0; +	zebra_evaluate_rnh(0, AF_INET, 1, RNH_NEXTHOP_TYPE, NULL); +	return CMD_SUCCESS;  }  DEFUN (ipv6_nht_default_route, @@ -1295,12 +1320,12 @@ DEFUN (ipv6_nht_default_route,         "Filter Next Hop tracking route resolution\n"         "Resolve via default route\n")  { -  if (zebra_rnh_ipv6_default_route) -    return CMD_SUCCESS; +	if (zebra_rnh_ipv6_default_route) +		return CMD_SUCCESS; -  zebra_rnh_ipv6_default_route = 1; -  zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL); -  return CMD_SUCCESS; +	zebra_rnh_ipv6_default_route = 1; +	zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL); +	return CMD_SUCCESS;  }  DEFUN (no_ipv6_nht_default_route, @@ -1311,12 +1336,12 @@ DEFUN (no_ipv6_nht_default_route,         "Filter Next Hop tracking route resolution\n"         "Resolve via default route\n")  { -  if (!zebra_rnh_ipv6_default_route) -    return CMD_SUCCESS; +	if (!zebra_rnh_ipv6_default_route) +		return CMD_SUCCESS; -  zebra_rnh_ipv6_default_route = 0; -  zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL); -  return CMD_SUCCESS; +	zebra_rnh_ipv6_default_route = 0; +	zebra_evaluate_rnh(0, AF_INET6, 1, RNH_NEXTHOP_TYPE, NULL); +	return CMD_SUCCESS;  }  DEFUN (show_ip_route_tag, @@ -1329,46 +1354,44 @@ DEFUN (show_ip_route_tag,         "Show only routes with tag\n"         "Tag value\n")  { -  int idx_vrf = 3; -  int idx_name = 4; -  int idx_tag = 6; -  struct route_table *table; -  struct route_node *rn; -  struct rib *rib; -  int first = 1; -  route_tag_t tag = 0; -  vrf_id_t vrf_id = VRF_DEFAULT; - -  if (strmatch(argv[idx_vrf]->text, "vrf")) -    { -      VRF_GET_ID (vrf_id, argv[idx_name]->arg); -      VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_tag]->arg, 0, 4294967295); -    } -  else -    { -      idx_tag -= 2; -      VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_tag]->arg, 0, 4294967295); -    } - -  table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id); -  if (! table) -    return CMD_SUCCESS; - -  /* Show all IPv4 routes with matching tag value. */ -  for (rn = route_top (table); rn; rn = route_next (rn)) -    RNODE_FOREACH_RIB (rn, rib) -      { -        if (rib->tag != tag) -          continue; - -        if (first) -          { -            vty_out (vty, SHOW_ROUTE_V4_HEADER); -            first = 0; -          } -        vty_show_ip_route (vty, rn, rib, NULL); -      } -  return CMD_SUCCESS; +	int idx_vrf = 3; +	int idx_name = 4; +	int idx_tag = 6; +	struct route_table *table; +	struct route_node *rn; +	struct rib *rib; +	int first = 1; +	route_tag_t tag = 0; +	vrf_id_t vrf_id = VRF_DEFAULT; + +	if (strmatch(argv[idx_vrf]->text, "vrf")) { +		VRF_GET_ID(vrf_id, argv[idx_name]->arg); +		VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_tag]->arg, 0, +				      4294967295); +	} else { +		idx_tag -= 2; +		VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_tag]->arg, 0, +				      4294967295); +	} + +	table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id); +	if (!table) +		return CMD_SUCCESS; + +	/* Show all IPv4 routes with matching tag value. */ +	for (rn = route_top(table); rn; rn = route_next(rn)) +		RNODE_FOREACH_RIB(rn, rib) +		{ +			if (rib->tag != tag) +				continue; + +			if (first) { +				vty_out(vty, SHOW_ROUTE_V4_HEADER); +				first = 0; +			} +			vty_show_ip_route(vty, rn, rib, NULL); +		} +	return CMD_SUCCESS;  }  DEFUN (show_ip_route_prefix_longer, @@ -1381,47 +1404,41 @@ DEFUN (show_ip_route_prefix_longer,         "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"         "Show route matching the specified Network/Mask pair only\n")  { -  struct route_table *table; -  struct route_node *rn; -  struct rib *rib; -  struct prefix p; -  int ret; -  int first = 1; -  vrf_id_t vrf_id = VRF_DEFAULT; - -  if (strmatch(argv[3]->text, "vrf")) -    { -      VRF_GET_ID (vrf_id, argv[4]->arg); -      ret = str2prefix (argv[5]->arg, &p); -    } -  else -    { -      ret = str2prefix (argv[3]->arg, &p); -    } - -  if (! ret) -    { -      vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE); -      return CMD_WARNING; -    } - -  table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id); -  if (! table) -    return CMD_SUCCESS; - -  /* Show matched type IPv4 routes. */ -  for (rn = route_top (table); rn; rn = route_next (rn)) -    RNODE_FOREACH_RIB (rn, rib) -      if (prefix_match (&p, &rn->p)) -	{ -	  if (first) -	    { -	      vty_out (vty, SHOW_ROUTE_V4_HEADER); -	      first = 0; -	    } -	  vty_show_ip_route (vty, rn, rib, NULL); +	struct route_table *table; +	struct route_node *rn; +	struct rib *rib; +	struct prefix p; +	int ret; +	int first = 1; +	vrf_id_t vrf_id = VRF_DEFAULT; + +	if (strmatch(argv[3]->text, "vrf")) { +		VRF_GET_ID(vrf_id, argv[4]->arg); +		ret = str2prefix(argv[5]->arg, &p); +	} else { +		ret = str2prefix(argv[3]->arg, &p);  	} -  return CMD_SUCCESS; + +	if (!ret) { +		vty_out(vty, "%% Malformed Prefix%s", VTY_NEWLINE); +		return CMD_WARNING; +	} + +	table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id); +	if (!table) +		return CMD_SUCCESS; + +	/* Show matched type IPv4 routes. */ +	for (rn = route_top(table); rn; rn = route_next(rn)) +		RNODE_FOREACH_RIB(rn, rib) +	if (prefix_match(&p, &rn->p)) { +		if (first) { +			vty_out(vty, SHOW_ROUTE_V4_HEADER); +			first = 0; +		} +		vty_show_ip_route(vty, rn, rib, NULL); +	} +	return CMD_SUCCESS;  }  DEFUN (show_ip_route_supernets, @@ -1433,39 +1450,37 @@ DEFUN (show_ip_route_supernets,         VRF_CMD_HELP_STR         "Show supernet entries only\n")  { -  struct route_table *table; -  struct route_node *rn; -  struct rib *rib; -  u_int32_t addr; -  int first = 1; -  vrf_id_t vrf_id = VRF_DEFAULT; - -  if (strmatch(argv[3]->text, "vrf")) -    VRF_GET_ID (vrf_id, argv[4]->arg); - -  table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id); -  if (! table) -    return CMD_SUCCESS; - -  /* Show matched type IPv4 routes. */ -  for (rn = route_top (table); rn; rn = route_next (rn)) -    RNODE_FOREACH_RIB (rn, rib) -      { -	addr = ntohl (rn->p.u.prefix4.s_addr); - -	if ((IN_CLASSC (addr) && rn->p.prefixlen < 24) -	   || (IN_CLASSB (addr) && rn->p.prefixlen < 16) -	   || (IN_CLASSA (addr) && rn->p.prefixlen < 8)) -	  { -	    if (first) -	      { -		vty_out (vty, SHOW_ROUTE_V4_HEADER); -		first = 0; -	      } -	    vty_show_ip_route (vty, rn, rib, NULL); -	  } -      } -  return CMD_SUCCESS; +	struct route_table *table; +	struct route_node *rn; +	struct rib *rib; +	u_int32_t addr; +	int first = 1; +	vrf_id_t vrf_id = VRF_DEFAULT; + +	if (strmatch(argv[3]->text, "vrf")) +		VRF_GET_ID(vrf_id, argv[4]->arg); + +	table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id); +	if (!table) +		return CMD_SUCCESS; + +	/* Show matched type IPv4 routes. */ +	for (rn = route_top(table); rn; rn = route_next(rn)) +		RNODE_FOREACH_RIB(rn, rib) +		{ +			addr = ntohl(rn->p.u.prefix4.s_addr); + +			if ((IN_CLASSC(addr) && rn->p.prefixlen < 24) +			    || (IN_CLASSB(addr) && rn->p.prefixlen < 16) +			    || (IN_CLASSA(addr) && rn->p.prefixlen < 8)) { +				if (first) { +					vty_out(vty, SHOW_ROUTE_V4_HEADER); +					first = 0; +				} +				vty_show_ip_route(vty, rn, rib, NULL); +			} +		} +	return CMD_SUCCESS;  }  DEFUN (show_ip_route_protocol, @@ -1477,43 +1492,40 @@ DEFUN (show_ip_route_protocol,         VRF_CMD_HELP_STR         FRR_IP_REDIST_HELP_STR_ZEBRA)  { -  int type; -  struct route_table *table; -  struct route_node *rn; -  struct rib *rib; -  int first = 1; -  vrf_id_t vrf_id = VRF_DEFAULT; - -  int idx = 0; -  if (argv_find (argv, argc, "NAME", &idx)) -    VRF_GET_ID (vrf_id, argv[idx]->arg); - -  char *proto = argv[argc - 1]->text; -  type = proto_redistnum (AFI_IP, proto); - -  if (type < 0) -    { -      vty_out (vty, "Unknown route type%s", VTY_NEWLINE); -      return CMD_WARNING; -    } - -  table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id); -  if (! table) -    return CMD_SUCCESS; - -  /* Show matched type IPv4 routes. */ -  for (rn = route_top (table); rn; rn = route_next (rn)) -    RNODE_FOREACH_RIB (rn, rib) -      if (rib->type == type) -	{ -	  if (first) -	    { -	      vty_out (vty, SHOW_ROUTE_V4_HEADER); -	      first = 0; -	    } -	  vty_show_ip_route (vty, rn, rib, NULL); +	int type; +	struct route_table *table; +	struct route_node *rn; +	struct rib *rib; +	int first = 1; +	vrf_id_t vrf_id = VRF_DEFAULT; + +	int idx = 0; +	if (argv_find(argv, argc, "NAME", &idx)) +		VRF_GET_ID(vrf_id, argv[idx]->arg); + +	char *proto = argv[argc - 1]->text; +	type = proto_redistnum(AFI_IP, proto); + +	if (type < 0) { +		vty_out(vty, "Unknown route type%s", VTY_NEWLINE); +		return CMD_WARNING; +	} + +	table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id); +	if (!table) +		return CMD_SUCCESS; + +	/* Show matched type IPv4 routes. */ +	for (rn = route_top(table); rn; rn = route_next(rn)) +		RNODE_FOREACH_RIB(rn, rib) +	if (rib->type == type) { +		if (first) { +			vty_out(vty, SHOW_ROUTE_V4_HEADER); +			first = 0; +		} +		vty_show_ip_route(vty, rn, rib, NULL);  	} -  return CMD_SUCCESS; +	return CMD_SUCCESS;  } @@ -1526,32 +1538,30 @@ DEFUN (show_ip_route_ospf_instance,         "Open Shortest Path First (OSPFv2)\n"         "Instance ID\n")  { -  int idx_number = 4; -  struct route_table *table; -  struct route_node *rn; -  struct rib *rib; -  int first = 1; -  u_short instance = 0; - -  VTY_GET_INTEGER ("Instance", instance, argv[idx_number]->arg); - -  table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, VRF_DEFAULT); -  if (! table) -    return CMD_SUCCESS; - -  /* Show matched type IPv4 routes. */ -  for (rn = route_top (table); rn; rn = route_next (rn)) -    RNODE_FOREACH_RIB (rn, rib) -      if (rib->type == ZEBRA_ROUTE_OSPF && rib->instance == instance) -	{ -	  if (first) -	    { -	      vty_out (vty, SHOW_ROUTE_V4_HEADER); -	      first = 0; -	    } -	  vty_show_ip_route (vty, rn, rib, NULL); +	int idx_number = 4; +	struct route_table *table; +	struct route_node *rn; +	struct rib *rib; +	int first = 1; +	u_short instance = 0; + +	VTY_GET_INTEGER("Instance", instance, argv[idx_number]->arg); + +	table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, VRF_DEFAULT); +	if (!table) +		return CMD_SUCCESS; + +	/* Show matched type IPv4 routes. */ +	for (rn = route_top(table); rn; rn = route_next(rn)) +		RNODE_FOREACH_RIB(rn, rib) +	if (rib->type == ZEBRA_ROUTE_OSPF && rib->instance == instance) { +		if (first) { +			vty_out(vty, SHOW_ROUTE_V4_HEADER); +			first = 0; +		} +		vty_show_ip_route(vty, rn, rib, NULL);  	} -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (show_ip_route_addr, @@ -1563,44 +1573,39 @@ DEFUN (show_ip_route_addr,         VRF_CMD_HELP_STR         "Network in the IP routing table to display\n")  { -  int ret; -  struct prefix_ipv4 p; -  struct route_table *table; -  struct route_node *rn; -  vrf_id_t vrf_id = VRF_DEFAULT; - -  if (strmatch(argv[3]->text, "vrf")) -    { -      VRF_GET_ID (vrf_id, argv[4]->arg); -      ret = str2prefix_ipv4 (argv[5]->arg, &p); -    } -  else -    { -      ret = str2prefix_ipv4 (argv[3]->arg, &p); -    } +	int ret; +	struct prefix_ipv4 p; +	struct route_table *table; +	struct route_node *rn; +	vrf_id_t vrf_id = VRF_DEFAULT; + +	if (strmatch(argv[3]->text, "vrf")) { +		VRF_GET_ID(vrf_id, argv[4]->arg); +		ret = str2prefix_ipv4(argv[5]->arg, &p); +	} else { +		ret = str2prefix_ipv4(argv[3]->arg, &p); +	} -  if (ret <= 0) -    { -      vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE); -      return CMD_WARNING; -    } +	if (ret <= 0) { +		vty_out(vty, "%% Malformed IPv4 address%s", VTY_NEWLINE); +		return CMD_WARNING; +	} -  table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id); -  if (! table) -    return CMD_SUCCESS; +	table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id); +	if (!table) +		return CMD_SUCCESS; -  rn = route_node_match (table, (struct prefix *) &p); -  if (! rn) -    { -      vty_out (vty, "%% Network not in table%s", VTY_NEWLINE); -      return CMD_WARNING; -    } +	rn = route_node_match(table, (struct prefix *)&p); +	if (!rn) { +		vty_out(vty, "%% Network not in table%s", VTY_NEWLINE); +		return CMD_WARNING; +	} -  vty_show_ip_route_detail (vty, rn, 0); +	vty_show_ip_route_detail(vty, rn, 0); -  route_unlock_node (rn); +	route_unlock_node(rn); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (show_ip_route_prefix, @@ -1612,113 +1617,104 @@ DEFUN (show_ip_route_prefix,         VRF_CMD_HELP_STR         "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")  { -  int ret; -  struct prefix_ipv4 p; -  struct route_table *table; -  struct route_node *rn; -  vrf_id_t vrf_id = VRF_DEFAULT; - -  if (strmatch(argv[3]->text, "vrf")) -    { -      VRF_GET_ID (vrf_id, argv[4]->arg); -      ret = str2prefix_ipv4 (argv[5]->arg, &p); -    } -  else -    { -      ret = str2prefix_ipv4 (argv[3]->arg, &p); -    } +	int ret; +	struct prefix_ipv4 p; +	struct route_table *table; +	struct route_node *rn; +	vrf_id_t vrf_id = VRF_DEFAULT; + +	if (strmatch(argv[3]->text, "vrf")) { +		VRF_GET_ID(vrf_id, argv[4]->arg); +		ret = str2prefix_ipv4(argv[5]->arg, &p); +	} else { +		ret = str2prefix_ipv4(argv[3]->arg, &p); +	} -  if (ret <= 0) -    { -      vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE); -      return CMD_WARNING; -    } +	if (ret <= 0) { +		vty_out(vty, "%% Malformed IPv4 address%s", VTY_NEWLINE); +		return CMD_WARNING; +	} -  table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id); -  if (! table) -    return CMD_SUCCESS; +	table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id); +	if (!table) +		return CMD_SUCCESS; -  rn = route_node_match (table, (struct prefix *) &p); -  if (! rn || rn->p.prefixlen != p.prefixlen) -    { -      vty_out (vty, "%% Network not in table%s", VTY_NEWLINE); -      return CMD_WARNING; -    } +	rn = route_node_match(table, (struct prefix *)&p); +	if (!rn || rn->p.prefixlen != p.prefixlen) { +		vty_out(vty, "%% Network not in table%s", VTY_NEWLINE); +		return CMD_WARNING; +	} -  vty_show_ip_route_detail (vty, rn, 0); +	vty_show_ip_route_detail(vty, rn, 0); -  route_unlock_node (rn); +	route_unlock_node(rn); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  } -static void -vty_show_ip_route_summary (struct vty *vty, struct route_table *table) +static void vty_show_ip_route_summary(struct vty *vty, +				      struct route_table *table)  { -  struct route_node *rn; -  struct rib *rib; +	struct route_node *rn; +	struct rib *rib;  #define ZEBRA_ROUTE_IBGP  ZEBRA_ROUTE_MAX  #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1) -  u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1]; -  u_int32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1]; -  u_int32_t i; -  u_int32_t is_ibgp; - -  memset (&rib_cnt, 0, sizeof(rib_cnt)); -  memset (&fib_cnt, 0, sizeof(fib_cnt)); -  for (rn = route_top (table); rn; rn = srcdest_route_next (rn)) -    RNODE_FOREACH_RIB (rn, rib) -      { -        is_ibgp = (rib->type == ZEBRA_ROUTE_BGP && -                   CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP)); - -        rib_cnt[ZEBRA_ROUTE_TOTAL]++; -        if (is_ibgp) -          rib_cnt[ZEBRA_ROUTE_IBGP]++; -        else -          rib_cnt[rib->type]++; - -        if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) -          { -            fib_cnt[ZEBRA_ROUTE_TOTAL]++; - -            if (is_ibgp) -              fib_cnt[ZEBRA_ROUTE_IBGP]++; -            else -              fib_cnt[rib->type]++; -          } -      } - -  vty_out (vty, "%-20s %-20s %s  (vrf %s)%s", -           "Route Source", "Routes", "FIB", -           zvrf_name (((rib_table_info_t *)table->info)->zvrf), -           VTY_NEWLINE); - -  for (i = 0; i < ZEBRA_ROUTE_MAX; i++) -    { -      if ((rib_cnt[i] > 0) || -	  (i == ZEBRA_ROUTE_BGP && rib_cnt[ZEBRA_ROUTE_IBGP] > 0)) -        { -          if (i == ZEBRA_ROUTE_BGP) -            { -              vty_out (vty, "%-20s %-20d %-20d %s", "ebgp", -                       rib_cnt[ZEBRA_ROUTE_BGP], fib_cnt[ZEBRA_ROUTE_BGP], -                       VTY_NEWLINE); -              vty_out (vty, "%-20s %-20d %-20d %s", "ibgp", -                       rib_cnt[ZEBRA_ROUTE_IBGP], fib_cnt[ZEBRA_ROUTE_IBGP], -                       VTY_NEWLINE); -            } -          else -            vty_out (vty, "%-20s %-20d %-20d %s", zebra_route_string(i), -                     rib_cnt[i], fib_cnt[i], VTY_NEWLINE); -        } -    } - -  vty_out (vty, "------%s", VTY_NEWLINE); -  vty_out (vty, "%-20s %-20d %-20d %s", "Totals", rib_cnt[ZEBRA_ROUTE_TOTAL], -           fib_cnt[ZEBRA_ROUTE_TOTAL], VTY_NEWLINE); -  vty_out (vty, "%s", VTY_NEWLINE); +	u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1]; +	u_int32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1]; +	u_int32_t i; +	u_int32_t is_ibgp; + +	memset(&rib_cnt, 0, sizeof(rib_cnt)); +	memset(&fib_cnt, 0, sizeof(fib_cnt)); +	for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) +		RNODE_FOREACH_RIB(rn, rib) +		{ +			is_ibgp = (rib->type == ZEBRA_ROUTE_BGP +				   && CHECK_FLAG(rib->flags, ZEBRA_FLAG_IBGP)); + +			rib_cnt[ZEBRA_ROUTE_TOTAL]++; +			if (is_ibgp) +				rib_cnt[ZEBRA_ROUTE_IBGP]++; +			else +				rib_cnt[rib->type]++; + +			if (CHECK_FLAG(rib->flags, ZEBRA_FLAG_SELECTED)) { +				fib_cnt[ZEBRA_ROUTE_TOTAL]++; + +				if (is_ibgp) +					fib_cnt[ZEBRA_ROUTE_IBGP]++; +				else +					fib_cnt[rib->type]++; +			} +		} + +	vty_out(vty, "%-20s %-20s %s  (vrf %s)%s", "Route Source", "Routes", +		"FIB", zvrf_name(((rib_table_info_t *)table->info)->zvrf), +		VTY_NEWLINE); + +	for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { +		if ((rib_cnt[i] > 0) || (i == ZEBRA_ROUTE_BGP +					 && rib_cnt[ZEBRA_ROUTE_IBGP] > 0)) { +			if (i == ZEBRA_ROUTE_BGP) { +				vty_out(vty, "%-20s %-20d %-20d %s", "ebgp", +					rib_cnt[ZEBRA_ROUTE_BGP], +					fib_cnt[ZEBRA_ROUTE_BGP], VTY_NEWLINE); +				vty_out(vty, "%-20s %-20d %-20d %s", "ibgp", +					rib_cnt[ZEBRA_ROUTE_IBGP], +					fib_cnt[ZEBRA_ROUTE_IBGP], VTY_NEWLINE); +			} else +				vty_out(vty, "%-20s %-20d %-20d %s", +					zebra_route_string(i), rib_cnt[i], +					fib_cnt[i], VTY_NEWLINE); +		} +	} + +	vty_out(vty, "------%s", VTY_NEWLINE); +	vty_out(vty, "%-20s %-20d %-20d %s", "Totals", +		rib_cnt[ZEBRA_ROUTE_TOTAL], fib_cnt[ZEBRA_ROUTE_TOTAL], +		VTY_NEWLINE); +	vty_out(vty, "%s", VTY_NEWLINE);  }  /* @@ -1728,78 +1724,79 @@ vty_show_ip_route_summary (struct vty *vty, struct route_table *table)   * protocols on the box.   *   */ -static void -vty_show_ip_route_summary_prefix (struct vty *vty, struct route_table *table) +static void vty_show_ip_route_summary_prefix(struct vty *vty, +					     struct route_table *table)  { -  struct route_node *rn; -  struct rib *rib; -  struct nexthop *nexthop; +	struct route_node *rn; +	struct rib *rib; +	struct nexthop *nexthop;  #define ZEBRA_ROUTE_IBGP  ZEBRA_ROUTE_MAX  #define ZEBRA_ROUTE_TOTAL (ZEBRA_ROUTE_IBGP + 1) -  u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1]; -  u_int32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1]; -  u_int32_t i; -  int       cnt; - -  memset (&rib_cnt, 0, sizeof(rib_cnt)); -  memset (&fib_cnt, 0, sizeof(fib_cnt)); -  for (rn = route_top (table); rn; rn = srcdest_route_next (rn)) -    RNODE_FOREACH_RIB (rn, rib) -      { - -       /* -        * In case of ECMP, count only once. -        */ -       cnt = 0; -       for (nexthop = rib->nexthop; (!cnt && nexthop); nexthop = nexthop->next) -         { -          cnt++; -          rib_cnt[ZEBRA_ROUTE_TOTAL]++; -          rib_cnt[rib->type]++; -          if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) -	        { -	         fib_cnt[ZEBRA_ROUTE_TOTAL]++; -             fib_cnt[rib->type]++; -            } -	      if (rib->type == ZEBRA_ROUTE_BGP && -	          CHECK_FLAG (rib->flags, ZEBRA_FLAG_IBGP)) -            { -	         rib_cnt[ZEBRA_ROUTE_IBGP]++; -		     if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)) -		        fib_cnt[ZEBRA_ROUTE_IBGP]++; -            } -	     } -      } - -  vty_out (vty, "%-20s %-20s %s  (vrf %s)%s", -           "Route Source", "Prefix Routes", "FIB", -           zvrf_name (((rib_table_info_t *)table->info)->zvrf), -           VTY_NEWLINE); - -  for (i = 0; i < ZEBRA_ROUTE_MAX; i++) -    { -      if (rib_cnt[i] > 0) -	{ -	  if (i == ZEBRA_ROUTE_BGP) -	    { -	      vty_out (vty, "%-20s %-20d %-20d %s", "ebgp", -		       rib_cnt[ZEBRA_ROUTE_BGP] - rib_cnt[ZEBRA_ROUTE_IBGP], -		       fib_cnt[ZEBRA_ROUTE_BGP] - fib_cnt[ZEBRA_ROUTE_IBGP], -		       VTY_NEWLINE); -	      vty_out (vty, "%-20s %-20d %-20d %s", "ibgp", -		       rib_cnt[ZEBRA_ROUTE_IBGP], fib_cnt[ZEBRA_ROUTE_IBGP], -		       VTY_NEWLINE); -	    } -	  else -	    vty_out (vty, "%-20s %-20d %-20d %s", zebra_route_string(i), -		     rib_cnt[i], fib_cnt[i], VTY_NEWLINE); -	} -    } - -  vty_out (vty, "------%s", VTY_NEWLINE); -  vty_out (vty, "%-20s %-20d %-20d %s", "Totals", rib_cnt[ZEBRA_ROUTE_TOTAL], -	   fib_cnt[ZEBRA_ROUTE_TOTAL], VTY_NEWLINE); -  vty_out (vty, "%s", VTY_NEWLINE); +	u_int32_t rib_cnt[ZEBRA_ROUTE_TOTAL + 1]; +	u_int32_t fib_cnt[ZEBRA_ROUTE_TOTAL + 1]; +	u_int32_t i; +	int cnt; + +	memset(&rib_cnt, 0, sizeof(rib_cnt)); +	memset(&fib_cnt, 0, sizeof(fib_cnt)); +	for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) +		RNODE_FOREACH_RIB(rn, rib) +		{ + +			/* +			 * In case of ECMP, count only once. +			 */ +			cnt = 0; +			for (nexthop = rib->nexthop; (!cnt && nexthop); +			     nexthop = nexthop->next) { +				cnt++; +				rib_cnt[ZEBRA_ROUTE_TOTAL]++; +				rib_cnt[rib->type]++; +				if (CHECK_FLAG(nexthop->flags, +					       NEXTHOP_FLAG_FIB)) { +					fib_cnt[ZEBRA_ROUTE_TOTAL]++; +					fib_cnt[rib->type]++; +				} +				if (rib->type == ZEBRA_ROUTE_BGP +				    && CHECK_FLAG(rib->flags, +						  ZEBRA_FLAG_IBGP)) { +					rib_cnt[ZEBRA_ROUTE_IBGP]++; +					if (CHECK_FLAG(nexthop->flags, +						       NEXTHOP_FLAG_FIB)) +						fib_cnt[ZEBRA_ROUTE_IBGP]++; +				} +			} +		} + +	vty_out(vty, "%-20s %-20s %s  (vrf %s)%s", "Route Source", +		"Prefix Routes", "FIB", +		zvrf_name(((rib_table_info_t *)table->info)->zvrf), +		VTY_NEWLINE); + +	for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { +		if (rib_cnt[i] > 0) { +			if (i == ZEBRA_ROUTE_BGP) { +				vty_out(vty, "%-20s %-20d %-20d %s", "ebgp", +					rib_cnt[ZEBRA_ROUTE_BGP] +						- rib_cnt[ZEBRA_ROUTE_IBGP], +					fib_cnt[ZEBRA_ROUTE_BGP] +						- fib_cnt[ZEBRA_ROUTE_IBGP], +					VTY_NEWLINE); +				vty_out(vty, "%-20s %-20d %-20d %s", "ibgp", +					rib_cnt[ZEBRA_ROUTE_IBGP], +					fib_cnt[ZEBRA_ROUTE_IBGP], VTY_NEWLINE); +			} else +				vty_out(vty, "%-20s %-20d %-20d %s", +					zebra_route_string(i), rib_cnt[i], +					fib_cnt[i], VTY_NEWLINE); +		} +	} + +	vty_out(vty, "------%s", VTY_NEWLINE); +	vty_out(vty, "%-20s %-20d %-20d %s", "Totals", +		rib_cnt[ZEBRA_ROUTE_TOTAL], fib_cnt[ZEBRA_ROUTE_TOTAL], +		VTY_NEWLINE); +	vty_out(vty, "%s", VTY_NEWLINE);  }  /* Show route summary.  */ @@ -1812,19 +1809,19 @@ DEFUN (show_ip_route_summary,         VRF_CMD_HELP_STR         "Summary of all routes\n")  { -  struct route_table *table; -  vrf_id_t vrf_id = VRF_DEFAULT; +	struct route_table *table; +	vrf_id_t vrf_id = VRF_DEFAULT; -  if (strmatch(argv[3]->text, "vrf")) -    VRF_GET_ID (vrf_id, argv[4]->arg); +	if (strmatch(argv[3]->text, "vrf")) +		VRF_GET_ID(vrf_id, argv[4]->arg); -  table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id); -  if (! table) -    return CMD_SUCCESS; +	table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id); +	if (!table) +		return CMD_SUCCESS; -  vty_show_ip_route_summary (vty, table); +	vty_show_ip_route_summary(vty, table); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  /* Show route summary prefix.  */ @@ -1838,19 +1835,19 @@ DEFUN (show_ip_route_summary_prefix,         "Summary of all routes\n"         "Prefix routes\n")  { -  struct route_table *table; -  vrf_id_t vrf_id = VRF_DEFAULT; +	struct route_table *table; +	vrf_id_t vrf_id = VRF_DEFAULT; -  if (strmatch(argv[3]->text, "vrf")) -    VRF_GET_ID (vrf_id, argv[4]->arg); +	if (strmatch(argv[3]->text, "vrf")) +		VRF_GET_ID(vrf_id, argv[4]->arg); -  table = zebra_vrf_table (AFI_IP, SAFI_UNICAST, vrf_id); -  if (! table) -    return CMD_SUCCESS; +	table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id); +	if (!table) +		return CMD_SUCCESS; -  vty_show_ip_route_summary_prefix (vty, table); +	vty_show_ip_route_summary_prefix(vty, table); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  } @@ -1862,41 +1859,40 @@ DEFUN (show_ip_route_vrf_all,         "IP routing table\n"         VRF_ALL_CMD_HELP_STR)  { -  struct route_table *table; -  struct route_node *rn; -  struct rib *rib; -  struct vrf *vrf; -  struct zebra_vrf *zvrf; -  int first = 1; -  int vrf_header = 1; - -  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) -    { -      if ((zvrf = vrf->info) == NULL || -          (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) -        continue; - -      /* Show all IPv4 routes. */ -      for (rn = route_top (table); rn; rn = route_next (rn)) -        RNODE_FOREACH_RIB (rn, rib) -          { -            if (first) -              { -                vty_out (vty, SHOW_ROUTE_V4_HEADER); -                first = 0; -              } - -            if (vrf_header) -              { -                vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); -                vrf_header = 0; -              } -            vty_show_ip_route (vty, rn, rib, NULL); -          } -      vrf_header  = 1; -    } - -  return CMD_SUCCESS; +	struct route_table *table; +	struct route_node *rn; +	struct rib *rib; +	struct vrf *vrf; +	struct zebra_vrf *zvrf; +	int first = 1; +	int vrf_header = 1; + +	RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) +	{ +		if ((zvrf = vrf->info) == NULL +		    || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) +			continue; + +		/* Show all IPv4 routes. */ +		for (rn = route_top(table); rn; rn = route_next(rn)) +			RNODE_FOREACH_RIB(rn, rib) +			{ +				if (first) { +					vty_out(vty, SHOW_ROUTE_V4_HEADER); +					first = 0; +				} + +				if (vrf_header) { +					vty_out(vty, "%sVRF %s:%s", VTY_NEWLINE, +						zvrf_name(zvrf), VTY_NEWLINE); +					vrf_header = 0; +				} +				vty_show_ip_route(vty, rn, rib, NULL); +			} +		vrf_header = 1; +	} + +	return CMD_SUCCESS;  }  DEFUN (show_ip_route_vrf_all_tag, @@ -1909,48 +1905,48 @@ DEFUN (show_ip_route_vrf_all_tag,         "Show only routes with tag\n"         "Tag value\n")  { -  int idx_number = 6; -  struct route_table *table; -  struct route_node *rn; -  struct rib *rib; -  struct vrf *vrf; -  struct zebra_vrf *zvrf; -  int first = 1; -  int vrf_header = 1; -  route_tag_t tag = 0; - -  if (argv[idx_number]->arg) -    VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_number]->arg, 0, 4294967295); - -  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) -    { -      if ((zvrf = vrf->info) == NULL || -          (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) -        continue; - -      /* Show all IPv4 routes with matching tag value. */ -      for (rn = route_top (table); rn; rn = route_next (rn)) -        RNODE_FOREACH_RIB (rn, rib) -          { -            if (rib->tag != tag) -              continue; - -            if (first) -              { -                vty_out (vty, SHOW_ROUTE_V4_HEADER); -                first = 0; -              } - -            if (vrf_header) -              { -                vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); -                vrf_header = 0; -              } -            vty_show_ip_route (vty, rn, rib, NULL); -          } -      vrf_header = 1; -    } -  return CMD_SUCCESS; +	int idx_number = 6; +	struct route_table *table; +	struct route_node *rn; +	struct rib *rib; +	struct vrf *vrf; +	struct zebra_vrf *zvrf; +	int first = 1; +	int vrf_header = 1; +	route_tag_t tag = 0; + +	if (argv[idx_number]->arg) +		VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_number]->arg, 0, +				      4294967295); + +	RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) +	{ +		if ((zvrf = vrf->info) == NULL +		    || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) +			continue; + +		/* Show all IPv4 routes with matching tag value. */ +		for (rn = route_top(table); rn; rn = route_next(rn)) +			RNODE_FOREACH_RIB(rn, rib) +			{ +				if (rib->tag != tag) +					continue; + +				if (first) { +					vty_out(vty, SHOW_ROUTE_V4_HEADER); +					first = 0; +				} + +				if (vrf_header) { +					vty_out(vty, "%sVRF %s:%s", VTY_NEWLINE, +						zvrf_name(zvrf), VTY_NEWLINE); +					vrf_header = 0; +				} +				vty_show_ip_route(vty, rn, rib, NULL); +			} +		vrf_header = 1; +	} +	return CMD_SUCCESS;  }  DEFUN (show_ip_route_vrf_all_prefix_longer, @@ -1963,52 +1959,49 @@ DEFUN (show_ip_route_vrf_all_prefix_longer,         "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"         "Show route matching the specified Network/Mask pair only\n")  { -  int idx_ipv4_prefixlen = 5; -  struct route_table *table; -  struct route_node *rn; -  struct rib *rib; -  struct prefix p; -  struct vrf *vrf; -  struct zebra_vrf *zvrf; -  int ret; -  int first = 1; -  int vrf_header = 1; - -  ret = str2prefix (argv[idx_ipv4_prefixlen]->arg, &p); -  if (! ret) -    { -      vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE); -      return CMD_WARNING; -    } - -  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) -    { -      if ((zvrf = vrf->info) == NULL || -          (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) -        continue; - -      /* Show matched type IPv4 routes. */ -      for (rn = route_top (table); rn; rn = route_next (rn)) -        RNODE_FOREACH_RIB (rn, rib) -          if (prefix_match (&p, &rn->p)) -            { -              if (first) -                { -                  vty_out (vty, SHOW_ROUTE_V4_HEADER); -                  first = 0; -                } - -              if (vrf_header) -                { -                  vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); -                  vrf_header = 0; -                } -              vty_show_ip_route (vty, rn, rib, NULL); -            } -      vrf_header = 1; -    } - -  return CMD_SUCCESS; +	int idx_ipv4_prefixlen = 5; +	struct route_table *table; +	struct route_node *rn; +	struct rib *rib; +	struct prefix p; +	struct vrf *vrf; +	struct zebra_vrf *zvrf; +	int ret; +	int first = 1; +	int vrf_header = 1; + +	ret = str2prefix(argv[idx_ipv4_prefixlen]->arg, &p); +	if (!ret) { +		vty_out(vty, "%% Malformed Prefix%s", VTY_NEWLINE); +		return CMD_WARNING; +	} + +	RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) +	{ +		if ((zvrf = vrf->info) == NULL +		    || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) +			continue; + +		/* Show matched type IPv4 routes. */ +		for (rn = route_top(table); rn; rn = route_next(rn)) +			RNODE_FOREACH_RIB(rn, rib) +		if (prefix_match(&p, &rn->p)) { +			if (first) { +				vty_out(vty, SHOW_ROUTE_V4_HEADER); +				first = 0; +			} + +			if (vrf_header) { +				vty_out(vty, "%sVRF %s:%s", VTY_NEWLINE, +					zvrf_name(zvrf), VTY_NEWLINE); +				vrf_header = 0; +			} +			vty_show_ip_route(vty, rn, rib, NULL); +		} +		vrf_header = 1; +	} + +	return CMD_SUCCESS;  }  DEFUN (show_ip_route_vrf_all_supernets, @@ -2020,48 +2013,50 @@ DEFUN (show_ip_route_vrf_all_supernets,         VRF_ALL_CMD_HELP_STR         "Show supernet entries only\n")  { -  struct route_table *table; -  struct route_node *rn; -  struct rib *rib; -  struct vrf *vrf; -  struct zebra_vrf *zvrf; -  u_int32_t addr; -  int first = 1; -  int vrf_header = 1; - -  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) -    { -      if ((zvrf = vrf->info) == NULL || -          (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) -        continue; - -      /* Show matched type IPv4 routes. */ -      for (rn = route_top (table); rn; rn = route_next (rn)) -        RNODE_FOREACH_RIB (rn, rib) -          { -            addr = ntohl (rn->p.u.prefix4.s_addr); - -            if ((IN_CLASSC (addr) && rn->p.prefixlen < 24) -               || (IN_CLASSB (addr) && rn->p.prefixlen < 16) -               || (IN_CLASSA (addr) && rn->p.prefixlen < 8)) -              { -                if (first) -                  { -                    vty_out (vty, SHOW_ROUTE_V4_HEADER); -                    first = 0; -                  } -                if (vrf_header) -                  { -                    vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); -                    vrf_header = 0; -                  } -                vty_show_ip_route (vty, rn, rib, NULL); -              } -          } -      vrf_header = 1; -    } - -  return CMD_SUCCESS; +	struct route_table *table; +	struct route_node *rn; +	struct rib *rib; +	struct vrf *vrf; +	struct zebra_vrf *zvrf; +	u_int32_t addr; +	int first = 1; +	int vrf_header = 1; + +	RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) +	{ +		if ((zvrf = vrf->info) == NULL +		    || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) +			continue; + +		/* Show matched type IPv4 routes. */ +		for (rn = route_top(table); rn; rn = route_next(rn)) +			RNODE_FOREACH_RIB(rn, rib) +			{ +				addr = ntohl(rn->p.u.prefix4.s_addr); + +				if ((IN_CLASSC(addr) && rn->p.prefixlen < 24) +				    || (IN_CLASSB(addr) && rn->p.prefixlen < 16) +				    || (IN_CLASSA(addr) +					&& rn->p.prefixlen < 8)) { +					if (first) { +						vty_out(vty, +							SHOW_ROUTE_V4_HEADER); +						first = 0; +					} +					if (vrf_header) { +						vty_out(vty, "%sVRF %s:%s", +							VTY_NEWLINE, +							zvrf_name(zvrf), +							VTY_NEWLINE); +						vrf_header = 0; +					} +					vty_show_ip_route(vty, rn, rib, NULL); +				} +			} +		vrf_header = 1; +	} + +	return CMD_SUCCESS;  }  DEFUN (show_ip_route_vrf_all_protocol, @@ -2073,52 +2068,49 @@ DEFUN (show_ip_route_vrf_all_protocol,         VRF_ALL_CMD_HELP_STR         FRR_IP_REDIST_HELP_STR_ZEBRA"\n")  { -  int type; -  struct route_table *table; -  struct route_node *rn; -  struct rib *rib; -  struct vrf *vrf; -  struct zebra_vrf *zvrf; -  int first = 1; -  int vrf_header = 1; - -  char *proto = argv[argc - 1]->text; -  type = proto_redistnum (AFI_IP, proto); - -  if (type < 0) -    { -      vty_out (vty, "Unknown route type%s", VTY_NEWLINE); -      return CMD_WARNING; -    } - -  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) -    { -      if ((zvrf = vrf->info) == NULL || -          (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) -        continue; - -      /* Show matched type IPv4 routes. */ -      for (rn = route_top (table); rn; rn = route_next (rn)) -        RNODE_FOREACH_RIB (rn, rib) -          if (rib->type == type) -            { -              if (first) -                { -                  vty_out (vty, SHOW_ROUTE_V4_HEADER); -                  first = 0; -                } - -              if (vrf_header) -                { -                  vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); -                  vrf_header = 0; -                } -              vty_show_ip_route (vty, rn, rib, NULL); -            } -      vrf_header = 1; -    } - -  return CMD_SUCCESS; +	int type; +	struct route_table *table; +	struct route_node *rn; +	struct rib *rib; +	struct vrf *vrf; +	struct zebra_vrf *zvrf; +	int first = 1; +	int vrf_header = 1; + +	char *proto = argv[argc - 1]->text; +	type = proto_redistnum(AFI_IP, proto); + +	if (type < 0) { +		vty_out(vty, "Unknown route type%s", VTY_NEWLINE); +		return CMD_WARNING; +	} + +	RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) +	{ +		if ((zvrf = vrf->info) == NULL +		    || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) +			continue; + +		/* Show matched type IPv4 routes. */ +		for (rn = route_top(table); rn; rn = route_next(rn)) +			RNODE_FOREACH_RIB(rn, rib) +		if (rib->type == type) { +			if (first) { +				vty_out(vty, SHOW_ROUTE_V4_HEADER); +				first = 0; +			} + +			if (vrf_header) { +				vty_out(vty, "%sVRF %s:%s", VTY_NEWLINE, +					zvrf_name(zvrf), VTY_NEWLINE); +				vrf_header = 0; +			} +			vty_show_ip_route(vty, rn, rib, NULL); +		} +		vrf_header = 1; +	} + +	return CMD_SUCCESS;  }  DEFUN (show_ip_route_vrf_all_addr, @@ -2130,37 +2122,36 @@ DEFUN (show_ip_route_vrf_all_addr,         VRF_ALL_CMD_HELP_STR         "Network in the IP routing table to display\n")  { -  int idx_ipv4 = 5; -  int ret; -  struct prefix_ipv4 p; -  struct route_table *table; -  struct route_node *rn; -  struct vrf *vrf; -  struct zebra_vrf *zvrf; - -  ret = str2prefix_ipv4 (argv[idx_ipv4]->arg, &p); -  if (ret <= 0) -    { -      vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE); -      return CMD_WARNING; -    } +	int idx_ipv4 = 5; +	int ret; +	struct prefix_ipv4 p; +	struct route_table *table; +	struct route_node *rn; +	struct vrf *vrf; +	struct zebra_vrf *zvrf; + +	ret = str2prefix_ipv4(argv[idx_ipv4]->arg, &p); +	if (ret <= 0) { +		vty_out(vty, "%% Malformed IPv4 address%s", VTY_NEWLINE); +		return CMD_WARNING; +	} -  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) -    { -      if ((zvrf = vrf->info) == NULL || -          (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) -        continue; +	RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) +	{ +		if ((zvrf = vrf->info) == NULL +		    || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) +			continue; -      rn = route_node_match (table, (struct prefix *) &p); -      if (! rn) -        continue; +		rn = route_node_match(table, (struct prefix *)&p); +		if (!rn) +			continue; -      vty_show_ip_route_detail (vty, rn, 0); +		vty_show_ip_route_detail(vty, rn, 0); -      route_unlock_node (rn); -    } +		route_unlock_node(rn); +	} -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (show_ip_route_vrf_all_prefix, @@ -2172,42 +2163,40 @@ DEFUN (show_ip_route_vrf_all_prefix,         VRF_ALL_CMD_HELP_STR         "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")  { -  int idx_ipv4_prefixlen = 5; -  int ret; -  struct prefix_ipv4 p; -  struct route_table *table; -  struct route_node *rn; -  struct vrf *vrf; -  struct zebra_vrf *zvrf; - -  ret = str2prefix_ipv4 (argv[idx_ipv4_prefixlen]->arg, &p); -  if (ret <= 0) -    { -      vty_out (vty, "%% Malformed IPv4 address%s", VTY_NEWLINE); -      return CMD_WARNING; -    } +	int idx_ipv4_prefixlen = 5; +	int ret; +	struct prefix_ipv4 p; +	struct route_table *table; +	struct route_node *rn; +	struct vrf *vrf; +	struct zebra_vrf *zvrf; + +	ret = str2prefix_ipv4(argv[idx_ipv4_prefixlen]->arg, &p); +	if (ret <= 0) { +		vty_out(vty, "%% Malformed IPv4 address%s", VTY_NEWLINE); +		return CMD_WARNING; +	} -  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) -    { -      if ((zvrf = vrf->info) == NULL || -          (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) -        continue; +	RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) +	{ +		if ((zvrf = vrf->info) == NULL +		    || (table = zvrf->table[AFI_IP][SAFI_UNICAST]) == NULL) +			continue; -      rn = route_node_match (table, (struct prefix *) &p); -      if (! rn) -        continue; -      if (rn->p.prefixlen != p.prefixlen) -        { -          route_unlock_node (rn); -          continue; -        } +		rn = route_node_match(table, (struct prefix *)&p); +		if (!rn) +			continue; +		if (rn->p.prefixlen != p.prefixlen) { +			route_unlock_node(rn); +			continue; +		} -      vty_show_ip_route_detail (vty, rn, 0); +		vty_show_ip_route_detail(vty, rn, 0); -      route_unlock_node (rn); -    } +		route_unlock_node(rn); +	} -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (show_ip_route_vrf_all_summary, @@ -2219,14 +2208,15 @@ DEFUN (show_ip_route_vrf_all_summary,         VRF_ALL_CMD_HELP_STR         "Summary of all routes\n")  { -  struct vrf *vrf; -  struct zebra_vrf *zvrf; +	struct vrf *vrf; +	struct zebra_vrf *zvrf; -  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) -    if ((zvrf = vrf->info) != NULL) -      vty_show_ip_route_summary (vty, zvrf->table[AFI_IP][SAFI_UNICAST]); +	RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) +	if ((zvrf = vrf->info) != NULL) +		vty_show_ip_route_summary(vty, +					  zvrf->table[AFI_IP][SAFI_UNICAST]); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (show_ip_route_vrf_all_summary_prefix, @@ -2239,245 +2229,252 @@ DEFUN (show_ip_route_vrf_all_summary_prefix,         "Summary of all routes\n"         "Prefix routes\n")  { -  struct vrf *vrf; -  struct zebra_vrf *zvrf; +	struct vrf *vrf; +	struct zebra_vrf *zvrf; -  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) -    if ((zvrf = vrf->info) != NULL) -      vty_show_ip_route_summary_prefix (vty, zvrf->table[AFI_IP][SAFI_UNICAST]); +	RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) +	if ((zvrf = vrf->info) != NULL) +		vty_show_ip_route_summary_prefix( +			vty, zvrf->table[AFI_IP][SAFI_UNICAST]); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  /* Write IPv4 static route configuration. */ -static int -static_config_ipv4 (struct vty *vty, safi_t safi, const char *cmd) -{ -  struct route_node *rn; -  struct static_route *si; -  struct route_table *stable; -  struct vrf *vrf; -  struct zebra_vrf *zvrf; -  char buf[BUFSIZ]; -  int write =0; - -  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) -    { -      if (!(zvrf = vrf->info)) -        continue; -      if ((stable = zvrf->stable[AFI_IP][safi]) == NULL) -        continue; - -      for (rn = route_top (stable); rn; rn = route_next (rn)) -        for (si = rn->info; si; si = si->next) -          { -            vty_out (vty, "%s %s", cmd, prefix2str (&rn->p, buf, sizeof buf)); - -            switch (si->type) -              { -              case STATIC_IPV4_GATEWAY: -                vty_out (vty, " %s", inet_ntoa (si->addr.ipv4)); -                break; -              case STATIC_IFNAME: -                vty_out (vty, " %s", si->ifname); -                break; -              case STATIC_BLACKHOLE: -                vty_out (vty, " Null0"); -                break; -	      case STATIC_IPV6_GATEWAY: -		vty_out (vty, " %s", inet_ntop (AF_INET6, &si->addr.ipv6, buf, BUFSIZ)); -		break; -	      case STATIC_IPV6_GATEWAY_IFNAME: -		vty_out (vty, " %s %s", -			 inet_ntop (AF_INET6, &si->addr.ipv6, buf, BUFSIZ), -			 ifindex2ifname (si->ifindex, si->vrf_id)); -		break; -              } - -            /* flags are incompatible with STATIC_BLACKHOLE */ -            if (si->type != STATIC_BLACKHOLE) -              { -                if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT)) -                  vty_out (vty, " %s", "reject"); - -                if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE)) -                  vty_out (vty, " %s", "blackhole"); -              } - -            if (si->tag) -              vty_out (vty, " tag %"ROUTE_TAG_PRI, si->tag); - -            if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT) -              vty_out (vty, " %d", si->distance); - -            if (si->vrf_id != VRF_DEFAULT) -                vty_out (vty, " vrf %s", zvrf ? zvrf_name (zvrf) : ""); - -            /* Label information */ -            if (si->snh_label.num_labels) -              vty_out (vty, " label %s", -                       mpls_label2str (si->snh_label.num_labels, -                                       si->snh_label.label, buf, sizeof buf)); - -            vty_out (vty, "%s", VTY_NEWLINE); - -            write = 1; -          } -    } -  return write; +static int static_config_ipv4(struct vty *vty, safi_t safi, const char *cmd) +{ +	struct route_node *rn; +	struct static_route *si; +	struct route_table *stable; +	struct vrf *vrf; +	struct zebra_vrf *zvrf; +	char buf[BUFSIZ]; +	int write = 0; + +	RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) +	{ +		if (!(zvrf = vrf->info)) +			continue; +		if ((stable = zvrf->stable[AFI_IP][safi]) == NULL) +			continue; + +		for (rn = route_top(stable); rn; rn = route_next(rn)) +			for (si = rn->info; si; si = si->next) { +				vty_out(vty, "%s %s", cmd, +					prefix2str(&rn->p, buf, sizeof buf)); + +				switch (si->type) { +				case STATIC_IPV4_GATEWAY: +					vty_out(vty, " %s", +						inet_ntoa(si->addr.ipv4)); +					break; +				case STATIC_IFNAME: +					vty_out(vty, " %s", si->ifname); +					break; +				case STATIC_BLACKHOLE: +					vty_out(vty, " Null0"); +					break; +				case STATIC_IPV6_GATEWAY: +					vty_out(vty, " %s", +						inet_ntop(AF_INET6, +							  &si->addr.ipv6, buf, +							  BUFSIZ)); +					break; +				case STATIC_IPV6_GATEWAY_IFNAME: +					vty_out(vty, " %s %s", +						inet_ntop(AF_INET6, +							  &si->addr.ipv6, buf, +							  BUFSIZ), +						ifindex2ifname(si->ifindex, +							       si->vrf_id)); +					break; +				} + +				/* flags are incompatible with STATIC_BLACKHOLE +				 */ +				if (si->type != STATIC_BLACKHOLE) { +					if (CHECK_FLAG(si->flags, +						       ZEBRA_FLAG_REJECT)) +						vty_out(vty, " %s", "reject"); + +					if (CHECK_FLAG(si->flags, +						       ZEBRA_FLAG_BLACKHOLE)) +						vty_out(vty, " %s", +							"blackhole"); +				} + +				if (si->tag) +					vty_out(vty, " tag %" ROUTE_TAG_PRI, +						si->tag); + +				if (si->distance +				    != ZEBRA_STATIC_DISTANCE_DEFAULT) +					vty_out(vty, " %d", si->distance); + +				if (si->vrf_id != VRF_DEFAULT) +					vty_out(vty, " vrf %s", +						zvrf ? zvrf_name(zvrf) : ""); + +				/* Label information */ +				if (si->snh_label.num_labels) +					vty_out(vty, " label %s", +						mpls_label2str( +							si->snh_label +								.num_labels, +							si->snh_label.label, +							buf, sizeof buf)); + +				vty_out(vty, "%s", VTY_NEWLINE); + +				write = 1; +			} +	} +	return write;  }  /* General fucntion for IPv6 static route. */ -int -static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str, -                  const char *src_str, -                  const char *gate_str, const char *ifname, -                  const char *flag_str, const char *tag_str, -                  const char *distance_str, const char *vrf_id_str, -                  const char *label_str) -{ -  int ret; -  u_char distance; -  struct prefix p, src; -  struct prefix_ipv6 *src_p = NULL; -  struct in6_addr *gate = NULL; -  struct in6_addr gate_addr; -  u_char type = STATIC_BLACKHOLE; -  u_char flag = 0; -  route_tag_t tag = 0; -  struct zebra_vrf *zvrf; -  struct static_nh_label snh_label; - -  ret = str2prefix (dest_str, &p); -  if (ret <= 0) -    { -      vty_out (vty, "%% Malformed address%s", VTY_NEWLINE); -      return CMD_WARNING; -    } - -  if (src_str) -    { -      ret = str2prefix (src_str, &src); -      if (ret <= 0 || src.family != AF_INET6) -        { -          vty_out (vty, "%% Malformed source address%s", VTY_NEWLINE); -          return CMD_WARNING; -        } -      src_p = (struct prefix_ipv6*)&src; -    } - -  /* Apply mask for given prefix. */ -  apply_mask (&p); - -  /* Administrative distance. */ -  if (distance_str) -    distance = atoi (distance_str); -  else -    distance = ZEBRA_STATIC_DISTANCE_DEFAULT; - -  /* tag */ -  if (tag_str) -    VTY_GET_INTEGER_RANGE("tag", tag, tag_str, 0, 4294967295); - -  /* When gateway is valid IPv6 addrees, then gate is treated as -     nexthop address other case gate is treated as interface name. */ -  ret = inet_pton (AF_INET6, gate_str, &gate_addr); - -  /* VRF id */ -  zvrf = zebra_vrf_lookup_by_name (vrf_id_str); - -  if (!zvrf) -    { -      vty_out (vty, "%% vrf %s is not defined%s", vrf_id_str, VTY_NEWLINE); -      return CMD_WARNING; -    } - -  /* Labels */ -  memset (&snh_label, 0, sizeof (struct static_nh_label)); -  if (label_str) -    { -      if (!mpls_enabled) -        { -          vty_out (vty, "%% MPLS not turned on in kernel, ignoring command%s", -                   VTY_NEWLINE); -          return CMD_WARNING; -        } -      if (mpls_str2label (label_str, &snh_label.num_labels, -                          snh_label.label)) -        { -          vty_out (vty, "%% Malformed label(s)%s", VTY_NEWLINE); -          return CMD_WARNING; -        } -    } - -  /* Null0 static route.  */ -  if ((gate_str != NULL) && (strncasecmp (gate_str, "Null0", strlen (gate_str)) == 0)) -    { -      if (flag_str) -        { -          vty_out (vty, "%% can not have flag %s with Null0%s", flag_str, VTY_NEWLINE); -          return CMD_WARNING; -        } -      if (add_cmd) -        static_add_route (AFI_IP6, SAFI_UNICAST, type, &p, src_p, NULL, ifname, -                          ZEBRA_FLAG_BLACKHOLE, tag, distance, zvrf, &snh_label); -      else -        static_delete_route (AFI_IP6, SAFI_UNICAST, type, &p, src_p, NULL, -                             ifname, tag, distance, zvrf, &snh_label); -      return CMD_SUCCESS; -    } - -  /* Route flags */ -  if (flag_str) { -    switch(flag_str[0]) { -      case 'r': -      case 'R': /* XXX */ -        SET_FLAG (flag, ZEBRA_FLAG_REJECT); -        break; -      case 'b': -      case 'B': /* XXX */ -        SET_FLAG (flag, ZEBRA_FLAG_BLACKHOLE); -        break; -      default: -        vty_out (vty, "%% Malformed flag %s %s", flag_str, VTY_NEWLINE); -        return CMD_WARNING; -    } -  } - - if (ifname) -    { -      /* When ifname is specified.  It must be come with gateway -         address. */ -      if (ret != 1) -        { -          vty_out (vty, "%% Malformed address%s", VTY_NEWLINE); -          return CMD_WARNING; -        } -      type = STATIC_IPV6_GATEWAY_IFNAME; -      gate = &gate_addr; -    } -  else -    { -      if (ret == 1) -        { -          type = STATIC_IPV6_GATEWAY; -          gate = &gate_addr; -        } -      else -        { -          type = STATIC_IFNAME; -          ifname = gate_str; -        } -    } - -  if (add_cmd) -    static_add_route (AFI_IP6, SAFI_UNICAST, type, &p, src_p, (union g_addr *)gate, -                      ifname, flag, tag, distance, zvrf, &snh_label); -  else -    static_delete_route (AFI_IP6, SAFI_UNICAST, type, &p, src_p, (union g_addr *)gate, -                         ifname, tag, distance, zvrf, &snh_label); - -  return CMD_SUCCESS; +int static_ipv6_func(struct vty *vty, int add_cmd, const char *dest_str, +		     const char *src_str, const char *gate_str, +		     const char *ifname, const char *flag_str, +		     const char *tag_str, const char *distance_str, +		     const char *vrf_id_str, const char *label_str) +{ +	int ret; +	u_char distance; +	struct prefix p, src; +	struct prefix_ipv6 *src_p = NULL; +	struct in6_addr *gate = NULL; +	struct in6_addr gate_addr; +	u_char type = STATIC_BLACKHOLE; +	u_char flag = 0; +	route_tag_t tag = 0; +	struct zebra_vrf *zvrf; +	struct static_nh_label snh_label; + +	ret = str2prefix(dest_str, &p); +	if (ret <= 0) { +		vty_out(vty, "%% Malformed address%s", VTY_NEWLINE); +		return CMD_WARNING; +	} + +	if (src_str) { +		ret = str2prefix(src_str, &src); +		if (ret <= 0 || src.family != AF_INET6) { +			vty_out(vty, "%% Malformed source address%s", +				VTY_NEWLINE); +			return CMD_WARNING; +		} +		src_p = (struct prefix_ipv6 *)&src; +	} + +	/* Apply mask for given prefix. */ +	apply_mask(&p); + +	/* Administrative distance. */ +	if (distance_str) +		distance = atoi(distance_str); +	else +		distance = ZEBRA_STATIC_DISTANCE_DEFAULT; + +	/* tag */ +	if (tag_str) +		VTY_GET_INTEGER_RANGE("tag", tag, tag_str, 0, 4294967295); + +	/* When gateway is valid IPv6 addrees, then gate is treated as +	   nexthop address other case gate is treated as interface name. */ +	ret = inet_pton(AF_INET6, gate_str, &gate_addr); + +	/* VRF id */ +	zvrf = zebra_vrf_lookup_by_name(vrf_id_str); + +	if (!zvrf) { +		vty_out(vty, "%% vrf %s is not defined%s", vrf_id_str, +			VTY_NEWLINE); +		return CMD_WARNING; +	} + +	/* Labels */ +	memset(&snh_label, 0, sizeof(struct static_nh_label)); +	if (label_str) { +		if (!mpls_enabled) { +			vty_out(vty, +				"%% MPLS not turned on in kernel, ignoring command%s", +				VTY_NEWLINE); +			return CMD_WARNING; +		} +		if (mpls_str2label(label_str, &snh_label.num_labels, +				   snh_label.label)) { +			vty_out(vty, "%% Malformed label(s)%s", VTY_NEWLINE); +			return CMD_WARNING; +		} +	} + +	/* Null0 static route.  */ +	if ((gate_str != NULL) +	    && (strncasecmp(gate_str, "Null0", strlen(gate_str)) == 0)) { +		if (flag_str) { +			vty_out(vty, "%% can not have flag %s with Null0%s", +				flag_str, VTY_NEWLINE); +			return CMD_WARNING; +		} +		if (add_cmd) +			static_add_route(AFI_IP6, SAFI_UNICAST, type, &p, src_p, +					 NULL, ifname, ZEBRA_FLAG_BLACKHOLE, +					 tag, distance, zvrf, &snh_label); +		else +			static_delete_route(AFI_IP6, SAFI_UNICAST, type, &p, +					    src_p, NULL, ifname, tag, distance, +					    zvrf, &snh_label); +		return CMD_SUCCESS; +	} + +	/* Route flags */ +	if (flag_str) { +		switch (flag_str[0]) { +		case 'r': +		case 'R': /* XXX */ +			SET_FLAG(flag, ZEBRA_FLAG_REJECT); +			break; +		case 'b': +		case 'B': /* XXX */ +			SET_FLAG(flag, ZEBRA_FLAG_BLACKHOLE); +			break; +		default: +			vty_out(vty, "%% Malformed flag %s %s", flag_str, +				VTY_NEWLINE); +			return CMD_WARNING; +		} +	} + +	if (ifname) { +		/* When ifname is specified.  It must be come with gateway +		   address. */ +		if (ret != 1) { +			vty_out(vty, "%% Malformed address%s", VTY_NEWLINE); +			return CMD_WARNING; +		} +		type = STATIC_IPV6_GATEWAY_IFNAME; +		gate = &gate_addr; +	} else { +		if (ret == 1) { +			type = STATIC_IPV6_GATEWAY; +			gate = &gate_addr; +		} else { +			type = STATIC_IFNAME; +			ifname = gate_str; +		} +	} + +	if (add_cmd) +		static_add_route(AFI_IP6, SAFI_UNICAST, type, &p, src_p, +				 (union g_addr *)gate, ifname, flag, tag, +				 distance, zvrf, &snh_label); +	else +		static_delete_route(AFI_IP6, SAFI_UNICAST, type, &p, src_p, +				    (union g_addr *)gate, ifname, tag, distance, +				    zvrf, &snh_label); + +	return CMD_SUCCESS;  }  DEFUN (ipv6_route, @@ -2498,33 +2495,28 @@ DEFUN (ipv6_route,         "Specify labels for this route\n"         "One or more labels separated by '/'\n")  { -  int idx_ipv6_prefixlen = 2; -  int idx_ipv6_ifname; -  int idx_curr; -  char *src, *tag, *distance, *vrf; - -  if (!strcmp(argv[3]->text, "from")) -    { -      src = argv[4]->arg; -      idx_ipv6_ifname = 5; -      idx_curr = 6; -    } -  else -    { -      src = NULL; -      idx_ipv6_ifname = 3; -      idx_curr = 4; -    } - -  tag = distance = vrf = NULL; -  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); - -  return static_ipv6_func (vty, 1, -			   argv[idx_ipv6_prefixlen]->arg, -			   src, -			   argv[idx_ipv6_ifname]->arg, -			   NULL, NULL, -			   tag, distance, vrf, NULL); +	int idx_ipv6_prefixlen = 2; +	int idx_ipv6_ifname; +	int idx_curr; +	char *src, *tag, *distance, *vrf; + +	if (!strcmp(argv[3]->text, "from")) { +		src = argv[4]->arg; +		idx_ipv6_ifname = 5; +		idx_curr = 6; +	} else { +		src = NULL; +		idx_ipv6_ifname = 3; +		idx_curr = 4; +	} + +	tag = distance = vrf = NULL; +	zebra_vty_ip_route_tdv_helper(argc, argv, idx_curr, &tag, &distance, +				      &vrf, NULL); + +	return static_ipv6_func(vty, 1, argv[idx_ipv6_prefixlen]->arg, src, +				argv[idx_ipv6_ifname]->arg, NULL, NULL, tag, +				distance, vrf, NULL);  }  DEFUN (ipv6_route_flags, @@ -2546,37 +2538,32 @@ DEFUN (ipv6_route_flags,         "Specify labels for this route\n"         "One or more labels separated by '/'\n")  { -  int idx_ipv6_prefixlen = 2; -  int idx_ipv6_ifname; -  int idx_reject_blackhole; -  int idx_curr; -  char *src, *tag, *distance, *vrf; - -  if (!strcmp(argv[3]->text, "from")) -    { -      src = argv[4]->arg; -      idx_ipv6_ifname = 5; -      idx_reject_blackhole = 6; -      idx_curr = 7; -    } -  else -    { -      src = NULL; -      idx_ipv6_ifname = 3; -      idx_reject_blackhole = 4; -      idx_curr = 5; -    } - -  tag = distance = vrf = NULL; -  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); - -  return static_ipv6_func (vty, 1, -			   argv[idx_ipv6_prefixlen]->arg, -			   src, -			   argv[idx_ipv6_ifname]->arg, -			   NULL, -			   argv[idx_reject_blackhole]->arg, -			   tag, distance, vrf, NULL); +	int idx_ipv6_prefixlen = 2; +	int idx_ipv6_ifname; +	int idx_reject_blackhole; +	int idx_curr; +	char *src, *tag, *distance, *vrf; + +	if (!strcmp(argv[3]->text, "from")) { +		src = argv[4]->arg; +		idx_ipv6_ifname = 5; +		idx_reject_blackhole = 6; +		idx_curr = 7; +	} else { +		src = NULL; +		idx_ipv6_ifname = 3; +		idx_reject_blackhole = 4; +		idx_curr = 5; +	} + +	tag = distance = vrf = NULL; +	zebra_vty_ip_route_tdv_helper(argc, argv, idx_curr, &tag, &distance, +				      &vrf, NULL); + +	return static_ipv6_func(vty, 1, argv[idx_ipv6_prefixlen]->arg, src, +				argv[idx_ipv6_ifname]->arg, NULL, +				argv[idx_reject_blackhole]->arg, tag, distance, +				vrf, NULL);  }  DEFUN (ipv6_route_ifname, @@ -2596,37 +2583,31 @@ DEFUN (ipv6_route_ifname,         "Specify labels for this route\n"         "One or more labels separated by '/'\n")  { -  int idx_ipv6_prefixlen = 2; -  int idx_ipv6 = 3; -  int idx_interface = 4; -  int idx_curr = 5; -  char *src, *tag, *distance, *vrf; - -  if (!strcmp(argv[3]->text, "from")) -    { -      src = argv[4]->arg; -      idx_ipv6 = 5; -      idx_interface = 6; -      idx_curr = 7; -    } -  else -    { -      src = NULL; -      idx_ipv6 = 3; -      idx_interface = 4; -      idx_curr = 5; -    } - -  tag = distance = vrf = NULL; -  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); - -  return static_ipv6_func (vty, 1, -			   argv[idx_ipv6_prefixlen]->arg, -			   src, -			   argv[idx_ipv6]->arg, -			   argv[idx_interface]->arg, -			   NULL, -			   tag, distance, vrf, NULL); +	int idx_ipv6_prefixlen = 2; +	int idx_ipv6 = 3; +	int idx_interface = 4; +	int idx_curr = 5; +	char *src, *tag, *distance, *vrf; + +	if (!strcmp(argv[3]->text, "from")) { +		src = argv[4]->arg; +		idx_ipv6 = 5; +		idx_interface = 6; +		idx_curr = 7; +	} else { +		src = NULL; +		idx_ipv6 = 3; +		idx_interface = 4; +		idx_curr = 5; +	} + +	tag = distance = vrf = NULL; +	zebra_vty_ip_route_tdv_helper(argc, argv, idx_curr, &tag, &distance, +				      &vrf, NULL); + +	return static_ipv6_func(vty, 1, argv[idx_ipv6_prefixlen]->arg, src, +				argv[idx_ipv6]->arg, argv[idx_interface]->arg, +				NULL, tag, distance, vrf, NULL);  }  DEFUN (ipv6_route_ifname_flags, @@ -2648,40 +2629,35 @@ DEFUN (ipv6_route_ifname_flags,         "Specify labels for this route\n"         "One or more labels separated by '/'\n")  { -  int idx_ipv6_prefixlen = 2; -  int idx_ipv6; -  int idx_interface; -  int idx_reject_blackhole; -  int idx_curr; -  char *src, *tag, *distance, *vrf; - -  if (!strcmp(argv[3]->text, "from")) -    { -      src = argv[4]->arg; -      idx_ipv6 = 5; -      idx_interface = 6; -      idx_reject_blackhole = 7; -      idx_curr = 8; -    } -  else -    { -      src = NULL; -      idx_ipv6 = 3; -      idx_interface = 4; -      idx_reject_blackhole = 5; -      idx_curr = 6; -    } - -  tag = distance = vrf = NULL; -  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); - -  return static_ipv6_func (vty, 1, -			   argv[idx_ipv6_prefixlen]->arg, -			   src, -			   argv[idx_ipv6]->arg, -			   argv[idx_interface]->arg, -			   argv[idx_reject_blackhole]->arg, -			   tag, distance, vrf, NULL); +	int idx_ipv6_prefixlen = 2; +	int idx_ipv6; +	int idx_interface; +	int idx_reject_blackhole; +	int idx_curr; +	char *src, *tag, *distance, *vrf; + +	if (!strcmp(argv[3]->text, "from")) { +		src = argv[4]->arg; +		idx_ipv6 = 5; +		idx_interface = 6; +		idx_reject_blackhole = 7; +		idx_curr = 8; +	} else { +		src = NULL; +		idx_ipv6 = 3; +		idx_interface = 4; +		idx_reject_blackhole = 5; +		idx_curr = 6; +	} + +	tag = distance = vrf = NULL; +	zebra_vty_ip_route_tdv_helper(argc, argv, idx_curr, &tag, &distance, +				      &vrf, NULL); + +	return static_ipv6_func(vty, 1, argv[idx_ipv6_prefixlen]->arg, src, +				argv[idx_ipv6]->arg, argv[idx_interface]->arg, +				argv[idx_reject_blackhole]->arg, tag, distance, +				vrf, NULL);  }  DEFUN (no_ipv6_route, @@ -2703,33 +2679,28 @@ DEFUN (no_ipv6_route,         "Specify labels for this route\n"         "One or more labels separated by '/'\n")  { -  int idx_ipv6_prefixlen = 3; -  int idx_ipv6_ifname; -  int idx_curr; -  char *src, *tag, *distance, *vrf; - -  if (!strcmp(argv[4]->text, "from")) -    { -      src = argv[5]->arg; -      idx_ipv6_ifname = 6; -      idx_curr = 7; -    } -  else -    { -      src = NULL; -      idx_ipv6_ifname = 4; -      idx_curr = 5; -    } - -  tag = distance = vrf = NULL; -  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); - -  return static_ipv6_func (vty, 0, -			   argv[idx_ipv6_prefixlen]->arg, -			   src, -			   argv[idx_ipv6_ifname]->arg, -			   NULL, NULL, -			   tag, distance, vrf, NULL); +	int idx_ipv6_prefixlen = 3; +	int idx_ipv6_ifname; +	int idx_curr; +	char *src, *tag, *distance, *vrf; + +	if (!strcmp(argv[4]->text, "from")) { +		src = argv[5]->arg; +		idx_ipv6_ifname = 6; +		idx_curr = 7; +	} else { +		src = NULL; +		idx_ipv6_ifname = 4; +		idx_curr = 5; +	} + +	tag = distance = vrf = NULL; +	zebra_vty_ip_route_tdv_helper(argc, argv, idx_curr, &tag, &distance, +				      &vrf, NULL); + +	return static_ipv6_func(vty, 0, argv[idx_ipv6_prefixlen]->arg, src, +				argv[idx_ipv6_ifname]->arg, NULL, NULL, tag, +				distance, vrf, NULL);  }  DEFUN (no_ipv6_route_flags, @@ -2752,37 +2723,32 @@ DEFUN (no_ipv6_route_flags,         "Specify labels for this route\n"         "One or more labels separated by '/'\n")  { -  int idx_ipv6_prefixlen = 3; -  int idx_ipv6_ifname; -  int idx_reject_blackhole; -  int idx_curr; -  char *src, *tag, *distance, *vrf; - -  if (!strcmp(argv[4]->text, "from")) -    { -      src = argv[5]->arg; -      idx_ipv6_ifname = 6; -      idx_reject_blackhole = 7; -      idx_curr = 8; -    } -  else -    { -      src = NULL; -      idx_ipv6_ifname = 4; -      idx_reject_blackhole = 5; -      idx_curr = 6; -    } - -  tag = distance = vrf = NULL; -  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); - -  return static_ipv6_func (vty, 0, -			   argv[idx_ipv6_prefixlen]->arg, -			   src, -			   argv[idx_ipv6_ifname]->arg, -			   NULL, -			   argv[idx_reject_blackhole]->arg, -			   tag, distance, vrf, NULL); +	int idx_ipv6_prefixlen = 3; +	int idx_ipv6_ifname; +	int idx_reject_blackhole; +	int idx_curr; +	char *src, *tag, *distance, *vrf; + +	if (!strcmp(argv[4]->text, "from")) { +		src = argv[5]->arg; +		idx_ipv6_ifname = 6; +		idx_reject_blackhole = 7; +		idx_curr = 8; +	} else { +		src = NULL; +		idx_ipv6_ifname = 4; +		idx_reject_blackhole = 5; +		idx_curr = 6; +	} + +	tag = distance = vrf = NULL; +	zebra_vty_ip_route_tdv_helper(argc, argv, idx_curr, &tag, &distance, +				      &vrf, NULL); + +	return static_ipv6_func(vty, 0, argv[idx_ipv6_prefixlen]->arg, src, +				argv[idx_ipv6_ifname]->arg, NULL, +				argv[idx_reject_blackhole]->arg, tag, distance, +				vrf, NULL);  }  DEFUN (no_ipv6_route_ifname, @@ -2803,37 +2769,31 @@ DEFUN (no_ipv6_route_ifname,         "Specify labels for this route\n"         "One or more labels separated by '/'\n")  { -  int idx_ipv6_prefixlen = 3; -  int idx_ipv6; -  int idx_interface; -  int idx_curr; -  char *src, *tag, *distance, *vrf; - -  if (!strcmp(argv[4]->text, "from")) -    { -      src = argv[5]->arg; -      idx_ipv6 = 6; -      idx_interface = 7; -      idx_curr = 8; -    } -  else -    { -      src = NULL; -      idx_ipv6 = 4; -      idx_interface = 5; -      idx_curr = 6; -    } - -  tag = distance = vrf = NULL; -  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); - -  return static_ipv6_func (vty, 0, -			   argv[idx_ipv6_prefixlen]->arg, -			   src, -			   argv[idx_ipv6]->arg, -			   argv[idx_interface]->arg, -			   NULL, -			   tag, distance, vrf, NULL); +	int idx_ipv6_prefixlen = 3; +	int idx_ipv6; +	int idx_interface; +	int idx_curr; +	char *src, *tag, *distance, *vrf; + +	if (!strcmp(argv[4]->text, "from")) { +		src = argv[5]->arg; +		idx_ipv6 = 6; +		idx_interface = 7; +		idx_curr = 8; +	} else { +		src = NULL; +		idx_ipv6 = 4; +		idx_interface = 5; +		idx_curr = 6; +	} + +	tag = distance = vrf = NULL; +	zebra_vty_ip_route_tdv_helper(argc, argv, idx_curr, &tag, &distance, +				      &vrf, NULL); + +	return static_ipv6_func(vty, 0, argv[idx_ipv6_prefixlen]->arg, src, +				argv[idx_ipv6]->arg, argv[idx_interface]->arg, +				NULL, tag, distance, vrf, NULL);  }  DEFUN (no_ipv6_route_ifname_flags, @@ -2856,40 +2816,35 @@ DEFUN (no_ipv6_route_ifname_flags,         "Specify labels for this route\n"         "One or more labels separated by '/'\n")  { -  int idx_ipv6_prefixlen = 3; -  int idx_ipv6; -  int idx_interface; -  int idx_reject_blackhole; -  int idx_curr; -  char *src, *tag, *distance, *vrf; - -  if (!strcmp(argv[4]->text, "from")) -    { -      src = argv[5]->arg; -      idx_ipv6 = 6; -      idx_interface = 7; -      idx_reject_blackhole = 8; -      idx_curr = 9; -    } -  else -    { -      src = NULL; -      idx_ipv6 = 4; -      idx_interface = 5; -      idx_reject_blackhole = 6; -      idx_curr = 7; -    } - -  tag = distance = vrf = NULL; -  zebra_vty_ip_route_tdv_helper (argc, argv, idx_curr, &tag, &distance, &vrf, NULL); - -  return static_ipv6_func (vty, 0, -			   argv[idx_ipv6_prefixlen]->arg, -			   src, -			   argv[idx_ipv6]->arg, -			   argv[idx_interface]->arg, -			   argv[idx_reject_blackhole]->arg, -			   tag, distance, vrf, NULL); +	int idx_ipv6_prefixlen = 3; +	int idx_ipv6; +	int idx_interface; +	int idx_reject_blackhole; +	int idx_curr; +	char *src, *tag, *distance, *vrf; + +	if (!strcmp(argv[4]->text, "from")) { +		src = argv[5]->arg; +		idx_ipv6 = 6; +		idx_interface = 7; +		idx_reject_blackhole = 8; +		idx_curr = 9; +	} else { +		src = NULL; +		idx_ipv6 = 4; +		idx_interface = 5; +		idx_reject_blackhole = 6; +		idx_curr = 7; +	} + +	tag = distance = vrf = NULL; +	zebra_vty_ip_route_tdv_helper(argc, argv, idx_curr, &tag, &distance, +				      &vrf, NULL); + +	return static_ipv6_func(vty, 0, argv[idx_ipv6_prefixlen]->arg, src, +				argv[idx_ipv6]->arg, argv[idx_interface]->arg, +				argv[idx_reject_blackhole]->arg, tag, distance, +				vrf, NULL);  }  DEFUN (show_ipv6_route, @@ -2901,94 +2856,86 @@ DEFUN (show_ipv6_route,         VRF_CMD_HELP_STR         "Output JSON\n")  { -  struct route_table *table; -  struct route_node *rn; -  struct rib *rib; -  int first = 1; -  vrf_id_t vrf_id = VRF_DEFAULT; -  struct zebra_vrf *zvrf = NULL; -  char buf[SRCDEST2STR_BUFFER]; -  json_object *json = NULL; -  json_object *json_prefix = NULL; - -  int vrf = (argc > 3 && strmatch (argv[3]->text, "vrf")); -  int uj = vrf ? argc == 6 : argc == 4; -  char *vrfname = vrf ? argv[4]->arg : NULL; - -  if (vrf) -  { -    if (!(zvrf = zebra_vrf_lookup_by_name (vrfname))) -       { -         if (uj) -           vty_out (vty, "{}%s", VTY_NEWLINE); -         else -           vty_out (vty, "vrf %s not defined%s", vrfname, VTY_NEWLINE); -         return CMD_SUCCESS; -       } - -     if (zvrf_id (zvrf) == VRF_UNKNOWN) -       { -         if (uj) -           vty_out (vty, "{}%s", VTY_NEWLINE); -         else -           vty_out (vty, "vrf %s inactive%s", vrfname, VTY_NEWLINE); -         return CMD_SUCCESS; -       } -     else -       vrf_id = zvrf_id (zvrf); -  } - -  table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id); -  if (!table) -    { -      if (uj) -        vty_out (vty, "{}%s", VTY_NEWLINE); -      return CMD_SUCCESS; -    } - -  if (uj) -    { -      json = json_object_new_object(); - -      /* Show all IPv6 route. */ -      for (rn = route_top (table); rn; rn = srcdest_route_next (rn)) -        { -          RNODE_FOREACH_RIB (rn, rib) -            { -              if (!json_prefix) -                json_prefix = json_object_new_array(); -              vty_show_ip_route (vty, rn, rib, json_prefix); -            } - -          if (json_prefix) -            { -              srcdest_rnode2str (rn, buf, sizeof buf); -              json_object_object_add(json, buf, json_prefix); -              json_prefix = NULL; -            } -        } - -      vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE); -      json_object_free(json); -    } -  else -    { -      /* Show all IPv6 route. */ -      for (rn = route_top (table); rn; rn = srcdest_route_next (rn)) -        { -          RNODE_FOREACH_RIB (rn, rib) -            { -              if (first) -                { -                  vty_out (vty, SHOW_ROUTE_V6_HEADER); -                  first = 0; -                } -              vty_show_ip_route (vty, rn, rib, NULL); -            } -        } -    } - -  return CMD_SUCCESS; +	struct route_table *table; +	struct route_node *rn; +	struct rib *rib; +	int first = 1; +	vrf_id_t vrf_id = VRF_DEFAULT; +	struct zebra_vrf *zvrf = NULL; +	char buf[SRCDEST2STR_BUFFER]; +	json_object *json = NULL; +	json_object *json_prefix = NULL; + +	int vrf = (argc > 3 && strmatch(argv[3]->text, "vrf")); +	int uj = vrf ? argc == 6 : argc == 4; +	char *vrfname = vrf ? argv[4]->arg : NULL; + +	if (vrf) { +		if (!(zvrf = zebra_vrf_lookup_by_name(vrfname))) { +			if (uj) +				vty_out(vty, "{}%s", VTY_NEWLINE); +			else +				vty_out(vty, "vrf %s not defined%s", vrfname, +					VTY_NEWLINE); +			return CMD_SUCCESS; +		} + +		if (zvrf_id(zvrf) == VRF_UNKNOWN) { +			if (uj) +				vty_out(vty, "{}%s", VTY_NEWLINE); +			else +				vty_out(vty, "vrf %s inactive%s", vrfname, +					VTY_NEWLINE); +			return CMD_SUCCESS; +		} else +			vrf_id = zvrf_id(zvrf); +	} + +	table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, vrf_id); +	if (!table) { +		if (uj) +			vty_out(vty, "{}%s", VTY_NEWLINE); +		return CMD_SUCCESS; +	} + +	if (uj) { +		json = json_object_new_object(); + +		/* Show all IPv6 route. */ +		for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) { +			RNODE_FOREACH_RIB(rn, rib) +			{ +				if (!json_prefix) +					json_prefix = json_object_new_array(); +				vty_show_ip_route(vty, rn, rib, json_prefix); +			} + +			if (json_prefix) { +				srcdest_rnode2str(rn, buf, sizeof buf); +				json_object_object_add(json, buf, json_prefix); +				json_prefix = NULL; +			} +		} + +		vty_out(vty, "%s%s", json_object_to_json_string_ext( +					     json, JSON_C_TO_STRING_PRETTY), +			VTY_NEWLINE); +		json_object_free(json); +	} else { +		/* Show all IPv6 route. */ +		for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) { +			RNODE_FOREACH_RIB(rn, rib) +			{ +				if (first) { +					vty_out(vty, SHOW_ROUTE_V6_HEADER); +					first = 0; +				} +				vty_show_ip_route(vty, rn, rib, NULL); +			} +		} +	} + +	return CMD_SUCCESS;  }  DEFUN (show_ipv6_route_tag, @@ -3001,46 +2948,44 @@ DEFUN (show_ipv6_route_tag,         "Show only routes with tag\n"         "Tag value\n")  { -  int idx_vrf = 3; -  int idx_name = 4; -  int idx_tag = 6; -  struct route_table *table; -  struct route_node *rn; -  struct rib *rib; -  int first = 1; -  route_tag_t tag = 0; -  vrf_id_t vrf_id = VRF_DEFAULT; - -  if (strmatch(argv[idx_vrf]->text, "vrf")) -    { -      VRF_GET_ID (vrf_id, argv[idx_name]->arg); -      VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_tag]->arg, 0, 4294967295); -    } -  else -    { -      idx_tag -= 2; -      VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_tag]->arg, 0, 4294967295); -    } - -  table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id); -  if (! table) -    return CMD_SUCCESS; - -  /* Show all IPv6 routes with matching tag value. */ -  for (rn = route_top (table); rn; rn = srcdest_route_next (rn)) -    RNODE_FOREACH_RIB (rn, rib) -      { -        if (rib->tag != tag) -          continue; - -	if (first) -	  { -	    vty_out (vty, SHOW_ROUTE_V6_HEADER); -	    first = 0; -	  } -	vty_show_ip_route (vty, rn, rib, NULL); -      } -  return CMD_SUCCESS; +	int idx_vrf = 3; +	int idx_name = 4; +	int idx_tag = 6; +	struct route_table *table; +	struct route_node *rn; +	struct rib *rib; +	int first = 1; +	route_tag_t tag = 0; +	vrf_id_t vrf_id = VRF_DEFAULT; + +	if (strmatch(argv[idx_vrf]->text, "vrf")) { +		VRF_GET_ID(vrf_id, argv[idx_name]->arg); +		VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_tag]->arg, 0, +				      4294967295); +	} else { +		idx_tag -= 2; +		VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_tag]->arg, 0, +				      4294967295); +	} + +	table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, vrf_id); +	if (!table) +		return CMD_SUCCESS; + +	/* Show all IPv6 routes with matching tag value. */ +	for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) +		RNODE_FOREACH_RIB(rn, rib) +		{ +			if (rib->tag != tag) +				continue; + +			if (first) { +				vty_out(vty, SHOW_ROUTE_V6_HEADER); +				first = 0; +			} +			vty_show_ip_route(vty, rn, rib, NULL); +		} +	return CMD_SUCCESS;  }  DEFUN (show_ipv6_route_prefix_longer, @@ -3053,52 +2998,46 @@ DEFUN (show_ipv6_route_prefix_longer,         "IPv6 prefix\n"         "Show route matching the specified Network/Mask pair only\n")  { -  struct route_table *table; -  struct route_node *rn; -  struct rib *rib; -  struct prefix p; -  int ret; -  int first = 1; -  vrf_id_t vrf_id = VRF_DEFAULT; - -  if (strmatch(argv[3]->text, "vrf")) -    { -      VRF_GET_ID (vrf_id, argv[4]->arg); -      ret = str2prefix (argv[5]->arg, &p); -    } -  else -    { -      ret = str2prefix (argv[3]->arg, &p); -    } - -  if (! ret) -    { -      vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE); -      return CMD_WARNING; -    } - -  table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id); -  if (! table) -    return CMD_SUCCESS; - -  /* Show matched type IPv6 routes. */ -  for (rn = route_top (table); rn; rn = srcdest_route_next (rn)) -    RNODE_FOREACH_RIB (rn, rib) -      { -        struct prefix *p, *src_p; -        srcdest_rnode_prefixes(rn, &p, &src_p); - -        if (prefix_match (p, &rn->p)) -          { -            if (first) -              { -                vty_out (vty, SHOW_ROUTE_V6_HEADER); -                first = 0; -              } -            vty_show_ip_route (vty, rn, rib, NULL); -          } -      } -  return CMD_SUCCESS; +	struct route_table *table; +	struct route_node *rn; +	struct rib *rib; +	struct prefix p; +	int ret; +	int first = 1; +	vrf_id_t vrf_id = VRF_DEFAULT; + +	if (strmatch(argv[3]->text, "vrf")) { +		VRF_GET_ID(vrf_id, argv[4]->arg); +		ret = str2prefix(argv[5]->arg, &p); +	} else { +		ret = str2prefix(argv[3]->arg, &p); +	} + +	if (!ret) { +		vty_out(vty, "%% Malformed Prefix%s", VTY_NEWLINE); +		return CMD_WARNING; +	} + +	table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, vrf_id); +	if (!table) +		return CMD_SUCCESS; + +	/* Show matched type IPv6 routes. */ +	for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) +		RNODE_FOREACH_RIB(rn, rib) +		{ +			struct prefix *p, *src_p; +			srcdest_rnode_prefixes(rn, &p, &src_p); + +			if (prefix_match(p, &rn->p)) { +				if (first) { +					vty_out(vty, SHOW_ROUTE_V6_HEADER); +					first = 0; +				} +				vty_show_ip_route(vty, rn, rib, NULL); +			} +		} +	return CMD_SUCCESS;  }  DEFUN (show_ipv6_route_protocol, @@ -3110,43 +3049,40 @@ DEFUN (show_ipv6_route_protocol,         VRF_CMD_HELP_STR         FRR_IP6_REDIST_HELP_STR_ZEBRA)  { -  int type; -  struct route_table *table; -  struct route_node *rn; -  struct rib *rib; -  int first = 1; -  vrf_id_t vrf_id = VRF_DEFAULT; - -  int idx = 0; -  if (argv_find (argv, argc, "NAME", &idx)) -    VRF_GET_ID (vrf_id, argv[idx]->arg); - -  char *proto = argv[argc - 1]->text; -  type = proto_redistnum (AFI_IP6, proto); - -  if (type < 0) -    { -      vty_out (vty, "Unknown route type%s", VTY_NEWLINE); -      return CMD_WARNING; -    } - -  table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id); -  if (! table) -    return CMD_SUCCESS; - -  /* Show matched type IPv6 routes. */ -  for (rn = route_top (table); rn; rn = srcdest_route_next (rn)) -    RNODE_FOREACH_RIB (rn, rib) -      if (rib->type == type) -	{ -	  if (first) -	    { -	      vty_out (vty, SHOW_ROUTE_V6_HEADER); -	      first = 0; -	    } -	  vty_show_ip_route (vty, rn, rib, NULL); +	int type; +	struct route_table *table; +	struct route_node *rn; +	struct rib *rib; +	int first = 1; +	vrf_id_t vrf_id = VRF_DEFAULT; + +	int idx = 0; +	if (argv_find(argv, argc, "NAME", &idx)) +		VRF_GET_ID(vrf_id, argv[idx]->arg); + +	char *proto = argv[argc - 1]->text; +	type = proto_redistnum(AFI_IP6, proto); + +	if (type < 0) { +		vty_out(vty, "Unknown route type%s", VTY_NEWLINE); +		return CMD_WARNING; +	} + +	table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, vrf_id); +	if (!table) +		return CMD_SUCCESS; + +	/* Show matched type IPv6 routes. */ +	for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) +		RNODE_FOREACH_RIB(rn, rib) +	if (rib->type == type) { +		if (first) { +			vty_out(vty, SHOW_ROUTE_V6_HEADER); +			first = 0; +		} +		vty_show_ip_route(vty, rn, rib, NULL);  	} -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (show_ipv6_route_addr, @@ -3158,44 +3094,39 @@ DEFUN (show_ipv6_route_addr,         VRF_CMD_HELP_STR         "IPv6 Address\n")  { -  int ret; -  struct prefix_ipv6 p; -  struct route_table *table; -  struct route_node *rn; -  vrf_id_t vrf_id = VRF_DEFAULT; - -  if (strmatch(argv[3]->text, "vrf")) -    { -      VRF_GET_ID (vrf_id, argv[4]->arg); -      ret = str2prefix_ipv6 (argv[5]->arg, &p); -    } -  else -    { -      ret = str2prefix_ipv6 (argv[3]->arg, &p); -    } +	int ret; +	struct prefix_ipv6 p; +	struct route_table *table; +	struct route_node *rn; +	vrf_id_t vrf_id = VRF_DEFAULT; + +	if (strmatch(argv[3]->text, "vrf")) { +		VRF_GET_ID(vrf_id, argv[4]->arg); +		ret = str2prefix_ipv6(argv[5]->arg, &p); +	} else { +		ret = str2prefix_ipv6(argv[3]->arg, &p); +	} -  if (ret <= 0) -    { -      vty_out (vty, "Malformed IPv6 address%s", VTY_NEWLINE); -      return CMD_WARNING; -    } +	if (ret <= 0) { +		vty_out(vty, "Malformed IPv6 address%s", VTY_NEWLINE); +		return CMD_WARNING; +	} -  table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id); -  if (! table) -    return CMD_SUCCESS; +	table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, vrf_id); +	if (!table) +		return CMD_SUCCESS; -  rn = route_node_match (table, (struct prefix *) &p); -  if (! rn) -    { -      vty_out (vty, "%% Network not in table%s", VTY_NEWLINE); -      return CMD_WARNING; -    } +	rn = route_node_match(table, (struct prefix *)&p); +	if (!rn) { +		vty_out(vty, "%% Network not in table%s", VTY_NEWLINE); +		return CMD_WARNING; +	} -  vty_show_ip_route_detail (vty, rn, 0); +	vty_show_ip_route_detail(vty, rn, 0); -  route_unlock_node (rn); +	route_unlock_node(rn); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (show_ipv6_route_prefix, @@ -3207,42 +3138,38 @@ DEFUN (show_ipv6_route_prefix,         VRF_CMD_HELP_STR         "IPv6 prefix\n")  { -  int ret; -  struct prefix_ipv6 p; -  struct route_table *table; -  struct route_node *rn; -  vrf_id_t vrf_id = VRF_DEFAULT; - -  if (strmatch(argv[3]->text, "vrf")) -    { -      VRF_GET_ID (vrf_id, argv[4]->arg); -      ret = str2prefix_ipv6 (argv[5]->arg, &p); -    } -  else -    ret = str2prefix_ipv6 (argv[3]->arg, &p); - -  if (ret <= 0) -    { -      vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE); -      return CMD_WARNING; -    } +	int ret; +	struct prefix_ipv6 p; +	struct route_table *table; +	struct route_node *rn; +	vrf_id_t vrf_id = VRF_DEFAULT; + +	if (strmatch(argv[3]->text, "vrf")) { +		VRF_GET_ID(vrf_id, argv[4]->arg); +		ret = str2prefix_ipv6(argv[5]->arg, &p); +	} else +		ret = str2prefix_ipv6(argv[3]->arg, &p); + +	if (ret <= 0) { +		vty_out(vty, "Malformed IPv6 prefix%s", VTY_NEWLINE); +		return CMD_WARNING; +	} -  table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id); -  if (! table) -    return CMD_SUCCESS; +	table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, vrf_id); +	if (!table) +		return CMD_SUCCESS; -  rn = route_node_match (table, (struct prefix *) &p); -  if (! rn || rn->p.prefixlen != p.prefixlen) -    { -      vty_out (vty, "%% Network not in table%s", VTY_NEWLINE); -      return CMD_WARNING; -    } +	rn = route_node_match(table, (struct prefix *)&p); +	if (!rn || rn->p.prefixlen != p.prefixlen) { +		vty_out(vty, "%% Network not in table%s", VTY_NEWLINE); +		return CMD_WARNING; +	} -  vty_show_ip_route_detail (vty, rn, 0); +	vty_show_ip_route_detail(vty, rn, 0); -  route_unlock_node (rn); +	route_unlock_node(rn); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  } @@ -3256,19 +3183,19 @@ DEFUN (show_ipv6_route_summary,         VRF_CMD_HELP_STR         "Summary of all IPv6 routes\n")  { -  struct route_table *table; -  vrf_id_t vrf_id = VRF_DEFAULT; +	struct route_table *table; +	vrf_id_t vrf_id = VRF_DEFAULT; -  if (strmatch(argv[3]->text, "vrf")) -    VRF_GET_ID (vrf_id, argv[4]->arg); +	if (strmatch(argv[3]->text, "vrf")) +		VRF_GET_ID(vrf_id, argv[4]->arg); -  table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id); -  if (! table) -    return CMD_SUCCESS; +	table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, vrf_id); +	if (!table) +		return CMD_SUCCESS; -  vty_show_ip_route_summary (vty, table); +	vty_show_ip_route_summary(vty, table); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  } @@ -3283,19 +3210,19 @@ DEFUN (show_ipv6_route_summary_prefix,         "Summary of all IPv6 routes\n"         "Prefix routes\n")  { -  struct route_table *table; -  vrf_id_t vrf_id = VRF_DEFAULT; +	struct route_table *table; +	vrf_id_t vrf_id = VRF_DEFAULT; -  if (strmatch(argv[3]->text, "vrf")) -    VRF_GET_ID (vrf_id, argv[4]->arg); +	if (strmatch(argv[3]->text, "vrf")) +		VRF_GET_ID(vrf_id, argv[4]->arg); -  table = zebra_vrf_table (AFI_IP6, SAFI_UNICAST, vrf_id); -  if (! table) -    return CMD_SUCCESS; +	table = zebra_vrf_table(AFI_IP6, SAFI_UNICAST, vrf_id); +	if (!table) +		return CMD_SUCCESS; -  vty_show_ip_route_summary_prefix (vty, table); +	vty_show_ip_route_summary_prefix(vty, table); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  } @@ -3311,31 +3238,30 @@ DEFUN (show_ipv6_mroute,         "IPv6 Multicast routing table\n"         VRF_CMD_HELP_STR)  { -  struct route_table *table; -  struct route_node *rn; -  struct rib *rib; -  int first = 1; -  vrf_id_t vrf_id = VRF_DEFAULT; +	struct route_table *table; +	struct route_node *rn; +	struct rib *rib; +	int first = 1; +	vrf_id_t vrf_id = VRF_DEFAULT; -  if (argc == 5) -    VRF_GET_ID (vrf_id, argv[4]->arg); +	if (argc == 5) +		VRF_GET_ID(vrf_id, argv[4]->arg); -  table = zebra_vrf_table (AFI_IP6, SAFI_MULTICAST, vrf_id); -  if (! table) -    return CMD_SUCCESS; +	table = zebra_vrf_table(AFI_IP6, SAFI_MULTICAST, vrf_id); +	if (!table) +		return CMD_SUCCESS; -  /* Show all IPv6 route. */ -  for (rn = route_top (table); rn; rn = srcdest_route_next (rn)) -    RNODE_FOREACH_RIB (rn, rib) -      { -       if (first) -         { -	   vty_out (vty, SHOW_ROUTE_V6_HEADER); -           first = 0; -         } -       vty_show_ip_route (vty, rn, rib, NULL); -      } -  return CMD_SUCCESS; +	/* Show all IPv6 route. */ +	for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) +		RNODE_FOREACH_RIB(rn, rib) +		{ +			if (first) { +				vty_out(vty, SHOW_ROUTE_V6_HEADER); +				first = 0; +			} +			vty_show_ip_route(vty, rn, rib, NULL); +		} +	return CMD_SUCCESS;  } @@ -3347,41 +3273,40 @@ DEFUN (show_ipv6_route_vrf_all,         "IPv6 routing table\n"         VRF_ALL_CMD_HELP_STR)  { -  struct route_table *table; -  struct route_node *rn; -  struct rib *rib; -  struct vrf *vrf; -  struct zebra_vrf *zvrf; -  int first = 1; -  int vrf_header = 1; - -  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) -    { -      if ((zvrf = vrf->info) == NULL || -          (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) -        continue; - -      /* Show all IPv6 route. */ -      for (rn = route_top (table); rn; rn = srcdest_route_next (rn)) -        RNODE_FOREACH_RIB (rn, rib) -          { -            if (first) -              { -                vty_out (vty, SHOW_ROUTE_V6_HEADER); -                first = 0; -              } - -            if (vrf_header) -              { -                vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); -                vrf_header = 0; -              } -            vty_show_ip_route (vty, rn, rib, NULL); -          } -      vrf_header = 1; -    } - -  return CMD_SUCCESS; +	struct route_table *table; +	struct route_node *rn; +	struct rib *rib; +	struct vrf *vrf; +	struct zebra_vrf *zvrf; +	int first = 1; +	int vrf_header = 1; + +	RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) +	{ +		if ((zvrf = vrf->info) == NULL +		    || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) +			continue; + +		/* Show all IPv6 route. */ +		for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) +			RNODE_FOREACH_RIB(rn, rib) +			{ +				if (first) { +					vty_out(vty, SHOW_ROUTE_V6_HEADER); +					first = 0; +				} + +				if (vrf_header) { +					vty_out(vty, "%sVRF %s:%s", VTY_NEWLINE, +						zvrf_name(zvrf), VTY_NEWLINE); +					vrf_header = 0; +				} +				vty_show_ip_route(vty, rn, rib, NULL); +			} +		vrf_header = 1; +	} + +	return CMD_SUCCESS;  }  DEFUN (show_ipv6_route_vrf_all_tag, @@ -3394,49 +3319,49 @@ DEFUN (show_ipv6_route_vrf_all_tag,         "Show only routes with tag\n"         "Tag value\n")  { -  int idx_number = 6; -  struct route_table *table; -  struct route_node *rn; -  struct rib *rib; -  struct vrf *vrf; -  struct zebra_vrf *zvrf; -  int first = 1; -  int vrf_header = 1; -  route_tag_t tag = 0; - -  if (argv[idx_number]->arg) -    VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_number]->arg, 0, 4294967295); - -  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) -    { -      if ((zvrf = vrf->info) == NULL || -          (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) -        continue; - -      /* Show all IPv6 routes with matching tag value. */ -      for (rn = route_top (table); rn; rn = srcdest_route_next (rn)) -        RNODE_FOREACH_RIB (rn, rib) -          { -            if (rib->tag != tag) -              continue; - -            if (first) -              { -                vty_out (vty, SHOW_ROUTE_V6_HEADER); -                first = 0; -              } - -            if (vrf_header) -              { -                vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); -                vrf_header = 0; -              } -            vty_show_ip_route (vty, rn, rib, NULL); -          } -      vrf_header = 1; -    } - -  return CMD_SUCCESS; +	int idx_number = 6; +	struct route_table *table; +	struct route_node *rn; +	struct rib *rib; +	struct vrf *vrf; +	struct zebra_vrf *zvrf; +	int first = 1; +	int vrf_header = 1; +	route_tag_t tag = 0; + +	if (argv[idx_number]->arg) +		VTY_GET_INTEGER_RANGE("tag", tag, argv[idx_number]->arg, 0, +				      4294967295); + +	RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) +	{ +		if ((zvrf = vrf->info) == NULL +		    || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) +			continue; + +		/* Show all IPv6 routes with matching tag value. */ +		for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) +			RNODE_FOREACH_RIB(rn, rib) +			{ +				if (rib->tag != tag) +					continue; + +				if (first) { +					vty_out(vty, SHOW_ROUTE_V6_HEADER); +					first = 0; +				} + +				if (vrf_header) { +					vty_out(vty, "%sVRF %s:%s", VTY_NEWLINE, +						zvrf_name(zvrf), VTY_NEWLINE); +					vrf_header = 0; +				} +				vty_show_ip_route(vty, rn, rib, NULL); +			} +		vrf_header = 1; +	} + +	return CMD_SUCCESS;  }  DEFUN (show_ipv6_route_vrf_all_prefix_longer, @@ -3449,56 +3374,56 @@ DEFUN (show_ipv6_route_vrf_all_prefix_longer,         "IPv6 prefix\n"         "Show route matching the specified Network/Mask pair only\n")  { -  int idx_ipv6_prefixlen = 5; -  struct route_table *table; -  struct route_node *rn; -  struct rib *rib; -  struct prefix p; -  struct vrf *vrf; -  struct zebra_vrf *zvrf; -  int ret; -  int first = 1; -  int vrf_header = 1; - -  ret = str2prefix (argv[idx_ipv6_prefixlen]->arg, &p); -  if (! ret) -    { -      vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE); -      return CMD_WARNING; -    } - -  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) -    { -      if ((zvrf = vrf->info) == NULL || -          (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) -        continue; - -      /* Show matched type IPv6 routes. */ -      for (rn = route_top (table); rn; rn = srcdest_route_next (rn)) -        RNODE_FOREACH_RIB (rn, rib) -          { -            struct prefix *p, *src_p; -            srcdest_rnode_prefixes(rn, &p, &src_p); -            if (prefix_match (p, &rn->p)) -              { -                if (first) -                  { -                    vty_out (vty, SHOW_ROUTE_V6_HEADER); -                    first = 0; -                  } - -                if (vrf_header) -                  { -                    vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); -                    vrf_header = 0; -                  } -                vty_show_ip_route (vty, rn, rib, NULL); -              } -          } -      vrf_header = 1; -    } - -  return CMD_SUCCESS; +	int idx_ipv6_prefixlen = 5; +	struct route_table *table; +	struct route_node *rn; +	struct rib *rib; +	struct prefix p; +	struct vrf *vrf; +	struct zebra_vrf *zvrf; +	int ret; +	int first = 1; +	int vrf_header = 1; + +	ret = str2prefix(argv[idx_ipv6_prefixlen]->arg, &p); +	if (!ret) { +		vty_out(vty, "%% Malformed Prefix%s", VTY_NEWLINE); +		return CMD_WARNING; +	} + +	RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) +	{ +		if ((zvrf = vrf->info) == NULL +		    || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) +			continue; + +		/* Show matched type IPv6 routes. */ +		for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) +			RNODE_FOREACH_RIB(rn, rib) +			{ +				struct prefix *p, *src_p; +				srcdest_rnode_prefixes(rn, &p, &src_p); +				if (prefix_match(p, &rn->p)) { +					if (first) { +						vty_out(vty, +							SHOW_ROUTE_V6_HEADER); +						first = 0; +					} + +					if (vrf_header) { +						vty_out(vty, "%sVRF %s:%s", +							VTY_NEWLINE, +							zvrf_name(zvrf), +							VTY_NEWLINE); +						vrf_header = 0; +					} +					vty_show_ip_route(vty, rn, rib, NULL); +				} +			} +		vrf_header = 1; +	} + +	return CMD_SUCCESS;  }  DEFUN (show_ipv6_route_vrf_all_protocol, @@ -3510,52 +3435,49 @@ DEFUN (show_ipv6_route_vrf_all_protocol,         VRF_ALL_CMD_HELP_STR         FRR_IP6_REDIST_HELP_STR_ZEBRA)  { -  int type; -  struct route_table *table; -  struct route_node *rn; -  struct rib *rib; -  struct vrf *vrf; -  struct zebra_vrf *zvrf; -  int first = 1; -  int vrf_header = 1; - -  char *proto = argv[argc - 1]->text; -  type = proto_redistnum (AFI_IP6, proto); - -  if (type < 0) -    { -      vty_out (vty, "Unknown route type%s", VTY_NEWLINE); -      return CMD_WARNING; -    } - -  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) -    { -      if ((zvrf = vrf->info) == NULL || -          (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) -        continue; - -      /* Show matched type IPv6 routes. */ -      for (rn = route_top (table); rn; rn = srcdest_route_next (rn)) -        RNODE_FOREACH_RIB (rn, rib) -          if (rib->type == type) -            { -              if (first) -                { -                  vty_out (vty, SHOW_ROUTE_V6_HEADER); -                  first = 0; -                } - -            if (vrf_header) -              { -                vty_out (vty, "%sVRF %s:%s", VTY_NEWLINE, zvrf_name (zvrf), VTY_NEWLINE); -                vrf_header = 0; -              } -              vty_show_ip_route (vty, rn, rib, NULL); -            } -      vrf_header = 1; -    } - -  return CMD_SUCCESS; +	int type; +	struct route_table *table; +	struct route_node *rn; +	struct rib *rib; +	struct vrf *vrf; +	struct zebra_vrf *zvrf; +	int first = 1; +	int vrf_header = 1; + +	char *proto = argv[argc - 1]->text; +	type = proto_redistnum(AFI_IP6, proto); + +	if (type < 0) { +		vty_out(vty, "Unknown route type%s", VTY_NEWLINE); +		return CMD_WARNING; +	} + +	RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) +	{ +		if ((zvrf = vrf->info) == NULL +		    || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) +			continue; + +		/* Show matched type IPv6 routes. */ +		for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) +			RNODE_FOREACH_RIB(rn, rib) +		if (rib->type == type) { +			if (first) { +				vty_out(vty, SHOW_ROUTE_V6_HEADER); +				first = 0; +			} + +			if (vrf_header) { +				vty_out(vty, "%sVRF %s:%s", VTY_NEWLINE, +					zvrf_name(zvrf), VTY_NEWLINE); +				vrf_header = 0; +			} +			vty_show_ip_route(vty, rn, rib, NULL); +		} +		vrf_header = 1; +	} + +	return CMD_SUCCESS;  }  DEFUN (show_ipv6_route_vrf_all_addr, @@ -3567,37 +3489,36 @@ DEFUN (show_ipv6_route_vrf_all_addr,         VRF_ALL_CMD_HELP_STR         "IPv6 Address\n")  { -  int idx_ipv6 = 5; -  int ret; -  struct prefix_ipv6 p; -  struct route_table *table; -  struct route_node *rn; -  struct vrf *vrf; -  struct zebra_vrf *zvrf; - -  ret = str2prefix_ipv6 (argv[idx_ipv6]->arg, &p); -  if (ret <= 0) -    { -      vty_out (vty, "Malformed IPv6 address%s", VTY_NEWLINE); -      return CMD_WARNING; -    } +	int idx_ipv6 = 5; +	int ret; +	struct prefix_ipv6 p; +	struct route_table *table; +	struct route_node *rn; +	struct vrf *vrf; +	struct zebra_vrf *zvrf; + +	ret = str2prefix_ipv6(argv[idx_ipv6]->arg, &p); +	if (ret <= 0) { +		vty_out(vty, "Malformed IPv6 address%s", VTY_NEWLINE); +		return CMD_WARNING; +	} -  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) -    { -      if ((zvrf = vrf->info) == NULL || -          (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) -        continue; +	RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) +	{ +		if ((zvrf = vrf->info) == NULL +		    || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) +			continue; -      rn = route_node_match (table, (struct prefix *) &p); -      if (! rn) -        continue; +		rn = route_node_match(table, (struct prefix *)&p); +		if (!rn) +			continue; -      vty_show_ip_route_detail (vty, rn, 0); +		vty_show_ip_route_detail(vty, rn, 0); -      route_unlock_node (rn); -    } +		route_unlock_node(rn); +	} -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (show_ipv6_route_vrf_all_prefix, @@ -3609,42 +3530,40 @@ DEFUN (show_ipv6_route_vrf_all_prefix,         VRF_ALL_CMD_HELP_STR         "IPv6 prefix\n")  { -  int idx_ipv6_prefixlen = 5; -  int ret; -  struct prefix_ipv6 p; -  struct route_table *table; -  struct route_node *rn; -  struct vrf *vrf; -  struct zebra_vrf *zvrf; - -  ret = str2prefix_ipv6 (argv[idx_ipv6_prefixlen]->arg, &p); -  if (ret <= 0) -    { -      vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE); -      return CMD_WARNING; -    } +	int idx_ipv6_prefixlen = 5; +	int ret; +	struct prefix_ipv6 p; +	struct route_table *table; +	struct route_node *rn; +	struct vrf *vrf; +	struct zebra_vrf *zvrf; + +	ret = str2prefix_ipv6(argv[idx_ipv6_prefixlen]->arg, &p); +	if (ret <= 0) { +		vty_out(vty, "Malformed IPv6 prefix%s", VTY_NEWLINE); +		return CMD_WARNING; +	} -  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) -    { -      if ((zvrf = vrf->info) == NULL || -          (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) -        continue; +	RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) +	{ +		if ((zvrf = vrf->info) == NULL +		    || (table = zvrf->table[AFI_IP6][SAFI_UNICAST]) == NULL) +			continue; -      rn = route_node_match (table, (struct prefix *) &p); -      if (! rn) -        continue; -      if (rn->p.prefixlen != p.prefixlen) -        { -          route_unlock_node (rn); -          continue; -        } +		rn = route_node_match(table, (struct prefix *)&p); +		if (!rn) +			continue; +		if (rn->p.prefixlen != p.prefixlen) { +			route_unlock_node(rn); +			continue; +		} -      vty_show_ip_route_detail (vty, rn, 0); +		vty_show_ip_route_detail(vty, rn, 0); -      route_unlock_node (rn); -    } +		route_unlock_node(rn); +	} -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (show_ipv6_route_vrf_all_summary, @@ -3656,14 +3575,15 @@ DEFUN (show_ipv6_route_vrf_all_summary,         VRF_ALL_CMD_HELP_STR         "Summary of all IPv6 routes\n")  { -  struct vrf *vrf; -  struct zebra_vrf *zvrf; +	struct vrf *vrf; +	struct zebra_vrf *zvrf; -  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) -    if ((zvrf = vrf->info) != NULL) -      vty_show_ip_route_summary (vty, zvrf->table[AFI_IP6][SAFI_UNICAST]); +	RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) +	if ((zvrf = vrf->info) != NULL) +		vty_show_ip_route_summary(vty, +					  zvrf->table[AFI_IP6][SAFI_UNICAST]); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (show_ipv6_mroute_vrf_all, @@ -3674,32 +3594,31 @@ DEFUN (show_ipv6_mroute_vrf_all,         "IPv6 Multicast routing table\n"         VRF_ALL_CMD_HELP_STR)  { -  struct route_table *table; -  struct route_node *rn; -  struct rib *rib; -  struct vrf *vrf; -  struct zebra_vrf *zvrf; -  int first = 1; - -  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) -    { -      if ((zvrf = vrf->info) == NULL || -          (table = zvrf->table[AFI_IP6][SAFI_MULTICAST]) == NULL) -        continue; - -      /* Show all IPv6 route. */ -      for (rn = route_top (table); rn; rn = srcdest_route_next (rn)) -        RNODE_FOREACH_RIB (rn, rib) -          { -           if (first) -             { -               vty_out (vty, SHOW_ROUTE_V6_HEADER); -               first = 0; -             } -           vty_show_ip_route (vty, rn, rib, NULL); -          } -    } -  return CMD_SUCCESS; +	struct route_table *table; +	struct route_node *rn; +	struct rib *rib; +	struct vrf *vrf; +	struct zebra_vrf *zvrf; +	int first = 1; + +	RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) +	{ +		if ((zvrf = vrf->info) == NULL +		    || (table = zvrf->table[AFI_IP6][SAFI_MULTICAST]) == NULL) +			continue; + +		/* Show all IPv6 route. */ +		for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) +			RNODE_FOREACH_RIB(rn, rib) +			{ +				if (first) { +					vty_out(vty, SHOW_ROUTE_V6_HEADER); +					first = 0; +				} +				vty_show_ip_route(vty, rn, rib, NULL); +			} +	} +	return CMD_SUCCESS;  }  DEFUN (show_ipv6_route_vrf_all_summary_prefix, @@ -3712,93 +3631,107 @@ DEFUN (show_ipv6_route_vrf_all_summary_prefix,         "Summary of all IPv6 routes\n"         "Prefix routes\n")  { -  struct vrf *vrf; -  struct zebra_vrf *zvrf; +	struct vrf *vrf; +	struct zebra_vrf *zvrf; -  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) -    if ((zvrf = vrf->info) != NULL) -      vty_show_ip_route_summary_prefix (vty, zvrf->table[AFI_IP6][SAFI_UNICAST]); +	RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) +	if ((zvrf = vrf->info) != NULL) +		vty_show_ip_route_summary_prefix( +			vty, zvrf->table[AFI_IP6][SAFI_UNICAST]); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  /* Write IPv6 static route configuration. */ -static int -static_config_ipv6 (struct vty *vty) -{ -  struct route_node *rn; -  struct static_route *si; -  int write = 0; -  char buf[SRCDEST2STR_BUFFER]; -  struct route_table *stable; -  struct vrf *vrf; -  struct zebra_vrf *zvrf; - -  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) -    { -      if (!(zvrf = vrf->info)) -        continue; -      if ((stable = zvrf->stable[AFI_IP6][SAFI_UNICAST]) == NULL) -        continue; - -      for (rn = route_top (stable); rn; rn = srcdest_route_next (rn)) -        for (si = rn->info; si; si = si->next) -          { -            vty_out (vty, "ipv6 route %s", srcdest_rnode2str (rn, buf, sizeof buf)); - -	    switch (si->type) -	      { -	      case STATIC_IPV4_GATEWAY: -                vty_out (vty, " %s", inet_ntoa (si->addr.ipv4)); -                break; -	      case STATIC_IPV6_GATEWAY: -		vty_out (vty, " %s", inet_ntop (AF_INET6, &si->addr.ipv6, buf, BUFSIZ)); -		break; -	      case STATIC_IFNAME: -		vty_out (vty, " %s", si->ifname); -		break; -	      case STATIC_BLACKHOLE: -		vty_out (vty, " Null0" ); -		break; -	      case STATIC_IPV6_GATEWAY_IFNAME: -		vty_out (vty, " %s %s", -			 inet_ntop (AF_INET6, &si->addr.ipv6, buf, BUFSIZ), -			 ifindex2ifname (si->ifindex, si->vrf_id)); -		break; -	      } - -            /* flags are incompatible with STATIC_BLACKHOLE */ -            if (si->type != STATIC_BLACKHOLE) -              { -                if (CHECK_FLAG(si->flags, ZEBRA_FLAG_REJECT)) -                  vty_out (vty, " %s", "reject"); -                if (CHECK_FLAG(si->flags, ZEBRA_FLAG_BLACKHOLE)) -                  vty_out (vty, " %s", "blackhole"); -              } - -            if (si->tag) -              vty_out (vty, " tag %"ROUTE_TAG_PRI, si->tag); - -            if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT) -              vty_out (vty, " %d", si->distance); - -            if (si->vrf_id != VRF_DEFAULT) -              { -                vty_out (vty, " vrf %s", zvrf_name (zvrf)); -              } - -            /* Label information */ -            if (si->snh_label.num_labels) -              vty_out (vty, " label %s", -                       mpls_label2str (si->snh_label.num_labels, -                                       si->snh_label.label, buf, sizeof buf)); - -            vty_out (vty, "%s", VTY_NEWLINE); - -            write = 1; -          } -    } -  return write; +static int static_config_ipv6(struct vty *vty) +{ +	struct route_node *rn; +	struct static_route *si; +	int write = 0; +	char buf[SRCDEST2STR_BUFFER]; +	struct route_table *stable; +	struct vrf *vrf; +	struct zebra_vrf *zvrf; + +	RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) +	{ +		if (!(zvrf = vrf->info)) +			continue; +		if ((stable = zvrf->stable[AFI_IP6][SAFI_UNICAST]) == NULL) +			continue; + +		for (rn = route_top(stable); rn; rn = srcdest_route_next(rn)) +			for (si = rn->info; si; si = si->next) { +				vty_out(vty, "ipv6 route %s", +					srcdest_rnode2str(rn, buf, sizeof buf)); + +				switch (si->type) { +				case STATIC_IPV4_GATEWAY: +					vty_out(vty, " %s", +						inet_ntoa(si->addr.ipv4)); +					break; +				case STATIC_IPV6_GATEWAY: +					vty_out(vty, " %s", +						inet_ntop(AF_INET6, +							  &si->addr.ipv6, buf, +							  BUFSIZ)); +					break; +				case STATIC_IFNAME: +					vty_out(vty, " %s", si->ifname); +					break; +				case STATIC_BLACKHOLE: +					vty_out(vty, " Null0"); +					break; +				case STATIC_IPV6_GATEWAY_IFNAME: +					vty_out(vty, " %s %s", +						inet_ntop(AF_INET6, +							  &si->addr.ipv6, buf, +							  BUFSIZ), +						ifindex2ifname(si->ifindex, +							       si->vrf_id)); +					break; +				} + +				/* flags are incompatible with STATIC_BLACKHOLE +				 */ +				if (si->type != STATIC_BLACKHOLE) { +					if (CHECK_FLAG(si->flags, +						       ZEBRA_FLAG_REJECT)) +						vty_out(vty, " %s", "reject"); +					if (CHECK_FLAG(si->flags, +						       ZEBRA_FLAG_BLACKHOLE)) +						vty_out(vty, " %s", +							"blackhole"); +				} + +				if (si->tag) +					vty_out(vty, " tag %" ROUTE_TAG_PRI, +						si->tag); + +				if (si->distance +				    != ZEBRA_STATIC_DISTANCE_DEFAULT) +					vty_out(vty, " %d", si->distance); + +				if (si->vrf_id != VRF_DEFAULT) { +					vty_out(vty, " vrf %s", +						zvrf_name(zvrf)); +				} + +				/* Label information */ +				if (si->snh_label.num_labels) +					vty_out(vty, " label %s", +						mpls_label2str( +							si->snh_label +								.num_labels, +							si->snh_label.label, +							buf, sizeof buf)); + +				vty_out(vty, "%s", VTY_NEWLINE); + +				write = 1; +			} +	} +	return write;  }  DEFUN (allow_external_route_update, @@ -3806,9 +3739,9 @@ DEFUN (allow_external_route_update,         "allow-external-route-update",         "Allow FRR routes to be overwritten by external processes\n")  { -  allow_delete = 1; +	allow_delete = 1; -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (no_allow_external_route_update, @@ -3817,9 +3750,9 @@ DEFUN (no_allow_external_route_update,         NO_STR         "Allow FRR routes to be overwritten by external processes\n")  { -  allow_delete = 0; +	allow_delete = 0; -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  /* show vrf */ @@ -3829,40 +3762,39 @@ DEFUN (show_vrf,         SHOW_STR         "VRF\n")  { -  struct vrf *vrf; -  struct zebra_vrf *zvrf; +	struct vrf *vrf; +	struct zebra_vrf *zvrf; -  RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) -    { -      if (!(zvrf = vrf->info)) -        continue; -      if (!zvrf_id (zvrf)) -        continue; - -     vty_out (vty, "vrf %s ", zvrf_name (zvrf)); -     if (zvrf_id (zvrf) == VRF_UNKNOWN) -       vty_out (vty, "inactive"); -     else -       vty_out (vty, "id %u table %u", zvrf_id (zvrf), zvrf->table_id); -     vty_out (vty, "%s", VTY_NEWLINE); - -    } +	RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) +	{ +		if (!(zvrf = vrf->info)) +			continue; +		if (!zvrf_id(zvrf)) +			continue; + +		vty_out(vty, "vrf %s ", zvrf_name(zvrf)); +		if (zvrf_id(zvrf) == VRF_UNKNOWN) +			vty_out(vty, "inactive"); +		else +			vty_out(vty, "id %u table %u", zvrf_id(zvrf), +				zvrf->table_id); +		vty_out(vty, "%s", VTY_NEWLINE); +	} -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  /* Static ip route configuration write function. */ -static int -zebra_ip_config (struct vty *vty) +static int zebra_ip_config(struct vty *vty)  { -  int write = 0; +	int write = 0; -  write += static_config_ipv4 (vty, SAFI_UNICAST, "ip route"); -  write += static_config_ipv4 (vty, SAFI_MULTICAST, "ip mroute"); -  write += static_config_ipv6 (vty); +	write += static_config_ipv4(vty, SAFI_UNICAST, "ip route"); +	write += static_config_ipv4(vty, SAFI_MULTICAST, "ip mroute"); +	write += static_config_ipv6(vty); -  write += zebra_import_table_config (vty); -  return write; +	write += zebra_import_table_config(vty); +	return write;  }  DEFUN (ip_zebra_import_table_distance, @@ -3876,30 +3808,33 @@ DEFUN (ip_zebra_import_table_distance,         "route-map for filtering\n"         "route-map name\n")  { -  u_int32_t table_id = 0; - -  VTY_GET_INTEGER("table", table_id, argv[2]->arg); -  int distance = ZEBRA_TABLE_DISTANCE_DEFAULT; -  char *rmap = strmatch (argv[argc - 2]->text, "route-map") ? -               XSTRDUP(MTYPE_ROUTE_MAP_NAME, argv[argc - 1]->arg) : NULL; -  if (argc == 7 || (argc == 5 && !rmap)) -    VTY_GET_INTEGER_RANGE("distance", distance, argv[4]->arg, 1, 255); - -  if (!is_zebra_valid_kernel_table(table_id)) -    { -      vty_out(vty, "Invalid routing table ID, %d. Must be in range 1-252%s", -	      table_id, VTY_NEWLINE); -      return CMD_WARNING; -    } +	u_int32_t table_id = 0; + +	VTY_GET_INTEGER("table", table_id, argv[2]->arg); +	int distance = ZEBRA_TABLE_DISTANCE_DEFAULT; +	char *rmap = +		strmatch(argv[argc - 2]->text, "route-map") +			? XSTRDUP(MTYPE_ROUTE_MAP_NAME, argv[argc - 1]->arg) +			: NULL; +	if (argc == 7 || (argc == 5 && !rmap)) +		VTY_GET_INTEGER_RANGE("distance", distance, argv[4]->arg, 1, +				      255); + +	if (!is_zebra_valid_kernel_table(table_id)) { +		vty_out(vty, +			"Invalid routing table ID, %d. Must be in range 1-252%s", +			table_id, VTY_NEWLINE); +		return CMD_WARNING; +	} -  if (is_zebra_main_routing_table(table_id)) -    { -      vty_out(vty, "Invalid routing table ID, %d. Must be non-default table%s", -              table_id, VTY_NEWLINE); -      return CMD_WARNING; -    } +	if (is_zebra_main_routing_table(table_id)) { +		vty_out(vty, +			"Invalid routing table ID, %d. Must be non-default table%s", +			table_id, VTY_NEWLINE); +		return CMD_WARNING; +	} -  return (zebra_import_table(AFI_IP, table_id, distance, rmap, 1)); +	return (zebra_import_table(AFI_IP, table_id, distance, rmap, 1));  }  DEFUN (no_ip_zebra_import_table, @@ -3914,151 +3849,155 @@ DEFUN (no_ip_zebra_import_table,         "route-map for filtering\n"         "route-map name\n")  { -  u_int32_t table_id = 0; -  VTY_GET_INTEGER("table", table_id, argv[3]->arg); +	u_int32_t table_id = 0; +	VTY_GET_INTEGER("table", table_id, argv[3]->arg); -  if (!is_zebra_valid_kernel_table(table_id)) -    { -      vty_out(vty, "Invalid routing table ID. Must be in range 1-252%s", -	      VTY_NEWLINE); -      return CMD_WARNING; -    } +	if (!is_zebra_valid_kernel_table(table_id)) { +		vty_out(vty, +			"Invalid routing table ID. Must be in range 1-252%s", +			VTY_NEWLINE); +		return CMD_WARNING; +	} -  if (is_zebra_main_routing_table(table_id)) -    { -      vty_out(vty, "Invalid routing table ID, %d. Must be non-default table%s", -	      table_id, VTY_NEWLINE); -      return CMD_WARNING; -    } +	if (is_zebra_main_routing_table(table_id)) { +		vty_out(vty, +			"Invalid routing table ID, %d. Must be non-default table%s", +			table_id, VTY_NEWLINE); +		return CMD_WARNING; +	} -  if (!is_zebra_import_table_enabled(AFI_IP, table_id)) -    return CMD_SUCCESS; +	if (!is_zebra_import_table_enabled(AFI_IP, table_id)) +		return CMD_SUCCESS; -  return (zebra_import_table(AFI_IP, table_id, 0, NULL, 0)); +	return (zebra_import_table(AFI_IP, table_id, 0, NULL, 0));  } -static int -config_write_protocol (struct vty *vty) +static int config_write_protocol(struct vty *vty)  { -  if (allow_delete) -    vty_out(vty, "allow-external-route-update%s", VTY_NEWLINE); +	if (allow_delete) +		vty_out(vty, "allow-external-route-update%s", VTY_NEWLINE); -  if (zebra_rnh_ip_default_route) -    vty_out(vty, "ip nht resolve-via-default%s", VTY_NEWLINE); +	if (zebra_rnh_ip_default_route) +		vty_out(vty, "ip nht resolve-via-default%s", VTY_NEWLINE); -  if (zebra_rnh_ipv6_default_route) -    vty_out(vty, "ipv6 nht resolve-via-default%s", VTY_NEWLINE); +	if (zebra_rnh_ipv6_default_route) +		vty_out(vty, "ipv6 nht resolve-via-default%s", VTY_NEWLINE); -  enum multicast_mode ipv4_multicast_mode = multicast_mode_ipv4_get (); +	enum multicast_mode ipv4_multicast_mode = multicast_mode_ipv4_get(); -  if (ipv4_multicast_mode != MCAST_NO_CONFIG) -    vty_out (vty, "ip multicast rpf-lookup-mode %s%s", -             ipv4_multicast_mode == MCAST_URIB_ONLY ? "urib-only" : -             ipv4_multicast_mode == MCAST_MRIB_ONLY ? "mrib-only" : -             ipv4_multicast_mode == MCAST_MIX_MRIB_FIRST ? "mrib-then-urib" : -             ipv4_multicast_mode == MCAST_MIX_DISTANCE ? "lower-distance" : -             "longer-prefix", -             VTY_NEWLINE); +	if (ipv4_multicast_mode != MCAST_NO_CONFIG) +		vty_out(vty, "ip multicast rpf-lookup-mode %s%s", +			ipv4_multicast_mode == MCAST_URIB_ONLY +				? "urib-only" +				: ipv4_multicast_mode == MCAST_MRIB_ONLY +					  ? "mrib-only" +					  : ipv4_multicast_mode +							    == MCAST_MIX_MRIB_FIRST +						    ? "mrib-then-urib" +						    : ipv4_multicast_mode +								      == MCAST_MIX_DISTANCE +							      ? "lower-distance" +							      : "longer-prefix", +			VTY_NEWLINE); -  zebra_routemap_config_write_protocol(vty); +	zebra_routemap_config_write_protocol(vty); -  return 1; +	return 1;  }  /* IP node for static routes. */ -static struct cmd_node ip_node = { IP_NODE,  "",  1 }; -static struct cmd_node protocol_node = { PROTOCOL_NODE, "", 1 }; +static struct cmd_node ip_node = {IP_NODE, "", 1}; +static struct cmd_node protocol_node = {PROTOCOL_NODE, "", 1};  /* Route VTY.  */ -void -zebra_vty_init (void) -{ -  install_node (&ip_node, zebra_ip_config); -  install_node (&protocol_node, config_write_protocol); - -  install_element (CONFIG_NODE, &allow_external_route_update_cmd); -  install_element (CONFIG_NODE, &no_allow_external_route_update_cmd); -  install_element (CONFIG_NODE, &ip_mroute_dist_cmd); -  install_element (CONFIG_NODE, &no_ip_mroute_dist_cmd); -  install_element (CONFIG_NODE, &ip_multicast_mode_cmd); -  install_element (CONFIG_NODE, &no_ip_multicast_mode_cmd); -  install_element (CONFIG_NODE, &ip_route_cmd); -  install_element (CONFIG_NODE, &ip_route_flags_cmd); -  install_element (CONFIG_NODE, &ip_route_mask_cmd); -  install_element (CONFIG_NODE, &ip_route_mask_flags_cmd); -  install_element (CONFIG_NODE, &no_ip_route_cmd); -  install_element (CONFIG_NODE, &no_ip_route_mask_cmd); -  install_element (CONFIG_NODE, &ip_zebra_import_table_distance_cmd); -  install_element (CONFIG_NODE, &no_ip_zebra_import_table_cmd); - -  install_element (VIEW_NODE, &show_vrf_cmd); -  install_element (VIEW_NODE, &show_ip_route_cmd); -  install_element (VIEW_NODE, &show_ip_route_ospf_instance_cmd); -  install_element (VIEW_NODE, &show_ip_route_tag_cmd); -  install_element (VIEW_NODE, &show_ip_nht_cmd); -  install_element (VIEW_NODE, &show_ip_nht_vrf_all_cmd); -  install_element (VIEW_NODE, &show_ipv6_nht_cmd); -  install_element (VIEW_NODE, &show_ipv6_nht_vrf_all_cmd); -  install_element (VIEW_NODE, &show_ip_route_addr_cmd); -  install_element (VIEW_NODE, &show_ip_route_prefix_cmd); -  install_element (VIEW_NODE, &show_ip_route_prefix_longer_cmd); -  install_element (VIEW_NODE, &show_ip_route_protocol_cmd); -  install_element (VIEW_NODE, &show_ip_route_supernets_cmd); -  install_element (VIEW_NODE, &show_ip_route_summary_cmd); -  install_element (VIEW_NODE, &show_ip_route_summary_prefix_cmd); - -  install_element (VIEW_NODE, &show_ip_rpf_cmd); -  install_element (VIEW_NODE, &show_ip_rpf_addr_cmd); - -  /* Commands for VRF */ - -  install_element (CONFIG_NODE, &no_ip_route_flags_cmd); -  install_element (CONFIG_NODE, &no_ip_route_mask_flags_cmd); - -  install_element (VIEW_NODE, &show_ip_route_vrf_cmd); - -  install_element (VIEW_NODE, &show_ip_route_vrf_all_cmd); -  install_element (VIEW_NODE, &show_ip_route_vrf_all_tag_cmd); -  install_element (VIEW_NODE, &show_ip_route_vrf_all_addr_cmd); -  install_element (VIEW_NODE, &show_ip_route_vrf_all_prefix_cmd); -  install_element (VIEW_NODE, &show_ip_route_vrf_all_prefix_longer_cmd); -  install_element (VIEW_NODE, &show_ip_route_vrf_all_protocol_cmd); -  install_element (VIEW_NODE, &show_ip_route_vrf_all_supernets_cmd); -  install_element (VIEW_NODE, &show_ip_route_vrf_all_summary_cmd); -  install_element (VIEW_NODE, &show_ip_route_vrf_all_summary_prefix_cmd); - -  install_element (CONFIG_NODE, &ipv6_route_cmd); -  install_element (CONFIG_NODE, &ipv6_route_flags_cmd); -  install_element (CONFIG_NODE, &ipv6_route_ifname_cmd); -  install_element (CONFIG_NODE, &ipv6_route_ifname_flags_cmd); -  install_element (CONFIG_NODE, &no_ipv6_route_cmd); -  install_element (CONFIG_NODE, &no_ipv6_route_flags_cmd); -  install_element (CONFIG_NODE, &no_ipv6_route_ifname_cmd); -  install_element (CONFIG_NODE, &no_ipv6_route_ifname_flags_cmd); -  install_element (CONFIG_NODE, &ip_nht_default_route_cmd); -  install_element (CONFIG_NODE, &no_ip_nht_default_route_cmd); -  install_element (CONFIG_NODE, &ipv6_nht_default_route_cmd); -  install_element (CONFIG_NODE, &no_ipv6_nht_default_route_cmd); -  install_element (VIEW_NODE, &show_ipv6_route_cmd); -  install_element (VIEW_NODE, &show_ipv6_route_tag_cmd); -  install_element (VIEW_NODE, &show_ipv6_route_summary_cmd); -  install_element (VIEW_NODE, &show_ipv6_route_summary_prefix_cmd); -  install_element (VIEW_NODE, &show_ipv6_route_protocol_cmd); -  install_element (VIEW_NODE, &show_ipv6_route_addr_cmd); -  install_element (VIEW_NODE, &show_ipv6_route_prefix_cmd); -  install_element (VIEW_NODE, &show_ipv6_route_prefix_longer_cmd); - -  install_element (VIEW_NODE, &show_ipv6_mroute_cmd); - -  /* Commands for VRF */ -  install_element (VIEW_NODE, &show_ipv6_route_vrf_all_cmd); -  install_element (VIEW_NODE, &show_ipv6_route_vrf_all_tag_cmd); -  install_element (VIEW_NODE, &show_ipv6_route_vrf_all_summary_cmd); -  install_element (VIEW_NODE, &show_ipv6_route_vrf_all_summary_prefix_cmd); -  install_element (VIEW_NODE, &show_ipv6_route_vrf_all_protocol_cmd); -  install_element (VIEW_NODE, &show_ipv6_route_vrf_all_addr_cmd); -  install_element (VIEW_NODE, &show_ipv6_route_vrf_all_prefix_cmd); -  install_element (VIEW_NODE, &show_ipv6_route_vrf_all_prefix_longer_cmd); - -  install_element (VIEW_NODE, &show_ipv6_mroute_vrf_all_cmd); +void zebra_vty_init(void) +{ +	install_node(&ip_node, zebra_ip_config); +	install_node(&protocol_node, config_write_protocol); + +	install_element(CONFIG_NODE, &allow_external_route_update_cmd); +	install_element(CONFIG_NODE, &no_allow_external_route_update_cmd); +	install_element(CONFIG_NODE, &ip_mroute_dist_cmd); +	install_element(CONFIG_NODE, &no_ip_mroute_dist_cmd); +	install_element(CONFIG_NODE, &ip_multicast_mode_cmd); +	install_element(CONFIG_NODE, &no_ip_multicast_mode_cmd); +	install_element(CONFIG_NODE, &ip_route_cmd); +	install_element(CONFIG_NODE, &ip_route_flags_cmd); +	install_element(CONFIG_NODE, &ip_route_mask_cmd); +	install_element(CONFIG_NODE, &ip_route_mask_flags_cmd); +	install_element(CONFIG_NODE, &no_ip_route_cmd); +	install_element(CONFIG_NODE, &no_ip_route_mask_cmd); +	install_element(CONFIG_NODE, &ip_zebra_import_table_distance_cmd); +	install_element(CONFIG_NODE, &no_ip_zebra_import_table_cmd); + +	install_element(VIEW_NODE, &show_vrf_cmd); +	install_element(VIEW_NODE, &show_ip_route_cmd); +	install_element(VIEW_NODE, &show_ip_route_ospf_instance_cmd); +	install_element(VIEW_NODE, &show_ip_route_tag_cmd); +	install_element(VIEW_NODE, &show_ip_nht_cmd); +	install_element(VIEW_NODE, &show_ip_nht_vrf_all_cmd); +	install_element(VIEW_NODE, &show_ipv6_nht_cmd); +	install_element(VIEW_NODE, &show_ipv6_nht_vrf_all_cmd); +	install_element(VIEW_NODE, &show_ip_route_addr_cmd); +	install_element(VIEW_NODE, &show_ip_route_prefix_cmd); +	install_element(VIEW_NODE, &show_ip_route_prefix_longer_cmd); +	install_element(VIEW_NODE, &show_ip_route_protocol_cmd); +	install_element(VIEW_NODE, &show_ip_route_supernets_cmd); +	install_element(VIEW_NODE, &show_ip_route_summary_cmd); +	install_element(VIEW_NODE, &show_ip_route_summary_prefix_cmd); + +	install_element(VIEW_NODE, &show_ip_rpf_cmd); +	install_element(VIEW_NODE, &show_ip_rpf_addr_cmd); + +	/* Commands for VRF */ + +	install_element(CONFIG_NODE, &no_ip_route_flags_cmd); +	install_element(CONFIG_NODE, &no_ip_route_mask_flags_cmd); + +	install_element(VIEW_NODE, &show_ip_route_vrf_cmd); + +	install_element(VIEW_NODE, &show_ip_route_vrf_all_cmd); +	install_element(VIEW_NODE, &show_ip_route_vrf_all_tag_cmd); +	install_element(VIEW_NODE, &show_ip_route_vrf_all_addr_cmd); +	install_element(VIEW_NODE, &show_ip_route_vrf_all_prefix_cmd); +	install_element(VIEW_NODE, &show_ip_route_vrf_all_prefix_longer_cmd); +	install_element(VIEW_NODE, &show_ip_route_vrf_all_protocol_cmd); +	install_element(VIEW_NODE, &show_ip_route_vrf_all_supernets_cmd); +	install_element(VIEW_NODE, &show_ip_route_vrf_all_summary_cmd); +	install_element(VIEW_NODE, &show_ip_route_vrf_all_summary_prefix_cmd); + +	install_element(CONFIG_NODE, &ipv6_route_cmd); +	install_element(CONFIG_NODE, &ipv6_route_flags_cmd); +	install_element(CONFIG_NODE, &ipv6_route_ifname_cmd); +	install_element(CONFIG_NODE, &ipv6_route_ifname_flags_cmd); +	install_element(CONFIG_NODE, &no_ipv6_route_cmd); +	install_element(CONFIG_NODE, &no_ipv6_route_flags_cmd); +	install_element(CONFIG_NODE, &no_ipv6_route_ifname_cmd); +	install_element(CONFIG_NODE, &no_ipv6_route_ifname_flags_cmd); +	install_element(CONFIG_NODE, &ip_nht_default_route_cmd); +	install_element(CONFIG_NODE, &no_ip_nht_default_route_cmd); +	install_element(CONFIG_NODE, &ipv6_nht_default_route_cmd); +	install_element(CONFIG_NODE, &no_ipv6_nht_default_route_cmd); +	install_element(VIEW_NODE, &show_ipv6_route_cmd); +	install_element(VIEW_NODE, &show_ipv6_route_tag_cmd); +	install_element(VIEW_NODE, &show_ipv6_route_summary_cmd); +	install_element(VIEW_NODE, &show_ipv6_route_summary_prefix_cmd); +	install_element(VIEW_NODE, &show_ipv6_route_protocol_cmd); +	install_element(VIEW_NODE, &show_ipv6_route_addr_cmd); +	install_element(VIEW_NODE, &show_ipv6_route_prefix_cmd); +	install_element(VIEW_NODE, &show_ipv6_route_prefix_longer_cmd); + +	install_element(VIEW_NODE, &show_ipv6_mroute_cmd); + +	/* Commands for VRF */ +	install_element(VIEW_NODE, &show_ipv6_route_vrf_all_cmd); +	install_element(VIEW_NODE, &show_ipv6_route_vrf_all_tag_cmd); +	install_element(VIEW_NODE, &show_ipv6_route_vrf_all_summary_cmd); +	install_element(VIEW_NODE, &show_ipv6_route_vrf_all_summary_prefix_cmd); +	install_element(VIEW_NODE, &show_ipv6_route_vrf_all_protocol_cmd); +	install_element(VIEW_NODE, &show_ipv6_route_vrf_all_addr_cmd); +	install_element(VIEW_NODE, &show_ipv6_route_vrf_all_prefix_cmd); +	install_element(VIEW_NODE, &show_ipv6_route_vrf_all_prefix_longer_cmd); + +	install_element(VIEW_NODE, &show_ipv6_mroute_vrf_all_cmd);  } diff --git a/zebra/zserv.c b/zebra/zserv.c index fb02d60ba4..e0defa3e36 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -14,9 +14,9 @@   * General Public License for more details.   *   * You should have received a copy of the GNU General Public License - * along with GNU Zebra; see the file COPYING.  If not, write to the  - * Free Software Foundation, Inc., 59 Temple Place - Suite 330,  - * Boston, MA 02111-1307, USA.   + * along with GNU Zebra; see the file COPYING.  If not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA.   */  #include <zebra.h> @@ -59,143 +59,138 @@  /* Event list of zebra. */  enum event { ZEBRA_SERV, ZEBRA_READ, ZEBRA_WRITE }; -static void zebra_event (enum event event, int sock, struct zserv *client); +static void zebra_event(enum event event, int sock, struct zserv *client);  extern struct zebra_privs_t zserv_privs; -static void zebra_client_close (struct zserv *client); - -static int -zserv_delayed_close(struct thread *thread) -{ -  struct zserv *client = THREAD_ARG(thread); - -  client->t_suicide = NULL; -  zebra_client_close(client); -  return 0; -} - -static int -zserv_flush_data(struct thread *thread) -{ -  struct zserv *client = THREAD_ARG(thread); - -  client->t_write = NULL; -  if (client->t_suicide) -    { -      zebra_client_close(client); -      return -1; -    } -  switch (buffer_flush_available(client->wb, client->sock)) -    { -    case BUFFER_ERROR: -      zlog_warn("%s: buffer_flush_available failed on zserv client fd %d, " -      		"closing", __func__, client->sock); -      zebra_client_close(client); -      client = NULL; -      break; -    case BUFFER_PENDING: -      client->t_write = thread_add_write(zebrad.master, zserv_flush_data, -      					 client, client->sock); -      break; -    case BUFFER_EMPTY: -      break; -    } - -  if (client) -    client->last_write_time = monotime(NULL); -  return 0; -} - -int -zebra_server_send_message(struct zserv *client) -{ -  if (client->t_suicide) -    return -1; - -  if (client->is_synchronous) -    return 0; - -  stream_set_getp(client->obuf, 0); -  client->last_write_cmd = stream_getw_from(client->obuf, 6); -  switch (buffer_write(client->wb, client->sock, STREAM_DATA(client->obuf), -		       stream_get_endp(client->obuf))) -    { -    case BUFFER_ERROR: -      zlog_warn("%s: buffer_write failed to zserv client fd %d, closing", -      		 __func__, client->sock); -      /* Schedule a delayed close since many of the functions that call this -         one do not check the return code.  They do not allow for the -	 possibility that an I/O error may have caused the client to be -	 deleted. */ -      client->t_suicide = thread_add_event(zebrad.master, zserv_delayed_close, -					   client, 0); -      return -1; -    case BUFFER_EMPTY: -      THREAD_OFF(client->t_write); -      break; -    case BUFFER_PENDING: -      THREAD_WRITE_ON(zebrad.master, client->t_write, -		      zserv_flush_data, client, client->sock); -      break; -    } - -  client->last_write_time = monotime(NULL); -  return 0; -} - -void -zserv_create_header (struct stream *s, uint16_t cmd, vrf_id_t vrf_id) -{ -  /* length placeholder, caller can update */ -  stream_putw (s, ZEBRA_HEADER_SIZE); -  stream_putc (s, ZEBRA_HEADER_MARKER); -  stream_putc (s, ZSERV_VERSION); -  stream_putw (s, vrf_id); -  stream_putw (s, cmd); -} - -static void -zserv_encode_interface (struct stream *s, struct interface *ifp) -{ -  /* Interface information. */ -  stream_put (s, ifp->name, INTERFACE_NAMSIZ); -  stream_putl (s, ifp->ifindex); -  stream_putc (s, ifp->status); -  stream_putq (s, ifp->flags); -  stream_putc (s, ifp->ptm_enable); -  stream_putc (s, ifp->ptm_status); -  stream_putl (s, ifp->metric); -  stream_putl (s, ifp->speed); -  stream_putl (s, ifp->mtu); -  stream_putl (s, ifp->mtu6); -  stream_putl (s, ifp->bandwidth); -  stream_putl (s, ifp->ll_type); -  stream_putl (s, ifp->hw_addr_len); -  if (ifp->hw_addr_len) -    stream_put (s, ifp->hw_addr, ifp->hw_addr_len); - -  /* Then, Traffic Engineering parameters if any */ -  if (HAS_LINK_PARAMS(ifp) && IS_LINK_PARAMS_SET(ifp->link_params)) -    { -      stream_putc (s, 1); -      zebra_interface_link_params_write (s, ifp); -    } -  else -    stream_putc (s, 0); - -  /* Write packet size. */ -  stream_putw_at (s, 0, stream_get_endp (s)); -} - -static void -zserv_encode_vrf (struct stream *s, struct zebra_vrf *zvrf) -{ -  /* Interface information. */ -  stream_put (s, zvrf_name (zvrf), VRF_NAMSIZ); - -  /* Write packet size. */ -  stream_putw_at (s, 0, stream_get_endp (s)); +static void zebra_client_close(struct zserv *client); + +static int zserv_delayed_close(struct thread *thread) +{ +	struct zserv *client = THREAD_ARG(thread); + +	client->t_suicide = NULL; +	zebra_client_close(client); +	return 0; +} + +static int zserv_flush_data(struct thread *thread) +{ +	struct zserv *client = THREAD_ARG(thread); + +	client->t_write = NULL; +	if (client->t_suicide) { +		zebra_client_close(client); +		return -1; +	} +	switch (buffer_flush_available(client->wb, client->sock)) { +	case BUFFER_ERROR: +		zlog_warn( +			"%s: buffer_flush_available failed on zserv client fd %d, " +			"closing", +			__func__, client->sock); +		zebra_client_close(client); +		client = NULL; +		break; +	case BUFFER_PENDING: +		client->t_write = thread_add_write( +			zebrad.master, zserv_flush_data, client, client->sock); +		break; +	case BUFFER_EMPTY: +		break; +	} + +	if (client) +		client->last_write_time = monotime(NULL); +	return 0; +} + +int zebra_server_send_message(struct zserv *client) +{ +	if (client->t_suicide) +		return -1; + +	if (client->is_synchronous) +		return 0; + +	stream_set_getp(client->obuf, 0); +	client->last_write_cmd = stream_getw_from(client->obuf, 6); +	switch (buffer_write(client->wb, client->sock, +			     STREAM_DATA(client->obuf), +			     stream_get_endp(client->obuf))) { +	case BUFFER_ERROR: +		zlog_warn( +			"%s: buffer_write failed to zserv client fd %d, closing", +			__func__, client->sock); +		/* Schedule a delayed close since many of the functions that +		   call this +		   one do not check the return code.  They do not allow for the +		   possibility that an I/O error may have caused the client to +		   be +		   deleted. */ +		client->t_suicide = thread_add_event( +			zebrad.master, zserv_delayed_close, client, 0); +		return -1; +	case BUFFER_EMPTY: +		THREAD_OFF(client->t_write); +		break; +	case BUFFER_PENDING: +		THREAD_WRITE_ON(zebrad.master, client->t_write, +				zserv_flush_data, client, client->sock); +		break; +	} + +	client->last_write_time = monotime(NULL); +	return 0; +} + +void zserv_create_header(struct stream *s, uint16_t cmd, vrf_id_t vrf_id) +{ +	/* length placeholder, caller can update */ +	stream_putw(s, ZEBRA_HEADER_SIZE); +	stream_putc(s, ZEBRA_HEADER_MARKER); +	stream_putc(s, ZSERV_VERSION); +	stream_putw(s, vrf_id); +	stream_putw(s, cmd); +} + +static void zserv_encode_interface(struct stream *s, struct interface *ifp) +{ +	/* Interface information. */ +	stream_put(s, ifp->name, INTERFACE_NAMSIZ); +	stream_putl(s, ifp->ifindex); +	stream_putc(s, ifp->status); +	stream_putq(s, ifp->flags); +	stream_putc(s, ifp->ptm_enable); +	stream_putc(s, ifp->ptm_status); +	stream_putl(s, ifp->metric); +	stream_putl(s, ifp->speed); +	stream_putl(s, ifp->mtu); +	stream_putl(s, ifp->mtu6); +	stream_putl(s, ifp->bandwidth); +	stream_putl(s, ifp->ll_type); +	stream_putl(s, ifp->hw_addr_len); +	if (ifp->hw_addr_len) +		stream_put(s, ifp->hw_addr, ifp->hw_addr_len); + +	/* Then, Traffic Engineering parameters if any */ +	if (HAS_LINK_PARAMS(ifp) && IS_LINK_PARAMS_SET(ifp->link_params)) { +		stream_putc(s, 1); +		zebra_interface_link_params_write(s, ifp); +	} else +		stream_putc(s, 0); + +	/* Write packet size. */ +	stream_putw_at(s, 0, stream_get_endp(s)); +} + +static void zserv_encode_vrf(struct stream *s, struct zebra_vrf *zvrf) +{ +	/* Interface information. */ +	stream_put(s, zvrf_name(zvrf), VRF_NAMSIZ); + +	/* Write packet size. */ +	stream_putw_at(s, 0, stream_get_endp(s));  }  /* Interface is added. Send ZEBRA_INTERFACE_ADD to client. */ @@ -209,99 +204,94 @@ zserv_encode_vrf (struct stream *s, struct zebra_vrf *zvrf)   *   an interface is marked IFF_UP (i.e., an RTM_IFINFO message is   *   received)   */ -int -zsend_interface_add (struct zserv *client, struct interface *ifp) +int zsend_interface_add(struct zserv *client, struct interface *ifp)  { -  struct stream *s; +	struct stream *s; -  s = client->obuf; -  stream_reset (s); +	s = client->obuf; +	stream_reset(s); -  zserv_create_header (s, ZEBRA_INTERFACE_ADD, ifp->vrf_id); -  zserv_encode_interface (s, ifp); +	zserv_create_header(s, ZEBRA_INTERFACE_ADD, ifp->vrf_id); +	zserv_encode_interface(s, ifp); -  client->ifadd_cnt++; -  return zebra_server_send_message(client); +	client->ifadd_cnt++; +	return zebra_server_send_message(client);  }  /* Interface deletion from zebra daemon. */ -int -zsend_interface_delete (struct zserv *client, struct interface *ifp) +int zsend_interface_delete(struct zserv *client, struct interface *ifp)  { -  struct stream *s; +	struct stream *s; -  s = client->obuf; -  stream_reset (s); +	s = client->obuf; +	stream_reset(s); -  zserv_create_header (s, ZEBRA_INTERFACE_DELETE, ifp->vrf_id); -  zserv_encode_interface (s, ifp); +	zserv_create_header(s, ZEBRA_INTERFACE_DELETE, ifp->vrf_id); +	zserv_encode_interface(s, ifp); -  client->ifdel_cnt++; -  return zebra_server_send_message (client); +	client->ifdel_cnt++; +	return zebra_server_send_message(client);  } -int -zsend_vrf_add (struct zserv *client, struct zebra_vrf *zvrf) +int zsend_vrf_add(struct zserv *client, struct zebra_vrf *zvrf)  { -  struct stream *s; +	struct stream *s; -  s = client->obuf; -  stream_reset (s); +	s = client->obuf; +	stream_reset(s); -  zserv_create_header (s, ZEBRA_VRF_ADD, zvrf_id (zvrf)); -  zserv_encode_vrf (s, zvrf); +	zserv_create_header(s, ZEBRA_VRF_ADD, zvrf_id(zvrf)); +	zserv_encode_vrf(s, zvrf); -  client->vrfadd_cnt++; -  return zebra_server_send_message(client); +	client->vrfadd_cnt++; +	return zebra_server_send_message(client);  }  /* VRF deletion from zebra daemon. */ -int -zsend_vrf_delete (struct zserv *client, struct zebra_vrf *zvrf) +int zsend_vrf_delete(struct zserv *client, struct zebra_vrf *zvrf)  { -  struct stream *s; +	struct stream *s; -  s = client->obuf; -  stream_reset (s); +	s = client->obuf; +	stream_reset(s); -  zserv_create_header (s, ZEBRA_VRF_DELETE, zvrf_id (zvrf)); -  zserv_encode_vrf (s, zvrf); +	zserv_create_header(s, ZEBRA_VRF_DELETE, zvrf_id(zvrf)); +	zserv_encode_vrf(s, zvrf); -  client->vrfdel_cnt++; -  return zebra_server_send_message (client); +	client->vrfdel_cnt++; +	return zebra_server_send_message(client);  } -int -zsend_interface_link_params (struct zserv *client, struct interface *ifp) +int zsend_interface_link_params(struct zserv *client, struct interface *ifp)  { -  struct stream *s; +	struct stream *s; -  /* Check this client need interface information. */ -  if (! client->ifinfo) -    return 0; +	/* Check this client need interface information. */ +	if (!client->ifinfo) +		return 0; -  if (!ifp->link_params) -    return 0; -  s = client->obuf; -  stream_reset (s); +	if (!ifp->link_params) +		return 0; +	s = client->obuf; +	stream_reset(s); -  zserv_create_header (s, ZEBRA_INTERFACE_LINK_PARAMS, ifp->vrf_id); +	zserv_create_header(s, ZEBRA_INTERFACE_LINK_PARAMS, ifp->vrf_id); -  /* Add Interface Index */ -  stream_putl (s, ifp->ifindex); +	/* Add Interface Index */ +	stream_putl(s, ifp->ifindex); -  /* Then TE Link Parameters */ -  if (zebra_interface_link_params_write (s, ifp) == 0) -    return 0; +	/* Then TE Link Parameters */ +	if (zebra_interface_link_params_write(s, ifp) == 0) +		return 0; -  /* Write packet size. */ -  stream_putw_at (s, 0, stream_get_endp (s)); +	/* Write packet size. */ +	stream_putw_at(s, 0, stream_get_endp(s)); -  return zebra_server_send_message (client); +	return zebra_server_send_message(client);  }  /* Interface address is added/deleted. Send ZEBRA_INTERFACE_ADDRESS_ADD or - * ZEBRA_INTERFACE_ADDRESS_DELETE to the client.  + * ZEBRA_INTERFACE_ADDRESS_DELETE to the client.   *   * A ZEBRA_INTERFACE_ADDRESS_ADD is sent in the following situations:   * - in response to a 3-byte ZEBRA_INTERFACE_ADD request @@ -316,13 +306,13 @@ zsend_interface_link_params (struct zserv *client, struct interface *ifp)   *    - for the vty commands "ip address A.B.C.D/M [<secondary>|<label LINE>]"   *      and "no bandwidth <1-10000000>", "ipv6 address X:X::X:X/M"   *    - when an RTM_NEWADDR message is received from the kernel, - *  - * The call tree that triggers ZEBRA_INTERFACE_ADDRESS_DELETE:  + * + * The call tree that triggers ZEBRA_INTERFACE_ADDRESS_DELETE:   *   *                   zsend_interface_address(DELETE) - *                           ^                          - *                           |                         - *          zebra_interface_address_delete_update     + *                           ^ + *                           | + *          zebra_interface_address_delete_update   *             ^                        ^      ^   *             |                        |      if_delete_update   *             |                        | @@ -338,232 +328,230 @@ zsend_interface_link_params (struct zserv *client, struct interface *ifp)   *     ["no ipv6 address X:X::X:X/M"]   *   */ -int -zsend_interface_address (int cmd, struct zserv *client,  -                         struct interface *ifp, struct connected *ifc) +int zsend_interface_address(int cmd, struct zserv *client, +			    struct interface *ifp, struct connected *ifc)  { -  int blen; -  struct stream *s; -  struct prefix *p; +	int blen; +	struct stream *s; +	struct prefix *p; + +	s = client->obuf; +	stream_reset(s); -  s = client->obuf; -  stream_reset (s); -   -  zserv_create_header (s, cmd, ifp->vrf_id); -  stream_putl (s, ifp->ifindex); +	zserv_create_header(s, cmd, ifp->vrf_id); +	stream_putl(s, ifp->ifindex); -  /* Interface address flag. */ -  stream_putc (s, ifc->flags); +	/* Interface address flag. */ +	stream_putc(s, ifc->flags); -  /* Prefix information. */ -  p = ifc->address; -  stream_putc (s, p->family); -  blen = prefix_blen (p); -  stream_put (s, &p->u.prefix, blen); +	/* Prefix information. */ +	p = ifc->address; +	stream_putc(s, p->family); +	blen = prefix_blen(p); +	stream_put(s, &p->u.prefix, blen); -  /*  -   * XXX gnu version does not send prefixlen for ZEBRA_INTERFACE_ADDRESS_DELETE -   * but zebra_interface_address_delete_read() in the gnu version  -   * expects to find it -   */ -  stream_putc (s, p->prefixlen); +	/* +	 * XXX gnu version does not send prefixlen for +	 * ZEBRA_INTERFACE_ADDRESS_DELETE +	 * but zebra_interface_address_delete_read() in the gnu version +	 * expects to find it +	 */ +	stream_putc(s, p->prefixlen); -  /* Destination. */ -  p = ifc->destination; -  if (p) -    stream_put (s, &p->u.prefix, blen); -  else -    stream_put (s, NULL, blen); +	/* Destination. */ +	p = ifc->destination; +	if (p) +		stream_put(s, &p->u.prefix, blen); +	else +		stream_put(s, NULL, blen); -  /* Write packet size. */ -  stream_putw_at (s, 0, stream_get_endp (s)); +	/* Write packet size. */ +	stream_putw_at(s, 0, stream_get_endp(s)); -  client->connected_rt_add_cnt++; -  return zebra_server_send_message(client); +	client->connected_rt_add_cnt++; +	return zebra_server_send_message(client);  } -static int -zsend_interface_nbr_address (int cmd, struct zserv *client, -                             struct interface *ifp, struct nbr_connected *ifc) +static int zsend_interface_nbr_address(int cmd, struct zserv *client, +				       struct interface *ifp, +				       struct nbr_connected *ifc)  { -  int blen; -  struct stream *s; -  struct prefix *p; +	int blen; +	struct stream *s; +	struct prefix *p; -  s = client->obuf; -  stream_reset (s); +	s = client->obuf; +	stream_reset(s); -  zserv_create_header (s, cmd, ifp->vrf_id); -  stream_putl (s, ifp->ifindex); +	zserv_create_header(s, cmd, ifp->vrf_id); +	stream_putl(s, ifp->ifindex); -  /* Prefix information. */ -  p = ifc->address; -  stream_putc (s, p->family); -  blen = prefix_blen (p); -  stream_put (s, &p->u.prefix, blen); +	/* Prefix information. */ +	p = ifc->address; +	stream_putc(s, p->family); +	blen = prefix_blen(p); +	stream_put(s, &p->u.prefix, blen); -  /* -   * XXX gnu version does not send prefixlen for ZEBRA_INTERFACE_ADDRESS_DELETE -   * but zebra_interface_address_delete_read() in the gnu version -   * expects to find it -   */ -  stream_putc (s, p->prefixlen); +	/* +	 * XXX gnu version does not send prefixlen for +	 * ZEBRA_INTERFACE_ADDRESS_DELETE +	 * but zebra_interface_address_delete_read() in the gnu version +	 * expects to find it +	 */ +	stream_putc(s, p->prefixlen); -  /* Write packet size. */ -  stream_putw_at (s, 0, stream_get_endp (s)); +	/* Write packet size. */ +	stream_putw_at(s, 0, stream_get_endp(s)); -  return zebra_server_send_message(client); +	return zebra_server_send_message(client);  }  /* Interface address addition. */ -static void -zebra_interface_nbr_address_add_update (struct interface *ifp, -                                        struct nbr_connected *ifc) -{ -  struct listnode *node, *nnode; -  struct zserv *client; -  struct prefix *p; - -  if (IS_ZEBRA_DEBUG_EVENT) -    { -      char buf[INET6_ADDRSTRLEN]; - -      p = ifc->address; -      zlog_debug ("MESSAGE: ZEBRA_INTERFACE_NBR_ADDRESS_ADD %s/%d on %s", -      inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN), -      p->prefixlen, ifc->ifp->name); -    } +static void zebra_interface_nbr_address_add_update(struct interface *ifp, +						   struct nbr_connected *ifc) +{ +	struct listnode *node, *nnode; +	struct zserv *client; +	struct prefix *p; + +	if (IS_ZEBRA_DEBUG_EVENT) { +		char buf[INET6_ADDRSTRLEN]; + +		p = ifc->address; +		zlog_debug( +			"MESSAGE: ZEBRA_INTERFACE_NBR_ADDRESS_ADD %s/%d on %s", +			inet_ntop(p->family, &p->u.prefix, buf, +				  INET6_ADDRSTRLEN), +			p->prefixlen, ifc->ifp->name); +	} -  for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) -    zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_ADD, client, ifp, ifc); +	for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) +		zsend_interface_nbr_address(ZEBRA_INTERFACE_NBR_ADDRESS_ADD, +					    client, ifp, ifc);  }  /* Interface address deletion. */ -static void -zebra_interface_nbr_address_delete_update (struct interface *ifp, -                                           struct nbr_connected *ifc) -{ -  struct listnode *node, *nnode; -  struct zserv *client; -  struct prefix *p; - -  if (IS_ZEBRA_DEBUG_EVENT) -    { -      char buf[INET6_ADDRSTRLEN]; - -      p = ifc->address; -      zlog_debug ("MESSAGE: ZEBRA_INTERFACE_NBR_ADDRESS_DELETE %s/%d on %s", -		  inet_ntop (p->family, &p->u.prefix, buf, INET6_ADDRSTRLEN), -		 p->prefixlen, ifc->ifp->name); -    } +static void zebra_interface_nbr_address_delete_update(struct interface *ifp, +						      struct nbr_connected *ifc) +{ +	struct listnode *node, *nnode; +	struct zserv *client; +	struct prefix *p; + +	if (IS_ZEBRA_DEBUG_EVENT) { +		char buf[INET6_ADDRSTRLEN]; + +		p = ifc->address; +		zlog_debug( +			"MESSAGE: ZEBRA_INTERFACE_NBR_ADDRESS_DELETE %s/%d on %s", +			inet_ntop(p->family, &p->u.prefix, buf, +				  INET6_ADDRSTRLEN), +			p->prefixlen, ifc->ifp->name); +	} -  for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) -    zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_DELETE, client, ifp, ifc); +	for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) +		zsend_interface_nbr_address(ZEBRA_INTERFACE_NBR_ADDRESS_DELETE, +					    client, ifp, ifc);  }  /* Send addresses on interface to client */ -int -zsend_interface_addresses (struct zserv *client, struct interface *ifp) +int zsend_interface_addresses(struct zserv *client, struct interface *ifp)  { -  struct listnode *cnode, *cnnode; -  struct connected *c; -  struct nbr_connected *nc; +	struct listnode *cnode, *cnnode; +	struct connected *c; +	struct nbr_connected *nc; -  /* Send interface addresses. */ -  for (ALL_LIST_ELEMENTS (ifp->connected, cnode, cnnode, c)) -    { -      if (!CHECK_FLAG (c->conf, ZEBRA_IFC_REAL)) -        continue; +	/* Send interface addresses. */ +	for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) { +		if (!CHECK_FLAG(c->conf, ZEBRA_IFC_REAL)) +			continue; -      if (zsend_interface_address (ZEBRA_INTERFACE_ADDRESS_ADD, client, -                                   ifp, c) < 0) -        return -1; -    } +		if (zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_ADD, client, +					    ifp, c) +		    < 0) +			return -1; +	} -  /* Send interface neighbors. */ -  for (ALL_LIST_ELEMENTS (ifp->nbr_connected, cnode, cnnode, nc)) -    { -      if (zsend_interface_nbr_address (ZEBRA_INTERFACE_NBR_ADDRESS_ADD, -                                       client, ifp, nc) < 0) -        return -1; -    } +	/* Send interface neighbors. */ +	for (ALL_LIST_ELEMENTS(ifp->nbr_connected, cnode, cnnode, nc)) { +		if (zsend_interface_nbr_address(ZEBRA_INTERFACE_NBR_ADDRESS_ADD, +						client, ifp, nc) +		    < 0) +			return -1; +	} -  return 0; +	return 0;  }  /* Notify client about interface moving from one VRF to another.   * Whether client is interested in old and new VRF is checked by caller.   */ -int -zsend_interface_vrf_update (struct zserv *client, struct interface *ifp, -                            vrf_id_t vrf_id) +int zsend_interface_vrf_update(struct zserv *client, struct interface *ifp, +			       vrf_id_t vrf_id)  { -  struct stream *s; +	struct stream *s; -  s = client->obuf; -  stream_reset (s); +	s = client->obuf; +	stream_reset(s); -  zserv_create_header (s, ZEBRA_INTERFACE_VRF_UPDATE, ifp->vrf_id); +	zserv_create_header(s, ZEBRA_INTERFACE_VRF_UPDATE, ifp->vrf_id); -  /* Fill in the ifIndex of the interface and its new VRF (id) */ -  stream_putl (s, ifp->ifindex); -  stream_putw (s, vrf_id); +	/* Fill in the ifIndex of the interface and its new VRF (id) */ +	stream_putl(s, ifp->ifindex); +	stream_putw(s, vrf_id); -  /* Write packet size. */ -  stream_putw_at (s, 0, stream_get_endp (s)); +	/* Write packet size. */ +	stream_putw_at(s, 0, stream_get_endp(s)); -  client->if_vrfchg_cnt++; -  return zebra_server_send_message(client); +	client->if_vrfchg_cnt++; +	return zebra_server_send_message(client);  }  /* Add new nbr connected IPv6 address */ -void -nbr_connected_add_ipv6 (struct interface *ifp, struct in6_addr *address) +void nbr_connected_add_ipv6(struct interface *ifp, struct in6_addr *address)  { -  struct nbr_connected *ifc; -  struct prefix p; +	struct nbr_connected *ifc; +	struct prefix p; -  p.family = AF_INET6; -  IPV6_ADDR_COPY (&p.u.prefix, address); -  p.prefixlen = IPV6_MAX_PREFIXLEN; +	p.family = AF_INET6; +	IPV6_ADDR_COPY(&p.u.prefix, address); +	p.prefixlen = IPV6_MAX_PREFIXLEN; -  if (!(ifc = listnode_head(ifp->nbr_connected))) -    { -      /* new addition */ -      ifc = nbr_connected_new (); -      ifc->address = prefix_new(); -      ifc->ifp = ifp; -      listnode_add (ifp->nbr_connected, ifc); -    } +	if (!(ifc = listnode_head(ifp->nbr_connected))) { +		/* new addition */ +		ifc = nbr_connected_new(); +		ifc->address = prefix_new(); +		ifc->ifp = ifp; +		listnode_add(ifp->nbr_connected, ifc); +	} -  prefix_copy(ifc->address, &p); +	prefix_copy(ifc->address, &p); -  zebra_interface_nbr_address_add_update (ifp, ifc); +	zebra_interface_nbr_address_add_update(ifp, ifc); -  if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp, address, 1); +	if_nbr_ipv6ll_to_ipv4ll_neigh_update(ifp, address, 1);  } -void -nbr_connected_delete_ipv6 (struct interface *ifp, struct in6_addr *address) +void nbr_connected_delete_ipv6(struct interface *ifp, struct in6_addr *address)  { -  struct nbr_connected *ifc; -  struct prefix p; +	struct nbr_connected *ifc; +	struct prefix p; -  p.family = AF_INET6; -  IPV6_ADDR_COPY (&p.u.prefix, address); -  p.prefixlen = IPV6_MAX_PREFIXLEN; +	p.family = AF_INET6; +	IPV6_ADDR_COPY(&p.u.prefix, address); +	p.prefixlen = IPV6_MAX_PREFIXLEN; -  ifc = nbr_connected_check(ifp, &p); -  if (!ifc) -    return; +	ifc = nbr_connected_check(ifp, &p); +	if (!ifc) +		return; -  listnode_delete (ifp->nbr_connected, ifc); +	listnode_delete(ifp->nbr_connected, ifc); -  zebra_interface_nbr_address_delete_update (ifp, ifc); +	zebra_interface_nbr_address_delete_update(ifp, ifc); -  if_nbr_ipv6ll_to_ipv4ll_neigh_update (ifp, address, 0); +	if_nbr_ipv6ll_to_ipv4ll_neigh_update(ifp, address, 0); -  nbr_connected_free (ifc); +	nbr_connected_free(ifc);  }  /* @@ -576,23 +564,22 @@ nbr_connected_delete_ipv6 (struct interface *ifp, struct in6_addr *address)   *   - a vty command modifying the bandwidth of an interface is received.   * The ZEBRA_INTERFACE_DOWN message is sent when an if_down is detected.   */ -int -zsend_interface_update (int cmd, struct zserv *client, struct interface *ifp) +int zsend_interface_update(int cmd, struct zserv *client, struct interface *ifp)  { -  struct stream *s; +	struct stream *s; -  s = client->obuf; -  stream_reset (s); +	s = client->obuf; +	stream_reset(s); -  zserv_create_header (s, cmd, ifp->vrf_id); -  zserv_encode_interface (s, ifp); +	zserv_create_header(s, cmd, ifp->vrf_id); +	zserv_encode_interface(s, ifp); -  if (cmd == ZEBRA_INTERFACE_UP) -    client->ifup_cnt++; -  else -    client->ifdown_cnt++; +	if (cmd == ZEBRA_INTERFACE_UP) +		client->ifup_cnt++; +	else +		client->ifdown_cnt++; -  return zebra_server_send_message(client); +	return zebra_server_send_message(client);  }  /* @@ -602,336 +589,316 @@ zsend_interface_update (int cmd, struct zserv *client, struct interface *ifp)   * away or ignored by the receiver. This is the leaner function that is not a   * duplicate of the zapi_ipv4_route_add/del.   * - * The primary difference is that this function merely sends a single NH instead of + * The primary difference is that this function merely sends a single NH instead + * of   * all the nexthops.   */ -int -zsend_redistribute_route (int add, struct zserv *client, struct prefix *p, -                          struct prefix *src_p, struct rib *rib) -{ -  afi_t afi; -  int cmd; -  int psize; -  struct stream *s; -  struct nexthop *nexthop; -  unsigned long nhnummark = 0, messmark = 0; -  int nhnum = 0; -  u_char zapi_flags = 0; -  struct nexthop dummy_nh; - -  afi = family2afi (p->family); -  if (add) -    { -      switch (afi) -	{ -	case AFI_IP: -	  cmd = ZEBRA_REDISTRIBUTE_IPV4_ADD; -	  client->redist_v4_add_cnt++; -	  break; -	case AFI_IP6: -	  cmd = ZEBRA_REDISTRIBUTE_IPV6_ADD; -	  client->redist_v6_add_cnt++; -	  break; -	default: -	  return -1; -	} -    } -  else -    { -      switch (afi) -	{ -	case AFI_IP: -	  cmd = ZEBRA_REDISTRIBUTE_IPV4_DEL; -	  client->redist_v4_del_cnt++; -	  break; -	case AFI_IP6: -	  cmd = ZEBRA_REDISTRIBUTE_IPV6_DEL; -	  client->redist_v6_del_cnt++; -	  break; -	default: -	  return -1; -	} -    } - -  s = client->obuf; -  stream_reset (s); -  memset(&dummy_nh, 0, sizeof(struct nexthop)); - -  zserv_create_header (s, cmd, rib->vrf_id); -   -  /* Put type and nexthop. */ -  stream_putc (s, rib->type); -  stream_putw (s, rib->instance); -  stream_putl (s, rib->flags); - -  /* marker for message flags field */ -  messmark = stream_get_endp (s); -  stream_putc (s, 0); - -  /* Prefix. */ -  psize = PSIZE (p->prefixlen); -  stream_putc (s, p->prefixlen); -  stream_write (s, (u_char *) & p->u.prefix, psize); - -  if (src_p) -    { -      SET_FLAG (zapi_flags, ZAPI_MESSAGE_SRCPFX); -      psize = PSIZE (src_p->prefixlen); -      stream_putc (s, src_p->prefixlen); -      stream_write (s, (u_char *) & src_p->u.prefix, psize); -    } - -  for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) -    { -      /* We don't send any nexthops when there's a multipath */ -      if (rib->nexthop_active_num > 1 && client->proto != ZEBRA_ROUTE_LDP) -	{ -          SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP); -          SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX); - -	  stream_putc(s, 1); -	  if (p->family == AF_INET) -	    { -	      stream_put_in_addr (s, &dummy_nh.gate.ipv4); -	    } -	  else if (p->family == AF_INET6) -	    { -                stream_write (s, (u_char *) &dummy_nh.gate.ipv6, 16); -	    } -	  else -	    { -	      /* We don't handle anything else now, abort */ -	      zlog_err("%s: Unable to redistribute route of unknown family, %d\n", -		       __func__, p->family); -	      return -1; -	    } -          stream_putc (s, 1); -          stream_putl (s, 0);	/* dummy ifindex */ -	  break; +int zsend_redistribute_route(int add, struct zserv *client, struct prefix *p, +			     struct prefix *src_p, struct rib *rib) +{ +	afi_t afi; +	int cmd; +	int psize; +	struct stream *s; +	struct nexthop *nexthop; +	unsigned long nhnummark = 0, messmark = 0; +	int nhnum = 0; +	u_char zapi_flags = 0; +	struct nexthop dummy_nh; + +	afi = family2afi(p->family); +	if (add) { +		switch (afi) { +		case AFI_IP: +			cmd = ZEBRA_REDISTRIBUTE_IPV4_ADD; +			client->redist_v4_add_cnt++; +			break; +		case AFI_IP6: +			cmd = ZEBRA_REDISTRIBUTE_IPV6_ADD; +			client->redist_v6_add_cnt++; +			break; +		default: +			return -1; +		} +	} else { +		switch (afi) { +		case AFI_IP: +			cmd = ZEBRA_REDISTRIBUTE_IPV4_DEL; +			client->redist_v4_del_cnt++; +			break; +		case AFI_IP6: +			cmd = ZEBRA_REDISTRIBUTE_IPV6_DEL; +			client->redist_v6_del_cnt++; +			break; +		default: +			return -1; +		}  	} -      if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) -        { -          SET_FLAG (zapi_flags, ZAPI_MESSAGE_NEXTHOP); -          SET_FLAG (zapi_flags, ZAPI_MESSAGE_IFINDEX); -          if (nhnummark == 0) -            { -              nhnummark = stream_get_endp (s); -              stream_putc (s, 1); /* placeholder */ -            } -          nhnum++; - -          switch(nexthop->type)  -            { -              case NEXTHOP_TYPE_IPV4: -              case NEXTHOP_TYPE_IPV4_IFINDEX: -                stream_put_in_addr (s, &nexthop->gate.ipv4); -                break; -              case NEXTHOP_TYPE_IPV6: -              case NEXTHOP_TYPE_IPV6_IFINDEX: -		/* Only BGP supports IPv4 prefix with IPv6 NH, so kill this */ -		if (p->family == AF_INET) -		  stream_put_in_addr(s, &dummy_nh.gate.ipv4); -		else -		  stream_write (s, (u_char *) &nexthop->gate.ipv6, 16); -                break; -              default: -                if (cmd == ZEBRA_REDISTRIBUTE_IPV4_ADD -                    || cmd == ZEBRA_REDISTRIBUTE_IPV4_DEL) -                  { -                    struct in_addr empty; -                    memset (&empty, 0, sizeof (struct in_addr)); -                    stream_write (s, (u_char *) &empty, IPV4_MAX_BYTELEN); -                  } -                else -                  { -                    struct in6_addr empty; -                    memset (&empty, 0, sizeof (struct in6_addr)); -                    stream_write (s, (u_char *) &empty, IPV6_MAX_BYTELEN); -                  } -              } - -          /* Interface index. */ -          stream_putc (s, 1); -          stream_putl (s, nexthop->ifindex); - -	  /* ldpd needs all nexthops */ -	  if (client->proto != ZEBRA_ROUTE_LDP) -            break; -        } -    } - -  /* Distance */ -  SET_FLAG (zapi_flags, ZAPI_MESSAGE_DISTANCE); -  stream_putc (s, rib->distance); - -  /* Metric */ -  SET_FLAG (zapi_flags, ZAPI_MESSAGE_METRIC); -  stream_putl (s, rib->metric); - -  /* Tag */ -  if (rib->tag) -    { -      SET_FLAG(zapi_flags, ZAPI_MESSAGE_TAG); -      stream_putl(s, rib->tag); -    } - -  /* MTU */ -  SET_FLAG (zapi_flags, ZAPI_MESSAGE_MTU); -  stream_putl (s, rib->mtu); - -  /* write real message flags value */ -  stream_putc_at (s, messmark, zapi_flags); - -  /* Write next-hop number */ -  if (nhnummark) -    stream_putc_at (s, nhnummark, nhnum); - -  /* Write packet size. */ -  stream_putw_at (s, 0, stream_get_endp (s)); - -  return zebra_server_send_message(client); -} - -static int -zsend_write_nexthop (struct stream *s, struct nexthop *nexthop) -{ -  stream_putc (s, nexthop->type); -  switch (nexthop->type) -    { -    case NEXTHOP_TYPE_IPV4: -    case NEXTHOP_TYPE_IPV4_IFINDEX: -      stream_put_in_addr (s, &nexthop->gate.ipv4); -      stream_putl (s, nexthop->ifindex); -      break; -    case NEXTHOP_TYPE_IPV6: -      stream_put (s, &nexthop->gate.ipv6, 16); -      break; -    case NEXTHOP_TYPE_IPV6_IFINDEX: -      stream_put (s, &nexthop->gate.ipv6, 16); -      stream_putl (s, nexthop->ifindex); -      break; -    case NEXTHOP_TYPE_IFINDEX: -      stream_putl (s, nexthop->ifindex); -      break; -    default: -      /* do nothing */ -      break; -    } -  return 1; -} +	s = client->obuf; +	stream_reset(s); +	memset(&dummy_nh, 0, sizeof(struct nexthop)); -/* Nexthop register */ -static int -zserv_rnh_register (struct zserv *client, int sock, u_short length, -		    rnh_type_t type, struct zebra_vrf *zvrf) -{ -  struct rnh *rnh; -  struct stream *s; -  struct prefix p; -  u_short l = 0; -  u_char flags = 0; - -  if (IS_ZEBRA_DEBUG_NHT) -    zlog_debug("rnh_register msg from client %s: length=%d, type=%s\n", -	       zebra_route_string(client->proto), length, -	       (type == RNH_NEXTHOP_TYPE) ? "nexthop" : "route"); - -  s = client->ibuf; - -  client->nh_reg_time = monotime(NULL); - -  while (l < length) -    { -      flags = stream_getc(s); -      p.family = stream_getw(s); -      p.prefixlen = stream_getc(s); -      l += 4; -      if (p.family == AF_INET) -	{ -	  p.u.prefix4.s_addr = stream_get_ipv4(s); -	  l += IPV4_MAX_BYTELEN; -	} -      else if (p.family == AF_INET6) -	{ -	  stream_get(&p.u.prefix6, s, IPV6_MAX_BYTELEN); -	  l += IPV6_MAX_BYTELEN; -	} -      else -	{ -	  zlog_err("rnh_register: Received unknown family type %d\n", -		   p.family); -	  return -1; +	zserv_create_header(s, cmd, rib->vrf_id); + +	/* Put type and nexthop. */ +	stream_putc(s, rib->type); +	stream_putw(s, rib->instance); +	stream_putl(s, rib->flags); + +	/* marker for message flags field */ +	messmark = stream_get_endp(s); +	stream_putc(s, 0); + +	/* Prefix. */ +	psize = PSIZE(p->prefixlen); +	stream_putc(s, p->prefixlen); +	stream_write(s, (u_char *)&p->u.prefix, psize); + +	if (src_p) { +		SET_FLAG(zapi_flags, ZAPI_MESSAGE_SRCPFX); +		psize = PSIZE(src_p->prefixlen); +		stream_putc(s, src_p->prefixlen); +		stream_write(s, (u_char *)&src_p->u.prefix, psize);  	} -      rnh = zebra_add_rnh(&p, zvrf_id (zvrf), type); -      if (type == RNH_NEXTHOP_TYPE) -	{ -	  if (flags && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)) -	    SET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED); -	  else if (!flags && CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)) -	    UNSET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED); + +	for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) { +		/* We don't send any nexthops when there's a multipath */ +		if (rib->nexthop_active_num > 1 +		    && client->proto != ZEBRA_ROUTE_LDP) { +			SET_FLAG(zapi_flags, ZAPI_MESSAGE_NEXTHOP); +			SET_FLAG(zapi_flags, ZAPI_MESSAGE_IFINDEX); + +			stream_putc(s, 1); +			if (p->family == AF_INET) { +				stream_put_in_addr(s, &dummy_nh.gate.ipv4); +			} else if (p->family == AF_INET6) { +				stream_write(s, (u_char *)&dummy_nh.gate.ipv6, +					     16); +			} else { +				/* We don't handle anything else now, abort */ +				zlog_err( +					"%s: Unable to redistribute route of unknown family, %d\n", +					__func__, p->family); +				return -1; +			} +			stream_putc(s, 1); +			stream_putl(s, 0); /* dummy ifindex */ +			break; +		} + +		if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) { +			SET_FLAG(zapi_flags, ZAPI_MESSAGE_NEXTHOP); +			SET_FLAG(zapi_flags, ZAPI_MESSAGE_IFINDEX); +			if (nhnummark == 0) { +				nhnummark = stream_get_endp(s); +				stream_putc(s, 1); /* placeholder */ +			} +			nhnum++; + +			switch (nexthop->type) { +			case NEXTHOP_TYPE_IPV4: +			case NEXTHOP_TYPE_IPV4_IFINDEX: +				stream_put_in_addr(s, &nexthop->gate.ipv4); +				break; +			case NEXTHOP_TYPE_IPV6: +			case NEXTHOP_TYPE_IPV6_IFINDEX: +				/* Only BGP supports IPv4 prefix with IPv6 NH, +				 * so kill this */ +				if (p->family == AF_INET) +					stream_put_in_addr(s, +							   &dummy_nh.gate.ipv4); +				else +					stream_write( +						s, +						(u_char *)&nexthop->gate.ipv6, +						16); +				break; +			default: +				if (cmd == ZEBRA_REDISTRIBUTE_IPV4_ADD +				    || cmd == ZEBRA_REDISTRIBUTE_IPV4_DEL) { +					struct in_addr empty; +					memset(&empty, 0, +					       sizeof(struct in_addr)); +					stream_write(s, (u_char *)&empty, +						     IPV4_MAX_BYTELEN); +				} else { +					struct in6_addr empty; +					memset(&empty, 0, +					       sizeof(struct in6_addr)); +					stream_write(s, (u_char *)&empty, +						     IPV6_MAX_BYTELEN); +				} +			} + +			/* Interface index. */ +			stream_putc(s, 1); +			stream_putl(s, nexthop->ifindex); + +			/* ldpd needs all nexthops */ +			if (client->proto != ZEBRA_ROUTE_LDP) +				break; +		}  	} -      else if (type == RNH_IMPORT_CHECK_TYPE) -	{ -	  if (flags && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH)) -	    SET_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH); -	  else if (!flags && CHECK_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH)) -	    UNSET_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH); + +	/* Distance */ +	SET_FLAG(zapi_flags, ZAPI_MESSAGE_DISTANCE); +	stream_putc(s, rib->distance); + +	/* Metric */ +	SET_FLAG(zapi_flags, ZAPI_MESSAGE_METRIC); +	stream_putl(s, rib->metric); + +	/* Tag */ +	if (rib->tag) { +		SET_FLAG(zapi_flags, ZAPI_MESSAGE_TAG); +		stream_putl(s, rib->tag);  	} -      zebra_add_rnh_client(rnh, client, type, zvrf_id (zvrf)); -      /* Anything not AF_INET/INET6 has been filtered out above */ -      zebra_evaluate_rnh(zvrf_id (zvrf), p.family, 1, type, &p); -    } -  return 0; +	/* MTU */ +	SET_FLAG(zapi_flags, ZAPI_MESSAGE_MTU); +	stream_putl(s, rib->mtu); + +	/* write real message flags value */ +	stream_putc_at(s, messmark, zapi_flags); + +	/* Write next-hop number */ +	if (nhnummark) +		stream_putc_at(s, nhnummark, nhnum); + +	/* Write packet size. */ +	stream_putw_at(s, 0, stream_get_endp(s)); + +	return zebra_server_send_message(client); +} + +static int zsend_write_nexthop(struct stream *s, struct nexthop *nexthop) +{ +	stream_putc(s, nexthop->type); +	switch (nexthop->type) { +	case NEXTHOP_TYPE_IPV4: +	case NEXTHOP_TYPE_IPV4_IFINDEX: +		stream_put_in_addr(s, &nexthop->gate.ipv4); +		stream_putl(s, nexthop->ifindex); +		break; +	case NEXTHOP_TYPE_IPV6: +		stream_put(s, &nexthop->gate.ipv6, 16); +		break; +	case NEXTHOP_TYPE_IPV6_IFINDEX: +		stream_put(s, &nexthop->gate.ipv6, 16); +		stream_putl(s, nexthop->ifindex); +		break; +	case NEXTHOP_TYPE_IFINDEX: +		stream_putl(s, nexthop->ifindex); +		break; +	default: +		/* do nothing */ +		break; +	} +	return 1;  }  /* Nexthop register */ -static int -zserv_rnh_unregister (struct zserv *client, int sock, u_short length, -		      rnh_type_t type, struct zebra_vrf *zvrf) -{ -  struct rnh *rnh; -  struct stream *s; -  struct prefix p; -  u_short l = 0; - -  if (IS_ZEBRA_DEBUG_NHT) -    zlog_debug("rnh_unregister msg from client %s: length=%d\n", -	       zebra_route_string(client->proto), length); - -  s = client->ibuf; - -  while (l < length) -    { -      (void)stream_getc(s); //Connected or not.  Not used in this function -      p.family = stream_getw(s); -      p.prefixlen = stream_getc(s); -      l += 4; -      if (p.family == AF_INET) -	{ -	  p.u.prefix4.s_addr = stream_get_ipv4(s); -	  l += IPV4_MAX_BYTELEN; +static int zserv_rnh_register(struct zserv *client, int sock, u_short length, +			      rnh_type_t type, struct zebra_vrf *zvrf) +{ +	struct rnh *rnh; +	struct stream *s; +	struct prefix p; +	u_short l = 0; +	u_char flags = 0; + +	if (IS_ZEBRA_DEBUG_NHT) +		zlog_debug( +			"rnh_register msg from client %s: length=%d, type=%s\n", +			zebra_route_string(client->proto), length, +			(type == RNH_NEXTHOP_TYPE) ? "nexthop" : "route"); + +	s = client->ibuf; + +	client->nh_reg_time = monotime(NULL); + +	while (l < length) { +		flags = stream_getc(s); +		p.family = stream_getw(s); +		p.prefixlen = stream_getc(s); +		l += 4; +		if (p.family == AF_INET) { +			p.u.prefix4.s_addr = stream_get_ipv4(s); +			l += IPV4_MAX_BYTELEN; +		} else if (p.family == AF_INET6) { +			stream_get(&p.u.prefix6, s, IPV6_MAX_BYTELEN); +			l += IPV6_MAX_BYTELEN; +		} else { +			zlog_err( +				"rnh_register: Received unknown family type %d\n", +				p.family); +			return -1; +		} +		rnh = zebra_add_rnh(&p, zvrf_id(zvrf), type); +		if (type == RNH_NEXTHOP_TYPE) { +			if (flags +			    && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)) +				SET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED); +			else if (!flags +				 && CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)) +				UNSET_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED); +		} else if (type == RNH_IMPORT_CHECK_TYPE) { +			if (flags +			    && !CHECK_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH)) +				SET_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH); +			else if (!flags && CHECK_FLAG(rnh->flags, +						      ZEBRA_NHT_EXACT_MATCH)) +				UNSET_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH); +		} + +		zebra_add_rnh_client(rnh, client, type, zvrf_id(zvrf)); +		/* Anything not AF_INET/INET6 has been filtered out above */ +		zebra_evaluate_rnh(zvrf_id(zvrf), p.family, 1, type, &p);  	} -      else if (p.family == AF_INET6) -	{ -	  stream_get(&p.u.prefix6, s, IPV6_MAX_BYTELEN); -	  l += IPV6_MAX_BYTELEN; -	} -      else -	{ -	  zlog_err("rnh_register: Received unknown family type %d\n", -		   p.family); -	  return -1; -	} -      rnh = zebra_lookup_rnh(&p, zvrf_id (zvrf), type); -      if (rnh) -	{ -	  client->nh_dereg_time = monotime(NULL); -	  zebra_remove_rnh_client(rnh, client, type); +	return 0; +} + +/* Nexthop register */ +static int zserv_rnh_unregister(struct zserv *client, int sock, u_short length, +				rnh_type_t type, struct zebra_vrf *zvrf) +{ +	struct rnh *rnh; +	struct stream *s; +	struct prefix p; +	u_short l = 0; + +	if (IS_ZEBRA_DEBUG_NHT) +		zlog_debug("rnh_unregister msg from client %s: length=%d\n", +			   zebra_route_string(client->proto), length); + +	s = client->ibuf; + +	while (l < length) { +		(void)stream_getc( +			s); // Connected or not.  Not used in this function +		p.family = stream_getw(s); +		p.prefixlen = stream_getc(s); +		l += 4; +		if (p.family == AF_INET) { +			p.u.prefix4.s_addr = stream_get_ipv4(s); +			l += IPV4_MAX_BYTELEN; +		} else if (p.family == AF_INET6) { +			stream_get(&p.u.prefix6, s, IPV6_MAX_BYTELEN); +			l += IPV6_MAX_BYTELEN; +		} else { +			zlog_err( +				"rnh_register: Received unknown family type %d\n", +				p.family); +			return -1; +		} +		rnh = zebra_lookup_rnh(&p, zvrf_id(zvrf), type); +		if (rnh) { +			client->nh_dereg_time = monotime(NULL); +			zebra_remove_rnh_client(rnh, client, type); +		}  	} -    } -  return 0; +	return 0;  }  /* @@ -939,1571 +906,1541 @@ zserv_rnh_unregister (struct zserv *client, int sock, u_short length,    Query unicast rib if nexthop is not found on mrib.    Returns both route metric and protocol distance.  */ -static int -zsend_ipv4_nexthop_lookup_mrib (struct zserv *client, struct in_addr addr, struct rib *rib, struct zebra_vrf *zvrf) -{ -  struct stream *s; -  unsigned long nump; -  u_char num; -  struct nexthop *nexthop; - -  /* Get output stream. */ -  s = client->obuf; -  stream_reset (s); - -  /* Fill in result. */ -  zserv_create_header (s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, zvrf_id (zvrf)); -  stream_put_in_addr (s, &addr); - -  if (rib) -    { -      stream_putc (s, rib->distance); -      stream_putl (s, rib->metric); -      num = 0; -      nump = stream_get_endp(s); /* remember position for nexthop_num */ -      stream_putc (s, 0);        /* reserve room for nexthop_num */ -      /* Only non-recursive routes are elegible to resolve the nexthop we -       * are looking up. Therefore, we will just iterate over the top -       * chain of nexthops. */ -      for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) -	if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) -	    num += zsend_write_nexthop (s, nexthop); -     -      stream_putc_at (s, nump, num); /* store nexthop_num */ -    } -  else -    { -      stream_putc (s, 0); /* distance */ -      stream_putl (s, 0); /* metric */ -      stream_putc (s, 0); /* nexthop_num */ -    } - -  stream_putw_at (s, 0, stream_get_endp (s)); -   -  return zebra_server_send_message(client); +static int zsend_ipv4_nexthop_lookup_mrib(struct zserv *client, +					  struct in_addr addr, struct rib *rib, +					  struct zebra_vrf *zvrf) +{ +	struct stream *s; +	unsigned long nump; +	u_char num; +	struct nexthop *nexthop; + +	/* Get output stream. */ +	s = client->obuf; +	stream_reset(s); + +	/* Fill in result. */ +	zserv_create_header(s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, zvrf_id(zvrf)); +	stream_put_in_addr(s, &addr); + +	if (rib) { +		stream_putc(s, rib->distance); +		stream_putl(s, rib->metric); +		num = 0; +		nump = stream_get_endp( +			s);	/* remember position for nexthop_num */ +		stream_putc(s, 0); /* reserve room for nexthop_num */ +		/* Only non-recursive routes are elegible to resolve the nexthop +		 * we +		 * are looking up. Therefore, we will just iterate over the top +		 * chain of nexthops. */ +		for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next) +			if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) +				num += zsend_write_nexthop(s, nexthop); + +		stream_putc_at(s, nump, num); /* store nexthop_num */ +	} else { +		stream_putc(s, 0); /* distance */ +		stream_putl(s, 0); /* metric */ +		stream_putc(s, 0); /* nexthop_num */ +	} + +	stream_putw_at(s, 0, stream_get_endp(s)); + +	return zebra_server_send_message(client);  }  /* Router-id is updated. Send ZEBRA_ROUTER_ID_ADD to client. */ -int -zsend_router_id_update (struct zserv *client, struct prefix *p, -    vrf_id_t vrf_id) +int zsend_router_id_update(struct zserv *client, struct prefix *p, +			   vrf_id_t vrf_id)  { -  struct stream *s; -  int blen; +	struct stream *s; +	int blen; -  /* Check this client need interface information. */ -  if (! vrf_bitmap_check (client->ridinfo, vrf_id)) -    return 0; +	/* Check this client need interface information. */ +	if (!vrf_bitmap_check(client->ridinfo, vrf_id)) +		return 0; -  s = client->obuf; -  stream_reset (s); +	s = client->obuf; +	stream_reset(s); -  /* Message type. */ -  zserv_create_header (s, ZEBRA_ROUTER_ID_UPDATE, vrf_id); +	/* Message type. */ +	zserv_create_header(s, ZEBRA_ROUTER_ID_UPDATE, vrf_id); -  /* Prefix information. */ -  stream_putc (s, p->family); -  blen = prefix_blen (p); -  stream_put (s, &p->u.prefix, blen); -  stream_putc (s, p->prefixlen); +	/* Prefix information. */ +	stream_putc(s, p->family); +	blen = prefix_blen(p); +	stream_put(s, &p->u.prefix, blen); +	stream_putc(s, p->prefixlen); -  /* Write packet size. */ -  stream_putw_at (s, 0, stream_get_endp (s)); +	/* Write packet size. */ +	stream_putw_at(s, 0, stream_get_endp(s)); -  return zebra_server_send_message(client); +	return zebra_server_send_message(client);  }  /*   * Function used by Zebra to send a PW status update to LDP daemon   */ -int -zsend_pw_update (struct zserv *client, struct zebra_pw *pw) +int zsend_pw_update(struct zserv *client, struct zebra_pw *pw)  { -  struct stream *s; +	struct stream *s; -  s = client->obuf; -  stream_reset (s); +	s = client->obuf; +	stream_reset(s); -  zserv_create_header (s, ZEBRA_PW_STATUS_UPDATE, pw->vrf_id); -  stream_write (s, pw->ifname, IF_NAMESIZE); -  stream_putl (s, pw->ifindex); -  stream_putl (s, pw->status); +	zserv_create_header(s, ZEBRA_PW_STATUS_UPDATE, pw->vrf_id); +	stream_write(s, pw->ifname, IF_NAMESIZE); +	stream_putl(s, pw->ifindex); +	stream_putl(s, pw->status); -  /* Put length at the first point of the stream. */ -  stream_putw_at (s, 0, stream_get_endp (s)); +	/* Put length at the first point of the stream. */ +	stream_putw_at(s, 0, stream_get_endp(s)); -  return zebra_server_send_message (client); +	return zebra_server_send_message(client);  }  /* Register zebra server interface information.  Send current all     interface and address information. */ -static int -zread_interface_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf) +static int zread_interface_add(struct zserv *client, u_short length, +			       struct zebra_vrf *zvrf)  { -  struct vrf *vrf; -  struct listnode *ifnode, *ifnnode; -  struct interface *ifp; +	struct vrf *vrf; +	struct listnode *ifnode, *ifnnode; +	struct interface *ifp; -  /* Interface information is needed. */ -  vrf_bitmap_set (client->ifinfo, zvrf_id (zvrf)); +	/* Interface information is needed. */ +	vrf_bitmap_set(client->ifinfo, zvrf_id(zvrf)); -  RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) -    { -      for (ALL_LIST_ELEMENTS (vrf->iflist, ifnode, ifnnode, ifp)) -        { -          /* Skip pseudo interface. */ -          if (! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE)) -	    continue; +	RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id) +	{ +		for (ALL_LIST_ELEMENTS(vrf->iflist, ifnode, ifnnode, ifp)) { +			/* Skip pseudo interface. */ +			if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) +				continue; -          if (zsend_interface_add (client, ifp) < 0) -            return -1; +			if (zsend_interface_add(client, ifp) < 0) +				return -1; -          if (zsend_interface_addresses (client, ifp) < 0) -            return -1; -        } -    } -  return 0; +			if (zsend_interface_addresses(client, ifp) < 0) +				return -1; +		} +	} +	return 0;  }  /* Unregister zebra server interface information. */ -static int -zread_interface_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf) +static int zread_interface_delete(struct zserv *client, u_short length, +				  struct zebra_vrf *zvrf)  { -  vrf_bitmap_unset (client->ifinfo, zvrf_id (zvrf)); -  return 0; +	vrf_bitmap_unset(client->ifinfo, zvrf_id(zvrf)); +	return 0;  } -void -zserv_nexthop_num_warn (const char *caller, const struct prefix *p, const unsigned int nexthop_num) +void zserv_nexthop_num_warn(const char *caller, const struct prefix *p, +			    const unsigned int nexthop_num)  { -  if (nexthop_num > multipath_num) -    { -      char buff[PREFIX2STR_BUFFER]; -      prefix2str(p, buff, sizeof (buff)); -      zlog_warn("%s: Prefix %s has %d nexthops, but we can only use the first %d", -		caller, buff, nexthop_num, multipath_num); -    } +	if (nexthop_num > multipath_num) { +		char buff[PREFIX2STR_BUFFER]; +		prefix2str(p, buff, sizeof(buff)); +		zlog_warn( +			"%s: Prefix %s has %d nexthops, but we can only use the first %d", +			caller, buff, nexthop_num, multipath_num); +	}  }  /* This function support multiple nexthop. */ -/*  +/*   * Parse the ZEBRA_IPV4_ROUTE_ADD sent from client. Update rib and - * add kernel route.  + * add kernel route.   */ -static int -zread_ipv4_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf) -{ -  int i; -  struct rib *rib; -  struct prefix p; -  u_char message; -  struct in_addr nexthop; -  u_char nexthop_num; -  u_char nexthop_type; -  struct stream *s; -  ifindex_t ifindex; -  safi_t safi; -  int ret; - -  /* Get input stream.  */ -  s = client->ibuf; - -  /* Allocate new rib. */ -  rib = XCALLOC (MTYPE_RIB, sizeof (struct rib)); -   -  /* Type, flags, message. */ -  rib->type = stream_getc (s); -  rib->instance = stream_getw (s); -  rib->flags = stream_getl (s); -  message = stream_getc (s);  -  safi = stream_getw (s); -  rib->uptime = time (NULL); - -  /* IPv4 prefix. */ -  memset (&p, 0, sizeof (struct prefix_ipv4)); -  p.family = AF_INET; -  p.prefixlen = stream_getc (s); -  stream_get (&p.u.prefix4, s, PSIZE (p.prefixlen)); - -  /* VRF ID */ -  rib->vrf_id = zvrf_id (zvrf); - -  /* Nexthop parse. */ -  if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP)) -    { -      nexthop_num = stream_getc (s); -      zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, nexthop_num); - -      for (i = 0; i < nexthop_num; i++) -	{ -	  nexthop_type = stream_getc (s); - -	  switch (nexthop_type) -	    { -	    case NEXTHOP_TYPE_IFINDEX: -	      ifindex = stream_getl (s); -	      rib_nexthop_ifindex_add (rib, ifindex); -	      break; -	    case NEXTHOP_TYPE_IPV4: -	      nexthop.s_addr = stream_get_ipv4 (s); -	      rib_nexthop_ipv4_add (rib, &nexthop, NULL); -	      break; -	    case NEXTHOP_TYPE_IPV4_IFINDEX: -	      nexthop.s_addr = stream_get_ipv4 (s); -	      ifindex = stream_getl (s); -	      rib_nexthop_ipv4_ifindex_add (rib, &nexthop, NULL, ifindex); -	      break; -	    case NEXTHOP_TYPE_IPV6: -	      stream_forward_getp (s, IPV6_MAX_BYTELEN); -	      break; -            case NEXTHOP_TYPE_BLACKHOLE: -              rib_nexthop_blackhole_add (rib); -              break; -            } +static int zread_ipv4_add(struct zserv *client, u_short length, +			  struct zebra_vrf *zvrf) +{ +	int i; +	struct rib *rib; +	struct prefix p; +	u_char message; +	struct in_addr nexthop; +	u_char nexthop_num; +	u_char nexthop_type; +	struct stream *s; +	ifindex_t ifindex; +	safi_t safi; +	int ret; + +	/* Get input stream.  */ +	s = client->ibuf; + +	/* Allocate new rib. */ +	rib = XCALLOC(MTYPE_RIB, sizeof(struct rib)); + +	/* Type, flags, message. */ +	rib->type = stream_getc(s); +	rib->instance = stream_getw(s); +	rib->flags = stream_getl(s); +	message = stream_getc(s); +	safi = stream_getw(s); +	rib->uptime = time(NULL); + +	/* IPv4 prefix. */ +	memset(&p, 0, sizeof(struct prefix_ipv4)); +	p.family = AF_INET; +	p.prefixlen = stream_getc(s); +	stream_get(&p.u.prefix4, s, PSIZE(p.prefixlen)); + +	/* VRF ID */ +	rib->vrf_id = zvrf_id(zvrf); + +	/* Nexthop parse. */ +	if (CHECK_FLAG(message, ZAPI_MESSAGE_NEXTHOP)) { +		nexthop_num = stream_getc(s); +		zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, +				       nexthop_num); + +		for (i = 0; i < nexthop_num; i++) { +			nexthop_type = stream_getc(s); + +			switch (nexthop_type) { +			case NEXTHOP_TYPE_IFINDEX: +				ifindex = stream_getl(s); +				rib_nexthop_ifindex_add(rib, ifindex); +				break; +			case NEXTHOP_TYPE_IPV4: +				nexthop.s_addr = stream_get_ipv4(s); +				rib_nexthop_ipv4_add(rib, &nexthop, NULL); +				break; +			case NEXTHOP_TYPE_IPV4_IFINDEX: +				nexthop.s_addr = stream_get_ipv4(s); +				ifindex = stream_getl(s); +				rib_nexthop_ipv4_ifindex_add(rib, &nexthop, +							     NULL, ifindex); +				break; +			case NEXTHOP_TYPE_IPV6: +				stream_forward_getp(s, IPV6_MAX_BYTELEN); +				break; +			case NEXTHOP_TYPE_BLACKHOLE: +				rib_nexthop_blackhole_add(rib); +				break; +			} +		}  	} -    } -  /* Distance. */ -  if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE)) -    rib->distance = stream_getc (s); +	/* Distance. */ +	if (CHECK_FLAG(message, ZAPI_MESSAGE_DISTANCE)) +		rib->distance = stream_getc(s); + +	/* Metric. */ +	if (CHECK_FLAG(message, ZAPI_MESSAGE_METRIC)) +		rib->metric = stream_getl(s); -  /* Metric. */ -  if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC)) -    rib->metric = stream_getl (s); -     -  /* Tag */ -  if (CHECK_FLAG (message, ZAPI_MESSAGE_TAG)) -    rib->tag = stream_getl (s); -  else -    rib->tag = 0; +	/* Tag */ +	if (CHECK_FLAG(message, ZAPI_MESSAGE_TAG)) +		rib->tag = stream_getl(s); +	else +		rib->tag = 0; -  if (CHECK_FLAG (message, ZAPI_MESSAGE_MTU)) -    rib->mtu = stream_getl (s); -  else -    rib->mtu = 0; +	if (CHECK_FLAG(message, ZAPI_MESSAGE_MTU)) +		rib->mtu = stream_getl(s); +	else +		rib->mtu = 0; -  /* Table */ -  rib->table = zvrf->table_id; +	/* Table */ +	rib->table = zvrf->table_id; -  ret = rib_add_multipath (AFI_IP, safi, &p, NULL, rib); +	ret = rib_add_multipath(AFI_IP, safi, &p, NULL, rib); -  /* Stats */ -  if (ret > 0) -    client->v4_route_add_cnt++; -  else if (ret < 0) -    client->v4_route_upd8_cnt++; -  return 0; +	/* Stats */ +	if (ret > 0) +		client->v4_route_add_cnt++; +	else if (ret < 0) +		client->v4_route_upd8_cnt++; +	return 0;  }  /* Zebra server IPv4 prefix delete function. */ -static int -zread_ipv4_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf) -{ -  int i; -  struct stream *s; -  struct zapi_ipv4 api; -  struct in_addr nexthop; -  union g_addr *nexthop_p; -  unsigned long ifindex; -  struct prefix p; -  u_char nexthop_num; -  u_char nexthop_type; -  u_int32_t table_id; - -  s = client->ibuf; -  ifindex = 0; -  nexthop.s_addr = 0; -  nexthop_p = NULL; - -  /* Type, flags, message. */ -  api.type = stream_getc (s); -  api.instance = stream_getw (s); -  api.flags = stream_getl (s); -  api.message = stream_getc (s); -  api.safi = stream_getw (s); - -  /* IPv4 prefix. */ -  memset (&p, 0, sizeof (struct prefix)); -  p.family = AF_INET; -  p.prefixlen = stream_getc (s); -  stream_get (&p.u.prefix4, s, PSIZE (p.prefixlen)); - -  /* Nexthop, ifindex, distance, metric. */ -  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) -    { -      nexthop_num = stream_getc (s); - -      for (i = 0; i < nexthop_num; i++) -	{ -	  nexthop_type = stream_getc (s); - -	  switch (nexthop_type) -	    { -	    case NEXTHOP_TYPE_IFINDEX: -	      ifindex = stream_getl (s); -	      break; -	    case NEXTHOP_TYPE_IPV4: -	      nexthop.s_addr = stream_get_ipv4 (s); -	      nexthop_p = (union g_addr *)&nexthop; -	      break; -	    case NEXTHOP_TYPE_IPV4_IFINDEX: -	      nexthop.s_addr = stream_get_ipv4 (s); -	      nexthop_p = (union g_addr *)&nexthop; -	      ifindex = stream_getl (s); -	      break; -	    case NEXTHOP_TYPE_IPV6: -	      stream_forward_getp (s, IPV6_MAX_BYTELEN); -	      break; -	    } +static int zread_ipv4_delete(struct zserv *client, u_short length, +			     struct zebra_vrf *zvrf) +{ +	int i; +	struct stream *s; +	struct zapi_ipv4 api; +	struct in_addr nexthop; +	union g_addr *nexthop_p; +	unsigned long ifindex; +	struct prefix p; +	u_char nexthop_num; +	u_char nexthop_type; +	u_int32_t table_id; + +	s = client->ibuf; +	ifindex = 0; +	nexthop.s_addr = 0; +	nexthop_p = NULL; + +	/* Type, flags, message. */ +	api.type = stream_getc(s); +	api.instance = stream_getw(s); +	api.flags = stream_getl(s); +	api.message = stream_getc(s); +	api.safi = stream_getw(s); + +	/* IPv4 prefix. */ +	memset(&p, 0, sizeof(struct prefix)); +	p.family = AF_INET; +	p.prefixlen = stream_getc(s); +	stream_get(&p.u.prefix4, s, PSIZE(p.prefixlen)); + +	/* Nexthop, ifindex, distance, metric. */ +	if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { +		nexthop_num = stream_getc(s); + +		for (i = 0; i < nexthop_num; i++) { +			nexthop_type = stream_getc(s); + +			switch (nexthop_type) { +			case NEXTHOP_TYPE_IFINDEX: +				ifindex = stream_getl(s); +				break; +			case NEXTHOP_TYPE_IPV4: +				nexthop.s_addr = stream_get_ipv4(s); +				nexthop_p = (union g_addr *)&nexthop; +				break; +			case NEXTHOP_TYPE_IPV4_IFINDEX: +				nexthop.s_addr = stream_get_ipv4(s); +				nexthop_p = (union g_addr *)&nexthop; +				ifindex = stream_getl(s); +				break; +			case NEXTHOP_TYPE_IPV6: +				stream_forward_getp(s, IPV6_MAX_BYTELEN); +				break; +			} +		}  	} -    } - -  /* Distance. */ -  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE)) -    api.distance = stream_getc (s); -  else -    api.distance = 0; - -  /* Metric. */ -  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC)) -    api.metric = stream_getl (s); -  else -    api.metric = 0; -     -  /* tag */ -  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG)) -    api.tag = stream_getl (s); -  else -    api.tag = 0; - -  table_id = zvrf->table_id; - -  rib_delete (AFI_IP, api.safi, zvrf_id (zvrf), api.type, api.instance, -	      api.flags, &p, NULL, nexthop_p, ifindex, table_id); -  client->v4_route_del_cnt++; -  return 0; + +	/* Distance. */ +	if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE)) +		api.distance = stream_getc(s); +	else +		api.distance = 0; + +	/* Metric. */ +	if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC)) +		api.metric = stream_getl(s); +	else +		api.metric = 0; + +	/* tag */ +	if (CHECK_FLAG(api.message, ZAPI_MESSAGE_TAG)) +		api.tag = stream_getl(s); +	else +		api.tag = 0; + +	table_id = zvrf->table_id; + +	rib_delete(AFI_IP, api.safi, zvrf_id(zvrf), api.type, api.instance, +		   api.flags, &p, NULL, nexthop_p, ifindex, table_id); +	client->v4_route_del_cnt++; +	return 0;  }  /* MRIB Nexthop lookup for IPv4. */ -static int -zread_ipv4_nexthop_lookup_mrib (struct zserv *client, u_short length, struct zebra_vrf *zvrf) +static int zread_ipv4_nexthop_lookup_mrib(struct zserv *client, u_short length, +					  struct zebra_vrf *zvrf)  { -  struct in_addr addr; -  struct rib *rib; +	struct in_addr addr; +	struct rib *rib; -  addr.s_addr = stream_get_ipv4 (client->ibuf); -  rib = rib_match_ipv4_multicast (zvrf_id (zvrf), addr, NULL); -  return zsend_ipv4_nexthop_lookup_mrib (client, addr, rib, zvrf); +	addr.s_addr = stream_get_ipv4(client->ibuf); +	rib = rib_match_ipv4_multicast(zvrf_id(zvrf), addr, NULL); +	return zsend_ipv4_nexthop_lookup_mrib(client, addr, rib, zvrf);  }  /* Zebra server IPv6 prefix add function. */ -static int -zread_ipv4_route_ipv6_nexthop_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf) -{ -  unsigned int i; -  struct stream *s; -  struct in6_addr nexthop; -  struct rib *rib; -  u_char message; -  u_char nexthop_num; -  u_char nexthop_type; -  struct prefix p; -  safi_t safi; -  static struct in6_addr nexthops[MULTIPATH_NUM]; -  static unsigned int ifindices[MULTIPATH_NUM]; -  int ret; - -  /* Get input stream.  */ -  s = client->ibuf; - -  memset (&nexthop, 0, sizeof (struct in6_addr)); - -  /* Allocate new rib. */ -  rib = XCALLOC (MTYPE_RIB, sizeof (struct rib)); - -  /* Type, flags, message. */ -  rib->type = stream_getc (s); -  rib->instance = stream_getw (s); -  rib->flags = stream_getl (s); -  message = stream_getc (s); -  safi = stream_getw (s); -  rib->uptime = time (NULL); - -  /* IPv4 prefix. */ -  memset (&p, 0, sizeof (struct prefix_ipv4)); -  p.family = AF_INET; -  p.prefixlen = stream_getc (s); -  stream_get (&p.u.prefix4, s, PSIZE (p.prefixlen)); - -  /* VRF ID */ -  rib->vrf_id = zvrf_id (zvrf); - -  /* We need to give nh-addr, nh-ifindex with the same next-hop object -   * to the rib to ensure that IPv6 multipathing works; need to coalesce -   * these. Clients should send the same number of paired set of -   * next-hop-addr/next-hop-ifindices. */ -  if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP)) -    { -      unsigned int nh_count = 0; -      unsigned int if_count = 0; -      unsigned int max_nh_if = 0; - -      nexthop_num = stream_getc (s); -      zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, nexthop_num); -      for (i = 0; i < nexthop_num; i++) -	{ -	  nexthop_type = stream_getc (s); - -	  switch (nexthop_type) -	    { -	    case NEXTHOP_TYPE_IPV6: -	      stream_get (&nexthop, s, 16); -              if (nh_count < multipath_num) { -	        nexthops[nh_count++] = nexthop; -              } -	      break; -	    case NEXTHOP_TYPE_IFINDEX: -              if (if_count < multipath_num) { -	        ifindices[if_count++] = stream_getl (s); -              } -	      break; -            case NEXTHOP_TYPE_BLACKHOLE: -              rib_nexthop_blackhole_add (rib); -              break; -	    } +static int zread_ipv4_route_ipv6_nexthop_add(struct zserv *client, +					     u_short length, +					     struct zebra_vrf *zvrf) +{ +	unsigned int i; +	struct stream *s; +	struct in6_addr nexthop; +	struct rib *rib; +	u_char message; +	u_char nexthop_num; +	u_char nexthop_type; +	struct prefix p; +	safi_t safi; +	static struct in6_addr nexthops[MULTIPATH_NUM]; +	static unsigned int ifindices[MULTIPATH_NUM]; +	int ret; + +	/* Get input stream.  */ +	s = client->ibuf; + +	memset(&nexthop, 0, sizeof(struct in6_addr)); + +	/* Allocate new rib. */ +	rib = XCALLOC(MTYPE_RIB, sizeof(struct rib)); + +	/* Type, flags, message. */ +	rib->type = stream_getc(s); +	rib->instance = stream_getw(s); +	rib->flags = stream_getl(s); +	message = stream_getc(s); +	safi = stream_getw(s); +	rib->uptime = time(NULL); + +	/* IPv4 prefix. */ +	memset(&p, 0, sizeof(struct prefix_ipv4)); +	p.family = AF_INET; +	p.prefixlen = stream_getc(s); +	stream_get(&p.u.prefix4, s, PSIZE(p.prefixlen)); + +	/* VRF ID */ +	rib->vrf_id = zvrf_id(zvrf); + +	/* We need to give nh-addr, nh-ifindex with the same next-hop object +	 * to the rib to ensure that IPv6 multipathing works; need to coalesce +	 * these. Clients should send the same number of paired set of +	 * next-hop-addr/next-hop-ifindices. */ +	if (CHECK_FLAG(message, ZAPI_MESSAGE_NEXTHOP)) { +		unsigned int nh_count = 0; +		unsigned int if_count = 0; +		unsigned int max_nh_if = 0; + +		nexthop_num = stream_getc(s); +		zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, +				       nexthop_num); +		for (i = 0; i < nexthop_num; i++) { +			nexthop_type = stream_getc(s); + +			switch (nexthop_type) { +			case NEXTHOP_TYPE_IPV6: +				stream_get(&nexthop, s, 16); +				if (nh_count < multipath_num) { +					nexthops[nh_count++] = nexthop; +				} +				break; +			case NEXTHOP_TYPE_IFINDEX: +				if (if_count < multipath_num) { +					ifindices[if_count++] = stream_getl(s); +				} +				break; +			case NEXTHOP_TYPE_BLACKHOLE: +				rib_nexthop_blackhole_add(rib); +				break; +			} +		} + +		max_nh_if = (nh_count > if_count) ? nh_count : if_count; +		for (i = 0; i < max_nh_if; i++) { +			if ((i < nh_count) +			    && !IN6_IS_ADDR_UNSPECIFIED(&nexthops[i])) { +				if ((i < if_count) && ifindices[i]) { +					rib_nexthop_ipv6_ifindex_add( +						rib, &nexthops[i], +						ifindices[i]); +				} else { +					rib_nexthop_ipv6_add(rib, &nexthops[i]); +				} +			} else { +				if ((i < if_count) && ifindices[i]) { +					rib_nexthop_ifindex_add(rib, +								ifindices[i]); +				} +			} +		}  	} -      max_nh_if = (nh_count > if_count) ? nh_count : if_count; -      for (i = 0; i < max_nh_if; i++) -        { -	  if ((i < nh_count) && !IN6_IS_ADDR_UNSPECIFIED (&nexthops[i])) { -            if ((i < if_count) && ifindices[i]) { -              rib_nexthop_ipv6_ifindex_add (rib, &nexthops[i], ifindices[i]); -            } -            else { -	      rib_nexthop_ipv6_add (rib, &nexthops[i]); -            } -          } -          else { -            if ((i < if_count) && ifindices[i]) { -	      rib_nexthop_ifindex_add (rib, ifindices[i]); -	    } -          } -	} -    } - -  /* Distance. */ -  if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE)) -    rib->distance = stream_getc (s); - -  /* Metric. */ -  if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC)) -    rib->metric = stream_getl (s); - -  /* Tag */ -  if (CHECK_FLAG (message, ZAPI_MESSAGE_TAG)) -    rib->tag = stream_getl (s); -  else -    rib->tag = 0; - -  if (CHECK_FLAG (message, ZAPI_MESSAGE_MTU)) -    rib->mtu = stream_getl (s); -  else -    rib->mtu = 0; - -  /* Table */ -  rib->table = zvrf->table_id; - -  ret = rib_add_multipath (AFI_IP6, safi, &p, NULL, rib); -  /* Stats */ -  if (ret > 0) -    client->v4_route_add_cnt++; -  else if (ret < 0) -    client->v4_route_upd8_cnt++; - -  return 0; -} - -static int -zread_ipv6_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf) -{ -  unsigned int i; -  struct stream *s; -  struct in6_addr nexthop; -  struct rib *rib; -  u_char message; -  u_char nexthop_num; -  u_char nexthop_type; -  struct prefix p; -  struct prefix_ipv6 src_p, *src_pp; -  safi_t safi; -  static struct in6_addr nexthops[MULTIPATH_NUM]; -  static unsigned int ifindices[MULTIPATH_NUM]; -  int ret; - -  /* Get input stream.  */ -  s = client->ibuf; - -  memset (&nexthop, 0, sizeof (struct in6_addr)); - -  /* Allocate new rib. */ -  rib = XCALLOC (MTYPE_RIB, sizeof (struct rib)); - -  /* Type, flags, message. */ -  rib->type = stream_getc (s); -  rib->instance = stream_getw (s); -  rib->flags = stream_getl (s); -  message = stream_getc (s); -  safi = stream_getw (s); -  rib->uptime = time (NULL); - -  /* IPv6 prefix. */ -  memset (&p, 0, sizeof (struct prefix_ipv6)); -  p.family = AF_INET6; -  p.prefixlen = stream_getc (s); -  stream_get (&p.u.prefix6, s, PSIZE (p.prefixlen)); - -  if (CHECK_FLAG (message, ZAPI_MESSAGE_SRCPFX)) -    { -      memset (&src_p, 0, sizeof (struct prefix_ipv6)); -      src_p.family = AF_INET6; -      src_p.prefixlen = stream_getc (s); -      stream_get (&src_p.prefix, s, PSIZE (src_p.prefixlen)); -      src_pp = &src_p; -    } -  else -    src_pp = NULL; - -  /* We need to give nh-addr, nh-ifindex with the same next-hop object -   * to the rib to ensure that IPv6 multipathing works; need to coalesce -   * these. Clients should send the same number of paired set of -   * next-hop-addr/next-hop-ifindices. */ -  if (CHECK_FLAG (message, ZAPI_MESSAGE_NEXTHOP)) -    { -      unsigned int nh_count = 0; -      unsigned int if_count = 0; -      unsigned int max_nh_if = 0; - -      nexthop_num = stream_getc (s); -      zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, nexthop_num); -      for (i = 0; i < nexthop_num; i++)  -	{ -	  nexthop_type = stream_getc (s); - -	  switch (nexthop_type) -	    { -	    case NEXTHOP_TYPE_IPV6: -	      stream_get (&nexthop, s, 16); -              if (nh_count < multipath_num) { -	        nexthops[nh_count++] = nexthop; -              } -	      break; -	    case NEXTHOP_TYPE_IFINDEX: -              if (if_count < multipath_num) { -	        ifindices[if_count++] = stream_getl (s); -              } -	      break; -            case NEXTHOP_TYPE_BLACKHOLE: -              rib_nexthop_blackhole_add (rib); -              break; -	    } +	/* Distance. */ +	if (CHECK_FLAG(message, ZAPI_MESSAGE_DISTANCE)) +		rib->distance = stream_getc(s); + +	/* Metric. */ +	if (CHECK_FLAG(message, ZAPI_MESSAGE_METRIC)) +		rib->metric = stream_getl(s); + +	/* Tag */ +	if (CHECK_FLAG(message, ZAPI_MESSAGE_TAG)) +		rib->tag = stream_getl(s); +	else +		rib->tag = 0; + +	if (CHECK_FLAG(message, ZAPI_MESSAGE_MTU)) +		rib->mtu = stream_getl(s); +	else +		rib->mtu = 0; + +	/* Table */ +	rib->table = zvrf->table_id; + +	ret = rib_add_multipath(AFI_IP6, safi, &p, NULL, rib); +	/* Stats */ +	if (ret > 0) +		client->v4_route_add_cnt++; +	else if (ret < 0) +		client->v4_route_upd8_cnt++; + +	return 0; +} + +static int zread_ipv6_add(struct zserv *client, u_short length, +			  struct zebra_vrf *zvrf) +{ +	unsigned int i; +	struct stream *s; +	struct in6_addr nexthop; +	struct rib *rib; +	u_char message; +	u_char nexthop_num; +	u_char nexthop_type; +	struct prefix p; +	struct prefix_ipv6 src_p, *src_pp; +	safi_t safi; +	static struct in6_addr nexthops[MULTIPATH_NUM]; +	static unsigned int ifindices[MULTIPATH_NUM]; +	int ret; + +	/* Get input stream.  */ +	s = client->ibuf; + +	memset(&nexthop, 0, sizeof(struct in6_addr)); + +	/* Allocate new rib. */ +	rib = XCALLOC(MTYPE_RIB, sizeof(struct rib)); + +	/* Type, flags, message. */ +	rib->type = stream_getc(s); +	rib->instance = stream_getw(s); +	rib->flags = stream_getl(s); +	message = stream_getc(s); +	safi = stream_getw(s); +	rib->uptime = time(NULL); + +	/* IPv6 prefix. */ +	memset(&p, 0, sizeof(struct prefix_ipv6)); +	p.family = AF_INET6; +	p.prefixlen = stream_getc(s); +	stream_get(&p.u.prefix6, s, PSIZE(p.prefixlen)); + +	if (CHECK_FLAG(message, ZAPI_MESSAGE_SRCPFX)) { +		memset(&src_p, 0, sizeof(struct prefix_ipv6)); +		src_p.family = AF_INET6; +		src_p.prefixlen = stream_getc(s); +		stream_get(&src_p.prefix, s, PSIZE(src_p.prefixlen)); +		src_pp = &src_p; +	} else +		src_pp = NULL; + +	/* We need to give nh-addr, nh-ifindex with the same next-hop object +	 * to the rib to ensure that IPv6 multipathing works; need to coalesce +	 * these. Clients should send the same number of paired set of +	 * next-hop-addr/next-hop-ifindices. */ +	if (CHECK_FLAG(message, ZAPI_MESSAGE_NEXTHOP)) { +		unsigned int nh_count = 0; +		unsigned int if_count = 0; +		unsigned int max_nh_if = 0; + +		nexthop_num = stream_getc(s); +		zserv_nexthop_num_warn(__func__, (const struct prefix *)&p, +				       nexthop_num); +		for (i = 0; i < nexthop_num; i++) { +			nexthop_type = stream_getc(s); + +			switch (nexthop_type) { +			case NEXTHOP_TYPE_IPV6: +				stream_get(&nexthop, s, 16); +				if (nh_count < multipath_num) { +					nexthops[nh_count++] = nexthop; +				} +				break; +			case NEXTHOP_TYPE_IFINDEX: +				if (if_count < multipath_num) { +					ifindices[if_count++] = stream_getl(s); +				} +				break; +			case NEXTHOP_TYPE_BLACKHOLE: +				rib_nexthop_blackhole_add(rib); +				break; +			} +		} + +		max_nh_if = (nh_count > if_count) ? nh_count : if_count; +		for (i = 0; i < max_nh_if; i++) { +			if ((i < nh_count) +			    && !IN6_IS_ADDR_UNSPECIFIED(&nexthops[i])) { +				if ((i < if_count) && ifindices[i]) +					rib_nexthop_ipv6_ifindex_add( +						rib, &nexthops[i], +						ifindices[i]); +				else +					rib_nexthop_ipv6_add(rib, &nexthops[i]); +			} else { +				if ((i < if_count) && ifindices[i]) +					rib_nexthop_ifindex_add(rib, +								ifindices[i]); +			} +		}  	} -      max_nh_if = (nh_count > if_count) ? nh_count : if_count; -      for (i = 0; i < max_nh_if; i++) -        { -	  if ((i < nh_count) && !IN6_IS_ADDR_UNSPECIFIED (&nexthops[i])) { -            if ((i < if_count) && ifindices[i]) -              rib_nexthop_ipv6_ifindex_add (rib, &nexthops[i], ifindices[i]); -            else -	      rib_nexthop_ipv6_add (rib, &nexthops[i]); -          } -          else { -            if ((i < if_count) && ifindices[i]) -	      rib_nexthop_ifindex_add (rib, ifindices[i]); -          } -	} -    } +	/* Distance. */ +	if (CHECK_FLAG(message, ZAPI_MESSAGE_DISTANCE)) +		rib->distance = stream_getc(s); -  /* Distance. */ -  if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE)) -    rib->distance = stream_getc (s); +	/* Metric. */ +	if (CHECK_FLAG(message, ZAPI_MESSAGE_METRIC)) +		rib->metric = stream_getl(s); -  /* Metric. */ -  if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC)) -    rib->metric = stream_getl (s); -     -  /* Tag */ -  if (CHECK_FLAG (message, ZAPI_MESSAGE_TAG)) -    rib->tag = stream_getl (s); -  else -    rib->tag = 0; +	/* Tag */ +	if (CHECK_FLAG(message, ZAPI_MESSAGE_TAG)) +		rib->tag = stream_getl(s); +	else +		rib->tag = 0; -  if (CHECK_FLAG (message, ZAPI_MESSAGE_MTU)) -    rib->mtu = stream_getl (s); -  else -    rib->mtu = 0; +	if (CHECK_FLAG(message, ZAPI_MESSAGE_MTU)) +		rib->mtu = stream_getl(s); +	else +		rib->mtu = 0; -  /* VRF ID */ -  rib->vrf_id = zvrf_id (zvrf); -  rib->table = zvrf->table_id; +	/* VRF ID */ +	rib->vrf_id = zvrf_id(zvrf); +	rib->table = zvrf->table_id; -  ret = rib_add_multipath (AFI_IP6, safi, &p, src_pp, rib); -  /* Stats */ -  if (ret > 0) -    client->v6_route_add_cnt++; -  else if (ret < 0) -    client->v6_route_upd8_cnt++; +	ret = rib_add_multipath(AFI_IP6, safi, &p, src_pp, rib); +	/* Stats */ +	if (ret > 0) +		client->v6_route_add_cnt++; +	else if (ret < 0) +		client->v6_route_upd8_cnt++; -  return 0; +	return 0;  }  /* Zebra server IPv6 prefix delete function. */ -static int -zread_ipv6_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf) -{ -  int i; -  struct stream *s; -  struct zapi_ipv6 api; -  struct in6_addr nexthop; -  union g_addr *pnexthop = NULL; -  unsigned long ifindex; -  struct prefix p; -  struct prefix_ipv6 src_p, *src_pp; -   -  s = client->ibuf; -  ifindex = 0; -  memset (&nexthop, 0, sizeof (struct in6_addr)); - -  /* Type, flags, message. */ -  api.type = stream_getc (s); -  api.instance = stream_getw (s); -  api.flags = stream_getl (s); -  api.message = stream_getc (s); -  api.safi = stream_getw (s); - -  /* IPv4 prefix. */ -  memset (&p, 0, sizeof (struct prefix_ipv6)); -  p.family = AF_INET6; -  p.prefixlen = stream_getc (s); -  stream_get (&p.u.prefix6, s, PSIZE (p.prefixlen)); - -  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_SRCPFX)) -    { -      memset (&src_p, 0, sizeof (struct prefix_ipv6)); -      src_p.family = AF_INET6; -      src_p.prefixlen = stream_getc (s); -      stream_get (&src_p.prefix, s, PSIZE (src_p.prefixlen)); -      src_pp = &src_p; -    } -  else -    src_pp = NULL; - -  /* Nexthop, ifindex, distance, metric. */ -  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) -    { -      u_char nexthop_type; - -      api.nexthop_num = stream_getc (s); -      for (i = 0; i < api.nexthop_num; i++) -	{ -	  nexthop_type = stream_getc (s); - -	  switch (nexthop_type) -	    { -	    case NEXTHOP_TYPE_IPV6: -	      stream_get (&nexthop, s, 16); -	      pnexthop = (union g_addr *)&nexthop; -	      break; -	    case NEXTHOP_TYPE_IFINDEX: -	      ifindex = stream_getl (s); -	      break; -	    } +static int zread_ipv6_delete(struct zserv *client, u_short length, +			     struct zebra_vrf *zvrf) +{ +	int i; +	struct stream *s; +	struct zapi_ipv6 api; +	struct in6_addr nexthop; +	union g_addr *pnexthop = NULL; +	unsigned long ifindex; +	struct prefix p; +	struct prefix_ipv6 src_p, *src_pp; + +	s = client->ibuf; +	ifindex = 0; +	memset(&nexthop, 0, sizeof(struct in6_addr)); + +	/* Type, flags, message. */ +	api.type = stream_getc(s); +	api.instance = stream_getw(s); +	api.flags = stream_getl(s); +	api.message = stream_getc(s); +	api.safi = stream_getw(s); + +	/* IPv4 prefix. */ +	memset(&p, 0, sizeof(struct prefix_ipv6)); +	p.family = AF_INET6; +	p.prefixlen = stream_getc(s); +	stream_get(&p.u.prefix6, s, PSIZE(p.prefixlen)); + +	if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) { +		memset(&src_p, 0, sizeof(struct prefix_ipv6)); +		src_p.family = AF_INET6; +		src_p.prefixlen = stream_getc(s); +		stream_get(&src_p.prefix, s, PSIZE(src_p.prefixlen)); +		src_pp = &src_p; +	} else +		src_pp = NULL; + +	/* Nexthop, ifindex, distance, metric. */ +	if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { +		u_char nexthop_type; + +		api.nexthop_num = stream_getc(s); +		for (i = 0; i < api.nexthop_num; i++) { +			nexthop_type = stream_getc(s); + +			switch (nexthop_type) { +			case NEXTHOP_TYPE_IPV6: +				stream_get(&nexthop, s, 16); +				pnexthop = (union g_addr *)&nexthop; +				break; +			case NEXTHOP_TYPE_IFINDEX: +				ifindex = stream_getl(s); +				break; +			} +		}  	} -    } - -  /* Distance. */ -  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE)) -    api.distance = stream_getc (s); -  else -    api.distance = 0; - -  /* Metric. */ -  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC)) -    api.metric = stream_getl (s); -  else -    api.metric = 0; -     -  /* tag */ -  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_TAG)) -    api.tag = stream_getl (s); -  else -    api.tag = 0; - -  if (IN6_IS_ADDR_UNSPECIFIED (&nexthop)) -    rib_delete (AFI_IP6, api.safi, zvrf_id (zvrf), api.type, api.instance, -		api.flags, &p, src_pp, NULL, ifindex, client->rtm_table); -  else -    rib_delete (AFI_IP6, api.safi, zvrf_id (zvrf), api.type, api.instance, -		api.flags, &p, src_pp, pnexthop, ifindex, client->rtm_table); - -  client->v6_route_del_cnt++; -  return 0; + +	/* Distance. */ +	if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE)) +		api.distance = stream_getc(s); +	else +		api.distance = 0; + +	/* Metric. */ +	if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC)) +		api.metric = stream_getl(s); +	else +		api.metric = 0; + +	/* tag */ +	if (CHECK_FLAG(api.message, ZAPI_MESSAGE_TAG)) +		api.tag = stream_getl(s); +	else +		api.tag = 0; + +	if (IN6_IS_ADDR_UNSPECIFIED(&nexthop)) +		rib_delete(AFI_IP6, api.safi, zvrf_id(zvrf), api.type, +			   api.instance, api.flags, &p, src_pp, NULL, ifindex, +			   client->rtm_table); +	else +		rib_delete(AFI_IP6, api.safi, zvrf_id(zvrf), api.type, +			   api.instance, api.flags, &p, src_pp, pnexthop, +			   ifindex, client->rtm_table); + +	client->v6_route_del_cnt++; +	return 0;  }  /* Register zebra server router-id information.  Send current router-id */ -static int -zread_router_id_add (struct zserv *client, u_short length, struct zebra_vrf *zvrf) +static int zread_router_id_add(struct zserv *client, u_short length, +			       struct zebra_vrf *zvrf)  { -  struct prefix p; +	struct prefix p; -  /* Router-id information is needed. */ -  vrf_bitmap_set (client->ridinfo, zvrf_id (zvrf)); +	/* Router-id information is needed. */ +	vrf_bitmap_set(client->ridinfo, zvrf_id(zvrf)); -  router_id_get (&p, zvrf_id (zvrf)); +	router_id_get(&p, zvrf_id(zvrf)); -  return zsend_router_id_update (client, &p, zvrf_id (zvrf)); +	return zsend_router_id_update(client, &p, zvrf_id(zvrf));  }  /* Unregister zebra server router-id information. */ -static int -zread_router_id_delete (struct zserv *client, u_short length, struct zebra_vrf *zvrf) +static int zread_router_id_delete(struct zserv *client, u_short length, +				  struct zebra_vrf *zvrf)  { -  vrf_bitmap_unset (client->ridinfo, zvrf_id (zvrf)); -  return 0; +	vrf_bitmap_unset(client->ridinfo, zvrf_id(zvrf)); +	return 0;  }  /* Tie up route-type and client->sock */ -static void -zread_hello (struct zserv *client) +static void zread_hello(struct zserv *client)  { -  /* type of protocol (lib/zebra.h) */ -  u_char proto; -  u_short instance; +	/* type of protocol (lib/zebra.h) */ +	u_char proto; +	u_short instance; -  proto = stream_getc (client->ibuf); -  instance = stream_getw (client->ibuf); +	proto = stream_getc(client->ibuf); +	instance = stream_getw(client->ibuf); -  /* accept only dynamic routing protocols */ -  if ((proto < ZEBRA_ROUTE_MAX) -  &&  (proto > ZEBRA_ROUTE_STATIC)) -    { -      zlog_notice ("client %d says hello and bids fair to announce only %s routes", -                    client->sock, zebra_route_string(proto)); -      if (instance) -        zlog_notice ("client protocol instance %d", instance); +	/* accept only dynamic routing protocols */ +	if ((proto < ZEBRA_ROUTE_MAX) && (proto > ZEBRA_ROUTE_STATIC)) { +		zlog_notice( +			"client %d says hello and bids fair to announce only %s routes", +			client->sock, zebra_route_string(proto)); +		if (instance) +			zlog_notice("client protocol instance %d", instance); -      client->proto = proto; -      client->instance = instance; -    } +		client->proto = proto; +		client->instance = instance; +	}  }  /* Unregister all information in a VRF. */ -static int -zread_vrf_unregister (struct zserv *client, u_short length, struct zebra_vrf *zvrf) -{ -  int i; -  afi_t afi; - -  for (afi = AFI_IP; afi < AFI_MAX; afi++) -    for (i = 0; i < ZEBRA_ROUTE_MAX; i++) -      vrf_bitmap_unset (client->redist[afi][i], zvrf_id (zvrf)); -  vrf_bitmap_unset (client->redist_default, zvrf_id (zvrf)); -  vrf_bitmap_unset (client->ifinfo, zvrf_id (zvrf)); -  vrf_bitmap_unset (client->ridinfo, zvrf_id (zvrf)); - -  return 0; -} - -static void -zread_mpls_labels (int command, struct zserv *client, u_short length, -		   vrf_id_t vrf_id) -{ -  struct stream *s; -  enum lsp_types_t type; -  struct prefix prefix; -  enum nexthop_types_t gtype; -  union g_addr gate; -  ifindex_t ifindex; -  mpls_label_t in_label, out_label; -  u_int8_t distance; -  struct zebra_vrf *zvrf; - -  zvrf = vrf_info_lookup (vrf_id); -  if (!zvrf) -    return; - -  /* Get input stream.  */ -  s = client->ibuf; - -  /* Get data. */ -  type = stream_getc (s); -  prefix.family = stream_getl (s); -  switch (prefix.family) -    { -    case AF_INET: -      prefix.u.prefix4.s_addr = stream_get_ipv4 (s); -      prefix.prefixlen = stream_getc (s); -      gate.ipv4.s_addr = stream_get_ipv4 (s); -      break; -    case AF_INET6: -      stream_get (&prefix.u.prefix6, s, 16); -      prefix.prefixlen = stream_getc (s); -      stream_get (&gate.ipv6, s, 16); -      break; -    default: -      return; -    } -  ifindex = stream_getl (s); -  distance = stream_getc (s); -  in_label = stream_getl (s); -  out_label = stream_getl (s); - -  switch (prefix.family) -    { -    case AF_INET: -      if (ifindex) -	gtype = NEXTHOP_TYPE_IPV4_IFINDEX; -      else -	gtype = NEXTHOP_TYPE_IPV4; -      break; -    case AF_INET6: -      if (ifindex) -	gtype = NEXTHOP_TYPE_IPV6_IFINDEX; -      else -	gtype = NEXTHOP_TYPE_IPV6; -      break; -    default: -      return; -    } - -  if (! mpls_enabled) -    return; - -  if (command == ZEBRA_MPLS_LABELS_ADD) -    { -      mpls_lsp_install (zvrf, type, in_label, out_label, gtype, &gate, -			NULL, ifindex); -      mpls_ftn_update (1, zvrf, type, &prefix, gtype, &gate, ifindex, -		       distance, out_label); -    } -  else if (command == ZEBRA_MPLS_LABELS_DELETE) -    { -      mpls_lsp_uninstall (zvrf, type, in_label, gtype, &gate, NULL, ifindex); -      mpls_ftn_update (0, zvrf, type, &prefix, gtype, &gate, ifindex, -		       distance, out_label); -    } +static int zread_vrf_unregister(struct zserv *client, u_short length, +				struct zebra_vrf *zvrf) +{ +	int i; +	afi_t afi; + +	for (afi = AFI_IP; afi < AFI_MAX; afi++) +		for (i = 0; i < ZEBRA_ROUTE_MAX; i++) +			vrf_bitmap_unset(client->redist[afi][i], zvrf_id(zvrf)); +	vrf_bitmap_unset(client->redist_default, zvrf_id(zvrf)); +	vrf_bitmap_unset(client->ifinfo, zvrf_id(zvrf)); +	vrf_bitmap_unset(client->ridinfo, zvrf_id(zvrf)); + +	return 0; +} + +static void zread_mpls_labels(int command, struct zserv *client, u_short length, +			      vrf_id_t vrf_id) +{ +	struct stream *s; +	enum lsp_types_t type; +	struct prefix prefix; +	enum nexthop_types_t gtype; +	union g_addr gate; +	ifindex_t ifindex; +	mpls_label_t in_label, out_label; +	u_int8_t distance; +	struct zebra_vrf *zvrf; + +	zvrf = vrf_info_lookup(vrf_id); +	if (!zvrf) +		return; + +	/* Get input stream.  */ +	s = client->ibuf; + +	/* Get data. */ +	type = stream_getc(s); +	prefix.family = stream_getl(s); +	switch (prefix.family) { +	case AF_INET: +		prefix.u.prefix4.s_addr = stream_get_ipv4(s); +		prefix.prefixlen = stream_getc(s); +		gate.ipv4.s_addr = stream_get_ipv4(s); +		break; +	case AF_INET6: +		stream_get(&prefix.u.prefix6, s, 16); +		prefix.prefixlen = stream_getc(s); +		stream_get(&gate.ipv6, s, 16); +		break; +	default: +		return; +	} +	ifindex = stream_getl(s); +	distance = stream_getc(s); +	in_label = stream_getl(s); +	out_label = stream_getl(s); + +	switch (prefix.family) { +	case AF_INET: +		if (ifindex) +			gtype = NEXTHOP_TYPE_IPV4_IFINDEX; +		else +			gtype = NEXTHOP_TYPE_IPV4; +		break; +	case AF_INET6: +		if (ifindex) +			gtype = NEXTHOP_TYPE_IPV6_IFINDEX; +		else +			gtype = NEXTHOP_TYPE_IPV6; +		break; +	default: +		return; +	} + +	if (!mpls_enabled) +		return; + +	if (command == ZEBRA_MPLS_LABELS_ADD) { +		mpls_lsp_install(zvrf, type, in_label, out_label, gtype, &gate, +				 NULL, ifindex); +		mpls_ftn_update(1, zvrf, type, &prefix, gtype, &gate, ifindex, +				distance, out_label); +	} else if (command == ZEBRA_MPLS_LABELS_DELETE) { +		mpls_lsp_uninstall(zvrf, type, in_label, gtype, &gate, NULL, +				   ifindex); +		mpls_ftn_update(0, zvrf, type, &prefix, gtype, &gate, ifindex, +				distance, out_label); +	}  }  /* Send response to a label manager connect request to client */ -static int -zsend_label_manager_connect_response (struct zserv *client, vrf_id_t vrf_id, u_short result) +static int zsend_label_manager_connect_response(struct zserv *client, +						vrf_id_t vrf_id, u_short result)  { -  struct stream *s; +	struct stream *s; -  s = client->obuf; -  stream_reset (s); +	s = client->obuf; +	stream_reset(s); -  zserv_create_header (s, ZEBRA_LABEL_MANAGER_CONNECT, vrf_id); +	zserv_create_header(s, ZEBRA_LABEL_MANAGER_CONNECT, vrf_id); -  /* result */ -  stream_putc (s, result); +	/* result */ +	stream_putc(s, result); -  /* Write packet size. */ -  stream_putw_at (s, 0, stream_get_endp (s)); +	/* Write packet size. */ +	stream_putw_at(s, 0, stream_get_endp(s)); -  return writen (client->sock, s->data, stream_get_endp (s)); +	return writen(client->sock, s->data, stream_get_endp(s));  } -static void -zread_label_manager_connect (struct zserv *client, vrf_id_t vrf_id) +static void zread_label_manager_connect(struct zserv *client, vrf_id_t vrf_id)  { -  struct stream *s; -  /* type of protocol (lib/zebra.h) */ -  u_char proto; -  u_short instance; +	struct stream *s; +	/* type of protocol (lib/zebra.h) */ +	u_char proto; +	u_short instance; -  /* Get input stream.  */ -  s = client->ibuf; +	/* Get input stream.  */ +	s = client->ibuf; -  /* Get data. */ -  proto = stream_getc (s); -  instance = stream_getw (s); +	/* Get data. */ +	proto = stream_getc(s); +	instance = stream_getw(s); -  /* accept only dynamic routing protocols */ -  if ((proto >= ZEBRA_ROUTE_MAX) -      ||  (proto <= ZEBRA_ROUTE_STATIC)) -    { -      zlog_err ("client %d has wrong protocol %s", -                client->sock, zebra_route_string(proto)); -      zsend_label_manager_connect_response (client, vrf_id, 1); -      return; -    } -  zlog_notice ("client %d with instance %u connected as %s", -               client->sock, instance, zebra_route_string(proto)); -  client->proto = proto; -  client->instance = instance; - -  /* -    Release previous labels of same protocol and instance. -    This is done in case it restarted from an unexpected shutdown. -  */ -  release_daemon_chunks (proto, instance); - -  zlog_debug (" Label Manager client connected: sock %d, proto %s, instance %u", -              client->sock, zebra_route_string(proto), instance); -  /* send response back */ -  zsend_label_manager_connect_response (client, vrf_id, 0); +	/* accept only dynamic routing protocols */ +	if ((proto >= ZEBRA_ROUTE_MAX) || (proto <= ZEBRA_ROUTE_STATIC)) { +		zlog_err("client %d has wrong protocol %s", client->sock, +			 zebra_route_string(proto)); +		zsend_label_manager_connect_response(client, vrf_id, 1); +		return; +	} +	zlog_notice("client %d with instance %u connected as %s", client->sock, +		    instance, zebra_route_string(proto)); +	client->proto = proto; +	client->instance = instance; + +	/* +	  Release previous labels of same protocol and instance. +	  This is done in case it restarted from an unexpected shutdown. +	*/ +	release_daemon_chunks(proto, instance); + +	zlog_debug( +		" Label Manager client connected: sock %d, proto %s, instance %u", +		client->sock, zebra_route_string(proto), instance); +	/* send response back */ +	zsend_label_manager_connect_response(client, vrf_id, 0);  }  /* Send response to a get label chunk request to client */ -static int -zsend_assign_label_chunk_response (struct zserv *client, vrf_id_t vrf_id, -                                   struct label_manager_chunk *lmc) -{ -  struct stream *s; - -  s = client->obuf; -  stream_reset (s); - -  zserv_create_header (s, ZEBRA_GET_LABEL_CHUNK, vrf_id); - -  if (lmc) -    { -      /* keep */ -      stream_putc (s, lmc->keep); -      /* start and end labels */ -      stream_putl (s, lmc->start); -      stream_putl (s, lmc->end); - -    } - -  /* Write packet size. */ -  stream_putw_at (s, 0, stream_get_endp (s)); - -  return writen (client->sock, s->data, stream_get_endp (s)); -} - -static void -zread_get_label_chunk (struct zserv *client, vrf_id_t vrf_id) -{ -  struct stream *s; -  u_char keep; -  uint32_t size; -  struct label_manager_chunk *lmc; - -  /* Get input stream.  */ -  s = client->ibuf; - -  /* Get data. */ -  keep = stream_getc (s); -  size = stream_getl (s); - -  lmc = assign_label_chunk (client->proto, client->instance, keep, size); -  if (!lmc) -    zlog_err ("%s: Unable to assign Label Chunk of size %u", __func__, size); -  else -    zlog_debug ("Assigned Label Chunk %u - %u to %u", -                lmc->start, lmc->end, keep); -  /* send response back */ -  zsend_assign_label_chunk_response (client, vrf_id, lmc); -} - -static void -zread_release_label_chunk (struct zserv *client) -{ -  struct stream *s; -  uint32_t start, end; - -  /* Get input stream.  */ -  s = client->ibuf; - -  /* Get data. */ -  start = stream_getl (s); -  end = stream_getl (s); - -  release_label_chunk (client->proto, client->instance, start, end); -} -static void -zread_label_manager_request (int cmd, struct zserv *client, vrf_id_t vrf_id) -{ -  /* to avoid sending other messages like ZERBA_INTERFACE_UP */ -  if (cmd == ZEBRA_LABEL_MANAGER_CONNECT) -    client->is_synchronous = 1; - -  /* external label manager */ -  if (lm_is_external) -    zread_relay_label_manager_request (cmd, client, vrf_id); -  /* this is a label manager */ -  else -    { -      if (cmd == ZEBRA_LABEL_MANAGER_CONNECT) -        zread_label_manager_connect (client, vrf_id); -      else -        { -          /* Sanity: don't allow 'unidentified' requests */ -          if (!client->proto) -            { -              zlog_err ("Got label request from an unidentified client"); -              return; -            } -          if (cmd == ZEBRA_GET_LABEL_CHUNK) -            zread_get_label_chunk (client, vrf_id); -          else if (cmd == ZEBRA_RELEASE_LABEL_CHUNK) -            zread_release_label_chunk (client); -        } -    } -} - -static int -zread_pseudowire (int command, struct zserv *client, u_short length, -		  vrf_id_t vrf_id) -{ -  struct stream *s; -  struct zebra_vrf *zvrf; -  char ifname[IF_NAMESIZE]; -  ifindex_t ifindex; -  int type; -  int af; -  union g_addr nexthop; -  uint32_t local_label; -  uint32_t remote_label; -  uint8_t flags; -  union pw_protocol_fields data; -  uint8_t protocol; -  struct zebra_pw *pw; - -  zvrf = vrf_info_lookup (vrf_id); -  if (!zvrf) -    return -1; - -  /* Get input stream.  */ -  s = client->ibuf; - -  /* Get data. */ -  stream_get (ifname, s, IF_NAMESIZE); -  ifindex = stream_getl (s); -  type = stream_getl (s); -  af = stream_getl (s); -  switch (af) -    { -    case AF_INET: -      nexthop.ipv4.s_addr = stream_get_ipv4 (s); -      break; -    case AF_INET6: -      stream_get (&nexthop.ipv6, s, 16); -      break; -    default: -      return -1; -    } -  local_label = stream_getl (s); -  remote_label = stream_getl (s); -  flags = stream_getc (s); -  stream_get (&data, s, sizeof(data)); -  protocol = client->proto; - -  pw = zebra_pw_find(zvrf, ifname); -  switch (command) -    { -    case ZEBRA_PW_ADD: -      if (pw) -	{ -	  zlog_warn ("%s: pseudowire %s already exists [%s]", __func__, ifname, -		     zserv_command_string (command)); -	  return -1; -	} +static int zsend_assign_label_chunk_response(struct zserv *client, +					     vrf_id_t vrf_id, +					     struct label_manager_chunk *lmc) +{ +	struct stream *s; -      zebra_pw_add (zvrf, ifname, protocol, client); -      break; -    case ZEBRA_PW_DELETE: -      if (!pw) -	{ -	  zlog_warn ("%s: pseudowire %s not found [%s]", __func__, ifname, -		     zserv_command_string (command)); -	  return -1; +	s = client->obuf; +	stream_reset(s); + +	zserv_create_header(s, ZEBRA_GET_LABEL_CHUNK, vrf_id); + +	if (lmc) { +		/* keep */ +		stream_putc(s, lmc->keep); +		/* start and end labels */ +		stream_putl(s, lmc->start); +		stream_putl(s, lmc->end);  	} -      zebra_pw_del (zvrf, pw); -      break; -    case ZEBRA_PW_SET: -    case ZEBRA_PW_UNSET: -      if (!pw) -	{ -	  zlog_warn ("%s: pseudowire %s not found [%s]", __func__, ifname, -		     zserv_command_string (command)); -	  return -1; +	/* Write packet size. */ +	stream_putw_at(s, 0, stream_get_endp(s)); + +	return writen(client->sock, s->data, stream_get_endp(s)); +} + +static void zread_get_label_chunk(struct zserv *client, vrf_id_t vrf_id) +{ +	struct stream *s; +	u_char keep; +	uint32_t size; +	struct label_manager_chunk *lmc; + +	/* Get input stream.  */ +	s = client->ibuf; + +	/* Get data. */ +	keep = stream_getc(s); +	size = stream_getl(s); + +	lmc = assign_label_chunk(client->proto, client->instance, keep, size); +	if (!lmc) +		zlog_err("%s: Unable to assign Label Chunk of size %u", +			 __func__, size); +	else +		zlog_debug("Assigned Label Chunk %u - %u to %u", lmc->start, +			   lmc->end, keep); +	/* send response back */ +	zsend_assign_label_chunk_response(client, vrf_id, lmc); +} + +static void zread_release_label_chunk(struct zserv *client) +{ +	struct stream *s; +	uint32_t start, end; + +	/* Get input stream.  */ +	s = client->ibuf; + +	/* Get data. */ +	start = stream_getl(s); +	end = stream_getl(s); + +	release_label_chunk(client->proto, client->instance, start, end); +} +static void zread_label_manager_request(int cmd, struct zserv *client, +					vrf_id_t vrf_id) +{ +	/* to avoid sending other messages like ZERBA_INTERFACE_UP */ +	if (cmd == ZEBRA_LABEL_MANAGER_CONNECT) +		client->is_synchronous = 1; + +	/* external label manager */ +	if (lm_is_external) +		zread_relay_label_manager_request(cmd, client, vrf_id); +	/* this is a label manager */ +	else { +		if (cmd == ZEBRA_LABEL_MANAGER_CONNECT) +			zread_label_manager_connect(client, vrf_id); +		else { +			/* Sanity: don't allow 'unidentified' requests */ +			if (!client->proto) { +				zlog_err( +					"Got label request from an unidentified client"); +				return; +			} +			if (cmd == ZEBRA_GET_LABEL_CHUNK) +				zread_get_label_chunk(client, vrf_id); +			else if (cmd == ZEBRA_RELEASE_LABEL_CHUNK) +				zread_release_label_chunk(client); +		}  	} +} -      switch (command) -	{ +static int zread_pseudowire(int command, struct zserv *client, u_short length, +			    vrf_id_t vrf_id) +{ +	struct stream *s; +	struct zebra_vrf *zvrf; +	char ifname[IF_NAMESIZE]; +	ifindex_t ifindex; +	int type; +	int af; +	union g_addr nexthop; +	uint32_t local_label; +	uint32_t remote_label; +	uint8_t flags; +	union pw_protocol_fields data; +	uint8_t protocol; +	struct zebra_pw *pw; + +	zvrf = vrf_info_lookup(vrf_id); +	if (!zvrf) +		return -1; + +	/* Get input stream.  */ +	s = client->ibuf; + +	/* Get data. */ +	stream_get(ifname, s, IF_NAMESIZE); +	ifindex = stream_getl(s); +	type = stream_getl(s); +	af = stream_getl(s); +	switch (af) { +	case AF_INET: +		nexthop.ipv4.s_addr = stream_get_ipv4(s); +		break; +	case AF_INET6: +		stream_get(&nexthop.ipv6, s, 16); +		break; +	default: +		return -1; +	} +	local_label = stream_getl(s); +	remote_label = stream_getl(s); +	flags = stream_getc(s); +	stream_get(&data, s, sizeof(data)); +	protocol = client->proto; + +	pw = zebra_pw_find(zvrf, ifname); +	switch (command) { +	case ZEBRA_PW_ADD: +		if (pw) { +			zlog_warn("%s: pseudowire %s already exists [%s]", +				  __func__, ifname, +				  zserv_command_string(command)); +			return -1; +		} + +		zebra_pw_add(zvrf, ifname, protocol, client); +		break; +	case ZEBRA_PW_DELETE: +		if (!pw) { +			zlog_warn("%s: pseudowire %s not found [%s]", __func__, +				  ifname, zserv_command_string(command)); +			return -1; +		} + +		zebra_pw_del(zvrf, pw); +		break;  	case ZEBRA_PW_SET: -	  pw->enabled = 1; -	  break;  	case ZEBRA_PW_UNSET: -	  pw->enabled = 0; -	  break; +		if (!pw) { +			zlog_warn("%s: pseudowire %s not found [%s]", __func__, +				  ifname, zserv_command_string(command)); +			return -1; +		} + +		switch (command) { +		case ZEBRA_PW_SET: +			pw->enabled = 1; +			break; +		case ZEBRA_PW_UNSET: +			pw->enabled = 0; +			break; +		} + +		zebra_pw_change(pw, ifindex, type, af, &nexthop, local_label, +				remote_label, flags, &data); +		break;  	} -      zebra_pw_change (pw, ifindex, type, af, &nexthop, local_label, -		       remote_label, flags, &data); -      break; -    } - -  return 0; +	return 0;  }  /* Cleanup registered nexthops (across VRFs) upon client disconnect. */ -static void -zebra_client_close_cleanup_rnh (struct zserv *client) -{ -  struct vrf *vrf; -  struct zebra_vrf *zvrf; - -  RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) -    { -      if ((zvrf = vrf->info) != NULL) -        { -          zebra_cleanup_rnh_client(zvrf_id (zvrf), AF_INET, client, RNH_NEXTHOP_TYPE); -          zebra_cleanup_rnh_client(zvrf_id (zvrf), AF_INET6, client, RNH_NEXTHOP_TYPE); -          zebra_cleanup_rnh_client(zvrf_id (zvrf), AF_INET, client, RNH_IMPORT_CHECK_TYPE); -          zebra_cleanup_rnh_client(zvrf_id (zvrf), AF_INET6, client, RNH_IMPORT_CHECK_TYPE); -	  if (client->proto == ZEBRA_ROUTE_LDP) -	    { -	      hash_iterate(zvrf->lsp_table, mpls_ldp_lsp_uninstall_all, -			   zvrf->lsp_table); -	      mpls_ldp_ftn_uninstall_all (zvrf, AFI_IP); -	      mpls_ldp_ftn_uninstall_all (zvrf, AFI_IP6); -	    } -        } -    } +static void zebra_client_close_cleanup_rnh(struct zserv *client) +{ +	struct vrf *vrf; +	struct zebra_vrf *zvrf; + +	RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id) +	{ +		if ((zvrf = vrf->info) != NULL) { +			zebra_cleanup_rnh_client(zvrf_id(zvrf), AF_INET, client, +						 RNH_NEXTHOP_TYPE); +			zebra_cleanup_rnh_client(zvrf_id(zvrf), AF_INET6, +						 client, RNH_NEXTHOP_TYPE); +			zebra_cleanup_rnh_client(zvrf_id(zvrf), AF_INET, client, +						 RNH_IMPORT_CHECK_TYPE); +			zebra_cleanup_rnh_client(zvrf_id(zvrf), AF_INET6, +						 client, RNH_IMPORT_CHECK_TYPE); +			if (client->proto == ZEBRA_ROUTE_LDP) { +				hash_iterate(zvrf->lsp_table, +					     mpls_ldp_lsp_uninstall_all, +					     zvrf->lsp_table); +				mpls_ldp_ftn_uninstall_all(zvrf, AFI_IP); +				mpls_ldp_ftn_uninstall_all(zvrf, AFI_IP6); +			} +		} +	}  }  /* Close zebra client. */ -static void -zebra_client_close (struct zserv *client) -{ -  /* Send client de-registration to BFD */ -  zebra_ptm_bfd_client_deregister(client->proto); - -  /* Cleanup any registered nexthops - across all VRFs. */ -  zebra_client_close_cleanup_rnh (client); - -  /* Release Label Manager chunks */ -  release_daemon_chunks (client->proto, client->instance); - -  /* Remove pseudowires associated with this client */ -  zebra_pw_client_close (client); - -  /* Close file descriptor. */ -  if (client->sock) -    { -      unsigned long nroutes; - -      close (client->sock); -      nroutes = rib_score_proto (client->proto, client->instance); -      zlog_notice ("client %d disconnected. %lu %s routes removed from the rib", -                   client->sock, nroutes, zebra_route_string (client->proto)); -      client->sock = -1; -    } - -  /* Free stream buffers. */ -  if (client->ibuf) -    stream_free (client->ibuf); -  if (client->obuf) -    stream_free (client->obuf); -  if (client->wb) -    buffer_free(client->wb); - -  /* Release threads. */ -  if (client->t_read) -    thread_cancel (client->t_read); -  if (client->t_write) -    thread_cancel (client->t_write); -  if (client->t_suicide) -    thread_cancel (client->t_suicide); - -  /* Free bitmaps. */ -  for (afi_t afi = AFI_IP; afi < AFI_MAX; afi++) -    for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) -      vrf_bitmap_free (client->redist[afi][i]); - -  vrf_bitmap_free (client->redist_default); -  vrf_bitmap_free (client->ifinfo); -  vrf_bitmap_free (client->ridinfo); - -  /* Free client structure. */ -  listnode_delete (zebrad.client_list, client); -  XFREE (MTYPE_TMP, client); +static void zebra_client_close(struct zserv *client) +{ +	/* Send client de-registration to BFD */ +	zebra_ptm_bfd_client_deregister(client->proto); + +	/* Cleanup any registered nexthops - across all VRFs. */ +	zebra_client_close_cleanup_rnh(client); + +	/* Release Label Manager chunks */ +	release_daemon_chunks(client->proto, client->instance); + +	/* Remove pseudowires associated with this client */ +	zebra_pw_client_close(client); + +	/* Close file descriptor. */ +	if (client->sock) { +		unsigned long nroutes; + +		close(client->sock); +		nroutes = rib_score_proto(client->proto, client->instance); +		zlog_notice( +			"client %d disconnected. %lu %s routes removed from the rib", +			client->sock, nroutes, +			zebra_route_string(client->proto)); +		client->sock = -1; +	} + +	/* Free stream buffers. */ +	if (client->ibuf) +		stream_free(client->ibuf); +	if (client->obuf) +		stream_free(client->obuf); +	if (client->wb) +		buffer_free(client->wb); + +	/* Release threads. */ +	if (client->t_read) +		thread_cancel(client->t_read); +	if (client->t_write) +		thread_cancel(client->t_write); +	if (client->t_suicide) +		thread_cancel(client->t_suicide); + +	/* Free bitmaps. */ +	for (afi_t afi = AFI_IP; afi < AFI_MAX; afi++) +		for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) +			vrf_bitmap_free(client->redist[afi][i]); + +	vrf_bitmap_free(client->redist_default); +	vrf_bitmap_free(client->ifinfo); +	vrf_bitmap_free(client->ridinfo); + +	/* Free client structure. */ +	listnode_delete(zebrad.client_list, client); +	XFREE(MTYPE_TMP, client);  }  /* Make new client. */ -static void -zebra_client_create (int sock) +static void zebra_client_create(int sock)  { -  struct zserv *client; -  int i; -  afi_t afi; +	struct zserv *client; +	int i; +	afi_t afi; + +	client = XCALLOC(MTYPE_TMP, sizeof(struct zserv)); -  client = XCALLOC (MTYPE_TMP, sizeof (struct zserv)); +	/* Make client input/output buffer. */ +	client->sock = sock; +	client->ibuf = stream_new(ZEBRA_MAX_PACKET_SIZ); +	client->obuf = stream_new(ZEBRA_MAX_PACKET_SIZ); +	client->wb = buffer_new(0); -  /* Make client input/output buffer. */ -  client->sock = sock; -  client->ibuf = stream_new (ZEBRA_MAX_PACKET_SIZ); -  client->obuf = stream_new (ZEBRA_MAX_PACKET_SIZ); -  client->wb = buffer_new(0); +	/* Set table number. */ +	client->rtm_table = zebrad.rtm_table_default; -  /* Set table number. */ -  client->rtm_table = zebrad.rtm_table_default; +	client->connect_time = monotime(NULL); +	/* Initialize flags */ +	for (afi = AFI_IP; afi < AFI_MAX; afi++) +		for (i = 0; i < ZEBRA_ROUTE_MAX; i++) +			client->redist[afi][i] = vrf_bitmap_init(); +	client->redist_default = vrf_bitmap_init(); +	client->ifinfo = vrf_bitmap_init(); +	client->ridinfo = vrf_bitmap_init(); -  client->connect_time = monotime(NULL); -  /* Initialize flags */ -  for (afi = AFI_IP; afi < AFI_MAX; afi++) -    for (i = 0; i < ZEBRA_ROUTE_MAX; i++) -      client->redist[afi][i] = vrf_bitmap_init (); -  client->redist_default = vrf_bitmap_init (); -  client->ifinfo = vrf_bitmap_init (); -  client->ridinfo = vrf_bitmap_init (); +	/* by default, it's not a synchronous client */ +	client->is_synchronous = 0; -  /* by default, it's not a synchronous client */ -  client->is_synchronous = 0; +	/* Add this client to linked list. */ +	listnode_add(zebrad.client_list, client); -  /* Add this client to linked list. */ -  listnode_add (zebrad.client_list, client); -   -  /* Make new read thread. */ -  zebra_event (ZEBRA_READ, sock, client); +	/* Make new read thread. */ +	zebra_event(ZEBRA_READ, sock, client); -  zebra_vrf_update_all (client); +	zebra_vrf_update_all(client);  }  /* Handler of zebra service request. */ -static int -zebra_client_read (struct thread *thread) -{ -  int sock; -  struct zserv *client; -  size_t already; -  uint16_t length, command; -  uint8_t marker, version; -  vrf_id_t vrf_id; -  struct zebra_vrf *zvrf; - -  /* Get thread data.  Reset reading thread because I'm running. */ -  sock = THREAD_FD (thread); -  client = THREAD_ARG (thread); -  client->t_read = NULL; - -  if (client->t_suicide) -    { -      zebra_client_close(client); -      return -1; -    } - -  /* Read length and command (if we don't have it already). */ -  if ((already = stream_get_endp(client->ibuf)) < ZEBRA_HEADER_SIZE) -    { -      ssize_t nbyte; -      if (((nbyte = stream_read_try (client->ibuf, sock, -				     ZEBRA_HEADER_SIZE-already)) == 0) || -	  (nbyte == -1)) -	{ -	  if (IS_ZEBRA_DEBUG_EVENT) -	    zlog_debug ("connection closed socket [%d]", sock); -	  zebra_client_close (client); -	  return -1; +static int zebra_client_read(struct thread *thread) +{ +	int sock; +	struct zserv *client; +	size_t already; +	uint16_t length, command; +	uint8_t marker, version; +	vrf_id_t vrf_id; +	struct zebra_vrf *zvrf; + +	/* Get thread data.  Reset reading thread because I'm running. */ +	sock = THREAD_FD(thread); +	client = THREAD_ARG(thread); +	client->t_read = NULL; + +	if (client->t_suicide) { +		zebra_client_close(client); +		return -1;  	} -      if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE-already)) -	{ -	  /* Try again later. */ -	  zebra_event (ZEBRA_READ, sock, client); -	  return 0; + +	/* Read length and command (if we don't have it already). */ +	if ((already = stream_get_endp(client->ibuf)) < ZEBRA_HEADER_SIZE) { +		ssize_t nbyte; +		if (((nbyte = stream_read_try(client->ibuf, sock, +					      ZEBRA_HEADER_SIZE - already)) +		     == 0) +		    || (nbyte == -1)) { +			if (IS_ZEBRA_DEBUG_EVENT) +				zlog_debug("connection closed socket [%d]", +					   sock); +			zebra_client_close(client); +			return -1; +		} +		if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE - already)) { +			/* Try again later. */ +			zebra_event(ZEBRA_READ, sock, client); +			return 0; +		} +		already = ZEBRA_HEADER_SIZE;  	} -      already = ZEBRA_HEADER_SIZE; -    } - -  /* Reset to read from the beginning of the incoming packet. */ -  stream_set_getp(client->ibuf, 0); - -  /* Fetch header values */ -  length = stream_getw (client->ibuf); -  marker = stream_getc (client->ibuf); -  version = stream_getc (client->ibuf); -  vrf_id = stream_getw (client->ibuf); -  command = stream_getw (client->ibuf); - -  if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) -    { -      zlog_err("%s: socket %d version mismatch, marker %d, version %d", -               __func__, sock, marker, version); -      zebra_client_close (client); -      return -1; -    } -  if (length < ZEBRA_HEADER_SIZE)  -    { -      zlog_warn("%s: socket %d message length %u is less than header size %d", -	        __func__, sock, length, ZEBRA_HEADER_SIZE); -      zebra_client_close (client); -      return -1; -    } -  if (length > STREAM_SIZE(client->ibuf)) -    { -      zlog_warn("%s: socket %d message length %u exceeds buffer size %lu", -	        __func__, sock, length, (u_long)STREAM_SIZE(client->ibuf)); -      zebra_client_close (client); -      return -1; -    } - -  /* Read rest of data. */ -  if (already < length) -    { -      ssize_t nbyte; -      if (((nbyte = stream_read_try (client->ibuf, sock, -				     length-already)) == 0) || -	  (nbyte == -1)) -	{ -	  if (IS_ZEBRA_DEBUG_EVENT) -	    zlog_debug ("connection closed [%d] when reading zebra data", sock); -	  zebra_client_close (client); -	  return -1; + +	/* Reset to read from the beginning of the incoming packet. */ +	stream_set_getp(client->ibuf, 0); + +	/* Fetch header values */ +	length = stream_getw(client->ibuf); +	marker = stream_getc(client->ibuf); +	version = stream_getc(client->ibuf); +	vrf_id = stream_getw(client->ibuf); +	command = stream_getw(client->ibuf); + +	if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) { +		zlog_err( +			"%s: socket %d version mismatch, marker %d, version %d", +			__func__, sock, marker, version); +		zebra_client_close(client); +		return -1; +	} +	if (length < ZEBRA_HEADER_SIZE) { +		zlog_warn( +			"%s: socket %d message length %u is less than header size %d", +			__func__, sock, length, ZEBRA_HEADER_SIZE); +		zebra_client_close(client); +		return -1;  	} -      if (nbyte != (ssize_t)(length-already)) -        { -	  /* Try again later. */ -	  zebra_event (ZEBRA_READ, sock, client); -	  return 0; +	if (length > STREAM_SIZE(client->ibuf)) { +		zlog_warn( +			"%s: socket %d message length %u exceeds buffer size %lu", +			__func__, sock, length, +			(u_long)STREAM_SIZE(client->ibuf)); +		zebra_client_close(client); +		return -1;  	} -    } - -  length -= ZEBRA_HEADER_SIZE; - -  /* Debug packet information. */ -  if (IS_ZEBRA_DEBUG_EVENT) -    zlog_debug ("zebra message comes from socket [%d]", sock); - -  if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) -    zlog_debug ("zebra message received [%s] %d in VRF %u", -	       zserv_command_string (command), length, vrf_id); - -  client->last_read_time = monotime(NULL); -  client->last_read_cmd = command; - -  zvrf = zebra_vrf_lookup_by_id (vrf_id); -  if (!zvrf) -    { -      if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) -        zlog_debug ("zebra received unknown VRF[%u]", vrf_id); -      goto zclient_read_out; -    } - -  switch (command)  -    { -    case ZEBRA_ROUTER_ID_ADD: -      zread_router_id_add (client, length, zvrf); -      break; -    case ZEBRA_ROUTER_ID_DELETE: -      zread_router_id_delete (client, length, zvrf); -      break; -    case ZEBRA_INTERFACE_ADD: -      zread_interface_add (client, length, zvrf); -      break; -    case ZEBRA_INTERFACE_DELETE: -      zread_interface_delete (client, length, zvrf); -      break; -    case ZEBRA_IPV4_ROUTE_ADD: -      zread_ipv4_add (client, length, zvrf); -      break; -    case ZEBRA_IPV4_ROUTE_DELETE: -      zread_ipv4_delete (client, length, zvrf); -      break; -    case ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD: -      zread_ipv4_route_ipv6_nexthop_add (client, length, zvrf); -      break; -    case ZEBRA_IPV4_NEXTHOP_ADD: -      zread_ipv4_add(client, length, zvrf); /* LB: r1.0 merge - id was 1 */ -      break; -    case ZEBRA_IPV4_NEXTHOP_DELETE: -      zread_ipv4_delete(client, length, zvrf); /* LB: r1.0 merge - id was 1 */ -      break; -    case ZEBRA_IPV6_ROUTE_ADD: -      zread_ipv6_add (client, length, zvrf); -      break; -    case ZEBRA_IPV6_ROUTE_DELETE: -      zread_ipv6_delete (client, length, zvrf); -      break; -    case ZEBRA_REDISTRIBUTE_ADD: -      zebra_redistribute_add (command, client, length, zvrf); -      break; -    case ZEBRA_REDISTRIBUTE_DELETE: -      zebra_redistribute_delete (command, client, length, zvrf); -      break; -    case ZEBRA_REDISTRIBUTE_DEFAULT_ADD: -      zebra_redistribute_default_add (command, client, length, zvrf); -      break; -    case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE: -      zebra_redistribute_default_delete (command, client, length, zvrf); -      break; -    case ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB: -      zread_ipv4_nexthop_lookup_mrib (client, length, zvrf); -      break; -    case ZEBRA_HELLO: -      zread_hello (client); -      break; -    case ZEBRA_NEXTHOP_REGISTER: -      zserv_rnh_register(client, sock, length, RNH_NEXTHOP_TYPE, zvrf); -      break; -    case ZEBRA_NEXTHOP_UNREGISTER: -      zserv_rnh_unregister(client, sock, length, RNH_NEXTHOP_TYPE, zvrf); -      break; -    case ZEBRA_IMPORT_ROUTE_REGISTER: -      zserv_rnh_register(client, sock, length, RNH_IMPORT_CHECK_TYPE, zvrf); -      break; -    case ZEBRA_IMPORT_ROUTE_UNREGISTER: -      zserv_rnh_unregister(client, sock, length, RNH_IMPORT_CHECK_TYPE, zvrf); -      break; -    case ZEBRA_BFD_DEST_UPDATE: -    case ZEBRA_BFD_DEST_REGISTER: -      zebra_ptm_bfd_dst_register(client, sock, length, command, zvrf); -      break; -    case ZEBRA_BFD_DEST_DEREGISTER: -      zebra_ptm_bfd_dst_deregister(client, sock, length, zvrf); -      break; -    case ZEBRA_VRF_UNREGISTER: -      zread_vrf_unregister (client, length, zvrf); -      break; -    case ZEBRA_BFD_CLIENT_REGISTER: -      zebra_ptm_bfd_client_register(client, sock, length); -      break; -    case ZEBRA_INTERFACE_ENABLE_RADV: -      zebra_interface_radv_set (client, sock, length, zvrf, 1); -      break; -    case ZEBRA_INTERFACE_DISABLE_RADV: -      zebra_interface_radv_set (client, sock, length, zvrf, 0); -      break; -    case ZEBRA_MPLS_LABELS_ADD: -    case ZEBRA_MPLS_LABELS_DELETE: -      zread_mpls_labels (command, client, length, vrf_id); -      break; -    case ZEBRA_IPMR_ROUTE_STATS: -      zebra_ipmr_route_stats (client, sock, length, zvrf); -      break; -    case ZEBRA_LABEL_MANAGER_CONNECT: -    case ZEBRA_GET_LABEL_CHUNK: -    case ZEBRA_RELEASE_LABEL_CHUNK: -      zread_label_manager_request (command, client, vrf_id); -      break; -    case ZEBRA_PW_ADD: -    case ZEBRA_PW_DELETE: -    case ZEBRA_PW_SET: -    case ZEBRA_PW_UNSET: -      zread_pseudowire (command, client, length, vrf_id); -      break; -    default: -      zlog_info ("Zebra received unknown command %d", command); -      break; -    } - -  if (client->t_suicide) -    { -      /* No need to wait for thread callback, just kill immediately. */ -      zebra_client_close(client); -      return -1; -    } - - zclient_read_out: -  stream_reset (client->ibuf); -  zebra_event (ZEBRA_READ, sock, client); -  return 0; + +	/* Read rest of data. */ +	if (already < length) { +		ssize_t nbyte; +		if (((nbyte = stream_read_try(client->ibuf, sock, +					      length - already)) +		     == 0) +		    || (nbyte == -1)) { +			if (IS_ZEBRA_DEBUG_EVENT) +				zlog_debug( +					"connection closed [%d] when reading zebra data", +					sock); +			zebra_client_close(client); +			return -1; +		} +		if (nbyte != (ssize_t)(length - already)) { +			/* Try again later. */ +			zebra_event(ZEBRA_READ, sock, client); +			return 0; +		} +	} + +	length -= ZEBRA_HEADER_SIZE; + +	/* Debug packet information. */ +	if (IS_ZEBRA_DEBUG_EVENT) +		zlog_debug("zebra message comes from socket [%d]", sock); + +	if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) +		zlog_debug("zebra message received [%s] %d in VRF %u", +			   zserv_command_string(command), length, vrf_id); + +	client->last_read_time = monotime(NULL); +	client->last_read_cmd = command; + +	zvrf = zebra_vrf_lookup_by_id(vrf_id); +	if (!zvrf) { +		if (IS_ZEBRA_DEBUG_PACKET && IS_ZEBRA_DEBUG_RECV) +			zlog_debug("zebra received unknown VRF[%u]", vrf_id); +		goto zclient_read_out; +	} + +	switch (command) { +	case ZEBRA_ROUTER_ID_ADD: +		zread_router_id_add(client, length, zvrf); +		break; +	case ZEBRA_ROUTER_ID_DELETE: +		zread_router_id_delete(client, length, zvrf); +		break; +	case ZEBRA_INTERFACE_ADD: +		zread_interface_add(client, length, zvrf); +		break; +	case ZEBRA_INTERFACE_DELETE: +		zread_interface_delete(client, length, zvrf); +		break; +	case ZEBRA_IPV4_ROUTE_ADD: +		zread_ipv4_add(client, length, zvrf); +		break; +	case ZEBRA_IPV4_ROUTE_DELETE: +		zread_ipv4_delete(client, length, zvrf); +		break; +	case ZEBRA_IPV4_ROUTE_IPV6_NEXTHOP_ADD: +		zread_ipv4_route_ipv6_nexthop_add(client, length, zvrf); +		break; +	case ZEBRA_IPV4_NEXTHOP_ADD: +		zread_ipv4_add(client, length, +			       zvrf); /* LB: r1.0 merge - id was 1 */ +		break; +	case ZEBRA_IPV4_NEXTHOP_DELETE: +		zread_ipv4_delete(client, length, +				  zvrf); /* LB: r1.0 merge - id was 1 */ +		break; +	case ZEBRA_IPV6_ROUTE_ADD: +		zread_ipv6_add(client, length, zvrf); +		break; +	case ZEBRA_IPV6_ROUTE_DELETE: +		zread_ipv6_delete(client, length, zvrf); +		break; +	case ZEBRA_REDISTRIBUTE_ADD: +		zebra_redistribute_add(command, client, length, zvrf); +		break; +	case ZEBRA_REDISTRIBUTE_DELETE: +		zebra_redistribute_delete(command, client, length, zvrf); +		break; +	case ZEBRA_REDISTRIBUTE_DEFAULT_ADD: +		zebra_redistribute_default_add(command, client, length, zvrf); +		break; +	case ZEBRA_REDISTRIBUTE_DEFAULT_DELETE: +		zebra_redistribute_default_delete(command, client, length, +						  zvrf); +		break; +	case ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB: +		zread_ipv4_nexthop_lookup_mrib(client, length, zvrf); +		break; +	case ZEBRA_HELLO: +		zread_hello(client); +		break; +	case ZEBRA_NEXTHOP_REGISTER: +		zserv_rnh_register(client, sock, length, RNH_NEXTHOP_TYPE, +				   zvrf); +		break; +	case ZEBRA_NEXTHOP_UNREGISTER: +		zserv_rnh_unregister(client, sock, length, RNH_NEXTHOP_TYPE, +				     zvrf); +		break; +	case ZEBRA_IMPORT_ROUTE_REGISTER: +		zserv_rnh_register(client, sock, length, RNH_IMPORT_CHECK_TYPE, +				   zvrf); +		break; +	case ZEBRA_IMPORT_ROUTE_UNREGISTER: +		zserv_rnh_unregister(client, sock, length, +				     RNH_IMPORT_CHECK_TYPE, zvrf); +		break; +	case ZEBRA_BFD_DEST_UPDATE: +	case ZEBRA_BFD_DEST_REGISTER: +		zebra_ptm_bfd_dst_register(client, sock, length, command, zvrf); +		break; +	case ZEBRA_BFD_DEST_DEREGISTER: +		zebra_ptm_bfd_dst_deregister(client, sock, length, zvrf); +		break; +	case ZEBRA_VRF_UNREGISTER: +		zread_vrf_unregister(client, length, zvrf); +		break; +	case ZEBRA_BFD_CLIENT_REGISTER: +		zebra_ptm_bfd_client_register(client, sock, length); +		break; +	case ZEBRA_INTERFACE_ENABLE_RADV: +		zebra_interface_radv_set(client, sock, length, zvrf, 1); +		break; +	case ZEBRA_INTERFACE_DISABLE_RADV: +		zebra_interface_radv_set(client, sock, length, zvrf, 0); +		break; +	case ZEBRA_MPLS_LABELS_ADD: +	case ZEBRA_MPLS_LABELS_DELETE: +		zread_mpls_labels(command, client, length, vrf_id); +		break; +	case ZEBRA_IPMR_ROUTE_STATS: +		zebra_ipmr_route_stats(client, sock, length, zvrf); +		break; +	case ZEBRA_LABEL_MANAGER_CONNECT: +	case ZEBRA_GET_LABEL_CHUNK: +	case ZEBRA_RELEASE_LABEL_CHUNK: +		zread_label_manager_request(command, client, vrf_id); +		break; +	case ZEBRA_PW_ADD: +	case ZEBRA_PW_DELETE: +	case ZEBRA_PW_SET: +	case ZEBRA_PW_UNSET: +		zread_pseudowire(command, client, length, vrf_id); +		break; +	default: +		zlog_info("Zebra received unknown command %d", command); +		break; +	} + +	if (client->t_suicide) { +		/* No need to wait for thread callback, just kill immediately. +		 */ +		zebra_client_close(client); +		return -1; +	} + +zclient_read_out: +	stream_reset(client->ibuf); +	zebra_event(ZEBRA_READ, sock, client); +	return 0;  }  /* Accept code of zebra server socket. */ -static int -zebra_accept (struct thread *thread) +static int zebra_accept(struct thread *thread)  { -  int accept_sock; -  int client_sock; -  struct sockaddr_in client; -  socklen_t len; +	int accept_sock; +	int client_sock; +	struct sockaddr_in client; +	socklen_t len; + +	accept_sock = THREAD_FD(thread); -  accept_sock = THREAD_FD (thread); +	/* Reregister myself. */ +	zebra_event(ZEBRA_SERV, accept_sock, NULL); -  /* Reregister myself. */ -  zebra_event (ZEBRA_SERV, accept_sock, NULL); +	len = sizeof(struct sockaddr_in); +	client_sock = accept(accept_sock, (struct sockaddr *)&client, &len); -  len = sizeof (struct sockaddr_in); -  client_sock = accept (accept_sock, (struct sockaddr *) &client, &len); +	if (client_sock < 0) { +		zlog_warn("Can't accept zebra socket: %s", +			  safe_strerror(errno)); +		return -1; +	} -  if (client_sock < 0) -    { -      zlog_warn ("Can't accept zebra socket: %s", safe_strerror (errno)); -      return -1; -    } +	/* Make client socket non-blocking.  */ +	set_nonblocking(client_sock); -  /* Make client socket non-blocking.  */ -  set_nonblocking(client_sock); -   -  /* Create new zebra client. */ -  zebra_client_create (client_sock); +	/* Create new zebra client. */ +	zebra_client_create(client_sock); -  return 0; +	return 0;  }  #ifdef HAVE_TCP_ZEBRA  /* Make zebra's server socket. */ -static void -zebra_serv () -{ -  int ret; -  int accept_sock; -  struct sockaddr_in addr; - -  accept_sock = socket (AF_INET, SOCK_STREAM, 0); - -  if (accept_sock < 0)  -    { -      zlog_warn ("Can't create zserv stream socket: %s",  -                 safe_strerror (errno)); -      zlog_warn ("zebra can't provice full functionality due to above error"); -      return; -    } - -  memset (&addr, 0, sizeof (struct sockaddr_in)); -  addr.sin_family = AF_INET; -  addr.sin_port = htons (ZEBRA_PORT); +static void zebra_serv() +{ +	int ret; +	int accept_sock; +	struct sockaddr_in addr; + +	accept_sock = socket(AF_INET, SOCK_STREAM, 0); + +	if (accept_sock < 0) { +		zlog_warn("Can't create zserv stream socket: %s", +			  safe_strerror(errno)); +		zlog_warn( +			"zebra can't provice full functionality due to above error"); +		return; +	} + +	memset(&addr, 0, sizeof(struct sockaddr_in)); +	addr.sin_family = AF_INET; +	addr.sin_port = htons(ZEBRA_PORT);  #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN -  addr.sin_len = sizeof (struct sockaddr_in); +	addr.sin_len = sizeof(struct sockaddr_in);  #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ -  addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); - -  sockopt_reuseaddr (accept_sock); -  sockopt_reuseport (accept_sock); - -  if ( zserv_privs.change(ZPRIVS_RAISE) ) -    zlog_err("Can't raise privileges"); -     -  ret  = bind (accept_sock, (struct sockaddr *)&addr,  -	       sizeof (struct sockaddr_in)); -  if (ret < 0) -    { -      zlog_warn ("Can't bind to stream socket: %s",  -                 safe_strerror (errno)); -      zlog_warn ("zebra can't provice full functionality due to above error"); -      close (accept_sock);      /* Avoid sd leak. */ -      return; -    } -     -  if ( zserv_privs.change(ZPRIVS_LOWER) ) -    zlog_err("Can't lower privileges"); - -  ret = listen (accept_sock, 1); -  if (ret < 0) -    { -      zlog_warn ("Can't listen to stream socket: %s",  -                 safe_strerror (errno)); -      zlog_warn ("zebra can't provice full functionality due to above error"); -      close (accept_sock);	/* Avoid sd leak. */ -      return; -    } - -  zebra_event (ZEBRA_SERV, accept_sock, NULL); +	addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + +	sockopt_reuseaddr(accept_sock); +	sockopt_reuseport(accept_sock); + +	if (zserv_privs.change(ZPRIVS_RAISE)) +		zlog_err("Can't raise privileges"); + +	ret = bind(accept_sock, (struct sockaddr *)&addr, +		   sizeof(struct sockaddr_in)); +	if (ret < 0) { +		zlog_warn("Can't bind to stream socket: %s", +			  safe_strerror(errno)); +		zlog_warn( +			"zebra can't provice full functionality due to above error"); +		close(accept_sock); /* Avoid sd leak. */ +		return; +	} + +	if (zserv_privs.change(ZPRIVS_LOWER)) +		zlog_err("Can't lower privileges"); + +	ret = listen(accept_sock, 1); +	if (ret < 0) { +		zlog_warn("Can't listen to stream socket: %s", +			  safe_strerror(errno)); +		zlog_warn( +			"zebra can't provice full functionality due to above error"); +		close(accept_sock); /* Avoid sd leak. */ +		return; +	} + +	zebra_event(ZEBRA_SERV, accept_sock, NULL);  }  #else /* HAVE_TCP_ZEBRA */ @@ -2511,223 +2448,220 @@ zebra_serv ()  #include <sys/un.h>  /* zebra server UNIX domain socket. */ -static void -zebra_serv_un (const char *path) -{ -  int ret; -  int sock, len; -  struct sockaddr_un serv; -  mode_t old_mask; - -  /* First of all, unlink existing socket */ -  unlink (path); - -  /* Set umask */ -  old_mask = umask (0077); - -  /* Make UNIX domain socket. */ -  sock = socket (AF_UNIX, SOCK_STREAM, 0); -  if (sock < 0) -    { -      zlog_warn ("Can't create zserv unix socket: %s",  -                 safe_strerror (errno)); -      zlog_warn ("zebra can't provide full functionality due to above error"); -      return; -    } - -  /* Make server socket. */ -  memset (&serv, 0, sizeof (struct sockaddr_un)); -  serv.sun_family = AF_UNIX; -  strncpy (serv.sun_path, path, strlen (path)); +static void zebra_serv_un(const char *path) +{ +	int ret; +	int sock, len; +	struct sockaddr_un serv; +	mode_t old_mask; + +	/* First of all, unlink existing socket */ +	unlink(path); + +	/* Set umask */ +	old_mask = umask(0077); + +	/* Make UNIX domain socket. */ +	sock = socket(AF_UNIX, SOCK_STREAM, 0); +	if (sock < 0) { +		zlog_warn("Can't create zserv unix socket: %s", +			  safe_strerror(errno)); +		zlog_warn( +			"zebra can't provide full functionality due to above error"); +		return; +	} + +	/* Make server socket. */ +	memset(&serv, 0, sizeof(struct sockaddr_un)); +	serv.sun_family = AF_UNIX; +	strncpy(serv.sun_path, path, strlen(path));  #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN -  len = serv.sun_len = SUN_LEN(&serv); +	len = serv.sun_len = SUN_LEN(&serv);  #else -  len = sizeof (serv.sun_family) + strlen (serv.sun_path); +	len = sizeof(serv.sun_family) + strlen(serv.sun_path);  #endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */ -  ret = bind (sock, (struct sockaddr *) &serv, len); -  if (ret < 0) -    { -      zlog_warn ("Can't bind to unix socket %s: %s",  -                 path, safe_strerror (errno)); -      zlog_warn ("zebra can't provide full functionality due to above error"); -      close (sock); -      return; -    } - -  ret = listen (sock, 5); -  if (ret < 0) -    { -      zlog_warn ("Can't listen to unix socket %s: %s",  -                 path, safe_strerror (errno)); -      zlog_warn ("zebra can't provide full functionality due to above error"); -      close (sock); -      return; -    } - -  umask (old_mask); - -  zebra_event (ZEBRA_SERV, sock, NULL); +	ret = bind(sock, (struct sockaddr *)&serv, len); +	if (ret < 0) { +		zlog_warn("Can't bind to unix socket %s: %s", path, +			  safe_strerror(errno)); +		zlog_warn( +			"zebra can't provide full functionality due to above error"); +		close(sock); +		return; +	} + +	ret = listen(sock, 5); +	if (ret < 0) { +		zlog_warn("Can't listen to unix socket %s: %s", path, +			  safe_strerror(errno)); +		zlog_warn( +			"zebra can't provide full functionality due to above error"); +		close(sock); +		return; +	} + +	umask(old_mask); + +	zebra_event(ZEBRA_SERV, sock, NULL);  }  #endif /* HAVE_TCP_ZEBRA */ -static void -zebra_event (enum event event, int sock, struct zserv *client) +static void zebra_event(enum event event, int sock, struct zserv *client)  { -  switch (event) -    { -    case ZEBRA_SERV: -      thread_add_read (zebrad.master, zebra_accept, client, sock); -      break; -    case ZEBRA_READ: -      client->t_read =  -	thread_add_read (zebrad.master, zebra_client_read, client, sock); -      break; -    case ZEBRA_WRITE: -      /**/ -      break; -    } +	switch (event) { +	case ZEBRA_SERV: +		thread_add_read(zebrad.master, zebra_accept, client, sock); +		break; +	case ZEBRA_READ: +		client->t_read = thread_add_read( +			zebrad.master, zebra_client_read, client, sock); +		break; +	case ZEBRA_WRITE: +		/**/ +		break; +	}  }  #define ZEBRA_TIME_BUF 32 -static char * -zserv_time_buf(time_t *time1, char *buf, int buflen) +static char *zserv_time_buf(time_t *time1, char *buf, int buflen)  { -  struct tm *tm; -  time_t now; +	struct tm *tm; +	time_t now; -  assert (buf != NULL); -  assert (buflen >= ZEBRA_TIME_BUF); -  assert (time1 != NULL); +	assert(buf != NULL); +	assert(buflen >= ZEBRA_TIME_BUF); +	assert(time1 != NULL); -  if (!*time1) -    { -      snprintf(buf, buflen, "never   "); -      return (buf); -    } +	if (!*time1) { +		snprintf(buf, buflen, "never   "); +		return (buf); +	} -  now = monotime(NULL); -  now -= *time1; -  tm = gmtime(&now); +	now = monotime(NULL); +	now -= *time1; +	tm = gmtime(&now); -  /* Making formatted timer strings. */ +/* Making formatted timer strings. */  #define ONE_DAY_SECOND 60*60*24  #define ONE_WEEK_SECOND 60*60*24*7 -  if (now < ONE_DAY_SECOND) -    snprintf (buf, buflen, "%02d:%02d:%02d", -	      tm->tm_hour, tm->tm_min, tm->tm_sec); -  else if (now < ONE_WEEK_SECOND) -    snprintf (buf, buflen, "%dd%02dh%02dm", -	      tm->tm_yday, tm->tm_hour, tm->tm_min); -  else -    snprintf (buf, buflen, "%02dw%dd%02dh", -	      tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour); -  return buf; -} - -static void -zebra_show_client_detail (struct vty *vty, struct zserv *client) -{ -  char cbuf[ZEBRA_TIME_BUF], rbuf[ZEBRA_TIME_BUF]; -  char wbuf[ZEBRA_TIME_BUF], nhbuf[ZEBRA_TIME_BUF], mbuf[ZEBRA_TIME_BUF]; - -  vty_out (vty, "Client: %s", zebra_route_string(client->proto)); -  if (client->instance) -    vty_out (vty, " Instance: %d", client->instance); -  vty_out (vty, "%s", VTY_NEWLINE); - -  vty_out (vty, "------------------------ %s", VTY_NEWLINE); -  vty_out (vty, "FD: %d %s", client->sock, VTY_NEWLINE); -  vty_out (vty, "Route Table ID: %d %s", client->rtm_table, VTY_NEWLINE); - -  vty_out (vty, "Connect Time: %s %s", -	   zserv_time_buf(&client->connect_time, cbuf, ZEBRA_TIME_BUF), -	   VTY_NEWLINE); -  if (client->nh_reg_time) -    { -      vty_out (vty, "Nexthop Registry Time: %s %s", -	       zserv_time_buf(&client->nh_reg_time, nhbuf, ZEBRA_TIME_BUF), -	       VTY_NEWLINE); -      if (client->nh_last_upd_time) -	vty_out (vty, "Nexthop Last Update Time: %s %s", -		 zserv_time_buf(&client->nh_last_upd_time, mbuf, ZEBRA_TIME_BUF), -		 VTY_NEWLINE); -      else -	vty_out (vty, "No Nexthop Update sent%s", VTY_NEWLINE); -    } -  else -    vty_out (vty, "Not registered for Nexthop Updates%s", VTY_NEWLINE); - -  vty_out (vty, "Last Msg Rx Time: %s %s", -	   zserv_time_buf(&client->last_read_time, rbuf, ZEBRA_TIME_BUF), -	   VTY_NEWLINE); -  vty_out (vty, "Last Msg Tx Time: %s %s", -	   zserv_time_buf(&client->last_write_time, wbuf, ZEBRA_TIME_BUF), -	   VTY_NEWLINE); -  if (client->last_read_time) -    vty_out (vty, "Last Rcvd Cmd: %s %s", -	     zserv_command_string(client->last_read_cmd), VTY_NEWLINE); -  if (client->last_write_time) -    vty_out (vty, "Last Sent Cmd: %s %s", -	     zserv_command_string(client->last_write_cmd), VTY_NEWLINE); -  vty_out (vty, "%s", VTY_NEWLINE); - -  vty_out (vty, "Type        Add        Update     Del %s", VTY_NEWLINE); -  vty_out (vty, "================================================== %s", VTY_NEWLINE); -  vty_out (vty, "IPv4        %-12d%-12d%-12d%s", client->v4_route_add_cnt, -	   client->v4_route_upd8_cnt, client->v4_route_del_cnt, VTY_NEWLINE); -  vty_out (vty, "IPv6        %-12d%-12d%-12d%s", client->v6_route_add_cnt, -	   client->v6_route_upd8_cnt, client->v6_route_del_cnt, VTY_NEWLINE); -  vty_out (vty, "Redist:v4   %-12d%-12d%-12d%s", client->redist_v4_add_cnt, 0, -	   client->redist_v4_del_cnt, VTY_NEWLINE); -  vty_out (vty, "Redist:v6   %-12d%-12d%-12d%s", client->redist_v6_add_cnt, 0, -	   client->redist_v6_del_cnt, VTY_NEWLINE); -  vty_out (vty, "Connected   %-12d%-12d%-12d%s", client->ifadd_cnt, 0, -	   client->ifdel_cnt, VTY_NEWLINE); -  vty_out (vty, "BFD peer    %-12d%-12d%-12d%s", client->bfd_peer_add_cnt, -       client->bfd_peer_upd8_cnt, client->bfd_peer_del_cnt, VTY_NEWLINE); -  vty_out (vty, "Interface Up Notifications: %d%s", client->ifup_cnt, -	   VTY_NEWLINE); -  vty_out (vty, "Interface Down Notifications: %d%s", client->ifdown_cnt, -	   VTY_NEWLINE); - -  vty_out (vty, "%s", VTY_NEWLINE); -  return; -} - -static void -zebra_show_client_brief (struct vty *vty, struct zserv *client) -{ -  char cbuf[ZEBRA_TIME_BUF], rbuf[ZEBRA_TIME_BUF]; -  char wbuf[ZEBRA_TIME_BUF]; - -  vty_out (vty, "%-8s%12s %12s%12s%8d/%-8d%8d/%-8d%s", -	   zebra_route_string(client->proto), -	   zserv_time_buf(&client->connect_time, cbuf, ZEBRA_TIME_BUF), -	   zserv_time_buf(&client->last_read_time, rbuf, ZEBRA_TIME_BUF), -	   zserv_time_buf(&client->last_write_time, wbuf, ZEBRA_TIME_BUF), -	   client->v4_route_add_cnt+client->v4_route_upd8_cnt, -	   client->v4_route_del_cnt, -	   client->v6_route_add_cnt+client->v6_route_upd8_cnt, -	   client->v6_route_del_cnt, VTY_NEWLINE); - -} - -struct zserv * -zebra_find_client (u_char proto) -{ -  struct listnode *node, *nnode; -  struct zserv *client; - -  for (ALL_LIST_ELEMENTS (zebrad.client_list, node, nnode, client)) -    { -      if (client->proto == proto) -        return client; -    } - -  return NULL; +	if (now < ONE_DAY_SECOND) +		snprintf(buf, buflen, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, +			 tm->tm_sec); +	else if (now < ONE_WEEK_SECOND) +		snprintf(buf, buflen, "%dd%02dh%02dm", tm->tm_yday, tm->tm_hour, +			 tm->tm_min); +	else +		snprintf(buf, buflen, "%02dw%dd%02dh", tm->tm_yday / 7, +			 tm->tm_yday - ((tm->tm_yday / 7) * 7), tm->tm_hour); +	return buf; +} + +static void zebra_show_client_detail(struct vty *vty, struct zserv *client) +{ +	char cbuf[ZEBRA_TIME_BUF], rbuf[ZEBRA_TIME_BUF]; +	char wbuf[ZEBRA_TIME_BUF], nhbuf[ZEBRA_TIME_BUF], mbuf[ZEBRA_TIME_BUF]; + +	vty_out(vty, "Client: %s", zebra_route_string(client->proto)); +	if (client->instance) +		vty_out(vty, " Instance: %d", client->instance); +	vty_out(vty, "%s", VTY_NEWLINE); + +	vty_out(vty, "------------------------ %s", VTY_NEWLINE); +	vty_out(vty, "FD: %d %s", client->sock, VTY_NEWLINE); +	vty_out(vty, "Route Table ID: %d %s", client->rtm_table, VTY_NEWLINE); + +	vty_out(vty, "Connect Time: %s %s", +		zserv_time_buf(&client->connect_time, cbuf, ZEBRA_TIME_BUF), +		VTY_NEWLINE); +	if (client->nh_reg_time) { +		vty_out(vty, "Nexthop Registry Time: %s %s", +			zserv_time_buf(&client->nh_reg_time, nhbuf, +				       ZEBRA_TIME_BUF), +			VTY_NEWLINE); +		if (client->nh_last_upd_time) +			vty_out(vty, "Nexthop Last Update Time: %s %s", +				zserv_time_buf(&client->nh_last_upd_time, mbuf, +					       ZEBRA_TIME_BUF), +				VTY_NEWLINE); +		else +			vty_out(vty, "No Nexthop Update sent%s", VTY_NEWLINE); +	} else +		vty_out(vty, "Not registered for Nexthop Updates%s", +			VTY_NEWLINE); + +	vty_out(vty, "Last Msg Rx Time: %s %s", +		zserv_time_buf(&client->last_read_time, rbuf, ZEBRA_TIME_BUF), +		VTY_NEWLINE); +	vty_out(vty, "Last Msg Tx Time: %s %s", +		zserv_time_buf(&client->last_write_time, wbuf, ZEBRA_TIME_BUF), +		VTY_NEWLINE); +	if (client->last_read_time) +		vty_out(vty, "Last Rcvd Cmd: %s %s", +			zserv_command_string(client->last_read_cmd), +			VTY_NEWLINE); +	if (client->last_write_time) +		vty_out(vty, "Last Sent Cmd: %s %s", +			zserv_command_string(client->last_write_cmd), +			VTY_NEWLINE); +	vty_out(vty, "%s", VTY_NEWLINE); + +	vty_out(vty, "Type        Add        Update     Del %s", VTY_NEWLINE); +	vty_out(vty, "================================================== %s", +		VTY_NEWLINE); +	vty_out(vty, "IPv4        %-12d%-12d%-12d%s", client->v4_route_add_cnt, +		client->v4_route_upd8_cnt, client->v4_route_del_cnt, +		VTY_NEWLINE); +	vty_out(vty, "IPv6        %-12d%-12d%-12d%s", client->v6_route_add_cnt, +		client->v6_route_upd8_cnt, client->v6_route_del_cnt, +		VTY_NEWLINE); +	vty_out(vty, "Redist:v4   %-12d%-12d%-12d%s", client->redist_v4_add_cnt, +		0, client->redist_v4_del_cnt, VTY_NEWLINE); +	vty_out(vty, "Redist:v6   %-12d%-12d%-12d%s", client->redist_v6_add_cnt, +		0, client->redist_v6_del_cnt, VTY_NEWLINE); +	vty_out(vty, "Connected   %-12d%-12d%-12d%s", client->ifadd_cnt, 0, +		client->ifdel_cnt, VTY_NEWLINE); +	vty_out(vty, "BFD peer    %-12d%-12d%-12d%s", client->bfd_peer_add_cnt, +		client->bfd_peer_upd8_cnt, client->bfd_peer_del_cnt, +		VTY_NEWLINE); +	vty_out(vty, "Interface Up Notifications: %d%s", client->ifup_cnt, +		VTY_NEWLINE); +	vty_out(vty, "Interface Down Notifications: %d%s", client->ifdown_cnt, +		VTY_NEWLINE); + +	vty_out(vty, "%s", VTY_NEWLINE); +	return; +} + +static void zebra_show_client_brief(struct vty *vty, struct zserv *client) +{ +	char cbuf[ZEBRA_TIME_BUF], rbuf[ZEBRA_TIME_BUF]; +	char wbuf[ZEBRA_TIME_BUF]; + +	vty_out(vty, "%-8s%12s %12s%12s%8d/%-8d%8d/%-8d%s", +		zebra_route_string(client->proto), +		zserv_time_buf(&client->connect_time, cbuf, ZEBRA_TIME_BUF), +		zserv_time_buf(&client->last_read_time, rbuf, ZEBRA_TIME_BUF), +		zserv_time_buf(&client->last_write_time, wbuf, ZEBRA_TIME_BUF), +		client->v4_route_add_cnt + client->v4_route_upd8_cnt, +		client->v4_route_del_cnt, +		client->v6_route_add_cnt + client->v6_route_upd8_cnt, +		client->v6_route_del_cnt, VTY_NEWLINE); +} + +struct zserv *zebra_find_client(u_char proto) +{ +	struct listnode *node, *nnode; +	struct zserv *client; + +	for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) { +		if (client->proto == proto) +			return client; +	} + +	return NULL;  }  #ifdef HAVE_NETLINK @@ -2738,9 +2672,8 @@ DEFUN (show_table,         SHOW_STR         "default routing table to use for all clients\n")  { -  vty_out (vty, "table %d%s", zebrad.rtm_table_default, -	   VTY_NEWLINE); -  return CMD_SUCCESS; +	vty_out(vty, "table %d%s", zebrad.rtm_table_default, VTY_NEWLINE); +	return CMD_SUCCESS;  }  DEFUN (config_table, @@ -2749,8 +2682,8 @@ DEFUN (config_table,         "Configure target kernel routing table\n"         "TABLE integer\n")  { -  zebrad.rtm_table_default = strtol (argv[1]->arg, (char**)0, 10); -  return CMD_SUCCESS; +	zebrad.rtm_table_default = strtol(argv[1]->arg, (char **)0, 10); +	return CMD_SUCCESS;  }  DEFUN (no_config_table, @@ -2760,8 +2693,8 @@ DEFUN (no_config_table,         "Configure target kernel routing table\n"         "TABLE integer\n")  { -  zebrad.rtm_table_default = 0; -  return CMD_SUCCESS; +	zebrad.rtm_table_default = 0; +	return CMD_SUCCESS;  }  #endif @@ -2771,19 +2704,18 @@ DEFUN (ip_forwarding,         IP_STR         "Turn on IP forwarding")  { -  int ret; +	int ret; -  ret = ipforward (); -  if (ret == 0) -    ret = ipforward_on (); +	ret = ipforward(); +	if (ret == 0) +		ret = ipforward_on(); -  if (ret == 0) -    { -      vty_out (vty, "Can't turn on IP forwarding%s", VTY_NEWLINE); -      return CMD_WARNING; -    } +	if (ret == 0) { +		vty_out(vty, "Can't turn on IP forwarding%s", VTY_NEWLINE); +		return CMD_WARNING; +	} -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (no_ip_forwarding, @@ -2793,19 +2725,18 @@ DEFUN (no_ip_forwarding,         IP_STR         "Turn off IP forwarding")  { -  int ret; +	int ret; -  ret = ipforward (); -  if (ret != 0) -    ret = ipforward_off (); +	ret = ipforward(); +	if (ret != 0) +		ret = ipforward_off(); -  if (ret != 0) -    { -      vty_out (vty, "Can't turn off IP forwarding%s", VTY_NEWLINE); -      return CMD_WARNING; -    } +	if (ret != 0) { +		vty_out(vty, "Can't turn off IP forwarding%s", VTY_NEWLINE); +		return CMD_WARNING; +	} -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  /* This command is for debugging purpose. */ @@ -2816,13 +2747,13 @@ DEFUN (show_zebra_client,         "Zebra information\n"         "Client information\n")  { -  struct listnode *node; -  struct zserv *client; +	struct listnode *node; +	struct zserv *client; -  for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client)) -    zebra_show_client_detail(vty, client); +	for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) +		zebra_show_client_detail(vty, client); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  /* This command is for debugging purpose. */ @@ -2834,38 +2765,37 @@ DEFUN (show_zebra_client_summary,         "Client information brief\n"         "Brief Summary\n")  { -  struct listnode *node; -  struct zserv *client; +	struct listnode *node; +	struct zserv *client; -  vty_out (vty, "Name    Connect Time    Last Read  Last Write  IPv4 Routes       IPv6 Routes    %s", -	   VTY_NEWLINE); -  vty_out (vty,"--------------------------------------------------------------------------------%s", -	   VTY_NEWLINE); +	vty_out(vty, +		"Name    Connect Time    Last Read  Last Write  IPv4 Routes       IPv6 Routes    %s", +		VTY_NEWLINE); +	vty_out(vty, +		"--------------------------------------------------------------------------------%s", +		VTY_NEWLINE); -  for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client)) -    zebra_show_client_brief(vty, client); +	for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) +		zebra_show_client_brief(vty, client); -  vty_out (vty, "Routes column shows (added+updated)/deleted%s", VTY_NEWLINE); -  return CMD_SUCCESS; +	vty_out(vty, "Routes column shows (added+updated)/deleted%s", +		VTY_NEWLINE); +	return CMD_SUCCESS;  }  /* Table configuration write function. */ -static int -config_write_table (struct vty *vty) +static int config_write_table(struct vty *vty)  { -  if (zebrad.rtm_table_default) -    vty_out (vty, "table %d%s", zebrad.rtm_table_default, -	     VTY_NEWLINE); -  return 0; +	if (zebrad.rtm_table_default) +		vty_out(vty, "table %d%s", zebrad.rtm_table_default, +			VTY_NEWLINE); +	return 0;  }  /* table node for routing tables. */ -static struct cmd_node table_node = -{ -  TABLE_NODE, -  "",				/* This node has no interface. */ -  1 -}; +static struct cmd_node table_node = {TABLE_NODE, +				     "", /* This node has no interface. */ +				     1};  /* Only display ip forwarding is enabled or not. */  DEFUN (show_ip_forwarding, @@ -2875,15 +2805,15 @@ DEFUN (show_ip_forwarding,         IP_STR         "IP forwarding status\n")  { -  int ret; +	int ret; -  ret = ipforward (); +	ret = ipforward(); -  if (ret == 0) -    vty_out (vty, "IP forwarding is off%s", VTY_NEWLINE); -  else -    vty_out (vty, "IP forwarding is on%s", VTY_NEWLINE); -  return CMD_SUCCESS; +	if (ret == 0) +		vty_out(vty, "IP forwarding is off%s", VTY_NEWLINE); +	else +		vty_out(vty, "IP forwarding is on%s", VTY_NEWLINE); +	return CMD_SUCCESS;  }  /* Only display ipv6 forwarding is enabled or not. */ @@ -2894,26 +2824,25 @@ DEFUN (show_ipv6_forwarding,         "IPv6 information\n"         "Forwarding status\n")  { -  int ret; +	int ret; -  ret = ipforward_ipv6 (); +	ret = ipforward_ipv6(); -  switch (ret) -    { -    case -1: -      vty_out (vty, "ipv6 forwarding is unknown%s", VTY_NEWLINE); -      break; -    case 0: -      vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE); -      break; -    case 1: -      vty_out (vty, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE); -      break; -    default: -      vty_out (vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE); -      break; -    } -  return CMD_SUCCESS; +	switch (ret) { +	case -1: +		vty_out(vty, "ipv6 forwarding is unknown%s", VTY_NEWLINE); +		break; +	case 0: +		vty_out(vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE); +		break; +	case 1: +		vty_out(vty, "ipv6 forwarding is %s%s", "on", VTY_NEWLINE); +		break; +	default: +		vty_out(vty, "ipv6 forwarding is %s%s", "off", VTY_NEWLINE); +		break; +	} +	return CMD_SUCCESS;  }  DEFUN (ipv6_forwarding, @@ -2922,19 +2851,18 @@ DEFUN (ipv6_forwarding,         IPV6_STR         "Turn on IPv6 forwarding")  { -  int ret; +	int ret; -  ret = ipforward_ipv6 (); -  if (ret == 0) -    ret = ipforward_ipv6_on (); +	ret = ipforward_ipv6(); +	if (ret == 0) +		ret = ipforward_ipv6_on(); -  if (ret == 0) -    { -      vty_out (vty, "Can't turn on IPv6 forwarding%s", VTY_NEWLINE); -      return CMD_WARNING; -    } +	if (ret == 0) { +		vty_out(vty, "Can't turn on IPv6 forwarding%s", VTY_NEWLINE); +		return CMD_WARNING; +	} -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (no_ipv6_forwarding, @@ -2944,82 +2872,75 @@ DEFUN (no_ipv6_forwarding,         IPV6_STR         "Turn off IPv6 forwarding")  { -  int ret; +	int ret; -  ret = ipforward_ipv6 (); -  if (ret != 0) -    ret = ipforward_ipv6_off (); +	ret = ipforward_ipv6(); +	if (ret != 0) +		ret = ipforward_ipv6_off(); -  if (ret != 0) -    { -      vty_out (vty, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE); -      return CMD_WARNING; -    } +	if (ret != 0) { +		vty_out(vty, "Can't turn off IPv6 forwarding%s", VTY_NEWLINE); +		return CMD_WARNING; +	} -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  /* IPForwarding configuration write function. */ -static int -config_write_forwarding (struct vty *vty) +static int config_write_forwarding(struct vty *vty)  { -  /* FIXME: Find better place for that. */ -  router_id_write (vty); +	/* FIXME: Find better place for that. */ +	router_id_write(vty); -  if (!ipforward ()) -    vty_out (vty, "no ip forwarding%s", VTY_NEWLINE); -  if (!ipforward_ipv6 ()) -    vty_out (vty, "no ipv6 forwarding%s", VTY_NEWLINE); -  vty_out (vty, "!%s", VTY_NEWLINE); -  return 0; +	if (!ipforward()) +		vty_out(vty, "no ip forwarding%s", VTY_NEWLINE); +	if (!ipforward_ipv6()) +		vty_out(vty, "no ipv6 forwarding%s", VTY_NEWLINE); +	vty_out(vty, "!%s", VTY_NEWLINE); +	return 0;  }  /* table node for routing tables. */ -static struct cmd_node forwarding_node = -{ -  FORWARDING_NODE, -  "",				/* This node has no interface. */ -  1 -}; +static struct cmd_node forwarding_node = {FORWARDING_NODE, +					  "", /* This node has no interface. */ +					  1};  /* Initialisation of zebra and installation of commands. */ -void -zebra_init (void) +void zebra_init(void)  { -  /* Client list init. */ -  zebrad.client_list = list_new (); +	/* Client list init. */ +	zebrad.client_list = list_new(); -  /* Install configuration write function. */ -  install_node (&table_node, config_write_table); -  install_node (&forwarding_node, config_write_forwarding); +	/* Install configuration write function. */ +	install_node(&table_node, config_write_table); +	install_node(&forwarding_node, config_write_forwarding); -  install_element (VIEW_NODE, &show_ip_forwarding_cmd); -  install_element (CONFIG_NODE, &ip_forwarding_cmd); -  install_element (CONFIG_NODE, &no_ip_forwarding_cmd); -  install_element (ENABLE_NODE, &show_zebra_client_cmd); -  install_element (ENABLE_NODE, &show_zebra_client_summary_cmd); +	install_element(VIEW_NODE, &show_ip_forwarding_cmd); +	install_element(CONFIG_NODE, &ip_forwarding_cmd); +	install_element(CONFIG_NODE, &no_ip_forwarding_cmd); +	install_element(ENABLE_NODE, &show_zebra_client_cmd); +	install_element(ENABLE_NODE, &show_zebra_client_summary_cmd);  #ifdef HAVE_NETLINK -  install_element (VIEW_NODE, &show_table_cmd); -  install_element (CONFIG_NODE, &config_table_cmd); -  install_element (CONFIG_NODE, &no_config_table_cmd); +	install_element(VIEW_NODE, &show_table_cmd); +	install_element(CONFIG_NODE, &config_table_cmd); +	install_element(CONFIG_NODE, &no_config_table_cmd);  #endif /* HAVE_NETLINK */ -  install_element (VIEW_NODE, &show_ipv6_forwarding_cmd); -  install_element (CONFIG_NODE, &ipv6_forwarding_cmd); -  install_element (CONFIG_NODE, &no_ipv6_forwarding_cmd); +	install_element(VIEW_NODE, &show_ipv6_forwarding_cmd); +	install_element(CONFIG_NODE, &ipv6_forwarding_cmd); +	install_element(CONFIG_NODE, &no_ipv6_forwarding_cmd); -  /* Route-map */ -  zebra_route_map_init (); +	/* Route-map */ +	zebra_route_map_init();  }  /* Make zebra server socket, wiping any existing one (see bug #403). */ -void -zebra_zserv_socket_init (char *path) +void zebra_zserv_socket_init(char *path)  {  #ifdef HAVE_TCP_ZEBRA -  zebra_serv (); +	zebra_serv();  #else -  zebra_serv_un (path ? path : ZEBRA_SERV_PATH); +	zebra_serv_un(path ? path : ZEBRA_SERV_PATH);  #endif /* HAVE_TCP_ZEBRA */  } diff --git a/zebra/zserv.h b/zebra/zserv.h index 42e762caa3..ccb3c9dabc 100644 --- a/zebra/zserv.h +++ b/zebra/zserv.h @@ -16,7 +16,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #ifndef _ZEBRA_ZSERV_H @@ -42,144 +42,143 @@  #define ZEBRA_RMAP_DEFAULT_UPDATE_TIMER 5 /* disabled by default */  /* Client structure. */ -struct zserv -{ -  /* Client file descriptor. */ -  int sock; - -  /* Input/output buffer to the client. */ -  struct stream *ibuf; -  struct stream *obuf; - -  /* Buffer of data waiting to be written to client. */ -  struct buffer *wb; - -  /* Threads for read/write. */ -  struct thread *t_read; -  struct thread *t_write; - -  /* Thread for delayed close. */ -  struct thread *t_suicide; - -  /* default routing table this client munges */ -  int rtm_table; - -  /* This client's redistribute flag. */ -  struct redist_proto mi_redist[AFI_MAX][ZEBRA_ROUTE_MAX]; -  vrf_bitmap_t redist[AFI_MAX][ZEBRA_ROUTE_MAX]; - -  /* Redistribute default route flag. */ -  vrf_bitmap_t redist_default; - -  /* Interface information. */ -  vrf_bitmap_t ifinfo; - -  /* Router-id information. */ -  vrf_bitmap_t ridinfo; - -  /* client's protocol */ -  u_char proto; -  u_short instance; -  u_char is_synchronous; - -  /* Statistics */ -  u_int32_t redist_v4_add_cnt; -  u_int32_t redist_v4_del_cnt; -  u_int32_t redist_v6_add_cnt; -  u_int32_t redist_v6_del_cnt; -  u_int32_t v4_route_add_cnt; -  u_int32_t v4_route_upd8_cnt; -  u_int32_t v4_route_del_cnt; -  u_int32_t v6_route_add_cnt; -  u_int32_t v6_route_del_cnt; -  u_int32_t v6_route_upd8_cnt; -  u_int32_t connected_rt_add_cnt; -  u_int32_t connected_rt_del_cnt; -  u_int32_t ifup_cnt; -  u_int32_t ifdown_cnt; -  u_int32_t ifadd_cnt; -  u_int32_t ifdel_cnt; -  u_int32_t if_bfd_cnt; -  u_int32_t bfd_peer_add_cnt; -  u_int32_t bfd_peer_upd8_cnt; -  u_int32_t bfd_peer_del_cnt; -  u_int32_t bfd_peer_replay_cnt; -  u_int32_t vrfadd_cnt; -  u_int32_t vrfdel_cnt; -  u_int32_t if_vrfchg_cnt; -  u_int32_t bfd_client_reg_cnt; - -  time_t connect_time; -  time_t last_read_time; -  time_t last_write_time; -  time_t nh_reg_time; -  time_t nh_dereg_time; -  time_t nh_last_upd_time; - -  int last_read_cmd; -  int last_write_cmd; +struct zserv { +	/* Client file descriptor. */ +	int sock; + +	/* Input/output buffer to the client. */ +	struct stream *ibuf; +	struct stream *obuf; + +	/* Buffer of data waiting to be written to client. */ +	struct buffer *wb; + +	/* Threads for read/write. */ +	struct thread *t_read; +	struct thread *t_write; + +	/* Thread for delayed close. */ +	struct thread *t_suicide; + +	/* default routing table this client munges */ +	int rtm_table; + +	/* This client's redistribute flag. */ +	struct redist_proto mi_redist[AFI_MAX][ZEBRA_ROUTE_MAX]; +	vrf_bitmap_t redist[AFI_MAX][ZEBRA_ROUTE_MAX]; + +	/* Redistribute default route flag. */ +	vrf_bitmap_t redist_default; + +	/* Interface information. */ +	vrf_bitmap_t ifinfo; + +	/* Router-id information. */ +	vrf_bitmap_t ridinfo; + +	/* client's protocol */ +	u_char proto; +	u_short instance; +	u_char is_synchronous; + +	/* Statistics */ +	u_int32_t redist_v4_add_cnt; +	u_int32_t redist_v4_del_cnt; +	u_int32_t redist_v6_add_cnt; +	u_int32_t redist_v6_del_cnt; +	u_int32_t v4_route_add_cnt; +	u_int32_t v4_route_upd8_cnt; +	u_int32_t v4_route_del_cnt; +	u_int32_t v6_route_add_cnt; +	u_int32_t v6_route_del_cnt; +	u_int32_t v6_route_upd8_cnt; +	u_int32_t connected_rt_add_cnt; +	u_int32_t connected_rt_del_cnt; +	u_int32_t ifup_cnt; +	u_int32_t ifdown_cnt; +	u_int32_t ifadd_cnt; +	u_int32_t ifdel_cnt; +	u_int32_t if_bfd_cnt; +	u_int32_t bfd_peer_add_cnt; +	u_int32_t bfd_peer_upd8_cnt; +	u_int32_t bfd_peer_del_cnt; +	u_int32_t bfd_peer_replay_cnt; +	u_int32_t vrfadd_cnt; +	u_int32_t vrfdel_cnt; +	u_int32_t if_vrfchg_cnt; +	u_int32_t bfd_client_reg_cnt; + +	time_t connect_time; +	time_t last_read_time; +	time_t last_write_time; +	time_t nh_reg_time; +	time_t nh_dereg_time; +	time_t nh_last_upd_time; + +	int last_read_cmd; +	int last_write_cmd;  };  /* Zebra instance */ -struct zebra_t -{ -  /* Thread master */ -  struct thread_master *master; -  struct list *client_list; +struct zebra_t { +	/* Thread master */ +	struct thread_master *master; +	struct list *client_list; -  /* default table */ -  u_int32_t rtm_table_default; +	/* default table */ +	u_int32_t rtm_table_default; -  /* rib work queue */ -  struct work_queue *ribq; -  struct meta_queue *mq; +	/* rib work queue */ +	struct work_queue *ribq; +	struct meta_queue *mq; -  /* LSP work queue */ -  struct work_queue *lsp_process_q; +	/* LSP work queue */ +	struct work_queue *lsp_process_q;  };  extern struct zebra_t zebrad;  extern unsigned int multipath_num;  /* Prototypes. */ -extern void zebra_init (void); -extern void zebra_if_init (void); -extern void zebra_zserv_socket_init (char *path); -extern void hostinfo_get (void); -extern void rib_init (void); -extern void interface_list (struct zebra_ns *); -extern void route_read (struct zebra_ns *); -extern void kernel_init (struct zebra_ns *); -extern void kernel_terminate (struct zebra_ns *); -extern void zebra_route_map_init (void); -extern void zebra_vty_init (void); - -extern int zsend_vrf_add (struct zserv *, struct zebra_vrf *); -extern int zsend_vrf_delete (struct zserv *, struct zebra_vrf *); - -extern int zsend_interface_add (struct zserv *, struct interface *); -extern int zsend_interface_delete (struct zserv *, struct interface *); -extern int zsend_interface_addresses (struct zserv *, struct interface *); -extern int zsend_interface_address (int, struct zserv *, struct interface *, -                                    struct connected *); -extern void nbr_connected_add_ipv6 (struct interface *, struct in6_addr *); -extern void nbr_connected_delete_ipv6 (struct interface *, struct in6_addr *); -extern int zsend_interface_update (int, struct zserv *, struct interface *); -extern int zsend_redistribute_route (int, struct zserv *, struct prefix *, -                                     struct prefix *, struct rib *); -extern int zsend_router_id_update (struct zserv *, struct prefix *, -                                   vrf_id_t); -extern int zsend_interface_vrf_update (struct zserv *, struct interface *, -                                       vrf_id_t); - -extern int zsend_interface_link_params (struct zserv *, struct interface *); -extern int zsend_pw_update (struct zserv *, struct zebra_pw *); +extern void zebra_init(void); +extern void zebra_if_init(void); +extern void zebra_zserv_socket_init(char *path); +extern void hostinfo_get(void); +extern void rib_init(void); +extern void interface_list(struct zebra_ns *); +extern void route_read(struct zebra_ns *); +extern void kernel_init(struct zebra_ns *); +extern void kernel_terminate(struct zebra_ns *); +extern void zebra_route_map_init(void); +extern void zebra_vty_init(void); + +extern int zsend_vrf_add(struct zserv *, struct zebra_vrf *); +extern int zsend_vrf_delete(struct zserv *, struct zebra_vrf *); + +extern int zsend_interface_add(struct zserv *, struct interface *); +extern int zsend_interface_delete(struct zserv *, struct interface *); +extern int zsend_interface_addresses(struct zserv *, struct interface *); +extern int zsend_interface_address(int, struct zserv *, struct interface *, +				   struct connected *); +extern void nbr_connected_add_ipv6(struct interface *, struct in6_addr *); +extern void nbr_connected_delete_ipv6(struct interface *, struct in6_addr *); +extern int zsend_interface_update(int, struct zserv *, struct interface *); +extern int zsend_redistribute_route(int, struct zserv *, struct prefix *, +				    struct prefix *, struct rib *); +extern int zsend_router_id_update(struct zserv *, struct prefix *, vrf_id_t); +extern int zsend_interface_vrf_update(struct zserv *, struct interface *, +				      vrf_id_t); + +extern int zsend_interface_link_params(struct zserv *, struct interface *); +extern int zsend_pw_update(struct zserv *, struct zebra_pw *);  extern pid_t pid; -extern void zserv_create_header(struct stream *s, uint16_t cmd, vrf_id_t vrf_id); -extern void zserv_nexthop_num_warn(const char *, const struct prefix *, const unsigned int); +extern void zserv_create_header(struct stream *s, uint16_t cmd, +				vrf_id_t vrf_id); +extern void zserv_nexthop_num_warn(const char *, const struct prefix *, +				   const unsigned int);  extern int zebra_server_send_message(struct zserv *client); -extern struct zserv *zebra_find_client (u_char proto); +extern struct zserv *zebra_find_client(u_char proto);  #endif /* _ZEBRA_ZEBRA_H */ diff --git a/zebra/zserv_null.c b/zebra/zserv_null.c index 4b52abb222..661554486f 100644 --- a/zebra/zserv_null.c +++ b/zebra/zserv_null.c @@ -30,11 +30,17 @@  #include <zebra_vrf.h>  #include <router-id.h> -int zsend_vrf_delete (struct zserv *zserv, struct zebra_vrf *zvrf) -{ return 0; } +int zsend_vrf_delete(struct zserv *zserv, struct zebra_vrf *zvrf) +{ +	return 0; +} -int zsend_vrf_add (struct zserv *zserv, struct zebra_vrf *zvrf) -{ return 0; } +int zsend_vrf_add(struct zserv *zserv, struct zebra_vrf *zvrf) +{ +	return 0; +} -void router_id_init (struct zebra_vrf *zvrf) -{ return; } +void router_id_init(struct zebra_vrf *zvrf) +{ +	return; +}  | 
