summaryrefslogtreecommitdiff
path: root/usr.sbin/bgpctl
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2018-12-11 09:03:37 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2018-12-11 09:03:37 +0000
commitc45d3e227fdec154b4b19d3a691352f91b29da41 (patch)
tree5c8e67fd0c803172e6c6d3247150c30b3a2304d9 /usr.sbin/bgpctl
parentbf129b3f320c50facaadd3b350190cb1b9b34af2 (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.c71
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);
}