summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/prefix.c6
-rw-r--r--zebra/zebra_rnh.c17
-rw-r--r--zebra/zebra_rnh.h1
3 files changed, 23 insertions, 1 deletions
diff --git a/lib/prefix.c b/lib/prefix.c
index dbfdc83012..739764842d 100644
--- a/lib/prefix.c
+++ b/lib/prefix.c
@@ -278,6 +278,12 @@ prefix_copy (struct prefix *dest, const struct prefix *src)
int
prefix_same (const struct prefix *p1, const struct prefix *p2)
{
+ if ((p1 && !p2) || (!p1 && p2))
+ return 0;
+
+ if (!p1 && !p2)
+ return 1;
+
if (p1->family == p2->family && p1->prefixlen == p2->prefixlen)
{
if (p1->family == AF_INET)
diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c
index 9b1c978ef7..380d06522b 100644
--- a/zebra/zebra_rnh.c
+++ b/zebra/zebra_rnh.c
@@ -266,6 +266,7 @@ zebra_evaluate_rnh_table (int vrfid, int family, int force)
char bufs[INET6_ADDRSTRLEN];
struct route_node *static_rn;
struct nexthop *nexthop;
+
ntable = lookup_rnh_table(vrfid, family);
if (!ntable)
{
@@ -312,7 +313,21 @@ zebra_evaluate_rnh_table (int vrfid, int family, int force)
state_changed = 0;
- if (compare_state(rib, rnh->state))
+ /* Ensure prefixes we're resolving over have stayed the same */
+ if (!prefix_same(&rnh->resolved_route, &prn->p))
+ {
+ if (rib)
+ UNSET_FLAG(rib->status, RIB_ENTRY_NEXTHOPS_CHANGED);
+
+ if (prn)
+ prefix_copy(&rnh->resolved_route, &prn->p);
+ else
+ memset(&rnh->resolved_route, 0, sizeof(struct prefix));
+
+ copy_state(rnh, rib, nrn);
+ state_changed = 1;
+ }
+ else if (compare_state(rib, rnh->state))
{
if (rib)
UNSET_FLAG(rib->status, RIB_ENTRY_NEXTHOPS_CHANGED);
diff --git a/zebra/zebra_rnh.h b/zebra/zebra_rnh.h
index af56d36aaa..f18679dad3 100644
--- a/zebra/zebra_rnh.h
+++ b/zebra/zebra_rnh.h
@@ -33,6 +33,7 @@ struct rnh
#define ZEBRA_NHT_CONNECTED 0x1
#define ZEBRA_NHT_DELETED 0x2
struct rib *state;
+ struct prefix resolved_route;
struct list *client_list;
struct list *zebra_static_route_list; /* static routes dependent on this NH */
struct route_node *node;