From dc235f7fbcff39b318b715f9d3d01f97b2634357 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Mon, 28 Oct 2013 13:54:40 -0700 Subject: TCP flags matching support. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Signed-off-by: Ben Pfaff Acked-by: Jesse Gross --- lib/meta-flow.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'lib/meta-flow.c') 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; -- cgit v1.2.1