Add first step of flowspec support. This adds the bits to establish a
authorclaudio <claudio@openbsd.org>
Mon, 3 Apr 2023 10:48:00 +0000 (10:48 +0000)
committerclaudio <claudio@openbsd.org>
Mon, 3 Apr 2023 10:48:00 +0000 (10:48 +0000)
connection with SAFI 133. Right now any sent UPDATE with SAFI 133 is
simply ignored. At the moment SAFI 134 (flowspec for L3VPN) is unsupported.
OK tb@

usr.sbin/bgpd/bgpd.8
usr.sbin/bgpd/bgpd.conf.5
usr.sbin/bgpd/bgpd.h
usr.sbin/bgpd/parse.y
usr.sbin/bgpd/rde.c
usr.sbin/bgpd/util.c

index 3103001..6b30444 100644 (file)
@@ -1,4 +1,4 @@
-.\" $OpenBSD: bgpd.8,v 1.77 2023/03/02 17:09:53 jmc Exp $
+.\" $OpenBSD: bgpd.8,v 1.78 2023/04/03 10:48:00 claudio Exp $
 .\"
 .\" Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
 .\"
@@ -14,7 +14,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: March 2 2023 $
+.Dd $Mdocdate: April 3 2023 $
 .Dt BGPD 8
 .Os
 .Sh NAME
@@ -478,6 +478,26 @@ has been started.
 .Re
 .Pp
 .Rs
+.%A C. Loibl
+.%A S. Hares
+.%A R. Raszuk
+.%A D. McPherson
+.%A M. Bacher
+.%D December 2020
+.%R RFC 8955
+.%T Dissemination of Flow Specification Rules
+.Re
+.Pp
+.Rs
+.%A C. Loibl
+.%A R. Raszuk
+.%A S. Hares
+.%D December 2020
+.%R RFC 8956
+.%T Dissemination of Flow Specification Rules for IPv6
+.Re
+.Pp
+.Rs
 .%A E. Chen
 .%A J. Scudder
 .%D July 2021
index 10cd3ba..cae44c6 100644 (file)
@@ -1,4 +1,4 @@
-.\" $OpenBSD: bgpd.conf.5,v 1.233 2023/03/13 18:31:54 jmc Exp $
+.\" $OpenBSD: bgpd.conf.5,v 1.234 2023/04/03 10:48:00 claudio Exp $
 .\"
 .\" Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
 .\" Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -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: March 13 2023 $
+.Dd $Mdocdate: April 3 2023 $
 .Dt BGPD.CONF 5
 .Os
 .Sh NAME
@@ -839,7 +839,7 @@ The neighbor properties are as follows:
 .It Xo
 .Ic announce
 .Pq Ic IPv4 Ns | Ns Ic IPv6
-.Pq Ic none Ns | Ns Ic unicast Ns | Ns Ic vpn
+.Pq Ic none Ns | Ns Ic unicast Ns | Ns Ic vpn | Ns Ic flowspec
 .Xc
 For the given address family, control which
 .Em subsequent address families
@@ -851,9 +851,11 @@ At the moment, only
 .Ic none ,
 which disables the announcement of that address family,
 .Ic unicast ,
-and
 .Ic vpn ,
-which allows the distribution of BGP MPLS VPNs, are supported.
+which allows the distribution of BGP MPLS VPNs, and
+.Ic flowspec ,
+which allows the distribution of Flow Specification Rules,
+are supported.
 .Pp
 The default is
 .Ic unicast
index 508d598..3bb27fd 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: bgpd.h,v 1.469 2023/03/29 14:35:38 claudio Exp $ */
+/*     $OpenBSD: bgpd.h,v 1.470 2023/04/03 10:48:00 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -152,11 +152,13 @@ enum reconf_action {
 #define        AFI_IPv6        2
 
 /* Subsequent Address Family Identifier as per RFC 4760 */
