summaryrefslogtreecommitdiff
path: root/zebra/zebra_rnh.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/zebra_rnh.c')
-rw-r--r--zebra/zebra_rnh.c53
1 files changed, 40 insertions, 13 deletions
diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c
index 8ca25359be..7934a9d206 100644
--- a/zebra/zebra_rnh.c
+++ b/zebra/zebra_rnh.c
@@ -132,13 +132,13 @@ static void zebra_rnh_store_in_routing_table(struct rnh *rnh)
route_unlock_node(rn);
}
-struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, bool *exists)
+struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, safi_t safi,
+ bool *exists)
{
struct route_table *table;
struct route_node *rn;
struct rnh *rnh = NULL;
afi_t afi = family2afi(p->family);
- safi_t safi = SAFI_UNICAST;
if (IS_ZEBRA_DEBUG_NHT) {
struct vrf *vrf = vrf_lookup_by_id(vrfid);
@@ -345,7 +345,7 @@ void zebra_register_rnh_pseudowire(vrf_id_t vrf_id, struct zebra_pw *pw,
return;
addr2hostprefix(pw->af, &pw->nexthop, &nh);
- rnh = zebra_add_rnh(&nh, vrf_id, &exists);
+ rnh = zebra_add_rnh(&nh, vrf_id, SAFI_UNICAST, &exists);
if (!rnh)
return;
@@ -768,7 +768,7 @@ static void zebra_rnh_clear_nhc_flag(struct zebra_vrf *zvrf, afi_t afi,
* of a particular VRF and address-family or a specific prefix.
*/
void zebra_evaluate_rnh(struct zebra_vrf *zvrf, afi_t afi, int force,
- struct prefix *p, safi_t safi)
+ const struct prefix *p, safi_t safi)
{
struct route_table *rnh_table;
struct route_node *nrn;
@@ -802,13 +802,13 @@ void zebra_evaluate_rnh(struct zebra_vrf *zvrf, afi_t afi, int force,
}
}
-void zebra_print_rnh_table(vrf_id_t vrfid, afi_t afi, struct vty *vty,
- struct prefix *p)
+void zebra_print_rnh_table(vrf_id_t vrfid, afi_t afi, safi_t safi,
+ struct vty *vty, const struct prefix *p)
{
struct route_table *table;
struct route_node *rn;
- table = get_rnh_table(vrfid, afi, SAFI_UNICAST);
+ table = get_rnh_table(vrfid, afi, safi);
if (!table) {
if (IS_ZEBRA_DEBUG_NHT)
zlog_debug("print_rnhs: rnh table not found");
@@ -1169,15 +1169,17 @@ int zebra_send_rnh_update(struct rnh *rnh, struct zserv *client,
SET_FLAG(message, ZAPI_MESSAGE_SRTE);
stream_putl(s, message);
+ /*
+ * Put what we were told to match against
+ */
stream_putw(s, rnh->safi);
stream_putw(s, rn->p.family);
+ stream_putc(s, rn->p.prefixlen);
switch (rn->p.family) {
case AF_INET:
- stream_putc(s, rn->p.prefixlen);
stream_put_in_addr(s, &rn->p.u.prefix4);
break;
case AF_INET6:
- stream_putc(s, rn->p.prefixlen);
stream_put(s, &rn->p.u.prefix6, IPV6_MAX_BYTELEN);
break;
default:
@@ -1186,6 +1188,26 @@ int zebra_send_rnh_update(struct rnh *rnh, struct zserv *client,
__func__, rn->p.family);
goto failure;
}
+
+ /*
+ * What we matched against
+ */
+ stream_putw(s, rnh->resolved_route.family);
+ stream_putc(s, rnh->resolved_route.prefixlen);
+ switch (rnh->resolved_route.family) {
+ case AF_INET:
+ stream_put_in_addr(s, &rnh->resolved_route.u.prefix4);
+ break;
+ case AF_INET6:
+ stream_put(s, &rnh->resolved_route.u.prefix6, IPV6_MAX_BYTELEN);
+ break;
+ default:
+ flog_err(EC_ZEBRA_RNH_UNKNOWN_FAMILY,
+ "%s: Unknown family (%d) notification attempted",
+ __func__, rn->p.family);
+ goto failure;
+ }
+
if (srte_color)
stream_putl(s, srte_color);
@@ -1315,7 +1337,7 @@ static void print_rnh(struct route_node *rn, struct vty *vty)
vty_out(vty, "\n");
}
-static int zebra_cleanup_rnh_client(vrf_id_t vrf_id, afi_t afi,
+static int zebra_cleanup_rnh_client(vrf_id_t vrf_id, afi_t afi, safi_t safi,
struct zserv *client)
{
struct route_table *ntable;
@@ -1330,7 +1352,7 @@ static int zebra_cleanup_rnh_client(vrf_id_t vrf_id, afi_t afi,
zebra_route_string(client->proto), afi2str(afi));
}
- ntable = get_rnh_table(vrf_id, afi, SAFI_UNICAST);
+ ntable = get_rnh_table(vrf_id, afi, safi);
if (!ntable) {
zlog_debug("cleanup_rnh_client: rnh table not found");
return -1;
@@ -1355,9 +1377,14 @@ static int zebra_client_cleanup_rnh(struct zserv *client)
RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
zvrf = vrf->info;
if (zvrf) {
- zebra_cleanup_rnh_client(zvrf_id(zvrf), AFI_IP, client);
+ zebra_cleanup_rnh_client(zvrf_id(zvrf), AFI_IP,
+ SAFI_UNICAST, client);
+ zebra_cleanup_rnh_client(zvrf_id(zvrf), AFI_IP,
+ SAFI_MULTICAST, client);
+ zebra_cleanup_rnh_client(zvrf_id(zvrf), AFI_IP6,
+ SAFI_UNICAST, client);
zebra_cleanup_rnh_client(zvrf_id(zvrf), AFI_IP6,
- client);
+ SAFI_MULTICAST, client);
}
}