]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
BGP: Handle flowspec rules without dst part
authorOndrej Zajicek (work) <santiago@crfreenet.org>
Tue, 3 Mar 2020 16:45:16 +0000 (17:45 +0100)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Tue, 3 Mar 2020 16:45:16 +0000 (17:45 +0100)
The RFC 5575 does not explicitly reject flowspec rules without dst part,
it just requires dst part in validation procedure for feasibility, which
we do not implement anyway. Thus flow without dst prefix is syntactically
valid, but unfeasible (if feasibilty testing is done).

Thanks to Alex D. for the bugreport.

lib/flowspec.c
lib/net.h
proto/bgp/packets.c

index ef19aa9626c394b3ca40960415c4fbc51b559e62..42770c5065ae8093886450cbf35902591476fbf6 100644 (file)
@@ -436,7 +436,6 @@ flow_validate(const byte *nlri, uint len, int ipv6)
   enum flow_type type = 0;
   const byte *pos = nlri;
   const byte *end = nlri + len;
-  int met_dst_pfx = 0;
 
   while (pos < end)
   {
@@ -448,8 +447,6 @@ flow_validate(const byte *nlri, uint len, int ipv6)
     switch (type)
     {
     case FLOW_TYPE_DST_PREFIX:
-      met_dst_pfx = 1;
-      /* Fall through */
     case FLOW_TYPE_SRC_PREFIX:
     {
       uint pxlen = *pos++;
@@ -556,9 +553,6 @@ flow_validate(const byte *nlri, uint len, int ipv6)
   if (pos != end)
     return FLOW_ST_NOT_COMPLETE;
 
-  if (!ipv6 && !met_dst_pfx)
-    return FLOW_ST_DEST_PREFIX_REQUIRED;
-
   return FLOW_ST_VALID;
 }
 
@@ -875,7 +869,7 @@ flow_builder4_finalize(struct flow_builder *fb, linpool *lpool)
   {
     byte *part = fb->data.data + fb->parts[FLOW_TYPE_DST_PREFIX].offset;
     prefix = flow_read_ip4_part(part);
-    pxlen = part[1];
+    pxlen = flow_read_pxlen(part);
   }
   *f = NET_ADDR_FLOW4(prefix, pxlen, data_len);
 
@@ -905,7 +899,7 @@ flow_builder6_finalize(struct flow_builder *fb, linpool *lpool)
   {
     byte *part = fb->data.data + fb->parts[FLOW_TYPE_DST_PREFIX].offset;
     prefix = flow_read_ip6_part(part);
-    pxlen = part[1];
+    pxlen = flow_read_pxlen(part);
   }
   *n = NET_ADDR_FLOW6(prefix, pxlen, data_len);
 
index 0cd5f735d6296fcc5aa7ffa6399dd1b04a3fde1c..8eb4c7b96d59006174980f543b09d53ad8322769 100644 (file)
--- a/lib/net.h
+++ b/lib/net.h
@@ -174,10 +174,10 @@ extern const u16 net_max_text_length[];
   ((net_addr_roa6) { NET_ROA6, pxlen, sizeof(net_addr_roa6), prefix, max_pxlen, asn })
 
 #define NET_ADDR_FLOW4(prefix,pxlen,dlen) \
-  ((net_addr_flow4) { NET_FLOW4, pxlen, sizeof(net_addr_ip4) + dlen, prefix })
+  ((net_addr_flow4) { NET_FLOW4, pxlen, sizeof(net_addr_flow4) + dlen, prefix })
 
 #define NET_ADDR_FLOW6(prefix,pxlen,dlen) \
-  ((net_addr_flow6) { NET_FLOW6, pxlen, sizeof(net_addr_ip6) + dlen, prefix })
+  ((net_addr_flow6) { NET_FLOW6, pxlen, sizeof(net_addr_flow6) + dlen, prefix })
 
 #define NET_ADDR_IP6_SADR(dst_prefix,dst_pxlen,src_prefix,src_pxlen) \
   ((net_addr_ip6_sadr) { NET_IP6_SADR, dst_pxlen, sizeof(net_addr_ip6_sadr), dst_prefix, src_pxlen, src_prefix })
index ed878e41597d826a5fcab46aff2ef5810031ad2f..ee031c05ae7e33b5c0a42cf641fe26a675f5313f 100644 (file)
@@ -1824,15 +1824,15 @@ bgp_decode_nlri_flow4(struct bgp_parse_state *s, byte *pos, uint len, rta *a)
       bgp_parse_error(s, 1);
     }
 
-    if (data[0] != FLOW_TYPE_DST_PREFIX)
-    {
-      log(L_REMOTE "%s: No dst prefix at first pos", s->proto->p.name);
-      bgp_parse_error(s, 1);
-    }
+    ip4_addr px = IP4_NONE;
+    uint pxlen = 0;
 
     /* Decode dst prefix */
-    ip4_addr px = flow_read_ip4_part(data);
-    uint pxlen = data[1];
+    if (data[0] == FLOW_TYPE_DST_PREFIX)
+    {
+      px = flow_read_ip4_part(data);
+      pxlen = flow_read_pxlen(data);
+    }
 
     /* Prepare the flow */
     net_addr *n = alloca(sizeof(struct net_addr_flow4) + flen);
@@ -1912,15 +1912,15 @@ bgp_decode_nlri_flow6(struct bgp_parse_state *s, byte *pos, uint len, rta *a)
       bgp_parse_error(s, 1);
     }
 
-    if (data[0] != FLOW_TYPE_DST_PREFIX)
-    {
-      log(L_REMOTE "%s: No dst prefix at first pos", s->proto->p.name);
-      bgp_parse_error(s, 1);
-    }
+    ip6_addr px = IP6_NONE;
+    uint pxlen = 0;
 
     /* Decode dst prefix */
-    ip6_addr px = flow_read_ip6_part(data);
-    uint pxlen = data[1];
+    if (data[0] == FLOW_TYPE_DST_PREFIX)
+    {
+      px = flow_read_ip6_part(data);
+      pxlen = flow_read_pxlen(data);
+    }
 
     /* Prepare the flow */
     net_addr *n = alloca(sizeof(struct net_addr_flow6) + flen);