[ovs-dev] [PATCH v2] datapath-windows: Add support for UPDATE events in Conntrack
Sairam Venugopal
vsairam at vmware.com
Thu Jun 22 00:23:57 UTC 2017
Acked-by: Sairam Venugopal <vsairam at vmware.com>
On 6/21/17, 1:33 PM, "ovs-dev-bounces at openvswitch.org on behalf of Anand Kumar" <ovs-dev-bounces at openvswitch.org on behalf of kumaranand at vmware.com> wrote:
>Introduce a new event type OVS_EVENT_CT_UPDATE to send a conntrack event
>whenever a MARK and/or LABEL gets changed for an existing conntrack entry.
>
> - Parse netlink conntrack attribute OVS_CT_ATTR_EVENTMASK, which is used
> to set the mask of bits specifying which conntrack events (IPCT_*)
> should be delivered via the Netfilter netlink multicast groups.
> - Send update event only when OVS_CT_ATTR_EVENTMASK attribute has the mask
> of bits set for IPCT_MARK and/or IPCT_LABEL.
>
>Signed-off-by: Anand Kumar <kumaranand at vmware.com>
>---
> datapath-windows/ovsext/Conntrack.c | 48 ++++++++++++++++++++++++++++++------
> datapath-windows/ovsext/Datapath.c | 3 +++
> datapath-windows/ovsext/DpInternal.h | 3 ++-
> datapath-windows/ovsext/Event.c | 3 ++-
> 4 files changed, 47 insertions(+), 10 deletions(-)
>
>diff --git a/datapath-windows/ovsext/Conntrack.c b/datapath-windows/ovsext/Conntrack.c
>index 07a9583..61c6bc7 100644
>--- a/datapath-windows/ovsext/Conntrack.c
>+++ b/datapath-windows/ovsext/Conntrack.c
>@@ -659,13 +659,15 @@ static __inline VOID
> OvsConntrackSetMark(OvsFlowKey *key,
> POVS_CT_ENTRY entry,
> UINT32 value,
>- UINT32 mask)
>+ UINT32 mask,
>+ BOOLEAN *markChanged)
> {
> UINT32 newMark;
> newMark = value | (entry->mark & ~(mask));
> if (entry->mark != newMark) {
> entry->mark = newMark;
> key->ct.mark = newMark;
>+ *markChanged = TRUE;
> }
> }
>
>@@ -673,7 +675,8 @@ static __inline void
> OvsConntrackSetLabels(OvsFlowKey *key,
> POVS_CT_ENTRY entry,
> struct ovs_key_ct_labels *val,
>- struct ovs_key_ct_labels *mask)
>+ struct ovs_key_ct_labels *mask,
>+ BOOLEAN *labelChanged)
> {
> ovs_u128 v, m, pktMdLabel = {0};
> memcpy(&v, val, sizeof v);
>@@ -682,6 +685,10 @@ OvsConntrackSetLabels(OvsFlowKey *key,
> pktMdLabel.u64.lo = v.u64.lo | (pktMdLabel.u64.lo & ~(m.u64.lo));
> pktMdLabel.u64.hi = v.u64.hi | (pktMdLabel.u64.hi & ~(m.u64.hi));
>
>+ if (!NdisEqualMemory(&entry->labels, &pktMdLabel,
>+ sizeof(struct ovs_key_ct_labels))) {
>+ *labelChanged = TRUE;
>+ }
> NdisMoveMemory(&entry->labels, &pktMdLabel,
> sizeof(struct ovs_key_ct_labels));
> NdisMoveMemory(&key->ct.labels, &pktMdLabel,
>@@ -698,9 +705,11 @@ OvsCtExecute_(OvsForwardingContext *fwdCtx,
> MD_MARK *mark,
> MD_LABELS *labels,
> PCHAR helper,
>- PNAT_ACTION_INFO natInfo)
>+ PNAT_ACTION_INFO natInfo,
>+ BOOLEAN postUpdateEvent)
> {
> NDIS_STATUS status = NDIS_STATUS_SUCCESS;
>+ BOOLEAN triggerUpdateEvent = FALSE;
> POVS_CT_ENTRY entry = NULL;
> PNET_BUFFER_LIST curNbl = fwdCtx->curNbl;
> OvsConntrackKeyLookupCtx ctx = { 0 };
>@@ -752,11 +761,13 @@ OvsCtExecute_(OvsForwardingContext *fwdCtx,
> }
>
> if (entry && mark) {
>- OvsConntrackSetMark(key, entry, mark->value, mark->mask);
>+ OvsConntrackSetMark(key, entry, mark->value, mark->mask,
>+ &triggerUpdateEvent);
> }
>
> if (entry && labels) {
>- OvsConntrackSetLabels(key, entry, &labels->value, &labels->mask);
>+ OvsConntrackSetLabels(key, entry, &labels->value, &labels->mask,
>+ &triggerUpdateEvent);
> }
>
> if (entry && OvsDetectFtpPacket(key)) {
>@@ -790,6 +801,9 @@ OvsCtExecute_(OvsForwardingContext *fwdCtx,
> if (entryCreated && entry) {
> OvsPostCtEventEntry(entry, OVS_EVENT_CT_NEW);
> }
>+ if (postUpdateEvent && entry && !entryCreated && triggerUpdateEvent) {
>+ OvsPostCtEventEntry(entry, OVS_EVENT_CT_UPDATE);
>+ }
>
> NdisReleaseRWLock(ovsConntrackLockObj, &lockState);
>
>@@ -811,7 +825,9 @@ OvsExecuteConntrackAction(OvsForwardingContext *fwdCtx,
> PNL_ATTR ctAttr;
> BOOLEAN commit = FALSE;
> BOOLEAN force = FALSE;
>+ BOOLEAN postUpdateEvent = FALSE;
> UINT16 zone = 0;
>+ UINT32 eventmask = 0;
> MD_MARK *mark = NULL;
> MD_LABELS *labels = NULL;
> PCHAR helper = NULL;
>@@ -922,9 +938,17 @@ OvsExecuteConntrackAction(OvsForwardingContext *fwdCtx,
> /* Force implicitly means commit */
> commit = TRUE;
> }
>+ ctAttr = NlAttrFindNested(a, OVS_CT_ATTR_EVENTMASK);
>+ if (ctAttr) {
>+ eventmask = NlAttrGetU32(ctAttr);
>+ /* Only mark and label updates are supported. */
>+ if (eventmask & (1 << IPCT_MARK | 1 << IPCT_LABEL))
>+ postUpdateEvent = TRUE;
>+ }
> /* If newNbl is not allocated, use the current Nbl*/
> status = OvsCtExecute_(fwdCtx, key, layers,
>- commit, force, zone, mark, labels, helper, &natActionInfo);
>+ commit, force, zone, mark, labels, helper, &natActionInfo,
>+ postUpdateEvent);
> return status;
> }
>
>@@ -1266,6 +1290,7 @@ OvsCreateNlMsgFromCtEntry(POVS_CT_ENTRY entry,
> NDIS_STATUS status;
> UINT64 currentTime, expiration;
> UINT16 nlmsgType;
>+ UINT16 nlmsgFlags = NLM_F_CREATE;
> NdisGetCurrentSystemTime((LARGE_INTEGER *)¤tTime);
> UINT8 nfgenFamily = 0;
> if (entry->key.dl_type == htons(ETH_TYPE_IPV4)) {
>@@ -1276,7 +1301,7 @@ OvsCreateNlMsgFromCtEntry(POVS_CT_ENTRY entry,
>
> NlBufInit(&nlBuf, outBuffer, outBufLen);
> /* Mimic netfilter */
>- if (eventType == OVS_EVENT_CT_NEW) {
>+ if (eventType == OVS_EVENT_CT_NEW || eventType == OVS_EVENT_CT_UPDATE) {
> nlmsgType = (UINT16) (NFNL_SUBSYS_CTNETLINK << 8 | IPCTNL_MSG_CT_NEW);
> } else if (eventType == OVS_EVENT_CT_DELETE) {
> nlmsgType = (UINT16) (NFNL_SUBSYS_CTNETLINK << 8 | IPCTNL_MSG_CT_DELETE);
>@@ -1284,7 +1309,14 @@ OvsCreateNlMsgFromCtEntry(POVS_CT_ENTRY entry,
> return STATUS_INVALID_PARAMETER;
> }
>
>- ok = NlFillOvsMsgForNfGenMsg(&nlBuf, nlmsgType, NLM_F_CREATE,
>+ if (eventType == OVS_EVENT_CT_UPDATE) {
>+ /* In netlink-conntrack.c IPCTNL_MSG_CT_NEW msg type is used to
>+ * differentiate between OVS_EVENT_CT_NEW and OVS_EVENT_CT_UPDATE
>+ * events based on nlmsgFlags, unset it to notify an update event.
>+ */
>+ nlmsgFlags = 0;
>+ }
>+ ok = NlFillOvsMsgForNfGenMsg(&nlBuf, nlmsgType, nlmsgFlags,
> nlmsgSeq, nlmsgPid, nfgenFamily,
> nfGenVersion, dpIfIndex);
> if (!ok) {
>diff --git a/datapath-windows/ovsext/Datapath.c b/datapath-windows/ovsext/Datapath.c
>index 83d996e..10412a1 100644
>--- a/datapath-windows/ovsext/Datapath.c
>+++ b/datapath-windows/ovsext/Datapath.c
>@@ -1312,6 +1312,9 @@ OvsSubscribeEventCmdHandler(POVS_USER_PARAMS_CONTEXT usrParamsCtx,
> if (mcastGrp == NFNLGRP_CONNTRACK_DESTROY) {
> request.mask = OVS_EVENT_CT_DELETE;
> }
>+ if (mcastGrp == NFNLGRP_CONNTRACK_UPDATE) {
>+ request.mask = OVS_EVENT_CT_UPDATE;
>+ }
> }
>
> status = OvsSubscribeEventIoctl(instance->fileObject, &request,
>diff --git a/datapath-windows/ovsext/DpInternal.h b/datapath-windows/ovsext/DpInternal.h
>index 743891c..3e351b7 100644
>--- a/datapath-windows/ovsext/DpInternal.h
>+++ b/datapath-windows/ovsext/DpInternal.h
>@@ -336,7 +336,8 @@ enum {
> enum {
> OVS_EVENT_CT_NEW = (1 << 0),
> OVS_EVENT_CT_DELETE = (1 << 1),
>- OVS_EVENT_CT_MASK_ALL = 0x3
>+ OVS_EVENT_CT_UPDATE = (1 << 2),
>+ OVS_EVENT_CT_MASK_ALL = 0x7
> };
>
> /* Supported mcast event groups */
>diff --git a/datapath-windows/ovsext/Event.c b/datapath-windows/ovsext/Event.c
>index cb0dc92..2b54692 100644
>--- a/datapath-windows/ovsext/Event.c
>+++ b/datapath-windows/ovsext/Event.c
>@@ -71,7 +71,8 @@ OvsGetMcastEventId(UINT32 protocol, UINT32 mcastMask, UINT32 *eventId)
> return NDIS_STATUS_SUCCESS;
> case NETLINK_NETFILTER:
> if ((mcastMask & OVS_EVENT_CT_NEW)
>- || (mcastMask & OVS_EVENT_CT_DELETE)) {
>+ || (mcastMask & OVS_EVENT_CT_DELETE)
>+ || (mcastMask & OVS_EVENT_CT_UPDATE)) {
> *eventId = OVS_MCAST_CT_EVENT;
> return NDIS_STATUS_SUCCESS;
> }
>--
>2.9.3.windows.1
>
>_______________________________________________
>dev mailing list
>dev at openvswitch.org
>https://urldefense.proofpoint.com/v2/url?u=https-3A__mail.openvswitch.org_mailman_listinfo_ovs-2Ddev&d=DwICAg&c=uilaK90D4TOVoH58JNXRgQ&r=Z6vowHUOjP5ysP_g372c49Nqc1vEKqHKNBkR5Q5Z7uo&m=uouqud_RY4Fwuv_KPzC_6BdizI7DDORt8MpvsObP7b0&s=BGZD1dnnODEXmXC64MF97TWGOSLdhyFZ1Mqt77s5CJg&e=
More information about the dev
mailing list