diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2018-12-11 09:03:37 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2018-12-11 09:03:37 +0000 |
commit | c45d3e227fdec154b4b19d3a691352f91b29da41 (patch) | |
tree | 5c8e67fd0c803172e6c6d3247150c30b3a2304d9 /usr.sbin/bgpctl | |
parent | bf129b3f320c50facaadd3b350190cb1b9b34af2 (diff) |
bgpctl can no long reuse the aspath_match function from bgpd so move the
roughly the same function here called match_aspath().
OK denis@
Diffstat (limited to 'usr.sbin/bgpctl')
-rw-r--r-- | usr.sbin/bgpctl/bgpctl.c | 71 |
1 files changed, 65 insertions, 6 deletions
diff --git a/usr.sbin/bgpctl/bgpctl.c b/usr.sbin/bgpctl/bgpctl.c index 0bce0ca8dc8..2c2105bb4ea 100644 --- a/usr.sbin/bgpctl/bgpctl.c +++ b/usr.sbin/bgpctl/bgpctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpctl.c,v 1.225 2018/12/05 06:53:52 denis Exp $ */ +/* $OpenBSD: bgpctl.c,v 1.226 2018/12/11 09:03:36 claudio Exp $ */ /* * Copyright (c) 2003 Henning Brauer <henning@openbsd.org> @@ -97,6 +97,7 @@ void mrt_to_bgpd_addr(union mrt_addr *, struct bgpd_addr *); const char *msg_type(u_int8_t); void network_bulk(struct parse_result *); const char *print_auth_method(enum auth_method); +int match_aspath(void *, u_int16_t, struct filter_as *); struct imsgbuf *ibuf; struct mrt_parser show_mrt = { show_mrt_dump, show_mrt_state, show_mrt_msg }; @@ -2056,8 +2057,7 @@ show_mrt_dump(struct mrt_rib *mr, struct mrt_peer *mp, void *arg) } /* filter by AS */ if (req->as.type != AS_UNDEF && - !aspath_match(mre->aspath, mre->aspath_len, - &req->as, 0)) + !match_aspath(mre->aspath, mre->aspath_len, &req->as)) continue; if (req->flags & F_CTL_DETAIL) { @@ -2122,8 +2122,7 @@ network_mrt_dump(struct mrt_rib *mr, struct mrt_peer *mp, void *arg) } /* filter by AS */ if (req->as.type != AS_UNDEF && - !aspath_match(mre->aspath, mre->aspath_len, - &req->as, 0)) + !match_aspath(mre->aspath, mre->aspath_len, &req->as)) continue; bzero(&net, sizeof(net)); @@ -2661,7 +2660,67 @@ msg_type(u_int8_t type) } int -as_set_match(const struct as_set *a, u_int32_t asnum) +match_aspath(void *data, u_int16_t len, struct filter_as *f) { + u_int8_t *seg; + int final; + u_int16_t seg_size; + u_int8_t i, seg_len; + u_int32_t as = 0; + + if (f->type == AS_EMPTY) { + if (len == 0) + return (1); + else + return (0); + } + + seg = data; + + /* just check the leftmost AS */ + if (f->type == AS_PEER && len >= 6) { + as = aspath_extract(seg, 0); + if (f->as_min == as) + return (1); + else + return (0); + } + + for (; len >= 6; len -= seg_size, seg += seg_size) { + seg_len = seg[1]; + seg_size = 2 + sizeof(u_int32_t) * seg_len; + + final = (len == seg_size); + + if (f->type == AS_SOURCE) { + /* + * Just extract the rightmost AS + * but if that segment is an AS_SET then the rightmost + * AS of a previous AS_SEQUENCE segment should be used. + * Because of that just look at AS_SEQUENCE segments. + */ + if (seg[0] == AS_SEQUENCE) + as = aspath_extract(seg, seg_len - 1); + /* not yet in the final segment */ + if (!final) + continue; + if (f->as_min == as) + return (1); + else + return (0); + } + /* AS_TRANSIT or AS_ALL */ + for (i = 0; i < seg_len; i++) { + /* + * the source (rightmost) AS is excluded from + * AS_TRANSIT matches. + */ + if (final && i == seg_len - 1 && f->type == AS_TRANSIT) + return (0); + as = aspath_extract(seg, i); + if (f->as_min == as) + return (1); + } + } return (0); } |