-#define        SAFI_NONE       0
-#define        SAFI_UNICAST    1
-#define        SAFI_MULTICAST  2
-#define        SAFI_MPLS       4
-#define        SAFI_MPLSVPN    128
+#define        SAFI_NONE               0
+#define        SAFI_UNICAST            1
+#define        SAFI_MULTICAST          2
+#define        SAFI_MPLS               4
+#define        SAFI_MPLSVPN            128
+#define        SAFI_FLOWSPEC           133
+#define        SAFI_VPNFLOWSPEC        134
 
 struct aid {
        uint16_t         afi;
@@ -172,7 +174,9 @@ extern const struct aid aid_vals[];
 #define        AID_INET6       2
 #define        AID_VPN_IPv4    3
 #define        AID_VPN_IPv6    4
-#define        AID_MAX         5
+#define        AID_FLOWSPECv4  5
+#define        AID_FLOWSPECv6  6
+#define        AID_MAX         7
 #define        AID_MIN         1       /* skip AID_UNSPEC since that is a dummy */
 
 #define AID_VALS       {                                       \
@@ -181,7 +185,9 @@ extern const struct aid aid_vals[];
        { AFI_IPv4, AF_INET, SAFI_UNICAST, "IPv4 unicast" },    \
        { AFI_IPv6, AF_INET6, SAFI_UNICAST, "IPv6 unicast" },   \
        { AFI_IPv4, AF_INET, SAFI_MPLSVPN, "IPv4 vpn" },        \
-       { AFI_IPv6, AF_INET6, SAFI_MPLSVPN, "IPv6 vpn" }        \
+       { AFI_IPv6, AF_INET6, SAFI_MPLSVPN, "IPv6 vpn" },       \
+       { AFI_IPv4, AF_INET, SAFI_FLOWSPEC, "IPv4 flowspec" },  \
+       { AFI_IPv6, AF_INET6, SAFI_FLOWSPEC, "IPv6 flowspec" }, \
 }
 
 #define BGP_MPLS_BOS   0x01
