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>
* - 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
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;
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);
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;
#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 */
UINT16 isIPv6:1;
UINT16 isTcp:1;
UINT16 isUdp:1;
+ UINT16 isSctp:1;
UINT16 tcpCsumNeeded:1;
UINT16 udpCsumNeeded:1;
UINT16 udpCsumZero:1;
UINT16 urg_ptr;
} TCPHdr;
+typedef struct SCTPHdr {
+ UINT16 source;
+ UINT16 dest;
+ UINT32 vtag;
+ UINT32 check;
+} SCTPHdr;
+
typedef struct PseudoHdr {
UINT32 sourceIPAddr;
UINT32 destIPAddr;
#define SOCKET_IPPROTO_TCP 6
#define SOCKET_IPPROTO_UDP 17
#define SOCKET_IPPROTO_GRE 47
+#define SOCKET_IPPROTO_SCTP 132
#endif /* __NET_PROTO_H_ */
}
}
+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);
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);
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,