diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2004-02-19 23:07:01 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2004-02-19 23:07:01 +0000 |
commit | 49f8c3fdbbe774bfbfa3545849045a6c406ed026 (patch) | |
tree | 7d170651e7f9d33ac46f5de5e58fdc0d76a504b3 /usr.sbin/bgpd/rde.c | |
parent | e45a0a2546dfa029ffe0b93d1a4bc268f2e37c42 (diff) |
Add support for basic filters. Nothing optimized and it has some issues but
this is a huge step forward. OK henning@
Diffstat (limited to 'usr.sbin/bgpd/rde.c')
-rw-r--r-- | usr.sbin/bgpd/rde.c | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c index 6f0636d4535..7f337846c8f 100644 --- a/usr.sbin/bgpd/rde.c +++ b/usr.sbin/bgpd/rde.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.c,v 1.82 2004/02/19 13:54:58 claudio Exp $ */ +/* $OpenBSD: rde.c,v 1.83 2004/02/19 23:07:00 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -377,6 +377,7 @@ rde_update_dispatch(struct imsg *imsg) return (-1); } + /* withdraw prefix */ while (withdrawn_len > 0) { if ((pos = rde_update_get_prefix(p, withdrawn_len, &prefix, &prefixlen)) == -1) { @@ -398,6 +399,12 @@ rde_update_dispatch(struct imsg *imsg) p += pos; withdrawn_len -= pos; + + /* input filter */ + if (rde_filter(peer, NULL, &prefix, prefixlen, + DIR_IN) == ACTION_DENY) + continue; + rde_update_log("withdraw", peer, NULL, &prefix, prefixlen); prefix_remove(peer, &prefix, prefixlen); } @@ -415,6 +422,7 @@ rde_update_dispatch(struct imsg *imsg) if (attrpath_len == 0) /* 0 = no NLRI information in this message */ return (0); + /* parse path attributes */ attr_init(&attrs); while (attrpath_len > 0) { if ((pos = attr_parse(p, attrpath_len, &attrs, @@ -422,19 +430,18 @@ rde_update_dispatch(struct imsg *imsg) emsg = attr_error(p, attrpath_len, &attrs, &subtype, &size); rde_update_err(peer, ERR_UPDATE, subtype, emsg, size); - aspath_destroy(attrs.aspath); - attr_optfree(&attrs); + attr_free(&attrs); return (-1); } p += pos; attrpath_len -= pos; } + /* check for missing but necessary attributes */ if ((subtype = attr_missing(&attrs, peer->conf.ebgp)) != 0) { rde_update_err(peer, ERR_UPDATE, ERR_UPD_MISSNG_WK_ATTR, &subtype, sizeof(u_int8_t)); - aspath_destroy(attrs.aspath); - attr_optfree(&attrs); + attr_free(&attrs); return (-1); } @@ -449,13 +456,13 @@ rde_update_dispatch(struct imsg *imsg) return (0); } + /* parse nlri prefix */ while (nlri_len > 0) { if ((pos = rde_update_get_prefix(p, nlri_len, &prefix, &prefixlen)) == -1) { rde_update_err(peer, ERR_UPDATE, ERR_UPD_NETWORK, NULL, 0); - aspath_destroy(attrs.aspath); - attr_optfree(&attrs); + attr_free(&attrs); return (-1); } if (prefixlen > 32) { @@ -468,22 +475,32 @@ rde_update_dispatch(struct imsg *imsg) p += pos; nlri_len -= pos; - rde_update_log("update", peer, &attrs, &prefix, prefixlen); + + /* input filter */ + /* + * XXX we need to copy attrs befor calling the filter + * but that stinks, because we copy it again in path_update. + */ + if (rde_filter(peer, &attrs, &prefix, prefixlen, + DIR_IN) == ACTION_DENY) + continue; + + /* max prefix checker */ if (peer->conf.max_prefix && peer->prefix_cnt >= peer->conf.max_prefix) { log_peer_warnx(&peer->conf, "prefix limit reached"); rde_update_err(peer, ERR_CEASE, ERR_CEASE_MAX_PREFIX, NULL, 0); - aspath_destroy(attrs.aspath); - attr_optfree(&attrs); + attr_free(&attrs); return (-1); } + + rde_update_log("update", peer, &attrs, &prefix, prefixlen); path_update(peer, &attrs, &prefix, prefixlen); } /* need to free allocated attribute memory that is no longer used */ - aspath_destroy(attrs.aspath); - attr_optfree(&attrs); + attr_free(&attrs); return (0); } |