summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pbrd/pbr_map.c25
-rw-r--r--pbrd/pbr_map.h3
-rw-r--r--pbrd/pbr_nht.c65
-rw-r--r--pbrd/pbr_nht.h2
-rw-r--r--pbrd/pbr_vty.c6
-rw-r--r--pbrd/pbr_zebra.c1
6 files changed, 100 insertions, 2 deletions
diff --git a/pbrd/pbr_map.c b/pbrd/pbr_map.c
index e37110c1c..b0d1e235f 100644
--- a/pbrd/pbr_map.c
+++ b/pbrd/pbr_map.c
@@ -796,6 +796,31 @@ void pbr_map_check_vrf_nh_group_change(const char *nh_group,
}
}
+void pbr_map_check_interface_nh_group_change(const char *nh_group,
+ struct interface *ifp,
+ ifindex_t oldifindex)
+{
+ struct pbr_map *pbrm;
+ struct pbr_map_sequence *pbrms;
+ struct listnode *node;
+
+ RB_FOREACH (pbrm, pbr_map_entry_head, &pbr_maps) {
+ for (ALL_LIST_ELEMENTS_RO(pbrm->seqnumbers, node, pbrms)) {
+ if (pbrms->nhgrp_name)
+ continue;
+
+ if (pbrms->nhg
+ && strcmp(nh_group, pbrms->internal_nhg_name))
+ continue;
+
+ if (pbrms->nhg->nexthop->ifindex != oldifindex)
+ continue;
+
+ pbrms->nhg->nexthop->ifindex = ifp->ifindex;
+ }
+ }
+}
+
void pbr_map_check(struct pbr_map_sequence *pbrms, bool changed)
{
struct pbr_map *pbrm;
diff --git a/pbrd/pbr_map.h b/pbrd/pbr_map.h
index 850070911..43266f21e 100644
--- a/pbrd/pbr_map.h
+++ b/pbrd/pbr_map.h
@@ -209,4 +209,7 @@ extern void pbr_map_policy_delete(struct pbr_map *pbrm,
extern void pbr_map_check_vrf_nh_group_change(const char *nh_group,
struct pbr_vrf *pbr_vrf,
uint32_t old_vrf_id);
+extern void pbr_map_check_interface_nh_group_change(const char *nh_group,
+ struct interface *ifp,
+ ifindex_t oldifindex);
#endif
diff --git a/pbrd/pbr_nht.c b/pbrd/pbr_nht.c
index e875ea1ce..4d0682300 100644
--- a/pbrd/pbr_nht.c
+++ b/pbrd/pbr_nht.c
@@ -563,6 +563,15 @@ void pbr_nht_add_individual_nexthop(struct pbr_map_sequence *pbrms,
strlcpy(pnhc->vrf_name, vrf->name,
sizeof(pnhc->vrf_name));
}
+
+ if (nhop->ifindex != 0) {
+ struct interface *ifp =
+ if_lookup_by_index(nhop->ifindex, nhop->vrf_id);
+
+ if (ifp)
+ strlcpy(pnhc->intf_name, ifp->name,
+ sizeof(pnhc->intf_name));
+ }
pbr_nht_install_nexthop_group(pnhgc, *pbrms->nhg);
}
@@ -947,6 +956,62 @@ void pbr_nht_vrf_update(struct pbr_vrf *pbr_vrf)
hash_iterate(pbr_nhg_hash, pbr_nht_nexthop_vrf_handle, pbr_vrf);
}
+static void pbr_nht_individual_nexthop_interface_handle(struct hash_bucket *b,
+ void *data)
+{
+ struct pbr_nexthop_cache *pnhc = b->data;
+ struct pbr_nht_individual *pnhi = data;
+
+ if (pnhc->nexthop->ifindex == 0)
+ return;
+
+ if ((strncmp(pnhc->intf_name, pnhi->ifp->name, sizeof(pnhc->intf_name))
+ == 0)
+ && pnhc->nexthop->ifindex != pnhi->ifp->ifindex)
+ pnhi->pnhc = pnhc;
+}
+
+static void pbr_nht_nexthop_interface_handle(struct hash_bucket *b, void *data)
+{
+ struct pbr_nexthop_group_cache *pnhgc = b->data;
+ struct interface *ifp = data;
+ struct pbr_nht_individual pnhi = {};
+ struct nhrc *nhrc;
+ uint32_t old_ifindex;
+
+ do {
+ memset(&pnhi, 0, sizeof(pnhi));
+ pnhi.ifp = ifp;
+ hash_iterate(pnhgc->nhh,
+ pbr_nht_individual_nexthop_interface_handle,
+ &pnhi);
+
+ if (!pnhi.pnhc)
+ continue;
+
+ pnhi.pnhc = hash_release(pnhgc->nhh, pnhi.pnhc);
+ old_ifindex = pnhi.pnhc->nexthop->ifindex;
+
+ nhrc = hash_lookup(pbr_nhrc_hash, pnhi.pnhc->nexthop);
+ if (nhrc) {
+ hash_release(pbr_nhrc_hash, nhrc);
+ nhrc->nexthop.ifindex = ifp->ifindex;
+ hash_get(pbr_nhrc_hash, nhrc, hash_alloc_intern);
+ }
+ pnhi.pnhc->nexthop->ifindex = ifp->ifindex;
+
+ hash_get(pnhgc->nhh, pnhi.pnhc, hash_alloc_intern);
+
+ pbr_map_check_interface_nh_group_change(pnhgc->name, ifp,
+ old_ifindex);
+ } while (pnhi.pnhc);
+}
+
+void pbr_nht_interface_update(struct interface *ifp)
+{
+ hash_iterate(pbr_nhg_hash, pbr_nht_nexthop_interface_handle, ifp);
+}
+
static void
pbr_nht_individual_nexthop_interface_update_lookup(struct hash_bucket *b,
void *data)
diff --git a/pbrd/pbr_nht.h b/pbrd/pbr_nht.h
index d1afbaa73..a1099a00c 100644
--- a/pbrd/pbr_nht.h
+++ b/pbrd/pbr_nht.h
@@ -49,6 +49,7 @@ struct pbr_nexthop_cache {
struct pbr_nexthop_group_cache *parent;
char vrf_name[VRF_NAMSIZ + 1];
+ char intf_name[INTERFACE_NAMSIZ + 1];
struct nexthop *nexthop;
@@ -132,4 +133,5 @@ extern void pbr_nht_nexthop_interface_update(struct interface *ifp);
extern void pbr_nht_init(void);
extern void pbr_nht_vrf_update(struct pbr_vrf *pbr_vrf);
+extern void pbr_nht_interface_update(struct interface *ifp);
#endif
diff --git a/pbrd/pbr_vty.c b/pbrd/pbr_vty.c
index 3ed227dd0..cf9185e7c 100644
--- a/pbrd/pbr_vty.c
+++ b/pbrd/pbr_vty.c
@@ -627,8 +627,6 @@ pbrms_nexthop_group_write_individual_nexthop(
struct pbr_nexthop_cache lookup;
struct pbr_nexthop_cache *pnhc;
- nexthop_group_write_nexthop_simple(vty, pbrms->nhg->nexthop, NULL);
-
memset(&find, 0, sizeof(find));
strlcpy(find.name, pbrms->internal_nhg_name, sizeof(find.name));
@@ -637,6 +635,10 @@ pbrms_nexthop_group_write_individual_nexthop(
lookup.nexthop = pbrms->nhg->nexthop;
pnhc = hash_lookup(pnhgc->nhh, &lookup);
+
+ nexthop_group_write_nexthop_simple(
+ vty, pbrms->nhg->nexthop,
+ pnhc->nexthop->ifindex != 0 ? pnhc->intf_name : NULL);
if (pnhc->nexthop->vrf_id != VRF_DEFAULT)
vty_out(vty, " nexthop-vrf %s", pnhc->vrf_name);
diff --git a/pbrd/pbr_zebra.c b/pbrd/pbr_zebra.c
index d0099a46e..a7420974a 100644
--- a/pbrd/pbr_zebra.c
+++ b/pbrd/pbr_zebra.c
@@ -67,6 +67,7 @@ int pbr_ifp_create(struct interface *ifp)
if (!ifp->info)
pbr_if_new(ifp);
+ pbr_nht_interface_update(ifp);
/* Update nexthops tracked from a `set nexthop` command */
pbr_nht_nexthop_interface_update(ifp);