From patchwork Wed Nov 22 00:47:13 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anand Kumar X-Patchwork-Id: 840235 X-Patchwork-Delegate: aserdean@cloudbasesolutions.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3yhP2G630Bz9sDB for ; Wed, 22 Nov 2017 11:48:06 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id E6E48AAC; Wed, 22 Nov 2017 00:47:29 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id EE63FAA5 for ; Wed, 22 Nov 2017 00:47:27 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from EX13-EDG-OU-001.vmware.com (ex13-edg-ou-001.vmware.com [208.91.0.189]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id F04B1E2 for ; Wed, 22 Nov 2017 00:47:26 +0000 (UTC) Received: from sc9-mailhost2.vmware.com (10.113.161.72) by EX13-EDG-OU-001.vmware.com (10.113.208.155) with Microsoft SMTP Server id 15.0.1156.6; Tue, 21 Nov 2017 16:47:21 -0800 Received: from localhost.localdomain (win-anand1.prom.eng.vmware.com [10.33.78.106]) by sc9-mailhost2.vmware.com (Postfix) with ESMTP id DA8C2B0923; Tue, 21 Nov 2017 16:47:25 -0800 (PST) From: Anand Kumar To: Date: Tue, 21 Nov 2017 16:47:13 -0800 Message-ID: <20171122004713.6724-2-kumaranand@vmware.com> X-Mailer: git-send-email 2.9.3.windows.1 In-Reply-To: <20171122004713.6724-1-kumaranand@vmware.com> References: <20171122004713.6724-1-kumaranand@vmware.com> MIME-Version: 1.0 Received-SPF: None (EX13-EDG-OU-001.vmware.com: kumaranand@vmware.com does not designate permitted sender hosts) X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v1] datapath-windows: Add support for deleting conntrack entry by 5-tuple. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org To delete a conntrack entry specified by 5-tuple pass an additional conntrack 5-tuple parameter to flush-conntrack. Signed-off-by: Anand Kumar Acked-by: Alin Gabriel Serdean --- datapath-windows/ovsext/Conntrack.c | 146 +++++++++++++++++++++++++++++++++--- 1 file changed, 134 insertions(+), 12 deletions(-) diff --git a/datapath-windows/ovsext/Conntrack.c b/datapath-windows/ovsext/Conntrack.c index 3203411..dc268b3 100644 --- a/datapath-windows/ovsext/Conntrack.c +++ b/datapath-windows/ovsext/Conntrack.c @@ -35,8 +35,10 @@ static PNDIS_RW_LOCK_EX ovsConntrackLockObj; extern POVS_SWITCH_CONTEXT gOvsSwitchContext; static UINT64 ctTotalEntries; -static __inline NDIS_STATUS OvsCtFlush(UINT16 zone); - +static __inline OvsCtFlush(UINT16 zone, struct ovs_key_ct_tuple_ipv4 *tuple); +static __inline NDIS_STATUS +MapNlToCtTuple(POVS_MESSAGE msgIn, PNL_ATTR attr, + struct ovs_key_ct_tuple_ipv4 *ct_tuple); /* *---------------------------------------------------------------------------- * OvsInitConntrack @@ -120,7 +122,7 @@ OvsCleanupConntrack(VOID) ObDereferenceObject(ctThreadCtx.threadObject); /* Force flush all entries before removing */ - OvsCtFlush(0); + OvsCtFlush(0, NULL); if (ovsConntrackTable) { OvsFreeMemoryWithTag(ovsConntrackTable, OVS_CT_POOL_TAG); @@ -1018,11 +1020,11 @@ OvsConntrackEntryCleaner(PVOID data) /* *---------------------------------------------------------------------------- * OvsCtFlush - * Flushes out all Conntrack Entries that match the given zone + * Flushes out all Conntrack Entries that match any of the arguments *---------------------------------------------------------------------------- */ static __inline NDIS_STATUS -OvsCtFlush(UINT16 zone) +OvsCtFlush(UINT16 zone, struct ovs_key_ct_tuple_ipv4 *tuple) { PLIST_ENTRY link, next; POVS_CT_ENTRY entry; @@ -1034,9 +1036,26 @@ OvsCtFlush(UINT16 zone) for (int i = 0; i < CT_HASH_TABLE_SIZE; i++) { LIST_FORALL_SAFE(&ovsConntrackTable[i], link, next) { entry = CONTAINING_RECORD(link, OVS_CT_ENTRY, link); - /* zone is a non-zero value */ - if (!zone || zone == entry->key.zone) + if (tuple) { + if (tuple->ipv4_proto != IPPROTO_ICMP && + tuple->ipv4_src == entry->key.src.addr.ipv4_aligned && + tuple->ipv4_dst == entry->key.dst.addr.ipv4_aligned && + tuple->ipv4_proto == entry->key.nw_proto && + tuple->src_port == entry->key.src.port && + tuple->dst_port == entry->key.dst.port && + (zone ? entry->key.zone == zone: TRUE)) { + OvsCtEntryDelete(entry); + } else if (tuple->ipv4_src == entry->key.src.addr.ipv4_aligned && + tuple->ipv4_dst == entry->key.dst.addr.ipv4_aligned && + tuple->ipv4_proto == entry->key.nw_proto && + tuple->src_port == entry->key.src.icmp_type && + tuple->dst_port == entry->key.src.icmp_code && + (zone ? entry->key.zone == zone: TRUE)) { + OvsCtEntryDelete(entry); + } + } else if (!zone || zone == entry->key.zone) { OvsCtEntryDelete(entry); + } } } } @@ -1058,19 +1077,21 @@ OvsCtDeleteCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, NL_ERROR nlError = NL_ERROR_SUCCESS; NTSTATUS status; UINT16 zone = 0; + struct ovs_key_ct_tuple_ipv4 *ct_tuple = NULL; NL_BUFFER nlBuf; UINT16 nlmsgType; PNL_MSG_HDR nlMsg; - static const NL_POLICY ctZonePolicy[] = { - [CTA_ZONE] = { .type = NL_A_BE16, .optional = TRUE }, + static const NL_POLICY ctAttrPolicy[] = { + [CTA_TUPLE_ORIG] = {.type = NL_A_NESTED, .optional = TRUE}, + [CTA_ZONE] = {.type = NL_A_BE16, .optional = TRUE }, }; if ((NlAttrParse(nlMsgHdr, attrOffset, NlNfMsgAttrsLen(nlMsgHdr), - ctZonePolicy, ARRAY_SIZE(ctZonePolicy), + ctAttrPolicy, ARRAY_SIZE(ctAttrPolicy), ctAttrs, ARRAY_SIZE(ctAttrs))) != TRUE) { - OVS_LOG_ERROR("Zone attr parsing failed for msg: %p", nlMsgHdr); + OVS_LOG_ERROR("Ct attr parsing failed for msg: %p", nlMsgHdr); status = STATUS_INVALID_PARAMETER; goto done; } @@ -1079,7 +1100,21 @@ OvsCtDeleteCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, zone = NlAttrGetU16(ctAttrs[CTA_ZONE]); } - status = OvsCtFlush(zone); + if (ctAttrs[CTA_TUPLE_ORIG]) { + ct_tuple = OvsAllocateMemoryWithTag(sizeof(struct ovs_key_ct_tuple_ipv4), + OVS_CT_POOL_TAG); + if (ct_tuple == NULL) { + status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + /* Parse ct tuple. */ + status = MapNlToCtTuple(msgIn, ctAttrs[CTA_TUPLE_ORIG], ct_tuple); + if (status != STATUS_SUCCESS) { + goto done; + } + } + + status = OvsCtFlush(zone, ct_tuple); if (status == STATUS_SUCCESS) { nlmsgType = (NFNL_SUBSYS_CTNETLINK << 8 | IPCTNL_MSG_CT_DELETE); NlBufInit(&nlBuf, @@ -1099,6 +1134,10 @@ OvsCtDeleteCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx, } done: + if (ct_tuple) { + OvsFreeMemoryWithTag(ct_tuple, OVS_CT_POOL_TAG); + } + nlError = NlMapStatusToNlErr(status); if (nlError != NL_ERROR_SUCCESS) { POVS_MESSAGE_ERROR msgError = (POVS_MESSAGE_ERROR) @@ -1114,6 +1153,89 @@ done: } static __inline NDIS_STATUS +MapNlToCtTuple(POVS_MESSAGE msgIn, PNL_ATTR ctAttr, + struct ovs_key_ct_tuple_ipv4 *ct_tuple) { + + PNL_MSG_HDR nlMsgHdr = &(msgIn->nlMsg); + PNL_ATTR ctTupleAttrs[__CTA_MAX]; + UINT32 attrOffset; + static const NL_POLICY ctTuplePolicy[] = { + [CTA_TUPLE_IP] = {.type = NL_A_NESTED, .optional = FALSE }, + [CTA_TUPLE_PROTO] = {.type = NL_A_NESTED, .optional = FALSE}, + }; + + static const NL_POLICY ctTupleIpPolicy[] = { + [CTA_IP_V4_SRC] = { .type = NL_A_BE32, .optional = TRUE }, + [CTA_IP_V4_DST] = { .type = NL_A_BE32, .optional = TRUE }, + }; + + static const NL_POLICY ctTupleProtoPolicy[] = { + [CTA_PROTO_NUM] = { .type = NL_A_U8, .optional = FALSE }, + [CTA_PROTO_SRC_PORT] = { .type = NL_A_BE16, .optional = TRUE }, + [CTA_PROTO_DST_PORT] = { .type = NL_A_BE16, .optional = TRUE }, + [CTA_PROTO_ICMP_TYPE] = { .type = NL_A_U8, .optional = TRUE }, + [CTA_PROTO_ICMP_CODE] = { .type = NL_A_U8, .optional = TRUE }, + }; + + if (!ctAttr) { + return STATUS_INVALID_PARAMETER; + } + + attrOffset = (UINT32)((PCHAR) ctAttr - (PCHAR)nlMsgHdr); + if ((NlAttrParseNested(nlMsgHdr, attrOffset, NlAttrLen(ctAttr), + ctTuplePolicy, ARRAY_SIZE(ctTuplePolicy), + ctTupleAttrs, ARRAY_SIZE(ctTupleAttrs))) + != TRUE) { + OVS_LOG_ERROR("CTA_TUPLE attr parsing failed for msg: %p", nlMsgHdr); + return STATUS_INVALID_PARAMETER; + } + + if (ctTupleAttrs[CTA_TUPLE_IP]) { + PNL_ATTR ctTupleIpAttrs[__CTA_MAX]; + attrOffset = (UINT32)((PCHAR) ctTupleAttrs[CTA_TUPLE_IP] - (PCHAR)nlMsgHdr); + if ((NlAttrParseNested(nlMsgHdr, attrOffset, NlAttrLen(ctTupleAttrs[CTA_TUPLE_IP]), + ctTupleIpPolicy, ARRAY_SIZE(ctTupleIpPolicy), + ctTupleIpAttrs, ARRAY_SIZE(ctTupleIpAttrs))) + != TRUE) { + OVS_LOG_ERROR("CTA_TUPLE_IP attr parsing failed for msg: %p", nlMsgHdr); + return STATUS_INVALID_PARAMETER; + } + + if (ctTupleIpAttrs[CTA_IP_V4_SRC] && ctTupleIpAttrs[CTA_IP_V4_DST]) { + ct_tuple->ipv4_src = NlAttrGetU32(ctTupleIpAttrs[CTA_IP_V4_SRC]); + ct_tuple->ipv4_dst = NlAttrGetU32(ctTupleIpAttrs[CTA_IP_V4_DST]); + } + } + + if (ctTupleAttrs[CTA_TUPLE_PROTO]) { + PNL_ATTR ctTupleProtoAttrs[__CTA_MAX]; + attrOffset = (UINT32)((PCHAR) ctTupleAttrs[CTA_TUPLE_PROTO] - (PCHAR)nlMsgHdr); + if ((NlAttrParseNested(nlMsgHdr, attrOffset, NlAttrLen(ctTupleAttrs[CTA_TUPLE_PROTO]), + ctTupleProtoPolicy, ARRAY_SIZE(ctTupleProtoPolicy), + ctTupleProtoAttrs, ARRAY_SIZE(ctTupleProtoAttrs))) + != TRUE) { + OVS_LOG_ERROR("CTA_TUPLE_PROTO attr parsing failed for msg: %p", nlMsgHdr); + return STATUS_INVALID_PARAMETER; + } + + if (ctTupleProtoAttrs[CTA_PROTO_NUM]) { + ct_tuple->ipv4_proto = NlAttrGetU8 (ctTupleProtoAttrs[CTA_PROTO_NUM]); + if (ctTupleProtoAttrs[CTA_PROTO_SRC_PORT] && ctTupleProtoAttrs[CTA_PROTO_DST_PORT]) { + ct_tuple->src_port = NlAttrGetU16(ctTupleProtoAttrs[CTA_PROTO_SRC_PORT]); + ct_tuple->dst_port = NlAttrGetU16(ctTupleProtoAttrs[CTA_PROTO_DST_PORT]); + } else if (ctTupleProtoAttrs[CTA_PROTO_ICMP_TYPE] && + ctTupleProtoAttrs[CTA_PROTO_ICMP_CODE] ) { + ct_tuple->src_port = NlAttrGetU8(ctTupleProtoAttrs[CTA_PROTO_ICMP_TYPE]); + ct_tuple->dst_port = NlAttrGetU8(ctTupleProtoAttrs[CTA_PROTO_ICMP_CODE]); + } + + } + } + + return NDIS_STATUS_SUCCESS; +} + +static __inline NDIS_STATUS MapIpTupleToNl(PNL_BUFFER nlBuf, OVS_CT_KEY *key) { NDIS_STATUS status = NDIS_STATUS_SUCCESS;