summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorclaudio <claudio@openbsd.org>2021-01-13 11:34:01 +0000
committerclaudio <claudio@openbsd.org>2021-01-13 11:34:01 +0000
commitd884cecf431fe69afd233cb7451e7877a4f6ccc0 (patch)
treee8329334f0da05ea2b1bdf9c1d2dd9ca75af6859
parentAdd support for the HYM8563 RTC, which is a PCF8563 clone. (diff)
downloadwireguard-openbsd-d884cecf431fe69afd233cb7451e7877a4f6ccc0.tar.xz
wireguard-openbsd-d884cecf431fe69afd233cb7451e7877a4f6ccc0.zip
Extend prefix_evaluate() to also be used when withdrawing a prefix.
Doing the LIST_REMOVE() outside of prefix_evalute() is no longer valid. As a benefit it is now simply possible to re-evaluate a prefix by passing it to prefix_evaluate() for both removal and insertion. prefix_evaluate() will then take care to ensure that a update is sent out if necessary. Also move rde_send_kroute() call to rde_generate_updates() to make it a bit easier to plug this module into a regress test. OK denis@
-rw-r--r--usr.sbin/bgpd/rde.c8
-rw-r--r--usr.sbin/bgpd/rde.h6
-rw-r--r--usr.sbin/bgpd/rde_decide.c36
-rw-r--r--usr.sbin/bgpd/rde_rib.c23
4 files changed, 33 insertions, 40 deletions
diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c
index 627fcd3b1ea..555eea56575 100644
--- a/usr.sbin/bgpd/rde.c
+++ b/usr.sbin/bgpd/rde.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.c,v 1.511 2021/01/09 16:49:41 claudio Exp $ */
+/* $OpenBSD: rde.c,v 1.512 2021/01/13 11:34:01 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -2825,6 +2825,9 @@ rde_generate_updates(struct rib *rib, struct prefix *new, struct prefix *old)
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_entry *re, void *arg)
/* 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);
}
}
diff --git a/usr.sbin/bgpd/rde.h b/usr.sbin/bgpd/rde.h
index c91594a4584..973d5691a74 100644
--- a/usr.sbin/bgpd/rde.h
+++ b/usr.sbin/bgpd/rde.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.h,v 1.235 2020/12/04 11:57:13 claudio Exp $ */
+/* $OpenBSD: rde.h,v 1.236 2021/01/13 11:34:01 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and
@@ -483,10 +483,10 @@ communities_unref(struct rde_community *comm)
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 *,
diff --git a/usr.sbin/bgpd/rde_decide.c b/usr.sbin/bgpd/rde_decide.c
index 83cfefac77d..56ba45aade4 100644
--- a/usr.sbin/bgpd/rde_decide.c
+++ b/usr.sbin/bgpd/rde_decide.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_decide.c,v 1.78 2019/08/09 13:44:27 claudio Exp $ */
+/* $OpenBSD: rde_decide.c,v 1.79 2021/01/13 11:34:01 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@@ -238,14 +238,16 @@ prefix_cmp(struct prefix *p1, struct prefix *p2)
* 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 rib_entry *re)
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 rib_entry *re)
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;
}
}
diff --git a/usr.sbin/bgpd/rde_rib.c b/usr.sbin/bgpd/rde_rib.c
index a172d3fd8b3..8ec419eb07c 100644
--- a/usr.sbin/bgpd/rde_rib.c
+++ b/usr.sbin/bgpd/rde_rib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_rib.c,v 1.218 2020/12/04 11:57:13 claudio Exp $ */
+/* $OpenBSD: rde_rib.c,v 1.219 2021/01/13 11:34:01 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@@ -1064,8 +1064,7 @@ prefix_move(struct prefix *p, struct rde_peer *peer,
* 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, enum nexthop_state state,
}
/* 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_entry *re, struct rde_peer *peer,
rde_pftable_add(asp->pftableid, p);
/* make route decision */
- prefix_evaluate(p, re);
+ prefix_evaluate(re, p, NULL);
}
/*