This diff changes two things:
- First, it move the kroute update into rde_generate_updates() simplifying
prefix_evaluate a little bit.
- Second, it changes prefix_evaluate to take an additional argument for the
old prefix (to be removed). Instead of doing this outside of
prefix_evaluate() with some drawbacks in case the same prefix is removed
and readded, the code is now in prefix_evaluate() and does all the magic
itself.
This is a necessary step to finally fix MED sorting.
--
:wq Claudio
Index: rde.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
retrieving revision 1.511
diff -u -p -r1.511 rde.c
--- rde.c 9 Jan 2021 16:49:41 -0000 1.511
+++ rde.c 12 Jan 2021 16:17:31 -0000
@@ -2825,6 +2825,9 @@ rde_generate_updates(struct rib *rib, st
if (old == NULL && new == NULL)
return;
+ if ((rib->flags & F_RIB_NOFIB) == 0)
+ rde_send_kroute(rib, new, old);
+
if (new)
aid = new->pt->aid;
else
@@ -3533,8 +3536,7 @@ rde_softreconfig_sync_reeval(struct rib_
/* need to re-link the nexthop if not already linked */
if ((p->flags & PREFIX_NEXTHOP_LINKED) == 0)
nexthop_link(p);
- LIST_REMOVE(p, entry.list.rib);
- prefix_evaluate(p, re);
+ prefix_evaluate(re, p, p);
}
}
Index: rde.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.h,v
retrieving revision 1.235
diff -u -p -r1.235 rde.h
--- rde.h 4 Dec 2020 11:57:13 -0000 1.235
+++ rde.h 12 Jan 2021 16:17:31 -0000
@@ -483,10 +483,10 @@ communities_unref(struct rde_community *
communities_unlink(comm);
}
-int community_to_rd(struct community *, u_int64_t *);
+int community_to_rd(struct community *, u_int64_t *);
/* rde_decide.c */
-void prefix_evaluate(struct prefix *, struct rib_entry *);
+void prefix_evaluate(struct rib_entry *, struct prefix *, struct prefix *);
/* rde_filter.c */
void rde_apply_set(struct filter_set_head *, struct rde_peer *,
Index: rde_decide.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde_decide.c,v
retrieving revision 1.78
diff -u -p -r1.78 rde_decide.c
--- rde_decide.c 9 Aug 2019 13:44:27 -0000 1.78
+++ rde_decide.c 12 Jan 2021 16:24:36 -0000
@@ -238,14 +238,16 @@ prefix_cmp(struct prefix *p1, struct pre
* The to evaluate prefix must not be in the prefix list.
*/
void
-prefix_evaluate(struct prefix *p, struct rib_entry *re)
+prefix_evaluate(struct rib_entry *re, struct prefix *new, struct prefix *old)
{
struct prefix *xp;
if (re_rib(re)->flags & F_RIB_NOEVALUATE) {
/* decision process is turned off */
- if (p != NULL)
- LIST_INSERT_HEAD(&re->prefix_h, p, entry.list.rib);
+ if (old != NULL)
+ LIST_REMOVE(old, entry.list.rib);
+ if (new != NULL)
+ LIST_INSERT_HEAD(&re->prefix_h, new, entry.list.rib);
if (re->active) {
/*
* During reloads it is possible that the decision
@@ -259,19 +261,22 @@ prefix_evaluate(struct prefix *p, struct
return;
}
- if (p != NULL) {
+ if (old != NULL)
+ LIST_REMOVE(old, entry.list.rib);
+
+ if (new != NULL) {
if (LIST_EMPTY(&re->prefix_h))
- LIST_INSERT_HEAD(&re->prefix_h, p, entry.list.rib);
+ LIST_INSERT_HEAD(&re->prefix_h, new, entry.list.rib);
else {
LIST_FOREACH(xp, &re->prefix_h, entry.list.rib) {
- if (prefix_cmp(p, xp) > 0) {
- LIST_INSERT_BEFORE(xp, p,
+ if (prefix_cmp(new, xp) > 0) {
+ LIST_INSERT_BEFORE(xp, new,
entry.list.rib);
break;
} else if (LIST_NEXT(xp, entry.list.rib) ==
NULL) {
/* if xp last element ... */
- LIST_INSERT_AFTER(xp, p,
+ LIST_INSERT_AFTER(xp, new,
entry.list.rib);
break;
}
@@ -290,18 +295,17 @@ prefix_evaluate(struct prefix *p, struct
xp = NULL;
}
- if (re->active != xp) {
- /* need to generate an update */
-
+ /*
+ * If the active prefix changed or the active prefix was removed
+ * and added again then generate an update.
+ */
+ if (re->active != xp || (old != NULL && xp == old)) {
/*
- * Send update with remove for re->active and add for xp
+ * Send update withdrawing re->active and adding xp
* but remember that xp may be NULL aka ineligible.
* Additional decision may be made by the called functions.
*/
rde_generate_updates(re_rib(re), xp, re->active);
- if ((re_rib(re)->flags & F_RIB_NOFIB) == 0)
- rde_send_kroute(re_rib(re), xp, re->active);
-
re->active = xp;
}
}
Index: rde_rib.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde_rib.c,v
retrieving revision 1.218
diff -u -p -r1.218 rde_rib.c
--- rde_rib.c 4 Dec 2020 11:57:13 -0000 1.218
+++ rde_rib.c 12 Jan 2021 16:17:31 -0000
@@ -1064,8 +1064,7 @@ prefix_move(struct prefix *p, struct rde
* This is safe because we create a new prefix and so the change
* is noticed by prefix_evaluate().
*/
- LIST_REMOVE(p, entry.list.rib);
- prefix_evaluate(np, np->re);
+ prefix_evaluate(np->re, np, p);
/* remove old prefix node */
/* as before peer count needs no update because of move */
@@ -1551,18 +1550,7 @@ prefix_evaluate_all(struct prefix *p, en
}
/* redo the route decision */
- LIST_REMOVE(p, entry.list.rib);
- /*
- * If the prefix is the active one remove it first,
- * this has to be done because we can not detect when
- * the active prefix changes its state. In this case
- * we know that this is a withdrawal and so the second
- * prefix_evaluate() will generate no update because
- * the nexthop is unreachable or ineligible.
- */
- if (p == p->re->active)
- prefix_evaluate(NULL, p->re);
- prefix_evaluate(p, p->re);
+ prefix_evaluate(p->re, p, p);
}
/* kill a prefix. */
@@ -1570,8 +1558,7 @@ void
prefix_destroy(struct prefix *p)
{
/* make route decision */
- LIST_REMOVE(p, entry.list.rib);
- prefix_evaluate(NULL, p->re);
+ prefix_evaluate(p->re, NULL, p);
prefix_unlink(p);
prefix_free(p);
@@ -1601,7 +1588,7 @@ prefix_link(struct prefix *p, struct rib
rde_pftable_add(asp->pftableid, p);
/* make route decision */
- prefix_evaluate(p, re);
+ prefix_evaluate(re, p, NULL);
}
/*