/* If force flag is not set, do not modify falgs at all for uninstall
the route from FIB. */
static int nexthop_active(afi_t afi, struct route_entry *re,
- struct nexthop *nexthop, int set,
+ struct nexthop *nexthop, bool set,
struct route_node *top)
{
struct prefix p;
return NULL;
}
-/*
- * This clone function, unlike its original rib_lookup_ipv4(), checks
- * if specified IPv4 route record (prefix/mask -> gate) exists in
- * the whole RIB and has ROUTE_ENTRY_SELECTED_FIB set.
- *
- * Return values:
- * -1: error
- * 0: exact match found
- * 1: a match was found with a different gate
- * 2: connected route found
- * 3: no matches found
- */
-int rib_lookup_ipv4_route(struct prefix_ipv4 *p, union sockunion *qgate,
- vrf_id_t vrf_id)
-{
- struct route_table *table;
- struct route_node *rn;
- struct route_entry *match = NULL;
- struct nexthop *nexthop;
- int nexthops_active;
- rib_dest_t *dest;
-
- /* Lookup table. */
- table = zebra_vrf_table(AFI_IP, SAFI_UNICAST, vrf_id);
- if (!table)
- return ZEBRA_RIB_LOOKUP_ERROR;
-
- /* Scan the RIB table for exactly matching RIB entry. */
- rn = route_node_lookup(table, (struct prefix *)p);
-
- /* No route for this prefix. */
- if (!rn)
- return ZEBRA_RIB_NOTFOUND;
-
- /* Unlock node. */
- route_unlock_node(rn);
- dest = rib_dest_from_rnode(rn);
-
- /* Find out if a "selected" RR for the discovered RIB entry exists ever.
- */
- if (dest && dest->selected_fib
- && !CHECK_FLAG(dest->selected_fib->status, ROUTE_ENTRY_REMOVED))
- match = dest->selected_fib;
-
- /* None such found :( */
- if (!match)
- return ZEBRA_RIB_NOTFOUND;
-
- if (match->type == ZEBRA_ROUTE_CONNECT)
- return ZEBRA_RIB_FOUND_CONNECTED;
-
- /* Ok, we have a cood candidate, let's check it's nexthop list... */
- nexthops_active = 0;
- for (ALL_NEXTHOPS(match->ng, nexthop))
- if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)) {
- nexthops_active = 1;
- if (nexthop->gate.ipv4.s_addr == sockunion2ip(qgate))
- return ZEBRA_RIB_FOUND_EXACT;
- if (IS_ZEBRA_DEBUG_RIB) {
- char gate_buf[INET_ADDRSTRLEN],
- qgate_buf[INET_ADDRSTRLEN];
- inet_ntop(AF_INET, &nexthop->gate.ipv4.s_addr,
- gate_buf, INET_ADDRSTRLEN);
- inet_ntop(AF_INET, &sockunion2ip(qgate),
- qgate_buf, INET_ADDRSTRLEN);
- zlog_debug("%s: qgate == %s, %s == %s",
- __func__, qgate_buf,
- nexthop->rparent ? "rgate" : "gate",
- gate_buf);
- }
- }
-
- if (nexthops_active)
- return ZEBRA_RIB_FOUND_NOGATE;
-
- return ZEBRA_RIB_NOTFOUND;
-}
-
#define RIB_SYSTEM_ROUTE(R) \
((R)->type == ZEBRA_ROUTE_KERNEL || (R)->type == ZEBRA_ROUTE_CONNECT)
static unsigned nexthop_active_check(struct route_node *rn,
struct route_entry *re,
- struct nexthop *nexthop, int set)
+ struct nexthop *nexthop, bool set)
{
struct interface *ifp;
route_map_result_t ret = RMAP_MATCH;
*/
static int nexthop_active_update(struct route_node *rn, struct route_entry *re,
- int set)
+ bool set)
{
struct nexthop *nexthop;
union g_addr prev_src;
prev_src = nexthop->rmap_src;
prev_active = CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
prev_index = nexthop->ifindex;
- if ((new_active = nexthop_active_check(rn, re, nexthop, set)))
+ /*
+ * We need to respect the multipath_num here
+ * as that what we should be able to install from
+ * a multipath perpsective should not be a data plane
+ * decision point.
+ */
+ new_active = nexthop_active_check(rn, re, nexthop, set);
+ if (new_active && re->nexthop_active_num >= multipath_num) {
+ UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
+ new_active = 0;
+ }
+ if (new_active)
re->nexthop_active_num++;
/* Don't allow src setting on IPv6 addr for now */
if (prev_active != new_active || prev_index != nexthop->ifindex
/* Update real nexthop. This may actually determine if nexthop is active
* or not. */
- if (!nexthop_active_update(rn, new, 1)) {
+ if (!nexthop_active_update(rn, new, true)) {
UNSET_FLAG(new->status, ROUTE_ENTRY_CHANGED);
return;
}
* down, causing the kernel to delete routes without sending DELROUTE
* notifications
*/
- if (!nexthop_active_update(rn, old, 1) &&
+ if (!nexthop_active_update(rn, old, true) &&
(RIB_KERNEL_ROUTE(old)))
SET_FLAG(old->status, ROUTE_ENTRY_REMOVED);
else
/* Update the nexthop; we could determine here that nexthop is
* inactive. */
- if (nexthop_active_update(rn, new, 1))
+ if (nexthop_active_update(rn, new, true))
nh_active = 1;
/* If nexthop is active, install the selected route, if
/* Update prior route. */
if (new != old) {
/* Set real nexthop. */
- nexthop_active_update(rn, old, 1);
+ nexthop_active_update(rn, old, true);
UNSET_FLAG(old->status, ROUTE_ENTRY_CHANGED);
}
* recursive NHs.
*/
if (!CHECK_FLAG(re->status, ROUTE_ENTRY_CHANGED)
- && !nexthop_active_update(rn, re, 0)) {
+ && !nexthop_active_update(rn, re, false)) {
if (re->type == ZEBRA_ROUTE_TABLE) {
/* XXX: HERE BE DRAGONS!!!!!
* In all honesty, I have not yet figured out
if (old_selected != new_selected || selected_changed) {
if (new_selected && new_selected != new_fib) {
- nexthop_active_update(rn, new_selected, 1);
+ nexthop_active_update(rn, new_selected, true);
UNSET_FLAG(new_selected->status, ROUTE_ENTRY_CHANGED);
}
op = dplane_ctx_get_op(ctx);
status = dplane_ctx_get_status(ctx);
- if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) {
+ if (IS_ZEBRA_DEBUG_DPLANE_DETAIL)
zlog_debug("%u:%s Processing dplane ctx %p, op %s result %s",
dplane_ctx_get_vrf(ctx), dest_str, ctx,
dplane_op2str(op), dplane_res2str(status));
- }
if (op == DPLANE_OP_ROUTE_DELETE) {
/*
zvrf->removals++;
} else {
zsend_route_notify_owner_ctx(ctx,
- ZAPI_ROUTE_FAIL_INSTALL);
+ ZAPI_ROUTE_REMOVE_FAIL);
zlog_warn("%u:%s: Route Deletion failure",
dplane_ctx_get_vrf(ctx),
/* XXX: TODO: These should be runtime configurable via vty */
zebra->ribq->spec.max_retries = 3;
zebra->ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME;
+ zebra->ribq->spec.retry = ZEBRA_RIB_PROCESS_RETRY_TIME;
if (!(zebra->mq = meta_queue_new())) {
flog_err(EC_ZEBRA_WQ_NONEXISTENT,
pthread_mutex_lock(&dplane_mutex);
{
/* Dequeue context block */
- dplane_ctx_dequeue(&rib_dplane_q, &ctx);
+ ctx = dplane_ctx_dequeue(&rib_dplane_q);
}
pthread_mutex_unlock(&dplane_mutex);
* the dataplane pthread. We enqueue the results here for processing by
* the main thread later.
*/
-static int rib_dplane_results(const struct zebra_dplane_ctx *ctx)
+static int rib_dplane_results(struct zebra_dplane_ctx *ctx)
{
/* Take lock controlling queue of results */
pthread_mutex_lock(&dplane_mutex);