diff options
author | Anand Kumar <kumaranand@vmware.com> | 2017-06-21 13:33:55 -0700 |
---|---|---|
committer | Gurucharan Shetty <guru@ovn.org> | 2017-06-21 18:55:34 -0700 |
commit | 6c6204b67886ff9b051417376ab69d64191c35f4 (patch) | |
tree | 72f303d6c6ecbc01ef91fd3c14d6adb742a6a613 /datapath-windows | |
parent | f32b745b3f33e9aa706eebcc22b4ed0dba6fcda7 (diff) | |
download | openvswitch-6c6204b67886ff9b051417376ab69d64191c35f4.tar.gz |
datapath-windows: Add support for UPDATE events in Conntrack
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>
Acked-by: Sairam Venugopal <vsairam@vmware.com>
Signed-off-by: Gurucharan Shetty <guru@ovn.org>
Diffstat (limited to 'datapath-windows')
-rw-r--r-- | datapath-windows/ovsext/Conntrack.c | 48 | ||||
-rw-r--r-- | datapath-windows/ovsext/Datapath.c | 3 | ||||
-rw-r--r-- | datapath-windows/ovsext/DpInternal.h | 3 | ||||
-rw-r--r-- | 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 e6cffb139..e0fb7b454 100644 --- a/datapath-windows/ovsext/Conntrack.c +++ b/datapath-windows/ovsext/Conntrack.c @@ -649,13 +649,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; } } @@ -663,7 +665,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); @@ -672,6 +675,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, @@ -688,9 +695,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 }; @@ -742,11 +751,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)) { @@ -780,6 +791,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); @@ -801,7 +815,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; @@ -912,9 +928,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; } @@ -1256,6 +1280,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)) { @@ -1266,7 +1291,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); @@ -1274,7 +1299,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 83d996e87..10412a1ba 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 743891ca3..3e351b770 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 cb0dc9262..2b5469238 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; } |