diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2009-05-27 06:58:16 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2009-05-27 06:58:16 +0000 |
commit | a211586afefef84c61a6b8dd42ae9b3d78852cb7 (patch) | |
tree | cbe3f71da1e5d7e423b0f4b5f49bbcc8b967db81 /usr.sbin/bgpd | |
parent | df7a4b984dacb8a1f9338d4d8dfdb8b9ee548a0c (diff) |
Move update and withdraw code into own functions to simplify the necessary
changes to make multiple RIB functional. Also change the way we account the
prefixes per peer (for maxprefix check). Every prefix that was added to any
RIB is counted. OK henning@
Diffstat (limited to 'usr.sbin/bgpd')
-rw-r--r-- | usr.sbin/bgpd/rde.c | 123 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde.h | 10 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde_rib.c | 48 |
3 files changed, 88 insertions, 93 deletions
diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c index 1ca29f3b4ff..fa423adabf6 100644 --- a/usr.sbin/bgpd/rde.c +++ b/usr.sbin/bgpd/rde.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.c,v 1.245 2009/05/17 14:45:25 claudio Exp $ */ +/* $OpenBSD: rde.c,v 1.246 2009/05/27 06:58:15 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -44,6 +44,10 @@ void rde_sighdlr(int); void rde_dispatch_imsg_session(struct imsgbuf *); void rde_dispatch_imsg_parent(struct imsgbuf *); int rde_update_dispatch(struct imsg *); +void rde_update_update(struct rde_peer *, struct rde_aspath *, + struct bgpd_addr *, u_int8_t); +void rde_update_withdraw(struct rde_peer *, struct bgpd_addr *, + u_int8_t); int rde_attr_parse(u_char *, u_int16_t, struct rde_peer *, struct rde_aspath *, struct mpattr *); u_int8_t rde_attr_missing(struct rde_aspath *, int, u_int16_t); @@ -727,7 +731,7 @@ int rde_update_dispatch(struct imsg *imsg) { struct rde_peer *peer; - struct rde_aspath *asp = NULL, *fasp; + struct rde_aspath *asp = NULL; u_char *p, *mpp = NULL; int error = -1, pos = 0; u_int16_t afi, len, mplen; @@ -848,10 +852,7 @@ rde_update_dispatch(struct imsg *imsg) goto done; } - peer->prefix_rcvd_withdraw++; - rde_update_log("withdraw", peer, NULL, &prefix, prefixlen); - prefix_remove(&ribs[1], peer, &prefix, prefixlen, 0); - prefix_remove(&ribs[0], peer, &prefix, prefixlen, 0); + rde_update_withdraw(peer, &prefix, prefixlen); } if (attrpath_len == 0) { @@ -906,13 +907,7 @@ rde_update_dispatch(struct imsg *imsg) mpp += pos; mplen -= pos; - peer->prefix_rcvd_withdraw++; - rde_update_log("withdraw", peer, NULL, - &prefix, prefixlen); - prefix_remove(&ribs[1], peer, &prefix, - prefixlen, 0); - prefix_remove(&ribs[0], peer, &prefix, - prefixlen, 0); + rde_update_withdraw(peer, &prefix, prefixlen); } break; default: @@ -960,17 +955,7 @@ rde_update_dispatch(struct imsg *imsg) goto done; } - peer->prefix_rcvd_update++; - /* add original path to the Adj-RIB-In */ - if (peer->conf.softreconfig_in) - path_update(&ribs[0], peer, asp, &prefix, prefixlen); - - /* input filter */ - if (rde_filter(&fasp, rules_l, peer, asp, &prefix, prefixlen, - peer, DIR_IN) == ACTION_DENY) { - path_put(fasp); - continue; - } + rde_update_update(peer, asp, &prefix, prefixlen); /* max prefix checker */ if (peer->conf.max_prefix && @@ -978,20 +963,9 @@ rde_update_dispatch(struct imsg *imsg) log_peer_warnx(&peer->conf, "prefix limit reached"); rde_update_err(peer, ERR_CEASE, ERR_CEASE_MAX_PREFIX, NULL, 0); - path_put(fasp); goto done; } - if (fasp == NULL) - fasp = asp; - - rde_update_log("update", peer, &fasp->nexthop->exit_nexthop, - &prefix, prefixlen); - path_update(&ribs[1], peer, fasp, &prefix, prefixlen); - - /* free modified aspath */ - if (fasp != asp) - path_put(fasp); } /* add MP_REACH_NLRI if available */ @@ -1053,19 +1027,8 @@ rde_update_dispatch(struct imsg *imsg) mpp += pos; mplen -= pos; - peer->prefix_rcvd_update++; - /* add original path to the Adj-RIB-In */ - if (peer->conf.softreconfig_in) - path_update(&ribs[0], peer, asp, - &prefix, prefixlen); - - /* input filter */ - if (rde_filter(&fasp, rules_l, peer, asp, - &prefix, prefixlen, peer, DIR_IN) == - ACTION_DENY) { - path_put(fasp); - continue; - } + rde_update_update(peer, asp, &prefix, + prefixlen); /* max prefix checker */ if (peer->conf.max_prefix && @@ -1074,22 +1037,9 @@ rde_update_dispatch(struct imsg *imsg) "prefix limit reached"); rde_update_err(peer, ERR_CEASE, ERR_CEASE_MAX_PREFIX, NULL, 0); - path_put(fasp); goto done; } - if (fasp == NULL) - fasp = asp; - - rde_update_log("update", peer, - &asp->nexthop->exit_nexthop, - &prefix, prefixlen); - path_update(&ribs[1], peer, fasp, &prefix, - prefixlen); - - /* free modified aspath */ - if (fasp != asp) - path_put(fasp); } break; default: @@ -1112,6 +1062,55 @@ done: return (error); } +void +rde_update_update(struct rde_peer *peer, struct rde_aspath *asp, + struct bgpd_addr *prefix, u_int8_t prefixlen) +{ + struct rde_aspath *fasp; + int r = 0; + + peer->prefix_rcvd_update++; + /* add original path to the Adj-RIB-In */ + if (peer->conf.softreconfig_in) + r += path_update(&ribs[0], peer, asp, prefix, prefixlen); + + /* input filter */ + if (rde_filter(&fasp, rules_l, peer, asp, prefix, prefixlen, + peer, DIR_IN) == ACTION_DENY) + goto done; + + if (fasp == NULL) + fasp = asp; + + rde_update_log("update", peer, &fasp->nexthop->exit_nexthop, + prefix, prefixlen); + r += path_update(&ribs[1], peer, fasp, prefix, prefixlen); + +done: + /* free modified aspath */ + if (fasp != asp) + path_put(fasp); + + if (r) + peer->prefix_cnt++; +} + +void +rde_update_withdraw(struct rde_peer *peer, struct bgpd_addr *prefix, + u_int8_t prefixlen) +{ + int r = 0; + + peer->prefix_rcvd_withdraw++; + rde_update_log("withdraw", peer, NULL, prefix, prefixlen); + + r += prefix_remove(&ribs[1], peer, prefix, prefixlen, 0); + r += prefix_remove(&ribs[0], peer, prefix, prefixlen, 0); + + if (r) + peer->prefix_cnt--; +} + /* * BGP UPDATE parser functions */ @@ -1709,7 +1708,6 @@ rde_dump_rib_as(struct prefix *p, struct rde_aspath *asp, pid_t pid, int flags) rib.med = asp->med; rib.prefix_cnt = asp->prefix_cnt; rib.active_cnt = asp->active_cnt; - rib.rib_cnt = asp->rib_cnt; strlcpy(rib.descr, asp->peer->conf.descr, sizeof(rib.descr)); memcpy(&rib.remote_addr, &asp->peer->remote_addr, sizeof(rib.remote_addr)); @@ -2609,6 +2607,7 @@ peer_down(u_int32_t id) path_remove(asp); } LIST_INIT(&peer->path_h); + peer->prefix_cnt = 0; /* Deletions are performed in path_remove() */ rde_send_pftable_commit(); diff --git a/usr.sbin/bgpd/rde.h b/usr.sbin/bgpd/rde.h index 7f2905db780..c84f7ecf880 100644 --- a/usr.sbin/bgpd/rde.h +++ b/usr.sbin/bgpd/rde.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.h,v 1.109 2009/05/21 15:47:03 claudio Exp $ */ +/* $OpenBSD: rde.h,v 1.110 2009/05/27 06:58:15 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and @@ -67,7 +67,6 @@ struct rde_peer { u_int64_t prefix_sent_update; u_int64_t prefix_sent_withdraw; u_int32_t prefix_cnt; /* # of prefixes */ - u_int32_t rib_cnt; /* # of p. in Adj-RIB-In */ u_int32_t remote_bgpid; /* host byte order! */ u_int32_t up_pcnt; u_int32_t up_acnt; @@ -184,7 +183,6 @@ struct rde_aspath { u_int32_t weight; /* low prio lpref */ u_int32_t prefix_cnt; /* # of prefixes */ u_int32_t active_cnt; /* # of active prefixes */ - u_int32_t rib_cnt; /* # of p. in Adj-RIB-In */ u_int32_t flags; /* internally used */ u_int16_t rtlabelid; /* route label id */ u_int16_t pftableid; /* pf table id */ @@ -355,7 +353,7 @@ void rib_dump_r(struct rib_context *); void path_init(u_int32_t); void path_shutdown(void); -void path_update(struct rib *, struct rde_peer *, +int path_update(struct rib *, struct rde_peer *, struct rde_aspath *, struct bgpd_addr *, int); int path_compare(struct rde_aspath *, struct rde_aspath *); struct rde_aspath *path_lookup(struct rde_aspath *, struct rde_peer *); @@ -371,10 +369,10 @@ int prefix_compare(const struct bgpd_addr *, const struct bgpd_addr *, int); struct prefix *prefix_get(struct rib *, struct rde_peer *, struct bgpd_addr *, int, u_int32_t); -void prefix_add(struct rib *, struct rde_aspath *, +int prefix_add(struct rib *, struct rde_aspath *, struct bgpd_addr *, int); void prefix_move(struct rde_aspath *, struct prefix *); -void prefix_remove(struct rib *, struct rde_peer *, +int prefix_remove(struct rib *, struct rde_peer *, struct bgpd_addr *, int, u_int32_t); int prefix_write(u_char *, int, struct bgpd_addr *, u_int8_t); struct prefix *prefix_bypeer(struct rib_entry *, struct rde_peer *, diff --git a/usr.sbin/bgpd/rde_rib.c b/usr.sbin/bgpd/rde_rib.c index 5ee64aedbfb..a4bd6b4a3f7 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.102 2009/05/21 15:47:03 claudio Exp $ */ +/* $OpenBSD: rde_rib.c,v 1.103 2009/05/27 06:58:15 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> @@ -292,12 +292,9 @@ done: } /* used to bump correct prefix counters */ -#define PREFIX_COUNT(x, id, op) \ - do { \ - if (id == 1) \ - (x)->prefix_cnt += (op); \ - else \ - (x)->rib_cnt += (op); \ +#define PREFIX_COUNT(x, op) \ + do { \ + (x)->prefix_cnt += (op); \ } while (0) /* path specific functions */ @@ -340,7 +337,7 @@ path_shutdown(void) free(pathtable.path_hashtbl); } -void +int path_update(struct rib *rib, struct rde_peer *peer, struct rde_aspath *nasp, struct bgpd_addr *prefix, int prefixlen) { @@ -359,7 +356,7 @@ path_update(struct rib *rib, struct rde_peer *peer, struct rde_aspath *nasp, if (path_compare(nasp, p->aspath) == 0) { /* no change, update last change */ p->lastchange = time(NULL); - return; + return (0); } } @@ -378,7 +375,8 @@ path_update(struct rib *rib, struct rde_peer *peer, struct rde_aspath *nasp, if (p != NULL) prefix_move(asp, p); else - prefix_add(rib, asp, prefix, prefixlen); + return (prefix_add(rib, asp, prefix, prefixlen)); + return (0); } int @@ -466,8 +464,7 @@ void path_destroy(struct rde_aspath *asp) { /* path_destroy can only unlink and free empty rde_aspath */ - if (asp->prefix_cnt != 0 || asp->active_cnt != 0 || - asp->rib_cnt != 0) + if (asp->prefix_cnt != 0 || asp->active_cnt != 0) log_warnx("path_destroy: prefix count out of sync"); nexthop_unlink(asp); @@ -644,7 +641,7 @@ prefix_get(struct rib *rib, struct rde_peer *peer, struct bgpd_addr *prefix, /* * Adds or updates a prefix. */ -void +int prefix_add(struct rib *rib, struct rde_aspath *asp, struct bgpd_addr *prefix, int prefixlen) @@ -660,13 +657,14 @@ prefix_add(struct rib *rib, struct rde_aspath *asp, struct bgpd_addr *prefix, if (p == NULL) { p = prefix_alloc(); prefix_link(p, re, asp); + return (1); } else { if (p->aspath != asp) { /* prefix belongs to a different aspath so move */ prefix_move(asp, p); - return; - } - p->lastchange = time(NULL); + } else + p->lastchange = time(NULL); + return (0); } } @@ -692,7 +690,7 @@ prefix_move(struct rde_aspath *asp, struct prefix *p) /* add to new as path */ LIST_INSERT_HEAD(&asp->prefix_h, np, path_l); - PREFIX_COUNT(asp, p->rib->rib->id, 1); + PREFIX_COUNT(asp, 1); /* * no need to update the peer prefix count because we are only moving * the prefix without changing the peer. @@ -712,7 +710,7 @@ prefix_move(struct rde_aspath *asp, struct prefix *p) /* remove old prefix node */ oasp = p->aspath; LIST_REMOVE(p, path_l); - PREFIX_COUNT(oasp, p->rib->rib->id, -1); + PREFIX_COUNT(oasp, -1); /* as before peer count needs no update because of move */ /* destroy all references to other objects and free the old prefix */ @@ -730,7 +728,7 @@ prefix_move(struct rde_aspath *asp, struct prefix *p) * Removes a prefix from all lists. If the parent objects -- path or * pt_entry -- become empty remove them too. */ -void +int prefix_remove(struct rib *rib, struct rde_peer *peer, struct bgpd_addr *prefix, int prefixlen, u_int32_t flags) { @@ -740,11 +738,11 @@ prefix_remove(struct rib *rib, struct rde_peer *peer, struct bgpd_addr *prefix, re = rib_get(rib, prefix, prefixlen); if (re == NULL) /* Got a dummy withdrawn request */ - return; + return (0); p = prefix_bypeer(re, peer, flags); if (p == NULL) /* Got a dummy withdrawn request. */ - return; + return (0); asp = p->aspath; @@ -761,6 +759,8 @@ prefix_remove(struct rib *rib, struct rde_peer *peer, struct bgpd_addr *prefix, rib_remove(re); if (path_empty(asp)) path_destroy(asp); + + return (1); } /* dump a prefix into specified buffer */ @@ -895,8 +895,7 @@ static void prefix_link(struct prefix *pref, struct rib_entry *re, struct rde_aspath *asp) { LIST_INSERT_HEAD(&asp->prefix_h, pref, path_l); - PREFIX_COUNT(asp, re->rib->id, 1); - PREFIX_COUNT(asp->peer, re->rib->id, 1); + PREFIX_COUNT(asp, 1); pref->aspath = asp; pref->rib = re; @@ -921,8 +920,7 @@ prefix_unlink(struct prefix *pref) } LIST_REMOVE(pref, path_l); - PREFIX_COUNT(pref->aspath, pref->rib->rib->id, -1); - PREFIX_COUNT(pref->aspath->peer, pref->rib->rib->id, -1); + PREFIX_COUNT(pref->aspath, -1); pt_unref(pref->prefix); if (pt_empty(pref->prefix)) |