git://git.onelab.eu
/
sliver-openvswitch.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
ofproto-dpif: Add SCTP support
[sliver-openvswitch.git]
/
lib
/
flow.c
diff --git
a/lib/flow.c
b/lib/flow.c
index
3e29aa1
..
ab49b80
100644
(file)
--- a/
lib/flow.c
+++ b/
lib/flow.c
@@
-81,6
+81,12
@@
pull_udp(struct ofpbuf *packet)
return ofpbuf_try_pull(packet, UDP_HEADER_LEN);
}
return ofpbuf_try_pull(packet, UDP_HEADER_LEN);
}
+static struct sctp_header *
+pull_sctp(struct ofpbuf *packet)
+{
+ return ofpbuf_try_pull(packet, SCTP_HEADER_LEN);
+}
+
static struct icmp_header *
pull_icmp(struct ofpbuf *packet)
{
static struct icmp_header *
pull_icmp(struct ofpbuf *packet)
{
@@
-265,6
+271,17
@@
parse_udp(struct ofpbuf *packet, struct ofpbuf *b, struct flow *flow)
}
}
}
}
+static void
+parse_sctp(struct ofpbuf *packet, struct ofpbuf *b, struct flow *flow)
+{
+ const struct sctp_header *sctp = pull_sctp(b);
+ if (sctp) {
+ flow->tp_src = sctp->sctp_src;
+ flow->tp_dst = sctp->sctp_dst;
+ packet->l7 = b->data;
+ }
+}
+
static bool
parse_icmpv6(struct ofpbuf *b, struct flow *flow)
{
static bool
parse_icmpv6(struct ofpbuf *b, struct flow *flow)
{
@@
-352,7
+369,7
@@
invalid:
* - packet->l4 to just past the IPv4 header, if one is present and has a
* correct length, and otherwise NULL.
*
* - 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/
ICMP header, if one is
* present and has a correct length, and otherwise NULL.
*/
void
* present and has a correct length, and otherwise NULL.
*/
void
@@
-430,6
+447,8
@@
flow_extract(struct ofpbuf *packet, uint32_t skb_priority, uint32_t pkt_mark,
parse_tcp(packet, &b, flow);
} else if (flow->nw_proto == IPPROTO_UDP) {
parse_udp(packet, &b, flow);
parse_tcp(packet, &b, flow);
} else if (flow->nw_proto == IPPROTO_UDP) {
parse_udp(packet, &b, flow);
+ } else if (flow->nw_proto == IPPROTO_SCTP) {
+ parse_sctp(packet, &b, flow);
} else if (flow->nw_proto == IPPROTO_ICMP) {
const struct icmp_header *icmp = pull_icmp(&b);
if (icmp) {
} else if (flow->nw_proto == IPPROTO_ICMP) {
const struct icmp_header *icmp = pull_icmp(&b);
if (icmp) {
@@
-450,6
+469,8
@@
flow_extract(struct ofpbuf *packet, uint32_t skb_priority, uint32_t pkt_mark,
parse_tcp(packet, &b, flow);
} else if (flow->nw_proto == IPPROTO_UDP) {
parse_udp(packet, &b, flow);
parse_tcp(packet, &b, flow);
} else if (flow->nw_proto == IPPROTO_UDP) {
parse_udp(packet, &b, flow);
+ } else if (flow->nw_proto == IPPROTO_SCTP) {
+ parse_sctp(packet, &b, flow);
} else if (flow->nw_proto == IPPROTO_ICMPV6) {
if (parse_icmpv6(&b, flow)) {
packet->l7 = b.data;
} else if (flow->nw_proto == IPPROTO_ICMPV6) {
if (parse_icmpv6(&b, flow)) {
packet->l7 = b.data;
@@
-761,7
+782,7
@@
flow_hash_symmetric_l4(const struct flow *flow, uint32_t basis)
if (fields.eth_type == htons(ETH_TYPE_IP)) {
fields.ipv4_addr = flow->nw_src ^ flow->nw_dst;
fields.ip_proto = flow->nw_proto;
if (fields.eth_type == htons(ETH_TYPE_IP)) {
fields.ipv4_addr = flow->nw_src ^ flow->nw_dst;
fields.ip_proto = flow->nw_proto;
- if (fields.ip_proto == IPPROTO_TCP) {
+ if (fields.ip_proto == IPPROTO_TCP
|| fields.ip_proto == IPPROTO_SCTP
) {
fields.tp_port = flow->tp_src ^ flow->tp_dst;
}
} else if (fields.eth_type == htons(ETH_TYPE_IPV6)) {
fields.tp_port = flow->tp_src ^ flow->tp_dst;
}
} else if (fields.eth_type == htons(ETH_TYPE_IPV6)) {
@@
-773,7
+794,7
@@
flow_hash_symmetric_l4(const struct flow *flow, uint32_t basis)
ipv6_addr[i] = a[i] ^ b[i];
}
fields.ip_proto = flow->nw_proto;
ipv6_addr[i] = a[i] ^ b[i];
}
fields.ip_proto = flow->nw_proto;
- if (fields.ip_proto == IPPROTO_TCP) {
+ if (fields.ip_proto == IPPROTO_TCP
|| fields.ip_proto == IPPROTO_SCTP
) {
fields.tp_port = flow->tp_src ^ flow->tp_dst;
}
}
fields.tp_port = flow->tp_src ^ flow->tp_dst;
}
}
@@
-999,6
+1020,12
@@
flow_compose(struct ofpbuf *b, const struct flow *flow)
b->l4 = udp = ofpbuf_put_zeros(b, sizeof *udp);
udp->udp_src = flow->tp_src;
udp->udp_dst = flow->tp_dst;
b->l4 = udp = ofpbuf_put_zeros(b, sizeof *udp);
udp->udp_src = flow->tp_src;
udp->udp_dst = flow->tp_dst;
+ } else if (flow->nw_proto == IPPROTO_SCTP) {
+ struct sctp_header *sctp;
+
+ b->l4 = sctp = ofpbuf_put_zeros(b, sizeof *sctp);
+ sctp->sctp_src = flow->tp_src;
+ sctp->sctp_dst = flow->tp_dst;
} else if (flow->nw_proto == IPPROTO_ICMP) {
struct icmp_header *icmp;
} else if (flow->nw_proto == IPPROTO_ICMP) {
struct icmp_header *icmp;