+// SPDX-License-Identifier: GPL-2.0-or-later
/*
-*
-* Copyright 2009-2016, LabN Consulting, L.L.C.
-*
-*
-* This program is free software; you can redistribute it and/or
-* modify it under the terms of the GNU General Public License
-* as published by the Free Software Foundation; either version 2
-* of the License, or (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program; see the file COPYING; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ * Copyright 2009-2016, LabN Consulting, L.L.C.
+ */
/*
* File: rfapi_import.c
#include "lib/memory.h"
#include "lib/log.h"
#include "lib/skiplist.h"
-#include "lib/thread.h"
+#include "frrevent.h"
#include "lib/stream.h"
#include "lib/lib_errors.h"
struct agg_node *rn;
int holddown_count = 0;
- int local_count = 0;
int imported_count = 0;
int remote_count = 0;
++holddown_count;
} else {
- if (RFAPI_LOCAL_BI(bpi)) {
- ++local_count;
- } else {
+ if (!RFAPI_LOCAL_BI(bpi)) {
if (RFAPI_DIRECT_IMPORT_BI(
bpi)) {
++imported_count;
}
break;
- default:
- assert(0);
+ case SAFI_UNSPEC:
+ case SAFI_UNICAST:
+ case SAFI_MULTICAST:
+ case SAFI_EVPN:
+ case SAFI_LABELED_UNICAST:
+ case SAFI_FLOWSPEC:
+ case SAFI_MAX:
+ assert(!"Passed in safi should be impossible");
}
}
if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)
&& bpi->extra->vnc.import.timer) {
struct rfapi_withdraw *wcb =
- THREAD_ARG(bpi->extra->vnc.import.timer);
+ EVENT_ARG(bpi->extra->vnc.import.timer);
XFREE(MTYPE_RFAPI_WITHDRAW, wcb);
- THREAD_OFF(bpi->extra->vnc.import.timer);
+ EVENT_OFF(bpi->extra->vnc.import.timer);
}
next = bpi->next;
for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
struct agg_node *rn;
+ struct agg_table *at;
- for (rn = agg_route_top(it->imported_vpn[afi]); rn;
- rn = agg_route_next(rn)) {
- /*
- * Each route_node has:
- * aggregate: points to rfapi_it_extra with monitor
- * chain(s)
- * info: points to chain of bgp_path_info
- */
- /* free bgp_path_info and its children */
- rfapiBgpInfoChainFree(rn->info);
- rn->info = NULL;
+ at = it->imported_vpn[afi];
+ if (at) {
+ for (rn = agg_route_top(at); rn;
+ rn = agg_route_next(rn)) {
+ /*
+ * Each route_node has:
+ * aggregate: points to rfapi_it_extra with
+ * monitor chain(s)
+ * info: points to chain of bgp_path_info
+ */
+ /* free bgp_path_info and its children */
+ rfapiBgpInfoChainFree(rn->info);
+ rn->info = NULL;
- rfapiMonitorExtraFlush(SAFI_MPLS_VPN, rn);
+ rfapiMonitorExtraFlush(SAFI_MPLS_VPN, rn);
+ }
+ agg_table_finish(at);
}
- for (rn = agg_route_top(it->imported_encap[afi]); rn;
- rn = agg_route_next(rn)) {
- /* free bgp_path_info and its children */
- rfapiBgpInfoChainFree(rn->info);
- rn->info = NULL;
+ if (at) {
+ at = it->imported_encap[afi];
+ for (rn = agg_route_top(at); rn;
+ rn = agg_route_next(rn)) {
+ /* free bgp_path_info and its children */
+ rfapiBgpInfoChainFree(rn->info);
+ rn->info = NULL;
- rfapiMonitorExtraFlush(SAFI_ENCAP, rn);
+ rfapiMonitorExtraFlush(SAFI_ENCAP, rn);
+ }
+ agg_table_finish(at);
}
-
- agg_table_finish(it->imported_vpn[afi]);
- agg_table_finish(it->imported_encap[afi]);
}
if (it->monitor_exterior_orphans) {
skiplist_free(it->monitor_exterior_orphans);
assert(bpi);
assert(bpi->extra);
- vnc_zlog_debug_verbose("%s: bpi %p, peer %p, rd %pRD", __func__, bpi,
+ vnc_zlog_debug_verbose("%s: bpi %p, peer %p, rd %pRDP", __func__, bpi,
bpi->peer, &bpi->extra->vnc.import.rd);
sl = RFAPI_RDINDEX_W_ALLOC(rn);
char buf[RD_ADDRSTRLEN];
char buf_aux_pfx[PREFIX_STRLEN];
- prefix_rd2str(&k->extra->vnc.import.rd, buf, sizeof(buf));
+ prefix_rd2str(
+ &k->extra->vnc.import.rd, buf, sizeof(buf),
+ bgp_get_asnotation(k->peer ? k->peer->bgp : NULL));
if (k->extra->vnc.import.aux_prefix.family) {
prefix2str(&k->extra->vnc.import.aux_prefix,
buf_aux_pfx, sizeof(buf_aux_pfx));
strlcpy(buf_aux_pfx, "(nil)", sizeof(buf_aux_pfx));
vnc_zlog_debug_verbose(
- "%s want prd=%pRD, peer=%p, aux_prefix=%s", __func__,
+ "%s want prd=%pRDP, peer=%p, aux_prefix=%s", __func__,
prd, peer, buf_aux_pfx);
rfapiItBiIndexDump(rn);
}
bpi_result = bpi_result->next) {
#ifdef DEBUG_BI_SEARCH
vnc_zlog_debug_verbose(
- "%s: bpi has prd=%pRD, peer=%p", __func__,
+ "%s: bpi has prd=%pRDP, peer=%p", __func__,
&bpi_result->extra->vnc.import.rd,
bpi_result->peer);
#endif
struct skiplist *sl;
int rc;
- vnc_zlog_debug_verbose("%s: bpi %p, peer %p, rd %pRD", __func__, bpi,
+ vnc_zlog_debug_verbose("%s: bpi %p, peer %p, rd %pRDP", __func__, bpi,
bpi->peer, &bpi->extra->vnc.import.rd);
sl = RFAPI_RDINDEX(rn);
}
/*
- * quagga lib/thread.h says this must return int even though
- * it doesn't do anything with the return value
+ * Timer callback for withdraw
*/
-static void rfapiWithdrawTimerVPN(struct thread *t)
+static void rfapiWithdrawTimerVPN(struct event *t)
{
- struct rfapi_withdraw *wcb = THREAD_ARG(t);
+ struct rfapi_withdraw *wcb = EVENT_ARG(t);
struct bgp_path_info *bpi = wcb->info;
struct bgp *bgp = bgp_get_default();
const struct prefix *p;
struct rfapi_monitor_vpn *moved;
afi_t afi;
+ bool early_exit = false;
if (bgp == NULL) {
vnc_zlog_debug_verbose(
"%s: NULL BGP pointer, assume shutdown race condition!!!",
__func__);
- return;
+ early_exit = true;
}
- if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
+ if (bgp && CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
vnc_zlog_debug_verbose(
"%s: BGP delete in progress, assume shutdown race condition!!!",
__func__);
+ early_exit = true;
+ }
+
+ /* This callback is responsible for the withdraw object's memory */
+ if (early_exit) {
+ XFREE(MTYPE_RFAPI_WITHDRAW, wcb);
return;
}
+
assert(wcb->node);
assert(bpi);
assert(wcb->import_table);
return 0;
}
-static void rfapiWithdrawTimerEncap(struct thread *t)
+static void rfapiWithdrawTimerEncap(struct event *t)
{
- struct rfapi_withdraw *wcb = THREAD_ARG(t);
+ struct rfapi_withdraw *wcb = EVENT_ARG(t);
struct bgp_path_info *bpi = wcb->info;
int was_first_route = 0;
struct rfapi_monitor_encap *em;
rfapiBiStartWithdrawTimer(struct rfapi_import_table *import_table,
struct agg_node *rn, struct bgp_path_info *bpi,
afi_t afi, safi_t safi,
- void (*timer_service_func)(struct thread *))
+ void (*timer_service_func)(struct event *))
{
uint32_t lifetime;
struct rfapi_withdraw *wcb;
if (lifetime > UINT32_MAX / 1001) {
/* sub-optimal case, but will probably never happen */
bpi->extra->vnc.import.timer = NULL;
- thread_add_timer(bm->master, timer_service_func, wcb, lifetime,
- &bpi->extra->vnc.import.timer);
+ event_add_timer(bm->master, timer_service_func, wcb, lifetime,
+ &bpi->extra->vnc.import.timer);
} else {
static uint32_t jitter;
uint32_t lifetime_msec;
lifetime_msec = (lifetime * 1000) + jitter;
bpi->extra->vnc.import.timer = NULL;
- thread_add_timer_msec(bm->master, timer_service_func, wcb,
- lifetime_msec,
- &bpi->extra->vnc.import.timer);
+ event_add_timer_msec(bm->master, timer_service_func, wcb,
+ lifetime_msec,
+ &bpi->extra->vnc.import.timer);
}
/* re-sort route list (BGP_PATH_REMOVED routes are last) */
struct agg_node *rn, struct bgp_path_info *bpi)
{
struct rfapi_withdraw *wcb;
- struct thread t;
+ struct event t;
/*
* pretend we're an expiring timer
vnc_zlog_debug_verbose(
"%s: entry: %s: prefix %s/%d", __func__, action_str,
- inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ), p->prefixlen);
+ inet_ntop(p->family, &p->u.prefix, buf, sizeof(buf)),
+ p->prefixlen);
memset(&p_firstbpi_old, 0, sizeof(p_firstbpi_old));
memset(&p_firstbpi_new, 0, sizeof(p_firstbpi_new));
rt = import_table->imported_encap[afi];
break;
- default:
+ case AFI_UNSPEC:
+ case AFI_L2VPN:
+ case AFI_MAX:
flog_err(EC_LIB_DEVELOPMENT, "%s: bad afi %d", __func__, afi);
return;
}
*/
if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)
&& bpi->extra->vnc.import.timer) {
- struct rfapi_withdraw *wcb = THREAD_ARG(
+ struct rfapi_withdraw *wcb = EVENT_ARG(
bpi->extra->vnc.import.timer);
XFREE(MTYPE_RFAPI_WITHDRAW, wcb);
- THREAD_OFF(
- bpi->extra->vnc.import.timer);
+ EVENT_OFF(bpi->extra->vnc.import.timer);
}
if (action == FIF_ACTION_UPDATE) {
* bpi
*/
struct rfapi_withdraw *wcb;
- struct thread t;
+ struct event t;
/*
* pretend we're an expiring timer
__func__);
if (bpi->extra->vnc.import.timer) {
struct rfapi_withdraw *wcb =
- THREAD_ARG(bpi->extra->vnc.import.timer);
+ EVENT_ARG(bpi->extra->vnc.import.timer);
XFREE(MTYPE_RFAPI_WITHDRAW, wcb);
- THREAD_OFF(bpi->extra->vnc.import.timer);
+ EVENT_OFF(bpi->extra->vnc.import.timer);
}
rfapiExpireEncapNow(import_table, rn, bpi);
}
int lockoffset)
{
struct rfapi_withdraw *wcb;
- struct thread t;
+ struct event t;
/*
* pretend we're an expiring timer
rt = import_table->imported_vpn[afi];
break;
- default:
+ case AFI_UNSPEC:
+ case AFI_MAX:
flog_err(EC_LIB_DEVELOPMENT, "%s: bad afi %d", __func__, afi);
return;
}
*/
if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)
&& bpi->extra->vnc.import.timer) {
- struct rfapi_withdraw *wcb = THREAD_ARG(
+ struct rfapi_withdraw *wcb = EVENT_ARG(
bpi->extra->vnc.import.timer);
XFREE(MTYPE_RFAPI_WITHDRAW, wcb);
- THREAD_OFF(
- bpi->extra->vnc.import.timer);
+ EVENT_OFF(bpi->extra->vnc.import.timer);
import_table->holddown_count[afi] -= 1;
RFAPI_UPDATE_ITABLE_COUNT(
__func__);
if (bpi->extra->vnc.import.timer) {
struct rfapi_withdraw *wcb =
- THREAD_ARG(bpi->extra->vnc.import.timer);
+ EVENT_ARG(bpi->extra->vnc.import.timer);
XFREE(MTYPE_RFAPI_WITHDRAW, wcb);
- THREAD_OFF(bpi->extra->vnc.import.timer);
+ EVENT_OFF(bpi->extra->vnc.import.timer);
}
rfapiExpireVpnNow(import_table, rn, bpi, 0);
}
case SAFI_ENCAP:
return rfapiBgpInfoFilteredImportEncap;
- default:
+ case SAFI_UNSPEC:
+ case SAFI_UNICAST:
+ case SAFI_MULTICAST:
+ case SAFI_EVPN:
+ case SAFI_LABELED_UNICAST:
+ case SAFI_FLOWSPEC:
+ case SAFI_MAX:
/* not expected */
flog_err(EC_LIB_DEVELOPMENT, "%s: bad safi %d", __func__, safi);
return rfapiBgpInfoFilteredImportBadSafi;
}
+
+ assert(!"Reached end of function when we were not expecting to");
}
void rfapiProcessUpdate(struct peer *peer,
{
struct agg_node *rn;
struct bgp_path_info *bpi;
- struct agg_table *rt;
- void (*timer_service_func)(struct thread *);
+ struct agg_table *rt = NULL;
+ void (*timer_service_func)(struct event *) = NULL;
assert(afi == AFI_IP || afi == AFI_IP6);
rt = import_table->imported_encap[afi];
timer_service_func = rfapiWithdrawTimerEncap;
break;
- default:
+ case SAFI_UNSPEC:
+ case SAFI_UNICAST:
+ case SAFI_MULTICAST:
+ case SAFI_EVPN:
+ case SAFI_LABELED_UNICAST:
+ case SAFI_FLOWSPEC:
+ case SAFI_MAX:
/* Suppress uninitialized variable warning */
rt = NULL;
timer_service_func = NULL;
assert(0);
}
-
for (rn = agg_route_top(rt); rn; rn = agg_route_next(rn)) {
for (bpi = rn->info; bpi; bpi = bpi->next) {
if (bpi->peer == peer) {
h->resolve_nve_nexthop = NULL;
}
- agg_table_finish(h->it_ce->imported_vpn[AFI_IP]);
- agg_table_finish(h->it_ce->imported_vpn[AFI_IP6]);
- agg_table_finish(h->it_ce->imported_encap[AFI_IP]);
- agg_table_finish(h->it_ce->imported_encap[AFI_IP6]);
+ rfapiImportTableFlush(h->it_ce);
if (h->import_mac) {
struct rfapi_import_table *it;
continue;
if (bpi->extra->vnc.import.timer) {
struct rfapi_withdraw *wcb =
- THREAD_ARG(
+ EVENT_ARG(
bpi->extra->vnc
.import
.timer);
afi, 1);
XFREE(MTYPE_RFAPI_WITHDRAW,
wcb);
- THREAD_OFF(
- bpi->extra->vnc.import
- .timer);
+ EVENT_OFF(bpi->extra->vnc.import
+ .timer);
}
} else {
if (!delete_active)