static void print_rnh(struct route_node *rn, struct vty *vty);
static int zebra_client_cleanup_rnh(struct zserv *client);
-int zebra_rnh_ip_default_route = 0;
-int zebra_rnh_ipv6_default_route = 0;
-
void zebra_rnh_init(void)
{
hook_register(zserv_client_close, zebra_client_cleanup_rnh);
break;
default:
memset(prefix, 0, sizeof(*prefix));
- zlog_debug("%s: unknown address family %d", __func__, af);
+ zlog_warn("%s: unknown address family %d", __func__, af);
break;
}
}
struct nexthop *nexthop;
if (re) {
- for (nexthop = re->ng.nexthop; nexthop;
+ for (nexthop = re->nhe->nhg->nexthop; nexthop;
nexthop = nexthop->next) {
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_RNH_FILTERED);
}
route_map_result_t ret;
if (prn && re) {
- for (nexthop = re->ng.nexthop; nexthop;
+ for (nexthop = re->nhe->nhg->nexthop; nexthop;
nexthop = nexthop->next) {
ret = zebra_nht_route_map_check(
afi, proto, &prn->p, zvrf, re, nexthop);
* match route to be exact if so specified
*/
if (is_default_prefix(&rn->p)
- && !rnh_resolve_via_default(rn->p.family)) {
+ && !rnh_resolve_via_default(zvrf, rn->p.family)) {
if (IS_ZEBRA_DEBUG_NHT_DETAILED)
zlog_debug(
"\tNot allowed to resolve through default prefix");
/* Just being SELECTED isn't quite enough - must
* have an installed nexthop to be useful.
*/
- for (ALL_NEXTHOPS(re->ng, nexthop)) {
+ for (ALL_NEXTHOPS_PTR(re->nhe->nhg, nexthop)) {
if (rnh_nexthop_valid(re, nexthop))
break;
}
break;
if (re->type == ZEBRA_ROUTE_NHRP) {
- for (nexthop = re->ng.nexthop; nexthop;
+ for (nexthop = re->nhe->nhg->nexthop;
+ nexthop;
nexthop = nexthop->next)
if (nexthop->type
== NEXTHOP_TYPE_IFINDEX)
re = zebra_rnh_resolve_nexthop_entry(zvrf, afi, nrn, rnh,
&prn);
- if (re) {
- UNSET_FLAG(re->status, ROUTE_ENTRY_NEXTHOPS_CHANGED);
+ if (re)
UNSET_FLAG(re->status, ROUTE_ENTRY_LABELS_CHANGED);
- }
}
/* Evaluate all tracked entries (nexthops or routes for import into BGP)
table = get_rnh_table(vrfid, afi, type);
if (!table) {
- zlog_debug("print_rnhs: rnh table not found");
+ if (IS_ZEBRA_DEBUG_NHT)
+ zlog_debug("print_rnhs: rnh table not found");
return;
}
for (rn = route_top(table); rn; rn = route_next(rn)) {
- if (p && prefix_cmp(&rn->p, p) != 0)
+ if (p && !prefix_match(&rn->p, p))
continue;
if (rn->info)
return;
/* free RE and nexthops */
- nexthops_free(re->ng.nexthop);
+ zebra_nhg_free(re->nhe);
XFREE(MTYPE_RE, re);
}
state->vrf_id = re->vrf_id;
state->status = re->status;
- route_entry_copy_nexthops(state, re->ng.nexthop);
+ state->nhe = zebra_nhg_alloc();
+ state->nhe->nhg = nexthop_group_new();
+
+ nexthop_group_copy(state->nhe->nhg, re->nhe->nhg);
rnh->state = state;
}
if (r1->metric != r2->metric)
return 1;
- if (r1->nexthop_num != r2->nexthop_num)
+ if (nexthop_group_nexthop_num(r1->nhe->nhg)
+ != nexthop_group_nexthop_num(r2->nhe->nhg))
return 1;
- if (nexthop_group_hash(&r1->ng) != nexthop_group_hash(&r2->ng))
+ if (nexthop_group_hash(r1->nhe->nhg) !=
+ nexthop_group_hash(r2->nhe->nhg))
return 1;
return 0;
break;
}
if (re) {
+ struct zapi_nexthop znh;
+
stream_putc(s, re->type);
stream_putw(s, re->instance);
stream_putc(s, re->distance);
num = 0;
nump = stream_get_endp(s);
stream_putc(s, 0);
- for (ALL_NEXTHOPS(re->ng, nh))
+ for (ALL_NEXTHOPS_PTR(re->nhe->nhg, nh))
if (rnh_nexthop_valid(re, nh)) {
- stream_putl(s, nh->vrf_id);
- stream_putc(s, nh->type);
- switch (nh->type) {
- case NEXTHOP_TYPE_IPV4:
- case NEXTHOP_TYPE_IPV4_IFINDEX:
- stream_put_in_addr(s, &nh->gate.ipv4);
- stream_putl(s, nh->ifindex);
- break;
- case NEXTHOP_TYPE_IFINDEX:
- stream_putl(s, nh->ifindex);
- break;
- case NEXTHOP_TYPE_IPV6:
- case NEXTHOP_TYPE_IPV6_IFINDEX:
- stream_put(s, &nh->gate.ipv6, 16);
- stream_putl(s, nh->ifindex);
- break;
- default:
- /* do nothing */
- break;
- }
- if (nh->nh_label) {
- stream_putc(s,
- nh->nh_label->num_labels);
- if (nh->nh_label->num_labels)
- stream_put(
- s,
- &nh->nh_label->label[0],
- nh->nh_label->num_labels
- * sizeof(mpls_label_t));
- } else
- stream_putc(s, 0);
+ zapi_nexthop_from_nexthop(&znh, nh);
+ zapi_nexthop_encode(s, &znh, 0 /* flags */);
num++;
}
stream_putc_at(s, nump, num);
if (rnh->state) {
vty_out(vty, " resolved via %s\n",
zebra_route_string(rnh->state->type));
- for (nexthop = rnh->state->ng.nexthop; nexthop;
+ for (nexthop = rnh->state->nhe->nhg->nexthop; nexthop;
nexthop = nexthop->next)
print_nh(nexthop, vty);
} else
RNH_IMPORT_CHECK_TYPE);
zebra_cleanup_rnh_client(zvrf_id(zvrf), AFI_IP6, client,
RNH_IMPORT_CHECK_TYPE);
- if (client->proto == ZEBRA_ROUTE_LDP) {
- hash_iterate(zvrf->lsp_table,
- mpls_ldp_lsp_uninstall_all,
- zvrf->lsp_table);
- mpls_ldp_ftn_uninstall_all(zvrf, AFI_IP);
- mpls_ldp_ftn_uninstall_all(zvrf, AFI_IP6);
- }
}
}
return 0;
}
+
+int rnh_resolve_via_default(struct zebra_vrf *zvrf, int family)
+{
+ if (((family == AF_INET) && zvrf->zebra_rnh_ip_default_route)
+ || ((family == AF_INET6) && zvrf->zebra_rnh_ipv6_default_route))
+ return 1;
+ else
+ return 0;
+}