diff options
Diffstat (limited to 'bgpd/rfapi/rfapi.c')
| -rw-r--r-- | bgpd/rfapi/rfapi.c | 6757 | 
1 files changed, 3239 insertions, 3518 deletions
diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c index 99d26cf13c..1cbb285707 100644 --- a/bgpd/rfapi/rfapi.c +++ b/bgpd/rfapi/rfapi.c @@ -1,4 +1,4 @@ -/*  +/*   *   * Copyright 2009-2016, LabN Consulting, L.L.C.   * @@ -66,38 +66,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"; +	}  }  /*------------------------------------------ @@ -107,20 +105,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;  }  /*------------------------------------------ @@ -128,7 +125,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)   * @@ -138,11 +135,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);  } @@ -151,19 +147,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;  }  /*------------------------------------------ @@ -171,505 +166,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))      { @@ -683,581 +632,545 @@ 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); -  assert (attr.extra); - -  /*  -   * 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. */ -          bgp_attr_extra_free (&attr); -          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.extra->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.extra->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.extra->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.extra->vnc_subtlvs) -            { -              attr.extra->vnc_subtlvs->next = encaptlv; -            } -          else -            { -              attr.extra->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.extra->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.extra->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.extra->ecommunity = ecommunity_new (); -  assert (attr.extra->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.extra->ecommunity, &beec); -    } - -  /* -   * Add extended community attributes to match rt export list -   */ -  if (rt_export_list) -    { -      attr.extra->ecommunity = -        ecommunity_merge (attr.extra->ecommunity, rt_export_list); -    } - -  if (attr.extra->ecommunity->size) -    { -      attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES); -    } -  else -    { -      ecommunity_free (&attr.extra->ecommunity); -      attr.extra->ecommunity = NULL; -    } -  vnc_zlog_debug_verbose ("%s: attr.extra->ecommunity=%p", __func__, -              attr.extra->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.extra->mp_nexthop_global_in = nexthop->addr.v4; -      attr.extra->mp_nexthop_len = 4; -      break; - -    case AF_INET6: -      attr.extra->mp_nexthop_global = nexthop->addr.v6; -      attr.extra->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. */ -  bgp_attr_extra_free (&attr); - -  /* -   * 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->tag); - -  /* 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); -    } - -  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); +	assert(attr.extra); + +	/* +	 * 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. */ +			bgp_attr_extra_free(&attr); +			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.extra->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.extra->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.extra->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.extra->vnc_subtlvs) { +				attr.extra->vnc_subtlvs->next = encaptlv; +			} else { +				attr.extra->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.extra->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.extra->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.extra->ecommunity = ecommunity_new(); +	assert(attr.extra->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.extra->ecommunity, &beec); +	} + +	/* +	 * Add extended community attributes to match rt export list +	 */ +	if (rt_export_list) { +		attr.extra->ecommunity = ecommunity_merge( +			attr.extra->ecommunity, rt_export_list); +	} + +	if (attr.extra->ecommunity->size) { +		attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES); +	} else { +		ecommunity_free(&attr.extra->ecommunity); +		attr.extra->ecommunity = NULL; +	} +	vnc_zlog_debug_verbose("%s: attr.extra->ecommunity=%p", __func__, +			       attr.extra->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.extra->mp_nexthop_global_in = nexthop->addr.v4; +		attr.extra->mp_nexthop_len = 4; +		break; + +	case AF_INET6: +		attr.extra->mp_nexthop_global = nexthop->addr.v6; +		attr.extra->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. */ +	bgp_attr_extra_free(&attr); + +	/* +	 * 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->tag); + +	/* 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); +	} + +	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);  } @@ -1268,88 +1181,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;  }  /*********************************************************************** @@ -1361,570 +1270,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;  }  /* @@ -1932,68 +1791,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;  }  /*------------------------------------------ @@ -2002,7 +1856,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   * @@ -2020,13 +1874,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 @@ -2036,188 +1890,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;  }  /* @@ -2233,246 +2075,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;  }  /* @@ -2492,580 +2322,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;  }  /*********************************************************************** @@ -3080,8 +2865,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 ( @@ -3097,28 +2882,25 @@ DEFUN (    "IPv4 address\n"    "IPv6 address\n")  { -  struct prefix pfx; - -  if (!str2prefix (argv[5]->arg, &pfx)) -    { -      vty_out (vty, "Malformed address \"%s\"%s", argv[5]->arg, VTY_NEWLINE); -      return CMD_WARNING; -    } -  if (pfx.family != AF_INET && pfx.family != AF_INET6) -    { -      vty_out (vty, "Invalid address \"%s\"%s", argv[5]->arg, VTY_NEWLINE); -      return CMD_WARNING; -    } - -  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\"%s", argv[5]->arg, +			VTY_NEWLINE); +		return CMD_WARNING; +	} +	if (pfx.family != AF_INET && pfx.family != AF_INET6) { +		vty_out(vty, "Invalid address \"%s\"%s", argv[5]->arg, +			VTY_NEWLINE); +		return CMD_WARNING; +	} + +	if (argv[4]->arg[0] == 'u') { +		rfapiPrintMatchingDescriptors(vty, NULL, &pfx); +	} else { +		rfapiPrintMatchingDescriptors(vty, &pfx, NULL); +	} +	return CMD_SUCCESS;  }  /* @@ -3126,29 +2908,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, ")%s", VTY_NEWLINE); +	fp(out, "Nexthops Callback, Target=("); +	// rfapiPrintRfapiIpAddr(stream, target); +	fp(out, ")%s", VTY_NEWLINE); -  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, @@ -3164,35 +2944,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%s", -           rc, handle, lifetime, VTY_NEWLINE); +	vty_out(vty, "rfapi_open: status %d, handle %p, lifetime %d%s", rc, +		handle, lifetime, VTY_NEWLINE); -  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%s", rc, VTY_NEWLINE); +	vty_out(vty, "rfapi_set_response_cb: status %d%s", rc, VTY_NEWLINE); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  } @@ -3209,38 +2989,37 @@ 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%s", -               argv[4]->arg, argv[6]->arg, VTY_NEWLINE); -      return CMD_WARNING; -    } +	if (rfapi_find_handle_vty(vty, &vn, &un, &handle)) { +		vty_out(vty, "can't locate handle matching vn=%s, un=%s%s", +			argv[4]->arg, argv[6]->arg, VTY_NEWLINE); +		return CMD_WARNING; +	} -  rc = rfapi_close (handle); +	rc = rfapi_close(handle); -  vty_out (vty, "rfapi_close(handle=%p): status %d%s", handle, rc, -           VTY_NEWLINE); +	vty_out(vty, "rfapi_close(handle=%p): status %d%s", handle, rc, +		VTY_NEWLINE); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (debug_rfapi_close_rfd, @@ -3251,24 +3030,23 @@ 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%s", argv[4]->arg, VTY_NEWLINE); -      return CMD_WARNING; -    } +	if (*endptr != '\0' || (uintptr_t)handle == UINTPTR_MAX) { +		vty_out(vty, "Invalid value: %s%s", argv[4]->arg, VTY_NEWLINE); +		return CMD_WARNING; +	} -  rc = rfapi_close (handle); +	rc = rfapi_close(handle); -  vty_out (vty, "rfapi_close(handle=%p): status %d%s", handle, rc, -           VTY_NEWLINE); +	vty_out(vty, "rfapi_close(handle=%p): status %d%s", handle, rc, +		VTY_NEWLINE); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (debug_rfapi_register_vn_un, @@ -3289,68 +3067,63 @@ 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%s", -               argv[4]->arg, argv[6]->arg, VTY_NEWLINE); -      return CMD_WARNING; -    } - -  /* -   * Get prefix to advertise -   */ -  if (!str2prefix (argv[8]->arg, &pfx)) -    { -      vty_out (vty, "Malformed prefix \"%s\"%s", argv[8]->arg, VTY_NEWLINE); -      return CMD_WARNING; -    } -  if (pfx.family != AF_INET && pfx.family != AF_INET6) -    { -      vty_out (vty, "Bad family for prefix \"%s\"%s", argv[8]->arg, VTY_NEWLINE); -      return CMD_WARNING; -    } -  rfapiQprefix2Rprefix (&pfx, &hpfx); - -  if (!strcmp (argv[10]->arg, "infinite")) -    { -      lifetime = RFAPI_INFINITE_LIFETIME; -    } -  else -    { -      VTY_GET_INTEGER ("Lifetime", lifetime, argv[10]->arg); -    } - - -  rc = rfapi_register (handle, &hpfx, lifetime, NULL, NULL, 0); -  if (rc) -    { -      vty_out (vty, "rfapi_register failed with rc=%d (%s)%s", rc, -               strerror (rc), VTY_NEWLINE); -    } - -  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%s", +			argv[4]->arg, argv[6]->arg, VTY_NEWLINE); +		return CMD_WARNING; +	} + +	/* +	 * Get prefix to advertise +	 */ +	if (!str2prefix(argv[8]->arg, &pfx)) { +		vty_out(vty, "Malformed prefix \"%s\"%s", argv[8]->arg, +			VTY_NEWLINE); +		return CMD_WARNING; +	} +	if (pfx.family != AF_INET && pfx.family != AF_INET6) { +		vty_out(vty, "Bad family for prefix \"%s\"%s", argv[8]->arg, +			VTY_NEWLINE); +		return CMD_WARNING; +	} +	rfapiQprefix2Rprefix(&pfx, &hpfx); + +	if (!strcmp(argv[10]->arg, "infinite")) { +		lifetime = RFAPI_INFINITE_LIFETIME; +	} else { +		VTY_GET_INTEGER("Lifetime", lifetime, argv[10]->arg); +	} + + +	rc = rfapi_register(handle, &hpfx, lifetime, NULL, NULL, 0); +	if (rc) { +		vty_out(vty, "rfapi_register failed with rc=%d (%s)%s", rc, +			strerror(rc), VTY_NEWLINE); +	} + +	return CMD_SUCCESS;  }  DEFUN (debug_rfapi_register_vn_un_l2o, @@ -3375,92 +3148,86 @@ 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%s", -               argv[4]->arg, argv[6]->arg, VTY_NEWLINE); -      return CMD_WARNING; -    } - -  /* -   * Get prefix to advertise -   */ -  if (!str2prefix (argv[8]->arg, &pfx)) -    { -      vty_out (vty, "Malformed prefix \"%s\"%s", argv[8]->arg, VTY_NEWLINE); -      return CMD_WARNING; -    } -  if (pfx.family != AF_INET && pfx.family != AF_INET6) -    { -      vty_out (vty, "Bad family for prefix \"%s\"%s", argv[8]->arg, VTY_NEWLINE); -      return CMD_WARNING; -    } -  rfapiQprefix2Rprefix (&pfx, &hpfx); - -  if (!strcmp (argv[10]->arg, "infinite")) -    { -      lifetime = RFAPI_INFINITE_LIFETIME; -    } -  else -    { -      VTY_GET_INTEGER ("Lifetime", lifetime, argv[10]->arg); -    } - -  /* L2 option parsing START */ -  memset (optary, 0, sizeof (optary)); -  VTY_GET_INTEGER ("Logical Network ID", -                   optary[opt_next].v.l2addr.logical_net_id, argv[14]->arg); -  if ((rc = rfapiStr2EthAddr (argv[12]->arg, &optary[opt_next].v.l2addr.macaddr))) -    { -      vty_out (vty, "Bad mac address \"%s\"%s", argv[12]->arg, VTY_NEWLINE); -      return CMD_WARNING; -    } -  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)%s", rc, -               strerror (rc), VTY_NEWLINE); -    } - -  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%s", +			argv[4]->arg, argv[6]->arg, VTY_NEWLINE); +		return CMD_WARNING; +	} + +	/* +	 * Get prefix to advertise +	 */ +	if (!str2prefix(argv[8]->arg, &pfx)) { +		vty_out(vty, "Malformed prefix \"%s\"%s", argv[8]->arg, +			VTY_NEWLINE); +		return CMD_WARNING; +	} +	if (pfx.family != AF_INET && pfx.family != AF_INET6) { +		vty_out(vty, "Bad family for prefix \"%s\"%s", argv[8]->arg, +			VTY_NEWLINE); +		return CMD_WARNING; +	} +	rfapiQprefix2Rprefix(&pfx, &hpfx); + +	if (!strcmp(argv[10]->arg, "infinite")) { +		lifetime = RFAPI_INFINITE_LIFETIME; +	} else { +		VTY_GET_INTEGER("Lifetime", lifetime, argv[10]->arg); +	} + +	/* L2 option parsing START */ +	memset(optary, 0, sizeof(optary)); +	VTY_GET_INTEGER("Logical Network ID", +			optary[opt_next].v.l2addr.logical_net_id, +			argv[14]->arg); +	if ((rc = rfapiStr2EthAddr(argv[12]->arg, +				   &optary[opt_next].v.l2addr.macaddr))) { +		vty_out(vty, "Bad mac address \"%s\"%s", argv[12]->arg, +			VTY_NEWLINE); +		return CMD_WARNING; +	} +	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)%s", rc, +			strerror(rc), VTY_NEWLINE); +	} + +	return CMD_SUCCESS;  } @@ -3476,52 +3243,51 @@ 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%s", -               argv[4]->arg, argv[6]->arg, VTY_NEWLINE); -      return CMD_WARNING; -    } - -  /* -   * Get prefix to advertise -   */ -  if (!str2prefix (argv[8]->arg, &pfx)) -    { -      vty_out (vty, "Malformed prefix \"%s\"%s", argv[8]->arg, VTY_NEWLINE); -      return CMD_WARNING; -    } -  if (pfx.family != AF_INET && pfx.family != AF_INET6) -    { -      vty_out (vty, "Bad family for prefix \"%s\"%s", argv[8]->arg, VTY_NEWLINE); -      return CMD_WARNING; -    } -  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%s", +			argv[4]->arg, argv[6]->arg, VTY_NEWLINE); +		return CMD_WARNING; +	} + +	/* +	 * Get prefix to advertise +	 */ +	if (!str2prefix(argv[8]->arg, &pfx)) { +		vty_out(vty, "Malformed prefix \"%s\"%s", argv[8]->arg, +			VTY_NEWLINE); +		return CMD_WARNING; +	} +	if (pfx.family != AF_INET && pfx.family != AF_INET6) { +		vty_out(vty, "Bad family for prefix \"%s\"%s", argv[8]->arg, +			VTY_NEWLINE); +		return CMD_WARNING; +	} +	rfapiQprefix2Rprefix(&pfx, &hpfx); + +	rfapi_register(handle, &hpfx, 0, NULL, NULL, 1); + +	return CMD_SUCCESS;  }  DEFUN (debug_rfapi_query_vn_un, @@ -3540,60 +3306,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%s", -               argv[4]->arg, argv[6]->arg, VTY_NEWLINE); -      return CMD_WARNING; -    } - -  /* -   * 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)%s", rc, -               strerror (rc), VTY_NEWLINE); -    } -  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%s", +			argv[4]->arg, argv[6]->arg, VTY_NEWLINE); +		return CMD_WARNING; +	} + +	/* +	 * 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)%s", rc, +			strerror(rc), VTY_NEWLINE); +	} else { +		/* +		 * print nexthop list +		 */ +		test_nexthops_callback(/*&target, */ pNextHopEntry, +				       vty); /* frees nh list! */ +	} + +	return CMD_SUCCESS;  } @@ -3614,28 +3377,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 ?????? */ @@ -3645,65 +3408,63 @@ DEFUN (debug_rfapi_query_vn_un_l2o,    if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[2], &target)))      return rc;  #else -  vty_out (vty, "%% This command is broken.%s", VTY_NEWLINE); -  return CMD_WARNING; +	vty_out(vty, "%% This command is broken.%s", VTY_NEWLINE); +	return CMD_WARNING;  #endif -  if (rfapi_find_handle_vty (vty, &vn, &un, &handle)) -    { -      vty_out (vty, "can't locate handle matching vn=%s, un=%s%s", -               argv[4]->arg, argv[6]->arg, VTY_NEWLINE); -      return CMD_WARNING; -    } - -  /* -   * 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\"%s", argv[10]->arg, VTY_NEWLINE); -      return CMD_WARNING; -    } - -  VTY_GET_INTEGER ("Logical Network ID", l2o_buf.logical_net_id, argv[8]->arg); - -  /* 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)%s", rc, -               strerror (rc), VTY_NEWLINE); -    } -  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%s", +			argv[4]->arg, argv[6]->arg, VTY_NEWLINE); +		return CMD_WARNING; +	} + +	/* +	 * 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\"%s", argv[10]->arg, +			VTY_NEWLINE); +		return CMD_WARNING; +	} + +	VTY_GET_INTEGER("Logical Network ID", l2o_buf.logical_net_id, +			argv[8]->arg); + +	/* 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)%s", rc, +			strerror(rc), VTY_NEWLINE); +	} else { +		/* +		 * print nexthop list +		 */ +		/* TBD enhance to print L2 information */ +		test_nexthops_callback(/*&target, */ pNextHopEntry, +				       vty); /* frees nh list! */ +	} + +	return CMD_SUCCESS;  } @@ -3724,48 +3485,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%s", -               argv[5]->arg, argv[7]->arg, VTY_NEWLINE); -      return CMD_WARNING; -    } +	if (rfapi_find_handle_vty(vty, &vn, &un, &handle)) { +		vty_out(vty, "can't locate handle matching vn=%s, un=%s%s", +			argv[5]->arg, argv[7]->arg, VTY_NEWLINE); +		return CMD_WARNING; +	} -  /* -   * 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%s", rc, VTY_NEWLINE); +	vty_out(vty, "rfapi_query_done returned %d%s", rc, VTY_NEWLINE); -  return CMD_SUCCESS; +	return CMD_SUCCESS;  }  DEFUN (debug_rfapi_show_import, @@ -3776,84 +3536,83 @@ 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%s", VTY_NEWLINE); -      return CMD_WARNING; -    } - -  h = bgp->rfapi; -  if (!h) -    { -      vty_out (vty, "No RFAPI instance%s", VTY_NEWLINE); -      return CMD_WARNING; -    } - -  /* -   * 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%s", it, s, VTY_NEWLINE); -      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, "%sLNI-based Ethernet Tables:%s", -                           VTY_NEWLINE, VTY_NEWLINE); -                  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%s", VTY_NEWLINE); +		return CMD_WARNING; +	} + +	h = bgp->rfapi; +	if (!h) { +		vty_out(vty, "No RFAPI instance%s", VTY_NEWLINE); +		return CMD_WARNING; +	} + +	/* +	 * 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%s", it, s, VTY_NEWLINE); +		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, +						"%sLNI-based Ethernet Tables:%s", +						VTY_NEWLINE, VTY_NEWLINE); +					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, @@ -3870,45 +3629,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%s", -               argv[5]->arg, argv[7]->arg, VTY_NEWLINE); -      return CMD_WARNING; -    } - -  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%s", +			argv[5]->arg, argv[7]->arg, VTY_NEWLINE); +		return CMD_WARNING; +	} + +	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, @@ -3919,25 +3677,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%s", VTY_NEWLINE); -      return CMD_WARNING; -    } -  if (!bgp->rfapi_cfg) -    { -      vty_out (vty, "VNC not configured%s", VTY_NEWLINE); -      return CMD_WARNING; -    } - -  if (!strcmp (argv[3]->arg, "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%s", VTY_NEWLINE); +		return CMD_WARNING; +	} +	if (!bgp->rfapi_cfg) { +		vty_out(vty, "VNC not configured%s", VTY_NEWLINE); +		return CMD_WARNING; +	} + +	if (!strcmp(argv[3]->arg, "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;  } @@ -3950,9 +3708,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, @@ -3961,151 +3719,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;  }  /*------------------------------------------ @@ -4113,7 +3859,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)   * @@ -4125,19 +3871,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;  }  /*------------------------------------------ @@ -4145,7 +3891,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: @@ -4156,91 +3902,83 @@ 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%s", VTY_NEWLINE); -      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%s", +			VTY_NEWLINE); +		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%s", VTY_NEWLINE); -      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%s", +			VTY_NEWLINE); +		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 @@ -4249,46 +3987,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;  }  /*------------------------------------------ @@ -4297,9 +4032,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 @@ -4308,64 +4043,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 @@ -4376,46 +4103,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;  }  /*------------------------------------------ @@ -4426,7 +4148,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 @@ -4437,35 +4159,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;  }  | 
