nice!

Job Snijders([email protected]) on 2017.03.28 14:12:42 -0500:
> Dear all,
> 
> BGP Origin Validation State communities are non-transitive opaque
> extended communities to carry the origination Autonomous System
> validation state inside an autonomous system. IBGP speakers that
> receive this validation state can configure local policies that allow it
> to influence their decision process. https://tools.ietf.org/html/rfc8097
> 
> This patch allows to configurations such as the below. This
> configuration was generated based on an external validation source (in
> this case RPKI) and allows manipulation through well-known identifiers.
> 
>     match from any \
>         set { ext-community bovs not-found \

do other implementations call this "bovs"?
dont get me wrong, i think junipers origin-validation-state-valid
is too long.


>               ext-community delete bovs invalid \
>               ext-community delete bovs valid }
>     match from any \
>         prefix 2a02:898::/32 or-longer \
>         set { ext-community bovs invalid }
>     match from any \
>         prefix 2a02:898::/32 source-as 8283 \
>         set { ext-community bovs valid }
>     match from any ext-community bovs valid \

So if we want to implement rfc6810/rfc6811 (BGP Prefix Origin Validation),
would this syntax become redundant? Should we not implement 

  match from any validation-state valid ...

at this point, and hide the community behind that? And when we get Origin
Validation, its transparent in the ruleset where the information came from,
from our own lookup or through the community.

Just a thought, not something that makes the config a bit cleaner.

