diff options
Diffstat (limited to 'bgpd/rfapi/rfapi_ap.c')
| -rw-r--r-- | bgpd/rfapi/rfapi_ap.c | 921 |
1 files changed, 428 insertions, 493 deletions
diff --git a/bgpd/rfapi/rfapi_ap.c b/bgpd/rfapi/rfapi_ap.c index fac28cd74c..3112505d4b 100644 --- a/bgpd/rfapi/rfapi_ap.c +++ b/bgpd/rfapi/rfapi_ap.c @@ -1,4 +1,4 @@ -/* +/* * * Copyright 2009-2016, LabN Consulting, L.L.C. * @@ -83,541 +83,476 @@ * is used to spread out the sort for adbs with the same lifetime * and thereby make the skip list operations more efficient. */ -static int -sl_adb_lifetime_cmp (void *adb1, void *adb2) +static int sl_adb_lifetime_cmp(void *adb1, void *adb2) { - struct rfapi_adb *a1 = adb1; - struct rfapi_adb *a2 = adb2; + struct rfapi_adb *a1 = adb1; + struct rfapi_adb *a2 = adb2; - if (a1->lifetime < a2->lifetime) - return -1; - if (a1->lifetime > a2->lifetime) - return 1; + if (a1->lifetime < a2->lifetime) + return -1; + if (a1->lifetime > a2->lifetime) + return 1; - if (a1 < a2) - return -1; - if (a1 > a2) - return 1; + if (a1 < a2) + return -1; + if (a1 > a2) + return 1; - return 0; + return 0; } -void -rfapiApInit (struct rfapi_advertised_prefixes *ap) +void rfapiApInit(struct rfapi_advertised_prefixes *ap) { - ap->ipN_by_prefix = skiplist_new (0, rfapi_rib_key_cmp, NULL); - ap->ip0_by_ether = skiplist_new (0, rfapi_rib_key_cmp, NULL); - ap->by_lifetime = skiplist_new (0, sl_adb_lifetime_cmp, NULL); + ap->ipN_by_prefix = skiplist_new(0, rfapi_rib_key_cmp, NULL); + ap->ip0_by_ether = skiplist_new(0, rfapi_rib_key_cmp, NULL); + ap->by_lifetime = skiplist_new(0, sl_adb_lifetime_cmp, NULL); } -void -rfapiApRelease (struct rfapi_advertised_prefixes *ap) +void rfapiApRelease(struct rfapi_advertised_prefixes *ap) { - struct rfapi_adb *adb; - - /* Free ADBs and lifetime items */ - while (0 == skiplist_first (ap->by_lifetime, NULL, (void **) &adb)) - { - rfapiAdbFree (adb); - skiplist_delete_first (ap->by_lifetime); - } - - while (0 == skiplist_delete_first (ap->ipN_by_prefix)); - while (0 == skiplist_delete_first (ap->ip0_by_ether)); - - /* Free lists */ - skiplist_free (ap->ipN_by_prefix); - skiplist_free (ap->ip0_by_ether); - skiplist_free (ap->by_lifetime); - - ap->ipN_by_prefix = NULL; - ap->ip0_by_ether = NULL; - ap->by_lifetime = NULL; + struct rfapi_adb *adb; + + /* Free ADBs and lifetime items */ + while (0 == skiplist_first(ap->by_lifetime, NULL, (void **)&adb)) { + rfapiAdbFree(adb); + skiplist_delete_first(ap->by_lifetime); + } + + while (0 == skiplist_delete_first(ap->ipN_by_prefix)) + ; + while (0 == skiplist_delete_first(ap->ip0_by_ether)) + ; + + /* Free lists */ + skiplist_free(ap->ipN_by_prefix); + skiplist_free(ap->ip0_by_ether); + skiplist_free(ap->by_lifetime); + + ap->ipN_by_prefix = NULL; + ap->ip0_by_ether = NULL; + ap->by_lifetime = NULL; } -int -rfapiApCount (struct rfapi_descriptor *rfd) +int rfapiApCount(struct rfapi_descriptor *rfd) { - if (!rfd->advertised.by_lifetime) - return 0; + if (!rfd->advertised.by_lifetime) + return 0; - return skiplist_count (rfd->advertised.by_lifetime); + return skiplist_count(rfd->advertised.by_lifetime); } -int -rfapiApCountAll (struct bgp *bgp) +int rfapiApCountAll(struct bgp *bgp) { - struct rfapi *h; - struct listnode *node; - struct rfapi_descriptor *rfd; - int total = 0; - - h = bgp->rfapi; - if (h) - { - for (ALL_LIST_ELEMENTS_RO (&h->descriptors, node, rfd)) - { - total += rfapiApCount (rfd); - } - } - return total; + struct rfapi *h; + struct listnode *node; + struct rfapi_descriptor *rfd; + int total = 0; + + h = bgp->rfapi; + if (h) { + for (ALL_LIST_ELEMENTS_RO(&h->descriptors, node, rfd)) { + total += rfapiApCount(rfd); + } + } + return total; } -void -rfapiApReadvertiseAll (struct bgp *bgp, struct rfapi_descriptor *rfd) +void rfapiApReadvertiseAll(struct bgp *bgp, struct rfapi_descriptor *rfd) { - struct rfapi_adb *adb; - void *cursor = NULL; - int rc; - - for (rc = - skiplist_next (rfd->advertised.by_lifetime, NULL, (void **) &adb, - &cursor); rc == 0; - rc = - skiplist_next (rfd->advertised.by_lifetime, NULL, (void **) &adb, - &cursor)) - { - - struct prefix_rd prd; - uint32_t local_pref = rfp_cost_to_localpref (adb->cost); - - prd = rfd->rd; - prd.family = AF_UNSPEC; - prd.prefixlen = 64; - - /* - * TBD this is not quite right. When pfx_ip is 0/32 or 0/128, - * we need to substitute the VN address as the prefix - */ - add_vnc_route (rfd, bgp, SAFI_MPLS_VPN, &adb->u.s.prefix_ip, &prd, /* RD to use (0 for ENCAP) */ - &rfd->vn_addr, /* nexthop */ - &local_pref, &adb->lifetime, NULL, NULL, /* struct rfapi_un_option */ - NULL, /* struct rfapi_vn_option */ - rfd->rt_export_list, NULL, /* med */ - NULL, ZEBRA_ROUTE_BGP, BGP_ROUTE_RFP, 0); - } + struct rfapi_adb *adb; + void *cursor = NULL; + int rc; + + for (rc = skiplist_next(rfd->advertised.by_lifetime, NULL, + (void **)&adb, &cursor); + rc == 0; rc = skiplist_next(rfd->advertised.by_lifetime, NULL, + (void **)&adb, &cursor)) { + + struct prefix_rd prd; + uint32_t local_pref = rfp_cost_to_localpref(adb->cost); + + prd = rfd->rd; + prd.family = AF_UNSPEC; + prd.prefixlen = 64; + + /* + * TBD this is not quite right. When pfx_ip is 0/32 or 0/128, + * we need to substitute the VN address as the prefix + */ + add_vnc_route(rfd, bgp, SAFI_MPLS_VPN, &adb->u.s.prefix_ip, + &prd, /* RD to use (0 for ENCAP) */ + &rfd->vn_addr, /* nexthop */ + &local_pref, &adb->lifetime, NULL, + NULL, /* struct rfapi_un_option */ + NULL, /* struct rfapi_vn_option */ + rfd->rt_export_list, NULL, /* med */ + NULL, ZEBRA_ROUTE_BGP, BGP_ROUTE_RFP, 0); + } } -void -rfapiApWithdrawAll (struct bgp *bgp, struct rfapi_descriptor *rfd) +void rfapiApWithdrawAll(struct bgp *bgp, struct rfapi_descriptor *rfd) { - struct rfapi_adb *adb; - void *cursor; - int rc; - - - cursor = NULL; - for (rc = - skiplist_next (rfd->advertised.by_lifetime, NULL, (void **) &adb, - &cursor); rc == 0; - rc = - skiplist_next (rfd->advertised.by_lifetime, NULL, (void **) &adb, - &cursor)) - { - - struct prefix pfx_vn_buf; - struct prefix *pfx_ip; - - if (!(RFAPI_0_PREFIX (&adb->u.s.prefix_ip) && - RFAPI_HOST_PREFIX (&adb->u.s.prefix_ip))) - { - - pfx_ip = &adb->u.s.prefix_ip; - - } - else - { - - pfx_ip = NULL; - - /* - * 0/32 or 0/128 => mac advertisement - */ - if (rfapiRaddr2Qprefix (&rfd->vn_addr, &pfx_vn_buf)) - { - /* - * Bad: it means we can't delete the route - */ - vnc_zlog_debug_verbose ("%s: BAD: handle has bad vn_addr: skipping", - __func__); - continue; - } - } - - del_vnc_route (rfd, rfd->peer, bgp, SAFI_MPLS_VPN, pfx_ip ? pfx_ip : &pfx_vn_buf, &adb->u.s.prd, /* RD to use (0 for ENCAP) */ - ZEBRA_ROUTE_BGP, BGP_ROUTE_RFP, NULL, 0); - } + struct rfapi_adb *adb; + void *cursor; + int rc; + + + cursor = NULL; + for (rc = skiplist_next(rfd->advertised.by_lifetime, NULL, + (void **)&adb, &cursor); + rc == 0; rc = skiplist_next(rfd->advertised.by_lifetime, NULL, + (void **)&adb, &cursor)) { + + struct prefix pfx_vn_buf; + struct prefix *pfx_ip; + + if (!(RFAPI_0_PREFIX(&adb->u.s.prefix_ip) + && RFAPI_HOST_PREFIX(&adb->u.s.prefix_ip))) { + + pfx_ip = &adb->u.s.prefix_ip; + + } else { + + pfx_ip = NULL; + + /* + * 0/32 or 0/128 => mac advertisement + */ + if (rfapiRaddr2Qprefix(&rfd->vn_addr, &pfx_vn_buf)) { + /* + * Bad: it means we can't delete the route + */ + vnc_zlog_debug_verbose( + "%s: BAD: handle has bad vn_addr: skipping", + __func__); + continue; + } + } + + del_vnc_route(rfd, rfd->peer, bgp, SAFI_MPLS_VPN, + pfx_ip ? pfx_ip : &pfx_vn_buf, + &adb->u.s.prd, /* RD to use (0 for ENCAP) */ + ZEBRA_ROUTE_BGP, BGP_ROUTE_RFP, NULL, 0); + } } /* * returns nonzero if tunnel readvertisement is needed, 0 otherwise */ -static int -rfapiApAdjustLifetimeStats ( - struct rfapi_descriptor *rfd, - uint32_t *old_lifetime, /* set if removing/replacing */ - uint32_t *new_lifetime) /* set if replacing/adding */ +static int rfapiApAdjustLifetimeStats( + struct rfapi_descriptor *rfd, + uint32_t *old_lifetime, /* set if removing/replacing */ + uint32_t *new_lifetime) /* set if replacing/adding */ { - int advertise = 0; - int find_max = 0; - int find_min = 0; - - vnc_zlog_debug_verbose ("%s: rfd=%p, pOldLife=%p, pNewLife=%p", - __func__, rfd, old_lifetime, new_lifetime); - if (old_lifetime) - vnc_zlog_debug_verbose ("%s: OldLife=%d", __func__, *old_lifetime); - if (new_lifetime) - vnc_zlog_debug_verbose ("%s: NewLife=%d", __func__, *new_lifetime); - - if (new_lifetime) - { - /* - * Adding new lifetime - */ - if (old_lifetime) - { - /* - * replacing existing lifetime - */ - - - /* old and new are same */ - if (*old_lifetime == *new_lifetime) - return 0; - - if (*old_lifetime == rfd->min_prefix_lifetime) - { - find_min = 1; - } - if (*old_lifetime == rfd->max_prefix_lifetime) - { - find_max = 1; - } - - /* no need to search if new value is at or equals min|max */ - if (*new_lifetime <= rfd->min_prefix_lifetime) - { - rfd->min_prefix_lifetime = *new_lifetime; - find_min = 0; - } - if (*new_lifetime >= rfd->max_prefix_lifetime) - { - rfd->max_prefix_lifetime = *new_lifetime; - advertise = 1; - find_max = 0; - } - - } - else - { - /* - * Just adding new lifetime - */ - if (*new_lifetime < rfd->min_prefix_lifetime) - { - rfd->min_prefix_lifetime = *new_lifetime; - } - if (*new_lifetime > rfd->max_prefix_lifetime) - { - advertise = 1; - rfd->max_prefix_lifetime = *new_lifetime; - } - - } - } - else - { - /* - * Deleting - */ - - /* - * See if the max prefix lifetime for this NVE has decreased. - * The easy optimization: track min & max; walk the table only - * if they are different. - * The general optimization: index the advertised_prefixes - * table by lifetime. - * - * Note: for a given nve_descriptor, only one of the - * advertised_prefixes[] tables will be used: viz., the - * address family that matches the VN address. - * - */ - if (rfd->max_prefix_lifetime == rfd->min_prefix_lifetime) - { - - /* - * Common case: all lifetimes are the same. Only - * thing we need to do here is check if there are - * no exported routes left. In that case, reinitialize - * the max and min values. - */ - if (!rfapiApCount (rfd)) - { - rfd->max_prefix_lifetime = 0; - rfd->min_prefix_lifetime = UINT32_MAX; - } - - - } - else - { - if (old_lifetime) - { - if (*old_lifetime == rfd->min_prefix_lifetime) - { - find_min = 1; - } - if (*old_lifetime == rfd->max_prefix_lifetime) - { - find_max = 1; - } - } - } - } - - if (find_min || find_max) - { - uint32_t min = UINT32_MAX; - uint32_t max = 0; - - struct rfapi_adb *adb_min; - struct rfapi_adb *adb_max; - - if (!skiplist_first - (rfd->advertised.by_lifetime, (void **) &adb_min, NULL) - && !skiplist_last (rfd->advertised.by_lifetime, (void **) &adb_max, - NULL)) - { - - /* - * This should always work - */ - min = adb_min->lifetime; - max = adb_max->lifetime; - - } - else - { - - void *cursor; - struct rfapi_rib_key rk; - struct rfapi_adb *adb; - int rc; - - vnc_zlog_debug_verbose ("%s: walking to find new min/max", __func__); - - cursor = NULL; - for (rc = skiplist_next (rfd->advertised.ipN_by_prefix, - (void **) &rk, (void **) &adb, - &cursor); !rc; - rc = - skiplist_next (rfd->advertised.ipN_by_prefix, - (void **) &rk, (void **) &adb, &cursor)) - { - - uint32_t lt = adb->lifetime; - - if (lt > max) - max = lt; - if (lt < min) - min = lt; - } - cursor = NULL; - for (rc = skiplist_next (rfd->advertised.ip0_by_ether, - (void **) &rk, (void **) &adb, - &cursor); !rc; - rc = - skiplist_next (rfd->advertised.ip0_by_ether, (void **) &rk, - (void **) &adb, &cursor)) - { - - uint32_t lt = adb->lifetime; - - if (lt > max) - max = lt; - if (lt < min) - min = lt; - } - } - - /* - * trigger tunnel route update - * but only if we found a VPN route and it had - * a lifetime greater than 0 - */ - if (max && rfd->max_prefix_lifetime != max) - advertise = 1; - rfd->max_prefix_lifetime = max; - rfd->min_prefix_lifetime = min; - } - - vnc_zlog_debug_verbose ("%s: returning advertise=%d, min=%d, max=%d", - __func__, advertise, rfd->min_prefix_lifetime, - rfd->max_prefix_lifetime); - - return (advertise != 0); + int advertise = 0; + int find_max = 0; + int find_min = 0; + + vnc_zlog_debug_verbose("%s: rfd=%p, pOldLife=%p, pNewLife=%p", __func__, + rfd, old_lifetime, new_lifetime); + if (old_lifetime) + vnc_zlog_debug_verbose("%s: OldLife=%d", __func__, + *old_lifetime); + if (new_lifetime) + vnc_zlog_debug_verbose("%s: NewLife=%d", __func__, + *new_lifetime); + + if (new_lifetime) { + /* + * Adding new lifetime + */ + if (old_lifetime) { + /* + * replacing existing lifetime + */ + + + /* old and new are same */ + if (*old_lifetime == *new_lifetime) + return 0; + + if (*old_lifetime == rfd->min_prefix_lifetime) { + find_min = 1; + } + if (*old_lifetime == rfd->max_prefix_lifetime) { + find_max = 1; + } + + /* no need to search if new value is at or equals + * min|max */ + if (*new_lifetime <= rfd->min_prefix_lifetime) { + rfd->min_prefix_lifetime = *new_lifetime; + find_min = 0; + } + if (*new_lifetime >= rfd->max_prefix_lifetime) { + rfd->max_prefix_lifetime = *new_lifetime; + advertise = 1; + find_max = 0; + } + + } else { + /* + * Just adding new lifetime + */ + if (*new_lifetime < rfd->min_prefix_lifetime) { + rfd->min_prefix_lifetime = *new_lifetime; + } + if (*new_lifetime > rfd->max_prefix_lifetime) { + advertise = 1; + rfd->max_prefix_lifetime = *new_lifetime; + } + } + } else { + /* + * Deleting + */ + + /* + * See if the max prefix lifetime for this NVE has decreased. + * The easy optimization: track min & max; walk the table only + * if they are different. + * The general optimization: index the advertised_prefixes + * table by lifetime. + * + * Note: for a given nve_descriptor, only one of the + * advertised_prefixes[] tables will be used: viz., the + * address family that matches the VN address. + * + */ + if (rfd->max_prefix_lifetime == rfd->min_prefix_lifetime) { + + /* + * Common case: all lifetimes are the same. Only + * thing we need to do here is check if there are + * no exported routes left. In that case, reinitialize + * the max and min values. + */ + if (!rfapiApCount(rfd)) { + rfd->max_prefix_lifetime = 0; + rfd->min_prefix_lifetime = UINT32_MAX; + } + + + } else { + if (old_lifetime) { + if (*old_lifetime == rfd->min_prefix_lifetime) { + find_min = 1; + } + if (*old_lifetime == rfd->max_prefix_lifetime) { + find_max = 1; + } + } + } + } + + if (find_min || find_max) { + uint32_t min = UINT32_MAX; + uint32_t max = 0; + + struct rfapi_adb *adb_min; + struct rfapi_adb *adb_max; + + if (!skiplist_first(rfd->advertised.by_lifetime, + (void **)&adb_min, NULL) + && !skiplist_last(rfd->advertised.by_lifetime, + (void **)&adb_max, NULL)) { + + /* + * This should always work + */ + min = adb_min->lifetime; + max = adb_max->lifetime; + + } else { + + void *cursor; + struct rfapi_rib_key rk; + struct rfapi_adb *adb; + int rc; + + vnc_zlog_debug_verbose( + "%s: walking to find new min/max", __func__); + + cursor = NULL; + for (rc = skiplist_next(rfd->advertised.ipN_by_prefix, + (void **)&rk, (void **)&adb, + &cursor); + !rc; + rc = skiplist_next(rfd->advertised.ipN_by_prefix, + (void **)&rk, (void **)&adb, + &cursor)) { + + uint32_t lt = adb->lifetime; + + if (lt > max) + max = lt; + if (lt < min) + min = lt; + } + cursor = NULL; + for (rc = skiplist_next(rfd->advertised.ip0_by_ether, + (void **)&rk, (void **)&adb, + &cursor); + !rc; + rc = skiplist_next(rfd->advertised.ip0_by_ether, + (void **)&rk, (void **)&adb, + &cursor)) { + + uint32_t lt = adb->lifetime; + + if (lt > max) + max = lt; + if (lt < min) + min = lt; + } + } + + /* + * trigger tunnel route update + * but only if we found a VPN route and it had + * a lifetime greater than 0 + */ + if (max && rfd->max_prefix_lifetime != max) + advertise = 1; + rfd->max_prefix_lifetime = max; + rfd->min_prefix_lifetime = min; + } + + vnc_zlog_debug_verbose("%s: returning advertise=%d, min=%d, max=%d", + __func__, advertise, rfd->min_prefix_lifetime, + rfd->max_prefix_lifetime); + + return (advertise != 0); } -/* +/* * Return Value * * 0 No need to advertise tunnel route * non-0 advertise tunnel route */ -int -rfapiApAdd ( - struct bgp *bgp, - struct rfapi_descriptor *rfd, - struct prefix *pfx_ip, - struct prefix *pfx_eth, - struct prefix_rd *prd, - uint32_t lifetime, - uint8_t cost, - struct rfapi_l2address_option *l2o) /* other options TBD */ +int rfapiApAdd(struct bgp *bgp, struct rfapi_descriptor *rfd, + struct prefix *pfx_ip, struct prefix *pfx_eth, + struct prefix_rd *prd, uint32_t lifetime, uint8_t cost, + struct rfapi_l2address_option *l2o) /* other options TBD */ { - int rc; - struct rfapi_adb *adb; - uint32_t old_lifetime = 0; - int use_ip0 = 0; - struct rfapi_rib_key rk; - - rfapi_rib_key_init(pfx_ip, prd, pfx_eth, &rk); - if (RFAPI_0_PREFIX (pfx_ip) && RFAPI_HOST_PREFIX (pfx_ip)) - { - use_ip0 = 1; - assert (pfx_eth); - rc = - skiplist_search (rfd->advertised.ip0_by_ether, &rk, - (void **) &adb); - - } - else - { - - /* find prefix in advertised prefixes list */ - rc = - skiplist_search (rfd->advertised.ipN_by_prefix, &rk, - (void **) &adb); - } - - - if (rc) - { - /* Not found */ - adb = XCALLOC (MTYPE_RFAPI_ADB, sizeof (struct rfapi_adb)); - assert (adb); - adb->lifetime = lifetime; - adb->u.key = rk; - - if (use_ip0) - { - assert (pfx_eth); - skiplist_insert (rfd->advertised.ip0_by_ether, &adb->u.key, - adb); - } - else - { - skiplist_insert (rfd->advertised.ipN_by_prefix, &adb->u.key, - adb); - } - - skiplist_insert (rfd->advertised.by_lifetime, adb, adb); - } - else - { - old_lifetime = adb->lifetime; - if (old_lifetime != lifetime) - { - assert (!skiplist_delete (rfd->advertised.by_lifetime, adb, NULL)); - adb->lifetime = lifetime; - assert (!skiplist_insert (rfd->advertised.by_lifetime, adb, adb)); - } - } - adb->cost = cost; - if (l2o) - adb->l2o = *l2o; - else - memset (&adb->l2o, 0, sizeof (struct rfapi_l2address_option)); - - if (rfapiApAdjustLifetimeStats - (rfd, (rc ? NULL : &old_lifetime), &lifetime)) - return 1; - - return 0; + int rc; + struct rfapi_adb *adb; + uint32_t old_lifetime = 0; + int use_ip0 = 0; + struct rfapi_rib_key rk; + + rfapi_rib_key_init(pfx_ip, prd, pfx_eth, &rk); + if (RFAPI_0_PREFIX(pfx_ip) && RFAPI_HOST_PREFIX(pfx_ip)) { + use_ip0 = 1; + assert(pfx_eth); + rc = skiplist_search(rfd->advertised.ip0_by_ether, &rk, + (void **)&adb); + + } else { + + /* find prefix in advertised prefixes list */ + rc = skiplist_search(rfd->advertised.ipN_by_prefix, &rk, + (void **)&adb); + } + + + if (rc) { + /* Not found */ + adb = XCALLOC(MTYPE_RFAPI_ADB, sizeof(struct rfapi_adb)); + assert(adb); + adb->lifetime = lifetime; + adb->u.key = rk; + + if (use_ip0) { + assert(pfx_eth); + skiplist_insert(rfd->advertised.ip0_by_ether, + &adb->u.key, adb); + } else { + skiplist_insert(rfd->advertised.ipN_by_prefix, + &adb->u.key, adb); + } + + skiplist_insert(rfd->advertised.by_lifetime, adb, adb); + } else { + old_lifetime = adb->lifetime; + if (old_lifetime != lifetime) { + assert(!skiplist_delete(rfd->advertised.by_lifetime, + adb, NULL)); + adb->lifetime = lifetime; + assert(!skiplist_insert(rfd->advertised.by_lifetime, + adb, adb)); + } + } + adb->cost = cost; + if (l2o) + adb->l2o = *l2o; + else + memset(&adb->l2o, 0, sizeof(struct rfapi_l2address_option)); + + if (rfapiApAdjustLifetimeStats(rfd, (rc ? NULL : &old_lifetime), + &lifetime)) + return 1; + + return 0; } /* * After this function returns successfully, caller should call * rfapiAdjustLifetimeStats() and possibly rfapiTunnelRouteAnnounce() */ -int -rfapiApDelete ( - struct bgp *bgp, - struct rfapi_descriptor *rfd, - struct prefix *pfx_ip, - struct prefix *pfx_eth, - struct prefix_rd *prd, - int *advertise_tunnel) /* out */ +int rfapiApDelete(struct bgp *bgp, struct rfapi_descriptor *rfd, + struct prefix *pfx_ip, struct prefix *pfx_eth, + struct prefix_rd *prd, int *advertise_tunnel) /* out */ { - int rc; - struct rfapi_adb *adb; - uint32_t old_lifetime; - int use_ip0 = 0; - struct rfapi_rib_key rk; - - if (advertise_tunnel) - *advertise_tunnel = 0; - - rfapi_rib_key_init(pfx_ip, prd, pfx_eth, &rk); - /* find prefix in advertised prefixes list */ - if (RFAPI_0_PREFIX (pfx_ip) && RFAPI_HOST_PREFIX (pfx_ip)) - { - use_ip0 = 1; - assert (pfx_eth); - - rc = - skiplist_search (rfd->advertised.ip0_by_ether, &rk, - (void **) &adb); - - } - else - { - - /* find prefix in advertised prefixes list */ - rc = - skiplist_search (rfd->advertised.ipN_by_prefix, &rk, - (void **) &adb); - } - - if (rc) - { - return ENOENT; - } - - old_lifetime = adb->lifetime; - - if (use_ip0) - { - rc = skiplist_delete (rfd->advertised.ip0_by_ether, &rk, NULL); - } - else - { - rc = skiplist_delete (rfd->advertised.ipN_by_prefix, &rk, NULL); - } - assert (!rc); - - rc = skiplist_delete (rfd->advertised.by_lifetime, adb, NULL); - assert (!rc); - - rfapiAdbFree (adb); - - if (rfapiApAdjustLifetimeStats (rfd, &old_lifetime, NULL)) - { - if (advertise_tunnel) - *advertise_tunnel = 1; - } - - return 0; + int rc; + struct rfapi_adb *adb; + uint32_t old_lifetime; + int use_ip0 = 0; + struct rfapi_rib_key rk; + + if (advertise_tunnel) + *advertise_tunnel = 0; + + rfapi_rib_key_init(pfx_ip, prd, pfx_eth, &rk); + /* find prefix in advertised prefixes list */ + if (RFAPI_0_PREFIX(pfx_ip) && RFAPI_HOST_PREFIX(pfx_ip)) { + use_ip0 = 1; + assert(pfx_eth); + + rc = skiplist_search(rfd->advertised.ip0_by_ether, &rk, + (void **)&adb); + + } else { + + /* find prefix in advertised prefixes list */ + rc = skiplist_search(rfd->advertised.ipN_by_prefix, &rk, + (void **)&adb); + } + + if (rc) { + return ENOENT; + } + + old_lifetime = adb->lifetime; + + if (use_ip0) { + rc = skiplist_delete(rfd->advertised.ip0_by_ether, &rk, NULL); + } else { + rc = skiplist_delete(rfd->advertised.ipN_by_prefix, &rk, NULL); + } + assert(!rc); + + rc = skiplist_delete(rfd->advertised.by_lifetime, adb, NULL); + assert(!rc); + + rfapiAdbFree(adb); + + if (rfapiApAdjustLifetimeStats(rfd, &old_lifetime, NULL)) { + if (advertise_tunnel) + *advertise_tunnel = 1; + } + + return 0; } |
