summaryrefslogtreecommitdiff
path: root/usr.sbin/bgpd/rde_update.c
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2018-11-04 12:34:55 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2018-11-04 12:34:55 +0000
commit44fb71c3b91165d95078c3131401f2955039f074 (patch)
tree58234d5635c883939c6b7f43460ccbc97b484aaa /usr.sbin/bgpd/rde_update.c
parent387671fcee8785988b21d4b1c89702fd5768f126 (diff)
Introduce a real Adj-RIB-Out. At the same time remove the update_rib
introduced before 6.4 because it now can be replaced with the real RIB. Main changes are: - simplified 'show rib' handling since everything is now a real RIB - path_update() is now returning if a prefix was not modified, added or moved - softreconfig out case is simpler since path_update does all the magic now - Adjust shutdown code to work with the Adj-RIB-Out Tested and OK denis@, benno@
Diffstat (limited to 'usr.sbin/bgpd/rde_update.c')
-rw-r--r--usr.sbin/bgpd/rde_update.c87
1 files changed, 13 insertions, 74 deletions
diff --git a/usr.sbin/bgpd/rde_update.c b/usr.sbin/bgpd/rde_update.c
index 013b57f7e44..a20922782b1 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.102 2018/10/24 08:26:37 claudio Exp $ */
+/* $OpenBSD: rde_update.c,v 1.103 2018/11/04 12:34:54 claudio Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@@ -53,15 +53,9 @@ struct update_attr {
u_int16_t mpattr_len;
};
-struct update_rib {
- RB_ENTRY(update_rib) entry;
- struct rib_entry *re;
-};
-
void up_clear(struct uplist_attr *, struct uplist_prefix *);
int up_prefix_cmp(struct update_prefix *, struct update_prefix *);
int up_attr_cmp(struct update_attr *, struct update_attr *);
-int up_rib_cmp(struct update_rib *, struct update_rib *);
int up_add(struct rde_peer *, struct update_prefix *, struct update_attr *);
RB_PROTOTYPE(uptree_prefix, update_prefix, entry, up_prefix_cmp)
@@ -70,9 +64,6 @@ RB_GENERATE(uptree_prefix, update_prefix, entry, up_prefix_cmp)
RB_PROTOTYPE(uptree_attr, update_attr, entry, up_attr_cmp)
RB_GENERATE(uptree_attr, update_attr, entry, up_attr_cmp)
-RB_PROTOTYPE(uptree_rib, update_rib, entry, up_rib_cmp)
-RB_GENERATE(uptree_rib, update_rib, entry, up_rib_cmp)
-
SIPHASH_KEY uptree_key;
void
@@ -86,7 +77,6 @@ up_init(struct rde_peer *peer)
}
RB_INIT(&peer->up_prefix);
RB_INIT(&peer->up_attrs);
- RB_INIT(&peer->up_rib);
peer->up_pcnt = 0;
peer->up_acnt = 0;
peer->up_nlricnt = 0;
@@ -120,7 +110,6 @@ up_clear(struct uplist_attr *updates, struct uplist_prefix *withdraws)
void
up_down(struct rde_peer *peer)
{
- struct update_rib *ur, *nur;
u_int8_t i;
for (i = 0; i < AID_MAX; i++)
@@ -128,10 +117,6 @@ up_down(struct rde_peer *peer)
RB_INIT(&peer->up_prefix);
RB_INIT(&peer->up_attrs);
- RB_FOREACH_SAFE(ur, uptree_rib, &peer->up_rib, nur) {
- RB_REMOVE(uptree_rib, &peer->up_rib, ur);
- free(ur);
- }
peer->up_pcnt = 0;
peer->up_acnt = 0;
@@ -210,58 +195,6 @@ up_attr_cmp(struct update_attr *a, struct update_attr *b)
}
int
-up_rib_cmp(struct update_rib *a, struct update_rib *b)
-{
- if (a->re != b->re)
- return (a->re > b->re ? 1 : -1);
- return 0;
-}
-
-int
-up_rib_remove(struct rde_peer *peer, struct rib_entry *re)
-{
- struct update_rib *ur, u;
- u.re = re;
-
- ur = RB_FIND(uptree_rib, &peer->up_rib, &u);
- if (ur != NULL) {
- RB_REMOVE(uptree_rib, &peer->up_rib, ur);
- free(ur);
- return 1;
- } else
- return 0;
-}
-
-void
-up_rib_add(struct rde_peer *peer, struct rib_entry *re)
-{
- struct update_rib *ur;
-
- if ((ur = calloc(1, sizeof(*ur))) == NULL)
- fatal("%s", __func__);
- ur->re = re;
-
- if (RB_INSERT(uptree_rib, &peer->up_rib, ur) != NULL)
- free(ur);
-}
-
-void
-up_withdraw_all(struct rde_peer *peer)
-{
- struct bgpd_addr addr;
- struct update_rib *ur, *nur;
-
- RB_FOREACH_SAFE(ur, uptree_rib, &peer->up_rib, nur) {
- RB_REMOVE(uptree_rib, &peer->up_rib, ur);
-
- /* withdraw prefix */
- pt_getaddr(ur->re->prefix, &addr);
- up_generate(peer, NULL, &addr, ur->re->prefix->prefixlen);
- free(ur);
- }
-}
-
-int
up_add(struct rde_peer *peer, struct update_prefix *p, struct update_attr *a)
{
struct update_attr *na = NULL;
@@ -473,14 +406,16 @@ up_generate_updates(struct filter_head *rules, struct rde_peer *peer,
if (new == NULL) {
withdraw:
- if (up_test_update(peer, old) != 1)
- return;
-
- if (!up_rib_remove(peer, old->re))
+ if (old == NULL)
return;
/* withdraw prefix */
pt_getaddr(old->re->prefix, &addr);
+ if (prefix_remove(&ribs[RIB_ADJ_OUT].rib, peer, &addr,
+ old->re->prefix->prefixlen) == 0) {
+ /* not in table, no need to send withdraw */
+ return;
+ }
up_generate(peer, NULL, &addr, old->re->prefix->prefixlen);
} else {
switch (up_test_update(peer, new)) {
@@ -500,8 +435,12 @@ withdraw:
}
pt_getaddr(new->re->prefix, &addr);
- up_generate(peer, &state, &addr, new->re->prefix->prefixlen);
- up_rib_add(peer, new->re);
+ if (path_update(&ribs[RIB_ADJ_OUT].rib, peer, &state, &addr,
+ new->re->prefix->prefixlen, prefix_vstate(new)) != 2) {
+ /* only send update if path changed */
+ up_generate(peer, &state, &addr,
+ new->re->prefix->prefixlen);
+ }
rde_filterstate_clean(&state);
}