From 060f4cb2c5863263ea05d28194b264ce291c0ceb Mon Sep 17 00:00:00 2001 From: claudio Date: Tue, 24 Jan 2023 14:13:11 +0000 Subject: [PATCH] Implement filter and control message matching for ASAP. This adds avs (ASPA validation state) which can be 'unknown', 'valid' or 'invalid'. It behaves similar to ovs but the ASPA validation state of paths from iBGP sessions is 'unknown' and the role of the ebgp session is important to get the right validation state. OK tb@ --- usr.sbin/bgpd/bgpd.conf.5 | 12 ++++++++++-- usr.sbin/bgpd/bgpd.h | 10 +++++++--- usr.sbin/bgpd/parse.y | 33 +++++++++++++++++++++++++++++---- usr.sbin/bgpd/printconf.c | 18 +++++++++++++++++- usr.sbin/bgpd/rde.c | 34 +++++++++++++++++++++++++++++++--- usr.sbin/bgpd/rde_filter.c | 7 ++++++- 6 files changed, 100 insertions(+), 14 deletions(-) diff --git a/usr.sbin/bgpd/bgpd.conf.5 b/usr.sbin/bgpd/bgpd.conf.5 index dd0656b665b..e112bf8eab6 100644 --- a/usr.sbin/bgpd/bgpd.conf.5 +++ b/usr.sbin/bgpd/bgpd.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: bgpd.conf.5,v 1.229 2023/01/20 15:41:33 claudio Exp $ +.\" $OpenBSD: bgpd.conf.5,v 1.230 2023/01/24 14:13:11 claudio Exp $ .\" .\" Copyright (c) 2004 Claudio Jeker .\" Copyright (c) 2003, 2004 Henning Brauer @@ -16,7 +16,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: January 20 2023 $ +.Dd $Mdocdate: January 24 2023 $ .Dt BGPD.CONF 5 .Os .Sh NAME @@ -1538,6 +1538,14 @@ deny from any { AS { 1, 2, 3 }, source-as 4, transit-as 5 } .Ed .Pp .It Xo +.Ic avs +.Pq Ic valid | unknown | invalid +.Xc +This rule applies only to +.Em UPDATES +where the ASPA Validation State (AVS) matches. +.Pp +.It Xo .Ic community .Ar as-number Ns Li \&: Ns Ar local .Xc diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h index 9cdad342271..99ffdc1bb30 100644 --- a/usr.sbin/bgpd/bgpd.h +++ b/usr.sbin/bgpd/bgpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.h,v 1.459 2023/01/24 11:28:41 claudio Exp $ */ +/* $OpenBSD: bgpd.h,v 1.460 2023/01/24 14:13:11 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -94,6 +94,9 @@ #define F_CTL_OVS_NOTFOUND 0x200000 #define F_CTL_NEIGHBORS 0x400000 /* only used by bgpctl */ #define F_CTL_HAS_PATHID 0x800000 /* only set on requests */ +#define F_CTL_AVS_VALID 0x1000000 +#define F_CTL_AVS_INVALID 0x2000000 +#define F_CTL_AVS_UNKNOWN 0x4000000 #define CTASSERT(x) extern char _ctassert[(x) ? 1 : -1 ] \ __attribute__((__unused__)) @@ -896,7 +899,7 @@ struct filter_originset { struct rde_prefixset *ps; }; -struct filter_ovs { +struct filter_vs { uint8_t validity; uint8_t is_set; }; @@ -1082,7 +1085,8 @@ struct filter_match { struct community community[MAX_COMM_MATCH]; struct filter_prefixset prefixset; struct filter_originset originset; - struct filter_ovs ovs; + struct filter_vs ovs; + struct filter_vs avs; int maxcomm; int maxextcomm; int maxlargecomm; diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y index 5c96dabfc37..de3ee73929c 100644 --- a/usr.sbin/bgpd/parse.y +++ b/usr.sbin/bgpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.439 2023/01/20 15:41:33 claudio Exp $ */ +/* $OpenBSD: parse.y,v 1.440 2023/01/24 14:13:11 claudio Exp $ */ /* * Copyright (c) 2002, 2003, 2004 Henning Brauer @@ -231,7 +231,7 @@ typedef struct { %token COMMUNITY EXTCOMMUNITY LARGECOMMUNITY DELETE %token MAXCOMMUNITIES MAXEXTCOMMUNITIES MAXLARGECOMMUNITIES %token PREFIX PREFIXLEN PREFIXSET -%token ASPASET ROASET ORIGINSET OVS EXPIRES +%token ASPASET ROASET ORIGINSET OVS AVS EXPIRES %token ASSET SOURCEAS TRANSITAS PEERAS PROVIDERAS CUSTOMERAS MAXASLEN MAXASSEQ %token SET LOCALPREF MED METRIC NEXTHOP REJECT BLACKHOLE NOMODIFY SELF %token PREPEND_SELF PREPEND_PEER PFTABLE WEIGHT RTLABEL ORIGIN PRIORITY @@ -244,7 +244,8 @@ typedef struct { %token NUMBER %type asnumber as4number as4number_any optnumber %type espah family safi restart origincode nettype -%type yesno inout restricted validity expires enforce +%type yesno inout restricted expires enforce +%type validity aspa_validity %type addpathextra addpathmax %type string %type address @@ -2622,6 +2623,14 @@ filter_elm : filter_prefix_h { fmopts.m.ovs.validity = $2; fmopts.m.ovs.is_set = 1; } + | AVS aspa_validity { + if (fmopts.m.avs.is_set) { + yyerror("avs filter already specified"); + YYERROR; + } + fmopts.m.avs.validity = $2; + fmopts.m.avs.is_set = 1; + } ; prefixlenop : /* empty */ { memset(&$$, 0, sizeof($$)); } @@ -3070,7 +3079,22 @@ validity : STRING { else if (!strcmp($1, "valid")) $$ = ROA_VALID; else { - yyerror("unknown validity \"%s\"", $1); + yyerror("unknown roa validity \"%s\"", $1); + free($1); + YYERROR; + } + free($1); + }; + +aspa_validity : STRING { + if (!strcmp($1, "unknown")) + $$ = ASPA_UNKNOWN; + else if (!strcmp($1, "invalid")) + $$ = ASPA_INVALID; + else if (!strcmp($1, "valid")) + $$ = ASPA_VALID; + else { + yyerror("unknown aspa validity \"%s\"", $1); free($1); YYERROR; } @@ -3149,6 +3173,7 @@ lookup(char *s) { "as-override", ASOVERRIDE}, { "as-set", ASSET }, { "aspa-set", ASPASET}, + { "avs", AVS}, { "blackhole", BLACKHOLE}, { "capabilities", CAPABILITIES}, { "community", COMMUNITY}, diff --git a/usr.sbin/bgpd/printconf.c b/usr.sbin/bgpd/printconf.c index cfa2bda4947..de6b4c3a8fe 100644 --- a/usr.sbin/bgpd/printconf.c +++ b/usr.sbin/bgpd/printconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: printconf.c,v 1.162 2023/01/20 15:41:33 claudio Exp $ */ +/* $OpenBSD: printconf.c,v 1.163 2023/01/24 14:13:12 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -944,6 +944,22 @@ print_rule(struct bgpd_config *conf, struct filter_rule *r) } } + if (r->match.avs.is_set) { + switch (r->match.avs.validity) { + case ASPA_VALID: + printf("avs valid "); + break; + case ASPA_INVALID: + printf("avs invalid "); + break; + case ASPA_UNKNOWN: + printf("avs unknown "); + break; + default: + printf("avs ??? %d ??? ", r->match.avs.validity); + } + } + if (r->match.prefix.addr.aid != AID_UNSPEC) { printf("prefix "); print_prefix(&r->match.prefix); diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c index bca75af2158..62593bc35cb 100644 --- a/usr.sbin/bgpd/rde.c +++ b/usr.sbin/bgpd/rde.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.c,v 1.590 2023/01/24 11:28:41 claudio Exp $ */ +/* $OpenBSD: rde.c,v 1.591 2023/01/24 14:13:12 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -103,7 +103,8 @@ static void network_dump_upcall(struct rib_entry *, void *); static void network_flush_upcall(struct rib_entry *, void *); void rde_shutdown(void); -int ovs_match(struct prefix *, uint32_t); +static int ovs_match(struct prefix *, uint32_t); +static int avs_match(struct prefix *, uint32_t); static struct imsgbuf *ibuf_se; static struct imsgbuf *ibuf_se_ctl; @@ -2776,6 +2777,8 @@ rde_dump_filter(struct prefix *p, struct ctl_show_rib_request *req, int adjout) } if (!ovs_match(p, req->flags)) return; + if (!avs_match(p, req->flags)) + return; rde_dump_rib_as(p, asp, req->pid, req->flags, adjout); } @@ -4528,7 +4531,7 @@ rde_roa_validity(struct rde_prefixset *ps, struct bgpd_addr *prefix, return (r & ROA_MASK); } -int +static int ovs_match(struct prefix *p, uint32_t flag) { if (flag & (F_CTL_OVS_VALID|F_CTL_OVS_INVALID|F_CTL_OVS_NOTFOUND)) { @@ -4552,3 +4555,28 @@ ovs_match(struct prefix *p, uint32_t flag) return 1; } + +static int +avs_match(struct prefix *p, uint32_t flag) +{ + if (flag & (F_CTL_AVS_VALID|F_CTL_AVS_INVALID|F_CTL_AVS_UNKNOWN)) { + switch (prefix_aspa_vstate(p) & ASPA_MASK) { + case ASPA_VALID: + if (!(flag & F_CTL_AVS_VALID)) + return 0; + break; + case ASPA_INVALID: + if (!(flag & F_CTL_AVS_INVALID)) + return 0; + break; + case ASPA_UNKNOWN: + if (!(flag & F_CTL_AVS_UNKNOWN)) + return 0; + break; + default: + break; + } + } + + return 1; +} diff --git a/usr.sbin/bgpd/rde_filter.c b/usr.sbin/bgpd/rde_filter.c index cbdba6cb437..be8fe97cd73 100644 --- a/usr.sbin/bgpd/rde_filter.c +++ b/usr.sbin/bgpd/rde_filter.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_filter.c,v 1.132 2023/01/24 11:28:41 claudio Exp $ */ +/* $OpenBSD: rde_filter.c,v 1.133 2023/01/24 14:13:12 claudio Exp $ */ /* * Copyright (c) 2004 Claudio Jeker @@ -227,6 +227,11 @@ rde_filter_match(struct filter_rule *f, struct rde_peer *peer, return (0); } + if (f->match.avs.is_set) { + if (((state->vstate >> 4) & ASPA_MASK) != f->match.avs.validity) + return (0); + } + if (asp != NULL && f->match.as.type != AS_UNDEF) { if (aspath_match(asp->aspath, &f->match.as, peer->conf.remote_as) == 0) -- 2.20.1