Flowspec: Max tcp mask length is 12 bits
This commit is contained in:
parent
a1de692a69
commit
5ca4bd5d90
4 changed files with 25 additions and 14 deletions
|
@ -105,27 +105,27 @@ protocol static flowstat4 {
|
||||||
proto = 0x12;
|
proto = 0x12;
|
||||||
sport > 0x5678 && < 0x9abc || 0xdef0 || 0x1234,0x5678,0x9abc..0xdef0;
|
sport > 0x5678 && < 0x9abc || 0xdef0 || 0x1234,0x5678,0x9abc..0xdef0;
|
||||||
dport = 50;
|
dport = 50;
|
||||||
tcp flags 0xabcd/0xbbdd;
|
tcp flags 0x000/0xf00;
|
||||||
};
|
};
|
||||||
|
|
||||||
route flow4 {
|
route flow4 {
|
||||||
dst 12.0.0.0/32;
|
dst 12.0.0.0/32;
|
||||||
tcp flags ! 0 / 0x9999;
|
tcp flags ! 0/0x999;
|
||||||
};
|
};
|
||||||
|
|
||||||
route flow4 {
|
route flow4 {
|
||||||
dst 220.0.254.0/24;
|
dst 220.0.254.0/24;
|
||||||
tcp flags 0x99 / 0x9999;
|
tcp flags 0x99/0x999;
|
||||||
};
|
};
|
||||||
|
|
||||||
route flow4 {
|
route flow4 {
|
||||||
dst 220.0.254.192/28;
|
dst 220.0.254.192/28;
|
||||||
tcp flags !0xffff / 0xFFFF;
|
tcp flags ! 0xfff/0xfff;
|
||||||
};
|
};
|
||||||
|
|
||||||
route flow4 {
|
route flow4 {
|
||||||
dst 15.0.0.0/8;
|
dst 15.0.0.0/8;
|
||||||
tcp flags !0x9999/0x9999;
|
tcp flags ! 0x999/0x999;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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>
|
<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.
|
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>
|
<tag><label id="flow-length">length <m/numbers-match/</tag>
|
||||||
Set a matching packet length (e.g. <cf>length > 1500;</cf>)
|
Set a matching packet length (e.g. <cf>length > 1500;</cf>)
|
||||||
|
|
|
@ -259,7 +259,8 @@ static const char* flow_validated_state_str_[] = {
|
||||||
[FLOW_ST_BAD_TYPE_ORDER] = "Bad component order",
|
[FLOW_ST_BAD_TYPE_ORDER] = "Bad component order",
|
||||||
[FLOW_ST_AND_BIT_SHOULD_BE_UNSET] = "The AND-bit should be unset",
|
[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_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"
|
[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))
|
if (neg && !(val == 0 || val == mask))
|
||||||
cf_error("For negation, value must be zero or bitmask");
|
cf_error("For negation, value must be zero or bitmask");
|
||||||
|
|
||||||
if (fb->this_type == FLOW_TYPE_FRAGMENT && fb->ipv6 && (mask & 0x01))
|
if ((fb->this_type == FLOW_TYPE_TCP_FLAGS) && (mask & 0xf000))
|
||||||
cf_error("Invalid mask 0x%x. Bit 0 must be 0", mask);
|
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)
|
if (val & ~mask)
|
||||||
cf_error("Value 0x%x outside bitmask 0x%x", 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;
|
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 */
|
/* Value length of operator */
|
||||||
uint len = get_value_length(pos);
|
uint len = get_value_length(pos);
|
||||||
if (len > flow_max_value_length(type, ipv6))
|
if (len > flow_max_value_length(type, ipv6))
|
||||||
return FLOW_ST_EXCEED_MAX_VALUE_LENGTH;
|
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;
|
pos += 1+len;
|
||||||
|
|
||||||
if (pos > end && !last)
|
if (pos > end && !last)
|
||||||
|
|
|
@ -115,6 +115,7 @@ enum flow_validated_state {
|
||||||
FLOW_ST_AND_BIT_SHOULD_BE_UNSET,
|
FLOW_ST_AND_BIT_SHOULD_BE_UNSET,
|
||||||
FLOW_ST_ZERO_BIT_SHOULD_BE_UNSED,
|
FLOW_ST_ZERO_BIT_SHOULD_BE_UNSED,
|
||||||
FLOW_ST_DEST_PREFIX_REQUIRED,
|
FLOW_ST_DEST_PREFIX_REQUIRED,
|
||||||
|
FLOW_ST_INVALID_TCP_FLAGS,
|
||||||
FLOW_ST_CANNOT_USE_DONT_FRAGMENT
|
FLOW_ST_CANNOT_USE_DONT_FRAGMENT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue