datapath-windows: Support for OVS_KEY_ATTR_SCTP attribute
authorSorin Vinturis <svinturis@cloudbasesolutions.com>
Wed, 11 Nov 2015 20:11:16 +0000 (20:11 +0000)
committerBen Pfaff <blp@ovn.org>
Wed, 25 Nov 2015 06:00:05 +0000 (22:00 -0800)
This patch adds OVS_KEY_ATTR_SCTP to the OVS flow mechanism.

Signed-off-by: Sorin Vinturis <svinturis@cloudbasesolutions.com>
Acked-by: Sairam Venugopal <vsairam@vmware.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
datapath-windows/ovsext/Flow.c
datapath-windows/ovsext/Flow.h
datapath-windows/ovsext/NetProto.h
datapath-windows/ovsext/PacketParser.c
datapath-windows/ovsext/PacketParser.h

index b629c93..31ddc66 100644 (file)
@@ -1673,7 +1673,7 @@ DeleteAllFlows(OVS_DATAPATH *datapath)
  *    - packet->l4 to just past the IPv4 header, if one is present and has a
  *      correct length, and otherwise NULL.
  *
- *    - packet->l7 to just past the TCP or UDP or ICMP header, if one is
+ *    - packet->l7 to just past the TCP, UDP, SCTP or ICMP header, if one is
  *      present and has a correct length, and otherwise NULL.
  *
  * Returns NDIS_STATUS_SUCCESS normally.  Fails only if packet data cannot be accessed
@@ -1802,6 +1802,8 @@ OvsExtractFlow(const NET_BUFFER_LIST *packet,
                     OvsParseTcp(packet, &ipKey->l4, layers);
                 } else if (ipKey->nwProto == SOCKET_IPPROTO_UDP) {
                     OvsParseUdp(packet, &ipKey->l4, layers);
+                } else if (ipKey->nwProto == SOCKET_IPPROTO_SCTP) {
+                    OvsParseSctp(packet, &ipKey->l4, layers);
                 } else if (ipKey->nwProto == SOCKET_IPPROTO_ICMP) {
                     ICMPHdr icmpStorage;
                     const ICMPHdr *icmp;
@@ -1835,6 +1837,8 @@ OvsExtractFlow(const NET_BUFFER_LIST *packet,
             OvsParseTcp(packet, &(flow->ipv6Key.l4), layers);
         } else if (flow->ipv6Key.nwProto == SOCKET_IPPROTO_UDP) {
             OvsParseUdp(packet, &(flow->ipv6Key.l4), layers);
+        } else if (flow->ipv6Key.nwProto == SOCKET_IPPROTO_SCTP) {
+            OvsParseSctp(packet, &flow->ipv6Key.l4, layers);
         } else if (flow->ipv6Key.nwProto == SOCKET_IPPROTO_ICMPV6) {
             OvsParseIcmpV6(packet, flow, layers);
             flow->l2.keyLen += (OVS_ICMPV6_KEY_SIZE - OVS_IPV6_KEY_SIZE);
index e817bcf..74b9dfb 100644 (file)
@@ -40,7 +40,7 @@ typedef struct _OvsFlow {
 
 typedef struct _OvsLayers {
     UINT32 l3Ofs;             // IPv4, IPv6, ARP, or other L3 header.
-    UINT32 l4Ofs;             // TCP, UDP, ICMP, ICMPv6, or other L4 header.
+    UINT32 l4Ofs;             // TCP, UDP, SCTP, ICMP, ICMPv6, or other L4 header.
     UINT32 l7Ofs;             // L4 protocol's payload.
 } OvsLayers;
 
index a364869..4364c5c 100644 (file)
@@ -82,6 +82,7 @@ typedef UINT64 IP6UnitLength;
 #define IPPROTO_UDP     17
 #define IPPROTO_GRE     47
 #define IPPROTO_TCP     6
+#define IPPROTO_SCTP    132
 #define IPPROTO_RSVD    0xff
 
 #define IPPROTO_HOPOPTS         0               /* Hop-by-hop option header */
@@ -202,6 +203,7 @@ typedef union _OVS_PACKET_HDR_INFO {
         UINT16 isIPv6:1;
         UINT16 isTcp:1;
         UINT16 isUdp:1;
+        UINT16 isSctp:1;
         UINT16 tcpCsumNeeded:1;
         UINT16 udpCsumNeeded:1;
         UINT16 udpCsumZero:1;
@@ -303,6 +305,13 @@ typedef struct TCPHdr {
    UINT16    urg_ptr;
 } TCPHdr;
 
+typedef struct SCTPHdr {
+   UINT16    source;
+   UINT16    dest;
+   UINT32    vtag;
+   UINT32    check;
+} SCTPHdr;
+
 typedef struct PseudoHdr {
    UINT32   sourceIPAddr;
    UINT32   destIPAddr;
@@ -365,5 +374,6 @@ typedef struct IPOpt {
 #define SOCKET_IPPROTO_TCP   6
 #define SOCKET_IPPROTO_UDP   17
 #define SOCKET_IPPROTO_GRE   47
+#define SOCKET_IPPROTO_SCTP  132
 
 #endif /* __NET_PROTO_H_ */
index e01be17..bba2631 100644 (file)
@@ -191,6 +191,21 @@ OvsParseTcp(const NET_BUFFER_LIST *packet,
     }
 }
 
+VOID
+OvsParseSctp(const NET_BUFFER_LIST *packet,
+             L4Key *flow,
+             POVS_PACKET_HDR_INFO layers)
+{
+    SCTPHdr sctpStorage;
+    const SCTPHdr *sctp = OvsGetSctp(packet, layers->l4Offset, &sctpStorage);
+    if (sctp) {
+        flow->tpSrc = sctp->source;
+        flow->tpDst = sctp->dest;
+        layers->isSctp = 1;
+        layers->l7Offset = layers->l4Offset + sizeof *sctp;
+    }
+}
+
 VOID
 OvsParseUdp(const NET_BUFFER_LIST *packet,
          L4Key *flow,
index 55d110f..7b8e656 100644 (file)
@@ -28,6 +28,8 @@ VOID OvsParseTcp(const NET_BUFFER_LIST *packet, L4Key *flow,
                  POVS_PACKET_HDR_INFO layers);
 VOID OvsParseUdp(const NET_BUFFER_LIST *packet, L4Key *flow,
                  POVS_PACKET_HDR_INFO layers);
+VOID OvsParseSctp(const NET_BUFFER_LIST *packet, L4Key *flow,
+                  POVS_PACKET_HDR_INFO layers);
 NDIS_STATUS OvsParseIcmpV6(const NET_BUFFER_LIST *packet, OvsFlowKey *key,
                             POVS_PACKET_HDR_INFO layers);
 
@@ -133,6 +135,14 @@ OvsGetUdp(const NET_BUFFER_LIST *packet,
     return OvsGetPacketBytes(packet, sizeof *storage, ofs, storage);
 }
 
+static const SCTPHdr *
+OvsGetSctp(const NET_BUFFER_LIST *packet,
+           UINT32 ofs,
+           SCTPHdr *storage)
+{
+    return OvsGetPacketBytes(packet, sizeof *storage, ofs, storage);
+}
+
 static const ICMPHdr *
 OvsGetIcmp(const NET_BUFFER_LIST *packet,
            UINT32 ofs,