@@ -1004,18 +1010,22 @@ struct filter_peers {
 #define EXT_COMMUNITY_IANA             0x80
 #define EXT_COMMUNITY_NON_TRANSITIVE   0x40
 #define EXT_COMMUNITY_VALUE            0x3f
-/* extended types transitive */
+/* extended transitive types */
 #define EXT_COMMUNITY_TRANS_TWO_AS     0x00    /* 2 octet AS specific */
 #define EXT_COMMUNITY_TRANS_IPV4       0x01    /* IPv4 specific */
 #define EXT_COMMUNITY_TRANS_FOUR_AS    0x02    /* 4 octet AS specific */
 #define EXT_COMMUNITY_TRANS_OPAQUE     0x03    /* opaque ext community */
 #define EXT_COMMUNITY_TRANS_EVPN       0x06    /* EVPN RFC 7432 */
-/* extended types non-transitive */
+/* extended non-transitive types */
 #define EXT_COMMUNITY_NON_TRANS_TWO_AS 0x40    /* 2 octet AS specific */
 #define EXT_COMMUNITY_NON_TRANS_IPV4   0x41    /* IPv4 specific */
 #define EXT_COMMUNITY_NON_TRANS_FOUR_AS        0x42    /* 4 octet AS specific */
 #define EXT_COMMUNITY_NON_TRANS_OPAQUE 0x43    /* opaque ext community */
 #define EXT_COMMUNITY_UNKNOWN          -1
+/* generic transitive types */
+#define EXT_COMMUNITY_GEN_TWO_AS       0x80    /* 2 octet AS specific */
+#define EXT_COMMUNITY_GEN_IPV4         0x81    /* IPv4 specific */
+#define EXT_COMMUNITY_GEN_FOUR_AS      0x82    /* 4 octet AS specific */
 
 /* BGP Origin Validation State Extended Community RFC 8097 */
 #define EXT_COMMUNITY_SUBTYPE_OVS      0
@@ -1063,11 +1073,49 @@ struct ext_comm_pairs {
        { EXT_COMMUNITY_TRANS_EVPN, 0x01, "esi-lab" },          \
        { EXT_COMMUNITY_TRANS_EVPN, 0x02, "esi-rt" },           \
                                                                \
+       { EXT_COMMUNITY_GEN_TWO_AS, 0x06, "flow-rate" },        \
+       { EXT_COMMUNITY_GEN_TWO_AS, 0x0c, "flow-pps" },         \
+       { EXT_COMMUNITY_GEN_TWO_AS, 0x07, "flow-action" },      \
+       { EXT_COMMUNITY_GEN_TWO_AS, 0x08, "flow-rt-redir" },    \
+       { EXT_COMMUNITY_GEN_IPV4,   0x08, "flow-rt-redir" },    \
+       { EXT_COMMUNITY_GEN_FOUR_AS, 0x08, "flow-rt-redir" },   \
+       { EXT_COMMUNITY_GEN_TWO_AS, 0x09, "flow-dscp" },        \
+                                                               \
        { 0 }                                                   \
 }
 
 extern const struct ext_comm_pairs iana_ext_comms[];
 
+/* BGP flowspec defines RFC 8955 and 8956 */
+#define FLOWSPEC_LEN_LIMIT             0xf0
+#define FLOWSPEC_OP_EOL                        0x80
+#define FLOWSPEC_OP_AND                        0x40
+#define FLOWSPEC_OP_LEN_MASK           0x30
+#define FLOWSPEC_OP_LEN_SHIFT          4
+#define FLOWSPEC_OP_LEN(op)                                    \
+       (1 << (((op) & FLOWSPEC_OP_LEN_MASK) >> FLOWSPEC_OP_LEN_SHIFT))
+#define FLOWSPEC_OP_NUM_LT             0x04
+#define FLOWSPEC_OP_NUM_GT             0x02
+#define FLOWSPEC_OP_NUM_EQ             0x01
+#define FLOWSPEC_OP_BIT_NOT            0x02
+#define FLOWSPEC_OP_BIT_MATCH          0x01
+
+#define FLOWSPEC_TYPE_MIN              1
+#define FLOWSPEC_TYPE_DEST             1
+#define FLOWSPEC_TYPE_SOURCE           2
+#define FLOWSPEC_TYPE_PROTO            3
+#define FLOWSPEC_TYPE_PORT             4
+#define FLOWSPEC_TYPE_DST_PORT         5
+#define FLOWSPEC_TYPE_SRC_PORT         6
+#define FLOWSPEC_TYPE_ICMP_TYPE                7
+#define FLOWSPEC_TYPE_ICMP_CODE                8
+#define FLOWSPEC_TYPE_TCP_FLAGS                9
+#define FLOWSPEC_TYPE_PKT_LEN          10
+#define FLOWSPEC_TYPE_DSCP             11
+#define FLOWSPEC_TYPE_FRAG             12
+#define FLOWSPEC_TYPE_FLOW             13
+#define FLOWSPEC_TYPE_MAX              13
+
 struct filter_prefix {
        struct bgpd_addr        addr;
        uint8_t                 op;
index 2954734..b3f1739 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: parse.y,v 1.442 2023/03/09 13:12:19 claudio Exp $ */
+/*     $OpenBSD: parse.y,v 1.443 2023/04/03 10:48:00 claudio Exp $ */
 
 /*
  * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -213,7 +213,7 @@ typedef struct {
 %}
 
 %token AS ROUTERID HOLDTIME YMIN LISTEN ON FIBUPDATE FIBPRIORITY RTABLE
-%token NONE UNICAST VPN RD EXPORT EXPORTTRGT IMPORTTRGT DEFAULTROUTE
+%token NONE UNICAST VPN FLOWSPEC RD EXPORT EXPORTTRGT IMPORTTRGT DEFAULTROUTE
 %token RDE RIB EVALUATE IGNORE COMPARE RTR PORT
 %token GROUP NEIGHBOR NETWORK
 %token EBGP IBGP
@@ -1995,6 +1995,7 @@ family            : IPV4  { $$ = AFI_IPv4; }
 safi           : NONE          { $$ = SAFI_NONE; }
                | UNICAST       { $$ = SAFI_UNICAST; }
                | VPN           { $$ = SAFI_MPLSVPN; }
+               | FLOWSPEC      { $$ = SAFI_FLOWSPEC; }
                ;
 
 nettype                : STATIC { $$ = 1; }
@@ -3200,6 +3201,7 @@ lookup(char *s)
                { "ext-community",      EXTCOMMUNITY},
                { "fib-priority",       FIBPRIORITY},
                { "fib-update",         FIBUPDATE},
+               { "flowspec",           FLOWSPEC},
                { "from",               FROM},
                { "group",              GROUP},
                { "holdtime",           HOLDTIME},
index 8d7897e..9a7ff40 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rde.c,v 1.598 2023/03/28 08:32:42 claudio Exp $ */
+/*     $OpenBSD: rde.c,v 1.599 2023/04/03 10:48:00 claudio Exp $ */
 
 /*
  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -1474,9 +1474,14 @@ rde_update_dispatch(struct rde_peer *peer, struct imsg *imsg)
                                        goto done;
                                }
                                break;
+                       case AID_FLOWSPECv4:
+                       case AID_FLOWSPECv6:
+                               /* ignore flowspec for now */
                        default:
                                /* ignore unsupported multiprotocol AF */
-                               break;
+                               mpp += mplen;
+                               mplen = 0;
+                               continue;
                        }
 
                        mpp += pos;
@@ -1674,9 +1679,14 @@ rde_update_dispatch(struct rde_peer *peer, struct imsg *imsg)
                                        goto done;
                                }
                                break;
