diff options
| author | whitespace / reindent <invalid@invalid.invalid> | 2017-07-17 14:03:14 +0200 | 
|---|---|---|
| committer | whitespace / reindent <invalid@invalid.invalid> | 2017-07-17 14:04:07 +0200 | 
| commit | d62a17aedeb0eebdba98238874bb13d62c48dbf9 (patch) | |
| tree | 3b319b1d61c8b85b4d1f06adf8b844bb8a9b5107 /bgpd/rfapi | |
| parent | 888ac268a0077fc9ebd1218cec6ae472af0bfc40 (diff) | |
*: reindentreindent-master-after
indent.py `git ls-files | pcregrep '\.[ch]$' | pcregrep -v '^(ldpd|babeld|nhrpd)/'`
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'bgpd/rfapi')
34 files changed, 26046 insertions, 28472 deletions
diff --git a/bgpd/rfapi/bgp_rfapi_cfg.c b/bgpd/rfapi/bgp_rfapi_cfg.c index d04b186dff..8a93d3984e 100644 --- a/bgpd/rfapi/bgp_rfapi_cfg.c +++ b/bgpd/rfapi/bgp_rfapi_cfg.c @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2009-2016, LabN Consulting, L.L.C.   * @@ -52,32 +52,32 @@  DEFINE_MGROUP(RFAPI, "rfapi") -DEFINE_MTYPE(RFAPI, RFAPI_CFG,			  "NVE Configuration") -DEFINE_MTYPE(RFAPI, RFAPI_GROUP_CFG,		  "NVE Group Configuration") -DEFINE_MTYPE(RFAPI, RFAPI_L2_CFG,		  "RFAPI L2 Group Configuration") -DEFINE_MTYPE(RFAPI, RFAPI_RFP_GROUP_CFG,	  "RFAPI RFP Group Configuration") -DEFINE_MTYPE(RFAPI, RFAPI,			  "RFAPI Generic") -DEFINE_MTYPE(RFAPI, RFAPI_DESC,			  "RFAPI Descriptor") -DEFINE_MTYPE(RFAPI, RFAPI_IMPORTTABLE,		  "RFAPI Import Table") -DEFINE_MTYPE(RFAPI, RFAPI_MONITOR,		  "RFAPI Monitor VPN") -DEFINE_MTYPE(RFAPI, RFAPI_MONITOR_ENCAP,	  "RFAPI Monitor Encap") -DEFINE_MTYPE(RFAPI, RFAPI_NEXTHOP,		  "RFAPI Next Hop") -DEFINE_MTYPE(RFAPI, RFAPI_VN_OPTION,		  "RFAPI VN Option") -DEFINE_MTYPE(RFAPI, RFAPI_UN_OPTION,		  "RFAPI UN Option") -DEFINE_MTYPE(RFAPI, RFAPI_WITHDRAW,		  "RFAPI Withdraw") -DEFINE_MTYPE(RFAPI, RFAPI_RFG_NAME,		  "RFAPI RFGName") -DEFINE_MTYPE(RFAPI, RFAPI_ADB,			  "RFAPI Advertisement Data") -DEFINE_MTYPE(RFAPI, RFAPI_ETI,			  "RFAPI Export Table Info") -DEFINE_MTYPE(RFAPI, RFAPI_NVE_ADDR,		  "RFAPI NVE Address") -DEFINE_MTYPE(RFAPI, RFAPI_PREFIX_BAG,		  "RFAPI Prefix Bag") -DEFINE_MTYPE(RFAPI, RFAPI_IT_EXTRA,		  "RFAPI IT Extra") -DEFINE_MTYPE(RFAPI, RFAPI_INFO,			  "RFAPI Info") -DEFINE_MTYPE(RFAPI, RFAPI_ADDR,			  "RFAPI Addr") +DEFINE_MTYPE(RFAPI, RFAPI_CFG, "NVE Configuration") +DEFINE_MTYPE(RFAPI, RFAPI_GROUP_CFG, "NVE Group Configuration") +DEFINE_MTYPE(RFAPI, RFAPI_L2_CFG, "RFAPI L2 Group Configuration") +DEFINE_MTYPE(RFAPI, RFAPI_RFP_GROUP_CFG, "RFAPI RFP Group Configuration") +DEFINE_MTYPE(RFAPI, RFAPI, "RFAPI Generic") +DEFINE_MTYPE(RFAPI, RFAPI_DESC, "RFAPI Descriptor") +DEFINE_MTYPE(RFAPI, RFAPI_IMPORTTABLE, "RFAPI Import Table") +DEFINE_MTYPE(RFAPI, RFAPI_MONITOR, "RFAPI Monitor VPN") +DEFINE_MTYPE(RFAPI, RFAPI_MONITOR_ENCAP, "RFAPI Monitor Encap") +DEFINE_MTYPE(RFAPI, RFAPI_NEXTHOP, "RFAPI Next Hop") +DEFINE_MTYPE(RFAPI, RFAPI_VN_OPTION, "RFAPI VN Option") +DEFINE_MTYPE(RFAPI, RFAPI_UN_OPTION, "RFAPI UN Option") +DEFINE_MTYPE(RFAPI, RFAPI_WITHDRAW, "RFAPI Withdraw") +DEFINE_MTYPE(RFAPI, RFAPI_RFG_NAME, "RFAPI RFGName") +DEFINE_MTYPE(RFAPI, RFAPI_ADB, "RFAPI Advertisement Data") +DEFINE_MTYPE(RFAPI, RFAPI_ETI, "RFAPI Export Table Info") +DEFINE_MTYPE(RFAPI, RFAPI_NVE_ADDR, "RFAPI NVE Address") +DEFINE_MTYPE(RFAPI, RFAPI_PREFIX_BAG, "RFAPI Prefix Bag") +DEFINE_MTYPE(RFAPI, RFAPI_IT_EXTRA, "RFAPI IT Extra") +DEFINE_MTYPE(RFAPI, RFAPI_INFO, "RFAPI Info") +DEFINE_MTYPE(RFAPI, RFAPI_ADDR, "RFAPI Addr")  DEFINE_MTYPE(RFAPI, RFAPI_UPDATED_RESPONSE_QUEUE, "RFAPI Updated Rsp Queue") -DEFINE_MTYPE(RFAPI, RFAPI_RECENT_DELETE,	  "RFAPI Recently Deleted Route") -DEFINE_MTYPE(RFAPI, RFAPI_L2ADDR_OPT,		  "RFAPI L2 Address Option") -DEFINE_MTYPE(RFAPI, RFAPI_AP,			  "RFAPI Advertised Prefix") -DEFINE_MTYPE(RFAPI, RFAPI_MONITOR_ETH,		  "RFAPI Monitor Ethernet") +DEFINE_MTYPE(RFAPI, RFAPI_RECENT_DELETE, "RFAPI Recently Deleted Route") +DEFINE_MTYPE(RFAPI, RFAPI_L2ADDR_OPT, "RFAPI L2 Address Option") +DEFINE_MTYPE(RFAPI, RFAPI_AP, "RFAPI Advertised Prefix") +DEFINE_MTYPE(RFAPI, RFAPI_MONITOR_ETH, "RFAPI Monitor Ethernet")  DEFINE_QOBJ_TYPE(rfapi_nve_group_cfg)  DEFINE_QOBJ_TYPE(rfapi_l2_group_cfg) @@ -86,139 +86,127 @@ DEFINE_QOBJ_TYPE(rfapi_l2_group_cfg)   ***********************************************************************/ -/*  +/*   * compaitibility to old quagga_time call - * time_t value in terms of stabilised absolute time.  + * time_t value in terms of stabilised absolute time.   * replacement for POSIX time()   */ -time_t  -rfapi_time (time_t *t) +time_t rfapi_time(time_t *t)  { -  time_t clock = bgp_clock(); -  if (t) -    *t = clock; -  return clock; +	time_t clock = bgp_clock(); +	if (t) +		*t = clock; +	return clock;  } -void -nve_group_to_nve_list ( -  struct rfapi_nve_group_cfg	*rfg, -  struct list			**nves, -  uint8_t			family)     /* AF_INET, AF_INET6 */ +void nve_group_to_nve_list(struct rfapi_nve_group_cfg *rfg, struct list **nves, +			   uint8_t family) /* AF_INET, AF_INET6 */  { -  struct listnode *hln; -  struct rfapi_descriptor *rfd; - -  /* -   * loop over nves in this grp, add to list -   */ -  for (ALL_LIST_ELEMENTS_RO (rfg->nves, hln, rfd)) -    { -      if (rfd->vn_addr.addr_family == family) -        { -          if (!*nves) -            *nves = list_new (); -          listnode_add (*nves, rfd); -        } -    } +	struct listnode *hln; +	struct rfapi_descriptor *rfd; + +	/* +	 * loop over nves in this grp, add to list +	 */ +	for (ALL_LIST_ELEMENTS_RO(rfg->nves, hln, rfd)) { +		if (rfd->vn_addr.addr_family == family) { +			if (!*nves) +				*nves = list_new(); +			listnode_add(*nves, rfd); +		} +	}  } -struct rfapi_nve_group_cfg * -bgp_rfapi_cfg_match_group ( -  struct rfapi_cfg	*hc, -  struct prefix		*vn, -  struct prefix		*un) +struct rfapi_nve_group_cfg *bgp_rfapi_cfg_match_group(struct rfapi_cfg *hc, +						      struct prefix *vn, +						      struct prefix *un)  { -  struct rfapi_nve_group_cfg *rfg_vn = NULL; -  struct rfapi_nve_group_cfg *rfg_un = NULL; - -  struct route_table *rt_vn; -  struct route_table *rt_un; -  struct route_node *rn_vn; -  struct route_node *rn_un; - -  struct rfapi_nve_group_cfg *rfg; -  struct listnode *node, *nnode; - -  switch (vn->family) -    { -    case AF_INET: -      rt_vn = &(hc->nve_groups_vn[AFI_IP]); -      break; -    case AF_INET6: -      rt_vn = &(hc->nve_groups_vn[AFI_IP6]); -      break; -    default: -      return NULL; -    } - -  switch (un->family) -    { -    case AF_INET: -      rt_un = &(hc->nve_groups_un[AFI_IP]); -      break; -    case AF_INET6: -      rt_un = &(hc->nve_groups_un[AFI_IP6]); -      break; -    default: -      return NULL; -    } - -  rn_vn = route_node_match (rt_vn, vn); /* NB locks node */ -  if (rn_vn) -    { -      rfg_vn = rn_vn->info; -      route_unlock_node (rn_vn); -    } - -  rn_un = route_node_match (rt_un, un); /* NB locks node */ -  if (rn_un) -    { -      rfg_un = rn_un->info; -      route_unlock_node (rn_un); -    } +	struct rfapi_nve_group_cfg *rfg_vn = NULL; +	struct rfapi_nve_group_cfg *rfg_un = NULL; + +	struct route_table *rt_vn; +	struct route_table *rt_un; +	struct route_node *rn_vn; +	struct route_node *rn_un; + +	struct rfapi_nve_group_cfg *rfg; +	struct listnode *node, *nnode; + +	switch (vn->family) { +	case AF_INET: +		rt_vn = &(hc->nve_groups_vn[AFI_IP]); +		break; +	case AF_INET6: +		rt_vn = &(hc->nve_groups_vn[AFI_IP6]); +		break; +	default: +		return NULL; +	} + +	switch (un->family) { +	case AF_INET: +		rt_un = &(hc->nve_groups_un[AFI_IP]); +		break; +	case AF_INET6: +		rt_un = &(hc->nve_groups_un[AFI_IP6]); +		break; +	default: +		return NULL; +	} + +	rn_vn = route_node_match(rt_vn, vn); /* NB locks node */ +	if (rn_vn) { +		rfg_vn = rn_vn->info; +		route_unlock_node(rn_vn); +	} + +	rn_un = route_node_match(rt_un, un); /* NB locks node */ +	if (rn_un) { +		rfg_un = rn_un->info; +		route_unlock_node(rn_un); +	}  #if BGP_VNC_DEBUG_MATCH_GROUP -  { -    char buf[BUFSIZ]; +	{ +		char buf[BUFSIZ]; -    prefix2str (vn, buf, BUFSIZ); -    vnc_zlog_debug_verbose ("%s: vn prefix: %s", __func__, buf); +		prefix2str(vn, buf, BUFSIZ); +		vnc_zlog_debug_verbose("%s: vn prefix: %s", __func__, buf); -    prefix2str (un, buf, BUFSIZ); -    vnc_zlog_debug_verbose ("%s: un prefix: %s", __func__, buf); +		prefix2str(un, buf, BUFSIZ); +		vnc_zlog_debug_verbose("%s: un prefix: %s", __func__, buf); -    vnc_zlog_debug_verbose ("%s: rn_vn=%p, rn_un=%p, rfg_vn=%p, rfg_un=%p", -                __func__, rn_vn, rn_un, rfg_vn, rfg_un); -  } +		vnc_zlog_debug_verbose( +			"%s: rn_vn=%p, rn_un=%p, rfg_vn=%p, rfg_un=%p", +			__func__, rn_vn, rn_un, rfg_vn, rfg_un); +	}  #endif -  if (rfg_un == rfg_vn)         /* same group */ -    return rfg_un; -  if (!rfg_un)                  /* un doesn't match, return vn-matched grp */ -    return rfg_vn; -  if (!rfg_vn)                  /* vn doesn't match, return un-matched grp */ -    return rfg_un; - -  /*  -   * Two different nve groups match: the group configured earlier wins. -   * For now, just walk the sequential list and pick the first one. -   * If this approach is too slow, then store serial numbers in the -   * nve group structures as they are defined and just compare -   * serial numbers. -   */ -  for (ALL_LIST_ELEMENTS (hc->nve_groups_sequential, node, nnode, rfg)) -    { -      if ((rfg == rfg_un) || (rfg == rfg_vn)) -        { -          return rfg; -        } -    } -  vnc_zlog_debug_verbose ("%s: shouldn't happen, returning NULL when un and vn match", -              __func__); -  return NULL;                  /* shouldn't happen */ +	if (rfg_un == rfg_vn) /* same group */ +		return rfg_un; +	if (!rfg_un) /* un doesn't match, return vn-matched grp */ +		return rfg_vn; +	if (!rfg_vn) /* vn doesn't match, return un-matched grp */ +		return rfg_un; + +	/* +	 * Two different nve groups match: the group configured earlier wins. +	 * For now, just walk the sequential list and pick the first one. +	 * If this approach is too slow, then store serial numbers in the +	 * nve group structures as they are defined and just compare +	 * serial numbers. +	 */ +	for (ALL_LIST_ELEMENTS(hc->nve_groups_sequential, node, nnode, rfg)) { +		if ((rfg == rfg_un) || (rfg == rfg_vn)) { +			return rfg; +		} +	} +	vnc_zlog_debug_verbose( +		"%s: shouldn't happen, returning NULL when un and vn match", +		__func__); +	return NULL; /* shouldn't happen */  }  /*------------------------------------------ @@ -230,15 +218,14 @@ bgp_rfapi_cfg_match_group (   *	void *		bgp structure   *   * returns: - *	void *           + *	void *   *------------------------------------------*/ -void * -rfapi_get_rfp_start_val (void *bgpv) +void *rfapi_get_rfp_start_val(void *bgpv)  { -  struct bgp *bgp = bgpv; -  if (bgp == NULL || bgp->rfapi == NULL) -    return NULL; -  return bgp->rfapi->rfp; +	struct bgp *bgp = bgpv; +	if (bgp == NULL || bgp->rfapi == NULL) +		return NULL; +	return bgp->rfapi->rfp;  }  /*------------------------------------------ @@ -246,7 +233,7 @@ rfapi_get_rfp_start_val (void *bgpv)   *   * Returns if VNC (BGP VPN messaging /VPN & encap SAFIs) are configured   * - * input:  + * input:   *    bgp        NULL (=use default instance)   *   * output: @@ -255,32 +242,28 @@ rfapi_get_rfp_start_val (void *bgpv)   *	0		Success   *	ENXIO		VNC not configured   --------------------------------------------*/ -int -bgp_rfapi_is_vnc_configured (struct bgp *bgp) +int bgp_rfapi_is_vnc_configured(struct bgp *bgp)  { -  if (bgp == NULL) -    bgp = bgp_get_default (); - -  if (bgp && bgp->rfapi_cfg) -    { -      struct peer *peer; -      struct peer_group *group; -      struct listnode *node, *nnode; -      /* if have configured VPN neighbors, assume running VNC */ -      for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group)) -        { -          if (group->conf->afc[AFI_IP][SAFI_MPLS_VPN] || -              group->conf->afc[AFI_IP6][SAFI_MPLS_VPN]) -            return 0; -        } -      for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer)) -        { -          if (peer->afc[AFI_IP][SAFI_MPLS_VPN] || -              peer->afc[AFI_IP6][SAFI_MPLS_VPN]) -            return 0; -        } -    } -  return ENXIO; +	if (bgp == NULL) +		bgp = bgp_get_default(); + +	if (bgp && bgp->rfapi_cfg) { +		struct peer *peer; +		struct peer_group *group; +		struct listnode *node, *nnode; +		/* if have configured VPN neighbors, assume running VNC */ +		for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) { +			if (group->conf->afc[AFI_IP][SAFI_MPLS_VPN] +			    || group->conf->afc[AFI_IP6][SAFI_MPLS_VPN]) +				return 0; +		} +		for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { +			if (peer->afc[AFI_IP][SAFI_MPLS_VPN] +			    || peer->afc[AFI_IP6][SAFI_MPLS_VPN]) +				return 0; +		} +	} +	return ENXIO;  }  /*********************************************************************** @@ -295,25 +278,21 @@ DEFUN (vnc_advertise_un_method,         "Method of advertising UN addresses\n"         "Via Tunnel Encap attribute (in VPN SAFI)\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); +	VTY_DECLVAR_CONTEXT(bgp, bgp); -  if (!bgp->rfapi_cfg) -    { -      vty_out (vty, "VNC not configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } +	if (!bgp->rfapi_cfg) { +		vty_out(vty, "VNC not configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} -  if (!strncmp (argv[2]->arg, "encap-safi", 7)) -    { -      bgp->rfapi_cfg->flags |= BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP; -    } -  else -    { -      bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP; -    } +	if (!strncmp(argv[2]->arg, "encap-safi", 7)) { +		bgp->rfapi_cfg->flags |= BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP; +	} else { +		bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP; +	} -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  /*------------------------------------------------------------------------- @@ -325,50 +304,41 @@ DEFUN_NOSH (vnc_defaults,         vnc_defaults_cmd,         "vnc defaults", VNC_CONFIG_STR "Configure default NVE group\n")  { -  vty->node = BGP_VNC_DEFAULTS_NODE; -  return CMD_SUCCESS; +	vty->node = BGP_VNC_DEFAULTS_NODE; +	return CMD_SUCCESS;  } -static int -set_ecom_list ( -  struct vty		*vty, -  int			argc, -  struct cmd_token	**argv, -  struct ecommunity	**list) +static int set_ecom_list(struct vty *vty, int argc, struct cmd_token **argv, +			 struct ecommunity **list)  { -  struct ecommunity *ecom = NULL; -  struct ecommunity *ecomadd; - -  for (; argc; --argc, ++argv) -    { - -      ecomadd = ecommunity_str2com (argv[0]->arg, ECOMMUNITY_ROUTE_TARGET, 0); -      if (!ecomadd) -        { -          vty_out (vty, "Malformed community-list value\n"); -          if (ecom) -            ecommunity_free (&ecom); -          return CMD_WARNING_CONFIG_FAILED; -        } - -      if (ecom) -        { -          ecommunity_merge (ecom, ecomadd); -          ecommunity_free (&ecomadd); -        } -      else -        { -          ecom = ecomadd; -        } -    } - -  if (*list) -    { -      ecommunity_free (&*list); -    } -  *list = ecom; - -  return CMD_SUCCESS; +	struct ecommunity *ecom = NULL; +	struct ecommunity *ecomadd; + +	for (; argc; --argc, ++argv) { + +		ecomadd = ecommunity_str2com(argv[0]->arg, +					     ECOMMUNITY_ROUTE_TARGET, 0); +		if (!ecomadd) { +			vty_out(vty, "Malformed community-list value\n"); +			if (ecom) +				ecommunity_free(&ecom); +			return CMD_WARNING_CONFIG_FAILED; +		} + +		if (ecom) { +			ecommunity_merge(ecom, ecomadd); +			ecommunity_free(&ecomadd); +		} else { +			ecom = ecomadd; +		} +	} + +	if (*list) { +		ecommunity_free(&*list); +	} +	*list = ecom; + +	return CMD_SUCCESS;  }  DEFUN (vnc_defaults_rt_import, @@ -378,9 +348,9 @@ DEFUN (vnc_defaults_rt_import,         "Import filter\n"         "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  return set_ecom_list (vty, argc - 2, argv + 2, -                        &bgp->rfapi_cfg->default_rt_import_list); +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	return set_ecom_list(vty, argc - 2, argv + 2, +			     &bgp->rfapi_cfg->default_rt_import_list);  }  DEFUN (vnc_defaults_rt_export, @@ -390,9 +360,9 @@ DEFUN (vnc_defaults_rt_export,         "Export filter\n"         "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  return set_ecom_list (vty, argc - 2, argv + 2, -                        &bgp->rfapi_cfg->default_rt_export_list); +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	return set_ecom_list(vty, argc - 2, argv + 2, +			     &bgp->rfapi_cfg->default_rt_export_list);  }  DEFUN (vnc_defaults_rt_both, @@ -402,15 +372,15 @@ DEFUN (vnc_defaults_rt_both,         "Export+import filters\n"         "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  int rc; - -  rc = set_ecom_list (vty, argc - 2, argv + 2, -                      &bgp->rfapi_cfg->default_rt_import_list); -  if (rc != CMD_SUCCESS) -    return rc; -  return set_ecom_list (vty, argc - 2, argv + 2, -                        &bgp->rfapi_cfg->default_rt_export_list); +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	int rc; + +	rc = set_ecom_list(vty, argc - 2, argv + 2, +			   &bgp->rfapi_cfg->default_rt_import_list); +	if (rc != CMD_SUCCESS) +		return rc; +	return set_ecom_list(vty, argc - 2, argv + 2, +			     &bgp->rfapi_cfg->default_rt_export_list);  }  DEFUN (vnc_defaults_rd, @@ -419,54 +389,48 @@ DEFUN (vnc_defaults_rd,         "Specify default route distinguisher\n"         "Route Distinguisher (<as-number>:<number> | <ip-address>:<number> | auto:vn:<number> )\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  int ret; -  struct prefix_rd prd; - -  if (!strncmp (argv[1]->arg, "auto:vn:", 8)) -    { -      /* -       * use AF_UNIX to designate automatically-assigned RD -       * auto:vn:nn where nn is a 2-octet quantity -       */ -      char *end = NULL; -      uint32_t value32 = strtoul (argv[1]->arg + 8, &end, 10); -      uint16_t value = value32 & 0xffff; - -      if (!argv[1]->arg[8] || *end) -        { -          vty_out (vty, "%% Malformed rd\n"); -          return CMD_WARNING_CONFIG_FAILED; -        } -      if (value32 > 0xffff) -        { -          vty_out (vty, "%% Malformed rd (must be less than %u\n", -                   0x0ffff); -          return CMD_WARNING_CONFIG_FAILED; -        } - -      memset (&prd, 0, sizeof (prd)); -      prd.family = AF_UNIX; -      prd.prefixlen = 64; -      prd.val[0] = (RD_TYPE_IP >> 8) & 0x0ff; -      prd.val[1] = RD_TYPE_IP & 0x0ff; -      prd.val[6] = (value >> 8) & 0x0ff; -      prd.val[7] = value & 0x0ff; - -    } -  else -    { - -      ret = str2prefix_rd (argv[1]->arg, &prd); -      if (!ret) -        { -          vty_out (vty, "%% Malformed rd\n"); -          return CMD_WARNING_CONFIG_FAILED; -        } -    } - -  bgp->rfapi_cfg->default_rd = prd; -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	int ret; +	struct prefix_rd prd; + +	if (!strncmp(argv[1]->arg, "auto:vn:", 8)) { +		/* +		 * use AF_UNIX to designate automatically-assigned RD +		 * auto:vn:nn where nn is a 2-octet quantity +		 */ +		char *end = NULL; +		uint32_t value32 = strtoul(argv[1]->arg + 8, &end, 10); +		uint16_t value = value32 & 0xffff; + +		if (!argv[1]->arg[8] || *end) { +			vty_out(vty, "%% Malformed rd\n"); +			return CMD_WARNING_CONFIG_FAILED; +		} +		if (value32 > 0xffff) { +			vty_out(vty, "%% Malformed rd (must be less than %u\n", +				0x0ffff); +			return CMD_WARNING_CONFIG_FAILED; +		} + +		memset(&prd, 0, sizeof(prd)); +		prd.family = AF_UNIX; +		prd.prefixlen = 64; +		prd.val[0] = (RD_TYPE_IP >> 8) & 0x0ff; +		prd.val[1] = RD_TYPE_IP & 0x0ff; +		prd.val[6] = (value >> 8) & 0x0ff; +		prd.val[7] = value & 0x0ff; + +	} else { + +		ret = str2prefix_rd(argv[1]->arg, &prd); +		if (!ret) { +			vty_out(vty, "%% Malformed rd\n"); +			return CMD_WARNING_CONFIG_FAILED; +		} +	} + +	bgp->rfapi_cfg->default_rd = prd; +	return CMD_SUCCESS;  }  DEFUN (vnc_defaults_l2rd, @@ -476,36 +440,32 @@ DEFUN (vnc_defaults_l2rd,         "Fixed value 1-255\n"         "use the low-order octet of the NVE's VN address\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  uint8_t value = 0; - -  if (strmatch(argv[1]->text, "auto-vn")) -    { -      value = 0; -    } -  else -    { -      char *end = NULL; -      unsigned long value_l = strtoul (argv[1]->arg, &end, 10); - -      value = value_l & 0xff; -      if (!argv[1]->arg[0] || *end) -        { -          vty_out (vty, "%% Malformed l2 nve ID \"%s\"\n",argv[1]->arg); -          return CMD_WARNING_CONFIG_FAILED; -        } -      if ((value_l < 1) || (value_l > 0xff)) -        { -          vty_out (vty, -                   "%% Malformed l2 nve id (must be greater than 0 and less than %u\n", -                   0x100); -          return CMD_WARNING_CONFIG_FAILED; -        } -    } -  bgp->rfapi_cfg->flags |= BGP_VNC_CONFIG_L2RD; -  bgp->rfapi_cfg->default_l2rd = value; - -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	uint8_t value = 0; + +	if (strmatch(argv[1]->text, "auto-vn")) { +		value = 0; +	} else { +		char *end = NULL; +		unsigned long value_l = strtoul(argv[1]->arg, &end, 10); + +		value = value_l & 0xff; +		if (!argv[1]->arg[0] || *end) { +			vty_out(vty, "%% Malformed l2 nve ID \"%s\"\n", +				argv[1]->arg); +			return CMD_WARNING_CONFIG_FAILED; +		} +		if ((value_l < 1) || (value_l > 0xff)) { +			vty_out(vty, +				"%% Malformed l2 nve id (must be greater than 0 and less than %u\n", +				0x100); +			return CMD_WARNING_CONFIG_FAILED; +		} +	} +	bgp->rfapi_cfg->flags |= BGP_VNC_CONFIG_L2RD; +	bgp->rfapi_cfg->default_l2rd = value; + +	return CMD_SUCCESS;  }  DEFUN (vnc_defaults_no_l2rd, @@ -514,12 +474,12 @@ DEFUN (vnc_defaults_no_l2rd,         NO_STR         "Specify default Local Nve ID value to use in RD for L2 routes\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); +	VTY_DECLVAR_CONTEXT(bgp, bgp); -  bgp->rfapi_cfg->default_l2rd = 0; -  bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_L2RD; +	bgp->rfapi_cfg->default_l2rd = 0; +	bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_L2RD; -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (vnc_defaults_responselifetime, @@ -528,262 +488,240 @@ DEFUN (vnc_defaults_responselifetime,         "Specify default response lifetime\n"         "Response lifetime in seconds\n" "Infinite response lifetime\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  uint32_t rspint; -  struct rfapi *h = NULL; -  struct listnode *hdnode; -  struct rfapi_descriptor *rfd; - -  h = bgp->rfapi; -  if (!h) -    return CMD_WARNING_CONFIG_FAILED; - -  if (strmatch(argv[1]->text, "infinite")) -    { -      rspint = RFAPI_INFINITE_LIFETIME; -    } -  else -    { -      rspint = strtoul(argv[1]->arg, NULL, 10); -      if (rspint > INT32_MAX) -        rspint = INT32_MAX;     /* is really an int, not an unsigned int */ -    } - -  bgp->rfapi_cfg->default_response_lifetime = rspint; - -  for (ALL_LIST_ELEMENTS_RO (&h->descriptors, hdnode, rfd)) -    if (rfd->rfg && !(rfd->rfg->flags & RFAPI_RFG_RESPONSE_LIFETIME)) -      rfd->response_lifetime = rfd->rfg->response_lifetime = rspint; - -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	uint32_t rspint; +	struct rfapi *h = NULL; +	struct listnode *hdnode; +	struct rfapi_descriptor *rfd; + +	h = bgp->rfapi; +	if (!h) +		return CMD_WARNING_CONFIG_FAILED; + +	if (strmatch(argv[1]->text, "infinite")) { +		rspint = RFAPI_INFINITE_LIFETIME; +	} else { +		rspint = strtoul(argv[1]->arg, NULL, 10); +		if (rspint > INT32_MAX) +			rspint = +				INT32_MAX; /* is really an int, not an unsigned +					      int */ +	} + +	bgp->rfapi_cfg->default_response_lifetime = rspint; + +	for (ALL_LIST_ELEMENTS_RO(&h->descriptors, hdnode, rfd)) +		if (rfd->rfg +		    && !(rfd->rfg->flags & RFAPI_RFG_RESPONSE_LIFETIME)) +			rfd->response_lifetime = rfd->rfg->response_lifetime = +				rspint; + +	return CMD_SUCCESS;  }  struct rfapi_nve_group_cfg * -bgp_rfapi_cfg_match_byname (struct bgp *bgp, const char *name, -                           rfapi_group_cfg_type_t type)  /* _MAX = any */ +bgp_rfapi_cfg_match_byname(struct bgp *bgp, const char *name, +			   rfapi_group_cfg_type_t type) /* _MAX = any */  { -  struct rfapi_nve_group_cfg *rfg; -  struct listnode *node, *nnode; - -  for (ALL_LIST_ELEMENTS -       (bgp->rfapi_cfg->nve_groups_sequential, node, nnode, rfg)) -    { -      if ((type == RFAPI_GROUP_CFG_MAX || type == rfg->type) && -          !strcmp (rfg->name, name)) -        return rfg; -    } -  return NULL; +	struct rfapi_nve_group_cfg *rfg; +	struct listnode *node, *nnode; + +	for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->nve_groups_sequential, node, +			       nnode, rfg)) { +		if ((type == RFAPI_GROUP_CFG_MAX || type == rfg->type) +		    && !strcmp(rfg->name, name)) +			return rfg; +	} +	return NULL;  }  static struct rfapi_nve_group_cfg * -rfapi_group_new (struct bgp *bgp, -                 rfapi_group_cfg_type_t type, -                 const char *name) +rfapi_group_new(struct bgp *bgp, rfapi_group_cfg_type_t type, const char *name)  { -  struct rfapi_nve_group_cfg *rfg; - -  rfg = XCALLOC (MTYPE_RFAPI_GROUP_CFG, sizeof (struct rfapi_nve_group_cfg)); -  if (rfg)  -    { -      rfg->type = type; -      rfg->name = strdup (name); -      /* add to tail of list */ -      listnode_add (bgp->rfapi_cfg->nve_groups_sequential, rfg); -    } -  rfg->label = MPLS_LABEL_ILLEGAL; -  QOBJ_REG (rfg, rfapi_nve_group_cfg); - -  return rfg; +	struct rfapi_nve_group_cfg *rfg; + +	rfg = XCALLOC(MTYPE_RFAPI_GROUP_CFG, +		      sizeof(struct rfapi_nve_group_cfg)); +	if (rfg) { +		rfg->type = type; +		rfg->name = strdup(name); +		/* add to tail of list */ +		listnode_add(bgp->rfapi_cfg->nve_groups_sequential, rfg); +	} +	rfg->label = MPLS_LABEL_ILLEGAL; +	QOBJ_REG(rfg, rfapi_nve_group_cfg); + +	return rfg;  } -static struct rfapi_l2_group_cfg * -rfapi_l2_group_lookup_byname (struct bgp *bgp, const char *name) +static struct rfapi_l2_group_cfg *rfapi_l2_group_lookup_byname(struct bgp *bgp, +							       const char *name)  { -  struct rfapi_l2_group_cfg *rfg; -  struct listnode *node, *nnode; - -  if (bgp->rfapi_cfg->l2_groups == NULL)        /* not the best place for this */ -    bgp->rfapi_cfg->l2_groups = list_new (); - -  for (ALL_LIST_ELEMENTS (bgp->rfapi_cfg->l2_groups, node, nnode, rfg)) -    { -      if (!strcmp (rfg->name, name)) -        return rfg; -    } -  return NULL; +	struct rfapi_l2_group_cfg *rfg; +	struct listnode *node, *nnode; + +	if (bgp->rfapi_cfg->l2_groups == NULL) /* not the best place for this */ +		bgp->rfapi_cfg->l2_groups = list_new(); + +	for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->l2_groups, node, nnode, rfg)) { +		if (!strcmp(rfg->name, name)) +			return rfg; +	} +	return NULL;  } -static struct rfapi_l2_group_cfg * -rfapi_l2_group_new () +static struct rfapi_l2_group_cfg *rfapi_l2_group_new()  { -  struct rfapi_l2_group_cfg *rfg; +	struct rfapi_l2_group_cfg *rfg; -  rfg = XCALLOC (MTYPE_RFAPI_L2_CFG, sizeof (struct rfapi_l2_group_cfg)); -  QOBJ_REG (rfg, rfapi_l2_group_cfg); +	rfg = XCALLOC(MTYPE_RFAPI_L2_CFG, sizeof(struct rfapi_l2_group_cfg)); +	QOBJ_REG(rfg, rfapi_l2_group_cfg); -  return rfg; +	return rfg;  } -static void -rfapi_l2_group_del (struct rfapi_l2_group_cfg *rfg) +static void rfapi_l2_group_del(struct rfapi_l2_group_cfg *rfg)  { -  QOBJ_UNREG (rfg); -  XFREE (MTYPE_RFAPI_L2_CFG, rfg); +	QOBJ_UNREG(rfg); +	XFREE(MTYPE_RFAPI_L2_CFG, rfg);  } -static int -rfapi_str2route_type ( -  const char	*l3str, -  const char	*pstr, -  afi_t		*afi, -  int		*type) +static int rfapi_str2route_type(const char *l3str, const char *pstr, afi_t *afi, +				int *type)  { -  if (!l3str || !pstr) -    return EINVAL; - -  if (!strcmp (l3str, "ipv4")) -    { -      *afi = AFI_IP; -    } -  else -    { -      if (!strcmp (l3str, "ipv6")) -        *afi = AFI_IP6; -      else -        return ENOENT; -    } - -  if (!strcmp (pstr, "connected")) -    *type = ZEBRA_ROUTE_CONNECT; -  if (!strcmp (pstr, "kernel")) -    *type = ZEBRA_ROUTE_KERNEL; -  if (!strcmp (pstr, "static")) -    *type = ZEBRA_ROUTE_STATIC; -  if (!strcmp (pstr, "bgp")) -    *type = ZEBRA_ROUTE_BGP; -  if (!strcmp (pstr, "bgp-direct")) -    *type = ZEBRA_ROUTE_BGP_DIRECT; -  if (!strcmp (pstr, "bgp-direct-to-nve-groups")) -    *type = ZEBRA_ROUTE_BGP_DIRECT_EXT; - -  if (!strcmp (pstr, "rip")) -    { -      if (*afi == AFI_IP) -        *type = ZEBRA_ROUTE_RIP; -      else -        *type = ZEBRA_ROUTE_RIPNG; -    } - -  if (!strcmp (pstr, "ripng")) -    { -      if (*afi == AFI_IP) -        return EAFNOSUPPORT; -      *type = ZEBRA_ROUTE_RIPNG; -    } - -  if (!strcmp (pstr, "ospf")) -    { -      if (*afi == AFI_IP) -        *type = ZEBRA_ROUTE_OSPF; -      else -        *type = ZEBRA_ROUTE_OSPF6; -    } - -  if (!strcmp (pstr, "ospf6")) -    { -      if (*afi == AFI_IP) -        return EAFNOSUPPORT; -      *type = ZEBRA_ROUTE_OSPF6; -    } - -  return 0; +	if (!l3str || !pstr) +		return EINVAL; + +	if (!strcmp(l3str, "ipv4")) { +		*afi = AFI_IP; +	} else { +		if (!strcmp(l3str, "ipv6")) +			*afi = AFI_IP6; +		else +			return ENOENT; +	} + +	if (!strcmp(pstr, "connected")) +		*type = ZEBRA_ROUTE_CONNECT; +	if (!strcmp(pstr, "kernel")) +		*type = ZEBRA_ROUTE_KERNEL; +	if (!strcmp(pstr, "static")) +		*type = ZEBRA_ROUTE_STATIC; +	if (!strcmp(pstr, "bgp")) +		*type = ZEBRA_ROUTE_BGP; +	if (!strcmp(pstr, "bgp-direct")) +		*type = ZEBRA_ROUTE_BGP_DIRECT; +	if (!strcmp(pstr, "bgp-direct-to-nve-groups")) +		*type = ZEBRA_ROUTE_BGP_DIRECT_EXT; + +	if (!strcmp(pstr, "rip")) { +		if (*afi == AFI_IP) +			*type = ZEBRA_ROUTE_RIP; +		else +			*type = ZEBRA_ROUTE_RIPNG; +	} + +	if (!strcmp(pstr, "ripng")) { +		if (*afi == AFI_IP) +			return EAFNOSUPPORT; +		*type = ZEBRA_ROUTE_RIPNG; +	} + +	if (!strcmp(pstr, "ospf")) { +		if (*afi == AFI_IP) +			*type = ZEBRA_ROUTE_OSPF; +		else +			*type = ZEBRA_ROUTE_OSPF6; +	} + +	if (!strcmp(pstr, "ospf6")) { +		if (*afi == AFI_IP) +			return EAFNOSUPPORT; +		*type = ZEBRA_ROUTE_OSPF6; +	} + +	return 0;  }  /*-------------------------------------------------------------------------   *			redistribute   *-----------------------------------------------------------------------*/ -#define VNC_REDIST_ENABLE(bgp, afi, type) do {			\ -    switch (type) {						\ -	case ZEBRA_ROUTE_BGP_DIRECT:				\ -	    vnc_import_bgp_redist_enable((bgp), (afi));		\ -	    break;						\ -	case ZEBRA_ROUTE_BGP_DIRECT_EXT:			\ -	    vnc_import_bgp_exterior_redist_enable((bgp), (afi));\ -	    break;						\ -	default:						\ -	    vnc_redistribute_set((bgp), (afi), (type));		\ -	    break;						\ -    }								\ -} while (0) - -#define VNC_REDIST_DISABLE(bgp, afi, type) do {			\ -    switch (type) {						\ -	case ZEBRA_ROUTE_BGP_DIRECT:				\ -	    vnc_import_bgp_redist_disable((bgp), (afi));	\ -	    break;						\ -	case ZEBRA_ROUTE_BGP_DIRECT_EXT:			\ -	    vnc_import_bgp_exterior_redist_disable((bgp), (afi));\ -	    break;						\ -	default:						\ -	    vnc_redistribute_unset((bgp), (afi), (type));	\ -	    break;						\ -    }								\ -} while (0) +#define VNC_REDIST_ENABLE(bgp, afi, type)                                      \ +	do {                                                                   \ +		switch (type) {                                                \ +		case ZEBRA_ROUTE_BGP_DIRECT:                                   \ +			vnc_import_bgp_redist_enable((bgp), (afi));            \ +			break;                                                 \ +		case ZEBRA_ROUTE_BGP_DIRECT_EXT:                               \ +			vnc_import_bgp_exterior_redist_enable((bgp), (afi));   \ +			break;                                                 \ +		default:                                                       \ +			vnc_redistribute_set((bgp), (afi), (type));            \ +			break;                                                 \ +		}                                                              \ +	} while (0) + +#define VNC_REDIST_DISABLE(bgp, afi, type)                                     \ +	do {                                                                   \ +		switch (type) {                                                \ +		case ZEBRA_ROUTE_BGP_DIRECT:                                   \ +			vnc_import_bgp_redist_disable((bgp), (afi));           \ +			break;                                                 \ +		case ZEBRA_ROUTE_BGP_DIRECT_EXT:                               \ +			vnc_import_bgp_exterior_redist_disable((bgp), (afi));  \ +			break;                                                 \ +		default:                                                       \ +			vnc_redistribute_unset((bgp), (afi), (type));          \ +			break;                                                 \ +		}                                                              \ +	} while (0)  static uint8_t redist_was_enabled[AFI_MAX][ZEBRA_ROUTE_MAX]; -static void -vnc_redistribute_prechange (struct bgp *bgp) +static void vnc_redistribute_prechange(struct bgp *bgp)  { -  afi_t afi; -  int type; - -  vnc_zlog_debug_verbose ("%s: entry", __func__); -  memset (redist_was_enabled, 0, sizeof (redist_was_enabled)); - -  /* -   * Look to see if we have any redistribution enabled. If so, flush -   * the corresponding routes and turn off redistribution temporarily. -   * We need to do it because the RD's used for the redistributed -   * routes depend on the nve group. -   */ -  for (afi = AFI_IP; afi < AFI_MAX; ++afi) -    { -      for (type = 0; type < ZEBRA_ROUTE_MAX; ++type) -        { -          if (bgp->rfapi_cfg->redist[afi][type]) -            { -              redist_was_enabled[afi][type] = 1; -              VNC_REDIST_DISABLE (bgp, afi, type); -            } -        } -    } -  vnc_zlog_debug_verbose ("%s: return", __func__); +	afi_t afi; +	int type; + +	vnc_zlog_debug_verbose("%s: entry", __func__); +	memset(redist_was_enabled, 0, sizeof(redist_was_enabled)); + +	/* +	 * Look to see if we have any redistribution enabled. If so, flush +	 * the corresponding routes and turn off redistribution temporarily. +	 * We need to do it because the RD's used for the redistributed +	 * routes depend on the nve group. +	 */ +	for (afi = AFI_IP; afi < AFI_MAX; ++afi) { +		for (type = 0; type < ZEBRA_ROUTE_MAX; ++type) { +			if (bgp->rfapi_cfg->redist[afi][type]) { +				redist_was_enabled[afi][type] = 1; +				VNC_REDIST_DISABLE(bgp, afi, type); +			} +		} +	} +	vnc_zlog_debug_verbose("%s: return", __func__);  } -static void -vnc_redistribute_postchange (struct bgp *bgp) +static void vnc_redistribute_postchange(struct bgp *bgp)  { -  afi_t afi; -  int type; - -  vnc_zlog_debug_verbose ("%s: entry", __func__); -  /* -   * If we turned off redistribution above, turn it back on. Doing so -   * will tell zebra to resend the routes to us -   */ -  for (afi = AFI_IP; afi < AFI_MAX; ++afi) -    { -      for (type = 0; type < ZEBRA_ROUTE_MAX; ++type) -        { -          if (redist_was_enabled[afi][type]) -            { -              VNC_REDIST_ENABLE (bgp, afi, type); -            } -        } -    } -  vnc_zlog_debug_verbose ("%s: return", __func__); +	afi_t afi; +	int type; + +	vnc_zlog_debug_verbose("%s: entry", __func__); +	/* +	 * If we turned off redistribution above, turn it back on. Doing so +	 * will tell zebra to resend the routes to us +	 */ +	for (afi = AFI_IP; afi < AFI_MAX; ++afi) { +		for (type = 0; type < ZEBRA_ROUTE_MAX; ++type) { +			if (redist_was_enabled[afi][type]) { +				VNC_REDIST_ENABLE(bgp, afi, type); +			} +		} +	} +	vnc_zlog_debug_verbose("%s: return", __func__);  }  DEFUN (vnc_redistribute_rh_roo_localadmin, @@ -794,51 +732,46 @@ DEFUN (vnc_redistribute_rh_roo_localadmin,         "Resolve-NVE mode\n"         "Route Origin Extended Community Local Admin Field\n" "Field value\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  uint32_t localadmin; -  char *endptr; - -  if (!bgp->rfapi_cfg) -    { -      vty_out (vty, "RFAPI not configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  localadmin = strtoul (argv[4]->arg, &endptr, 0); -  if (!argv[4]->arg[0] || *endptr) -    { -      vty_out (vty, "%% Malformed value\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (localadmin > 0xffff) -    { -      vty_out (vty, "%% Value out of range (0-%d)\n", 0xffff); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (bgp->rfapi_cfg->resolve_nve_roo_local_admin == localadmin) -    return CMD_SUCCESS; - -  if ((bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) == -      BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE) -    { - -      vnc_export_bgp_prechange (bgp); -    } -  vnc_redistribute_prechange (bgp); - -  bgp->rfapi_cfg->resolve_nve_roo_local_admin = localadmin; - -  if ((bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) == -      BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE) -    { - -      vnc_export_bgp_postchange (bgp); -    } -  vnc_redistribute_postchange (bgp); - -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	uint32_t localadmin; +	char *endptr; + +	if (!bgp->rfapi_cfg) { +		vty_out(vty, "RFAPI not configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	localadmin = strtoul(argv[4]->arg, &endptr, 0); +	if (!argv[4]->arg[0] || *endptr) { +		vty_out(vty, "%% Malformed value\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (localadmin > 0xffff) { +		vty_out(vty, "%% Value out of range (0-%d)\n", 0xffff); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (bgp->rfapi_cfg->resolve_nve_roo_local_admin == localadmin) +		return CMD_SUCCESS; + +	if ((bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) +	    == BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE) { + +		vnc_export_bgp_prechange(bgp); +	} +	vnc_redistribute_prechange(bgp); + +	bgp->rfapi_cfg->resolve_nve_roo_local_admin = localadmin; + +	if ((bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) +	    == BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE) { + +		vnc_export_bgp_postchange(bgp); +	} +	vnc_redistribute_postchange(bgp); + +	return CMD_SUCCESS;  } @@ -851,43 +784,40 @@ DEFUN (vnc_redistribute_mode,         "Based on redistribute nve-group\n"         "Unmodified\n" "Resolve each nexthop to connected NVEs\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  vnc_redist_mode_t newmode; - -  if (!bgp->rfapi_cfg) -    { -      vty_out (vty, "RFAPI not configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - - -  switch (argv[3]->arg[0]) -    { -    case 'n': -      newmode = VNC_REDIST_MODE_RFG; -      break; - -    case 'p': -      newmode = VNC_REDIST_MODE_PLAIN; -      break; - -    case 'r': -      newmode = VNC_REDIST_MODE_RESOLVE_NVE; -      break; - -    default: -      vty_out (vty, "unknown redistribute mode\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (newmode != bgp->rfapi_cfg->redist_mode) -    { -      vnc_redistribute_prechange (bgp); -      bgp->rfapi_cfg->redist_mode = newmode; -      vnc_redistribute_postchange (bgp); -    } - -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	vnc_redist_mode_t newmode; + +	if (!bgp->rfapi_cfg) { +		vty_out(vty, "RFAPI not configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + + +	switch (argv[3]->arg[0]) { +	case 'n': +		newmode = VNC_REDIST_MODE_RFG; +		break; + +	case 'p': +		newmode = VNC_REDIST_MODE_PLAIN; +		break; + +	case 'r': +		newmode = VNC_REDIST_MODE_RESOLVE_NVE; +		break; + +	default: +		vty_out(vty, "unknown redistribute mode\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (newmode != bgp->rfapi_cfg->redist_mode) { +		vnc_redistribute_prechange(bgp); +		bgp->rfapi_cfg->redist_mode = newmode; +		vnc_redistribute_postchange(bgp); +	} + +	return CMD_SUCCESS;  }  DEFUN (vnc_redistribute_protocol, @@ -905,36 +835,33 @@ DEFUN (vnc_redistribute_protocol,         "From Open Shortest Path First (OSPF)\n"         "From Routing Information Protocol (RIP)\n" "From Static routes\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  int type = ZEBRA_ROUTE_MAX;     /* init to bogus value */ -  afi_t afi; - -  if (!bgp->rfapi_cfg) -    { -      vty_out (vty, "RFAPI not configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (rfapi_str2route_type (argv[2]->arg, argv[3]->arg, &afi, &type)) -    { -      vty_out (vty, "%% Invalid route type\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (type == ZEBRA_ROUTE_BGP_DIRECT_EXT) -    { -      if (bgp->rfapi_cfg->redist_bgp_exterior_view_name) -        { -          VNC_REDIST_DISABLE (bgp, afi, type);  /* disabled view implicitly */ -          free (bgp->rfapi_cfg->redist_bgp_exterior_view_name); -          bgp->rfapi_cfg->redist_bgp_exterior_view_name = NULL; -        } -      bgp->rfapi_cfg->redist_bgp_exterior_view = bgp; -    } - -  VNC_REDIST_ENABLE (bgp, afi, type); - -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	int type = ZEBRA_ROUTE_MAX; /* init to bogus value */ +	afi_t afi; + +	if (!bgp->rfapi_cfg) { +		vty_out(vty, "RFAPI not configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (rfapi_str2route_type(argv[2]->arg, argv[3]->arg, &afi, &type)) { +		vty_out(vty, "%% Invalid route type\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (type == ZEBRA_ROUTE_BGP_DIRECT_EXT) { +		if (bgp->rfapi_cfg->redist_bgp_exterior_view_name) { +			VNC_REDIST_DISABLE(bgp, afi, +					   type); /* disabled view implicitly */ +			free(bgp->rfapi_cfg->redist_bgp_exterior_view_name); +			bgp->rfapi_cfg->redist_bgp_exterior_view_name = NULL; +		} +		bgp->rfapi_cfg->redist_bgp_exterior_view = bgp; +	} + +	VNC_REDIST_ENABLE(bgp, afi, type); + +	return CMD_SUCCESS;  }  DEFUN (vnc_no_redistribute_protocol, @@ -953,35 +880,31 @@ DEFUN (vnc_no_redistribute_protocol,         "From Open Shortest Path First (OSPF)\n"         "From Routing Information Protocol (RIP)\n" "From Static routes\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  int type; -  afi_t afi; - -  if (!bgp->rfapi_cfg) -    { -      vty_out (vty, "RFAPI not configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (rfapi_str2route_type (argv[3]->arg, argv[4]->arg, &afi, &type)) -    { -      vty_out (vty, "%% Invalid route type\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  VNC_REDIST_DISABLE (bgp, afi, type); - -  if (type == ZEBRA_ROUTE_BGP_DIRECT_EXT) -    { -      if (bgp->rfapi_cfg->redist_bgp_exterior_view_name) -        { -          free (bgp->rfapi_cfg->redist_bgp_exterior_view_name); -          bgp->rfapi_cfg->redist_bgp_exterior_view_name = NULL; -        } -      bgp->rfapi_cfg->redist_bgp_exterior_view = NULL; -    } - -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	int type; +	afi_t afi; + +	if (!bgp->rfapi_cfg) { +		vty_out(vty, "RFAPI not configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (rfapi_str2route_type(argv[3]->arg, argv[4]->arg, &afi, &type)) { +		vty_out(vty, "%% Invalid route type\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	VNC_REDIST_DISABLE(bgp, afi, type); + +	if (type == ZEBRA_ROUTE_BGP_DIRECT_EXT) { +		if (bgp->rfapi_cfg->redist_bgp_exterior_view_name) { +			free(bgp->rfapi_cfg->redist_bgp_exterior_view_name); +			bgp->rfapi_cfg->redist_bgp_exterior_view_name = NULL; +		} +		bgp->rfapi_cfg->redist_bgp_exterior_view = NULL; +	} + +	return CMD_SUCCESS;  }  DEFUN (vnc_redistribute_bgp_exterior, @@ -994,31 +917,31 @@ DEFUN (vnc_redistribute_bgp_exterior,         "From BGP without Zebra, only to configured NVE groups\n"         "From BGP view\n" "BGP view name\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  int type; -  afi_t afi; - -  if (!bgp->rfapi_cfg) -    { -      vty_out (vty, "RFAPI not configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (rfapi_str2route_type (argv[2]->arg, "bgp-direct-to-nve-groups", &afi, &type)) -    { -      vty_out (vty, "%% Invalid route type\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (bgp->rfapi_cfg->redist_bgp_exterior_view_name) -    free (bgp->rfapi_cfg->redist_bgp_exterior_view_name); -  bgp->rfapi_cfg->redist_bgp_exterior_view_name = strdup (argv[5]->arg); -  /* could be NULL if name is not defined yet */ -  bgp->rfapi_cfg->redist_bgp_exterior_view = bgp_lookup_by_name (argv[5]->arg); - -  VNC_REDIST_ENABLE (bgp, afi, type); - -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	int type; +	afi_t afi; + +	if (!bgp->rfapi_cfg) { +		vty_out(vty, "RFAPI not configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (rfapi_str2route_type(argv[2]->arg, "bgp-direct-to-nve-groups", &afi, +				 &type)) { +		vty_out(vty, "%% Invalid route type\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (bgp->rfapi_cfg->redist_bgp_exterior_view_name) +		free(bgp->rfapi_cfg->redist_bgp_exterior_view_name); +	bgp->rfapi_cfg->redist_bgp_exterior_view_name = strdup(argv[5]->arg); +	/* could be NULL if name is not defined yet */ +	bgp->rfapi_cfg->redist_bgp_exterior_view = +		bgp_lookup_by_name(argv[5]->arg); + +	VNC_REDIST_ENABLE(bgp, afi, type); + +	return CMD_SUCCESS;  }  DEFUN (vnc_redistribute_nvegroup, @@ -1028,29 +951,28 @@ DEFUN (vnc_redistribute_nvegroup,         "Assign a NVE group to routes redistributed from another routing protocol\n"         "NVE group\n" "Group name\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); +	VTY_DECLVAR_CONTEXT(bgp, bgp); -  if (!bgp->rfapi_cfg) -    { -      vty_out (vty, "rfapi not configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } +	if (!bgp->rfapi_cfg) { +		vty_out(vty, "rfapi not configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} -  vnc_redistribute_prechange (bgp); +	vnc_redistribute_prechange(bgp); -  /* -   * OK if nve group doesn't exist yet; we'll set the pointer -   * when the group is defined later -   */ -  bgp->rfapi_cfg->rfg_redist = bgp_rfapi_cfg_match_byname (bgp, argv[3]->arg, -                                                           RFAPI_GROUP_CFG_NVE); -  if (bgp->rfapi_cfg->rfg_redist_name) -    free (bgp->rfapi_cfg->rfg_redist_name); -  bgp->rfapi_cfg->rfg_redist_name = strdup (argv[3]->arg); +	/* +	 * OK if nve group doesn't exist yet; we'll set the pointer +	 * when the group is defined later +	 */ +	bgp->rfapi_cfg->rfg_redist = bgp_rfapi_cfg_match_byname( +		bgp, argv[3]->arg, RFAPI_GROUP_CFG_NVE); +	if (bgp->rfapi_cfg->rfg_redist_name) +		free(bgp->rfapi_cfg->rfg_redist_name); +	bgp->rfapi_cfg->rfg_redist_name = strdup(argv[3]->arg); -  vnc_redistribute_postchange (bgp); +	vnc_redistribute_postchange(bgp); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (vnc_redistribute_no_nvegroup, @@ -1061,24 +983,23 @@ DEFUN (vnc_redistribute_no_nvegroup,         "Redistribute from other protocol\n"         "Assign a NVE group to routes redistributed from another routing protocol\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); +	VTY_DECLVAR_CONTEXT(bgp, bgp); -  if (!bgp->rfapi_cfg) -    { -      vty_out (vty, "rfapi not configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } +	if (!bgp->rfapi_cfg) { +		vty_out(vty, "rfapi not configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} -  vnc_redistribute_prechange (bgp); +	vnc_redistribute_prechange(bgp); -  bgp->rfapi_cfg->rfg_redist = NULL; -  if (bgp->rfapi_cfg->rfg_redist_name) -    free (bgp->rfapi_cfg->rfg_redist_name); -  bgp->rfapi_cfg->rfg_redist_name = NULL; +	bgp->rfapi_cfg->rfg_redist = NULL; +	if (bgp->rfapi_cfg->rfg_redist_name) +		free(bgp->rfapi_cfg->rfg_redist_name); +	bgp->rfapi_cfg->rfg_redist_name = NULL; -  vnc_redistribute_postchange (bgp); +	vnc_redistribute_postchange(bgp); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  } @@ -1091,28 +1012,25 @@ DEFUN (vnc_redistribute_lifetime,         "lifetime value (32 bit)\n"         "Allow lifetime to never expire\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); +	VTY_DECLVAR_CONTEXT(bgp, bgp); -  if (!bgp->rfapi_cfg) -    { -      vty_out (vty, "rfapi not configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } +	if (!bgp->rfapi_cfg) { +		vty_out(vty, "rfapi not configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} -  vnc_redistribute_prechange (bgp); +	vnc_redistribute_prechange(bgp); -  if (strmatch(argv[3]->text, "infinite")) -    { -      bgp->rfapi_cfg->redist_lifetime = RFAPI_INFINITE_LIFETIME; -    } -  else -    { -      bgp->rfapi_cfg->redist_lifetime = strtoul(argv[3]->arg, NULL, 10); -    } +	if (strmatch(argv[3]->text, "infinite")) { +		bgp->rfapi_cfg->redist_lifetime = RFAPI_INFINITE_LIFETIME; +	} else { +		bgp->rfapi_cfg->redist_lifetime = +			strtoul(argv[3]->arg, NULL, 10); +	} -  vnc_redistribute_postchange (bgp); +	vnc_redistribute_postchange(bgp); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  /*-- redist policy, non-nvegroup start --*/ @@ -1128,45 +1046,38 @@ DEFUN (vnc_redist_bgpdirect_no_prefixlist,         "IPv4 routes\n"         "IPv6 routes\n" "Prefix-list for filtering redistributed routes\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  afi_t afi; -  struct rfapi_cfg *hc; -  uint8_t route_type = 0; - -  if (!(hc = bgp->rfapi_cfg)) -    { -      vty_out (vty, "rfapi not configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (strmatch(argv[3]->text, "bgp-direct")) -    { -      route_type = ZEBRA_ROUTE_BGP_DIRECT; -    } -  else -    { -      route_type = ZEBRA_ROUTE_BGP_DIRECT_EXT; -    } - -  if (strmatch(argv[4]->text, "ipv4")) -    { -      afi = AFI_IP; -    } -  else -    { -      afi = AFI_IP6; -    } - -  vnc_redistribute_prechange (bgp); - -  if (hc->plist_redist_name[route_type][afi]) -    free (hc->plist_redist_name[route_type][afi]); -  hc->plist_redist_name[route_type][afi] = NULL; -  hc->plist_redist[route_type][afi] = NULL; - -  vnc_redistribute_postchange (bgp); - -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	afi_t afi; +	struct rfapi_cfg *hc; +	uint8_t route_type = 0; + +	if (!(hc = bgp->rfapi_cfg)) { +		vty_out(vty, "rfapi not configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (strmatch(argv[3]->text, "bgp-direct")) { +		route_type = ZEBRA_ROUTE_BGP_DIRECT; +	} else { +		route_type = ZEBRA_ROUTE_BGP_DIRECT_EXT; +	} + +	if (strmatch(argv[4]->text, "ipv4")) { +		afi = AFI_IP; +	} else { +		afi = AFI_IP6; +	} + +	vnc_redistribute_prechange(bgp); + +	if (hc->plist_redist_name[route_type][afi]) +		free(hc->plist_redist_name[route_type][afi]); +	hc->plist_redist_name[route_type][afi] = NULL; +	hc->plist_redist[route_type][afi] = NULL; + +	vnc_redistribute_postchange(bgp); + +	return CMD_SUCCESS;  }  DEFUN (vnc_redist_bgpdirect_prefixlist, @@ -1181,45 +1092,39 @@ DEFUN (vnc_redist_bgpdirect_prefixlist,         "Prefix-list for filtering redistributed routes\n"         "prefix list name\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  struct rfapi_cfg *hc; -  afi_t afi; -  uint8_t route_type = 0; - -  if (!(hc = bgp->rfapi_cfg)) -    { -      vty_out (vty, "rfapi not configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (strmatch(argv[2]->text, "bgp-direct")) -    { -      route_type = ZEBRA_ROUTE_BGP_DIRECT; -    } -  else -    { -      route_type = ZEBRA_ROUTE_BGP_DIRECT_EXT; -    } - -  if (strmatch(argv[3]->text, "ipv4")) -    { -      afi = AFI_IP; -    } -  else -    { -      afi = AFI_IP6; -    } - -  vnc_redistribute_prechange (bgp); - -  if (hc->plist_redist_name[route_type][afi]) -    free (hc->plist_redist_name[route_type][afi]); -  hc->plist_redist_name[route_type][afi] = strdup (argv[5]->arg); -  hc->plist_redist[route_type][afi] = prefix_list_lookup (afi, argv[5]->arg); - -  vnc_redistribute_postchange (bgp); - -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	struct rfapi_cfg *hc; +	afi_t afi; +	uint8_t route_type = 0; + +	if (!(hc = bgp->rfapi_cfg)) { +		vty_out(vty, "rfapi not configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (strmatch(argv[2]->text, "bgp-direct")) { +		route_type = ZEBRA_ROUTE_BGP_DIRECT; +	} else { +		route_type = ZEBRA_ROUTE_BGP_DIRECT_EXT; +	} + +	if (strmatch(argv[3]->text, "ipv4")) { +		afi = AFI_IP; +	} else { +		afi = AFI_IP6; +	} + +	vnc_redistribute_prechange(bgp); + +	if (hc->plist_redist_name[route_type][afi]) +		free(hc->plist_redist_name[route_type][afi]); +	hc->plist_redist_name[route_type][afi] = strdup(argv[5]->arg); +	hc->plist_redist[route_type][afi] = +		prefix_list_lookup(afi, argv[5]->arg); + +	vnc_redistribute_postchange(bgp); + +	return CMD_SUCCESS;  }  DEFUN (vnc_redist_bgpdirect_no_routemap, @@ -1232,35 +1137,31 @@ DEFUN (vnc_redist_bgpdirect_no_routemap,         "Redistribute from BGP without Zebra, only to configured NVE groups\n"         "Route-map for filtering redistributed routes\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  struct rfapi_cfg *hc; -  uint8_t route_type = 0; - -  if (!(hc = bgp->rfapi_cfg)) -    { -      vty_out (vty, "rfapi not configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (strmatch(argv[3]->text, "bgp-direct")) -    { -      route_type = ZEBRA_ROUTE_BGP_DIRECT; -    } -  else -    { -      route_type = ZEBRA_ROUTE_BGP_DIRECT_EXT; -    } - -  vnc_redistribute_prechange (bgp); - -  if (hc->routemap_redist_name[route_type]) -    free (hc->routemap_redist_name[route_type]); -  hc->routemap_redist_name[route_type] = NULL; -  hc->routemap_redist[route_type] = NULL; - -  vnc_redistribute_postchange (bgp); - -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	struct rfapi_cfg *hc; +	uint8_t route_type = 0; + +	if (!(hc = bgp->rfapi_cfg)) { +		vty_out(vty, "rfapi not configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (strmatch(argv[3]->text, "bgp-direct")) { +		route_type = ZEBRA_ROUTE_BGP_DIRECT; +	} else { +		route_type = ZEBRA_ROUTE_BGP_DIRECT_EXT; +	} + +	vnc_redistribute_prechange(bgp); + +	if (hc->routemap_redist_name[route_type]) +		free(hc->routemap_redist_name[route_type]); +	hc->routemap_redist_name[route_type] = NULL; +	hc->routemap_redist[route_type] = NULL; + +	vnc_redistribute_postchange(bgp); + +	return CMD_SUCCESS;  }  DEFUN (vnc_redist_bgpdirect_routemap, @@ -1272,35 +1173,32 @@ DEFUN (vnc_redist_bgpdirect_routemap,         "Redistribute from BGP without Zebra, only to configured NVE groups\n"         "Route-map for filtering exported routes\n" "route map name\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  struct rfapi_cfg *hc; -  uint8_t route_type = 0; - -  if (!(hc = bgp->rfapi_cfg)) -    { -      vty_out (vty, "rfapi not configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (strmatch(argv[2]->text, "bgp-direct")) -    { -      route_type = ZEBRA_ROUTE_BGP_DIRECT; -    } -  else -    { -      route_type = ZEBRA_ROUTE_BGP_DIRECT_EXT; -    } - -  vnc_redistribute_prechange (bgp); - -  if (hc->routemap_redist_name[route_type]) -    free (hc->routemap_redist_name[route_type]); -  hc->routemap_redist_name[route_type] = strdup (argv[4]->arg); -  hc->routemap_redist[route_type] = route_map_lookup_by_name (argv[4]->arg); - -  vnc_redistribute_postchange (bgp); - -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	struct rfapi_cfg *hc; +	uint8_t route_type = 0; + +	if (!(hc = bgp->rfapi_cfg)) { +		vty_out(vty, "rfapi not configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (strmatch(argv[2]->text, "bgp-direct")) { +		route_type = ZEBRA_ROUTE_BGP_DIRECT; +	} else { +		route_type = ZEBRA_ROUTE_BGP_DIRECT_EXT; +	} + +	vnc_redistribute_prechange(bgp); + +	if (hc->routemap_redist_name[route_type]) +		free(hc->routemap_redist_name[route_type]); +	hc->routemap_redist_name[route_type] = strdup(argv[4]->arg); +	hc->routemap_redist[route_type] = +		route_map_lookup_by_name(argv[4]->arg); + +	vnc_redistribute_postchange(bgp); + +	return CMD_SUCCESS;  }  /*-- redist policy, non-nvegroup end --*/ @@ -1317,43 +1215,38 @@ DEFUN (vnc_nve_group_redist_bgpdirect_no_prefixlist,         "IPv6 routes\n"         "Prefix-list for filtering redistributed routes\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg) -  afi_t afi; - -  if (!bgp->rfapi_cfg) -    { -      vty_out (vty, "rfapi not configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  /* make sure it's still in list */ -  if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) -    { -      /* Not in list anymore */ -      vty_out (vty, "Current NVE group no longer exists\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (strmatch(argv[3]->text, "ipv4")) -    { -      afi = AFI_IP; -    } -  else -    { -      afi = AFI_IP6; -    } - -  vnc_redistribute_prechange (bgp); - -  if (rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]) -    free (rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]); -  rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi] = NULL; -  rfg->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi] = NULL; - -  vnc_redistribute_postchange (bgp); - -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg) +	afi_t afi; + +	if (!bgp->rfapi_cfg) { +		vty_out(vty, "rfapi not configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	/* make sure it's still in list */ +	if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { +		/* Not in list anymore */ +		vty_out(vty, "Current NVE group no longer exists\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (strmatch(argv[3]->text, "ipv4")) { +		afi = AFI_IP; +	} else { +		afi = AFI_IP6; +	} + +	vnc_redistribute_prechange(bgp); + +	if (rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]) +		free(rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]); +	rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi] = NULL; +	rfg->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi] = NULL; + +	vnc_redistribute_postchange(bgp); + +	return CMD_SUCCESS;  }  DEFUN (vnc_nve_group_redist_bgpdirect_prefixlist, @@ -1366,44 +1259,40 @@ DEFUN (vnc_nve_group_redist_bgpdirect_prefixlist,         "Prefix-list for filtering redistributed routes\n"         "prefix list name\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); -  afi_t afi; - -  if (!bgp->rfapi_cfg) -    { -      vty_out (vty, "rfapi not configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  /* make sure it's still in list */ -  if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) -    { -      /* Not in list anymore */ -      vty_out (vty, "Current NVE group no longer exists\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (strmatch(argv[2]->text, "ipv4")) -    { -      afi = AFI_IP; -    } -  else -    { -      afi = AFI_IP6; -    } - -  vnc_redistribute_prechange (bgp); - -  if (rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]) -    free (rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]); -  rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi] = strdup (argv[4]->arg); -  rfg->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi] = -    prefix_list_lookup (afi, argv[4]->arg); - -  vnc_redistribute_postchange (bgp); - -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); +	afi_t afi; + +	if (!bgp->rfapi_cfg) { +		vty_out(vty, "rfapi not configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	/* make sure it's still in list */ +	if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { +		/* Not in list anymore */ +		vty_out(vty, "Current NVE group no longer exists\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (strmatch(argv[2]->text, "ipv4")) { +		afi = AFI_IP; +	} else { +		afi = AFI_IP6; +	} + +	vnc_redistribute_prechange(bgp); + +	if (rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]) +		free(rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]); +	rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi] = +		strdup(argv[4]->arg); +	rfg->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi] = +		prefix_list_lookup(afi, argv[4]->arg); + +	vnc_redistribute_postchange(bgp); + +	return CMD_SUCCESS;  }  DEFUN (vnc_nve_group_redist_bgpdirect_no_routemap, @@ -1414,33 +1303,31 @@ DEFUN (vnc_nve_group_redist_bgpdirect_no_routemap,         "Redistribute from BGP directly\n"         "Route-map for filtering redistributed routes\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); -  if (!bgp->rfapi_cfg) -    { -      vty_out (vty, "rfapi not configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } +	if (!bgp->rfapi_cfg) { +		vty_out(vty, "rfapi not configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} -  /* make sure it's still in list */ -  if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) -    { -      /* Not in list anymore */ -      vty_out (vty, "Current NVE group no longer exists\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } +	/* make sure it's still in list */ +	if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { +		/* Not in list anymore */ +		vty_out(vty, "Current NVE group no longer exists\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} -  vnc_redistribute_prechange (bgp); +	vnc_redistribute_prechange(bgp); -  if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]) -    free (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]); -  rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT] = NULL; -  rfg->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT] = NULL; +	if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]) +		free(rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]); +	rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT] = NULL; +	rfg->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT] = NULL; -  vnc_redistribute_postchange (bgp); +	vnc_redistribute_postchange(bgp); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (vnc_nve_group_redist_bgpdirect_routemap, @@ -1450,34 +1337,33 @@ DEFUN (vnc_nve_group_redist_bgpdirect_routemap,         "Redistribute from BGP directly\n"         "Route-map for filtering exported routes\n" "route map name\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); - -  if (!bgp->rfapi_cfg) -    { -      vty_out (vty, "rfapi not configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  /* make sure it's still in list */ -  if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) -    { -      /* Not in list anymore */ -      vty_out (vty, "Current NVE group no longer exists\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  vnc_redistribute_prechange (bgp); - -  if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]) -    free (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]); -  rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT] = strdup (argv[3]->arg); -  rfg->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT] = -    route_map_lookup_by_name (argv[3]->arg); - -  vnc_redistribute_postchange (bgp); - -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); + +	if (!bgp->rfapi_cfg) { +		vty_out(vty, "rfapi not configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	/* make sure it's still in list */ +	if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { +		/* Not in list anymore */ +		vty_out(vty, "Current NVE group no longer exists\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	vnc_redistribute_prechange(bgp); + +	if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]) +		free(rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]); +	rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT] = +		strdup(argv[3]->arg); +	rfg->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT] = +		route_map_lookup_by_name(argv[3]->arg); + +	vnc_redistribute_postchange(bgp); + +	return CMD_SUCCESS;  }  /*-- redist policy, nvegroup end --*/ @@ -1498,116 +1384,106 @@ DEFUN (vnc_export_mode,         "Export routes with NVE connected router next-hops\n"         "Disable export\n" "Export routes with registering NVE as next-hop\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  uint32_t oldmode = 0; -  uint32_t newmode = 0; - -  if (!bgp->rfapi_cfg) -    { -      vty_out (vty, "VNC not configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (argv[2]->arg[0] == 'b') -    { -      oldmode = bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS; -      switch (argv[4]->arg[0]) -        { -        case 'g': -          newmode = BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP; -          break; -        case 'c': -          newmode = BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE; -          break; -        case 'n': -          newmode = 0; -          break; -        case 'r': -          newmode = BGP_VNC_CONFIG_EXPORT_BGP_MODE_RH; -          break; -        default: -          vty_out (vty, "Invalid mode specified\n"); -          return CMD_WARNING_CONFIG_FAILED; -        } - -      if (newmode == oldmode) -        { -          vty_out (vty, "Mode unchanged\n"); -          return CMD_SUCCESS; -        } - -      vnc_export_bgp_prechange (bgp); - -      bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS; -      bgp->rfapi_cfg->flags |= newmode; - -      vnc_export_bgp_postchange (bgp); - - -    } -  else -    { -      /* -       * export to zebra with RH mode is not yet implemented -       */ -      vty_out (vty,"Changing modes for zebra export not implemented yet\n"); -      return CMD_WARNING_CONFIG_FAILED; - -      oldmode = bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS; -      bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS; -      switch (argv[4]->arg[0]) -        { -        case 'g': -          if (oldmode == BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_RH) -            { -              /* TBD */ -            } -          bgp->rfapi_cfg->flags |= BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP; -          if (oldmode != BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP) -            { -              /* TBD */ -            } -          break; -        case 'n': -          if (oldmode == BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_RH) -            { -              /* TBD */ -            } -          if (oldmode == BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP) -            { -              /* TBD */ -            } -          break; -        case 'r': -          if (oldmode == BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP) -            { -              /* TBD */ -            } -          bgp->rfapi_cfg->flags |= BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_RH; -          if (oldmode != BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_RH) -            { -              /* TBD */ -            } -          break; -        default: -          vty_out (vty, "Invalid mode\n"); -          return CMD_WARNING_CONFIG_FAILED; -        } -    } - -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	uint32_t oldmode = 0; +	uint32_t newmode = 0; + +	if (!bgp->rfapi_cfg) { +		vty_out(vty, "VNC not configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (argv[2]->arg[0] == 'b') { +		oldmode = bgp->rfapi_cfg->flags +			  & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS; +		switch (argv[4]->arg[0]) { +		case 'g': +			newmode = BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP; +			break; +		case 'c': +			newmode = BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE; +			break; +		case 'n': +			newmode = 0; +			break; +		case 'r': +			newmode = BGP_VNC_CONFIG_EXPORT_BGP_MODE_RH; +			break; +		default: +			vty_out(vty, "Invalid mode specified\n"); +			return CMD_WARNING_CONFIG_FAILED; +		} + +		if (newmode == oldmode) { +			vty_out(vty, "Mode unchanged\n"); +			return CMD_SUCCESS; +		} + +		vnc_export_bgp_prechange(bgp); + +		bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS; +		bgp->rfapi_cfg->flags |= newmode; + +		vnc_export_bgp_postchange(bgp); + + +	} else { +		/* +		 * export to zebra with RH mode is not yet implemented +		 */ +		vty_out(vty, +			"Changing modes for zebra export not implemented yet\n"); +		return CMD_WARNING_CONFIG_FAILED; + +		oldmode = bgp->rfapi_cfg->flags +			  & BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS; +		bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS; +		switch (argv[4]->arg[0]) { +		case 'g': +			if (oldmode == BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_RH) { +				/* TBD */ +			} +			bgp->rfapi_cfg->flags |= +				BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP; +			if (oldmode != BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP) { +				/* TBD */ +			} +			break; +		case 'n': +			if (oldmode == BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_RH) { +				/* TBD */ +			} +			if (oldmode == BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP) { +				/* TBD */ +			} +			break; +		case 'r': +			if (oldmode == BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP) { +				/* TBD */ +			} +			bgp->rfapi_cfg->flags |= +				BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_RH; +			if (oldmode != BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_RH) { +				/* TBD */ +			} +			break; +		default: +			vty_out(vty, "Invalid mode\n"); +			return CMD_WARNING_CONFIG_FAILED; +		} +	} + +	return CMD_SUCCESS;  } -static struct rfapi_rfg_name * -rfgn_new () +static struct rfapi_rfg_name *rfgn_new()  { -  return XCALLOC (MTYPE_RFAPI_RFG_NAME, sizeof (struct rfapi_rfg_name)); +	return XCALLOC(MTYPE_RFAPI_RFG_NAME, sizeof(struct rfapi_rfg_name));  } -static void -rfgn_free (struct rfapi_rfg_name *rfgn) +static void rfgn_free(struct rfapi_rfg_name *rfgn)  { -  XFREE (MTYPE_RFAPI_RFG_NAME, rfgn); +	XFREE(MTYPE_RFAPI_RFG_NAME, rfgn);  }  DEFUN (vnc_export_nvegroup, @@ -1620,91 +1496,86 @@ DEFUN (vnc_export_nvegroup,         "NVE group, used in 'group-nve' export mode\n"         "NVE group\n" "Group name\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  struct rfapi_nve_group_cfg *rfg_new; - -  if (!bgp->rfapi_cfg) -    { -      vty_out (vty, "rfapi not configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  rfg_new = bgp_rfapi_cfg_match_byname (bgp, argv[5]->arg, RFAPI_GROUP_CFG_NVE); - -  if (argv[2]->arg[0] == 'b') -    { - -      struct listnode *node; -      struct rfapi_rfg_name *rfgn; - -      /* -       * Set group for export to BGP Direct -       */ - -      /* see if group is already included in export list */ -      for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_direct_bgp_l, -                                 node, rfgn)) -        { - -          if (!strcmp (rfgn->name, argv[5]->arg)) -            { -              /* already in the list: we're done */ -              return CMD_SUCCESS; -            } -        } - -      rfgn = rfgn_new (); -      rfgn->name = strdup (argv[5]->arg); -      rfgn->rfg = rfg_new;      /* OK if not set yet */ - -      listnode_add (bgp->rfapi_cfg->rfg_export_direct_bgp_l, rfgn); - -      vnc_zlog_debug_verbose ("%s: testing rfg_new", __func__); -      if (rfg_new) -        { -          vnc_zlog_debug_verbose ("%s: testing bgp grp mode enabled", __func__); -          if (VNC_EXPORT_BGP_GRP_ENABLED (bgp->rfapi_cfg)) -            vnc_zlog_debug_verbose ("%s: calling vnc_direct_bgp_add_group", __func__); -          vnc_direct_bgp_add_group (bgp, rfg_new); -        } - -    } -  else -    { - -      struct listnode *node; -      struct rfapi_rfg_name *rfgn; - -      /* -       * Set group for export to Zebra -       */ - -      /* see if group is already included in export list */ -      for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_zebra_l, -                                 node, rfgn)) -        { - -          if (!strcmp (rfgn->name, argv[5]->arg)) -            { -              /* already in the list: we're done */ -              return CMD_SUCCESS; -            } -        } - -      rfgn = rfgn_new (); -      rfgn->name = strdup (argv[5]->arg); -      rfgn->rfg = rfg_new;      /* OK if not set yet */ - -      listnode_add (bgp->rfapi_cfg->rfg_export_zebra_l, rfgn); - -      if (rfg_new) -        { -          if (VNC_EXPORT_ZEBRA_GRP_ENABLED (bgp->rfapi_cfg)) -            vnc_zebra_add_group (bgp, rfg_new); -        } -    } - -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	struct rfapi_nve_group_cfg *rfg_new; + +	if (!bgp->rfapi_cfg) { +		vty_out(vty, "rfapi not configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	rfg_new = bgp_rfapi_cfg_match_byname(bgp, argv[5]->arg, +					     RFAPI_GROUP_CFG_NVE); + +	if (argv[2]->arg[0] == 'b') { + +		struct listnode *node; +		struct rfapi_rfg_name *rfgn; + +		/* +		 * Set group for export to BGP Direct +		 */ + +		/* see if group is already included in export list */ +		for (ALL_LIST_ELEMENTS_RO( +			     bgp->rfapi_cfg->rfg_export_direct_bgp_l, node, +			     rfgn)) { + +			if (!strcmp(rfgn->name, argv[5]->arg)) { +				/* already in the list: we're done */ +				return CMD_SUCCESS; +			} +		} + +		rfgn = rfgn_new(); +		rfgn->name = strdup(argv[5]->arg); +		rfgn->rfg = rfg_new; /* OK if not set yet */ + +		listnode_add(bgp->rfapi_cfg->rfg_export_direct_bgp_l, rfgn); + +		vnc_zlog_debug_verbose("%s: testing rfg_new", __func__); +		if (rfg_new) { +			vnc_zlog_debug_verbose( +				"%s: testing bgp grp mode enabled", __func__); +			if (VNC_EXPORT_BGP_GRP_ENABLED(bgp->rfapi_cfg)) +				vnc_zlog_debug_verbose( +					"%s: calling vnc_direct_bgp_add_group", +					__func__); +			vnc_direct_bgp_add_group(bgp, rfg_new); +		} + +	} else { + +		struct listnode *node; +		struct rfapi_rfg_name *rfgn; + +		/* +		 * Set group for export to Zebra +		 */ + +		/* see if group is already included in export list */ +		for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, +					  node, rfgn)) { + +			if (!strcmp(rfgn->name, argv[5]->arg)) { +				/* already in the list: we're done */ +				return CMD_SUCCESS; +			} +		} + +		rfgn = rfgn_new(); +		rfgn->name = strdup(argv[5]->arg); +		rfgn->rfg = rfg_new; /* OK if not set yet */ + +		listnode_add(bgp->rfapi_cfg->rfg_export_zebra_l, rfgn); + +		if (rfg_new) { +			if (VNC_EXPORT_ZEBRA_GRP_ENABLED(bgp->rfapi_cfg)) +				vnc_zebra_add_group(bgp, rfg_new); +		} +	} + +	return CMD_SUCCESS;  }  /* @@ -1721,54 +1592,52 @@ DEFUN (vnc_no_export_nvegroup,         "NVE group, used in 'group-nve' export mode\n"         "Disable export of VNC routes\n" "NVE group\n" "Group name\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  struct listnode *node, *nnode; -  struct rfapi_rfg_name *rfgn; - -  if (!bgp->rfapi_cfg) -    { -      vty_out (vty, "rfapi not configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (argv[2]->arg[0] == 'b') -    { -      for (ALL_LIST_ELEMENTS (bgp->rfapi_cfg->rfg_export_direct_bgp_l, -                              node, nnode, rfgn)) -        { - -          if (rfgn->name && !strcmp (rfgn->name, argv[6]->arg)) -            { -              vnc_zlog_debug_verbose ("%s: matched \"%s\"", __func__, rfgn->name); -              if (rfgn->rfg) -                vnc_direct_bgp_del_group (bgp, rfgn->rfg); -              free (rfgn->name); -              list_delete_node (bgp->rfapi_cfg->rfg_export_direct_bgp_l, -                                node); -              rfgn_free (rfgn); -              break; -            } -        } -    } -  else -    { -      for (ALL_LIST_ELEMENTS (bgp->rfapi_cfg->rfg_export_zebra_l, -                              node, nnode, rfgn)) -        { - -          vnc_zlog_debug_verbose ("does rfg \"%s\" match?", rfgn->name); -          if (rfgn->name && !strcmp (rfgn->name, argv[6]->arg)) -            { -              if (rfgn->rfg) -                vnc_zebra_del_group (bgp, rfgn->rfg); -              free (rfgn->name); -              list_delete_node (bgp->rfapi_cfg->rfg_export_zebra_l, node); -              rfgn_free (rfgn); -              break; -            } -        } -    } -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	struct listnode *node, *nnode; +	struct rfapi_rfg_name *rfgn; + +	if (!bgp->rfapi_cfg) { +		vty_out(vty, "rfapi not configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (argv[2]->arg[0] == 'b') { +		for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->rfg_export_direct_bgp_l, +				       node, nnode, rfgn)) { + +			if (rfgn->name && !strcmp(rfgn->name, argv[6]->arg)) { +				vnc_zlog_debug_verbose("%s: matched \"%s\"", +						       __func__, rfgn->name); +				if (rfgn->rfg) +					vnc_direct_bgp_del_group(bgp, +								 rfgn->rfg); +				free(rfgn->name); +				list_delete_node( +					bgp->rfapi_cfg->rfg_export_direct_bgp_l, +					node); +				rfgn_free(rfgn); +				break; +			} +		} +	} else { +		for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->rfg_export_zebra_l, node, +				       nnode, rfgn)) { + +			vnc_zlog_debug_verbose("does rfg \"%s\" match?", +					       rfgn->name); +			if (rfgn->name && !strcmp(rfgn->name, argv[6]->arg)) { +				if (rfgn->rfg) +					vnc_zebra_del_group(bgp, rfgn->rfg); +				free(rfgn->name); +				list_delete_node( +					bgp->rfapi_cfg->rfg_export_zebra_l, +					node); +				rfgn_free(rfgn); +				break; +			} +		} +	} +	return CMD_SUCCESS;  }  DEFUN (vnc_nve_group_export_no_prefixlist, @@ -1782,63 +1651,53 @@ DEFUN (vnc_nve_group_export_no_prefixlist,         "IPv6 routes\n"         "Prefix-list for filtering exported routes\n" "prefix list name\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); -  afi_t afi; - -  if (!bgp->rfapi_cfg) -    { -      vty_out (vty, "rfapi not configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  /* make sure it's still in list */ -  if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) -    { -      /* Not in list anymore */ -      vty_out (vty, "Current NVE group no longer exists\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (strmatch(argv[3]->text, "ipv4")) -    { -      afi = AFI_IP; -    } -  else -    { -      afi = AFI_IP6; -    } - -  if (argv[2]->arg[0] == 'b') -    { -      if (((argc > 5) -           && strmatch(argv[5]->text, rfg->plist_export_bgp_name[afi])) -          || (argc <= 5)) -        { - -          if (rfg->plist_export_bgp_name[afi]) -            free (rfg->plist_export_bgp_name[afi]); -          rfg->plist_export_bgp_name[afi] = NULL; -          rfg->plist_export_bgp[afi] = NULL; - -          vnc_direct_bgp_reexport_group_afi (bgp, rfg, afi); -        } -    } -  else -    { -      if (((argc > 5) -           && strmatch(argv[5]->text, rfg->plist_export_zebra_name[afi])) -          || (argc <= 5)) -        { -          if (rfg->plist_export_zebra_name[afi]) -            free (rfg->plist_export_zebra_name[afi]); -          rfg->plist_export_zebra_name[afi] = NULL; -          rfg->plist_export_zebra[afi] = NULL; - -          vnc_zebra_reexport_group_afi (bgp, rfg, afi); -        } -    } -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); +	afi_t afi; + +	if (!bgp->rfapi_cfg) { +		vty_out(vty, "rfapi not configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	/* make sure it's still in list */ +	if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { +		/* Not in list anymore */ +		vty_out(vty, "Current NVE group no longer exists\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (strmatch(argv[3]->text, "ipv4")) { +		afi = AFI_IP; +	} else { +		afi = AFI_IP6; +	} + +	if (argv[2]->arg[0] == 'b') { +		if (((argc > 5) && strmatch(argv[5]->text, +					    rfg->plist_export_bgp_name[afi])) +		    || (argc <= 5)) { + +			if (rfg->plist_export_bgp_name[afi]) +				free(rfg->plist_export_bgp_name[afi]); +			rfg->plist_export_bgp_name[afi] = NULL; +			rfg->plist_export_bgp[afi] = NULL; + +			vnc_direct_bgp_reexport_group_afi(bgp, rfg, afi); +		} +	} else { +		if (((argc > 5) && strmatch(argv[5]->text, +					    rfg->plist_export_zebra_name[afi])) +		    || (argc <= 5)) { +			if (rfg->plist_export_zebra_name[afi]) +				free(rfg->plist_export_zebra_name[afi]); +			rfg->plist_export_zebra_name[afi] = NULL; +			rfg->plist_export_zebra[afi] = NULL; + +			vnc_zebra_reexport_group_afi(bgp, rfg, afi); +		} +	} +	return CMD_SUCCESS;  }  DEFUN (vnc_nve_group_export_prefixlist, @@ -1851,53 +1710,47 @@ DEFUN (vnc_nve_group_export_prefixlist,         "IPv6 routes\n"         "Prefix-list for filtering exported routes\n" "prefix list name\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); -  afi_t afi; - -  if (!bgp->rfapi_cfg) -    { -      vty_out (vty, "rfapi not configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  /* make sure it's still in list */ -  if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) -    { -      /* Not in list anymore */ -      vty_out (vty, "Current NVE group no longer exists\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (strmatch(argv[2]->text, "ipv4")) -    { -      afi = AFI_IP; -    } -  else -    { -      afi = AFI_IP6; -    } - -  if (argv[1]->arg[0] == 'b') -    { -      if (rfg->plist_export_bgp_name[afi]) -        free (rfg->plist_export_bgp_name[afi]); -      rfg->plist_export_bgp_name[afi] = strdup (argv[4]->arg); -      rfg->plist_export_bgp[afi] = prefix_list_lookup (afi, argv[4]->arg); - -      vnc_direct_bgp_reexport_group_afi (bgp, rfg, afi); - -    } -  else -    { -      if (rfg->plist_export_zebra_name[afi]) -        free (rfg->plist_export_zebra_name[afi]); -      rfg->plist_export_zebra_name[afi] = strdup (argv[4]->arg); -      rfg->plist_export_zebra[afi] = prefix_list_lookup (afi, argv[4]->arg); - -      vnc_zebra_reexport_group_afi (bgp, rfg, afi); -    } -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); +	afi_t afi; + +	if (!bgp->rfapi_cfg) { +		vty_out(vty, "rfapi not configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	/* make sure it's still in list */ +	if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { +		/* Not in list anymore */ +		vty_out(vty, "Current NVE group no longer exists\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (strmatch(argv[2]->text, "ipv4")) { +		afi = AFI_IP; +	} else { +		afi = AFI_IP6; +	} + +	if (argv[1]->arg[0] == 'b') { +		if (rfg->plist_export_bgp_name[afi]) +			free(rfg->plist_export_bgp_name[afi]); +		rfg->plist_export_bgp_name[afi] = strdup(argv[4]->arg); +		rfg->plist_export_bgp[afi] = +			prefix_list_lookup(afi, argv[4]->arg); + +		vnc_direct_bgp_reexport_group_afi(bgp, rfg, afi); + +	} else { +		if (rfg->plist_export_zebra_name[afi]) +			free(rfg->plist_export_zebra_name[afi]); +		rfg->plist_export_zebra_name[afi] = strdup(argv[4]->arg); +		rfg->plist_export_zebra[afi] = +			prefix_list_lookup(afi, argv[4]->arg); + +		vnc_zebra_reexport_group_afi(bgp, rfg, afi); +	} +	return CMD_SUCCESS;  }  DEFUN (vnc_nve_group_export_no_routemap, @@ -1909,55 +1762,48 @@ DEFUN (vnc_nve_group_export_no_routemap,         "Export to Zebra (experimental)\n"         "Route-map for filtering exported routes\n" "route map name\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); - -  if (!bgp->rfapi_cfg) -    { -      vty_out (vty, "rfapi not configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  /* make sure it's still in list */ -  if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) -    { -      /* Not in list anymore */ -      vty_out (vty, "Current NVE group no longer exists\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (argv[2]->arg[0] == 'b') -    { -      if (((argc > 4) -           && strmatch(argv[4]->text, rfg->routemap_export_bgp_name)) -          || (argc <= 4)) -        { - -          if (rfg->routemap_export_bgp_name) -            free (rfg->routemap_export_bgp_name); -          rfg->routemap_export_bgp_name = NULL; -          rfg->routemap_export_bgp = NULL; - -          vnc_direct_bgp_reexport_group_afi (bgp, rfg, AFI_IP); -          vnc_direct_bgp_reexport_group_afi (bgp, rfg, AFI_IP6); -        } -    } -  else -    { -      if (((argc > 4) -           && strmatch(argv[4]->text, rfg->routemap_export_zebra_name)) -          || (argc <= 4)) -        { -          if (rfg->routemap_export_zebra_name) -            free (rfg->routemap_export_zebra_name); -          rfg->routemap_export_zebra_name = NULL; -          rfg->routemap_export_zebra = NULL; - -          vnc_zebra_reexport_group_afi (bgp, rfg, AFI_IP); -          vnc_zebra_reexport_group_afi (bgp, rfg, AFI_IP6); -        } -    } -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); + +	if (!bgp->rfapi_cfg) { +		vty_out(vty, "rfapi not configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	/* make sure it's still in list */ +	if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { +		/* Not in list anymore */ +		vty_out(vty, "Current NVE group no longer exists\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (argv[2]->arg[0] == 'b') { +		if (((argc > 4) +		     && strmatch(argv[4]->text, rfg->routemap_export_bgp_name)) +		    || (argc <= 4)) { + +			if (rfg->routemap_export_bgp_name) +				free(rfg->routemap_export_bgp_name); +			rfg->routemap_export_bgp_name = NULL; +			rfg->routemap_export_bgp = NULL; + +			vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP); +			vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP6); +		} +	} else { +		if (((argc > 4) && strmatch(argv[4]->text, +					    rfg->routemap_export_zebra_name)) +		    || (argc <= 4)) { +			if (rfg->routemap_export_zebra_name) +				free(rfg->routemap_export_zebra_name); +			rfg->routemap_export_zebra_name = NULL; +			rfg->routemap_export_zebra = NULL; + +			vnc_zebra_reexport_group_afi(bgp, rfg, AFI_IP); +			vnc_zebra_reexport_group_afi(bgp, rfg, AFI_IP6); +		} +	} +	return CMD_SUCCESS;  }  DEFUN (vnc_nve_group_export_routemap, @@ -1968,42 +1814,39 @@ DEFUN (vnc_nve_group_export_routemap,         "Export to Zebra (experimental)\n"         "Route-map for filtering exported routes\n" "route map name\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); - -  if (!bgp->rfapi_cfg) -    { -      vty_out (vty, "rfapi not configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  /* make sure it's still in list */ -  if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) -    { -      /* Not in list anymore */ -      vty_out (vty, "Current NVE group no longer exists\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (argv[1]->arg[0] == 'b') -    { -      if (rfg->routemap_export_bgp_name) -        free (rfg->routemap_export_bgp_name); -      rfg->routemap_export_bgp_name = strdup (argv[3]->arg); -      rfg->routemap_export_bgp = route_map_lookup_by_name (argv[3]->arg); -      vnc_direct_bgp_reexport_group_afi (bgp, rfg, AFI_IP); -      vnc_direct_bgp_reexport_group_afi (bgp, rfg, AFI_IP6); -    } -  else -    { -      if (rfg->routemap_export_zebra_name) -        free (rfg->routemap_export_zebra_name); -      rfg->routemap_export_zebra_name = strdup (argv[3]->arg); -      rfg->routemap_export_zebra = route_map_lookup_by_name (argv[3]->arg); -      vnc_zebra_reexport_group_afi (bgp, rfg, AFI_IP); -      vnc_zebra_reexport_group_afi (bgp, rfg, AFI_IP6); -    } -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); + +	if (!bgp->rfapi_cfg) { +		vty_out(vty, "rfapi not configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	/* make sure it's still in list */ +	if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { +		/* Not in list anymore */ +		vty_out(vty, "Current NVE group no longer exists\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (argv[1]->arg[0] == 'b') { +		if (rfg->routemap_export_bgp_name) +			free(rfg->routemap_export_bgp_name); +		rfg->routemap_export_bgp_name = strdup(argv[3]->arg); +		rfg->routemap_export_bgp = +			route_map_lookup_by_name(argv[3]->arg); +		vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP); +		vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP6); +	} else { +		if (rfg->routemap_export_zebra_name) +			free(rfg->routemap_export_zebra_name); +		rfg->routemap_export_zebra_name = strdup(argv[3]->arg); +		rfg->routemap_export_zebra = +			route_map_lookup_by_name(argv[3]->arg); +		vnc_zebra_reexport_group_afi(bgp, rfg, AFI_IP); +		vnc_zebra_reexport_group_afi(bgp, rfg, AFI_IP6); +	} +	return CMD_SUCCESS;  }  DEFUN (vnc_nve_export_no_prefixlist, @@ -2018,54 +1861,44 @@ DEFUN (vnc_nve_export_no_prefixlist,         "IPv6 prefixes\n"         "Prefix-list for filtering exported routes\n" "Prefix list name\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  struct rfapi_cfg *hc; -  afi_t afi; - -  if (!(hc = bgp->rfapi_cfg)) -    { -      vty_out (vty, "rfapi not configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (strmatch(argv[4]->text, "ipv4")) -    { -      afi = AFI_IP; -    } -  else -    { -      afi = AFI_IP6; -    } - -  if (argv[3]->arg[0] == 'b') -    { -      if (((argc > 6) -           && hc->plist_export_bgp_name[afi] -           && strmatch(argv[6]->text, hc->plist_export_bgp_name[afi])) -          || (argc <= 6)) -        { - -          free (hc->plist_export_bgp_name[afi]); -          hc->plist_export_bgp_name[afi] = NULL; -          hc->plist_export_bgp[afi] = NULL; -          vnc_direct_bgp_reexport (bgp, afi); -        } -    } -  else -    { -      if (((argc > 6) -           && hc->plist_export_zebra_name[afi] -           && strmatch(argv[6]->text, hc->plist_export_zebra_name[afi])) -          || (argc <= 6)) -        { - -          free (hc->plist_export_zebra_name[afi]); -          hc->plist_export_zebra_name[afi] = NULL; -          hc->plist_export_zebra[afi] = NULL; -          /* TBD vnc_zebra_rh_reexport(bgp, afi); */ -        } -    } -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	struct rfapi_cfg *hc; +	afi_t afi; + +	if (!(hc = bgp->rfapi_cfg)) { +		vty_out(vty, "rfapi not configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (strmatch(argv[4]->text, "ipv4")) { +		afi = AFI_IP; +	} else { +		afi = AFI_IP6; +	} + +	if (argv[3]->arg[0] == 'b') { +		if (((argc > 6) && hc->plist_export_bgp_name[afi] +		     && strmatch(argv[6]->text, hc->plist_export_bgp_name[afi])) +		    || (argc <= 6)) { + +			free(hc->plist_export_bgp_name[afi]); +			hc->plist_export_bgp_name[afi] = NULL; +			hc->plist_export_bgp[afi] = NULL; +			vnc_direct_bgp_reexport(bgp, afi); +		} +	} else { +		if (((argc > 6) && hc->plist_export_zebra_name[afi] +		     && strmatch(argv[6]->text, +				 hc->plist_export_zebra_name[afi])) +		    || (argc <= 6)) { + +			free(hc->plist_export_zebra_name[afi]); +			hc->plist_export_zebra_name[afi] = NULL; +			hc->plist_export_zebra[afi] = NULL; +			/* TBD vnc_zebra_rh_reexport(bgp, afi); */ +		} +	} +	return CMD_SUCCESS;  }  DEFUN (vnc_nve_export_prefixlist, @@ -2079,42 +1912,37 @@ DEFUN (vnc_nve_export_prefixlist,         "IPv6 prefixes\n"         "Prefix-list for filtering exported routes\n" "Prefix list name\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  struct rfapi_cfg *hc; -  afi_t afi; - -  if (!(hc = bgp->rfapi_cfg)) -    { -      vty_out (vty, "rfapi not configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (strmatch(argv[3]->text, "ipv4")) -    { -      afi = AFI_IP; -    } -  else -    { -      afi = AFI_IP6; -    } - -  if (argv[2]->arg[0] == 'b') -    { -      if (hc->plist_export_bgp_name[afi]) -        free (hc->plist_export_bgp_name[afi]); -      hc->plist_export_bgp_name[afi] = strdup (argv[5]->arg); -      hc->plist_export_bgp[afi] = prefix_list_lookup (afi, argv[5]->arg); -      vnc_direct_bgp_reexport (bgp, afi); -    } -  else -    { -      if (hc->plist_export_zebra_name[afi]) -        free (hc->plist_export_zebra_name[afi]); -      hc->plist_export_zebra_name[afi] = strdup (argv[5]->arg); -      hc->plist_export_zebra[afi] = prefix_list_lookup (afi, argv[5]->arg); -      /* TBD vnc_zebra_rh_reexport(bgp, afi); */ -    } -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	struct rfapi_cfg *hc; +	afi_t afi; + +	if (!(hc = bgp->rfapi_cfg)) { +		vty_out(vty, "rfapi not configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (strmatch(argv[3]->text, "ipv4")) { +		afi = AFI_IP; +	} else { +		afi = AFI_IP6; +	} + +	if (argv[2]->arg[0] == 'b') { +		if (hc->plist_export_bgp_name[afi]) +			free(hc->plist_export_bgp_name[afi]); +		hc->plist_export_bgp_name[afi] = strdup(argv[5]->arg); +		hc->plist_export_bgp[afi] = +			prefix_list_lookup(afi, argv[5]->arg); +		vnc_direct_bgp_reexport(bgp, afi); +	} else { +		if (hc->plist_export_zebra_name[afi]) +			free(hc->plist_export_zebra_name[afi]); +		hc->plist_export_zebra_name[afi] = strdup(argv[5]->arg); +		hc->plist_export_zebra[afi] = +			prefix_list_lookup(afi, argv[5]->arg); +		/* TBD vnc_zebra_rh_reexport(bgp, afi); */ +	} +	return CMD_SUCCESS;  }  DEFUN (vnc_nve_export_no_routemap, @@ -2127,46 +1955,38 @@ DEFUN (vnc_nve_export_no_routemap,         "Export to Zebra (experimental)\n"         "Route-map for filtering exported routes\n" "Route map name\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  struct rfapi_cfg *hc; - -  if (!(hc = bgp->rfapi_cfg)) -    { -      vty_out (vty, "rfapi not configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (argv[3]->arg[0] == 'b') -    { -      if (((argc > 5) -           && hc->routemap_export_bgp_name -           && strmatch(argv[5]->text, hc->routemap_export_bgp_name)) -          || (argc <= 5)) -        { - -          free (hc->routemap_export_bgp_name); -          hc->routemap_export_bgp_name = NULL; -          hc->routemap_export_bgp = NULL; -          vnc_direct_bgp_reexport (bgp, AFI_IP); -          vnc_direct_bgp_reexport (bgp, AFI_IP6); -        } -    } -  else -    { -      if (((argc > 5) -           && hc->routemap_export_zebra_name -           && strmatch(argv[5]->text, hc->routemap_export_zebra_name)) -          || (argc <= 5)) -        { - -          free (hc->routemap_export_zebra_name); -          hc->routemap_export_zebra_name = NULL; -          hc->routemap_export_zebra = NULL; -          /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */ -          /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */ -        } -    } -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	struct rfapi_cfg *hc; + +	if (!(hc = bgp->rfapi_cfg)) { +		vty_out(vty, "rfapi not configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (argv[3]->arg[0] == 'b') { +		if (((argc > 5) && hc->routemap_export_bgp_name +		     && strmatch(argv[5]->text, hc->routemap_export_bgp_name)) +		    || (argc <= 5)) { + +			free(hc->routemap_export_bgp_name); +			hc->routemap_export_bgp_name = NULL; +			hc->routemap_export_bgp = NULL; +			vnc_direct_bgp_reexport(bgp, AFI_IP); +			vnc_direct_bgp_reexport(bgp, AFI_IP6); +		} +	} else { +		if (((argc > 5) && hc->routemap_export_zebra_name +		     && strmatch(argv[5]->text, hc->routemap_export_zebra_name)) +		    || (argc <= 5)) { + +			free(hc->routemap_export_zebra_name); +			hc->routemap_export_zebra_name = NULL; +			hc->routemap_export_zebra = NULL; +			/* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */ +			/* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */ +		} +	} +	return CMD_SUCCESS;  }  DEFUN (vnc_nve_export_routemap, @@ -2178,232 +1998,210 @@ DEFUN (vnc_nve_export_routemap,         "Export to Zebra (experimental)\n"         "Route-map for filtering exported routes\n" "Route map name\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  struct rfapi_cfg *hc; - -  if (!(hc = bgp->rfapi_cfg)) -    { -      vty_out (vty, "rfapi not configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (argv[2]->arg[0] == 'b') -    { -      if (hc->routemap_export_bgp_name) -        free (hc->routemap_export_bgp_name); -      hc->routemap_export_bgp_name = strdup (argv[4]->arg); -      hc->routemap_export_bgp = route_map_lookup_by_name (argv[4]->arg); -      vnc_direct_bgp_reexport (bgp, AFI_IP); -      vnc_direct_bgp_reexport (bgp, AFI_IP6); -    } -  else -    { -      if (hc->routemap_export_zebra_name) -        free (hc->routemap_export_zebra_name); -      hc->routemap_export_zebra_name = strdup (argv[4]->arg); -      hc->routemap_export_zebra = route_map_lookup_by_name (argv[4]->arg); -      /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */ -      /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */ -    } -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	struct rfapi_cfg *hc; + +	if (!(hc = bgp->rfapi_cfg)) { +		vty_out(vty, "rfapi not configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (argv[2]->arg[0] == 'b') { +		if (hc->routemap_export_bgp_name) +			free(hc->routemap_export_bgp_name); +		hc->routemap_export_bgp_name = strdup(argv[4]->arg); +		hc->routemap_export_bgp = +			route_map_lookup_by_name(argv[4]->arg); +		vnc_direct_bgp_reexport(bgp, AFI_IP); +		vnc_direct_bgp_reexport(bgp, AFI_IP6); +	} else { +		if (hc->routemap_export_zebra_name) +			free(hc->routemap_export_zebra_name); +		hc->routemap_export_zebra_name = strdup(argv[4]->arg); +		hc->routemap_export_zebra = +			route_map_lookup_by_name(argv[4]->arg); +		/* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */ +		/* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */ +	} +	return CMD_SUCCESS;  }  /*   * respond to changes in the global prefix list configuration   */ -void -vnc_prefix_list_update (struct bgp *bgp) +void vnc_prefix_list_update(struct bgp *bgp)  { -  afi_t afi; -  struct listnode *n; -  struct rfapi_nve_group_cfg *rfg; -  struct rfapi_cfg *hc; -  int i; - -  if (!bgp) -    { -      vnc_zlog_debug_verbose ("%s: No BGP process is configured", __func__); -      return; -    } - -  if (!(hc = bgp->rfapi_cfg)) -    { -      vnc_zlog_debug_verbose ("%s: rfapi not configured", __func__); -      return; -    } - -  for (afi = AFI_IP; afi < AFI_MAX; afi++) -    { -      /* -       * Loop over nve groups -       */ -      for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->nve_groups_sequential, -                                 n, rfg)) -        { - -          if (rfg->plist_export_bgp_name[afi]) -            { -              rfg->plist_export_bgp[afi] = -                prefix_list_lookup (afi, rfg->plist_export_bgp_name[afi]); -            } -          if (rfg->plist_export_zebra_name[afi]) -            { -              rfg->plist_export_zebra[afi] = -                prefix_list_lookup (afi, rfg->plist_export_zebra_name[afi]); -            } -          for (i = 0; i < ZEBRA_ROUTE_MAX; ++i) -            { -              if (rfg->plist_redist_name[i][afi]) -                { -                  rfg->plist_redist[i][afi] = -                    prefix_list_lookup (afi, rfg->plist_redist_name[i][afi]); -                } -            } - -          vnc_direct_bgp_reexport_group_afi (bgp, rfg, afi); -          /* TBD vnc_zebra_reexport_group_afi(bgp, rfg, afi); */ -        } - -      /* -       * RH config, too -       */ -      if (hc->plist_export_bgp_name[afi]) -        { -          hc->plist_export_bgp[afi] = -            prefix_list_lookup (afi, hc->plist_export_bgp_name[afi]); -        } -      if (hc->plist_export_zebra_name[afi]) -        { -          hc->plist_export_zebra[afi] = -            prefix_list_lookup (afi, hc->plist_export_zebra_name[afi]); -        } - -      for (i = 0; i < ZEBRA_ROUTE_MAX; ++i) -        { -          if (hc->plist_redist_name[i][afi]) -            { -              hc->plist_redist[i][afi] = -                prefix_list_lookup (afi, hc->plist_redist_name[i][afi]); -            } -        } - -    } - -  vnc_direct_bgp_reexport (bgp, AFI_IP); -  vnc_direct_bgp_reexport (bgp, AFI_IP6); - -  /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */ -  /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */ - -  vnc_redistribute_prechange (bgp); -  vnc_redistribute_postchange (bgp); +	afi_t afi; +	struct listnode *n; +	struct rfapi_nve_group_cfg *rfg; +	struct rfapi_cfg *hc; +	int i; + +	if (!bgp) { +		vnc_zlog_debug_verbose("%s: No BGP process is configured", +				       __func__); +		return; +	} + +	if (!(hc = bgp->rfapi_cfg)) { +		vnc_zlog_debug_verbose("%s: rfapi not configured", __func__); +		return; +	} + +	for (afi = AFI_IP; afi < AFI_MAX; afi++) { +		/* +		 * Loop over nve groups +		 */ +		for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->nve_groups_sequential, +					  n, rfg)) { + +			if (rfg->plist_export_bgp_name[afi]) { +				rfg->plist_export_bgp[afi] = prefix_list_lookup( +					afi, rfg->plist_export_bgp_name[afi]); +			} +			if (rfg->plist_export_zebra_name[afi]) { +				rfg->plist_export_zebra +					[afi] = prefix_list_lookup( +					afi, rfg->plist_export_zebra_name[afi]); +			} +			for (i = 0; i < ZEBRA_ROUTE_MAX; ++i) { +				if (rfg->plist_redist_name[i][afi]) { +					rfg->plist_redist +						[i][afi] = prefix_list_lookup( +						afi, +						rfg->plist_redist_name[i][afi]); +				} +			} + +			vnc_direct_bgp_reexport_group_afi(bgp, rfg, afi); +			/* TBD vnc_zebra_reexport_group_afi(bgp, rfg, afi); */ +		} + +		/* +		 * RH config, too +		 */ +		if (hc->plist_export_bgp_name[afi]) { +			hc->plist_export_bgp[afi] = prefix_list_lookup( +				afi, hc->plist_export_bgp_name[afi]); +		} +		if (hc->plist_export_zebra_name[afi]) { +			hc->plist_export_zebra[afi] = prefix_list_lookup( +				afi, hc->plist_export_zebra_name[afi]); +		} + +		for (i = 0; i < ZEBRA_ROUTE_MAX; ++i) { +			if (hc->plist_redist_name[i][afi]) { +				hc->plist_redist[i][afi] = prefix_list_lookup( +					afi, hc->plist_redist_name[i][afi]); +			} +		} +	} + +	vnc_direct_bgp_reexport(bgp, AFI_IP); +	vnc_direct_bgp_reexport(bgp, AFI_IP6); + +	/* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */ +	/* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */ + +	vnc_redistribute_prechange(bgp); +	vnc_redistribute_postchange(bgp);  }  /*   * respond to changes in the global route map configuration   */ -void -vnc_routemap_update (struct bgp *bgp, const char *unused) +void vnc_routemap_update(struct bgp *bgp, const char *unused)  { -  struct listnode *n; -  struct rfapi_nve_group_cfg *rfg; -  struct rfapi_cfg *hc; -  int i; - -  vnc_zlog_debug_verbose ("%s(arg=%s)", __func__, unused); - -  if (!bgp) -    { -      vnc_zlog_debug_verbose ("%s: No BGP process is configured", __func__); -      return; -    } - -  if (!(hc = bgp->rfapi_cfg)) -    { -      vnc_zlog_debug_verbose ("%s: rfapi not configured", __func__); -      return; -    } - -  /* -   * Loop over nve groups -   */ -  for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->nve_groups_sequential, n, rfg)) -    { - -      if (rfg->routemap_export_bgp_name) -        { -          rfg->routemap_export_bgp = -            route_map_lookup_by_name (rfg->routemap_export_bgp_name); -        } -      if (rfg->routemap_export_zebra_name) -        { -          rfg->routemap_export_bgp = -            route_map_lookup_by_name (rfg->routemap_export_zebra_name); -        } -      for (i = 0; i < ZEBRA_ROUTE_MAX; ++i) -        { -          if (rfg->routemap_redist_name[i]) -            { -              rfg->routemap_redist[i] = -                route_map_lookup_by_name (rfg->routemap_redist_name[i]); -            } -        } - -      vnc_direct_bgp_reexport_group_afi (bgp, rfg, AFI_IP); -      vnc_direct_bgp_reexport_group_afi (bgp, rfg, AFI_IP6); -      /* TBD vnc_zebra_reexport_group_afi(bgp, rfg, afi); */ -    } - -  /* -   * RH config, too -   */ -  if (hc->routemap_export_bgp_name) -    { -      hc->routemap_export_bgp = -        route_map_lookup_by_name (hc->routemap_export_bgp_name); -    } -  if (hc->routemap_export_zebra_name) -    { -      hc->routemap_export_bgp = -        route_map_lookup_by_name (hc->routemap_export_zebra_name); -    } -  for (i = 0; i < ZEBRA_ROUTE_MAX; ++i) -    { -      if (hc->routemap_redist_name[i]) -        { -          hc->routemap_redist[i] = -            route_map_lookup_by_name (hc->routemap_redist_name[i]); -        } -    } - -  vnc_direct_bgp_reexport (bgp, AFI_IP); -  vnc_direct_bgp_reexport (bgp, AFI_IP6); - -  /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */ -  /* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */ - -  vnc_redistribute_prechange (bgp); -  vnc_redistribute_postchange (bgp); - -  vnc_zlog_debug_verbose ("%s done", __func__); +	struct listnode *n; +	struct rfapi_nve_group_cfg *rfg; +	struct rfapi_cfg *hc; +	int i; + +	vnc_zlog_debug_verbose("%s(arg=%s)", __func__, unused); + +	if (!bgp) { +		vnc_zlog_debug_verbose("%s: No BGP process is configured", +				       __func__); +		return; +	} + +	if (!(hc = bgp->rfapi_cfg)) { +		vnc_zlog_debug_verbose("%s: rfapi not configured", __func__); +		return; +	} + +	/* +	 * Loop over nve groups +	 */ +	for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->nve_groups_sequential, n, +				  rfg)) { + +		if (rfg->routemap_export_bgp_name) { +			rfg->routemap_export_bgp = route_map_lookup_by_name( +				rfg->routemap_export_bgp_name); +		} +		if (rfg->routemap_export_zebra_name) { +			rfg->routemap_export_bgp = route_map_lookup_by_name( +				rfg->routemap_export_zebra_name); +		} +		for (i = 0; i < ZEBRA_ROUTE_MAX; ++i) { +			if (rfg->routemap_redist_name[i]) { +				rfg->routemap_redist[i] = +					route_map_lookup_by_name( +						rfg->routemap_redist_name[i]); +			} +		} + +		vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP); +		vnc_direct_bgp_reexport_group_afi(bgp, rfg, AFI_IP6); +		/* TBD vnc_zebra_reexport_group_afi(bgp, rfg, afi); */ +	} + +	/* +	 * RH config, too +	 */ +	if (hc->routemap_export_bgp_name) { +		hc->routemap_export_bgp = +			route_map_lookup_by_name(hc->routemap_export_bgp_name); +	} +	if (hc->routemap_export_zebra_name) { +		hc->routemap_export_bgp = route_map_lookup_by_name( +			hc->routemap_export_zebra_name); +	} +	for (i = 0; i < ZEBRA_ROUTE_MAX; ++i) { +		if (hc->routemap_redist_name[i]) { +			hc->routemap_redist[i] = route_map_lookup_by_name( +				hc->routemap_redist_name[i]); +		} +	} + +	vnc_direct_bgp_reexport(bgp, AFI_IP); +	vnc_direct_bgp_reexport(bgp, AFI_IP6); + +	/* TBD vnc_zebra_rh_reexport(bgp, AFI_IP); */ +	/* TBD vnc_zebra_rh_reexport(bgp, AFI_IP6); */ + +	vnc_redistribute_prechange(bgp); +	vnc_redistribute_postchange(bgp); + +	vnc_zlog_debug_verbose("%s done", __func__);  } -static void -vnc_routemap_event (route_map_event_t type,     /* ignored */ -                    const char *rmap_name)      /* ignored */ +static void vnc_routemap_event(route_map_event_t type, /* ignored */ +			       const char *rmap_name)  /* ignored */  { -  struct listnode *mnode, *mnnode; -  struct bgp *bgp; +	struct listnode *mnode, *mnnode; +	struct bgp *bgp; -  vnc_zlog_debug_verbose ("%s(event type=%d)", __func__, type); -  if (bm->bgp == NULL)          /* may be called during cleanup */ -    return; +	vnc_zlog_debug_verbose("%s(event type=%d)", __func__, type); +	if (bm->bgp == NULL) /* may be called during cleanup */ +		return; -  for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp)) -    vnc_routemap_update (bgp, rmap_name); +	for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) +		vnc_routemap_update(bgp, rmap_name); -  vnc_zlog_debug_verbose ("%s: done", __func__); +	vnc_zlog_debug_verbose("%s: done", __func__);  }  /*------------------------------------------------------------------------- @@ -2416,288 +2214,267 @@ DEFUN_NOSH (vnc_nve_group,         "vnc nve-group NAME",         VNC_CONFIG_STR "Configure a NVE group\n" "Group name\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  struct rfapi_nve_group_cfg *rfg; -  struct listnode *node, *nnode; -  struct rfapi_rfg_name *rfgn; - -  /* Search for name */ -  rfg = bgp_rfapi_cfg_match_byname (bgp, argv[2]->arg, RFAPI_GROUP_CFG_NVE); - -  if (!rfg) -    { -      rfg = rfapi_group_new (bgp, RFAPI_GROUP_CFG_NVE, argv[2]->arg); -      if (!rfg) -        { -          /* Error out of memory */ -          vty_out (vty, "Can't allocate memory for NVE group\n"); -          return CMD_WARNING_CONFIG_FAILED; -        } - -      /* Copy defaults from struct rfapi_cfg */ -      rfg->rd = bgp->rfapi_cfg->default_rd; -      if (bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_L2RD) -        { -          rfg->l2rd = bgp->rfapi_cfg->default_l2rd; -          rfg->flags |= RFAPI_RFG_L2RD; -        } -      rfg->rd = bgp->rfapi_cfg->default_rd; -      rfg->response_lifetime = bgp->rfapi_cfg->default_response_lifetime; - -      if (bgp->rfapi_cfg->default_rt_export_list) -        { -          rfg->rt_export_list = -            ecommunity_dup (bgp->rfapi_cfg->default_rt_export_list); -        } - -      if (bgp->rfapi_cfg->default_rt_import_list) -        { -          rfg->rt_import_list = -            ecommunity_dup (bgp->rfapi_cfg->default_rt_import_list); -          rfg->rfapi_import_table = -            rfapiImportTableRefAdd (bgp, rfg->rt_import_list, rfg); -        } - -      /* -       * If a redist nve group was named but the group was not defined, -       * make the linkage now -       */ -      if (!bgp->rfapi_cfg->rfg_redist) -        { -          if (bgp->rfapi_cfg->rfg_redist_name && -              !strcmp (bgp->rfapi_cfg->rfg_redist_name, rfg->name)) -            { - -              vnc_redistribute_prechange (bgp); -              bgp->rfapi_cfg->rfg_redist = rfg; -              vnc_redistribute_postchange (bgp); - -            } -        } - -      /* -       * Same treatment for bgp-direct export group -       */ -      for (ALL_LIST_ELEMENTS (bgp->rfapi_cfg->rfg_export_direct_bgp_l, -                              node, nnode, rfgn)) -        { - -          if (!strcmp (rfgn->name, rfg->name)) -            { -              rfgn->rfg = rfg; -              vnc_direct_bgp_add_group (bgp, rfg); -              break; -            } -        } - -      /* -       * Same treatment for zebra export group -       */ -      for (ALL_LIST_ELEMENTS (bgp->rfapi_cfg->rfg_export_zebra_l, -                              node, nnode, rfgn)) -        { - -          vnc_zlog_debug_verbose ("%s: ezport zebra: checking if \"%s\" == \"%s\"", -                      __func__, rfgn->name, rfg->name); -          if (!strcmp (rfgn->name, rfg->name)) -            { -              rfgn->rfg = rfg; -              vnc_zebra_add_group (bgp, rfg); -              break; -            } -        } -    } - -  /* -   * XXX subsequent calls will need to make sure this item is still -   * in the linked list and has the same name -   */ -  VTY_PUSH_CONTEXT_SUB (BGP_VNC_NVE_GROUP_NODE, rfg); - -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	struct rfapi_nve_group_cfg *rfg; +	struct listnode *node, *nnode; +	struct rfapi_rfg_name *rfgn; + +	/* Search for name */ +	rfg = bgp_rfapi_cfg_match_byname(bgp, argv[2]->arg, +					 RFAPI_GROUP_CFG_NVE); + +	if (!rfg) { +		rfg = rfapi_group_new(bgp, RFAPI_GROUP_CFG_NVE, argv[2]->arg); +		if (!rfg) { +			/* Error out of memory */ +			vty_out(vty, "Can't allocate memory for NVE group\n"); +			return CMD_WARNING_CONFIG_FAILED; +		} + +		/* Copy defaults from struct rfapi_cfg */ +		rfg->rd = bgp->rfapi_cfg->default_rd; +		if (bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_L2RD) { +			rfg->l2rd = bgp->rfapi_cfg->default_l2rd; +			rfg->flags |= RFAPI_RFG_L2RD; +		} +		rfg->rd = bgp->rfapi_cfg->default_rd; +		rfg->response_lifetime = +			bgp->rfapi_cfg->default_response_lifetime; + +		if (bgp->rfapi_cfg->default_rt_export_list) { +			rfg->rt_export_list = ecommunity_dup( +				bgp->rfapi_cfg->default_rt_export_list); +		} + +		if (bgp->rfapi_cfg->default_rt_import_list) { +			rfg->rt_import_list = ecommunity_dup( +				bgp->rfapi_cfg->default_rt_import_list); +			rfg->rfapi_import_table = rfapiImportTableRefAdd( +				bgp, rfg->rt_import_list, rfg); +		} + +		/* +		 * If a redist nve group was named but the group was not +		 * defined, +		 * make the linkage now +		 */ +		if (!bgp->rfapi_cfg->rfg_redist) { +			if (bgp->rfapi_cfg->rfg_redist_name +			    && !strcmp(bgp->rfapi_cfg->rfg_redist_name, +				       rfg->name)) { + +				vnc_redistribute_prechange(bgp); +				bgp->rfapi_cfg->rfg_redist = rfg; +				vnc_redistribute_postchange(bgp); +			} +		} + +		/* +		 * Same treatment for bgp-direct export group +		 */ +		for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->rfg_export_direct_bgp_l, +				       node, nnode, rfgn)) { + +			if (!strcmp(rfgn->name, rfg->name)) { +				rfgn->rfg = rfg; +				vnc_direct_bgp_add_group(bgp, rfg); +				break; +			} +		} + +		/* +		 * Same treatment for zebra export group +		 */ +		for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->rfg_export_zebra_l, node, +				       nnode, rfgn)) { + +			vnc_zlog_debug_verbose( +				"%s: ezport zebra: checking if \"%s\" == \"%s\"", +				__func__, rfgn->name, rfg->name); +			if (!strcmp(rfgn->name, rfg->name)) { +				rfgn->rfg = rfg; +				vnc_zebra_add_group(bgp, rfg); +				break; +			} +		} +	} + +	/* +	 * XXX subsequent calls will need to make sure this item is still +	 * in the linked list and has the same name +	 */ +	VTY_PUSH_CONTEXT_SUB(BGP_VNC_NVE_GROUP_NODE, rfg); + +	return CMD_SUCCESS;  } -static void -bgp_rfapi_delete_nve_group ( -  struct vty			*vty,    /* NULL = no output */ -  struct bgp			*bgp, -  struct rfapi_nve_group_cfg	*rfg) +static void bgp_rfapi_delete_nve_group(struct vty *vty, /* NULL = no output */ +				       struct bgp *bgp, +				       struct rfapi_nve_group_cfg *rfg)  { -  struct list *orphaned_nves = NULL; -  struct listnode *node, *nnode; - -  /* -   * If there are currently-open NVEs that belong to this group, -   * zero out their references to this group structure. -   */ -  if (rfg->nves) -    { -      struct rfapi_descriptor *rfd; -      orphaned_nves = list_new (); -      while ((rfd = listnode_head (rfg->nves))) -        { -          rfd->rfg = NULL; -          listnode_delete (rfg->nves, rfd); -          listnode_add (orphaned_nves, rfd); -        } -      list_delete (rfg->nves); -      rfg->nves = NULL; -    } - -  /* delete it */ -  free (rfg->name); -  if (rfg->rfapi_import_table) -    rfapiImportTableRefDelByIt (bgp, rfg->rfapi_import_table); -  if (rfg->rt_import_list) -    ecommunity_free (&rfg->rt_import_list); -  if (rfg->rt_export_list) -    ecommunity_free (&rfg->rt_export_list); - -  if (rfg->vn_node) -    { -      rfg->vn_node->info = NULL; -      route_unlock_node (rfg->vn_node); /* frees */ -    } -  if (rfg->un_node) -    { -      rfg->un_node->info = NULL; -      route_unlock_node (rfg->un_node); /* frees */ -    } -  if (rfg->rfp_cfg) -    XFREE (MTYPE_RFAPI_RFP_GROUP_CFG, rfg->rfp_cfg); -  listnode_delete (bgp->rfapi_cfg->nve_groups_sequential, rfg); - -  QOBJ_UNREG (rfg); -  XFREE (MTYPE_RFAPI_GROUP_CFG, rfg); - -  /* -   * Attempt to reassign the orphaned nves to a new group. If -   * a NVE can not be reassigned, its rfd->rfg will remain NULL -   * and it will become a zombie until released by rfapi_close(). -   */ -  if (orphaned_nves) -    { -      struct rfapi_descriptor *rfd; - -      for (ALL_LIST_ELEMENTS (orphaned_nves, node, nnode, rfd)) -        { -          /* -           * 1. rfapi_close() equivalent except: -           *          a. don't free original descriptor -           *          b. remember query list -           *          c. remember advertised route list -           * 2. rfapi_open() equivalent except: -           *          a. reuse original descriptor -           * 3. rfapi_register() on remembered advertised route list -           * 4. rfapi_query on rememebred query list -           */ - -          int rc; - -          rc = rfapi_reopen (rfd, bgp); - -          if (!rc) -            { -              list_delete_node (orphaned_nves, node); -              if (vty) -                vty_out (vty, "WARNING: reassigned NVE vn="); -              rfapiPrintRfapiIpAddr (vty, &rfd->vn_addr); -              if (vty) -                vty_out (vty, " un="); -              rfapiPrintRfapiIpAddr (vty, &rfd->un_addr); -              if (vty) -                vty_out (vty, " to new group \"%s\"\n",rfd->rfg->name); - -            } -        } - -      for (ALL_LIST_ELEMENTS_RO (orphaned_nves, node, rfd)) -        { -          if (vty) -            vty_out (vty, "WARNING: orphaned NVE vn="); -          rfapiPrintRfapiIpAddr (vty, &rfd->vn_addr); -          if (vty) -            vty_out (vty, " un="); -          rfapiPrintRfapiIpAddr (vty, &rfd->un_addr); -          if (vty) -            vty_out (vty, "\n"); -        } -      list_delete (orphaned_nves); -    } +	struct list *orphaned_nves = NULL; +	struct listnode *node, *nnode; + +	/* +	 * If there are currently-open NVEs that belong to this group, +	 * zero out their references to this group structure. +	 */ +	if (rfg->nves) { +		struct rfapi_descriptor *rfd; +		orphaned_nves = list_new(); +		while ((rfd = listnode_head(rfg->nves))) { +			rfd->rfg = NULL; +			listnode_delete(rfg->nves, rfd); +			listnode_add(orphaned_nves, rfd); +		} +		list_delete(rfg->nves); +		rfg->nves = NULL; +	} + +	/* delete it */ +	free(rfg->name); +	if (rfg->rfapi_import_table) +		rfapiImportTableRefDelByIt(bgp, rfg->rfapi_import_table); +	if (rfg->rt_import_list) +		ecommunity_free(&rfg->rt_import_list); +	if (rfg->rt_export_list) +		ecommunity_free(&rfg->rt_export_list); + +	if (rfg->vn_node) { +		rfg->vn_node->info = NULL; +		route_unlock_node(rfg->vn_node); /* frees */ +	} +	if (rfg->un_node) { +		rfg->un_node->info = NULL; +		route_unlock_node(rfg->un_node); /* frees */ +	} +	if (rfg->rfp_cfg) +		XFREE(MTYPE_RFAPI_RFP_GROUP_CFG, rfg->rfp_cfg); +	listnode_delete(bgp->rfapi_cfg->nve_groups_sequential, rfg); + +	QOBJ_UNREG(rfg); +	XFREE(MTYPE_RFAPI_GROUP_CFG, rfg); + +	/* +	 * Attempt to reassign the orphaned nves to a new group. If +	 * a NVE can not be reassigned, its rfd->rfg will remain NULL +	 * and it will become a zombie until released by rfapi_close(). +	 */ +	if (orphaned_nves) { +		struct rfapi_descriptor *rfd; + +		for (ALL_LIST_ELEMENTS(orphaned_nves, node, nnode, rfd)) { +			/* +			 * 1. rfapi_close() equivalent except: +			 *          a. don't free original descriptor +			 *          b. remember query list +			 *          c. remember advertised route list +			 * 2. rfapi_open() equivalent except: +			 *          a. reuse original descriptor +			 * 3. rfapi_register() on remembered advertised route +			 * list +			 * 4. rfapi_query on rememebred query list +			 */ + +			int rc; + +			rc = rfapi_reopen(rfd, bgp); + +			if (!rc) { +				list_delete_node(orphaned_nves, node); +				if (vty) +					vty_out(vty, +						"WARNING: reassigned NVE vn="); +				rfapiPrintRfapiIpAddr(vty, &rfd->vn_addr); +				if (vty) +					vty_out(vty, " un="); +				rfapiPrintRfapiIpAddr(vty, &rfd->un_addr); +				if (vty) +					vty_out(vty, " to new group \"%s\"\n", +						rfd->rfg->name); +			} +		} + +		for (ALL_LIST_ELEMENTS_RO(orphaned_nves, node, rfd)) { +			if (vty) +				vty_out(vty, "WARNING: orphaned NVE vn="); +			rfapiPrintRfapiIpAddr(vty, &rfd->vn_addr); +			if (vty) +				vty_out(vty, " un="); +			rfapiPrintRfapiIpAddr(vty, &rfd->un_addr); +			if (vty) +				vty_out(vty, "\n"); +		} +		list_delete(orphaned_nves); +	}  }  static int -bgp_rfapi_delete_named_nve_group ( -  struct vty *vty,      /* NULL = no output */ -  struct bgp *bgp, -  const char *rfg_name, /* NULL = any */ -  rfapi_group_cfg_type_t type)  /* _MAX = any */ +bgp_rfapi_delete_named_nve_group(struct vty *vty, /* NULL = no output */ +				 struct bgp *bgp, +				 const char *rfg_name,	/* NULL = any */ +				 rfapi_group_cfg_type_t type) /* _MAX = any */  { -  struct rfapi_nve_group_cfg *rfg = NULL; -  struct listnode *node, *nnode; -  struct rfapi_rfg_name *rfgn; - -  /* Search for name */ -  if (rfg_name) -    { -      rfg = bgp_rfapi_cfg_match_byname (bgp, rfg_name, type); -      if (!rfg) -        { -          if (vty) -            vty_out (vty, "No NVE group named \"%s\"\n",rfg_name); -          return CMD_WARNING_CONFIG_FAILED; -        } -    } - -  /* -   * If this group is the redist nve group, unlink it -   */ -  if (rfg_name == NULL || bgp->rfapi_cfg->rfg_redist == rfg) -    { -      vnc_redistribute_prechange (bgp); -      bgp->rfapi_cfg->rfg_redist = NULL; -      vnc_redistribute_postchange (bgp); -    } - - -  /* -   * remove reference from bgp direct export list -   */ -  for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_direct_bgp_l, -                             node, rfgn)) -    { -      if (rfg_name == NULL || -          (type == RFAPI_GROUP_CFG_NVE && !strcmp (rfgn->name, rfg_name))) -        { -          rfgn->rfg = NULL; -          /* remove exported routes from this group */ -          vnc_direct_bgp_del_group (bgp, rfg); -          break; -        } -    } - -  /* -   * remove reference from zebra export list -   */ -  for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_zebra_l, node, rfgn)) -    { - -      if (rfg_name == NULL || -          (type == RFAPI_GROUP_CFG_NVE && !strcmp (rfgn->name, rfg_name))) -        { -          rfgn->rfg = NULL; -          /* remove exported routes from this group */ -          vnc_zebra_del_group (bgp, rfg); -          break; -        } -    } -  if (rfg) -    bgp_rfapi_delete_nve_group (vty, bgp, rfg); -  else                          /* must be delete all */ -    for (ALL_LIST_ELEMENTS -         (bgp->rfapi_cfg->nve_groups_sequential, node, nnode, rfg)) -      bgp_rfapi_delete_nve_group (vty, bgp, rfg); -  return CMD_SUCCESS; +	struct rfapi_nve_group_cfg *rfg = NULL; +	struct listnode *node, *nnode; +	struct rfapi_rfg_name *rfgn; + +	/* Search for name */ +	if (rfg_name) { +		rfg = bgp_rfapi_cfg_match_byname(bgp, rfg_name, type); +		if (!rfg) { +			if (vty) +				vty_out(vty, "No NVE group named \"%s\"\n", +					rfg_name); +			return CMD_WARNING_CONFIG_FAILED; +		} +	} + +	/* +	 * If this group is the redist nve group, unlink it +	 */ +	if (rfg_name == NULL || bgp->rfapi_cfg->rfg_redist == rfg) { +		vnc_redistribute_prechange(bgp); +		bgp->rfapi_cfg->rfg_redist = NULL; +		vnc_redistribute_postchange(bgp); +	} + + +	/* +	 * remove reference from bgp direct export list +	 */ +	for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node, +				  rfgn)) { +		if (rfg_name == NULL || (type == RFAPI_GROUP_CFG_NVE +					 && !strcmp(rfgn->name, rfg_name))) { +			rfgn->rfg = NULL; +			/* remove exported routes from this group */ +			vnc_direct_bgp_del_group(bgp, rfg); +			break; +		} +	} + +	/* +	 * remove reference from zebra export list +	 */ +	for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, node, +				  rfgn)) { + +		if (rfg_name == NULL || (type == RFAPI_GROUP_CFG_NVE +					 && !strcmp(rfgn->name, rfg_name))) { +			rfgn->rfg = NULL; +			/* remove exported routes from this group */ +			vnc_zebra_del_group(bgp, rfg); +			break; +		} +	} +	if (rfg) +		bgp_rfapi_delete_nve_group(vty, bgp, rfg); +	else /* must be delete all */ +		for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->nve_groups_sequential, +				       node, nnode, rfg)) +			bgp_rfapi_delete_nve_group(vty, bgp, rfg); +	return CMD_SUCCESS;  }  DEFUN (vnc_no_nve_group, @@ -2708,9 +2485,10 @@ DEFUN (vnc_no_nve_group,         "Configure a NVE group\n"         "Group name\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); +	VTY_DECLVAR_CONTEXT(bgp, bgp); -  return bgp_rfapi_delete_named_nve_group (vty, bgp, argv[3]->arg, RFAPI_GROUP_CFG_NVE); +	return bgp_rfapi_delete_named_nve_group(vty, bgp, argv[3]->arg, +						RFAPI_GROUP_CFG_NVE);  }  DEFUN (vnc_nve_group_prefix, @@ -2722,116 +2500,101 @@ DEFUN (vnc_nve_group_prefix,         "IPv4 prefix\n"         "IPv6 prefix\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); -  struct prefix p; -  int afi; -  struct route_table *rt; -  struct route_node *rn; -  int is_un_prefix = 0; - -  /* make sure it's still in list */ -  if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) -    { -      /* Not in list anymore */ -      vty_out (vty, "Current NVE group no longer exists\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (!str2prefix (argv[2]->arg, &p)) -    { -      vty_out (vty, "Malformed prefix \"%s\"\n", argv[2]->arg); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  afi = family2afi (p.family); -  if (!afi) -    { -      vty_out (vty, "Unsupported address family\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (argv[1]->arg[0] == 'u') -    { -      rt = &(bgp->rfapi_cfg->nve_groups_un[afi]); -      is_un_prefix = 1; -    } -  else -    { -      rt = &(bgp->rfapi_cfg->nve_groups_vn[afi]); -    } - -  rn = route_node_get (rt, &p); /* NB locks node */ -  if (rn->info) -    { -      /* -       * There is already a group with this prefix -       */ -      route_unlock_node (rn); -      if (rn->info != rfg) -        { -          /* -           * different group name: fail -           */ -          vty_out (vty, "nve group \"%s\" already has \"%s\" prefix %s\n", -                   ((struct rfapi_nve_group_cfg *) (rn->info))->name, -                   argv[1]->arg, argv[2]->arg); -          return CMD_WARNING_CONFIG_FAILED; -        } -      else -        { -          /* -           * same group name: it's already in the correct place -           * in the table, so we're done. -           * -           * Implies rfg->(vn|un)_prefix is already correct. -           */ -          return CMD_SUCCESS; -        } -    } - -  if (bgp->rfapi_cfg->rfg_redist == rfg) -    { -      vnc_redistribute_prechange (bgp); -    } - -  /* New prefix, new node */ - -  if (is_un_prefix) -    { - -      /* detach rfg from previous route table location */ -      if (rfg->un_node) -        { -          rfg->un_node->info = NULL; -          route_unlock_node (rfg->un_node);     /* frees */ -        } -      rfg->un_node = rn;        /* back ref */ -      rfg->un_prefix = p; - -    } -  else -    { - -      /* detach rfg from previous route table location */ -      if (rfg->vn_node) -        { -          rfg->vn_node->info = NULL; -          route_unlock_node (rfg->vn_node);     /* frees */ -        } -      rfg->vn_node = rn;        /* back ref */ -      rfg->vn_prefix = p; -    } - -  /* attach */ -  rn->info = rfg; - -  if (bgp->rfapi_cfg->rfg_redist == rfg) -    { -      vnc_redistribute_postchange (bgp); -    } - -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); +	struct prefix p; +	int afi; +	struct route_table *rt; +	struct route_node *rn; +	int is_un_prefix = 0; + +	/* make sure it's still in list */ +	if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { +		/* Not in list anymore */ +		vty_out(vty, "Current NVE group no longer exists\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (!str2prefix(argv[2]->arg, &p)) { +		vty_out(vty, "Malformed prefix \"%s\"\n", argv[2]->arg); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	afi = family2afi(p.family); +	if (!afi) { +		vty_out(vty, "Unsupported address family\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (argv[1]->arg[0] == 'u') { +		rt = &(bgp->rfapi_cfg->nve_groups_un[afi]); +		is_un_prefix = 1; +	} else { +		rt = &(bgp->rfapi_cfg->nve_groups_vn[afi]); +	} + +	rn = route_node_get(rt, &p); /* NB locks node */ +	if (rn->info) { +		/* +		 * There is already a group with this prefix +		 */ +		route_unlock_node(rn); +		if (rn->info != rfg) { +			/* +			 * different group name: fail +			 */ +			vty_out(vty, +				"nve group \"%s\" already has \"%s\" prefix %s\n", +				((struct rfapi_nve_group_cfg *)(rn->info)) +					->name, +				argv[1]->arg, argv[2]->arg); +			return CMD_WARNING_CONFIG_FAILED; +		} else { +			/* +			 * same group name: it's already in the correct place +			 * in the table, so we're done. +			 * +			 * Implies rfg->(vn|un)_prefix is already correct. +			 */ +			return CMD_SUCCESS; +		} +	} + +	if (bgp->rfapi_cfg->rfg_redist == rfg) { +		vnc_redistribute_prechange(bgp); +	} + +	/* New prefix, new node */ + +	if (is_un_prefix) { + +		/* detach rfg from previous route table location */ +		if (rfg->un_node) { +			rfg->un_node->info = NULL; +			route_unlock_node(rfg->un_node); /* frees */ +		} +		rfg->un_node = rn; /* back ref */ +		rfg->un_prefix = p; + +	} else { + +		/* detach rfg from previous route table location */ +		if (rfg->vn_node) { +			rfg->vn_node->info = NULL; +			route_unlock_node(rfg->vn_node); /* frees */ +		} +		rfg->vn_node = rn; /* back ref */ +		rfg->vn_prefix = p; +	} + +	/* attach */ +	rn->info = rfg; + +	if (bgp->rfapi_cfg->rfg_redist == rfg) { +		vnc_redistribute_postchange(bgp); +	} + +	return CMD_SUCCESS;  }  DEFUN (vnc_nve_group_rt_import, @@ -2841,67 +2604,64 @@ DEFUN (vnc_nve_group_rt_import,         "Import filter\n"         "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); -  int rc; -  struct listnode *node; -  struct rfapi_rfg_name *rfgn; -  int is_export_bgp = 0; -  int is_export_zebra = 0; - -  /* make sure it's still in list */ -  if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) -    { -      /* Not in list anymore */ -      vty_out (vty, "Current NVE group no longer exists\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  rc = set_ecom_list (vty, argc - 2, argv + 2, &rfg->rt_import_list); -  if (rc != CMD_SUCCESS) -    return rc; - -  for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_direct_bgp_l, -                             node, rfgn)) -    { - -      if (rfgn->rfg == rfg) -        { -          is_export_bgp = 1; -          break; -        } -    } - -  if (is_export_bgp) -    vnc_direct_bgp_del_group (bgp, rfg); - -  for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_zebra_l, node, rfgn)) -    { - -      if (rfgn->rfg == rfg) -        { -          is_export_zebra = 1; -          break; -        } -    } - -  if (is_export_zebra) -    vnc_zebra_del_group (bgp, rfg); - -  /* -   * stop referencing old import table, now reference new one -   */ -  if (rfg->rfapi_import_table) -    rfapiImportTableRefDelByIt (bgp, rfg->rfapi_import_table); -  rfg->rfapi_import_table = rfapiImportTableRefAdd (bgp, rfg->rt_import_list, rfg); - -  if (is_export_bgp) -    vnc_direct_bgp_add_group (bgp, rfg); - -  if (is_export_zebra) -    vnc_zebra_add_group (bgp, rfg); - -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); +	int rc; +	struct listnode *node; +	struct rfapi_rfg_name *rfgn; +	int is_export_bgp = 0; +	int is_export_zebra = 0; + +	/* make sure it's still in list */ +	if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { +		/* Not in list anymore */ +		vty_out(vty, "Current NVE group no longer exists\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_import_list); +	if (rc != CMD_SUCCESS) +		return rc; + +	for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node, +				  rfgn)) { + +		if (rfgn->rfg == rfg) { +			is_export_bgp = 1; +			break; +		} +	} + +	if (is_export_bgp) +		vnc_direct_bgp_del_group(bgp, rfg); + +	for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, node, +				  rfgn)) { + +		if (rfgn->rfg == rfg) { +			is_export_zebra = 1; +			break; +		} +	} + +	if (is_export_zebra) +		vnc_zebra_del_group(bgp, rfg); + +	/* +	 * stop referencing old import table, now reference new one +	 */ +	if (rfg->rfapi_import_table) +		rfapiImportTableRefDelByIt(bgp, rfg->rfapi_import_table); +	rfg->rfapi_import_table = +		rfapiImportTableRefAdd(bgp, rfg->rt_import_list, rfg); + +	if (is_export_bgp) +		vnc_direct_bgp_add_group(bgp, rfg); + +	if (is_export_zebra) +		vnc_zebra_add_group(bgp, rfg); + +	return CMD_SUCCESS;  }  DEFUN (vnc_nve_group_rt_export, @@ -2911,31 +2671,28 @@ DEFUN (vnc_nve_group_rt_export,         "Export filter\n"         "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); -  int rc; - -  /* make sure it's still in list */ -  if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) -    { -      /* Not in list anymore */ -      vty_out (vty, "Current NVE group no longer exists\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (bgp->rfapi_cfg->rfg_redist == rfg) -    { -      vnc_redistribute_prechange (bgp); -    } - -  rc = set_ecom_list (vty, argc - 2, argv + 2, &rfg->rt_export_list); - -  if (bgp->rfapi_cfg->rfg_redist == rfg) -    { -      vnc_redistribute_postchange (bgp); -    } - -  return rc; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); +	int rc; + +	/* make sure it's still in list */ +	if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { +		/* Not in list anymore */ +		vty_out(vty, "Current NVE group no longer exists\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (bgp->rfapi_cfg->rfg_redist == rfg) { +		vnc_redistribute_prechange(bgp); +	} + +	rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_export_list); + +	if (bgp->rfapi_cfg->rfg_redist == rfg) { +		vnc_redistribute_postchange(bgp); +	} + +	return rc;  }  DEFUN (vnc_nve_group_rt_both, @@ -2945,83 +2702,76 @@ DEFUN (vnc_nve_group_rt_both,         "Export+import filters\n"         "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); -  int rc; -  int is_export_bgp = 0; -  int is_export_zebra = 0; -  struct listnode *node; -  struct rfapi_rfg_name *rfgn; - -  /* make sure it's still in list */ -  if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) -    { -      /* Not in list anymore */ -      vty_out (vty, "Current NVE group no longer exists\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  rc = set_ecom_list (vty, argc - 2, argv + 2, &rfg->rt_import_list); -  if (rc != CMD_SUCCESS) -    return rc; - -  for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_direct_bgp_l, -                             node, rfgn)) -    { - -      if (rfgn->rfg == rfg) -        { -          is_export_bgp = 1; -          break; -        } -    } - -  if (is_export_bgp) -    vnc_direct_bgp_del_group (bgp, rfg); - -  for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_zebra_l, node, rfgn)) -    { - -      if (rfgn->rfg == rfg) -        { -          is_export_zebra = 1; -          break; -        } -    } - -  if (is_export_zebra) -    { -      vnc_zlog_debug_verbose ("%s: is_export_zebra", __func__); -      vnc_zebra_del_group (bgp, rfg); -    } - -  /* -   * stop referencing old import table, now reference new one -   */ -  if (rfg->rfapi_import_table) -    rfapiImportTableRefDelByIt (bgp, rfg->rfapi_import_table); -  rfg->rfapi_import_table = rfapiImportTableRefAdd (bgp, rfg->rt_import_list, rfg); - -  if (is_export_bgp) -    vnc_direct_bgp_add_group (bgp, rfg); - -  if (is_export_zebra) -    vnc_zebra_add_group (bgp, rfg); - -  if (bgp->rfapi_cfg->rfg_redist == rfg) -    { -      vnc_redistribute_prechange (bgp); -    } - -  rc = set_ecom_list (vty, argc - 2, argv + 2, &rfg->rt_export_list); - -  if (bgp->rfapi_cfg->rfg_redist == rfg) -    { -      vnc_redistribute_postchange (bgp); -    } - -  return rc; - +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); +	int rc; +	int is_export_bgp = 0; +	int is_export_zebra = 0; +	struct listnode *node; +	struct rfapi_rfg_name *rfgn; + +	/* make sure it's still in list */ +	if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { +		/* Not in list anymore */ +		vty_out(vty, "Current NVE group no longer exists\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_import_list); +	if (rc != CMD_SUCCESS) +		return rc; + +	for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node, +				  rfgn)) { + +		if (rfgn->rfg == rfg) { +			is_export_bgp = 1; +			break; +		} +	} + +	if (is_export_bgp) +		vnc_direct_bgp_del_group(bgp, rfg); + +	for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, node, +				  rfgn)) { + +		if (rfgn->rfg == rfg) { +			is_export_zebra = 1; +			break; +		} +	} + +	if (is_export_zebra) { +		vnc_zlog_debug_verbose("%s: is_export_zebra", __func__); +		vnc_zebra_del_group(bgp, rfg); +	} + +	/* +	 * stop referencing old import table, now reference new one +	 */ +	if (rfg->rfapi_import_table) +		rfapiImportTableRefDelByIt(bgp, rfg->rfapi_import_table); +	rfg->rfapi_import_table = +		rfapiImportTableRefAdd(bgp, rfg->rt_import_list, rfg); + +	if (is_export_bgp) +		vnc_direct_bgp_add_group(bgp, rfg); + +	if (is_export_zebra) +		vnc_zebra_add_group(bgp, rfg); + +	if (bgp->rfapi_cfg->rfg_redist == rfg) { +		vnc_redistribute_prechange(bgp); +	} + +	rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_export_list); + +	if (bgp->rfapi_cfg->rfg_redist == rfg) { +		vnc_redistribute_postchange(bgp); +	} + +	return rc;  }  DEFUN (vnc_nve_group_l2rd, @@ -3031,45 +2781,40 @@ DEFUN (vnc_nve_group_l2rd,         "Fixed value 1-255\n"         "use the low-order octet of the NVE's VN address\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); - -  /* make sure it's still in list */ -  if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) -    { -      /* Not in list anymore */ -      vty_out (vty, "Current NVE group no longer exists\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (strmatch(argv[1]->text, "auto:vn")) -    { -      rfg->l2rd = 0; -    } -  else -    { -      char *end = NULL; -      unsigned long value_l = strtoul (argv[1]->arg, &end, 10); -      uint8_t value = value_l & 0xff; - -      if (!argv[1]->arg[0] || *end) -        { -          vty_out (vty, "%% Malformed l2 nve ID \"%s\"\n",argv[1]->arg); -          return CMD_WARNING_CONFIG_FAILED; -        } -      if ((value_l < 1) || (value_l > 0xff)) -        { -          vty_out (vty, -                   "%% Malformed l2 nve id (must be greater than 0 and less than %u\n", -                   0x100); -          return CMD_WARNING_CONFIG_FAILED; -        } - -      rfg->l2rd = value; -    } -  rfg->flags |= RFAPI_RFG_L2RD; - -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); + +	/* make sure it's still in list */ +	if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { +		/* Not in list anymore */ +		vty_out(vty, "Current NVE group no longer exists\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (strmatch(argv[1]->text, "auto:vn")) { +		rfg->l2rd = 0; +	} else { +		char *end = NULL; +		unsigned long value_l = strtoul(argv[1]->arg, &end, 10); +		uint8_t value = value_l & 0xff; + +		if (!argv[1]->arg[0] || *end) { +			vty_out(vty, "%% Malformed l2 nve ID \"%s\"\n", +				argv[1]->arg); +			return CMD_WARNING_CONFIG_FAILED; +		} +		if ((value_l < 1) || (value_l > 0xff)) { +			vty_out(vty, +				"%% Malformed l2 nve id (must be greater than 0 and less than %u\n", +				0x100); +			return CMD_WARNING_CONFIG_FAILED; +		} + +		rfg->l2rd = value; +	} +	rfg->flags |= RFAPI_RFG_L2RD; + +	return CMD_SUCCESS;  }  DEFUN (vnc_nve_group_no_l2rd, @@ -3078,21 +2823,20 @@ DEFUN (vnc_nve_group_no_l2rd,         NO_STR         "Specify default Local Nve ID value to use in RD for L2 routes\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); -  /* make sure it's still in list */ -  if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) -    { -      /* Not in list anymore */ -      vty_out (vty, "Current NVE group no longer exists\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } +	/* make sure it's still in list */ +	if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { +		/* Not in list anymore */ +		vty_out(vty, "Current NVE group no longer exists\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} -  rfg->l2rd = 0; -  rfg->flags &= ~RFAPI_RFG_L2RD; +	rfg->l2rd = 0; +	rfg->flags &= ~RFAPI_RFG_L2RD; -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (vnc_nve_group_rd, @@ -3101,73 +2845,64 @@ DEFUN (vnc_nve_group_rd,         "Specify route distinguisher\n"         "Route Distinguisher (<as-number>:<number> | <ip-address>:<number> | auto:vn:<number> )\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  int ret; -  struct prefix_rd prd; -  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); - -  /* make sure it's still in list */ -  if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) -    { -      /* Not in list anymore */ -      vty_out (vty, "Current NVE group no longer exists\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (!strncmp (argv[1]->arg, "auto:vn:", 8)) -    { -      /* -       * use AF_UNIX to designate automatically-assigned RD -       * auto:vn:nn where nn is a 2-octet quantity -       */ -      char *end = NULL; -      uint32_t value32 = strtoul (argv[1]->arg + 8, &end, 10); -      uint16_t value = value32 & 0xffff; - -      if (!argv[1]->arg[8] || *end) -        { -          vty_out (vty, "%% Malformed rd\n"); -          return CMD_WARNING_CONFIG_FAILED; -        } -      if (value32 > 0xffff) -        { -          vty_out (vty, "%% Malformed rd (must be less than %u\n", -                   0x0ffff); -          return CMD_WARNING_CONFIG_FAILED; -        } - -      memset (&prd, 0, sizeof (prd)); -      prd.family = AF_UNIX; -      prd.prefixlen = 64; -      prd.val[0] = (RD_TYPE_IP >> 8) & 0x0ff; -      prd.val[1] = RD_TYPE_IP & 0x0ff; -      prd.val[6] = (value >> 8) & 0x0ff; -      prd.val[7] = value & 0x0ff; - -    } -  else -    { - -      ret = str2prefix_rd (argv[1]->arg, &prd); -      if (!ret) -        { -          vty_out (vty, "%% Malformed rd\n"); -          return CMD_WARNING_CONFIG_FAILED; -        } -    } - -  if (bgp->rfapi_cfg->rfg_redist == rfg) -    { -      vnc_redistribute_prechange (bgp); -    } - -  rfg->rd = prd; - -  if (bgp->rfapi_cfg->rfg_redist == rfg) -    { -      vnc_redistribute_postchange (bgp); -    } -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	int ret; +	struct prefix_rd prd; +	VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); + +	/* make sure it's still in list */ +	if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { +		/* Not in list anymore */ +		vty_out(vty, "Current NVE group no longer exists\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (!strncmp(argv[1]->arg, "auto:vn:", 8)) { +		/* +		 * use AF_UNIX to designate automatically-assigned RD +		 * auto:vn:nn where nn is a 2-octet quantity +		 */ +		char *end = NULL; +		uint32_t value32 = strtoul(argv[1]->arg + 8, &end, 10); +		uint16_t value = value32 & 0xffff; + +		if (!argv[1]->arg[8] || *end) { +			vty_out(vty, "%% Malformed rd\n"); +			return CMD_WARNING_CONFIG_FAILED; +		} +		if (value32 > 0xffff) { +			vty_out(vty, "%% Malformed rd (must be less than %u\n", +				0x0ffff); +			return CMD_WARNING_CONFIG_FAILED; +		} + +		memset(&prd, 0, sizeof(prd)); +		prd.family = AF_UNIX; +		prd.prefixlen = 64; +		prd.val[0] = (RD_TYPE_IP >> 8) & 0x0ff; +		prd.val[1] = RD_TYPE_IP & 0x0ff; +		prd.val[6] = (value >> 8) & 0x0ff; +		prd.val[7] = value & 0x0ff; + +	} else { + +		ret = str2prefix_rd(argv[1]->arg, &prd); +		if (!ret) { +			vty_out(vty, "%% Malformed rd\n"); +			return CMD_WARNING_CONFIG_FAILED; +		} +	} + +	if (bgp->rfapi_cfg->rfg_redist == rfg) { +		vnc_redistribute_prechange(bgp); +	} + +	rfg->rd = prd; + +	if (bgp->rfapi_cfg->rfg_redist == rfg) { +		vnc_redistribute_postchange(bgp); +	} +	return CMD_SUCCESS;  }  DEFUN (vnc_nve_group_responselifetime, @@ -3176,40 +2911,36 @@ DEFUN (vnc_nve_group_responselifetime,         "Specify response lifetime\n"         "Response lifetime in seconds\n" "Infinite response lifetime\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  unsigned int rspint; -  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); -  struct rfapi_descriptor *rfd; -  struct listnode *hdnode; - -  /* make sure it's still in list */ -  if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) -    { -      /* Not in list anymore */ -      vty_out (vty, "Current NVE group no longer exists\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (strmatch(argv[1]->text, "infinite")) -    { -      rspint = RFAPI_INFINITE_LIFETIME; -    } -  else -    { -      rspint = strtoul(argv[1]->arg, NULL, 10); -    } - -  rfg->response_lifetime = rspint; -  rfg->flags |= RFAPI_RFG_RESPONSE_LIFETIME; -  if (rfg->nves) -    for (ALL_LIST_ELEMENTS_RO (rfg->nves, hdnode, rfd)) -      rfd->response_lifetime = rspint; -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	unsigned int rspint; +	VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); +	struct rfapi_descriptor *rfd; +	struct listnode *hdnode; + +	/* make sure it's still in list */ +	if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { +		/* Not in list anymore */ +		vty_out(vty, "Current NVE group no longer exists\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (strmatch(argv[1]->text, "infinite")) { +		rspint = RFAPI_INFINITE_LIFETIME; +	} else { +		rspint = strtoul(argv[1]->arg, NULL, 10); +	} + +	rfg->response_lifetime = rspint; +	rfg->flags |= RFAPI_RFG_RESPONSE_LIFETIME; +	if (rfg->nves) +		for (ALL_LIST_ELEMENTS_RO(rfg->nves, hdnode, rfd)) +			rfd->response_lifetime = rspint; +	return CMD_SUCCESS;  }  /*   * Sigh. This command, like exit-address-family, is a hack to deal - * with the lack of rigorous level control in the command handler.  + * with the lack of rigorous level control in the command handler.   * TBD fix command handler.   */  DEFUN_NOSH (exit_vnc, @@ -3217,27 +2948,20 @@ DEFUN_NOSH (exit_vnc,         "exit-vnc",         "Exit VNC configuration mode\n")  { -  if (vty->node == BGP_VNC_DEFAULTS_NODE || -      vty->node == BGP_VNC_NVE_GROUP_NODE || -      vty->node == BGP_VNC_L2_GROUP_NODE) -    { - -      vty->node = BGP_NODE; -    } -  return CMD_SUCCESS; +	if (vty->node == BGP_VNC_DEFAULTS_NODE +	    || vty->node == BGP_VNC_NVE_GROUP_NODE +	    || vty->node == BGP_VNC_L2_GROUP_NODE) { + +		vty->node = BGP_NODE; +	} +	return CMD_SUCCESS;  }  static struct cmd_node bgp_vnc_defaults_node = { -  BGP_VNC_DEFAULTS_NODE, -  "%s(config-router-vnc-defaults)# ", -  1 -}; +	BGP_VNC_DEFAULTS_NODE, "%s(config-router-vnc-defaults)# ", 1};  static struct cmd_node bgp_vnc_nve_group_node = { -  BGP_VNC_NVE_GROUP_NODE, -  "%s(config-router-vnc-nve-group)# ", -  1 -}; +	BGP_VNC_NVE_GROUP_NODE, "%s(config-router-vnc-nve-group)# ", 1};  /*-------------------------------------------------------------------------   *			VNC nve-group @@ -3250,35 +2974,33 @@ DEFUN_NOSH (vnc_vrf_policy,         "Configure a VRF policy group\n"         "VRF name\n")  { -  struct rfapi_nve_group_cfg *rfg; -  VTY_DECLVAR_CONTEXT(bgp, bgp); - -  if (!bgp) -    { -      vty_out (vty, "No BGP process is configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  /* Search for name */ -  rfg = bgp_rfapi_cfg_match_byname (bgp, argv[1]->arg, RFAPI_GROUP_CFG_VRF); - -  if (!rfg) -    { -      rfg = rfapi_group_new (bgp, RFAPI_GROUP_CFG_VRF, argv[1]->arg); -      if (!rfg) -        { -          /* Error out of memory */ -          vty_out (vty, "Can't allocate memory for NVE group\n"); -          return CMD_WARNING_CONFIG_FAILED; -        } -    } -  /* -   * XXX subsequent calls will need to make sure this item is still -   * in the linked list and has the same name -   */ -  VTY_PUSH_CONTEXT_SUB (BGP_VRF_POLICY_NODE, rfg); - -  return CMD_SUCCESS; +	struct rfapi_nve_group_cfg *rfg; +	VTY_DECLVAR_CONTEXT(bgp, bgp); + +	if (!bgp) { +		vty_out(vty, "No BGP process is configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	/* Search for name */ +	rfg = bgp_rfapi_cfg_match_byname(bgp, argv[1]->arg, +					 RFAPI_GROUP_CFG_VRF); + +	if (!rfg) { +		rfg = rfapi_group_new(bgp, RFAPI_GROUP_CFG_VRF, argv[1]->arg); +		if (!rfg) { +			/* Error out of memory */ +			vty_out(vty, "Can't allocate memory for NVE group\n"); +			return CMD_WARNING_CONFIG_FAILED; +		} +	} +	/* +	 * XXX subsequent calls will need to make sure this item is still +	 * in the linked list and has the same name +	 */ +	VTY_PUSH_CONTEXT_SUB(BGP_VRF_POLICY_NODE, rfg); + +	return CMD_SUCCESS;  }  DEFUN (vnc_no_vrf_policy, @@ -3288,14 +3010,14 @@ DEFUN (vnc_no_vrf_policy,         "Remove a VRF policy group\n"         "VRF name\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); - -  if (!bgp) -    { -      vty_out (vty, "No BGP process is configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } -  return bgp_rfapi_delete_named_nve_group (vty, bgp, argv[2]->arg, RFAPI_GROUP_CFG_VRF); +	VTY_DECLVAR_CONTEXT(bgp, bgp); + +	if (!bgp) { +		vty_out(vty, "No BGP process is configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} +	return bgp_rfapi_delete_named_nve_group(vty, bgp, argv[2]->arg, +						RFAPI_GROUP_CFG_VRF);  }  DEFUN (vnc_vrf_policy_label, @@ -3304,39 +3026,35 @@ DEFUN (vnc_vrf_policy_label,         "Default label value for VRF\n"         "Label Value <0-1048575>\n")  { -  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); - -  uint32_t label; -  VTY_DECLVAR_CONTEXT(bgp, bgp); - -  if (!bgp) -    { -      vty_out (vty, "No BGP process is configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  /* make sure it's still in list */ -  if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) -    { -      /* Not in list anymore */ -      vty_out (vty, "Current NVE group no longer exists\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  label = strtoul(argv[1]->arg, NULL, 10); - -  if (bgp->rfapi_cfg->rfg_redist == rfg) -    { -      vnc_redistribute_prechange (bgp); -    } - -  rfg->label = label; - -  if (bgp->rfapi_cfg->rfg_redist == rfg) -    { -      vnc_redistribute_postchange (bgp); -    } -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); + +	uint32_t label; +	VTY_DECLVAR_CONTEXT(bgp, bgp); + +	if (!bgp) { +		vty_out(vty, "No BGP process is configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	/* make sure it's still in list */ +	if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { +		/* Not in list anymore */ +		vty_out(vty, "Current NVE group no longer exists\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	label = strtoul(argv[1]->arg, NULL, 10); + +	if (bgp->rfapi_cfg->rfg_redist == rfg) { +		vnc_redistribute_prechange(bgp); +	} + +	rfg->label = label; + +	if (bgp->rfapi_cfg->rfg_redist == rfg) { +		vnc_redistribute_postchange(bgp); +	} +	return CMD_SUCCESS;  }  DEFUN (vnc_vrf_policy_no_label, @@ -3345,29 +3063,26 @@ DEFUN (vnc_vrf_policy_no_label,         NO_STR         "Remove VRF default label\n")  { -  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); -  VTY_DECLVAR_CONTEXT(bgp, bgp); - -  /* make sure it's still in list */ -  if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) -    { -      /* Not in list anymore */ -      vty_out (vty, "Current VRF group no longer exists\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (bgp->rfapi_cfg->rfg_redist == rfg) -    { -      vnc_redistribute_prechange (bgp); -    } - -  rfg->label = MPLS_LABEL_ILLEGAL; - -  if (bgp->rfapi_cfg->rfg_redist == rfg) -    { -      vnc_redistribute_postchange (bgp); -    } -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); +	VTY_DECLVAR_CONTEXT(bgp, bgp); + +	/* make sure it's still in list */ +	if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { +		/* Not in list anymore */ +		vty_out(vty, "Current VRF group no longer exists\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (bgp->rfapi_cfg->rfg_redist == rfg) { +		vnc_redistribute_prechange(bgp); +	} + +	rfg->label = MPLS_LABEL_ILLEGAL; + +	if (bgp->rfapi_cfg->rfg_redist == rfg) { +		vnc_redistribute_postchange(bgp); +	} +	return CMD_SUCCESS;  }  DEFUN (vnc_vrf_policy_nexthop, @@ -3378,45 +3093,40 @@ DEFUN (vnc_vrf_policy_nexthop,         "IPv6 prefix\n"         "Use configured router-id (default)\n")  { -  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); -  struct prefix p; - -  VTY_DECLVAR_CONTEXT(bgp, bgp); - -  /* make sure it's still in list */ -  if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) -    { -      /* Not in list anymore */ -      vty_out (vty, "Current VRF no longer exists\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (bgp->rfapi_cfg->rfg_redist == rfg) -    { -      vnc_redistribute_prechange (bgp); -    } - -  if (!str2prefix (argv[1]->arg, &p) && p.family) -    { -      //vty_out (vty, "Nexthop set to self\n"); -      SET_FLAG (rfg->flags, RFAPI_RFG_VPN_NH_SELF); -      memset(&rfg->vn_prefix, 0, sizeof(struct prefix)); -    } -  else -    { -      UNSET_FLAG (rfg->flags, RFAPI_RFG_VPN_NH_SELF); -      rfg->vn_prefix = p; -      rfg->un_prefix = p; -    } - -  /* TBD handle router-id/ nexthop changes when have advertised prefixes */ - -  if (bgp->rfapi_cfg->rfg_redist == rfg) -    { -      vnc_redistribute_postchange (bgp); -    } - -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); +	struct prefix p; + +	VTY_DECLVAR_CONTEXT(bgp, bgp); + +	/* make sure it's still in list */ +	if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { +		/* Not in list anymore */ +		vty_out(vty, "Current VRF no longer exists\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (bgp->rfapi_cfg->rfg_redist == rfg) { +		vnc_redistribute_prechange(bgp); +	} + +	if (!str2prefix(argv[1]->arg, &p) && p.family) { +		// vty_out (vty, "Nexthop set to self\n"); +		SET_FLAG(rfg->flags, RFAPI_RFG_VPN_NH_SELF); +		memset(&rfg->vn_prefix, 0, sizeof(struct prefix)); +	} else { +		UNSET_FLAG(rfg->flags, RFAPI_RFG_VPN_NH_SELF); +		rfg->vn_prefix = p; +		rfg->un_prefix = p; +	} + +	/* TBD handle router-id/ nexthop changes when have advertised prefixes +	 */ + +	if (bgp->rfapi_cfg->rfg_redist == rfg) { +		vnc_redistribute_postchange(bgp); +	} + +	return CMD_SUCCESS;  }  /* The RT code should be refactored/simplified with above... */ @@ -3427,73 +3137,69 @@ DEFUN (vnc_vrf_policy_rt_import,         "Import filter\n"         "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")  { -  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  int rc; -  struct listnode *node; -  struct rfapi_rfg_name *rfgn; -  int is_export_bgp = 0; -  int is_export_zebra = 0; - -  if (!bgp) -    { -      vty_out (vty, "No BGP process is configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  /* make sure it's still in list */ -  if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) -    { -      /* Not in list anymore */ -      vty_out (vty, "Current NVE group no longer exists\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  rc = set_ecom_list (vty, argc-2, argv+2, &rfg->rt_import_list); -  if (rc != CMD_SUCCESS) -    return rc; - -  for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_direct_bgp_l, -                             node, rfgn)) -    { - -      if (rfgn->rfg == rfg) -        { -          is_export_bgp = 1; -          break; -        } -    } - -  if (is_export_bgp) -    vnc_direct_bgp_del_group (bgp, rfg); - -  for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_zebra_l, node, rfgn)) -    { - -      if (rfgn->rfg == rfg) -        { -          is_export_zebra = 1; -          break; -        } -    } - -  if (is_export_zebra) -    vnc_zebra_del_group (bgp, rfg); - -  /* -   * stop referencing old import table, now reference new one -   */ -  if (rfg->rfapi_import_table) -    rfapiImportTableRefDelByIt (bgp, rfg->rfapi_import_table); -  rfg->rfapi_import_table = rfapiImportTableRefAdd (bgp, rfg->rt_import_list, rfg); - -  if (is_export_bgp) -    vnc_direct_bgp_add_group (bgp, rfg); - -  if (is_export_zebra) -    vnc_zebra_add_group (bgp, rfg); - -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	int rc; +	struct listnode *node; +	struct rfapi_rfg_name *rfgn; +	int is_export_bgp = 0; +	int is_export_zebra = 0; + +	if (!bgp) { +		vty_out(vty, "No BGP process is configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	/* make sure it's still in list */ +	if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { +		/* Not in list anymore */ +		vty_out(vty, "Current NVE group no longer exists\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_import_list); +	if (rc != CMD_SUCCESS) +		return rc; + +	for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node, +				  rfgn)) { + +		if (rfgn->rfg == rfg) { +			is_export_bgp = 1; +			break; +		} +	} + +	if (is_export_bgp) +		vnc_direct_bgp_del_group(bgp, rfg); + +	for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, node, +				  rfgn)) { + +		if (rfgn->rfg == rfg) { +			is_export_zebra = 1; +			break; +		} +	} + +	if (is_export_zebra) +		vnc_zebra_del_group(bgp, rfg); + +	/* +	 * stop referencing old import table, now reference new one +	 */ +	if (rfg->rfapi_import_table) +		rfapiImportTableRefDelByIt(bgp, rfg->rfapi_import_table); +	rfg->rfapi_import_table = +		rfapiImportTableRefAdd(bgp, rfg->rt_import_list, rfg); + +	if (is_export_bgp) +		vnc_direct_bgp_add_group(bgp, rfg); + +	if (is_export_zebra) +		vnc_zebra_add_group(bgp, rfg); + +	return CMD_SUCCESS;  }  DEFUN (vnc_vrf_policy_rt_export, @@ -3503,37 +3209,33 @@ DEFUN (vnc_vrf_policy_rt_export,         "Export filter\n"         "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")  { -  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  int rc; - -  if (!bgp) -    { -      vty_out (vty, "No BGP process is configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  /* make sure it's still in list */ -  if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) -    { -      /* Not in list anymore */ -      vty_out (vty, "Current NVE group no longer exists\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (bgp->rfapi_cfg->rfg_redist == rfg) -    { -      vnc_redistribute_prechange (bgp); -    } - -  rc = set_ecom_list (vty, argc-2, argv+2, &rfg->rt_export_list); - -  if (bgp->rfapi_cfg->rfg_redist == rfg) -    { -      vnc_redistribute_postchange (bgp); -    } - -  return rc; +	VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	int rc; + +	if (!bgp) { +		vty_out(vty, "No BGP process is configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	/* make sure it's still in list */ +	if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { +		/* Not in list anymore */ +		vty_out(vty, "Current NVE group no longer exists\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (bgp->rfapi_cfg->rfg_redist == rfg) { +		vnc_redistribute_prechange(bgp); +	} + +	rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_export_list); + +	if (bgp->rfapi_cfg->rfg_redist == rfg) { +		vnc_redistribute_postchange(bgp); +	} + +	return rc;  }  DEFUN (vnc_vrf_policy_rt_both, @@ -3543,89 +3245,81 @@ DEFUN (vnc_vrf_policy_rt_both,         "Export+import filters\n"         "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")  { -  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  int rc; -  int is_export_bgp = 0; -  int is_export_zebra = 0; -  struct listnode *node; -  struct rfapi_rfg_name *rfgn; - -  if (!bgp) -    { -      vty_out (vty, "No BGP process is configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  /* make sure it's still in list */ -  if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) -    { -      /* Not in list anymore */ -      vty_out (vty, "Current NVE group no longer exists\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  rc = set_ecom_list (vty, argc-2, argv+2, &rfg->rt_import_list); -  if (rc != CMD_SUCCESS) -    return rc; - -  for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_direct_bgp_l, -                             node, rfgn)) -    { - -      if (rfgn->rfg == rfg) -        { -          is_export_bgp = 1; -          break; -        } -    } - -  if (is_export_bgp) -    vnc_direct_bgp_del_group (bgp, rfg); - -  for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_zebra_l, node, rfgn)) -    { - -      if (rfgn->rfg == rfg) -        { -          is_export_zebra = 1; -          break; -        } -    } - -  if (is_export_zebra) -    { -      vnc_zlog_debug_verbose ("%s: is_export_zebra", __func__); -      vnc_zebra_del_group (bgp, rfg); -    } - -  /* -   * stop referencing old import table, now reference new one -   */ -  if (rfg->rfapi_import_table) -    rfapiImportTableRefDelByIt (bgp, rfg->rfapi_import_table); -  rfg->rfapi_import_table = rfapiImportTableRefAdd (bgp, rfg->rt_import_list, rfg); - -  if (is_export_bgp) -    vnc_direct_bgp_add_group (bgp, rfg); - -  if (is_export_zebra) -    vnc_zebra_add_group (bgp, rfg); - -  if (bgp->rfapi_cfg->rfg_redist == rfg) -    { -      vnc_redistribute_prechange (bgp); -    } - -  rc = set_ecom_list (vty, argc-2, argv+2, &rfg->rt_export_list); - -  if (bgp->rfapi_cfg->rfg_redist == rfg) -    { -      vnc_redistribute_postchange (bgp); -    } - -  return rc; - +	VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	int rc; +	int is_export_bgp = 0; +	int is_export_zebra = 0; +	struct listnode *node; +	struct rfapi_rfg_name *rfgn; + +	if (!bgp) { +		vty_out(vty, "No BGP process is configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	/* make sure it's still in list */ +	if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { +		/* Not in list anymore */ +		vty_out(vty, "Current NVE group no longer exists\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_import_list); +	if (rc != CMD_SUCCESS) +		return rc; + +	for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node, +				  rfgn)) { + +		if (rfgn->rfg == rfg) { +			is_export_bgp = 1; +			break; +		} +	} + +	if (is_export_bgp) +		vnc_direct_bgp_del_group(bgp, rfg); + +	for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, node, +				  rfgn)) { + +		if (rfgn->rfg == rfg) { +			is_export_zebra = 1; +			break; +		} +	} + +	if (is_export_zebra) { +		vnc_zlog_debug_verbose("%s: is_export_zebra", __func__); +		vnc_zebra_del_group(bgp, rfg); +	} + +	/* +	 * stop referencing old import table, now reference new one +	 */ +	if (rfg->rfapi_import_table) +		rfapiImportTableRefDelByIt(bgp, rfg->rfapi_import_table); +	rfg->rfapi_import_table = +		rfapiImportTableRefAdd(bgp, rfg->rt_import_list, rfg); + +	if (is_export_bgp) +		vnc_direct_bgp_add_group(bgp, rfg); + +	if (is_export_zebra) +		vnc_zebra_add_group(bgp, rfg); + +	if (bgp->rfapi_cfg->rfg_redist == rfg) { +		vnc_redistribute_prechange(bgp); +	} + +	rc = set_ecom_list(vty, argc - 2, argv + 2, &rfg->rt_export_list); + +	if (bgp->rfapi_cfg->rfg_redist == rfg) { +		vnc_redistribute_postchange(bgp); +	} + +	return rc;  }  DEFUN (vnc_vrf_policy_rd, @@ -3634,79 +3328,69 @@ DEFUN (vnc_vrf_policy_rd,         "Specify default VRF route distinguisher\n"         "Route Distinguisher (<as-number>:<number> | <ip-address>:<number> | auto:nh:<number> )\n")  { -  int ret; -  struct prefix_rd prd; -  VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); -  VTY_DECLVAR_CONTEXT(bgp, bgp); - -  if (!bgp) -    { -      vty_out (vty, "No BGP process is configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  /* make sure it's still in list */ -  if (!listnode_lookup (bgp->rfapi_cfg->nve_groups_sequential, rfg)) -    { -      /* Not in list anymore */ -      vty_out (vty, "Current NVE group no longer exists\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (!strncmp (argv[1]->arg, "auto:nh:", 8)) -    { -      /* -       * use AF_UNIX to designate automatically-assigned RD -       * auto:vn:nn where nn is a 2-octet quantity -       */ -      char *end = NULL; -      uint32_t value32 = strtoul (argv[1]->arg + 8, &end, 10); -      uint16_t value = value32 & 0xffff; - -      if (!*(argv[1]->arg + 5) || *end) -        { -          vty_out (vty, "%% Malformed rd\n"); -          return CMD_WARNING_CONFIG_FAILED; -        } -      if (value32 > 0xffff) -        { -          vty_out (vty, "%% Malformed rd (must be less than %u\n", -                   0x0ffff); -          return CMD_WARNING_CONFIG_FAILED; -        } - -      memset (&prd, 0, sizeof (prd)); -      prd.family = AF_UNIX; -      prd.prefixlen = 64; -      prd.val[0] = (RD_TYPE_IP >> 8) & 0x0ff; -      prd.val[1] = RD_TYPE_IP & 0x0ff; -      prd.val[6] = (value >> 8) & 0x0ff; -      prd.val[7] = value & 0x0ff; - -    } -  else -    { - -      ret = str2prefix_rd (argv[1]->arg, &prd); -      if (!ret) -        { -          vty_out (vty, "%% Malformed rd\n"); -          return CMD_WARNING_CONFIG_FAILED; -        } -    } - -  if (bgp->rfapi_cfg->rfg_redist == rfg) -    { -      vnc_redistribute_prechange (bgp); -    } - -  rfg->rd = prd; - -  if (bgp->rfapi_cfg->rfg_redist == rfg) -    { -      vnc_redistribute_postchange (bgp); -    } -  return CMD_SUCCESS; +	int ret; +	struct prefix_rd prd; +	VTY_DECLVAR_CONTEXT_SUB(rfapi_nve_group_cfg, rfg); +	VTY_DECLVAR_CONTEXT(bgp, bgp); + +	if (!bgp) { +		vty_out(vty, "No BGP process is configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	/* make sure it's still in list */ +	if (!listnode_lookup(bgp->rfapi_cfg->nve_groups_sequential, rfg)) { +		/* Not in list anymore */ +		vty_out(vty, "Current NVE group no longer exists\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (!strncmp(argv[1]->arg, "auto:nh:", 8)) { +		/* +		 * use AF_UNIX to designate automatically-assigned RD +		 * auto:vn:nn where nn is a 2-octet quantity +		 */ +		char *end = NULL; +		uint32_t value32 = strtoul(argv[1]->arg + 8, &end, 10); +		uint16_t value = value32 & 0xffff; + +		if (!*(argv[1]->arg + 5) || *end) { +			vty_out(vty, "%% Malformed rd\n"); +			return CMD_WARNING_CONFIG_FAILED; +		} +		if (value32 > 0xffff) { +			vty_out(vty, "%% Malformed rd (must be less than %u\n", +				0x0ffff); +			return CMD_WARNING_CONFIG_FAILED; +		} + +		memset(&prd, 0, sizeof(prd)); +		prd.family = AF_UNIX; +		prd.prefixlen = 64; +		prd.val[0] = (RD_TYPE_IP >> 8) & 0x0ff; +		prd.val[1] = RD_TYPE_IP & 0x0ff; +		prd.val[6] = (value >> 8) & 0x0ff; +		prd.val[7] = value & 0x0ff; + +	} else { + +		ret = str2prefix_rd(argv[1]->arg, &prd); +		if (!ret) { +			vty_out(vty, "%% Malformed rd\n"); +			return CMD_WARNING_CONFIG_FAILED; +		} +	} + +	if (bgp->rfapi_cfg->rfg_redist == rfg) { +		vnc_redistribute_prechange(bgp); +	} + +	rfg->rd = prd; + +	if (bgp->rfapi_cfg->rfg_redist == rfg) { +		vnc_redistribute_postchange(bgp); +	} +	return CMD_SUCCESS;  }  DEFUN_NOSH (exit_vrf_policy, @@ -3714,18 +3398,14 @@ DEFUN_NOSH (exit_vrf_policy,         "exit-vrf-policy",         "Exit VRF policy configuration mode\n")  { -  if (vty->node == BGP_VRF_POLICY_NODE) -    { -      vty->node = BGP_NODE; -    } -  return CMD_SUCCESS; +	if (vty->node == BGP_VRF_POLICY_NODE) { +		vty->node = BGP_NODE; +	} +	return CMD_SUCCESS;  }  static struct cmd_node bgp_vrf_policy_node = { -  BGP_VRF_POLICY_NODE, -  "%s(config-router-vrf-policy)# ", -  1 -}; +	BGP_VRF_POLICY_NODE, "%s(config-router-vrf-policy)# ", 1};  /*-------------------------------------------------------------------------   *			vnc-l2-group @@ -3737,88 +3417,82 @@ DEFUN_NOSH (vnc_l2_group,         "vnc l2-group NAME",         VNC_CONFIG_STR "Configure a L2 group\n" "Group name\n")  { -  struct rfapi_l2_group_cfg *rfg; -  VTY_DECLVAR_CONTEXT(bgp, bgp); - -  if (!bgp) -    { -      vty_out (vty, "No BGP process is configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  /* Search for name */ -  rfg = rfapi_l2_group_lookup_byname (bgp, argv[1]->arg); - -  if (!rfg) -    { -      rfg = rfapi_l2_group_new (); -      if (!rfg) -        { -          /* Error out of memory */ -          vty_out (vty, "Can't allocate memory for L2 group\n"); -          return CMD_WARNING_CONFIG_FAILED; -        } -      rfg->name = strdup (argv[1]->arg); -      /* add to tail of list */ -      listnode_add (bgp->rfapi_cfg->l2_groups, rfg); -    } - -  /* -   * XXX subsequent calls will need to make sure this item is still -   * in the linked list and has the same name -   */ -  VTY_PUSH_CONTEXT_SUB (BGP_VNC_L2_GROUP_NODE, rfg); -  return CMD_SUCCESS; +	struct rfapi_l2_group_cfg *rfg; +	VTY_DECLVAR_CONTEXT(bgp, bgp); + +	if (!bgp) { +		vty_out(vty, "No BGP process is configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	/* Search for name */ +	rfg = rfapi_l2_group_lookup_byname(bgp, argv[1]->arg); + +	if (!rfg) { +		rfg = rfapi_l2_group_new(); +		if (!rfg) { +			/* Error out of memory */ +			vty_out(vty, "Can't allocate memory for L2 group\n"); +			return CMD_WARNING_CONFIG_FAILED; +		} +		rfg->name = strdup(argv[1]->arg); +		/* add to tail of list */ +		listnode_add(bgp->rfapi_cfg->l2_groups, rfg); +	} + +	/* +	 * XXX subsequent calls will need to make sure this item is still +	 * in the linked list and has the same name +	 */ +	VTY_PUSH_CONTEXT_SUB(BGP_VNC_L2_GROUP_NODE, rfg); +	return CMD_SUCCESS;  } -static void -bgp_rfapi_delete_l2_group ( -  struct vty			*vty,     /* NULL = no output */ -  struct bgp			*bgp, -  struct rfapi_l2_group_cfg	*rfg) +static void bgp_rfapi_delete_l2_group(struct vty *vty, /* NULL = no output */ +				      struct bgp *bgp, +				      struct rfapi_l2_group_cfg *rfg)  { -  /* delete it */ -  free (rfg->name); -  if (rfg->rt_import_list) -    ecommunity_free (&rfg->rt_import_list); -  if (rfg->rt_export_list) -    ecommunity_free (&rfg->rt_export_list); -  if (rfg->labels) -    list_delete (rfg->labels); -  if (rfg->rfp_cfg) -    XFREE (MTYPE_RFAPI_RFP_GROUP_CFG, rfg->rfp_cfg); -  listnode_delete (bgp->rfapi_cfg->l2_groups, rfg); - -  rfapi_l2_group_del (rfg); +	/* delete it */ +	free(rfg->name); +	if (rfg->rt_import_list) +		ecommunity_free(&rfg->rt_import_list); +	if (rfg->rt_export_list) +		ecommunity_free(&rfg->rt_export_list); +	if (rfg->labels) +		list_delete(rfg->labels); +	if (rfg->rfp_cfg) +		XFREE(MTYPE_RFAPI_RFP_GROUP_CFG, rfg->rfp_cfg); +	listnode_delete(bgp->rfapi_cfg->l2_groups, rfg); + +	rfapi_l2_group_del(rfg);  }  static int -bgp_rfapi_delete_named_l2_group ( -  struct vty *vty,       /* NULL = no output */ -  struct bgp *bgp, -  const char *rfg_name) /* NULL = any */ +bgp_rfapi_delete_named_l2_group(struct vty *vty, /* NULL = no output */ +				struct bgp *bgp, +				const char *rfg_name) /* NULL = any */  { -  struct rfapi_l2_group_cfg *rfg = NULL; -  struct listnode *node, *nnode; - -  /* Search for name */ -  if (rfg_name) -    { -      rfg = rfapi_l2_group_lookup_byname (bgp, rfg_name); -      if (!rfg) -        { -          if (vty) -            vty_out (vty, "No L2 group named \"%s\"\n",rfg_name); -          return CMD_WARNING_CONFIG_FAILED; -        } -    } - -  if (rfg) -    bgp_rfapi_delete_l2_group (vty, bgp, rfg); -  else                          /* must be delete all */ -    for (ALL_LIST_ELEMENTS (bgp->rfapi_cfg->l2_groups, node, nnode, rfg)) -      bgp_rfapi_delete_l2_group (vty, bgp, rfg); -  return CMD_SUCCESS; +	struct rfapi_l2_group_cfg *rfg = NULL; +	struct listnode *node, *nnode; + +	/* Search for name */ +	if (rfg_name) { +		rfg = rfapi_l2_group_lookup_byname(bgp, rfg_name); +		if (!rfg) { +			if (vty) +				vty_out(vty, "No L2 group named \"%s\"\n", +					rfg_name); +			return CMD_WARNING_CONFIG_FAILED; +		} +	} + +	if (rfg) +		bgp_rfapi_delete_l2_group(vty, bgp, rfg); +	else /* must be delete all */ +		for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->l2_groups, node, nnode, +				       rfg)) +			bgp_rfapi_delete_l2_group(vty, bgp, rfg); +	return CMD_SUCCESS;  }  DEFUN (vnc_no_l2_group, @@ -3829,14 +3503,13 @@ DEFUN (vnc_no_l2_group,         "Configure a L2 group\n"         "Group name\n")  { -  VTY_DECLVAR_CONTEXT(bgp, bgp); - -  if (!bgp) -    { -      vty_out (vty, "No BGP process is configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } -  return bgp_rfapi_delete_named_l2_group (vty, bgp, argv[3]->arg); +	VTY_DECLVAR_CONTEXT(bgp, bgp); + +	if (!bgp) { +		vty_out(vty, "No BGP process is configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} +	return bgp_rfapi_delete_named_l2_group(vty, bgp, argv[3]->arg);  } @@ -3846,26 +3519,24 @@ DEFUN (vnc_l2_group_lni,         "Specify Logical Network ID associated with group\n"         "value\n")  { -  VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg, rfg); -  VTY_DECLVAR_CONTEXT(bgp, bgp); - -  if (!bgp) -    { -      vty_out (vty, "No BGP process is configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  /* make sure it's still in list */ -  if (!listnode_lookup (bgp->rfapi_cfg->l2_groups, rfg)) -    { -      /* Not in list anymore */ -      vty_out (vty, "Current L2 group no longer exists\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  rfg->logical_net_id = strtoul(argv[1]->arg, NULL, 10); - -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg, rfg); +	VTY_DECLVAR_CONTEXT(bgp, bgp); + +	if (!bgp) { +		vty_out(vty, "No BGP process is configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	/* make sure it's still in list */ +	if (!listnode_lookup(bgp->rfapi_cfg->l2_groups, rfg)) { +		/* Not in list anymore */ +		vty_out(vty, "Current L2 group no longer exists\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	rfg->logical_net_id = strtoul(argv[1]->arg, NULL, 10); + +	return CMD_SUCCESS;  }  DEFUN (vnc_l2_group_labels, @@ -3874,41 +3545,37 @@ DEFUN (vnc_l2_group_labels,         "Specify label values associated with group\n"         "Space separated list of label values <0-1048575>\n")  { -  VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg, rfg); -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  struct list *ll; - -  if (!bgp) -    { -      vty_out (vty, "No BGP process is configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  /* make sure it's still in list */ -  if (!listnode_lookup (bgp->rfapi_cfg->l2_groups, rfg)) -    { -      /* Not in list anymore */ -      vty_out (vty, "Current L2 group no longer exists\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  ll = rfg->labels; -  if (ll == NULL) -    { -      ll = list_new (); -      rfg->labels = ll; -    } -  argc--; -  argv++; -  for (; argc; --argc, ++argv) -    { -      uint32_t label; -      label = strtoul(argv[0]->arg, NULL, 10); -      if (!listnode_lookup (ll, (void *) (uintptr_t) label)) -        listnode_add (ll, (void *) (uintptr_t) label); -    } - -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg, rfg); +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	struct list *ll; + +	if (!bgp) { +		vty_out(vty, "No BGP process is configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	/* make sure it's still in list */ +	if (!listnode_lookup(bgp->rfapi_cfg->l2_groups, rfg)) { +		/* Not in list anymore */ +		vty_out(vty, "Current L2 group no longer exists\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	ll = rfg->labels; +	if (ll == NULL) { +		ll = list_new(); +		rfg->labels = ll; +	} +	argc--; +	argv++; +	for (; argc; --argc, ++argv) { +		uint32_t label; +		label = strtoul(argv[0]->arg, NULL, 10); +		if (!listnode_lookup(ll, (void *)(uintptr_t)label)) +			listnode_add(ll, (void *)(uintptr_t)label); +	} + +	return CMD_SUCCESS;  }  DEFUN (vnc_l2_group_no_labels, @@ -3918,41 +3585,37 @@ DEFUN (vnc_l2_group_no_labels,         "Specify label values associated with L2 group\n"         "Space separated list of label values <0-1048575>\n")  { -  VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg, rfg); -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  struct list *ll; - -  if (!bgp) -    { -      vty_out (vty, "No BGP process is configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  /* make sure it's still in list */ -  if (!listnode_lookup (bgp->rfapi_cfg->l2_groups, rfg)) -    { -      /* Not in list anymore */ -      vty_out (vty, "Current L2 group no longer exists\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  ll = rfg->labels; -  if (ll == NULL) -    { -      vty_out (vty, "Label no longer associated with group\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  argc-=2; -  argv+=2; -  for (; argc; --argc, ++argv) -    { -      uint32_t label; -      label = strtoul(argv[0]->arg, NULL, 10); -      listnode_delete (ll, (void *) (uintptr_t) label); -    } - -  return CMD_SUCCESS; +	VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg, rfg); +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	struct list *ll; + +	if (!bgp) { +		vty_out(vty, "No BGP process is configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	/* make sure it's still in list */ +	if (!listnode_lookup(bgp->rfapi_cfg->l2_groups, rfg)) { +		/* Not in list anymore */ +		vty_out(vty, "Current L2 group no longer exists\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	ll = rfg->labels; +	if (ll == NULL) { +		vty_out(vty, "Label no longer associated with group\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	argc -= 2; +	argv += 2; +	for (; argc; --argc, ++argv) { +		uint32_t label; +		label = strtoul(argv[0]->arg, NULL, 10); +		listnode_delete(ll, (void *)(uintptr_t)label); +	} + +	return CMD_SUCCESS;  }  DEFUN (vnc_l2_group_rt, @@ -3964,1086 +3627,1075 @@ DEFUN (vnc_l2_group_rt,         "Import filters\n"         "A route target\n")  { -  VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg, rfg); -  VTY_DECLVAR_CONTEXT(bgp, bgp); -  int rc = CMD_SUCCESS; -  int do_import = 0; -  int do_export = 0; - -  switch (argv[1]->arg[0]) -    { -    case 'b': -      do_export = 1;            /* fall through */ -    case 'i': -      do_import = 1; -      break; -    case 'e': -      do_export = 1; -      break; -    default: -      vty_out (vty, "Unknown option, %s\n", argv[1]->arg); -      return CMD_ERR_NO_MATCH; - -    } -  if (!bgp) -    { -      vty_out (vty, "No BGP process is configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  /* make sure it's still in list */ -  if (!listnode_lookup (bgp->rfapi_cfg->l2_groups, rfg)) -    { -      /* Not in list anymore */ -      vty_out (vty, "Current L2 group no longer exists\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (do_import) -    rc = set_ecom_list (vty, argc-2, argv+2, &rfg->rt_import_list); -  if (rc == CMD_SUCCESS && do_export) -    rc = set_ecom_list (vty, argc-2, argv+2, &rfg->rt_export_list); -  return rc; +	VTY_DECLVAR_CONTEXT_SUB(rfapi_l2_group_cfg, rfg); +	VTY_DECLVAR_CONTEXT(bgp, bgp); +	int rc = CMD_SUCCESS; +	int do_import = 0; +	int do_export = 0; + +	switch (argv[1]->arg[0]) { +	case 'b': +		do_export = 1; /* fall through */ +	case 'i': +		do_import = 1; +		break; +	case 'e': +		do_export = 1; +		break; +	default: +		vty_out(vty, "Unknown option, %s\n", argv[1]->arg); +		return CMD_ERR_NO_MATCH; +	} +	if (!bgp) { +		vty_out(vty, "No BGP process is configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	/* make sure it's still in list */ +	if (!listnode_lookup(bgp->rfapi_cfg->l2_groups, rfg)) { +		/* Not in list anymore */ +		vty_out(vty, "Current L2 group no longer exists\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (do_import) +		rc = set_ecom_list(vty, argc - 2, argv + 2, +				   &rfg->rt_import_list); +	if (rc == CMD_SUCCESS && do_export) +		rc = set_ecom_list(vty, argc - 2, argv + 2, +				   &rfg->rt_export_list); +	return rc;  }  static struct cmd_node bgp_vnc_l2_group_node = { -  BGP_VNC_L2_GROUP_NODE, -  "%s(config-router-vnc-l2-group)# ", -  1 -}; +	BGP_VNC_L2_GROUP_NODE, "%s(config-router-vnc-l2-group)# ", 1};  struct rfapi_l2_group_cfg * -bgp_rfapi_get_group_by_lni_label ( -  struct bgp	*bgp, -  uint32_t	logical_net_id, -  uint32_t	label) +bgp_rfapi_get_group_by_lni_label(struct bgp *bgp, uint32_t logical_net_id, +				 uint32_t label)  { -  struct rfapi_l2_group_cfg *rfg; -  struct listnode *node; - -  if (bgp->rfapi_cfg->l2_groups == NULL)        /* not the best place for this */ -    return NULL; - -  label = label & 0xfffff;      /* label is 20 bits! */ - -  for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->l2_groups, node, rfg)) -    { -      if (rfg->logical_net_id == logical_net_id) -        { -          struct listnode *lnode; -          void *data; -          for (ALL_LIST_ELEMENTS_RO (rfg->labels, lnode, data)) -            if (((uint32_t) ((uintptr_t) data)) == label) -              {                 /* match! */ -                return rfg; -              } -        } -    } -  return NULL; +	struct rfapi_l2_group_cfg *rfg; +	struct listnode *node; + +	if (bgp->rfapi_cfg->l2_groups == NULL) /* not the best place for this */ +		return NULL; + +	label = label & 0xfffff; /* label is 20 bits! */ + +	for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->l2_groups, node, rfg)) { +		if (rfg->logical_net_id == logical_net_id) { +			struct listnode *lnode; +			void *data; +			for (ALL_LIST_ELEMENTS_RO(rfg->labels, lnode, data)) +				if (((uint32_t)((uintptr_t)data)) +				    == label) { /* match! */ +					return rfg; +				} +		} +	} +	return NULL;  } -struct list * -bgp_rfapi_get_labellist_by_lni_label ( -  struct bgp	*bgp, -  uint32_t	logical_net_id, -  uint32_t	label) +struct list *bgp_rfapi_get_labellist_by_lni_label(struct bgp *bgp, +						  uint32_t logical_net_id, +						  uint32_t label)  { -  struct rfapi_l2_group_cfg *rfg; -  rfg = bgp_rfapi_get_group_by_lni_label (bgp, logical_net_id, label); -  if (rfg) -    { -      return rfg->labels; -    } -  return NULL; +	struct rfapi_l2_group_cfg *rfg; +	rfg = bgp_rfapi_get_group_by_lni_label(bgp, logical_net_id, label); +	if (rfg) { +		return rfg->labels; +	} +	return NULL;  }  struct ecommunity * -bgp_rfapi_get_ecommunity_by_lni_label ( -  struct bgp	*bgp, -  uint32_t	is_import, -  uint32_t	logical_net_id, -  uint32_t	label) +bgp_rfapi_get_ecommunity_by_lni_label(struct bgp *bgp, uint32_t is_import, +				      uint32_t logical_net_id, uint32_t label)  { -  struct rfapi_l2_group_cfg *rfg; -  rfg = bgp_rfapi_get_group_by_lni_label (bgp, logical_net_id, label); -  if (rfg) -    { -      if (is_import) -        return rfg->rt_import_list; -      else -        return rfg->rt_export_list; -    } -  return NULL; +	struct rfapi_l2_group_cfg *rfg; +	rfg = bgp_rfapi_get_group_by_lni_label(bgp, logical_net_id, label); +	if (rfg) { +		if (is_import) +			return rfg->rt_import_list; +		else +			return rfg->rt_export_list; +	} +	return NULL;  } -void -bgp_rfapi_cfg_init (void) +void bgp_rfapi_cfg_init(void)  { -  /* main bgpd code does not use this hook, but vnc does */ -  route_map_event_hook (vnc_routemap_event); - -  install_node (&bgp_vnc_defaults_node, NULL); -  install_node (&bgp_vnc_nve_group_node, NULL); -  install_node (&bgp_vrf_policy_node, NULL); -  install_node (&bgp_vnc_l2_group_node, NULL); -  install_default (BGP_VRF_POLICY_NODE); -  install_default (BGP_VNC_DEFAULTS_NODE); -  install_default (BGP_VNC_NVE_GROUP_NODE); -  install_default (BGP_VNC_L2_GROUP_NODE); - -  /* -   * Add commands -   */ -  install_element (BGP_NODE, &vnc_defaults_cmd); -  install_element (BGP_NODE, &vnc_nve_group_cmd); -  install_element (BGP_NODE, &vnc_no_nve_group_cmd); -  install_element (BGP_NODE, &vnc_vrf_policy_cmd); -  install_element (BGP_NODE, &vnc_no_vrf_policy_cmd); -  install_element (BGP_NODE, &vnc_l2_group_cmd); -  install_element (BGP_NODE, &vnc_no_l2_group_cmd); -  install_element (BGP_NODE, &vnc_advertise_un_method_cmd); -  install_element (BGP_NODE, &vnc_export_mode_cmd); - -  install_element (BGP_VNC_DEFAULTS_NODE, &vnc_defaults_rt_import_cmd); -  install_element (BGP_VNC_DEFAULTS_NODE, &vnc_defaults_rt_export_cmd); -  install_element (BGP_VNC_DEFAULTS_NODE, &vnc_defaults_rt_both_cmd); -  install_element (BGP_VNC_DEFAULTS_NODE, &vnc_defaults_rd_cmd); -  install_element (BGP_VNC_DEFAULTS_NODE, &vnc_defaults_l2rd_cmd); -  install_element (BGP_VNC_DEFAULTS_NODE, &vnc_defaults_no_l2rd_cmd); -  install_element (BGP_VNC_DEFAULTS_NODE, &vnc_defaults_responselifetime_cmd); -  install_element (BGP_VNC_DEFAULTS_NODE, &exit_vnc_cmd); - -  install_element (BGP_NODE, &vnc_redistribute_protocol_cmd); -  install_element (BGP_NODE, &vnc_no_redistribute_protocol_cmd); -  install_element (BGP_NODE, &vnc_redistribute_nvegroup_cmd); -  install_element (BGP_NODE, &vnc_redistribute_no_nvegroup_cmd); -  install_element (BGP_NODE, &vnc_redistribute_lifetime_cmd); -  install_element (BGP_NODE, &vnc_redistribute_rh_roo_localadmin_cmd); -  install_element (BGP_NODE, &vnc_redistribute_mode_cmd); -  install_element (BGP_NODE, &vnc_redistribute_bgp_exterior_cmd); - -  install_element (BGP_NODE, &vnc_redist_bgpdirect_no_prefixlist_cmd); -  install_element (BGP_NODE, &vnc_redist_bgpdirect_prefixlist_cmd); -  install_element (BGP_NODE, &vnc_redist_bgpdirect_no_routemap_cmd); -  install_element (BGP_NODE, &vnc_redist_bgpdirect_routemap_cmd); - -  install_element (BGP_VNC_NVE_GROUP_NODE, -                   &vnc_nve_group_redist_bgpdirect_no_prefixlist_cmd); -  install_element (BGP_VNC_NVE_GROUP_NODE, -                   &vnc_nve_group_redist_bgpdirect_prefixlist_cmd); -  install_element (BGP_VNC_NVE_GROUP_NODE, -                   &vnc_nve_group_redist_bgpdirect_no_routemap_cmd); -  install_element (BGP_VNC_NVE_GROUP_NODE, -                   &vnc_nve_group_redist_bgpdirect_routemap_cmd); - -  install_element (BGP_NODE, &vnc_export_nvegroup_cmd); -  install_element (BGP_NODE, &vnc_no_export_nvegroup_cmd); -  install_element (BGP_NODE, &vnc_nve_export_prefixlist_cmd); -  install_element (BGP_NODE, &vnc_nve_export_routemap_cmd); -  install_element (BGP_NODE, &vnc_nve_export_no_prefixlist_cmd); -  install_element (BGP_NODE, &vnc_nve_export_no_routemap_cmd); - -  install_element (BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_l2rd_cmd); -  install_element (BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_no_l2rd_cmd); -  install_element (BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_prefix_cmd); -  install_element (BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_rt_import_cmd); -  install_element (BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_rt_export_cmd); -  install_element (BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_rt_both_cmd); -  install_element (BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_rd_cmd); -  install_element (BGP_VNC_NVE_GROUP_NODE, -                   &vnc_nve_group_responselifetime_cmd); -  install_element (BGP_VNC_NVE_GROUP_NODE, -                   &vnc_nve_group_export_prefixlist_cmd); -  install_element (BGP_VNC_NVE_GROUP_NODE, -                   &vnc_nve_group_export_routemap_cmd); -  install_element (BGP_VNC_NVE_GROUP_NODE, -                   &vnc_nve_group_export_no_prefixlist_cmd); -  install_element (BGP_VNC_NVE_GROUP_NODE, -                   &vnc_nve_group_export_no_routemap_cmd); -  install_element (BGP_VNC_NVE_GROUP_NODE, &exit_vnc_cmd); - -  install_element (BGP_VRF_POLICY_NODE, &vnc_vrf_policy_label_cmd); -  install_element (BGP_VRF_POLICY_NODE, &vnc_vrf_policy_no_label_cmd); -  //Reenable to support VRF controller use case and testing -  install_element (BGP_VRF_POLICY_NODE, &vnc_vrf_policy_nexthop_cmd); -  install_element (BGP_VRF_POLICY_NODE, &vnc_vrf_policy_rt_import_cmd); -  install_element (BGP_VRF_POLICY_NODE, &vnc_vrf_policy_rt_export_cmd); -  install_element (BGP_VRF_POLICY_NODE, &vnc_vrf_policy_rt_both_cmd); -  install_element (BGP_VRF_POLICY_NODE, &vnc_vrf_policy_rd_cmd); -  install_element (BGP_VRF_POLICY_NODE, &exit_vrf_policy_cmd); - -  install_element (BGP_VNC_L2_GROUP_NODE, &vnc_l2_group_lni_cmd); -  install_element (BGP_VNC_L2_GROUP_NODE, &vnc_l2_group_labels_cmd); -  install_element (BGP_VNC_L2_GROUP_NODE, &vnc_l2_group_no_labels_cmd); -  install_element (BGP_VNC_L2_GROUP_NODE, &vnc_l2_group_rt_cmd); -  install_element (BGP_VNC_L2_GROUP_NODE, &exit_vnc_cmd); +	/* main bgpd code does not use this hook, but vnc does */ +	route_map_event_hook(vnc_routemap_event); + +	install_node(&bgp_vnc_defaults_node, NULL); +	install_node(&bgp_vnc_nve_group_node, NULL); +	install_node(&bgp_vrf_policy_node, NULL); +	install_node(&bgp_vnc_l2_group_node, NULL); +	install_default(BGP_VRF_POLICY_NODE); +	install_default(BGP_VNC_DEFAULTS_NODE); +	install_default(BGP_VNC_NVE_GROUP_NODE); +	install_default(BGP_VNC_L2_GROUP_NODE); + +	/* +	 * Add commands +	 */ +	install_element(BGP_NODE, &vnc_defaults_cmd); +	install_element(BGP_NODE, &vnc_nve_group_cmd); +	install_element(BGP_NODE, &vnc_no_nve_group_cmd); +	install_element(BGP_NODE, &vnc_vrf_policy_cmd); +	install_element(BGP_NODE, &vnc_no_vrf_policy_cmd); +	install_element(BGP_NODE, &vnc_l2_group_cmd); +	install_element(BGP_NODE, &vnc_no_l2_group_cmd); +	install_element(BGP_NODE, &vnc_advertise_un_method_cmd); +	install_element(BGP_NODE, &vnc_export_mode_cmd); + +	install_element(BGP_VNC_DEFAULTS_NODE, &vnc_defaults_rt_import_cmd); +	install_element(BGP_VNC_DEFAULTS_NODE, &vnc_defaults_rt_export_cmd); +	install_element(BGP_VNC_DEFAULTS_NODE, &vnc_defaults_rt_both_cmd); +	install_element(BGP_VNC_DEFAULTS_NODE, &vnc_defaults_rd_cmd); +	install_element(BGP_VNC_DEFAULTS_NODE, &vnc_defaults_l2rd_cmd); +	install_element(BGP_VNC_DEFAULTS_NODE, &vnc_defaults_no_l2rd_cmd); +	install_element(BGP_VNC_DEFAULTS_NODE, +			&vnc_defaults_responselifetime_cmd); +	install_element(BGP_VNC_DEFAULTS_NODE, &exit_vnc_cmd); + +	install_element(BGP_NODE, &vnc_redistribute_protocol_cmd); +	install_element(BGP_NODE, &vnc_no_redistribute_protocol_cmd); +	install_element(BGP_NODE, &vnc_redistribute_nvegroup_cmd); +	install_element(BGP_NODE, &vnc_redistribute_no_nvegroup_cmd); +	install_element(BGP_NODE, &vnc_redistribute_lifetime_cmd); +	install_element(BGP_NODE, &vnc_redistribute_rh_roo_localadmin_cmd); +	install_element(BGP_NODE, &vnc_redistribute_mode_cmd); +	install_element(BGP_NODE, &vnc_redistribute_bgp_exterior_cmd); + +	install_element(BGP_NODE, &vnc_redist_bgpdirect_no_prefixlist_cmd); +	install_element(BGP_NODE, &vnc_redist_bgpdirect_prefixlist_cmd); +	install_element(BGP_NODE, &vnc_redist_bgpdirect_no_routemap_cmd); +	install_element(BGP_NODE, &vnc_redist_bgpdirect_routemap_cmd); + +	install_element(BGP_VNC_NVE_GROUP_NODE, +			&vnc_nve_group_redist_bgpdirect_no_prefixlist_cmd); +	install_element(BGP_VNC_NVE_GROUP_NODE, +			&vnc_nve_group_redist_bgpdirect_prefixlist_cmd); +	install_element(BGP_VNC_NVE_GROUP_NODE, +			&vnc_nve_group_redist_bgpdirect_no_routemap_cmd); +	install_element(BGP_VNC_NVE_GROUP_NODE, +			&vnc_nve_group_redist_bgpdirect_routemap_cmd); + +	install_element(BGP_NODE, &vnc_export_nvegroup_cmd); +	install_element(BGP_NODE, &vnc_no_export_nvegroup_cmd); +	install_element(BGP_NODE, &vnc_nve_export_prefixlist_cmd); +	install_element(BGP_NODE, &vnc_nve_export_routemap_cmd); +	install_element(BGP_NODE, &vnc_nve_export_no_prefixlist_cmd); +	install_element(BGP_NODE, &vnc_nve_export_no_routemap_cmd); + +	install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_l2rd_cmd); +	install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_no_l2rd_cmd); +	install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_prefix_cmd); +	install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_rt_import_cmd); +	install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_rt_export_cmd); +	install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_rt_both_cmd); +	install_element(BGP_VNC_NVE_GROUP_NODE, &vnc_nve_group_rd_cmd); +	install_element(BGP_VNC_NVE_GROUP_NODE, +			&vnc_nve_group_responselifetime_cmd); +	install_element(BGP_VNC_NVE_GROUP_NODE, +			&vnc_nve_group_export_prefixlist_cmd); +	install_element(BGP_VNC_NVE_GROUP_NODE, +			&vnc_nve_group_export_routemap_cmd); +	install_element(BGP_VNC_NVE_GROUP_NODE, +			&vnc_nve_group_export_no_prefixlist_cmd); +	install_element(BGP_VNC_NVE_GROUP_NODE, +			&vnc_nve_group_export_no_routemap_cmd); +	install_element(BGP_VNC_NVE_GROUP_NODE, &exit_vnc_cmd); + +	install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_label_cmd); +	install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_no_label_cmd); +	// Reenable to support VRF controller use case and testing +	install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_nexthop_cmd); +	install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_rt_import_cmd); +	install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_rt_export_cmd); +	install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_rt_both_cmd); +	install_element(BGP_VRF_POLICY_NODE, &vnc_vrf_policy_rd_cmd); +	install_element(BGP_VRF_POLICY_NODE, &exit_vrf_policy_cmd); + +	install_element(BGP_VNC_L2_GROUP_NODE, &vnc_l2_group_lni_cmd); +	install_element(BGP_VNC_L2_GROUP_NODE, &vnc_l2_group_labels_cmd); +	install_element(BGP_VNC_L2_GROUP_NODE, &vnc_l2_group_no_labels_cmd); +	install_element(BGP_VNC_L2_GROUP_NODE, &vnc_l2_group_rt_cmd); +	install_element(BGP_VNC_L2_GROUP_NODE, &exit_vnc_cmd);  } -struct rfapi_cfg * -bgp_rfapi_cfg_new (struct rfapi_rfp_cfg *cfg) +struct rfapi_cfg *bgp_rfapi_cfg_new(struct rfapi_rfp_cfg *cfg)  { -  struct rfapi_cfg *h; -  int afi; - -  h = -    (struct rfapi_cfg *) XCALLOC (MTYPE_RFAPI_CFG, sizeof (struct rfapi_cfg)); -  assert (h); - -  h->nve_groups_sequential = list_new (); -  assert (h->nve_groups_sequential); - -  for (afi = AFI_IP; afi < AFI_MAX; afi++) -    { -      /* ugly, to deal with addition of delegates, part of 0.99.24.1 merge */ -      h->nve_groups_vn[afi].delegate = route_table_get_default_delegate (); -      h->nve_groups_un[afi].delegate = route_table_get_default_delegate (); -    } -  h->default_response_lifetime = BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT; -  h->rfg_export_direct_bgp_l = list_new (); -  h->rfg_export_zebra_l = list_new (); -  h->resolve_nve_roo_local_admin = -    BGP_VNC_CONFIG_RESOLVE_NVE_ROO_LOCAL_ADMIN_DEFAULT; - -  SET_FLAG (h->flags, BGP_VNC_CONFIG_FLAGS_DEFAULT); - -  if (cfg == NULL) -    { -      h->rfp_cfg.download_type = RFAPI_RFP_DOWNLOAD_PARTIAL; -      h->rfp_cfg.ftd_advertisement_interval = -        RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL; -      h->rfp_cfg.holddown_factor = RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR; -      h->rfp_cfg.use_updated_response = 0; -      h->rfp_cfg.use_removes = 0; -    } -  else -    { -      h->rfp_cfg.download_type = cfg->download_type; -      h->rfp_cfg.ftd_advertisement_interval = cfg->ftd_advertisement_interval; -      h->rfp_cfg.holddown_factor = cfg->holddown_factor; -      h->rfp_cfg.use_updated_response = cfg->use_updated_response; -      h->rfp_cfg.use_removes = cfg->use_removes; -      if (cfg->use_updated_response) -        h->flags &= ~BGP_VNC_CONFIG_CALLBACK_DISABLE; -      else -        h->flags |= BGP_VNC_CONFIG_CALLBACK_DISABLE; -      if (cfg->use_removes) -        h->flags &= ~BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE; -      else -        h->flags |= BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE; -    } -  return h; +	struct rfapi_cfg *h; +	int afi; + +	h = (struct rfapi_cfg *)XCALLOC(MTYPE_RFAPI_CFG, +					sizeof(struct rfapi_cfg)); +	assert(h); + +	h->nve_groups_sequential = list_new(); +	assert(h->nve_groups_sequential); + +	for (afi = AFI_IP; afi < AFI_MAX; afi++) { +		/* ugly, to deal with addition of delegates, part of 0.99.24.1 +		 * merge */ +		h->nve_groups_vn[afi].delegate = +			route_table_get_default_delegate(); +		h->nve_groups_un[afi].delegate = +			route_table_get_default_delegate(); +	} +	h->default_response_lifetime = +		BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT; +	h->rfg_export_direct_bgp_l = list_new(); +	h->rfg_export_zebra_l = list_new(); +	h->resolve_nve_roo_local_admin = +		BGP_VNC_CONFIG_RESOLVE_NVE_ROO_LOCAL_ADMIN_DEFAULT; + +	SET_FLAG(h->flags, BGP_VNC_CONFIG_FLAGS_DEFAULT); + +	if (cfg == NULL) { +		h->rfp_cfg.download_type = RFAPI_RFP_DOWNLOAD_PARTIAL; +		h->rfp_cfg.ftd_advertisement_interval = +			RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL; +		h->rfp_cfg.holddown_factor = +			RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR; +		h->rfp_cfg.use_updated_response = 0; +		h->rfp_cfg.use_removes = 0; +	} else { +		h->rfp_cfg.download_type = cfg->download_type; +		h->rfp_cfg.ftd_advertisement_interval = +			cfg->ftd_advertisement_interval; +		h->rfp_cfg.holddown_factor = cfg->holddown_factor; +		h->rfp_cfg.use_updated_response = cfg->use_updated_response; +		h->rfp_cfg.use_removes = cfg->use_removes; +		if (cfg->use_updated_response) +			h->flags &= ~BGP_VNC_CONFIG_CALLBACK_DISABLE; +		else +			h->flags |= BGP_VNC_CONFIG_CALLBACK_DISABLE; +		if (cfg->use_removes) +			h->flags &= ~BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE; +		else +			h->flags |= BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE; +	} +	return h;  } -void -bgp_rfapi_cfg_destroy (struct bgp *bgp, struct rfapi_cfg *h) +void bgp_rfapi_cfg_destroy(struct bgp *bgp, struct rfapi_cfg *h)  { -  if (h == NULL) -    return; - -  bgp_rfapi_delete_named_nve_group (NULL, bgp, NULL, RFAPI_GROUP_CFG_MAX); -  bgp_rfapi_delete_named_l2_group (NULL, bgp, NULL); -  if (h->l2_groups != NULL) -    list_delete (h->l2_groups); -  list_delete (h->nve_groups_sequential); -  list_delete (h->rfg_export_direct_bgp_l); -  list_delete (h->rfg_export_zebra_l); -  if (h->default_rt_export_list) -    ecommunity_free (&h->default_rt_export_list); -  if (h->default_rt_import_list) -    ecommunity_free (&h->default_rt_import_list); -  if (h->default_rfp_cfg) -    XFREE (MTYPE_RFAPI_RFP_GROUP_CFG, h->default_rfp_cfg); -  XFREE (MTYPE_RFAPI_CFG, h); - +	if (h == NULL) +		return; + +	bgp_rfapi_delete_named_nve_group(NULL, bgp, NULL, RFAPI_GROUP_CFG_MAX); +	bgp_rfapi_delete_named_l2_group(NULL, bgp, NULL); +	if (h->l2_groups != NULL) +		list_delete(h->l2_groups); +	list_delete(h->nve_groups_sequential); +	list_delete(h->rfg_export_direct_bgp_l); +	list_delete(h->rfg_export_zebra_l); +	if (h->default_rt_export_list) +		ecommunity_free(&h->default_rt_export_list); +	if (h->default_rt_import_list) +		ecommunity_free(&h->default_rt_import_list); +	if (h->default_rfp_cfg) +		XFREE(MTYPE_RFAPI_RFP_GROUP_CFG, h->default_rfp_cfg); +	XFREE(MTYPE_RFAPI_CFG, h);  } -int -bgp_rfapi_cfg_write (struct vty *vty, struct bgp *bgp) +int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp)  { -  struct listnode *node, *nnode; -  struct rfapi_nve_group_cfg *rfg; -  struct rfapi_cfg *hc = bgp->rfapi_cfg; -  struct rfapi_rfg_name *rfgn; -  int write = 0; -  afi_t afi; -  int type; -  if (bgp->rfapi == NULL || hc == NULL) -    return write; - -  vty_out (vty, "!\n"); -  for (ALL_LIST_ELEMENTS (hc->nve_groups_sequential, node, nnode, rfg)) -    if (rfg->type == RFAPI_GROUP_CFG_VRF) -      { -        ++write; -        vty_out (vty, " vrf-policy %s\n", rfg->name); -        if (rfg->label <= MPLS_LABEL_MAX) -          { -            vty_out (vty, "  label %u\n", rfg->label); - -          } -        if (CHECK_FLAG (rfg->flags, RFAPI_RFG_VPN_NH_SELF)) -          { -            vty_out (vty, "  nexthop self\n"); - -          } -        else  -          { -            if (rfg->vn_prefix.family) -              { -                char buf[BUFSIZ]; -                buf[0] = buf[BUFSIZ - 1] = 0; -                inet_ntop(rfg->vn_prefix.family, &rfg->vn_prefix.u.prefix, buf, sizeof(buf)); -                if (!buf[0] || buf[BUFSIZ - 1]) -                  { -                    //vty_out (vty, "nexthop self\n"); -                  } -                else -                  { -                    vty_out (vty, "  nexthop %s\n", buf); -                  } -              } -          } - -        if (rfg->rd.prefixlen) -          { -            char buf[BUFSIZ]; -            buf[0] = buf[BUFSIZ - 1] = 0; - -            if (AF_UNIX == rfg->rd.family) -              { - -                uint16_t value = 0; - -                value = ((rfg->rd.val[6] << 8) & 0x0ff00) | -                  (rfg->rd.val[7] & 0x0ff); - -                vty_out (vty, "  rd auto:nh:%d\n", value); - -              } -            else -              { - -                if (!prefix_rd2str (&rfg->rd, buf, BUFSIZ) || -                    !buf[0] || buf[BUFSIZ - 1]) -                  { - -                    vty_out (vty, "!Error: Can't convert rd\n"); -                  } -                else -                  { -                    vty_out (vty, "  rd %s\n", buf); -                  } -              } -          } - -        if (rfg->rt_import_list && rfg->rt_export_list && -            ecommunity_cmp (rfg->rt_import_list, rfg->rt_export_list)) -          { -            char *b = ecommunity_ecom2str (rfg->rt_import_list, -                                           ECOMMUNITY_FORMAT_ROUTE_MAP, ECOMMUNITY_ROUTE_TARGET); -            vty_out (vty, "  rt both %s\n", b); -            XFREE (MTYPE_ECOMMUNITY_STR, b); -          } -        else -          { -            if (rfg->rt_import_list) -              { -                char *b = ecommunity_ecom2str (rfg->rt_import_list, -                                               ECOMMUNITY_FORMAT_ROUTE_MAP, ECOMMUNITY_ROUTE_TARGET); -                vty_out (vty, "  rt import %s\n", b); -                XFREE (MTYPE_ECOMMUNITY_STR, b); -              } -            if (rfg->rt_export_list) -              { -                char *b = ecommunity_ecom2str (rfg->rt_export_list, -                                               ECOMMUNITY_FORMAT_ROUTE_MAP, ECOMMUNITY_ROUTE_TARGET); -                vty_out (vty, "  rt export %s\n", b); -                XFREE (MTYPE_ECOMMUNITY_STR, b); -              } -          } - -        /* -         * route filtering: prefix-lists and route-maps -         */ -        for (afi = AFI_IP; afi < AFI_MAX; ++afi) -          { - -            const char *afistr = (afi == AFI_IP) ? "ipv4" : "ipv6"; - -            if (rfg->plist_export_bgp_name[afi]) -              { -                vty_out (vty, "  export bgp %s prefix-list %s\n", -                         afistr,rfg->plist_export_bgp_name[afi]); -              } -            if (rfg->plist_export_zebra_name[afi]) -              { -                vty_out (vty, "  export zebra %s prefix-list %s\n", -                         afistr,rfg->plist_export_zebra_name[afi]); -              } -            /* -             * currently we only support redist plists for bgp-direct. -             * If we later add plist support for redistributing other -             * protocols, we'll need to loop over protocols here -             */ -            if (rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]) -              { -                vty_out (vty, "  redistribute bgp-direct %s prefix-list %s\n", -                         afistr, -                         rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]); -              } -            if (rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT_EXT][afi]) -              { -                vty_out (vty, -                         "  redistribute bgp-direct-to-nve-groups %s prefix-list %s\n", -                         afistr, -                         rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT_EXT][afi]); -              } -          } - -        if (rfg->routemap_export_bgp_name) -          { -            vty_out (vty, "  export bgp route-map %s\n", -                     rfg->routemap_export_bgp_name); -          } -        if (rfg->routemap_export_zebra_name) -          { -            vty_out (vty, "  export zebra route-map %s\n", -                     rfg->routemap_export_zebra_name); -          } -        if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]) -          { -            vty_out (vty, "  redistribute bgp-direct route-map %s\n", -                     rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]); -          } -        if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT_EXT]) -          { -            vty_out (vty, -                     "  redistribute bgp-direct-to-nve-groups route-map %s\n", -                     rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT_EXT]); -          } -        vty_out (vty, "  exit-vrf-policy\n"); -        vty_out (vty, "!\n"); -      } -  if (hc->flags & BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP) -    { -      vty_out (vty, " vnc advertise-un-method encap-safi\n"); -      write++; -    } - -  {                             /* was based on listen ports */ -    /* for now allow both old and new */ -    if (bgp->rfapi->rfp_methods.cfg_cb) -      write += (bgp->rfapi->rfp_methods.cfg_cb) (vty, bgp->rfapi->rfp); - -    if (write) -      vty_out (vty, "!\n"); - -    if (hc->l2_groups) -      { -        struct rfapi_l2_group_cfg *rfg = NULL; -        struct listnode *gnode; -        for (ALL_LIST_ELEMENTS_RO (hc->l2_groups, gnode, rfg)) -          { -            struct listnode *lnode; -            void *data; -            ++write; -            vty_out (vty, " vnc l2-group %s\n", rfg->name); -            if (rfg->logical_net_id != 0) -              vty_out (vty, "   logical-network-id %u\n", -                         rfg->logical_net_id); -            if (rfg->labels != NULL && listhead (rfg->labels) != NULL) -              { -                vty_out (vty, "   labels "); -                for (ALL_LIST_ELEMENTS_RO (rfg->labels, lnode, data)) -                  { -                    vty_out (vty, "%hu ", (uint16_t) ((uintptr_t) data)); -                  } -                vty_out (vty, "\n"); -              } - -            if (rfg->rt_import_list && rfg->rt_export_list && -                ecommunity_cmp (rfg->rt_import_list, rfg->rt_export_list)) -              { -                char *b = ecommunity_ecom2str (rfg->rt_import_list, -                                               ECOMMUNITY_FORMAT_ROUTE_MAP, ECOMMUNITY_ROUTE_TARGET); -                vty_out (vty, "   rt both %s\n", b); -                XFREE (MTYPE_ECOMMUNITY_STR, b); -              } -            else -              { -                if (rfg->rt_import_list) -                  { -                    char *b = ecommunity_ecom2str (rfg->rt_import_list, -                                                   ECOMMUNITY_FORMAT_ROUTE_MAP, ECOMMUNITY_ROUTE_TARGET); -                    vty_out (vty, "  rt import %s\n", b); -                    XFREE (MTYPE_ECOMMUNITY_STR, b); -                  } -                if (rfg->rt_export_list) -                  { -                    char *b = ecommunity_ecom2str (rfg->rt_export_list, -                                                   ECOMMUNITY_FORMAT_ROUTE_MAP, ECOMMUNITY_ROUTE_TARGET); -                    vty_out (vty, "  rt export %s\n", b); -                    XFREE (MTYPE_ECOMMUNITY_STR, b); -                  } -              } -            if (bgp->rfapi->rfp_methods.cfg_group_cb) -              write += -                (bgp->rfapi->rfp_methods.cfg_group_cb) (vty, -                                                        bgp->rfapi->rfp, -                                                        RFAPI_RFP_CFG_GROUP_L2, -                                                        rfg->name, -                                                        rfg->rfp_cfg); -            vty_out (vty, "   exit-vnc\n"); -            vty_out (vty, "!\n"); -          } -      } - -    if (hc->default_rd.family || -        hc->default_response_lifetime || -        hc->default_rt_import_list || -        hc->default_rt_export_list || hc->nve_groups_sequential->count) -      { - - -        ++write; -        vty_out (vty, " vnc defaults\n"); - -        if (hc->default_rd.prefixlen) -          { -            char buf[BUFSIZ]; -            buf[0] = buf[BUFSIZ - 1] = 0; - -            if (AF_UNIX == hc->default_rd.family) -              { -                uint16_t value = 0; - -                value = ((hc->default_rd.val[6] << 8) & 0x0ff00) | -                  (hc->default_rd.val[7] & 0x0ff); - -                vty_out (vty, "  rd auto:vn:%d\n", value); - -              } -            else -              { - -                if (!prefix_rd2str (&hc->default_rd, buf, BUFSIZ) || -                    !buf[0] || buf[BUFSIZ - 1]) -                  { - -                    vty_out (vty, "!Error: Can't convert rd\n"); -                  } -                else -                  { -                    vty_out (vty, "  rd %s\n", buf); -                  } -              } -          } -        if (hc->default_response_lifetime) -          { -            vty_out (vty, "  response-lifetime "); -            if (hc->default_response_lifetime != UINT32_MAX) -              vty_out (vty, "%d", hc->default_response_lifetime); -            else -              vty_out (vty, "infinite"); -            vty_out (vty, "\n"); -          } -        if (hc->default_rt_import_list && hc->default_rt_export_list && -            ecommunity_cmp (hc->default_rt_import_list, -                            hc->default_rt_export_list)) -          { -            char *b = ecommunity_ecom2str (hc->default_rt_import_list, -                                           ECOMMUNITY_FORMAT_ROUTE_MAP, ECOMMUNITY_ROUTE_TARGET); -            vty_out (vty, "  rt both %s\n", b); -            XFREE (MTYPE_ECOMMUNITY_STR, b); -          } -        else -          { -            if (hc->default_rt_import_list) -              { -                char *b = ecommunity_ecom2str (hc->default_rt_import_list, -                                               ECOMMUNITY_FORMAT_ROUTE_MAP, ECOMMUNITY_ROUTE_TARGET); -                vty_out (vty, "  rt import %s\n", b); -                XFREE (MTYPE_ECOMMUNITY_STR, b); -              } -            if (hc->default_rt_export_list) -              { -                char *b = ecommunity_ecom2str (hc->default_rt_export_list, -                                               ECOMMUNITY_FORMAT_ROUTE_MAP, ECOMMUNITY_ROUTE_TARGET); -                vty_out (vty, "  rt export %s\n", b); -                XFREE (MTYPE_ECOMMUNITY_STR, b); -              } -          } -        if (bgp->rfapi->rfp_methods.cfg_group_cb) -          write += -            (bgp->rfapi->rfp_methods.cfg_group_cb) (vty, -                                                    bgp->rfapi->rfp, -                                                    RFAPI_RFP_CFG_GROUP_DEFAULT, -                                                    NULL, -                                                    bgp->rfapi_cfg->default_rfp_cfg); -        vty_out (vty, "  exit-vnc\n"); -        vty_out (vty, "!\n"); -      } - -    for (ALL_LIST_ELEMENTS (hc->nve_groups_sequential, node, nnode, rfg)) -      if (rfg->type == RFAPI_GROUP_CFG_NVE) -      { -        ++write; -        vty_out (vty, " vnc nve-group %s\n", rfg->name); - -        if (rfg->vn_prefix.family && rfg->vn_node) -          { -            char buf[BUFSIZ]; -            buf[0] = buf[BUFSIZ - 1] = 0; - -            prefix2str (&rfg->vn_prefix, buf, BUFSIZ); -            if (!buf[0] || buf[BUFSIZ - 1]) -              { -                vty_out (vty, "!Error: Can't convert prefix\n"); -              } -            else -              { -                vty_out (vty, "  prefix %s %s\n", "vn", buf); -              } -          } - -        if (rfg->un_prefix.family && rfg->un_node) -          { -            char buf[BUFSIZ]; -            buf[0] = buf[BUFSIZ - 1] = 0; -            prefix2str (&rfg->un_prefix, buf, BUFSIZ); -            if (!buf[0] || buf[BUFSIZ - 1]) -              { -                vty_out (vty, "!Error: Can't convert prefix\n"); -              } -            else -              { -                vty_out (vty, "  prefix %s %s\n", "un", buf); -              } -          } - - -        if (rfg->rd.prefixlen) -          { -            char buf[BUFSIZ]; -            buf[0] = buf[BUFSIZ - 1] = 0; - -            if (AF_UNIX == rfg->rd.family) -              { - -                uint16_t value = 0; - -                value = ((rfg->rd.val[6] << 8) & 0x0ff00) | -                  (rfg->rd.val[7] & 0x0ff); - -                vty_out (vty, "  rd auto:vn:%d\n", value); - -              } -            else -              { - -                if (!prefix_rd2str (&rfg->rd, buf, BUFSIZ) || -                    !buf[0] || buf[BUFSIZ - 1]) -                  { - -                    vty_out (vty, "!Error: Can't convert rd\n"); -                  } -                else -                  { -                    vty_out (vty, "  rd %s\n", buf); -                  } -              } -          } -        if (rfg->flags & RFAPI_RFG_RESPONSE_LIFETIME) -          { -            vty_out (vty, "  response-lifetime "); -            if (rfg->response_lifetime != UINT32_MAX) -              vty_out (vty, "%d", rfg->response_lifetime); -            else -              vty_out (vty, "infinite"); -            vty_out (vty, "\n"); -          } - -        if (rfg->rt_import_list && rfg->rt_export_list && -            ecommunity_cmp (rfg->rt_import_list, rfg->rt_export_list)) -          { -            char *b = ecommunity_ecom2str (rfg->rt_import_list, -                                           ECOMMUNITY_FORMAT_ROUTE_MAP, -                                           ECOMMUNITY_ROUTE_TARGET); -            vty_out (vty, "  rt both %s\n", b); -            XFREE (MTYPE_ECOMMUNITY_STR, b); -          } -        else -          { -            if (rfg->rt_import_list) -              { -                char *b = ecommunity_ecom2str (rfg->rt_import_list, -                                               ECOMMUNITY_FORMAT_ROUTE_MAP, -                                               ECOMMUNITY_ROUTE_TARGET); -                vty_out (vty, "  rt import %s\n", b); -                XFREE (MTYPE_ECOMMUNITY_STR, b); -              } -            if (rfg->rt_export_list) -              { -                char *b = ecommunity_ecom2str (rfg->rt_export_list, -                                               ECOMMUNITY_FORMAT_ROUTE_MAP, ECOMMUNITY_ROUTE_TARGET); -                vty_out (vty, "  rt export %s\n", b); -                XFREE (MTYPE_ECOMMUNITY_STR, b); -              } -          } - -        /* -         * route filtering: prefix-lists and route-maps -         */ -        for (afi = AFI_IP; afi < AFI_MAX; ++afi) -          { - -            const char *afistr = (afi == AFI_IP) ? "ipv4" : "ipv6"; - -            if (rfg->plist_export_bgp_name[afi]) -              { -                vty_out (vty, "  export bgp %s prefix-list %s\n", -                         afistr,rfg->plist_export_bgp_name[afi]); -              } -            if (rfg->plist_export_zebra_name[afi]) -              { -                vty_out (vty, "  export zebra %s prefix-list %s\n", -                         afistr,rfg->plist_export_zebra_name[afi]); -              } -            /* -             * currently we only support redist plists for bgp-direct. -             * If we later add plist support for redistributing other -             * protocols, we'll need to loop over protocols here -             */ -            if (rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]) -              { -                vty_out (vty, "  redistribute bgp-direct %s prefix-list %s\n", -                         afistr, -                         rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]); -              } -            if (rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT_EXT][afi]) -              { -                vty_out (vty, -                         "  redistribute bgp-direct-to-nve-groups %s prefix-list %s\n", -                         afistr, -                         rfg->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT_EXT][afi]); -              } -          } - -        if (rfg->routemap_export_bgp_name) -          { -            vty_out (vty, "  export bgp route-map %s\n", -                     rfg->routemap_export_bgp_name); -          } -        if (rfg->routemap_export_zebra_name) -          { -            vty_out (vty, "  export zebra route-map %s\n", -                     rfg->routemap_export_zebra_name); -          } -        if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]) -          { -            vty_out (vty, "  redistribute bgp-direct route-map %s\n", -                     rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]); -          } -        if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT_EXT]) -          { -            vty_out (vty, -                     "  redistribute bgp-direct-to-nve-groups route-map %s\n", -                     rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT_EXT]); -          } -        if (bgp->rfapi->rfp_methods.cfg_group_cb) -          write += -            (bgp->rfapi->rfp_methods.cfg_group_cb) (vty, -                                                    bgp->rfapi->rfp, -                                                    RFAPI_RFP_CFG_GROUP_NVE, -                                                    rfg->name, rfg->rfp_cfg); -        vty_out (vty, "  exit-vnc\n"); -        vty_out (vty, "!\n"); -      } -  }                             /* have listen ports */ - -  /* -   * route export to other protocols -   */ -  if (VNC_EXPORT_BGP_GRP_ENABLED (hc)) -    { -      vty_out (vty, " vnc export bgp mode group-nve\n"); -    } -  else if (VNC_EXPORT_BGP_RH_ENABLED (hc)) -    { -      vty_out (vty, " vnc export bgp mode registering-nve\n"); -    } -  else if (VNC_EXPORT_BGP_CE_ENABLED (hc)) -    { -      vty_out (vty, " vnc export bgp mode ce\n"); -    } - -  if (VNC_EXPORT_ZEBRA_GRP_ENABLED (hc)) -    { -      vty_out (vty, " vnc export zebra mode group-nve\n"); -    } -  else if (VNC_EXPORT_ZEBRA_RH_ENABLED (hc)) -    { -      vty_out (vty, " vnc export zebra mode registering-nve\n"); -    } - -  if (hc->rfg_export_direct_bgp_l) -    { -      for (ALL_LIST_ELEMENTS (hc->rfg_export_direct_bgp_l, node, nnode, rfgn)) -        { - -          vty_out (vty, " vnc export bgp group-nve group %s\n", -                   rfgn->name); -        } -    } - -  if (hc->rfg_export_zebra_l) -    { -      for (ALL_LIST_ELEMENTS (hc->rfg_export_zebra_l, node, nnode, rfgn)) -        { - -          vty_out (vty, " vnc export zebra group-nve group %s\n", -                   rfgn->name); -        } -    } - - -  if (hc->rfg_redist_name) -    { -      vty_out (vty, " vnc redistribute nve-group %s\n", -               hc->rfg_redist_name); -    } -  if (hc->redist_lifetime) -    { -      vty_out (vty, " vnc redistribute lifetime %d\n", -               hc->redist_lifetime); -    } -  if (hc->resolve_nve_roo_local_admin != -      BGP_VNC_CONFIG_RESOLVE_NVE_ROO_LOCAL_ADMIN_DEFAULT) -    { - -      vty_out (vty, " vnc redistribute resolve-nve roo-ec-local-admin %d\n", -               hc->resolve_nve_roo_local_admin); -    } - -  if (hc->redist_mode)          /* ! default */ -    { -      const char *s = ""; - -      switch (hc->redist_mode) -        { -        case VNC_REDIST_MODE_PLAIN: -          s = "plain"; -          break; -        case VNC_REDIST_MODE_RFG: -          s = "nve-group"; -          break; -        case VNC_REDIST_MODE_RESOLVE_NVE: -          s = "resolve-nve"; -          break; -        } -      if (s) -        { -          vty_out (vty, " vnc redistribute mode %s\n", s); -        } -    } - -  /* -   * route filtering: prefix-lists and route-maps -   */ -  for (afi = AFI_IP; afi < AFI_MAX; ++afi) -    { - -      const char *afistr = (afi == AFI_IP) ? "ipv4" : "ipv6"; - -      if (hc->plist_export_bgp_name[afi]) -        { -          vty_out (vty, " vnc export bgp %s prefix-list %s\n", -                   afistr, hc->plist_export_bgp_name[afi]); -        } -      if (hc->plist_export_zebra_name[afi]) -        { -          vty_out (vty, " vnc export zebra %s prefix-list %s\n", -                   afistr, hc->plist_export_zebra_name[afi]); -        } -      if (hc->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]) -        { -          vty_out (vty, " vnc redistribute bgp-direct %s prefix-list %s\n", -                   afistr,hc->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]); -        } -    } - -  if (hc->routemap_export_bgp_name) -    { -      vty_out (vty, " vnc export bgp route-map %s\n", -               hc->routemap_export_bgp_name); -    } -  if (hc->routemap_export_zebra_name) -    { -      vty_out (vty, " vnc export zebra route-map %s\n", -               hc->routemap_export_zebra_name); -    } -  if (hc->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]) -    { -      vty_out (vty, " vnc redistribute bgp-direct route-map %s\n", -               hc->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]); -    } - -  for (afi = AFI_IP; afi < AFI_MAX; ++afi) -    { -      for (type = 0; type < ZEBRA_ROUTE_MAX; ++type) -        { -          if (hc->redist[afi][type]) -            { -              if (type == ZEBRA_ROUTE_BGP_DIRECT_EXT && -                  hc->redist_bgp_exterior_view_name) -                { -                  vty_out (vty, " vnc redistribute %s %s view %s\n", -                           ((afi == AFI_IP) ? "ipv4" : "ipv6"), -                           zebra_route_string (type), -                           hc->redist_bgp_exterior_view_name); -                } -              else -                { -                  vty_out (vty, " vnc redistribute %s %s\n", -                           ((afi == AFI_IP) ? "ipv4" : "ipv6"), -                           zebra_route_string(type)); -                } -            } -        } -    } -  return write; +	struct listnode *node, *nnode; +	struct rfapi_nve_group_cfg *rfg; +	struct rfapi_cfg *hc = bgp->rfapi_cfg; +	struct rfapi_rfg_name *rfgn; +	int write = 0; +	afi_t afi; +	int type; +	if (bgp->rfapi == NULL || hc == NULL) +		return write; + +	vty_out(vty, "!\n"); +	for (ALL_LIST_ELEMENTS(hc->nve_groups_sequential, node, nnode, rfg)) +		if (rfg->type == RFAPI_GROUP_CFG_VRF) { +			++write; +			vty_out(vty, " vrf-policy %s\n", rfg->name); +			if (rfg->label <= MPLS_LABEL_MAX) { +				vty_out(vty, "  label %u\n", rfg->label); +			} +			if (CHECK_FLAG(rfg->flags, RFAPI_RFG_VPN_NH_SELF)) { +				vty_out(vty, "  nexthop self\n"); + +			} else { +				if (rfg->vn_prefix.family) { +					char buf[BUFSIZ]; +					buf[0] = buf[BUFSIZ - 1] = 0; +					inet_ntop(rfg->vn_prefix.family, +						  &rfg->vn_prefix.u.prefix, buf, +						  sizeof(buf)); +					if (!buf[0] || buf[BUFSIZ - 1]) { +						// vty_out (vty, "nexthop +						// self\n"); +					} else { +						vty_out(vty, "  nexthop %s\n", +							buf); +					} +				} +			} + +			if (rfg->rd.prefixlen) { +				char buf[BUFSIZ]; +				buf[0] = buf[BUFSIZ - 1] = 0; + +				if (AF_UNIX == rfg->rd.family) { + +					uint16_t value = 0; + +					value = ((rfg->rd.val[6] << 8) +						 & 0x0ff00) +						| (rfg->rd.val[7] & 0x0ff); + +					vty_out(vty, "  rd auto:nh:%d\n", +						value); + +				} else { + +					if (!prefix_rd2str(&rfg->rd, buf, +							   BUFSIZ) +					    || !buf[0] || buf[BUFSIZ - 1]) { + +						vty_out(vty, +							"!Error: Can't convert rd\n"); +					} else { +						vty_out(vty, "  rd %s\n", buf); +					} +				} +			} + +			if (rfg->rt_import_list && rfg->rt_export_list +			    && ecommunity_cmp(rfg->rt_import_list, +					      rfg->rt_export_list)) { +				char *b = ecommunity_ecom2str( +					rfg->rt_import_list, +					ECOMMUNITY_FORMAT_ROUTE_MAP, +					ECOMMUNITY_ROUTE_TARGET); +				vty_out(vty, "  rt both %s\n", b); +				XFREE(MTYPE_ECOMMUNITY_STR, b); +			} else { +				if (rfg->rt_import_list) { +					char *b = ecommunity_ecom2str( +						rfg->rt_import_list, +						ECOMMUNITY_FORMAT_ROUTE_MAP, +						ECOMMUNITY_ROUTE_TARGET); +					vty_out(vty, "  rt import %s\n", b); +					XFREE(MTYPE_ECOMMUNITY_STR, b); +				} +				if (rfg->rt_export_list) { +					char *b = ecommunity_ecom2str( +						rfg->rt_export_list, +						ECOMMUNITY_FORMAT_ROUTE_MAP, +						ECOMMUNITY_ROUTE_TARGET); +					vty_out(vty, "  rt export %s\n", b); +					XFREE(MTYPE_ECOMMUNITY_STR, b); +				} +			} + +			/* +			 * route filtering: prefix-lists and route-maps +			 */ +			for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + +				const char *afistr = +					(afi == AFI_IP) ? "ipv4" : "ipv6"; + +				if (rfg->plist_export_bgp_name[afi]) { +					vty_out(vty, +						"  export bgp %s prefix-list %s\n", +						afistr, +						rfg->plist_export_bgp_name +							[afi]); +				} +				if (rfg->plist_export_zebra_name[afi]) { +					vty_out(vty, +						"  export zebra %s prefix-list %s\n", +						afistr, +						rfg->plist_export_zebra_name +							[afi]); +				} +				/* +				 * currently we only support redist plists for +				 * bgp-direct. +				 * If we later add plist support for +				 * redistributing other +				 * protocols, we'll need to loop over protocols +				 * here +				 */ +				if (rfg->plist_redist_name +					    [ZEBRA_ROUTE_BGP_DIRECT][afi]) { +					vty_out(vty, +						"  redistribute bgp-direct %s prefix-list %s\n", +						afistr, +						rfg->plist_redist_name +							[ZEBRA_ROUTE_BGP_DIRECT] +							[afi]); +				} +				if (rfg->plist_redist_name +					    [ZEBRA_ROUTE_BGP_DIRECT_EXT][afi]) { +					vty_out(vty, +						"  redistribute bgp-direct-to-nve-groups %s prefix-list %s\n", +						afistr, +						rfg->plist_redist_name +							[ZEBRA_ROUTE_BGP_DIRECT_EXT] +							[afi]); +				} +			} + +			if (rfg->routemap_export_bgp_name) { +				vty_out(vty, "  export bgp route-map %s\n", +					rfg->routemap_export_bgp_name); +			} +			if (rfg->routemap_export_zebra_name) { +				vty_out(vty, "  export zebra route-map %s\n", +					rfg->routemap_export_zebra_name); +			} +			if (rfg->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]) { +				vty_out(vty, +					"  redistribute bgp-direct route-map %s\n", +					rfg->routemap_redist_name +						[ZEBRA_ROUTE_BGP_DIRECT]); +			} +			if (rfg->routemap_redist_name +				    [ZEBRA_ROUTE_BGP_DIRECT_EXT]) { +				vty_out(vty, +					"  redistribute bgp-direct-to-nve-groups route-map %s\n", +					rfg->routemap_redist_name +						[ZEBRA_ROUTE_BGP_DIRECT_EXT]); +			} +			vty_out(vty, "  exit-vrf-policy\n"); +			vty_out(vty, "!\n"); +		} +	if (hc->flags & BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP) { +		vty_out(vty, " vnc advertise-un-method encap-safi\n"); +		write++; +	} + +	{ /* was based on listen ports */ +		/* for now allow both old and new */ +		if (bgp->rfapi->rfp_methods.cfg_cb) +			write += (bgp->rfapi->rfp_methods.cfg_cb)( +				vty, bgp->rfapi->rfp); + +		if (write) +			vty_out(vty, "!\n"); + +		if (hc->l2_groups) { +			struct rfapi_l2_group_cfg *rfg = NULL; +			struct listnode *gnode; +			for (ALL_LIST_ELEMENTS_RO(hc->l2_groups, gnode, rfg)) { +				struct listnode *lnode; +				void *data; +				++write; +				vty_out(vty, " vnc l2-group %s\n", rfg->name); +				if (rfg->logical_net_id != 0) +					vty_out(vty, +						"   logical-network-id %u\n", +						rfg->logical_net_id); +				if (rfg->labels != NULL +				    && listhead(rfg->labels) != NULL) { +					vty_out(vty, "   labels "); +					for (ALL_LIST_ELEMENTS_RO(rfg->labels, +								  lnode, +								  data)) { +						vty_out(vty, "%hu ", +							(uint16_t)( +								(uintptr_t) +									data)); +					} +					vty_out(vty, "\n"); +				} + +				if (rfg->rt_import_list && rfg->rt_export_list +				    && ecommunity_cmp(rfg->rt_import_list, +						      rfg->rt_export_list)) { +					char *b = ecommunity_ecom2str( +						rfg->rt_import_list, +						ECOMMUNITY_FORMAT_ROUTE_MAP, +						ECOMMUNITY_ROUTE_TARGET); +					vty_out(vty, "   rt both %s\n", b); +					XFREE(MTYPE_ECOMMUNITY_STR, b); +				} else { +					if (rfg->rt_import_list) { +						char *b = ecommunity_ecom2str( +							rfg->rt_import_list, +							ECOMMUNITY_FORMAT_ROUTE_MAP, +							ECOMMUNITY_ROUTE_TARGET); +						vty_out(vty, "  rt import %s\n", +							b); +						XFREE(MTYPE_ECOMMUNITY_STR, b); +					} +					if (rfg->rt_export_list) { +						char *b = ecommunity_ecom2str( +							rfg->rt_export_list, +							ECOMMUNITY_FORMAT_ROUTE_MAP, +							ECOMMUNITY_ROUTE_TARGET); +						vty_out(vty, "  rt export %s\n", +							b); +						XFREE(MTYPE_ECOMMUNITY_STR, b); +					} +				} +				if (bgp->rfapi->rfp_methods.cfg_group_cb) +					write += (bgp->rfapi->rfp_methods +							  .cfg_group_cb)( +						vty, bgp->rfapi->rfp, +						RFAPI_RFP_CFG_GROUP_L2, +						rfg->name, rfg->rfp_cfg); +				vty_out(vty, "   exit-vnc\n"); +				vty_out(vty, "!\n"); +			} +		} + +		if (hc->default_rd.family || hc->default_response_lifetime +		    || hc->default_rt_import_list || hc->default_rt_export_list +		    || hc->nve_groups_sequential->count) { + + +			++write; +			vty_out(vty, " vnc defaults\n"); + +			if (hc->default_rd.prefixlen) { +				char buf[BUFSIZ]; +				buf[0] = buf[BUFSIZ - 1] = 0; + +				if (AF_UNIX == hc->default_rd.family) { +					uint16_t value = 0; + +					value = ((hc->default_rd.val[6] << 8) +						 & 0x0ff00) +						| (hc->default_rd.val[7] +						   & 0x0ff); + +					vty_out(vty, "  rd auto:vn:%d\n", +						value); + +				} else { + +					if (!prefix_rd2str(&hc->default_rd, buf, +							   BUFSIZ) +					    || !buf[0] || buf[BUFSIZ - 1]) { + +						vty_out(vty, +							"!Error: Can't convert rd\n"); +					} else { +						vty_out(vty, "  rd %s\n", buf); +					} +				} +			} +			if (hc->default_response_lifetime) { +				vty_out(vty, "  response-lifetime "); +				if (hc->default_response_lifetime != UINT32_MAX) +					vty_out(vty, "%d", +						hc->default_response_lifetime); +				else +					vty_out(vty, "infinite"); +				vty_out(vty, "\n"); +			} +			if (hc->default_rt_import_list +			    && hc->default_rt_export_list +			    && ecommunity_cmp(hc->default_rt_import_list, +					      hc->default_rt_export_list)) { +				char *b = ecommunity_ecom2str( +					hc->default_rt_import_list, +					ECOMMUNITY_FORMAT_ROUTE_MAP, +					ECOMMUNITY_ROUTE_TARGET); +				vty_out(vty, "  rt both %s\n", b); +				XFREE(MTYPE_ECOMMUNITY_STR, b); +			} else { +				if (hc->default_rt_import_list) { +					char *b = ecommunity_ecom2str( +						hc->default_rt_import_list, +						ECOMMUNITY_FORMAT_ROUTE_MAP, +						ECOMMUNITY_ROUTE_TARGET); +					vty_out(vty, "  rt import %s\n", b); +					XFREE(MTYPE_ECOMMUNITY_STR, b); +				} +				if (hc->default_rt_export_list) { +					char *b = ecommunity_ecom2str( +						hc->default_rt_export_list, +						ECOMMUNITY_FORMAT_ROUTE_MAP, +						ECOMMUNITY_ROUTE_TARGET); +					vty_out(vty, "  rt export %s\n", b); +					XFREE(MTYPE_ECOMMUNITY_STR, b); +				} +			} +			if (bgp->rfapi->rfp_methods.cfg_group_cb) +				write += (bgp->rfapi->rfp_methods.cfg_group_cb)( +					vty, bgp->rfapi->rfp, +					RFAPI_RFP_CFG_GROUP_DEFAULT, NULL, +					bgp->rfapi_cfg->default_rfp_cfg); +			vty_out(vty, "  exit-vnc\n"); +			vty_out(vty, "!\n"); +		} + +		for (ALL_LIST_ELEMENTS(hc->nve_groups_sequential, node, nnode, +				       rfg)) +			if (rfg->type == RFAPI_GROUP_CFG_NVE) { +				++write; +				vty_out(vty, " vnc nve-group %s\n", rfg->name); + +				if (rfg->vn_prefix.family && rfg->vn_node) { +					char buf[BUFSIZ]; +					buf[0] = buf[BUFSIZ - 1] = 0; + +					prefix2str(&rfg->vn_prefix, buf, +						   BUFSIZ); +					if (!buf[0] || buf[BUFSIZ - 1]) { +						vty_out(vty, +							"!Error: Can't convert prefix\n"); +					} else { +						vty_out(vty, "  prefix %s %s\n", +							"vn", buf); +					} +				} + +				if (rfg->un_prefix.family && rfg->un_node) { +					char buf[BUFSIZ]; +					buf[0] = buf[BUFSIZ - 1] = 0; +					prefix2str(&rfg->un_prefix, buf, +						   BUFSIZ); +					if (!buf[0] || buf[BUFSIZ - 1]) { +						vty_out(vty, +							"!Error: Can't convert prefix\n"); +					} else { +						vty_out(vty, "  prefix %s %s\n", +							"un", buf); +					} +				} + + +				if (rfg->rd.prefixlen) { +					char buf[BUFSIZ]; +					buf[0] = buf[BUFSIZ - 1] = 0; + +					if (AF_UNIX == rfg->rd.family) { + +						uint16_t value = 0; + +						value = ((rfg->rd.val[6] << 8) +							 & 0x0ff00) +							| (rfg->rd.val[7] +							   & 0x0ff); + +						vty_out(vty, +							"  rd auto:vn:%d\n", +							value); + +					} else { + +						if (!prefix_rd2str(&rfg->rd, +								   buf, BUFSIZ) +						    || !buf[0] +						    || buf[BUFSIZ - 1]) { + +							vty_out(vty, +								"!Error: Can't convert rd\n"); +						} else { +							vty_out(vty, +								"  rd %s\n", +								buf); +						} +					} +				} +				if (rfg->flags & RFAPI_RFG_RESPONSE_LIFETIME) { +					vty_out(vty, "  response-lifetime "); +					if (rfg->response_lifetime +					    != UINT32_MAX) +						vty_out(vty, "%d", +							rfg->response_lifetime); +					else +						vty_out(vty, "infinite"); +					vty_out(vty, "\n"); +				} + +				if (rfg->rt_import_list && rfg->rt_export_list +				    && ecommunity_cmp(rfg->rt_import_list, +						      rfg->rt_export_list)) { +					char *b = ecommunity_ecom2str( +						rfg->rt_import_list, +						ECOMMUNITY_FORMAT_ROUTE_MAP, +						ECOMMUNITY_ROUTE_TARGET); +					vty_out(vty, "  rt both %s\n", b); +					XFREE(MTYPE_ECOMMUNITY_STR, b); +				} else { +					if (rfg->rt_import_list) { +						char *b = ecommunity_ecom2str( +							rfg->rt_import_list, +							ECOMMUNITY_FORMAT_ROUTE_MAP, +							ECOMMUNITY_ROUTE_TARGET); +						vty_out(vty, "  rt import %s\n", +							b); +						XFREE(MTYPE_ECOMMUNITY_STR, b); +					} +					if (rfg->rt_export_list) { +						char *b = ecommunity_ecom2str( +							rfg->rt_export_list, +							ECOMMUNITY_FORMAT_ROUTE_MAP, +							ECOMMUNITY_ROUTE_TARGET); +						vty_out(vty, "  rt export %s\n", +							b); +						XFREE(MTYPE_ECOMMUNITY_STR, b); +					} +				} + +				/* +				 * route filtering: prefix-lists and route-maps +				 */ +				for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + +					const char *afistr = (afi == AFI_IP) +								     ? "ipv4" +								     : "ipv6"; + +					if (rfg->plist_export_bgp_name[afi]) { +						vty_out(vty, +							"  export bgp %s prefix-list %s\n", +							afistr, +							rfg->plist_export_bgp_name +								[afi]); +					} +					if (rfg->plist_export_zebra_name[afi]) { +						vty_out(vty, +							"  export zebra %s prefix-list %s\n", +							afistr, +							rfg->plist_export_zebra_name +								[afi]); +					} +					/* +					 * currently we only support redist +					 * plists for bgp-direct. +					 * If we later add plist support for +					 * redistributing other +					 * protocols, we'll need to loop over +					 * protocols here +					 */ +					if (rfg->plist_redist_name +						    [ZEBRA_ROUTE_BGP_DIRECT] +						    [afi]) { +						vty_out(vty, +							"  redistribute bgp-direct %s prefix-list %s\n", +							afistr, +							rfg->plist_redist_name +								[ZEBRA_ROUTE_BGP_DIRECT] +								[afi]); +					} +					if (rfg->plist_redist_name +						    [ZEBRA_ROUTE_BGP_DIRECT_EXT] +						    [afi]) { +						vty_out(vty, +							"  redistribute bgp-direct-to-nve-groups %s prefix-list %s\n", +							afistr, +							rfg->plist_redist_name +								[ZEBRA_ROUTE_BGP_DIRECT_EXT] +								[afi]); +					} +				} + +				if (rfg->routemap_export_bgp_name) { +					vty_out(vty, +						"  export bgp route-map %s\n", +						rfg->routemap_export_bgp_name); +				} +				if (rfg->routemap_export_zebra_name) { +					vty_out(vty, +						"  export zebra route-map %s\n", +						rfg->routemap_export_zebra_name); +				} +				if (rfg->routemap_redist_name +					    [ZEBRA_ROUTE_BGP_DIRECT]) { +					vty_out(vty, +						"  redistribute bgp-direct route-map %s\n", +						rfg->routemap_redist_name +							[ZEBRA_ROUTE_BGP_DIRECT]); +				} +				if (rfg->routemap_redist_name +					    [ZEBRA_ROUTE_BGP_DIRECT_EXT]) { +					vty_out(vty, +						"  redistribute bgp-direct-to-nve-groups route-map %s\n", +						rfg->routemap_redist_name +							[ZEBRA_ROUTE_BGP_DIRECT_EXT]); +				} +				if (bgp->rfapi->rfp_methods.cfg_group_cb) +					write += (bgp->rfapi->rfp_methods +							  .cfg_group_cb)( +						vty, bgp->rfapi->rfp, +						RFAPI_RFP_CFG_GROUP_NVE, +						rfg->name, rfg->rfp_cfg); +				vty_out(vty, "  exit-vnc\n"); +				vty_out(vty, "!\n"); +			} +	} /* have listen ports */ + +	/* +	 * route export to other protocols +	 */ +	if (VNC_EXPORT_BGP_GRP_ENABLED(hc)) { +		vty_out(vty, " vnc export bgp mode group-nve\n"); +	} else if (VNC_EXPORT_BGP_RH_ENABLED(hc)) { +		vty_out(vty, " vnc export bgp mode registering-nve\n"); +	} else if (VNC_EXPORT_BGP_CE_ENABLED(hc)) { +		vty_out(vty, " vnc export bgp mode ce\n"); +	} + +	if (VNC_EXPORT_ZEBRA_GRP_ENABLED(hc)) { +		vty_out(vty, " vnc export zebra mode group-nve\n"); +	} else if (VNC_EXPORT_ZEBRA_RH_ENABLED(hc)) { +		vty_out(vty, " vnc export zebra mode registering-nve\n"); +	} + +	if (hc->rfg_export_direct_bgp_l) { +		for (ALL_LIST_ELEMENTS(hc->rfg_export_direct_bgp_l, node, nnode, +				       rfgn)) { + +			vty_out(vty, " vnc export bgp group-nve group %s\n", +				rfgn->name); +		} +	} + +	if (hc->rfg_export_zebra_l) { +		for (ALL_LIST_ELEMENTS(hc->rfg_export_zebra_l, node, nnode, +				       rfgn)) { + +			vty_out(vty, " vnc export zebra group-nve group %s\n", +				rfgn->name); +		} +	} + + +	if (hc->rfg_redist_name) { +		vty_out(vty, " vnc redistribute nve-group %s\n", +			hc->rfg_redist_name); +	} +	if (hc->redist_lifetime) { +		vty_out(vty, " vnc redistribute lifetime %d\n", +			hc->redist_lifetime); +	} +	if (hc->resolve_nve_roo_local_admin +	    != BGP_VNC_CONFIG_RESOLVE_NVE_ROO_LOCAL_ADMIN_DEFAULT) { + +		vty_out(vty, +			" vnc redistribute resolve-nve roo-ec-local-admin %d\n", +			hc->resolve_nve_roo_local_admin); +	} + +	if (hc->redist_mode) /* ! default */ +	{ +		const char *s = ""; + +		switch (hc->redist_mode) { +		case VNC_REDIST_MODE_PLAIN: +			s = "plain"; +			break; +		case VNC_REDIST_MODE_RFG: +			s = "nve-group"; +			break; +		case VNC_REDIST_MODE_RESOLVE_NVE: +			s = "resolve-nve"; +			break; +		} +		if (s) { +			vty_out(vty, " vnc redistribute mode %s\n", s); +		} +	} + +	/* +	 * route filtering: prefix-lists and route-maps +	 */ +	for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + +		const char *afistr = (afi == AFI_IP) ? "ipv4" : "ipv6"; + +		if (hc->plist_export_bgp_name[afi]) { +			vty_out(vty, " vnc export bgp %s prefix-list %s\n", +				afistr, hc->plist_export_bgp_name[afi]); +		} +		if (hc->plist_export_zebra_name[afi]) { +			vty_out(vty, " vnc export zebra %s prefix-list %s\n", +				afistr, hc->plist_export_zebra_name[afi]); +		} +		if (hc->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT][afi]) { +			vty_out(vty, +				" vnc redistribute bgp-direct %s prefix-list %s\n", +				afistr, +				hc->plist_redist_name[ZEBRA_ROUTE_BGP_DIRECT] +						     [afi]); +		} +	} + +	if (hc->routemap_export_bgp_name) { +		vty_out(vty, " vnc export bgp route-map %s\n", +			hc->routemap_export_bgp_name); +	} +	if (hc->routemap_export_zebra_name) { +		vty_out(vty, " vnc export zebra route-map %s\n", +			hc->routemap_export_zebra_name); +	} +	if (hc->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]) { +		vty_out(vty, " vnc redistribute bgp-direct route-map %s\n", +			hc->routemap_redist_name[ZEBRA_ROUTE_BGP_DIRECT]); +	} + +	for (afi = AFI_IP; afi < AFI_MAX; ++afi) { +		for (type = 0; type < ZEBRA_ROUTE_MAX; ++type) { +			if (hc->redist[afi][type]) { +				if (type == ZEBRA_ROUTE_BGP_DIRECT_EXT +				    && hc->redist_bgp_exterior_view_name) { +					vty_out(vty, +						" vnc redistribute %s %s view %s\n", +						((afi == AFI_IP) ? "ipv4" +								 : "ipv6"), +						zebra_route_string(type), +						hc->redist_bgp_exterior_view_name); +				} else { +					vty_out(vty, +						" vnc redistribute %s %s\n", +						((afi == AFI_IP) ? "ipv4" +								 : "ipv6"), +						zebra_route_string(type)); +				} +			} +		} +	} +	return write;  } -void -bgp_rfapi_show_summary (struct bgp *bgp, struct vty *vty) +void bgp_rfapi_show_summary(struct bgp *bgp, struct vty *vty)  { -  struct rfapi_cfg *hc = bgp->rfapi_cfg; -  int afi, type, redist = 0; -  char tmp[40]; -  if (hc == NULL) -    return; - -  vty_out (vty, "%-39s %-19s %s\n", "VNC Advertise method:", -           (hc->flags & BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP -            ? "Encapsulation SAFI" : "Tunnel Encap attribute"), -           ((hc->flags & BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP) == (BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP & BGP_VNC_CONFIG_FLAGS_DEFAULT) ? "(default)" : "")); -  /* export */ -  vty_out (vty, "%-39s ", "Export from VNC:"); -  /* -   * route export to other protocols -   */ -  if (VNC_EXPORT_BGP_GRP_ENABLED (hc)) -    { -      redist++; -      vty_out (vty, "ToBGP Groups={"); -      if (hc->rfg_export_direct_bgp_l) -        { -          int cnt = 0; -          struct listnode *node, *nnode; -          struct rfapi_rfg_name *rfgn; -          for (ALL_LIST_ELEMENTS (hc->rfg_export_direct_bgp_l, -                                  node, nnode, rfgn)) -            { -              if (cnt++ != 0) -                vty_out (vty, ","); - -              vty_out (vty, "%s", rfgn->name); -            } -        } -      vty_out (vty, "}"); -    } -  else if (VNC_EXPORT_BGP_RH_ENABLED (hc)) -    { -      redist++; -      vty_out (vty, "ToBGP {Registering NVE}"); -      /* note filters, route-maps not shown */ -    } -  else if (VNC_EXPORT_BGP_CE_ENABLED (hc)) -    { -      redist++; -      vty_out (vty, "ToBGP {NVE connected router:%d}", -               hc->resolve_nve_roo_local_admin); -      /* note filters, route-maps not shown */ -    } - -  if (VNC_EXPORT_ZEBRA_GRP_ENABLED (hc)) -    { -      redist++; -      vty_out (vty, "%sToZebra Groups={", (redist == 1 ? "" : " ")); -      if (hc->rfg_export_direct_bgp_l) -        { -          int cnt = 0; -          struct listnode *node, *nnode; -          struct rfapi_rfg_name *rfgn; -          for (ALL_LIST_ELEMENTS (hc->rfg_export_zebra_l, node, nnode, rfgn)) -            { -              if (cnt++ != 0) -                vty_out (vty, ","); -              vty_out (vty, "%s", rfgn->name); -            } -        } -      vty_out (vty, "}"); -    } -  else if (VNC_EXPORT_ZEBRA_RH_ENABLED (hc)) -    { -      redist++; -      vty_out (vty, "%sToZebra {Registering NVE}", (redist == 1 ? "" : " ")); -      /* note filters, route-maps not shown */ -    } -  vty_out (vty, "%-19s %s\n", (redist ? "" : "Off"), -           (redist ? "" : "(default)")); - -  /* Redistribution */ -  redist = 0; -  vty_out (vty, "%-39s ", "Redistribution into VNC:"); -  for (afi = AFI_IP; afi < AFI_MAX; ++afi) -    { -      for (type = 0; type < ZEBRA_ROUTE_MAX; ++type) -        { -          if (hc->redist[afi][type]) -            { -              vty_out (vty, "{%s,%s} ", -                       ((afi == AFI_IP) ? "ipv4" : "ipv6"), -                       zebra_route_string (type)); -              redist++; -            } -        } -    } -  vty_out (vty, "%-19s %s\n", (redist ? "" : "Off"), -           (redist ? "" : "(default)")); - -  vty_out (vty, "%-39s %3u%-16s %s\n", "RFP Registration Hold-Down Factor:", -           hc->rfp_cfg.holddown_factor, "%", -           (hc->rfp_cfg.holddown_factor == RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR ? "(default)" : "")); -  vty_out (vty, "%-39s %-19s %s\n", "RFP Updated responses:", -           (hc->rfp_cfg.use_updated_response == 0 ? "Off" : "On"), -           (hc->rfp_cfg.use_updated_response == 0 ? "(default)" : "")); -  vty_out (vty, "%-39s %-19s %s\n", "RFP Removal responses:", -           (hc->rfp_cfg.use_removes == 0 ? "Off" : "On"), -           (hc->rfp_cfg.use_removes == 0 ? "(default)" : "")); -  vty_out (vty, "%-39s %-19s %s\n", "RFP Full table download:", -           (hc->rfp_cfg.download_type == -            RFAPI_RFP_DOWNLOAD_FULL ? "On" : "Off"), -           (hc->rfp_cfg.download_type == RFAPI_RFP_DOWNLOAD_PARTIAL ? "(default)" : "")); -  sprintf (tmp, "%u seconds", hc->rfp_cfg.ftd_advertisement_interval); -  vty_out (vty, "%-39s %-19s %s\n", "    Advertisement Interval:", tmp, -           (hc->rfp_cfg.ftd_advertisement_interval == RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL ? "(default)" : "")); -  vty_out (vty, "%-39s %d seconds\n", "Default RFP response lifetime:", -           hc->default_response_lifetime); -  vty_out (vty, "\n"); -  return; +	struct rfapi_cfg *hc = bgp->rfapi_cfg; +	int afi, type, redist = 0; +	char tmp[40]; +	if (hc == NULL) +		return; + +	vty_out(vty, "%-39s %-19s %s\n", "VNC Advertise method:", +		(hc->flags & BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP +			 ? "Encapsulation SAFI" +			 : "Tunnel Encap attribute"), +		((hc->flags & BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP) +				 == (BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP +				     & BGP_VNC_CONFIG_FLAGS_DEFAULT) +			 ? "(default)" +			 : "")); +	/* export */ +	vty_out(vty, "%-39s ", "Export from VNC:"); +	/* +	 * route export to other protocols +	 */ +	if (VNC_EXPORT_BGP_GRP_ENABLED(hc)) { +		redist++; +		vty_out(vty, "ToBGP Groups={"); +		if (hc->rfg_export_direct_bgp_l) { +			int cnt = 0; +			struct listnode *node, *nnode; +			struct rfapi_rfg_name *rfgn; +			for (ALL_LIST_ELEMENTS(hc->rfg_export_direct_bgp_l, +					       node, nnode, rfgn)) { +				if (cnt++ != 0) +					vty_out(vty, ","); + +				vty_out(vty, "%s", rfgn->name); +			} +		} +		vty_out(vty, "}"); +	} else if (VNC_EXPORT_BGP_RH_ENABLED(hc)) { +		redist++; +		vty_out(vty, "ToBGP {Registering NVE}"); +		/* note filters, route-maps not shown */ +	} else if (VNC_EXPORT_BGP_CE_ENABLED(hc)) { +		redist++; +		vty_out(vty, "ToBGP {NVE connected router:%d}", +			hc->resolve_nve_roo_local_admin); +		/* note filters, route-maps not shown */ +	} + +	if (VNC_EXPORT_ZEBRA_GRP_ENABLED(hc)) { +		redist++; +		vty_out(vty, "%sToZebra Groups={", (redist == 1 ? "" : " ")); +		if (hc->rfg_export_direct_bgp_l) { +			int cnt = 0; +			struct listnode *node, *nnode; +			struct rfapi_rfg_name *rfgn; +			for (ALL_LIST_ELEMENTS(hc->rfg_export_zebra_l, node, +					       nnode, rfgn)) { +				if (cnt++ != 0) +					vty_out(vty, ","); +				vty_out(vty, "%s", rfgn->name); +			} +		} +		vty_out(vty, "}"); +	} else if (VNC_EXPORT_ZEBRA_RH_ENABLED(hc)) { +		redist++; +		vty_out(vty, "%sToZebra {Registering NVE}", +			(redist == 1 ? "" : " ")); +		/* note filters, route-maps not shown */ +	} +	vty_out(vty, "%-19s %s\n", (redist ? "" : "Off"), +		(redist ? "" : "(default)")); + +	/* Redistribution */ +	redist = 0; +	vty_out(vty, "%-39s ", "Redistribution into VNC:"); +	for (afi = AFI_IP; afi < AFI_MAX; ++afi) { +		for (type = 0; type < ZEBRA_ROUTE_MAX; ++type) { +			if (hc->redist[afi][type]) { +				vty_out(vty, "{%s,%s} ", +					((afi == AFI_IP) ? "ipv4" : "ipv6"), +					zebra_route_string(type)); +				redist++; +			} +		} +	} +	vty_out(vty, "%-19s %s\n", (redist ? "" : "Off"), +		(redist ? "" : "(default)")); + +	vty_out(vty, "%-39s %3u%-16s %s\n", +		"RFP Registration Hold-Down Factor:", +		hc->rfp_cfg.holddown_factor, "%", +		(hc->rfp_cfg.holddown_factor +				 == RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR +			 ? "(default)" +			 : "")); +	vty_out(vty, "%-39s %-19s %s\n", "RFP Updated responses:", +		(hc->rfp_cfg.use_updated_response == 0 ? "Off" : "On"), +		(hc->rfp_cfg.use_updated_response == 0 ? "(default)" : "")); +	vty_out(vty, "%-39s %-19s %s\n", "RFP Removal responses:", +		(hc->rfp_cfg.use_removes == 0 ? "Off" : "On"), +		(hc->rfp_cfg.use_removes == 0 ? "(default)" : "")); +	vty_out(vty, "%-39s %-19s %s\n", "RFP Full table download:", +		(hc->rfp_cfg.download_type == RFAPI_RFP_DOWNLOAD_FULL ? "On" +								      : "Off"), +		(hc->rfp_cfg.download_type == RFAPI_RFP_DOWNLOAD_PARTIAL +			 ? "(default)" +			 : "")); +	sprintf(tmp, "%u seconds", hc->rfp_cfg.ftd_advertisement_interval); +	vty_out(vty, "%-39s %-19s %s\n", "    Advertisement Interval:", tmp, +		(hc->rfp_cfg.ftd_advertisement_interval +				 == RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL +			 ? "(default)" +			 : "")); +	vty_out(vty, "%-39s %d seconds\n", "Default RFP response lifetime:", +		hc->default_response_lifetime); +	vty_out(vty, "\n"); +	return;  } -struct rfapi_cfg * -bgp_rfapi_get_config (struct bgp *bgp) +struct rfapi_cfg *bgp_rfapi_get_config(struct bgp *bgp)  { -  struct rfapi_cfg *hc = NULL; -  if (bgp == NULL) -    bgp = bgp_get_default (); -  if (bgp != NULL) -    hc = bgp->rfapi_cfg; -  return hc; +	struct rfapi_cfg *hc = NULL; +	if (bgp == NULL) +		bgp = bgp_get_default(); +	if (bgp != NULL) +		hc = bgp->rfapi_cfg; +	return hc;  }  #endif /* ENABLE_BGP_VNC */ diff --git a/bgpd/rfapi/bgp_rfapi_cfg.h b/bgpd/rfapi/bgp_rfapi_cfg.h index 44abbe2223..d99aefa60d 100644 --- a/bgpd/rfapi/bgp_rfapi_cfg.h +++ b/bgpd/rfapi/bgp_rfapi_cfg.h @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2009-2016, LabN Consulting, L.L.C.   * @@ -27,200 +27,195 @@  #if ENABLE_BGP_VNC  #include "rfapi.h" -struct rfapi_l2_group_cfg -{ -  char *name; -  uint32_t logical_net_id; -  struct list *labels;          /* list of uint32_t */ -  struct ecommunity *rt_import_list; -  struct ecommunity *rt_export_list; -  void *rfp_cfg;                /* rfp owned group config */ +struct rfapi_l2_group_cfg { +	char *name; +	uint32_t logical_net_id; +	struct list *labels; /* list of uint32_t */ +	struct ecommunity *rt_import_list; +	struct ecommunity *rt_export_list; +	void *rfp_cfg; /* rfp owned group config */ -  QOBJ_FIELDS +	QOBJ_FIELDS  };  DECLARE_QOBJ_TYPE(rfapi_l2_group_cfg) -typedef enum -{ -  RFAPI_GROUP_CFG_NVE = 1, -  RFAPI_GROUP_CFG_VRF, -  RFAPI_GROUP_CFG_L2, -  RFAPI_GROUP_CFG_MAX +typedef enum { +	RFAPI_GROUP_CFG_NVE = 1, +	RFAPI_GROUP_CFG_VRF, +	RFAPI_GROUP_CFG_L2, +	RFAPI_GROUP_CFG_MAX  } rfapi_group_cfg_type_t; -struct rfapi_nve_group_cfg -{ -  struct route_node *vn_node;   /* backref */ -  struct route_node *un_node;   /* backref */ +struct rfapi_nve_group_cfg { +	struct route_node *vn_node; /* backref */ +	struct route_node *un_node; /* backref */ -  rfapi_group_cfg_type_t type;  /* NVE|VPN */ -  char *name;                   /* unique by type! */ -  struct prefix vn_prefix; -  struct prefix un_prefix; +	rfapi_group_cfg_type_t type; /* NVE|VPN */ +	char *name;		     /* unique by type! */ +	struct prefix vn_prefix; +	struct prefix un_prefix; -  struct prefix_rd rd; -  uint8_t l2rd;                 /* 0 = VN addr LSB */ -  uint32_t response_lifetime; -  uint32_t flags; +	struct prefix_rd rd; +	uint8_t l2rd; /* 0 = VN addr LSB */ +	uint32_t response_lifetime; +	uint32_t flags;  #define RFAPI_RFG_RESPONSE_LIFETIME	0x01 /* bits */  #define RFAPI_RFG_L2RD			0x02  #define RFAPI_RFG_VPN_NH_SELF		0x04 -  struct ecommunity *rt_import_list; -  struct ecommunity *rt_export_list; -  struct rfapi_import_table *rfapi_import_table; - -  void *rfp_cfg;                /* rfp owned group config */ -  /* -   * List of NVE descriptors that are assigned to this NVE group -   * -   * Currently (Mar 2010) this list is used only by the route -   * export code to generate per-NVE nexthops for each route. -   * -   * The nve descriptors listed here have pointers back to -   * this nve group config structure to enable them to delete -   * their own list entries when they are closed. Consequently, -   * if an instance of this nve group config structure is deleted, -   * we must first set the nve descriptor references to it to NULL. -   */ -  struct list *nves; - -  /* -   * Route filtering -   * -   * Prefix lists are segregated by afi (part of the base plist code) -   * Route-maps are not segregated -   */ -  char *plist_export_bgp_name[AFI_MAX]; -  struct prefix_list *plist_export_bgp[AFI_MAX]; - -  char *plist_export_zebra_name[AFI_MAX]; -  struct prefix_list *plist_export_zebra[AFI_MAX]; - -  char *plist_redist_name[ZEBRA_ROUTE_MAX][AFI_MAX]; -  struct prefix_list *plist_redist[ZEBRA_ROUTE_MAX][AFI_MAX]; - -  char *routemap_export_bgp_name; -  struct route_map *routemap_export_bgp; - -  char *routemap_export_zebra_name; -  struct route_map *routemap_export_zebra; - -  char *routemap_redist_name[ZEBRA_ROUTE_MAX]; -  struct route_map *routemap_redist[ZEBRA_ROUTE_MAX]; - -  /* for VRF type groups */ -  uint32_t                label; -  struct rfapi_descriptor *rfd; -  QOBJ_FIELDS +	struct ecommunity *rt_import_list; +	struct ecommunity *rt_export_list; +	struct rfapi_import_table *rfapi_import_table; + +	void *rfp_cfg; /* rfp owned group config */ +	/* +	 * List of NVE descriptors that are assigned to this NVE group +	 * +	 * Currently (Mar 2010) this list is used only by the route +	 * export code to generate per-NVE nexthops for each route. +	 * +	 * The nve descriptors listed here have pointers back to +	 * this nve group config structure to enable them to delete +	 * their own list entries when they are closed. Consequently, +	 * if an instance of this nve group config structure is deleted, +	 * we must first set the nve descriptor references to it to NULL. +	 */ +	struct list *nves; + +	/* +	 * Route filtering +	 * +	 * Prefix lists are segregated by afi (part of the base plist code) +	 * Route-maps are not segregated +	 */ +	char *plist_export_bgp_name[AFI_MAX]; +	struct prefix_list *plist_export_bgp[AFI_MAX]; + +	char *plist_export_zebra_name[AFI_MAX]; +	struct prefix_list *plist_export_zebra[AFI_MAX]; + +	char *plist_redist_name[ZEBRA_ROUTE_MAX][AFI_MAX]; +	struct prefix_list *plist_redist[ZEBRA_ROUTE_MAX][AFI_MAX]; + +	char *routemap_export_bgp_name; +	struct route_map *routemap_export_bgp; + +	char *routemap_export_zebra_name; +	struct route_map *routemap_export_zebra; + +	char *routemap_redist_name[ZEBRA_ROUTE_MAX]; +	struct route_map *routemap_redist[ZEBRA_ROUTE_MAX]; + +	/* for VRF type groups */ +	uint32_t label; +	struct rfapi_descriptor *rfd; +	QOBJ_FIELDS  };  DECLARE_QOBJ_TYPE(rfapi_nve_group_cfg) -struct rfapi_rfg_name -{ -  struct rfapi_nve_group_cfg *rfg; -  char *name; +struct rfapi_rfg_name { +	struct rfapi_nve_group_cfg *rfg; +	char *name;  }; -typedef enum -{ -  VNC_REDIST_MODE_PLAIN = 0,    /* 0 = default */ -  VNC_REDIST_MODE_RFG, -  VNC_REDIST_MODE_RESOLVE_NVE +typedef enum { +	VNC_REDIST_MODE_PLAIN = 0, /* 0 = default */ +	VNC_REDIST_MODE_RFG, +	VNC_REDIST_MODE_RESOLVE_NVE  } vnc_redist_mode_t; -struct rfapi_cfg -{ -  struct prefix_rd default_rd; -  uint8_t default_l2rd; -  struct ecommunity *default_rt_import_list; -  struct ecommunity *default_rt_export_list; -  uint32_t default_response_lifetime; +struct rfapi_cfg { +	struct prefix_rd default_rd; +	uint8_t default_l2rd; +	struct ecommunity *default_rt_import_list; +	struct ecommunity *default_rt_export_list; +	uint32_t default_response_lifetime;  #define BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT 3600 -  void *default_rfp_cfg;        /* rfp owned group config */ - -  struct list *l2_groups;       /* rfapi_l2_group_cfg list */ -  /* three views into the same collection of rfapi_nve_group_cfg */ -  struct list *nve_groups_sequential; -  struct route_table nve_groups_vn[AFI_MAX]; -  struct route_table nve_groups_un[AFI_MAX]; - -  /* -   * For Single VRF export to ordinary routing protocols. This is -   * the nve-group that the ordinary protocols belong to. We use it -   * to set the RD when sending unicast Zebra routes to VNC -   */ -  uint8_t redist[AFI_MAX][ZEBRA_ROUTE_MAX]; -  uint32_t redist_lifetime; -  vnc_redist_mode_t redist_mode; - -  /* -   * view name of BGP unicast instance that holds -   * exterior routes  -   */ -  char *redist_bgp_exterior_view_name; -  struct bgp *redist_bgp_exterior_view; - -  /*  -   * nve group for redistribution of routes from zebra to VNC -   * (which is probably not useful for production networks) -   */ -  char *rfg_redist_name; -  struct rfapi_nve_group_cfg *rfg_redist; - -  /* -   * List of NVE groups on whose behalf we will export VNC -   * routes to zebra. ((NB: it's actually a list of <struct rfapi_rfg_name>) -   * This list is used when BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS is -   * BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP -   */ -  struct list *rfg_export_zebra_l; - -  /* -   * List of NVE groups on whose behalf we will export VNC -   * routes directly to the bgp unicast RIB. (NB: it's actually -   * a list of <struct rfapi_rfg_name>) -   * This list is used when BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS is -   * BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP -   */ -  struct list *rfg_export_direct_bgp_l; - -  /* -   * Exported Route filtering -   * -   * Prefix lists are segregated by afi (part of the base plist code) -   * Route-maps are not segregated -   */ -  char *plist_export_bgp_name[AFI_MAX]; -  struct prefix_list *plist_export_bgp[AFI_MAX]; - -  char *plist_export_zebra_name[AFI_MAX]; -  struct prefix_list *plist_export_zebra[AFI_MAX]; - -  char *routemap_export_bgp_name; -  struct route_map *routemap_export_bgp; - -  char *routemap_export_zebra_name; -  struct route_map *routemap_export_zebra; - -  /* -   * Redistributed route filtering (routes from other -   * protocols into VNC) -   */ -  char *plist_redist_name[ZEBRA_ROUTE_MAX][AFI_MAX]; -  struct prefix_list *plist_redist[ZEBRA_ROUTE_MAX][AFI_MAX]; - -  char *routemap_redist_name[ZEBRA_ROUTE_MAX]; -  struct route_map *routemap_redist[ZEBRA_ROUTE_MAX]; - -  /*  -   * For importing bgp unicast routes to VNC, we encode the CE -   * (route nexthop) in a Route Origin extended community. The -   * local part (16-bit) is user-configurable. -   */ -  uint16_t resolve_nve_roo_local_admin; +	void *default_rfp_cfg; /* rfp owned group config */ + +	struct list *l2_groups; /* rfapi_l2_group_cfg list */ +	/* three views into the same collection of rfapi_nve_group_cfg */ +	struct list *nve_groups_sequential; +	struct route_table nve_groups_vn[AFI_MAX]; +	struct route_table nve_groups_un[AFI_MAX]; + +	/* +	 * For Single VRF export to ordinary routing protocols. This is +	 * the nve-group that the ordinary protocols belong to. We use it +	 * to set the RD when sending unicast Zebra routes to VNC +	 */ +	uint8_t redist[AFI_MAX][ZEBRA_ROUTE_MAX]; +	uint32_t redist_lifetime; +	vnc_redist_mode_t redist_mode; + +	/* +	 * view name of BGP unicast instance that holds +	 * exterior routes +	 */ +	char *redist_bgp_exterior_view_name; +	struct bgp *redist_bgp_exterior_view; + +	/* +	 * nve group for redistribution of routes from zebra to VNC +	 * (which is probably not useful for production networks) +	 */ +	char *rfg_redist_name; +	struct rfapi_nve_group_cfg *rfg_redist; + +	/* +	 * List of NVE groups on whose behalf we will export VNC +	 * routes to zebra. ((NB: it's actually a list of <struct +	 * rfapi_rfg_name>) +	 * This list is used when BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS is +	 * BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP +	 */ +	struct list *rfg_export_zebra_l; + +	/* +	 * List of NVE groups on whose behalf we will export VNC +	 * routes directly to the bgp unicast RIB. (NB: it's actually +	 * a list of <struct rfapi_rfg_name>) +	 * This list is used when BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS is +	 * BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP +	 */ +	struct list *rfg_export_direct_bgp_l; + +	/* +	 * Exported Route filtering +	 * +	 * Prefix lists are segregated by afi (part of the base plist code) +	 * Route-maps are not segregated +	 */ +	char *plist_export_bgp_name[AFI_MAX]; +	struct prefix_list *plist_export_bgp[AFI_MAX]; + +	char *plist_export_zebra_name[AFI_MAX]; +	struct prefix_list *plist_export_zebra[AFI_MAX]; + +	char *routemap_export_bgp_name; +	struct route_map *routemap_export_bgp; + +	char *routemap_export_zebra_name; +	struct route_map *routemap_export_zebra; + +	/* +	 * Redistributed route filtering (routes from other +	 * protocols into VNC) +	 */ +	char *plist_redist_name[ZEBRA_ROUTE_MAX][AFI_MAX]; +	struct prefix_list *plist_redist[ZEBRA_ROUTE_MAX][AFI_MAX]; + +	char *routemap_redist_name[ZEBRA_ROUTE_MAX]; +	struct route_map *routemap_redist[ZEBRA_ROUTE_MAX]; + +	/* +	 * For importing bgp unicast routes to VNC, we encode the CE +	 * (route nexthop) in a Route Origin extended community. The +	 * local part (16-bit) is user-configurable. +	 */ +	uint16_t resolve_nve_roo_local_admin;  #define BGP_VNC_CONFIG_RESOLVE_NVE_ROO_LOCAL_ADMIN_DEFAULT 5226 -  uint32_t flags; +	uint32_t flags;  #define BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP	0x00000001  #define BGP_VNC_CONFIG_CALLBACK_DISABLE		0x00000002  #define BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE	0x00000004 @@ -244,98 +239,76 @@ struct rfapi_cfg  /* Filter querying NVE's registrations from responses */  /* Default to updated-responses off */  /* Default to removal-responses off */ -#define BGP_VNC_CONFIG_FLAGS_DEFAULT		 \ -    (BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP	|\ -     BGP_VNC_CONFIG_CALLBACK_DISABLE		|\ -     BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE) +#define BGP_VNC_CONFIG_FLAGS_DEFAULT                                           \ +	(BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP | BGP_VNC_CONFIG_CALLBACK_DISABLE \ +	 | BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE) -  struct rfapi_rfp_cfg rfp_cfg; /* rfp related configuration  */ +	struct rfapi_rfp_cfg rfp_cfg; /* rfp related configuration  */  }; -#define VNC_EXPORT_ZEBRA_GRP_ENABLED(hc)			\ -    (((hc)->flags & BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS) ==	\ -    BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP) +#define VNC_EXPORT_ZEBRA_GRP_ENABLED(hc)                                       \ +	(((hc)->flags & BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS)                 \ +	 == BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_GRP) -#define VNC_EXPORT_ZEBRA_RH_ENABLED(hc)				\ -    (((hc)->flags & BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS) ==	\ -    BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_RH) +#define VNC_EXPORT_ZEBRA_RH_ENABLED(hc)                                        \ +	(((hc)->flags & BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_BITS)                 \ +	 == BGP_VNC_CONFIG_EXPORT_ZEBRA_MODE_RH) -#define VNC_EXPORT_BGP_GRP_ENABLED(hc)				\ -    (((hc)->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) ==	\ -    BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP) +#define VNC_EXPORT_BGP_GRP_ENABLED(hc)                                         \ +	(((hc)->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS)                   \ +	 == BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP) -#define VNC_EXPORT_BGP_RH_ENABLED(hc)				\ -    (((hc)->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) ==	\ -    BGP_VNC_CONFIG_EXPORT_BGP_MODE_RH) +#define VNC_EXPORT_BGP_RH_ENABLED(hc)                                          \ +	(((hc)->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS)                   \ +	 == BGP_VNC_CONFIG_EXPORT_BGP_MODE_RH) -#define VNC_EXPORT_BGP_CE_ENABLED(hc)				\ -    (((hc)->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) ==	\ -    BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE) +#define VNC_EXPORT_BGP_CE_ENABLED(hc)                                          \ +	(((hc)->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS)                   \ +	 == BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE) -void -bgp_rfapi_cfg_init (void); +void bgp_rfapi_cfg_init(void); -struct rfapi_cfg * -bgp_rfapi_cfg_new (struct rfapi_rfp_cfg *cfg); +struct rfapi_cfg *bgp_rfapi_cfg_new(struct rfapi_rfp_cfg *cfg); -void -bgp_rfapi_cfg_destroy (struct bgp *bgp, struct rfapi_cfg *h); +void bgp_rfapi_cfg_destroy(struct bgp *bgp, struct rfapi_cfg *h); -int -bgp_rfapi_cfg_write (struct vty *vty, struct bgp *bgp); +int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp); -extern int -bgp_rfapi_is_vnc_configured (struct bgp *bgp); +extern int bgp_rfapi_is_vnc_configured(struct bgp *bgp); -extern void -nve_group_to_nve_list ( -  struct rfapi_nve_group_cfg	*rfg, -  struct list			**nves, -  uint8_t			family);        /* AF_INET, AF_INET6 */ +extern void nve_group_to_nve_list(struct rfapi_nve_group_cfg *rfg, +				  struct list **nves, +				  uint8_t family); /* AF_INET, AF_INET6 */ -struct rfapi_nve_group_cfg * -bgp_rfapi_cfg_match_group ( -  struct rfapi_cfg	*hc, -  struct prefix		*vn, -  struct prefix		*un); +struct rfapi_nve_group_cfg *bgp_rfapi_cfg_match_group(struct rfapi_cfg *hc, +						      struct prefix *vn, +						      struct prefix *un);  struct rfapi_nve_group_cfg * -bgp_rfapi_cfg_match_byname ( -  struct bgp *bgp, -  const char *name, -  rfapi_group_cfg_type_t type);  /* _MAX = any */ +bgp_rfapi_cfg_match_byname(struct bgp *bgp, const char *name, +			   rfapi_group_cfg_type_t type); /* _MAX = any */ -extern void -vnc_prefix_list_update (struct bgp *bgp); +extern void vnc_prefix_list_update(struct bgp *bgp); -extern void -vnc_routemap_update (struct bgp *bgp, const char *unused); +extern void vnc_routemap_update(struct bgp *bgp, const char *unused); -extern void -bgp_rfapi_show_summary (struct bgp *bgp, struct vty *vty); +extern void bgp_rfapi_show_summary(struct bgp *bgp, struct vty *vty); -extern struct rfapi_cfg * -bgp_rfapi_get_config (struct bgp *bgp); +extern struct rfapi_cfg *bgp_rfapi_get_config(struct bgp *bgp);  extern struct rfapi_l2_group_cfg * -bgp_rfapi_get_group_by_lni_label ( -  struct bgp	*bgp, -  uint32_t	logical_net_id, -  uint32_t	label); +bgp_rfapi_get_group_by_lni_label(struct bgp *bgp, uint32_t logical_net_id, +				 uint32_t label);  extern struct ecommunity * -bgp_rfapi_get_ecommunity_by_lni_label ( -  struct bgp	*bgp, -  uint32_t	is_import, -  uint32_t	logical_net_id, -  uint32_t	label);	/* note, 20bit label! */ +bgp_rfapi_get_ecommunity_by_lni_label(struct bgp *bgp, uint32_t is_import, +				      uint32_t logical_net_id, +				      uint32_t label); /* note, 20bit label! */  extern struct list * -bgp_rfapi_get_labellist_by_lni_label ( -  struct bgp	*bgp, -  uint32_t	logical_net_id, -  uint32_t	label);	/* note, 20bit label! */ +bgp_rfapi_get_labellist_by_lni_label(struct bgp *bgp, uint32_t logical_net_id, +				     uint32_t label); /* note, 20bit label! */  #endif /* ENABLE_BGP_VNC */ diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c index a959b9827c..3a2a608a7c 100644 --- a/bgpd/rfapi/rfapi.c +++ b/bgpd/rfapi/rfapi.c @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2009-2016, LabN Consulting, L.L.C.   * @@ -65,38 +65,36 @@  #include <execinfo.h>  #endif /* HAVE_GLIBC_BACKTRACE */ -struct ethaddr rfapi_ethaddr0 = { {0} }; +struct ethaddr rfapi_ethaddr0 = {{0}};  #define DEBUG_RFAPI_STR "RF API debugging/testing command\n" -const char * -rfapi_error_str (int code) +const char *rfapi_error_str(int code)  { -  switch (code) -    { -    case 0: -      return "Success"; -    case ENXIO: -      return "BGP or VNC not configured"; -    case ENOENT: -      return "No match"; -    case EEXIST: -      return "Handle already open"; -    case ENOMSG: -      return "Incomplete configuration"; -    case EAFNOSUPPORT: -      return "Invalid address family"; -    case EDEADLK: -      return "Called from within a callback procedure"; -    case EBADF: -      return "Invalid handle"; -    case EINVAL: -      return "Invalid argument"; -    case ESTALE: -      return "Stale descriptor"; -    default: -      return "Unknown error"; -    } +	switch (code) { +	case 0: +		return "Success"; +	case ENXIO: +		return "BGP or VNC not configured"; +	case ENOENT: +		return "No match"; +	case EEXIST: +		return "Handle already open"; +	case ENOMSG: +		return "Incomplete configuration"; +	case EAFNOSUPPORT: +		return "Invalid address family"; +	case EDEADLK: +		return "Called from within a callback procedure"; +	case EBADF: +		return "Invalid handle"; +	case EINVAL: +		return "Invalid argument"; +	case ESTALE: +		return "Stale descriptor"; +	default: +		return "Unknown error"; +	}  }  /*------------------------------------------ @@ -106,20 +104,19 @@ rfapi_error_str (int code)   *    rfp_start_val     value returned by rfp_start or   *                      NULL (=use default instance)   * - * input:  + * input:   *    None   *   * output:   *   * return value: The bgp instance default lifetime for a response.   --------------------------------------------*/ -int -rfapi_get_response_lifetime_default (void *rfp_start_val) +int rfapi_get_response_lifetime_default(void *rfp_start_val)  { -  struct bgp *bgp = rfapi_bgp_lookup_by_rfp (rfp_start_val); -  if (bgp) -    return bgp->rfapi_cfg->default_response_lifetime; -  return BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT; +	struct bgp *bgp = rfapi_bgp_lookup_by_rfp(rfp_start_val); +	if (bgp) +		return bgp->rfapi_cfg->default_response_lifetime; +	return BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT;  }  /*------------------------------------------ @@ -127,7 +124,7 @@ rfapi_get_response_lifetime_default (void *rfp_start_val)   *   * Returns if VNC (BGP VPN messaging /VPN & encap SAFIs) are configured   * - * input:  + * input:   *    rfp_start_val     value returned by rfp_start or   *                      NULL (=use default instance)   * @@ -137,11 +134,10 @@ rfapi_get_response_lifetime_default (void *rfp_start_val)   *	0		Success   *	ENXIO		VNC not configured   --------------------------------------------*/ -int -rfapi_is_vnc_configured (void *rfp_start_val) +int rfapi_is_vnc_configured(void *rfp_start_val)  { -  struct bgp *bgp = rfapi_bgp_lookup_by_rfp (rfp_start_val); -  return bgp_rfapi_is_vnc_configured (bgp); +	struct bgp *bgp = rfapi_bgp_lookup_by_rfp(rfp_start_val); +	return bgp_rfapi_is_vnc_configured(bgp);  } @@ -150,19 +146,18 @@ rfapi_is_vnc_configured (void *rfp_start_val)   *   * Get the virtual network address used by an NVE based on it's RFD   * - * input:  + * input:   *    rfd: rfapi descriptor returned by rfapi_open or rfapi_create_generic   *   * output:   * - * return value:  + * return value:   *	vn		NVE virtual network address   *------------------------------------------*/ -struct rfapi_ip_addr * -rfapi_get_vn_addr (void *rfd) +struct rfapi_ip_addr *rfapi_get_vn_addr(void *rfd)  { -  struct rfapi_descriptor *rrfd = (struct rfapi_descriptor *) rfd; -  return &rrfd->vn_addr; +	struct rfapi_descriptor *rrfd = (struct rfapi_descriptor *)rfd; +	return &rrfd->vn_addr;  }  /*------------------------------------------ @@ -170,505 +165,459 @@ rfapi_get_vn_addr (void *rfd)   *   * Get the underlay network address used by an NVE based on it's RFD   * - * input:  + * input:   *    rfd: rfapi descriptor returned by rfapi_open or rfapi_create_generic   *   * output:   * - * return value:  + * return value:   *	un		NVE underlay network address   *------------------------------------------*/ -struct rfapi_ip_addr * -rfapi_get_un_addr (void *rfd) +struct rfapi_ip_addr *rfapi_get_un_addr(void *rfd)  { -  struct rfapi_descriptor *rrfd = (struct rfapi_descriptor *) rfd; -  return &rrfd->un_addr; +	struct rfapi_descriptor *rrfd = (struct rfapi_descriptor *)rfd; +	return &rrfd->un_addr;  } -int -rfapi_ip_addr_cmp (struct rfapi_ip_addr *a1, struct rfapi_ip_addr *a2) +int rfapi_ip_addr_cmp(struct rfapi_ip_addr *a1, struct rfapi_ip_addr *a2)  { -  if (a1->addr_family != a2->addr_family) -    return a1->addr_family - a2->addr_family; +	if (a1->addr_family != a2->addr_family) +		return a1->addr_family - a2->addr_family; -  if (a1->addr_family == AF_INET) -    { -      return IPV4_ADDR_CMP (&a1->addr.v4, &a2->addr.v4); -    } +	if (a1->addr_family == AF_INET) { +		return IPV4_ADDR_CMP(&a1->addr.v4, &a2->addr.v4); +	} -  if (a1->addr_family == AF_INET6) -    { -      return IPV6_ADDR_CMP (&a1->addr.v6, &a2->addr.v6); -    } +	if (a1->addr_family == AF_INET6) { +		return IPV6_ADDR_CMP(&a1->addr.v6, &a2->addr.v6); +	} -  assert (1); -  /* NOTREACHED */ -  return 1; +	assert(1); +	/* NOTREACHED */ +	return 1;  } -static int -rfapi_find_node ( -  struct bgp		*bgp, -  struct rfapi_ip_addr	*vn_addr, -  struct rfapi_ip_addr	*un_addr, -  struct route_node	**node) +static int rfapi_find_node(struct bgp *bgp, struct rfapi_ip_addr *vn_addr, +			   struct rfapi_ip_addr *un_addr, +			   struct route_node **node)  { -  struct rfapi *h; -  struct prefix p; -  struct route_node *rn; -  int rc; -  int afi; +	struct rfapi *h; +	struct prefix p; +	struct route_node *rn; +	int rc; +	int afi; -  if (!bgp) -    { -      return ENXIO; -    } +	if (!bgp) { +		return ENXIO; +	} -  h = bgp->rfapi; -  if (!h) -    { -      return ENXIO; -    } +	h = bgp->rfapi; +	if (!h) { +		return ENXIO; +	} -  afi = family2afi (un_addr->addr_family); -  if (!afi) -    { -      return EAFNOSUPPORT; -    } +	afi = family2afi(un_addr->addr_family); +	if (!afi) { +		return EAFNOSUPPORT; +	} -  if ((rc = rfapiRaddr2Qprefix (un_addr, &p))) -    return rc; +	if ((rc = rfapiRaddr2Qprefix(un_addr, &p))) +		return rc; -  rn = route_node_lookup (&h->un[afi], &p); +	rn = route_node_lookup(&h->un[afi], &p); -  if (!rn) -    return ENOENT; +	if (!rn) +		return ENOENT; -  route_unlock_node (rn); +	route_unlock_node(rn); -  *node = rn; +	*node = rn; -  return 0; +	return 0;  } -int -rfapi_find_rfd ( -  struct bgp			*bgp, -  struct rfapi_ip_addr		*vn_addr, -  struct rfapi_ip_addr		*un_addr, -  struct rfapi_descriptor	**rfd) +int rfapi_find_rfd(struct bgp *bgp, struct rfapi_ip_addr *vn_addr, +		   struct rfapi_ip_addr *un_addr, struct rfapi_descriptor **rfd)  { -  struct route_node *rn; -  int rc; +	struct route_node *rn; +	int rc; -  rc = rfapi_find_node (bgp, vn_addr, un_addr, &rn); +	rc = rfapi_find_node(bgp, vn_addr, un_addr, &rn); -  if (rc) -    return rc; +	if (rc) +		return rc; -  for (*rfd = (struct rfapi_descriptor *) (rn->info); *rfd; -       *rfd = (*rfd)->next) -    { -      if (!rfapi_ip_addr_cmp (&(*rfd)->vn_addr, vn_addr)) -        break; -    } +	for (*rfd = (struct rfapi_descriptor *)(rn->info); *rfd; +	     *rfd = (*rfd)->next) { +		if (!rfapi_ip_addr_cmp(&(*rfd)->vn_addr, vn_addr)) +			break; +	} -  if (!*rfd) -    return ENOENT; +	if (!*rfd) +		return ENOENT; -  return 0; +	return 0;  }  /*------------------------------------------   * rfapi_find_handle   * - * input:  + * input:   *	un		underlay network address   *	vn		virtual network address   *   * output:   *	pHandle		pointer to location to store handle   * - * return value:  + * return value:   *	0		Success   *	ENOENT		no matching handle   *	ENXIO		BGP or VNC not configured   *------------------------------------------*/ -static int -rfapi_find_handle ( -  struct bgp		*bgp, -  struct rfapi_ip_addr	*vn_addr, -  struct rfapi_ip_addr	*un_addr, -  rfapi_handle		*handle) +static int rfapi_find_handle(struct bgp *bgp, struct rfapi_ip_addr *vn_addr, +			     struct rfapi_ip_addr *un_addr, +			     rfapi_handle *handle)  { -  struct rfapi_descriptor **rfd; +	struct rfapi_descriptor **rfd; -  rfd = (struct rfapi_descriptor **) handle; +	rfd = (struct rfapi_descriptor **)handle; -  return rfapi_find_rfd (bgp, vn_addr, un_addr, rfd); +	return rfapi_find_rfd(bgp, vn_addr, un_addr, rfd);  } -static int -rfapi_find_handle_vty ( -  struct vty		*vty, -  struct rfapi_ip_addr	*vn_addr, -  struct rfapi_ip_addr	*un_addr, -  rfapi_handle		*handle) +static int rfapi_find_handle_vty(struct vty *vty, struct rfapi_ip_addr *vn_addr, +				 struct rfapi_ip_addr *un_addr, +				 rfapi_handle *handle)  { -  struct bgp *bgp; -  struct rfapi_descriptor **rfd; +	struct bgp *bgp; +	struct rfapi_descriptor **rfd; -  bgp = bgp_get_default ();     /* assume 1 instance for now */ +	bgp = bgp_get_default(); /* assume 1 instance for now */ -  rfd = (struct rfapi_descriptor **) handle; +	rfd = (struct rfapi_descriptor **)handle; -  return rfapi_find_rfd (bgp, vn_addr, un_addr, rfd); +	return rfapi_find_rfd(bgp, vn_addr, un_addr, rfd);  } -static int -is_valid_rfd (struct rfapi_descriptor *rfd) +static int is_valid_rfd(struct rfapi_descriptor *rfd)  { -  rfapi_handle hh; +	rfapi_handle hh; -  if (!rfd || rfd->bgp == NULL) -    return 0; +	if (!rfd || rfd->bgp == NULL) +		return 0; -  if (CHECK_FLAG(rfd->flags, RFAPI_HD_FLAG_IS_VRF)) /* assume VRF/internal are valid */ -    return 1; +	if (CHECK_FLAG( +		    rfd->flags, +		    RFAPI_HD_FLAG_IS_VRF)) /* assume VRF/internal are valid */ +		return 1; -  if (rfapi_find_handle (rfd->bgp, &rfd->vn_addr, &rfd->un_addr, &hh)) -    return 0; +	if (rfapi_find_handle(rfd->bgp, &rfd->vn_addr, &rfd->un_addr, &hh)) +		return 0; -  if (rfd != hh) -    return 0; +	if (rfd != hh) +		return 0; -  return 1; +	return 1;  }  /*   * check status of descriptor   */ -int -rfapi_check (void *handle) +int rfapi_check(void *handle)  { -  struct rfapi_descriptor *rfd = (struct rfapi_descriptor *) handle; -  rfapi_handle hh; -  int rc; +	struct rfapi_descriptor *rfd = (struct rfapi_descriptor *)handle; +	rfapi_handle hh; +	int rc; -  if (!rfd || rfd->bgp == NULL) -    return EINVAL; +	if (!rfd || rfd->bgp == NULL) +		return EINVAL; -  if (CHECK_FLAG(rfd->flags, RFAPI_HD_FLAG_IS_VRF)) /* assume VRF/internal are valid */ -    return 0; +	if (CHECK_FLAG( +		    rfd->flags, +		    RFAPI_HD_FLAG_IS_VRF)) /* assume VRF/internal are valid */ +		return 0; -  if ((rc = rfapi_find_handle (rfd->bgp, &rfd->vn_addr, &rfd->un_addr, &hh))) -    return rc; +	if ((rc = rfapi_find_handle(rfd->bgp, &rfd->vn_addr, &rfd->un_addr, +				    &hh))) +		return rc; -  if (rfd != hh) -    return ENOENT; +	if (rfd != hh) +		return ENOENT; -  if (!rfd->rfg) -    return ESTALE; +	if (!rfd->rfg) +		return ESTALE; -  return 0; +	return 0;  } - -void -del_vnc_route ( -  struct rfapi_descriptor	*rfd, -  struct peer			*peer, /* rfd->peer for RFP regs */ -  struct bgp			*bgp, -  safi_t			safi, -  struct prefix			*p, -  struct prefix_rd		*prd, -  uint8_t			type, -  uint8_t			sub_type, -  struct rfapi_nexthop		*lnh, -  int				kill) +void del_vnc_route(struct rfapi_descriptor *rfd, +		   struct peer *peer, /* rfd->peer for RFP regs */ +		   struct bgp *bgp, safi_t safi, struct prefix *p, +		   struct prefix_rd *prd, uint8_t type, uint8_t sub_type, +		   struct rfapi_nexthop *lnh, int kill)  { -  afi_t afi;                    /* of the VN address */ -  struct bgp_node *bn; -  struct bgp_info *bi; -  char buf[BUFSIZ]; -  char buf2[BUFSIZ]; -  struct prefix_rd prd0; - -  prefix2str (p, buf, BUFSIZ); -  buf[BUFSIZ - 1] = 0;          /* guarantee NUL-terminated */ - -  prefix_rd2str (prd, buf2, BUFSIZ); -  buf2[BUFSIZ - 1] = 0; - -  afi = family2afi (p->family); -  assert (afi == AFI_IP || afi == AFI_IP6); - -  if (safi == SAFI_ENCAP) -    { -      memset (&prd0, 0, sizeof (prd0)); -      prd0.family = AF_UNSPEC; -      prd0.prefixlen = 64; -      prd = &prd0; -    } -  bn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd); - -  vnc_zlog_debug_verbose -    ("%s: peer=%p, prefix=%s, prd=%s afi=%d, safi=%d bn=%p, bn->info=%p", -     __func__, peer, buf, buf2, afi, safi, bn, (bn ? bn->info : NULL)); - -  for (bi = (bn ? bn->info : NULL); bi; bi = bi->next) -    { - -      vnc_zlog_debug_verbose -        ("%s: trying bi=%p, bi->peer=%p, bi->type=%d, bi->sub_type=%d, bi->extra->vnc.export.rfapi_handle=%p, local_pref=%u", -         __func__, bi, bi->peer, bi->type, bi->sub_type, -         (bi->extra ? bi->extra->vnc.export.rfapi_handle : NULL), -	 ((bi->attr && CHECK_FLAG(bi->attr->flag, ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)))? bi->attr->local_pref: 0)); - -      if (bi->peer == peer && -          bi->type == type && -          bi->sub_type == sub_type && -          bi->extra && bi->extra->vnc.export.rfapi_handle == (void *) rfd) -        { - -          vnc_zlog_debug_verbose ("%s: matched it", __func__); - -          break; -        } -    } - -  if (lnh) -    { -      /* -       * lnh set means to JUST delete the local nexthop from this -       * route. Leave the route itself in place. -       * TBD add return code reporting of success/failure -       */ -      if (!bi || !bi->extra || !bi->extra->vnc.export.local_nexthops) -        { -          /* -           * no local nexthops -           */ -          vnc_zlog_debug_verbose ("%s: lnh list already empty at prefix %s", -                      __func__, buf); -          goto done; -        } - -      /* -       * look for it -       */ -      struct listnode *node; -      struct rfapi_nexthop *pLnh = NULL; - -      for (ALL_LIST_ELEMENTS_RO (bi->extra->vnc.export.local_nexthops, -                                 node, pLnh)) -        { - -          if (prefix_same (&pLnh->addr, &lnh->addr)) -            { -              break; -            } -        } - -      if (pLnh) -        { -          listnode_delete (bi->extra->vnc.export.local_nexthops, pLnh); - -          /* silly rabbit, listnode_delete doesn't invoke list->del on data */ -          rfapi_nexthop_free (pLnh); -        } -      else -        { -          vnc_zlog_debug_verbose ("%s: desired lnh not found %s", __func__, buf); -        } -      goto done; -    } - -  /* -   * loop back to import tables -   * Do this before removing from BGP RIB because rfapiProcessWithdraw -   * might refer to it -   */ -  rfapiProcessWithdraw (peer, rfd, p, prd, NULL, afi, safi, type, kill); - -  if (bi) -    { -      char buf[BUFSIZ]; - -      prefix2str (p, buf, BUFSIZ); -      buf[BUFSIZ - 1] = 0;      /* guarantee NUL-terminated */ - -      vnc_zlog_debug_verbose ("%s: Found route (safi=%d) to delete at prefix %s", -                  __func__, safi, buf); - -      if (safi == SAFI_MPLS_VPN) -        { -          struct bgp_node *prn = NULL; -          struct bgp_table *table = NULL; - -          prn = bgp_node_get (bgp->rib[afi][safi], (struct prefix *) prd); -          if (prn->info) -            { -              table = (struct bgp_table *) (prn->info); - -              vnc_import_bgp_del_vnc_host_route_mode_resolve_nve (bgp, -                                                                  prd, -                                                                  table, -                                                                  p, bi); -            } -          bgp_unlock_node (prn); -        } - -      /* -       * Delete local_nexthops list -       */ -      if (bi->extra && bi->extra->vnc.export.local_nexthops) -        { -          list_delete (bi->extra->vnc.export.local_nexthops); -        } - -      bgp_aggregate_decrement (bgp, p, bi, afi, safi); -      bgp_info_delete (bn, bi); -      bgp_process (bgp, bn, afi, safi); -    } -  else -    { -      vnc_zlog_debug_verbose ("%s: Couldn't find route (safi=%d) at prefix %s", -                  __func__, safi, buf); -    } +	afi_t afi; /* of the VN address */ +	struct bgp_node *bn; +	struct bgp_info *bi; +	char buf[BUFSIZ]; +	char buf2[BUFSIZ]; +	struct prefix_rd prd0; + +	prefix2str(p, buf, BUFSIZ); +	buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */ + +	prefix_rd2str(prd, buf2, BUFSIZ); +	buf2[BUFSIZ - 1] = 0; + +	afi = family2afi(p->family); +	assert(afi == AFI_IP || afi == AFI_IP6); + +	if (safi == SAFI_ENCAP) { +		memset(&prd0, 0, sizeof(prd0)); +		prd0.family = AF_UNSPEC; +		prd0.prefixlen = 64; +		prd = &prd0; +	} +	bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd); + +	vnc_zlog_debug_verbose( +		"%s: peer=%p, prefix=%s, prd=%s afi=%d, safi=%d bn=%p, bn->info=%p", +		__func__, peer, buf, buf2, afi, safi, bn, +		(bn ? bn->info : NULL)); + +	for (bi = (bn ? bn->info : NULL); bi; bi = bi->next) { + +		vnc_zlog_debug_verbose( +			"%s: trying bi=%p, bi->peer=%p, bi->type=%d, bi->sub_type=%d, bi->extra->vnc.export.rfapi_handle=%p, local_pref=%u", +			__func__, bi, bi->peer, bi->type, bi->sub_type, +			(bi->extra ? bi->extra->vnc.export.rfapi_handle : NULL), +			((bi->attr +			  && CHECK_FLAG(bi->attr->flag, +					ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))) +				 ? bi->attr->local_pref +				 : 0)); + +		if (bi->peer == peer && bi->type == type +		    && bi->sub_type == sub_type && bi->extra +		    && bi->extra->vnc.export.rfapi_handle == (void *)rfd) { + +			vnc_zlog_debug_verbose("%s: matched it", __func__); + +			break; +		} +	} + +	if (lnh) { +		/* +		 * lnh set means to JUST delete the local nexthop from this +		 * route. Leave the route itself in place. +		 * TBD add return code reporting of success/failure +		 */ +		if (!bi || !bi->extra +		    || !bi->extra->vnc.export.local_nexthops) { +			/* +			 * no local nexthops +			 */ +			vnc_zlog_debug_verbose( +				"%s: lnh list already empty at prefix %s", +				__func__, buf); +			goto done; +		} + +		/* +		 * look for it +		 */ +		struct listnode *node; +		struct rfapi_nexthop *pLnh = NULL; + +		for (ALL_LIST_ELEMENTS_RO(bi->extra->vnc.export.local_nexthops, +					  node, pLnh)) { + +			if (prefix_same(&pLnh->addr, &lnh->addr)) { +				break; +			} +		} + +		if (pLnh) { +			listnode_delete(bi->extra->vnc.export.local_nexthops, +					pLnh); + +			/* silly rabbit, listnode_delete doesn't invoke +			 * list->del on data */ +			rfapi_nexthop_free(pLnh); +		} else { +			vnc_zlog_debug_verbose("%s: desired lnh not found %s", +					       __func__, buf); +		} +		goto done; +	} + +	/* +	 * loop back to import tables +	 * Do this before removing from BGP RIB because rfapiProcessWithdraw +	 * might refer to it +	 */ +	rfapiProcessWithdraw(peer, rfd, p, prd, NULL, afi, safi, type, kill); + +	if (bi) { +		char buf[BUFSIZ]; + +		prefix2str(p, buf, BUFSIZ); +		buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */ + +		vnc_zlog_debug_verbose( +			"%s: Found route (safi=%d) to delete at prefix %s", +			__func__, safi, buf); + +		if (safi == SAFI_MPLS_VPN) { +			struct bgp_node *prn = NULL; +			struct bgp_table *table = NULL; + +			prn = bgp_node_get(bgp->rib[afi][safi], +					   (struct prefix *)prd); +			if (prn->info) { +				table = (struct bgp_table *)(prn->info); + +				vnc_import_bgp_del_vnc_host_route_mode_resolve_nve( +					bgp, prd, table, p, bi); +			} +			bgp_unlock_node(prn); +		} + +		/* +		 * Delete local_nexthops list +		 */ +		if (bi->extra && bi->extra->vnc.export.local_nexthops) { +			list_delete(bi->extra->vnc.export.local_nexthops); +		} + +		bgp_aggregate_decrement(bgp, p, bi, afi, safi); +		bgp_info_delete(bn, bi); +		bgp_process(bgp, bn, afi, safi); +	} else { +		vnc_zlog_debug_verbose( +			"%s: Couldn't find route (safi=%d) at prefix %s", +			__func__, safi, buf); +	}  done: -  bgp_unlock_node (bn); +	bgp_unlock_node(bn);  } -struct rfapi_nexthop * -rfapi_nexthop_new (struct rfapi_nexthop *copyme) +struct rfapi_nexthop *rfapi_nexthop_new(struct rfapi_nexthop *copyme)  { -  struct rfapi_nexthop *new = -    XCALLOC (MTYPE_RFAPI_NEXTHOP, sizeof (struct rfapi_nexthop)); -  if (copyme) -    *new = *copyme; -  return new; +	struct rfapi_nexthop *new = +		XCALLOC(MTYPE_RFAPI_NEXTHOP, sizeof(struct rfapi_nexthop)); +	if (copyme) +		*new = *copyme; +	return new;  } -void -rfapi_nexthop_free (void *p) +void rfapi_nexthop_free(void *p)  { -  struct rfapi_nexthop *goner = p; -  XFREE (MTYPE_RFAPI_NEXTHOP, goner); +	struct rfapi_nexthop *goner = p; +	XFREE(MTYPE_RFAPI_NEXTHOP, goner);  } -struct rfapi_vn_option * -rfapi_vn_options_dup (struct rfapi_vn_option *existing) +struct rfapi_vn_option *rfapi_vn_options_dup(struct rfapi_vn_option *existing)  { -  struct rfapi_vn_option *p; -  struct rfapi_vn_option *head = NULL; -  struct rfapi_vn_option *tail = NULL; - -  for (p = existing; p; p = p->next) -    { -      struct rfapi_vn_option *new; - -      new = XCALLOC (MTYPE_RFAPI_VN_OPTION, sizeof (struct rfapi_vn_option)); -      *new = *p; -      new->next = NULL; -      if (tail) -        (tail)->next = new; -      tail = new; -      if (!head) -        { -          head = new; -        } -    } -  return head; +	struct rfapi_vn_option *p; +	struct rfapi_vn_option *head = NULL; +	struct rfapi_vn_option *tail = NULL; + +	for (p = existing; p; p = p->next) { +		struct rfapi_vn_option *new; + +		new = XCALLOC(MTYPE_RFAPI_VN_OPTION, +			      sizeof(struct rfapi_vn_option)); +		*new = *p; +		new->next = NULL; +		if (tail) +			(tail)->next = new; +		tail = new; +		if (!head) { +			head = new; +		} +	} +	return head;  } -void -rfapi_un_options_free (struct rfapi_un_option *p) +void rfapi_un_options_free(struct rfapi_un_option *p)  { -  struct rfapi_un_option *next; +	struct rfapi_un_option *next; -  while (p) -    { -      next = p->next; -      XFREE (MTYPE_RFAPI_UN_OPTION, p); -      p = next; -    } +	while (p) { +		next = p->next; +		XFREE(MTYPE_RFAPI_UN_OPTION, p); +		p = next; +	}  } -void -rfapi_vn_options_free (struct rfapi_vn_option *p) +void rfapi_vn_options_free(struct rfapi_vn_option *p)  { -  struct rfapi_vn_option *next; +	struct rfapi_vn_option *next; -  while (p) -    { -      next = p->next; -      XFREE (MTYPE_RFAPI_VN_OPTION, p); -      p = next; -    } +	while (p) { +		next = p->next; +		XFREE(MTYPE_RFAPI_VN_OPTION, p); +		p = next; +	}  }  /* Based on bgp_redistribute_add() */ -void -add_vnc_route ( -  struct rfapi_descriptor	*rfd,		/* cookie, VPN UN addr, peer */ -  struct bgp			*bgp, -  int				safi, -  struct prefix			*p, -  struct prefix_rd		*prd, -  struct rfapi_ip_addr		*nexthop, -  uint32_t			*local_pref, -  uint32_t			*lifetime,	/* NULL => dont send lifetime */ -  struct bgp_tea_options	*rfp_options, -  struct rfapi_un_option	*options_un, -  struct rfapi_vn_option	*options_vn, -  struct ecommunity		*rt_export_list,/* Copied, not consumed */ -  uint32_t			*med,		/* NULL => don't set med */ -  uint32_t			*label,		/* low order 3 bytes */ -  uint8_t			type, -  uint8_t			sub_type,	/* RFP, NORMAL or REDIST */ -  int				flags) +void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */ +		   struct bgp *bgp, int safi, struct prefix *p, +		   struct prefix_rd *prd, struct rfapi_ip_addr *nexthop, +		   uint32_t *local_pref, +		   uint32_t *lifetime, /* NULL => dont send lifetime */ +		   struct bgp_tea_options *rfp_options, +		   struct rfapi_un_option *options_un, +		   struct rfapi_vn_option *options_vn, +		   struct ecommunity *rt_export_list, /* Copied, not consumed */ +		   uint32_t *med,		   /* NULL => don't set med */ +		   uint32_t *label,		   /* low order 3 bytes */ +		   uint8_t type, uint8_t sub_type, /* RFP, NORMAL or REDIST */ +		   int flags)  { -  afi_t afi;                    /* of the VN address */ -  struct bgp_info *new; -  struct bgp_info *bi; -  struct bgp_node *bn; - -  struct attr attr = { 0 }; -  struct attr *new_attr; -  uint32_t    label_val; - -  struct bgp_attr_encap_subtlv *encaptlv; -  char buf[BUFSIZ]; -  char buf2[BUFSIZ]; -#if 0   /* unused? */ +	afi_t afi; /* of the VN address */ +	struct bgp_info *new; +	struct bgp_info *bi; +	struct bgp_node *bn; + +	struct attr attr = {0}; +	struct attr *new_attr; +	uint32_t label_val; + +	struct bgp_attr_encap_subtlv *encaptlv; +	char buf[BUFSIZ]; +	char buf2[BUFSIZ]; +#if 0 /* unused? */    struct prefix pfx_buf;  #endif -  struct rfapi_nexthop *lnh = NULL;     /* local nexthop */ -  struct rfapi_vn_option *vo; -  struct rfapi_l2address_option *l2o = NULL; -  struct rfapi_ip_addr		*un_addr = &rfd->un_addr; +	struct rfapi_nexthop *lnh = NULL; /* local nexthop */ +	struct rfapi_vn_option *vo; +	struct rfapi_l2address_option *l2o = NULL; +	struct rfapi_ip_addr *un_addr = &rfd->un_addr; -  bgp_encap_types TunnelType = BGP_ENCAP_TYPE_RESERVED; -  struct bgp_redist *red; +	bgp_encap_types TunnelType = BGP_ENCAP_TYPE_RESERVED; +	struct bgp_redist *red; -  if (safi == SAFI_ENCAP && -      !(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP)) -    { +	if (safi == SAFI_ENCAP +	    && !(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP)) { -      /* -       * Encap mode not enabled. UN addresses will be communicated -       * via VNC Tunnel subtlv instead. -       */ -      vnc_zlog_debug_verbose ("%s: encap mode not enabled, not adding SAFI_ENCAP route", -                  __func__); -      return; -    } +		/* +		 * Encap mode not enabled. UN addresses will be communicated +		 * via VNC Tunnel subtlv instead. +		 */ +		vnc_zlog_debug_verbose( +			"%s: encap mode not enabled, not adding SAFI_ENCAP route", +			__func__); +		return; +	} -#if 0   /* unused? */ +#if 0 /* unused? */    if ((safi == SAFI_MPLS_VPN) && (flags & RFAPI_AHR_SET_PFX_TO_NEXTHOP))      { @@ -682,579 +631,542 @@ add_vnc_route (        p = &pfx_buf;      }  #endif -  for (vo = options_vn; vo; vo = vo->next) -    { -      if (RFAPI_VN_OPTION_TYPE_L2ADDR == vo->type) -        { -          l2o = &vo->v.l2addr; -          if (RFAPI_0_ETHERADDR (&l2o->macaddr)) -            l2o = NULL;         /* not MAC resolution */ -        } -      if (RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP == vo->type) -        { -          lnh = &vo->v.local_nexthop; -        } -    } - -  if (label) -    label_val = *label; -  else  -    label_val = MPLS_LABEL_IMPLICIT_NULL; - -  prefix_rd2str (prd, buf2, BUFSIZ); -  buf2[BUFSIZ - 1] = 0; - - -  afi = family2afi (p->family); -  assert (afi == AFI_IP || afi == AFI_IP6); - -  vnc_zlog_debug_verbose ("%s: afi=%s, safi=%s", __func__, afi2str (afi), -              safi2str (safi)); - -  /* Make default attribute. Produces already-interned attr.aspath */ -  /* Cripes, the memory management of attributes is byzantine */ - -  bgp_attr_default_set (&attr, BGP_ORIGIN_INCOMPLETE); - -  /*  -   * At this point: -   * attr: static -   *  extra: dynamically allocated, owned by attr -   *  aspath: points to interned hash from aspath hash table -   */ - - -  /* -   * Route-specific un_options get added to the VPN SAFI -   * advertisement tunnel encap attribute.  (the per-NVE -   * "default" un_options are put into the 1-per-NVE ENCAP -   * SAFI advertisement). The VPN SAFI also gets the -   * default un_options if there are no route-specific options. -   */ -  if (options_un) -    { -      struct rfapi_un_option *uo; - -      for (uo = options_un; uo; uo = uo->next) -        { -          if (RFAPI_UN_OPTION_TYPE_TUNNELTYPE == uo->type) -            { -              TunnelType = rfapi_tunneltype_option_to_tlv ( -		bgp, un_addr, &uo->v.tunnel, &attr, l2o != NULL); -            } -        } -    } -  else -    { -      /* -       * Add encap attr -       * These are the NVE-specific "default" un_options which are -       * put into the 1-per-NVE ENCAP advertisement. -       */ -      if (rfd->default_tunneltype_option.type) -        { -          TunnelType = rfapi_tunneltype_option_to_tlv ( -	    bgp, un_addr, &rfd->default_tunneltype_option, &attr, -	    l2o != NULL); -        } -      else                      /* create default for local addse  */ -        if (type == ZEBRA_ROUTE_BGP && sub_type == BGP_ROUTE_RFP) -          TunnelType =  -            rfapi_tunneltype_option_to_tlv (bgp, un_addr, NULL, -                                            &attr, l2o != NULL); -    } - -  if (TunnelType == BGP_ENCAP_TYPE_MPLS) -    { -      if (safi == SAFI_ENCAP) -        { -          /* Encap SAFI not used with MPLS  */ -          vnc_zlog_debug_verbose ("%s: mpls tunnel type, encap safi omitted", __func__); -          aspath_unintern (&attr.aspath);       /* Unintern original. */ -          return; -        } -    } - -  if (local_pref) -    { -      attr.local_pref = *local_pref; -      attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF); -    } - -  if (med) -    { -      attr.med = *med; -      attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC); -    } - -  /* override default weight assigned by bgp_attr_default_set() */ -  attr.weight = rfd->peer ? rfd->peer->weight[afi][safi] : 0; - -  /* -   * NB: ticket 81: do not reset attr.aspath here because it would -   * cause iBGP peers to drop route -   */ - -  /* -   * Set originator ID for routes imported from BGP directly. -   * These routes could be synthetic, and therefore could -   * reuse the peer pointers of the routes they are derived -   * from. Setting the originator ID to "us" prevents the -   * wrong originator ID from being sent when this route is -   * sent from a route reflector. -   */ -  if (type == ZEBRA_ROUTE_BGP_DIRECT || type == ZEBRA_ROUTE_BGP_DIRECT_EXT) -    { -      attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID); -      attr.originator_id = bgp->router_id; -    } - - -  /* Set up vnc attribute (sub-tlv for Prefix Lifetime) */ -  if (lifetime && *lifetime != RFAPI_INFINITE_LIFETIME) -    { -      uint32_t lt; - -      encaptlv = -        XCALLOC (MTYPE_ENCAP_TLV, -                 sizeof (struct bgp_attr_encap_subtlv) - 1 + 4); -      assert (encaptlv); -      encaptlv->type = BGP_VNC_SUBTLV_TYPE_LIFETIME;    /* prefix lifetime */ -      encaptlv->length = 4; -      lt = htonl (*lifetime); -      memcpy (encaptlv->value, <, 4); -      attr.vnc_subtlvs = encaptlv; -      vnc_zlog_debug_verbose ("%s: set Encap Attr Prefix Lifetime to %d", -                  __func__, *lifetime); -    } - -  /* add rfp options to vnc attr */ -  if (rfp_options) -    { - -      if (flags & RFAPI_AHR_RFPOPT_IS_VNCTLV) -        { - -          /* -           * this flag means we're passing a pointer to an -           * existing encap tlv chain which we should copy. -           * It's a hack to avoid adding yet another argument -           * to add_vnc_route() -           */ -          encaptlv = -            encap_tlv_dup ((struct bgp_attr_encap_subtlv *) rfp_options); -          if (attr.vnc_subtlvs) -            { -              attr.vnc_subtlvs->next = encaptlv; -            } -          else -            { -              attr.vnc_subtlvs = encaptlv; -            } - -        } -      else -        { -          struct bgp_tea_options *hop; -          /* XXX max of one tlv present so far from above code */ -          struct bgp_attr_encap_subtlv *tail = attr.vnc_subtlvs; - -          for (hop = rfp_options; hop; hop = hop->next) -            { - -              /* -               * Construct subtlv -               */ -              encaptlv = XCALLOC (MTYPE_ENCAP_TLV, -                                  sizeof (struct bgp_attr_encap_subtlv) - 1 + -                                  2 + hop->length); -              assert (encaptlv); -              encaptlv->type = BGP_VNC_SUBTLV_TYPE_RFPOPTION;   /* RFP option */ -              encaptlv->length = 2 + hop->length; -              *((uint8_t *) (encaptlv->value) + 0) = hop->type; -              *((uint8_t *) (encaptlv->value) + 1) = hop->length; -              memcpy (((uint8_t *) encaptlv->value) + 2, hop->value, -                      hop->length); - -              /* -               * add to end of subtlv chain -               */ -              if (tail) -                { -                  tail->next = encaptlv; -                } -              else -                { -                  attr.vnc_subtlvs = encaptlv; -                } -              tail = encaptlv; -            } -        } -    } - -  /*  -   * At this point: -   * attr: static -   *  extra: dynamically allocated, owned by attr -   *      vnc_subtlvs: dynamic chain, length 1 -   *  aspath: points to interned hash from aspath hash table -   */ - - -  attr.ecommunity = ecommunity_new (); -  assert (attr.ecommunity); - -  if (TunnelType != BGP_ENCAP_TYPE_MPLS &&  -      TunnelType != BGP_ENCAP_TYPE_RESERVED) -    { -      /* -       * Add BGP Encapsulation Extended Community. Format described in -       * section 4.5 of RFC 5512. -       * Always include when not MPLS type, to disambiguate this case. -       */ -      struct ecommunity_val beec; - -      memset (&beec, 0, sizeof (beec)); -      beec.val[0] = ECOMMUNITY_ENCODE_OPAQUE; -      beec.val[1] = ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP; -      beec.val[6] = ((TunnelType) >> 8) & 0xff; -      beec.val[7] = (TunnelType) & 0xff; -      ecommunity_add_val (attr.ecommunity, &beec); -    } - -  /* -   * Add extended community attributes to match rt export list -   */ -  if (rt_export_list) -    { -      attr.ecommunity = -        ecommunity_merge (attr.ecommunity, rt_export_list); -    } - -  if (attr.ecommunity->size) -    { -      attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES); -    } -  else -    { -      ecommunity_free (&attr.ecommunity); -      attr.ecommunity = NULL; -    } -  vnc_zlog_debug_verbose ("%s: attr.ecommunity=%p", __func__, -              attr.ecommunity); - - -  /*  -   * At this point: -   * attr: static -   *  extra: dynamically allocated, owned by attr -   *      vnc_subtlvs: dynamic chain, length 1 -   *      ecommunity: dynamic 2-part -   *  aspath: points to interned hash from aspath hash table -   */ - -  /* stuff nexthop in attr_extra; which field depends on IPv4 or IPv6 */ -  switch (nexthop->addr_family) -    { -    case AF_INET: -      /* -       * set this field to prevent bgp_route.c code from setting -       * mp_nexthop_global_in to self -       */ -      attr.nexthop.s_addr = nexthop->addr.v4.s_addr; - -      attr.mp_nexthop_global_in = nexthop->addr.v4; -      attr.mp_nexthop_len = 4; -      break; - -    case AF_INET6: -      attr.mp_nexthop_global = nexthop->addr.v6; -      attr.mp_nexthop_len = 16; -      break; - -    default: -      assert (0); -    } - - -  prefix2str (p, buf, BUFSIZ); -  buf[BUFSIZ - 1] = 0;          /* guarantee NUL-terminated */ - -  /*  -   * At this point: -   * -   * attr: static -   *  extra: dynamically allocated, owned by attr -   *      vnc_subtlvs: dynamic chain, length 1 -   *      ecommunity: dynamic 2-part -   *  aspath: points to interned hash from aspath hash table -   */ - -  red = bgp_redist_lookup(bgp, afi, type, VRF_DEFAULT); - -  if (red && red->redist_metric_flag) -    { -      attr.med = red->redist_metric; -      attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC); -    } - -  bn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd); - -  /* -   * bgp_attr_intern creates a new reference to a cached -   * attribute, but leaves the following bits of trash: -   * - old attr -   * - old attr->extra (free via bgp_attr_extra_free(attr)) -   * -   * Note that it frees the original attr->extra->ecommunity -   * but leaves the new attribute pointing to the ORIGINAL -   * vnc options (which therefore we needn't free from the -   * static attr) -   */ -  new_attr = bgp_attr_intern (&attr); - -  aspath_unintern (&attr.aspath);       /* Unintern original. */ - -  /* -   * At this point: -   * -   * attr: static -   *  extra: dynamically allocated, owned by attr -   *      vnc_subtlvs: dynamic chain, length 1 -   *      ecommunity: POINTS TO INTERNED ecom, THIS REF NOT COUNTED -   * -   * new_attr: an attr that is part of the hash table, distinct -   *           from attr which is static. -   *  extra: dynamically allocated, owned by new_attr (in hash table) -   *      vnc_subtlvs: POINTS TO SAME dynamic chain AS attr -   *      ecommunity: POINTS TO interned/refcounted dynamic 2-part AS attr -   *  aspath: POINTS TO interned/refcounted hashed block -   */ -  for (bi = bn->info; bi; bi = bi->next) -    { -      /* probably only need to check bi->extra->vnc.export.rfapi_handle */ -      if (bi->peer == rfd->peer && -          bi->type == type && -          bi->sub_type == sub_type && -          bi->extra && bi->extra->vnc.export.rfapi_handle == (void *) rfd) -        { - -          break; -        } -    } - -  if (bi) -    { - -      /* -       * Adding new local_nexthop, which does not by itself change -       * what is advertised via BGP -       */ -      if (lnh) -        { -          if (!bi->extra->vnc.export.local_nexthops) -            { -              /* TBD make arrangements to free when needed */ -              bi->extra->vnc.export.local_nexthops = list_new (); -              bi->extra->vnc.export.local_nexthops->del = rfapi_nexthop_free; -            } - -          /* -           * already present? -           */ -          struct listnode *node; -          struct rfapi_nexthop *pLnh = NULL; - -          for (ALL_LIST_ELEMENTS_RO (bi->extra->vnc.export.local_nexthops, -                                     node, pLnh)) -            { - -              if (prefix_same (&pLnh->addr, &lnh->addr)) -                { -                  break; -                } -            } - -          /* -           * Not present, add new one -           */ -          if (!pLnh) -            { -              pLnh = rfapi_nexthop_new (lnh); -              listnode_add (bi->extra->vnc.export.local_nexthops, pLnh); -            } -        } - -      if (attrhash_cmp (bi->attr, new_attr) && -          !CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) -        { -          bgp_attr_unintern (&new_attr); -          bgp_unlock_node (bn); - -          vnc_zlog_debug_any ("%s: Found route (safi=%d) at prefix %s, no change", -                     __func__, safi, buf); - -          goto done; -        } -      else -        { -          /* The attribute is changed. */ -          bgp_info_set_flag (bn, bi, BGP_INFO_ATTR_CHANGED); - -          if (safi == SAFI_MPLS_VPN) -            { -              struct bgp_node *prn = NULL; -              struct bgp_table *table = NULL; - -              prn = bgp_node_get (bgp->rib[afi][safi], (struct prefix *) prd); -              if (prn->info) -                { -                  table = (struct bgp_table *) (prn->info); - -                  vnc_import_bgp_del_vnc_host_route_mode_resolve_nve ( -		    bgp, prd, table, p, bi); -                } -              bgp_unlock_node (prn); -            } - -          /* Rewrite BGP route information. */ -          if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) -            bgp_info_restore (bn, bi); -          else -            bgp_aggregate_decrement (bgp, p, bi, afi, safi); -          bgp_attr_unintern (&bi->attr); -          bi->attr = new_attr; -          bi->uptime = bgp_clock (); - - -          if (safi == SAFI_MPLS_VPN) -            { -              struct bgp_node *prn = NULL; -              struct bgp_table *table = NULL; - -              prn = bgp_node_get (bgp->rib[afi][safi], (struct prefix *) prd); -              if (prn->info) -                { -                  table = (struct bgp_table *) (prn->info); - -                  vnc_import_bgp_add_vnc_host_route_mode_resolve_nve ( -		    bgp, prd, table, p, bi); -                } -              bgp_unlock_node (prn); -            } - -          /* Process change. */ -          bgp_aggregate_increment (bgp, p, bi, afi, safi); -          bgp_process (bgp, bn, afi, safi); -          bgp_unlock_node (bn); - -          vnc_zlog_debug_any ("%s: Found route (safi=%d) at prefix %s, changed attr", -                     __func__, safi, buf); - -          goto done; -        } -    } - - -  new = bgp_info_new (); -  new->type = type; -  new->sub_type = sub_type; -  new->peer = rfd->peer; -  SET_FLAG (new->flags, BGP_INFO_VALID); -  new->attr = new_attr; -  new->uptime = bgp_clock (); - -  /* save backref to rfapi handle */ -  assert (bgp_info_extra_get (new)); -  new->extra->vnc.export.rfapi_handle = (void *) rfd; -  encode_label (label_val, &new->extra->label); - -  /* debug */ - -  if (VNC_DEBUG(VERBOSE)) -    { -      vnc_zlog_debug_verbose ("%s: printing BI", __func__); -      rfapiPrintBi (NULL, new); -    } - -  bgp_aggregate_increment (bgp, p, new, afi, safi); -  bgp_info_add (bn, new); - -  if (safi == SAFI_MPLS_VPN) -    { -      struct bgp_node *prn = NULL; -      struct bgp_table *table = NULL; - -      prn = bgp_node_get (bgp->rib[afi][safi], (struct prefix *) prd); -      if (prn->info) -        { -          table = (struct bgp_table *) (prn->info); - -          vnc_import_bgp_add_vnc_host_route_mode_resolve_nve ( -	    bgp, prd, table, p, new); -        } -      bgp_unlock_node (prn); -      encode_label (label_val, &bn->local_label); -    } - -  bgp_unlock_node (bn); -  bgp_process (bgp, bn, afi, safi); - -  vnc_zlog_debug_any ("%s: Added route (safi=%s) at prefix %s (bn=%p, prd=%s)", -             __func__, safi2str (safi), buf, bn, buf2); +	for (vo = options_vn; vo; vo = vo->next) { +		if (RFAPI_VN_OPTION_TYPE_L2ADDR == vo->type) { +			l2o = &vo->v.l2addr; +			if (RFAPI_0_ETHERADDR(&l2o->macaddr)) +				l2o = NULL; /* not MAC resolution */ +		} +		if (RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP == vo->type) { +			lnh = &vo->v.local_nexthop; +		} +	} + +	if (label) +		label_val = *label; +	else +		label_val = MPLS_LABEL_IMPLICIT_NULL; + +	prefix_rd2str(prd, buf2, BUFSIZ); +	buf2[BUFSIZ - 1] = 0; + + +	afi = family2afi(p->family); +	assert(afi == AFI_IP || afi == AFI_IP6); + +	vnc_zlog_debug_verbose("%s: afi=%s, safi=%s", __func__, afi2str(afi), +			       safi2str(safi)); + +	/* Make default attribute. Produces already-interned attr.aspath */ +	/* Cripes, the memory management of attributes is byzantine */ + +	bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE); + +	/* +	 * At this point: +	 * attr: static +	 *  extra: dynamically allocated, owned by attr +	 *  aspath: points to interned hash from aspath hash table +	 */ + + +	/* +	 * Route-specific un_options get added to the VPN SAFI +	 * advertisement tunnel encap attribute.  (the per-NVE +	 * "default" un_options are put into the 1-per-NVE ENCAP +	 * SAFI advertisement). The VPN SAFI also gets the +	 * default un_options if there are no route-specific options. +	 */ +	if (options_un) { +		struct rfapi_un_option *uo; + +		for (uo = options_un; uo; uo = uo->next) { +			if (RFAPI_UN_OPTION_TYPE_TUNNELTYPE == uo->type) { +				TunnelType = rfapi_tunneltype_option_to_tlv( +					bgp, un_addr, &uo->v.tunnel, &attr, +					l2o != NULL); +			} +		} +	} else { +		/* +		 * Add encap attr +		 * These are the NVE-specific "default" un_options which are +		 * put into the 1-per-NVE ENCAP advertisement. +		 */ +		if (rfd->default_tunneltype_option.type) { +			TunnelType = rfapi_tunneltype_option_to_tlv( +				bgp, un_addr, &rfd->default_tunneltype_option, +				&attr, l2o != NULL); +		} else /* create default for local addse  */ +			if (type == ZEBRA_ROUTE_BGP +			    && sub_type == BGP_ROUTE_RFP) +			TunnelType = rfapi_tunneltype_option_to_tlv( +				bgp, un_addr, NULL, &attr, l2o != NULL); +	} + +	if (TunnelType == BGP_ENCAP_TYPE_MPLS) { +		if (safi == SAFI_ENCAP) { +			/* Encap SAFI not used with MPLS  */ +			vnc_zlog_debug_verbose( +				"%s: mpls tunnel type, encap safi omitted", +				__func__); +			aspath_unintern(&attr.aspath); /* Unintern original. */ +			return; +		} +	} + +	if (local_pref) { +		attr.local_pref = *local_pref; +		attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF); +	} + +	if (med) { +		attr.med = *med; +		attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC); +	} + +	/* override default weight assigned by bgp_attr_default_set() */ +	attr.weight = rfd->peer ? rfd->peer->weight[afi][safi] : 0; + +	/* +	 * NB: ticket 81: do not reset attr.aspath here because it would +	 * cause iBGP peers to drop route +	 */ + +	/* +	 * Set originator ID for routes imported from BGP directly. +	 * These routes could be synthetic, and therefore could +	 * reuse the peer pointers of the routes they are derived +	 * from. Setting the originator ID to "us" prevents the +	 * wrong originator ID from being sent when this route is +	 * sent from a route reflector. +	 */ +	if (type == ZEBRA_ROUTE_BGP_DIRECT +	    || type == ZEBRA_ROUTE_BGP_DIRECT_EXT) { +		attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID); +		attr.originator_id = bgp->router_id; +	} + + +	/* Set up vnc attribute (sub-tlv for Prefix Lifetime) */ +	if (lifetime && *lifetime != RFAPI_INFINITE_LIFETIME) { +		uint32_t lt; + +		encaptlv = +			XCALLOC(MTYPE_ENCAP_TLV, +				sizeof(struct bgp_attr_encap_subtlv) - 1 + 4); +		assert(encaptlv); +		encaptlv->type = +			BGP_VNC_SUBTLV_TYPE_LIFETIME; /* prefix lifetime */ +		encaptlv->length = 4; +		lt = htonl(*lifetime); +		memcpy(encaptlv->value, <, 4); +		attr.vnc_subtlvs = encaptlv; +		vnc_zlog_debug_verbose( +			"%s: set Encap Attr Prefix Lifetime to %d", __func__, +			*lifetime); +	} + +	/* add rfp options to vnc attr */ +	if (rfp_options) { + +		if (flags & RFAPI_AHR_RFPOPT_IS_VNCTLV) { + +			/* +			 * this flag means we're passing a pointer to an +			 * existing encap tlv chain which we should copy. +			 * It's a hack to avoid adding yet another argument +			 * to add_vnc_route() +			 */ +			encaptlv = encap_tlv_dup( +				(struct bgp_attr_encap_subtlv *)rfp_options); +			if (attr.vnc_subtlvs) { +				attr.vnc_subtlvs->next = encaptlv; +			} else { +				attr.vnc_subtlvs = encaptlv; +			} + +		} else { +			struct bgp_tea_options *hop; +			/* XXX max of one tlv present so far from above code */ +			struct bgp_attr_encap_subtlv *tail = attr.vnc_subtlvs; + +			for (hop = rfp_options; hop; hop = hop->next) { + +				/* +				 * Construct subtlv +				 */ +				encaptlv = XCALLOC( +					MTYPE_ENCAP_TLV, +					sizeof(struct bgp_attr_encap_subtlv) - 1 +						+ 2 + hop->length); +				assert(encaptlv); +				encaptlv->type = +					BGP_VNC_SUBTLV_TYPE_RFPOPTION; /* RFP +									  option +									  */ +				encaptlv->length = 2 + hop->length; +				*((uint8_t *)(encaptlv->value) + 0) = hop->type; +				*((uint8_t *)(encaptlv->value) + 1) = +					hop->length; +				memcpy(((uint8_t *)encaptlv->value) + 2, +				       hop->value, hop->length); + +				/* +				 * add to end of subtlv chain +				 */ +				if (tail) { +					tail->next = encaptlv; +				} else { +					attr.vnc_subtlvs = encaptlv; +				} +				tail = encaptlv; +			} +		} +	} + +	/* +	 * At this point: +	 * attr: static +	 *  extra: dynamically allocated, owned by attr +	 *      vnc_subtlvs: dynamic chain, length 1 +	 *  aspath: points to interned hash from aspath hash table +	 */ + + +	attr.ecommunity = ecommunity_new(); +	assert(attr.ecommunity); + +	if (TunnelType != BGP_ENCAP_TYPE_MPLS +	    && TunnelType != BGP_ENCAP_TYPE_RESERVED) { +		/* +		 * Add BGP Encapsulation Extended Community. Format described in +		 * section 4.5 of RFC 5512. +		 * Always include when not MPLS type, to disambiguate this case. +		 */ +		struct ecommunity_val beec; + +		memset(&beec, 0, sizeof(beec)); +		beec.val[0] = ECOMMUNITY_ENCODE_OPAQUE; +		beec.val[1] = ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP; +		beec.val[6] = ((TunnelType) >> 8) & 0xff; +		beec.val[7] = (TunnelType)&0xff; +		ecommunity_add_val(attr.ecommunity, &beec); +	} + +	/* +	 * Add extended community attributes to match rt export list +	 */ +	if (rt_export_list) { +		attr.ecommunity = +			ecommunity_merge(attr.ecommunity, rt_export_list); +	} + +	if (attr.ecommunity->size) { +		attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES); +	} else { +		ecommunity_free(&attr.ecommunity); +		attr.ecommunity = NULL; +	} +	vnc_zlog_debug_verbose("%s: attr.ecommunity=%p", __func__, +			       attr.ecommunity); + + +	/* +	 * At this point: +	 * attr: static +	 *  extra: dynamically allocated, owned by attr +	 *      vnc_subtlvs: dynamic chain, length 1 +	 *      ecommunity: dynamic 2-part +	 *  aspath: points to interned hash from aspath hash table +	 */ + +	/* stuff nexthop in attr_extra; which field depends on IPv4 or IPv6 */ +	switch (nexthop->addr_family) { +	case AF_INET: +		/* +		 * set this field to prevent bgp_route.c code from setting +		 * mp_nexthop_global_in to self +		 */ +		attr.nexthop.s_addr = nexthop->addr.v4.s_addr; + +		attr.mp_nexthop_global_in = nexthop->addr.v4; +		attr.mp_nexthop_len = 4; +		break; + +	case AF_INET6: +		attr.mp_nexthop_global = nexthop->addr.v6; +		attr.mp_nexthop_len = 16; +		break; + +	default: +		assert(0); +	} + + +	prefix2str(p, buf, BUFSIZ); +	buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */ + +	/* +	 * At this point: +	 * +	 * attr: static +	 *  extra: dynamically allocated, owned by attr +	 *      vnc_subtlvs: dynamic chain, length 1 +	 *      ecommunity: dynamic 2-part +	 *  aspath: points to interned hash from aspath hash table +	 */ + +	red = bgp_redist_lookup(bgp, afi, type, VRF_DEFAULT); + +	if (red && red->redist_metric_flag) { +		attr.med = red->redist_metric; +		attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC); +	} + +	bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd); + +	/* +	 * bgp_attr_intern creates a new reference to a cached +	 * attribute, but leaves the following bits of trash: +	 * - old attr +	 * - old attr->extra (free via bgp_attr_extra_free(attr)) +	 * +	 * Note that it frees the original attr->extra->ecommunity +	 * but leaves the new attribute pointing to the ORIGINAL +	 * vnc options (which therefore we needn't free from the +	 * static attr) +	 */ +	new_attr = bgp_attr_intern(&attr); + +	aspath_unintern(&attr.aspath); /* Unintern original. */ + +	/* +	 * At this point: +	 * +	 * attr: static +	 *  extra: dynamically allocated, owned by attr +	 *      vnc_subtlvs: dynamic chain, length 1 +	 *      ecommunity: POINTS TO INTERNED ecom, THIS REF NOT COUNTED +	 * +	 * new_attr: an attr that is part of the hash table, distinct +	 *           from attr which is static. +	 *  extra: dynamically allocated, owned by new_attr (in hash table) +	 *      vnc_subtlvs: POINTS TO SAME dynamic chain AS attr +	 *      ecommunity: POINTS TO interned/refcounted dynamic 2-part AS attr +	 *  aspath: POINTS TO interned/refcounted hashed block +	 */ +	for (bi = bn->info; bi; bi = bi->next) { +		/* probably only need to check +		 * bi->extra->vnc.export.rfapi_handle */ +		if (bi->peer == rfd->peer && bi->type == type +		    && bi->sub_type == sub_type && bi->extra +		    && bi->extra->vnc.export.rfapi_handle == (void *)rfd) { + +			break; +		} +	} + +	if (bi) { + +		/* +		 * Adding new local_nexthop, which does not by itself change +		 * what is advertised via BGP +		 */ +		if (lnh) { +			if (!bi->extra->vnc.export.local_nexthops) { +				/* TBD make arrangements to free when needed */ +				bi->extra->vnc.export.local_nexthops = +					list_new(); +				bi->extra->vnc.export.local_nexthops->del = +					rfapi_nexthop_free; +			} + +			/* +			 * already present? +			 */ +			struct listnode *node; +			struct rfapi_nexthop *pLnh = NULL; + +			for (ALL_LIST_ELEMENTS_RO( +				     bi->extra->vnc.export.local_nexthops, node, +				     pLnh)) { + +				if (prefix_same(&pLnh->addr, &lnh->addr)) { +					break; +				} +			} + +			/* +			 * Not present, add new one +			 */ +			if (!pLnh) { +				pLnh = rfapi_nexthop_new(lnh); +				listnode_add( +					bi->extra->vnc.export.local_nexthops, +					pLnh); +			} +		} + +		if (attrhash_cmp(bi->attr, new_attr) +		    && !CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) { +			bgp_attr_unintern(&new_attr); +			bgp_unlock_node(bn); + +			vnc_zlog_debug_any( +				"%s: Found route (safi=%d) at prefix %s, no change", +				__func__, safi, buf); + +			goto done; +		} else { +			/* The attribute is changed. */ +			bgp_info_set_flag(bn, bi, BGP_INFO_ATTR_CHANGED); + +			if (safi == SAFI_MPLS_VPN) { +				struct bgp_node *prn = NULL; +				struct bgp_table *table = NULL; + +				prn = bgp_node_get(bgp->rib[afi][safi], +						   (struct prefix *)prd); +				if (prn->info) { +					table = (struct bgp_table *)(prn->info); + +					vnc_import_bgp_del_vnc_host_route_mode_resolve_nve( +						bgp, prd, table, p, bi); +				} +				bgp_unlock_node(prn); +			} + +			/* Rewrite BGP route information. */ +			if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) +				bgp_info_restore(bn, bi); +			else +				bgp_aggregate_decrement(bgp, p, bi, afi, safi); +			bgp_attr_unintern(&bi->attr); +			bi->attr = new_attr; +			bi->uptime = bgp_clock(); + + +			if (safi == SAFI_MPLS_VPN) { +				struct bgp_node *prn = NULL; +				struct bgp_table *table = NULL; + +				prn = bgp_node_get(bgp->rib[afi][safi], +						   (struct prefix *)prd); +				if (prn->info) { +					table = (struct bgp_table *)(prn->info); + +					vnc_import_bgp_add_vnc_host_route_mode_resolve_nve( +						bgp, prd, table, p, bi); +				} +				bgp_unlock_node(prn); +			} + +			/* Process change. */ +			bgp_aggregate_increment(bgp, p, bi, afi, safi); +			bgp_process(bgp, bn, afi, safi); +			bgp_unlock_node(bn); + +			vnc_zlog_debug_any( +				"%s: Found route (safi=%d) at prefix %s, changed attr", +				__func__, safi, buf); + +			goto done; +		} +	} + + +	new = bgp_info_new(); +	new->type = type; +	new->sub_type = sub_type; +	new->peer = rfd->peer; +	SET_FLAG(new->flags, BGP_INFO_VALID); +	new->attr = new_attr; +	new->uptime = bgp_clock(); + +	/* save backref to rfapi handle */ +	assert(bgp_info_extra_get(new)); +	new->extra->vnc.export.rfapi_handle = (void *)rfd; +	encode_label(label_val, &new->extra->label); + +	/* debug */ + +	if (VNC_DEBUG(VERBOSE)) { +		vnc_zlog_debug_verbose("%s: printing BI", __func__); +		rfapiPrintBi(NULL, new); +	} + +	bgp_aggregate_increment(bgp, p, new, afi, safi); +	bgp_info_add(bn, new); + +	if (safi == SAFI_MPLS_VPN) { +		struct bgp_node *prn = NULL; +		struct bgp_table *table = NULL; + +		prn = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd); +		if (prn->info) { +			table = (struct bgp_table *)(prn->info); + +			vnc_import_bgp_add_vnc_host_route_mode_resolve_nve( +				bgp, prd, table, p, new); +		} +		bgp_unlock_node(prn); +		encode_label(label_val, &bn->local_label); +	} + +	bgp_unlock_node(bn); +	bgp_process(bgp, bn, afi, safi); + +	vnc_zlog_debug_any( +		"%s: Added route (safi=%s) at prefix %s (bn=%p, prd=%s)", +		__func__, safi2str(safi), buf, bn, buf2);  done: -  /* Loop back to import tables */ -  rfapiProcessUpdate (rfd->peer, -                      rfd, -                      p, prd, new_attr, afi, safi, type, sub_type, &label_val); -  vnc_zlog_debug_verbose ("%s: looped back import route (safi=%d)", __func__, safi); +	/* Loop back to import tables */ +	rfapiProcessUpdate(rfd->peer, rfd, p, prd, new_attr, afi, safi, type, +			   sub_type, &label_val); +	vnc_zlog_debug_verbose("%s: looped back import route (safi=%d)", +			       __func__, safi);  } -uint32_t -rfp_cost_to_localpref (uint8_t cost) +uint32_t rfp_cost_to_localpref(uint8_t cost)  { -  return 255 - cost; +	return 255 - cost;  } -static void -rfapiTunnelRouteAnnounce ( -  struct bgp			*bgp, -  struct rfapi_descriptor	*rfd, -  uint32_t			*pLifetime) +static void rfapiTunnelRouteAnnounce(struct bgp *bgp, +				     struct rfapi_descriptor *rfd, +				     uint32_t *pLifetime)  { -  struct prefix_rd prd; -  struct prefix pfx_vn; -  int rc; -  uint32_t local_pref = rfp_cost_to_localpref (0); - -  rc = rfapiRaddr2Qprefix (&(rfd->vn_addr), &pfx_vn); -  assert (!rc); - -  /* -   * Construct route distinguisher = 0 -   */ -  memset (&prd, 0, sizeof (prd)); -  prd.family = AF_UNSPEC; -  prd.prefixlen = 64; - -  add_vnc_route (rfd,           /* rfapi descr, for export list  & backref */ -                 bgp,           /* which bgp instance */ -                 SAFI_ENCAP,    /* which SAFI */ -                 &pfx_vn,       /* prefix to advertise */ -                 &prd,          /* route distinguisher to use */ -                 &rfd->un_addr, /* nexthop */ -                 &local_pref, -		 pLifetime,     /* max lifetime of child VPN routes */ -                 NULL,          /* no rfp options  for ENCAP safi */ -                 NULL,          /* rfp un options */ -                 NULL,          /* rfp vn options */ -                 rfd->rt_export_list, -		 NULL,          /* med */ -                 NULL,          /* label: default */ -                 ZEBRA_ROUTE_BGP, -		 BGP_ROUTE_RFP, -		 0); +	struct prefix_rd prd; +	struct prefix pfx_vn; +	int rc; +	uint32_t local_pref = rfp_cost_to_localpref(0); + +	rc = rfapiRaddr2Qprefix(&(rfd->vn_addr), &pfx_vn); +	assert(!rc); + +	/* +	 * Construct route distinguisher = 0 +	 */ +	memset(&prd, 0, sizeof(prd)); +	prd.family = AF_UNSPEC; +	prd.prefixlen = 64; + +	add_vnc_route(rfd,	/* rfapi descr, for export list  & backref */ +		      bgp,	/* which bgp instance */ +		      SAFI_ENCAP, /* which SAFI */ +		      &pfx_vn,    /* prefix to advertise */ +		      &prd,       /* route distinguisher to use */ +		      &rfd->un_addr, /* nexthop */ +		      &local_pref, +		      pLifetime, /* max lifetime of child VPN routes */ +		      NULL,      /* no rfp options  for ENCAP safi */ +		      NULL,      /* rfp un options */ +		      NULL,      /* rfp vn options */ +		      rfd->rt_export_list, NULL, /* med */ +		      NULL,			 /* label: default */ +		      ZEBRA_ROUTE_BGP, BGP_ROUTE_RFP, 0);  } @@ -1265,88 +1177,84 @@ rfapiTunnelRouteAnnounce (  /*------------------------------------------   * rfapi_rfp_set_configuration   * - * This is used to change rfapi's processing behavior based on  - * RFP requirements.  + * This is used to change rfapi's processing behavior based on + * RFP requirements.   * - * input:  + * input:   *    rfp_start_val     value returned by rfp_start   *    rfapi_rfp_cfg     Pointer to configuration structure   *   * output:   *    none   * - * return value:  + * return value:   *	0		Success   *	ENXIO		Unabled to locate configured BGP/VNC  --------------------------------------------*/ -int -rfapi_rfp_set_configuration (void *rfp_start_val, struct rfapi_rfp_cfg *new) +int rfapi_rfp_set_configuration(void *rfp_start_val, struct rfapi_rfp_cfg *new)  { -  struct rfapi_rfp_cfg *rcfg; -  struct bgp *bgp; - -  bgp = rfapi_bgp_lookup_by_rfp (rfp_start_val); - -  if (!new || !bgp || !bgp->rfapi_cfg) -    return ENXIO; - -  rcfg = &bgp->rfapi_cfg->rfp_cfg; -  rcfg->download_type = new->download_type; -  rcfg->ftd_advertisement_interval = new->ftd_advertisement_interval; -  rcfg->holddown_factor = new->holddown_factor; - -  if (rcfg->use_updated_response != new->use_updated_response) -    { -      rcfg->use_updated_response = new->use_updated_response; -      if (rcfg->use_updated_response) -        rfapiMonitorCallbacksOn (bgp); -      else -        rfapiMonitorCallbacksOff (bgp); -    } -  if (rcfg->use_removes != new->use_removes) -    { -      rcfg->use_removes = new->use_removes; -      if (rcfg->use_removes) -        rfapiMonitorResponseRemovalOn (bgp); -      else -        rfapiMonitorResponseRemovalOff (bgp); -    } -  return 0; +	struct rfapi_rfp_cfg *rcfg; +	struct bgp *bgp; + +	bgp = rfapi_bgp_lookup_by_rfp(rfp_start_val); + +	if (!new || !bgp || !bgp->rfapi_cfg) +		return ENXIO; + +	rcfg = &bgp->rfapi_cfg->rfp_cfg; +	rcfg->download_type = new->download_type; +	rcfg->ftd_advertisement_interval = new->ftd_advertisement_interval; +	rcfg->holddown_factor = new->holddown_factor; + +	if (rcfg->use_updated_response != new->use_updated_response) { +		rcfg->use_updated_response = new->use_updated_response; +		if (rcfg->use_updated_response) +			rfapiMonitorCallbacksOn(bgp); +		else +			rfapiMonitorCallbacksOff(bgp); +	} +	if (rcfg->use_removes != new->use_removes) { +		rcfg->use_removes = new->use_removes; +		if (rcfg->use_removes) +			rfapiMonitorResponseRemovalOn(bgp); +		else +			rfapiMonitorResponseRemovalOff(bgp); +	} +	return 0;  }  /*------------------------------------------   * rfapi_rfp_set_cb_methods   * - * Change registered callback functions for asynchronous notifications  + * Change registered callback functions for asynchronous notifications   * from RFAPI to the RFP client.   * - * input:  + * input:   *    rfp_start_val     value returned by rfp_start   *    methods		Pointer to struct rfapi_rfp_cb_methods containing   *			pointers to callback methods as described above   * - * return value:  + * return value:   *	0		Success   *	ENXIO		BGP or VNC not configured   *------------------------------------------*/ -int -rfapi_rfp_set_cb_methods (void *rfp_start_val, -                          struct rfapi_rfp_cb_methods *methods) +int rfapi_rfp_set_cb_methods(void *rfp_start_val, +			     struct rfapi_rfp_cb_methods *methods)  { -  struct rfapi *h; -  struct bgp *bgp; +	struct rfapi *h; +	struct bgp *bgp; -  bgp = rfapi_bgp_lookup_by_rfp (rfp_start_val); -  if (!bgp) -    return ENXIO; +	bgp = rfapi_bgp_lookup_by_rfp(rfp_start_val); +	if (!bgp) +		return ENXIO; -  h = bgp->rfapi; -  if (!h) -    return ENXIO; +	h = bgp->rfapi; +	if (!h) +		return ENXIO; -  h->rfp_methods = *methods; +	h->rfp_methods = *methods; -  return 0; +	return 0;  }  /*********************************************************************** @@ -1358,570 +1266,520 @@ rfapi_rfp_set_cb_methods (void *rfp_start_val,   * The advertised_prefixes[] array elements should be NULL to   * have this function set them to newly-allocated radix trees.   */ -static int -rfapi_open_inner ( -  struct rfapi_descriptor	*rfd, -  struct bgp			*bgp, -  struct rfapi			*h, -  struct rfapi_nve_group_cfg	*rfg) +static int rfapi_open_inner(struct rfapi_descriptor *rfd, struct bgp *bgp, +			    struct rfapi *h, struct rfapi_nve_group_cfg *rfg)  { -  int ret; - -  if (h->flags & RFAPI_INCALLBACK) -    return EDEADLK; +	int ret; + +	if (h->flags & RFAPI_INCALLBACK) +		return EDEADLK; + +	/* +	 * Fill in configured fields +	 */ + +	/* +	 * If group's RD is specified as "auto", then fill in based +	 * on NVE's VN address +	 */ +	rfd->rd = rfg->rd; + +	if (rfd->rd.family == AF_UNIX) { +		ret = rfapi_set_autord_from_vn(&rfd->rd, &rfd->vn_addr); +		if (ret != 0) +			return ret; +	} +	rfd->rt_export_list = (rfg->rt_export_list) +				      ? ecommunity_dup(rfg->rt_export_list) +				      : NULL; +	rfd->response_lifetime = rfg->response_lifetime; +	rfd->rfg = rfg; + +	/* +	 * Fill in BGP peer structure +	 */ +	rfd->peer = peer_new(bgp); +	rfd->peer->status = Established; /* keep bgp core happy */ +	bgp_sync_delete(rfd->peer);      /* don't need these */ +	if (rfd->peer->ibuf) { +		stream_free(rfd->peer->ibuf); /* don't need it */ +		rfd->peer->ibuf = NULL; +	} +	if (rfd->peer->obuf) { +		stream_fifo_free(rfd->peer->obuf); /* don't need it */ +		rfd->peer->obuf = NULL; +	} +	if (rfd->peer->work) { +		stream_free(rfd->peer->work); /* don't need it */ +		rfd->peer->work = NULL; +	} +	{ /* base code assumes have valid host pointer */ +		char buf[BUFSIZ]; +		buf[0] = 0; + +		if (rfd->vn_addr.addr_family == AF_INET) { +			inet_ntop(AF_INET, &rfd->vn_addr.addr.v4, buf, BUFSIZ); +		} else if (rfd->vn_addr.addr_family == AF_INET6) { +			inet_ntop(AF_INET6, &rfd->vn_addr.addr.v6, buf, BUFSIZ); +		} +		rfd->peer->host = XSTRDUP(MTYPE_BGP_PEER_HOST, buf); +	} +	/* Mark peer as belonging to HD */ +	SET_FLAG(rfd->peer->flags, PEER_FLAG_IS_RFAPI_HD); + +	/* +	 * Set min prefix lifetime to max value so it will get set +	 * upon first rfapi_register() +	 */ +	rfd->min_prefix_lifetime = UINT32_MAX; -  /* -   * Fill in configured fields -   */ - -  /* -   * If group's RD is specified as "auto", then fill in based -   * on NVE's VN address -   */ -  rfd->rd = rfg->rd; - -  if (rfd->rd.family == AF_UNIX) -    { -      ret = rfapi_set_autord_from_vn (&rfd->rd, &rfd->vn_addr); -      if (ret != 0) -        return ret; -    } -  rfd->rt_export_list = (rfg->rt_export_list) ? -    ecommunity_dup (rfg->rt_export_list) : NULL; -  rfd->response_lifetime = rfg->response_lifetime; -  rfd->rfg = rfg; - -  /* -   * Fill in BGP peer structure -   */ -  rfd->peer = peer_new (bgp); -  rfd->peer->status = Established; /* keep bgp core happy */ -  bgp_sync_delete (rfd->peer);  /* don't need these */ -  if (rfd->peer->ibuf) -    { -      stream_free (rfd->peer->ibuf);    /* don't need it */ -      rfd->peer->ibuf = NULL; -    } -  if (rfd->peer->obuf) -    { -      stream_fifo_free (rfd->peer->obuf);       /* don't need it */ -      rfd->peer->obuf = NULL; -    } -  if (rfd->peer->work) -    { -      stream_free (rfd->peer->work);    /* don't need it */ -      rfd->peer->work = NULL; -    } -  {                             /* base code assumes have valid host pointer */ -    char buf[BUFSIZ]; -    buf[0] = 0; - -    if (rfd->vn_addr.addr_family == AF_INET) -      { -        inet_ntop (AF_INET, &rfd->vn_addr.addr.v4, buf, BUFSIZ); -      } -    else if (rfd->vn_addr.addr_family == AF_INET6) -      { -        inet_ntop (AF_INET6, &rfd->vn_addr.addr.v6, buf, BUFSIZ); -      } -    rfd->peer->host = XSTRDUP (MTYPE_BGP_PEER_HOST, buf); -  } -  /* Mark peer as belonging to HD */ -  SET_FLAG (rfd->peer->flags, PEER_FLAG_IS_RFAPI_HD); - -  /* -   * Set min prefix lifetime to max value so it will get set -   * upon first rfapi_register() -   */ -  rfd->min_prefix_lifetime = UINT32_MAX; - -  /* -   * Allocate response tables if needed -   */ -#define RFD_RTINIT_AFI(rh, ary, afi) do {\ -  if (!ary[afi]) {    \ -    ary[afi] = route_table_init ();\ -    ary[afi]->info = rh;\ -  }\ -} while (0) - -#define RFD_RTINIT(rh, ary) do {\ -    RFD_RTINIT_AFI(rh, ary, AFI_IP);\ -    RFD_RTINIT_AFI(rh, ary, AFI_IP6);\ -    RFD_RTINIT_AFI(rh, ary, AFI_L2VPN);\ -} while(0) - -  RFD_RTINIT(rfd, rfd->rib); -  RFD_RTINIT(rfd, rfd->rib_pending); -  RFD_RTINIT(rfd, rfd->rsp_times); - -  /* -   * Link to Import Table -   */ -  rfd->import_table = rfg->rfapi_import_table; -  rfd->import_table->refcount += 1; - -  rfapiApInit (&rfd->advertised); - -  /* -   * add this NVE descriptor to the list of NVEs in the NVE group -   */ -  if (!rfg->nves) -    { -      rfg->nves = list_new (); -    } -  listnode_add (rfg->nves, rfd); - -  vnc_direct_bgp_add_nve (bgp, rfd); -  vnc_zebra_add_nve (bgp, rfd); - -  return 0; +/* + * Allocate response tables if needed + */ +#define RFD_RTINIT_AFI(rh, ary, afi)                                           \ +	do {                                                                   \ +		if (!ary[afi]) {                                               \ +			ary[afi] = route_table_init();                         \ +			ary[afi]->info = rh;                                   \ +		}                                                              \ +	} while (0) + +#define RFD_RTINIT(rh, ary)                                                    \ +	do {                                                                   \ +		RFD_RTINIT_AFI(rh, ary, AFI_IP);                               \ +		RFD_RTINIT_AFI(rh, ary, AFI_IP6);                              \ +		RFD_RTINIT_AFI(rh, ary, AFI_L2VPN);                            \ +	} while (0) + +	RFD_RTINIT(rfd, rfd->rib); +	RFD_RTINIT(rfd, rfd->rib_pending); +	RFD_RTINIT(rfd, rfd->rsp_times); + +	/* +	 * Link to Import Table +	 */ +	rfd->import_table = rfg->rfapi_import_table; +	rfd->import_table->refcount += 1; + +	rfapiApInit(&rfd->advertised); + +	/* +	 * add this NVE descriptor to the list of NVEs in the NVE group +	 */ +	if (!rfg->nves) { +		rfg->nves = list_new(); +	} +	listnode_add(rfg->nves, rfd); + +	vnc_direct_bgp_add_nve(bgp, rfd); +	vnc_zebra_add_nve(bgp, rfd); + +	return 0;  }  /* moved from rfapi_register */ -int -rfapi_init_and_open( -  struct bgp			*bgp, -  struct rfapi_descriptor	*rfd, -  struct rfapi_nve_group_cfg	*rfg) +int rfapi_init_and_open(struct bgp *bgp, struct rfapi_descriptor *rfd, +			struct rfapi_nve_group_cfg *rfg)  { -  struct rfapi *h = bgp->rfapi; -  char buf_vn[BUFSIZ]; -  char buf_un[BUFSIZ]; -  afi_t afi_vn, afi_un; -  struct prefix pfx_un; -  struct route_node             *rn; - - -  rfapi_time (&rfd->open_time); - -  if (rfg->type == RFAPI_GROUP_CFG_VRF) -    SET_FLAG(rfd->flags, RFAPI_HD_FLAG_IS_VRF); - -  rfapiRfapiIpAddr2Str (&rfd->vn_addr, buf_vn, BUFSIZ); -  rfapiRfapiIpAddr2Str (&rfd->un_addr, buf_un, BUFSIZ); - -  vnc_zlog_debug_verbose ("%s: new RFD with VN=%s UN=%s cookie=%p", -                          __func__, buf_vn, buf_un, rfd->cookie); - -  if (rfg->type != RFAPI_GROUP_CFG_VRF) /* unclear if needed for VRF */ -    { -      listnode_add (&h->descriptors, rfd); -      if (h->descriptors.count > h->stat.max_descriptors) -        { -          h->stat.max_descriptors = h->descriptors.count; -        } - -      /* -       * attach to UN radix tree -       */ -      afi_vn = family2afi (rfd->vn_addr.addr_family); -      afi_un = family2afi (rfd->un_addr.addr_family); -      assert (afi_vn && afi_un); -      assert (!rfapiRaddr2Qprefix (&rfd->un_addr, &pfx_un)); - -      rn = route_node_get (&(h->un[afi_un]), &pfx_un); -      assert (rn); -      rfd->next = rn->info; -      rn->info = rfd; -      rfd->un_node = rn; -    }   -  return rfapi_open_inner (rfd, bgp, h, rfg); +	struct rfapi *h = bgp->rfapi; +	char buf_vn[BUFSIZ]; +	char buf_un[BUFSIZ]; +	afi_t afi_vn, afi_un; +	struct prefix pfx_un; +	struct route_node *rn; + + +	rfapi_time(&rfd->open_time); + +	if (rfg->type == RFAPI_GROUP_CFG_VRF) +		SET_FLAG(rfd->flags, RFAPI_HD_FLAG_IS_VRF); + +	rfapiRfapiIpAddr2Str(&rfd->vn_addr, buf_vn, BUFSIZ); +	rfapiRfapiIpAddr2Str(&rfd->un_addr, buf_un, BUFSIZ); + +	vnc_zlog_debug_verbose("%s: new RFD with VN=%s UN=%s cookie=%p", +			       __func__, buf_vn, buf_un, rfd->cookie); + +	if (rfg->type != RFAPI_GROUP_CFG_VRF) /* unclear if needed for VRF */ +	{ +		listnode_add(&h->descriptors, rfd); +		if (h->descriptors.count > h->stat.max_descriptors) { +			h->stat.max_descriptors = h->descriptors.count; +		} + +		/* +		 * attach to UN radix tree +		 */ +		afi_vn = family2afi(rfd->vn_addr.addr_family); +		afi_un = family2afi(rfd->un_addr.addr_family); +		assert(afi_vn && afi_un); +		assert(!rfapiRaddr2Qprefix(&rfd->un_addr, &pfx_un)); + +		rn = route_node_get(&(h->un[afi_un]), &pfx_un); +		assert(rn); +		rfd->next = rn->info; +		rn->info = rfd; +		rfd->un_node = rn; +	} +	return rfapi_open_inner(rfd, bgp, h, rfg);  } -struct rfapi_vn_option * -rfapiVnOptionsDup (struct rfapi_vn_option *orig) +struct rfapi_vn_option *rfapiVnOptionsDup(struct rfapi_vn_option *orig)  { -  struct rfapi_vn_option *head = NULL; -  struct rfapi_vn_option *tail = NULL; -  struct rfapi_vn_option *vo = NULL; - -  for (vo = orig; vo; vo = vo->next) -    { -      struct rfapi_vn_option *new; - -      new = XCALLOC (MTYPE_RFAPI_VN_OPTION, sizeof (struct rfapi_vn_option)); -      memcpy (new, vo, sizeof (struct rfapi_vn_option)); -      new->next = NULL; - -      if (tail) -        { -          tail->next = new; -        } -      else -        { -          head = tail = new; -        } -    } -  return head; +	struct rfapi_vn_option *head = NULL; +	struct rfapi_vn_option *tail = NULL; +	struct rfapi_vn_option *vo = NULL; + +	for (vo = orig; vo; vo = vo->next) { +		struct rfapi_vn_option *new; + +		new = XCALLOC(MTYPE_RFAPI_VN_OPTION, +			      sizeof(struct rfapi_vn_option)); +		memcpy(new, vo, sizeof(struct rfapi_vn_option)); +		new->next = NULL; + +		if (tail) { +			tail->next = new; +		} else { +			head = tail = new; +		} +	} +	return head;  } -struct rfapi_un_option * -rfapiUnOptionsDup (struct rfapi_un_option *orig) +struct rfapi_un_option *rfapiUnOptionsDup(struct rfapi_un_option *orig)  { -  struct rfapi_un_option *head = NULL; -  struct rfapi_un_option *tail = NULL; -  struct rfapi_un_option *uo = NULL; - -  for (uo = orig; uo; uo = uo->next) -    { -      struct rfapi_un_option *new; - -      new = XCALLOC (MTYPE_RFAPI_UN_OPTION, sizeof (struct rfapi_un_option)); -      memcpy (new, uo, sizeof (struct rfapi_un_option)); -      new->next = NULL; - -      if (tail) -        { -          tail->next = new; -        } -      else -        { -          head = tail = new; -        } -    } -  return head; +	struct rfapi_un_option *head = NULL; +	struct rfapi_un_option *tail = NULL; +	struct rfapi_un_option *uo = NULL; + +	for (uo = orig; uo; uo = uo->next) { +		struct rfapi_un_option *new; + +		new = XCALLOC(MTYPE_RFAPI_UN_OPTION, +			      sizeof(struct rfapi_un_option)); +		memcpy(new, uo, sizeof(struct rfapi_un_option)); +		new->next = NULL; + +		if (tail) { +			tail->next = new; +		} else { +			head = tail = new; +		} +	} +	return head;  } -struct bgp_tea_options * -rfapiOptionsDup (struct bgp_tea_options *orig) +struct bgp_tea_options *rfapiOptionsDup(struct bgp_tea_options *orig)  { -  struct bgp_tea_options *head = NULL; -  struct bgp_tea_options *tail = NULL; -  struct bgp_tea_options *hop = NULL; - -  for (hop = orig; hop; hop = hop->next) -    { -      struct bgp_tea_options *new; - -      new = XCALLOC (MTYPE_BGP_TEA_OPTIONS, sizeof (struct bgp_tea_options)); -      memcpy (new, hop, sizeof (struct bgp_tea_options)); -      new->next = NULL; -      if (hop->value) -        { -          new->value = XCALLOC (MTYPE_BGP_TEA_OPTIONS_VALUE, hop->length); -          memcpy (new->value, hop->value, hop->length); -        } -      if (tail) -        { -          tail->next = new; -        } -      else -        { -          head = tail = new; -        } -    } -  return head; +	struct bgp_tea_options *head = NULL; +	struct bgp_tea_options *tail = NULL; +	struct bgp_tea_options *hop = NULL; + +	for (hop = orig; hop; hop = hop->next) { +		struct bgp_tea_options *new; + +		new = XCALLOC(MTYPE_BGP_TEA_OPTIONS, +			      sizeof(struct bgp_tea_options)); +		memcpy(new, hop, sizeof(struct bgp_tea_options)); +		new->next = NULL; +		if (hop->value) { +			new->value = XCALLOC(MTYPE_BGP_TEA_OPTIONS_VALUE, +					     hop->length); +			memcpy(new->value, hop->value, hop->length); +		} +		if (tail) { +			tail->next = new; +		} else { +			head = tail = new; +		} +	} +	return head;  } -void -rfapiFreeBgpTeaOptionChain (struct bgp_tea_options *p) +void rfapiFreeBgpTeaOptionChain(struct bgp_tea_options *p)  { -  struct bgp_tea_options *next; +	struct bgp_tea_options *next; -  while (p) -    { -      next = p->next; +	while (p) { +		next = p->next; -      if (p->value) -        { -          XFREE (MTYPE_BGP_TEA_OPTIONS_VALUE, p->value); -          p->value = NULL; -        } -      XFREE (MTYPE_BGP_TEA_OPTIONS, p); +		if (p->value) { +			XFREE(MTYPE_BGP_TEA_OPTIONS_VALUE, p->value); +			p->value = NULL; +		} +		XFREE(MTYPE_BGP_TEA_OPTIONS, p); -      p = next; -    } +		p = next; +	}  } -void -rfapiAdbFree (struct rfapi_adb *adb) +void rfapiAdbFree(struct rfapi_adb *adb)  { -  XFREE (MTYPE_RFAPI_ADB, adb); +	XFREE(MTYPE_RFAPI_ADB, adb);  }  static int -rfapi_query_inner ( -  void				*handle, -  struct rfapi_ip_addr		*target, -  struct rfapi_l2address_option	*l2o,      /* may be NULL */ -  struct rfapi_next_hop_entry	**ppNextHopEntry) +rfapi_query_inner(void *handle, struct rfapi_ip_addr *target, +		  struct rfapi_l2address_option *l2o, /* may be NULL */ +		  struct rfapi_next_hop_entry **ppNextHopEntry)  { -  afi_t                         afi; -  struct prefix                 p; -  struct prefix                 p_original; -  struct route_node             *rn; -  struct rfapi_descriptor       *rfd = (struct rfapi_descriptor *) handle; -  struct bgp                    *bgp = rfd->bgp; -  struct rfapi_next_hop_entry   *pNHE = NULL; -  struct rfapi_ip_addr          *self_vn_addr = NULL; -  int                           eth_is_0 = 0; -  int                           use_eth_resolution = 0; -  struct rfapi_next_hop_entry   *i_nhe; - -  /* preemptive */ -  if (!bgp) -    { -      vnc_zlog_debug_verbose ("%s: No BGP instance, returning ENXIO", __func__); -      return ENXIO; -    } -  if (!bgp->rfapi) -    { -      vnc_zlog_debug_verbose ("%s: No RFAPI instance, returning ENXIO", __func__); -      return ENXIO; -    } -  if (bgp->rfapi->flags & RFAPI_INCALLBACK) -    { -      vnc_zlog_debug_verbose ("%s: Called during calback, returning EDEADLK", __func__); -      return EDEADLK; -    } - -  if (!is_valid_rfd (rfd)) -    { -      vnc_zlog_debug_verbose ("%s: invalid handle, returning EBADF", __func__); -      return EBADF; -    } - -  rfd->rsp_counter++;                 /* dedup: identify this generation */ -  rfd->rsp_time = rfapi_time (NULL); /* response content dedup */ -  rfd->ftd_last_allowed_time = -    bgp_clock() - bgp->rfapi_cfg->rfp_cfg.ftd_advertisement_interval; - -  if (l2o) -    { -      if (!memcmp (l2o->macaddr.octet, rfapi_ethaddr0.octet, ETHER_ADDR_LEN)) -        { -          eth_is_0 = 1; -        } -      /* per t/c Paul/Lou 151022 */ -      if (!eth_is_0 || l2o->logical_net_id) -        { -          use_eth_resolution = 1; -        } -    } - -  if (ppNextHopEntry) -    *ppNextHopEntry = NULL; - -  /* -   * Save original target in prefix form. In case of L2-based queries, -   * p_original will be modified to reflect the L2 target -   */ -  assert(!rfapiRaddr2Qprefix (target, &p_original)); - -  if (bgp->rfapi_cfg->rfp_cfg.download_type == RFAPI_RFP_DOWNLOAD_FULL) -    { -      /* convert query to 0/0 when full-table download is enabled */ -      memset ((char *) &p, 0, sizeof (p)); -      p.family = target->addr_family; -    } -  else -    { -      p = p_original; -    } - -  { -    char buf[BUFSIZ]; -    char *s; - -    prefix2str (&p, buf, BUFSIZ); -    buf[BUFSIZ - 1] = 0;        /* guarantee NUL-terminated */ -    vnc_zlog_debug_verbose ("%s(rfd=%p, target=%s, ppNextHop=%p)", -                __func__, rfd, buf, ppNextHopEntry); - -    s = ecommunity_ecom2str(rfd->import_table->rt_import_list, -                            ECOMMUNITY_FORMAT_ROUTE_MAP, 0); -    vnc_zlog_debug_verbose("%s rfd->import_table=%p, rfd->import_table->rt_import_list: %s", -        __func__, rfd->import_table, s); XFREE (MTYPE_ECOMMUNITY_STR, s); -  } - -  afi = family2afi (p.family); -  assert (afi); - -  if (CHECK_FLAG (bgp->rfapi_cfg->flags, BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP)) -    { -      self_vn_addr = &rfd->vn_addr; -    } - -  if (use_eth_resolution) -    { -      uint32_t logical_net_id = l2o->logical_net_id; -      struct ecommunity *l2com; - -      /* -       * fix up p_original to contain L2 address -       */ -      rfapiL2o2Qprefix (l2o, &p_original); - -      l2com = -        bgp_rfapi_get_ecommunity_by_lni_label (bgp, 1, logical_net_id, -                                               l2o->label); -      if (l2com) -        { -          uint8_t *v = l2com->val; -          logical_net_id = (v[5] << 16) + (v[6] << 8) + (v[7]); -        } -      /* -       * Ethernet/L2-based lookup -       * -       * Always returns IT node corresponding to route -       */ - -      if (RFAPI_RFP_DOWNLOAD_FULL == bgp->rfapi_cfg->rfp_cfg.download_type) -        { -          eth_is_0 = 1; -        } - -      rn = rfapiMonitorEthAdd (bgp, -                               rfd, -                               (eth_is_0 ? &rfapi_ethaddr0 : &l2o->macaddr), -                               logical_net_id); - -      if (eth_is_0) -        { -          struct rfapi_ip_prefix rprefix; - -          memset (&rprefix, 0, sizeof (rprefix)); -          rprefix.prefix.addr_family = target->addr_family; -          if (target->addr_family == AF_INET) -            { -              rprefix.length = 32; -            } -          else -            { -              rprefix.length = 128; -            } - -          pNHE = rfapiEthRouteTable2NextHopList (logical_net_id, &rprefix, -            rfd->response_lifetime, self_vn_addr, rfd->rib[afi], &p_original); -          goto done; -        } - -    } -  else -    { - -      /* -       * IP-based lookup -       */ - -      rn = rfapiMonitorAdd (bgp, rfd, &p); - -      /* -       * If target address is 0, this request is special: means to -       * return ALL routes in the table -       *  -       * Monitors for All-Routes queries get put on a special list, -       * not in the VPN tree -       */ -      if (RFAPI_0_PREFIX (&p)) -        { - -          vnc_zlog_debug_verbose ("%s: 0-prefix", __func__); - -          /* -           * Generate nexthop list for caller -           */ -          pNHE = rfapiRouteTable2NextHopList ( -	    rfd->import_table->imported_vpn[afi], rfd->response_lifetime, -            self_vn_addr, rfd->rib[afi], &p_original); -          goto done; -        } - -      if (rn) -        { -          route_lock_node (rn); /* so we can unlock below */ -        } -      else -        { -          /* -           * returns locked node. Don't unlock yet because the unlock -           * might free it before we're done with it. This situation -           * could occur when rfapiMonitorGetAttachNode() returns a -           * newly-created default node. -           */ -          rn = rfapiMonitorGetAttachNode (rfd, &p); -        } -    } - -  assert (rn); -  if (!rn->info) -    { -      route_unlock_node (rn); -      vnc_zlog_debug_verbose ("%s: VPN route not found, returning ENOENT", __func__); -      return ENOENT; -    } - -  if (VNC_DEBUG(RFAPI_QUERY)) -    { -      rfapiShowImportTable (NULL, "query", rfd->import_table->imported_vpn[afi], -                        1); -    } - -  if (use_eth_resolution) -    { - -      struct rfapi_ip_prefix rprefix; - -      memset (&rprefix, 0, sizeof (rprefix)); -      rprefix.prefix.addr_family = target->addr_family; -      if (target->addr_family == AF_INET) -        { -          rprefix.length = 32; -        } -      else -        { -          rprefix.length = 128; -        } - -      pNHE = rfapiEthRouteNode2NextHopList (rn, &rprefix, -        rfd->response_lifetime, self_vn_addr, rfd->rib[afi], &p_original); - - -    } -  else -    { -      /*  -       * Generate answer to query -       */ -      pNHE = rfapiRouteNode2NextHopList(rn, rfd->response_lifetime, -        self_vn_addr, rfd->rib[afi], &p_original); -    } - -  route_unlock_node (rn); +	afi_t afi; +	struct prefix p; +	struct prefix p_original; +	struct route_node *rn; +	struct rfapi_descriptor *rfd = (struct rfapi_descriptor *)handle; +	struct bgp *bgp = rfd->bgp; +	struct rfapi_next_hop_entry *pNHE = NULL; +	struct rfapi_ip_addr *self_vn_addr = NULL; +	int eth_is_0 = 0; +	int use_eth_resolution = 0; +	struct rfapi_next_hop_entry *i_nhe; + +	/* preemptive */ +	if (!bgp) { +		vnc_zlog_debug_verbose("%s: No BGP instance, returning ENXIO", +				       __func__); +		return ENXIO; +	} +	if (!bgp->rfapi) { +		vnc_zlog_debug_verbose("%s: No RFAPI instance, returning ENXIO", +				       __func__); +		return ENXIO; +	} +	if (bgp->rfapi->flags & RFAPI_INCALLBACK) { +		vnc_zlog_debug_verbose( +			"%s: Called during calback, returning EDEADLK", +			__func__); +		return EDEADLK; +	} + +	if (!is_valid_rfd(rfd)) { +		vnc_zlog_debug_verbose("%s: invalid handle, returning EBADF", +				       __func__); +		return EBADF; +	} + +	rfd->rsp_counter++;		  /* dedup: identify this generation */ +	rfd->rsp_time = rfapi_time(NULL); /* response content dedup */ +	rfd->ftd_last_allowed_time = +		bgp_clock() +		- bgp->rfapi_cfg->rfp_cfg.ftd_advertisement_interval; + +	if (l2o) { +		if (!memcmp(l2o->macaddr.octet, rfapi_ethaddr0.octet, +			    ETHER_ADDR_LEN)) { +			eth_is_0 = 1; +		} +		/* per t/c Paul/Lou 151022 */ +		if (!eth_is_0 || l2o->logical_net_id) { +			use_eth_resolution = 1; +		} +	} + +	if (ppNextHopEntry) +		*ppNextHopEntry = NULL; + +	/* +	 * Save original target in prefix form. In case of L2-based queries, +	 * p_original will be modified to reflect the L2 target +	 */ +	assert(!rfapiRaddr2Qprefix(target, &p_original)); + +	if (bgp->rfapi_cfg->rfp_cfg.download_type == RFAPI_RFP_DOWNLOAD_FULL) { +		/* convert query to 0/0 when full-table download is enabled */ +		memset((char *)&p, 0, sizeof(p)); +		p.family = target->addr_family; +	} else { +		p = p_original; +	} + +	{ +		char buf[BUFSIZ]; +		char *s; + +		prefix2str(&p, buf, BUFSIZ); +		buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */ +		vnc_zlog_debug_verbose("%s(rfd=%p, target=%s, ppNextHop=%p)", +				       __func__, rfd, buf, ppNextHopEntry); + +		s = ecommunity_ecom2str(rfd->import_table->rt_import_list, +					ECOMMUNITY_FORMAT_ROUTE_MAP, 0); +		vnc_zlog_debug_verbose( +			"%s rfd->import_table=%p, rfd->import_table->rt_import_list: %s", +			__func__, rfd->import_table, s); +		XFREE(MTYPE_ECOMMUNITY_STR, s); +	} + +	afi = family2afi(p.family); +	assert(afi); + +	if (CHECK_FLAG(bgp->rfapi_cfg->flags, +		       BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP)) { +		self_vn_addr = &rfd->vn_addr; +	} + +	if (use_eth_resolution) { +		uint32_t logical_net_id = l2o->logical_net_id; +		struct ecommunity *l2com; + +		/* +		 * fix up p_original to contain L2 address +		 */ +		rfapiL2o2Qprefix(l2o, &p_original); + +		l2com = bgp_rfapi_get_ecommunity_by_lni_label( +			bgp, 1, logical_net_id, l2o->label); +		if (l2com) { +			uint8_t *v = l2com->val; +			logical_net_id = (v[5] << 16) + (v[6] << 8) + (v[7]); +		} +		/* +		 * Ethernet/L2-based lookup +		 * +		 * Always returns IT node corresponding to route +		 */ + +		if (RFAPI_RFP_DOWNLOAD_FULL +		    == bgp->rfapi_cfg->rfp_cfg.download_type) { +			eth_is_0 = 1; +		} + +		rn = rfapiMonitorEthAdd( +			bgp, rfd, (eth_is_0 ? &rfapi_ethaddr0 : &l2o->macaddr), +			logical_net_id); + +		if (eth_is_0) { +			struct rfapi_ip_prefix rprefix; + +			memset(&rprefix, 0, sizeof(rprefix)); +			rprefix.prefix.addr_family = target->addr_family; +			if (target->addr_family == AF_INET) { +				rprefix.length = 32; +			} else { +				rprefix.length = 128; +			} + +			pNHE = rfapiEthRouteTable2NextHopList( +				logical_net_id, &rprefix, +				rfd->response_lifetime, self_vn_addr, +				rfd->rib[afi], &p_original); +			goto done; +		} + +	} else { + +		/* +		 * IP-based lookup +		 */ + +		rn = rfapiMonitorAdd(bgp, rfd, &p); + +		/* +		 * If target address is 0, this request is special: means to +		 * return ALL routes in the table +		 * +		 * Monitors for All-Routes queries get put on a special list, +		 * not in the VPN tree +		 */ +		if (RFAPI_0_PREFIX(&p)) { + +			vnc_zlog_debug_verbose("%s: 0-prefix", __func__); + +			/* +			 * Generate nexthop list for caller +			 */ +			pNHE = rfapiRouteTable2NextHopList( +				rfd->import_table->imported_vpn[afi], +				rfd->response_lifetime, self_vn_addr, +				rfd->rib[afi], &p_original); +			goto done; +		} + +		if (rn) { +			route_lock_node(rn); /* so we can unlock below */ +		} else { +			/* +			 * returns locked node. Don't unlock yet because the +			 * unlock +			 * might free it before we're done with it. This +			 * situation +			 * could occur when rfapiMonitorGetAttachNode() returns +			 * a +			 * newly-created default node. +			 */ +			rn = rfapiMonitorGetAttachNode(rfd, &p); +		} +	} + +	assert(rn); +	if (!rn->info) { +		route_unlock_node(rn); +		vnc_zlog_debug_verbose( +			"%s: VPN route not found, returning ENOENT", __func__); +		return ENOENT; +	} + +	if (VNC_DEBUG(RFAPI_QUERY)) { +		rfapiShowImportTable(NULL, "query", +				     rfd->import_table->imported_vpn[afi], 1); +	} + +	if (use_eth_resolution) { + +		struct rfapi_ip_prefix rprefix; + +		memset(&rprefix, 0, sizeof(rprefix)); +		rprefix.prefix.addr_family = target->addr_family; +		if (target->addr_family == AF_INET) { +			rprefix.length = 32; +		} else { +			rprefix.length = 128; +		} + +		pNHE = rfapiEthRouteNode2NextHopList( +			rn, &rprefix, rfd->response_lifetime, self_vn_addr, +			rfd->rib[afi], &p_original); + + +	} else { +		/* +		 * Generate answer to query +		 */ +		pNHE = rfapiRouteNode2NextHopList(rn, rfd->response_lifetime, +						  self_vn_addr, rfd->rib[afi], +						  &p_original); +	} + +	route_unlock_node(rn);  done: -  if (ppNextHopEntry) -    { -       /* only count if caller gets it */ -       ++bgp->rfapi->response_immediate_count; -    } - -  if (!pNHE) -    { -      vnc_zlog_debug_verbose ("%s: NO NHEs, returning ENOENT", __func__); -      return ENOENT; -    } - -  /* -   * count nexthops for statistics -   */ -  for (i_nhe = pNHE; i_nhe; i_nhe = i_nhe->next) -    { -      ++rfd->stat_count_nh_reachable; -    } - -  if (ppNextHopEntry) -    { -      *ppNextHopEntry = pNHE; -    } -  else -    { -      rfapi_free_next_hop_list (pNHE); -    } - -  vnc_zlog_debug_verbose ("%s: success", __func__); -  return 0; +	if (ppNextHopEntry) { +		/* only count if caller gets it */ +		++bgp->rfapi->response_immediate_count; +	} + +	if (!pNHE) { +		vnc_zlog_debug_verbose("%s: NO NHEs, returning ENOENT", +				       __func__); +		return ENOENT; +	} + +	/* +	 * count nexthops for statistics +	 */ +	for (i_nhe = pNHE; i_nhe; i_nhe = i_nhe->next) { +		++rfd->stat_count_nh_reachable; +	} + +	if (ppNextHopEntry) { +		*ppNextHopEntry = pNHE; +	} else { +		rfapi_free_next_hop_list(pNHE); +	} + +	vnc_zlog_debug_verbose("%s: success", __func__); +	return 0;  }  /* @@ -1929,68 +1787,63 @@ done:   * nve-group in the event that its original nve-group is   * administratively deleted.   */ -static int -rfapi_open_rfd (struct rfapi_descriptor *rfd, struct bgp *bgp) +static int rfapi_open_rfd(struct rfapi_descriptor *rfd, struct bgp *bgp)  { -  struct prefix pfx_vn; -  struct prefix pfx_un; -  struct rfapi_nve_group_cfg *rfg; -  struct rfapi *h; -  struct rfapi_cfg *hc; -  int rc; - -  h = bgp->rfapi; -  if (!h) -    return ENXIO; - -  hc = bgp->rfapi_cfg; -  if (!hc) -    return ENXIO; - -  rc = rfapiRaddr2Qprefix (&rfd->vn_addr, &pfx_vn); -  assert (!rc); - -  rc = rfapiRaddr2Qprefix (&rfd->un_addr, &pfx_un); -  assert (!rc); - -  /* -   * Find the matching nve group config block -   */ -  rfg = bgp_rfapi_cfg_match_group (hc, &pfx_vn, &pfx_un); -  if (!rfg) -    { -      return ENOENT; -    } - -  /* -   * check nve group config block for required values -   */ -  if (!rfg->rt_export_list || !rfg->rfapi_import_table) -    { - -      return ENOMSG; -    } - -  rc = rfapi_open_inner (rfd, bgp, h, rfg); -  if (rc) -    { -      return rc; -    } - -  /* -   * re-advertise registered routes, this time as part of new NVE-group -   */ -  rfapiApReadvertiseAll (bgp, rfd); - -  /* -   * re-attach callbacks to import table -   */ -  if (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE)) -    { -      rfapiMonitorAttachImportHd (rfd); -    } - -  return 0; +	struct prefix pfx_vn; +	struct prefix pfx_un; +	struct rfapi_nve_group_cfg *rfg; +	struct rfapi *h; +	struct rfapi_cfg *hc; +	int rc; + +	h = bgp->rfapi; +	if (!h) +		return ENXIO; + +	hc = bgp->rfapi_cfg; +	if (!hc) +		return ENXIO; + +	rc = rfapiRaddr2Qprefix(&rfd->vn_addr, &pfx_vn); +	assert(!rc); + +	rc = rfapiRaddr2Qprefix(&rfd->un_addr, &pfx_un); +	assert(!rc); + +	/* +	 * Find the matching nve group config block +	 */ +	rfg = bgp_rfapi_cfg_match_group(hc, &pfx_vn, &pfx_un); +	if (!rfg) { +		return ENOENT; +	} + +	/* +	 * check nve group config block for required values +	 */ +	if (!rfg->rt_export_list || !rfg->rfapi_import_table) { + +		return ENOMSG; +	} + +	rc = rfapi_open_inner(rfd, bgp, h, rfg); +	if (rc) { +		return rc; +	} + +	/* +	 * re-advertise registered routes, this time as part of new NVE-group +	 */ +	rfapiApReadvertiseAll(bgp, rfd); + +	/* +	 * re-attach callbacks to import table +	 */ +	if (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE)) { +		rfapiMonitorAttachImportHd(rfd); +	} + +	return 0;  }  /*------------------------------------------ @@ -1999,7 +1852,7 @@ rfapi_open_rfd (struct rfapi_descriptor *rfd, struct bgp *bgp)   * This function initializes a NVE record and associates it with   * the specified VN and underlay network addresses   * - * input:  + * input:   *      rfp_start_val   value returned by rfp_start   *	vn		NVE virtual network address   * @@ -2017,13 +1870,13 @@ rfapi_open_rfd (struct rfapi_descriptor *rfd, struct bgp *bgp)   *   * output:   *	response_lifetime The length of time that responses sent to this - *			NVE are valid.  + *			NVE are valid.   *   *	pHandle		pointer to location to store rfapi handle. The   *			handle must be passed on subsequent rfapi_ calls.   *   * - * return value:  + * return value:   *	0		Success   *	EEXIST		NVE with this {vn,un} already open   *	ENOENT		No matching nve group config @@ -2033,188 +1886,176 @@ rfapi_open_rfd (struct rfapi_descriptor *rfd, struct bgp *bgp)   *			but underlay network address is not IPv4   *	EDEADLK		Called from within a callback procedure   *------------------------------------------*/ -int -rfapi_open ( -  void				*rfp_start_val, -  struct rfapi_ip_addr		*vn, -  struct rfapi_ip_addr		*un, -  struct rfapi_un_option	*default_options, -  uint32_t			*response_lifetime, -  void				*userdata,     /* callback cookie */ -  rfapi_handle			*pHandle) +int rfapi_open(void *rfp_start_val, struct rfapi_ip_addr *vn, +	       struct rfapi_ip_addr *un, +	       struct rfapi_un_option *default_options, +	       uint32_t *response_lifetime, +	       void *userdata, /* callback cookie */ +	       rfapi_handle *pHandle)  { -  struct bgp *bgp; -  struct rfapi *h; -  struct rfapi_descriptor *rfd; -  struct rfapi_cfg *hc; -  struct rfapi_nve_group_cfg *rfg; - -  struct prefix pfx_vn; -  struct prefix pfx_un; - -  int rc; -  rfapi_handle hh = NULL; -  int reusing_provisional = 0; - -  { -    char buf[2][INET_ADDRSTRLEN]; -    vnc_zlog_debug_verbose ("%s: VN=%s UN=%s", __func__, -                rfapiRfapiIpAddr2Str (vn, buf[0], INET_ADDRSTRLEN), -                rfapiRfapiIpAddr2Str (un, buf[1], INET_ADDRSTRLEN)); -  } - -  assert (pHandle); -  *pHandle = NULL; - -  bgp = rfapi_bgp_lookup_by_rfp (rfp_start_val); -  if (!bgp) -    return ENXIO; - -  h = bgp->rfapi; -  if (!h) -    return ENXIO; - -  hc = bgp->rfapi_cfg; -  if (!hc) -    return ENXIO; - -  if (h->flags & RFAPI_INCALLBACK) -    return EDEADLK; - -  rc = rfapiRaddr2Qprefix (vn, &pfx_vn); -  assert (!rc); - -  rc = rfapiRaddr2Qprefix (un, &pfx_un); -  assert (!rc); - -  /* -   * already have a descriptor with VN and UN? -   */ -  if (!rfapi_find_handle (bgp, vn, un, &hh)) -    { -      /* -       * we might have set up a handle for static routes before -       * this NVE was opened. In that case, reuse the handle -       */ -      rfd = hh; -      if (!CHECK_FLAG (rfd->flags, RFAPI_HD_FLAG_PROVISIONAL)) -        { -          return EEXIST; -        } - -      /* -       * reuse provisional descriptor -       * hh is not NULL -       */ -      reusing_provisional = 1; -    } - -  /* -   * Find the matching nve group config block -   */ -  rfg = bgp_rfapi_cfg_match_group (hc, &pfx_vn, &pfx_un); -  if (!rfg) -    { -      ++h->stat.count_unknown_nves; -      { -        char buf[2][INET_ADDRSTRLEN]; -        zlog_notice ("%s: no matching group VN=%s UN=%s", __func__, -                     rfapiRfapiIpAddr2Str (vn, buf[0], INET_ADDRSTRLEN), -                     rfapiRfapiIpAddr2Str (un, buf[1], INET_ADDRSTRLEN)); -      } -      return ENOENT; -    } - -  /* -   * check nve group config block for required values -   */ -  if (!rfg->rt_export_list || !rfg->rfapi_import_table) -    { - -      ++h->stat.count_unknown_nves; -      return ENOMSG; -    } - -  /* -   * If group config specifies auto-rd assignment, check that -   * VN address is IPv4|v6 so we don't fail in rfapi_open_inner(). -   * Check here so we don't need to unwind memory allocations, &c. -   */ -  if ((rfg->rd.family == AF_UNIX) && (vn->addr_family != AF_INET) -      && (vn->addr_family != AF_INET6)) -    { -      return EAFNOSUPPORT; -    } - -  if (hh) -    { -      /* -       * reusing provisional rfd -       */ -      rfd = hh; -    } -  else -    { -      rfd = XCALLOC (MTYPE_RFAPI_DESC, sizeof (struct rfapi_descriptor)); -    } -  assert (rfd); - -  rfd->bgp = bgp; -  if (default_options) -    { -      struct rfapi_un_option *p; - -      for (p = default_options; p; p = p->next) -        { -          if ((RFAPI_UN_OPTION_TYPE_PROVISIONAL == p->type)) -            { -              rfd->flags |= RFAPI_HD_FLAG_PROVISIONAL; -            } -          if ((RFAPI_UN_OPTION_TYPE_TUNNELTYPE == p->type)) -            { -              rfd->default_tunneltype_option = p->v.tunnel; -            } -        } -    } - -  /* -   * Fill in caller fields -   */ -  rfd->vn_addr = *vn; -  rfd->un_addr = *un; -  rfd->cookie = userdata; - -  if (!reusing_provisional) -    { -      rc = rfapi_init_and_open(bgp, rfd, rfg); -      /* -       * This can fail only if the VN address is IPv6 and the group -       * specified auto-assignment of RDs, which only works for v4, -       * and the check above should catch it. -       * -       * Another failure possibility is that we were called -       * during an rfapi callback. Also checked above. -       */ -      assert (!rc); -    } - -  if (response_lifetime) -    *response_lifetime = rfd->response_lifetime; -  *pHandle = rfd; -  return 0; +	struct bgp *bgp; +	struct rfapi *h; +	struct rfapi_descriptor *rfd; +	struct rfapi_cfg *hc; +	struct rfapi_nve_group_cfg *rfg; + +	struct prefix pfx_vn; +	struct prefix pfx_un; + +	int rc; +	rfapi_handle hh = NULL; +	int reusing_provisional = 0; + +	{ +		char buf[2][INET_ADDRSTRLEN]; +		vnc_zlog_debug_verbose( +			"%s: VN=%s UN=%s", __func__, +			rfapiRfapiIpAddr2Str(vn, buf[0], INET_ADDRSTRLEN), +			rfapiRfapiIpAddr2Str(un, buf[1], INET_ADDRSTRLEN)); +	} + +	assert(pHandle); +	*pHandle = NULL; + +	bgp = rfapi_bgp_lookup_by_rfp(rfp_start_val); +	if (!bgp) +		return ENXIO; + +	h = bgp->rfapi; +	if (!h) +		return ENXIO; + +	hc = bgp->rfapi_cfg; +	if (!hc) +		return ENXIO; + +	if (h->flags & RFAPI_INCALLBACK) +		return EDEADLK; + +	rc = rfapiRaddr2Qprefix(vn, &pfx_vn); +	assert(!rc); + +	rc = rfapiRaddr2Qprefix(un, &pfx_un); +	assert(!rc); + +	/* +	 * already have a descriptor with VN and UN? +	 */ +	if (!rfapi_find_handle(bgp, vn, un, &hh)) { +		/* +		 * we might have set up a handle for static routes before +		 * this NVE was opened. In that case, reuse the handle +		 */ +		rfd = hh; +		if (!CHECK_FLAG(rfd->flags, RFAPI_HD_FLAG_PROVISIONAL)) { +			return EEXIST; +		} + +		/* +		 * reuse provisional descriptor +		 * hh is not NULL +		 */ +		reusing_provisional = 1; +	} + +	/* +	 * Find the matching nve group config block +	 */ +	rfg = bgp_rfapi_cfg_match_group(hc, &pfx_vn, &pfx_un); +	if (!rfg) { +		++h->stat.count_unknown_nves; +		{ +			char buf[2][INET_ADDRSTRLEN]; +			zlog_notice("%s: no matching group VN=%s UN=%s", +				    __func__, +				    rfapiRfapiIpAddr2Str(vn, buf[0], +							 INET_ADDRSTRLEN), +				    rfapiRfapiIpAddr2Str(un, buf[1], +							 INET_ADDRSTRLEN)); +		} +		return ENOENT; +	} + +	/* +	 * check nve group config block for required values +	 */ +	if (!rfg->rt_export_list || !rfg->rfapi_import_table) { + +		++h->stat.count_unknown_nves; +		return ENOMSG; +	} + +	/* +	 * If group config specifies auto-rd assignment, check that +	 * VN address is IPv4|v6 so we don't fail in rfapi_open_inner(). +	 * Check here so we don't need to unwind memory allocations, &c. +	 */ +	if ((rfg->rd.family == AF_UNIX) && (vn->addr_family != AF_INET) +	    && (vn->addr_family != AF_INET6)) { +		return EAFNOSUPPORT; +	} + +	if (hh) { +		/* +		 * reusing provisional rfd +		 */ +		rfd = hh; +	} else { +		rfd = XCALLOC(MTYPE_RFAPI_DESC, +			      sizeof(struct rfapi_descriptor)); +	} +	assert(rfd); + +	rfd->bgp = bgp; +	if (default_options) { +		struct rfapi_un_option *p; + +		for (p = default_options; p; p = p->next) { +			if ((RFAPI_UN_OPTION_TYPE_PROVISIONAL == p->type)) { +				rfd->flags |= RFAPI_HD_FLAG_PROVISIONAL; +			} +			if ((RFAPI_UN_OPTION_TYPE_TUNNELTYPE == p->type)) { +				rfd->default_tunneltype_option = p->v.tunnel; +			} +		} +	} + +	/* +	 * Fill in caller fields +	 */ +	rfd->vn_addr = *vn; +	rfd->un_addr = *un; +	rfd->cookie = userdata; + +	if (!reusing_provisional) { +		rc = rfapi_init_and_open(bgp, rfd, rfg); +		/* +		 * This can fail only if the VN address is IPv6 and the group +		 * specified auto-assignment of RDs, which only works for v4, +		 * and the check above should catch it. +		 * +		 * Another failure possibility is that we were called +		 * during an rfapi callback. Also checked above. +		 */ +		assert(!rc); +	} + +	if (response_lifetime) +		*response_lifetime = rfd->response_lifetime; +	*pHandle = rfd; +	return 0;  }  /*   * For use with debug functions   */ -static int -rfapi_set_response_cb (struct rfapi_descriptor *rfd, -                       rfapi_response_cb_t * response_cb) +static int rfapi_set_response_cb(struct rfapi_descriptor *rfd, +				 rfapi_response_cb_t *response_cb)  { -  if (!is_valid_rfd (rfd)) -    return EBADF; -  rfd->response_cb = response_cb; -  return 0; +	if (!is_valid_rfd(rfd)) +		return EBADF; +	rfd->response_cb = response_cb; +	return 0;  }  /* @@ -2230,246 +2071,234 @@ rfapi_set_response_cb (struct rfapi_descriptor *rfd,   * reassignment of an already-open nve to a new nve-group in the   * event that its original nve-group is administratively deleted.   */ -static int -rfapi_close_inner (struct rfapi_descriptor *rfd, struct bgp *bgp) +static int rfapi_close_inner(struct rfapi_descriptor *rfd, struct bgp *bgp)  { -  int rc; -  struct prefix pfx_vn; -  struct prefix_rd prd;         /* currently always 0 for VN->UN */ - -  if (!is_valid_rfd (rfd)) -    return EBADF; - -  rc = rfapiRaddr2Qprefix (&rfd->vn_addr, &pfx_vn); -  assert (!rc);                 /* should never have bad AF in stored vn address */ - -  /* -   * update exported routes to reflect disappearance of this NVE as nexthop -   */ -  vnc_direct_bgp_del_nve (bgp, rfd); -  vnc_zebra_del_nve (bgp, rfd); - -  /* -   * unlink this HD's monitors from import table -   */ -  rfapiMonitorDetachImportHd (rfd); - -  /* -   * Unlink from Import Table -   * NB rfd->import_table will be NULL if we are closing a stale descriptor -   */ -  if (rfd->import_table) -    rfapiImportTableRefDelByIt (bgp, rfd->import_table); -  rfd->import_table = NULL; - -  /* -   * Construct route distinguisher -   */ -  memset (&prd, 0, sizeof (prd)); -  prd = rfd->rd; -  prd.family = AF_UNSPEC; -  prd.prefixlen = 64; - -  /* -   * withdraw tunnel -   */ -  del_vnc_route ( -    rfd, -    rfd->peer, -    bgp, -    SAFI_ENCAP, -    &pfx_vn,		/* prefix being advertised */ -    &prd,		/* route distinguisher to use (0 for ENCAP) */ -    ZEBRA_ROUTE_BGP, -    BGP_ROUTE_RFP, -    NULL, -    0);			/* no kill */ - -  /* -   * Construct route distinguisher for VPN routes -   */ -  prd = rfd->rd; -  prd.family = AF_UNSPEC; -  prd.prefixlen = 64; - -  /* -   * find all VPN routes associated with this rfd and delete them, too -   */ -  rfapiApWithdrawAll (bgp, rfd); - -  /* -   * remove this nve descriptor from the list of nves -   * associated with the nve group -   */ -  if (rfd->rfg) -    { -      listnode_delete (rfd->rfg->nves, rfd); -      rfd->rfg = NULL;          /* XXX mark as orphaned/stale */ -    } - -  if (rfd->rt_export_list) -    ecommunity_free (&rfd->rt_export_list); -  rfd->rt_export_list = NULL; - -  /* -   * free peer structure (possibly delayed until its -   * refcount reaches zero) -   */ -  if (rfd->peer) -    { -      vnc_zlog_debug_verbose ("%s: calling peer_delete(%p), #%d", -                  __func__, rfd->peer, rfd->peer->lock); -      peer_delete (rfd->peer); -    } -  rfd->peer = NULL; - -  return 0; +	int rc; +	struct prefix pfx_vn; +	struct prefix_rd prd; /* currently always 0 for VN->UN */ + +	if (!is_valid_rfd(rfd)) +		return EBADF; + +	rc = rfapiRaddr2Qprefix(&rfd->vn_addr, &pfx_vn); +	assert(!rc); /* should never have bad AF in stored vn address */ + +	/* +	 * update exported routes to reflect disappearance of this NVE as +	 * nexthop +	 */ +	vnc_direct_bgp_del_nve(bgp, rfd); +	vnc_zebra_del_nve(bgp, rfd); + +	/* +	 * unlink this HD's monitors from import table +	 */ +	rfapiMonitorDetachImportHd(rfd); + +	/* +	 * Unlink from Import Table +	 * NB rfd->import_table will be NULL if we are closing a stale +	 * descriptor +	 */ +	if (rfd->import_table) +		rfapiImportTableRefDelByIt(bgp, rfd->import_table); +	rfd->import_table = NULL; + +	/* +	 * Construct route distinguisher +	 */ +	memset(&prd, 0, sizeof(prd)); +	prd = rfd->rd; +	prd.family = AF_UNSPEC; +	prd.prefixlen = 64; + +	/* +	 * withdraw tunnel +	 */ +	del_vnc_route(rfd, rfd->peer, bgp, SAFI_ENCAP, +		      &pfx_vn, /* prefix being advertised */ +		      &prd,    /* route distinguisher to use (0 for ENCAP) */ +		      ZEBRA_ROUTE_BGP, BGP_ROUTE_RFP, NULL, 0); /* no kill */ + +	/* +	 * Construct route distinguisher for VPN routes +	 */ +	prd = rfd->rd; +	prd.family = AF_UNSPEC; +	prd.prefixlen = 64; + +	/* +	 * find all VPN routes associated with this rfd and delete them, too +	 */ +	rfapiApWithdrawAll(bgp, rfd); + +	/* +	 * remove this nve descriptor from the list of nves +	 * associated with the nve group +	 */ +	if (rfd->rfg) { +		listnode_delete(rfd->rfg->nves, rfd); +		rfd->rfg = NULL; /* XXX mark as orphaned/stale */ +	} + +	if (rfd->rt_export_list) +		ecommunity_free(&rfd->rt_export_list); +	rfd->rt_export_list = NULL; + +	/* +	 * free peer structure (possibly delayed until its +	 * refcount reaches zero) +	 */ +	if (rfd->peer) { +		vnc_zlog_debug_verbose("%s: calling peer_delete(%p), #%d", +				       __func__, rfd->peer, rfd->peer->lock); +		peer_delete(rfd->peer); +	} +	rfd->peer = NULL; + +	return 0;  } -int -rfapi_close (void *handle) +int rfapi_close(void *handle)  { -  struct rfapi_descriptor *rfd = (struct rfapi_descriptor *) handle; -  int rc; -  struct route_node *node; -  struct bgp *bgp; -  struct rfapi *h; +	struct rfapi_descriptor *rfd = (struct rfapi_descriptor *)handle; +	int rc; +	struct route_node *node; +	struct bgp *bgp; +	struct rfapi *h; -  vnc_zlog_debug_verbose ("%s: rfd=%p", __func__, rfd); +	vnc_zlog_debug_verbose("%s: rfd=%p", __func__, rfd);  #if RFAPI_WHO_IS_CALLING_ME  #ifdef HAVE_GLIBC_BACKTRACE  #define RFAPI_DEBUG_BACKTRACE_NENTRIES 5 -  { -    void *buf[RFAPI_DEBUG_BACKTRACE_NENTRIES]; -    char **syms; -    int i; -    size_t size; - -    size = backtrace (buf, RFAPI_DEBUG_BACKTRACE_NENTRIES); -    syms = backtrace_symbols (buf, size); -    for (i = 0; i < size && i < RFAPI_DEBUG_BACKTRACE_NENTRIES; ++i) -      { -        vnc_zlog_debug_verbose ("backtrace[%2d]: %s", i, syms[i]); -      } -    free (syms); -  } +	{ +		void *buf[RFAPI_DEBUG_BACKTRACE_NENTRIES]; +		char **syms; +		int i; +		size_t size; + +		size = backtrace(buf, RFAPI_DEBUG_BACKTRACE_NENTRIES); +		syms = backtrace_symbols(buf, size); +		for (i = 0; i < size && i < RFAPI_DEBUG_BACKTRACE_NENTRIES; +		     ++i) { +			vnc_zlog_debug_verbose("backtrace[%2d]: %s", i, +					       syms[i]); +		} +		free(syms); +	}  #endif  #endif -  bgp = rfd->bgp; -  if (!bgp) -    return ENXIO; - -  h = bgp->rfapi; -  if (!h) -    return ENXIO; - -  if (!is_valid_rfd (rfd)) -    return EBADF; - -  if (h->flags & RFAPI_INCALLBACK) -    { -      /* -       * Queue these close requests for processing after callback -       * is finished -       */ -      if (!CHECK_FLAG (rfd->flags, RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY)) -        { -          work_queue_add (h->deferred_close_q, handle); -          vnc_zlog_debug_verbose ("%s: added handle %p to deferred close queue", -                      __func__, handle); -        } -      return 0; -    } - -  if (CHECK_FLAG (rfd->flags, RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY)) -    { - -      vnc_zlog_debug_verbose ("%s administrative close rfd=%p", __func__, rfd); - -      if (h && h->rfp_methods.close_cb) -        { -          vnc_zlog_debug_verbose ("%s calling close callback rfd=%p", __func__, rfd); - -          /* -           * call the callback fairly early so that it can still lookup un/vn -           * from handle, etc. -           * -           * NB RFAPI_INCALLBACK is tested above, so if we reach this point -           * we are not already in the context of a callback. -           */ -          h->flags |= RFAPI_INCALLBACK; -          (*h->rfp_methods.close_cb) (handle, EIDRM); -          h->flags &= ~RFAPI_INCALLBACK; -        } -    } - -  if (rfd->rfg) -    { -      /*  -       * Orphaned descriptors have already done this part, so do -       * only for non-orphaned descriptors. -       */ -      if ((rc = rfapi_close_inner (rfd, bgp))) -        return rc; -    } - -  /* -   * Remove descriptor from UN index -   * (remove from chain at node) -   */ -  rc = rfapi_find_node (bgp, &rfd->vn_addr, &rfd->un_addr, &node); -  if (!rc) -    { -      struct rfapi_descriptor *hh; - -      if (node->info == rfd) -        { -          node->info = rfd->next; -        } -      else -        { - -          for (hh = node->info; hh; hh = hh->next) -            { -              if (hh->next == rfd) -                { -                  hh->next = rfd->next; -                  break; -                } -            } -        } -      route_unlock_node (node); -    } - -  /* -   * remove from descriptor list -   */ -  listnode_delete (&h->descriptors, rfd); - -  /* -   * Delete monitor list items and free monitor structures -   */ -  (void) rfapiMonitorDelHd (rfd); - -  /* -   * release advertised prefix data -   */ -  rfapiApRelease (&rfd->advertised); - -  /* -   * Release RFP callback RIB -   */ -  rfapiRibFree (rfd); - -  /* -   * free descriptor -   */ -  memset (rfd, 0, sizeof (struct rfapi_descriptor)); -  XFREE (MTYPE_RFAPI_DESC, rfd); - -  return 0; +	bgp = rfd->bgp; +	if (!bgp) +		return ENXIO; + +	h = bgp->rfapi; +	if (!h) +		return ENXIO; + +	if (!is_valid_rfd(rfd)) +		return EBADF; + +	if (h->flags & RFAPI_INCALLBACK) { +		/* +		 * Queue these close requests for processing after callback +		 * is finished +		 */ +		if (!CHECK_FLAG(rfd->flags, +				RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY)) { +			work_queue_add(h->deferred_close_q, handle); +			vnc_zlog_debug_verbose( +				"%s: added handle %p to deferred close queue", +				__func__, handle); +		} +		return 0; +	} + +	if (CHECK_FLAG(rfd->flags, RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY)) { + +		vnc_zlog_debug_verbose("%s administrative close rfd=%p", +				       __func__, rfd); + +		if (h && h->rfp_methods.close_cb) { +			vnc_zlog_debug_verbose( +				"%s calling close callback rfd=%p", __func__, +				rfd); + +			/* +			 * call the callback fairly early so that it can still +			 * lookup un/vn +			 * from handle, etc. +			 * +			 * NB RFAPI_INCALLBACK is tested above, so if we reach +			 * this point +			 * we are not already in the context of a callback. +			 */ +			h->flags |= RFAPI_INCALLBACK; +			(*h->rfp_methods.close_cb)(handle, EIDRM); +			h->flags &= ~RFAPI_INCALLBACK; +		} +	} + +	if (rfd->rfg) { +		/* +		 * Orphaned descriptors have already done this part, so do +		 * only for non-orphaned descriptors. +		 */ +		if ((rc = rfapi_close_inner(rfd, bgp))) +			return rc; +	} + +	/* +	 * Remove descriptor from UN index +	 * (remove from chain at node) +	 */ +	rc = rfapi_find_node(bgp, &rfd->vn_addr, &rfd->un_addr, &node); +	if (!rc) { +		struct rfapi_descriptor *hh; + +		if (node->info == rfd) { +			node->info = rfd->next; +		} else { + +			for (hh = node->info; hh; hh = hh->next) { +				if (hh->next == rfd) { +					hh->next = rfd->next; +					break; +				} +			} +		} +		route_unlock_node(node); +	} + +	/* +	 * remove from descriptor list +	 */ +	listnode_delete(&h->descriptors, rfd); + +	/* +	 * Delete monitor list items and free monitor structures +	 */ +	(void)rfapiMonitorDelHd(rfd); + +	/* +	 * release advertised prefix data +	 */ +	rfapiApRelease(&rfd->advertised); + +	/* +	 * Release RFP callback RIB +	 */ +	rfapiRibFree(rfd); + +	/* +	 * free descriptor +	 */ +	memset(rfd, 0, sizeof(struct rfapi_descriptor)); +	XFREE(MTYPE_RFAPI_DESC, rfd); + +	return 0;  }  /* @@ -2489,580 +2318,535 @@ rfapi_close (void *handle)   * caused by deleting and then adding the NVE: advertised prefixes   * and nexthop lists for exported routes can turn over.   */ -int -rfapi_reopen (struct rfapi_descriptor *rfd, struct bgp *bgp) +int rfapi_reopen(struct rfapi_descriptor *rfd, struct bgp *bgp)  { -  struct rfapi *h; -  int rc; - -  if ((rc = rfapi_close_inner (rfd, bgp))) -    { -      return rc; -    } -  if ((rc = rfapi_open_rfd (rfd, bgp))) -    { - -      h = bgp->rfapi; - -      assert (!CHECK_FLAG (h->flags, RFAPI_INCALLBACK)); - -      if (CHECK_FLAG (rfd->flags, RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY) && -          h && h->rfp_methods.close_cb) -        { - -          /* -           * NB RFAPI_INCALLBACK is tested above, so if we reach this point -           * we are not already in the context of a callback. -           */ -          h->flags |= RFAPI_INCALLBACK; -          (*h->rfp_methods.close_cb) ((rfapi_handle) rfd, ESTALE); -          h->flags &= ~RFAPI_INCALLBACK; -        } -      return rc; -    } -  return 0; +	struct rfapi *h; +	int rc; + +	if ((rc = rfapi_close_inner(rfd, bgp))) { +		return rc; +	} +	if ((rc = rfapi_open_rfd(rfd, bgp))) { + +		h = bgp->rfapi; + +		assert(!CHECK_FLAG(h->flags, RFAPI_INCALLBACK)); + +		if (CHECK_FLAG(rfd->flags, +			       RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY) +		    && h && h->rfp_methods.close_cb) { + +			/* +			 * NB RFAPI_INCALLBACK is tested above, so if we reach +			 * this point +			 * we are not already in the context of a callback. +			 */ +			h->flags |= RFAPI_INCALLBACK; +			(*h->rfp_methods.close_cb)((rfapi_handle)rfd, ESTALE); +			h->flags &= ~RFAPI_INCALLBACK; +		} +		return rc; +	} +	return 0;  }  /***********************************************************************   *			NVE Routes   ***********************************************************************/ -/*  +/*   * Announce reachability to this prefix via the NVE   */ -int -rfapi_register ( -  void				*handle, -  struct rfapi_ip_prefix	*prefix, -  uint32_t			lifetime,        /* host byte order */ -  struct rfapi_un_option	*options_un, -  struct rfapi_vn_option	*options_vn, -  rfapi_register_action		action) +int rfapi_register(void *handle, struct rfapi_ip_prefix *prefix, +		   uint32_t lifetime, /* host byte order */ +		   struct rfapi_un_option *options_un, +		   struct rfapi_vn_option *options_vn, +		   rfapi_register_action action)  { -  struct rfapi_descriptor	*rfd = (struct rfapi_descriptor *) handle; -  struct bgp			*bgp; -  struct prefix			p; -  struct prefix			*pfx_ip = NULL; -  struct prefix_rd		prd; -  int				afi; -  struct prefix			pfx_mac_buf; -  struct prefix			*pfx_mac = NULL; -  struct prefix			pfx_vn_buf; -  const char			*action_str = NULL; -  uint32_t			*label = NULL; -  struct rfapi_vn_option	*vo; -  struct rfapi_l2address_option	*l2o = NULL; -  struct prefix_rd		*prd_override = NULL; - -  switch (action) -    { -    case RFAPI_REGISTER_ADD: -      action_str = "add"; -      break; -    case RFAPI_REGISTER_WITHDRAW: -      action_str = "withdraw"; -      break; -    case RFAPI_REGISTER_KILL: -      action_str = "kill"; -      break; -    default: -      assert (0); -      break; -    } - -  /* -   * Inspect VN options -   */ -  for (vo = options_vn; vo; vo = vo->next) -    { -      if (RFAPI_VN_OPTION_TYPE_L2ADDR == vo->type) -        { -          l2o = &vo->v.l2addr; -        } -      if (RFAPI_VN_OPTION_TYPE_INTERNAL_RD == vo->type) -        { -          prd_override = &vo->v.internal_rd; -        } -    } - -    /********************************************************************* -     *			advertise prefix -     *********************************************************************/ - -  /* -   * set <p> based on <prefix> -   */ -  assert (!rfapiRprefix2Qprefix (prefix, &p)); - -  afi = family2afi (prefix->prefix.addr_family); -  assert (afi); - - -  { -    char buf[BUFSIZ]; - -    prefix2str (&p, buf, BUFSIZ); -    buf[BUFSIZ - 1] = 0;        /* guarantee NUL-terminated */ -    vnc_zlog_debug_verbose -      ("%s(rfd=%p, pfx=%s, lifetime=%d, opts_un=%p, opts_vn=%p, action=%s)", -       __func__, rfd, buf, lifetime, options_un, options_vn, action_str); -  } - -  /* -   * These tests come after the prefix conversion so that we can -   * print the prefix in a debug message before failing -   */ - -  bgp = rfd->bgp; -  if (!bgp) -    { -      vnc_zlog_debug_verbose ("%s: no BGP instance: returning ENXIO", __func__); -      return ENXIO; -    } -  if (!bgp->rfapi) -    { -      vnc_zlog_debug_verbose ("%s: no RFAPI instance: returning ENXIO", __func__); -      return ENXIO; -    } -  if (!rfd->rfg) -    { -      if (RFAPI_REGISTER_ADD == action) -        { -          ++bgp->rfapi->stat.count_registrations_failed; -        } -      vnc_zlog_debug_verbose ("%s: rfd=%p, no RF GRP instance: returning ESTALE", -                  __func__, rfd); -      return ESTALE; -    } - -  if (bgp->rfapi->flags & RFAPI_INCALLBACK) -    { -      if (RFAPI_REGISTER_ADD == action) -        { -          ++bgp->rfapi->stat.count_registrations_failed; -        } -      vnc_zlog_debug_verbose ("%s: in callback: returning EDEADLK", __func__); -      return EDEADLK; -    } - -  if (!is_valid_rfd (rfd)) -    { -      if (RFAPI_REGISTER_ADD == action) -        { -          ++bgp->rfapi->stat.count_registrations_failed; -        } -      vnc_zlog_debug_verbose ("%s: invalid handle: returning EBADF", __func__); -      return EBADF; -    } - -  /* -   * Is there a MAC address in this registration? -   */ -  if (l2o && !RFAPI_0_ETHERADDR (&l2o->macaddr)) -    { -      rfapiL2o2Qprefix (l2o, &pfx_mac_buf); -      pfx_mac = &pfx_mac_buf; -    } - -  /* -   * Is there an IP prefix in this registration? -   */ -  if (!(RFAPI_0_PREFIX (&p) && RFAPI_HOST_PREFIX (&p))) -    { -      pfx_ip = &p; -    } -  else -    { -      if (!pfx_mac) -        { -          vnc_zlog_debug_verbose ("%s: missing mac addr that is required for host 0 pfx", -                      __func__); -          if (RFAPI_REGISTER_ADD == action) -            { -              ++bgp->rfapi->stat.count_registrations_failed; -            } -          return EINVAL; -        } -      if (rfapiRaddr2Qprefix (&rfd->vn_addr, &pfx_vn_buf)) -        { -          vnc_zlog_debug_verbose ("%s: handle has bad vn_addr: returning EBADF", -                      __func__); -          if (RFAPI_REGISTER_ADD == action) -            { -              ++bgp->rfapi->stat.count_registrations_failed; -            } -          return EBADF; -        } -    } - -  if (RFAPI_REGISTER_ADD == action) -    { -      ++bgp->rfapi->stat.count_registrations; -    } - -  /* -   * Figure out if this registration is missing an IP address -   * -   * MAC-addr based: -   * -   *  In RFAPI, we use prefixes in family AF_LINK to store -   *  the MAC addresses. These prefixes are used for the -   *  list of advertised prefixes and in the RFAPI import -   *  tables. -   * -   *  In BGP proper, we use the prefix matching the NVE's -   *  VN address with a host prefix-length (i.e., 32 or 128). -   *   -   */ -  if (l2o && l2o->logical_net_id && RFAPI_0_PREFIX (&p) && -      RFAPI_HOST_PREFIX (&p)) -    { - -      rfapiL2o2Qprefix (l2o, &pfx_mac_buf); -      pfx_mac = &pfx_mac_buf; -    } - -  /* -   * Construct route distinguisher -   */ -  if (prd_override) -    { -      prd = *prd_override; -    } -  else -    { -      memset (&prd, 0, sizeof (prd)); -      if (pfx_mac) -        { -          prd.family = AF_UNSPEC; -          prd.prefixlen = 64; -          encode_rd_type(RD_TYPE_VNC_ETH, prd.val); -          if (l2o->local_nve_id || !(rfd->rfg->flags & RFAPI_RFG_L2RD)) -            { -              /* -               * If Local NVE ID is specified in message, use it. -               * (if no local default configured, also use it even if 0) -               */ -              prd.val[1] = l2o->local_nve_id; -            } -          else -            { -              if (rfd->rfg->l2rd) -                { -                  /* -                   * locally-configured literal value -                   */ -                  prd.val[1] = rfd->rfg->l2rd; -                } -              else -                { -                  /*  -                   * 0 means auto:vn, which means use LSB of VN addr -                   */ -                  if (rfd->vn_addr.addr_family == AF_INET) -                    { -                      prd.val[1] = -                        *(((char *) &rfd->vn_addr.addr.v4.s_addr) + 3); -                    } -                  else -                    { -                      prd.val[1] = -                        *(((char *) &rfd->vn_addr.addr.v6.s6_addr) + 15); -                    } -                } -            } -          memcpy (prd.val + 2, pfx_mac->u.prefix_eth.octet, 6); -        } -      else -        { -          prd = rfd->rd; -          prd.family = AF_UNSPEC; -          prd.prefixlen = 64; -        } -    } - - -  if (action == RFAPI_REGISTER_WITHDRAW || action == RFAPI_REGISTER_KILL) -    { - -      int adv_tunnel = 0; - -      /* -       * withdraw previous advertisement -       */ -      del_vnc_route ( -	rfd, -	rfd->peer, -	bgp, -	SAFI_MPLS_VPN, -	pfx_ip ? pfx_ip : &pfx_vn_buf,	/* prefix being advertised */ -	&prd,				/* route distinguisher (0 for ENCAP) */ -	ZEBRA_ROUTE_BGP, -	BGP_ROUTE_RFP, -	NULL, -	action == RFAPI_REGISTER_KILL); - -      if (0 == rfapiApDelete (bgp, rfd, &p, pfx_mac, &prd, &adv_tunnel)) -        { -          if (adv_tunnel) -            rfapiTunnelRouteAnnounce (bgp, rfd, &rfd->max_prefix_lifetime); -        } - -    } -  else -    { - -      int adv_tunnel = 0; -      uint32_t local_pref; -      struct ecommunity *rtlist = NULL; -      struct ecommunity_val ecom_value; - -      if (!rfapiApCount (rfd)) -        { -          /*  -           * make sure we advertise tunnel route upon adding the -           * first VPN route -           */ -          adv_tunnel = 1; -        } - -      if (rfapiApAdd (bgp, rfd, &p, pfx_mac, &prd, lifetime, prefix->cost, -                      l2o)) -        { -          adv_tunnel = 1; -        } - -      vnc_zlog_debug_verbose ("%s: adv_tunnel = %d", __func__, adv_tunnel); -      if (adv_tunnel) -        { -          vnc_zlog_debug_verbose ("%s: announcing tunnel route", __func__); -          rfapiTunnelRouteAnnounce (bgp, rfd, &rfd->max_prefix_lifetime); -        } - -      vnc_zlog_debug_verbose ("%s: calling add_vnc_route", __func__); - -      local_pref = rfp_cost_to_localpref (prefix->cost); - -      if (l2o && l2o->label) -        label = &l2o->label; - -      if (pfx_mac) -        { -          struct ecommunity *l2com = NULL; - -          if (label) -            { -              l2com = bgp_rfapi_get_ecommunity_by_lni_label (bgp, 1, -                                                             l2o->logical_net_id, -                                                             *label); -            } -          if (l2com) -            { -              rtlist = ecommunity_dup (l2com); -            } -          else -            { -              /* -               * If mac address is set, add an RT based on the registered LNI -               */ -              memset ((char *) &ecom_value, 0, sizeof (ecom_value)); -              ecom_value.val[1] = ECOMMUNITY_ROUTE_TARGET; -              ecom_value.val[5] = (l2o->logical_net_id >> 16) & 0xff; -              ecom_value.val[6] = (l2o->logical_net_id >> 8) & 0xff; -              ecom_value.val[7] = (l2o->logical_net_id >> 0) & 0xff; -              rtlist = ecommunity_new(); -              ecommunity_add_val (rtlist, &ecom_value); -            } -          if (l2o->tag_id)  -            { -              as_t as      = bgp->as; -              uint16_t val = l2o->tag_id; -              memset ((char *) &ecom_value, 0, sizeof (ecom_value)); -              ecom_value.val[1] = ECOMMUNITY_ROUTE_TARGET; -              if (as > BGP_AS_MAX) -                {       -                  ecom_value.val[0] = ECOMMUNITY_ENCODE_AS4; -                  ecom_value.val[2] = (as >>24) & 0xff; -                  ecom_value.val[3] = (as >>16) & 0xff; -                  ecom_value.val[4] = (as >>8) & 0xff; -                  ecom_value.val[5] =  as & 0xff; -                } -              else -                { -                  ecom_value.val[0] = ECOMMUNITY_ENCODE_AS; -                  ecom_value.val[2] = (as >>8) & 0xff; -                  ecom_value.val[3] = as & 0xff; -                } -              ecom_value.val[6] = (val >> 8) & 0xff; -              ecom_value.val[7] = val & 0xff; -              if (rtlist == NULL) -                rtlist = ecommunity_new(); -              ecommunity_add_val (rtlist, &ecom_value); -            } -        } - -      /* -       * advertise prefix via tunnel endpoint -       */ -      add_vnc_route ( -	rfd,			/* rfapi descr, for export list & backref */ -	bgp,			/* which bgp instance */ -	SAFI_MPLS_VPN,		/* which SAFI */ -	(pfx_ip ? pfx_ip : &pfx_vn_buf),	/* prefix being advertised */ -	&prd,			/* route distinguisher to use (0 for ENCAP) */ -	&rfd->vn_addr,		/* nexthop */ -	&local_pref, -	&lifetime,		/* prefix lifetime -> Tunnel Encap attr */ -	NULL, -	options_un,		/* rfapi un options */ -	options_vn,		/* rfapi vn options */ -	(rtlist ? rtlist : rfd->rt_export_list), -	NULL,			/* med */ -	label,			/* label: default */ -	ZEBRA_ROUTE_BGP, -	BGP_ROUTE_RFP, -	0); - -      if (rtlist) -        ecommunity_free (&rtlist);      /* sets rtlist = NULL */ -    } - -  vnc_zlog_debug_verbose ("%s: success", __func__); -  return 0; +	struct rfapi_descriptor *rfd = (struct rfapi_descriptor *)handle; +	struct bgp *bgp; +	struct prefix p; +	struct prefix *pfx_ip = NULL; +	struct prefix_rd prd; +	int afi; +	struct prefix pfx_mac_buf; +	struct prefix *pfx_mac = NULL; +	struct prefix pfx_vn_buf; +	const char *action_str = NULL; +	uint32_t *label = NULL; +	struct rfapi_vn_option *vo; +	struct rfapi_l2address_option *l2o = NULL; +	struct prefix_rd *prd_override = NULL; + +	switch (action) { +	case RFAPI_REGISTER_ADD: +		action_str = "add"; +		break; +	case RFAPI_REGISTER_WITHDRAW: +		action_str = "withdraw"; +		break; +	case RFAPI_REGISTER_KILL: +		action_str = "kill"; +		break; +	default: +		assert(0); +		break; +	} + +	/* +	 * Inspect VN options +	 */ +	for (vo = options_vn; vo; vo = vo->next) { +		if (RFAPI_VN_OPTION_TYPE_L2ADDR == vo->type) { +			l2o = &vo->v.l2addr; +		} +		if (RFAPI_VN_OPTION_TYPE_INTERNAL_RD == vo->type) { +			prd_override = &vo->v.internal_rd; +		} +	} + +	/********************************************************************* +	 *			advertise prefix +	 *********************************************************************/ + +	/* +	 * set <p> based on <prefix> +	 */ +	assert(!rfapiRprefix2Qprefix(prefix, &p)); + +	afi = family2afi(prefix->prefix.addr_family); +	assert(afi); + + +	{ +		char buf[BUFSIZ]; + +		prefix2str(&p, buf, BUFSIZ); +		buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */ +		vnc_zlog_debug_verbose( +			"%s(rfd=%p, pfx=%s, lifetime=%d, opts_un=%p, opts_vn=%p, action=%s)", +			__func__, rfd, buf, lifetime, options_un, options_vn, +			action_str); +	} + +	/* +	 * These tests come after the prefix conversion so that we can +	 * print the prefix in a debug message before failing +	 */ + +	bgp = rfd->bgp; +	if (!bgp) { +		vnc_zlog_debug_verbose("%s: no BGP instance: returning ENXIO", +				       __func__); +		return ENXIO; +	} +	if (!bgp->rfapi) { +		vnc_zlog_debug_verbose("%s: no RFAPI instance: returning ENXIO", +				       __func__); +		return ENXIO; +	} +	if (!rfd->rfg) { +		if (RFAPI_REGISTER_ADD == action) { +			++bgp->rfapi->stat.count_registrations_failed; +		} +		vnc_zlog_debug_verbose( +			"%s: rfd=%p, no RF GRP instance: returning ESTALE", +			__func__, rfd); +		return ESTALE; +	} + +	if (bgp->rfapi->flags & RFAPI_INCALLBACK) { +		if (RFAPI_REGISTER_ADD == action) { +			++bgp->rfapi->stat.count_registrations_failed; +		} +		vnc_zlog_debug_verbose("%s: in callback: returning EDEADLK", +				       __func__); +		return EDEADLK; +	} + +	if (!is_valid_rfd(rfd)) { +		if (RFAPI_REGISTER_ADD == action) { +			++bgp->rfapi->stat.count_registrations_failed; +		} +		vnc_zlog_debug_verbose("%s: invalid handle: returning EBADF", +				       __func__); +		return EBADF; +	} + +	/* +	 * Is there a MAC address in this registration? +	 */ +	if (l2o && !RFAPI_0_ETHERADDR(&l2o->macaddr)) { +		rfapiL2o2Qprefix(l2o, &pfx_mac_buf); +		pfx_mac = &pfx_mac_buf; +	} + +	/* +	 * Is there an IP prefix in this registration? +	 */ +	if (!(RFAPI_0_PREFIX(&p) && RFAPI_HOST_PREFIX(&p))) { +		pfx_ip = &p; +	} else { +		if (!pfx_mac) { +			vnc_zlog_debug_verbose( +				"%s: missing mac addr that is required for host 0 pfx", +				__func__); +			if (RFAPI_REGISTER_ADD == action) { +				++bgp->rfapi->stat.count_registrations_failed; +			} +			return EINVAL; +		} +		if (rfapiRaddr2Qprefix(&rfd->vn_addr, &pfx_vn_buf)) { +			vnc_zlog_debug_verbose( +				"%s: handle has bad vn_addr: returning EBADF", +				__func__); +			if (RFAPI_REGISTER_ADD == action) { +				++bgp->rfapi->stat.count_registrations_failed; +			} +			return EBADF; +		} +	} + +	if (RFAPI_REGISTER_ADD == action) { +		++bgp->rfapi->stat.count_registrations; +	} + +	/* +	 * Figure out if this registration is missing an IP address +	 * +	 * MAC-addr based: +	 * +	 *  In RFAPI, we use prefixes in family AF_LINK to store +	 *  the MAC addresses. These prefixes are used for the +	 *  list of advertised prefixes and in the RFAPI import +	 *  tables. +	 * +	 *  In BGP proper, we use the prefix matching the NVE's +	 *  VN address with a host prefix-length (i.e., 32 or 128). +	 * +	 */ +	if (l2o && l2o->logical_net_id && RFAPI_0_PREFIX(&p) +	    && RFAPI_HOST_PREFIX(&p)) { + +		rfapiL2o2Qprefix(l2o, &pfx_mac_buf); +		pfx_mac = &pfx_mac_buf; +	} + +	/* +	 * Construct route distinguisher +	 */ +	if (prd_override) { +		prd = *prd_override; +	} else { +		memset(&prd, 0, sizeof(prd)); +		if (pfx_mac) { +			prd.family = AF_UNSPEC; +			prd.prefixlen = 64; +			encode_rd_type(RD_TYPE_VNC_ETH, prd.val); +			if (l2o->local_nve_id +			    || !(rfd->rfg->flags & RFAPI_RFG_L2RD)) { +				/* +				 * If Local NVE ID is specified in message, use +				 * it. +				 * (if no local default configured, also use it +				 * even if 0) +				 */ +				prd.val[1] = l2o->local_nve_id; +			} else { +				if (rfd->rfg->l2rd) { +					/* +					 * locally-configured literal value +					 */ +					prd.val[1] = rfd->rfg->l2rd; +				} else { +					/* +					 * 0 means auto:vn, which means use LSB +					 * of VN addr +					 */ +					if (rfd->vn_addr.addr_family +					    == AF_INET) { +						prd.val[1] = +							*(((char *)&rfd->vn_addr +								   .addr.v4 +								   .s_addr) +							  + 3); +					} else { +						prd.val[1] = +							*(((char *)&rfd->vn_addr +								   .addr.v6 +								   .s6_addr) +							  + 15); +					} +				} +			} +			memcpy(prd.val + 2, pfx_mac->u.prefix_eth.octet, 6); +		} else { +			prd = rfd->rd; +			prd.family = AF_UNSPEC; +			prd.prefixlen = 64; +		} +	} + + +	if (action == RFAPI_REGISTER_WITHDRAW +	    || action == RFAPI_REGISTER_KILL) { + +		int adv_tunnel = 0; + +		/* +		 * withdraw previous advertisement +		 */ +		del_vnc_route( +			rfd, rfd->peer, bgp, SAFI_MPLS_VPN, +			pfx_ip ? pfx_ip +			       : &pfx_vn_buf, /* prefix being advertised */ +			&prd, /* route distinguisher (0 for ENCAP) */ +			ZEBRA_ROUTE_BGP, BGP_ROUTE_RFP, NULL, +			action == RFAPI_REGISTER_KILL); + +		if (0 == rfapiApDelete(bgp, rfd, &p, pfx_mac, &prd, +				       &adv_tunnel)) { +			if (adv_tunnel) +				rfapiTunnelRouteAnnounce( +					bgp, rfd, &rfd->max_prefix_lifetime); +		} + +	} else { + +		int adv_tunnel = 0; +		uint32_t local_pref; +		struct ecommunity *rtlist = NULL; +		struct ecommunity_val ecom_value; + +		if (!rfapiApCount(rfd)) { +			/* +			 * make sure we advertise tunnel route upon adding the +			 * first VPN route +			 */ +			adv_tunnel = 1; +		} + +		if (rfapiApAdd(bgp, rfd, &p, pfx_mac, &prd, lifetime, +			       prefix->cost, l2o)) { +			adv_tunnel = 1; +		} + +		vnc_zlog_debug_verbose("%s: adv_tunnel = %d", __func__, +				       adv_tunnel); +		if (adv_tunnel) { +			vnc_zlog_debug_verbose("%s: announcing tunnel route", +					       __func__); +			rfapiTunnelRouteAnnounce(bgp, rfd, +						 &rfd->max_prefix_lifetime); +		} + +		vnc_zlog_debug_verbose("%s: calling add_vnc_route", __func__); + +		local_pref = rfp_cost_to_localpref(prefix->cost); + +		if (l2o && l2o->label) +			label = &l2o->label; + +		if (pfx_mac) { +			struct ecommunity *l2com = NULL; + +			if (label) { +				l2com = bgp_rfapi_get_ecommunity_by_lni_label( +					bgp, 1, l2o->logical_net_id, *label); +			} +			if (l2com) { +				rtlist = ecommunity_dup(l2com); +			} else { +				/* +				 * If mac address is set, add an RT based on the +				 * registered LNI +				 */ +				memset((char *)&ecom_value, 0, +				       sizeof(ecom_value)); +				ecom_value.val[1] = ECOMMUNITY_ROUTE_TARGET; +				ecom_value.val[5] = +					(l2o->logical_net_id >> 16) & 0xff; +				ecom_value.val[6] = +					(l2o->logical_net_id >> 8) & 0xff; +				ecom_value.val[7] = +					(l2o->logical_net_id >> 0) & 0xff; +				rtlist = ecommunity_new(); +				ecommunity_add_val(rtlist, &ecom_value); +			} +			if (l2o->tag_id) { +				as_t as = bgp->as; +				uint16_t val = l2o->tag_id; +				memset((char *)&ecom_value, 0, +				       sizeof(ecom_value)); +				ecom_value.val[1] = ECOMMUNITY_ROUTE_TARGET; +				if (as > BGP_AS_MAX) { +					ecom_value.val[0] = +						ECOMMUNITY_ENCODE_AS4; +					ecom_value.val[2] = (as >> 24) & 0xff; +					ecom_value.val[3] = (as >> 16) & 0xff; +					ecom_value.val[4] = (as >> 8) & 0xff; +					ecom_value.val[5] = as & 0xff; +				} else { +					ecom_value.val[0] = +						ECOMMUNITY_ENCODE_AS; +					ecom_value.val[2] = (as >> 8) & 0xff; +					ecom_value.val[3] = as & 0xff; +				} +				ecom_value.val[6] = (val >> 8) & 0xff; +				ecom_value.val[7] = val & 0xff; +				if (rtlist == NULL) +					rtlist = ecommunity_new(); +				ecommunity_add_val(rtlist, &ecom_value); +			} +		} + +		/* +		 * advertise prefix via tunnel endpoint +		 */ +		add_vnc_route( +			rfd, /* rfapi descr, for export list & backref */ +			bgp, /* which bgp instance */ +			SAFI_MPLS_VPN, /* which SAFI */ +			(pfx_ip ? pfx_ip +				: &pfx_vn_buf), /* prefix being advertised */ +			&prd, /* route distinguisher to use (0 for ENCAP) */ +			&rfd->vn_addr, /* nexthop */ +			&local_pref, +			&lifetime, /* prefix lifetime -> Tunnel Encap attr */ +			NULL, options_un, /* rfapi un options */ +			options_vn,       /* rfapi vn options */ +			(rtlist ? rtlist : rfd->rt_export_list), NULL, /* med */ +			label, /* label: default */ +			ZEBRA_ROUTE_BGP, BGP_ROUTE_RFP, 0); + +		if (rtlist) +			ecommunity_free(&rtlist); /* sets rtlist = NULL */ +	} + +	vnc_zlog_debug_verbose("%s: success", __func__); +	return 0;  } -int -rfapi_query ( -  void				*handle, -  struct rfapi_ip_addr		*target, -  struct rfapi_l2address_option	*l2o,    /* may be NULL */ -  struct rfapi_next_hop_entry	**ppNextHopEntry) +int rfapi_query(void *handle, struct rfapi_ip_addr *target, +		struct rfapi_l2address_option *l2o, /* may be NULL */ +		struct rfapi_next_hop_entry **ppNextHopEntry)  { -  struct rfapi_descriptor *rfd = (struct rfapi_descriptor *) handle; -  struct bgp *bgp = rfd->bgp; -  int rc; - -  assert (ppNextHopEntry); -  *ppNextHopEntry = NULL; - -  if (bgp && bgp->rfapi) -    { -      bgp->rfapi->stat.count_queries++; -    } - -  if (!rfd->rfg) -    { -      if (bgp && bgp->rfapi) -        ++bgp->rfapi->stat.count_queries_failed; -      return ESTALE; -    } - -  if ((rc = rfapi_query_inner (handle, target, l2o, ppNextHopEntry))) -    { -      if (bgp && bgp->rfapi) -        ++bgp->rfapi->stat.count_queries_failed; -    } -  return rc; +	struct rfapi_descriptor *rfd = (struct rfapi_descriptor *)handle; +	struct bgp *bgp = rfd->bgp; +	int rc; + +	assert(ppNextHopEntry); +	*ppNextHopEntry = NULL; + +	if (bgp && bgp->rfapi) { +		bgp->rfapi->stat.count_queries++; +	} + +	if (!rfd->rfg) { +		if (bgp && bgp->rfapi) +			++bgp->rfapi->stat.count_queries_failed; +		return ESTALE; +	} + +	if ((rc = rfapi_query_inner(handle, target, l2o, ppNextHopEntry))) { +		if (bgp && bgp->rfapi) +			++bgp->rfapi->stat.count_queries_failed; +	} +	return rc;  } -int -rfapi_query_done (rfapi_handle handle, struct rfapi_ip_addr *target) +int rfapi_query_done(rfapi_handle handle, struct rfapi_ip_addr *target)  { -  struct prefix p; -  int rc; -  struct rfapi_descriptor *rfd = (struct rfapi_descriptor *) handle; -  struct bgp *bgp = rfd->bgp; +	struct prefix p; +	int rc; +	struct rfapi_descriptor *rfd = (struct rfapi_descriptor *)handle; +	struct bgp *bgp = rfd->bgp; -  if (!rfd->rfg) -    return ESTALE; +	if (!rfd->rfg) +		return ESTALE; -  assert (target); -  rc = rfapiRaddr2Qprefix (target, &p); -  assert (!rc); +	assert(target); +	rc = rfapiRaddr2Qprefix(target, &p); +	assert(!rc); -  if (!is_valid_rfd (rfd)) -    return EBADF; +	if (!is_valid_rfd(rfd)) +		return EBADF; -  /* preemptive */ -  if (!bgp || !bgp->rfapi) -    return ENXIO; +	/* preemptive */ +	if (!bgp || !bgp->rfapi) +		return ENXIO; -  if (bgp->rfapi->flags & RFAPI_INCALLBACK) -    return EDEADLK; +	if (bgp->rfapi->flags & RFAPI_INCALLBACK) +		return EDEADLK; -  rfapiMonitorDel (bgp, rfd, &p); +	rfapiMonitorDel(bgp, rfd, &p); -  return 0; +	return 0;  } -int -rfapi_query_done_all (rfapi_handle handle, int *count) +int rfapi_query_done_all(rfapi_handle handle, int *count)  { -  struct rfapi_descriptor *rfd = (struct rfapi_descriptor *) handle; -  struct bgp *bgp = rfd->bgp;; -  int num; +	struct rfapi_descriptor *rfd = (struct rfapi_descriptor *)handle; +	struct bgp *bgp = rfd->bgp; +	; +	int num; -  if (!rfd->rfg) -    return ESTALE; +	if (!rfd->rfg) +		return ESTALE; -  if (!is_valid_rfd (rfd)) -    return EBADF; +	if (!is_valid_rfd(rfd)) +		return EBADF; -  /* preemptive */ -  if (!bgp || !bgp->rfapi) -    return ENXIO; +	/* preemptive */ +	if (!bgp || !bgp->rfapi) +		return ENXIO; -  if (bgp->rfapi->flags & RFAPI_INCALLBACK) -    return EDEADLK; +	if (bgp->rfapi->flags & RFAPI_INCALLBACK) +		return EDEADLK; -  num = rfapiMonitorDelHd (rfd); +	num = rfapiMonitorDelHd(rfd); -  if (count) -    *count = num; +	if (count) +		*count = num; -  return 0; +	return 0;  } -void -rfapi_free_next_hop_list (struct rfapi_next_hop_entry *list) +void rfapi_free_next_hop_list(struct rfapi_next_hop_entry *list)  { -  struct rfapi_next_hop_entry *nh; -  struct rfapi_next_hop_entry *next; - -  for (nh = list; nh; nh = next) -    { -      next = nh->next; -      rfapi_un_options_free (nh->un_options); -      nh->un_options = NULL; -      rfapi_vn_options_free (nh->vn_options); -      nh->vn_options = NULL; -      XFREE (MTYPE_RFAPI_NEXTHOP, nh); -    } +	struct rfapi_next_hop_entry *nh; +	struct rfapi_next_hop_entry *next; + +	for (nh = list; nh; nh = next) { +		next = nh->next; +		rfapi_un_options_free(nh->un_options); +		nh->un_options = NULL; +		rfapi_vn_options_free(nh->vn_options); +		nh->vn_options = NULL; +		XFREE(MTYPE_RFAPI_NEXTHOP, nh); +	}  }  /*   * NULL handle => return total count across all nves   */ -uint32_t -rfapi_monitor_count (void *handle) +uint32_t rfapi_monitor_count(void *handle)  { -  struct bgp *bgp = bgp_get_default (); -  uint32_t count; +	struct bgp *bgp = bgp_get_default(); +	uint32_t count; -  if (handle) -    { -      struct rfapi_descriptor *rfd = (struct rfapi_descriptor *) handle; -      count = rfd->monitor_count; -    } -  else -    { +	if (handle) { +		struct rfapi_descriptor *rfd = +			(struct rfapi_descriptor *)handle; +		count = rfd->monitor_count; +	} else { -      if (!bgp || !bgp->rfapi) -        return 0; +		if (!bgp || !bgp->rfapi) +			return 0; -      count = bgp->rfapi->monitor_count; -    } +		count = bgp->rfapi->monitor_count; +	} -  return count; +	return count;  }  /*********************************************************************** @@ -3077,8 +2861,8 @@ DEFUN (debug_rfapi_show_nves,         SHOW_STR         "NVE Information\n")  { -  rfapiPrintMatchingDescriptors (vty, NULL, NULL); -  return CMD_SUCCESS; +	rfapiPrintMatchingDescriptors(vty, NULL, NULL); +	return CMD_SUCCESS;  }  DEFUN ( @@ -3094,28 +2878,23 @@ DEFUN (    "IPv4 address\n"    "IPv6 address\n")  { -  struct prefix pfx; - -  if (!str2prefix (argv[5]->arg, &pfx)) -    { -      vty_out (vty, "Malformed address \"%s\"\n", argv[5]->arg); -      return CMD_WARNING_CONFIG_FAILED; -    } -  if (pfx.family != AF_INET && pfx.family != AF_INET6) -    { -      vty_out (vty, "Invalid address \"%s\"\n", argv[5]->arg); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (argv[4]->arg[0] == 'u') -    { -      rfapiPrintMatchingDescriptors (vty, NULL, &pfx); -    } -  else -    { -      rfapiPrintMatchingDescriptors (vty, &pfx, NULL); -    } -  return CMD_SUCCESS; +	struct prefix pfx; + +	if (!str2prefix(argv[5]->arg, &pfx)) { +		vty_out(vty, "Malformed address \"%s\"\n", argv[5]->arg); +		return CMD_WARNING_CONFIG_FAILED; +	} +	if (pfx.family != AF_INET && pfx.family != AF_INET6) { +		vty_out(vty, "Invalid address \"%s\"\n", argv[5]->arg); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (argv[4]->arg[0] == 'u') { +		rfapiPrintMatchingDescriptors(vty, NULL, &pfx); +	} else { +		rfapiPrintMatchingDescriptors(vty, &pfx, NULL); +	} +	return CMD_SUCCESS;  }  /* @@ -3123,29 +2902,27 @@ DEFUN (   * with a stream pointing to a vty, the user will have to type something   * before the callback output shows up   */ -static void -test_nexthops_callback ( -//    struct rfapi_ip_addr        *target, -                         struct rfapi_next_hop_entry *next_hops, -                         void *userdata) +static void test_nexthops_callback( +	//    struct rfapi_ip_addr        *target, +	struct rfapi_next_hop_entry *next_hops, void *userdata)  { -  void *stream = userdata; +	void *stream = userdata; -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; -  fp (out, "Nexthops Callback, Target=("); -  //rfapiPrintRfapiIpAddr(stream, target); -  fp (out, ")\n"); +	fp(out, "Nexthops Callback, Target=("); +	// rfapiPrintRfapiIpAddr(stream, target); +	fp(out, ")\n"); -  rfapiPrintNhl (stream, next_hops); +	rfapiPrintNhl(stream, next_hops); -  rfapi_free_next_hop_list (next_hops); +	rfapi_free_next_hop_list(next_hops);  }  DEFUN (debug_rfapi_open, @@ -3161,35 +2938,35 @@ DEFUN (debug_rfapi_open,         "underlay network interface IPv4 address\n"         "underlay network interface IPv6 address\n")  { -  struct rfapi_ip_addr vn; -  struct rfapi_ip_addr un; -  uint32_t lifetime; -  int rc; -  rfapi_handle handle; +	struct rfapi_ip_addr vn; +	struct rfapi_ip_addr un; +	uint32_t lifetime; +	int rc; +	rfapi_handle handle; -  /* -   * Get VN addr -   */ -  if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[4]->arg, &vn))) -    return rc; +	/* +	 * Get VN addr +	 */ +	if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[4]->arg, &vn))) +		return rc; -  /* -   * Get UN addr -   */ -  if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[6]->arg, &un))) -    return rc; +	/* +	 * Get UN addr +	 */ +	if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[6]->arg, &un))) +		return rc; -  rc = rfapi_open (rfapi_get_rfp_start_val_by_bgp (bgp_get_default ()), -                   &vn, &un, /*&uo */ NULL, &lifetime, NULL, &handle); +	rc = rfapi_open(rfapi_get_rfp_start_val_by_bgp(bgp_get_default()), &vn, +			&un, /*&uo */ NULL, &lifetime, NULL, &handle); -  vty_out (vty, "rfapi_open: status %d, handle %p, lifetime %d\n", -           rc, handle, lifetime); +	vty_out(vty, "rfapi_open: status %d, handle %p, lifetime %d\n", rc, +		handle, lifetime); -  rc = rfapi_set_response_cb (handle, test_nexthops_callback); +	rc = rfapi_set_response_cb(handle, test_nexthops_callback); -  vty_out (vty, "rfapi_set_response_cb: status %d\n", rc); +	vty_out(vty, "rfapi_set_response_cb: status %d\n", rc); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  } @@ -3206,37 +2983,36 @@ DEFUN (debug_rfapi_close_vn_un,         "underlay network interface IPv4 address\n"         "underlay network interface IPv6 address\n")  { -  struct rfapi_ip_addr vn; -  struct rfapi_ip_addr un; -  rfapi_handle handle; -  int rc; +	struct rfapi_ip_addr vn; +	struct rfapi_ip_addr un; +	rfapi_handle handle; +	int rc; -  /* -   * Get VN addr -   */ -  if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[4]->arg, &vn))) -    return rc; +	/* +	 * Get VN addr +	 */ +	if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[4]->arg, &vn))) +		return rc; -  /* -   * Get UN addr -   */ -  if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[6]->arg, &un))) -    return rc; +	/* +	 * Get UN addr +	 */ +	if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[6]->arg, &un))) +		return rc; -  if (rfapi_find_handle_vty (vty, &vn, &un, &handle)) -    { -      vty_out (vty, "can't locate handle matching vn=%s, un=%s\n", -               argv[4]->arg, argv[6]->arg); -      return CMD_WARNING_CONFIG_FAILED; -    } +	if (rfapi_find_handle_vty(vty, &vn, &un, &handle)) { +		vty_out(vty, "can't locate handle matching vn=%s, un=%s\n", +			argv[4]->arg, argv[6]->arg); +		return CMD_WARNING_CONFIG_FAILED; +	} -  rc = rfapi_close (handle); +	rc = rfapi_close(handle); -  vty_out (vty, "rfapi_close(handle=%p): status %d\n", handle,rc); +	vty_out(vty, "rfapi_close(handle=%p): status %d\n", handle, rc); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (debug_rfapi_close_rfd, @@ -3247,23 +3023,22 @@ DEFUN (debug_rfapi_close_rfd,         "rfapi_close\n"         "indicate handle follows\n" "rfapi handle in hexadecimal\n")  { -  rfapi_handle handle; -  int rc; -  char *endptr = NULL; +	rfapi_handle handle; +	int rc; +	char *endptr = NULL; -  handle = (rfapi_handle) (uintptr_t) (strtoull (argv[4]->arg, &endptr, 16)); +	handle = (rfapi_handle)(uintptr_t)(strtoull(argv[4]->arg, &endptr, 16)); -  if (*endptr != '\0' || (uintptr_t) handle == UINTPTR_MAX) -    { -      vty_out (vty, "Invalid value: %s\n", argv[4]->arg); -      return CMD_WARNING_CONFIG_FAILED; -    } +	if (*endptr != '\0' || (uintptr_t)handle == UINTPTR_MAX) { +		vty_out(vty, "Invalid value: %s\n", argv[4]->arg); +		return CMD_WARNING_CONFIG_FAILED; +	} -  rc = rfapi_close (handle); +	rc = rfapi_close(handle); -  vty_out (vty, "rfapi_close(handle=%p): status %d\n", handle,rc); +	vty_out(vty, "rfapi_close(handle=%p): status %d\n", handle, rc); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (debug_rfapi_register_vn_un, @@ -3284,68 +3059,61 @@ DEFUN (debug_rfapi_register_vn_un,         "indicate lifetime follows\n"         "lifetime\n")  { -  struct rfapi_ip_addr vn; -  struct rfapi_ip_addr un; -  rfapi_handle handle; -  struct prefix pfx; -  uint32_t lifetime; -  struct rfapi_ip_prefix hpfx; -  int rc; - -  /* -   * Get VN addr -   */ -  if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[4]->arg, &vn))) -    return rc; - - -  /* -   * Get UN addr -   */ -  if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[6]->arg, &un))) -    return rc; - - -  if (rfapi_find_handle_vty (vty, &vn, &un, &handle)) -    { -      vty_out (vty, "can't locate handle matching vn=%s, un=%s\n", -               argv[4]->arg, argv[6]->arg); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  /* -   * Get prefix to advertise -   */ -  if (!str2prefix (argv[8]->arg, &pfx)) -    { -      vty_out (vty, "Malformed prefix \"%s\"\n", argv[8]->arg); -      return CMD_WARNING_CONFIG_FAILED; -    } -  if (pfx.family != AF_INET && pfx.family != AF_INET6) -    { -      vty_out (vty, "Bad family for prefix \"%s\"\n", argv[8]->arg); -      return CMD_WARNING_CONFIG_FAILED; -    } -  rfapiQprefix2Rprefix (&pfx, &hpfx); - -  if (strmatch(argv[10]->text, "infinite")) -    { -      lifetime = RFAPI_INFINITE_LIFETIME; -    } -  else -    { -      lifetime = strtoul(argv[10]->arg, NULL, 10); -    } - - -  rc = rfapi_register (handle, &hpfx, lifetime, NULL, NULL, 0); -  if (rc) -    { -      vty_out (vty, "rfapi_register failed with rc=%d (%s)\n", rc, -               strerror(rc)); -    } - -  return CMD_SUCCESS; +	struct rfapi_ip_addr vn; +	struct rfapi_ip_addr un; +	rfapi_handle handle; +	struct prefix pfx; +	uint32_t lifetime; +	struct rfapi_ip_prefix hpfx; +	int rc; + +	/* +	 * Get VN addr +	 */ +	if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[4]->arg, &vn))) +		return rc; + + +	/* +	 * Get UN addr +	 */ +	if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[6]->arg, &un))) +		return rc; + + +	if (rfapi_find_handle_vty(vty, &vn, &un, &handle)) { +		vty_out(vty, "can't locate handle matching vn=%s, un=%s\n", +			argv[4]->arg, argv[6]->arg); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	/* +	 * Get prefix to advertise +	 */ +	if (!str2prefix(argv[8]->arg, &pfx)) { +		vty_out(vty, "Malformed prefix \"%s\"\n", argv[8]->arg); +		return CMD_WARNING_CONFIG_FAILED; +	} +	if (pfx.family != AF_INET && pfx.family != AF_INET6) { +		vty_out(vty, "Bad family for prefix \"%s\"\n", argv[8]->arg); +		return CMD_WARNING_CONFIG_FAILED; +	} +	rfapiQprefix2Rprefix(&pfx, &hpfx); + +	if (strmatch(argv[10]->text, "infinite")) { +		lifetime = RFAPI_INFINITE_LIFETIME; +	} else { +		lifetime = strtoul(argv[10]->arg, NULL, 10); +	} + + +	rc = rfapi_register(handle, &hpfx, lifetime, NULL, NULL, 0); +	if (rc) { +		vty_out(vty, "rfapi_register failed with rc=%d (%s)\n", rc, +			strerror(rc)); +	} + +	return CMD_SUCCESS;  }  DEFUN (debug_rfapi_register_vn_un_l2o, @@ -3370,91 +3138,82 @@ DEFUN (debug_rfapi_register_vn_un_l2o,         "indicate lni follows\n"         "lni value range\n")  { -  struct rfapi_ip_addr vn; -  struct rfapi_ip_addr un; -  rfapi_handle handle; -  struct prefix pfx; -  uint32_t lifetime; -  struct rfapi_ip_prefix hpfx; -  int rc; -  struct rfapi_vn_option optary[10];    /* XXX must be big enough */ -  struct rfapi_vn_option *opt = NULL; -  int opt_next = 0; - -  /* -   * Get VN addr -   */ -  if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[4]->arg, &vn))) -    return rc; - - -  /* -   * Get UN addr -   */ -  if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[6]->arg, &un))) -    return rc; - - -  if (rfapi_find_handle_vty (vty, &vn, &un, &handle)) -    { -      vty_out (vty, "can't locate handle matching vn=%s, un=%s\n", -               argv[4]->arg, argv[6]->arg); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  /* -   * Get prefix to advertise -   */ -  if (!str2prefix (argv[8]->arg, &pfx)) -    { -      vty_out (vty, "Malformed prefix \"%s\"\n", argv[8]->arg); -      return CMD_WARNING_CONFIG_FAILED; -    } -  if (pfx.family != AF_INET && pfx.family != AF_INET6) -    { -      vty_out (vty, "Bad family for prefix \"%s\"\n", argv[8]->arg); -      return CMD_WARNING_CONFIG_FAILED; -    } -  rfapiQprefix2Rprefix (&pfx, &hpfx); - -  if (strmatch(argv[10]->text, "infinite")) -    { -      lifetime = RFAPI_INFINITE_LIFETIME; -    } -  else -    { -      lifetime = strtoul(argv[10]->arg, NULL, 10); -    } - -  /* L2 option parsing START */ -  memset (optary, 0, sizeof (optary)); -  optary[opt_next].v.l2addr.logical_net_id = strtoul(argv[14]->arg, NULL, 10); -  if ((rc = rfapiStr2EthAddr (argv[12]->arg, &optary[opt_next].v.l2addr.macaddr))) -    { -      vty_out (vty, "Bad mac address \"%s\"\n", argv[12]->arg); -      return CMD_WARNING_CONFIG_FAILED; -    } -  optary[opt_next].type = RFAPI_VN_OPTION_TYPE_L2ADDR; -  if (opt_next) -    { -      optary[opt_next - 1].next = optary + opt_next; -    } -  else -    { -      opt = optary; -    } -  ++opt_next; -  /* L2 option parsing END */ - -  /* TBD fixme */ -  rc = rfapi_register (handle, &hpfx, lifetime, NULL /* &uo */ , opt, 0); -  if (rc) -    { -      vty_out (vty, "rfapi_register failed with rc=%d (%s)\n", rc, -               strerror(rc)); -    } - -  return CMD_SUCCESS; +	struct rfapi_ip_addr vn; +	struct rfapi_ip_addr un; +	rfapi_handle handle; +	struct prefix pfx; +	uint32_t lifetime; +	struct rfapi_ip_prefix hpfx; +	int rc; +	struct rfapi_vn_option optary[10]; /* XXX must be big enough */ +	struct rfapi_vn_option *opt = NULL; +	int opt_next = 0; + +	/* +	 * Get VN addr +	 */ +	if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[4]->arg, &vn))) +		return rc; + + +	/* +	 * Get UN addr +	 */ +	if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[6]->arg, &un))) +		return rc; + + +	if (rfapi_find_handle_vty(vty, &vn, &un, &handle)) { +		vty_out(vty, "can't locate handle matching vn=%s, un=%s\n", +			argv[4]->arg, argv[6]->arg); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	/* +	 * Get prefix to advertise +	 */ +	if (!str2prefix(argv[8]->arg, &pfx)) { +		vty_out(vty, "Malformed prefix \"%s\"\n", argv[8]->arg); +		return CMD_WARNING_CONFIG_FAILED; +	} +	if (pfx.family != AF_INET && pfx.family != AF_INET6) { +		vty_out(vty, "Bad family for prefix \"%s\"\n", argv[8]->arg); +		return CMD_WARNING_CONFIG_FAILED; +	} +	rfapiQprefix2Rprefix(&pfx, &hpfx); + +	if (strmatch(argv[10]->text, "infinite")) { +		lifetime = RFAPI_INFINITE_LIFETIME; +	} else { +		lifetime = strtoul(argv[10]->arg, NULL, 10); +	} + +	/* L2 option parsing START */ +	memset(optary, 0, sizeof(optary)); +	optary[opt_next].v.l2addr.logical_net_id = +		strtoul(argv[14]->arg, NULL, 10); +	if ((rc = rfapiStr2EthAddr(argv[12]->arg, +				   &optary[opt_next].v.l2addr.macaddr))) { +		vty_out(vty, "Bad mac address \"%s\"\n", argv[12]->arg); +		return CMD_WARNING_CONFIG_FAILED; +	} +	optary[opt_next].type = RFAPI_VN_OPTION_TYPE_L2ADDR; +	if (opt_next) { +		optary[opt_next - 1].next = optary + opt_next; +	} else { +		opt = optary; +	} +	++opt_next; +	/* L2 option parsing END */ + +	/* TBD fixme */ +	rc = rfapi_register(handle, &hpfx, lifetime, NULL /* &uo */, opt, 0); +	if (rc) { +		vty_out(vty, "rfapi_register failed with rc=%d (%s)\n", rc, +			strerror(rc)); +	} + +	return CMD_SUCCESS;  } @@ -3470,52 +3229,49 @@ DEFUN (debug_rfapi_unregister_vn_un,         "underlay network interface address\n"         "indicate prefix follows\n" "prefix")  { -  struct rfapi_ip_addr vn; -  struct rfapi_ip_addr un; -  rfapi_handle handle; -  struct prefix pfx; -  struct rfapi_ip_prefix hpfx; -  int rc; - -  /* -   * Get VN addr -   */ -  if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[4]->arg, &vn))) -    return rc; - - -  /* -   * Get UN addr -   */ -  if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[6]->arg, &un))) -    return rc; - - -  if (rfapi_find_handle_vty (vty, &vn, &un, &handle)) -    { -      vty_out (vty, "can't locate handle matching vn=%s, un=%s\n", -               argv[4]->arg, argv[6]->arg); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  /* -   * Get prefix to advertise -   */ -  if (!str2prefix (argv[8]->arg, &pfx)) -    { -      vty_out (vty, "Malformed prefix \"%s\"\n", argv[8]->arg); -      return CMD_WARNING_CONFIG_FAILED; -    } -  if (pfx.family != AF_INET && pfx.family != AF_INET6) -    { -      vty_out (vty, "Bad family for prefix \"%s\"\n", argv[8]->arg); -      return CMD_WARNING_CONFIG_FAILED; -    } -  rfapiQprefix2Rprefix (&pfx, &hpfx); - -  rfapi_register (handle, &hpfx, 0, NULL, NULL, 1); - -  return CMD_SUCCESS; +	struct rfapi_ip_addr vn; +	struct rfapi_ip_addr un; +	rfapi_handle handle; +	struct prefix pfx; +	struct rfapi_ip_prefix hpfx; +	int rc; + +	/* +	 * Get VN addr +	 */ +	if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[4]->arg, &vn))) +		return rc; + + +	/* +	 * Get UN addr +	 */ +	if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[6]->arg, &un))) +		return rc; + + +	if (rfapi_find_handle_vty(vty, &vn, &un, &handle)) { +		vty_out(vty, "can't locate handle matching vn=%s, un=%s\n", +			argv[4]->arg, argv[6]->arg); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	/* +	 * Get prefix to advertise +	 */ +	if (!str2prefix(argv[8]->arg, &pfx)) { +		vty_out(vty, "Malformed prefix \"%s\"\n", argv[8]->arg); +		return CMD_WARNING_CONFIG_FAILED; +	} +	if (pfx.family != AF_INET && pfx.family != AF_INET6) { +		vty_out(vty, "Bad family for prefix \"%s\"\n", argv[8]->arg); +		return CMD_WARNING_CONFIG_FAILED; +	} +	rfapiQprefix2Rprefix(&pfx, &hpfx); + +	rfapi_register(handle, &hpfx, 0, NULL, NULL, 1); + +	return CMD_SUCCESS;  }  DEFUN (debug_rfapi_query_vn_un, @@ -3534,60 +3290,57 @@ DEFUN (debug_rfapi_query_vn_un,         "target IPv4 address\n"         "target IPv6 address\n")  { -  struct rfapi_ip_addr vn; -  struct rfapi_ip_addr un; -  struct rfapi_ip_addr target; -  rfapi_handle handle; -  int rc; -  struct rfapi_next_hop_entry *pNextHopEntry; - -  /* -   * Get VN addr -   */ -  if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[4]->arg, &vn))) -    return rc; - - -  /* -   * Get UN addr -   */ -  if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[6]->arg, &un))) -    return rc; - - -  /* -   * Get target addr -   */ -  if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[8]->arg, &target))) -    return rc; - - -  if (rfapi_find_handle_vty (vty, &vn, &un, &handle)) -    { -      vty_out (vty, "can't locate handle matching vn=%s, un=%s\n", -               argv[4]->arg, argv[6]->arg); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  /* -   * options parameter not used? Set to NULL for now -   */ -  rc = rfapi_query (handle, &target, NULL, &pNextHopEntry); - -  if (rc) -    { -      vty_out (vty, "rfapi_query failed with rc=%d (%s)\n", rc, -               strerror(rc)); -    } -  else -    { -      /* -       * print nexthop list -       */ -      test_nexthops_callback ( /*&target, */ pNextHopEntry, vty);       /* frees nh list! */ -    } - -  return CMD_SUCCESS; +	struct rfapi_ip_addr vn; +	struct rfapi_ip_addr un; +	struct rfapi_ip_addr target; +	rfapi_handle handle; +	int rc; +	struct rfapi_next_hop_entry *pNextHopEntry; + +	/* +	 * Get VN addr +	 */ +	if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[4]->arg, &vn))) +		return rc; + + +	/* +	 * Get UN addr +	 */ +	if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[6]->arg, &un))) +		return rc; + + +	/* +	 * Get target addr +	 */ +	if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[8]->arg, &target))) +		return rc; + + +	if (rfapi_find_handle_vty(vty, &vn, &un, &handle)) { +		vty_out(vty, "can't locate handle matching vn=%s, un=%s\n", +			argv[4]->arg, argv[6]->arg); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	/* +	 * options parameter not used? Set to NULL for now +	 */ +	rc = rfapi_query(handle, &target, NULL, &pNextHopEntry); + +	if (rc) { +		vty_out(vty, "rfapi_query failed with rc=%d (%s)\n", rc, +			strerror(rc)); +	} else { +		/* +		 * print nexthop list +		 */ +		test_nexthops_callback(/*&target, */ pNextHopEntry, +				       vty); /* frees nh list! */ +	} + +	return CMD_SUCCESS;  } @@ -3608,28 +3361,28 @@ DEFUN (debug_rfapi_query_vn_un_l2o,         "indicate target MAC addr follows\n"         "target MAC addr\n")  { -  struct rfapi_ip_addr vn; -  struct rfapi_ip_addr un; -  struct rfapi_ip_addr target; -  rfapi_handle handle; -  int rc; -  struct rfapi_next_hop_entry *pNextHopEntry; -  struct rfapi_l2address_option l2o_buf; -  struct bgp_tea_options hopt; -  uint8_t valbuf[14]; - -  /* -   * Get VN addr -   */ -  if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[4]->arg, &vn))) -    return rc; - - -  /* -   * Get UN addr -   */ -  if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[6]->arg, &un))) -    return rc; +	struct rfapi_ip_addr vn; +	struct rfapi_ip_addr un; +	struct rfapi_ip_addr target; +	rfapi_handle handle; +	int rc; +	struct rfapi_next_hop_entry *pNextHopEntry; +	struct rfapi_l2address_option l2o_buf; +	struct bgp_tea_options hopt; +	uint8_t valbuf[14]; + +	/* +	 * Get VN addr +	 */ +	if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[4]->arg, &vn))) +		return rc; + + +	/* +	 * Get UN addr +	 */ +	if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[6]->arg, &un))) +		return rc;  #if 0 /* there is no IP target arg here ?????? */ @@ -3639,65 +3392,61 @@ DEFUN (debug_rfapi_query_vn_un_l2o,    if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[2], &target)))      return rc;  #else -  vty_out (vty, "%% This command is broken.\n"); -  return CMD_WARNING_CONFIG_FAILED; +	vty_out(vty, "%% This command is broken.\n"); +	return CMD_WARNING_CONFIG_FAILED;  #endif -  if (rfapi_find_handle_vty (vty, &vn, &un, &handle)) -    { -      vty_out (vty, "can't locate handle matching vn=%s, un=%s\n", -               argv[4]->arg, argv[6]->arg); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  /* -   * Set up L2 parameters -   */ -  memset (&l2o_buf, 0, sizeof (l2o_buf)); -  if (rfapiStr2EthAddr (argv[10]->arg, &l2o_buf.macaddr)) -    { -      vty_out (vty, "Bad mac address \"%s\"\n", argv[10]->arg); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  l2o_buf.logical_net_id = strtoul(argv[8]->arg, NULL, 10); - -  /* construct option chain */ - -  memset (valbuf, 0, sizeof (valbuf)); -  memcpy (valbuf, &l2o_buf.macaddr.octet, ETHER_ADDR_LEN); -  valbuf[11] = (l2o_buf.logical_net_id >> 16) & 0xff; -  valbuf[12] = (l2o_buf.logical_net_id >> 8) & 0xff; -  valbuf[13] = l2o_buf.logical_net_id & 0xff; - -  memset (&hopt, 0, sizeof (hopt)); -  hopt.options_count = 1; -  hopt.options_length = sizeof (valbuf);        /* is this right? */ -  hopt.type = RFAPI_VN_OPTION_TYPE_L2ADDR; -  hopt.length = sizeof (valbuf); -  hopt.value = valbuf; - - -  /* -   * options parameter not used? Set to NULL for now -   */ -  rc = rfapi_query (handle, &target, &l2o_buf, &pNextHopEntry); - -  if (rc) -    { -      vty_out (vty, "rfapi_query failed with rc=%d (%s)\n", rc, -               strerror(rc)); -    } -  else -    { -      /* -       * print nexthop list -       */ -      /* TBD enhance to print L2 information */ -      test_nexthops_callback ( /*&target, */ pNextHopEntry, vty);       /* frees nh list! */ -    } - -  return CMD_SUCCESS; +	if (rfapi_find_handle_vty(vty, &vn, &un, &handle)) { +		vty_out(vty, "can't locate handle matching vn=%s, un=%s\n", +			argv[4]->arg, argv[6]->arg); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	/* +	 * Set up L2 parameters +	 */ +	memset(&l2o_buf, 0, sizeof(l2o_buf)); +	if (rfapiStr2EthAddr(argv[10]->arg, &l2o_buf.macaddr)) { +		vty_out(vty, "Bad mac address \"%s\"\n", argv[10]->arg); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	l2o_buf.logical_net_id = strtoul(argv[8]->arg, NULL, 10); + +	/* construct option chain */ + +	memset(valbuf, 0, sizeof(valbuf)); +	memcpy(valbuf, &l2o_buf.macaddr.octet, ETHER_ADDR_LEN); +	valbuf[11] = (l2o_buf.logical_net_id >> 16) & 0xff; +	valbuf[12] = (l2o_buf.logical_net_id >> 8) & 0xff; +	valbuf[13] = l2o_buf.logical_net_id & 0xff; + +	memset(&hopt, 0, sizeof(hopt)); +	hopt.options_count = 1; +	hopt.options_length = sizeof(valbuf); /* is this right? */ +	hopt.type = RFAPI_VN_OPTION_TYPE_L2ADDR; +	hopt.length = sizeof(valbuf); +	hopt.value = valbuf; + + +	/* +	 * options parameter not used? Set to NULL for now +	 */ +	rc = rfapi_query(handle, &target, &l2o_buf, &pNextHopEntry); + +	if (rc) { +		vty_out(vty, "rfapi_query failed with rc=%d (%s)\n", rc, +			strerror(rc)); +	} else { +		/* +		 * print nexthop list +		 */ +		/* TBD enhance to print L2 information */ +		test_nexthops_callback(/*&target, */ pNextHopEntry, +				       vty); /* frees nh list! */ +	} + +	return CMD_SUCCESS;  } @@ -3718,48 +3467,47 @@ DEFUN (debug_rfapi_query_done_vn_un,         "Target IPv4 address\n"         "Target IPv6 address\n")  { -  struct rfapi_ip_addr vn; -  struct rfapi_ip_addr un; -  struct rfapi_ip_addr target; -  rfapi_handle handle; -  int rc; +	struct rfapi_ip_addr vn; +	struct rfapi_ip_addr un; +	struct rfapi_ip_addr target; +	rfapi_handle handle; +	int rc; -  /* -   * Get VN addr -   */ -  if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[5]->arg, &vn))) -    return rc; +	/* +	 * Get VN addr +	 */ +	if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[5]->arg, &vn))) +		return rc; -  /* -   * Get UN addr -   */ -  if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[7]->arg, &un))) -    return rc; +	/* +	 * Get UN addr +	 */ +	if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[7]->arg, &un))) +		return rc; -  /* -   * Get target addr -   */ -  if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[9]->arg, &target))) -    return rc; +	/* +	 * Get target addr +	 */ +	if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[9]->arg, &target))) +		return rc; -  if (rfapi_find_handle_vty (vty, &vn, &un, &handle)) -    { -      vty_out (vty, "can't locate handle matching vn=%s, un=%s\n", -               argv[5]->arg, argv[7]->arg); -      return CMD_WARNING_CONFIG_FAILED; -    } +	if (rfapi_find_handle_vty(vty, &vn, &un, &handle)) { +		vty_out(vty, "can't locate handle matching vn=%s, un=%s\n", +			argv[5]->arg, argv[7]->arg); +		return CMD_WARNING_CONFIG_FAILED; +	} -  /* -   * options parameter not used? Set to NULL for now -   */ -  rc = rfapi_query_done (handle, &target); +	/* +	 * options parameter not used? Set to NULL for now +	 */ +	rc = rfapi_query_done(handle, &target); -  vty_out (vty, "rfapi_query_done returned %d\n", rc); +	vty_out(vty, "rfapi_query_done returned %d\n", rc); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (debug_rfapi_show_import, @@ -3770,83 +3518,82 @@ DEFUN (debug_rfapi_show_import,         SHOW_STR         "import\n")  { -  struct bgp *bgp; -  struct rfapi *h; -  struct rfapi_import_table *it; -  char *s; -  int first_l2 = 1; - -  /* -   * Show all import tables -   */ - -  bgp = bgp_get_default ();     /* assume 1 instance for now */ -  if (!bgp) -    { -      vty_out (vty, "No BGP instance\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  h = bgp->rfapi; -  if (!h) -    { -      vty_out (vty, "No RFAPI instance\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  /* -   * Iterate over all import tables; do a filtered import -   * for the afi/safi combination -   */ - - -  for (it = h->imports; it; it = it->next) -    { -      s = ecommunity_ecom2str (it->rt_import_list, -                               ECOMMUNITY_FORMAT_ROUTE_MAP, 0); -      vty_out (vty, "Import Table %p, RTs: %s\n", it, s); -      XFREE (MTYPE_ECOMMUNITY_STR, s); - -      rfapiShowImportTable (vty, "IP VPN", it->imported_vpn[AFI_IP], 1); -      rfapiShowImportTable (vty, "IP ENCAP", it->imported_encap[AFI_IP], 0); -      rfapiShowImportTable (vty, "IP6 VPN", it->imported_vpn[AFI_IP6], 1); -      rfapiShowImportTable (vty, "IP6 ENCAP", it->imported_encap[AFI_IP6], 0); -    } - -  if (h->import_mac) -    { -      void *cursor = NULL; -      uint32_t lni; -      uintptr_t lni_as_ptr; -      int rc; -      char buf[BUFSIZ]; - -      for (rc = -           skiplist_next (h->import_mac, (void **) &lni_as_ptr, (void **) &it, -                          &cursor); !rc; -           rc = -           skiplist_next (h->import_mac, (void **) &lni_as_ptr, (void **) &it, -                          &cursor)) -        { - -          if (it->imported_vpn[AFI_L2VPN]) -            { -              lni = lni_as_ptr; -              if (first_l2) -                { -                  vty_out (vty, "\nLNI-based Ethernet Tables:\n"); -                  first_l2 = 0; -                } -              snprintf (buf, BUFSIZ, "L2VPN LNI=%u", lni); -              rfapiShowImportTable (vty, buf, it->imported_vpn[AFI_L2VPN], 1); -            } -        } -    } - -  rfapiShowImportTable (vty, "CE IT - IP VPN", -                        h->it_ce->imported_vpn[AFI_IP], 1); - -  return CMD_SUCCESS; +	struct bgp *bgp; +	struct rfapi *h; +	struct rfapi_import_table *it; +	char *s; +	int first_l2 = 1; + +	/* +	 * Show all import tables +	 */ + +	bgp = bgp_get_default(); /* assume 1 instance for now */ +	if (!bgp) { +		vty_out(vty, "No BGP instance\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	h = bgp->rfapi; +	if (!h) { +		vty_out(vty, "No RFAPI instance\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	/* +	 * Iterate over all import tables; do a filtered import +	 * for the afi/safi combination +	 */ + + +	for (it = h->imports; it; it = it->next) { +		s = ecommunity_ecom2str(it->rt_import_list, +					ECOMMUNITY_FORMAT_ROUTE_MAP, 0); +		vty_out(vty, "Import Table %p, RTs: %s\n", it, s); +		XFREE(MTYPE_ECOMMUNITY_STR, s); + +		rfapiShowImportTable(vty, "IP VPN", it->imported_vpn[AFI_IP], +				     1); +		rfapiShowImportTable(vty, "IP ENCAP", +				     it->imported_encap[AFI_IP], 0); +		rfapiShowImportTable(vty, "IP6 VPN", it->imported_vpn[AFI_IP6], +				     1); +		rfapiShowImportTable(vty, "IP6 ENCAP", +				     it->imported_encap[AFI_IP6], 0); +	} + +	if (h->import_mac) { +		void *cursor = NULL; +		uint32_t lni; +		uintptr_t lni_as_ptr; +		int rc; +		char buf[BUFSIZ]; + +		for (rc = skiplist_next(h->import_mac, (void **)&lni_as_ptr, +					(void **)&it, &cursor); +		     !rc; +		     rc = skiplist_next(h->import_mac, (void **)&lni_as_ptr, +					(void **)&it, &cursor)) { + +			if (it->imported_vpn[AFI_L2VPN]) { +				lni = lni_as_ptr; +				if (first_l2) { +					vty_out(vty, +						"\nLNI-based Ethernet Tables:\n"); +					first_l2 = 0; +				} +				snprintf(buf, BUFSIZ, "L2VPN LNI=%u", lni); +				rfapiShowImportTable( +					vty, buf, it->imported_vpn[AFI_L2VPN], +					1); +			} +		} +	} + +	rfapiShowImportTable(vty, "CE IT - IP VPN", +			     h->it_ce->imported_vpn[AFI_IP], 1); + +	return CMD_SUCCESS;  }  DEFUN (debug_rfapi_show_import_vn_un, @@ -3863,45 +3610,44 @@ DEFUN (debug_rfapi_show_import_vn_un,         "underlay network interface IPv4 address\n"         "underlay network interface IPv6 address\n")  { -  struct rfapi_ip_addr vn; -  struct rfapi_ip_addr un; -  rfapi_handle handle; -  int rc; -  struct rfapi_descriptor *rfd; - -  /* -   * Get VN addr -   */ -  if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[5]->arg, &vn))) -    return rc; - - -  /* -   * Get UN addr -   */ -  if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[7]->arg, &un))) -    return rc; - - -  if (rfapi_find_handle_vty (vty, &vn, &un, &handle)) -    { -      vty_out (vty, "can't locate handle matching vn=%s, un=%s\n", -               argv[5]->arg, argv[7]->arg); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  rfd = (struct rfapi_descriptor *) handle; - -  rfapiShowImportTable (vty, "IP VPN", -                        rfd->import_table->imported_vpn[AFI_IP], 1); -  rfapiShowImportTable (vty, "IP ENCAP", -                        rfd->import_table->imported_encap[AFI_IP], 0); -  rfapiShowImportTable (vty, "IP6 VPN", -                        rfd->import_table->imported_vpn[AFI_IP6], 1); -  rfapiShowImportTable (vty, "IP6 ENCAP", -                        rfd->import_table->imported_encap[AFI_IP6], 0); - -  return CMD_SUCCESS; +	struct rfapi_ip_addr vn; +	struct rfapi_ip_addr un; +	rfapi_handle handle; +	int rc; +	struct rfapi_descriptor *rfd; + +	/* +	 * Get VN addr +	 */ +	if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[5]->arg, &vn))) +		return rc; + + +	/* +	 * Get UN addr +	 */ +	if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[7]->arg, &un))) +		return rc; + + +	if (rfapi_find_handle_vty(vty, &vn, &un, &handle)) { +		vty_out(vty, "can't locate handle matching vn=%s, un=%s\n", +			argv[5]->arg, argv[7]->arg); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	rfd = (struct rfapi_descriptor *)handle; + +	rfapiShowImportTable(vty, "IP VPN", +			     rfd->import_table->imported_vpn[AFI_IP], 1); +	rfapiShowImportTable(vty, "IP ENCAP", +			     rfd->import_table->imported_encap[AFI_IP], 0); +	rfapiShowImportTable(vty, "IP6 VPN", +			     rfd->import_table->imported_vpn[AFI_IP6], 1); +	rfapiShowImportTable(vty, "IP6 ENCAP", +			     rfd->import_table->imported_encap[AFI_IP6], 0); + +	return CMD_SUCCESS;  }  DEFUN (debug_rfapi_response_omit_self, @@ -3912,25 +3658,25 @@ DEFUN (debug_rfapi_response_omit_self,         "Omit self in RFP responses\n"         "filter out self from responses\n" "leave self in responses\n")  { -  struct bgp *bgp = bgp_get_default (); - -  if (!bgp) -    { -      vty_out (vty, "No BGP process is configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } -  if (!bgp->rfapi_cfg) -    { -      vty_out (vty, "VNC not configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  if (strmatch(argv[3]->text, "on")) -    SET_FLAG (bgp->rfapi_cfg->flags, BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP); -  else -    UNSET_FLAG (bgp->rfapi_cfg->flags, BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP); - -  return CMD_SUCCESS; +	struct bgp *bgp = bgp_get_default(); + +	if (!bgp) { +		vty_out(vty, "No BGP process is configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} +	if (!bgp->rfapi_cfg) { +		vty_out(vty, "VNC not configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	if (strmatch(argv[3]->text, "on")) +		SET_FLAG(bgp->rfapi_cfg->flags, +			 BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP); +	else +		UNSET_FLAG(bgp->rfapi_cfg->flags, +			   BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP); + +	return CMD_SUCCESS;  } @@ -3943,9 +3689,9 @@ DEFUN (skiplist_test_cli,         "skiplist command\n"         "test\n")  { -  skiplist_test (vty); +	skiplist_test(vty); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (skiplist_debug_cli, @@ -3954,151 +3700,139 @@ DEFUN (skiplist_debug_cli,         "skiplist command\n"         "debug\n")  { -  skiplist_debug (vty, NULL); -  return CMD_SUCCESS; +	skiplist_debug(vty, NULL); +	return CMD_SUCCESS;  }  #endif /* RFAPI_DEBUG_SKIPLIST_CLI */ -void -rfapi_init (void) +void rfapi_init(void)  { -  bgp_rfapi_cfg_init (); -  vnc_debug_init(); +	bgp_rfapi_cfg_init(); +	vnc_debug_init(); -  install_element (ENABLE_NODE, &debug_rfapi_show_import_cmd); -  install_element (ENABLE_NODE, &debug_rfapi_show_import_vn_un_cmd); +	install_element(ENABLE_NODE, &debug_rfapi_show_import_cmd); +	install_element(ENABLE_NODE, &debug_rfapi_show_import_vn_un_cmd); -  install_element (ENABLE_NODE, &debug_rfapi_open_cmd); -  install_element (ENABLE_NODE, &debug_rfapi_close_vn_un_cmd); -  install_element (ENABLE_NODE, &debug_rfapi_close_rfd_cmd); -  install_element (ENABLE_NODE, &debug_rfapi_register_vn_un_cmd); -  install_element (ENABLE_NODE, &debug_rfapi_unregister_vn_un_cmd); -  install_element (ENABLE_NODE, &debug_rfapi_query_vn_un_cmd); -  install_element (ENABLE_NODE, &debug_rfapi_query_vn_un_done_cmd); -  install_element (ENABLE_NODE, &debug_rfapi_query_vn_un_l2o_cmd); +	install_element(ENABLE_NODE, &debug_rfapi_open_cmd); +	install_element(ENABLE_NODE, &debug_rfapi_close_vn_un_cmd); +	install_element(ENABLE_NODE, &debug_rfapi_close_rfd_cmd); +	install_element(ENABLE_NODE, &debug_rfapi_register_vn_un_cmd); +	install_element(ENABLE_NODE, &debug_rfapi_unregister_vn_un_cmd); +	install_element(ENABLE_NODE, &debug_rfapi_query_vn_un_cmd); +	install_element(ENABLE_NODE, &debug_rfapi_query_vn_un_done_cmd); +	install_element(ENABLE_NODE, &debug_rfapi_query_vn_un_l2o_cmd); -  install_element (ENABLE_NODE, &debug_rfapi_response_omit_self_cmd); +	install_element(ENABLE_NODE, &debug_rfapi_response_omit_self_cmd); -  /* Need the following show commands for gpz test scripts */ -  install_element (ENABLE_NODE, &debug_rfapi_show_nves_cmd); -  install_element (ENABLE_NODE, &debug_rfapi_show_nves_vn_un_cmd); -  install_element (ENABLE_NODE, &debug_rfapi_register_vn_un_l2o_cmd); +	/* Need the following show commands for gpz test scripts */ +	install_element(ENABLE_NODE, &debug_rfapi_show_nves_cmd); +	install_element(ENABLE_NODE, &debug_rfapi_show_nves_vn_un_cmd); +	install_element(ENABLE_NODE, &debug_rfapi_register_vn_un_l2o_cmd);  #ifdef RFAPI_DEBUG_SKIPLIST_CLI -  install_element (ENABLE_NODE, &skiplist_test_cli_cmd); -  install_element (ENABLE_NODE, &skiplist_debug_cli_cmd); +	install_element(ENABLE_NODE, &skiplist_test_cli_cmd); +	install_element(ENABLE_NODE, &skiplist_debug_cli_cmd);  #endif -  rfapi_vty_init (); +	rfapi_vty_init();  }  #ifdef DEBUG_RFAPI -static void -rfapi_print_exported (struct bgp *bgp) +static void rfapi_print_exported(struct bgp *bgp)  { -  struct bgp_node *rdn; -  struct bgp_node *rn; -  struct bgp_info *bi; - -  if (!bgp) -    return; - -  for (rdn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rdn; -       rdn = bgp_route_next (rdn)) -    { -      if (!rdn->info) -        continue; -      fprintf (stderr, "%s: vpn rdn=%p\n", __func__, rdn); -      for (rn = bgp_table_top (rdn->info); rn; rn = bgp_route_next (rn)) -        { -          if (!rn->info) -            continue; -          fprintf (stderr, "%s: rn=%p\n", __func__, rn); -          for (bi = rn->info; bi; bi = bi->next) -            { -              rfapiPrintBi ((void *) 2, bi);    /* 2 => stderr */ -            } -        } -    } -  for (rdn = bgp_table_top (bgp->rib[AFI_IP][SAFI_ENCAP]); rdn; -       rdn = bgp_route_next (rdn)) -    { -      if (!rdn->info) -        continue; -      fprintf (stderr, "%s: encap rdn=%p\n", __func__, rdn); -      for (rn = bgp_table_top (rdn->info); rn; rn = bgp_route_next (rn)) -        { -          if (!rn->info) -            continue; -          fprintf (stderr, "%s: rn=%p\n", __func__, rn); -          for (bi = rn->info; bi; bi = bi->next) -            { -              rfapiPrintBi ((void *) 2, bi);    /* 2 => stderr */ -            } -        } -    } - +	struct bgp_node *rdn; +	struct bgp_node *rn; +	struct bgp_info *bi; + +	if (!bgp) +		return; + +	for (rdn = bgp_table_top(bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rdn; +	     rdn = bgp_route_next(rdn)) { +		if (!rdn->info) +			continue; +		fprintf(stderr, "%s: vpn rdn=%p\n", __func__, rdn); +		for (rn = bgp_table_top(rdn->info); rn; +		     rn = bgp_route_next(rn)) { +			if (!rn->info) +				continue; +			fprintf(stderr, "%s: rn=%p\n", __func__, rn); +			for (bi = rn->info; bi; bi = bi->next) { +				rfapiPrintBi((void *)2, bi); /* 2 => stderr */ +			} +		} +	} +	for (rdn = bgp_table_top(bgp->rib[AFI_IP][SAFI_ENCAP]); rdn; +	     rdn = bgp_route_next(rdn)) { +		if (!rdn->info) +			continue; +		fprintf(stderr, "%s: encap rdn=%p\n", __func__, rdn); +		for (rn = bgp_table_top(rdn->info); rn; +		     rn = bgp_route_next(rn)) { +			if (!rn->info) +				continue; +			fprintf(stderr, "%s: rn=%p\n", __func__, rn); +			for (bi = rn->info; bi; bi = bi->next) { +				rfapiPrintBi((void *)2, bi); /* 2 => stderr */ +			} +		} +	}  }  #endif /* defined(DEBUG_RFAPI) */  /*   * Free all memory to prepare for clean exit as seen by valgrind memcheck   */ -void -rfapi_delete (struct bgp *bgp) +void rfapi_delete(struct bgp *bgp)  { -  extern void rfp_clear_vnc_nve_all (void);     /* can't fix correctly yet */ - -  /* -   * This clears queries and registered routes, and closes nves -   */ -  if (bgp->rfapi) -    rfp_clear_vnc_nve_all (); -  bgp_rfapi_cfg_destroy (bgp, bgp->rfapi_cfg); -  bgp->rfapi_cfg = NULL; -  bgp_rfapi_destroy (bgp, bgp->rfapi); -  bgp->rfapi = NULL; +	extern void rfp_clear_vnc_nve_all(void); /* can't fix correctly yet */ + +	/* +	 * This clears queries and registered routes, and closes nves +	 */ +	if (bgp->rfapi) +		rfp_clear_vnc_nve_all(); +	bgp_rfapi_cfg_destroy(bgp, bgp->rfapi_cfg); +	bgp->rfapi_cfg = NULL; +	bgp_rfapi_destroy(bgp, bgp->rfapi); +	bgp->rfapi = NULL;  #ifdef DEBUG_RFAPI -  /* -   * show what's left in the BGP MPLSVPN RIB -   */ -  rfapi_print_exported (bgp); +	/* +	 * show what's left in the BGP MPLSVPN RIB +	 */ +	rfapi_print_exported(bgp);  #endif -  } -int -rfapi_set_autord_from_vn (struct prefix_rd *rd, struct rfapi_ip_addr *vn) +int rfapi_set_autord_from_vn(struct prefix_rd *rd, struct rfapi_ip_addr *vn)  { -  vnc_zlog_debug_verbose ("%s: auto-assigning RD", __func__); -  if (vn->addr_family != AF_INET -      && vn->addr_family != AF_INET6) -    { -      vnc_zlog_debug_verbose ("%s: can't auto-assign RD, VN addr family is not IPv4" -                  "|v6" -                  , __func__); -      return EAFNOSUPPORT; -    } -  rd->family = AF_UNSPEC; -  rd->prefixlen = 64; -  rd->val[1] = RD_TYPE_IP; -  if (vn->addr_family == AF_INET) -    { -      memcpy (rd->val + 2, &vn->addr.v4.s_addr, 4); -    } -  else -    {                           /* is v6 */ -      memcpy (rd->val + 2, &vn->addr.v6.s6_addr32[3], 4);/* low order 4 bytes */ -    } -  { -    char buf[BUFSIZ]; -    buf[0] = 0; -    prefix_rd2str (rd, buf, BUFSIZ); -    buf[BUFSIZ - 1] = 0; -    vnc_zlog_debug_verbose ("%s: auto-RD is set to %s", __func__, buf); -  } -  return 0; +	vnc_zlog_debug_verbose("%s: auto-assigning RD", __func__); +	if (vn->addr_family != AF_INET && vn->addr_family != AF_INET6) { +		vnc_zlog_debug_verbose( +			"%s: can't auto-assign RD, VN addr family is not IPv4" +			"|v6", +			__func__); +		return EAFNOSUPPORT; +	} +	rd->family = AF_UNSPEC; +	rd->prefixlen = 64; +	rd->val[1] = RD_TYPE_IP; +	if (vn->addr_family == AF_INET) { +		memcpy(rd->val + 2, &vn->addr.v4.s_addr, 4); +	} else { /* is v6 */ +		memcpy(rd->val + 2, &vn->addr.v6.s6_addr32[3], +		       4); /* low order 4 bytes */ +	} +	{ +		char buf[BUFSIZ]; +		buf[0] = 0; +		prefix_rd2str(rd, buf, BUFSIZ); +		buf[BUFSIZ - 1] = 0; +		vnc_zlog_debug_verbose("%s: auto-RD is set to %s", __func__, +				       buf); +	} +	return 0;  }  /*------------------------------------------ @@ -4106,7 +3840,7 @@ rfapi_set_autord_from_vn (struct prefix_rd *rd, struct rfapi_ip_addr *vn)   *   * Find bgp instance pointer based on value returned by rfp_start   * - * input:  + * input:   *      rfp_start_val     value returned by rfp_startor   *                        NULL (=get default instance)   * @@ -4118,19 +3852,19 @@ rfapi_set_autord_from_vn (struct prefix_rd *rd, struct rfapi_ip_addr *vn)   *      NULL = not found   *   --------------------------------------------*/ -struct bgp * -rfapi_bgp_lookup_by_rfp (void *rfp_start_val) +struct bgp *rfapi_bgp_lookup_by_rfp(void *rfp_start_val)  { -  struct bgp *bgp = NULL; -  struct listnode *node, *nnode; - -  if (rfp_start_val == NULL) -    bgp = bgp_get_default (); -  else -    for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp)) -      if (bgp->rfapi != NULL && bgp->rfapi->rfp == rfp_start_val) -        return bgp; -  return bgp; +	struct bgp *bgp = NULL; +	struct listnode *node, *nnode; + +	if (rfp_start_val == NULL) +		bgp = bgp_get_default(); +	else +		for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) +			if (bgp->rfapi != NULL +			    && bgp->rfapi->rfp == rfp_start_val) +				return bgp; +	return bgp;  }  /*------------------------------------------ @@ -4138,7 +3872,7 @@ rfapi_bgp_lookup_by_rfp (void *rfp_start_val)   *   * Find bgp instance pointer based on value returned by rfp_start   * - * input:  + * input:   *	bgp             bgp instance pointer   *   * output: @@ -4149,91 +3883,81 @@ rfapi_bgp_lookup_by_rfp (void *rfp_start_val)   *      NULL = not found   *   --------------------------------------------*/ -void * -rfapi_get_rfp_start_val_by_bgp (struct bgp *bgp) +void *rfapi_get_rfp_start_val_by_bgp(struct bgp *bgp)  { -  if (!bgp || !bgp->rfapi) -    return NULL; -  return bgp->rfapi->rfp; +	if (!bgp || !bgp->rfapi) +		return NULL; +	return bgp->rfapi->rfp;  }  /***********************************************************************   *		 RFP group specific configuration   ***********************************************************************/ -static void * -rfapi_rfp_get_or_init_group_config_default ( -  struct rfapi_cfg	*rfc, -  struct vty		*vty, -  uint32_t		size) +static void *rfapi_rfp_get_or_init_group_config_default(struct rfapi_cfg *rfc, +							struct vty *vty, +							uint32_t size)  { -  if (rfc->default_rfp_cfg == NULL && size > 0) -    { -      rfc->default_rfp_cfg = XCALLOC (MTYPE_RFAPI_RFP_GROUP_CFG, size); -      vnc_zlog_debug_verbose ("%s: allocated, size=%d", __func__, size); - -    } -  return rfc->default_rfp_cfg; +	if (rfc->default_rfp_cfg == NULL && size > 0) { +		rfc->default_rfp_cfg = XCALLOC(MTYPE_RFAPI_RFP_GROUP_CFG, size); +		vnc_zlog_debug_verbose("%s: allocated, size=%d", __func__, +				       size); +	} +	return rfc->default_rfp_cfg;  } -static void * -rfapi_rfp_get_or_init_group_config_nve ( -  struct rfapi_cfg	*rfc, -  struct vty		*vty, -  uint32_t		size) +static void *rfapi_rfp_get_or_init_group_config_nve(struct rfapi_cfg *rfc, +						    struct vty *vty, +						    uint32_t size)  { -  struct rfapi_nve_group_cfg *rfg = VTY_GET_CONTEXT_SUB(rfapi_nve_group_cfg); - -  /* make sure group is still in list */ -  if (!rfg || !listnode_lookup (rfc->nve_groups_sequential, rfg)) -    { -      /* Not in list anymore */ -      vty_out (vty, "Current NVE group no longer exists\n"); -      return NULL; -    } - -  if (rfg->rfp_cfg == NULL && size > 0) -    { -      rfg->rfp_cfg = XCALLOC (MTYPE_RFAPI_RFP_GROUP_CFG, size); -      vnc_zlog_debug_verbose ("%s: allocated, size=%d", __func__, size); - -    } -  return rfg->rfp_cfg; +	struct rfapi_nve_group_cfg *rfg = +		VTY_GET_CONTEXT_SUB(rfapi_nve_group_cfg); + +	/* make sure group is still in list */ +	if (!rfg || !listnode_lookup(rfc->nve_groups_sequential, rfg)) { +		/* Not in list anymore */ +		vty_out(vty, "Current NVE group no longer exists\n"); +		return NULL; +	} + +	if (rfg->rfp_cfg == NULL && size > 0) { +		rfg->rfp_cfg = XCALLOC(MTYPE_RFAPI_RFP_GROUP_CFG, size); +		vnc_zlog_debug_verbose("%s: allocated, size=%d", __func__, +				       size); +	} +	return rfg->rfp_cfg;  } -static void * -rfapi_rfp_get_or_init_group_config_l2 ( -  struct rfapi_cfg	*rfc, -  struct vty		*vty, -  uint32_t		size) +static void *rfapi_rfp_get_or_init_group_config_l2(struct rfapi_cfg *rfc, +						   struct vty *vty, +						   uint32_t size)  { -  struct rfapi_l2_group_cfg *rfg = VTY_GET_CONTEXT_SUB(rfapi_l2_group_cfg); - -  /* make sure group is still in list */ -  if (!rfg || !listnode_lookup (rfc->l2_groups, rfg)) -    { -      /* Not in list anymore */ -      vty_out (vty, "Current L2 group no longer exists\n"); -      return NULL; -    } -  if (rfg->rfp_cfg == NULL && size > 0) -    { -      rfg->rfp_cfg = XCALLOC (MTYPE_RFAPI_RFP_GROUP_CFG, size); -      vnc_zlog_debug_verbose ("%s: allocated, size=%d", __func__, size); - -    } -  return rfg->rfp_cfg; +	struct rfapi_l2_group_cfg *rfg = +		VTY_GET_CONTEXT_SUB(rfapi_l2_group_cfg); + +	/* make sure group is still in list */ +	if (!rfg || !listnode_lookup(rfc->l2_groups, rfg)) { +		/* Not in list anymore */ +		vty_out(vty, "Current L2 group no longer exists\n"); +		return NULL; +	} +	if (rfg->rfp_cfg == NULL && size > 0) { +		rfg->rfp_cfg = XCALLOC(MTYPE_RFAPI_RFP_GROUP_CFG, size); +		vnc_zlog_debug_verbose("%s: allocated, size=%d", __func__, +				       size); +	} +	return rfg->rfp_cfg;  }  /*------------------------------------------   * rfapi_rfp_init_group_config_ptr_vty   *   * This is used to init or return a previously init'ed group specific - * configuration pointer. Group is identified by vty context.  + * configuration pointer. Group is identified by vty context.   * NOTE: size is ignored when a previously init'ed value is returned.   * RFAPI frees rfp_cfg_group when group is deleted during reconfig,   * bgp restart or shutdown.   * - * input:  + * input:   *    rfp_start_val     value returned by rfp_start   *    type              group type   *    vty               quagga vty context @@ -4242,46 +3966,43 @@ rfapi_rfp_get_or_init_group_config_l2 (   * output:   *    none   * - * return value:  + * return value:   *    rfp_cfg_group     NULL or Pointer to configuration structure  --------------------------------------------*/ -void * -rfapi_rfp_init_group_config_ptr_vty ( -  void				*rfp_start_val, -  rfapi_rfp_cfg_group_type	type, -  struct vty			*vty, -  uint32_t			size) +void *rfapi_rfp_init_group_config_ptr_vty(void *rfp_start_val, +					  rfapi_rfp_cfg_group_type type, +					  struct vty *vty, uint32_t size)  { -  struct bgp *bgp; -  void *ret = NULL; - -  if (rfp_start_val == NULL || vty == NULL) -    return NULL; - -  bgp = rfapi_bgp_lookup_by_rfp (rfp_start_val); -  if (!bgp || !bgp->rfapi_cfg) -    return NULL; - -  switch (type) -    { -    case RFAPI_RFP_CFG_GROUP_DEFAULT: -      ret = rfapi_rfp_get_or_init_group_config_default (bgp->rfapi_cfg, -                                                        vty, size); -      break; -    case RFAPI_RFP_CFG_GROUP_NVE: -      ret = rfapi_rfp_get_or_init_group_config_nve (bgp->rfapi_cfg, -                                                    vty, size); -      break; -    case RFAPI_RFP_CFG_GROUP_L2: -      ret = rfapi_rfp_get_or_init_group_config_l2 (bgp->rfapi_cfg, vty, size); -      break; -    default: -      zlog_err ("%s: Unknown group type=%d", __func__, type); -      /* should never happen */ -      assert ("Unknown type" == NULL); -      break; -    } -  return ret; +	struct bgp *bgp; +	void *ret = NULL; + +	if (rfp_start_val == NULL || vty == NULL) +		return NULL; + +	bgp = rfapi_bgp_lookup_by_rfp(rfp_start_val); +	if (!bgp || !bgp->rfapi_cfg) +		return NULL; + +	switch (type) { +	case RFAPI_RFP_CFG_GROUP_DEFAULT: +		ret = rfapi_rfp_get_or_init_group_config_default(bgp->rfapi_cfg, +								 vty, size); +		break; +	case RFAPI_RFP_CFG_GROUP_NVE: +		ret = rfapi_rfp_get_or_init_group_config_nve(bgp->rfapi_cfg, +							     vty, size); +		break; +	case RFAPI_RFP_CFG_GROUP_L2: +		ret = rfapi_rfp_get_or_init_group_config_l2(bgp->rfapi_cfg, vty, +							    size); +		break; +	default: +		zlog_err("%s: Unknown group type=%d", __func__, type); +		/* should never happen */ +		assert("Unknown type" == NULL); +		break; +	} +	return ret;  }  /*------------------------------------------ @@ -4290,9 +4011,9 @@ rfapi_rfp_init_group_config_ptr_vty (   * This is used to get group specific configuration pointer.   * Group is identified by type and vty context.   * RFAPI frees rfp_cfg_group when group is deleted during reconfig, - * bgp restart or shutdown.  + * bgp restart or shutdown.   * - * input:  + * input:   *    rfp_start_val     value returned by rfp_start   *    type              group type   *    vty               quagga vty context @@ -4301,64 +4022,56 @@ rfapi_rfp_init_group_config_ptr_vty (   *    none   *   * return value: - *    rfp_cfg_group     Pointer to configuration structure  + *    rfp_cfg_group     Pointer to configuration structure  --------------------------------------------*/ -void * -rfapi_rfp_get_group_config_ptr_vty ( -  void				*rfp_start_val, -  rfapi_rfp_cfg_group_type	type, -  struct vty			*vty) +void *rfapi_rfp_get_group_config_ptr_vty(void *rfp_start_val, +					 rfapi_rfp_cfg_group_type type, +					 struct vty *vty)  { -  return rfapi_rfp_init_group_config_ptr_vty (rfp_start_val, type, vty, 0); +	return rfapi_rfp_init_group_config_ptr_vty(rfp_start_val, type, vty, 0);  }  static void * -rfapi_rfp_get_group_config_name_nve ( -  struct rfapi_cfg		*rfc, -  const char			*name, -  void				*criteria, -  rfp_group_config_search_cb_t	*search_cb) +rfapi_rfp_get_group_config_name_nve(struct rfapi_cfg *rfc, const char *name, +				    void *criteria, +				    rfp_group_config_search_cb_t *search_cb)  { -  struct rfapi_nve_group_cfg *rfg; -  struct listnode *node; - -  for (ALL_LIST_ELEMENTS_RO (rfc->nve_groups_sequential, node, rfg)) -    { -      if (!strcmp (rfg->name, name) &&  /* name match */ -          (search_cb == NULL || !search_cb (criteria, rfg->rfp_cfg))) -        return rfg->rfp_cfg; -    } -  return NULL; +	struct rfapi_nve_group_cfg *rfg; +	struct listnode *node; + +	for (ALL_LIST_ELEMENTS_RO(rfc->nve_groups_sequential, node, rfg)) { +		if (!strcmp(rfg->name, name) && /* name match */ +		    (search_cb == NULL || !search_cb(criteria, rfg->rfp_cfg))) +			return rfg->rfp_cfg; +	} +	return NULL;  }  static void * -rfapi_rfp_get_group_config_name_l2 ( -  struct rfapi_cfg		*rfc, -  const char			*name, -  void				*criteria, -  rfp_group_config_search_cb_t	*search_cb) +rfapi_rfp_get_group_config_name_l2(struct rfapi_cfg *rfc, const char *name, +				   void *criteria, +				   rfp_group_config_search_cb_t *search_cb)  { -  struct rfapi_l2_group_cfg *rfg; -  struct listnode *node; - -  for (ALL_LIST_ELEMENTS_RO (rfc->l2_groups, node, rfg)) -    { -      if (!strcmp (rfg->name, name) &&  /* name match */ -          (search_cb == NULL || !search_cb (criteria, rfg->rfp_cfg))) -        return rfg->rfp_cfg; -    } -  return NULL; +	struct rfapi_l2_group_cfg *rfg; +	struct listnode *node; + +	for (ALL_LIST_ELEMENTS_RO(rfc->l2_groups, node, rfg)) { +		if (!strcmp(rfg->name, name) && /* name match */ +		    (search_cb == NULL || !search_cb(criteria, rfg->rfp_cfg))) +			return rfg->rfp_cfg; +	} +	return NULL;  }  /*------------------------------------------   * rfapi_rfp_get_group_config_ptr_name   *   * This is used to get group specific configuration pointer. - * Group is identified by type and name context.  + * Group is identified by type and name context.   * RFAPI frees rfp_cfg_group when group is deleted during reconfig,   * bgp restart or shutdown.   * - * input:  + * input:   *    rfp_start_val     value returned by rfp_start   *    type              group type   *    name              group name @@ -4369,46 +4082,41 @@ rfapi_rfp_get_group_config_name_l2 (   *    none   *   * return value: - *    rfp_cfg_group     Pointer to configuration structure  + *    rfp_cfg_group     Pointer to configuration structure  --------------------------------------------*/ -void * -rfapi_rfp_get_group_config_ptr_name ( -  void				*rfp_start_val, -  rfapi_rfp_cfg_group_type	type, -  const char			*name, -  void				*criteria, -  rfp_group_config_search_cb_t	*search_cb) +void *rfapi_rfp_get_group_config_ptr_name( +	void *rfp_start_val, rfapi_rfp_cfg_group_type type, const char *name, +	void *criteria, rfp_group_config_search_cb_t *search_cb)  { -  struct bgp *bgp; -  void *ret = NULL; - -  if (rfp_start_val == NULL || name == NULL) -    return NULL; - -  bgp = rfapi_bgp_lookup_by_rfp (rfp_start_val); -  if (!bgp || !bgp->rfapi_cfg) -    return NULL; - -  switch (type) -    { -    case RFAPI_RFP_CFG_GROUP_DEFAULT: -      ret = bgp->rfapi_cfg->default_rfp_cfg; -      break; -    case RFAPI_RFP_CFG_GROUP_NVE: -      ret = rfapi_rfp_get_group_config_name_nve (bgp->rfapi_cfg, -                                                 name, criteria, search_cb); -      break; -    case RFAPI_RFP_CFG_GROUP_L2: -      ret = rfapi_rfp_get_group_config_name_l2 (bgp->rfapi_cfg, -                                                name, criteria, search_cb); -      break; -    default: -      zlog_err ("%s: Unknown group type=%d", __func__, type); -      /* should never happen */ -      assert ("Unknown type" == NULL); -      break; -    } -  return ret; +	struct bgp *bgp; +	void *ret = NULL; + +	if (rfp_start_val == NULL || name == NULL) +		return NULL; + +	bgp = rfapi_bgp_lookup_by_rfp(rfp_start_val); +	if (!bgp || !bgp->rfapi_cfg) +		return NULL; + +	switch (type) { +	case RFAPI_RFP_CFG_GROUP_DEFAULT: +		ret = bgp->rfapi_cfg->default_rfp_cfg; +		break; +	case RFAPI_RFP_CFG_GROUP_NVE: +		ret = rfapi_rfp_get_group_config_name_nve(bgp->rfapi_cfg, name, +							  criteria, search_cb); +		break; +	case RFAPI_RFP_CFG_GROUP_L2: +		ret = rfapi_rfp_get_group_config_name_l2(bgp->rfapi_cfg, name, +							 criteria, search_cb); +		break; +	default: +		zlog_err("%s: Unknown group type=%d", __func__, type); +		/* should never happen */ +		assert("Unknown type" == NULL); +		break; +	} +	return ret;  }  /*------------------------------------------ @@ -4419,7 +4127,7 @@ rfapi_rfp_get_group_config_ptr_name (   * RFAPI frees rfp_cfg_group when group is deleted during reconfig,   * bgp restart or shutdown.   * - * input:  + * input:   *    rfp_start_val     value returned by rfp_start   *    type              group type   *    logical_net_id    group logical network identifier @@ -4430,35 +4138,34 @@ rfapi_rfp_get_group_config_ptr_name (   *    none   *   * return value: - *    rfp_cfg_group     Pointer to configuration structure  + *    rfp_cfg_group     Pointer to configuration structure  --------------------------------------------*/  void * -rfapi_rfp_get_l2_group_config_ptr_lni ( -  void				*rfp_start_val, -  uint32_t			logical_net_id, -  void				*criteria, -  rfp_group_config_search_cb_t	*search_cb) +rfapi_rfp_get_l2_group_config_ptr_lni(void *rfp_start_val, +				      uint32_t logical_net_id, void *criteria, +				      rfp_group_config_search_cb_t *search_cb)  { -  struct bgp *bgp; -  struct rfapi_l2_group_cfg *rfg; -  struct listnode *node; - -  if (rfp_start_val == NULL) -    return NULL; - -  bgp = rfapi_bgp_lookup_by_rfp (rfp_start_val); -  if (!bgp || !bgp->rfapi_cfg) -    return NULL; - -  for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->l2_groups, node, rfg)) -    { -      if (rfg->logical_net_id == logical_net_id && -          (search_cb == NULL || !search_cb (criteria, rfg->rfp_cfg))) -        { -          if (rfg->rfp_cfg == NULL) -            vnc_zlog_debug_verbose ("%s: returning rfp group config for lni=0", __func__); -          return rfg->rfp_cfg; -        } -    } -  return NULL; +	struct bgp *bgp; +	struct rfapi_l2_group_cfg *rfg; +	struct listnode *node; + +	if (rfp_start_val == NULL) +		return NULL; + +	bgp = rfapi_bgp_lookup_by_rfp(rfp_start_val); +	if (!bgp || !bgp->rfapi_cfg) +		return NULL; + +	for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->l2_groups, node, rfg)) { +		if (rfg->logical_net_id == logical_net_id +		    && (search_cb == NULL +			|| !search_cb(criteria, rfg->rfp_cfg))) { +			if (rfg->rfp_cfg == NULL) +				vnc_zlog_debug_verbose( +					"%s: returning rfp group config for lni=0", +					__func__); +			return rfg->rfp_cfg; +		} +	} +	return NULL;  } diff --git a/bgpd/rfapi/rfapi.h b/bgpd/rfapi/rfapi.h index 11d41c9d1d..8eb0d717df 100644 --- a/bgpd/rfapi/rfapi.h +++ b/bgpd/rfapi/rfapi.h @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2009-2016, LabN Consulting, L.L.C.   * @@ -32,138 +32,127 @@  #include "bgpd/bgp_encap_types.h"  /* probably ought to have a field-specific define in config.h */ -# ifndef s6_addr32              /* for solaris/bsd */ -#  ifdef SOLARIS_IPV6 +#ifndef s6_addr32 /* for solaris/bsd */ +#ifdef SOLARIS_IPV6  #   define	s6_addr32	_S6_un._S6_u32 -#  else +#else  #   define	s6_addr32	__u6_addr.__u6_addr32 -#  endif -# endif +#endif +#endif  #define RFAPI_V4_ADDR 0x04  #define RFAPI_V6_ADDR 0x06  #define RFAPI_SHOW_STR "VNC information\n" -struct rfapi_ip_addr -{ -  uint8_t addr_family;          /* AF_INET | AF_INET6 */ -  union -  { -    struct in_addr v4;          /* in network order */ -    struct in6_addr v6;         /* in network order */ -  } addr; +struct rfapi_ip_addr { +	uint8_t addr_family; /* AF_INET | AF_INET6 */ +	union { +		struct in_addr v4;  /* in network order */ +		struct in6_addr v6; /* in network order */ +	} addr;  }; -struct rfapi_ip_prefix -{ -  uint8_t length; -  uint8_t cost;                 /* bgp local pref = 255 - cost */ -  struct rfapi_ip_addr prefix; +struct rfapi_ip_prefix { +	uint8_t length; +	uint8_t cost; /* bgp local pref = 255 - cost */ +	struct rfapi_ip_addr prefix;  }; -struct rfapi_nexthop -{ -  struct prefix addr; -  uint8_t cost; +struct rfapi_nexthop { +	struct prefix addr; +	uint8_t cost;  }; -struct rfapi_next_hop_entry -{ -  struct rfapi_next_hop_entry	*next; -  struct rfapi_ip_prefix	prefix; -  uint32_t			lifetime; -  struct rfapi_ip_addr		un_address; -  struct rfapi_ip_addr		vn_address; -  struct rfapi_vn_option	*vn_options; -  struct rfapi_un_option	*un_options; +struct rfapi_next_hop_entry { +	struct rfapi_next_hop_entry *next; +	struct rfapi_ip_prefix prefix; +	uint32_t lifetime; +	struct rfapi_ip_addr un_address; +	struct rfapi_ip_addr vn_address; +	struct rfapi_vn_option *vn_options; +	struct rfapi_un_option *un_options;  };  #define RFAPI_REMOVE_RESPONSE_LIFETIME  0  #define RFAPI_INFINITE_LIFETIME         0xFFFFFFFF -struct rfapi_l2address_option -{ -  struct ethaddr	macaddr;	/* use 0 to assign label to IP prefix */ -  uint32_t		label;		/* 20bit label in low bits, no TC, S, or TTL  */ -  uint32_t		logical_net_id;	/* ~= EVPN Ethernet Segment Id, -                                   must not be zero for mac regis. */ -  uint8_t		local_nve_id; -  uint16_t		tag_id;         /* EVPN Ethernet Tag ID, 0 = none */ +struct rfapi_l2address_option { +	struct ethaddr macaddr; /* use 0 to assign label to IP prefix */ +	uint32_t label;		/* 20bit label in low bits, no TC, S, or TTL  */ +	uint32_t logical_net_id; /* ~= EVPN Ethernet Segment Id, +			    must not be zero for mac regis. */ +	uint8_t local_nve_id; +	uint16_t tag_id; /* EVPN Ethernet Tag ID, 0 = none */  }; -typedef enum -{ -  RFAPI_UN_OPTION_TYPE_PROVISIONAL,     /* internal use only */ -  RFAPI_UN_OPTION_TYPE_TUNNELTYPE, +typedef enum { +	RFAPI_UN_OPTION_TYPE_PROVISIONAL, /* internal use only */ +	RFAPI_UN_OPTION_TYPE_TUNNELTYPE,  } rfapi_un_option_type; -struct rfapi_tunneltype_option -{ -  bgp_encap_types type; -  union -  { -    struct bgp_encap_type_reserved			reserved; -    struct bgp_encap_type_l2tpv3_over_ip		l2tpv3_ip; -    struct bgp_encap_type_gre				gre; -    struct bgp_encap_type_transmit_tunnel_endpoint	transmit_tunnel_endpoint; -    struct bgp_encap_type_ipsec_in_tunnel_mode		ipsec_tunnel; -    struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode	ip_ipsec; -    struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode	mpls_ipsec; -    struct bgp_encap_type_ip_in_ip			ip_ip; -    struct bgp_encap_type_vxlan				vxlan; -    struct bgp_encap_type_nvgre				nvgre; -    struct bgp_encap_type_mpls				mpls; -    struct bgp_encap_type_mpls_in_gre			mpls_gre; -    struct bgp_encap_type_vxlan_gpe			vxlan_gpe; -    struct bgp_encap_type_mpls_in_udp			mpls_udp; -    struct bgp_encap_type_pbb				pbb; -  } bgpinfo; +struct rfapi_tunneltype_option { +	bgp_encap_types type; +	union { +		struct bgp_encap_type_reserved reserved; +		struct bgp_encap_type_l2tpv3_over_ip l2tpv3_ip; +		struct bgp_encap_type_gre gre; +		struct bgp_encap_type_transmit_tunnel_endpoint +			transmit_tunnel_endpoint; +		struct bgp_encap_type_ipsec_in_tunnel_mode ipsec_tunnel; +		struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode +			ip_ipsec; +		struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode +			mpls_ipsec; +		struct bgp_encap_type_ip_in_ip ip_ip; +		struct bgp_encap_type_vxlan vxlan; +		struct bgp_encap_type_nvgre nvgre; +		struct bgp_encap_type_mpls mpls; +		struct bgp_encap_type_mpls_in_gre mpls_gre; +		struct bgp_encap_type_vxlan_gpe vxlan_gpe; +		struct bgp_encap_type_mpls_in_udp mpls_udp; +		struct bgp_encap_type_pbb pbb; +	} bgpinfo;  }; -struct rfapi_un_option -{ -  struct rfapi_un_option		*next; -  rfapi_un_option_type			type; -  union -  { -    struct rfapi_tunneltype_option	tunnel; -  } v; +struct rfapi_un_option { +	struct rfapi_un_option *next; +	rfapi_un_option_type type; +	union { +		struct rfapi_tunneltype_option tunnel; +	} v;  }; -typedef enum -{ -  RFAPI_VN_OPTION_TYPE_L2ADDR = 3,      /* Layer 2 address, 3 for legacy compatibility */ -  RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP,   /* for static routes */ -  RFAPI_VN_OPTION_TYPE_INTERNAL_RD,     /* internal use only */ +typedef enum { +	RFAPI_VN_OPTION_TYPE_L2ADDR = +		3, /* Layer 2 address, 3 for legacy compatibility */ +	RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP, /* for static routes */ +	RFAPI_VN_OPTION_TYPE_INTERNAL_RD,   /* internal use only */  } rfapi_vn_option_type; -struct rfapi_vn_option -{ -  struct rfapi_vn_option		*next; +struct rfapi_vn_option { +	struct rfapi_vn_option *next; -  rfapi_vn_option_type			type; +	rfapi_vn_option_type type; -  union -  { -    struct rfapi_l2address_option	l2addr; +	union { +		struct rfapi_l2address_option l2addr; -    /* -     * If this option is present, the next hop is local to the -     * client NVE (i.e., not via a tunnel). -     */ -    struct rfapi_nexthop		local_nexthop; +		/* +		 * If this option is present, the next hop is local to the +		 * client NVE (i.e., not via a tunnel). +		 */ +		struct rfapi_nexthop local_nexthop; -    /* -     * For rfapi internal use only -     */ -    struct prefix_rd			internal_rd; -  } v; +		/* +		 * For rfapi internal use only +		 */ +		struct prefix_rd internal_rd; +	} v;  }; -struct rfapi_l2address_option_match -{ -  struct rfapi_l2address_option o; -  uint32_t flags; +struct rfapi_l2address_option_match { +	struct rfapi_l2address_option o; +	uint32_t flags;  #define RFAPI_L2O_MACADDR		0x00000001  #define RFAPI_L2O_LABEL			0x00000002 @@ -181,7 +170,7 @@ typedef void *rfapi_handle;  /*------------------------------------------   * rfapi_response_cb_t (callback typedef)   * - * Callbacks of this type are used to provide asynchronous  + * Callbacks of this type are used to provide asynchronous   * route updates from RFAPI to the RFP client.   *   * response_cb @@ -200,7 +189,7 @@ typedef void *rfapi_handle;   *	has been added or deleted. Deleted routes are indicated   *	with lifetime==RFAPI_REMOVE_RESPONSE_LIFETIME.   * - * input:  + * input:   *	next_hops	a list of possible next hops.   *			This is a linked list allocated within the   *			rfapi. The response_cb callback function is responsible @@ -211,16 +200,16 @@ typedef void *rfapi_handle;   *			rfapi_open()   *   *------------------------------------------*/ -typedef void (rfapi_response_cb_t) (struct rfapi_next_hop_entry * next_hops, -                                    void *userdata); +typedef void(rfapi_response_cb_t)(struct rfapi_next_hop_entry *next_hops, +				  void *userdata);  /*------------------------------------------   * rfapi_nve_close_cb_t (callback typedef)   * - * Callbacks of this type are used to provide asynchronous  + * Callbacks of this type are used to provide asynchronous   * notification that an rfapi_handle was invalidated   * - * input:  + * input:   *	pHandle		Firmerly valid rfapi_handle returned to   *			client via rfapi_open().   * @@ -228,72 +217,67 @@ typedef void (rfapi_response_cb_t) (struct rfapi_next_hop_entry * next_hops,   *			ESTALE	handle invalidated by configuration change   *   *------------------------------------------*/ -typedef void (rfapi_nve_close_cb_t) (rfapi_handle pHandle, int reason); +typedef void(rfapi_nve_close_cb_t)(rfapi_handle pHandle, int reason);  /*------------------------------------------   * rfp_cfg_write_cb_t (callback typedef)   *   * This callback is used to generate output for any config parameters - * that may supported by RFP  via RFP defined vty commands at the bgp  + * that may supported by RFP  via RFP defined vty commands at the bgp   * level.  See loglevel as an example.   * - * input:  + * input:   *    vty           -- quagga vty context   *    rfp_start_val -- value returned by rfp_start   *   * output:   *    to vty, rfp related configuration   * - * return value:  + * return value:   *    lines written  --------------------------------------------*/ -typedef int (rfp_cfg_write_cb_t) (struct vty * vty, void *rfp_start_val); +typedef int(rfp_cfg_write_cb_t)(struct vty *vty, void *rfp_start_val);  /*------------------------------------------   * rfp_cfg_group_write_cb_t (callback typedef)   *   * This callback is used to generate output for any config parameters - * that may supported by RFP via RFP defined vty commands at the  + * that may supported by RFP via RFP defined vty commands at the   * L2 or NVE level.  See loglevel as an example.   * - * input:  + * input:   *    vty              quagga vty context   *    rfp_start_val    value returned by rfp_start   *    type             group type   *    name             group name - *    rfp_cfg_group    Pointer to configuration structure  + *    rfp_cfg_group    Pointer to configuration structure   *   * output:   *    to vty, rfp related configuration   * - * return value:  + * return value:   *    lines written  --------------------------------------------*/ -typedef enum -{ -  RFAPI_RFP_CFG_GROUP_DEFAULT, -  RFAPI_RFP_CFG_GROUP_NVE, -  RFAPI_RFP_CFG_GROUP_L2 +typedef enum { +	RFAPI_RFP_CFG_GROUP_DEFAULT, +	RFAPI_RFP_CFG_GROUP_NVE, +	RFAPI_RFP_CFG_GROUP_L2  } rfapi_rfp_cfg_group_type; -typedef int (rfp_cfg_group_write_cb_t) (struct vty * vty, -                                        void *rfp_start_val, -                                        rfapi_rfp_cfg_group_type type, -                                        const char *name, -                                        void *rfp_cfg_group); +typedef int(rfp_cfg_group_write_cb_t)(struct vty *vty, void *rfp_start_val, +				      rfapi_rfp_cfg_group_type type, +				      const char *name, void *rfp_cfg_group);  /***********************************************************************   * Configuration related defines and structures   ***********************************************************************/ -struct rfapi_rfp_cb_methods -{ -  rfp_cfg_write_cb_t *cfg_cb;   /* show top level config */ -  rfp_cfg_group_write_cb_t *cfg_group_cb;       /* show group level config */ -  rfapi_response_cb_t *response_cb;     /* unsolicited responses */ -  rfapi_response_cb_t *local_cb;        /* local route add/delete */ -  rfapi_nve_close_cb_t *close_cb;       /* handle closed */ - +struct rfapi_rfp_cb_methods { +	rfp_cfg_write_cb_t *cfg_cb;		/* show top level config */ +	rfp_cfg_group_write_cb_t *cfg_group_cb; /* show group level config */ +	rfapi_response_cb_t *response_cb;       /* unsolicited responses */ +	rfapi_response_cb_t *local_cb;		/* local route add/delete */ +	rfapi_nve_close_cb_t *close_cb;		/* handle closed */  };  /* @@ -303,7 +287,7 @@ struct rfapi_rfp_cb_methods   */  #define RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY (60*120) -/*  +/*   * the factor that should be applied to a prefix's <lifetime> value   * before using it to expire a withdrawn prefix, expressed as a percent.   * Thus, a value of 100 means to use the exact value of <lifetime>, @@ -312,46 +296,44 @@ struct rfapi_rfp_cb_methods  #define RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR	150  /* - * This is used by rfapi to determine if RFP is using/supports  + * This is used by rfapi to determine if RFP is using/supports   * a partial (i.e., cache) or full table download approach for   * mapping information.  When  full table download approach is   * used all information is passed to RFP after an initial - * rfapi_query.  When partial table download is used, only  - * information matching a query is passed.   + * rfapi_query.  When partial table download is used, only + * information matching a query is passed.   */ -typedef enum -{ -  RFAPI_RFP_DOWNLOAD_PARTIAL = 0, -  RFAPI_RFP_DOWNLOAD_FULL +typedef enum { +	RFAPI_RFP_DOWNLOAD_PARTIAL = 0, +	RFAPI_RFP_DOWNLOAD_FULL  } rfapi_rfp_download_type;  #define RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL 1 -struct rfapi_rfp_cfg -{ -  /* partial or full table download */ -  rfapi_rfp_download_type download_type;        /* default=partial */ -  /* -   * When full-table-download is enabled, this is the minimum -   * number of seconds between times a non-queried prefix will -   * be updated to a particular NVE. -   * default: RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL -   */ -  uint32_t ftd_advertisement_interval; -  /* -   * percentage of registration lifetime to continue to use information -   * post soft-state refresh timeout -   default: RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR -   */ -  uint32_t holddown_factor; -  /* Control generation of updated RFP responses */ -  uint8_t use_updated_response; /* default=0/no */ -  /* when use_updated_response, also generate remove responses */ -  uint8_t use_removes;          /* default=0/no */ +struct rfapi_rfp_cfg { +	/* partial or full table download */ +	rfapi_rfp_download_type download_type; /* default=partial */ +	/* +	 * When full-table-download is enabled, this is the minimum +	 * number of seconds between times a non-queried prefix will +	 * be updated to a particular NVE. +	 * default: RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL +	 */ +	uint32_t ftd_advertisement_interval; +	/* +	 * percentage of registration lifetime to continue to use information +	 * post soft-state refresh timeout +	 default: RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR +	 */ +	uint32_t holddown_factor; +	/* Control generation of updated RFP responses */ +	uint8_t use_updated_response; /* default=0/no */ +	/* when use_updated_response, also generate remove responses */ +	uint8_t use_removes; /* default=0/no */  };  /*********************************************************************** - * Process related functions -- MUST be provided by the RFAPI user <<===  + * Process related functions -- MUST be provided by the RFAPI user <<===   ***********************************************************************/  /*------------------------------------------ @@ -359,38 +341,35 @@ struct rfapi_rfp_cfg   *   * This function will start the RFP code   * - * input:  + * input:   *    master    quagga thread_master to tie into bgpd threads - *  + *   * output: - *    cfgp      Pointer to rfapi_rfp_cfg (null = use defaults),  + *    cfgp      Pointer to rfapi_rfp_cfg (null = use defaults),   *              copied by caller, updated via rfp_set_configuration   *    cbmp      Pointer to rfapi_rfp_cb_methods, may be null   *              copied by caller, updated via rfapi_rfp_set_cb_methods - * return value:  + * return value:   *    rfp_start_val rfp returned value passed on rfp_stop and other rfapi calls  --------------------------------------------*/ -extern void * -rfp_start ( -  struct thread_master		*master, -  struct rfapi_rfp_cfg		**cfgp, -  struct rfapi_rfp_cb_methods	**cbmp); +extern void *rfp_start(struct thread_master *master, +		       struct rfapi_rfp_cfg **cfgp, +		       struct rfapi_rfp_cb_methods **cbmp);  /*------------------------------------------   * rfp_stop   *   * This function is called on shutdown to trigger RFP cleanup   * - * input:  + * input:   *    rfp_start_val   *   * output:   *    none   * - * return value:  + * return value:  --------------------------------------------*/ -extern void -rfp_stop (void *rfp_start_val); +extern void rfp_stop(void *rfp_start_val);  /***********************************************************************   *		 RFP processing behavior configuration @@ -399,44 +378,40 @@ rfp_stop (void *rfp_start_val);  /*------------------------------------------   * rfapi_rfp_set_configuration   * - * This is used to change rfapi's processing behavior based on  - * RFP requirements.  + * This is used to change rfapi's processing behavior based on + * RFP requirements.   * - * input:  + * input:   *    rfp_start_val     value returned by rfp_start   *    rfapi_rfp_cfg     Pointer to configuration structure   *   * output:   *    none   * - * return value:  + * return value:   *	0		Success   *	ENXIO		Unabled to locate configured BGP/VNC  --------------------------------------------*/ -extern int -rfapi_rfp_set_configuration ( -  void			*rfp_start_val, -  struct rfapi_rfp_cfg	*rfp_cfg); +extern int rfapi_rfp_set_configuration(void *rfp_start_val, +				       struct rfapi_rfp_cfg *rfp_cfg);  /*------------------------------------------   * rfapi_rfp_set_cb_methods   * - * Change registered callback functions for asynchronous notifications  + * Change registered callback functions for asynchronous notifications   * from RFAPI to the RFP client.   * - * input:  + * input:   *    rfp_start_val     value by rfp_start   *    methods		Pointer to struct rfapi_rfp_cb_methods containing   *			pointers to callback methods as described above   * - * return value:  + * return value:   *	0		Success   *	ENXIO		BGP or VNC not configured   *------------------------------------------*/ -extern int -rfapi_rfp_set_cb_methods ( -  void				*rfp_start_val, -  struct rfapi_rfp_cb_methods	*methods); +extern int rfapi_rfp_set_cb_methods(void *rfp_start_val, +				    struct rfapi_rfp_cb_methods *methods);  /***********************************************************************   *		 RFP group specific configuration @@ -446,12 +421,12 @@ rfapi_rfp_set_cb_methods (   * rfapi_rfp_init_group_config_ptr_vty   *   * This is used to init or return a previously init'ed group specific - * configuration pointer. Group is identified by vty context.  + * configuration pointer. Group is identified by vty context.   * NOTE: size is ignored when a previously init'ed value is returned.   * RFAPI frees rfp_cfg_group when group is deleted during reconfig,   * bgp restart or shutdown.   * - * input:  + * input:   *    rfp_start_val     value returned by rfp_start   *    type              group type   *    vty               quagga vty context @@ -460,25 +435,23 @@ rfapi_rfp_set_cb_methods (   * output:   *    none   * - * return value:  + * return value:   *    rfp_cfg_group     NULL or Pointer to configuration structure  --------------------------------------------*/ -extern void * -rfapi_rfp_init_group_config_ptr_vty ( -  void				*rfp_start_val, -  rfapi_rfp_cfg_group_type	type, -  struct vty			*vty, -  uint32_t			size); +extern void *rfapi_rfp_init_group_config_ptr_vty(void *rfp_start_val, +						 rfapi_rfp_cfg_group_type type, +						 struct vty *vty, +						 uint32_t size);  /*------------------------------------------   * rfapi_rfp_get_group_config_ptr_vty   *   * This is used to get group specific configuration pointer. - * Group is identified by type and vty context.  + * Group is identified by type and vty context.   * RFAPI frees rfp_cfg_group when group is deleted during reconfig,   * bgp restart or shutdown.   * - * input:  + * input:   *    rfp_start_val     value returned by rfp_start   *    type              group type   *    vty               quagga vty context @@ -487,43 +460,40 @@ rfapi_rfp_init_group_config_ptr_vty (   *    none   *   * return value: - *    rfp_cfg_group     Pointer to configuration structure  + *    rfp_cfg_group     Pointer to configuration structure  --------------------------------------------*/ -extern void * -rfapi_rfp_get_group_config_ptr_vty ( -  void				*rfp_start_val, -  rfapi_rfp_cfg_group_type	type, -  struct vty			*vty); +extern void *rfapi_rfp_get_group_config_ptr_vty(void *rfp_start_val, +						rfapi_rfp_cfg_group_type type, +						struct vty *vty);  /*------------------------------------------   * rfp_group_config_search_cb_t (callback typedef)   * - * This callback is used to called from within a  + * This callback is used to called from within a   * rfapi_rfp_get_group_config_ptr to check if the rfp_cfg_group   * matches the search criteria   * - * input:  + * input:   *    criteria          RFAPI caller provided serach criteria   *    rfp_cfg_group     Pointer to configuration structure | NULL   *   * output:   * - * return value:  + * return value:   *      0               Match/Success   *	ENOENT		No matching  --------------------------------------------*/ -typedef int (rfp_group_config_search_cb_t) (void *criteria, -                                            void *rfp_cfg_group); +typedef int(rfp_group_config_search_cb_t)(void *criteria, void *rfp_cfg_group);  /*------------------------------------------   * rfapi_rfp_get_group_config_ptr_name   *   * This is used to get group specific configuration pointer. - * Group is identified by type and name context.  + * Group is identified by type and name context.   * RFAPI frees rfp_cfg_group when group is deleted during reconfig,   * bgp restart or shutdown.   * - * input:  + * input:   *    rfp_start_val     value returned by rfp_start   *    type              group type   *    name              group name @@ -534,15 +504,11 @@ typedef int (rfp_group_config_search_cb_t) (void *criteria,   *    none   *   * return value: - *    rfp_cfg_group     Pointer to configuration structure  + *    rfp_cfg_group     Pointer to configuration structure  --------------------------------------------*/ -extern void * -rfapi_rfp_get_group_config_ptr_name ( -  void				*rfp_start_val, -  rfapi_rfp_cfg_group_type	type, -  const char			*name, -  void				*criteria, -  rfp_group_config_search_cb_t	*search_cb); +extern void *rfapi_rfp_get_group_config_ptr_name( +	void *rfp_start_val, rfapi_rfp_cfg_group_type type, const char *name, +	void *criteria, rfp_group_config_search_cb_t *search_cb);  /*------------------------------------------   * rfapi_rfp_get_l2_group_config_ptr_lni @@ -550,9 +516,9 @@ rfapi_rfp_get_group_config_ptr_name (   * This is used to get group specific configuration pointer.   * Group is identified by type and logical network identifier.   * RFAPI frees rfp_cfg_group when group is deleted during reconfig, - * bgp restart or shutdown.  + * bgp restart or shutdown.   * - * input:  + * input:   *    rfp_start_val     value returned by rfp_start   *    logical_net_id    group logical network identifier   *    criteria          RFAPI caller provided serach criteria @@ -562,14 +528,12 @@ rfapi_rfp_get_group_config_ptr_name (   *    none   *   * return value: - *    rfp_cfg_group     Pointer to configuration structure  + *    rfp_cfg_group     Pointer to configuration structure  --------------------------------------------*/  extern void * -rfapi_rfp_get_l2_group_config_ptr_lni ( -  void				*rfp_start_val, -  uint32_t			logical_net_id, -  void				*criteria, -  rfp_group_config_search_cb_t	*search_cb); +rfapi_rfp_get_l2_group_config_ptr_lni(void *rfp_start_val, +				      uint32_t logical_net_id, void *criteria, +				      rfp_group_config_search_cb_t *search_cb);  /***********************************************************************   *			NVE Sessions @@ -581,7 +545,7 @@ rfapi_rfp_get_l2_group_config_ptr_lni (   * This function initializes a NVE record and associates it with   * the specified VN and underlay network addresses   * - * input:  + * input:   *      rfp_start_val   value returned by rfp_start   *	vn		NVE virtual network address   * @@ -599,13 +563,13 @@ rfapi_rfp_get_l2_group_config_ptr_lni (   *   * output:   *	response_lifetime The length of time that responses sent to this - *			NVE are valid.  + *			NVE are valid.   *   *	pHandle		pointer to location to store rfapi handle. The   *			handle must be passed on subsequent rfapi_ calls.   *   * - * return value:  + * return value:   *	0		Success   *	EEXIST		NVE with this {vn,un} already open   *	ENOENT		No matching nve group config @@ -615,15 +579,11 @@ rfapi_rfp_get_l2_group_config_ptr_lni (   *			but underlay network address is not IPv4   *	EDEADLK		Called from within a callback procedure   *------------------------------------------*/ -extern int -rfapi_open ( -  void				*rfp_start_val, -  struct rfapi_ip_addr		*vn, -  struct rfapi_ip_addr		*un, -  struct rfapi_un_option	*default_options, -  uint32_t			*response_lifetime, -  void				*userdata, -  rfapi_handle			*pHandle); +extern int rfapi_open(void *rfp_start_val, struct rfapi_ip_addr *vn, +		      struct rfapi_ip_addr *un, +		      struct rfapi_un_option *default_options, +		      uint32_t *response_lifetime, void *userdata, +		      rfapi_handle *pHandle);  /*------------------------------------------ @@ -633,7 +593,7 @@ rfapi_open (   * from within a rfapi callback procedure is permitted (the close   * will be completed asynchronously after the callback finishes).   * - * input:  + * input:   *    rfd: rfapi descriptor returned by rfapi_open   *   * output: @@ -643,15 +603,14 @@ rfapi_open (   *	EBADF		invalid handle   *	ENXIO		BGP or VNC not configured   *------------------------------------------*/ -extern int -rfapi_close (rfapi_handle rfd); +extern int rfapi_close(rfapi_handle rfd);  /*------------------------------------------   * rfapi_check   *   * Test rfapi descriptor   * - * input:  + * input:   *    rfd: rfapi descriptor returned by rfapi_open   *   * output: @@ -664,8 +623,7 @@ rfapi_close (rfapi_handle rfd);   *	ENXIO		BGP or VNC not configured   *	EAFNOSUPPORT	Internal addressing error   *------------------------------------------*/ -extern int -rfapi_check (rfapi_handle rfd); +extern int rfapi_check(rfapi_handle rfd);  /***********************************************************************   *			NVE Routes @@ -674,14 +632,14 @@ rfapi_check (rfapi_handle rfd);  /*------------------------------------------   * rfapi_query   * - * This function queries the RIB for a  - * particular route.  Note that this call may result in subsequent  + * This function queries the RIB for a + * particular route.  Note that this call may result in subsequent   * callbacks to response_cb.  Response callbacks can be cancelled   * by calling rfapi_query_done.  A duplicate query using the same target   * will result in only one callback per change in next_hops. (i.e.,   * cancel/replace the prior query results.)   * - * input:  + * input:   *    rfd:	rfapi descriptor returned by rfapi_open   *    target:	the destination address   *    l2o	ptr to L2 Options struct, NULL if not present in query @@ -701,20 +659,17 @@ rfapi_check (rfapi_handle rfd);   *	ESTALE		descriptor is no longer usable; should be closed   *	EDEADLK		Called from within a callback procedure  --------------------------------------------*/ -extern int -rfapi_query ( -  rfapi_handle			rfd, -  struct rfapi_ip_addr		*target, -  struct rfapi_l2address_option	*l2o, -  struct rfapi_next_hop_entry	**ppNextHopEntry); +extern int rfapi_query(rfapi_handle rfd, struct rfapi_ip_addr *target, +		       struct rfapi_l2address_option *l2o, +		       struct rfapi_next_hop_entry **ppNextHopEntry);  /*------------------------------------------   * rfapi_query_done   * - * Notifies the rfapi that the user is no longer interested  - * in the specified target.  + * Notifies the rfapi that the user is no longer interested + * in the specified target.   * - * input:  + * input:   *    rfd:	rfapi descriptor returned by rfapi_open   *    target:	the destination address   * @@ -728,16 +683,15 @@ rfapi_query (   *	ESTALE		descriptor is no longer usable; should be closed   *	EDEADLK		Called from within a callback procedure  --------------------------------------------*/ -extern int -rfapi_query_done (rfapi_handle rfd, struct rfapi_ip_addr *target); +extern int rfapi_query_done(rfapi_handle rfd, struct rfapi_ip_addr *target);  /*------------------------------------------   * rfapi_query_done_all   * - * Notifies the rfapi that the user is no longer interested  - * in any target.  + * Notifies the rfapi that the user is no longer interested + * in any target.   * - * input:  + * input:   *    rfd:	rfapi descriptor returned by rfapi_open   *   * output: @@ -750,8 +704,7 @@ rfapi_query_done (rfapi_handle rfd, struct rfapi_ip_addr *target);   *	ESTALE		descriptor is no longer usable; should be closed   *	EDEADLK		Called from within a callback procedure  --------------------------------------------*/ -extern int -rfapi_query_done_all (rfapi_handle rfd, int *count); +extern int rfapi_query_done_all(rfapi_handle rfd, int *count);  /*------------------------------------------   * rfapi_register @@ -759,11 +712,11 @@ rfapi_query_done_all (rfapi_handle rfd, int *count);   * Requests that reachability to the indicated prefix via this NVE   * be advertised by BGP. If <unregister> is non-zero, then the previously-   * advertised prefix should be withdrawn. - *  - * (This function should NOT be called if the rfapi_open() function  + * + * (This function should NOT be called if the rfapi_open() function   * returns NULL)   * - * input:  + * input:   *    rfd:		rfapi descriptor returned by rfapi_open   *    prefix:           A prefix to be registered or deregistered   *    lifetime		Prefix lifetime in seconds, host byte order @@ -785,21 +738,16 @@ rfapi_query_done_all (rfapi_handle rfd, int *count);   *	EDEADLK		Called from within a callback procedure   --------------------------------------------*/ -typedef enum -{ -  RFAPI_REGISTER_ADD, -  RFAPI_REGISTER_WITHDRAW, -  RFAPI_REGISTER_KILL +typedef enum { +	RFAPI_REGISTER_ADD, +	RFAPI_REGISTER_WITHDRAW, +	RFAPI_REGISTER_KILL  } rfapi_register_action; -extern int -rfapi_register ( -    rfapi_handle		rfd, -    struct rfapi_ip_prefix	*prefix, -    uint32_t			lifetime, -    struct rfapi_un_option	*options_un, -    struct rfapi_vn_option	*options_vn, -    rfapi_register_action	action); +extern int rfapi_register(rfapi_handle rfd, struct rfapi_ip_prefix *prefix, +			  uint32_t lifetime, struct rfapi_un_option *options_un, +			  struct rfapi_vn_option *options_vn, +			  rfapi_register_action action);  /***********************************************************************   *			Helper / Utility functions @@ -810,32 +758,30 @@ rfapi_register (   *   * Get the virtual network address used by an NVE based on it's RFD   * - * input:  + * input:   *    rfd: rfapi descriptor returned by rfapi_open or rfapi_create_generic   *   * output:   * - * return value:  + * return value:   *	vn		NVE virtual network address   *------------------------------------------*/ -extern struct rfapi_ip_addr * -rfapi_get_vn_addr (void *); +extern struct rfapi_ip_addr *rfapi_get_vn_addr(void *);  /*------------------------------------------   * rfapi_get_un_addr   *   * Get the underlay network address used by an NVE based on it's RFD   * - * input:  + * input:   *    rfd: rfapi descriptor returned by rfapi_open or rfapi_create_generic   *   * output:   * - * return value:  + * return value:   *	un		NVE underlay network address   *------------------------------------------*/ -extern struct rfapi_ip_addr * -rfapi_get_un_addr (void *); +extern struct rfapi_ip_addr *rfapi_get_un_addr(void *);  /*------------------------------------------   * rfapi_error_str @@ -850,8 +796,7 @@ rfapi_get_un_addr (void *);   *   *	const char *	String   *------------------------------------------*/ -extern const char * -rfapi_error_str (int code); +extern const char *rfapi_error_str(int code);  /*------------------------------------------   * rfapi_get_rfp_start_val @@ -862,17 +807,16 @@ rfapi_error_str (int code);   *	void *		bgp structure   *   * returns: - *	void *           + *	void *   *------------------------------------------*/ -extern void * -rfapi_get_rfp_start_val (void *bgpv); +extern void *rfapi_get_rfp_start_val(void *bgpv);  /*------------------------------------------   * rfapi_compare_rfds   *   * Compare two generic rfapi descriptors.   * - * input:  + * input:   *    rfd1: rfapi descriptor returned by rfapi_open or rfapi_create_generic   *    rfd2: rfapi descriptor returned by rfapi_open or rfapi_create_generic   * @@ -882,24 +826,22 @@ rfapi_get_rfp_start_val (void *bgpv);   *	0		Mismatch   *	1		Match   *------------------------------------------*/ -extern int -rfapi_compare_rfds (void *rfd1, void *rfd2); +extern int rfapi_compare_rfds(void *rfd1, void *rfd2);  /*------------------------------------------   * rfapi_free_next_hop_list   *   * Frees a next_hop_list returned by a rfapi_query invocation   * - * input:  - *    list:   a pointer to a response list (as a  + * input: + *    list:   a pointer to a response list (as a   *            struct rfapi_next_hop_entry) to free.   *   * output:   *   * return value: None   --------------------------------------------*/ -extern void -rfapi_free_next_hop_list (struct rfapi_next_hop_entry *list); +extern void rfapi_free_next_hop_list(struct rfapi_next_hop_entry *list);  /*------------------------------------------   * rfapi_get_response_lifetime_default @@ -908,22 +850,21 @@ rfapi_free_next_hop_list (struct rfapi_next_hop_entry *list);   *    rfp_start_val     value returned by rfp_start or   *                      NULL (=use default instance)   * - * input:  + * input:   *    None   *   * output:   *   * return value: The bgp instance default lifetime for a response.   --------------------------------------------*/ -extern int -rfapi_get_response_lifetime_default (void *rfp_start_val); +extern int rfapi_get_response_lifetime_default(void *rfp_start_val);  /*------------------------------------------   * rfapi_is_vnc_configured   *   * Returns if VNC (BGP VPN messaging /VPN & encap SAFIs) are configured   * - * input:  + * input:   *    rfp_start_val     value returned by rfp_start or   *                      NULL (=use default instance)   * @@ -933,15 +874,14 @@ rfapi_get_response_lifetime_default (void *rfp_start_val);   *	0		Success   *	ENXIO		VNC not configured   --------------------------------------------*/ -extern int -rfapi_is_vnc_configured (void *rfp_start_val); +extern int rfapi_is_vnc_configured(void *rfp_start_val);  /*------------------------------------------   * rfapi_bgp_lookup_by_rfp   *   * Find bgp instance pointer based on value returned by rfp_start   * - * input:  + * input:   *      rfp_start_val     value returned by rfp_startor   *                        NULL (=get default instance)   * @@ -953,15 +893,14 @@ rfapi_is_vnc_configured (void *rfp_start_val);   *      NULL = not found   *   --------------------------------------------*/ -extern struct bgp * -rfapi_bgp_lookup_by_rfp (void *rfp_start_val); +extern struct bgp *rfapi_bgp_lookup_by_rfp(void *rfp_start_val);  /*------------------------------------------   * rfapi_get_rfp_start_val_by_bgp   *   * Find bgp instance pointer based on value returned by rfp_start   * - * input:  + * input:   *	bgp             bgp instance pointer   *   * output: @@ -972,8 +911,7 @@ rfapi_bgp_lookup_by_rfp (void *rfp_start_val);   *      NULL = not found   *   --------------------------------------------*/ -extern void * -rfapi_get_rfp_start_val_by_bgp (struct bgp *bgp); +extern void *rfapi_get_rfp_start_val_by_bgp(struct bgp *bgp);  #endif /* ENABLE_BGP_VNC */ diff --git a/bgpd/rfapi/rfapi_ap.c b/bgpd/rfapi/rfapi_ap.c index fac28cd74c..3112505d4b 100644 --- a/bgpd/rfapi/rfapi_ap.c +++ b/bgpd/rfapi/rfapi_ap.c @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2009-2016, LabN Consulting, L.L.C.   * @@ -83,541 +83,476 @@   * is used to spread out the sort for adbs with the same lifetime   * and thereby make the skip list operations more efficient.   */ -static int -sl_adb_lifetime_cmp (void *adb1, void *adb2) +static int sl_adb_lifetime_cmp(void *adb1, void *adb2)  { -  struct rfapi_adb *a1 = adb1; -  struct rfapi_adb *a2 = adb2; +	struct rfapi_adb *a1 = adb1; +	struct rfapi_adb *a2 = adb2; -  if (a1->lifetime < a2->lifetime) -    return -1; -  if (a1->lifetime > a2->lifetime) -    return 1; +	if (a1->lifetime < a2->lifetime) +		return -1; +	if (a1->lifetime > a2->lifetime) +		return 1; -  if (a1 < a2) -    return -1; -  if (a1 > a2) -    return 1; +	if (a1 < a2) +		return -1; +	if (a1 > a2) +		return 1; -  return 0; +	return 0;  } -void -rfapiApInit (struct rfapi_advertised_prefixes *ap) +void rfapiApInit(struct rfapi_advertised_prefixes *ap)  { -  ap->ipN_by_prefix = skiplist_new (0, rfapi_rib_key_cmp, NULL); -  ap->ip0_by_ether = skiplist_new (0, rfapi_rib_key_cmp, NULL); -  ap->by_lifetime = skiplist_new (0, sl_adb_lifetime_cmp, NULL); +	ap->ipN_by_prefix = skiplist_new(0, rfapi_rib_key_cmp, NULL); +	ap->ip0_by_ether = skiplist_new(0, rfapi_rib_key_cmp, NULL); +	ap->by_lifetime = skiplist_new(0, sl_adb_lifetime_cmp, NULL);  } -void -rfapiApRelease (struct rfapi_advertised_prefixes *ap) +void rfapiApRelease(struct rfapi_advertised_prefixes *ap)  { -  struct rfapi_adb *adb; - -  /* Free ADBs and lifetime items */ -  while (0 == skiplist_first (ap->by_lifetime, NULL, (void **) &adb)) -    { -      rfapiAdbFree (adb); -      skiplist_delete_first (ap->by_lifetime); -    } - -  while (0 == skiplist_delete_first (ap->ipN_by_prefix)); -  while (0 == skiplist_delete_first (ap->ip0_by_ether)); - -  /* Free lists */ -  skiplist_free (ap->ipN_by_prefix); -  skiplist_free (ap->ip0_by_ether); -  skiplist_free (ap->by_lifetime); - -  ap->ipN_by_prefix = NULL; -  ap->ip0_by_ether = NULL; -  ap->by_lifetime = NULL; +	struct rfapi_adb *adb; + +	/* Free ADBs and lifetime items */ +	while (0 == skiplist_first(ap->by_lifetime, NULL, (void **)&adb)) { +		rfapiAdbFree(adb); +		skiplist_delete_first(ap->by_lifetime); +	} + +	while (0 == skiplist_delete_first(ap->ipN_by_prefix)) +		; +	while (0 == skiplist_delete_first(ap->ip0_by_ether)) +		; + +	/* Free lists */ +	skiplist_free(ap->ipN_by_prefix); +	skiplist_free(ap->ip0_by_ether); +	skiplist_free(ap->by_lifetime); + +	ap->ipN_by_prefix = NULL; +	ap->ip0_by_ether = NULL; +	ap->by_lifetime = NULL;  } -int -rfapiApCount (struct rfapi_descriptor *rfd) +int rfapiApCount(struct rfapi_descriptor *rfd)  { -  if (!rfd->advertised.by_lifetime) -    return 0; +	if (!rfd->advertised.by_lifetime) +		return 0; -  return skiplist_count (rfd->advertised.by_lifetime); +	return skiplist_count(rfd->advertised.by_lifetime);  } -int -rfapiApCountAll (struct bgp *bgp) +int rfapiApCountAll(struct bgp *bgp)  { -  struct rfapi *h; -  struct listnode *node; -  struct rfapi_descriptor *rfd; -  int total = 0; - -  h = bgp->rfapi; -  if (h) -    { -      for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd)) -        { -          total += rfapiApCount (rfd); -        } -    } -  return total; +	struct rfapi *h; +	struct listnode *node; +	struct rfapi_descriptor *rfd; +	int total = 0; + +	h = bgp->rfapi; +	if (h) { +		for (ALL_LIST_ELEMENTS_RO(&h->descriptors, node, rfd)) { +			total += rfapiApCount(rfd); +		} +	} +	return total;  } -void -rfapiApReadvertiseAll (struct bgp *bgp, struct rfapi_descriptor *rfd) +void rfapiApReadvertiseAll(struct bgp *bgp, struct rfapi_descriptor *rfd)  { -  struct rfapi_adb *adb; -  void *cursor = NULL; -  int rc; - -  for (rc = -       skiplist_next (rfd->advertised.by_lifetime, NULL, (void **) &adb, -                      &cursor); rc == 0; -       rc = -       skiplist_next (rfd->advertised.by_lifetime, NULL, (void **) &adb, -                      &cursor)) -    { - -      struct prefix_rd prd; -      uint32_t local_pref = rfp_cost_to_localpref (adb->cost); - -      prd = rfd->rd; -      prd.family = AF_UNSPEC; -      prd.prefixlen = 64; - -      /* -       * TBD this is not quite right. When pfx_ip is 0/32 or 0/128, -       * we need to substitute the VN address as the prefix -       */ -      add_vnc_route (rfd, bgp, SAFI_MPLS_VPN, &adb->u.s.prefix_ip, &prd,    /* RD to use (0 for ENCAP) */ -                     &rfd->vn_addr,     /* nexthop */ -                     &local_pref, &adb->lifetime, NULL, NULL,   /* struct rfapi_un_option */ -                     NULL,      /* struct rfapi_vn_option */ -                     rfd->rt_export_list, NULL, /* med */ -                     NULL, ZEBRA_ROUTE_BGP, BGP_ROUTE_RFP, 0); -    } +	struct rfapi_adb *adb; +	void *cursor = NULL; +	int rc; + +	for (rc = skiplist_next(rfd->advertised.by_lifetime, NULL, +				(void **)&adb, &cursor); +	     rc == 0; rc = skiplist_next(rfd->advertised.by_lifetime, NULL, +					 (void **)&adb, &cursor)) { + +		struct prefix_rd prd; +		uint32_t local_pref = rfp_cost_to_localpref(adb->cost); + +		prd = rfd->rd; +		prd.family = AF_UNSPEC; +		prd.prefixlen = 64; + +		/* +		 * TBD this is not quite right. When pfx_ip is 0/32 or 0/128, +		 * we need to substitute the VN address as the prefix +		 */ +		add_vnc_route(rfd, bgp, SAFI_MPLS_VPN, &adb->u.s.prefix_ip, +			      &prd,	  /* RD to use (0 for ENCAP) */ +			      &rfd->vn_addr, /* nexthop */ +			      &local_pref, &adb->lifetime, NULL, +			      NULL, /* struct rfapi_un_option */ +			      NULL, /* struct rfapi_vn_option */ +			      rfd->rt_export_list, NULL, /* med */ +			      NULL, ZEBRA_ROUTE_BGP, BGP_ROUTE_RFP, 0); +	}  } -void -rfapiApWithdrawAll (struct bgp *bgp, struct rfapi_descriptor *rfd) +void rfapiApWithdrawAll(struct bgp *bgp, struct rfapi_descriptor *rfd)  { -  struct rfapi_adb *adb; -  void *cursor; -  int rc; - - -  cursor = NULL; -  for (rc = -       skiplist_next (rfd->advertised.by_lifetime, NULL, (void **) &adb, -                      &cursor); rc == 0; -       rc = -       skiplist_next (rfd->advertised.by_lifetime, NULL, (void **) &adb, -                      &cursor)) -    { - -      struct prefix pfx_vn_buf; -      struct prefix *pfx_ip; - -      if (!(RFAPI_0_PREFIX (&adb->u.s.prefix_ip) && -            RFAPI_HOST_PREFIX (&adb->u.s.prefix_ip))) -        { - -          pfx_ip = &adb->u.s.prefix_ip; - -        } -      else -        { - -          pfx_ip = NULL; - -          /* -           * 0/32 or 0/128 => mac advertisement -           */ -          if (rfapiRaddr2Qprefix (&rfd->vn_addr, &pfx_vn_buf)) -            { -              /* -               * Bad: it means we can't delete the route -               */ -              vnc_zlog_debug_verbose ("%s: BAD: handle has bad vn_addr: skipping", -                          __func__); -              continue; -            } -        } - -      del_vnc_route (rfd, rfd->peer, bgp, SAFI_MPLS_VPN, pfx_ip ? pfx_ip : &pfx_vn_buf, &adb->u.s.prd,      /* RD to use (0 for ENCAP) */ -                     ZEBRA_ROUTE_BGP, BGP_ROUTE_RFP, NULL, 0); -    } +	struct rfapi_adb *adb; +	void *cursor; +	int rc; + + +	cursor = NULL; +	for (rc = skiplist_next(rfd->advertised.by_lifetime, NULL, +				(void **)&adb, &cursor); +	     rc == 0; rc = skiplist_next(rfd->advertised.by_lifetime, NULL, +					 (void **)&adb, &cursor)) { + +		struct prefix pfx_vn_buf; +		struct prefix *pfx_ip; + +		if (!(RFAPI_0_PREFIX(&adb->u.s.prefix_ip) +		      && RFAPI_HOST_PREFIX(&adb->u.s.prefix_ip))) { + +			pfx_ip = &adb->u.s.prefix_ip; + +		} else { + +			pfx_ip = NULL; + +			/* +			 * 0/32 or 0/128 => mac advertisement +			 */ +			if (rfapiRaddr2Qprefix(&rfd->vn_addr, &pfx_vn_buf)) { +				/* +				 * Bad: it means we can't delete the route +				 */ +				vnc_zlog_debug_verbose( +					"%s: BAD: handle has bad vn_addr: skipping", +					__func__); +				continue; +			} +		} + +		del_vnc_route(rfd, rfd->peer, bgp, SAFI_MPLS_VPN, +			      pfx_ip ? pfx_ip : &pfx_vn_buf, +			      &adb->u.s.prd, /* RD to use (0 for ENCAP) */ +			      ZEBRA_ROUTE_BGP, BGP_ROUTE_RFP, NULL, 0); +	}  }  /*   * returns nonzero if tunnel readvertisement is needed, 0 otherwise   */ -static int -rfapiApAdjustLifetimeStats ( -  struct rfapi_descriptor	*rfd, -  uint32_t			*old_lifetime,	/* set if removing/replacing */ -  uint32_t			*new_lifetime)	/* set if replacing/adding */ +static int rfapiApAdjustLifetimeStats( +	struct rfapi_descriptor *rfd, +	uint32_t *old_lifetime, /* set if removing/replacing */ +	uint32_t *new_lifetime) /* set if replacing/adding */  { -  int advertise = 0; -  int find_max = 0; -  int find_min = 0; - -  vnc_zlog_debug_verbose ("%s: rfd=%p, pOldLife=%p, pNewLife=%p", -              __func__, rfd, old_lifetime, new_lifetime); -  if (old_lifetime) -    vnc_zlog_debug_verbose ("%s: OldLife=%d", __func__, *old_lifetime); -  if (new_lifetime) -    vnc_zlog_debug_verbose ("%s: NewLife=%d", __func__, *new_lifetime); - -  if (new_lifetime) -    { -      /* -       * Adding new lifetime -       */ -      if (old_lifetime) -        { -          /* -           * replacing existing lifetime -           */ - - -          /* old and new are same */ -          if (*old_lifetime == *new_lifetime) -            return 0; - -          if (*old_lifetime == rfd->min_prefix_lifetime) -            { -              find_min = 1; -            } -          if (*old_lifetime == rfd->max_prefix_lifetime) -            { -              find_max = 1; -            } - -          /* no need to search if new value is at or equals min|max  */ -          if (*new_lifetime <= rfd->min_prefix_lifetime) -            { -              rfd->min_prefix_lifetime = *new_lifetime; -              find_min = 0; -            } -          if (*new_lifetime >= rfd->max_prefix_lifetime) -            { -              rfd->max_prefix_lifetime = *new_lifetime; -              advertise = 1; -              find_max = 0; -            } - -        } -      else -        { -          /* -           * Just adding new lifetime -           */ -          if (*new_lifetime < rfd->min_prefix_lifetime) -            { -              rfd->min_prefix_lifetime = *new_lifetime; -            } -          if (*new_lifetime > rfd->max_prefix_lifetime) -            { -              advertise = 1; -              rfd->max_prefix_lifetime = *new_lifetime; -            } - -        } -    } -  else -    { -      /* -       * Deleting -       */ - -      /* -       * See if the max prefix lifetime for this NVE has decreased. -       * The easy optimization: track min & max; walk the table only -       * if they are different. -       * The general optimization: index the advertised_prefixes -       * table by lifetime. -       * -       * Note: for a given nve_descriptor, only one of the -       * advertised_prefixes[] tables will be used: viz., the -       * address family that matches the VN address. -       * -       */ -      if (rfd->max_prefix_lifetime == rfd->min_prefix_lifetime) -        { - -          /* -           * Common case: all lifetimes are the same. Only -           * thing we need to do here is check if there are -           * no exported routes left. In that case, reinitialize -           * the max and min values. -           */ -          if (!rfapiApCount (rfd)) -            { -              rfd->max_prefix_lifetime = 0; -              rfd->min_prefix_lifetime = UINT32_MAX; -            } - - -        } -      else -        { -          if (old_lifetime) -            { -              if (*old_lifetime == rfd->min_prefix_lifetime) -                { -                  find_min = 1; -                } -              if (*old_lifetime == rfd->max_prefix_lifetime) -                { -                  find_max = 1; -                } -            } -        } -    } - -  if (find_min || find_max) -    { -      uint32_t min = UINT32_MAX; -      uint32_t max = 0; - -      struct rfapi_adb *adb_min; -      struct rfapi_adb *adb_max; - -      if (!skiplist_first -          (rfd->advertised.by_lifetime, (void **) &adb_min, NULL) -          && !skiplist_last (rfd->advertised.by_lifetime, (void **) &adb_max, -                             NULL)) -        { - -          /* -           * This should always work -           */ -          min = adb_min->lifetime; -          max = adb_max->lifetime; - -        } -      else -        { - -          void *cursor; -          struct rfapi_rib_key rk; -          struct rfapi_adb    *adb; -          int rc; - -          vnc_zlog_debug_verbose ("%s: walking to find new min/max", __func__); - -          cursor = NULL; -          for (rc = skiplist_next (rfd->advertised.ipN_by_prefix, -                                   (void **) &rk, (void **) &adb, -                                   &cursor); !rc; -               rc = -               skiplist_next (rfd->advertised.ipN_by_prefix, -                              (void **) &rk, (void **) &adb, &cursor)) -            { - -              uint32_t lt = adb->lifetime; - -              if (lt > max) -                max = lt; -              if (lt < min) -                min = lt; -            } -          cursor = NULL; -          for (rc = skiplist_next (rfd->advertised.ip0_by_ether, -                                   (void **) &rk, (void **) &adb, -                                   &cursor); !rc; -               rc = -               skiplist_next (rfd->advertised.ip0_by_ether, (void **) &rk, -                              (void **) &adb, &cursor)) -            { - -              uint32_t lt = adb->lifetime; - -              if (lt > max) -                max = lt; -              if (lt < min) -                min = lt; -            } -        } - -      /* -       * trigger tunnel route update -       * but only if we found a VPN route and it had -       * a lifetime greater than 0 -       */ -      if (max && rfd->max_prefix_lifetime != max) -        advertise = 1; -      rfd->max_prefix_lifetime = max; -      rfd->min_prefix_lifetime = min; -    } - -  vnc_zlog_debug_verbose ("%s: returning advertise=%d, min=%d, max=%d", -              __func__, advertise, rfd->min_prefix_lifetime, -              rfd->max_prefix_lifetime); - -  return (advertise != 0); +	int advertise = 0; +	int find_max = 0; +	int find_min = 0; + +	vnc_zlog_debug_verbose("%s: rfd=%p, pOldLife=%p, pNewLife=%p", __func__, +			       rfd, old_lifetime, new_lifetime); +	if (old_lifetime) +		vnc_zlog_debug_verbose("%s: OldLife=%d", __func__, +				       *old_lifetime); +	if (new_lifetime) +		vnc_zlog_debug_verbose("%s: NewLife=%d", __func__, +				       *new_lifetime); + +	if (new_lifetime) { +		/* +		 * Adding new lifetime +		 */ +		if (old_lifetime) { +			/* +			 * replacing existing lifetime +			 */ + + +			/* old and new are same */ +			if (*old_lifetime == *new_lifetime) +				return 0; + +			if (*old_lifetime == rfd->min_prefix_lifetime) { +				find_min = 1; +			} +			if (*old_lifetime == rfd->max_prefix_lifetime) { +				find_max = 1; +			} + +			/* no need to search if new value is at or equals +			 * min|max  */ +			if (*new_lifetime <= rfd->min_prefix_lifetime) { +				rfd->min_prefix_lifetime = *new_lifetime; +				find_min = 0; +			} +			if (*new_lifetime >= rfd->max_prefix_lifetime) { +				rfd->max_prefix_lifetime = *new_lifetime; +				advertise = 1; +				find_max = 0; +			} + +		} else { +			/* +			 * Just adding new lifetime +			 */ +			if (*new_lifetime < rfd->min_prefix_lifetime) { +				rfd->min_prefix_lifetime = *new_lifetime; +			} +			if (*new_lifetime > rfd->max_prefix_lifetime) { +				advertise = 1; +				rfd->max_prefix_lifetime = *new_lifetime; +			} +		} +	} else { +		/* +		 * Deleting +		 */ + +		/* +		 * See if the max prefix lifetime for this NVE has decreased. +		 * The easy optimization: track min & max; walk the table only +		 * if they are different. +		 * The general optimization: index the advertised_prefixes +		 * table by lifetime. +		 * +		 * Note: for a given nve_descriptor, only one of the +		 * advertised_prefixes[] tables will be used: viz., the +		 * address family that matches the VN address. +		 * +		 */ +		if (rfd->max_prefix_lifetime == rfd->min_prefix_lifetime) { + +			/* +			 * Common case: all lifetimes are the same. Only +			 * thing we need to do here is check if there are +			 * no exported routes left. In that case, reinitialize +			 * the max and min values. +			 */ +			if (!rfapiApCount(rfd)) { +				rfd->max_prefix_lifetime = 0; +				rfd->min_prefix_lifetime = UINT32_MAX; +			} + + +		} else { +			if (old_lifetime) { +				if (*old_lifetime == rfd->min_prefix_lifetime) { +					find_min = 1; +				} +				if (*old_lifetime == rfd->max_prefix_lifetime) { +					find_max = 1; +				} +			} +		} +	} + +	if (find_min || find_max) { +		uint32_t min = UINT32_MAX; +		uint32_t max = 0; + +		struct rfapi_adb *adb_min; +		struct rfapi_adb *adb_max; + +		if (!skiplist_first(rfd->advertised.by_lifetime, +				    (void **)&adb_min, NULL) +		    && !skiplist_last(rfd->advertised.by_lifetime, +				      (void **)&adb_max, NULL)) { + +			/* +			 * This should always work +			 */ +			min = adb_min->lifetime; +			max = adb_max->lifetime; + +		} else { + +			void *cursor; +			struct rfapi_rib_key rk; +			struct rfapi_adb *adb; +			int rc; + +			vnc_zlog_debug_verbose( +				"%s: walking to find new min/max", __func__); + +			cursor = NULL; +			for (rc = skiplist_next(rfd->advertised.ipN_by_prefix, +						(void **)&rk, (void **)&adb, +						&cursor); +			     !rc; +			     rc = skiplist_next(rfd->advertised.ipN_by_prefix, +						(void **)&rk, (void **)&adb, +						&cursor)) { + +				uint32_t lt = adb->lifetime; + +				if (lt > max) +					max = lt; +				if (lt < min) +					min = lt; +			} +			cursor = NULL; +			for (rc = skiplist_next(rfd->advertised.ip0_by_ether, +						(void **)&rk, (void **)&adb, +						&cursor); +			     !rc; +			     rc = skiplist_next(rfd->advertised.ip0_by_ether, +						(void **)&rk, (void **)&adb, +						&cursor)) { + +				uint32_t lt = adb->lifetime; + +				if (lt > max) +					max = lt; +				if (lt < min) +					min = lt; +			} +		} + +		/* +		 * trigger tunnel route update +		 * but only if we found a VPN route and it had +		 * a lifetime greater than 0 +		 */ +		if (max && rfd->max_prefix_lifetime != max) +			advertise = 1; +		rfd->max_prefix_lifetime = max; +		rfd->min_prefix_lifetime = min; +	} + +	vnc_zlog_debug_verbose("%s: returning advertise=%d, min=%d, max=%d", +			       __func__, advertise, rfd->min_prefix_lifetime, +			       rfd->max_prefix_lifetime); + +	return (advertise != 0);  } -/*  +/*   * Return Value   *   *	0	No need to advertise tunnel route   *	non-0	advertise tunnel route   */ -int -rfapiApAdd ( -  struct bgp			*bgp, -  struct rfapi_descriptor	*rfd, -  struct prefix			*pfx_ip, -  struct prefix			*pfx_eth, -  struct prefix_rd		*prd, -  uint32_t			lifetime, -  uint8_t			cost, -  struct rfapi_l2address_option	*l2o)   /* other options TBD */ +int rfapiApAdd(struct bgp *bgp, struct rfapi_descriptor *rfd, +	       struct prefix *pfx_ip, struct prefix *pfx_eth, +	       struct prefix_rd *prd, uint32_t lifetime, uint8_t cost, +	       struct rfapi_l2address_option *l2o) /* other options TBD */  { -  int rc; -  struct rfapi_adb *adb; -  uint32_t old_lifetime = 0; -  int use_ip0 = 0; -  struct rfapi_rib_key rk; - -  rfapi_rib_key_init(pfx_ip, prd, pfx_eth, &rk); -  if (RFAPI_0_PREFIX (pfx_ip) && RFAPI_HOST_PREFIX (pfx_ip)) -    { -      use_ip0 = 1; -      assert (pfx_eth); -      rc = -        skiplist_search (rfd->advertised.ip0_by_ether, &rk, -                         (void **) &adb); - -    } -  else -    { - -      /* find prefix in advertised prefixes list */ -      rc = -        skiplist_search (rfd->advertised.ipN_by_prefix, &rk, -                         (void **) &adb); -    } - - -  if (rc) -    { -      /* Not found */ -      adb = XCALLOC (MTYPE_RFAPI_ADB, sizeof (struct rfapi_adb)); -      assert (adb); -      adb->lifetime = lifetime; -      adb->u.key = rk; - -      if (use_ip0) -        { -          assert (pfx_eth); -          skiplist_insert (rfd->advertised.ip0_by_ether, &adb->u.key, -                           adb); -        } -      else -        { -          skiplist_insert (rfd->advertised.ipN_by_prefix, &adb->u.key, -                           adb); -        } - -      skiplist_insert (rfd->advertised.by_lifetime, adb, adb); -    } -  else -    { -      old_lifetime = adb->lifetime; -      if (old_lifetime != lifetime) -        { -          assert (!skiplist_delete (rfd->advertised.by_lifetime, adb, NULL)); -          adb->lifetime = lifetime; -          assert (!skiplist_insert (rfd->advertised.by_lifetime, adb, adb)); -        } -    } -  adb->cost = cost; -  if (l2o) -    adb->l2o = *l2o; -  else -    memset (&adb->l2o, 0, sizeof (struct rfapi_l2address_option)); - -  if (rfapiApAdjustLifetimeStats -      (rfd, (rc ? NULL : &old_lifetime), &lifetime)) -    return 1; - -  return 0; +	int rc; +	struct rfapi_adb *adb; +	uint32_t old_lifetime = 0; +	int use_ip0 = 0; +	struct rfapi_rib_key rk; + +	rfapi_rib_key_init(pfx_ip, prd, pfx_eth, &rk); +	if (RFAPI_0_PREFIX(pfx_ip) && RFAPI_HOST_PREFIX(pfx_ip)) { +		use_ip0 = 1; +		assert(pfx_eth); +		rc = skiplist_search(rfd->advertised.ip0_by_ether, &rk, +				     (void **)&adb); + +	} else { + +		/* find prefix in advertised prefixes list */ +		rc = skiplist_search(rfd->advertised.ipN_by_prefix, &rk, +				     (void **)&adb); +	} + + +	if (rc) { +		/* Not found */ +		adb = XCALLOC(MTYPE_RFAPI_ADB, sizeof(struct rfapi_adb)); +		assert(adb); +		adb->lifetime = lifetime; +		adb->u.key = rk; + +		if (use_ip0) { +			assert(pfx_eth); +			skiplist_insert(rfd->advertised.ip0_by_ether, +					&adb->u.key, adb); +		} else { +			skiplist_insert(rfd->advertised.ipN_by_prefix, +					&adb->u.key, adb); +		} + +		skiplist_insert(rfd->advertised.by_lifetime, adb, adb); +	} else { +		old_lifetime = adb->lifetime; +		if (old_lifetime != lifetime) { +			assert(!skiplist_delete(rfd->advertised.by_lifetime, +						adb, NULL)); +			adb->lifetime = lifetime; +			assert(!skiplist_insert(rfd->advertised.by_lifetime, +						adb, adb)); +		} +	} +	adb->cost = cost; +	if (l2o) +		adb->l2o = *l2o; +	else +		memset(&adb->l2o, 0, sizeof(struct rfapi_l2address_option)); + +	if (rfapiApAdjustLifetimeStats(rfd, (rc ? NULL : &old_lifetime), +				       &lifetime)) +		return 1; + +	return 0;  }  /*   * After this function returns successfully, caller should call   * rfapiAdjustLifetimeStats() and possibly rfapiTunnelRouteAnnounce()   */ -int -rfapiApDelete ( -  struct bgp			*bgp, -  struct rfapi_descriptor	*rfd, -  struct prefix			*pfx_ip, -  struct prefix			*pfx_eth, -  struct prefix_rd		*prd, -  int				*advertise_tunnel)	/* out */ +int rfapiApDelete(struct bgp *bgp, struct rfapi_descriptor *rfd, +		  struct prefix *pfx_ip, struct prefix *pfx_eth, +		  struct prefix_rd *prd, int *advertise_tunnel) /* out */  { -  int rc; -  struct rfapi_adb *adb; -  uint32_t old_lifetime; -  int use_ip0 = 0; -  struct rfapi_rib_key rk; - -  if (advertise_tunnel) -    *advertise_tunnel = 0; - -  rfapi_rib_key_init(pfx_ip, prd, pfx_eth, &rk); -  /* find prefix in advertised prefixes list */ -  if (RFAPI_0_PREFIX (pfx_ip) && RFAPI_HOST_PREFIX (pfx_ip)) -    { -      use_ip0 = 1; -      assert (pfx_eth); - -      rc = -        skiplist_search (rfd->advertised.ip0_by_ether, &rk, -                         (void **) &adb); - -    } -  else -    { - -      /* find prefix in advertised prefixes list */ -      rc = -        skiplist_search (rfd->advertised.ipN_by_prefix, &rk, -                         (void **) &adb); -    } - -  if (rc) -    { -      return ENOENT; -    } - -  old_lifetime = adb->lifetime; - -  if (use_ip0) -    { -      rc = skiplist_delete (rfd->advertised.ip0_by_ether, &rk, NULL); -    } -  else -    { -      rc = skiplist_delete (rfd->advertised.ipN_by_prefix, &rk, NULL); -    } -  assert (!rc); - -  rc = skiplist_delete (rfd->advertised.by_lifetime, adb, NULL); -  assert (!rc); - -  rfapiAdbFree (adb); - -  if (rfapiApAdjustLifetimeStats (rfd, &old_lifetime, NULL)) -    { -      if (advertise_tunnel) -        *advertise_tunnel = 1; -    } - -  return 0; +	int rc; +	struct rfapi_adb *adb; +	uint32_t old_lifetime; +	int use_ip0 = 0; +	struct rfapi_rib_key rk; + +	if (advertise_tunnel) +		*advertise_tunnel = 0; + +	rfapi_rib_key_init(pfx_ip, prd, pfx_eth, &rk); +	/* find prefix in advertised prefixes list */ +	if (RFAPI_0_PREFIX(pfx_ip) && RFAPI_HOST_PREFIX(pfx_ip)) { +		use_ip0 = 1; +		assert(pfx_eth); + +		rc = skiplist_search(rfd->advertised.ip0_by_ether, &rk, +				     (void **)&adb); + +	} else { + +		/* find prefix in advertised prefixes list */ +		rc = skiplist_search(rfd->advertised.ipN_by_prefix, &rk, +				     (void **)&adb); +	} + +	if (rc) { +		return ENOENT; +	} + +	old_lifetime = adb->lifetime; + +	if (use_ip0) { +		rc = skiplist_delete(rfd->advertised.ip0_by_ether, &rk, NULL); +	} else { +		rc = skiplist_delete(rfd->advertised.ipN_by_prefix, &rk, NULL); +	} +	assert(!rc); + +	rc = skiplist_delete(rfd->advertised.by_lifetime, adb, NULL); +	assert(!rc); + +	rfapiAdbFree(adb); + +	if (rfapiApAdjustLifetimeStats(rfd, &old_lifetime, NULL)) { +		if (advertise_tunnel) +			*advertise_tunnel = 1; +	} + +	return 0;  } diff --git a/bgpd/rfapi/rfapi_ap.h b/bgpd/rfapi/rfapi_ap.h index c875a52e50..56977bd246 100644 --- a/bgpd/rfapi/rfapi_ap.h +++ b/bgpd/rfapi/rfapi_ap.h @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2009-2016, LabN Consulting, L.L.C.   * @@ -56,44 +56,30 @@  #include "rfapi_rib.h" -extern void -rfapiApInit (struct rfapi_advertised_prefixes *ap); +extern void rfapiApInit(struct rfapi_advertised_prefixes *ap); -extern void -rfapiApRelease (struct rfapi_advertised_prefixes *ap); - -extern int -rfapiApCount (struct rfapi_descriptor *rfd); +extern void rfapiApRelease(struct rfapi_advertised_prefixes *ap); +extern int rfapiApCount(struct rfapi_descriptor *rfd); -extern int -rfapiApCountAll (struct bgp *bgp); -extern void -rfapiApReadvertiseAll (struct bgp *bgp, struct rfapi_descriptor *rfd); +extern int rfapiApCountAll(struct bgp *bgp); -extern void -rfapiApWithdrawAll (struct bgp *bgp, struct rfapi_descriptor *rfd); +extern void rfapiApReadvertiseAll(struct bgp *bgp, +				  struct rfapi_descriptor *rfd); -extern int -rfapiApAdd ( -  struct bgp			*bgp, -  struct rfapi_descriptor	*rfd, -  struct prefix			*pfx_ip, -  struct prefix			*pfx_eth, -  struct prefix_rd		*prd, -  uint32_t			lifetime, -  uint8_t			cost, -  struct rfapi_l2address_option	*l2o);       /* other options TBD */ +extern void rfapiApWithdrawAll(struct bgp *bgp, struct rfapi_descriptor *rfd);  extern int -rfapiApDelete ( -  struct bgp			*bgp, -  struct rfapi_descriptor	*rfd, -  struct prefix			*pfx_ip, -  struct prefix			*pfx_eth, -  struct prefix_rd		*prd, -  int				*advertise_tunnel); /* out */ +rfapiApAdd(struct bgp *bgp, struct rfapi_descriptor *rfd, struct prefix *pfx_ip, +	   struct prefix *pfx_eth, struct prefix_rd *prd, uint32_t lifetime, +	   uint8_t cost, +	   struct rfapi_l2address_option *l2o); /* other options TBD */ + +extern int rfapiApDelete(struct bgp *bgp, struct rfapi_descriptor *rfd, +			 struct prefix *pfx_ip, struct prefix *pfx_eth, +			 struct prefix_rd *prd, +			 int *advertise_tunnel); /* out */  #endif /* _QUAGGA_BGP_RFAPI_AP_H */ diff --git a/bgpd/rfapi/rfapi_backend.h b/bgpd/rfapi/rfapi_backend.h index a2537bd918..4455d66a26 100644 --- a/bgpd/rfapi/rfapi_backend.h +++ b/bgpd/rfapi/rfapi_backend.h @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2009-2016, LabN Consulting, L.L.C.   * @@ -26,56 +26,44 @@  #include "bgpd/bgp_route.h"  #include "bgpd/bgp_nexthop.h" -extern void rfapi_init (void); -extern void vnc_zebra_init (struct thread_master *master); -extern void vnc_zebra_destroy (void); +extern void rfapi_init(void); +extern void vnc_zebra_init(struct thread_master *master); +extern void vnc_zebra_destroy(void); -extern void rfapi_delete (struct bgp *); +extern void rfapi_delete(struct bgp *); -struct rfapi *bgp_rfapi_new (struct bgp *bgp); -void bgp_rfapi_destroy (struct bgp *bgp, struct rfapi *h); +struct rfapi *bgp_rfapi_new(struct bgp *bgp); +void bgp_rfapi_destroy(struct bgp *bgp, struct rfapi *h); -extern void -rfapiProcessUpdate (struct peer *peer, -                    void *rfd, -                    struct prefix *p, -                    struct prefix_rd *prd, -                    struct attr *attr, -                    afi_t afi, -                    safi_t safi, -                    u_char type, u_char sub_type, uint32_t * label); +extern void rfapiProcessUpdate(struct peer *peer, void *rfd, struct prefix *p, +			       struct prefix_rd *prd, struct attr *attr, +			       afi_t afi, safi_t safi, u_char type, +			       u_char sub_type, uint32_t *label); -extern void -rfapiProcessWithdraw (struct peer *peer, -                      void *rfd, -                      struct prefix *p, -                      struct prefix_rd *prd, -                      struct attr *attr, -                      afi_t afi, safi_t safi, u_char type, int kill); +extern void rfapiProcessWithdraw(struct peer *peer, void *rfd, struct prefix *p, +				 struct prefix_rd *prd, struct attr *attr, +				 afi_t afi, safi_t safi, u_char type, int kill); -extern void rfapiProcessPeerDown (struct peer *peer); +extern void rfapiProcessPeerDown(struct peer *peer); -extern void -vnc_zebra_announce (struct prefix *p, -                    struct bgp_info *new_select, struct bgp *bgp); +extern void vnc_zebra_announce(struct prefix *p, struct bgp_info *new_select, +			       struct bgp *bgp); -extern void -vnc_zebra_withdraw (struct prefix *p, struct bgp_info *old_select); +extern void vnc_zebra_withdraw(struct prefix *p, struct bgp_info *old_select); -extern void -rfapi_vty_out_vncinfo (struct vty *vty, -                       struct prefix *p, struct bgp_info *bi, safi_t safi); +extern void rfapi_vty_out_vncinfo(struct vty *vty, struct prefix *p, +				  struct bgp_info *bi, safi_t safi); -extern void vnc_direct_bgp_vpn_enable (struct bgp *bgp, afi_t afi); +extern void vnc_direct_bgp_vpn_enable(struct bgp *bgp, afi_t afi); -extern void vnc_direct_bgp_vpn_disable (struct bgp *bgp, afi_t afi); +extern void vnc_direct_bgp_vpn_disable(struct bgp *bgp, afi_t afi); -extern void vnc_direct_bgp_rh_vpn_enable (struct bgp *bgp, afi_t afi); +extern void vnc_direct_bgp_rh_vpn_enable(struct bgp *bgp, afi_t afi); -extern void vnc_direct_bgp_rh_vpn_disable (struct bgp *bgp, afi_t afi); +extern void vnc_direct_bgp_rh_vpn_disable(struct bgp *bgp, afi_t afi);  #endif /* ENABLE_BGP_VNC */ diff --git a/bgpd/rfapi/rfapi_descriptor_rfp_utils.c b/bgpd/rfapi/rfapi_descriptor_rfp_utils.c index d05b271288..3217d34e77 100644 --- a/bgpd/rfapi/rfapi_descriptor_rfp_utils.c +++ b/bgpd/rfapi/rfapi_descriptor_rfp_utils.c @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2009-2016, LabN Consulting, L.L.C.   * @@ -36,15 +36,14 @@  #include "bgpd/rfapi/vnc_debug.h" -void * -rfapi_create_generic (struct rfapi_ip_addr *vn, struct rfapi_ip_addr *un) +void *rfapi_create_generic(struct rfapi_ip_addr *vn, struct rfapi_ip_addr *un)  { -  struct rfapi_descriptor *rfd; -  rfd = XCALLOC (MTYPE_RFAPI_DESC, sizeof (struct rfapi_descriptor)); -  vnc_zlog_debug_verbose ("%s: rfd=%p", __func__, rfd); -  rfd->vn_addr = *vn; -  rfd->un_addr = *un; -  return (void *) rfd; +	struct rfapi_descriptor *rfd; +	rfd = XCALLOC(MTYPE_RFAPI_DESC, sizeof(struct rfapi_descriptor)); +	vnc_zlog_debug_verbose("%s: rfd=%p", __func__, rfd); +	rfd->vn_addr = *vn; +	rfd->un_addr = *un; +	return (void *)rfd;  }  /*------------------------------------------ @@ -52,20 +51,19 @@ rfapi_create_generic (struct rfapi_ip_addr *vn, struct rfapi_ip_addr *un)   *   * Compare two generic rfapi descriptors.   * - * input:  + * input:   *    grfd: rfapi descriptor returned by rfapi_open or rfapi_create_generic   *   * output:   * - * return value:  + * return value:   *   *------------------------------------------*/ -void -rfapi_free_generic (void *grfd) +void rfapi_free_generic(void *grfd)  { -  struct rfapi_descriptor *rfd; -  rfd = (struct rfapi_descriptor *) grfd; -  XFREE (MTYPE_RFAPI_DESC, rfd); +	struct rfapi_descriptor *rfd; +	rfd = (struct rfapi_descriptor *)grfd; +	XFREE(MTYPE_RFAPI_DESC, rfd);  } @@ -74,7 +72,7 @@ rfapi_free_generic (void *grfd)   *   * Compare two generic rfapi descriptors.   * - * input:  + * input:   *    rfd1: rfapi descriptor returned by rfapi_open or rfapi_create_generic   *    rfd2: rfapi descriptor returned by rfapi_open or rfapi_create_generic   * @@ -84,48 +82,45 @@ rfapi_free_generic (void *grfd)   *	0		Mismatch   *	1		Match   *------------------------------------------*/ -int -rfapi_compare_rfds (void *rfd1, void *rfd2) +int rfapi_compare_rfds(void *rfd1, void *rfd2)  { -  struct rfapi_descriptor *rrfd1, *rrfd2; -  int match = 0; +	struct rfapi_descriptor *rrfd1, *rrfd2; +	int match = 0; -  rrfd1 = (struct rfapi_descriptor *) rfd1; -  rrfd2 = (struct rfapi_descriptor *) rfd2; +	rrfd1 = (struct rfapi_descriptor *)rfd1; +	rrfd2 = (struct rfapi_descriptor *)rfd2; -  if (rrfd1->vn_addr.addr_family == rrfd2->vn_addr.addr_family) -    { -      if (rrfd1->vn_addr.addr_family == AF_INET) -        match = IPV4_ADDR_SAME (&(rrfd1->vn_addr.addr.v4), -                                &(rrfd2->vn_addr.addr.v4)); -      else -        match = IPV6_ADDR_SAME (&(rrfd1->vn_addr.addr.v6), -                                &(rrfd2->vn_addr.addr.v6)); -    } +	if (rrfd1->vn_addr.addr_family == rrfd2->vn_addr.addr_family) { +		if (rrfd1->vn_addr.addr_family == AF_INET) +			match = IPV4_ADDR_SAME(&(rrfd1->vn_addr.addr.v4), +					       &(rrfd2->vn_addr.addr.v4)); +		else +			match = IPV6_ADDR_SAME(&(rrfd1->vn_addr.addr.v6), +					       &(rrfd2->vn_addr.addr.v6)); +	} -  /*  -   * If the VN addresses don't match in all forms,  -   * give up. -   */ -  if (!match) -    return 0; +	/* +	 * If the VN addresses don't match in all forms, +	 * give up. +	 */ +	if (!match) +		return 0; -  /*  -   * do the process again for the UN addresses.  -   */ -  match = 0; -  if (rrfd1->un_addr.addr_family == rrfd2->un_addr.addr_family) -    { -      /* VN addresses match -       * UN address families match  -       * now check the actual UN addresses -       */ -      if (rrfd1->un_addr.addr_family == AF_INET) -        match = IPV4_ADDR_SAME (&(rrfd1->un_addr.addr.v4), -                                &(rrfd2->un_addr.addr.v4)); -      else -        match = IPV6_ADDR_SAME (&(rrfd1->un_addr.addr.v6), -                                &(rrfd2->un_addr.addr.v6)); -    } -  return match; +	/* +	 * do the process again for the UN addresses. +	 */ +	match = 0; +	if (rrfd1->un_addr.addr_family == rrfd2->un_addr.addr_family) { +		/* VN addresses match +		 * UN address families match +		 * now check the actual UN addresses +		 */ +		if (rrfd1->un_addr.addr_family == AF_INET) +			match = IPV4_ADDR_SAME(&(rrfd1->un_addr.addr.v4), +					       &(rrfd2->un_addr.addr.v4)); +		else +			match = IPV6_ADDR_SAME(&(rrfd1->un_addr.addr.v6), +					       &(rrfd2->un_addr.addr.v6)); +	} +	return match;  } diff --git a/bgpd/rfapi/rfapi_descriptor_rfp_utils.h b/bgpd/rfapi/rfapi_descriptor_rfp_utils.h index 04fbfbcec8..dcc197961c 100644 --- a/bgpd/rfapi/rfapi_descriptor_rfp_utils.h +++ b/bgpd/rfapi/rfapi_descriptor_rfp_utils.h @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2009-2016, LabN Consulting, L.L.C.   * @@ -19,20 +19,20 @@   */ -extern void *rfapi_create_generic (struct rfapi_ip_addr *vn, -                                   struct rfapi_ip_addr *un); +extern void *rfapi_create_generic(struct rfapi_ip_addr *vn, +				  struct rfapi_ip_addr *un);  /*------------------------------------------   * rfapi_free_generic   *   * Compare two generic rfapi descriptors.   * - * input:  + * input:   *    grfd: rfapi descriptor returned by rfapi_open or rfapi_create_generic   *   * output:   * - * return value:  + * return value:   *   *------------------------------------------*/ -extern void rfapi_free_generic (void *grfd); +extern void rfapi_free_generic(void *grfd); diff --git a/bgpd/rfapi/rfapi_encap_tlv.c b/bgpd/rfapi/rfapi_encap_tlv.c index 24bfb41bfa..f31342e192 100644 --- a/bgpd/rfapi/rfapi_encap_tlv.c +++ b/bgpd/rfapi/rfapi_encap_tlv.c @@ -1,4 +1,4 @@ -/*  +/*   * Copyright 2015-2016, LabN Consulting, L.L.C.   *   * This program is free software; you can redistribute it and/or @@ -37,374 +37,350 @@  #include "bgpd/rfapi/bgp_rfapi_cfg.h"  #include "bgpd/rfapi/vnc_debug.h" -static void -rfapi_add_endpoint_address_to_subtlv ( -  struct bgp				*bgp, -  struct rfapi_ip_addr			*ea, -  struct bgp_tea_subtlv_remote_endpoint	*subtlv) +static void rfapi_add_endpoint_address_to_subtlv( +	struct bgp *bgp, struct rfapi_ip_addr *ea, +	struct bgp_tea_subtlv_remote_endpoint *subtlv)  { -  subtlv->family = ea->addr_family; -  if (subtlv->family == AF_INET) -    subtlv->ip_address.v4 = ea->addr.v4; -  else -    subtlv->ip_address.v6 = ea->addr.v6; -  subtlv->as4 = htonl (bgp->as); +	subtlv->family = ea->addr_family; +	if (subtlv->family == AF_INET) +		subtlv->ip_address.v4 = ea->addr.v4; +	else +		subtlv->ip_address.v6 = ea->addr.v6; +	subtlv->as4 = htonl(bgp->as);  }  bgp_encap_types -rfapi_tunneltype_option_to_tlv ( -  struct bgp				*bgp, -  struct rfapi_ip_addr			*ea, -  struct rfapi_tunneltype_option	*tto, -  struct attr				*attr, -  int					always_add) +rfapi_tunneltype_option_to_tlv(struct bgp *bgp, struct rfapi_ip_addr *ea, +			       struct rfapi_tunneltype_option *tto, +			       struct attr *attr, int always_add)  { -#define _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(ttype)                               \ -    if ((always_add || (bgp->rfapi_cfg &&                                     \ -                        !CHECK_FLAG(bgp->rfapi_cfg->flags,                    \ -                                    BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP))) &&  \ -        ea && !CHECK_SUBTLV_FLAG(&tto->bgpinfo.ttype,                         \ -                                 BGP_TEA_SUBTLV_REMOTE_ENDPOINT)) {           \ -        rfapi_add_endpoint_address_to_subtlv(bgp, ea,                         \ -                                           &tto->bgpinfo.ttype.st_endpoint);  \ -        SET_SUBTLV_FLAG(&tto->bgpinfo.ttype, BGP_TEA_SUBTLV_REMOTE_ENDPOINT); \ -    } - -  struct rfapi_tunneltype_option dto; -  if (tto == NULL) -    {                           /* create default type */ -      tto = &dto; -      memset (tto, 0, sizeof (dto)); -      tto->type = RFAPI_BGP_ENCAP_TYPE_DEFAULT; -    } -  switch (tto->type) -    { -    case BGP_ENCAP_TYPE_L2TPV3_OVER_IP: -      _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (l2tpv3_ip); -      bgp_encap_type_l2tpv3overip_to_tlv (&tto->bgpinfo.l2tpv3_ip, attr); -      break; - -    case BGP_ENCAP_TYPE_GRE: -      _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (gre); -      bgp_encap_type_gre_to_tlv (&tto->bgpinfo.gre, attr); -      break; - -    case BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT: -      _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (transmit_tunnel_endpoint); -      bgp_encap_type_transmit_tunnel_endpoint (&tto->bgpinfo.transmit_tunnel_endpoint, -                                               attr); -      break; - -    case BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE: -      _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (ipsec_tunnel); -      bgp_encap_type_ipsec_in_tunnel_mode_to_tlv (&tto->bgpinfo.ipsec_tunnel, -                                                  attr); -      break; - -    case BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE: -      _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (ip_ipsec); -      bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode_to_tlv -        (&tto->bgpinfo.ip_ipsec, attr); -      break; - -    case BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE: -      _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (mpls_ipsec); -      bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode_to_tlv -        (&tto->bgpinfo.mpls_ipsec, attr); -      break; - -    case BGP_ENCAP_TYPE_IP_IN_IP: -      _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (ip_ip); -      bgp_encap_type_ip_in_ip_to_tlv (&tto->bgpinfo.ip_ip, attr); -      break; - -    case BGP_ENCAP_TYPE_VXLAN: -      _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (vxlan); -      bgp_encap_type_vxlan_to_tlv (&tto->bgpinfo.vxlan, attr); -      break; - -    case BGP_ENCAP_TYPE_NVGRE: -      _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (nvgre); -      bgp_encap_type_nvgre_to_tlv (&tto->bgpinfo.nvgre, attr); -      break; - -    case BGP_ENCAP_TYPE_MPLS: -      /* nothing to do for MPLS */ -      break; - -    case BGP_ENCAP_TYPE_MPLS_IN_GRE: -      _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (mpls_gre); -      bgp_encap_type_mpls_in_gre_to_tlv (&tto->bgpinfo.mpls_gre, attr); -      break; - -    case BGP_ENCAP_TYPE_VXLAN_GPE: -      _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (vxlan_gpe); -      bgp_encap_type_vxlan_gpe_to_tlv (&tto->bgpinfo.vxlan_gpe, attr); -      break; - -    case BGP_ENCAP_TYPE_MPLS_IN_UDP: -      _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (mpls_udp); -      bgp_encap_type_mpls_in_udp_to_tlv (&tto->bgpinfo.mpls_udp, attr); -      break; - -    case BGP_ENCAP_TYPE_PBB: -      _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS (pbb); -      bgp_encap_type_pbb_to_tlv (&tto->bgpinfo.pbb, attr); -      break; - -    default: -      assert (0); -    } -  return tto->type; +#define _RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(ttype)                                \ +	if ((always_add                                                        \ +	     || (bgp->rfapi_cfg                                                \ +		 && !CHECK_FLAG(bgp->rfapi_cfg->flags,                         \ +				BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP)))          \ +	    && ea                                                              \ +	    && !CHECK_SUBTLV_FLAG(&tto->bgpinfo.ttype,                         \ +				  BGP_TEA_SUBTLV_REMOTE_ENDPOINT)) {           \ +		rfapi_add_endpoint_address_to_subtlv(                          \ +			bgp, ea, &tto->bgpinfo.ttype.st_endpoint);             \ +		SET_SUBTLV_FLAG(&tto->bgpinfo.ttype,                           \ +				BGP_TEA_SUBTLV_REMOTE_ENDPOINT);               \ +	} + +	struct rfapi_tunneltype_option dto; +	if (tto == NULL) { /* create default type */ +		tto = &dto; +		memset(tto, 0, sizeof(dto)); +		tto->type = RFAPI_BGP_ENCAP_TYPE_DEFAULT; +	} +	switch (tto->type) { +	case BGP_ENCAP_TYPE_L2TPV3_OVER_IP: +		_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(l2tpv3_ip); +		bgp_encap_type_l2tpv3overip_to_tlv(&tto->bgpinfo.l2tpv3_ip, +						   attr); +		break; + +	case BGP_ENCAP_TYPE_GRE: +		_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(gre); +		bgp_encap_type_gre_to_tlv(&tto->bgpinfo.gre, attr); +		break; + +	case BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT: +		_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(transmit_tunnel_endpoint); +		bgp_encap_type_transmit_tunnel_endpoint( +			&tto->bgpinfo.transmit_tunnel_endpoint, attr); +		break; + +	case BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE: +		_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(ipsec_tunnel); +		bgp_encap_type_ipsec_in_tunnel_mode_to_tlv( +			&tto->bgpinfo.ipsec_tunnel, attr); +		break; + +	case BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE: +		_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(ip_ipsec); +		bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode_to_tlv( +			&tto->bgpinfo.ip_ipsec, attr); +		break; + +	case BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE: +		_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(mpls_ipsec); +		bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode_to_tlv( +			&tto->bgpinfo.mpls_ipsec, attr); +		break; + +	case BGP_ENCAP_TYPE_IP_IN_IP: +		_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(ip_ip); +		bgp_encap_type_ip_in_ip_to_tlv(&tto->bgpinfo.ip_ip, attr); +		break; + +	case BGP_ENCAP_TYPE_VXLAN: +		_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(vxlan); +		bgp_encap_type_vxlan_to_tlv(&tto->bgpinfo.vxlan, attr); +		break; + +	case BGP_ENCAP_TYPE_NVGRE: +		_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(nvgre); +		bgp_encap_type_nvgre_to_tlv(&tto->bgpinfo.nvgre, attr); +		break; + +	case BGP_ENCAP_TYPE_MPLS: +		/* nothing to do for MPLS */ +		break; + +	case BGP_ENCAP_TYPE_MPLS_IN_GRE: +		_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(mpls_gre); +		bgp_encap_type_mpls_in_gre_to_tlv(&tto->bgpinfo.mpls_gre, attr); +		break; + +	case BGP_ENCAP_TYPE_VXLAN_GPE: +		_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(vxlan_gpe); +		bgp_encap_type_vxlan_gpe_to_tlv(&tto->bgpinfo.vxlan_gpe, attr); +		break; + +	case BGP_ENCAP_TYPE_MPLS_IN_UDP: +		_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(mpls_udp); +		bgp_encap_type_mpls_in_udp_to_tlv(&tto->bgpinfo.mpls_udp, attr); +		break; + +	case BGP_ENCAP_TYPE_PBB: +		_RTTO_MAYBE_ADD_ENDPOINT_ADDRESS(pbb); +		bgp_encap_type_pbb_to_tlv(&tto->bgpinfo.pbb, attr); +		break; + +	default: +		assert(0); +	} +	return tto->type;  } -struct rfapi_un_option * -rfapi_encap_tlv_to_un_option (struct attr *attr) +struct rfapi_un_option *rfapi_encap_tlv_to_un_option(struct attr *attr)  { -  struct rfapi_un_option *uo = NULL; -  struct rfapi_tunneltype_option *tto; -  int rc; -  struct bgp_attr_encap_subtlv *stlv; - -  /* no tunnel encap attr stored */ -  if (!attr->encap_tunneltype) -    return NULL; - -  stlv = attr->encap_subtlvs; - -  uo = XCALLOC (MTYPE_RFAPI_UN_OPTION, sizeof (struct rfapi_un_option)); -  assert (uo); -  uo->type = RFAPI_UN_OPTION_TYPE_TUNNELTYPE; -  uo->v.tunnel.type = attr->encap_tunneltype; -  tto = &uo->v.tunnel; - -  switch (attr->encap_tunneltype) -    { -    case BGP_ENCAP_TYPE_L2TPV3_OVER_IP: -      rc = tlv_to_bgp_encap_type_l2tpv3overip (stlv, &tto->bgpinfo.l2tpv3_ip); -      break; - -    case BGP_ENCAP_TYPE_GRE: -      rc = tlv_to_bgp_encap_type_gre (stlv, &tto->bgpinfo.gre); -      break; - -    case BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT: -      rc = tlv_to_bgp_encap_type_transmit_tunnel_endpoint (stlv, -                                                           &tto->bgpinfo.transmit_tunnel_endpoint); -      break; - -    case BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE: -      rc = tlv_to_bgp_encap_type_ipsec_in_tunnel_mode (stlv, -                                                       &tto->bgpinfo.ipsec_tunnel); -      break; - -    case BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE: -      rc = -        tlv_to_bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode (stlv, -                                                                         &tto->bgpinfo.ip_ipsec); -      break; - -    case BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE: -      rc = -        tlv_to_bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode -        (stlv, &tto->bgpinfo.mpls_ipsec); -      break; - -    case BGP_ENCAP_TYPE_IP_IN_IP: -      rc = tlv_to_bgp_encap_type_ip_in_ip (stlv, &tto->bgpinfo.ip_ip); -      break; - -    case BGP_ENCAP_TYPE_VXLAN: -      rc = tlv_to_bgp_encap_type_vxlan (stlv, &tto->bgpinfo.vxlan); -      break; - -    case BGP_ENCAP_TYPE_NVGRE: -      rc = tlv_to_bgp_encap_type_nvgre (stlv, &tto->bgpinfo.nvgre); -      break; - -    case BGP_ENCAP_TYPE_MPLS: -      rc = tlv_to_bgp_encap_type_mpls (stlv, &tto->bgpinfo.mpls); -      break; - -    case BGP_ENCAP_TYPE_MPLS_IN_GRE: -      rc = tlv_to_bgp_encap_type_mpls_in_gre (stlv, &tto->bgpinfo.mpls_gre); -      break; - -    case BGP_ENCAP_TYPE_VXLAN_GPE: -      rc = tlv_to_bgp_encap_type_vxlan_gpe (stlv, &tto->bgpinfo.vxlan_gpe); -      break; - -    case BGP_ENCAP_TYPE_MPLS_IN_UDP: -      rc = tlv_to_bgp_encap_type_mpls_in_udp (stlv, &tto->bgpinfo.mpls_udp); -      break; - -    case BGP_ENCAP_TYPE_PBB: -      rc = tlv_to_bgp_encap_type_pbb (stlv, &tto->bgpinfo.pbb); -      break; - -    default: -      vnc_zlog_debug_verbose ("%s: unknown tunnel type %d", -                  __func__, attr->encap_tunneltype); -      rc = -1; -      break; -    } -  if (rc) -    { -      XFREE (MTYPE_RFAPI_UN_OPTION, uo); -      uo = NULL; -    } -  return uo; +	struct rfapi_un_option *uo = NULL; +	struct rfapi_tunneltype_option *tto; +	int rc; +	struct bgp_attr_encap_subtlv *stlv; + +	/* no tunnel encap attr stored */ +	if (!attr->encap_tunneltype) +		return NULL; + +	stlv = attr->encap_subtlvs; + +	uo = XCALLOC(MTYPE_RFAPI_UN_OPTION, sizeof(struct rfapi_un_option)); +	assert(uo); +	uo->type = RFAPI_UN_OPTION_TYPE_TUNNELTYPE; +	uo->v.tunnel.type = attr->encap_tunneltype; +	tto = &uo->v.tunnel; + +	switch (attr->encap_tunneltype) { +	case BGP_ENCAP_TYPE_L2TPV3_OVER_IP: +		rc = tlv_to_bgp_encap_type_l2tpv3overip( +			stlv, &tto->bgpinfo.l2tpv3_ip); +		break; + +	case BGP_ENCAP_TYPE_GRE: +		rc = tlv_to_bgp_encap_type_gre(stlv, &tto->bgpinfo.gre); +		break; + +	case BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT: +		rc = tlv_to_bgp_encap_type_transmit_tunnel_endpoint( +			stlv, &tto->bgpinfo.transmit_tunnel_endpoint); +		break; + +	case BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE: +		rc = tlv_to_bgp_encap_type_ipsec_in_tunnel_mode( +			stlv, &tto->bgpinfo.ipsec_tunnel); +		break; + +	case BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE: +		rc = tlv_to_bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode( +			stlv, &tto->bgpinfo.ip_ipsec); +		break; + +	case BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE: +		rc = tlv_to_bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode( +			stlv, &tto->bgpinfo.mpls_ipsec); +		break; + +	case BGP_ENCAP_TYPE_IP_IN_IP: +		rc = tlv_to_bgp_encap_type_ip_in_ip(stlv, &tto->bgpinfo.ip_ip); +		break; + +	case BGP_ENCAP_TYPE_VXLAN: +		rc = tlv_to_bgp_encap_type_vxlan(stlv, &tto->bgpinfo.vxlan); +		break; + +	case BGP_ENCAP_TYPE_NVGRE: +		rc = tlv_to_bgp_encap_type_nvgre(stlv, &tto->bgpinfo.nvgre); +		break; + +	case BGP_ENCAP_TYPE_MPLS: +		rc = tlv_to_bgp_encap_type_mpls(stlv, &tto->bgpinfo.mpls); +		break; + +	case BGP_ENCAP_TYPE_MPLS_IN_GRE: +		rc = tlv_to_bgp_encap_type_mpls_in_gre(stlv, +						       &tto->bgpinfo.mpls_gre); +		break; + +	case BGP_ENCAP_TYPE_VXLAN_GPE: +		rc = tlv_to_bgp_encap_type_vxlan_gpe(stlv, +						     &tto->bgpinfo.vxlan_gpe); +		break; + +	case BGP_ENCAP_TYPE_MPLS_IN_UDP: +		rc = tlv_to_bgp_encap_type_mpls_in_udp(stlv, +						       &tto->bgpinfo.mpls_udp); +		break; + +	case BGP_ENCAP_TYPE_PBB: +		rc = tlv_to_bgp_encap_type_pbb(stlv, &tto->bgpinfo.pbb); +		break; + +	default: +		vnc_zlog_debug_verbose("%s: unknown tunnel type %d", __func__, +				       attr->encap_tunneltype); +		rc = -1; +		break; +	} +	if (rc) { +		XFREE(MTYPE_RFAPI_UN_OPTION, uo); +		uo = NULL; +	} +	return uo;  }  /***********************************************************************   *			SUBTLV PRINT   ***********************************************************************/ -static void -subtlv_print_encap_l2tpv3_over_ip ( -  void						*stream, -  int						column_offset, -  struct bgp_tea_subtlv_encap_l2tpv3_over_ip	*st) +static void subtlv_print_encap_l2tpv3_over_ip( +	void *stream, int column_offset, +	struct bgp_tea_subtlv_encap_l2tpv3_over_ip *st)  { -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; - -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; -  if (!st) -    return; - -  fp (out, "%*s%s%s", column_offset, "", "SubTLV: Encap(L2TPv3 over IP)", -      vty_newline); -  fp (out, "%*s  SessionID: %d%s", column_offset, "", st->sessionid, -      vty_newline); -  fp (out, "%*s  Cookie: (length %d)%s", column_offset, "", st->cookie_length, -      vty_newline); +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; + +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; +	if (!st) +		return; + +	fp(out, "%*s%s%s", column_offset, "", "SubTLV: Encap(L2TPv3 over IP)", +	   vty_newline); +	fp(out, "%*s  SessionID: %d%s", column_offset, "", st->sessionid, +	   vty_newline); +	fp(out, "%*s  Cookie: (length %d)%s", column_offset, "", +	   st->cookie_length, vty_newline);  } -static void -subtlv_print_encap_gre ( -  void					*stream, -  int					column_offset, -  struct bgp_tea_subtlv_encap_gre_key	*st) +static void subtlv_print_encap_gre(void *stream, int column_offset, +				   struct bgp_tea_subtlv_encap_gre_key *st)  { -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; - -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; -  if (!st) -    return; - -  fp (out, "%*s%s%s", column_offset, "", "SubTLV: Encap(GRE)", vty_newline); -  fp (out, "%*s  GRE key: %d (0x%x)%s", column_offset, "", st->gre_key, -      st->gre_key, vty_newline); +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; + +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; +	if (!st) +		return; + +	fp(out, "%*s%s%s", column_offset, "", "SubTLV: Encap(GRE)", +	   vty_newline); +	fp(out, "%*s  GRE key: %d (0x%x)%s", column_offset, "", st->gre_key, +	   st->gre_key, vty_newline);  } -static void -subtlv_print_encap_pbb ( -  void					*stream, -  int					column_offset, -  struct bgp_tea_subtlv_encap_pbb	*st) +static void subtlv_print_encap_pbb(void *stream, int column_offset, +				   struct bgp_tea_subtlv_encap_pbb *st)  { -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; - -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; -  if (!st) -    return; - -  fp (out, "%*s%s%s", column_offset, "", "SubTLV: Encap(PBB)", vty_newline); -  if (st->flag_isid) -    { -      fp (out, "%*s  ISID: %d (0x%x)%s", column_offset, "", st->isid, -          st->isid, vty_newline); -    } -  if (st->flag_vid) -    { -      fp (out, "%*s  VID: %d (0x%x)%s", column_offset, "", st->vid, st->vid, -          vty_newline); -    } -  fp (out, "%*s  MACADDR %02x:%02x:%02x:%02x:%02x:%02x%s", -      column_offset, "", -      st->macaddr[0], -      st->macaddr[1], -      st->macaddr[2], -      st->macaddr[3], st->macaddr[4], st->macaddr[5], vty_newline); +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; + +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; +	if (!st) +		return; + +	fp(out, "%*s%s%s", column_offset, "", "SubTLV: Encap(PBB)", +	   vty_newline); +	if (st->flag_isid) { +		fp(out, "%*s  ISID: %d (0x%x)%s", column_offset, "", st->isid, +		   st->isid, vty_newline); +	} +	if (st->flag_vid) { +		fp(out, "%*s  VID: %d (0x%x)%s", column_offset, "", st->vid, +		   st->vid, vty_newline); +	} +	fp(out, "%*s  MACADDR %02x:%02x:%02x:%02x:%02x:%02x%s", column_offset, +	   "", st->macaddr[0], st->macaddr[1], st->macaddr[2], st->macaddr[3], +	   st->macaddr[4], st->macaddr[5], vty_newline);  } -static void -subtlv_print_proto_type ( -  void					*stream, -  int					column_offset, -  struct bgp_tea_subtlv_proto_type	*st) +static void subtlv_print_proto_type(void *stream, int column_offset, +				    struct bgp_tea_subtlv_proto_type *st)  { -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; - -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; -  if (!st) -    return; - -  fp (out, "%*s%s%s", column_offset, "", "SubTLV: Encap(Proto Type)", -      vty_newline); -  fp (out, "%*s  Proto %d (0x%x)%s", column_offset, "", st->proto, st->proto, -      vty_newline); +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; + +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; +	if (!st) +		return; + +	fp(out, "%*s%s%s", column_offset, "", "SubTLV: Encap(Proto Type)", +	   vty_newline); +	fp(out, "%*s  Proto %d (0x%x)%s", column_offset, "", st->proto, +	   st->proto, vty_newline);  } -static void -subtlv_print_color ( -  void				*stream, -  int				column_offset, -  struct bgp_tea_subtlv_color	*st) +static void subtlv_print_color(void *stream, int column_offset, +			       struct bgp_tea_subtlv_color *st)  { -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; - -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; -  if (!st) -    return; - -  fp (out, "%*s%s%s", column_offset, "", "SubTLV: Color", vty_newline); -  fp (out, "%*s  Color: %d (0x%x)", column_offset, "", st->color, st->color, -      vty_newline); +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; + +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; +	if (!st) +		return; + +	fp(out, "%*s%s%s", column_offset, "", "SubTLV: Color", vty_newline); +	fp(out, "%*s  Color: %d (0x%x)", column_offset, "", st->color, +	   st->color, vty_newline);  } -static void -subtlv_print_ipsec_ta ( -  void					*stream, -  int					column_offset, -  struct bgp_tea_subtlv_ipsec_ta	*st) +static void subtlv_print_ipsec_ta(void *stream, int column_offset, +				  struct bgp_tea_subtlv_ipsec_ta *st)  { -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; - -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; -  if (!st) -    return; - -  fp (out, "%*s%s%s", column_offset, "", "SubTLV: IPSEC TA", vty_newline); -  fp (out, "%*s  Authenticator Type: %d (0x%x)", column_offset, "", -      st->authenticator_type, st->authenticator_type, vty_newline); -  fp (out, "%*s  Authenticator: (length %d)", column_offset, "", -      st->authenticator_length, vty_newline); +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; + +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; +	if (!st) +		return; + +	fp(out, "%*s%s%s", column_offset, "", "SubTLV: IPSEC TA", vty_newline); +	fp(out, "%*s  Authenticator Type: %d (0x%x)", column_offset, "", +	   st->authenticator_type, st->authenticator_type, vty_newline); +	fp(out, "%*s  Authenticator: (length %d)", column_offset, "", +	   st->authenticator_length, vty_newline);  }  /*********************************************************************** @@ -412,396 +388,358 @@ subtlv_print_ipsec_ta (   ***********************************************************************/  static void -print_encap_type_l2tpv3overip ( -  void					*stream, -  int					column_offset, -  struct bgp_encap_type_l2tpv3_over_ip	*bet) +print_encap_type_l2tpv3overip(void *stream, int column_offset, +			      struct bgp_encap_type_l2tpv3_over_ip *bet)  { -  const char *type = "L2TPv3 over IP"; -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; - -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; -  if (!bet) -    return; - -  fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); - -  subtlv_print_encap_l2tpv3_over_ip (stream, column_offset + 2, -                                     &bet->st_encap); -  subtlv_print_proto_type (stream, column_offset + 2, &bet->st_proto); -  subtlv_print_color (stream, column_offset + 2, &bet->st_color); +	const char *type = "L2TPv3 over IP"; +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; + +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; +	if (!bet) +		return; + +	fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); + +	subtlv_print_encap_l2tpv3_over_ip(stream, column_offset + 2, +					  &bet->st_encap); +	subtlv_print_proto_type(stream, column_offset + 2, &bet->st_proto); +	subtlv_print_color(stream, column_offset + 2, &bet->st_color);  } -static void -print_encap_type_gre ( -  void				*stream, -  int				column_offset, -  struct bgp_encap_type_gre	*bet) +static void print_encap_type_gre(void *stream, int column_offset, +				 struct bgp_encap_type_gre *bet)  { -  const char *type = "GRE"; -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; - -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; -  if (!bet) -    return; - -  fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); - -  subtlv_print_encap_gre (stream, column_offset + 2, &bet->st_encap); -  subtlv_print_proto_type (stream, column_offset + 2, &bet->st_proto); -  subtlv_print_color (stream, column_offset + 2, &bet->st_color); +	const char *type = "GRE"; +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; + +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; +	if (!bet) +		return; + +	fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); + +	subtlv_print_encap_gre(stream, column_offset + 2, &bet->st_encap); +	subtlv_print_proto_type(stream, column_offset + 2, &bet->st_proto); +	subtlv_print_color(stream, column_offset + 2, &bet->st_color);  } -static void -print_encap_type_ip_in_ip ( -  void					*stream, -  int					column_offset, -  struct bgp_encap_type_ip_in_ip	*bet) +static void print_encap_type_ip_in_ip(void *stream, int column_offset, +				      struct bgp_encap_type_ip_in_ip *bet)  { -  const char *type = "IP in IP"; -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; +	const char *type = "IP in IP"; +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; -  if (!bet) -    return; +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; +	if (!bet) +		return; -  fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); +	fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); -  subtlv_print_proto_type (stream, column_offset + 2, &bet->st_proto); -  subtlv_print_color (stream, column_offset + 2, &bet->st_color); +	subtlv_print_proto_type(stream, column_offset + 2, &bet->st_proto); +	subtlv_print_color(stream, column_offset + 2, &bet->st_color);  } -static void -print_encap_type_transmit_tunnel_endpoint ( -  void							*stream, -  int							column_offset, -  struct bgp_encap_type_transmit_tunnel_endpoint	*bet) +static void print_encap_type_transmit_tunnel_endpoint( +	void *stream, int column_offset, +	struct bgp_encap_type_transmit_tunnel_endpoint *bet)  { -  const char *type = "Transmit Tunnel Endpoint"; -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; +	const char *type = "Transmit Tunnel Endpoint"; +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; -  if (!bet) -    return; +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; +	if (!bet) +		return; -  fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); +	fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); -  /* no subtlvs for this type */ +	/* no subtlvs for this type */  } -static void -print_encap_type_ipsec_in_tunnel_mode ( -  void						*stream, -  int						column_offset, -  struct bgp_encap_type_ipsec_in_tunnel_mode	*bet) +static void print_encap_type_ipsec_in_tunnel_mode( +	void *stream, int column_offset, +	struct bgp_encap_type_ipsec_in_tunnel_mode *bet)  { -  const char *type = "IPSEC in Tunnel mode"; -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; - -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; -  if (!bet) -    return; - -  fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); -  subtlv_print_ipsec_ta (stream, column_offset + 2, &bet->st_ipsec_ta); +	const char *type = "IPSEC in Tunnel mode"; +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; + +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; +	if (!bet) +		return; + +	fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); +	subtlv_print_ipsec_ta(stream, column_offset + 2, &bet->st_ipsec_ta);  } -static void -print_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode ( -  void	*stream, -  int	column_offset, -  struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode	*bet) +static void print_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode( +	void *stream, int column_offset, +	struct bgp_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode *bet)  { -  const char *type = "IP in IP Tunnel with IPSEC transport mode"; -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; +	const char *type = "IP in IP Tunnel with IPSEC transport mode"; +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; -  if (!bet) -    return; +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; +	if (!bet) +		return; -  fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); +	fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); -  subtlv_print_ipsec_ta (stream, column_offset + 2, &bet->st_ipsec_ta); +	subtlv_print_ipsec_ta(stream, column_offset + 2, &bet->st_ipsec_ta);  } -static void -print_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode ( -  void	*stream, -  int	column_offset, -  struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode	*bet) +static void print_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode( +	void *stream, int column_offset, +	struct bgp_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode *bet)  { -  const char *type = "MPLS in IP Tunnel with IPSEC transport mode"; -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; +	const char *type = "MPLS in IP Tunnel with IPSEC transport mode"; +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; -  if (!bet) -    return; +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; +	if (!bet) +		return; -  fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); +	fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); -  subtlv_print_ipsec_ta (stream, column_offset + 2, &bet->st_ipsec_ta); +	subtlv_print_ipsec_ta(stream, column_offset + 2, &bet->st_ipsec_ta);  } -static void -print_encap_type_pbb ( -  void				*stream, -  int				column_offset, -  struct bgp_encap_type_pbb	*bet) +static void print_encap_type_pbb(void *stream, int column_offset, +				 struct bgp_encap_type_pbb *bet)  { -  const char *type = "PBB"; -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; +	const char *type = "PBB"; +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; -  if (!bet) -    return; +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; +	if (!bet) +		return; -  fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); +	fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); -  subtlv_print_encap_pbb (stream, column_offset + 2, &bet->st_encap); +	subtlv_print_encap_pbb(stream, column_offset + 2, &bet->st_encap);  } -static void -print_encap_type_vxlan ( -  void				*stream, -  int				column_offset, -  struct bgp_encap_type_vxlan	*bet) +static void print_encap_type_vxlan(void *stream, int column_offset, +				   struct bgp_encap_type_vxlan *bet)  { -  const char *type = "VXLAN"; -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; +	const char *type = "VXLAN"; +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; -  if (!bet) -    return; +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; +	if (!bet) +		return; -  fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); +	fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); -  /* no subtlvs for this type */ +	/* no subtlvs for this type */  } -static void -print_encap_type_nvgre ( -  void				*stream, -  int				column_offset, -  struct bgp_encap_type_nvgre	*bet) +static void print_encap_type_nvgre(void *stream, int column_offset, +				   struct bgp_encap_type_nvgre *bet)  { -  const char *type = "NVGRE"; -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; +	const char *type = "NVGRE"; +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; -  if (!bet) -    return; +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; +	if (!bet) +		return; -  fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); +	fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); -  /* no subtlvs for this type */ +	/* no subtlvs for this type */  } -static void -print_encap_type_mpls ( -  void				*stream, -  int				column_offset, -  struct bgp_encap_type_mpls	*bet) +static void print_encap_type_mpls(void *stream, int column_offset, +				  struct bgp_encap_type_mpls *bet)  { -  const char *type = "MPLS"; -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; +	const char *type = "MPLS"; +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; -  if (!bet) -    return; +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; +	if (!bet) +		return; -  fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); +	fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); -  /* no subtlvs for this type */ +	/* no subtlvs for this type */  } -static void -print_encap_type_mpls_in_gre ( -  void					*stream, -  int					column_offset, -  struct bgp_encap_type_mpls_in_gre	*bet) +static void print_encap_type_mpls_in_gre(void *stream, int column_offset, +					 struct bgp_encap_type_mpls_in_gre *bet)  { -  const char *type = "MPLS in GRE"; -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; +	const char *type = "MPLS in GRE"; +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; -  if (!bet) -    return; +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; +	if (!bet) +		return; -  fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); +	fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); -  /* no subtlvs for this type */ +	/* no subtlvs for this type */  } -static void -print_encap_type_vxlan_gpe ( -  void					*stream, -  int					column_offset, -  struct bgp_encap_type_vxlan_gpe	*bet) +static void print_encap_type_vxlan_gpe(void *stream, int column_offset, +				       struct bgp_encap_type_vxlan_gpe *bet)  { -  const char *type = "VXLAN GPE"; -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; +	const char *type = "VXLAN GPE"; +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; -  if (!bet) -    return; +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; +	if (!bet) +		return; -  fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); +	fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); -  /* no subtlvs for this type */ +	/* no subtlvs for this type */  } -static void -print_encap_type_mpls_in_udp ( -  void					*stream, -  int					column_offset, -  struct bgp_encap_type_mpls_in_udp	*bet) +static void print_encap_type_mpls_in_udp(void *stream, int column_offset, +					 struct bgp_encap_type_mpls_in_udp *bet)  { -  const char *type = "MPLS in UDP"; -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; +	const char *type = "MPLS in UDP"; +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; -  if (!bet) -    return; +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; +	if (!bet) +		return; -  fp (out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); +	fp(out, "%*sTEA type %s%s", column_offset, "", type, vty_newline); -  /* no subtlvs for this type */ +	/* no subtlvs for this type */  } -void -rfapi_print_tunneltype_option ( -  void					*stream, -  int					column_offset, -  struct rfapi_tunneltype_option	*tto) +void rfapi_print_tunneltype_option(void *stream, int column_offset, +				   struct rfapi_tunneltype_option *tto)  { -  switch (tto->type) -    { -    case BGP_ENCAP_TYPE_L2TPV3_OVER_IP: -      print_encap_type_l2tpv3overip (stream, column_offset, -                                     &tto->bgpinfo.l2tpv3_ip); -      break; - -    case BGP_ENCAP_TYPE_GRE: -      print_encap_type_gre (stream, column_offset, &tto->bgpinfo.gre); -      break; - -    case BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT: -      print_encap_type_transmit_tunnel_endpoint (stream, column_offset, -                                                 &tto->bgpinfo.transmit_tunnel_endpoint); -      break; - -    case BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE: -      print_encap_type_ipsec_in_tunnel_mode (stream, column_offset, -                                             &tto->bgpinfo.ipsec_tunnel); -      break; - -    case BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE: -      print_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode (stream, -                                                                  column_offset, -                                                                  &tto->bgpinfo.ip_ipsec); -      break; - -    case BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE: -      print_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode (stream, -                                                                    column_offset, -                                                                    &tto->bgpinfo.mpls_ipsec); -      break; - -    case BGP_ENCAP_TYPE_IP_IN_IP: -      print_encap_type_ip_in_ip (stream, column_offset, &tto->bgpinfo.ip_ip); -      break; - -    case BGP_ENCAP_TYPE_VXLAN: -      print_encap_type_vxlan (stream, column_offset, &tto->bgpinfo.vxlan); -      break; - -    case BGP_ENCAP_TYPE_NVGRE: -      print_encap_type_nvgre (stream, column_offset, &tto->bgpinfo.nvgre); -      break; - -    case BGP_ENCAP_TYPE_MPLS: -      print_encap_type_mpls (stream, column_offset, &tto->bgpinfo.mpls); -      break; - -    case BGP_ENCAP_TYPE_MPLS_IN_GRE: -      print_encap_type_mpls_in_gre (stream, column_offset, -                                    &tto->bgpinfo.mpls_gre); -      break; - -    case BGP_ENCAP_TYPE_VXLAN_GPE: -      print_encap_type_vxlan_gpe (stream, column_offset, -                                  &tto->bgpinfo.vxlan_gpe); -      break; - -    case BGP_ENCAP_TYPE_MPLS_IN_UDP: -      print_encap_type_mpls_in_udp (stream, column_offset, -                                    &tto->bgpinfo.mpls_udp); -      break; - -    case BGP_ENCAP_TYPE_PBB: -      print_encap_type_pbb (stream, column_offset, &tto->bgpinfo.pbb); -      break; - -    default: -      assert (0); -    } +	switch (tto->type) { +	case BGP_ENCAP_TYPE_L2TPV3_OVER_IP: +		print_encap_type_l2tpv3overip(stream, column_offset, +					      &tto->bgpinfo.l2tpv3_ip); +		break; + +	case BGP_ENCAP_TYPE_GRE: +		print_encap_type_gre(stream, column_offset, &tto->bgpinfo.gre); +		break; + +	case BGP_ENCAP_TYPE_TRANSMIT_TUNNEL_ENDPOINT: +		print_encap_type_transmit_tunnel_endpoint( +			stream, column_offset, +			&tto->bgpinfo.transmit_tunnel_endpoint); +		break; + +	case BGP_ENCAP_TYPE_IPSEC_IN_TUNNEL_MODE: +		print_encap_type_ipsec_in_tunnel_mode( +			stream, column_offset, &tto->bgpinfo.ipsec_tunnel); +		break; + +	case BGP_ENCAP_TYPE_IP_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE: +		print_encap_type_ip_in_ip_tunnel_with_ipsec_transport_mode( +			stream, column_offset, &tto->bgpinfo.ip_ipsec); +		break; + +	case BGP_ENCAP_TYPE_MPLS_IN_IP_TUNNEL_WITH_IPSEC_TRANSPORT_MODE: +		print_encap_type_mpls_in_ip_tunnel_with_ipsec_transport_mode( +			stream, column_offset, &tto->bgpinfo.mpls_ipsec); +		break; + +	case BGP_ENCAP_TYPE_IP_IN_IP: +		print_encap_type_ip_in_ip(stream, column_offset, +					  &tto->bgpinfo.ip_ip); +		break; + +	case BGP_ENCAP_TYPE_VXLAN: +		print_encap_type_vxlan(stream, column_offset, +				       &tto->bgpinfo.vxlan); +		break; + +	case BGP_ENCAP_TYPE_NVGRE: +		print_encap_type_nvgre(stream, column_offset, +				       &tto->bgpinfo.nvgre); +		break; + +	case BGP_ENCAP_TYPE_MPLS: +		print_encap_type_mpls(stream, column_offset, +				      &tto->bgpinfo.mpls); +		break; + +	case BGP_ENCAP_TYPE_MPLS_IN_GRE: +		print_encap_type_mpls_in_gre(stream, column_offset, +					     &tto->bgpinfo.mpls_gre); +		break; + +	case BGP_ENCAP_TYPE_VXLAN_GPE: +		print_encap_type_vxlan_gpe(stream, column_offset, +					   &tto->bgpinfo.vxlan_gpe); +		break; + +	case BGP_ENCAP_TYPE_MPLS_IN_UDP: +		print_encap_type_mpls_in_udp(stream, column_offset, +					     &tto->bgpinfo.mpls_udp); +		break; + +	case BGP_ENCAP_TYPE_PBB: +		print_encap_type_pbb(stream, column_offset, &tto->bgpinfo.pbb); +		break; + +	default: +		assert(0); +	}  } diff --git a/bgpd/rfapi/rfapi_encap_tlv.h b/bgpd/rfapi/rfapi_encap_tlv.h index 19e16a41a5..57e1b5ef04 100644 --- a/bgpd/rfapi/rfapi_encap_tlv.h +++ b/bgpd/rfapi/rfapi_encap_tlv.h @@ -1,4 +1,4 @@ -/*  +/*   * Copyright 2015-2016, LabN Consulting, L.L.C.   *   * This program is free software; you can redistribute it and/or @@ -22,21 +22,14 @@  #define RFAPI_BGP_ENCAP_TYPE_DEFAULT BGP_ENCAP_TYPE_IP_IN_IP  extern bgp_encap_types -rfapi_tunneltype_option_to_tlv ( -  struct bgp				*bgp, -  struct rfapi_ip_addr			*ea, -  struct rfapi_tunneltype_option	*tto, -  struct attr				*attr, -  int					always_add); +rfapi_tunneltype_option_to_tlv(struct bgp *bgp, struct rfapi_ip_addr *ea, +			       struct rfapi_tunneltype_option *tto, +			       struct attr *attr, int always_add); -extern struct rfapi_un_option * -rfapi_encap_tlv_to_un_option (struct attr *attr); +extern struct rfapi_un_option *rfapi_encap_tlv_to_un_option(struct attr *attr); -extern void -rfapi_print_tunneltype_option ( -  void					*stream, -  int					column_offset, -  struct rfapi_tunneltype_option	*tto); +extern void rfapi_print_tunneltype_option(void *stream, int column_offset, +					  struct rfapi_tunneltype_option *tto);  #endif /* _QUAGGA_BGP_RFAPI_ENCAP_TLV_H */ diff --git a/bgpd/rfapi/rfapi_import.c b/bgpd/rfapi/rfapi_import.c index dc8dc1ed2e..d0379e1ef8 100644 --- a/bgpd/rfapi/rfapi_import.c +++ b/bgpd/rfapi/rfapi_import.c @@ -1,22 +1,22 @@ - /*  - * - * Copyright 2009-2016, LabN Consulting, L.L.C. - * - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ +/* +* +* Copyright 2009-2016, LabN Consulting, L.L.C. +* +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License along +* with this program; see the file COPYING; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/  /*   * File:	rfapi_import.c @@ -38,7 +38,7 @@  #include "bgpd/bgp_ecommunity.h"  #include "bgpd/bgp_attr.h"  #include "bgpd/bgp_route.h" -#include "bgpd/bgp_mplsvpn.h"        /* prefix_rd2str() */ +#include "bgpd/bgp_mplsvpn.h" /* prefix_rd2str() */  #include "bgpd/bgp_vnc_types.h"  #include "bgpd/rfapi/rfapi.h" @@ -75,47 +75,44 @@   * Allocated for each withdraw timer instance; freed when the timer   * expires or is canceled   */ -struct rfapi_withdraw -{ -  struct rfapi_import_table *import_table; -  struct route_node *node; -  struct bgp_info *info; -  safi_t safi;                  /* used only for bulk operations */ -  /* -   * For import table node reference count checking (i.e., debugging). -   * Normally when a timer expires, lockoffset should be 0. However, if -   * the timer expiration function is called directly (e.g., -   * rfapiExpireVpnNow), the node could be locked by a preceding -   * route_top() or route_next() in a loop, so we need to pass this -   * value in. -   */ -  int lockoffset; +struct rfapi_withdraw { +	struct rfapi_import_table *import_table; +	struct route_node *node; +	struct bgp_info *info; +	safi_t safi; /* used only for bulk operations */ +	/* +	 * For import table node reference count checking (i.e., debugging). +	 * Normally when a timer expires, lockoffset should be 0. However, if +	 * the timer expiration function is called directly (e.g., +	 * rfapiExpireVpnNow), the node could be locked by a preceding +	 * route_top() or route_next() in a loop, so we need to pass this +	 * value in. +	 */ +	int lockoffset;  }; -/*  +/*   * DEBUG FUNCTION   * It's evil and fiendish. It's compiler-dependent.   * ? Might need LDFLAGS -rdynamic to produce all function names   */ -void -rfapiDebugBacktrace (void) +void rfapiDebugBacktrace(void)  {  #ifdef HAVE_GLIBC_BACKTRACE  #define RFAPI_DEBUG_BACKTRACE_NENTRIES	200 -  void *buf[RFAPI_DEBUG_BACKTRACE_NENTRIES]; -  char **syms; -  size_t i; -  size_t size; +	void *buf[RFAPI_DEBUG_BACKTRACE_NENTRIES]; +	char **syms; +	size_t i; +	size_t size; -  size = backtrace (buf, RFAPI_DEBUG_BACKTRACE_NENTRIES); -  syms = backtrace_symbols (buf, size); +	size = backtrace(buf, RFAPI_DEBUG_BACKTRACE_NENTRIES); +	syms = backtrace_symbols(buf, size); -  for (i = 0; i < size && i < RFAPI_DEBUG_BACKTRACE_NENTRIES; ++i) -    { -      vnc_zlog_debug_verbose ("backtrace[%2zu]: %s", i, syms[i]); -    } +	for (i = 0; i < size && i < RFAPI_DEBUG_BACKTRACE_NENTRIES; ++i) { +		vnc_zlog_debug_verbose("backtrace[%2zu]: %s", i, syms[i]); +	} -  free (syms); +	free(syms);  #else  #endif  } @@ -125,89 +122,80 @@ rfapiDebugBacktrace (void)   * Count remote routes and compare with actively-maintained values.   * Abort if they disagree.   */ -void -rfapiCheckRouteCount () +void rfapiCheckRouteCount()  { -  struct bgp *bgp = bgp_get_default (); -  struct rfapi *h; -  struct rfapi_import_table *it; -  afi_t afi; - -  assert (bgp); - -  h = bgp->rfapi; -  assert (h); - -  for (it = h->imports; it; it = it->next) -    { -      for (afi = AFI_IP; afi < AFI_MAX; ++afi) -        { - -          struct route_table *rt; -          struct route_node *rn; - -          int holddown_count = 0; -          int local_count = 0; -          int imported_count = 0; -          int remote_count = 0; - -          rt = it->imported_vpn[afi]; - -          for (rn = route_top (rt); rn; rn = route_next (rn)) -            { -              struct bgp_info *bi; -              struct bgp_info *next; - -              for (bi = rn->info; bi; bi = next) -                { -                  next = bi->next; - -                  if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) -                    { -                      ++holddown_count; - -                    } -                  else -                    { -                      if (RFAPI_LOCAL_BI (bi)) -                        { -                          ++local_count; -                        } -                      else -                        { -                          if (RFAPI_DIRECT_IMPORT_BI (bi)) -                            { -                              ++imported_count; -                            } -                          else -                            { -                              ++remote_count; -                            } -                        } -                    } -                } -            } - -          if (it->holddown_count[afi] != holddown_count) -            { -              vnc_zlog_debug_verbose ("%s: it->holddown_count %d != holddown_count %d", -                          __func__, it->holddown_count[afi], holddown_count); -              assert (0); -            } -          if (it->remote_count[afi] != remote_count) -            { -              vnc_zlog_debug_verbose ("%s: it->remote_count %d != remote_count %d", -                          __func__, it->remote_count[afi], remote_count); -              assert (0); -            } -          if (it->imported_count[afi] != imported_count) -            { -              vnc_zlog_debug_verbose ("%s: it->imported_count %d != imported_count %d", -                          __func__, it->imported_count[afi], imported_count); -              assert (0); -            } -        } -    } +	struct bgp *bgp = bgp_get_default(); +	struct rfapi *h; +	struct rfapi_import_table *it; +	afi_t afi; + +	assert(bgp); + +	h = bgp->rfapi; +	assert(h); + +	for (it = h->imports; it; it = it->next) { +		for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + +			struct route_table *rt; +			struct route_node *rn; + +			int holddown_count = 0; +			int local_count = 0; +			int imported_count = 0; +			int remote_count = 0; + +			rt = it->imported_vpn[afi]; + +			for (rn = route_top(rt); rn; rn = route_next(rn)) { +				struct bgp_info *bi; +				struct bgp_info *next; + +				for (bi = rn->info; bi; bi = next) { +					next = bi->next; + +					if (CHECK_FLAG(bi->flags, +						       BGP_INFO_REMOVED)) { +						++holddown_count; + +					} else { +						if (RFAPI_LOCAL_BI(bi)) { +							++local_count; +						} else { +							if (RFAPI_DIRECT_IMPORT_BI( +								    bi)) { +								++imported_count; +							} else { +								++remote_count; +							} +						} +					} +				} +			} + +			if (it->holddown_count[afi] != holddown_count) { +				vnc_zlog_debug_verbose( +					"%s: it->holddown_count %d != holddown_count %d", +					__func__, it->holddown_count[afi], +					holddown_count); +				assert(0); +			} +			if (it->remote_count[afi] != remote_count) { +				vnc_zlog_debug_verbose( +					"%s: it->remote_count %d != remote_count %d", +					__func__, it->remote_count[afi], +					remote_count); +				assert(0); +			} +			if (it->imported_count[afi] != imported_count) { +				vnc_zlog_debug_verbose( +					"%s: it->imported_count %d != imported_count %d", +					__func__, it->imported_count[afi], +					imported_count); +				assert(0); +			} +		} +	}  }  #if DEBUG_ROUTE_COUNTERS @@ -224,825 +212,777 @@ rfapiCheckRouteCount ()   * node->lock == 1, and we have to validate the refcount before   * the node is deleted. In this case, we specify lockoffset 1.   */ -void -rfapiCheckRefcount (struct route_node *rn, safi_t safi, int lockoffset) +void rfapiCheckRefcount(struct route_node *rn, safi_t safi, int lockoffset)  { -  unsigned int count_bi = 0; -  unsigned int count_monitor = 0; -  struct bgp_info *bi; -  struct rfapi_monitor_encap *hme; -  struct rfapi_monitor_vpn *hmv; - -  for (bi = rn->info; bi; bi = bi->next) -    ++count_bi; - - -  if (rn->aggregate) -    { -      ++count_monitor;          /* rfapi_it_extra */ - -      switch (safi) -        { -          void *cursor; -          int rc; - -        case SAFI_ENCAP: -          for (hme = RFAPI_MONITOR_ENCAP (rn); hme; hme = hme->next) -            ++count_monitor; -          break; - -        case SAFI_MPLS_VPN: - -          for (hmv = RFAPI_MONITOR_VPN (rn); hmv; hmv = hmv->next) -            ++count_monitor; - -          if (RFAPI_MONITOR_EXTERIOR (rn)->source) -            { -              ++count_monitor;  /* sl */ -              cursor = NULL; -              for (rc = skiplist_next (RFAPI_MONITOR_EXTERIOR (rn)->source, -                                       NULL, NULL, &cursor); -                   !rc; -                   rc = skiplist_next (RFAPI_MONITOR_EXTERIOR (rn)->source, -                                       NULL, NULL, &cursor)) -                { - -                  ++count_monitor;      /* sl entry */ -                } -            } -          break; - -        default: -          assert (0); -        } -    } - -  if (count_bi + count_monitor + lockoffset != rn->lock) -    { -      vnc_zlog_debug_verbose -        ("%s: count_bi=%d, count_monitor=%d, lockoffset=%d, rn->lock=%d", -         __func__, count_bi, count_monitor, lockoffset, rn->lock); -      assert (0); -    } +	unsigned int count_bi = 0; +	unsigned int count_monitor = 0; +	struct bgp_info *bi; +	struct rfapi_monitor_encap *hme; +	struct rfapi_monitor_vpn *hmv; + +	for (bi = rn->info; bi; bi = bi->next) +		++count_bi; + + +	if (rn->aggregate) { +		++count_monitor; /* rfapi_it_extra */ + +		switch (safi) { +			void *cursor; +			int rc; + +		case SAFI_ENCAP: +			for (hme = RFAPI_MONITOR_ENCAP(rn); hme; +			     hme = hme->next) +				++count_monitor; +			break; + +		case SAFI_MPLS_VPN: + +			for (hmv = RFAPI_MONITOR_VPN(rn); hmv; hmv = hmv->next) +				++count_monitor; + +			if (RFAPI_MONITOR_EXTERIOR(rn)->source) { +				++count_monitor; /* sl */ +				cursor = NULL; +				for (rc = skiplist_next( +					     RFAPI_MONITOR_EXTERIOR(rn)->source, +					     NULL, NULL, &cursor); +				     !rc; +				     rc = skiplist_next( +					     RFAPI_MONITOR_EXTERIOR(rn)->source, +					     NULL, NULL, &cursor)) { + +					++count_monitor; /* sl entry */ +				} +			} +			break; + +		default: +			assert(0); +		} +	} + +	if (count_bi + count_monitor + lockoffset != rn->lock) { +		vnc_zlog_debug_verbose( +			"%s: count_bi=%d, count_monitor=%d, lockoffset=%d, rn->lock=%d", +			__func__, count_bi, count_monitor, lockoffset, +			rn->lock); +		assert(0); +	}  }  /*   * Perform deferred rfapi_close operations that were queued   * during callbacks.   */ -static wq_item_status -rfapi_deferred_close_workfunc (struct work_queue *q, void *data) +static wq_item_status rfapi_deferred_close_workfunc(struct work_queue *q, +						    void *data)  { -  struct rfapi_descriptor *rfd = data; -  struct rfapi *h = q->spec.data; - -  assert (!(h->flags & RFAPI_INCALLBACK)); -  rfapi_close (rfd); -  vnc_zlog_debug_verbose ("%s: completed deferred close on handle %p", __func__, rfd); -  return WQ_SUCCESS; +	struct rfapi_descriptor *rfd = data; +	struct rfapi *h = q->spec.data; + +	assert(!(h->flags & RFAPI_INCALLBACK)); +	rfapi_close(rfd); +	vnc_zlog_debug_verbose("%s: completed deferred close on handle %p", +			       __func__, rfd); +	return WQ_SUCCESS;  }  /*   * Extract layer 2 option from Encap TLVS in BGP attrs   */ -int -rfapiGetL2o (struct attr *attr, struct rfapi_l2address_option *l2o) +int rfapiGetL2o(struct attr *attr, struct rfapi_l2address_option *l2o)  { -  if (attr) -    { - -      struct bgp_attr_encap_subtlv *pEncap; - -      for (pEncap = attr->vnc_subtlvs; pEncap; pEncap = pEncap->next) -        { - -          if (pEncap->type == BGP_VNC_SUBTLV_TYPE_RFPOPTION) -            { -              if (pEncap->value[0] == RFAPI_VN_OPTION_TYPE_L2ADDR) -                { - -                  if (pEncap->value[1] == 14) -                    { -                      memcpy (l2o->macaddr.octet, pEncap->value + 2, -                              ETHER_ADDR_LEN); -                      l2o->label = -                        ((pEncap->value[10] >> 4) & 0x0f) + -                        ((pEncap->value[9] << 4) & 0xff0) + -                        ((pEncap->value[8] << 12) & 0xff000); - -                      l2o->local_nve_id = pEncap->value[12]; - -                      l2o->logical_net_id = -                        (pEncap->value[15] & 0xff) + -                        ((pEncap->value[14] << 8) & 0xff00) + -                        ((pEncap->value[13] << 16) & 0xff0000); -                    } - -                  return 0; -                } -            } -        } -    } - -  return ENOENT; +	if (attr) { + +		struct bgp_attr_encap_subtlv *pEncap; + +		for (pEncap = attr->vnc_subtlvs; pEncap; +		     pEncap = pEncap->next) { + +			if (pEncap->type == BGP_VNC_SUBTLV_TYPE_RFPOPTION) { +				if (pEncap->value[0] +				    == RFAPI_VN_OPTION_TYPE_L2ADDR) { + +					if (pEncap->value[1] == 14) { +						memcpy(l2o->macaddr.octet, +						       pEncap->value + 2, +						       ETHER_ADDR_LEN); +						l2o->label = +							((pEncap->value[10] +							  >> 4) +							 & 0x0f) +							+ ((pEncap->value[9] +							    << 4) +							   & 0xff0) +							+ ((pEncap->value[8] +							    << 12) +							   & 0xff000); + +						l2o->local_nve_id = +							pEncap->value[12]; + +						l2o->logical_net_id = +							(pEncap->value[15] +							 & 0xff) +							+ ((pEncap->value[14] +							    << 8) +							   & 0xff00) +							+ ((pEncap->value[13] +							    << 16) +							   & 0xff0000); +					} + +					return 0; +				} +			} +		} +	} + +	return ENOENT;  }  /*   * Extract the lifetime from the Tunnel Encap attribute of a route in   * an import table   */ -int -rfapiGetVncLifetime (struct attr *attr, uint32_t * lifetime) +int rfapiGetVncLifetime(struct attr *attr, uint32_t *lifetime)  { -  struct bgp_attr_encap_subtlv *pEncap; +	struct bgp_attr_encap_subtlv *pEncap; -  *lifetime = RFAPI_INFINITE_LIFETIME;        /* default to infinite */ +	*lifetime = RFAPI_INFINITE_LIFETIME; /* default to infinite */ -  if (attr) -    { +	if (attr) { -      for (pEncap = attr->vnc_subtlvs; pEncap; pEncap = pEncap->next) -        { +		for (pEncap = attr->vnc_subtlvs; pEncap; +		     pEncap = pEncap->next) { -          if (pEncap->type == BGP_VNC_SUBTLV_TYPE_LIFETIME) -            {                   /* lifetime */ -              if (pEncap->length == 4) -                { -                  memcpy (lifetime, pEncap->value, 4); -                  *lifetime = ntohl (*lifetime); -                  return 0; -                } -            } -        } -    } +			if (pEncap->type +			    == BGP_VNC_SUBTLV_TYPE_LIFETIME) { /* lifetime */ +				if (pEncap->length == 4) { +					memcpy(lifetime, pEncap->value, 4); +					*lifetime = ntohl(*lifetime); +					return 0; +				} +			} +		} +	} -  return ENOENT; +	return ENOENT;  }  /*   * Extract the tunnel type from the extended community   */ -int -rfapiGetTunnelType (struct attr     *attr,  -                    bgp_encap_types *type) +int rfapiGetTunnelType(struct attr *attr, bgp_encap_types *type)  { -  *type = BGP_ENCAP_TYPE_MPLS;  /* default to MPLS */ -  if (attr && attr->ecommunity) -    { -      struct ecommunity *ecom = attr->ecommunity; -      int i; - -      for (i = 0; i < (ecom->size * ECOMMUNITY_SIZE); i += ECOMMUNITY_SIZE) -        { -          uint8_t *ep; - -          ep = ecom->val + i; -          if (ep[0] == ECOMMUNITY_ENCODE_OPAQUE && -              ep[1] == ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP) -            { -              *type = (ep[6]<<8) + ep[7]; -              return 0; -            } -        } -    } - -  return ENOENT; +	*type = BGP_ENCAP_TYPE_MPLS; /* default to MPLS */ +	if (attr && attr->ecommunity) { +		struct ecommunity *ecom = attr->ecommunity; +		int i; + +		for (i = 0; i < (ecom->size * ECOMMUNITY_SIZE); +		     i += ECOMMUNITY_SIZE) { +			uint8_t *ep; + +			ep = ecom->val + i; +			if (ep[0] == ECOMMUNITY_ENCODE_OPAQUE +			    && ep[1] == ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP) { +				*type = (ep[6] << 8) + ep[7]; +				return 0; +			} +		} +	} + +	return ENOENT;  }  /*   * Look for UN address in Encap attribute   */ -int -rfapiGetVncTunnelUnAddr (struct attr *attr, struct prefix *p) +int rfapiGetVncTunnelUnAddr(struct attr *attr, struct prefix *p)  { -  struct bgp_attr_encap_subtlv *pEncap; -  bgp_encap_types               tun_type; -   -  rfapiGetTunnelType (attr, &tun_type); -  if (tun_type == BGP_ENCAP_TYPE_MPLS)  -    { -      if (!p) -        return 0; -      /* MPLS carries UN address in next hop */ -      rfapiNexthop2Prefix (attr, p); -      if (p->family != 0) -        return 0; - -      return ENOENT; -    } -  if (attr) -    { -      for (pEncap = attr->encap_subtlvs; pEncap; pEncap = pEncap->next) -        { - -          if (pEncap->type == BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT) -            {                   /* un addr */ -              switch (pEncap->length) -                { -                case 8: -                  if (p) -                    { -                      p->family = AF_INET; -                      p->prefixlen = 32; -                      memcpy (p->u.val, pEncap->value, 4); -                    } -                  return 0; - -                case 20: -                  if (p) -                    { -                      p->family = AF_INET6; -                      p->prefixlen = 128; -                      memcpy (p->u.val, pEncap->value, 16); -                    } -                  return 0; -                } -            } -        } -    } - -  return ENOENT; +	struct bgp_attr_encap_subtlv *pEncap; +	bgp_encap_types tun_type; + +	rfapiGetTunnelType(attr, &tun_type); +	if (tun_type == BGP_ENCAP_TYPE_MPLS) { +		if (!p) +			return 0; +		/* MPLS carries UN address in next hop */ +		rfapiNexthop2Prefix(attr, p); +		if (p->family != 0) +			return 0; + +		return ENOENT; +	} +	if (attr) { +		for (pEncap = attr->encap_subtlvs; pEncap; +		     pEncap = pEncap->next) { + +			if (pEncap->type +			    == BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT) { /* un +									   addr +									   */ +				switch (pEncap->length) { +				case 8: +					if (p) { +						p->family = AF_INET; +						p->prefixlen = 32; +						memcpy(p->u.val, pEncap->value, +						       4); +					} +					return 0; + +				case 20: +					if (p) { +						p->family = AF_INET6; +						p->prefixlen = 128; +						memcpy(p->u.val, pEncap->value, +						       16); +					} +					return 0; +				} +			} +		} +	} + +	return ENOENT;  }  /*   * Get UN address wherever it might be   */ -int -rfapiGetUnAddrOfVpnBi (struct bgp_info *bi, struct prefix *p) +int rfapiGetUnAddrOfVpnBi(struct bgp_info *bi, struct prefix *p)  { -  /* If it's in this route's VNC attribute, we're done */ -  if (!rfapiGetVncTunnelUnAddr (bi->attr, p)) -    return 0; -  /* -   * Otherwise, see if it's cached from a corresponding ENCAP SAFI -   * advertisement -   */ -  if (bi->extra) -    { -      switch (bi->extra->vnc.import.un_family) -        { -        case AF_INET: -          if (p) -            { -              p->family = bi->extra->vnc.import.un_family; -              p->u.prefix4 = bi->extra->vnc.import.un.addr4; -              p->prefixlen = 32; -            } -          return 0; -        case AF_INET6: -          if (p) -            { -              p->family = bi->extra->vnc.import.un_family; -              p->u.prefix6 = bi->extra->vnc.import.un.addr6; -              p->prefixlen = 128; -            } -          return 0; -        default: -          if (p) -            p->family = 0; +	/* If it's in this route's VNC attribute, we're done */ +	if (!rfapiGetVncTunnelUnAddr(bi->attr, p)) +		return 0; +	/* +	 * Otherwise, see if it's cached from a corresponding ENCAP SAFI +	 * advertisement +	 */ +	if (bi->extra) { +		switch (bi->extra->vnc.import.un_family) { +		case AF_INET: +			if (p) { +				p->family = bi->extra->vnc.import.un_family; +				p->u.prefix4 = bi->extra->vnc.import.un.addr4; +				p->prefixlen = 32; +			} +			return 0; +		case AF_INET6: +			if (p) { +				p->family = bi->extra->vnc.import.un_family; +				p->u.prefix6 = bi->extra->vnc.import.un.addr6; +				p->prefixlen = 128; +			} +			return 0; +		default: +			if (p) +				p->family = 0;  #if DEBUG_ENCAP_MONITOR -          vnc_zlog_debug_verbose ("%s: bi->extra->vnc.import.un_family is 0, no UN addr", -                      __func__); +			vnc_zlog_debug_verbose( +				"%s: bi->extra->vnc.import.un_family is 0, no UN addr", +				__func__);  #endif -          break; -        } -    } +			break; +		} +	} -  return ENOENT; +	return ENOENT;  }  /*   * Make a new bgp_info from gathered parameters   */ -static struct bgp_info * -rfapiBgpInfoCreate ( -  struct attr		*attr, -  struct peer		*peer, -  void			*rfd, -  struct prefix_rd	*prd, -  u_char		type, -  u_char		sub_type, -  uint32_t		*label) +static struct bgp_info *rfapiBgpInfoCreate(struct attr *attr, struct peer *peer, +					   void *rfd, struct prefix_rd *prd, +					   u_char type, u_char sub_type, +					   uint32_t *label)  { -  struct bgp_info *new; - -  new = bgp_info_new (); -  assert (new); - -  if (attr) -    { -      if (!new->attr) -        new->attr = bgp_attr_intern (attr); -    } -  bgp_info_extra_get (new); -  if (prd) -    { -      new->extra->vnc.import.rd = *prd; -      rfapi_time (&new->extra->vnc.import.create_time); -    } -  if (label) -    encode_label (*label, &new->extra->label); -  new->type = type; -  new->sub_type = sub_type; -  new->peer = peer; -  peer_lock (peer); - -  return new; +	struct bgp_info *new; + +	new = bgp_info_new(); +	assert(new); + +	if (attr) { +		if (!new->attr) +			new->attr = bgp_attr_intern(attr); +	} +	bgp_info_extra_get(new); +	if (prd) { +		new->extra->vnc.import.rd = *prd; +		rfapi_time(&new->extra->vnc.import.create_time); +	} +	if (label) +		encode_label(*label, &new->extra->label); +	new->type = type; +	new->sub_type = sub_type; +	new->peer = peer; +	peer_lock(peer); + +	return new;  }  /*   * Frees bgp_info as used in import tables (parts are not   * allocated exactly the way they are in the main RIBs)   */ -static void -rfapiBgpInfoFree (struct bgp_info *goner) +static void rfapiBgpInfoFree(struct bgp_info *goner)  { -  if (!goner) -    return; - -  if (goner->peer) -    { -      vnc_zlog_debug_verbose ("%s: calling peer_unlock(%p), #%d", -                  __func__, goner->peer, goner->peer->lock); -      peer_unlock (goner->peer); -    } - -  if (goner->attr) -    { -      bgp_attr_unintern (&goner->attr); -    } -  if (goner->extra) -    { -      assert (!goner->extra->damp_info);        /* Not used in import tbls */ -      XFREE (MTYPE_BGP_ROUTE_EXTRA, goner->extra); -      goner->extra = NULL; -    } -  XFREE (MTYPE_BGP_ROUTE, goner); +	if (!goner) +		return; + +	if (goner->peer) { +		vnc_zlog_debug_verbose("%s: calling peer_unlock(%p), #%d", +				       __func__, goner->peer, +				       goner->peer->lock); +		peer_unlock(goner->peer); +	} + +	if (goner->attr) { +		bgp_attr_unintern(&goner->attr); +	} +	if (goner->extra) { +		assert(!goner->extra->damp_info); /* Not used in import tbls */ +		XFREE(MTYPE_BGP_ROUTE_EXTRA, goner->extra); +		goner->extra = NULL; +	} +	XFREE(MTYPE_BGP_ROUTE, goner);  } -struct rfapi_import_table * -rfapiMacImportTableGetNoAlloc (struct bgp *bgp, uint32_t lni) +struct rfapi_import_table *rfapiMacImportTableGetNoAlloc(struct bgp *bgp, +							 uint32_t lni)  { -  struct rfapi *h; -  struct rfapi_import_table *it = NULL; -  uintptr_t lni_as_ptr = lni; +	struct rfapi *h; +	struct rfapi_import_table *it = NULL; +	uintptr_t lni_as_ptr = lni; -  h = bgp->rfapi; -  if (!h) -    return NULL; +	h = bgp->rfapi; +	if (!h) +		return NULL; -  if (!h->import_mac) -    return NULL; +	if (!h->import_mac) +		return NULL; -  if (skiplist_search (h->import_mac, (void *) lni_as_ptr, (void **) &it)) -    return NULL; +	if (skiplist_search(h->import_mac, (void *)lni_as_ptr, (void **)&it)) +		return NULL; -  return it; +	return it;  } -struct rfapi_import_table * -rfapiMacImportTableGet (struct bgp *bgp, uint32_t lni) +struct rfapi_import_table *rfapiMacImportTableGet(struct bgp *bgp, uint32_t lni)  { -  struct rfapi *h; -  struct rfapi_import_table *it = NULL; -  uintptr_t lni_as_ptr = lni; - -  h = bgp->rfapi; -  assert (h); - -  if (!h->import_mac) -    { -      /* default cmp is good enough for LNI */ -      h->import_mac = skiplist_new (0, NULL, NULL); -    } - -  if (skiplist_search (h->import_mac, (void *) lni_as_ptr, (void **) &it)) -    { - -      struct ecommunity *enew; -      struct ecommunity_val eval; -      afi_t afi; - -      it = -        XCALLOC (MTYPE_RFAPI_IMPORTTABLE, sizeof (struct rfapi_import_table)); -      /* set RT list of new import table based on LNI */ -      memset ((char *) &eval, 0, sizeof (eval)); -      eval.val[0] = 0;          /* VNC L2VPN */ -      eval.val[1] = 2;          /* VNC L2VPN */ -      eval.val[5] = (lni >> 16) & 0xff; -      eval.val[6] = (lni >> 8) & 0xff; -      eval.val[7] = (lni >> 0) & 0xff; - -      enew = ecommunity_new (); -      ecommunity_add_val (enew, &eval); -      it->rt_import_list = enew; - -      for (afi = AFI_IP; afi < AFI_MAX; ++afi) -        { -          it->imported_vpn[afi] = route_table_init (); -          it->imported_encap[afi] = route_table_init (); -        } - -      it->l2_logical_net_id = lni; - -      skiplist_insert (h->import_mac, (void *) lni_as_ptr, it); -    } - -  assert (it); -  return it; +	struct rfapi *h; +	struct rfapi_import_table *it = NULL; +	uintptr_t lni_as_ptr = lni; + +	h = bgp->rfapi; +	assert(h); + +	if (!h->import_mac) { +		/* default cmp is good enough for LNI */ +		h->import_mac = skiplist_new(0, NULL, NULL); +	} + +	if (skiplist_search(h->import_mac, (void *)lni_as_ptr, (void **)&it)) { + +		struct ecommunity *enew; +		struct ecommunity_val eval; +		afi_t afi; + +		it = XCALLOC(MTYPE_RFAPI_IMPORTTABLE, +			     sizeof(struct rfapi_import_table)); +		/* set RT list of new import table based on LNI */ +		memset((char *)&eval, 0, sizeof(eval)); +		eval.val[0] = 0; /* VNC L2VPN */ +		eval.val[1] = 2; /* VNC L2VPN */ +		eval.val[5] = (lni >> 16) & 0xff; +		eval.val[6] = (lni >> 8) & 0xff; +		eval.val[7] = (lni >> 0) & 0xff; + +		enew = ecommunity_new(); +		ecommunity_add_val(enew, &eval); +		it->rt_import_list = enew; + +		for (afi = AFI_IP; afi < AFI_MAX; ++afi) { +			it->imported_vpn[afi] = route_table_init(); +			it->imported_encap[afi] = route_table_init(); +		} + +		it->l2_logical_net_id = lni; + +		skiplist_insert(h->import_mac, (void *)lni_as_ptr, it); +	} + +	assert(it); +	return it;  }  /*   * Implement MONITOR_MOVE_SHORTER(original_node) from   * RFAPI-Import-Event-Handling.txt - *  + *   * Returns pointer to the list of moved monitors   */  static struct rfapi_monitor_vpn * -rfapiMonitorMoveShorter (struct route_node *original_vpn_node, int lockoffset) +rfapiMonitorMoveShorter(struct route_node *original_vpn_node, int lockoffset)  { -  struct bgp_info *bi; -  struct route_node *par; -  struct rfapi_monitor_vpn *m; -  struct rfapi_monitor_vpn *mlast; -  struct rfapi_monitor_vpn *moved; -  int movecount = 0; -  int parent_already_refcounted = 0; +	struct bgp_info *bi; +	struct route_node *par; +	struct rfapi_monitor_vpn *m; +	struct rfapi_monitor_vpn *mlast; +	struct rfapi_monitor_vpn *moved; +	int movecount = 0; +	int parent_already_refcounted = 0; -  RFAPI_CHECK_REFCOUNT (original_vpn_node, SAFI_MPLS_VPN, lockoffset); +	RFAPI_CHECK_REFCOUNT(original_vpn_node, SAFI_MPLS_VPN, lockoffset);  #if DEBUG_MONITOR_MOVE_SHORTER -  { -    char buf[BUFSIZ]; +	{ +		char buf[BUFSIZ]; -    prefix2str (&original_vpn_node->p, buf, BUFSIZ); -    buf[BUFSIZ - 1] = 0; -    vnc_zlog_debug_verbose ("%s: called with node pfx=%s", __func__, buf); -  } +		prefix2str(&original_vpn_node->p, buf, BUFSIZ); +		buf[BUFSIZ - 1] = 0; +		vnc_zlog_debug_verbose("%s: called with node pfx=%s", __func__, +				       buf); +	}  #endif -  /* -   * 1. If there is at least one bi (either regular route or -   *    route marked as withdrawn, with a pending timer) at -   *    original_node with a valid UN address, we're done. Return. -   */ -  for (bi = original_vpn_node->info; bi; bi = bi->next) -    { -      struct prefix pfx; - -      if (!rfapiGetUnAddrOfVpnBi (bi, &pfx)) -        { +	/* +	 * 1. If there is at least one bi (either regular route or +	 *    route marked as withdrawn, with a pending timer) at +	 *    original_node with a valid UN address, we're done. Return. +	 */ +	for (bi = original_vpn_node->info; bi; bi = bi->next) { +		struct prefix pfx; + +		if (!rfapiGetUnAddrOfVpnBi(bi, &pfx)) {  #if DEBUG_MONITOR_MOVE_SHORTER -          vnc_zlog_debug_verbose ("%s: have valid UN at original node, no change", -                      __func__); +			vnc_zlog_debug_verbose( +				"%s: have valid UN at original node, no change", +				__func__);  #endif -          return NULL; -        } -    } - -  /* -   * 2. Travel up the tree (toward less-specific prefixes) from -   *    original_node to find the first node that has at least -   *    one route (even if it is only a withdrawn route) with a -   *    valid UN address. Call this node "Node P." -   */ -  for (par = original_vpn_node->parent; par; par = par->parent) -    { -      for (bi = par->info; bi; bi = bi->next) -        { -          struct prefix pfx; -          if (!rfapiGetUnAddrOfVpnBi (bi, &pfx)) -            { -              break; -            } -        } -      if (bi) -        break; -    } - -  if (par) -    { -      RFAPI_CHECK_REFCOUNT (par, SAFI_MPLS_VPN, 0); -    } - -  /* -   * If no less-specific routes, try to use the 0/0 node -   */ -  if (!par) -    { -      /* this isn't necessarily 0/0 */ -      par = route_top (original_vpn_node->table); - -      /* -       * If we got the top node but it wasn't 0/0, -       * ignore it -       */ -      if (par && par->p.prefixlen) -        { -          route_unlock_node (par);      /* maybe free */ -          par = NULL; -        } - -      if (par) -        { -          ++parent_already_refcounted; -        } -    } - -  /*  -   * Create 0/0 node if it isn't there -   */ -  if (!par) -    { -      struct prefix pfx_default; - -      memset (&pfx_default, 0, sizeof (pfx_default)); -      pfx_default.family = original_vpn_node->p.family; - -      /* creates default node if none exists */ -      par = route_node_get (original_vpn_node->table, &pfx_default); -      ++parent_already_refcounted; -    } - -  /* -   * 3. Move each of the monitors found at original_node to Node P. -   *    These are "Moved Monitors." -   * -   */ - -  /* -   * Attach at end so that the list pointer we return points -   * only to the moved routes -   */ -  for (m = RFAPI_MONITOR_VPN (par), mlast = NULL; m; mlast = m, m = m->next); - -  if (mlast) -    { -      moved = mlast->next = RFAPI_MONITOR_VPN (original_vpn_node); -    } -  else -    { -      moved = RFAPI_MONITOR_VPN_W_ALLOC (par) = -        RFAPI_MONITOR_VPN (original_vpn_node); -    } -  if (RFAPI_MONITOR_VPN (original_vpn_node))    /* check agg, so not allocated */ -    RFAPI_MONITOR_VPN_W_ALLOC (original_vpn_node) = NULL; - -  /* -   * update the node pointers on the monitors -   */ -  for (m = moved; m; m = m->next) -    { -      ++movecount; -      m->node = par; -    } - -  RFAPI_CHECK_REFCOUNT (par, SAFI_MPLS_VPN, -                        parent_already_refcounted - movecount); -  while (movecount > parent_already_refcounted) -    { -      route_lock_node (par); -      ++parent_already_refcounted; -    } -  while (movecount < parent_already_refcounted) -    { -      /* unlikely, but code defensively */ -      route_unlock_node (par); -      --parent_already_refcounted; -    } -  RFAPI_CHECK_REFCOUNT (original_vpn_node, SAFI_MPLS_VPN, -                        movecount + lockoffset); -  while (movecount--) -    { -      route_unlock_node (original_vpn_node); -    } +			return NULL; +		} +	} + +	/* +	 * 2. Travel up the tree (toward less-specific prefixes) from +	 *    original_node to find the first node that has at least +	 *    one route (even if it is only a withdrawn route) with a +	 *    valid UN address. Call this node "Node P." +	 */ +	for (par = original_vpn_node->parent; par; par = par->parent) { +		for (bi = par->info; bi; bi = bi->next) { +			struct prefix pfx; +			if (!rfapiGetUnAddrOfVpnBi(bi, &pfx)) { +				break; +			} +		} +		if (bi) +			break; +	} + +	if (par) { +		RFAPI_CHECK_REFCOUNT(par, SAFI_MPLS_VPN, 0); +	} + +	/* +	 * If no less-specific routes, try to use the 0/0 node +	 */ +	if (!par) { +		/* this isn't necessarily 0/0 */ +		par = route_top(original_vpn_node->table); + +		/* +		 * If we got the top node but it wasn't 0/0, +		 * ignore it +		 */ +		if (par && par->p.prefixlen) { +			route_unlock_node(par); /* maybe free */ +			par = NULL; +		} + +		if (par) { +			++parent_already_refcounted; +		} +	} + +	/* +	 * Create 0/0 node if it isn't there +	 */ +	if (!par) { +		struct prefix pfx_default; + +		memset(&pfx_default, 0, sizeof(pfx_default)); +		pfx_default.family = original_vpn_node->p.family; + +		/* creates default node if none exists */ +		par = route_node_get(original_vpn_node->table, &pfx_default); +		++parent_already_refcounted; +	} + +	/* +	 * 3. Move each of the monitors found at original_node to Node P. +	 *    These are "Moved Monitors." +	 * +	 */ + +	/* +	 * Attach at end so that the list pointer we return points +	 * only to the moved routes +	 */ +	for (m = RFAPI_MONITOR_VPN(par), mlast = NULL; m; +	     mlast = m, m = m->next) +		; + +	if (mlast) { +		moved = mlast->next = RFAPI_MONITOR_VPN(original_vpn_node); +	} else { +		moved = RFAPI_MONITOR_VPN_W_ALLOC(par) = +			RFAPI_MONITOR_VPN(original_vpn_node); +	} +	if (RFAPI_MONITOR_VPN( +		    original_vpn_node)) /* check agg, so not allocated */ +		RFAPI_MONITOR_VPN_W_ALLOC(original_vpn_node) = NULL; + +	/* +	 * update the node pointers on the monitors +	 */ +	for (m = moved; m; m = m->next) { +		++movecount; +		m->node = par; +	} + +	RFAPI_CHECK_REFCOUNT(par, SAFI_MPLS_VPN, +			     parent_already_refcounted - movecount); +	while (movecount > parent_already_refcounted) { +		route_lock_node(par); +		++parent_already_refcounted; +	} +	while (movecount < parent_already_refcounted) { +		/* unlikely, but code defensively */ +		route_unlock_node(par); +		--parent_already_refcounted; +	} +	RFAPI_CHECK_REFCOUNT(original_vpn_node, SAFI_MPLS_VPN, +			     movecount + lockoffset); +	while (movecount--) { +		route_unlock_node(original_vpn_node); +	}  #if DEBUG_MONITOR_MOVE_SHORTER -  { -    char buf[BUFSIZ]; +	{ +		char buf[BUFSIZ]; -    prefix2str (&par->p, buf, BUFSIZ); -    buf[BUFSIZ - 1] = 0; -    vnc_zlog_debug_verbose ("%s: moved to node pfx=%s", __func__, buf); -  } +		prefix2str(&par->p, buf, BUFSIZ); +		buf[BUFSIZ - 1] = 0; +		vnc_zlog_debug_verbose("%s: moved to node pfx=%s", __func__, +				       buf); +	}  #endif -  return moved; +	return moved;  }  /*   * Implement MONITOR_MOVE_LONGER(new_node) from   * RFAPI-Import-Event-Handling.txt   */ -static void -rfapiMonitorMoveLonger (struct route_node *new_vpn_node) +static void rfapiMonitorMoveLonger(struct route_node *new_vpn_node)  { -  struct rfapi_monitor_vpn *monitor; -  struct rfapi_monitor_vpn *mlast; -  struct bgp_info *bi; -  struct route_node *par; - -  RFAPI_CHECK_REFCOUNT (new_vpn_node, SAFI_MPLS_VPN, 0); - -  /* -   * Make sure we have at least one valid route at the new node -   */ -  for (bi = new_vpn_node->info; bi; bi = bi->next) -    { -      struct prefix pfx; -      if (!rfapiGetUnAddrOfVpnBi (bi, &pfx)) -        break; -    } - -  if (!bi) -    { -      vnc_zlog_debug_verbose ("%s: no valid routes at node %p, so not attempting moves", -                  __func__, new_vpn_node); -      return; -    } - -  /* -   * Find first parent node that has monitors -   */ -  for (par = new_vpn_node->parent; par; par = par->parent) -    { -      if (RFAPI_MONITOR_VPN (par)) -        break; -    } - -  if (!par) -    { -      vnc_zlog_debug_verbose ("%s: no parent nodes with monitors, done", __func__); -      return; -    } - -  /* -   * Check each of these monitors to see of their longest-match -   * is now the updated node. Move any such monitors to the more- -   * specific updated node -   */ -  for (mlast = NULL, monitor = RFAPI_MONITOR_VPN (par); monitor;) -    { - -      /* -       * If new longest match for monitor prefix is the new -       * route's prefix, move monitor to new route's prefix -       */ -      if (prefix_match (&new_vpn_node->p, &monitor->p)) -        { -          /* detach */ -          if (mlast) -            { -              mlast->next = monitor->next; -            } -          else -            { -              RFAPI_MONITOR_VPN_W_ALLOC (par) = monitor->next; -            } - - -          /* attach */ -          monitor->next = RFAPI_MONITOR_VPN (new_vpn_node); -          RFAPI_MONITOR_VPN_W_ALLOC (new_vpn_node) = monitor; -          monitor->node = new_vpn_node; - -          route_lock_node (new_vpn_node);       /* incr refcount */ - -          monitor = mlast ? mlast->next : RFAPI_MONITOR_VPN (par); - -          RFAPI_CHECK_REFCOUNT (par, SAFI_MPLS_VPN, 1); -          /* decr refcount after we're done with par as this might free it */ -          route_unlock_node (par); - -          continue; -        } -      mlast = monitor; -      monitor = monitor->next; -    } - -  RFAPI_CHECK_REFCOUNT (new_vpn_node, SAFI_MPLS_VPN, 0); +	struct rfapi_monitor_vpn *monitor; +	struct rfapi_monitor_vpn *mlast; +	struct bgp_info *bi; +	struct route_node *par; + +	RFAPI_CHECK_REFCOUNT(new_vpn_node, SAFI_MPLS_VPN, 0); + +	/* +	 * Make sure we have at least one valid route at the new node +	 */ +	for (bi = new_vpn_node->info; bi; bi = bi->next) { +		struct prefix pfx; +		if (!rfapiGetUnAddrOfVpnBi(bi, &pfx)) +			break; +	} + +	if (!bi) { +		vnc_zlog_debug_verbose( +			"%s: no valid routes at node %p, so not attempting moves", +			__func__, new_vpn_node); +		return; +	} + +	/* +	 * Find first parent node that has monitors +	 */ +	for (par = new_vpn_node->parent; par; par = par->parent) { +		if (RFAPI_MONITOR_VPN(par)) +			break; +	} + +	if (!par) { +		vnc_zlog_debug_verbose( +			"%s: no parent nodes with monitors, done", __func__); +		return; +	} + +	/* +	 * Check each of these monitors to see of their longest-match +	 * is now the updated node. Move any such monitors to the more- +	 * specific updated node +	 */ +	for (mlast = NULL, monitor = RFAPI_MONITOR_VPN(par); monitor;) { + +		/* +		 * If new longest match for monitor prefix is the new +		 * route's prefix, move monitor to new route's prefix +		 */ +		if (prefix_match(&new_vpn_node->p, &monitor->p)) { +			/* detach */ +			if (mlast) { +				mlast->next = monitor->next; +			} else { +				RFAPI_MONITOR_VPN_W_ALLOC(par) = monitor->next; +			} + + +			/* attach */ +			monitor->next = RFAPI_MONITOR_VPN(new_vpn_node); +			RFAPI_MONITOR_VPN_W_ALLOC(new_vpn_node) = monitor; +			monitor->node = new_vpn_node; + +			route_lock_node(new_vpn_node); /* incr refcount */ + +			monitor = mlast ? mlast->next : RFAPI_MONITOR_VPN(par); + +			RFAPI_CHECK_REFCOUNT(par, SAFI_MPLS_VPN, 1); +			/* decr refcount after we're done with par as this might +			 * free it */ +			route_unlock_node(par); + +			continue; +		} +		mlast = monitor; +		monitor = monitor->next; +	} + +	RFAPI_CHECK_REFCOUNT(new_vpn_node, SAFI_MPLS_VPN, 0);  } -static void -rfapiBgpInfoChainFree (struct bgp_info *bi) +static void rfapiBgpInfoChainFree(struct bgp_info *bi)  { -  struct bgp_info *next; - -  while (bi) -    { - -      /* -       * If there is a timer waiting to delete this bi, cancel -       * the timer and delete immediately -       */ -      if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED) && -          bi->extra->vnc.import.timer) -        { - -          struct thread *t = (struct thread *) bi->extra->vnc.import.timer; -          struct rfapi_withdraw *wcb = t->arg; - -          XFREE (MTYPE_RFAPI_WITHDRAW, wcb); -          thread_cancel (t); -        } - -      next = bi->next; -      bi->next = NULL; -      rfapiBgpInfoFree (bi); -      bi = next; -    } +	struct bgp_info *next; + +	while (bi) { + +		/* +		 * If there is a timer waiting to delete this bi, cancel +		 * the timer and delete immediately +		 */ +		if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED) +		    && bi->extra->vnc.import.timer) { + +			struct thread *t = +				(struct thread *)bi->extra->vnc.import.timer; +			struct rfapi_withdraw *wcb = t->arg; + +			XFREE(MTYPE_RFAPI_WITHDRAW, wcb); +			thread_cancel(t); +		} + +		next = bi->next; +		bi->next = NULL; +		rfapiBgpInfoFree(bi); +		bi = next; +	}  } -static void -rfapiImportTableFlush (struct rfapi_import_table *it) +static void rfapiImportTableFlush(struct rfapi_import_table *it)  { -  afi_t afi; - -  /* -   * Free ecommunity -   */ -  ecommunity_free (&it->rt_import_list); -  it->rt_import_list = NULL; - -  for (afi = AFI_IP; afi < AFI_MAX; ++afi) -    { - -      struct route_node *rn; - -      for (rn = route_top (it->imported_vpn[afi]); rn; rn = route_next (rn)) -        { -          /* -           * Each route_node has: -           * aggregate: points to rfapi_it_extra with monitor chain(s) -           * info: points to chain of bgp_info -           */ -          /* free bgp_info and its children */ -          rfapiBgpInfoChainFree (rn->info); -          rn->info = NULL; - -          rfapiMonitorExtraFlush (SAFI_MPLS_VPN, rn); -        } - -      for (rn = route_top (it->imported_encap[afi]); rn; rn = route_next (rn)) -        { -          /* free bgp_info and its children */ -          rfapiBgpInfoChainFree (rn->info); -          rn->info = NULL; - -          rfapiMonitorExtraFlush (SAFI_ENCAP, rn); -        } - -      route_table_finish (it->imported_vpn[afi]); -      route_table_finish (it->imported_encap[afi]); -    } -  if (it->monitor_exterior_orphans) -    { -      skiplist_free (it->monitor_exterior_orphans); -    } +	afi_t afi; + +	/* +	 * Free ecommunity +	 */ +	ecommunity_free(&it->rt_import_list); +	it->rt_import_list = NULL; + +	for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + +		struct route_node *rn; + +		for (rn = route_top(it->imported_vpn[afi]); rn; +		     rn = route_next(rn)) { +			/* +			 * Each route_node has: +			 * aggregate: points to rfapi_it_extra with monitor +			 * chain(s) +			 * info: points to chain of bgp_info +			 */ +			/* free bgp_info and its children */ +			rfapiBgpInfoChainFree(rn->info); +			rn->info = NULL; + +			rfapiMonitorExtraFlush(SAFI_MPLS_VPN, rn); +		} + +		for (rn = route_top(it->imported_encap[afi]); rn; +		     rn = route_next(rn)) { +			/* free bgp_info and its children */ +			rfapiBgpInfoChainFree(rn->info); +			rn->info = NULL; + +			rfapiMonitorExtraFlush(SAFI_ENCAP, rn); +		} + +		route_table_finish(it->imported_vpn[afi]); +		route_table_finish(it->imported_encap[afi]); +	} +	if (it->monitor_exterior_orphans) { +		skiplist_free(it->monitor_exterior_orphans); +	}  } -void -rfapiImportTableRefDelByIt ( -  struct bgp			*bgp, -  struct rfapi_import_table	*it_target) +void rfapiImportTableRefDelByIt(struct bgp *bgp, +				struct rfapi_import_table *it_target)  { -  struct rfapi *h; -  struct rfapi_import_table *it; -  struct rfapi_import_table *prev = NULL; - -  assert (it_target); - -  h = bgp->rfapi; -  assert (h); - -  for (it = h->imports; it; prev = it, it = it->next) -    { -      if (it == it_target) -        break; -    } - -  assert (it); -  assert (it->refcount); - -  it->refcount -= 1; - -  if (!it->refcount) -    { -      if (prev) -        { -          prev->next = it->next; -        } -      else -        { -          h->imports = it->next; -        } -      rfapiImportTableFlush (it); -      XFREE (MTYPE_RFAPI_IMPORTTABLE, it); -    } +	struct rfapi *h; +	struct rfapi_import_table *it; +	struct rfapi_import_table *prev = NULL; + +	assert(it_target); + +	h = bgp->rfapi; +	assert(h); + +	for (it = h->imports; it; prev = it, it = it->next) { +		if (it == it_target) +			break; +	} + +	assert(it); +	assert(it->refcount); + +	it->refcount -= 1; + +	if (!it->refcount) { +		if (prev) { +			prev->next = it->next; +		} else { +			h->imports = it->next; +		} +		rfapiImportTableFlush(it); +		XFREE(MTYPE_RFAPI_IMPORTTABLE, it); +	}  }  #if RFAPI_REQUIRE_ENCAP_BEEC @@ -1050,298 +990,272 @@ rfapiImportTableRefDelByIt (   * Look for magic BGP Encapsulation Extended Community value   * Format in RFC 5512 Sect. 4.5   */ -static int -rfapiEcommunitiesMatchBeec (struct ecommunity *ecom, -                            bgp_encap_types    type) +static int rfapiEcommunitiesMatchBeec(struct ecommunity *ecom, +				      bgp_encap_types type)  { -  int i; - -  if (!ecom) -    return 0; +	int i; -  for (i = 0; i < (ecom->size * ECOMMUNITY_SIZE); i += ECOMMUNITY_SIZE) -    { +	if (!ecom) +		return 0; -      uint8_t *ep; +	for (i = 0; i < (ecom->size * ECOMMUNITY_SIZE); i += ECOMMUNITY_SIZE) { -      ep = ecom->val + i; +		uint8_t *ep; -      if (ep[0] == ECOMMUNITY_ENCODE_OPAQUE &&  -          ep[1] == ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP &&  -          ep[6] == ((type && 0xff00)>>8) && -          ep[7] == (type&0xff)) -        { +		ep = ecom->val + i; -          return 1; -        } -    } -  return 0; +		if (ep[0] == ECOMMUNITY_ENCODE_OPAQUE +		    && ep[1] == ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP +		    && ep[6] == ((type && 0xff00) >> 8) +		    && ep[7] == (type & 0xff)) { +			return 1; +		} +	} +	return 0;  }  #endif -int -rfapiEcommunitiesIntersect (struct ecommunity *e1, struct ecommunity *e2) +int rfapiEcommunitiesIntersect(struct ecommunity *e1, struct ecommunity *e2)  { -  int i, j; - -  if (!e1 || !e2) -    return 0; - -  { -    char *s1, *s2; -    s1 = ecommunity_ecom2str (e1, ECOMMUNITY_FORMAT_DISPLAY, 0); -    s2 = ecommunity_ecom2str (e2, ECOMMUNITY_FORMAT_DISPLAY, 0); -    vnc_zlog_debug_verbose ("%s: e1[%s], e2[%s]", __func__, s1, s2); -    XFREE (MTYPE_ECOMMUNITY_STR, s1); -    XFREE (MTYPE_ECOMMUNITY_STR, s2); -  } - -  for (i = 0; i < e1->size; ++i) -    { -      for (j = 0; j < e2->size; ++j) -        { -          if (!memcmp (e1->val + (i * ECOMMUNITY_SIZE), -                       e2->val + (j * ECOMMUNITY_SIZE), ECOMMUNITY_SIZE)) -            { - -              return 1; -            } -        } -    } -  return 0; +	int i, j; + +	if (!e1 || !e2) +		return 0; + +	{ +		char *s1, *s2; +		s1 = ecommunity_ecom2str(e1, ECOMMUNITY_FORMAT_DISPLAY, 0); +		s2 = ecommunity_ecom2str(e2, ECOMMUNITY_FORMAT_DISPLAY, 0); +		vnc_zlog_debug_verbose("%s: e1[%s], e2[%s]", __func__, s1, s2); +		XFREE(MTYPE_ECOMMUNITY_STR, s1); +		XFREE(MTYPE_ECOMMUNITY_STR, s2); +	} + +	for (i = 0; i < e1->size; ++i) { +		for (j = 0; j < e2->size; ++j) { +			if (!memcmp(e1->val + (i * ECOMMUNITY_SIZE), +				    e2->val + (j * ECOMMUNITY_SIZE), +				    ECOMMUNITY_SIZE)) { + +				return 1; +			} +		} +	} +	return 0;  } -int -rfapiEcommunityGetLNI (struct ecommunity *ecom, uint32_t * lni) +int rfapiEcommunityGetLNI(struct ecommunity *ecom, uint32_t *lni)  { -  if (ecom) -    { -      int i; -      for (i = 0; i < ecom->size; ++i) -        { -          uint8_t *p = ecom->val + (i * ECOMMUNITY_SIZE); - -          if ((*(p + 0) == 0x00) && (*(p + 1) == 0x02)) -            { - -              *lni = (*(p + 5) << 16) | (*(p + 6) << 8) | (*(p + 7)); -              return 0; -            } -        } -    } -  return ENOENT; +	if (ecom) { +		int i; +		for (i = 0; i < ecom->size; ++i) { +			uint8_t *p = ecom->val + (i * ECOMMUNITY_SIZE); + +			if ((*(p + 0) == 0x00) && (*(p + 1) == 0x02)) { + +				*lni = (*(p + 5) << 16) | (*(p + 6) << 8) +				       | (*(p + 7)); +				return 0; +			} +		} +	} +	return ENOENT;  } -int -rfapiEcommunityGetEthernetTag (struct ecommunity *ecom, uint16_t * tag_id) +int rfapiEcommunityGetEthernetTag(struct ecommunity *ecom, uint16_t *tag_id)  { -  struct bgp *bgp = bgp_get_default (); -  *tag_id = 0;                  /* default to untagged */ -  if (ecom) -    { -      int i; -      for (i = 0; i < ecom->size; ++i) -        { -          as_t as    = 0; -          int encode = 0; -          uint8_t *p = ecom->val + (i * ECOMMUNITY_SIZE); -           -          /* High-order octet of type. */ -          encode = *p++; - -          if (*p++ == ECOMMUNITY_ROUTE_TARGET) { -            if (encode == ECOMMUNITY_ENCODE_AS4) -              { -                as =  (*p++ << 24); -                as |= (*p++ << 16); -                as |= (*p++ << 8); -                as |= (*p++); -              }  -            else if (encode == ECOMMUNITY_ENCODE_AS) -              { -                as =  (*p++ << 8); -                as |= (*p++); -                p += 2;         /* skip next two, tag/vid always in lowest bytes */ -              } -            if (as == bgp->as)  -              { -                *tag_id  = *p++ << 8; -                *tag_id |= (*p++); -                return 0; -              } -          } -        } -    } -  return ENOENT; +	struct bgp *bgp = bgp_get_default(); +	*tag_id = 0; /* default to untagged */ +	if (ecom) { +		int i; +		for (i = 0; i < ecom->size; ++i) { +			as_t as = 0; +			int encode = 0; +			uint8_t *p = ecom->val + (i * ECOMMUNITY_SIZE); + +			/* High-order octet of type. */ +			encode = *p++; + +			if (*p++ == ECOMMUNITY_ROUTE_TARGET) { +				if (encode == ECOMMUNITY_ENCODE_AS4) { +					as = (*p++ << 24); +					as |= (*p++ << 16); +					as |= (*p++ << 8); +					as |= (*p++); +				} else if (encode == ECOMMUNITY_ENCODE_AS) { +					as = (*p++ << 8); +					as |= (*p++); +					p += +						2; /* skip next two, tag/vid +						      always in lowest bytes */ +				} +				if (as == bgp->as) { +					*tag_id = *p++ << 8; +					*tag_id |= (*p++); +					return 0; +				} +			} +		} +	} +	return ENOENT;  } -static int -rfapiVpnBiNhEqualsPt (struct bgp_info *bi, struct rfapi_ip_addr *hpt) +static int rfapiVpnBiNhEqualsPt(struct bgp_info *bi, struct rfapi_ip_addr *hpt)  { -  uint8_t family; +	uint8_t family; -  if (!hpt || !bi) -    return 0; +	if (!hpt || !bi) +		return 0; -  family = BGP_MP_NEXTHOP_FAMILY (bi->attr->mp_nexthop_len); +	family = BGP_MP_NEXTHOP_FAMILY(bi->attr->mp_nexthop_len); -  if (hpt->addr_family != family) -    return 0; +	if (hpt->addr_family != family) +		return 0; -  switch (family) -    { -    case AF_INET: -      if (bi->attr->mp_nexthop_global_in.s_addr != hpt->addr.v4.s_addr) -        return 0; -      break; +	switch (family) { +	case AF_INET: +		if (bi->attr->mp_nexthop_global_in.s_addr +		    != hpt->addr.v4.s_addr) +			return 0; +		break; -    case AF_INET6: -      if (IPV6_ADDR_CMP (&bi->attr->mp_nexthop_global, &hpt->addr.v6)) -        return 0; -      break; +	case AF_INET6: +		if (IPV6_ADDR_CMP(&bi->attr->mp_nexthop_global, &hpt->addr.v6)) +			return 0; +		break; -    default: -      return 0; -      break; -    } +	default: +		return 0; +		break; +	} -  return 1; +	return 1;  }  /*   * Compare 2 VPN BIs. Return true if they have the same VN and UN addresses   */ -static int -rfapiVpnBiSamePtUn (struct bgp_info *bi1, struct bgp_info *bi2) +static int rfapiVpnBiSamePtUn(struct bgp_info *bi1, struct bgp_info *bi2)  { -  struct prefix pfx_un1; -  struct prefix pfx_un2; - -  if (!bi1 || !bi2) -    return 0; - -  if (!bi1->attr || !bi2->attr) -    return 0; - -  /* -   * VN address comparisons -   */ - -  if (BGP_MP_NEXTHOP_FAMILY (bi1->attr->mp_nexthop_len) != -      BGP_MP_NEXTHOP_FAMILY (bi2->attr->mp_nexthop_len)) -    { -      return 0; -    } - -  switch (BGP_MP_NEXTHOP_FAMILY (bi1->attr->mp_nexthop_len)) -    { -    case AF_INET: -      if (bi1->attr->mp_nexthop_global_in.s_addr != -          bi2->attr->mp_nexthop_global_in.s_addr) -        return 0; -      break; - -    case AF_INET6: -      if (IPV6_ADDR_CMP (&bi1->attr->mp_nexthop_global, -                         &bi2->attr->mp_nexthop_global)) -        return 0; -      break; - -    default: -      return 0; -      break; -    } - -  /* -   * UN address comparisons -   */ -  if (rfapiGetVncTunnelUnAddr (bi1->attr, &pfx_un1)) -    { -      if (bi1->extra) -        { -          pfx_un1.family = bi1->extra->vnc.import.un_family; -          switch (bi1->extra->vnc.import.un_family) -            { -            case AF_INET: -              pfx_un1.u.prefix4 = bi1->extra->vnc.import.un.addr4; -              break; -            case AF_INET6: -              pfx_un1.u.prefix6 = bi1->extra->vnc.import.un.addr6; -              break; -            default: -              pfx_un1.family = 0; -              break; -            } -        } -    } - -  if (rfapiGetVncTunnelUnAddr (bi2->attr, &pfx_un2)) -    { -      if (bi2->extra) -        { -          pfx_un2.family = bi2->extra->vnc.import.un_family; -          switch (bi2->extra->vnc.import.un_family) -            { -            case AF_INET: -              pfx_un2.u.prefix4 = bi2->extra->vnc.import.un.addr4; -              break; -            case AF_INET6: -              pfx_un2.u.prefix6 = bi2->extra->vnc.import.un.addr6; -              break; -            default: -              pfx_un2.family = 0; -              break; -            } -        } -    } - -  if (!pfx_un1.family || !pfx_un2.family) -    return 0; - -  if (pfx_un1.family != pfx_un2.family) -    return 0; - -  switch (pfx_un1.family) -    { -    case AF_INET: -      if (!IPV4_ADDR_SAME -          (&pfx_un1.u.prefix4.s_addr, &pfx_un2.u.prefix4.s_addr)) -        return 0; -      break; -    case AF_INET6: -      if (!IPV6_ADDR_SAME (&pfx_un1.u.prefix6, &pfx_un2.u.prefix6)) -        return 0; -      break; -    } - - - -  return 1; +	struct prefix pfx_un1; +	struct prefix pfx_un2; + +	if (!bi1 || !bi2) +		return 0; + +	if (!bi1->attr || !bi2->attr) +		return 0; + +	/* +	 * VN address comparisons +	 */ + +	if (BGP_MP_NEXTHOP_FAMILY(bi1->attr->mp_nexthop_len) +	    != BGP_MP_NEXTHOP_FAMILY(bi2->attr->mp_nexthop_len)) { +		return 0; +	} + +	switch (BGP_MP_NEXTHOP_FAMILY(bi1->attr->mp_nexthop_len)) { +	case AF_INET: +		if (bi1->attr->mp_nexthop_global_in.s_addr +		    != bi2->attr->mp_nexthop_global_in.s_addr) +			return 0; +		break; + +	case AF_INET6: +		if (IPV6_ADDR_CMP(&bi1->attr->mp_nexthop_global, +				  &bi2->attr->mp_nexthop_global)) +			return 0; +		break; + +	default: +		return 0; +		break; +	} + +	/* +	 * UN address comparisons +	 */ +	if (rfapiGetVncTunnelUnAddr(bi1->attr, &pfx_un1)) { +		if (bi1->extra) { +			pfx_un1.family = bi1->extra->vnc.import.un_family; +			switch (bi1->extra->vnc.import.un_family) { +			case AF_INET: +				pfx_un1.u.prefix4 = +					bi1->extra->vnc.import.un.addr4; +				break; +			case AF_INET6: +				pfx_un1.u.prefix6 = +					bi1->extra->vnc.import.un.addr6; +				break; +			default: +				pfx_un1.family = 0; +				break; +			} +		} +	} + +	if (rfapiGetVncTunnelUnAddr(bi2->attr, &pfx_un2)) { +		if (bi2->extra) { +			pfx_un2.family = bi2->extra->vnc.import.un_family; +			switch (bi2->extra->vnc.import.un_family) { +			case AF_INET: +				pfx_un2.u.prefix4 = +					bi2->extra->vnc.import.un.addr4; +				break; +			case AF_INET6: +				pfx_un2.u.prefix6 = +					bi2->extra->vnc.import.un.addr6; +				break; +			default: +				pfx_un2.family = 0; +				break; +			} +		} +	} + +	if (!pfx_un1.family || !pfx_un2.family) +		return 0; + +	if (pfx_un1.family != pfx_un2.family) +		return 0; + +	switch (pfx_un1.family) { +	case AF_INET: +		if (!IPV4_ADDR_SAME(&pfx_un1.u.prefix4.s_addr, +				    &pfx_un2.u.prefix4.s_addr)) +			return 0; +		break; +	case AF_INET6: +		if (!IPV6_ADDR_SAME(&pfx_un1.u.prefix6, &pfx_un2.u.prefix6)) +			return 0; +		break; +	} + + +	return 1;  } -uint8_t -rfapiRfpCost (struct attr * attr) +uint8_t rfapiRfpCost(struct attr *attr)  { -  if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)) -    { -      if (attr->local_pref > 255) -        { -          return 0; -        } -      return 255 - attr->local_pref; -    } - -  return 255; +	if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) { +		if (attr->local_pref > 255) { +			return 0; +		} +		return 255 - attr->local_pref; +	} + +	return 255;  }  /*------------------------------------------   * rfapi_extract_l2o   * - * Find Layer 2 options in an option chain  + * Find Layer 2 options in an option chain   * - * input:  + * input:   *	pHop		option chain   *   * output: @@ -1352,404 +1266,384 @@ rfapiRfpCost (struct attr * attr)   *	1		no options found   *   --------------------------------------------*/ -int -rfapi_extract_l2o (struct bgp_tea_options *pHop,        /* chain of options */ -                   struct rfapi_l2address_option *l2o)  /* return extracted value */ +int rfapi_extract_l2o( +	struct bgp_tea_options *pHop,       /* chain of options */ +	struct rfapi_l2address_option *l2o) /* return extracted value */  { -  struct bgp_tea_options *p; +	struct bgp_tea_options *p; -  for (p = pHop; p; p = p->next) -    { -      if ((p->type == RFAPI_VN_OPTION_TYPE_L2ADDR) && (p->length >= 8)) -        { +	for (p = pHop; p; p = p->next) { +		if ((p->type == RFAPI_VN_OPTION_TYPE_L2ADDR) +		    && (p->length >= 8)) { -          char *v = p->value; +			char *v = p->value; -          memcpy (&l2o->macaddr, v, 6); +			memcpy(&l2o->macaddr, v, 6); -          l2o->label = -            ((v[6] << 12) & 0xff000) + -            ((v[7] << 4) & 0xff0) + ((v[8] >> 4) & 0xf); +			l2o->label = ((v[6] << 12) & 0xff000) +				     + ((v[7] << 4) & 0xff0) +				     + ((v[8] >> 4) & 0xf); -          l2o->local_nve_id = (uint8_t) v[10]; +			l2o->local_nve_id = (uint8_t)v[10]; -          l2o->logical_net_id = (v[11] << 16) + (v[12] << 8) + (v[13] << 0); +			l2o->logical_net_id = +				(v[11] << 16) + (v[12] << 8) + (v[13] << 0); -          return 0; -        } -    } -  return 1; +			return 0; +		} +	} +	return 1;  }  static struct rfapi_next_hop_entry * -rfapiRouteInfo2NextHopEntry ( -  struct rfapi_ip_prefix	*rprefix, -  struct bgp_info		*bi,      /* route to encode */ -  uint32_t			lifetime, /* use this in nhe */ -  struct route_node		*rn)      /* req for L2 eth addr */ +rfapiRouteInfo2NextHopEntry(struct rfapi_ip_prefix *rprefix, +			    struct bgp_info *bi,   /* route to encode */ +			    uint32_t lifetime,     /* use this in nhe */ +			    struct route_node *rn) /* req for L2 eth addr */  { -  struct rfapi_next_hop_entry *new; -  int have_vnc_tunnel_un = 0; +	struct rfapi_next_hop_entry *new; +	int have_vnc_tunnel_un = 0;  #if DEBUG_ENCAP_MONITOR -  vnc_zlog_debug_verbose ("%s: entry, bi %p, rn %p", __func__, bi, rn); +	vnc_zlog_debug_verbose("%s: entry, bi %p, rn %p", __func__, bi, rn);  #endif -  new = XCALLOC (MTYPE_RFAPI_NEXTHOP, sizeof (struct rfapi_next_hop_entry)); -  assert (new); - -  new->prefix = *rprefix; - -  if (bi->extra &&  -      decode_rd_type(bi->extra->vnc.import.rd.val) == RD_TYPE_VNC_ETH) -    { -      /* ethernet */ - -      struct rfapi_vn_option *vo; - -      vo = XCALLOC (MTYPE_RFAPI_VN_OPTION, sizeof (struct rfapi_vn_option)); -      assert (vo); - -      vo->type = RFAPI_VN_OPTION_TYPE_L2ADDR; - -      memcpy (&vo->v.l2addr.macaddr, &rn->p.u.prefix_eth.octet, -              ETHER_ADDR_LEN); -      /* only low 3 bytes of this are significant */ -      if (bi->attr) -        { -          (void) rfapiEcommunityGetLNI (bi->attr->ecommunity, -                                        &vo->v.l2addr.logical_net_id); -          (void) rfapiEcommunityGetEthernetTag (bi->attr->ecommunity, -                                                &vo->v.l2addr.tag_id); -        } - -      /* local_nve_id comes from lower byte of RD type */ -      vo->v.l2addr.local_nve_id = bi->extra->vnc.import.rd.val[1]; - -      /* label comes from MP_REACH_NLRI label */ -      vo->v.l2addr.label = decode_label (&bi->extra->label); - -      new->vn_options = vo; - -      /* -       * If there is an auxiliary prefix (i.e., host IP address), -       * use it as the nexthop prefix instead of the query prefix -       */ -      if (bi->extra->vnc.import.aux_prefix.family) -        { -          rfapiQprefix2Rprefix (&bi->extra->vnc.import.aux_prefix, -                                &new->prefix); -        } -    } - -  if (bi->attr) -    { -      bgp_encap_types  tun_type; -      new->prefix.cost = rfapiRfpCost (bi->attr); - -      struct bgp_attr_encap_subtlv *pEncap; - -      switch (BGP_MP_NEXTHOP_FAMILY (bi->attr->mp_nexthop_len)) -        { -        case AF_INET: -          new->vn_address.addr_family = AF_INET; -          new->vn_address.addr.v4 = bi->attr->mp_nexthop_global_in; -          break; - -        case AF_INET6: -          new->vn_address.addr_family = AF_INET6; -          new->vn_address.addr.v6 = bi->attr->mp_nexthop_global; -          break; - -        default: -          zlog_warn ("%s: invalid vpn nexthop length: %d", -                     __func__, bi->attr->mp_nexthop_len); -          rfapi_free_next_hop_list (new); -          return NULL; -        } - -      for (pEncap = bi->attr->vnc_subtlvs; pEncap; -           pEncap = pEncap->next) -        { -          switch (pEncap->type) -            { -            case BGP_VNC_SUBTLV_TYPE_LIFETIME: -              /* use configured lifetime, not attr lifetime */ -              break; - -            default: -              zlog_warn ("%s: unknown VNC option type %d", -                         __func__, pEncap->type); - - -              break; -            } -        } - -      rfapiGetTunnelType (bi->attr, &tun_type); -      if (tun_type == BGP_ENCAP_TYPE_MPLS) -        { -          struct prefix p; -          /* MPLS carries UN address in next hop */ -          rfapiNexthop2Prefix (bi->attr, &p); -          if (p.family != 0) -            { -              rfapiQprefix2Raddr(&p, &new->un_address); -              have_vnc_tunnel_un = 1; -            } -        } - -      for (pEncap = bi->attr->encap_subtlvs; pEncap; -           pEncap = pEncap->next) -        { -          switch (pEncap->type) -            { -            case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT: -              /* -               * Overrides ENCAP UN address, if any -               */ -              switch (pEncap->length) -                { - -                case 8: -                  new->un_address.addr_family = AF_INET; -                  memcpy (&new->un_address.addr.v4, pEncap->value, 4); -                  have_vnc_tunnel_un = 1; -                  break; - -                case 20: -                  new->un_address.addr_family = AF_INET6; -                  memcpy (&new->un_address.addr.v6, pEncap->value, 16); -                  have_vnc_tunnel_un = 1; -                  break; - -                default: -                  zlog_warn -                    ("%s: invalid tunnel subtlv UN addr length (%d) for bi %p", -                     __func__, pEncap->length, bi); -                } -              break; - -            default: -              zlog_warn ("%s: unknown Encap Attribute option type %d", -                         __func__, pEncap->type); - - -              break; -            } -        } - -      new->un_options = rfapi_encap_tlv_to_un_option (bi->attr); +	new = XCALLOC(MTYPE_RFAPI_NEXTHOP, sizeof(struct rfapi_next_hop_entry)); +	assert(new); + +	new->prefix = *rprefix; + +	if (bi->extra +	    && decode_rd_type(bi->extra->vnc.import.rd.val) +		       == RD_TYPE_VNC_ETH) { +		/* ethernet */ + +		struct rfapi_vn_option *vo; + +		vo = XCALLOC(MTYPE_RFAPI_VN_OPTION, +			     sizeof(struct rfapi_vn_option)); +		assert(vo); + +		vo->type = RFAPI_VN_OPTION_TYPE_L2ADDR; + +		memcpy(&vo->v.l2addr.macaddr, &rn->p.u.prefix_eth.octet, +		       ETHER_ADDR_LEN); +		/* only low 3 bytes of this are significant */ +		if (bi->attr) { +			(void)rfapiEcommunityGetLNI( +				bi->attr->ecommunity, +				&vo->v.l2addr.logical_net_id); +			(void)rfapiEcommunityGetEthernetTag( +				bi->attr->ecommunity, &vo->v.l2addr.tag_id); +		} + +		/* local_nve_id comes from lower byte of RD type */ +		vo->v.l2addr.local_nve_id = bi->extra->vnc.import.rd.val[1]; + +		/* label comes from MP_REACH_NLRI label */ +		vo->v.l2addr.label = decode_label(&bi->extra->label); + +		new->vn_options = vo; + +		/* +		 * If there is an auxiliary prefix (i.e., host IP address), +		 * use it as the nexthop prefix instead of the query prefix +		 */ +		if (bi->extra->vnc.import.aux_prefix.family) { +			rfapiQprefix2Rprefix(&bi->extra->vnc.import.aux_prefix, +					     &new->prefix); +		} +	} + +	if (bi->attr) { +		bgp_encap_types tun_type; +		new->prefix.cost = rfapiRfpCost(bi->attr); + +		struct bgp_attr_encap_subtlv *pEncap; + +		switch (BGP_MP_NEXTHOP_FAMILY(bi->attr->mp_nexthop_len)) { +		case AF_INET: +			new->vn_address.addr_family = AF_INET; +			new->vn_address.addr.v4 = +				bi->attr->mp_nexthop_global_in; +			break; + +		case AF_INET6: +			new->vn_address.addr_family = AF_INET6; +			new->vn_address.addr.v6 = bi->attr->mp_nexthop_global; +			break; + +		default: +			zlog_warn("%s: invalid vpn nexthop length: %d", +				  __func__, bi->attr->mp_nexthop_len); +			rfapi_free_next_hop_list(new); +			return NULL; +		} + +		for (pEncap = bi->attr->vnc_subtlvs; pEncap; +		     pEncap = pEncap->next) { +			switch (pEncap->type) { +			case BGP_VNC_SUBTLV_TYPE_LIFETIME: +				/* use configured lifetime, not attr lifetime */ +				break; + +			default: +				zlog_warn("%s: unknown VNC option type %d", +					  __func__, pEncap->type); + + +				break; +			} +		} + +		rfapiGetTunnelType(bi->attr, &tun_type); +		if (tun_type == BGP_ENCAP_TYPE_MPLS) { +			struct prefix p; +			/* MPLS carries UN address in next hop */ +			rfapiNexthop2Prefix(bi->attr, &p); +			if (p.family != 0) { +				rfapiQprefix2Raddr(&p, &new->un_address); +				have_vnc_tunnel_un = 1; +			} +		} + +		for (pEncap = bi->attr->encap_subtlvs; pEncap; +		     pEncap = pEncap->next) { +			switch (pEncap->type) { +			case BGP_ENCAP_SUBTLV_TYPE_REMOTE_ENDPOINT: +				/* +				 * Overrides ENCAP UN address, if any +				 */ +				switch (pEncap->length) { + +				case 8: +					new->un_address.addr_family = AF_INET; +					memcpy(&new->un_address.addr.v4, +					       pEncap->value, 4); +					have_vnc_tunnel_un = 1; +					break; + +				case 20: +					new->un_address.addr_family = AF_INET6; +					memcpy(&new->un_address.addr.v6, +					       pEncap->value, 16); +					have_vnc_tunnel_un = 1; +					break; + +				default: +					zlog_warn( +						"%s: invalid tunnel subtlv UN addr length (%d) for bi %p", +						__func__, pEncap->length, bi); +				} +				break; + +			default: +				zlog_warn( +					"%s: unknown Encap Attribute option type %d", +					__func__, pEncap->type); + + +				break; +			} +		} + +		new->un_options = rfapi_encap_tlv_to_un_option(bi->attr);  #if DEBUG_ENCAP_MONITOR -      vnc_zlog_debug_verbose ("%s: line %d: have_vnc_tunnel_un=%d", -                              __func__, __LINE__, have_vnc_tunnel_un); +		vnc_zlog_debug_verbose("%s: line %d: have_vnc_tunnel_un=%d", +				       __func__, __LINE__, have_vnc_tunnel_un);  #endif -      if (!have_vnc_tunnel_un && bi && bi->extra) -        { -          /* -           * use cached UN address from ENCAP route -           */ -          new->un_address.addr_family = bi->extra->vnc.import.un_family; -          switch (new->un_address.addr_family) -            { -            case AF_INET: -              new->un_address.addr.v4 = bi->extra->vnc.import.un.addr4; -              break; -            case AF_INET6: -              new->un_address.addr.v6 = bi->extra->vnc.import.un.addr6; -              break; -            default: -              zlog_warn ("%s: invalid UN addr family (%d) for bi %p", -                         __func__, new->un_address.addr_family, bi); -              rfapi_free_next_hop_list (new); -              return NULL; -              break; -            } -        } -    } - -  new->lifetime = lifetime; -  return new; +		if (!have_vnc_tunnel_un && bi && bi->extra) { +			/* +			 * use cached UN address from ENCAP route +			 */ +			new->un_address.addr_family = +				bi->extra->vnc.import.un_family; +			switch (new->un_address.addr_family) { +			case AF_INET: +				new->un_address.addr.v4 = +					bi->extra->vnc.import.un.addr4; +				break; +			case AF_INET6: +				new->un_address.addr.v6 = +					bi->extra->vnc.import.un.addr6; +				break; +			default: +				zlog_warn( +					"%s: invalid UN addr family (%d) for bi %p", +					__func__, new->un_address.addr_family, +					bi); +				rfapi_free_next_hop_list(new); +				return NULL; +				break; +			} +		} +	} + +	new->lifetime = lifetime; +	return new;  } -int -rfapiHasNonRemovedRoutes (struct route_node *rn) +int rfapiHasNonRemovedRoutes(struct route_node *rn)  { -  struct bgp_info *bi; +	struct bgp_info *bi; -  for (bi = rn->info; bi; bi = bi->next) -    { -      struct prefix pfx; +	for (bi = rn->info; bi; bi = bi->next) { +		struct prefix pfx; -      if (!CHECK_FLAG (bi->flags, BGP_INFO_REMOVED) && -          (bi->extra && !rfapiGetUnAddrOfVpnBi (bi, &pfx))) -        { +		if (!CHECK_FLAG(bi->flags, BGP_INFO_REMOVED) +		    && (bi->extra && !rfapiGetUnAddrOfVpnBi(bi, &pfx))) { -          return 1; -        } -    } -  return 0; +			return 1; +		} +	} +	return 0;  }  #if DEBUG_IT_NODES -/*  +/*   * DEBUG FUNCTION   */ -void -rfapiDumpNode (struct route_node *rn) +void rfapiDumpNode(struct route_node *rn)  { -  struct bgp_info *bi; - -  vnc_zlog_debug_verbose ("%s: rn=%p", __func__, rn); -  for (bi = rn->info; bi; bi = bi->next) -    { -      struct prefix pfx; -      int ctrc = rfapiGetUnAddrOfVpnBi (bi, &pfx); -      int nr; - -      if (!CHECK_FLAG (bi->flags, BGP_INFO_REMOVED) && (bi->extra && !ctrc)) -        { - -          nr = 1; -        } -      else -        { -          nr = 0; -        } - -      vnc_zlog_debug_verbose ("  bi=%p, nr=%d, flags=0x%x, extra=%p, ctrc=%d", -                  bi, nr, bi->flags, bi->extra, ctrc); -    } +	struct bgp_info *bi; + +	vnc_zlog_debug_verbose("%s: rn=%p", __func__, rn); +	for (bi = rn->info; bi; bi = bi->next) { +		struct prefix pfx; +		int ctrc = rfapiGetUnAddrOfVpnBi(bi, &pfx); +		int nr; + +		if (!CHECK_FLAG(bi->flags, BGP_INFO_REMOVED) +		    && (bi->extra && !ctrc)) { + +			nr = 1; +		} else { +			nr = 0; +		} + +		vnc_zlog_debug_verbose( +			"  bi=%p, nr=%d, flags=0x%x, extra=%p, ctrc=%d", bi, nr, +			bi->flags, bi->extra, ctrc); +	}  }  #endif -static int -rfapiNhlAddNodeRoutes ( -  struct route_node		*rn,         /* in */ -  struct rfapi_ip_prefix	*rprefix,    /* in */ -  uint32_t			lifetime,    /* in */ -  int				removed,     /* in */ -  struct rfapi_next_hop_entry	**head,      /* in/out */ -  struct rfapi_next_hop_entry	**tail,      /* in/out */ -  struct rfapi_ip_addr		*exclude_vnaddr,  /* omit routes to same NVE */ -  struct route_node		*rfd_rib_node,/* preload this NVE rib node */ -  struct prefix			*pfx_target_original) /* query target */ +static int rfapiNhlAddNodeRoutes( +	struct route_node *rn,		      /* in */ +	struct rfapi_ip_prefix *rprefix,      /* in */ +	uint32_t lifetime,		      /* in */ +	int removed,			      /* in */ +	struct rfapi_next_hop_entry **head,   /* in/out */ +	struct rfapi_next_hop_entry **tail,   /* in/out */ +	struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ +	struct route_node *rfd_rib_node,      /* preload this NVE rib node */ +	struct prefix *pfx_target_original)   /* query target */  { -  struct bgp_info               *bi; -  struct rfapi_next_hop_entry   *new; -  struct prefix                 pfx_un; -  struct skiplist               *seen_nexthops; -  int                           count = 0; -  int                           is_l2 = (rn->p.family == AF_ETHERNET); - -  if (rfapiRibFTDFilterRecentPrefix( -    (struct rfapi_descriptor *)(rfd_rib_node->table->info), rn, -    pfx_target_original)) -    { -      return 0; -    } - -  seen_nexthops = -    skiplist_new (0, vnc_prefix_cmp, (void (*)(void *)) prefix_free); - -  for (bi = rn->info; bi; bi = bi->next) -    { - -      struct prefix pfx_vn; -      struct prefix *newpfx; - -      if (removed && !CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) -        { +	struct bgp_info *bi; +	struct rfapi_next_hop_entry *new; +	struct prefix pfx_un; +	struct skiplist *seen_nexthops; +	int count = 0; +	int is_l2 = (rn->p.family == AF_ETHERNET); + +	if (rfapiRibFTDFilterRecentPrefix( +		    (struct rfapi_descriptor *)(rfd_rib_node->table->info), rn, +		    pfx_target_original)) { +		return 0; +	} + +	seen_nexthops = +		skiplist_new(0, vnc_prefix_cmp, (void (*)(void *))prefix_free); + +	for (bi = rn->info; bi; bi = bi->next) { + +		struct prefix pfx_vn; +		struct prefix *newpfx; + +		if (removed && !CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) {  #if DEBUG_RETURNED_NHL -          vnc_zlog_debug_verbose ("%s: want holddown, this route not holddown, skip", -                      __func__); +			vnc_zlog_debug_verbose( +				"%s: want holddown, this route not holddown, skip", +				__func__);  #endif -          continue; -        } -      if (!removed && CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) -        { -          continue; -        } - -      if (!bi->extra) -        { -          continue; -        } - -      /* -       * Check for excluded VN address -       */ -      if (rfapiVpnBiNhEqualsPt (bi, exclude_vnaddr)) -        continue; - -      /* -       * Check for VN address (nexthop) copied already -       */ -      if (is_l2) -        { -          /* L2 routes: semantic nexthop in aux_prefix; VN addr ain't it */ -          pfx_vn = bi->extra->vnc.import.aux_prefix; -        } -      else -        { -          rfapiNexthop2Prefix (bi->attr, &pfx_vn); -        } -      if (!skiplist_search (seen_nexthops, &pfx_vn, NULL)) -        { +			continue; +		} +		if (!removed && CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) { +			continue; +		} + +		if (!bi->extra) { +			continue; +		} + +		/* +		 * Check for excluded VN address +		 */ +		if (rfapiVpnBiNhEqualsPt(bi, exclude_vnaddr)) +			continue; + +		/* +		 * Check for VN address (nexthop) copied already +		 */ +		if (is_l2) { +			/* L2 routes: semantic nexthop in aux_prefix; VN addr +			 * ain't it */ +			pfx_vn = bi->extra->vnc.import.aux_prefix; +		} else { +			rfapiNexthop2Prefix(bi->attr, &pfx_vn); +		} +		if (!skiplist_search(seen_nexthops, &pfx_vn, NULL)) {  #if DEBUG_RETURNED_NHL -          char buf[BUFSIZ]; +			char buf[BUFSIZ]; -          prefix2str (&pfx_vn, buf, BUFSIZ); -          buf[BUFSIZ - 1] = 0;  /* guarantee NUL-terminated */ -          vnc_zlog_debug_verbose ("%s: already put VN/nexthop %s, skip", __func__, buf); +			prefix2str(&pfx_vn, buf, BUFSIZ); +			buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */ +			vnc_zlog_debug_verbose( +				"%s: already put VN/nexthop %s, skip", __func__, +				buf);  #endif -          continue; -        } +			continue; +		} -      if (rfapiGetUnAddrOfVpnBi (bi, &pfx_un)) -        { +		if (rfapiGetUnAddrOfVpnBi(bi, &pfx_un)) {  #if DEBUG_ENCAP_MONITOR -          vnc_zlog_debug_verbose ("%s: failed to get UN address of this VPN bi", -                      __func__); +			vnc_zlog_debug_verbose( +				"%s: failed to get UN address of this VPN bi", +				__func__);  #endif -          continue; -        } - -      newpfx = prefix_new (); -      *newpfx = pfx_vn; -      skiplist_insert (seen_nexthops, newpfx, newpfx); - -      new = rfapiRouteInfo2NextHopEntry(rprefix, bi, lifetime, rn); -      if (new) -	{ -	  if (rfapiRibPreloadBi(rfd_rib_node, &pfx_vn, &pfx_un, lifetime, bi)) -	    { -	      /* duplicate filtered by RIB */ -	      rfapi_free_next_hop_list (new); -	      new = NULL; -	    } -        } - -      if (new) -        { -          if (*tail) -            { -              (*tail)->next = new; -            } -          else -            { -              *head = new; -            } -          *tail = new; -          ++count; -        } -    } - -  skiplist_free (seen_nexthops); - -  return count; +			continue; +		} + +		newpfx = prefix_new(); +		*newpfx = pfx_vn; +		skiplist_insert(seen_nexthops, newpfx, newpfx); + +		new = rfapiRouteInfo2NextHopEntry(rprefix, bi, lifetime, rn); +		if (new) { +			if (rfapiRibPreloadBi(rfd_rib_node, &pfx_vn, &pfx_un, +					      lifetime, bi)) { +				/* duplicate filtered by RIB */ +				rfapi_free_next_hop_list(new); +				new = NULL; +			} +		} + +		if (new) { +			if (*tail) { +				(*tail)->next = new; +			} else { +				*head = new; +			} +			*tail = new; +			++count; +		} +	} + +	skiplist_free(seen_nexthops); + +	return count;  } @@ -1762,85 +1656,84 @@ rfapiNhlAddNodeRoutes (   * its routes in the list, so we skip it if the right or left node   * matches (of course, we still travel down its child subtrees).   */ -static int -rfapiNhlAddSubtree ( -    struct route_node		*rn,		/* in */ -    uint32_t			lifetime,	/* in */ -    struct rfapi_next_hop_entry	**head,		/* in/out */ -    struct rfapi_next_hop_entry	**tail,		/* in/out */ -    struct route_node		*omit_node,	/* in */ -    struct rfapi_ip_addr	*exclude_vnaddr,/* omit routes to same NVE */ -    struct route_table          *rfd_rib_table,/* preload here */ -    struct prefix		*pfx_target_original) /* query target */ +static int rfapiNhlAddSubtree( +	struct route_node *rn,		      /* in */ +	uint32_t lifetime,		      /* in */ +	struct rfapi_next_hop_entry **head,   /* in/out */ +	struct rfapi_next_hop_entry **tail,   /* in/out */ +	struct route_node *omit_node,	 /* in */ +	struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ +	struct route_table *rfd_rib_table,    /* preload here */ +	struct prefix *pfx_target_original)   /* query target */  { -  struct rfapi_ip_prefix rprefix; -  int                    rcount = 0; - -  /* FIXME: need to find a better way here to work without sticking our -   * hands in node->link */ -  if (rn->l_left && rn->l_left != omit_node) -    { -      if (rn->l_left->info) -        { -          int               count = 0; -          struct route_node *rib_rn = NULL; - -          rfapiQprefix2Rprefix (&rn->l_left->p, &rprefix); -          if (rfd_rib_table) -            { -              rib_rn = route_node_get(rfd_rib_table, &rn->l_left->p); -            } - -          count = rfapiNhlAddNodeRoutes (rn->l_left, &rprefix, lifetime, 0, -            head, tail, exclude_vnaddr, rib_rn, pfx_target_original); -          if (!count) -            { -              count = rfapiNhlAddNodeRoutes (rn->l_left, &rprefix, lifetime, 1, -                head, tail, exclude_vnaddr, rib_rn, pfx_target_original); -            } -          rcount += count; -	  if (rib_rn) -	    route_unlock_node(rib_rn); -        } -    } - -  if (rn->l_right && rn->l_right != omit_node) -    { -      if (rn->l_right->info) -        { -          int               count = 0; -          struct route_node *rib_rn = NULL; - -          rfapiQprefix2Rprefix (&rn->l_right->p, &rprefix); -          if (rfd_rib_table) -            { -              rib_rn = route_node_get(rfd_rib_table, &rn->l_right->p); -            } -          count = rfapiNhlAddNodeRoutes (rn->l_right, &rprefix, lifetime, 0, -            head, tail, exclude_vnaddr, rib_rn, pfx_target_original); -          if (!count) -            { -              count = rfapiNhlAddNodeRoutes (rn->l_right, &rprefix, lifetime, 1, -                head, tail, exclude_vnaddr, rib_rn, pfx_target_original); -            } -          rcount += count; -	  if (rib_rn) -	    route_unlock_node(rib_rn); -        } -    } - -  if (rn->l_left) -    { -      rcount += rfapiNhlAddSubtree (rn->l_left, lifetime, head, tail, omit_node, -        exclude_vnaddr, rfd_rib_table, pfx_target_original); -    } -  if (rn->l_right) -    { -      rcount += rfapiNhlAddSubtree (rn->l_right, lifetime, head, tail, -        omit_node, exclude_vnaddr, rfd_rib_table, pfx_target_original); -    } - -  return rcount; +	struct rfapi_ip_prefix rprefix; +	int rcount = 0; + +	/* FIXME: need to find a better way here to work without sticking our +	 * hands in node->link */ +	if (rn->l_left && rn->l_left != omit_node) { +		if (rn->l_left->info) { +			int count = 0; +			struct route_node *rib_rn = NULL; + +			rfapiQprefix2Rprefix(&rn->l_left->p, &rprefix); +			if (rfd_rib_table) { +				rib_rn = route_node_get(rfd_rib_table, +							&rn->l_left->p); +			} + +			count = rfapiNhlAddNodeRoutes( +				rn->l_left, &rprefix, lifetime, 0, head, tail, +				exclude_vnaddr, rib_rn, pfx_target_original); +			if (!count) { +				count = rfapiNhlAddNodeRoutes( +					rn->l_left, &rprefix, lifetime, 1, head, +					tail, exclude_vnaddr, rib_rn, +					pfx_target_original); +			} +			rcount += count; +			if (rib_rn) +				route_unlock_node(rib_rn); +		} +	} + +	if (rn->l_right && rn->l_right != omit_node) { +		if (rn->l_right->info) { +			int count = 0; +			struct route_node *rib_rn = NULL; + +			rfapiQprefix2Rprefix(&rn->l_right->p, &rprefix); +			if (rfd_rib_table) { +				rib_rn = route_node_get(rfd_rib_table, +							&rn->l_right->p); +			} +			count = rfapiNhlAddNodeRoutes( +				rn->l_right, &rprefix, lifetime, 0, head, tail, +				exclude_vnaddr, rib_rn, pfx_target_original); +			if (!count) { +				count = rfapiNhlAddNodeRoutes( +					rn->l_right, &rprefix, lifetime, 1, +					head, tail, exclude_vnaddr, rib_rn, +					pfx_target_original); +			} +			rcount += count; +			if (rib_rn) +				route_unlock_node(rib_rn); +		} +	} + +	if (rn->l_left) { +		rcount += rfapiNhlAddSubtree( +			rn->l_left, lifetime, head, tail, omit_node, +			exclude_vnaddr, rfd_rib_table, pfx_target_original); +	} +	if (rn->l_right) { +		rcount += rfapiNhlAddSubtree( +			rn->l_right, lifetime, head, tail, omit_node, +			exclude_vnaddr, rfd_rib_table, pfx_target_original); +	} + +	return rcount;  }  /* @@ -1854,343 +1747,326 @@ rfapiNhlAddSubtree (   * then return those, and also include all the non-removed routes from the   * next less-specific node (i.e., this node's parent) at the end.   */ -struct rfapi_next_hop_entry * -rfapiRouteNode2NextHopList ( -  struct route_node	*rn, -  uint32_t		lifetime,	/* put into nexthop entries */ -  struct rfapi_ip_addr	*exclude_vnaddr,/* omit routes to same NVE */ -  struct route_table	*rfd_rib_table,/* preload here */ -  struct prefix		*pfx_target_original) /* query target */ +struct rfapi_next_hop_entry *rfapiRouteNode2NextHopList( +	struct route_node *rn, uint32_t lifetime, /* put into nexthop entries */ +	struct rfapi_ip_addr *exclude_vnaddr,     /* omit routes to same NVE */ +	struct route_table *rfd_rib_table,	/* preload here */ +	struct prefix *pfx_target_original)       /* query target */  { -  struct rfapi_ip_prefix      rprefix; -  struct rfapi_next_hop_entry *answer = NULL; -  struct rfapi_next_hop_entry *last = NULL; -  struct route_node           *parent; -  int                         count = 0; -  struct route_node           *rib_rn; +	struct rfapi_ip_prefix rprefix; +	struct rfapi_next_hop_entry *answer = NULL; +	struct rfapi_next_hop_entry *last = NULL; +	struct route_node *parent; +	int count = 0; +	struct route_node *rib_rn;  #if DEBUG_RETURNED_NHL -  { -    char buf[BUFSIZ]; - -    prefix2str (&rn->p, buf, BUFSIZ); -    buf[BUFSIZ - 1] = 0; -    vnc_zlog_debug_verbose ("%s: called with node pfx=%s", __func__, buf); -  } -  rfapiDebugBacktrace (); +	{ +		char buf[BUFSIZ]; + +		prefix2str(&rn->p, buf, BUFSIZ); +		buf[BUFSIZ - 1] = 0; +		vnc_zlog_debug_verbose("%s: called with node pfx=%s", __func__, +				       buf); +	} +	rfapiDebugBacktrace();  #endif -  rfapiQprefix2Rprefix (&rn->p, &rprefix); - -  rib_rn = rfd_rib_table? route_node_get(rfd_rib_table, &rn->p): NULL; - -  /* -   * Add non-withdrawn routes at this node -   */ -  count = rfapiNhlAddNodeRoutes (rn, &rprefix, lifetime, 0, &answer, &last, -    exclude_vnaddr, rib_rn, pfx_target_original); - -  /* -   * If the list has at least one entry, it's finished -   */ -  if (count) -    { -      count += rfapiNhlAddSubtree (rn, lifetime, &answer, &last, NULL, -        exclude_vnaddr, rfd_rib_table, pfx_target_original); -      vnc_zlog_debug_verbose ("%s: %d nexthops, answer=%p", __func__, count, answer); +	rfapiQprefix2Rprefix(&rn->p, &rprefix); + +	rib_rn = rfd_rib_table ? route_node_get(rfd_rib_table, &rn->p) : NULL; + +	/* +	 * Add non-withdrawn routes at this node +	 */ +	count = rfapiNhlAddNodeRoutes(rn, &rprefix, lifetime, 0, &answer, &last, +				      exclude_vnaddr, rib_rn, +				      pfx_target_original); + +	/* +	 * If the list has at least one entry, it's finished +	 */ +	if (count) { +		count += rfapiNhlAddSubtree(rn, lifetime, &answer, &last, NULL, +					    exclude_vnaddr, rfd_rib_table, +					    pfx_target_original); +		vnc_zlog_debug_verbose("%s: %d nexthops, answer=%p", __func__, +				       count, answer);  #if DEBUG_RETURNED_NHL -      rfapiPrintNhl (NULL, answer); +		rfapiPrintNhl(NULL, answer);  #endif -      if (rib_rn) -        route_unlock_node(rib_rn); -      return answer; -    } - -  /* -   * Add withdrawn routes at this node -   */ -  count = rfapiNhlAddNodeRoutes (rn, &rprefix, lifetime, 1, &answer, &last, -    exclude_vnaddr, rib_rn, pfx_target_original); -  if (rib_rn) -    route_unlock_node(rib_rn); - -  // rfapiPrintNhl(NULL, answer); - -  /* -   * walk up the tree until we find a node with non-deleted -   * routes, then add them -   */ -  for (parent = rn->parent; parent; parent = parent->parent) -    { -      if (rfapiHasNonRemovedRoutes (parent)) -        { -          break; -        } -    } - -  /* -   * Add non-withdrawn routes from less-specific prefix -   */ -  if (parent) -    { -      rib_rn = rfd_rib_table? route_node_get(rfd_rib_table, &parent->p): NULL; -      rfapiQprefix2Rprefix (&parent->p, &rprefix); -      count += rfapiNhlAddNodeRoutes (parent, &rprefix, lifetime, 0, -        &answer, &last, exclude_vnaddr, rib_rn, pfx_target_original); -      count += rfapiNhlAddSubtree (parent, lifetime, &answer, &last, rn, -        exclude_vnaddr, rfd_rib_table, pfx_target_original); -      if (rib_rn) -        route_unlock_node(rib_rn); -    } -  else -    { -      /* -       * There is no parent with non-removed routes. Still need to -       * add subtree of original node if it contributed routes to the -       * answer. -       */ -      if (count) -        count += rfapiNhlAddSubtree (rn, lifetime, &answer, &last, rn, -          exclude_vnaddr, rfd_rib_table, pfx_target_original); -    } - -  vnc_zlog_debug_verbose ("%s: %d nexthops, answer=%p", __func__, count, answer); +		if (rib_rn) +			route_unlock_node(rib_rn); +		return answer; +	} + +	/* +	 * Add withdrawn routes at this node +	 */ +	count = rfapiNhlAddNodeRoutes(rn, &rprefix, lifetime, 1, &answer, &last, +				      exclude_vnaddr, rib_rn, +				      pfx_target_original); +	if (rib_rn) +		route_unlock_node(rib_rn); + +	// rfapiPrintNhl(NULL, answer); + +	/* +	 * walk up the tree until we find a node with non-deleted +	 * routes, then add them +	 */ +	for (parent = rn->parent; parent; parent = parent->parent) { +		if (rfapiHasNonRemovedRoutes(parent)) { +			break; +		} +	} + +	/* +	 * Add non-withdrawn routes from less-specific prefix +	 */ +	if (parent) { +		rib_rn = rfd_rib_table +				 ? route_node_get(rfd_rib_table, &parent->p) +				 : NULL; +		rfapiQprefix2Rprefix(&parent->p, &rprefix); +		count += rfapiNhlAddNodeRoutes(parent, &rprefix, lifetime, 0, +					       &answer, &last, exclude_vnaddr, +					       rib_rn, pfx_target_original); +		count += rfapiNhlAddSubtree(parent, lifetime, &answer, &last, +					    rn, exclude_vnaddr, rfd_rib_table, +					    pfx_target_original); +		if (rib_rn) +			route_unlock_node(rib_rn); +	} else { +		/* +		 * There is no parent with non-removed routes. Still need to +		 * add subtree of original node if it contributed routes to the +		 * answer. +		 */ +		if (count) +			count += rfapiNhlAddSubtree(rn, lifetime, &answer, +						    &last, rn, exclude_vnaddr, +						    rfd_rib_table, +						    pfx_target_original); +	} + +	vnc_zlog_debug_verbose("%s: %d nexthops, answer=%p", __func__, count, +			       answer);  #if DEBUG_RETURNED_NHL -  rfapiPrintNhl (NULL, answer); +	rfapiPrintNhl(NULL, answer);  #endif -  return answer; +	return answer;  }  /*   * Construct nexthop list of all routes in table   */ -struct rfapi_next_hop_entry * -rfapiRouteTable2NextHopList ( -    struct route_table		*rt, -    uint32_t			lifetime,	/* put into nexthop entries */ -    struct rfapi_ip_addr	*exclude_vnaddr,/* omit routes to same NVE */ -    struct route_table		*rfd_rib_table, /* preload this NVE rib table */ -    struct prefix		*pfx_target_original) /* query target */ +struct rfapi_next_hop_entry *rfapiRouteTable2NextHopList( +	struct route_table *rt, +	uint32_t lifetime,		      /* put into nexthop entries */ +	struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ +	struct route_table *rfd_rib_table,    /* preload this NVE rib table */ +	struct prefix *pfx_target_original)   /* query target */  { -  struct route_node *rn; -  struct rfapi_next_hop_entry *biglist = NULL; -  struct rfapi_next_hop_entry *nhl; -  struct rfapi_next_hop_entry *tail = NULL; -  int count = 0; - -  for (rn = route_top (rt); rn; rn = route_next (rn)) -    { - -      nhl = rfapiRouteNode2NextHopList (rn, lifetime, exclude_vnaddr, -	rfd_rib_table, pfx_target_original); -      if (!tail) -        { -          tail = biglist = nhl; -          if (tail) -            count = 1; -        } -      else -        { -          tail->next = nhl; -        } -      if (tail) -        { -          while (tail->next) -            { -              ++count; -              tail = tail->next; -            } -        } -    } - -  vnc_zlog_debug_verbose ("%s: returning %d routes", __func__, count); -  return biglist; +	struct route_node *rn; +	struct rfapi_next_hop_entry *biglist = NULL; +	struct rfapi_next_hop_entry *nhl; +	struct rfapi_next_hop_entry *tail = NULL; +	int count = 0; + +	for (rn = route_top(rt); rn; rn = route_next(rn)) { + +		nhl = rfapiRouteNode2NextHopList(rn, lifetime, exclude_vnaddr, +						 rfd_rib_table, +						 pfx_target_original); +		if (!tail) { +			tail = biglist = nhl; +			if (tail) +				count = 1; +		} else { +			tail->next = nhl; +		} +		if (tail) { +			while (tail->next) { +				++count; +				tail = tail->next; +			} +		} +	} + +	vnc_zlog_debug_verbose("%s: returning %d routes", __func__, count); +	return biglist;  } -struct rfapi_next_hop_entry * -rfapiEthRouteNode2NextHopList ( -  struct route_node		*rn, -  struct rfapi_ip_prefix	*rprefix, -  uint32_t			lifetime,       /* put into nexthop entries */ -  struct rfapi_ip_addr		*exclude_vnaddr,/* omit routes to same NVE */ -  struct route_table		*rfd_rib_table,/* preload NVE rib table */ -  struct prefix			*pfx_target_original) /* query target */ +struct rfapi_next_hop_entry *rfapiEthRouteNode2NextHopList( +	struct route_node *rn, struct rfapi_ip_prefix *rprefix, +	uint32_t lifetime,		      /* put into nexthop entries */ +	struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ +	struct route_table *rfd_rib_table,    /* preload NVE rib table */ +	struct prefix *pfx_target_original)   /* query target */  { -  int count = 0; -  struct rfapi_next_hop_entry *answer = NULL; -  struct rfapi_next_hop_entry *last = NULL; -  struct route_node           *rib_rn; +	int count = 0; +	struct rfapi_next_hop_entry *answer = NULL; +	struct rfapi_next_hop_entry *last = NULL; +	struct route_node *rib_rn; -  rib_rn = rfd_rib_table? route_node_get(rfd_rib_table, &rn->p): NULL; +	rib_rn = rfd_rib_table ? route_node_get(rfd_rib_table, &rn->p) : NULL; -  count = rfapiNhlAddNodeRoutes (rn, rprefix, lifetime, 0, &answer, &last, -    NULL, rib_rn, pfx_target_original); +	count = rfapiNhlAddNodeRoutes(rn, rprefix, lifetime, 0, &answer, &last, +				      NULL, rib_rn, pfx_target_original);  #if DEBUG_ENCAP_MONITOR -  vnc_zlog_debug_verbose ("%s: node %p: %d non-holddown routes", __func__, rn, count); +	vnc_zlog_debug_verbose("%s: node %p: %d non-holddown routes", __func__, +			       rn, count);  #endif -  if (!count) -    { -      count = rfapiNhlAddNodeRoutes (rn, rprefix, lifetime, 1, &answer, &last, -	exclude_vnaddr, rib_rn, pfx_target_original); -      vnc_zlog_debug_verbose ("%s: node %p: %d holddown routes", __func__, rn, count); -    } +	if (!count) { +		count = rfapiNhlAddNodeRoutes(rn, rprefix, lifetime, 1, &answer, +					      &last, exclude_vnaddr, rib_rn, +					      pfx_target_original); +		vnc_zlog_debug_verbose("%s: node %p: %d holddown routes", +				       __func__, rn, count); +	} -    if (rib_rn) -      route_unlock_node(rib_rn); +	if (rib_rn) +		route_unlock_node(rib_rn);  #if DEBUG_RETURNED_NHL -  rfapiPrintNhl (NULL, answer); +	rfapiPrintNhl(NULL, answer);  #endif -  return answer; +	return answer;  }  /*   * Construct nexthop list of all routes in table   */ -struct rfapi_next_hop_entry * -rfapiEthRouteTable2NextHopList ( -  uint32_t			logical_net_id, -  struct rfapi_ip_prefix	*rprefix, -  uint32_t			lifetime,	/* put into nexthop entries */ -  struct rfapi_ip_addr		*exclude_vnaddr,/* omit routes to same NVE */ -  struct route_table		*rfd_rib_table, /* preload NVE rib node */ -  struct prefix			*pfx_target_original) /* query target */ +struct rfapi_next_hop_entry *rfapiEthRouteTable2NextHopList( +	uint32_t logical_net_id, struct rfapi_ip_prefix *rprefix, +	uint32_t lifetime,		      /* put into nexthop entries */ +	struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ +	struct route_table *rfd_rib_table,    /* preload NVE rib node */ +	struct prefix *pfx_target_original)   /* query target */  { -  struct rfapi_import_table *it; -  struct bgp *bgp = bgp_get_default (); -  struct route_table *rt; -  struct route_node *rn; -  struct rfapi_next_hop_entry *biglist = NULL; -  struct rfapi_next_hop_entry *nhl; -  struct rfapi_next_hop_entry *tail = NULL; -  int count = 0; - - -  it = rfapiMacImportTableGet (bgp, logical_net_id); -  rt = it->imported_vpn[AFI_L2VPN]; - -  for (rn = route_top (rt); rn; rn = route_next (rn)) -    { - -      nhl = rfapiEthRouteNode2NextHopList(rn, rprefix, lifetime, -	exclude_vnaddr, rfd_rib_table, pfx_target_original); -      if (!tail) -        { -          tail = biglist = nhl; -          if (tail) -            count = 1; -        } -      else -        { -          tail->next = nhl; -        } -      if (tail) -        { -          while (tail->next) -            { -              ++count; -              tail = tail->next; -            } -        } -    } - -  vnc_zlog_debug_verbose ("%s: returning %d routes", __func__, count); -  return biglist; +	struct rfapi_import_table *it; +	struct bgp *bgp = bgp_get_default(); +	struct route_table *rt; +	struct route_node *rn; +	struct rfapi_next_hop_entry *biglist = NULL; +	struct rfapi_next_hop_entry *nhl; +	struct rfapi_next_hop_entry *tail = NULL; +	int count = 0; + + +	it = rfapiMacImportTableGet(bgp, logical_net_id); +	rt = it->imported_vpn[AFI_L2VPN]; + +	for (rn = route_top(rt); rn; rn = route_next(rn)) { + +		nhl = rfapiEthRouteNode2NextHopList( +			rn, rprefix, lifetime, exclude_vnaddr, rfd_rib_table, +			pfx_target_original); +		if (!tail) { +			tail = biglist = nhl; +			if (tail) +				count = 1; +		} else { +			tail->next = nhl; +		} +		if (tail) { +			while (tail->next) { +				++count; +				tail = tail->next; +			} +		} +	} + +	vnc_zlog_debug_verbose("%s: returning %d routes", __func__, count); +	return biglist;  }  /*   * Insert a new bi to the imported route table node,   * keeping the list of BIs sorted best route first   */ -static void -rfapiBgpInfoAttachSorted ( -  struct route_node	*rn, -  struct bgp_info	*info_new, -  afi_t			afi, -  safi_t		safi) +static void rfapiBgpInfoAttachSorted(struct route_node *rn, +				     struct bgp_info *info_new, afi_t afi, +				     safi_t safi)  { -  struct bgp		*bgp; -  struct bgp_info	*prev; -  struct bgp_info	*next; -  char pfx_buf[PREFIX2STR_BUFFER]; - - -  bgp = bgp_get_default ();     /* assume 1 instance for now */ - -  if (VNC_DEBUG(IMPORT_BI_ATTACH)) -    { -  vnc_zlog_debug_verbose ("%s: info_new->peer=%p", __func__, info_new->peer); -  vnc_zlog_debug_verbose ("%s: info_new->peer->su_remote=%p", __func__, -              info_new->peer->su_remote); -    } - -  for (prev = NULL, next = rn->info; next; prev = next, next = next->next) -    { -      if (!bgp || -          (!CHECK_FLAG (info_new->flags, BGP_INFO_REMOVED) && -           CHECK_FLAG (next->flags, BGP_INFO_REMOVED)) || -          bgp_info_cmp_compatible (bgp, info_new, next, pfx_buf, afi, safi) == -1) -        {                       /* -1 if 1st is better */ -          break; -        } -    } -  vnc_zlog_debug_verbose ("%s: prev=%p, next=%p", __func__, prev, next); -  if (prev) -    { -      prev->next = info_new; -    } -  else -    { -      rn->info = info_new; -    } -  info_new->prev = prev; -  info_new->next = next; -  if (next) -    next->prev = info_new; -  bgp_attr_intern (info_new->attr); +	struct bgp *bgp; +	struct bgp_info *prev; +	struct bgp_info *next; +	char pfx_buf[PREFIX2STR_BUFFER]; + + +	bgp = bgp_get_default(); /* assume 1 instance for now */ + +	if (VNC_DEBUG(IMPORT_BI_ATTACH)) { +		vnc_zlog_debug_verbose("%s: info_new->peer=%p", __func__, +				       info_new->peer); +		vnc_zlog_debug_verbose("%s: info_new->peer->su_remote=%p", +				       __func__, info_new->peer->su_remote); +	} + +	for (prev = NULL, next = rn->info; next; +	     prev = next, next = next->next) { +		if (!bgp || (!CHECK_FLAG(info_new->flags, BGP_INFO_REMOVED) +			     && CHECK_FLAG(next->flags, BGP_INFO_REMOVED)) +		    || bgp_info_cmp_compatible(bgp, info_new, next, pfx_buf, +					       afi, safi) +			       == -1) { /* -1 if 1st is better */ +			break; +		} +	} +	vnc_zlog_debug_verbose("%s: prev=%p, next=%p", __func__, prev, next); +	if (prev) { +		prev->next = info_new; +	} else { +		rn->info = info_new; +	} +	info_new->prev = prev; +	info_new->next = next; +	if (next) +		next->prev = info_new; +	bgp_attr_intern(info_new->attr);  } -static void -rfapiBgpInfoDetach (struct route_node *rn, struct bgp_info *bi) +static void rfapiBgpInfoDetach(struct route_node *rn, struct bgp_info *bi)  { -  /* -   * Remove the route (doubly-linked) -   */ -  //  bgp_attr_unintern (&bi->attr); -  if (bi->next) -    bi->next->prev = bi->prev; -  if (bi->prev) -    bi->prev->next = bi->next; -  else -    rn->info = bi->next; +	/* +	 * Remove the route (doubly-linked) +	 */ +	//  bgp_attr_unintern (&bi->attr); +	if (bi->next) +		bi->next->prev = bi->prev; +	if (bi->prev) +		bi->prev->next = bi->next; +	else +		rn->info = bi->next;  }  /*   * For L3-indexed import tables   */ -static int -rfapi_bi_peer_rd_cmp (void *b1, void *b2) +static int rfapi_bi_peer_rd_cmp(void *b1, void *b2)  { -  struct bgp_info *bi1 = b1; -  struct bgp_info *bi2 = b2; - -  /* -   * Compare peers -   */ -  if (bi1->peer < bi2->peer) -    return -1; -  if (bi1->peer > bi2->peer) -    return 1; - -  /* -   * compare RDs -   */ -  return vnc_prefix_cmp ((struct prefix *) &bi1->extra->vnc.import.rd, -                         (struct prefix *) &bi2->extra->vnc.import.rd); +	struct bgp_info *bi1 = b1; +	struct bgp_info *bi2 = b2; + +	/* +	 * Compare peers +	 */ +	if (bi1->peer < bi2->peer) +		return -1; +	if (bi1->peer > bi2->peer) +		return 1; + +	/* +	 * compare RDs +	 */ +	return vnc_prefix_cmp((struct prefix *)&bi1->extra->vnc.import.rd, +			      (struct prefix *)&bi2->extra->vnc.import.rd);  }  /* @@ -2198,765 +2074,717 @@ rfapi_bi_peer_rd_cmp (void *b1, void *b2)   * The BIs in these tables should ALWAYS have an aux_prefix set because   * they arrive via IPv4 or IPv6 advertisements.   */ -static int -rfapi_bi_peer_rd_aux_cmp (void *b1, void *b2) +static int rfapi_bi_peer_rd_aux_cmp(void *b1, void *b2)  { -  struct bgp_info *bi1 = b1; -  struct bgp_info *bi2 = b2; -  int rc; - -  /* -   * Compare peers -   */ -  if (bi1->peer < bi2->peer) -    return -1; -  if (bi1->peer > bi2->peer) -    return 1; - -  /* -   * compare RDs -   */ -  rc = vnc_prefix_cmp ((struct prefix *) &bi1->extra->vnc.import.rd, -                       (struct prefix *) &bi2->extra->vnc.import.rd); -  if (rc) -    { -      return rc; -    } - -  /* -   * L2 import tables can have multiple entries with the -   * same MAC address, same RD, but different L3 addresses. -   * -   * Use presence of aux_prefix with AF=ethernet and prefixlen=1 -   * as magic value to signify explicit wildcarding of the aux_prefix. -   * This magic value will not appear in bona fide bi entries in -   * the import table, but is allowed in the "fake" bi used to -   * probe the table when searching. (We have to test both b1 and b2 -   * because there is no guarantee of the order the test key and -   * the real key will be passed) -   */ -  if ((bi1->extra->vnc.import.aux_prefix.family == AF_ETHERNET && -       (bi1->extra->vnc.import.aux_prefix.prefixlen == 1)) || -      (bi2->extra->vnc.import.aux_prefix.family == AF_ETHERNET && -       (bi2->extra->vnc.import.aux_prefix.prefixlen == 1))) -    { - -      /* -       * wildcard aux address specified -       */ -      return 0; -    } - -  return vnc_prefix_cmp (&bi1->extra->vnc.import.aux_prefix, -                         &bi2->extra->vnc.import.aux_prefix); +	struct bgp_info *bi1 = b1; +	struct bgp_info *bi2 = b2; +	int rc; + +	/* +	 * Compare peers +	 */ +	if (bi1->peer < bi2->peer) +		return -1; +	if (bi1->peer > bi2->peer) +		return 1; + +	/* +	 * compare RDs +	 */ +	rc = vnc_prefix_cmp((struct prefix *)&bi1->extra->vnc.import.rd, +			    (struct prefix *)&bi2->extra->vnc.import.rd); +	if (rc) { +		return rc; +	} + +	/* +	 * L2 import tables can have multiple entries with the +	 * same MAC address, same RD, but different L3 addresses. +	 * +	 * Use presence of aux_prefix with AF=ethernet and prefixlen=1 +	 * as magic value to signify explicit wildcarding of the aux_prefix. +	 * This magic value will not appear in bona fide bi entries in +	 * the import table, but is allowed in the "fake" bi used to +	 * probe the table when searching. (We have to test both b1 and b2 +	 * because there is no guarantee of the order the test key and +	 * the real key will be passed) +	 */ +	if ((bi1->extra->vnc.import.aux_prefix.family == AF_ETHERNET +	     && (bi1->extra->vnc.import.aux_prefix.prefixlen == 1)) +	    || (bi2->extra->vnc.import.aux_prefix.family == AF_ETHERNET +		&& (bi2->extra->vnc.import.aux_prefix.prefixlen == 1))) { + +		/* +		 * wildcard aux address specified +		 */ +		return 0; +	} + +	return vnc_prefix_cmp(&bi1->extra->vnc.import.aux_prefix, +			      &bi2->extra->vnc.import.aux_prefix);  }  /*   * Index on RD and Peer   */ -static void -rfapiItBiIndexAdd ( -  struct route_node	*rn,	/* Import table VPN node */ -  struct bgp_info	*bi)	/* new BI */ +static void rfapiItBiIndexAdd(struct route_node *rn, /* Import table VPN node */ +			      struct bgp_info *bi)   /* new BI */  { -  struct skiplist *sl; - -  assert (rn); -  assert (bi); -  assert (bi->extra); - -  { -    char buf[BUFSIZ]; -    prefix_rd2str (&bi->extra->vnc.import.rd, buf, BUFSIZ); -    vnc_zlog_debug_verbose ("%s: bi %p, peer %p, rd %s", __func__, bi, bi->peer, buf); -  } - -  sl = RFAPI_RDINDEX_W_ALLOC (rn); -  if (!sl) -    { -      if (AF_ETHERNET == rn->p.family) -        { -          sl = skiplist_new (0, rfapi_bi_peer_rd_aux_cmp, NULL); -        } -      else -        { -          sl = skiplist_new (0, rfapi_bi_peer_rd_cmp, NULL); -        } -      RFAPI_IT_EXTRA_GET (rn)->u.vpn.idx_rd = sl; -      route_lock_node (rn);     /* for skiplist */ -    } -  assert (!skiplist_insert (sl, (void *) bi, (void *) bi)); -  route_lock_node (rn);         /* for skiplist entry */ - -  /* NB: BIs in import tables are not refcounted */ +	struct skiplist *sl; + +	assert(rn); +	assert(bi); +	assert(bi->extra); + +	{ +		char buf[BUFSIZ]; +		prefix_rd2str(&bi->extra->vnc.import.rd, buf, BUFSIZ); +		vnc_zlog_debug_verbose("%s: bi %p, peer %p, rd %s", __func__, +				       bi, bi->peer, buf); +	} + +	sl = RFAPI_RDINDEX_W_ALLOC(rn); +	if (!sl) { +		if (AF_ETHERNET == rn->p.family) { +			sl = skiplist_new(0, rfapi_bi_peer_rd_aux_cmp, NULL); +		} else { +			sl = skiplist_new(0, rfapi_bi_peer_rd_cmp, NULL); +		} +		RFAPI_IT_EXTRA_GET(rn)->u.vpn.idx_rd = sl; +		route_lock_node(rn); /* for skiplist */ +	} +	assert(!skiplist_insert(sl, (void *)bi, (void *)bi)); +	route_lock_node(rn); /* for skiplist entry */ + +	/* NB: BIs in import tables are not refcounted */  } -static void -rfapiItBiIndexDump (struct route_node *rn) +static void rfapiItBiIndexDump(struct route_node *rn)  { -  struct skiplist *sl; -  void *cursor = NULL; -  struct bgp_info *k; -  struct bgp_info *v; -  int rc; - -  sl = RFAPI_RDINDEX (rn); -  if (!sl) -    return; - -  for (rc = skiplist_next (sl, (void **) &k, (void **) &v, &cursor); -       !rc; rc = skiplist_next (sl, (void **) &k, (void **) &v, &cursor)) -    { - -      char buf[BUFSIZ]; -      char buf_aux_pfx[BUFSIZ]; - -      prefix_rd2str (&k->extra->vnc.import.rd, buf, BUFSIZ); -      buf_aux_pfx[0] = 0; -      if (k->extra->vnc.import.aux_prefix.family) -        { -          prefix2str (&k->extra->vnc.import.aux_prefix, buf_aux_pfx, BUFSIZ); -        } -      else -        { -          strncpy (buf_aux_pfx, "(none)", BUFSIZ); -          buf_aux_pfx[BUFSIZ - 1] = 0; -        } - -      vnc_zlog_debug_verbose ("bi %p, peer %p, rd %s, aux_prefix %s", k, k->peer, buf, -                  buf_aux_pfx); -    } +	struct skiplist *sl; +	void *cursor = NULL; +	struct bgp_info *k; +	struct bgp_info *v; +	int rc; + +	sl = RFAPI_RDINDEX(rn); +	if (!sl) +		return; + +	for (rc = skiplist_next(sl, (void **)&k, (void **)&v, &cursor); !rc; +	     rc = skiplist_next(sl, (void **)&k, (void **)&v, &cursor)) { + +		char buf[BUFSIZ]; +		char buf_aux_pfx[BUFSIZ]; + +		prefix_rd2str(&k->extra->vnc.import.rd, buf, BUFSIZ); +		buf_aux_pfx[0] = 0; +		if (k->extra->vnc.import.aux_prefix.family) { +			prefix2str(&k->extra->vnc.import.aux_prefix, +				   buf_aux_pfx, BUFSIZ); +		} else { +			strncpy(buf_aux_pfx, "(none)", BUFSIZ); +			buf_aux_pfx[BUFSIZ - 1] = 0; +		} + +		vnc_zlog_debug_verbose("bi %p, peer %p, rd %s, aux_prefix %s", +				       k, k->peer, buf, buf_aux_pfx); +	}  } -static struct bgp_info * -rfapiItBiIndexSearch ( -  struct route_node	*rn,		/* Import table VPN node */ -  struct prefix_rd	*prd, -  struct peer		*peer, -  struct prefix		*aux_prefix)	/* optional L3 addr for L2 ITs */ +static struct bgp_info *rfapiItBiIndexSearch( +	struct route_node *rn, /* Import table VPN node */ +	struct prefix_rd *prd, struct peer *peer, +	struct prefix *aux_prefix) /* optional L3 addr for L2 ITs */  { -  struct skiplist	*sl; -  int			rc; -  struct bgp_info	bi_fake; -  struct bgp_info_extra	bi_extra; -  struct bgp_info	*bi_result; +	struct skiplist *sl; +	int rc; +	struct bgp_info bi_fake; +	struct bgp_info_extra bi_extra; +	struct bgp_info *bi_result; -  sl = RFAPI_RDINDEX (rn); -  if (!sl) -    return NULL; +	sl = RFAPI_RDINDEX(rn); +	if (!sl) +		return NULL;  #if DEBUG_BI_SEARCH -  { -    char buf[BUFSIZ]; -    char buf_aux_pfx[BUFSIZ]; - -    prefix_rd2str (prd, buf, BUFSIZ); -    if (aux_prefix) -      { -        prefix2str (aux_prefix, buf_aux_pfx, BUFSIZ); -      } -    else -      { -        strncpy (buf_aux_pfx, "(nil)", BUFSIZ - 1); -        buf_aux_pfx[BUFSIZ - 1] = 0; -      } - -    vnc_zlog_debug_verbose ("%s want prd=%s, peer=%p, aux_prefix=%s", -                __func__, buf, peer, buf_aux_pfx); -    rfapiItBiIndexDump (rn); -  } +	{ +		char buf[BUFSIZ]; +		char buf_aux_pfx[BUFSIZ]; + +		prefix_rd2str(prd, buf, BUFSIZ); +		if (aux_prefix) { +			prefix2str(aux_prefix, buf_aux_pfx, BUFSIZ); +		} else { +			strncpy(buf_aux_pfx, "(nil)", BUFSIZ - 1); +			buf_aux_pfx[BUFSIZ - 1] = 0; +		} + +		vnc_zlog_debug_verbose("%s want prd=%s, peer=%p, aux_prefix=%s", +				       __func__, buf, peer, buf_aux_pfx); +		rfapiItBiIndexDump(rn); +	}  #endif -  /* threshold is a WAG */ -  if (sl->count < 3) -    { +	/* threshold is a WAG */ +	if (sl->count < 3) {  #if DEBUG_BI_SEARCH -      vnc_zlog_debug_verbose ("%s: short list algorithm", __func__); +		vnc_zlog_debug_verbose("%s: short list algorithm", __func__);  #endif -      /* if short list, linear search might be faster */ -      for (bi_result = rn->info; bi_result; bi_result = bi_result->next) -        { +		/* if short list, linear search might be faster */ +		for (bi_result = rn->info; bi_result; +		     bi_result = bi_result->next) {  #if DEBUG_BI_SEARCH -          { -            char buf[BUFSIZ]; -            prefix_rd2str (&bi_result->extra->vnc.import.rd, buf, BUFSIZ); -            vnc_zlog_debug_verbose ("%s: bi has prd=%s, peer=%p", __func__, -                        buf, bi_result->peer); -          } +			{ +				char buf[BUFSIZ]; +				prefix_rd2str(&bi_result->extra->vnc.import.rd, +					      buf, BUFSIZ); +				vnc_zlog_debug_verbose( +					"%s: bi has prd=%s, peer=%p", __func__, +					buf, bi_result->peer); +			}  #endif -          if (peer == bi_result->peer && -              !prefix_cmp ((struct prefix *) &bi_result->extra->vnc.import.rd, -                           (struct prefix *) prd)) -            { +			if (peer == bi_result->peer +			    && !prefix_cmp((struct prefix *)&bi_result->extra +						   ->vnc.import.rd, +					   (struct prefix *)prd)) {  #if DEBUG_BI_SEARCH -              vnc_zlog_debug_verbose ("%s: peer and RD same, doing aux_prefix check", -                          __func__); +				vnc_zlog_debug_verbose( +					"%s: peer and RD same, doing aux_prefix check", +					__func__);  #endif -              if (!aux_prefix || -                  !prefix_cmp (aux_prefix, -                               &bi_result->extra->vnc.import.aux_prefix)) -                { +				if (!aux_prefix +				    || !prefix_cmp(aux_prefix, +						   &bi_result->extra->vnc.import +							    .aux_prefix)) {  #if DEBUG_BI_SEARCH -                  vnc_zlog_debug_verbose ("%s: match", __func__); +					vnc_zlog_debug_verbose("%s: match", +							       __func__);  #endif -                  break; -                } - -            } -        } -      return bi_result; -    } - -  bi_fake.peer = peer; -  bi_fake.extra = &bi_extra; -  bi_fake.extra->vnc.import.rd = *(struct prefix_rd *) prd; -  if (aux_prefix) -    { -      bi_fake.extra->vnc.import.aux_prefix = *aux_prefix; -    } -  else -    { -      /* wildcard */ -      bi_fake.extra->vnc.import.aux_prefix.family = AF_ETHERNET; -      bi_fake.extra->vnc.import.aux_prefix.prefixlen = 1; -    } - -  rc = skiplist_search (sl, (void *) &bi_fake, (void *) &bi_result); - -  if (rc) -    { +					break; +				} +			} +		} +		return bi_result; +	} + +	bi_fake.peer = peer; +	bi_fake.extra = &bi_extra; +	bi_fake.extra->vnc.import.rd = *(struct prefix_rd *)prd; +	if (aux_prefix) { +		bi_fake.extra->vnc.import.aux_prefix = *aux_prefix; +	} else { +		/* wildcard */ +		bi_fake.extra->vnc.import.aux_prefix.family = AF_ETHERNET; +		bi_fake.extra->vnc.import.aux_prefix.prefixlen = 1; +	} + +	rc = skiplist_search(sl, (void *)&bi_fake, (void *)&bi_result); + +	if (rc) {  #if DEBUG_BI_SEARCH -      vnc_zlog_debug_verbose ("%s: no match", __func__); +		vnc_zlog_debug_verbose("%s: no match", __func__);  #endif -      return NULL; -    } +		return NULL; +	}  #if DEBUG_BI_SEARCH -  vnc_zlog_debug_verbose ("%s: matched bi=%p", __func__, bi_result); +	vnc_zlog_debug_verbose("%s: matched bi=%p", __func__, bi_result);  #endif -  return bi_result; +	return bi_result;  } -static void -rfapiItBiIndexDel ( -  struct route_node	*rn,	/* Import table VPN node */ -  struct bgp_info	*bi)	/* old BI */ +static void rfapiItBiIndexDel(struct route_node *rn, /* Import table VPN node */ +			      struct bgp_info *bi)   /* old BI */  { -  struct skiplist *sl; -  int rc; +	struct skiplist *sl; +	int rc; -  { -    char buf[BUFSIZ]; -    prefix_rd2str (&bi->extra->vnc.import.rd, buf, BUFSIZ); -    vnc_zlog_debug_verbose ("%s: bi %p, peer %p, rd %s", __func__, bi, bi->peer, buf); -  } +	{ +		char buf[BUFSIZ]; +		prefix_rd2str(&bi->extra->vnc.import.rd, buf, BUFSIZ); +		vnc_zlog_debug_verbose("%s: bi %p, peer %p, rd %s", __func__, +				       bi, bi->peer, buf); +	} -  sl = RFAPI_RDINDEX (rn); -  assert (sl); +	sl = RFAPI_RDINDEX(rn); +	assert(sl); -  rc = skiplist_delete (sl, (void *) (bi), (void *) bi); -  if (rc) -    { -      rfapiItBiIndexDump (rn); -    } -  assert (!rc); +	rc = skiplist_delete(sl, (void *)(bi), (void *)bi); +	if (rc) { +		rfapiItBiIndexDump(rn); +	} +	assert(!rc); -  route_unlock_node (rn);       /* for skiplist entry */ +	route_unlock_node(rn); /* for skiplist entry */ -  /* NB: BIs in import tables are not refcounted */ +	/* NB: BIs in import tables are not refcounted */  }  /*   * Add a backreference at the ENCAP node to the VPN route that   * refers to it   */ -static void -rfapiMonitorEncapAdd ( -  struct rfapi_import_table	*import_table, -  struct prefix			*p,		/* VN address */ -  struct route_node		*vpn_rn,	/* VPN node */ -  struct bgp_info		*vpn_bi)	/* VPN bi/route */ +static void rfapiMonitorEncapAdd(struct rfapi_import_table *import_table, +				 struct prefix *p,	  /* VN address */ +				 struct route_node *vpn_rn, /* VPN node */ +				 struct bgp_info *vpn_bi)   /* VPN bi/route */  { -  afi_t				afi = family2afi (p->family); -  struct route_node		*rn; -  struct rfapi_monitor_encap	*m; - -  assert (afi); -  rn = route_node_get (import_table->imported_encap[afi], p);   /* locks rn */ -  assert (rn); - -  m = -    XCALLOC (MTYPE_RFAPI_MONITOR_ENCAP, sizeof (struct rfapi_monitor_encap)); -  assert (m); - -  m->node = vpn_rn; -  m->bi = vpn_bi; -  m->rn = rn; - -  /* insert to encap node's list */ -  m->next = RFAPI_MONITOR_ENCAP (rn); -  if (m->next) -    m->next->prev = m; -  RFAPI_MONITOR_ENCAP_W_ALLOC (rn) = m; - -  /* for easy lookup when deleting vpn route */ -  vpn_bi->extra->vnc.import.hme = m; - -  vnc_zlog_debug_verbose -    ("%s: it=%p, vpn_bi=%p, afi=%d, encap rn=%p, setting vpn_bi->extra->vnc.import.hme=%p", -     __func__, import_table, vpn_bi, afi, rn, m); - -  RFAPI_CHECK_REFCOUNT (rn, SAFI_ENCAP, 0); -  bgp_attr_intern (vpn_bi->attr); +	afi_t afi = family2afi(p->family); +	struct route_node *rn; +	struct rfapi_monitor_encap *m; + +	assert(afi); +	rn = route_node_get(import_table->imported_encap[afi], +			    p); /* locks rn */ +	assert(rn); + +	m = XCALLOC(MTYPE_RFAPI_MONITOR_ENCAP, +		    sizeof(struct rfapi_monitor_encap)); +	assert(m); + +	m->node = vpn_rn; +	m->bi = vpn_bi; +	m->rn = rn; + +	/* insert to encap node's list */ +	m->next = RFAPI_MONITOR_ENCAP(rn); +	if (m->next) +		m->next->prev = m; +	RFAPI_MONITOR_ENCAP_W_ALLOC(rn) = m; + +	/* for easy lookup when deleting vpn route */ +	vpn_bi->extra->vnc.import.hme = m; + +	vnc_zlog_debug_verbose( +		"%s: it=%p, vpn_bi=%p, afi=%d, encap rn=%p, setting vpn_bi->extra->vnc.import.hme=%p", +		__func__, import_table, vpn_bi, afi, rn, m); + +	RFAPI_CHECK_REFCOUNT(rn, SAFI_ENCAP, 0); +	bgp_attr_intern(vpn_bi->attr);  } -static void -rfapiMonitorEncapDelete (struct bgp_info *vpn_bi) +static void rfapiMonitorEncapDelete(struct bgp_info *vpn_bi)  { -  /* -   * Remove encap monitor -   */ -  vnc_zlog_debug_verbose ("%s: vpn_bi=%p", __func__, vpn_bi); -  if (vpn_bi->extra) -    { -      struct rfapi_monitor_encap *hme = vpn_bi->extra->vnc.import.hme; - -      if (hme) -        { - -          vnc_zlog_debug_verbose ("%s: hme=%p", __func__, hme); - -          /* Refcount checking takes too long here */ -          //RFAPI_CHECK_REFCOUNT(hme->rn, SAFI_ENCAP, 0); -          if (hme->next) -            hme->next->prev = hme->prev; -          if (hme->prev) -            hme->prev->next = hme->next; -          else -            RFAPI_MONITOR_ENCAP_W_ALLOC (hme->rn) = hme->next; -          /* Refcount checking takes too long here */ -          //RFAPI_CHECK_REFCOUNT(hme->rn, SAFI_ENCAP, 1); - -          /* see if the struct rfapi_it_extra is empty and can be freed */ -          rfapiMonitorExtraPrune (SAFI_ENCAP, hme->rn); - -          route_unlock_node (hme->rn);  /* decr ref count */ -          XFREE (MTYPE_RFAPI_MONITOR_ENCAP, hme); -          vpn_bi->extra->vnc.import.hme = NULL; -        } -    } +	/* +	 * Remove encap monitor +	 */ +	vnc_zlog_debug_verbose("%s: vpn_bi=%p", __func__, vpn_bi); +	if (vpn_bi->extra) { +		struct rfapi_monitor_encap *hme = vpn_bi->extra->vnc.import.hme; + +		if (hme) { + +			vnc_zlog_debug_verbose("%s: hme=%p", __func__, hme); + +			/* Refcount checking takes too long here */ +			// RFAPI_CHECK_REFCOUNT(hme->rn, SAFI_ENCAP, 0); +			if (hme->next) +				hme->next->prev = hme->prev; +			if (hme->prev) +				hme->prev->next = hme->next; +			else +				RFAPI_MONITOR_ENCAP_W_ALLOC(hme->rn) = +					hme->next; +			/* Refcount checking takes too long here */ +			// RFAPI_CHECK_REFCOUNT(hme->rn, SAFI_ENCAP, 1); + +			/* see if the struct rfapi_it_extra is empty and can be +			 * freed */ +			rfapiMonitorExtraPrune(SAFI_ENCAP, hme->rn); + +			route_unlock_node(hme->rn); /* decr ref count */ +			XFREE(MTYPE_RFAPI_MONITOR_ENCAP, hme); +			vpn_bi->extra->vnc.import.hme = NULL; +		} +	}  }  /*   * quagga lib/thread.h says this must return int even though   * it doesn't do anything with the return value   */ -static int -rfapiWithdrawTimerVPN (struct thread *t) +static int rfapiWithdrawTimerVPN(struct thread *t)  { -  struct rfapi_withdraw *wcb = t->arg; -  struct bgp_info *bi = wcb->info; -  struct bgp *bgp = bgp_get_default (); - -  struct rfapi_monitor_vpn *moved; -  afi_t afi; - -  assert (wcb->node); -  assert (bi); -  assert (wcb->import_table); -  assert (bi->extra); - -  RFAPI_CHECK_REFCOUNT (wcb->node, SAFI_MPLS_VPN, wcb->lockoffset); - -  { -    char buf[BUFSIZ]; - -    vnc_zlog_debug_verbose ("%s: removing bi %p at prefix %s/%d", -                __func__, -                bi, -                rfapi_ntop (wcb->node->p.family, &wcb->node->p.u.prefix, buf, -                            BUFSIZ), wcb->node->p.prefixlen); -  } - -  /* -   * Remove the route (doubly-linked) -   */ -  if (CHECK_FLAG (bi->flags, BGP_INFO_VALID) -      && VALID_INTERIOR_TYPE (bi->type)) -    RFAPI_MONITOR_EXTERIOR (wcb->node)->valid_interior_count--; - -  afi = family2afi (wcb->node->p.family); -  wcb->import_table->holddown_count[afi] -= 1;  /* keep count consistent */ -  rfapiItBiIndexDel (wcb->node, bi); -  rfapiBgpInfoDetach (wcb->node, bi);   /* with removed bi */ - -  vnc_import_bgp_exterior_del_route_interior (bgp, wcb->import_table, -                                              wcb->node, bi); - - -  /* -   * If VNC is configured to send response remove messages, AND -   * if the removed route had a UN address, do response removal -   * processing. -   */ -  if (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE)) -    { - -      int has_valid_duplicate = 0; -      struct bgp_info *bii; - -      /* -       * First check if there are any OTHER routes at this node -       * that have the same nexthop and a valid UN address. If -       * there are (e.g., from other peers), then the route isn't -       * really gone, so skip sending a response removal message. -       */ -      for (bii = wcb->node->info; bii; bii = bii->next) -        { -          if (rfapiVpnBiSamePtUn (bi, bii)) -            { -              has_valid_duplicate = 1; -              break; -            } -        } - -      vnc_zlog_debug_verbose ("%s: has_valid_duplicate=%d", __func__, -                  has_valid_duplicate); - -      if (!has_valid_duplicate) -        { -	  rfapiRibPendingDeleteRoute (bgp, wcb->import_table, afi, wcb->node); -        } -    } - -  rfapiMonitorEncapDelete (bi); - -  /* -   * If there are no VPN monitors at this VPN Node A, -   * we are done -   */ -  if (!RFAPI_MONITOR_VPN (wcb->node)) -    { -      vnc_zlog_debug_verbose ("%s: no VPN monitors at this node", __func__); -      goto done; -    } - -  /* -   * rfapiMonitorMoveShorter only moves monitors if there are -   * no remaining valid routes at the current node -   */ -  moved = rfapiMonitorMoveShorter (wcb->node, 1); - -  if (moved) -    { -      rfapiMonitorMovedUp (wcb->import_table, wcb->node, moved->node, moved); -    } +	struct rfapi_withdraw *wcb = t->arg; +	struct bgp_info *bi = wcb->info; +	struct bgp *bgp = bgp_get_default(); + +	struct rfapi_monitor_vpn *moved; +	afi_t afi; + +	assert(wcb->node); +	assert(bi); +	assert(wcb->import_table); +	assert(bi->extra); + +	RFAPI_CHECK_REFCOUNT(wcb->node, SAFI_MPLS_VPN, wcb->lockoffset); + +	{ +		char buf[BUFSIZ]; + +		vnc_zlog_debug_verbose( +			"%s: removing bi %p at prefix %s/%d", __func__, bi, +			rfapi_ntop(wcb->node->p.family, &wcb->node->p.u.prefix, +				   buf, BUFSIZ), +			wcb->node->p.prefixlen); +	} + +	/* +	 * Remove the route (doubly-linked) +	 */ +	if (CHECK_FLAG(bi->flags, BGP_INFO_VALID) +	    && VALID_INTERIOR_TYPE(bi->type)) +		RFAPI_MONITOR_EXTERIOR(wcb->node)->valid_interior_count--; + +	afi = family2afi(wcb->node->p.family); +	wcb->import_table->holddown_count[afi] -= 1; /* keep count consistent */ +	rfapiItBiIndexDel(wcb->node, bi); +	rfapiBgpInfoDetach(wcb->node, bi); /* with removed bi */ + +	vnc_import_bgp_exterior_del_route_interior(bgp, wcb->import_table, +						   wcb->node, bi); + + +	/* +	 * If VNC is configured to send response remove messages, AND +	 * if the removed route had a UN address, do response removal +	 * processing. +	 */ +	if (!(bgp->rfapi_cfg->flags +	      & BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE)) { + +		int has_valid_duplicate = 0; +		struct bgp_info *bii; + +		/* +		 * First check if there are any OTHER routes at this node +		 * that have the same nexthop and a valid UN address. If +		 * there are (e.g., from other peers), then the route isn't +		 * really gone, so skip sending a response removal message. +		 */ +		for (bii = wcb->node->info; bii; bii = bii->next) { +			if (rfapiVpnBiSamePtUn(bi, bii)) { +				has_valid_duplicate = 1; +				break; +			} +		} + +		vnc_zlog_debug_verbose("%s: has_valid_duplicate=%d", __func__, +				       has_valid_duplicate); + +		if (!has_valid_duplicate) { +			rfapiRibPendingDeleteRoute(bgp, wcb->import_table, afi, +						   wcb->node); +		} +	} + +	rfapiMonitorEncapDelete(bi); + +	/* +	 * If there are no VPN monitors at this VPN Node A, +	 * we are done +	 */ +	if (!RFAPI_MONITOR_VPN(wcb->node)) { +		vnc_zlog_debug_verbose("%s: no VPN monitors at this node", +				       __func__); +		goto done; +	} + +	/* +	 * rfapiMonitorMoveShorter only moves monitors if there are +	 * no remaining valid routes at the current node +	 */ +	moved = rfapiMonitorMoveShorter(wcb->node, 1); + +	if (moved) { +		rfapiMonitorMovedUp(wcb->import_table, wcb->node, moved->node, +				    moved); +	}  done: -  /* -   * Free VPN bi -   */ -  rfapiBgpInfoFree (bi); -  wcb->info = NULL; - -  /* -   * If route count at this node has gone to 0, withdraw exported prefix -   */ -  if (!wcb->node->info) -    { -      /* see if the struct rfapi_it_extra is empty and can be freed */ -      rfapiMonitorExtraPrune (SAFI_MPLS_VPN, wcb->node); -      vnc_direct_bgp_del_prefix (bgp, wcb->import_table, wcb->node); -      vnc_zebra_del_prefix (bgp, wcb->import_table, wcb->node); -    } -  else -    { -      /* -       * nexthop change event -       * vnc_direct_bgp_add_prefix() will recompute the VN addr ecommunity -       */ -      vnc_direct_bgp_add_prefix (bgp, wcb->import_table, wcb->node); -    } - -  RFAPI_CHECK_REFCOUNT (wcb->node, SAFI_MPLS_VPN, 1 + wcb->lockoffset); -  route_unlock_node (wcb->node);        /* decr ref count */ -  XFREE (MTYPE_RFAPI_WITHDRAW, wcb); -  return 0; +	/* +	 * Free VPN bi +	 */ +	rfapiBgpInfoFree(bi); +	wcb->info = NULL; + +	/* +	 * If route count at this node has gone to 0, withdraw exported prefix +	 */ +	if (!wcb->node->info) { +		/* see if the struct rfapi_it_extra is empty and can be freed */ +		rfapiMonitorExtraPrune(SAFI_MPLS_VPN, wcb->node); +		vnc_direct_bgp_del_prefix(bgp, wcb->import_table, wcb->node); +		vnc_zebra_del_prefix(bgp, wcb->import_table, wcb->node); +	} else { +		/* +		 * nexthop change event +		 * vnc_direct_bgp_add_prefix() will recompute the VN addr +		 * ecommunity +		 */ +		vnc_direct_bgp_add_prefix(bgp, wcb->import_table, wcb->node); +	} + +	RFAPI_CHECK_REFCOUNT(wcb->node, SAFI_MPLS_VPN, 1 + wcb->lockoffset); +	route_unlock_node(wcb->node); /* decr ref count */ +	XFREE(MTYPE_RFAPI_WITHDRAW, wcb); +	return 0;  }  /*   * This works for multiprotocol extension, but not for plain ol'   * unicast IPv4 because that nexthop is stored in attr->nexthop   */ -void -rfapiNexthop2Prefix (struct attr *attr, struct prefix *p) +void rfapiNexthop2Prefix(struct attr *attr, struct prefix *p)  { -  assert (p); -  assert (attr); - -  memset (p, 0, sizeof (struct prefix)); - -  switch (p->family = BGP_MP_NEXTHOP_FAMILY (attr->mp_nexthop_len)) -    { -    case AF_INET: -      p->u.prefix4 = attr->mp_nexthop_global_in; -      p->prefixlen = 32; -      break; - -    case AF_INET6: -      p->u.prefix6 = attr->mp_nexthop_global; -      p->prefixlen = 128; -      break; - -    default: -      vnc_zlog_debug_verbose ("%s: Family is unknown = %d", -                  __func__, p->family); -    } +	assert(p); +	assert(attr); + +	memset(p, 0, sizeof(struct prefix)); + +	switch (p->family = BGP_MP_NEXTHOP_FAMILY(attr->mp_nexthop_len)) { +	case AF_INET: +		p->u.prefix4 = attr->mp_nexthop_global_in; +		p->prefixlen = 32; +		break; + +	case AF_INET6: +		p->u.prefix6 = attr->mp_nexthop_global; +		p->prefixlen = 128; +		break; + +	default: +		vnc_zlog_debug_verbose("%s: Family is unknown = %d", __func__, +				       p->family); +	}  } -void -rfapiUnicastNexthop2Prefix (afi_t afi, struct attr *attr, struct prefix *p) +void rfapiUnicastNexthop2Prefix(afi_t afi, struct attr *attr, struct prefix *p)  { -  if (afi == AFI_IP) -    { -      p->family = AF_INET; -      p->prefixlen = 32; -      p->u.prefix4 = attr->nexthop; -    } -  else -    { -      rfapiNexthop2Prefix (attr, p); -    } +	if (afi == AFI_IP) { +		p->family = AF_INET; +		p->prefixlen = 32; +		p->u.prefix4 = attr->nexthop; +	} else { +		rfapiNexthop2Prefix(attr, p); +	}  } -static int -rfapiAttrNexthopAddrDifferent (struct prefix *p1, struct prefix *p2) +static int rfapiAttrNexthopAddrDifferent(struct prefix *p1, struct prefix *p2)  { -  if (!p1 || !p2) -    { -      vnc_zlog_debug_verbose ("%s: p1 or p2 is NULL", __func__); -      return 1; -    } - -  /* -   * Are address families the same? -   */ -  if (p1->family != p2->family) -    { -      return 1; -    } - -  switch (p1->family) -    { -    case AF_INET: -      if (IPV4_ADDR_SAME (&p1->u.prefix4, &p2->u.prefix4)) -        return 0; -      break; - -    case AF_INET6: -      if (IPV6_ADDR_SAME (&p1->u.prefix6, &p2->u.prefix6)) -        return 0; -      break; - -    default: -      assert (1); - -    } - -  return 1; +	if (!p1 || !p2) { +		vnc_zlog_debug_verbose("%s: p1 or p2 is NULL", __func__); +		return 1; +	} + +	/* +	 * Are address families the same? +	 */ +	if (p1->family != p2->family) { +		return 1; +	} + +	switch (p1->family) { +	case AF_INET: +		if (IPV4_ADDR_SAME(&p1->u.prefix4, &p2->u.prefix4)) +			return 0; +		break; + +	case AF_INET6: +		if (IPV6_ADDR_SAME(&p1->u.prefix6, &p2->u.prefix6)) +			return 0; +		break; + +	default: +		assert(1); +	} + +	return 1;  } -static void -rfapiCopyUnEncap2VPN (struct bgp_info *encap_bi, struct bgp_info *vpn_bi) +static void rfapiCopyUnEncap2VPN(struct bgp_info *encap_bi, +				 struct bgp_info *vpn_bi)  { -  if (!encap_bi->attr) -    { -      zlog_warn ("%s: no encap bi attr/extra, can't copy UN address", -                 __func__); -      return; -    } - -  if (!vpn_bi || !vpn_bi->extra) -    { -      zlog_warn ("%s: no vpn  bi attr/extra, can't copy UN address", -                 __func__); -      return; -    } - -  switch (BGP_MP_NEXTHOP_FAMILY (encap_bi->attr->mp_nexthop_len)) -    { -    case AF_INET: - -      /* -       * instrumentation to debug segfault of 091127 -       */ -      vnc_zlog_debug_verbose ("%s: vpn_bi=%p", __func__, vpn_bi); -      if (vpn_bi) -        { -          vnc_zlog_debug_verbose ("%s: vpn_bi->extra=%p", __func__, vpn_bi->extra); -        } - -      vpn_bi->extra->vnc.import.un_family = AF_INET; -      vpn_bi->extra->vnc.import.un.addr4 = encap_bi->attr->mp_nexthop_global_in; -      break; - -    case AF_INET6: -      vpn_bi->extra->vnc.import.un_family = AF_INET6; -      vpn_bi->extra->vnc.import.un.addr6 = encap_bi->attr->mp_nexthop_global; -      break; - -    default: -      zlog_warn ("%s: invalid encap nexthop length: %d", -                 __func__, encap_bi->attr->mp_nexthop_len); -      vpn_bi->extra->vnc.import.un_family = 0; -      break; -    } +	if (!encap_bi->attr) { +		zlog_warn("%s: no encap bi attr/extra, can't copy UN address", +			  __func__); +		return; +	} + +	if (!vpn_bi || !vpn_bi->extra) { +		zlog_warn("%s: no vpn  bi attr/extra, can't copy UN address", +			  __func__); +		return; +	} + +	switch (BGP_MP_NEXTHOP_FAMILY(encap_bi->attr->mp_nexthop_len)) { +	case AF_INET: + +		/* +		 * instrumentation to debug segfault of 091127 +		 */ +		vnc_zlog_debug_verbose("%s: vpn_bi=%p", __func__, vpn_bi); +		if (vpn_bi) { +			vnc_zlog_debug_verbose("%s: vpn_bi->extra=%p", __func__, +					       vpn_bi->extra); +		} + +		vpn_bi->extra->vnc.import.un_family = AF_INET; +		vpn_bi->extra->vnc.import.un.addr4 = +			encap_bi->attr->mp_nexthop_global_in; +		break; + +	case AF_INET6: +		vpn_bi->extra->vnc.import.un_family = AF_INET6; +		vpn_bi->extra->vnc.import.un.addr6 = +			encap_bi->attr->mp_nexthop_global; +		break; + +	default: +		zlog_warn("%s: invalid encap nexthop length: %d", __func__, +			  encap_bi->attr->mp_nexthop_len); +		vpn_bi->extra->vnc.import.un_family = 0; +		break; +	}  }  /*   * returns 0 on success, nonzero on error   */ -static int -rfapiWithdrawEncapUpdateCachedUn ( -  struct rfapi_import_table	*import_table, -  struct bgp_info		*encap_bi, -  struct route_node		*vpn_rn, -  struct bgp_info		*vpn_bi) +static int rfapiWithdrawEncapUpdateCachedUn( +	struct rfapi_import_table *import_table, struct bgp_info *encap_bi, +	struct route_node *vpn_rn, struct bgp_info *vpn_bi)  { -  if (!encap_bi) -    { - -      /*  -       * clear cached UN address -       */ -      if (!vpn_bi || !vpn_bi->extra) -        { -          zlog_warn ("%s: missing VPN bi/extra, can't clear UN addr", -                     __func__); -          return 1; -        } -      vpn_bi->extra->vnc.import.un_family = 0; -      memset (&vpn_bi->extra->vnc.import.un, 0, -              sizeof (vpn_bi->extra->vnc.import.un)); -      if (CHECK_FLAG (vpn_bi->flags, BGP_INFO_VALID)) -        { -          if (rfapiGetVncTunnelUnAddr (vpn_bi->attr, NULL)) -            { -              UNSET_FLAG (vpn_bi->flags, BGP_INFO_VALID); -              if (VALID_INTERIOR_TYPE (vpn_bi->type)) -                RFAPI_MONITOR_EXTERIOR (vpn_rn)->valid_interior_count--; -              /* signal interior route withdrawal to import-exterior */ -              vnc_import_bgp_exterior_del_route_interior (bgp_get_default (), -                                                          import_table, -                                                          vpn_rn, vpn_bi); -            } -        } - -    } -  else -    { -      if (!vpn_bi) -        { -          zlog_warn ("%s: missing VPN bi, can't clear UN addr", __func__); -          return 1; -        } -      rfapiCopyUnEncap2VPN (encap_bi, vpn_bi); -      if (!CHECK_FLAG (vpn_bi->flags, BGP_INFO_VALID)) -        { -          SET_FLAG (vpn_bi->flags, BGP_INFO_VALID); -          if (VALID_INTERIOR_TYPE (vpn_bi->type)) -            RFAPI_MONITOR_EXTERIOR (vpn_rn)->valid_interior_count++; -          /* signal interior route withdrawal to import-exterior */ -          vnc_import_bgp_exterior_add_route_interior (bgp_get_default (), -                                                      import_table, -                                                      vpn_rn, vpn_bi); -        } -    } -  return 0; +	if (!encap_bi) { + +		/* +		 * clear cached UN address +		 */ +		if (!vpn_bi || !vpn_bi->extra) { +			zlog_warn( +				"%s: missing VPN bi/extra, can't clear UN addr", +				__func__); +			return 1; +		} +		vpn_bi->extra->vnc.import.un_family = 0; +		memset(&vpn_bi->extra->vnc.import.un, 0, +		       sizeof(vpn_bi->extra->vnc.import.un)); +		if (CHECK_FLAG(vpn_bi->flags, BGP_INFO_VALID)) { +			if (rfapiGetVncTunnelUnAddr(vpn_bi->attr, NULL)) { +				UNSET_FLAG(vpn_bi->flags, BGP_INFO_VALID); +				if (VALID_INTERIOR_TYPE(vpn_bi->type)) +					RFAPI_MONITOR_EXTERIOR(vpn_rn) +						->valid_interior_count--; +				/* signal interior route withdrawal to +				 * import-exterior */ +				vnc_import_bgp_exterior_del_route_interior( +					bgp_get_default(), import_table, vpn_rn, +					vpn_bi); +			} +		} + +	} else { +		if (!vpn_bi) { +			zlog_warn("%s: missing VPN bi, can't clear UN addr", +				  __func__); +			return 1; +		} +		rfapiCopyUnEncap2VPN(encap_bi, vpn_bi); +		if (!CHECK_FLAG(vpn_bi->flags, BGP_INFO_VALID)) { +			SET_FLAG(vpn_bi->flags, BGP_INFO_VALID); +			if (VALID_INTERIOR_TYPE(vpn_bi->type)) +				RFAPI_MONITOR_EXTERIOR(vpn_rn) +					->valid_interior_count++; +			/* signal interior route withdrawal to import-exterior +			 */ +			vnc_import_bgp_exterior_add_route_interior( +				bgp_get_default(), import_table, vpn_rn, +				vpn_bi); +		} +	} +	return 0;  } -static int -rfapiWithdrawTimerEncap (struct thread *t) +static int rfapiWithdrawTimerEncap(struct thread *t)  { -  struct rfapi_withdraw *wcb = t->arg; -  struct bgp_info *bi = wcb->info; -  int was_first_route = 0; -  struct rfapi_monitor_encap *em; -  struct skiplist *vpn_node_sl = skiplist_new (0, NULL, NULL); - -  assert (wcb->node); -  assert (bi); -  assert (wcb->import_table); - -  RFAPI_CHECK_REFCOUNT (wcb->node, SAFI_ENCAP, 0); - -  if (wcb->node->info == bi) -    was_first_route = 1; - -  /* -   * Remove the route/bi and free it -   */ -  rfapiBgpInfoDetach (wcb->node, bi); -  rfapiBgpInfoFree (bi); - -  if (!was_first_route) -    goto done; - -  for (em = RFAPI_MONITOR_ENCAP (wcb->node); em; em = em->next) -    { - -      /* -       * Update monitoring VPN BIs with new encap info at the -       * head of the encap bi chain (which could be NULL after -       * removing the expiring bi above) -       */ -      if (rfapiWithdrawEncapUpdateCachedUn -          (wcb->import_table, wcb->node->info, em->node, em->bi)) -        continue; - -      /* -       * Build a list of unique VPN nodes referenced by these monitors. -       * Use a skiplist for speed. -       */ -      skiplist_insert (vpn_node_sl, em->node, em->node); -    } - - -  /* -   * for each VPN node referenced in the ENCAP monitors: -   */ -  struct route_node *rn; -  while (!skiplist_first (vpn_node_sl, (void **) &rn, NULL)) -    { -      if (!wcb->node->info) -        { -          struct rfapi_monitor_vpn *moved; - -          moved = rfapiMonitorMoveShorter (rn, 0); -          if (moved) -            { -              //rfapiDoRouteCallback(wcb->import_table, moved->node, moved); -              rfapiMonitorMovedUp (wcb->import_table, rn, moved->node, moved); -            } -        } -      else -        { -          //rfapiDoRouteCallback(wcb->import_table, rn, NULL); -          rfapiMonitorItNodeChanged (wcb->import_table, rn, NULL); -        } -      skiplist_delete_first (vpn_node_sl); -    } +	struct rfapi_withdraw *wcb = t->arg; +	struct bgp_info *bi = wcb->info; +	int was_first_route = 0; +	struct rfapi_monitor_encap *em; +	struct skiplist *vpn_node_sl = skiplist_new(0, NULL, NULL); + +	assert(wcb->node); +	assert(bi); +	assert(wcb->import_table); + +	RFAPI_CHECK_REFCOUNT(wcb->node, SAFI_ENCAP, 0); + +	if (wcb->node->info == bi) +		was_first_route = 1; + +	/* +	 * Remove the route/bi and free it +	 */ +	rfapiBgpInfoDetach(wcb->node, bi); +	rfapiBgpInfoFree(bi); + +	if (!was_first_route) +		goto done; + +	for (em = RFAPI_MONITOR_ENCAP(wcb->node); em; em = em->next) { + +		/* +		 * Update monitoring VPN BIs with new encap info at the +		 * head of the encap bi chain (which could be NULL after +		 * removing the expiring bi above) +		 */ +		if (rfapiWithdrawEncapUpdateCachedUn(wcb->import_table, +						     wcb->node->info, em->node, +						     em->bi)) +			continue; + +		/* +		 * Build a list of unique VPN nodes referenced by these +		 * monitors. +		 * Use a skiplist for speed. +		 */ +		skiplist_insert(vpn_node_sl, em->node, em->node); +	} + + +	/* +	 * for each VPN node referenced in the ENCAP monitors: +	 */ +	struct route_node *rn; +	while (!skiplist_first(vpn_node_sl, (void **)&rn, NULL)) { +		if (!wcb->node->info) { +			struct rfapi_monitor_vpn *moved; + +			moved = rfapiMonitorMoveShorter(rn, 0); +			if (moved) { +				// rfapiDoRouteCallback(wcb->import_table, +				// moved->node, moved); +				rfapiMonitorMovedUp(wcb->import_table, rn, +						    moved->node, moved); +			} +		} else { +			// rfapiDoRouteCallback(wcb->import_table, rn, NULL); +			rfapiMonitorItNodeChanged(wcb->import_table, rn, NULL); +		} +		skiplist_delete_first(vpn_node_sl); +	}  done: -  RFAPI_CHECK_REFCOUNT (wcb->node, SAFI_ENCAP, 1); -  route_unlock_node (wcb->node);        /* decr ref count */ -  XFREE (MTYPE_RFAPI_WITHDRAW, wcb); -  skiplist_free (vpn_node_sl); -  return 0; +	RFAPI_CHECK_REFCOUNT(wcb->node, SAFI_ENCAP, 1); +	route_unlock_node(wcb->node); /* decr ref count */ +	XFREE(MTYPE_RFAPI_WITHDRAW, wcb); +	skiplist_free(vpn_node_sl); +	return 0;  } @@ -2965,1391 +2793,1272 @@ done:   * in each case   */  static void -rfapiBiStartWithdrawTimer ( -  struct rfapi_import_table	*import_table, -  struct route_node		*rn, -  struct bgp_info		*bi, -  afi_t				afi, -  safi_t			safi, -  int				(*timer_service_func) (struct thread *)) +rfapiBiStartWithdrawTimer(struct rfapi_import_table *import_table, +			  struct route_node *rn, struct bgp_info *bi, afi_t afi, +			  safi_t safi, +			  int (*timer_service_func)(struct thread *))  { -  uint32_t lifetime; -  struct rfapi_withdraw *wcb; - -  if CHECK_FLAG -    (bi->flags, BGP_INFO_REMOVED) -    { -      /* -       * Already on the path to being withdrawn, -       * should already have a timer set up to -       * delete it. -       */ -      vnc_zlog_debug_verbose ("%s: already being withdrawn, do nothing", __func__); -      return; -    } - -  rfapiGetVncLifetime (bi->attr, &lifetime); -  vnc_zlog_debug_verbose ("%s: VNC lifetime is %u", __func__, lifetime); - -  /* -   * withdrawn routes get to hang around for a while -   */ -  SET_FLAG (bi->flags, BGP_INFO_REMOVED); - -  /* set timer to remove the route later */ -  lifetime = rfapiGetHolddownFromLifetime (lifetime); -  vnc_zlog_debug_verbose ("%s: using timeout %u", __func__, lifetime); - -  /* -   * Stash import_table, node, and info for use by timer -   * service routine, which is supposed to free the wcb. -   */ -  wcb = XCALLOC (MTYPE_RFAPI_WITHDRAW, sizeof (struct rfapi_withdraw)); -  assert (wcb); -  wcb->node = rn; -  wcb->info = bi; -  wcb->import_table = import_table; -  bgp_attr_intern (bi->attr); - -  if (VNC_DEBUG(VERBOSE)) -    { -      vnc_zlog_debug_verbose -         ("%s: wcb values: node=%p, info=%p, import_table=%p (bi follows)", -          __func__, wcb->node, wcb->info, wcb->import_table); -      rfapiPrintBi (NULL, bi); -    } - - -  assert (bi->extra); -  if (lifetime > UINT32_MAX / 1001) -    { -      /* sub-optimal case, but will probably never happen */ -      bi->extra->vnc.import.timer = NULL; -      thread_add_timer(bm->master, timer_service_func, wcb, lifetime, -                       &bi->extra->vnc.import.timer); -    } -  else -    { -      static uint32_t jitter; -      uint32_t lifetime_msec; - -      /*  -       * the goal here is to spread out the timers so they are -       * sortable in the skip list -       */ -      if (++jitter >= 1000) -        jitter = 0; - -      lifetime_msec = (lifetime * 1000) + jitter; - -      bi->extra->vnc.import.timer = NULL; -      thread_add_timer_msec(bm->master, timer_service_func, wcb, lifetime_msec, -                            &bi->extra->vnc.import.timer); -    } - -  /* re-sort route list (BGP_INFO_REMOVED routes are last) */ -  if (((struct bgp_info *) rn->info)->next) -    { -      rfapiBgpInfoDetach (rn, bi); -      rfapiBgpInfoAttachSorted (rn, bi, afi, safi); -    } +	uint32_t lifetime; +	struct rfapi_withdraw *wcb; + +	if +		CHECK_FLAG(bi->flags, BGP_INFO_REMOVED) +		{ +			/* +			 * Already on the path to being withdrawn, +			 * should already have a timer set up to +			 * delete it. +			 */ +			vnc_zlog_debug_verbose( +				"%s: already being withdrawn, do nothing", +				__func__); +			return; +		} + +	rfapiGetVncLifetime(bi->attr, &lifetime); +	vnc_zlog_debug_verbose("%s: VNC lifetime is %u", __func__, lifetime); + +	/* +	 * withdrawn routes get to hang around for a while +	 */ +	SET_FLAG(bi->flags, BGP_INFO_REMOVED); + +	/* set timer to remove the route later */ +	lifetime = rfapiGetHolddownFromLifetime(lifetime); +	vnc_zlog_debug_verbose("%s: using timeout %u", __func__, lifetime); + +	/* +	 * Stash import_table, node, and info for use by timer +	 * service routine, which is supposed to free the wcb. +	 */ +	wcb = XCALLOC(MTYPE_RFAPI_WITHDRAW, sizeof(struct rfapi_withdraw)); +	assert(wcb); +	wcb->node = rn; +	wcb->info = bi; +	wcb->import_table = import_table; +	bgp_attr_intern(bi->attr); + +	if (VNC_DEBUG(VERBOSE)) { +		vnc_zlog_debug_verbose( +			"%s: wcb values: node=%p, info=%p, import_table=%p (bi follows)", +			__func__, wcb->node, wcb->info, wcb->import_table); +		rfapiPrintBi(NULL, bi); +	} + + +	assert(bi->extra); +	if (lifetime > UINT32_MAX / 1001) { +		/* sub-optimal case, but will probably never happen */ +		bi->extra->vnc.import.timer = NULL; +		thread_add_timer(bm->master, timer_service_func, wcb, lifetime, +				 &bi->extra->vnc.import.timer); +	} else { +		static uint32_t jitter; +		uint32_t lifetime_msec; + +		/* +		 * the goal here is to spread out the timers so they are +		 * sortable in the skip list +		 */ +		if (++jitter >= 1000) +			jitter = 0; + +		lifetime_msec = (lifetime * 1000) + jitter; + +		bi->extra->vnc.import.timer = NULL; +		thread_add_timer_msec(bm->master, timer_service_func, wcb, +				      lifetime_msec, +				      &bi->extra->vnc.import.timer); +	} + +	/* re-sort route list (BGP_INFO_REMOVED routes are last) */ +	if (((struct bgp_info *)rn->info)->next) { +		rfapiBgpInfoDetach(rn, bi); +		rfapiBgpInfoAttachSorted(rn, bi, afi, safi); +	}  } -typedef void (rfapi_bi_filtered_import_f) (struct rfapi_import_table *, -                                           int, -                                           struct peer *, -                                           void *, -                                           struct prefix *, -                                           struct prefix *, -                                           afi_t, -                                           struct prefix_rd *, -                                           struct attr *, -                                           u_char, u_char, uint32_t *); +typedef void(rfapi_bi_filtered_import_f)(struct rfapi_import_table *, int, +					 struct peer *, void *, struct prefix *, +					 struct prefix *, afi_t, +					 struct prefix_rd *, struct attr *, +					 u_char, u_char, uint32_t *); -static void -rfapiExpireEncapNow ( -  struct rfapi_import_table	*it, -  struct route_node		*rn, -  struct bgp_info		*bi) +static void rfapiExpireEncapNow(struct rfapi_import_table *it, +				struct route_node *rn, struct bgp_info *bi)  { -  struct rfapi_withdraw *wcb; -  struct thread t; - -  /* -   * pretend we're an expiring timer -   */ -  wcb = XCALLOC (MTYPE_RFAPI_WITHDRAW, sizeof (struct rfapi_withdraw)); -  wcb->info = bi; -  wcb->node = rn; -  wcb->import_table = it; -  memset (&t, 0, sizeof (t)); -  t.arg = wcb; -  rfapiWithdrawTimerEncap (&t); /* frees wcb */ +	struct rfapi_withdraw *wcb; +	struct thread t; + +	/* +	 * pretend we're an expiring timer +	 */ +	wcb = XCALLOC(MTYPE_RFAPI_WITHDRAW, sizeof(struct rfapi_withdraw)); +	wcb->info = bi; +	wcb->node = rn; +	wcb->import_table = it; +	memset(&t, 0, sizeof(t)); +	t.arg = wcb; +	rfapiWithdrawTimerEncap(&t); /* frees wcb */  } -static int -rfapiGetNexthop (struct attr *attr, struct prefix *prefix) +static int rfapiGetNexthop(struct attr *attr, struct prefix *prefix)  { -  switch (BGP_MP_NEXTHOP_FAMILY (attr->mp_nexthop_len)) -    { -    case AF_INET: -      prefix->family = AF_INET; -      prefix->prefixlen = 32; -      prefix->u.prefix4 = attr->mp_nexthop_global_in; -      break; -    case AF_INET6: -      prefix->family = AF_INET6; -      prefix->prefixlen = 128; -      prefix->u.prefix6 = attr->mp_nexthop_global; -      break; -    default: -      vnc_zlog_debug_verbose ("%s: unknown attr->mp_nexthop_len %d", __func__, -                  attr->mp_nexthop_len); -      return EINVAL; -    } -  return 0; +	switch (BGP_MP_NEXTHOP_FAMILY(attr->mp_nexthop_len)) { +	case AF_INET: +		prefix->family = AF_INET; +		prefix->prefixlen = 32; +		prefix->u.prefix4 = attr->mp_nexthop_global_in; +		break; +	case AF_INET6: +		prefix->family = AF_INET6; +		prefix->prefixlen = 128; +		prefix->u.prefix6 = attr->mp_nexthop_global; +		break; +	default: +		vnc_zlog_debug_verbose("%s: unknown attr->mp_nexthop_len %d", +				       __func__, attr->mp_nexthop_len); +		return EINVAL; +	} +	return 0;  } -/*  +/*   * import a bgp_info if its route target list intersects with the   * import table's route target list   */ -static void -rfapiBgpInfoFilteredImportEncap ( -  struct rfapi_import_table	*import_table, -  int				action, -  struct peer			*peer, -  void				*rfd,		/* set for looped back routes */ -  struct prefix			*p, -  struct prefix			*aux_prefix,	/* Unused for encap routes */ -  afi_t				afi, -  struct prefix_rd		*prd, -  struct attr			*attr,		/* part of bgp_info */ -  u_char			type,		/* part of bgp_info */ -  u_char			sub_type,	/* part of bgp_info */ -  uint32_t			*label)		/* part of bgp_info */ +static void rfapiBgpInfoFilteredImportEncap( +	struct rfapi_import_table *import_table, int action, struct peer *peer, +	void *rfd, /* set for looped back routes */ +	struct prefix *p, +	struct prefix *aux_prefix, /* Unused for encap routes */ +	afi_t afi, struct prefix_rd *prd, +	struct attr *attr, /* part of bgp_info */ +	u_char type,       /* part of bgp_info */ +	u_char sub_type,   /* part of bgp_info */ +	uint32_t *label)   /* part of bgp_info */  { -  struct route_table *rt = NULL; -  struct route_node *rn; -  struct bgp_info *info_new; -  struct bgp_info *bi; -  struct bgp_info *next; -  char buf[BUFSIZ]; - -  struct prefix p_firstbi_old; -  struct prefix p_firstbi_new; -  int replacing = 0; -  const char *action_str = NULL; -  struct prefix un_prefix; - -  struct bgp *bgp; -  bgp = bgp_get_default ();     /* assume 1 instance for now */ - -  switch (action) -    { -    case FIF_ACTION_UPDATE: -      action_str = "update"; -      break; -    case FIF_ACTION_WITHDRAW: -      action_str = "withdraw"; -      break; -    case FIF_ACTION_KILL: -      action_str = "kill"; -      break; -    default: -      assert (0); -      break; -    } - -  vnc_zlog_debug_verbose ("%s: entry: %s: prefix %s/%d", __func__, -              action_str, -              inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ), p->prefixlen); - -  memset (&p_firstbi_old, 0, sizeof (p_firstbi_old)); -  memset (&p_firstbi_new, 0, sizeof (p_firstbi_new)); - -  if (action == FIF_ACTION_UPDATE) -    { -      /* -       * Compare rt lists. If no intersection, don't import this route -       * On a withdraw, peer and RD are sufficient to determine if -       * we should act. -       */ -      if (!attr || !attr->ecommunity) -        { - -          vnc_zlog_debug_verbose ("%s: attr, extra, or ecommunity missing, not importing", -                      __func__); -          return; -        } +	struct route_table *rt = NULL; +	struct route_node *rn; +	struct bgp_info *info_new; +	struct bgp_info *bi; +	struct bgp_info *next; +	char buf[BUFSIZ]; + +	struct prefix p_firstbi_old; +	struct prefix p_firstbi_new; +	int replacing = 0; +	const char *action_str = NULL; +	struct prefix un_prefix; + +	struct bgp *bgp; +	bgp = bgp_get_default(); /* assume 1 instance for now */ + +	switch (action) { +	case FIF_ACTION_UPDATE: +		action_str = "update"; +		break; +	case FIF_ACTION_WITHDRAW: +		action_str = "withdraw"; +		break; +	case FIF_ACTION_KILL: +		action_str = "kill"; +		break; +	default: +		assert(0); +		break; +	} + +	vnc_zlog_debug_verbose( +		"%s: entry: %s: prefix %s/%d", __func__, action_str, +		inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ), p->prefixlen); + +	memset(&p_firstbi_old, 0, sizeof(p_firstbi_old)); +	memset(&p_firstbi_new, 0, sizeof(p_firstbi_new)); + +	if (action == FIF_ACTION_UPDATE) { +		/* +		 * Compare rt lists. If no intersection, don't import this route +		 * On a withdraw, peer and RD are sufficient to determine if +		 * we should act. +		 */ +		if (!attr || !attr->ecommunity) { + +			vnc_zlog_debug_verbose( +				"%s: attr, extra, or ecommunity missing, not importing", +				__func__); +			return; +		}  #if RFAPI_REQUIRE_ENCAP_BEEC -      if (!rfapiEcommunitiesMatchBeec (attr->ecommunity)) -        { -          vnc_zlog_debug_verbose ("%s: it=%p: no match for BGP Encapsulation ecommunity", -                      __func__, import_table); -          return; -        } +		if (!rfapiEcommunitiesMatchBeec(attr->ecommunity)) { +			vnc_zlog_debug_verbose( +				"%s: it=%p: no match for BGP Encapsulation ecommunity", +				__func__, import_table); +			return; +		}  #endif -      if (!rfapiEcommunitiesIntersect (import_table->rt_import_list, -                                       attr->ecommunity)) -        { - -          vnc_zlog_debug_verbose ("%s: it=%p: no ecommunity intersection", -                      __func__, import_table); -          return; -        } - -      /* -       * Updates must also have a nexthop address -       */ -      memset (&un_prefix, 0, sizeof (un_prefix));       /* keep valgrind happy */ -      if (rfapiGetNexthop (attr, &un_prefix)) -        { -          vnc_zlog_debug_verbose ("%s: missing nexthop address", __func__); -          return; -        } -    } - -  /* -   * Figure out which radix tree the route would go into -   */ -  switch (afi) -    { -    case AFI_IP: -    case AFI_IP6: -      rt = import_table->imported_encap[afi]; -      break; - -    default: -      zlog_err ("%s: bad afi %d", __func__, afi); -      return; -    } - -  /* -   * route_node_lookup returns a node only if there is at least -   * one route attached. -   */ -  rn = route_node_lookup (rt, p); +		if (!rfapiEcommunitiesIntersect(import_table->rt_import_list, +						attr->ecommunity)) { + +			vnc_zlog_debug_verbose( +				"%s: it=%p: no ecommunity intersection", +				__func__, import_table); +			return; +		} + +		/* +		 * Updates must also have a nexthop address +		 */ +		memset(&un_prefix, 0, +		       sizeof(un_prefix)); /* keep valgrind happy */ +		if (rfapiGetNexthop(attr, &un_prefix)) { +			vnc_zlog_debug_verbose("%s: missing nexthop address", +					       __func__); +			return; +		} +	} + +	/* +	 * Figure out which radix tree the route would go into +	 */ +	switch (afi) { +	case AFI_IP: +	case AFI_IP6: +		rt = import_table->imported_encap[afi]; +		break; + +	default: +		zlog_err("%s: bad afi %d", __func__, afi); +		return; +	} + +	/* +	 * route_node_lookup returns a node only if there is at least +	 * one route attached. +	 */ +	rn = route_node_lookup(rt, p);  #if DEBUG_ENCAP_MONITOR -  vnc_zlog_debug_verbose ("%s: initial encap lookup(it=%p) rn=%p", -              __func__, import_table, rn); +	vnc_zlog_debug_verbose("%s: initial encap lookup(it=%p) rn=%p", +			       __func__, import_table, rn);  #endif -  if (rn) -    { - -      RFAPI_CHECK_REFCOUNT (rn, SAFI_ENCAP, 1); -      route_unlock_node (rn);   /* undo lock in route_node_lookup */ - - -      /* -       * capture nexthop of first bi -       */ -      if (rn->info) -        { -          rfapiNexthop2Prefix (((struct bgp_info *) (rn->info))->attr, -                               &p_firstbi_old); -        } - -      for (bi = rn->info; bi; bi = bi->next) -        { - -          /* -           * Does this bgp_info refer to the same route -           * as we are trying to add? -           */ -          vnc_zlog_debug_verbose ("%s: comparing BI %p", __func__, bi); - - -          /* -           * Compare RDs -           * -           * RD of import table bi is in bi->extra->vnc.import.rd -           * RD of info_orig is in prd -           */ -          if (!bi->extra) -            { -              vnc_zlog_debug_verbose ("%s: no bi->extra", __func__); -              continue; -            } -          if (prefix_cmp ((struct prefix *) &bi->extra->vnc.import.rd, -                          (struct prefix *) prd)) -            { - -              vnc_zlog_debug_verbose ("%s: prd does not match", __func__); -              continue; -            } - -          /* -           * Compare peers -           */ -          if (bi->peer != peer) -            { -              vnc_zlog_debug_verbose ("%s: peer does not match", __func__); -              continue; -            } - -          vnc_zlog_debug_verbose ("%s: found matching bi", __func__); - -          /* Same route. Delete this bi, replace with new one */ - -          if (action == FIF_ACTION_WITHDRAW) -            { - -              vnc_zlog_debug_verbose ("%s: withdrawing at prefix %s/%d", -                          __func__, -                          inet_ntop (rn->p.family, &rn->p.u.prefix, buf, -                                     BUFSIZ), rn->p.prefixlen); - -              rfapiBiStartWithdrawTimer (import_table, rn, bi, -                                         afi, SAFI_ENCAP, -                                         rfapiWithdrawTimerEncap); - -            } -          else -            { -              vnc_zlog_debug_verbose ("%s: %s at prefix %s/%d", -                          __func__, -                          ((action == -                            FIF_ACTION_KILL) ? "killing" : "replacing"), -                          inet_ntop (rn->p.family, &rn->p.u.prefix, buf, -                                     BUFSIZ), rn->p.prefixlen); - -              /* -               * If this route is waiting to be deleted because of -               * a previous withdraw, we must cancel its timer. -               */ -              if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED) -                  && bi->extra->vnc.import.timer) -                { - -                  struct thread *t = -                    (struct thread *) bi->extra->vnc.import.timer; -                  struct rfapi_withdraw *wcb = t->arg; - -                  XFREE (MTYPE_RFAPI_WITHDRAW, wcb); -                  thread_cancel (t); -                } - -              if (action == FIF_ACTION_UPDATE) -                { -                  rfapiBgpInfoDetach (rn, bi); -                  rfapiBgpInfoFree (bi); -                  replacing = 1; -                } -              else -                { -                  /* -                   * Kill: do export stuff when removing bi -                   */ -                  struct rfapi_withdraw *wcb; -                  struct thread t; - -                  /* -                   * pretend we're an expiring timer -                   */ -                  wcb = -                    XCALLOC (MTYPE_RFAPI_WITHDRAW, -                             sizeof (struct rfapi_withdraw)); -                  wcb->info = bi; -                  wcb->node = rn; -                  wcb->import_table = import_table; -                  memset (&t, 0, sizeof (t)); -                  t.arg = wcb; -                  rfapiWithdrawTimerEncap (&t); /* frees wcb */ -                } -            } - -          break; -        } -    } - -  if (rn) -    RFAPI_CHECK_REFCOUNT (rn, SAFI_ENCAP, replacing ? 1 : 0); - -  if (action == FIF_ACTION_WITHDRAW || action == FIF_ACTION_KILL) -    return; - -  info_new = rfapiBgpInfoCreate (attr, peer, rfd, prd, type, sub_type, NULL); - -  if (rn) -    { -      if (!replacing) -        route_lock_node (rn);   /* incr ref count for new BI */ -    } -  else -    { -      rn = route_node_get (rt, p); -    } - -  vnc_zlog_debug_verbose ("%s: (afi=%d, rn=%p) inserting at prefix %s/%d", -              __func__, -              afi, -              rn, -              inet_ntop (rn->p.family, &rn->p.u.prefix, buf, BUFSIZ), -              rn->p.prefixlen); - -  rfapiBgpInfoAttachSorted (rn, info_new, afi, SAFI_ENCAP); - -  /* -   * Delete holddown routes from same NVE. See details in -   * rfapiBgpInfoFilteredImportVPN() -   */ -  for (bi = info_new->next; bi; bi = next) -    { - -      struct prefix pfx_un; -      int un_match = 0; - -      next = bi->next; -      if (!CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) -        continue; - -      /* -       * We already match the VN address (it is the prefix -       * of the route node) -       */ - -      if (!rfapiGetNexthop (bi->attr, &pfx_un) && -          prefix_same (&pfx_un, &un_prefix)) -        { - -          un_match = 1; -        } - -      if (!un_match) -        continue; - -      vnc_zlog_debug_verbose ("%s: removing holddown bi matching NVE of new route", -                  __func__); -      if (bi->extra->vnc.import.timer) -        { -          struct thread *t = (struct thread *) bi->extra->vnc.import.timer; -          struct rfapi_withdraw *wcb = t->arg; - -          XFREE (MTYPE_RFAPI_WITHDRAW, wcb); -          thread_cancel (t); -        } -      rfapiExpireEncapNow (import_table, rn, bi); -    } - -  rfapiNexthop2Prefix (((struct bgp_info *) (rn->info))->attr, -                       &p_firstbi_new); - -  /* -   * If the nexthop address of the selected Encap route (i.e., -   * the UN address) has changed, then we must update the VPN -   * routes that refer to this Encap route and possibly force -   * rfapi callbacks. -   */ -  if (rfapiAttrNexthopAddrDifferent (&p_firstbi_old, &p_firstbi_new)) -    { - -      struct rfapi_monitor_encap *m; -      struct rfapi_monitor_encap *mnext; - -      struct route_node *referenced_vpn_prefix; - -      /* -       * Optimized approach: build radix tree on the fly to -       * hold list of VPN nodes referenced by the ENCAP monitors -       * -       * The nodes in this table correspond to prefixes of VPN routes. -       * The "info" pointer of the node points to a chain of -       * struct rfapi_monitor_encap, each of which refers to a -       * specific VPN node. -       */ -      struct route_table *referenced_vpn_table; - -      referenced_vpn_table = route_table_init (); -      assert (referenced_vpn_table); - -      /* -       * iterate over the set of monitors at this ENCAP node. -       */ +	if (rn) { + +		RFAPI_CHECK_REFCOUNT(rn, SAFI_ENCAP, 1); +		route_unlock_node(rn); /* undo lock in route_node_lookup */ + + +		/* +		 * capture nexthop of first bi +		 */ +		if (rn->info) { +			rfapiNexthop2Prefix( +				((struct bgp_info *)(rn->info))->attr, +				&p_firstbi_old); +		} + +		for (bi = rn->info; bi; bi = bi->next) { + +			/* +			 * Does this bgp_info refer to the same route +			 * as we are trying to add? +			 */ +			vnc_zlog_debug_verbose("%s: comparing BI %p", __func__, +					       bi); + + +			/* +			 * Compare RDs +			 * +			 * RD of import table bi is in bi->extra->vnc.import.rd +			 * RD of info_orig is in prd +			 */ +			if (!bi->extra) { +				vnc_zlog_debug_verbose("%s: no bi->extra", +						       __func__); +				continue; +			} +			if (prefix_cmp( +				    (struct prefix *)&bi->extra->vnc.import.rd, +				    (struct prefix *)prd)) { + +				vnc_zlog_debug_verbose("%s: prd does not match", +						       __func__); +				continue; +			} + +			/* +			 * Compare peers +			 */ +			if (bi->peer != peer) { +				vnc_zlog_debug_verbose( +					"%s: peer does not match", __func__); +				continue; +			} + +			vnc_zlog_debug_verbose("%s: found matching bi", +					       __func__); + +			/* Same route. Delete this bi, replace with new one */ + +			if (action == FIF_ACTION_WITHDRAW) { + +				vnc_zlog_debug_verbose( +					"%s: withdrawing at prefix %s/%d", +					__func__, +					inet_ntop(rn->p.family, &rn->p.u.prefix, +						  buf, BUFSIZ), +					rn->p.prefixlen); + +				rfapiBiStartWithdrawTimer( +					import_table, rn, bi, afi, SAFI_ENCAP, +					rfapiWithdrawTimerEncap); + +			} else { +				vnc_zlog_debug_verbose( +					"%s: %s at prefix %s/%d", __func__, +					((action == FIF_ACTION_KILL) +						 ? "killing" +						 : "replacing"), +					inet_ntop(rn->p.family, &rn->p.u.prefix, +						  buf, BUFSIZ), +					rn->p.prefixlen); + +				/* +				 * If this route is waiting to be deleted +				 * because of +				 * a previous withdraw, we must cancel its +				 * timer. +				 */ +				if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED) +				    && bi->extra->vnc.import.timer) { + +					struct thread *t = +						(struct thread *)bi->extra->vnc +							.import.timer; +					struct rfapi_withdraw *wcb = t->arg; + +					XFREE(MTYPE_RFAPI_WITHDRAW, wcb); +					thread_cancel(t); +				} + +				if (action == FIF_ACTION_UPDATE) { +					rfapiBgpInfoDetach(rn, bi); +					rfapiBgpInfoFree(bi); +					replacing = 1; +				} else { +					/* +					 * Kill: do export stuff when removing +					 * bi +					 */ +					struct rfapi_withdraw *wcb; +					struct thread t; + +					/* +					 * pretend we're an expiring timer +					 */ +					wcb = XCALLOC( +						MTYPE_RFAPI_WITHDRAW, +						sizeof(struct rfapi_withdraw)); +					wcb->info = bi; +					wcb->node = rn; +					wcb->import_table = import_table; +					memset(&t, 0, sizeof(t)); +					t.arg = wcb; +					rfapiWithdrawTimerEncap( +						&t); /* frees wcb */ +				} +			} + +			break; +		} +	} + +	if (rn) +		RFAPI_CHECK_REFCOUNT(rn, SAFI_ENCAP, replacing ? 1 : 0); + +	if (action == FIF_ACTION_WITHDRAW || action == FIF_ACTION_KILL) +		return; + +	info_new = +		rfapiBgpInfoCreate(attr, peer, rfd, prd, type, sub_type, NULL); + +	if (rn) { +		if (!replacing) +			route_lock_node(rn); /* incr ref count for new BI */ +	} else { +		rn = route_node_get(rt, p); +	} + +	vnc_zlog_debug_verbose( +		"%s: (afi=%d, rn=%p) inserting at prefix %s/%d", __func__, afi, +		rn, inet_ntop(rn->p.family, &rn->p.u.prefix, buf, BUFSIZ), +		rn->p.prefixlen); + +	rfapiBgpInfoAttachSorted(rn, info_new, afi, SAFI_ENCAP); + +	/* +	 * Delete holddown routes from same NVE. See details in +	 * rfapiBgpInfoFilteredImportVPN() +	 */ +	for (bi = info_new->next; bi; bi = next) { + +		struct prefix pfx_un; +		int un_match = 0; + +		next = bi->next; +		if (!CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) +			continue; + +		/* +		 * We already match the VN address (it is the prefix +		 * of the route node) +		 */ + +		if (!rfapiGetNexthop(bi->attr, &pfx_un) +		    && prefix_same(&pfx_un, &un_prefix)) { + +			un_match = 1; +		} + +		if (!un_match) +			continue; + +		vnc_zlog_debug_verbose( +			"%s: removing holddown bi matching NVE of new route", +			__func__); +		if (bi->extra->vnc.import.timer) { +			struct thread *t = +				(struct thread *)bi->extra->vnc.import.timer; +			struct rfapi_withdraw *wcb = t->arg; + +			XFREE(MTYPE_RFAPI_WITHDRAW, wcb); +			thread_cancel(t); +		} +		rfapiExpireEncapNow(import_table, rn, bi); +	} + +	rfapiNexthop2Prefix(((struct bgp_info *)(rn->info))->attr, +			    &p_firstbi_new); + +	/* +	 * If the nexthop address of the selected Encap route (i.e., +	 * the UN address) has changed, then we must update the VPN +	 * routes that refer to this Encap route and possibly force +	 * rfapi callbacks. +	 */ +	if (rfapiAttrNexthopAddrDifferent(&p_firstbi_old, &p_firstbi_new)) { + +		struct rfapi_monitor_encap *m; +		struct rfapi_monitor_encap *mnext; + +		struct route_node *referenced_vpn_prefix; + +		/* +		 * Optimized approach: build radix tree on the fly to +		 * hold list of VPN nodes referenced by the ENCAP monitors +		 * +		 * The nodes in this table correspond to prefixes of VPN routes. +		 * The "info" pointer of the node points to a chain of +		 * struct rfapi_monitor_encap, each of which refers to a +		 * specific VPN node. +		 */ +		struct route_table *referenced_vpn_table; + +		referenced_vpn_table = route_table_init(); +		assert(referenced_vpn_table); + +/* + * iterate over the set of monitors at this ENCAP node. + */  #if DEBUG_ENCAP_MONITOR -      vnc_zlog_debug_verbose ("%s: examining monitors at rn=%p", __func__, rn); +		vnc_zlog_debug_verbose("%s: examining monitors at rn=%p", +				       __func__, rn);  #endif -      for (m = RFAPI_MONITOR_ENCAP (rn); m; m = m->next) -        { - -          /* -           * For each referenced bi/route, copy the ENCAP route's -           * nexthop to the VPN route's cached UN address field and set -           * the address family of the cached UN address field. -           */ -          rfapiCopyUnEncap2VPN (info_new, m->bi); -          if (!CHECK_FLAG (m->bi->flags, BGP_INFO_VALID)) -            { -              SET_FLAG (m->bi->flags, BGP_INFO_VALID); -              if (VALID_INTERIOR_TYPE (m->bi->type)) -                RFAPI_MONITOR_EXTERIOR (m->node)->valid_interior_count++; -              vnc_import_bgp_exterior_add_route_interior (bgp, -                                                          import_table, -                                                          m->node, m->bi); -            } - -          /* -           * Build a list of unique VPN nodes referenced by these monitors -           * -           * There could be more than one VPN node here with a given -           * prefix. Those are currently in an unsorted linear list -           * per prefix. -           */ - -          referenced_vpn_prefix = -            route_node_get (referenced_vpn_table, &m->node->p); -          assert (referenced_vpn_prefix); -          for (mnext = referenced_vpn_prefix->info; mnext; -               mnext = mnext->next) -            { - -              if (mnext->node == m->node) -                break; -            } - -          if (mnext) -            { -              /* -               * already have an entry for this VPN node -               */ -              route_unlock_node (referenced_vpn_prefix); -            } -          else -            { -              mnext = XCALLOC (MTYPE_RFAPI_MONITOR_ENCAP, -                               sizeof (struct rfapi_monitor_encap)); -              assert (mnext); -              mnext->node = m->node; -              mnext->next = referenced_vpn_prefix->info; -              referenced_vpn_prefix->info = mnext; -            } - -        } - -      /* -       * for each VPN node referenced in the ENCAP monitors: -       */ -      for (referenced_vpn_prefix = route_top (referenced_vpn_table); -           referenced_vpn_prefix; -           referenced_vpn_prefix = route_next (referenced_vpn_prefix)) -        { - -          while ((m = referenced_vpn_prefix->info)) -            { - -              struct route_node *n; - -              rfapiMonitorMoveLonger (m->node); -              for (n = m->node; n; n = n->parent) -                { -                  //rfapiDoRouteCallback(import_table, n, NULL); -                } -              rfapiMonitorItNodeChanged (import_table, m->node, NULL); - -              referenced_vpn_prefix->info = m->next; -              route_unlock_node (referenced_vpn_prefix); -              XFREE (MTYPE_RFAPI_MONITOR_ENCAP, m); -            } - -        } -      route_table_finish (referenced_vpn_table); -    } - -  RFAPI_CHECK_REFCOUNT (rn, SAFI_ENCAP, 0); +		for (m = RFAPI_MONITOR_ENCAP(rn); m; m = m->next) { + +			/* +			 * For each referenced bi/route, copy the ENCAP route's +			 * nexthop to the VPN route's cached UN address field +			 * and set +			 * the address family of the cached UN address field. +			 */ +			rfapiCopyUnEncap2VPN(info_new, m->bi); +			if (!CHECK_FLAG(m->bi->flags, BGP_INFO_VALID)) { +				SET_FLAG(m->bi->flags, BGP_INFO_VALID); +				if (VALID_INTERIOR_TYPE(m->bi->type)) +					RFAPI_MONITOR_EXTERIOR(m->node) +						->valid_interior_count++; +				vnc_import_bgp_exterior_add_route_interior( +					bgp, import_table, m->node, m->bi); +			} + +			/* +			 * Build a list of unique VPN nodes referenced by these +			 * monitors +			 * +			 * There could be more than one VPN node here with a +			 * given +			 * prefix. Those are currently in an unsorted linear +			 * list +			 * per prefix. +			 */ + +			referenced_vpn_prefix = route_node_get( +				referenced_vpn_table, &m->node->p); +			assert(referenced_vpn_prefix); +			for (mnext = referenced_vpn_prefix->info; mnext; +			     mnext = mnext->next) { + +				if (mnext->node == m->node) +					break; +			} + +			if (mnext) { +				/* +				 * already have an entry for this VPN node +				 */ +				route_unlock_node(referenced_vpn_prefix); +			} else { +				mnext = XCALLOC( +					MTYPE_RFAPI_MONITOR_ENCAP, +					sizeof(struct rfapi_monitor_encap)); +				assert(mnext); +				mnext->node = m->node; +				mnext->next = referenced_vpn_prefix->info; +				referenced_vpn_prefix->info = mnext; +			} +		} + +		/* +		 * for each VPN node referenced in the ENCAP monitors: +		 */ +		for (referenced_vpn_prefix = route_top(referenced_vpn_table); +		     referenced_vpn_prefix; referenced_vpn_prefix = route_next( +						    referenced_vpn_prefix)) { + +			while ((m = referenced_vpn_prefix->info)) { + +				struct route_node *n; + +				rfapiMonitorMoveLonger(m->node); +				for (n = m->node; n; n = n->parent) { +					// rfapiDoRouteCallback(import_table, n, +					// NULL); +				} +				rfapiMonitorItNodeChanged(import_table, m->node, +							  NULL); + +				referenced_vpn_prefix->info = m->next; +				route_unlock_node(referenced_vpn_prefix); +				XFREE(MTYPE_RFAPI_MONITOR_ENCAP, m); +			} +		} +		route_table_finish(referenced_vpn_table); +	} + +	RFAPI_CHECK_REFCOUNT(rn, SAFI_ENCAP, 0);  } -static void -rfapiExpireVpnNow ( -  struct rfapi_import_table	*it, -  struct route_node		*rn, -  struct bgp_info		*bi, -  int				lockoffset) +static void rfapiExpireVpnNow(struct rfapi_import_table *it, +			      struct route_node *rn, struct bgp_info *bi, +			      int lockoffset)  { -  struct rfapi_withdraw *wcb; -  struct thread t; - -  /* -   * pretend we're an expiring timer -   */ -  wcb = XCALLOC (MTYPE_RFAPI_WITHDRAW, sizeof (struct rfapi_withdraw)); -  wcb->info = bi; -  wcb->node = rn; -  wcb->import_table = it; -  wcb->lockoffset = lockoffset; -  memset (&t, 0, sizeof (t)); -  t.arg = wcb; -  rfapiWithdrawTimerVPN (&t);   /* frees wcb */ +	struct rfapi_withdraw *wcb; +	struct thread t; + +	/* +	 * pretend we're an expiring timer +	 */ +	wcb = XCALLOC(MTYPE_RFAPI_WITHDRAW, sizeof(struct rfapi_withdraw)); +	wcb->info = bi; +	wcb->node = rn; +	wcb->import_table = it; +	wcb->lockoffset = lockoffset; +	memset(&t, 0, sizeof(t)); +	t.arg = wcb; +	rfapiWithdrawTimerVPN(&t); /* frees wcb */  } -/*  +/*   * import a bgp_info if its route target list intersects with the   * import table's route target list   */ -void -rfapiBgpInfoFilteredImportVPN ( -  struct rfapi_import_table	*import_table, -  int				action, -  struct peer			*peer, -  void				*rfd,		/* set for looped back routes */ -  struct prefix			*p, -  struct prefix			*aux_prefix,	/* AFI_L2VPN: optional IP */ -  afi_t				afi, -  struct prefix_rd		*prd, -  struct attr			*attr,		/* part of bgp_info */ -  u_char			type,		/* part of bgp_info */ -  u_char			sub_type,	/* part of bgp_info */ -  uint32_t			*label)		/* part of bgp_info */ +void rfapiBgpInfoFilteredImportVPN( +	struct rfapi_import_table *import_table, int action, struct peer *peer, +	void *rfd, /* set for looped back routes */ +	struct prefix *p, +	struct prefix *aux_prefix, /* AFI_L2VPN: optional IP */ +	afi_t afi, struct prefix_rd *prd, +	struct attr *attr, /* part of bgp_info */ +	u_char type,       /* part of bgp_info */ +	u_char sub_type,   /* part of bgp_info */ +	uint32_t *label)   /* part of bgp_info */  { -  struct route_table	*rt = NULL; -  struct route_node	*rn; -  struct route_node	*n; -  struct bgp_info	*info_new; -  struct bgp_info	*bi; -  struct bgp_info	*next; -  char			buf[BUFSIZ]; -  struct prefix		vn_prefix; -  struct prefix		un_prefix; -  int			un_prefix_valid = 0; -  struct route_node	*ern; -  int			replacing = 0; -  int			original_had_routes = 0; -  struct prefix		original_nexthop; -  const char		*action_str = NULL; -  int			is_it_ce = 0; - -  struct bgp *bgp; -  bgp = bgp_get_default ();     /* assume 1 instance for now */ - -  switch (action) -    { -    case FIF_ACTION_UPDATE: -      action_str = "update"; -      break; -    case FIF_ACTION_WITHDRAW: -      action_str = "withdraw"; -      break; -    case FIF_ACTION_KILL: -      action_str = "kill"; -      break; -    default: -      assert (0); -      break; -    } - -  if (import_table == bgp->rfapi->it_ce) -    is_it_ce = 1; - -  vnc_zlog_debug_verbose ("%s: entry: %s%s: prefix %s/%d: it %p, afi %s", __func__, -              (is_it_ce ? "CE-IT " : ""), -              action_str, -              rfapi_ntop (p->family, &p->u.prefix, buf, BUFSIZ), -              p->prefixlen, import_table, afi2str (afi)); - -  VNC_ITRCCK; - -  /* -   * Compare rt lists. If no intersection, don't import this route -   * On a withdraw, peer and RD are sufficient to determine if -   * we should act. -   */ -  if (action == FIF_ACTION_UPDATE) -    { -      if (!attr || !attr->ecommunity) -        { - -          vnc_zlog_debug_verbose ("%s: attr, extra, or ecommunity missing, not importing", -                      __func__); -          return; -        } -      if ((import_table != bgp->rfapi->it_ce) && -          !rfapiEcommunitiesIntersect (import_table->rt_import_list, -                                       attr->ecommunity)) -        { - -          vnc_zlog_debug_verbose ("%s: it=%p: no ecommunity intersection", -                      __func__, import_table); -          return; -        } - -      memset (&vn_prefix, 0, sizeof (vn_prefix));       /* keep valgrind happy */ -      if (rfapiGetNexthop (attr, &vn_prefix)) -        { -          /* missing nexthop address would be a bad, bad thing */ -          vnc_zlog_debug_verbose ("%s: missing nexthop", __func__); -          return; -        } -    } - -  /* -   * Figure out which radix tree the route would go into -   */ -  switch (afi) -    { -    case AFI_IP: -    case AFI_IP6: -    case AFI_L2VPN: -      rt = import_table->imported_vpn[afi]; -      break; - -    default: -      zlog_err ("%s: bad afi %d", __func__, afi); -      return; -    } - -  /* clear it */ -  memset (&original_nexthop, 0, sizeof (original_nexthop)); - -  /* -   * route_node_lookup returns a node only if there is at least -   * one route attached. -   */ -  rn = route_node_lookup (rt, p); - -  vnc_zlog_debug_verbose ("%s: rn=%p", __func__, rn); - -  if (rn) -    { - -      RFAPI_CHECK_REFCOUNT (rn, SAFI_MPLS_VPN, 1); -      route_unlock_node (rn);   /* undo lock in route_node_lookup */ - -      if (rn->info) -        original_had_routes = 1; - -      if (VNC_DEBUG(VERBOSE)) -        { -          vnc_zlog_debug_verbose ("%s: showing IT node on entry", __func__); -          rfapiShowItNode (NULL, rn);   /* debug */ -        } - -      /* -       * Look for same route (will have same RD and peer) -       */ -      bi = rfapiItBiIndexSearch (rn, prd, peer, aux_prefix); - -      if (bi) -        { - -          /* -           * This was an old test when we iterated over the -           * BIs linearly. Since we're now looking up with -           * RD and peer, comparing types should not be -           * needed. Changed to assertion. -           * -           * Compare types. Doing so prevents a RFP-originated -           * route from matching an imported route, for example. -           */ -          assert (bi->type == type); - -          vnc_zlog_debug_verbose ("%s: found matching bi", __func__); - -          /* -           * In the special CE table, withdrawals occur without holddown -           */ -          if (import_table == bgp->rfapi->it_ce) -            { -              vnc_direct_bgp_del_route_ce (bgp, rn, bi); -              if (action == FIF_ACTION_WITHDRAW) -                action = FIF_ACTION_KILL; -            } - -          if (action == FIF_ACTION_WITHDRAW) -            { - -              int washolddown = CHECK_FLAG (bi->flags, BGP_INFO_REMOVED); - -              vnc_zlog_debug_verbose ("%s: withdrawing at prefix %s/%d%s", -                          __func__, -                          rfapi_ntop (rn->p.family, &rn->p.u.prefix, buf, -                                      BUFSIZ), rn->p.prefixlen, -                          (washolddown ? " (already being withdrawn)" : "")); - -              VNC_ITRCCK; -              if (!washolddown) -                { -                  rfapiBiStartWithdrawTimer (import_table, rn, bi, -                                             afi, SAFI_MPLS_VPN, -                                             rfapiWithdrawTimerVPN); - -                  RFAPI_UPDATE_ITABLE_COUNT (bi, import_table, afi, -1); -                  import_table->holddown_count[afi] += 1; -                } -              VNC_ITRCCK; -            } -          else -            { -              vnc_zlog_debug_verbose ("%s: %s at prefix %s/%d", -                          __func__, -                          ((action == -                            FIF_ACTION_KILL) ? "killing" : "replacing"), -                          rfapi_ntop (rn->p.family, &rn->p.u.prefix, buf, -                                      BUFSIZ), rn->p.prefixlen); - -              /* -               * If this route is waiting to be deleted because of -               * a previous withdraw, we must cancel its timer. -               */ -              if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED) && -                  bi->extra->vnc.import.timer) -                { - -                  struct thread *t = -                    (struct thread *) bi->extra->vnc.import.timer; -                  struct rfapi_withdraw *wcb = t->arg; - -                  XFREE (MTYPE_RFAPI_WITHDRAW, wcb); -                  thread_cancel (t); - -                  import_table->holddown_count[afi] -= 1; -                  RFAPI_UPDATE_ITABLE_COUNT (bi, import_table, afi, 1); -                } -              /* -               * decrement remote count (if route is remote) because -               * we are going to remove it below -               */ -              RFAPI_UPDATE_ITABLE_COUNT (bi, import_table, afi, -1); -              if (action == FIF_ACTION_UPDATE) -                { -                  replacing = 1; - -                  /* -                   * make copy of original nexthop so we can see if it changed -                   */ -                  rfapiGetNexthop (bi->attr, &original_nexthop); - -                  /* -                   * remove bi without doing any export processing -                   */ -                  if (CHECK_FLAG (bi->flags, BGP_INFO_VALID) -                      && VALID_INTERIOR_TYPE (bi->type)) -                    RFAPI_MONITOR_EXTERIOR (rn)->valid_interior_count--; -                  rfapiItBiIndexDel (rn, bi); -                  rfapiBgpInfoDetach (rn, bi); -                  rfapiMonitorEncapDelete (bi); -                  vnc_import_bgp_exterior_del_route_interior (bgp, -                                                              import_table, -                                                              rn, bi); -                  rfapiBgpInfoFree (bi); -                } -              else -                { -                  /* Kill */ -                  /* -                   * remove bi and do export processing -                   */ -                  import_table->holddown_count[afi] += 1; -                  rfapiExpireVpnNow (import_table, rn, bi, 0); -                } - -            } -        } - -    } - -  if (rn) -    RFAPI_CHECK_REFCOUNT (rn, SAFI_MPLS_VPN, replacing ? 1 : 0); - -  if (action == FIF_ACTION_WITHDRAW || action == FIF_ACTION_KILL) -    { -      VNC_ITRCCK; -      return; -    } - -  info_new = rfapiBgpInfoCreate (attr, peer, rfd, prd, type, sub_type, label); - -  /* -   * lookup un address in encap table -   */ -  ern = route_node_match (import_table->imported_encap[afi], &vn_prefix); -  if (ern) -    { -      rfapiCopyUnEncap2VPN (ern->info, info_new); -      route_unlock_node (ern);  /* undo lock in route_note_match */ -    } -  else -    { -      char buf[BUFSIZ]; -      prefix2str (&vn_prefix, buf, sizeof (buf)); -      buf[BUFSIZ - 1] = 0; -      /* Not a big deal, just means VPN route got here first */ -      vnc_zlog_debug_verbose ("%s: no encap route for vn addr %s", __func__, buf); -      info_new->extra->vnc.import.un_family = 0; -    } - -  if (rn) -    { -      if (!replacing) -        route_lock_node (rn); -    } -  else -    { -      /* -       * No need to increment reference count, so only "get" -       * if the node is not there already -       */ -      rn = route_node_get (rt, p); -    } - -  /* -   * For ethernet routes, if there is an accompanying IP address, -   * save it in the bi -   */ -  if ((AFI_L2VPN == afi) && aux_prefix) -    { - -      vnc_zlog_debug_verbose ("%s: setting BI's aux_prefix", __func__); -      info_new->extra->vnc.import.aux_prefix = *aux_prefix; -    } - -  vnc_zlog_debug_verbose ("%s: inserting bi %p at prefix %s/%d #%d", -              __func__, -              info_new, -              rfapi_ntop (rn->p.family, &rn->p.u.prefix, buf, BUFSIZ), -              rn->p.prefixlen, rn->lock); - -  rfapiBgpInfoAttachSorted (rn, info_new, afi, SAFI_MPLS_VPN); -  rfapiItBiIndexAdd (rn, info_new); -  if (!rfapiGetUnAddrOfVpnBi (info_new, NULL)) -    { -      if (VALID_INTERIOR_TYPE (info_new->type)) -        RFAPI_MONITOR_EXTERIOR (rn)->valid_interior_count++; -      SET_FLAG (info_new->flags, BGP_INFO_VALID); -    } -  RFAPI_UPDATE_ITABLE_COUNT (info_new, import_table, afi, 1); -  vnc_import_bgp_exterior_add_route_interior (bgp, import_table, rn, -                                              info_new); - -  if (import_table == bgp->rfapi->it_ce) -    vnc_direct_bgp_add_route_ce (bgp, rn, info_new); - -  if (VNC_DEBUG(VERBOSE)) -    { -      vnc_zlog_debug_verbose ("%s: showing IT node", __func__); -      rfapiShowItNode (NULL, rn);   /* debug */ -    } - -  rfapiMonitorEncapAdd (import_table, &vn_prefix, rn, info_new); - -  if (!rfapiGetUnAddrOfVpnBi (info_new, &un_prefix)) -    { - -      /*  -       * if we have a valid UN address (either via Encap route -       * or via tunnel attribute), then we should attempt -       * to move any monitors at less-specific nodes to this node -       */ -      rfapiMonitorMoveLonger (rn); - -      un_prefix_valid = 1; - -    } - -  /* -   * 101129 Enhancement: if we add a route (implication: it is not -   * in holddown), delete all other routes from this nve at this -   * node that are in holddown, regardless of peer. -   * -   * Reasons it's OK to do that: -   * -   * - if the holddown route being deleted originally came from BGP VPN,  -   *   it is already gone from BGP (implication of holddown), so there -   *   won't be any added inconsistency with the BGP RIB. -   * -   * - once a fresh route is added at a prefix, any routes in holddown -   *   at that prefix will not show up in RFP responses, so deleting -   *   the holddown routes won't affect the contents of responses. -   * -   * - lifetimes are supposed to be consistent, so there should not -   *   be a case where the fresh route has a shorter lifetime than -   *   the holddown route, so we don't expect the fresh route to -   *   disappear and complete its holddown time before the existing -   *   holddown routes time out. Therefore, we won't have a situation -   *   where we expect the existing holddown routes to be hidden and -   *   then  to reappear sometime later (as holddown routes) in a -   *   RFP response. -   * -   * Among other things, this would enable us to skirt the problem -   * of local holddown routes that refer to NVE descriptors that -   * have already been closed (if the same NVE triggers a subsequent -   * rfapi_open(), the new peer is different and doesn't match the -   * peer of the holddown route, so the stale holddown route still -   * hangs around until it times out instead of just being replaced -   * by the fresh route). -   */ -  /* -   * We know that the new bi will have been inserted before any routes -   * in holddown, so we can skip any that came before it -   */ -  for (bi = info_new->next; bi; bi = next) -    { - -      struct prefix pfx_vn; -      struct prefix pfx_un; -      int un_match = 0; -      int remote_peer_match = 0; - -      next = bi->next; - -      /* -       * Must be holddown -       */ -      if (!CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) -        continue; - -      /* -       * Must match VN address (nexthop of VPN route) -       */ -      if (rfapiGetNexthop (bi->attr, &pfx_vn)) -        continue; -      if (!prefix_same (&pfx_vn, &vn_prefix)) -        continue; - -      if (un_prefix_valid &&    /* new route UN addr */ -          !rfapiGetUnAddrOfVpnBi (bi, &pfx_un) &&       /* old route UN addr */ -          prefix_same (&pfx_un, &un_prefix)) -        {                       /* compare */ -          un_match = 1; -        } -      if (!RFAPI_LOCAL_BI (bi) && !RFAPI_LOCAL_BI (info_new) && -          sockunion_same (&bi->peer->su, &info_new->peer->su)) -        { -          /* old & new are both remote, same peer */ -          remote_peer_match = 1; -        } - -      if (!un_match & !remote_peer_match) -        continue; - -      vnc_zlog_debug_verbose ("%s: removing holddown bi matching NVE of new route", -                  __func__); -      if (bi->extra->vnc.import.timer) -        { -          struct thread *t = (struct thread *) bi->extra->vnc.import.timer; -          struct rfapi_withdraw *wcb = t->arg; - -          XFREE (MTYPE_RFAPI_WITHDRAW, wcb); -          thread_cancel (t); -        } -      rfapiExpireVpnNow (import_table, rn, bi, 0); -    } - -  if (!original_had_routes) -    { -      /* -       * We went from 0 usable routes to 1 usable route. Perform the -       * "Adding a Route" export process. -       */ -      vnc_direct_bgp_add_prefix (bgp, import_table, rn); -      vnc_zebra_add_prefix (bgp, import_table, rn); -    } -  else -    { -      /* -       * Check for nexthop change event -       * Note: the prefix_same() test below detects two situations: -       * 1. route is replaced, new route has different nexthop -       * 2. new route is added (original_nexthop is 0) -       */ -      struct prefix new_nexthop; - -      rfapiGetNexthop (attr, &new_nexthop); -      if (!prefix_same (&original_nexthop, &new_nexthop)) -        { -          /* -           * nexthop change event -           * vnc_direct_bgp_add_prefix() will recompute VN addr ecommunity -           */ -          vnc_direct_bgp_add_prefix (bgp, import_table, rn); -        } -    } - -  if (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE)) -    { -      for (n = rn; n; n = n->parent) -        { -          //rfapiDoRouteCallback(import_table, n, NULL); -        } -      rfapiMonitorItNodeChanged (import_table, rn, NULL); -    } -  RFAPI_CHECK_REFCOUNT (rn, SAFI_MPLS_VPN, 0); -  VNC_ITRCCK; +	struct route_table *rt = NULL; +	struct route_node *rn; +	struct route_node *n; +	struct bgp_info *info_new; +	struct bgp_info *bi; +	struct bgp_info *next; +	char buf[BUFSIZ]; +	struct prefix vn_prefix; +	struct prefix un_prefix; +	int un_prefix_valid = 0; +	struct route_node *ern; +	int replacing = 0; +	int original_had_routes = 0; +	struct prefix original_nexthop; +	const char *action_str = NULL; +	int is_it_ce = 0; + +	struct bgp *bgp; +	bgp = bgp_get_default(); /* assume 1 instance for now */ + +	switch (action) { +	case FIF_ACTION_UPDATE: +		action_str = "update"; +		break; +	case FIF_ACTION_WITHDRAW: +		action_str = "withdraw"; +		break; +	case FIF_ACTION_KILL: +		action_str = "kill"; +		break; +	default: +		assert(0); +		break; +	} + +	if (import_table == bgp->rfapi->it_ce) +		is_it_ce = 1; + +	vnc_zlog_debug_verbose("%s: entry: %s%s: prefix %s/%d: it %p, afi %s", +			       __func__, (is_it_ce ? "CE-IT " : ""), action_str, +			       rfapi_ntop(p->family, &p->u.prefix, buf, BUFSIZ), +			       p->prefixlen, import_table, afi2str(afi)); + +	VNC_ITRCCK; + +	/* +	 * Compare rt lists. If no intersection, don't import this route +	 * On a withdraw, peer and RD are sufficient to determine if +	 * we should act. +	 */ +	if (action == FIF_ACTION_UPDATE) { +		if (!attr || !attr->ecommunity) { + +			vnc_zlog_debug_verbose( +				"%s: attr, extra, or ecommunity missing, not importing", +				__func__); +			return; +		} +		if ((import_table != bgp->rfapi->it_ce) +		    && !rfapiEcommunitiesIntersect(import_table->rt_import_list, +						   attr->ecommunity)) { + +			vnc_zlog_debug_verbose( +				"%s: it=%p: no ecommunity intersection", +				__func__, import_table); +			return; +		} + +		memset(&vn_prefix, 0, +		       sizeof(vn_prefix)); /* keep valgrind happy */ +		if (rfapiGetNexthop(attr, &vn_prefix)) { +			/* missing nexthop address would be a bad, bad thing */ +			vnc_zlog_debug_verbose("%s: missing nexthop", __func__); +			return; +		} +	} + +	/* +	 * Figure out which radix tree the route would go into +	 */ +	switch (afi) { +	case AFI_IP: +	case AFI_IP6: +	case AFI_L2VPN: +		rt = import_table->imported_vpn[afi]; +		break; + +	default: +		zlog_err("%s: bad afi %d", __func__, afi); +		return; +	} + +	/* clear it */ +	memset(&original_nexthop, 0, sizeof(original_nexthop)); + +	/* +	 * route_node_lookup returns a node only if there is at least +	 * one route attached. +	 */ +	rn = route_node_lookup(rt, p); + +	vnc_zlog_debug_verbose("%s: rn=%p", __func__, rn); + +	if (rn) { + +		RFAPI_CHECK_REFCOUNT(rn, SAFI_MPLS_VPN, 1); +		route_unlock_node(rn); /* undo lock in route_node_lookup */ + +		if (rn->info) +			original_had_routes = 1; + +		if (VNC_DEBUG(VERBOSE)) { +			vnc_zlog_debug_verbose("%s: showing IT node on entry", +					       __func__); +			rfapiShowItNode(NULL, rn); /* debug */ +		} + +		/* +		 * Look for same route (will have same RD and peer) +		 */ +		bi = rfapiItBiIndexSearch(rn, prd, peer, aux_prefix); + +		if (bi) { + +			/* +			 * This was an old test when we iterated over the +			 * BIs linearly. Since we're now looking up with +			 * RD and peer, comparing types should not be +			 * needed. Changed to assertion. +			 * +			 * Compare types. Doing so prevents a RFP-originated +			 * route from matching an imported route, for example. +			 */ +			assert(bi->type == type); + +			vnc_zlog_debug_verbose("%s: found matching bi", +					       __func__); + +			/* +			 * In the special CE table, withdrawals occur without +			 * holddown +			 */ +			if (import_table == bgp->rfapi->it_ce) { +				vnc_direct_bgp_del_route_ce(bgp, rn, bi); +				if (action == FIF_ACTION_WITHDRAW) +					action = FIF_ACTION_KILL; +			} + +			if (action == FIF_ACTION_WITHDRAW) { + +				int washolddown = +					CHECK_FLAG(bi->flags, BGP_INFO_REMOVED); + +				vnc_zlog_debug_verbose( +					"%s: withdrawing at prefix %s/%d%s", +					__func__, rfapi_ntop(rn->p.family, +							     &rn->p.u.prefix, +							     buf, BUFSIZ), +					rn->p.prefixlen, +					(washolddown +						 ? " (already being withdrawn)" +						 : "")); + +				VNC_ITRCCK; +				if (!washolddown) { +					rfapiBiStartWithdrawTimer( +						import_table, rn, bi, afi, +						SAFI_MPLS_VPN, +						rfapiWithdrawTimerVPN); + +					RFAPI_UPDATE_ITABLE_COUNT( +						bi, import_table, afi, -1); +					import_table->holddown_count[afi] += 1; +				} +				VNC_ITRCCK; +			} else { +				vnc_zlog_debug_verbose( +					"%s: %s at prefix %s/%d", __func__, +					((action == FIF_ACTION_KILL) +						 ? "killing" +						 : "replacing"), +					rfapi_ntop(rn->p.family, +						   &rn->p.u.prefix, buf, +						   BUFSIZ), +					rn->p.prefixlen); + +				/* +				 * If this route is waiting to be deleted +				 * because of +				 * a previous withdraw, we must cancel its +				 * timer. +				 */ +				if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED) +				    && bi->extra->vnc.import.timer) { + +					struct thread *t = +						(struct thread *)bi->extra->vnc +							.import.timer; +					struct rfapi_withdraw *wcb = t->arg; + +					XFREE(MTYPE_RFAPI_WITHDRAW, wcb); +					thread_cancel(t); + +					import_table->holddown_count[afi] -= 1; +					RFAPI_UPDATE_ITABLE_COUNT( +						bi, import_table, afi, 1); +				} +				/* +				 * decrement remote count (if route is remote) +				 * because +				 * we are going to remove it below +				 */ +				RFAPI_UPDATE_ITABLE_COUNT(bi, import_table, afi, +							  -1); +				if (action == FIF_ACTION_UPDATE) { +					replacing = 1; + +					/* +					 * make copy of original nexthop so we +					 * can see if it changed +					 */ +					rfapiGetNexthop(bi->attr, +							&original_nexthop); + +					/* +					 * remove bi without doing any export +					 * processing +					 */ +					if (CHECK_FLAG(bi->flags, +						       BGP_INFO_VALID) +					    && VALID_INTERIOR_TYPE(bi->type)) +						RFAPI_MONITOR_EXTERIOR(rn) +							->valid_interior_count--; +					rfapiItBiIndexDel(rn, bi); +					rfapiBgpInfoDetach(rn, bi); +					rfapiMonitorEncapDelete(bi); +					vnc_import_bgp_exterior_del_route_interior( +						bgp, import_table, rn, bi); +					rfapiBgpInfoFree(bi); +				} else { +					/* Kill */ +					/* +					 * remove bi and do export processing +					 */ +					import_table->holddown_count[afi] += 1; +					rfapiExpireVpnNow(import_table, rn, bi, +							  0); +				} +			} +		} +	} + +	if (rn) +		RFAPI_CHECK_REFCOUNT(rn, SAFI_MPLS_VPN, replacing ? 1 : 0); + +	if (action == FIF_ACTION_WITHDRAW || action == FIF_ACTION_KILL) { +		VNC_ITRCCK; +		return; +	} + +	info_new = +		rfapiBgpInfoCreate(attr, peer, rfd, prd, type, sub_type, label); + +	/* +	 * lookup un address in encap table +	 */ +	ern = route_node_match(import_table->imported_encap[afi], &vn_prefix); +	if (ern) { +		rfapiCopyUnEncap2VPN(ern->info, info_new); +		route_unlock_node(ern); /* undo lock in route_note_match */ +	} else { +		char buf[BUFSIZ]; +		prefix2str(&vn_prefix, buf, sizeof(buf)); +		buf[BUFSIZ - 1] = 0; +		/* Not a big deal, just means VPN route got here first */ +		vnc_zlog_debug_verbose("%s: no encap route for vn addr %s", +				       __func__, buf); +		info_new->extra->vnc.import.un_family = 0; +	} + +	if (rn) { +		if (!replacing) +			route_lock_node(rn); +	} else { +		/* +		 * No need to increment reference count, so only "get" +		 * if the node is not there already +		 */ +		rn = route_node_get(rt, p); +	} + +	/* +	 * For ethernet routes, if there is an accompanying IP address, +	 * save it in the bi +	 */ +	if ((AFI_L2VPN == afi) && aux_prefix) { + +		vnc_zlog_debug_verbose("%s: setting BI's aux_prefix", __func__); +		info_new->extra->vnc.import.aux_prefix = *aux_prefix; +	} + +	vnc_zlog_debug_verbose( +		"%s: inserting bi %p at prefix %s/%d #%d", __func__, info_new, +		rfapi_ntop(rn->p.family, &rn->p.u.prefix, buf, BUFSIZ), +		rn->p.prefixlen, rn->lock); + +	rfapiBgpInfoAttachSorted(rn, info_new, afi, SAFI_MPLS_VPN); +	rfapiItBiIndexAdd(rn, info_new); +	if (!rfapiGetUnAddrOfVpnBi(info_new, NULL)) { +		if (VALID_INTERIOR_TYPE(info_new->type)) +			RFAPI_MONITOR_EXTERIOR(rn)->valid_interior_count++; +		SET_FLAG(info_new->flags, BGP_INFO_VALID); +	} +	RFAPI_UPDATE_ITABLE_COUNT(info_new, import_table, afi, 1); +	vnc_import_bgp_exterior_add_route_interior(bgp, import_table, rn, +						   info_new); + +	if (import_table == bgp->rfapi->it_ce) +		vnc_direct_bgp_add_route_ce(bgp, rn, info_new); + +	if (VNC_DEBUG(VERBOSE)) { +		vnc_zlog_debug_verbose("%s: showing IT node", __func__); +		rfapiShowItNode(NULL, rn); /* debug */ +	} + +	rfapiMonitorEncapAdd(import_table, &vn_prefix, rn, info_new); + +	if (!rfapiGetUnAddrOfVpnBi(info_new, &un_prefix)) { + +		/* +		 * if we have a valid UN address (either via Encap route +		 * or via tunnel attribute), then we should attempt +		 * to move any monitors at less-specific nodes to this node +		 */ +		rfapiMonitorMoveLonger(rn); + +		un_prefix_valid = 1; +	} + +	/* +	 * 101129 Enhancement: if we add a route (implication: it is not +	 * in holddown), delete all other routes from this nve at this +	 * node that are in holddown, regardless of peer. +	 * +	 * Reasons it's OK to do that: +	 * +	 * - if the holddown route being deleted originally came from BGP VPN, +	 *   it is already gone from BGP (implication of holddown), so there +	 *   won't be any added inconsistency with the BGP RIB. +	 * +	 * - once a fresh route is added at a prefix, any routes in holddown +	 *   at that prefix will not show up in RFP responses, so deleting +	 *   the holddown routes won't affect the contents of responses. +	 * +	 * - lifetimes are supposed to be consistent, so there should not +	 *   be a case where the fresh route has a shorter lifetime than +	 *   the holddown route, so we don't expect the fresh route to +	 *   disappear and complete its holddown time before the existing +	 *   holddown routes time out. Therefore, we won't have a situation +	 *   where we expect the existing holddown routes to be hidden and +	 *   then  to reappear sometime later (as holddown routes) in a +	 *   RFP response. +	 * +	 * Among other things, this would enable us to skirt the problem +	 * of local holddown routes that refer to NVE descriptors that +	 * have already been closed (if the same NVE triggers a subsequent +	 * rfapi_open(), the new peer is different and doesn't match the +	 * peer of the holddown route, so the stale holddown route still +	 * hangs around until it times out instead of just being replaced +	 * by the fresh route). +	 */ +	/* +	 * We know that the new bi will have been inserted before any routes +	 * in holddown, so we can skip any that came before it +	 */ +	for (bi = info_new->next; bi; bi = next) { + +		struct prefix pfx_vn; +		struct prefix pfx_un; +		int un_match = 0; +		int remote_peer_match = 0; + +		next = bi->next; + +		/* +		 * Must be holddown +		 */ +		if (!CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) +			continue; + +		/* +		 * Must match VN address (nexthop of VPN route) +		 */ +		if (rfapiGetNexthop(bi->attr, &pfx_vn)) +			continue; +		if (!prefix_same(&pfx_vn, &vn_prefix)) +			continue; + +		if (un_prefix_valid && /* new route UN addr */ +		    !rfapiGetUnAddrOfVpnBi(bi, &pfx_un) +		    &&					/* old route UN addr */ +		    prefix_same(&pfx_un, &un_prefix)) { /* compare */ +			un_match = 1; +		} +		if (!RFAPI_LOCAL_BI(bi) && !RFAPI_LOCAL_BI(info_new) +		    && sockunion_same(&bi->peer->su, &info_new->peer->su)) { +			/* old & new are both remote, same peer */ +			remote_peer_match = 1; +		} + +		if (!un_match & !remote_peer_match) +			continue; + +		vnc_zlog_debug_verbose( +			"%s: removing holddown bi matching NVE of new route", +			__func__); +		if (bi->extra->vnc.import.timer) { +			struct thread *t = +				(struct thread *)bi->extra->vnc.import.timer; +			struct rfapi_withdraw *wcb = t->arg; + +			XFREE(MTYPE_RFAPI_WITHDRAW, wcb); +			thread_cancel(t); +		} +		rfapiExpireVpnNow(import_table, rn, bi, 0); +	} + +	if (!original_had_routes) { +		/* +		 * We went from 0 usable routes to 1 usable route. Perform the +		 * "Adding a Route" export process. +		 */ +		vnc_direct_bgp_add_prefix(bgp, import_table, rn); +		vnc_zebra_add_prefix(bgp, import_table, rn); +	} else { +		/* +		 * Check for nexthop change event +		 * Note: the prefix_same() test below detects two situations: +		 * 1. route is replaced, new route has different nexthop +		 * 2. new route is added (original_nexthop is 0) +		 */ +		struct prefix new_nexthop; + +		rfapiGetNexthop(attr, &new_nexthop); +		if (!prefix_same(&original_nexthop, &new_nexthop)) { +			/* +			 * nexthop change event +			 * vnc_direct_bgp_add_prefix() will recompute VN addr +			 * ecommunity +			 */ +			vnc_direct_bgp_add_prefix(bgp, import_table, rn); +		} +	} + +	if (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE)) { +		for (n = rn; n; n = n->parent) { +			// rfapiDoRouteCallback(import_table, n, NULL); +		} +		rfapiMonitorItNodeChanged(import_table, rn, NULL); +	} +	RFAPI_CHECK_REFCOUNT(rn, SAFI_MPLS_VPN, 0); +	VNC_ITRCCK;  }  static rfapi_bi_filtered_import_f * -rfapiBgpInfoFilteredImportFunction (safi_t safi) +rfapiBgpInfoFilteredImportFunction(safi_t safi)  { -  switch (safi) -    { -    case SAFI_MPLS_VPN: -      return rfapiBgpInfoFilteredImportVPN; - -    case SAFI_ENCAP: -      return rfapiBgpInfoFilteredImportEncap; -    } -  zlog_err ("%s: bad safi %d", __func__, safi); -  return NULL; +	switch (safi) { +	case SAFI_MPLS_VPN: +		return rfapiBgpInfoFilteredImportVPN; + +	case SAFI_ENCAP: +		return rfapiBgpInfoFilteredImportEncap; +	} +	zlog_err("%s: bad safi %d", __func__, safi); +	return NULL;  } -void -rfapiProcessUpdate ( -  struct peer		*peer, -  void			*rfd,	/* set when looped from RFP/RFAPI */ -  struct prefix		*p, -  struct prefix_rd	*prd, -  struct attr		*attr, -  afi_t			afi, -  safi_t		safi, -  u_char		type, -  u_char		sub_type, -  uint32_t		*label) +void rfapiProcessUpdate(struct peer *peer, +			void *rfd, /* set when looped from RFP/RFAPI */ +			struct prefix *p, struct prefix_rd *prd, +			struct attr *attr, afi_t afi, safi_t safi, u_char type, +			u_char sub_type, uint32_t *label)  { -  struct bgp			*bgp; -  struct rfapi			*h; -  struct rfapi_import_table	*it; -  int				has_ip_route = 1; -  uint32_t			lni = 0; - -  bgp = bgp_get_default ();     /* assume 1 instance for now */ -  assert (bgp); - -  h = bgp->rfapi; -  assert (h); - -  /* -   * look at high-order byte of RD. FF means MAC -   * address is present (VNC L2VPN) -   */ -  if ((safi == SAFI_MPLS_VPN) &&  -      (decode_rd_type(prd->val) == RD_TYPE_VNC_ETH)) -    { -      struct prefix pfx_mac_buf; -      struct prefix pfx_nexthop_buf; -      int rc; - -      /* -       * Set flag if prefix and nexthop are the same - don't -       * add the route to normal IP-based import tables -       */ -      if (!rfapiGetNexthop (attr, &pfx_nexthop_buf)) -        { -          if (!prefix_cmp (&pfx_nexthop_buf, p)) -            { -              has_ip_route = 0; -            } -        } - -      memset (&pfx_mac_buf, 0, sizeof (pfx_mac_buf)); -      pfx_mac_buf.family = AF_ETHERNET; -      pfx_mac_buf.prefixlen = 48; -      memcpy (&pfx_mac_buf.u.prefix_eth.octet, prd->val + 2, 6); - -      /* -       * Find rt containing LNI (Logical Network ID), which -       * _should_ always be present when mac address is present -       */ -      rc = rfapiEcommunityGetLNI (attr->ecommunity, &lni); - -      vnc_zlog_debug_verbose -        ("%s: rfapiEcommunityGetLNI returned %d, lni=%d, attr=%p", -         __func__, rc, lni, attr); -      if (attr && !rc) -        { -          it = rfapiMacImportTableGet (bgp, lni); - -          rfapiBgpInfoFilteredImportVPN ( -	    it, -	    FIF_ACTION_UPDATE, -	    peer, -	    rfd, -	    &pfx_mac_buf,	/* prefix */ -	    p,			/* aux prefix: IP addr */ -	    AFI_L2VPN, -	    prd, -	    attr, -	    type, -	    sub_type, -	    label); -        } - -    } - -  if (!has_ip_route) -    return; - -  /* -   * Iterate over all import tables; do a filtered import -   * for the afi/safi combination -   */ -  for (it = h->imports; it; it = it->next) -    { -      (*rfapiBgpInfoFilteredImportFunction (safi)) ( -	it, -	FIF_ACTION_UPDATE, -	peer, -	rfd, -	p,        /* prefix */ -	NULL, -	afi, -	prd, -	attr, -	type, -	sub_type, -	label); -    } - -  if (safi == SAFI_MPLS_VPN) -    { -      vnc_direct_bgp_rh_add_route (bgp, afi, p, peer, attr); -    } - -  if (safi == SAFI_MPLS_VPN) -    { -      rfapiBgpInfoFilteredImportVPN ( -	bgp->rfapi->it_ce, -	FIF_ACTION_UPDATE, -	peer, -	rfd, -	p,        /* prefix */ -	NULL, -	afi, -	prd, -	attr, -	type, -	sub_type, -	label); -    } +	struct bgp *bgp; +	struct rfapi *h; +	struct rfapi_import_table *it; +	int has_ip_route = 1; +	uint32_t lni = 0; + +	bgp = bgp_get_default(); /* assume 1 instance for now */ +	assert(bgp); + +	h = bgp->rfapi; +	assert(h); + +	/* +	 * look at high-order byte of RD. FF means MAC +	 * address is present (VNC L2VPN) +	 */ +	if ((safi == SAFI_MPLS_VPN) +	    && (decode_rd_type(prd->val) == RD_TYPE_VNC_ETH)) { +		struct prefix pfx_mac_buf; +		struct prefix pfx_nexthop_buf; +		int rc; + +		/* +		 * Set flag if prefix and nexthop are the same - don't +		 * add the route to normal IP-based import tables +		 */ +		if (!rfapiGetNexthop(attr, &pfx_nexthop_buf)) { +			if (!prefix_cmp(&pfx_nexthop_buf, p)) { +				has_ip_route = 0; +			} +		} + +		memset(&pfx_mac_buf, 0, sizeof(pfx_mac_buf)); +		pfx_mac_buf.family = AF_ETHERNET; +		pfx_mac_buf.prefixlen = 48; +		memcpy(&pfx_mac_buf.u.prefix_eth.octet, prd->val + 2, 6); + +		/* +		 * Find rt containing LNI (Logical Network ID), which +		 * _should_ always be present when mac address is present +		 */ +		rc = rfapiEcommunityGetLNI(attr->ecommunity, &lni); + +		vnc_zlog_debug_verbose( +			"%s: rfapiEcommunityGetLNI returned %d, lni=%d, attr=%p", +			__func__, rc, lni, attr); +		if (attr && !rc) { +			it = rfapiMacImportTableGet(bgp, lni); + +			rfapiBgpInfoFilteredImportVPN( +				it, FIF_ACTION_UPDATE, peer, rfd, +				&pfx_mac_buf, /* prefix */ +				p,	    /* aux prefix: IP addr */ +				AFI_L2VPN, prd, attr, type, sub_type, label); +		} +	} + +	if (!has_ip_route) +		return; + +	/* +	 * Iterate over all import tables; do a filtered import +	 * for the afi/safi combination +	 */ +	for (it = h->imports; it; it = it->next) { +		(*rfapiBgpInfoFilteredImportFunction(safi))( +			it, FIF_ACTION_UPDATE, peer, rfd, p, /* prefix */ +			NULL, afi, prd, attr, type, sub_type, label); +	} + +	if (safi == SAFI_MPLS_VPN) { +		vnc_direct_bgp_rh_add_route(bgp, afi, p, peer, attr); +	} + +	if (safi == SAFI_MPLS_VPN) { +		rfapiBgpInfoFilteredImportVPN( +			bgp->rfapi->it_ce, FIF_ACTION_UPDATE, peer, rfd, +			p, /* prefix */ +			NULL, afi, prd, attr, type, sub_type, label); +	}  } -void -rfapiProcessWithdraw ( -  struct peer		*peer, -  void			*rfd, -  struct prefix		*p, -  struct prefix_rd	*prd, -  struct attr		*attr, -  afi_t			afi, -  safi_t		safi, -  u_char		type, -  int			kill) +void rfapiProcessWithdraw(struct peer *peer, void *rfd, struct prefix *p, +			  struct prefix_rd *prd, struct attr *attr, afi_t afi, +			  safi_t safi, u_char type, int kill)  { -  struct bgp *bgp; -  struct rfapi *h; -  struct rfapi_import_table *it; - -  bgp = bgp_get_default ();     /* assume 1 instance for now */ -  assert (bgp); - -  h = bgp->rfapi; -  assert (h); - -  /* -   * look at high-order byte of RD. FF means MAC -   * address is present (VNC L2VPN) -   */ -  if (h->import_mac != NULL && safi == SAFI_MPLS_VPN && -      decode_rd_type(prd->val) == RD_TYPE_VNC_ETH) -    { -      struct prefix pfx_mac_buf; -      void *cursor = NULL; -      int rc; - -      memset (&pfx_mac_buf, 0, sizeof (pfx_mac_buf)); -      pfx_mac_buf.family = AF_ETHERNET; -      pfx_mac_buf.prefixlen = 48; -      memcpy (&pfx_mac_buf.u.prefix_eth, prd->val + 2, 6); - -      /* -       * withdraw does not contain attrs, so we don't have -       * access to the route's LNI, which would ordinarily -       * select the specific mac-based import table. Instead, -       * we must iterate over all mac-based tables and rely -       * on the RD to match. -       * -       * If this approach is too slow, add an index where -       * key is {RD, peer} and value is the import table -       */ -      for (rc = skiplist_next (h->import_mac, NULL, (void **) &it, &cursor); -           rc == 0; -           rc = skiplist_next (h->import_mac, NULL, (void **) &it, &cursor)) -        { +	struct bgp *bgp; +	struct rfapi *h; +	struct rfapi_import_table *it; + +	bgp = bgp_get_default(); /* assume 1 instance for now */ +	assert(bgp); + +	h = bgp->rfapi; +	assert(h); + +	/* +	 * look at high-order byte of RD. FF means MAC +	 * address is present (VNC L2VPN) +	 */ +	if (h->import_mac != NULL && safi == SAFI_MPLS_VPN +	    && decode_rd_type(prd->val) == RD_TYPE_VNC_ETH) { +		struct prefix pfx_mac_buf; +		void *cursor = NULL; +		int rc; + +		memset(&pfx_mac_buf, 0, sizeof(pfx_mac_buf)); +		pfx_mac_buf.family = AF_ETHERNET; +		pfx_mac_buf.prefixlen = 48; +		memcpy(&pfx_mac_buf.u.prefix_eth, prd->val + 2, 6); + +		/* +		 * withdraw does not contain attrs, so we don't have +		 * access to the route's LNI, which would ordinarily +		 * select the specific mac-based import table. Instead, +		 * we must iterate over all mac-based tables and rely +		 * on the RD to match. +		 * +		 * If this approach is too slow, add an index where +		 * key is {RD, peer} and value is the import table +		 */ +		for (rc = skiplist_next(h->import_mac, NULL, (void **)&it, +					&cursor); +		     rc == 0; rc = skiplist_next(h->import_mac, NULL, +						 (void **)&it, &cursor)) {  #if DEBUG_L2_EXTRA -          vnc_zlog_debug_verbose -            ("%s: calling rfapiBgpInfoFilteredImportVPN(it=%p, afi=AFI_L2VPN)", -             __func__, it); +			vnc_zlog_debug_verbose( +				"%s: calling rfapiBgpInfoFilteredImportVPN(it=%p, afi=AFI_L2VPN)", +				__func__, it);  #endif -          rfapiBgpInfoFilteredImportVPN ( -	    it, -	    (kill ? FIF_ACTION_KILL : FIF_ACTION_WITHDRAW), -	    peer, -	    rfd, -	    &pfx_mac_buf,	/* prefix */ -	    p,			/* aux_prefix: IP */ -	    AFI_L2VPN, -	    prd, -	    attr, -	    type, -	    0, -	    NULL);		/* sub_type & label unused for withdraw */ -        } -    } - -  /* -   * XXX For the case where the withdraw involves an L2 -   * route with no IP information, we rely on the lack -   * of RT-list intersection to filter out the withdraw -   * from the IP-based import tables below -   */ - -  /* -   * Iterate over all import tables; do a filtered import -   * for the afi/safi combination -   */ - -  for (it = h->imports; it; it = it->next) -    { -      (*rfapiBgpInfoFilteredImportFunction (safi)) ( -	it, -	(kill ? FIF_ACTION_KILL : FIF_ACTION_WITHDRAW), -	peer, -	rfd, -	p,	/* prefix */ -	NULL, -	afi, -	prd, -	attr, -	type, -	0, -	NULL);	/* sub_type & label unused for withdraw */ -    } - -  /* TBD the deletion should happen after the lifetime expires */ -  if (safi == SAFI_MPLS_VPN) -    vnc_direct_bgp_rh_del_route (bgp, afi, p, peer); - -  if (safi == SAFI_MPLS_VPN) -    { -      rfapiBgpInfoFilteredImportVPN ( -	bgp->rfapi->it_ce, -	(kill ? FIF_ACTION_KILL : FIF_ACTION_WITHDRAW), -	peer, -	rfd, -	p,	/* prefix */ -	NULL, -	afi, -	prd, -	attr, -	type, -	0, -	NULL);	/* sub_type & label unused for withdraw */ -    } +			rfapiBgpInfoFilteredImportVPN( +				it, +				(kill ? FIF_ACTION_KILL : FIF_ACTION_WITHDRAW), +				peer, rfd, &pfx_mac_buf, /* prefix */ +				p,			 /* aux_prefix: IP */ +				AFI_L2VPN, prd, attr, type, 0, +				NULL); /* sub_type & label unused for withdraw +					  */ +		} +	} + +	/* +	 * XXX For the case where the withdraw involves an L2 +	 * route with no IP information, we rely on the lack +	 * of RT-list intersection to filter out the withdraw +	 * from the IP-based import tables below +	 */ + +	/* +	 * Iterate over all import tables; do a filtered import +	 * for the afi/safi combination +	 */ + +	for (it = h->imports; it; it = it->next) { +		(*rfapiBgpInfoFilteredImportFunction(safi))( +			it, (kill ? FIF_ACTION_KILL : FIF_ACTION_WITHDRAW), +			peer, rfd, p, /* prefix */ +			NULL, afi, prd, attr, type, 0, +			NULL); /* sub_type & label unused for withdraw */ +	} + +	/* TBD the deletion should happen after the lifetime expires */ +	if (safi == SAFI_MPLS_VPN) +		vnc_direct_bgp_rh_del_route(bgp, afi, p, peer); + +	if (safi == SAFI_MPLS_VPN) { +		rfapiBgpInfoFilteredImportVPN( +			bgp->rfapi->it_ce, +			(kill ? FIF_ACTION_KILL : FIF_ACTION_WITHDRAW), peer, +			rfd, p, /* prefix */ +			NULL, afi, prd, attr, type, 0, +			NULL); /* sub_type & label unused for withdraw */ +	}  }  /* @@ -4378,65 +4087,57 @@ rfapiProcessWithdraw (  /* surprise, this gets called from peer_delete(), from rfapi_close() */ -static void -rfapiProcessPeerDownRt ( -  struct peer			*peer, -  struct rfapi_import_table	*import_table, -  afi_t				afi, -  safi_t			safi) +static void rfapiProcessPeerDownRt(struct peer *peer, +				   struct rfapi_import_table *import_table, +				   afi_t afi, safi_t safi)  { -  struct route_node	*rn; -  struct bgp_info	*bi; -  struct route_table	*rt; -  int			(*timer_service_func) (struct thread *); - -  assert (afi == AFI_IP || afi == AFI_IP6); - -  VNC_ITRCCK; - -  switch (safi) -    { -    case SAFI_MPLS_VPN: -      rt = import_table->imported_vpn[afi]; -      timer_service_func = rfapiWithdrawTimerVPN; -      break; -    case SAFI_ENCAP: -      rt = import_table->imported_encap[afi]; -      timer_service_func = rfapiWithdrawTimerEncap; -      break; -    default: -      assert (0); -    } - - -  for (rn = route_top (rt); rn; rn = route_next (rn)) -    { -      for (bi = rn->info; bi; bi = bi->next) -        { -          if (bi->peer == peer) -            { - -              if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) -                { -                  /* already in holddown, skip */ -                  continue; -                } - -              if (safi == SAFI_MPLS_VPN) -                { -                  RFAPI_UPDATE_ITABLE_COUNT (bi, import_table, afi, -1); -                  import_table->holddown_count[afi] += 1; -                } -              rfapiBiStartWithdrawTimer (import_table, rn, bi, -                                         afi, safi, -                                         timer_service_func); -            } -        } -    } -  VNC_ITRCCK; +	struct route_node *rn; +	struct bgp_info *bi; +	struct route_table *rt; +	int (*timer_service_func)(struct thread *); + +	assert(afi == AFI_IP || afi == AFI_IP6); + +	VNC_ITRCCK; + +	switch (safi) { +	case SAFI_MPLS_VPN: +		rt = import_table->imported_vpn[afi]; +		timer_service_func = rfapiWithdrawTimerVPN; +		break; +	case SAFI_ENCAP: +		rt = import_table->imported_encap[afi]; +		timer_service_func = rfapiWithdrawTimerEncap; +		break; +	default: +		assert(0); +	} + + +	for (rn = route_top(rt); rn; rn = route_next(rn)) { +		for (bi = rn->info; bi; bi = bi->next) { +			if (bi->peer == peer) { + +				if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) { +					/* already in holddown, skip */ +					continue; +				} + +				if (safi == SAFI_MPLS_VPN) { +					RFAPI_UPDATE_ITABLE_COUNT( +						bi, import_table, afi, -1); +					import_table->holddown_count[afi] += 1; +				} +				rfapiBiStartWithdrawTimer(import_table, rn, bi, +							  afi, safi, +							  timer_service_func); +			} +		} +	} +	VNC_ITRCCK;  } -/*  +/*   * This gets called when a peer connection drops. We have to remove   * all the routes from this peer.   * @@ -4444,49 +4145,46 @@ rfapiProcessPeerDownRt (   * grouping withdrawn routes so we can generate callbacks more   * efficiently.   */ -void -rfapiProcessPeerDown (struct peer *peer) +void rfapiProcessPeerDown(struct peer *peer)  { -  struct bgp *bgp; -  struct rfapi *h; -  struct rfapi_import_table *it; - -  /* -   * If this peer is a "dummy" peer structure atached to a RFAPI -   * nve_descriptor, we don't need to walk the import tables -   * because the routes are already withdrawn by rfapi_close() -   */ -  if (CHECK_FLAG (peer->flags, PEER_FLAG_IS_RFAPI_HD)) -    return; - -  /* -   * 1. Visit all BIs in all ENCAP import tables. -   *    Start withdraw timer on the BIs that match peer. -   * -   * 2. Visit All BIs in all VPN import tables. -   *    Start withdraw timer on the BIs that match peer. -   */ - -  bgp = bgp_get_default ();     /* assume 1 instance for now */ -  if (!bgp) -    return; - -  h = bgp->rfapi; -  assert (h); - -  for (it = h->imports; it; it = it->next) -    { -      rfapiProcessPeerDownRt (peer, it, AFI_IP, SAFI_ENCAP); -      rfapiProcessPeerDownRt (peer, it, AFI_IP6, SAFI_ENCAP); -      rfapiProcessPeerDownRt (peer, it, AFI_IP, SAFI_MPLS_VPN); -      rfapiProcessPeerDownRt (peer, it, AFI_IP6, SAFI_MPLS_VPN); -    } - -  if (h->it_ce) -    { -      rfapiProcessPeerDownRt (peer, h->it_ce, AFI_IP, SAFI_MPLS_VPN); -      rfapiProcessPeerDownRt (peer, h->it_ce, AFI_IP6, SAFI_MPLS_VPN); -    } +	struct bgp *bgp; +	struct rfapi *h; +	struct rfapi_import_table *it; + +	/* +	 * If this peer is a "dummy" peer structure atached to a RFAPI +	 * nve_descriptor, we don't need to walk the import tables +	 * because the routes are already withdrawn by rfapi_close() +	 */ +	if (CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)) +		return; + +	/* +	 * 1. Visit all BIs in all ENCAP import tables. +	 *    Start withdraw timer on the BIs that match peer. +	 * +	 * 2. Visit All BIs in all VPN import tables. +	 *    Start withdraw timer on the BIs that match peer. +	 */ + +	bgp = bgp_get_default(); /* assume 1 instance for now */ +	if (!bgp) +		return; + +	h = bgp->rfapi; +	assert(h); + +	for (it = h->imports; it; it = it->next) { +		rfapiProcessPeerDownRt(peer, it, AFI_IP, SAFI_ENCAP); +		rfapiProcessPeerDownRt(peer, it, AFI_IP6, SAFI_ENCAP); +		rfapiProcessPeerDownRt(peer, it, AFI_IP, SAFI_MPLS_VPN); +		rfapiProcessPeerDownRt(peer, it, AFI_IP6, SAFI_MPLS_VPN); +	} + +	if (h->it_ce) { +		rfapiProcessPeerDownRt(peer, h->it_ce, AFI_IP, SAFI_MPLS_VPN); +		rfapiProcessPeerDownRt(peer, h->it_ce, AFI_IP6, SAFI_MPLS_VPN); +	}  }  /* @@ -4494,445 +4192,431 @@ rfapiProcessPeerDown (struct peer *peer)   * filtered according to the import table's RT list   *   * TBD: does this function need additions to match rfapiProcessUpdate() - * for, e.g., L2 handling?  + * for, e.g., L2 handling?   */ -static void -rfapiBgpTableFilteredImport ( -  struct bgp			*bgp, -  struct rfapi_import_table	*it, -  afi_t				afi, -  safi_t			safi) +static void rfapiBgpTableFilteredImport(struct bgp *bgp, +					struct rfapi_import_table *it, +					afi_t afi, safi_t safi)  { -  struct bgp_node *rn1; -  struct bgp_node *rn2; - -  /* Only these SAFIs have 2-level RIBS */ -  assert (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP); - -  /*  -   * Now visit all the rd nodes and the nodes of all the -   * route tables attached to them, and import the routes -   * if they have matching route targets -   */ -  for (rn1 = bgp_table_top (bgp->rib[afi][safi]); -       rn1; rn1 = bgp_route_next (rn1)) -    { - -      if (rn1->info) -        { -          for (rn2 = bgp_table_top (rn1->info); -               rn2; rn2 = bgp_route_next (rn2)) -            { - -              struct bgp_info *bi; - -              for (bi = rn2->info; bi; bi = bi->next) -                { -                  u_int32_t label = 0; - -                  if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) -                    continue; - -                  if (bi->extra) -                    label = decode_label (&bi->extra->label); -                  (*rfapiBgpInfoFilteredImportFunction (safi)) ( -		    it,				/* which import table */ -		    FIF_ACTION_UPDATE, -		    bi->peer, -		    NULL, -		    &rn2->p,			/* prefix */ -		    NULL, -		    afi, -		    (struct prefix_rd *) &rn1->p, -		    bi->attr, -		    bi->type, -		    bi->sub_type, -		    &label); -                } -            } -        } -    } +	struct bgp_node *rn1; +	struct bgp_node *rn2; + +	/* Only these SAFIs have 2-level RIBS */ +	assert(safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP); + +	/* +	 * Now visit all the rd nodes and the nodes of all the +	 * route tables attached to them, and import the routes +	 * if they have matching route targets +	 */ +	for (rn1 = bgp_table_top(bgp->rib[afi][safi]); rn1; +	     rn1 = bgp_route_next(rn1)) { + +		if (rn1->info) { +			for (rn2 = bgp_table_top(rn1->info); rn2; +			     rn2 = bgp_route_next(rn2)) { + +				struct bgp_info *bi; + +				for (bi = rn2->info; bi; bi = bi->next) { +					u_int32_t label = 0; + +					if (CHECK_FLAG(bi->flags, +						       BGP_INFO_REMOVED)) +						continue; + +					if (bi->extra) +						label = decode_label( +							&bi->extra->label); +					(*rfapiBgpInfoFilteredImportFunction( +						safi))( +						it, /* which import table */ +						FIF_ACTION_UPDATE, bi->peer, +						NULL, &rn2->p, /* prefix */ +						NULL, afi, +						(struct prefix_rd *)&rn1->p, +						bi->attr, bi->type, +						bi->sub_type, &label); +				} +			} +		} +	}  }  /* per-bgp-instance rfapi data */ -struct rfapi * -bgp_rfapi_new (struct bgp *bgp) +struct rfapi *bgp_rfapi_new(struct bgp *bgp)  { -  struct rfapi *h; -  int afi; -  struct rfapi_rfp_cfg *cfg = NULL; -  struct rfapi_rfp_cb_methods *cbm = NULL; - -  assert (bgp->rfapi_cfg == NULL); - -  h = (struct rfapi *) XCALLOC (MTYPE_RFAPI, sizeof (struct rfapi)); - -  for (afi = AFI_IP; afi < AFI_MAX; afi++) -    { -      /* ugly, to deal with addition of delegates, part of 0.99.24.1 merge */ -      h->un[afi].delegate = route_table_get_default_delegate (); -    } - -  /* -   * initialize the ce import table -   */ -  h->it_ce = -    XCALLOC (MTYPE_RFAPI_IMPORTTABLE, sizeof (struct rfapi_import_table)); -  h->it_ce->imported_vpn[AFI_IP] = route_table_init (); -  h->it_ce->imported_vpn[AFI_IP6] = route_table_init (); -  h->it_ce->imported_encap[AFI_IP] = route_table_init (); -  h->it_ce->imported_encap[AFI_IP6] = route_table_init (); -  rfapiBgpTableFilteredImport (bgp, h->it_ce, AFI_IP, SAFI_MPLS_VPN); -  rfapiBgpTableFilteredImport (bgp, h->it_ce, AFI_IP6, SAFI_MPLS_VPN); - -  /*  -   * Set up work queue for deferred rfapi_close operations -   */ -  h->deferred_close_q = work_queue_new (bm->master, "rfapi deferred close"); -  h->deferred_close_q->spec.workfunc = rfapi_deferred_close_workfunc; -  h->deferred_close_q->spec.data = h; - -  h->rfp = rfp_start (bm->master, &cfg, &cbm); -  bgp->rfapi_cfg = bgp_rfapi_cfg_new (cfg); -  if (cbm != NULL) -    { -      h->rfp_methods = *cbm; -    } -  return h; +	struct rfapi *h; +	int afi; +	struct rfapi_rfp_cfg *cfg = NULL; +	struct rfapi_rfp_cb_methods *cbm = NULL; + +	assert(bgp->rfapi_cfg == NULL); + +	h = (struct rfapi *)XCALLOC(MTYPE_RFAPI, sizeof(struct rfapi)); + +	for (afi = AFI_IP; afi < AFI_MAX; afi++) { +		/* ugly, to deal with addition of delegates, part of 0.99.24.1 +		 * merge */ +		h->un[afi].delegate = route_table_get_default_delegate(); +	} + +	/* +	 * initialize the ce import table +	 */ +	h->it_ce = XCALLOC(MTYPE_RFAPI_IMPORTTABLE, +			   sizeof(struct rfapi_import_table)); +	h->it_ce->imported_vpn[AFI_IP] = route_table_init(); +	h->it_ce->imported_vpn[AFI_IP6] = route_table_init(); +	h->it_ce->imported_encap[AFI_IP] = route_table_init(); +	h->it_ce->imported_encap[AFI_IP6] = route_table_init(); +	rfapiBgpTableFilteredImport(bgp, h->it_ce, AFI_IP, SAFI_MPLS_VPN); +	rfapiBgpTableFilteredImport(bgp, h->it_ce, AFI_IP6, SAFI_MPLS_VPN); + +	/* +	 * Set up work queue for deferred rfapi_close operations +	 */ +	h->deferred_close_q = +		work_queue_new(bm->master, "rfapi deferred close"); +	h->deferred_close_q->spec.workfunc = rfapi_deferred_close_workfunc; +	h->deferred_close_q->spec.data = h; + +	h->rfp = rfp_start(bm->master, &cfg, &cbm); +	bgp->rfapi_cfg = bgp_rfapi_cfg_new(cfg); +	if (cbm != NULL) { +		h->rfp_methods = *cbm; +	} +	return h;  } -void -bgp_rfapi_destroy (struct bgp *bgp, struct rfapi *h) +void bgp_rfapi_destroy(struct bgp *bgp, struct rfapi *h)  { -  if (bgp == NULL || h == NULL) -    return; - -  if (h->resolve_nve_nexthop) -    { -      skiplist_free (h->resolve_nve_nexthop); -      h->resolve_nve_nexthop = NULL; -    } - -  route_table_finish (h->it_ce->imported_vpn[AFI_IP]); -  route_table_finish (h->it_ce->imported_vpn[AFI_IP6]); -  route_table_finish (h->it_ce->imported_encap[AFI_IP]); -  route_table_finish (h->it_ce->imported_encap[AFI_IP6]); - -  if (h->import_mac) -    { -      struct rfapi_import_table *it; -      void *cursor; -      int rc; - -      for (cursor = NULL, -           rc = skiplist_next (h->import_mac, NULL, (void **) &it, &cursor); -           !rc; -           rc = skiplist_next (h->import_mac, NULL, (void **) &it, &cursor)) -        { - -          rfapiImportTableFlush (it); -          XFREE (MTYPE_RFAPI_IMPORTTABLE, it); -        } -      skiplist_free (h->import_mac); -      h->import_mac = NULL; -    } - -  work_queue_free (h->deferred_close_q); - -  if (h->rfp != NULL) -    rfp_stop (h->rfp); -  XFREE (MTYPE_RFAPI_IMPORTTABLE, h->it_ce); -  XFREE (MTYPE_RFAPI, h); +	if (bgp == NULL || h == NULL) +		return; + +	if (h->resolve_nve_nexthop) { +		skiplist_free(h->resolve_nve_nexthop); +		h->resolve_nve_nexthop = NULL; +	} + +	route_table_finish(h->it_ce->imported_vpn[AFI_IP]); +	route_table_finish(h->it_ce->imported_vpn[AFI_IP6]); +	route_table_finish(h->it_ce->imported_encap[AFI_IP]); +	route_table_finish(h->it_ce->imported_encap[AFI_IP6]); + +	if (h->import_mac) { +		struct rfapi_import_table *it; +		void *cursor; +		int rc; + +		for (cursor = NULL, +		    rc = skiplist_next(h->import_mac, NULL, (void **)&it, +				       &cursor); +		     !rc; rc = skiplist_next(h->import_mac, NULL, (void **)&it, +					     &cursor)) { + +			rfapiImportTableFlush(it); +			XFREE(MTYPE_RFAPI_IMPORTTABLE, it); +		} +		skiplist_free(h->import_mac); +		h->import_mac = NULL; +	} + +	work_queue_free(h->deferred_close_q); + +	if (h->rfp != NULL) +		rfp_stop(h->rfp); +	XFREE(MTYPE_RFAPI_IMPORTTABLE, h->it_ce); +	XFREE(MTYPE_RFAPI, h);  }  struct rfapi_import_table * -rfapiImportTableRefAdd (struct bgp *bgp, struct ecommunity *rt_import_list, -                        struct rfapi_nve_group_cfg *rfg) +rfapiImportTableRefAdd(struct bgp *bgp, struct ecommunity *rt_import_list, +		       struct rfapi_nve_group_cfg *rfg)  { -  struct rfapi *h; -  struct rfapi_import_table *it; -  afi_t afi; - -  h = bgp->rfapi; -  assert (h); - -  for (it = h->imports; it; it = it->next) -    { -      if (ecommunity_cmp (it->rt_import_list, rt_import_list)) -        break; -    } - -  vnc_zlog_debug_verbose ("%s: matched it=%p", __func__, it); - -  if (!it) -    { -      it = -        XCALLOC (MTYPE_RFAPI_IMPORTTABLE, sizeof (struct rfapi_import_table)); -      assert (it); -      it->next = h->imports; -      h->imports = it; - -      it->rt_import_list = ecommunity_dup (rt_import_list); -      it->rfg = rfg; -      it->monitor_exterior_orphans = -        skiplist_new (0, NULL, (void (*)(void *)) prefix_free); - -      /* -       * fill import route tables from RIBs -       * -       * Potential area for optimization. If this occurs when -       * tables are large (e.g., the operator adds a nve group -       * with a new RT list to a running system), it could take -       * a while. -       *  -       */ -      for (afi = AFI_IP; afi < AFI_MAX; ++afi) -        { - -          it->imported_vpn[afi] = route_table_init (); -          it->imported_encap[afi] = route_table_init (); - -          rfapiBgpTableFilteredImport (bgp, it, afi, SAFI_MPLS_VPN); -          rfapiBgpTableFilteredImport (bgp, it, afi, SAFI_ENCAP); - -          vnc_import_bgp_exterior_redist_enable_it (bgp, afi, it); -        } -    } - -  it->refcount += 1; - -  return it; +	struct rfapi *h; +	struct rfapi_import_table *it; +	afi_t afi; + +	h = bgp->rfapi; +	assert(h); + +	for (it = h->imports; it; it = it->next) { +		if (ecommunity_cmp(it->rt_import_list, rt_import_list)) +			break; +	} + +	vnc_zlog_debug_verbose("%s: matched it=%p", __func__, it); + +	if (!it) { +		it = XCALLOC(MTYPE_RFAPI_IMPORTTABLE, +			     sizeof(struct rfapi_import_table)); +		assert(it); +		it->next = h->imports; +		h->imports = it; + +		it->rt_import_list = ecommunity_dup(rt_import_list); +		it->rfg = rfg; +		it->monitor_exterior_orphans = +			skiplist_new(0, NULL, (void (*)(void *))prefix_free); + +		/* +		 * fill import route tables from RIBs +		 * +		 * Potential area for optimization. If this occurs when +		 * tables are large (e.g., the operator adds a nve group +		 * with a new RT list to a running system), it could take +		 * a while. +		 * +		 */ +		for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + +			it->imported_vpn[afi] = route_table_init(); +			it->imported_encap[afi] = route_table_init(); + +			rfapiBgpTableFilteredImport(bgp, it, afi, +						    SAFI_MPLS_VPN); +			rfapiBgpTableFilteredImport(bgp, it, afi, SAFI_ENCAP); + +			vnc_import_bgp_exterior_redist_enable_it(bgp, afi, it); +		} +	} + +	it->refcount += 1; + +	return it;  }  /*   * skiplist element free function   */ -static void -delete_rem_pfx_na_free (void *na) +static void delete_rem_pfx_na_free(void *na)  { -  uint32_t *pCounter = ((struct rfapi_nve_addr *) na)->info; +	uint32_t *pCounter = ((struct rfapi_nve_addr *)na)->info; -  *pCounter += 1; -  XFREE (MTYPE_RFAPI_NVE_ADDR, na); +	*pCounter += 1; +	XFREE(MTYPE_RFAPI_NVE_ADDR, na);  }  /*   * Common deleter for IP and MAC import tables   */ -static void -rfapiDeleteRemotePrefixesIt ( -    struct bgp			*bgp, -    struct rfapi_import_table	*it, -    struct prefix		*un, -    struct prefix		*vn, -    struct prefix		*p, -    int				delete_active, -    int				delete_holddown, -    uint32_t			*pARcount, -    uint32_t			*pAHcount, -    uint32_t			*pHRcount, -    uint32_t			*pHHcount, -    struct skiplist		*uniq_active_nves, -    struct skiplist		*uniq_holddown_nves) +static void rfapiDeleteRemotePrefixesIt( +	struct bgp *bgp, struct rfapi_import_table *it, struct prefix *un, +	struct prefix *vn, struct prefix *p, int delete_active, +	int delete_holddown, uint32_t *pARcount, uint32_t *pAHcount, +	uint32_t *pHRcount, uint32_t *pHHcount, +	struct skiplist *uniq_active_nves, struct skiplist *uniq_holddown_nves)  { -  afi_t afi; +	afi_t afi;  #if DEBUG_L2_EXTRA -  { -    char buf_pfx[BUFSIZ]; - -    if (p) -      { -        prefix2str (p, buf_pfx, BUFSIZ); -      } -    else -      { -        buf_pfx[0] = '*'; -        buf_pfx[1] = 0; -      } - -    vnc_zlog_debug_verbose ("%s: entry, p=%s, delete_active=%d, delete_holddown=%d", -                __func__, buf_pfx, delete_active, delete_holddown); -  } +	{ +		char buf_pfx[BUFSIZ]; + +		if (p) { +			prefix2str(p, buf_pfx, BUFSIZ); +		} else { +			buf_pfx[0] = '*'; +			buf_pfx[1] = 0; +		} + +		vnc_zlog_debug_verbose( +			"%s: entry, p=%s, delete_active=%d, delete_holddown=%d", +			__func__, buf_pfx, delete_active, delete_holddown); +	}  #endif -  for (afi = AFI_IP; afi < AFI_MAX; ++afi) -    { - -      struct route_table *rt; -      struct route_node *rn; - -      if (p && (family2afi (p->family) != afi)) -        { -          continue; -        } - -      rt = it->imported_vpn[afi]; -      if (!rt) -        continue; - -      vnc_zlog_debug_verbose ("%s: scanning rt for afi=%d", __func__, afi); - -      for (rn = route_top (rt); rn; rn = route_next (rn)) -        { -          struct bgp_info *bi; -          struct bgp_info *next; - -	  if (VNC_DEBUG(IMPORT_DEL_REMOTE)) -	    { -	      char p1line[BUFSIZ]; -	      char p2line[BUFSIZ]; - -	      prefix2str (p, p1line, BUFSIZ); -	      prefix2str (&rn->p, p2line, BUFSIZ); -	      vnc_zlog_debug_any ("%s: want %s, have %s", __func__, p1line, p2line); -	    } - -          if (p && prefix_cmp (p, &rn->p)) -            continue; - -          { -            char buf_pfx[BUFSIZ]; -            prefix2str (&rn->p, buf_pfx, BUFSIZ); -            vnc_zlog_debug_verbose ("%s: rn pfx=%s", __func__, buf_pfx); -          } - -          /* TBD is this valid for afi == AFI_L2VPN? */ -          RFAPI_CHECK_REFCOUNT (rn, SAFI_MPLS_VPN, 1); - -          for (bi = rn->info; bi; bi = next) -            { -              next = bi->next; - -              struct prefix qpt; -              struct prefix qct; -              int qpt_valid = 0; -              int qct_valid = 0; -              int is_active = 0; - -              vnc_zlog_debug_verbose ("%s: examining bi %p", __func__, bi); - -              if (bi->attr) -                { -                  if (!rfapiGetNexthop (bi->attr, &qpt)) -                    qpt_valid = 1; -                } -              if (vn) -                { -                  if (!qpt_valid || !prefix_match (vn, &qpt)) -                    { +	for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + +		struct route_table *rt; +		struct route_node *rn; + +		if (p && (family2afi(p->family) != afi)) { +			continue; +		} + +		rt = it->imported_vpn[afi]; +		if (!rt) +			continue; + +		vnc_zlog_debug_verbose("%s: scanning rt for afi=%d", __func__, +				       afi); + +		for (rn = route_top(rt); rn; rn = route_next(rn)) { +			struct bgp_info *bi; +			struct bgp_info *next; + +			if (VNC_DEBUG(IMPORT_DEL_REMOTE)) { +				char p1line[BUFSIZ]; +				char p2line[BUFSIZ]; + +				prefix2str(p, p1line, BUFSIZ); +				prefix2str(&rn->p, p2line, BUFSIZ); +				vnc_zlog_debug_any("%s: want %s, have %s", +						   __func__, p1line, p2line); +			} + +			if (p && prefix_cmp(p, &rn->p)) +				continue; + +			{ +				char buf_pfx[BUFSIZ]; +				prefix2str(&rn->p, buf_pfx, BUFSIZ); +				vnc_zlog_debug_verbose("%s: rn pfx=%s", +						       __func__, buf_pfx); +			} + +			/* TBD is this valid for afi == AFI_L2VPN? */ +			RFAPI_CHECK_REFCOUNT(rn, SAFI_MPLS_VPN, 1); + +			for (bi = rn->info; bi; bi = next) { +				next = bi->next; + +				struct prefix qpt; +				struct prefix qct; +				int qpt_valid = 0; +				int qct_valid = 0; +				int is_active = 0; + +				vnc_zlog_debug_verbose("%s: examining bi %p", +						       __func__, bi); + +				if (bi->attr) { +					if (!rfapiGetNexthop(bi->attr, &qpt)) +						qpt_valid = 1; +				} +				if (vn) { +					if (!qpt_valid +					    || !prefix_match(vn, &qpt)) {  #if DEBUG_L2_EXTRA -                      vnc_zlog_debug_verbose -                        ("%s: continue at vn && !qpt_valid || !prefix_match(vn, &qpt)", -                         __func__); +						vnc_zlog_debug_verbose( +							"%s: continue at vn && !qpt_valid || !prefix_match(vn, &qpt)", +							__func__);  #endif -                      continue; -                    } -                } +						continue; +					} +				} -              if (!rfapiGetUnAddrOfVpnBi (bi, &qct)) -                qct_valid = 1; +				if (!rfapiGetUnAddrOfVpnBi(bi, &qct)) +					qct_valid = 1; -              if (un) -                { -                  if (!qct_valid || !prefix_match (un, &qct)) -                    { +				if (un) { +					if (!qct_valid +					    || !prefix_match(un, &qct)) {  #if DEBUG_L2_EXTRA -                      vnc_zlog_debug_verbose -                        ("%s: continue at un && !qct_valid || !prefix_match(un, &qct)", -                         __func__); +						vnc_zlog_debug_verbose( +							"%s: continue at un && !qct_valid || !prefix_match(un, &qct)", +							__func__);  #endif -                      continue; -                    } -                } - - -              /* -               * Blow bi away -               */ -              /* -               * If this route is waiting to be deleted because of -               * a previous withdraw, we must cancel its timer. -               */ -              if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) -                { -                  if (!delete_holddown) -                    continue; -                  if (bi->extra->vnc.import.timer) -                    { - -                      struct thread *t = -                        (struct thread *) bi->extra->vnc.import.timer; -                      struct rfapi_withdraw *wcb = t->arg; - -                      wcb->import_table->holddown_count[afi] -= 1; -                      RFAPI_UPDATE_ITABLE_COUNT (bi, wcb->import_table, afi, -                                                 1); -                      XFREE (MTYPE_RFAPI_WITHDRAW, wcb); -                      thread_cancel (t); -                    } -                } -              else -                { -                  if (!delete_active) -                    continue; -                  is_active = 1; -                } - -              vnc_zlog_debug_verbose -                ("%s: deleting bi %p (qct_valid=%d, qpt_valid=%d, delete_holddown=%d, delete_active=%d)", -                 __func__, bi, qct_valid, qpt_valid, delete_holddown, -                 delete_active); - - -              /* -               * add nve to list -               */ -              if (qct_valid && qpt_valid) -                { - -                  struct rfapi_nve_addr na; -                  struct rfapi_nve_addr *nap; - -                  memset (&na, 0, sizeof (na)); -                  assert (!rfapiQprefix2Raddr (&qct, &na.un)); -                  assert (!rfapiQprefix2Raddr (&qpt, &na.vn)); - -                  if (skiplist_search ((is_active ? uniq_active_nves : -                                        uniq_holddown_nves), &na, -                                       (void **) &nap)) -                    { -                      char line[BUFSIZ]; - -                      nap = XCALLOC (MTYPE_RFAPI_NVE_ADDR, -                                     sizeof (struct rfapi_nve_addr)); -                      assert (nap); -                      *nap = na; -                      nap->info = is_active ? pAHcount : pHHcount; -                      skiplist_insert ((is_active ? uniq_active_nves : -                                        uniq_holddown_nves), nap, nap); - -                      rfapiNveAddr2Str (nap, line, BUFSIZ); -                    } -                } - -              vnc_direct_bgp_rh_del_route (bgp, afi, &rn->p, bi->peer); - -              RFAPI_UPDATE_ITABLE_COUNT (bi, it, afi, -1); -              it->holddown_count[afi] += 1; -              rfapiExpireVpnNow (it, rn, bi, 1); - -              vnc_zlog_debug_verbose ("%s: incrementing count (is_active=%d)", -                          __func__, is_active); - -              if (is_active) -                ++ * pARcount; -              else -                ++ * pHRcount; -            } -        } -    } +						continue; +					} +				} + + +				/* +				 * Blow bi away +				 */ +				/* +				 * If this route is waiting to be deleted +				 * because of +				 * a previous withdraw, we must cancel its +				 * timer. +				 */ +				if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) { +					if (!delete_holddown) +						continue; +					if (bi->extra->vnc.import.timer) { + +						struct thread *t = +							(struct thread *)bi +								->extra->vnc +								.import.timer; +						struct rfapi_withdraw *wcb = +							t->arg; + +						wcb->import_table +							->holddown_count[afi] -= +							1; +						RFAPI_UPDATE_ITABLE_COUNT( +							bi, wcb->import_table, +							afi, 1); +						XFREE(MTYPE_RFAPI_WITHDRAW, +						      wcb); +						thread_cancel(t); +					} +				} else { +					if (!delete_active) +						continue; +					is_active = 1; +				} + +				vnc_zlog_debug_verbose( +					"%s: deleting bi %p (qct_valid=%d, qpt_valid=%d, delete_holddown=%d, delete_active=%d)", +					__func__, bi, qct_valid, qpt_valid, +					delete_holddown, delete_active); + + +				/* +				 * add nve to list +				 */ +				if (qct_valid && qpt_valid) { + +					struct rfapi_nve_addr na; +					struct rfapi_nve_addr *nap; + +					memset(&na, 0, sizeof(na)); +					assert(!rfapiQprefix2Raddr(&qct, +								   &na.un)); +					assert(!rfapiQprefix2Raddr(&qpt, +								   &na.vn)); + +					if (skiplist_search( +						    (is_active +							     ? uniq_active_nves +							     : uniq_holddown_nves), +						    &na, (void **)&nap)) { +						char line[BUFSIZ]; + +						nap = XCALLOC( +							MTYPE_RFAPI_NVE_ADDR, +							sizeof(struct +							       rfapi_nve_addr)); +						assert(nap); +						*nap = na; +						nap->info = is_active +								    ? pAHcount +								    : pHHcount; +						skiplist_insert( +							(is_active +								 ? uniq_active_nves +								 : uniq_holddown_nves), +							nap, nap); + +						rfapiNveAddr2Str(nap, line, +								 BUFSIZ); +					} +				} + +				vnc_direct_bgp_rh_del_route(bgp, afi, &rn->p, +							    bi->peer); + +				RFAPI_UPDATE_ITABLE_COUNT(bi, it, afi, -1); +				it->holddown_count[afi] += 1; +				rfapiExpireVpnNow(it, rn, bi, 1); + +				vnc_zlog_debug_verbose( +					"%s: incrementing count (is_active=%d)", +					__func__, is_active); + +				if (is_active) +					++*pARcount; +				else +					++*pHRcount; +			} +		} +	}  } @@ -4944,7 +4628,7 @@ rfapiDeleteRemotePrefixesIt (   *   * UI helper: For use by the "clear vnc prefixes" command   * - * input:  + * input:   *	un			if set, tunnel must match this prefix   *	vn			if set, nexthop prefix must match this prefix   *	p			if set, prefix must match this prefix @@ -4959,133 +4643,110 @@ rfapiDeleteRemotePrefixesIt (   * return value:   *	void   --------------------------------------------*/ -void -rfapiDeleteRemotePrefixes ( -    struct prefix	*un, -    struct prefix	*vn, -    struct prefix	*p, -    struct rfapi_import_table *arg_it, -    int			delete_active, -    int			delete_holddown, -    uint32_t		*pARcount, -    uint32_t		*pAHcount, -    uint32_t		*pHRcount, -    uint32_t		*pHHcount) +void rfapiDeleteRemotePrefixes(struct prefix *un, struct prefix *vn, +			       struct prefix *p, +			       struct rfapi_import_table *arg_it, +			       int delete_active, int delete_holddown, +			       uint32_t *pARcount, uint32_t *pAHcount, +			       uint32_t *pHRcount, uint32_t *pHHcount)  { -  struct bgp			*bgp; -  struct rfapi			*h; -  struct rfapi_import_table	*it; -  uint32_t			deleted_holddown_route_count = 0; -  uint32_t			deleted_active_route_count = 0; -  uint32_t			deleted_holddown_nve_count = 0; -  uint32_t			deleted_active_nve_count = 0; -  struct skiplist		*uniq_holddown_nves; -  struct skiplist		*uniq_active_nves; - -  VNC_ITRCCK; - -  bgp = bgp_get_default ();     /* assume 1 instance for now */ -  /* If no bgp instantiated yet, no vnc prefixes exist */ -  if (!bgp) -    return; - -  h = bgp->rfapi; -  assert (h); - -  uniq_holddown_nves = -    skiplist_new (0, rfapi_nve_addr_cmp, delete_rem_pfx_na_free); -  uniq_active_nves = -    skiplist_new (0, rfapi_nve_addr_cmp, delete_rem_pfx_na_free); - -  /* -   * Iterate over all import tables; do a filtered import -   * for the afi/safi combination -   */ - -  if (arg_it) -    it = arg_it; -  else -    it = h->imports; -  for (; it; ) -    { - -      vnc_zlog_debug_verbose -        ("%s: calling rfapiDeleteRemotePrefixesIt() on (IP) import %p", -         __func__, it); - -      rfapiDeleteRemotePrefixesIt ( -	bgp, -	it, -	un, -	vn, -	p, -	delete_active, -	delete_holddown, -	&deleted_active_route_count, -	&deleted_active_nve_count, -	&deleted_holddown_route_count, -	&deleted_holddown_nve_count, -	uniq_active_nves, -	uniq_holddown_nves); - -      if (arg_it) -        it = NULL; -      else -        it = it->next; -    } - -  /* -   * Now iterate over L2 import tables -   */ -  if (h->import_mac && !(p && (p->family != AF_ETHERNET))) -    { - -      void *cursor = NULL; -      int rc; - -      for (cursor = NULL, -           rc = skiplist_next (h->import_mac, NULL, (void **) &it, &cursor); -           !rc; -           rc = skiplist_next (h->import_mac, NULL, (void **) &it, &cursor)) -        { - -          vnc_zlog_debug_verbose -            ("%s: calling rfapiDeleteRemotePrefixesIt() on import_mac %p", -             __func__, it); - -          rfapiDeleteRemotePrefixesIt ( -	    bgp, -	    it, -	    un, -	    vn, -	    p, -	    delete_active, -	    delete_holddown, -	    &deleted_active_route_count, -	    &deleted_active_nve_count, -	    &deleted_holddown_route_count, -	    &deleted_holddown_nve_count, -	    uniq_active_nves, -	    uniq_holddown_nves); -        } -    } - -  /* -   * our custom element freeing function above counts as it deletes -   */ -  skiplist_free (uniq_holddown_nves); -  skiplist_free (uniq_active_nves); - -  if (pARcount) -    *pARcount = deleted_active_route_count; -  if (pAHcount) -    *pAHcount = deleted_active_nve_count; -  if (pHRcount) -    *pHRcount = deleted_holddown_route_count; -  if (pHHcount) -    *pHHcount = deleted_holddown_nve_count; - -  VNC_ITRCCK; +	struct bgp *bgp; +	struct rfapi *h; +	struct rfapi_import_table *it; +	uint32_t deleted_holddown_route_count = 0; +	uint32_t deleted_active_route_count = 0; +	uint32_t deleted_holddown_nve_count = 0; +	uint32_t deleted_active_nve_count = 0; +	struct skiplist *uniq_holddown_nves; +	struct skiplist *uniq_active_nves; + +	VNC_ITRCCK; + +	bgp = bgp_get_default(); /* assume 1 instance for now */ +	/* If no bgp instantiated yet, no vnc prefixes exist */ +	if (!bgp) +		return; + +	h = bgp->rfapi; +	assert(h); + +	uniq_holddown_nves = +		skiplist_new(0, rfapi_nve_addr_cmp, delete_rem_pfx_na_free); +	uniq_active_nves = +		skiplist_new(0, rfapi_nve_addr_cmp, delete_rem_pfx_na_free); + +	/* +	 * Iterate over all import tables; do a filtered import +	 * for the afi/safi combination +	 */ + +	if (arg_it) +		it = arg_it; +	else +		it = h->imports; +	for (; it;) { + +		vnc_zlog_debug_verbose( +			"%s: calling rfapiDeleteRemotePrefixesIt() on (IP) import %p", +			__func__, it); + +		rfapiDeleteRemotePrefixesIt( +			bgp, it, un, vn, p, delete_active, delete_holddown, +			&deleted_active_route_count, &deleted_active_nve_count, +			&deleted_holddown_route_count, +			&deleted_holddown_nve_count, uniq_active_nves, +			uniq_holddown_nves); + +		if (arg_it) +			it = NULL; +		else +			it = it->next; +	} + +	/* +	 * Now iterate over L2 import tables +	 */ +	if (h->import_mac && !(p && (p->family != AF_ETHERNET))) { + +		void *cursor = NULL; +		int rc; + +		for (cursor = NULL, +		    rc = skiplist_next(h->import_mac, NULL, (void **)&it, +				       &cursor); +		     !rc; rc = skiplist_next(h->import_mac, NULL, (void **)&it, +					     &cursor)) { + +			vnc_zlog_debug_verbose( +				"%s: calling rfapiDeleteRemotePrefixesIt() on import_mac %p", +				__func__, it); + +			rfapiDeleteRemotePrefixesIt( +				bgp, it, un, vn, p, delete_active, +				delete_holddown, &deleted_active_route_count, +				&deleted_active_nve_count, +				&deleted_holddown_route_count, +				&deleted_holddown_nve_count, uniq_active_nves, +				uniq_holddown_nves); +		} +	} + +	/* +	 * our custom element freeing function above counts as it deletes +	 */ +	skiplist_free(uniq_holddown_nves); +	skiplist_free(uniq_active_nves); + +	if (pARcount) +		*pARcount = deleted_active_route_count; +	if (pAHcount) +		*pAHcount = deleted_active_nve_count; +	if (pHRcount) +		*pHRcount = deleted_holddown_route_count; +	if (pHHcount) +		*pHHcount = deleted_holddown_nve_count; + +	VNC_ITRCCK;  }  /*------------------------------------------ @@ -5093,7 +4754,7 @@ rfapiDeleteRemotePrefixes (   *   * UI helper: count VRF routes from BGP side   * - * input:  + * input:   *   * output   *	pALRcount		count of active local routes @@ -5104,83 +4765,73 @@ rfapiDeleteRemotePrefixes (   * return value:   *	void   --------------------------------------------*/ -void -rfapiCountAllItRoutes (int *pALRcount,  /* active local routes */ -                       int *pARRcount,  /* active remote routes */ -                       int *pHRcount,   /* holddown routes */ -                       int *pIRcount)   /* imported routes */ +void rfapiCountAllItRoutes(int *pALRcount, /* active local routes */ +			   int *pARRcount, /* active remote routes */ +			   int *pHRcount,  /* holddown routes */ +			   int *pIRcount)  /* imported routes */  { -  struct bgp *bgp; -  struct rfapi *h; -  struct rfapi_import_table *it; -  afi_t afi; - -  int total_active_local = 0; -  int total_active_remote = 0; -  int total_holddown = 0; -  int total_imported = 0; - -  bgp = bgp_get_default ();     /* assume 1 instance for now */ -  assert (bgp); - -  h = bgp->rfapi; -  assert (h); - -  /* -   * Iterate over all import tables; do a filtered import -   * for the afi/safi combination -   */ - -  for (it = h->imports; it; it = it->next) -    { - -      for (afi = AFI_IP; afi < AFI_MAX; ++afi) -        { - -          total_active_local += it->local_count[afi]; -          total_active_remote += it->remote_count[afi]; -          total_holddown += it->holddown_count[afi]; -          total_imported += it->imported_count[afi]; - -        } -    } - -  void *cursor; -  int rc; - -  if (h->import_mac) -    { -      for (cursor = NULL, -           rc = skiplist_next (h->import_mac, NULL, (void **) &it, &cursor); -           !rc; -           rc = skiplist_next (h->import_mac, NULL, (void **) &it, &cursor)) -        { - -          total_active_local += it->local_count[AFI_L2VPN]; -          total_active_remote += it->remote_count[AFI_L2VPN]; -          total_holddown += it->holddown_count[AFI_L2VPN]; -          total_imported += it->imported_count[AFI_L2VPN]; - -        } -    } - - -  if (pALRcount) -    { -      *pALRcount = total_active_local; -    } -  if (pARRcount) -    { -      *pARRcount = total_active_remote; -    } -  if (pHRcount) -    { -      *pHRcount = total_holddown; -    } -  if (pIRcount) -    { -      *pIRcount = total_imported; -    } +	struct bgp *bgp; +	struct rfapi *h; +	struct rfapi_import_table *it; +	afi_t afi; + +	int total_active_local = 0; +	int total_active_remote = 0; +	int total_holddown = 0; +	int total_imported = 0; + +	bgp = bgp_get_default(); /* assume 1 instance for now */ +	assert(bgp); + +	h = bgp->rfapi; +	assert(h); + +	/* +	 * Iterate over all import tables; do a filtered import +	 * for the afi/safi combination +	 */ + +	for (it = h->imports; it; it = it->next) { + +		for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + +			total_active_local += it->local_count[afi]; +			total_active_remote += it->remote_count[afi]; +			total_holddown += it->holddown_count[afi]; +			total_imported += it->imported_count[afi]; +		} +	} + +	void *cursor; +	int rc; + +	if (h->import_mac) { +		for (cursor = NULL, +		    rc = skiplist_next(h->import_mac, NULL, (void **)&it, +				       &cursor); +		     !rc; rc = skiplist_next(h->import_mac, NULL, (void **)&it, +					     &cursor)) { + +			total_active_local += it->local_count[AFI_L2VPN]; +			total_active_remote += it->remote_count[AFI_L2VPN]; +			total_holddown += it->holddown_count[AFI_L2VPN]; +			total_imported += it->imported_count[AFI_L2VPN]; +		} +	} + + +	if (pALRcount) { +		*pALRcount = total_active_local; +	} +	if (pARRcount) { +		*pARRcount = total_active_remote; +	} +	if (pHRcount) { +		*pHRcount = total_holddown; +	} +	if (pIRcount) { +		*pIRcount = total_imported; +	}  }  /*------------------------------------------ @@ -5188,7 +4839,7 @@ rfapiCountAllItRoutes (int *pALRcount,  /* active local routes */   *   * calculate holddown value based on lifetime   * - * input:  + * input:   *     lifetime                lifetime   *   * return value: @@ -5197,22 +4848,21 @@ rfapiCountAllItRoutes (int *pALRcount,  /* active local routes */   *   --------------------------------------------*/  /* hold down time maxes out at RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY */ -uint32_t -rfapiGetHolddownFromLifetime (uint32_t lifetime) +uint32_t rfapiGetHolddownFromLifetime(uint32_t lifetime)  { -  uint32_t factor; -  struct bgp *bgp; - -  bgp = bgp_get_default (); -  if (bgp && bgp->rfapi_cfg) -    factor = bgp->rfapi_cfg->rfp_cfg.holddown_factor; -  else -    factor = RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR; - -  if (factor < 100 || lifetime < RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY) -    lifetime = lifetime * factor / 100; -  if (lifetime < RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY) -    return lifetime; -  else -    return RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY; +	uint32_t factor; +	struct bgp *bgp; + +	bgp = bgp_get_default(); +	if (bgp && bgp->rfapi_cfg) +		factor = bgp->rfapi_cfg->rfp_cfg.holddown_factor; +	else +		factor = RFAPI_RFP_CFG_DEFAULT_HOLDDOWN_FACTOR; + +	if (factor < 100 || lifetime < RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY) +		lifetime = lifetime * factor / 100; +	if (lifetime < RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY) +		return lifetime; +	else +		return RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY;  } diff --git a/bgpd/rfapi/rfapi_import.h b/bgpd/rfapi/rfapi_import.h index 1888d5f25d..fc5bb01cef 100644 --- a/bgpd/rfapi/rfapi_import.h +++ b/bgpd/rfapi/rfapi_import.h @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2009-2016, LabN Consulting, L.L.C.   * @@ -34,72 +34,60 @@   * routes are not segregated by RD - the RD is stored in bgp_info_extra   * and is needed to determine if two prefixes are the same.   */ -struct rfapi_import_table -{ -  struct rfapi_import_table *next; -  struct rfapi_nve_group_cfg *rfg; -  struct ecommunity *rt_import_list;    /* copied from nve grp */ -  int refcount;                 /* nve grps and nves */ -  uint32_t l2_logical_net_id;   /* L2 only: EVPN Eth Seg Id */ -  struct route_table *imported_vpn[AFI_MAX]; -  struct rfapi_monitor_vpn *vpn0_queries[AFI_MAX]; -  struct rfapi_monitor_eth *eth0_queries; -  struct route_table *imported_encap[AFI_MAX]; -  struct skiplist *monitor_exterior_orphans; -  int local_count[AFI_MAX]; -  int remote_count[AFI_MAX]; -  int holddown_count[AFI_MAX]; -  int imported_count[AFI_MAX]; +struct rfapi_import_table { +	struct rfapi_import_table *next; +	struct rfapi_nve_group_cfg *rfg; +	struct ecommunity *rt_import_list; /* copied from nve grp */ +	int refcount;			   /* nve grps and nves */ +	uint32_t l2_logical_net_id;	/* L2 only: EVPN Eth Seg Id */ +	struct route_table *imported_vpn[AFI_MAX]; +	struct rfapi_monitor_vpn *vpn0_queries[AFI_MAX]; +	struct rfapi_monitor_eth *eth0_queries; +	struct route_table *imported_encap[AFI_MAX]; +	struct skiplist *monitor_exterior_orphans; +	int local_count[AFI_MAX]; +	int remote_count[AFI_MAX]; +	int holddown_count[AFI_MAX]; +	int imported_count[AFI_MAX];  }; -#define RFAPI_LOCAL_BI(bi) \ -    (((bi)->type == ZEBRA_ROUTE_BGP) && ((bi)->sub_type == BGP_ROUTE_RFP)) +#define RFAPI_LOCAL_BI(bi)                                                     \ +	(((bi)->type == ZEBRA_ROUTE_BGP) && ((bi)->sub_type == BGP_ROUTE_RFP)) -#define RFAPI_DIRECT_IMPORT_BI(bi) \ -    (((bi)->type ==  ZEBRA_ROUTE_BGP_DIRECT) || ((bi)->type ==  ZEBRA_ROUTE_BGP_DIRECT_EXT)) +#define RFAPI_DIRECT_IMPORT_BI(bi)                                             \ +	(((bi)->type == ZEBRA_ROUTE_BGP_DIRECT)                                \ +	 || ((bi)->type == ZEBRA_ROUTE_BGP_DIRECT_EXT)) -#define RFAPI_UPDATE_ITABLE_COUNT(bi, itable, afi, cnt) \ -    if (RFAPI_LOCAL_BI(bi)) {				\ -	(itable)->local_count[(afi)] += (cnt);		\ -    } else {						\ -        if (RFAPI_DIRECT_IMPORT_BI(bi))                 \ -            (itable)->imported_count[(afi)] += (cnt);   \ -        else                                            \ -            (itable)->remote_count[(afi)]   += (cnt);   \ -    } +#define RFAPI_UPDATE_ITABLE_COUNT(bi, itable, afi, cnt)                        \ +	if (RFAPI_LOCAL_BI(bi)) {                                              \ +		(itable)->local_count[(afi)] += (cnt);                         \ +	} else {                                                               \ +		if (RFAPI_DIRECT_IMPORT_BI(bi))                                \ +			(itable)->imported_count[(afi)] += (cnt);              \ +		else                                                           \ +			(itable)->remote_count[(afi)] += (cnt);                \ +	} -extern uint8_t -rfapiRfpCost (struct attr *attr); +extern uint8_t rfapiRfpCost(struct attr *attr); -extern void -rfapiDebugBacktrace (void); +extern void rfapiDebugBacktrace(void); -extern void -rfapiCheckRouteCount (void); +extern void rfapiCheckRouteCount(void);  /*   * Print BI in an Import Table   */ -extern void -rfapiPrintBi (void *stream, struct bgp_info *bi); +extern void rfapiPrintBi(void *stream, struct bgp_info *bi); -extern void -rfapiShowImportTable ( -  void			*stream, -  const char		*label, -  struct route_table	*rt, -  int			isvpn); +extern void rfapiShowImportTable(void *stream, const char *label, +				 struct route_table *rt, int isvpn);  extern struct rfapi_import_table * -rfapiImportTableRefAdd ( -  struct bgp *bgp, -  struct ecommunity *rt_import_list, -  struct rfapi_nve_group_cfg *rfg); +rfapiImportTableRefAdd(struct bgp *bgp, struct ecommunity *rt_import_list, +		       struct rfapi_nve_group_cfg *rfg); -extern void -rfapiImportTableRefDelByIt ( -  struct bgp			*bgp, -  struct rfapi_import_table	*it_target); +extern void rfapiImportTableRefDelByIt(struct bgp *bgp, +				       struct rfapi_import_table *it_target);  /* @@ -111,106 +99,78 @@ rfapiImportTableRefDelByIt (   * then return those, and also include all the non-removed routes from the   * next less-specific node (i.e., this node's parent) at the end.   */ -extern struct rfapi_next_hop_entry * -rfapiRouteNode2NextHopList ( -  struct route_node	*rn, -  uint32_t		lifetime,		/* put into nexthop entries */ -  struct rfapi_ip_addr	*exclude_vnaddr,	/* omit routes to same NVE */ -  struct route_table    *rfd_rib_table,		/* preload this NVE rib table */ -  struct prefix		*pfx_target_original);	/* query target */ - -extern struct rfapi_next_hop_entry * -rfapiRouteTable2NextHopList ( -  struct route_table	*rt, -  uint32_t		lifetime,		/* put into nexthop entries */ -  struct rfapi_ip_addr	*exclude_vnaddr,	/* omit routes to same NVE */ -  struct route_table    *rfd_rib_table,		/* preload this NVE rib table */ -  struct prefix		*pfx_target_original);	/* query target */ - -extern struct rfapi_next_hop_entry * -rfapiEthRouteTable2NextHopList ( -  uint32_t			logical_net_id, -  struct rfapi_ip_prefix	*rprefix, -  uint32_t			lifetime,        /* put into nexthop entries */ -  struct rfapi_ip_addr		*exclude_vnaddr, /* omit routes to same NVE */ -  struct route_table            *rib_route_table,/* preload NVE rib node */ -  struct prefix			*pfx_target_original);	/* query target */ - -extern int -rfapiEcommunitiesIntersect (struct ecommunity *e1, struct ecommunity *e2); - -extern void -rfapiCheckRefcount (struct route_node *rn, safi_t safi, int lockoffset); - -extern int -rfapiHasNonRemovedRoutes (struct route_node *rn); - -extern int -rfapiProcessDeferredClose (struct thread *t); - -extern int -rfapiGetUnAddrOfVpnBi (struct bgp_info *bi, struct prefix *p); - -extern void -rfapiNexthop2Prefix (struct attr *attr, struct prefix *p); - -extern void -rfapiUnicastNexthop2Prefix ( -  afi_t		afi, -  struct attr	*attr, -  struct prefix	*p); +extern struct rfapi_next_hop_entry *rfapiRouteNode2NextHopList( +	struct route_node *rn, uint32_t lifetime, /* put into nexthop entries */ +	struct rfapi_ip_addr *exclude_vnaddr,     /* omit routes to same NVE */ +	struct route_table *rfd_rib_table,   /* preload this NVE rib table */ +	struct prefix *pfx_target_original); /* query target */ + +extern struct rfapi_next_hop_entry *rfapiRouteTable2NextHopList( +	struct route_table *rt, +	uint32_t lifetime,		      /* put into nexthop entries */ +	struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ +	struct route_table *rfd_rib_table,    /* preload this NVE rib table */ +	struct prefix *pfx_target_original);  /* query target */ + +extern struct rfapi_next_hop_entry *rfapiEthRouteTable2NextHopList( +	uint32_t logical_net_id, struct rfapi_ip_prefix *rprefix, +	uint32_t lifetime,		      /* put into nexthop entries */ +	struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ +	struct route_table *rib_route_table,  /* preload NVE rib node */ +	struct prefix *pfx_target_original);  /* query target */ + +extern int rfapiEcommunitiesIntersect(struct ecommunity *e1, +				      struct ecommunity *e2); + +extern void rfapiCheckRefcount(struct route_node *rn, safi_t safi, +			       int lockoffset); + +extern int rfapiHasNonRemovedRoutes(struct route_node *rn); + +extern int rfapiProcessDeferredClose(struct thread *t); + +extern int rfapiGetUnAddrOfVpnBi(struct bgp_info *bi, struct prefix *p); + +extern void rfapiNexthop2Prefix(struct attr *attr, struct prefix *p); + +extern void rfapiUnicastNexthop2Prefix(afi_t afi, struct attr *attr, +				       struct prefix *p);  /* Filtered Import Function actions */  #define FIF_ACTION_UPDATE	0  #define FIF_ACTION_WITHDRAW	1  #define FIF_ACTION_KILL		2 -extern void -rfapiBgpInfoFilteredImportVPN ( -  struct rfapi_import_table	*import_table, -  int				action, -  struct peer			*peer, -  void				*rfd,		/* set for looped back routes */ -  struct prefix			*p, -  struct prefix			*aux_prefix,	/* AFI_ETHER: optional IP */ -  afi_t				afi, -  struct prefix_rd		*prd, -  struct attr			*attr,		/* part of bgp_info */ -  u_char			type,		/* part of bgp_info */ -  u_char			sub_type,	/* part of bgp_info */ -  uint32_t			*label);	/* part of bgp_info */ - -extern struct rfapi_next_hop_entry * -rfapiEthRouteNode2NextHopList ( -  struct route_node		*rn, -  struct rfapi_ip_prefix	*rprefix, -  uint32_t			lifetime,	 /* put into nexthop entries */ -  struct rfapi_ip_addr		*exclude_vnaddr, /* omit routes to same NVE */ -  struct route_table            *rib_route_table,/* preload NVE rib table */ -  struct prefix			*pfx_target_original); /* query target */ +extern void rfapiBgpInfoFilteredImportVPN( +	struct rfapi_import_table *import_table, int action, struct peer *peer, +	void *rfd, /* set for looped back routes */ +	struct prefix *p, +	struct prefix *aux_prefix, /* AFI_ETHER: optional IP */ +	afi_t afi, struct prefix_rd *prd, +	struct attr *attr, /* part of bgp_info */ +	u_char type,       /* part of bgp_info */ +	u_char sub_type,   /* part of bgp_info */ +	uint32_t *label);  /* part of bgp_info */ -extern struct rfapi_import_table * -rfapiMacImportTableGetNoAlloc ( -  struct bgp	*bgp, -  uint32_t	lni); +extern struct rfapi_next_hop_entry *rfapiEthRouteNode2NextHopList( +	struct route_node *rn, struct rfapi_ip_prefix *rprefix, +	uint32_t lifetime,		      /* put into nexthop entries */ +	struct rfapi_ip_addr *exclude_vnaddr, /* omit routes to same NVE */ +	struct route_table *rib_route_table,  /* preload NVE rib table */ +	struct prefix *pfx_target_original);  /* query target */ -extern struct rfapi_import_table * -rfapiMacImportTableGet ( -  struct bgp	*bgp, -  uint32_t	lni); +extern struct rfapi_import_table *rfapiMacImportTableGetNoAlloc(struct bgp *bgp, +								uint32_t lni); + +extern struct rfapi_import_table *rfapiMacImportTableGet(struct bgp *bgp, +							 uint32_t lni); -extern int -rfapiGetL2o ( -  struct attr			*attr, -  struct rfapi_l2address_option *l2o); +extern int rfapiGetL2o(struct attr *attr, struct rfapi_l2address_option *l2o); -extern int rfapiEcommunityGetLNI ( -  struct ecommunity	*ecom, -  uint32_t		*lni); +extern int rfapiEcommunityGetLNI(struct ecommunity *ecom, uint32_t *lni); -extern int rfapiEcommunityGetEthernetTag ( -  struct ecommunity *ecom, -  uint16_t * tag_id); +extern int rfapiEcommunityGetEthernetTag(struct ecommunity *ecom, +					 uint16_t *tag_id);  /* enable for debugging; disable for performance */  #if 0 @@ -224,7 +184,7 @@ extern int rfapiEcommunityGetEthernetTag (   *   * UI helper: For use by the "clear vnc prefixes" command   * - * input:  + * input:   *	un			if set, tunnel must match this prefix   *	vn			if set, nexthop prefix must match this prefix   *	p			if set, prefix must match this prefix @@ -239,25 +199,21 @@ extern int rfapiEcommunityGetEthernetTag (   * return value:   *	void   --------------------------------------------*/ -extern void -rfapiDeleteRemotePrefixes ( -  struct prefix	*un, -  struct prefix	*vn, -  struct prefix	*p, -  struct rfapi_import_table *it, -  int		delete_active, -  int		delete_holddown, -  uint32_t	*pARcount,     /* active routes */ -  uint32_t	*pAHcount,     /* active nves */ -  uint32_t	*pHRcount,     /* holddown routes */ -  uint32_t	*pHHcount);    /* holddown nves */ +extern void rfapiDeleteRemotePrefixes(struct prefix *un, struct prefix *vn, +				      struct prefix *p, +				      struct rfapi_import_table *it, +				      int delete_active, int delete_holddown, +				      uint32_t *pARcount,  /* active routes */ +				      uint32_t *pAHcount,  /* active nves */ +				      uint32_t *pHRcount,  /* holddown routes */ +				      uint32_t *pHHcount); /* holddown nves */  /*------------------------------------------   * rfapiCountAllItRoutes   *   * UI helper: count VRF routes from BGP side   * - * input:  + * input:   *   * output   *	pARcount		count of active routes @@ -267,19 +223,17 @@ rfapiDeleteRemotePrefixes (   * return value:   *	void   --------------------------------------------*/ -extern void -rfapiCountAllItRoutes ( -  int *pALRcount,      /* active local routes */ -  int *pARRcount,      /* active remote routes */ -  int *pHRcount,       /* holddown routes */ -  int *pIRcount);      /* direct imported routes */ +extern void rfapiCountAllItRoutes(int *pALRcount, /* active local routes */ +				  int *pARRcount, /* active remote routes */ +				  int *pHRcount,  /* holddown routes */ +				  int *pIRcount); /* direct imported routes */  /*------------------------------------------   * rfapiGetHolddownFromLifetime   *   * calculate holddown value based on lifetime   * - * input:  + * input:   *     lifetime                lifetime   *   * return value: @@ -287,7 +241,6 @@ rfapiCountAllItRoutes (   *     and RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY   *   --------------------------------------------*/ -extern uint32_t -rfapiGetHolddownFromLifetime (uint32_t lifetime); +extern uint32_t rfapiGetHolddownFromLifetime(uint32_t lifetime);  #endif /* QUAGGA_HGP_RFAPI_IMPORT_H */ diff --git a/bgpd/rfapi/rfapi_monitor.c b/bgpd/rfapi/rfapi_monitor.c index 275e448967..9c0d9da6ff 100644 --- a/bgpd/rfapi/rfapi_monitor.c +++ b/bgpd/rfapi/rfapi_monitor.c @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2009-2016, LabN Consulting, L.L.C.   * @@ -54,49 +54,44 @@  #define DEBUG_DUP_CHECK 0  #define DEBUG_ETH_SL 0 -static void -rfapiMonitorTimerRestart (struct rfapi_monitor_vpn *m); +static void rfapiMonitorTimerRestart(struct rfapi_monitor_vpn *m); -static void -rfapiMonitorEthTimerRestart (struct rfapi_monitor_eth *m); +static void rfapiMonitorEthTimerRestart(struct rfapi_monitor_eth *m);  /*   * Forward declarations   */ -static void -rfapiMonitorEthDetachImport (struct bgp *bgp, struct rfapi_monitor_eth *mon); +static void rfapiMonitorEthDetachImport(struct bgp *bgp, +					struct rfapi_monitor_eth *mon);  #if DEBUG_ETH_SL  /*   * Debug function, special case   */ -void -rfapiMonitorEthSlCheck( -    struct route_node	*rn, -    const char		*tag1, -    const char		*tag2) +void rfapiMonitorEthSlCheck(struct route_node *rn, const char *tag1, +			    const char *tag2)  { -    struct route_node      *rn_saved = NULL; -    static struct skiplist *sl_saved = NULL; -    struct skiplist        *sl; - -    if (!rn) -	return; - -    if (rn_saved && (rn != rn_saved)) -	return; - -    if (!rn_saved) -	rn_saved = rn; - -    sl = RFAPI_MONITOR_ETH(rn); -    if (sl || sl_saved) -      { -	vnc_zlog_debug_verbose("%s[%s%s]: rn=%p, rn->lock=%d, old sl=%p, new sl=%p", -	    __func__, (tag1? tag1: ""), (tag2? tag2: ""), rn, rn->lock, -	    sl_saved, sl); -	sl_saved = sl; -      } +	struct route_node *rn_saved = NULL; +	static struct skiplist *sl_saved = NULL; +	struct skiplist *sl; + +	if (!rn) +		return; + +	if (rn_saved && (rn != rn_saved)) +		return; + +	if (!rn_saved) +		rn_saved = rn; + +	sl = RFAPI_MONITOR_ETH(rn); +	if (sl || sl_saved) { +		vnc_zlog_debug_verbose( +			"%s[%s%s]: rn=%p, rn->lock=%d, old sl=%p, new sl=%p", +			__func__, (tag1 ? tag1 : ""), (tag2 ? tag2 : ""), rn, +			rn->lock, sl_saved, sl); +		sl_saved = sl; +	}  }  #endif @@ -104,13 +99,12 @@ rfapiMonitorEthSlCheck(   * Debugging function that aborts when it finds monitors whose   * "next" pointer * references themselves   */ -void -rfapiMonitorLoopCheck (struct rfapi_monitor_vpn *mchain) +void rfapiMonitorLoopCheck(struct rfapi_monitor_vpn *mchain)  { -  struct rfapi_monitor_vpn *m; +	struct rfapi_monitor_vpn *m; -  for (m = mchain; m; m = m->next) -    assert (m != m->next); +	for (m = mchain; m; m = m->next) +		assert(m != m->next);  }  #if DEBUG_DUP_CHECK @@ -118,381 +112,349 @@ rfapiMonitorLoopCheck (struct rfapi_monitor_vpn *mchain)   * Debugging code: see if a monitor is mentioned more than once   * in a HD's monitor list   */ -void -rfapiMonitorDupCheck (struct bgp *bgp) +void rfapiMonitorDupCheck(struct bgp *bgp)  { -  struct listnode *hnode; -  struct rfapi_descriptor *rfd; - -  for (ALL_LIST_ELEMENTS_RO (&bgp->rfapi->descriptors, hnode, rfd)) -    { -      struct route_node *mrn; - -      if (!rfd->mon) -        continue; - -      for (mrn = route_top (rfd->mon); mrn; mrn = route_next (mrn)) -        { -          struct rfapi_monitor_vpn *m; -          for (m = (struct rfapi_monitor_vpn *) (mrn->info); m; m = m->next) -            m->dcount = 0; -        } -    } - -  for (ALL_LIST_ELEMENTS_RO (&bgp->rfapi->descriptors, hnode, rfd)) -    { -      struct route_node *mrn; - -      if (!rfd->mon) -        continue; - -      for (mrn = route_top (rfd->mon); mrn; mrn = route_next (mrn)) -        { -          struct rfapi_monitor_vpn *m; - -          for (m = (struct rfapi_monitor_vpn *) (mrn->info); m; m = m->next) -            assert (++m->dcount == 1); -        } -    } +	struct listnode *hnode; +	struct rfapi_descriptor *rfd; + +	for (ALL_LIST_ELEMENTS_RO(&bgp->rfapi->descriptors, hnode, rfd)) { +		struct route_node *mrn; + +		if (!rfd->mon) +			continue; + +		for (mrn = route_top(rfd->mon); mrn; mrn = route_next(mrn)) { +			struct rfapi_monitor_vpn *m; +			for (m = (struct rfapi_monitor_vpn *)(mrn->info); m; +			     m = m->next) +				m->dcount = 0; +		} +	} + +	for (ALL_LIST_ELEMENTS_RO(&bgp->rfapi->descriptors, hnode, rfd)) { +		struct route_node *mrn; + +		if (!rfd->mon) +			continue; + +		for (mrn = route_top(rfd->mon); mrn; mrn = route_next(mrn)) { +			struct rfapi_monitor_vpn *m; + +			for (m = (struct rfapi_monitor_vpn *)(mrn->info); m; +			     m = m->next) +				assert(++m->dcount == 1); +		} +	}  }  #endif  /* debug */ -void -rfapiMonitorCleanCheck (struct bgp *bgp) +void rfapiMonitorCleanCheck(struct bgp *bgp)  { -  struct listnode *hnode; -  struct rfapi_descriptor *rfd; +	struct listnode *hnode; +	struct rfapi_descriptor *rfd; -  for (ALL_LIST_ELEMENTS_RO (&bgp->rfapi->descriptors, hnode, rfd)) -    { -      assert (!rfd->import_table->vpn0_queries[AFI_IP]); -      assert (!rfd->import_table->vpn0_queries[AFI_IP6]); +	for (ALL_LIST_ELEMENTS_RO(&bgp->rfapi->descriptors, hnode, rfd)) { +		assert(!rfd->import_table->vpn0_queries[AFI_IP]); +		assert(!rfd->import_table->vpn0_queries[AFI_IP6]); -      struct route_node *rn; +		struct route_node *rn; -      for (rn = route_top (rfd->import_table->imported_vpn[AFI_IP]); rn; -           rn = route_next (rn)) -        { +		for (rn = route_top(rfd->import_table->imported_vpn[AFI_IP]); +		     rn; rn = route_next(rn)) { -          assert (!RFAPI_MONITOR_VPN (rn)); -        } -      for (rn = route_top (rfd->import_table->imported_vpn[AFI_IP6]); rn; -           rn = route_next (rn)) -        { +			assert(!RFAPI_MONITOR_VPN(rn)); +		} +		for (rn = route_top(rfd->import_table->imported_vpn[AFI_IP6]); +		     rn; rn = route_next(rn)) { -          assert (!RFAPI_MONITOR_VPN (rn)); -        } -    } +			assert(!RFAPI_MONITOR_VPN(rn)); +		} +	}  }  /* debug */ -void -rfapiMonitorCheckAttachAllowed (void) +void rfapiMonitorCheckAttachAllowed(void)  { -  struct bgp *bgp = bgp_get_default (); -  assert (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE)); +	struct bgp *bgp = bgp_get_default(); +	assert(!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE));  } -void -rfapiMonitorExtraFlush (safi_t safi, struct route_node *rn) +void rfapiMonitorExtraFlush(safi_t safi, struct route_node *rn)  { -  struct rfapi_it_extra *hie; -  struct rfapi_monitor_vpn *v; -  struct rfapi_monitor_vpn *v_next; -  struct rfapi_monitor_encap *e = NULL; -  struct rfapi_monitor_encap *e_next = NULL; - -  if (!rn) -    return; - -  if (!rn->aggregate) -    return; - -  hie = (struct rfapi_it_extra *) (rn->aggregate); - -  switch (safi) -    { -    case SAFI_ENCAP: -      for (e = hie->u.encap.e; e; e = e_next) -        { -          e_next = e->next; -          e->next = NULL; -          XFREE (MTYPE_RFAPI_MONITOR_ENCAP, e); -          route_unlock_node (rn); -        } -      hie->u.encap.e = NULL; -      break; - -    case SAFI_MPLS_VPN: -      for (v = hie->u.vpn.v; v; v = v_next) -        { -          v_next = v->next; -          v->next = NULL; -          XFREE (MTYPE_RFAPI_MONITOR, e); -          route_unlock_node (rn); -        } -      hie->u.vpn.v = NULL; -      if (hie->u.vpn.e.source) -        { -          while (!skiplist_delete_first (hie->u.vpn.e.source)) -            { -              route_unlock_node (rn); -            } -          skiplist_free (hie->u.vpn.e.source); -          hie->u.vpn.e.source = NULL; -          route_unlock_node (rn); -        } -      if (hie->u.vpn.idx_rd) -        { -          /* looping through bi->extra->vnc.import.rd is tbd */ -          while (!skiplist_delete_first (hie->u.vpn.idx_rd)) -            { -              route_unlock_node (rn); -            } -          skiplist_free (hie->u.vpn.idx_rd); -          hie->u.vpn.idx_rd = NULL; -          route_unlock_node (rn); -        } -      if (hie->u.vpn.mon_eth) -        { -          while (!skiplist_delete_first (hie->u.vpn.mon_eth)) -            { -              route_unlock_node (rn); -            } -          skiplist_free (hie->u.vpn.mon_eth); -          hie->u.vpn.mon_eth = NULL; -          route_unlock_node (rn); -        } -      break; - -    default: -      assert (0); -    } -  XFREE (MTYPE_RFAPI_IT_EXTRA, hie); -  rn->aggregate = NULL; -  route_unlock_node (rn); +	struct rfapi_it_extra *hie; +	struct rfapi_monitor_vpn *v; +	struct rfapi_monitor_vpn *v_next; +	struct rfapi_monitor_encap *e = NULL; +	struct rfapi_monitor_encap *e_next = NULL; + +	if (!rn) +		return; + +	if (!rn->aggregate) +		return; + +	hie = (struct rfapi_it_extra *)(rn->aggregate); + +	switch (safi) { +	case SAFI_ENCAP: +		for (e = hie->u.encap.e; e; e = e_next) { +			e_next = e->next; +			e->next = NULL; +			XFREE(MTYPE_RFAPI_MONITOR_ENCAP, e); +			route_unlock_node(rn); +		} +		hie->u.encap.e = NULL; +		break; + +	case SAFI_MPLS_VPN: +		for (v = hie->u.vpn.v; v; v = v_next) { +			v_next = v->next; +			v->next = NULL; +			XFREE(MTYPE_RFAPI_MONITOR, e); +			route_unlock_node(rn); +		} +		hie->u.vpn.v = NULL; +		if (hie->u.vpn.e.source) { +			while (!skiplist_delete_first(hie->u.vpn.e.source)) { +				route_unlock_node(rn); +			} +			skiplist_free(hie->u.vpn.e.source); +			hie->u.vpn.e.source = NULL; +			route_unlock_node(rn); +		} +		if (hie->u.vpn.idx_rd) { +			/* looping through bi->extra->vnc.import.rd is tbd */ +			while (!skiplist_delete_first(hie->u.vpn.idx_rd)) { +				route_unlock_node(rn); +			} +			skiplist_free(hie->u.vpn.idx_rd); +			hie->u.vpn.idx_rd = NULL; +			route_unlock_node(rn); +		} +		if (hie->u.vpn.mon_eth) { +			while (!skiplist_delete_first(hie->u.vpn.mon_eth)) { +				route_unlock_node(rn); +			} +			skiplist_free(hie->u.vpn.mon_eth); +			hie->u.vpn.mon_eth = NULL; +			route_unlock_node(rn); +		} +		break; + +	default: +		assert(0); +	} +	XFREE(MTYPE_RFAPI_IT_EXTRA, hie); +	rn->aggregate = NULL; +	route_unlock_node(rn);  }  /*   * If the child lists are empty, release the rfapi_it_extra struct   */ -void -rfapiMonitorExtraPrune (safi_t safi, struct route_node *rn) +void rfapiMonitorExtraPrune(safi_t safi, struct route_node *rn)  { -  struct rfapi_it_extra *hie; - -  if (!rn) -    return; - -  if (!rn->aggregate) -    return; - -  hie = (struct rfapi_it_extra *) (rn->aggregate); - -  switch (safi) -    { -    case SAFI_ENCAP: -      if (hie->u.encap.e) -        return; -      break; - -    case SAFI_MPLS_VPN: -      if (hie->u.vpn.v) -        return; -      if (hie->u.vpn.mon_eth) -	{ -	  if (skiplist_count (hie->u.vpn.mon_eth)) -	    return; -          skiplist_free (hie->u.vpn.mon_eth); -          hie->u.vpn.mon_eth = NULL; -          route_unlock_node (rn);	/* uncount skiplist */ -        } -      if (hie->u.vpn.e.source) -        { -          if (skiplist_count (hie->u.vpn.e.source)) -            return; -          skiplist_free (hie->u.vpn.e.source); -          hie->u.vpn.e.source = NULL; -          route_unlock_node (rn); -        } -      if (hie->u.vpn.idx_rd) -        { -          if (skiplist_count (hie->u.vpn.idx_rd)) -            return; -          skiplist_free (hie->u.vpn.idx_rd); -          hie->u.vpn.idx_rd = NULL; -          route_unlock_node (rn); -        } -      if (hie->u.vpn.mon_eth) -        { -          if (skiplist_count (hie->u.vpn.mon_eth)) -            return; -          skiplist_free (hie->u.vpn.mon_eth); -          hie->u.vpn.mon_eth = NULL; -          route_unlock_node (rn); -        } -      break; - -    default: -      assert (0); -    } -  XFREE (MTYPE_RFAPI_IT_EXTRA, hie); -  rn->aggregate = NULL; -  route_unlock_node (rn); +	struct rfapi_it_extra *hie; + +	if (!rn) +		return; + +	if (!rn->aggregate) +		return; + +	hie = (struct rfapi_it_extra *)(rn->aggregate); + +	switch (safi) { +	case SAFI_ENCAP: +		if (hie->u.encap.e) +			return; +		break; + +	case SAFI_MPLS_VPN: +		if (hie->u.vpn.v) +			return; +		if (hie->u.vpn.mon_eth) { +			if (skiplist_count(hie->u.vpn.mon_eth)) +				return; +			skiplist_free(hie->u.vpn.mon_eth); +			hie->u.vpn.mon_eth = NULL; +			route_unlock_node(rn); /* uncount skiplist */ +		} +		if (hie->u.vpn.e.source) { +			if (skiplist_count(hie->u.vpn.e.source)) +				return; +			skiplist_free(hie->u.vpn.e.source); +			hie->u.vpn.e.source = NULL; +			route_unlock_node(rn); +		} +		if (hie->u.vpn.idx_rd) { +			if (skiplist_count(hie->u.vpn.idx_rd)) +				return; +			skiplist_free(hie->u.vpn.idx_rd); +			hie->u.vpn.idx_rd = NULL; +			route_unlock_node(rn); +		} +		if (hie->u.vpn.mon_eth) { +			if (skiplist_count(hie->u.vpn.mon_eth)) +				return; +			skiplist_free(hie->u.vpn.mon_eth); +			hie->u.vpn.mon_eth = NULL; +			route_unlock_node(rn); +		} +		break; + +	default: +		assert(0); +	} +	XFREE(MTYPE_RFAPI_IT_EXTRA, hie); +	rn->aggregate = NULL; +	route_unlock_node(rn);  }  /*   * returns locked node   */ -struct route_node * -rfapiMonitorGetAttachNode (struct rfapi_descriptor *rfd, struct prefix *p) +struct route_node *rfapiMonitorGetAttachNode(struct rfapi_descriptor *rfd, +					     struct prefix *p)  { -  afi_t afi; -  struct route_node *rn; - -  if (RFAPI_0_PREFIX (p)) -    { -      assert (1); -    } - -  afi = family2afi (p->family); -  assert (afi); - -  /* -   * It's possible that even though there is a route at this node, -   * there are no routes with valid UN addresses (i.e,. with no -   * valid tunnel routes). Check for that and walk back up the -   * tree if necessary. -   * -   * When the outer loop completes, the matched node, if any, is -   * locked (i.e., its reference count has been incremented) to -   * account for the VPN monitor we are about to attach. -   * -   * if a monitor is moved to another node, there must be -   * corresponding unlock/locks -   */ -  for (rn = route_node_match (rfd->import_table->imported_vpn[afi], p); rn;) -    { - -      struct bgp_info *bi; -      struct prefix pfx_dummy; - -      /* TBD update this code to use new valid_interior_count */ -      for (bi = rn->info; bi; bi = bi->next) -        { -          /* -           * If there is a cached ENCAP UN address, it's a usable -           * VPN route -           */ -          if (bi->extra && bi->extra->vnc.import.un_family) -            { -              break; -            } - -          /* -           * Or if there is a valid Encap Attribute tunnel subtlv address, -           * it's a usable VPN route. -           */ -          if (!rfapiGetVncTunnelUnAddr (bi->attr, &pfx_dummy)) -            { -              break; -            } -        } -      if (bi) -        break; - -      route_unlock_node (rn); -      if ((rn = rn->parent)) -        { -          route_lock_node (rn); -        } -    } - -  if (!rn) -    { -      struct prefix pfx_default; - -      memset (&pfx_default, 0, sizeof (pfx_default)); -      pfx_default.family = p->family; - -      /* creates default node if none exists, and increments ref count */ -      rn = -        route_node_get (rfd->import_table->imported_vpn[afi], &pfx_default); -    } - -  return rn; +	afi_t afi; +	struct route_node *rn; + +	if (RFAPI_0_PREFIX(p)) { +		assert(1); +	} + +	afi = family2afi(p->family); +	assert(afi); + +	/* +	 * It's possible that even though there is a route at this node, +	 * there are no routes with valid UN addresses (i.e,. with no +	 * valid tunnel routes). Check for that and walk back up the +	 * tree if necessary. +	 * +	 * When the outer loop completes, the matched node, if any, is +	 * locked (i.e., its reference count has been incremented) to +	 * account for the VPN monitor we are about to attach. +	 * +	 * if a monitor is moved to another node, there must be +	 * corresponding unlock/locks +	 */ +	for (rn = route_node_match(rfd->import_table->imported_vpn[afi], p); +	     rn;) { + +		struct bgp_info *bi; +		struct prefix pfx_dummy; + +		/* TBD update this code to use new valid_interior_count */ +		for (bi = rn->info; bi; bi = bi->next) { +			/* +			 * If there is a cached ENCAP UN address, it's a usable +			 * VPN route +			 */ +			if (bi->extra && bi->extra->vnc.import.un_family) { +				break; +			} + +			/* +			 * Or if there is a valid Encap Attribute tunnel subtlv +			 * address, +			 * it's a usable VPN route. +			 */ +			if (!rfapiGetVncTunnelUnAddr(bi->attr, &pfx_dummy)) { +				break; +			} +		} +		if (bi) +			break; + +		route_unlock_node(rn); +		if ((rn = rn->parent)) { +			route_lock_node(rn); +		} +	} + +	if (!rn) { +		struct prefix pfx_default; + +		memset(&pfx_default, 0, sizeof(pfx_default)); +		pfx_default.family = p->family; + +		/* creates default node if none exists, and increments ref count +		 */ +		rn = route_node_get(rfd->import_table->imported_vpn[afi], +				    &pfx_default); +	} + +	return rn;  } -/*  +/*   * If this function happens to attach the monitor to a radix tree   * node (as opposed to the 0-prefix list), the node pointer is   * returned (for the benefit of caller which might like to use it   * to generate an immediate query response).   */ -static struct route_node * -rfapiMonitorAttachImport (struct rfapi_descriptor *rfd, -                          struct rfapi_monitor_vpn *m) +static struct route_node *rfapiMonitorAttachImport(struct rfapi_descriptor *rfd, +						   struct rfapi_monitor_vpn *m)  { -  struct route_node *rn; - -  rfapiMonitorCheckAttachAllowed (); - -  if (RFAPI_0_PREFIX (&m->p)) -    { -      /* -       * Add new monitor entry to vpn0 list -       */ -      afi_t afi; - -      afi = family2afi (m->p.family); -      assert (afi); - -      m->next = rfd->import_table->vpn0_queries[afi]; -      rfd->import_table->vpn0_queries[afi] = m; -      vnc_zlog_debug_verbose ("%s: attached monitor %p to vpn0 list", __func__, m); -      return NULL; -    } - -  /* -   * Attach new monitor entry to import table node -   */ -  rn = rfapiMonitorGetAttachNode (rfd, &m->p);  /* returns locked rn */ -  m->node = rn; -  m->next = RFAPI_MONITOR_VPN (rn); -  RFAPI_MONITOR_VPN_W_ALLOC (rn) = m; -  RFAPI_CHECK_REFCOUNT (rn, SAFI_MPLS_VPN, 0); -  vnc_zlog_debug_verbose ("%s: attached monitor %p to rn %p", __func__, m, rn); -  return rn; +	struct route_node *rn; + +	rfapiMonitorCheckAttachAllowed(); + +	if (RFAPI_0_PREFIX(&m->p)) { +		/* +		 * Add new monitor entry to vpn0 list +		 */ +		afi_t afi; + +		afi = family2afi(m->p.family); +		assert(afi); + +		m->next = rfd->import_table->vpn0_queries[afi]; +		rfd->import_table->vpn0_queries[afi] = m; +		vnc_zlog_debug_verbose("%s: attached monitor %p to vpn0 list", +				       __func__, m); +		return NULL; +	} + +	/* +	 * Attach new monitor entry to import table node +	 */ +	rn = rfapiMonitorGetAttachNode(rfd, &m->p); /* returns locked rn */ +	m->node = rn; +	m->next = RFAPI_MONITOR_VPN(rn); +	RFAPI_MONITOR_VPN_W_ALLOC(rn) = m; +	RFAPI_CHECK_REFCOUNT(rn, SAFI_MPLS_VPN, 0); +	vnc_zlog_debug_verbose("%s: attached monitor %p to rn %p", __func__, m, +			       rn); +	return rn;  }  /*   * reattach monitors for this HD to import table   */ -void -rfapiMonitorAttachImportHd (struct rfapi_descriptor *rfd) +void rfapiMonitorAttachImportHd(struct rfapi_descriptor *rfd)  { -  struct route_node *mrn; - -  if (!rfd->mon) -    { -      /* -       * No monitors for this HD -       */ -      return; -    } - -  for (mrn = route_top (rfd->mon); mrn; mrn = route_next (mrn)) -    { - -      if (!mrn->info) -        continue; - -      (void) rfapiMonitorAttachImport (rfd, -                                       (struct rfapi_monitor_vpn -                                        *) (mrn->info)); -    } +	struct route_node *mrn; + +	if (!rfd->mon) { +		/* +		 * No monitors for this HD +		 */ +		return; +	} + +	for (mrn = route_top(rfd->mon); mrn; mrn = route_next(mrn)) { + +		if (!mrn->info) +			continue; + +		(void)rfapiMonitorAttachImport( +			rfd, (struct rfapi_monitor_vpn *)(mrn->info)); +	}  }  /* @@ -506,1198 +468,1123 @@ rfapiMonitorAttachImportHd (struct rfapi_descriptor *rfd)   * caller will have to do its own lookup.   */  struct route_node * -rfapiMonitorAdd ( -  struct bgp			*bgp, -  struct rfapi_descriptor	*rfd, -  struct prefix			*p) +rfapiMonitorAdd(struct bgp *bgp, struct rfapi_descriptor *rfd, struct prefix *p)  { -  struct rfapi_monitor_vpn *m; -  struct route_node *rn; - -  /* -   * Initialize nve's monitor list if needed -   * NB use the same radix tree for IPv4 and IPv6 targets. -   * The prefix will always have full-length mask (/32, /128) -   * or be 0/0 so they won't get mixed up.  -   */ -  if (!rfd->mon) -    { -      rfd->mon = route_table_init (); -    } -  rn = route_node_get (rfd->mon, p); -  if (rn->info) -    { -      /* -       * received this query before, no further action needed -       */ -      rfapiMonitorTimerRestart ((struct rfapi_monitor_vpn *) rn->info); -      route_unlock_node (rn); -      return NULL; -    } - -  /* -   * New query for this nve, record it in the HD -   */ -  rn->info = XCALLOC (MTYPE_RFAPI_MONITOR, sizeof (struct rfapi_monitor_vpn)); -  m = (struct rfapi_monitor_vpn *) (rn->info); -  m->rfd = rfd; -  prefix_copy (&m->p, p); - -  ++rfd->monitor_count; -  ++bgp->rfapi->monitor_count; - -  rfapiMonitorTimerRestart (m); - -  if (bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE) -    { -      /* -       * callbacks turned off, so don't attach monitor to import table -       */ -      return NULL; -    } - - -  /* -   * attach to import table -   */ -  return rfapiMonitorAttachImport (rfd, m); +	struct rfapi_monitor_vpn *m; +	struct route_node *rn; + +	/* +	 * Initialize nve's monitor list if needed +	 * NB use the same radix tree for IPv4 and IPv6 targets. +	 * The prefix will always have full-length mask (/32, /128) +	 * or be 0/0 so they won't get mixed up. +	 */ +	if (!rfd->mon) { +		rfd->mon = route_table_init(); +	} +	rn = route_node_get(rfd->mon, p); +	if (rn->info) { +		/* +		 * received this query before, no further action needed +		 */ +		rfapiMonitorTimerRestart((struct rfapi_monitor_vpn *)rn->info); +		route_unlock_node(rn); +		return NULL; +	} + +	/* +	 * New query for this nve, record it in the HD +	 */ +	rn->info = +		XCALLOC(MTYPE_RFAPI_MONITOR, sizeof(struct rfapi_monitor_vpn)); +	m = (struct rfapi_monitor_vpn *)(rn->info); +	m->rfd = rfd; +	prefix_copy(&m->p, p); + +	++rfd->monitor_count; +	++bgp->rfapi->monitor_count; + +	rfapiMonitorTimerRestart(m); + +	if (bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE) { +		/* +		 * callbacks turned off, so don't attach monitor to import table +		 */ +		return NULL; +	} + + +	/* +	 * attach to import table +	 */ +	return rfapiMonitorAttachImport(rfd, m);  }  /*   * returns monitor pointer if found, NULL if not   */  static struct rfapi_monitor_vpn * -rfapiMonitorDetachImport (struct rfapi_monitor_vpn *m) +rfapiMonitorDetachImport(struct rfapi_monitor_vpn *m)  { -  struct rfapi_monitor_vpn *prev; -  struct rfapi_monitor_vpn *this = NULL; - -  if (RFAPI_0_PREFIX (&m->p)) -    { -      afi_t afi; - -      /* -       * 0-prefix monitors are stored in a special list and not -       * in the import VPN tree -       */ - -      afi = family2afi (m->p.family); -      assert (afi); - -      if (m->rfd->import_table) -        { -          for (prev = NULL, this = m->rfd->import_table->vpn0_queries[afi]; -               this; prev = this, this = this->next) -            { - -              if (this == m) -                break; -            } -          if (this) -            { -              if (!prev) -                { -                  m->rfd->import_table->vpn0_queries[afi] = this->next; -                } -              else -                { -                  prev->next = this->next; -                } -            } -        } -    } -  else -    { - -      if (m->node) -        { -          for (prev = NULL, -               this = RFAPI_MONITOR_VPN (m->node); -               this; prev = this, this = this->next) -            { - -              if (this == m) -                break; -            } -          if (this) -            { -              if (prev) -                { -                  prev->next = this->next; -                } -              else -                { -                  RFAPI_MONITOR_VPN_W_ALLOC (m->node) = this->next; -                } -              RFAPI_CHECK_REFCOUNT (m->node, SAFI_MPLS_VPN, 1); -              route_unlock_node (m->node); -            } -          m->node = NULL; -        } -    } -  return this; +	struct rfapi_monitor_vpn *prev; +	struct rfapi_monitor_vpn *this = NULL; + +	if (RFAPI_0_PREFIX(&m->p)) { +		afi_t afi; + +		/* +		 * 0-prefix monitors are stored in a special list and not +		 * in the import VPN tree +		 */ + +		afi = family2afi(m->p.family); +		assert(afi); + +		if (m->rfd->import_table) { +			for (prev = NULL, +			    this = m->rfd->import_table->vpn0_queries[afi]; +			     this; prev = this, this = this->next) { + +				if (this == m) +					break; +			} +			if (this) { +				if (!prev) { +					m->rfd->import_table +						->vpn0_queries[afi] = +						this->next; +				} else { +					prev->next = this->next; +				} +			} +		} +	} else { + +		if (m->node) { +			for (prev = NULL, this = RFAPI_MONITOR_VPN(m->node); +			     this; prev = this, this = this->next) { + +				if (this == m) +					break; +			} +			if (this) { +				if (prev) { +					prev->next = this->next; +				} else { +					RFAPI_MONITOR_VPN_W_ALLOC(m->node) = +						this->next; +				} +				RFAPI_CHECK_REFCOUNT(m->node, SAFI_MPLS_VPN, 1); +				route_unlock_node(m->node); +			} +			m->node = NULL; +		} +	} +	return this;  } -void -rfapiMonitorDetachImportHd (struct rfapi_descriptor *rfd) +void rfapiMonitorDetachImportHd(struct rfapi_descriptor *rfd)  { -  struct route_node *rn; - -  if (!rfd->mon) -    return; - -  for (rn = route_top (rfd->mon); rn; rn = route_next (rn)) -    { -      if (rn->info) -        { -          rfapiMonitorDetachImport ((struct rfapi_monitor_vpn *) (rn->info)); -        } -    } +	struct route_node *rn; + +	if (!rfd->mon) +		return; + +	for (rn = route_top(rfd->mon); rn; rn = route_next(rn)) { +		if (rn->info) { +			rfapiMonitorDetachImport( +				(struct rfapi_monitor_vpn *)(rn->info)); +		} +	}  } -void -rfapiMonitorDel ( -  struct bgp			*bgp, -  struct rfapi_descriptor	*rfd, -  struct prefix			*p) +void rfapiMonitorDel(struct bgp *bgp, struct rfapi_descriptor *rfd, +		     struct prefix *p)  { -  struct route_node *rn; -  struct rfapi_monitor_vpn *m; - -  assert (rfd->mon); -  rn = route_node_get (rfd->mon, p);    /* locks node */ -  m = rn->info; - -  assert (m); - -  /* -   * remove from import table -   */ -  if (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE)) -    { -      rfapiMonitorDetachImport (m); -    } - -  if (m->timer) -    { -      thread_cancel (m->timer); -      m->timer = NULL; -    } - -  /* -   * remove from rfd list -   */ -  XFREE (MTYPE_RFAPI_MONITOR, m); -  rn->info = NULL; -  route_unlock_node (rn);       /* undo original lock when created */ -  route_unlock_node (rn);       /* undo lock in route_node_get */ - -  --rfd->monitor_count; -  --bgp->rfapi->monitor_count; +	struct route_node *rn; +	struct rfapi_monitor_vpn *m; + +	assert(rfd->mon); +	rn = route_node_get(rfd->mon, p); /* locks node */ +	m = rn->info; + +	assert(m); + +	/* +	 * remove from import table +	 */ +	if (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE)) { +		rfapiMonitorDetachImport(m); +	} + +	if (m->timer) { +		thread_cancel(m->timer); +		m->timer = NULL; +	} + +	/* +	 * remove from rfd list +	 */ +	XFREE(MTYPE_RFAPI_MONITOR, m); +	rn->info = NULL; +	route_unlock_node(rn); /* undo original lock when created */ +	route_unlock_node(rn); /* undo lock in route_node_get */ + +	--rfd->monitor_count; +	--bgp->rfapi->monitor_count;  }  /*   * returns count of monitors deleted   */ -int -rfapiMonitorDelHd (struct rfapi_descriptor *rfd) +int rfapiMonitorDelHd(struct rfapi_descriptor *rfd)  { -  struct route_node *rn; -  struct bgp *bgp; -  int count = 0; - -  vnc_zlog_debug_verbose ("%s: entry rfd=%p", __func__, rfd); - -  bgp = bgp_get_default (); - -  if (rfd->mon) -    { -      for (rn = route_top (rfd->mon); rn; rn = route_next (rn)) -        { -          struct rfapi_monitor_vpn *m; -          if ((m = rn->info)) -            { -              if (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE)) -                { -                  rfapiMonitorDetachImport (m); -                } - -              if (m->timer) -                { -                  thread_cancel (m->timer); -                  m->timer = NULL; -                } - -              XFREE (MTYPE_RFAPI_MONITOR, m); -              rn->info = NULL; -              route_unlock_node (rn);   /* undo original lock when created */ -              ++count; -              --rfd->monitor_count; -              --bgp->rfapi->monitor_count; -            } -        } -      route_table_finish (rfd->mon); -      rfd->mon = NULL; -    } - -  if (rfd->mon_eth) -    { - -      struct rfapi_monitor_eth *mon_eth; - -      while (!skiplist_first (rfd->mon_eth, NULL, (void **) &mon_eth)) -        { - -          int rc; - -          if (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE)) -            { -              rfapiMonitorEthDetachImport (bgp, mon_eth); -            } -          else -            { +	struct route_node *rn; +	struct bgp *bgp; +	int count = 0; + +	vnc_zlog_debug_verbose("%s: entry rfd=%p", __func__, rfd); + +	bgp = bgp_get_default(); + +	if (rfd->mon) { +		for (rn = route_top(rfd->mon); rn; rn = route_next(rn)) { +			struct rfapi_monitor_vpn *m; +			if ((m = rn->info)) { +				if (!(bgp->rfapi_cfg->flags +				      & BGP_VNC_CONFIG_CALLBACK_DISABLE)) { +					rfapiMonitorDetachImport(m); +				} + +				if (m->timer) { +					thread_cancel(m->timer); +					m->timer = NULL; +				} + +				XFREE(MTYPE_RFAPI_MONITOR, m); +				rn->info = NULL; +				route_unlock_node(rn); /* undo original lock +							  when created */ +				++count; +				--rfd->monitor_count; +				--bgp->rfapi->monitor_count; +			} +		} +		route_table_finish(rfd->mon); +		rfd->mon = NULL; +	} + +	if (rfd->mon_eth) { + +		struct rfapi_monitor_eth *mon_eth; + +		while (!skiplist_first(rfd->mon_eth, NULL, (void **)&mon_eth)) { + +			int rc; + +			if (!(bgp->rfapi_cfg->flags +			      & BGP_VNC_CONFIG_CALLBACK_DISABLE)) { +				rfapiMonitorEthDetachImport(bgp, mon_eth); +			} else {  #if DEBUG_L2_EXTRA -              vnc_zlog_debug_verbose -                ("%s: callbacks disabled, not attempting to detach mon_eth %p", -                 __func__, mon_eth); +				vnc_zlog_debug_verbose( +					"%s: callbacks disabled, not attempting to detach mon_eth %p", +					__func__, mon_eth);  #endif -            } - -          if (mon_eth->timer) -            { -              thread_cancel (mon_eth->timer); -              mon_eth->timer = NULL; -            } - -          /* -           * remove from rfd list -           */ -          rc = skiplist_delete (rfd->mon_eth, mon_eth, mon_eth); -          assert (!rc); - -          vnc_zlog_debug_verbose ("%s: freeing mon_eth %p", __func__, mon_eth); -          XFREE (MTYPE_RFAPI_MONITOR_ETH, mon_eth); - -          ++count; -          --rfd->monitor_count; -          --bgp->rfapi->monitor_count; -        } -      skiplist_free (rfd->mon_eth); -      rfd->mon_eth = NULL; - -    } - -  return count; +			} + +			if (mon_eth->timer) { +				thread_cancel(mon_eth->timer); +				mon_eth->timer = NULL; +			} + +			/* +			 * remove from rfd list +			 */ +			rc = skiplist_delete(rfd->mon_eth, mon_eth, mon_eth); +			assert(!rc); + +			vnc_zlog_debug_verbose("%s: freeing mon_eth %p", +					       __func__, mon_eth); +			XFREE(MTYPE_RFAPI_MONITOR_ETH, mon_eth); + +			++count; +			--rfd->monitor_count; +			--bgp->rfapi->monitor_count; +		} +		skiplist_free(rfd->mon_eth); +		rfd->mon_eth = NULL; +	} + +	return count;  } -void -rfapiMonitorResponseRemovalOff (struct bgp *bgp) +void rfapiMonitorResponseRemovalOff(struct bgp *bgp)  { -  if (bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE) -    { -      return; -    } -  bgp->rfapi_cfg->flags |= BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE; +	if (bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE) { +		return; +	} +	bgp->rfapi_cfg->flags |= BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE;  } -void -rfapiMonitorResponseRemovalOn (struct bgp *bgp) +void rfapiMonitorResponseRemovalOn(struct bgp *bgp)  { -  if (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE)) -    { -      return; -    } -  bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE; +	if (!(bgp->rfapi_cfg->flags +	      & BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE)) { +		return; +	} +	bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE;  } -static int -rfapiMonitorTimerExpire (struct thread *t) +static int rfapiMonitorTimerExpire(struct thread *t)  { -  struct rfapi_monitor_vpn *m = t->arg; +	struct rfapi_monitor_vpn *m = t->arg; -  /* forget reference to thread, it's gone */ -  m->timer = NULL; +	/* forget reference to thread, it's gone */ +	m->timer = NULL; -  /* delete the monitor */ -  rfapiMonitorDel (bgp_get_default (), m->rfd, &m->p); +	/* delete the monitor */ +	rfapiMonitorDel(bgp_get_default(), m->rfd, &m->p); -  return 0; +	return 0;  } -static void -rfapiMonitorTimerRestart (struct rfapi_monitor_vpn *m) +static void rfapiMonitorTimerRestart(struct rfapi_monitor_vpn *m)  { -  if (m->timer) -    { -      unsigned long remain = thread_timer_remain_second (m->timer); - -      /* unexpected case, but avoid wraparound problems below */ -      if (remain > m->rfd->response_lifetime) -        return; - -      /* don't restart if we just restarted recently */ -      if (m->rfd->response_lifetime - remain < 2) -        return; - -      thread_cancel (m->timer); -      m->timer = NULL; -    } - -  { -    char buf[BUFSIZ]; - -    vnc_zlog_debug_verbose ("%s: target %s life %u", __func__, -                rfapi_ntop (m->p.family, m->p.u.val, buf, BUFSIZ), -                m->rfd->response_lifetime); -  } -  m->timer = NULL; -  thread_add_timer(bm->master, rfapiMonitorTimerExpire, m, m->rfd->response_lifetime, -                   &m->timer); +	if (m->timer) { +		unsigned long remain = thread_timer_remain_second(m->timer); + +		/* unexpected case, but avoid wraparound problems below */ +		if (remain > m->rfd->response_lifetime) +			return; + +		/* don't restart if we just restarted recently */ +		if (m->rfd->response_lifetime - remain < 2) +			return; + +		thread_cancel(m->timer); +		m->timer = NULL; +	} + +	{ +		char buf[BUFSIZ]; + +		vnc_zlog_debug_verbose( +			"%s: target %s life %u", __func__, +			rfapi_ntop(m->p.family, m->p.u.val, buf, BUFSIZ), +			m->rfd->response_lifetime); +	} +	m->timer = NULL; +	thread_add_timer(bm->master, rfapiMonitorTimerExpire, m, +			 m->rfd->response_lifetime, &m->timer);  } -/*  +/*   * called when an updated response is sent to the NVE. Per   * ticket 255, restart timers for any monitors that could have   * been responsible for the response, i.e., any monitors for   * the exact prefix or a parent of it.   */ -void -rfapiMonitorTimersRestart (struct rfapi_descriptor *rfd, struct prefix *p) +void rfapiMonitorTimersRestart(struct rfapi_descriptor *rfd, struct prefix *p)  { -  struct route_node *rn; - -  if (AF_ETHERNET == p->family) -    { -      struct rfapi_monitor_eth *mon_eth; -      int rc; -      void *cursor; - -      /* -       * XXX match any LNI -       */ -      for (cursor = NULL, -           rc = -           skiplist_next (rfd->mon_eth, NULL, (void **) &mon_eth, &cursor); -           rc == 0; -           rc = -           skiplist_next (rfd->mon_eth, NULL, (void **) &mon_eth, &cursor)) -        { - -          if (!memcmp (mon_eth->macaddr.octet, p->u.prefix_eth.octet, -                       ETHER_ADDR_LEN)) -            { - -              rfapiMonitorEthTimerRestart (mon_eth); - -            } -        } - -    } -  else -    { -      for (rn = route_top (rfd->mon); rn; rn = route_next (rn)) -        { -          struct rfapi_monitor_vpn *m; - -          if (!((m = rn->info))) -            continue; - -          /* NB order of test is significant ! */ -          if (!m->node || prefix_match (&m->node->p, p)) -            { -              rfapiMonitorTimerRestart (m); -            } -        } -    } +	struct route_node *rn; + +	if (AF_ETHERNET == p->family) { +		struct rfapi_monitor_eth *mon_eth; +		int rc; +		void *cursor; + +		/* +		 * XXX match any LNI +		 */ +		for (cursor = NULL, +		    rc = skiplist_next(rfd->mon_eth, NULL, (void **)&mon_eth, +				       &cursor); +		     rc == 0; rc = skiplist_next(rfd->mon_eth, NULL, +						 (void **)&mon_eth, &cursor)) { + +			if (!memcmp(mon_eth->macaddr.octet, +				    p->u.prefix_eth.octet, ETHER_ADDR_LEN)) { + +				rfapiMonitorEthTimerRestart(mon_eth); +			} +		} + +	} else { +		for (rn = route_top(rfd->mon); rn; rn = route_next(rn)) { +			struct rfapi_monitor_vpn *m; + +			if (!((m = rn->info))) +				continue; + +			/* NB order of test is significant ! */ +			if (!m->node || prefix_match(&m->node->p, p)) { +				rfapiMonitorTimerRestart(m); +			} +		} +	}  }  /*   * Find monitors at this node and all its parents. Call   * rfapiRibUpdatePendingNode with this node and all corresponding NVEs.   */ -void -rfapiMonitorItNodeChanged ( -  struct rfapi_import_table	*import_table, -  struct route_node		*it_node, -  struct rfapi_monitor_vpn	*monitor_list) /* for base it node, NULL=all */ +void rfapiMonitorItNodeChanged( +	struct rfapi_import_table *import_table, struct route_node *it_node, +	struct rfapi_monitor_vpn *monitor_list) /* for base it node, NULL=all */  { -  struct skiplist   *nves_seen; -  struct route_node *rn = it_node; -  struct bgp        *bgp = bgp_get_default (); -  afi_t             afi = family2afi (rn->p.family); +	struct skiplist *nves_seen; +	struct route_node *rn = it_node; +	struct bgp *bgp = bgp_get_default(); +	afi_t afi = family2afi(rn->p.family);  #if DEBUG_L2_EXTRA -  char              buf_prefix[BUFSIZ]; +	char buf_prefix[BUFSIZ];  #endif -  assert (bgp); -  assert (import_table); +	assert(bgp); +	assert(import_table); -  nves_seen = skiplist_new (0, NULL, NULL); +	nves_seen = skiplist_new(0, NULL, NULL);  #if DEBUG_L2_EXTRA -  prefix2str (&it_node->p, buf_prefix, BUFSIZ); -  vnc_zlog_debug_verbose ("%s: it=%p, it_node=%p, it_node->prefix=%s", -              __func__, import_table, it_node, buf_prefix); +	prefix2str(&it_node->p, buf_prefix, BUFSIZ); +	vnc_zlog_debug_verbose("%s: it=%p, it_node=%p, it_node->prefix=%s", +			       __func__, import_table, it_node, buf_prefix);  #endif -  if (AFI_L2VPN == afi) -    { -      struct rfapi_monitor_eth *m; -      struct skiplist *sl; -      void *cursor; -      int rc; - -      if ((sl = RFAPI_MONITOR_ETH (rn))) -        { - -          for (cursor = NULL, -            rc = skiplist_next (sl, NULL, (void **) &m, (void **) &cursor); -            !rc; -            rc = skiplist_next (sl, NULL, (void **) &m, (void **) &cursor)) -            { - -              if (skiplist_search (nves_seen, m->rfd, NULL)) -                { -                  /* -                   * Haven't done this NVE yet. Add to "seen" list. -                   */ -                  assert (!skiplist_insert (nves_seen, m->rfd, NULL)); - -                  /* -                   * update its RIB -                   */ -                  rfapiRibUpdatePendingNode(bgp, m->rfd, import_table, -                    it_node, m->rfd->response_lifetime); -                } -            } -        } - -    } -  else -    { - -      struct rfapi_monitor_vpn *m; - -      if (monitor_list) -        { -          m = monitor_list; -        } -      else -        { -          m = RFAPI_MONITOR_VPN (rn); -        } - -      do -        { -          /*  -           * If we have reached the root node (parent==NULL) and there -           * are no routes here (info==NULL), and the IT node that -           * changed was not the root node (it_node->parent != NULL), -           * then any monitors at this node are here because they had -           * no match at all. Therefore, do not send route updates to them -           * because we haven't sent them an initial route. -           */ -          if (!rn->parent && !rn->info && it_node->parent) -            break; - -          for (; m; m = m->next) -            { - -              if (RFAPI_0_PREFIX (&m->p)) -                { -                  /* shouldn't happen, but be safe */ -                  continue; -                } -              if (skiplist_search (nves_seen, m->rfd, NULL)) -                { -                  /* -                   * Haven't done this NVE yet. Add to "seen" list. -                   */ -                  assert (!skiplist_insert (nves_seen, m->rfd, NULL)); - -                  { -                    char buf_attach_pfx[BUFSIZ]; -                    char buf_target_pfx[BUFSIZ]; - -                    prefix2str (&m->node->p, buf_attach_pfx, BUFSIZ); -                    prefix2str (&m->p, buf_target_pfx, BUFSIZ); -                    vnc_zlog_debug_verbose -                      ("%s: update rfd %p attached to pfx %s (targ=%s)", -                       __func__, m->rfd, buf_attach_pfx, buf_target_pfx); -                  } - -                  /* -                   * update its RIB -                   */ -                  rfapiRibUpdatePendingNode(bgp, m->rfd, import_table, -                    it_node, m->rfd->response_lifetime); -                } -            } -          rn = rn->parent; -          if (rn) -            m = RFAPI_MONITOR_VPN (rn); -        } -      while (rn); -    } - -  /* -   * All-routes L2 monitors -   */ -  if (AFI_L2VPN == afi) -    { -      struct rfapi_monitor_eth *e; +	if (AFI_L2VPN == afi) { +		struct rfapi_monitor_eth *m; +		struct skiplist *sl; +		void *cursor; +		int rc; + +		if ((sl = RFAPI_MONITOR_ETH(rn))) { + +			for (cursor = NULL, +			    rc = skiplist_next(sl, NULL, (void **)&m, +					       (void **)&cursor); +			     !rc; rc = skiplist_next(sl, NULL, (void **)&m, +						     (void **)&cursor)) { + +				if (skiplist_search(nves_seen, m->rfd, NULL)) { +					/* +					 * Haven't done this NVE yet. Add to +					 * "seen" list. +					 */ +					assert(!skiplist_insert(nves_seen, +								m->rfd, NULL)); + +					/* +					 * update its RIB +					 */ +					rfapiRibUpdatePendingNode( +						bgp, m->rfd, import_table, +						it_node, +						m->rfd->response_lifetime); +				} +			} +		} + +	} else { + +		struct rfapi_monitor_vpn *m; + +		if (monitor_list) { +			m = monitor_list; +		} else { +			m = RFAPI_MONITOR_VPN(rn); +		} + +		do { +			/* +			 * If we have reached the root node (parent==NULL) and +			 * there +			 * are no routes here (info==NULL), and the IT node that +			 * changed was not the root node (it_node->parent != +			 * NULL), +			 * then any monitors at this node are here because they +			 * had +			 * no match at all. Therefore, do not send route updates +			 * to them +			 * because we haven't sent them an initial route. +			 */ +			if (!rn->parent && !rn->info && it_node->parent) +				break; + +			for (; m; m = m->next) { + +				if (RFAPI_0_PREFIX(&m->p)) { +					/* shouldn't happen, but be safe */ +					continue; +				} +				if (skiplist_search(nves_seen, m->rfd, NULL)) { +					/* +					 * Haven't done this NVE yet. Add to +					 * "seen" list. +					 */ +					assert(!skiplist_insert(nves_seen, +								m->rfd, NULL)); + +					{ +						char buf_attach_pfx[BUFSIZ]; +						char buf_target_pfx[BUFSIZ]; + +						prefix2str(&m->node->p, +							   buf_attach_pfx, +							   BUFSIZ); +						prefix2str(&m->p, +							   buf_target_pfx, +							   BUFSIZ); +						vnc_zlog_debug_verbose( +							"%s: update rfd %p attached to pfx %s (targ=%s)", +							__func__, m->rfd, +							buf_attach_pfx, +							buf_target_pfx); +					} + +					/* +					 * update its RIB +					 */ +					rfapiRibUpdatePendingNode( +						bgp, m->rfd, import_table, +						it_node, +						m->rfd->response_lifetime); +				} +			} +			rn = rn->parent; +			if (rn) +				m = RFAPI_MONITOR_VPN(rn); +		} while (rn); +	} + +	/* +	 * All-routes L2 monitors +	 */ +	if (AFI_L2VPN == afi) { +		struct rfapi_monitor_eth *e;  #if DEBUG_L2_EXTRA -      vnc_zlog_debug_verbose ("%s: checking L2 all-routes monitors", __func__); +		vnc_zlog_debug_verbose("%s: checking L2 all-routes monitors", +				       __func__);  #endif -      for (e = import_table->eth0_queries; e; e = e->next) -        { +		for (e = import_table->eth0_queries; e; e = e->next) {  #if DEBUG_L2_EXTRA -          vnc_zlog_debug_verbose ("%s: checking eth0 mon=%p", __func__, e); +			vnc_zlog_debug_verbose("%s: checking eth0 mon=%p", +					       __func__, e);  #endif -          if (skiplist_search (nves_seen, e->rfd, NULL)) -            { -              /* -               * Haven't done this NVE yet. Add to "seen" list. -               */ -              assert (!skiplist_insert (nves_seen, e->rfd, NULL)); - -              /* -               * update its RIB -               */ +			if (skiplist_search(nves_seen, e->rfd, NULL)) { +				/* +				 * Haven't done this NVE yet. Add to "seen" +				 * list. +				 */ +				assert(!skiplist_insert(nves_seen, e->rfd, +							NULL)); + +/* + * update its RIB + */  #if DEBUG_L2_EXTRA -              vnc_zlog_debug_verbose ("%s: found L2 all-routes monitor %p", __func__, e); +				vnc_zlog_debug_verbose( +					"%s: found L2 all-routes monitor %p", +					__func__, e);  #endif -              rfapiRibUpdatePendingNode (bgp, e->rfd, import_table, it_node, -                e->rfd->response_lifetime); -            } -        } -    } -  else -    { -      struct rfapi_monitor_vpn *m; - -      /* -       * All-routes IPv4. IPv6 monitors -       */ -      for (m = import_table->vpn0_queries[afi]; m; m = m->next) -        { -          if (skiplist_search (nves_seen, m->rfd, NULL)) -            { -              /* -               * Haven't done this NVE yet. Add to "seen" list. -               */ -              assert (!skiplist_insert (nves_seen, m->rfd, NULL)); - -              /* -               * update its RIB -               */ -              rfapiRibUpdatePendingNode (bgp, m->rfd, import_table, it_node, -                m->rfd->response_lifetime); -            } -        } -    } - -  skiplist_free (nves_seen); +				rfapiRibUpdatePendingNode( +					bgp, e->rfd, import_table, it_node, +					e->rfd->response_lifetime); +			} +		} +	} else { +		struct rfapi_monitor_vpn *m; + +		/* +		 * All-routes IPv4. IPv6 monitors +		 */ +		for (m = import_table->vpn0_queries[afi]; m; m = m->next) { +			if (skiplist_search(nves_seen, m->rfd, NULL)) { +				/* +				 * Haven't done this NVE yet. Add to "seen" +				 * list. +				 */ +				assert(!skiplist_insert(nves_seen, m->rfd, +							NULL)); + +				/* +				 * update its RIB +				 */ +				rfapiRibUpdatePendingNode( +					bgp, m->rfd, import_table, it_node, +					m->rfd->response_lifetime); +			} +		} +	} + +	skiplist_free(nves_seen);  }  /*   * For the listed monitors, update new node and its subtree, but   * omit old node and its subtree   */ -void -rfapiMonitorMovedUp ( -  struct rfapi_import_table	*import_table, -  struct route_node		*old_node, -  struct route_node		*new_node, -  struct rfapi_monitor_vpn	*monitor_list) +void rfapiMonitorMovedUp(struct rfapi_import_table *import_table, +			 struct route_node *old_node, +			 struct route_node *new_node, +			 struct rfapi_monitor_vpn *monitor_list)  { -  struct bgp *bgp = bgp_get_default (); -  struct rfapi_monitor_vpn *m; - -  assert (new_node); -  assert (old_node); -  assert (new_node != old_node); - -  /* -   * If new node is 0/0 and there is no route there, don't -   * generate an update because it will not contain any -   * routes including the target. -   */ -  if (!new_node->parent && !new_node->info) -    { -      vnc_zlog_debug_verbose ("%s: new monitor at 0/0 and no routes, no updates", -                  __func__); -      return; -    } - -  for (m = monitor_list; m; m = m->next) -    { -      rfapiRibUpdatePendingNode (bgp, m->rfd, import_table, new_node, -                                 m->rfd->response_lifetime); -      rfapiRibUpdatePendingNodeSubtree (bgp, m->rfd, import_table, new_node, -                                        old_node, m->rfd->response_lifetime); -    } +	struct bgp *bgp = bgp_get_default(); +	struct rfapi_monitor_vpn *m; + +	assert(new_node); +	assert(old_node); +	assert(new_node != old_node); + +	/* +	 * If new node is 0/0 and there is no route there, don't +	 * generate an update because it will not contain any +	 * routes including the target. +	 */ +	if (!new_node->parent && !new_node->info) { +		vnc_zlog_debug_verbose( +			"%s: new monitor at 0/0 and no routes, no updates", +			__func__); +		return; +	} + +	for (m = monitor_list; m; m = m->next) { +		rfapiRibUpdatePendingNode(bgp, m->rfd, import_table, new_node, +					  m->rfd->response_lifetime); +		rfapiRibUpdatePendingNodeSubtree(bgp, m->rfd, import_table, +						 new_node, old_node, +						 m->rfd->response_lifetime); +	}  } -static int -rfapiMonitorEthTimerExpire (struct thread *t) +static int rfapiMonitorEthTimerExpire(struct thread *t)  { -  struct rfapi_monitor_eth *m = t->arg; +	struct rfapi_monitor_eth *m = t->arg; -  /* forget reference to thread, it's gone */ -  m->timer = NULL; +	/* forget reference to thread, it's gone */ +	m->timer = NULL; -  /* delete the monitor */ -  rfapiMonitorEthDel (bgp_get_default (), m->rfd, &m->macaddr, -                      m->logical_net_id); +	/* delete the monitor */ +	rfapiMonitorEthDel(bgp_get_default(), m->rfd, &m->macaddr, +			   m->logical_net_id); -  return 0; +	return 0;  } -static void -rfapiMonitorEthTimerRestart (struct rfapi_monitor_eth *m) +static void rfapiMonitorEthTimerRestart(struct rfapi_monitor_eth *m)  { -  if (m->timer) -    { -      unsigned long remain = thread_timer_remain_second (m->timer); - -      /* unexpected case, but avoid wraparound problems below */ -      if (remain > m->rfd->response_lifetime) -        return; - -      /* don't restart if we just restarted recently */ -      if (m->rfd->response_lifetime - remain < 2) -        return; - -      thread_cancel (m->timer); -      m->timer = NULL; -    } - -  { -    char buf[BUFSIZ]; - -    vnc_zlog_debug_verbose ("%s: target %s life %u", __func__, -                rfapiEthAddr2Str (&m->macaddr, buf, BUFSIZ), -                m->rfd->response_lifetime); -  } -  m->timer = NULL; -  thread_add_timer(bm->master, rfapiMonitorEthTimerExpire, m, m->rfd->response_lifetime, -                   &m->timer); +	if (m->timer) { +		unsigned long remain = thread_timer_remain_second(m->timer); + +		/* unexpected case, but avoid wraparound problems below */ +		if (remain > m->rfd->response_lifetime) +			return; + +		/* don't restart if we just restarted recently */ +		if (m->rfd->response_lifetime - remain < 2) +			return; + +		thread_cancel(m->timer); +		m->timer = NULL; +	} + +	{ +		char buf[BUFSIZ]; + +		vnc_zlog_debug_verbose( +			"%s: target %s life %u", __func__, +			rfapiEthAddr2Str(&m->macaddr, buf, BUFSIZ), +			m->rfd->response_lifetime); +	} +	m->timer = NULL; +	thread_add_timer(bm->master, rfapiMonitorEthTimerExpire, m, +			 m->rfd->response_lifetime, &m->timer);  } -static int -mon_eth_cmp (void *a, void *b) +static int mon_eth_cmp(void *a, void *b)  { -  struct rfapi_monitor_eth *m1; -  struct rfapi_monitor_eth *m2; - -  int i; - -  m1 = (struct rfapi_monitor_eth *) a; -  m2 = (struct rfapi_monitor_eth *) b; - -  /* -   * compare ethernet addresses -   */ -  for (i = 0; i < ETHER_ADDR_LEN; ++i) -    { -      if (m1->macaddr.octet[i] != m2->macaddr.octet[i]) -        return (m1->macaddr.octet[i] - m2->macaddr.octet[i]); -    } - -  /* -   * compare LNIs -   */ -  return (m1->logical_net_id - m2->logical_net_id); +	struct rfapi_monitor_eth *m1; +	struct rfapi_monitor_eth *m2; + +	int i; + +	m1 = (struct rfapi_monitor_eth *)a; +	m2 = (struct rfapi_monitor_eth *)b; + +	/* +	 * compare ethernet addresses +	 */ +	for (i = 0; i < ETHER_ADDR_LEN; ++i) { +		if (m1->macaddr.octet[i] != m2->macaddr.octet[i]) +			return (m1->macaddr.octet[i] - m2->macaddr.octet[i]); +	} + +	/* +	 * compare LNIs +	 */ +	return (m1->logical_net_id - m2->logical_net_id);  } -static void -rfapiMonitorEthAttachImport ( -  struct rfapi_import_table	*it, -  struct route_node		*rn,      /* it node attach point if non-0 */ -  struct rfapi_monitor_eth	*mon)     /* monitor struct to attach */ +static void rfapiMonitorEthAttachImport( +	struct rfapi_import_table *it, +	struct route_node *rn,	 /* it node attach point if non-0 */ +	struct rfapi_monitor_eth *mon) /* monitor struct to attach */  { -  struct skiplist *sl; -  int rc; +	struct skiplist *sl; +	int rc; -  vnc_zlog_debug_verbose ("%s: it=%p", __func__, it); +	vnc_zlog_debug_verbose("%s: it=%p", __func__, it); -  rfapiMonitorCheckAttachAllowed (); +	rfapiMonitorCheckAttachAllowed(); -  if (RFAPI_0_ETHERADDR (&mon->macaddr)) -    { -      /* -       * These go on a different list -       */ -      mon->next = it->eth0_queries; -      it->eth0_queries = mon; +	if (RFAPI_0_ETHERADDR(&mon->macaddr)) { +		/* +		 * These go on a different list +		 */ +		mon->next = it->eth0_queries; +		it->eth0_queries = mon;  #if DEBUG_L2_EXTRA -      vnc_zlog_debug_verbose ("%s: attached monitor %p to eth0 list", __func__, mon); +		vnc_zlog_debug_verbose("%s: attached monitor %p to eth0 list", +				       __func__, mon);  #endif -      return; -    } +		return; +	} -  if (rn == NULL) -    { +	if (rn == NULL) {  #if DEBUG_L2_EXTRA -      vnc_zlog_debug_verbose ("%s: rn is null!", __func__); +		vnc_zlog_debug_verbose("%s: rn is null!", __func__);  #endif -      return; -    } - -  /* -   * Get sl to attach to -   */ -  sl = RFAPI_MONITOR_ETH_W_ALLOC (rn); -  if (!sl) -    { -      sl = RFAPI_MONITOR_ETH_W_ALLOC (rn) = skiplist_new (0, NULL, NULL); -      route_lock_node(rn);	/* count skiplist mon_eth */ -    } +		return; +	} + +	/* +	 * Get sl to attach to +	 */ +	sl = RFAPI_MONITOR_ETH_W_ALLOC(rn); +	if (!sl) { +		sl = RFAPI_MONITOR_ETH_W_ALLOC(rn) = +			skiplist_new(0, NULL, NULL); +		route_lock_node(rn); /* count skiplist mon_eth */ +	}  #if DEBUG_L2_EXTRA -  vnc_zlog_debug_verbose ("%s: rn=%p, rn->lock=%d, sl=%p, attaching eth mon %p", -    __func__, rn, rn->lock, sl, mon); +	vnc_zlog_debug_verbose( +		"%s: rn=%p, rn->lock=%d, sl=%p, attaching eth mon %p", __func__, +		rn, rn->lock, sl, mon);  #endif -  rc = skiplist_insert (sl, (void *) mon, (void *) mon); -  assert (!rc); +	rc = skiplist_insert(sl, (void *)mon, (void *)mon); +	assert(!rc); -  /* count eth monitor */ -  route_lock_node(rn); +	/* count eth monitor */ +	route_lock_node(rn);  }  /*   * reattach monitors for this HD to import table   */ -static void -rfapiMonitorEthAttachImportHd (struct bgp *bgp, struct rfapi_descriptor *rfd) +static void rfapiMonitorEthAttachImportHd(struct bgp *bgp, +					  struct rfapi_descriptor *rfd)  { -  void *cursor; -  struct rfapi_monitor_eth *mon; -  int rc; - -  if (!rfd->mon_eth) -    { -      /* -       * No monitors for this HD -       */ -      return; -    } - -  for (cursor = NULL, -       rc = skiplist_next (rfd->mon_eth, NULL, (void **) &mon, &cursor); -       rc == 0; -       rc = skiplist_next (rfd->mon_eth, NULL, (void **) &mon, &cursor)) -    { - -      struct rfapi_import_table *it; -      struct prefix pfx_mac_buf; -      struct route_node *rn; - -      it = rfapiMacImportTableGet (bgp, mon->logical_net_id); -      assert (it); - -      memset ((void *) &pfx_mac_buf, 0, sizeof (struct prefix)); -      pfx_mac_buf.family = AF_ETHERNET; -      pfx_mac_buf.prefixlen = 48; -      pfx_mac_buf.u.prefix_eth = mon->macaddr; - -      rn = route_node_get (it->imported_vpn[AFI_L2VPN], &pfx_mac_buf); -      assert (rn); - -      (void) rfapiMonitorEthAttachImport (it, rn, mon); -    } +	void *cursor; +	struct rfapi_monitor_eth *mon; +	int rc; + +	if (!rfd->mon_eth) { +		/* +		 * No monitors for this HD +		 */ +		return; +	} + +	for (cursor = NULL, +	    rc = skiplist_next(rfd->mon_eth, NULL, (void **)&mon, &cursor); +	     rc == 0; +	     rc = skiplist_next(rfd->mon_eth, NULL, (void **)&mon, &cursor)) { + +		struct rfapi_import_table *it; +		struct prefix pfx_mac_buf; +		struct route_node *rn; + +		it = rfapiMacImportTableGet(bgp, mon->logical_net_id); +		assert(it); + +		memset((void *)&pfx_mac_buf, 0, sizeof(struct prefix)); +		pfx_mac_buf.family = AF_ETHERNET; +		pfx_mac_buf.prefixlen = 48; +		pfx_mac_buf.u.prefix_eth = mon->macaddr; + +		rn = route_node_get(it->imported_vpn[AFI_L2VPN], &pfx_mac_buf); +		assert(rn); + +		(void)rfapiMonitorEthAttachImport(it, rn, mon); +	}  } -static void -rfapiMonitorEthDetachImport ( -  struct bgp			*bgp, -  struct rfapi_monitor_eth	*mon)    /* monitor struct to detach */ +static void rfapiMonitorEthDetachImport( +	struct bgp *bgp, +	struct rfapi_monitor_eth *mon) /* monitor struct to detach */  { -  struct rfapi_import_table *it; -  struct prefix pfx_mac_buf; -  struct skiplist *sl; -  struct route_node *rn; -  int rc; - -  it = rfapiMacImportTableGet (bgp, mon->logical_net_id); -  assert (it); - -  if (RFAPI_0_ETHERADDR (&mon->macaddr)) -    { -      struct rfapi_monitor_eth *prev; -      struct rfapi_monitor_eth *this = NULL; - -      for (prev = NULL, -           this = it->eth0_queries; this; prev = this, this = this->next) -        { - -          if (this == mon) -            break; -        } -      if (this) -        { -          if (!prev) -            { -              it->eth0_queries = this->next; -            } -          else -            { -              prev->next = this->next; -            } -        } +	struct rfapi_import_table *it; +	struct prefix pfx_mac_buf; +	struct skiplist *sl; +	struct route_node *rn; +	int rc; + +	it = rfapiMacImportTableGet(bgp, mon->logical_net_id); +	assert(it); + +	if (RFAPI_0_ETHERADDR(&mon->macaddr)) { +		struct rfapi_monitor_eth *prev; +		struct rfapi_monitor_eth *this = NULL; + +		for (prev = NULL, this = it->eth0_queries; this; +		     prev = this, this = this->next) { + +			if (this == mon) +				break; +		} +		if (this) { +			if (!prev) { +				it->eth0_queries = this->next; +			} else { +				prev->next = this->next; +			} +		}  #if DEBUG_L2_EXTRA -      vnc_zlog_debug_verbose ("%s: it=%p, LNI=%d, detached eth0 mon %p", -                  __func__, it, mon->logical_net_id, mon); +		vnc_zlog_debug_verbose( +			"%s: it=%p, LNI=%d, detached eth0 mon %p", __func__, it, +			mon->logical_net_id, mon);  #endif -      return; -    } +		return; +	} -  memset ((void *) &pfx_mac_buf, 0, sizeof (struct prefix)); -  pfx_mac_buf.family = AF_ETHERNET; -  pfx_mac_buf.prefixlen = 48; -  pfx_mac_buf.u.prefix_eth = mon->macaddr; +	memset((void *)&pfx_mac_buf, 0, sizeof(struct prefix)); +	pfx_mac_buf.family = AF_ETHERNET; +	pfx_mac_buf.prefixlen = 48; +	pfx_mac_buf.u.prefix_eth = mon->macaddr; -  rn = route_node_get (it->imported_vpn[AFI_L2VPN], &pfx_mac_buf); -  assert (rn); +	rn = route_node_get(it->imported_vpn[AFI_L2VPN], &pfx_mac_buf); +	assert(rn);  #if DEBUG_L2_EXTRA -  char buf_prefix[BUFSIZ]; -  prefix2str (&rn->p, buf_prefix, BUFSIZ); +	char buf_prefix[BUFSIZ]; +	prefix2str(&rn->p, buf_prefix, BUFSIZ);  #endif -  /* -   * Get sl to detach from -   */ -  sl = RFAPI_MONITOR_ETH (rn); +	/* +	 * Get sl to detach from +	 */ +	sl = RFAPI_MONITOR_ETH(rn);  #if DEBUG_L2_EXTRA -  vnc_zlog_debug_verbose ("%s: it=%p, rn=%p, rn->lock=%d, sl=%p, pfx=%s, LNI=%d, detaching eth mon %p", -              __func__, it, rn, rn->lock, sl, buf_prefix, mon->logical_net_id, mon); +	vnc_zlog_debug_verbose( +		"%s: it=%p, rn=%p, rn->lock=%d, sl=%p, pfx=%s, LNI=%d, detaching eth mon %p", +		__func__, it, rn, rn->lock, sl, buf_prefix, mon->logical_net_id, +		mon);  #endif -  assert (sl); +	assert(sl); -  rc = skiplist_delete (sl, (void *) mon, (void *) mon); -  assert (!rc); +	rc = skiplist_delete(sl, (void *)mon, (void *)mon); +	assert(!rc); -  /* uncount eth monitor */ -  route_unlock_node(rn); +	/* uncount eth monitor */ +	route_unlock_node(rn);  } -struct route_node * -rfapiMonitorEthAdd ( -  struct bgp			*bgp, -  struct rfapi_descriptor	*rfd, -  struct ethaddr		*macaddr, -  uint32_t			logical_net_id) +struct route_node *rfapiMonitorEthAdd(struct bgp *bgp, +				      struct rfapi_descriptor *rfd, +				      struct ethaddr *macaddr, +				      uint32_t logical_net_id)  { -  int                           rc; -  struct rfapi_monitor_eth      mon_buf; -  struct rfapi_monitor_eth      *val; -  struct rfapi_import_table     *it; -  struct route_node             *rn = NULL; -  struct prefix                 pfx_mac_buf; - -  if (!rfd->mon_eth) -    { -      rfd->mon_eth = skiplist_new (0, mon_eth_cmp, NULL); -    } - -  it = rfapiMacImportTableGet (bgp, logical_net_id); -  assert (it); - -  /* -   * Get route node in import table. Here is where we attach the -   * monitor. -   * -   * Look it up now because we return it to caller regardless of -   * whether we create a new monitor or not. -   */ -  memset ((void *) &pfx_mac_buf, 0, sizeof (struct prefix)); -  pfx_mac_buf.family = AF_ETHERNET; -  pfx_mac_buf.prefixlen = 48; -  pfx_mac_buf.u.prefix_eth = *macaddr; - -  if (!RFAPI_0_ETHERADDR (macaddr)) -    { -      rn = route_node_get (it->imported_vpn[AFI_L2VPN], &pfx_mac_buf); -      assert (rn); -    } - -  memset ((void *) &mon_buf, 0, sizeof (mon_buf)); -  mon_buf.rfd = rfd; -  mon_buf.macaddr = *macaddr; -  mon_buf.logical_net_id = logical_net_id; - -  { -    char buf[BUFSIZ]; - -    vnc_zlog_debug_verbose ("%s: LNI=%d: rfd=%p, pfx=%s", -                __func__, logical_net_id, rfd, -                rfapi_ntop (pfx_mac_buf.family, pfx_mac_buf.u.val, buf, -                            BUFSIZ)); -  } - - -  /* -   * look up query -   */ -  rc = skiplist_search (rfd->mon_eth, (void *) &mon_buf, (void **) &val); -  if (!rc) -    { -      /* -       * Found monitor - we have seen this query before -       * restart timer -       */ -      vnc_zlog_debug_verbose ("%s: already present in rfd->mon_eth, not adding", -                  __func__); -      rfapiMonitorEthTimerRestart (val); -      return rn; -    } - -  /* -   * New query -   */ -  val = XCALLOC (MTYPE_RFAPI_MONITOR_ETH, sizeof (struct rfapi_monitor_eth)); -  assert (val); -  *val = mon_buf; - -  ++rfd->monitor_count; -  ++bgp->rfapi->monitor_count; - -  rc = skiplist_insert (rfd->mon_eth, val, val); +	int rc; +	struct rfapi_monitor_eth mon_buf; +	struct rfapi_monitor_eth *val; +	struct rfapi_import_table *it; +	struct route_node *rn = NULL; +	struct prefix pfx_mac_buf; + +	if (!rfd->mon_eth) { +		rfd->mon_eth = skiplist_new(0, mon_eth_cmp, NULL); +	} + +	it = rfapiMacImportTableGet(bgp, logical_net_id); +	assert(it); + +	/* +	 * Get route node in import table. Here is where we attach the +	 * monitor. +	 * +	 * Look it up now because we return it to caller regardless of +	 * whether we create a new monitor or not. +	 */ +	memset((void *)&pfx_mac_buf, 0, sizeof(struct prefix)); +	pfx_mac_buf.family = AF_ETHERNET; +	pfx_mac_buf.prefixlen = 48; +	pfx_mac_buf.u.prefix_eth = *macaddr; + +	if (!RFAPI_0_ETHERADDR(macaddr)) { +		rn = route_node_get(it->imported_vpn[AFI_L2VPN], &pfx_mac_buf); +		assert(rn); +	} + +	memset((void *)&mon_buf, 0, sizeof(mon_buf)); +	mon_buf.rfd = rfd; +	mon_buf.macaddr = *macaddr; +	mon_buf.logical_net_id = logical_net_id; + +	{ +		char buf[BUFSIZ]; + +		vnc_zlog_debug_verbose( +			"%s: LNI=%d: rfd=%p, pfx=%s", __func__, logical_net_id, +			rfd, rfapi_ntop(pfx_mac_buf.family, pfx_mac_buf.u.val, +					buf, BUFSIZ)); +	} + + +	/* +	 * look up query +	 */ +	rc = skiplist_search(rfd->mon_eth, (void *)&mon_buf, (void **)&val); +	if (!rc) { +		/* +		 * Found monitor - we have seen this query before +		 * restart timer +		 */ +		vnc_zlog_debug_verbose( +			"%s: already present in rfd->mon_eth, not adding", +			__func__); +		rfapiMonitorEthTimerRestart(val); +		return rn; +	} + +	/* +	 * New query +	 */ +	val = XCALLOC(MTYPE_RFAPI_MONITOR_ETH, +		      sizeof(struct rfapi_monitor_eth)); +	assert(val); +	*val = mon_buf; + +	++rfd->monitor_count; +	++bgp->rfapi->monitor_count; + +	rc = skiplist_insert(rfd->mon_eth, val, val);  #if DEBUG_L2_EXTRA -  vnc_zlog_debug_verbose ("%s: inserted rfd=%p mon_eth=%p, rc=%d", __func__, rfd, val, -              rc); +	vnc_zlog_debug_verbose("%s: inserted rfd=%p mon_eth=%p, rc=%d", +			       __func__, rfd, val, rc);  #endif -  /* -   * start timer -   */ -  rfapiMonitorEthTimerRestart (val); +	/* +	 * start timer +	 */ +	rfapiMonitorEthTimerRestart(val); -  if (bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE) -    { -      /* -       * callbacks turned off, so don't attach monitor to import table -       */ +	if (bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE) { +/* + * callbacks turned off, so don't attach monitor to import table + */  #if DEBUG_L2_EXTRA -      vnc_zlog_debug_verbose -        ("%s: callbacks turned off, not attaching mon_eth %p to import table", -         __func__, val); +		vnc_zlog_debug_verbose( +			"%s: callbacks turned off, not attaching mon_eth %p to import table", +			__func__, val);  #endif -      return rn; -    } +		return rn; +	} -  /* -   * attach to import table -   */ -  rfapiMonitorEthAttachImport (it, rn, val); +	/* +	 * attach to import table +	 */ +	rfapiMonitorEthAttachImport(it, rn, val); -  return rn; +	return rn;  } -void -rfapiMonitorEthDel ( -  struct bgp			*bgp, -  struct rfapi_descriptor	*rfd, -  struct ethaddr		*macaddr, -  uint32_t			logical_net_id) +void rfapiMonitorEthDel(struct bgp *bgp, struct rfapi_descriptor *rfd, +			struct ethaddr *macaddr, uint32_t logical_net_id)  { -  struct rfapi_monitor_eth *val; -  struct rfapi_monitor_eth mon_buf; -  int rc; +	struct rfapi_monitor_eth *val; +	struct rfapi_monitor_eth mon_buf; +	int rc; -  vnc_zlog_debug_verbose ("%s: entry rfd=%p", __func__, rfd); +	vnc_zlog_debug_verbose("%s: entry rfd=%p", __func__, rfd); -  assert (rfd->mon_eth); +	assert(rfd->mon_eth); -  memset ((void *) &mon_buf, 0, sizeof (mon_buf)); -  mon_buf.macaddr = *macaddr; -  mon_buf.logical_net_id = logical_net_id; +	memset((void *)&mon_buf, 0, sizeof(mon_buf)); +	mon_buf.macaddr = *macaddr; +	mon_buf.logical_net_id = logical_net_id; -  rc = skiplist_search (rfd->mon_eth, (void *) &mon_buf, (void **) &val); -  assert (!rc); +	rc = skiplist_search(rfd->mon_eth, (void *)&mon_buf, (void **)&val); +	assert(!rc); -  /* -   * remove from import table -   */ -  if (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE)) -    { -      rfapiMonitorEthDetachImport (bgp, val); -    } +	/* +	 * remove from import table +	 */ +	if (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE)) { +		rfapiMonitorEthDetachImport(bgp, val); +	} -  if (val->timer) -    { -      thread_cancel (val->timer); -      val->timer = NULL; -    } +	if (val->timer) { +		thread_cancel(val->timer); +		val->timer = NULL; +	} -  /* -   * remove from rfd list -   */ -  rc = skiplist_delete (rfd->mon_eth, val, val); -  assert (!rc); +	/* +	 * remove from rfd list +	 */ +	rc = skiplist_delete(rfd->mon_eth, val, val); +	assert(!rc);  #if DEBUG_L2_EXTRA -  vnc_zlog_debug_verbose ("%s: freeing mon_eth %p", __func__, val); +	vnc_zlog_debug_verbose("%s: freeing mon_eth %p", __func__, val);  #endif -  XFREE (MTYPE_RFAPI_MONITOR_ETH, val); +	XFREE(MTYPE_RFAPI_MONITOR_ETH, val); -  --rfd->monitor_count; -  --bgp->rfapi->monitor_count; +	--rfd->monitor_count; +	--bgp->rfapi->monitor_count;  } -void -rfapiMonitorCallbacksOff (struct bgp *bgp) +void rfapiMonitorCallbacksOff(struct bgp *bgp)  { -  struct rfapi_import_table *it; -  afi_t                     afi; -  struct route_table        *rt; -  struct route_node         *rn; -  void                      *cursor; -  int                       rc; -  struct rfapi              *h = bgp->rfapi; - -  if (bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE) -    { -      /* -       * Already off. -       */ -      return; -    } -  bgp->rfapi_cfg->flags |= BGP_VNC_CONFIG_CALLBACK_DISABLE; +	struct rfapi_import_table *it; +	afi_t afi; +	struct route_table *rt; +	struct route_node *rn; +	void *cursor; +	int rc; +	struct rfapi *h = bgp->rfapi; + +	if (bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE) { +		/* +		 * Already off. +		 */ +		return; +	} +	bgp->rfapi_cfg->flags |= BGP_VNC_CONFIG_CALLBACK_DISABLE;  #if DEBUG_L2_EXTRA -  vnc_zlog_debug_verbose ("%s: turned off callbacks", __func__); +	vnc_zlog_debug_verbose("%s: turned off callbacks", __func__);  #endif -  if (h == NULL) -    return; -  /* -   * detach monitors from import VPN tables. The monitors -   * will still be linked in per-nve monitor lists. -   */ -  for (it = h->imports; it; it = it->next) -    { -      for (afi = AFI_IP; afi < AFI_MAX; ++afi) -        { - -          struct rfapi_monitor_vpn *m; -          struct rfapi_monitor_vpn *next; - -          rt = it->imported_vpn[afi]; - -          for (rn = route_top (rt); rn; rn = route_next (rn)) -            { -              m = RFAPI_MONITOR_VPN (rn); -              if (RFAPI_MONITOR_VPN (rn)) -                RFAPI_MONITOR_VPN_W_ALLOC (rn) = NULL; -              for (; m; m = next) -                { -                  next = m->next; -                  m->next = NULL;       /* gratuitous safeness */ -                  m->node = NULL; -                  route_unlock_node (rn);       /* uncount */ -                } -            } - -          for (m = it->vpn0_queries[afi]; m; m = next) -            { -              next = m->next; -              m->next = NULL;   /* gratuitous safeness */ -              m->node = NULL; -            } -          it->vpn0_queries[afi] = NULL; /* detach first monitor */ -        } -    } - -  /* -   * detach monitors from import Eth tables. The monitors -   * will still be linked in per-nve monitor lists. -   */ - -  /* -   * Loop over ethernet import tables -   */ -  for (cursor = NULL, -       rc = skiplist_next (h->import_mac, NULL, (void **) &it, &cursor); -       !rc; rc = skiplist_next (h->import_mac, NULL, (void **) &it, &cursor)) -    { -      struct rfapi_monitor_eth *e; -      struct rfapi_monitor_eth *enext; - -      /* -       * The actual route table -       */ -      rt = it->imported_vpn[AFI_L2VPN]; - -      /*  -       * Find non-0 monitors (i.e., actual addresses, not FTD monitors) -       */ -      for (rn = route_top (rt); rn; rn = route_next (rn)) -        { -	  struct skiplist *sl; - -	  sl = RFAPI_MONITOR_ETH (rn); -	  while (!skiplist_delete_first(sl)) -	    { -              route_unlock_node (rn);   /* uncount monitor */ -	    } -        } - -      /* -       * Find 0-monitors (FTD queries) -       */ -      for (e = it->eth0_queries; e; e = enext) -        { +	if (h == NULL) +		return; +	/* +	 * detach monitors from import VPN tables. The monitors +	 * will still be linked in per-nve monitor lists. +	 */ +	for (it = h->imports; it; it = it->next) { +		for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + +			struct rfapi_monitor_vpn *m; +			struct rfapi_monitor_vpn *next; + +			rt = it->imported_vpn[afi]; + +			for (rn = route_top(rt); rn; rn = route_next(rn)) { +				m = RFAPI_MONITOR_VPN(rn); +				if (RFAPI_MONITOR_VPN(rn)) +					RFAPI_MONITOR_VPN_W_ALLOC(rn) = NULL; +				for (; m; m = next) { +					next = m->next; +					m->next = +						NULL; /* gratuitous safeness */ +					m->node = NULL; +					route_unlock_node(rn); /* uncount */ +				} +			} + +			for (m = it->vpn0_queries[afi]; m; m = next) { +				next = m->next; +				m->next = NULL; /* gratuitous safeness */ +				m->node = NULL; +			} +			it->vpn0_queries[afi] = NULL; /* detach first monitor */ +		} +	} + +	/* +	 * detach monitors from import Eth tables. The monitors +	 * will still be linked in per-nve monitor lists. +	 */ + +	/* +	 * Loop over ethernet import tables +	 */ +	for (cursor = NULL, +	    rc = skiplist_next(h->import_mac, NULL, (void **)&it, &cursor); +	     !rc; +	     rc = skiplist_next(h->import_mac, NULL, (void **)&it, &cursor)) { +		struct rfapi_monitor_eth *e; +		struct rfapi_monitor_eth *enext; + +		/* +		 * The actual route table +		 */ +		rt = it->imported_vpn[AFI_L2VPN]; + +		/* +		 * Find non-0 monitors (i.e., actual addresses, not FTD +		 * monitors) +		 */ +		for (rn = route_top(rt); rn; rn = route_next(rn)) { +			struct skiplist *sl; + +			sl = RFAPI_MONITOR_ETH(rn); +			while (!skiplist_delete_first(sl)) { +				route_unlock_node(rn); /* uncount monitor */ +			} +		} + +		/* +		 * Find 0-monitors (FTD queries) +		 */ +		for (e = it->eth0_queries; e; e = enext) {  #if DEBUG_L2_EXTRA -          vnc_zlog_debug_verbose ("%s: detaching eth0 mon %p", __func__, e); +			vnc_zlog_debug_verbose("%s: detaching eth0 mon %p", +					       __func__, e);  #endif -          enext = e->next; -          e->next = NULL;       /* gratuitous safeness */ -        } -      it->eth0_queries = NULL;  /* detach first monitor */ -    } +			enext = e->next; +			e->next = NULL; /* gratuitous safeness */ +		} +		it->eth0_queries = NULL; /* detach first monitor */ +	}  } -void -rfapiMonitorCallbacksOn (struct bgp *bgp) +void rfapiMonitorCallbacksOn(struct bgp *bgp)  { -  struct listnode *hnode; -  struct rfapi_descriptor *rfd; - -  if (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE)) -    { -      /* -       * Already on. It's important that we don't try to reattach -       * monitors that are already attached because, in the interest -       * of performance, there is no checking at the lower level  -       * whether a monitor is already attached. It leads to -       * corrupted chains (e.g., looped pointers) -       */ -      return; -    } -  bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_CALLBACK_DISABLE; +	struct listnode *hnode; +	struct rfapi_descriptor *rfd; + +	if (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE)) { +		/* +		 * Already on. It's important that we don't try to reattach +		 * monitors that are already attached because, in the interest +		 * of performance, there is no checking at the lower level +		 * whether a monitor is already attached. It leads to +		 * corrupted chains (e.g., looped pointers) +		 */ +		return; +	} +	bgp->rfapi_cfg->flags &= ~BGP_VNC_CONFIG_CALLBACK_DISABLE;  #if DEBUG_L2_EXTRA -  vnc_zlog_debug_verbose ("%s: turned on callbacks", __func__); +	vnc_zlog_debug_verbose("%s: turned on callbacks", __func__);  #endif -  if (bgp->rfapi == NULL) -    return; - -  /* -   * reattach monitors -   */ -  for (ALL_LIST_ELEMENTS_RO (&bgp->rfapi->descriptors, hnode, rfd)) -    { - -      rfapiMonitorAttachImportHd (rfd); -      rfapiMonitorEthAttachImportHd (bgp, rfd); -    } +	if (bgp->rfapi == NULL) +		return; + +	/* +	 * reattach monitors +	 */ +	for (ALL_LIST_ELEMENTS_RO(&bgp->rfapi->descriptors, hnode, rfd)) { + +		rfapiMonitorAttachImportHd(rfd); +		rfapiMonitorEthAttachImportHd(bgp, rfd); +	}  } diff --git a/bgpd/rfapi/rfapi_monitor.h b/bgpd/rfapi/rfapi_monitor.h index 667d61ec1d..edc9744cdb 100644 --- a/bgpd/rfapi/rfapi_monitor.h +++ b/bgpd/rfapi/rfapi_monitor.h @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2009-2016, LabN Consulting, L.L.C.   * @@ -29,35 +29,32 @@   * These get attached to the nodes in an import table (using "aggregate" ptr)   * to indicate which nves are interested in a prefix/target   */ -struct rfapi_monitor_vpn -{ -  struct rfapi_monitor_vpn	*next;	/* chain from struct route_node */ -  struct rfapi_descriptor	*rfd;	/* which NVE requested the route */ -  struct prefix			p;	/* constant: pfx in original request */ -  struct route_node		*node;	/* node we're currently attached to */ -  uint32_t			flags; +struct rfapi_monitor_vpn { +	struct rfapi_monitor_vpn *next; /* chain from struct route_node */ +	struct rfapi_descriptor *rfd;   /* which NVE requested the route */ +	struct prefix p;		/* constant: pfx in original request */ +	struct route_node *node;	/* node we're currently attached to */ +	uint32_t flags;  #define RFAPI_MON_FLAG_NEEDCALLBACK	0x00000001      /* deferred callback */ -  //int				dcount;	/* debugging counter */ -  struct thread		 	*timer; +	// int				dcount;	/* debugging counter */ +	struct thread *timer;  }; -struct rfapi_monitor_encap -{ -  struct rfapi_monitor_encap	*next; -  struct rfapi_monitor_encap	*prev; -  struct route_node		*node;	/* VPN node */ -  struct bgp_info		*bi;	/* VPN bi */ -  struct route_node		*rn;	/* parent node */ +struct rfapi_monitor_encap { +	struct rfapi_monitor_encap *next; +	struct rfapi_monitor_encap *prev; +	struct route_node *node; /* VPN node */ +	struct bgp_info *bi;     /* VPN bi */ +	struct route_node *rn;   /* parent node */  }; -struct rfapi_monitor_eth -{ -  struct rfapi_monitor_eth	*next;	/* for use in vpn0_queries list */ -  struct rfapi_descriptor	*rfd;	/* which NVE requested the route */ -  struct ethaddr		macaddr; -  uint32_t			logical_net_id; -  struct thread		*timer; +struct rfapi_monitor_eth { +	struct rfapi_monitor_eth *next; /* for use in vpn0_queries list */ +	struct rfapi_descriptor *rfd;   /* which NVE requested the route */ +	struct ethaddr macaddr; +	uint32_t logical_net_id; +	struct thread *timer;  };  /* @@ -75,142 +72,119 @@ struct rfapi_monitor_eth   *	- one lock per chained struct rfapi_monitor_encap   *   */ -struct rfapi_it_extra -{ -  union -  { -    struct -    { -      struct rfapi_monitor_vpn	*v; -      struct skiplist		*idx_rd;  /* RD index */ -      struct skiplist		*mon_eth; /* ether queries */ -      struct -      { -        /* routes with UN addrs, either cached encap or Encap TLV */ -        int			valid_interior_count; - -        /* unicast exterior routes, key=bi, val=allocated prefix */ -        struct skiplist		*source; -      } e; -    } vpn; -    struct -    { -      struct rfapi_monitor_encap *e; -    } encap; -  } u; +struct rfapi_it_extra { +	union { +		struct { +			struct rfapi_monitor_vpn *v; +			struct skiplist *idx_rd;  /* RD index */ +			struct skiplist *mon_eth; /* ether queries */ +			struct { +				/* routes with UN addrs, either cached encap or +				 * Encap TLV */ +				int valid_interior_count; + +				/* unicast exterior routes, key=bi, +				 * val=allocated prefix */ +				struct skiplist *source; +			} e; +		} vpn; +		struct { +			struct rfapi_monitor_encap *e; +		} encap; +	} u;  }; -#define RFAPI_IT_EXTRA_GET(rn) ((struct rfapi_it_extra *)(	\ -    (rn)->aggregate? (rn)->aggregate:				\ -	(route_lock_node(rn), (rn)->aggregate =			\ -	XCALLOC(MTYPE_RFAPI_IT_EXTRA,sizeof(struct rfapi_it_extra))))) +#define RFAPI_IT_EXTRA_GET(rn)                                                 \ +	((struct rfapi_it_extra                                                \ +		  *)((rn)->aggregate                                           \ +			     ? (rn)->aggregate                                 \ +			     : (route_lock_node(rn),                           \ +				(rn)->aggregate = XCALLOC(                     \ +					MTYPE_RFAPI_IT_EXTRA,                  \ +					sizeof(struct rfapi_it_extra))))) -#define RFAPI_RDINDEX(rn)					\ -    ((rn)->aggregate ? RFAPI_IT_EXTRA_GET(rn)->u.vpn.idx_rd : NULL) +#define RFAPI_RDINDEX(rn)                                                      \ +	((rn)->aggregate ? RFAPI_IT_EXTRA_GET(rn)->u.vpn.idx_rd : NULL)  #define RFAPI_RDINDEX_W_ALLOC(rn) (RFAPI_IT_EXTRA_GET(rn)->u.vpn.idx_rd) -#define RFAPI_MONITOR_ETH(rn)					\ -    ((rn)->aggregate ? RFAPI_IT_EXTRA_GET(rn)->u.vpn.mon_eth : NULL) +#define RFAPI_MONITOR_ETH(rn)                                                  \ +	((rn)->aggregate ? RFAPI_IT_EXTRA_GET(rn)->u.vpn.mon_eth : NULL)  #define RFAPI_MONITOR_ETH_W_ALLOC(rn) (RFAPI_IT_EXTRA_GET(rn)->u.vpn.mon_eth) -#define RFAPI_MONITOR_VPN(rn)                                   \ -    ((rn)->aggregate ? RFAPI_IT_EXTRA_GET(rn)->u.vpn.v : NULL) +#define RFAPI_MONITOR_VPN(rn)                                                  \ +	((rn)->aggregate ? RFAPI_IT_EXTRA_GET(rn)->u.vpn.v : NULL)  #define RFAPI_MONITOR_VPN_W_ALLOC(rn) (RFAPI_IT_EXTRA_GET(rn)->u.vpn.v) -#define RFAPI_MONITOR_ENCAP(rn)                                 \ -    ((rn)->aggregate ? RFAPI_IT_EXTRA_GET(rn)->u.encap.e : NULL) +#define RFAPI_MONITOR_ENCAP(rn)                                                \ +	((rn)->aggregate ? RFAPI_IT_EXTRA_GET(rn)->u.encap.e : NULL)  #define RFAPI_MONITOR_ENCAP_W_ALLOC(rn) (RFAPI_IT_EXTRA_GET(rn)->u.encap.e)  #define RFAPI_MONITOR_EXTERIOR(rn) (&(RFAPI_IT_EXTRA_GET(rn)->u.vpn.e)) -#define RFAPI_HAS_MONITOR_EXTERIOR(rn) (rn && rn->aggregate &&		\ -    ((struct rfapi_it_extra *)(rn->aggregate))->u.vpn.e.source &&	\ -    !skiplist_first(((struct rfapi_it_extra *)(rn->aggregate))->	\ -    u.vpn.e.source, NULL, NULL)) +#define RFAPI_HAS_MONITOR_EXTERIOR(rn)                                         \ +	(rn && rn->aggregate                                                   \ +	 && ((struct rfapi_it_extra *)(rn->aggregate))->u.vpn.e.source         \ +	 && !skiplist_first(((struct rfapi_it_extra *)(rn->aggregate))         \ +				    ->u.vpn.e.source,                          \ +			    NULL, NULL)) -extern void -rfapiMonitorLoopCheck (struct rfapi_monitor_vpn *mchain); +extern void rfapiMonitorLoopCheck(struct rfapi_monitor_vpn *mchain); -extern void -rfapiMonitorCleanCheck (struct bgp *bgp); +extern void rfapiMonitorCleanCheck(struct bgp *bgp); -extern void -rfapiMonitorCheckAttachAllowed (void); +extern void rfapiMonitorCheckAttachAllowed(void); -extern void -rfapiMonitorExtraFlush (safi_t safi, struct route_node *rn); +extern void rfapiMonitorExtraFlush(safi_t safi, struct route_node *rn);  extern struct route_node * -rfapiMonitorGetAttachNode (struct rfapi_descriptor *rfd, struct prefix *p); +rfapiMonitorGetAttachNode(struct rfapi_descriptor *rfd, struct prefix *p); -extern void -rfapiMonitorAttachImportHd (struct rfapi_descriptor *rfd); +extern void rfapiMonitorAttachImportHd(struct rfapi_descriptor *rfd); -extern struct route_node * -rfapiMonitorAdd ( -  struct bgp			*bgp, -  struct rfapi_descriptor	*rfd, -  struct prefix			*p); +extern struct route_node *rfapiMonitorAdd(struct bgp *bgp, +					  struct rfapi_descriptor *rfd, +					  struct prefix *p); -extern void -rfapiMonitorDetachImportHd (struct rfapi_descriptor *rfd); +extern void rfapiMonitorDetachImportHd(struct rfapi_descriptor *rfd); -extern void -rfapiMonitorDel ( -  struct bgp			*bgp, -  struct rfapi_descriptor	*rfd, -  struct prefix			*p); +extern void rfapiMonitorDel(struct bgp *bgp, struct rfapi_descriptor *rfd, +			    struct prefix *p); -extern int -rfapiMonitorDelHd (struct rfapi_descriptor *rfd); +extern int rfapiMonitorDelHd(struct rfapi_descriptor *rfd); -extern void -rfapiMonitorCallbacksOff (struct bgp *bgp); +extern void rfapiMonitorCallbacksOff(struct bgp *bgp); -extern void -rfapiMonitorCallbacksOn (struct bgp *bgp); +extern void rfapiMonitorCallbacksOn(struct bgp *bgp); -extern void -rfapiMonitorResponseRemovalOff (struct bgp *bgp); +extern void rfapiMonitorResponseRemovalOff(struct bgp *bgp); -extern void -rfapiMonitorResponseRemovalOn (struct bgp *bgp); +extern void rfapiMonitorResponseRemovalOn(struct bgp *bgp); -extern void -rfapiMonitorExtraPrune (safi_t safi, struct route_node *rn); +extern void rfapiMonitorExtraPrune(safi_t safi, struct route_node *rn); -extern void -rfapiMonitorTimersRestart (struct rfapi_descriptor *rfd, struct prefix *p); +extern void rfapiMonitorTimersRestart(struct rfapi_descriptor *rfd, +				      struct prefix *p); -extern void -rfapiMonitorItNodeChanged ( -  struct rfapi_import_table	*import_table, -  struct route_node		*it_node, -  struct rfapi_monitor_vpn	*monitor_list); +extern void rfapiMonitorItNodeChanged(struct rfapi_import_table *import_table, +				      struct route_node *it_node, +				      struct rfapi_monitor_vpn *monitor_list); -extern void -rfapiMonitorMovedUp ( -  struct rfapi_import_table	*import_table, -  struct route_node		*old_node, -  struct route_node		*new_node, -  struct rfapi_monitor_vpn	*monitor_list); +extern void rfapiMonitorMovedUp(struct rfapi_import_table *import_table, +				struct route_node *old_node, +				struct route_node *new_node, +				struct rfapi_monitor_vpn *monitor_list); -extern struct route_node * -rfapiMonitorEthAdd ( -  struct bgp			*bgp, -  struct rfapi_descriptor	*rfd, -  struct ethaddr		*macaddr, -  uint32_t			logical_net_id); - -extern void -rfapiMonitorEthDel ( -  struct bgp			*bgp, -  struct rfapi_descriptor	*rfd, -  struct ethaddr		*macaddr, -  uint32_t			logical_net_id); +extern struct route_node *rfapiMonitorEthAdd(struct bgp *bgp, +					     struct rfapi_descriptor *rfd, +					     struct ethaddr *macaddr, +					     uint32_t logical_net_id); + +extern void rfapiMonitorEthDel(struct bgp *bgp, struct rfapi_descriptor *rfd, +			       struct ethaddr *macaddr, +			       uint32_t logical_net_id);  #endif /* QUAGGA_HGP_RFAPI_MONITOR_H */ diff --git a/bgpd/rfapi/rfapi_nve_addr.c b/bgpd/rfapi/rfapi_nve_addr.c index f80455bbed..0fb887912c 100644 --- a/bgpd/rfapi/rfapi_nve_addr.c +++ b/bgpd/rfapi/rfapi_nve_addr.c @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2009-2016, LabN Consulting, L.L.C.   * @@ -41,135 +41,118 @@  #define DEBUG_NVE_ADDR 0 -void rfapiNveAddr2Str (struct rfapi_nve_addr *, char *, int); +void rfapiNveAddr2Str(struct rfapi_nve_addr *, char *, int);  #if DEBUG_NVE_ADDR -static void -logdifferent (const char *tag, -              struct rfapi_nve_addr *a, struct rfapi_nve_addr *b) +static void logdifferent(const char *tag, struct rfapi_nve_addr *a, +			 struct rfapi_nve_addr *b)  { -  char a_str[BUFSIZ]; -  char b_str[BUFSIZ]; +	char a_str[BUFSIZ]; +	char b_str[BUFSIZ]; -  rfapiNveAddr2Str (a, a_str, BUFSIZ); -  rfapiNveAddr2Str (b, b_str, BUFSIZ); -  vnc_zlog_debug_verbose ("%s: [%s] [%s]", tag, a_str, b_str); +	rfapiNveAddr2Str(a, a_str, BUFSIZ); +	rfapiNveAddr2Str(b, b_str, BUFSIZ); +	vnc_zlog_debug_verbose("%s: [%s] [%s]", tag, a_str, b_str);  }  #endif -int -rfapi_nve_addr_cmp (void *k1, void *k2) +int rfapi_nve_addr_cmp(void *k1, void *k2)  { -  struct rfapi_nve_addr *a = (struct rfapi_nve_addr *) k1; -  struct rfapi_nve_addr *b = (struct rfapi_nve_addr *) k2; -  int ret = 0; +	struct rfapi_nve_addr *a = (struct rfapi_nve_addr *)k1; +	struct rfapi_nve_addr *b = (struct rfapi_nve_addr *)k2; +	int ret = 0; -  if (!a || !b) -    { +	if (!a || !b) {  #if DEBUG_NVE_ADDR -      vnc_zlog_debug_verbose ("%s: missing address a=%p b=%p", __func__, a, b); +		vnc_zlog_debug_verbose("%s: missing address a=%p b=%p", +				       __func__, a, b);  #endif -      return (a - b); -    } -  if (a->un.addr_family != b->un.addr_family) -    { +		return (a - b); +	} +	if (a->un.addr_family != b->un.addr_family) {  #if DEBUG_NVE_ADDR -      vnc_zlog_debug_verbose ("diff: UN addr fam a->un.af=%d, b->un.af=%d", -                  a->un.addr_family, b->un.addr_family); +		vnc_zlog_debug_verbose( +			"diff: UN addr fam a->un.af=%d, b->un.af=%d", +			a->un.addr_family, b->un.addr_family);  #endif -      return (a->un.addr_family - b->un.addr_family); -    } -  if (a->un.addr_family == AF_INET) -    { -      ret = IPV4_ADDR_CMP (&a->un.addr.v4, &b->un.addr.v4); -      if (ret != 0) -        { +		return (a->un.addr_family - b->un.addr_family); +	} +	if (a->un.addr_family == AF_INET) { +		ret = IPV4_ADDR_CMP(&a->un.addr.v4, &b->un.addr.v4); +		if (ret != 0) {  #if DEBUG_NVE_ADDR -          logdifferent ("diff: UN addr", a, b); +			logdifferent("diff: UN addr", a, b);  #endif -          return ret; -        } -    } -  else if (a->un.addr_family == AF_INET6) -    { -      ret = IPV6_ADDR_CMP (&a->un.addr.v6, &b->un.addr.v6); -      if (ret == 0) -        { +			return ret; +		} +	} else if (a->un.addr_family == AF_INET6) { +		ret = IPV6_ADDR_CMP(&a->un.addr.v6, &b->un.addr.v6); +		if (ret == 0) {  #if DEBUG_NVE_ADDR -          logdifferent ("diff: UN addr", a, b); +			logdifferent("diff: UN addr", a, b);  #endif -          return ret; -        } -    } -  else -    { -      assert (0); -    } -  if (a->vn.addr_family != b->vn.addr_family) -    { +			return ret; +		} +	} else { +		assert(0); +	} +	if (a->vn.addr_family != b->vn.addr_family) {  #if DEBUG_NVE_ADDR -      vnc_zlog_debug_verbose ("diff: pT addr fam a->vn.af=%d, b->vn.af=%d", -                  a->vn.addr_family, b->vn.addr_family); +		vnc_zlog_debug_verbose( +			"diff: pT addr fam a->vn.af=%d, b->vn.af=%d", +			a->vn.addr_family, b->vn.addr_family);  #endif -      return (a->vn.addr_family - b->vn.addr_family); -    } -  if (a->vn.addr_family == AF_INET) -    { -      ret = IPV4_ADDR_CMP (&a->vn.addr.v4, &b->vn.addr.v4); -      if (ret != 0) -        { +		return (a->vn.addr_family - b->vn.addr_family); +	} +	if (a->vn.addr_family == AF_INET) { +		ret = IPV4_ADDR_CMP(&a->vn.addr.v4, &b->vn.addr.v4); +		if (ret != 0) {  #if DEBUG_NVE_ADDR -          logdifferent ("diff: VN addr", a, b); +			logdifferent("diff: VN addr", a, b);  #endif -          return ret; -        } -    } -  else if (a->vn.addr_family == AF_INET6) -    { -      ret = IPV6_ADDR_CMP (&a->vn.addr.v6, &b->vn.addr.v6); -      if (ret == 0) -        { +			return ret; +		} +	} else if (a->vn.addr_family == AF_INET6) { +		ret = IPV6_ADDR_CMP(&a->vn.addr.v6, &b->vn.addr.v6); +		if (ret == 0) {  #if DEBUG_NVE_ADDR -          logdifferent ("diff: VN addr", a, b); +			logdifferent("diff: VN addr", a, b);  #endif -          return ret; -        } -    } -  else -    { -      assert (0); -    } -  return 0; +			return ret; +		} +	} else { +		assert(0); +	} +	return 0;  } -void -rfapiNveAddr2Str (struct rfapi_nve_addr *na, char *buf, int bufsize) +void rfapiNveAddr2Str(struct rfapi_nve_addr *na, char *buf, int bufsize)  { -  char *p = buf; -  int r; +	char *p = buf; +	int r;  #define REMAIN (bufsize - (p-buf))  #define INCP {p += (r > REMAIN)? REMAIN: r;} -  if (bufsize < 1) -    return; +	if (bufsize < 1) +		return; -  r = snprintf (p, REMAIN, "VN="); -  INCP; +	r = snprintf(p, REMAIN, "VN="); +	INCP; -  if (!rfapiRfapiIpAddr2Str (&na->vn, p, REMAIN)) -    goto done; +	if (!rfapiRfapiIpAddr2Str(&na->vn, p, REMAIN)) +		goto done; -  buf[bufsize - 1] = 0; -  p = buf + strlen (buf); +	buf[bufsize - 1] = 0; +	p = buf + strlen(buf); -  r = snprintf (p, REMAIN, ", UN="); -  INCP; +	r = snprintf(p, REMAIN, ", UN="); +	INCP; -  rfapiRfapiIpAddr2Str (&na->un, p, REMAIN); +	rfapiRfapiIpAddr2Str(&na->un, p, REMAIN);  done: -  buf[bufsize - 1] = 0; +	buf[bufsize - 1] = 0;  } diff --git a/bgpd/rfapi/rfapi_nve_addr.h b/bgpd/rfapi/rfapi_nve_addr.h index f2159d1063..2d54d4a3cc 100644 --- a/bgpd/rfapi/rfapi_nve_addr.h +++ b/bgpd/rfapi/rfapi_nve_addr.h @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2009-2016, LabN Consulting, L.L.C.   * @@ -23,20 +23,16 @@  #include "rfapi.h" -struct rfapi_nve_addr -{ -  struct rfapi_ip_addr vn; -  struct rfapi_ip_addr un; -  void *info; +struct rfapi_nve_addr { +	struct rfapi_ip_addr vn; +	struct rfapi_ip_addr un; +	void *info;  }; -extern int -rfapi_nve_addr_cmp (void *k1, void *k2); - -extern void -rfapiNveAddr2Str (struct rfapi_nve_addr *na, char *buf, int bufsize); +extern int rfapi_nve_addr_cmp(void *k1, void *k2); +extern void rfapiNveAddr2Str(struct rfapi_nve_addr *na, char *buf, int bufsize);  #endif /* _QUAGGA_BGP_RFAPI_NVE_ADDR_H */ diff --git a/bgpd/rfapi/rfapi_private.h b/bgpd/rfapi/rfapi_private.h index 5a6936fcce..e7a3e5aae3 100644 --- a/bgpd/rfapi/rfapi_private.h +++ b/bgpd/rfapi/rfapi_private.h @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2009-2016, LabN Consulting, L.L.C.   * @@ -18,7 +18,7 @@   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA   */ -/*  +/*   * Internal definitions for RFAPI. Not for use by other code   */ @@ -40,96 +40,94 @@   * 1. each is referenced in by_lifetime   * 2. each is referenced by exactly one of: ipN_by_prefix, ip0_by_ether   */ -struct rfapi_advertised_prefixes -{ -  struct skiplist *ipN_by_prefix; /* all except 0/32, 0/128 */ -  struct skiplist *ip0_by_ether;  /* ip prefix 0/32, 0/128 */ -  struct skiplist *by_lifetime;   /* all */ +struct rfapi_advertised_prefixes { +	struct skiplist *ipN_by_prefix; /* all except 0/32, 0/128 */ +	struct skiplist *ip0_by_ether;  /* ip prefix 0/32, 0/128 */ +	struct skiplist *by_lifetime;   /* all */  }; -struct rfapi_descriptor -{ -  struct route_node		*un_node;	/* backref to un table */ - -  struct rfapi_descriptor	*next;		/* next vn_addr */ - -  /* supplied by client */ -  struct bgp			*bgp;		/* from rfp_start_val */ -  struct rfapi_ip_addr		vn_addr; -  struct rfapi_ip_addr		un_addr; -  rfapi_response_cb_t		*response_cb;	/* override per-bgp response_cb */ -  void				*cookie;	/* for callbacks */ -  struct rfapi_tunneltype_option default_tunneltype_option; - -  /* supplied by matched configuration */ -  struct prefix_rd		rd; -  struct ecommunity		*rt_export_list; -  uint32_t			response_lifetime; - -  /* list of prefixes currently being advertised by this nve */ -  struct rfapi_advertised_prefixes	advertised; - -  time_t			open_time; - -  uint32_t			max_prefix_lifetime; -  uint32_t			min_prefix_lifetime; - -  /* reference to this nve's import table */ -  struct rfapi_import_table	*import_table; - -  uint32_t			monitor_count; -  struct route_table		*mon;		/* rfapi_monitors */ -  struct skiplist		*mon_eth;	/* ethernet monitors */ - -  /* -   * rib            RIB as seen by NVE -   * rib_pending    RIB containing nodes with updated info chains -   * rsp_times      last time we sent response containing pfx -   */ -  uint32_t			rib_prefix_count;	/* pfxes with routes */ -  struct route_table		*rib[AFI_MAX]; -  struct route_table		*rib_pending[AFI_MAX]; -  struct work_queue		*updated_responses_queue; -  struct route_table		*rsp_times[AFI_MAX]; - -  uint32_t			rsp_counter;		/* dedup initial rsp */ -  time_t			rsp_time;		/* dedup initial rsp */ -  time_t			ftd_last_allowed_time;	/* FTD filter */ - -  unsigned int			stat_count_nh_reachable; -  unsigned int			stat_count_nh_removal; - -  /* -   * points to the original nve group structure that matched -   * when this nve_descriptor was created. We use this pointer -   * in rfapi_close() to find the nve group structure and -   * delete its reference back to us. -   * -   * If the nve group structure is deleted (via configuration -   * change) while this nve_descriptor exists, this rfg pointer -   * will be set to NULL. -   */ -  struct rfapi_nve_group_cfg	*rfg; - -  /* -   * This ~7kB structure is here to permit multiple routes for -   * a prefix to be injected to BGP. There are at least two -   * situations where such conditions obtain: -   * -   * When an VNC route is exported to BGP on behalf of the set of -   * NVEs that belong to the export NVE group, it is replicated -   * so that there is one route per NVE (and the route's nexthop -   * is the NVE's VN address). -   * -   * Each of these routes being injected to BGP must have a distinct -   * peer pointer (otherwise, if they have the same peer pointer, each -   * route will be considered an implicit waithdraw of the previous -   * route injected from that peer, and the new route will replace -   * rather than augment the old one(s)). -   */ -  struct peer			*peer; - -  uint32_t			flags; +struct rfapi_descriptor { +	struct route_node *un_node; /* backref to un table */ + +	struct rfapi_descriptor *next; /* next vn_addr */ + +	/* supplied by client */ +	struct bgp *bgp; /* from rfp_start_val */ +	struct rfapi_ip_addr vn_addr; +	struct rfapi_ip_addr un_addr; +	rfapi_response_cb_t *response_cb; /* override per-bgp response_cb */ +	void *cookie;			  /* for callbacks */ +	struct rfapi_tunneltype_option default_tunneltype_option; + +	/* supplied by matched configuration */ +	struct prefix_rd rd; +	struct ecommunity *rt_export_list; +	uint32_t response_lifetime; + +	/* list of prefixes currently being advertised by this nve */ +	struct rfapi_advertised_prefixes advertised; + +	time_t open_time; + +	uint32_t max_prefix_lifetime; +	uint32_t min_prefix_lifetime; + +	/* reference to this nve's import table */ +	struct rfapi_import_table *import_table; + +	uint32_t monitor_count; +	struct route_table *mon;  /* rfapi_monitors */ +	struct skiplist *mon_eth; /* ethernet monitors */ + +	/* +	 * rib            RIB as seen by NVE +	 * rib_pending    RIB containing nodes with updated info chains +	 * rsp_times      last time we sent response containing pfx +	 */ +	uint32_t rib_prefix_count; /* pfxes with routes */ +	struct route_table *rib[AFI_MAX]; +	struct route_table *rib_pending[AFI_MAX]; +	struct work_queue *updated_responses_queue; +	struct route_table *rsp_times[AFI_MAX]; + +	uint32_t rsp_counter;	 /* dedup initial rsp */ +	time_t rsp_time;	      /* dedup initial rsp */ +	time_t ftd_last_allowed_time; /* FTD filter */ + +	unsigned int stat_count_nh_reachable; +	unsigned int stat_count_nh_removal; + +	/* +	 * points to the original nve group structure that matched +	 * when this nve_descriptor was created. We use this pointer +	 * in rfapi_close() to find the nve group structure and +	 * delete its reference back to us. +	 * +	 * If the nve group structure is deleted (via configuration +	 * change) while this nve_descriptor exists, this rfg pointer +	 * will be set to NULL. +	 */ +	struct rfapi_nve_group_cfg *rfg; + +	/* +	 * This ~7kB structure is here to permit multiple routes for +	 * a prefix to be injected to BGP. There are at least two +	 * situations where such conditions obtain: +	 * +	 * When an VNC route is exported to BGP on behalf of the set of +	 * NVEs that belong to the export NVE group, it is replicated +	 * so that there is one route per NVE (and the route's nexthop +	 * is the NVE's VN address). +	 * +	 * Each of these routes being injected to BGP must have a distinct +	 * peer pointer (otherwise, if they have the same peer pointer, each +	 * route will be considered an implicit waithdraw of the previous +	 * route injected from that peer, and the new route will replace +	 * rather than augment the old one(s)). +	 */ +	struct peer *peer; + +	uint32_t flags;  #define RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_IP		0x00000001  #define RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_IP6	0x00000002  #define RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_L2VPN	0x00000004 @@ -138,30 +136,32 @@ struct rfapi_descriptor  #define RFAPI_HD_FLAG_IS_VRF             		0x00000012  }; -#define RFAPI_QUEUED_FLAG(afi) (					\ -    ((afi) == AFI_IP)? RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_IP: 	\ -    (((afi) == AFI_IP6)? RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_IP6:	\ -    (((afi) == AFI_L2VPN)? RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_L2VPN:	\ -    (assert(0), 0) ))) +#define RFAPI_QUEUED_FLAG(afi)                                                      \ +	(((afi) == AFI_IP)                                                          \ +		 ? RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_IP                          \ +		 : (((afi) == AFI_IP6)                                              \ +			    ? RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_IP6              \ +			    : (((afi) == AFI_L2VPN)                                 \ +				       ? RFAPI_HD_FLAG_CALLBACK_SCHEDULED_AFI_L2VPN \ +				       : (assert(0), 0)))) -struct rfapi_global_stats -{ -  time_t		last_reset; -  unsigned int		max_descriptors; +struct rfapi_global_stats { +	time_t last_reset; +	unsigned int max_descriptors; -  unsigned int		count_unknown_nves; +	unsigned int count_unknown_nves; -  unsigned int		count_queries; -  unsigned int		count_queries_failed; +	unsigned int count_queries; +	unsigned int count_queries_failed; -  unsigned int		max_responses;   /* semantics? */ +	unsigned int max_responses; /* semantics? */ -  unsigned int		count_registrations; -  unsigned int		count_registrations_failed; +	unsigned int count_registrations; +	unsigned int count_registrations_failed; -  unsigned int		count_updated_response_updates; -  unsigned int		count_updated_response_deletes; +	unsigned int count_updated_response_updates; +	unsigned int count_updated_response_deletes;  };  /* @@ -170,220 +170,187 @@ struct rfapi_global_stats   * Radix tree is indexed by un address; follow chain and   * check vn address to get exact match.   */ -struct rfapi -{ -  struct route_table		un[AFI_MAX]; -  struct rfapi_import_table	*imports;	/* IPv4, IPv6 */ -  struct list			descriptors;/* debug & resolve-nve imports */ - -  struct rfapi_global_stats	stat; - -  /*  -   * callbacks into RFP, set at startup time (bgp_rfapi_new() gets -   * values from rfp_start()) or via rfapi_rfp_set_cb_methods() -   * (otherwise NULL). Note that the response_cb method can also -   * be overridden per-rfd (currently used only for debug/test scenarios) -   */ -  struct rfapi_rfp_cb_methods	rfp_methods; - -  /* -   * Import tables for Ethernet over IPSEC -   * -   * The skiplist keys are LNIs. Values are pointers -   * to struct rfapi_import_table. -   */ -  struct skiplist		*import_mac;  /* L2 */ - -  /* -   * when exporting plain routes ("registered-nve" mode) to -   * bgp unicast or zebra, we need to keep track of information -   * related to expiring the routes according to the VNC lifetime -   */ -  struct route_table		*rt_export_bgp[AFI_MAX]; -  struct route_table		*rt_export_zebra[AFI_MAX]; - -  /* -   * For VNC->BGP unicast exports in CE mode, we need a -   * routing table that collects all of the VPN routes -   * in a single tree. The VPN rib is split up according -   * to RD first, so we can't use that. This is an import -   * table that matches all RTs. -   */ -  struct rfapi_import_table	*it_ce; - -  /* -   * when importing bgp-direct routes in resolve-nve mode, -   * this list maps unicast route nexthops to their bgp_infos -   * in the unicast table -   */ -  struct skiplist		*resolve_nve_nexthop; - -  /*  -   * Descriptors for which rfapi_close() was called during a callback. -   * They will be closed after the callback finishes. -   */ -  struct work_queue		*deferred_close_q; - -  /* -   * For "show vnc responses" -   */ -  uint32_t			response_immediate_count; -  uint32_t			response_updated_count; -  uint32_t			monitor_count; - -  uint32_t			rib_prefix_count_total; -  uint32_t			rib_prefix_count_total_max; - -  uint32_t			flags; +struct rfapi { +	struct route_table un[AFI_MAX]; +	struct rfapi_import_table *imports; /* IPv4, IPv6 */ +	struct list descriptors;	    /* debug & resolve-nve imports */ + +	struct rfapi_global_stats stat; + +	/* +	 * callbacks into RFP, set at startup time (bgp_rfapi_new() gets +	 * values from rfp_start()) or via rfapi_rfp_set_cb_methods() +	 * (otherwise NULL). Note that the response_cb method can also +	 * be overridden per-rfd (currently used only for debug/test scenarios) +	 */ +	struct rfapi_rfp_cb_methods rfp_methods; + +	/* +	 * Import tables for Ethernet over IPSEC +	 * +	 * The skiplist keys are LNIs. Values are pointers +	 * to struct rfapi_import_table. +	 */ +	struct skiplist *import_mac; /* L2 */ + +	/* +	 * when exporting plain routes ("registered-nve" mode) to +	 * bgp unicast or zebra, we need to keep track of information +	 * related to expiring the routes according to the VNC lifetime +	 */ +	struct route_table *rt_export_bgp[AFI_MAX]; +	struct route_table *rt_export_zebra[AFI_MAX]; + +	/* +	 * For VNC->BGP unicast exports in CE mode, we need a +	 * routing table that collects all of the VPN routes +	 * in a single tree. The VPN rib is split up according +	 * to RD first, so we can't use that. This is an import +	 * table that matches all RTs. +	 */ +	struct rfapi_import_table *it_ce; + +	/* +	 * when importing bgp-direct routes in resolve-nve mode, +	 * this list maps unicast route nexthops to their bgp_infos +	 * in the unicast table +	 */ +	struct skiplist *resolve_nve_nexthop; + +	/* +	 * Descriptors for which rfapi_close() was called during a callback. +	 * They will be closed after the callback finishes. +	 */ +	struct work_queue *deferred_close_q; + +	/* +	 * For "show vnc responses" +	 */ +	uint32_t response_immediate_count; +	uint32_t response_updated_count; +	uint32_t monitor_count; + +	uint32_t rib_prefix_count_total; +	uint32_t rib_prefix_count_total_max; + +	uint32_t flags;  #define RFAPI_INCALLBACK	0x00000001 -  void				*rfp;	/* from rfp_start */ +	void *rfp; /* from rfp_start */  }; -#define RFAPI_RIB_PREFIX_COUNT_INCR(rfd, rfapi) do {			\ -    ++(rfd)->rib_prefix_count;						\ -    ++(rfapi)->rib_prefix_count_total;					\ -    if ((rfapi)->rib_prefix_count_total > (rfapi)->rib_prefix_count_total_max) \ -	++(rfapi)->rib_prefix_count_total_max;				\ -    } while (0) - -#define RFAPI_RIB_PREFIX_COUNT_DECR(rfd, rfapi) do {			\ -    --(rfd)->rib_prefix_count;						\ -    --(rfapi)->rib_prefix_count_total;					\ -    } while (0) - -#define RFAPI_0_PREFIX(prefix) (					\ -    (((prefix)->family == AF_INET)? (prefix)->u.prefix4.s_addr == 0:	\ -    (((prefix)->family == AF_INET6)?					\ -	 (IN6_IS_ADDR_UNSPECIFIED(&(prefix)->u.prefix6)) : 0))			\ -) - -#define RFAPI_0_ETHERADDR(ea) (						\ -    ((ea)->octet[0] | (ea)->octet[1] | (ea)->octet[2] |			\ -    (ea)->octet[3] | (ea)->octet[4] | (ea)->octet[5]) == 0) - -#define RFAPI_HOST_PREFIX(prefix) (					\ -    ((prefix)->family == AF_INET)? ((prefix)->prefixlen == 32):		\ -    (((prefix)->family == AF_INET6)? ((prefix)->prefixlen == 128): 0) ) - -extern void -rfapiQprefix2Rprefix ( -  struct prefix			*qprefix, -  struct rfapi_ip_prefix	*rprefix); - -extern int -rfapi_find_rfd ( -  struct bgp			*bgp, -  struct rfapi_ip_addr		*vn_addr, -  struct rfapi_ip_addr		*un_addr, -  struct rfapi_descriptor	**rfd); +#define RFAPI_RIB_PREFIX_COUNT_INCR(rfd, rfapi)                                \ +	do {                                                                   \ +		++(rfd)->rib_prefix_count;                                     \ +		++(rfapi)->rib_prefix_count_total;                             \ +		if ((rfapi)->rib_prefix_count_total                            \ +		    > (rfapi)->rib_prefix_count_total_max)                     \ +			++(rfapi)->rib_prefix_count_total_max;                 \ +	} while (0) + +#define RFAPI_RIB_PREFIX_COUNT_DECR(rfd, rfapi)                                \ +	do {                                                                   \ +		--(rfd)->rib_prefix_count;                                     \ +		--(rfapi)->rib_prefix_count_total;                             \ +	} while (0) + +#define RFAPI_0_PREFIX(prefix)                                                 \ +	((((prefix)->family == AF_INET)                                        \ +		  ? (prefix)->u.prefix4.s_addr == 0                            \ +		  : (((prefix)->family == AF_INET6)                            \ +			     ? (IN6_IS_ADDR_UNSPECIFIED(&(prefix)->u.prefix6)) \ +			     : 0))) + +#define RFAPI_0_ETHERADDR(ea)                                                  \ +	(((ea)->octet[0] | (ea)->octet[1] | (ea)->octet[2] | (ea)->octet[3]    \ +	  | (ea)->octet[4] | (ea)->octet[5])                                   \ +	 == 0) + +#define RFAPI_HOST_PREFIX(prefix)                                              \ +	(((prefix)->family == AF_INET)                                         \ +		 ? ((prefix)->prefixlen == 32)                                 \ +		 : (((prefix)->family == AF_INET6)                             \ +			    ? ((prefix)->prefixlen == 128)                     \ +			    : 0)) + +extern void rfapiQprefix2Rprefix(struct prefix *qprefix, +				 struct rfapi_ip_prefix *rprefix); + +extern int rfapi_find_rfd(struct bgp *bgp, struct rfapi_ip_addr *vn_addr, +			  struct rfapi_ip_addr *un_addr, +			  struct rfapi_descriptor **rfd);  extern void -add_vnc_route ( -  struct rfapi_descriptor	*rfd,		/* cookie + UN addr for VPN */ -  struct bgp			*bgp, -  int				safi, -  struct prefix			*p, -  struct prefix_rd		*prd, -  struct rfapi_ip_addr		*nexthop, -  uint32_t			*local_pref,	/* host byte order */ -  uint32_t			*lifetime,	/* host byte order */ -  struct bgp_tea_options	*rfp_options, -  struct rfapi_un_option	*options_un, -  struct rfapi_vn_option	*options_vn, -  struct ecommunity		*rt_export_list, -  uint32_t			*med, -  uint32_t			*label, -  uint8_t			type, -  uint8_t			sub_type, -  int				flags); +add_vnc_route(struct rfapi_descriptor *rfd, /* cookie + UN addr for VPN */ +	      struct bgp *bgp, int safi, struct prefix *p, +	      struct prefix_rd *prd, struct rfapi_ip_addr *nexthop, +	      uint32_t *local_pref, /* host byte order */ +	      uint32_t *lifetime,   /* host byte order */ +	      struct bgp_tea_options *rfp_options, +	      struct rfapi_un_option *options_un, +	      struct rfapi_vn_option *options_vn, +	      struct ecommunity *rt_export_list, uint32_t *med, uint32_t *label, +	      uint8_t type, uint8_t sub_type, int flags);  #define RFAPI_AHR_NO_TUNNEL_SUBTLV	0x00000001  #define RFAPI_AHR_RFPOPT_IS_VNCTLV	0x00000002      /* hack! */ -#if 0   /* unused? */ +#if 0 /* unused? */  #  define RFAPI_AHR_SET_PFX_TO_NEXTHOP	0x00000004  #endif -extern void -del_vnc_route ( -  struct rfapi_descriptor	*rfd, -  struct peer			*peer, -  struct bgp			*bgp, -  safi_t			safi, -  struct prefix			*p, -  struct prefix_rd		*prd, -  uint8_t			type, -  uint8_t			sub_type, -  struct rfapi_nexthop		*lnh, -  int				kill); +extern void del_vnc_route(struct rfapi_descriptor *rfd, struct peer *peer, +			  struct bgp *bgp, safi_t safi, struct prefix *p, +			  struct prefix_rd *prd, uint8_t type, uint8_t sub_type, +			  struct rfapi_nexthop *lnh, int kill); -extern int -rfapiCliGetPrefixAddr (struct vty *vty, const char *str, struct prefix *p); +extern int rfapiCliGetPrefixAddr(struct vty *vty, const char *str, +				 struct prefix *p); -extern int -rfapiGetVncLifetime (struct attr *attr, uint32_t * lifetime); +extern int rfapiGetVncLifetime(struct attr *attr, uint32_t *lifetime); -extern int -rfapiGetTunnelType (struct attr *attr, bgp_encap_types *type); +extern int rfapiGetTunnelType(struct attr *attr, bgp_encap_types *type); -extern int -rfapiGetVncTunnelUnAddr (struct attr *attr, struct prefix *p); +extern int rfapiGetVncTunnelUnAddr(struct attr *attr, struct prefix *p); -extern int -rfapi_reopen (struct rfapi_descriptor *rfd, struct bgp *bgp); +extern int rfapi_reopen(struct rfapi_descriptor *rfd, struct bgp *bgp); -extern void -vnc_import_bgp_add_rfp_host_route_mode_resolve_nve ( -  struct bgp			*bgp, -  struct rfapi_descriptor	*rfd, -  struct prefix			*prefix); +extern void vnc_import_bgp_add_rfp_host_route_mode_resolve_nve( +	struct bgp *bgp, struct rfapi_descriptor *rfd, struct prefix *prefix); -extern void -vnc_import_bgp_del_rfp_host_route_mode_resolve_nve ( -  struct bgp			*bgp, -  struct rfapi_descriptor	*rfd, -  struct prefix			*prefix); +extern void vnc_import_bgp_del_rfp_host_route_mode_resolve_nve( +	struct bgp *bgp, struct rfapi_descriptor *rfd, struct prefix *prefix); -extern void -rfapiFreeBgpTeaOptionChain (struct bgp_tea_options *p); +extern void rfapiFreeBgpTeaOptionChain(struct bgp_tea_options *p); -extern struct rfapi_vn_option * -rfapiVnOptionsDup (struct rfapi_vn_option *orig); +extern struct rfapi_vn_option *rfapiVnOptionsDup(struct rfapi_vn_option *orig); -extern struct rfapi_un_option * -rfapiUnOptionsDup (struct rfapi_un_option *orig); +extern struct rfapi_un_option *rfapiUnOptionsDup(struct rfapi_un_option *orig); -extern struct bgp_tea_options * -rfapiOptionsDup (struct bgp_tea_options *orig); +extern struct bgp_tea_options *rfapiOptionsDup(struct bgp_tea_options *orig); -extern int -rfapi_ip_addr_cmp (struct rfapi_ip_addr *a1, struct rfapi_ip_addr *a2); +extern int rfapi_ip_addr_cmp(struct rfapi_ip_addr *a1, +			     struct rfapi_ip_addr *a2); -extern uint32_t -rfp_cost_to_localpref (uint8_t cost); +extern uint32_t rfp_cost_to_localpref(uint8_t cost); -extern int -rfapi_set_autord_from_vn (struct prefix_rd *rd, struct rfapi_ip_addr *vn); +extern int rfapi_set_autord_from_vn(struct prefix_rd *rd, +				    struct rfapi_ip_addr *vn); -extern struct rfapi_nexthop * -rfapi_nexthop_new (struct rfapi_nexthop *copyme); +extern struct rfapi_nexthop *rfapi_nexthop_new(struct rfapi_nexthop *copyme); -extern void -rfapi_nexthop_free (void *goner); +extern void rfapi_nexthop_free(void *goner);  extern struct rfapi_vn_option * -rfapi_vn_options_dup (struct rfapi_vn_option *existing); +rfapi_vn_options_dup(struct rfapi_vn_option *existing); -extern void -rfapi_un_options_free (struct rfapi_un_option *goner); +extern void rfapi_un_options_free(struct rfapi_un_option *goner); -extern void -rfapi_vn_options_free (struct rfapi_vn_option *goner); +extern void rfapi_vn_options_free(struct rfapi_vn_option *goner);  /*------------------------------------------   * rfapi_extract_l2o   * - * Find Layer 2 options in an option chain  + * Find Layer 2 options in an option chain   * - * input:  + * input:   *	pHop		option chain   *   * output: @@ -394,17 +361,16 @@ rfapi_vn_options_free (struct rfapi_vn_option *goner);   *	1		no options found   *   --------------------------------------------*/ -extern int -rfapi_extract_l2o ( -  struct bgp_tea_options	*pHop,	/* chain of options */ -  struct rfapi_l2address_option	*l2o);	/* return extracted value */ +extern int rfapi_extract_l2o( +	struct bgp_tea_options *pHop,	/* chain of options */ +	struct rfapi_l2address_option *l2o); /* return extracted value */ -/*  +/*   * compaitibility to old quagga_time call - * time_t value in terms of stabilised absolute time.  + * time_t value in terms of stabilised absolute time.   * replacement for POSIX time()   */ -extern time_t rfapi_time (time_t *t); +extern time_t rfapi_time(time_t *t);  DECLARE_MGROUP(RFAPI)  DECLARE_MTYPE(RFAPI_CFG) @@ -441,10 +407,7 @@ DECLARE_MTYPE(RFAPI_MONITOR_ETH)   * The advertised_prefixes[] array elements should be NULL to   * have this function set them to newly-allocated radix trees.   */ -extern int -rfapi_init_and_open( -  struct bgp			*bgp, -  struct rfapi_descriptor	*rfd, -  struct rfapi_nve_group_cfg	*rfg); +extern int rfapi_init_and_open(struct bgp *bgp, struct rfapi_descriptor *rfd, +			       struct rfapi_nve_group_cfg *rfg);  #endif /* _QUAGGA_BGP_RFAPI_PRIVATE_H */ diff --git a/bgpd/rfapi/rfapi_rib.c b/bgpd/rfapi/rfapi_rib.c index 902e702079..a414df1ab4 100644 --- a/bgpd/rfapi/rfapi_rib.c +++ b/bgpd/rfapi/rfapi_rib.c @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2009-2016, LabN Consulting, L.L.C.   * @@ -58,8 +58,8 @@  /* forward decl */  #if DEBUG_NHL -static void -rfapiRibShowRibSl (void *stream, struct prefix *pfx, struct skiplist *sl); +static void rfapiRibShowRibSl(void *stream, struct prefix *pfx, +			      struct skiplist *sl);  #endif  /* @@ -121,330 +121,295 @@ rfapiRibShowRibSl (void *stream, struct prefix *pfx, struct skiplist *sl);  /*   * iterate over RIB to count responses, compare with running counters   */ -void -rfapiRibCheckCounts ( -  int		checkstats,	/* validate rfd & global counts */ -  unsigned int	offset)		/* number of ri's held separately */ +void rfapiRibCheckCounts( +	int checkstats,      /* validate rfd & global counts */ +	unsigned int offset) /* number of ri's held separately */  { -  struct rfapi_descriptor *rfd; -  struct listnode *node; - -  struct bgp *bgp = bgp_get_default (); - -  uint32_t t_pfx_active = 0; -  uint32_t t_pfx_deleted = 0; - -  uint32_t t_ri_active = 0; -  uint32_t t_ri_deleted = 0; -  uint32_t t_ri_pend = 0; - -  unsigned int alloc_count; - -  /* -   * loop over NVEs -   */ -  for (ALL_LIST_ELEMENTS_RO (&bgp->rfapi->descriptors, node, rfd)) -    { - -      afi_t afi; -      uint32_t pfx_active = 0; -      uint32_t pfx_deleted = 0; - -      for (afi = AFI_IP; afi < AFI_MAX; ++afi) -        { - -          struct route_node *rn; - -          for (rn = route_top (rfd->rib[afi]); rn; rn = route_next (rn)) -            { - -              struct skiplist *sl = rn->info; -              struct skiplist *dsl = rn->aggregate; -              uint32_t ri_active = 0; -              uint32_t ri_deleted = 0; - -              if (sl) -                { -                  ri_active = skiplist_count (sl); -                  assert (ri_active); -                  t_ri_active += ri_active; -                  ++pfx_active; -                  ++t_pfx_active; -                } - -              if (dsl) -                { -                  ri_deleted = skiplist_count (dsl); -                  t_ri_deleted += ri_deleted; -                  ++pfx_deleted; -                  ++t_pfx_deleted; -                } -            } -          for (rn = route_top (rfd->rib_pending[afi]); rn; -               rn = route_next (rn)) -            { - -              struct list *l = rn->info;        /* sorted by cost */ -              struct skiplist *sl = rn->aggregate; -              uint32_t ri_pend_cost = 0; -              uint32_t ri_pend_uniq = 0; - -              if (sl) -                { -                  ri_pend_uniq = skiplist_count (sl); -                } - -              if (l && (l != (void *) 1)) -                { -                  ri_pend_cost = l->count; -                  t_ri_pend += l->count; -                } - -              assert (ri_pend_uniq == ri_pend_cost); -            } -        } - -      if (checkstats) -        { -          if (pfx_active != rfd->rib_prefix_count) -            { -              vnc_zlog_debug_verbose ("%s: rfd %p actual pfx count %u != running %u", -                          __func__, rfd, pfx_active, rfd->rib_prefix_count); -              assert (0); -            } -        } -    } - -  if (checkstats && bgp && bgp->rfapi) -    { -      if (t_pfx_active != bgp->rfapi->rib_prefix_count_total) -        { -          vnc_zlog_debug_verbose ("%s: actual total pfx count %u != running %u", -                      __func__, t_pfx_active, -                      bgp->rfapi->rib_prefix_count_total); -          assert (0); -        } -    } - -  /* -   * Check against memory allocation count -   */ -  alloc_count = mtype_stats_alloc (MTYPE_RFAPI_INFO); -  assert (t_ri_active + t_ri_deleted + t_ri_pend + offset == alloc_count); +	struct rfapi_descriptor *rfd; +	struct listnode *node; + +	struct bgp *bgp = bgp_get_default(); + +	uint32_t t_pfx_active = 0; +	uint32_t t_pfx_deleted = 0; + +	uint32_t t_ri_active = 0; +	uint32_t t_ri_deleted = 0; +	uint32_t t_ri_pend = 0; + +	unsigned int alloc_count; + +	/* +	 * loop over NVEs +	 */ +	for (ALL_LIST_ELEMENTS_RO(&bgp->rfapi->descriptors, node, rfd)) { + +		afi_t afi; +		uint32_t pfx_active = 0; +		uint32_t pfx_deleted = 0; + +		for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + +			struct route_node *rn; + +			for (rn = route_top(rfd->rib[afi]); rn; +			     rn = route_next(rn)) { + +				struct skiplist *sl = rn->info; +				struct skiplist *dsl = rn->aggregate; +				uint32_t ri_active = 0; +				uint32_t ri_deleted = 0; + +				if (sl) { +					ri_active = skiplist_count(sl); +					assert(ri_active); +					t_ri_active += ri_active; +					++pfx_active; +					++t_pfx_active; +				} + +				if (dsl) { +					ri_deleted = skiplist_count(dsl); +					t_ri_deleted += ri_deleted; +					++pfx_deleted; +					++t_pfx_deleted; +				} +			} +			for (rn = route_top(rfd->rib_pending[afi]); rn; +			     rn = route_next(rn)) { + +				struct list *l = rn->info; /* sorted by cost */ +				struct skiplist *sl = rn->aggregate; +				uint32_t ri_pend_cost = 0; +				uint32_t ri_pend_uniq = 0; + +				if (sl) { +					ri_pend_uniq = skiplist_count(sl); +				} + +				if (l && (l != (void *)1)) { +					ri_pend_cost = l->count; +					t_ri_pend += l->count; +				} + +				assert(ri_pend_uniq == ri_pend_cost); +			} +		} + +		if (checkstats) { +			if (pfx_active != rfd->rib_prefix_count) { +				vnc_zlog_debug_verbose( +					"%s: rfd %p actual pfx count %u != running %u", +					__func__, rfd, pfx_active, +					rfd->rib_prefix_count); +				assert(0); +			} +		} +	} + +	if (checkstats && bgp && bgp->rfapi) { +		if (t_pfx_active != bgp->rfapi->rib_prefix_count_total) { +			vnc_zlog_debug_verbose( +				"%s: actual total pfx count %u != running %u", +				__func__, t_pfx_active, +				bgp->rfapi->rib_prefix_count_total); +			assert(0); +		} +	} + +	/* +	 * Check against memory allocation count +	 */ +	alloc_count = mtype_stats_alloc(MTYPE_RFAPI_INFO); +	assert(t_ri_active + t_ri_deleted + t_ri_pend + offset == alloc_count);  } -static struct rfapi_info * -rfapi_info_new () +static struct rfapi_info *rfapi_info_new()  { -  return XCALLOC (MTYPE_RFAPI_INFO, sizeof (struct rfapi_info)); +	return XCALLOC(MTYPE_RFAPI_INFO, sizeof(struct rfapi_info));  } -void -rfapiFreeRfapiUnOptionChain (struct rfapi_un_option *p) +void rfapiFreeRfapiUnOptionChain(struct rfapi_un_option *p)  { -  while (p) -    { -      struct rfapi_un_option *next; - -      next = p->next; -      XFREE (MTYPE_RFAPI_UN_OPTION, p); -      p = next; -    } +	while (p) { +		struct rfapi_un_option *next; + +		next = p->next; +		XFREE(MTYPE_RFAPI_UN_OPTION, p); +		p = next; +	}  } -void -rfapiFreeRfapiVnOptionChain (struct rfapi_vn_option *p) +void rfapiFreeRfapiVnOptionChain(struct rfapi_vn_option *p)  { -  while (p) -    { -      struct rfapi_vn_option *next; - -      next = p->next; -      XFREE (MTYPE_RFAPI_VN_OPTION, p); -      p = next; -    } +	while (p) { +		struct rfapi_vn_option *next; + +		next = p->next; +		XFREE(MTYPE_RFAPI_VN_OPTION, p); +		p = next; +	}  } -static void -rfapi_info_free (struct rfapi_info *goner) +static void rfapi_info_free(struct rfapi_info *goner)  { -  if (goner) -    { -      if (goner->tea_options) -        { -          rfapiFreeBgpTeaOptionChain (goner->tea_options); -          goner->tea_options = NULL; -        } -      if (goner->un_options) -        { -          rfapiFreeRfapiUnOptionChain (goner->un_options); -          goner->un_options = NULL; -        } -      if (goner->vn_options) -        { -          rfapiFreeRfapiVnOptionChain (goner->vn_options); -          goner->vn_options = NULL; -        } -      if (goner->timer) -        { -          struct rfapi_rib_tcb *tcb; - -          tcb = ((struct thread *) goner->timer)->arg; -          thread_cancel ((struct thread *) goner->timer); -          XFREE (MTYPE_RFAPI_RECENT_DELETE, tcb); -          goner->timer = NULL; -        } -      XFREE (MTYPE_RFAPI_INFO, goner); -    } +	if (goner) { +		if (goner->tea_options) { +			rfapiFreeBgpTeaOptionChain(goner->tea_options); +			goner->tea_options = NULL; +		} +		if (goner->un_options) { +			rfapiFreeRfapiUnOptionChain(goner->un_options); +			goner->un_options = NULL; +		} +		if (goner->vn_options) { +			rfapiFreeRfapiVnOptionChain(goner->vn_options); +			goner->vn_options = NULL; +		} +		if (goner->timer) { +			struct rfapi_rib_tcb *tcb; + +			tcb = ((struct thread *)goner->timer)->arg; +			thread_cancel((struct thread *)goner->timer); +			XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb); +			goner->timer = NULL; +		} +		XFREE(MTYPE_RFAPI_INFO, goner); +	}  }  /*   * Timer control block for recently-deleted and expired routes   */ -struct rfapi_rib_tcb -{ -  struct rfapi_descriptor *rfd; -  struct skiplist *sl; -  struct rfapi_info *ri; -  struct route_node *rn; -  int flags; +struct rfapi_rib_tcb { +	struct rfapi_descriptor *rfd; +	struct skiplist *sl; +	struct rfapi_info *ri; +	struct route_node *rn; +	int flags;  #define RFAPI_RIB_TCB_FLAG_DELETED	0x00000001  };  /*   * remove route from rib   */ -static int -rfapiRibExpireTimer (struct thread *t) +static int rfapiRibExpireTimer(struct thread *t)  { -  struct rfapi_rib_tcb *tcb = t->arg; - -  RFAPI_RIB_CHECK_COUNTS (1, 0); - -  /* -   * Forget reference to thread. Otherwise rfapi_info_free() will -   * attempt to free thread pointer as an option chain -   */ -  tcb->ri->timer = NULL; - -  /* "deleted" skiplist frees ri, "active" doesn't */ -  assert (!skiplist_delete (tcb->sl, &tcb->ri->rk, NULL)); -  if (!tcb->sl->del) -    { -      /* -       * XXX in this case, skiplist has no delete function: we must -       * therefore delete rfapi_info explicitly. -       */ -      rfapi_info_free (tcb->ri); -    } - -  if (skiplist_empty (tcb->sl)) -    { -      if (CHECK_FLAG (tcb->flags, RFAPI_RIB_TCB_FLAG_DELETED)) -        tcb->rn->aggregate = NULL; -      else -        { -          struct bgp *bgp = bgp_get_default (); -          tcb->rn->info = NULL; -          RFAPI_RIB_PREFIX_COUNT_DECR (tcb->rfd, bgp->rfapi); -        } -      skiplist_free (tcb->sl); -      route_unlock_node (tcb->rn); -    } - -  XFREE (MTYPE_RFAPI_RECENT_DELETE, tcb); - -  RFAPI_RIB_CHECK_COUNTS (1, 0); - -  return 0; +	struct rfapi_rib_tcb *tcb = t->arg; + +	RFAPI_RIB_CHECK_COUNTS(1, 0); + +	/* +	 * Forget reference to thread. Otherwise rfapi_info_free() will +	 * attempt to free thread pointer as an option chain +	 */ +	tcb->ri->timer = NULL; + +	/* "deleted" skiplist frees ri, "active" doesn't */ +	assert(!skiplist_delete(tcb->sl, &tcb->ri->rk, NULL)); +	if (!tcb->sl->del) { +		/* +		 * XXX in this case, skiplist has no delete function: we must +		 * therefore delete rfapi_info explicitly. +		 */ +		rfapi_info_free(tcb->ri); +	} + +	if (skiplist_empty(tcb->sl)) { +		if (CHECK_FLAG(tcb->flags, RFAPI_RIB_TCB_FLAG_DELETED)) +			tcb->rn->aggregate = NULL; +		else { +			struct bgp *bgp = bgp_get_default(); +			tcb->rn->info = NULL; +			RFAPI_RIB_PREFIX_COUNT_DECR(tcb->rfd, bgp->rfapi); +		} +		skiplist_free(tcb->sl); +		route_unlock_node(tcb->rn); +	} + +	XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb); + +	RFAPI_RIB_CHECK_COUNTS(1, 0); + +	return 0;  }  static void -rfapiRibStartTimer ( -  struct rfapi_descriptor	*rfd, -  struct rfapi_info		*ri, -  struct route_node		*rn, /* route node attached to */ -  int				deleted) +rfapiRibStartTimer(struct rfapi_descriptor *rfd, struct rfapi_info *ri, +		   struct route_node *rn, /* route node attached to */ +		   int deleted)  { -  struct thread *t = ri->timer; -  struct rfapi_rib_tcb *tcb = NULL; -  char buf_prefix[BUFSIZ]; - -  if (t) -    { -      tcb = t->arg; -      thread_cancel (t); -      ri->timer = NULL; -    } -  else -    { -      tcb = -        XCALLOC (MTYPE_RFAPI_RECENT_DELETE, sizeof (struct rfapi_rib_tcb)); -    } -  tcb->rfd = rfd; -  tcb->ri = ri; -  tcb->rn = rn; -  if (deleted) -    { -      tcb->sl = (struct skiplist *) rn->aggregate; -      SET_FLAG (tcb->flags, RFAPI_RIB_TCB_FLAG_DELETED); -    } -  else -    { -      tcb->sl = (struct skiplist *) rn->info; -      UNSET_FLAG (tcb->flags, RFAPI_RIB_TCB_FLAG_DELETED); -    } - -  prefix2str (&rn->p, buf_prefix, BUFSIZ); -  vnc_zlog_debug_verbose ("%s: rfd %p pfx %s life %u", __func__, rfd, buf_prefix, -              ri->lifetime); -  ri->timer = NULL; -  thread_add_timer(bm->master, rfapiRibExpireTimer, tcb, ri->lifetime, -                   &ri->timer); -  assert (ri->timer); +	struct thread *t = ri->timer; +	struct rfapi_rib_tcb *tcb = NULL; +	char buf_prefix[BUFSIZ]; + +	if (t) { +		tcb = t->arg; +		thread_cancel(t); +		ri->timer = NULL; +	} else { +		tcb = XCALLOC(MTYPE_RFAPI_RECENT_DELETE, +			      sizeof(struct rfapi_rib_tcb)); +	} +	tcb->rfd = rfd; +	tcb->ri = ri; +	tcb->rn = rn; +	if (deleted) { +		tcb->sl = (struct skiplist *)rn->aggregate; +		SET_FLAG(tcb->flags, RFAPI_RIB_TCB_FLAG_DELETED); +	} else { +		tcb->sl = (struct skiplist *)rn->info; +		UNSET_FLAG(tcb->flags, RFAPI_RIB_TCB_FLAG_DELETED); +	} + +	prefix2str(&rn->p, buf_prefix, BUFSIZ); +	vnc_zlog_debug_verbose("%s: rfd %p pfx %s life %u", __func__, rfd, +			       buf_prefix, ri->lifetime); +	ri->timer = NULL; +	thread_add_timer(bm->master, rfapiRibExpireTimer, tcb, ri->lifetime, +			 &ri->timer); +	assert(ri->timer);  } -extern void -rfapi_rib_key_init (struct prefix        *prefix, /* may be NULL */ -                    struct prefix_rd     *rd,     /* may be NULL */ -                    struct prefix        *aux,    /* may be NULL */ -                    struct rfapi_rib_key *rk) -   +extern void rfapi_rib_key_init(struct prefix *prefix, /* may be NULL */ +			       struct prefix_rd *rd,  /* may be NULL */ +			       struct prefix *aux,    /* may be NULL */ +			       struct rfapi_rib_key *rk) +  { -  memset((void *)rk, 0, sizeof(struct rfapi_rib_key)); -  if (prefix) -    rk->vn = *prefix; -  if (rd) -    rk->rd = *rd; -  if (aux) -    rk->aux_prefix = *aux; +	memset((void *)rk, 0, sizeof(struct rfapi_rib_key)); +	if (prefix) +		rk->vn = *prefix; +	if (rd) +		rk->rd = *rd; +	if (aux) +		rk->aux_prefix = *aux;  }  /*   * Compares two <struct rfapi_rib_key>s   */ -int -rfapi_rib_key_cmp (void *k1, void *k2) +int rfapi_rib_key_cmp(void *k1, void *k2)  { -  struct rfapi_rib_key *a = (struct rfapi_rib_key *) k1; -  struct rfapi_rib_key *b = (struct rfapi_rib_key *) k2; -  int ret; +	struct rfapi_rib_key *a = (struct rfapi_rib_key *)k1; +	struct rfapi_rib_key *b = (struct rfapi_rib_key *)k2; +	int ret; -  if (!a || !b) -    return (a - b); +	if (!a || !b) +		return (a - b); -  ret = vnc_prefix_cmp (&a->vn, &b->vn); -  if (ret) -    return ret; +	ret = vnc_prefix_cmp(&a->vn, &b->vn); +	if (ret) +		return ret; -  ret = vnc_prefix_cmp(&a->rd, &b->rd); -  if (ret) -    return ret; +	ret = vnc_prefix_cmp(&a->rd, &b->rd); +	if (ret) +		return ret; -  ret = vnc_prefix_cmp (&a->aux_prefix, &b->aux_prefix); +	ret = vnc_prefix_cmp(&a->aux_prefix, &b->aux_prefix); -  return ret; +	return ret;  } @@ -459,295 +424,296 @@ rfapi_rib_key_cmp (void *k1, void *k2)   * thoroughly, but it's not clear that the extra compuation would   * be worth it.   */ -static int -bgp_tea_options_cmp (struct bgp_tea_options *a, struct bgp_tea_options *b) +static int bgp_tea_options_cmp(struct bgp_tea_options *a, +			       struct bgp_tea_options *b)  { -  int rc; - -  if (!a || !b) -    { -      return (a - b); -    } - -  if (a->type != b->type) -    return (a->type - b->type); -  if (a->length != b->length) -    return (a->length = b->length); -  if ((rc = memcmp (a->value, b->value, a->length))) -    return rc; -  if (!a->next != !b->next) -    {                           /* logical xor */ -      return (a->next - b->next); -    } -  if (a->next) -    return bgp_tea_options_cmp (a->next, b->next); -  return 0; +	int rc; + +	if (!a || !b) { +		return (a - b); +	} +	if (a->type != b->type) +		return (a->type - b->type); +	if (a->length != b->length) +		return (a->length = b->length); +	if ((rc = memcmp(a->value, b->value, a->length))) +		return rc; +	if (!a->next != !b->next) { /* logical xor */ +		return (a->next - b->next); +	} +	if (a->next) +		return bgp_tea_options_cmp(a->next, b->next); +	return 0;  } -static int -rfapi_info_cmp (struct rfapi_info *a, struct rfapi_info *b) +static int rfapi_info_cmp(struct rfapi_info *a, struct rfapi_info *b)  { -  int rc; +	int rc; -  if (!a || !b) -    return (a - b); +	if (!a || !b) +		return (a - b); -  if ((rc = rfapi_rib_key_cmp (&a->rk, &b->rk))) -    return rc; +	if ((rc = rfapi_rib_key_cmp(&a->rk, &b->rk))) +		return rc; -  if ((rc = vnc_prefix_cmp (&a->un, &b->un))) -    return rc; +	if ((rc = vnc_prefix_cmp(&a->un, &b->un))) +		return rc; -  if (a->cost != b->cost) -    return (a->cost - b->cost); +	if (a->cost != b->cost) +		return (a->cost - b->cost); -  if (a->lifetime != b->lifetime) -    return (a->lifetime - b->lifetime); +	if (a->lifetime != b->lifetime) +		return (a->lifetime - b->lifetime); -  if ((rc = bgp_tea_options_cmp (a->tea_options, b->tea_options))) -    return rc; +	if ((rc = bgp_tea_options_cmp(a->tea_options, b->tea_options))) +		return rc; -  return 0; +	return 0;  } -void -rfapiRibClear (struct rfapi_descriptor *rfd) +void rfapiRibClear(struct rfapi_descriptor *rfd)  { -  struct bgp *bgp; -  afi_t afi; +	struct bgp *bgp; +	afi_t afi; -  if (rfd->bgp) -    bgp = rfd->bgp; -  else -    bgp = bgp_get_default (); +	if (rfd->bgp) +		bgp = rfd->bgp; +	else +		bgp = bgp_get_default();  #if DEBUG_L2_EXTRA -  vnc_zlog_debug_verbose ("%s: rfd=%p", __func__, rfd); +	vnc_zlog_debug_verbose("%s: rfd=%p", __func__, rfd);  #endif -  for (afi = AFI_IP; afi < AFI_MAX; ++afi) -    { -      struct route_node *pn; -      struct route_node *rn; - -      if (rfd->rib_pending[afi]) -        { -          for (pn = route_top (rfd->rib_pending[afi]); pn; -               pn = route_next (pn)) -            { -              if (pn->aggregate) -                { -                  /*  -                   * free references into the rfapi_info structures before -                   * freeing the structures themselves -                   */ -                  skiplist_free ((struct skiplist *) (pn->aggregate)); -                  pn->aggregate = NULL; -                  route_unlock_node (pn);       /* skiplist deleted */ -                } -              /*  -               * free the rfapi_info structures -               */ -              if (pn->info) -                { -                  if (pn->info != (void *) 1) -                    { -                      list_delete ((struct list *) (pn->info)); -                    } -                  pn->info = NULL; -                  route_unlock_node (pn);       /* linklist or 1 deleted */ -                } -            } -        } -      if (rfd->rib[afi]) -        { -          for (rn = route_top (rfd->rib[afi]); rn; rn = route_next (rn)) -            { -              if (rn->info) -                { - -                  struct rfapi_info *ri; - -                  while (0 == -                         skiplist_first ((struct skiplist *) rn->info, NULL, -                                         (void **) &ri)) -                    { - -                      rfapi_info_free (ri); -                      skiplist_delete_first ((struct skiplist *) rn->info); -                    } -                  skiplist_free ((struct skiplist *) rn->info); -                  rn->info = NULL; -                  route_unlock_node (rn); -                  RFAPI_RIB_PREFIX_COUNT_DECR (rfd, bgp->rfapi); -                } -              if (rn->aggregate) -                { - -                  struct rfapi_info *ri_del; - -                  /* delete skiplist & contents */ -                  while (!skiplist_first ((struct skiplist *) (rn->aggregate), -                                          NULL, (void **) &ri_del)) -                    { - -                      /* sl->del takes care of ri_del */ -                      skiplist_delete_first ( -			(struct skiplist *) (rn->aggregate)); -                    } -                  skiplist_free ((struct skiplist *) (rn->aggregate)); - -                  rn->aggregate = NULL; -                  route_unlock_node (rn); -                } -            } -        } -    } -  if (rfd->updated_responses_queue) -    { -      work_queue_free (rfd->updated_responses_queue); -      rfd->updated_responses_queue = NULL; -    } +	for (afi = AFI_IP; afi < AFI_MAX; ++afi) { +		struct route_node *pn; +		struct route_node *rn; + +		if (rfd->rib_pending[afi]) { +			for (pn = route_top(rfd->rib_pending[afi]); pn; +			     pn = route_next(pn)) { +				if (pn->aggregate) { +					/* +					 * free references into the rfapi_info +					 * structures before +					 * freeing the structures themselves +					 */ +					skiplist_free( +						(struct skiplist +							 *)(pn->aggregate)); +					pn->aggregate = NULL; +					route_unlock_node( +						pn); /* skiplist deleted */ +				} +				/* +				 * free the rfapi_info structures +				 */ +				if (pn->info) { +					if (pn->info != (void *)1) { +						list_delete( +							(struct list +								 *)(pn->info)); +					} +					pn->info = NULL; +					route_unlock_node( +						pn); /* linklist or 1 deleted */ +				} +			} +		} +		if (rfd->rib[afi]) { +			for (rn = route_top(rfd->rib[afi]); rn; +			     rn = route_next(rn)) { +				if (rn->info) { + +					struct rfapi_info *ri; + +					while (0 == skiplist_first( +							    (struct skiplist *) +								    rn->info, +							    NULL, +							    (void **)&ri)) { + +						rfapi_info_free(ri); +						skiplist_delete_first( +							(struct skiplist *) +								rn->info); +					} +					skiplist_free( +						(struct skiplist *)rn->info); +					rn->info = NULL; +					route_unlock_node(rn); +					RFAPI_RIB_PREFIX_COUNT_DECR(rfd, +								    bgp->rfapi); +				} +				if (rn->aggregate) { + +					struct rfapi_info *ri_del; + +					/* delete skiplist & contents */ +					while (!skiplist_first( +						(struct skiplist +							 *)(rn->aggregate), +						NULL, (void **)&ri_del)) { + +						/* sl->del takes care of ri_del +						 */ +						skiplist_delete_first(( +							struct skiplist +								*)(rn->aggregate)); +					} +					skiplist_free( +						(struct skiplist +							 *)(rn->aggregate)); + +					rn->aggregate = NULL; +					route_unlock_node(rn); +				} +			} +		} +	} +	if (rfd->updated_responses_queue) { +		work_queue_free(rfd->updated_responses_queue); +		rfd->updated_responses_queue = NULL; +	}  }  /*   * Release all dynamically-allocated memory that is part of an HD's RIB   */ -void -rfapiRibFree (struct rfapi_descriptor *rfd) +void rfapiRibFree(struct rfapi_descriptor *rfd)  { -  afi_t afi; +	afi_t afi; -  /* -   * NB rfd is typically detached from master list, so is not included -   * in the count performed by RFAPI_RIB_CHECK_COUNTS -   */ +	/* +	 * NB rfd is typically detached from master list, so is not included +	 * in the count performed by RFAPI_RIB_CHECK_COUNTS +	 */ -  /* -   * Free routes attached to radix trees -   */ -  rfapiRibClear (rfd); +	/* +	 * Free routes attached to radix trees +	 */ +	rfapiRibClear(rfd); -  /* Now the uncounted rfapi_info's are freed, so the check should succeed */ -  RFAPI_RIB_CHECK_COUNTS (1, 0); +	/* Now the uncounted rfapi_info's are freed, so the check should succeed +	 */ +	RFAPI_RIB_CHECK_COUNTS(1, 0); -  /* -   * Free radix trees -   */ -  for (afi = AFI_IP; afi < AFI_MAX; ++afi) -    { -      route_table_finish (rfd->rib_pending[afi]); -      rfd->rib_pending[afi] = NULL; +	/* +	 * Free radix trees +	 */ +	for (afi = AFI_IP; afi < AFI_MAX; ++afi) { +		route_table_finish(rfd->rib_pending[afi]); +		rfd->rib_pending[afi] = NULL; -      route_table_finish (rfd->rib[afi]); -      rfd->rib[afi] = NULL; +		route_table_finish(rfd->rib[afi]); +		rfd->rib[afi] = NULL; -      /* NB route_table_finish frees only prefix nodes, not chained info */ -      route_table_finish (rfd->rsp_times[afi]); -      rfd->rib[afi] = NULL; -    } +		/* NB route_table_finish frees only prefix nodes, not chained +		 * info */ +		route_table_finish(rfd->rsp_times[afi]); +		rfd->rib[afi] = NULL; +	}  }  /*   * Copies struct bgp_info to struct rfapi_info, except for rk fields and un   */ -static void -rfapiRibBi2Ri( -  struct bgp_info   *bi, -  struct rfapi_info *ri, -  uint32_t          lifetime) +static void rfapiRibBi2Ri(struct bgp_info *bi, struct rfapi_info *ri, +			  uint32_t lifetime)  { -  struct bgp_attr_encap_subtlv *pEncap; - -  ri->cost = rfapiRfpCost (bi->attr); -  ri->lifetime = lifetime; - -  /* This loop based on rfapiRouteInfo2NextHopEntry() */ -  for (pEncap = bi->attr->vnc_subtlvs; pEncap; pEncap = pEncap->next) -    { -      struct bgp_tea_options *hop; - -      switch (pEncap->type) -        { -        case BGP_VNC_SUBTLV_TYPE_LIFETIME: -          /* use configured lifetime, not attr lifetime */ -          break; - -        case BGP_VNC_SUBTLV_TYPE_RFPOPTION: -          hop = XCALLOC (MTYPE_BGP_TEA_OPTIONS, -                         sizeof (struct bgp_tea_options)); -          assert (hop); -          hop->type = pEncap->value[0]; -          hop->length = pEncap->value[1]; -          hop->value = XCALLOC (MTYPE_BGP_TEA_OPTIONS_VALUE, -                                pEncap->length - 2); -          assert (hop->value); -          memcpy (hop->value, pEncap->value + 2, pEncap->length - 2); -          if (hop->length > pEncap->length - 2) -            { -              zlog_warn ("%s: VNC subtlv length mismatch: " -                         "RFP option says %d, attr says %d " -                         "(shrinking)", -                         __func__, hop->length, pEncap->length - 2); -              hop->length = pEncap->length - 2; -            } -          hop->next = ri->tea_options; -          ri->tea_options = hop; -          break; - -        default: -          break; -        } -    } - -  rfapi_un_options_free (ri->un_options);   /* maybe free old version */ -  ri->un_options = rfapi_encap_tlv_to_un_option (bi->attr); - -  /* -   * VN options -   */ -  if (bi->extra &&  -      decode_rd_type(bi->extra->vnc.import.rd.val) == RD_TYPE_VNC_ETH) -    { -      /* ethernet route */ - -      struct rfapi_vn_option *vo; - -      vo = XCALLOC (MTYPE_RFAPI_VN_OPTION, sizeof (struct rfapi_vn_option)); -      assert (vo); - -      vo->type = RFAPI_VN_OPTION_TYPE_L2ADDR; - -      /* copy from RD already stored in bi, so we don't need it_node */ -      memcpy (&vo->v.l2addr.macaddr, bi->extra->vnc.import.rd.val+2, -	ETHER_ADDR_LEN); - -      if (bi->attr) -        { -          (void) rfapiEcommunityGetLNI (bi->attr->ecommunity, -                                        &vo->v.l2addr.logical_net_id); -          (void) rfapiEcommunityGetEthernetTag (bi->attr->ecommunity, -                                                &vo->v.l2addr.tag_id); -        } - -      /* local_nve_id comes from RD */ -      vo->v.l2addr.local_nve_id = bi->extra->vnc.import.rd.val[1]; - -      /* label comes from MP_REACH_NLRI label */ -      vo->v.l2addr.label = decode_label (&bi->extra->label); - -      rfapi_vn_options_free (ri->vn_options);   /* maybe free old version */ -      ri->vn_options = vo; -    } - -  /* -   * If there is an auxiliary IP address (L2 can have it), copy it -   */ -  if (bi && bi->extra && bi->extra->vnc.import.aux_prefix.family) -    { -      ri->rk.aux_prefix = bi->extra->vnc.import.aux_prefix; -    } +	struct bgp_attr_encap_subtlv *pEncap; + +	ri->cost = rfapiRfpCost(bi->attr); +	ri->lifetime = lifetime; + +	/* This loop based on rfapiRouteInfo2NextHopEntry() */ +	for (pEncap = bi->attr->vnc_subtlvs; pEncap; pEncap = pEncap->next) { +		struct bgp_tea_options *hop; + +		switch (pEncap->type) { +		case BGP_VNC_SUBTLV_TYPE_LIFETIME: +			/* use configured lifetime, not attr lifetime */ +			break; + +		case BGP_VNC_SUBTLV_TYPE_RFPOPTION: +			hop = XCALLOC(MTYPE_BGP_TEA_OPTIONS, +				      sizeof(struct bgp_tea_options)); +			assert(hop); +			hop->type = pEncap->value[0]; +			hop->length = pEncap->value[1]; +			hop->value = XCALLOC(MTYPE_BGP_TEA_OPTIONS_VALUE, +					     pEncap->length - 2); +			assert(hop->value); +			memcpy(hop->value, pEncap->value + 2, +			       pEncap->length - 2); +			if (hop->length > pEncap->length - 2) { +				zlog_warn( +					"%s: VNC subtlv length mismatch: " +					"RFP option says %d, attr says %d " +					"(shrinking)", +					__func__, hop->length, +					pEncap->length - 2); +				hop->length = pEncap->length - 2; +			} +			hop->next = ri->tea_options; +			ri->tea_options = hop; +			break; + +		default: +			break; +		} +	} + +	rfapi_un_options_free(ri->un_options); /* maybe free old version */ +	ri->un_options = rfapi_encap_tlv_to_un_option(bi->attr); + +	/* +	 * VN options +	 */ +	if (bi->extra +	    && decode_rd_type(bi->extra->vnc.import.rd.val) +		       == RD_TYPE_VNC_ETH) { +		/* ethernet route */ + +		struct rfapi_vn_option *vo; + +		vo = XCALLOC(MTYPE_RFAPI_VN_OPTION, +			     sizeof(struct rfapi_vn_option)); +		assert(vo); + +		vo->type = RFAPI_VN_OPTION_TYPE_L2ADDR; + +		/* copy from RD already stored in bi, so we don't need it_node +		 */ +		memcpy(&vo->v.l2addr.macaddr, bi->extra->vnc.import.rd.val + 2, +		       ETHER_ADDR_LEN); + +		if (bi->attr) { +			(void)rfapiEcommunityGetLNI( +				bi->attr->ecommunity, +				&vo->v.l2addr.logical_net_id); +			(void)rfapiEcommunityGetEthernetTag( +				bi->attr->ecommunity, &vo->v.l2addr.tag_id); +		} + +		/* local_nve_id comes from RD */ +		vo->v.l2addr.local_nve_id = bi->extra->vnc.import.rd.val[1]; + +		/* label comes from MP_REACH_NLRI label */ +		vo->v.l2addr.label = decode_label(&bi->extra->label); + +		rfapi_vn_options_free( +			ri->vn_options); /* maybe free old version */ +		ri->vn_options = vo; +	} + +	/* +	 * If there is an auxiliary IP address (L2 can have it), copy it +	 */ +	if (bi && bi->extra && bi->extra->vnc.import.aux_prefix.family) { +		ri->rk.aux_prefix = bi->extra->vnc.import.aux_prefix; +	}  }  /* @@ -768,94 +734,86 @@ rfapiRibBi2Ri(   *	0	OK to include route in response   *	!0	do not include route in response   */ -int -rfapiRibPreloadBi( -  struct route_node *rfd_rib_node,	/* NULL = don't preload or filter */ -  struct prefix     *pfx_vn, -  struct prefix     *pfx_un, -  uint32_t          lifetime, -  struct bgp_info   *bi) +int rfapiRibPreloadBi( +	struct route_node *rfd_rib_node, /* NULL = don't preload or filter */ +	struct prefix *pfx_vn, struct prefix *pfx_un, uint32_t lifetime, +	struct bgp_info *bi)  { -  struct rfapi_descriptor *rfd; -  struct skiplist         *slRibPt = NULL; -  struct rfapi_info       *ori = NULL; -  struct rfapi_rib_key    rk; -  struct route_node       *trn; -  afi_t                   afi; - -  if (!rfd_rib_node) -    return 0; - -  afi  = family2afi(rfd_rib_node->p.family); - -  rfd = (struct rfapi_descriptor *)(rfd_rib_node->table->info); - -  memset((void *)&rk, 0, sizeof(rk)); -  rk.vn = *pfx_vn; -  rk.rd = bi->extra->vnc.import.rd; - -  /* -   * If there is an auxiliary IP address (L2 can have it), copy it -   */ -  if (bi->extra->vnc.import.aux_prefix.family) -    { -      rk.aux_prefix = bi->extra->vnc.import.aux_prefix; -    } - -  /* -   * is this route already in NVE's RIB? -   */ -  slRibPt = (struct skiplist *) rfd_rib_node->info; - -  if (slRibPt && !skiplist_search (slRibPt, &rk, (void **) &ori)) -    { - -      if ((ori->rsp_counter == rfd->rsp_counter) && -        (ori->last_sent_time == rfd->rsp_time)) -	{ -	  return -1;	/* duplicate in this response */ +	struct rfapi_descriptor *rfd; +	struct skiplist *slRibPt = NULL; +	struct rfapi_info *ori = NULL; +	struct rfapi_rib_key rk; +	struct route_node *trn; +	afi_t afi; + +	if (!rfd_rib_node) +		return 0; + +	afi = family2afi(rfd_rib_node->p.family); + +	rfd = (struct rfapi_descriptor *)(rfd_rib_node->table->info); + +	memset((void *)&rk, 0, sizeof(rk)); +	rk.vn = *pfx_vn; +	rk.rd = bi->extra->vnc.import.rd; + +	/* +	 * If there is an auxiliary IP address (L2 can have it), copy it +	 */ +	if (bi->extra->vnc.import.aux_prefix.family) { +		rk.aux_prefix = bi->extra->vnc.import.aux_prefix; +	} + +	/* +	 * is this route already in NVE's RIB? +	 */ +	slRibPt = (struct skiplist *)rfd_rib_node->info; + +	if (slRibPt && !skiplist_search(slRibPt, &rk, (void **)&ori)) { + +		if ((ori->rsp_counter == rfd->rsp_counter) +		    && (ori->last_sent_time == rfd->rsp_time)) { +			return -1; /* duplicate in this response */ +		} + +		/* found: update contents of existing route in RIB */ +		ori->un = *pfx_un; +		rfapiRibBi2Ri(bi, ori, lifetime); +	} else { +		/* not found: add new route to RIB */ +		ori = rfapi_info_new(); +		ori->rk = rk; +		ori->un = *pfx_un; +		rfapiRibBi2Ri(bi, ori, lifetime); + +		if (!slRibPt) { +			slRibPt = skiplist_new(0, rfapi_rib_key_cmp, NULL); +			rfd_rib_node->info = slRibPt; +			route_lock_node(rfd_rib_node); +			RFAPI_RIB_PREFIX_COUNT_INCR(rfd, rfd->bgp->rfapi); +		} +		skiplist_insert(slRibPt, &ori->rk, ori);  	} -      /* found: update contents of existing route in RIB */ -      ori->un = *pfx_un; -      rfapiRibBi2Ri(bi, ori, lifetime); -    } -  else -    { -      /* not found: add new route to RIB */ -      ori = rfapi_info_new (); -      ori->rk = rk; -      ori->un = *pfx_un; -      rfapiRibBi2Ri(bi, ori, lifetime); - -      if (!slRibPt) -        { -          slRibPt = skiplist_new (0, rfapi_rib_key_cmp, NULL); -          rfd_rib_node->info = slRibPt; -          route_lock_node (rfd_rib_node); -          RFAPI_RIB_PREFIX_COUNT_INCR (rfd, rfd->bgp->rfapi); -        } -      skiplist_insert (slRibPt, &ori->rk, ori); -    } - -  ori->last_sent_time = rfapi_time (NULL); - -  /* -   * poke timer -   */ -  RFAPI_RIB_CHECK_COUNTS (0, 0); -  rfapiRibStartTimer (rfd, ori, rfd_rib_node, 0); -  RFAPI_RIB_CHECK_COUNTS (0, 0); - -  /* -   * Update last sent time for prefix -   */ -  trn = route_node_get (rfd->rsp_times[afi], &rfd_rib_node->p); /* locks trn */ -  trn->info = (void *) (uintptr_t) bgp_clock (); -  if (trn->lock > 1) -    route_unlock_node (trn); - -  return 0; +	ori->last_sent_time = rfapi_time(NULL); + +	/* +	 * poke timer +	 */ +	RFAPI_RIB_CHECK_COUNTS(0, 0); +	rfapiRibStartTimer(rfd, ori, rfd_rib_node, 0); +	RFAPI_RIB_CHECK_COUNTS(0, 0); + +	/* +	 * Update last sent time for prefix +	 */ +	trn = route_node_get(rfd->rsp_times[afi], +			     &rfd_rib_node->p); /* locks trn */ +	trn->info = (void *)(uintptr_t)bgp_clock(); +	if (trn->lock > 1) +		route_unlock_node(trn); + +	return 0;  }  /* @@ -882,617 +840,638 @@ rfapiRibPreloadBi(   *   * Clear pending node   */ -static void -process_pending_node ( -  struct bgp *bgp, -  struct rfapi_descriptor	*rfd, -  afi_t				afi, -  struct route_node		*pn,			/* pending node */ -  struct rfapi_next_hop_entry	**head, -  struct rfapi_next_hop_entry	**tail) +static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd, +				 afi_t afi, +				 struct route_node *pn, /* pending node */ +				 struct rfapi_next_hop_entry **head, +				 struct rfapi_next_hop_entry **tail)  { -  struct listnode		*node = NULL; -  struct listnode		*nnode = NULL; -  struct rfapi_info		*ri = NULL;		/* happy valgrind */ -  struct rfapi_ip_prefix	hp = { 0 };		/* pfx to put in NHE */ -  struct route_node		*rn = NULL; -  struct skiplist		*slRibPt = NULL;	/* rib list */ -  struct skiplist		*slPendPt = NULL; -  struct list			*lPendCost = NULL; -  struct list			*delete_list = NULL; -  int				printedprefix = 0; -  char				buf_prefix[BUFSIZ]; -  int				rib_node_started_nonempty = 0; -  int				sendingsomeroutes = 0; +	struct listnode *node = NULL; +	struct listnode *nnode = NULL; +	struct rfapi_info *ri = NULL;    /* happy valgrind */ +	struct rfapi_ip_prefix hp = {0}; /* pfx to put in NHE */ +	struct route_node *rn = NULL; +	struct skiplist *slRibPt = NULL; /* rib list */ +	struct skiplist *slPendPt = NULL; +	struct list *lPendCost = NULL; +	struct list *delete_list = NULL; +	int printedprefix = 0; +	char buf_prefix[BUFSIZ]; +	int rib_node_started_nonempty = 0; +	int sendingsomeroutes = 0;  #if DEBUG_PROCESS_PENDING_NODE -  unsigned int count_rib_initial = 0; -  unsigned int count_pend_vn_initial = 0; -  unsigned int count_pend_cost_initial = 0; +	unsigned int count_rib_initial = 0; +	unsigned int count_pend_vn_initial = 0; +	unsigned int count_pend_cost_initial = 0;  #endif -  assert (pn); -  prefix2str (&pn->p, buf_prefix, BUFSIZ); -  vnc_zlog_debug_verbose ("%s: afi=%d, %s pn->info=%p", -              __func__, afi, buf_prefix, pn->info); +	assert(pn); +	prefix2str(&pn->p, buf_prefix, BUFSIZ); +	vnc_zlog_debug_verbose("%s: afi=%d, %s pn->info=%p", __func__, afi, +			       buf_prefix, pn->info); -  if (AFI_L2VPN != afi) -    { -      rfapiQprefix2Rprefix (&pn->p, &hp); -    } +	if (AFI_L2VPN != afi) { +		rfapiQprefix2Rprefix(&pn->p, &hp); +	} -  RFAPI_RIB_CHECK_COUNTS (1, 0); +	RFAPI_RIB_CHECK_COUNTS(1, 0); -  /* -   * Find corresponding RIB node -   */ -  rn = route_node_get (rfd->rib[afi], &pn->p);  /* locks rn */ +	/* +	 * Find corresponding RIB node +	 */ +	rn = route_node_get(rfd->rib[afi], &pn->p); /* locks rn */ -  /* -   * RIB skiplist has key=rfapi_addr={vn,un}, val = rfapi_info, -   * skiplist.del = NULL -   */ -  slRibPt = (struct skiplist *) rn->info; -  if (slRibPt) -    rib_node_started_nonempty = 1; +	/* +	 * RIB skiplist has key=rfapi_addr={vn,un}, val = rfapi_info, +	 * skiplist.del = NULL +	 */ +	slRibPt = (struct skiplist *)rn->info; +	if (slRibPt) +		rib_node_started_nonempty = 1; -  slPendPt = (struct skiplist *) (pn->aggregate); -  lPendCost = (struct list *) (pn->info); +	slPendPt = (struct skiplist *)(pn->aggregate); +	lPendCost = (struct list *)(pn->info);  #if DEBUG_PROCESS_PENDING_NODE -  /* debugging */ -  if (slRibPt) -    count_rib_initial = skiplist_count (slRibPt); +	/* debugging */ +	if (slRibPt) +		count_rib_initial = skiplist_count(slRibPt); -  if (slPendPt) -    count_pend_vn_initial = skiplist_count (slPendPt); +	if (slPendPt) +		count_pend_vn_initial = skiplist_count(slPendPt); -  if (lPendCost && lPendCost != (struct list *) 1) -    count_pend_cost_initial = lPendCost->count; +	if (lPendCost && lPendCost != (struct list *)1) +		count_pend_cost_initial = lPendCost->count;  #endif -  /* -   * Handle special case: delete all routes at prefix -   */ -  if (lPendCost == (struct list *) 1) -    { -      vnc_zlog_debug_verbose ("%s: lPendCost=1 => delete all", __func__); -      if (slRibPt && !skiplist_empty (slRibPt)) -        { -          delete_list = list_new (); -          while (0 == skiplist_first (slRibPt, NULL, (void **) &ri)) -            { - -              char buf[BUFSIZ]; -              char buf2[BUFSIZ]; - -              listnode_add (delete_list, ri); -              vnc_zlog_debug_verbose ("%s: after listnode_add, delete_list->count=%d", -                          __func__, delete_list->count); -              rfapiFreeBgpTeaOptionChain (ri->tea_options); -              ri->tea_options = NULL; - -              if (ri->timer) -                { -                  struct rfapi_rib_tcb *tcb; - -                  tcb = ((struct thread *) ri->timer)->arg; -                  thread_cancel (ri->timer); -                  XFREE (MTYPE_RFAPI_RECENT_DELETE, tcb); -                  ri->timer = NULL; -                } - -              prefix2str (&ri->rk.vn, buf, BUFSIZ); -              prefix2str (&ri->un, buf2, BUFSIZ); -              vnc_zlog_debug_verbose -                ("%s:   put dl pfx=%s vn=%s un=%s cost=%d life=%d vn_options=%p", -                 __func__, buf_prefix, buf, buf2, ri->cost, ri->lifetime, -                 ri->vn_options); - -              skiplist_delete_first (slRibPt); -            } - -          assert (skiplist_empty (slRibPt)); - -          skiplist_free (slRibPt); -          rn->info = slRibPt = NULL; -          route_unlock_node (rn); - -          lPendCost = pn->info = NULL; -          route_unlock_node (pn); - -          goto callback; -        } -      if (slRibPt) -        { -          skiplist_free (slRibPt); -          rn->info = NULL; -          route_unlock_node (rn); -        } - -      assert (!slPendPt); -      if (slPendPt) -        {                       /* TBD I think we can toss this block */ -          skiplist_free (slPendPt); -          pn->aggregate = NULL; -          route_unlock_node (pn); -        } - -      pn->info = NULL; -      route_unlock_node (pn); - -      route_unlock_node (rn);   /* route_node_get() */ - -      if (rib_node_started_nonempty) -        { -          RFAPI_RIB_PREFIX_COUNT_DECR (rfd, bgp->rfapi); -        } - -      RFAPI_RIB_CHECK_COUNTS (1, 0); - -      return; -    } - -  vnc_zlog_debug_verbose ("%s:   lPendCost->count=%d, slRibPt->count=%d", -              __func__, -              (lPendCost ? (int) lPendCost->count : -1), -              (slRibPt ? (int) slRibPt->count : -1)); - -  /* -   * Iterate over routes at RIB Node. -   * If not found at Pending Node, delete from RIB Node and add to deletelist -   * If found at Pending Node -   *      If identical rfapi_info, delete from Pending Node -   */ -  if (slRibPt) -    { -      void *cursor = NULL; -      struct rfapi_info *ori; - -      /* -       * Iterate over RIB List -       * -       */ -      while (!skiplist_next (slRibPt, NULL, (void **) &ori, &cursor)) -        { - -          if (skiplist_search (slPendPt, &ori->rk, (void **) &ri)) -            { -              /* -               * Not in Pending list, so it should be deleted -               */ -              if (!delete_list) -                delete_list = list_new (); -              listnode_add (delete_list, ori); -              rfapiFreeBgpTeaOptionChain (ori->tea_options); -              ori->tea_options = NULL; -              if (ori->timer) -                { -                  struct rfapi_rib_tcb *tcb; - -                  tcb = ((struct thread *) ori->timer)->arg; -                  thread_cancel (ori->timer); -                  XFREE (MTYPE_RFAPI_RECENT_DELETE, tcb); -                  ori->timer = NULL; -                } +	/* +	 * Handle special case: delete all routes at prefix +	 */ +	if (lPendCost == (struct list *)1) { +		vnc_zlog_debug_verbose("%s: lPendCost=1 => delete all", +				       __func__); +		if (slRibPt && !skiplist_empty(slRibPt)) { +			delete_list = list_new(); +			while (0 +			       == skiplist_first(slRibPt, NULL, (void **)&ri)) { + +				char buf[BUFSIZ]; +				char buf2[BUFSIZ]; + +				listnode_add(delete_list, ri); +				vnc_zlog_debug_verbose( +					"%s: after listnode_add, delete_list->count=%d", +					__func__, delete_list->count); +				rfapiFreeBgpTeaOptionChain(ri->tea_options); +				ri->tea_options = NULL; + +				if (ri->timer) { +					struct rfapi_rib_tcb *tcb; + +					tcb = ((struct thread *)ri->timer)->arg; +					thread_cancel(ri->timer); +					XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb); +					ri->timer = NULL; +				} + +				prefix2str(&ri->rk.vn, buf, BUFSIZ); +				prefix2str(&ri->un, buf2, BUFSIZ); +				vnc_zlog_debug_verbose( +					"%s:   put dl pfx=%s vn=%s un=%s cost=%d life=%d vn_options=%p", +					__func__, buf_prefix, buf, buf2, +					ri->cost, ri->lifetime, ri->vn_options); + +				skiplist_delete_first(slRibPt); +			} + +			assert(skiplist_empty(slRibPt)); + +			skiplist_free(slRibPt); +			rn->info = slRibPt = NULL; +			route_unlock_node(rn); + +			lPendCost = pn->info = NULL; +			route_unlock_node(pn); + +			goto callback; +		} +		if (slRibPt) { +			skiplist_free(slRibPt); +			rn->info = NULL; +			route_unlock_node(rn); +		} + +		assert(!slPendPt); +		if (slPendPt) { /* TBD I think we can toss this block */ +			skiplist_free(slPendPt); +			pn->aggregate = NULL; +			route_unlock_node(pn); +		} + +		pn->info = NULL; +		route_unlock_node(pn); + +		route_unlock_node(rn); /* route_node_get() */ + +		if (rib_node_started_nonempty) { +			RFAPI_RIB_PREFIX_COUNT_DECR(rfd, bgp->rfapi); +		} + +		RFAPI_RIB_CHECK_COUNTS(1, 0); + +		return; +	} + +	vnc_zlog_debug_verbose("%s:   lPendCost->count=%d, slRibPt->count=%d", +			       __func__, +			       (lPendCost ? (int)lPendCost->count : -1), +			       (slRibPt ? (int)slRibPt->count : -1)); + +	/* +	 * Iterate over routes at RIB Node. +	 * If not found at Pending Node, delete from RIB Node and add to +	 * deletelist +	 * If found at Pending Node +	 *      If identical rfapi_info, delete from Pending Node +	 */ +	if (slRibPt) { +		void *cursor = NULL; +		struct rfapi_info *ori; + +		/* +		 * Iterate over RIB List +		 * +		 */ +		while (!skiplist_next(slRibPt, NULL, (void **)&ori, &cursor)) { + +			if (skiplist_search(slPendPt, &ori->rk, (void **)&ri)) { +				/* +				 * Not in Pending list, so it should be deleted +				 */ +				if (!delete_list) +					delete_list = list_new(); +				listnode_add(delete_list, ori); +				rfapiFreeBgpTeaOptionChain(ori->tea_options); +				ori->tea_options = NULL; +				if (ori->timer) { +					struct rfapi_rib_tcb *tcb; + +					tcb = ((struct thread *)ori->timer) +						      ->arg; +					thread_cancel(ori->timer); +					XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb); +					ori->timer = NULL; +				}  #if DEBUG_PROCESS_PENDING_NODE -              /* deleted from slRibPt below, after we're done iterating */ -              vnc_zlog_debug_verbose -                ("%s:   slRibPt ri %p not matched in pending list, delete", -                 __func__, ori); +				/* deleted from slRibPt below, after we're done +				 * iterating */ +				vnc_zlog_debug_verbose( +					"%s:   slRibPt ri %p not matched in pending list, delete", +					__func__, ori);  #endif -            } -          else -            { -              /* -               * Found in pending list. If same lifetime, cost, options, -               * then remove from pending list because the route -               * hasn't changed. -               */ -              if (!rfapi_info_cmp (ori, ri)) -                { -                  skiplist_delete (slPendPt, &ri->rk, NULL); -                  assert (lPendCost); -                  if (lPendCost) -                    { -                      /* linear walk: might need optimization */ -                      listnode_delete (lPendCost, ri);  /* XXX doesn't free data! bug? */ -                      rfapi_info_free (ri);     /* grr... */ -                    } -                } +			} else { +				/* +				 * Found in pending list. If same lifetime, +				 * cost, options, +				 * then remove from pending list because the +				 * route +				 * hasn't changed. +				 */ +				if (!rfapi_info_cmp(ori, ri)) { +					skiplist_delete(slPendPt, &ri->rk, +							NULL); +					assert(lPendCost); +					if (lPendCost) { +						/* linear walk: might need +						 * optimization */ +						listnode_delete(lPendCost, +								ri); /* XXX +									doesn't +									free +									data! +									bug? */ +						rfapi_info_free( +							ri); /* grr... */ +					} +				}  #if DEBUG_PROCESS_PENDING_NODE -              vnc_zlog_debug_verbose ("%s:   slRibPt ri %p matched in pending list, %s", -                          __func__, ori, -                          (same ? "same info" : "different info")); +				vnc_zlog_debug_verbose( +					"%s:   slRibPt ri %p matched in pending list, %s", +					__func__, ori, +					(same ? "same info" +					      : "different info"));  #endif -            } -        } -      /* -       * Go back and delete items from RIB -       */ -      if (delete_list) -        { -          for (ALL_LIST_ELEMENTS_RO (delete_list, node, ri)) -            { -              vnc_zlog_debug_verbose ("%s:   deleting ri %p from slRibPt", __func__, ri); -              assert (!skiplist_delete (slRibPt, &ri->rk, NULL)); -            } -          if (skiplist_empty (slRibPt)) -            { -              skiplist_free (slRibPt); -              slRibPt = rn->info = NULL; -              route_unlock_node (rn); -            } -        } -    } - -  RFAPI_RIB_CHECK_COUNTS (0, (delete_list ? delete_list->count : 0)); - -  /* -   * Iterate over routes at Pending Node -   * -   * If {vn} found at RIB Node, update RIB Node route contents to match PN -   * If {vn} NOT found at RIB Node, add copy to RIB Node -   */ -  if (lPendCost) -    { -      for (ALL_LIST_ELEMENTS_RO (lPendCost, node, ri)) -        { - -          struct rfapi_info *ori; - -          if (slRibPt && !skiplist_search (slRibPt, &ri->rk, (void **) &ori)) -            { - -              /* found: update contents of existing route in RIB */ -              ori->un = ri->un; -              ori->cost = ri->cost; -              ori->lifetime = ri->lifetime; -              rfapiFreeBgpTeaOptionChain (ori->tea_options); -              ori->tea_options = rfapiOptionsDup (ri->tea_options); -              ori->last_sent_time = rfapi_time (NULL); - -              rfapiFreeRfapiVnOptionChain (ori->vn_options); -              ori->vn_options = rfapiVnOptionsDup (ri->vn_options); - -              rfapiFreeRfapiUnOptionChain (ori->un_options); -              ori->un_options = rfapiUnOptionsDup (ri->un_options); - -              vnc_zlog_debug_verbose -                ("%s:   matched lPendCost item %p in slRibPt, rewrote", -                 __func__, ri); - -            } -          else -            { - -	      char	buf_rd[BUFSIZ]; - -              /* not found: add new route to RIB */ -              ori = rfapi_info_new (); -              ori->rk = ri->rk; -              ori->un = ri->un; -              ori->cost = ri->cost; -              ori->lifetime = ri->lifetime; -              ori->tea_options = rfapiOptionsDup (ri->tea_options); -              ori->last_sent_time = rfapi_time (NULL); -              ori->vn_options = rfapiVnOptionsDup (ri->vn_options); -              ori->un_options = rfapiUnOptionsDup (ri->un_options); - -              if (!slRibPt) -                { -                  slRibPt = skiplist_new (0, rfapi_rib_key_cmp, NULL); -                  rn->info = slRibPt; -                  route_lock_node (rn); -                } -              skiplist_insert (slRibPt, &ori->rk, ori); +			} +		} +		/* +		 * Go back and delete items from RIB +		 */ +		if (delete_list) { +			for (ALL_LIST_ELEMENTS_RO(delete_list, node, ri)) { +				vnc_zlog_debug_verbose( +					"%s:   deleting ri %p from slRibPt", +					__func__, ri); +				assert(!skiplist_delete(slRibPt, &ri->rk, +							NULL)); +			} +			if (skiplist_empty(slRibPt)) { +				skiplist_free(slRibPt); +				slRibPt = rn->info = NULL; +				route_unlock_node(rn); +			} +		} +	} + +	RFAPI_RIB_CHECK_COUNTS(0, (delete_list ? delete_list->count : 0)); + +	/* +	 * Iterate over routes at Pending Node +	 * +	 * If {vn} found at RIB Node, update RIB Node route contents to match PN +	 * If {vn} NOT found at RIB Node, add copy to RIB Node +	 */ +	if (lPendCost) { +		for (ALL_LIST_ELEMENTS_RO(lPendCost, node, ri)) { + +			struct rfapi_info *ori; + +			if (slRibPt +			    && !skiplist_search(slRibPt, &ri->rk, +						(void **)&ori)) { + +				/* found: update contents of existing route in +				 * RIB */ +				ori->un = ri->un; +				ori->cost = ri->cost; +				ori->lifetime = ri->lifetime; +				rfapiFreeBgpTeaOptionChain(ori->tea_options); +				ori->tea_options = +					rfapiOptionsDup(ri->tea_options); +				ori->last_sent_time = rfapi_time(NULL); + +				rfapiFreeRfapiVnOptionChain(ori->vn_options); +				ori->vn_options = +					rfapiVnOptionsDup(ri->vn_options); + +				rfapiFreeRfapiUnOptionChain(ori->un_options); +				ori->un_options = +					rfapiUnOptionsDup(ri->un_options); + +				vnc_zlog_debug_verbose( +					"%s:   matched lPendCost item %p in slRibPt, rewrote", +					__func__, ri); + +			} else { + +				char buf_rd[BUFSIZ]; + +				/* not found: add new route to RIB */ +				ori = rfapi_info_new(); +				ori->rk = ri->rk; +				ori->un = ri->un; +				ori->cost = ri->cost; +				ori->lifetime = ri->lifetime; +				ori->tea_options = +					rfapiOptionsDup(ri->tea_options); +				ori->last_sent_time = rfapi_time(NULL); +				ori->vn_options = +					rfapiVnOptionsDup(ri->vn_options); +				ori->un_options = +					rfapiUnOptionsDup(ri->un_options); + +				if (!slRibPt) { +					slRibPt = skiplist_new( +						0, rfapi_rib_key_cmp, NULL); +					rn->info = slRibPt; +					route_lock_node(rn); +				} +				skiplist_insert(slRibPt, &ori->rk, ori);  #if DEBUG_RIB_SL_RD -	      prefix_rd2str(&ori->rk.rd, buf_rd, sizeof(buf_rd)); +				prefix_rd2str(&ori->rk.rd, buf_rd, +					      sizeof(buf_rd));  #else -	      buf_rd[0] = 0; +				buf_rd[0] = 0;  #endif -              vnc_zlog_debug_verbose ("%s:   nomatch lPendCost item %p in slRibPt, added (rd=%s)", -                          __func__, ri, buf_rd); -            } - -          /* -           * poke timer -           */ -          RFAPI_RIB_CHECK_COUNTS (0, (delete_list ? delete_list->count : 0)); -          rfapiRibStartTimer (rfd, ori, rn, 0); -          RFAPI_RIB_CHECK_COUNTS (0, (delete_list ? delete_list->count : 0)); -        } -    } +				vnc_zlog_debug_verbose( +					"%s:   nomatch lPendCost item %p in slRibPt, added (rd=%s)", +					__func__, ri, buf_rd); +			} + +			/* +			 * poke timer +			 */ +			RFAPI_RIB_CHECK_COUNTS( +				0, (delete_list ? delete_list->count : 0)); +			rfapiRibStartTimer(rfd, ori, rn, 0); +			RFAPI_RIB_CHECK_COUNTS( +				0, (delete_list ? delete_list->count : 0)); +		} +	}  callback: -  /* -   * Construct NHL as concatenation of pending list + delete list -   */ - - -  RFAPI_RIB_CHECK_COUNTS (0, (delete_list ? delete_list->count : 0)); - -  if (lPendCost) -    { - -      char buf[BUFSIZ]; -      char buf2[BUFSIZ]; - -      vnc_zlog_debug_verbose ("%s: lPendCost->count now %d", __func__, lPendCost->count); -      vnc_zlog_debug_verbose ("%s: For prefix %s (a)", __func__, buf_prefix); -      printedprefix = 1; - -      for (ALL_LIST_ELEMENTS (lPendCost, node, nnode, ri)) -        { - -          struct rfapi_next_hop_entry *new; -          struct route_node *trn; - -          new = -            XCALLOC (MTYPE_RFAPI_NEXTHOP, -                     sizeof (struct rfapi_next_hop_entry)); -          assert (new); - -          if (ri->rk.aux_prefix.family) -            { -              rfapiQprefix2Rprefix (&ri->rk.aux_prefix, &new->prefix); -            } -          else -            { -              new->prefix = hp; -              if (AFI_L2VPN == afi) -                { -                  /* hp is 0; need to set length to match AF of vn */ -                  new->prefix.length = -                    (ri->rk.vn.family == AF_INET) ? 32 : 128; -                } -            } -          new->prefix.cost = ri->cost; -          new->lifetime = ri->lifetime; -          rfapiQprefix2Raddr (&ri->rk.vn, &new->vn_address); -          rfapiQprefix2Raddr (&ri->un, &new->un_address); -          /* free option chain from ri */ -          rfapiFreeBgpTeaOptionChain (ri->tea_options); - -          ri->tea_options = NULL;	/* option chain was transferred to NHL */ - -          new->vn_options = ri->vn_options; -          ri->vn_options = NULL;        /* option chain was transferred to NHL */ - -          new->un_options = ri->un_options; -          ri->un_options = NULL;        /* option chain was transferred to NHL */ - -          if (*tail) -            (*tail)->next = new; -          *tail = new; -          if (!*head) -            { -              *head = new; -            } -          sendingsomeroutes = 1; - -          ++rfd->stat_count_nh_reachable; -          ++bgp->rfapi->stat.count_updated_response_updates; - -          /* -           * update this NVE's timestamp for this prefix -           */ -          trn = route_node_get (rfd->rsp_times[afi], &pn->p);   /* locks trn */ -          trn->info = (void *) (uintptr_t) bgp_clock (); -          if (trn->lock > 1) -            route_unlock_node (trn); - -          rfapiRfapiIpAddr2Str (&new->vn_address, buf, BUFSIZ); -          rfapiRfapiIpAddr2Str (&new->un_address, buf2, BUFSIZ); -          vnc_zlog_debug_verbose ("%s:   add vn=%s un=%s cost=%d life=%d", __func__, -                      buf, buf2, new->prefix.cost, new->lifetime); -        } -    } - -  RFAPI_RIB_CHECK_COUNTS (0, (delete_list ? delete_list->count : 0)); - -  if (delete_list) -    { - -      char buf[BUFSIZ]; -      char buf2[BUFSIZ]; - -      if (!printedprefix) -        { -          vnc_zlog_debug_verbose ("%s: For prefix %s (d)", __func__, buf_prefix); -        } -      vnc_zlog_debug_verbose ("%s: delete_list has %d elements", -                  __func__, delete_list->count); - -      RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); -      if (!CHECK_FLAG (bgp->rfapi_cfg->flags, -                       BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE)) -        { - -          for (ALL_LIST_ELEMENTS (delete_list, node, nnode, ri)) -            { - -              struct rfapi_next_hop_entry *new; -              struct rfapi_info *ri_del; - -              RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); -              new = XCALLOC (MTYPE_RFAPI_NEXTHOP, -                             sizeof (struct rfapi_next_hop_entry)); -              assert (new); - -              if (ri->rk.aux_prefix.family) -                { -                  rfapiQprefix2Rprefix (&ri->rk.aux_prefix, &new->prefix); -                } -              else -                { -                  new->prefix = hp; -                  if (AFI_L2VPN == afi) -                    { -                      /* hp is 0; need to set length to match AF of vn */ -                      new->prefix.length = -                        (ri->rk.vn.family == AF_INET) ? 32 : 128; -                    } -                } - -              new->prefix.cost = ri->cost; -              new->lifetime = RFAPI_REMOVE_RESPONSE_LIFETIME; -              rfapiQprefix2Raddr (&ri->rk.vn, &new->vn_address); -              rfapiQprefix2Raddr (&ri->un, &new->un_address); - -              new->vn_options = ri->vn_options; -              ri->vn_options = NULL;    /* option chain was transferred to NHL */ - -              new->un_options = ri->un_options; -              ri->un_options = NULL;    /* option chain was transferred to NHL */ - -              if (*tail) -                (*tail)->next = new; -              *tail = new; -              if (!*head) -                { -                  *head = new; -                } -              ++rfd->stat_count_nh_removal; -              ++bgp->rfapi->stat.count_updated_response_deletes; - -              rfapiRfapiIpAddr2Str (&new->vn_address, buf, BUFSIZ); -              rfapiRfapiIpAddr2Str (&new->un_address, buf2, BUFSIZ); -              vnc_zlog_debug_verbose ("%s:   DEL vn=%s un=%s cost=%d life=%d", __func__, -                          buf, buf2, new->prefix.cost, new->lifetime); - -              RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); -              /* -               * Update/add to list of recent deletions at this prefix -               */ -              if (!rn->aggregate) -                { -                  rn->aggregate = skiplist_new (0, rfapi_rib_key_cmp, -                                                (void (*)(void *)) -                                                rfapi_info_free); -                  route_lock_node (rn); -                } -              RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); - -              /* sanity check lifetime */ -              if (ri->lifetime > RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY) -                ri->lifetime = RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY; - -              RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); -              /* cancel normal expire timer */ -              if (ri->timer) -                { -                  struct rfapi_rib_tcb *tcb; - -                  tcb = ((struct thread *) ri->timer)->arg; -                  thread_cancel ((struct thread *) ri->timer); -                  XFREE (MTYPE_RFAPI_RECENT_DELETE, tcb); -                  ri->timer = NULL; -                } -              RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); - -              /* -               * Look in "recently-deleted" list -               */ -              if (skiplist_search ((struct skiplist *) (rn->aggregate), -                                   &ri->rk, (void **) &ri_del)) -                { - -                  int rc; - -                  RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); -                  /* -                   * NOT in "recently-deleted" list -                   */ -                  list_delete_node (delete_list, node); /* does not free ri */ -                  rc = skiplist_insert ((struct skiplist *) (rn->aggregate), -                                        &ri->rk, ri); -                  assert (!rc); - -                  RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); -                  rfapiRibStartTimer (rfd, ri, rn, 1); -                  RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); -                  ri->last_sent_time = rfapi_time (NULL); +	/* +	 * Construct NHL as concatenation of pending list + delete list +	 */ + + +	RFAPI_RIB_CHECK_COUNTS(0, (delete_list ? delete_list->count : 0)); + +	if (lPendCost) { + +		char buf[BUFSIZ]; +		char buf2[BUFSIZ]; + +		vnc_zlog_debug_verbose("%s: lPendCost->count now %d", __func__, +				       lPendCost->count); +		vnc_zlog_debug_verbose("%s: For prefix %s (a)", __func__, +				       buf_prefix); +		printedprefix = 1; + +		for (ALL_LIST_ELEMENTS(lPendCost, node, nnode, ri)) { + +			struct rfapi_next_hop_entry *new; +			struct route_node *trn; + +			new = XCALLOC(MTYPE_RFAPI_NEXTHOP, +				      sizeof(struct rfapi_next_hop_entry)); +			assert(new); + +			if (ri->rk.aux_prefix.family) { +				rfapiQprefix2Rprefix(&ri->rk.aux_prefix, +						     &new->prefix); +			} else { +				new->prefix = hp; +				if (AFI_L2VPN == afi) { +					/* hp is 0; need to set length to match +					 * AF of vn */ +					new->prefix.length = +						(ri->rk.vn.family == AF_INET) +							? 32 +							: 128; +				} +			} +			new->prefix.cost = ri->cost; +			new->lifetime = ri->lifetime; +			rfapiQprefix2Raddr(&ri->rk.vn, &new->vn_address); +			rfapiQprefix2Raddr(&ri->un, &new->un_address); +			/* free option chain from ri */ +			rfapiFreeBgpTeaOptionChain(ri->tea_options); + +			ri->tea_options = +				NULL; /* option chain was transferred to NHL */ + +			new->vn_options = ri->vn_options; +			ri->vn_options = +				NULL; /* option chain was transferred to NHL */ + +			new->un_options = ri->un_options; +			ri->un_options = +				NULL; /* option chain was transferred to NHL */ + +			if (*tail) +				(*tail)->next = new; +			*tail = new; +			if (!*head) { +				*head = new; +			} +			sendingsomeroutes = 1; + +			++rfd->stat_count_nh_reachable; +			++bgp->rfapi->stat.count_updated_response_updates; + +			/* +			 * update this NVE's timestamp for this prefix +			 */ +			trn = route_node_get(rfd->rsp_times[afi], +					     &pn->p); /* locks trn */ +			trn->info = (void *)(uintptr_t)bgp_clock(); +			if (trn->lock > 1) +				route_unlock_node(trn); + +			rfapiRfapiIpAddr2Str(&new->vn_address, buf, BUFSIZ); +			rfapiRfapiIpAddr2Str(&new->un_address, buf2, BUFSIZ); +			vnc_zlog_debug_verbose( +				"%s:   add vn=%s un=%s cost=%d life=%d", +				__func__, buf, buf2, new->prefix.cost, +				new->lifetime); +		} +	} + +	RFAPI_RIB_CHECK_COUNTS(0, (delete_list ? delete_list->count : 0)); + +	if (delete_list) { + +		char buf[BUFSIZ]; +		char buf2[BUFSIZ]; + +		if (!printedprefix) { +			vnc_zlog_debug_verbose("%s: For prefix %s (d)", +					       __func__, buf_prefix); +		} +		vnc_zlog_debug_verbose("%s: delete_list has %d elements", +				       __func__, delete_list->count); + +		RFAPI_RIB_CHECK_COUNTS(0, delete_list->count); +		if (!CHECK_FLAG(bgp->rfapi_cfg->flags, +				BGP_VNC_CONFIG_RESPONSE_REMOVAL_DISABLE)) { + +			for (ALL_LIST_ELEMENTS(delete_list, node, nnode, ri)) { + +				struct rfapi_next_hop_entry *new; +				struct rfapi_info *ri_del; + +				RFAPI_RIB_CHECK_COUNTS(0, delete_list->count); +				new = XCALLOC( +					MTYPE_RFAPI_NEXTHOP, +					sizeof(struct rfapi_next_hop_entry)); +				assert(new); + +				if (ri->rk.aux_prefix.family) { +					rfapiQprefix2Rprefix(&ri->rk.aux_prefix, +							     &new->prefix); +				} else { +					new->prefix = hp; +					if (AFI_L2VPN == afi) { +						/* hp is 0; need to set length +						 * to match AF of vn */ +						new->prefix.length = +							(ri->rk.vn.family +							 == AF_INET) +								? 32 +								: 128; +					} +				} + +				new->prefix.cost = ri->cost; +				new->lifetime = RFAPI_REMOVE_RESPONSE_LIFETIME; +				rfapiQprefix2Raddr(&ri->rk.vn, +						   &new->vn_address); +				rfapiQprefix2Raddr(&ri->un, &new->un_address); + +				new->vn_options = ri->vn_options; +				ri->vn_options = NULL; /* option chain was +							  transferred to NHL */ + +				new->un_options = ri->un_options; +				ri->un_options = NULL; /* option chain was +							  transferred to NHL */ + +				if (*tail) +					(*tail)->next = new; +				*tail = new; +				if (!*head) { +					*head = new; +				} +				++rfd->stat_count_nh_removal; +				++bgp->rfapi->stat +					  .count_updated_response_deletes; + +				rfapiRfapiIpAddr2Str(&new->vn_address, buf, +						     BUFSIZ); +				rfapiRfapiIpAddr2Str(&new->un_address, buf2, +						     BUFSIZ); +				vnc_zlog_debug_verbose( +					"%s:   DEL vn=%s un=%s cost=%d life=%d", +					__func__, buf, buf2, new->prefix.cost, +					new->lifetime); + +				RFAPI_RIB_CHECK_COUNTS(0, delete_list->count); +				/* +				 * Update/add to list of recent deletions at +				 * this prefix +				 */ +				if (!rn->aggregate) { +					rn->aggregate = skiplist_new( +						0, rfapi_rib_key_cmp, +						(void (*)(void *)) +							rfapi_info_free); +					route_lock_node(rn); +				} +				RFAPI_RIB_CHECK_COUNTS(0, delete_list->count); + +				/* sanity check lifetime */ +				if (ri->lifetime +				    > RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY) +					ri->lifetime = +						RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY; + +				RFAPI_RIB_CHECK_COUNTS(0, delete_list->count); +				/* cancel normal expire timer */ +				if (ri->timer) { +					struct rfapi_rib_tcb *tcb; + +					tcb = ((struct thread *)ri->timer)->arg; +					thread_cancel( +						(struct thread *)ri->timer); +					XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb); +					ri->timer = NULL; +				} +				RFAPI_RIB_CHECK_COUNTS(0, delete_list->count); + +				/* +				 * Look in "recently-deleted" list +				 */ +				if (skiplist_search( +					    (struct skiplist *)(rn->aggregate), +					    &ri->rk, (void **)&ri_del)) { + +					int rc; + +					RFAPI_RIB_CHECK_COUNTS( +						0, delete_list->count); +					/* +					 * NOT in "recently-deleted" list +					 */ +					list_delete_node( +						delete_list, +						node); /* does not free ri */ +					rc = skiplist_insert( +						(struct skiplist +							 *)(rn->aggregate), +						&ri->rk, ri); +					assert(!rc); + +					RFAPI_RIB_CHECK_COUNTS( +						0, delete_list->count); +					rfapiRibStartTimer(rfd, ri, rn, 1); +					RFAPI_RIB_CHECK_COUNTS( +						0, delete_list->count); +					ri->last_sent_time = rfapi_time(NULL);  #if DEBUG_RIB_SL_RD -		  { -		    char buf_rd[BUFSIZ]; -		    prefix_rd2str(&ri->rk.rd, buf_rd, sizeof(buf_rd)); -		    vnc_zlog_debug_verbose("%s: move route to recently deleted list, rd=%s", -			__func__, buf_rd); -		  } +					{ +						char buf_rd[BUFSIZ]; +						prefix_rd2str(&ri->rk.rd, +							      buf_rd, +							      sizeof(buf_rd)); +						vnc_zlog_debug_verbose( +							"%s: move route to recently deleted list, rd=%s", +							__func__, buf_rd); +					}  #endif -                } -              else -                { -                  /* -                   * IN "recently-deleted" list -                   */ -                  RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); -                  rfapiRibStartTimer (rfd, ri_del, rn, 1); -                  RFAPI_RIB_CHECK_COUNTS (0, delete_list->count); -                  ri->last_sent_time = rfapi_time (NULL); - -                } -            } -        } -      else -        { -          vnc_zlog_debug_verbose ("%s: response removal disabled, omitting removals", -                      __func__); -        } - -      delete_list->del = (void (*)(void *)) rfapi_info_free; -      list_delete (delete_list); -    } - -  RFAPI_RIB_CHECK_COUNTS (0, 0); - -  /* -   * Reset pending lists. The final route_unlock_node() will probably -   * cause the pending node to be released. -   */ -  if (slPendPt) -    { -      skiplist_free (slPendPt); -      pn->aggregate = NULL; -      route_unlock_node (pn); -    } -  if (lPendCost) -    { -      list_delete (lPendCost); -      pn->info = NULL; -      route_unlock_node (pn); -    } -  RFAPI_RIB_CHECK_COUNTS (0, 0); - -  if (rib_node_started_nonempty) -    { -      if (!rn->info) -        { -          RFAPI_RIB_PREFIX_COUNT_DECR (rfd, bgp->rfapi); -        } -    } -  else -    { -      if (rn->info) -        { -          RFAPI_RIB_PREFIX_COUNT_INCR (rfd, bgp->rfapi); -        } -    } - -  if (sendingsomeroutes) -    rfapiMonitorTimersRestart (rfd, &pn->p); - -  route_unlock_node (rn);       /* route_node_get() */ - -  RFAPI_RIB_CHECK_COUNTS (1, 0); +				} else { +					/* +					 * IN "recently-deleted" list +					 */ +					RFAPI_RIB_CHECK_COUNTS( +						0, delete_list->count); +					rfapiRibStartTimer(rfd, ri_del, rn, 1); +					RFAPI_RIB_CHECK_COUNTS( +						0, delete_list->count); +					ri->last_sent_time = rfapi_time(NULL); +				} +			} +		} else { +			vnc_zlog_debug_verbose( +				"%s: response removal disabled, omitting removals", +				__func__); +		} + +		delete_list->del = (void (*)(void *))rfapi_info_free; +		list_delete(delete_list); +	} + +	RFAPI_RIB_CHECK_COUNTS(0, 0); + +	/* +	 * Reset pending lists. The final route_unlock_node() will probably +	 * cause the pending node to be released. +	 */ +	if (slPendPt) { +		skiplist_free(slPendPt); +		pn->aggregate = NULL; +		route_unlock_node(pn); +	} +	if (lPendCost) { +		list_delete(lPendCost); +		pn->info = NULL; +		route_unlock_node(pn); +	} +	RFAPI_RIB_CHECK_COUNTS(0, 0); + +	if (rib_node_started_nonempty) { +		if (!rn->info) { +			RFAPI_RIB_PREFIX_COUNT_DECR(rfd, bgp->rfapi); +		} +	} else { +		if (rn->info) { +			RFAPI_RIB_PREFIX_COUNT_INCR(rfd, bgp->rfapi); +		} +	} + +	if (sendingsomeroutes) +		rfapiMonitorTimersRestart(rfd, &pn->p); + +	route_unlock_node(rn); /* route_node_get() */ + +	RFAPI_RIB_CHECK_COUNTS(1, 0);  }  /* @@ -1503,97 +1482,95 @@ callback:   * Do callback   *   */ -static void -rib_do_callback_onepass (struct rfapi_descriptor *rfd, afi_t afi) +static void rib_do_callback_onepass(struct rfapi_descriptor *rfd, afi_t afi)  { -  struct bgp *bgp = bgp_get_default (); -  struct rfapi_next_hop_entry *head = NULL; -  struct rfapi_next_hop_entry *tail = NULL; -  struct route_node *rn; +	struct bgp *bgp = bgp_get_default(); +	struct rfapi_next_hop_entry *head = NULL; +	struct rfapi_next_hop_entry *tail = NULL; +	struct route_node *rn;  #if DEBUG_L2_EXTRA -  vnc_zlog_debug_verbose ("%s: rfd=%p, afi=%d", __func__, rfd, afi); +	vnc_zlog_debug_verbose("%s: rfd=%p, afi=%d", __func__, rfd, afi);  #endif -  if (!rfd->rib_pending[afi]) -    return; +	if (!rfd->rib_pending[afi]) +		return; -  assert (bgp->rfapi); +	assert(bgp->rfapi); -  for (rn = route_top (rfd->rib_pending[afi]); rn; rn = route_next (rn)) -    { -      process_pending_node (bgp, rfd, afi, rn, &head, &tail); -    } +	for (rn = route_top(rfd->rib_pending[afi]); rn; rn = route_next(rn)) { +		process_pending_node(bgp, rfd, afi, rn, &head, &tail); +	} -  if (head) -    { -      rfapi_response_cb_t *f; +	if (head) { +		rfapi_response_cb_t *f;  #if DEBUG_NHL -      vnc_zlog_debug_verbose ("%s: response callback NHL follows:", __func__); -      rfapiPrintNhl (NULL, head); +		vnc_zlog_debug_verbose("%s: response callback NHL follows:", +				       __func__); +		rfapiPrintNhl(NULL, head);  #endif -      if (rfd->response_cb) -        f = rfd->response_cb; -      else -        f = bgp->rfapi->rfp_methods.response_cb; - -      bgp->rfapi->flags |= RFAPI_INCALLBACK; -      vnc_zlog_debug_verbose ("%s: invoking updated response callback", __func__); -      (*f) (head, rfd->cookie); -      bgp->rfapi->flags &= ~RFAPI_INCALLBACK; -      ++bgp->rfapi->response_updated_count; -    } +		if (rfd->response_cb) +			f = rfd->response_cb; +		else +			f = bgp->rfapi->rfp_methods.response_cb; + +		bgp->rfapi->flags |= RFAPI_INCALLBACK; +		vnc_zlog_debug_verbose("%s: invoking updated response callback", +				       __func__); +		(*f)(head, rfd->cookie); +		bgp->rfapi->flags &= ~RFAPI_INCALLBACK; +		++bgp->rfapi->response_updated_count; +	}  } -static wq_item_status -rfapiRibDoQueuedCallback (struct work_queue *wq, void *data) +static wq_item_status rfapiRibDoQueuedCallback(struct work_queue *wq, +					       void *data)  { -  struct rfapi_descriptor *rfd; -  afi_t afi; -  uint32_t queued_flag; +	struct rfapi_descriptor *rfd; +	afi_t afi; +	uint32_t queued_flag; -  RFAPI_RIB_CHECK_COUNTS (1, 0); +	RFAPI_RIB_CHECK_COUNTS(1, 0); -  rfd = ((struct rfapi_updated_responses_queue *) data)->rfd; -  afi = ((struct rfapi_updated_responses_queue *) data)->afi; +	rfd = ((struct rfapi_updated_responses_queue *)data)->rfd; +	afi = ((struct rfapi_updated_responses_queue *)data)->afi; -  /* Make sure the HD wasn't closed after the work item was scheduled */ -  if (rfapi_check (rfd)) -    return WQ_SUCCESS; +	/* Make sure the HD wasn't closed after the work item was scheduled */ +	if (rfapi_check(rfd)) +		return WQ_SUCCESS; -  rib_do_callback_onepass (rfd, afi); +	rib_do_callback_onepass(rfd, afi); -  queued_flag = RFAPI_QUEUED_FLAG (afi); +	queued_flag = RFAPI_QUEUED_FLAG(afi); -  UNSET_FLAG (rfd->flags, queued_flag); +	UNSET_FLAG(rfd->flags, queued_flag); -  RFAPI_RIB_CHECK_COUNTS (1, 0); +	RFAPI_RIB_CHECK_COUNTS(1, 0); -  return WQ_SUCCESS; +	return WQ_SUCCESS;  } -static void -rfapiRibQueueItemDelete (struct work_queue *wq, void *data) +static void rfapiRibQueueItemDelete(struct work_queue *wq, void *data)  { -  XFREE (MTYPE_RFAPI_UPDATED_RESPONSE_QUEUE, data); +	XFREE(MTYPE_RFAPI_UPDATED_RESPONSE_QUEUE, data);  } -static void -updated_responses_queue_init (struct rfapi_descriptor *rfd) +static void updated_responses_queue_init(struct rfapi_descriptor *rfd)  { -  if (rfd->updated_responses_queue) -    return; - -  rfd->updated_responses_queue = work_queue_new (bm->master, -                                                 "rfapi updated responses"); -  assert (rfd->updated_responses_queue); - -  rfd->updated_responses_queue->spec.workfunc = rfapiRibDoQueuedCallback; -  rfd->updated_responses_queue->spec.del_item_data = rfapiRibQueueItemDelete; -  rfd->updated_responses_queue->spec.max_retries = 0; -  rfd->updated_responses_queue->spec.hold = 1; +	if (rfd->updated_responses_queue) +		return; + +	rfd->updated_responses_queue = +		work_queue_new(bm->master, "rfapi updated responses"); +	assert(rfd->updated_responses_queue); + +	rfd->updated_responses_queue->spec.workfunc = rfapiRibDoQueuedCallback; +	rfd->updated_responses_queue->spec.del_item_data = +		rfapiRibQueueItemDelete; +	rfd->updated_responses_queue->spec.max_retries = 0; +	rfd->updated_responses_queue->spec.hold = 1;  }  /* @@ -1608,219 +1585,202 @@ updated_responses_queue_init (struct rfapi_descriptor *rfd)   *   * Based on rfapiNhlAddNodeRoutes()   */ -void -rfapiRibUpdatePendingNode ( -  struct bgp			*bgp, -  struct rfapi_descriptor	*rfd, -  struct rfapi_import_table	*it,        /* needed for L2 */ -  struct route_node		*it_node, -  uint32_t			lifetime) +void rfapiRibUpdatePendingNode( +	struct bgp *bgp, struct rfapi_descriptor *rfd, +	struct rfapi_import_table *it, /* needed for L2 */ +	struct route_node *it_node, uint32_t lifetime)  { -  struct prefix			*prefix; -  struct bgp_info		*bi; -  struct route_node		*pn; -  afi_t				afi; -  uint32_t			queued_flag; -  int				count = 0; -  char				buf[BUFSIZ]; - -  vnc_zlog_debug_verbose ("%s: entry", __func__); - -  if (CHECK_FLAG (bgp->rfapi_cfg->flags, BGP_VNC_CONFIG_CALLBACK_DISABLE)) -    return; - -  vnc_zlog_debug_verbose ("%s: callbacks are not disabled", __func__); - -  RFAPI_RIB_CHECK_COUNTS (1, 0); - -  prefix = &it_node->p; -  afi = family2afi (prefix->family); -  prefix2str (prefix, buf, BUFSIZ); -  vnc_zlog_debug_verbose ("%s: prefix=%s", __func__, buf); - -  pn = route_node_get (rfd->rib_pending[afi], prefix); -  assert (pn); - -  vnc_zlog_debug_verbose ("%s: pn->info=%p, pn->aggregate=%p", __func__, pn->info, -              pn->aggregate); - -  if (pn->aggregate) -    { -      /*  -       * free references into the rfapi_info structures before -       * freeing the structures themselves -       */ -      skiplist_free ((struct skiplist *) (pn->aggregate)); -      pn->aggregate = NULL; -      route_unlock_node (pn);   /* skiplist deleted */ -    } - - -  /*  -   * free the rfapi_info structures -   */ -  if (pn->info) -    { -      if (pn->info != (void *) 1) -        { -          list_delete ((struct list *) (pn->info)); -        } -      pn->info = NULL; -      route_unlock_node (pn);   /* linklist or 1 deleted */ -    } - -  /* -   * The BIs in the import table are already sorted by cost -   */ -  for (bi = it_node->info; bi; bi = bi->next) -    { - -      struct rfapi_info *ri; -      struct prefix pfx_nh; - -      if (!bi->attr) -        { -          /* shouldn't happen */ -          /* TBD increment error stats counter */ -          continue; -        } -      if (!bi->extra) -        { -          /* shouldn't happen */ -          /* TBD increment error stats counter */ -          continue; -        } - -      rfapiNexthop2Prefix (bi->attr, &pfx_nh); - -      /* -       * Omit route if nexthop is self -       */ -      if (CHECK_FLAG -          (bgp->rfapi_cfg->flags, BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP)) -        { - -          struct prefix pfx_vn; - -          rfapiRaddr2Qprefix (&rfd->vn_addr, &pfx_vn); -          if (prefix_same (&pfx_vn, &pfx_nh)) -            continue; -        } - -      ri = rfapi_info_new (); -      ri->rk.vn = pfx_nh; -      ri->rk.rd = bi->extra->vnc.import.rd; -      /* -       * If there is an auxiliary IP address (L2 can have it), copy it -       */ -      if (bi->extra->vnc.import.aux_prefix.family) -        { -          ri->rk.aux_prefix = bi->extra->vnc.import.aux_prefix; -        } - -      if (rfapiGetUnAddrOfVpnBi (bi, &ri->un)) -        { -          rfapi_info_free (ri); -          continue; -        } - -      if (!pn->aggregate) -        { -          pn->aggregate = skiplist_new (0, rfapi_rib_key_cmp, NULL); -          route_lock_node (pn); -        } - -      /* -       * If we have already added this nexthop, the insert will fail. -       * Note that the skiplist key is a pointer INTO the rfapi_info -       * structure which will be added to the "info" list. -       * The skiplist entry VALUE is not used for anything but -       * might be useful during debugging. -       */ -      if (skiplist_insert ((struct skiplist *) pn->aggregate, &ri->rk, ri)) -        { - -          /* -           * duplicate -           */ -          rfapi_info_free (ri); -          continue; -        } - -      rfapiRibBi2Ri(bi, ri, lifetime); - -      if (!pn->info) -        { -          pn->info = list_new (); -          ((struct list *)(pn->info))->del = (void (*)(void *))rfapi_info_free; -          route_lock_node (pn); -        } - -      listnode_add ((struct list *) (pn->info), ri); -    } - -  if (pn->info) -    { -      count = ((struct list *) (pn->info))->count; -    } - -  if (!count) -    { -      assert (!pn->info); -      assert (!pn->aggregate); -      pn->info = (void *) 1;    /* magic value means this node has no routes */ -      route_lock_node (pn); -    } - -  route_unlock_node (pn);       /* route_node_get */ - -  queued_flag = RFAPI_QUEUED_FLAG (afi); - -  if (!CHECK_FLAG (rfd->flags, queued_flag)) -    { - -      struct rfapi_updated_responses_queue *urq; - -      urq = XCALLOC (MTYPE_RFAPI_UPDATED_RESPONSE_QUEUE, -                     sizeof (struct rfapi_updated_responses_queue)); -      assert (urq); -      if (!rfd->updated_responses_queue) -        updated_responses_queue_init (rfd); - -      SET_FLAG (rfd->flags, queued_flag); -      urq->rfd = rfd; -      urq->afi = afi; -      work_queue_add (rfd->updated_responses_queue, urq); -    } -  RFAPI_RIB_CHECK_COUNTS (1, 0); +	struct prefix *prefix; +	struct bgp_info *bi; +	struct route_node *pn; +	afi_t afi; +	uint32_t queued_flag; +	int count = 0; +	char buf[BUFSIZ]; + +	vnc_zlog_debug_verbose("%s: entry", __func__); + +	if (CHECK_FLAG(bgp->rfapi_cfg->flags, BGP_VNC_CONFIG_CALLBACK_DISABLE)) +		return; + +	vnc_zlog_debug_verbose("%s: callbacks are not disabled", __func__); + +	RFAPI_RIB_CHECK_COUNTS(1, 0); + +	prefix = &it_node->p; +	afi = family2afi(prefix->family); +	prefix2str(prefix, buf, BUFSIZ); +	vnc_zlog_debug_verbose("%s: prefix=%s", __func__, buf); + +	pn = route_node_get(rfd->rib_pending[afi], prefix); +	assert(pn); + +	vnc_zlog_debug_verbose("%s: pn->info=%p, pn->aggregate=%p", __func__, +			       pn->info, pn->aggregate); + +	if (pn->aggregate) { +		/* +		 * free references into the rfapi_info structures before +		 * freeing the structures themselves +		 */ +		skiplist_free((struct skiplist *)(pn->aggregate)); +		pn->aggregate = NULL; +		route_unlock_node(pn); /* skiplist deleted */ +	} + + +	/* +	 * free the rfapi_info structures +	 */ +	if (pn->info) { +		if (pn->info != (void *)1) { +			list_delete((struct list *)(pn->info)); +		} +		pn->info = NULL; +		route_unlock_node(pn); /* linklist or 1 deleted */ +	} + +	/* +	 * The BIs in the import table are already sorted by cost +	 */ +	for (bi = it_node->info; bi; bi = bi->next) { + +		struct rfapi_info *ri; +		struct prefix pfx_nh; + +		if (!bi->attr) { +			/* shouldn't happen */ +			/* TBD increment error stats counter */ +			continue; +		} +		if (!bi->extra) { +			/* shouldn't happen */ +			/* TBD increment error stats counter */ +			continue; +		} + +		rfapiNexthop2Prefix(bi->attr, &pfx_nh); + +		/* +		 * Omit route if nexthop is self +		 */ +		if (CHECK_FLAG(bgp->rfapi_cfg->flags, +			       BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP)) { + +			struct prefix pfx_vn; + +			rfapiRaddr2Qprefix(&rfd->vn_addr, &pfx_vn); +			if (prefix_same(&pfx_vn, &pfx_nh)) +				continue; +		} + +		ri = rfapi_info_new(); +		ri->rk.vn = pfx_nh; +		ri->rk.rd = bi->extra->vnc.import.rd; +		/* +		 * If there is an auxiliary IP address (L2 can have it), copy it +		 */ +		if (bi->extra->vnc.import.aux_prefix.family) { +			ri->rk.aux_prefix = bi->extra->vnc.import.aux_prefix; +		} + +		if (rfapiGetUnAddrOfVpnBi(bi, &ri->un)) { +			rfapi_info_free(ri); +			continue; +		} + +		if (!pn->aggregate) { +			pn->aggregate = +				skiplist_new(0, rfapi_rib_key_cmp, NULL); +			route_lock_node(pn); +		} + +		/* +		 * If we have already added this nexthop, the insert will fail. +		 * Note that the skiplist key is a pointer INTO the rfapi_info +		 * structure which will be added to the "info" list. +		 * The skiplist entry VALUE is not used for anything but +		 * might be useful during debugging. +		 */ +		if (skiplist_insert((struct skiplist *)pn->aggregate, &ri->rk, +				    ri)) { + +			/* +			 * duplicate +			 */ +			rfapi_info_free(ri); +			continue; +		} + +		rfapiRibBi2Ri(bi, ri, lifetime); + +		if (!pn->info) { +			pn->info = list_new(); +			((struct list *)(pn->info))->del = +				(void (*)(void *))rfapi_info_free; +			route_lock_node(pn); +		} + +		listnode_add((struct list *)(pn->info), ri); +	} + +	if (pn->info) { +		count = ((struct list *)(pn->info))->count; +	} + +	if (!count) { +		assert(!pn->info); +		assert(!pn->aggregate); +		pn->info = (void *)1; /* magic value means this node has no +					 routes */ +		route_lock_node(pn); +	} + +	route_unlock_node(pn); /* route_node_get */ + +	queued_flag = RFAPI_QUEUED_FLAG(afi); + +	if (!CHECK_FLAG(rfd->flags, queued_flag)) { + +		struct rfapi_updated_responses_queue *urq; + +		urq = XCALLOC(MTYPE_RFAPI_UPDATED_RESPONSE_QUEUE, +			      sizeof(struct rfapi_updated_responses_queue)); +		assert(urq); +		if (!rfd->updated_responses_queue) +			updated_responses_queue_init(rfd); + +		SET_FLAG(rfd->flags, queued_flag); +		urq->rfd = rfd; +		urq->afi = afi; +		work_queue_add(rfd->updated_responses_queue, urq); +	} +	RFAPI_RIB_CHECK_COUNTS(1, 0);  } -void -rfapiRibUpdatePendingNodeSubtree ( -  struct bgp			*bgp, -  struct rfapi_descriptor	*rfd, -  struct rfapi_import_table	*it, -  struct route_node		*it_node, -  struct route_node		*omit_subtree,    /* may be NULL */ -  uint32_t			lifetime) +void rfapiRibUpdatePendingNodeSubtree( +	struct bgp *bgp, struct rfapi_descriptor *rfd, +	struct rfapi_import_table *it, struct route_node *it_node, +	struct route_node *omit_subtree, /* may be NULL */ +	uint32_t lifetime)  { -  /* FIXME: need to find a better way here to work without sticking our -   * hands in node->link */ -  if (it_node->l_left && (it_node->l_left != omit_subtree)) -    { -      if (it_node->l_left->info) -        rfapiRibUpdatePendingNode (bgp, rfd, it, it_node->l_left, lifetime); -      rfapiRibUpdatePendingNodeSubtree (bgp, rfd, it, it_node->l_left, -                                        omit_subtree, lifetime); -    } - -  if (it_node->l_right && (it_node->l_right != omit_subtree)) -    { -      if (it_node->l_right->info) -        rfapiRibUpdatePendingNode (bgp, rfd, it, it_node->l_right, lifetime); -      rfapiRibUpdatePendingNodeSubtree (bgp, rfd, it, it_node->l_right, -                                        omit_subtree, lifetime); -    } +	/* FIXME: need to find a better way here to work without sticking our +	 * hands in node->link */ +	if (it_node->l_left && (it_node->l_left != omit_subtree)) { +		if (it_node->l_left->info) +			rfapiRibUpdatePendingNode(bgp, rfd, it, it_node->l_left, +						  lifetime); +		rfapiRibUpdatePendingNodeSubtree(bgp, rfd, it, it_node->l_left, +						 omit_subtree, lifetime); +	} + +	if (it_node->l_right && (it_node->l_right != omit_subtree)) { +		if (it_node->l_right->info) +			rfapiRibUpdatePendingNode(bgp, rfd, it, +						  it_node->l_right, lifetime); +		rfapiRibUpdatePendingNodeSubtree(bgp, rfd, it, it_node->l_right, +						 omit_subtree, lifetime); +	}  }  /* @@ -1829,72 +1789,72 @@ rfapiRibUpdatePendingNodeSubtree (   *	0	allow prefix to be included in response   *	!0	don't allow prefix to be included in response   */ -int -rfapiRibFTDFilterRecentPrefix( -  struct rfapi_descriptor	*rfd, -  struct route_node             *it_rn,                /* import table node */ -  struct prefix                 *pfx_target_original)  /* query target */ +int rfapiRibFTDFilterRecentPrefix( +	struct rfapi_descriptor *rfd, +	struct route_node *it_rn,	   /* import table node */ +	struct prefix *pfx_target_original) /* query target */  { -  struct bgp			*bgp = rfd->bgp; -  afi_t                         afi = family2afi(it_rn->p.family); -  time_t                        prefix_time; -  struct route_node             *trn; - -  /* -   * Not in FTD mode, so allow prefix -   */ -  if (bgp->rfapi_cfg->rfp_cfg.download_type != RFAPI_RFP_DOWNLOAD_FULL) -    return 0; - -  /* -   * TBD -   * This matches behavior of now-obsolete rfapiRibFTDFilterRecent(), -   * but we need to decide if that is correct. -   */ -  if (it_rn->p.family == AF_ETHERNET) -    return 0; +	struct bgp *bgp = rfd->bgp; +	afi_t afi = family2afi(it_rn->p.family); +	time_t prefix_time; +	struct route_node *trn; + +	/* +	 * Not in FTD mode, so allow prefix +	 */ +	if (bgp->rfapi_cfg->rfp_cfg.download_type != RFAPI_RFP_DOWNLOAD_FULL) +		return 0; + +	/* +	 * TBD +	 * This matches behavior of now-obsolete rfapiRibFTDFilterRecent(), +	 * but we need to decide if that is correct. +	 */ +	if (it_rn->p.family == AF_ETHERNET) +		return 0;  #if DEBUG_FTD_FILTER_RECENT -  { -    char   buf_pfx[BUFSIZ]; +	{ +		char buf_pfx[BUFSIZ]; -    prefix2str(&it_rn->p, buf_pfx, BUFSIZ); -    vnc_zlog_debug_verbose("%s: prefix %s", __func__, buf_pfx); -  } +		prefix2str(&it_rn->p, buf_pfx, BUFSIZ); +		vnc_zlog_debug_verbose("%s: prefix %s", __func__, buf_pfx); +	}  #endif -  /* -   * prefix covers target address, so allow prefix -   */ -  if (prefix_match (&it_rn->p, pfx_target_original)) -    { +	/* +	 * prefix covers target address, so allow prefix +	 */ +	if (prefix_match(&it_rn->p, pfx_target_original)) {  #if DEBUG_FTD_FILTER_RECENT -      vnc_zlog_debug_verbose("%s: prefix covers target, allowed", __func__); +		vnc_zlog_debug_verbose("%s: prefix covers target, allowed", +				       __func__);  #endif -      return 0; -    } +		return 0; +	} -  /* -   * check this NVE's timestamp for this prefix -   */ -  trn = route_node_get (rfd->rsp_times[afi], &it_rn->p);  /* locks trn */ -  prefix_time = (time_t) trn->info; -  if (trn->lock > 1) -    route_unlock_node (trn); +	/* +	 * check this NVE's timestamp for this prefix +	 */ +	trn = route_node_get(rfd->rsp_times[afi], &it_rn->p); /* locks trn */ +	prefix_time = (time_t)trn->info; +	if (trn->lock > 1) +		route_unlock_node(trn);  #if DEBUG_FTD_FILTER_RECENT -  vnc_zlog_debug_verbose("%s: last sent time %lu, last allowed time %lu", -    __func__, prefix_time, rfd->ftd_last_allowed_time); +	vnc_zlog_debug_verbose("%s: last sent time %lu, last allowed time %lu", +			       __func__, prefix_time, +			       rfd->ftd_last_allowed_time);  #endif -  /* -   * haven't sent this prefix, which doesn't cover target address, -   * to NVE since ftd_advertisement_interval, so OK to send now. -   */ -  if (prefix_time <= rfd->ftd_last_allowed_time) -    return 0; +	/* +	 * haven't sent this prefix, which doesn't cover target address, +	 * to NVE since ftd_advertisement_interval, so OK to send now. +	 */ +	if (prefix_time <= rfd->ftd_last_allowed_time) +		return 0; -  return 1; +	return 1;  }  /* @@ -1905,648 +1865,626 @@ rfapiRibFTDFilterRecentPrefix(   * value of nexthop chain.   */  struct rfapi_next_hop_entry * -rfapiRibPreload ( -  struct bgp			*bgp, -  struct rfapi_descriptor	*rfd, -  struct rfapi_next_hop_entry	*response, -  int				use_eth_resolution) +rfapiRibPreload(struct bgp *bgp, struct rfapi_descriptor *rfd, +		struct rfapi_next_hop_entry *response, int use_eth_resolution)  { -  struct rfapi_next_hop_entry *nhp; -  struct rfapi_next_hop_entry *nhp_next; -  struct rfapi_next_hop_entry *head = NULL; -  struct rfapi_next_hop_entry *tail = NULL; -  time_t new_last_sent_time; - -  vnc_zlog_debug_verbose ("%s: loading response=%p, use_eth_resolution=%d", -              __func__, response, use_eth_resolution); - -  new_last_sent_time = rfapi_time (NULL); - -  for (nhp = response; nhp; nhp = nhp_next) -    { - -      struct prefix pfx; -      struct rfapi_rib_key rk; -      afi_t afi; -      struct rfapi_info *ri; -      int need_insert; -      struct route_node *rn; -      int rib_node_started_nonempty = 0; -      struct route_node *trn; -      int allowed = 0; - -      /* save in case we delete nhp */ -      nhp_next = nhp->next; - -      if (nhp->lifetime == RFAPI_REMOVE_RESPONSE_LIFETIME) -        { -          /* -           * weird, shouldn't happen -           */ -          vnc_zlog_debug_verbose -            ("%s: got nhp->lifetime == RFAPI_REMOVE_RESPONSE_LIFETIME", -             __func__); -          continue; -        } - - -      if (use_eth_resolution) -        { -          /* get the prefix of the ethernet address in the L2 option */ -          struct rfapi_l2address_option *pL2o; -          struct rfapi_vn_option *vo; - -          /* -           * Look for VN option of type RFAPI_VN_OPTION_TYPE_L2ADDR -           */ -          for (pL2o = NULL, vo = nhp->vn_options; vo; vo = vo->next) -            { -              if (RFAPI_VN_OPTION_TYPE_L2ADDR == vo->type) -                { -                  pL2o = &vo->v.l2addr; -                  break; -                } -            } - -          if (!pL2o) -            { -              /* -               * not supposed to happen -               */ -              vnc_zlog_debug_verbose ("%s: missing L2 info", __func__); -              continue; -            } - -          afi = AFI_L2VPN; -          rfapiL2o2Qprefix (pL2o, &pfx); -        } -      else -        { -          rfapiRprefix2Qprefix (&nhp->prefix, &pfx); -          afi = family2afi (pfx.family); -        } - -      /* -       * TBD for ethernet, rib must know the right way to distinguish -       * duplicate routes -       * -       * Current approach: prefix is key to radix tree; then -       * each prefix has a set of routes with unique VN addrs -       */ - -      /* -       * Look up prefix in RIB -       */ -      rn = route_node_get (rfd->rib[afi], &pfx);        /* locks rn */ - -      if (rn->info) -        { -          rib_node_started_nonempty = 1; -        } -      else -        { -          rn->info = skiplist_new (0, rfapi_rib_key_cmp, NULL); -          route_lock_node (rn); -        } - -      /* -       * Look up route at prefix -       */ -      need_insert = 0; -      memset ((void *) &rk, 0, sizeof (rk)); -      assert (!rfapiRaddr2Qprefix (&nhp->vn_address, &rk.vn)); - -      if (use_eth_resolution) -        { -          /* copy what came from aux_prefix to rk.aux_prefix */ -          rfapiRprefix2Qprefix (&nhp->prefix, &rk.aux_prefix); -          if (RFAPI_0_PREFIX (&rk.aux_prefix) -              && RFAPI_HOST_PREFIX (&rk.aux_prefix)) -            { -              /* mark as "none" if nhp->prefix is 0/32 or 0/128 */ -              rk.aux_prefix.family = 0; -            } -        } +	struct rfapi_next_hop_entry *nhp; +	struct rfapi_next_hop_entry *nhp_next; +	struct rfapi_next_hop_entry *head = NULL; +	struct rfapi_next_hop_entry *tail = NULL; +	time_t new_last_sent_time; + +	vnc_zlog_debug_verbose("%s: loading response=%p, use_eth_resolution=%d", +			       __func__, response, use_eth_resolution); + +	new_last_sent_time = rfapi_time(NULL); + +	for (nhp = response; nhp; nhp = nhp_next) { + +		struct prefix pfx; +		struct rfapi_rib_key rk; +		afi_t afi; +		struct rfapi_info *ri; +		int need_insert; +		struct route_node *rn; +		int rib_node_started_nonempty = 0; +		struct route_node *trn; +		int allowed = 0; + +		/* save in case we delete nhp */ +		nhp_next = nhp->next; + +		if (nhp->lifetime == RFAPI_REMOVE_RESPONSE_LIFETIME) { +			/* +			 * weird, shouldn't happen +			 */ +			vnc_zlog_debug_verbose( +				"%s: got nhp->lifetime == RFAPI_REMOVE_RESPONSE_LIFETIME", +				__func__); +			continue; +		} + + +		if (use_eth_resolution) { +			/* get the prefix of the ethernet address in the L2 +			 * option */ +			struct rfapi_l2address_option *pL2o; +			struct rfapi_vn_option *vo; + +			/* +			 * Look for VN option of type +			 * RFAPI_VN_OPTION_TYPE_L2ADDR +			 */ +			for (pL2o = NULL, vo = nhp->vn_options; vo; +			     vo = vo->next) { +				if (RFAPI_VN_OPTION_TYPE_L2ADDR == vo->type) { +					pL2o = &vo->v.l2addr; +					break; +				} +			} + +			if (!pL2o) { +				/* +				 * not supposed to happen +				 */ +				vnc_zlog_debug_verbose("%s: missing L2 info", +						       __func__); +				continue; +			} + +			afi = AFI_L2VPN; +			rfapiL2o2Qprefix(pL2o, &pfx); +		} else { +			rfapiRprefix2Qprefix(&nhp->prefix, &pfx); +			afi = family2afi(pfx.family); +		} + +		/* +		 * TBD for ethernet, rib must know the right way to distinguish +		 * duplicate routes +		 * +		 * Current approach: prefix is key to radix tree; then +		 * each prefix has a set of routes with unique VN addrs +		 */ + +		/* +		 * Look up prefix in RIB +		 */ +		rn = route_node_get(rfd->rib[afi], &pfx); /* locks rn */ + +		if (rn->info) { +			rib_node_started_nonempty = 1; +		} else { +			rn->info = skiplist_new(0, rfapi_rib_key_cmp, NULL); +			route_lock_node(rn); +		} + +		/* +		 * Look up route at prefix +		 */ +		need_insert = 0; +		memset((void *)&rk, 0, sizeof(rk)); +		assert(!rfapiRaddr2Qprefix(&nhp->vn_address, &rk.vn)); + +		if (use_eth_resolution) { +			/* copy what came from aux_prefix to rk.aux_prefix */ +			rfapiRprefix2Qprefix(&nhp->prefix, &rk.aux_prefix); +			if (RFAPI_0_PREFIX(&rk.aux_prefix) +			    && RFAPI_HOST_PREFIX(&rk.aux_prefix)) { +				/* mark as "none" if nhp->prefix is 0/32 or +				 * 0/128 */ +				rk.aux_prefix.family = 0; +			} +		}  #if DEBUG_NHL -      { -        char str_vn[BUFSIZ]; -        char str_aux_prefix[BUFSIZ]; - -        str_vn[0] = 0; -        str_aux_prefix[0] = 0; - -        prefix2str (&rk.vn, str_vn, BUFSIZ); -        prefix2str (&rk.aux_prefix, str_aux_prefix, BUFSIZ); - -        if (!rk.aux_prefix.family) -          { - -          } -        vnc_zlog_debug_verbose ("%s:   rk.vn=%s rk.aux_prefix=%s", -                    __func__, str_vn, -                    (rk.aux_prefix.family ? str_aux_prefix : "-")); -      } -      vnc_zlog_debug_verbose ("%s: RIB skiplist for this prefix follows", __func__); -      rfapiRibShowRibSl (NULL, &rn->p, (struct skiplist *) rn->info); +		{ +			char str_vn[BUFSIZ]; +			char str_aux_prefix[BUFSIZ]; + +			str_vn[0] = 0; +			str_aux_prefix[0] = 0; + +			prefix2str(&rk.vn, str_vn, BUFSIZ); +			prefix2str(&rk.aux_prefix, str_aux_prefix, BUFSIZ); + +			if (!rk.aux_prefix.family) { +			} +			vnc_zlog_debug_verbose( +				"%s:   rk.vn=%s rk.aux_prefix=%s", __func__, +				str_vn, +				(rk.aux_prefix.family ? str_aux_prefix : "-")); +		} +		vnc_zlog_debug_verbose( +			"%s: RIB skiplist for this prefix follows", __func__); +		rfapiRibShowRibSl(NULL, &rn->p, (struct skiplist *)rn->info);  #endif -      if (!skiplist_search ((struct skiplist *) rn->info, &rk, (void **) &ri)) -        { -          /* -           * Already have this route; make values match -           */ -          rfapiFreeRfapiUnOptionChain (ri->un_options); -          ri->un_options = NULL; -          rfapiFreeRfapiVnOptionChain (ri->vn_options); -          ri->vn_options = NULL; +		if (!skiplist_search((struct skiplist *)rn->info, &rk, +				     (void **)&ri)) { +			/* +			 * Already have this route; make values match +			 */ +			rfapiFreeRfapiUnOptionChain(ri->un_options); +			ri->un_options = NULL; +			rfapiFreeRfapiVnOptionChain(ri->vn_options); +			ri->vn_options = NULL;  #if DEBUG_NHL -          vnc_zlog_debug_verbose ("%s: found in RIB", __func__); +			vnc_zlog_debug_verbose("%s: found in RIB", __func__);  #endif -          /* -           * Filter duplicate routes from initial response. -           * Check timestamps to avoid wraparound problems -           */ -          if ((ri->rsp_counter != rfd->rsp_counter) || -              (ri->last_sent_time != new_last_sent_time)) -            { +			/* +			 * Filter duplicate routes from initial response. +			 * Check timestamps to avoid wraparound problems +			 */ +			if ((ri->rsp_counter != rfd->rsp_counter) +			    || (ri->last_sent_time != new_last_sent_time)) {  #if DEBUG_NHL -              vnc_zlog_debug_verbose ("%s: allowed due to counter/timestamp diff", -                          __func__); +				vnc_zlog_debug_verbose( +					"%s: allowed due to counter/timestamp diff", +					__func__);  #endif -              allowed = 1; -            } +				allowed = 1; +			} -        } -      else -        { +		} else {  #if DEBUG_NHL -          vnc_zlog_debug_verbose ("%s: allowed due to not yet in RIB", __func__); +			vnc_zlog_debug_verbose( +				"%s: allowed due to not yet in RIB", __func__);  #endif -          /* not found: add new route to RIB */ -          ri = rfapi_info_new (); -          need_insert = 1; -          allowed = 1; -        } - -      ri->rk = rk; -      assert (!rfapiRaddr2Qprefix (&nhp->un_address, &ri->un)); -      ri->cost = nhp->prefix.cost; -      ri->lifetime = nhp->lifetime; -      ri->vn_options = rfapiVnOptionsDup (nhp->vn_options); -      ri->rsp_counter = rfd->rsp_counter; -      ri->last_sent_time = rfapi_time (NULL); - -      if (need_insert) -        { -          int rc; -          rc = skiplist_insert ((struct skiplist *) rn->info, &ri->rk, ri); -          assert (!rc); -        } - -      if (!rib_node_started_nonempty) -        { -          RFAPI_RIB_PREFIX_COUNT_INCR (rfd, bgp->rfapi); -        } - -      RFAPI_RIB_CHECK_COUNTS (0, 0); -      rfapiRibStartTimer (rfd, ri, rn, 0); -      RFAPI_RIB_CHECK_COUNTS (0, 0); - -      route_unlock_node (rn); - -      /* -       * update this NVE's timestamp for this prefix -       */ -      trn = route_node_get (rfd->rsp_times[afi], &pfx); /* locks trn */ -      trn->info = (void *) (uintptr_t) bgp_clock (); -      if (trn->lock > 1) -        route_unlock_node (trn); - -      { -        char str_pfx[BUFSIZ]; -        char str_pfx_vn[BUFSIZ]; - -        prefix2str (&pfx, str_pfx, BUFSIZ); -        prefix2str (&rk.vn, str_pfx_vn, BUFSIZ); -        vnc_zlog_debug_verbose -          ("%s:   added pfx=%s nh[vn]=%s, cost=%u, lifetime=%u, allowed=%d", -           __func__, str_pfx, str_pfx_vn, nhp->prefix.cost, nhp->lifetime, -           allowed); -      } - -      if (allowed) -        { -          if (tail) -            (tail)->next = nhp; -          tail = nhp; -          if (!head) -            { -              head = nhp; -            } -        } -      else -        { -          rfapi_un_options_free (nhp->un_options); -          nhp->un_options = NULL; -          rfapi_vn_options_free (nhp->vn_options); -          nhp->vn_options = NULL; - -          XFREE (MTYPE_RFAPI_NEXTHOP, nhp); -          nhp = NULL; -        } -    } - -  if (tail) -    tail->next = NULL; -  return head; +			/* not found: add new route to RIB */ +			ri = rfapi_info_new(); +			need_insert = 1; +			allowed = 1; +		} + +		ri->rk = rk; +		assert(!rfapiRaddr2Qprefix(&nhp->un_address, &ri->un)); +		ri->cost = nhp->prefix.cost; +		ri->lifetime = nhp->lifetime; +		ri->vn_options = rfapiVnOptionsDup(nhp->vn_options); +		ri->rsp_counter = rfd->rsp_counter; +		ri->last_sent_time = rfapi_time(NULL); + +		if (need_insert) { +			int rc; +			rc = skiplist_insert((struct skiplist *)rn->info, +					     &ri->rk, ri); +			assert(!rc); +		} + +		if (!rib_node_started_nonempty) { +			RFAPI_RIB_PREFIX_COUNT_INCR(rfd, bgp->rfapi); +		} + +		RFAPI_RIB_CHECK_COUNTS(0, 0); +		rfapiRibStartTimer(rfd, ri, rn, 0); +		RFAPI_RIB_CHECK_COUNTS(0, 0); + +		route_unlock_node(rn); + +		/* +		 * update this NVE's timestamp for this prefix +		 */ +		trn = route_node_get(rfd->rsp_times[afi], &pfx); /* locks trn */ +		trn->info = (void *)(uintptr_t)bgp_clock(); +		if (trn->lock > 1) +			route_unlock_node(trn); + +		{ +			char str_pfx[BUFSIZ]; +			char str_pfx_vn[BUFSIZ]; + +			prefix2str(&pfx, str_pfx, BUFSIZ); +			prefix2str(&rk.vn, str_pfx_vn, BUFSIZ); +			vnc_zlog_debug_verbose( +				"%s:   added pfx=%s nh[vn]=%s, cost=%u, lifetime=%u, allowed=%d", +				__func__, str_pfx, str_pfx_vn, nhp->prefix.cost, +				nhp->lifetime, allowed); +		} + +		if (allowed) { +			if (tail) +				(tail)->next = nhp; +			tail = nhp; +			if (!head) { +				head = nhp; +			} +		} else { +			rfapi_un_options_free(nhp->un_options); +			nhp->un_options = NULL; +			rfapi_vn_options_free(nhp->vn_options); +			nhp->vn_options = NULL; + +			XFREE(MTYPE_RFAPI_NEXTHOP, nhp); +			nhp = NULL; +		} +	} + +	if (tail) +		tail->next = NULL; +	return head;  } -void -rfapiRibPendingDeleteRoute ( -  struct bgp			*bgp, -  struct rfapi_import_table	*it, -  afi_t				afi, -  struct route_node		*it_node) +void rfapiRibPendingDeleteRoute(struct bgp *bgp, struct rfapi_import_table *it, +				afi_t afi, struct route_node *it_node)  { -  struct rfapi_descriptor *rfd; -  struct listnode *node; -  char buf[BUFSIZ]; - -  prefix2str (&it_node->p, buf, BUFSIZ); -  vnc_zlog_debug_verbose ("%s: entry, it=%p, afi=%d, it_node=%p, pfx=%s", -              __func__, it, afi, it_node, buf); - -  if (AFI_L2VPN == afi) -    { -      /* -       * ethernet import tables are per-LNI and each ethernet monitor  -       * identifies the rfd that owns it. -       */ -      struct rfapi_monitor_eth *m; -      struct route_node *rn; -      struct skiplist *sl; -      void *cursor; -      int rc; - -      /* -       * route-specific monitors -       */ -      if ((sl = RFAPI_MONITOR_ETH (it_node))) -        { - -          vnc_zlog_debug_verbose ("%s: route-specific skiplist: %p", __func__, sl); - -          for (cursor = NULL, rc = -               skiplist_next (sl, NULL, (void **) &m, (void **) &cursor); !rc; -               rc = skiplist_next (sl, NULL, (void **) &m, (void **) &cursor)) -            { +	struct rfapi_descriptor *rfd; +	struct listnode *node; +	char buf[BUFSIZ]; + +	prefix2str(&it_node->p, buf, BUFSIZ); +	vnc_zlog_debug_verbose("%s: entry, it=%p, afi=%d, it_node=%p, pfx=%s", +			       __func__, it, afi, it_node, buf); + +	if (AFI_L2VPN == afi) { +		/* +		 * ethernet import tables are per-LNI and each ethernet monitor +		 * identifies the rfd that owns it. +		 */ +		struct rfapi_monitor_eth *m; +		struct route_node *rn; +		struct skiplist *sl; +		void *cursor; +		int rc; + +		/* +		 * route-specific monitors +		 */ +		if ((sl = RFAPI_MONITOR_ETH(it_node))) { + +			vnc_zlog_debug_verbose( +				"%s: route-specific skiplist: %p", __func__, +				sl); + +			for (cursor = NULL, +			    rc = skiplist_next(sl, NULL, (void **)&m, +					       (void **)&cursor); +			     !rc; rc = skiplist_next(sl, NULL, (void **)&m, +						     (void **)&cursor)) {  #if DEBUG_PENDING_DELETE_ROUTE -              vnc_zlog_debug_verbose ("%s: eth monitor rfd=%p", __func__, m->rfd); +				vnc_zlog_debug_verbose("%s: eth monitor rfd=%p", +						       __func__, m->rfd);  #endif -              /* -               * If we have already sent a route with this prefix to this -               * NVE, it's OK to send an update with the delete -               */ -              if ((rn = route_node_lookup (m->rfd->rib[afi], &it_node->p))) -                { -                  rfapiRibUpdatePendingNode (bgp, m->rfd, it, it_node, -                                             m->rfd->response_lifetime); -                  route_unlock_node (rn); -                } -            } -        } - -      /* -       * all-routes/FTD monitors -       */ -      for (m = it->eth0_queries; m; m = m->next) -        { +				/* +				 * If we have already sent a route with this +				 * prefix to this +				 * NVE, it's OK to send an update with the +				 * delete +				 */ +				if ((rn = route_node_lookup(m->rfd->rib[afi], +							    &it_node->p))) { +					rfapiRibUpdatePendingNode( +						bgp, m->rfd, it, it_node, +						m->rfd->response_lifetime); +					route_unlock_node(rn); +				} +			} +		} + +		/* +		 * all-routes/FTD monitors +		 */ +		for (m = it->eth0_queries; m; m = m->next) {  #if DEBUG_PENDING_DELETE_ROUTE -          vnc_zlog_debug_verbose ("%s: eth0 monitor rfd=%p", __func__, m->rfd); +			vnc_zlog_debug_verbose("%s: eth0 monitor rfd=%p", +					       __func__, m->rfd);  #endif -          /* -           * If we have already sent a route with this prefix to this -           * NVE, it's OK to send an update with the delete -           */ -          if ((rn = route_node_lookup (m->rfd->rib[afi], &it_node->p))) -            { -              rfapiRibUpdatePendingNode (bgp, m->rfd, it, it_node, -                                         m->rfd->response_lifetime); -            } -        } - -    } -  else -    { -      /* -       * Find RFDs that reference this import table -       */ -      for (ALL_LIST_ELEMENTS_RO (&bgp->rfapi->descriptors, node, rfd)) -        { - -          struct route_node *rn; - -          vnc_zlog_debug_verbose ("%s: comparing rfd(%p)->import_table=%p to it=%p", -                      __func__, rfd, rfd->import_table, it); - -          if (rfd->import_table != it) -            continue; - -          vnc_zlog_debug_verbose ("%s: matched rfd %p", __func__, rfd); - -          /* -           * If we have sent a response to this NVE with this prefix -           * previously, we should send an updated response. -           */ -          if ((rn = route_node_lookup (rfd->rib[afi], &it_node->p))) -            { -              rfapiRibUpdatePendingNode (bgp, rfd, it, it_node, -                                         rfd->response_lifetime); -              route_unlock_node (rn); -            } -        } -    } +			/* +			 * If we have already sent a route with this prefix to +			 * this +			 * NVE, it's OK to send an update with the delete +			 */ +			if ((rn = route_node_lookup(m->rfd->rib[afi], +						    &it_node->p))) { +				rfapiRibUpdatePendingNode( +					bgp, m->rfd, it, it_node, +					m->rfd->response_lifetime); +			} +		} + +	} else { +		/* +		 * Find RFDs that reference this import table +		 */ +		for (ALL_LIST_ELEMENTS_RO(&bgp->rfapi->descriptors, node, +					  rfd)) { + +			struct route_node *rn; + +			vnc_zlog_debug_verbose( +				"%s: comparing rfd(%p)->import_table=%p to it=%p", +				__func__, rfd, rfd->import_table, it); + +			if (rfd->import_table != it) +				continue; + +			vnc_zlog_debug_verbose("%s: matched rfd %p", __func__, +					       rfd); + +			/* +			 * If we have sent a response to this NVE with this +			 * prefix +			 * previously, we should send an updated response. +			 */ +			if ((rn = route_node_lookup(rfd->rib[afi], +						    &it_node->p))) { +				rfapiRibUpdatePendingNode( +					bgp, rfd, it, it_node, +					rfd->response_lifetime); +				route_unlock_node(rn); +			} +		} +	}  } -void -rfapiRibShowResponsesSummary (void *stream) +void rfapiRibShowResponsesSummary(void *stream)  { -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; -  struct bgp *bgp = bgp_get_default (); - -  int nves = 0; -  int nves_with_nonempty_ribs = 0; -  struct rfapi_descriptor *rfd; -  struct listnode *node; - - -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; - -  fp (out, "%-24s ", "Responses: (Prefixes)"); -  fp (out, "%-8s %-8u ", "Active:", bgp->rfapi->rib_prefix_count_total); -  fp (out, "%-8s %-8u", "Maximum:", bgp->rfapi->rib_prefix_count_total_max); -  fp (out, "\n"); - -  fp (out, "%-24s ", "           (Updated)"); -  fp (out, "%-8s %-8u ", "Update:", -      bgp->rfapi->stat.count_updated_response_updates); -  fp (out, "%-8s %-8u", "Remove:", -      bgp->rfapi->stat.count_updated_response_deletes); -  fp (out, "%-8s %-8u", "Total:", -      bgp->rfapi->stat.count_updated_response_updates + -      bgp->rfapi->stat.count_updated_response_deletes); -  fp (out, "\n"); - -  fp (out, "%-24s ", "           (NVEs)"); -  for (ALL_LIST_ELEMENTS_RO (&bgp->rfapi->descriptors, node, rfd)) -    { -      ++nves; -      if (rfd->rib_prefix_count) -        ++nves_with_nonempty_ribs; -    } -  fp (out, "%-8s %-8u ", "Active:", nves_with_nonempty_ribs); -  fp (out, "%-8s %-8u", "Total:", nves); -  fp (out, "\n"); - +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; +	struct bgp *bgp = bgp_get_default(); + +	int nves = 0; +	int nves_with_nonempty_ribs = 0; +	struct rfapi_descriptor *rfd; +	struct listnode *node; + + +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; + +	fp(out, "%-24s ", "Responses: (Prefixes)"); +	fp(out, "%-8s %-8u ", "Active:", bgp->rfapi->rib_prefix_count_total); +	fp(out, "%-8s %-8u", +	   "Maximum:", bgp->rfapi->rib_prefix_count_total_max); +	fp(out, "\n"); + +	fp(out, "%-24s ", "           (Updated)"); +	fp(out, "%-8s %-8u ", +	   "Update:", bgp->rfapi->stat.count_updated_response_updates); +	fp(out, "%-8s %-8u", +	   "Remove:", bgp->rfapi->stat.count_updated_response_deletes); +	fp(out, "%-8s %-8u", "Total:", +	   bgp->rfapi->stat.count_updated_response_updates +		   + bgp->rfapi->stat.count_updated_response_deletes); +	fp(out, "\n"); + +	fp(out, "%-24s ", "           (NVEs)"); +	for (ALL_LIST_ELEMENTS_RO(&bgp->rfapi->descriptors, node, rfd)) { +		++nves; +		if (rfd->rib_prefix_count) +			++nves_with_nonempty_ribs; +	} +	fp(out, "%-8s %-8u ", "Active:", nves_with_nonempty_ribs); +	fp(out, "%-8s %-8u", "Total:", nves); +	fp(out, "\n");  } -void -rfapiRibShowResponsesSummaryClear (void) +void rfapiRibShowResponsesSummaryClear(void)  { -  struct bgp *bgp = bgp_get_default (); +	struct bgp *bgp = bgp_get_default(); -  bgp->rfapi->rib_prefix_count_total_max = bgp->rfapi->rib_prefix_count_total; +	bgp->rfapi->rib_prefix_count_total_max = +		bgp->rfapi->rib_prefix_count_total;  } -static int -print_rib_sl ( -  int (*fp) (void *, const char *, ...), -  struct vty		*vty, -  void			*out, -  struct skiplist	*sl, -  int			deleted, -  char			*str_pfx, -  int			*printedprefix) +static int print_rib_sl(int (*fp)(void *, const char *, ...), struct vty *vty, +			void *out, struct skiplist *sl, int deleted, +			char *str_pfx, int *printedprefix)  { -  struct rfapi_info *ri; -  int rc; -  void *cursor; -  int routes_displayed = 0; - -  cursor = NULL; -  for (rc = skiplist_next (sl, NULL, (void **) &ri, &cursor); -       !rc; rc = skiplist_next (sl, NULL, (void **) &ri, &cursor)) -    { - -      char str_vn[BUFSIZ]; -      char str_un[BUFSIZ]; -      char str_lifetime[BUFSIZ]; -      char str_age[BUFSIZ]; -      char *p; -      char str_rd[BUFSIZ]; - -      ++routes_displayed; - -      prefix2str (&ri->rk.vn, str_vn, BUFSIZ); -      p = index (str_vn, '/'); -      if (p) -        *p = 0; - -      prefix2str (&ri->un, str_un, BUFSIZ); -      p = index (str_un, '/'); -      if (p) -        *p = 0; - -      rfapiFormatSeconds (ri->lifetime, str_lifetime, BUFSIZ); +	struct rfapi_info *ri; +	int rc; +	void *cursor; +	int routes_displayed = 0; + +	cursor = NULL; +	for (rc = skiplist_next(sl, NULL, (void **)&ri, &cursor); !rc; +	     rc = skiplist_next(sl, NULL, (void **)&ri, &cursor)) { + +		char str_vn[BUFSIZ]; +		char str_un[BUFSIZ]; +		char str_lifetime[BUFSIZ]; +		char str_age[BUFSIZ]; +		char *p; +		char str_rd[BUFSIZ]; + +		++routes_displayed; + +		prefix2str(&ri->rk.vn, str_vn, BUFSIZ); +		p = index(str_vn, '/'); +		if (p) +			*p = 0; + +		prefix2str(&ri->un, str_un, BUFSIZ); +		p = index(str_un, '/'); +		if (p) +			*p = 0; + +		rfapiFormatSeconds(ri->lifetime, str_lifetime, BUFSIZ);  #if RFAPI_REGISTRATIONS_REPORT_AGE -      rfapiFormatAge (ri->last_sent_time, str_age, BUFSIZ); +		rfapiFormatAge(ri->last_sent_time, str_age, BUFSIZ);  #else -      { -        time_t now = rfapi_time (NULL); -        time_t expire = ri->last_sent_time + (time_t) ri->lifetime; -        /* allow for delayed/async removal */ -        rfapiFormatSeconds ((expire > now ? expire - now : 1), -                            str_age, BUFSIZ); -      } +		{ +			time_t now = rfapi_time(NULL); +			time_t expire = +				ri->last_sent_time + (time_t)ri->lifetime; +			/* allow for delayed/async removal */ +			rfapiFormatSeconds((expire > now ? expire - now : 1), +					   str_age, BUFSIZ); +		}  #endif -    str_rd[0] = 0;	/* start empty */ +		str_rd[0] = 0; /* start empty */  #if DEBUG_RIB_SL_RD -    str_rd[0] = ' '; -    prefix_rd2str(&ri->rk.rd, str_rd+1, BUFSIZ-1); +		str_rd[0] = ' '; +		prefix_rd2str(&ri->rk.rd, str_rd + 1, BUFSIZ - 1);  #endif -      fp (out, " %c %-20s %-15s %-15s %-4u %-8s %-8s%s\n", -          deleted ? 'r' : ' ', -          *printedprefix ? "" : str_pfx, -          str_vn, str_un, ri->cost, str_lifetime, str_age, str_rd); +		fp(out, " %c %-20s %-15s %-15s %-4u %-8s %-8s%s\n", +		   deleted ? 'r' : ' ', *printedprefix ? "" : str_pfx, str_vn, +		   str_un, ri->cost, str_lifetime, str_age, str_rd); -      if (!*printedprefix) -        *printedprefix = 1; -    } -  return routes_displayed; +		if (!*printedprefix) +			*printedprefix = 1; +	} +	return routes_displayed;  }  #if DEBUG_NHL  /*   * This one is for debugging (set stream to NULL to send output to log)   */ -static void -rfapiRibShowRibSl (void *stream, struct prefix *pfx, struct skiplist *sl) +static void rfapiRibShowRibSl(void *stream, struct prefix *pfx, +			      struct skiplist *sl)  { -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; -  int nhs_displayed = 0; -  char str_pfx[BUFSIZ]; -  int printedprefix = 0; +	int nhs_displayed = 0; +	char str_pfx[BUFSIZ]; +	int printedprefix = 0; -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; -  prefix2str (pfx, str_pfx, BUFSIZ); +	prefix2str(pfx, str_pfx, BUFSIZ); -  nhs_displayed += print_rib_sl (fp, vty, out, sl, -                                 0, str_pfx, &printedprefix); +	nhs_displayed += +		print_rib_sl(fp, vty, out, sl, 0, str_pfx, &printedprefix);  }  #endif -void -rfapiRibShowResponses ( -  void		*stream, -  struct prefix	*pfx_match, -  int		show_removed) +void rfapiRibShowResponses(void *stream, struct prefix *pfx_match, +			   int show_removed)  { -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; - -  struct rfapi_descriptor *rfd; -  struct listnode *node; - -  struct bgp *bgp = bgp_get_default (); -  int printedheader = 0; -  int routes_total = 0; -  int nhs_total = 0; -  int prefixes_total = 0; -  int prefixes_displayed = 0; -  int nves_total = 0; -  int nves_with_routes = 0; -  int nves_displayed = 0; -  int routes_displayed = 0; -  int nhs_displayed = 0; - -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; -  /* -   * loop over NVEs -   */ -  for (ALL_LIST_ELEMENTS_RO (&bgp->rfapi->descriptors, node, rfd)) -    { - -      int printednve = 0; -      afi_t afi; - -      ++nves_total; -      if (rfd->rib_prefix_count) -        ++nves_with_routes; - -      for (afi = AFI_IP; afi < AFI_MAX; ++afi) -        { - -          struct route_node *rn; - -          if (!rfd->rib[afi]) -            continue; - -          for (rn = route_top (rfd->rib[afi]); rn; rn = route_next (rn)) -            { - -              struct skiplist *sl; -              char str_pfx[BUFSIZ]; -              int printedprefix = 0; - -              if (!show_removed) -                sl = rn->info; -              else -                sl = rn->aggregate; - -              if (!sl) -                continue; - -              routes_total++; -              nhs_total += skiplist_count (sl); -              ++prefixes_total; - -              if (pfx_match && !prefix_match (pfx_match, &rn->p) && -                  !prefix_match (&rn->p, pfx_match)) -                continue; - -              ++prefixes_displayed; - -              if (!printedheader) -                { -                  ++printedheader; - -                  fp (out, "\n[%s]\n", -                      show_removed ? "Removed" : "Active"); -                  fp (out, "%-15s %-15s\n", "Querying VN", "Querying UN"); -                  fp (out, "   %-20s %-15s %-15s %4s %-8s %-8s\n", -                      "Prefix", "Registered VN", "Registered UN", "Cost", -                      "Lifetime", +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; + +	struct rfapi_descriptor *rfd; +	struct listnode *node; + +	struct bgp *bgp = bgp_get_default(); +	int printedheader = 0; +	int routes_total = 0; +	int nhs_total = 0; +	int prefixes_total = 0; +	int prefixes_displayed = 0; +	int nves_total = 0; +	int nves_with_routes = 0; +	int nves_displayed = 0; +	int routes_displayed = 0; +	int nhs_displayed = 0; + +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; +	/* +	 * loop over NVEs +	 */ +	for (ALL_LIST_ELEMENTS_RO(&bgp->rfapi->descriptors, node, rfd)) { + +		int printednve = 0; +		afi_t afi; + +		++nves_total; +		if (rfd->rib_prefix_count) +			++nves_with_routes; + +		for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + +			struct route_node *rn; + +			if (!rfd->rib[afi]) +				continue; + +			for (rn = route_top(rfd->rib[afi]); rn; +			     rn = route_next(rn)) { + +				struct skiplist *sl; +				char str_pfx[BUFSIZ]; +				int printedprefix = 0; + +				if (!show_removed) +					sl = rn->info; +				else +					sl = rn->aggregate; + +				if (!sl) +					continue; + +				routes_total++; +				nhs_total += skiplist_count(sl); +				++prefixes_total; + +				if (pfx_match +				    && !prefix_match(pfx_match, &rn->p) +				    && !prefix_match(&rn->p, pfx_match)) +					continue; + +				++prefixes_displayed; + +				if (!printedheader) { +					++printedheader; + +					fp(out, "\n[%s]\n", +					   show_removed ? "Removed" : "Active"); +					fp(out, "%-15s %-15s\n", "Querying VN", +					   "Querying UN"); +					fp(out, +					   "   %-20s %-15s %-15s %4s %-8s %-8s\n", +					   "Prefix", "Registered VN", +					   "Registered UN", "Cost", "Lifetime",  #if RFAPI_REGISTRATIONS_REPORT_AGE -                      "Age" +					   "Age"  #else -                      "Remaining" +					   "Remaining"  #endif -                      ); -                } -              if (!printednve) -                { -                  char str_vn[BUFSIZ]; -                  char str_un[BUFSIZ]; - -                  ++printednve; -                  ++nves_displayed; - -                  fp (out, "%-15s %-15s\n", -                      rfapiRfapiIpAddr2Str (&rfd->vn_addr, str_vn, BUFSIZ), -                      rfapiRfapiIpAddr2Str (&rfd->un_addr, str_un, BUFSIZ)); - -                } -              prefix2str (&rn->p, str_pfx, BUFSIZ); -              //fp(out, "  %s\n", buf);  /* prefix */ - -              routes_displayed++; -              nhs_displayed += print_rib_sl (fp, vty, out, sl, -                                             show_removed, str_pfx, -                                             &printedprefix); -            } -        } -    } - -  if (routes_total) -    { -      fp (out, "\n"); -      fp (out, "Displayed %u NVEs, and %u out of %u %s prefixes", -          nves_displayed, routes_displayed, -          routes_total, show_removed ? "removed" : "active"); -      if (nhs_displayed != routes_displayed || nhs_total != routes_total) -        fp (out, " with %u out of %u next hops", nhs_displayed, nhs_total); -      fp (out, "\n"); -    } +					   ); +				} +				if (!printednve) { +					char str_vn[BUFSIZ]; +					char str_un[BUFSIZ]; + +					++printednve; +					++nves_displayed; + +					fp(out, "%-15s %-15s\n", +					   rfapiRfapiIpAddr2Str(&rfd->vn_addr, +								str_vn, BUFSIZ), +					   rfapiRfapiIpAddr2Str(&rfd->un_addr, +								str_un, +								BUFSIZ)); +				} +				prefix2str(&rn->p, str_pfx, BUFSIZ); +				// fp(out, "  %s\n", buf);  /* prefix */ + +				routes_displayed++; +				nhs_displayed += print_rib_sl( +					fp, vty, out, sl, show_removed, str_pfx, +					&printedprefix); +			} +		} +	} + +	if (routes_total) { +		fp(out, "\n"); +		fp(out, "Displayed %u NVEs, and %u out of %u %s prefixes", +		   nves_displayed, routes_displayed, routes_total, +		   show_removed ? "removed" : "active"); +		if (nhs_displayed != routes_displayed +		    || nhs_total != routes_total) +			fp(out, " with %u out of %u next hops", nhs_displayed, +			   nhs_total); +		fp(out, "\n"); +	}  } diff --git a/bgpd/rfapi/rfapi_rib.h b/bgpd/rfapi/rfapi_rib.h index 40e4c0c2f2..0542727c2e 100644 --- a/bgpd/rfapi/rfapi_rib.h +++ b/bgpd/rfapi/rfapi_rib.h @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2009-2016, LabN Consulting, L.L.C.   * @@ -33,16 +33,15 @@   * For L2 RIBs, it is possible to have multiple routes to a given L2   * prefix via a given VN address, but each route having a unique aux_prefix.   */ -struct rfapi_rib_key -{ -  struct prefix		vn; -  struct prefix_rd	rd; - -  /* -   * for L2 routes: optional IP addr -   * .family == 0 means "none" -   */ -  struct prefix aux_prefix; +struct rfapi_rib_key { +	struct prefix vn; +	struct prefix_rd rd; + +	/* +	 * for L2 routes: optional IP addr +	 * .family == 0 means "none" +	 */ +	struct prefix aux_prefix;  };  #include "rfapi.h" @@ -51,118 +50,90 @@ struct rfapi_rib_key   *   * Holds NVE prefix advertisement information   */ -struct rfapi_adb -{ -  union { -    struct { -      struct prefix		prefix_ip; -      struct prefix_rd		prd; -      struct prefix		prefix_eth; -    } s;                                        /* mainly for legacy use */ -    struct rfapi_rib_key        key; -  } u; -  uint32_t			lifetime; -  uint8_t			cost; -  struct rfapi_l2address_option	l2o; +struct rfapi_adb { +	union { +		struct { +			struct prefix prefix_ip; +			struct prefix_rd prd; +			struct prefix prefix_eth; +		} s; /* mainly for legacy use */ +		struct rfapi_rib_key key; +	} u; +	uint32_t lifetime; +	uint8_t cost; +	struct rfapi_l2address_option l2o;  }; -struct rfapi_info -{ -  struct rfapi_rib_key		rk;		/* NVE VN addr + aux addr */ -  struct prefix			un; -  uint8_t			cost; -  uint32_t			lifetime; -  time_t			last_sent_time; -  uint32_t			rsp_counter;	/* dedup initial responses */ -  struct bgp_tea_options	*tea_options; -  struct rfapi_un_option	*un_options; -  struct rfapi_vn_option	*vn_options; -  struct thread		*timer; +struct rfapi_info { +	struct rfapi_rib_key rk; /* NVE VN addr + aux addr */ +	struct prefix un; +	uint8_t cost; +	uint32_t lifetime; +	time_t last_sent_time; +	uint32_t rsp_counter; /* dedup initial responses */ +	struct bgp_tea_options *tea_options; +	struct rfapi_un_option *un_options; +	struct rfapi_vn_option *vn_options; +	struct thread *timer;  };  /*   * Work item for updated responses queue   */ -struct rfapi_updated_responses_queue -{ -  struct rfapi_descriptor	*rfd; -  afi_t				afi; +struct rfapi_updated_responses_queue { +	struct rfapi_descriptor *rfd; +	afi_t afi;  }; -extern void -rfapiRibClear (struct rfapi_descriptor *rfd); +extern void rfapiRibClear(struct rfapi_descriptor *rfd); -extern void -rfapiRibFree (struct rfapi_descriptor *rfd); +extern void rfapiRibFree(struct rfapi_descriptor *rfd); -extern void -rfapiRibUpdatePendingNode ( -  struct bgp			*bgp, -  struct rfapi_descriptor	*rfd, -  struct rfapi_import_table	*it, -  struct route_node		*it_node, -  uint32_t			lifetime); +extern void rfapiRibUpdatePendingNode(struct bgp *bgp, +				      struct rfapi_descriptor *rfd, +				      struct rfapi_import_table *it, +				      struct route_node *it_node, +				      uint32_t lifetime); -extern void -rfapiRibUpdatePendingNodeSubtree ( -  struct bgp			*bgp, -  struct rfapi_descriptor	*rfd, -  struct rfapi_import_table	*it, -  struct route_node		*it_node, -  struct route_node		*omit_subtree, -  uint32_t			lifetime); - -extern int -rfapiRibPreloadBi( -  struct route_node *rfd_rib_node, -  struct prefix     *pfx_vn, -  struct prefix     *pfx_un, -  uint32_t          lifetime, -  struct bgp_info   *bi); +extern void rfapiRibUpdatePendingNodeSubtree(struct bgp *bgp, +					     struct rfapi_descriptor *rfd, +					     struct rfapi_import_table *it, +					     struct route_node *it_node, +					     struct route_node *omit_subtree, +					     uint32_t lifetime); + +extern int rfapiRibPreloadBi(struct route_node *rfd_rib_node, +			     struct prefix *pfx_vn, struct prefix *pfx_un, +			     uint32_t lifetime, struct bgp_info *bi);  extern struct rfapi_next_hop_entry * -rfapiRibPreload ( -  struct bgp			*bgp, -  struct rfapi_descriptor	*rfd, -  struct rfapi_next_hop_entry	*response, -  int				use_eth_resolution); +rfapiRibPreload(struct bgp *bgp, struct rfapi_descriptor *rfd, +		struct rfapi_next_hop_entry *response, int use_eth_resolution); -extern void -rfapiRibPendingDeleteRoute ( -  struct bgp			*bgp, -  struct rfapi_import_table	*it, -  afi_t				afi, -  struct route_node		*it_node); +extern void rfapiRibPendingDeleteRoute(struct bgp *bgp, +				       struct rfapi_import_table *it, afi_t afi, +				       struct route_node *it_node); -extern void -rfapiRibShowResponsesSummary (void *stream); +extern void rfapiRibShowResponsesSummary(void *stream); -extern void -rfapiRibShowResponsesSummaryClear (void); +extern void rfapiRibShowResponsesSummaryClear(void); -extern void -rfapiRibShowResponses ( -  void		*stream, -  struct prefix	*pfx_match, -  int		show_removed); +extern void rfapiRibShowResponses(void *stream, struct prefix *pfx_match, +				  int show_removed); -extern int -rfapiRibFTDFilterRecentPrefix( -  struct rfapi_descriptor	*rfd, -  struct route_node             *it_rn,                /* import table node */ -  struct prefix                 *pfx_target_original); /* query target */ +extern int rfapiRibFTDFilterRecentPrefix( +	struct rfapi_descriptor *rfd, +	struct route_node *it_rn,	    /* import table node */ +	struct prefix *pfx_target_original); /* query target */ -extern void -rfapiFreeRfapiUnOptionChain (struct rfapi_un_option *p); +extern void rfapiFreeRfapiUnOptionChain(struct rfapi_un_option *p); -extern void -rfapiFreeRfapiVnOptionChain (struct rfapi_vn_option *p); +extern void rfapiFreeRfapiVnOptionChain(struct rfapi_vn_option *p);  extern void -rfapiRibCheckCounts ( -  int		checkstats,	/* validate rfd & global counts */ -  unsigned int	offset);	/* number of ri's held separately */ +rfapiRibCheckCounts(int checkstats,       /* validate rfd & global counts */ +		    unsigned int offset); /* number of ri's held separately */  /* enable for debugging; disable for performance */  #if 0 @@ -171,16 +142,13 @@ rfapiRibCheckCounts (  #define RFAPI_RIB_CHECK_COUNTS(checkstats, offset)  #endif -extern void -rfapi_rib_key_init (struct prefix        *prefix, /* may be NULL */ -                    struct prefix_rd     *rd,     /* may be NULL */ -                    struct prefix        *aux,    /* may be NULL */ -                    struct rfapi_rib_key *rk); +extern void rfapi_rib_key_init(struct prefix *prefix, /* may be NULL */ +			       struct prefix_rd *rd,  /* may be NULL */ +			       struct prefix *aux,    /* may be NULL */ +			       struct rfapi_rib_key *rk); -extern int -rfapi_rib_key_cmp (void *k1, void *k2); +extern int rfapi_rib_key_cmp(void *k1, void *k2); -extern void -rfapiAdbFree (struct rfapi_adb *adb); +extern void rfapiAdbFree(struct rfapi_adb *adb);  #endif /* QUAGGA_HGP_RFAPI_RIB_H */ diff --git a/bgpd/rfapi/rfapi_vty.c b/bgpd/rfapi/rfapi_vty.c index 103f87ed0b..98c3decbd8 100644 --- a/bgpd/rfapi/rfapi_vty.c +++ b/bgpd/rfapi/rfapi_vty.c @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2009-2016, LabN Consulting, L.L.C.   * @@ -69,68 +69,53 @@  #define FMT_DAY     (24  * FMT_HOUR)  #define FMT_YEAR    (365 * FMT_DAY) -char * -rfapiFormatSeconds (uint32_t seconds, char *buf, size_t len) +char *rfapiFormatSeconds(uint32_t seconds, char *buf, size_t len)  { -  int year, day, hour, min; - -  if (seconds >= FMT_YEAR) -    { -      year = seconds / FMT_YEAR; -      seconds -= year * FMT_YEAR; -    } -  else -    year = 0; - -  if (seconds >= FMT_DAY) -    { -      day = seconds / FMT_DAY; -      seconds -= day * FMT_DAY; -    } -  else -    day = 0; - -  if (seconds >= FMT_HOUR) -    { -      hour = seconds / FMT_HOUR; -      seconds -= hour * FMT_HOUR; -    } -  else -    hour = 0; - -  if (seconds >= FMT_MIN) -    { -      min = seconds / FMT_MIN; -      seconds -= min * FMT_MIN; -    } -  else -    min = 0; - -  if (year > 0) -    { -      snprintf (buf, len, "%dy%dd%dh", year, day, hour); -    } -  else if (day > 0) -    { -      snprintf (buf, len, "%dd%dh%dm", day, hour, min); -    } -  else -    { -      snprintf (buf, len, "%02d:%02d:%02d", hour, min, seconds); -    } - -  return buf; +	int year, day, hour, min; + +	if (seconds >= FMT_YEAR) { +		year = seconds / FMT_YEAR; +		seconds -= year * FMT_YEAR; +	} else +		year = 0; + +	if (seconds >= FMT_DAY) { +		day = seconds / FMT_DAY; +		seconds -= day * FMT_DAY; +	} else +		day = 0; + +	if (seconds >= FMT_HOUR) { +		hour = seconds / FMT_HOUR; +		seconds -= hour * FMT_HOUR; +	} else +		hour = 0; + +	if (seconds >= FMT_MIN) { +		min = seconds / FMT_MIN; +		seconds -= min * FMT_MIN; +	} else +		min = 0; + +	if (year > 0) { +		snprintf(buf, len, "%dy%dd%dh", year, day, hour); +	} else if (day > 0) { +		snprintf(buf, len, "%dd%dh%dm", day, hour, min); +	} else { +		snprintf(buf, len, "%02d:%02d:%02d", hour, min, seconds); +	} + +	return buf;  } -char * -rfapiFormatAge (time_t age, char *buf, size_t len) +char *rfapiFormatAge(time_t age, char *buf, size_t len)  { -  time_t now, age_adjusted; +	time_t now, age_adjusted; -  now = rfapi_time (NULL); -  age_adjusted = now - age; +	now = rfapi_time(NULL); +	age_adjusted = now - age; -  return rfapiFormatSeconds (age_adjusted, buf, len); +	return rfapiFormatSeconds(age_adjusted, buf, len);  } @@ -138,47 +123,43 @@ rfapiFormatAge (time_t age, char *buf, size_t len)   * Reimplementation of quagga/lib/prefix.c function, but   * for RFAPI-style prefixes   */ -void -rfapiRprefixApplyMask (struct rfapi_ip_prefix *rprefix) +void rfapiRprefixApplyMask(struct rfapi_ip_prefix *rprefix)  { -  uint8_t *pnt; -  int index; -  int offset; - -  static uint8_t maskbit[] = -    { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff }; - -  switch (rprefix->prefix.addr_family) -    { -    case AF_INET: -      index = rprefix->length / 8; -      if (index < 4) -        { -          pnt = (uint8_t *) & rprefix->prefix.addr.v4; -          offset = rprefix->length % 8; -          pnt[index] &= maskbit[offset]; -          index++; -          while (index < 4) -            pnt[index++] = 0; -        } -      break; - -    case AF_INET6: -      index = rprefix->length / 8; -      if (index < 16) -        { -          pnt = (uint8_t *) & rprefix->prefix.addr.v6; -          offset = rprefix->length % 8; -          pnt[index] &= maskbit[offset]; -          index++; -          while (index < 16) -            pnt[index++] = 0; -        } -      break; - -    default: -      assert (0); -    } +	uint8_t *pnt; +	int index; +	int offset; + +	static uint8_t maskbit[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0, +				    0xf8, 0xfc, 0xfe, 0xff}; + +	switch (rprefix->prefix.addr_family) { +	case AF_INET: +		index = rprefix->length / 8; +		if (index < 4) { +			pnt = (uint8_t *)&rprefix->prefix.addr.v4; +			offset = rprefix->length % 8; +			pnt[index] &= maskbit[offset]; +			index++; +			while (index < 4) +				pnt[index++] = 0; +		} +		break; + +	case AF_INET6: +		index = rprefix->length / 8; +		if (index < 16) { +			pnt = (uint8_t *)&rprefix->prefix.addr.v6; +			offset = rprefix->length % 8; +			pnt[index] &= maskbit[offset]; +			index++; +			while (index < 16) +				pnt[index++] = 0; +		} +		break; + +	default: +		assert(0); +	}  }  /* @@ -190,71 +171,67 @@ rfapiRprefixApplyMask (struct rfapi_ip_prefix *rprefix)   *	0	Success   *	<0	Error   */ -int -rfapiQprefix2Raddr (struct prefix *qprefix, struct rfapi_ip_addr *raddr) +int rfapiQprefix2Raddr(struct prefix *qprefix, struct rfapi_ip_addr *raddr)  { -  memset (raddr, 0, sizeof (struct rfapi_ip_addr)); -  raddr->addr_family = qprefix->family; -  switch (qprefix->family) -    { -    case AF_INET: -      if (qprefix->prefixlen != 32) -        return -1; -      raddr->addr.v4 = qprefix->u.prefix4; -      break; -    case AF_INET6: -      if (qprefix->prefixlen != 128) -        return -1; -      raddr->addr.v6 = qprefix->u.prefix6; -      break; -    default: -      return -1; -    } -  return 0; +	memset(raddr, 0, sizeof(struct rfapi_ip_addr)); +	raddr->addr_family = qprefix->family; +	switch (qprefix->family) { +	case AF_INET: +		if (qprefix->prefixlen != 32) +			return -1; +		raddr->addr.v4 = qprefix->u.prefix4; +		break; +	case AF_INET6: +		if (qprefix->prefixlen != 128) +			return -1; +		raddr->addr.v6 = qprefix->u.prefix6; +		break; +	default: +		return -1; +	} +	return 0;  } -/*  +/*   * Translate Quagga prefix to RFAPI prefix   */  /* rprefix->cost set to 0 */ -void -rfapiQprefix2Rprefix (struct prefix *qprefix, struct rfapi_ip_prefix *rprefix) +void rfapiQprefix2Rprefix(struct prefix *qprefix, +			  struct rfapi_ip_prefix *rprefix)  { -  memset (rprefix, 0, sizeof (struct rfapi_ip_prefix)); -  rprefix->length = qprefix->prefixlen; -  rprefix->prefix.addr_family = qprefix->family; -  switch (qprefix->family) -    { -    case AF_INET: -      rprefix->prefix.addr.v4 = qprefix->u.prefix4; -      break; -    case AF_INET6: -      rprefix->prefix.addr.v6 = qprefix->u.prefix6; -      break; -    default: -      assert (0); -    } +	memset(rprefix, 0, sizeof(struct rfapi_ip_prefix)); +	rprefix->length = qprefix->prefixlen; +	rprefix->prefix.addr_family = qprefix->family; +	switch (qprefix->family) { +	case AF_INET: +		rprefix->prefix.addr.v4 = qprefix->u.prefix4; +		break; +	case AF_INET6: +		rprefix->prefix.addr.v6 = qprefix->u.prefix6; +		break; +	default: +		assert(0); +	}  } -int -rfapiRprefix2Qprefix (struct rfapi_ip_prefix *rprefix, struct prefix *qprefix) +int rfapiRprefix2Qprefix(struct rfapi_ip_prefix *rprefix, +			 struct prefix *qprefix)  { -  memset (qprefix, 0, sizeof (struct prefix)); -  qprefix->prefixlen = rprefix->length; -  qprefix->family = rprefix->prefix.addr_family; - -  switch (rprefix->prefix.addr_family) -    { -    case AF_INET: -      qprefix->u.prefix4 = rprefix->prefix.addr.v4; -      break; -    case AF_INET6: -      qprefix->u.prefix6 = rprefix->prefix.addr.v6; -      break; -    default: -      return EAFNOSUPPORT; -    } -  return 0; +	memset(qprefix, 0, sizeof(struct prefix)); +	qprefix->prefixlen = rprefix->length; +	qprefix->family = rprefix->prefix.addr_family; + +	switch (rprefix->prefix.addr_family) { +	case AF_INET: +		qprefix->u.prefix4 = rprefix->prefix.addr.v4; +		break; +	case AF_INET6: +		qprefix->u.prefix6 = rprefix->prefix.addr.v6; +		break; +	default: +		return EAFNOSUPPORT; +	} +	return 0;  }  /* @@ -264,122 +241,111 @@ rfapiRprefix2Qprefix (struct rfapi_ip_prefix *rprefix, struct prefix *qprefix)   * For paralellism with quagga/lib/prefix.c. if we need a comparison   * where host bits are ignored, call that function rfapiRprefixCmp.   */ -int -rfapiRprefixSame (struct rfapi_ip_prefix *hp1, struct rfapi_ip_prefix *hp2) +int rfapiRprefixSame(struct rfapi_ip_prefix *hp1, struct rfapi_ip_prefix *hp2)  { -  if (hp1->prefix.addr_family != hp2->prefix.addr_family) -    return 0; -  if (hp1->length != hp2->length) -    return 0; -  if (hp1->prefix.addr_family == AF_INET) -    if (IPV4_ADDR_SAME (&hp1->prefix.addr.v4, &hp2->prefix.addr.v4)) -      return 1; -  if (hp1->prefix.addr_family == AF_INET6) -    if (IPV6_ADDR_SAME (&hp1->prefix.addr.v6, &hp2->prefix.addr.v6)) -      return 1; -  return 0; +	if (hp1->prefix.addr_family != hp2->prefix.addr_family) +		return 0; +	if (hp1->length != hp2->length) +		return 0; +	if (hp1->prefix.addr_family == AF_INET) +		if (IPV4_ADDR_SAME(&hp1->prefix.addr.v4, &hp2->prefix.addr.v4)) +			return 1; +	if (hp1->prefix.addr_family == AF_INET6) +		if (IPV6_ADDR_SAME(&hp1->prefix.addr.v6, &hp2->prefix.addr.v6)) +			return 1; +	return 0;  } -int -rfapiRaddr2Qprefix (struct rfapi_ip_addr *hia, struct prefix *pfx) +int rfapiRaddr2Qprefix(struct rfapi_ip_addr *hia, struct prefix *pfx)  { -  memset (pfx, 0, sizeof (struct prefix)); -  pfx->family = hia->addr_family; - -  switch (hia->addr_family) -    { -    case AF_INET: -      pfx->prefixlen = 32; -      pfx->u.prefix4 = hia->addr.v4; -      break; -    case AF_INET6: -      pfx->prefixlen = 128; -      pfx->u.prefix6 = hia->addr.v6; -      break; -    default: -      return EAFNOSUPPORT; -    } -  return 0; +	memset(pfx, 0, sizeof(struct prefix)); +	pfx->family = hia->addr_family; + +	switch (hia->addr_family) { +	case AF_INET: +		pfx->prefixlen = 32; +		pfx->u.prefix4 = hia->addr.v4; +		break; +	case AF_INET6: +		pfx->prefixlen = 128; +		pfx->u.prefix6 = hia->addr.v6; +		break; +	default: +		return EAFNOSUPPORT; +	} +	return 0;  } -void -rfapiL2o2Qprefix (struct rfapi_l2address_option *l2o, struct prefix *pfx) +void rfapiL2o2Qprefix(struct rfapi_l2address_option *l2o, struct prefix *pfx)  { -  memset (pfx, 0, sizeof (struct prefix)); -  pfx->family = AF_ETHERNET; -  pfx->prefixlen = 48; -  pfx->u.prefix_eth = l2o->macaddr; +	memset(pfx, 0, sizeof(struct prefix)); +	pfx->family = AF_ETHERNET; +	pfx->prefixlen = 48; +	pfx->u.prefix_eth = l2o->macaddr;  } -char * -rfapiEthAddr2Str (const struct ethaddr *ea, char *buf, int bufsize) +char *rfapiEthAddr2Str(const struct ethaddr *ea, char *buf, int bufsize)  { -  return prefix_mac2str (ea, buf, bufsize); +	return prefix_mac2str(ea, buf, bufsize);  } -int -rfapiStr2EthAddr (const char *str, struct ethaddr *ea) +int rfapiStr2EthAddr(const char *str, struct ethaddr *ea)  { -  unsigned int a[6]; -  int i; +	unsigned int a[6]; +	int i; -  if (sscanf (str, "%2x:%2x:%2x:%2x:%2x:%2x", -              a + 0, a + 1, a + 2, a + 3, a + 4, a + 5) != 6) -    { +	if (sscanf(str, "%2x:%2x:%2x:%2x:%2x:%2x", a + 0, a + 1, a + 2, a + 3, +		   a + 4, a + 5) +	    != 6) { -      return EINVAL; -    } +		return EINVAL; +	} -  for (i = 0; i < 6; ++i) -    ea->octet[i] = a[i] & 0xff; +	for (i = 0; i < 6; ++i) +		ea->octet[i] = a[i] & 0xff; -  return 0; +	return 0;  } -const char * -rfapi_ntop (int af, const void *src, char *buf, socklen_t size) +const char *rfapi_ntop(int af, const void *src, char *buf, socklen_t size)  { -  if (af == AF_ETHERNET) -    { -      return rfapiEthAddr2Str ((const struct ethaddr *) src, buf, size); -    } +	if (af == AF_ETHERNET) { +		return rfapiEthAddr2Str((const struct ethaddr *)src, buf, size); +	} -  return inet_ntop (af, src, buf, size); +	return inet_ntop(af, src, buf, size);  } -int -rfapiDebugPrintf (void *dummy, const char *format, ...) +int rfapiDebugPrintf(void *dummy, const char *format, ...)  { -  va_list args; -  va_start (args, format); -  vzlog (LOG_DEBUG, format, args); -  va_end (args); -  return 0; +	va_list args; +	va_start(args, format); +	vzlog(LOG_DEBUG, format, args); +	va_end(args); +	return 0;  } -static int -rfapiStdioPrintf (void *stream, const char *format, ...) +static int rfapiStdioPrintf(void *stream, const char *format, ...)  { -  FILE *file = NULL; - -  va_list args; -  va_start (args, format); - -  switch ((uintptr_t) stream) -    { -    case 1: -      file = stdout; -      break; -    case 2: -      file = stderr; -      break; -    default: -      assert (0); -    } - -  vfprintf (file, format, args); -  va_end (args); -  return 0; +	FILE *file = NULL; + +	va_list args; +	va_start(args, format); + +	switch ((uintptr_t)stream) { +	case 1: +		file = stdout; +		break; +	case 2: +		file = stderr; +		break; +	default: +		assert(0); +	} + +	vfprintf(file, format, args); +	va_end(args); +	return 0;  }  /* Fake out for debug logging */ @@ -387,1133 +353,1016 @@ static struct vty vty_dummy_zlog;  static struct vty vty_dummy_stdio;  #define HVTYNL ((vty == &vty_dummy_zlog)? "": "\n") -static const char * -str_vty_newline (struct vty *vty) +static const char *str_vty_newline(struct vty *vty)  { -  if (vty == &vty_dummy_zlog) -    return ""; -  return "\n"; +	if (vty == &vty_dummy_zlog) +		return ""; +	return "\n";  } -int -rfapiStream2Vty ( -  void	*stream,					/* input */ -  int		(**fp) (void *, const char *, ...),	/* output */ -  struct vty	**vty,					/* output */ -  void	**outstream,					/* output */ -  const char	**vty_newline)				/* output */ +int rfapiStream2Vty(void *stream,			   /* input */ +		    int (**fp)(void *, const char *, ...), /* output */ +		    struct vty **vty,			   /* output */ +		    void **outstream,			   /* output */ +		    const char **vty_newline)		   /* output */  { -  if (!stream) -    { -      vty_dummy_zlog.type = VTY_SHELL;  /* for VTYNL */ -      *vty = &vty_dummy_zlog; -      *fp = (int (*)(void *, const char *,...)) rfapiDebugPrintf; -      *outstream = NULL; -      *vty_newline = str_vty_newline (*vty); -      return (vzlog_test (LOG_DEBUG)); -    } - -  if (((uintptr_t) stream == (uintptr_t) 1) || -      ((uintptr_t) stream == (uintptr_t) 2)) -    { - -      vty_dummy_stdio.type = VTY_SHELL; /* for VTYNL */ -      *vty = &vty_dummy_stdio; -      *fp = (int (*)(void *, const char *,...)) rfapiStdioPrintf; -      *outstream = stream; -      *vty_newline = str_vty_newline (*vty); -      return 1; -    } - -  if (stream) -    { -      *vty = stream;            /* VTYNL requires vty to be legit */ -      *fp = (int (*)(void *, const char *,...)) vty_out; -      *outstream = stream; -      *vty_newline = str_vty_newline (*vty); -      return 1; -    } - -  return 0; +	if (!stream) { +		vty_dummy_zlog.type = VTY_SHELL; /* for VTYNL */ +		*vty = &vty_dummy_zlog; +		*fp = (int (*)(void *, const char *, ...))rfapiDebugPrintf; +		*outstream = NULL; +		*vty_newline = str_vty_newline(*vty); +		return (vzlog_test(LOG_DEBUG)); +	} + +	if (((uintptr_t)stream == (uintptr_t)1) +	    || ((uintptr_t)stream == (uintptr_t)2)) { + +		vty_dummy_stdio.type = VTY_SHELL; /* for VTYNL */ +		*vty = &vty_dummy_stdio; +		*fp = (int (*)(void *, const char *, ...))rfapiStdioPrintf; +		*outstream = stream; +		*vty_newline = str_vty_newline(*vty); +		return 1; +	} + +	if (stream) { +		*vty = stream; /* VTYNL requires vty to be legit */ +		*fp = (int (*)(void *, const char *, ...))vty_out; +		*outstream = stream; +		*vty_newline = str_vty_newline(*vty); +		return 1; +	} + +	return 0;  }  /* called from bgpd/bgp_vty.c'route_vty_out() */ -void -rfapi_vty_out_vncinfo ( -  struct vty		*vty, -  struct prefix		*p, -  struct bgp_info	*bi, -  safi_t		safi) +void rfapi_vty_out_vncinfo(struct vty *vty, struct prefix *p, +			   struct bgp_info *bi, safi_t safi)  { -  char *s; -  uint32_t lifetime; - -  /* -   * Print, on an indented line: -   *  UN address [if VPN route and VNC UN addr subtlv] -   *  EC list -   *  VNC lifetime -   */ -  vty_out (vty, "    "); - -  if (safi == SAFI_MPLS_VPN) -    { -      struct prefix pfx_un; - -      if (!rfapiGetVncTunnelUnAddr (bi->attr, &pfx_un)) -        { -          char buf[BUFSIZ]; -          vty_out (vty, "UN=%s", inet_ntop (pfx_un.family, -                                            pfx_un.u.val, buf, BUFSIZ)); -        } -    } - -  if (bi->attr && bi->attr->ecommunity) -    { -      s = ecommunity_ecom2str (bi->attr->ecommunity, -                               ECOMMUNITY_FORMAT_ROUTE_MAP, 0); -      vty_out (vty, " EC{%s}", s); -      XFREE (MTYPE_ECOMMUNITY_STR, s); -    } - -  if (bi->extra != NULL) -    vty_out (vty, " label=%u", decode_label (&bi->extra->label)); - -  if (!rfapiGetVncLifetime (bi->attr, &lifetime)) -    { -      vty_out (vty, " life=%d", lifetime); -    } - -  vty_out (vty, " type=%s, subtype=%d", -           zebra_route_string (bi->type), bi->sub_type); - -  vty_out (vty, "%s", HVTYNL); +	char *s; +	uint32_t lifetime; + +	/* +	 * Print, on an indented line: +	 *  UN address [if VPN route and VNC UN addr subtlv] +	 *  EC list +	 *  VNC lifetime +	 */ +	vty_out(vty, "    "); + +	if (safi == SAFI_MPLS_VPN) { +		struct prefix pfx_un; + +		if (!rfapiGetVncTunnelUnAddr(bi->attr, &pfx_un)) { +			char buf[BUFSIZ]; +			vty_out(vty, "UN=%s", +				inet_ntop(pfx_un.family, pfx_un.u.val, buf, +					  BUFSIZ)); +		} +	} + +	if (bi->attr && bi->attr->ecommunity) { +		s = ecommunity_ecom2str(bi->attr->ecommunity, +					ECOMMUNITY_FORMAT_ROUTE_MAP, 0); +		vty_out(vty, " EC{%s}", s); +		XFREE(MTYPE_ECOMMUNITY_STR, s); +	} + +	if (bi->extra != NULL) +		vty_out(vty, " label=%u", decode_label(&bi->extra->label)); + +	if (!rfapiGetVncLifetime(bi->attr, &lifetime)) { +		vty_out(vty, " life=%d", lifetime); +	} + +	vty_out(vty, " type=%s, subtype=%d", zebra_route_string(bi->type), +		bi->sub_type); + +	vty_out(vty, "%s", HVTYNL);  } -void -rfapiPrintAttrPtrs (void *stream, struct attr *attr) +void rfapiPrintAttrPtrs(void *stream, struct attr *attr)  { -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; - -  char buf[BUFSIZ]; - -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; - -  fp (out, "Attr[%p]:%s", attr, HVTYNL); -  if (!attr) -    return; - -  /* IPv4 Nexthop */ -  inet_ntop (AF_INET, &attr->nexthop, buf, BUFSIZ); -  fp (out, "  nexthop=%s%s", buf, HVTYNL); - -  fp (out, "  aspath=%p, refcnt=%d%s", attr->aspath, -      (attr->aspath ? attr->aspath->refcnt : 0), HVTYNL); -  fp (out, "  community=%p, refcnt=%d%s", attr->community, -      (attr->community ? attr->community->refcnt : 0), HVTYNL); - -  fp (out, "  ecommunity=%p, refcnt=%d%s", attr->ecommunity, -      (attr->ecommunity ? attr->ecommunity->refcnt : 0), HVTYNL); -  fp (out, "  cluster=%p, refcnt=%d%s", attr->cluster, -      (attr->cluster ? attr->cluster->refcnt : 0), HVTYNL); -  fp (out, "  transit=%p, refcnt=%d%s", attr->transit, -      (attr->transit ? attr->transit->refcnt : 0), HVTYNL); +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; + +	char buf[BUFSIZ]; + +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; + +	fp(out, "Attr[%p]:%s", attr, HVTYNL); +	if (!attr) +		return; + +	/* IPv4 Nexthop */ +	inet_ntop(AF_INET, &attr->nexthop, buf, BUFSIZ); +	fp(out, "  nexthop=%s%s", buf, HVTYNL); + +	fp(out, "  aspath=%p, refcnt=%d%s", attr->aspath, +	   (attr->aspath ? attr->aspath->refcnt : 0), HVTYNL); +	fp(out, "  community=%p, refcnt=%d%s", attr->community, +	   (attr->community ? attr->community->refcnt : 0), HVTYNL); + +	fp(out, "  ecommunity=%p, refcnt=%d%s", attr->ecommunity, +	   (attr->ecommunity ? attr->ecommunity->refcnt : 0), HVTYNL); +	fp(out, "  cluster=%p, refcnt=%d%s", attr->cluster, +	   (attr->cluster ? attr->cluster->refcnt : 0), HVTYNL); +	fp(out, "  transit=%p, refcnt=%d%s", attr->transit, +	   (attr->transit ? attr->transit->refcnt : 0), HVTYNL);  }  /*   * Print BI in an Import Table   */ -void -rfapiPrintBi (void *stream, struct bgp_info *bi) +void rfapiPrintBi(void *stream, struct bgp_info *bi)  { -  char buf[BUFSIZ]; -  char *s; - -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; - -  char line[BUFSIZ]; -  char *p = line; -  int r; -  int has_macaddr = 0; -  struct ethaddr macaddr; -  struct rfapi_l2address_option l2o_buf; -  uint8_t l2hid=0;                /* valid if has_macaddr */ +	char buf[BUFSIZ]; +	char *s; + +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; + +	char line[BUFSIZ]; +	char *p = line; +	int r; +	int has_macaddr = 0; +	struct ethaddr macaddr; +	struct rfapi_l2address_option l2o_buf; +	uint8_t l2hid = 0; /* valid if has_macaddr */  #define REMAIN (BUFSIZ - (p-line))  #define INCP {p += (r > REMAIN)? REMAIN: r;} -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; - -  if (!bi) -    return; - -  if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED) && bi->extra -      && bi->extra->vnc.import.timer) -    { -      struct thread *t = (struct thread *) bi->extra->vnc.import.timer; -      r = snprintf (p, REMAIN, " [%4lu] ", thread_timer_remain_second (t)); -      INCP; - -    } -  else -    { -      r = snprintf (p, REMAIN, "        "); -      INCP; -    } - -  if (bi->extra) -    { -      /* TBD This valid only for SAFI_MPLS_VPN, but not for encap */ -      if (decode_rd_type(bi->extra->vnc.import.rd.val) == RD_TYPE_VNC_ETH) -        { -          has_macaddr = 1; -          memcpy (macaddr.octet, bi->extra->vnc.import.rd.val + 2, 6); -          l2hid = bi->extra->vnc.import.rd.val[1]; -        } -    } - -  /* -   * Print these items: -   *          type/subtype -   *          nexthop address -   *          lifetime -   *          RFP option sizes (they are opaque values) -   *          extended communities (RTs) -   */ -  if (bi->attr) -    { -      uint32_t lifetime; -      int printed_1st_gol = 0; -      struct bgp_attr_encap_subtlv *pEncap; -      struct prefix pfx_un; -      int af = BGP_MP_NEXTHOP_FAMILY (bi->attr->mp_nexthop_len); - -      /* Nexthop */ -      if (af == AF_INET) -        { -          r = snprintf (p, REMAIN, "%s", inet_ntop (AF_INET, -                                                    &bi->attr->mp_nexthop_global_in, -                                                    buf, BUFSIZ)); -          INCP; -        } -      else if (af == AF_INET6) -        { -          r = snprintf (p, REMAIN, "%s", inet_ntop (AF_INET6, -                                                    &bi->attr->mp_nexthop_global, -                                                    buf, BUFSIZ)); -          INCP; -        } -      else -        { -          r = snprintf (p, REMAIN, "?"); -          INCP; -        } - -      /* -       * VNC tunnel subtlv, if present, contains UN address -       */ -      if (!rfapiGetVncTunnelUnAddr (bi->attr, &pfx_un)) -        { -          r = snprintf (p, REMAIN, " un=%s", inet_ntop (pfx_un.family, -                                                        pfx_un.u.val, buf, -                                                        BUFSIZ)); -          INCP; - -        } - -      /* Lifetime */ -      if (rfapiGetVncLifetime (bi->attr, &lifetime)) -        { -          r = snprintf (p, REMAIN, " nolife"); -          INCP; -        } -      else -        { -          if (lifetime == 0xffffffff) -            r = snprintf (p, REMAIN, " %6s", "infini"); -          else -            r = snprintf (p, REMAIN, " %6u", lifetime); -          INCP; -        } - -      /* RFP option lengths */ -      for (pEncap = bi->attr->vnc_subtlvs; pEncap; -           pEncap = pEncap->next) -        { - -          if (pEncap->type == BGP_VNC_SUBTLV_TYPE_RFPOPTION) -            { -              if (printed_1st_gol) -                { -                  r = snprintf (p, REMAIN, ","); -                  INCP; -                } -              else -                { -                  r = snprintf (p, REMAIN, " ");        /* leading space */ -                  INCP; -                } -              r = snprintf (p, REMAIN, "%d", pEncap->length); -              INCP; -              printed_1st_gol = 1; -            } -        } - -      /* RT list */ -      if (bi->attr->ecommunity) -        { -          s = ecommunity_ecom2str (bi->attr->ecommunity, -                                   ECOMMUNITY_FORMAT_ROUTE_MAP, 0); -          r = snprintf (p, REMAIN, " %s", s); -          INCP; -          XFREE (MTYPE_ECOMMUNITY_STR, s); -        } - -    } - -  r = snprintf (p, REMAIN, " bi@%p", bi); -  INCP; - -  r = snprintf (p, REMAIN, " p@%p", bi->peer); -  INCP; - -  if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) -    { -      r = snprintf (p, REMAIN, " HD=yes"); -      INCP; -    } -  else -    { -      r = snprintf (p, REMAIN, " HD=no"); -      INCP; -    } - -  if (bi->attr) -    { - -      if (bi->attr->weight) -        { -          r = snprintf (p, REMAIN, " W=%d", bi->attr->weight); -          INCP; -        } - -      if (bi->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)) -        { -          r = snprintf (p, REMAIN, " LP=%d", bi->attr->local_pref); -          INCP; -        } -      else -        { -          r = snprintf (p, REMAIN, " LP=unset"); -          INCP; -        } -    } - -  r = -    snprintf (p, REMAIN, " %c:%u", zebra_route_char (bi->type), bi->sub_type); -  INCP; - -  fp (out, "%s%s", line, HVTYNL); - -  if (has_macaddr) -    { -      fp (out, "        RD HID=%d ETH=%02x:%02x:%02x:%02x:%02x:%02x%s", -          l2hid, -          macaddr.octet[0], -          macaddr.octet[1], -          macaddr.octet[2], -          macaddr.octet[3], macaddr.octet[4], macaddr.octet[5], HVTYNL); -    } - -  if (!rfapiGetL2o (bi->attr, &l2o_buf)) -    { -      fp (out, -          "        L2O ETH=%02x:%02x:%02x:%02x:%02x:%02x LBL=%d LNI=%d LHI=%hhu%s", -          l2o_buf.macaddr.octet[0], l2o_buf.macaddr.octet[1], -          l2o_buf.macaddr.octet[2], l2o_buf.macaddr.octet[3], -          l2o_buf.macaddr.octet[4], l2o_buf.macaddr.octet[5], l2o_buf.label, -          l2o_buf.logical_net_id, l2o_buf.local_nve_id, HVTYNL); -    } -  if (bi->extra && bi->extra->vnc.import.aux_prefix.family) -    { -      char buf[BUFSIZ]; -      const char *sp; - -      sp = rfapi_ntop (bi->extra->vnc.import.aux_prefix.family, -                       &bi->extra->vnc.import.aux_prefix.u.prefix, -                       buf, BUFSIZ); -      buf[BUFSIZ - 1] = 0; -      if (sp) -        { -          fp (out, "        IP: %s%s", sp, HVTYNL); -        } -    } -  { -    struct rfapi_un_option *uo = rfapi_encap_tlv_to_un_option (bi->attr); -    if (uo) -      { -        rfapi_print_tunneltype_option (stream, 8, &uo->v.tunnel); -        rfapi_un_options_free (uo); -      } -  } +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; + +	if (!bi) +		return; + +	if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED) && bi->extra +	    && bi->extra->vnc.import.timer) { +		struct thread *t = (struct thread *)bi->extra->vnc.import.timer; +		r = snprintf(p, REMAIN, " [%4lu] ", +			     thread_timer_remain_second(t)); +		INCP; + +	} else { +		r = snprintf(p, REMAIN, "        "); +		INCP; +	} + +	if (bi->extra) { +		/* TBD This valid only for SAFI_MPLS_VPN, but not for encap */ +		if (decode_rd_type(bi->extra->vnc.import.rd.val) +		    == RD_TYPE_VNC_ETH) { +			has_macaddr = 1; +			memcpy(macaddr.octet, bi->extra->vnc.import.rd.val + 2, +			       6); +			l2hid = bi->extra->vnc.import.rd.val[1]; +		} +	} + +	/* +	 * Print these items: +	 *          type/subtype +	 *          nexthop address +	 *          lifetime +	 *          RFP option sizes (they are opaque values) +	 *          extended communities (RTs) +	 */ +	if (bi->attr) { +		uint32_t lifetime; +		int printed_1st_gol = 0; +		struct bgp_attr_encap_subtlv *pEncap; +		struct prefix pfx_un; +		int af = BGP_MP_NEXTHOP_FAMILY(bi->attr->mp_nexthop_len); + +		/* Nexthop */ +		if (af == AF_INET) { +			r = snprintf(p, REMAIN, "%s", +				     inet_ntop(AF_INET, +					       &bi->attr->mp_nexthop_global_in, +					       buf, BUFSIZ)); +			INCP; +		} else if (af == AF_INET6) { +			r = snprintf(p, REMAIN, "%s", +				     inet_ntop(AF_INET6, +					       &bi->attr->mp_nexthop_global, +					       buf, BUFSIZ)); +			INCP; +		} else { +			r = snprintf(p, REMAIN, "?"); +			INCP; +		} + +		/* +		 * VNC tunnel subtlv, if present, contains UN address +		 */ +		if (!rfapiGetVncTunnelUnAddr(bi->attr, &pfx_un)) { +			r = snprintf(p, REMAIN, " un=%s", +				     inet_ntop(pfx_un.family, pfx_un.u.val, buf, +					       BUFSIZ)); +			INCP; +		} + +		/* Lifetime */ +		if (rfapiGetVncLifetime(bi->attr, &lifetime)) { +			r = snprintf(p, REMAIN, " nolife"); +			INCP; +		} else { +			if (lifetime == 0xffffffff) +				r = snprintf(p, REMAIN, " %6s", "infini"); +			else +				r = snprintf(p, REMAIN, " %6u", lifetime); +			INCP; +		} + +		/* RFP option lengths */ +		for (pEncap = bi->attr->vnc_subtlvs; pEncap; +		     pEncap = pEncap->next) { + +			if (pEncap->type == BGP_VNC_SUBTLV_TYPE_RFPOPTION) { +				if (printed_1st_gol) { +					r = snprintf(p, REMAIN, ","); +					INCP; +				} else { +					r = snprintf(p, REMAIN, +						     " "); /* leading space */ +					INCP; +				} +				r = snprintf(p, REMAIN, "%d", pEncap->length); +				INCP; +				printed_1st_gol = 1; +			} +		} + +		/* RT list */ +		if (bi->attr->ecommunity) { +			s = ecommunity_ecom2str(bi->attr->ecommunity, +						ECOMMUNITY_FORMAT_ROUTE_MAP, 0); +			r = snprintf(p, REMAIN, " %s", s); +			INCP; +			XFREE(MTYPE_ECOMMUNITY_STR, s); +		} +	} + +	r = snprintf(p, REMAIN, " bi@%p", bi); +	INCP; + +	r = snprintf(p, REMAIN, " p@%p", bi->peer); +	INCP; + +	if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) { +		r = snprintf(p, REMAIN, " HD=yes"); +		INCP; +	} else { +		r = snprintf(p, REMAIN, " HD=no"); +		INCP; +	} + +	if (bi->attr) { + +		if (bi->attr->weight) { +			r = snprintf(p, REMAIN, " W=%d", bi->attr->weight); +			INCP; +		} + +		if (bi->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) { +			r = snprintf(p, REMAIN, " LP=%d", bi->attr->local_pref); +			INCP; +		} else { +			r = snprintf(p, REMAIN, " LP=unset"); +			INCP; +		} +	} + +	r = snprintf(p, REMAIN, " %c:%u", zebra_route_char(bi->type), +		     bi->sub_type); +	INCP; + +	fp(out, "%s%s", line, HVTYNL); + +	if (has_macaddr) { +		fp(out, "        RD HID=%d ETH=%02x:%02x:%02x:%02x:%02x:%02x%s", +		   l2hid, macaddr.octet[0], macaddr.octet[1], macaddr.octet[2], +		   macaddr.octet[3], macaddr.octet[4], macaddr.octet[5], +		   HVTYNL); +	} + +	if (!rfapiGetL2o(bi->attr, &l2o_buf)) { +		fp(out, +		   "        L2O ETH=%02x:%02x:%02x:%02x:%02x:%02x LBL=%d LNI=%d LHI=%hhu%s", +		   l2o_buf.macaddr.octet[0], l2o_buf.macaddr.octet[1], +		   l2o_buf.macaddr.octet[2], l2o_buf.macaddr.octet[3], +		   l2o_buf.macaddr.octet[4], l2o_buf.macaddr.octet[5], +		   l2o_buf.label, l2o_buf.logical_net_id, l2o_buf.local_nve_id, +		   HVTYNL); +	} +	if (bi->extra && bi->extra->vnc.import.aux_prefix.family) { +		char buf[BUFSIZ]; +		const char *sp; + +		sp = rfapi_ntop(bi->extra->vnc.import.aux_prefix.family, +				&bi->extra->vnc.import.aux_prefix.u.prefix, buf, +				BUFSIZ); +		buf[BUFSIZ - 1] = 0; +		if (sp) { +			fp(out, "        IP: %s%s", sp, HVTYNL); +		} +	} +	{ +		struct rfapi_un_option *uo = +			rfapi_encap_tlv_to_un_option(bi->attr); +		if (uo) { +			rfapi_print_tunneltype_option(stream, 8, &uo->v.tunnel); +			rfapi_un_options_free(uo); +		} +	}  } -char * -rfapiMonitorVpn2Str (struct rfapi_monitor_vpn *m, char *buf, int size) +char *rfapiMonitorVpn2Str(struct rfapi_monitor_vpn *m, char *buf, int size)  { -  char buf_pfx[BUFSIZ]; -  char buf_vn[BUFSIZ]; -  char buf_un[BUFSIZ]; -  int rc; - -  rfapiRfapiIpAddr2Str (&m->rfd->un_addr, buf_vn, BUFSIZ); -  rfapiRfapiIpAddr2Str (&m->rfd->vn_addr, buf_un, BUFSIZ); - -  rc = snprintf (buf, size, -                 "m=%p, next=%p, rfd=%p(vn=%s un=%s), p=%s/%d, node=%p", -                 m, m->next, m->rfd, buf_vn, buf_un, -                 inet_ntop (m->p.family, &m->p.u.prefix, buf_pfx, BUFSIZ), -                 m->p.prefixlen, m->node); -  buf[size - 1] = 0; -  if (rc >= size) -    return NULL; -  return buf; +	char buf_pfx[BUFSIZ]; +	char buf_vn[BUFSIZ]; +	char buf_un[BUFSIZ]; +	int rc; + +	rfapiRfapiIpAddr2Str(&m->rfd->un_addr, buf_vn, BUFSIZ); +	rfapiRfapiIpAddr2Str(&m->rfd->vn_addr, buf_un, BUFSIZ); + +	rc = snprintf(buf, size, +		      "m=%p, next=%p, rfd=%p(vn=%s un=%s), p=%s/%d, node=%p", m, +		      m->next, m->rfd, buf_vn, buf_un, +		      inet_ntop(m->p.family, &m->p.u.prefix, buf_pfx, BUFSIZ), +		      m->p.prefixlen, m->node); +	buf[size - 1] = 0; +	if (rc >= size) +		return NULL; +	return buf;  } -static void -rfapiDebugPrintMonitorVpn (void *stream, struct rfapi_monitor_vpn *m) +static void rfapiDebugPrintMonitorVpn(void *stream, struct rfapi_monitor_vpn *m)  { -  char buf[BUFSIZ]; +	char buf[BUFSIZ]; -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; -  rfapiMonitorVpn2Str (m, buf, BUFSIZ); -  fp (out, "    Mon %s%s", buf, HVTYNL); +	rfapiMonitorVpn2Str(m, buf, BUFSIZ); +	fp(out, "    Mon %s%s", buf, HVTYNL);  } -static void -rfapiDebugPrintMonitorEncap (void *stream, struct rfapi_monitor_encap *m) +static void rfapiDebugPrintMonitorEncap(void *stream, +					struct rfapi_monitor_encap *m)  { -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out = NULL; -  const char *vty_newline; +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out = NULL; +	const char *vty_newline; -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; -  fp (out, "    Mon m=%p, next=%p, node=%p, bi=%p%s", -      m, m->next, m->node, m->bi, HVTYNL); +	fp(out, "    Mon m=%p, next=%p, node=%p, bi=%p%s", m, m->next, m->node, +	   m->bi, HVTYNL);  } -void -rfapiShowItNode (void *stream, struct route_node *rn) +void rfapiShowItNode(void *stream, struct route_node *rn)  { -  struct bgp_info *bi; -  char buf[BUFSIZ]; +	struct bgp_info *bi; +	char buf[BUFSIZ]; -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; -  fp (out, "%s/%d @%p #%d%s", -      rfapi_ntop (rn->p.family, &rn->p.u.prefix, buf, BUFSIZ), -      rn->p.prefixlen, rn, rn->lock, HVTYNL); +	fp(out, "%s/%d @%p #%d%s", +	   rfapi_ntop(rn->p.family, &rn->p.u.prefix, buf, BUFSIZ), +	   rn->p.prefixlen, rn, rn->lock, HVTYNL); -  for (bi = rn->info; bi; bi = bi->next) -    { -      rfapiPrintBi (stream, bi); -    } +	for (bi = rn->info; bi; bi = bi->next) { +		rfapiPrintBi(stream, bi); +	} -  /* doesn't show montors */ +	/* doesn't show montors */  } -void -rfapiShowImportTable ( -  void			*stream, -  const char		*label, -  struct route_table	*rt, -  int			isvpn) +void rfapiShowImportTable(void *stream, const char *label, +			  struct route_table *rt, int isvpn)  { -  struct route_node *rn; -  char buf[BUFSIZ]; - -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; - -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; - -  fp (out, "Import Table [%s]%s", label, HVTYNL); - -  for (rn = route_top (rt); rn; rn = route_next (rn)) -    { -      struct bgp_info *bi; - -      if (rn->p.family == AF_ETHERNET) -        { -          rfapiEthAddr2Str (&rn->p.u.prefix_eth, buf, BUFSIZ); -        } -      else -        { -          inet_ntop (rn->p.family, &rn->p.u.prefix, buf, BUFSIZ); -        } - -      fp (out, "%s/%d @%p #%d%s", buf, rn->p.prefixlen, rn, rn->lock - 1,       /* account for loop iterator locking */ -          HVTYNL); - -      for (bi = rn->info; bi; bi = bi->next) -        { -          rfapiPrintBi (stream, bi); -        } - -      if (isvpn) -        { -          struct rfapi_monitor_vpn *m; -          for (m = RFAPI_MONITOR_VPN (rn); m; m = m->next) -            { -              rfapiDebugPrintMonitorVpn (stream, m); -            } -        } -      else -        { -          struct rfapi_monitor_encap *m; -          for (m = RFAPI_MONITOR_ENCAP (rn); m; m = m->next) -            { -              rfapiDebugPrintMonitorEncap (stream, m); -            } -        } -    } +	struct route_node *rn; +	char buf[BUFSIZ]; + +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; + +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; + +	fp(out, "Import Table [%s]%s", label, HVTYNL); + +	for (rn = route_top(rt); rn; rn = route_next(rn)) { +		struct bgp_info *bi; + +		if (rn->p.family == AF_ETHERNET) { +			rfapiEthAddr2Str(&rn->p.u.prefix_eth, buf, BUFSIZ); +		} else { +			inet_ntop(rn->p.family, &rn->p.u.prefix, buf, BUFSIZ); +		} + +		fp(out, "%s/%d @%p #%d%s", buf, rn->p.prefixlen, rn, +		   rn->lock - 1, /* account for loop iterator locking */ +		   HVTYNL); + +		for (bi = rn->info; bi; bi = bi->next) { +			rfapiPrintBi(stream, bi); +		} + +		if (isvpn) { +			struct rfapi_monitor_vpn *m; +			for (m = RFAPI_MONITOR_VPN(rn); m; m = m->next) { +				rfapiDebugPrintMonitorVpn(stream, m); +			} +		} else { +			struct rfapi_monitor_encap *m; +			for (m = RFAPI_MONITOR_ENCAP(rn); m; m = m->next) { +				rfapiDebugPrintMonitorEncap(stream, m); +			} +		} +	}  } -int -rfapiShowVncQueries (void *stream, struct prefix *pfx_match) +int rfapiShowVncQueries(void *stream, struct prefix *pfx_match)  { -  struct bgp *bgp; -  struct rfapi *h; -  struct listnode *node; -  struct rfapi_descriptor *rfd; - -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; - -  int printedheader = 0; - -  int nves_total = 0; -  int nves_with_queries = 0; -  int nves_displayed = 0; - -  int queries_total = 0; -  int queries_displayed = 0; - -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return CMD_WARNING; - -  bgp = bgp_get_default ();     /* assume 1 instance for now */ -  if (!bgp) -    { -      vty_out (vty, "No BGP instance\n"); -      return CMD_WARNING; -    } - -  h = bgp->rfapi; -  if (!h) -    { -      vty_out (vty, "No RFAPI instance\n"); -      return CMD_WARNING; -    } - -  for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd)) -    { - -      struct route_node *rn; -      int printedquerier = 0; - - -      ++nves_total; - -      if (rfd->mon || (rfd->mon_eth && skiplist_count (rfd->mon_eth))) -        { -          ++nves_with_queries; -        } -      else -        { -          continue; -        } - -      /* -       * IP Queries -       */ -      if (rfd->mon) -        { -          for (rn = route_top (rfd->mon); rn; rn = route_next (rn)) -            { -              struct rfapi_monitor_vpn *m; -              char buf_remain[BUFSIZ]; -              char buf_pfx[BUFSIZ]; - -              if (!rn->info) -                continue; - -              m = rn->info; - -              ++queries_total; - -              if (pfx_match && !prefix_match (pfx_match, &rn->p) && -                  !prefix_match (&rn->p, pfx_match)) -                continue; - -              ++queries_displayed; - -              if (!printedheader) -                { -                  ++printedheader; -                  fp (out, "\n"); -                  fp (out, "%-15s %-15s %-15s %-10s\n", -                      "VN Address", "UN Address", -                      "Target", "Remaining"); -                } - -              if (!printedquerier) -                { -                  char buf_vn[BUFSIZ]; -                  char buf_un[BUFSIZ]; - -                  rfapiRfapiIpAddr2Str (&rfd->un_addr, buf_un, BUFSIZ); -                  rfapiRfapiIpAddr2Str (&rfd->vn_addr, buf_vn, BUFSIZ); - -                  fp (out, "%-15s %-15s", buf_vn, buf_un); -                  printedquerier = 1; - -                  ++nves_displayed; -                } -              else -                fp (out, "%-15s %-15s", "", ""); -              buf_remain[0] = 0; -              if (m->timer) -                { -                  rfapiFormatSeconds (thread_timer_remain_second (m->timer), -                                      buf_remain, BUFSIZ); -                } -              fp (out, " %-15s %-10s\n", -                  inet_ntop (m->p.family, &m->p.u.prefix, buf_pfx, BUFSIZ), -                  buf_remain); -            } -        } - -      /* -       * Ethernet Queries -       */ -      if (rfd->mon_eth && skiplist_count (rfd->mon_eth)) -        { - -          int rc; -          void *cursor; -          struct rfapi_monitor_eth *mon_eth; - -          for (cursor = NULL, -               rc = -               skiplist_next (rfd->mon_eth, NULL, (void **) &mon_eth, -                              &cursor); rc == 0; -               rc = -               skiplist_next (rfd->mon_eth, NULL, (void **) &mon_eth, -                              &cursor)) -            { - -              char buf_remain[BUFSIZ]; -              char buf_pfx[BUFSIZ]; -              struct prefix pfx_mac; - -              ++queries_total; - -              vnc_zlog_debug_verbose ("%s: checking rfd=%p mon_eth=%p", __func__, rfd, -                          mon_eth); - -              memset ((void *) &pfx_mac, 0, sizeof (struct prefix)); -              pfx_mac.family = AF_ETHERNET; -              pfx_mac.prefixlen = 48; -              pfx_mac.u.prefix_eth = mon_eth->macaddr; - -              if (pfx_match && !prefix_match (pfx_match, &pfx_mac) && -                  !prefix_match (&pfx_mac, pfx_match)) -                continue; - -              ++queries_displayed; - -              if (!printedheader) -                { -                  ++printedheader; -                  fp (out, "\n"); -                  fp (out, "%-15s %-15s %-17s %10s %-10s\n", -                      "VN Address", "UN Address", -                      "Target", "LNI", "Remaining"); -                } - -              if (!printedquerier) -                { -                  char buf_vn[BUFSIZ]; -                  char buf_un[BUFSIZ]; - -                  rfapiRfapiIpAddr2Str (&rfd->un_addr, buf_un, BUFSIZ); -                  rfapiRfapiIpAddr2Str (&rfd->vn_addr, buf_vn, BUFSIZ); - -                  fp (out, "%-15s %-15s", buf_vn, buf_un); -                  printedquerier = 1; - -                  ++nves_displayed; -                } -              else -                fp (out, "%-15s %-15s", "", ""); -              buf_remain[0] = 0; -              if (mon_eth->timer) -                { -                  rfapiFormatSeconds (thread_timer_remain_second -                                      (mon_eth->timer), buf_remain, BUFSIZ); -                } -              fp (out, " %-17s %10d %-10s\n", -                  rfapi_ntop (pfx_mac.family, &pfx_mac.u.prefix, buf_pfx, -                              BUFSIZ), mon_eth->logical_net_id, buf_remain); -            } -        } -    } - -  if (queries_total) -    { -      fp (out, "\n"); -      fp (out, "Displayed %d out of %d total queries\n", -          queries_displayed, queries_total); -    } -  return CMD_SUCCESS; +	struct bgp *bgp; +	struct rfapi *h; +	struct listnode *node; +	struct rfapi_descriptor *rfd; + +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; + +	int printedheader = 0; + +	int nves_total = 0; +	int nves_with_queries = 0; +	int nves_displayed = 0; + +	int queries_total = 0; +	int queries_displayed = 0; + +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return CMD_WARNING; + +	bgp = bgp_get_default(); /* assume 1 instance for now */ +	if (!bgp) { +		vty_out(vty, "No BGP instance\n"); +		return CMD_WARNING; +	} + +	h = bgp->rfapi; +	if (!h) { +		vty_out(vty, "No RFAPI instance\n"); +		return CMD_WARNING; +	} + +	for (ALL_LIST_ELEMENTS_RO(&h->descriptors, node, rfd)) { + +		struct route_node *rn; +		int printedquerier = 0; + + +		++nves_total; + +		if (rfd->mon +		    || (rfd->mon_eth && skiplist_count(rfd->mon_eth))) { +			++nves_with_queries; +		} else { +			continue; +		} + +		/* +		 * IP Queries +		 */ +		if (rfd->mon) { +			for (rn = route_top(rfd->mon); rn; +			     rn = route_next(rn)) { +				struct rfapi_monitor_vpn *m; +				char buf_remain[BUFSIZ]; +				char buf_pfx[BUFSIZ]; + +				if (!rn->info) +					continue; + +				m = rn->info; + +				++queries_total; + +				if (pfx_match +				    && !prefix_match(pfx_match, &rn->p) +				    && !prefix_match(&rn->p, pfx_match)) +					continue; + +				++queries_displayed; + +				if (!printedheader) { +					++printedheader; +					fp(out, "\n"); +					fp(out, "%-15s %-15s %-15s %-10s\n", +					   "VN Address", "UN Address", "Target", +					   "Remaining"); +				} + +				if (!printedquerier) { +					char buf_vn[BUFSIZ]; +					char buf_un[BUFSIZ]; + +					rfapiRfapiIpAddr2Str(&rfd->un_addr, +							     buf_un, BUFSIZ); +					rfapiRfapiIpAddr2Str(&rfd->vn_addr, +							     buf_vn, BUFSIZ); + +					fp(out, "%-15s %-15s", buf_vn, buf_un); +					printedquerier = 1; + +					++nves_displayed; +				} else +					fp(out, "%-15s %-15s", "", ""); +				buf_remain[0] = 0; +				if (m->timer) { +					rfapiFormatSeconds( +						thread_timer_remain_second( +							m->timer), +						buf_remain, BUFSIZ); +				} +				fp(out, " %-15s %-10s\n", +				   inet_ntop(m->p.family, &m->p.u.prefix, +					     buf_pfx, BUFSIZ), +				   buf_remain); +			} +		} + +		/* +		 * Ethernet Queries +		 */ +		if (rfd->mon_eth && skiplist_count(rfd->mon_eth)) { + +			int rc; +			void *cursor; +			struct rfapi_monitor_eth *mon_eth; + +			for (cursor = NULL, +			    rc = skiplist_next(rfd->mon_eth, NULL, +					       (void **)&mon_eth, &cursor); +			     rc == 0; +			     rc = skiplist_next(rfd->mon_eth, NULL, +						(void **)&mon_eth, &cursor)) { + +				char buf_remain[BUFSIZ]; +				char buf_pfx[BUFSIZ]; +				struct prefix pfx_mac; + +				++queries_total; + +				vnc_zlog_debug_verbose( +					"%s: checking rfd=%p mon_eth=%p", +					__func__, rfd, mon_eth); + +				memset((void *)&pfx_mac, 0, +				       sizeof(struct prefix)); +				pfx_mac.family = AF_ETHERNET; +				pfx_mac.prefixlen = 48; +				pfx_mac.u.prefix_eth = mon_eth->macaddr; + +				if (pfx_match +				    && !prefix_match(pfx_match, &pfx_mac) +				    && !prefix_match(&pfx_mac, pfx_match)) +					continue; + +				++queries_displayed; + +				if (!printedheader) { +					++printedheader; +					fp(out, "\n"); +					fp(out, +					   "%-15s %-15s %-17s %10s %-10s\n", +					   "VN Address", "UN Address", "Target", +					   "LNI", "Remaining"); +				} + +				if (!printedquerier) { +					char buf_vn[BUFSIZ]; +					char buf_un[BUFSIZ]; + +					rfapiRfapiIpAddr2Str(&rfd->un_addr, +							     buf_un, BUFSIZ); +					rfapiRfapiIpAddr2Str(&rfd->vn_addr, +							     buf_vn, BUFSIZ); + +					fp(out, "%-15s %-15s", buf_vn, buf_un); +					printedquerier = 1; + +					++nves_displayed; +				} else +					fp(out, "%-15s %-15s", "", ""); +				buf_remain[0] = 0; +				if (mon_eth->timer) { +					rfapiFormatSeconds( +						thread_timer_remain_second( +							mon_eth->timer), +						buf_remain, BUFSIZ); +				} +				fp(out, " %-17s %10d %-10s\n", +				   rfapi_ntop(pfx_mac.family, &pfx_mac.u.prefix, +					      buf_pfx, BUFSIZ), +				   mon_eth->logical_net_id, buf_remain); +			} +		} +	} + +	if (queries_total) { +		fp(out, "\n"); +		fp(out, "Displayed %d out of %d total queries\n", +		   queries_displayed, queries_total); +	} +	return CMD_SUCCESS;  } -static int -rfapiPrintRemoteRegBi ( -  struct bgp		*bgp, -  void			*stream, -  struct route_node	*rn, -  struct bgp_info	*bi) +static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream, +				 struct route_node *rn, struct bgp_info *bi)  { -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; -  struct prefix pfx_un; -  struct prefix pfx_vn; -  uint8_t cost; -  uint32_t lifetime; -  bgp_encap_types tun_type; - -  char buf_pfx[BUFSIZ]; -  char buf_ntop[BUFSIZ]; -  char buf_un[BUFSIZ]; -  char buf_vn[BUFSIZ]; -  char buf_lifetime[BUFSIZ]; -  int nlines = 0; - -  if (!stream) -    return 0;                   /* for debug log, print into buf & call output once */ - -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return 0; - -  /* -   * Prefix -   */ -  buf_pfx[0] = 0; -  snprintf (buf_pfx, BUFSIZ, "%s/%d", -            rfapi_ntop (rn->p.family, &rn->p.u.prefix, buf_ntop, BUFSIZ), -            rn->p.prefixlen); -  buf_pfx[BUFSIZ - 1] = 0; -  nlines++; - -  /* -   * UN addr -   */ -  buf_un[0] = 0; -  if (!rfapiGetUnAddrOfVpnBi (bi, &pfx_un)) -    { -      snprintf (buf_un, BUFSIZ, "%s", -                inet_ntop (pfx_un.family, &pfx_un.u.prefix, buf_ntop, -                           BUFSIZ)); -    } - -  rfapiGetTunnelType(bi->attr,&tun_type); -  /* -   * VN addr -   */ -  buf_vn[0] = 0; -  rfapiNexthop2Prefix (bi->attr, &pfx_vn); -  if (tun_type == BGP_ENCAP_TYPE_MPLS) -    { -      /* MPLS carries un in nrli next hop (same as vn for IP tunnels) */ -      snprintf (buf_un, BUFSIZ, "%s", -                inet_ntop (pfx_vn.family, &pfx_vn.u.prefix, buf_ntop, BUFSIZ)); -      if (bi->extra) -        { -          u_int32_t l = decode_label (&bi->extra->label); -          snprintf (buf_vn, BUFSIZ, "Label: %d", l); -        } -      else                      /* should never happen */ -        { -          snprintf (buf_vn, BUFSIZ, "Label: N/A"); -        } -    } -  else -    { -      snprintf (buf_vn, BUFSIZ, "%s", -                inet_ntop (pfx_vn.family, &pfx_vn.u.prefix, buf_ntop, BUFSIZ)); -    } -  buf_vn[BUFSIZ - 1] = 0; -  buf_un[BUFSIZ - 1] = 0; - -  /* -   * Cost is encoded in local_pref as (255-cost) -   * See rfapi_import.c'rfapiRouteInfo2NextHopEntry() for conversion -   * back to cost. -   */ -  if (bi->attr) -    { -      uint32_t local_pref; -      if (bi->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)) -        local_pref = bi->attr->local_pref; -      else -        local_pref = 0; -      cost = (local_pref > 255) ? 0 : 255 - local_pref; -    } -  else -    { -      cost = 0; -    } - -  fp (out, "%-20s ", buf_pfx); -  fp (out, "%-15s ", buf_vn); -  fp (out, "%-15s ", buf_un); -  fp (out, "%-4d ", cost); - -  /* Lifetime */ -  /* NB rfapiGetVncLifetime sets infinite value when returning !0 */ -  if (rfapiGetVncLifetime (bi->attr, &lifetime) || -      (lifetime == RFAPI_INFINITE_LIFETIME)) -    { - -      fp (out, "%-10s ", "infinite"); -    } -  else -    { -      time_t t_lifetime = lifetime; -      rfapiFormatSeconds (t_lifetime, buf_lifetime, BUFSIZ); -      fp (out, "%-10s ", buf_lifetime); -    } - -  if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED) && -      bi->extra && bi->extra->vnc.import.timer) -    { - -      uint32_t remaining; -      time_t age; -      char buf_age[BUFSIZ]; - -      struct thread *t = (struct thread *) bi->extra->vnc.import.timer; -      remaining = thread_timer_remain_second (t); +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; +	struct prefix pfx_un; +	struct prefix pfx_vn; +	uint8_t cost; +	uint32_t lifetime; +	bgp_encap_types tun_type; + +	char buf_pfx[BUFSIZ]; +	char buf_ntop[BUFSIZ]; +	char buf_un[BUFSIZ]; +	char buf_vn[BUFSIZ]; +	char buf_lifetime[BUFSIZ]; +	int nlines = 0; + +	if (!stream) +		return 0; /* for debug log, print into buf & call output once */ + +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return 0; + +	/* +	 * Prefix +	 */ +	buf_pfx[0] = 0; +	snprintf(buf_pfx, BUFSIZ, "%s/%d", +		 rfapi_ntop(rn->p.family, &rn->p.u.prefix, buf_ntop, BUFSIZ), +		 rn->p.prefixlen); +	buf_pfx[BUFSIZ - 1] = 0; +	nlines++; + +	/* +	 * UN addr +	 */ +	buf_un[0] = 0; +	if (!rfapiGetUnAddrOfVpnBi(bi, &pfx_un)) { +		snprintf(buf_un, BUFSIZ, "%s", +			 inet_ntop(pfx_un.family, &pfx_un.u.prefix, buf_ntop, +				   BUFSIZ)); +	} + +	rfapiGetTunnelType(bi->attr, &tun_type); +	/* +	 * VN addr +	 */ +	buf_vn[0] = 0; +	rfapiNexthop2Prefix(bi->attr, &pfx_vn); +	if (tun_type == BGP_ENCAP_TYPE_MPLS) { +		/* MPLS carries un in nrli next hop (same as vn for IP tunnels) +		 */ +		snprintf(buf_un, BUFSIZ, "%s", +			 inet_ntop(pfx_vn.family, &pfx_vn.u.prefix, buf_ntop, +				   BUFSIZ)); +		if (bi->extra) { +			u_int32_t l = decode_label(&bi->extra->label); +			snprintf(buf_vn, BUFSIZ, "Label: %d", l); +		} else /* should never happen */ +		{ +			snprintf(buf_vn, BUFSIZ, "Label: N/A"); +		} +	} else { +		snprintf(buf_vn, BUFSIZ, "%s", +			 inet_ntop(pfx_vn.family, &pfx_vn.u.prefix, buf_ntop, +				   BUFSIZ)); +	} +	buf_vn[BUFSIZ - 1] = 0; +	buf_un[BUFSIZ - 1] = 0; + +	/* +	 * Cost is encoded in local_pref as (255-cost) +	 * See rfapi_import.c'rfapiRouteInfo2NextHopEntry() for conversion +	 * back to cost. +	 */ +	if (bi->attr) { +		uint32_t local_pref; +		if (bi->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) +			local_pref = bi->attr->local_pref; +		else +			local_pref = 0; +		cost = (local_pref > 255) ? 0 : 255 - local_pref; +	} else { +		cost = 0; +	} + +	fp(out, "%-20s ", buf_pfx); +	fp(out, "%-15s ", buf_vn); +	fp(out, "%-15s ", buf_un); +	fp(out, "%-4d ", cost); + +	/* Lifetime */ +	/* NB rfapiGetVncLifetime sets infinite value when returning !0 */ +	if (rfapiGetVncLifetime(bi->attr, &lifetime) +	    || (lifetime == RFAPI_INFINITE_LIFETIME)) { + +		fp(out, "%-10s ", "infinite"); +	} else { +		time_t t_lifetime = lifetime; +		rfapiFormatSeconds(t_lifetime, buf_lifetime, BUFSIZ); +		fp(out, "%-10s ", buf_lifetime); +	} + +	if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED) && bi->extra +	    && bi->extra->vnc.import.timer) { + +		uint32_t remaining; +		time_t age; +		char buf_age[BUFSIZ]; + +		struct thread *t = (struct thread *)bi->extra->vnc.import.timer; +		remaining = thread_timer_remain_second(t);  #if RFAPI_REGISTRATIONS_REPORT_AGE -      /* -       * Calculate when the timer started. Doing so here saves -       * us a timestamp field in "struct bgp_info". -       * -       * See rfapi_import.c'rfapiBiStartWithdrawTimer() for the -       * original calculation. -       */ -      age = rfapiGetHolddownFromLifetime (lifetime, factor) - remaining; +		/* +		 * Calculate when the timer started. Doing so here saves +		 * us a timestamp field in "struct bgp_info". +		 * +		 * See rfapi_import.c'rfapiBiStartWithdrawTimer() for the +		 * original calculation. +		 */ +		age = rfapiGetHolddownFromLifetime(lifetime, factor) +		      - remaining;  #else /* report remaining time */ -      age = remaining; +		age = remaining;  #endif -      rfapiFormatSeconds (age, buf_age, BUFSIZ); - -      fp (out, "%-10s ", buf_age); - -    } -  else if (RFAPI_LOCAL_BI (bi)) -    { - -      char buf_age[BUFSIZ]; - -      if (bi && bi->extra && bi->extra->vnc.import.create_time) -        { -          rfapiFormatAge (bi->extra->vnc.import.create_time, buf_age, BUFSIZ); -        } -      else -        { -          buf_age[0] = '?'; -          buf_age[1] = 0; -        } -      fp (out, "%-10s ", buf_age); -    } -  fp (out, "%s", HVTYNL); - -  if (rn->p.family == AF_ETHERNET) -    { -      /* -       * If there is a corresponding IP address && != VN address,  -       * print that on the next line -       */ - -      if (bi && bi->extra && bi->extra->vnc.import.aux_prefix.family) -        { -          const char *sp; - -          sp = rfapi_ntop (bi->extra->vnc.import.aux_prefix.family, -                           &bi->extra->vnc.import.aux_prefix.u.prefix, -                           buf_ntop, BUFSIZ); -          buf_ntop[BUFSIZ - 1] = 0; - -          if (sp && strcmp (buf_vn, sp) != 0) -            { -              fp (out, "  IP: %s", sp); -              if (nlines == 1) -                nlines++; -            } -        } -    } -  if (tun_type != BGP_ENCAP_TYPE_MPLS && bi->extra) -    { -      u_int32_t l = decode_label (&bi->extra->label); -      if (!MPLS_LABEL_IS_NULL (l)) -        { -          fp (out, "  Label: %d", l); -          if (nlines == 1) -            nlines++; -        } -    } -  if (nlines > 1) -    fp (out, "%s", HVTYNL); - -  return 1; +		rfapiFormatSeconds(age, buf_age, BUFSIZ); + +		fp(out, "%-10s ", buf_age); + +	} else if (RFAPI_LOCAL_BI(bi)) { + +		char buf_age[BUFSIZ]; + +		if (bi && bi->extra && bi->extra->vnc.import.create_time) { +			rfapiFormatAge(bi->extra->vnc.import.create_time, +				       buf_age, BUFSIZ); +		} else { +			buf_age[0] = '?'; +			buf_age[1] = 0; +		} +		fp(out, "%-10s ", buf_age); +	} +	fp(out, "%s", HVTYNL); + +	if (rn->p.family == AF_ETHERNET) { +		/* +		 * If there is a corresponding IP address && != VN address, +		 * print that on the next line +		 */ + +		if (bi && bi->extra +		    && bi->extra->vnc.import.aux_prefix.family) { +			const char *sp; + +			sp = rfapi_ntop( +				bi->extra->vnc.import.aux_prefix.family, +				&bi->extra->vnc.import.aux_prefix.u.prefix, +				buf_ntop, BUFSIZ); +			buf_ntop[BUFSIZ - 1] = 0; + +			if (sp && strcmp(buf_vn, sp) != 0) { +				fp(out, "  IP: %s", sp); +				if (nlines == 1) +					nlines++; +			} +		} +	} +	if (tun_type != BGP_ENCAP_TYPE_MPLS && bi->extra) { +		u_int32_t l = decode_label(&bi->extra->label); +		if (!MPLS_LABEL_IS_NULL(l)) { +			fp(out, "  Label: %d", l); +			if (nlines == 1) +				nlines++; +		} +	} +	if (nlines > 1) +		fp(out, "%s", HVTYNL); + +	return 1;  } -static int -rfapiShowRemoteRegistrationsIt ( -  struct bgp			*bgp, -  void				*stream, -  struct rfapi_import_table	*it, -  struct prefix			*prefix_only, -  int				show_expiring,	/* either/or */ -  int				show_local, -  int				show_remote, -  int				show_imported,	/* either/or */ -  uint32_t			*pLni)		/* AFI_L2VPN only */ +static int rfapiShowRemoteRegistrationsIt(struct bgp *bgp, void *stream, +					  struct rfapi_import_table *it, +					  struct prefix *prefix_only, +					  int show_expiring, /* either/or */ +					  int show_local, int show_remote, +					  int show_imported, /* either/or */ +					  uint32_t *pLni) /* AFI_L2VPN only */  { -  afi_t afi; -  int printed_rtlist_hdr = 0; - -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; -  int total = 0; -  int printed = 0; - -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return printed; - -  for (afi = AFI_IP; afi < AFI_MAX; ++afi) -    { - -      struct route_node *rn; - -      if (!it->imported_vpn[afi]) -        continue; - -      for (rn = route_top (it->imported_vpn[afi]); rn; rn = route_next (rn)) -        { - -          struct bgp_info *bi; -          int count_only; - -          /* allow for wider or more narrow mask from user */ -          if (prefix_only && -              !prefix_match (prefix_only, &rn->p) && -              !prefix_match (&rn->p, prefix_only)) -            count_only = 1; -          else -            count_only = 0; - -          for (bi = rn->info; bi; bi = bi->next) -            { - -              if (!show_local && RFAPI_LOCAL_BI (bi)) -                { - -                  /* local route from RFP */ -                  continue; -                } - -              if (!show_remote && !RFAPI_LOCAL_BI (bi)) -                { - -                  /* remote route */ -                  continue; -                } - -              if (show_expiring && !CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) -                continue; - -              if (!show_expiring && CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) -                continue; - -              if (bi->type == ZEBRA_ROUTE_BGP_DIRECT || -                  bi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT) -                { -                  if (!show_imported) -                    continue; -                } -              else -                { -                  if (show_imported) -                    continue; -                } - -              total++; -              if (count_only == 1) -                continue; -              if (!printed_rtlist_hdr) -                { -                  const char *agetype = ""; -                  char *s; -                  const char *type = ""; -                  if (show_imported) -                    { -                      type = "Imported"; -                    } -                  else -                    { -                      if (show_expiring) -                        { -                          type = "Holddown"; -                        } -                      else -                        { -                          if (RFAPI_LOCAL_BI (bi)) -                            { -                              type = "Local"; -                            } -                          else -                            { -                              type = "Remote"; -                            } -                        } -                    } - -                  s = ecommunity_ecom2str (it->rt_import_list, -                                           ECOMMUNITY_FORMAT_ROUTE_MAP, 0); - -                  if (pLni) -                    { -                      fp (out, "%s[%s] L2VPN Network 0x%x (%u) RT={%s}", -                          HVTYNL, type, *pLni, (*pLni & 0xfff), s); -                    } -                  else -                    { -                      fp (out, "%s[%s] Prefix RT={%s}", -                          HVTYNL, type, s); -                    } -                  XFREE (MTYPE_ECOMMUNITY_STR, s); - -                  if (it->rfg && it->rfg->name) -                    { -                      fp (out, " %s \"%s\"", -                          (it->rfg->type == RFAPI_GROUP_CFG_VRF ?  -                           "VRF" : "NVE group"), -                          it->rfg->name); -                    } -                  fp (out, "%s", HVTYNL); -                  if (show_expiring) -                    { +	afi_t afi; +	int printed_rtlist_hdr = 0; + +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline; +	int total = 0; +	int printed = 0; + +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return printed; + +	for (afi = AFI_IP; afi < AFI_MAX; ++afi) { + +		struct route_node *rn; + +		if (!it->imported_vpn[afi]) +			continue; + +		for (rn = route_top(it->imported_vpn[afi]); rn; +		     rn = route_next(rn)) { + +			struct bgp_info *bi; +			int count_only; + +			/* allow for wider or more narrow mask from user */ +			if (prefix_only && !prefix_match(prefix_only, &rn->p) +			    && !prefix_match(&rn->p, prefix_only)) +				count_only = 1; +			else +				count_only = 0; + +			for (bi = rn->info; bi; bi = bi->next) { + +				if (!show_local && RFAPI_LOCAL_BI(bi)) { + +					/* local route from RFP */ +					continue; +				} + +				if (!show_remote && !RFAPI_LOCAL_BI(bi)) { + +					/* remote route */ +					continue; +				} + +				if (show_expiring +				    && !CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) +					continue; + +				if (!show_expiring +				    && CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) +					continue; + +				if (bi->type == ZEBRA_ROUTE_BGP_DIRECT +				    || bi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT) { +					if (!show_imported) +						continue; +				} else { +					if (show_imported) +						continue; +				} + +				total++; +				if (count_only == 1) +					continue; +				if (!printed_rtlist_hdr) { +					const char *agetype = ""; +					char *s; +					const char *type = ""; +					if (show_imported) { +						type = "Imported"; +					} else { +						if (show_expiring) { +							type = "Holddown"; +						} else { +							if (RFAPI_LOCAL_BI( +								    bi)) { +								type = "Local"; +							} else { +								type = "Remote"; +							} +						} +					} + +					s = ecommunity_ecom2str( +						it->rt_import_list, +						ECOMMUNITY_FORMAT_ROUTE_MAP, 0); + +					if (pLni) { +						fp(out, +						   "%s[%s] L2VPN Network 0x%x (%u) RT={%s}", +						   HVTYNL, type, *pLni, +						   (*pLni & 0xfff), s); +					} else { +						fp(out, "%s[%s] Prefix RT={%s}", +						   HVTYNL, type, s); +					} +					XFREE(MTYPE_ECOMMUNITY_STR, s); + +					if (it->rfg && it->rfg->name) { +						fp(out, " %s \"%s\"", +						   (it->rfg->type == RFAPI_GROUP_CFG_VRF +							    ? "VRF" +							    : "NVE group"), +						   it->rfg->name); +					} +					fp(out, "%s", HVTYNL); +					if (show_expiring) {  #if RFAPI_REGISTRATIONS_REPORT_AGE -                      agetype = "Age"; +						agetype = "Age";  #else -                      agetype = "Remaining"; +						agetype = "Remaining";  #endif -                    } -                  else if (show_local) -                    { -                      agetype = "Age"; -                    } - -                  printed_rtlist_hdr = 1; - -                  fp (out, "%-20s %-15s %-15s %4s %-10s %-10s%s", -                      (pLni ? "L2 Address/IP" : "Prefix"), -                      "VN Address", "UN Address", "Cost", -                      "Lifetime", agetype, HVTYNL); -                } -              printed += rfapiPrintRemoteRegBi (bgp, stream, rn, bi); -            } -        } -    } - -  if (printed > 0) -    { - -      const char *type = "prefixes"; - -      if (show_imported) -        { -          type = "imported prefixes"; -        } -      else -        { -          if (show_expiring) -            { -              type = "prefixes in holddown"; -            } -          else -            { -              if (show_local && !show_remote) -                { -                  type = "locally registered prefixes"; -                } -              else if (!show_local && show_remote) -                { -                  type = "remotely registered prefixes"; -                } -            } -        } - -      fp (out, "Displayed %d out of %d %s%s", -          printed, total, type, HVTYNL); +					} else if (show_local) { +						agetype = "Age"; +					} + +					printed_rtlist_hdr = 1; + +					fp(out, +					   "%-20s %-15s %-15s %4s %-10s %-10s%s", +					   (pLni ? "L2 Address/IP" : "Prefix"), +					   "VN Address", "UN Address", "Cost", +					   "Lifetime", agetype, HVTYNL); +				} +				printed += rfapiPrintRemoteRegBi(bgp, stream, +								 rn, bi); +			} +		} +	} + +	if (printed > 0) { + +		const char *type = "prefixes"; + +		if (show_imported) { +			type = "imported prefixes"; +		} else { +			if (show_expiring) { +				type = "prefixes in holddown"; +			} else { +				if (show_local && !show_remote) { +					type = "locally registered prefixes"; +				} else if (!show_local && show_remote) { +					type = "remotely registered prefixes"; +				} +			} +		} + +		fp(out, "Displayed %d out of %d %s%s", printed, total, type, +		   HVTYNL);  #if DEBUG_SHOW_EXTRA -      fp(out, "IT table above: it=%p%s", it, HVTYNL); +		fp(out, "IT table above: it=%p%s", it, HVTYNL);  #endif -    } -  return printed; +	} +	return printed;  } -  /*   * rfapiShowRemoteRegistrations   * @@ -1521,70 +1370,56 @@ rfapiShowRemoteRegistrationsIt (   * is mean to produce the "remote" portion of the output   * of "show vnc registrations".   */ -int -rfapiShowRemoteRegistrations ( -  void		*stream, -  struct prefix	*prefix_only, -  int		show_expiring, -  int		show_local, -  int		show_remote, -  int		show_imported) +int rfapiShowRemoteRegistrations(void *stream, struct prefix *prefix_only, +				 int show_expiring, int show_local, +				 int show_remote, int show_imported)  { -  struct bgp *bgp; -  struct rfapi *h; -  struct rfapi_import_table *it; -  int printed = 0; - -  bgp = bgp_get_default (); -  if (!bgp) -    { -      return printed; -    } - -  h = bgp->rfapi; -  if (!h) -    { -      return printed; -    } - -  for (it = h->imports; it; it = it->next) -    { -      printed += -        rfapiShowRemoteRegistrationsIt (bgp, stream, it, prefix_only, -                                        show_expiring, show_local, -                                        show_remote, show_imported, NULL); -    } - -  if (h->import_mac) -    { -      void *cursor = NULL; -      int rc; -      uintptr_t lni_as_ptr; -      uint32_t lni; -      uint32_t *pLni; - -      for (rc = -           skiplist_next (h->import_mac, (void **) &lni_as_ptr, (void **) &it, -                          &cursor); !rc; -           rc = -           skiplist_next (h->import_mac, (void **) &lni_as_ptr, (void **) &it, -                          &cursor)) -        { -          pLni = NULL; -          if ((lni_as_ptr & 0xffffffff) == lni_as_ptr) -            { -              lni = (uint32_t) (lni_as_ptr & 0xffffffff); -              pLni = &lni; -            } - -          printed += -            rfapiShowRemoteRegistrationsIt (bgp, stream, it, prefix_only, -                                            show_expiring, show_local, -                                            show_remote, show_imported, pLni); -        } -    } - -  return printed; +	struct bgp *bgp; +	struct rfapi *h; +	struct rfapi_import_table *it; +	int printed = 0; + +	bgp = bgp_get_default(); +	if (!bgp) { +		return printed; +	} + +	h = bgp->rfapi; +	if (!h) { +		return printed; +	} + +	for (it = h->imports; it; it = it->next) { +		printed += rfapiShowRemoteRegistrationsIt( +			bgp, stream, it, prefix_only, show_expiring, show_local, +			show_remote, show_imported, NULL); +	} + +	if (h->import_mac) { +		void *cursor = NULL; +		int rc; +		uintptr_t lni_as_ptr; +		uint32_t lni; +		uint32_t *pLni; + +		for (rc = skiplist_next(h->import_mac, (void **)&lni_as_ptr, +					(void **)&it, &cursor); +		     !rc; +		     rc = skiplist_next(h->import_mac, (void **)&lni_as_ptr, +					(void **)&it, &cursor)) { +			pLni = NULL; +			if ((lni_as_ptr & 0xffffffff) == lni_as_ptr) { +				lni = (uint32_t)(lni_as_ptr & 0xffffffff); +				pLni = &lni; +			} + +			printed += rfapiShowRemoteRegistrationsIt( +				bgp, stream, it, prefix_only, show_expiring, +				show_local, show_remote, show_imported, pLni); +		} +	} + +	return printed;  }  /*------------------------------------------ @@ -1592,7 +1427,7 @@ rfapiShowRemoteRegistrations (   *   * UI helper: generate string from rfapi_ip_addr   * - * input:  + * input:   *	a			IP v4/v6 address   *   * output @@ -1603,385 +1438,342 @@ rfapiShowRemoteRegistrations (   *	NULL			conversion failed   *	non-NULL		pointer to buf   --------------------------------------------*/ -const char * -rfapiRfapiIpAddr2Str (struct rfapi_ip_addr *a, char *buf, int bufsize) +const char *rfapiRfapiIpAddr2Str(struct rfapi_ip_addr *a, char *buf, +				 int bufsize)  { -  const char *rc = NULL; - -  switch (a->addr_family) -    { -    case AF_INET: -      rc = inet_ntop (a->addr_family, &a->addr.v4, buf, bufsize); -      break; -    case AF_INET6: -      rc = inet_ntop (a->addr_family, &a->addr.v6, buf, bufsize); -      break; -    } -  return rc; +	const char *rc = NULL; + +	switch (a->addr_family) { +	case AF_INET: +		rc = inet_ntop(a->addr_family, &a->addr.v4, buf, bufsize); +		break; +	case AF_INET6: +		rc = inet_ntop(a->addr_family, &a->addr.v6, buf, bufsize); +		break; +	} +	return rc;  } -void -rfapiPrintRfapiIpAddr (void *stream, struct rfapi_ip_addr *a) +void rfapiPrintRfapiIpAddr(void *stream, struct rfapi_ip_addr *a)  { -  char buf[BUFSIZ]; -  const char *rc = NULL; +	char buf[BUFSIZ]; +	const char *rc = NULL; -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out = NULL; -  const char *vty_newline; +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out = NULL; +	const char *vty_newline; -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; -  rc = rfapiRfapiIpAddr2Str (a, buf, BUFSIZ); +	rc = rfapiRfapiIpAddr2Str(a, buf, BUFSIZ); -  if (rc) -    fp (out, "%s", buf); +	if (rc) +		fp(out, "%s", buf);  } -const char * -rfapiRfapiIpPrefix2Str (struct rfapi_ip_prefix *p, char *buf, int bufsize) +const char *rfapiRfapiIpPrefix2Str(struct rfapi_ip_prefix *p, char *buf, +				   int bufsize)  { -  struct rfapi_ip_addr *a = &p->prefix; -  const char *rc = NULL; - -  switch (a->addr_family) -    { -    case AF_INET: -      rc = inet_ntop (a->addr_family, &a->addr.v4, buf, bufsize); -      break; -    case AF_INET6: -      rc = inet_ntop (a->addr_family, &a->addr.v6, buf, bufsize); -      break; -    } - -  if (rc) -    { -      int alen = strlen (buf); -      int remaining = bufsize - alen - 1; -      int slen; - -      if (remaining > 0) -        { -          slen = snprintf (buf + alen, remaining, "/%u", p->length); -          if (slen < remaining) /* see man page for snprintf(3) */ -            return rc; -        } -    } - -  return NULL; +	struct rfapi_ip_addr *a = &p->prefix; +	const char *rc = NULL; + +	switch (a->addr_family) { +	case AF_INET: +		rc = inet_ntop(a->addr_family, &a->addr.v4, buf, bufsize); +		break; +	case AF_INET6: +		rc = inet_ntop(a->addr_family, &a->addr.v6, buf, bufsize); +		break; +	} + +	if (rc) { +		int alen = strlen(buf); +		int remaining = bufsize - alen - 1; +		int slen; + +		if (remaining > 0) { +			slen = snprintf(buf + alen, remaining, "/%u", +					p->length); +			if (slen < remaining) /* see man page for snprintf(3) */ +				return rc; +		} +	} + +	return NULL;  } -void -rfapiPrintRfapiIpPrefix (void *stream, struct rfapi_ip_prefix *p) +void rfapiPrintRfapiIpPrefix(void *stream, struct rfapi_ip_prefix *p)  { -  char buf[BUFSIZ]; -  const char *rc; +	char buf[BUFSIZ]; +	const char *rc; -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out = NULL; -  const char *vty_newline; +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out = NULL; +	const char *vty_newline; -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; -  rc = rfapiRfapiIpPrefix2Str (p, buf, BUFSIZ); +	rc = rfapiRfapiIpPrefix2Str(p, buf, BUFSIZ); -  if (rc) -    fp (out, "%s:%u", buf, p->cost); -  else -    fp (out, "?/?:?"); +	if (rc) +		fp(out, "%s:%u", buf, p->cost); +	else +		fp(out, "?/?:?");  } -void -rfapiPrintRd (struct vty *vty, struct prefix_rd *prd) +void rfapiPrintRd(struct vty *vty, struct prefix_rd *prd)  { -  char buf[BUFSIZ]; +	char buf[BUFSIZ]; -  buf[0] = 0; -  prefix_rd2str (prd, buf, BUFSIZ); -  buf[BUFSIZ - 1] = 0; -  vty_out (vty, "%s", buf); +	buf[0] = 0; +	prefix_rd2str(prd, buf, BUFSIZ); +	buf[BUFSIZ - 1] = 0; +	vty_out(vty, "%s", buf);  } -void -rfapiPrintAdvertisedInfo ( -  struct vty			*vty, -  struct rfapi_descriptor	*rfd, -  safi_t			safi, -  struct prefix			*p) +void rfapiPrintAdvertisedInfo(struct vty *vty, struct rfapi_descriptor *rfd, +			      safi_t safi, struct prefix *p)  { -  afi_t afi;                    /* of the VN address */ -  struct bgp_node *bn; -  struct bgp_info *bi; -  uint8_t type = ZEBRA_ROUTE_BGP; -  struct bgp *bgp; -  int printed = 0; -  struct prefix_rd prd0; -  struct prefix_rd *prd; - -  /* -   * Find the bgp_info in the RIB corresponding to this -   * prefix and rfd -   */ - -  afi = family2afi (p->family); -  assert (afi == AFI_IP || afi == AFI_IP6); - -  bgp = bgp_get_default ();     /* assume 1 instance for now */ -  assert (bgp); - -  if (safi == SAFI_ENCAP) -    { -      memset (&prd0, 0, sizeof (prd0)); -      prd0.family = AF_UNSPEC; -      prd0.prefixlen = 64; -      prd = &prd0; -    } -  else -    { -      prd = &rfd->rd; -    } -  bn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd); - -  vty_out (vty, "  bn=%p%s", bn, HVTYNL); - -  for (bi = bn->info; bi; bi = bi->next) -    { -      if (bi->peer == rfd->peer && -          bi->type == type && -          bi->sub_type == BGP_ROUTE_RFP && -          bi->extra && bi->extra->vnc.export.rfapi_handle == (void *) rfd) -        { - -          rfapiPrintBi (vty, bi); -          printed = 1; -        } -    } - -  if (!printed) -    { -      vty_out (vty, "    --?--%s", HVTYNL); -      return; -    } - +	afi_t afi; /* of the VN address */ +	struct bgp_node *bn; +	struct bgp_info *bi; +	uint8_t type = ZEBRA_ROUTE_BGP; +	struct bgp *bgp; +	int printed = 0; +	struct prefix_rd prd0; +	struct prefix_rd *prd; + +	/* +	 * Find the bgp_info in the RIB corresponding to this +	 * prefix and rfd +	 */ + +	afi = family2afi(p->family); +	assert(afi == AFI_IP || afi == AFI_IP6); + +	bgp = bgp_get_default(); /* assume 1 instance for now */ +	assert(bgp); + +	if (safi == SAFI_ENCAP) { +		memset(&prd0, 0, sizeof(prd0)); +		prd0.family = AF_UNSPEC; +		prd0.prefixlen = 64; +		prd = &prd0; +	} else { +		prd = &rfd->rd; +	} +	bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd); + +	vty_out(vty, "  bn=%p%s", bn, HVTYNL); + +	for (bi = bn->info; bi; bi = bi->next) { +		if (bi->peer == rfd->peer && bi->type == type +		    && bi->sub_type == BGP_ROUTE_RFP && bi->extra +		    && bi->extra->vnc.export.rfapi_handle == (void *)rfd) { + +			rfapiPrintBi(vty, bi); +			printed = 1; +		} +	} + +	if (!printed) { +		vty_out(vty, "    --?--%s", HVTYNL); +		return; +	}  } -void -rfapiPrintDescriptor (struct vty *vty, struct rfapi_descriptor *rfd) +void rfapiPrintDescriptor(struct vty *vty, struct rfapi_descriptor *rfd)  { -  /* pHD un-addr vn-addr pCB cookie rd lifetime */ -  /* RT export list */ -  /* RT import list */ -  /* list of advertised prefixes */ -  /* dump import table */ - -  char *s; -  void *cursor; -  int rc; -  afi_t afi; -  struct rfapi_adb *adb; -  char buf[BUFSIZ]; - -  vty_out (vty, "%-10p ", rfd); -  rfapiPrintRfapiIpAddr (vty, &rfd->un_addr); -  vty_out (vty, " "); -  rfapiPrintRfapiIpAddr (vty, &rfd->vn_addr); -  vty_out (vty, " %p %p ", rfd->response_cb, rfd->cookie); -  rfapiPrintRd (vty, &rfd->rd); -  vty_out (vty, " %d", rfd->response_lifetime); -  vty_out (vty, " %s", (rfd->rfg ? rfd->rfg->name : "<orphaned>")); -  vty_out (vty, "%s", HVTYNL); - -  vty_out (vty, " Peer %p #%d%s", rfd->peer, rfd->peer->lock, HVTYNL); - -  /* export RT list */ -  if (rfd->rt_export_list) -    { -      s = -        ecommunity_ecom2str (rfd->rt_export_list, -                             ECOMMUNITY_FORMAT_ROUTE_MAP, 0); -      vty_out (vty, " Export %s%s", s, HVTYNL); -      XFREE (MTYPE_ECOMMUNITY_STR, s); -    } -  else -    { -      vty_out (vty, " Export (nil)%s", HVTYNL); -    } - -  /* import RT list */ -  if (rfd->import_table) -    { -      s = ecommunity_ecom2str (rfd->import_table->rt_import_list, -                               ECOMMUNITY_FORMAT_ROUTE_MAP, 0); -      vty_out (vty, " Import %s%s", s, HVTYNL); -      XFREE (MTYPE_ECOMMUNITY_STR, s); -    } -  else -    { -      vty_out (vty, " Import (nil)%s", HVTYNL); -    } - -  for (afi = AFI_IP; afi < AFI_MAX; ++afi) -    { -      u_char family; - -      family = afi2family (afi); -      if (!family) -        continue; - -      cursor = NULL; -      for (rc = -           skiplist_next (rfd->advertised.ipN_by_prefix, NULL, (void **) &adb, -                          &cursor); rc == 0; -           rc = -           skiplist_next (rfd->advertised.ipN_by_prefix, NULL, (void **) &adb, -                          &cursor)) -        { - -          /* group like family prefixes together in output */ -          if (family != adb->u.s.prefix_ip.family) -            continue; - -          prefix2str (&adb->u.s.prefix_ip, buf, BUFSIZ); -          buf[BUFSIZ - 1] = 0;  /* guarantee NUL-terminated */ - -          vty_out (vty, "  Adv Pfx: %s%s", buf, HVTYNL); -          rfapiPrintAdvertisedInfo (vty, rfd, SAFI_MPLS_VPN, &adb->u.s.prefix_ip); -        } -    } -  for (rc = -       skiplist_next (rfd->advertised.ip0_by_ether, NULL, (void **) &adb, -                      &cursor); rc == 0; -       rc = -       skiplist_next (rfd->advertised.ip0_by_ether, NULL, (void **) &adb, -                      &cursor)) -    { - -      prefix2str (&adb->u.s.prefix_eth, buf, BUFSIZ); -      buf[BUFSIZ - 1] = 0;      /* guarantee NUL-terminated */ - -      vty_out (vty, "  Adv Pfx: %s%s", buf, HVTYNL); - -      /* TBD update the following function to print ethernet info */ -      /* Also need to pass/use rd */ -      rfapiPrintAdvertisedInfo (vty, rfd, SAFI_MPLS_VPN, &adb->u.s.prefix_ip); -    } -  vty_out (vty, "%s", HVTYNL); +	/* pHD un-addr vn-addr pCB cookie rd lifetime */ +	/* RT export list */ +	/* RT import list */ +	/* list of advertised prefixes */ +	/* dump import table */ + +	char *s; +	void *cursor; +	int rc; +	afi_t afi; +	struct rfapi_adb *adb; +	char buf[BUFSIZ]; + +	vty_out(vty, "%-10p ", rfd); +	rfapiPrintRfapiIpAddr(vty, &rfd->un_addr); +	vty_out(vty, " "); +	rfapiPrintRfapiIpAddr(vty, &rfd->vn_addr); +	vty_out(vty, " %p %p ", rfd->response_cb, rfd->cookie); +	rfapiPrintRd(vty, &rfd->rd); +	vty_out(vty, " %d", rfd->response_lifetime); +	vty_out(vty, " %s", (rfd->rfg ? rfd->rfg->name : "<orphaned>")); +	vty_out(vty, "%s", HVTYNL); + +	vty_out(vty, " Peer %p #%d%s", rfd->peer, rfd->peer->lock, HVTYNL); + +	/* export RT list */ +	if (rfd->rt_export_list) { +		s = ecommunity_ecom2str(rfd->rt_export_list, +					ECOMMUNITY_FORMAT_ROUTE_MAP, 0); +		vty_out(vty, " Export %s%s", s, HVTYNL); +		XFREE(MTYPE_ECOMMUNITY_STR, s); +	} else { +		vty_out(vty, " Export (nil)%s", HVTYNL); +	} + +	/* import RT list */ +	if (rfd->import_table) { +		s = ecommunity_ecom2str(rfd->import_table->rt_import_list, +					ECOMMUNITY_FORMAT_ROUTE_MAP, 0); +		vty_out(vty, " Import %s%s", s, HVTYNL); +		XFREE(MTYPE_ECOMMUNITY_STR, s); +	} else { +		vty_out(vty, " Import (nil)%s", HVTYNL); +	} + +	for (afi = AFI_IP; afi < AFI_MAX; ++afi) { +		u_char family; + +		family = afi2family(afi); +		if (!family) +			continue; + +		cursor = NULL; +		for (rc = skiplist_next(rfd->advertised.ipN_by_prefix, NULL, +					(void **)&adb, &cursor); +		     rc == 0; +		     rc = skiplist_next(rfd->advertised.ipN_by_prefix, NULL, +					(void **)&adb, &cursor)) { + +			/* group like family prefixes together in output */ +			if (family != adb->u.s.prefix_ip.family) +				continue; + +			prefix2str(&adb->u.s.prefix_ip, buf, BUFSIZ); +			buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */ + +			vty_out(vty, "  Adv Pfx: %s%s", buf, HVTYNL); +			rfapiPrintAdvertisedInfo(vty, rfd, SAFI_MPLS_VPN, +						 &adb->u.s.prefix_ip); +		} +	} +	for (rc = skiplist_next(rfd->advertised.ip0_by_ether, NULL, +				(void **)&adb, &cursor); +	     rc == 0; rc = skiplist_next(rfd->advertised.ip0_by_ether, NULL, +					 (void **)&adb, &cursor)) { + +		prefix2str(&adb->u.s.prefix_eth, buf, BUFSIZ); +		buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */ + +		vty_out(vty, "  Adv Pfx: %s%s", buf, HVTYNL); + +		/* TBD update the following function to print ethernet info */ +		/* Also need to pass/use rd */ +		rfapiPrintAdvertisedInfo(vty, rfd, SAFI_MPLS_VPN, +					 &adb->u.s.prefix_ip); +	} +	vty_out(vty, "%s", HVTYNL);  }  /*   * test scripts rely on first line for each nve starting in 1st column,   * leading whitespace for additional detail of that nve   */ -void -rfapiPrintMatchingDescriptors (struct vty *vty, -                               struct prefix *vn_prefix, -                               struct prefix *un_prefix) +void rfapiPrintMatchingDescriptors(struct vty *vty, struct prefix *vn_prefix, +				   struct prefix *un_prefix)  { -  struct bgp *bgp; -  struct rfapi *h; -  struct listnode *ln; -  struct rfapi_descriptor *rfd; -  int printed = 0; - -  bgp = bgp_get_default ();     /* assume 1 instance for now */ -  if (!bgp) -    return; - -  h = bgp->rfapi; -  assert (h); - -  for (ln = listhead (&h->descriptors); ln; ln = listnextnode (ln)) -    { -      rfd = listgetdata (ln); - -      struct prefix pfx; - -      if (vn_prefix) -        { -          assert (!rfapiRaddr2Qprefix (&rfd->vn_addr, &pfx)); -          if (!prefix_match (vn_prefix, &pfx)) -            continue; -        } - -      if (un_prefix) -        { -          assert (!rfapiRaddr2Qprefix (&rfd->un_addr, &pfx)); -          if (!prefix_match (un_prefix, &pfx)) -            continue; -        } - -      if (!printed) -        { -          /* print column header */ -          vty_out (vty, -                   "%s %s %s %s %s %s %s %s%s", -                   "descriptor", "un-addr", "vn-addr", "callback", "cookie", -                   "RD", "lifetime", "group", HVTYNL); -        } -      rfapiPrintDescriptor (vty, rfd); -      printed = 1; -    } +	struct bgp *bgp; +	struct rfapi *h; +	struct listnode *ln; +	struct rfapi_descriptor *rfd; +	int printed = 0; + +	bgp = bgp_get_default(); /* assume 1 instance for now */ +	if (!bgp) +		return; + +	h = bgp->rfapi; +	assert(h); + +	for (ln = listhead(&h->descriptors); ln; ln = listnextnode(ln)) { +		rfd = listgetdata(ln); + +		struct prefix pfx; + +		if (vn_prefix) { +			assert(!rfapiRaddr2Qprefix(&rfd->vn_addr, &pfx)); +			if (!prefix_match(vn_prefix, &pfx)) +				continue; +		} + +		if (un_prefix) { +			assert(!rfapiRaddr2Qprefix(&rfd->un_addr, &pfx)); +			if (!prefix_match(un_prefix, &pfx)) +				continue; +		} + +		if (!printed) { +			/* print column header */ +			vty_out(vty, "%s %s %s %s %s %s %s %s%s", "descriptor", +				"un-addr", "vn-addr", "callback", "cookie", +				"RD", "lifetime", "group", HVTYNL); +		} +		rfapiPrintDescriptor(vty, rfd); +		printed = 1; +	}  }  /*   * Parse an address and put into a struct prefix   */ -int -rfapiCliGetPrefixAddr (struct vty *vty, const char *str, struct prefix *p) +int rfapiCliGetPrefixAddr(struct vty *vty, const char *str, struct prefix *p)  { -  if (!str2prefix (str, p)) -    { -      vty_out (vty, "Malformed address \"%s\"%s", str, HVTYNL); -      return CMD_WARNING; -    } -  switch (p->family) -    { -    case AF_INET: -      if (p->prefixlen != 32) -        { -          vty_out (vty, "Not a host address: \"%s\"%s", str, HVTYNL); -          return CMD_WARNING; -        } -      break; -    case AF_INET6: -      if (p->prefixlen != 128) -        { -          vty_out (vty, "Not a host address: \"%s\"%s", str, HVTYNL); -          return CMD_WARNING; -        } -      break; -    default: -      vty_out (vty, "Invalid address \"%s\"%s", str, HVTYNL); -      return CMD_WARNING; -    } -  return 0; +	if (!str2prefix(str, p)) { +		vty_out(vty, "Malformed address \"%s\"%s", str, HVTYNL); +		return CMD_WARNING; +	} +	switch (p->family) { +	case AF_INET: +		if (p->prefixlen != 32) { +			vty_out(vty, "Not a host address: \"%s\"%s", str, +				HVTYNL); +			return CMD_WARNING; +		} +		break; +	case AF_INET6: +		if (p->prefixlen != 128) { +			vty_out(vty, "Not a host address: \"%s\"%s", str, +				HVTYNL); +			return CMD_WARNING; +		} +		break; +	default: +		vty_out(vty, "Invalid address \"%s\"%s", str, HVTYNL); +		return CMD_WARNING; +	} +	return 0;  } -int -rfapiCliGetRfapiIpAddr ( -  struct vty		*vty, -  const char		*str, -  struct rfapi_ip_addr	*hai) +int rfapiCliGetRfapiIpAddr(struct vty *vty, const char *str, +			   struct rfapi_ip_addr *hai)  { -  struct prefix pfx; -  int rc; +	struct prefix pfx; +	int rc; -  rc = rfapiCliGetPrefixAddr (vty, str, &pfx); -  if (rc) -    return rc; +	rc = rfapiCliGetPrefixAddr(vty, str, &pfx); +	if (rc) +		return rc; -  hai->addr_family = pfx.family; -  if (pfx.family == AF_INET) -    hai->addr.v4 = pfx.u.prefix4; -  else -    hai->addr.v6 = pfx.u.prefix6; +	hai->addr_family = pfx.family; +	if (pfx.family == AF_INET) +		hai->addr.v4 = pfx.u.prefix4; +	else +		hai->addr.v6 = pfx.u.prefix6; -  return 0; +	return 0;  }  /* @@ -1989,137 +1781,125 @@ rfapiCliGetRfapiIpAddr (   * with a stream pointing to a vty, the user will have to type something   * before the callback output shows up   */ -void -rfapiPrintNhl (void *stream, struct rfapi_next_hop_entry *next_hops) +void rfapiPrintNhl(void *stream, struct rfapi_next_hop_entry *next_hops)  { -  struct rfapi_next_hop_entry *nh; -  int count; +	struct rfapi_next_hop_entry *nh; +	int count; -  int (*fp) (void *, const char *, ...); -  struct vty *vty; -  void *out; -  const char *vty_newline; +	int (*fp)(void *, const char *, ...); +	struct vty *vty; +	void *out; +	const char *vty_newline;  #define REMAIN (BUFSIZ - (p-line))  #define INCP {p += (r > REMAIN)? REMAIN: r;} - -  if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0) -    return; - -  for (nh = next_hops, count = 1; nh; nh = nh->next, ++count) -    { - -      char line[BUFSIZ]; -      char *p = line; -      int r; - -      r = snprintf (p, REMAIN, "%3d  pfx=", count); -      INCP; - -      if (rfapiRfapiIpPrefix2Str (&nh->prefix, p, REMAIN)) -        { -          /* it fit, so count length */ -          r = strlen (p); -        } -      else -        { -          /* didn't fit */ -          goto truncate; -        } -      INCP; - -      r = snprintf (p, REMAIN, ", un="); -      INCP; - -      if (rfapiRfapiIpAddr2Str (&nh->un_address, p, REMAIN)) -        { -          /* it fit, so count length */ -          r = strlen (p); -        } -      else -        { -          /* didn't fit */ -          goto truncate; -        } -      INCP; - -      r = snprintf (p, REMAIN, ", vn="); -      INCP; - -      if (rfapiRfapiIpAddr2Str (&nh->vn_address, p, REMAIN)) -        { -          /* it fit, so count length */ -          r = strlen (p); -        } -      else -        { -          /* didn't fit */ -          goto truncate; -        } -      INCP; - -    truncate: -      line[BUFSIZ - 1] = 0; -      fp (out, "%s%s", line, HVTYNL); - -      /* -       * options -       */ -      if (nh->vn_options) -        { -          struct rfapi_vn_option *vo; -          char offset[] = "     "; - -          for (vo = nh->vn_options; vo; vo = vo->next) -            { -              char pbuf[100]; - -              switch (vo->type) -                { -                case RFAPI_VN_OPTION_TYPE_L2ADDR: -                  rfapiEthAddr2Str (&vo->v.l2addr.macaddr, pbuf, -                                    sizeof (pbuf)); -                  fp (out, "%sL2 %s LBL=0x%06x NETID=0x%06x NVEID=%d%s", -                      offset, pbuf, (vo->v.l2addr.label & 0x00ffffff), -                      (vo->v.l2addr.logical_net_id & 0x00ffffff), -                      vo->v.l2addr.local_nve_id, HVTYNL); -                  break; - -                case RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP: -                  prefix2str (&vo->v.local_nexthop.addr, pbuf, sizeof (pbuf)); -                  fp (out, "%sLNH %s cost=%d%s", -                      offset, pbuf, vo->v.local_nexthop.cost, HVTYNL); -                  break; - -                default: -                  fp (out, "%svn option type %d (unknown)%s", -                      offset, vo->type, HVTYNL); -                  break; -                } -            } -        } -      if (nh->un_options) -        { -          struct rfapi_un_option *uo; -          char offset[] = "     "; - -          for (uo = nh->un_options; uo; uo = uo->next) -            { -              switch (uo->type) -                { -                case RFAPI_UN_OPTION_TYPE_TUNNELTYPE: -                  rfapi_print_tunneltype_option (stream, 8, &uo->v.tunnel); -                  break; -                default: -                  fp (out, "%sUN Option type %d%s", -                      offset, uo->type, vty_newline); -                  break; -                } - -            } -        } -    } +	if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0) +		return; + +	for (nh = next_hops, count = 1; nh; nh = nh->next, ++count) { + +		char line[BUFSIZ]; +		char *p = line; +		int r; + +		r = snprintf(p, REMAIN, "%3d  pfx=", count); +		INCP; + +		if (rfapiRfapiIpPrefix2Str(&nh->prefix, p, REMAIN)) { +			/* it fit, so count length */ +			r = strlen(p); +		} else { +			/* didn't fit */ +			goto truncate; +		} +		INCP; + +		r = snprintf(p, REMAIN, ", un="); +		INCP; + +		if (rfapiRfapiIpAddr2Str(&nh->un_address, p, REMAIN)) { +			/* it fit, so count length */ +			r = strlen(p); +		} else { +			/* didn't fit */ +			goto truncate; +		} +		INCP; + +		r = snprintf(p, REMAIN, ", vn="); +		INCP; + +		if (rfapiRfapiIpAddr2Str(&nh->vn_address, p, REMAIN)) { +			/* it fit, so count length */ +			r = strlen(p); +		} else { +			/* didn't fit */ +			goto truncate; +		} +		INCP; + +	truncate: +		line[BUFSIZ - 1] = 0; +		fp(out, "%s%s", line, HVTYNL); + +		/* +		 * options +		 */ +		if (nh->vn_options) { +			struct rfapi_vn_option *vo; +			char offset[] = "     "; + +			for (vo = nh->vn_options; vo; vo = vo->next) { +				char pbuf[100]; + +				switch (vo->type) { +				case RFAPI_VN_OPTION_TYPE_L2ADDR: +					rfapiEthAddr2Str(&vo->v.l2addr.macaddr, +							 pbuf, sizeof(pbuf)); +					fp(out, +					   "%sL2 %s LBL=0x%06x NETID=0x%06x NVEID=%d%s", +					   offset, pbuf, +					   (vo->v.l2addr.label & 0x00ffffff), +					   (vo->v.l2addr.logical_net_id +					    & 0x00ffffff), +					   vo->v.l2addr.local_nve_id, HVTYNL); +					break; + +				case RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP: +					prefix2str(&vo->v.local_nexthop.addr, +						   pbuf, sizeof(pbuf)); +					fp(out, "%sLNH %s cost=%d%s", offset, +					   pbuf, vo->v.local_nexthop.cost, +					   HVTYNL); +					break; + +				default: +					fp(out, +					   "%svn option type %d (unknown)%s", +					   offset, vo->type, HVTYNL); +					break; +				} +			} +		} +		if (nh->un_options) { +			struct rfapi_un_option *uo; +			char offset[] = "     "; + +			for (uo = nh->un_options; uo; uo = uo->next) { +				switch (uo->type) { +				case RFAPI_UN_OPTION_TYPE_TUNNELTYPE: +					rfapi_print_tunneltype_option( +						stream, 8, &uo->v.tunnel); +					break; +				default: +					fp(out, "%sUN Option type %d%s", offset, +					   uo->type, vty_newline); +					break; +				} +			} +		} +	}  }  /*********************************************************************** @@ -2129,397 +1909,350 @@ rfapiPrintNhl (void *stream, struct rfapi_next_hop_entry *next_hops)  /*   * Add another nexthop to the NHL   */ -static void -rfapiAddDeleteLocalRfpPrefix ( -  struct rfapi_ip_addr		*un_addr, -  struct rfapi_ip_addr		*vn_addr, -  struct rfapi_ip_prefix	*rprefix, -  int				is_add, -  uint32_t			lifetime,     /* add only */ -  struct rfapi_vn_option	*vn_options, -  struct rfapi_next_hop_entry	**head, -  struct rfapi_next_hop_entry	**tail) +static void rfapiAddDeleteLocalRfpPrefix(struct rfapi_ip_addr *un_addr, +					 struct rfapi_ip_addr *vn_addr, +					 struct rfapi_ip_prefix *rprefix, +					 int is_add, +					 uint32_t lifetime, /* add only */ +					 struct rfapi_vn_option *vn_options, +					 struct rfapi_next_hop_entry **head, +					 struct rfapi_next_hop_entry **tail)  { -  struct rfapi_next_hop_entry *new; - -  /* -   * construct NHL -   */ - -  new = XCALLOC (MTYPE_RFAPI_NEXTHOP, sizeof (struct rfapi_next_hop_entry)); -  new->prefix = *rprefix; -  new->un_address = *un_addr; -  new->vn_address = *vn_addr; - -  new->vn_options = vn_options; -  if (is_add) -    { -      new->lifetime = lifetime; -    } -  else -    { -      new->lifetime = RFAPI_REMOVE_RESPONSE_LIFETIME; -    } - -  if (*tail) -    (*tail)->next = new; -  *tail = new; -  if (!*head) -    { -      *head = new; -    } +	struct rfapi_next_hop_entry *new; + +	/* +	 * construct NHL +	 */ + +	new = XCALLOC(MTYPE_RFAPI_NEXTHOP, sizeof(struct rfapi_next_hop_entry)); +	new->prefix = *rprefix; +	new->un_address = *un_addr; +	new->vn_address = *vn_addr; + +	new->vn_options = vn_options; +	if (is_add) { +		new->lifetime = lifetime; +	} else { +		new->lifetime = RFAPI_REMOVE_RESPONSE_LIFETIME; +	} + +	if (*tail) +		(*tail)->next = new; +	*tail = new; +	if (!*head) { +		*head = new; +	}  }  static int -register_add ( -  struct vty *vty, -  struct cmd_token *carg_prefix, -  struct cmd_token *carg_vn, -  struct cmd_token *carg_un, -  struct cmd_token *carg_cost,     /* optional */ -  struct cmd_token *carg_lifetime, /* optional */ -  struct cmd_token *carg_macaddr,  /* optional */ -  struct cmd_token *carg_vni,      /* mac present=>mandatory Virtual Network ID */ -  int        argc, -  struct cmd_token **argv) +register_add(struct vty *vty, struct cmd_token *carg_prefix, +	     struct cmd_token *carg_vn, struct cmd_token *carg_un, +	     struct cmd_token *carg_cost,     /* optional */ +	     struct cmd_token *carg_lifetime, /* optional */ +	     struct cmd_token *carg_macaddr,  /* optional */ +	     struct cmd_token +		     *carg_vni, /* mac present=>mandatory Virtual Network ID */ +	     int argc, struct cmd_token **argv)  { -       const char *arg_prefix = carg_prefix ? carg_prefix->arg : NULL; -       const char *arg_vn = carg_vn ? carg_vn->arg : NULL; -       const char *arg_un = carg_un ? carg_un->arg : NULL; -       const char *arg_cost = carg_cost ? carg_cost->arg : NULL; -       const char *arg_lifetime = carg_lifetime ? carg_lifetime->arg : NULL; -       const char *arg_macaddr = carg_macaddr ? carg_macaddr->arg : NULL; -       const char *arg_vni = carg_vni ? carg_vni->arg : NULL; -       struct rfapi_ip_addr vn_address; -       struct rfapi_ip_addr un_address; -       struct prefix pfx; -       struct rfapi_ip_prefix rpfx; -       uint32_t cost; -       uint32_t lnh_cost; -       uint32_t lifetime; -       rfapi_handle rfd; -       struct rfapi_vn_option optary[10];       /* XXX must be big enough */ -       struct rfapi_vn_option *opt = NULL; -       int opt_next = 0; - -       int rc = CMD_WARNING_CONFIG_FAILED; -       char *endptr; -       struct bgp *bgp; -       struct rfapi *h; -       struct rfapi_cfg *rfapi_cfg; - -       const char *arg_lnh = NULL; -       const char *arg_lnh_cost = NULL; - -         bgp = bgp_get_default ();      /* assume 1 instance for now */ -       if (!bgp) -         { -           if (vty) -             vty_out (vty, "BGP not configured\n"); -           return CMD_WARNING_CONFIG_FAILED; -         } - -       h = bgp->rfapi; -       rfapi_cfg = bgp->rfapi_cfg; -       if (!h || !rfapi_cfg) -         { -           if (vty) -             vty_out (vty, "RFAPI not configured\n"); -           return CMD_WARNING_CONFIG_FAILED; -         } - -       for (; argc; --argc, ++argv) -         { -           if (strmatch(argv[0]->text, "local-next-hop")) -             { -               if (arg_lnh) -                 { -                   vty_out (vty,"local-next-hop specified more than once\n"); -                   return CMD_WARNING_CONFIG_FAILED; -                 } -               if (argc <= 1) -                 { -                   vty_out (vty,"Missing parameter for local-next-hop\n"); -                   return CMD_WARNING_CONFIG_FAILED; -                 } -               ++argv, --argc; -               arg_lnh = argv[0]->arg; -             } -           if (strmatch(argv[0]->text, "local-cost")) -             { -               if (arg_lnh_cost) -                 { -                   vty_out (vty,"local-cost specified more than once\n"); -                   return CMD_WARNING_CONFIG_FAILED; -                 } -               if (argc <= 1) -                 { -                   vty_out (vty,"Missing parameter for local-cost\n"); -                   return CMD_WARNING_CONFIG_FAILED; -                 } -               ++argv, --argc; -               arg_lnh_cost = argv[0]->arg; -             } -         } - -       if ((rc = rfapiCliGetRfapiIpAddr (vty, arg_vn, &vn_address))) -         goto fail; -       if ((rc = rfapiCliGetRfapiIpAddr (vty, arg_un, &un_address))) -         goto fail; - -       /* arg_prefix is optional if mac address is given */ -       if (arg_macaddr && !arg_prefix) -         { -           /* -            * fake up a 0/32 or 0/128 prefix -            */ -           switch (vn_address.addr_family) -             { -             case AF_INET: -               arg_prefix = "0.0.0.0/32"; -               break; -             case AF_INET6: -               arg_prefix = "0::0/128"; -               break; -             default: -               vty_out (vty,"Internal error, unknown VN address family\n"); -               return CMD_WARNING_CONFIG_FAILED; -             } - -         } - -       if (!str2prefix (arg_prefix, &pfx)) -         { -           vty_out (vty, "Malformed prefix \"%s\"\n",arg_prefix); -           goto fail; -         } -       if (pfx.family != AF_INET -           && pfx.family != AF_INET6) -         { -           vty_out (vty, "prefix \"%s\" has invalid address family\n", -                    arg_prefix); -           goto fail; -         } - - -       memset (optary, 0, sizeof (optary)); - -       if (arg_cost) -         { -           endptr = NULL; -           cost = strtoul (arg_cost, &endptr, 10); -           if (*endptr != '\0' || cost > 255) -             { -               vty_out (vty, "%% Invalid %s value\n", "cost"); -               goto fail; -             } -         } -       else -         { -           cost = 255; -         } - -       if (arg_lifetime) -         { -           if (!strcmp (arg_lifetime, "infinite")) -             { -               lifetime = RFAPI_INFINITE_LIFETIME; -             } -           else -             { -               endptr = NULL; -               lifetime = strtoul (arg_lifetime, &endptr, 10); -               if (*endptr != '\0') -                 { -                   vty_out (vty, "%% Invalid %s value\n","lifetime"); -                   goto fail; -                 } -             } -         } -       else -         { -           lifetime = RFAPI_INFINITE_LIFETIME;  /* default infinite */ -         } - -       if (arg_lnh_cost) -         { -           if (!arg_lnh) -             { -               vty_out (vty, -                        "%% %s may only be specified with local-next-hop\n", -                        "local-cost"); -               goto fail; -             } -           endptr = NULL; -           lnh_cost = strtoul (arg_lnh_cost, &endptr, 10); -           if (*endptr != '\0' || lnh_cost > 255) -             { -               vty_out (vty, "%% Invalid %s value\n","local-cost"); -               goto fail; -             } -         } -       else -         { -           lnh_cost = 255; -         } - -       if (arg_lnh) -         { -           if (!arg_prefix) -             { -               vty_out (vty, "%% %s may only be specified with prefix\n", -                        "local-next-hop"); -               goto fail; -             } -           if ((rc = rfapiCliGetPrefixAddr (vty, arg_lnh, -                                            &optary[opt_next].v. -                                            local_nexthop.addr))) -             { - -               goto fail; -             } - -           optary[opt_next].v.local_nexthop.cost = lnh_cost; -           optary[opt_next].type = RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP; - -           if (opt_next) -             { -               optary[opt_next - 1].next = optary + opt_next; -             } -           else -             { -               opt = optary; -             } -           ++opt_next; -         } - -       if (arg_vni && !arg_macaddr) -         { -           vty_out (vty, "%% %s may only be specified with mac address\n", -                    "virtual-network-identifier"); -           goto fail; -         } - -       if (arg_macaddr) -         { -           if (!arg_vni) -             { -               vty_out (vty, -                        "Missing \"vni\" parameter (mandatory with mac)\n"); -               return CMD_WARNING_CONFIG_FAILED; -             } -           optary[opt_next].v.l2addr.logical_net_id = strtoul(arg_vni, NULL, -                                                              10); - -           if ((rc = rfapiStr2EthAddr (arg_macaddr, -                                       &optary[opt_next].v.l2addr.macaddr))) -             { -               vty_out (vty, "Invalid %s value\n","mac address"); -               goto fail; -             } -           /* TBD label, NVE ID */ - -           optary[opt_next].type = RFAPI_VN_OPTION_TYPE_L2ADDR; - -           if (opt_next) -             { -               optary[opt_next - 1].next = optary + opt_next; -             } -           else -             { -               opt = optary; -             } -           ++opt_next; -         } - -       vnc_zlog_debug_verbose -         ("%s: vn=%s, un=%s, prefix=%s, cost=%s, lifetime=%s, lnh=%s", -          __func__, arg_vn, arg_un, arg_prefix, -          (arg_cost ? arg_cost : "NULL"), -          (arg_lifetime ? arg_lifetime : "NULL"), -          (arg_lnh ? arg_lnh : "NULL")); - -       rfapiQprefix2Rprefix (&pfx, &rpfx); - -       rpfx.cost = cost & 255; - -       /* look up rf descriptor, call open if it doesn't exist  */ -       rc = -         rfapi_find_rfd (bgp, &vn_address, &un_address, -                         (struct rfapi_descriptor **) &rfd); -       if (rc) -         { -           if (ENOENT == rc) -             { -               struct rfapi_un_option uo; - -               /* -                * flag descriptor as provisionally opened for static route -                * registration so that we can fix up the other parameters -                * when the real open comes along -                */ -               memset (&uo, 0, sizeof (uo)); -               uo.type = RFAPI_UN_OPTION_TYPE_PROVISIONAL; - -               rc = rfapi_open (rfapi_get_rfp_start_val_by_bgp (bgp), &vn_address, &un_address, &uo,    /* flags */ -                                NULL, NULL,     /* no userdata */ -                                &rfd); -               if (rc) -                 { -                   vty_out (vty, "Can't open session for this NVE: %s\n", -                            rfapi_error_str(rc)); -                   rc = CMD_WARNING_CONFIG_FAILED; -                   goto fail; -                 } -             } -           else -             { -               vty_out (vty, "Can't find session for this NVE: %s\n", -                        rfapi_error_str(rc)); -               goto fail; -             } -         } - -       rc = -         rfapi_register (rfd, &rpfx, lifetime, NULL, opt, RFAPI_REGISTER_ADD); -       if (!rc) -         { -           struct rfapi_next_hop_entry *head = NULL; -           struct rfapi_next_hop_entry *tail = NULL; -           struct rfapi_vn_option *vn_opt_new; - -           vnc_zlog_debug_verbose ("%s: rfapi_register succeeded, returning 0", __func__); - -           if (h->rfp_methods.local_cb) -             { -               struct rfapi_descriptor *r = (struct rfapi_descriptor *) rfd; -               vn_opt_new = rfapi_vn_options_dup (opt); - -               rfapiAddDeleteLocalRfpPrefix (&r->un_addr, &r->vn_addr, &rpfx, -                                             1, lifetime, vn_opt_new, &head, -                                             &tail); -               if (head) -                 { -                   h->flags |= RFAPI_INCALLBACK; -                   (*h->rfp_methods.local_cb) (head, r->cookie); -                   h->flags &= ~RFAPI_INCALLBACK; -                 } -               head = tail = NULL; -             } -           return 0; -         } - -       vnc_zlog_debug_verbose ("%s: rfapi_register failed", __func__); -       vty_out (vty, "\n"); -       vty_out (vty, "Registration failed.\n"); -       vty_out (vty, -                "Confirm that either the VN or UN address matches a configured NVE group.\n"); -       return CMD_WARNING_CONFIG_FAILED; - -     fail: -       vnc_zlog_debug_verbose ("%s: fail, rc=%d", __func__, rc); -       return rc; +	const char *arg_prefix = carg_prefix ? carg_prefix->arg : NULL; +	const char *arg_vn = carg_vn ? carg_vn->arg : NULL; +	const char *arg_un = carg_un ? carg_un->arg : NULL; +	const char *arg_cost = carg_cost ? carg_cost->arg : NULL; +	const char *arg_lifetime = carg_lifetime ? carg_lifetime->arg : NULL; +	const char *arg_macaddr = carg_macaddr ? carg_macaddr->arg : NULL; +	const char *arg_vni = carg_vni ? carg_vni->arg : NULL; +	struct rfapi_ip_addr vn_address; +	struct rfapi_ip_addr un_address; +	struct prefix pfx; +	struct rfapi_ip_prefix rpfx; +	uint32_t cost; +	uint32_t lnh_cost; +	uint32_t lifetime; +	rfapi_handle rfd; +	struct rfapi_vn_option optary[10]; /* XXX must be big enough */ +	struct rfapi_vn_option *opt = NULL; +	int opt_next = 0; + +	int rc = CMD_WARNING_CONFIG_FAILED; +	char *endptr; +	struct bgp *bgp; +	struct rfapi *h; +	struct rfapi_cfg *rfapi_cfg; + +	const char *arg_lnh = NULL; +	const char *arg_lnh_cost = NULL; + +	bgp = bgp_get_default(); /* assume 1 instance for now */ +	if (!bgp) { +		if (vty) +			vty_out(vty, "BGP not configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	h = bgp->rfapi; +	rfapi_cfg = bgp->rfapi_cfg; +	if (!h || !rfapi_cfg) { +		if (vty) +			vty_out(vty, "RFAPI not configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	for (; argc; --argc, ++argv) { +		if (strmatch(argv[0]->text, "local-next-hop")) { +			if (arg_lnh) { +				vty_out(vty, +					"local-next-hop specified more than once\n"); +				return CMD_WARNING_CONFIG_FAILED; +			} +			if (argc <= 1) { +				vty_out(vty, +					"Missing parameter for local-next-hop\n"); +				return CMD_WARNING_CONFIG_FAILED; +			} +			++argv, --argc; +			arg_lnh = argv[0]->arg; +		} +		if (strmatch(argv[0]->text, "local-cost")) { +			if (arg_lnh_cost) { +				vty_out(vty, +					"local-cost specified more than once\n"); +				return CMD_WARNING_CONFIG_FAILED; +			} +			if (argc <= 1) { +				vty_out(vty, +					"Missing parameter for local-cost\n"); +				return CMD_WARNING_CONFIG_FAILED; +			} +			++argv, --argc; +			arg_lnh_cost = argv[0]->arg; +		} +	} + +	if ((rc = rfapiCliGetRfapiIpAddr(vty, arg_vn, &vn_address))) +		goto fail; +	if ((rc = rfapiCliGetRfapiIpAddr(vty, arg_un, &un_address))) +		goto fail; + +	/* arg_prefix is optional if mac address is given */ +	if (arg_macaddr && !arg_prefix) { +		/* +		 * fake up a 0/32 or 0/128 prefix +		 */ +		switch (vn_address.addr_family) { +		case AF_INET: +			arg_prefix = "0.0.0.0/32"; +			break; +		case AF_INET6: +			arg_prefix = "0::0/128"; +			break; +		default: +			vty_out(vty, +				"Internal error, unknown VN address family\n"); +			return CMD_WARNING_CONFIG_FAILED; +		} +	} + +	if (!str2prefix(arg_prefix, &pfx)) { +		vty_out(vty, "Malformed prefix \"%s\"\n", arg_prefix); +		goto fail; +	} +	if (pfx.family != AF_INET && pfx.family != AF_INET6) { +		vty_out(vty, "prefix \"%s\" has invalid address family\n", +			arg_prefix); +		goto fail; +	} + + +	memset(optary, 0, sizeof(optary)); + +	if (arg_cost) { +		endptr = NULL; +		cost = strtoul(arg_cost, &endptr, 10); +		if (*endptr != '\0' || cost > 255) { +			vty_out(vty, "%% Invalid %s value\n", "cost"); +			goto fail; +		} +	} else { +		cost = 255; +	} + +	if (arg_lifetime) { +		if (!strcmp(arg_lifetime, "infinite")) { +			lifetime = RFAPI_INFINITE_LIFETIME; +		} else { +			endptr = NULL; +			lifetime = strtoul(arg_lifetime, &endptr, 10); +			if (*endptr != '\0') { +				vty_out(vty, "%% Invalid %s value\n", +					"lifetime"); +				goto fail; +			} +		} +	} else { +		lifetime = RFAPI_INFINITE_LIFETIME; /* default infinite */ +	} + +	if (arg_lnh_cost) { +		if (!arg_lnh) { +			vty_out(vty, +				"%% %s may only be specified with local-next-hop\n", +				"local-cost"); +			goto fail; +		} +		endptr = NULL; +		lnh_cost = strtoul(arg_lnh_cost, &endptr, 10); +		if (*endptr != '\0' || lnh_cost > 255) { +			vty_out(vty, "%% Invalid %s value\n", "local-cost"); +			goto fail; +		} +	} else { +		lnh_cost = 255; +	} + +	if (arg_lnh) { +		if (!arg_prefix) { +			vty_out(vty, +				"%% %s may only be specified with prefix\n", +				"local-next-hop"); +			goto fail; +		} +		if ((rc = rfapiCliGetPrefixAddr( +			     vty, arg_lnh, +			     &optary[opt_next].v.local_nexthop.addr))) { + +			goto fail; +		} + +		optary[opt_next].v.local_nexthop.cost = lnh_cost; +		optary[opt_next].type = RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP; + +		if (opt_next) { +			optary[opt_next - 1].next = optary + opt_next; +		} else { +			opt = optary; +		} +		++opt_next; +	} + +	if (arg_vni && !arg_macaddr) { +		vty_out(vty, "%% %s may only be specified with mac address\n", +			"virtual-network-identifier"); +		goto fail; +	} + +	if (arg_macaddr) { +		if (!arg_vni) { +			vty_out(vty, +				"Missing \"vni\" parameter (mandatory with mac)\n"); +			return CMD_WARNING_CONFIG_FAILED; +		} +		optary[opt_next].v.l2addr.logical_net_id = +			strtoul(arg_vni, NULL, 10); + +		if ((rc = rfapiStr2EthAddr( +			     arg_macaddr, +			     &optary[opt_next].v.l2addr.macaddr))) { +			vty_out(vty, "Invalid %s value\n", "mac address"); +			goto fail; +		} +		/* TBD label, NVE ID */ + +		optary[opt_next].type = RFAPI_VN_OPTION_TYPE_L2ADDR; + +		if (opt_next) { +			optary[opt_next - 1].next = optary + opt_next; +		} else { +			opt = optary; +		} +		++opt_next; +	} + +	vnc_zlog_debug_verbose( +		"%s: vn=%s, un=%s, prefix=%s, cost=%s, lifetime=%s, lnh=%s", +		__func__, arg_vn, arg_un, arg_prefix, +		(arg_cost ? arg_cost : "NULL"), +		(arg_lifetime ? arg_lifetime : "NULL"), +		(arg_lnh ? arg_lnh : "NULL")); + +	rfapiQprefix2Rprefix(&pfx, &rpfx); + +	rpfx.cost = cost & 255; + +	/* look up rf descriptor, call open if it doesn't exist  */ +	rc = rfapi_find_rfd(bgp, &vn_address, &un_address, +			    (struct rfapi_descriptor **)&rfd); +	if (rc) { +		if (ENOENT == rc) { +			struct rfapi_un_option uo; + +			/* +			 * flag descriptor as provisionally opened for static +			 * route +			 * registration so that we can fix up the other +			 * parameters +			 * when the real open comes along +			 */ +			memset(&uo, 0, sizeof(uo)); +			uo.type = RFAPI_UN_OPTION_TYPE_PROVISIONAL; + +			rc = rfapi_open(rfapi_get_rfp_start_val_by_bgp(bgp), +					&vn_address, &un_address, +					&uo,	/* flags */ +					NULL, NULL, /* no userdata */ +					&rfd); +			if (rc) { +				vty_out(vty, +					"Can't open session for this NVE: %s\n", +					rfapi_error_str(rc)); +				rc = CMD_WARNING_CONFIG_FAILED; +				goto fail; +			} +		} else { +			vty_out(vty, "Can't find session for this NVE: %s\n", +				rfapi_error_str(rc)); +			goto fail; +		} +	} + +	rc = rfapi_register(rfd, &rpfx, lifetime, NULL, opt, +			    RFAPI_REGISTER_ADD); +	if (!rc) { +		struct rfapi_next_hop_entry *head = NULL; +		struct rfapi_next_hop_entry *tail = NULL; +		struct rfapi_vn_option *vn_opt_new; + +		vnc_zlog_debug_verbose( +			"%s: rfapi_register succeeded, returning 0", __func__); + +		if (h->rfp_methods.local_cb) { +			struct rfapi_descriptor *r = +				(struct rfapi_descriptor *)rfd; +			vn_opt_new = rfapi_vn_options_dup(opt); + +			rfapiAddDeleteLocalRfpPrefix(&r->un_addr, &r->vn_addr, +						     &rpfx, 1, lifetime, +						     vn_opt_new, &head, &tail); +			if (head) { +				h->flags |= RFAPI_INCALLBACK; +				(*h->rfp_methods.local_cb)(head, r->cookie); +				h->flags &= ~RFAPI_INCALLBACK; +			} +			head = tail = NULL; +		} +		return 0; +	} + +	vnc_zlog_debug_verbose("%s: rfapi_register failed", __func__); +	vty_out(vty, "\n"); +	vty_out(vty, "Registration failed.\n"); +	vty_out(vty, +		"Confirm that either the VN or UN address matches a configured NVE group.\n"); +	return CMD_WARNING_CONFIG_FAILED; + +fail: +	vnc_zlog_debug_verbose("%s: fail, rc=%d", __func__, rc); +	return rc;  }  /************************************************************************ @@ -2545,10 +2278,10 @@ DEFUN (add_vnc_prefix_cost_life_lnh,         "Lifetime value in seconds\n"         "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")  { -  /*                       pfx      vn       un       cost     life */ -  return register_add (vty, argv[3], argv[5], argv[7], argv[9], argv[11], -                       /* mac vni */ -                       NULL, NULL, argc - 12, argv + 12); +	/*                       pfx      vn       un       cost     life */ +	return register_add(vty, argv[3], argv[5], argv[7], argv[9], argv[11], +			    /* mac vni */ +			    NULL, NULL, argc - 12, argv + 12);  }  DEFUN (add_vnc_prefix_life_cost_lnh, @@ -2571,10 +2304,10 @@ DEFUN (add_vnc_prefix_life_cost_lnh,         "Administrative cost\n"         "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")  { -  /*                       pfx      vn       un       cost     life */ -  return register_add (vty, argv[3], argv[5], argv[7], argv[11], argv[9], -                       /* mac vni */ -                       NULL, NULL, argc - 12, argv + 12); +	/*                       pfx      vn       un       cost     life */ +	return register_add(vty, argv[3], argv[5], argv[7], argv[11], argv[9], +			    /* mac vni */ +			    NULL, NULL, argc - 12, argv + 12);  }  DEFUN (add_vnc_prefix_cost_lnh, @@ -2595,10 +2328,10 @@ DEFUN (add_vnc_prefix_cost_lnh,         "Administrative cost\n"         "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")  { -  /*                       pfx      vn       un       cost     life */ -  return register_add (vty, argv[3], argv[5], argv[7], argv[9], NULL, -                       /* mac vni */ -                       NULL, NULL, argc - 10, argv + 10); +	/*                       pfx      vn       un       cost     life */ +	return register_add(vty, argv[3], argv[5], argv[7], argv[9], NULL, +			    /* mac vni */ +			    NULL, NULL, argc - 10, argv + 10);  }  DEFUN (add_vnc_prefix_life_lnh, @@ -2619,10 +2352,10 @@ DEFUN (add_vnc_prefix_life_lnh,         "Lifetime value in seconds\n"         "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")  { -  /*                       pfx      vn       un       cost     life */ -  return register_add (vty, argv[3], argv[5], argv[7], NULL, argv[9], -                       /* mac vni */ -                       NULL, NULL, argc - 10, argv + 10); +	/*                       pfx      vn       un       cost     life */ +	return register_add(vty, argv[3], argv[5], argv[7], NULL, argv[9], +			    /* mac vni */ +			    NULL, NULL, argc - 10, argv + 10);  }  DEFUN (add_vnc_prefix_lnh, @@ -2641,10 +2374,10 @@ DEFUN (add_vnc_prefix_lnh,         "UN IPv6 interface address\n"         "[local-next-hop (A.B.C.D|X:X::X:X)] [local-cost <0-255>]\n")  { -  /*                       pfx      vn       un       cost     life */ -  return register_add (vty, argv[3], argv[5], argv[7], NULL, NULL, -                       /* mac vni */ -                       NULL, NULL, argc - 8, argv + 8); +	/*                       pfx      vn       un       cost     life */ +	return register_add(vty, argv[3], argv[5], argv[7], NULL, NULL, +			    /* mac vni */ +			    NULL, NULL, argc - 8, argv + 8);  }  /************************************************************************ @@ -2669,10 +2402,10 @@ DEFUN (add_vnc_prefix_cost_life,         "Registration lifetime [default: infinite]\n"         "Lifetime value in seconds\n")  { -  /*                       pfx      vn       un       cost     life */ -  return register_add (vty, argv[3], argv[5], argv[7], argv[9], argv[11], -                       /* mac vni */ -                       NULL, NULL, 0, NULL); +	/*                       pfx      vn       un       cost     life */ +	return register_add(vty, argv[3], argv[5], argv[7], argv[9], argv[11], +			    /* mac vni */ +			    NULL, NULL, 0, NULL);  }  DEFUN (add_vnc_prefix_life_cost, @@ -2694,10 +2427,10 @@ DEFUN (add_vnc_prefix_life_cost,         "Administrative cost   [default: 255]\n"         "Administrative cost\n")  { -  /*                       pfx      vn       un       cost     life */ -  return register_add (vty, argv[3], argv[5], argv[7], argv[11], argv[9], -                       /* mac vni */ -                       NULL, NULL, 0, NULL); +	/*                       pfx      vn       un       cost     life */ +	return register_add(vty, argv[3], argv[5], argv[7], argv[11], argv[9], +			    /* mac vni */ +			    NULL, NULL, 0, NULL);  }  DEFUN (add_vnc_prefix_cost, @@ -2717,10 +2450,10 @@ DEFUN (add_vnc_prefix_cost,         "Administrative cost   [default: 255]\n"         "Administrative cost\n")  { -  /*                       pfx      vn       un       cost     life */ -  return register_add (vty, argv[3], argv[5], argv[7], argv[9], NULL, -                       /* mac vni */ -                       NULL, NULL, 0, NULL); +	/*                       pfx      vn       un       cost     life */ +	return register_add(vty, argv[3], argv[5], argv[7], argv[9], NULL, +			    /* mac vni */ +			    NULL, NULL, 0, NULL);  }  DEFUN (add_vnc_prefix_life, @@ -2740,10 +2473,10 @@ DEFUN (add_vnc_prefix_life,         "Registration lifetime [default: infinite]\n"         "Lifetime value in seconds\n")  { -  /*                       pfx      vn       un       cost     life */ -  return register_add (vty, argv[3], argv[5], argv[7], NULL, argv[9], -                       /* mac vni */ -                       NULL, NULL, 0, NULL); +	/*                       pfx      vn       un       cost     life */ +	return register_add(vty, argv[3], argv[5], argv[7], NULL, argv[9], +			    /* mac vni */ +			    NULL, NULL, 0, NULL);  }  DEFUN (add_vnc_prefix, @@ -2761,10 +2494,10 @@ DEFUN (add_vnc_prefix,         "UN IPv4 interface address\n"         "UN IPv6 interface address\n")  { -  /*                       pfx      vn       un       cost     life */ -  return register_add (vty, argv[3], argv[5], argv[7], NULL, NULL, -                       /* mac vni */ -                       NULL, NULL, 0, NULL); +	/*                       pfx      vn       un       cost     life */ +	return register_add(vty, argv[3], argv[5], argv[7], NULL, NULL, +			    /* mac vni */ +			    NULL, NULL, 0, NULL);  }  /************************************************************************ @@ -2793,10 +2526,10 @@ DEFUN (add_vnc_mac_vni_prefix_cost_life,         "Registration lifetime [default: infinite]\n"         "Lifetime value in seconds\n")  { -  /*                       pfx      vn       un       cost     life */ -  return register_add (vty, argv[11], argv[7], argv[9], argv[13], argv[15], -                       /* mac vni */ -                       argv[3], argv[5], 0, NULL); +	/*                       pfx      vn       un       cost     life */ +	return register_add(vty, argv[11], argv[7], argv[9], argv[13], argv[15], +			    /* mac vni */ +			    argv[3], argv[5], 0, NULL);  } @@ -2821,10 +2554,10 @@ DEFUN (add_vnc_mac_vni_prefix_life,         "Registration lifetime [default: infinite]\n"         "Lifetime value in seconds\n")  { -  /*                       pfx      vn       un       cost     life */ -  return register_add (vty, argv[11], argv[7], argv[9], NULL, argv[13], -                       /* mac vni */ -                       argv[3], argv[5], 0, NULL); +	/*                       pfx      vn       un       cost     life */ +	return register_add(vty, argv[11], argv[7], argv[9], NULL, argv[13], +			    /* mac vni */ +			    argv[3], argv[5], 0, NULL);  }  DEFUN (add_vnc_mac_vni_prefix_cost, @@ -2847,10 +2580,10 @@ DEFUN (add_vnc_mac_vni_prefix_cost,         "IPv6 prefix\n"         "Administrative cost   [default: 255]\n" "Administrative cost\n")  { -  /*                       pfx      vn       un       cost     life */ -  return register_add (vty, argv[11], argv[7], argv[9], argv[13], NULL, -                       /* mac vni */ -                       argv[3], argv[5], 0, NULL); +	/*                       pfx      vn       un       cost     life */ +	return register_add(vty, argv[11], argv[7], argv[9], argv[13], NULL, +			    /* mac vni */ +			    argv[3], argv[5], 0, NULL);  }  DEFUN (add_vnc_mac_vni_prefix, @@ -2871,10 +2604,10 @@ DEFUN (add_vnc_mac_vni_prefix,         "Add/modify prefix related information\n"         "IPv4 prefix\n" "IPv6 prefix\n")  { -  /*                       pfx      vn       un       cost     life */ -  return register_add (vty, argv[11], argv[7], argv[9], NULL, NULL, -                       /* mac vni */ -                       argv[3], argv[5], 0, NULL); +	/*                       pfx      vn       un       cost     life */ +	return register_add(vty, argv[11], argv[7], argv[9], NULL, NULL, +			    /* mac vni */ +			    argv[3], argv[5], 0, NULL);  }  DEFUN (add_vnc_mac_vni_cost_life, @@ -2897,10 +2630,10 @@ DEFUN (add_vnc_mac_vni_cost_life,         "Registration lifetime [default: infinite]\n"         "Lifetime value in seconds\n")  { -  /*                       pfx      vn       un       cost     life */ -  return register_add (vty, NULL, argv[7], argv[9], argv[11], argv[13], -                       /* mac vni */ -                       argv[3], argv[5], 0, NULL); +	/*                       pfx      vn       un       cost     life */ +	return register_add(vty, NULL, argv[7], argv[9], argv[11], argv[13], +			    /* mac vni */ +			    argv[3], argv[5], 0, NULL);  } @@ -2921,10 +2654,10 @@ DEFUN (add_vnc_mac_vni_cost,         "UN IPv6 interface address\n"         "Administrative cost   [default: 255]\n" "Administrative cost\n")  { -  /*                       pfx      vn       un    cost     life */ -  return register_add (vty, NULL, argv[7], argv[9], argv[11], NULL, -                       /* mac vni */ -                       argv[3], argv[5], 0, NULL); +	/*                       pfx      vn       un    cost     life */ +	return register_add(vty, NULL, argv[7], argv[9], argv[11], NULL, +			    /* mac vni */ +			    argv[3], argv[5], 0, NULL);  } @@ -2946,10 +2679,10 @@ DEFUN (add_vnc_mac_vni_life,         "Registration lifetime [default: infinite]\n"         "Lifetime value in seconds\n")  { -  /*                       pfx      vn       un    cost  life */ -  return register_add (vty, NULL, argv[7], argv[9], NULL, argv[11], -                       /* mac vni */ -                       argv[3], argv[5], 0, NULL); +	/*                       pfx      vn       un    cost  life */ +	return register_add(vty, NULL, argv[7], argv[9], NULL, argv[11], +			    /* mac vni */ +			    argv[3], argv[5], 0, NULL);  } @@ -2968,674 +2701,643 @@ DEFUN (add_vnc_mac_vni,         "UN address of NVE\n"         "UN IPv4 interface address\n" "UN IPv6 interface address\n")  { -  /*                       pfx      vn       un    cost  life */ -  return register_add (vty, NULL, argv[7], argv[9], NULL, NULL, -                       /* mac vni */ -                       argv[3], argv[5], 0, NULL); +	/*                       pfx      vn       un    cost  life */ +	return register_add(vty, NULL, argv[7], argv[9], NULL, NULL, +			    /* mac vni */ +			    argv[3], argv[5], 0, NULL);  }  /************************************************************************   *			Delete prefix   ************************************************************************/ -struct rfapi_local_reg_delete_arg -{ -  /* -   * match parameters -   */ -  struct bgp           *bgp; -  struct rfapi_ip_addr	un_address;	/* AF==0: wildcard */ -  struct rfapi_ip_addr	vn_address;	/* AF==0: wildcard */ -  struct prefix		prefix;		/* AF==0: wildcard */ -  struct prefix_rd	rd;		/* plen!=64: wildcard */ -  struct rfapi_nve_group_cfg *rfg;      /* NULL: wildcard */ - -  struct rfapi_l2address_option_match l2o; - -  /* -   * result parameters -   */ -  struct vty		*vty; -  uint32_t		reg_count; -  uint32_t		pfx_count; -  uint32_t		query_count; - -  uint32_t		failed_pfx_count; - -  uint32_t		nve_count; -  struct skiplist	*nves; - -  uint32_t		remote_active_nve_count; -  uint32_t		remote_active_pfx_count; -  uint32_t		remote_holddown_nve_count; -  uint32_t		remote_holddown_pfx_count; +struct rfapi_local_reg_delete_arg { +	/* +	 * match parameters +	 */ +	struct bgp *bgp; +	struct rfapi_ip_addr un_address; /* AF==0: wildcard */ +	struct rfapi_ip_addr vn_address; /* AF==0: wildcard */ +	struct prefix prefix;		 /* AF==0: wildcard */ +	struct prefix_rd rd;		 /* plen!=64: wildcard */ +	struct rfapi_nve_group_cfg *rfg; /* NULL: wildcard */ + +	struct rfapi_l2address_option_match l2o; + +	/* +	 * result parameters +	 */ +	struct vty *vty; +	uint32_t reg_count; +	uint32_t pfx_count; +	uint32_t query_count; + +	uint32_t failed_pfx_count; + +	uint32_t nve_count; +	struct skiplist *nves; + +	uint32_t remote_active_nve_count; +	uint32_t remote_active_pfx_count; +	uint32_t remote_holddown_nve_count; +	uint32_t remote_holddown_pfx_count;  }; -struct nve_addr -{ -  struct rfapi_ip_addr			vn; -  struct rfapi_ip_addr			un; -  struct rfapi_descriptor		*rfd; -  struct rfapi_local_reg_delete_arg	*cda; +struct nve_addr { +	struct rfapi_ip_addr vn; +	struct rfapi_ip_addr un; +	struct rfapi_descriptor *rfd; +	struct rfapi_local_reg_delete_arg *cda;  }; -static void -nve_addr_free (void *hap) +static void nve_addr_free(void *hap)  { -  ((struct nve_addr *) hap)->cda->nve_count += 1; -  XFREE (MTYPE_RFAPI_NVE_ADDR, hap); +	((struct nve_addr *)hap)->cda->nve_count += 1; +	XFREE(MTYPE_RFAPI_NVE_ADDR, hap);  } -static int -nve_addr_cmp (void *k1, void *k2) +static int nve_addr_cmp(void *k1, void *k2)  { -  struct nve_addr *a = (struct nve_addr *) k1; -  struct nve_addr *b = (struct nve_addr *) k2; -  int ret = 0; - -  if (!a || !b) -    { -      return (a - b); -    } -  if (a->un.addr_family != b->un.addr_family) -    { -      return (a->un.addr_family - b->un.addr_family); -    } -  if (a->vn.addr_family != b->vn.addr_family) -    { -      return (a->vn.addr_family - b->vn.addr_family); -    } -  if (a->un.addr_family == AF_INET) -    { -      ret = IPV4_ADDR_CMP (&a->un.addr.v4, &b->un.addr.v4); -      if (ret != 0) -        { -          return ret; -        } -    } -  else if (a->un.addr_family == AF_INET6) -    { -      ret = IPV6_ADDR_CMP (&a->un.addr.v6, &b->un.addr.v6); -      if (ret != 0) -        { -          return ret; -        } -    } -  else -    { -      assert (0); -    } -  if (a->vn.addr_family == AF_INET) -    { -      ret = IPV4_ADDR_CMP (&a->vn.addr.v4, &b->vn.addr.v4); -      if (ret != 0) -        return ret; -    } -  else if (a->vn.addr_family == AF_INET6) -    { -      ret = IPV6_ADDR_CMP (&a->vn.addr.v6, &b->vn.addr.v6); -      if (ret == 0) -        { -          return ret; -        } -    } -  else -    { -      assert (0); -    } -  return 0; +	struct nve_addr *a = (struct nve_addr *)k1; +	struct nve_addr *b = (struct nve_addr *)k2; +	int ret = 0; + +	if (!a || !b) { +		return (a - b); +	} +	if (a->un.addr_family != b->un.addr_family) { +		return (a->un.addr_family - b->un.addr_family); +	} +	if (a->vn.addr_family != b->vn.addr_family) { +		return (a->vn.addr_family - b->vn.addr_family); +	} +	if (a->un.addr_family == AF_INET) { +		ret = IPV4_ADDR_CMP(&a->un.addr.v4, &b->un.addr.v4); +		if (ret != 0) { +			return ret; +		} +	} else if (a->un.addr_family == AF_INET6) { +		ret = IPV6_ADDR_CMP(&a->un.addr.v6, &b->un.addr.v6); +		if (ret != 0) { +			return ret; +		} +	} else { +		assert(0); +	} +	if (a->vn.addr_family == AF_INET) { +		ret = IPV4_ADDR_CMP(&a->vn.addr.v4, &b->vn.addr.v4); +		if (ret != 0) +			return ret; +	} else if (a->vn.addr_family == AF_INET6) { +		ret = IPV6_ADDR_CMP(&a->vn.addr.v6, &b->vn.addr.v6); +		if (ret == 0) { +			return ret; +		} +	} else { +		assert(0); +	} +	return 0;  } -static int -parse_deleter_args ( -  struct vty			    *vty, -  struct bgp                        *bgp, -  const char                        *arg_prefix, -  const char                        *arg_vn, -  const char                        *arg_un, -  const char                        *arg_l2addr, -  const char                        *arg_vni, -  const char                        *arg_rd, -  struct rfapi_nve_group_cfg        *arg_rfg, -  struct rfapi_local_reg_delete_arg *rcdarg) +static int parse_deleter_args(struct vty *vty, struct bgp *bgp, +			      const char *arg_prefix, const char *arg_vn, +			      const char *arg_un, const char *arg_l2addr, +			      const char *arg_vni, const char *arg_rd, +			      struct rfapi_nve_group_cfg *arg_rfg, +			      struct rfapi_local_reg_delete_arg *rcdarg)  { -  int rc = CMD_WARNING; - -  memset (rcdarg, 0, sizeof (struct rfapi_local_reg_delete_arg)); - -  rcdarg->vty = vty; -  if (bgp == NULL) -    bgp = bgp_get_default(); -  rcdarg->bgp = bgp; -  rcdarg->rfg = arg_rfg;        /* may be NULL */ - -  if (arg_vn && strcmp (arg_vn, "*")) -    { -      if ((rc = rfapiCliGetRfapiIpAddr (vty, arg_vn, &rcdarg->vn_address))) -        return rc; -    } -  if (arg_un && strcmp (arg_un, "*")) -    { -      if ((rc = rfapiCliGetRfapiIpAddr (vty, arg_un, &rcdarg->un_address))) -        return rc; -    } -  if (arg_prefix && strcmp (arg_prefix, "*")) -    { - -      if (!str2prefix (arg_prefix, &rcdarg->prefix)) -        { -          vty_out (vty, "Malformed prefix \"%s\"\n", arg_prefix); -          return rc; -        } -    } - -  if (arg_l2addr) -    { -      if (!arg_vni) -        { -          vty_out (vty, "Missing VNI\n"); -          return rc; -        } -      if (strcmp (arg_l2addr, "*")) -        { -          if ((rc = rfapiStr2EthAddr (arg_l2addr, &rcdarg->l2o.o.macaddr))) -            { -              vty_out (vty, "Malformed L2 Address \"%s\"\n", -                       arg_l2addr); -              return rc; -            } -          rcdarg->l2o.flags |= RFAPI_L2O_MACADDR; -        } -      if (strcmp (arg_vni, "*")) -        { -          rcdarg->l2o.o.logical_net_id = strtoul(arg_vni, NULL, 10); -          rcdarg->l2o.flags |= RFAPI_L2O_LNI; -        } -    } -  if (arg_rd) -    { -      if (!str2prefix_rd (arg_rd, &rcdarg->rd)) -        { -          vty_out (vty, "Malformed RD \"%s\"\n", -                   arg_rd); -          return rc; -        } -    } - -  return CMD_SUCCESS; +	int rc = CMD_WARNING; + +	memset(rcdarg, 0, sizeof(struct rfapi_local_reg_delete_arg)); + +	rcdarg->vty = vty; +	if (bgp == NULL) +		bgp = bgp_get_default(); +	rcdarg->bgp = bgp; +	rcdarg->rfg = arg_rfg; /* may be NULL */ + +	if (arg_vn && strcmp(arg_vn, "*")) { +		if ((rc = rfapiCliGetRfapiIpAddr(vty, arg_vn, +						 &rcdarg->vn_address))) +			return rc; +	} +	if (arg_un && strcmp(arg_un, "*")) { +		if ((rc = rfapiCliGetRfapiIpAddr(vty, arg_un, +						 &rcdarg->un_address))) +			return rc; +	} +	if (arg_prefix && strcmp(arg_prefix, "*")) { + +		if (!str2prefix(arg_prefix, &rcdarg->prefix)) { +			vty_out(vty, "Malformed prefix \"%s\"\n", arg_prefix); +			return rc; +		} +	} + +	if (arg_l2addr) { +		if (!arg_vni) { +			vty_out(vty, "Missing VNI\n"); +			return rc; +		} +		if (strcmp(arg_l2addr, "*")) { +			if ((rc = rfapiStr2EthAddr(arg_l2addr, +						   &rcdarg->l2o.o.macaddr))) { +				vty_out(vty, "Malformed L2 Address \"%s\"\n", +					arg_l2addr); +				return rc; +			} +			rcdarg->l2o.flags |= RFAPI_L2O_MACADDR; +		} +		if (strcmp(arg_vni, "*")) { +			rcdarg->l2o.o.logical_net_id = +				strtoul(arg_vni, NULL, 10); +			rcdarg->l2o.flags |= RFAPI_L2O_LNI; +		} +	} +	if (arg_rd) { +		if (!str2prefix_rd(arg_rd, &rcdarg->rd)) { +			vty_out(vty, "Malformed RD \"%s\"\n", arg_rd); +			return rc; +		} +	} + +	return CMD_SUCCESS;  }  static int -parse_deleter_tokens ( -  struct vty				*vty, -  struct bgp                            *bgp, -  struct cmd_token			*carg_prefix, -  struct cmd_token			*carg_vn, -  struct cmd_token			*carg_un, -  struct cmd_token			*carg_l2addr, -  struct cmd_token			*carg_vni, -  struct cmd_token			*carg_rd, -  struct rfapi_nve_group_cfg            *arg_rfg, -  struct rfapi_local_reg_delete_arg	*rcdarg) +parse_deleter_tokens(struct vty *vty, struct bgp *bgp, +		     struct cmd_token *carg_prefix, struct cmd_token *carg_vn, +		     struct cmd_token *carg_un, struct cmd_token *carg_l2addr, +		     struct cmd_token *carg_vni, struct cmd_token *carg_rd, +		     struct rfapi_nve_group_cfg *arg_rfg, +		     struct rfapi_local_reg_delete_arg *rcdarg)  { -  const char *arg_prefix = carg_prefix ? carg_prefix->arg : NULL; -  const char *arg_vn     = carg_vn ? carg_vn->arg : NULL; -  const char *arg_un     = carg_un ? carg_un->arg : NULL; -  const char *arg_l2addr = carg_l2addr ? carg_l2addr->arg : NULL; -  const char *arg_vni    = carg_vni ? carg_vni->arg : NULL; -  const char *arg_rd     = carg_rd ? carg_rd->arg : NULL; -  return parse_deleter_args (vty, bgp,arg_prefix, arg_vn, arg_un, -                             arg_l2addr, arg_vni, arg_rd, -                             arg_rfg, rcdarg); +	const char *arg_prefix = carg_prefix ? carg_prefix->arg : NULL; +	const char *arg_vn = carg_vn ? carg_vn->arg : NULL; +	const char *arg_un = carg_un ? carg_un->arg : NULL; +	const char *arg_l2addr = carg_l2addr ? carg_l2addr->arg : NULL; +	const char *arg_vni = carg_vni ? carg_vni->arg : NULL; +	const char *arg_rd = carg_rd ? carg_rd->arg : NULL; +	return parse_deleter_args(vty, bgp, arg_prefix, arg_vn, arg_un, +				  arg_l2addr, arg_vni, arg_rd, arg_rfg, rcdarg);  } -static void -record_nve_in_cda_list ( -  struct rfapi_local_reg_delete_arg	*cda, -  struct rfapi_ip_addr			*un_address, -  struct rfapi_ip_addr			*vn_address, -  struct rfapi_descriptor		*rfd) +static void record_nve_in_cda_list(struct rfapi_local_reg_delete_arg *cda, +				   struct rfapi_ip_addr *un_address, +				   struct rfapi_ip_addr *vn_address, +				   struct rfapi_descriptor *rfd)  { -  struct nve_addr ha; -  struct nve_addr *hap; - -    memset (&ha, 0, sizeof (ha)); -    ha.un = *un_address; -    ha.vn = *vn_address; -    ha.rfd = rfd; - -  if (!cda->nves) -      cda->nves = skiplist_new (0, nve_addr_cmp, nve_addr_free); - -  if (skiplist_search (cda->nves, &ha, (void *) &hap)) -    { -      hap = XCALLOC (MTYPE_RFAPI_NVE_ADDR, sizeof (struct nve_addr)); -        assert (hap); -        ha.cda = cda; -      * hap = ha; -        skiplist_insert (cda->nves, hap, hap); -    } +	struct nve_addr ha; +	struct nve_addr *hap; + +	memset(&ha, 0, sizeof(ha)); +	ha.un = *un_address; +	ha.vn = *vn_address; +	ha.rfd = rfd; + +	if (!cda->nves) +		cda->nves = skiplist_new(0, nve_addr_cmp, nve_addr_free); + +	if (skiplist_search(cda->nves, &ha, (void *)&hap)) { +		hap = XCALLOC(MTYPE_RFAPI_NVE_ADDR, sizeof(struct nve_addr)); +		assert(hap); +		ha.cda = cda; +		*hap = ha; +		skiplist_insert(cda->nves, hap, hap); +	}  } -static void -clear_vnc_responses (struct rfapi_local_reg_delete_arg *cda) +static void clear_vnc_responses(struct rfapi_local_reg_delete_arg *cda)  { -  struct rfapi *h; -  struct rfapi_descriptor *rfd; -  int query_count = 0; -  struct listnode *node; -  struct bgp *bgp_default = bgp_get_default (); - -  if (cda->vn_address.addr_family && cda->un_address.addr_family) -    { -      /* -       * Single nve case -       */ -      if (rfapi_find_rfd -          (bgp_default, &cda->vn_address, &cda->un_address, &rfd)) -        return; - -      rfapiRibClear (rfd); -      rfapi_query_done_all (rfd, &query_count); -      cda->query_count += query_count; - -      /* -       * Track unique nves seen -       */ -      record_nve_in_cda_list (cda, &rfd->un_addr, &rfd->vn_addr, rfd); -      return; -    } - -  /* -   * wildcard case -   */ - -  if (!bgp_default) -      return;                   /* ENXIO */ - -  h = bgp_default->rfapi; - -  if (!h) -    return;                     /* ENXIO */ - -  for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd)) -    { -      /* -       * match un, vn addresses of NVEs -       */ -      if (cda->un_address.addr_family && -          rfapi_ip_addr_cmp (&cda->un_address, &rfd->un_addr)) -        { -          continue; -        } -      if (cda->vn_address.addr_family && -          rfapi_ip_addr_cmp (&cda->vn_address, &rfd->vn_addr)) -        { -          continue; -        } - -      rfapiRibClear (rfd); - -      rfapi_query_done_all (rfd, &query_count); -      cda->query_count += query_count; - -      /* -       * Track unique nves seen -       */ -      record_nve_in_cda_list (cda, &rfd->un_addr, &rfd->vn_addr, rfd); -    } +	struct rfapi *h; +	struct rfapi_descriptor *rfd; +	int query_count = 0; +	struct listnode *node; +	struct bgp *bgp_default = bgp_get_default(); + +	if (cda->vn_address.addr_family && cda->un_address.addr_family) { +		/* +		 * Single nve case +		 */ +		if (rfapi_find_rfd(bgp_default, &cda->vn_address, +				   &cda->un_address, &rfd)) +			return; + +		rfapiRibClear(rfd); +		rfapi_query_done_all(rfd, &query_count); +		cda->query_count += query_count; + +		/* +		 * Track unique nves seen +		 */ +		record_nve_in_cda_list(cda, &rfd->un_addr, &rfd->vn_addr, rfd); +		return; +	} + +	/* +	 * wildcard case +	 */ + +	if (!bgp_default) +		return; /* ENXIO */ + +	h = bgp_default->rfapi; + +	if (!h) +		return; /* ENXIO */ + +	for (ALL_LIST_ELEMENTS_RO(&h->descriptors, node, rfd)) { +		/* +		 * match un, vn addresses of NVEs +		 */ +		if (cda->un_address.addr_family +		    && rfapi_ip_addr_cmp(&cda->un_address, &rfd->un_addr)) { +			continue; +		} +		if (cda->vn_address.addr_family +		    && rfapi_ip_addr_cmp(&cda->vn_address, &rfd->vn_addr)) { +			continue; +		} + +		rfapiRibClear(rfd); + +		rfapi_query_done_all(rfd, &query_count); +		cda->query_count += query_count; + +		/* +		 * Track unique nves seen +		 */ +		record_nve_in_cda_list(cda, &rfd->un_addr, &rfd->vn_addr, rfd); +	}  }  /*   * TBD need to count deleted prefixes and nves?   *   * ENXIO	BGP or VNC not configured - */  -static int -rfapiDeleteLocalPrefixesByRFD (struct rfapi_local_reg_delete_arg *cda, -                               struct rfapi_descriptor *rfd) + */ +static int rfapiDeleteLocalPrefixesByRFD(struct rfapi_local_reg_delete_arg *cda, +					 struct rfapi_descriptor *rfd)  { -  struct rfapi_ip_addr *pUn;     /* NULL = wildcard */ -  struct rfapi_ip_addr *pVn;     /* NULL = wildcard */ -  struct prefix        *pPrefix; /* NULL = wildcard */ -  struct prefix_rd     *pPrd;    /* NULL = wildcard */ +	struct rfapi_ip_addr *pUn; /* NULL = wildcard */ +	struct rfapi_ip_addr *pVn; /* NULL = wildcard */ +	struct prefix *pPrefix;    /* NULL = wildcard */ +	struct prefix_rd *pPrd;    /* NULL = wildcard */ -  struct rfapi_ip_prefix rprefix; -  struct rfapi_next_hop_entry *head = NULL; -  struct rfapi_next_hop_entry *tail = NULL; +	struct rfapi_ip_prefix rprefix; +	struct rfapi_next_hop_entry *head = NULL; +	struct rfapi_next_hop_entry *tail = NULL;  #if DEBUG_L2_EXTRA -  vnc_zlog_debug_verbose ("%s: entry", __func__); +	vnc_zlog_debug_verbose("%s: entry", __func__);  #endif -  pUn = (cda->un_address.addr_family ? &cda->un_address : NULL); -  pVn = (cda->vn_address.addr_family ? &cda->vn_address : NULL); -  pPrefix = (cda->prefix.family ? &cda->prefix : NULL); -  pPrd = (cda->rd.prefixlen == 64 ? &cda->rd : NULL); - -  if (pPrefix) -    { -      rfapiQprefix2Rprefix (pPrefix, &rprefix); -    } - -  do                            /* to preserve old code structure */ -    { -      struct rfapi *h=cda->bgp->rfapi;; -      struct rfapi_adb *adb; -      int rc; -      int deleted_from_this_nve; -      struct nve_addr ha; -      struct nve_addr *hap; +	pUn = (cda->un_address.addr_family ? &cda->un_address : NULL); +	pVn = (cda->vn_address.addr_family ? &cda->vn_address : NULL); +	pPrefix = (cda->prefix.family ? &cda->prefix : NULL); +	pPrd = (cda->rd.prefixlen == 64 ? &cda->rd : NULL); + +	if (pPrefix) { +		rfapiQprefix2Rprefix(pPrefix, &rprefix); +	} + +	do /* to preserve old code structure */ +	{ +		struct rfapi *h = cda->bgp->rfapi; +		; +		struct rfapi_adb *adb; +		int rc; +		int deleted_from_this_nve; +		struct nve_addr ha; +		struct nve_addr *hap;  #if DEBUG_L2_EXTRA -      vnc_zlog_debug_verbose ("%s: rfd=%p", __func__, rfd); +		vnc_zlog_debug_verbose("%s: rfd=%p", __func__, rfd);  #endif -      /* -       * match un, vn addresses of NVEs -       */ -      if (pUn && (rfapi_ip_addr_cmp (pUn, &rfd->un_addr))) -        continue; -      if (pVn && (rfapi_ip_addr_cmp (pVn, &rfd->vn_addr))) -        continue; +		/* +		 * match un, vn addresses of NVEs +		 */ +		if (pUn && (rfapi_ip_addr_cmp(pUn, &rfd->un_addr))) +			continue; +		if (pVn && (rfapi_ip_addr_cmp(pVn, &rfd->vn_addr))) +			continue;  #if DEBUG_L2_EXTRA -      vnc_zlog_debug_verbose ("%s: un, vn match", __func__); +		vnc_zlog_debug_verbose("%s: un, vn match", __func__);  #endif -      /* -       * match prefix -       */ - -      deleted_from_this_nve = 0; - -      { -        struct skiplist *sl; -        struct rfapi_ip_prefix rp; -        void *cursor; -        struct list *adb_delete_list; - -        /* -         * The advertisements are stored in a skiplist. Withdrawing -         * the registration deletes the advertisement from the -         * skiplist, which we can't do while iterating over that -         * same skiplist using the current skiplist API. -         * -         * Strategy: iterate over the skiplist and build another -         * list containing only the matching ADBs. Then delete -         * _everything_ in that second list (which can be done -         * using either skiplists or quagga linklists). -         */ -        adb_delete_list = list_new (); - -        /* -         * Advertised IP prefixes (not 0/32 or 0/128) -         */ -        sl = rfd->advertised.ipN_by_prefix; - -        for (cursor = NULL, -             rc = skiplist_next (sl, NULL, (void **) &adb, &cursor); -             !rc; rc = skiplist_next (sl, NULL, (void **) &adb, &cursor)) -          { - -            if (pPrefix) -              { -                if (!prefix_same (pPrefix, &adb->u.s.prefix_ip)) -                  { +		/* +		 * match prefix +		 */ + +		deleted_from_this_nve = 0; + +		{ +			struct skiplist *sl; +			struct rfapi_ip_prefix rp; +			void *cursor; +			struct list *adb_delete_list; + +			/* +			 * The advertisements are stored in a skiplist. +			 * Withdrawing +			 * the registration deletes the advertisement from the +			 * skiplist, which we can't do while iterating over that +			 * same skiplist using the current skiplist API. +			 * +			 * Strategy: iterate over the skiplist and build another +			 * list containing only the matching ADBs. Then delete +			 * _everything_ in that second list (which can be done +			 * using either skiplists or quagga linklists). +			 */ +			adb_delete_list = list_new(); + +			/* +			 * Advertised IP prefixes (not 0/32 or 0/128) +			 */ +			sl = rfd->advertised.ipN_by_prefix; + +			for (cursor = NULL, +			    rc = skiplist_next(sl, NULL, (void **)&adb, +					       &cursor); +			     !rc; rc = skiplist_next(sl, NULL, (void **)&adb, +						     &cursor)) { + +				if (pPrefix) { +					if (!prefix_same(pPrefix, +							 &adb->u.s.prefix_ip)) {  #if DEBUG_L2_EXTRA -                    vnc_zlog_debug_verbose ("%s: adb=%p, prefix doesn't match, skipping", -                                __func__, adb); +						vnc_zlog_debug_verbose( +							"%s: adb=%p, prefix doesn't match, skipping", +							__func__, adb);  #endif -                    continue; -                  } -              } -            if (pPrd)  -              { -                if (memcmp(pPrd->val, adb->u.s.prd.val, 8) != 0) -                  { +						continue; +					} +				} +				if (pPrd) { +					if (memcmp(pPrd->val, adb->u.s.prd.val, +						   8) +					    != 0) {  #if DEBUG_L2_EXTRA -                    vnc_zlog_debug_verbose ("%s: adb=%p, RD doesn't match, skipping", -                                __func__, adb); +						vnc_zlog_debug_verbose( +							"%s: adb=%p, RD doesn't match, skipping", +							__func__, adb);  #endif -                    continue; -                  } -              } -            if (CHECK_FLAG (cda->l2o.flags, RFAPI_L2O_MACADDR)) -              { -                if (memcmp -                    (cda->l2o.o.macaddr.octet, -                     adb->u.s.prefix_eth.u.prefix_eth.octet, ETHER_ADDR_LEN)) -                  { +						continue; +					} +				} +				if (CHECK_FLAG(cda->l2o.flags, +					       RFAPI_L2O_MACADDR)) { +					if (memcmp(cda->l2o.o.macaddr.octet, +						   adb->u.s.prefix_eth.u +							   .prefix_eth.octet, +						   ETHER_ADDR_LEN)) {  #if DEBUG_L2_EXTRA -                    vnc_zlog_debug_verbose ("%s: adb=%p, macaddr doesn't match, skipping", -                                __func__, adb); +						vnc_zlog_debug_verbose( +							"%s: adb=%p, macaddr doesn't match, skipping", +							__func__, adb);  #endif -                    continue; -                  } -              } - -            if (CHECK_FLAG (cda->l2o.flags, RFAPI_L2O_LNI)) -              { -                if (cda->l2o.o.logical_net_id != adb->l2o.logical_net_id) -                  { +						continue; +					} +				} + +				if (CHECK_FLAG(cda->l2o.flags, RFAPI_L2O_LNI)) { +					if (cda->l2o.o.logical_net_id +					    != adb->l2o.logical_net_id) {  #if DEBUG_L2_EXTRA -                    vnc_zlog_debug_verbose ("%s: adb=%p, LNI doesn't match, skipping", -                                __func__, adb); +						vnc_zlog_debug_verbose( +							"%s: adb=%p, LNI doesn't match, skipping", +							__func__, adb);  #endif -                    continue; -                  } -              } +						continue; +					} +				}  #if DEBUG_L2_EXTRA -            vnc_zlog_debug_verbose ("%s: ipN adding adb %p to delete list", __func__, -                        adb); +				vnc_zlog_debug_verbose( +					"%s: ipN adding adb %p to delete list", +					__func__, adb);  #endif -            listnode_add (adb_delete_list, adb); -          } - -        struct listnode *node; - -        for (ALL_LIST_ELEMENTS_RO (adb_delete_list, node, adb)) -          { -            int this_advertisement_prefix_count; -            struct rfapi_vn_option optary[3]; -            struct rfapi_vn_option *opt = NULL; -            int                     cur_opt = 0; - -            this_advertisement_prefix_count = 1; - -            rfapiQprefix2Rprefix (&adb->u.s.prefix_ip, &rp); - -            memset (optary, 0, sizeof (optary)); - -            /* if mac addr present in advert,  make l2o vn option */ -            if (adb->u.s.prefix_eth.family == AF_ETHERNET) -              { -                if (opt != NULL) -                  opt->next = &optary[cur_opt]; -                opt = &optary[cur_opt++]; -                opt->type = RFAPI_VN_OPTION_TYPE_L2ADDR; -                opt->v.l2addr.macaddr = adb->u.s.prefix_eth.u.prefix_eth; -                ++this_advertisement_prefix_count; -              } -            /* -             * use saved RD value instead of trying to invert -             * complex RD computation in rfapi_register() -             */ -            if (opt != NULL) -              opt->next = &optary[cur_opt]; -            opt = &optary[cur_opt++]; -            opt->type = RFAPI_VN_OPTION_TYPE_INTERNAL_RD; -            opt->v.internal_rd = adb->u.s.prd; +				listnode_add(adb_delete_list, adb); +			} + +			struct listnode *node; + +			for (ALL_LIST_ELEMENTS_RO(adb_delete_list, node, adb)) { +				int this_advertisement_prefix_count; +				struct rfapi_vn_option optary[3]; +				struct rfapi_vn_option *opt = NULL; +				int cur_opt = 0; + +				this_advertisement_prefix_count = 1; + +				rfapiQprefix2Rprefix(&adb->u.s.prefix_ip, &rp); + +				memset(optary, 0, sizeof(optary)); + +				/* if mac addr present in advert,  make l2o vn +				 * option */ +				if (adb->u.s.prefix_eth.family == AF_ETHERNET) { +					if (opt != NULL) +						opt->next = &optary[cur_opt]; +					opt = &optary[cur_opt++]; +					opt->type = RFAPI_VN_OPTION_TYPE_L2ADDR; +					opt->v.l2addr.macaddr = +						adb->u.s.prefix_eth.u +							.prefix_eth; +					++this_advertisement_prefix_count; +				} +				/* +				 * use saved RD value instead of trying to +				 * invert +				 * complex RD computation in rfapi_register() +				 */ +				if (opt != NULL) +					opt->next = &optary[cur_opt]; +				opt = &optary[cur_opt++]; +				opt->type = RFAPI_VN_OPTION_TYPE_INTERNAL_RD; +				opt->v.internal_rd = adb->u.s.prd;  #if DEBUG_L2_EXTRA -            vnc_zlog_debug_verbose ("%s: ipN killing reg from adb %p ", __func__, adb); +				vnc_zlog_debug_verbose( +					"%s: ipN killing reg from adb %p ", +					__func__, adb);  #endif -            rc = rfapi_register (rfd, &rp, 0, NULL,  -                                 (cur_opt ? optary : NULL), RFAPI_REGISTER_KILL); -            if (!rc) -              { -                cda->pfx_count += this_advertisement_prefix_count; -                cda->reg_count += 1; -                deleted_from_this_nve = 1; -              } -            if (h->rfp_methods.local_cb) -              { -                rfapiAddDeleteLocalRfpPrefix (&rfd->un_addr, &rfd->vn_addr, -                                              &rp, 0, 0, NULL, &head, &tail); -              } -          } -        list_delete_all_node (adb_delete_list); - -        if (!(pPrefix && !RFAPI_0_PREFIX (pPrefix))) -          { -            void *cursor; - -            /* -             * Caller didn't specify a prefix, or specified (0/32 or 0/128) -             */ - -            /* -             * Advertised 0/32 and 0/128 (indexed by ethernet address) -             */ -            sl = rfd->advertised.ip0_by_ether; - -            for (cursor = NULL, -                 rc = skiplist_next (sl, NULL, (void **) &adb, &cursor); -                 !rc; rc = skiplist_next (sl, NULL, (void **) &adb, &cursor)) -              { - -                if (CHECK_FLAG (cda->l2o.flags, RFAPI_L2O_MACADDR)) -                  { -                    if (memcmp (cda->l2o.o.macaddr.octet, -                                adb->u.s.prefix_eth.u.prefix_eth.octet, -                                ETHER_ADDR_LEN)) -                      { - -                        continue; -                      } -                  } -                if (CHECK_FLAG (cda->l2o.flags, RFAPI_L2O_LNI)) -                  { -                    if (cda->l2o.o.logical_net_id != adb->l2o.logical_net_id) -                      { -                        continue; -                      } -                  } +				rc = rfapi_register(rfd, &rp, 0, NULL, +						    (cur_opt ? optary : NULL), +						    RFAPI_REGISTER_KILL); +				if (!rc) { +					cda->pfx_count += +						this_advertisement_prefix_count; +					cda->reg_count += 1; +					deleted_from_this_nve = 1; +				} +				if (h->rfp_methods.local_cb) { +					rfapiAddDeleteLocalRfpPrefix( +						&rfd->un_addr, &rfd->vn_addr, +						&rp, 0, 0, NULL, &head, &tail); +				} +			} +			list_delete_all_node(adb_delete_list); + +			if (!(pPrefix && !RFAPI_0_PREFIX(pPrefix))) { +				void *cursor; + +				/* +				 * Caller didn't specify a prefix, or specified +				 * (0/32 or 0/128) +				 */ + +				/* +				 * Advertised 0/32 and 0/128 (indexed by +				 * ethernet address) +				 */ +				sl = rfd->advertised.ip0_by_ether; + +				for (cursor = NULL, +				    rc = skiplist_next(sl, NULL, (void **)&adb, +						       &cursor); +				     !rc; +				     rc = skiplist_next(sl, NULL, (void **)&adb, +							&cursor)) { + +					if (CHECK_FLAG(cda->l2o.flags, +						       RFAPI_L2O_MACADDR)) { +						if (memcmp(cda->l2o.o.macaddr +								   .octet, +							   adb->u.s.prefix_eth.u +								   .prefix_eth +								   .octet, +							   ETHER_ADDR_LEN)) { + +							continue; +						} +					} +					if (CHECK_FLAG(cda->l2o.flags, +						       RFAPI_L2O_LNI)) { +						if (cda->l2o.o.logical_net_id +						    != adb->l2o.logical_net_id) { +							continue; +						} +					}  #if DEBUG_L2_EXTRA -                vnc_zlog_debug_verbose ("%s: ip0 adding adb %p to delete list", -                            __func__, adb); +					vnc_zlog_debug_verbose( +						"%s: ip0 adding adb %p to delete list", +						__func__, adb);  #endif -                listnode_add (adb_delete_list, adb); -              } +					listnode_add(adb_delete_list, adb); +				} -            for (ALL_LIST_ELEMENTS_RO (adb_delete_list, node, adb)) -              { +				for (ALL_LIST_ELEMENTS_RO(adb_delete_list, node, +							  adb)) { -                struct rfapi_vn_option vn; +					struct rfapi_vn_option vn; -                rfapiQprefix2Rprefix (&adb->u.s.prefix_ip, &rp); +					rfapiQprefix2Rprefix( +						&adb->u.s.prefix_ip, &rp); -                memset (&vn, 0, sizeof (vn)); -                vn.type = RFAPI_VN_OPTION_TYPE_L2ADDR; -                vn.v.l2addr = adb->l2o; +					memset(&vn, 0, sizeof(vn)); +					vn.type = RFAPI_VN_OPTION_TYPE_L2ADDR; +					vn.v.l2addr = adb->l2o;  #if DEBUG_L2_EXTRA -                vnc_zlog_debug_verbose ("%s: ip0 killing reg from adb %p ", -                            __func__, adb); +					vnc_zlog_debug_verbose( +						"%s: ip0 killing reg from adb %p ", +						__func__, adb);  #endif -                rc = rfapi_register (rfd, &rp, 0, NULL, &vn, -                                     RFAPI_REGISTER_KILL); -                if (!rc) -                  { -                    cda->pfx_count += 1; -                    cda->reg_count += 1; -                    deleted_from_this_nve = 1; -                  } -                if (h->rfp_methods.local_cb) -                  { -                    struct rfapi_vn_option *vn_opt_new; - -                    vn_opt_new = rfapi_vn_options_dup (&vn); -                    rfapiAddDeleteLocalRfpPrefix (&rfd->un_addr, -                                                  &rfd->vn_addr, &rp, 0, 0, -                                                  vn_opt_new, &head, &tail); -                  } -              } -            list_delete_all_node (adb_delete_list); -          } -        list_delete (adb_delete_list); -      } - - -      if (head) -        {                       /* should not be set if (NULL == rfapi_cfg->local_cb) */ -          h->flags |= RFAPI_INCALLBACK; -          (*h->rfp_methods.local_cb) (head, rfd->cookie); -          h->flags &= ~RFAPI_INCALLBACK; -          head = tail = NULL; -        } - -      if (deleted_from_this_nve) -        { -          /* -           * track unique NVEs seen -           */ -          memset (&ha, 0, sizeof (ha)); -          ha.un = rfd->un_addr; -          ha.vn = rfd->vn_addr; - -          if (!cda->nves) -            cda->nves = skiplist_new (0, nve_addr_cmp, nve_addr_free); -          if (skiplist_search (cda->nves, &ha, (void **) &hap)) -            { -              hap = XCALLOC (MTYPE_RFAPI_NVE_ADDR, sizeof (struct nve_addr)); -              assert (hap); -              ha.cda = cda; -              *hap = ha; -              skiplist_insert (cda->nves, hap, hap); -            } -        } -    } while (0);                /*  to preserve old code structure */ - -  return 0; +					rc = rfapi_register( +						rfd, &rp, 0, NULL, &vn, +						RFAPI_REGISTER_KILL); +					if (!rc) { +						cda->pfx_count += 1; +						cda->reg_count += 1; +						deleted_from_this_nve = 1; +					} +					if (h->rfp_methods.local_cb) { +						struct rfapi_vn_option +							*vn_opt_new; + +						vn_opt_new = +							rfapi_vn_options_dup( +								&vn); +						rfapiAddDeleteLocalRfpPrefix( +							&rfd->un_addr, +							&rfd->vn_addr, &rp, 0, +							0, vn_opt_new, &head, +							&tail); +					} +				} +				list_delete_all_node(adb_delete_list); +			} +			list_delete(adb_delete_list); +		} + + +		if (head) { /* should not be set if (NULL == +			       rfapi_cfg->local_cb) */ +			h->flags |= RFAPI_INCALLBACK; +			(*h->rfp_methods.local_cb)(head, rfd->cookie); +			h->flags &= ~RFAPI_INCALLBACK; +			head = tail = NULL; +		} + +		if (deleted_from_this_nve) { +			/* +			 * track unique NVEs seen +			 */ +			memset(&ha, 0, sizeof(ha)); +			ha.un = rfd->un_addr; +			ha.vn = rfd->vn_addr; + +			if (!cda->nves) +				cda->nves = skiplist_new(0, nve_addr_cmp, +							 nve_addr_free); +			if (skiplist_search(cda->nves, &ha, (void **)&hap)) { +				hap = XCALLOC(MTYPE_RFAPI_NVE_ADDR, +					      sizeof(struct nve_addr)); +				assert(hap); +				ha.cda = cda; +				*hap = ha; +				skiplist_insert(cda->nves, hap, hap); +			} +		} +	} while (0); /*  to preserve old code structure */ + +	return 0;  } -static int -rfapiDeleteLocalPrefixes (struct rfapi_local_reg_delete_arg *cda) +static int rfapiDeleteLocalPrefixes(struct rfapi_local_reg_delete_arg *cda)  { -  int rc = 0; - -  if (cda->rfg) -    { -      if (cda->rfg->rfd)        /* if not open, nothing to delete */ -        rc = rfapiDeleteLocalPrefixesByRFD (cda, cda->rfg->rfd); -    } -  else -    { -      struct bgp *bgp = cda->bgp; -      struct rfapi *h; -      struct rfapi_cfg *rfapi_cfg; - -      struct listnode *node; -      struct rfapi_descriptor *rfd; -      if (!bgp) -        return ENXIO; -      h = bgp->rfapi; -      rfapi_cfg = bgp->rfapi_cfg; -      if (!h || !rfapi_cfg) -        return ENXIO; -      vnc_zlog_debug_verbose ("%s: starting descriptor loop", __func__); -      for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd)) -        { -          rc = rfapiDeleteLocalPrefixesByRFD (cda, rfd); -        } -    } -  return rc; +	int rc = 0; + +	if (cda->rfg) { +		if (cda->rfg->rfd) /* if not open, nothing to delete */ +			rc = rfapiDeleteLocalPrefixesByRFD(cda, cda->rfg->rfd); +	} else { +		struct bgp *bgp = cda->bgp; +		struct rfapi *h; +		struct rfapi_cfg *rfapi_cfg; + +		struct listnode *node; +		struct rfapi_descriptor *rfd; +		if (!bgp) +			return ENXIO; +		h = bgp->rfapi; +		rfapi_cfg = bgp->rfapi_cfg; +		if (!h || !rfapi_cfg) +			return ENXIO; +		vnc_zlog_debug_verbose("%s: starting descriptor loop", +				       __func__); +		for (ALL_LIST_ELEMENTS_RO(&h->descriptors, node, rfd)) { +			rc = rfapiDeleteLocalPrefixesByRFD(cda, rfd); +		} +	} +	return rc;  }  /* @@ -3643,108 +3345,98 @@ rfapiDeleteLocalPrefixes (struct rfapi_local_reg_delete_arg *cda)   *   * Deletes local and remote prefixes that match   */ -static void -clear_vnc_prefix (struct rfapi_local_reg_delete_arg *cda) +static void clear_vnc_prefix(struct rfapi_local_reg_delete_arg *cda)  { -  struct prefix pfx_un; -  struct prefix pfx_vn; - -  struct prefix *pUN = NULL; -  struct prefix *pVN = NULL; -  struct prefix *pPrefix = NULL; - -  struct rfapi_import_table *it = NULL; - -  /* -   * Delete matching remote prefixes in holddown -   */ -  if (cda->vn_address.addr_family) -    { -      if (!rfapiRaddr2Qprefix (&cda->vn_address, &pfx_vn)) -        pVN = &pfx_vn; -    } -  if (cda->un_address.addr_family) -    { -      if (!rfapiRaddr2Qprefix (&cda->un_address, &pfx_un)) -        pUN = &pfx_un; -    } -  if (cda->prefix.family) -    { -      pPrefix = &cda->prefix; -    } -  if (cda->rfg) -    { -      it = cda->rfg->rfapi_import_table; -    } -  rfapiDeleteRemotePrefixes (pUN, pVN, pPrefix, it, -                             0, 1, &cda->remote_active_pfx_count, -                             &cda->remote_active_nve_count, -                             &cda->remote_holddown_pfx_count, -                             &cda->remote_holddown_nve_count); - -  /* -   * Now do local prefixes -   */ -  rfapiDeleteLocalPrefixes (cda); +	struct prefix pfx_un; +	struct prefix pfx_vn; + +	struct prefix *pUN = NULL; +	struct prefix *pVN = NULL; +	struct prefix *pPrefix = NULL; + +	struct rfapi_import_table *it = NULL; + +	/* +	 * Delete matching remote prefixes in holddown +	 */ +	if (cda->vn_address.addr_family) { +		if (!rfapiRaddr2Qprefix(&cda->vn_address, &pfx_vn)) +			pVN = &pfx_vn; +	} +	if (cda->un_address.addr_family) { +		if (!rfapiRaddr2Qprefix(&cda->un_address, &pfx_un)) +			pUN = &pfx_un; +	} +	if (cda->prefix.family) { +		pPrefix = &cda->prefix; +	} +	if (cda->rfg) { +		it = cda->rfg->rfapi_import_table; +	} +	rfapiDeleteRemotePrefixes( +		pUN, pVN, pPrefix, it, 0, 1, &cda->remote_active_pfx_count, +		&cda->remote_active_nve_count, &cda->remote_holddown_pfx_count, +		&cda->remote_holddown_nve_count); + +	/* +	 * Now do local prefixes +	 */ +	rfapiDeleteLocalPrefixes(cda);  } -static void -print_cleared_stats (struct rfapi_local_reg_delete_arg *cda) +static void print_cleared_stats(struct rfapi_local_reg_delete_arg *cda)  { -  struct vty *vty = cda->vty;   /* for benefit of VTYNL */ - -  /* Our special element-deleting function counts nves */ -  if (cda->nves) -    { -      skiplist_free (cda->nves); -      cda->nves = NULL; -    } -  if (cda->failed_pfx_count) -      vty_out (vty, "Failed to delete %d prefixes\n", -               cda->failed_pfx_count); - -  /* left as "prefixes" even in single case for ease of machine parsing */ -  vty_out (vty, -           "[Local] Cleared %u registrations, %u prefixes, %u responses from %d NVEs\n", -           cda->reg_count, cda->pfx_count, cda->query_count,cda->nve_count); - -/* - * We don't currently allow deletion of active remote prefixes from - * the command line - */ - -  vty_out (vty, "[Holddown] Cleared %u prefixes from %u NVEs\n", -           cda->remote_holddown_pfx_count,cda->remote_holddown_nve_count); +	struct vty *vty = cda->vty; /* for benefit of VTYNL */ + +	/* Our special element-deleting function counts nves */ +	if (cda->nves) { +		skiplist_free(cda->nves); +		cda->nves = NULL; +	} +	if (cda->failed_pfx_count) +		vty_out(vty, "Failed to delete %d prefixes\n", +			cda->failed_pfx_count); + +	/* left as "prefixes" even in single case for ease of machine parsing */ +	vty_out(vty, +		"[Local] Cleared %u registrations, %u prefixes, %u responses from %d NVEs\n", +		cda->reg_count, cda->pfx_count, cda->query_count, +		cda->nve_count); + +	/* +	 * We don't currently allow deletion of active remote prefixes from +	 * the command line +	 */ + +	vty_out(vty, "[Holddown] Cleared %u prefixes from %u NVEs\n", +		cda->remote_holddown_pfx_count, cda->remote_holddown_nve_count);  } -/*  +/*   * Caller has already deleted registrations and queries for this/these   * NVEs. Now we just have to close their descriptors.   */ -static void -clear_vnc_nve_closer (struct rfapi_local_reg_delete_arg *cda) +static void clear_vnc_nve_closer(struct rfapi_local_reg_delete_arg *cda)  { -  struct skiplist *sl = cda->nves;      /* contains affected NVEs */ -  struct nve_addr *pKey; -  struct nve_addr *pValue; -  void *cursor = NULL; -  int rc; - -  if (!sl) -      return; - -  for (rc = skiplist_next (sl, (void **) &pKey, (void **) &pValue, &cursor); -       !rc; -       rc = skiplist_next (sl, (void **) &pKey, (void **) &pValue, &cursor)) -    { - -      if (pValue->rfd) -        { -          ((struct rfapi_descriptor *) pValue->rfd)->flags |= -            RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY; -          rfapi_close (pValue->rfd); -        } -    } +	struct skiplist *sl = cda->nves; /* contains affected NVEs */ +	struct nve_addr *pKey; +	struct nve_addr *pValue; +	void *cursor = NULL; +	int rc; + +	if (!sl) +		return; + +	for (rc = skiplist_next(sl, (void **)&pKey, (void **)&pValue, &cursor); +	     !rc; rc = skiplist_next(sl, (void **)&pKey, (void **)&pValue, +				     &cursor)) { + +		if (pValue->rfd) { +			((struct rfapi_descriptor *)pValue->rfd)->flags |= +				RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY; +			rfapi_close(pValue->rfd); +		} +	}  }  DEFUN (clear_vnc_nve_all, @@ -3756,21 +3448,22 @@ DEFUN (clear_vnc_nve_all,         "For all NVEs\n")  { -  struct rfapi_local_reg_delete_arg cda; -  int rc; +	struct rfapi_local_reg_delete_arg cda; +	int rc; -  if ((rc = parse_deleter_args (vty, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &cda))) -    return rc; +	if ((rc = parse_deleter_args(vty, NULL, NULL, NULL, NULL, NULL, NULL, +				     NULL, NULL, &cda))) +		return rc; -  cda.vty = vty; +	cda.vty = vty; -  clear_vnc_responses (&cda); -  clear_vnc_prefix (&cda); -  clear_vnc_nve_closer (&cda); +	clear_vnc_responses(&cda); +	clear_vnc_prefix(&cda); +	clear_vnc_nve_closer(&cda); -  print_cleared_stats (&cda); +	print_cleared_stats(&cda); -  return 0; +	return 0;  }  DEFUN (clear_vnc_nve_vn_un, @@ -3788,22 +3481,22 @@ DEFUN (clear_vnc_nve_vn_un,         "UN IPv4 interface address\n"         "UN IPv6 interface address\n")  { -  struct rfapi_local_reg_delete_arg cda; -  int rc; +	struct rfapi_local_reg_delete_arg cda; +	int rc; -  if ((rc = -       parse_deleter_tokens (vty, NULL, NULL, argv[4], argv[6], NULL, NULL, NULL, NULL, &cda))) -    return rc; +	if ((rc = parse_deleter_tokens(vty, NULL, NULL, argv[4], argv[6], NULL, +				       NULL, NULL, NULL, &cda))) +		return rc; -  cda.vty = vty; +	cda.vty = vty; -  clear_vnc_responses (&cda); -  clear_vnc_prefix (&cda); -  clear_vnc_nve_closer (&cda); +	clear_vnc_responses(&cda); +	clear_vnc_prefix(&cda); +	clear_vnc_nve_closer(&cda); -  print_cleared_stats (&cda); +	print_cleared_stats(&cda); -  return 0; +	return 0;  }  DEFUN (clear_vnc_nve_un_vn, @@ -3821,22 +3514,22 @@ DEFUN (clear_vnc_nve_un_vn,         "VN IPv4 interface address\n"         "VN IPv6 interface address\n")  { -  struct rfapi_local_reg_delete_arg cda; -  int rc; +	struct rfapi_local_reg_delete_arg cda; +	int rc; -  if ((rc = -       parse_deleter_tokens (vty, NULL, NULL, argv[6], argv[4], NULL, NULL, NULL, NULL, &cda))) -    return rc; +	if ((rc = parse_deleter_tokens(vty, NULL, NULL, argv[6], argv[4], NULL, +				       NULL, NULL, NULL, &cda))) +		return rc; -  cda.vty = vty; +	cda.vty = vty; -  clear_vnc_responses (&cda); -  clear_vnc_prefix (&cda); -  clear_vnc_nve_closer (&cda); +	clear_vnc_responses(&cda); +	clear_vnc_prefix(&cda); +	clear_vnc_nve_closer(&cda); -  print_cleared_stats (&cda); +	print_cleared_stats(&cda); -  return 0; +	return 0;  }  DEFUN (clear_vnc_nve_vn, @@ -3850,20 +3543,21 @@ DEFUN (clear_vnc_nve_vn,         "VN IPv4 interface address\n"         "VN IPv6 interface address\n")  { -  struct rfapi_local_reg_delete_arg cda; -  int rc; +	struct rfapi_local_reg_delete_arg cda; +	int rc; -  if ((rc = parse_deleter_tokens (vty, NULL, NULL, argv[4], NULL, NULL, NULL, NULL, NULL, &cda))) -    return rc; +	if ((rc = parse_deleter_tokens(vty, NULL, NULL, argv[4], NULL, NULL, +				       NULL, NULL, NULL, &cda))) +		return rc; -  cda.vty = vty; +	cda.vty = vty; -  clear_vnc_responses (&cda); -  clear_vnc_prefix (&cda); -  clear_vnc_nve_closer (&cda); +	clear_vnc_responses(&cda); +	clear_vnc_prefix(&cda); +	clear_vnc_nve_closer(&cda); -  print_cleared_stats (&cda); -  return 0; +	print_cleared_stats(&cda); +	return 0;  }  DEFUN (clear_vnc_nve_un, @@ -3877,20 +3571,21 @@ DEFUN (clear_vnc_nve_un,         "UN IPv4 interface address\n"         "UN IPv6 interface address\n")  { -  struct rfapi_local_reg_delete_arg cda; -  int rc; +	struct rfapi_local_reg_delete_arg cda; +	int rc; -  if ((rc = parse_deleter_tokens (vty, NULL, NULL, NULL, argv[4], NULL, NULL, NULL, NULL, &cda))) -    return rc; +	if ((rc = parse_deleter_tokens(vty, NULL, NULL, NULL, argv[4], NULL, +				       NULL, NULL, NULL, &cda))) +		return rc; -  cda.vty = vty; +	cda.vty = vty; -  clear_vnc_responses (&cda); -  clear_vnc_prefix (&cda); -  clear_vnc_nve_closer (&cda); +	clear_vnc_responses(&cda); +	clear_vnc_prefix(&cda); +	clear_vnc_nve_closer(&cda); -  print_cleared_stats (&cda); -  return 0; +	print_cleared_stats(&cda); +	return 0;  }  /*------------------------------------------------- @@ -3919,16 +3614,16 @@ DEFUN (clear_vnc_prefix_vn_un,         "UN IPv4 interface address\n"         "UN IPv6 interface address\n")  { -  struct rfapi_local_reg_delete_arg cda; -  int rc; - -  if ((rc = -       parse_deleter_tokens (vty, NULL, argv[3], argv[5], argv[7], NULL, NULL, NULL, NULL, &cda))) -    return rc; -  cda.vty = vty; -  clear_vnc_prefix (&cda); -  print_cleared_stats (&cda); -  return 0; +	struct rfapi_local_reg_delete_arg cda; +	int rc; + +	if ((rc = parse_deleter_tokens(vty, NULL, argv[3], argv[5], argv[7], +				       NULL, NULL, NULL, NULL, &cda))) +		return rc; +	cda.vty = vty; +	clear_vnc_prefix(&cda); +	print_cleared_stats(&cda); +	return 0;  }  DEFUN (clear_vnc_prefix_un_vn, @@ -3949,16 +3644,16 @@ DEFUN (clear_vnc_prefix_un_vn,         "VN IPv4 interface address\n"         "VN IPv6 interface address\n")  { -  struct rfapi_local_reg_delete_arg cda; -  int rc; - -  if ((rc = -       parse_deleter_tokens (vty, NULL, argv[3], argv[7], argv[5], NULL, NULL, NULL, NULL, &cda))) -    return rc; -  cda.vty = vty; -  clear_vnc_prefix (&cda); -  print_cleared_stats (&cda); -  return 0; +	struct rfapi_local_reg_delete_arg cda; +	int rc; + +	if ((rc = parse_deleter_tokens(vty, NULL, argv[3], argv[7], argv[5], +				       NULL, NULL, NULL, NULL, &cda))) +		return rc; +	cda.vty = vty; +	clear_vnc_prefix(&cda); +	print_cleared_stats(&cda); +	return 0;  }  DEFUN (clear_vnc_prefix_un, @@ -3975,16 +3670,16 @@ DEFUN (clear_vnc_prefix_un,         "UN IPv4 interface address\n"         "UN IPv6 interface address\n")  { -  struct rfapi_local_reg_delete_arg cda; -  int rc; - -  if ((rc = -       parse_deleter_tokens (vty, NULL, argv[3], NULL, argv[5], NULL, NULL, NULL, NULL, &cda))) -    return rc; -  cda.vty = vty; -  clear_vnc_prefix (&cda); -  print_cleared_stats (&cda); -  return 0; +	struct rfapi_local_reg_delete_arg cda; +	int rc; + +	if ((rc = parse_deleter_tokens(vty, NULL, argv[3], NULL, argv[5], NULL, +				       NULL, NULL, NULL, &cda))) +		return rc; +	cda.vty = vty; +	clear_vnc_prefix(&cda); +	print_cleared_stats(&cda); +	return 0;  }  DEFUN (clear_vnc_prefix_vn, @@ -4001,16 +3696,16 @@ DEFUN (clear_vnc_prefix_vn,         "VN IPv4 interface address\n"         "VN IPv6 interface address\n")  { -  struct rfapi_local_reg_delete_arg cda; -  int rc; - -  if ((rc = -       parse_deleter_tokens (vty, NULL, argv[3], argv[5], NULL, NULL, NULL, NULL, NULL, &cda))) -    return rc; -  cda.vty = vty; -  clear_vnc_prefix (&cda); -  print_cleared_stats (&cda); -  return 0; +	struct rfapi_local_reg_delete_arg cda; +	int rc; + +	if ((rc = parse_deleter_tokens(vty, NULL, argv[3], argv[5], NULL, NULL, +				       NULL, NULL, NULL, &cda))) +		return rc; +	cda.vty = vty; +	clear_vnc_prefix(&cda); +	print_cleared_stats(&cda); +	return 0;  }  DEFUN (clear_vnc_prefix_all, @@ -4024,15 +3719,16 @@ DEFUN (clear_vnc_prefix_all,         "IPv6 prefix\n"         "From any NVE\n")  { -  struct rfapi_local_reg_delete_arg cda; -  int rc; - -  if ((rc = parse_deleter_tokens (vty, NULL, argv[3], NULL, NULL, NULL, NULL, NULL, NULL, &cda))) -    return rc; -  cda.vty = vty; -  clear_vnc_prefix (&cda); -  print_cleared_stats (&cda); -  return 0; +	struct rfapi_local_reg_delete_arg cda; +	int rc; + +	if ((rc = parse_deleter_tokens(vty, NULL, argv[3], NULL, NULL, NULL, +				       NULL, NULL, NULL, &cda))) +		return rc; +	cda.vty = vty; +	clear_vnc_prefix(&cda); +	print_cleared_stats(&cda); +	return 0;  }  /*------------------------------------------------- @@ -4063,18 +3759,17 @@ DEFUN (clear_vnc_mac_vn_un,         "UN IPv4 interface address\n"         "UN IPv6 interface address\n")  { -  struct rfapi_local_reg_delete_arg cda; -  int rc; - -  /* pfx vn un L2 VNI */ -  if ((rc = -       parse_deleter_tokens (vty, NULL, NULL, argv[7], argv[9], argv[3], argv[5], -                           NULL, NULL, &cda))) -    return rc; -  cda.vty = vty; -  clear_vnc_prefix (&cda); -  print_cleared_stats (&cda); -  return 0; +	struct rfapi_local_reg_delete_arg cda; +	int rc; + +	/* pfx vn un L2 VNI */ +	if ((rc = parse_deleter_tokens(vty, NULL, NULL, argv[7], argv[9], +				       argv[3], argv[5], NULL, NULL, &cda))) +		return rc; +	cda.vty = vty; +	clear_vnc_prefix(&cda); +	print_cleared_stats(&cda); +	return 0;  }  DEFUN (clear_vnc_mac_un_vn, @@ -4097,18 +3792,17 @@ DEFUN (clear_vnc_mac_un_vn,         "VN IPv4 interface address\n"         "VN IPv6 interface address\n")  { -  struct rfapi_local_reg_delete_arg cda; -  int rc; - -  /* pfx vn un L2 VNI */ -  if ((rc = -       parse_deleter_tokens (vty, NULL, NULL, argv[9], argv[7], argv[3], argv[5], -                           NULL, NULL, &cda))) -    return rc; -  cda.vty = vty; -  clear_vnc_prefix (&cda); -  print_cleared_stats (&cda); -  return 0; +	struct rfapi_local_reg_delete_arg cda; +	int rc; + +	/* pfx vn un L2 VNI */ +	if ((rc = parse_deleter_tokens(vty, NULL, NULL, argv[9], argv[7], +				       argv[3], argv[5], NULL, NULL, &cda))) +		return rc; +	cda.vty = vty; +	clear_vnc_prefix(&cda); +	print_cleared_stats(&cda); +	return 0;  }  DEFUN (clear_vnc_mac_un, @@ -4127,17 +3821,17 @@ DEFUN (clear_vnc_mac_un,         "UN IPv4 interface address\n"         "UN IPv6 interface address\n")  { -  struct rfapi_local_reg_delete_arg cda; -  int rc; - -  /* pfx vn un L2 VNI */ -  if ((rc = -       parse_deleter_tokens (vty, NULL, NULL, NULL, argv[7], argv[3], argv[5], NULL, NULL, &cda))) -    return rc; -  cda.vty = vty; -  clear_vnc_prefix (&cda); -  print_cleared_stats (&cda); -  return 0; +	struct rfapi_local_reg_delete_arg cda; +	int rc; + +	/* pfx vn un L2 VNI */ +	if ((rc = parse_deleter_tokens(vty, NULL, NULL, NULL, argv[7], argv[3], +				       argv[5], NULL, NULL, &cda))) +		return rc; +	cda.vty = vty; +	clear_vnc_prefix(&cda); +	print_cleared_stats(&cda); +	return 0;  }  DEFUN (clear_vnc_mac_vn, @@ -4156,17 +3850,17 @@ DEFUN (clear_vnc_mac_vn,         "VN IPv4 interface address\n"         "VN IPv6 interface address\n")  { -  struct rfapi_local_reg_delete_arg cda; -  int rc; - -  /* pfx vn un L2 VNI */ -  if ((rc = -       parse_deleter_tokens (vty, NULL, NULL, argv[7], NULL, argv[3], argv[5], NULL, NULL, &cda))) -    return rc; -  cda.vty = vty; -  clear_vnc_prefix (&cda); -  print_cleared_stats (&cda); -  return 0; +	struct rfapi_local_reg_delete_arg cda; +	int rc; + +	/* pfx vn un L2 VNI */ +	if ((rc = parse_deleter_tokens(vty, NULL, NULL, argv[7], NULL, argv[3], +				       argv[5], NULL, NULL, &cda))) +		return rc; +	cda.vty = vty; +	clear_vnc_prefix(&cda); +	print_cleared_stats(&cda); +	return 0;  }  DEFUN (clear_vnc_mac_all, @@ -4182,17 +3876,17 @@ DEFUN (clear_vnc_mac_all,         "Virtual network identifier\n"         "From any NVE\n")  { -  struct rfapi_local_reg_delete_arg cda; -  int rc; - -  /* pfx vn un L2 VNI */ -  if ((rc = -       parse_deleter_tokens (vty, NULL, NULL, NULL, NULL, argv[3], argv[5], NULL, NULL, &cda))) -    return rc; -  cda.vty = vty; -  clear_vnc_prefix (&cda); -  print_cleared_stats (&cda); -  return 0; +	struct rfapi_local_reg_delete_arg cda; +	int rc; + +	/* pfx vn un L2 VNI */ +	if ((rc = parse_deleter_tokens(vty, NULL, NULL, NULL, NULL, argv[3], +				       argv[5], NULL, NULL, &cda))) +		return rc; +	cda.vty = vty; +	clear_vnc_prefix(&cda); +	print_cleared_stats(&cda); +	return 0;  }  /*------------------------------------------------- @@ -4223,18 +3917,17 @@ DEFUN (clear_vnc_mac_vn_un_prefix,         "IPv4 prefix\n"         "IPv6 prefix\n")  { -  struct rfapi_local_reg_delete_arg cda; -  int rc; - -  /* pfx vn un L2 VNI */ -  if ((rc = -       parse_deleter_tokens (vty, NULL, argv[11], argv[7], argv[9], argv[3], argv[5], -                           NULL, NULL, &cda))) -    return rc; -  cda.vty = vty; -  clear_vnc_prefix (&cda); -  print_cleared_stats (&cda); -  return 0; +	struct rfapi_local_reg_delete_arg cda; +	int rc; + +	/* pfx vn un L2 VNI */ +	if ((rc = parse_deleter_tokens(vty, NULL, argv[11], argv[7], argv[9], +				       argv[3], argv[5], NULL, NULL, &cda))) +		return rc; +	cda.vty = vty; +	clear_vnc_prefix(&cda); +	print_cleared_stats(&cda); +	return 0;  }  DEFUN (clear_vnc_mac_un_vn_prefix, @@ -4265,18 +3958,17 @@ DEFUN (clear_vnc_mac_un_vn_prefix,         "IPv4 prefix\n"         "IPv6 prefix\n")  { -  struct rfapi_local_reg_delete_arg cda; -  int rc; - -  /* pfx vn un L2 VNI */ -  if ((rc = -       parse_deleter_tokens (vty, NULL, argv[11], argv[9], argv[7], argv[3], argv[5], -                           NULL, NULL, &cda))) -    return rc; -  cda.vty = vty; -  clear_vnc_prefix (&cda); -  print_cleared_stats (&cda); -  return 0; +	struct rfapi_local_reg_delete_arg cda; +	int rc; + +	/* pfx vn un L2 VNI */ +	if ((rc = parse_deleter_tokens(vty, NULL, argv[11], argv[9], argv[7], +				       argv[3], argv[5], NULL, NULL, &cda))) +		return rc; +	cda.vty = vty; +	clear_vnc_prefix(&cda); +	print_cleared_stats(&cda); +	return 0;  }  DEFUN (clear_vnc_mac_un_prefix, @@ -4299,18 +3991,17 @@ DEFUN (clear_vnc_mac_un_prefix,         "IPv4 Prefix\n"         "IPv6 Prefix\n")  { -  struct rfapi_local_reg_delete_arg cda; -  int rc; - -  /* pfx vn un L2 VNI */ -  if ((rc = -       parse_deleter_tokens (vty, NULL, argv[9], NULL, argv[7], argv[3], argv[5], -                           NULL, NULL, &cda))) -    return rc; -  cda.vty = vty; -  clear_vnc_prefix (&cda); -  print_cleared_stats (&cda); -  return 0; +	struct rfapi_local_reg_delete_arg cda; +	int rc; + +	/* pfx vn un L2 VNI */ +	if ((rc = parse_deleter_tokens(vty, NULL, argv[9], NULL, argv[7], +				       argv[3], argv[5], NULL, NULL, &cda))) +		return rc; +	cda.vty = vty; +	clear_vnc_prefix(&cda); +	print_cleared_stats(&cda); +	return 0;  }  DEFUN (clear_vnc_mac_vn_prefix, @@ -4333,18 +4024,17 @@ DEFUN (clear_vnc_mac_vn_prefix,         "IPv4 Prefix\n"         "IPv6 Prefix\n")  { -  struct rfapi_local_reg_delete_arg cda; -  int rc; - -  /* pfx vn un L2 VNI */ -  if ((rc = -       parse_deleter_tokens (vty, NULL, argv[9], argv[7], NULL, argv[3], argv[5], -                           NULL, NULL, &cda))) -    return rc; -  cda.vty = vty; -  clear_vnc_prefix (&cda); -  print_cleared_stats (&cda); -  return 0; +	struct rfapi_local_reg_delete_arg cda; +	int rc; + +	/* pfx vn un L2 VNI */ +	if ((rc = parse_deleter_tokens(vty, NULL, argv[9], argv[7], NULL, +				       argv[3], argv[5], NULL, NULL, &cda))) +		return rc; +	cda.vty = vty; +	clear_vnc_prefix(&cda); +	print_cleared_stats(&cda); +	return 0;  }  DEFUN (clear_vnc_mac_all_prefix, @@ -4363,17 +4053,17 @@ DEFUN (clear_vnc_mac_all_prefix,         "VN IPv4 interface address\n"         "VN IPv6 interface address\n")  { -  struct rfapi_local_reg_delete_arg cda; -  int rc; - -  /* pfx vn un L2 VNI */ -  if ((rc = -       parse_deleter_tokens (vty, NULL, argv[7], NULL, NULL, argv[3], argv[5], NULL, NULL, &cda))) -    return rc; -  cda.vty = vty; -  clear_vnc_prefix (&cda); -  print_cleared_stats (&cda); -  return 0; +	struct rfapi_local_reg_delete_arg cda; +	int rc; + +	/* pfx vn un L2 VNI */ +	if ((rc = parse_deleter_tokens(vty, NULL, argv[7], NULL, NULL, argv[3], +				       argv[5], NULL, NULL, &cda))) +		return rc; +	cda.vty = vty; +	clear_vnc_prefix(&cda); +	print_cleared_stats(&cda); +	return 0;  }  /************************************************************************ @@ -4382,222 +4072,216 @@ DEFUN (clear_vnc_mac_all_prefix,  /* copied from rfp_vty.c */ -static int -check_and_display_is_vnc_running (struct vty *vty) +static int check_and_display_is_vnc_running(struct vty *vty)  { -  if (!bgp_rfapi_is_vnc_configured (NULL)) -    return 1;                   /* is running */ - -  if (vty) -    { -      vty_out (vty, -               "VNC is not configured. (There are no configured BGP VPN SAFI peers.)\n"); -    } -  return 0;                     /* not running */ +	if (!bgp_rfapi_is_vnc_configured(NULL)) +		return 1; /* is running */ + +	if (vty) { +		vty_out(vty, +			"VNC is not configured. (There are no configured BGP VPN SAFI peers.)\n"); +	} +	return 0; /* not running */  } -static int -rfapi_vty_show_nve_summary (struct vty *vty, show_nve_summary_t show_type) +static int rfapi_vty_show_nve_summary(struct vty *vty, +				      show_nve_summary_t show_type)  { -  struct bgp *bgp_default = bgp_get_default (); -  struct rfapi *h; -  int is_vnc_running = !bgp_rfapi_is_vnc_configured (bgp_default); - -  int active_local_routes; -  int active_remote_routes; -  int holddown_remote_routes; -  int imported_remote_routes; - -  if (!bgp_default) -      goto notcfg; - -    h = bgp_default->rfapi; - -  if (!h) -      goto notcfg; - -  /* don't show local info if not running RFP */ -  if (is_vnc_running || show_type == SHOW_NVE_SUMMARY_REGISTERED) -    { - -      switch (show_type) -        { - -        case SHOW_NVE_SUMMARY_ACTIVE_NVES: -          vty_out (vty, "%-24s ", "NVEs:"); -          vty_out (vty, "%-8s %-8u ", "Active:", h->descriptors.count); -          vty_out (vty, "%-8s %-8u ", "Maximum:", h->stat.max_descriptors); -          vty_out (vty, "%-8s %-8u", "Unknown:", h->stat.count_unknown_nves); -          break; - -          case SHOW_NVE_SUMMARY_REGISTERED: -            /* -             * NB: With the introduction of L2 route support, we no -             * longer have a one-to-one correspondence between -             * locally-originated route advertisements and routes in -             * the import tables that have local origin. This -             * discrepancy arises because a single advertisement -             * may contain both an IP prefix and a MAC address. -             * Such an advertisement results in two import table -             * entries: one indexed by IP prefix, the other indexed -             * by MAC address. -             * -             * TBD: update computation and display of registration -             * statistics to reflect the underlying semantics. -             */ -          if (is_vnc_running) -            { -              vty_out (vty, "%-24s ", "Registrations:"); -              vty_out (vty, "%-8s %-8u ", "Active:", -                       rfapiApCountAll (bgp_default)); -              vty_out (vty, "%-8s %-8u ", "Failed:", -                       h->stat.count_registrations_failed); -              vty_out (vty, "%-8s %-8u", "Total:", -                       h->stat.count_registrations); -              vty_out (vty, "\n"); -            } -          vty_out (vty, "%-24s ", "Prefixes registered:"); -          vty_out (vty, "\n"); - -          rfapiCountAllItRoutes (&active_local_routes, -                                 &active_remote_routes, -                                 &holddown_remote_routes, -                                 &imported_remote_routes); - -          /* local */ -          if (is_vnc_running) -            { -              vty_out (vty, "    %-20s ", "Locally:"); -              vty_out (vty, "%-8s %-8u ", "Active:", active_local_routes); -              vty_out (vty, "\n"); -            } - - -          vty_out (vty, "    %-20s ", "Remotely:"); -          vty_out (vty, "%-8s %-8u", "Active:", active_remote_routes); -          vty_out (vty, "\n"); -          vty_out (vty, "    %-20s ", "In Holddown:"); -          vty_out (vty, "%-8s %-8u", "Active:", holddown_remote_routes); -          vty_out (vty, "\n"); -          vty_out (vty, "    %-20s ", "Imported:"); -          vty_out (vty, "%-8s %-8u", "Active:", imported_remote_routes); -          break; - -        case SHOW_NVE_SUMMARY_QUERIES: -          vty_out (vty, "%-24s ", "Queries:"); -          vty_out (vty, "%-8s %-8u ", "Active:", rfapi_monitor_count (NULL)); -          vty_out (vty, "%-8s %-8u ", "Failed:", -                   h->stat.count_queries_failed); -          vty_out (vty, "%-8s %-8u", "Total:", h->stat.count_queries); -          break; - -        case SHOW_NVE_SUMMARY_RESPONSES: -          rfapiRibShowResponsesSummary (vty); - -        default: -          break; -        } -      vty_out (vty, "\n"); -    } -  return 0; +	struct bgp *bgp_default = bgp_get_default(); +	struct rfapi *h; +	int is_vnc_running = !bgp_rfapi_is_vnc_configured(bgp_default); + +	int active_local_routes; +	int active_remote_routes; +	int holddown_remote_routes; +	int imported_remote_routes; + +	if (!bgp_default) +		goto notcfg; + +	h = bgp_default->rfapi; + +	if (!h) +		goto notcfg; + +	/* don't show local info if not running RFP */ +	if (is_vnc_running || show_type == SHOW_NVE_SUMMARY_REGISTERED) { + +		switch (show_type) { + +		case SHOW_NVE_SUMMARY_ACTIVE_NVES: +			vty_out(vty, "%-24s ", "NVEs:"); +			vty_out(vty, "%-8s %-8u ", +				"Active:", h->descriptors.count); +			vty_out(vty, "%-8s %-8u ", +				"Maximum:", h->stat.max_descriptors); +			vty_out(vty, "%-8s %-8u", +				"Unknown:", h->stat.count_unknown_nves); +			break; + +		case SHOW_NVE_SUMMARY_REGISTERED: +			/* +			 * NB: With the introduction of L2 route support, we no +			 * longer have a one-to-one correspondence between +			 * locally-originated route advertisements and routes in +			 * the import tables that have local origin. This +			 * discrepancy arises because a single advertisement +			 * may contain both an IP prefix and a MAC address. +			 * Such an advertisement results in two import table +			 * entries: one indexed by IP prefix, the other indexed +			 * by MAC address. +			 * +			 * TBD: update computation and display of registration +			 * statistics to reflect the underlying semantics. +			 */ +			if (is_vnc_running) { +				vty_out(vty, "%-24s ", "Registrations:"); +				vty_out(vty, "%-8s %-8u ", "Active:", +					rfapiApCountAll(bgp_default)); +				vty_out(vty, "%-8s %-8u ", "Failed:", +					h->stat.count_registrations_failed); +				vty_out(vty, "%-8s %-8u", +					"Total:", h->stat.count_registrations); +				vty_out(vty, "\n"); +			} +			vty_out(vty, "%-24s ", "Prefixes registered:"); +			vty_out(vty, "\n"); + +			rfapiCountAllItRoutes(&active_local_routes, +					      &active_remote_routes, +					      &holddown_remote_routes, +					      &imported_remote_routes); + +			/* local */ +			if (is_vnc_running) { +				vty_out(vty, "    %-20s ", "Locally:"); +				vty_out(vty, "%-8s %-8u ", +					"Active:", active_local_routes); +				vty_out(vty, "\n"); +			} + + +			vty_out(vty, "    %-20s ", "Remotely:"); +			vty_out(vty, "%-8s %-8u", +				"Active:", active_remote_routes); +			vty_out(vty, "\n"); +			vty_out(vty, "    %-20s ", "In Holddown:"); +			vty_out(vty, "%-8s %-8u", +				"Active:", holddown_remote_routes); +			vty_out(vty, "\n"); +			vty_out(vty, "    %-20s ", "Imported:"); +			vty_out(vty, "%-8s %-8u", +				"Active:", imported_remote_routes); +			break; + +		case SHOW_NVE_SUMMARY_QUERIES: +			vty_out(vty, "%-24s ", "Queries:"); +			vty_out(vty, "%-8s %-8u ", +				"Active:", rfapi_monitor_count(NULL)); +			vty_out(vty, "%-8s %-8u ", +				"Failed:", h->stat.count_queries_failed); +			vty_out(vty, "%-8s %-8u", +				"Total:", h->stat.count_queries); +			break; + +		case SHOW_NVE_SUMMARY_RESPONSES: +			rfapiRibShowResponsesSummary(vty); + +		default: +			break; +		} +		vty_out(vty, "\n"); +	} +	return 0;  notcfg: -  vty_out (vty, "VNC is not configured.\n"); -  return CMD_WARNING; +	vty_out(vty, "VNC is not configured.\n"); +	return CMD_WARNING;  } -static int -rfapi_show_nves ( -  struct vty	*vty, -  struct prefix	*vn_prefix, -  struct prefix	*un_prefix) +static int rfapi_show_nves(struct vty *vty, struct prefix *vn_prefix, +			   struct prefix *un_prefix)  { -  //struct hash                      *rfds; -  //struct rfp_rfapi_descriptor_param param; - -  struct bgp *bgp_default = bgp_get_default (); -  struct rfapi *h; -  struct listnode *node; -  struct rfapi_descriptor *rfd; - -  int total = 0; -  int printed = 0; -  int rc; - -  if (!bgp_default) -      goto notcfg; - -    h = bgp_default->rfapi; - -  if (!h) -      goto notcfg; - -    rc = rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_ACTIVE_NVES); -  if (rc) -      return rc; - -  for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd)) -    { -      struct prefix pfx; -      char vn_addr_buf[INET6_ADDRSTRLEN] = -      { -      0,}; -      char un_addr_buf[INET6_ADDRSTRLEN] = -      { -      0,}; -      char age[10]; - -      ++total; - -      if (vn_prefix) -        { -          assert (!rfapiRaddr2Qprefix (&rfd->vn_addr, &pfx)); -          if (!prefix_match (vn_prefix, &pfx)) -            continue; -        } - -      if (un_prefix) -        { -          assert (!rfapiRaddr2Qprefix (&rfd->un_addr, &pfx)); -          if (!prefix_match (un_prefix, &pfx)) -            continue; -        } - -      rfapiRfapiIpAddr2Str (&rfd->vn_addr, vn_addr_buf, INET6_ADDRSTRLEN); -      rfapiRfapiIpAddr2Str (&rfd->un_addr, un_addr_buf, INET6_ADDRSTRLEN); - -      if (!printed) -        { -          /* print out a header */ -          vty_out (vty, -                     "                                Active      Next Hops\n"); -          vty_out (vty, "%-15s %-15s %-5s %-5s %-6s %-6s %s\n", -                   "VN Address", -                   "UN Address", -                   "Regis", "Resps", "Reach", "Remove", "Age"); -        } - -      ++printed; - -      vty_out (vty, "%-15s %-15s %-5u %-5u %-6u %-6u %s\n", -               vn_addr_buf, -               un_addr_buf, -               rfapiApCount (rfd), -               rfapi_monitor_count (rfd), -               rfd->stat_count_nh_reachable, -               rfd->stat_count_nh_removal, -               rfapiFormatAge(rfd->open_time, age, 10)); -    } - -  if (printed > 0 || vn_prefix || un_prefix) -    vty_out (vty, "Displayed %d out of %d active NVEs\n", -             printed, total); - -  return 0; +	// struct hash                      *rfds; +	// struct rfp_rfapi_descriptor_param param; + +	struct bgp *bgp_default = bgp_get_default(); +	struct rfapi *h; +	struct listnode *node; +	struct rfapi_descriptor *rfd; + +	int total = 0; +	int printed = 0; +	int rc; + +	if (!bgp_default) +		goto notcfg; + +	h = bgp_default->rfapi; + +	if (!h) +		goto notcfg; + +	rc = rfapi_vty_show_nve_summary(vty, SHOW_NVE_SUMMARY_ACTIVE_NVES); +	if (rc) +		return rc; + +	for (ALL_LIST_ELEMENTS_RO(&h->descriptors, node, rfd)) { +		struct prefix pfx; +		char vn_addr_buf[INET6_ADDRSTRLEN] = { +			0, +		}; +		char un_addr_buf[INET6_ADDRSTRLEN] = { +			0, +		}; +		char age[10]; + +		++total; + +		if (vn_prefix) { +			assert(!rfapiRaddr2Qprefix(&rfd->vn_addr, &pfx)); +			if (!prefix_match(vn_prefix, &pfx)) +				continue; +		} + +		if (un_prefix) { +			assert(!rfapiRaddr2Qprefix(&rfd->un_addr, &pfx)); +			if (!prefix_match(un_prefix, &pfx)) +				continue; +		} + +		rfapiRfapiIpAddr2Str(&rfd->vn_addr, vn_addr_buf, +				     INET6_ADDRSTRLEN); +		rfapiRfapiIpAddr2Str(&rfd->un_addr, un_addr_buf, +				     INET6_ADDRSTRLEN); + +		if (!printed) { +			/* print out a header */ +			vty_out(vty, +				"                                Active      Next Hops\n"); +			vty_out(vty, "%-15s %-15s %-5s %-5s %-6s %-6s %s\n", +				"VN Address", "UN Address", "Regis", "Resps", +				"Reach", "Remove", "Age"); +		} + +		++printed; + +		vty_out(vty, "%-15s %-15s %-5u %-5u %-6u %-6u %s\n", +			vn_addr_buf, un_addr_buf, rfapiApCount(rfd), +			rfapi_monitor_count(rfd), rfd->stat_count_nh_reachable, +			rfd->stat_count_nh_removal, +			rfapiFormatAge(rfd->open_time, age, 10)); +	} + +	if (printed > 0 || vn_prefix || un_prefix) +		vty_out(vty, "Displayed %d out of %d active NVEs\n", printed, +			total); + +	return 0;  notcfg: -  vty_out (vty, "VNC is not configured.\n"); -  return CMD_WARNING; +	vty_out(vty, "VNC is not configured.\n"); +	return CMD_WARNING;  } @@ -4608,15 +4292,15 @@ DEFUN (vnc_show_summary,         VNC_SHOW_STR         "Display VNC status summary\n")  { -  if (!check_and_display_is_vnc_running (vty)) -    return CMD_SUCCESS; -  bgp_rfapi_show_summary (bgp_get_default (), vty); -  vty_out (vty, "\n"); -  rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_ACTIVE_NVES); -  rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_QUERIES); -  rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_RESPONSES); -  rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_REGISTERED); -  return CMD_SUCCESS; +	if (!check_and_display_is_vnc_running(vty)) +		return CMD_SUCCESS; +	bgp_rfapi_show_summary(bgp_get_default(), vty); +	vty_out(vty, "\n"); +	rfapi_vty_show_nve_summary(vty, SHOW_NVE_SUMMARY_ACTIVE_NVES); +	rfapi_vty_show_nve_summary(vty, SHOW_NVE_SUMMARY_QUERIES); +	rfapi_vty_show_nve_summary(vty, SHOW_NVE_SUMMARY_RESPONSES); +	rfapi_vty_show_nve_summary(vty, SHOW_NVE_SUMMARY_REGISTERED); +	return CMD_SUCCESS;  }  DEFUN (vnc_show_nves, @@ -4626,8 +4310,8 @@ DEFUN (vnc_show_nves,         VNC_SHOW_STR         "List known NVEs\n")  { -  rfapi_show_nves (vty, NULL, NULL); -  return CMD_SUCCESS; +	rfapi_show_nves(vty, NULL, NULL); +	return CMD_SUCCESS;  }  DEFUN (vnc_show_nves_ptct, @@ -4641,75 +4325,65 @@ DEFUN (vnc_show_nves_ptct,         "IPv4 interface address\n"         "IPv6 interface address\n")  { -  struct prefix pfx; - -  if (!check_and_display_is_vnc_running (vty)) -    return CMD_SUCCESS; - -  if (!str2prefix (argv[4]->arg, &pfx)) -    { -      vty_out (vty, "Malformed address \"%s\"\n", argv[4]->arg); -      return CMD_WARNING; -    } -  if (pfx.family != AF_INET && pfx.family != AF_INET6) -    { -      vty_out (vty, "Invalid address \"%s\"\n", argv[4]->arg); -      return CMD_WARNING; -    } - -  if (argv[3]->arg[0] == 'u') -    { -      rfapi_show_nves (vty, NULL, &pfx); -    } -  else -    { -      rfapi_show_nves (vty, &pfx, NULL); -    } - -  return CMD_SUCCESS; +	struct prefix pfx; + +	if (!check_and_display_is_vnc_running(vty)) +		return CMD_SUCCESS; + +	if (!str2prefix(argv[4]->arg, &pfx)) { +		vty_out(vty, "Malformed address \"%s\"\n", argv[4]->arg); +		return CMD_WARNING; +	} +	if (pfx.family != AF_INET && pfx.family != AF_INET6) { +		vty_out(vty, "Invalid address \"%s\"\n", argv[4]->arg); +		return CMD_WARNING; +	} + +	if (argv[3]->arg[0] == 'u') { +		rfapi_show_nves(vty, NULL, &pfx); +	} else { +		rfapi_show_nves(vty, &pfx, NULL); +	} + +	return CMD_SUCCESS;  }  /* adapted from rfp_registration_cache_log() */ -static void -rfapi_show_registrations ( -  struct vty	*vty, -  struct prefix	*restrict_to, -  int		show_local, -  int		show_remote, -  int		show_holddown, -  int		show_imported) +static void rfapi_show_registrations(struct vty *vty, +				     struct prefix *restrict_to, int show_local, +				     int show_remote, int show_holddown, +				     int show_imported)  { -  int printed = 0; - -  if (!vty) -      return; - -    rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_REGISTERED); - -  if (show_local) -    { -      /* non-expiring, local */ -      printed += rfapiShowRemoteRegistrations (vty, restrict_to, 0, 1, 0, 0); -    } -  if (show_remote) -    { -      /* non-expiring, non-local */ -      printed += rfapiShowRemoteRegistrations (vty, restrict_to, 0, 0, 1, 0); -    } -  if (show_holddown) -    { -      /* expiring, including local */ -      printed += rfapiShowRemoteRegistrations (vty, restrict_to, 1, 1, 1, 0); -    } -  if (show_imported) -    { -      /* non-expiring, non-local */ -      printed += rfapiShowRemoteRegistrations (vty, restrict_to, 0, 0, 1, 1); -    } -  if (!printed) -    { -      vty_out (vty, "\n"); -    } +	int printed = 0; + +	if (!vty) +		return; + +	rfapi_vty_show_nve_summary(vty, SHOW_NVE_SUMMARY_REGISTERED); + +	if (show_local) { +		/* non-expiring, local */ +		printed += rfapiShowRemoteRegistrations(vty, restrict_to, 0, 1, +							0, 0); +	} +	if (show_remote) { +		/* non-expiring, non-local */ +		printed += rfapiShowRemoteRegistrations(vty, restrict_to, 0, 0, +							1, 0); +	} +	if (show_holddown) { +		/* expiring, including local */ +		printed += rfapiShowRemoteRegistrations(vty, restrict_to, 1, 1, +							1, 0); +	} +	if (show_imported) { +		/* non-expiring, non-local */ +		printed += rfapiShowRemoteRegistrations(vty, restrict_to, 0, 0, +							1, 1); +	} +	if (!printed) { +		vty_out(vty, "\n"); +	}  }  DEFUN (vnc_show_registrations_pfx, @@ -4722,24 +4396,20 @@ DEFUN (vnc_show_registrations_pfx,         "Limit output to a particular IPv6 prefix\n"         "Limit output to a particular IPv6 address\n")  { -  struct prefix p; -  struct prefix *p_addr = NULL; - -  if (argc > 3) -    { -      if (!str2prefix (argv[3]->arg, &p)) -        { -          vty_out (vty, "Invalid prefix: %s\n", argv[3]->arg); -          return CMD_SUCCESS; -        } -      else -        { -          p_addr = &p; -        } -    } - -  rfapi_show_registrations (vty, p_addr, 1, 1, 1, 1); -  return CMD_SUCCESS; +	struct prefix p; +	struct prefix *p_addr = NULL; + +	if (argc > 3) { +		if (!str2prefix(argv[3]->arg, &p)) { +			vty_out(vty, "Invalid prefix: %s\n", argv[3]->arg); +			return CMD_SUCCESS; +		} else { +			p_addr = &p; +		} +	} + +	rfapi_show_registrations(vty, p_addr, 1, 1, 1, 1); +	return CMD_SUCCESS;  }  DEFUN (vnc_show_registrations_some_pfx, @@ -4757,56 +4427,50 @@ DEFUN (vnc_show_registrations_some_pfx,           "Limit output to a particular prefix or address\n"           "Limit output to a particular prefix or address\n")  { -  struct prefix p; -  struct prefix *p_addr = NULL; - -  int show_local = 0; -  int show_remote = 0; -  int show_holddown = 0; -  int show_imported = 0; - -  if (argc > 4) -    { -      if (!str2prefix (argv[4]->arg, &p)) -        { -          vty_out (vty, "Invalid prefix: %s\n", argv[4]->arg); -          return CMD_SUCCESS; -        } -      else -        { -          p_addr = &p; -        } -    } -  switch (argv[3]->arg[0]) -    { -    case 'a': -      show_local = 1; -      show_remote = 1; -      show_holddown = 1; -      show_imported = 1; -      break; - -    case 'h': -      show_holddown = 1; -      break; - -    case 'i': -      show_imported = 1; -      break; - -    case 'l': -      show_local = 1; -      break; - -    case 'r': -      show_remote = 1; -      break; -    } - -  rfapi_show_registrations (vty, p_addr, -                            show_local, show_remote, show_holddown, -                            show_imported); -  return CMD_SUCCESS; +	struct prefix p; +	struct prefix *p_addr = NULL; + +	int show_local = 0; +	int show_remote = 0; +	int show_holddown = 0; +	int show_imported = 0; + +	if (argc > 4) { +		if (!str2prefix(argv[4]->arg, &p)) { +			vty_out(vty, "Invalid prefix: %s\n", argv[4]->arg); +			return CMD_SUCCESS; +		} else { +			p_addr = &p; +		} +	} +	switch (argv[3]->arg[0]) { +	case 'a': +		show_local = 1; +		show_remote = 1; +		show_holddown = 1; +		show_imported = 1; +		break; + +	case 'h': +		show_holddown = 1; +		break; + +	case 'i': +		show_imported = 1; +		break; + +	case 'l': +		show_local = 1; +		break; + +	case 'r': +		show_remote = 1; +		break; +	} + +	rfapi_show_registrations(vty, p_addr, show_local, show_remote, +				 show_holddown, show_imported); +	return CMD_SUCCESS;  }  DEFUN (vnc_show_responses_pfx, @@ -4819,29 +4483,25 @@ DEFUN (vnc_show_responses_pfx,         "Limit output to a particular IPv6 prefix\n"         "Limit output to a particular IPv6 address\n" )  { -  struct prefix p; -  struct prefix *p_addr = NULL; - -  if (argc > 3) -    { -      if (!str2prefix (argv[3]->arg, &p)) -        { -          vty_out (vty, "Invalid prefix: %s\n", argv[3]->arg); -          return CMD_SUCCESS; -        } -      else -        { -          p_addr = &p; -        } -    } -  rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_QUERIES); - -  rfapiRibShowResponsesSummary (vty); - -  rfapiRibShowResponses (vty, p_addr, 0); -  rfapiRibShowResponses (vty, p_addr, 1); - -  return CMD_SUCCESS; +	struct prefix p; +	struct prefix *p_addr = NULL; + +	if (argc > 3) { +		if (!str2prefix(argv[3]->arg, &p)) { +			vty_out(vty, "Invalid prefix: %s\n", argv[3]->arg); +			return CMD_SUCCESS; +		} else { +			p_addr = &p; +		} +	} +	rfapi_vty_show_nve_summary(vty, SHOW_NVE_SUMMARY_QUERIES); + +	rfapiRibShowResponsesSummary(vty); + +	rfapiRibShowResponses(vty, p_addr, 0); +	rfapiRibShowResponses(vty, p_addr, 1); + +	return CMD_SUCCESS;  }  DEFUN (vnc_show_responses_some_pfx, @@ -4856,49 +4516,44 @@ DEFUN (vnc_show_responses_some_pfx,         "Limit output to a particular IPv6 prefix\n"         "Limit output to a particular IPV6 address\n")  { -  struct prefix p; -  struct prefix *p_addr = NULL; - -  int show_active = 0; -  int show_removed = 0; - -  if (!check_and_display_is_vnc_running (vty)) -    return CMD_SUCCESS; - -  if (argc > 4) -    { -      if (!str2prefix (argv[4]->arg, &p)) -        { -          vty_out (vty, "Invalid prefix: %s\n", argv[4]->arg); -          return CMD_SUCCESS; -        } -      else -        { -          p_addr = &p; -        } -    } - -  switch (argv[3]->arg[0]) -    { -    case 'a': -      show_active = 1; -      break; - -    case 'r': -      show_removed = 1; -      break; -    } - -  rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_QUERIES); - -  rfapiRibShowResponsesSummary (vty); - -  if (show_active) -    rfapiRibShowResponses (vty, p_addr, 0); -  if (show_removed) -    rfapiRibShowResponses (vty, p_addr, 1); - -  return CMD_SUCCESS; +	struct prefix p; +	struct prefix *p_addr = NULL; + +	int show_active = 0; +	int show_removed = 0; + +	if (!check_and_display_is_vnc_running(vty)) +		return CMD_SUCCESS; + +	if (argc > 4) { +		if (!str2prefix(argv[4]->arg, &p)) { +			vty_out(vty, "Invalid prefix: %s\n", argv[4]->arg); +			return CMD_SUCCESS; +		} else { +			p_addr = &p; +		} +	} + +	switch (argv[3]->arg[0]) { +	case 'a': +		show_active = 1; +		break; + +	case 'r': +		show_removed = 1; +		break; +	} + +	rfapi_vty_show_nve_summary(vty, SHOW_NVE_SUMMARY_QUERIES); + +	rfapiRibShowResponsesSummary(vty); + +	if (show_active) +		rfapiRibShowResponses(vty, p_addr, 0); +	if (show_removed) +		rfapiRibShowResponses(vty, p_addr, 1); + +	return CMD_SUCCESS;  }  DEFUN (show_vnc_queries_pfx, @@ -4911,22 +4566,20 @@ DEFUN (show_vnc_queries_pfx,         "Limit output to a particular IPv6 prefix\n"         "Limit output to a particualr IPV6 address\n")  { -  struct prefix pfx; -  struct prefix *p = NULL; - -  if (argc > 3) -    { -      if (!str2prefix (argv[3]->arg, &pfx)) -        { -          vty_out (vty, "Invalid prefix: %s\n", argv[3]->arg); -          return CMD_WARNING; -        } -      p = &pfx; -    } - -  rfapi_vty_show_nve_summary (vty, SHOW_NVE_SUMMARY_QUERIES); - -  return rfapiShowVncQueries (vty, p); +	struct prefix pfx; +	struct prefix *p = NULL; + +	if (argc > 3) { +		if (!str2prefix(argv[3]->arg, &pfx)) { +			vty_out(vty, "Invalid prefix: %s\n", argv[3]->arg); +			return CMD_WARNING; +		} +		p = &pfx; +	} + +	rfapi_vty_show_nve_summary(vty, SHOW_NVE_SUMMARY_QUERIES); + +	return rfapiShowVncQueries(vty, p);  }  DEFUN (vnc_clear_counters, @@ -4936,43 +4589,42 @@ DEFUN (vnc_clear_counters,         VNC_SHOW_STR         "Reset VNC counters\n")  { -  struct bgp *bgp_default = bgp_get_default (); -  struct rfapi *h; -  struct listnode *node; -  struct rfapi_descriptor *rfd; +	struct bgp *bgp_default = bgp_get_default(); +	struct rfapi *h; +	struct listnode *node; +	struct rfapi_descriptor *rfd; -  if (!bgp_default) -    goto notcfg; +	if (!bgp_default) +		goto notcfg; -  h = bgp_default->rfapi; +	h = bgp_default->rfapi; -  if (!h) -    goto notcfg; +	if (!h) +		goto notcfg; -  /* per-rfd */ -  for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd)) -    { -      rfd->stat_count_nh_reachable = 0; -      rfd->stat_count_nh_removal = 0; -    } +	/* per-rfd */ +	for (ALL_LIST_ELEMENTS_RO(&h->descriptors, node, rfd)) { +		rfd->stat_count_nh_reachable = 0; +		rfd->stat_count_nh_removal = 0; +	} -  /* global */ -  memset (&h->stat, 0, sizeof (h->stat)); +	/* global */ +	memset(&h->stat, 0, sizeof(h->stat)); -  /* -   * 151122 per bug 103, set count_registrations = number active. -   * Do same for queries -   */ -  h->stat.count_registrations = rfapiApCountAll (bgp_default); -  h->stat.count_queries = rfapi_monitor_count (NULL); +	/* +	 * 151122 per bug 103, set count_registrations = number active. +	 * Do same for queries +	 */ +	h->stat.count_registrations = rfapiApCountAll(bgp_default); +	h->stat.count_queries = rfapi_monitor_count(NULL); -  rfapiRibShowResponsesSummaryClear (); +	rfapiRibShowResponsesSummaryClear(); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  notcfg: -  vty_out (vty, "VNC is not configured.\n"); -  return CMD_WARNING; +	vty_out(vty, "VNC is not configured.\n"); +	return CMD_WARNING;  }  /************************************************************************ @@ -4981,172 +4633,160 @@ notcfg:   * add [vrf <vrf-name>] prefix <prefix>   *     [rd <value>] [label <value>] [local-preference <0-4294967295>]   ************************************************************************/ -static int -vnc_add_vrf_prefix (struct vty *vty, -                    const char *arg_vrf, -                    const char *arg_prefix, -                    const char *arg_rd,     /* optional */ -                    const char *arg_label,  /* optional */ -                    const char *arg_pref)   /* optional */ +static int vnc_add_vrf_prefix(struct vty *vty, const char *arg_vrf, +			      const char *arg_prefix, +			      const char *arg_rd,    /* optional */ +			      const char *arg_label, /* optional */ +			      const char *arg_pref)  /* optional */  { -  struct bgp                 *bgp; -  struct rfapi_nve_group_cfg *rfg; -  struct prefix               pfx; -  struct rfapi_ip_prefix      rpfx; -  uint32_t                    pref = 0; -  struct rfapi_vn_option      optary[3]; -  struct rfapi_vn_option      *opt = NULL; -  int                         cur_opt = 0; - -  bgp = bgp_get_default (); /* assume main instance for now */ -  if (!bgp) -    { -      vty_out (vty, "No BGP process is configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } -  if (!bgp->rfapi || !bgp->rfapi_cfg) -    { -      vty_out (vty, "VRF support not configured\n"); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  rfg = bgp_rfapi_cfg_match_byname (bgp,  arg_vrf, RFAPI_GROUP_CFG_VRF); -  /* arg checks */ -  if (!rfg) -    { -      vty_out (vty, "VRF \"%s\" appears not to be configured.\n", -               arg_vrf); -      return CMD_WARNING_CONFIG_FAILED; -    } -  if (!rfg->rt_export_list || !rfg->rfapi_import_table) -    { -      vty_out (vty, "VRF \"%s\" is missing RT import/export RT configuration.\n", -               arg_vrf); -      return CMD_WARNING_CONFIG_FAILED; -    } -  if (!rfg->rd.family && !arg_rd) -    { -      vty_out (vty, "VRF \"%s\" isn't configured with an RD, so RD must be provided.\n", -               arg_vrf); -      return CMD_WARNING_CONFIG_FAILED; -    } -  if (rfg->label > MPLS_LABEL_MAX && !arg_label) -    { -      vty_out (vty, "VRF \"%s\" isn't configured with a default labels, so a label must be provided.\n", -               arg_vrf); -      return CMD_WARNING_CONFIG_FAILED; -    } -  if (!str2prefix (arg_prefix, &pfx)) -    { -      vty_out (vty, "Malformed prefix \"%s\"\n", -               arg_prefix); -      return CMD_WARNING_CONFIG_FAILED; -    } -  rfapiQprefix2Rprefix (&pfx, &rpfx); -  memset (optary, 0, sizeof (optary)); -  if (arg_rd) -    { -      if (opt != NULL) -        opt->next = &optary[cur_opt]; -      opt = &optary[cur_opt++]; -      opt->type = RFAPI_VN_OPTION_TYPE_INTERNAL_RD; -      if (!str2prefix_rd (arg_rd, &opt->v.internal_rd)) -        { -          vty_out (vty, "Malformed RD \"%s\"\n", -                   arg_rd); -          return CMD_WARNING_CONFIG_FAILED; -        } -    } -  if (rfg->label <= MPLS_LABEL_MAX || arg_label) -    { -      struct rfapi_l2address_option	*l2o; -      if (opt != NULL) -        opt->next = &optary[cur_opt]; -      opt = &optary[cur_opt++]; -      opt->type  = RFAPI_VN_OPTION_TYPE_L2ADDR; -      l2o =  &opt->v.l2addr; -      if (arg_label) -        { -          int32_t label; -          label = strtoul(arg_label, NULL, 10); -          l2o->label = label; -        } -      else -        l2o->label = rfg->label; -    } -  if (arg_pref) -    { -      char *endptr = NULL; -      pref = strtoul (arg_pref, &endptr, 10); -      if (*endptr != '\0') -        { -          vty_out (vty, "%% Invalid local-preference value \"%s\"\n", -                     arg_pref); -          return CMD_WARNING_CONFIG_FAILED; -         } -    } -  rpfx.cost = 255 - (pref & 255) ; -  if (rfg->rfd == NULL)         /* need new rfapi_handle */ -    { -      /* based on rfapi_open */ -      struct rfapi_descriptor *rfd; -      rfd = XCALLOC (MTYPE_RFAPI_DESC, sizeof (struct rfapi_descriptor)); -      rfd->bgp = bgp; -      rfg->rfd = rfd; -      /* leave most fields empty as will get from (dynamic) config when needed */ -      rfd->default_tunneltype_option.type = BGP_ENCAP_TYPE_MPLS; -      rfd->cookie = rfg; -      if (rfg->vn_prefix.family && -          !CHECK_FLAG(rfg->flags, RFAPI_RFG_VPN_NH_SELF)) -        { -          rfapiQprefix2Raddr(&rfg->vn_prefix, &rfd->vn_addr); -        } -      else -        { -          memset(&rfd->vn_addr, 0, sizeof(struct rfapi_ip_addr)); -          rfd->vn_addr.addr_family = AF_INET; -          rfd->vn_addr.addr.v4 = bgp->router_id; -        } -      rfd->un_addr = rfd->vn_addr; /* sigh, need something in UN for lookups */ -      vnc_zlog_debug_verbose ("%s: Opening RFD for VRF %s", -                              __func__, rfg->name); -      rfapi_init_and_open(bgp, rfd, rfg); -    } - -  if (!rfapi_register (rfg->rfd, &rpfx, RFAPI_INFINITE_LIFETIME, NULL, -                       (cur_opt ? optary : NULL), RFAPI_REGISTER_ADD)) -    { -      struct rfapi_next_hop_entry *head = NULL; -      struct rfapi_next_hop_entry *tail = NULL; -      struct rfapi_vn_option *vn_opt_new; - -      vnc_zlog_debug_verbose ("%s: rfapi_register succeeded", __func__); - -      if (bgp->rfapi->rfp_methods.local_cb) -        { -          struct rfapi_descriptor *r = (struct rfapi_descriptor *) rfg->rfd; -          vn_opt_new = rfapi_vn_options_dup (opt); - -          rfapiAddDeleteLocalRfpPrefix (&r->un_addr, &r->vn_addr, &rpfx, -                                        1, RFAPI_INFINITE_LIFETIME, -                                        vn_opt_new, &head, &tail); -          if (head) -            { -              bgp->rfapi->flags |= RFAPI_INCALLBACK; -              (*bgp->rfapi->rfp_methods.local_cb) (head, r->cookie); -              bgp->rfapi->flags &= ~RFAPI_INCALLBACK; -            } -          head = tail = NULL; -        } -      vnc_zlog_debug_verbose ("%s completed, count=%d/%d",  __func__, -                              rfg->rfapi_import_table->local_count[AFI_IP], -                              rfg->rfapi_import_table->local_count[AFI_IP6]); -      return CMD_SUCCESS; -    } - -  vnc_zlog_debug_verbose ("%s: rfapi_register failed", __func__); -  vty_out (vty, "Add failed.\n"); -  return CMD_WARNING_CONFIG_FAILED; +	struct bgp *bgp; +	struct rfapi_nve_group_cfg *rfg; +	struct prefix pfx; +	struct rfapi_ip_prefix rpfx; +	uint32_t pref = 0; +	struct rfapi_vn_option optary[3]; +	struct rfapi_vn_option *opt = NULL; +	int cur_opt = 0; + +	bgp = bgp_get_default(); /* assume main instance for now */ +	if (!bgp) { +		vty_out(vty, "No BGP process is configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} +	if (!bgp->rfapi || !bgp->rfapi_cfg) { +		vty_out(vty, "VRF support not configured\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	rfg = bgp_rfapi_cfg_match_byname(bgp, arg_vrf, RFAPI_GROUP_CFG_VRF); +	/* arg checks */ +	if (!rfg) { +		vty_out(vty, "VRF \"%s\" appears not to be configured.\n", +			arg_vrf); +		return CMD_WARNING_CONFIG_FAILED; +	} +	if (!rfg->rt_export_list || !rfg->rfapi_import_table) { +		vty_out(vty, +			"VRF \"%s\" is missing RT import/export RT configuration.\n", +			arg_vrf); +		return CMD_WARNING_CONFIG_FAILED; +	} +	if (!rfg->rd.family && !arg_rd) { +		vty_out(vty, +			"VRF \"%s\" isn't configured with an RD, so RD must be provided.\n", +			arg_vrf); +		return CMD_WARNING_CONFIG_FAILED; +	} +	if (rfg->label > MPLS_LABEL_MAX && !arg_label) { +		vty_out(vty, +			"VRF \"%s\" isn't configured with a default labels, so a label must be provided.\n", +			arg_vrf); +		return CMD_WARNING_CONFIG_FAILED; +	} +	if (!str2prefix(arg_prefix, &pfx)) { +		vty_out(vty, "Malformed prefix \"%s\"\n", arg_prefix); +		return CMD_WARNING_CONFIG_FAILED; +	} +	rfapiQprefix2Rprefix(&pfx, &rpfx); +	memset(optary, 0, sizeof(optary)); +	if (arg_rd) { +		if (opt != NULL) +			opt->next = &optary[cur_opt]; +		opt = &optary[cur_opt++]; +		opt->type = RFAPI_VN_OPTION_TYPE_INTERNAL_RD; +		if (!str2prefix_rd(arg_rd, &opt->v.internal_rd)) { +			vty_out(vty, "Malformed RD \"%s\"\n", arg_rd); +			return CMD_WARNING_CONFIG_FAILED; +		} +	} +	if (rfg->label <= MPLS_LABEL_MAX || arg_label) { +		struct rfapi_l2address_option *l2o; +		if (opt != NULL) +			opt->next = &optary[cur_opt]; +		opt = &optary[cur_opt++]; +		opt->type = RFAPI_VN_OPTION_TYPE_L2ADDR; +		l2o = &opt->v.l2addr; +		if (arg_label) { +			int32_t label; +			label = strtoul(arg_label, NULL, 10); +			l2o->label = label; +		} else +			l2o->label = rfg->label; +	} +	if (arg_pref) { +		char *endptr = NULL; +		pref = strtoul(arg_pref, &endptr, 10); +		if (*endptr != '\0') { +			vty_out(vty, +				"%% Invalid local-preference value \"%s\"\n", +				arg_pref); +			return CMD_WARNING_CONFIG_FAILED; +		} +	} +	rpfx.cost = 255 - (pref & 255); +	if (rfg->rfd == NULL) /* need new rfapi_handle */ +	{ +		/* based on rfapi_open */ +		struct rfapi_descriptor *rfd; +		rfd = XCALLOC(MTYPE_RFAPI_DESC, +			      sizeof(struct rfapi_descriptor)); +		rfd->bgp = bgp; +		rfg->rfd = rfd; +		/* leave most fields empty as will get from (dynamic) config +		 * when needed */ +		rfd->default_tunneltype_option.type = BGP_ENCAP_TYPE_MPLS; +		rfd->cookie = rfg; +		if (rfg->vn_prefix.family +		    && !CHECK_FLAG(rfg->flags, RFAPI_RFG_VPN_NH_SELF)) { +			rfapiQprefix2Raddr(&rfg->vn_prefix, &rfd->vn_addr); +		} else { +			memset(&rfd->vn_addr, 0, sizeof(struct rfapi_ip_addr)); +			rfd->vn_addr.addr_family = AF_INET; +			rfd->vn_addr.addr.v4 = bgp->router_id; +		} +		rfd->un_addr = rfd->vn_addr; /* sigh, need something in UN for +						lookups */ +		vnc_zlog_debug_verbose("%s: Opening RFD for VRF %s", __func__, +				       rfg->name); +		rfapi_init_and_open(bgp, rfd, rfg); +	} + +	if (!rfapi_register(rfg->rfd, &rpfx, RFAPI_INFINITE_LIFETIME, NULL, +			    (cur_opt ? optary : NULL), RFAPI_REGISTER_ADD)) { +		struct rfapi_next_hop_entry *head = NULL; +		struct rfapi_next_hop_entry *tail = NULL; +		struct rfapi_vn_option *vn_opt_new; + +		vnc_zlog_debug_verbose("%s: rfapi_register succeeded", +				       __func__); + +		if (bgp->rfapi->rfp_methods.local_cb) { +			struct rfapi_descriptor *r = +				(struct rfapi_descriptor *)rfg->rfd; +			vn_opt_new = rfapi_vn_options_dup(opt); + +			rfapiAddDeleteLocalRfpPrefix(&r->un_addr, &r->vn_addr, +						     &rpfx, 1, +						     RFAPI_INFINITE_LIFETIME, +						     vn_opt_new, &head, &tail); +			if (head) { +				bgp->rfapi->flags |= RFAPI_INCALLBACK; +				(*bgp->rfapi->rfp_methods.local_cb)(head, +								    r->cookie); +				bgp->rfapi->flags &= ~RFAPI_INCALLBACK; +			} +			head = tail = NULL; +		} +		vnc_zlog_debug_verbose( +			"%s completed, count=%d/%d", __func__, +			rfg->rfapi_import_table->local_count[AFI_IP], +			rfg->rfapi_import_table->local_count[AFI_IP6]); +		return CMD_SUCCESS; +	} + +	vnc_zlog_debug_verbose("%s: rfapi_register failed", __func__); +	vty_out(vty, "Add failed.\n"); +	return CMD_WARNING_CONFIG_FAILED;  }  DEFUN (add_vrf_prefix_rd_label_pref, @@ -5165,33 +4805,32 @@ DEFUN (add_vrf_prefix_rd_label_pref,         "Set advertised local preference\n"         "local preference (higher=more preferred)\n")  { -  char *arg_vrf    = argv[2]->arg; -  char *arg_prefix = argv[4]->arg; -  char *arg_rd     = NULL;      /* optional */ -  char *arg_label  = NULL;      /* optional */ -  char *arg_pref   = NULL;      /* optional */ -  int  pargc = 5; -  argc--;                        /* don't parse argument */ -  while (pargc < argc)  -    { -      switch (argv[pargc++]->arg[0]) -        { -        case 'r': -          arg_rd    = argv[pargc]->arg; -          break; -        case 'l': -          arg_label = argv[pargc]->arg; -          break; -        case 'p': -          arg_pref  = argv[pargc]->arg; -          break; -        default: -          break; -        } -      pargc ++; -    } -   -  return vnc_add_vrf_prefix (vty, arg_vrf, arg_prefix, arg_rd, arg_label, arg_pref); +	char *arg_vrf = argv[2]->arg; +	char *arg_prefix = argv[4]->arg; +	char *arg_rd = NULL;    /* optional */ +	char *arg_label = NULL; /* optional */ +	char *arg_pref = NULL;  /* optional */ +	int pargc = 5; +	argc--; /* don't parse argument */ +	while (pargc < argc) { +		switch (argv[pargc++]->arg[0]) { +		case 'r': +			arg_rd = argv[pargc]->arg; +			break; +		case 'l': +			arg_label = argv[pargc]->arg; +			break; +		case 'p': +			arg_pref = argv[pargc]->arg; +			break; +		default: +			break; +		} +		pargc++; +	} + +	return vnc_add_vrf_prefix(vty, arg_vrf, arg_prefix, arg_rd, arg_label, +				  arg_pref);  }  /************************************************************************ @@ -5199,89 +4838,78 @@ DEFUN (add_vrf_prefix_rd_label_pref,   *   * clear [vrf <vrf-name>] prefix <prefix> [rd <value>]   ************************************************************************/ -static int -rfapi_cfg_group_it_count(struct rfapi_nve_group_cfg *rfg) +static int rfapi_cfg_group_it_count(struct rfapi_nve_group_cfg *rfg)  { -  int count = 0; -  afi_t afi = AFI_MAX; -  while (afi-- > 0) -    { -      count += rfg->rfapi_import_table->local_count[afi]; -    } -  return count; +	int count = 0; +	afi_t afi = AFI_MAX; +	while (afi-- > 0) { +		count += rfg->rfapi_import_table->local_count[afi]; +	} +	return count;  } -static void -clear_vnc_vrf_closer (struct rfapi_nve_group_cfg *rfg) +static void clear_vnc_vrf_closer(struct rfapi_nve_group_cfg *rfg)  { -  struct rfapi_descriptor *rfd = rfg->rfd; -  afi_t                    afi; - -  if (rfd == NULL) -    return; -  /* check if IT is empty */ -  for (afi = 0;  -       afi < AFI_MAX && rfg->rfapi_import_table->local_count[afi] == 0;  -       afi++); - -  if (afi == AFI_MAX) -    { -      vnc_zlog_debug_verbose ("%s: closing RFD for VRF %s", -                              __func__, rfg->name); -      rfg->rfd = NULL; -      rfapi_close(rfd); -    } -  else -    { -      vnc_zlog_debug_verbose ("%s: VRF %s afi=%d count=%d", -                              __func__, rfg->name, afi,  -                              rfg->rfapi_import_table->local_count[afi]); -    } +	struct rfapi_descriptor *rfd = rfg->rfd; +	afi_t afi; + +	if (rfd == NULL) +		return; +	/* check if IT is empty */ +	for (afi = 0; +	     afi < AFI_MAX && rfg->rfapi_import_table->local_count[afi] == 0; +	     afi++) +		; + +	if (afi == AFI_MAX) { +		vnc_zlog_debug_verbose("%s: closing RFD for VRF %s", __func__, +				       rfg->name); +		rfg->rfd = NULL; +		rfapi_close(rfd); +	} else { +		vnc_zlog_debug_verbose( +			"%s: VRF %s afi=%d count=%d", __func__, rfg->name, afi, +			rfg->rfapi_import_table->local_count[afi]); +	}  } -static int -vnc_clear_vrf (struct vty *vty, -               struct bgp *bgp, -               const char *arg_vrf, -               const char *arg_prefix, /* NULL = all */ -               const char *arg_rd)     /* optional */ +static int vnc_clear_vrf(struct vty *vty, struct bgp *bgp, const char *arg_vrf, +			 const char *arg_prefix, /* NULL = all */ +			 const char *arg_rd)     /* optional */  { -  struct rfapi_nve_group_cfg        *rfg; -  struct rfapi_local_reg_delete_arg  cda; -  int                                rc; -  int                                start_count; - -  if (bgp == NULL) -    bgp = bgp_get_default (); /* assume main instance for now */ -  if (!bgp) -    { -      vty_out (vty, "No BGP process is configured\n"); -      return CMD_WARNING; -    } -  if (!bgp->rfapi || !bgp->rfapi_cfg) -    { -      vty_out (vty, "VRF support not configured\n"); -      return CMD_WARNING; -    } -  rfg = bgp_rfapi_cfg_match_byname (bgp,  arg_vrf, RFAPI_GROUP_CFG_VRF); -  /* arg checks */ -  if (!rfg) -    { -      vty_out (vty, "VRF \"%s\" appears not to be configured.\n", -               arg_vrf); -          return CMD_WARNING; -    } -  rc = parse_deleter_args (vty, bgp, arg_prefix, NULL, NULL, NULL, NULL, -                           arg_rd, rfg, &cda); -  if (rc != CMD_SUCCESS)        /* parse error */ -    return rc; - -  start_count = rfapi_cfg_group_it_count(rfg); -  clear_vnc_prefix (&cda); -  clear_vnc_vrf_closer (rfg); -  vty_out (vty, "Cleared %u out of %d prefixes.\n",  -           cda.pfx_count, start_count); -  return CMD_SUCCESS; +	struct rfapi_nve_group_cfg *rfg; +	struct rfapi_local_reg_delete_arg cda; +	int rc; +	int start_count; + +	if (bgp == NULL) +		bgp = bgp_get_default(); /* assume main instance for now */ +	if (!bgp) { +		vty_out(vty, "No BGP process is configured\n"); +		return CMD_WARNING; +	} +	if (!bgp->rfapi || !bgp->rfapi_cfg) { +		vty_out(vty, "VRF support not configured\n"); +		return CMD_WARNING; +	} +	rfg = bgp_rfapi_cfg_match_byname(bgp, arg_vrf, RFAPI_GROUP_CFG_VRF); +	/* arg checks */ +	if (!rfg) { +		vty_out(vty, "VRF \"%s\" appears not to be configured.\n", +			arg_vrf); +		return CMD_WARNING; +	} +	rc = parse_deleter_args(vty, bgp, arg_prefix, NULL, NULL, NULL, NULL, +				arg_rd, rfg, &cda); +	if (rc != CMD_SUCCESS) /* parse error */ +		return rc; + +	start_count = rfapi_cfg_group_it_count(rfg); +	clear_vnc_prefix(&cda); +	clear_vnc_vrf_closer(rfg); +	vty_out(vty, "Cleared %u out of %d prefixes.\n", cda.pfx_count, +		start_count); +	return CMD_SUCCESS;  }  DEFUN (clear_vrf_prefix_rd, @@ -5296,27 +4924,25 @@ DEFUN (clear_vrf_prefix_rd,         "Specific VRF Route Distinguisher\n"         "<as-number>:<number> or <ip-address>:<number>\n")  { -  char *arg_vrf    = argv[2]->arg; -  char *arg_prefix = NULL;       /* optional */ -  char *arg_rd     = NULL;       /* optional */ -  int  pargc = 3; -  argc--;                       /* don't check parameter */ -  while (pargc < argc)  -    { -      switch (argv[pargc++]->arg[0]) -        { -        case 'r': -          arg_rd     = argv[pargc]->arg; -          break; -        case 'p': -          arg_prefix = argv[pargc]->arg; -          break; -        default: -          break; -        } -      pargc ++; -    } -  return vnc_clear_vrf (vty, NULL, arg_vrf, arg_prefix, arg_rd); +	char *arg_vrf = argv[2]->arg; +	char *arg_prefix = NULL; /* optional */ +	char *arg_rd = NULL;     /* optional */ +	int pargc = 3; +	argc--; /* don't check parameter */ +	while (pargc < argc) { +		switch (argv[pargc++]->arg[0]) { +		case 'r': +			arg_rd = argv[pargc]->arg; +			break; +		case 'p': +			arg_prefix = argv[pargc]->arg; +			break; +		default: +			break; +		} +		pargc++; +	} +	return vnc_clear_vrf(vty, NULL, arg_vrf, arg_prefix, arg_rd);  }  DEFUN (clear_vrf_all, @@ -5327,71 +4953,71 @@ DEFUN (clear_vrf_all,         "VRF name\n"         "All prefixes\n")  { -  char *arg_vrf    = argv[2]->arg; -  return vnc_clear_vrf (vty, NULL, arg_vrf, NULL, NULL); +	char *arg_vrf = argv[2]->arg; +	return vnc_clear_vrf(vty, NULL, arg_vrf, NULL, NULL);  } -void rfapi_vty_init () +void rfapi_vty_init()  { -  install_element (ENABLE_NODE, &add_vnc_prefix_cost_life_lnh_cmd); -  install_element (ENABLE_NODE, &add_vnc_prefix_life_cost_lnh_cmd); -  install_element (ENABLE_NODE, &add_vnc_prefix_cost_lnh_cmd); -  install_element (ENABLE_NODE, &add_vnc_prefix_life_lnh_cmd); -  install_element (ENABLE_NODE, &add_vnc_prefix_lnh_cmd); - -  install_element (ENABLE_NODE, &add_vnc_prefix_cost_life_cmd); -  install_element (ENABLE_NODE, &add_vnc_prefix_life_cost_cmd); -  install_element (ENABLE_NODE, &add_vnc_prefix_cost_cmd); -  install_element (ENABLE_NODE, &add_vnc_prefix_life_cmd); -  install_element (ENABLE_NODE, &add_vnc_prefix_cmd); - -  install_element (ENABLE_NODE, &add_vnc_mac_vni_prefix_cost_life_cmd); -  install_element (ENABLE_NODE, &add_vnc_mac_vni_prefix_life_cmd); -  install_element (ENABLE_NODE, &add_vnc_mac_vni_prefix_cost_cmd); -  install_element (ENABLE_NODE, &add_vnc_mac_vni_prefix_cmd); -  install_element (ENABLE_NODE, &add_vnc_mac_vni_cost_life_cmd); -  install_element (ENABLE_NODE, &add_vnc_mac_vni_cost_cmd); -  install_element (ENABLE_NODE, &add_vnc_mac_vni_life_cmd); -  install_element (ENABLE_NODE, &add_vnc_mac_vni_cmd); - -  install_element (ENABLE_NODE, &add_vrf_prefix_rd_label_pref_cmd); - -  install_element (ENABLE_NODE, &clear_vnc_nve_all_cmd); -  install_element (ENABLE_NODE, &clear_vnc_nve_vn_un_cmd); -  install_element (ENABLE_NODE, &clear_vnc_nve_un_vn_cmd); -  install_element (ENABLE_NODE, &clear_vnc_nve_vn_cmd); -  install_element (ENABLE_NODE, &clear_vnc_nve_un_cmd); - -  install_element (ENABLE_NODE, &clear_vnc_prefix_vn_un_cmd); -  install_element (ENABLE_NODE, &clear_vnc_prefix_un_vn_cmd); -  install_element (ENABLE_NODE, &clear_vnc_prefix_un_cmd); -  install_element (ENABLE_NODE, &clear_vnc_prefix_vn_cmd); -  install_element (ENABLE_NODE, &clear_vnc_prefix_all_cmd); - -  install_element (ENABLE_NODE, &clear_vnc_mac_vn_un_cmd); -  install_element (ENABLE_NODE, &clear_vnc_mac_un_vn_cmd); -  install_element (ENABLE_NODE, &clear_vnc_mac_un_cmd); -  install_element (ENABLE_NODE, &clear_vnc_mac_vn_cmd); -  install_element (ENABLE_NODE, &clear_vnc_mac_all_cmd); - -  install_element (ENABLE_NODE, &clear_vnc_mac_vn_un_prefix_cmd); -  install_element (ENABLE_NODE, &clear_vnc_mac_un_vn_prefix_cmd); -  install_element (ENABLE_NODE, &clear_vnc_mac_un_prefix_cmd); -  install_element (ENABLE_NODE, &clear_vnc_mac_vn_prefix_cmd); -  install_element (ENABLE_NODE, &clear_vnc_mac_all_prefix_cmd); - -  install_element (ENABLE_NODE, &clear_vrf_prefix_rd_cmd); -  install_element (ENABLE_NODE, &clear_vrf_all_cmd); - -  install_element (ENABLE_NODE, &vnc_clear_counters_cmd); - -  install_element (VIEW_NODE, &vnc_show_summary_cmd); -  install_element (VIEW_NODE, &vnc_show_nves_cmd); -  install_element (VIEW_NODE, &vnc_show_nves_ptct_cmd); - -  install_element (VIEW_NODE, &vnc_show_registrations_pfx_cmd); -  install_element (VIEW_NODE, &vnc_show_registrations_some_pfx_cmd); -  install_element (VIEW_NODE, &vnc_show_responses_pfx_cmd); -  install_element (VIEW_NODE, &vnc_show_responses_some_pfx_cmd); -  install_element (VIEW_NODE, &show_vnc_queries_pfx_cmd); +	install_element(ENABLE_NODE, &add_vnc_prefix_cost_life_lnh_cmd); +	install_element(ENABLE_NODE, &add_vnc_prefix_life_cost_lnh_cmd); +	install_element(ENABLE_NODE, &add_vnc_prefix_cost_lnh_cmd); +	install_element(ENABLE_NODE, &add_vnc_prefix_life_lnh_cmd); +	install_element(ENABLE_NODE, &add_vnc_prefix_lnh_cmd); + +	install_element(ENABLE_NODE, &add_vnc_prefix_cost_life_cmd); +	install_element(ENABLE_NODE, &add_vnc_prefix_life_cost_cmd); +	install_element(ENABLE_NODE, &add_vnc_prefix_cost_cmd); +	install_element(ENABLE_NODE, &add_vnc_prefix_life_cmd); +	install_element(ENABLE_NODE, &add_vnc_prefix_cmd); + +	install_element(ENABLE_NODE, &add_vnc_mac_vni_prefix_cost_life_cmd); +	install_element(ENABLE_NODE, &add_vnc_mac_vni_prefix_life_cmd); +	install_element(ENABLE_NODE, &add_vnc_mac_vni_prefix_cost_cmd); +	install_element(ENABLE_NODE, &add_vnc_mac_vni_prefix_cmd); +	install_element(ENABLE_NODE, &add_vnc_mac_vni_cost_life_cmd); +	install_element(ENABLE_NODE, &add_vnc_mac_vni_cost_cmd); +	install_element(ENABLE_NODE, &add_vnc_mac_vni_life_cmd); +	install_element(ENABLE_NODE, &add_vnc_mac_vni_cmd); + +	install_element(ENABLE_NODE, &add_vrf_prefix_rd_label_pref_cmd); + +	install_element(ENABLE_NODE, &clear_vnc_nve_all_cmd); +	install_element(ENABLE_NODE, &clear_vnc_nve_vn_un_cmd); +	install_element(ENABLE_NODE, &clear_vnc_nve_un_vn_cmd); +	install_element(ENABLE_NODE, &clear_vnc_nve_vn_cmd); +	install_element(ENABLE_NODE, &clear_vnc_nve_un_cmd); + +	install_element(ENABLE_NODE, &clear_vnc_prefix_vn_un_cmd); +	install_element(ENABLE_NODE, &clear_vnc_prefix_un_vn_cmd); +	install_element(ENABLE_NODE, &clear_vnc_prefix_un_cmd); +	install_element(ENABLE_NODE, &clear_vnc_prefix_vn_cmd); +	install_element(ENABLE_NODE, &clear_vnc_prefix_all_cmd); + +	install_element(ENABLE_NODE, &clear_vnc_mac_vn_un_cmd); +	install_element(ENABLE_NODE, &clear_vnc_mac_un_vn_cmd); +	install_element(ENABLE_NODE, &clear_vnc_mac_un_cmd); +	install_element(ENABLE_NODE, &clear_vnc_mac_vn_cmd); +	install_element(ENABLE_NODE, &clear_vnc_mac_all_cmd); + +	install_element(ENABLE_NODE, &clear_vnc_mac_vn_un_prefix_cmd); +	install_element(ENABLE_NODE, &clear_vnc_mac_un_vn_prefix_cmd); +	install_element(ENABLE_NODE, &clear_vnc_mac_un_prefix_cmd); +	install_element(ENABLE_NODE, &clear_vnc_mac_vn_prefix_cmd); +	install_element(ENABLE_NODE, &clear_vnc_mac_all_prefix_cmd); + +	install_element(ENABLE_NODE, &clear_vrf_prefix_rd_cmd); +	install_element(ENABLE_NODE, &clear_vrf_all_cmd); + +	install_element(ENABLE_NODE, &vnc_clear_counters_cmd); + +	install_element(VIEW_NODE, &vnc_show_summary_cmd); +	install_element(VIEW_NODE, &vnc_show_nves_cmd); +	install_element(VIEW_NODE, &vnc_show_nves_ptct_cmd); + +	install_element(VIEW_NODE, &vnc_show_registrations_pfx_cmd); +	install_element(VIEW_NODE, &vnc_show_registrations_some_pfx_cmd); +	install_element(VIEW_NODE, &vnc_show_responses_pfx_cmd); +	install_element(VIEW_NODE, &vnc_show_responses_some_pfx_cmd); +	install_element(VIEW_NODE, &show_vnc_queries_pfx_cmd);  } diff --git a/bgpd/rfapi/rfapi_vty.h b/bgpd/rfapi/rfapi_vty.h index 46b77b55ed..a08183aa46 100644 --- a/bgpd/rfapi/rfapi_vty.h +++ b/bgpd/rfapi/rfapi_vty.h @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2009-2016, LabN Consulting, L.L.C.   * @@ -23,74 +23,59 @@  #include "lib/vty.h" -typedef enum -{ -  SHOW_NVE_SUMMARY_ACTIVE_NVES, -  SHOW_NVE_SUMMARY_UNKNOWN_NVES,        /* legacy */ -  SHOW_NVE_SUMMARY_REGISTERED, -  SHOW_NVE_SUMMARY_QUERIES, -  SHOW_NVE_SUMMARY_RESPONSES, -  SHOW_NVE_SUMMARY_MAX +typedef enum { +	SHOW_NVE_SUMMARY_ACTIVE_NVES, +	SHOW_NVE_SUMMARY_UNKNOWN_NVES, /* legacy */ +	SHOW_NVE_SUMMARY_REGISTERED, +	SHOW_NVE_SUMMARY_QUERIES, +	SHOW_NVE_SUMMARY_RESPONSES, +	SHOW_NVE_SUMMARY_MAX  } show_nve_summary_t;  #define VNC_SHOW_STR "VNC information\n" -extern char * -rfapiFormatSeconds (uint32_t seconds, char *buf, size_t len); +extern char *rfapiFormatSeconds(uint32_t seconds, char *buf, size_t len); -extern char * -rfapiFormatAge (time_t age, char *buf, size_t len); +extern char *rfapiFormatAge(time_t age, char *buf, size_t len); -extern void -rfapiRprefixApplyMask (struct rfapi_ip_prefix *rprefix); +extern void rfapiRprefixApplyMask(struct rfapi_ip_prefix *rprefix); -extern int -rfapiQprefix2Raddr (struct prefix *qprefix, struct rfapi_ip_addr *raddr); +extern int rfapiQprefix2Raddr(struct prefix *qprefix, +			      struct rfapi_ip_addr *raddr); -extern void -rfapiQprefix2Rprefix (struct prefix *qprefix, -                      struct rfapi_ip_prefix *rprefix); +extern void rfapiQprefix2Rprefix(struct prefix *qprefix, +				 struct rfapi_ip_prefix *rprefix); -extern int -rfapiRprefix2Qprefix (struct rfapi_ip_prefix *rprefix, -                      struct prefix *qprefix); +extern int rfapiRprefix2Qprefix(struct rfapi_ip_prefix *rprefix, +				struct prefix *qprefix); -extern int -rfapiRaddr2Qprefix (struct rfapi_ip_addr *hia, struct prefix *pfx); +extern int rfapiRaddr2Qprefix(struct rfapi_ip_addr *hia, struct prefix *pfx); -extern int -rfapiRprefixSame (struct rfapi_ip_prefix *hp1, struct rfapi_ip_prefix *hp2); +extern int rfapiRprefixSame(struct rfapi_ip_prefix *hp1, +			    struct rfapi_ip_prefix *hp2); -extern void -rfapiL2o2Qprefix (struct rfapi_l2address_option *l2o, struct prefix *pfx); +extern void rfapiL2o2Qprefix(struct rfapi_l2address_option *l2o, +			     struct prefix *pfx); -extern int -rfapiStr2EthAddr (const char *str, struct ethaddr *ea); +extern int rfapiStr2EthAddr(const char *str, struct ethaddr *ea); -extern const char * -rfapi_ntop ( -    int		af, -    const void	*src, -    char	*buf, -    socklen_t	size); +extern const char *rfapi_ntop(int af, const void *src, char *buf, +			      socklen_t size); -extern int -rfapiDebugPrintf (void *dummy, const char *format, ...); +extern int rfapiDebugPrintf(void *dummy, const char *format, ...); -extern int -rfapiStream2Vty ( -    void	*stream,				/* input */ -    int		(**fp) (void *, const char *, ...),	/* output */ -    struct vty	**vty,					/* output */ -    void	**outstream,				/* output */ -    const char	**vty_newline);				/* output */ +extern int rfapiStream2Vty(void *stream,			  /* input */ +			   int (**fp)(void *, const char *, ...), /* output */ +			   struct vty **vty,			  /* output */ +			   void **outstream,			  /* output */ +			   const char **vty_newline);		  /* output */  /*------------------------------------------   * rfapiRfapiIpAddr2Str   *   * UI helper: generate string from rfapi_ip_addr   * - * input:  + * input:   *	a			IP v4/v6 address   *   * output @@ -101,75 +86,50 @@ rfapiStream2Vty (   *	NULL			conversion failed   *	non-NULL		pointer to buf   --------------------------------------------*/ -extern const char * -rfapiRfapiIpAddr2Str (struct rfapi_ip_addr *a, char *buf, int bufsize); +extern const char *rfapiRfapiIpAddr2Str(struct rfapi_ip_addr *a, char *buf, +					int bufsize); -extern void -rfapiPrintRfapiIpAddr (void *stream, struct rfapi_ip_addr *a); +extern void rfapiPrintRfapiIpAddr(void *stream, struct rfapi_ip_addr *a); -extern void -rfapiPrintRfapiIpPrefix (void *stream, struct rfapi_ip_prefix *p); +extern void rfapiPrintRfapiIpPrefix(void *stream, struct rfapi_ip_prefix *p); -void -rfapiPrintRd (struct vty *vty, struct prefix_rd *prd); +void rfapiPrintRd(struct vty *vty, struct prefix_rd *prd); -extern void -rfapiPrintAdvertisedInfo ( -    struct vty			*vty, -    struct rfapi_descriptor	*rfd, -    safi_t			safi, -    struct prefix		*p); +extern void rfapiPrintAdvertisedInfo(struct vty *vty, +				     struct rfapi_descriptor *rfd, safi_t safi, +				     struct prefix *p); -extern void -rfapiPrintDescriptor (struct vty *vty, struct rfapi_descriptor *rfd); +extern void rfapiPrintDescriptor(struct vty *vty, struct rfapi_descriptor *rfd); -extern void -rfapiPrintMatchingDescriptors (struct vty *vty, -                               struct prefix *vn_prefix, -                               struct prefix *un_prefix); +extern void rfapiPrintMatchingDescriptors(struct vty *vty, +					  struct prefix *vn_prefix, +					  struct prefix *un_prefix); -extern void -rfapiPrintAttrPtrs (void *stream, struct attr *attr); +extern void rfapiPrintAttrPtrs(void *stream, struct attr *attr);  /*   * Parse an address and put into a struct prefix   */ -extern int -rfapiCliGetPrefixAddr (struct vty *vty, const char *str, struct prefix *p); - -extern int -rfapiCliGetRfapiIpAddr ( -    struct vty			*vty, -    const char			*str, -    struct rfapi_ip_addr	*hai); - -extern void -rfapiPrintNhl (void *stream, struct rfapi_next_hop_entry *next_hops); - -extern char * -rfapiMonitorVpn2Str ( -    struct rfapi_monitor_vpn	*m, -    char			*buf, -    int				size); - -extern const char * -rfapiRfapiIpPrefix2Str ( -    struct rfapi_ip_prefix	*p, -    char			*buf, -    int				bufsize); - -extern void -rfapiShowItNode (void *stream, struct route_node *rn); - -extern char * -rfapiEthAddr2Str ( -    const struct ethaddr	*ea, -    char			*buf, -   int				bufsize); +extern int rfapiCliGetPrefixAddr(struct vty *vty, const char *str, +				 struct prefix *p); + +extern int rfapiCliGetRfapiIpAddr(struct vty *vty, const char *str, +				  struct rfapi_ip_addr *hai); + +extern void rfapiPrintNhl(void *stream, struct rfapi_next_hop_entry *next_hops); + +extern char *rfapiMonitorVpn2Str(struct rfapi_monitor_vpn *m, char *buf, +				 int size); + +extern const char *rfapiRfapiIpPrefix2Str(struct rfapi_ip_prefix *p, char *buf, +					  int bufsize); + +extern void rfapiShowItNode(void *stream, struct route_node *rn); + +extern char *rfapiEthAddr2Str(const struct ethaddr *ea, char *buf, int bufsize);  /* install vty commands */ -extern void -rfapi_vty_init (void); +extern void rfapi_vty_init(void);  /*------------------------------------------   * rfapiShowRemoteRegistrations @@ -177,7 +137,7 @@ rfapi_vty_init (void);   * UI helper: produces the "remote" portion of the output   * of "show vnc registrations".   * - * input:  + * input:   *	stream		pointer to output stream   *	prefix_only	pointer to prefix. If non-NULL, print only registrations   *			matching the specified prefix @@ -189,21 +149,17 @@ rfapi_vty_init (void);   *	0		nothing printed   *	>0		something printed   --------------------------------------------*/ -extern int -rfapiShowRemoteRegistrations ( -    void		*stream, -    struct prefix	*prefix_only, -    int			show_expiring, -    int			show_local, -    int			show_remote, -    int			show_imported); +extern int rfapiShowRemoteRegistrations(void *stream, +					struct prefix *prefix_only, +					int show_expiring, int show_local, +					int show_remote, int show_imported);  /*------------------------------------------   * rfapi_monitor_count   *   * UI helper: count number of active monitors   * - * input:  + * input:   *	handle			rfapi handle (NULL to count across   *				all open handles)   * @@ -212,11 +168,9 @@ rfapiShowRemoteRegistrations (   * return value:   *	count of monitors   --------------------------------------------*/ -extern uint32_t -rfapi_monitor_count (rfapi_handle); +extern uint32_t rfapi_monitor_count(rfapi_handle); -extern int -rfapiShowVncQueries (void *stream, struct prefix *pfx_match); +extern int rfapiShowVncQueries(void *stream, struct prefix *pfx_match);  #endif diff --git a/bgpd/rfapi/vnc_debug.c b/bgpd/rfapi/vnc_debug.c index 1f9e1b10fe..d4ff9451c3 100644 --- a/bgpd/rfapi/vnc_debug.c +++ b/bgpd/rfapi/vnc_debug.c @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2016, LabN Consulting, L.L.C.   * @@ -34,19 +34,18 @@ unsigned long conf_vnc_debug;  unsigned long term_vnc_debug;  struct vnc_debug { -	unsigned long	bit; -	const char		*name; +	unsigned long bit; +	const char *name;  }; -struct vnc_debug	vncdebug[] = -{ -	{VNC_DEBUG_RFAPI_QUERY,		"rfapi-query"}, -	{VNC_DEBUG_IMPORT_BI_ATTACH,	"import-bi-attach"}, -	{VNC_DEBUG_IMPORT_DEL_REMOTE,	"import-del-remote"}, -	{VNC_DEBUG_EXPORT_BGP_GETCE,	"export-bgp-getce"}, -	{VNC_DEBUG_EXPORT_BGP_DIRECT_ADD,	"export-bgp-direct-add"}, -	{VNC_DEBUG_IMPORT_BGP_ADD_ROUTE,	"import-bgp-add-route"}, -	{VNC_DEBUG_VERBOSE,         	"verbose"}, +struct vnc_debug vncdebug[] = { +	{VNC_DEBUG_RFAPI_QUERY, "rfapi-query"}, +	{VNC_DEBUG_IMPORT_BI_ATTACH, "import-bi-attach"}, +	{VNC_DEBUG_IMPORT_DEL_REMOTE, "import-del-remote"}, +	{VNC_DEBUG_EXPORT_BGP_GETCE, "export-bgp-getce"}, +	{VNC_DEBUG_EXPORT_BGP_DIRECT_ADD, "export-bgp-direct-add"}, +	{VNC_DEBUG_IMPORT_BGP_ADD_ROUTE, "import-bgp-add-route"}, +	{VNC_DEBUG_VERBOSE, "verbose"},  };  #define VNC_STR "VNC information\n" @@ -65,28 +64,23 @@ DEFUN (debug_bgp_vnc,         "import delete remote routes\n"         "verbose logging\n")  { -  size_t	i; - -  for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i) -    { -      if (strmatch(argv[3]->text, vncdebug[i].name)) -	{ -	  if (vty->node == CONFIG_NODE) -	    { -	      conf_vnc_debug |= vncdebug[i].bit; -	      term_vnc_debug |= vncdebug[i].bit; -	    } -	  else -	    { -	      term_vnc_debug |= vncdebug[i].bit; -	      vty_out (vty, "BGP vnc %s debugging is on\n", -		vncdebug[i].name); -	    } -	  return CMD_SUCCESS; +	size_t i; + +	for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i) { +		if (strmatch(argv[3]->text, vncdebug[i].name)) { +			if (vty->node == CONFIG_NODE) { +				conf_vnc_debug |= vncdebug[i].bit; +				term_vnc_debug |= vncdebug[i].bit; +			} else { +				term_vnc_debug |= vncdebug[i].bit; +				vty_out(vty, "BGP vnc %s debugging is on\n", +					vncdebug[i].name); +			} +			return CMD_SUCCESS; +		}  	} -    } -  vty_out (vty, "Unknown debug flag: %s\n", argv[3]->arg); -  return CMD_WARNING_CONFIG_FAILED; +	vty_out(vty, "Unknown debug flag: %s\n", argv[3]->arg); +	return CMD_WARNING_CONFIG_FAILED;  }  DEFUN (no_debug_bgp_vnc, @@ -102,30 +96,25 @@ DEFUN (no_debug_bgp_vnc,         "import delete remote routes\n"         "verbose logging\n")  { -  size_t	i; - -  if (strmatch(argv[0]->text, "no")) -    argc--, argv++; -  for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i) -    { -      if (strmatch(argv[3]->text, vncdebug[i].name)) -	{ -	  if (vty->node == CONFIG_NODE) -	    { -	      conf_vnc_debug &= ~vncdebug[i].bit; -	      term_vnc_debug &= ~vncdebug[i].bit; -	    } -	  else -	    { -	      term_vnc_debug &= ~vncdebug[i].bit; -	      vty_out (vty, "BGP vnc %s debugging is off\n", -		vncdebug[i].name); -	    } -	  return CMD_SUCCESS; +	size_t i; + +	if (strmatch(argv[0]->text, "no")) +		argc--, argv++; +	for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i) { +		if (strmatch(argv[3]->text, vncdebug[i].name)) { +			if (vty->node == CONFIG_NODE) { +				conf_vnc_debug &= ~vncdebug[i].bit; +				term_vnc_debug &= ~vncdebug[i].bit; +			} else { +				term_vnc_debug &= ~vncdebug[i].bit; +				vty_out(vty, "BGP vnc %s debugging is off\n", +					vncdebug[i].name); +			} +			return CMD_SUCCESS; +		}  	} -    } -  vty_out (vty, "Unknown debug flag: %s\n", argv[3]->arg); -  return CMD_WARNING_CONFIG_FAILED; +	vty_out(vty, "Unknown debug flag: %s\n", argv[3]->arg); +	return CMD_WARNING_CONFIG_FAILED;  } @@ -143,10 +132,10 @@ DEFUN (no_debug_bgp_vnc_all,         BGP_STR         VNC_STR)  { -  term_vnc_debug = 0; -  vty_out (vty, "All possible VNC debugging has been turned off\n"); -       -  return CMD_SUCCESS; +	term_vnc_debug = 0; +	vty_out(vty, "All possible VNC debugging has been turned off\n"); + +	return CMD_SUCCESS;  }  /*********************************************************************** @@ -161,55 +150,44 @@ DEFUN (show_debugging_bgp_vnc,         BGP_STR         VNC_STR)  { -  size_t	i; +	size_t i; -  vty_out (vty, "BGP VNC debugging status:\n"); +	vty_out(vty, "BGP VNC debugging status:\n"); -  for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i) -    { -      if (term_vnc_debug & vncdebug[i].bit) -	{ -	  vty_out (vty, "  BGP VNC %s debugging is on\n", -	    vncdebug[i].name); +	for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i) { +		if (term_vnc_debug & vncdebug[i].bit) { +			vty_out(vty, "  BGP VNC %s debugging is on\n", +				vncdebug[i].name); +		}  	} -    } -  vty_out (vty, "\n"); -  return CMD_SUCCESS; +	vty_out(vty, "\n"); +	return CMD_SUCCESS;  } -static int -bgp_vnc_config_write_debug (struct vty *vty) +static int bgp_vnc_config_write_debug(struct vty *vty)  { -  int write = 0; -  size_t	i; - -  for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i) -    { -      if (conf_vnc_debug & vncdebug[i].bit) -	{ -	  vty_out (vty, "debug bgp vnc %s\n", vncdebug[i].name); -	  write++; +	int write = 0; +	size_t i; + +	for (i = 0; i < (sizeof(vncdebug) / sizeof(struct vnc_debug)); ++i) { +		if (conf_vnc_debug & vncdebug[i].bit) { +			vty_out(vty, "debug bgp vnc %s\n", vncdebug[i].name); +			write++; +		}  	} -    } -  return write; +	return write;  } -static struct cmd_node debug_node = -{ -  DEBUG_VNC_NODE, -  "", -  1 -}; +static struct cmd_node debug_node = {DEBUG_VNC_NODE, "", 1}; -void -vnc_debug_init (void) +void vnc_debug_init(void)  { -  install_node (&debug_node, bgp_vnc_config_write_debug); -  install_element (ENABLE_NODE, &show_debugging_bgp_vnc_cmd); +	install_node(&debug_node, bgp_vnc_config_write_debug); +	install_element(ENABLE_NODE, &show_debugging_bgp_vnc_cmd); -  install_element (ENABLE_NODE, &debug_bgp_vnc_cmd); -  install_element (CONFIG_NODE, &debug_bgp_vnc_cmd); -  install_element (ENABLE_NODE, &no_debug_bgp_vnc_cmd); +	install_element(ENABLE_NODE, &debug_bgp_vnc_cmd); +	install_element(CONFIG_NODE, &debug_bgp_vnc_cmd); +	install_element(ENABLE_NODE, &no_debug_bgp_vnc_cmd); -  install_element (ENABLE_NODE, &no_debug_bgp_vnc_all_cmd); +	install_element(ENABLE_NODE, &no_debug_bgp_vnc_all_cmd);  } diff --git a/bgpd/rfapi/vnc_debug.h b/bgpd/rfapi/vnc_debug.h index c1d81f5c15..dd49383072 100644 --- a/bgpd/rfapi/vnc_debug.h +++ b/bgpd/rfapi/vnc_debug.h @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2016, LabN Consulting, L.L.C.   * @@ -44,8 +44,7 @@ extern unsigned long term_vnc_debug;  #define vnc_zlog_debug_verbose  if (VNC_DEBUG(VERBOSE)) zlog_debug  #define vnc_zlog_debug_any      if (VNC_DEBUG(ANY)) zlog_debug -extern void -vnc_debug_init (void); +extern void vnc_debug_init(void);  #endif /* ENABLE_BGP_VNC */ diff --git a/bgpd/rfapi/vnc_export_bgp.c b/bgpd/rfapi/vnc_export_bgp.c index 342dc6a193..b699cec9e7 100644 --- a/bgpd/rfapi/vnc_export_bgp.c +++ b/bgpd/rfapi/vnc_export_bgp.c @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2009-2016, LabN Consulting, L.L.C.   * @@ -63,472 +63,441 @@   *	- strip Tunnel Encap attr   *	- copy all ECs   */ -static void -encap_attr_export_ce ( -    struct attr		*new, -    struct attr		*orig, -    struct prefix	*use_nexthop) +static void encap_attr_export_ce(struct attr *new, struct attr *orig, +				 struct prefix *use_nexthop)  { -  /* -   * Make "new" a ghost attr copy of "orig" -   */ -  memset (new, 0, sizeof (struct attr)); -  bgp_attr_dup (new, orig); - -  /* -   * Set nexthop -   */ -  switch (use_nexthop->family) -    { -    case AF_INET: -      new->nexthop = use_nexthop->u.prefix4; -      new->mp_nexthop_len = 4;   /* bytes */ -      new->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP); -      break; - -    case AF_INET6: -      new->mp_nexthop_global = use_nexthop->u.prefix6; -      new->mp_nexthop_len = 16;  /* bytes */ -      break; - -    default: -      assert (0); -      break; -    } - -  /* -   * Set MED -   * -   * Note that it will be deleted when BGP sends to any eBGP -   * peer unless PEER_FLAG_MED_UNCHANGED is set: -   * -   *          neighbor NEIGHBOR attribute-unchanged med -   */ -  if (!CHECK_FLAG (new->flag, BGP_ATTR_MULTI_EXIT_DISC)) -    { -      if (CHECK_FLAG (new->flag, BGP_ATTR_LOCAL_PREF)) -        { -          if (new->local_pref > 255) -            new->med = 0; -          else -            new->med = 255 - new->local_pref; -        } -      else -        { -          new->med = 255;       /* shouldn't happen */ -        } -      new->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC); -    } - -  /* -   * "new" is now a ghost attr: -   *  - it owns an "extra" struct -   *  - it owns any non-interned parts -   *  - any references to interned parts are not counted -   * -   * Caller should, after using the attr, call: -   *  - bgp_attr_flush() to free non-interned parts -   */ +	/* +	 * Make "new" a ghost attr copy of "orig" +	 */ +	memset(new, 0, sizeof(struct attr)); +	bgp_attr_dup(new, orig); + +	/* +	 * Set nexthop +	 */ +	switch (use_nexthop->family) { +	case AF_INET: +		new->nexthop = use_nexthop->u.prefix4; +		new->mp_nexthop_len = 4; /* bytes */ +		new->flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP); +		break; + +	case AF_INET6: +		new->mp_nexthop_global = use_nexthop->u.prefix6; +		new->mp_nexthop_len = 16; /* bytes */ +		break; + +	default: +		assert(0); +		break; +	} + +	/* +	 * Set MED +	 * +	 * Note that it will be deleted when BGP sends to any eBGP +	 * peer unless PEER_FLAG_MED_UNCHANGED is set: +	 * +	 *          neighbor NEIGHBOR attribute-unchanged med +	 */ +	if (!CHECK_FLAG(new->flag, BGP_ATTR_MULTI_EXIT_DISC)) { +		if (CHECK_FLAG(new->flag, BGP_ATTR_LOCAL_PREF)) { +			if (new->local_pref > 255) +				new->med = 0; +			else +				new->med = 255 - new->local_pref; +		} else { +			new->med = 255; /* shouldn't happen */ +		} +		new->flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC); +	} + +	/* +	 * "new" is now a ghost attr: +	 *  - it owns an "extra" struct +	 *  - it owns any non-interned parts +	 *  - any references to interned parts are not counted +	 * +	 * Caller should, after using the attr, call: +	 *  - bgp_attr_flush() to free non-interned parts +	 */  } -static int -getce (struct bgp *bgp, struct attr *attr, struct prefix *pfx_ce) +static int getce(struct bgp *bgp, struct attr *attr, struct prefix *pfx_ce)  { -  uint8_t *ecp; -  int i; -  uint16_t localadmin = bgp->rfapi_cfg->resolve_nve_roo_local_admin; - -  for (ecp = attr->ecommunity->val, i = 0; -       i < attr->ecommunity->size; ++i, ecp += ECOMMUNITY_SIZE) -    { - -      if (VNC_DEBUG(EXPORT_BGP_GETCE)) -	{ -	  vnc_zlog_debug_any ("%s: %02x %02x %02x %02x %02x %02x %02x %02x", -                  __func__, -                  ecp[0], ecp[1], ecp[2], ecp[3], ecp[4], ecp[5], ecp[6], -                  ecp[7]); -	} - -      /* -       * is it ROO? -       */ -      if (ecp[0] != 1 || ecp[1] != 3) -        { -          continue; -        } - -      /* -       * Match local admin value? -       */ -      if (ecp[6] != ((localadmin & 0xff00) >> 8) || -          ecp[7] != (localadmin & 0xff)) -        continue; - -      memset ((uint8_t *) pfx_ce, 0, sizeof (*pfx_ce)); -      memcpy (&pfx_ce->u.prefix4, ecp + 2, 4); -      pfx_ce->family = AF_INET; -      pfx_ce->prefixlen = 32; - -      return 0; -    } -  return -1; +	uint8_t *ecp; +	int i; +	uint16_t localadmin = bgp->rfapi_cfg->resolve_nve_roo_local_admin; + +	for (ecp = attr->ecommunity->val, i = 0; i < attr->ecommunity->size; +	     ++i, ecp += ECOMMUNITY_SIZE) { + +		if (VNC_DEBUG(EXPORT_BGP_GETCE)) { +			vnc_zlog_debug_any( +				"%s: %02x %02x %02x %02x %02x %02x %02x %02x", +				__func__, ecp[0], ecp[1], ecp[2], ecp[3], +				ecp[4], ecp[5], ecp[6], ecp[7]); +		} + +		/* +		 * is it ROO? +		 */ +		if (ecp[0] != 1 || ecp[1] != 3) { +			continue; +		} + +		/* +		 * Match local admin value? +		 */ +		if (ecp[6] != ((localadmin & 0xff00) >> 8) +		    || ecp[7] != (localadmin & 0xff)) +			continue; + +		memset((uint8_t *)pfx_ce, 0, sizeof(*pfx_ce)); +		memcpy(&pfx_ce->u.prefix4, ecp + 2, 4); +		pfx_ce->family = AF_INET; +		pfx_ce->prefixlen = 32; + +		return 0; +	} +	return -1;  } -void -vnc_direct_bgp_add_route_ce ( -    struct bgp		*bgp, -    struct route_node	*rn, -    struct bgp_info	*bi) +void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct route_node *rn, +				 struct bgp_info *bi)  { -  struct attr *attr = bi->attr; -  struct peer *peer = bi->peer; -  struct prefix *prefix = &rn->p; -  afi_t afi = family2afi (prefix->family); -  struct bgp_node *urn; -  struct bgp_info *ubi; -  struct attr hattr; -  struct attr *iattr; -  struct prefix ce_nexthop; -  struct prefix post_routemap_nexthop; - - -  if (!afi) -    { -      zlog_err ("%s: can't get afi of route node", __func__); -      return; -    } - -  if ((bi->type != ZEBRA_ROUTE_BGP) || -      (bi->sub_type != BGP_ROUTE_NORMAL && -       bi->sub_type != BGP_ROUTE_RFP && bi->sub_type != BGP_ROUTE_STATIC)) -    { - -      vnc_zlog_debug_verbose ("%s: wrong route type/sub_type for export, skipping", -                  __func__); -      return; -    } - -  /* check bgp redist flag for vnc direct ("vpn") routes */ -  if (!bgp->redist[afi][ZEBRA_ROUTE_VNC_DIRECT]) -    { -      vnc_zlog_debug_verbose ("%s: bgp redistribution of VNC direct routes is off", -                  __func__); -      return; -    } - -  if (!bgp->rfapi_cfg) -    { -      vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); -      return; -    } - -  if (!VNC_EXPORT_BGP_CE_ENABLED (bgp->rfapi_cfg)) -    { -      vnc_zlog_debug_verbose ("%s: export-to-bgp ce mode not enabled, skipping", -                  __func__); -      return; -    } - -  /* -   * prefix list check -   */ -  if (bgp->rfapi_cfg->plist_export_bgp[afi]) -    { -      if (prefix_list_apply (bgp->rfapi_cfg->plist_export_bgp[afi], prefix) == -          PREFIX_DENY) -        { -          vnc_zlog_debug_verbose ("%s: prefix list denied, skipping", __func__); -          return; -        } -    } - - -  /* -   * Extract CE -   * This works only for IPv4 because IPv6 addresses are too big -   * to fit in an extended community -   */ -  if (getce (bgp, attr, &ce_nexthop)) -    { -      vnc_zlog_debug_verbose ("%s: EC has no encoded CE, skipping", __func__); -      return; -    } - -  /* -   * Is this route already represented in the unicast RIB? -   * (look up prefix; compare route type, sub_type, peer, nexthop) -   */ -  urn = -    bgp_afi_node_get (bgp->rib[afi][SAFI_UNICAST], afi, SAFI_UNICAST, prefix, -                      NULL); -  for (ubi = urn->info; ubi; ubi = ubi->next) -    { -      struct prefix unicast_nexthop; - -      if (CHECK_FLAG (ubi->flags, BGP_INFO_REMOVED)) -        continue; - -      rfapiUnicastNexthop2Prefix (afi, ubi->attr, &unicast_nexthop); - -      if (ubi->type == ZEBRA_ROUTE_VNC_DIRECT && -          ubi->sub_type == BGP_ROUTE_REDISTRIBUTE && -          ubi->peer == peer && prefix_same (&unicast_nexthop, &ce_nexthop)) -        { - -          vnc_zlog_debug_verbose -            ("%s: already have matching exported unicast route, skipping", -             __func__); -          return; -        } -    } - -  /* -   * Construct new attribute set with CE addr as -   * nexthop and without Tunnel Encap attr -   */ -  encap_attr_export_ce (&hattr, attr, &ce_nexthop); -  if (bgp->rfapi_cfg->routemap_export_bgp) -    { -      struct bgp_info info; -      route_map_result_t ret; - -      memset (&info, 0, sizeof (info)); -      info.peer = peer; -      info.attr = &hattr; -      ret = -        route_map_apply (bgp->rfapi_cfg->routemap_export_bgp, prefix, -                         RMAP_BGP, &info); -      if (ret == RMAP_DENYMATCH) -        { -          bgp_attr_flush (&hattr); -          return; -        } -    } - -  iattr = bgp_attr_intern (&hattr); -  bgp_attr_flush (&hattr); - -  /* -   * Rule: disallow route-map alteration of next-hop, because it -   * would make it too difficult to keep track of the correspondence -   * between VPN routes and unicast routes. -   */ -  rfapiUnicastNexthop2Prefix (afi, iattr, &post_routemap_nexthop); - -  if (!prefix_same (&ce_nexthop, &post_routemap_nexthop)) -    { -      vnc_zlog_debug_verbose -        ("%s: route-map modification of nexthop not allowed, skipping", -         __func__); -      bgp_attr_unintern (&iattr); -      return; -    } - -  bgp_update (peer, prefix,   -              0,                /* addpath_id */ -              iattr,      /* bgp_update copies this attr */ -              afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL,  /* RD not used for unicast */ -              NULL,             /* tag not used for unicast */ -              0, NULL);         /* EVPN not used */ -  bgp_attr_unintern (&iattr); +	struct attr *attr = bi->attr; +	struct peer *peer = bi->peer; +	struct prefix *prefix = &rn->p; +	afi_t afi = family2afi(prefix->family); +	struct bgp_node *urn; +	struct bgp_info *ubi; +	struct attr hattr; +	struct attr *iattr; +	struct prefix ce_nexthop; +	struct prefix post_routemap_nexthop; + + +	if (!afi) { +		zlog_err("%s: can't get afi of route node", __func__); +		return; +	} + +	if ((bi->type != ZEBRA_ROUTE_BGP) +	    || (bi->sub_type != BGP_ROUTE_NORMAL +		&& bi->sub_type != BGP_ROUTE_RFP +		&& bi->sub_type != BGP_ROUTE_STATIC)) { + +		vnc_zlog_debug_verbose( +			"%s: wrong route type/sub_type for export, skipping", +			__func__); +		return; +	} + +	/* check bgp redist flag for vnc direct ("vpn") routes */ +	if (!bgp->redist[afi][ZEBRA_ROUTE_VNC_DIRECT]) { +		vnc_zlog_debug_verbose( +			"%s: bgp redistribution of VNC direct routes is off", +			__func__); +		return; +	} + +	if (!bgp->rfapi_cfg) { +		vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", +				       __func__); +		return; +	} + +	if (!VNC_EXPORT_BGP_CE_ENABLED(bgp->rfapi_cfg)) { +		vnc_zlog_debug_verbose( +			"%s: export-to-bgp ce mode not enabled, skipping", +			__func__); +		return; +	} + +	/* +	 * prefix list check +	 */ +	if (bgp->rfapi_cfg->plist_export_bgp[afi]) { +		if (prefix_list_apply(bgp->rfapi_cfg->plist_export_bgp[afi], +				      prefix) +		    == PREFIX_DENY) { +			vnc_zlog_debug_verbose( +				"%s: prefix list denied, skipping", __func__); +			return; +		} +	} + + +	/* +	 * Extract CE +	 * This works only for IPv4 because IPv6 addresses are too big +	 * to fit in an extended community +	 */ +	if (getce(bgp, attr, &ce_nexthop)) { +		vnc_zlog_debug_verbose("%s: EC has no encoded CE, skipping", +				       __func__); +		return; +	} + +	/* +	 * Is this route already represented in the unicast RIB? +	 * (look up prefix; compare route type, sub_type, peer, nexthop) +	 */ +	urn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi, SAFI_UNICAST, +			       prefix, NULL); +	for (ubi = urn->info; ubi; ubi = ubi->next) { +		struct prefix unicast_nexthop; + +		if (CHECK_FLAG(ubi->flags, BGP_INFO_REMOVED)) +			continue; + +		rfapiUnicastNexthop2Prefix(afi, ubi->attr, &unicast_nexthop); + +		if (ubi->type == ZEBRA_ROUTE_VNC_DIRECT +		    && ubi->sub_type == BGP_ROUTE_REDISTRIBUTE +		    && ubi->peer == peer +		    && prefix_same(&unicast_nexthop, &ce_nexthop)) { + +			vnc_zlog_debug_verbose( +				"%s: already have matching exported unicast route, skipping", +				__func__); +			return; +		} +	} + +	/* +	 * Construct new attribute set with CE addr as +	 * nexthop and without Tunnel Encap attr +	 */ +	encap_attr_export_ce(&hattr, attr, &ce_nexthop); +	if (bgp->rfapi_cfg->routemap_export_bgp) { +		struct bgp_info info; +		route_map_result_t ret; + +		memset(&info, 0, sizeof(info)); +		info.peer = peer; +		info.attr = &hattr; +		ret = route_map_apply(bgp->rfapi_cfg->routemap_export_bgp, +				      prefix, RMAP_BGP, &info); +		if (ret == RMAP_DENYMATCH) { +			bgp_attr_flush(&hattr); +			return; +		} +	} + +	iattr = bgp_attr_intern(&hattr); +	bgp_attr_flush(&hattr); + +	/* +	 * Rule: disallow route-map alteration of next-hop, because it +	 * would make it too difficult to keep track of the correspondence +	 * between VPN routes and unicast routes. +	 */ +	rfapiUnicastNexthop2Prefix(afi, iattr, &post_routemap_nexthop); + +	if (!prefix_same(&ce_nexthop, &post_routemap_nexthop)) { +		vnc_zlog_debug_verbose( +			"%s: route-map modification of nexthop not allowed, skipping", +			__func__); +		bgp_attr_unintern(&iattr); +		return; +	} + +	bgp_update(peer, prefix, 0, /* addpath_id */ +		   iattr,	   /* bgp_update copies this attr */ +		   afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT, +		   BGP_ROUTE_REDISTRIBUTE, NULL, /* RD not used for unicast */ +		   NULL,			 /* tag not used for unicast */ +		   0, NULL);			 /* EVPN not used */ +	bgp_attr_unintern(&iattr);  }  /*   * "Withdrawing a Route" export process   */ -void -vnc_direct_bgp_del_route_ce ( -    struct bgp		*bgp, -    struct route_node	*rn, -    struct bgp_info	*bi) +void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct route_node *rn, +				 struct bgp_info *bi)  { -  afi_t afi = family2afi (rn->p.family); -  struct bgp_info *vbi; -  struct prefix ce_nexthop; - -  if (!afi) -    { -      zlog_err ("%s: bad afi", __func__); -      return; -    } - -  /* check bgp redist flag for vnc direct ("vpn") routes */ -  if (!bgp->redist[afi][ZEBRA_ROUTE_VNC_DIRECT]) -    { -      vnc_zlog_debug_verbose ("%s: bgp redistribution of VNC direct routes is off", -                  __func__); -      return; -    } - -  if (!bgp->rfapi_cfg) -    { -      vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); -      return; -    } -  if (!VNC_EXPORT_BGP_CE_ENABLED (bgp->rfapi_cfg)) -    { -      vnc_zlog_debug_verbose ("%s: export-to-bgp ce mode not enabled, skipping", -                  __func__); -      return; -    } - -  /* -   * Extract CE -   * This works only for IPv4 because IPv6 addresses are too big -   * to fit in an extended community -   */ -  if (getce (bgp, bi->attr, &ce_nexthop)) -    { -      vnc_zlog_debug_verbose ("%s: EC has no encoded CE, skipping", __func__); -      return; -    } - -  /* -   * Look for other VPN routes with same prefix, same 5226 CE, -   * same peer. If at least one is present, don't remove the -   * route from the unicast RIB -   */ - -  for (vbi = rn->info; vbi; vbi = vbi->next) -    { -      struct prefix ce; -      if (bi == vbi) -        continue; -      if (bi->peer != vbi->peer) -        continue; -      if (getce (bgp, vbi->attr, &ce)) -        continue; -      if (prefix_same (&ce, &ce_nexthop)) -        { -          vnc_zlog_debug_verbose ("%s: still have a route via CE, not deleting unicast", -                      __func__); -          return; -        } -    } - -  /* -   * withdraw the route -   */ -  bgp_withdraw (bi->peer, &rn->p,  -                0,                /* addpath_id */ -                NULL, /* attr, ignored */ -                afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL,        /* RD not used for unicast */ -                NULL, NULL);          /* tag not used for unicast */ +	afi_t afi = family2afi(rn->p.family); +	struct bgp_info *vbi; +	struct prefix ce_nexthop; + +	if (!afi) { +		zlog_err("%s: bad afi", __func__); +		return; +	} + +	/* check bgp redist flag for vnc direct ("vpn") routes */ +	if (!bgp->redist[afi][ZEBRA_ROUTE_VNC_DIRECT]) { +		vnc_zlog_debug_verbose( +			"%s: bgp redistribution of VNC direct routes is off", +			__func__); +		return; +	} + +	if (!bgp->rfapi_cfg) { +		vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", +				       __func__); +		return; +	} +	if (!VNC_EXPORT_BGP_CE_ENABLED(bgp->rfapi_cfg)) { +		vnc_zlog_debug_verbose( +			"%s: export-to-bgp ce mode not enabled, skipping", +			__func__); +		return; +	} + +	/* +	 * Extract CE +	 * This works only for IPv4 because IPv6 addresses are too big +	 * to fit in an extended community +	 */ +	if (getce(bgp, bi->attr, &ce_nexthop)) { +		vnc_zlog_debug_verbose("%s: EC has no encoded CE, skipping", +				       __func__); +		return; +	} + +	/* +	 * Look for other VPN routes with same prefix, same 5226 CE, +	 * same peer. If at least one is present, don't remove the +	 * route from the unicast RIB +	 */ + +	for (vbi = rn->info; vbi; vbi = vbi->next) { +		struct prefix ce; +		if (bi == vbi) +			continue; +		if (bi->peer != vbi->peer) +			continue; +		if (getce(bgp, vbi->attr, &ce)) +			continue; +		if (prefix_same(&ce, &ce_nexthop)) { +			vnc_zlog_debug_verbose( +				"%s: still have a route via CE, not deleting unicast", +				__func__); +			return; +		} +	} +	/* +	 * withdraw the route +	 */ +	bgp_withdraw(bi->peer, &rn->p, 0, /* addpath_id */ +		     NULL,		  /* attr, ignored */ +		     afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT, +		     BGP_ROUTE_REDISTRIBUTE, NULL, /* RD not used for unicast */ +		     NULL, NULL); /* tag not used for unicast */  } -static void -vnc_direct_bgp_vpn_enable_ce (struct bgp *bgp, afi_t afi) +static void vnc_direct_bgp_vpn_enable_ce(struct bgp *bgp, afi_t afi)  { -  struct rfapi_cfg *hc; -  struct route_node *rn; -  struct bgp_info *ri; +	struct rfapi_cfg *hc; +	struct route_node *rn; +	struct bgp_info *ri; -  vnc_zlog_debug_verbose ("%s: entry, afi=%d", __func__, afi); +	vnc_zlog_debug_verbose("%s: entry, afi=%d", __func__, afi); -  if (!bgp) -    return; +	if (!bgp) +		return; -  if (!(hc = bgp->rfapi_cfg)) -    return; +	if (!(hc = bgp->rfapi_cfg)) +		return; -  if (!VNC_EXPORT_BGP_CE_ENABLED (bgp->rfapi_cfg)) -    { -      vnc_zlog_debug_verbose ("%s: export of CE routes not enabled, skipping", __func__); -      return; -    } - -  if (afi != AFI_IP -      && afi != AFI_IP6) -    { -      vnc_zlog_debug_verbose ("%s: bad afi: %d", __func__, afi); -      return; -    } +	if (!VNC_EXPORT_BGP_CE_ENABLED(bgp->rfapi_cfg)) { +		vnc_zlog_debug_verbose( +			"%s: export of CE routes not enabled, skipping", +			__func__); +		return; +	} -  /* -   * Go through entire ce import table and export to BGP unicast. -   */ -  for (rn = route_top (bgp->rfapi->it_ce->imported_vpn[afi]); rn; -       rn = route_next (rn)) -    { +	if (afi != AFI_IP && afi != AFI_IP6) { +		vnc_zlog_debug_verbose("%s: bad afi: %d", __func__, afi); +		return; +	} -      if (!rn->info) -        continue; +	/* +	 * Go through entire ce import table and export to BGP unicast. +	 */ +	for (rn = route_top(bgp->rfapi->it_ce->imported_vpn[afi]); rn; +	     rn = route_next(rn)) { -      { -        char prefixstr[BUFSIZ]; +		if (!rn->info) +			continue; -        prefixstr[0] = 0; -        inet_ntop (rn->p.family, &rn->p.u.prefix, prefixstr, BUFSIZ); -        vnc_zlog_debug_verbose ("%s: checking prefix %s/%d", __func__, prefixstr, -                    rn->p.prefixlen); -      } +		{ +			char prefixstr[BUFSIZ]; -      for (ri = rn->info; ri; ri = ri->next) -        { +			prefixstr[0] = 0; +			inet_ntop(rn->p.family, &rn->p.u.prefix, prefixstr, +				  BUFSIZ); +			vnc_zlog_debug_verbose("%s: checking prefix %s/%d", +					       __func__, prefixstr, +					       rn->p.prefixlen); +		} -          vnc_zlog_debug_verbose ("%s: ri->sub_type: %d", __func__, ri->sub_type); +		for (ri = rn->info; ri; ri = ri->next) { -          if (ri->sub_type == BGP_ROUTE_NORMAL || -              ri->sub_type == BGP_ROUTE_RFP || -              ri->sub_type == BGP_ROUTE_STATIC) -            { +			vnc_zlog_debug_verbose("%s: ri->sub_type: %d", __func__, +					       ri->sub_type); -              vnc_direct_bgp_add_route_ce (bgp, rn, ri); -            } +			if (ri->sub_type == BGP_ROUTE_NORMAL +			    || ri->sub_type == BGP_ROUTE_RFP +			    || ri->sub_type == BGP_ROUTE_STATIC) { -        } -    } +				vnc_direct_bgp_add_route_ce(bgp, rn, ri); +			} +		} +	}  } -static void -vnc_direct_bgp_vpn_disable_ce (struct bgp *bgp, afi_t afi) +static void vnc_direct_bgp_vpn_disable_ce(struct bgp *bgp, afi_t afi)  { -  struct bgp_node *rn; - -  vnc_zlog_debug_verbose ("%s: entry, afi=%d", __func__, afi); - -  if (!bgp) -    return; - -  if (afi != AFI_IP -      && afi != AFI_IP6) -    { -      vnc_zlog_debug_verbose ("%s: bad afi: %d", __func__, afi); -      return; -    } - -  /* -   * Go through the entire BGP unicast table and remove routes that -   * originated from us -   */ -  for (rn = bgp_table_top (bgp->rib[afi][SAFI_UNICAST]); rn; -       rn = bgp_route_next (rn)) -    { - -      struct bgp_info *ri; -      struct bgp_info *next; - -      for (ri = rn->info, next = NULL; ri; ri = next) -        { - -          next = ri->next; - -          if (ri->type == ZEBRA_ROUTE_VNC_DIRECT && -              ri->sub_type == BGP_ROUTE_REDISTRIBUTE) -            { - -              bgp_withdraw (ri->peer, &rn->p,   /* prefix */ -                            0,                /* addpath_id */ -                            NULL,       /* ignored */ -                            AFI_IP, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL, /* RD not used for unicast */ -                            NULL, NULL);      /* tag not used for unicast */ -            } -        } -    } +	struct bgp_node *rn; + +	vnc_zlog_debug_verbose("%s: entry, afi=%d", __func__, afi); + +	if (!bgp) +		return; + +	if (afi != AFI_IP && afi != AFI_IP6) { +		vnc_zlog_debug_verbose("%s: bad afi: %d", __func__, afi); +		return; +	} + +	/* +	 * Go through the entire BGP unicast table and remove routes that +	 * originated from us +	 */ +	for (rn = bgp_table_top(bgp->rib[afi][SAFI_UNICAST]); rn; +	     rn = bgp_route_next(rn)) { + +		struct bgp_info *ri; +		struct bgp_info *next; + +		for (ri = rn->info, next = NULL; ri; ri = next) { + +			next = ri->next; + +			if (ri->type == ZEBRA_ROUTE_VNC_DIRECT +			    && ri->sub_type == BGP_ROUTE_REDISTRIBUTE) { + +				bgp_withdraw( +					ri->peer, &rn->p, /* prefix */ +					0,		  /* addpath_id */ +					NULL,		  /* ignored */ +					AFI_IP, SAFI_UNICAST, +					ZEBRA_ROUTE_VNC_DIRECT, +					BGP_ROUTE_REDISTRIBUTE, +					NULL, /* RD not used for unicast */ +					NULL, +					NULL); /* tag not used for unicast */ +			} +		} +	}  }  /*********************************************************************** @@ -539,73 +508,68 @@ vnc_direct_bgp_vpn_disable_ce (struct bgp *bgp, afi_t afi)   * Export methods that proxy nexthop BEGIN   ***********************************************************************/ -static struct ecommunity * -vnc_route_origin_ecom (struct route_node *rn) +static struct ecommunity *vnc_route_origin_ecom(struct route_node *rn)  { -  struct ecommunity *new; -  struct bgp_info *bi; - -  if (!rn->info) -    return NULL; - -  new = ecommunity_new (); - -  for (bi = rn->info; bi; bi = bi->next) -    { - -      struct ecommunity_val roec; - -      switch (BGP_MP_NEXTHOP_FAMILY (bi->attr->mp_nexthop_len)) -        { -        case AF_INET: -          memset (&roec, 0, sizeof (roec)); -          roec.val[0] = 0x01; -          roec.val[1] = 0x03; -          memcpy (roec.val + 2, -                  &bi->attr->mp_nexthop_global_in.s_addr, 4); -          roec.val[6] = 0; -          roec.val[7] = 0; -          ecommunity_add_val (new, &roec); -          break; -        case AF_INET6: -          /* No support for IPv6 addresses in extended communities */ -          break; -        } -    } - -  if (!new->size) -    { -      ecommunity_free (&new); -      new = NULL; -    } - -  return new; +	struct ecommunity *new; +	struct bgp_info *bi; + +	if (!rn->info) +		return NULL; + +	new = ecommunity_new(); + +	for (bi = rn->info; bi; bi = bi->next) { + +		struct ecommunity_val roec; + +		switch (BGP_MP_NEXTHOP_FAMILY(bi->attr->mp_nexthop_len)) { +		case AF_INET: +			memset(&roec, 0, sizeof(roec)); +			roec.val[0] = 0x01; +			roec.val[1] = 0x03; +			memcpy(roec.val + 2, +			       &bi->attr->mp_nexthop_global_in.s_addr, 4); +			roec.val[6] = 0; +			roec.val[7] = 0; +			ecommunity_add_val(new, &roec); +			break; +		case AF_INET6: +			/* No support for IPv6 addresses in extended communities +			 */ +			break; +		} +	} + +	if (!new->size) { +		ecommunity_free(&new); +		new = NULL; +	} + +	return new;  } -static struct ecommunity * -vnc_route_origin_ecom_single (struct in_addr *origin) +static struct ecommunity *vnc_route_origin_ecom_single(struct in_addr *origin)  { -  struct ecommunity *new; -  struct ecommunity_val roec; - -  memset (&roec, 0, sizeof (roec)); -  roec.val[0] = 0x01; -  roec.val[1] = 0x03; -  memcpy (roec.val + 2, &origin->s_addr, 4); -  roec.val[6] = 0; -  roec.val[7] = 0; - -  new = ecommunity_new (); -  assert (new); -  ecommunity_add_val (new, &roec); - -  if (!new->size) -    { -      ecommunity_free (&new); -      new = NULL; -    } - -  return new; +	struct ecommunity *new; +	struct ecommunity_val roec; + +	memset(&roec, 0, sizeof(roec)); +	roec.val[0] = 0x01; +	roec.val[1] = 0x03; +	memcpy(roec.val + 2, &origin->s_addr, 4); +	roec.val[6] = 0; +	roec.val[7] = 0; + +	new = ecommunity_new(); +	assert(new); +	ecommunity_add_val(new, &roec); + +	if (!new->size) { +		ecommunity_free(&new); +		new = NULL; +	} + +	return new;  } @@ -615,750 +579,722 @@ vnc_route_origin_ecom_single (struct in_addr *origin)   * memory is allocated by caller.   */  static int -encap_attr_export ( -    struct attr		*new, -    struct attr		*orig, -    struct prefix	*new_nexthop, -    struct route_node	*rn)		/* for VN addrs for ecom list */ -					/* if rn is 0, use route's nexthop */ +encap_attr_export(struct attr *new, struct attr *orig, +		  struct prefix *new_nexthop, +		  struct route_node *rn) /* for VN addrs for ecom list */ +					 /* if rn is 0, use route's nexthop */  { -  struct prefix orig_nexthop; -  struct prefix *use_nexthop; -  static struct ecommunity *ecom_ro; - -  if (new_nexthop) -    { -      use_nexthop = new_nexthop; -    } -  else -    { -      use_nexthop = &orig_nexthop; -      orig_nexthop.family = -        BGP_MP_NEXTHOP_FAMILY (orig->mp_nexthop_len); -      if (orig_nexthop.family == AF_INET) -        { -          orig_nexthop.prefixlen = 32; -          orig_nexthop.u.prefix4 = orig->mp_nexthop_global_in; -        } -      else if (orig_nexthop.family == AF_INET6) -        { -          orig_nexthop.prefixlen = 128; -          orig_nexthop.u.prefix6 = orig->mp_nexthop_global; -        } -      else -        { -          return -1;            /* FAIL - can't compute nexthop */ -        } -    } - - -  /* -   * Make "new" a ghost attr copy of "orig" -   */ -  memset (new, 0, sizeof (struct attr)); -  bgp_attr_dup (new, orig); - -  /* -   * Set nexthop -   */ -  switch (use_nexthop->family) -    { -    case AF_INET: -      new->nexthop = use_nexthop->u.prefix4; -      new->mp_nexthop_len = 4;   /* bytes */ -      new->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP); -      break; - -    case AF_INET6: -      new->mp_nexthop_global = use_nexthop->u.prefix6; -      new->mp_nexthop_len = 16;  /* bytes */ -      break; - -    default: -      assert (0); -      break; -    } - -  if (rn) -    { -      ecom_ro = vnc_route_origin_ecom (rn); -    } -  else -    { -      /* TBD test/assert for IPv6 */ -      ecom_ro = vnc_route_origin_ecom_single (&use_nexthop->u.prefix4); -    } -  if (new->ecommunity) -    { -      if (ecom_ro) -        new->ecommunity =  ecommunity_merge (ecom_ro, new->ecommunity); -    } -  else -    { -      new->ecommunity = ecom_ro; -    } -  if (ecom_ro) -    { -      new->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES); -    } - -  /* -   * Set MED -   * -   * Note that it will be deleted when BGP sends to any eBGP -   * peer unless PEER_FLAG_MED_UNCHANGED is set: -   * -   *          neighbor NEIGHBOR attribute-unchanged med -   */ -  if (!CHECK_FLAG (new->flag, BGP_ATTR_MULTI_EXIT_DISC)) -    { -      if (CHECK_FLAG (new->flag, BGP_ATTR_LOCAL_PREF)) -        { -          if (new->local_pref > 255) -            new->med = 0; -          else -            new->med = 255 - new->local_pref; -        } -      else -        { -          new->med = 255;       /* shouldn't happen */ -        } -      new->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC); -    } - -  /* -   * "new" is now a ghost attr: -   *  - it owns an "extra" struct -   *  - it owns any non-interned parts -   *  - any references to interned parts are not counted -   * -   * Caller should, after using the attr, call: -   *  - bgp_attr_flush() to free non-interned parts -   */ - -  return 0; +	struct prefix orig_nexthop; +	struct prefix *use_nexthop; +	static struct ecommunity *ecom_ro; + +	if (new_nexthop) { +		use_nexthop = new_nexthop; +	} else { +		use_nexthop = &orig_nexthop; +		orig_nexthop.family = +			BGP_MP_NEXTHOP_FAMILY(orig->mp_nexthop_len); +		if (orig_nexthop.family == AF_INET) { +			orig_nexthop.prefixlen = 32; +			orig_nexthop.u.prefix4 = orig->mp_nexthop_global_in; +		} else if (orig_nexthop.family == AF_INET6) { +			orig_nexthop.prefixlen = 128; +			orig_nexthop.u.prefix6 = orig->mp_nexthop_global; +		} else { +			return -1; /* FAIL - can't compute nexthop */ +		} +	} + + +	/* +	 * Make "new" a ghost attr copy of "orig" +	 */ +	memset(new, 0, sizeof(struct attr)); +	bgp_attr_dup(new, orig); + +	/* +	 * Set nexthop +	 */ +	switch (use_nexthop->family) { +	case AF_INET: +		new->nexthop = use_nexthop->u.prefix4; +		new->mp_nexthop_len = 4; /* bytes */ +		new->flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP); +		break; + +	case AF_INET6: +		new->mp_nexthop_global = use_nexthop->u.prefix6; +		new->mp_nexthop_len = 16; /* bytes */ +		break; + +	default: +		assert(0); +		break; +	} + +	if (rn) { +		ecom_ro = vnc_route_origin_ecom(rn); +	} else { +		/* TBD test/assert for IPv6 */ +		ecom_ro = vnc_route_origin_ecom_single(&use_nexthop->u.prefix4); +	} +	if (new->ecommunity) { +		if (ecom_ro) +			new->ecommunity = +				ecommunity_merge(ecom_ro, new->ecommunity); +	} else { +		new->ecommunity = ecom_ro; +	} +	if (ecom_ro) { +		new->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES); +	} + +	/* +	 * Set MED +	 * +	 * Note that it will be deleted when BGP sends to any eBGP +	 * peer unless PEER_FLAG_MED_UNCHANGED is set: +	 * +	 *          neighbor NEIGHBOR attribute-unchanged med +	 */ +	if (!CHECK_FLAG(new->flag, BGP_ATTR_MULTI_EXIT_DISC)) { +		if (CHECK_FLAG(new->flag, BGP_ATTR_LOCAL_PREF)) { +			if (new->local_pref > 255) +				new->med = 0; +			else +				new->med = 255 - new->local_pref; +		} else { +			new->med = 255; /* shouldn't happen */ +		} +		new->flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC); +	} + +	/* +	 * "new" is now a ghost attr: +	 *  - it owns an "extra" struct +	 *  - it owns any non-interned parts +	 *  - any references to interned parts are not counted +	 * +	 * Caller should, after using the attr, call: +	 *  - bgp_attr_flush() to free non-interned parts +	 */ + +	return 0;  }  /*   * "Adding a Route" export process   */ -void -vnc_direct_bgp_add_prefix ( -    struct bgp			*bgp, -    struct rfapi_import_table	*import_table, -    struct route_node		*rn) +void vnc_direct_bgp_add_prefix(struct bgp *bgp, +			       struct rfapi_import_table *import_table, +			       struct route_node *rn)  { -  struct attr attr = { 0 }; -  struct listnode *node, *nnode; -  struct rfapi_rfg_name *rfgn; -  afi_t afi = family2afi (rn->p.family); - -  if (!afi) -    { -      zlog_err ("%s: can't get afi of route node", __func__); -      return; -    } - -  /* check bgp redist flag for vnc direct ("vpn") routes */ -  if (!bgp->redist[afi][ZEBRA_ROUTE_VNC_DIRECT]) -    { -      vnc_zlog_debug_verbose ("%s: bgp redistribution of VNC direct routes is off", -                  __func__); -      return; -    } - -  if (!bgp->rfapi_cfg) -    { -      vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); -      return; -    } - -  if (!VNC_EXPORT_BGP_GRP_ENABLED (bgp->rfapi_cfg)) -    { -      vnc_zlog_debug_verbose ("%s: export-to-bgp group mode not enabled, skipping", -                  __func__); -      return; -    } - -  if (!listcount (bgp->rfapi_cfg->rfg_export_direct_bgp_l)) -    { -      vnc_zlog_debug_verbose ("%s: no bgp-direct export nve group, skipping", __func__); -      return; -    } - -  bgp_attr_default_set (&attr, BGP_ORIGIN_INCOMPLETE); -  /* TBD set some configured med, see add_vnc_route() */ - -  vnc_zlog_debug_verbose ("%s: looping over nve-groups in direct-bgp export list", -              __func__); - -  for (ALL_LIST_ELEMENTS (bgp->rfapi_cfg->rfg_export_direct_bgp_l, -                          node, nnode, rfgn)) -    { - -      struct listnode *ln; - -      /* -       * If nve group is not defined yet, skip it -       */ -      if (!rfgn->rfg) -        continue; - -      /* -       * If the nve group uses a different import table, skip it -       */ -      if (import_table != rfgn->rfg->rfapi_import_table) -        continue; - -      /* -       * if no NVEs currently associated with this group, skip it -       */ -      if (!rfgn->rfg->nves) -        continue; - -      /* -       * per-nve-group prefix list check -       */ -      if (rfgn->rfg->plist_export_bgp[afi]) -        { -          if (prefix_list_apply (rfgn->rfg->plist_export_bgp[afi], &rn->p) == -              PREFIX_DENY) - -            continue; -        } - -      /* -       * For each NVE that is assigned to the export nve group, generate -       * a route with that NVE as its next hop -       */ -      for (ln = listhead (rfgn->rfg->nves); ln; ln = listnextnode (ln)) -        { - -          struct prefix nhp; -          struct rfapi_descriptor *irfd; -          struct bgp_info info; -          struct attr hattr; -          struct attr *iattr; - -          irfd = listgetdata (ln); - -          if (rfapiRaddr2Qprefix (&irfd->vn_addr, &nhp)) -            continue; - -          /* -           * Construct new attribute set with NVE's VN addr as -           * nexthop and without Tunnel Encap attr -           */ -          if (encap_attr_export (&hattr, &attr, &nhp, rn)) -            continue; - -	  if (VNC_DEBUG(EXPORT_BGP_DIRECT_ADD)) -	    { -	      vnc_zlog_debug_any ("%s: attr follows", __func__); -	      rfapiPrintAttrPtrs (NULL, &attr); -	      vnc_zlog_debug_any ("%s: hattr follows", __func__); -	      rfapiPrintAttrPtrs (NULL, &hattr); -	    } - -          if (rfgn->rfg->routemap_export_bgp) -            { -              route_map_result_t ret; -              info.peer = irfd->peer; -              info.attr = &hattr; -              ret = route_map_apply (rfgn->rfg->routemap_export_bgp, &rn->p, -                                     RMAP_BGP, &info); -              if (ret == RMAP_DENYMATCH) -                { -                  bgp_attr_flush (&hattr); -                  vnc_zlog_debug_verbose -                    ("%s: route map says DENY, so not calling bgp_update", -                     __func__); -                  continue; -                } -            } - -	  if (VNC_DEBUG(EXPORT_BGP_DIRECT_ADD)) -	    { -              vnc_zlog_debug_any ("%s: hattr after route_map_apply:", __func__); -              rfapiPrintAttrPtrs (NULL, &hattr); -	    } - -          iattr = bgp_attr_intern (&hattr); -          bgp_attr_flush (&hattr); - -          bgp_update (irfd->peer, &rn->p,       /* prefix */  -                      0,                        /* addpath_id */ -                      iattr,    /* bgp_update copies it */ -                      afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL,  /* RD not used for unicast */ -                      NULL,     /* tag not used for unicast */ -                      0, NULL); /* EVPN not used */ - -          bgp_attr_unintern (&iattr); -        } -    } - -  aspath_unintern (&attr.aspath); +	struct attr attr = {0}; +	struct listnode *node, *nnode; +	struct rfapi_rfg_name *rfgn; +	afi_t afi = family2afi(rn->p.family); + +	if (!afi) { +		zlog_err("%s: can't get afi of route node", __func__); +		return; +	} + +	/* check bgp redist flag for vnc direct ("vpn") routes */ +	if (!bgp->redist[afi][ZEBRA_ROUTE_VNC_DIRECT]) { +		vnc_zlog_debug_verbose( +			"%s: bgp redistribution of VNC direct routes is off", +			__func__); +		return; +	} + +	if (!bgp->rfapi_cfg) { +		vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", +				       __func__); +		return; +	} + +	if (!VNC_EXPORT_BGP_GRP_ENABLED(bgp->rfapi_cfg)) { +		vnc_zlog_debug_verbose( +			"%s: export-to-bgp group mode not enabled, skipping", +			__func__); +		return; +	} + +	if (!listcount(bgp->rfapi_cfg->rfg_export_direct_bgp_l)) { +		vnc_zlog_debug_verbose( +			"%s: no bgp-direct export nve group, skipping", +			__func__); +		return; +	} + +	bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE); +	/* TBD set some configured med, see add_vnc_route() */ + +	vnc_zlog_debug_verbose( +		"%s: looping over nve-groups in direct-bgp export list", +		__func__); + +	for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node, +			       nnode, rfgn)) { + +		struct listnode *ln; + +		/* +		 * If nve group is not defined yet, skip it +		 */ +		if (!rfgn->rfg) +			continue; + +		/* +		 * If the nve group uses a different import table, skip it +		 */ +		if (import_table != rfgn->rfg->rfapi_import_table) +			continue; + +		/* +		 * if no NVEs currently associated with this group, skip it +		 */ +		if (!rfgn->rfg->nves) +			continue; + +		/* +		 * per-nve-group prefix list check +		 */ +		if (rfgn->rfg->plist_export_bgp[afi]) { +			if (prefix_list_apply(rfgn->rfg->plist_export_bgp[afi], +					      &rn->p) +			    == PREFIX_DENY) + +				continue; +		} + +		/* +		 * For each NVE that is assigned to the export nve group, +		 * generate +		 * a route with that NVE as its next hop +		 */ +		for (ln = listhead(rfgn->rfg->nves); ln; +		     ln = listnextnode(ln)) { + +			struct prefix nhp; +			struct rfapi_descriptor *irfd; +			struct bgp_info info; +			struct attr hattr; +			struct attr *iattr; + +			irfd = listgetdata(ln); + +			if (rfapiRaddr2Qprefix(&irfd->vn_addr, &nhp)) +				continue; + +			/* +			 * Construct new attribute set with NVE's VN addr as +			 * nexthop and without Tunnel Encap attr +			 */ +			if (encap_attr_export(&hattr, &attr, &nhp, rn)) +				continue; + +			if (VNC_DEBUG(EXPORT_BGP_DIRECT_ADD)) { +				vnc_zlog_debug_any("%s: attr follows", +						   __func__); +				rfapiPrintAttrPtrs(NULL, &attr); +				vnc_zlog_debug_any("%s: hattr follows", +						   __func__); +				rfapiPrintAttrPtrs(NULL, &hattr); +			} + +			if (rfgn->rfg->routemap_export_bgp) { +				route_map_result_t ret; +				info.peer = irfd->peer; +				info.attr = &hattr; +				ret = route_map_apply( +					rfgn->rfg->routemap_export_bgp, &rn->p, +					RMAP_BGP, &info); +				if (ret == RMAP_DENYMATCH) { +					bgp_attr_flush(&hattr); +					vnc_zlog_debug_verbose( +						"%s: route map says DENY, so not calling bgp_update", +						__func__); +					continue; +				} +			} + +			if (VNC_DEBUG(EXPORT_BGP_DIRECT_ADD)) { +				vnc_zlog_debug_any( +					"%s: hattr after route_map_apply:", +					__func__); +				rfapiPrintAttrPtrs(NULL, &hattr); +			} + +			iattr = bgp_attr_intern(&hattr); +			bgp_attr_flush(&hattr); + +			bgp_update(irfd->peer, &rn->p, /* prefix */ +				   0,		       /* addpath_id */ +				   iattr, /* bgp_update copies it */ +				   afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT, +				   BGP_ROUTE_REDISTRIBUTE, +				   NULL,     /* RD not used for unicast */ +				   NULL,     /* tag not used for unicast */ +				   0, NULL); /* EVPN not used */ + +			bgp_attr_unintern(&iattr); +		} +	} + +	aspath_unintern(&attr.aspath);  }  /*   * "Withdrawing a Route" export process   */ -void -vnc_direct_bgp_del_prefix ( -    struct bgp			*bgp, -    struct rfapi_import_table	*import_table, -    struct route_node		*rn) +void vnc_direct_bgp_del_prefix(struct bgp *bgp, +			       struct rfapi_import_table *import_table, +			       struct route_node *rn)  { -  struct listnode *node, *nnode; -  struct rfapi_rfg_name *rfgn; -  afi_t afi = family2afi (rn->p.family); - -  if (!afi) -    { -      zlog_err ("%s: can't get afi route node", __func__); -      return; -    } - -  /* check bgp redist flag for vnc direct ("vpn") routes */ -  if (!bgp->redist[afi][ZEBRA_ROUTE_VNC_DIRECT]) -    { -      vnc_zlog_debug_verbose ("%s: bgp redistribution of VNC direct routes is off", -                  __func__); -      return; -    } - -  if (!bgp->rfapi_cfg) -    { -      vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); -      return; -    } - -  if (!VNC_EXPORT_BGP_GRP_ENABLED (bgp->rfapi_cfg)) -    { -      vnc_zlog_debug_verbose ("%s: export-to-bgp group mode not enabled, skipping", -                  __func__); -      return; -    } - -  if (!listcount (bgp->rfapi_cfg->rfg_export_direct_bgp_l)) -    { -      vnc_zlog_debug_verbose ("%s: no bgp-direct export nve group, skipping", __func__); -      return; -    } - -  for (ALL_LIST_ELEMENTS (bgp->rfapi_cfg->rfg_export_direct_bgp_l, -                          node, nnode, rfgn)) -    { - -      struct listnode *ln; - -      /* -       * If nve group is not defined yet, skip it -       */ -      if (!rfgn->rfg) -        continue; - -      /* -       * if no NVEs currently associated with this group, skip it -       */ -      if (!rfgn->rfg->nves) -        continue; - -      /* -       * If the nve group uses a different import table, -       * skip it -       */ -      if (import_table != rfgn->rfg->rfapi_import_table) -        continue; - -      /* -       * For each NVE that is assigned to the export nve group, generate -       * a route with that NVE as its next hop -       */ -      for (ln = listhead (rfgn->rfg->nves); ln; ln = listnextnode (ln)) -        { - -          struct prefix nhp; -          struct rfapi_descriptor *irfd; - -          irfd = listgetdata (ln); - -          if (rfapiRaddr2Qprefix (&irfd->vn_addr, &nhp)) -            continue; - -          bgp_withdraw (irfd->peer, &rn->p,     /* prefix */ -                        0,                /* addpath_id */ -                        NULL,   /* attr, ignored */ -                        afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL,        /* RD not used for unicast */ -                        NULL, NULL);  /* tag not used for unicast */ -        } -    } +	struct listnode *node, *nnode; +	struct rfapi_rfg_name *rfgn; +	afi_t afi = family2afi(rn->p.family); + +	if (!afi) { +		zlog_err("%s: can't get afi route node", __func__); +		return; +	} + +	/* check bgp redist flag for vnc direct ("vpn") routes */ +	if (!bgp->redist[afi][ZEBRA_ROUTE_VNC_DIRECT]) { +		vnc_zlog_debug_verbose( +			"%s: bgp redistribution of VNC direct routes is off", +			__func__); +		return; +	} + +	if (!bgp->rfapi_cfg) { +		vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", +				       __func__); +		return; +	} + +	if (!VNC_EXPORT_BGP_GRP_ENABLED(bgp->rfapi_cfg)) { +		vnc_zlog_debug_verbose( +			"%s: export-to-bgp group mode not enabled, skipping", +			__func__); +		return; +	} + +	if (!listcount(bgp->rfapi_cfg->rfg_export_direct_bgp_l)) { +		vnc_zlog_debug_verbose( +			"%s: no bgp-direct export nve group, skipping", +			__func__); +		return; +	} + +	for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node, +			       nnode, rfgn)) { + +		struct listnode *ln; + +		/* +		 * If nve group is not defined yet, skip it +		 */ +		if (!rfgn->rfg) +			continue; + +		/* +		 * if no NVEs currently associated with this group, skip it +		 */ +		if (!rfgn->rfg->nves) +			continue; + +		/* +		 * If the nve group uses a different import table, +		 * skip it +		 */ +		if (import_table != rfgn->rfg->rfapi_import_table) +			continue; + +		/* +		 * For each NVE that is assigned to the export nve group, +		 * generate +		 * a route with that NVE as its next hop +		 */ +		for (ln = listhead(rfgn->rfg->nves); ln; +		     ln = listnextnode(ln)) { + +			struct prefix nhp; +			struct rfapi_descriptor *irfd; + +			irfd = listgetdata(ln); + +			if (rfapiRaddr2Qprefix(&irfd->vn_addr, &nhp)) +				continue; + +			bgp_withdraw(irfd->peer, &rn->p, /* prefix */ +				     0,			 /* addpath_id */ +				     NULL,		 /* attr, ignored */ +				     afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT, +				     BGP_ROUTE_REDISTRIBUTE, +				     NULL,	/* RD not used for unicast */ +				     NULL, NULL); /* tag not used for unicast */ +		} +	}  } -void -vnc_direct_bgp_add_nve (struct bgp *bgp, struct rfapi_descriptor *rfd) +void vnc_direct_bgp_add_nve(struct bgp *bgp, struct rfapi_descriptor *rfd)  { -  struct listnode *node, *nnode; -  struct rfapi_rfg_name *rfgn; -  struct rfapi_nve_group_cfg *rfg = rfd->rfg; -  afi_t afi = family2afi (rfd->vn_addr.addr_family); - -  if (!afi) -    { -      zlog_err ("%s: can't get afi of nve vn addr", __func__); -      return; -    } - -  if (!bgp) -    return; -  if (!bgp->rfapi_cfg) -    { -      vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); -      return; -    } -  if (!VNC_EXPORT_BGP_GRP_ENABLED (bgp->rfapi_cfg)) -    { -      vnc_zlog_debug_verbose ("%s: export-to-bgp group mode not enabled, skipping", -                  __func__); -      return; -    } - -  if (!bgp->redist[afi][ZEBRA_ROUTE_VNC_DIRECT]) -    { -      vnc_zlog_debug_verbose ("%s: bgp redistribution of VNC direct routes is off", -                  __func__); -      return; -    } - -  /* -   * Loop over the list of NVE-Groups configured for -   * exporting to direct-bgp and see if this new NVE's -   * group is among them. -   */ -  for (ALL_LIST_ELEMENTS (bgp->rfapi_cfg->rfg_export_direct_bgp_l, -                          node, nnode, rfgn)) -    { - -      /* -       * Yes, this NVE's group is configured for export to direct-bgp -       */ -      if (rfgn->rfg == rfg) -        { - -          struct route_table *rt = NULL; -          struct route_node *rn; -          struct attr attr = { 0 }; -          struct rfapi_import_table *import_table; - - -          import_table = rfg->rfapi_import_table; - -          bgp_attr_default_set (&attr, BGP_ORIGIN_INCOMPLETE); -          /* TBD set some configured med, see add_vnc_route() */ - -          if (afi == AFI_IP -              || afi == AFI_IP6) -            { -              rt = import_table->imported_vpn[afi]; -            } -          else -            { -              zlog_err ("%s: bad afi %d", __func__, afi); -              return; -            } - -          /*  -           * Walk the NVE-Group's VNC Import table -           */ -          for (rn = route_top (rt); rn; rn = route_next (rn)) -            { - -              if (rn->info) -                { - -                  struct prefix nhp; -                  struct rfapi_descriptor *irfd = rfd; -                  struct attr hattr; -                  struct attr *iattr; -                  struct bgp_info info; - -                  if (rfapiRaddr2Qprefix (&irfd->vn_addr, &nhp)) -                    continue; - -                  /* -                   * per-nve-group prefix list check -                   */ -                  if (rfgn->rfg->plist_export_bgp[afi]) -                    { -                      if (prefix_list_apply (rfgn->rfg->plist_export_bgp[afi], -                                             &rn->p) == PREFIX_DENY) - -                        continue; -                    } - - -                  /* -                   * Construct new attribute set with NVE's VN addr as -                   * nexthop and without Tunnel Encap attr -                   */ -                  if (encap_attr_export (&hattr, &attr, &nhp, rn)) -                    continue; - -                  if (rfgn->rfg->routemap_export_bgp) -                    { -                      route_map_result_t ret; -                      info.peer = irfd->peer; -                      info.attr = &hattr; -                      ret = route_map_apply (rfgn->rfg->routemap_export_bgp, -                                             &rn->p, RMAP_BGP, &info); -                      if (ret == RMAP_DENYMATCH) -                        { -                          bgp_attr_flush (&hattr); -                          continue; -                        } - -                    } - -                  iattr = bgp_attr_intern (&hattr); -                  bgp_attr_flush (&hattr); - -                  bgp_update (irfd->peer, &rn->p,       /* prefix */  -                              0,                        /* addpath_id */ -                              iattr,    /* bgp_update copies it */ -                              afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL,  /* RD not used for unicast */ -                              NULL,     /* tag not used for unicast */ -                              0, NULL); /* EVPN not used */ - -                  bgp_attr_unintern (&iattr); - -                } -            } - -          aspath_unintern (&attr.aspath); -        } -    } +	struct listnode *node, *nnode; +	struct rfapi_rfg_name *rfgn; +	struct rfapi_nve_group_cfg *rfg = rfd->rfg; +	afi_t afi = family2afi(rfd->vn_addr.addr_family); + +	if (!afi) { +		zlog_err("%s: can't get afi of nve vn addr", __func__); +		return; +	} + +	if (!bgp) +		return; +	if (!bgp->rfapi_cfg) { +		vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", +				       __func__); +		return; +	} +	if (!VNC_EXPORT_BGP_GRP_ENABLED(bgp->rfapi_cfg)) { +		vnc_zlog_debug_verbose( +			"%s: export-to-bgp group mode not enabled, skipping", +			__func__); +		return; +	} + +	if (!bgp->redist[afi][ZEBRA_ROUTE_VNC_DIRECT]) { +		vnc_zlog_debug_verbose( +			"%s: bgp redistribution of VNC direct routes is off", +			__func__); +		return; +	} + +	/* +	 * Loop over the list of NVE-Groups configured for +	 * exporting to direct-bgp and see if this new NVE's +	 * group is among them. +	 */ +	for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node, +			       nnode, rfgn)) { + +		/* +		 * Yes, this NVE's group is configured for export to direct-bgp +		 */ +		if (rfgn->rfg == rfg) { + +			struct route_table *rt = NULL; +			struct route_node *rn; +			struct attr attr = {0}; +			struct rfapi_import_table *import_table; + + +			import_table = rfg->rfapi_import_table; + +			bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE); +			/* TBD set some configured med, see add_vnc_route() */ + +			if (afi == AFI_IP || afi == AFI_IP6) { +				rt = import_table->imported_vpn[afi]; +			} else { +				zlog_err("%s: bad afi %d", __func__, afi); +				return; +			} + +			/* +			 * Walk the NVE-Group's VNC Import table +			 */ +			for (rn = route_top(rt); rn; rn = route_next(rn)) { + +				if (rn->info) { + +					struct prefix nhp; +					struct rfapi_descriptor *irfd = rfd; +					struct attr hattr; +					struct attr *iattr; +					struct bgp_info info; + +					if (rfapiRaddr2Qprefix(&irfd->vn_addr, +							       &nhp)) +						continue; + +					/* +					 * per-nve-group prefix list check +					 */ +					if (rfgn->rfg->plist_export_bgp[afi]) { +						if (prefix_list_apply( +							    rfgn->rfg->plist_export_bgp +								    [afi], +							    &rn->p) +						    == PREFIX_DENY) + +							continue; +					} + + +					/* +					 * Construct new attribute set with +					 * NVE's VN addr as +					 * nexthop and without Tunnel Encap attr +					 */ +					if (encap_attr_export(&hattr, &attr, +							      &nhp, rn)) +						continue; + +					if (rfgn->rfg->routemap_export_bgp) { +						route_map_result_t ret; +						info.peer = irfd->peer; +						info.attr = &hattr; +						ret = route_map_apply( +							rfgn->rfg +								->routemap_export_bgp, +							&rn->p, RMAP_BGP, +							&info); +						if (ret == RMAP_DENYMATCH) { +							bgp_attr_flush(&hattr); +							continue; +						} +					} + +					iattr = bgp_attr_intern(&hattr); +					bgp_attr_flush(&hattr); + +					bgp_update(irfd->peer, +						   &rn->p, /* prefix */ +						   0,      /* addpath_id */ +						   iattr,  /* bgp_update copies +							      it */ +						   afi, SAFI_UNICAST, +						   ZEBRA_ROUTE_VNC_DIRECT, +						   BGP_ROUTE_REDISTRIBUTE, +						   NULL,     /* RD not used for +								unicast */ +						   NULL,     /* tag not used for +								unicast */ +						   0, NULL); /* EVPN not used */ + +					bgp_attr_unintern(&iattr); +				} +			} + +			aspath_unintern(&attr.aspath); +		} +	}  } -void -vnc_direct_bgp_del_nve (struct bgp *bgp, struct rfapi_descriptor *rfd) +void vnc_direct_bgp_del_nve(struct bgp *bgp, struct rfapi_descriptor *rfd)  { -  struct listnode *node, *nnode; -  struct rfapi_rfg_name *rfgn; -  struct rfapi_nve_group_cfg *rfg = rfd->rfg; -  afi_t afi = family2afi (rfd->vn_addr.addr_family); - -  if (!afi) -    { -      zlog_err ("%s: can't get afi of nve vn addr", __func__); -      return; -    } - -  if (!bgp) -    return; -  if (!bgp->rfapi_cfg) -    { -      vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); -      return; -    } -  if (!VNC_EXPORT_BGP_GRP_ENABLED (bgp->rfapi_cfg)) -    { -      vnc_zlog_debug_verbose ("%s: export-to-bgp group mode not enabled, skipping", -                  __func__); -      return; -    } - -  if (!bgp->redist[afi][ZEBRA_ROUTE_VNC_DIRECT]) -    { -      vnc_zlog_debug_verbose ("%s: bgp redistribution of VNC direct routes is off", -                  __func__); -      return; -    } - -  /* -   * Loop over the list of NVE-Groups configured for -   * exporting to direct-bgp and see if this new NVE's -   * group is among them. -   */ -  for (ALL_LIST_ELEMENTS (bgp->rfapi_cfg->rfg_export_direct_bgp_l, -                          node, nnode, rfgn)) -    { - -      /* -       * Yes, this NVE's group is configured for export to direct-bgp -       */ -      if (rfg && rfgn->rfg == rfg) -        { - -          struct route_table *rt = NULL; -          struct route_node *rn; -          struct rfapi_import_table *import_table; - -          import_table = rfg->rfapi_import_table; - -          if (afi == AFI_IP -              || afi == AFI_IP6) -            { -              rt = import_table->imported_vpn[afi]; -            } -          else -            { -              zlog_err ("%s: bad afi %d", __func__, afi); -              return; -            } - -          /*  -           * Walk the NVE-Group's VNC Import table -           */ -          for (rn = route_top (rt); rn; rn = route_next (rn)) -            { - -              if (rn->info) -                { - -                  struct prefix nhp; -                  struct rfapi_descriptor *irfd = rfd; - -                  if (rfapiRaddr2Qprefix (&irfd->vn_addr, &nhp)) -                    continue; - -                  bgp_withdraw (irfd->peer, &rn->p,     /* prefix */ -                                0,                      /* addpath_id */ -                                NULL,   /* attr, ignored */ -                                afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL,        /* RD not used for unicast */ -                                NULL, NULL);  /* tag not used for unicast */ - -                } -            } -        } -    } -} +	struct listnode *node, *nnode; +	struct rfapi_rfg_name *rfgn; +	struct rfapi_nve_group_cfg *rfg = rfd->rfg; +	afi_t afi = family2afi(rfd->vn_addr.addr_family); + +	if (!afi) { +		zlog_err("%s: can't get afi of nve vn addr", __func__); +		return; +	} + +	if (!bgp) +		return; +	if (!bgp->rfapi_cfg) { +		vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", +				       __func__); +		return; +	} +	if (!VNC_EXPORT_BGP_GRP_ENABLED(bgp->rfapi_cfg)) { +		vnc_zlog_debug_verbose( +			"%s: export-to-bgp group mode not enabled, skipping", +			__func__); +		return; +	} + +	if (!bgp->redist[afi][ZEBRA_ROUTE_VNC_DIRECT]) { +		vnc_zlog_debug_verbose( +			"%s: bgp redistribution of VNC direct routes is off", +			__func__); +		return; +	} +	/* +	 * Loop over the list of NVE-Groups configured for +	 * exporting to direct-bgp and see if this new NVE's +	 * group is among them. +	 */ +	for (ALL_LIST_ELEMENTS(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node, +			       nnode, rfgn)) { + +		/* +		 * Yes, this NVE's group is configured for export to direct-bgp +		 */ +		if (rfg && rfgn->rfg == rfg) { + +			struct route_table *rt = NULL; +			struct route_node *rn; +			struct rfapi_import_table *import_table; + +			import_table = rfg->rfapi_import_table; + +			if (afi == AFI_IP || afi == AFI_IP6) { +				rt = import_table->imported_vpn[afi]; +			} else { +				zlog_err("%s: bad afi %d", __func__, afi); +				return; +			} + +			/* +			 * Walk the NVE-Group's VNC Import table +			 */ +			for (rn = route_top(rt); rn; rn = route_next(rn)) { + +				if (rn->info) { + +					struct prefix nhp; +					struct rfapi_descriptor *irfd = rfd; + +					if (rfapiRaddr2Qprefix(&irfd->vn_addr, +							       &nhp)) +						continue; + +					bgp_withdraw(irfd->peer, +						     &rn->p, /* prefix */ +						     0,      /* addpath_id */ +						     NULL,   /* attr, ignored */ +						     afi, SAFI_UNICAST, +						     ZEBRA_ROUTE_VNC_DIRECT, +						     BGP_ROUTE_REDISTRIBUTE, +						     NULL, /* RD not used for +							      unicast */ +						     NULL, NULL); /* tag not +								     used for +								     unicast */ +				} +			} +		} +	} +}  /*   * Caller is responsible for ensuring that the specified nve-group   * is actually part of the list of exported nve groups.   */ -static void -vnc_direct_bgp_add_group_afi ( -    struct bgp			*bgp, -    struct rfapi_nve_group_cfg	*rfg, -    afi_t			afi) +static void vnc_direct_bgp_add_group_afi(struct bgp *bgp, +					 struct rfapi_nve_group_cfg *rfg, +					 afi_t afi)  { -  struct route_table *rt = NULL; -  struct route_node *rn; -  struct attr attr = { 0 }; -  struct rfapi_import_table *import_table; - -  vnc_zlog_debug_verbose ("%s: entry", __func__); - -  import_table = rfg->rfapi_import_table; -  if (!import_table) -    { -      vnc_zlog_debug_verbose ("%s: import table not defined, returning", __func__); -      return; -    } - -  if (afi == AFI_IP -      || afi == AFI_IP6) -    { -      rt = import_table->imported_vpn[afi]; -    } -  else -    { -      zlog_err ("%s: bad afi %d", __func__, afi); -      return; -    } - -  if (!rfg->nves) -    { -      /* avoid segfault below if list doesn't exist */ -      vnc_zlog_debug_verbose ("%s: no NVEs in this group", __func__); -      return; -    } - -  bgp_attr_default_set (&attr, BGP_ORIGIN_INCOMPLETE); -  /* TBD set some configured med, see add_vnc_route() */ - -  /*  -   * Walk the NVE-Group's VNC Import table -   */ -  for (rn = route_top (rt); rn; rn = route_next (rn)) -    { - -      if (rn->info) -        { - -          struct listnode *ln; - -          /* -           * per-nve-group prefix list check -           */ -          if (rfg->plist_export_bgp[afi]) -            { -              if (prefix_list_apply (rfg->plist_export_bgp[afi], &rn->p) == -                  PREFIX_DENY) - -                continue; -            } - -          /* -           * For each NVE that is assigned to the export nve group, generate -           * a route with that NVE as its next hop -           */ -          for (ln = listhead (rfg->nves); ln; ln = listnextnode (ln)) -            { - -              struct prefix nhp; -              struct rfapi_descriptor *irfd; -              struct bgp_info info; -              struct attr hattr; -              struct attr *iattr; - -              irfd = listgetdata (ln); - -              if (rfapiRaddr2Qprefix (&irfd->vn_addr, &nhp)) -                continue; - -              /* -               * Construct new attribute set with NVE's VN addr as -               * nexthop and without Tunnel Encap attr -               */ -              if (encap_attr_export (&hattr, &attr, &nhp, rn)) -                continue; - -              if (rfg->routemap_export_bgp) -                { -                  route_map_result_t ret; -                  info.peer = irfd->peer; -                  info.attr = &hattr; -                  ret = route_map_apply (rfg->routemap_export_bgp, -                                         &rn->p, RMAP_BGP, &info); -                  if (ret == RMAP_DENYMATCH) -                    { -                      bgp_attr_flush (&hattr); -                      continue; -                    } - -                } - -              iattr = bgp_attr_intern (&hattr); -              bgp_attr_flush (&hattr); - -              bgp_update (irfd->peer, &rn->p,   /* prefix */  -                          0,                    /* addpath_id */ -                          iattr,        /* bgp_update copies it */ -                          afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL,      /* RD not used for unicast */ -                          NULL, /* tag not used for unicast */ -                          0, NULL); /* EVPN not used */ - -              bgp_attr_unintern (&iattr); -            } -        } -    } - -  aspath_unintern (&attr.aspath); +	struct route_table *rt = NULL; +	struct route_node *rn; +	struct attr attr = {0}; +	struct rfapi_import_table *import_table; + +	vnc_zlog_debug_verbose("%s: entry", __func__); + +	import_table = rfg->rfapi_import_table; +	if (!import_table) { +		vnc_zlog_debug_verbose( +			"%s: import table not defined, returning", __func__); +		return; +	} + +	if (afi == AFI_IP || afi == AFI_IP6) { +		rt = import_table->imported_vpn[afi]; +	} else { +		zlog_err("%s: bad afi %d", __func__, afi); +		return; +	} + +	if (!rfg->nves) { +		/* avoid segfault below if list doesn't exist */ +		vnc_zlog_debug_verbose("%s: no NVEs in this group", __func__); +		return; +	} + +	bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE); +	/* TBD set some configured med, see add_vnc_route() */ + +	/* +	 * Walk the NVE-Group's VNC Import table +	 */ +	for (rn = route_top(rt); rn; rn = route_next(rn)) { + +		if (rn->info) { + +			struct listnode *ln; + +			/* +			 * per-nve-group prefix list check +			 */ +			if (rfg->plist_export_bgp[afi]) { +				if (prefix_list_apply( +					    rfg->plist_export_bgp[afi], &rn->p) +				    == PREFIX_DENY) + +					continue; +			} + +			/* +			 * For each NVE that is assigned to the export nve +			 * group, generate +			 * a route with that NVE as its next hop +			 */ +			for (ln = listhead(rfg->nves); ln; +			     ln = listnextnode(ln)) { + +				struct prefix nhp; +				struct rfapi_descriptor *irfd; +				struct bgp_info info; +				struct attr hattr; +				struct attr *iattr; + +				irfd = listgetdata(ln); + +				if (rfapiRaddr2Qprefix(&irfd->vn_addr, &nhp)) +					continue; + +				/* +				 * Construct new attribute set with NVE's VN +				 * addr as +				 * nexthop and without Tunnel Encap attr +				 */ +				if (encap_attr_export(&hattr, &attr, &nhp, rn)) +					continue; + +				if (rfg->routemap_export_bgp) { +					route_map_result_t ret; +					info.peer = irfd->peer; +					info.attr = &hattr; +					ret = route_map_apply( +						rfg->routemap_export_bgp, +						&rn->p, RMAP_BGP, &info); +					if (ret == RMAP_DENYMATCH) { +						bgp_attr_flush(&hattr); +						continue; +					} +				} + +				iattr = bgp_attr_intern(&hattr); +				bgp_attr_flush(&hattr); + +				bgp_update(irfd->peer, &rn->p, /* prefix */ +					   0,		       /* addpath_id */ +					   iattr, /* bgp_update copies it */ +					   afi, SAFI_UNICAST, +					   ZEBRA_ROUTE_VNC_DIRECT, +					   BGP_ROUTE_REDISTRIBUTE, +					   NULL, /* RD not used for unicast */ +					   NULL, /* tag not used for unicast */ +					   0, NULL); /* EVPN not used */ + +				bgp_attr_unintern(&iattr); +			} +		} +	} + +	aspath_unintern(&attr.aspath);  } @@ -1366,80 +1302,77 @@ vnc_direct_bgp_add_group_afi (   * Caller is responsible for ensuring that the specified nve-group   * is actually part of the list of exported nve groups.   */ -void -vnc_direct_bgp_add_group (struct bgp *bgp, struct rfapi_nve_group_cfg *rfg) +void vnc_direct_bgp_add_group(struct bgp *bgp, struct rfapi_nve_group_cfg *rfg)  { -  vnc_direct_bgp_add_group_afi (bgp, rfg, AFI_IP); -  vnc_direct_bgp_add_group_afi (bgp, rfg, AFI_IP6); +	vnc_direct_bgp_add_group_afi(bgp, rfg, AFI_IP); +	vnc_direct_bgp_add_group_afi(bgp, rfg, AFI_IP6);  } -  /*   * Caller is responsible for ensuring that the specified nve-group   * was actually part of the list of exported nve groups.   */ -static void -vnc_direct_bgp_del_group_afi ( -    struct bgp			*bgp, -    struct rfapi_nve_group_cfg	*rfg, -    afi_t			afi) +static void vnc_direct_bgp_del_group_afi(struct bgp *bgp, +					 struct rfapi_nve_group_cfg *rfg, +					 afi_t afi)  { -  struct route_table *rt = NULL; -  struct route_node *rn; -  struct rfapi_import_table *import_table; - -  vnc_zlog_debug_verbose ("%s: entry", __func__); - -  import_table = rfg->rfapi_import_table; -  if (!import_table) -    { -      vnc_zlog_debug_verbose ("%s: import table not defined, returning", __func__); -      return; -    } - -  assert (afi == AFI_IP -          || afi == AFI_IP6); -  rt = import_table->imported_vpn[afi]; - -  if (!rfg->nves) -    { -      /* avoid segfault below if list does not exist */ -      vnc_zlog_debug_verbose ("%s: no NVEs in this group", __func__); -      return; -    } - -  /*  -   * Walk the NVE-Group's VNC Import table -   */ -  for (rn = route_top (rt); rn; rn = route_next (rn)) -    { - -      if (rn->info) -        { - -          struct listnode *ln; - -          /* -           * For each NVE that is assigned to the export nve group, generate -           * a route with that NVE as its next hop -           */ -          for (ln = listhead (rfg->nves); ln; ln = listnextnode (ln)) -            { - -              struct rfapi_descriptor *irfd; - -              irfd = listgetdata (ln); - -              bgp_withdraw (irfd->peer, &rn->p, /* prefix */ -                            0,                  /* addpath_id */ -                            NULL,       /* attr, ignored */ -                            afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL,    /* RD not used for unicast */ -                            NULL, NULL);      /* tag not used for unicast */ - -            } -        } -    } +	struct route_table *rt = NULL; +	struct route_node *rn; +	struct rfapi_import_table *import_table; + +	vnc_zlog_debug_verbose("%s: entry", __func__); + +	import_table = rfg->rfapi_import_table; +	if (!import_table) { +		vnc_zlog_debug_verbose( +			"%s: import table not defined, returning", __func__); +		return; +	} + +	assert(afi == AFI_IP || afi == AFI_IP6); +	rt = import_table->imported_vpn[afi]; + +	if (!rfg->nves) { +		/* avoid segfault below if list does not exist */ +		vnc_zlog_debug_verbose("%s: no NVEs in this group", __func__); +		return; +	} + +	/* +	 * Walk the NVE-Group's VNC Import table +	 */ +	for (rn = route_top(rt); rn; rn = route_next(rn)) { + +		if (rn->info) { + +			struct listnode *ln; + +			/* +			 * For each NVE that is assigned to the export nve +			 * group, generate +			 * a route with that NVE as its next hop +			 */ +			for (ln = listhead(rfg->nves); ln; +			     ln = listnextnode(ln)) { + +				struct rfapi_descriptor *irfd; + +				irfd = listgetdata(ln); + +				bgp_withdraw( +					irfd->peer, &rn->p, /* prefix */ +					0,		    /* addpath_id */ +					NULL,		    /* attr, ignored */ +					afi, SAFI_UNICAST, +					ZEBRA_ROUTE_VNC_DIRECT, +					BGP_ROUTE_REDISTRIBUTE, +					NULL, /* RD not used for unicast */ +					NULL, +					NULL); /* tag not used for unicast */ +			} +		} +	}  } @@ -1447,189 +1380,173 @@ vnc_direct_bgp_del_group_afi (   * Caller is responsible for ensuring that the specified nve-group   * was actually part of the list of exported nve groups.   */ -void -vnc_direct_bgp_del_group (struct bgp *bgp, struct rfapi_nve_group_cfg *rfg) +void vnc_direct_bgp_del_group(struct bgp *bgp, struct rfapi_nve_group_cfg *rfg)  { -  vnc_direct_bgp_del_group_afi (bgp, rfg, AFI_IP); -  vnc_direct_bgp_del_group_afi (bgp, rfg, AFI_IP6); +	vnc_direct_bgp_del_group_afi(bgp, rfg, AFI_IP); +	vnc_direct_bgp_del_group_afi(bgp, rfg, AFI_IP6);  } -void -vnc_direct_bgp_reexport_group_afi ( -    struct bgp			*bgp, -    struct rfapi_nve_group_cfg	*rfg, -    afi_t			afi) +void vnc_direct_bgp_reexport_group_afi(struct bgp *bgp, +				       struct rfapi_nve_group_cfg *rfg, +				       afi_t afi)  { -  struct listnode *node; -  struct rfapi_rfg_name *rfgn; - -  if (VNC_EXPORT_BGP_GRP_ENABLED (bgp->rfapi_cfg)) -    { -      /* -       * look in the list of currently-exported groups -       */ -      for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_direct_bgp_l, -                                 node, rfgn)) -        { - -          if (rfgn->rfg == rfg) -            { -              /* -               * If it matches, reexport it -               */ -              vnc_direct_bgp_del_group_afi (bgp, rfg, afi); -              vnc_direct_bgp_add_group_afi (bgp, rfg, afi); -              break; -            } -        } -    } +	struct listnode *node; +	struct rfapi_rfg_name *rfgn; + +	if (VNC_EXPORT_BGP_GRP_ENABLED(bgp->rfapi_cfg)) { +		/* +		 * look in the list of currently-exported groups +		 */ +		for (ALL_LIST_ELEMENTS_RO( +			     bgp->rfapi_cfg->rfg_export_direct_bgp_l, node, +			     rfgn)) { + +			if (rfgn->rfg == rfg) { +				/* +				 * If it matches, reexport it +				 */ +				vnc_direct_bgp_del_group_afi(bgp, rfg, afi); +				vnc_direct_bgp_add_group_afi(bgp, rfg, afi); +				break; +			} +		} +	}  } -static void -vnc_direct_bgp_unexport_table ( -    afi_t		afi, -    struct route_table	*rt, -    struct list		*nve_list) +static void vnc_direct_bgp_unexport_table(afi_t afi, struct route_table *rt, +					  struct list *nve_list)  { -  if (nve_list) -    { - -      struct route_node *rn; - -      for (rn = route_top (rt); rn; rn = route_next (rn)) -        { - -          if (rn->info) -            { - -              struct listnode *hln; -              struct rfapi_descriptor *irfd; - -              for (ALL_LIST_ELEMENTS_RO (nve_list, hln, irfd)) -                { - -                  bgp_withdraw (irfd->peer, &rn->p,     /* prefix */ -                                0,                      /* addpath_id */ -                                NULL,   /* attr, ignored */ -                                afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL,        /* RD not used for unicast */ -                                NULL, NULL);  /* tag not used for unicast, EVPN neither */ - -                } -            } -        } -    } +	if (nve_list) { + +		struct route_node *rn; + +		for (rn = route_top(rt); rn; rn = route_next(rn)) { + +			if (rn->info) { + +				struct listnode *hln; +				struct rfapi_descriptor *irfd; + +				for (ALL_LIST_ELEMENTS_RO(nve_list, hln, +							  irfd)) { + +					bgp_withdraw(irfd->peer, +						     &rn->p, /* prefix */ +						     0,      /* addpath_id */ +						     NULL,   /* attr, ignored */ +						     afi, SAFI_UNICAST, +						     ZEBRA_ROUTE_VNC_DIRECT, +						     BGP_ROUTE_REDISTRIBUTE, +						     NULL, /* RD not used for +							      unicast */ +						     NULL, NULL); /* tag not +								     used for +								     unicast, +								     EVPN +								     neither */ +				} +			} +		} +	}  } -static void -import_table_to_nve_list_direct_bgp ( -    struct bgp			*bgp, -    struct rfapi_import_table	*it, -    struct list			**nves, -    uint8_t			family) +static void import_table_to_nve_list_direct_bgp(struct bgp *bgp, +						struct rfapi_import_table *it, +						struct list **nves, +						uint8_t family)  { -  struct listnode *node; -  struct rfapi_rfg_name *rfgn; - -  /* -   * Loop over the list of NVE-Groups configured for -   * exporting to direct-bgp. -   * -   * Build a list of NVEs that use this import table -   */ -  *nves = NULL; -  for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_direct_bgp_l, -                             node, rfgn)) -    { - -      /* -       * If this NVE-Group's import table matches the current one -       */ -      if (rfgn->rfg && rfgn->rfg->nves && rfgn->rfg->rfapi_import_table == it) -        { - -          nve_group_to_nve_list (rfgn->rfg, nves, family); -        } -    } +	struct listnode *node; +	struct rfapi_rfg_name *rfgn; + +	/* +	 * Loop over the list of NVE-Groups configured for +	 * exporting to direct-bgp. +	 * +	 * Build a list of NVEs that use this import table +	 */ +	*nves = NULL; +	for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_direct_bgp_l, node, +				  rfgn)) { + +		/* +		 * If this NVE-Group's import table matches the current one +		 */ +		if (rfgn->rfg && rfgn->rfg->nves +		    && rfgn->rfg->rfapi_import_table == it) { + +			nve_group_to_nve_list(rfgn->rfg, nves, family); +		} +	}  } -void -vnc_direct_bgp_vpn_enable (struct bgp *bgp, afi_t afi) +void vnc_direct_bgp_vpn_enable(struct bgp *bgp, afi_t afi)  { -  struct listnode *rfgn; -  struct rfapi_nve_group_cfg *rfg; - -  if (!bgp) -    return; - -  if (!VNC_EXPORT_BGP_GRP_ENABLED (bgp->rfapi_cfg)) -    { -      vnc_zlog_debug_verbose ("%s: export-to-bgp group mode not enabled, skipping", -                  __func__); -      return; -    } - -  if (afi != AFI_IP -      && afi != AFI_IP6) -    { -      vnc_zlog_debug_verbose ("%s: bad afi: %d", __func__, afi); -      return; -    } - -  /* -   * Policy is applied per-nve-group, so we need to iterate -   * over the groups to add everything. -   */ -  for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->nve_groups_sequential, -                             rfgn, rfg)) -    { - -      /* -       * contains policy management -       */ -      vnc_direct_bgp_add_group_afi (bgp, rfg, afi); -    } +	struct listnode *rfgn; +	struct rfapi_nve_group_cfg *rfg; + +	if (!bgp) +		return; + +	if (!VNC_EXPORT_BGP_GRP_ENABLED(bgp->rfapi_cfg)) { +		vnc_zlog_debug_verbose( +			"%s: export-to-bgp group mode not enabled, skipping", +			__func__); +		return; +	} + +	if (afi != AFI_IP && afi != AFI_IP6) { +		vnc_zlog_debug_verbose("%s: bad afi: %d", __func__, afi); +		return; +	} + +	/* +	 * Policy is applied per-nve-group, so we need to iterate +	 * over the groups to add everything. +	 */ +	for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->nve_groups_sequential, rfgn, +				  rfg)) { + +		/* +		 * contains policy management +		 */ +		vnc_direct_bgp_add_group_afi(bgp, rfg, afi); +	}  } -void -vnc_direct_bgp_vpn_disable (struct bgp *bgp, afi_t afi) +void vnc_direct_bgp_vpn_disable(struct bgp *bgp, afi_t afi)  { -  struct rfapi_import_table *it; -  uint8_t family = afi2family (afi); +	struct rfapi_import_table *it; +	uint8_t family = afi2family(afi); -  vnc_zlog_debug_verbose ("%s: entry, afi=%d", __func__, afi); +	vnc_zlog_debug_verbose("%s: entry, afi=%d", __func__, afi); -  if (!bgp) -    return; +	if (!bgp) +		return; -  if (!bgp->rfapi) -    { -      vnc_zlog_debug_verbose ("%s: rfapi not initialized", __func__); -      return; -    } +	if (!bgp->rfapi) { +		vnc_zlog_debug_verbose("%s: rfapi not initialized", __func__); +		return; +	} -  if (!family || (afi != AFI_IP -                  && afi != AFI_IP6)) -    { -      vnc_zlog_debug_verbose ("%s: bad afi: %d", __func__, afi); -      return; -    } +	if (!family || (afi != AFI_IP && afi != AFI_IP6)) { +		vnc_zlog_debug_verbose("%s: bad afi: %d", __func__, afi); +		return; +	} -  for (it = bgp->rfapi->imports; it; it = it->next) -    { +	for (it = bgp->rfapi->imports; it; it = it->next) { -      struct list *nve_list = NULL; +		struct list *nve_list = NULL; -      import_table_to_nve_list_direct_bgp (bgp, it, &nve_list, family); +		import_table_to_nve_list_direct_bgp(bgp, it, &nve_list, family); -      if (nve_list) -        { -          vnc_direct_bgp_unexport_table (afi, it->imported_vpn[afi], -                                         nve_list); -          list_free (nve_list); -        } -    } +		if (nve_list) { +			vnc_direct_bgp_unexport_table( +				afi, it->imported_vpn[afi], nve_list); +			list_free(nve_list); +		} +	}  } @@ -1649,137 +1566,121 @@ vnc_direct_bgp_vpn_disable (struct bgp *bgp, afi_t afi)   * TBD do we need to check bi->type and bi->sub_type here, or does   * caller do it?   */ -void -vnc_direct_bgp_rh_add_route ( -    struct bgp		*bgp, -    afi_t		afi, -    struct prefix	*prefix, -    struct peer		*peer, -    struct attr		*attr) +void vnc_direct_bgp_rh_add_route(struct bgp *bgp, afi_t afi, +				 struct prefix *prefix, struct peer *peer, +				 struct attr *attr)  { -  struct vnc_export_info *eti; -  struct attr hattr; -  struct rfapi_cfg *hc; -  struct attr *iattr; - -  if (!afi) -    { -      zlog_err ("%s: can't get afi of route node", __func__); -      return; -    } - -  /* check bgp redist flag for vnc direct ("vpn") routes */ -  if (!bgp->redist[afi][ZEBRA_ROUTE_VNC_DIRECT]) -    { -      vnc_zlog_debug_verbose ("%s: bgp redistribution of VNC direct routes is off", -                  __func__); -      return; -    } - -  if (!(hc = bgp->rfapi_cfg)) -    { -      vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); -      return; -    } - -  if (!VNC_EXPORT_BGP_RH_ENABLED (bgp->rfapi_cfg)) -    { -      vnc_zlog_debug_verbose ("%s: export-to-bgp RH mode not enabled, skipping", -                  __func__); -      return; -    } - -  /* -   * prefix list check -   */ -  if (hc->plist_export_bgp[afi]) -    { -      if (prefix_list_apply (hc->plist_export_bgp[afi], prefix) == -          PREFIX_DENY) -        return; -    } - -  /* -   * Construct new attribute set with NVE's VN addr as -   * nexthop and without Tunnel Encap attr -   */ -  if (encap_attr_export (&hattr, attr, NULL, NULL)) -    return; -  if (hc->routemap_export_bgp) -    { -      struct bgp_info info; -      route_map_result_t ret; - -      memset (&info, 0, sizeof (info)); -      info.peer = peer; -      info.attr = &hattr; -      ret = -        route_map_apply (hc->routemap_export_bgp, prefix, RMAP_BGP, &info); -      if (ret == RMAP_DENYMATCH) -        { -          bgp_attr_flush (&hattr); -          return; -        } -    } - -  iattr = bgp_attr_intern (&hattr); -  bgp_attr_flush (&hattr); - -  /* -   * record route information that we will need to expire -   * this route -   */ -  eti = vnc_eti_get (bgp, EXPORT_TYPE_BGP, prefix, peer, -                     ZEBRA_ROUTE_VNC_DIRECT_RH, BGP_ROUTE_REDISTRIBUTE); -  rfapiGetVncLifetime (attr, &eti->lifetime); -  eti->lifetime = rfapiGetHolddownFromLifetime (eti->lifetime); - -  if (eti->timer) -    { -      /* -       * export expiration timer is already running on -       * this route: cancel it -       */ -      thread_cancel (eti->timer); -      eti->timer = NULL; -    } - -  bgp_update (peer, prefix,     /* prefix */  -              0,                /* addpath_id */ -              iattr,            /* bgp_update copies this attr */ -              afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT_RH, BGP_ROUTE_REDISTRIBUTE, NULL,       /* RD not used for unicast */ -              NULL,             /* tag not used for unicast, EVPN neither */ -              0, NULL);         /* EVPN not used */ -  bgp_attr_unintern (&iattr); +	struct vnc_export_info *eti; +	struct attr hattr; +	struct rfapi_cfg *hc; +	struct attr *iattr; + +	if (!afi) { +		zlog_err("%s: can't get afi of route node", __func__); +		return; +	} + +	/* check bgp redist flag for vnc direct ("vpn") routes */ +	if (!bgp->redist[afi][ZEBRA_ROUTE_VNC_DIRECT]) { +		vnc_zlog_debug_verbose( +			"%s: bgp redistribution of VNC direct routes is off", +			__func__); +		return; +	} + +	if (!(hc = bgp->rfapi_cfg)) { +		vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", +				       __func__); +		return; +	} + +	if (!VNC_EXPORT_BGP_RH_ENABLED(bgp->rfapi_cfg)) { +		vnc_zlog_debug_verbose( +			"%s: export-to-bgp RH mode not enabled, skipping", +			__func__); +		return; +	} + +	/* +	 * prefix list check +	 */ +	if (hc->plist_export_bgp[afi]) { +		if (prefix_list_apply(hc->plist_export_bgp[afi], prefix) +		    == PREFIX_DENY) +			return; +	} + +	/* +	 * Construct new attribute set with NVE's VN addr as +	 * nexthop and without Tunnel Encap attr +	 */ +	if (encap_attr_export(&hattr, attr, NULL, NULL)) +		return; +	if (hc->routemap_export_bgp) { +		struct bgp_info info; +		route_map_result_t ret; + +		memset(&info, 0, sizeof(info)); +		info.peer = peer; +		info.attr = &hattr; +		ret = route_map_apply(hc->routemap_export_bgp, prefix, RMAP_BGP, +				      &info); +		if (ret == RMAP_DENYMATCH) { +			bgp_attr_flush(&hattr); +			return; +		} +	} + +	iattr = bgp_attr_intern(&hattr); +	bgp_attr_flush(&hattr); + +	/* +	 * record route information that we will need to expire +	 * this route +	 */ +	eti = vnc_eti_get(bgp, EXPORT_TYPE_BGP, prefix, peer, +			  ZEBRA_ROUTE_VNC_DIRECT_RH, BGP_ROUTE_REDISTRIBUTE); +	rfapiGetVncLifetime(attr, &eti->lifetime); +	eti->lifetime = rfapiGetHolddownFromLifetime(eti->lifetime); + +	if (eti->timer) { +		/* +		 * export expiration timer is already running on +		 * this route: cancel it +		 */ +		thread_cancel(eti->timer); +		eti->timer = NULL; +	} +	bgp_update(peer, prefix, /* prefix */ +		   0,		 /* addpath_id */ +		   iattr,	/* bgp_update copies this attr */ +		   afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT_RH, +		   BGP_ROUTE_REDISTRIBUTE, NULL, /* RD not used for unicast */ +		   NULL,     /* tag not used for unicast, EVPN neither */ +		   0, NULL); /* EVPN not used */ +	bgp_attr_unintern(&iattr);  } -static int -vncExportWithdrawTimer (struct thread *t) +static int vncExportWithdrawTimer(struct thread *t)  { -  struct vnc_export_info *eti = t->arg; - -  /* -   * withdraw the route -   */ -  bgp_withdraw ( -    eti->peer, -    &eti->node->p, -    0,                                  /* addpath_id */ -    NULL,				/* attr, ignored */ -    family2afi (eti->node->p.family), -    SAFI_UNICAST, -    eti->type, -    eti->subtype, -    NULL,				/* RD not used for unicast */ -    NULL, NULL);			/* tag not used for unicast, EVPN neither */ - -  /* -   * Free the eti -   */ -  vnc_eti_delete (eti); - -  return 0; +	struct vnc_export_info *eti = t->arg; + +	/* +	 * withdraw the route +	 */ +	bgp_withdraw(eti->peer, &eti->node->p, 0, /* addpath_id */ +		     NULL,			  /* attr, ignored */ +		     family2afi(eti->node->p.family), SAFI_UNICAST, eti->type, +		     eti->subtype, NULL, /* RD not used for unicast */ +		     NULL, NULL); /* tag not used for unicast, EVPN neither */ + +	/* +	 * Free the eti +	 */ +	vnc_eti_delete(eti); + +	return 0;  }  /* @@ -1787,287 +1688,295 @@ vncExportWithdrawTimer (struct thread *t)   * TBD do we need to check bi->type and bi->sub_type here, or does   * caller do it?   */ -void -vnc_direct_bgp_rh_del_route ( -    struct bgp		*bgp, -    afi_t		afi, -    struct prefix	*prefix, -    struct peer		*peer) +void vnc_direct_bgp_rh_del_route(struct bgp *bgp, afi_t afi, +				 struct prefix *prefix, struct peer *peer)  { -  struct vnc_export_info *eti; - -  if (!afi) -    { -      zlog_err ("%s: can't get afi route node", __func__); -      return; -    } - -  /* check bgp redist flag for vnc direct ("vpn") routes */ -  if (!bgp->redist[afi][ZEBRA_ROUTE_VNC_DIRECT]) -    { -      vnc_zlog_debug_verbose ("%s: bgp redistribution of VNC direct routes is off", -                  __func__); -      return; -    } - -  if (!bgp->rfapi_cfg) -    { -      vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); -      return; -    } -  if (!VNC_EXPORT_BGP_RH_ENABLED (bgp->rfapi_cfg)) -    { -      vnc_zlog_debug_verbose ("%s: export-to-bgp group mode not enabled, skipping", -                  __func__); -      return; -    } - -  eti = vnc_eti_get (bgp, EXPORT_TYPE_BGP, prefix, peer, -                     ZEBRA_ROUTE_VNC_DIRECT_RH, BGP_ROUTE_REDISTRIBUTE); - -  if (!eti->timer && eti->lifetime <= INT32_MAX) -    { -      eti->timer = NULL; -      thread_add_timer(bm->master, vncExportWithdrawTimer, eti, eti->lifetime, -                       &eti->timer); -      vnc_zlog_debug_verbose ("%s: set expiration timer for %u seconds", -                  __func__, eti->lifetime); -    } +	struct vnc_export_info *eti; + +	if (!afi) { +		zlog_err("%s: can't get afi route node", __func__); +		return; +	} + +	/* check bgp redist flag for vnc direct ("vpn") routes */ +	if (!bgp->redist[afi][ZEBRA_ROUTE_VNC_DIRECT]) { +		vnc_zlog_debug_verbose( +			"%s: bgp redistribution of VNC direct routes is off", +			__func__); +		return; +	} + +	if (!bgp->rfapi_cfg) { +		vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", +				       __func__); +		return; +	} +	if (!VNC_EXPORT_BGP_RH_ENABLED(bgp->rfapi_cfg)) { +		vnc_zlog_debug_verbose( +			"%s: export-to-bgp group mode not enabled, skipping", +			__func__); +		return; +	} + +	eti = vnc_eti_get(bgp, EXPORT_TYPE_BGP, prefix, peer, +			  ZEBRA_ROUTE_VNC_DIRECT_RH, BGP_ROUTE_REDISTRIBUTE); + +	if (!eti->timer && eti->lifetime <= INT32_MAX) { +		eti->timer = NULL; +		thread_add_timer(bm->master, vncExportWithdrawTimer, eti, +				 eti->lifetime, &eti->timer); +		vnc_zlog_debug_verbose( +			"%s: set expiration timer for %u seconds", __func__, +			eti->lifetime); +	}  } -void -vnc_direct_bgp_rh_vpn_enable (struct bgp *bgp, afi_t afi) +void vnc_direct_bgp_rh_vpn_enable(struct bgp *bgp, afi_t afi)  { -  struct prefix_rd prd; -  struct bgp_node *prn; -  struct rfapi_cfg *hc; - -  vnc_zlog_debug_verbose ("%s: entry, afi=%d", __func__, afi); - -  if (!bgp) -    return; - -  if (!(hc = bgp->rfapi_cfg)) -    return; - -  if (!VNC_EXPORT_BGP_RH_ENABLED (bgp->rfapi_cfg)) -    { -      vnc_zlog_debug_verbose ("%s: export of RH routes not enabled, skipping", __func__); -      return; -    } - -  if (afi != AFI_IP -      && afi != AFI_IP6) -    { -      vnc_zlog_debug_verbose ("%s: bad afi: %d", __func__, afi); -      return; -    } - -  /* -   * Go through the entire BGP VPN table and export to BGP unicast. -   */ - -  vnc_zlog_debug_verbose ("%s: starting RD loop", __func__); - -  /* Loop over all the RDs */ -  for (prn = bgp_table_top (bgp->rib[afi][SAFI_MPLS_VPN]); prn; -       prn = bgp_route_next (prn)) -    { - -      struct bgp_table *table; -      struct bgp_node *rn; -      struct bgp_info *ri; - -      memset (&prd, 0, sizeof (prd)); -      prd.family = AF_UNSPEC; -      prd.prefixlen = 64; -      memcpy (prd.val, prn->p.u.val, 8); - -      /* This is the per-RD table of prefixes */ -      table = prn->info; - -      for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn)) -        { - -          /* -           * skip prefix list check if no routes here -           */ -          if (!rn->info) -            continue; - -          { -            char prefixstr[BUFSIZ]; - -            prefixstr[0] = 0; -            inet_ntop (rn->p.family, &rn->p.u.prefix, prefixstr, BUFSIZ); -            vnc_zlog_debug_verbose ("%s: checking prefix %s/%d", __func__, prefixstr, -                        rn->p.prefixlen); -          } - -          /* -           * prefix list check -           */ -          if (hc->plist_export_bgp[afi]) -            { -              if (prefix_list_apply (hc->plist_export_bgp[afi], &rn->p) == -                  PREFIX_DENY) -                { - -                  vnc_zlog_debug_verbose ("%s:   prefix list says DENY", __func__); -                  continue; -                } -            } - -          for (ri = rn->info; ri; ri = ri->next) -            { - -              vnc_zlog_debug_verbose ("%s: ri->sub_type: %d", __func__, ri->sub_type); - -              if (ri->sub_type == BGP_ROUTE_NORMAL || -                  ri->sub_type == BGP_ROUTE_RFP) -                { - -                  struct vnc_export_info *eti; -                  struct attr hattr; -                  struct attr *iattr; - -                  /* -                   * Construct new attribute set with NVE's VN addr as -                   * nexthop and without Tunnel Encap attr -                   */ -                  if (encap_attr_export (&hattr, ri->attr, NULL, NULL)) -                    { -                      vnc_zlog_debug_verbose ("%s:   encap_attr_export failed", __func__); -                      continue; -                    } - -                  if (hc->routemap_export_bgp) -                    { -                      struct bgp_info info; -                      route_map_result_t ret; - -                      memset (&info, 0, sizeof (info)); -                      info.peer = ri->peer; -                      info.attr = &hattr; -                      ret = route_map_apply (hc->routemap_export_bgp, -                                             &rn->p, RMAP_BGP, &info); -                      if (ret == RMAP_DENYMATCH) -                        { -                          bgp_attr_flush (&hattr); -                          vnc_zlog_debug_verbose ("%s:   route map says DENY", __func__); -                          continue; -                        } -                    } - -                  iattr = bgp_attr_intern (&hattr); -                  bgp_attr_flush (&hattr); - -                  /* -                   * record route information that we will need to expire -                   * this route -                   */ -                  eti = vnc_eti_get (bgp, EXPORT_TYPE_BGP, &rn->p, ri->peer, -                                     ZEBRA_ROUTE_VNC_DIRECT_RH, -                                     BGP_ROUTE_REDISTRIBUTE); -                  rfapiGetVncLifetime (ri->attr, &eti->lifetime); - -                  if (eti->timer) -                    { -                      /* -                       * export expiration timer is already running on -                       * this route: cancel it -                       */ -                      thread_cancel (eti->timer); -                      eti->timer = NULL; -                    } - -                  vnc_zlog_debug_verbose ("%s: calling bgp_update", __func__); - -                  bgp_update (ri->peer, &rn->p, /* prefix */  -                              0,                /* addpath_id */ -                              iattr,    /* bgp_update copies it */ -                              AFI_IP, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT_RH, BGP_ROUTE_REDISTRIBUTE, NULL,    /* RD not used for unicast */ -                              NULL,     /* tag not used for unicast, EVPN neither */ -                              0, NULL); /* EVPN not used */ -                  bgp_attr_unintern (&iattr); -                } -            } -        } -    } +	struct prefix_rd prd; +	struct bgp_node *prn; +	struct rfapi_cfg *hc; + +	vnc_zlog_debug_verbose("%s: entry, afi=%d", __func__, afi); + +	if (!bgp) +		return; + +	if (!(hc = bgp->rfapi_cfg)) +		return; + +	if (!VNC_EXPORT_BGP_RH_ENABLED(bgp->rfapi_cfg)) { +		vnc_zlog_debug_verbose( +			"%s: export of RH routes not enabled, skipping", +			__func__); +		return; +	} + +	if (afi != AFI_IP && afi != AFI_IP6) { +		vnc_zlog_debug_verbose("%s: bad afi: %d", __func__, afi); +		return; +	} + +	/* +	 * Go through the entire BGP VPN table and export to BGP unicast. +	 */ + +	vnc_zlog_debug_verbose("%s: starting RD loop", __func__); + +	/* Loop over all the RDs */ +	for (prn = bgp_table_top(bgp->rib[afi][SAFI_MPLS_VPN]); prn; +	     prn = bgp_route_next(prn)) { + +		struct bgp_table *table; +		struct bgp_node *rn; +		struct bgp_info *ri; + +		memset(&prd, 0, sizeof(prd)); +		prd.family = AF_UNSPEC; +		prd.prefixlen = 64; +		memcpy(prd.val, prn->p.u.val, 8); + +		/* This is the per-RD table of prefixes */ +		table = prn->info; + +		for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) { + +			/* +			 * skip prefix list check if no routes here +			 */ +			if (!rn->info) +				continue; + +			{ +				char prefixstr[BUFSIZ]; + +				prefixstr[0] = 0; +				inet_ntop(rn->p.family, &rn->p.u.prefix, +					  prefixstr, BUFSIZ); +				vnc_zlog_debug_verbose( +					"%s: checking prefix %s/%d", __func__, +					prefixstr, rn->p.prefixlen); +			} + +			/* +			 * prefix list check +			 */ +			if (hc->plist_export_bgp[afi]) { +				if (prefix_list_apply(hc->plist_export_bgp[afi], +						      &rn->p) +				    == PREFIX_DENY) { + +					vnc_zlog_debug_verbose( +						"%s:   prefix list says DENY", +						__func__); +					continue; +				} +			} + +			for (ri = rn->info; ri; ri = ri->next) { + +				vnc_zlog_debug_verbose("%s: ri->sub_type: %d", +						       __func__, ri->sub_type); + +				if (ri->sub_type == BGP_ROUTE_NORMAL +				    || ri->sub_type == BGP_ROUTE_RFP) { + +					struct vnc_export_info *eti; +					struct attr hattr; +					struct attr *iattr; + +					/* +					 * Construct new attribute set with +					 * NVE's VN addr as +					 * nexthop and without Tunnel Encap attr +					 */ +					if (encap_attr_export(&hattr, ri->attr, +							      NULL, NULL)) { +						vnc_zlog_debug_verbose( +							"%s:   encap_attr_export failed", +							__func__); +						continue; +					} + +					if (hc->routemap_export_bgp) { +						struct bgp_info info; +						route_map_result_t ret; + +						memset(&info, 0, sizeof(info)); +						info.peer = ri->peer; +						info.attr = &hattr; +						ret = route_map_apply( +							hc->routemap_export_bgp, +							&rn->p, RMAP_BGP, +							&info); +						if (ret == RMAP_DENYMATCH) { +							bgp_attr_flush(&hattr); +							vnc_zlog_debug_verbose( +								"%s:   route map says DENY", +								__func__); +							continue; +						} +					} + +					iattr = bgp_attr_intern(&hattr); +					bgp_attr_flush(&hattr); + +					/* +					 * record route information that we will +					 * need to expire +					 * this route +					 */ +					eti = vnc_eti_get( +						bgp, EXPORT_TYPE_BGP, &rn->p, +						ri->peer, +						ZEBRA_ROUTE_VNC_DIRECT_RH, +						BGP_ROUTE_REDISTRIBUTE); +					rfapiGetVncLifetime(ri->attr, +							    &eti->lifetime); + +					if (eti->timer) { +						/* +						 * export expiration timer is +						 * already running on +						 * this route: cancel it +						 */ +						thread_cancel(eti->timer); +						eti->timer = NULL; +					} + +					vnc_zlog_debug_verbose( +						"%s: calling bgp_update", +						__func__); + +					bgp_update(ri->peer, +						   &rn->p, /* prefix */ +						   0,      /* addpath_id */ +						   iattr,  /* bgp_update copies +							      it */ +						   AFI_IP, SAFI_UNICAST, +						   ZEBRA_ROUTE_VNC_DIRECT_RH, +						   BGP_ROUTE_REDISTRIBUTE, +						   NULL,     /* RD not used for +								unicast */ +						   NULL,     /* tag not used for +								unicast, EVPN +								neither */ +						   0, NULL); /* EVPN not used */ +					bgp_attr_unintern(&iattr); +				} +			} +		} +	}  } -void -vnc_direct_bgp_rh_vpn_disable (struct bgp *bgp, afi_t afi) +void vnc_direct_bgp_rh_vpn_disable(struct bgp *bgp, afi_t afi)  { -  struct bgp_node *rn; - -  vnc_zlog_debug_verbose ("%s: entry, afi=%d", __func__, afi); - -  if (!bgp) -    return; - -  if (afi != AFI_IP -      && afi != AFI_IP6) -    { -      vnc_zlog_debug_verbose ("%s: bad afi: %d", __func__, afi); -      return; -    } - -  /* -   * Go through the entire BGP unicast table and remove routes that -   * originated from us -   */ -  for (rn = bgp_table_top (bgp->rib[afi][SAFI_UNICAST]); rn; -       rn = bgp_route_next (rn)) -    { - -      struct bgp_info *ri; -      struct bgp_info *next; - -      for (ri = rn->info, next = NULL; ri; ri = next) -        { - -          next = ri->next; - -          if (ri->type == ZEBRA_ROUTE_VNC_DIRECT_RH && -              ri->sub_type == BGP_ROUTE_REDISTRIBUTE) -            { - -              struct vnc_export_info *eti; - -              /* -               * Delete routes immediately (no timer) -               */ -              eti = -                vnc_eti_checktimer (bgp, EXPORT_TYPE_BGP, &rn->p, ri->peer, -                                    ZEBRA_ROUTE_VNC_DIRECT_RH, -                                    BGP_ROUTE_REDISTRIBUTE); -              if (eti) -                { -                  if (eti->timer) -                    thread_cancel (eti->timer); -                  vnc_eti_delete (eti); -                } - -              bgp_withdraw (ri->peer, &rn->p,   /* prefix */ -                            0,                  /* addpath_id */ -                            NULL,       /* ignored */ -                            AFI_IP, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT_RH, BGP_ROUTE_REDISTRIBUTE, NULL,      /* RD not used for unicast */ -                            NULL, NULL);      /* tag not used for unicast, EVPN neither */ -            } -        } -    } +	struct bgp_node *rn; + +	vnc_zlog_debug_verbose("%s: entry, afi=%d", __func__, afi); + +	if (!bgp) +		return; + +	if (afi != AFI_IP && afi != AFI_IP6) { +		vnc_zlog_debug_verbose("%s: bad afi: %d", __func__, afi); +		return; +	} + +	/* +	 * Go through the entire BGP unicast table and remove routes that +	 * originated from us +	 */ +	for (rn = bgp_table_top(bgp->rib[afi][SAFI_UNICAST]); rn; +	     rn = bgp_route_next(rn)) { + +		struct bgp_info *ri; +		struct bgp_info *next; + +		for (ri = rn->info, next = NULL; ri; ri = next) { + +			next = ri->next; + +			if (ri->type == ZEBRA_ROUTE_VNC_DIRECT_RH +			    && ri->sub_type == BGP_ROUTE_REDISTRIBUTE) { + +				struct vnc_export_info *eti; + +				/* +				 * Delete routes immediately (no timer) +				 */ +				eti = vnc_eti_checktimer( +					bgp, EXPORT_TYPE_BGP, &rn->p, ri->peer, +					ZEBRA_ROUTE_VNC_DIRECT_RH, +					BGP_ROUTE_REDISTRIBUTE); +				if (eti) { +					if (eti->timer) +						thread_cancel(eti->timer); +					vnc_eti_delete(eti); +				} + +				bgp_withdraw(ri->peer, &rn->p, /* prefix */ +					     0,		       /* addpath_id */ +					     NULL,	     /* ignored */ +					     AFI_IP, SAFI_UNICAST, +					     ZEBRA_ROUTE_VNC_DIRECT_RH, +					     BGP_ROUTE_REDISTRIBUTE, +					     NULL, /* RD not used for unicast */ +					     NULL, NULL); /* tag not used for +							     unicast, EVPN +							     neither */ +			} +		} +	}  } -void -vnc_direct_bgp_rh_reexport (struct bgp *bgp, afi_t afi) +void vnc_direct_bgp_rh_reexport(struct bgp *bgp, afi_t afi)  { -  if (VNC_EXPORT_BGP_RH_ENABLED (bgp->rfapi_cfg)) -    { -      vnc_direct_bgp_rh_vpn_disable (bgp, afi); -      vnc_direct_bgp_rh_vpn_enable (bgp, afi); -    } +	if (VNC_EXPORT_BGP_RH_ENABLED(bgp->rfapi_cfg)) { +		vnc_direct_bgp_rh_vpn_disable(bgp, afi); +		vnc_direct_bgp_rh_vpn_enable(bgp, afi); +	}  }  /*********************************************************************** @@ -2079,67 +1988,60 @@ vnc_direct_bgp_rh_reexport (struct bgp *bgp, afi_t afi)   * is OK to call this function from, e.g., bgp_redistribute_set()   * without caring if export is enabled or not   */ -void -vnc_export_bgp_enable (struct bgp *bgp, afi_t afi) +void vnc_export_bgp_enable(struct bgp *bgp, afi_t afi)  { -  switch (bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) -    { -    case BGP_VNC_CONFIG_EXPORT_BGP_MODE_NONE: -      break; - -    case BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP: -      vnc_direct_bgp_vpn_enable (bgp, afi); -      break; - -    case BGP_VNC_CONFIG_EXPORT_BGP_MODE_RH: -      vnc_direct_bgp_rh_vpn_enable (bgp, afi); -      break; - -    case BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE: -      vnc_direct_bgp_vpn_enable_ce (bgp, afi); -      break; -    } +	switch (bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) { +	case BGP_VNC_CONFIG_EXPORT_BGP_MODE_NONE: +		break; + +	case BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP: +		vnc_direct_bgp_vpn_enable(bgp, afi); +		break; + +	case BGP_VNC_CONFIG_EXPORT_BGP_MODE_RH: +		vnc_direct_bgp_rh_vpn_enable(bgp, afi); +		break; + +	case BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE: +		vnc_direct_bgp_vpn_enable_ce(bgp, afi); +		break; +	}  } -void -vnc_export_bgp_disable (struct bgp *bgp, afi_t afi) +void vnc_export_bgp_disable(struct bgp *bgp, afi_t afi)  { -  switch (bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) -    { -    case BGP_VNC_CONFIG_EXPORT_BGP_MODE_NONE: -      break; - -    case BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP: -      vnc_direct_bgp_vpn_disable (bgp, afi); -      break; - -    case BGP_VNC_CONFIG_EXPORT_BGP_MODE_RH: -      vnc_direct_bgp_rh_vpn_disable (bgp, afi); -      break; - -    case BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE: -      vnc_direct_bgp_vpn_disable_ce (bgp, afi); -      break; -    } +	switch (bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_EXPORT_BGP_MODE_BITS) { +	case BGP_VNC_CONFIG_EXPORT_BGP_MODE_NONE: +		break; + +	case BGP_VNC_CONFIG_EXPORT_BGP_MODE_GRP: +		vnc_direct_bgp_vpn_disable(bgp, afi); +		break; + +	case BGP_VNC_CONFIG_EXPORT_BGP_MODE_RH: +		vnc_direct_bgp_rh_vpn_disable(bgp, afi); +		break; + +	case BGP_VNC_CONFIG_EXPORT_BGP_MODE_CE: +		vnc_direct_bgp_vpn_disable_ce(bgp, afi); +		break; +	}  } -void -vnc_export_bgp_prechange (struct bgp *bgp) +void vnc_export_bgp_prechange(struct bgp *bgp)  { -  vnc_export_bgp_disable (bgp, AFI_IP); -  vnc_export_bgp_disable (bgp, AFI_IP6); +	vnc_export_bgp_disable(bgp, AFI_IP); +	vnc_export_bgp_disable(bgp, AFI_IP6);  } -void -vnc_export_bgp_postchange (struct bgp *bgp) +void vnc_export_bgp_postchange(struct bgp *bgp)  { -  vnc_export_bgp_enable (bgp, AFI_IP); -  vnc_export_bgp_enable (bgp, AFI_IP6); +	vnc_export_bgp_enable(bgp, AFI_IP); +	vnc_export_bgp_enable(bgp, AFI_IP6);  } -void -vnc_direct_bgp_reexport (struct bgp *bgp, afi_t afi) +void vnc_direct_bgp_reexport(struct bgp *bgp, afi_t afi)  { -  vnc_export_bgp_disable (bgp, afi); -  vnc_export_bgp_enable (bgp, afi); +	vnc_export_bgp_disable(bgp, afi); +	vnc_export_bgp_enable(bgp, afi);  } diff --git a/bgpd/rfapi/vnc_export_bgp.h b/bgpd/rfapi/vnc_export_bgp.h index 7dbbb40e0a..a6f8c82c0d 100644 --- a/bgpd/rfapi/vnc_export_bgp.h +++ b/bgpd/rfapi/vnc_export_bgp.h @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2009-2016, LabN Consulting, L.L.C.   * @@ -28,14 +28,14 @@  #include "bgpd/bgp_route.h" -extern void vnc_direct_bgp_rh_reexport (struct bgp *bgp, afi_t afi); +extern void vnc_direct_bgp_rh_reexport(struct bgp *bgp, afi_t afi); -extern void vnc_export_bgp_prechange (struct bgp *bgp); +extern void vnc_export_bgp_prechange(struct bgp *bgp); -extern void vnc_export_bgp_postchange (struct bgp *bgp); +extern void vnc_export_bgp_postchange(struct bgp *bgp); -extern void vnc_export_bgp_enable (struct bgp *bgp, afi_t afi); +extern void vnc_export_bgp_enable(struct bgp *bgp, afi_t afi); -extern void vnc_export_bgp_disable (struct bgp *bgp, afi_t afi); +extern void vnc_export_bgp_disable(struct bgp *bgp, afi_t afi);  #endif /* _QUAGGA_RFAPI_VNC_EXPORT_BGP_H_ */ diff --git a/bgpd/rfapi/vnc_export_bgp_p.h b/bgpd/rfapi/vnc_export_bgp_p.h index 31830a3c13..c164a35432 100644 --- a/bgpd/rfapi/vnc_export_bgp_p.h +++ b/bgpd/rfapi/vnc_export_bgp_p.h @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2009-2016, LabN Consulting, L.L.C.   * @@ -29,66 +29,46 @@  #include "rfapi_private.h" -extern void -vnc_direct_bgp_add_route_ce ( -    struct bgp		*bgp, -    struct route_node	*rn, -    struct bgp_info	*bi); - -extern void -vnc_direct_bgp_del_route_ce ( -    struct bgp		*bgp, -    struct route_node	*rn, -    struct bgp_info	*bi); - -extern void -vnc_direct_bgp_add_prefix ( -    struct bgp			*bgp, -    struct rfapi_import_table	*import_table, -    struct route_node		*rn); - -extern void -vnc_direct_bgp_del_prefix ( -    struct bgp			*bgp, -    struct rfapi_import_table	*import_table, -    struct route_node		*rn); - -extern void -vnc_direct_bgp_add_nve (struct bgp *bgp, struct rfapi_descriptor *rfd); - -extern void -vnc_direct_bgp_del_nve (struct bgp *bgp, struct rfapi_descriptor *rfd); - -extern void -vnc_direct_bgp_add_group (struct bgp *bgp, struct rfapi_nve_group_cfg *rfg); - -extern void -vnc_direct_bgp_del_group (struct bgp *bgp, struct rfapi_nve_group_cfg *rfg); - -extern void -vnc_direct_bgp_reexport_group_afi ( -    struct bgp			*bgp, -    struct rfapi_nve_group_cfg	*rfg, -    afi_t			afi); - - -extern void -vnc_direct_bgp_rh_add_route ( -    struct bgp		*bgp, -    afi_t		afi, -    struct prefix	*prefix, -    struct peer		*peer, -    struct attr		*attr); - - -extern void -vnc_direct_bgp_rh_del_route ( -    struct bgp		*bgp, -    afi_t		afi, -    struct prefix	*prefix, -    struct peer		*peer); - -extern void -vnc_direct_bgp_reexport (struct bgp *bgp, afi_t afi); +extern void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct route_node *rn, +					struct bgp_info *bi); + +extern void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct route_node *rn, +					struct bgp_info *bi); + +extern void vnc_direct_bgp_add_prefix(struct bgp *bgp, +				      struct rfapi_import_table *import_table, +				      struct route_node *rn); + +extern void vnc_direct_bgp_del_prefix(struct bgp *bgp, +				      struct rfapi_import_table *import_table, +				      struct route_node *rn); + +extern void vnc_direct_bgp_add_nve(struct bgp *bgp, +				   struct rfapi_descriptor *rfd); + +extern void vnc_direct_bgp_del_nve(struct bgp *bgp, +				   struct rfapi_descriptor *rfd); + +extern void vnc_direct_bgp_add_group(struct bgp *bgp, +				     struct rfapi_nve_group_cfg *rfg); + +extern void vnc_direct_bgp_del_group(struct bgp *bgp, +				     struct rfapi_nve_group_cfg *rfg); + +extern void vnc_direct_bgp_reexport_group_afi(struct bgp *bgp, +					      struct rfapi_nve_group_cfg *rfg, +					      afi_t afi); + + +extern void vnc_direct_bgp_rh_add_route(struct bgp *bgp, afi_t afi, +					struct prefix *prefix, +					struct peer *peer, struct attr *attr); + + +extern void vnc_direct_bgp_rh_del_route(struct bgp *bgp, afi_t afi, +					struct prefix *prefix, +					struct peer *peer); + +extern void vnc_direct_bgp_reexport(struct bgp *bgp, afi_t afi);  #endif /* _QUAGGA_RFAPI_VNC_EXPORT_BGP_P_H_ */ diff --git a/bgpd/rfapi/vnc_export_table.c b/bgpd/rfapi/vnc_export_table.c index 5c7a64d3bb..bbdb59c125 100644 --- a/bgpd/rfapi/vnc_export_table.c +++ b/bgpd/rfapi/vnc_export_table.c @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2009-2016, LabN Consulting, L.L.C.   * @@ -33,182 +33,160 @@  #include "bgpd/rfapi/rfapi_import.h"  #include "bgpd/rfapi/vnc_debug.h" -struct route_node * -vnc_etn_get (struct bgp *bgp, vnc_export_type_t type, struct prefix *p) +struct route_node *vnc_etn_get(struct bgp *bgp, vnc_export_type_t type, +			       struct prefix *p)  { -  struct route_table *t = NULL; -  struct route_node *rn = NULL; -  afi_t afi; - -  if (!bgp || !bgp->rfapi) -    return NULL; - -  afi = family2afi (p->family); -  assert (afi == AFI_IP || afi == AFI_IP6); - -  switch (type) -    { -    case EXPORT_TYPE_BGP: -      if (!bgp->rfapi->rt_export_bgp[afi]) -        bgp->rfapi->rt_export_bgp[afi] = route_table_init (); -      t = bgp->rfapi->rt_export_bgp[afi]; -      break; - -    case EXPORT_TYPE_ZEBRA: -      if (!bgp->rfapi->rt_export_zebra[afi]) -        bgp->rfapi->rt_export_zebra[afi] = route_table_init (); -      t = bgp->rfapi->rt_export_zebra[afi]; -      break; -    } - -  if (t) -    rn = route_node_get (t, p); -  return rn; +	struct route_table *t = NULL; +	struct route_node *rn = NULL; +	afi_t afi; + +	if (!bgp || !bgp->rfapi) +		return NULL; + +	afi = family2afi(p->family); +	assert(afi == AFI_IP || afi == AFI_IP6); + +	switch (type) { +	case EXPORT_TYPE_BGP: +		if (!bgp->rfapi->rt_export_bgp[afi]) +			bgp->rfapi->rt_export_bgp[afi] = route_table_init(); +		t = bgp->rfapi->rt_export_bgp[afi]; +		break; + +	case EXPORT_TYPE_ZEBRA: +		if (!bgp->rfapi->rt_export_zebra[afi]) +			bgp->rfapi->rt_export_zebra[afi] = route_table_init(); +		t = bgp->rfapi->rt_export_zebra[afi]; +		break; +	} + +	if (t) +		rn = route_node_get(t, p); +	return rn;  } -struct route_node * -vnc_etn_lookup (struct bgp *bgp, vnc_export_type_t type, struct prefix *p) +struct route_node *vnc_etn_lookup(struct bgp *bgp, vnc_export_type_t type, +				  struct prefix *p)  { -  struct route_table *t = NULL; -  struct route_node *rn = NULL; -  afi_t afi; - -  if (!bgp || !bgp->rfapi) -    return NULL; - -  afi = family2afi (p->family); -  assert (afi == AFI_IP || afi == AFI_IP6); - -  switch (type) -    { -    case EXPORT_TYPE_BGP: -      if (!bgp->rfapi->rt_export_bgp[afi]) -        bgp->rfapi->rt_export_bgp[afi] = route_table_init (); -      t = bgp->rfapi->rt_export_bgp[afi]; -      break; - -    case EXPORT_TYPE_ZEBRA: -      if (!bgp->rfapi->rt_export_zebra[afi]) -        bgp->rfapi->rt_export_zebra[afi] = route_table_init (); -      t = bgp->rfapi->rt_export_zebra[afi]; -      break; -    } - -  if (t) -    rn = route_node_lookup (t, p); -  return rn; +	struct route_table *t = NULL; +	struct route_node *rn = NULL; +	afi_t afi; + +	if (!bgp || !bgp->rfapi) +		return NULL; + +	afi = family2afi(p->family); +	assert(afi == AFI_IP || afi == AFI_IP6); + +	switch (type) { +	case EXPORT_TYPE_BGP: +		if (!bgp->rfapi->rt_export_bgp[afi]) +			bgp->rfapi->rt_export_bgp[afi] = route_table_init(); +		t = bgp->rfapi->rt_export_bgp[afi]; +		break; + +	case EXPORT_TYPE_ZEBRA: +		if (!bgp->rfapi->rt_export_zebra[afi]) +			bgp->rfapi->rt_export_zebra[afi] = route_table_init(); +		t = bgp->rfapi->rt_export_zebra[afi]; +		break; +	} + +	if (t) +		rn = route_node_lookup(t, p); +	return rn;  } -struct vnc_export_info * -vnc_eti_get ( -    struct bgp		*bgp, -    vnc_export_type_t	etype, -    struct prefix	*p, -    struct peer		*peer, -    uint8_t		type, -    uint8_t		subtype) +struct vnc_export_info *vnc_eti_get(struct bgp *bgp, vnc_export_type_t etype, +				    struct prefix *p, struct peer *peer, +				    uint8_t type, uint8_t subtype)  { -  struct route_node *etn; -  struct vnc_export_info *eti; - -  etn = vnc_etn_get (bgp, etype, p); -  assert (etn); - -  for (eti = etn->info; eti; eti = eti->next) -    { -      if (peer == eti->peer && type == eti->type && subtype == eti->subtype) -        { - -          break; -        } -    } - -  if (eti) -    { -      route_unlock_node (etn); -    } -  else -    { -      eti = XCALLOC (MTYPE_RFAPI_ETI, sizeof (struct vnc_export_info)); -      assert (eti); -      eti->node = etn; -      eti->peer = peer; -      peer_lock (peer); -      eti->type = type; -      eti->subtype = subtype; -      eti->next = etn->info; -      etn->info = eti; -    } - -  return eti; +	struct route_node *etn; +	struct vnc_export_info *eti; + +	etn = vnc_etn_get(bgp, etype, p); +	assert(etn); + +	for (eti = etn->info; eti; eti = eti->next) { +		if (peer == eti->peer && type == eti->type +		    && subtype == eti->subtype) { + +			break; +		} +	} + +	if (eti) { +		route_unlock_node(etn); +	} else { +		eti = XCALLOC(MTYPE_RFAPI_ETI, sizeof(struct vnc_export_info)); +		assert(eti); +		eti->node = etn; +		eti->peer = peer; +		peer_lock(peer); +		eti->type = type; +		eti->subtype = subtype; +		eti->next = etn->info; +		etn->info = eti; +	} + +	return eti;  } -void -vnc_eti_delete (struct vnc_export_info *goner) +void vnc_eti_delete(struct vnc_export_info *goner)  { -  struct route_node *etn; -  struct vnc_export_info *eti; -  struct vnc_export_info *eti_prev = NULL; - -  etn = goner->node; - -  for (eti = etn->info; eti; eti_prev = eti, eti = eti->next) -    { -      if (eti == goner) -        break; -    } - -  if (!eti) -    { -      vnc_zlog_debug_verbose ("%s: COULDN'T FIND ETI", __func__); -      return; -    } - -  if (eti_prev) -    { -      eti_prev->next = goner->next; -    } -  else -    { -      etn->info = goner->next; -    } - -  peer_unlock (eti->peer); -  goner->node = NULL; -  XFREE (MTYPE_RFAPI_ETI, goner); - -  route_unlock_node (etn); +	struct route_node *etn; +	struct vnc_export_info *eti; +	struct vnc_export_info *eti_prev = NULL; + +	etn = goner->node; + +	for (eti = etn->info; eti; eti_prev = eti, eti = eti->next) { +		if (eti == goner) +			break; +	} + +	if (!eti) { +		vnc_zlog_debug_verbose("%s: COULDN'T FIND ETI", __func__); +		return; +	} + +	if (eti_prev) { +		eti_prev->next = goner->next; +	} else { +		etn->info = goner->next; +	} + +	peer_unlock(eti->peer); +	goner->node = NULL; +	XFREE(MTYPE_RFAPI_ETI, goner); + +	route_unlock_node(etn);  } -struct vnc_export_info * -vnc_eti_checktimer ( -    struct bgp		*bgp, -    vnc_export_type_t	etype, -    struct prefix	*p, -    struct peer		*peer, -    uint8_t		type, -    uint8_t		subtype) +struct vnc_export_info *vnc_eti_checktimer(struct bgp *bgp, +					   vnc_export_type_t etype, +					   struct prefix *p, struct peer *peer, +					   uint8_t type, uint8_t subtype)  { -  struct route_node *etn; -  struct vnc_export_info *eti; +	struct route_node *etn; +	struct vnc_export_info *eti; -  etn = vnc_etn_lookup (bgp, etype, p); -  if (!etn) -    return NULL; +	etn = vnc_etn_lookup(bgp, etype, p); +	if (!etn) +		return NULL; -  for (eti = etn->info; eti; eti = eti->next) -    { -      if (peer == eti->peer && type == eti->type && subtype == eti->subtype) -        { +	for (eti = etn->info; eti; eti = eti->next) { +		if (peer == eti->peer && type == eti->type +		    && subtype == eti->subtype) { -          break; -        } -    } +			break; +		} +	} -  route_unlock_node (etn); +	route_unlock_node(etn); -  if (eti && eti->timer) -    return eti; +	if (eti && eti->timer) +		return eti; -  return NULL; +	return NULL;  } diff --git a/bgpd/rfapi/vnc_export_table.h b/bgpd/rfapi/vnc_export_table.h index 234520670d..aa38233e8f 100644 --- a/bgpd/rfapi/vnc_export_table.h +++ b/bgpd/rfapi/vnc_export_table.h @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2009-2016, LabN Consulting, L.L.C.   * @@ -30,55 +30,37 @@  #define VNC_EXPORT_TYPE_BGP	1  #define VNC_EXPORT_TYPE_ZEBRA	2 -typedef enum vnc_export_type -{ -  EXPORT_TYPE_BGP, -  EXPORT_TYPE_ZEBRA +typedef enum vnc_export_type { +	EXPORT_TYPE_BGP, +	EXPORT_TYPE_ZEBRA  } vnc_export_type_t; -struct vnc_export_info -{ -  struct vnc_export_info	*next; -  struct route_node		*node; -  struct peer			*peer; -  u_char			type; -  u_char			subtype; -  uint32_t			lifetime; -  struct thread			*timer; +struct vnc_export_info { +	struct vnc_export_info *next; +	struct route_node *node; +	struct peer *peer; +	u_char type; +	u_char subtype; +	uint32_t lifetime; +	struct thread *timer;  }; -extern struct route_node * -vnc_etn_get ( -    struct bgp		*bgp, -    vnc_export_type_t	type, -    struct prefix	*p); +extern struct route_node *vnc_etn_get(struct bgp *bgp, vnc_export_type_t type, +				      struct prefix *p);  extern struct route_node * -vnc_etn_lookup ( -    struct bgp		*bgp, -    vnc_export_type_t	type, -    struct prefix	*p); +vnc_etn_lookup(struct bgp *bgp, vnc_export_type_t type, struct prefix *p); -extern struct vnc_export_info * -vnc_eti_get ( -    struct bgp		*bgp, -    vnc_export_type_t	etype, -    struct prefix	*p, -    struct peer		*peer, -    uint8_t		type, -    uint8_t		subtype); +extern struct vnc_export_info *vnc_eti_get(struct bgp *bgp, +					   vnc_export_type_t etype, +					   struct prefix *p, struct peer *peer, +					   uint8_t type, uint8_t subtype); -extern void -vnc_eti_delete (struct vnc_export_info *goner); +extern void vnc_eti_delete(struct vnc_export_info *goner);  extern struct vnc_export_info * -vnc_eti_checktimer ( -    struct bgp		*bgp, -    vnc_export_type_t	etype, -    struct prefix	*p, -    struct peer		*peer, -    uint8_t		type, -    uint8_t		subtype); +vnc_eti_checktimer(struct bgp *bgp, vnc_export_type_t etype, struct prefix *p, +		   struct peer *peer, uint8_t type, uint8_t subtype);  #endif /* _QUAGGA_VNC_VNC_EXPORT_TABLE_H_ */ diff --git a/bgpd/rfapi/vnc_import_bgp.c b/bgpd/rfapi/vnc_import_bgp.c index 1daf02a6bf..117d4fbfd4 100644 --- a/bgpd/rfapi/vnc_import_bgp.c +++ b/bgpd/rfapi/vnc_import_bgp.c @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2009-2016, LabN Consulting, L.L.C.   * @@ -37,7 +37,7 @@  #include "bgpd/bgp_ecommunity.h"  #include "bgpd/bgp_attr.h"  #include "bgpd/bgp_route.h" -#include "bgpd/bgp_mplsvpn.h"        /* for RD_TYPE_IP */ +#include "bgpd/bgp_mplsvpn.h" /* for RD_TYPE_IP */  #include "bgpd/rfapi/vnc_export_bgp.h"  #include "bgpd/rfapi/bgp_rfapi_cfg.h" @@ -69,237 +69,212 @@ static struct rfapi_descriptor vncHDResolveNve; /* dummy nve descriptor */   *   *	LOCAL_PREF unchanged   */ -uint32_t -calc_local_pref (struct attr *attr, struct peer *peer) +uint32_t calc_local_pref(struct attr *attr, struct peer *peer)  { -  uint32_t local_pref = 0; - -  if (!attr) -    { -      if (peer) -        { -          return peer->bgp->default_local_pref; -        } -      return bgp_get_default ()->default_local_pref; -    } - -  if (peer && (peer->as != peer->bgp->as)) -    { -      if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)) -        { -          if (attr->med > 255) -            { -              local_pref = 0; -            } -          else -            { -              local_pref = 255 - attr->med; -            } -        } -      else -        { -          local_pref = peer->bgp->default_local_pref; -        } -    } -  else -    { -      if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)) -        { -          local_pref = attr->local_pref; -        } -      else -        { -          if (peer && peer->bgp) -            { -              local_pref = peer->bgp->default_local_pref; -            } -        } -    } - -  return local_pref; +	uint32_t local_pref = 0; + +	if (!attr) { +		if (peer) { +			return peer->bgp->default_local_pref; +		} +		return bgp_get_default()->default_local_pref; +	} + +	if (peer && (peer->as != peer->bgp->as)) { +		if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) { +			if (attr->med > 255) { +				local_pref = 0; +			} else { +				local_pref = 255 - attr->med; +			} +		} else { +			local_pref = peer->bgp->default_local_pref; +		} +	} else { +		if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) { +			local_pref = attr->local_pref; +		} else { +			if (peer && peer->bgp) { +				local_pref = peer->bgp->default_local_pref; +			} +		} +	} + +	return local_pref;  } -static int -is_host_prefix (struct prefix *p) +static int is_host_prefix(struct prefix *p)  { -  switch (p->family) -    { -    case AF_INET: -      return (p->prefixlen == 32); -    case AF_INET6: -      return (p->prefixlen == 128); -    } -  return 0; +	switch (p->family) { +	case AF_INET: +		return (p->prefixlen == 32); +	case AF_INET6: +		return (p->prefixlen == 128); +	} +	return 0;  }  /***********************************************************************   *				RHN list   ***********************************************************************/ -struct prefix_bag -{ -  struct prefix hpfx;           /* ce address = unicast nexthop */ -  struct prefix upfx;           /* unicast prefix */ -  struct bgp_info *ubi;         /* unicast route */ +struct prefix_bag { +	struct prefix hpfx;   /* ce address = unicast nexthop */ +	struct prefix upfx;   /* unicast prefix */ +	struct bgp_info *ubi; /* unicast route */  }; -static const u_char maskbit[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, -  0xf8, 0xfc, 0xfe, 0xff -}; +static const u_char maskbit[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0, +				 0xf8, 0xfc, 0xfe, 0xff}; -int -vnc_prefix_cmp (void *pfx1, void *pfx2) +int vnc_prefix_cmp(void *pfx1, void *pfx2)  { -  int offset; -  int shift; -  u_char mask; - -  struct prefix *p1 = pfx1; -  struct prefix *p2 = pfx2; - -  if (p1->family < p2->family) -    return -1; -  if (p1->family > p2->family) -    return 1; - -  if (p1->prefixlen < p2->prefixlen) -    return -1; -  if (p1->prefixlen > p2->prefixlen) -    return 1; - -  offset = p1->prefixlen / 8; -  shift = p1->prefixlen % 8; -  if (shift == 0 && offset) -    {                           /* catch aligned case */ -      offset--; -      shift = 8; -    } - -  /* Set both prefix's head pointer. */ -  const u_char *pp1 = (const u_char *) &p1->u.prefix; -  const u_char *pp2 = (const u_char *) &p2->u.prefix; - -  while (offset--) -    { -      if (*pp1 < *pp2) -        return -1; -      if (*pp1 > *pp2) -        return 1; -      ++pp1; -      ++pp2; -    } - -  mask = maskbit[shift]; -  if ((*pp1 & mask) < (*pp2 & mask)) -    return -1; -  if ((*pp1 & mask) > (*pp2 & mask)) -    return 1; - -  return 0; +	int offset; +	int shift; +	u_char mask; + +	struct prefix *p1 = pfx1; +	struct prefix *p2 = pfx2; + +	if (p1->family < p2->family) +		return -1; +	if (p1->family > p2->family) +		return 1; + +	if (p1->prefixlen < p2->prefixlen) +		return -1; +	if (p1->prefixlen > p2->prefixlen) +		return 1; + +	offset = p1->prefixlen / 8; +	shift = p1->prefixlen % 8; +	if (shift == 0 && offset) { /* catch aligned case */ +		offset--; +		shift = 8; +	} + +	/* Set both prefix's head pointer. */ +	const u_char *pp1 = (const u_char *)&p1->u.prefix; +	const u_char *pp2 = (const u_char *)&p2->u.prefix; + +	while (offset--) { +		if (*pp1 < *pp2) +			return -1; +		if (*pp1 > *pp2) +			return 1; +		++pp1; +		++pp2; +	} + +	mask = maskbit[shift]; +	if ((*pp1 & mask) < (*pp2 & mask)) +		return -1; +	if ((*pp1 & mask) > (*pp2 & mask)) +		return 1; + +	return 0;  } -static void -prefix_bag_free (void *pb) +static void prefix_bag_free(void *pb)  { -  XFREE (MTYPE_RFAPI_PREFIX_BAG, pb); +	XFREE(MTYPE_RFAPI_PREFIX_BAG, pb);  }  #if DEBUG_RHN_LIST -static void -print_rhn_list (const char *tag1, const char *tag2) +static void print_rhn_list(const char *tag1, const char *tag2)  { -  struct bgp *bgp; -  struct skiplist *sl; -  struct skiplistnode *p; -  struct prefix_bag *pb; -  int count = 0; - -  bgp = bgp_get_default (); -  if (!bgp) -    return; - -  sl = bgp->frapi->resolve_nve_nexthop; -  if (!sl) -    { -      vnc_zlog_debug_verbose ("%s: %s: RHN List is empty", (tag1 ? tag1 : ""), -                  (tag2 ? tag2 : "")); -      return; -    } - -  vnc_zlog_debug_verbose ("%s: %s: RHN list:", (tag1 ? tag1 : ""), (tag2 ? tag2 : "")); - -  /* XXX uses secret knowledge of skiplist structure */ -  for (p = sl->header->forward[0]; p; p = p->forward[0]) -    { -      char kbuf[BUFSIZ]; -      char hbuf[BUFSIZ]; -      char ubuf[BUFSIZ]; - -      pb = p->value; - -      prefix2str (p->key, kbuf, BUFSIZ); -      prefix2str (&pb->hpfx, hbuf, BUFSIZ); -      prefix2str (&pb->upfx, ubuf, BUFSIZ); - -      vnc_zlog_debug_verbose ("RHN Entry %d (q=%p): kpfx=%s, upfx=%s, hpfx=%s, ubi=%p", -                  ++count, p, kbuf, ubuf, hbuf, pb->ubi); -    } +	struct bgp *bgp; +	struct skiplist *sl; +	struct skiplistnode *p; +	struct prefix_bag *pb; +	int count = 0; + +	bgp = bgp_get_default(); +	if (!bgp) +		return; + +	sl = bgp->frapi->resolve_nve_nexthop; +	if (!sl) { +		vnc_zlog_debug_verbose("%s: %s: RHN List is empty", +				       (tag1 ? tag1 : ""), (tag2 ? tag2 : "")); +		return; +	} + +	vnc_zlog_debug_verbose("%s: %s: RHN list:", (tag1 ? tag1 : ""), +			       (tag2 ? tag2 : "")); + +	/* XXX uses secret knowledge of skiplist structure */ +	for (p = sl->header->forward[0]; p; p = p->forward[0]) { +		char kbuf[BUFSIZ]; +		char hbuf[BUFSIZ]; +		char ubuf[BUFSIZ]; + +		pb = p->value; + +		prefix2str(p->key, kbuf, BUFSIZ); +		prefix2str(&pb->hpfx, hbuf, BUFSIZ); +		prefix2str(&pb->upfx, ubuf, BUFSIZ); + +		vnc_zlog_debug_verbose( +			"RHN Entry %d (q=%p): kpfx=%s, upfx=%s, hpfx=%s, ubi=%p", +			++count, p, kbuf, ubuf, hbuf, pb->ubi); +	}  }  #endif  #ifdef ENABLE_VNC_RHNCK -static void -vnc_rhnck (char *tag) +static void vnc_rhnck(char *tag)  { -  struct bgp *bgp; -  struct skiplist *sl; -  struct skiplistnode *p; - -  bgp = bgp_get_default (); -  if (!bgp) -    return; -  sl = bgp->rfapi->resolve_nve_nexthop; - -  if (!sl) -    return; - -  /* XXX uses secret knowledge of skiplist structure */ -  for (p = sl->header->forward[0]; p; p = p->forward[0]) -    { -      struct prefix_bag *pb; -      struct prefix *pkey; -      afi_t afi; -      struct prefix pfx_orig_nexthop; - -      memset (&pfx_orig_nexthop, 0, sizeof (struct prefix));    /* keep valgrind happy */ - -      pkey = p->key; -      pb = p->value; - -      afi = family2afi (pb->upfx.family); - -      rfapiUnicastNexthop2Prefix (afi, pb->ubi->attr, &pfx_orig_nexthop); - -      /* pb->hpfx, pb->ubi nexthop, pkey should all reflect the same pfx */ -      assert (!vnc_prefix_cmp (&pb->hpfx, pkey)); -      if (vnc_prefix_cmp (&pb->hpfx, &pfx_orig_nexthop)) -        { -          char str_onh[BUFSIZ]; -          char str_nve_pfx[BUFSIZ]; - -          prefix2str (&pfx_orig_nexthop, str_onh, BUFSIZ); -          str_onh[BUFSIZ - 1] = 0; - -          prefix2str (&pb->hpfx, str_nve_pfx, BUFSIZ); -          str_nve_pfx[BUFSIZ - 1] = 0; - -          vnc_zlog_debug_verbose -            ("%s: %s: FATAL: resolve_nve_nexthop list item bi nexthop %s != nve pfx %s", -             __func__, tag, str_onh, str_nve_pfx); -          assert (0); -        } -    } -  vnc_zlog_debug_verbose ("%s: vnc_rhnck OK", tag); +	struct bgp *bgp; +	struct skiplist *sl; +	struct skiplistnode *p; + +	bgp = bgp_get_default(); +	if (!bgp) +		return; +	sl = bgp->rfapi->resolve_nve_nexthop; + +	if (!sl) +		return; + +	/* XXX uses secret knowledge of skiplist structure */ +	for (p = sl->header->forward[0]; p; p = p->forward[0]) { +		struct prefix_bag *pb; +		struct prefix *pkey; +		afi_t afi; +		struct prefix pfx_orig_nexthop; + +		memset(&pfx_orig_nexthop, 0, +		       sizeof(struct prefix)); /* keep valgrind happy */ + +		pkey = p->key; +		pb = p->value; + +		afi = family2afi(pb->upfx.family); + +		rfapiUnicastNexthop2Prefix(afi, pb->ubi->attr, +					   &pfx_orig_nexthop); + +		/* pb->hpfx, pb->ubi nexthop, pkey should all reflect the same +		 * pfx */ +		assert(!vnc_prefix_cmp(&pb->hpfx, pkey)); +		if (vnc_prefix_cmp(&pb->hpfx, &pfx_orig_nexthop)) { +			char str_onh[BUFSIZ]; +			char str_nve_pfx[BUFSIZ]; + +			prefix2str(&pfx_orig_nexthop, str_onh, BUFSIZ); +			str_onh[BUFSIZ - 1] = 0; + +			prefix2str(&pb->hpfx, str_nve_pfx, BUFSIZ); +			str_nve_pfx[BUFSIZ - 1] = 0; + +			vnc_zlog_debug_verbose( +				"%s: %s: FATAL: resolve_nve_nexthop list item bi nexthop %s != nve pfx %s", +				__func__, tag, str_onh, str_nve_pfx); +			assert(0); +		} +	} +	vnc_zlog_debug_verbose("%s: vnc_rhnck OK", tag);  }  #define VNC_RHNCK(n)	do {char buf[BUFSIZ];sprintf(buf,"%s: %s", __func__, #n);vnc_rhnck(buf);} while (0) @@ -324,1181 +299,1106 @@ vnc_rhnck (char *tag)   *   * If return code is 0, caller MUST release ecom   */ -static int -process_unicast_route ( -    struct bgp		*bgp,			/* in */ -    afi_t		afi,			/* in */ -    struct prefix	*prefix,		/* in */ -    struct bgp_info	*info,			/* in */ -    struct ecommunity	**ecom,			/* OUT */ -    struct prefix	*unicast_nexthop)	/* OUT */ +static int process_unicast_route(struct bgp *bgp,		 /* in */ +				 afi_t afi,			 /* in */ +				 struct prefix *prefix,		 /* in */ +				 struct bgp_info *info,		 /* in */ +				 struct ecommunity **ecom,       /* OUT */ +				 struct prefix *unicast_nexthop) /* OUT */  { -  struct rfapi_cfg *hc = bgp->rfapi_cfg; -  struct peer *peer = info->peer; -  struct attr *attr = info->attr; -  struct attr hattr; -  struct route_map *rmap = NULL; -  struct prefix pfx_orig_nexthop; - -  memset (&pfx_orig_nexthop, 0, sizeof (struct prefix));        /* keep valgrind happy */ - -  /* -   * prefix list check -   */ -  if (hc->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi]) -    { -      vnc_zlog_debug_verbose ("%s: HC prefix list is set, checking", __func__); -      if (prefix_list_apply -          (hc->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi], -           prefix) == PREFIX_DENY) -        { -          vnc_zlog_debug_verbose ("%s: prefix list returns DENY, blocking route", -                      __func__); -          return -1; -        } -      vnc_zlog_debug_verbose ("%s: prefix list returns PASS, allowing route", __func__); -    } - -  /* apply routemap, if any, later */ -  rmap = hc->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT]; - -  /* -   * Extract original nexthop, which we expect to be a NVE connected router -   * Note that this is the nexthop before any possible application of policy -   */ -  /* -   * Incoming prefix is unicast. If v6, it is in multiprotocol area, -   * but if v4 it is in attr->nexthop -   */ -  rfapiUnicastNexthop2Prefix (afi, attr, &pfx_orig_nexthop); - -  /* -   * route map handling -   * This code is here because it allocates an interned attr which -   * must be freed before we return. It's easier to put it after -   * all of the possible returns above. -   */ -  memset (&hattr, 0, sizeof (struct attr)); -  bgp_attr_dup (&hattr, attr);  /* hattr becomes a ghost attr */ - -  if (rmap) -    { -      struct bgp_info info; -      route_map_result_t ret; - -      memset (&info, 0, sizeof (info)); -      info.peer = peer; -      info.attr = &hattr; -      ret = route_map_apply (rmap, prefix, RMAP_BGP, &info); -      if (ret == RMAP_DENYMATCH) -        { -          bgp_attr_flush (&hattr); -          vnc_zlog_debug_verbose ("%s: route map \"%s\" says DENY, returning", __func__, -                      rmap->name); -          return -1; -        } -    } - -  /* -   * Get the (possibly altered by policy) unicast nexthop -   * for later lookup in the Import Table by caller -   */ -  rfapiUnicastNexthop2Prefix (afi, &hattr, unicast_nexthop); - -  if (hattr.ecommunity) -    *ecom = ecommunity_dup (hattr.ecommunity); -  else -    *ecom = ecommunity_new (); - -  /* -   * Done with hattr, clean up -   */ -  bgp_attr_flush (&hattr); - -  /* -   * Add EC that carries original NH of iBGP route (2 bytes = magic -   * value indicating it came from an VNC gateway; default 5226, but -   * must be user configurable). Note that this is the nexthop before -   * any application of policy. -   */ -  { -    struct ecommunity_val vnc_gateway_magic; -    uint16_t localadmin; - -    /* Using route origin extended community type */ -    memset (&vnc_gateway_magic, 0, sizeof (vnc_gateway_magic)); -    vnc_gateway_magic.val[0] = 0x01; -    vnc_gateway_magic.val[1] = 0x03; - -    /* Only works for IPv4 nexthops */ -    if (prefix->family == AF_INET) -      { -        memcpy (vnc_gateway_magic.val + 2, &unicast_nexthop->u.prefix4, 4); -      } -    localadmin = htons (hc->resolve_nve_roo_local_admin); -    memcpy (vnc_gateway_magic.val + 6, (char *) &localadmin, 2); - -    ecommunity_add_val (*ecom, &vnc_gateway_magic); -  } - -  return 0; +	struct rfapi_cfg *hc = bgp->rfapi_cfg; +	struct peer *peer = info->peer; +	struct attr *attr = info->attr; +	struct attr hattr; +	struct route_map *rmap = NULL; +	struct prefix pfx_orig_nexthop; + +	memset(&pfx_orig_nexthop, 0, +	       sizeof(struct prefix)); /* keep valgrind happy */ + +	/* +	 * prefix list check +	 */ +	if (hc->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi]) { +		vnc_zlog_debug_verbose("%s: HC prefix list is set, checking", +				       __func__); +		if (prefix_list_apply( +			    hc->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi], +			    prefix) +		    == PREFIX_DENY) { +			vnc_zlog_debug_verbose( +				"%s: prefix list returns DENY, blocking route", +				__func__); +			return -1; +		} +		vnc_zlog_debug_verbose( +			"%s: prefix list returns PASS, allowing route", +			__func__); +	} + +	/* apply routemap, if any, later */ +	rmap = hc->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT]; + +	/* +	 * Extract original nexthop, which we expect to be a NVE connected +	 * router +	 * Note that this is the nexthop before any possible application of +	 * policy +	 */ +	/* +	 * Incoming prefix is unicast. If v6, it is in multiprotocol area, +	 * but if v4 it is in attr->nexthop +	 */ +	rfapiUnicastNexthop2Prefix(afi, attr, &pfx_orig_nexthop); + +	/* +	 * route map handling +	 * This code is here because it allocates an interned attr which +	 * must be freed before we return. It's easier to put it after +	 * all of the possible returns above. +	 */ +	memset(&hattr, 0, sizeof(struct attr)); +	bgp_attr_dup(&hattr, attr); /* hattr becomes a ghost attr */ + +	if (rmap) { +		struct bgp_info info; +		route_map_result_t ret; + +		memset(&info, 0, sizeof(info)); +		info.peer = peer; +		info.attr = &hattr; +		ret = route_map_apply(rmap, prefix, RMAP_BGP, &info); +		if (ret == RMAP_DENYMATCH) { +			bgp_attr_flush(&hattr); +			vnc_zlog_debug_verbose( +				"%s: route map \"%s\" says DENY, returning", +				__func__, rmap->name); +			return -1; +		} +	} + +	/* +	 * Get the (possibly altered by policy) unicast nexthop +	 * for later lookup in the Import Table by caller +	 */ +	rfapiUnicastNexthop2Prefix(afi, &hattr, unicast_nexthop); + +	if (hattr.ecommunity) +		*ecom = ecommunity_dup(hattr.ecommunity); +	else +		*ecom = ecommunity_new(); + +	/* +	 * Done with hattr, clean up +	 */ +	bgp_attr_flush(&hattr); + +	/* +	 * Add EC that carries original NH of iBGP route (2 bytes = magic +	 * value indicating it came from an VNC gateway; default 5226, but +	 * must be user configurable). Note that this is the nexthop before +	 * any application of policy. +	 */ +	{ +		struct ecommunity_val vnc_gateway_magic; +		uint16_t localadmin; + +		/* Using route origin extended community type */ +		memset(&vnc_gateway_magic, 0, sizeof(vnc_gateway_magic)); +		vnc_gateway_magic.val[0] = 0x01; +		vnc_gateway_magic.val[1] = 0x03; + +		/* Only works for IPv4 nexthops */ +		if (prefix->family == AF_INET) { +			memcpy(vnc_gateway_magic.val + 2, +			       &unicast_nexthop->u.prefix4, 4); +		} +		localadmin = htons(hc->resolve_nve_roo_local_admin); +		memcpy(vnc_gateway_magic.val + 6, (char *)&localadmin, 2); + +		ecommunity_add_val(*ecom, &vnc_gateway_magic); +	} + +	return 0;  } -static void -vnc_import_bgp_add_route_mode_resolve_nve_one_bi ( -  struct bgp		*bgp, -  afi_t			afi, -  struct bgp_info	*bi,        /* VPN bi */ -  struct prefix_rd	*prd,       /* RD */ -  struct prefix		*prefix,    /* unicast route prefix */ -  uint32_t		*local_pref,/* NULL = no local_pref */ -  uint32_t		*med,       /* NULL = no med */ -  struct ecommunity	*ecom)      /* generated ecoms */ +static void vnc_import_bgp_add_route_mode_resolve_nve_one_bi( +	struct bgp *bgp, afi_t afi, struct bgp_info *bi, /* VPN bi */ +	struct prefix_rd *prd,				 /* RD */ +	struct prefix *prefix,   /* unicast route prefix */ +	uint32_t *local_pref,    /* NULL = no local_pref */ +	uint32_t *med,		 /* NULL = no med */ +	struct ecommunity *ecom) /* generated ecoms */  { -  struct prefix un; -  struct prefix nexthop; -  struct rfapi_ip_addr nexthop_h; -  uint32_t lifetime; -  uint32_t *plifetime; -  struct bgp_attr_encap_subtlv *encaptlvs; -  uint32_t label = 0; - -  struct rfapi_un_option      optary[3]; -  struct rfapi_un_option      *opt = NULL; -  int                         cur_opt = 0; - -  vnc_zlog_debug_verbose ("%s: entry", __func__); - -  if (bi->type != ZEBRA_ROUTE_BGP && bi->type != ZEBRA_ROUTE_BGP_DIRECT) -    { - -      return; -    } -  if (bi->sub_type != BGP_ROUTE_NORMAL && -      bi->sub_type != BGP_ROUTE_STATIC && bi->sub_type != BGP_ROUTE_RFP) -    { - -      return; -    } -  if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) -    return; - -  vncHDResolveNve.peer = bi->peer; -  if (!rfapiGetVncTunnelUnAddr (bi->attr, &un)) -    { -      if (rfapiQprefix2Raddr (&un, &vncHDResolveNve.un_addr)) -        return; -    } -  else -    { -      memset (&vncHDResolveNve.un_addr, 0, sizeof (vncHDResolveNve.un_addr)); -    } - -  /* Use nexthop of VPN route as nexthop of constructed route */ -  rfapiNexthop2Prefix (bi->attr, &nexthop); -  rfapiQprefix2Raddr (&nexthop, &nexthop_h); - -  if (rfapiGetVncLifetime (bi->attr, &lifetime)) -    { -      plifetime = NULL; -    } -  else -    { -      plifetime = &lifetime; -    } - -  if (bi->attr) -    { -      encaptlvs = bi->attr->vnc_subtlvs; -      if (bi->attr->encap_tunneltype != BGP_ENCAP_TYPE_RESERVED && -          bi->attr->encap_tunneltype != BGP_ENCAP_TYPE_MPLS) -        { -          if (opt != NULL) -            opt->next = &optary[cur_opt]; -          opt = &optary[cur_opt++]; -          memset (opt, 0, sizeof (struct rfapi_un_option)); -          opt->type = RFAPI_UN_OPTION_TYPE_TUNNELTYPE; -          opt->v.tunnel.type =  bi->attr->encap_tunneltype; -          /* TBD parse bi->attr->extra->encap_subtlvs */ -        } -    } -  else -    { -      encaptlvs = NULL; -    } - -  struct ecommunity *new_ecom = ecommunity_dup (ecom); - -  if (bi->attr && bi->attr->ecommunity) -    ecommunity_merge (new_ecom, bi->attr->ecommunity); - -  if (bi->extra) -    label = decode_label (&bi->extra->label); - -  add_vnc_route ( -    &vncHDResolveNve, -    bgp, -    SAFI_MPLS_VPN, -    prefix,					/* unicast route prefix */ -    prd, -    &nexthop_h,					/* new nexthop */ -    local_pref, -    plifetime, -    (struct bgp_tea_options *) encaptlvs,	/* RFP options */ -    opt, -    NULL, -    new_ecom, -    med,					/* NULL => don't set med */ -    (label?&label:NULL),			/* NULL= default */ -    ZEBRA_ROUTE_BGP_DIRECT, -    BGP_ROUTE_REDISTRIBUTE, -    RFAPI_AHR_RFPOPT_IS_VNCTLV);		/* flags */ - -  ecommunity_free (&new_ecom); +	struct prefix un; +	struct prefix nexthop; +	struct rfapi_ip_addr nexthop_h; +	uint32_t lifetime; +	uint32_t *plifetime; +	struct bgp_attr_encap_subtlv *encaptlvs; +	uint32_t label = 0; + +	struct rfapi_un_option optary[3]; +	struct rfapi_un_option *opt = NULL; +	int cur_opt = 0; +	vnc_zlog_debug_verbose("%s: entry", __func__); + +	if (bi->type != ZEBRA_ROUTE_BGP && bi->type != ZEBRA_ROUTE_BGP_DIRECT) { + +		return; +	} +	if (bi->sub_type != BGP_ROUTE_NORMAL && bi->sub_type != BGP_ROUTE_STATIC +	    && bi->sub_type != BGP_ROUTE_RFP) { + +		return; +	} +	if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) +		return; + +	vncHDResolveNve.peer = bi->peer; +	if (!rfapiGetVncTunnelUnAddr(bi->attr, &un)) { +		if (rfapiQprefix2Raddr(&un, &vncHDResolveNve.un_addr)) +			return; +	} else { +		memset(&vncHDResolveNve.un_addr, 0, +		       sizeof(vncHDResolveNve.un_addr)); +	} + +	/* Use nexthop of VPN route as nexthop of constructed route */ +	rfapiNexthop2Prefix(bi->attr, &nexthop); +	rfapiQprefix2Raddr(&nexthop, &nexthop_h); + +	if (rfapiGetVncLifetime(bi->attr, &lifetime)) { +		plifetime = NULL; +	} else { +		plifetime = &lifetime; +	} + +	if (bi->attr) { +		encaptlvs = bi->attr->vnc_subtlvs; +		if (bi->attr->encap_tunneltype != BGP_ENCAP_TYPE_RESERVED +		    && bi->attr->encap_tunneltype != BGP_ENCAP_TYPE_MPLS) { +			if (opt != NULL) +				opt->next = &optary[cur_opt]; +			opt = &optary[cur_opt++]; +			memset(opt, 0, sizeof(struct rfapi_un_option)); +			opt->type = RFAPI_UN_OPTION_TYPE_TUNNELTYPE; +			opt->v.tunnel.type = bi->attr->encap_tunneltype; +			/* TBD parse bi->attr->extra->encap_subtlvs */ +		} +	} else { +		encaptlvs = NULL; +	} + +	struct ecommunity *new_ecom = ecommunity_dup(ecom); + +	if (bi->attr && bi->attr->ecommunity) +		ecommunity_merge(new_ecom, bi->attr->ecommunity); + +	if (bi->extra) +		label = decode_label(&bi->extra->label); + +	add_vnc_route(&vncHDResolveNve, bgp, SAFI_MPLS_VPN, +		      prefix,	  /* unicast route prefix */ +		      prd, &nexthop_h, /* new nexthop */ +		      local_pref, plifetime, +		      (struct bgp_tea_options *)encaptlvs, /* RFP options */ +		      opt, NULL, new_ecom, med, /* NULL => don't set med */ +		      (label ? &label : NULL),  /* NULL= default */ +		      ZEBRA_ROUTE_BGP_DIRECT, BGP_ROUTE_REDISTRIBUTE, +		      RFAPI_AHR_RFPOPT_IS_VNCTLV); /* flags */ + +	ecommunity_free(&new_ecom);  } -static void -vnc_import_bgp_add_route_mode_resolve_nve_one_rd ( -    struct prefix_rd	*prd,		/* RD */ -    struct bgp_table	*table_rd,	/* per-rd VPN route table */ -    afi_t		afi, -    struct bgp		*bgp, -    struct prefix	*prefix,	/* unicast prefix */ -    struct ecommunity	*ecom,		/* generated ecoms */ -    uint32_t		*local_pref,	/* NULL = no local_pref */ -    uint32_t		*med,		/* NULL = no med */ -    struct prefix	*ubi_nexthop)	/* unicast nexthop */ +static void vnc_import_bgp_add_route_mode_resolve_nve_one_rd( +	struct prefix_rd *prd,      /* RD */ +	struct bgp_table *table_rd, /* per-rd VPN route table */ +	afi_t afi, struct bgp *bgp, struct prefix *prefix, /* unicast prefix */ +	struct ecommunity *ecom,			   /* generated ecoms */ +	uint32_t *local_pref,       /* NULL = no local_pref */ +	uint32_t *med,		    /* NULL = no med */ +	struct prefix *ubi_nexthop) /* unicast nexthop */  { -  struct bgp_node *bn; -  struct bgp_info *bi; +	struct bgp_node *bn; +	struct bgp_info *bi; -  if (!table_rd) -    return; +	if (!table_rd) +		return; -  { -    char str_nh[BUFSIZ]; +	{ +		char str_nh[BUFSIZ]; -    prefix2str (ubi_nexthop, str_nh, BUFSIZ); -    str_nh[BUFSIZ - 1] = 0; +		prefix2str(ubi_nexthop, str_nh, BUFSIZ); +		str_nh[BUFSIZ - 1] = 0; -    vnc_zlog_debug_verbose ("%s: ubi_nexthop=%s", __func__, str_nh); -  } +		vnc_zlog_debug_verbose("%s: ubi_nexthop=%s", __func__, str_nh); +	} -  /* exact match */ -  bn = bgp_node_lookup (table_rd, ubi_nexthop); -  if (!bn) -    { -      vnc_zlog_debug_verbose ("%s: no match in RD's table for ubi_nexthop", __func__); -      return; -    } +	/* exact match */ +	bn = bgp_node_lookup(table_rd, ubi_nexthop); +	if (!bn) { +		vnc_zlog_debug_verbose( +			"%s: no match in RD's table for ubi_nexthop", __func__); +		return; +	} -  /* Iterate over bgp_info items at this node */ -  for (bi = bn->info; bi; bi = bi->next) -    { +	/* Iterate over bgp_info items at this node */ +	for (bi = bn->info; bi; bi = bi->next) { -      vnc_import_bgp_add_route_mode_resolve_nve_one_bi (bgp, afi, bi,   /* VPN bi */ -                                                        prd, -                                                        prefix, -                                                        local_pref, -                                                        med, ecom); -    } +		vnc_import_bgp_add_route_mode_resolve_nve_one_bi( +			bgp, afi, bi, /* VPN bi */ +			prd, prefix, local_pref, med, ecom); +	} -  bgp_unlock_node (bn); +	bgp_unlock_node(bn);  } -static void -vnc_import_bgp_add_route_mode_resolve_nve ( -    struct bgp		*bgp, -    struct prefix	*prefix,/* unicast prefix */ -    struct bgp_info	*info)	/* unicast info */ +static void vnc_import_bgp_add_route_mode_resolve_nve( +	struct bgp *bgp, struct prefix *prefix, /* unicast prefix */ +	struct bgp_info *info)			/* unicast info */  { -  afi_t afi = family2afi (prefix->family); -  struct rfapi_cfg *hc = NULL; - -  struct prefix pfx_unicast_nexthop = { 0 };    /* happy valgrind */ - -  struct ecommunity *ecom = NULL; -  uint32_t local_pref; -  uint32_t *med = NULL; - -  struct prefix_bag *pb; -  struct bgp_node *bnp;         /* prd table node */ - -  /*debugging */ -  { -    char str_pfx[BUFSIZ]; -    char str_nh[BUFSIZ]; -    struct prefix nh; - -    prefix2str (prefix, str_pfx, BUFSIZ); -    str_pfx[BUFSIZ - 1] = 0; - -    nh.prefixlen = 0; -    rfapiUnicastNexthop2Prefix (afi, info->attr, &nh); -    if (nh.prefixlen) -      { -        prefix2str (&nh, str_nh, BUFSIZ); -        str_nh[BUFSIZ - 1] = 0; -      } -    else -      { -        str_nh[0] = '?'; -        str_nh[1] = 0; -      } - -    vnc_zlog_debug_verbose ("%s(bgp=%p, unicast prefix=%s, unicast nh=%s)", -                __func__, bgp, str_pfx, str_nh); -  } - -  if (info->type != ZEBRA_ROUTE_BGP) -    { -      vnc_zlog_debug_verbose ("%s: unicast type %d=\"%s\" is not %d=%s, skipping", -                  __func__, info->type, zebra_route_string (info->type), -                  ZEBRA_ROUTE_BGP, "ZEBRA_ROUTE_BGP"); -      return; -    } - -  /* -   * Preliminary checks -   */ - -  if (!afi) -    { -      zlog_err ("%s: can't get afi of prefix", __func__); -      return; -    } - -  if (!(hc = bgp->rfapi_cfg)) -    { -      vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); -      return; -    } - -  /* check vnc redist flag for bgp direct routes */ -  if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) -    { -      vnc_zlog_debug_verbose -        ("%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping", -         __func__, afi); -      return; -    } - - -  if (process_unicast_route (bgp, afi, prefix, info, -                             &ecom, &pfx_unicast_nexthop)) -    { - -      vnc_zlog_debug_verbose ("%s: process_unicast_route error, skipping", __func__); -      return; -    } - -  local_pref = calc_local_pref (info->attr, info->peer); -  if (info->attr && -      (info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))) -    { - -      med = &info->attr->med; -    } - - -  /* -   * At this point, we have allocated: -   * -   *  ecom    ecommunity ptr, union of unicast and ROO parts (no NVE part) -   * -   * And we have set: -   * -   *  pfx_unicast_nexthop     nexthop of uncast route -   */ - -  if (!bgp->rfapi->resolve_nve_nexthop) -    { -      bgp->rfapi->resolve_nve_nexthop = -        skiplist_new (SKIPLIST_FLAG_ALLOW_DUPLICATES, vnc_prefix_cmp, -                      prefix_bag_free); -    } - -  pb = XCALLOC (MTYPE_RFAPI_PREFIX_BAG, sizeof (struct prefix_bag)); -  pb->hpfx = pfx_unicast_nexthop; -  pb->ubi = info; -  pb->upfx = *prefix; - -  bgp_info_lock (info);         /* skiplist refers to it */ -  skiplist_insert (bgp->rfapi->resolve_nve_nexthop, &pb->hpfx, pb); - -  /* -   * Iterate over RDs in VPN RIB. For each RD, look up unicast nexthop -   * (exact match, /32). If an exact match is found, call add_vnc_route. -   */ - -  for (bnp = bgp_table_top (bgp->rib[afi][SAFI_MPLS_VPN]); bnp; -       bnp = bgp_route_next (bnp)) -    { - -      struct bgp_table *table; - -      table = (struct bgp_table *) (bnp->info); - -      if (!table) -        continue; - -      vnc_import_bgp_add_route_mode_resolve_nve_one_rd ((struct prefix_rd *) -                                                        &bnp->p, table, afi, -                                                        bgp, prefix, ecom, -                                                        &local_pref, med, -                                                        &pfx_unicast_nexthop); - -    } - - -  if (ecom) -    ecommunity_free (&ecom); - -  vnc_zlog_debug_verbose ("%s: done", __func__); +	afi_t afi = family2afi(prefix->family); +	struct rfapi_cfg *hc = NULL; + +	struct prefix pfx_unicast_nexthop = {0}; /* happy valgrind */ + +	struct ecommunity *ecom = NULL; +	uint32_t local_pref; +	uint32_t *med = NULL; + +	struct prefix_bag *pb; +	struct bgp_node *bnp; /* prd table node */ + +	/*debugging */ +	{ +		char str_pfx[BUFSIZ]; +		char str_nh[BUFSIZ]; +		struct prefix nh; + +		prefix2str(prefix, str_pfx, BUFSIZ); +		str_pfx[BUFSIZ - 1] = 0; + +		nh.prefixlen = 0; +		rfapiUnicastNexthop2Prefix(afi, info->attr, &nh); +		if (nh.prefixlen) { +			prefix2str(&nh, str_nh, BUFSIZ); +			str_nh[BUFSIZ - 1] = 0; +		} else { +			str_nh[0] = '?'; +			str_nh[1] = 0; +		} + +		vnc_zlog_debug_verbose( +			"%s(bgp=%p, unicast prefix=%s, unicast nh=%s)", +			__func__, bgp, str_pfx, str_nh); +	} + +	if (info->type != ZEBRA_ROUTE_BGP) { +		vnc_zlog_debug_verbose( +			"%s: unicast type %d=\"%s\" is not %d=%s, skipping", +			__func__, info->type, zebra_route_string(info->type), +			ZEBRA_ROUTE_BGP, "ZEBRA_ROUTE_BGP"); +		return; +	} + +	/* +	 * Preliminary checks +	 */ + +	if (!afi) { +		zlog_err("%s: can't get afi of prefix", __func__); +		return; +	} + +	if (!(hc = bgp->rfapi_cfg)) { +		vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", +				       __func__); +		return; +	} + +	/* check vnc redist flag for bgp direct routes */ +	if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) { +		vnc_zlog_debug_verbose( +			"%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping", +			__func__, afi); +		return; +	} + + +	if (process_unicast_route(bgp, afi, prefix, info, &ecom, +				  &pfx_unicast_nexthop)) { + +		vnc_zlog_debug_verbose( +			"%s: process_unicast_route error, skipping", __func__); +		return; +	} + +	local_pref = calc_local_pref(info->attr, info->peer); +	if (info->attr +	    && (info->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))) { + +		med = &info->attr->med; +	} + + +	/* +	 * At this point, we have allocated: +	 * +	 *  ecom    ecommunity ptr, union of unicast and ROO parts (no NVE part) +	 * +	 * And we have set: +	 * +	 *  pfx_unicast_nexthop     nexthop of uncast route +	 */ + +	if (!bgp->rfapi->resolve_nve_nexthop) { +		bgp->rfapi->resolve_nve_nexthop = +			skiplist_new(SKIPLIST_FLAG_ALLOW_DUPLICATES, +				     vnc_prefix_cmp, prefix_bag_free); +	} + +	pb = XCALLOC(MTYPE_RFAPI_PREFIX_BAG, sizeof(struct prefix_bag)); +	pb->hpfx = pfx_unicast_nexthop; +	pb->ubi = info; +	pb->upfx = *prefix; + +	bgp_info_lock(info); /* skiplist refers to it */ +	skiplist_insert(bgp->rfapi->resolve_nve_nexthop, &pb->hpfx, pb); + +	/* +	 * Iterate over RDs in VPN RIB. For each RD, look up unicast nexthop +	 * (exact match, /32). If an exact match is found, call add_vnc_route. +	 */ + +	for (bnp = bgp_table_top(bgp->rib[afi][SAFI_MPLS_VPN]); bnp; +	     bnp = bgp_route_next(bnp)) { + +		struct bgp_table *table; + +		table = (struct bgp_table *)(bnp->info); + +		if (!table) +			continue; + +		vnc_import_bgp_add_route_mode_resolve_nve_one_rd( +			(struct prefix_rd *)&bnp->p, table, afi, bgp, prefix, +			ecom, &local_pref, med, &pfx_unicast_nexthop); +	} + + +	if (ecom) +		ecommunity_free(&ecom); + +	vnc_zlog_debug_verbose("%s: done", __func__);  } -static void -vnc_import_bgp_add_route_mode_plain (struct bgp *bgp, -                                     struct prefix *prefix, -                                     struct bgp_info *info) +static void vnc_import_bgp_add_route_mode_plain(struct bgp *bgp, +						struct prefix *prefix, +						struct bgp_info *info)  { -  afi_t afi = family2afi (prefix->family); -  struct peer *peer = info->peer; -  struct attr *attr = info->attr; -  struct attr hattr; -  struct rfapi_cfg *hc = NULL; -  struct attr *iattr = NULL; - -  struct rfapi_ip_addr vnaddr; -  struct prefix vn_pfx_space; -  struct prefix *vn_pfx = NULL; -  int ahr_flags = 0; -  struct ecommunity *ecom = NULL; -  struct prefix_rd prd; -  struct route_map *rmap = NULL; -  uint32_t local_pref; -  uint32_t *med = NULL; - -  { -    char buf[BUFSIZ]; - -    buf[0] = 0; -    prefix2str (prefix, buf, BUFSIZ); -    buf[BUFSIZ - 1] = 0; -    vnc_zlog_debug_verbose ("%s(prefix=%s) entry", __func__, buf); -  } - -  if (!afi) -    { -      zlog_err ("%s: can't get afi of prefix", __func__); -      return; -    } - -  if (!(hc = bgp->rfapi_cfg)) -    { -      vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); -      return; -    } - -  /* check vnc redist flag for bgp direct routes */ -  if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) -    { -      vnc_zlog_debug_verbose -        ("%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping", -         __func__, afi); -      return; -    } - -  /* -   * mode "plain" specific code -   */ -  { -    vnc_zlog_debug_verbose ("%s: NOT using redist RFG", __func__); - -    /* -     * prefix list check -     */ -    if (hc->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi]) -      { -        vnc_zlog_debug_verbose ("%s: HC prefix list is set, checking", __func__); -        if (prefix_list_apply -            (hc->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi], -             prefix) == PREFIX_DENY) -          { -            vnc_zlog_debug_verbose ("%s: prefix list returns DENY, blocking route", -                        __func__); -            return; -          } -        vnc_zlog_debug_verbose ("%s: prefix list returns PASS, allowing route", __func__); -      } - -    /* apply routemap, if any, later */ -    rmap = hc->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT]; - -    /* -     * Incoming prefix is unicast. If v6, it is in multiprotocol area, -     * but if v4 it is in attr->nexthop -     */ -    rfapiUnicastNexthop2Prefix (afi, attr, &vn_pfx_space); -    vn_pfx = &vn_pfx_space; - -    /* UN address */ -    ahr_flags |= RFAPI_AHR_NO_TUNNEL_SUBTLV; -  } - -  if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) -    { -      char buf[BUFSIZ]; - -      buf[0] = 0; -      prefix2str (vn_pfx, buf, BUFSIZ); -      buf[BUFSIZ - 1] = 0; -      vnc_zlog_debug_any ("%s vn_pfx=%s", __func__, buf); -    } - -  /* -   * Compute VN address -   */ -  if (rfapiQprefix2Raddr (vn_pfx, &vnaddr)) -    { -      vnc_zlog_debug_verbose ("%s: redist VN invalid, skipping", __func__); -      return; -    } - -  /* -   * route map handling -   * This code is here because it allocates an interned attr which -   * must be freed before we return. It's easier to put it after -   * all of the possible returns above. -   */ -  memset (&hattr, 0, sizeof (struct attr)); -  bgp_attr_dup (&hattr, attr);  /* hattr becomes a ghost attr */ - -  if (rmap) -    { -      struct bgp_info info; -      route_map_result_t ret; - -      memset (&info, 0, sizeof (info)); -      info.peer = peer; -      info.attr = &hattr; -      ret = route_map_apply (rmap, prefix, RMAP_BGP, &info); -      if (ret == RMAP_DENYMATCH) -        { -          bgp_attr_flush (&hattr); -          vnc_zlog_debug_verbose ("%s: route map \"%s\" says DENY, returning", __func__, -                      rmap->name); -          return; -        } -    } - -  iattr = bgp_attr_intern (&hattr); -  bgp_attr_flush (&hattr); - -  /* Now iattr is an allocated interned attr */ - -  /* -   * Mode "plain" specific code -   * -   * Sets RD in dummy HD -   * Allocates ecom -   */ -  { -    if (vnaddr.addr_family != AF_INET) -      { -        vnc_zlog_debug_verbose -          ("%s: can't auto-assign RD, VN AF (%d) is not IPv4, skipping", -           __func__, vnaddr.addr_family); -        if (iattr) -          { -            bgp_attr_unintern (&iattr); -          } -        return; -      } -    memset (&prd, 0, sizeof (prd)); -    rfapi_set_autord_from_vn (&prd, &vnaddr); - -    if (iattr && iattr->ecommunity) -      ecom = ecommunity_dup (iattr->ecommunity); - -  } - -  local_pref = calc_local_pref (iattr, peer); - -  if (iattr && (iattr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))) -    { -      med = &iattr->med; -    } - -  if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) -    { -      char buf[BUFSIZ]; - -      buf[0] = 0; -      rfapiRfapiIpAddr2Str (&vnaddr, buf, BUFSIZ); -      buf[BUFSIZ - 1] = 0; -      vnc_zlog_debug_any ("%s: setting vnaddr to %s", __func__, buf); -    } - -  vncHDBgpDirect.peer = peer; -  add_vnc_route (&vncHDBgpDirect, bgp, SAFI_MPLS_VPN, prefix, &prd, &vnaddr, &local_pref, &(bgp->rfapi_cfg->redist_lifetime), NULL,     /* RFP options */ -                 NULL, NULL, ecom, med, /* med */ -                 NULL,          /* label: default */ -                 ZEBRA_ROUTE_BGP_DIRECT, BGP_ROUTE_REDISTRIBUTE, ahr_flags); -  vncHDBgpDirect.peer = NULL; - -  if (ecom) -    ecommunity_free (&ecom); +	afi_t afi = family2afi(prefix->family); +	struct peer *peer = info->peer; +	struct attr *attr = info->attr; +	struct attr hattr; +	struct rfapi_cfg *hc = NULL; +	struct attr *iattr = NULL; + +	struct rfapi_ip_addr vnaddr; +	struct prefix vn_pfx_space; +	struct prefix *vn_pfx = NULL; +	int ahr_flags = 0; +	struct ecommunity *ecom = NULL; +	struct prefix_rd prd; +	struct route_map *rmap = NULL; +	uint32_t local_pref; +	uint32_t *med = NULL; + +	{ +		char buf[BUFSIZ]; + +		buf[0] = 0; +		prefix2str(prefix, buf, BUFSIZ); +		buf[BUFSIZ - 1] = 0; +		vnc_zlog_debug_verbose("%s(prefix=%s) entry", __func__, buf); +	} + +	if (!afi) { +		zlog_err("%s: can't get afi of prefix", __func__); +		return; +	} + +	if (!(hc = bgp->rfapi_cfg)) { +		vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", +				       __func__); +		return; +	} + +	/* check vnc redist flag for bgp direct routes */ +	if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) { +		vnc_zlog_debug_verbose( +			"%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping", +			__func__, afi); +		return; +	} + +	/* +	 * mode "plain" specific code +	 */ +	{ +		vnc_zlog_debug_verbose("%s: NOT using redist RFG", __func__); + +		/* +		 * prefix list check +		 */ +		if (hc->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi]) { +			vnc_zlog_debug_verbose( +				"%s: HC prefix list is set, checking", +				__func__); +			if (prefix_list_apply( +				    hc->plist_redist[ZEBRA_ROUTE_BGP_DIRECT] +						    [afi], +				    prefix) +			    == PREFIX_DENY) { +				vnc_zlog_debug_verbose( +					"%s: prefix list returns DENY, blocking route", +					__func__); +				return; +			} +			vnc_zlog_debug_verbose( +				"%s: prefix list returns PASS, allowing route", +				__func__); +		} + +		/* apply routemap, if any, later */ +		rmap = hc->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT]; + +		/* +		 * Incoming prefix is unicast. If v6, it is in multiprotocol +		 * area, +		 * but if v4 it is in attr->nexthop +		 */ +		rfapiUnicastNexthop2Prefix(afi, attr, &vn_pfx_space); +		vn_pfx = &vn_pfx_space; + +		/* UN address */ +		ahr_flags |= RFAPI_AHR_NO_TUNNEL_SUBTLV; +	} + +	if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) { +		char buf[BUFSIZ]; + +		buf[0] = 0; +		prefix2str(vn_pfx, buf, BUFSIZ); +		buf[BUFSIZ - 1] = 0; +		vnc_zlog_debug_any("%s vn_pfx=%s", __func__, buf); +	} + +	/* +	 * Compute VN address +	 */ +	if (rfapiQprefix2Raddr(vn_pfx, &vnaddr)) { +		vnc_zlog_debug_verbose("%s: redist VN invalid, skipping", +				       __func__); +		return; +	} + +	/* +	 * route map handling +	 * This code is here because it allocates an interned attr which +	 * must be freed before we return. It's easier to put it after +	 * all of the possible returns above. +	 */ +	memset(&hattr, 0, sizeof(struct attr)); +	bgp_attr_dup(&hattr, attr); /* hattr becomes a ghost attr */ + +	if (rmap) { +		struct bgp_info info; +		route_map_result_t ret; + +		memset(&info, 0, sizeof(info)); +		info.peer = peer; +		info.attr = &hattr; +		ret = route_map_apply(rmap, prefix, RMAP_BGP, &info); +		if (ret == RMAP_DENYMATCH) { +			bgp_attr_flush(&hattr); +			vnc_zlog_debug_verbose( +				"%s: route map \"%s\" says DENY, returning", +				__func__, rmap->name); +			return; +		} +	} + +	iattr = bgp_attr_intern(&hattr); +	bgp_attr_flush(&hattr); + +	/* Now iattr is an allocated interned attr */ + +	/* +	 * Mode "plain" specific code +	 * +	 * Sets RD in dummy HD +	 * Allocates ecom +	 */ +	{ +		if (vnaddr.addr_family != AF_INET) { +			vnc_zlog_debug_verbose( +				"%s: can't auto-assign RD, VN AF (%d) is not IPv4, skipping", +				__func__, vnaddr.addr_family); +			if (iattr) { +				bgp_attr_unintern(&iattr); +			} +			return; +		} +		memset(&prd, 0, sizeof(prd)); +		rfapi_set_autord_from_vn(&prd, &vnaddr); + +		if (iattr && iattr->ecommunity) +			ecom = ecommunity_dup(iattr->ecommunity); +	} + +	local_pref = calc_local_pref(iattr, peer); + +	if (iattr && (iattr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))) { +		med = &iattr->med; +	} + +	if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) { +		char buf[BUFSIZ]; + +		buf[0] = 0; +		rfapiRfapiIpAddr2Str(&vnaddr, buf, BUFSIZ); +		buf[BUFSIZ - 1] = 0; +		vnc_zlog_debug_any("%s: setting vnaddr to %s", __func__, buf); +	} + +	vncHDBgpDirect.peer = peer; +	add_vnc_route(&vncHDBgpDirect, bgp, SAFI_MPLS_VPN, prefix, &prd, +		      &vnaddr, &local_pref, &(bgp->rfapi_cfg->redist_lifetime), +		      NULL,		     /* RFP options */ +		      NULL, NULL, ecom, med, /* med */ +		      NULL,		     /* label: default */ +		      ZEBRA_ROUTE_BGP_DIRECT, BGP_ROUTE_REDISTRIBUTE, +		      ahr_flags); +	vncHDBgpDirect.peer = NULL; + +	if (ecom) +		ecommunity_free(&ecom);  }  static void -vnc_import_bgp_add_route_mode_nvegroup (struct bgp *bgp, -                                        struct prefix *prefix, -                                        struct bgp_info *info, -                                        struct rfapi_nve_group_cfg *rfg) +vnc_import_bgp_add_route_mode_nvegroup(struct bgp *bgp, struct prefix *prefix, +				       struct bgp_info *info, +				       struct rfapi_nve_group_cfg *rfg)  { -  afi_t afi = family2afi (prefix->family); -  struct peer *peer = info->peer; -  struct attr *attr = info->attr; -  struct attr hattr; -  struct rfapi_cfg *hc = NULL; -  struct attr *iattr = NULL; - -  struct rfapi_ip_addr vnaddr; -  struct prefix *vn_pfx = NULL; -  int ahr_flags = 0; -  struct ecommunity *ecom = NULL; -  struct prefix_rd prd; -  struct route_map *rmap = NULL; -  uint32_t local_pref; - -  { -    char buf[BUFSIZ]; - -    buf[0] = 0; -    prefix2str (prefix, buf, BUFSIZ); -    buf[BUFSIZ - 1] = 0; -    vnc_zlog_debug_verbose ("%s(prefix=%s) entry", __func__, buf); -  } - -  assert (rfg); - -  if (!afi) -    { -      zlog_err ("%s: can't get afi of prefix", __func__); -      return; -    } - -  if (!(hc = bgp->rfapi_cfg)) -    { -      vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); -      return; -    } - -  /* check vnc redist flag for bgp direct routes */ -  if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) -    { -      vnc_zlog_debug_verbose -        ("%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping", -         __func__, afi); -      return; -    } - - -  /* -   * RFG-specific code -   */ -  { - -    struct rfapi_ip_prefix pfx_un; - -    vnc_zlog_debug_verbose ("%s: using redist RFG", __func__); - -    /* -     * RFG prefix list check -     */ -    if (rfg->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi]) -      { -        vnc_zlog_debug_verbose ("%s: RFG prefix list is set, checking", __func__); -        if (prefix_list_apply -            (rfg->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi], -             prefix) == PREFIX_DENY) -          { -            vnc_zlog_debug_verbose ("%s: prefix list returns DENY, blocking route", -                        __func__); -            return; -          } -        vnc_zlog_debug_verbose ("%s: prefix list returns PASS, allowing route", __func__); -      } - -    /* apply routemap, if any, later */ -    rmap = rfg->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT]; - -    /* -     * export nve group's VN addr prefix must be a /32 which -     * will yield the VN addr to use -     */ -    vn_pfx = &rfg->vn_prefix; - -    /* -     * UN Address -     */ -    if (!is_host_prefix (&rfg->un_prefix)) -      { -        /* NB prefixlen==0 means it has not been configured */ -        vnc_zlog_debug_verbose ("%s: redist RFG UN pfx not host pfx (plen=%d), skipping", -                    __func__, rfg->un_prefix.prefixlen); -        return; -      } - -    rfapiQprefix2Rprefix (&rfg->un_prefix, &pfx_un); - -    vncHDBgpDirect.un_addr = pfx_un.prefix; -  } - -  if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) -    { -      char buf[BUFSIZ]; - -      buf[0] = 0; -      prefix2str (vn_pfx, buf, BUFSIZ); -      buf[BUFSIZ - 1] = 0; -      vnc_zlog_debug_any ("%s vn_pfx=%s", __func__, buf); -    } - -  /* -   * Compute VN address -   */ -  if (rfapiQprefix2Raddr (vn_pfx, &vnaddr)) -    { -      vnc_zlog_debug_verbose ("%s: redist VN invalid, skipping", __func__); -      return; -    } - -  /* -   * route map handling -   * This code is here because it allocates an interned attr which -   * must be freed before we return. It's easier to put it after -   * all of the possible returns above. -   */ -  memset (&hattr, 0, sizeof (struct attr)); -  bgp_attr_dup (&hattr, attr);  /* hattr becomes a ghost attr */ - -  if (rmap) -    { -      struct bgp_info info; -      route_map_result_t ret; - -      memset (&info, 0, sizeof (info)); -      info.peer = peer; -      info.attr = &hattr; -      ret = route_map_apply (rmap, prefix, RMAP_BGP, &info); -      if (ret == RMAP_DENYMATCH) -        { -          bgp_attr_flush (&hattr); -          vnc_zlog_debug_verbose ("%s: route map \"%s\" says DENY, returning", __func__, -                      rmap->name); -          return; -        } -    } - -  iattr = bgp_attr_intern (&hattr); -  bgp_attr_flush (&hattr); - -  /* Now iattr is an allocated interned attr */ - -  /* -   * RFG-specific code -   * -   * Sets RD in dummy HD -   * Allocates ecom -   */ -  { - -    memset (&prd, 0, sizeof (prd)); -    prd = rfg->rd; -    prd.family = AF_UNSPEC; -    prd.prefixlen = 64; - -    if (rfg->rd.family == AF_UNIX) -      { -        rfapi_set_autord_from_vn (&prd, &vnaddr); -      } - -    if (rfg->rt_export_list) -      ecom = ecommunity_dup (bgp->rfapi_cfg->rfg_redist->rt_export_list); -    else -      ecom = ecommunity_new (); - -    if (iattr && iattr->ecommunity) -      ecom = ecommunity_merge (ecom, iattr->ecommunity); -  } - -  local_pref = calc_local_pref (iattr, peer); - -  if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) -    { -      char buf[BUFSIZ]; - -      buf[0] = 0; -      rfapiRfapiIpAddr2Str (&vnaddr, buf, BUFSIZ); -      buf[BUFSIZ - 1] = 0; -      vnc_zlog_debug_any ("%s: setting vnaddr to %s", __func__, buf); -    } - -  vncHDBgpDirect.peer = peer; -  add_vnc_route ( -    &vncHDBgpDirect, -    bgp, -    SAFI_MPLS_VPN, -    prefix, -    &prd, -    &vnaddr, -    &local_pref, -    &(bgp->rfapi_cfg->redist_lifetime), -    NULL,          /* RFP options */ -    NULL, -    NULL, -    ecom, -    NULL,          /* med */ -    NULL,          /* label: default */ -    ZEBRA_ROUTE_BGP_DIRECT, -    BGP_ROUTE_REDISTRIBUTE, -    ahr_flags); -  vncHDBgpDirect.peer = NULL; - -  if (ecom) -    ecommunity_free (&ecom); +	afi_t afi = family2afi(prefix->family); +	struct peer *peer = info->peer; +	struct attr *attr = info->attr; +	struct attr hattr; +	struct rfapi_cfg *hc = NULL; +	struct attr *iattr = NULL; + +	struct rfapi_ip_addr vnaddr; +	struct prefix *vn_pfx = NULL; +	int ahr_flags = 0; +	struct ecommunity *ecom = NULL; +	struct prefix_rd prd; +	struct route_map *rmap = NULL; +	uint32_t local_pref; + +	{ +		char buf[BUFSIZ]; + +		buf[0] = 0; +		prefix2str(prefix, buf, BUFSIZ); +		buf[BUFSIZ - 1] = 0; +		vnc_zlog_debug_verbose("%s(prefix=%s) entry", __func__, buf); +	} + +	assert(rfg); + +	if (!afi) { +		zlog_err("%s: can't get afi of prefix", __func__); +		return; +	} + +	if (!(hc = bgp->rfapi_cfg)) { +		vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", +				       __func__); +		return; +	} + +	/* check vnc redist flag for bgp direct routes */ +	if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) { +		vnc_zlog_debug_verbose( +			"%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping", +			__func__, afi); +		return; +	} + + +	/* +	 * RFG-specific code +	 */ +	{ + +		struct rfapi_ip_prefix pfx_un; + +		vnc_zlog_debug_verbose("%s: using redist RFG", __func__); + +		/* +		 * RFG prefix list check +		 */ +		if (rfg->plist_redist[ZEBRA_ROUTE_BGP_DIRECT][afi]) { +			vnc_zlog_debug_verbose( +				"%s: RFG prefix list is set, checking", +				__func__); +			if (prefix_list_apply( +				    rfg->plist_redist[ZEBRA_ROUTE_BGP_DIRECT] +						     [afi], +				    prefix) +			    == PREFIX_DENY) { +				vnc_zlog_debug_verbose( +					"%s: prefix list returns DENY, blocking route", +					__func__); +				return; +			} +			vnc_zlog_debug_verbose( +				"%s: prefix list returns PASS, allowing route", +				__func__); +		} + +		/* apply routemap, if any, later */ +		rmap = rfg->routemap_redist[ZEBRA_ROUTE_BGP_DIRECT]; + +		/* +		 * export nve group's VN addr prefix must be a /32 which +		 * will yield the VN addr to use +		 */ +		vn_pfx = &rfg->vn_prefix; + +		/* +		 * UN Address +		 */ +		if (!is_host_prefix(&rfg->un_prefix)) { +			/* NB prefixlen==0 means it has not been configured */ +			vnc_zlog_debug_verbose( +				"%s: redist RFG UN pfx not host pfx (plen=%d), skipping", +				__func__, rfg->un_prefix.prefixlen); +			return; +		} + +		rfapiQprefix2Rprefix(&rfg->un_prefix, &pfx_un); + +		vncHDBgpDirect.un_addr = pfx_un.prefix; +	} + +	if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) { +		char buf[BUFSIZ]; + +		buf[0] = 0; +		prefix2str(vn_pfx, buf, BUFSIZ); +		buf[BUFSIZ - 1] = 0; +		vnc_zlog_debug_any("%s vn_pfx=%s", __func__, buf); +	} + +	/* +	 * Compute VN address +	 */ +	if (rfapiQprefix2Raddr(vn_pfx, &vnaddr)) { +		vnc_zlog_debug_verbose("%s: redist VN invalid, skipping", +				       __func__); +		return; +	} + +	/* +	 * route map handling +	 * This code is here because it allocates an interned attr which +	 * must be freed before we return. It's easier to put it after +	 * all of the possible returns above. +	 */ +	memset(&hattr, 0, sizeof(struct attr)); +	bgp_attr_dup(&hattr, attr); /* hattr becomes a ghost attr */ + +	if (rmap) { +		struct bgp_info info; +		route_map_result_t ret; + +		memset(&info, 0, sizeof(info)); +		info.peer = peer; +		info.attr = &hattr; +		ret = route_map_apply(rmap, prefix, RMAP_BGP, &info); +		if (ret == RMAP_DENYMATCH) { +			bgp_attr_flush(&hattr); +			vnc_zlog_debug_verbose( +				"%s: route map \"%s\" says DENY, returning", +				__func__, rmap->name); +			return; +		} +	} + +	iattr = bgp_attr_intern(&hattr); +	bgp_attr_flush(&hattr); + +	/* Now iattr is an allocated interned attr */ + +	/* +	 * RFG-specific code +	 * +	 * Sets RD in dummy HD +	 * Allocates ecom +	 */ +	{ + +		memset(&prd, 0, sizeof(prd)); +		prd = rfg->rd; +		prd.family = AF_UNSPEC; +		prd.prefixlen = 64; + +		if (rfg->rd.family == AF_UNIX) { +			rfapi_set_autord_from_vn(&prd, &vnaddr); +		} + +		if (rfg->rt_export_list) +			ecom = ecommunity_dup( +				bgp->rfapi_cfg->rfg_redist->rt_export_list); +		else +			ecom = ecommunity_new(); + +		if (iattr && iattr->ecommunity) +			ecom = ecommunity_merge(ecom, iattr->ecommunity); +	} + +	local_pref = calc_local_pref(iattr, peer); + +	if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) { +		char buf[BUFSIZ]; + +		buf[0] = 0; +		rfapiRfapiIpAddr2Str(&vnaddr, buf, BUFSIZ); +		buf[BUFSIZ - 1] = 0; +		vnc_zlog_debug_any("%s: setting vnaddr to %s", __func__, buf); +	} + +	vncHDBgpDirect.peer = peer; +	add_vnc_route(&vncHDBgpDirect, bgp, SAFI_MPLS_VPN, prefix, &prd, +		      &vnaddr, &local_pref, &(bgp->rfapi_cfg->redist_lifetime), +		      NULL,		      /* RFP options */ +		      NULL, NULL, ecom, NULL, /* med */ +		      NULL,		      /* label: default */ +		      ZEBRA_ROUTE_BGP_DIRECT, BGP_ROUTE_REDISTRIBUTE, +		      ahr_flags); +	vncHDBgpDirect.peer = NULL; + +	if (ecom) +		ecommunity_free(&ecom);  } -static void -vnc_import_bgp_del_route_mode_plain (struct bgp *bgp, -                                     struct prefix *prefix, -                                     struct bgp_info *info) +static void vnc_import_bgp_del_route_mode_plain(struct bgp *bgp, +						struct prefix *prefix, +						struct bgp_info *info)  { -  struct prefix_rd prd; -  afi_t afi = family2afi (prefix->family); -  struct prefix *vn_pfx = NULL; -  struct rfapi_ip_addr vnaddr; -  struct prefix vn_pfx_space; - - -  assert (afi); - -  /* -   * Compute VN address -   */ - -  if (info && info->attr) -    { -      rfapiUnicastNexthop2Prefix (afi, info->attr, &vn_pfx_space); -    } -  else -    { -      vnc_zlog_debug_verbose ("%s: no attr, can't delete route", __func__); -      return; -    } -  vn_pfx = &vn_pfx_space; - -  vnaddr.addr_family = vn_pfx->family; -  switch (vn_pfx->family) -    { -    case AF_INET: -      if (vn_pfx->prefixlen != 32) -        { -          vnc_zlog_debug_verbose ("%s: redist VN plen (%d) != 32, skipping", -                      __func__, vn_pfx->prefixlen); -          return; -        } -      vnaddr.addr.v4 = vn_pfx->u.prefix4; -      break; - -    case AF_INET6: -      if (vn_pfx->prefixlen != 128) -        { -          vnc_zlog_debug_verbose ("%s: redist VN plen (%d) != 128, skipping", -                      __func__, vn_pfx->prefixlen); -          return; -        } -      vnaddr.addr.v6 = vn_pfx->u.prefix6; -      break; - -    default: -      vnc_zlog_debug_verbose ("%s: no redist RFG VN host pfx configured, skipping", -                  __func__); -      return; -    } - - -  memset (&prd, 0, sizeof (prd)); -  if (rfapi_set_autord_from_vn (&prd, &vnaddr)) -    { -      vnc_zlog_debug_verbose ("%s: can't auto-assign RD, skipping", __func__); -      return; -    } - -  vncHDBgpDirect.peer = info->peer; -  vnc_zlog_debug_verbose ("%s: setting peer to %p", __func__, vncHDBgpDirect.peer); -  del_vnc_route (&vncHDBgpDirect, -                 info->peer, -                 bgp, -                 SAFI_MPLS_VPN, -                 prefix, -                 &prd, -                 ZEBRA_ROUTE_BGP_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL, 1); - -  vncHDBgpDirect.peer = NULL; +	struct prefix_rd prd; +	afi_t afi = family2afi(prefix->family); +	struct prefix *vn_pfx = NULL; +	struct rfapi_ip_addr vnaddr; +	struct prefix vn_pfx_space; + + +	assert(afi); + +	/* +	 * Compute VN address +	 */ + +	if (info && info->attr) { +		rfapiUnicastNexthop2Prefix(afi, info->attr, &vn_pfx_space); +	} else { +		vnc_zlog_debug_verbose("%s: no attr, can't delete route", +				       __func__); +		return; +	} +	vn_pfx = &vn_pfx_space; + +	vnaddr.addr_family = vn_pfx->family; +	switch (vn_pfx->family) { +	case AF_INET: +		if (vn_pfx->prefixlen != 32) { +			vnc_zlog_debug_verbose( +				"%s: redist VN plen (%d) != 32, skipping", +				__func__, vn_pfx->prefixlen); +			return; +		} +		vnaddr.addr.v4 = vn_pfx->u.prefix4; +		break; + +	case AF_INET6: +		if (vn_pfx->prefixlen != 128) { +			vnc_zlog_debug_verbose( +				"%s: redist VN plen (%d) != 128, skipping", +				__func__, vn_pfx->prefixlen); +			return; +		} +		vnaddr.addr.v6 = vn_pfx->u.prefix6; +		break; + +	default: +		vnc_zlog_debug_verbose( +			"%s: no redist RFG VN host pfx configured, skipping", +			__func__); +		return; +	} + + +	memset(&prd, 0, sizeof(prd)); +	if (rfapi_set_autord_from_vn(&prd, &vnaddr)) { +		vnc_zlog_debug_verbose("%s: can't auto-assign RD, skipping", +				       __func__); +		return; +	} + +	vncHDBgpDirect.peer = info->peer; +	vnc_zlog_debug_verbose("%s: setting peer to %p", __func__, +			       vncHDBgpDirect.peer); +	del_vnc_route(&vncHDBgpDirect, info->peer, bgp, SAFI_MPLS_VPN, prefix, +		      &prd, ZEBRA_ROUTE_BGP_DIRECT, BGP_ROUTE_REDISTRIBUTE, +		      NULL, 1); + +	vncHDBgpDirect.peer = NULL;  } -static void -vnc_import_bgp_del_route_mode_nvegroup (struct bgp *bgp, -                                        struct prefix *prefix, -                                        struct bgp_info *info) +static void vnc_import_bgp_del_route_mode_nvegroup(struct bgp *bgp, +						   struct prefix *prefix, +						   struct bgp_info *info)  { -  struct prefix_rd prd; -  afi_t afi = family2afi (prefix->family); -  struct rfapi_nve_group_cfg *rfg = NULL; -  struct prefix *vn_pfx = NULL; -  struct rfapi_ip_addr vnaddr; - - -  assert (afi); - -  assert ((rfg = bgp->rfapi_cfg->rfg_redist)); - -  /* -   * Compute VN address -   */ - -  /* -   * export nve group's VN addr prefix must be a /32 which -   * will yield the VN addr to use -   */ -  vn_pfx = &rfg->vn_prefix; - - -  vnaddr.addr_family = vn_pfx->family; -  switch (vn_pfx->family) -    { -    case AF_INET: -      if (vn_pfx->prefixlen != 32) -        { -          vnc_zlog_debug_verbose ("%s: redist VN plen (%d) != 32, skipping", -                      __func__, vn_pfx->prefixlen); -          return; -        } -      vnaddr.addr.v4 = vn_pfx->u.prefix4; -      break; - -    case AF_INET6: -      if (vn_pfx->prefixlen != 128) -        { -          vnc_zlog_debug_verbose ("%s: redist VN plen (%d) != 128, skipping", -                      __func__, vn_pfx->prefixlen); -          return; -        } -      vnaddr.addr.v6 = vn_pfx->u.prefix6; -      break; - -    default: -      vnc_zlog_debug_verbose ("%s: no redist RFG VN host pfx configured, skipping", -                  __func__); -      return; -    } - -  memset (&prd, 0, sizeof (prd)); -  prd = rfg->rd; -  prd.family = AF_UNSPEC; -  prd.prefixlen = 64; - -  if (rfg->rd.family == AF_UNIX) -    { -      /* means "auto" with VN addr */ -      if (rfapi_set_autord_from_vn (&prd, &vnaddr)) -        { -          vnc_zlog_debug_verbose ("%s: can't auto-assign RD, skipping", __func__); -          return; -        } -    } - - -  vncHDBgpDirect.peer = info->peer; -  vnc_zlog_debug_verbose ("%s: setting peer to %p", __func__, vncHDBgpDirect.peer); -  del_vnc_route (&vncHDBgpDirect, -                 info->peer, -                 bgp, -                 SAFI_MPLS_VPN, -                 prefix, -                 &prd, -                 ZEBRA_ROUTE_BGP_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL, 1); - -  vncHDBgpDirect.peer = NULL; +	struct prefix_rd prd; +	afi_t afi = family2afi(prefix->family); +	struct rfapi_nve_group_cfg *rfg = NULL; +	struct prefix *vn_pfx = NULL; +	struct rfapi_ip_addr vnaddr; + + +	assert(afi); + +	assert((rfg = bgp->rfapi_cfg->rfg_redist)); + +	/* +	 * Compute VN address +	 */ + +	/* +	 * export nve group's VN addr prefix must be a /32 which +	 * will yield the VN addr to use +	 */ +	vn_pfx = &rfg->vn_prefix; + + +	vnaddr.addr_family = vn_pfx->family; +	switch (vn_pfx->family) { +	case AF_INET: +		if (vn_pfx->prefixlen != 32) { +			vnc_zlog_debug_verbose( +				"%s: redist VN plen (%d) != 32, skipping", +				__func__, vn_pfx->prefixlen); +			return; +		} +		vnaddr.addr.v4 = vn_pfx->u.prefix4; +		break; + +	case AF_INET6: +		if (vn_pfx->prefixlen != 128) { +			vnc_zlog_debug_verbose( +				"%s: redist VN plen (%d) != 128, skipping", +				__func__, vn_pfx->prefixlen); +			return; +		} +		vnaddr.addr.v6 = vn_pfx->u.prefix6; +		break; + +	default: +		vnc_zlog_debug_verbose( +			"%s: no redist RFG VN host pfx configured, skipping", +			__func__); +		return; +	} + +	memset(&prd, 0, sizeof(prd)); +	prd = rfg->rd; +	prd.family = AF_UNSPEC; +	prd.prefixlen = 64; + +	if (rfg->rd.family == AF_UNIX) { +		/* means "auto" with VN addr */ +		if (rfapi_set_autord_from_vn(&prd, &vnaddr)) { +			vnc_zlog_debug_verbose( +				"%s: can't auto-assign RD, skipping", __func__); +			return; +		} +	} + + +	vncHDBgpDirect.peer = info->peer; +	vnc_zlog_debug_verbose("%s: setting peer to %p", __func__, +			       vncHDBgpDirect.peer); +	del_vnc_route(&vncHDBgpDirect, info->peer, bgp, SAFI_MPLS_VPN, prefix, +		      &prd, ZEBRA_ROUTE_BGP_DIRECT, BGP_ROUTE_REDISTRIBUTE, +		      NULL, 1); + +	vncHDBgpDirect.peer = NULL;  } -static void -vnc_import_bgp_del_route_mode_resolve_nve_one_bi ( -    struct bgp		*bgp, -    afi_t		afi, -    struct bgp_info	*bi,	/* VPN bi */ -    struct prefix_rd	*prd,	/* RD */ -    struct prefix	*prefix)/* unicast route prefix */ +static void vnc_import_bgp_del_route_mode_resolve_nve_one_bi( +	struct bgp *bgp, afi_t afi, struct bgp_info *bi, /* VPN bi */ +	struct prefix_rd *prd,				 /* RD */ +	struct prefix *prefix) /* unicast route prefix */  { -  struct prefix un; - -  if (bi->type != ZEBRA_ROUTE_BGP && bi->type != ZEBRA_ROUTE_BGP_DIRECT) -    { - -      return; -    } -  if (bi->sub_type != BGP_ROUTE_NORMAL && -      bi->sub_type != BGP_ROUTE_STATIC && bi->sub_type != BGP_ROUTE_RFP) -    { - -      return; -    } -  if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) -    return; - -  vncHDResolveNve.peer = bi->peer; -  if (!rfapiGetVncTunnelUnAddr (bi->attr, &un)) -    { -      if (rfapiQprefix2Raddr (&un, &vncHDResolveNve.un_addr)) -        return; -    } -  else -    { -      memset (&vncHDResolveNve.un_addr, 0, sizeof (vncHDResolveNve.un_addr)); -    } - -  del_vnc_route (&vncHDResolveNve, vncHDResolveNve.peer, bgp, SAFI_MPLS_VPN, prefix,    /* unicast route prefix */ -                 prd, ZEBRA_ROUTE_BGP_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL, 0); /* flags */ +	struct prefix un; + +	if (bi->type != ZEBRA_ROUTE_BGP && bi->type != ZEBRA_ROUTE_BGP_DIRECT) { +		return; +	} +	if (bi->sub_type != BGP_ROUTE_NORMAL && bi->sub_type != BGP_ROUTE_STATIC +	    && bi->sub_type != BGP_ROUTE_RFP) { + +		return; +	} +	if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) +		return; + +	vncHDResolveNve.peer = bi->peer; +	if (!rfapiGetVncTunnelUnAddr(bi->attr, &un)) { +		if (rfapiQprefix2Raddr(&un, &vncHDResolveNve.un_addr)) +			return; +	} else { +		memset(&vncHDResolveNve.un_addr, 0, +		       sizeof(vncHDResolveNve.un_addr)); +	} + +	del_vnc_route(&vncHDResolveNve, vncHDResolveNve.peer, bgp, +		      SAFI_MPLS_VPN, prefix, /* unicast route prefix */ +		      prd, ZEBRA_ROUTE_BGP_DIRECT, BGP_ROUTE_REDISTRIBUTE, NULL, +		      0); /* flags */  } -static void -vnc_import_bgp_del_route_mode_resolve_nve_one_rd ( -    struct prefix_rd	*prd, -    struct bgp_table	*table_rd,    /* per-rd VPN route table */ -    afi_t		afi, -    struct bgp		*bgp, -    struct prefix	*prefix,    /* unicast prefix */ -    struct prefix	*ubi_nexthop)   /* unicast bi's nexthop */ +static void vnc_import_bgp_del_route_mode_resolve_nve_one_rd( +	struct prefix_rd *prd, +	struct bgp_table *table_rd, /* per-rd VPN route table */ +	afi_t afi, struct bgp *bgp, struct prefix *prefix, /* unicast prefix */ +	struct prefix *ubi_nexthop) /* unicast bi's nexthop */  { -  struct bgp_node *bn; -  struct bgp_info *bi; +	struct bgp_node *bn; +	struct bgp_info *bi; -  if (!table_rd) -    return; +	if (!table_rd) +		return; -  { -    char str_nh[BUFSIZ]; +	{ +		char str_nh[BUFSIZ]; -    prefix2str (ubi_nexthop, str_nh, BUFSIZ); -    str_nh[BUFSIZ - 1] = 0; +		prefix2str(ubi_nexthop, str_nh, BUFSIZ); +		str_nh[BUFSIZ - 1] = 0; -    vnc_zlog_debug_verbose ("%s: ubi_nexthop=%s", __func__, str_nh); -  } +		vnc_zlog_debug_verbose("%s: ubi_nexthop=%s", __func__, str_nh); +	} -  /* exact match */ -  bn = bgp_node_lookup (table_rd, ubi_nexthop); -  if (!bn) -    { -      vnc_zlog_debug_verbose ("%s: no match in RD's table for ubi_nexthop", __func__); -      return; -    } +	/* exact match */ +	bn = bgp_node_lookup(table_rd, ubi_nexthop); +	if (!bn) { +		vnc_zlog_debug_verbose( +			"%s: no match in RD's table for ubi_nexthop", __func__); +		return; +	} -  /* Iterate over bgp_info items at this node */ -  for (bi = bn->info; bi; bi = bi->next) -    { +	/* Iterate over bgp_info items at this node */ +	for (bi = bn->info; bi; bi = bi->next) { -      vnc_import_bgp_del_route_mode_resolve_nve_one_bi (bgp, afi, bi,   /* VPN bi */ -                                                        prd,    /* VPN RD */ -                                                        prefix);        /* unicast route prefix */ -    } +		vnc_import_bgp_del_route_mode_resolve_nve_one_bi( +			bgp, afi, bi, /* VPN bi */ +			prd,	  /* VPN RD */ +			prefix);      /* unicast route prefix */ +	} -  bgp_unlock_node (bn); +	bgp_unlock_node(bn);  } -static void -vnc_import_bgp_del_route_mode_resolve_nve (struct bgp *bgp, -                                           afi_t afi, -                                           struct prefix *prefix, -                                           struct bgp_info *info) +static void vnc_import_bgp_del_route_mode_resolve_nve(struct bgp *bgp, +						      afi_t afi, +						      struct prefix *prefix, +						      struct bgp_info *info)  { -  struct ecommunity *ecom = NULL; -  struct prefix pfx_unicast_nexthop = { 0 };    /* happy valgrind */ - -  //struct listnode           *hnode; -  //struct rfapi_descriptor   *rfd; -  struct prefix_bag *pb; -  void *cursor; -  struct skiplist *sl = bgp->rfapi->resolve_nve_nexthop; -  int rc; -  struct bgp_node *bnp;         /* prd table node */ - -  if (!sl) -    { -      vnc_zlog_debug_verbose ("%s: no RHN entries, skipping", __func__); -      return; -    } - -  if (info->type != ZEBRA_ROUTE_BGP) -    { -      vnc_zlog_debug_verbose ("%s: unicast type %d=\"%s\" is not %d=%s, skipping", -                  __func__, info->type, zebra_route_string (info->type), -                  ZEBRA_ROUTE_BGP, "ZEBRA_ROUTE_BGP"); -      return; -    } - -  if (process_unicast_route (bgp, afi, prefix, info, -                             &ecom, &pfx_unicast_nexthop)) -    { - -      vnc_zlog_debug_verbose ("%s: process_unicast_route error, skipping", __func__); -      return; -    } - -  rc = skiplist_first_value (sl, &pfx_unicast_nexthop, (void *) &pb, &cursor); -  while (!rc) -    { -      if (pb->ubi == info) -        { -          skiplist_delete (sl, &pfx_unicast_nexthop, pb); -          bgp_info_unlock (info); -          break; -        } -      rc = -        skiplist_next_value (sl, &pfx_unicast_nexthop, (void *) &pb, &cursor); -    } - -  /* -   * Iterate over RDs in VPN RIB. For each RD, look up unicast nexthop -   * (exact match, /32). If an exact match is found, call add_vnc_route. -   */ - -  for (bnp = bgp_table_top (bgp->rib[afi][SAFI_MPLS_VPN]); bnp; -       bnp = bgp_route_next (bnp)) -    { - -      struct bgp_table *table; - -      table = (struct bgp_table *) (bnp->info); - -      if (!table) -        continue; - -      vnc_import_bgp_del_route_mode_resolve_nve_one_rd ((struct prefix_rd *) &bnp->p, table, afi, bgp, prefix, &pfx_unicast_nexthop);   /* TBD how is this set? */ -    } - -  if (ecom) -    ecommunity_free (&ecom); -} +	struct ecommunity *ecom = NULL; +	struct prefix pfx_unicast_nexthop = {0}; /* happy valgrind */ + +	// struct listnode           *hnode; +	// struct rfapi_descriptor   *rfd; +	struct prefix_bag *pb; +	void *cursor; +	struct skiplist *sl = bgp->rfapi->resolve_nve_nexthop; +	int rc; +	struct bgp_node *bnp; /* prd table node */ + +	if (!sl) { +		vnc_zlog_debug_verbose("%s: no RHN entries, skipping", +				       __func__); +		return; +	} +	if (info->type != ZEBRA_ROUTE_BGP) { +		vnc_zlog_debug_verbose( +			"%s: unicast type %d=\"%s\" is not %d=%s, skipping", +			__func__, info->type, zebra_route_string(info->type), +			ZEBRA_ROUTE_BGP, "ZEBRA_ROUTE_BGP"); +		return; +	} +	if (process_unicast_route(bgp, afi, prefix, info, &ecom, +				  &pfx_unicast_nexthop)) { + +		vnc_zlog_debug_verbose( +			"%s: process_unicast_route error, skipping", __func__); +		return; +	} + +	rc = skiplist_first_value(sl, &pfx_unicast_nexthop, (void *)&pb, +				  &cursor); +	while (!rc) { +		if (pb->ubi == info) { +			skiplist_delete(sl, &pfx_unicast_nexthop, pb); +			bgp_info_unlock(info); +			break; +		} +		rc = skiplist_next_value(sl, &pfx_unicast_nexthop, (void *)&pb, +					 &cursor); +	} + +	/* +	 * Iterate over RDs in VPN RIB. For each RD, look up unicast nexthop +	 * (exact match, /32). If an exact match is found, call add_vnc_route. +	 */ + +	for (bnp = bgp_table_top(bgp->rib[afi][SAFI_MPLS_VPN]); bnp; +	     bnp = bgp_route_next(bnp)) { + +		struct bgp_table *table; + +		table = (struct bgp_table *)(bnp->info); + +		if (!table) +			continue; + +		vnc_import_bgp_del_route_mode_resolve_nve_one_rd( +			(struct prefix_rd *)&bnp->p, table, afi, bgp, prefix, +			&pfx_unicast_nexthop); /* TBD how is this set? */ +	} + +	if (ecom) +		ecommunity_free(&ecom); +}  /*********************************************************************** @@ -1509,262 +1409,256 @@ vnc_import_bgp_del_route_mode_resolve_nve (struct bgp *bgp,   * Should be called whan a bi is added to VPN RIB. This function   * will check if it is a host route and return immediately if not.   */ -void -vnc_import_bgp_add_vnc_host_route_mode_resolve_nve ( -    struct bgp		*bgp, -    struct prefix_rd	*prd,		/* RD */ -    struct bgp_table	*table_rd,	/* per-rd VPN route table */ -    struct prefix	*prefix,	/* VPN prefix */ -    struct bgp_info	*bi)		/* new VPN host route */ +void vnc_import_bgp_add_vnc_host_route_mode_resolve_nve( +	struct bgp *bgp, struct prefix_rd *prd, /* RD */ +	struct bgp_table *table_rd,		/* per-rd VPN route table */ +	struct prefix *prefix,			/* VPN prefix */ +	struct bgp_info *bi)			/* new VPN host route */  { -  afi_t afi = family2afi (prefix->family); -  struct skiplist *sl = NULL; -  int rc; -  struct prefix_bag *pb; -  void *cursor; -  struct rfapi_cfg *hc = NULL; - -  vnc_zlog_debug_verbose ("%s: entry", __func__); - -  if (afi != AFI_IP && afi != AFI_IP6) -    { -      vnc_zlog_debug_verbose ("%s: bad afi %d, skipping", __func__, afi); -      return; -    } - -  if (!(hc = bgp->rfapi_cfg)) -    { -      vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); -      return; -    } - -  /* check vnc redist flag for bgp direct routes */ -  if (!hc->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) -    { -      vnc_zlog_debug_verbose -        ("%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping", -         __func__, afi); -      return; -    } - -  if (hc->redist_mode != VNC_REDIST_MODE_RESOLVE_NVE) -    { -      vnc_zlog_debug_verbose ("%s: not in resolve-nve mode, skipping", __func__); -      return; -    } - -  if (bgp && bgp->rfapi) -    sl = bgp->rfapi->resolve_nve_nexthop; - -  if (!sl) -    { -      vnc_zlog_debug_verbose ("%s: no resolve_nve_nexthop skiplist, skipping", __func__); -      return; -    } - -  if (!is_host_prefix (prefix)) -    { -      vnc_zlog_debug_verbose ("%s: not host prefix, skipping", __func__); -      return; -    } - -  rc = skiplist_first_value (sl, prefix, (void *) &pb, &cursor); -  while (!rc) -    { -      struct ecommunity *ecom; -      struct prefix pfx_unicast_nexthop; -      uint32_t *med = NULL; -      uint32_t local_pref; - -      memset (&pfx_unicast_nexthop, 0, sizeof (struct prefix)); /* keep valgrind happy */ - -      if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) -	{ -	  char hbuf[BUFSIZ]; -	  char ubuf[BUFSIZ]; +	afi_t afi = family2afi(prefix->family); +	struct skiplist *sl = NULL; +	int rc; +	struct prefix_bag *pb; +	void *cursor; +	struct rfapi_cfg *hc = NULL; + +	vnc_zlog_debug_verbose("%s: entry", __func__); + +	if (afi != AFI_IP && afi != AFI_IP6) { +		vnc_zlog_debug_verbose("%s: bad afi %d, skipping", __func__, +				       afi); +		return; +	} + +	if (!(hc = bgp->rfapi_cfg)) { +		vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", +				       __func__); +		return; +	} -	  prefix2str (&pb->hpfx, hbuf, BUFSIZ); -	  prefix2str (&pb->upfx, ubuf, BUFSIZ); +	/* check vnc redist flag for bgp direct routes */ +	if (!hc->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) { +		vnc_zlog_debug_verbose( +			"%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping", +			__func__, afi); +		return; +	} -	  vnc_zlog_debug_any -	    ("%s: examining RHN Entry (q=%p): upfx=%s, hpfx=%s, ubi=%p", -	     __func__, cursor, ubuf, hbuf, pb->ubi); +	if (hc->redist_mode != VNC_REDIST_MODE_RESOLVE_NVE) { +		vnc_zlog_debug_verbose("%s: not in resolve-nve mode, skipping", +				       __func__); +		return;  	} -      if (process_unicast_route (bgp, afi, &pb->upfx, pb->ubi, -                                 &ecom, &pfx_unicast_nexthop)) -        { +	if (bgp && bgp->rfapi) +		sl = bgp->rfapi->resolve_nve_nexthop; + +	if (!sl) { +		vnc_zlog_debug_verbose( +			"%s: no resolve_nve_nexthop skiplist, skipping", +			__func__); +		return; +	} + +	if (!is_host_prefix(prefix)) { +		vnc_zlog_debug_verbose("%s: not host prefix, skipping", +				       __func__); +		return; +	} + +	rc = skiplist_first_value(sl, prefix, (void *)&pb, &cursor); +	while (!rc) { +		struct ecommunity *ecom; +		struct prefix pfx_unicast_nexthop; +		uint32_t *med = NULL; +		uint32_t local_pref; + +		memset(&pfx_unicast_nexthop, 0, +		       sizeof(struct prefix)); /* keep valgrind happy */ + +		if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) { +			char hbuf[BUFSIZ]; +			char ubuf[BUFSIZ]; -          vnc_zlog_debug_verbose ("%s: process_unicast_route error, skipping", __func__); -          continue; -        } -      local_pref = calc_local_pref (pb->ubi->attr, pb->ubi->peer); +			prefix2str(&pb->hpfx, hbuf, BUFSIZ); +			prefix2str(&pb->upfx, ubuf, BUFSIZ); -      if (pb->ubi->attr && -          (pb->ubi->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))) -        { +			vnc_zlog_debug_any( +				"%s: examining RHN Entry (q=%p): upfx=%s, hpfx=%s, ubi=%p", +				__func__, cursor, ubuf, hbuf, pb->ubi); +		} -          med = &pb->ubi->attr->med; -        } +		if (process_unicast_route(bgp, afi, &pb->upfx, pb->ubi, &ecom, +					  &pfx_unicast_nexthop)) { -      /* -       * Sanity check -       */ -      if (vnc_prefix_cmp (&pfx_unicast_nexthop, prefix)) -        { -          char str_unh[BUFSIZ]; -          char str_nve_pfx[BUFSIZ]; +			vnc_zlog_debug_verbose( +				"%s: process_unicast_route error, skipping", +				__func__); +			continue; +		} +		local_pref = calc_local_pref(pb->ubi->attr, pb->ubi->peer); -          prefix2str (&pfx_unicast_nexthop, str_unh, BUFSIZ); -          str_unh[BUFSIZ - 1] = 0; +		if (pb->ubi->attr +		    && (pb->ubi->attr->flag +			& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))) { -          prefix2str (prefix, str_nve_pfx, BUFSIZ); -          str_nve_pfx[BUFSIZ - 1] = 0; +			med = &pb->ubi->attr->med; +		} -          vnc_zlog_debug_verbose -            ("%s: FATAL: resolve_nve_nexthop list item bi nexthop %s != nve pfx %s", -             __func__, str_unh, str_nve_pfx); -          assert (0); -        } +		/* +		 * Sanity check +		 */ +		if (vnc_prefix_cmp(&pfx_unicast_nexthop, prefix)) { +			char str_unh[BUFSIZ]; +			char str_nve_pfx[BUFSIZ]; -      vnc_import_bgp_add_route_mode_resolve_nve_one_bi (bgp, afi, bi,   /* VPN bi */ -                                                        prd, &pb->upfx, /* unicast prefix */ -                                                        &local_pref, -                                                        med, ecom); +			prefix2str(&pfx_unicast_nexthop, str_unh, BUFSIZ); +			str_unh[BUFSIZ - 1] = 0; -      if (ecom) -        ecommunity_free (&ecom); +			prefix2str(prefix, str_nve_pfx, BUFSIZ); +			str_nve_pfx[BUFSIZ - 1] = 0; + +			vnc_zlog_debug_verbose( +				"%s: FATAL: resolve_nve_nexthop list item bi nexthop %s != nve pfx %s", +				__func__, str_unh, str_nve_pfx); +			assert(0); +		} + +		vnc_import_bgp_add_route_mode_resolve_nve_one_bi( +			bgp, afi, bi,   /* VPN bi */ +			prd, &pb->upfx, /* unicast prefix */ +			&local_pref, med, ecom); + +		if (ecom) +			ecommunity_free(&ecom);  #if DEBUG_RHN_LIST -      /* debug */ -      { -        char pbuf[BUFSIZ]; +		/* debug */ +		{ +			char pbuf[BUFSIZ]; -        prefix2str (prefix, pbuf, BUFSIZ); +			prefix2str(prefix, pbuf, BUFSIZ); -        vnc_zlog_debug_verbose ("%s: advancing past RHN Entry (q=%p): with prefix %s", -                    __func__, cursor, pbuf); -        print_rhn_list (__func__, NULL);        /* debug */ -      } +			vnc_zlog_debug_verbose( +				"%s: advancing past RHN Entry (q=%p): with prefix %s", +				__func__, cursor, pbuf); +			print_rhn_list(__func__, NULL); /* debug */ +		}  #endif -      rc = skiplist_next_value (sl, prefix, (void *) &pb, &cursor); -    } -  vnc_zlog_debug_verbose ("%s: done", __func__); +		rc = skiplist_next_value(sl, prefix, (void *)&pb, &cursor); +	} +	vnc_zlog_debug_verbose("%s: done", __func__);  } -void -vnc_import_bgp_del_vnc_host_route_mode_resolve_nve ( -  struct bgp		*bgp, -  struct prefix_rd	*prd,		/* RD */ -  struct bgp_table	*table_rd,	/* per-rd VPN route table */ -  struct prefix		*prefix,	/* VPN prefix */ -  struct bgp_info	*bi)		/* old VPN host route */ +void vnc_import_bgp_del_vnc_host_route_mode_resolve_nve( +	struct bgp *bgp, struct prefix_rd *prd, /* RD */ +	struct bgp_table *table_rd,		/* per-rd VPN route table */ +	struct prefix *prefix,			/* VPN prefix */ +	struct bgp_info *bi)			/* old VPN host route */  { -  afi_t afi = family2afi (prefix->family); -  struct skiplist *sl = NULL; -  struct prefix_bag *pb; -  void *cursor; -  struct rfapi_cfg *hc = NULL; -  int rc; - -  { -    char str_pfx[BUFSIZ]; - -    prefix2str (prefix, str_pfx, BUFSIZ); -    str_pfx[BUFSIZ - 1] = 0; - -    vnc_zlog_debug_verbose ("%s(bgp=%p, nve prefix=%s)", __func__, bgp, str_pfx); -  } - -  if (afi != AFI_IP && afi != AFI_IP6) -    return; - -  if (!(hc = bgp->rfapi_cfg)) -    { -      vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); -      return; -    } - -  /* check vnc redist flag for bgp direct routes */ -  if (!hc->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) -    { -      vnc_zlog_debug_verbose -        ("%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping", -         __func__, afi); -      return; -    } - -  if (hc->redist_mode != VNC_REDIST_MODE_RESOLVE_NVE) -    { -      vnc_zlog_debug_verbose ("%s: not in resolve-nve mode, skipping", __func__); -      return; -    } - -  if (bgp && bgp->rfapi) -    sl = bgp->rfapi->resolve_nve_nexthop; - -  if (!sl) -    { -      vnc_zlog_debug_verbose ("%s: no RHN entries, skipping", __func__); -      return; -    } - -  if (!is_host_prefix (prefix)) -    { -      vnc_zlog_debug_verbose ("%s: not host route, skip", __func__); -      return; -    } - -  /* -   * Find all entries with key == CE in the RHN list -   */ -  rc = skiplist_first_value (sl, prefix, (void *) &pb, &cursor); -  while (!rc) -    { - -      struct ecommunity *ecom; -      struct prefix pfx_unicast_nexthop; - -      memset (&pfx_unicast_nexthop, 0, sizeof (struct prefix)); /* keep valgrind happy */ - -      if (process_unicast_route (bgp, afi, &pb->upfx, pb->ubi, -                                 &ecom, &pfx_unicast_nexthop)) -        { - -          vnc_zlog_debug_verbose ("%s: process_unicast_route error, skipping", __func__); -          continue; -        } - -      /* -       * Sanity check -       */ -      if (vnc_prefix_cmp (&pfx_unicast_nexthop, prefix)) -        { -          char str_unh[BUFSIZ]; -          char str_nve_pfx[BUFSIZ]; - -          prefix2str (&pfx_unicast_nexthop, str_unh, BUFSIZ); -          str_unh[BUFSIZ - 1] = 0; - -          prefix2str (prefix, str_nve_pfx, BUFSIZ); -          str_nve_pfx[BUFSIZ - 1] = 0; - -          vnc_zlog_debug_verbose -            ("%s: FATAL: resolve_nve_nexthop list item bi nexthop %s != nve pfx %s", -             __func__, str_unh, str_nve_pfx); -          assert (0); -        } - -      vnc_import_bgp_del_route_mode_resolve_nve_one_bi (bgp, -                                                        afi, -                                                        bi, prd, &pb->upfx); - -      if (ecom) -        ecommunity_free (&ecom); - -      rc = skiplist_next_value (sl, prefix, (void *) &pb, &cursor); -    } +	afi_t afi = family2afi(prefix->family); +	struct skiplist *sl = NULL; +	struct prefix_bag *pb; +	void *cursor; +	struct rfapi_cfg *hc = NULL; +	int rc; + +	{ +		char str_pfx[BUFSIZ]; + +		prefix2str(prefix, str_pfx, BUFSIZ); +		str_pfx[BUFSIZ - 1] = 0; + +		vnc_zlog_debug_verbose("%s(bgp=%p, nve prefix=%s)", __func__, +				       bgp, str_pfx); +	} + +	if (afi != AFI_IP && afi != AFI_IP6) +		return; + +	if (!(hc = bgp->rfapi_cfg)) { +		vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", +				       __func__); +		return; +	} + +	/* check vnc redist flag for bgp direct routes */ +	if (!hc->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) { +		vnc_zlog_debug_verbose( +			"%s: bgp->rfapi_cfg->redist[afi=%d][type=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping", +			__func__, afi); +		return; +	} + +	if (hc->redist_mode != VNC_REDIST_MODE_RESOLVE_NVE) { +		vnc_zlog_debug_verbose("%s: not in resolve-nve mode, skipping", +				       __func__); +		return; +	} + +	if (bgp && bgp->rfapi) +		sl = bgp->rfapi->resolve_nve_nexthop; + +	if (!sl) { +		vnc_zlog_debug_verbose("%s: no RHN entries, skipping", +				       __func__); +		return; +	} + +	if (!is_host_prefix(prefix)) { +		vnc_zlog_debug_verbose("%s: not host route, skip", __func__); +		return; +	} + +	/* +	 * Find all entries with key == CE in the RHN list +	 */ +	rc = skiplist_first_value(sl, prefix, (void *)&pb, &cursor); +	while (!rc) { + +		struct ecommunity *ecom; +		struct prefix pfx_unicast_nexthop; + +		memset(&pfx_unicast_nexthop, 0, +		       sizeof(struct prefix)); /* keep valgrind happy */ + +		if (process_unicast_route(bgp, afi, &pb->upfx, pb->ubi, &ecom, +					  &pfx_unicast_nexthop)) { + +			vnc_zlog_debug_verbose( +				"%s: process_unicast_route error, skipping", +				__func__); +			continue; +		} + +		/* +		 * Sanity check +		 */ +		if (vnc_prefix_cmp(&pfx_unicast_nexthop, prefix)) { +			char str_unh[BUFSIZ]; +			char str_nve_pfx[BUFSIZ]; + +			prefix2str(&pfx_unicast_nexthop, str_unh, BUFSIZ); +			str_unh[BUFSIZ - 1] = 0; + +			prefix2str(prefix, str_nve_pfx, BUFSIZ); +			str_nve_pfx[BUFSIZ - 1] = 0; + +			vnc_zlog_debug_verbose( +				"%s: FATAL: resolve_nve_nexthop list item bi nexthop %s != nve pfx %s", +				__func__, str_unh, str_nve_pfx); +			assert(0); +		} + +		vnc_import_bgp_del_route_mode_resolve_nve_one_bi( +			bgp, afi, bi, prd, &pb->upfx); + +		if (ecom) +			ecommunity_free(&ecom); + +		rc = skiplist_next_value(sl, prefix, (void *)&pb, &cursor); +	}  } @@ -1774,25 +1668,24 @@ vnc_import_bgp_del_vnc_host_route_mode_resolve_nve (  #define DEBUG_IS_USABLE_INTERIOR 1 -static int -is_usable_interior_route (struct bgp_info *bi_interior) +static int is_usable_interior_route(struct bgp_info *bi_interior)  { -  if (!VALID_INTERIOR_TYPE (bi_interior->type)) -    { +	if (!VALID_INTERIOR_TYPE(bi_interior->type)) {  #if DEBUG_IS_USABLE_INTERIOR -      vnc_zlog_debug_verbose ("%s: NO: type %d is not valid interior type", -                  __func__, bi_interior->type); +		vnc_zlog_debug_verbose( +			"%s: NO: type %d is not valid interior type", __func__, +			bi_interior->type);  #endif -      return 0; -    } -  if (!CHECK_FLAG (bi_interior->flags, BGP_INFO_VALID)) -    { +		return 0; +	} +	if (!CHECK_FLAG(bi_interior->flags, BGP_INFO_VALID)) {  #if DEBUG_IS_USABLE_INTERIOR -      vnc_zlog_debug_verbose ("%s: NO: BGP_INFO_VALID not set", __func__); +		vnc_zlog_debug_verbose("%s: NO: BGP_INFO_VALID not set", +				       __func__);  #endif -      return 0; -    } -  return 1; +		return 0; +	} +	return 1;  }  /* @@ -1804,192 +1697,188 @@ is_usable_interior_route (struct bgp_info *bi_interior)   * We filter here on the instance name to make sure we get only the   * right routes.   */ -static void -vnc_import_bgp_exterior_add_route_it ( -    struct bgp			*bgp,	/* exterior instance, we hope */ -    struct prefix		*prefix,/* unicast prefix */ -    struct bgp_info		*info,	/* unicast info */ -    struct rfapi_import_table	*it_only)/* NULL, or limit to this IT */ +static void vnc_import_bgp_exterior_add_route_it( +	struct bgp *bgp,		    /* exterior instance, we hope */ +	struct prefix *prefix,		    /* unicast prefix */ +	struct bgp_info *info,		    /* unicast info */ +	struct rfapi_import_table *it_only) /* NULL, or limit to this IT */  { -  struct rfapi *h; -  struct rfapi_cfg *hc; -  struct prefix pfx_orig_nexthop; -  struct rfapi_import_table *it; -  struct bgp *bgp_default = bgp_get_default (); -  afi_t afi = family2afi (prefix->family); - -  if (!bgp_default) -    return; - -  h = bgp_default->rfapi; -  hc = bgp_default->rfapi_cfg; - -  vnc_zlog_debug_verbose ("%s: entry with it=%p", __func__, it_only); - -  if (!h || !hc) -    { -      vnc_zlog_debug_verbose ("%s: rfapi or rfapi_cfg not instantiated, skipping", -                  __func__); -      return; -    } -  if (!hc->redist_bgp_exterior_view) -    { -      vnc_zlog_debug_verbose ("%s: exterior view not set, skipping", __func__); -      return; -    } -  if (bgp != hc->redist_bgp_exterior_view) -    { -      vnc_zlog_debug_verbose ("%s: bgp %p != hc->redist_bgp_exterior_view %p, skipping", -                  __func__, bgp, hc->redist_bgp_exterior_view); -      return; -    } - -  if (!hc->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT]) -    { -      vnc_zlog_debug_verbose ("%s: redist of exterior routes not enabled, skipping", -                  __func__); -      return; -    } - -  if (!info->attr) -    { -      vnc_zlog_debug_verbose ("%s: no info, skipping", __func__); -      return; -    } - -  /* -   * Extract nexthop from exterior route -   * -   * Incoming prefix is unicast. If v6, it is in multiprotocol area, -   * but if v4 it is in attr->nexthop -   */ -  rfapiUnicastNexthop2Prefix (afi, info->attr, &pfx_orig_nexthop); - -  for (it = h->imports; it; it = it->next) -    { -      struct route_table *table; -      struct route_node *rn; -      struct route_node *par; -      struct bgp_info *bi_interior; -      int have_usable_route; - -      vnc_zlog_debug_verbose ("%s: doing it %p", __func__, it); - -      if (it_only && (it_only != it)) -        { -          vnc_zlog_debug_verbose ("%s: doesn't match it_only %p", __func__, it_only); -          continue; -        } - -      table = it->imported_vpn[afi]; - -      for (rn = route_node_match (table, &pfx_orig_nexthop), -           have_usable_route = 0; (!have_usable_route) && rn;) -        { - -          vnc_zlog_debug_verbose ("%s: it %p trying rn %p", __func__, it, rn); - -          for (bi_interior = rn->info; bi_interior; -               bi_interior = bi_interior->next) -            { -              struct prefix_rd *prd; -              struct attr new_attr; -              u_int32_t label = 0; - -              if (!is_usable_interior_route (bi_interior)) -                continue; - -              vnc_zlog_debug_verbose ("%s: usable: bi_interior %p", __func__, -                          bi_interior); - -              /* -               * have a legitimate route to exterior's nexthop -               * via NVE. -               * -               * Import unicast route to the import table -               */ -              have_usable_route = 1; - -              if (bi_interior->extra) -                { -                  prd = &bi_interior->extra->vnc.import.rd; -                  label = decode_label (&bi_interior->extra->label); -                } -              else -                prd = NULL; - -              /* use local_pref from unicast route */ -              memset (&new_attr, 0, sizeof (struct attr)); -              bgp_attr_dup (&new_attr, bi_interior->attr); -              if (info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)) -                { -                  new_attr.local_pref = info->attr->local_pref; -                  new_attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF); -                } - -              rfapiBgpInfoFilteredImportVPN (it, FIF_ACTION_UPDATE, bi_interior->peer, NULL,    /* rfd */ -                                             prefix, -                                             NULL, -                                             afi, -                                             prd, -                                             &new_attr, -                                             ZEBRA_ROUTE_BGP_DIRECT_EXT, -                                             BGP_ROUTE_REDISTRIBUTE, &label); - -            } - -          if (have_usable_route) -            { -              /* -               * Make monitor -               * -               * TBD factor this out into its own function -               */ -              struct prefix *pfx_mon = prefix_new (); -              if (!RFAPI_MONITOR_EXTERIOR (rn)->source) -                { -                  RFAPI_MONITOR_EXTERIOR (rn)->source = -                    skiplist_new (0, NULL, (void (*)(void *)) prefix_free); -                  route_lock_node (rn); /* for skiplist */ -                } -              route_lock_node (rn);     /* for skiplist entry */ -              prefix_copy (pfx_mon, prefix); -              if (!skiplist_insert (RFAPI_MONITOR_EXTERIOR (rn)->source, -                                    info, pfx_mon)) -                { - -                  bgp_info_lock (info); -                } -            } -          par = rn->parent; -          if (par) -            route_lock_node (par); -          route_unlock_node (rn); -          rn = par; -        } -      if (rn) -        route_unlock_node (rn); - -      if (!have_usable_route) -        { -          struct prefix *pfx_mon = prefix_new (); -          prefix_copy (pfx_mon, prefix); -          if (!skiplist_insert (it->monitor_exterior_orphans, info, pfx_mon)) -            { - -              bgp_info_lock (info); -            } -        } -    } +	struct rfapi *h; +	struct rfapi_cfg *hc; +	struct prefix pfx_orig_nexthop; +	struct rfapi_import_table *it; +	struct bgp *bgp_default = bgp_get_default(); +	afi_t afi = family2afi(prefix->family); + +	if (!bgp_default) +		return; + +	h = bgp_default->rfapi; +	hc = bgp_default->rfapi_cfg; + +	vnc_zlog_debug_verbose("%s: entry with it=%p", __func__, it_only); + +	if (!h || !hc) { +		vnc_zlog_debug_verbose( +			"%s: rfapi or rfapi_cfg not instantiated, skipping", +			__func__); +		return; +	} +	if (!hc->redist_bgp_exterior_view) { +		vnc_zlog_debug_verbose("%s: exterior view not set, skipping", +				       __func__); +		return; +	} +	if (bgp != hc->redist_bgp_exterior_view) { +		vnc_zlog_debug_verbose( +			"%s: bgp %p != hc->redist_bgp_exterior_view %p, skipping", +			__func__, bgp, hc->redist_bgp_exterior_view); +		return; +	} + +	if (!hc->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT]) { +		vnc_zlog_debug_verbose( +			"%s: redist of exterior routes not enabled, skipping", +			__func__); +		return; +	} + +	if (!info->attr) { +		vnc_zlog_debug_verbose("%s: no info, skipping", __func__); +		return; +	} + +	/* +	 * Extract nexthop from exterior route +	 * +	 * Incoming prefix is unicast. If v6, it is in multiprotocol area, +	 * but if v4 it is in attr->nexthop +	 */ +	rfapiUnicastNexthop2Prefix(afi, info->attr, &pfx_orig_nexthop); + +	for (it = h->imports; it; it = it->next) { +		struct route_table *table; +		struct route_node *rn; +		struct route_node *par; +		struct bgp_info *bi_interior; +		int have_usable_route; + +		vnc_zlog_debug_verbose("%s: doing it %p", __func__, it); + +		if (it_only && (it_only != it)) { +			vnc_zlog_debug_verbose("%s: doesn't match it_only %p", +					       __func__, it_only); +			continue; +		} + +		table = it->imported_vpn[afi]; + +		for (rn = route_node_match(table, &pfx_orig_nexthop), +		    have_usable_route = 0; +		     (!have_usable_route) && rn;) { + +			vnc_zlog_debug_verbose("%s: it %p trying rn %p", +					       __func__, it, rn); + +			for (bi_interior = rn->info; bi_interior; +			     bi_interior = bi_interior->next) { +				struct prefix_rd *prd; +				struct attr new_attr; +				u_int32_t label = 0; + +				if (!is_usable_interior_route(bi_interior)) +					continue; + +				vnc_zlog_debug_verbose( +					"%s: usable: bi_interior %p", __func__, +					bi_interior); + +				/* +				 * have a legitimate route to exterior's nexthop +				 * via NVE. +				 * +				 * Import unicast route to the import table +				 */ +				have_usable_route = 1; + +				if (bi_interior->extra) { +					prd = &bi_interior->extra->vnc.import +						       .rd; +					label = decode_label( +						&bi_interior->extra->label); +				} else +					prd = NULL; + +				/* use local_pref from unicast route */ +				memset(&new_attr, 0, sizeof(struct attr)); +				bgp_attr_dup(&new_attr, bi_interior->attr); +				if (info->attr->flag +				    & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) { +					new_attr.local_pref = +						info->attr->local_pref; +					new_attr.flag |= ATTR_FLAG_BIT( +						BGP_ATTR_LOCAL_PREF); +				} + +				rfapiBgpInfoFilteredImportVPN( +					it, FIF_ACTION_UPDATE, +					bi_interior->peer, NULL, /* rfd */ +					prefix, NULL, afi, prd, &new_attr, +					ZEBRA_ROUTE_BGP_DIRECT_EXT, +					BGP_ROUTE_REDISTRIBUTE, &label); +			} + +			if (have_usable_route) { +				/* +				 * Make monitor +				 * +				 * TBD factor this out into its own function +				 */ +				struct prefix *pfx_mon = prefix_new(); +				if (!RFAPI_MONITOR_EXTERIOR(rn)->source) { +					RFAPI_MONITOR_EXTERIOR(rn)->source = +						skiplist_new( +							0, NULL, +							(void (*)(void *)) +								prefix_free); +					route_lock_node(rn); /* for skiplist */ +				} +				route_lock_node(rn); /* for skiplist entry */ +				prefix_copy(pfx_mon, prefix); +				if (!skiplist_insert( +					    RFAPI_MONITOR_EXTERIOR(rn)->source, +					    info, pfx_mon)) { + +					bgp_info_lock(info); +				} +			} +			par = rn->parent; +			if (par) +				route_lock_node(par); +			route_unlock_node(rn); +			rn = par; +		} +		if (rn) +			route_unlock_node(rn); + +		if (!have_usable_route) { +			struct prefix *pfx_mon = prefix_new(); +			prefix_copy(pfx_mon, prefix); +			if (!skiplist_insert(it->monitor_exterior_orphans, info, +					     pfx_mon)) { + +				bgp_info_lock(info); +			} +		} +	}  } -void -vnc_import_bgp_exterior_add_route ( -    struct bgp		*bgp,	/* exterior instance, we hope */ -    struct prefix	*prefix,/* unicast prefix */ -    struct bgp_info	*info)	/* unicast info */ +void vnc_import_bgp_exterior_add_route( +	struct bgp *bgp,       /* exterior instance, we hope */ +	struct prefix *prefix, /* unicast prefix */ +	struct bgp_info *info) /* unicast info */  { -  vnc_import_bgp_exterior_add_route_it (bgp, prefix, info, NULL); +	vnc_import_bgp_exterior_add_route_it(bgp, prefix, info, NULL);  }  /* @@ -2001,155 +1890,163 @@ vnc_import_bgp_exterior_add_route (   * We filter here on the instance name to make sure we get only the   * right routes.   */ -void -vnc_import_bgp_exterior_del_route ( -    struct bgp		*bgp, -    struct prefix	*prefix,	/* unicast prefix */ -    struct bgp_info	*info)		/* unicast info */ +void vnc_import_bgp_exterior_del_route( +	struct bgp *bgp, struct prefix *prefix, /* unicast prefix */ +	struct bgp_info *info)			/* unicast info */  { -  struct rfapi *h; -  struct rfapi_cfg *hc; -  struct rfapi_import_table *it; -  struct prefix pfx_orig_nexthop; -  afi_t afi = family2afi (prefix->family); -  struct bgp *bgp_default = bgp_get_default (); - -  if (!bgp_default) -    return; - -  memset (&pfx_orig_nexthop, 0, sizeof (struct prefix));        /* keep valgrind happy */ - -  h = bgp_default->rfapi; -  hc = bgp_default->rfapi_cfg; - -  if (!h || !hc) -    { -      vnc_zlog_debug_verbose ("%s: rfapi or rfapi_cfg not instantiated, skipping", -                  __func__); -      return; -    } -  if (!hc->redist_bgp_exterior_view) -    { -      vnc_zlog_debug_verbose ("%s: exterior view not set, skipping", __func__); -      return; -    } -  if (bgp != hc->redist_bgp_exterior_view) -    { -      vnc_zlog_debug_verbose ("%s: bgp %p != hc->redist_bgp_exterior_view %p, skipping", -                  __func__, bgp, hc->redist_bgp_exterior_view); -      return; -    } -  if (!hc->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT]) -    { -      vnc_zlog_debug_verbose ("%s: redist of exterior routes no enabled, skipping", -                  __func__); -      return; -    } - -  if (!info->attr) -    { -      vnc_zlog_debug_verbose ("%s: no info, skipping", __func__); -      return; -    } - -  /* -   * Extract nexthop from exterior route -   * -   * Incoming prefix is unicast. If v6, it is in multiprotocol area, -   * but if v4 it is in attr->nexthop -   */ -  rfapiUnicastNexthop2Prefix (afi, info->attr, &pfx_orig_nexthop); - -  for (it = h->imports; it; it = it->next) -    { -      struct route_table *table; -      struct route_node *rn; -      struct route_node *par; -      struct bgp_info *bi_interior; -      int have_usable_route; - -      table = it->imported_vpn[afi]; - -      for (rn = route_node_match (table, &pfx_orig_nexthop), -           have_usable_route = 0; (!have_usable_route) && rn;) -        { - -          for (bi_interior = rn->info; bi_interior; -               bi_interior = bi_interior->next) -            { -              struct prefix_rd *prd; -              u_int32_t label = 0; - -              if (!is_usable_interior_route (bi_interior)) -                continue; - -              /* -               * have a legitimate route to exterior's nexthop -               * via NVE. -               * -               * Import unicast route to the import table -               */ -              have_usable_route = 1; - -              if (bi_interior->extra) -                { -                  prd = &bi_interior->extra->vnc.import.rd; -                  label = decode_label (&bi_interior->extra->label); -                } -              else -                prd = NULL; - -              rfapiBgpInfoFilteredImportVPN (it, FIF_ACTION_KILL, bi_interior->peer, NULL,      /* rfd */ -                                             prefix, -                                             NULL, -                                             afi, -                                             prd, -                                             bi_interior->attr, -                                             ZEBRA_ROUTE_BGP_DIRECT_EXT, -                                             BGP_ROUTE_REDISTRIBUTE, &label); - -              /* -               * Delete monitor -               * -               * TBD factor this out into its own function -               */ -              { -                if (RFAPI_MONITOR_EXTERIOR (rn)->source) -                  { -                    if (!skiplist_delete (RFAPI_MONITOR_EXTERIOR (rn)->source, -                                          info, NULL)) -                      { - -                        bgp_info_unlock (info); -                        route_unlock_node (rn); /* sl entry */ -                      } -                    if (skiplist_empty (RFAPI_MONITOR_EXTERIOR (rn)->source)) -                      { -                        skiplist_free (RFAPI_MONITOR_EXTERIOR (rn)->source); -                        RFAPI_MONITOR_EXTERIOR (rn)->source = NULL; -                        route_unlock_node (rn); /* skiplist itself */ -                      } -                  } -              } -            } -          par = rn->parent; -          if (par) -            route_lock_node (par); -          route_unlock_node (rn); -          rn = par; -        } -      if (rn) -        route_unlock_node (rn); - -      if (!have_usable_route) -        { -          if (!skiplist_delete (it->monitor_exterior_orphans, info, NULL)) -            { - -              bgp_info_unlock (info); -            } -        } -    } +	struct rfapi *h; +	struct rfapi_cfg *hc; +	struct rfapi_import_table *it; +	struct prefix pfx_orig_nexthop; +	afi_t afi = family2afi(prefix->family); +	struct bgp *bgp_default = bgp_get_default(); + +	if (!bgp_default) +		return; + +	memset(&pfx_orig_nexthop, 0, +	       sizeof(struct prefix)); /* keep valgrind happy */ + +	h = bgp_default->rfapi; +	hc = bgp_default->rfapi_cfg; + +	if (!h || !hc) { +		vnc_zlog_debug_verbose( +			"%s: rfapi or rfapi_cfg not instantiated, skipping", +			__func__); +		return; +	} +	if (!hc->redist_bgp_exterior_view) { +		vnc_zlog_debug_verbose("%s: exterior view not set, skipping", +				       __func__); +		return; +	} +	if (bgp != hc->redist_bgp_exterior_view) { +		vnc_zlog_debug_verbose( +			"%s: bgp %p != hc->redist_bgp_exterior_view %p, skipping", +			__func__, bgp, hc->redist_bgp_exterior_view); +		return; +	} +	if (!hc->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT]) { +		vnc_zlog_debug_verbose( +			"%s: redist of exterior routes no enabled, skipping", +			__func__); +		return; +	} + +	if (!info->attr) { +		vnc_zlog_debug_verbose("%s: no info, skipping", __func__); +		return; +	} + +	/* +	 * Extract nexthop from exterior route +	 * +	 * Incoming prefix is unicast. If v6, it is in multiprotocol area, +	 * but if v4 it is in attr->nexthop +	 */ +	rfapiUnicastNexthop2Prefix(afi, info->attr, &pfx_orig_nexthop); + +	for (it = h->imports; it; it = it->next) { +		struct route_table *table; +		struct route_node *rn; +		struct route_node *par; +		struct bgp_info *bi_interior; +		int have_usable_route; + +		table = it->imported_vpn[afi]; + +		for (rn = route_node_match(table, &pfx_orig_nexthop), +		    have_usable_route = 0; +		     (!have_usable_route) && rn;) { + +			for (bi_interior = rn->info; bi_interior; +			     bi_interior = bi_interior->next) { +				struct prefix_rd *prd; +				u_int32_t label = 0; + +				if (!is_usable_interior_route(bi_interior)) +					continue; + +				/* +				 * have a legitimate route to exterior's nexthop +				 * via NVE. +				 * +				 * Import unicast route to the import table +				 */ +				have_usable_route = 1; + +				if (bi_interior->extra) { +					prd = &bi_interior->extra->vnc.import +						       .rd; +					label = decode_label( +						&bi_interior->extra->label); +				} else +					prd = NULL; + +				rfapiBgpInfoFilteredImportVPN( +					it, FIF_ACTION_KILL, bi_interior->peer, +					NULL, /* rfd */ +					prefix, NULL, afi, prd, +					bi_interior->attr, +					ZEBRA_ROUTE_BGP_DIRECT_EXT, +					BGP_ROUTE_REDISTRIBUTE, &label); + +				/* +				 * Delete monitor +				 * +				 * TBD factor this out into its own function +				 */ +				{ +					if (RFAPI_MONITOR_EXTERIOR(rn) +						    ->source) { +						if (!skiplist_delete( +							    RFAPI_MONITOR_EXTERIOR( +								    rn) +								    ->source, +							    info, NULL)) { + +							bgp_info_unlock(info); +							route_unlock_node( +								rn); /* sl entry +									*/ +						} +						if (skiplist_empty( +							    RFAPI_MONITOR_EXTERIOR( +								    rn) +								    ->source)) { +							skiplist_free( +								RFAPI_MONITOR_EXTERIOR( +									rn) +									->source); +							RFAPI_MONITOR_EXTERIOR( +								rn) +								->source = NULL; +							route_unlock_node( +								rn); /* skiplist +									itself +									*/ +						} +					} +				} +			} +			par = rn->parent; +			if (par) +				route_lock_node(par); +			route_unlock_node(rn); +			rn = par; +		} +		if (rn) +			route_unlock_node(rn); + +		if (!have_usable_route) { +			if (!skiplist_delete(it->monitor_exterior_orphans, info, +					     NULL)) { + +				bgp_info_unlock(info); +			} +		} +	}  }  /* @@ -2159,387 +2056,378 @@ vnc_import_bgp_exterior_del_route (   * NB should also be called whenever an existing vpn interior route   * becomes valid (e.g., valid_interior_count is inremented)   */ -void -vnc_import_bgp_exterior_add_route_interior ( -    struct bgp			*bgp, -    struct rfapi_import_table	*it, -    struct route_node		*rn_interior,	/* VPN IT node */ -    struct bgp_info		*bi_interior)	/* VPN IT route */ +void vnc_import_bgp_exterior_add_route_interior( +	struct bgp *bgp, struct rfapi_import_table *it, +	struct route_node *rn_interior, /* VPN IT node */ +	struct bgp_info *bi_interior)   /* VPN IT route */  { -  afi_t afi = family2afi (rn_interior->p.family); -  struct route_node *par; -  struct bgp_info *bi_exterior; -  struct prefix *pfx_exterior;  /* exterior pfx */ -  void *cursor; -  int rc; -  struct list *list_adopted; - -  vnc_zlog_debug_verbose ("%s: entry", __func__); - -  if (!is_usable_interior_route (bi_interior)) -    { -      vnc_zlog_debug_verbose ("%s: not usable interior route, skipping", __func__); -      return; -    } - -  if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT]) -    { -      vnc_zlog_debug_verbose ("%s: redist of exterior routes no enabled, skipping", -                  __func__); -      return; -    } - -  if (it == bgp->rfapi->it_ce) -    { -      vnc_zlog_debug_verbose ("%s: import table is it_ce, skipping", __func__); -      return; -    } - -  /*debugging */ -  { -    char str_pfx[BUFSIZ]; - -    prefix2str (&rn_interior->p, str_pfx, BUFSIZ); -    str_pfx[BUFSIZ - 1] = 0; - -    vnc_zlog_debug_verbose ("%s: interior prefix=%s, bi type=%d", -                __func__, str_pfx, bi_interior->type); -  } - -  if (RFAPI_HAS_MONITOR_EXTERIOR (rn_interior)) -    { - -      int count = 0;            /* debugging */ - -      vnc_zlog_debug_verbose ("%s: has exterior monitor; ext src: %p", __func__, -                  RFAPI_MONITOR_EXTERIOR (rn_interior)->source); - -      /* -       * There is a monitor here already. Therefore, we do not need -       * to do any pulldown. Just construct exterior routes based -       * on the new interior route. -       */ -      cursor = NULL; -      for (rc = skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior)->source, -                               (void **) &bi_exterior, -                               (void **) &pfx_exterior, &cursor); !rc; -           rc = -           skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior)->source, -                          (void **) &bi_exterior, (void **) &pfx_exterior, -                          &cursor)) -        { - -          struct prefix_rd *prd; -          struct attr new_attr; -          u_int32_t label = 0; - - -          ++count;              /* debugging */ - -          assert (bi_exterior); -          assert (pfx_exterior); - -          if (bi_interior->extra) -            { -              prd = &bi_interior->extra->vnc.import.rd; -              label = decode_label (&bi_interior->extra->label); -            } -          else -            prd = NULL; - -          /* use local_pref from unicast route */ -          memset (&new_attr, 0, sizeof (struct attr)); -          bgp_attr_dup (&new_attr, bi_interior->attr); -          if (bi_exterior && -              (bi_exterior->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))) -            { -              new_attr.local_pref = bi_exterior->attr->local_pref; -              new_attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF); -            } - -          rfapiBgpInfoFilteredImportVPN (it, FIF_ACTION_UPDATE, bi_interior->peer, NULL,        /* rfd */ -                                         pfx_exterior, -                                         NULL, -                                         afi, -                                         prd, -                                         &new_attr, -                                         ZEBRA_ROUTE_BGP_DIRECT_EXT, -                                         BGP_ROUTE_REDISTRIBUTE, &label); - -        } -      vnc_zlog_debug_verbose -        ("%s: finished constructing exteriors based on existing monitors", -         __func__); -      return; -    } - -  vnc_zlog_debug_verbose ("%s: no exterior monitor", __func__); - -  /* -   * No monitor at this node. Is this the first valid interior -   * route at this node? -   */ -  if (RFAPI_MONITOR_EXTERIOR (rn_interior)->valid_interior_count > 1) -    { -      vnc_zlog_debug_verbose -        ("%s: new interior route not first valid one, skipping pulldown", -         __func__); -      return; -    } - -  /* -   * Look up the tree for possible pulldown candidates. -   * Find nearest parent with an exterior route monitor -   */ -  for (par = rn_interior->parent; par; par = par->parent) -    { -      if (RFAPI_HAS_MONITOR_EXTERIOR (par)) -        break; -    } - -  if (par) -    { - -      vnc_zlog_debug_verbose ("%s: checking parent %p for possible pulldowns", -                  __func__, par); - -      /* check monitors at par for possible pulldown */ -      cursor = NULL; -      for (rc = skiplist_next (RFAPI_MONITOR_EXTERIOR (par)->source, -                               (void **) &bi_exterior, -                               (void **) &pfx_exterior, &cursor); !rc; -           rc = -           skiplist_next (RFAPI_MONITOR_EXTERIOR (par)->source, -                          (void **) &bi_exterior, (void **) &pfx_exterior, -                          &cursor)) -        { - -          struct prefix pfx_nexthop; - -          memset (&pfx_nexthop, 0, sizeof (struct prefix));     /* keep valgrind happy */ - -          /* check original nexthop for prefix match */ -          rfapiUnicastNexthop2Prefix (afi, bi_exterior->attr, &pfx_nexthop); - -          if (prefix_match (&rn_interior->p, &pfx_nexthop)) -            { - -              struct bgp_info *bi; -              struct prefix_rd *prd; -              struct attr new_attr; -              u_int32_t label = 0; - -              /* do pull-down */ - -              /* -               * add monitor to longer prefix -               */ -              struct prefix *pfx_mon = prefix_new (); -              prefix_copy (pfx_mon, pfx_exterior); -              if (!RFAPI_MONITOR_EXTERIOR (rn_interior)->source) -                { -                  RFAPI_MONITOR_EXTERIOR (rn_interior)->source = -                    skiplist_new (0, NULL, (void (*)(void *)) prefix_free); -                  route_lock_node (rn_interior); -                } -              skiplist_insert (RFAPI_MONITOR_EXTERIOR (rn_interior)->source, -                               bi_exterior, pfx_mon); -              route_lock_node (rn_interior); - -              /* -               * Delete constructed exterior routes based on -               * parent routes. -               */ -              for (bi = par->info; bi; bi = bi->next) -                { - -                  if (bi->extra) -                    { -                      prd = &bi->extra->vnc.import.rd; -                      label = decode_label (&bi->extra->label); -                    } -                  else -                    prd = NULL; - -                  rfapiBgpInfoFilteredImportVPN (it, FIF_ACTION_KILL, bi->peer, NULL,   /* rfd */ -                                                 pfx_exterior, -                                                 NULL, -                                                 afi, -                                                 prd, -                                                 bi->attr, -                                                 ZEBRA_ROUTE_BGP_DIRECT_EXT, -                                                 BGP_ROUTE_REDISTRIBUTE, -                                                 &label); -                } - - -              /* -               * Add constructed exterior routes based on -               * the new interior route at longer prefix. -               */ -              if (bi_interior->extra) -                { -                  prd = &bi_interior->extra->vnc.import.rd; -                  label = decode_label (&bi_interior->extra->label); -                } -              else -                prd = NULL; - -              /* use local_pref from unicast route */ -              memset (&new_attr, 0, sizeof (struct attr)); -              bgp_attr_dup (&new_attr, bi_interior->attr); -              if (bi_exterior && -                  (bi_exterior->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))) -                { -                  new_attr.local_pref = bi_exterior->attr->local_pref; -                  new_attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF); -                } - -              rfapiBgpInfoFilteredImportVPN (it, FIF_ACTION_UPDATE, bi_interior->peer, NULL,    /* rfd */ -                                             pfx_exterior, -                                             NULL, -                                             afi, -                                             prd, -                                             &new_attr, -                                             ZEBRA_ROUTE_BGP_DIRECT_EXT, -                                             BGP_ROUTE_REDISTRIBUTE, &label); - -            } -        } - -      /* -       * The only monitors at rn_interior are the ones we added just -       * above, so we can use the rn_interior list to identify which -       * monitors to delete from the parent. -       */ -      cursor = NULL; -      for (rc = skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior)->source, -                               (void **) &bi_exterior, NULL, &cursor); -           !rc; -           rc = skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior)->source, -                               (void **) &bi_exterior, NULL, &cursor)) -        { - - -          skiplist_delete (RFAPI_MONITOR_EXTERIOR (par)->source, -                           bi_exterior, NULL); -          route_unlock_node (par);      /* sl entry */ -        } -      if (skiplist_empty (RFAPI_MONITOR_EXTERIOR (par)->source)) -        { -          skiplist_free (RFAPI_MONITOR_EXTERIOR (par)->source); -          RFAPI_MONITOR_EXTERIOR (par)->source = NULL; -          route_unlock_node (par);      /* sl itself */ -        } -    } - -  vnc_zlog_debug_verbose ("%s: checking orphans", __func__); - -  /* -   * See if any orphans can be pulled down to the current node -   */ -  cursor = NULL; -  list_adopted = NULL; -  for (rc = skiplist_next (it->monitor_exterior_orphans, -                           (void **) &bi_exterior, (void **) &pfx_exterior, -                           &cursor); !rc; -       rc = -       skiplist_next (it->monitor_exterior_orphans, (void **) &bi_exterior, -                      (void **) &pfx_exterior, &cursor)) -    { - -      struct prefix pfx_nexthop; -      char buf[BUFSIZ]; -      afi_t afi_exterior = family2afi (pfx_exterior->family); - -      prefix2str (pfx_exterior, buf, sizeof (buf)); -      buf[sizeof (buf) - 1] = 0; -      vnc_zlog_debug_verbose ("%s: checking exterior orphan at prefix %s", __func__, buf); - -      if (afi_exterior != afi) -        { -          vnc_zlog_debug_verbose ("%s: exterior orphan afi %d != interior afi %d, skip", -                      __func__, afi_exterior, afi); -          continue; -        } - -      /* check original nexthop for prefix match */ -      rfapiUnicastNexthop2Prefix (afi, bi_exterior->attr, &pfx_nexthop); - -      if (prefix_match (&rn_interior->p, &pfx_nexthop)) -        { - -          struct prefix_rd *prd; -          struct attr new_attr; -          u_int32_t label = 0; - -          /* do pull-down */ - -          /* -           * add monitor to longer prefix -           */ - -          struct prefix *pfx_mon = prefix_new (); -          prefix_copy (pfx_mon, pfx_exterior); -          if (!RFAPI_MONITOR_EXTERIOR (rn_interior)->source) -            { -              RFAPI_MONITOR_EXTERIOR (rn_interior)->source = -                skiplist_new (0, NULL, (void (*)(void *)) prefix_free); -              route_lock_node (rn_interior);    /* sl */ -            } -          skiplist_insert (RFAPI_MONITOR_EXTERIOR (rn_interior)->source, -                           bi_exterior, pfx_mon); -          route_lock_node (rn_interior);        /* sl entry */ -          if (!list_adopted) -            { -              list_adopted = list_new (); -            } -          listnode_add (list_adopted, bi_exterior); - -          /* -           * Add constructed exterior routes based on the -           * new interior route at the longer prefix. -           */ -          if (bi_interior->extra) -            { -              prd = &bi_interior->extra->vnc.import.rd; -              label = decode_label (&bi_interior->extra->label); -            } -          else -            prd = NULL; - -          /* use local_pref from unicast route */ -          memset (&new_attr, 0, sizeof (struct attr)); -          bgp_attr_dup (&new_attr, bi_interior->attr); -          if (bi_exterior && -              (bi_exterior->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))) -            { -              new_attr.local_pref = bi_exterior->attr->local_pref; -              new_attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF); -            } - -          rfapiBgpInfoFilteredImportVPN (it, FIF_ACTION_UPDATE, bi_interior->peer, NULL,        /* rfd */ -                                         pfx_exterior, -                                         NULL, -                                         afi, -                                         prd, -                                         &new_attr, -                                         ZEBRA_ROUTE_BGP_DIRECT_EXT, -                                         BGP_ROUTE_REDISTRIBUTE, &label); - -        } -    } -  if (list_adopted) -    { -      struct listnode *node; -      struct route_node *bi_exterior; - -      for (ALL_LIST_ELEMENTS_RO (list_adopted, node, bi_exterior)) -        { -          skiplist_delete (it->monitor_exterior_orphans, bi_exterior, NULL); -        } -      list_delete (list_adopted); -    } +	afi_t afi = family2afi(rn_interior->p.family); +	struct route_node *par; +	struct bgp_info *bi_exterior; +	struct prefix *pfx_exterior; /* exterior pfx */ +	void *cursor; +	int rc; +	struct list *list_adopted; + +	vnc_zlog_debug_verbose("%s: entry", __func__); + +	if (!is_usable_interior_route(bi_interior)) { +		vnc_zlog_debug_verbose( +			"%s: not usable interior route, skipping", __func__); +		return; +	} + +	if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT]) { +		vnc_zlog_debug_verbose( +			"%s: redist of exterior routes no enabled, skipping", +			__func__); +		return; +	} + +	if (it == bgp->rfapi->it_ce) { +		vnc_zlog_debug_verbose("%s: import table is it_ce, skipping", +				       __func__); +		return; +	} + +	/*debugging */ +	{ +		char str_pfx[BUFSIZ]; + +		prefix2str(&rn_interior->p, str_pfx, BUFSIZ); +		str_pfx[BUFSIZ - 1] = 0; + +		vnc_zlog_debug_verbose("%s: interior prefix=%s, bi type=%d", +				       __func__, str_pfx, bi_interior->type); +	} + +	if (RFAPI_HAS_MONITOR_EXTERIOR(rn_interior)) { + +		int count = 0; /* debugging */ + +		vnc_zlog_debug_verbose( +			"%s: has exterior monitor; ext src: %p", __func__, +			RFAPI_MONITOR_EXTERIOR(rn_interior)->source); + +		/* +		 * There is a monitor here already. Therefore, we do not need +		 * to do any pulldown. Just construct exterior routes based +		 * on the new interior route. +		 */ +		cursor = NULL; +		for (rc = skiplist_next( +			     RFAPI_MONITOR_EXTERIOR(rn_interior)->source, +			     (void **)&bi_exterior, (void **)&pfx_exterior, +			     &cursor); +		     !rc; rc = skiplist_next( +				  RFAPI_MONITOR_EXTERIOR(rn_interior)->source, +				  (void **)&bi_exterior, (void **)&pfx_exterior, +				  &cursor)) { + +			struct prefix_rd *prd; +			struct attr new_attr; +			u_int32_t label = 0; + + +			++count; /* debugging */ + +			assert(bi_exterior); +			assert(pfx_exterior); + +			if (bi_interior->extra) { +				prd = &bi_interior->extra->vnc.import.rd; +				label = decode_label( +					&bi_interior->extra->label); +			} else +				prd = NULL; + +			/* use local_pref from unicast route */ +			memset(&new_attr, 0, sizeof(struct attr)); +			bgp_attr_dup(&new_attr, bi_interior->attr); +			if (bi_exterior +			    && (bi_exterior->attr->flag +				& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))) { +				new_attr.local_pref = +					bi_exterior->attr->local_pref; +				new_attr.flag |= +					ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF); +			} + +			rfapiBgpInfoFilteredImportVPN( +				it, FIF_ACTION_UPDATE, bi_interior->peer, +				NULL, /* rfd */ +				pfx_exterior, NULL, afi, prd, &new_attr, +				ZEBRA_ROUTE_BGP_DIRECT_EXT, +				BGP_ROUTE_REDISTRIBUTE, &label); +		} +		vnc_zlog_debug_verbose( +			"%s: finished constructing exteriors based on existing monitors", +			__func__); +		return; +	} + +	vnc_zlog_debug_verbose("%s: no exterior monitor", __func__); + +	/* +	 * No monitor at this node. Is this the first valid interior +	 * route at this node? +	 */ +	if (RFAPI_MONITOR_EXTERIOR(rn_interior)->valid_interior_count > 1) { +		vnc_zlog_debug_verbose( +			"%s: new interior route not first valid one, skipping pulldown", +			__func__); +		return; +	} + +	/* +	 * Look up the tree for possible pulldown candidates. +	 * Find nearest parent with an exterior route monitor +	 */ +	for (par = rn_interior->parent; par; par = par->parent) { +		if (RFAPI_HAS_MONITOR_EXTERIOR(par)) +			break; +	} + +	if (par) { + +		vnc_zlog_debug_verbose( +			"%s: checking parent %p for possible pulldowns", +			__func__, par); + +		/* check monitors at par for possible pulldown */ +		cursor = NULL; +		for (rc = skiplist_next(RFAPI_MONITOR_EXTERIOR(par)->source, +					(void **)&bi_exterior, +					(void **)&pfx_exterior, &cursor); +		     !rc; +		     rc = skiplist_next(RFAPI_MONITOR_EXTERIOR(par)->source, +					(void **)&bi_exterior, +					(void **)&pfx_exterior, &cursor)) { + +			struct prefix pfx_nexthop; + +			memset(&pfx_nexthop, 0, +			       sizeof(struct prefix)); /* keep valgrind happy */ + +			/* check original nexthop for prefix match */ +			rfapiUnicastNexthop2Prefix(afi, bi_exterior->attr, +						   &pfx_nexthop); + +			if (prefix_match(&rn_interior->p, &pfx_nexthop)) { + +				struct bgp_info *bi; +				struct prefix_rd *prd; +				struct attr new_attr; +				u_int32_t label = 0; + +				/* do pull-down */ + +				/* +				 * add monitor to longer prefix +				 */ +				struct prefix *pfx_mon = prefix_new(); +				prefix_copy(pfx_mon, pfx_exterior); +				if (!RFAPI_MONITOR_EXTERIOR(rn_interior) +					     ->source) { +					RFAPI_MONITOR_EXTERIOR(rn_interior) +						->source = skiplist_new( +						0, NULL, +						(void (*)(void *))prefix_free); +					route_lock_node(rn_interior); +				} +				skiplist_insert( +					RFAPI_MONITOR_EXTERIOR(rn_interior) +						->source, +					bi_exterior, pfx_mon); +				route_lock_node(rn_interior); + +				/* +				 * Delete constructed exterior routes based on +				 * parent routes. +				 */ +				for (bi = par->info; bi; bi = bi->next) { + +					if (bi->extra) { +						prd = &bi->extra->vnc.import.rd; +						label = decode_label( +							&bi->extra->label); +					} else +						prd = NULL; + +					rfapiBgpInfoFilteredImportVPN( +						it, FIF_ACTION_KILL, bi->peer, +						NULL, /* rfd */ +						pfx_exterior, NULL, afi, prd, +						bi->attr, +						ZEBRA_ROUTE_BGP_DIRECT_EXT, +						BGP_ROUTE_REDISTRIBUTE, &label); +				} + + +				/* +				 * Add constructed exterior routes based on +				 * the new interior route at longer prefix. +				 */ +				if (bi_interior->extra) { +					prd = &bi_interior->extra->vnc.import +						       .rd; +					label = decode_label( +						&bi_interior->extra->label); +				} else +					prd = NULL; + +				/* use local_pref from unicast route */ +				memset(&new_attr, 0, sizeof(struct attr)); +				bgp_attr_dup(&new_attr, bi_interior->attr); +				if (bi_exterior +				    && (bi_exterior->attr->flag +					& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))) { +					new_attr.local_pref = +						bi_exterior->attr->local_pref; +					new_attr.flag |= ATTR_FLAG_BIT( +						BGP_ATTR_LOCAL_PREF); +				} + +				rfapiBgpInfoFilteredImportVPN( +					it, FIF_ACTION_UPDATE, +					bi_interior->peer, NULL, /* rfd */ +					pfx_exterior, NULL, afi, prd, &new_attr, +					ZEBRA_ROUTE_BGP_DIRECT_EXT, +					BGP_ROUTE_REDISTRIBUTE, &label); +			} +		} + +		/* +		 * The only monitors at rn_interior are the ones we added just +		 * above, so we can use the rn_interior list to identify which +		 * monitors to delete from the parent. +		 */ +		cursor = NULL; +		for (rc = skiplist_next( +			     RFAPI_MONITOR_EXTERIOR(rn_interior)->source, +			     (void **)&bi_exterior, NULL, &cursor); +		     !rc; rc = skiplist_next( +				  RFAPI_MONITOR_EXTERIOR(rn_interior)->source, +				  (void **)&bi_exterior, NULL, &cursor)) { + + +			skiplist_delete(RFAPI_MONITOR_EXTERIOR(par)->source, +					bi_exterior, NULL); +			route_unlock_node(par); /* sl entry */ +		} +		if (skiplist_empty(RFAPI_MONITOR_EXTERIOR(par)->source)) { +			skiplist_free(RFAPI_MONITOR_EXTERIOR(par)->source); +			RFAPI_MONITOR_EXTERIOR(par)->source = NULL; +			route_unlock_node(par); /* sl itself */ +		} +	} + +	vnc_zlog_debug_verbose("%s: checking orphans", __func__); + +	/* +	 * See if any orphans can be pulled down to the current node +	 */ +	cursor = NULL; +	list_adopted = NULL; +	for (rc = skiplist_next(it->monitor_exterior_orphans, +				(void **)&bi_exterior, (void **)&pfx_exterior, +				&cursor); +	     !rc; rc = skiplist_next(it->monitor_exterior_orphans, +				     (void **)&bi_exterior, +				     (void **)&pfx_exterior, &cursor)) { + +		struct prefix pfx_nexthop; +		char buf[BUFSIZ]; +		afi_t afi_exterior = family2afi(pfx_exterior->family); + +		prefix2str(pfx_exterior, buf, sizeof(buf)); +		buf[sizeof(buf) - 1] = 0; +		vnc_zlog_debug_verbose( +			"%s: checking exterior orphan at prefix %s", __func__, +			buf); + +		if (afi_exterior != afi) { +			vnc_zlog_debug_verbose( +				"%s: exterior orphan afi %d != interior afi %d, skip", +				__func__, afi_exterior, afi); +			continue; +		} + +		/* check original nexthop for prefix match */ +		rfapiUnicastNexthop2Prefix(afi, bi_exterior->attr, +					   &pfx_nexthop); + +		if (prefix_match(&rn_interior->p, &pfx_nexthop)) { + +			struct prefix_rd *prd; +			struct attr new_attr; +			u_int32_t label = 0; + +			/* do pull-down */ + +			/* +			 * add monitor to longer prefix +			 */ + +			struct prefix *pfx_mon = prefix_new(); +			prefix_copy(pfx_mon, pfx_exterior); +			if (!RFAPI_MONITOR_EXTERIOR(rn_interior)->source) { +				RFAPI_MONITOR_EXTERIOR(rn_interior)->source = +					skiplist_new( +						0, NULL, +						(void (*)(void *))prefix_free); +				route_lock_node(rn_interior); /* sl */ +			} +			skiplist_insert( +				RFAPI_MONITOR_EXTERIOR(rn_interior)->source, +				bi_exterior, pfx_mon); +			route_lock_node(rn_interior); /* sl entry */ +			if (!list_adopted) { +				list_adopted = list_new(); +			} +			listnode_add(list_adopted, bi_exterior); + +			/* +			 * Add constructed exterior routes based on the +			 * new interior route at the longer prefix. +			 */ +			if (bi_interior->extra) { +				prd = &bi_interior->extra->vnc.import.rd; +				label = decode_label( +					&bi_interior->extra->label); +			} else +				prd = NULL; + +			/* use local_pref from unicast route */ +			memset(&new_attr, 0, sizeof(struct attr)); +			bgp_attr_dup(&new_attr, bi_interior->attr); +			if (bi_exterior +			    && (bi_exterior->attr->flag +				& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))) { +				new_attr.local_pref = +					bi_exterior->attr->local_pref; +				new_attr.flag |= +					ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF); +			} + +			rfapiBgpInfoFilteredImportVPN( +				it, FIF_ACTION_UPDATE, bi_interior->peer, +				NULL, /* rfd */ +				pfx_exterior, NULL, afi, prd, &new_attr, +				ZEBRA_ROUTE_BGP_DIRECT_EXT, +				BGP_ROUTE_REDISTRIBUTE, &label); +		} +	} +	if (list_adopted) { +		struct listnode *node; +		struct route_node *bi_exterior; + +		for (ALL_LIST_ELEMENTS_RO(list_adopted, node, bi_exterior)) { +			skiplist_delete(it->monitor_exterior_orphans, +					bi_exterior, NULL); +		} +		list_delete(list_adopted); +	}  }  /* @@ -2552,348 +2440,327 @@ vnc_import_bgp_exterior_add_route_interior (   * NB should also be called whenever an existing vpn interior route   * becomes invalid (e.g., valid_interior_count is decremented)   */ -void -vnc_import_bgp_exterior_del_route_interior ( -    struct bgp			*bgp, -    struct rfapi_import_table	*it, -    struct route_node		*rn_interior,	/* VPN IT node */ -    struct bgp_info		*bi_interior)	/* VPN IT route */ +void vnc_import_bgp_exterior_del_route_interior( +	struct bgp *bgp, struct rfapi_import_table *it, +	struct route_node *rn_interior, /* VPN IT node */ +	struct bgp_info *bi_interior)   /* VPN IT route */  { -  afi_t afi = family2afi (rn_interior->p.family); -  struct route_node *par; -  struct bgp_info *bi_exterior; -  struct prefix *pfx_exterior;  /* exterior pfx */ -  void *cursor; -  int rc; - -  if (!VALID_INTERIOR_TYPE (bi_interior->type)) -    { -      vnc_zlog_debug_verbose ("%s: type %d not valid interior type, skipping", -                  __func__, bi_interior->type); -      return; -    } - -  if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT]) -    { -      vnc_zlog_debug_verbose ("%s: redist of exterior routes no enabled, skipping", -                  __func__); -      return; -    } - -  if (it == bgp->rfapi->it_ce) -    { -      vnc_zlog_debug_verbose ("%s: it is it_ce, skipping", __func__); -      return; -    } - -  /* If no exterior routes depend on this prefix, nothing to do */ -  if (!RFAPI_HAS_MONITOR_EXTERIOR (rn_interior)) -    { -      vnc_zlog_debug_verbose ("%s: no exterior monitor, skipping", __func__); -      return; -    } - -  /*debugging */ -  { -    char str_pfx[BUFSIZ]; - -    prefix2str (&rn_interior->p, str_pfx, BUFSIZ); -    str_pfx[BUFSIZ - 1] = 0; - -    vnc_zlog_debug_verbose ("%s: interior prefix=%s, bi type=%d", -                __func__, str_pfx, bi_interior->type); -  } - -  /* -   * Remove constructed routes based on the deleted interior route -   */ -  cursor = NULL; -  for (rc = skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior)->source, -                           (void **) &bi_exterior, (void **) &pfx_exterior, -                           &cursor); !rc; -       rc = -       skiplist_next (RFAPI_MONITOR_EXTERIOR (rn_interior)->source, -                      (void **) &bi_exterior, (void **) &pfx_exterior, -                      &cursor)) -    { - -      struct prefix_rd *prd; -      u_int32_t label = 0; - -      if (bi_interior->extra) -        { -          prd = &bi_interior->extra->vnc.import.rd; -          label = decode_label (&bi_interior->extra->label); -        } -      else -        prd = NULL; - -      rfapiBgpInfoFilteredImportVPN (it, FIF_ACTION_KILL, bi_interior->peer, NULL,      /* rfd */ -                                     pfx_exterior, -                                     NULL, -                                     afi, -                                     prd, -                                     bi_interior->attr, -                                     ZEBRA_ROUTE_BGP_DIRECT_EXT, -                                     BGP_ROUTE_REDISTRIBUTE, &label); -    } - -  /* -   * If there are no remaining valid interior routes at this prefix, -   * we need to look up the tree for a possible node to move monitors to -   */ -  if (RFAPI_MONITOR_EXTERIOR (rn_interior)->valid_interior_count) -    { -      vnc_zlog_debug_verbose ("%s: interior routes still present, skipping", __func__); -      return; -    } - -  /* -   * Find nearest parent with at least one valid interior route -   * If none is found, par will end up NULL, and we will move -   * the monitors to the orphan list for this import table -   */ -  for (par = rn_interior->parent; par; par = par->parent) -    { -      if (RFAPI_MONITOR_EXTERIOR (par)->valid_interior_count) -        break; -    } - -  vnc_zlog_debug_verbose ("%s: par=%p, ext src: %p", __func__, -              par, RFAPI_MONITOR_EXTERIOR (rn_interior)->source); - -  /* move all monitors */ -  /* -   * We will use and delete every element of the source skiplist -   */ -  while (!skiplist_first (RFAPI_MONITOR_EXTERIOR (rn_interior)->source, -                          (void **) &bi_exterior, (void **) &pfx_exterior)) -    { - -      struct prefix *pfx_mon = prefix_new (); - -      prefix_copy (pfx_mon, pfx_exterior); - -      if (par) -        { - -          struct bgp_info *bi; - -          /*  -           * Add monitor to parent node -           */ -          if (!RFAPI_MONITOR_EXTERIOR (par)->source) -            { -              RFAPI_MONITOR_EXTERIOR (par)->source = -                skiplist_new (0, NULL, (void (*)(void *)) prefix_free); -              route_lock_node (par);    /* sl */ -            } -          skiplist_insert (RFAPI_MONITOR_EXTERIOR (par)->source, -                           bi_exterior, pfx_mon); -          route_lock_node (par);        /* sl entry */ - -          /* Add constructed exterior routes based on parent */ -          for (bi = par->info; bi; bi = bi->next) -            { - -              struct prefix_rd *prd; -              struct attr new_attr; -              u_int32_t label = 0; - -              if (bi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT) -                continue; - -              if (bi->extra) -                { -                  prd = &bi->extra->vnc.import.rd; -                  label = decode_label (&bi->extra->label); -                } -              else -                prd = NULL; - -              /* use local_pref from unicast route */ -              memset (&new_attr, 0, sizeof (struct attr)); -              bgp_attr_dup (&new_attr, bi->attr); -              if (bi_exterior && -                  (bi_exterior->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))) -                { -                  new_attr.local_pref = bi_exterior->attr->local_pref; -                  new_attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF); -                } - -              rfapiBgpInfoFilteredImportVPN (it, FIF_ACTION_UPDATE, bi->peer, NULL,     /* rfd */ -                                             pfx_exterior, -                                             NULL, -                                             afi, -                                             prd, -                                             &new_attr, -                                             ZEBRA_ROUTE_BGP_DIRECT_EXT, -                                             BGP_ROUTE_REDISTRIBUTE, &label); - -            } - -        } -      else -        { - -          /* -           * No interior route for exterior's nexthop. Save monitor -           * in orphan list to await future route. -           */ -          skiplist_insert (it->monitor_exterior_orphans, -                           bi_exterior, pfx_mon); -        } - -      skiplist_delete_first (RFAPI_MONITOR_EXTERIOR (rn_interior)->source); -      route_unlock_node (rn_interior);  /* sl entry */ -    } -  if (skiplist_empty (RFAPI_MONITOR_EXTERIOR (rn_interior)->source)) -    { -      skiplist_free (RFAPI_MONITOR_EXTERIOR (rn_interior)->source); -      RFAPI_MONITOR_EXTERIOR (rn_interior)->source = NULL; -      route_unlock_node (rn_interior);  /* sl itself */ -    } +	afi_t afi = family2afi(rn_interior->p.family); +	struct route_node *par; +	struct bgp_info *bi_exterior; +	struct prefix *pfx_exterior; /* exterior pfx */ +	void *cursor; +	int rc; + +	if (!VALID_INTERIOR_TYPE(bi_interior->type)) { +		vnc_zlog_debug_verbose( +			"%s: type %d not valid interior type, skipping", +			__func__, bi_interior->type); +		return; +	} + +	if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT]) { +		vnc_zlog_debug_verbose( +			"%s: redist of exterior routes no enabled, skipping", +			__func__); +		return; +	} + +	if (it == bgp->rfapi->it_ce) { +		vnc_zlog_debug_verbose("%s: it is it_ce, skipping", __func__); +		return; +	} + +	/* If no exterior routes depend on this prefix, nothing to do */ +	if (!RFAPI_HAS_MONITOR_EXTERIOR(rn_interior)) { +		vnc_zlog_debug_verbose("%s: no exterior monitor, skipping", +				       __func__); +		return; +	} + +	/*debugging */ +	{ +		char str_pfx[BUFSIZ]; + +		prefix2str(&rn_interior->p, str_pfx, BUFSIZ); +		str_pfx[BUFSIZ - 1] = 0; + +		vnc_zlog_debug_verbose("%s: interior prefix=%s, bi type=%d", +				       __func__, str_pfx, bi_interior->type); +	} + +	/* +	 * Remove constructed routes based on the deleted interior route +	 */ +	cursor = NULL; +	for (rc = skiplist_next(RFAPI_MONITOR_EXTERIOR(rn_interior)->source, +				(void **)&bi_exterior, (void **)&pfx_exterior, +				&cursor); +	     !rc; +	     rc = skiplist_next(RFAPI_MONITOR_EXTERIOR(rn_interior)->source, +				(void **)&bi_exterior, (void **)&pfx_exterior, +				&cursor)) { + +		struct prefix_rd *prd; +		u_int32_t label = 0; + +		if (bi_interior->extra) { +			prd = &bi_interior->extra->vnc.import.rd; +			label = decode_label(&bi_interior->extra->label); +		} else +			prd = NULL; + +		rfapiBgpInfoFilteredImportVPN( +			it, FIF_ACTION_KILL, bi_interior->peer, NULL, /* rfd */ +			pfx_exterior, NULL, afi, prd, bi_interior->attr, +			ZEBRA_ROUTE_BGP_DIRECT_EXT, BGP_ROUTE_REDISTRIBUTE, +			&label); +	} + +	/* +	 * If there are no remaining valid interior routes at this prefix, +	 * we need to look up the tree for a possible node to move monitors to +	 */ +	if (RFAPI_MONITOR_EXTERIOR(rn_interior)->valid_interior_count) { +		vnc_zlog_debug_verbose( +			"%s: interior routes still present, skipping", +			__func__); +		return; +	} +	/* +	 * Find nearest parent with at least one valid interior route +	 * If none is found, par will end up NULL, and we will move +	 * the monitors to the orphan list for this import table +	 */ +	for (par = rn_interior->parent; par; par = par->parent) { +		if (RFAPI_MONITOR_EXTERIOR(par)->valid_interior_count) +			break; +	} + +	vnc_zlog_debug_verbose("%s: par=%p, ext src: %p", __func__, par, +			       RFAPI_MONITOR_EXTERIOR(rn_interior)->source); + +	/* move all monitors */ +	/* +	 * We will use and delete every element of the source skiplist +	 */ +	while (!skiplist_first(RFAPI_MONITOR_EXTERIOR(rn_interior)->source, +			       (void **)&bi_exterior, (void **)&pfx_exterior)) { + +		struct prefix *pfx_mon = prefix_new(); + +		prefix_copy(pfx_mon, pfx_exterior); + +		if (par) { + +			struct bgp_info *bi; + +			/* +			 * Add monitor to parent node +			 */ +			if (!RFAPI_MONITOR_EXTERIOR(par)->source) { +				RFAPI_MONITOR_EXTERIOR(par)->source = +					skiplist_new( +						0, NULL, +						(void (*)(void *))prefix_free); +				route_lock_node(par); /* sl */ +			} +			skiplist_insert(RFAPI_MONITOR_EXTERIOR(par)->source, +					bi_exterior, pfx_mon); +			route_lock_node(par); /* sl entry */ + +			/* Add constructed exterior routes based on parent */ +			for (bi = par->info; bi; bi = bi->next) { + +				struct prefix_rd *prd; +				struct attr new_attr; +				u_int32_t label = 0; + +				if (bi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT) +					continue; + +				if (bi->extra) { +					prd = &bi->extra->vnc.import.rd; +					label = decode_label(&bi->extra->label); +				} else +					prd = NULL; + +				/* use local_pref from unicast route */ +				memset(&new_attr, 0, sizeof(struct attr)); +				bgp_attr_dup(&new_attr, bi->attr); +				if (bi_exterior +				    && (bi_exterior->attr->flag +					& ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))) { +					new_attr.local_pref = +						bi_exterior->attr->local_pref; +					new_attr.flag |= ATTR_FLAG_BIT( +						BGP_ATTR_LOCAL_PREF); +				} + +				rfapiBgpInfoFilteredImportVPN( +					it, FIF_ACTION_UPDATE, bi->peer, +					NULL, /* rfd */ +					pfx_exterior, NULL, afi, prd, &new_attr, +					ZEBRA_ROUTE_BGP_DIRECT_EXT, +					BGP_ROUTE_REDISTRIBUTE, &label); +			} + +		} else { + +			/* +			 * No interior route for exterior's nexthop. Save +			 * monitor +			 * in orphan list to await future route. +			 */ +			skiplist_insert(it->monitor_exterior_orphans, +					bi_exterior, pfx_mon); +		} + +		skiplist_delete_first( +			RFAPI_MONITOR_EXTERIOR(rn_interior)->source); +		route_unlock_node(rn_interior); /* sl entry */ +	} +	if (skiplist_empty(RFAPI_MONITOR_EXTERIOR(rn_interior)->source)) { +		skiplist_free(RFAPI_MONITOR_EXTERIOR(rn_interior)->source); +		RFAPI_MONITOR_EXTERIOR(rn_interior)->source = NULL; +		route_unlock_node(rn_interior); /* sl itself */ +	}  }  /***********************************************************************   *			Generic add/delete unicast routes   ***********************************************************************/ -void -vnc_import_bgp_add_route ( -    struct bgp		*bgp, -    struct prefix	*prefix, -    struct bgp_info	*info) +void vnc_import_bgp_add_route(struct bgp *bgp, struct prefix *prefix, +			      struct bgp_info *info)  { -  afi_t afi = family2afi (prefix->family); +	afi_t afi = family2afi(prefix->family); -  { -    struct prefix pfx_nexthop; -    char buf[BUFSIZ]; -    char buf_nh[BUFSIZ]; +	{ +		struct prefix pfx_nexthop; +		char buf[BUFSIZ]; +		char buf_nh[BUFSIZ]; -    prefix2str (prefix, buf, BUFSIZ); -    rfapiUnicastNexthop2Prefix (afi, info->attr, &pfx_nexthop); -    prefix2str (&pfx_nexthop, buf_nh, BUFSIZ); +		prefix2str(prefix, buf, BUFSIZ); +		rfapiUnicastNexthop2Prefix(afi, info->attr, &pfx_nexthop); +		prefix2str(&pfx_nexthop, buf_nh, BUFSIZ); -    vnc_zlog_debug_verbose ("%s: pfx %s, nh %s", __func__, buf, buf_nh); -  } +		vnc_zlog_debug_verbose("%s: pfx %s, nh %s", __func__, buf, +				       buf_nh); +	}  #if DEBUG_RHN_LIST -  print_rhn_list(__func__, "ENTER "); +	print_rhn_list(__func__, "ENTER ");  #endif -  VNC_RHNCK (enter); - -  if (!afi) -    { -      zlog_err ("%s: can't get afi of prefix", __func__); -      return; -    } - -  if (!bgp->rfapi_cfg) -    { -      vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); -      return; -    } - -  /* check vnc redist flag for bgp direct routes */ -  if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) -    { -      vnc_zlog_debug_verbose -        ("%s: bgp->rfapi_cfg->redist[afi=%d][type=%d=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping", -         __func__, afi, ZEBRA_ROUTE_BGP_DIRECT); -      return; -    } - -  switch (bgp->rfapi_cfg->redist_mode) -    { -    case VNC_REDIST_MODE_PLAIN: -      vnc_import_bgp_add_route_mode_plain (bgp, prefix, info); -      break; - -    case VNC_REDIST_MODE_RFG: -      if (bgp->rfapi_cfg->rfg_redist) -        vnc_import_bgp_add_route_mode_nvegroup (bgp, prefix, info, -                                                bgp->rfapi_cfg->rfg_redist); -      else -        vnc_zlog_debug_verbose ("%s: mode RFG but no redist RFG", __func__); -      break; - -    case VNC_REDIST_MODE_RESOLVE_NVE: -      vnc_import_bgp_add_route_mode_resolve_nve (bgp, prefix, info); -      break; -    } +	VNC_RHNCK(enter); + +	if (!afi) { +		zlog_err("%s: can't get afi of prefix", __func__); +		return; +	} + +	if (!bgp->rfapi_cfg) { +		vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", +				       __func__); +		return; +	} + +	/* check vnc redist flag for bgp direct routes */ +	if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) { +		vnc_zlog_debug_verbose( +			"%s: bgp->rfapi_cfg->redist[afi=%d][type=%d=ZEBRA_ROUTE_BGP_DIRECT] is 0, skipping", +			__func__, afi, ZEBRA_ROUTE_BGP_DIRECT); +		return; +	} + +	switch (bgp->rfapi_cfg->redist_mode) { +	case VNC_REDIST_MODE_PLAIN: +		vnc_import_bgp_add_route_mode_plain(bgp, prefix, info); +		break; + +	case VNC_REDIST_MODE_RFG: +		if (bgp->rfapi_cfg->rfg_redist) +			vnc_import_bgp_add_route_mode_nvegroup( +				bgp, prefix, info, bgp->rfapi_cfg->rfg_redist); +		else +			vnc_zlog_debug_verbose("%s: mode RFG but no redist RFG", +					       __func__); +		break; + +	case VNC_REDIST_MODE_RESOLVE_NVE: +		vnc_import_bgp_add_route_mode_resolve_nve(bgp, prefix, info); +		break; +	}  #if DEBUG_RHN_LIST -  print_rhn_list(__func__, "LEAVE "); +	print_rhn_list(__func__, "LEAVE ");  #endif -  VNC_RHNCK (leave); +	VNC_RHNCK(leave);  }  /*   * "Withdrawing a Route" import process   */ -void -vnc_import_bgp_del_route ( -    struct bgp		*bgp, -    struct prefix	*prefix, -    struct bgp_info	*info)	/* unicast info */ +void vnc_import_bgp_del_route(struct bgp *bgp, struct prefix *prefix, +			      struct bgp_info *info) /* unicast info */  { -  afi_t afi = family2afi (prefix->family); +	afi_t afi = family2afi(prefix->family); -  assert (afi); +	assert(afi); -  { -    struct prefix pfx_nexthop; -    char buf[BUFSIZ]; -    char buf_nh[BUFSIZ]; +	{ +		struct prefix pfx_nexthop; +		char buf[BUFSIZ]; +		char buf_nh[BUFSIZ]; -    prefix2str (prefix, buf, BUFSIZ); -    rfapiUnicastNexthop2Prefix (afi, info->attr, &pfx_nexthop); -    prefix2str (&pfx_nexthop, buf_nh, BUFSIZ); +		prefix2str(prefix, buf, BUFSIZ); +		rfapiUnicastNexthop2Prefix(afi, info->attr, &pfx_nexthop); +		prefix2str(&pfx_nexthop, buf_nh, BUFSIZ); -    vnc_zlog_debug_verbose ("%s: pfx %s, nh %s", __func__, buf, buf_nh); -  } +		vnc_zlog_debug_verbose("%s: pfx %s, nh %s", __func__, buf, +				       buf_nh); +	}  #if DEBUG_RHN_LIST -  print_rhn_list(__func__, "ENTER "); +	print_rhn_list(__func__, "ENTER ");  #endif -  VNC_RHNCK (enter); - -  if (!bgp->rfapi_cfg) -    { -      vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); -      return; -    } - -  /* check bgp redist flag for vnc direct ("vpn") routes */ -  if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) -    { -      vnc_zlog_debug_verbose ("%s: bgp redistribution of afi=%d VNC direct routes is off", -                              __func__, afi); -      return; -    } - -  switch (bgp->rfapi_cfg->redist_mode) -    { -    case VNC_REDIST_MODE_PLAIN: -      vnc_import_bgp_del_route_mode_plain (bgp, prefix, info); -      break; - -    case VNC_REDIST_MODE_RFG: -      if (bgp->rfapi_cfg->rfg_redist) -        vnc_import_bgp_del_route_mode_nvegroup (bgp, prefix, info); -      else -        vnc_zlog_debug_verbose ("%s: mode RFG but no redist RFG", __func__); -      break; - -    case VNC_REDIST_MODE_RESOLVE_NVE: -      vnc_import_bgp_del_route_mode_resolve_nve (bgp, afi, prefix, info); -      break; - -    } +	VNC_RHNCK(enter); + +	if (!bgp->rfapi_cfg) { +		vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", +				       __func__); +		return; +	} + +	/* check bgp redist flag for vnc direct ("vpn") routes */ +	if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) { +		vnc_zlog_debug_verbose( +			"%s: bgp redistribution of afi=%d VNC direct routes is off", +			__func__, afi); +		return; +	} + +	switch (bgp->rfapi_cfg->redist_mode) { +	case VNC_REDIST_MODE_PLAIN: +		vnc_import_bgp_del_route_mode_plain(bgp, prefix, info); +		break; + +	case VNC_REDIST_MODE_RFG: +		if (bgp->rfapi_cfg->rfg_redist) +			vnc_import_bgp_del_route_mode_nvegroup(bgp, prefix, +							       info); +		else +			vnc_zlog_debug_verbose("%s: mode RFG but no redist RFG", +					       __func__); +		break; + +	case VNC_REDIST_MODE_RESOLVE_NVE: +		vnc_import_bgp_del_route_mode_resolve_nve(bgp, afi, prefix, +							  info); +		break; +	}  #if DEBUG_RHN_LIST -  print_rhn_list(__func__, "LEAVE "); +	print_rhn_list(__func__, "LEAVE ");  #endif -  VNC_RHNCK (leave); +	VNC_RHNCK(leave);  } @@ -2901,257 +2768,257 @@ vnc_import_bgp_del_route (   *			Enable/Disable   ***********************************************************************/ -void -vnc_import_bgp_redist_enable (struct bgp *bgp, afi_t afi) +void vnc_import_bgp_redist_enable(struct bgp *bgp, afi_t afi)  { -  /* iterate over bgp unicast v4 and v6 routes, call vnc_import_bgp_add_route */ +	/* iterate over bgp unicast v4 and v6 routes, call +	 * vnc_import_bgp_add_route */ -  struct bgp_node *rn; +	struct bgp_node *rn; -  vnc_zlog_debug_verbose ("%s: entry, afi=%d", __func__, afi); +	vnc_zlog_debug_verbose("%s: entry, afi=%d", __func__, afi); -  if (bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) -    { -      vnc_zlog_debug_verbose ("%s: already enabled for afi %d, skipping", __func__, afi); -      return; -    } -  bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT] = 1; +	if (bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) { +		vnc_zlog_debug_verbose( +			"%s: already enabled for afi %d, skipping", __func__, +			afi); +		return; +	} +	bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT] = 1; -  for (rn = bgp_table_top (bgp->rib[afi][SAFI_UNICAST]); -       rn; rn = bgp_route_next (rn)) -    { +	for (rn = bgp_table_top(bgp->rib[afi][SAFI_UNICAST]); rn; +	     rn = bgp_route_next(rn)) { -      struct bgp_info *bi; +		struct bgp_info *bi; -      for (bi = rn->info; bi; bi = bi->next) -        { +		for (bi = rn->info; bi; bi = bi->next) { -          if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) -            continue; +			if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) +				continue; -          vnc_import_bgp_add_route (bgp, &rn->p, bi); -        } -    } -  vnc_zlog_debug_verbose ("%s: set redist[afi=%d][type=%d=ZEBRA_ROUTE_BGP_DIRECT] return", -              __func__, afi, ZEBRA_ROUTE_BGP_DIRECT); +			vnc_import_bgp_add_route(bgp, &rn->p, bi); +		} +	} +	vnc_zlog_debug_verbose( +		"%s: set redist[afi=%d][type=%d=ZEBRA_ROUTE_BGP_DIRECT] return", +		__func__, afi, ZEBRA_ROUTE_BGP_DIRECT);  } -void -vnc_import_bgp_exterior_redist_enable (struct bgp *bgp, afi_t afi) +void vnc_import_bgp_exterior_redist_enable(struct bgp *bgp, afi_t afi)  { -  struct bgp *bgp_exterior; -  struct bgp_node *rn; - -  bgp_exterior = bgp->rfapi_cfg->redist_bgp_exterior_view; +	struct bgp *bgp_exterior; +	struct bgp_node *rn; -  if (bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT]) -    { -      vnc_zlog_debug_verbose ("%s: already enabled for afi %d, skipping", __func__, afi); -      return; -    } -  bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT] = 1; +	bgp_exterior = bgp->rfapi_cfg->redist_bgp_exterior_view; -  if (!bgp_exterior) -    { -      vnc_zlog_debug_verbose ("%s: no exterior view set yet, no routes to import yet", -                  __func__); -      return; -    } +	if (bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT]) { +		vnc_zlog_debug_verbose( +			"%s: already enabled for afi %d, skipping", __func__, +			afi); +		return; +	} +	bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT] = 1; -  for (rn = bgp_table_top (bgp_exterior->rib[afi][SAFI_UNICAST]); -       rn; rn = bgp_route_next (rn)) -    { +	if (!bgp_exterior) { +		vnc_zlog_debug_verbose( +			"%s: no exterior view set yet, no routes to import yet", +			__func__); +		return; +	} -      struct bgp_info *bi; +	for (rn = bgp_table_top(bgp_exterior->rib[afi][SAFI_UNICAST]); rn; +	     rn = bgp_route_next(rn)) { -      for (bi = rn->info; bi; bi = bi->next) -        { +		struct bgp_info *bi; -          if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) -            continue; +		for (bi = rn->info; bi; bi = bi->next) { -          vnc_import_bgp_exterior_add_route (bgp_exterior, &rn->p, bi); -        } -    } -  vnc_zlog_debug_verbose ("%s: set redist[afi=%d][type=%d=ZEBRA_ROUTE_BGP_DIRECT] return", -              __func__, afi, ZEBRA_ROUTE_BGP_DIRECT); +			if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) +				continue; +			vnc_import_bgp_exterior_add_route(bgp_exterior, &rn->p, +							  bi); +		} +	} +	vnc_zlog_debug_verbose( +		"%s: set redist[afi=%d][type=%d=ZEBRA_ROUTE_BGP_DIRECT] return", +		__func__, afi, ZEBRA_ROUTE_BGP_DIRECT);  }  /*   * This function is for populating a newly-created Import Table   */ -void -vnc_import_bgp_exterior_redist_enable_it ( -    struct bgp			*bgp, -    afi_t			afi, -    struct rfapi_import_table	*it_only) +void vnc_import_bgp_exterior_redist_enable_it( +	struct bgp *bgp, afi_t afi, struct rfapi_import_table *it_only)  { -  struct bgp *bgp_exterior; -  struct bgp_node *rn; +	struct bgp *bgp_exterior; +	struct bgp_node *rn; -  vnc_zlog_debug_verbose ("%s: entry", __func__); +	vnc_zlog_debug_verbose("%s: entry", __func__); -  bgp_exterior = bgp->rfapi_cfg->redist_bgp_exterior_view; +	bgp_exterior = bgp->rfapi_cfg->redist_bgp_exterior_view; -  if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT]) -    { -      vnc_zlog_debug_verbose ("%s: not enabled for afi %d, skipping", __func__, afi); -      return; -    } - -  if (!bgp_exterior) -    { -      vnc_zlog_debug_verbose ("%s: no exterior view set yet, no routes to import yet", -                  __func__); -      return; -    } +	if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT]) { +		vnc_zlog_debug_verbose("%s: not enabled for afi %d, skipping", +				       __func__, afi); +		return; +	} -  for (rn = bgp_table_top (bgp_exterior->rib[afi][SAFI_UNICAST]); -       rn; rn = bgp_route_next (rn)) -    { +	if (!bgp_exterior) { +		vnc_zlog_debug_verbose( +			"%s: no exterior view set yet, no routes to import yet", +			__func__); +		return; +	} -      struct bgp_info *bi; +	for (rn = bgp_table_top(bgp_exterior->rib[afi][SAFI_UNICAST]); rn; +	     rn = bgp_route_next(rn)) { -      for (bi = rn->info; bi; bi = bi->next) -        { +		struct bgp_info *bi; -          if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) -            continue; +		for (bi = rn->info; bi; bi = bi->next) { -          vnc_import_bgp_exterior_add_route_it (bgp_exterior, &rn->p, bi, -                                                it_only); -        } -    } +			if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) +				continue; +			vnc_import_bgp_exterior_add_route_it( +				bgp_exterior, &rn->p, bi, it_only); +		} +	}  } -void -vnc_import_bgp_redist_disable (struct bgp *bgp, afi_t afi) +void vnc_import_bgp_redist_disable(struct bgp *bgp, afi_t afi)  { -  /* -   * iterate over vpn routes, find routes of type ZEBRA_ROUTE_BGP_DIRECT, -   * delete (call timer expire immediately) -   */ -  struct bgp_node *rn1; -  struct bgp_node *rn2; - -  vnc_zlog_debug_verbose ("%s: entry", __func__); - -  if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) -    { -      vnc_zlog_debug_verbose ("%s: already disabled for afi %d, skipping", __func__, afi); -      return; -    } - -  /* -   * Two-level table for SAFI_MPLS_VPN -   * Be careful when changing the things we iterate over -   */ -  for (rn1 = bgp_table_top (bgp->rib[afi][SAFI_MPLS_VPN]); -       rn1; rn1 = bgp_route_next (rn1)) -    { - -      if (rn1->info) -        { -          for (rn2 = bgp_table_top (rn1->info); -               rn2; rn2 = bgp_route_next (rn2)) -            { - -              struct bgp_info *bi; -              struct bgp_info *nextbi; - -              for (bi = rn2->info; bi; bi = nextbi) -                { - -                  nextbi = bi->next; - -                  if (bi->type == ZEBRA_ROUTE_BGP_DIRECT) -                    { - -                      struct rfapi_descriptor *rfd; -                      vncHDBgpDirect.peer = bi->peer; - -                      rfd = bi->extra->vnc.export.rfapi_handle; - -                      vnc_zlog_debug_verbose -                        ("%s: deleting bi=%p, bi->peer=%p, bi->type=%d, bi->sub_type=%d, bi->extra->vnc.export.rfapi_handle=%p [passing rfd=%p]", -                         __func__, bi, bi->peer, bi->type, bi->sub_type, -                         (bi->extra ? bi->extra->vnc. -                          export.rfapi_handle : NULL), rfd); - - -                      del_vnc_route (rfd, bi->peer, bgp, SAFI_MPLS_VPN, &rn2->p, (struct prefix_rd *) &rn1->p, bi->type, bi->sub_type, NULL, 1);        /* kill */ - -                      vncHDBgpDirect.peer = NULL; -                    } -                } -            } -        } -    } -  /* Clear RHN list */ -  if (bgp->rfapi->resolve_nve_nexthop) -    { -      struct prefix_bag *pb; -      struct bgp_info *info; -      while (!skiplist_first -             (bgp->rfapi->resolve_nve_nexthop, NULL, (void *) &pb)) -        { -          info = pb->ubi; -          skiplist_delete_first (bgp->rfapi->resolve_nve_nexthop); -          bgp_info_unlock (info); -        } -    } - -  bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT] = 0; -  vnc_zlog_debug_verbose ("%s: return", __func__); +	/* +	 * iterate over vpn routes, find routes of type ZEBRA_ROUTE_BGP_DIRECT, +	 * delete (call timer expire immediately) +	 */ +	struct bgp_node *rn1; +	struct bgp_node *rn2; + +	vnc_zlog_debug_verbose("%s: entry", __func__); + +	if (!bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT]) { +		vnc_zlog_debug_verbose( +			"%s: already disabled for afi %d, skipping", __func__, +			afi); +		return; +	} + +	/* +	 * Two-level table for SAFI_MPLS_VPN +	 * Be careful when changing the things we iterate over +	 */ +	for (rn1 = bgp_table_top(bgp->rib[afi][SAFI_MPLS_VPN]); rn1; +	     rn1 = bgp_route_next(rn1)) { + +		if (rn1->info) { +			for (rn2 = bgp_table_top(rn1->info); rn2; +			     rn2 = bgp_route_next(rn2)) { + +				struct bgp_info *bi; +				struct bgp_info *nextbi; + +				for (bi = rn2->info; bi; bi = nextbi) { + +					nextbi = bi->next; + +					if (bi->type +					    == ZEBRA_ROUTE_BGP_DIRECT) { + +						struct rfapi_descriptor *rfd; +						vncHDBgpDirect.peer = bi->peer; + +						rfd = bi->extra->vnc.export +							      .rfapi_handle; + +						vnc_zlog_debug_verbose( +							"%s: deleting bi=%p, bi->peer=%p, bi->type=%d, bi->sub_type=%d, bi->extra->vnc.export.rfapi_handle=%p [passing rfd=%p]", +							__func__, bi, bi->peer, +							bi->type, bi->sub_type, +							(bi->extra +								 ? bi->extra +									   ->vnc +									   .export +									   .rfapi_handle +								 : NULL), +							rfd); + + +						del_vnc_route( +							rfd, bi->peer, bgp, +							SAFI_MPLS_VPN, &rn2->p, +							(struct prefix_rd *)&rn1 +								->p, +							bi->type, bi->sub_type, +							NULL, 1); /* kill */ + +						vncHDBgpDirect.peer = NULL; +					} +				} +			} +		} +	} +	/* Clear RHN list */ +	if (bgp->rfapi->resolve_nve_nexthop) { +		struct prefix_bag *pb; +		struct bgp_info *info; +		while (!skiplist_first(bgp->rfapi->resolve_nve_nexthop, NULL, +				       (void *)&pb)) { +			info = pb->ubi; +			skiplist_delete_first(bgp->rfapi->resolve_nve_nexthop); +			bgp_info_unlock(info); +		} +	} + +	bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT] = 0; +	vnc_zlog_debug_verbose("%s: return", __func__);  } -void -vnc_import_bgp_exterior_redist_disable (struct bgp *bgp, afi_t afi) +void vnc_import_bgp_exterior_redist_disable(struct bgp *bgp, afi_t afi)  { -  struct rfapi_cfg *hc = bgp->rfapi_cfg; -  struct bgp *bgp_exterior = hc->redist_bgp_exterior_view; +	struct rfapi_cfg *hc = bgp->rfapi_cfg; +	struct bgp *bgp_exterior = hc->redist_bgp_exterior_view; -  vnc_zlog_debug_verbose ("%s: entry", __func__); +	vnc_zlog_debug_verbose("%s: entry", __func__); -  if (!hc->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT]) -    { -      vnc_zlog_debug_verbose ("%s: already disabled for afi %d, skipping", __func__, afi); -      return; -    } +	if (!hc->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT]) { +		vnc_zlog_debug_verbose( +			"%s: already disabled for afi %d, skipping", __func__, +			afi); +		return; +	} -  if (!bgp_exterior) -    { -      vnc_zlog_debug_verbose ("%s: bgp exterior view not defined, skipping", __func__); -      return; -    } +	if (!bgp_exterior) { +		vnc_zlog_debug_verbose( +			"%s: bgp exterior view not defined, skipping", +			__func__); +		return; +	} -  { -    struct bgp_node *rn; -    for (rn = bgp_table_top (bgp_exterior->rib[afi][SAFI_UNICAST]); -         rn; rn = bgp_route_next (rn)) -      { +	{ +		struct bgp_node *rn; +		for (rn = bgp_table_top(bgp_exterior->rib[afi][SAFI_UNICAST]); +		     rn; rn = bgp_route_next(rn)) { -        struct bgp_info *bi; +			struct bgp_info *bi; -        for (bi = rn->info; bi; bi = bi->next) -          { +			for (bi = rn->info; bi; bi = bi->next) { -            if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED)) -              continue; +				if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) +					continue; -            vnc_import_bgp_exterior_del_route (bgp_exterior, &rn->p, bi); -          } -      } +				vnc_import_bgp_exterior_del_route(bgp_exterior, +								  &rn->p, bi); +			} +		}  #if DEBUG_RHN_LIST -    print_rhn_list (__func__, NULL); +		print_rhn_list(__func__, NULL);  #endif -  } +	} -  bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT] = 0; -  vnc_zlog_debug_verbose ("%s: return", __func__); +	bgp->rfapi_cfg->redist[afi][ZEBRA_ROUTE_BGP_DIRECT_EXT] = 0; +	vnc_zlog_debug_verbose("%s: return", __func__);  } diff --git a/bgpd/rfapi/vnc_import_bgp.h b/bgpd/rfapi/vnc_import_bgp.h index 9a7261067a..7c15939904 100644 --- a/bgpd/rfapi/vnc_import_bgp.h +++ b/bgpd/rfapi/vnc_import_bgp.h @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2009-2016, LabN Consulting, L.L.C.   * @@ -27,66 +27,48 @@  #include "bgpd/bgpd.h"  #include "bgpd/bgp_route.h" -#define VALID_INTERIOR_TYPE(type)	\ -    (((type) == ZEBRA_ROUTE_BGP) || ((type) == ZEBRA_ROUTE_BGP_DIRECT)) +#define VALID_INTERIOR_TYPE(type)                                              \ +	(((type) == ZEBRA_ROUTE_BGP) || ((type) == ZEBRA_ROUTE_BGP_DIRECT)) -extern uint32_t -calc_local_pref (struct attr *attr, struct peer *peer); +extern uint32_t calc_local_pref(struct attr *attr, struct peer *peer); -extern int -vnc_prefix_cmp (void *pfx1, void *pfx2); +extern int vnc_prefix_cmp(void *pfx1, void *pfx2); -extern void -vnc_import_bgp_add_route ( -    struct bgp		*bgp, -    struct prefix	*prefix, -    struct bgp_info	*info); +extern void vnc_import_bgp_add_route(struct bgp *bgp, struct prefix *prefix, +				     struct bgp_info *info); -extern void -vnc_import_bgp_del_route ( -    struct bgp		*bgp, -    struct prefix	*prefix, -    struct bgp_info	*info); +extern void vnc_import_bgp_del_route(struct bgp *bgp, struct prefix *prefix, +				     struct bgp_info *info); -extern void -vnc_import_bgp_redist_enable (struct bgp *bgp, afi_t afi); +extern void vnc_import_bgp_redist_enable(struct bgp *bgp, afi_t afi); -extern void -vnc_import_bgp_redist_disable (struct bgp *bgp, afi_t afi); +extern void vnc_import_bgp_redist_disable(struct bgp *bgp, afi_t afi); -extern void -vnc_import_bgp_exterior_redist_enable (struct bgp *bgp, afi_t afi); +extern void vnc_import_bgp_exterior_redist_enable(struct bgp *bgp, afi_t afi); -extern void -vnc_import_bgp_exterior_redist_disable (struct bgp *bgp, afi_t afi); +extern void vnc_import_bgp_exterior_redist_disable(struct bgp *bgp, afi_t afi); -extern void -vnc_import_bgp_exterior_add_route ( -    struct bgp		*bgp,	/* exterior instance, we hope */ -    struct prefix	*prefix,/* unicast prefix */ -    struct bgp_info	*info);	/* unicast info */ - -extern void -vnc_import_bgp_exterior_del_route ( -    struct bgp		*bgp, -    struct prefix	*prefix,/* unicast prefix */ -    struct bgp_info	*info);	/* unicast info */ - -extern void -vnc_import_bgp_add_vnc_host_route_mode_resolve_nve ( -    struct bgp		*bgp, -    struct prefix_rd	*prd,		/* RD */ -    struct bgp_table	*table_rd,	/* per-rd VPN route table */ -    struct prefix	*prefix,	/* VPN prefix */ -    struct bgp_info	*bi);		/* new VPN host route */ +extern void vnc_import_bgp_exterior_add_route( +	struct bgp *bgp,	/* exterior instance, we hope */ +	struct prefix *prefix,  /* unicast prefix */ +	struct bgp_info *info); /* unicast info */  extern void -vnc_import_bgp_del_vnc_host_route_mode_resolve_nve ( -    struct bgp		*bgp, -    struct prefix_rd	*prd,		/* RD */ -    struct bgp_table	*table_rd,	/* per-rd VPN route table */ -    struct prefix	*prefix,	/* VPN prefix */ -    struct bgp_info	*bi);		/* old VPN host route */ +vnc_import_bgp_exterior_del_route(struct bgp *bgp, +				  struct prefix *prefix,  /* unicast prefix */ +				  struct bgp_info *info); /* unicast info */ + +extern void vnc_import_bgp_add_vnc_host_route_mode_resolve_nve( +	struct bgp *bgp, struct prefix_rd *prd, /* RD */ +	struct bgp_table *table_rd,		/* per-rd VPN route table */ +	struct prefix *prefix,			/* VPN prefix */ +	struct bgp_info *bi);			/* new VPN host route */ + +extern void vnc_import_bgp_del_vnc_host_route_mode_resolve_nve( +	struct bgp *bgp, struct prefix_rd *prd, /* RD */ +	struct bgp_table *table_rd,		/* per-rd VPN route table */ +	struct prefix *prefix,			/* VPN prefix */ +	struct bgp_info *bi);			/* old VPN host route */  #endif /* _QUAGGA_RFAPI_VNC_IMPORT_BGP_H_ */ diff --git a/bgpd/rfapi/vnc_import_bgp_p.h b/bgpd/rfapi/vnc_import_bgp_p.h index 19bcd19253..b38fa2276a 100644 --- a/bgpd/rfapi/vnc_import_bgp_p.h +++ b/bgpd/rfapi/vnc_import_bgp_p.h @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2009-2016, LabN Consulting, L.L.C.   * @@ -27,24 +27,18 @@  #include "bgpd/bgpd.h"  #include "bgpd/bgp_route.h" -extern void -vnc_import_bgp_exterior_add_route_interior ( -    struct bgp			*bgp, -    struct rfapi_import_table	*it, -    struct route_node		*rn_interior,	/* VPN IT node */ -    struct bgp_info		*bi_interior);	/* VPN IT route */ +extern void vnc_import_bgp_exterior_add_route_interior( +	struct bgp *bgp, struct rfapi_import_table *it, +	struct route_node *rn_interior, /* VPN IT node */ +	struct bgp_info *bi_interior);  /* VPN IT route */ -extern void -vnc_import_bgp_exterior_del_route_interior ( -    struct bgp			*bgp, -    struct rfapi_import_table	*it, -    struct route_node		*rn_interior, /* VPN IT node */ -    struct bgp_info		*bi_interior);  /* VPN IT route */ +extern void vnc_import_bgp_exterior_del_route_interior( +	struct bgp *bgp, struct rfapi_import_table *it, +	struct route_node *rn_interior, /* VPN IT node */ +	struct bgp_info *bi_interior);  /* VPN IT route */  extern void -vnc_import_bgp_exterior_redist_enable_it ( -    struct bgp			*bgp, -    afi_t			afi, -    struct rfapi_import_table	*it_only); +vnc_import_bgp_exterior_redist_enable_it(struct bgp *bgp, afi_t afi, +					 struct rfapi_import_table *it_only);  #endif /* _QUAGGA_RFAPI_VNC_IMPORT_BGP_P_H_ */ diff --git a/bgpd/rfapi/vnc_zebra.c b/bgpd/rfapi/vnc_zebra.c index de1249ff2c..3075d4109f 100644 --- a/bgpd/rfapi/vnc_zebra.c +++ b/bgpd/rfapi/vnc_zebra.c @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2009-2016, LabN Consulting, L.L.C.   * @@ -47,7 +47,7 @@  #include "bgpd/rfapi/rfapi_backend.h"  #include "bgpd/rfapi/vnc_debug.h" -static struct rfapi_descriptor vncHD1VR;        /* Single-VR export dummy nve descr */ +static struct rfapi_descriptor vncHD1VR; /* Single-VR export dummy nve descr */  static struct zclient *zclient_vnc = NULL;  /*********************************************************************** @@ -57,281 +57,271 @@ static struct zclient *zclient_vnc = NULL;  /*   * Routes coming from zebra get added to VNC here   */ -static void -vnc_redistribute_add ( -    struct prefix	*p, -    struct in_addr	*nexthop, -    u_int32_t		metric, -    uint8_t		type) +static void vnc_redistribute_add(struct prefix *p, struct in_addr *nexthop, +				 u_int32_t metric, uint8_t type)  { -  struct bgp *bgp = bgp_get_default (); -  struct prefix_rd prd; -  struct rfapi_ip_addr vnaddr; -  afi_t afi; -  uint32_t local_pref = rfp_cost_to_localpref (metric > 255 ? 255 : metric); - -  if (!bgp) -    return; - -  if (!bgp->rfapi_cfg) -    { -      vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); -      return; -    } - -  afi = family2afi (p->family); -  if (!afi) -    { -      vnc_zlog_debug_verbose ("%s: unknown prefix address family %d", __func__, -                  p->family); -      return; -    } - -  if (!bgp->rfapi_cfg->redist[afi][type]) -    { -      vnc_zlog_debug_verbose -        ("%s: bgp->rfapi_cfg->redist[afi=%d][type=%d] is 0, skipping", -         __func__, afi, type); -      return; -    } -  if (!bgp->rfapi_cfg->rfg_redist) -    { -      vnc_zlog_debug_verbose ("%s: no redist nve group, skipping", __func__); -      return; -    } - -  /* -   * Assume nve group's configured VN address prefix is a host -   * route which also happens to give the NVE VN address to use -   * for redistributing into VNC. -   */ -  vnaddr.addr_family = bgp->rfapi_cfg->rfg_redist->vn_prefix.family; -  switch (bgp->rfapi_cfg->rfg_redist->vn_prefix.family) -    { -    case AF_INET: -      if (bgp->rfapi_cfg->rfg_redist->vn_prefix.prefixlen != 32) -        { -          vnc_zlog_debug_verbose -            ("%s: redist nve group VN prefix len (%d) != 32, skipping", -             __func__, bgp->rfapi_cfg->rfg_redist->vn_prefix.prefixlen); -          return; -        } -      vnaddr.addr.v4 = bgp->rfapi_cfg->rfg_redist->vn_prefix.u.prefix4; -      break; -    case AF_INET6: -      if (bgp->rfapi_cfg->rfg_redist->vn_prefix.prefixlen != 128) -        { -          vnc_zlog_debug_verbose -            ("%s: redist nve group VN prefix len (%d) != 128, skipping", -             __func__, bgp->rfapi_cfg->rfg_redist->vn_prefix.prefixlen); -          return; -        } -      vnaddr.addr.v6 = bgp->rfapi_cfg->rfg_redist->vn_prefix.u.prefix6; -      break; -    default: -      vnc_zlog_debug_verbose -        ("%s: no redist nve group VN host prefix configured, skipping", -         __func__); -      return; -    } - -  /* -   * Assume nve group's configured UN address prefix is a host -   * route which also happens to give the NVE UN address to use -   * for redistributing into VNC. -   */ - -  /* -   * Set UN address in dummy nve descriptor so add_vnc_route -   * can use it in VNC tunnel SubTLV -   */ -  { -    struct rfapi_ip_prefix pfx_un; - -    rfapiQprefix2Rprefix (&bgp->rfapi_cfg->rfg_redist->un_prefix, &pfx_un); - -    switch (pfx_un.prefix.addr_family) -      { -      case AF_INET: -        if (pfx_un.length != 32) -          { -            vnc_zlog_debug_verbose -              ("%s: redist nve group UN prefix len (%d) != 32, skipping", -               __func__, pfx_un.length); -            return; -          } -        break; -      case AF_INET6: -        if (pfx_un.length != 128) -          { -            vnc_zlog_debug_verbose -              ("%s: redist nve group UN prefix len (%d) != 128, skipping", -               __func__, pfx_un.length); -            return; -          } -        break; -      default: -        vnc_zlog_debug_verbose -          ("%s: no redist nve group UN host prefix configured, skipping", -           __func__); -        return; -      } - -    vncHD1VR.un_addr = pfx_un.prefix; - -    if (!vncHD1VR.peer) -      { -        /* -         * Same setup as in rfapi_open() -         */ -        vncHD1VR.peer = peer_new (bgp); -        vncHD1VR.peer->status = Established;    /* keep bgp core happy */ -        bgp_sync_delete (vncHD1VR.peer);        /* don't need these */ -        if (vncHD1VR.peer->ibuf) -          { -            stream_free (vncHD1VR.peer->ibuf);  /* don't need it */ -            vncHD1VR.peer->ibuf = NULL; -          } -        if (vncHD1VR.peer->obuf) -          { -            stream_fifo_free (vncHD1VR.peer->obuf);     /* don't need it */ -            vncHD1VR.peer->obuf = NULL; -          } -        if (vncHD1VR.peer->work) -          { -            stream_free (vncHD1VR.peer->work);  /* don't need it */ -            vncHD1VR.peer->work = NULL; -          } -        /* base code assumes have valid host pointer */ -        vncHD1VR.peer->host = XSTRDUP (MTYPE_BGP_PEER_HOST, ".zebra."); - -        /* Mark peer as belonging to HD */ -        SET_FLAG (vncHD1VR.peer->flags, PEER_FLAG_IS_RFAPI_HD); -      } -  } - -  memset (&prd, 0, sizeof (prd)); -  prd = bgp->rfapi_cfg->rfg_redist->rd; -  prd.family = AF_UNSPEC; -  prd.prefixlen = 64; - -  add_vnc_route (&vncHD1VR,     /* cookie + UN addr */ -                 bgp, SAFI_MPLS_VPN, p, &prd, &vnaddr, &local_pref, &(bgp->rfapi_cfg->redist_lifetime), NULL,   /* RFP options */ -                 NULL,          /* struct rfapi_un_option */ -                 NULL,          /* struct rfapi_vn_option */ -                 bgp->rfapi_cfg->rfg_redist->rt_export_list, NULL, NULL,        /* label: default */ -                 type, BGP_ROUTE_REDISTRIBUTE, 0);      /* flags */ +	struct bgp *bgp = bgp_get_default(); +	struct prefix_rd prd; +	struct rfapi_ip_addr vnaddr; +	afi_t afi; +	uint32_t local_pref = +		rfp_cost_to_localpref(metric > 255 ? 255 : metric); + +	if (!bgp) +		return; + +	if (!bgp->rfapi_cfg) { +		vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", +				       __func__); +		return; +	} + +	afi = family2afi(p->family); +	if (!afi) { +		vnc_zlog_debug_verbose("%s: unknown prefix address family %d", +				       __func__, p->family); +		return; +	} + +	if (!bgp->rfapi_cfg->redist[afi][type]) { +		vnc_zlog_debug_verbose( +			"%s: bgp->rfapi_cfg->redist[afi=%d][type=%d] is 0, skipping", +			__func__, afi, type); +		return; +	} +	if (!bgp->rfapi_cfg->rfg_redist) { +		vnc_zlog_debug_verbose("%s: no redist nve group, skipping", +				       __func__); +		return; +	} + +	/* +	 * Assume nve group's configured VN address prefix is a host +	 * route which also happens to give the NVE VN address to use +	 * for redistributing into VNC. +	 */ +	vnaddr.addr_family = bgp->rfapi_cfg->rfg_redist->vn_prefix.family; +	switch (bgp->rfapi_cfg->rfg_redist->vn_prefix.family) { +	case AF_INET: +		if (bgp->rfapi_cfg->rfg_redist->vn_prefix.prefixlen != 32) { +			vnc_zlog_debug_verbose( +				"%s: redist nve group VN prefix len (%d) != 32, skipping", +				__func__, +				bgp->rfapi_cfg->rfg_redist->vn_prefix +					.prefixlen); +			return; +		} +		vnaddr.addr.v4 = +			bgp->rfapi_cfg->rfg_redist->vn_prefix.u.prefix4; +		break; +	case AF_INET6: +		if (bgp->rfapi_cfg->rfg_redist->vn_prefix.prefixlen != 128) { +			vnc_zlog_debug_verbose( +				"%s: redist nve group VN prefix len (%d) != 128, skipping", +				__func__, +				bgp->rfapi_cfg->rfg_redist->vn_prefix +					.prefixlen); +			return; +		} +		vnaddr.addr.v6 = +			bgp->rfapi_cfg->rfg_redist->vn_prefix.u.prefix6; +		break; +	default: +		vnc_zlog_debug_verbose( +			"%s: no redist nve group VN host prefix configured, skipping", +			__func__); +		return; +	} + +	/* +	 * Assume nve group's configured UN address prefix is a host +	 * route which also happens to give the NVE UN address to use +	 * for redistributing into VNC. +	 */ + +	/* +	 * Set UN address in dummy nve descriptor so add_vnc_route +	 * can use it in VNC tunnel SubTLV +	 */ +	{ +		struct rfapi_ip_prefix pfx_un; + +		rfapiQprefix2Rprefix(&bgp->rfapi_cfg->rfg_redist->un_prefix, +				     &pfx_un); + +		switch (pfx_un.prefix.addr_family) { +		case AF_INET: +			if (pfx_un.length != 32) { +				vnc_zlog_debug_verbose( +					"%s: redist nve group UN prefix len (%d) != 32, skipping", +					__func__, pfx_un.length); +				return; +			} +			break; +		case AF_INET6: +			if (pfx_un.length != 128) { +				vnc_zlog_debug_verbose( +					"%s: redist nve group UN prefix len (%d) != 128, skipping", +					__func__, pfx_un.length); +				return; +			} +			break; +		default: +			vnc_zlog_debug_verbose( +				"%s: no redist nve group UN host prefix configured, skipping", +				__func__); +			return; +		} + +		vncHD1VR.un_addr = pfx_un.prefix; + +		if (!vncHD1VR.peer) { +			/* +			 * Same setup as in rfapi_open() +			 */ +			vncHD1VR.peer = peer_new(bgp); +			vncHD1VR.peer->status = +				Established; /* keep bgp core happy */ +			bgp_sync_delete(vncHD1VR.peer); /* don't need these */ +			if (vncHD1VR.peer->ibuf) { +				stream_free(vncHD1VR.peer +						    ->ibuf); /* don't need it */ +				vncHD1VR.peer->ibuf = NULL; +			} +			if (vncHD1VR.peer->obuf) { +				stream_fifo_free( +					vncHD1VR.peer +						->obuf); /* don't need it */ +				vncHD1VR.peer->obuf = NULL; +			} +			if (vncHD1VR.peer->work) { +				stream_free(vncHD1VR.peer +						    ->work); /* don't need it */ +				vncHD1VR.peer->work = NULL; +			} +			/* base code assumes have valid host pointer */ +			vncHD1VR.peer->host = +				XSTRDUP(MTYPE_BGP_PEER_HOST, ".zebra."); + +			/* Mark peer as belonging to HD */ +			SET_FLAG(vncHD1VR.peer->flags, PEER_FLAG_IS_RFAPI_HD); +		} +	} + +	memset(&prd, 0, sizeof(prd)); +	prd = bgp->rfapi_cfg->rfg_redist->rd; +	prd.family = AF_UNSPEC; +	prd.prefixlen = 64; + +	add_vnc_route(&vncHD1VR, /* cookie + UN addr */ +		      bgp, SAFI_MPLS_VPN, p, &prd, &vnaddr, &local_pref, +		      &(bgp->rfapi_cfg->redist_lifetime), +		      NULL, /* RFP options */ +		      NULL, /* struct rfapi_un_option */ +		      NULL, /* struct rfapi_vn_option */ +		      bgp->rfapi_cfg->rfg_redist->rt_export_list, NULL, +		      NULL,				/* label: default */ +		      type, BGP_ROUTE_REDISTRIBUTE, 0); /* flags */  }  /*   * Route deletions from zebra propagate to VNC here   */ -static void -vnc_redistribute_delete (struct prefix *p, uint8_t type) +static void vnc_redistribute_delete(struct prefix *p, uint8_t type)  { -  struct bgp *bgp = bgp_get_default (); -  struct prefix_rd prd; -  afi_t afi; - -  if (!bgp) -    return; - -  if (!bgp->rfapi_cfg) -    { -      vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); -      return; -    } -  afi = family2afi (p->family); -  if (!afi) -    { -      vnc_zlog_debug_verbose ("%s: unknown prefix address family %d", __func__, -                  p->family); -      return; -    } -  if (!bgp->rfapi_cfg->redist[afi][type]) -    { -      vnc_zlog_debug_verbose -        ("%s: bgp->rfapi_cfg->redist[afi=%d][type=%d] is 0, skipping", -         __func__, afi, type); -      return; -    } -  if (!bgp->rfapi_cfg->rfg_redist) -    { -      vnc_zlog_debug_verbose ("%s: no redist nve group, skipping", __func__); -      return; -    } - -  memset (&prd, 0, sizeof (prd)); -  prd = bgp->rfapi_cfg->rfg_redist->rd; -  prd.family = AF_UNSPEC; -  prd.prefixlen = 64; - -  del_vnc_route (&vncHD1VR,     /* use dummy ptr as cookie */ -                 vncHD1VR.peer, -                 bgp, -                 SAFI_MPLS_VPN, -                 p, &prd, type, BGP_ROUTE_REDISTRIBUTE, NULL, 0); +	struct bgp *bgp = bgp_get_default(); +	struct prefix_rd prd; +	afi_t afi; + +	if (!bgp) +		return; + +	if (!bgp->rfapi_cfg) { +		vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", +				       __func__); +		return; +	} +	afi = family2afi(p->family); +	if (!afi) { +		vnc_zlog_debug_verbose("%s: unknown prefix address family %d", +				       __func__, p->family); +		return; +	} +	if (!bgp->rfapi_cfg->redist[afi][type]) { +		vnc_zlog_debug_verbose( +			"%s: bgp->rfapi_cfg->redist[afi=%d][type=%d] is 0, skipping", +			__func__, afi, type); +		return; +	} +	if (!bgp->rfapi_cfg->rfg_redist) { +		vnc_zlog_debug_verbose("%s: no redist nve group, skipping", +				       __func__); +		return; +	} + +	memset(&prd, 0, sizeof(prd)); +	prd = bgp->rfapi_cfg->rfg_redist->rd; +	prd.family = AF_UNSPEC; +	prd.prefixlen = 64; + +	del_vnc_route(&vncHD1VR, /* use dummy ptr as cookie */ +		      vncHD1VR.peer, bgp, SAFI_MPLS_VPN, p, &prd, type, +		      BGP_ROUTE_REDISTRIBUTE, NULL, 0);  }  /*   * Flush all redistributed routes of type <type>   */ -static void -vnc_redistribute_withdraw (struct bgp *bgp, afi_t afi, uint8_t type) +static void vnc_redistribute_withdraw(struct bgp *bgp, afi_t afi, uint8_t type)  { -  struct prefix_rd prd; -  struct bgp_table *table; -  struct bgp_node *prn; -  struct bgp_node *rn; - -  vnc_zlog_debug_verbose ("%s: entry", __func__); - -  if (!bgp) -    return; -  if (!bgp->rfapi_cfg) -    { -      vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); -      return; -    } - -  /* -   * Loop over all the RDs -   */ -  for (prn = bgp_table_top (bgp->rib[afi][SAFI_MPLS_VPN]); prn; -       prn = bgp_route_next (prn)) -    { -      memset (&prd, 0, sizeof (prd)); -      prd.family = AF_UNSPEC; -      prd.prefixlen = 64; -      memcpy (prd.val, prn->p.u.val, 8); - -      /* This is the per-RD table of prefixes */ -      table = prn->info; - -      for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn)) -        { - -          struct bgp_info *ri; - -          for (ri = rn->info; ri; ri = ri->next) -            { -              if (ri->type == type) -                {               /* has matching redist type */ -                  break; -                } -            } -          if (ri) -            { -              del_vnc_route (&vncHD1VR, /* use dummy ptr as cookie */ -                             vncHD1VR.peer, -                             bgp, -                             SAFI_MPLS_VPN, -                             &(rn->p), -                             &prd, type, BGP_ROUTE_REDISTRIBUTE, NULL, 0); -            } -        } -    } -  vnc_zlog_debug_verbose ("%s: return", __func__); +	struct prefix_rd prd; +	struct bgp_table *table; +	struct bgp_node *prn; +	struct bgp_node *rn; + +	vnc_zlog_debug_verbose("%s: entry", __func__); + +	if (!bgp) +		return; +	if (!bgp->rfapi_cfg) { +		vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", +				       __func__); +		return; +	} + +	/* +	 * Loop over all the RDs +	 */ +	for (prn = bgp_table_top(bgp->rib[afi][SAFI_MPLS_VPN]); prn; +	     prn = bgp_route_next(prn)) { +		memset(&prd, 0, sizeof(prd)); +		prd.family = AF_UNSPEC; +		prd.prefixlen = 64; +		memcpy(prd.val, prn->p.u.val, 8); + +		/* This is the per-RD table of prefixes */ +		table = prn->info; + +		for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) { + +			struct bgp_info *ri; + +			for (ri = rn->info; ri; ri = ri->next) { +				if (ri->type +				    == type) { /* has matching redist type */ +					break; +				} +			} +			if (ri) { +				del_vnc_route( +					&vncHD1VR, /* use dummy ptr as cookie */ +					vncHD1VR.peer, bgp, SAFI_MPLS_VPN, +					&(rn->p), &prd, type, +					BGP_ROUTE_REDISTRIBUTE, NULL, 0); +			} +		} +	} +	vnc_zlog_debug_verbose("%s: return", __func__);  }  /* @@ -339,177 +329,159 @@ vnc_redistribute_withdraw (struct bgp *bgp, afi_t afi, uint8_t type)   *   * Assumes 1 nexthop   */ -static int -vnc_zebra_read_ipv4 ( -    int			command, -    struct zclient	*zclient, -    zebra_size_t	length, -    vrf_id_t		vrf_id) +static int vnc_zebra_read_ipv4(int command, struct zclient *zclient, +			       zebra_size_t length, vrf_id_t vrf_id)  { -  struct stream *s; -  struct zapi_ipv4 api; -  struct in_addr nexthop; -  struct prefix_ipv4 p; - -  s = zclient->ibuf; -  nexthop.s_addr = 0; - -  /* Type, flags, message. */ -  api.type = stream_getc (s); -  api.flags = stream_getc (s); -  api.message = stream_getc (s); - -  /* IPv4 prefix. */ -  memset (&p, 0, sizeof (struct prefix_ipv4)); -  p.family = AF_INET; -  p.prefixlen = stream_getc (s); -  stream_get (&p.prefix, s, PSIZE (p.prefixlen)); - -  /* Nexthop, ifindex, distance, metric. */ -  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) -    { -      api.nexthop_num = stream_getc (s); -      nexthop.s_addr = stream_get_ipv4 (s); -    } -  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) -    { -      api.ifindex_num = stream_getc (s); -      stream_getl (s); -    } -  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE)) -    api.distance = stream_getc (s); -  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC)) -    api.metric = stream_getl (s); -  else -    api.metric = 0; - -  if (command == ZEBRA_IPV4_ROUTE_ADD) -    { -      if (BGP_DEBUG (zebra, ZEBRA)) -        { -          char buf[2][INET_ADDRSTRLEN]; -          vnc_zlog_debug_verbose -            ("%s: Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u", -             __func__, zebra_route_string (api.type), inet_ntop (AF_INET, -                                                                 &p.prefix, -                                                                 buf[0], -                                                                 sizeof (buf -                                                                         [0])), -             p.prefixlen, inet_ntop (AF_INET, &nexthop, buf[1], -                                     sizeof (buf[1])), api.metric); -        } -      vnc_redistribute_add ((struct prefix *) &p, &nexthop, api.metric, -                            api.type); -    } -  else -    { -      if (BGP_DEBUG (zebra, ZEBRA)) -        { -          char buf[2][INET_ADDRSTRLEN]; -          vnc_zlog_debug_verbose ("%s: Zebra rcvd: IPv4 route delete %s %s/%d " -                      "nexthop %s metric %u", -                      __func__, -                      zebra_route_string (api.type), -                      inet_ntop (AF_INET, &p.prefix, buf[0], sizeof (buf[0])), -                      p.prefixlen, -                      inet_ntop (AF_INET, &nexthop, buf[1], sizeof (buf[1])), -                      api.metric); -        } -      vnc_redistribute_delete ((struct prefix *) &p, api.type); -    } - -  return 0; +	struct stream *s; +	struct zapi_ipv4 api; +	struct in_addr nexthop; +	struct prefix_ipv4 p; + +	s = zclient->ibuf; +	nexthop.s_addr = 0; + +	/* Type, flags, message. */ +	api.type = stream_getc(s); +	api.flags = stream_getc(s); +	api.message = stream_getc(s); + +	/* IPv4 prefix. */ +	memset(&p, 0, sizeof(struct prefix_ipv4)); +	p.family = AF_INET; +	p.prefixlen = stream_getc(s); +	stream_get(&p.prefix, s, PSIZE(p.prefixlen)); + +	/* Nexthop, ifindex, distance, metric. */ +	if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { +		api.nexthop_num = stream_getc(s); +		nexthop.s_addr = stream_get_ipv4(s); +	} +	if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX)) { +		api.ifindex_num = stream_getc(s); +		stream_getl(s); +	} +	if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE)) +		api.distance = stream_getc(s); +	if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC)) +		api.metric = stream_getl(s); +	else +		api.metric = 0; + +	if (command == ZEBRA_IPV4_ROUTE_ADD) { +		if (BGP_DEBUG(zebra, ZEBRA)) { +			char buf[2][INET_ADDRSTRLEN]; +			vnc_zlog_debug_verbose( +				"%s: Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u", +				__func__, zebra_route_string(api.type), +				inet_ntop(AF_INET, &p.prefix, buf[0], +					  sizeof(buf[0])), +				p.prefixlen, inet_ntop(AF_INET, &nexthop, +						       buf[1], sizeof(buf[1])), +				api.metric); +		} +		vnc_redistribute_add((struct prefix *)&p, &nexthop, api.metric, +				     api.type); +	} else { +		if (BGP_DEBUG(zebra, ZEBRA)) { +			char buf[2][INET_ADDRSTRLEN]; +			vnc_zlog_debug_verbose( +				"%s: Zebra rcvd: IPv4 route delete %s %s/%d " +				"nexthop %s metric %u", +				__func__, zebra_route_string(api.type), +				inet_ntop(AF_INET, &p.prefix, buf[0], +					  sizeof(buf[0])), +				p.prefixlen, inet_ntop(AF_INET, &nexthop, +						       buf[1], sizeof(buf[1])), +				api.metric); +		} +		vnc_redistribute_delete((struct prefix *)&p, api.type); +	} + +	return 0;  }  /* Zebra route add and delete treatment. */ -static int -vnc_zebra_read_ipv6 ( -    int			command, -    struct zclient	*zclient, -    zebra_size_t	length, -    vrf_id_t		vrf_id) +static int vnc_zebra_read_ipv6(int command, struct zclient *zclient, +			       zebra_size_t length, vrf_id_t vrf_id)  { -  struct stream *s; -  struct zapi_ipv6 api; -  struct in6_addr nexthop; -  struct prefix_ipv6 p, src_p; - -  s = zclient->ibuf; -  memset (&nexthop, 0, sizeof (struct in6_addr)); - -  /* Type, flags, message. */ -  api.type = stream_getc (s); -  api.flags = stream_getc (s); -  api.message = stream_getc (s); - -  /* IPv6 prefix. */ -  memset (&p, 0, sizeof (struct prefix_ipv6)); -  p.family = AF_INET6; -  p.prefixlen = stream_getc (s); -  stream_get (&p.prefix, s, PSIZE (p.prefixlen)); - -  memset (&src_p, 0, sizeof (struct prefix_ipv6)); -  src_p.family = AF_INET6; -  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_SRCPFX)) -    { -      src_p.prefixlen = stream_getc (s); -      stream_get (&src_p.prefix, s, PSIZE (src_p.prefixlen)); -    } - -  if (src_p.prefixlen) -    /* we completely ignore srcdest routes for now. */ -    return 0; - -  /* Nexthop, ifindex, distance, metric. */ -  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP)) -    { -      api.nexthop_num = stream_getc (s); -      stream_get (&nexthop, s, 16); -    } -  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX)) -    { -      api.ifindex_num = stream_getc (s); -      stream_getl (s); -    } -  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE)) -    api.distance = stream_getc (s); -  else -    api.distance = 0; -  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC)) -    api.metric = stream_getl (s); -  else -    api.metric = 0; - -  /* Simply ignore link-local address. */ -  if (IN6_IS_ADDR_LINKLOCAL (&p.prefix)) -    return 0; - -  if (command == ZEBRA_IPV6_ROUTE_ADD) -    { -      if (BGP_DEBUG (zebra, ZEBRA)) -        { -          char buf[INET6_ADDRSTRLEN]; -          vnc_zlog_debug_verbose ("Zebra rcvd: IPv6 route add %s %s/%d metric %u", -                      zebra_route_string (api.type), -                      inet_ntop (AF_INET6, &p.prefix, buf, sizeof (buf)), -                      p.prefixlen, api.metric); -        } -      vnc_redistribute_add ((struct prefix *) &p, NULL, api.metric, api.type); -    } -  else -    { -      if (BGP_DEBUG (zebra, ZEBRA)) -        { -          char buf[INET6_ADDRSTRLEN]; -          vnc_zlog_debug_verbose ("Zebra rcvd: IPv6 route delete %s %s/%d metric %u", -                      zebra_route_string (api.type), -                      inet_ntop (AF_INET6, &p.prefix, buf, sizeof (buf)), -                      p.prefixlen, api.metric); -        } -      vnc_redistribute_delete ((struct prefix *) &p, api.type); -    } - -  return 0; +	struct stream *s; +	struct zapi_ipv6 api; +	struct in6_addr nexthop; +	struct prefix_ipv6 p, src_p; + +	s = zclient->ibuf; +	memset(&nexthop, 0, sizeof(struct in6_addr)); + +	/* Type, flags, message. */ +	api.type = stream_getc(s); +	api.flags = stream_getc(s); +	api.message = stream_getc(s); + +	/* IPv6 prefix. */ +	memset(&p, 0, sizeof(struct prefix_ipv6)); +	p.family = AF_INET6; +	p.prefixlen = stream_getc(s); +	stream_get(&p.prefix, s, PSIZE(p.prefixlen)); + +	memset(&src_p, 0, sizeof(struct prefix_ipv6)); +	src_p.family = AF_INET6; +	if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) { +		src_p.prefixlen = stream_getc(s); +		stream_get(&src_p.prefix, s, PSIZE(src_p.prefixlen)); +	} + +	if (src_p.prefixlen) +		/* we completely ignore srcdest routes for now. */ +		return 0; + +	/* Nexthop, ifindex, distance, metric. */ +	if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { +		api.nexthop_num = stream_getc(s); +		stream_get(&nexthop, s, 16); +	} +	if (CHECK_FLAG(api.message, ZAPI_MESSAGE_IFINDEX)) { +		api.ifindex_num = stream_getc(s); +		stream_getl(s); +	} +	if (CHECK_FLAG(api.message, ZAPI_MESSAGE_DISTANCE)) +		api.distance = stream_getc(s); +	else +		api.distance = 0; +	if (CHECK_FLAG(api.message, ZAPI_MESSAGE_METRIC)) +		api.metric = stream_getl(s); +	else +		api.metric = 0; + +	/* Simply ignore link-local address. */ +	if (IN6_IS_ADDR_LINKLOCAL(&p.prefix)) +		return 0; + +	if (command == ZEBRA_IPV6_ROUTE_ADD) { +		if (BGP_DEBUG(zebra, ZEBRA)) { +			char buf[INET6_ADDRSTRLEN]; +			vnc_zlog_debug_verbose( +				"Zebra rcvd: IPv6 route add %s %s/%d metric %u", +				zebra_route_string(api.type), +				inet_ntop(AF_INET6, &p.prefix, buf, +					  sizeof(buf)), +				p.prefixlen, api.metric); +		} +		vnc_redistribute_add((struct prefix *)&p, NULL, api.metric, +				     api.type); +	} else { +		if (BGP_DEBUG(zebra, ZEBRA)) { +			char buf[INET6_ADDRSTRLEN]; +			vnc_zlog_debug_verbose( +				"Zebra rcvd: IPv6 route delete %s %s/%d metric %u", +				zebra_route_string(api.type), +				inet_ntop(AF_INET6, &p.prefix, buf, +					  sizeof(buf)), +				p.prefixlen, api.metric); +		} +		vnc_redistribute_delete((struct prefix *)&p, api.type); +	} + +	return 0;  }  /*********************************************************************** @@ -519,509 +491,465 @@ vnc_zebra_read_ipv6 (  /*   * low-level message builder   */ -static void -vnc_zebra_route_msg ( -    struct prefix	*p, -    int			nhp_count, -    void		*nhp_ary, -    int			add)   /* 1 = add, 0 = del */ +static void vnc_zebra_route_msg(struct prefix *p, int nhp_count, void *nhp_ary, +				int add) /* 1 = add, 0 = del */  { -  if (!nhp_count) -    { -      vnc_zlog_debug_verbose ("%s: empty nexthop list, skipping", __func__); -      return; -    } - -  if (p->family == AF_INET) -    { - -      struct zapi_ipv4 api; - -      api.flags = 0; -      api.vrf_id = VRF_DEFAULT; -      api.type = ZEBRA_ROUTE_VNC; -      api.message = 0; -      SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);     /* TBD what's it mean? */ -      api.nexthop_num = nhp_count; -      api.nexthop = nhp_ary; -      api.ifindex_num = 0; -      api.instance = 0; -      api.safi = SAFI_UNICAST; - -      if (BGP_DEBUG (zebra, ZEBRA)) -        { - -          char buf[INET_ADDRSTRLEN]; -          vnc_zlog_debug_verbose ("%s: Zebra send: IPv4 route %s %s/%d, nhp_count=%d", -                      __func__, -                      (add ? "add" : "del"), -                      inet_ntop (AF_INET, &p->u.prefix4, buf, sizeof (buf)), -                      p->prefixlen, nhp_count); -        } - -      zapi_ipv4_route ((add ? ZEBRA_IPV4_NEXTHOP_ADD : -                        ZEBRA_IPV4_NEXTHOP_DELETE), zclient_vnc, -                       (struct prefix_ipv4 *) p, &api); - -    } -  else if (p->family == AF_INET6) -    { - -      struct zapi_ipv6 api; -      ifindex_t ifindex = 0; - -      /* Make Zebra API structure. */ -      api.flags = 0; -      api.vrf_id = VRF_DEFAULT; -      api.type = ZEBRA_ROUTE_VNC; -      api.message = 0; -      SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);     /* TBD means? */ -      api.nexthop_num = nhp_count; -      api.nexthop = nhp_ary; -      SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX); -      api.ifindex_num = 1; -      api.ifindex = &ifindex; -      api.instance = 0; -      api.safi = SAFI_UNICAST; - -      if (BGP_DEBUG (zebra, ZEBRA)) -        { - -          char buf[INET6_ADDRSTRLEN]; -          vnc_zlog_debug_verbose ("%s: Zebra send: IPv6 route %s %s/%d nhp_count=%d", -                      __func__, -                      (add ? "add" : "del"), -                      inet_ntop (AF_INET6, &p->u.prefix6, buf, sizeof (buf)), -                      p->prefixlen, nhp_count); -        } - -      zapi_ipv6_route ((add ? ZEBRA_IPV6_NEXTHOP_ADD : -                        ZEBRA_IPV6_NEXTHOP_DELETE), zclient_vnc, -                       (struct prefix_ipv6 *) p, NULL, &api); -    } -  else -    { -      vnc_zlog_debug_verbose ("%s: unknown prefix address family, skipping", __func__); -      return; -    } +	if (!nhp_count) { +		vnc_zlog_debug_verbose("%s: empty nexthop list, skipping", +				       __func__); +		return; +	} + +	if (p->family == AF_INET) { + +		struct zapi_ipv4 api; + +		api.flags = 0; +		api.vrf_id = VRF_DEFAULT; +		api.type = ZEBRA_ROUTE_VNC; +		api.message = 0; +		SET_FLAG(api.message, +			 ZAPI_MESSAGE_NEXTHOP); /* TBD what's it mean? */ +		api.nexthop_num = nhp_count; +		api.nexthop = nhp_ary; +		api.ifindex_num = 0; +		api.instance = 0; +		api.safi = SAFI_UNICAST; + +		if (BGP_DEBUG(zebra, ZEBRA)) { + +			char buf[INET_ADDRSTRLEN]; +			vnc_zlog_debug_verbose( +				"%s: Zebra send: IPv4 route %s %s/%d, nhp_count=%d", +				__func__, (add ? "add" : "del"), +				inet_ntop(AF_INET, &p->u.prefix4, buf, +					  sizeof(buf)), +				p->prefixlen, nhp_count); +		} + +		zapi_ipv4_route((add ? ZEBRA_IPV4_NEXTHOP_ADD +				     : ZEBRA_IPV4_NEXTHOP_DELETE), +				zclient_vnc, (struct prefix_ipv4 *)p, &api); + +	} else if (p->family == AF_INET6) { + +		struct zapi_ipv6 api; +		ifindex_t ifindex = 0; + +		/* Make Zebra API structure. */ +		api.flags = 0; +		api.vrf_id = VRF_DEFAULT; +		api.type = ZEBRA_ROUTE_VNC; +		api.message = 0; +		SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); /* TBD means? */ +		api.nexthop_num = nhp_count; +		api.nexthop = nhp_ary; +		SET_FLAG(api.message, ZAPI_MESSAGE_IFINDEX); +		api.ifindex_num = 1; +		api.ifindex = &ifindex; +		api.instance = 0; +		api.safi = SAFI_UNICAST; + +		if (BGP_DEBUG(zebra, ZEBRA)) { + +			char buf[INET6_ADDRSTRLEN]; +			vnc_zlog_debug_verbose( +				"%s: Zebra send: IPv6 route %s %s/%d nhp_count=%d", +				__func__, (add ? "add" : "del"), +				inet_ntop(AF_INET6, &p->u.prefix6, buf, +					  sizeof(buf)), +				p->prefixlen, nhp_count); +		} + +		zapi_ipv6_route((add ? ZEBRA_IPV6_NEXTHOP_ADD +				     : ZEBRA_IPV6_NEXTHOP_DELETE), +				zclient_vnc, (struct prefix_ipv6 *)p, NULL, +				&api); +	} else { +		vnc_zlog_debug_verbose( +			"%s: unknown prefix address family, skipping", +			__func__); +		return; +	}  }  static void -nve_list_to_nh_array ( -    u_char	family, -    struct list	*nve_list, -    int		*nh_count_ret, -    void	**nh_ary_ret,	/* returned address array */ -    void	**nhp_ary_ret)	/* returned pointer array */ +nve_list_to_nh_array(u_char family, struct list *nve_list, int *nh_count_ret, +		     void **nh_ary_ret,  /* returned address array */ +		     void **nhp_ary_ret) /* returned pointer array */  { -  int nve_count = listcount (nve_list); +	int nve_count = listcount(nve_list); -  *nh_count_ret = 0; -  *nh_ary_ret = NULL; -  *nhp_ary_ret = NULL; +	*nh_count_ret = 0; +	*nh_ary_ret = NULL; +	*nhp_ary_ret = NULL; -  if (!nve_count) -    { -      vnc_zlog_debug_verbose ("%s: empty nve_list, skipping", __func__); -      return; -    } +	if (!nve_count) { +		vnc_zlog_debug_verbose("%s: empty nve_list, skipping", +				       __func__); +		return; +	} -  if (family == AF_INET) -    { -      struct listnode *ln; -      struct in_addr *iap; -      struct in_addr **v; +	if (family == AF_INET) { +		struct listnode *ln; +		struct in_addr *iap; +		struct in_addr **v; -      /*  -       * Array of nexthop addresses -       */ -      *nh_ary_ret = XCALLOC (MTYPE_TMP, nve_count * sizeof (struct in_addr)); +		/* +		 * Array of nexthop addresses +		 */ +		*nh_ary_ret = +			XCALLOC(MTYPE_TMP, nve_count * sizeof(struct in_addr)); -      /* -       * Array of pointers to nexthop addresses -       */ -      *nhp_ary_ret = -        XCALLOC (MTYPE_TMP, nve_count * sizeof (struct in_addr *)); -      iap = *nh_ary_ret; -      v = *nhp_ary_ret; +		/* +		 * Array of pointers to nexthop addresses +		 */ +		*nhp_ary_ret = XCALLOC(MTYPE_TMP, +				       nve_count * sizeof(struct in_addr *)); +		iap = *nh_ary_ret; +		v = *nhp_ary_ret; -      for (ln = listhead (nve_list); ln; ln = listnextnode (ln)) -        { +		for (ln = listhead(nve_list); ln; ln = listnextnode(ln)) { -          struct rfapi_descriptor *irfd; -          struct prefix nhp; +			struct rfapi_descriptor *irfd; +			struct prefix nhp; -          irfd = listgetdata (ln); +			irfd = listgetdata(ln); -          if (rfapiRaddr2Qprefix (&irfd->vn_addr, &nhp)) -            continue; +			if (rfapiRaddr2Qprefix(&irfd->vn_addr, &nhp)) +				continue; -          *iap = nhp.u.prefix4; -          *v = iap; -          vnc_zlog_debug_verbose ("%s: ipadr: (%p)<-0x%x, ptr: (%p)<-%p", -                      __func__, iap, nhp.u.prefix4.s_addr, v, iap); +			*iap = nhp.u.prefix4; +			*v = iap; +			vnc_zlog_debug_verbose( +				"%s: ipadr: (%p)<-0x%x, ptr: (%p)<-%p", +				__func__, iap, nhp.u.prefix4.s_addr, v, iap); -          ++iap; -          ++v; -          ++*nh_count_ret; -        } +			++iap; +			++v; +			++*nh_count_ret; +		} -    } -  else if (family == AF_INET6) -    { +	} else if (family == AF_INET6) { -      struct listnode *ln; +		struct listnode *ln; -      *nh_ary_ret = XCALLOC (MTYPE_TMP, nve_count * sizeof (struct in6_addr)); +		*nh_ary_ret = +			XCALLOC(MTYPE_TMP, nve_count * sizeof(struct in6_addr)); -      *nhp_ary_ret = XCALLOC (MTYPE_TMP, -                              nve_count * sizeof (struct in6_addr *)); +		*nhp_ary_ret = XCALLOC(MTYPE_TMP, +				       nve_count * sizeof(struct in6_addr *)); -      for (ln = listhead (nve_list); ln; ln = listnextnode (ln)) -        { +		for (ln = listhead(nve_list); ln; ln = listnextnode(ln)) { -          struct rfapi_descriptor *irfd; -          struct in6_addr *iap = *nh_ary_ret; -          struct in6_addr **v = *nhp_ary_ret; -          struct prefix nhp; +			struct rfapi_descriptor *irfd; +			struct in6_addr *iap = *nh_ary_ret; +			struct in6_addr **v = *nhp_ary_ret; +			struct prefix nhp; -          irfd = listgetdata (ln); +			irfd = listgetdata(ln); -          if (rfapiRaddr2Qprefix (&irfd->vn_addr, &nhp)) -            continue; +			if (rfapiRaddr2Qprefix(&irfd->vn_addr, &nhp)) +				continue; -          *iap = nhp.u.prefix6; -          *v = iap; +			*iap = nhp.u.prefix6; +			*v = iap; -          ++iap; -          ++v; -          ++*nh_count_ret; -        } -    } +			++iap; +			++v; +			++*nh_count_ret; +		} +	}  } -static void -import_table_to_nve_list_zebra ( -    struct bgp			*bgp, -    struct rfapi_import_table	*it, -    struct list			**nves, -    uint8_t			family) +static void import_table_to_nve_list_zebra(struct bgp *bgp, +					   struct rfapi_import_table *it, +					   struct list **nves, uint8_t family)  { -  struct listnode *node; -  struct rfapi_rfg_name *rfgn; - -  /* -   * Loop over the list of NVE-Groups configured for -   * exporting to direct-bgp. -   * -   * Build a list of NVEs that use this import table -   */ -  *nves = NULL; -  for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_zebra_l, node, rfgn)) -    { - -      /* -       * If this NVE-Group's import table matches the current one -       */ -      if (rfgn->rfg && rfgn->rfg->nves && rfgn->rfg->rfapi_import_table == it) -        { - -          nve_group_to_nve_list (rfgn->rfg, nves, family); -        } -    } +	struct listnode *node; +	struct rfapi_rfg_name *rfgn; + +	/* +	 * Loop over the list of NVE-Groups configured for +	 * exporting to direct-bgp. +	 * +	 * Build a list of NVEs that use this import table +	 */ +	*nves = NULL; +	for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, node, +				  rfgn)) { + +		/* +		 * If this NVE-Group's import table matches the current one +		 */ +		if (rfgn->rfg && rfgn->rfg->nves +		    && rfgn->rfg->rfapi_import_table == it) { + +			nve_group_to_nve_list(rfgn->rfg, nves, family); +		} +	}  } -static void -vnc_zebra_add_del_prefix ( -    struct bgp			*bgp, -    struct rfapi_import_table	*import_table, -    struct route_node		*rn, -    int				add)	/* !0 = add, 0 = del */ +static void vnc_zebra_add_del_prefix(struct bgp *bgp, +				     struct rfapi_import_table *import_table, +				     struct route_node *rn, +				     int add) /* !0 = add, 0 = del */  { -  struct list *nves; - -  int nexthop_count = 0; -  void *nh_ary = NULL; -  void *nhp_ary = NULL; - -  vnc_zlog_debug_verbose ("%s: entry, add=%d", __func__, add); - -  if (zclient_vnc->sock < 0) -    return; - -  if (rn->p.family != AF_INET -      && rn->p.family != AF_INET6) -    { -      zlog_err ("%s: invalid route node addr family", __func__); -      return; -    } - -  if (!zclient_vnc->redist[family2afi(rn->p.family)][ZEBRA_ROUTE_VNC]) -    return; - -  if (!bgp->rfapi_cfg) -    { -      vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); -      return; -    } -  if (!listcount (bgp->rfapi_cfg->rfg_export_zebra_l)) -    { -      vnc_zlog_debug_verbose ("%s: no zebra export nve group, skipping", __func__); -      return; -    } - -  import_table_to_nve_list_zebra (bgp, import_table, &nves, rn->p.family); - -  if (nves) -    { -      nve_list_to_nh_array (rn->p.family, -                            nves, &nexthop_count, &nh_ary, &nhp_ary); - -      list_delete (nves); - -      if (nexthop_count) -        vnc_zebra_route_msg (&rn->p, nexthop_count, nhp_ary, add); -    } - -  if (nhp_ary) -    XFREE (MTYPE_TMP, nhp_ary); -  if (nh_ary) -    XFREE (MTYPE_TMP, nh_ary); +	struct list *nves; + +	int nexthop_count = 0; +	void *nh_ary = NULL; +	void *nhp_ary = NULL; + +	vnc_zlog_debug_verbose("%s: entry, add=%d", __func__, add); + +	if (zclient_vnc->sock < 0) +		return; + +	if (rn->p.family != AF_INET && rn->p.family != AF_INET6) { +		zlog_err("%s: invalid route node addr family", __func__); +		return; +	} + +	if (!zclient_vnc->redist[family2afi(rn->p.family)][ZEBRA_ROUTE_VNC]) +		return; + +	if (!bgp->rfapi_cfg) { +		vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", +				       __func__); +		return; +	} +	if (!listcount(bgp->rfapi_cfg->rfg_export_zebra_l)) { +		vnc_zlog_debug_verbose( +			"%s: no zebra export nve group, skipping", __func__); +		return; +	} + +	import_table_to_nve_list_zebra(bgp, import_table, &nves, rn->p.family); + +	if (nves) { +		nve_list_to_nh_array(rn->p.family, nves, &nexthop_count, +				     &nh_ary, &nhp_ary); + +		list_delete(nves); + +		if (nexthop_count) +			vnc_zebra_route_msg(&rn->p, nexthop_count, nhp_ary, +					    add); +	} + +	if (nhp_ary) +		XFREE(MTYPE_TMP, nhp_ary); +	if (nh_ary) +		XFREE(MTYPE_TMP, nh_ary);  } -void -vnc_zebra_add_prefix ( -    struct bgp			*bgp, -    struct rfapi_import_table	*import_table, -    struct route_node		*rn) +void vnc_zebra_add_prefix(struct bgp *bgp, +			  struct rfapi_import_table *import_table, +			  struct route_node *rn)  { -  vnc_zebra_add_del_prefix (bgp, import_table, rn, 1); +	vnc_zebra_add_del_prefix(bgp, import_table, rn, 1);  } -void -vnc_zebra_del_prefix ( -    struct bgp			*bgp, -    struct rfapi_import_table	*import_table, -    struct route_node		*rn) +void vnc_zebra_del_prefix(struct bgp *bgp, +			  struct rfapi_import_table *import_table, +			  struct route_node *rn)  { -  vnc_zebra_add_del_prefix (bgp, import_table, rn, 0); +	vnc_zebra_add_del_prefix(bgp, import_table, rn, 0);  } - -static void -vnc_zebra_add_del_nve ( -    struct bgp			*bgp, -    struct rfapi_descriptor	*rfd, -    int				add)  /* 0 = del, !0 = add */ +static void vnc_zebra_add_del_nve(struct bgp *bgp, struct rfapi_descriptor *rfd, +				  int add) /* 0 = del, !0 = add */  { -  struct listnode *node; -  struct rfapi_rfg_name *rfgn; -  struct rfapi_nve_group_cfg *rfg = rfd->rfg; -  afi_t afi = family2afi (rfd->vn_addr.addr_family); -  struct prefix nhp; -//    struct prefix             *nhpp; -  void *pAddr; - -  vnc_zlog_debug_verbose ("%s: entry, add=%d", __func__, add); - -  if (zclient_vnc->sock < 0) -    return; - -  if (!zclient_vnc->redist[afi][ZEBRA_ROUTE_VNC]) -    return; - -  if (afi != AFI_IP && afi != AFI_IP6) -    { -      zlog_err ("%s: invalid vn addr family", __func__); -      return; -    } - -  if (!bgp) -    return; -  if (!bgp->rfapi_cfg) -    { -      vnc_zlog_debug_verbose ("%s: bgp->rfapi_cfg is NULL, skipping", __func__); -      return; -    } - -  if (rfapiRaddr2Qprefix (&rfd->vn_addr, &nhp)) -    { -      vnc_zlog_debug_verbose ("%s: can't convert vn address, skipping", __func__); -      return; -    } - -  pAddr = &nhp.u.prefix4; - -  /* -   * Loop over the list of NVE-Groups configured for -   * exporting to zebra and see if this new NVE's -   * group is among them. -   */ -  for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_zebra_l, node, rfgn)) -    { - -      /* -       * Yes, this NVE's group is configured for export to zebra -       */ -      if (rfgn->rfg == rfg) -        { - -          struct route_table *rt = NULL; -          struct route_node *rn; -          struct rfapi_import_table *import_table; -          import_table = rfg->rfapi_import_table; - -          vnc_zlog_debug_verbose ("%s: this nve's group is in zebra export list", -                      __func__); - -          rt = import_table->imported_vpn[afi]; - -          /*  -           * Walk the NVE-Group's VNC Import table -           */ -          for (rn = route_top (rt); rn; rn = route_next (rn)) -            { - -              if (rn->info) -                { - -                  vnc_zlog_debug_verbose ("%s: sending %s", __func__, -                              (add ? "add" : "del")); -                  vnc_zebra_route_msg (&rn->p, 1, &pAddr, add); -                } -            } -        } -    } +	struct listnode *node; +	struct rfapi_rfg_name *rfgn; +	struct rfapi_nve_group_cfg *rfg = rfd->rfg; +	afi_t afi = family2afi(rfd->vn_addr.addr_family); +	struct prefix nhp; +	//    struct prefix             *nhpp; +	void *pAddr; + +	vnc_zlog_debug_verbose("%s: entry, add=%d", __func__, add); + +	if (zclient_vnc->sock < 0) +		return; + +	if (!zclient_vnc->redist[afi][ZEBRA_ROUTE_VNC]) +		return; + +	if (afi != AFI_IP && afi != AFI_IP6) { +		zlog_err("%s: invalid vn addr family", __func__); +		return; +	} + +	if (!bgp) +		return; +	if (!bgp->rfapi_cfg) { +		vnc_zlog_debug_verbose("%s: bgp->rfapi_cfg is NULL, skipping", +				       __func__); +		return; +	} + +	if (rfapiRaddr2Qprefix(&rfd->vn_addr, &nhp)) { +		vnc_zlog_debug_verbose("%s: can't convert vn address, skipping", +				       __func__); +		return; +	} + +	pAddr = &nhp.u.prefix4; + +	/* +	 * Loop over the list of NVE-Groups configured for +	 * exporting to zebra and see if this new NVE's +	 * group is among them. +	 */ +	for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, node, +				  rfgn)) { + +		/* +		 * Yes, this NVE's group is configured for export to zebra +		 */ +		if (rfgn->rfg == rfg) { + +			struct route_table *rt = NULL; +			struct route_node *rn; +			struct rfapi_import_table *import_table; +			import_table = rfg->rfapi_import_table; + +			vnc_zlog_debug_verbose( +				"%s: this nve's group is in zebra export list", +				__func__); + +			rt = import_table->imported_vpn[afi]; + +			/* +			 * Walk the NVE-Group's VNC Import table +			 */ +			for (rn = route_top(rt); rn; rn = route_next(rn)) { + +				if (rn->info) { + +					vnc_zlog_debug_verbose( +						"%s: sending %s", __func__, +						(add ? "add" : "del")); +					vnc_zebra_route_msg(&rn->p, 1, &pAddr, +							    add); +				} +			} +		} +	}  } -void -vnc_zebra_add_nve (struct bgp *bgp, struct rfapi_descriptor *rfd) +void vnc_zebra_add_nve(struct bgp *bgp, struct rfapi_descriptor *rfd)  { -  vnc_zebra_add_del_nve (bgp, rfd, 1); +	vnc_zebra_add_del_nve(bgp, rfd, 1);  } -void -vnc_zebra_del_nve (struct bgp *bgp, struct rfapi_descriptor *rfd) +void vnc_zebra_del_nve(struct bgp *bgp, struct rfapi_descriptor *rfd)  { -  vnc_zebra_add_del_nve (bgp, rfd, 0); +	vnc_zebra_add_del_nve(bgp, rfd, 0);  } -static void -vnc_zebra_add_del_group_afi ( -    struct bgp			*bgp, -    struct rfapi_nve_group_cfg	*rfg, -    afi_t			afi, -    int				add) +static void vnc_zebra_add_del_group_afi(struct bgp *bgp, +					struct rfapi_nve_group_cfg *rfg, +					afi_t afi, int add)  { -  struct route_table *rt = NULL; -  struct route_node *rn; -  struct rfapi_import_table *import_table; -  uint8_t family = afi2family (afi); - -  struct list *nves = NULL; -  int nexthop_count = 0; -  void *nh_ary = NULL; -  void *nhp_ary = NULL; - -  vnc_zlog_debug_verbose ("%s: entry", __func__); -  import_table = rfg->rfapi_import_table; -  if (!import_table) -    { -      vnc_zlog_debug_verbose ("%s: import table not defined, returning", __func__); -      return; -    } - -  if (afi == AFI_IP -      || afi == AFI_IP6) -    { -      rt = import_table->imported_vpn[afi]; -    } -  else -    { -      zlog_err ("%s: bad afi %d", __func__, afi); -      return; -    } - -  if (!family) -    { -      zlog_err ("%s: computed bad family: %d", __func__, family); -      return; -    } - -  if (!rfg->nves) -    { -      /* avoid segfault below if list doesn't exist */ -      vnc_zlog_debug_verbose ("%s: no NVEs in this group", __func__); -      return; -    } - -  nve_group_to_nve_list (rfg, &nves, family); -  if (nves) -    { -      vnc_zlog_debug_verbose ("%s: have nves", __func__); -      nve_list_to_nh_array (family, nves, &nexthop_count, &nh_ary, &nhp_ary); - -      vnc_zlog_debug_verbose ("%s: family: %d, nve count: %d", __func__, family, -                  nexthop_count); - -      list_delete (nves); - -      if (nexthop_count) -        { -          /*  -           * Walk the NVE-Group's VNC Import table -           */ -          for (rn = route_top (rt); rn; rn = route_next (rn)) -            { -              if (rn->info) -                { -                  vnc_zebra_route_msg (&rn->p, nexthop_count, nhp_ary, add); -                } -            } -        } -      if (nhp_ary) -        XFREE (MTYPE_TMP, nhp_ary); -      if (nh_ary) -        XFREE (MTYPE_TMP, nh_ary); -    } +	struct route_table *rt = NULL; +	struct route_node *rn; +	struct rfapi_import_table *import_table; +	uint8_t family = afi2family(afi); + +	struct list *nves = NULL; +	int nexthop_count = 0; +	void *nh_ary = NULL; +	void *nhp_ary = NULL; + +	vnc_zlog_debug_verbose("%s: entry", __func__); +	import_table = rfg->rfapi_import_table; +	if (!import_table) { +		vnc_zlog_debug_verbose( +			"%s: import table not defined, returning", __func__); +		return; +	} + +	if (afi == AFI_IP || afi == AFI_IP6) { +		rt = import_table->imported_vpn[afi]; +	} else { +		zlog_err("%s: bad afi %d", __func__, afi); +		return; +	} + +	if (!family) { +		zlog_err("%s: computed bad family: %d", __func__, family); +		return; +	} + +	if (!rfg->nves) { +		/* avoid segfault below if list doesn't exist */ +		vnc_zlog_debug_verbose("%s: no NVEs in this group", __func__); +		return; +	} + +	nve_group_to_nve_list(rfg, &nves, family); +	if (nves) { +		vnc_zlog_debug_verbose("%s: have nves", __func__); +		nve_list_to_nh_array(family, nves, &nexthop_count, &nh_ary, +				     &nhp_ary); + +		vnc_zlog_debug_verbose("%s: family: %d, nve count: %d", +				       __func__, family, nexthop_count); + +		list_delete(nves); + +		if (nexthop_count) { +			/* +			 * Walk the NVE-Group's VNC Import table +			 */ +			for (rn = route_top(rt); rn; rn = route_next(rn)) { +				if (rn->info) { +					vnc_zebra_route_msg(&rn->p, +							    nexthop_count, +							    nhp_ary, add); +				} +			} +		} +		if (nhp_ary) +			XFREE(MTYPE_TMP, nhp_ary); +		if (nh_ary) +			XFREE(MTYPE_TMP, nh_ary); +	}  } -void -vnc_zebra_add_group (struct bgp *bgp, struct rfapi_nve_group_cfg *rfg) +void vnc_zebra_add_group(struct bgp *bgp, struct rfapi_nve_group_cfg *rfg)  { -  vnc_zebra_add_del_group_afi (bgp, rfg, AFI_IP, 1); -  vnc_zebra_add_del_group_afi (bgp, rfg, AFI_IP6, 1); +	vnc_zebra_add_del_group_afi(bgp, rfg, AFI_IP, 1); +	vnc_zebra_add_del_group_afi(bgp, rfg, AFI_IP6, 1);  } -void -vnc_zebra_del_group (struct bgp *bgp, struct rfapi_nve_group_cfg *rfg) +void vnc_zebra_del_group(struct bgp *bgp, struct rfapi_nve_group_cfg *rfg)  { -  vnc_zlog_debug_verbose ("%s: entry", __func__); -  vnc_zebra_add_del_group_afi (bgp, rfg, AFI_IP, 0); -  vnc_zebra_add_del_group_afi (bgp, rfg, AFI_IP6, 0); +	vnc_zlog_debug_verbose("%s: entry", __func__); +	vnc_zebra_add_del_group_afi(bgp, rfg, AFI_IP, 0); +	vnc_zebra_add_del_group_afi(bgp, rfg, AFI_IP6, 0);  } -void -vnc_zebra_reexport_group_afi ( -    struct bgp			*bgp, -    struct rfapi_nve_group_cfg	*rfg, -    afi_t			afi) +void vnc_zebra_reexport_group_afi(struct bgp *bgp, +				  struct rfapi_nve_group_cfg *rfg, afi_t afi)  { -  struct listnode *node; -  struct rfapi_rfg_name *rfgn; - -  for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->rfg_export_zebra_l, node, rfgn)) -    { - -      if (rfgn->rfg == rfg) -        { -          vnc_zebra_add_del_group_afi (bgp, rfg, afi, 0); -          vnc_zebra_add_del_group_afi (bgp, rfg, afi, 1); -          break; -        } -    } +	struct listnode *node; +	struct rfapi_rfg_name *rfgn; + +	for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->rfg_export_zebra_l, node, +				  rfgn)) { + +		if (rfgn->rfg == rfg) { +			vnc_zebra_add_del_group_afi(bgp, rfg, afi, 0); +			vnc_zebra_add_del_group_afi(bgp, rfg, afi, 1); +			break; +		} +	}  } @@ -1031,77 +959,76 @@ vnc_zebra_reexport_group_afi (  /* Other routes redistribution into BGP. */ -int -vnc_redistribute_set (struct bgp *bgp, afi_t afi, int type) +int vnc_redistribute_set(struct bgp *bgp, afi_t afi, int type)  { -  if (!bgp->rfapi_cfg) -    { -      return CMD_WARNING_CONFIG_FAILED; -    } +	if (!bgp->rfapi_cfg) { +		return CMD_WARNING_CONFIG_FAILED; +	} -  /* Set flag to BGP instance. */ -  bgp->rfapi_cfg->redist[afi][type] = 1; +	/* Set flag to BGP instance. */ +	bgp->rfapi_cfg->redist[afi][type] = 1; -//  bgp->redist[afi][type] = 1; +	//  bgp->redist[afi][type] = 1; -  /* Return if already redistribute flag is set. */ -  if (zclient_vnc->redist[afi][type]) -    return CMD_WARNING_CONFIG_FAILED; +	/* Return if already redistribute flag is set. */ +	if (zclient_vnc->redist[afi][type]) +		return CMD_WARNING_CONFIG_FAILED; -  vrf_bitmap_set (zclient_vnc->redist[afi][type], VRF_DEFAULT); +	vrf_bitmap_set(zclient_vnc->redist[afi][type], VRF_DEFAULT); -  //zclient_vnc->redist[afi][type] = 1;  +	// zclient_vnc->redist[afi][type] = 1; -  /* Return if zebra connection is not established. */ -  if (zclient_vnc->sock < 0) -    return CMD_WARNING_CONFIG_FAILED; +	/* Return if zebra connection is not established. */ +	if (zclient_vnc->sock < 0) +		return CMD_WARNING_CONFIG_FAILED; -  if (BGP_DEBUG (zebra, ZEBRA)) -    vnc_zlog_debug_verbose ("Zebra send: redistribute add %s", zebra_route_string (type)); +	if (BGP_DEBUG(zebra, ZEBRA)) +		vnc_zlog_debug_verbose("Zebra send: redistribute add %s", +				       zebra_route_string(type)); -  /* Send distribute add message to zebra. */ -  zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient_vnc, afi, type, 0, VRF_DEFAULT); +	/* Send distribute add message to zebra. */ +	zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient_vnc, afi, type, +				0, VRF_DEFAULT); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  /* Unset redistribution.  */ -int -vnc_redistribute_unset (struct bgp *bgp, afi_t afi, int type) +int vnc_redistribute_unset(struct bgp *bgp, afi_t afi, int type)  { -  vnc_zlog_debug_verbose ("%s: type=%d entry", __func__, type); - -  if (!bgp->rfapi_cfg) -    { -      vnc_zlog_debug_verbose ("%s: return (no rfapi_cfg)", __func__); -      return CMD_WARNING_CONFIG_FAILED; -    } - -  /* Unset flag from BGP instance. */ -  bgp->rfapi_cfg->redist[afi][type] = 0; - -  /* Return if zebra connection is disabled. */ -  if (!zclient_vnc->redist[afi][type]) -    return CMD_WARNING_CONFIG_FAILED; -  zclient_vnc->redist[afi][type] = 0; - -  if (bgp->rfapi_cfg->redist[AFI_IP][type] == 0 -      && bgp->rfapi_cfg->redist[AFI_IP6][type] == 0 && zclient_vnc->sock >= 0) -    { -      /* Send distribute delete message to zebra. */ -      if (BGP_DEBUG (zebra, ZEBRA)) -        vnc_zlog_debug_verbose ("Zebra send: redistribute delete %s", -                    zebra_route_string (type)); -      zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient_vnc, afi, type, -                               0, VRF_DEFAULT); -    } - -  /* Withdraw redistributed routes from current BGP's routing table. */ -  vnc_redistribute_withdraw (bgp, afi, type); - -  vnc_zlog_debug_verbose ("%s: return", __func__); - -  return CMD_SUCCESS; +	vnc_zlog_debug_verbose("%s: type=%d entry", __func__, type); + +	if (!bgp->rfapi_cfg) { +		vnc_zlog_debug_verbose("%s: return (no rfapi_cfg)", __func__); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	/* Unset flag from BGP instance. */ +	bgp->rfapi_cfg->redist[afi][type] = 0; + +	/* Return if zebra connection is disabled. */ +	if (!zclient_vnc->redist[afi][type]) +		return CMD_WARNING_CONFIG_FAILED; +	zclient_vnc->redist[afi][type] = 0; + +	if (bgp->rfapi_cfg->redist[AFI_IP][type] == 0 +	    && bgp->rfapi_cfg->redist[AFI_IP6][type] == 0 +	    && zclient_vnc->sock >= 0) { +		/* Send distribute delete message to zebra. */ +		if (BGP_DEBUG(zebra, ZEBRA)) +			vnc_zlog_debug_verbose( +				"Zebra send: redistribute delete %s", +				zebra_route_string(type)); +		zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient_vnc, +					afi, type, 0, VRF_DEFAULT); +	} + +	/* Withdraw redistributed routes from current BGP's routing table. */ +	vnc_redistribute_withdraw(bgp, afi, type); + +	vnc_zlog_debug_verbose("%s: return", __func__); + +	return CMD_SUCCESS;  } @@ -1109,25 +1036,23 @@ vnc_redistribute_unset (struct bgp *bgp, afi_t afi, int type)   * Modeled after bgp_zebra.c'bgp_zebra_init()   * Charriere asks, "Is it possible to carry two?"   */ -void -vnc_zebra_init (struct thread_master *master) +void vnc_zebra_init(struct thread_master *master)  { -  /* Set default values. */ -  zclient_vnc = zclient_new (master); -  zclient_init (zclient_vnc, ZEBRA_ROUTE_VNC, 0); - -  zclient_vnc->redistribute_route_ipv4_add = vnc_zebra_read_ipv4; -  zclient_vnc->redistribute_route_ipv4_del = vnc_zebra_read_ipv4; -  zclient_vnc->redistribute_route_ipv6_add = vnc_zebra_read_ipv6; -  zclient_vnc->redistribute_route_ipv6_del = vnc_zebra_read_ipv6; +	/* Set default values. */ +	zclient_vnc = zclient_new(master); +	zclient_init(zclient_vnc, ZEBRA_ROUTE_VNC, 0); + +	zclient_vnc->redistribute_route_ipv4_add = vnc_zebra_read_ipv4; +	zclient_vnc->redistribute_route_ipv4_del = vnc_zebra_read_ipv4; +	zclient_vnc->redistribute_route_ipv6_add = vnc_zebra_read_ipv6; +	zclient_vnc->redistribute_route_ipv6_del = vnc_zebra_read_ipv6;  } -void -vnc_zebra_destroy (void) +void vnc_zebra_destroy(void)  { -  if (zclient_vnc == NULL) -    return; -  zclient_stop (zclient_vnc); -  zclient_free (zclient_vnc); -  zclient_vnc = NULL; +	if (zclient_vnc == NULL) +		return; +	zclient_stop(zclient_vnc); +	zclient_free(zclient_vnc); +	zclient_vnc = NULL;  } diff --git a/bgpd/rfapi/vnc_zebra.h b/bgpd/rfapi/vnc_zebra.h index 68e567ec35..708aaeef50 100644 --- a/bgpd/rfapi/vnc_zebra.h +++ b/bgpd/rfapi/vnc_zebra.h @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2009-2016, LabN Consulting, L.L.C.   * @@ -27,40 +27,30 @@  #include "lib/zebra.h" -extern void -vnc_zebra_add_prefix ( -    struct bgp			*bgp, -    struct rfapi_import_table	*import_table, -    struct route_node		*rn); +extern void vnc_zebra_add_prefix(struct bgp *bgp, +				 struct rfapi_import_table *import_table, +				 struct route_node *rn); -extern void -vnc_zebra_del_prefix ( -    struct bgp			*bgp, -    struct rfapi_import_table	*import_table, -    struct route_node		*rn); +extern void vnc_zebra_del_prefix(struct bgp *bgp, +				 struct rfapi_import_table *import_table, +				 struct route_node *rn); -extern void -vnc_zebra_add_nve (struct bgp *bgp, struct rfapi_descriptor *rfd); +extern void vnc_zebra_add_nve(struct bgp *bgp, struct rfapi_descriptor *rfd); -extern void -vnc_zebra_del_nve (struct bgp *bgp, struct rfapi_descriptor *rfd); +extern void vnc_zebra_del_nve(struct bgp *bgp, struct rfapi_descriptor *rfd); -extern void -vnc_zebra_add_group (struct bgp *bgp, struct rfapi_nve_group_cfg *rfg); +extern void vnc_zebra_add_group(struct bgp *bgp, +				struct rfapi_nve_group_cfg *rfg); -extern void -vnc_zebra_del_group (struct bgp *bgp, struct rfapi_nve_group_cfg *rfg); +extern void vnc_zebra_del_group(struct bgp *bgp, +				struct rfapi_nve_group_cfg *rfg); -extern void -vnc_zebra_reexport_group_afi ( -    struct bgp			*bgp, -    struct rfapi_nve_group_cfg	*rfg, -    afi_t			afi); +extern void vnc_zebra_reexport_group_afi(struct bgp *bgp, +					 struct rfapi_nve_group_cfg *rfg, +					 afi_t afi); -extern int -vnc_redistribute_set (struct bgp *bgp, afi_t afi, int type); +extern int vnc_redistribute_set(struct bgp *bgp, afi_t afi, int type); -extern int -vnc_redistribute_unset (struct bgp *bgp, afi_t afi, int type); +extern int vnc_redistribute_unset(struct bgp *bgp, afi_t afi, int type);  #endif /* _QUAGGA_BGP_VNC_ZEBRA_H */  | 
