]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Minor improvements in Flowspec parsing master
authorOndrej Zajicek <santiago@crfreenet.org>
Wed, 10 Jun 2026 14:21:38 +0000 (16:21 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Wed, 17 Jun 2026 15:16:34 +0000 (17:16 +0200)
conf/flowspec.Y
lib/flowspec.c

index cdb578ac4fe15f6a4499812146eb9b67c4c0ebdf..927a34b8dbf707e52a8e71a4d0ede5a01b13cd2e 100644 (file)
@@ -59,7 +59,7 @@ flow_num_type_:
  | ICMP CODE   { $$ = FLOW_TYPE_ICMP_CODE; }
  | LENGTH      { $$ = FLOW_TYPE_PACKET_LENGTH; }
  | DSCP                { $$ = FLOW_TYPE_DSCP; }
  | ICMP CODE   { $$ = FLOW_TYPE_ICMP_CODE; }
  | LENGTH      { $$ = FLOW_TYPE_PACKET_LENGTH; }
  | DSCP                { $$ = FLOW_TYPE_DSCP; }
- | LABEL       { $$ = FLOW_TYPE_LABEL; }
+ | LABEL       { $$ = FLOW_TYPE_LABEL; if (!this_flow->ipv6) cf_error("Flow label not valid in flow4"); }
  ;
 
 flow_num_type: flow_num_type_{ flow_builder_set_type(this_flow, $1); };
  ;
 
 flow_num_type: flow_num_type_{ flow_builder_set_type(this_flow, $1); };
@@ -123,7 +123,7 @@ flow_neg:
  ;
 
 flow_frag_val:
  ;
 
 flow_frag_val:
-   DONT_FRAGMENT  { $$ = 1; }
+   DONT_FRAGMENT  { $$ = 1; if (this_flow->ipv6) cf_error("Flag dont_fragment not valid in flow6"); }
  | IS_FRAGMENT   { $$ = 2; }
  | FIRST_FRAGMENT { $$ = 4; }
  | LAST_FRAGMENT  { $$ = 8; }
  | IS_FRAGMENT   { $$ = 2; }
  | FIRST_FRAGMENT { $$ = 4; }
  | LAST_FRAGMENT  { $$ = 8; }
index c534054faa3de5b254224cce1029df3b66d2c1b4..343c296bc4df854498299cd6fdf390add20c756d 100644 (file)
@@ -350,17 +350,17 @@ static const u8 flow_max_value_length[FLOW_TYPE_MAX] = {
   [FLOW_TYPE_FRAGMENT]         = 1,
 };
 
   [FLOW_TYPE_FRAGMENT]         = 1,
 };
 
-/* Maximum valid numeric values (in bytes), semantically */
+/* Maximum valid numeric values (in bits), semantically */
 static const u8 flow_max_valid_value[FLOW_TYPE_MAX] = {
 static const u8 flow_max_valid_value[FLOW_TYPE_MAX] = {
-  [FLOW_TYPE_IP_PROTOCOL]      = 1,
-  [FLOW_TYPE_PORT]             = 2,
-  [FLOW_TYPE_DST_PORT]         = 2,
-  [FLOW_TYPE_SRC_PORT]         = 2,
-  [FLOW_TYPE_ICMP_TYPE]                = 1,
-  [FLOW_TYPE_ICMP_CODE]                = 1,
-  [FLOW_TYPE_PACKET_LENGTH]    = 2,
-  [FLOW_TYPE_DSCP]             = 1,
-  [FLOW_TYPE_LABEL]            = 4,
+  [FLOW_TYPE_IP_PROTOCOL]      = 8,
+  [FLOW_TYPE_PORT]             = 16,
+  [FLOW_TYPE_DST_PORT]         = 16,
+  [FLOW_TYPE_SRC_PORT]         = 16,
+  [FLOW_TYPE_ICMP_TYPE]                = 8,
+  [FLOW_TYPE_ICMP_CODE]                = 8,
+  [FLOW_TYPE_PACKET_LENGTH]    = 16,
+  [FLOW_TYPE_DSCP]             = 6,
+  [FLOW_TYPE_LABEL]            = 20,
 };
 
 /**
 };
 
 /**
@@ -405,16 +405,10 @@ void
 flow_check_cf_numeric_arg(struct flow_builder *fb, uint val)
 {
   enum flow_type t = fb->this_type;
 flow_check_cf_numeric_arg(struct flow_builder *fb, uint val)
 {
   enum flow_type t = fb->this_type;
-  uint max = flow_max_valid_value[t];
-
-  if (t == FLOW_TYPE_DSCP && val > 0x3f)
-    cf_error("%s value %u out of range (0-63)", flow_type_str(t, fb->ipv6), val);
-
-  if (max == 1 && (val > 0xff))
-    cf_error("%s value %u out of range (0-255)", flow_type_str(t, fb->ipv6), val);
+  u64 max = (U64(1) << flow_max_valid_value[t]) - 1;
 
 
-  if (max == 2 && (val > 0xffff))
-    cf_error("%s value %u out of range (0-65535)", flow_type_str(t, fb->ipv6), val);
+  if (max && (val > max))
+    cf_error("%s value %u out of range (0-%lu)", flow_type_str(t, fb->ipv6), val, max);
 }
 
 /* Bitmask of padding bits in last byte of prefix */
 }
 
 /* Bitmask of padding bits in last byte of prefix */