BGP: Handle flowspec rules without dst part
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.
This commit is contained in:
parent
757cab18d6
commit
78e4a123bb
3 changed files with 18 additions and 24 deletions
|
@ -436,7 +436,6 @@ flow_validate(const byte *nlri, uint len, int ipv6)
|
||||||
enum flow_type type = 0;
|
enum flow_type type = 0;
|
||||||
const byte *pos = nlri;
|
const byte *pos = nlri;
|
||||||
const byte *end = nlri + len;
|
const byte *end = nlri + len;
|
||||||
int met_dst_pfx = 0;
|
|
||||||
|
|
||||||
while (pos < end)
|
while (pos < end)
|
||||||
{
|
{
|
||||||
|
@ -448,8 +447,6 @@ flow_validate(const byte *nlri, uint len, int ipv6)
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case FLOW_TYPE_DST_PREFIX:
|
case FLOW_TYPE_DST_PREFIX:
|
||||||
met_dst_pfx = 1;
|
|
||||||
/* Fall through */
|
|
||||||
case FLOW_TYPE_SRC_PREFIX:
|
case FLOW_TYPE_SRC_PREFIX:
|
||||||
{
|
{
|
||||||
uint pxlen = *pos++;
|
uint pxlen = *pos++;
|
||||||
|
@ -556,9 +553,6 @@ flow_validate(const byte *nlri, uint len, int ipv6)
|
||||||
if (pos != end)
|
if (pos != end)
|
||||||
return FLOW_ST_NOT_COMPLETE;
|
return FLOW_ST_NOT_COMPLETE;
|
||||||
|
|
||||||
if (!ipv6 && !met_dst_pfx)
|
|
||||||
return FLOW_ST_DEST_PREFIX_REQUIRED;
|
|
||||||
|
|
||||||
return FLOW_ST_VALID;
|
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;
|
byte *part = fb->data.data + fb->parts[FLOW_TYPE_DST_PREFIX].offset;
|
||||||
prefix = flow_read_ip4_part(part);
|
prefix = flow_read_ip4_part(part);
|
||||||
pxlen = part[1];
|
pxlen = flow_read_pxlen(part);
|
||||||
}
|
}
|
||||||
*f = NET_ADDR_FLOW4(prefix, pxlen, data_len);
|
*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;
|
byte *part = fb->data.data + fb->parts[FLOW_TYPE_DST_PREFIX].offset;
|
||||||
prefix = flow_read_ip6_part(part);
|
prefix = flow_read_ip6_part(part);
|
||||||
pxlen = part[1];
|
pxlen = flow_read_pxlen(part);
|
||||||
}
|
}
|
||||||
*n = NET_ADDR_FLOW6(prefix, pxlen, data_len);
|
*n = NET_ADDR_FLOW6(prefix, pxlen, data_len);
|
||||||
|
|
||||||
|
|
|
@ -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 })
|
((net_addr_roa6) { NET_ROA6, pxlen, sizeof(net_addr_roa6), prefix, max_pxlen, asn })
|
||||||
|
|
||||||
#define NET_ADDR_FLOW4(prefix,pxlen,dlen) \
|
#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) \
|
#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) \
|
#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 })
|
((net_addr_ip6_sadr) { NET_IP6_SADR, dst_pxlen, sizeof(net_addr_ip6_sadr), dst_prefix, src_pxlen, src_prefix })
|
||||||
|
|
|
@ -1824,15 +1824,15 @@ bgp_decode_nlri_flow4(struct bgp_parse_state *s, byte *pos, uint len, rta *a)
|
||||||
bgp_parse_error(s, 1);
|
bgp_parse_error(s, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data[0] != FLOW_TYPE_DST_PREFIX)
|
ip4_addr px = IP4_NONE;
|
||||||
{
|
uint pxlen = 0;
|
||||||
log(L_REMOTE "%s: No dst prefix at first pos", s->proto->p.name);
|
|
||||||
bgp_parse_error(s, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Decode dst prefix */
|
/* Decode dst prefix */
|
||||||
ip4_addr px = flow_read_ip4_part(data);
|
if (data[0] == FLOW_TYPE_DST_PREFIX)
|
||||||
uint pxlen = data[1];
|
{
|
||||||
|
px = flow_read_ip4_part(data);
|
||||||
|
pxlen = flow_read_pxlen(data);
|
||||||
|
}
|
||||||
|
|
||||||
/* Prepare the flow */
|
/* Prepare the flow */
|
||||||
net_addr *n = alloca(sizeof(struct net_addr_flow4) + flen);
|
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);
|
bgp_parse_error(s, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data[0] != FLOW_TYPE_DST_PREFIX)
|
ip6_addr px = IP6_NONE;
|
||||||
{
|
uint pxlen = 0;
|
||||||
log(L_REMOTE "%s: No dst prefix at first pos", s->proto->p.name);
|
|
||||||
bgp_parse_error(s, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Decode dst prefix */
|
/* Decode dst prefix */
|
||||||
ip6_addr px = flow_read_ip6_part(data);
|
if (data[0] == FLOW_TYPE_DST_PREFIX)
|
||||||
uint pxlen = data[1];
|
{
|
||||||
|
px = flow_read_ip6_part(data);
|
||||||
|
pxlen = flow_read_pxlen(data);
|
||||||
|
}
|
||||||
|
|
||||||
/* Prepare the flow */
|
/* Prepare the flow */
|
||||||
net_addr *n = alloca(sizeof(struct net_addr_flow6) + flen);
|
net_addr *n = alloca(sizeof(struct net_addr_flow6) + flen);
|
||||||
|
|
Loading…
Reference in a new issue