On Mon, Apr 03, 2023 at 10:41:15AM +0200, Claudio Jeker wrote:
> Flowspec RFC 8955 and 8956 allows to propegate traffic filtering rules
> to other routers. The main use case is to drop DDoS traffic further
> upstream and by that reducing the impact of such denial of service
> attacks.
> 
> This diff only adds the needed plumbing to announce the MP capability for
> flowspec. Any flowspec UPDATE received will be silently ignored and there
> is no way to send anything. Still this is a first small step and more
> changes will follow to send flowspec rules.
> 
> The diff includes all the defines needed for flowspec.
> On top of this there is a small fix in rde_update_dispatch() to
> properly jump over unknown MP attributes (2 hunks).
> In rde_get_mp_nexthop() I moved the AID_VPN_IPv6 case around and used the
> same error message for lenght check in all cases. This is why the diff is
> a bit larger.
> 
> I successfully tested this against exabgp.

ok

Some minor comments:

> Index: bgpd.h

[...]

> @@ -1063,10 +1073,47 @@ 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" },        \

Perhaps keep the empty line before { 0 } here?

>       { 0 }                                                   \
>  }
>  
>  extern const struct ext_comm_pairs iana_ext_comms[];
> +
> +/* BGP flowspec defines RFC 8955 */

I'd also mention RFC 8956 since FLOWSPEC_TYPE_FLOW isn't in RFC 8955
(or add a comment to that define).

> +#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;

[...]

> Index: rde.c

[...]

> +     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);
> +             }
> +             totlen += nhlen + 1;
> +             return (totlen);

It's fine as it is, but since nhlen == 0 I was a bit taken aback.
Perhaps the previous two lines could be replaced with:

                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);
>  }

Reply via email to