diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2018-11-04 12:34:55 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2018-11-04 12:34:55 +0000 |
commit | 44fb71c3b91165d95078c3131401f2955039f074 (patch) | |
tree | 58234d5635c883939c6b7f43460ccbc97b484aaa /usr.sbin/bgpd/rde_update.c | |
parent | 387671fcee8785988b21d4b1c89702fd5768f126 (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.c | 87 |
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); } |