+                       case AID_FLOWSPECv4:
+                       case AID_FLOWSPECv6:
+                               /* ignore flowspec for now */
                        default:
                                /* ignore unsupported multiprotocol AF */
-                               break;
+                               mpp += mplen;
+                               mplen = 0;
+                               continue;
                        }
 
                        mpp += pos;
@@ -2314,7 +2324,6 @@ rde_get_mp_nexthop(u_char *data, uint16_t len, uint8_t aid,
                return (-1);
 
        memset(&nexthop, 0, sizeof(nexthop));
-       nexthop.aid = aid;
        switch (aid) {
        case AID_INET6:
                /*
@@ -2326,19 +2335,11 @@ rde_get_mp_nexthop(u_char *data, uint16_t len, uint8_t aid,
                 * traffic.
                 */
                if (nhlen != 16 && nhlen != 32) {
-                       log_warnx("bad multiprotocol nexthop, bad size");
-                       return (-1);
-               }
-               memcpy(&nexthop.v6.s6_addr, data, 16);
-               break;
-       case AID_VPN_IPv6:
-               if (nhlen != 24) {
-                       log_warnx("bad multiprotocol nexthop, bad size %d",
+                       log_warnx("bad %s nexthop, bad size %d", aid2str(aid),
                            nhlen);
                        return (-1);
                }
-               memcpy(&nexthop.v6, data + sizeof(uint64_t),
-                   sizeof(nexthop.v6));
+               memcpy(&nexthop.v6.s6_addr, data, 16);
                nexthop.aid = AID_INET6;
                break;
        case AID_VPN_IPv4:
@@ -2356,24 +2357,43 @@ rde_get_mp_nexthop(u_char *data, uint16_t len, uint8_t aid,
                 * AID_VPN_IPv4 in nexthop and kroute.
                 */
                if (nhlen != 12) {
-                       log_warnx("bad multiprotocol nexthop, bad size");
+                       log_warnx("bad %s nexthop, bad size %d", aid2str(aid),
+                           nhlen);
                        return (-1);
                }
                nexthop.aid = AID_INET;
                memcpy(&nexthop.v4, data + sizeof(uint64_t),
                    sizeof(nexthop.v4));
                break;
+       case AID_VPN_IPv6:
+               if (nhlen != 24) {
+                       log_warnx("bad %s nexthop, bad size %d", aid2str(aid),
+                           nhlen);
+                       return (-1);
+               }
+               memcpy(&nexthop.v6, data + sizeof(uint64_t),
+                   sizeof(nexthop.v6));
+               nexthop.aid = AID_INET6;
+               break;
+       case AID_FLOWSPECv4:
+       case AID_FLOWSPECv6:
+               /* nexthop must be 0 and ignored for flowspec */
+               if (nhlen != 0) {
+                       log_warnx("bad %s nexthop, bad size %d", aid2str(aid),
+                           nhlen);
+                       return (-1);
+               }
+               /* also ignore reserved (old SNPA) field as per RFC4760 */
+               return (totlen + 1);
        default:
                log_warnx("bad multiprotocol nexthop, bad AID");
                return (-1);
        }
 
-       nexthop_unref(state->nexthop);  /* just to be sure */
        state->nexthop = nexthop_get(&nexthop);
 
        /* ignore reserved (old SNPA) field as per RFC4760 */
        totlen += nhlen + 1;
-       data += nhlen + 1;
 
        return (totlen);
 }
index 85f15a6..e11755a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: util.c,v 1.75 2023/03/30 14:47:25 claudio Exp $ */
+/*     $OpenBSD: util.c,v 1.76 2023/04/03 10:48:00 claudio Exp $ */
 
 /*
  * Copyright (c) 2006 Claudio Jeker <claudio@openbsd.org>
@@ -918,6 +918,9 @@ addr2sa(const struct bgpd_addr *addr, uint16_t port, socklen_t *len)
                sa_in6->sin6_scope_id = addr->scope_id;
                *len = sizeof(struct sockaddr_in6);
                break;
+       case AID_FLOWSPECv4:
+       case AID_FLOWSPECv6:
+               return (NULL);
        }
 
        return ((struct sockaddr *)&ss);