Here is hopefully the last pieces to finish ASAP support.
This adds filter support. It is similar to origin validation and called
AVS (ASPA validation state). Only difference is that not-found is called
unknown in AVS.
The diff also adds `bgpctl show rib avs invalid` support.

~> bgpctl show rib avs invalid
flags: * = Valid, > = Selected, I = via IBGP, A = Announced,
       S = Stale, E = Error
origin validation state: N = not-found, V = valid, ! = invalid
aspa validation state: ? = unknown, V = valid, ! = invalid
origin: i = IGP, e = EGP, ? = Incomplete

flags  vs destination          gateway          lpref   med aspath origin
*>    V-! 2606:b0c0:b00b::/48  2001:db8::252    100     0 8271 6939 61138 945 i
*m    V-! 2606:b0c0:b00b::/48  2001:db8::253    100     0 8271 6939 61138 945 i

So with this I found the first two invalid ASPA paths, time to adjust the
filters :)
-- 
:wq Claudio

Index: usr.sbin/bgpd/bgpd.conf.5
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.conf.5,v
retrieving revision 1.229
diff -u -p -r1.229 bgpd.conf.5
--- usr.sbin/bgpd/bgpd.conf.5   20 Jan 2023 15:41:33 -0000      1.229
+++ usr.sbin/bgpd/bgpd.conf.5   24 Jan 2023 13:10:37 -0000
@@ -1538,6 +1538,14 @@ deny from any { AS { 1, 2, 3 }, source-a
 .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
Index: usr.sbin/bgpd/bgpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
retrieving revision 1.459
diff -u -p -r1.459 bgpd.h
--- usr.sbin/bgpd/bgpd.h        24 Jan 2023 11:28:41 -0000      1.459
+++ usr.sbin/bgpd/bgpd.h        24 Jan 2023 13:10:37 -0000
@@ -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;
Index: usr.sbin/bgpd/parse.y
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v
retrieving revision 1.439
diff -u -p -r1.439 parse.y
--- usr.sbin/bgpd/parse.y       20 Jan 2023 15:41:33 -0000      1.439
+++ usr.sbin/bgpd/parse.y       24 Jan 2023 13:10:37 -0000
@@ -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 <v.number>              NUMBER
 %type  <v.number>              asnumber as4number as4number_any optnumber
 %type  <v.number>              espah family safi restart origincode nettype
-%type  <v.number>              yesno inout restricted validity expires enforce
+%type  <v.number>              yesno inout restricted expires enforce
+%type  <v.number>              validity aspa_validity
 %type  <v.number>              addpathextra addpathmax
 %type  <v.string>              string
 %type  <v.addr>                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},
Index: usr.sbin/bgpd/printconf.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/printconf.c,v
retrieving revision 1.162
diff -u -p -r1.162 printconf.c
--- usr.sbin/bgpd/printconf.c   20 Jan 2023 15:41:33 -0000      1.162
+++ usr.sbin/bgpd/printconf.c   24 Jan 2023 13:10:37 -0000
@@ -944,6 +944,22 @@ print_rule(struct bgpd_config *conf, str
                }
        }
 
+       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);
Index: usr.sbin/bgpd/rde.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
retrieving revision 1.590
diff -u -p -r1.590 rde.c
--- usr.sbin/bgpd/rde.c 24 Jan 2023 11:28:41 -0000      1.590
+++ usr.sbin/bgpd/rde.c 24 Jan 2023 13:10:37 -0000
@@ -103,7 +103,8 @@ static void  network_dump_upcall(struct 
 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
        }
        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 *p
        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)) {
@@ -4543,6 +4546,31 @@ ovs_match(struct prefix *p, uint32_t fla
                        break;
                case ROA_NOTFOUND:
                        if (!(flag & F_CTL_OVS_NOTFOUND))
+                               return 0;
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       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:
Index: usr.sbin/bgpd/rde_filter.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde_filter.c,v
retrieving revision 1.132
diff -u -p -r1.132 rde_filter.c
--- usr.sbin/bgpd/rde_filter.c  24 Jan 2023 11:28:41 -0000      1.132
+++ usr.sbin/bgpd/rde_filter.c  24 Jan 2023 13:10:37 -0000
@@ -227,6 +227,11 @@ rde_filter_match(struct filter_rule *f, 
                        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)
Index: usr.sbin/bgpctl/bgpctl.8
===================================================================
RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.8,v
retrieving revision 1.103
diff -u -p -r1.103 bgpctl.8
--- usr.sbin/bgpctl/bgpctl.8    22 Dec 2022 19:53:24 -0000      1.103
+++ usr.sbin/bgpctl/bgpctl.8    24 Jan 2023 13:10:37 -0000
@@ -375,6 +375,8 @@ Show all entries with
 anywhere but rightmost.
 .It Cm ovs Pq Ic valid | not-found | invalid
 Show all entries with matching Origin Validation State (OVS).
+.It Cm avs Pq Ic valid | unknown | invalid
+Show all entries with matching ASAP Validation State (AVS).
 .El
 .Pp
 Additionally, the following
Index: usr.sbin/bgpctl/parser.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpctl/parser.c,v
retrieving revision 1.118
diff -u -p -r1.118 parser.c
--- usr.sbin/bgpctl/parser.c    10 Nov 2022 10:47:30 -0000      1.118
+++ usr.sbin/bgpctl/parser.c    24 Jan 2023 13:10:37 -0000
@@ -77,6 +77,7 @@ static const struct token t_show[];
 static const struct token t_show_summary[];
 static const struct token t_show_fib[];
 static const struct token t_show_rib[];
+static const struct token t_show_avs[];
 static const struct token t_show_ovs[];
 static const struct token t_show_mrt[];
 static const struct token t_show_mrt_file[];
@@ -181,6 +182,7 @@ static const struct token t_show_rib[] =
        { FLAG,         "in",           F_CTL_ADJ_IN,   t_show_rib},
        { FLAG,         "out",          F_CTL_ADJ_OUT,  t_show_rib},
        { KEYWORD,      "neighbor",     NONE,           t_show_rib_neigh},
+       { KEYWORD,      "avs",          NONE,           t_show_avs},
        { KEYWORD,      "ovs",          NONE,           t_show_ovs},
        { KEYWORD,      "path-id",      NONE,           t_show_rib_path},
        { KEYWORD,      "table",        NONE,           t_show_rib_rib},
@@ -188,6 +190,13 @@ static const struct token t_show_rib[] =
        { KEYWORD,      "memory",       SHOW_RIB_MEM,   NULL},
        { FAMILY,       "",             NONE,           t_show_rib},
        { PREFIX,       "",             NONE,           t_show_prefix},
+       { ENDTOKEN,     "",             NONE,           NULL}
+};
+
+static const struct token t_show_avs[] = {
+       { FLAG,         "valid" ,       F_CTL_AVS_VALID,        t_show_rib},
+       { FLAG,         "invalid",      F_CTL_AVS_INVALID,      t_show_rib},
+       { FLAG,         "unknonw",      F_CTL_AVS_UNKNOWN,      t_show_rib},
        { ENDTOKEN,     "",             NONE,           NULL}
 };
 

Reply via email to