diff mbox

[ovs-dev,v2] datapath-windows: Add support for UPDATE events in Conntrack

Message ID 20170621203355.4808-1-kumaranand@vmware.com
State Accepted
Headers show

Commit Message

Anand Kumar June 21, 2017, 8:33 p.m. UTC
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@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(-)

Comments

Sairam Venugopal June 22, 2017, 12:23 a.m. UTC | #1
Acked-by: Sairam Venugopal <vsairam@vmware.com>





On 6/21/17, 1:33 PM, "ovs-dev-bounces@openvswitch.org on behalf of Anand Kumar" <ovs-dev-bounces@openvswitch.org on behalf of kumaranand@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@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 *)&currentTime);
>     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@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=
Gurucharan Shetty June 22, 2017, 1:56 a.m. UTC | #2
On 21 June 2017 at 13:33, Anand Kumar <kumaranand@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@vmware.com>
>
Applied, thanks!


> ---
>  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 *)&currentTime);
>      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@openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>
diff mbox

Patch

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 *)&currentTime);
     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;
         }