On Mon, May 11, 2015 at 5:42 AM, Sorin Vinturis
<svintu...@cloudbasesolutions.com> wrote:
> At the moment the OVS extension supports only one VXLAN tunnel that
> is cached in the extension switch context. Replaced the latter
> cached pointer with an array list that contains all VXLAN tunnel
> vports.
>
> Signed-off-by: Sorin Vinturis <svintu...@cloudbasesolutions.com>
> Reported-by: Alin Gabriel Serdean <aserd...@cloudbasesolutions.com>
> Reported-at: https://github.com/openvswitch/ovs-issues/issues/64
> Acked-by: Eitan Eliahu <elia...@vmware.com>
The patch does not apply on tip of master. Please rebase.

> ---
>  datapath-windows/ovsext/Actions.c | 13 +++++++++----
>  datapath-windows/ovsext/Switch.c  | 16 +++++++++++-----
>  datapath-windows/ovsext/Switch.h  |  6 ++++--
>  datapath-windows/ovsext/Tunnel.c  |  3 ++-
>  datapath-windows/ovsext/Vport.c   | 40 
> +++++++++++++++++++++++++++++++++------
>  datapath-windows/ovsext/Vport.h   | 21 +++++---------------
>  datapath-windows/ovsext/Vxlan.c   |  2 +-
>  datapath-windows/ovsext/Vxlan.h   |  2 +-
>  8 files changed, 67 insertions(+), 36 deletions(-)
>
> diff --git a/datapath-windows/ovsext/Actions.c 
> b/datapath-windows/ovsext/Actions.c
> index a93fe03..79e464c 100644
> --- a/datapath-windows/ovsext/Actions.c
> +++ b/datapath-windows/ovsext/Actions.c
> @@ -184,6 +184,9 @@ OvsInitForwardingCtx(OvsForwardingContext *ovsFwdCtx,
>  }
>
>  /*
> + * XXX: When we search for the tunnelVport we also need to specify the
> + * tunnelling protocol or the L4 protocol as key as well, because there are
> + * different protocols that can use the same destination port.
>   * --------------------------------------------------------------------------
>   * OvsDetectTunnelRxPkt --
>   *     Utility function for an RX packet to detect its tunnel type.
> @@ -203,16 +206,17 @@ OvsDetectTunnelRxPkt(OvsForwardingContext *ovsFwdCtx,
>       * packets only if they are at least VXLAN header size.
>       */
>      if (!flowKey->ipKey.nwFrag &&
> -        flowKey->ipKey.nwProto == IPPROTO_UDP &&
> -        flowKey->ipKey.l4.tpDst == VXLAN_UDP_PORT_NBO) {
> -        tunnelVport = ovsFwdCtx->switchContext->vxlanVport;
> -        ovsActionStats.rxVxlan++;
> +        flowKey->ipKey.nwProto == IPPROTO_UDP) {
> +        UINT16 dstPort = htons(flowKey->ipKey.l4.tpDst);
> +        tunnelVport = OvsFindTunnelVportByDstPort(ovsFwdCtx->switchContext,
> +                                                  dstPort);
>      }
>
>      // We might get tunnel packets even before the tunnel gets initialized.
>      if (tunnelVport) {
>          ASSERT(ovsFwdCtx->tunnelRxNic == NULL);
>          ovsFwdCtx->tunnelRxNic = tunnelVport;
> +        ovsActionStats.rxVxlan++;
>          return TRUE;
>      }
>
> @@ -1318,6 +1322,7 @@ OvsExecuteSetAction(OvsForwardingContext *ovsFwdCtx,
>                 status = OvsTunnelAttrToIPv4TunnelKey((PNL_ATTR)a, &tunKey);
>          ASSERT(status == NDIS_STATUS_SUCCESS);
>          tunKey.flow_hash = (uint16)(hash ? *hash : OvsHashFlow(key));
> +        tunKey.dst_port = key->ipKey.l4.tpDst;
>          RtlCopyMemory(&ovsFwdCtx->tunKey, &tunKey, sizeof ovsFwdCtx->tunKey);
>
>          break;
> diff --git a/datapath-windows/ovsext/Switch.c 
> b/datapath-windows/ovsext/Switch.c
> index 416bcc0..f877854 100644
> --- a/datapath-windows/ovsext/Switch.c
> +++ b/datapath-windows/ovsext/Switch.c
> @@ -367,6 +367,8 @@ OvsInitSwitchContext(POVS_SWITCH_CONTEXT switchContext)
>          sizeof(LIST_ENTRY) * OVS_MAX_VPORT_ARRAY_SIZE, OVS_SWITCH_POOL_TAG);
>      switchContext->pidHashArray = (PLIST_ENTRY)OvsAllocateMemoryWithTag(
>          sizeof(LIST_ENTRY) * OVS_MAX_PID_ARRAY_SIZE, OVS_SWITCH_POOL_TAG);
> +    switchContext->tunnelVportsArray = (PLIST_ENTRY)OvsAllocateMemoryWithTag(
> +        sizeof(LIST_ENTRY) * OVS_MAX_VPORT_ARRAY_SIZE, OVS_SWITCH_POOL_TAG);
>      status = OvsAllocateFlowTable(&switchContext->datapath, switchContext);
>
>      if (status == NDIS_STATUS_SUCCESS) {
> @@ -377,7 +379,8 @@ OvsInitSwitchContext(POVS_SWITCH_CONTEXT switchContext)
>          switchContext->portNoHashArray == NULL ||
>          switchContext->ovsPortNameHashArray == NULL ||
>          switchContext->portIdHashArray== NULL ||
> -        switchContext->pidHashArray == NULL) {
> +        switchContext->pidHashArray == NULL ||
> +        switchContext->tunnelVportsArray == NULL) {
>          if (switchContext->dispatchLock) {
>              NdisFreeRWLock(switchContext->dispatchLock);
>          }
> @@ -398,6 +401,10 @@ OvsInitSwitchContext(POVS_SWITCH_CONTEXT switchContext)
>                                   OVS_SWITCH_POOL_TAG);
>          }
>
> +        if (switchContext->tunnelVportsArray) {
> +            OvsFreeMemory(switchContext->tunnelVportsArray);
> +        }
> +
>          OvsDeleteFlowTable(&switchContext->datapath);
>          OvsCleanupBufferPool(switchContext);
>
> @@ -407,12 +414,9 @@ OvsInitSwitchContext(POVS_SWITCH_CONTEXT switchContext)
>
>      for (i = 0; i < OVS_MAX_VPORT_ARRAY_SIZE; i++) {
>          InitializeListHead(&switchContext->ovsPortNameHashArray[i]);
> -    }
> -    for (i = 0; i < OVS_MAX_VPORT_ARRAY_SIZE; i++) {
>          InitializeListHead(&switchContext->portIdHashArray[i]);
> -    }
> -    for (i = 0; i < OVS_MAX_VPORT_ARRAY_SIZE; i++) {
>          InitializeListHead(&switchContext->portNoHashArray[i]);
> +        InitializeListHead(&switchContext->tunnelVportsArray[i]);
>      }
>
>      for (i = 0; i < OVS_MAX_PID_ARRAY_SIZE; i++) {
> @@ -465,6 +469,8 @@ OvsDeleteSwitchContext(POVS_SWITCH_CONTEXT switchContext)
>      OvsFreeMemoryWithTag(switchContext->pidHashArray,
>                           OVS_SWITCH_POOL_TAG);
>      switchContext->pidHashArray = NULL;
> +    OvsFreeMemory(switchContext->tunnelVportsArray);
> +    switchContext->tunnelVportsArray = NULL;
>      OvsDeleteFlowTable(&switchContext->datapath);
>      OvsCleanupBufferPool(switchContext);
>
> diff --git a/datapath-windows/ovsext/Switch.h 
> b/datapath-windows/ovsext/Switch.h
> index 6ec34e1..8e1eb5f 100644
> --- a/datapath-windows/ovsext/Switch.h
> +++ b/datapath-windows/ovsext/Switch.h
> @@ -132,8 +132,6 @@ typedef struct _OVS_SWITCH_CONTEXT
>      POVS_VPORT_ENTRY        virtualExternalVport;   // the virtual adapter 
> vport
>      POVS_VPORT_ENTRY        internalVport;
>
> -    POVS_VPORT_ENTRY        vxlanVport;
> -
>      /*
>       * 'portIdHashArray' ONLY contains ports that exist on the Hyper-V 
> switch,
>       * namely: VIF (vNIC) ports, external port and Hyper-V internal port.
> @@ -148,11 +146,15 @@ typedef struct _OVS_SWITCH_CONTEXT
>       * exist on the Hyper-V switch, and 'numNonHvVports' counts such ports in
>       * 'portNoHashArray'.
>       *
> +     * 'tunnelVportsArray' contains tunnel ports that are added from OVS
> +     * userspace. Currently only VXLAN tunnels are added in this list.
> +     *
>       * 'ovsPortNameHashArray' contains the same entries as 'portNoHashArray' 
> but
>       * hashed on a different key.
>       */
>      PLIST_ENTRY             portIdHashArray;        // based on Hyper-V 
> portId
>      PLIST_ENTRY             portNoHashArray;        // based on ovs port 
> number
> +    PLIST_ENTRY             tunnelVportsArray;      // based on ovs dst port 
> number
>      PLIST_ENTRY             ovsPortNameHashArray;   // based on ovsName
>      PLIST_ENTRY             pidHashArray;           // based on packet pids
>      NDIS_SPIN_LOCK          pidHashLock;            // Lock for pidHash table
> diff --git a/datapath-windows/ovsext/Tunnel.c 
> b/datapath-windows/ovsext/Tunnel.c
> index fed58f1..002f180 100644
> --- a/datapath-windows/ovsext/Tunnel.c
> +++ b/datapath-windows/ovsext/Tunnel.c
> @@ -285,7 +285,8 @@ OvsInjectPacketThroughActions(PNET_BUFFER_LIST pNbl,
>
>          SendFlags |= NDIS_SEND_FLAGS_DISPATCH_LEVEL;
>
> -        vport = gOvsSwitchContext->vxlanVport;
> +        vport = OvsFindTunnelVportByDstPort(gOvsSwitchContext,
> +                                            htons(tunnelKey.dst_port));
>
>          if (vport == NULL){
>              status = STATUS_UNSUCCESSFUL;
> diff --git a/datapath-windows/ovsext/Vport.c b/datapath-windows/ovsext/Vport.c
> index e3a1803..aafbbcc 100644
> --- a/datapath-windows/ovsext/Vport.c
> +++ b/datapath-windows/ovsext/Vport.c
> @@ -591,6 +591,25 @@ OvsFindVportByPortNo(POVS_SWITCH_CONTEXT switchContext,
>
>
>  POVS_VPORT_ENTRY
> +OvsFindTunnelVportByDstPort(POVS_SWITCH_CONTEXT switchContext,
> +                            UINT16 dstPort)
> +{
> +    POVS_VPORT_ENTRY vport;
> +    PLIST_ENTRY head, link;
> +    UINT32 hash = OvsJhashBytes((const VOID *)&dstPort, sizeof(dstPort),
> +                                OVS_HASH_BASIS);
> +    head = &(switchContext->tunnelVportsArray[hash & OVS_VPORT_MASK]);
> +    LIST_FORALL(head, link) {
> +        vport = CONTAINING_RECORD(link, OVS_VPORT_ENTRY, tunnelVportLink);
> +        if (((POVS_VXLAN_VPORT)vport->priv)->dstPort == dstPort) {
> +            return vport;
> +        }
> +    }
> +    return NULL;
> +}
> +
> +
> +POVS_VPORT_ENTRY
>  OvsFindVportByOvsName(POVS_SWITCH_CONTEXT switchContext,
>                        PSTR name)
>  {
> @@ -1038,8 +1057,8 @@ InitHvVportCommon(POVS_SWITCH_CONTEXT switchContext,
>   * --------------------------------------------------------------------------
>   * Functionality common to any port added from OVS userspace.
>   *
> - * Inserts the port into 'portIdHashArray', 'ovsPortNameHashArray' and caches
> - * the pointer in the 'switchContext' if needed.
> + * Inserts the port into 'portNoHashArray', 'ovsPortNameHashArray' and in
> + * 'tunnelVportsArray' if appropriate.
>   * --------------------------------------------------------------------------
>   */
>  NDIS_STATUS
> @@ -1050,9 +1069,17 @@ InitOvsVportCommon(POVS_SWITCH_CONTEXT switchContext,
>
>      switch(vport->ovsType) {
>      case OVS_VPORT_TYPE_VXLAN:
> -        switchContext->vxlanVport = vport;
> +    {
> +        POVS_VXLAN_VPORT vxlanVport = (POVS_VXLAN_VPORT)vport->priv;
> +        hash = OvsJhashBytes(&vxlanVport->dstPort,
> +                             sizeof(vxlanVport->dstPort),
> +                             OVS_HASH_BASIS);
> +        InsertHeadList(
> +            &gOvsSwitchContext->tunnelVportsArray[hash & OVS_VPORT_MASK],
> +            &vport->tunnelVportLink);
>          switchContext->numNonHvVports++;
>          break;
> +    }
>      case OVS_VPORT_TYPE_INTERNAL:
>          if (vport->isBridgeInternal) {
>              switchContext->numNonHvVports++;
> @@ -1152,7 +1179,8 @@ OvsRemoveAndDeleteVport(PVOID usrParamsContext,
>                                         OvsTunnelVportPendingUninit,
>                                         tunnelContext);
>
> -        switchContext->vxlanVport = NULL;
> +        RemoveEntryList(&vport->tunnelVportLink);
> +        InitializeListHead(&vport->tunnelVportLink);
>          break;
>      }
>      case OVS_VPORT_TYPE_GRE:
> @@ -1352,6 +1380,7 @@ OvsClearAllSwitchVports(POVS_SWITCH_CONTEXT 
> switchContext)
>              OvsRemoveAndDeleteVport(NULL, switchContext, vport, TRUE, TRUE);
>          }
>      }
> +
>      /*
>       * Remove 'virtualExternalVport' as well. This port is not part of the
>       * 'portIdHashArray'.
> @@ -1361,9 +1390,9 @@ OvsClearAllSwitchVports(POVS_SWITCH_CONTEXT 
> switchContext)
>              (POVS_VPORT_ENTRY)switchContext->virtualExternalVport, TRUE, 
> TRUE);
>      }
>
> +
>      for (UINT hash = 0; hash < OVS_MAX_VPORT_ARRAY_SIZE; hash++) {
>          PLIST_ENTRY head, link, next;
> -
>          head = &(switchContext->portNoHashArray[hash & OVS_VPORT_MASK]);
>          LIST_FORALL_SAFE(head, link, next) {
>              POVS_VPORT_ENTRY vport;
> @@ -1377,7 +1406,6 @@ OvsClearAllSwitchVports(POVS_SWITCH_CONTEXT 
> switchContext)
>
>      ASSERT(switchContext->virtualExternalVport == NULL);
>      ASSERT(switchContext->internalVport == NULL);
> -    ASSERT(switchContext->vxlanVport == NULL);
>  }
>
>
> diff --git a/datapath-windows/ovsext/Vport.h b/datapath-windows/ovsext/Vport.h
> index 4cfda30..086f03f 100644
> --- a/datapath-windows/ovsext/Vport.h
> +++ b/datapath-windows/ovsext/Vport.h
> @@ -84,6 +84,7 @@ typedef struct _OVS_VPORT_ENTRY {
>      LIST_ENTRY             ovsNameLink;
>      LIST_ENTRY             portIdLink;
>      LIST_ENTRY             portNoLink;
> +    LIST_ENTRY             tunnelVportLink;
>
>      OVS_VPORT_STATE        ovsState;
>      OVS_VPORT_TYPE         ovsType;
> @@ -135,10 +136,8 @@ typedef struct _OVS_VPORT_ENTRY {
>
>  struct _OVS_SWITCH_CONTEXT;
>
> -POVS_VPORT_ENTRY
> -OvsFindVportByPortNo(struct _OVS_SWITCH_CONTEXT *switchContext,
> -                     UINT32 portNo);
> -
> +POVS_VPORT_ENTRY OvsFindVportByPortNo(POVS_SWITCH_CONTEXT switchContext,
> +                                      UINT32 portNo);
>  /* "name" is null-terminated */
>  POVS_VPORT_ENTRY OvsFindVportByOvsName(POVS_SWITCH_CONTEXT switchContext,
>                                         PSTR name);
> @@ -147,6 +146,8 @@ POVS_VPORT_ENTRY 
> OvsFindVportByHvNameA(POVS_SWITCH_CONTEXT switchContext,
>  POVS_VPORT_ENTRY OvsFindVportByPortIdAndNicIndex(POVS_SWITCH_CONTEXT 
> switchContext,
>                                                   NDIS_SWITCH_PORT_ID portId,
>                                                   NDIS_SWITCH_NIC_INDEX 
> index);
> +POVS_VPORT_ENTRY OvsFindTunnelVportByDstPort(POVS_SWITCH_CONTEXT 
> switchContext,
> +                                             UINT16 dstPort);
>
>  NDIS_STATUS OvsAddConfiguredSwitchPorts(struct _OVS_SWITCH_CONTEXT 
> *switchContext);
>  NDIS_STATUS OvsInitConfiguredSwitchNics(struct _OVS_SWITCH_CONTEXT 
> *switchContext);
> @@ -180,18 +181,6 @@ OvsIsTunnelVportType(OVS_VPORT_TYPE ovsType)
>             ovsType == OVS_VPORT_TYPE_GRE64;
>  }
>
> -static __inline POVS_VPORT_ENTRY
> -OvsGetTunnelVport(POVS_SWITCH_CONTEXT switchContext,
> -                  OVS_VPORT_TYPE ovsType)
> -{
> -    switch(ovsType) {
> -    case OVS_VPORT_TYPE_VXLAN:
> -        return switchContext->vxlanVport;
> -    default:
> -        return NULL;
> -    }
> -}
> -
>  static __inline BOOLEAN
>  OvsIsInternalVportType(OVS_VPORT_TYPE ovsType)
>  {
> diff --git a/datapath-windows/ovsext/Vxlan.c b/datapath-windows/ovsext/Vxlan.c
> index 963d033..0474fcd 100644
> --- a/datapath-windows/ovsext/Vxlan.c
> +++ b/datapath-windows/ovsext/Vxlan.c
> @@ -264,7 +264,7 @@ OvsDoEncapVxlan(PNET_BUFFER_LIST curNbl,
>          /* UDP header */
>          udpHdr = (UDPHdr *)((PCHAR)ipHdr + sizeof *ipHdr);
>          udpHdr->source = htons(tunKey->flow_hash | 32768);
> -        udpHdr->dest = VXLAN_UDP_PORT_NBO;
> +        udpHdr->dest = htons(tunKey->dst_port);
>          udpHdr->len = htons(NET_BUFFER_DATA_LENGTH(curNb) - headRoom +
>                              sizeof *udpHdr + sizeof *vxlanHdr);
>          udpHdr->check = 0;
> diff --git a/datapath-windows/ovsext/Vxlan.h b/datapath-windows/ovsext/Vxlan.h
> index 248a5dc..0e28304 100644
> --- a/datapath-windows/ovsext/Vxlan.h
> +++ b/datapath-windows/ovsext/Vxlan.h
> @@ -19,7 +19,7 @@
>
>  #include "NetProto.h"
>  typedef struct _OVS_VXLAN_VPORT {
> -    UINT32 dstPort;
> +    UINT16 dstPort;
>      UINT64 inPkts;
>      UINT64 outPkts;
>      UINT64 slowInPkts;
> --
> 1.9.0.msysgit.0
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to