summaryrefslogtreecommitdiff
path: root/lib/meta-flow.c
diff options
context:
space:
mode:
authorJarno Rajahalme <jrajahalme@nicira.com>2013-10-28 13:54:40 -0700
committerBen Pfaff <blp@nicira.com>2013-10-29 09:43:59 -0700
commitdc235f7fbcff39b318b715f9d3d01f97b2634357 (patch)
tree856bf86db33b7c71a8dcdeb7baa457a806d4d8ba /lib/meta-flow.c
parenta66733a8bc1c42d92f498108d7e27987989dc206 (diff)
downloadopenvswitch-dc235f7fbcff39b318b715f9d3d01f97b2634357.tar.gz
TCP flags matching support.
tcp_flags=flags/mask Bitwise match on TCP flags. The flags and mask are 16-bit num‐ bers written in decimal or in hexadecimal prefixed by 0x. Each 1-bit in mask requires that the corresponding bit in port must match. Each 0-bit in mask causes the corresponding bit to be ignored. TCP protocol currently defines 9 flag bits, and additional 3 bits are reserved (must be transmitted as zero), see RFCs 793, 3168, and 3540. The flag bits are, numbering from the least significant bit: 0: FIN No more data from sender. 1: SYN Synchronize sequence numbers. 2: RST Reset the connection. 3: PSH Push function. 4: ACK Acknowledgement field significant. 5: URG Urgent pointer field significant. 6: ECE ECN Echo. 7: CWR Congestion Windows Reduced. 8: NS Nonce Sum. 9-11: Reserved. 12-15: Not matchable, must be zero. Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com> Signed-off-by: Ben Pfaff <blp@nicira.com> Acked-by: Jesse Gross <jesse@nicira.com>
Diffstat (limited to 'lib/meta-flow.c')
-rw-r--r--lib/meta-flow.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/lib/meta-flow.c b/lib/meta-flow.c
index 12811ef07..b9553af0d 100644
--- a/lib/meta-flow.c
+++ b/lib/meta-flow.c
@@ -559,6 +559,17 @@ static const struct mf_field mf_fields[MFF_N_IDS] = {
OXM_OF_TCP_DST, "OXM_OF_TCP_DST",
OFPUTIL_P_ANY,
OFPUTIL_P_NXM_OXM_ANY,
+ }, {
+ MFF_TCP_FLAGS, "tcp_flags", NULL,
+ 2, 12,
+ MFM_FULLY,
+ MFS_HEXADECIMAL,
+ MFP_TCP,
+ false,
+ NXM_NX_TCP_FLAGS, "NXM_NX_TCP_FLAGS",
+ NXM_NX_TCP_FLAGS, "NXM_NX_TCP_FLAGS",
+ OFPUTIL_P_NXM_OXM_ANY,
+ OFPUTIL_P_NXM_OXM_ANY,
},
{
@@ -919,6 +930,8 @@ mf_is_all_wild(const struct mf_field *mf, const struct flow_wildcards *wc)
case MFF_ICMPV4_CODE:
case MFF_ICMPV6_CODE:
return !wc->masks.tp_dst;
+ case MFF_TCP_FLAGS:
+ return !wc->masks.tcp_flags;
case MFF_N_IDS:
default:
@@ -1128,6 +1141,8 @@ mf_is_value_valid(const struct mf_field *mf, const union mf_value *value)
return !(value->u8 & ~IP_ECN_MASK);
case MFF_IP_FRAG:
return !(value->u8 & ~FLOW_NW_FRAG_MASK);
+ case MFF_TCP_FLAGS:
+ return !(value->be16 & ~htons(0x0fff));
case MFF_ARP_OP:
return !(value->be16 & htons(0xff00));
@@ -1326,6 +1341,10 @@ mf_get_value(const struct mf_field *mf, const struct flow *flow,
value->be16 = flow->tp_dst;
break;
+ case MFF_TCP_FLAGS:
+ value->be16 = flow->tcp_flags;
+ break;
+
case MFF_ICMPV4_TYPE:
case MFF_ICMPV6_TYPE:
value->u8 = ntohs(flow->tp_src);
@@ -1518,6 +1537,10 @@ mf_set_value(const struct mf_field *mf,
match_set_tp_dst(match, value->be16);
break;
+ case MFF_TCP_FLAGS:
+ match_set_tcp_flags(match, value->be16);
+ break;
+
case MFF_ICMPV4_TYPE:
case MFF_ICMPV6_TYPE:
match_set_icmp_type(match, value->u8);
@@ -1730,6 +1753,10 @@ mf_set_flow_value(const struct mf_field *mf,
flow->tp_dst = value->be16;
break;
+ case MFF_TCP_FLAGS:
+ flow->tcp_flags = value->be16;
+ break;
+
case MFF_ICMPV4_TYPE:
case MFF_ICMPV6_TYPE:
flow->tp_src = htons(value->u8);
@@ -1941,6 +1968,11 @@ mf_set_wild(const struct mf_field *mf, struct match *match)
match->flow.tp_dst = htons(0);
break;
+ case MFF_TCP_FLAGS:
+ match->wc.masks.tcp_flags = htons(0);
+ match->flow.tcp_flags = htons(0);
+ break;
+
case MFF_ND_TARGET:
memset(&match->wc.masks.nd_target, 0,
sizeof match->wc.masks.nd_target);
@@ -2111,6 +2143,10 @@ mf_set(const struct mf_field *mf,
match_set_tp_dst_masked(match, value->be16, mask->be16);
break;
+ case MFF_TCP_FLAGS:
+ match_set_tcp_flags_masked(match, value->be16, mask->be16);
+ break;
+
case MFF_N_IDS:
default:
NOT_REACHED();
@@ -2232,6 +2268,10 @@ mf_random_value(const struct mf_field *mf, union mf_value *value)
case MFF_ND_TLL:
break;
+ case MFF_TCP_FLAGS:
+ value->be16 &= htons(0x0fff);
+ break;
+
case MFF_IN_PORT_OXM:
value->be32 = ofputil_port_to_ofp11(u16_to_ofp(ntohs(value->be16)));
break;