summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2023-03-29 10:46:12 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2023-03-29 10:46:12 +0000
commit3f7868cd9c2358472c23a0e307d6b9833a5bdbf8 (patch)
tree64548c44170a0b248979c2f7b416856dff20b861 /usr.sbin
parent2d13231dc82b6c942a0c53a9b0a53336a1cf99ba (diff)
Switch prefix_adjout_get and new prefix_adjout_first to use a pt_entry
as argument instead of the bgpd_addr + prefixlen. Do the same with prefix_adjout_update but leave prefix_adjout_lookup and prefix_adjout_match since those are used by bgpctl code that does not use pt_entry structs. With this most of the update code no longer needs struct bgpd_addr and pt_getaddr(). OK tb@
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/bgpd/rde.h13
-rw-r--r--usr.sbin/bgpd/rde_rib.c35
-rw-r--r--usr.sbin/bgpd/rde_update.c61
3 files changed, 50 insertions, 59 deletions
diff --git a/usr.sbin/bgpd/rde.h b/usr.sbin/bgpd/rde.h
index 1d6abfcd1e7..cd33d5f2b1b 100644
--- a/usr.sbin/bgpd/rde.h
+++ b/usr.sbin/bgpd/rde.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.h,v 1.288 2023/03/28 15:17:34 claudio Exp $ */
+/* $OpenBSD: rde.h,v 1.289 2023/03/29 10:46:11 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and
@@ -580,19 +580,20 @@ void path_put(struct rde_aspath *);
struct prefix *prefix_get(struct rib *, struct rde_peer *, uint32_t,
struct bgpd_addr *, int);
struct prefix *prefix_adjout_get(struct rde_peer *, uint32_t,
- struct bgpd_addr *, int);
-struct prefix *prefix_match(struct rde_peer *, struct bgpd_addr *);
-struct prefix *prefix_adjout_match(struct rde_peer *, struct bgpd_addr *);
+ struct pt_entry *);
+struct prefix *prefix_adjout_first(struct rde_peer *, struct pt_entry *);
+struct prefix *prefix_adjout_next(struct rde_peer *, struct prefix *);
struct prefix *prefix_adjout_lookup(struct rde_peer *, struct bgpd_addr *,
int);
-struct prefix *prefix_adjout_next(struct rde_peer *, struct prefix *);
+struct prefix *prefix_adjout_match(struct rde_peer *, struct bgpd_addr *);
+struct prefix *prefix_match(struct rde_peer *, struct bgpd_addr *);
int prefix_update(struct rib *, struct rde_peer *, uint32_t,
uint32_t, struct filterstate *, struct bgpd_addr *, int);
int prefix_withdraw(struct rib *, struct rde_peer *, uint32_t,
struct bgpd_addr *, int);
void prefix_add_eor(struct rde_peer *, uint8_t);
void prefix_adjout_update(struct prefix *, struct rde_peer *,
- struct filterstate *, struct bgpd_addr *, int, uint32_t);
+ struct filterstate *, struct pt_entry *, uint32_t);
void prefix_adjout_withdraw(struct prefix *);
void prefix_adjout_destroy(struct prefix *);
void prefix_adjout_dump(struct rde_peer *, void *,
diff --git a/usr.sbin/bgpd/rde_rib.c b/usr.sbin/bgpd/rde_rib.c
index bc4ae021540..99c7119f7a3 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.256 2023/03/28 15:17:34 claudio Exp $ */
+/* $OpenBSD: rde_rib.c,v 1.257 2023/03/29 10:46:11 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@@ -873,12 +873,12 @@ prefix_get(struct rib *rib, struct rde_peer *peer, uint32_t path_id,
*/
struct prefix *
prefix_adjout_get(struct rde_peer *peer, uint32_t path_id_tx,
- struct bgpd_addr *prefix, int prefixlen)
+ struct pt_entry *pte)
{
struct prefix xp;
memset(&xp, 0, sizeof(xp));
- xp.pt = pt_fill(prefix, prefixlen);
+ xp.pt = pte;
xp.path_id_tx = path_id_tx;
return RB_FIND(prefix_index, &peer->adj_rib_out, &xp);
@@ -889,13 +889,12 @@ prefix_adjout_get(struct rde_peer *peer, uint32_t path_id_tx,
* Returns NULL if not found.
*/
struct prefix *
-prefix_adjout_lookup(struct rde_peer *peer, struct bgpd_addr *prefix,
- int prefixlen)
+prefix_adjout_first(struct rde_peer *peer, struct pt_entry *pte)
{
struct prefix xp, *np;
memset(&xp, 0, sizeof(xp));
- xp.pt = pt_fill(prefix, prefixlen);
+ xp.pt = pte;
np = RB_NFIND(prefix_index, &peer->adj_rib_out, &xp);
if (np == NULL || pt_prefix_cmp(np->pt, xp.pt) != 0)
@@ -918,6 +917,16 @@ prefix_adjout_next(struct rde_peer *peer, struct prefix *p)
}
/*
+ * Lookup addr/prefixlen in the peer prefix_index. Returns first match.
+ * Returns NULL if not found.
+ */
+struct prefix *
+prefix_adjout_lookup(struct rde_peer *peer, struct bgpd_addr *addr, int plen)
+{
+ return prefix_adjout_first(peer, pt_fill(addr, plen));
+}
+
+/*
* Lookup addr in the peer prefix_index. Returns first match.
* Returns NULL if not found.
*/
@@ -1124,8 +1133,7 @@ prefix_add_eor(struct rde_peer *peer, uint8_t aid)
*/
void
prefix_adjout_update(struct prefix *p, struct rde_peer *peer,
- struct filterstate *state, struct bgpd_addr *prefix, int prefixlen,
- uint32_t path_id_tx)
+ struct filterstate *state, struct pt_entry *pte, uint32_t path_id_tx)
{
struct rde_aspath *asp;
struct rde_community *comm;
@@ -1135,10 +1143,7 @@ prefix_adjout_update(struct prefix *p, struct rde_peer *peer,
/* initially mark DEAD so code below is skipped */
p->flags |= PREFIX_FLAG_ADJOUT | PREFIX_FLAG_DEAD;
- p->pt = pt_get(prefix, prefixlen);
- if (p->pt == NULL)
- p->pt = pt_add(prefix, prefixlen);
- pt_ref(p->pt);
+ p->pt = pt_ref(pte);
p->peer = peer;
p->path_id_tx = path_id_tx;
@@ -1170,7 +1175,7 @@ prefix_adjout_update(struct prefix *p, struct rde_peer *peer,
/* if pending update unhook it before it is unlinked */
if (p->flags & PREFIX_FLAG_UPDATE) {
- RB_REMOVE(prefix_tree, &peer->updates[prefix->aid], p);
+ RB_REMOVE(prefix_tree, &peer->updates[pte->aid], p);
peer->stats.pending_update--;
}
@@ -1179,7 +1184,7 @@ prefix_adjout_update(struct prefix *p, struct rde_peer *peer,
peer->stats.prefix_out_cnt--;
}
if (p->flags & PREFIX_FLAG_WITHDRAW) {
- RB_REMOVE(prefix_tree, &peer->withdraws[prefix->aid], p);
+ RB_REMOVE(prefix_tree, &peer->withdraws[pte->aid], p);
peer->stats.pending_withdraw--;
}
@@ -1213,7 +1218,7 @@ prefix_adjout_update(struct prefix *p, struct rde_peer *peer,
if (p->flags & PREFIX_FLAG_MASK)
fatalx("%s: bad flags %x", __func__, p->flags);
p->flags |= PREFIX_FLAG_UPDATE;
- if (RB_INSERT(prefix_tree, &peer->updates[prefix->aid], p) != NULL)
+ if (RB_INSERT(prefix_tree, &peer->updates[pte->aid], p) != NULL)
fatalx("%s: RB tree invariant violated", __func__);
peer->stats.pending_update++;
}
diff --git a/usr.sbin/bgpd/rde_update.c b/usr.sbin/bgpd/rde_update.c
index dc4bf1e9673..9667b4fcd4b 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.160 2023/03/28 15:17:34 claudio Exp $ */
+/* $OpenBSD: rde_update.c,v 1.161 2023/03/29 10:46:11 claudio Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@@ -150,10 +150,10 @@ up_enforce_open_policy(struct rde_peer *peer, struct filterstate *state,
* - UP_EXCLUDED if prefix was excluded because of up_test_update()
*/
static enum up_state
-up_process_prefix(struct rde_peer *peer, struct prefix *new, struct prefix *p,
- struct bgpd_addr *addr, uint8_t plen)
+up_process_prefix(struct rde_peer *peer, struct prefix *new, struct prefix *p)
{
struct filterstate state;
+ struct bgpd_addr addr;
int excluded = 0;
/*
@@ -166,14 +166,15 @@ up_process_prefix(struct rde_peer *peer, struct prefix *new, struct prefix *p,
excluded = 1;
rde_filterstate_prep(&state, new);
- if (rde_filter(peer->out_rules, peer, prefix_peer(new), addr, plen,
- &state) == ACTION_DENY) {
+ pt_getaddr(new->pt, &addr);
+ if (rde_filter(peer->out_rules, peer, prefix_peer(new), &addr,
+ new->pt->prefixlen, &state) == ACTION_DENY) {
rde_filterstate_clean(&state);
return UP_FILTERED;
}
/* Open Policy Check: acts like an output filter */
- if (up_enforce_open_policy(peer, &state, addr->aid)) {
+ if (up_enforce_open_policy(peer, &state, new->pt->aid)) {
rde_filterstate_clean(&state);
return UP_FILTERED;
}
@@ -185,10 +186,10 @@ up_process_prefix(struct rde_peer *peer, struct prefix *new, struct prefix *p,
/* from here on we know this is an update */
if (p == (void *)-1)
- p = prefix_adjout_get(peer, new->path_id_tx, addr, plen);
+ p = prefix_adjout_get(peer, new->path_id_tx, new->pt);
- up_prep_adjout(peer, &state, addr->aid);
- prefix_adjout_update(p, peer, &state, addr, plen, new->path_id_tx);
+ up_prep_adjout(peer, &state, new->pt->aid);
+ prefix_adjout_update(p, peer, &state, new->pt, new->path_id_tx);
rde_filterstate_clean(&state);
/* max prefix checker outbound */
@@ -208,18 +209,13 @@ up_process_prefix(struct rde_peer *peer, struct prefix *new, struct prefix *p,
void
up_generate_updates(struct rde_peer *peer, struct rib_entry *re)
{
- struct bgpd_addr addr;
struct prefix *new, *p;
- uint8_t prefixlen;
- pt_getaddr(re->prefix, &addr);
- prefixlen = re->prefix->prefixlen;
-
- p = prefix_adjout_lookup(peer, &addr, prefixlen);
+ p = prefix_adjout_first(peer, re->prefix);
new = prefix_best(re);
while (new != NULL) {
- switch (up_process_prefix(peer, new, p, &addr, prefixlen)) {
+ switch (up_process_prefix(peer, new, p)) {
case UP_OK:
case UP_ERR_LIMIT:
return;
@@ -251,16 +247,11 @@ done:
void
up_generate_addpath(struct rde_peer *peer, struct rib_entry *re)
{
- struct bgpd_addr addr;
struct prefix *head, *new, *p;
- uint8_t prefixlen;
int maxpaths = 0, extrapaths = 0, extra;
int checkmode = 1;
- pt_getaddr(re->prefix, &addr);
- prefixlen = re->prefix->prefixlen;
-
- head = prefix_adjout_lookup(peer, &addr, prefixlen);
+ head = prefix_adjout_first(peer, re->prefix);
/* mark all paths as stale */
for (p = head; p != NULL; p = prefix_adjout_next(peer, p))
@@ -310,8 +301,7 @@ up_generate_addpath(struct rde_peer *peer, struct rib_entry *re)
}
}
- switch (up_process_prefix(peer, new, (void *)-1, &addr,
- prefixlen)) {
+ switch (up_process_prefix(peer, new, (void *)-1)) {
case UP_OK:
maxpaths++;
extrapaths += extra;
@@ -345,21 +335,16 @@ void
up_generate_addpath_all(struct rde_peer *peer, struct rib_entry *re,
struct prefix *new, struct prefix *old)
{
- struct bgpd_addr addr;
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 */
- head = prefix_adjout_lookup(peer, &addr, prefixlen);
+ head = prefix_adjout_first(peer, re->prefix);
for (p = head; p != NULL; p = prefix_adjout_next(peer, p))
p->flags |= PREFIX_FLAG_STALE;
@@ -369,15 +354,14 @@ up_generate_addpath_all(struct rde_peer *peer, struct rib_entry *re,
if (old != NULL) {
/* withdraw stale paths */
- p = prefix_adjout_get(peer, old->path_id_tx, &addr, prefixlen);
+ p = prefix_adjout_get(peer, old->path_id_tx, old->pt);
if (p != NULL)
prefix_adjout_withdraw(p);
}
/* add new path (or multiple if all is set) */
while (new != NULL) {
- switch (up_process_prefix(peer, new, (void *)-1, &addr,
- prefixlen)) {
+ switch (up_process_prefix(peer, new, (void *)-1)) {
case UP_OK:
case UP_FILTERED:
case UP_EXCLUDED:
@@ -405,10 +389,6 @@ up_generate_addpath_all(struct rde_peer *peer, struct rib_entry *re,
}
}
-struct rib_entry *rib_add(struct rib *, struct bgpd_addr *, int);
-void rib_remove(struct rib_entry *);
-int rib_empty(struct rib_entry *);
-
/* send a default route to the specified peer */
void
up_generate_default(struct rde_peer *peer, uint8_t aid)
@@ -417,6 +397,7 @@ up_generate_default(struct rde_peer *peer, uint8_t aid)
struct filterstate state;
struct rde_aspath *asp;
struct prefix *p;
+ struct pt_entry *pte;
struct bgpd_addr addr;
if (peer->capa.mp[aid] == 0)
@@ -447,7 +428,11 @@ up_generate_default(struct rde_peer *peer, uint8_t aid)
}
up_prep_adjout(peer, &state, addr.aid);
- prefix_adjout_update(p, peer, &state, &addr, 0, 0);
+ /* can't use pt_fill here since prefix_adjout_update keeps a ref */
+ pte = pt_get(&addr, 0);
+ if (pte == NULL)
+ pte = pt_add(&addr, 0);
+ prefix_adjout_update(p, peer, &state, pte, 0);
rde_filterstate_clean(&state);
/* max prefix checker outbound */