Message ID | 20170621203355.4808-1-kumaranand@vmware.com |
---|---|
State | Accepted |
Headers | show |
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 *)¤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@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=
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 *)¤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@openvswitch.org > https://mail.openvswitch.org/mailman/listinfo/ovs-dev >
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; }
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(-)