]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Flowspec: Max tcp mask length is 12 bits
authorOndrej Zajicek (work) <santiago@crfreenet.org>
Wed, 26 Apr 2017 15:13:45 +0000 (17:13 +0200)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Wed, 26 Apr 2017 15:13:45 +0000 (17:13 +0200)
doc/bird.conf.example2
doc/bird.sgml
lib/flowspec.c
lib/flowspec.h

index a4081f14b1a0aa01d57821a796c9c7e63dc34954..51fcfb646e5b7a072e546794baa6f17f00742ebc 100644 (file)
@@ -105,27 +105,27 @@ protocol static flowstat4 {
                proto = 0x12;
                sport > 0x5678 && < 0x9abc || 0xdef0 || 0x1234,0x5678,0x9abc..0xdef0;
                dport = 50;
-               tcp flags 0xabcd/0xbbdd;
+               tcp flags 0x000/0xf00;
        };
 
        route flow4 {
                dst 12.0.0.0/32;
-               tcp flags ! 0 / 0x9999;
+               tcp flags ! 0/0x999;
        };
 
        route flow4 {
                dst 220.0.254.0/24;
-               tcp flags 0x99 / 0x9999;
+               tcp flags 0x99/0x999;
        };
 
        route flow4 {
                dst 220.0.254.192/28;
-               tcp flags !0xffff / 0xFFFF;
+               tcp flags ! 0xfff/0xfff;
        };
 
        route flow4 {
                dst 15.0.0.0/8;
-               tcp flags !0x9999/0x9999;
+               tcp flags ! 0x999/0x999;
        };
 }
 
index 0e072dd2f9d3d3bf1c917d0df35135cd6231386b..4bbcb871cf097878e07f0a87828aa1d973ad7a89 100644 (file)
@@ -768,7 +768,8 @@ logical operators <cf/&&/ or <cf/||/. Allowed relational operators are <cf/=/,
 
        <tag><label id="flow-tcp-flags">tcp flags <m/bitmask-match/</tag>
        Set a matching bitmask for TCP header flags (aka control bits) (e.g.
-       <cf>tcp flags 0x03/0x0f;</cf>).
+       <cf>tcp flags 0x03/0x0f;</cf>). The maximum length of mask is 12 bits
+       (0xfff).
 
        <tag><label id="flow-length">length <m/numbers-match/</tag>
        Set a matching packet length (e.g. <cf>length > 1500;</cf>)
index 764b648e6cf351e804235b8501a643a6d623889e..0b863ed958f7ef7fe5c4722fd9115f03da9c5a75 100644 (file)
@@ -259,7 +259,8 @@ static const char* flow_validated_state_str_[] = {
   [FLOW_ST_BAD_TYPE_ORDER]             = "Bad component order",
   [FLOW_ST_AND_BIT_SHOULD_BE_UNSET]    = "The AND-bit should be unset",
   [FLOW_ST_ZERO_BIT_SHOULD_BE_UNSED]   = "The Zero-bit should be unset",
-  [FLOW_ST_DEST_PREFIX_REQUIRED]       = "Destination prefix is required to define",
+  [FLOW_ST_DEST_PREFIX_REQUIRED]       = "Destination prefix is missing",
+  [FLOW_ST_INVALID_TCP_FLAGS]          = "TCP flags exceeding 0xfff",
   [FLOW_ST_CANNOT_USE_DONT_FRAGMENT]    = "Cannot use Don't fragment flag in IPv6 flow"
 };
 
@@ -332,8 +333,11 @@ flow_check_cf_bmk_values(struct flow_builder *fb, u8 neg, u32 val, u32 mask)
   if (neg && !(val == 0 || val == mask))
     cf_error("For negation, value must be zero or bitmask");
 
-  if (fb->this_type == FLOW_TYPE_FRAGMENT && fb->ipv6 && (mask & 0x01))
-    cf_error("Invalid mask 0x%x. Bit 0 must be 0", mask);
+  if ((fb->this_type == FLOW_TYPE_TCP_FLAGS) && (mask & 0xf000))
+    cf_error("Invalid mask 0x%x, must not exceed 0xfff", mask);
+
+  if ((fb->this_type == FLOW_TYPE_FRAGMENT) && fb->ipv6 && (mask & 0x01))
+    cf_error("Invalid mask 0x%x, bit 0 must be 0", mask);
 
   if (val & ~mask)
     cf_error("Value 0x%x outside bitmask 0x%x", val, mask);
@@ -456,15 +460,20 @@ flow_validate(const byte *nlri, uint len, int ipv6)
            return FLOW_ST_ZERO_BIT_SHOULD_BE_UNSED;
        }
 
-       /* Bit-7 must be 0 [draft-ietf-idr-flow-spec-v6] */
-       if (ipv6 && type == FLOW_TYPE_FRAGMENT && (*(pos+1) & 0x01))
-         return FLOW_ST_CANNOT_USE_DONT_FRAGMENT;
-       /* XXX: Could be a fragment component encoded in 2-bytes? */
-
        /* Value length of operator */
        uint len = get_value_length(pos);
        if (len > flow_max_value_length(type, ipv6))
          return FLOW_ST_EXCEED_MAX_VALUE_LENGTH;
+
+       /* TCP Flags component must not check highest nibble (just 12 valid bits) */
+       if ((type == FLOW_TYPE_TCP_FLAGS) && (len == 2) && (pos[1] & 0xf0))
+         return FLOW_ST_INVALID_TCP_FLAGS;
+
+       /* Bit-7 must be 0 [draft-ietf-idr-flow-spec-v6] */
+       if ((type == FLOW_TYPE_FRAGMENT) && ipv6 && (pos[1] & 0x01))
+         return FLOW_ST_CANNOT_USE_DONT_FRAGMENT;
+       /* XXX: Could be a fragment component encoded in 2-bytes? */
+
        pos += 1+len;
 
        if (pos > end && !last)
index 9150ca91e100ce14a79bb522acb715bd58d6708e..185d5a1ccd89579042d48bb0c5311df049770460 100644 (file)
@@ -115,6 +115,7 @@ enum flow_validated_state {
   FLOW_ST_AND_BIT_SHOULD_BE_UNSET,
   FLOW_ST_ZERO_BIT_SHOULD_BE_UNSED,
   FLOW_ST_DEST_PREFIX_REQUIRED,
+  FLOW_ST_INVALID_TCP_FLAGS,
   FLOW_ST_CANNOT_USE_DONT_FRAGMENT
 };