diff options
author | Sairam Venugopal <vsairam@vmware.com> | 2016-11-09 16:34:22 -0800 |
---|---|---|
committer | Gurucharan Shetty <guru@ovn.org> | 2016-11-11 13:53:07 -0800 |
commit | 6e83dfd9c77d83c873f9a51455a90d273e3ee157 (patch) | |
tree | efb999fe360395e8164a1a9a4db6546c8f933d6f /datapath-windows/ovsext/Conntrack.c | |
parent | a4dabb3df5d000e689915ff9f1df1d21ece0d496 (diff) | |
download | openvswitch-6e83dfd9c77d83c873f9a51455a90d273e3ee157.tar.gz |
datapath-windows: Enable support for tracking ICMP code and type
Add support for tracking ICMP code and Type in the Hyper-V Conntrack
module. This code is similar to the userspace connection tracker.
Signed-off-by: Sairam Venugopal <vsairam@vmware.com>
Acked-by: Anand Kumar <kumaranand@vmware.com>
Signed-off-by: Gurucharan Shetty <guru@ovn.org>
Diffstat (limited to 'datapath-windows/ovsext/Conntrack.c')
-rw-r--r-- | datapath-windows/ovsext/Conntrack.c | 73 |
1 files changed, 67 insertions, 6 deletions
diff --git a/datapath-windows/ovsext/Conntrack.c b/datapath-windows/ovsext/Conntrack.c index 74fb38c40..b0846f6fc 100644 --- a/datapath-windows/ovsext/Conntrack.c +++ b/datapath-windows/ovsext/Conntrack.c @@ -211,7 +211,28 @@ OvsCtEntryCreate(PNET_BUFFER_LIST curNbl, return entry; } case IPPROTO_ICMP: + { + ICMPHdr storage; + const ICMPHdr *icmp; + icmp = OvsGetIcmp(curNbl, l4Offset, &storage); + if (!OvsConntrackValidateIcmpPacket(icmp)) { + goto invalid; + } + + state |= OVS_CS_F_NEW; + if (commit) { + entry = OvsConntrackCreateIcmpEntry(currentTime); + if (!entry) { + return NULL; + } + OvsCtAddEntry(entry, ctx, currentTime); + } + + OvsCtUpdateFlowKey(key, state, ctx->key.zone, 0, NULL); + return entry; + } case IPPROTO_UDP: + { state |= OVS_CS_F_NEW; if (commit) { entry = OvsConntrackCreateOtherEntry(currentTime); @@ -223,6 +244,7 @@ OvsCtEntryCreate(PNET_BUFFER_LIST curNbl, OvsCtUpdateFlowKey(key, state, ctx->key.zone, 0, NULL); return entry; + } default: goto invalid; } @@ -254,6 +276,7 @@ OvsCtUpdateEntry(OVS_CT_ENTRY* entry, return OvsConntrackUpdateTcpEntry(entry, tcp, nbl, reply, now); } case IPPROTO_ICMP: + return OvsConntrackUpdateIcmpEntry(entry, reply, now); case IPPROTO_UDP: return OvsConntrackUpdateOtherEntry(entry, reply, now); default: @@ -338,8 +361,7 @@ OvsCtLookup(OvsConntrackKeyLookupCtx *ctx) BOOLEAN reply = FALSE; POVS_CT_ENTRY found = NULL; - if (!ctTotalEntries) - { + if (!ctTotalEntries) { return found; } @@ -384,6 +406,27 @@ OvsExtractLookupCtxHash(OvsConntrackKeyLookupCtx *ctx) hash); } +static UINT8 +OvsReverseIcmpType(UINT8 type) +{ + switch (type) { + case ICMP4_ECHO_REQUEST: + return ICMP4_ECHO_REPLY; + case ICMP4_ECHO_REPLY: + return ICMP4_ECHO_REQUEST; + case ICMP4_TIMESTAMP_REQUEST: + return ICMP4_TIMESTAMP_REPLY; + case ICMP4_TIMESTAMP_REPLY: + return ICMP4_TIMESTAMP_REQUEST; + case ICMP4_INFO_REQUEST: + return ICMP4_INFO_REPLY; + case ICMP4_INFO_REPLY: + return ICMP4_INFO_REQUEST; + default: + return 0; + } +} + static __inline NDIS_STATUS OvsCtSetupLookupCtx(OvsFlowKey *flowKey, UINT16 zone, @@ -408,16 +451,31 @@ OvsCtSetupLookupCtx(OvsFlowKey *flowKey, const ICMPHdr *icmp; icmp = OvsGetIcmp(curNbl, l4Offset, &icmpStorage); ASSERT(icmp); - ctx->key.src.port = ctx->key.dst.port = icmp->fields.echo.id; /* Related bit is set when ICMP has an error */ /* XXX parse out the appropriate src and dst from inner pkt */ switch (icmp->type) { + case ICMP4_ECHO_REQUEST: + case ICMP4_ECHO_REPLY: + case ICMP4_TIMESTAMP_REQUEST: + case ICMP4_TIMESTAMP_REPLY: + case ICMP4_INFO_REQUEST: + case ICMP4_INFO_REPLY: + if (icmp->code != 0) { + return NDIS_STATUS_INVALID_PACKET; + } + /* Separate ICMP connection: identified using id */ + ctx->key.dst.icmp_id = icmp->fields.echo.id; + ctx->key.src.icmp_id = icmp->fields.echo.id; + ctx->key.src.icmp_type = icmp->type; + ctx->key.dst.icmp_type = OvsReverseIcmpType(icmp->type); + break; case ICMP4_DEST_UNREACH: case ICMP4_TIME_EXCEEDED: case ICMP4_PARAM_PROB: case ICMP4_SOURCE_QUENCH: case ICMP4_REDIRECT: { + /* XXX Handle inner packet */ ctx->related = TRUE; break; } @@ -830,15 +888,18 @@ MapProtoTupleToNl(PNL_BUFFER nlBuf, OVS_CT_KEY *key) || key->dl_type == ntohs(ETH_TYPE_IPV6)) { /* ICMP and ICMPv6 Type, Code and ID are currently not tracked */ if (key->nw_proto == IPPROTO_ICMP) { - if (!NlMsgPutTailU16(nlBuf, CTA_PROTO_ICMP_ID, 0)) { + if (!NlMsgPutTailU16(nlBuf, CTA_PROTO_ICMP_ID, + htons(key->src.icmp_id))) { status = NDIS_STATUS_FAILURE; goto done; } - if (!NlMsgPutTailU8(nlBuf, CTA_PROTO_ICMP_TYPE, 0)) { + if (!NlMsgPutTailU8(nlBuf, CTA_PROTO_ICMP_TYPE, + key->src.icmp_type)) { status = NDIS_STATUS_FAILURE; goto done; } - if (!NlMsgPutTailU8(nlBuf, CTA_PROTO_ICMP_CODE, 0)) { + if (!NlMsgPutTailU8(nlBuf, CTA_PROTO_ICMP_CODE, + key->src.icmp_code)) { status = NDIS_STATUS_FAILURE; goto done; } |