zebra_route_string(client->proto),
rnh_str(rnh, buf, sizeof(buf)), type);
}
zebra_route_string(client->proto),
rnh_str(rnh, buf, sizeof(buf)), type);
}
- send_client(rnh, client, type, vrf_id);
- }
+
+ /*
+ * We always need to respond with known information,
+ * currently multiple daemons expect this behavior
+ */
+ send_client(rnh, client, type, vrf_id);
addr2hostprefix(pw->af, &pw->nexthop, &nh);
rnh = zebra_add_rnh(&nh, vrf_id, RNH_NEXTHOP_TYPE, &exists);
if (rnh && !listnode_lookup(rnh->zebra_pseudowire_list, pw)) {
listnode_add(rnh->zebra_pseudowire_list, pw);
pw->rnh = rnh;
addr2hostprefix(pw->af, &pw->nexthop, &nh);
rnh = zebra_add_rnh(&nh, vrf_id, RNH_NEXTHOP_TYPE, &exists);
if (rnh && !listnode_lookup(rnh->zebra_pseudowire_list, pw)) {
listnode_add(rnh->zebra_pseudowire_list, pw);
pw->rnh = rnh;
- zebra_evaluate_rnh(vrf_id, pw->af, 1, RNH_NEXTHOP_TYPE, &nh);
+ zebra_evaluate_rnh(zvrf, pw->af, 1, RNH_NEXTHOP_TYPE, &nh);
-static int zebra_rnh_apply_nht_rmap(int family, struct route_node *prn,
+static int zebra_rnh_apply_nht_rmap(int family, struct zebra_vrf *zvrf,
+ struct route_node *prn,
- ret = zebra_nht_route_map_check(rmap_family, proto,
- &prn->p, re, nexthop);
+ ret = zebra_nht_route_map_check(
+ rmap_family, proto, &prn->p, zvrf, re, nexthop);
if (ret != RMAP_DENYMATCH) {
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
at_least_one++; /* at least one valid NH */
if (ret != RMAP_DENYMATCH) {
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
at_least_one++; /* at least one valid NH */
-static void zebra_rnh_notify_protocol_clients(vrf_id_t vrfid, int family,
- struct route_node *nrn,
- struct rnh *rnh,
- struct route_node *prn,
- struct route_entry *re)
+static void zebra_rnh_notify_protocol_clients(
+ struct zebra_vrf *zvrf, int family, struct route_node *nrn,
+ struct rnh *rnh, struct route_node *prn, struct route_entry *re)
prefix2str(&nrn->p, bufn, INET6_ADDRSTRLEN);
if (prn && re) {
prefix2str(&prn->p, bufp, INET6_ADDRSTRLEN);
prefix2str(&nrn->p, bufn, INET6_ADDRSTRLEN);
if (prn && re) {
prefix2str(&prn->p, bufp, INET6_ADDRSTRLEN);
- zlog_debug("%u:%s: NH resolved over route %s", vrfid,
- bufn, bufp);
+ zlog_debug("%u:%s: NH resolved over route %s",
+ zvrf->vrf->vrf_id, bufn, bufp);
- zlog_debug("%u:%s: NH has become unresolved", vrfid,
- bufn);
+ zlog_debug("%u:%s: NH has become unresolved",
+ zvrf->vrf->vrf_id, bufn);
- family, prn, re, client->proto);
+ family, zvrf, prn, re, client->proto);
- send_client(rnh, client, RNH_NEXTHOP_TYPE, vrfid);
+ send_client(rnh, client, RNH_NEXTHOP_TYPE, zvrf->vrf->vrf_id);
- zns = zebra_ns_lookup(NS_DEFAULT);
- RB_FOREACH (znst, zebra_ns_table_head, &zns->ns_tables) {
- if (afi != znst->afi)
+ RB_FOREACH (zrt, zebra_router_table_head, &zrouter.tables) {
+ if (afi != zrt->afi)
RNODE_FOREACH_RE (o_rn, o_re) {
if (o_re->type == ZEBRA_ROUTE_PBR)
break;
RNODE_FOREACH_RE (o_rn, o_re) {
if (o_re->type == ZEBRA_ROUTE_PBR)
break;
+/*
+ * Utility to determine whether a candidate nexthop is useable. We make this
+ * check in a couple of places, so this is a single home for the logic we
+ * use.
+ */
+static bool rnh_nexthop_valid(const struct nexthop *nh)
+{
+ return (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_FIB)
+ && CHECK_FLAG(nh->flags, NEXTHOP_FLAG_ACTIVE));
+}
+
struct route_node *nrn, struct rnh *rnh,
struct route_node **prn)
{
struct route_table *route_table;
struct route_node *rn;
struct route_entry *re;
struct route_node *nrn, struct rnh *rnh,
struct route_node **prn)
{
struct route_table *route_table;
struct route_node *rn;
struct route_entry *re;
+ /* Just being SELECTED isn't quite enough - must
+ * have an installed nexthop to be useful.
+ */
+ for (ALL_NEXTHOPS(re->ng, nexthop)) {
+ if (rnh_nexthop_valid(nexthop))
+ break;
+ }
+
+ if (nexthop == NULL)
+ continue;
+
if (CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)) {
if ((re->type == ZEBRA_ROUTE_CONNECT)
|| (re->type == ZEBRA_ROUTE_STATIC))
break;
if (re->type == ZEBRA_ROUTE_NHRP) {
if (CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)) {
if ((re->type == ZEBRA_ROUTE_CONNECT)
|| (re->type == ZEBRA_ROUTE_STATIC))
break;
if (re->type == ZEBRA_ROUTE_NHRP) {
* take appropriate action; this involves notifying any clients and/or
* scheduling dependent static routes for processing.
*/
* take appropriate action; this involves notifying any clients and/or
* scheduling dependent static routes for processing.
*/
-static void zebra_rnh_eval_nexthop_entry(vrf_id_t vrfid, int family, int force,
- struct route_node *nrn,
+static void zebra_rnh_eval_nexthop_entry(struct zebra_vrf *zvrf, int family,
+ int force, struct route_node *nrn,
- zebra_rnh_notify_protocol_clients(vrfid, family, nrn, rnh, prn,
+ zebra_rnh_notify_protocol_clients(zvrf, family, nrn, rnh, prn,
- zebra_rnh_process_pbr_tables(family, nrn, rnh, prn,
- rnh->state);
+ zebra_rnh_process_pbr_tables(family, nrn, rnh, prn, rnh->state);
-static void zebra_rnh_evaluate_entry(vrf_id_t vrfid, int family, int force,
- rnh_type_t type, struct route_node *nrn)
+static void zebra_rnh_evaluate_entry(struct zebra_vrf *zvrf, int family,
+ int force, rnh_type_t type,
+ struct route_node *nrn)
if (IS_ZEBRA_DEBUG_NHT) {
prefix2str(&nrn->p, bufn, INET6_ADDRSTRLEN);
if (IS_ZEBRA_DEBUG_NHT) {
prefix2str(&nrn->p, bufn, INET6_ADDRSTRLEN);
- zlog_debug("%u:%s: Evaluate RNH, type %d %s", vrfid, bufn, type,
- force ? "(force)" : "");
+ zlog_debug("%u:%s: Evaluate RNH, type %d %s", zvrf->vrf->vrf_id,
+ bufn, type, force ? "(force)" : "");
- re = zebra_rnh_resolve_import_entry(vrfid, family, nrn, rnh,
+ re = zebra_rnh_resolve_import_entry(zvrf, family, nrn, rnh,
- re = zebra_rnh_resolve_nexthop_entry(vrfid, family, nrn, rnh,
+ re = zebra_rnh_resolve_nexthop_entry(zvrf, family, nrn, rnh,
- zebra_rnh_eval_import_check_entry(vrfid, family, force, nrn,
- rnh, re);
+ zebra_rnh_eval_import_check_entry(zvrf->vrf->vrf_id, family,
+ force, nrn, rnh, re);
- zebra_rnh_eval_nexthop_entry(vrfid, family, force, nrn, rnh,
- prn, re);
+ zebra_rnh_eval_nexthop_entry(zvrf, family, force, nrn, rnh, prn,
+ re);
- re = zebra_rnh_resolve_import_entry(vrfid, family, nrn, rnh,
+ re = zebra_rnh_resolve_import_entry(zvrf, family, nrn, rnh,
- re = zebra_rnh_resolve_nexthop_entry(vrfid, family, nrn, rnh,
+ re = zebra_rnh_resolve_nexthop_entry(zvrf, family, nrn, rnh,
/* Evaluate all tracked entries (nexthops or routes for import into BGP)
* of a particular VRF and address-family or a specific prefix.
*/
/* Evaluate all tracked entries (nexthops or routes for import into BGP)
* of a particular VRF and address-family or a specific prefix.
*/
-void zebra_evaluate_rnh(vrf_id_t vrfid, int family, int force, rnh_type_t type,
- struct prefix *p)
+void zebra_evaluate_rnh(struct zebra_vrf *zvrf, int family, int force,
+ rnh_type_t type, struct prefix *p)
/* Evaluating a specific entry, make sure it exists. */
nrn = route_node_lookup(rnh_table, p);
if (nrn && nrn->info)
/* Evaluating a specific entry, make sure it exists. */
nrn = route_node_lookup(rnh_table, p);
if (nrn && nrn->info)
- zebra_rnh_evaluate_entry(vrfid, family, force, type,
+ zebra_rnh_evaluate_entry(zvrf, family, force, type,
- zebra_rnh_evaluate_entry(vrfid, family, force,
+ zebra_rnh_evaluate_entry(zvrf, family, force,
- zebra_rnh_clear_nhc_flag(vrfid, family, type,
+ zebra_rnh_clear_nhc_flag(zvrf, family, type,
- for (nh = re->ng.nexthop; nh; nh = nh->next)
- if ((CHECK_FLAG(nh->flags, NEXTHOP_FLAG_FIB)
- || CHECK_FLAG(nh->flags, NEXTHOP_FLAG_RECURSIVE))
- && CHECK_FLAG(nh->flags, NEXTHOP_FLAG_ACTIVE)) {
+ for (ALL_NEXTHOPS(re->ng, nh))
+ if (rnh_nexthop_valid(nh)) {
+ stream_putl(s, nh->vrf_id);