summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/bgpd/rde.c9
-rw-r--r--usr.sbin/bgpd/rde.h14
-rw-r--r--usr.sbin/bgpd/rde_decide.c12
-rw-r--r--usr.sbin/bgpd/rde_peer.c42
-rw-r--r--usr.sbin/bgpd/rde_update.c81
5 files changed, 59 insertions, 99 deletions
diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c
index 3a251628b54..9cb68ef9865 100644
--- a/usr.sbin/bgpd/rde.c
+++ b/usr.sbin/bgpd/rde.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.c,v 1.592 2023/02/09 13:43:23 claudio Exp $ */
+/* $OpenBSD: rde.c,v 1.593 2023/02/13 18:07:53 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -3888,14 +3888,11 @@ rde_softreconfig_in(struct rib_entry *re, void *bula)
static void
rde_softreconfig_out(struct rib_entry *re, void *arg)
{
- struct rib *rib = arg;
- struct prefix *p;
-
- if ((p = prefix_best(re)) == NULL)
+ if (prefix_best(re) == NULL)
/* no valid path for prefix */
return;
- rde_generate_updates(rib, p, NULL, NULL, NULL, EVAL_RECONF);
+ rde_generate_updates(re, NULL, NULL, EVAL_RECONF);
}
static void
diff --git a/usr.sbin/bgpd/rde.h b/usr.sbin/bgpd/rde.h
index 2e996435280..d9f728ae270 100644
--- a/usr.sbin/bgpd/rde.h
+++ b/usr.sbin/bgpd/rde.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.h,v 1.282 2023/02/09 13:43:23 claudio Exp $ */
+/* $OpenBSD: rde.h,v 1.283 2023/02/13 18:07:53 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and
@@ -392,9 +392,6 @@ void rde_pftable_add(uint16_t, struct prefix *);
void rde_pftable_del(uint16_t, struct prefix *);
int rde_evaluate_all(void);
-void rde_generate_updates(struct rib *, struct prefix *,
- struct prefix *, struct prefix *, struct prefix *,
- enum eval_mode);
uint32_t rde_local_as(void);
int rde_decisionflags(void);
void rde_peer_send_rrefresh(struct rde_peer *, uint8_t, uint8_t);
@@ -412,6 +409,9 @@ struct rde_peer *peer_get(uint32_t);
struct rde_peer *peer_match(struct ctl_neighbor *, uint32_t);
struct rde_peer *peer_add(uint32_t, struct peer_config *);
+void rde_generate_updates(struct rib_entry *, struct prefix *,
+ struct prefix *, enum eval_mode);
+
void peer_up(struct rde_peer *, struct session_up *);
void peer_down(struct rde_peer *, void *);
void peer_flush(struct rde_peer *, uint8_t, time_t);
@@ -729,11 +729,11 @@ int nexthop_compare(struct nexthop *, struct nexthop *);
/* rde_update.c */
void up_init(struct rde_peer *);
void up_generate_updates(struct filter_head *, struct rde_peer *,
- struct prefix *, struct prefix *);
+ struct rib_entry *);
void up_generate_addpath(struct filter_head *, struct rde_peer *,
- struct prefix *, struct prefix *);
+ struct rib_entry *);
void up_generate_addpath_all(struct filter_head *,
- struct rde_peer *, struct prefix *, struct prefix *,
+ struct rde_peer *, struct rib_entry *, struct prefix *,
struct prefix *);
void up_generate_default(struct filter_head *, struct rde_peer *,
uint8_t);
diff --git a/usr.sbin/bgpd/rde_decide.c b/usr.sbin/bgpd/rde_decide.c
index b9d7860627b..9f0646703a1 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.98 2022/09/23 15:49:20 claudio Exp $ */
+/* $OpenBSD: rde_decide.c,v 1.99 2023/02/13 18:07:53 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@@ -556,10 +556,9 @@ prefix_evaluate(struct rib_entry *re, struct prefix *new, struct prefix *old)
* but remember that newbest may be NULL aka ineligible.
* Additional decision may be made by the called functions.
*/
- rde_generate_updates(rib, newbest, oldbest, new, old,
- EVAL_DEFAULT);
if ((rib->flags & F_RIB_NOFIB) == 0)
rde_send_kroute(rib, newbest, oldbest);
+ rde_generate_updates(re, new, old, EVAL_DEFAULT);
return;
}
@@ -570,8 +569,7 @@ prefix_evaluate(struct rib_entry *re, struct prefix *new, struct prefix *old)
*/
if (rde_evaluate_all())
if ((new != NULL && prefix_eligible(new)) || old != NULL)
- rde_generate_updates(rib, newbest, NULL, new, old,
- EVAL_ALL);
+ rde_generate_updates(re, new, old, EVAL_ALL);
}
void
@@ -630,9 +628,9 @@ prefix_evaluate_nexthop(struct prefix *p, enum nexthop_state state,
* but remember that newbest may be NULL aka ineligible.
* Additional decision may be made by the called functions.
*/
- rde_generate_updates(rib, newbest, oldbest, p, p, EVAL_DEFAULT);
if ((rib->flags & F_RIB_NOFIB) == 0)
rde_send_kroute(rib, newbest, oldbest);
+ rde_generate_updates(re, p, p, EVAL_DEFAULT);
return;
}
@@ -642,5 +640,5 @@ prefix_evaluate_nexthop(struct prefix *p, enum nexthop_state state,
* rde_generate_updates() will then take care of distribution.
*/
if (rde_evaluate_all())
- rde_generate_updates(rib, newbest, NULL, p, p, EVAL_ALL);
+ rde_generate_updates(re, p, p, EVAL_ALL);
}
diff --git a/usr.sbin/bgpd/rde_peer.c b/usr.sbin/bgpd/rde_peer.c
index 040d1e96ba1..6d58de17301 100644
--- a/usr.sbin/bgpd/rde_peer.c
+++ b/usr.sbin/bgpd/rde_peer.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_peer.c,v 1.28 2023/02/09 13:43:23 claudio Exp $ */
+/* $OpenBSD: rde_peer.c,v 1.29 2023/02/13 18:07:53 claudio Exp $ */
/*
* Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org>
@@ -207,23 +207,13 @@ peer_cmp(struct rde_peer *a, struct rde_peer *b)
RB_GENERATE(peer_tree, rde_peer, entry, peer_cmp);
static void
-peer_generate_update(struct rde_peer *peer, uint16_t rib_id,
- struct prefix *newbest, struct prefix *oldbest,
+peer_generate_update(struct rde_peer *peer, struct rib_entry *re,
struct prefix *newpath, struct prefix *oldpath,
enum eval_mode mode)
{
uint8_t aid;
- if (newbest != NULL)
- aid = newbest->pt->aid;
- else if (oldbest != NULL)
- aid = oldbest->pt->aid;
- else if (newpath != NULL)
- aid = newpath->pt->aid;
- else if (oldpath != NULL)
- aid = oldpath->pt->aid;
- else
- return;
+ aid = re->prefix->aid;
/* skip ourself */
if (peer == peerself)
@@ -231,7 +221,7 @@ peer_generate_update(struct rde_peer *peer, uint16_t rib_id,
if (peer->state != PEER_UP)
return;
/* skip peers using a different rib */
- if (peer->loc_rib_id != rib_id)
+ if (peer->loc_rib_id != re->rib_id)
return;
/* check if peer actually supports the address family */
if (peer->capa.mp[aid] == 0)
@@ -248,37 +238,27 @@ peer_generate_update(struct rde_peer *peer, uint16_t rib_id,
/* handle peers with add-path */
if (peer_has_add_path(peer, aid, CAPA_AP_SEND)) {
if (peer->eval.mode == ADDPATH_EVAL_ALL)
- up_generate_addpath_all(out_rules, peer, newbest,
+ up_generate_addpath_all(out_rules, peer, re,
newpath, oldpath);
else
- up_generate_addpath(out_rules, peer, newbest, oldbest);
+ up_generate_addpath(out_rules, peer, re);
return;
}
/* skip regular peers if the best path didn't change */
if (mode == EVAL_ALL && (peer->flags & PEERFLAG_EVALUATE_ALL) == 0)
return;
- up_generate_updates(out_rules, peer, newbest, oldbest);
+ up_generate_updates(out_rules, peer, re);
}
void
-rde_generate_updates(struct rib *rib, struct prefix *newbest,
- struct prefix *oldbest, struct prefix *newpath, struct prefix *oldpath,
- enum eval_mode mode)
+rde_generate_updates(struct rib_entry *re, struct prefix *newpath,
+ struct prefix *oldpath, enum eval_mode mode)
{
struct rde_peer *peer;
- /*
- * If oldbest is != NULL we know it was active and should be removed.
- * If newbest is != NULL we know it is reachable and then we should
- * generate an update.
- */
- if (oldbest == NULL && newbest == NULL)
- return;
-
RB_FOREACH(peer, peer_tree, &peertable)
- peer_generate_update(peer, rib->id, newbest, oldbest, newpath,
- oldpath, mode);
+ peer_generate_update(peer, re, newpath, oldpath, mode);
}
/*
@@ -389,7 +369,7 @@ rde_up_dump_upcall(struct rib_entry *re, void *ptr)
if ((p = prefix_best(re)) == NULL)
/* no eligible prefix, not even for 'evaluate all' */
return;
- peer_generate_update(peer, re->rib_id, p, NULL, NULL, NULL, 0);
+ peer_generate_update(peer, re, NULL, NULL, 0);
}
static void
diff --git a/usr.sbin/bgpd/rde_update.c b/usr.sbin/bgpd/rde_update.c
index 60437202312..808c5c728ff 100644
--- a/usr.sbin/bgpd/rde_update.c
+++ b/usr.sbin/bgpd/rde_update.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_update.c,v 1.155 2023/02/11 08:50:43 claudio Exp $ */
+/* $OpenBSD: rde_update.c,v 1.156 2023/02/13 18:07:53 claudio Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@@ -206,22 +206,18 @@ up_process_prefix(struct filter_head *rules, struct rde_peer *peer,
void
up_generate_updates(struct filter_head *rules, struct rde_peer *peer,
- struct prefix *new, struct prefix *old)
+ struct rib_entry *re)
{
struct bgpd_addr addr;
- struct prefix *p;
+ struct prefix *new, *p;
uint8_t prefixlen;
- if (new == NULL) {
- pt_getaddr(old->pt, &addr);
- prefixlen = old->pt->prefixlen;
- } else {
- pt_getaddr(new->pt, &addr);
- prefixlen = new->pt->prefixlen;
- }
+ pt_getaddr(re->prefix, &addr);
+ prefixlen = re->prefix->prefixlen;
p = prefix_adjout_lookup(peer, &addr, prefixlen);
+ new = prefix_best(re);
while (new != NULL) {
switch (up_process_prefix(rules, peer, new, p,
&addr, prefixlen)) {
@@ -255,21 +251,16 @@ done:
*/
void
up_generate_addpath(struct filter_head *rules, struct rde_peer *peer,
- struct prefix *new, struct prefix *old)
+ struct rib_entry *re)
{
struct bgpd_addr addr;
- struct prefix *head, *p;
+ struct prefix *head, *new, *p;
uint8_t prefixlen;
int maxpaths = 0, extrapaths = 0, extra;
int checkmode = 1;
- if (new == NULL) {
- pt_getaddr(old->pt, &addr);
- prefixlen = old->pt->prefixlen;
- } else {
- pt_getaddr(new->pt, &addr);
- prefixlen = new->pt->prefixlen;
- }
+ pt_getaddr(re->prefix, &addr);
+ prefixlen = re->prefix->prefixlen;
head = prefix_adjout_lookup(peer, &addr, prefixlen);
@@ -278,11 +269,8 @@ up_generate_addpath(struct filter_head *rules, struct rde_peer *peer,
p->flags |= PREFIX_FLAG_STALE;
/* update paths */
- for ( ; new != NULL; new = TAILQ_NEXT(new, entry.list.rib)) {
- /* since list is sorted, stop at first invalid prefix */
- if (!prefix_eligible(new))
- break;
-
+ new = prefix_best(re);
+ while (new != NULL) {
/* check limits and stop when a limit is reached */
if (peer->eval.maxpaths != 0 &&
maxpaths >= peer->eval.maxpaths)
@@ -337,6 +325,11 @@ up_generate_addpath(struct filter_head *rules, struct rde_peer *peer,
/* just give up */
return;
}
+
+ /* only allow valid prefixes */
+ new = TAILQ_NEXT(new, entry.list.rib);
+ if (new == NULL || !prefix_eligible(new))
+ break;
}
/* withdraw stale paths */
@@ -352,55 +345,39 @@ up_generate_addpath(struct filter_head *rules, struct rde_peer *peer,
*/
void
up_generate_addpath_all(struct filter_head *rules, struct rde_peer *peer,
- struct prefix *best, struct prefix *new, struct prefix *old)
+ struct rib_entry *re, struct prefix *new, struct prefix *old)
{
struct bgpd_addr addr;
- struct prefix *p, *next, *head = NULL;
+ struct prefix *p, *head = NULL;
uint8_t prefixlen;
int all = 0;
+ pt_getaddr(re->prefix, &addr);
+ prefixlen = re->prefix->prefixlen;
+
/*
* if old and new are NULL then insert all prefixes from best,
* clearing old routes in the process
*/
if (old == NULL && new == NULL) {
/* mark all paths as stale */
- pt_getaddr(best->pt, &addr);
- prefixlen = best->pt->prefixlen;
-
head = prefix_adjout_lookup(peer, &addr, prefixlen);
for (p = head; p != NULL; p = prefix_adjout_next(peer, p))
p->flags |= PREFIX_FLAG_STALE;
- new = best;
+ new = prefix_best(re);
all = 1;
}
if (old != NULL) {
/* withdraw stale paths */
- pt_getaddr(old->pt, &addr);
- p = prefix_adjout_get(peer, old->path_id_tx, &addr,
- old->pt->prefixlen);
+ p = prefix_adjout_get(peer, old->path_id_tx, &addr, prefixlen);
if (p != NULL)
prefix_adjout_withdraw(p);
}
- if (new != NULL) {
- pt_getaddr(new->pt, &addr);
- prefixlen = new->pt->prefixlen;
- }
-
/* add new path (or multiple if all is set) */
- for (; new != NULL; new = next) {
- if (all)
- next = TAILQ_NEXT(new, entry.list.rib);
- else
- next = NULL;
-
- /* only allow valid prefixes */
- if (!prefix_eligible(new))
- break;
-
+ while (new != NULL) {
switch (up_process_prefix(rules, peer, new, (void *)-1,
&addr, prefixlen)) {
case UP_OK:
@@ -411,6 +388,14 @@ up_generate_addpath_all(struct filter_head *rules, struct rde_peer *peer,
/* just give up */
return;
}
+
+ if (!all)
+ break;
+
+ /* only allow valid prefixes */
+ new = TAILQ_NEXT(new, entry.list.rib);
+ if (new == NULL || !prefix_eligible(new))
+ break;
}
if (all) {