>         set { ext-community delete bovs invalid \
>               ext-community delete bovs not-found }
>     match from any ext-community bovs invalid \
>         set { ext-community delete bovs not-found }
> 
> The following new mapping exists between keywords and Extended BGP
> Communities:
> 
>       keywords        | ext type | subtype | value
>       ----------------+----------+---------+-------
>       bovs valid      |   0x2b   |   0x0   |  0x0
>       bovs not-found  |   0x2b   |   0x0   |  0x1
>       bovs invalid    |   0x2b   |   0x0   |  0x2
> 
> [job@kiera ~]$ bgpctl show rib detail 2a02:898::/32 longer-prefixes
> 
> BGP routing table entry for 2a02:898::/32
>     2914 8283
>     Nexthop 2001:728:0:1000::2 (via ???) from AS15562_scarlett_IPv6 
> (165.254.255.1)
>     Origin IGP, metric 0, localpref 100, weight 0, internal
>     Last update: 00:00:49 ago
>     Communities: 2914:420 2914:1206 2914:2203 2914:3200 65504:8283
>     Ext. communities: bovs valid
> 
> [job@kiera ~]$
> 
> Index: bgpctl/bgpctl.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.c,v
> retrieving revision 1.193
> diff -u -p -r1.193 bgpctl.c
> --- bgpctl/bgpctl.c   23 Jan 2017 23:38:51 -0000      1.193
> +++ bgpctl/bgpctl.c   28 Mar 2017 19:01:33 -0000
> @@ -1585,7 +1585,7 @@ show_ext_community(u_char *data, u_int16
>       struct in_addr  ip;
>       u_int32_t       as4, u32;
>       u_int16_t       i, as2, u16;
> -     u_int8_t        type, subtype;
> +     u_int8_t        type, subtype, state;
>  
>       if (len & 0x7)
>               return;
> @@ -1618,6 +1618,13 @@ show_ext_community(u_char *data, u_int16
>                       ext = betoh64(ext) & 0xffffffffffffLL;
>                       printf("%s 0x%llx", log_ext_subtype(subtype), ext);
>                       break;
> +             case EXT_COMMUNITY_NON_TRANS_OPAQUE:
> +                     if (subtype == EXT_COMMUNITY_VALIDATION_STATE) {
> +                             state = data[i + 7];
> +                             printf("%s %s", log_ext_subtype(subtype),
> +                                 log_ext_bovs_value(state));
> +                             break;
> +                     }
>               default:
>                       memcpy(&ext, data + i, sizeof(ext));
>                       printf("0x%llx", betoh64(ext));
> Index: bgpd/bgpd.8
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/bgpd.8,v
> retrieving revision 1.52
> diff -u -p -r1.52 bgpd.8
> --- bgpd/bgpd.8       19 Feb 2017 11:38:24 -0000      1.52
> +++ bgpd/bgpd.8       28 Mar 2017 19:01:33 -0000
> @@ -390,6 +390,17 @@ control socket
>  .%R draft-ietf-idr-shutdown
>  .%T BGP Administrative Shutdown Communication
>  .Re
> +.Pp
> +.Rs
> +.%A P. Mohapatra
> +.%A K. Patel
> +.%A J. Scudder
> +.%A D. Ward
> +.%A R. Bush
> +.%D March 2017
> +.%R RFC 8097
> +.%T BGP Prefix Origin Validation State Extended Community
> +.Re
>  .Sh HISTORY
>  The
>  .Nm
> Index: bgpd/bgpd.conf.5
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/bgpd.conf.5,v
> retrieving revision 1.152
> diff -u -p -r1.152 bgpd.conf.5
> --- bgpd/bgpd.conf.5  13 Jan 2017 18:59:12 -0000      1.152
> +++ bgpd/bgpd.conf.5  28 Mar 2017 19:01:33 -0000
> @@ -1195,6 +1195,11 @@ which is expanded to the current neighbo
>  .Ic ext-community
>  .Ar subtype Ar numvalue
>  .Xc
> +.It Xo
> +.Ic ext-community
> +.Ar bovs
> +.Pq Ic valid | not-found | invalid
> +.Xc
>  This rule applies only to
>  .Em UPDATES
>  where the
> @@ -1456,6 +1461,11 @@ to do wildcard matching.
>  .Ic ext-community Op Ar delete
>  .Ar subtype Ar numvalue
>  .Xc
> +.It Xo
> +.Ic ext-community Op Ar delete
> +.Ar bovs
> +.Pq Ic valid | not-found | invalid
> +.Xc
>  Set or delete the
>  .Em Extended Community
>  AS path attribute.
> @@ -1481,6 +1491,7 @@ odi      OSPF Domain Identifier
>  ort      OSPF Route Type
>  ori      OSPF Router ID
>  bdc      BGP Data Collection
> +bovs     BGP Origin Validation State
>  .Ed
>  .Pp
>  Not all type and subtype value pairs are allowed by IANA and the parser
> Index: bgpd/bgpd.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
> retrieving revision 1.300
> diff -u -p -r1.300 bgpd.h
> --- bgpd/bgpd.h       25 Jan 2017 00:11:07 -0000      1.300
> +++ bgpd/bgpd.h       28 Mar 2017 19:01:33 -0000
> @@ -755,7 +755,8 @@ struct filter_peers {
>  #define EXT_COMMUNITY_TWO_AS         0       /* 2 octet AS specific */
>  #define EXT_COMMUNITY_IPV4           1       /* IPv4 specific */
>  #define EXT_COMMUNITY_FOUR_AS                2       /* 4 octet AS specific 
> */
> -#define EXT_COMMUNITY_OPAQUE         3       /* opaque ext community */
> +#define EXT_COMMUNITY_OPAQUE         3       /* transitive opaque ext */
> +#define EXT_COMMUNITY_NON_TRANS_OPAQUE 43    /* non-transitive opaque ext */
>  /* sub types */
>  #define EXT_COMMUNITY_ROUTE_TGT              2       /* RFC 4360 & RFC4364 */
>  #define EXT_COMMUNITY_ROUTE_ORIG     3       /* RFC 4360 & RFC4364 */
> @@ -763,6 +764,11 @@ struct filter_peers {
>  #define EXT_COMMUNITY_OSPF_RTR_TYPE  6       /* RFC 4577 */
>  #define EXT_COMMUNITY_OSPF_RTR_ID    7       /* RFC 4577 */
>  #define EXT_COMMUNITY_BGP_COLLECT    8       /* RFC 4384 */
> +#define EXT_COMMUNITY_VALIDATION_STATE       0       /* RFC 8097 */
> +/* RFC 8097 validation states */
> +#define EXT_COMMUNITY_VALIDATION_STATE_VALID 0
> +#define EXT_COMMUNITY_VALIDATION_STATE_NOTFOUND      1
> +#define EXT_COMMUNITY_VALIDATION_STATE_INVALID       2
>  /* other handy defines */
>  #define EXT_COMMUNITY_OPAQUE_MAX     0xffffffffffffULL
>  #define EXT_COMMUNITY_FLAG_VALID     0x01
> @@ -783,7 +789,8 @@ struct ext_comm_pairs {
>       { EXT_COMMUNITY_IPV4, EXT_COMMUNITY_ROUTE_TGT, 0 },             \
>       { EXT_COMMUNITY_IPV4, EXT_COMMUNITY_ROUTE_ORIG, 0 },            \
>       { EXT_COMMUNITY_IPV4, EXT_COMMUNITY_OSPF_RTR_ID, 0 },           \
> -     { EXT_COMMUNITY_OPAQUE, EXT_COMMUNITY_OSPF_RTR_TYPE, 0 }        \
> +     { EXT_COMMUNITY_OPAQUE, EXT_COMMUNITY_OSPF_RTR_TYPE, 0 },       \
> +     { EXT_COMMUNITY_NON_TRANS_OPAQUE, EXT_COMMUNITY_VALIDATION_STATE, 0 }   
> \
>  }
>  
>  
> @@ -1067,6 +1074,7 @@ const char      *log_sockaddr(struct sockaddr
>  const char   *log_as(u_int32_t);
>  const char   *log_rd(u_int64_t);
>  const char   *log_ext_subtype(u_int8_t);
> +const char   *log_ext_bovs_value(u_int8_t);
>  const char   *log_shutcomm(const char *);
>  int           aspath_snprint(char *, size_t, void *, u_int16_t);
>  int           aspath_asprint(char **, void *, u_int16_t);
> Index: bgpd/parse.y
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v
> retrieving revision 1.298
> diff -u -p -r1.298 parse.y
> --- bgpd/parse.y      22 Feb 2017 13:55:14 -0000      1.298
> +++ bgpd/parse.y      28 Mar 2017 19:01:33 -0000
> @@ -145,6 +145,7 @@ int                parsecommunity(struct filter_commu
>  int64_t       getlargecommunity(char *);
>  int           parselargecommunity(struct filter_largecommunity *, char *);
>  int           parsesubtype(char *);
> +int           parse_bgp_validation_state(char *);
>  int           parseextvalue(char *, u_int32_t *);
>  int           parseextcommunity(struct filter_extcommunity *, char *,
>                   char *);
> @@ -3022,11 +3023,31 @@ parselargecommunity(struct filter_largec
>  }
>  
>  int
> +parse_bgp_validation_state(char *state)
> +{
> +     /* this has to be sorted always */
> +     static const struct keywords keywords[] = {
> +             { "invalid",    EXT_COMMUNITY_VALIDATION_STATE_INVALID },
> +             { "not-found",  EXT_COMMUNITY_VALIDATION_STATE_NOTFOUND },
> +             { "valid",      EXT_COMMUNITY_VALIDATION_STATE_VALID }
> +     };
> +     const struct keywords   *p;
> +     p = bsearch(state, keywords, sizeof(keywords)/sizeof(keywords[0]),
> +             sizeof(keywords[0]), kw_cmp);
> +
> +     if (p)
> +             return (p->k_val);
> +     else
> +             return (-1);
> +}
> +
> +int
>  parsesubtype(char *type)
>  {
>       /* this has to be sorted always */
>       static const struct keywords keywords[] = {
>               { "bdc",        EXT_COMMUNITY_BGP_COLLECT },
> +             { "bovs",       EXT_COMMUNITY_VALIDATION_STATE },
>               { "odi",        EXT_COMMUNITY_OSPF_DOM_ID },
>               { "ori",        EXT_COMMUNITY_OSPF_RTR_ID },
>               { "ort",        EXT_COMMUNITY_OSPF_RTR_TYPE },
> @@ -3100,15 +3121,22 @@ parseextcommunity(struct filter_extcommu
>       u_int32_t        uval;
>       char            *p, *ep;
>       unsigned int     i;
> -     int              type, subtype;
> +     int              type, state, subtype;
>  
>       if ((subtype = parsesubtype(t)) == -1) {
>               yyerror("Bad ext-community unknown type");
>               return (-1);
>       }
>  
> -     if ((p = strchr(s, ':')) == NULL) {
> -             type = EXT_COMMUNITY_OPAQUE,
> +     if (subtype == EXT_COMMUNITY_VALIDATION_STATE) {
> +             if ((state = parse_bgp_validation_state(s)) == -1) {
> +                     yyerror("Invalid BGP Origin Validation State 
> Community");
> +                     return(-1);
> +             }
> +             type = EXT_COMMUNITY_NON_TRANS_OPAQUE;
> +             c->data.ext_opaq = state;
> +     } else if ((p = strchr(s, ':')) == NULL) {
> +             type = EXT_COMMUNITY_OPAQUE;
>               errno = 0;
>               ullval = strtoull(s, &ep, 0);
>               if (s[0] == '\0' || *ep != '\0') {
> Index: bgpd/printconf.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/printconf.c,v
> retrieving revision 1.100
> diff -u -p -r1.100 printconf.c
> --- bgpd/printconf.c  24 Jan 2017 04:22:42 -0000      1.100
> +++ bgpd/printconf.c  28 Mar 2017 19:01:34 -0000
> @@ -149,6 +149,7 @@ print_extcommunity(struct filter_extcomm
>                   log_as(c->data.ext_as4.as4), c->data.ext_as.val);
>               break;
>       case EXT_COMMUNITY_OPAQUE:
> +     case EXT_COMMUNITY_NON_TRANS_OPAQUE:
>               printf("%s 0x%llx ", log_ext_subtype(c->subtype),
>                   c->data.ext_opaq);
>               break;
> Index: bgpd/util.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/util.c,v
> retrieving revision 1.24
> diff -u -p -r1.24 util.c
> --- bgpd/util.c       24 Jan 2017 04:22:42 -0000      1.24
> +++ bgpd/util.c       28 Mar 2017 19:01:34 -0000
> @@ -154,11 +154,32 @@ log_ext_subtype(u_int8_t subtype)
>               return ("ori"); /* ospf router id */
>       case EXT_COMMUNITY_BGP_COLLECT:
>               return ("bdc"); /* bgp data collection */
> +     case EXT_COMMUNITY_VALIDATION_STATE:
> +             return ("bovs"); /* RFC 8097 */

spell out what bovs means?

>       default:
>               snprintf(etype, sizeof(etype), "[%u]", subtype);
>               return (etype);
>       }
>  }
> +
> +const char *
> +log_ext_bovs_value(u_int8_t value)
> +{
> +     static char s[6];
> +
> +     switch (value) {
> +     case EXT_COMMUNITY_VALIDATION_STATE_VALID:
> +             return ("valid");
> +     case EXT_COMMUNITY_VALIDATION_STATE_NOTFOUND:
> +             return ("not-found");
> +     case EXT_COMMUNITY_VALIDATION_STATE_INVALID:
> +             return ("invalid");
> +     default:
> +             snprintf(s, sizeof(s), "[%u?]", value);
> +             return (s);
> +     }
> +}

this function is only used in bgpctl. it should be moved there.
we are trying to get rid of the reacharound *ctl programs are doing,
so you should not add another function.

otherwise ok to go in after 6.1.

> +
>  
>  const char *
>  log_shutcomm(const char *communication) {
> 

Reply via email to