summaryrefslogtreecommitdiffstats
path: root/bgpd/rfapi/rfapi.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/rfapi/rfapi.c')
-rw-r--r--bgpd/rfapi/rfapi.c6731
1 files changed, 3219 insertions, 3512 deletions
diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c
index a959b9827..3a2a608a7 100644
--- a/bgpd/rfapi/rfapi.c
+++ b/bgpd/rfapi/rfapi.c
@@ -1,4 +1,4 @@
-/*
+/*
*
* Copyright 2009-2016, LabN Consulting, L.L.C.
*
@@ -65,38 +65,36 @@
#include <execinfo.h>
#endif /* HAVE_GLIBC_BACKTRACE */
-struct ethaddr rfapi_ethaddr0 = { {0} };
+struct ethaddr rfapi_ethaddr0 = {{0}};
#define DEBUG_RFAPI_STR "RF API debugging/testing command\n"
-const char *
-rfapi_error_str (int code)
+const char *rfapi_error_str(int code)
{
- switch (code)
- {
- case 0:
- return "Success";
- case ENXIO:
- return "BGP or VNC not configured";
- case ENOENT:
- return "No match";
- case EEXIST:
- return "Handle already open";
- case ENOMSG:
- return "Incomplete configuration";
- case EAFNOSUPPORT:
- return "Invalid address family";
- case EDEADLK:
- return "Called from within a callback procedure";
- case EBADF:
- return "Invalid handle";
- case EINVAL:
- return "Invalid argument";
- case ESTALE:
- return "Stale descriptor";
- default:
- return "Unknown error";
- }
+ switch (code) {
+ case 0:
+ return "Success";
+ case ENXIO:
+ return "BGP or VNC not configured";
+ case ENOENT:
+ return "No match";
+ case EEXIST:
+ return "Handle already open";
+ case ENOMSG:
+ return "Incomplete configuration";
+ case EAFNOSUPPORT:
+ return "Invalid address family";
+ case EDEADLK:
+ return "Called from within a callback procedure";
+ case EBADF:
+ return "Invalid handle";
+ case EINVAL:
+ return "Invalid argument";
+ case ESTALE:
+ return "Stale descriptor";
+ default:
+ return "Unknown error";
+ }
}
/*------------------------------------------
@@ -106,20 +104,19 @@ rfapi_error_str (int code)
* rfp_start_val value returned by rfp_start or
* NULL (=use default instance)
*
- * input:
+ * input:
* None
*
* output:
*
* return value: The bgp instance default lifetime for a response.
--------------------------------------------*/
-int
-rfapi_get_response_lifetime_default (void *rfp_start_val)
+int rfapi_get_response_lifetime_default(void *rfp_start_val)
{
- struct bgp *bgp = rfapi_bgp_lookup_by_rfp (rfp_start_val);
- if (bgp)
- return bgp->rfapi_cfg->default_response_lifetime;
- return BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT;
+ struct bgp *bgp = rfapi_bgp_lookup_by_rfp(rfp_start_val);
+ if (bgp)
+ return bgp->rfapi_cfg->default_response_lifetime;
+ return BGP_VNC_DEFAULT_RESPONSE_LIFETIME_DEFAULT;
}
/*------------------------------------------
@@ -127,7 +124,7 @@ rfapi_get_response_lifetime_default (void *rfp_start_val)
*
* Returns if VNC (BGP VPN messaging /VPN & encap SAFIs) are configured
*
- * input:
+ * input:
* rfp_start_val value returned by rfp_start or
* NULL (=use default instance)
*
@@ -137,11 +134,10 @@ rfapi_get_response_lifetime_default (void *rfp_start_val)
* 0 Success
* ENXIO VNC not configured
--------------------------------------------*/
-int
-rfapi_is_vnc_configured (void *rfp_start_val)
+int rfapi_is_vnc_configured(void *rfp_start_val)
{
- struct bgp *bgp = rfapi_bgp_lookup_by_rfp (rfp_start_val);
- return bgp_rfapi_is_vnc_configured (bgp);
+ struct bgp *bgp = rfapi_bgp_lookup_by_rfp(rfp_start_val);
+ return bgp_rfapi_is_vnc_configured(bgp);
}
@@ -150,19 +146,18 @@ rfapi_is_vnc_configured (void *rfp_start_val)
*
* Get the virtual network address used by an NVE based on it's RFD
*
- * input:
+ * input:
* rfd: rfapi descriptor returned by rfapi_open or rfapi_create_generic
*
* output:
*
- * return value:
+ * return value:
* vn NVE virtual network address
*------------------------------------------*/
-struct rfapi_ip_addr *
-rfapi_get_vn_addr (void *rfd)
+struct rfapi_ip_addr *rfapi_get_vn_addr(void *rfd)
{
- struct rfapi_descriptor *rrfd = (struct rfapi_descriptor *) rfd;
- return &rrfd->vn_addr;
+ struct rfapi_descriptor *rrfd = (struct rfapi_descriptor *)rfd;
+ return &rrfd->vn_addr;
}
/*------------------------------------------
@@ -170,505 +165,459 @@ rfapi_get_vn_addr (void *rfd)
*
* Get the underlay network address used by an NVE based on it's RFD
*
- * input:
+ * input:
* rfd: rfapi descriptor returned by rfapi_open or rfapi_create_generic
*
* output:
*
- * return value:
+ * return value:
* un NVE underlay network address
*------------------------------------------*/
-struct rfapi_ip_addr *
-rfapi_get_un_addr (void *rfd)
+struct rfapi_ip_addr *rfapi_get_un_addr(void *rfd)
{
- struct rfapi_descriptor *rrfd = (struct rfapi_descriptor *) rfd;
- return &rrfd->un_addr;
+ struct rfapi_descriptor *rrfd = (struct rfapi_descriptor *)rfd;
+ return &rrfd->un_addr;
}
-int
-rfapi_ip_addr_cmp (struct rfapi_ip_addr *a1, struct rfapi_ip_addr *a2)
+int rfapi_ip_addr_cmp(struct rfapi_ip_addr *a1, struct rfapi_ip_addr *a2)
{
- if (a1->addr_family != a2->addr_family)
- return a1->addr_family - a2->addr_family;
+ if (a1->addr_family != a2->addr_family)
+ return a1->addr_family - a2->addr_family;
- if (a1->addr_family == AF_INET)
- {
- return IPV4_ADDR_CMP (&a1->addr.v4, &a2->addr.v4);
- }
+ if (a1->addr_family == AF_INET) {
+ return IPV4_ADDR_CMP(&a1->addr.v4, &a2->addr.v4);
+ }
- if (a1->addr_family == AF_INET6)
- {
- return IPV6_ADDR_CMP (&a1->addr.v6, &a2->addr.v6);
- }
+ if (a1->addr_family == AF_INET6) {
+ return IPV6_ADDR_CMP(&a1->addr.v6, &a2->addr.v6);
+ }
- assert (1);
- /* NOTREACHED */
- return 1;
+ assert(1);
+ /* NOTREACHED */
+ return 1;
}
-static int
-rfapi_find_node (
- struct bgp *bgp,
- struct rfapi_ip_addr *vn_addr,
- struct rfapi_ip_addr *un_addr,
- struct route_node **node)
+static int rfapi_find_node(struct bgp *bgp, struct rfapi_ip_addr *vn_addr,
+ struct rfapi_ip_addr *un_addr,
+ struct route_node **node)
{
- struct rfapi *h;
- struct prefix p;
- struct route_node *rn;
- int rc;
- int afi;
+ struct rfapi *h;
+ struct prefix p;
+ struct route_node *rn;
+ int rc;
+ int afi;
- if (!bgp)
- {
- return ENXIO;
- }
+ if (!bgp) {
+ return ENXIO;
+ }
- h = bgp->rfapi;
- if (!h)
- {
- return ENXIO;
- }
+ h = bgp->rfapi;
+ if (!h) {
+ return ENXIO;
+ }
- afi = family2afi (un_addr->addr_family);
- if (!afi)
- {
- return EAFNOSUPPORT;
- }
+ afi = family2afi(un_addr->addr_family);
+ if (!afi) {
+ return EAFNOSUPPORT;
+ }
- if ((rc = rfapiRaddr2Qprefix (un_addr, &p)))
- return rc;
+ if ((rc = rfapiRaddr2Qprefix(un_addr, &p)))
+ return rc;
- rn = route_node_lookup (&h->un[afi], &p);
+ rn = route_node_lookup(&h->un[afi], &p);
- if (!rn)
- return ENOENT;
+ if (!rn)
+ return ENOENT;
- route_unlock_node (rn);
+ route_unlock_node(rn);
- *node = rn;
+ *node = rn;
- return 0;
+ return 0;
}
-int
-rfapi_find_rfd (
- struct bgp *bgp,
- struct rfapi_ip_addr *vn_addr,
- struct rfapi_ip_addr *un_addr,
- struct rfapi_descriptor **rfd)
+int rfapi_find_rfd(struct bgp *bgp, struct rfapi_ip_addr *vn_addr,
+ struct rfapi_ip_addr *un_addr, struct rfapi_descriptor **rfd)
{
- struct route_node *rn;
- int rc;
+ struct route_node *rn;
+ int rc;
- rc = rfapi_find_node (bgp, vn_addr, un_addr, &rn);
+ rc = rfapi_find_node(bgp, vn_addr, un_addr, &rn);
- if (rc)
- return rc;
+ if (rc)
+ return rc;
- for (*rfd = (struct rfapi_descriptor *) (rn->info); *rfd;
- *rfd = (*rfd)->next)
- {
- if (!rfapi_ip_addr_cmp (&(*rfd)->vn_addr, vn_addr))
- break;
- }
+ for (*rfd = (struct rfapi_descriptor *)(rn->info); *rfd;
+ *rfd = (*rfd)->next) {
+ if (!rfapi_ip_addr_cmp(&(*rfd)->vn_addr, vn_addr))
+ break;
+ }
- if (!*rfd)
- return ENOENT;
+ if (!*rfd)
+ return ENOENT;
- return 0;
+ return 0;
}
/*------------------------------------------
* rfapi_find_handle
*
- * input:
+ * input:
* un underlay network address
* vn virtual network address
*
* output:
* pHandle pointer to location to store handle
*
- * return value:
+ * return value:
* 0 Success
* ENOENT no matching handle
* ENXIO BGP or VNC not configured
*------------------------------------------*/
-static int
-rfapi_find_handle (
- struct bgp *bgp,
- struct rfapi_ip_addr *vn_addr,
- struct rfapi_ip_addr *un_addr,
- rfapi_handle *handle)
+static int rfapi_find_handle(struct bgp *bgp, struct rfapi_ip_addr *vn_addr,
+ struct rfapi_ip_addr *un_addr,
+ rfapi_handle *handle)
{
- struct rfapi_descriptor **rfd;
+ struct rfapi_descriptor **rfd;
- rfd = (struct rfapi_descriptor **) handle;
+ rfd = (struct rfapi_descriptor **)handle;
- return rfapi_find_rfd (bgp, vn_addr, un_addr, rfd);
+ return rfapi_find_rfd(bgp, vn_addr, un_addr, rfd);
}
-static int
-rfapi_find_handle_vty (
- struct vty *vty,
- struct rfapi_ip_addr *vn_addr,
- struct rfapi_ip_addr *un_addr,
- rfapi_handle *handle)
+static int rfapi_find_handle_vty(struct vty *vty, struct rfapi_ip_addr *vn_addr,
+ struct rfapi_ip_addr *un_addr,
+ rfapi_handle *handle)
{
- struct bgp *bgp;
- struct rfapi_descriptor **rfd;
+ struct bgp *bgp;
+ struct rfapi_descriptor **rfd;
- bgp = bgp_get_default (); /* assume 1 instance for now */
+ bgp = bgp_get_default(); /* assume 1 instance for now */
- rfd = (struct rfapi_descriptor **) handle;
+ rfd = (struct rfapi_descriptor **)handle;
- return rfapi_find_rfd (bgp, vn_addr, un_addr, rfd);
+ return rfapi_find_rfd(bgp, vn_addr, un_addr, rfd);
}
-static int
-is_valid_rfd (struct rfapi_descriptor *rfd)
+static int is_valid_rfd(struct rfapi_descriptor *rfd)
{
- rfapi_handle hh;
+ rfapi_handle hh;
- if (!rfd || rfd->bgp == NULL)
- return 0;
+ if (!rfd || rfd->bgp == NULL)
+ return 0;
- if (CHECK_FLAG(rfd->flags, RFAPI_HD_FLAG_IS_VRF)) /* assume VRF/internal are valid */
- return 1;
+ if (CHECK_FLAG(
+ rfd->flags,
+ RFAPI_HD_FLAG_IS_VRF)) /* assume VRF/internal are valid */
+ return 1;
- if (rfapi_find_handle (rfd->bgp, &rfd->vn_addr, &rfd->un_addr, &hh))
- return 0;
+ if (rfapi_find_handle(rfd->bgp, &rfd->vn_addr, &rfd->un_addr, &hh))
+ return 0;
- if (rfd != hh)
- return 0;
+ if (rfd != hh)
+ return 0;
- return 1;
+ return 1;
}
/*
* check status of descriptor
*/
-int
-rfapi_check (void *handle)
+int rfapi_check(void *handle)
{
- struct rfapi_descriptor *rfd = (struct rfapi_descriptor *) handle;
- rfapi_handle hh;
- int rc;
+ struct rfapi_descriptor *rfd = (struct rfapi_descriptor *)handle;
+ rfapi_handle hh;
+ int rc;
- if (!rfd || rfd->bgp == NULL)
- return EINVAL;
+ if (!rfd || rfd->bgp == NULL)
+ return EINVAL;
- if (CHECK_FLAG(rfd->flags, RFAPI_HD_FLAG_IS_VRF)) /* assume VRF/internal are valid */
- return 0;
+ if (CHECK_FLAG(
+ rfd->flags,
+ RFAPI_HD_FLAG_IS_VRF)) /* assume VRF/internal are valid */
+ return 0;
- if ((rc = rfapi_find_handle (rfd->bgp, &rfd->vn_addr, &rfd->un_addr, &hh)))
- return rc;
+ if ((rc = rfapi_find_handle(rfd->bgp, &rfd->vn_addr, &rfd->un_addr,
+ &hh)))
+ return rc;
- if (rfd != hh)
- return ENOENT;
+ if (rfd != hh)
+ return ENOENT;
- if (!rfd->rfg)
- return ESTALE;
+ if (!rfd->rfg)
+ return ESTALE;
- return 0;
+ return 0;
}
-
-void
-del_vnc_route (
- struct rfapi_descriptor *rfd,
- struct peer *peer, /* rfd->peer for RFP regs */
- struct bgp *bgp,
- safi_t safi,
- struct prefix *p,
- struct prefix_rd *prd,
- uint8_t type,
- uint8_t sub_type,
- struct rfapi_nexthop *lnh,
- int kill)
+void del_vnc_route(struct rfapi_descriptor *rfd,
+ struct peer *peer, /* rfd->peer for RFP regs */
+ struct bgp *bgp, safi_t safi, struct prefix *p,
+ struct prefix_rd *prd, uint8_t type, uint8_t sub_type,
+ struct rfapi_nexthop *lnh, int kill)
{
- afi_t afi; /* of the VN address */
- struct bgp_node *bn;
- struct bgp_info *bi;
- char buf[BUFSIZ];
- char buf2[BUFSIZ];
- struct prefix_rd prd0;
-
- prefix2str (p, buf, BUFSIZ);
- buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */
-
- prefix_rd2str (prd, buf2, BUFSIZ);
- buf2[BUFSIZ - 1] = 0;
-
- afi = family2afi (p->family);
- assert (afi == AFI_IP || afi == AFI_IP6);
-
- if (safi == SAFI_ENCAP)
- {
- memset (&prd0, 0, sizeof (prd0));
- prd0.family = AF_UNSPEC;
- prd0.prefixlen = 64;
- prd = &prd0;
- }
- bn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
-
- vnc_zlog_debug_verbose
- ("%s: peer=%p, prefix=%s, prd=%s afi=%d, safi=%d bn=%p, bn->info=%p",
- __func__, peer, buf, buf2, afi, safi, bn, (bn ? bn->info : NULL));
-
- for (bi = (bn ? bn->info : NULL); bi; bi = bi->next)
- {
-
- vnc_zlog_debug_verbose
- ("%s: trying bi=%p, bi->peer=%p, bi->type=%d, bi->sub_type=%d, bi->extra->vnc.export.rfapi_handle=%p, local_pref=%u",
- __func__, bi, bi->peer, bi->type, bi->sub_type,
- (bi->extra ? bi->extra->vnc.export.rfapi_handle : NULL),
- ((bi->attr && CHECK_FLAG(bi->attr->flag, ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)))? bi->attr->local_pref: 0));
-
- if (bi->peer == peer &&
- bi->type == type &&
- bi->sub_type == sub_type &&
- bi->extra && bi->extra->vnc.export.rfapi_handle == (void *) rfd)
- {
-
- vnc_zlog_debug_verbose ("%s: matched it", __func__);
-
- break;
- }
- }
-
- if (lnh)
- {
- /*
- * lnh set means to JUST delete the local nexthop from this
- * route. Leave the route itself in place.
- * TBD add return code reporting of success/failure
- */
- if (!bi || !bi->extra || !bi->extra->vnc.export.local_nexthops)
- {
- /*
- * no local nexthops
- */
- vnc_zlog_debug_verbose ("%s: lnh list already empty at prefix %s",
- __func__, buf);
- goto done;
- }
-
- /*
- * look for it
- */
- struct listnode *node;
- struct rfapi_nexthop *pLnh = NULL;
-
- for (ALL_LIST_ELEMENTS_RO (bi->extra->vnc.export.local_nexthops,
- node, pLnh))
- {
-
- if (prefix_same (&pLnh->addr, &lnh->addr))
- {
- break;
- }
- }
-
- if (pLnh)
- {
- listnode_delete (bi->extra->vnc.export.local_nexthops, pLnh);
-
- /* silly rabbit, listnode_delete doesn't invoke list->del on data */
- rfapi_nexthop_free (pLnh);
- }
- else
- {
- vnc_zlog_debug_verbose ("%s: desired lnh not found %s", __func__, buf);
- }
- goto done;
- }
-
- /*
- * loop back to import tables
- * Do this before removing from BGP RIB because rfapiProcessWithdraw
- * might refer to it
- */
- rfapiProcessWithdraw (peer, rfd, p, prd, NULL, afi, safi, type, kill);
-
- if (bi)
- {
- char buf[BUFSIZ];
-
- prefix2str (p, buf, BUFSIZ);
- buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */
-
- vnc_zlog_debug_verbose ("%s: Found route (safi=%d) to delete at prefix %s",
- __func__, safi, buf);
-
- if (safi == SAFI_MPLS_VPN)
- {
- struct bgp_node *prn = NULL;
- struct bgp_table *table = NULL;
-
- prn = bgp_node_get (bgp->rib[afi][safi], (struct prefix *) prd);
- if (prn->info)
- {
- table = (struct bgp_table *) (prn->info);
-
- vnc_import_bgp_del_vnc_host_route_mode_resolve_nve (bgp,
- prd,
- table,
- p, bi);
- }
- bgp_unlock_node (prn);
- }
-
- /*
- * Delete local_nexthops list
- */
- if (bi->extra && bi->extra->vnc.export.local_nexthops)
- {
- list_delete (bi->extra->vnc.export.local_nexthops);
- }
-
- bgp_aggregate_decrement (bgp, p, bi, afi, safi);
- bgp_info_delete (bn, bi);
- bgp_process (bgp, bn, afi, safi);
- }
- else
- {
- vnc_zlog_debug_verbose ("%s: Couldn't find route (safi=%d) at prefix %s",
- __func__, safi, buf);
- }
+ afi_t afi; /* of the VN address */
+ struct bgp_node *bn;
+ struct bgp_info *bi;
+ char buf[BUFSIZ];
+ char buf2[BUFSIZ];
+ struct prefix_rd prd0;
+
+ prefix2str(p, buf, BUFSIZ);
+ buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */
+
+ prefix_rd2str(prd, buf2, BUFSIZ);
+ buf2[BUFSIZ - 1] = 0;
+
+ afi = family2afi(p->family);
+ assert(afi == AFI_IP || afi == AFI_IP6);
+
+ if (safi == SAFI_ENCAP) {
+ memset(&prd0, 0, sizeof(prd0));
+ prd0.family = AF_UNSPEC;
+ prd0.prefixlen = 64;
+ prd = &prd0;
+ }
+ bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
+
+ vnc_zlog_debug_verbose(
+ "%s: peer=%p, prefix=%s, prd=%s afi=%d, safi=%d bn=%p, bn->info=%p",
+ __func__, peer, buf, buf2, afi, safi, bn,
+ (bn ? bn->info : NULL));
+
+ for (bi = (bn ? bn->info : NULL); bi; bi = bi->next) {
+
+ vnc_zlog_debug_verbose(
+ "%s: trying bi=%p, bi->peer=%p, bi->type=%d, bi->sub_type=%d, bi->extra->vnc.export.rfapi_handle=%p, local_pref=%u",
+ __func__, bi, bi->peer, bi->type, bi->sub_type,
+ (bi->extra ? bi->extra->vnc.export.rfapi_handle : NULL),
+ ((bi->attr
+ && CHECK_FLAG(bi->attr->flag,
+ ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))
+ ? bi->attr->local_pref
+ : 0));
+
+ if (bi->peer == peer && bi->type == type
+ && bi->sub_type == sub_type && bi->extra
+ && bi->extra->vnc.export.rfapi_handle == (void *)rfd) {
+
+ vnc_zlog_debug_verbose("%s: matched it", __func__);
+
+ break;
+ }
+ }
+
+ if (lnh) {
+ /*
+ * lnh set means to JUST delete the local nexthop from this
+ * route. Leave the route itself in place.
+ * TBD add return code reporting of success/failure
+ */
+ if (!bi || !bi->extra
+ || !bi->extra->vnc.export.local_nexthops) {
+ /*
+ * no local nexthops
+ */
+ vnc_zlog_debug_verbose(
+ "%s: lnh list already empty at prefix %s",
+ __func__, buf);
+ goto done;
+ }
+
+ /*
+ * look for it
+ */
+ struct listnode *node;
+ struct rfapi_nexthop *pLnh = NULL;
+
+ for (ALL_LIST_ELEMENTS_RO(bi->extra->vnc.export.local_nexthops,
+ node, pLnh)) {
+
+ if (prefix_same(&pLnh->addr, &lnh->addr)) {
+ break;
+ }
+ }
+
+ if (pLnh) {
+ listnode_delete(bi->extra->vnc.export.local_nexthops,
+ pLnh);
+
+ /* silly rabbit, listnode_delete doesn't invoke
+ * list->del on data */
+ rfapi_nexthop_free(pLnh);
+ } else {
+ vnc_zlog_debug_verbose("%s: desired lnh not found %s",
+ __func__, buf);
+ }
+ goto done;
+ }
+
+ /*
+ * loop back to import tables
+ * Do this before removing from BGP RIB because rfapiProcessWithdraw
+ * might refer to it
+ */
+ rfapiProcessWithdraw(peer, rfd, p, prd, NULL, afi, safi, type, kill);
+
+ if (bi) {
+ char buf[BUFSIZ];
+
+ prefix2str(p, buf, BUFSIZ);
+ buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */
+
+ vnc_zlog_debug_verbose(
+ "%s: Found route (safi=%d) to delete at prefix %s",
+ __func__, safi, buf);
+
+ if (safi == SAFI_MPLS_VPN) {
+ struct bgp_node *prn = NULL;
+ struct bgp_table *table = NULL;
+
+ prn = bgp_node_get(bgp->rib[afi][safi],
+ (struct prefix *)prd);
+ if (prn->info) {
+ table = (struct bgp_table *)(prn->info);
+
+ vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
+ bgp, prd, table, p, bi);
+ }
+ bgp_unlock_node(prn);
+ }
+
+ /*
+ * Delete local_nexthops list
+ */
+ if (bi->extra && bi->extra->vnc.export.local_nexthops) {
+ list_delete(bi->extra->vnc.export.local_nexthops);
+ }
+
+ bgp_aggregate_decrement(bgp, p, bi, afi, safi);
+ bgp_info_delete(bn, bi);
+ bgp_process(bgp, bn, afi, safi);
+ } else {
+ vnc_zlog_debug_verbose(
+ "%s: Couldn't find route (safi=%d) at prefix %s",
+ __func__, safi, buf);
+ }
done:
- bgp_unlock_node (bn);
+ bgp_unlock_node(bn);
}
-struct rfapi_nexthop *
-rfapi_nexthop_new (struct rfapi_nexthop *copyme)
+struct rfapi_nexthop *rfapi_nexthop_new(struct rfapi_nexthop *copyme)
{
- struct rfapi_nexthop *new =
- XCALLOC (MTYPE_RFAPI_NEXTHOP, sizeof (struct rfapi_nexthop));
- if (copyme)
- *new = *copyme;
- return new;
+ struct rfapi_nexthop *new =
+ XCALLOC(MTYPE_RFAPI_NEXTHOP, sizeof(struct rfapi_nexthop));
+ if (copyme)
+ *new = *copyme;
+ return new;
}
-void
-rfapi_nexthop_free (void *p)
+void rfapi_nexthop_free(void *p)
{
- struct rfapi_nexthop *goner = p;
- XFREE (MTYPE_RFAPI_NEXTHOP, goner);
+ struct rfapi_nexthop *goner = p;
+ XFREE(MTYPE_RFAPI_NEXTHOP, goner);
}
-struct rfapi_vn_option *
-rfapi_vn_options_dup (struct rfapi_vn_option *existing)
+struct rfapi_vn_option *rfapi_vn_options_dup(struct rfapi_vn_option *existing)
{
- struct rfapi_vn_option *p;
- struct rfapi_vn_option *head = NULL;
- struct rfapi_vn_option *tail = NULL;
-
- for (p = existing; p; p = p->next)
- {
- struct rfapi_vn_option *new;
-
- new = XCALLOC (MTYPE_RFAPI_VN_OPTION, sizeof (struct rfapi_vn_option));
- *new = *p;
- new->next = NULL;
- if (tail)
- (tail)->next = new;
- tail = new;
- if (!head)
- {
- head = new;
- }
- }
- return head;
+ struct rfapi_vn_option *p;
+ struct rfapi_vn_option *head = NULL;
+ struct rfapi_vn_option *tail = NULL;
+
+ for (p = existing; p; p = p->next) {
+ struct rfapi_vn_option *new;
+
+ new = XCALLOC(MTYPE_RFAPI_VN_OPTION,
+ sizeof(struct rfapi_vn_option));
+ *new = *p;
+ new->next = NULL;
+ if (tail)
+ (tail)->next = new;
+ tail = new;
+ if (!head) {
+ head = new;
+ }
+ }
+ return head;
}
-void
-rfapi_un_options_free (struct rfapi_un_option *p)
+void rfapi_un_options_free(struct rfapi_un_option *p)
{
- struct rfapi_un_option *next;
+ struct rfapi_un_option *next;
- while (p)
- {
- next = p->next;
- XFREE (MTYPE_RFAPI_UN_OPTION, p);
- p = next;
- }
+ while (p) {
+ next = p->next;
+ XFREE(MTYPE_RFAPI_UN_OPTION, p);
+ p = next;
+ }
}
-void
-rfapi_vn_options_free (struct rfapi_vn_option *p)
+void rfapi_vn_options_free(struct rfapi_vn_option *p)
{
- struct rfapi_vn_option *next;
+ struct rfapi_vn_option *next;
- while (p)
- {
- next = p->next;
- XFREE (MTYPE_RFAPI_VN_OPTION, p);
- p = next;
- }
+ while (p) {
+ next = p->next;
+ XFREE(MTYPE_RFAPI_VN_OPTION, p);
+ p = next;
+ }
}
/* Based on bgp_redistribute_add() */
-void
-add_vnc_route (
- struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
- struct bgp *bgp,
- int safi,
- struct prefix *p,
- struct prefix_rd *prd,
- struct rfapi_ip_addr *nexthop,
- uint32_t *local_pref,
- uint32_t *lifetime, /* NULL => dont send lifetime */
- struct bgp_tea_options *rfp_options,
- struct rfapi_un_option *options_un,
- struct rfapi_vn_option *options_vn,
- struct ecommunity *rt_export_list,/* Copied, not consumed */
- uint32_t *med, /* NULL => don't set med */
- uint32_t *label, /* low order 3 bytes */
- uint8_t type,
- uint8_t sub_type, /* RFP, NORMAL or REDIST */
- int flags)
+void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
+ struct bgp *bgp, int safi, struct prefix *p,
+ struct prefix_rd *prd, struct rfapi_ip_addr *nexthop,
+ uint32_t *local_pref,
+ uint32_t *lifetime, /* NULL => dont send lifetime */
+ struct bgp_tea_options *rfp_options,
+ struct rfapi_un_option *options_un,
+ struct rfapi_vn_option *options_vn,
+ struct ecommunity *rt_export_list, /* Copied, not consumed */
+ uint32_t *med, /* NULL => don't set med */
+ uint32_t *label, /* low order 3 bytes */
+ uint8_t type, uint8_t sub_type, /* RFP, NORMAL or REDIST */
+ int flags)
{
- afi_t afi; /* of the VN address */
- struct bgp_info *new;
- struct bgp_info *bi;
- struct bgp_node *bn;
-
- struct attr attr = { 0 };
- struct attr *new_attr;
- uint32_t label_val;
-
- struct bgp_attr_encap_subtlv *encaptlv;
- char buf[BUFSIZ];
- char buf2[BUFSIZ];
-#if 0 /* unused? */
+ afi_t afi; /* of the VN address */
+ struct bgp_info *new;
+ struct bgp_info *bi;
+ struct bgp_node *bn;
+
+ struct attr attr = {0};
+ struct attr *new_attr;
+ uint32_t label_val;
+
+ struct bgp_attr_encap_subtlv *encaptlv;
+ char buf[BUFSIZ];
+ char buf2[BUFSIZ];
+#if 0 /* unused? */
struct prefix pfx_buf;
#endif
- struct rfapi_nexthop *lnh = NULL; /* local nexthop */
- struct rfapi_vn_option *vo;
- struct rfapi_l2address_option *l2o = NULL;
- struct rfapi_ip_addr *un_addr = &rfd->un_addr;
+ struct rfapi_nexthop *lnh = NULL; /* local nexthop */
+ struct rfapi_vn_option *vo;
+ struct rfapi_l2address_option *l2o = NULL;
+ struct rfapi_ip_addr *un_addr = &rfd->un_addr;
- bgp_encap_types TunnelType = BGP_ENCAP_TYPE_RESERVED;
- struct bgp_redist *red;
+ bgp_encap_types TunnelType = BGP_ENCAP_TYPE_RESERVED;
+ struct bgp_redist *red;
- if (safi == SAFI_ENCAP &&
- !(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP))
- {
+ if (safi == SAFI_ENCAP
+ && !(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_ADV_UN_METHOD_ENCAP)) {
- /*
- * Encap mode not enabled. UN addresses will be communicated
- * via VNC Tunnel subtlv instead.
- */
- vnc_zlog_debug_verbose ("%s: encap mode not enabled, not adding SAFI_ENCAP route",
- __func__);
- return;
- }
+ /*
+ * Encap mode not enabled. UN addresses will be communicated
+ * via VNC Tunnel subtlv instead.
+ */
+ vnc_zlog_debug_verbose(
+ "%s: encap mode not enabled, not adding SAFI_ENCAP route",
+ __func__);
+ return;
+ }
-#if 0 /* unused? */
+#if 0 /* unused? */
if ((safi == SAFI_MPLS_VPN) && (flags & RFAPI_AHR_SET_PFX_TO_NEXTHOP))
{
@@ -682,579 +631,542 @@ add_vnc_route (
p = &pfx_buf;
}
#endif
- for (vo = options_vn; vo; vo = vo->next)
- {
- if (RFAPI_VN_OPTION_TYPE_L2ADDR == vo->type)
- {
- l2o = &vo->v.l2addr;
- if (RFAPI_0_ETHERADDR (&l2o->macaddr))
- l2o = NULL; /* not MAC resolution */
- }
- if (RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP == vo->type)
- {
- lnh = &vo->v.local_nexthop;
- }
- }
-
- if (label)
- label_val = *label;
- else
- label_val = MPLS_LABEL_IMPLICIT_NULL;
-
- prefix_rd2str (prd, buf2, BUFSIZ);
- buf2[BUFSIZ - 1] = 0;
-
-
- afi = family2afi (p->family);
- assert (afi == AFI_IP || afi == AFI_IP6);
-
- vnc_zlog_debug_verbose ("%s: afi=%s, safi=%s", __func__, afi2str (afi),
- safi2str (safi));
-
- /* Make default attribute. Produces already-interned attr.aspath */
- /* Cripes, the memory management of attributes is byzantine */
-
- bgp_attr_default_set (&attr, BGP_ORIGIN_INCOMPLETE);
-
- /*
- * At this point:
- * attr: static
- * extra: dynamically allocated, owned by attr
- * aspath: points to interned hash from aspath hash table
- */
-
-
- /*
- * Route-specific un_options get added to the VPN SAFI
- * advertisement tunnel encap attribute. (the per-NVE
- * "default" un_options are put into the 1-per-NVE ENCAP
- * SAFI advertisement). The VPN SAFI also gets the
- * default un_options if there are no route-specific options.
- */
- if (options_un)
- {
- struct rfapi_un_option *uo;
-
- for (uo = options_un; uo; uo = uo->next)
- {
- if (RFAPI_UN_OPTION_TYPE_TUNNELTYPE == uo->type)
- {
- TunnelType = rfapi_tunneltype_option_to_tlv (
- bgp, un_addr, &uo->v.tunnel, &attr, l2o != NULL);
- }
- }
- }
- else
- {
- /*
- * Add encap attr
- * These are the NVE-specific "default" un_options which are
- * put into the 1-per-NVE ENCAP advertisement.
- */
- if (rfd->default_tunneltype_option.type)
- {
- TunnelType = rfapi_tunneltype_option_to_tlv (
- bgp, un_addr, &rfd->default_tunneltype_option, &attr,
- l2o != NULL);
- }
- else /* create default for local addse */
- if (type == ZEBRA_ROUTE_BGP && sub_type == BGP_ROUTE_RFP)
- TunnelType =
- rfapi_tunneltype_option_to_tlv (bgp, un_addr, NULL,
- &attr, l2o != NULL);
- }
-
- if (TunnelType == BGP_ENCAP_TYPE_MPLS)
- {
- if (safi == SAFI_ENCAP)
- {
- /* Encap SAFI not used with MPLS */
- vnc_zlog_debug_verbose ("%s: mpls tunnel type, encap safi omitted", __func__);
- aspath_unintern (&attr.aspath); /* Unintern original. */
- return;
- }
- }
-
- if (local_pref)
- {
- attr.local_pref = *local_pref;
- attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
- }
-
- if (med)
- {
- attr.med = *med;
- attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
- }
-
- /* override default weight assigned by bgp_attr_default_set() */
- attr.weight = rfd->peer ? rfd->peer->weight[afi][safi] : 0;
-
- /*
- * NB: ticket 81: do not reset attr.aspath here because it would
- * cause iBGP peers to drop route
- */
-
- /*
- * Set originator ID for routes imported from BGP directly.
- * These routes could be synthetic, and therefore could
- * reuse the peer pointers of the routes they are derived
- * from. Setting the originator ID to "us" prevents the
- * wrong originator ID from being sent when this route is
- * sent from a route reflector.
- */
- if (type == ZEBRA_ROUTE_BGP_DIRECT || type == ZEBRA_ROUTE_BGP_DIRECT_EXT)
- {
- attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID);
- attr.originator_id = bgp->router_id;
- }
-
-
- /* Set up vnc attribute (sub-tlv for Prefix Lifetime) */
- if (lifetime && *lifetime != RFAPI_INFINITE_LIFETIME)
- {
- uint32_t lt;
-
- encaptlv =
- XCALLOC (MTYPE_ENCAP_TLV,
- sizeof (struct bgp_attr_encap_subtlv) - 1 + 4);
- assert (encaptlv);
- encaptlv->type = BGP_VNC_SUBTLV_TYPE_LIFETIME; /* prefix lifetime */
- encaptlv->length = 4;
- lt = htonl (*lifetime);
- memcpy (encaptlv->value, &lt, 4);
- attr.vnc_subtlvs = encaptlv;
- vnc_zlog_debug_verbose ("%s: set Encap Attr Prefix Lifetime to %d",
- __func__, *lifetime);
- }
-
- /* add rfp options to vnc attr */
- if (rfp_options)
- {
-
- if (flags & RFAPI_AHR_RFPOPT_IS_VNCTLV)
- {
-
- /*
- * this flag means we're passing a pointer to an
- * existing encap tlv chain which we should copy.
- * It's a hack to avoid adding yet another argument
- * to add_vnc_route()
- */
- encaptlv =
- encap_tlv_dup ((struct bgp_attr_encap_subtlv *) rfp_options);
- if (attr.vnc_subtlvs)
- {
- attr.vnc_subtlvs->next = encaptlv;
- }
- else
- {
- attr.vnc_subtlvs = encaptlv;
- }
-
- }
- else
- {
- struct bgp_tea_options *hop;
- /* XXX max of one tlv present so far from above code */
- struct bgp_attr_encap_subtlv *tail = attr.vnc_subtlvs;
-
- for (hop = rfp_options; hop; hop = hop->next)
- {
-
- /*
- * Construct subtlv
- */
- encaptlv = XCALLOC (MTYPE_ENCAP_TLV,
- sizeof (struct bgp_attr_encap_subtlv) - 1 +
- 2 + hop->length);
- assert (encaptlv);
- encaptlv->type = BGP_VNC_SUBTLV_TYPE_RFPOPTION; /* RFP option */
- encaptlv->length = 2 + hop->length;
- *((uint8_t *) (encaptlv->value) + 0) = hop->type;
- *((uint8_t *) (encaptlv->value) + 1) = hop->length;
- memcpy (((uint8_t *) encaptlv->value) + 2, hop->value,
- hop->length);
-
- /*
- * add to end of subtlv chain
- */
- if (tail)
- {
- tail->next = encaptlv;
- }
- else
- {
- attr.vnc_subtlvs = encaptlv;
- }
- tail = encaptlv;
- }
- }
- }
-
- /*
- * At this point:
- * attr: static
- * extra: dynamically allocated, owned by attr
- * vnc_subtlvs: dynamic chain, length 1
- * aspath: points to interned hash from aspath hash table
- */
-
-
- attr.ecommunity = ecommunity_new ();
- assert (attr.ecommunity);
-
- if (TunnelType != BGP_ENCAP_TYPE_MPLS &&
- TunnelType != BGP_ENCAP_TYPE_RESERVED)
- {
- /*
- * Add BGP Encapsulation Extended Community. Format described in
- * section 4.5 of RFC 5512.
- * Always include when not MPLS type, to disambiguate this case.
- */
- struct ecommunity_val beec;
-
- memset (&beec, 0, sizeof (beec));
- beec.val[0] = ECOMMUNITY_ENCODE_OPAQUE;
- beec.val[1] = ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP;
- beec.val[6] = ((TunnelType) >> 8) & 0xff;
- beec.val[7] = (TunnelType) & 0xff;
- ecommunity_add_val (attr.ecommunity, &beec);
- }
-
- /*
- * Add extended community attributes to match rt export list
- */
- if (rt_export_list)
- {
- attr.ecommunity =
- ecommunity_merge (attr.ecommunity, rt_export_list);
- }
-
- if (attr.ecommunity->size)
- {
- attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
- }
- else
- {
- ecommunity_free (&attr.ecommunity);
- attr.ecommunity = NULL;
- }
- vnc_zlog_debug_verbose ("%s: attr.ecommunity=%p", __func__,
- attr.ecommunity);
-
-
- /*
- * At this point:
- * attr: static
- * extra: dynamically allocated, owned by attr
- * vnc_subtlvs: dynamic chain, length 1
- * ecommunity: dynamic 2-part
- * aspath: points to interned hash from aspath hash table
- */
-
- /* stuff nexthop in attr_extra; which field depends on IPv4 or IPv6 */
- switch (nexthop->addr_family)
- {
- case AF_INET:
- /*
- * set this field to prevent bgp_route.c code from setting
- * mp_nexthop_global_in to self
- */
- attr.nexthop.s_addr = nexthop->addr.v4.s_addr;
-
- attr.mp_nexthop_global_in = nexthop->addr.v4;
- attr.mp_nexthop_len = 4;
- break;
-
- case AF_INET6:
- attr.mp_nexthop_global = nexthop->addr.v6;
- attr.mp_nexthop_len = 16;
- break;
-
- default:
- assert (0);
- }
-
-
- prefix2str (p, buf, BUFSIZ);
- buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */
-
- /*
- * At this point:
- *
- * attr: static
- * extra: dynamically allocated, owned by attr
- * vnc_subtlvs: dynamic chain, length 1
- * ecommunity: dynamic 2-part
- * aspath: points to interned hash from aspath hash table
- */
-
- red = bgp_redist_lookup(bgp, afi, type, VRF_DEFAULT);
-
- if (red && red->redist_metric_flag)
- {
- attr.med = red->redist_metric;
- attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
- }
-
- bn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
-
- /*
- * bgp_attr_intern creates a new reference to a cached
- * attribute, but leaves the following bits of trash:
- * - old attr
- * - old attr->extra (free via bgp_attr_extra_free(attr))
- *
- * Note that it frees the original attr->extra->ecommunity
- * but leaves the new attribute pointing to the ORIGINAL
- * vnc options (which therefore we needn't free from the
- * static attr)
- */
- new_attr = bgp_attr_intern (&attr);
-
- aspath_unintern (&attr.aspath); /* Unintern original. */
-
- /*
- * At this point:
- *
- * attr: static
- * extra: dynamically allocated, owned by attr
- * vnc_subtlvs: dynamic chain, length 1
- * ecommunity: POINTS TO INTERNED ecom, THIS REF NOT COUNTED
- *
- * new_attr: an attr that is part of the hash table, distinct
- * from attr which is static.
- * extra: dynamically allocated, owned by new_attr (in hash table)
- * vnc_subtlvs: POINTS TO SAME dynamic chain AS attr
- * ecommunity: POINTS TO interned/refcounted dynamic 2-part AS attr
- * aspath: POINTS TO interned/refcounted hashed block
- */
- for (bi = bn->info; bi; bi = bi->next)
- {
- /* probably only need to check bi->extra->vnc.export.rfapi_handle */
- if (bi->peer == rfd->peer &&
- bi->type == type &&
- bi->sub_type == sub_type &&
- bi->extra && bi->extra->vnc.export.rfapi_handle == (void *) rfd)
- {
-
- break;
- }
- }
-
- if (bi)
- {
-
- /*
- * Adding new local_nexthop, which does not by itself change
- * what is advertised via BGP
- */
- if (lnh)
- {
- if (!bi->extra->vnc.export.local_nexthops)
- {
- /* TBD make arrangements to free when needed */
- bi->extra->vnc.export.local_nexthops = list_new ();
- bi->extra->vnc.export.local_nexthops->del = rfapi_nexthop_free;
- }
-
- /*
- * already present?
- */
- struct listnode *node;
- struct rfapi_nexthop *pLnh = NULL;
-
- for (ALL_LIST_ELEMENTS_RO (bi->extra->vnc.export.local_nexthops,
- node, pLnh))
- {
-
- if (prefix_same (&pLnh->addr, &lnh->addr))
- {
- break;
- }
- }
-
- /*
- * Not present, add new one
- */
- if (!pLnh)
- {
- pLnh = rfapi_nexthop_new (lnh);
- listnode_add (bi->extra->vnc.export.local_nexthops, pLnh);
- }
- }
-
- if (attrhash_cmp (bi->attr, new_attr) &&
- !CHECK_FLAG (bi->flags, BGP_INFO_REMOVED))
- {
- bgp_attr_unintern (&new_attr);
- bgp_unlock_node (bn);
-
- vnc_zlog_debug_any ("%s: Found route (safi=%d) at prefix %s, no change",
- __func__, safi, buf);
-
- goto done;
- }
- else
- {
- /* The attribute is changed. */
- bgp_info_set_flag (bn, bi, BGP_INFO_ATTR_CHANGED);
-
- if (safi == SAFI_MPLS_VPN)
- {
- struct bgp_node *prn = NULL;
- struct bgp_table *table = NULL;
-
- prn = bgp_node_get (bgp->rib[afi][safi], (struct prefix *) prd);
- if (prn->info)
- {
- table = (struct bgp_table *) (prn->info);
-
- vnc_import_bgp_del_vnc_host_route_mode_resolve_nve (
- bgp, prd, table, p, bi);
- }
- bgp_unlock_node (prn);
- }
-
- /* Rewrite BGP route information. */
- if (CHECK_FLAG (bi->flags, BGP_INFO_REMOVED))
- bgp_info_restore (bn, bi);
- else
- bgp_aggregate_decrement (bgp, p, bi, afi, safi);
- bgp_attr_unintern (&bi->attr);
- bi->attr = new_attr;
- bi->uptime = bgp_clock ();
-
-
- if (safi == SAFI_MPLS_VPN)
- {
- struct bgp_node *prn = NULL;
- struct bgp_table *table = NULL;
-
- prn = bgp_node_get (bgp->rib[afi][safi], (struct prefix *) prd);
- if (prn->info)
- {
- table = (struct bgp_table *) (prn->info);
-
- vnc_import_bgp_add_vnc_host_route_mode_resolve_nve (
- bgp, prd, table, p, bi);
- }
- bgp_unlock_node (prn);
- }
-
- /* Process change. */
- bgp_aggregate_increment (bgp, p, bi, afi, safi);
- bgp_process (bgp, bn, afi, safi);
- bgp_unlock_node (bn);
-
- vnc_zlog_debug_any ("%s: Found route (safi=%d) at prefix %s, changed attr",
- __func__, safi, buf);
-
- goto done;
- }
- }
-
-
- new = bgp_info_new ();
- new->type = type;
- new->sub_type = sub_type;
- new->peer = rfd->peer;
- SET_FLAG (new->flags, BGP_INFO_VALID);
- new->attr = new_attr;
- new->uptime = bgp_clock ();
-
- /* save backref to rfapi handle */
- assert (bgp_info_extra_get (new));
- new->extra->vnc.export.rfapi_handle = (void *) rfd;
- encode_label (label_val, &new->extra->label);
-
- /* debug */
-
- if (VNC_DEBUG(VERBOSE))
- {
- vnc_zlog_debug_verbose ("%s: printing BI", __func__);
- rfapiPrintBi (NULL, new);
- }
-
- bgp_aggregate_increment (bgp, p, new, afi, safi);
- bgp_info_add (bn, new);
-
- if (safi == SAFI_MPLS_VPN)
- {
- struct bgp_node *prn = NULL;
- struct bgp_table *table = NULL;
-
- prn = bgp_node_get (bgp->rib[afi][safi], (struct prefix *) prd);
- if (prn->info)
- {
- table = (struct bgp_table *) (prn->info);
-
- vnc_import_bgp_add_vnc_host_route_mode_resolve_nve (
- bgp, prd, table, p, new);
- }
- bgp_unlock_node (prn);
- encode_label (label_val, &bn->local_label);
- }
-
- bgp_unlock_node (bn);
- bgp_process (bgp, bn, afi, safi);
-
- vnc_zlog_debug_any ("%s: Added route (safi=%s) at prefix %s (bn=%p, prd=%s)",
- __func__, safi2str (safi), buf, bn, buf2);
+ for (vo = options_vn; vo; vo = vo->next) {
+ if (RFAPI_VN_OPTION_TYPE_L2ADDR == vo->type) {
+ l2o = &vo->v.l2addr;
+ if (RFAPI_0_ETHERADDR(&l2o->macaddr))
+ l2o = NULL; /* not MAC resolution */
+ }
+ if (RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP == vo->type) {
+ lnh = &vo->v.local_nexthop;
+ }
+ }
+
+ if (label)
+ label_val = *label;
+ else
+ label_val = MPLS_LABEL_IMPLICIT_NULL;
+
+ prefix_rd2str(prd, buf2, BUFSIZ);
+ buf2[BUFSIZ - 1] = 0;
+
+
+ afi = family2afi(p->family);
+ assert(afi == AFI_IP || afi == AFI_IP6);
+
+ vnc_zlog_debug_verbose("%s: afi=%s, safi=%s", __func__, afi2str(afi),
+ safi2str(safi));
+
+ /* Make default attribute. Produces already-interned attr.aspath */
+ /* Cripes, the memory management of attributes is byzantine */
+
+ bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE);
+
+ /*
+ * At this point:
+ * attr: static
+ * extra: dynamically allocated, owned by attr
+ * aspath: points to interned hash from aspath hash table
+ */
+
+
+ /*
+ * Route-specific un_options get added to the VPN SAFI
+ * advertisement tunnel encap attribute. (the per-NVE
+ * "default" un_options are put into the 1-per-NVE ENCAP
+ * SAFI advertisement). The VPN SAFI also gets the
+ * default un_options if there are no route-specific options.
+ */
+ if (options_un) {
+ struct rfapi_un_option *uo;
+
+ for (uo = options_un; uo; uo = uo->next) {
+ if (RFAPI_UN_OPTION_TYPE_TUNNELTYPE == uo->type) {
+ TunnelType = rfapi_tunneltype_option_to_tlv(
+ bgp, un_addr, &uo->v.tunnel, &attr,
+ l2o != NULL);
+ }
+ }
+ } else {
+ /*
+ * Add encap attr
+ * These are the NVE-specific "default" un_options which are
+ * put into the 1-per-NVE ENCAP advertisement.
+ */
+ if (rfd->default_tunneltype_option.type) {
+ TunnelType = rfapi_tunneltype_option_to_tlv(
+ bgp, un_addr, &rfd->default_tunneltype_option,
+ &attr, l2o != NULL);
+ } else /* create default for local addse */
+ if (type == ZEBRA_ROUTE_BGP
+ && sub_type == BGP_ROUTE_RFP)
+ TunnelType = rfapi_tunneltype_option_to_tlv(
+ bgp, un_addr, NULL, &attr, l2o != NULL);
+ }
+
+ if (TunnelType == BGP_ENCAP_TYPE_MPLS) {
+ if (safi == SAFI_ENCAP) {
+ /* Encap SAFI not used with MPLS */
+ vnc_zlog_debug_verbose(
+ "%s: mpls tunnel type, encap safi omitted",
+ __func__);
+ aspath_unintern(&attr.aspath); /* Unintern original. */
+ return;
+ }
+ }
+
+ if (local_pref) {
+ attr.local_pref = *local_pref;
+ attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
+ }
+
+ if (med) {
+ attr.med = *med;
+ attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
+ }
+
+ /* override default weight assigned by bgp_attr_default_set() */
+ attr.weight = rfd->peer ? rfd->peer->weight[afi][safi] : 0;
+
+ /*
+ * NB: ticket 81: do not reset attr.aspath here because it would
+ * cause iBGP peers to drop route
+ */
+
+ /*
+ * Set originator ID for routes imported from BGP directly.
+ * These routes could be synthetic, and therefore could
+ * reuse the peer pointers of the routes they are derived
+ * from. Setting the originator ID to "us" prevents the
+ * wrong originator ID from being sent when this route is
+ * sent from a route reflector.
+ */
+ if (type == ZEBRA_ROUTE_BGP_DIRECT
+ || type == ZEBRA_ROUTE_BGP_DIRECT_EXT) {
+ attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID);
+ attr.originator_id = bgp->router_id;
+ }
+
+
+ /* Set up vnc attribute (sub-tlv for Prefix Lifetime) */
+ if (lifetime && *lifetime != RFAPI_INFINITE_LIFETIME) {
+ uint32_t lt;
+
+ encaptlv =
+ XCALLOC(MTYPE_ENCAP_TLV,
+ sizeof(struct bgp_attr_encap_subtlv) - 1 + 4);
+ assert(encaptlv);
+ encaptlv->type =
+ BGP_VNC_SUBTLV_TYPE_LIFETIME; /* prefix lifetime */
+ encaptlv->length = 4;
+ lt = htonl(*lifetime);
+ memcpy(encaptlv->value, &lt, 4);
+ attr.vnc_subtlvs = encaptlv;
+ vnc_zlog_debug_verbose(
+ "%s: set Encap Attr Prefix Lifetime to %d", __func__,
+ *lifetime);
+ }
+
+ /* add rfp options to vnc attr */
+ if (rfp_options) {
+
+ if (flags & RFAPI_AHR_RFPOPT_IS_VNCTLV) {
+
+ /*
+ * this flag means we're passing a pointer to an
+ * existing encap tlv chain which we should copy.
+ * It's a hack to avoid adding yet another argument
+ * to add_vnc_route()
+ */
+ encaptlv = encap_tlv_dup(
+ (struct bgp_attr_encap_subtlv *)rfp_options);
+ if (attr.vnc_subtlvs) {
+ attr.vnc_subtlvs->next = encaptlv;
+ } else {
+ attr.vnc_subtlvs = encaptlv;
+ }
+
+ } else {
+ struct bgp_tea_options *hop;
+ /* XXX max of one tlv present so far from above code */
+ struct bgp_attr_encap_subtlv *tail = attr.vnc_subtlvs;
+
+ for (hop = rfp_options; hop; hop = hop->next) {
+
+ /*
+ * Construct subtlv
+ */
+ encaptlv = XCALLOC(
+ MTYPE_ENCAP_TLV,
+ sizeof(struct bgp_attr_encap_subtlv) - 1
+ + 2 + hop->length);
+ assert(encaptlv);
+ encaptlv->type =
+ BGP_VNC_SUBTLV_TYPE_RFPOPTION; /* RFP
+ option
+ */
+ encaptlv->length = 2 + hop->length;
+ *((uint8_t *)(encaptlv->value) + 0) = hop->type;
+ *((uint8_t *)(encaptlv->value) + 1) =
+ hop->length;
+ memcpy(((uint8_t *)encaptlv->value) + 2,
+ hop->value, hop->length);
+
+ /*
+ * add to end of subtlv chain
+ */
+ if (tail) {
+ tail->next = encaptlv;
+ } else {
+ attr.vnc_subtlvs = encaptlv;
+ }
+ tail = encaptlv;
+ }
+ }
+ }
+
+ /*
+ * At this point:
+ * attr: static
+ * extra: dynamically allocated, owned by attr
+ * vnc_subtlvs: dynamic chain, length 1
+ * aspath: points to interned hash from aspath hash table
+ */
+
+
+ attr.ecommunity = ecommunity_new();
+ assert(attr.ecommunity);
+
+ if (TunnelType != BGP_ENCAP_TYPE_MPLS
+ && TunnelType != BGP_ENCAP_TYPE_RESERVED) {
+ /*
+ * Add BGP Encapsulation Extended Community. Format described in
+ * section 4.5 of RFC 5512.
+ * Always include when not MPLS type, to disambiguate this case.
+ */
+ struct ecommunity_val beec;
+
+ memset(&beec, 0, sizeof(beec));
+ beec.val[0] = ECOMMUNITY_ENCODE_OPAQUE;
+ beec.val[1] = ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP;
+ beec.val[6] = ((TunnelType) >> 8) & 0xff;
+ beec.val[7] = (TunnelType)&0xff;
+ ecommunity_add_val(attr.ecommunity, &beec);
+ }
+
+ /*
+ * Add extended community attributes to match rt export list
+ */
+ if (rt_export_list) {
+ attr.ecommunity =
+ ecommunity_merge(attr.ecommunity, rt_export_list);
+ }
+
+ if (attr.ecommunity->size) {
+ attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
+ } else {
+ ecommunity_free(&attr.ecommunity);
+ attr.ecommunity = NULL;
+ }
+ vnc_zlog_debug_verbose("%s: attr.ecommunity=%p", __func__,
+ attr.ecommunity);
+
+
+ /*
+ * At this point:
+ * attr: static
+ * extra: dynamically allocated, owned by attr
+ * vnc_subtlvs: dynamic chain, length 1
+ * ecommunity: dynamic 2-part
+ * aspath: points to interned hash from aspath hash table
+ */
+
+ /* stuff nexthop in attr_extra; which field depends on IPv4 or IPv6 */
+ switch (nexthop->addr_family) {
+ case AF_INET:
+ /*
+ * set this field to prevent bgp_route.c code from setting
+ * mp_nexthop_global_in to self
+ */
+ attr.nexthop.s_addr = nexthop->addr.v4.s_addr;
+
+ attr.mp_nexthop_global_in = nexthop->addr.v4;
+ attr.mp_nexthop_len = 4;
+ break;
+
+ case AF_INET6:
+ attr.mp_nexthop_global = nexthop->addr.v6;
+ attr.mp_nexthop_len = 16;
+ break;
+
+ default:
+ assert(0);
+ }
+
+
+ prefix2str(p, buf, BUFSIZ);
+ buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */
+
+ /*
+ * At this point:
+ *
+ * attr: static
+ * extra: dynamically allocated, owned by attr
+ * vnc_subtlvs: dynamic chain, length 1
+ * ecommunity: dynamic 2-part
+ * aspath: points to interned hash from aspath hash table
+ */
+
+ red = bgp_redist_lookup(bgp, afi, type, VRF_DEFAULT);
+
+ if (red && red->redist_metric_flag) {
+ attr.med = red->redist_metric;
+ attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
+ }
+
+ bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
+
+ /*
+ * bgp_attr_intern creates a new reference to a cached
+ * attribute, but leaves the following bits of trash:
+ * - old attr
+ * - old attr->extra (free via bgp_attr_extra_free(attr))
+ *
+ * Note that it frees the original attr->extra->ecommunity
+ * but leaves the new attribute pointing to the ORIGINAL
+ * vnc options (which therefore we needn't free from the
+ * static attr)
+ */
+ new_attr = bgp_attr_intern(&attr);
+
+ aspath_unintern(&attr.aspath); /* Unintern original. */
+
+ /*
+ * At this point:
+ *
+ * attr: static
+ * extra: dynamically allocated, owned by attr
+ * vnc_subtlvs: dynamic chain, length 1
+ * ecommunity: POINTS TO INTERNED ecom, THIS REF NOT COUNTED
+ *
+ * new_attr: an attr that is part of the hash table, distinct
+ * from attr which is static.
+ * extra: dynamically allocated, owned by new_attr (in hash table)
+ * vnc_subtlvs: POINTS TO SAME dynamic chain AS attr
+ * ecommunity: POINTS TO interned/refcounted dynamic 2-part AS attr
+ * aspath: POINTS TO interned/refcounted hashed block
+ */
+ for (bi = bn->info; bi; bi = bi->next) {
+ /* probably only need to check
+ * bi->extra->vnc.export.rfapi_handle */
+ if (bi->peer == rfd->peer && bi->type == type
+ && bi->sub_type == sub_type && bi->extra
+ && bi->extra->vnc.export.rfapi_handle == (void *)rfd) {
+
+ break;
+ }
+ }
+
+ if (bi) {
+
+ /*
+ * Adding new local_nexthop, which does not by itself change
+ * what is advertised via BGP
+ */
+ if (lnh) {
+ if (!bi->extra->vnc.export.local_nexthops) {
+ /* TBD make arrangements to free when needed */
+ bi->extra->vnc.export.local_nexthops =
+ list_new();
+ bi->extra->vnc.export.local_nexthops->del =
+ rfapi_nexthop_free;
+ }
+
+ /*
+ * already present?
+ */
+ struct listnode *node;
+ struct rfapi_nexthop *pLnh = NULL;
+
+ for (ALL_LIST_ELEMENTS_RO(
+ bi->extra->vnc.export.local_nexthops, node,
+ pLnh)) {
+
+ if (prefix_same(&pLnh->addr, &lnh->addr)) {
+ break;
+ }
+ }
+
+ /*
+ * Not present, add new one
+ */
+ if (!pLnh) {
+ pLnh = rfapi_nexthop_new(lnh);
+ listnode_add(
+ bi->extra->vnc.export.local_nexthops,
+ pLnh);
+ }
+ }
+
+ if (attrhash_cmp(bi->attr, new_attr)
+ && !CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) {
+ bgp_attr_unintern(&new_attr);
+ bgp_unlock_node(bn);
+
+ vnc_zlog_debug_any(
+ "%s: Found route (safi=%d) at prefix %s, no change",
+ __func__, safi, buf);
+
+ goto done;
+ } else {
+ /* The attribute is changed. */
+ bgp_info_set_flag(bn, bi, BGP_INFO_ATTR_CHANGED);
+
+ if (safi == SAFI_MPLS_VPN) {
+ struct bgp_node *prn = NULL;
+ struct bgp_table *table = NULL;
+
+ prn = bgp_node_get(bgp->rib[afi][safi],
+ (struct prefix *)prd);
+ if (prn->info) {
+ table = (struct bgp_table *)(prn->info);
+
+ vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
+ bgp, prd, table, p, bi);
+ }
+ bgp_unlock_node(prn);
+ }
+
+ /* Rewrite BGP route information. */
+ if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED))
+ bgp_info_restore(bn, bi);
+ else
+ bgp_aggregate_decrement(bgp, p, bi, afi, safi);
+ bgp_attr_unintern(&bi->attr);
+ bi->attr = new_attr;
+ bi->uptime = bgp_clock();
+
+
+ if (safi == SAFI_MPLS_VPN) {
+ struct bgp_node *prn = NULL;
+ struct bgp_table *table = NULL;
+
+ prn = bgp_node_get(bgp->rib[afi][safi],
+ (struct prefix *)prd);
+ if (prn->info) {
+ table = (struct bgp_table *)(prn->info);
+
+ vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
+ bgp, prd, table, p, bi);
+ }
+ bgp_unlock_node(prn);
+ }
+
+ /* Process change. */
+ bgp_aggregate_increment(bgp, p, bi, afi, safi);
+ bgp_process(bgp, bn, afi, safi);
+ bgp_unlock_node(bn);
+
+ vnc_zlog_debug_any(
+ "%s: Found route (safi=%d) at prefix %s, changed attr",
+ __func__, safi, buf);
+
+ goto done;
+ }
+ }
+
+
+ new = bgp_info_new();
+ new->type = type;
+ new->sub_type = sub_type;
+ new->peer = rfd->peer;
+ SET_FLAG(new->flags, BGP_INFO_VALID);
+ new->attr = new_attr;
+ new->uptime = bgp_clock();
+
+ /* save backref to rfapi handle */
+ assert(bgp_info_extra_get(new));
+ new->extra->vnc.export.rfapi_handle = (void *)rfd;
+ encode_label(label_val, &new->extra->label);
+
+ /* debug */
+
+ if (VNC_DEBUG(VERBOSE)) {
+ vnc_zlog_debug_verbose("%s: printing BI", __func__);
+ rfapiPrintBi(NULL, new);
+ }
+
+ bgp_aggregate_increment(bgp, p, new, afi, safi);
+ bgp_info_add(bn, new);
+
+ if (safi == SAFI_MPLS_VPN) {
+ struct bgp_node *prn = NULL;
+ struct bgp_table *table = NULL;
+
+ prn = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
+ if (prn->info) {
+ table = (struct bgp_table *)(prn->info);
+
+ vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
+ bgp, prd, table, p, new);
+ }
+ bgp_unlock_node(prn);
+ encode_label(label_val, &bn->local_label);
+ }
+
+ bgp_unlock_node(bn);
+ bgp_process(bgp, bn, afi, safi);
+
+ vnc_zlog_debug_any(
+ "%s: Added route (safi=%s) at prefix %s (bn=%p, prd=%s)",
+ __func__, safi2str(safi), buf, bn, buf2);
done:
- /* Loop back to import tables */
- rfapiProcessUpdate (rfd->peer,
- rfd,
- p, prd, new_attr, afi, safi, type, sub_type, &label_val);
- vnc_zlog_debug_verbose ("%s: looped back import route (safi=%d)", __func__, safi);
+ /* Loop back to import tables */
+ rfapiProcessUpdate(rfd->peer, rfd, p, prd, new_attr, afi, safi, type,
+ sub_type, &label_val);
+ vnc_zlog_debug_verbose("%s: looped back import route (safi=%d)",
+ __func__, safi);
}
-uint32_t
-rfp_cost_to_localpref (uint8_t cost)
+uint32_t rfp_cost_to_localpref(uint8_t cost)
{
- return 255 - cost;
+ return 255 - cost;
}
-static void
-rfapiTunnelRouteAnnounce (
- struct bgp *bgp,
- struct rfapi_descriptor *rfd,
- uint32_t *pLifetime)
+static void rfapiTunnelRouteAnnounce(struct bgp *bgp,
+ struct rfapi_descriptor *rfd,
+ uint32_t *pLifetime)
{
- struct prefix_rd prd;
- struct prefix pfx_vn;
- int rc;
- uint32_t local_pref = rfp_cost_to_localpref (0);
-
- rc = rfapiRaddr2Qprefix (&(rfd->vn_addr), &pfx_vn);
- assert (!rc);
-
- /*
- * Construct route distinguisher = 0
- */
- memset (&prd, 0, sizeof (prd));
- prd.family = AF_UNSPEC;
- prd.prefixlen = 64;
-
- add_vnc_route (rfd, /* rfapi descr, for export list & backref */
- bgp, /* which bgp instance */
- SAFI_ENCAP, /* which SAFI */
- &pfx_vn, /* prefix to advertise */
- &prd, /* route distinguisher to use */
- &rfd->un_addr, /* nexthop */
- &local_pref,
- pLifetime, /* max lifetime of child VPN routes */
- NULL, /* no rfp options for ENCAP safi */
- NULL, /* rfp un options */
- NULL, /* rfp vn options */
- rfd->rt_export_list,
- NULL, /* med */
- NULL, /* label: default */
- ZEBRA_ROUTE_BGP,
- BGP_ROUTE_RFP,
- 0);
+ struct prefix_rd prd;
+ struct prefix pfx_vn;
+ int rc;
+ uint32_t local_pref = rfp_cost_to_localpref(0);
+
+ rc = rfapiRaddr2Qprefix(&(rfd->vn_addr), &pfx_vn);
+ assert(!rc);
+
+ /*
+ * Construct route distinguisher = 0
+ */
+ memset(&prd, 0, sizeof(prd));
+ prd.family = AF_UNSPEC;
+ prd.prefixlen = 64;
+
+ add_vnc_route(rfd, /* rfapi descr, for export list & backref */
+ bgp, /* which bgp instance */
+ SAFI_ENCAP, /* which SAFI */
+ &pfx_vn, /* prefix to advertise */
+ &prd, /* route distinguisher to use */
+ &rfd->un_addr, /* nexthop */
+ &local_pref,
+ pLifetime, /* max lifetime of child VPN routes */
+ NULL, /* no rfp options for ENCAP safi */
+ NULL, /* rfp un options */
+ NULL, /* rfp vn options */
+ rfd->rt_export_list, NULL, /* med */
+ NULL, /* label: default */
+ ZEBRA_ROUTE_BGP, BGP_ROUTE_RFP, 0);
}
@@ -1265,88 +1177,84 @@ rfapiTunnelRouteAnnounce (
/*------------------------------------------
* rfapi_rfp_set_configuration
*
- * This is used to change rfapi's processing behavior based on
- * RFP requirements.
+ * This is used to change rfapi's processing behavior based on
+ * RFP requirements.
*
- * input:
+ * input:
* rfp_start_val value returned by rfp_start
* rfapi_rfp_cfg Pointer to configuration structure
*
* output:
* none
*
- * return value:
+ * return value:
* 0 Success
* ENXIO Unabled to locate configured BGP/VNC
--------------------------------------------*/
-int
-rfapi_rfp_set_configuration (void *rfp_start_val, struct rfapi_rfp_cfg *new)
+int rfapi_rfp_set_configuration(void *rfp_start_val, struct rfapi_rfp_cfg *new)
{
- struct rfapi_rfp_cfg *rcfg;
- struct bgp *bgp;
-
- bgp = rfapi_bgp_lookup_by_rfp (rfp_start_val);
-
- if (!new || !bgp || !bgp->rfapi_cfg)
- return ENXIO;
-
- rcfg = &bgp->rfapi_cfg->rfp_cfg;
- rcfg->download_type = new->download_type;
- rcfg->ftd_advertisement_interval = new->ftd_advertisement_interval;
- rcfg->holddown_factor = new->holddown_factor;
-
- if (rcfg->use_updated_response != new->use_updated_response)
- {
- rcfg->use_updated_response = new->use_updated_response;
- if (rcfg->use_updated_response)
- rfapiMonitorCallbacksOn (bgp);
- else
- rfapiMonitorCallbacksOff (bgp);
- }
- if (rcfg->use_removes != new->use_removes)
- {
- rcfg->use_removes = new->use_removes;
- if (rcfg->use_removes)
- rfapiMonitorResponseRemovalOn (bgp);
- else
- rfapiMonitorResponseRemovalOff (bgp);
- }
- return 0;
+ struct rfapi_rfp_cfg *rcfg;
+ struct bgp *bgp;
+
+ bgp = rfapi_bgp_lookup_by_rfp(rfp_start_val);
+
+ if (!new || !bgp || !bgp->rfapi_cfg)
+ return ENXIO;
+
+ rcfg = &bgp->rfapi_cfg->rfp_cfg;
+ rcfg->download_type = new->download_type;
+ rcfg->ftd_advertisement_interval = new->ftd_advertisement_interval;
+ rcfg->holddown_factor = new->holddown_factor;
+
+ if (rcfg->use_updated_response != new->use_updated_response) {
+ rcfg->use_updated_response = new->use_updated_response;
+ if (rcfg->use_updated_response)
+ rfapiMonitorCallbacksOn(bgp);
+ else
+ rfapiMonitorCallbacksOff(bgp);
+ }
+ if (rcfg->use_removes != new->use_removes) {
+ rcfg->use_removes = new->use_removes;
+ if (rcfg->use_removes)
+ rfapiMonitorResponseRemovalOn(bgp);
+ else
+ rfapiMonitorResponseRemovalOff(bgp);
+ }
+ return 0;
}
/*------------------------------------------
* rfapi_rfp_set_cb_methods
*
- * Change registered callback functions for asynchronous notifications
+ * Change registered callback functions for asynchronous notifications
* from RFAPI to the RFP client.
*
- * input:
+ * input:
* rfp_start_val value returned by rfp_start
* methods Pointer to struct rfapi_rfp_cb_methods containing
* pointers to callback methods as described above
*
- * return value:
+ * return value:
* 0 Success
* ENXIO BGP or VNC not configured
*------------------------------------------*/
-int
-rfapi_rfp_set_cb_methods (void *rfp_start_val,
- struct rfapi_rfp_cb_methods *methods)
+int rfapi_rfp_set_cb_methods(void *rfp_start_val,
+ struct rfapi_rfp_cb_methods *methods)
{
- struct rfapi *h;
- struct bgp *bgp;
+ struct rfapi *h;
+ struct bgp *bgp;
- bgp = rfapi_bgp_lookup_by_rfp (rfp_start_val);
- if (!bgp)
- return ENXIO;
+ bgp = rfapi_bgp_lookup_by_rfp(rfp_start_val);
+ if (!bgp)
+ return ENXIO;
- h = bgp->rfapi;
- if (!h)
- return ENXIO;
+ h = bgp->rfapi;
+ if (!h)
+ return ENXIO;
- h->rfp_methods = *methods;
+ h->rfp_methods = *methods;
- return 0;
+ return 0;
}
/***********************************************************************
@@ -1358,570 +1266,520 @@ rfapi_rfp_set_cb_methods (void *rfp_start_val,
* The advertised_prefixes[] array elements should be NULL to
* have this function set them to newly-allocated radix trees.
*/
-static int
-rfapi_open_inner (
- struct rfapi_descriptor *rfd,
- struct bgp *bgp,
- struct rfapi *h,
- struct rfapi_nve_group_cfg *rfg)
+static int rfapi_open_inner(struct rfapi_descriptor *rfd, struct bgp *bgp,
+ struct rfapi *h, struct rfapi_nve_group_cfg *rfg)
{
- int ret;
-
- if (h->flags & RFAPI_INCALLBACK)
- return EDEADLK;
+ int ret;
+
+ if (h->flags & RFAPI_INCALLBACK)
+ return EDEADLK;
+
+ /*
+ * Fill in configured fields
+ */
+
+ /*
+ * If group's RD is specified as "auto", then fill in based
+ * on NVE's VN address
+ */
+ rfd->rd = rfg->rd;
+
+ if (rfd->rd.family == AF_UNIX) {
+ ret = rfapi_set_autord_from_vn(&rfd->rd, &rfd->vn_addr);
+ if (ret != 0)
+ return ret;
+ }
+ rfd->rt_export_list = (rfg->rt_export_list)
+ ? ecommunity_dup(rfg->rt_export_list)
+ : NULL;
+ rfd->response_lifetime = rfg->response_lifetime;
+ rfd->rfg = rfg;
+
+ /*
+ * Fill in BGP peer structure
+ */
+ rfd->peer = peer_new(bgp);
+ rfd->peer->status = Established; /* keep bgp core happy */
+ bgp_sync_delete(rfd->peer); /* don't need these */
+ if (rfd->peer->ibuf) {
+ stream_free(rfd->peer->ibuf); /* don't need it */
+ rfd->peer->ibuf = NULL;
+ }
+ if (rfd->peer->obuf) {
+ stream_fifo_free(rfd->peer->obuf); /* don't need it */
+ rfd->peer->obuf = NULL;
+ }
+ if (rfd->peer->work) {
+ stream_free(rfd->peer->work); /* don't need it */
+ rfd->peer->work = NULL;
+ }
+ { /* base code assumes have valid host pointer */
+ char buf[BUFSIZ];
+ buf[0] = 0;
+
+ if (rfd->vn_addr.addr_family == AF_INET) {
+ inet_ntop(AF_INET, &rfd->vn_addr.addr.v4, buf, BUFSIZ);
+ } else if (rfd->vn_addr.addr_family == AF_INET6) {
+ inet_ntop(AF_INET6, &rfd->vn_addr.addr.v6, buf, BUFSIZ);
+ }
+ rfd->peer->host = XSTRDUP(MTYPE_BGP_PEER_HOST, buf);
+ }
+ /* Mark peer as belonging to HD */
+ SET_FLAG(rfd->peer->flags, PEER_FLAG_IS_RFAPI_HD);
+
+ /*
+ * Set min prefix lifetime to max value so it will get set
+ * upon first rfapi_register()
+ */
+ rfd->min_prefix_lifetime = UINT32_MAX;
- /*
- * Fill in configured fields
- */
-
- /*
- * If group's RD is specified as "auto", then fill in based
- * on NVE's VN address
- */
- rfd->rd = rfg->rd;
-
- if (rfd->rd.family == AF_UNIX)
- {
- ret = rfapi_set_autord_from_vn (&rfd->rd, &rfd->vn_addr);
- if (ret != 0)
- return ret;
- }
- rfd->rt_export_list = (rfg->rt_export_list) ?
- ecommunity_dup (rfg->rt_export_list) : NULL;
- rfd->response_lifetime = rfg->response_lifetime;
- rfd->rfg = rfg;
-
- /*
- * Fill in BGP peer structure
- */
- rfd->peer = peer_new (bgp);
- rfd->peer->status = Established; /* keep bgp core happy */
- bgp_sync_delete (rfd->peer); /* don't need these */
- if (rfd->peer->ibuf)
- {
- stream_free (rfd->peer->ibuf); /* don't need it */
- rfd->peer->ibuf = NULL;
- }
- if (rfd->peer->obuf)
- {
- stream_fifo_free (rfd->peer->obuf); /* don't need it */
- rfd->peer->obuf = NULL;
- }
- if (rfd->peer->work)
- {
- stream_free (rfd->peer->work); /* don't need it */
- rfd->peer->work = NULL;
- }
- { /* base code assumes have valid host pointer */
- char buf[BUFSIZ];
- buf[0] = 0;
-
- if (rfd->vn_addr.addr_family == AF_INET)
- {
- inet_ntop (AF_INET, &rfd->vn_addr.addr.v4, buf, BUFSIZ);
- }
- else if (rfd->vn_addr.addr_family == AF_INET6)
- {
- inet_ntop (AF_INET6, &rfd->vn_addr.addr.v6, buf, BUFSIZ);
- }
- rfd->peer->host = XSTRDUP (MTYPE_BGP_PEER_HOST, buf);
- }
- /* Mark peer as belonging to HD */
- SET_FLAG (rfd->peer->flags, PEER_FLAG_IS_RFAPI_HD);
-
- /*
- * Set min prefix lifetime to max value so it will get set
- * upon first rfapi_register()
- */
- rfd->min_prefix_lifetime = UINT32_MAX;
-
- /*
- * Allocate response tables if needed
- */
-#define RFD_RTINIT_AFI(rh, ary, afi) do {\
- if (!ary[afi]) { \
- ary[afi] = route_table_init ();\
- ary[afi]->info = rh;\
- }\
-} while (0)
-
-#define RFD_RTINIT(rh, ary) do {\
- RFD_RTINIT_AFI(rh, ary, AFI_IP);\
- RFD_RTINIT_AFI(rh, ary, AFI_IP6);\
- RFD_RTINIT_AFI(rh, ary, AFI_L2VPN);\
-} while(0)
-
- RFD_RTINIT(rfd, rfd->rib);
- RFD_RTINIT(rfd, rfd->rib_pending);
- RFD_RTINIT(rfd, rfd->rsp_times);
-
- /*
- * Link to Import Table
- */
- rfd->import_table = rfg->rfapi_import_table;
- rfd->import_table->refcount += 1;
-
- rfapiApInit (&rfd->advertised);
-
- /*
- * add this NVE descriptor to the list of NVEs in the NVE group
- */
- if (!rfg->nves)
- {
- rfg->nves = list_new ();
- }
- listnode_add (rfg->nves, rfd);
-
- vnc_direct_bgp_add_nve (bgp, rfd);
- vnc_zebra_add_nve (bgp, rfd);
-
- return 0;
+/*
+ * Allocate response tables if needed
+ */
+#define RFD_RTINIT_AFI(rh, ary, afi) \
+ do { \
+ if (!ary[afi]) { \
+ ary[afi] = route_table_init(); \
+ ary[afi]->info = rh; \
+ } \
+ } while (0)
+
+#define RFD_RTINIT(rh, ary) \
+ do { \
+ RFD_RTINIT_AFI(rh, ary, AFI_IP); \
+ RFD_RTINIT_AFI(rh, ary, AFI_IP6); \
+ RFD_RTINIT_AFI(rh, ary, AFI_L2VPN); \
+ } while (0)
+
+ RFD_RTINIT(rfd, rfd->rib);
+ RFD_RTINIT(rfd, rfd->rib_pending);
+ RFD_RTINIT(rfd, rfd->rsp_times);
+
+ /*
+ * Link to Import Table
+ */
+ rfd->import_table = rfg->rfapi_import_table;
+ rfd->import_table->refcount += 1;
+
+ rfapiApInit(&rfd->advertised);
+
+ /*
+ * add this NVE descriptor to the list of NVEs in the NVE group
+ */
+ if (!rfg->nves) {
+ rfg->nves = list_new();
+ }
+ listnode_add(rfg->nves, rfd);
+
+ vnc_direct_bgp_add_nve(bgp, rfd);
+ vnc_zebra_add_nve(bgp, rfd);
+
+ return 0;
}
/* moved from rfapi_register */
-int
-rfapi_init_and_open(
- struct bgp *bgp,
- struct rfapi_descriptor *rfd,
- struct rfapi_nve_group_cfg *rfg)
+int rfapi_init_and_open(struct bgp *bgp, struct rfapi_descriptor *rfd,
+ struct rfapi_nve_group_cfg *rfg)
{
- struct rfapi *h = bgp->rfapi;
- char buf_vn[BUFSIZ];
- char buf_un[BUFSIZ];
- afi_t afi_vn, afi_un;
- struct prefix pfx_un;
- struct route_node *rn;
-
-
- rfapi_time (&rfd->open_time);
-
- if (rfg->type == RFAPI_GROUP_CFG_VRF)
- SET_FLAG(rfd->flags, RFAPI_HD_FLAG_IS_VRF);
-
- rfapiRfapiIpAddr2Str (&rfd->vn_addr, buf_vn, BUFSIZ);
- rfapiRfapiIpAddr2Str (&rfd->un_addr, buf_un, BUFSIZ);
-
- vnc_zlog_debug_verbose ("%s: new RFD with VN=%s UN=%s cookie=%p",
- __func__, buf_vn, buf_un, rfd->cookie);
-
- if (rfg->type != RFAPI_GROUP_CFG_VRF) /* unclear if needed for VRF */
- {
- listnode_add (&h->descriptors, rfd);
- if (h->descriptors.count > h->stat.max_descriptors)
- {
- h->stat.max_descriptors = h->descriptors.count;
- }
-
- /*
- * attach to UN radix tree
- */
- afi_vn = family2afi (rfd->vn_addr.addr_family);
- afi_un = family2afi (rfd->un_addr.addr_family);
- assert (afi_vn && afi_un);
- assert (!rfapiRaddr2Qprefix (&rfd->un_addr, &pfx_un));
-
- rn = route_node_get (&(h->un[afi_un]), &pfx_un);
- assert (rn);
- rfd->next = rn->info;
- rn->info = rfd;
- rfd->un_node = rn;
- }
- return rfapi_open_inner (rfd, bgp, h, rfg);
+ struct rfapi *h = bgp->rfapi;
+ char buf_vn[BUFSIZ];
+ char buf_un[BUFSIZ];
+ afi_t afi_vn, afi_un;
+ struct prefix pfx_un;
+ struct route_node *rn;
+
+
+ rfapi_time(&rfd->open_time);
+
+ if (rfg->type == RFAPI_GROUP_CFG_VRF)
+ SET_FLAG(rfd->flags, RFAPI_HD_FLAG_IS_VRF);
+
+ rfapiRfapiIpAddr2Str(&rfd->vn_addr, buf_vn, BUFSIZ);
+ rfapiRfapiIpAddr2Str(&rfd->un_addr, buf_un, BUFSIZ);
+
+ vnc_zlog_debug_verbose("%s: new RFD with VN=%s UN=%s cookie=%p",
+ __func__, buf_vn, buf_un, rfd->cookie);
+
+ if (rfg->type != RFAPI_GROUP_CFG_VRF) /* unclear if needed for VRF */
+ {
+ listnode_add(&h->descriptors, rfd);
+ if (h->descriptors.count > h->stat.max_descriptors) {
+ h->stat.max_descriptors = h->descriptors.count;
+ }
+
+ /*
+ * attach to UN radix tree
+ */
+ afi_vn = family2afi(rfd->vn_addr.addr_family);
+ afi_un = family2afi(rfd->un_addr.addr_family);
+ assert(afi_vn && afi_un);
+ assert(!rfapiRaddr2Qprefix(&rfd->un_addr, &pfx_un));
+
+ rn = route_node_get(&(h->un[afi_un]), &pfx_un);
+ assert(rn);
+ rfd->next = rn->info;
+ rn->info = rfd;
+ rfd->un_node = rn;
+ }
+ return rfapi_open_inner(rfd, bgp, h, rfg);
}
-struct rfapi_vn_option *
-rfapiVnOptionsDup (struct rfapi_vn_option *orig)
+struct rfapi_vn_option *rfapiVnOptionsDup(struct rfapi_vn_option *orig)
{
- struct rfapi_vn_option *head = NULL;
- struct rfapi_vn_option *tail = NULL;
- struct rfapi_vn_option *vo = NULL;
-
- for (vo = orig; vo; vo = vo->next)
- {
- struct rfapi_vn_option *new;
-
- new = XCALLOC (MTYPE_RFAPI_VN_OPTION, sizeof (struct rfapi_vn_option));
- memcpy (new, vo, sizeof (struct rfapi_vn_option));
- new->next = NULL;
-
- if (tail)
- {
- tail->next = new;
- }
- else
- {
- head = tail = new;
- }
- }
- return head;
+ struct rfapi_vn_option *head = NULL;
+ struct rfapi_vn_option *tail = NULL;
+ struct rfapi_vn_option *vo = NULL;
+
+ for (vo = orig; vo; vo = vo->next) {
+ struct rfapi_vn_option *new;
+
+ new = XCALLOC(MTYPE_RFAPI_VN_OPTION,
+ sizeof(struct rfapi_vn_option));
+ memcpy(new, vo, sizeof(struct rfapi_vn_option));
+ new->next = NULL;
+
+ if (tail) {
+ tail->next = new;
+ } else {
+ head = tail = new;
+ }
+ }
+ return head;
}
-struct rfapi_un_option *
-rfapiUnOptionsDup (struct rfapi_un_option *orig)
+struct rfapi_un_option *rfapiUnOptionsDup(struct rfapi_un_option *orig)
{
- struct rfapi_un_option *head = NULL;
- struct rfapi_un_option *tail = NULL;
- struct rfapi_un_option *uo = NULL;
-
- for (uo = orig; uo; uo = uo->next)
- {
- struct rfapi_un_option *new;
-
- new = XCALLOC (MTYPE_RFAPI_UN_OPTION, sizeof (struct rfapi_un_option));
- memcpy (new, uo, sizeof (struct rfapi_un_option));
- new->next = NULL;
-
- if (tail)
- {
- tail->next = new;
- }
- else
- {
- head = tail = new;
- }
- }
- return head;
+ struct rfapi_un_option *head = NULL;
+ struct rfapi_un_option *tail = NULL;
+ struct rfapi_un_option *uo = NULL;
+
+ for (uo = orig; uo; uo = uo->next) {
+ struct rfapi_un_option *new;
+
+ new = XCALLOC(MTYPE_RFAPI_UN_OPTION,
+ sizeof(struct rfapi_un_option));
+ memcpy(new, uo, sizeof(struct rfapi_un_option));
+ new->next = NULL;
+
+ if (tail) {
+ tail->next = new;
+ } else {
+ head = tail = new;
+ }
+ }
+ return head;
}
-struct bgp_tea_options *
-rfapiOptionsDup (struct bgp_tea_options *orig)
+struct bgp_tea_options *rfapiOptionsDup(struct bgp_tea_options *orig)
{
- struct bgp_tea_options *head = NULL;
- struct bgp_tea_options *tail = NULL;
- struct bgp_tea_options *hop = NULL;
-
- for (hop = orig; hop; hop = hop->next)
- {
- struct bgp_tea_options *new;
-
- new = XCALLOC (MTYPE_BGP_TEA_OPTIONS, sizeof (struct bgp_tea_options));
- memcpy (new, hop, sizeof (struct bgp_tea_options));
- new->next = NULL;
- if (hop->value)
- {
- new->value = XCALLOC (MTYPE_BGP_TEA_OPTIONS_VALUE, hop->length);
- memcpy (new->value, hop->value, hop->length);
- }
- if (tail)
- {
- tail->next = new;
- }
- else
- {
- head = tail = new;
- }
- }
- return head;
+ struct bgp_tea_options *head = NULL;
+ struct bgp_tea_options *tail = NULL;
+ struct bgp_tea_options *hop = NULL;
+
+ for (hop = orig; hop; hop = hop->next) {
+ struct bgp_tea_options *new;
+
+ new = XCALLOC(MTYPE_BGP_TEA_OPTIONS,
+ sizeof(struct bgp_tea_options));
+ memcpy(new, hop, sizeof(struct bgp_tea_options));
+ new->next = NULL;
+ if (hop->value) {
+ new->value = XCALLOC(MTYPE_BGP_TEA_OPTIONS_VALUE,
+ hop->length);
+ memcpy(new->value, hop->value, hop->length);
+ }
+ if (tail) {
+ tail->next = new;
+ } else {
+ head = tail = new;
+ }
+ }
+ return head;
}
-void
-rfapiFreeBgpTeaOptionChain (struct bgp_tea_options *p)
+void rfapiFreeBgpTeaOptionChain(struct bgp_tea_options *p)
{
- struct bgp_tea_options *next;
+ struct bgp_tea_options *next;
- while (p)
- {
- next = p->next;
+ while (p) {
+ next = p->next;
- if (p->value)
- {
- XFREE (MTYPE_BGP_TEA_OPTIONS_VALUE, p->value);
- p->value = NULL;
- }
- XFREE (MTYPE_BGP_TEA_OPTIONS, p);
+ if (p->value) {
+ XFREE(MTYPE_BGP_TEA_OPTIONS_VALUE, p->value);
+ p->value = NULL;
+ }
+ XFREE(MTYPE_BGP_TEA_OPTIONS, p);
- p = next;
- }
+ p = next;
+ }
}
-void
-rfapiAdbFree (struct rfapi_adb *adb)
+void rfapiAdbFree(struct rfapi_adb *adb)
{
- XFREE (MTYPE_RFAPI_ADB, adb);
+ XFREE(MTYPE_RFAPI_ADB, adb);
}
static int
-rfapi_query_inner (
- void *handle,
- struct rfapi_ip_addr *target,
- struct rfapi_l2address_option *l2o, /* may be NULL */
- struct rfapi_next_hop_entry **ppNextHopEntry)
+rfapi_query_inner(void *handle, struct rfapi_ip_addr *target,
+ struct rfapi_l2address_option *l2o, /* may be NULL */
+ struct rfapi_next_hop_entry **ppNextHopEntry)
{
- afi_t afi;
- struct prefix p;
- struct prefix p_original;
- struct route_node *rn;
- struct rfapi_descriptor *rfd = (struct rfapi_descriptor *) handle;
- struct bgp *bgp = rfd->bgp;
- struct rfapi_next_hop_entry *pNHE = NULL;
- struct rfapi_ip_addr *self_vn_addr = NULL;
- int eth_is_0 = 0;
- int use_eth_resolution = 0;
- struct rfapi_next_hop_entry *i_nhe;
-
- /* preemptive */
- if (!bgp)
- {
- vnc_zlog_debug_verbose ("%s: No BGP instance, returning ENXIO", __func__);
- return ENXIO;
- }
- if (!bgp->rfapi)
- {
- vnc_zlog_debug_verbose ("%s: No RFAPI instance, returning ENXIO", __func__);
- return ENXIO;
- }
- if (bgp->rfapi->flags & RFAPI_INCALLBACK)
- {
- vnc_zlog_debug_verbose ("%s: Called during calback, returning EDEADLK", __func__);
- return EDEADLK;
- }
-
- if (!is_valid_rfd (rfd))
- {
- vnc_zlog_debug_verbose ("%s: invalid handle, returning EBADF", __func__);
- return EBADF;
- }
-
- rfd->rsp_counter++; /* dedup: identify this generation */
- rfd->rsp_time = rfapi_time (NULL); /* response content dedup */
- rfd->ftd_last_allowed_time =
- bgp_clock() - bgp->rfapi_cfg->rfp_cfg.ftd_advertisement_interval;
-
- if (l2o)
- {
- if (!memcmp (l2o->macaddr.octet, rfapi_ethaddr0.octet, ETHER_ADDR_LEN))
- {
- eth_is_0 = 1;
- }
- /* per t/c Paul/Lou 151022 */
- if (!eth_is_0 || l2o->logical_net_id)
- {
- use_eth_resolution = 1;
- }
- }
-
- if (ppNextHopEntry)
- *ppNextHopEntry = NULL;
-
- /*
- * Save original target in prefix form. In case of L2-based queries,
- * p_original will be modified to reflect the L2 target
- */
- assert(!rfapiRaddr2Qprefix (target, &p_original));
-
- if (bgp->rfapi_cfg->rfp_cfg.download_type == RFAPI_RFP_DOWNLOAD_FULL)
- {
- /* convert query to 0/0 when full-table download is enabled */
- memset ((char *) &p, 0, sizeof (p));
- p.family = target->addr_family;
- }
- else
- {
- p = p_original;
- }
-
- {
- char buf[BUFSIZ];
- char *s;
-
- prefix2str (&p, buf, BUFSIZ);
- buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */
- vnc_zlog_debug_verbose ("%s(rfd=%p, target=%s, ppNextHop=%p)",
- __func__, rfd, buf, ppNextHopEntry);
-
- s = ecommunity_ecom2str(rfd->import_table->rt_import_list,
- ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
- vnc_zlog_debug_verbose("%s rfd->import_table=%p, rfd->import_table->rt_import_list: %s",
- __func__, rfd->import_table, s); XFREE (MTYPE_ECOMMUNITY_STR, s);
- }
-
- afi = family2afi (p.family);
- assert (afi);
-
- if (CHECK_FLAG (bgp->rfapi_cfg->flags, BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP))
- {
- self_vn_addr = &rfd->vn_addr;
- }
-
- if (use_eth_resolution)
- {
- uint32_t logical_net_id = l2o->logical_net_id;
- struct ecommunity *l2com;
-
- /*
- * fix up p_original to contain L2 address
- */
- rfapiL2o2Qprefix (l2o, &p_original);
-
- l2com =
- bgp_rfapi_get_ecommunity_by_lni_label (bgp, 1, logical_net_id,
- l2o->label);
- if (l2com)
- {
- uint8_t *v = l2com->val;
- logical_net_id = (v[5] << 16) + (v[6] << 8) + (v[7]);
- }
- /*
- * Ethernet/L2-based lookup
- *
- * Always returns IT node corresponding to route
- */
-
- if (RFAPI_RFP_DOWNLOAD_FULL == bgp->rfapi_cfg->rfp_cfg.download_type)
- {
- eth_is_0 = 1;
- }
-
- rn = rfapiMonitorEthAdd (bgp,
- rfd,
- (eth_is_0 ? &rfapi_ethaddr0 : &l2o->macaddr),
- logical_net_id);
-
- if (eth_is_0)
- {
- struct rfapi_ip_prefix rprefix;
-
- memset (&rprefix, 0, sizeof (rprefix));
- rprefix.prefix.addr_family = target->addr_family;
- if (target->addr_family == AF_INET)
- {
- rprefix.length = 32;
- }
- else
- {
- rprefix.length = 128;
- }
-
- pNHE = rfapiEthRouteTable2NextHopList (logical_net_id, &rprefix,
- rfd->response_lifetime, self_vn_addr, rfd->rib[afi], &p_original);
- goto done;
- }
-
- }
- else
- {
-
- /*
- * IP-based lookup
- */
-
- rn = rfapiMonitorAdd (bgp, rfd, &p);
-
- /*
- * If target address is 0, this request is special: means to
- * return ALL routes in the table
- *
- * Monitors for All-Routes queries get put on a special list,
- * not in the VPN tree
- */
- if (RFAPI_0_PREFIX (&p))
- {
-
- vnc_zlog_debug_verbose ("%s: 0-prefix", __func__);
-
- /*
- * Generate nexthop list for caller
- */
- pNHE = rfapiRouteTable2NextHopList (
- rfd->import_table->imported_vpn[afi], rfd->response_lifetime,
- self_vn_addr, rfd->rib[afi], &p_original);
- goto done;
- }
-
- if (rn)
- {
- route_lock_node (rn); /* so we can unlock below */
- }
- else
- {
- /*
- * returns locked node. Don't unlock yet because the unlock
- * might free it before we're done with it. This situation
- * could occur when rfapiMonitorGetAttachNode() returns a
- * newly-created default node.
- */
- rn = rfapiMonitorGetAttachNode (rfd, &p);
- }
- }
-
- assert (rn);
- if (!rn->info)
- {
- route_unlock_node (rn);
- vnc_zlog_debug_verbose ("%s: VPN route not found, returning ENOENT", __func__);
- return ENOENT;
- }
-
- if (VNC_DEBUG(RFAPI_QUERY))
- {
- rfapiShowImportTable (NULL, "query", rfd->import_table->imported_vpn[afi],
- 1);
- }
-
- if (use_eth_resolution)
- {
-
- struct rfapi_ip_prefix rprefix;
-
- memset (&rprefix, 0, sizeof (rprefix));
- rprefix.prefix.addr_family = target->addr_family;
- if (target->addr_family == AF_INET)
- {
- rprefix.length = 32;
- }
- else
- {
- rprefix.length = 128;
- }
-
- pNHE = rfapiEthRouteNode2NextHopList (rn, &rprefix,
- rfd->response_lifetime, self_vn_addr, rfd->rib[afi], &p_original);
-
-
- }
- else
- {
- /*
- * Generate answer to query
- */
- pNHE = rfapiRouteNode2NextHopList(rn, rfd->response_lifetime,
- self_vn_addr, rfd->rib[afi], &p_original);
- }
-
- route_unlock_node (rn);
+ afi_t afi;
+ struct prefix p;
+ struct prefix p_original;
+ struct route_node *rn;
+ struct rfapi_descriptor *rfd = (struct rfapi_descriptor *)handle;
+ struct bgp *bgp = rfd->bgp;
+ struct rfapi_next_hop_entry *pNHE = NULL;
+ struct rfapi_ip_addr *self_vn_addr = NULL;
+ int eth_is_0 = 0;
+ int use_eth_resolution = 0;
+ struct rfapi_next_hop_entry *i_nhe;
+
+ /* preemptive */
+ if (!bgp) {
+ vnc_zlog_debug_verbose("%s: No BGP instance, returning ENXIO",
+ __func__);
+ return ENXIO;
+ }
+ if (!bgp->rfapi) {
+ vnc_zlog_debug_verbose("%s: No RFAPI instance, returning ENXIO",
+ __func__);
+ return ENXIO;
+ }
+ if (bgp->rfapi->flags & RFAPI_INCALLBACK) {
+ vnc_zlog_debug_verbose(
+ "%s: Called during calback, returning EDEADLK",
+ __func__);
+ return EDEADLK;
+ }
+
+ if (!is_valid_rfd(rfd)) {
+ vnc_zlog_debug_verbose("%s: invalid handle, returning EBADF",
+ __func__);
+ return EBADF;
+ }
+
+ rfd->rsp_counter++; /* dedup: identify this generation */
+ rfd->rsp_time = rfapi_time(NULL); /* response content dedup */
+ rfd->ftd_last_allowed_time =
+ bgp_clock()
+ - bgp->rfapi_cfg->rfp_cfg.ftd_advertisement_interval;
+
+ if (l2o) {
+ if (!memcmp(l2o->macaddr.octet, rfapi_ethaddr0.octet,
+ ETHER_ADDR_LEN)) {
+ eth_is_0 = 1;
+ }
+ /* per t/c Paul/Lou 151022 */
+ if (!eth_is_0 || l2o->logical_net_id) {
+ use_eth_resolution = 1;
+ }
+ }
+
+ if (ppNextHopEntry)
+ *ppNextHopEntry = NULL;
+
+ /*
+ * Save original target in prefix form. In case of L2-based queries,
+ * p_original will be modified to reflect the L2 target
+ */
+ assert(!rfapiRaddr2Qprefix(target, &p_original));
+
+ if (bgp->rfapi_cfg->rfp_cfg.download_type == RFAPI_RFP_DOWNLOAD_FULL) {
+ /* convert query to 0/0 when full-table download is enabled */
+ memset((char *)&p, 0, sizeof(p));
+ p.family = target->addr_family;
+ } else {
+ p = p_original;
+ }
+
+ {
+ char buf[BUFSIZ];
+ char *s;
+
+ prefix2str(&p, buf, BUFSIZ);
+ buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */
+ vnc_zlog_debug_verbose("%s(rfd=%p, target=%s, ppNextHop=%p)",
+ __func__, rfd, buf, ppNextHopEntry);
+
+ s = ecommunity_ecom2str(rfd->import_table->rt_import_list,
+ ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
+ vnc_zlog_debug_verbose(
+ "%s rfd->import_table=%p, rfd->import_table->rt_import_list: %s",
+ __func__, rfd->import_table, s);
+ XFREE(MTYPE_ECOMMUNITY_STR, s);
+ }
+
+ afi = family2afi(p.family);
+ assert(afi);
+
+ if (CHECK_FLAG(bgp->rfapi_cfg->flags,
+ BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP)) {
+ self_vn_addr = &rfd->vn_addr;
+ }
+
+ if (use_eth_resolution) {
+ uint32_t logical_net_id = l2o->logical_net_id;
+ struct ecommunity *l2com;
+
+ /*
+ * fix up p_original to contain L2 address
+ */
+ rfapiL2o2Qprefix(l2o, &p_original);
+
+ l2com = bgp_rfapi_get_ecommunity_by_lni_label(
+ bgp, 1, logical_net_id, l2o->label);
+ if (l2com) {
+ uint8_t *v = l2com->val;
+ logical_net_id = (v[5] << 16) + (v[6] << 8) + (v[7]);
+ }
+ /*
+ * Ethernet/L2-based lookup
+ *
+ * Always returns IT node corresponding to route
+ */
+
+ if (RFAPI_RFP_DOWNLOAD_FULL
+ == bgp->rfapi_cfg->rfp_cfg.download_type) {
+ eth_is_0 = 1;
+ }
+
+ rn = rfapiMonitorEthAdd(
+ bgp, rfd, (eth_is_0 ? &rfapi_ethaddr0 : &l2o->macaddr),
+ logical_net_id);
+
+ if (eth_is_0) {
+ struct rfapi_ip_prefix rprefix;
+
+ memset(&rprefix, 0, sizeof(rprefix));
+ rprefix.prefix.addr_family = target->addr_family;
+ if (target->addr_family == AF_INET) {
+ rprefix.length = 32;
+ } else {
+ rprefix.length = 128;
+ }
+
+ pNHE = rfapiEthRouteTable2NextHopList(
+ logical_net_id, &rprefix,
+ rfd->response_lifetime, self_vn_addr,
+ rfd->rib[afi], &p_original);
+ goto done;
+ }
+
+ } else {
+
+ /*
+ * IP-based lookup
+ */
+
+ rn = rfapiMonitorAdd(bgp, rfd, &p);
+
+ /*
+ * If target address is 0, this request is special: means to
+ * return ALL routes in the table
+ *
+ * Monitors for All-Routes queries get put on a special list,
+ * not in the VPN tree
+ */
+ if (RFAPI_0_PREFIX(&p)) {
+
+ vnc_zlog_debug_verbose("%s: 0-prefix", __func__);
+
+ /*
+ * Generate nexthop list for caller
+ */
+ pNHE = rfapiRouteTable2NextHopList(
+ rfd->import_table->imported_vpn[afi],
+ rfd->response_lifetime, self_vn_addr,
+ rfd->rib[afi], &p_original);
+ goto done;
+ }
+
+ if (rn) {
+ route_lock_node(rn); /* so we can unlock below */
+ } else {
+ /*
+ * returns locked node. Don't unlock yet because the
+ * unlock
+ * might free it before we're done with it. This
+ * situation
+ * could occur when rfapiMonitorGetAttachNode() returns
+ * a
+ * newly-created default node.
+ */
+ rn = rfapiMonitorGetAttachNode(rfd, &p);
+ }
+ }
+
+ assert(rn);
+ if (!rn->info) {
+ route_unlock_node(rn);
+ vnc_zlog_debug_verbose(
+ "%s: VPN route not found, returning ENOENT", __func__);
+ return ENOENT;
+ }
+
+ if (VNC_DEBUG(RFAPI_QUERY)) {
+ rfapiShowImportTable(NULL, "query",
+ rfd->import_table->imported_vpn[afi], 1);
+ }
+
+ if (use_eth_resolution) {
+
+ struct rfapi_ip_prefix rprefix;
+
+ memset(&rprefix, 0, sizeof(rprefix));
+ rprefix.prefix.addr_family = target->addr_family;
+ if (target->addr_family == AF_INET) {
+ rprefix.length = 32;
+ } else {
+ rprefix.length = 128;
+ }
+
+ pNHE = rfapiEthRouteNode2NextHopList(
+ rn, &rprefix, rfd->response_lifetime, self_vn_addr,
+ rfd->rib[afi], &p_original);
+
+
+ } else {
+ /*
+ * Generate answer to query
+ */
+ pNHE = rfapiRouteNode2NextHopList(rn, rfd->response_lifetime,
+ self_vn_addr, rfd->rib[afi],
+ &p_original);
+ }
+
+ route_unlock_node(rn);
done:
- if (ppNextHopEntry)
- {
- /* only count if caller gets it */
- ++bgp->rfapi->response_immediate_count;
- }
-
- if (!pNHE)
- {
- vnc_zlog_debug_verbose ("%s: NO NHEs, returning ENOENT", __func__);
- return ENOENT;
- }
-
- /*
- * count nexthops for statistics
- */
- for (i_nhe = pNHE; i_nhe; i_nhe = i_nhe->next)
- {
- ++rfd->stat_count_nh_reachable;
- }
-
- if (ppNextHopEntry)
- {
- *ppNextHopEntry = pNHE;
- }
- else
- {
- rfapi_free_next_hop_list (pNHE);
- }
-
- vnc_zlog_debug_verbose ("%s: success", __func__);
- return 0;
+ if (ppNextHopEntry) {
+ /* only count if caller gets it */
+ ++bgp->rfapi->response_immediate_count;
+ }
+
+ if (!pNHE) {
+ vnc_zlog_debug_verbose("%s: NO NHEs, returning ENOENT",
+ __func__);
+ return ENOENT;
+ }
+
+ /*
+ * count nexthops for statistics
+ */
+ for (i_nhe = pNHE; i_nhe; i_nhe = i_nhe->next) {
+ ++rfd->stat_count_nh_reachable;
+ }
+
+ if (ppNextHopEntry) {
+ *ppNextHopEntry = pNHE;
+ } else {
+ rfapi_free_next_hop_list(pNHE);
+ }
+
+ vnc_zlog_debug_verbose("%s: success", __func__);
+ return 0;
}
/*
@@ -1929,68 +1787,63 @@ done:
* nve-group in the event that its original nve-group is
* administratively deleted.
*/
-static int
-rfapi_open_rfd (struct rfapi_descriptor *rfd, struct bgp *bgp)
+static int rfapi_open_rfd(struct rfapi_descriptor *rfd, struct bgp *bgp)
{
- struct prefix pfx_vn;
- struct prefix pfx_un;
- struct rfapi_nve_group_cfg *rfg;
- struct rfapi *h;
- struct rfapi_cfg *hc;
- int rc;
-
- h = bgp->rfapi;
- if (!h)
- return ENXIO;
-
- hc = bgp->rfapi_cfg;
- if (!hc)
- return ENXIO;
-
- rc = rfapiRaddr2Qprefix (&rfd->vn_addr, &pfx_vn);
- assert (!rc);
-
- rc = rfapiRaddr2Qprefix (&rfd->un_addr, &pfx_un);
- assert (!rc);
-
- /*
- * Find the matching nve group config block
- */
- rfg = bgp_rfapi_cfg_match_group (hc, &pfx_vn, &pfx_un);
- if (!rfg)
- {
- return ENOENT;
- }
-
- /*
- * check nve group config block for required values
- */
- if (!rfg->rt_export_list || !rfg->rfapi_import_table)
- {
-
- return ENOMSG;
- }
-
- rc = rfapi_open_inner (rfd, bgp, h, rfg);
- if (rc)
- {
- return rc;
- }
-
- /*
- * re-advertise registered routes, this time as part of new NVE-group
- */
- rfapiApReadvertiseAll (bgp, rfd);
-
- /*
- * re-attach callbacks to import table
- */
- if (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE))
- {
- rfapiMonitorAttachImportHd (rfd);
- }
-
- return 0;
+ struct prefix pfx_vn;
+ struct prefix pfx_un;
+ struct rfapi_nve_group_cfg *rfg;
+ struct rfapi *h;
+ struct rfapi_cfg *hc;
+ int rc;
+
+ h = bgp->rfapi;
+ if (!h)
+ return ENXIO;
+
+ hc = bgp->rfapi_cfg;
+ if (!hc)
+ return ENXIO;
+
+ rc = rfapiRaddr2Qprefix(&rfd->vn_addr, &pfx_vn);
+ assert(!rc);
+
+ rc = rfapiRaddr2Qprefix(&rfd->un_addr, &pfx_un);
+ assert(!rc);
+
+ /*
+ * Find the matching nve group config block
+ */
+ rfg = bgp_rfapi_cfg_match_group(hc, &pfx_vn, &pfx_un);
+ if (!rfg) {
+ return ENOENT;
+ }
+
+ /*
+ * check nve group config block for required values
+ */
+ if (!rfg->rt_export_list || !rfg->rfapi_import_table) {
+
+ return ENOMSG;
+ }
+
+ rc = rfapi_open_inner(rfd, bgp, h, rfg);
+ if (rc) {
+ return rc;
+ }
+
+ /*
+ * re-advertise registered routes, this time as part of new NVE-group
+ */
+ rfapiApReadvertiseAll(bgp, rfd);
+
+ /*
+ * re-attach callbacks to import table
+ */
+ if (!(bgp->rfapi_cfg->flags & BGP_VNC_CONFIG_CALLBACK_DISABLE)) {
+ rfapiMonitorAttachImportHd(rfd);
+ }
+
+ return 0;
}
/*------------------------------------------
@@ -1999,7 +1852,7 @@ rfapi_open_rfd (struct rfapi_descriptor *rfd, struct bgp *bgp)
* This function initializes a NVE record and associates it with
* the specified VN and underlay network addresses
*
- * input:
+ * input:
* rfp_start_val value returned by rfp_start
* vn NVE virtual network address
*
@@ -2017,13 +1870,13 @@ rfapi_open_rfd (struct rfapi_descriptor *rfd, struct bgp *bgp)
*
* output:
* response_lifetime The length of time that responses sent to this
- * NVE are valid.
+ * NVE are valid.
*
* pHandle pointer to location to store rfapi handle. The
* handle must be passed on subsequent rfapi_ calls.
*
*
- * return value:
+ * return value:
* 0 Success
* EEXIST NVE with this {vn,un} already open
* ENOENT No matching nve group config
@@ -2033,188 +1886,176 @@ rfapi_open_rfd (struct rfapi_descriptor *rfd, struct bgp *bgp)
* but underlay network address is not IPv4
* EDEADLK Called from within a callback procedure
*------------------------------------------*/
-int
-rfapi_open (
- void *rfp_start_val,
- struct rfapi_ip_addr *vn,
- struct rfapi_ip_addr *un,
- struct rfapi_un_option *default_options,
- uint32_t *response_lifetime,
- void *userdata, /* callback cookie */
- rfapi_handle *pHandle)
+int rfapi_open(void *rfp_start_val, struct rfapi_ip_addr *vn,
+ struct rfapi_ip_addr *un,
+ struct rfapi_un_option *default_options,
+ uint32_t *response_lifetime,
+ void *userdata, /* callback cookie */
+ rfapi_handle *pHandle)
{
- struct bgp *bgp;
- struct rfapi *h;
- struct rfapi_descriptor *rfd;
- struct rfapi_cfg *hc;
- struct rfapi_nve_group_cfg *rfg;
-
- struct prefix pfx_vn;
- struct prefix pfx_un;
-
- int rc;
- rfapi_handle hh = NULL;
- int reusing_provisional = 0;
-
- {
- char buf[2][INET_ADDRSTRLEN];
- vnc_zlog_debug_verbose ("%s: VN=%s UN=%s", __func__,
- rfapiRfapiIpAddr2Str (vn, buf[0], INET_ADDRSTRLEN),
- rfapiRfapiIpAddr2Str (un, buf[1], INET_ADDRSTRLEN));
- }
-
- assert (pHandle);
- *pHandle = NULL;
-
- bgp = rfapi_bgp_lookup_by_rfp (rfp_start_val);
- if (!bgp)
- return ENXIO;
-
- h = bgp->rfapi;
- if (!h)
- return ENXIO;
-
- hc = bgp->rfapi_cfg;
- if (!hc)
- return ENXIO;
-
- if (h->flags & RFAPI_INCALLBACK)
- return EDEADLK;
-
- rc = rfapiRaddr2Qprefix (vn, &pfx_vn);
- assert (!rc);
-
- rc = rfapiRaddr2Qprefix (un, &pfx_un);
- assert (!rc);
-
- /*
- * already have a descriptor with VN and UN?
- */
- if (!rfapi_find_handle (bgp, vn, un, &hh))
- {
- /*
- * we might have set up a handle for static routes before
- * this NVE was opened. In that case, reuse the handle
- */
- rfd = hh;
- if (!CHECK_FLAG (rfd->flags, RFAPI_HD_FLAG_PROVISIONAL))
- {
- return EEXIST;
- }
-
- /*
- * reuse provisional descriptor
- * hh is not NULL
- */
- reusing_provisional = 1;
- }
-
- /*
- * Find the matching nve group config block
- */
- rfg = bgp_rfapi_cfg_match_group (hc, &pfx_vn, &pfx_un);
- if (!rfg)
- {
- ++h->stat.count_unknown_nves;
- {
- char buf[2][INET_ADDRSTRLEN];
- zlog_notice ("%s: no matching group VN=%s UN=%s", __func__,
- rfapiRfapiIpAddr2Str (vn, buf[0], INET_ADDRSTRLEN),
- rfapiRfapiIpAddr2Str (un, buf[1], INET_ADDRSTRLEN));
- }
- return ENOENT;
- }
-
- /*
- * check nve group config block for required values
- */
- if (!rfg->rt_export_list || !rfg->rfapi_import_table)
- {
-
- ++h->stat.count_unknown_nves;
- return ENOMSG;
- }
-
- /*
- * If group config specifies auto-rd assignment, check that
- * VN address is IPv4|v6 so we don't fail in rfapi_open_inner().
- * Check here so we don't need to unwind memory allocations, &c.
- */
- if ((rfg->rd.family == AF_UNIX) && (vn->addr_family != AF_INET)
- && (vn->addr_family != AF_INET6))
- {
- return EAFNOSUPPORT;
- }
-
- if (hh)
- {
- /*
- * reusing provisional rfd
- */
- rfd = hh;
- }
- else
- {
- rfd = XCALLOC (MTYPE_RFAPI_DESC, sizeof (struct rfapi_descriptor));
- }
- assert (rfd);
-
- rfd->bgp = bgp;
- if (default_options)
- {
- struct rfapi_un_option *p;
-
- for (p = default_options; p; p = p->next)
- {
- if ((RFAPI_UN_OPTION_TYPE_PROVISIONAL == p->type))
- {
- rfd->flags |= RFAPI_HD_FLAG_PROVISIONAL;
- }
- if ((RFAPI_UN_OPTION_TYPE_TUNNELTYPE == p->type))
- {
- rfd->default_tunneltype_option = p->v.tunnel;
- }
- }
- }
-
- /*
- * Fill in caller fields
- */
- rfd->vn_addr = *vn;
- rfd->un_addr = *un;
- rfd->cookie = userdata;
-
- if (!reusing_provisional)
- {
- rc = rfapi_init_and_open(bgp, rfd, rfg);
- /*
- * This can fail only if the VN address is IPv6 and the group
- * specified auto-assignment of RDs, which only works for v4,
- * and the check above should catch it.
- *
- * Another failure possibility is that we were called
- * during an rfapi callback. Also checked above.
- */
- assert (!rc);
- }
-
- if (response_lifetime)
- *response_lifetime = rfd->response_lifetime;
- *pHandle = rfd;
- return 0;
+ struct bgp *bgp;
+ struct rfapi *h;
+ struct rfapi_descriptor *rfd;
+ struct rfapi_cfg *hc;
+ struct rfapi_nve_group_cfg *rfg;
+
+ struct prefix pfx_vn;
+ struct prefix pfx_un;
+
+ int rc;
+ rfapi_handle hh = NULL;
+ int reusing_provisional = 0;
+
+ {
+ char buf[2][INET_ADDRSTRLEN];
+ vnc_zlog_debug_verbose(
+ "%s: VN=%s UN=%s", __func__,
+ rfapiRfapiIpAddr2Str(vn, buf[0], INET_ADDRSTRLEN),
+ rfapiRfapiIpAddr2Str(un, buf[1], INET_ADDRSTRLEN));
+ }
+
+ assert(pHandle);
+ *pHandle = NULL;
+
+ bgp = rfapi_bgp_lookup_by_rfp(rfp_start_val);
+ if (!bgp)
+ return ENXIO;
+
+ h = bgp->rfapi;
+ if (!h)
+ return ENXIO;
+
+ hc = bgp->rfapi_cfg;
+ if (!hc)
+ return ENXIO;
+
+ if (h->flags & RFAPI_INCALLBACK)
+ return EDEADLK;
+
+ rc = rfapiRaddr2Qprefix(vn, &pfx_vn);
+ assert(!rc);
+
+ rc = rfapiRaddr2Qprefix(un, &pfx_un);
+ assert(!rc);
+
+ /*
+ * already have a descriptor with VN and UN?
+ */
+ if (!rfapi_find_handle(bgp, vn, un, &hh)) {
+ /*
+ * we might have set up a handle for static routes before
+ * this NVE was opened. In that case, reuse the handle
+ */
+ rfd = hh;
+ if (!CHECK_FLAG(rfd->flags, RFAPI_HD_FLAG_PROVISIONAL)) {
+ return EEXIST;
+ }
+
+ /*
+ * reuse provisional descriptor
+ * hh is not NULL
+ */
+ reusing_provisional = 1;
+ }
+
+ /*
+ * Find the matching nve group config block
+ */
+ rfg = bgp_rfapi_cfg_match_group(hc, &pfx_vn, &pfx_un);
+ if (!rfg) {
+ ++h->stat.count_unknown_nves;
+ {
+ char buf[2][INET_ADDRSTRLEN];
+ zlog_notice("%s: no matching group VN=%s UN=%s",
+ __func__,
+ rfapiRfapiIpAddr2Str(vn, buf[0],
+ INET_ADDRSTRLEN),
+ rfapiRfapiIpAddr2Str(un, buf[1],
+ INET_ADDRSTRLEN));
+ }
+ return ENOENT;
+ }
+
+ /*
+ * check nve group config block for required values
+ */
+ if (!rfg->rt_export_list || !rfg->rfapi_import_table) {
+
+ ++h->stat.count_unknown_nves;
+ return ENOMSG;
+ }
+
+ /*
+ * If group config specifies auto-rd assignment, check that
+ * VN address is IPv4|v6 so we don't fail in rfapi_open_inner().
+ * Check here so we don't need to unwind memory allocations, &c.
+ */
+ if ((rfg->rd.family == AF_UNIX) && (vn->addr_family != AF_INET)
+ && (vn->addr_family != AF_INET6)) {
+ return EAFNOSUPPORT;
+ }
+
+ if (hh) {
+ /*
+ * reusing provisional rfd
+ */
+ rfd = hh;
+ } else {
+ rfd = XCALLOC(MTYPE_RFAPI_DESC,
+ sizeof(struct rfapi_descriptor));
+ }
+ assert(rfd);
+
+ rfd->bgp = bgp;
+ if (default_options) {
+ struct rfapi_un_option *p;
+
+ for (p = default_options; p; p = p->next) {
+ if ((RFAPI_UN_OPTION_TYPE_PROVISIONAL == p->type)) {
+ rfd->flags |= RFAPI_HD_FLAG_PROVISIONAL;
+ }
+ if ((RFAPI_UN_OPTION_TYPE_TUNNELTYPE == p->type)) {
+ rfd->default_tunneltype_option = p->v.tunnel;
+ }
+ }
+ }
+
+ /*
+ * Fill in caller fields
+ */
+ rfd->vn_addr = *vn;
+ rfd->un_addr = *un;
+ rfd->cookie = userdata;
+
+ if (!reusing_provisional) {
+ rc = rfapi_init_and_open(bgp, rfd, rfg);
+ /*
+ * This can fail only if the VN address is IPv6 and the group
+ * specified auto-assignment of RDs, which only works for v4,
+ * and the check above should catch it.
+ *
+ * Another failure possibility is that we were called
+ * during an rfapi callback. Also checked above.
+ */
+ assert(!rc);
+ }
+
+ if (response_lifetime)
+ *response_lifetime = rfd->response_lifetime;
+ *pHandle = rfd;
+ return 0;
}
/*
* For use with debug functions
*/
-static int
-rfapi_set_response_cb (struct rfapi_descriptor *rfd,
- rfapi_response_cb_t * response_cb)
+static int rfapi_set_response_cb(struct rfapi_descriptor *rfd,
+ rfapi_response_cb_t *response_cb)
{
- if (!is_valid_rfd (rfd))
- return EBADF;
- rfd->response_cb = response_cb;
- return 0;
+ if (!is_valid_rfd(rfd))
+ return EBADF;
+ rfd->response_cb = response_cb;
+ return 0;
}
/*
@@ -2230,246 +2071,234 @@ rfapi_set_response_cb (struct rfapi_descriptor *rfd,
* reassignment of an already-open nve to a new nve-group in the
* event that its original nve-group is administratively deleted.
*/
-static int
-rfapi_close_inner (struct rfapi_descriptor *rfd, struct bgp *bgp)
+static int rfapi_close_inner(struct rfapi_descriptor *rfd, struct bgp *bgp)
{
- int rc;
- struct prefix pfx_vn;
- struct prefix_rd prd; /* currently always 0 for VN->UN */
-
- if (!is_valid_rfd (rfd))
- return EBADF;
-
- rc = rfapiRaddr2Qprefix (&rfd->vn_addr, &pfx_vn);
- assert (!rc); /* should never have bad AF in stored vn address */
-
- /*
- * update exported routes to reflect disappearance of this NVE as nexthop
- */
- vnc_direct_bgp_del_nve (bgp, rfd);
- vnc_zebra_del_nve (bgp, rfd);
-
- /*
- * unlink this HD's monitors from import table
- */
- rfapiMonitorDetachImportHd (rfd);
-
- /*
- * Unlink from Import Table
- * NB rfd->import_table will be NULL if we are closing a stale descriptor
- */
- if (rfd->import_table)
- rfapiImportTableRefDelByIt (bgp, rfd->import_table);
- rfd->import_table = NULL;
-
- /*
- * Construct route distinguisher
- */
- memset (&prd, 0, sizeof (prd));
- prd = rfd->rd;
- prd.family = AF_UNSPEC;
- prd.prefixlen = 64;
-
- /*
- * withdraw tunnel
- */
- del_vnc_route (
- rfd,
- rfd->peer,
- bgp,
- SAFI_ENCAP,
- &pfx_vn, /* prefix being advertised */
- &prd, /* route distinguisher to use (0 for ENCAP) */
- ZEBRA_ROUTE_BGP,
- BGP_ROUTE_RFP,
- NULL,
- 0); /* no kill */
-
- /*
- * Construct route distinguisher for VPN routes
- */
- prd = rfd->rd;
- prd.family = AF_UNSPEC;
- prd.prefixlen = 64;
-
- /*
- * find all VPN routes associated with this rfd and delete them, too
- */
- rfapiApWithdrawAll (bgp, rfd);
-
- /*
- * remove this nve descriptor from the list of nves
- * associated with the nve group
- */
- if (rfd->rfg)
- {
- listnode_delete (rfd->rfg->nves, rfd);
- rfd->rfg = NULL; /* XXX mark as orphaned/stale */
- }
-
- if (rfd->rt_export_list)
- ecommunity_free (&rfd->rt_export_list);
- rfd->rt_export_list = NULL;
-
- /*
- * free peer structure (possibly delayed until its
- * refcount reaches zero)
- */
- if (rfd->peer)
- {
- vnc_zlog_debug_verbose ("%s: calling peer_delete(%p), #%d",
- __func__, rfd->peer, rfd->peer->lock);
- peer_delete (rfd->peer);
- }
- rfd->peer = NULL;
-
- return 0;
+ int rc;
+ struct prefix pfx_vn;
+ struct prefix_rd prd; /* currently always 0 for VN->UN */
+
+ if (!is_valid_rfd(rfd))
+ return EBADF;
+
+ rc = rfapiRaddr2Qprefix(&rfd->vn_addr, &pfx_vn);
+ assert(!rc); /* should never have bad AF in stored vn address */
+
+ /*
+ * update exported routes to reflect disappearance of this NVE as
+ * nexthop
+ */
+ vnc_direct_bgp_del_nve(bgp, rfd);
+ vnc_zebra_del_nve(bgp, rfd);
+
+ /*
+ * unlink this HD's monitors from import table
+ */
+ rfapiMonitorDetachImportHd(rfd);
+
+ /*
+ * Unlink from Import Table
+ * NB rfd->import_table will be NULL if we are closing a stale
+ * descriptor
+ */
+ if (rfd->import_table)
+ rfapiImportTableRefDelByIt(bgp, rfd->import_table);
+ rfd->import_table = NULL;
+
+ /*
+ * Construct route distinguisher
+ */
+ memset(&prd, 0, sizeof(prd));
+ prd = rfd->rd;
+ prd.family = AF_UNSPEC;
+ prd.prefixlen = 64;
+
+ /*
+ * withdraw tunnel
+ */
+ del_vnc_route(rfd, rfd->peer, bgp, SAFI_ENCAP,
+ &pfx_vn, /* prefix being advertised */
+ &prd, /* route distinguisher to use (0 for ENCAP) */
+ ZEBRA_ROUTE_BGP, BGP_ROUTE_RFP, NULL, 0); /* no kill */
+
+ /*
+ * Construct route distinguisher for VPN routes
+ */
+ prd = rfd->rd;
+ prd.family = AF_UNSPEC;
+ prd.prefixlen = 64;
+
+ /*
+ * find all VPN routes associated with this rfd and delete them, too
+ */
+ rfapiApWithdrawAll(bgp, rfd);
+
+ /*
+ * remove this nve descriptor from the list of nves
+ * associated with the nve group
+ */
+ if (rfd->rfg) {
+ listnode_delete(rfd->rfg->nves, rfd);
+ rfd->rfg = NULL; /* XXX mark as orphaned/stale */
+ }
+
+ if (rfd->rt_export_list)
+ ecommunity_free(&rfd->rt_export_list);
+ rfd->rt_export_list = NULL;
+
+ /*
+ * free peer structure (possibly delayed until its
+ * refcount reaches zero)
+ */
+ if (rfd->peer) {
+ vnc_zlog_debug_verbose("%s: calling peer_delete(%p), #%d",
+ __func__, rfd->peer, rfd->peer->lock);
+ peer_delete(rfd->peer);
+ }
+ rfd->peer = NULL;
+
+ return 0;
}
-int
-rfapi_close (void *handle)
+int rfapi_close(void *handle)
{
- struct rfapi_descriptor *rfd = (struct rfapi_descriptor *) handle;
- int rc;
- struct route_node *node;
- struct bgp *bgp;
- struct rfapi *h;
+ struct rfapi_descriptor *rfd = (struct rfapi_descriptor *)handle;
+ int rc;
+ struct route_node *node;
+ struct bgp *bgp;
+ struct rfapi *h;
- vnc_zlog_debug_verbose ("%s: rfd=%p", __func__, rfd);
+ vnc_zlog_debug_verbose("%s: rfd=%p", __func__, rfd);
#if RFAPI_WHO_IS_CALLING_ME
#ifdef HAVE_GLIBC_BACKTRACE
#define RFAPI_DEBUG_BACKTRACE_NENTRIES 5
- {
- void *buf[RFAPI_DEBUG_BACKTRACE_NENTRIES];
- char **syms;
- int i;
- size_t size;
-
- size = backtrace (buf, RFAPI_DEBUG_BACKTRACE_NENTRIES);
- syms = backtrace_symbols (buf, size);
- for (i = 0; i < size && i < RFAPI_DEBUG_BACKTRACE_NENTRIES; ++i)
- {
- vnc_zlog_debug_verbose ("backtrace[%2d]: %s", i, syms[i]);
- }
- free (syms);
- }
+ {
+ void *buf[RFAPI_DEBUG_BACKTRACE_NENTRIES];
+ char **syms;
+ int i;
+ size_t size;
+
+ size = backtrace(buf, RFAPI_DEBUG_BACKTRACE_NENTRIES);
+ syms = backtrace_symbols(buf, size);
+ for (i = 0; i < size && i < RFAPI_DEBUG_BACKTRACE_NENTRIES;
+ ++i) {
+ vnc_zlog_debug_verbose("backtrace[%2d]: %s", i,
+ syms[i]);
+ }
+ free(syms);
+ }
#endif
#endif
- bgp = rfd->bgp;
- if (!bgp)
- return ENXIO;
-
- h = bgp->rfapi;
- if (!h)
- return ENXIO;
-
- if (!is_valid_rfd (rfd))
- return EBADF;
-
- if (h->flags & RFAPI_INCALLBACK)
- {
- /*
- * Queue these close requests for processing after callback
- * is finished
- */
- if (!CHECK_FLAG (rfd->flags, RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY))
- {
- work_queue_add (h->deferred_close_q, handle);
- vnc_zlog_debug_verbose ("%s: added handle %p to deferred close queue",
- __func__, handle);
- }
- return 0;
- }
-
- if (CHECK_FLAG (rfd->flags, RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY))
- {
-
- vnc_zlog_debug_verbose ("%s administrative close rfd=%p", __func__, rfd);
-
- if (h && h->rfp_methods.close_cb)
- {
- vnc_zlog_debug_verbose ("%s calling close callback rfd=%p", __func__, rfd);
-
- /*
- * call the callback fairly early so that it can still lookup un/vn
- * from handle, etc.
- *
- * NB RFAPI_INCALLBACK is tested above, so if we reach this point
- * we are not already in the context of a callback.
- */
- h->flags |= RFAPI_INCALLBACK;
- (*h->rfp_methods.close_cb) (handle, EIDRM);
- h->flags &= ~RFAPI_INCALLBACK;
- }
- }
-
- if (rfd->rfg)
- {
- /*
- * Orphaned descriptors have already done this part, so do
- * only for non-orphaned descriptors.
- */
- if ((rc = rfapi_close_inner (rfd, bgp)))
- return rc;
- }
-
- /*
- * Remove descriptor from UN index
- * (remove from chain at node)
- */
- rc = rfapi_find_node (bgp, &rfd->vn_addr, &rfd->un_addr, &node);
- if (!rc)
- {
- struct rfapi_descriptor *hh;
-
- if (node->info == rfd)
- {
- node->info = rfd->next;
- }
- else
- {
-
- for (hh = node->info; hh; hh = hh->next)
- {
- if (hh->next == rfd)
- {
- hh->next = rfd->next;
- break;
- }
- }
- }
- route_unlock_node (node);
- }
-
- /*
- * remove from descriptor list
- */
- listnode_delete (&h->descriptors, rfd);
-
- /*
- * Delete monitor list items and free monitor structures
- */
- (void) rfapiMonitorDelHd (rfd);
-
- /*
- * release advertised prefix data
- */
- rfapiApRelease (&rfd->advertised);
-
- /*
- * Release RFP callback RIB
- */
- rfapiRibFree (rfd);
-
- /*
- * free descriptor
- */
- memset (rfd, 0, sizeof (struct rfapi_descriptor));
- XFREE (MTYPE_RFAPI_DESC, rfd);
-
- return 0;
+ bgp = rfd->bgp;
+ if (!bgp)
+ return ENXIO;
+
+ h = bgp->rfapi;
+ if (!h)
+ return ENXIO;
+
+ if (!is_valid_rfd(rfd))
+ return EBADF;
+
+ if (h->flags & RFAPI_INCALLBACK) {
+ /*
+ * Queue these close requests for processing after callback
+ * is finished
+ */
+ if (!CHECK_FLAG(rfd->flags,
+ RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY)) {
+ work_queue_add(h->deferred_close_q, handle);
+ vnc_zlog_debug_verbose(
+ "%s: added handle %p to deferred close queue",
+ __func__, handle);
+ }
+ return 0;
+ }
+
+ if (CHECK_FLAG(rfd->flags, RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY)) {
+
+ vnc_zlog_debug_verbose("%s administrative close rfd=%p",
+ __func__, rfd);
+
+ if (h && h->rfp_methods.close_cb) {
+ vnc_zlog_debug_verbose(
+ "%s calling close callback rfd=%p", __func__,
+ rfd);
+
+ /*
+ * call the callback fairly early so that it can still
+ * lookup un/vn
+ * from handle, etc.
+ *
+ * NB RFAPI_INCALLBACK is tested above, so if we reach
+ * this point
+ * we are not already in the context of a callback.
+ */
+ h->flags |= RFAPI_INCALLBACK;
+ (*h->rfp_methods.close_cb)(handle, EIDRM);
+ h->flags &= ~RFAPI_INCALLBACK;
+ }
+ }
+
+ if (rfd->rfg) {
+ /*
+ * Orphaned descriptors have already done this part, so do
+ * only for non-orphaned descriptors.
+ */
+ if ((rc = rfapi_close_inner(rfd, bgp)))
+ return rc;
+ }
+
+ /*
+ * Remove descriptor from UN index
+ * (remove from chain at node)
+ */
+ rc = rfapi_find_node(bgp, &rfd->vn_addr, &rfd->un_addr, &node);
+ if (!rc) {
+ struct rfapi_descriptor *hh;
+
+ if (node->info == rfd) {
+ node->info = rfd->next;
+ } else {
+
+ for (hh = node->info; hh; hh = hh->next) {
+ if (hh->next == rfd) {
+ hh->next = rfd->next;
+ break;
+ }
+ }
+ }
+ route_unlock_node(node);
+ }
+
+ /*
+ * remove from descriptor list
+ */
+ listnode_delete(&h->descriptors, rfd);
+
+ /*
+ * Delete monitor list items and free monitor structures
+ */
+ (void)rfapiMonitorDelHd(rfd);
+
+ /*
+ * release advertised prefix data
+ */
+ rfapiApRelease(&rfd->advertised);
+
+ /*
+ * Release RFP callback RIB
+ */
+ rfapiRibFree(rfd);
+
+ /*
+ * free descriptor
+ */
+ memset(rfd, 0, sizeof(struct rfapi_descriptor));
+ XFREE(MTYPE_RFAPI_DESC, rfd);
+
+ return 0;
}
/*
@@ -2489,580 +2318,535 @@ rfapi_close (void *handle)
* caused by deleting and then adding the NVE: advertised prefixes
* and nexthop lists for exported routes can turn over.
*/
-int
-rfapi_reopen (struct rfapi_descriptor *rfd, struct bgp *bgp)
+int rfapi_reopen(struct rfapi_descriptor *rfd, struct bgp *bgp)
{
- struct rfapi *h;
- int rc;
-
- if ((rc = rfapi_close_inner (rfd, bgp)))
- {
- return rc;
- }
- if ((rc = rfapi_open_rfd (rfd, bgp)))
- {
-
- h = bgp->rfapi;
-
- assert (!CHECK_FLAG (h->flags, RFAPI_INCALLBACK));
-
- if (CHECK_FLAG (rfd->flags, RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY) &&
- h && h->rfp_methods.close_cb)
- {
-
- /*
- * NB RFAPI_INCALLBACK is tested above, so if we reach this point
- * we are not already in the context of a callback.
- */
- h->flags |= RFAPI_INCALLBACK;
- (*h->rfp_methods.close_cb) ((rfapi_handle) rfd, ESTALE);
- h->flags &= ~RFAPI_INCALLBACK;
- }
- return rc;
- }
- return 0;
+ struct rfapi *h;
+ int rc;
+
+ if ((rc = rfapi_close_inner(rfd, bgp))) {
+ return rc;
+ }
+ if ((rc = rfapi_open_rfd(rfd, bgp))) {
+
+ h = bgp->rfapi;
+
+ assert(!CHECK_FLAG(h->flags, RFAPI_INCALLBACK));
+
+ if (CHECK_FLAG(rfd->flags,
+ RFAPI_HD_FLAG_CLOSING_ADMINISTRATIVELY)
+ && h && h->rfp_methods.close_cb) {
+
+ /*
+ * NB RFAPI_INCALLBACK is tested above, so if we reach
+ * this point
+ * we are not already in the context of a callback.
+ */
+ h->flags |= RFAPI_INCALLBACK;
+ (*h->rfp_methods.close_cb)((rfapi_handle)rfd, ESTALE);
+ h->flags &= ~RFAPI_INCALLBACK;
+ }
+ return rc;
+ }
+ return 0;
}
/***********************************************************************
* NVE Routes
***********************************************************************/
-/*
+/*
* Announce reachability to this prefix via the NVE
*/
-int
-rfapi_register (
- void *handle,
- struct rfapi_ip_prefix *prefix,
- uint32_t lifetime, /* host byte order */
- struct rfapi_un_option *options_un,
- struct rfapi_vn_option *options_vn,
- rfapi_register_action action)
+int rfapi_register(void *handle, struct rfapi_ip_prefix *prefix,
+ uint32_t lifetime, /* host byte order */
+ struct rfapi_un_option *options_un,
+ struct rfapi_vn_option *options_vn,
+ rfapi_register_action action)
{
- struct rfapi_descriptor *rfd = (struct rfapi_descriptor *) handle;
- struct bgp *bgp;
- struct prefix p;
- struct prefix *pfx_ip = NULL;
- struct prefix_rd prd;
- int afi;
- struct prefix pfx_mac_buf;
- struct prefix *pfx_mac = NULL;
- struct prefix pfx_vn_buf;
- const char *action_str = NULL;
- uint32_t *label = NULL;
- struct rfapi_vn_option *vo;
- struct rfapi_l2address_option *l2o = NULL;
- struct prefix_rd *prd_override = NULL;
-
- switch (action)
- {
- case RFAPI_REGISTER_ADD:
- action_str = "add";
- break;
- case RFAPI_REGISTER_WITHDRAW:
- action_str = "withdraw";
- break;
- case RFAPI_REGISTER_KILL:
- action_str = "kill";
- break;
- default:
- assert (0);
- break;
- }
-
- /*
- * Inspect VN options
- */
- for (vo = options_vn; vo; vo = vo->next)
- {
- if (RFAPI_VN_OPTION_TYPE_L2ADDR == vo->type)
- {
- l2o = &vo->v.l2addr;
- }
- if (RFAPI_VN_OPTION_TYPE_INTERNAL_RD == vo->type)
- {
- prd_override = &vo->v.internal_rd;
- }
- }
-
- /*********************************************************************
- * advertise prefix
- *********************************************************************/
-
- /*
- * set <p> based on <prefix>
- */
- assert (!rfapiRprefix2Qprefix (prefix, &p));
-
- afi = family2afi (prefix->prefix.addr_family);
- assert (afi);
-
-
- {
- char buf[BUFSIZ];
-
- prefix2str (&p, buf, BUFSIZ);
- buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */
- vnc_zlog_debug_verbose
- ("%s(rfd=%p, pfx=%s, lifetime=%d, opts_un=%p, opts_vn=%p, action=%s)",
- __func__, rfd, buf, lifetime, options_un, options_vn, action_str);
- }
-
- /*
- * These tests come after the prefix conversion so that we can
- * print the prefix in a debug message before failing
- */
-
- bgp = rfd->bgp;
- if (!bgp)
- {
- vnc_zlog_debug_verbose ("%s: no BGP instance: returning ENXIO", __func__);
- return ENXIO;
- }
- if (!bgp->rfapi)
- {
- vnc_zlog_debug_verbose ("%s: no RFAPI instance: returning ENXIO", __func__);
- return ENXIO;
- }
- if (!rfd->rfg)
- {
- if (RFAPI_REGISTER_ADD == action)
- {
- ++bgp->rfapi->stat.count_registrations_failed;
- }
- vnc_zlog_debug_verbose ("%s: rfd=%p, no RF GRP instance: returning ESTALE",
- __func__, rfd);
- return ESTALE;
- }
-
- if (bgp->rfapi->flags & RFAPI_INCALLBACK)
- {
- if (RFAPI_REGISTER_ADD == action)
- {
- ++bgp->rfapi->stat.count_registrations_failed;
- }
- vnc_zlog_debug_verbose ("%s: in callback: returning EDEADLK", __func__);
- return EDEADLK;
- }
-
- if (!is_valid_rfd (rfd))
- {
- if (RFAPI_REGISTER_ADD == action)
- {
- ++bgp->rfapi->stat.count_registrations_failed;
- }
- vnc_zlog_debug_verbose ("%s: invalid handle: returning EBADF", __func__);
- return EBADF;
- }
-
- /*
- * Is there a MAC address in this registration?
- */
- if (l2o && !RFAPI_0_ETHERADDR (&l2o->macaddr))
- {
- rfapiL2o2Qprefix (l2o, &pfx_mac_buf);
- pfx_mac = &pfx_mac_buf;
- }
-
- /*
- * Is there an IP prefix in this registration?
- */
- if (!(RFAPI_0_PREFIX (&p) && RFAPI_HOST_PREFIX (&p)))
- {
- pfx_ip = &p;
- }
- else
- {
- if (!pfx_mac)
- {
- vnc_zlog_debug_verbose ("%s: missing mac addr that is required for host 0 pfx",
- __func__);
- if (RFAPI_REGISTER_ADD == action)
- {
- ++bgp->rfapi->stat.count_registrations_failed;
- }
- return EINVAL;
- }
- if (rfapiRaddr2Qprefix (&rfd->vn_addr, &pfx_vn_buf))
- {
- vnc_zlog_debug_verbose ("%s: handle has bad vn_addr: returning EBADF",
- __func__);
- if (RFAPI_REGISTER_ADD == action)
- {
- ++bgp->rfapi->stat.count_registrations_failed;
- }
- return EBADF;
- }
- }
-
- if (RFAPI_REGISTER_ADD == action)
- {
- ++bgp->rfapi->stat.count_registrations;
- }
-
- /*
- * Figure out if this registration is missing an IP address
- *
- * MAC-addr based:
- *
- * In RFAPI, we use prefixes in family AF_LINK to store
- * the MAC addresses. These prefixes are used for the
- * list of advertised prefixes and in the RFAPI import
- * tables.
- *
- * In BGP proper, we use the prefix matching the NVE's
- * VN address with a host prefix-length (i.e., 32 or 128).
- *
- */
- if (l2o && l2o->logical_net_id && RFAPI_0_PREFIX (&p) &&
- RFAPI_HOST_PREFIX (&p))
- {
-
- rfapiL2o2Qprefix (l2o, &pfx_mac_buf);
- pfx_mac = &pfx_mac_buf;
- }
-
- /*
- * Construct route distinguisher
- */
- if (prd_override)
- {
- prd = *prd_override;
- }
- else
- {
- memset (&prd, 0, sizeof (prd));
- if (pfx_mac)
- {
- prd.family = AF_UNSPEC;
- prd.prefixlen = 64;
- encode_rd_type(RD_TYPE_VNC_ETH, prd.val);
- if (l2o->local_nve_id || !(rfd->rfg->flags & RFAPI_RFG_L2RD))
- {
- /*
- * If Local NVE ID is specified in message, use it.
- * (if no local default configured, also use it even if 0)
- */
- prd.val[1] = l2o->local_nve_id;
- }
- else
- {
- if (rfd->rfg->l2rd)
- {
- /*
- * locally-configured literal value
- */
- prd.val[1] = rfd->rfg->l2rd;
- }
- else
- {
- /*
- * 0 means auto:vn, which means use LSB of VN addr
- */
- if (rfd->vn_addr.addr_family == AF_INET)
- {
- prd.val[1] =
- *(((char *) &rfd->vn_addr.addr.v4.s_addr) + 3);
- }
- else
- {
- prd.val[1] =
- *(((char *) &rfd->vn_addr.addr.v6.s6_addr) + 15);
- }
- }
- }
- memcpy (prd.val + 2, pfx_mac->u.prefix_eth.octet, 6);
- }
- else
- {
- prd = rfd->rd;
- prd.family = AF_UNSPEC;
- prd.prefixlen = 64;
- }
- }
-
-
- if (action == RFAPI_REGISTER_WITHDRAW || action == RFAPI_REGISTER_KILL)
- {
-
- int adv_tunnel = 0;
-
- /*
- * withdraw previous advertisement
- */
- del_vnc_route (
- rfd,
- rfd->peer,
- bgp,
- SAFI_MPLS_VPN,
- pfx_ip ? pfx_ip : &pfx_vn_buf, /* prefix being advertised */
- &prd, /* route distinguisher (0 for ENCAP) */
- ZEBRA_ROUTE_BGP,
- BGP_ROUTE_RFP,
- NULL,
- action == RFAPI_REGISTER_KILL);
-
- if (0 == rfapiApDelete (bgp, rfd, &p, pfx_mac, &prd, &adv_tunnel))
- {
- if (adv_tunnel)
- rfapiTunnelRouteAnnounce (bgp, rfd, &rfd->max_prefix_lifetime);
- }
-
- }
- else
- {
-
- int adv_tunnel = 0;
- uint32_t local_pref;
- struct ecommunity *rtlist = NULL;
- struct ecommunity_val ecom_value;
-
- if (!rfapiApCount (rfd))
- {
- /*
- * make sure we advertise tunnel route upon adding the
- * first VPN route
- */
- adv_tunnel = 1;
- }
-
- if (rfapiApAdd (bgp, rfd, &p, pfx_mac, &prd, lifetime, prefix->cost,
- l2o))
- {
- adv_tunnel = 1;
- }
-
- vnc_zlog_debug_verbose ("%s: adv_tunnel = %d", __func__, adv_tunnel);
- if (adv_tunnel)
- {
- vnc_zlog_debug_verbose ("%s: announcing tunnel route", __func__);
- rfapiTunnelRouteAnnounce (bgp, rfd, &rfd->max_prefix_lifetime);
- }
-
- vnc_zlog_debug_verbose ("%s: calling add_vnc_route", __func__);
-
- local_pref = rfp_cost_to_localpref (prefix->cost);
-
- if (l2o && l2o->label)
- label = &l2o->label;
-
- if (pfx_mac)
- {
- struct ecommunity *l2com = NULL;
-
- if (label)
- {
- l2com = bgp_rfapi_get_ecommunity_by_lni_label (bgp, 1,
- l2o->logical_net_id,
- *label);
- }
- if (l2com)
- {
- rtlist = ecommunity_dup (l2com);
- }
- else
- {
- /*
- * If mac address is set, add an RT based on the registered LNI
- */
- memset ((char *) &ecom_value, 0, sizeof (ecom_value));
- ecom_value.val[1] = ECOMMUNITY_ROUTE_TARGET;
- ecom_value.val[5] = (l2o->logical_net_id >> 16) & 0xff;
- ecom_value.val[6] = (l2o->logical_net_id >> 8) & 0xff;
- ecom_value.val[7] = (l2o->logical_net_id >> 0) & 0xff;
- rtlist = ecommunity_new();
- ecommunity_add_val (rtlist, &ecom_value);
- }
- if (l2o->tag_id)
- {
- as_t as = bgp->as;
- uint16_t val = l2o->tag_id;
- memset ((char *) &ecom_value, 0, sizeof (ecom_value));
- ecom_value.val[1] = ECOMMUNITY_ROUTE_TARGET;
- if (as > BGP_AS_MAX)
- {
- ecom_value.val[0] = ECOMMUNITY_ENCODE_AS4;
- ecom_value.val[2] = (as >>24) & 0xff;
- ecom_value.val[3] = (as >>16) & 0xff;
- ecom_value.val[4] = (as >>8) & 0xff;
- ecom_value.val[5] = as & 0xff;
- }
- else
- {
- ecom_value.val[0] = ECOMMUNITY_ENCODE_AS;
- ecom_value.val[2] = (as >>8) & 0xff;
- ecom_value.val[3] = as & 0xff;
- }
- ecom_value.val[6] = (val >> 8) & 0xff;
- ecom_value.val[7] = val & 0xff;
- if (rtlist == NULL)
- rtlist = ecommunity_new();
- ecommunity_add_val (rtlist, &ecom_value);
- }
- }
-
- /*
- * advertise prefix via tunnel endpoint
- */
- add_vnc_route (
- rfd, /* rfapi descr, for export list & backref */
- bgp, /* which bgp instance */
- SAFI_MPLS_VPN, /* which SAFI */
- (pfx_ip ? pfx_ip : &pfx_vn_buf), /* prefix being advertised */
- &prd, /* route distinguisher to use (0 for ENCAP) */
- &rfd->vn_addr, /* nexthop */
- &local_pref,
- &lifetime, /* prefix lifetime -> Tunnel Encap attr */
- NULL,
- options_un, /* rfapi un options */
- options_vn, /* rfapi vn options */
- (rtlist ? rtlist : rfd->rt_export_list),
- NULL, /* med */
- label, /* label: default */
- ZEBRA_ROUTE_BGP,
- BGP_ROUTE_RFP,
- 0);
-
- if (rtlist)
- ecommunity_free (&rtlist); /* sets rtlist = NULL */
- }
-
- vnc_zlog_debug_verbose ("%s: success", __func__);
- return 0;
+ struct rfapi_descriptor *rfd = (struct rfapi_descriptor *)handle;
+ struct bgp *bgp;
+ struct prefix p;
+ struct prefix *pfx_ip = NULL;
+ struct prefix_rd prd;
+ int afi;
+ struct prefix pfx_mac_buf;
+ struct prefix *pfx_mac = NULL;
+ struct prefix pfx_vn_buf;
+ const char *action_str = NULL;
+ uint32_t *label = NULL;
+ struct rfapi_vn_option *vo;
+ struct rfapi_l2address_option *l2o = NULL;
+ struct prefix_rd *prd_override = NULL;
+
+ switch (action) {
+ case RFAPI_REGISTER_ADD:
+ action_str = "add";
+ break;
+ case RFAPI_REGISTER_WITHDRAW:
+ action_str = "withdraw";
+ break;
+ case RFAPI_REGISTER_KILL:
+ action_str = "kill";
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ /*
+ * Inspect VN options
+ */
+ for (vo = options_vn; vo; vo = vo->next) {
+ if (RFAPI_VN_OPTION_TYPE_L2ADDR == vo->type) {
+ l2o = &vo->v.l2addr;
+ }
+ if (RFAPI_VN_OPTION_TYPE_INTERNAL_RD == vo->type) {
+ prd_override = &vo->v.internal_rd;
+ }
+ }
+
+ /*********************************************************************
+ * advertise prefix
+ *********************************************************************/
+
+ /*
+ * set <p> based on <prefix>
+ */
+ assert(!rfapiRprefix2Qprefix(prefix, &p));
+
+ afi = family2afi(prefix->prefix.addr_family);
+ assert(afi);
+
+
+ {
+ char buf[BUFSIZ];
+
+ prefix2str(&p, buf, BUFSIZ);
+ buf[BUFSIZ - 1] = 0; /* guarantee NUL-terminated */
+ vnc_zlog_debug_verbose(
+ "%s(rfd=%p, pfx=%s, lifetime=%d, opts_un=%p, opts_vn=%p, action=%s)",
+ __func__, rfd, buf, lifetime, options_un, options_vn,
+ action_str);
+ }
+
+ /*
+ * These tests come after the prefix conversion so that we can
+ * print the prefix in a debug message before failing
+ */
+
+ bgp = rfd->bgp;
+ if (!bgp) {
+ vnc_zlog_debug_verbose("%s: no BGP instance: returning ENXIO",
+ __func__);
+ return ENXIO;
+ }
+ if (!bgp->rfapi) {
+ vnc_zlog_debug_verbose("%s: no RFAPI instance: returning ENXIO",
+ __func__);
+ return ENXIO;
+ }
+ if (!rfd->rfg) {
+ if (RFAPI_REGISTER_ADD == action) {
+ ++bgp->rfapi->stat.count_registrations_failed;
+ }
+ vnc_zlog_debug_verbose(
+ "%s: rfd=%p, no RF GRP instance: returning ESTALE",
+ __func__, rfd);
+ return ESTALE;
+ }
+
+ if (bgp->rfapi->flags & RFAPI_INCALLBACK) {
+ if (RFAPI_REGISTER_ADD == action) {
+ ++bgp->rfapi->stat.count_registrations_failed;
+ }
+ vnc_zlog_debug_verbose("%s: in callback: returning EDEADLK",
+ __func__);
+ return EDEADLK;
+ }
+
+ if (!is_valid_rfd(rfd)) {
+ if (RFAPI_REGISTER_ADD == action) {
+ ++bgp->rfapi->stat.count_registrations_failed;
+ }
+ vnc_zlog_debug_verbose("%s: invalid handle: returning EBADF",
+ __func__);
+ return EBADF;
+ }
+
+ /*
+ * Is there a MAC address in this registration?
+ */
+ if (l2o && !RFAPI_0_ETHERADDR(&l2o->macaddr)) {
+ rfapiL2o2Qprefix(l2o, &pfx_mac_buf);
+ pfx_mac = &pfx_mac_buf;
+ }
+
+ /*
+ * Is there an IP prefix in this registration?
+ */
+ if (!(RFAPI_0_PREFIX(&p) && RFAPI_HOST_PREFIX(&p))) {
+ pfx_ip = &p;
+ } else {
+ if (!pfx_mac) {
+ vnc_zlog_debug_verbose(
+ "%s: missing mac addr that is required for host 0 pfx",
+ __func__);
+ if (RFAPI_REGISTER_ADD == action) {
+ ++bgp->rfapi->stat.count_registrations_failed;
+ }
+ return EINVAL;
+ }
+ if (rfapiRaddr2Qprefix(&rfd->vn_addr, &pfx_vn_buf)) {
+ vnc_zlog_debug_verbose(
+ "%s: handle has bad vn_addr: returning EBADF",
+ __func__);
+ if (RFAPI_REGISTER_ADD == action) {
+ ++bgp->rfapi->stat.count_registrations_failed;
+ }
+ return EBADF;
+ }
+ }
+
+ if (RFAPI_REGISTER_ADD == action) {
+ ++bgp->rfapi->stat.count_registrations;
+ }
+
+ /*
+ * Figure out if this registration is missing an IP address
+ *
+ * MAC-addr based:
+ *
+ * In RFAPI, we use prefixes in family AF_LINK to store
+ * the MAC addresses. These prefixes are used for the
+ * list of advertised prefixes and in the RFAPI import
+ * tables.
+ *
+ * In BGP proper, we use the prefix matching the NVE's
+ * VN address with a host prefix-length (i.e., 32 or 128).
+ *
+ */
+ if (l2o && l2o->logical_net_id && RFAPI_0_PREFIX(&p)
+ && RFAPI_HOST_PREFIX(&p)) {
+
+ rfapiL2o2Qprefix(l2o, &pfx_mac_buf);
+ pfx_mac = &pfx_mac_buf;
+ }
+
+ /*
+ * Construct route distinguisher
+ */
+ if (prd_override) {
+ prd = *prd_override;
+ } else {
+ memset(&prd, 0, sizeof(prd));
+ if (pfx_mac) {
+ prd.family = AF_UNSPEC;
+ prd.prefixlen = 64;
+ encode_rd_type(RD_TYPE_VNC_ETH, prd.val);
+ if (l2o->local_nve_id
+ || !(rfd->rfg->flags & RFAPI_RFG_L2RD)) {
+ /*
+ * If Local NVE ID is specified in message, use
+ * it.
+ * (if no local default configured, also use it
+ * even if 0)
+ */
+ prd.val[1] = l2o->local_nve_id;
+ } else {
+ if (rfd->rfg->l2rd) {
+ /*
+ * locally-configured literal value
+ */
+ prd.val[1] = rfd->rfg->l2rd;
+ } else {
+ /*
+ * 0 means auto:vn, which means use LSB
+ * of VN addr
+ */
+ if (rfd->vn_addr.addr_family
+ == AF_INET) {
+ prd.val[1] =
+ *(((char *)&rfd->vn_addr
+ .addr.v4
+ .s_addr)
+ + 3);
+ } else {
+ prd.val[1] =
+ *(((char *)&rfd->vn_addr
+ .addr.v6
+ .s6_addr)
+ + 15);
+ }
+ }
+ }
+ memcpy(prd.val + 2, pfx_mac->u.prefix_eth.octet, 6);
+ } else {
+ prd = rfd->rd;
+ prd.family = AF_UNSPEC;
+ prd.prefixlen = 64;
+ }
+ }
+
+
+ if (action == RFAPI_REGISTER_WITHDRAW
+ || action == RFAPI_REGISTER_KILL) {
+
+ int adv_tunnel = 0;
+
+ /*
+ * withdraw previous advertisement
+ */
+ del_vnc_route(
+ rfd, rfd->peer, bgp, SAFI_MPLS_VPN,
+ pfx_ip ? pfx_ip
+ : &pfx_vn_buf, /* prefix being advertised */
+ &prd, /* route distinguisher (0 for ENCAP) */
+ ZEBRA_ROUTE_BGP, BGP_ROUTE_RFP, NULL,
+ action == RFAPI_REGISTER_KILL);
+
+ if (0 == rfapiApDelete(bgp, rfd, &p, pfx_mac, &prd,
+ &adv_tunnel)) {
+ if (adv_tunnel)
+ rfapiTunnelRouteAnnounce(
+ bgp, rfd, &rfd->max_prefix_lifetime);
+ }
+
+ } else {
+
+ int adv_tunnel = 0;
+ uint32_t local_pref;
+ struct ecommunity *rtlist = NULL;
+ struct ecommunity_val ecom_value;
+
+ if (!rfapiApCount(rfd)) {
+ /*
+ * make sure we advertise tunnel route upon adding the
+ * first VPN route
+ */
+ adv_tunnel = 1;
+ }
+
+ if (rfapiApAdd(bgp, rfd, &p, pfx_mac, &prd, lifetime,
+ prefix->cost, l2o)) {
+ adv_tunnel = 1;
+ }
+
+ vnc_zlog_debug_verbose("%s: adv_tunnel = %d", __func__,
+ adv_tunnel);
+ if (adv_tunnel) {
+ vnc_zlog_debug_verbose("%s: announcing tunnel route",
+ __func__);
+ rfapiTunnelRouteAnnounce(bgp, rfd,
+ &rfd->max_prefix_lifetime);
+ }
+
+ vnc_zlog_debug_verbose("%s: calling add_vnc_route", __func__);
+
+ local_pref = rfp_cost_to_localpref(prefix->cost);
+
+ if (l2o && l2o->label)
+ label = &l2o->label;
+
+ if (pfx_mac) {
+ struct ecommunity *l2com = NULL;
+
+ if (label) {
+ l2com = bgp_rfapi_get_ecommunity_by_lni_label(
+ bgp, 1, l2o->logical_net_id, *label);
+ }
+ if (l2com) {
+ rtlist = ecommunity_dup(l2com);
+ } else {
+ /*
+ * If mac address is set, add an RT based on the
+ * registered LNI
+ */
+ memset((char *)&ecom_value, 0,
+ sizeof(ecom_value));
+ ecom_value.val[1] = ECOMMUNITY_ROUTE_TARGET;
+ ecom_value.val[5] =
+ (l2o->logical_net_id >> 16) & 0xff;
+ ecom_value.val[6] =
+ (l2o->logical_net_id >> 8) & 0xff;
+ ecom_value.val[7] =
+ (l2o->logical_net_id >> 0) & 0xff;
+ rtlist = ecommunity_new();
+ ecommunity_add_val(rtlist, &ecom_value);
+ }
+ if (l2o->tag_id) {
+ as_t as = bgp->as;
+ uint16_t val = l2o->tag_id;
+ memset((char *)&ecom_value, 0,
+ sizeof(ecom_value));
+ ecom_value.val[1] = ECOMMUNITY_ROUTE_TARGET;
+ if (as > BGP_AS_MAX) {
+ ecom_value.val[0] =
+ ECOMMUNITY_ENCODE_AS4;
+ ecom_value.val[2] = (as >> 24) & 0xff;
+ ecom_value.val[3] = (as >> 16) & 0xff;
+ ecom_value.val[4] = (as >> 8) & 0xff;
+ ecom_value.val[5] = as & 0xff;
+ } else {
+ ecom_value.val[0] =
+ ECOMMUNITY_ENCODE_AS;
+ ecom_value.val[2] = (as >> 8) & 0xff;
+ ecom_value.val[3] = as & 0xff;
+ }
+ ecom_value.val[6] = (val >> 8) & 0xff;
+ ecom_value.val[7] = val & 0xff;
+ if (rtlist == NULL)
+ rtlist = ecommunity_new();
+ ecommunity_add_val(rtlist, &ecom_value);
+ }
+ }
+
+ /*
+ * advertise prefix via tunnel endpoint
+ */
+ add_vnc_route(
+ rfd, /* rfapi descr, for export list & backref */
+ bgp, /* which bgp instance */
+ SAFI_MPLS_VPN, /* which SAFI */
+ (pfx_ip ? pfx_ip
+ : &pfx_vn_buf), /* prefix being advertised */
+ &prd, /* route distinguisher to use (0 for ENCAP) */
+ &rfd->vn_addr, /* nexthop */
+ &local_pref,
+ &lifetime, /* prefix lifetime -> Tunnel Encap attr */
+ NULL, options_un, /* rfapi un options */
+ options_vn, /* rfapi vn options */
+ (rtlist ? rtlist : rfd->rt_export_list), NULL, /* med */
+ label, /* label: default */
+ ZEBRA_ROUTE_BGP, BGP_ROUTE_RFP, 0);
+
+ if (rtlist)
+ ecommunity_free(&rtlist); /* sets rtlist = NULL */
+ }
+
+ vnc_zlog_debug_verbose("%s: success", __func__);
+ return 0;
}
-int
-rfapi_query (
- void *handle,
- struct rfapi_ip_addr *target,
- struct rfapi_l2address_option *l2o, /* may be NULL */
- struct rfapi_next_hop_entry **ppNextHopEntry)
+int rfapi_query(void *handle, struct rfapi_ip_addr *target,
+ struct rfapi_l2address_option *l2o, /* may be NULL */
+ struct rfapi_next_hop_entry **ppNextHopEntry)
{
- struct rfapi_descriptor *rfd = (struct rfapi_descriptor *) handle;
- struct bgp *bgp = rfd->bgp;
- int rc;
-
- assert (ppNextHopEntry);
- *ppNextHopEntry = NULL;
-
- if (bgp && bgp->rfapi)
- {
- bgp->rfapi->stat.count_queries++;
- }
-
- if (!rfd->rfg)
- {
- if (bgp && bgp->rfapi)
- ++bgp->rfapi->stat.count_queries_failed;
- return ESTALE;
- }
-
- if ((rc = rfapi_query_inner (handle, target, l2o, ppNextHopEntry)))
- {
- if (bgp && bgp->rfapi)
- ++bgp->rfapi->stat.count_queries_failed;
- }
- return rc;
+ struct rfapi_descriptor *rfd = (struct rfapi_descriptor *)handle;
+ struct bgp *bgp = rfd->bgp;
+ int rc;
+
+ assert(ppNextHopEntry);
+ *ppNextHopEntry = NULL;
+
+ if (bgp && bgp->rfapi) {
+ bgp->rfapi->stat.count_queries++;
+ }
+
+ if (!rfd->rfg) {
+ if (bgp && bgp->rfapi)
+ ++bgp->rfapi->stat.count_queries_failed;
+ return ESTALE;
+ }
+
+ if ((rc = rfapi_query_inner(handle, target, l2o, ppNextHopEntry))) {
+ if (bgp && bgp->rfapi)
+ ++bgp->rfapi->stat.count_queries_failed;
+ }
+ return rc;
}
-int
-rfapi_query_done (rfapi_handle handle, struct rfapi_ip_addr *target)
+int rfapi_query_done(rfapi_handle handle, struct rfapi_ip_addr *target)
{
- struct prefix p;
- int rc;
- struct rfapi_descriptor *rfd = (struct rfapi_descriptor *) handle;
- struct bgp *bgp = rfd->bgp;
+ struct prefix p;
+ int rc;
+ struct rfapi_descriptor *rfd = (struct rfapi_descriptor *)handle;
+ struct bgp *bgp = rfd->bgp;
- if (!rfd->rfg)
- return ESTALE;
+ if (!rfd->rfg)
+ return ESTALE;
- assert (target);
- rc = rfapiRaddr2Qprefix (target, &p);
- assert (!rc);
+ assert(target);
+ rc = rfapiRaddr2Qprefix(target, &p);
+ assert(!rc);
- if (!is_valid_rfd (rfd))
- return EBADF;
+ if (!is_valid_rfd(rfd))
+ return EBADF;
- /* preemptive */
- if (!bgp || !bgp->rfapi)
- return ENXIO;
+ /* preemptive */
+ if (!bgp || !bgp->rfapi)
+ return ENXIO;
- if (bgp->rfapi->flags & RFAPI_INCALLBACK)
- return EDEADLK;
+ if (bgp->rfapi->flags & RFAPI_INCALLBACK)
+ return EDEADLK;
- rfapiMonitorDel (bgp, rfd, &p);
+ rfapiMonitorDel(bgp, rfd, &p);
- return 0;
+ return 0;
}
-int
-rfapi_query_done_all (rfapi_handle handle, int *count)
+int rfapi_query_done_all(rfapi_handle handle, int *count)
{
- struct rfapi_descriptor *rfd = (struct rfapi_descriptor *) handle;
- struct bgp *bgp = rfd->bgp;;
- int num;
+ struct rfapi_descriptor *rfd = (struct rfapi_descriptor *)handle;
+ struct bgp *bgp = rfd->bgp;
+ ;
+ int num;
- if (!rfd->rfg)
- return ESTALE;
+ if (!rfd->rfg)
+ return ESTALE;
- if (!is_valid_rfd (rfd))
- return EBADF;
+ if (!is_valid_rfd(rfd))
+ return EBADF;
- /* preemptive */
- if (!bgp || !bgp->rfapi)
- return ENXIO;
+ /* preemptive */
+ if (!bgp || !bgp->rfapi)
+ return ENXIO;
- if (bgp->rfapi->flags & RFAPI_INCALLBACK)
- return EDEADLK;
+ if (bgp->rfapi->flags & RFAPI_INCALLBACK)
+ return EDEADLK;
- num = rfapiMonitorDelHd (rfd);
+ num = rfapiMonitorDelHd(rfd);
- if (count)
- *count = num;
+ if (count)
+ *count = num;
- return 0;
+ return 0;
}
-void
-rfapi_free_next_hop_list (struct rfapi_next_hop_entry *list)
+void rfapi_free_next_hop_list(struct rfapi_next_hop_entry *list)
{
- struct rfapi_next_hop_entry *nh;
- struct rfapi_next_hop_entry *next;
-
- for (nh = list; nh; nh = next)
- {
- next = nh->next;
- rfapi_un_options_free (nh->un_options);
- nh->un_options = NULL;
- rfapi_vn_options_free (nh->vn_options);
- nh->vn_options = NULL;
- XFREE (MTYPE_RFAPI_NEXTHOP, nh);
- }
+ struct rfapi_next_hop_entry *nh;
+ struct rfapi_next_hop_entry *next;
+
+ for (nh = list; nh; nh = next) {
+ next = nh->next;
+ rfapi_un_options_free(nh->un_options);
+ nh->un_options = NULL;
+ rfapi_vn_options_free(nh->vn_options);
+ nh->vn_options = NULL;
+ XFREE(MTYPE_RFAPI_NEXTHOP, nh);
+ }
}
/*
* NULL handle => return total count across all nves
*/
-uint32_t
-rfapi_monitor_count (void *handle)
+uint32_t rfapi_monitor_count(void *handle)
{
- struct bgp *bgp = bgp_get_default ();
- uint32_t count;
+ struct bgp *bgp = bgp_get_default();
+ uint32_t count;
- if (handle)
- {
- struct rfapi_descriptor *rfd = (struct rfapi_descriptor *) handle;
- count = rfd->monitor_count;
- }
- else
- {
+ if (handle) {
+ struct rfapi_descriptor *rfd =
+ (struct rfapi_descriptor *)handle;
+ count = rfd->monitor_count;
+ } else {
- if (!bgp || !bgp->rfapi)
- return 0;
+ if (!bgp || !bgp->rfapi)
+ return 0;
- count = bgp->rfapi->monitor_count;
- }
+ count = bgp->rfapi->monitor_count;
+ }
- return count;
+ return count;
}
/***********************************************************************
@@ -3077,8 +2861,8 @@ DEFUN (debug_rfapi_show_nves,
SHOW_STR
"NVE Information\n")
{
- rfapiPrintMatchingDescriptors (vty, NULL, NULL);
- return CMD_SUCCESS;
+ rfapiPrintMatchingDescriptors(vty, NULL, NULL);
+ return CMD_SUCCESS;
}
DEFUN (
@@ -3094,28 +2878,23 @@ DEFUN (
"IPv4 address\n"
"IPv6 address\n")
{
- struct prefix pfx;
-
- if (!str2prefix (argv[5]->arg, &pfx))
- {
- vty_out (vty, "Malformed address \"%s\"\n", argv[5]->arg);
- return CMD_WARNING_CONFIG_FAILED;
- }
- if (pfx.family != AF_INET && pfx.family != AF_INET6)
- {
- vty_out (vty, "Invalid address \"%s\"\n", argv[5]->arg);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- if (argv[4]->arg[0] == 'u')
- {
- rfapiPrintMatchingDescriptors (vty, NULL, &pfx);
- }
- else
- {
- rfapiPrintMatchingDescriptors (vty, &pfx, NULL);
- }
- return CMD_SUCCESS;
+ struct prefix pfx;
+
+ if (!str2prefix(argv[5]->arg, &pfx)) {
+ vty_out(vty, "Malformed address \"%s\"\n", argv[5]->arg);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ if (pfx.family != AF_INET && pfx.family != AF_INET6) {
+ vty_out(vty, "Invalid address \"%s\"\n", argv[5]->arg);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ if (argv[4]->arg[0] == 'u') {
+ rfapiPrintMatchingDescriptors(vty, NULL, &pfx);
+ } else {
+ rfapiPrintMatchingDescriptors(vty, &pfx, NULL);
+ }
+ return CMD_SUCCESS;
}
/*
@@ -3123,29 +2902,27 @@ DEFUN (
* with a stream pointing to a vty, the user will have to type something
* before the callback output shows up
*/
-static void
-test_nexthops_callback (
-// struct rfapi_ip_addr *target,
- struct rfapi_next_hop_entry *next_hops,
- void *userdata)
+static void test_nexthops_callback(
+ // struct rfapi_ip_addr *target,
+ struct rfapi_next_hop_entry *next_hops, void *userdata)
{
- void *stream = userdata;
+ void *stream = userdata;
- int (*fp) (void *, const char *, ...);
- struct vty *vty;
- void *out;
- const char *vty_newline;
+ int (*fp)(void *, const char *, ...);
+ struct vty *vty;
+ void *out;
+ const char *vty_newline;
- if (rfapiStream2Vty (stream, &fp, &vty, &out, &vty_newline) == 0)
- return;
+ if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
+ return;
- fp (out, "Nexthops Callback, Target=(");
- //rfapiPrintRfapiIpAddr(stream, target);
- fp (out, ")\n");
+ fp(out, "Nexthops Callback, Target=(");
+ // rfapiPrintRfapiIpAddr(stream, target);
+ fp(out, ")\n");
- rfapiPrintNhl (stream, next_hops);
+ rfapiPrintNhl(stream, next_hops);
- rfapi_free_next_hop_list (next_hops);
+ rfapi_free_next_hop_list(next_hops);
}
DEFUN (debug_rfapi_open,
@@ -3161,35 +2938,35 @@ DEFUN (debug_rfapi_open,
"underlay network interface IPv4 address\n"
"underlay network interface IPv6 address\n")
{
- struct rfapi_ip_addr vn;
- struct rfapi_ip_addr un;
- uint32_t lifetime;
- int rc;
- rfapi_handle handle;
+ struct rfapi_ip_addr vn;
+ struct rfapi_ip_addr un;
+ uint32_t lifetime;
+ int rc;
+ rfapi_handle handle;
- /*
- * Get VN addr
- */
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[4]->arg, &vn)))
- return rc;
+ /*
+ * Get VN addr
+ */
+ if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[4]->arg, &vn)))
+ return rc;
- /*
- * Get UN addr
- */
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[6]->arg, &un)))
- return rc;
+ /*
+ * Get UN addr
+ */
+ if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[6]->arg, &un)))
+ return rc;
- rc = rfapi_open (rfapi_get_rfp_start_val_by_bgp (bgp_get_default ()),
- &vn, &un, /*&uo */ NULL, &lifetime, NULL, &handle);
+ rc = rfapi_open(rfapi_get_rfp_start_val_by_bgp(bgp_get_default()), &vn,
+ &un, /*&uo */ NULL, &lifetime, NULL, &handle);
- vty_out (vty, "rfapi_open: status %d, handle %p, lifetime %d\n",
- rc, handle, lifetime);
+ vty_out(vty, "rfapi_open: status %d, handle %p, lifetime %d\n", rc,
+ handle, lifetime);
- rc = rfapi_set_response_cb (handle, test_nexthops_callback);
+ rc = rfapi_set_response_cb(handle, test_nexthops_callback);
- vty_out (vty, "rfapi_set_response_cb: status %d\n", rc);
+ vty_out(vty, "rfapi_set_response_cb: status %d\n", rc);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
@@ -3206,37 +2983,36 @@ DEFUN (debug_rfapi_close_vn_un,
"underlay network interface IPv4 address\n"
"underlay network interface IPv6 address\n")
{
- struct rfapi_ip_addr vn;
- struct rfapi_ip_addr un;
- rfapi_handle handle;
- int rc;
+ struct rfapi_ip_addr vn;
+ struct rfapi_ip_addr un;
+ rfapi_handle handle;
+ int rc;
- /*
- * Get VN addr
- */
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[4]->arg, &vn)))
- return rc;
+ /*
+ * Get VN addr
+ */
+ if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[4]->arg, &vn)))
+ return rc;
- /*
- * Get UN addr
- */
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[6]->arg, &un)))
- return rc;
+ /*
+ * Get UN addr
+ */
+ if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[6]->arg, &un)))
+ return rc;
- if (rfapi_find_handle_vty (vty, &vn, &un, &handle))
- {
- vty_out (vty, "can't locate handle matching vn=%s, un=%s\n",
- argv[4]->arg, argv[6]->arg);
- return CMD_WARNING_CONFIG_FAILED;
- }
+ if (rfapi_find_handle_vty(vty, &vn, &un, &handle)) {
+ vty_out(vty, "can't locate handle matching vn=%s, un=%s\n",
+ argv[4]->arg, argv[6]->arg);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- rc = rfapi_close (handle);
+ rc = rfapi_close(handle);
- vty_out (vty, "rfapi_close(handle=%p): status %d\n", handle,rc);
+ vty_out(vty, "rfapi_close(handle=%p): status %d\n", handle, rc);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (debug_rfapi_close_rfd,
@@ -3247,23 +3023,22 @@ DEFUN (debug_rfapi_close_rfd,
"rfapi_close\n"
"indicate handle follows\n" "rfapi handle in hexadecimal\n")
{
- rfapi_handle handle;
- int rc;
- char *endptr = NULL;
+ rfapi_handle handle;
+ int rc;
+ char *endptr = NULL;
- handle = (rfapi_handle) (uintptr_t) (strtoull (argv[4]->arg, &endptr, 16));
+ handle = (rfapi_handle)(uintptr_t)(strtoull(argv[4]->arg, &endptr, 16));
- if (*endptr != '\0' || (uintptr_t) handle == UINTPTR_MAX)
- {
- vty_out (vty, "Invalid value: %s\n", argv[4]->arg);
- return CMD_WARNING_CONFIG_FAILED;
- }
+ if (*endptr != '\0' || (uintptr_t)handle == UINTPTR_MAX) {
+ vty_out(vty, "Invalid value: %s\n", argv[4]->arg);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- rc = rfapi_close (handle);
+ rc = rfapi_close(handle);
- vty_out (vty, "rfapi_close(handle=%p): status %d\n", handle,rc);
+ vty_out(vty, "rfapi_close(handle=%p): status %d\n", handle, rc);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (debug_rfapi_register_vn_un,
@@ -3284,68 +3059,61 @@ DEFUN (debug_rfapi_register_vn_un,
"indicate lifetime follows\n"
"lifetime\n")
{
- struct rfapi_ip_addr vn;
- struct rfapi_ip_addr un;
- rfapi_handle handle;
- struct prefix pfx;
- uint32_t lifetime;
- struct rfapi_ip_prefix hpfx;
- int rc;
-
- /*
- * Get VN addr
- */
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[4]->arg, &vn)))
- return rc;
-
-
- /*
- * Get UN addr
- */
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[6]->arg, &un)))
- return rc;
-
-
- if (rfapi_find_handle_vty (vty, &vn, &un, &handle))
- {
- vty_out (vty, "can't locate handle matching vn=%s, un=%s\n",
- argv[4]->arg, argv[6]->arg);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- /*
- * Get prefix to advertise
- */
- if (!str2prefix (argv[8]->arg, &pfx))
- {
- vty_out (vty, "Malformed prefix \"%s\"\n", argv[8]->arg);
- return CMD_WARNING_CONFIG_FAILED;
- }
- if (pfx.family != AF_INET && pfx.family != AF_INET6)
- {
- vty_out (vty, "Bad family for prefix \"%s\"\n", argv[8]->arg);
- return CMD_WARNING_CONFIG_FAILED;
- }
- rfapiQprefix2Rprefix (&pfx, &hpfx);
-
- if (strmatch(argv[10]->text, "infinite"))
- {
- lifetime = RFAPI_INFINITE_LIFETIME;
- }
- else
- {
- lifetime = strtoul(argv[10]->arg, NULL, 10);
- }
-
-
- rc = rfapi_register (handle, &hpfx, lifetime, NULL, NULL, 0);
- if (rc)
- {
- vty_out (vty, "rfapi_register failed with rc=%d (%s)\n", rc,
- strerror(rc));
- }
-
- return CMD_SUCCESS;
+ struct rfapi_ip_addr vn;
+ struct rfapi_ip_addr un;
+ rfapi_handle handle;
+ struct prefix pfx;
+ uint32_t lifetime;
+ struct rfapi_ip_prefix hpfx;
+ int rc;
+
+ /*
+ * Get VN addr
+ */
+ if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[4]->arg, &vn)))
+ return rc;
+
+
+ /*
+ * Get UN addr
+ */
+ if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[6]->arg, &un)))
+ return rc;
+
+
+ if (rfapi_find_handle_vty(vty, &vn, &un, &handle)) {
+ vty_out(vty, "can't locate handle matching vn=%s, un=%s\n",
+ argv[4]->arg, argv[6]->arg);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ /*
+ * Get prefix to advertise
+ */
+ if (!str2prefix(argv[8]->arg, &pfx)) {
+ vty_out(vty, "Malformed prefix \"%s\"\n", argv[8]->arg);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ if (pfx.family != AF_INET && pfx.family != AF_INET6) {
+ vty_out(vty, "Bad family for prefix \"%s\"\n", argv[8]->arg);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ rfapiQprefix2Rprefix(&pfx, &hpfx);
+
+ if (strmatch(argv[10]->text, "infinite")) {
+ lifetime = RFAPI_INFINITE_LIFETIME;
+ } else {
+ lifetime = strtoul(argv[10]->arg, NULL, 10);
+ }
+
+
+ rc = rfapi_register(handle, &hpfx, lifetime, NULL, NULL, 0);
+ if (rc) {
+ vty_out(vty, "rfapi_register failed with rc=%d (%s)\n", rc,
+ strerror(rc));
+ }
+
+ return CMD_SUCCESS;
}
DEFUN (debug_rfapi_register_vn_un_l2o,
@@ -3370,91 +3138,82 @@ DEFUN (debug_rfapi_register_vn_un_l2o,
"indicate lni follows\n"
"lni value range\n")
{
- struct rfapi_ip_addr vn;
- struct rfapi_ip_addr un;
- rfapi_handle handle;
- struct prefix pfx;
- uint32_t lifetime;
- struct rfapi_ip_prefix hpfx;
- int rc;
- struct rfapi_vn_option optary[10]; /* XXX must be big enough */
- struct rfapi_vn_option *opt = NULL;
- int opt_next = 0;
-
- /*
- * Get VN addr
- */
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[4]->arg, &vn)))
- return rc;
-
-
- /*
- * Get UN addr
- */
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[6]->arg, &un)))
- return rc;
-
-
- if (rfapi_find_handle_vty (vty, &vn, &un, &handle))
- {
- vty_out (vty, "can't locate handle matching vn=%s, un=%s\n",
- argv[4]->arg, argv[6]->arg);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- /*
- * Get prefix to advertise
- */
- if (!str2prefix (argv[8]->arg, &pfx))
- {
- vty_out (vty, "Malformed prefix \"%s\"\n", argv[8]->arg);
- return CMD_WARNING_CONFIG_FAILED;
- }
- if (pfx.family != AF_INET && pfx.family != AF_INET6)
- {
- vty_out (vty, "Bad family for prefix \"%s\"\n", argv[8]->arg);
- return CMD_WARNING_CONFIG_FAILED;
- }
- rfapiQprefix2Rprefix (&pfx, &hpfx);
-
- if (strmatch(argv[10]->text, "infinite"))
- {
- lifetime = RFAPI_INFINITE_LIFETIME;
- }
- else
- {
- lifetime = strtoul(argv[10]->arg, NULL, 10);
- }
-
- /* L2 option parsing START */
- memset (optary, 0, sizeof (optary));
- optary[opt_next].v.l2addr.logical_net_id = strtoul(argv[14]->arg, NULL, 10);
- if ((rc = rfapiStr2EthAddr (argv[12]->arg, &optary[opt_next].v.l2addr.macaddr)))
- {
- vty_out (vty, "Bad mac address \"%s\"\n", argv[12]->arg);
- return CMD_WARNING_CONFIG_FAILED;
- }
- optary[opt_next].type = RFAPI_VN_OPTION_TYPE_L2ADDR;
- if (opt_next)
- {
- optary[opt_next - 1].next = optary + opt_next;
- }
- else
- {
- opt = optary;
- }
- ++opt_next;
- /* L2 option parsing END */
-
- /* TBD fixme */
- rc = rfapi_register (handle, &hpfx, lifetime, NULL /* &uo */ , opt, 0);
- if (rc)
- {
- vty_out (vty, "rfapi_register failed with rc=%d (%s)\n", rc,
- strerror(rc));
- }
-
- return CMD_SUCCESS;
+ struct rfapi_ip_addr vn;
+ struct rfapi_ip_addr un;
+ rfapi_handle handle;
+ struct prefix pfx;
+ uint32_t lifetime;
+ struct rfapi_ip_prefix hpfx;
+ int rc;
+ struct rfapi_vn_option optary[10]; /* XXX must be big enough */
+ struct rfapi_vn_option *opt = NULL;
+ int opt_next = 0;
+
+ /*
+ * Get VN addr
+ */
+ if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[4]->arg, &vn)))
+ return rc;
+
+
+ /*
+ * Get UN addr
+ */
+ if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[6]->arg, &un)))
+ return rc;
+
+
+ if (rfapi_find_handle_vty(vty, &vn, &un, &handle)) {
+ vty_out(vty, "can't locate handle matching vn=%s, un=%s\n",
+ argv[4]->arg, argv[6]->arg);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ /*
+ * Get prefix to advertise
+ */
+ if (!str2prefix(argv[8]->arg, &pfx)) {
+ vty_out(vty, "Malformed prefix \"%s\"\n", argv[8]->arg);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ if (pfx.family != AF_INET && pfx.family != AF_INET6) {
+ vty_out(vty, "Bad family for prefix \"%s\"\n", argv[8]->arg);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ rfapiQprefix2Rprefix(&pfx, &hpfx);
+
+ if (strmatch(argv[10]->text, "infinite")) {
+ lifetime = RFAPI_INFINITE_LIFETIME;
+ } else {
+ lifetime = strtoul(argv[10]->arg, NULL, 10);
+ }
+
+ /* L2 option parsing START */
+ memset(optary, 0, sizeof(optary));
+ optary[opt_next].v.l2addr.logical_net_id =
+ strtoul(argv[14]->arg, NULL, 10);
+ if ((rc = rfapiStr2EthAddr(argv[12]->arg,
+ &optary[opt_next].v.l2addr.macaddr))) {
+ vty_out(vty, "Bad mac address \"%s\"\n", argv[12]->arg);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ optary[opt_next].type = RFAPI_VN_OPTION_TYPE_L2ADDR;
+ if (opt_next) {
+ optary[opt_next - 1].next = optary + opt_next;
+ } else {
+ opt = optary;
+ }
+ ++opt_next;
+ /* L2 option parsing END */
+
+ /* TBD fixme */
+ rc = rfapi_register(handle, &hpfx, lifetime, NULL /* &uo */, opt, 0);
+ if (rc) {
+ vty_out(vty, "rfapi_register failed with rc=%d (%s)\n", rc,
+ strerror(rc));
+ }
+
+ return CMD_SUCCESS;
}
@@ -3470,52 +3229,49 @@ DEFUN (debug_rfapi_unregister_vn_un,
"underlay network interface address\n"
"indicate prefix follows\n" "prefix")
{
- struct rfapi_ip_addr vn;
- struct rfapi_ip_addr un;
- rfapi_handle handle;
- struct prefix pfx;
- struct rfapi_ip_prefix hpfx;
- int rc;
-
- /*
- * Get VN addr
- */
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[4]->arg, &vn)))
- return rc;
-
-
- /*
- * Get UN addr
- */
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[6]->arg, &un)))
- return rc;
-
-
- if (rfapi_find_handle_vty (vty, &vn, &un, &handle))
- {
- vty_out (vty, "can't locate handle matching vn=%s, un=%s\n",
- argv[4]->arg, argv[6]->arg);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- /*
- * Get prefix to advertise
- */
- if (!str2prefix (argv[8]->arg, &pfx))
- {
- vty_out (vty, "Malformed prefix \"%s\"\n", argv[8]->arg);
- return CMD_WARNING_CONFIG_FAILED;
- }
- if (pfx.family != AF_INET && pfx.family != AF_INET6)
- {
- vty_out (vty, "Bad family for prefix \"%s\"\n", argv[8]->arg);
- return CMD_WARNING_CONFIG_FAILED;
- }
- rfapiQprefix2Rprefix (&pfx, &hpfx);
-
- rfapi_register (handle, &hpfx, 0, NULL, NULL, 1);
-
- return CMD_SUCCESS;
+ struct rfapi_ip_addr vn;
+ struct rfapi_ip_addr un;
+ rfapi_handle handle;
+ struct prefix pfx;
+ struct rfapi_ip_prefix hpfx;
+ int rc;
+
+ /*
+ * Get VN addr
+ */
+ if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[4]->arg, &vn)))
+ return rc;
+
+
+ /*
+ * Get UN addr
+ */
+ if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[6]->arg, &un)))
+ return rc;
+
+
+ if (rfapi_find_handle_vty(vty, &vn, &un, &handle)) {
+ vty_out(vty, "can't locate handle matching vn=%s, un=%s\n",
+ argv[4]->arg, argv[6]->arg);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ /*
+ * Get prefix to advertise
+ */
+ if (!str2prefix(argv[8]->arg, &pfx)) {
+ vty_out(vty, "Malformed prefix \"%s\"\n", argv[8]->arg);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ if (pfx.family != AF_INET && pfx.family != AF_INET6) {
+ vty_out(vty, "Bad family for prefix \"%s\"\n", argv[8]->arg);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ rfapiQprefix2Rprefix(&pfx, &hpfx);
+
+ rfapi_register(handle, &hpfx, 0, NULL, NULL, 1);
+
+ return CMD_SUCCESS;
}
DEFUN (debug_rfapi_query_vn_un,
@@ -3534,60 +3290,57 @@ DEFUN (debug_rfapi_query_vn_un,
"target IPv4 address\n"
"target IPv6 address\n")
{
- struct rfapi_ip_addr vn;
- struct rfapi_ip_addr un;
- struct rfapi_ip_addr target;
- rfapi_handle handle;
- int rc;
- struct rfapi_next_hop_entry *pNextHopEntry;
-
- /*
- * Get VN addr
- */
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[4]->arg, &vn)))
- return rc;
-
-
- /*
- * Get UN addr
- */
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[6]->arg, &un)))
- return rc;
-
-
- /*
- * Get target addr
- */
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[8]->arg, &target)))
- return rc;
-
-
- if (rfapi_find_handle_vty (vty, &vn, &un, &handle))
- {
- vty_out (vty, "can't locate handle matching vn=%s, un=%s\n",
- argv[4]->arg, argv[6]->arg);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- /*
- * options parameter not used? Set to NULL for now
- */
- rc = rfapi_query (handle, &target, NULL, &pNextHopEntry);
-
- if (rc)
- {
- vty_out (vty, "rfapi_query failed with rc=%d (%s)\n", rc,
- strerror(rc));
- }
- else
- {
- /*
- * print nexthop list
- */
- test_nexthops_callback ( /*&target, */ pNextHopEntry, vty); /* frees nh list! */
- }
-
- return CMD_SUCCESS;
+ struct rfapi_ip_addr vn;
+ struct rfapi_ip_addr un;
+ struct rfapi_ip_addr target;
+ rfapi_handle handle;
+ int rc;
+ struct rfapi_next_hop_entry *pNextHopEntry;
+
+ /*
+ * Get VN addr
+ */
+ if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[4]->arg, &vn)))
+ return rc;
+
+
+ /*
+ * Get UN addr
+ */
+ if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[6]->arg, &un)))
+ return rc;
+
+
+ /*
+ * Get target addr
+ */
+ if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[8]->arg, &target)))
+ return rc;
+
+
+ if (rfapi_find_handle_vty(vty, &vn, &un, &handle)) {
+ vty_out(vty, "can't locate handle matching vn=%s, un=%s\n",
+ argv[4]->arg, argv[6]->arg);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ /*
+ * options parameter not used? Set to NULL for now
+ */
+ rc = rfapi_query(handle, &target, NULL, &pNextHopEntry);
+
+ if (rc) {
+ vty_out(vty, "rfapi_query failed with rc=%d (%s)\n", rc,
+ strerror(rc));
+ } else {
+ /*
+ * print nexthop list
+ */
+ test_nexthops_callback(/*&target, */ pNextHopEntry,
+ vty); /* frees nh list! */
+ }
+
+ return CMD_SUCCESS;
}
@@ -3608,28 +3361,28 @@ DEFUN (debug_rfapi_query_vn_un_l2o,
"indicate target MAC addr follows\n"
"target MAC addr\n")
{
- struct rfapi_ip_addr vn;
- struct rfapi_ip_addr un;
- struct rfapi_ip_addr target;
- rfapi_handle handle;
- int rc;
- struct rfapi_next_hop_entry *pNextHopEntry;
- struct rfapi_l2address_option l2o_buf;
- struct bgp_tea_options hopt;
- uint8_t valbuf[14];
-
- /*
- * Get VN addr
- */
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[4]->arg, &vn)))
- return rc;
-
-
- /*
- * Get UN addr
- */
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[6]->arg, &un)))
- return rc;
+ struct rfapi_ip_addr vn;
+ struct rfapi_ip_addr un;
+ struct rfapi_ip_addr target;
+ rfapi_handle handle;
+ int rc;
+ struct rfapi_next_hop_entry *pNextHopEntry;
+ struct rfapi_l2address_option l2o_buf;
+ struct bgp_tea_options hopt;
+ uint8_t valbuf[14];
+
+ /*
+ * Get VN addr
+ */
+ if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[4]->arg, &vn)))
+ return rc;
+
+
+ /*
+ * Get UN addr
+ */
+ if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[6]->arg, &un)))
+ return rc;
#if 0 /* there is no IP target arg here ?????? */
@@ -3639,65 +3392,61 @@ DEFUN (debug_rfapi_query_vn_un_l2o,
if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[2], &target)))
return rc;
#else
- vty_out (vty, "%% This command is broken.\n");
- return CMD_WARNING_CONFIG_FAILED;
+ vty_out(vty, "%% This command is broken.\n");
+ return CMD_WARNING_CONFIG_FAILED;
#endif
- if (rfapi_find_handle_vty (vty, &vn, &un, &handle))
- {
- vty_out (vty, "can't locate handle matching vn=%s, un=%s\n",
- argv[4]->arg, argv[6]->arg);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- /*
- * Set up L2 parameters
- */
- memset (&l2o_buf, 0, sizeof (l2o_buf));
- if (rfapiStr2EthAddr (argv[10]->arg, &l2o_buf.macaddr))
- {
- vty_out (vty, "Bad mac address \"%s\"\n", argv[10]->arg);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- l2o_buf.logical_net_id = strtoul(argv[8]->arg, NULL, 10);
-
- /* construct option chain */
-
- memset (valbuf, 0, sizeof (valbuf));
- memcpy (valbuf, &l2o_buf.macaddr.octet, ETHER_ADDR_LEN);
- valbuf[11] = (l2o_buf.logical_net_id >> 16) & 0xff;
- valbuf[12] = (l2o_buf.logical_net_id >> 8) & 0xff;
- valbuf[13] = l2o_buf.logical_net_id & 0xff;
-
- memset (&hopt, 0, sizeof (hopt));
- hopt.options_count = 1;
- hopt.options_length = sizeof (valbuf); /* is this right? */
- hopt.type = RFAPI_VN_OPTION_TYPE_L2ADDR;
- hopt.length = sizeof (valbuf);
- hopt.value = valbuf;
-
-
- /*
- * options parameter not used? Set to NULL for now
- */
- rc = rfapi_query (handle, &target, &l2o_buf, &pNextHopEntry);
-
- if (rc)
- {
- vty_out (vty, "rfapi_query failed with rc=%d (%s)\n", rc,
- strerror(rc));
- }
- else
- {
- /*
- * print nexthop list
- */
- /* TBD enhance to print L2 information */
- test_nexthops_callback ( /*&target, */ pNextHopEntry, vty); /* frees nh list! */
- }
-
- return CMD_SUCCESS;
+ if (rfapi_find_handle_vty(vty, &vn, &un, &handle)) {
+ vty_out(vty, "can't locate handle matching vn=%s, un=%s\n",
+ argv[4]->arg, argv[6]->arg);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ /*
+ * Set up L2 parameters
+ */
+ memset(&l2o_buf, 0, sizeof(l2o_buf));
+ if (rfapiStr2EthAddr(argv[10]->arg, &l2o_buf.macaddr)) {
+ vty_out(vty, "Bad mac address \"%s\"\n", argv[10]->arg);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ l2o_buf.logical_net_id = strtoul(argv[8]->arg, NULL, 10);
+
+ /* construct option chain */
+
+ memset(valbuf, 0, sizeof(valbuf));
+ memcpy(valbuf, &l2o_buf.macaddr.octet, ETHER_ADDR_LEN);
+ valbuf[11] = (l2o_buf.logical_net_id >> 16) & 0xff;
+ valbuf[12] = (l2o_buf.logical_net_id >> 8) & 0xff;
+ valbuf[13] = l2o_buf.logical_net_id & 0xff;
+
+ memset(&hopt, 0, sizeof(hopt));
+ hopt.options_count = 1;
+ hopt.options_length = sizeof(valbuf); /* is this right? */
+ hopt.type = RFAPI_VN_OPTION_TYPE_L2ADDR;
+ hopt.length = sizeof(valbuf);
+ hopt.value = valbuf;
+
+
+ /*
+ * options parameter not used? Set to NULL for now
+ */
+ rc = rfapi_query(handle, &target, &l2o_buf, &pNextHopEntry);
+
+ if (rc) {
+ vty_out(vty, "rfapi_query failed with rc=%d (%s)\n", rc,
+ strerror(rc));
+ } else {
+ /*
+ * print nexthop list
+ */
+ /* TBD enhance to print L2 information */
+ test_nexthops_callback(/*&target, */ pNextHopEntry,
+ vty); /* frees nh list! */
+ }
+
+ return CMD_SUCCESS;
}
@@ -3718,48 +3467,47 @@ DEFUN (debug_rfapi_query_done_vn_un,
"Target IPv4 address\n"
"Target IPv6 address\n")
{
- struct rfapi_ip_addr vn;
- struct rfapi_ip_addr un;
- struct rfapi_ip_addr target;
- rfapi_handle handle;
- int rc;
+ struct rfapi_ip_addr vn;
+ struct rfapi_ip_addr un;
+ struct rfapi_ip_addr target;
+ rfapi_handle handle;
+ int rc;
- /*
- * Get VN addr
- */
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[5]->arg, &vn)))
- return rc;
+ /*
+ * Get VN addr
+ */
+ if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[5]->arg, &vn)))
+ return rc;
- /*
- * Get UN addr
- */
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[7]->arg, &un)))
- return rc;
+ /*
+ * Get UN addr
+ */
+ if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[7]->arg, &un)))
+ return rc;
- /*
- * Get target addr
- */
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[9]->arg, &target)))
- return rc;
+ /*
+ * Get target addr
+ */
+ if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[9]->arg, &target)))
+ return rc;
- if (rfapi_find_handle_vty (vty, &vn, &un, &handle))
- {
- vty_out (vty, "can't locate handle matching vn=%s, un=%s\n",
- argv[5]->arg, argv[7]->arg);
- return CMD_WARNING_CONFIG_FAILED;
- }
+ if (rfapi_find_handle_vty(vty, &vn, &un, &handle)) {
+ vty_out(vty, "can't locate handle matching vn=%s, un=%s\n",
+ argv[5]->arg, argv[7]->arg);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- /*
- * options parameter not used? Set to NULL for now
- */
- rc = rfapi_query_done (handle, &target);
+ /*
+ * options parameter not used? Set to NULL for now
+ */
+ rc = rfapi_query_done(handle, &target);
- vty_out (vty, "rfapi_query_done returned %d\n", rc);
+ vty_out(vty, "rfapi_query_done returned %d\n", rc);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (debug_rfapi_show_import,
@@ -3770,83 +3518,82 @@ DEFUN (debug_rfapi_show_import,
SHOW_STR
"import\n")
{
- struct bgp *bgp;
- struct rfapi *h;
- struct rfapi_import_table *it;
- char *s;
- int first_l2 = 1;
-
- /*
- * Show all import tables
- */
-
- bgp = bgp_get_default (); /* assume 1 instance for now */
- if (!bgp)
- {
- vty_out (vty, "No BGP instance\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- h = bgp->rfapi;
- if (!h)
- {
- vty_out (vty, "No RFAPI instance\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- /*
- * Iterate over all import tables; do a filtered import
- * for the afi/safi combination
- */
-
-
- for (it = h->imports; it; it = it->next)
- {
- s = ecommunity_ecom2str (it->rt_import_list,
- ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
- vty_out (vty, "Import Table %p, RTs: %s\n", it, s);
- XFREE (MTYPE_ECOMMUNITY_STR, s);
-
- rfapiShowImportTable (vty, "IP VPN", it->imported_vpn[AFI_IP], 1);
- rfapiShowImportTable (vty, "IP ENCAP", it->imported_encap[AFI_IP], 0);
- rfapiShowImportTable (vty, "IP6 VPN", it->imported_vpn[AFI_IP6], 1);
- rfapiShowImportTable (vty, "IP6 ENCAP", it->imported_encap[AFI_IP6], 0);
- }
-
- if (h->import_mac)
- {
- void *cursor = NULL;
- uint32_t lni;
- uintptr_t lni_as_ptr;
- int rc;
- char buf[BUFSIZ];
-
- for (rc =
- skiplist_next (h->import_mac, (void **) &lni_as_ptr, (void **) &it,
- &cursor); !rc;
- rc =
- skiplist_next (h->import_mac, (void **) &lni_as_ptr, (void **) &it,
- &cursor))
- {
-
- if (it->imported_vpn[AFI_L2VPN])
- {
- lni = lni_as_ptr;
- if (first_l2)
- {
- vty_out (vty, "\nLNI-based Ethernet Tables:\n");
- first_l2 = 0;
- }
- snprintf (buf, BUFSIZ, "L2VPN LNI=%u", lni);
- rfapiShowImportTable (vty, buf, it->imported_vpn[AFI_L2VPN], 1);
- }
- }
- }
-
- rfapiShowImportTable (vty, "CE IT - IP VPN",
- h->it_ce->imported_vpn[AFI_IP], 1);
-
- return CMD_SUCCESS;
+ struct bgp *bgp;
+ struct rfapi *h;
+ struct rfapi_import_table *it;
+ char *s;
+ int first_l2 = 1;
+
+ /*
+ * Show all import tables
+ */
+
+ bgp = bgp_get_default(); /* assume 1 instance for now */
+ if (!bgp) {
+ vty_out(vty, "No BGP instance\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ h = bgp->rfapi;
+ if (!h) {
+ vty_out(vty, "No RFAPI instance\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ /*
+ * Iterate over all import tables; do a filtered import
+ * for the afi/safi combination
+ */
+
+
+ for (it = h->imports; it; it = it->next) {
+ s = ecommunity_ecom2str(it->rt_import_list,
+ ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
+ vty_out(vty, "Import Table %p, RTs: %s\n", it, s);
+ XFREE(MTYPE_ECOMMUNITY_STR, s);
+
+ rfapiShowImportTable(vty, "IP VPN", it->imported_vpn[AFI_IP],
+ 1);
+ rfapiShowImportTable(vty, "IP ENCAP",
+ it->imported_encap[AFI_IP], 0);
+ rfapiShowImportTable(vty, "IP6 VPN", it->imported_vpn[AFI_IP6],
+ 1);
+ rfapiShowImportTable(vty, "IP6 ENCAP",
+ it->imported_encap[AFI_IP6], 0);
+ }
+
+ if (h->import_mac) {
+ void *cursor = NULL;
+ uint32_t lni;
+ uintptr_t lni_as_ptr;
+ int rc;
+ char buf[BUFSIZ];
+
+ for (rc = skiplist_next(h->import_mac, (void **)&lni_as_ptr,
+ (void **)&it, &cursor);
+ !rc;
+ rc = skiplist_next(h->import_mac, (void **)&lni_as_ptr,
+ (void **)&it, &cursor)) {
+
+ if (it->imported_vpn[AFI_L2VPN]) {
+ lni = lni_as_ptr;
+ if (first_l2) {
+ vty_out(vty,
+ "\nLNI-based Ethernet Tables:\n");
+ first_l2 = 0;
+ }
+ snprintf(buf, BUFSIZ, "L2VPN LNI=%u", lni);
+ rfapiShowImportTable(
+ vty, buf, it->imported_vpn[AFI_L2VPN],
+ 1);
+ }
+ }
+ }
+
+ rfapiShowImportTable(vty, "CE IT - IP VPN",
+ h->it_ce->imported_vpn[AFI_IP], 1);
+
+ return CMD_SUCCESS;
}
DEFUN (debug_rfapi_show_import_vn_un,
@@ -3863,45 +3610,44 @@ DEFUN (debug_rfapi_show_import_vn_un,
"underlay network interface IPv4 address\n"
"underlay network interface IPv6 address\n")
{
- struct rfapi_ip_addr vn;
- struct rfapi_ip_addr un;
- rfapi_handle handle;
- int rc;
- struct rfapi_descriptor *rfd;
-
- /*
- * Get VN addr
- */
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[5]->arg, &vn)))
- return rc;
-
-
- /*
- * Get UN addr
- */
- if ((rc = rfapiCliGetRfapiIpAddr (vty, argv[7]->arg, &un)))
- return rc;
-
-
- if (rfapi_find_handle_vty (vty, &vn, &un, &handle))
- {
- vty_out (vty, "can't locate handle matching vn=%s, un=%s\n",
- argv[5]->arg, argv[7]->arg);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- rfd = (struct rfapi_descriptor *) handle;
-
- rfapiShowImportTable (vty, "IP VPN",
- rfd->import_table->imported_vpn[AFI_IP], 1);
- rfapiShowImportTable (vty, "IP ENCAP",
- rfd->import_table->imported_encap[AFI_IP], 0);
- rfapiShowImportTable (vty, "IP6 VPN",
- rfd->import_table->imported_vpn[AFI_IP6], 1);
- rfapiShowImportTable (vty, "IP6 ENCAP",
- rfd->import_table->imported_encap[AFI_IP6], 0);
-
- return CMD_SUCCESS;
+ struct rfapi_ip_addr vn;
+ struct rfapi_ip_addr un;
+ rfapi_handle handle;
+ int rc;
+ struct rfapi_descriptor *rfd;
+
+ /*
+ * Get VN addr
+ */
+ if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[5]->arg, &vn)))
+ return rc;
+
+
+ /*
+ * Get UN addr
+ */
+ if ((rc = rfapiCliGetRfapiIpAddr(vty, argv[7]->arg, &un)))
+ return rc;
+
+
+ if (rfapi_find_handle_vty(vty, &vn, &un, &handle)) {
+ vty_out(vty, "can't locate handle matching vn=%s, un=%s\n",
+ argv[5]->arg, argv[7]->arg);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ rfd = (struct rfapi_descriptor *)handle;
+
+ rfapiShowImportTable(vty, "IP VPN",
+ rfd->import_table->imported_vpn[AFI_IP], 1);
+ rfapiShowImportTable(vty, "IP ENCAP",
+ rfd->import_table->imported_encap[AFI_IP], 0);
+ rfapiShowImportTable(vty, "IP6 VPN",
+ rfd->import_table->imported_vpn[AFI_IP6], 1);
+ rfapiShowImportTable(vty, "IP6 ENCAP",
+ rfd->import_table->imported_encap[AFI_IP6], 0);
+
+ return CMD_SUCCESS;
}
DEFUN (debug_rfapi_response_omit_self,
@@ -3912,25 +3658,25 @@ DEFUN (debug_rfapi_response_omit_self,
"Omit self in RFP responses\n"
"filter out self from responses\n" "leave self in responses\n")
{
- struct bgp *bgp = bgp_get_default ();
-
- if (!bgp)
- {
- vty_out (vty, "No BGP process is configured\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- if (!bgp->rfapi_cfg)
- {
- vty_out (vty, "VNC not configured\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- if (strmatch(argv[3]->text, "on"))
- SET_FLAG (bgp->rfapi_cfg->flags, BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP);
- else
- UNSET_FLAG (bgp->rfapi_cfg->flags, BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP);
-
- return CMD_SUCCESS;
+ struct bgp *bgp = bgp_get_default();
+
+ if (!bgp) {
+ vty_out(vty, "No BGP process is configured\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ if (!bgp->rfapi_cfg) {
+ vty_out(vty, "VNC not configured\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ if (strmatch(argv[3]->text, "on"))
+ SET_FLAG(bgp->rfapi_cfg->flags,
+ BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP);
+ else
+ UNSET_FLAG(bgp->rfapi_cfg->flags,
+ BGP_VNC_CONFIG_FILTER_SELF_FROM_RSP);
+
+ return CMD_SUCCESS;
}
@@ -3943,9 +3689,9 @@ DEFUN (skiplist_test_cli,
"skiplist command\n"
"test\n")
{
- skiplist_test (vty);
+ skiplist_test(vty);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (skiplist_debug_cli,
@@ -3954,151 +3700,139 @@ DEFUN (skiplist_debug_cli,
"skiplist command\n"
"debug\n")
{
- skiplist_debug (vty, NULL);
- return CMD_SUCCESS;
+ skiplist_debug(vty, NULL);
+ return CMD_SUCCESS;
}
#endif /* RFAPI_DEBUG_SKIPLIST_CLI */
-void
-rfapi_init (void)
+void rfapi_init(void)
{
- bgp_rfapi_cfg_init ();
- vnc_debug_init();
+ bgp_rfapi_cfg_init();
+ vnc_debug_init();
- install_element (ENABLE_NODE, &debug_rfapi_show_import_cmd);
- install_element (ENABLE_NODE, &debug_rfapi_show_import_vn_un_cmd);
+ install_element(ENABLE_NODE, &debug_rfapi_show_import_cmd);
+ install_element(ENABLE_NODE, &debug_rfapi_show_import_vn_un_cmd);
- install_element (ENABLE_NODE, &debug_rfapi_open_cmd);
- install_element (ENABLE_NODE, &debug_rfapi_close_vn_un_cmd);
- install_element (ENABLE_NODE, &debug_rfapi_close_rfd_cmd);
- install_element (ENABLE_NODE, &debug_rfapi_register_vn_un_cmd);
- install_element (ENABLE_NODE, &debug_rfapi_unregister_vn_un_cmd);
- install_element (ENABLE_NODE, &debug_rfapi_query_vn_un_cmd);
- install_element (ENABLE_NODE, &debug_rfapi_query_vn_un_done_cmd);
- install_element (ENABLE_NODE, &debug_rfapi_query_vn_un_l2o_cmd);
+ install_element(ENABLE_NODE, &debug_rfapi_open_cmd);
+ install_element(ENABLE_NODE, &debug_rfapi_close_vn_un_cmd);
+ install_element(ENABLE_NODE, &debug_rfapi_close_rfd_cmd);
+ install_element(ENABLE_NODE, &debug_rfapi_register_vn_un_cmd);
+ install_element(ENABLE_NODE, &debug_rfapi_unregister_vn_un_cmd);
+ install_element(ENABLE_NODE, &debug_rfapi_query_vn_un_cmd);
+ install_element(ENABLE_NODE, &debug_rfapi_query_vn_un_done_cmd);
+ install_element(ENABLE_NODE, &debug_rfapi_query_vn_un_l2o_cmd);
- install_element (ENABLE_NODE, &debug_rfapi_response_omit_self_cmd);
+ install_element(ENABLE_NODE, &debug_rfapi_response_omit_self_cmd);
- /* Need the following show commands for gpz test scripts */
- install_element (ENABLE_NODE, &debug_rfapi_show_nves_cmd);
- install_element (ENABLE_NODE, &debug_rfapi_show_nves_vn_un_cmd);
- install_element (ENABLE_NODE, &debug_rfapi_register_vn_un_l2o_cmd);
+ /* Need the following show commands for gpz test scripts */
+ install_element(ENABLE_NODE, &debug_rfapi_show_nves_cmd);
+ install_element(ENABLE_NODE, &debug_rfapi_show_nves_vn_un_cmd);
+ install_element(ENABLE_NODE, &debug_rfapi_register_vn_un_l2o_cmd);
#ifdef RFAPI_DEBUG_SKIPLIST_CLI
- install_element (ENABLE_NODE, &skiplist_test_cli_cmd);
- install_element (ENABLE_NODE, &skiplist_debug_cli_cmd);
+ install_element(ENABLE_NODE, &skiplist_test_cli_cmd);
+ install_element(ENABLE_NODE, &skiplist_debug_cli_cmd);
#endif
- rfapi_vty_init ();
+ rfapi_vty_init();
}
#ifdef DEBUG_RFAPI
-static void
-rfapi_print_exported (struct bgp *bgp)
+static void rfapi_print_exported(struct bgp *bgp)
{
- struct bgp_node *rdn;
- struct bgp_node *rn;
- struct bgp_info *bi;
-
- if (!bgp)
- return;
-
- for (rdn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rdn;
- rdn = bgp_route_next (rdn))
- {
- if (!rdn->info)
- continue;
- fprintf (stderr, "%s: vpn rdn=%p\n", __func__, rdn);
- for (rn = bgp_table_top (rdn->info); rn; rn = bgp_route_next (rn))
- {
- if (!rn->info)
- continue;
- fprintf (stderr, "%s: rn=%p\n", __func__, rn);
- for (bi = rn->info; bi; bi = bi->next)
- {
- rfapiPrintBi ((void *) 2, bi); /* 2 => stderr */
- }
- }
- }
- for (rdn = bgp_table_top (bgp->rib[AFI_IP][SAFI_ENCAP]); rdn;
- rdn = bgp_route_next (rdn))
- {
- if (!rdn->info)
- continue;
- fprintf (stderr, "%s: encap rdn=%p\n", __func__, rdn);
- for (rn = bgp_table_top (rdn->info); rn; rn = bgp_route_next (rn))
- {
- if (!rn->info)
- continue;
- fprintf (stderr, "%s: rn=%p\n", __func__, rn);
- for (bi = rn->info; bi; bi = bi->next)
- {
- rfapiPrintBi ((void *) 2, bi); /* 2 => stderr */
- }
- }
- }
-
+ struct bgp_node *rdn;
+ struct bgp_node *rn;
+ struct bgp_info *bi;
+
+ if (!bgp)
+ return;
+
+ for (rdn = bgp_table_top(bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rdn;
+ rdn = bgp_route_next(rdn)) {
+ if (!rdn->info)
+ continue;
+ fprintf(stderr, "%s: vpn rdn=%p\n", __func__, rdn);
+ for (rn = bgp_table_top(rdn->info); rn;
+ rn = bgp_route_next(rn)) {
+ if (!rn->info)
+ continue;
+ fprintf(stderr, "%s: rn=%p\n", __func__, rn);
+ for (bi = rn->info; bi; bi = bi->next) {
+ rfapiPrintBi((void *)2, bi); /* 2 => stderr */
+ }
+ }
+ }
+ for (rdn = bgp_table_top(bgp->rib[AFI_IP][SAFI_ENCAP]); rdn;
+ rdn = bgp_route_next(rdn)) {
+ if (!rdn->info)
+ continue;
+ fprintf(stderr, "%s: encap rdn=%p\n", __func__, rdn);
+ for (rn = bgp_table_top(rdn->info); rn;
+ rn = bgp_route_next(rn)) {
+ if (!rn->info)
+ continue;
+ fprintf(stderr, "%s: rn=%p\n", __func__, rn);
+ for (bi = rn->info; bi; bi = bi->next) {
+ rfapiPrintBi((void *)2, bi); /* 2 => stderr */
+ }
+ }
+ }
}
#endif /* defined(DEBUG_RFAPI) */
/*
* Free all memory to prepare for clean exit as seen by valgrind memcheck
*/
-void
-rfapi_delete (struct bgp *bgp)
+void rfapi_delete(struct bgp *bgp)
{
- extern void rfp_clear_vnc_nve_all (void); /* can't fix correctly yet */
-
- /*
- * This clears queries and registered routes, and closes nves
- */
- if (bgp->rfapi)
- rfp_clear_vnc_nve_all ();
- bgp_rfapi_cfg_destroy (bgp, bgp->rfapi_cfg);
- bgp->rfapi_cfg = NULL;
- bgp_rfapi_destroy (bgp, bgp->rfapi);
- bgp->rfapi = NULL;
+ extern void rfp_clear_vnc_nve_all(void); /* can't fix correctly yet */
+
+ /*
+ * This clears queries and registered routes, and closes nves
+ */
+ if (bgp->rfapi)
+ rfp_clear_vnc_nve_all();
+ bgp_rfapi_cfg_destroy(bgp, bgp->rfapi_cfg);
+ bgp->rfapi_cfg = NULL;
+ bgp_rfapi_destroy(bgp, bgp->rfapi);
+ bgp->rfapi = NULL;
#ifdef DEBUG_RFAPI
- /*
- * show what's left in the BGP MPLSVPN RIB
- */
- rfapi_print_exported (bgp);
+ /*
+ * show what's left in the BGP MPLSVPN RIB
+ */
+ rfapi_print_exported(bgp);
#endif
-
}
-int
-rfapi_set_autord_from_vn (struct prefix_rd *rd, struct rfapi_ip_addr *vn)
+int rfapi_set_autord_from_vn(struct prefix_rd *rd, struct rfapi_ip_addr *vn)
{
- vnc_zlog_debug_verbose ("%s: auto-assigning RD", __func__);
- if (vn->addr_family != AF_INET
- && vn->addr_family != AF_INET6)
- {
- vnc_zlog_debug_verbose ("%s: can't auto-assign RD, VN addr family is not IPv4"
- "|v6"
- , __func__);
- return EAFNOSUPPORT;
- }
- rd->family = AF_UNSPEC;
- rd->prefixlen = 64;
- rd->val[1] = RD_TYPE_IP;
- if (vn->addr_family == AF_INET)
- {
- memcpy (rd->val + 2, &vn->addr.v4.s_addr, 4);
- }
- else
- { /* is v6 */
- memcpy (rd->val + 2, &vn->addr.v6.s6_addr32[3], 4);/* low order 4 bytes */
- }
- {
- char buf[BUFSIZ];
- buf[0] = 0;
- prefix_rd2str (rd, buf, BUFSIZ);
- buf[BUFSIZ - 1] = 0;
- vnc_zlog_debug_verbose ("%s: auto-RD is set to %s", __func__, buf);
- }
- return 0;
+ vnc_zlog_debug_verbose("%s: auto-assigning RD", __func__);
+ if (vn->addr_family != AF_INET && vn->addr_family != AF_INET6) {
+ vnc_zlog_debug_verbose(
+ "%s: can't auto-assign RD, VN addr family is not IPv4"
+ "|v6",
+ __func__);
+ return EAFNOSUPPORT;
+ }
+ rd->family = AF_UNSPEC;
+ rd->prefixlen = 64;
+ rd->val[1] = RD_TYPE_IP;
+ if (vn->addr_family == AF_INET) {
+ memcpy(rd->val + 2, &vn->addr.v4.s_addr, 4);
+ } else { /* is v6 */
+ memcpy(rd->val + 2, &vn->addr.v6.s6_addr32[3],
+ 4); /* low order 4 bytes */
+ }
+ {
+ char buf[BUFSIZ];
+ buf[0] = 0;
+ prefix_rd2str(rd, buf, BUFSIZ);
+ buf[BUFSIZ - 1] = 0;
+ vnc_zlog_debug_verbose("%s: auto-RD is set to %s", __func__,
+ buf);
+ }
+ return 0;
}
/*------------------------------------------
@@ -4106,7 +3840,7 @@ rfapi_set_autord_from_vn (struct prefix_rd *rd, struct rfapi_ip_addr *vn)
*
* Find bgp instance pointer based on value returned by rfp_start
*
- * input:
+ * input:
* rfp_start_val value returned by rfp_startor
* NULL (=get default instance)
*
@@ -4118,19 +3852,19 @@ rfapi_set_autord_from_vn (struct prefix_rd *rd, struct rfapi_ip_addr *vn)
* NULL = not found
*
--------------------------------------------*/
-struct bgp *
-rfapi_bgp_lookup_by_rfp (void *rfp_start_val)
+struct bgp *rfapi_bgp_lookup_by_rfp(void *rfp_start_val)
{
- struct bgp *bgp = NULL;
- struct listnode *node, *nnode;
-
- if (rfp_start_val == NULL)
- bgp = bgp_get_default ();
- else
- for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
- if (bgp->rfapi != NULL && bgp->rfapi->rfp == rfp_start_val)
- return bgp;
- return bgp;
+ struct bgp *bgp = NULL;
+ struct listnode *node, *nnode;
+
+ if (rfp_start_val == NULL)
+ bgp = bgp_get_default();
+ else
+ for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
+ if (bgp->rfapi != NULL
+ && bgp->rfapi->rfp == rfp_start_val)
+ return bgp;
+ return bgp;
}
/*------------------------------------------
@@ -4138,7 +3872,7 @@ rfapi_bgp_lookup_by_rfp (void *rfp_start_val)
*
* Find bgp instance pointer based on value returned by rfp_start
*
- * input:
+ * input:
* bgp bgp instance pointer
*
* output:
@@ -4149,91 +3883,81 @@ rfapi_bgp_lookup_by_rfp (void *rfp_start_val)
* NULL = not found
*
--------------------------------------------*/
-void *
-rfapi_get_rfp_start_val_by_bgp (struct bgp *bgp)
+void *rfapi_get_rfp_start_val_by_bgp(struct bgp *bgp)
{
- if (!bgp || !bgp->rfapi)
- return NULL;
- return bgp->rfapi->rfp;
+ if (!bgp || !bgp->rfapi)
+ return NULL;
+ return bgp->rfapi->rfp;
}
/***********************************************************************
* RFP group specific configuration
***********************************************************************/
-static void *
-rfapi_rfp_get_or_init_group_config_default (
- struct rfapi_cfg *rfc,
- struct vty *vty,
- uint32_t size)
+static void *rfapi_rfp_get_or_init_group_config_default(struct rfapi_cfg *rfc,
+ struct vty *vty,
+ uint32_t size)
{
- if (rfc->default_rfp_cfg == NULL && size > 0)
- {
- rfc->default_rfp_cfg = XCALLOC (MTYPE_RFAPI_RFP_GROUP_CFG, size);
- vnc_zlog_debug_verbose ("%s: allocated, size=%d", __func__, size);
-
- }
- return rfc->default_rfp_cfg;
+ if (rfc->default_rfp_cfg == NULL && size > 0) {
+ rfc->default_rfp_cfg = XCALLOC(MTYPE_RFAPI_RFP_GROUP_CFG, size);
+ vnc_zlog_debug_verbose("%s: allocated, size=%d", __func__,
+ size);
+ }
+ return rfc->default_rfp_cfg;
}
-static void *
-rfapi_rfp_get_or_init_group_config_nve (
- struct rfapi_cfg *rfc,
- struct vty *vty,
- uint32_t size)
+static void *rfapi_rfp_get_or_init_group_config_nve(struct rfapi_cfg *rfc,
+ struct vty *vty,
+ uint32_t size)
{
- struct rfapi_nve_group_cfg *rfg = VTY_GET_CONTEXT_SUB(rfapi_nve_group_cfg);
-
- /* make sure group is still in list */
- if (!rfg || !listnode_lookup (rfc->nve_groups_sequential, rfg))
- {
- /* Not in list anymore */
- vty_out (vty, "Current NVE group no longer exists\n");
- return NULL;
- }
-
- if (rfg->rfp_cfg == NULL && size > 0)
- {
- rfg->rfp_cfg = XCALLOC (MTYPE_RFAPI_RFP_GROUP_CFG, size);
- vnc_zlog_debug_verbose ("%s: allocated, size=%d", __func__, size);
-
- }
- return rfg->rfp_cfg;
+ struct rfapi_nve_group_cfg *rfg =
+ VTY_GET_CONTEXT_SUB(rfapi_nve_group_cfg);
+
+ /* make sure group is still in list */
+ if (!rfg || !listnode_lookup(rfc->nve_groups_sequential, rfg)) {
+ /* Not in list anymore */
+ vty_out(vty, "Current NVE group no longer exists\n");
+ return NULL;
+ }
+
+ if (rfg->rfp_cfg == NULL && size > 0) {
+ rfg->rfp_cfg = XCALLOC(MTYPE_RFAPI_RFP_GROUP_CFG, size);
+ vnc_zlog_debug_verbose("%s: allocated, size=%d", __func__,
+ size);
+ }
+ return rfg->rfp_cfg;
}
-static void *
-rfapi_rfp_get_or_init_group_config_l2 (
- struct rfapi_cfg *rfc,
- struct vty *vty,
- uint32_t size)
+static void *rfapi_rfp_get_or_init_group_config_l2(struct rfapi_cfg *rfc,
+ struct vty *vty,
+ uint32_t size)
{
- struct rfapi_l2_group_cfg *rfg = VTY_GET_CONTEXT_SUB(rfapi_l2_group_cfg);
-
- /* make sure group is still in list */
- if (!rfg || !listnode_lookup (rfc->l2_groups, rfg))
- {
- /* Not in list anymore */
- vty_out (vty, "Current L2 group no longer exists\n");
- return NULL;
- }
- if (rfg->rfp_cfg == NULL && size > 0)
- {
- rfg->rfp_cfg = XCALLOC (MTYPE_RFAPI_RFP_GROUP_CFG, size);
- vnc_zlog_debug_verbose ("%s: allocated, size=%d", __func__, size);
-
- }
- return rfg->rfp_cfg;
+ struct rfapi_l2_group_cfg *rfg =
+ VTY_GET_CONTEXT_SUB(rfapi_l2_group_cfg);
+
+ /* make sure group is still in list */
+ if (!rfg || !listnode_lookup(rfc->l2_groups, rfg)) {
+ /* Not in list anymore */
+ vty_out(vty, "Current L2 group no longer exists\n");
+ return NULL;
+ }
+ if (rfg->rfp_cfg == NULL && size > 0) {
+ rfg->rfp_cfg = XCALLOC(MTYPE_RFAPI_RFP_GROUP_CFG, size);
+ vnc_zlog_debug_verbose("%s: allocated, size=%d", __func__,
+ size);
+ }
+ return rfg->rfp_cfg;
}
/*------------------------------------------
* rfapi_rfp_init_group_config_ptr_vty
*
* This is used to init or return a previously init'ed group specific
- * configuration pointer. Group is identified by vty context.
+ * configuration pointer. Group is identified by vty context.
* NOTE: size is ignored when a previously init'ed value is returned.
* RFAPI frees rfp_cfg_group when group is deleted during reconfig,
* bgp restart or shutdown.
*
- * input:
+ * input:
* rfp_start_val value returned by rfp_start
* type group type
* vty quagga vty context
@@ -4242,46 +3966,43 @@ rfapi_rfp_get_or_init_group_config_l2 (
* output:
* none
*
- * return value:
+ * return value:
* rfp_cfg_group NULL or Pointer to configuration structure
--------------------------------------------*/
-void *
-rfapi_rfp_init_group_config_ptr_vty (
- void *rfp_start_val,
- rfapi_rfp_cfg_group_type type,
- struct vty *vty,
- uint32_t size)
+void *rfapi_rfp_init_group_config_ptr_vty(void *rfp_start_val,
+ rfapi_rfp_cfg_group_type type,
+ struct vty *vty, uint32_t size)
{
- struct bgp *bgp;
- void *ret = NULL;
-
- if (rfp_start_val == NULL || vty == NULL)
- return NULL;
-
- bgp = rfapi_bgp_lookup_by_rfp (rfp_start_val);
- if (!bgp || !bgp->rfapi_cfg)
- return NULL;
-
- switch (type)
- {
- case RFAPI_RFP_CFG_GROUP_DEFAULT:
- ret = rfapi_rfp_get_or_init_group_config_default (bgp->rfapi_cfg,
- vty, size);
- break;
- case RFAPI_RFP_CFG_GROUP_NVE:
- ret = rfapi_rfp_get_or_init_group_config_nve (bgp->rfapi_cfg,
- vty, size);
- break;
- case RFAPI_RFP_CFG_GROUP_L2:
- ret = rfapi_rfp_get_or_init_group_config_l2 (bgp->rfapi_cfg, vty, size);
- break;
- default:
- zlog_err ("%s: Unknown group type=%d", __func__, type);
- /* should never happen */
- assert ("Unknown type" == NULL);
- break;
- }
- return ret;
+ struct bgp *bgp;
+ void *ret = NULL;
+
+ if (rfp_start_val == NULL || vty == NULL)
+ return NULL;
+
+ bgp = rfapi_bgp_lookup_by_rfp(rfp_start_val);
+ if (!bgp || !bgp->rfapi_cfg)
+ return NULL;
+
+ switch (type) {
+ case RFAPI_RFP_CFG_GROUP_DEFAULT:
+ ret = rfapi_rfp_get_or_init_group_config_default(bgp->rfapi_cfg,
+ vty, size);
+ break;
+ case RFAPI_RFP_CFG_GROUP_NVE:
+ ret = rfapi_rfp_get_or_init_group_config_nve(bgp->rfapi_cfg,
+ vty, size);
+ break;
+ case RFAPI_RFP_CFG_GROUP_L2:
+ ret = rfapi_rfp_get_or_init_group_config_l2(bgp->rfapi_cfg, vty,
+ size);
+ break;
+ default:
+ zlog_err("%s: Unknown group type=%d", __func__, type);
+ /* should never happen */
+ assert("Unknown type" == NULL);
+ break;
+ }
+ return ret;
}
/*------------------------------------------
@@ -4290,9 +4011,9 @@ rfapi_rfp_init_group_config_ptr_vty (
* This is used to get group specific configuration pointer.
* Group is identified by type and vty context.
* RFAPI frees rfp_cfg_group when group is deleted during reconfig,
- * bgp restart or shutdown.
+ * bgp restart or shutdown.
*
- * input:
+ * input:
* rfp_start_val value returned by rfp_start
* type group type
* vty quagga vty context
@@ -4301,64 +4022,56 @@ rfapi_rfp_init_group_config_ptr_vty (
* none
*
* return value:
- * rfp_cfg_group Pointer to configuration structure
+ * rfp_cfg_group Pointer to configuration structure
--------------------------------------------*/
-void *
-rfapi_rfp_get_group_config_ptr_vty (
- void *rfp_start_val,
- rfapi_rfp_cfg_group_type type,
- struct vty *vty)
+void *rfapi_rfp_get_group_config_ptr_vty(void *rfp_start_val,
+ rfapi_rfp_cfg_group_type type,
+ struct vty *vty)
{
- return rfapi_rfp_init_group_config_ptr_vty (rfp_start_val, type, vty, 0);
+ return rfapi_rfp_init_group_config_ptr_vty(rfp_start_val, type, vty, 0);
}
static void *
-rfapi_rfp_get_group_config_name_nve (
- struct rfapi_cfg *rfc,
- const char *name,
- void *criteria,
- rfp_group_config_search_cb_t *search_cb)
+rfapi_rfp_get_group_config_name_nve(struct rfapi_cfg *rfc, const char *name,
+ void *criteria,
+ rfp_group_config_search_cb_t *search_cb)
{
- struct rfapi_nve_group_cfg *rfg;
- struct listnode *node;
-
- for (ALL_LIST_ELEMENTS_RO (rfc->nve_groups_sequential, node, rfg))
- {
- if (!strcmp (rfg->name, name) && /* name match */
- (search_cb == NULL || !search_cb (criteria, rfg->rfp_cfg)))
- return rfg->rfp_cfg;
- }
- return NULL;
+ struct rfapi_nve_group_cfg *rfg;
+ struct listnode *node;
+
+ for (ALL_LIST_ELEMENTS_RO(rfc->nve_groups_sequential, node, rfg)) {
+ if (!strcmp(rfg->name, name) && /* name match */
+ (search_cb == NULL || !search_cb(criteria, rfg->rfp_cfg)))
+ return rfg->rfp_cfg;
+ }
+ return NULL;
}
static void *
-rfapi_rfp_get_group_config_name_l2 (
- struct rfapi_cfg *rfc,
- const char *name,
- void *criteria,
- rfp_group_config_search_cb_t *search_cb)
+rfapi_rfp_get_group_config_name_l2(struct rfapi_cfg *rfc, const char *name,
+ void *criteria,
+ rfp_group_config_search_cb_t *search_cb)
{
- struct rfapi_l2_group_cfg *rfg;
- struct listnode *node;
-
- for (ALL_LIST_ELEMENTS_RO (rfc->l2_groups, node, rfg))
- {
- if (!strcmp (rfg->name, name) && /* name match */
- (search_cb == NULL || !search_cb (criteria, rfg->rfp_cfg)))
- return rfg->rfp_cfg;
- }
- return NULL;
+ struct rfapi_l2_group_cfg *rfg;
+ struct listnode *node;
+
+ for (ALL_LIST_ELEMENTS_RO(rfc->l2_groups, node, rfg)) {
+ if (!strcmp(rfg->name, name) && /* name match */
+ (search_cb == NULL || !search_cb(criteria, rfg->rfp_cfg)))
+ return rfg->rfp_cfg;
+ }
+ return NULL;
}
/*------------------------------------------
* rfapi_rfp_get_group_config_ptr_name
*
* This is used to get group specific configuration pointer.
- * Group is identified by type and name context.
+ * Group is identified by type and name context.
* RFAPI frees rfp_cfg_group when group is deleted during reconfig,
* bgp restart or shutdown.
*
- * input:
+ * input:
* rfp_start_val value returned by rfp_start
* type group type
* name group name
@@ -4369,46 +4082,41 @@ rfapi_rfp_get_group_config_name_l2 (
* none
*
* return value:
- * rfp_cfg_group Pointer to configuration structure
+ * rfp_cfg_group Pointer to configuration structure
--------------------------------------------*/
-void *
-rfapi_rfp_get_group_config_ptr_name (
- void *rfp_start_val,
- rfapi_rfp_cfg_group_type type,
- const char *name,
- void *criteria,
- rfp_group_config_search_cb_t *search_cb)
+void *rfapi_rfp_get_group_config_ptr_name(
+ void *rfp_start_val, rfapi_rfp_cfg_group_type type, const char *name,
+ void *criteria, rfp_group_config_search_cb_t *search_cb)
{
- struct bgp *bgp;
- void *ret = NULL;
-
- if (rfp_start_val == NULL || name == NULL)
- return NULL;
-
- bgp = rfapi_bgp_lookup_by_rfp (rfp_start_val);
- if (!bgp || !bgp->rfapi_cfg)
- return NULL;
-
- switch (type)
- {
- case RFAPI_RFP_CFG_GROUP_DEFAULT:
- ret = bgp->rfapi_cfg->default_rfp_cfg;
- break;
- case RFAPI_RFP_CFG_GROUP_NVE:
- ret = rfapi_rfp_get_group_config_name_nve (bgp->rfapi_cfg,
- name, criteria, search_cb);
- break;
- case RFAPI_RFP_CFG_GROUP_L2:
- ret = rfapi_rfp_get_group_config_name_l2 (bgp->rfapi_cfg,
- name, criteria, search_cb);
- break;
- default:
- zlog_err ("%s: Unknown group type=%d", __func__, type);
- /* should never happen */
- assert ("Unknown type" == NULL);
- break;
- }
- return ret;
+ struct bgp *bgp;
+ void *ret = NULL;
+
+ if (rfp_start_val == NULL || name == NULL)
+ return NULL;
+
+ bgp = rfapi_bgp_lookup_by_rfp(rfp_start_val);
+ if (!bgp || !bgp->rfapi_cfg)
+ return NULL;
+
+ switch (type) {
+ case RFAPI_RFP_CFG_GROUP_DEFAULT:
+ ret = bgp->rfapi_cfg->default_rfp_cfg;
+ break;
+ case RFAPI_RFP_CFG_GROUP_NVE:
+ ret = rfapi_rfp_get_group_config_name_nve(bgp->rfapi_cfg, name,
+ criteria, search_cb);
+ break;
+ case RFAPI_RFP_CFG_GROUP_L2:
+ ret = rfapi_rfp_get_group_config_name_l2(bgp->rfapi_cfg, name,
+ criteria, search_cb);
+ break;
+ default:
+ zlog_err("%s: Unknown group type=%d", __func__, type);
+ /* should never happen */
+ assert("Unknown type" == NULL);
+ break;
+ }
+ return ret;
}
/*------------------------------------------
@@ -4419,7 +4127,7 @@ rfapi_rfp_get_group_config_ptr_name (
* RFAPI frees rfp_cfg_group when group is deleted during reconfig,
* bgp restart or shutdown.
*
- * input:
+ * input:
* rfp_start_val value returned by rfp_start
* type group type
* logical_net_id group logical network identifier
@@ -4430,35 +4138,34 @@ rfapi_rfp_get_group_config_ptr_name (
* none
*
* return value:
- * rfp_cfg_group Pointer to configuration structure
+ * rfp_cfg_group Pointer to configuration structure
--------------------------------------------*/
void *
-rfapi_rfp_get_l2_group_config_ptr_lni (
- void *rfp_start_val,
- uint32_t logical_net_id,
- void *criteria,
- rfp_group_config_search_cb_t *search_cb)
+rfapi_rfp_get_l2_group_config_ptr_lni(void *rfp_start_val,
+ uint32_t logical_net_id, void *criteria,
+ rfp_group_config_search_cb_t *search_cb)
{
- struct bgp *bgp;
- struct rfapi_l2_group_cfg *rfg;
- struct listnode *node;
-
- if (rfp_start_val == NULL)
- return NULL;
-
- bgp = rfapi_bgp_lookup_by_rfp (rfp_start_val);
- if (!bgp || !bgp->rfapi_cfg)
- return NULL;
-
- for (ALL_LIST_ELEMENTS_RO (bgp->rfapi_cfg->l2_groups, node, rfg))
- {
- if (rfg->logical_net_id == logical_net_id &&
- (search_cb == NULL || !search_cb (criteria, rfg->rfp_cfg)))
- {
- if (rfg->rfp_cfg == NULL)
- vnc_zlog_debug_verbose ("%s: returning rfp group config for lni=0", __func__);
- return rfg->rfp_cfg;
- }
- }
- return NULL;
+ struct bgp *bgp;
+ struct rfapi_l2_group_cfg *rfg;
+ struct listnode *node;
+
+ if (rfp_start_val == NULL)
+ return NULL;
+
+ bgp = rfapi_bgp_lookup_by_rfp(rfp_start_val);
+ if (!bgp || !bgp->rfapi_cfg)
+ return NULL;
+
+ for (ALL_LIST_ELEMENTS_RO(bgp->rfapi_cfg->l2_groups, node, rfg)) {
+ if (rfg->logical_net_id == logical_net_id
+ && (search_cb == NULL
+ || !search_cb(criteria, rfg->rfp_cfg))) {
+ if (rfg->rfp_cfg == NULL)
+ vnc_zlog_debug_verbose(
+ "%s: returning rfp group config for lni=0",
+ __func__);
+ return rfg->rfp_cfg;
+ }
+ }
+ return NULL;
}