[ovs-dev] [PATCH 4/4] ofp-util: Support matching on SCTP src, dst ports
Joe Stringer
joe at wand.net.nz
Fri Aug 31 10:44:35 UTC 2012
Signed-off-by: Joe Stringer <joe at wand.net.nz>
---
lib/classifier.c | 4 ++++
lib/meta-flow.c | 40 ++++++++++++++++++++++++++++++++++++++++
lib/meta-flow.h | 4 ++++
lib/nx-match.c | 3 +++
lib/ofp-parse.c | 2 ++
lib/ofp-print.c | 6 ++++++
lib/ofp-util.c | 8 +++-----
tests/ovs-ofctl.at | 9 +++------
tests/test-netflow.c | 6 ++++++
utilities/ovs-ofctl.8.in | 6 ++++++
10 files changed, 77 insertions(+), 11 deletions(-)
diff --git a/lib/classifier.c b/lib/classifier.c
index 38f1a4f..9e1b322 100644
--- a/lib/classifier.c
+++ b/lib/classifier.c
@@ -624,6 +624,8 @@ cls_rule_format(const struct cls_rule *rule, struct ds *s)
ds_put_cstr(s, "tcp,");
} else if (f->nw_proto == IPPROTO_UDP) {
ds_put_cstr(s, "udp,");
+ } else if (f->nw_proto == IPPROTO_SCTP) {
+ ds_put_cstr(s, "sctp,");
} else {
ds_put_cstr(s, "ip,");
skip_proto = false;
@@ -640,6 +642,8 @@ cls_rule_format(const struct cls_rule *rule, struct ds *s)
ds_put_cstr(s, "tcp6,");
} else if (f->nw_proto == IPPROTO_UDP) {
ds_put_cstr(s, "udp6,");
+ } else if (f->nw_proto == IPPROTO_SCTP) {
+ ds_put_cstr(s, "sctp6,");
} else {
ds_put_cstr(s, "ipv6,");
skip_proto = false;
diff --git a/lib/meta-flow.c b/lib/meta-flow.c
index 3713ca4..7fa3881 100644
--- a/lib/meta-flow.c
+++ b/lib/meta-flow.c
@@ -387,6 +387,26 @@ static const struct mf_field mf_fields[MFF_N_IDS] = {
},
{
+ MFF_SCTP_SRC, "sctp_src", NULL,
+ MF_FIELD_SIZES(be16),
+ MFM_FULLY, 0,
+ MFS_DECIMAL,
+ MFP_SCTP,
+ true,
+ OXM_OF_SCTP_SRC, "OXM_OF_SCTP_SRC",
+ OXM_OF_SCTP_SRC, "OXM_OF_SCTP_SRC",
+ }, {
+ MFF_SCTP_DST, "sctp_dst", NULL,
+ MF_FIELD_SIZES(be16),
+ MFM_FULLY, 0,
+ MFS_DECIMAL,
+ MFP_SCTP,
+ true,
+ OXM_OF_SCTP_DST, "OXM_OF_SCTP_DST",
+ OXM_OF_SCTP_DST, "OXM_OF_SCTP_DST",
+ },
+
+ {
MFF_ICMPV4_TYPE, "icmp_type", NULL,
MF_FIELD_SIZES(u8),
MFM_NONE, 0,
@@ -640,11 +660,13 @@ mf_is_all_wild(const struct mf_field *mf, const struct flow_wildcards *wc)
case MFF_TCP_SRC:
case MFF_UDP_SRC:
+ case MFF_SCTP_SRC:
case MFF_ICMPV4_TYPE:
case MFF_ICMPV6_TYPE:
return !wc->tp_src_mask;
case MFF_TCP_DST:
case MFF_UDP_DST:
+ case MFF_SCTP_DST:
case MFF_ICMPV4_CODE:
case MFF_ICMPV6_CODE:
return !wc->tp_dst_mask;
@@ -752,10 +774,12 @@ mf_get_mask(const struct mf_field *mf, const struct flow_wildcards *wc,
case MFF_TCP_SRC:
case MFF_UDP_SRC:
+ case MFF_SCTP_SRC:
mask->be16 = wc->tp_src_mask;
break;
case MFF_TCP_DST:
case MFF_UDP_DST:
+ case MFF_SCTP_DST:
mask->be16 = wc->tp_dst_mask;
break;
@@ -835,6 +859,8 @@ mf_are_prereqs_ok(const struct mf_field *mf, const struct flow *flow)
return is_ip_any(flow) && flow->nw_proto == IPPROTO_TCP;
case MFP_UDP:
return is_ip_any(flow) && flow->nw_proto == IPPROTO_UDP;
+ case MFP_SCTP:
+ return is_ip_any(flow) && flow->nw_proto == IPPROTO_SCTP;
case MFP_ICMPV4:
return is_icmpv4(flow);
case MFP_ICMPV6:
@@ -894,6 +920,8 @@ mf_is_value_valid(const struct mf_field *mf, const union mf_value *value)
case MFF_TCP_DST:
case MFF_UDP_SRC:
case MFF_UDP_DST:
+ case MFF_SCTP_SRC:
+ case MFF_SCTP_DST:
case MFF_ICMPV4_TYPE:
case MFF_ICMPV4_CODE:
case MFF_ICMPV6_TYPE:
@@ -1045,11 +1073,13 @@ mf_get_value(const struct mf_field *mf, const struct flow *flow,
case MFF_TCP_SRC:
case MFF_UDP_SRC:
+ case MFF_SCTP_SRC:
value->be16 = flow->tp_src;
break;
case MFF_TCP_DST:
case MFF_UDP_DST:
+ case MFF_SCTP_DST:
value->be16 = flow->tp_dst;
break;
@@ -1188,11 +1218,13 @@ mf_set_value(const struct mf_field *mf,
case MFF_TCP_SRC:
case MFF_UDP_SRC:
+ case MFF_SCTP_SRC:
cls_rule_set_tp_src(rule, value->be16);
break;
case MFF_TCP_DST:
case MFF_UDP_DST:
+ case MFF_SCTP_DST:
cls_rule_set_tp_dst(rule, value->be16);
break;
@@ -1333,11 +1365,13 @@ mf_set_flow_value(const struct mf_field *mf,
case MFF_TCP_SRC:
case MFF_UDP_SRC:
+ case MFF_SCTP_SRC:
flow->tp_src = value->be16;
break;
case MFF_TCP_DST:
case MFF_UDP_DST:
+ case MFF_SCTP_DST:
flow->tp_dst = value->be16;
break;
@@ -1495,6 +1529,7 @@ mf_set_wild(const struct mf_field *mf, struct cls_rule *rule)
case MFF_TCP_SRC:
case MFF_UDP_SRC:
+ case MFF_SCTP_SRC:
case MFF_ICMPV4_TYPE:
case MFF_ICMPV6_TYPE:
rule->wc.tp_src_mask = htons(0);
@@ -1503,6 +1538,7 @@ mf_set_wild(const struct mf_field *mf, struct cls_rule *rule)
case MFF_TCP_DST:
case MFF_UDP_DST:
+ case MFF_SCTP_DST:
case MFF_ICMPV4_CODE:
case MFF_ICMPV6_CODE:
rule->wc.tp_dst_mask = htons(0);
@@ -1641,11 +1677,13 @@ mf_set(const struct mf_field *mf,
case MFF_TCP_SRC:
case MFF_UDP_SRC:
+ case MFF_SCTP_SRC:
cls_rule_set_tp_src_masked(rule, value->be16, mask->be16);
break;
case MFF_TCP_DST:
case MFF_UDP_DST:
+ case MFF_SCTP_DST:
cls_rule_set_tp_dst_masked(rule, value->be16, mask->be16);
break;
@@ -1743,6 +1781,8 @@ mf_random_value(const struct mf_field *mf, union mf_value *value)
case MFF_TCP_DST:
case MFF_UDP_SRC:
case MFF_UDP_DST:
+ case MFF_SCTP_SRC:
+ case MFF_SCTP_DST:
case MFF_ICMPV4_TYPE:
case MFF_ICMPV4_CODE:
case MFF_ICMPV6_TYPE:
diff --git a/lib/meta-flow.h b/lib/meta-flow.h
index 12a4baa..91c1d31 100644
--- a/lib/meta-flow.h
+++ b/lib/meta-flow.h
@@ -98,6 +98,9 @@ enum mf_field_id {
MFF_UDP_SRC, /* be16 (used for IPv4 or IPv6) */
MFF_UDP_DST, /* be16 (used for IPv4 or IPv6) */
+ MFF_SCTP_SRC, /* be16 (used for IPv4 or IPv6) */
+ MFF_SCTP_DST, /* be16 (used for IPv4 or IPv6) */
+
MFF_ICMPV4_TYPE, /* u8 */
MFF_ICMPV4_CODE, /* u8 */
@@ -164,6 +167,7 @@ enum mf_prereqs {
/* L2+L3 requirements. */
MFP_TCP, /* On IPv4 or IPv6. */
MFP_UDP, /* On IPv4 or IPv6. */
+ MFP_SCTP,
MFP_ICMPV4,
MFP_ICMPV6,
diff --git a/lib/nx-match.c b/lib/nx-match.c
index 16c1674..82cd7ef 100644
--- a/lib/nx-match.c
+++ b/lib/nx-match.c
@@ -527,6 +527,9 @@ nxm_put_ip(struct ofpbuf *b, const struct cls_rule *cr,
flow->tp_src, cr->wc.tp_src_mask);
nxm_put_16m(b, oxm ? OXM_OF_UDP_DST : NXM_OF_UDP_DST,
flow->tp_dst, cr->wc.tp_dst_mask);
+ } else if (flow->nw_proto == IPPROTO_SCTP) {
+ nxm_put_16m(b, OXM_OF_SCTP_SRC, flow->tp_src, cr->wc.tp_src_mask);
+ nxm_put_16m(b, OXM_OF_SCTP_DST, flow->tp_dst, cr->wc.tp_dst_mask);
} else if (flow->nw_proto == icmp_proto) {
if (cr->wc.tp_src_mask) {
nxm_put_8(b, icmp_type, ntohs(flow->tp_src));
diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c
index 0d904b1..e4d7a93 100644
--- a/lib/ofp-parse.c
+++ b/lib/ofp-parse.c
@@ -522,11 +522,13 @@ parse_protocol(const char *name, const struct protocol **p_out)
{ "icmp", ETH_TYPE_IP, IPPROTO_ICMP },
{ "tcp", ETH_TYPE_IP, IPPROTO_TCP },
{ "udp", ETH_TYPE_IP, IPPROTO_UDP },
+ { "sctp", ETH_TYPE_IP, IPPROTO_SCTP },
{ "ipv6", ETH_TYPE_IPV6, 0 },
{ "ip6", ETH_TYPE_IPV6, 0 },
{ "icmp6", ETH_TYPE_IPV6, IPPROTO_ICMPV6 },
{ "tcp6", ETH_TYPE_IPV6, IPPROTO_TCP },
{ "udp6", ETH_TYPE_IPV6, IPPROTO_UDP },
+ { "sctp6", ETH_TYPE_IPV6, IPPROTO_SCTP },
};
const struct protocol *p;
diff --git a/lib/ofp-print.c b/lib/ofp-print.c
index 99e6456..221baa4 100644
--- a/lib/ofp-print.c
+++ b/lib/ofp-print.c
@@ -75,6 +75,10 @@ ofp_packet_to_string(const void *data, size_t len)
struct udp_header *uh = buf.l4;
ds_put_format(&ds, " udp_csum:%"PRIx16,
ntohs(uh->udp_csum));
+ } else if (flow.nw_proto == IPPROTO_SCTP) {
+ struct sctp_header *sh = buf.l4;
+ ds_put_format(&ds, " sctp_csum:%"PRIx32,
+ ntohs(sh->sctp_csum));
}
}
@@ -607,6 +611,8 @@ ofp10_match_to_string(const struct ofp10_match *om, int verbosity)
ds_put_cstr(&f, "tcp,");
} else if (om->nw_proto == IPPROTO_UDP) {
ds_put_cstr(&f, "udp,");
+ } else if (om->nw_proto == IPPROTO_SCTP) {
+ ds_put_cstr(&f, "sctp,");
} else {
ds_put_cstr(&f, "ip,");
skip_proto = false;
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index ce9bb74..2259f0d 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -427,6 +427,7 @@ ofputil_cls_rule_from_ofp11_match(const struct ofp11_match *match,
case IPPROTO_TCP:
case IPPROTO_UDP:
+ case IPPROTO_SCTP:
if (!(wc & (OFPFW11_TP_SRC))) {
cls_rule_set_tp_src(rule, match->tp_src);
}
@@ -435,11 +436,6 @@ ofputil_cls_rule_from_ofp11_match(const struct ofp11_match *match,
}
break;
- case IPPROTO_SCTP:
- /* We don't support SCTP and it seems that we should tell the
- * controller, since OF1.1 implementations are supposed to. */
- return OFPERR_OFPBMC_BAD_FIELD;
-
default:
/* OF1.1 says explicitly to ignore this. */
break;
@@ -3608,12 +3604,14 @@ ofputil_normalize_rule__(struct cls_rule *rule, bool may_log)
may_match = MAY_NW_PROTO | MAY_IPVx | MAY_NW_ADDR;
if (rule->flow.nw_proto == IPPROTO_TCP ||
rule->flow.nw_proto == IPPROTO_UDP ||
+ rule->flow.nw_proto == IPPROTO_SCTP ||
rule->flow.nw_proto == IPPROTO_ICMP) {
may_match |= MAY_TP_ADDR;
}
} else if (rule->flow.dl_type == htons(ETH_TYPE_IPV6)) {
may_match = MAY_NW_PROTO | MAY_IPVx | MAY_IPV6;
if (rule->flow.nw_proto == IPPROTO_TCP ||
+ rule->flow.nw_proto == IPPROTO_SCTP ||
rule->flow.nw_proto == IPPROTO_UDP) {
may_match |= MAY_TP_ADDR;
} else if (rule->flow.nw_proto == IPPROTO_ICMPV6) {
diff --git a/tests/ovs-ofctl.at b/tests/ovs-ofctl.at
index 947f985..af2cb53 100644
--- a/tests/ovs-ofctl.at
+++ b/tests/ovs-ofctl.at
@@ -1159,22 +1159,19 @@ dnl Try invalid TOS:
0000 00 00 0800 00 11 00000000ffffffff 00000000ffffffff 0000 01bb dnl
00000000 00 000000 0000000000000000ffffffffffffffff
-dnl SCTP, no ports.
-# ip,nw_proto=132
+# sctp
0000 0058 00000000 000003d7 dnl
000000000000ffffffffffff 000000000000ffffffffffff dnl
0000 00 00 0800 00 84 00000000ffffffff 00000000ffffffff 0000 0000 dnl
00000000 00 000000 0000000000000000ffffffffffffffff
-dnl SCTP tp_src matching not supported:
-# bad ofp11_match: OFPBMC_BAD_FIELD
+# sctp,tp_src=443
0000 0058 00000000 00000397 dnl
000000000000ffffffffffff 000000000000ffffffffffff dnl
0000 00 00 0800 00 84 00000000ffffffff 00000000ffffffff 01bb 0000 dnl
00000000 00 000000 0000000000000000ffffffffffffffff
-dnl SCTP tp_dst matching not supported:
-# bad ofp11_match: OFPBMC_BAD_FIELD
+# sctp,tp_dst=443
0000 0058 00000000 00000357 dnl
000000000000ffffffffffff 000000000000ffffffffffff dnl
0000 00 00 0800 00 84 00000000ffffffff 00000000ffffffff 0000 01bb dnl
diff --git a/tests/test-netflow.c b/tests/test-netflow.c
index 85ab5e7..0cf44eb 100644
--- a/tests/test-netflow.c
+++ b/tests/test-netflow.c
@@ -100,6 +100,11 @@ print_netflow(struct ofpbuf *buf)
ntohs(rec->src_port), ntohs(rec->dst_port));
break;
+ case IPPROTO_SCTP:
+ printf(", SCTP %"PRIu16" > %"PRIu16,
+ ntohs(rec->src_port), ntohs(rec->dst_port));
+ break;
+
case IPPROTO_ICMP:
printf(", ICMP %"PRIu16":%"PRIu16,
ntohs(rec->dst_port) >> 8,
@@ -120,6 +125,7 @@ print_netflow(struct ofpbuf *buf)
if (rec->ip_proto != IPPROTO_TCP &&
rec->ip_proto != IPPROTO_UDP &&
+ rec->ip_proto != IPPROTO_SCTP &&
rec->ip_proto != IPPROTO_ICMP) {
if (rec->src_port != htons(0)) {
printf(", src_port %"PRIu16, ntohs(rec->src_port));
diff --git a/utilities/ovs-ofctl.8.in b/utilities/ovs-ofctl.8.in
index aad9325..29386da 100644
--- a/utilities/ovs-ofctl.8.in
+++ b/utilities/ovs-ofctl.8.in
@@ -637,6 +637,9 @@ Same as \fBdl_type=0x0800,nw_proto=6\fR.
.IP \fBudp\fR
Same as \fBdl_type=0x0800,nw_proto=17\fR.
.
+.IP \fBsctp\fR
+Same as \fBdl_type=0x0800,nw_proto=132\fR.
+.
.IP \fBarp\fR
Same as \fBdl_type=0x0806\fR.
.
@@ -784,6 +787,9 @@ Same as \fBdl_type=0x86dd,nw_proto=6\fR.
.IP \fBudp6\fR
Same as \fBdl_type=0x86dd,nw_proto=17\fR.
.
+.IP \fBsctp6\fR
+Same as \fBdl_type=0x86dd,nw_proto=132\fR.
+.
.IP \fBicmp6\fR
Same as \fBdl_type=0x86dd,nw_proto=58\fR.
.
--
1.7.2.5
More information about the dev
mailing list