diff --git a/datapath-windows/ovsext/Flow.c b/datapath-windows/ovsext/Flow.c
index b629c93..31ddc66 100644
--- a/datapath-windows/ovsext/Flow.c
+++ b/datapath-windows/ovsext/Flow.c
@@ -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);
diff --git a/datapath-windows/ovsext/Flow.h b/datapath-windows/ovsext/Flow.h
index e817bcf..74b9dfb 100644
--- a/datapath-windows/ovsext/Flow.h
+++ b/datapath-windows/ovsext/Flow.h
@@ -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;
 
diff --git a/datapath-windows/ovsext/NetProto.h b/datapath-windows/ovsext/NetProto.h
index a364869..4364c5c 100644
--- a/datapath-windows/ovsext/NetProto.h
+++ b/datapath-windows/ovsext/NetProto.h
@@ -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_ */
diff --git a/datapath-windows/ovsext/PacketParser.c b/datapath-windows/ovsext/PacketParser.c
index e01be17..bba2631 100644
--- a/datapath-windows/ovsext/PacketParser.c
+++ b/datapath-windows/ovsext/PacketParser.c
@@ -192,6 +192,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,
          POVS_PACKET_HDR_INFO layers)
diff --git a/datapath-windows/ovsext/PacketParser.h b/datapath-windows/ovsext/PacketParser.h
index 55d110f..7b8e656 100644
--- a/datapath-windows/ovsext/PacketParser.h
+++ b/datapath-windows/ovsext/PacketParser.h
@@ -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,
