[ovs-dev] [PATCH v3 2/7] flow: Add support for IGMP protocol
Flavio Leitner
fbl at redhat.com
Sat May 31 04:53:16 UTC 2014
Add IGMP support to struct flow, flow compose and flow extract.
Signed-off-by: Flavio Leitner <fbl at redhat.com>
---
lib/flow.c | 22 ++++++++++++++++++++--
lib/flow.h | 11 ++++++-----
lib/match.c | 8 +++++++-
lib/nx-match.c | 2 +-
lib/ofp-util.c | 2 +-
ofproto/ofproto-dpif-xlate.c | 2 +-
6 files changed, 36 insertions(+), 11 deletions(-)
diff --git a/lib/flow.c b/lib/flow.c
index da4f79b..ffa52e7 100644
--- a/lib/flow.c
+++ b/lib/flow.c
@@ -598,6 +598,15 @@ miniflow_extract(struct ofpbuf *packet, const struct pkt_metadata *md,
miniflow_push_be16(mf, tp_src, htons(icmp->icmp_type));
miniflow_push_be16(mf, tp_dst, htons(icmp->icmp_code));
}
+ } else if (OVS_LIKELY(nw_proto == IPPROTO_IGMP)) {
+ if (OVS_LIKELY(size >= IGMP_HEADER_LEN)) {
+ const struct igmp_header *igmp = data;
+
+ miniflow_push_be16(mf, tp_src, htons(igmp->igmp_type));
+ miniflow_push_be16(mf, tp_dst, htons(igmp->igmp_code));
+ miniflow_push_be32(mf, igmp_group_ip4,
+ get_16aligned_be32(&igmp->group));
+ }
} else if (OVS_LIKELY(nw_proto == IPPROTO_ICMPV6)) {
if (OVS_LIKELY(size >= sizeof(struct icmp6_hdr))) {
const struct in6_addr *nd_target = NULL;
@@ -656,7 +665,7 @@ flow_unwildcard_tp_ports(const struct flow *flow, struct flow_wildcards *wc)
void
flow_get_metadata(const struct flow *flow, struct flow_metadata *fmd)
{
- BUILD_ASSERT_DECL(FLOW_WC_SEQ == 26);
+ BUILD_ASSERT_DECL(FLOW_WC_SEQ == 27);
fmd->dp_hash = flow->dp_hash;
fmd->recirc_id = flow->recirc_id;
@@ -1316,7 +1325,7 @@ flow_push_mpls(struct flow *flow, int n, ovs_be16 mpls_eth_type,
flow->mpls_lse[0] = set_mpls_lse_values(ttl, tc, 1, htonl(label));
/* Clear all L3 and L4 fields. */
- BUILD_ASSERT(FLOW_WC_SEQ == 26);
+ BUILD_ASSERT(FLOW_WC_SEQ == 27);
memset((char *) flow + FLOW_SEGMENT_2_ENDS_AT, 0,
sizeof(struct flow) - FLOW_SEGMENT_2_ENDS_AT);
}
@@ -1427,6 +1436,15 @@ flow_compose_l4(struct ofpbuf *b, const struct flow *flow)
icmp->icmp_type = ntohs(flow->tp_src);
icmp->icmp_code = ntohs(flow->tp_dst);
icmp->icmp_csum = csum(icmp, ICMP_HEADER_LEN);
+ } else if (flow->nw_proto == IPPROTO_IGMP) {
+ struct igmp_header *igmp;
+
+ l4_len = sizeof *igmp;
+ igmp = ofpbuf_put_zeros(b, l4_len);
+ igmp->igmp_type = ntohs(flow->tp_src);
+ igmp->igmp_code = ntohs(flow->tp_dst);
+ put_16aligned_be32(&igmp->group, flow->igmp_group_ip4);
+ igmp->igmp_csum = csum(igmp, IGMP_HEADER_LEN);
} else if (flow->nw_proto == IPPROTO_ICMPV6) {
struct icmp6_hdr *icmp;
diff --git a/lib/flow.h b/lib/flow.h
index 139e7f6..e75e6f6 100644
--- a/lib/flow.h
+++ b/lib/flow.h
@@ -38,7 +38,7 @@ struct pkt_metadata;
/* This sequence number should be incremented whenever anything involving flows
* or the wildcarding of flows changes. This will cause build assertion
* failures in places which likely need to be updated. */
-#define FLOW_WC_SEQ 26
+#define FLOW_WC_SEQ 27
#define FLOW_N_REGS 8
BUILD_ASSERT_DECL(FLOW_N_REGS <= NXM_NX_MAX_REGS);
@@ -118,8 +118,9 @@ struct flow {
/* L4 */
ovs_be16 tp_src; /* TCP/UDP/SCTP source port. */
- ovs_be16 tp_dst; /* TCP/UDP/SCTP destination port.
- * Keep last for the BUILD_ASSERT_DECL below */
+ ovs_be16 tp_dst; /* TCP/UDP/SCTP destination port. */
+ ovs_be32 igmp_group_ip4; /* IGMP group IPv4 address */
+ /* Keep last for the BUILD_ASSERT_DECL below */
uint32_t dp_hash; /* Datapath computed hash value. The exact
computation is opaque to the user space.*/
};
@@ -129,8 +130,8 @@ BUILD_ASSERT_DECL(sizeof(struct flow) % 4 == 0);
/* Remember to update FLOW_WC_SEQ when changing 'struct flow'. */
BUILD_ASSERT_DECL(offsetof(struct flow, dp_hash) + sizeof(uint32_t)
- == sizeof(struct flow_tnl) + 172
- && FLOW_WC_SEQ == 26);
+ == sizeof(struct flow_tnl) + 176
+ && FLOW_WC_SEQ == 27);
/* Incremental points at which flow classification may be performed in
* segments.
diff --git a/lib/match.c b/lib/match.c
index 308f906..6c67d08 100644
--- a/lib/match.c
+++ b/lib/match.c
@@ -943,7 +943,7 @@ match_format(const struct match *match, struct ds *s, unsigned int priority)
int i;
- BUILD_ASSERT_DECL(FLOW_WC_SEQ == 26);
+ BUILD_ASSERT_DECL(FLOW_WC_SEQ == 27);
if (priority != OFP_DEFAULT_PRIORITY) {
ds_put_format(s, "priority=%u,", priority);
@@ -972,6 +972,8 @@ match_format(const struct match *match, struct ds *s, unsigned int priority)
skip_proto = true;
if (f->nw_proto == IPPROTO_ICMP) {
ds_put_cstr(s, "icmp,");
+ } else if (f->nw_proto == IPPROTO_IGMP) {
+ ds_put_cstr(s, "igmp,");
} else if (f->nw_proto == IPPROTO_TCP) {
ds_put_cstr(s, "tcp,");
} else if (f->nw_proto == IPPROTO_UDP) {
@@ -1146,6 +1148,10 @@ match_format(const struct match *match, struct ds *s, unsigned int priority)
f->nw_proto == IPPROTO_ICMP) {
format_be16_masked(s, "icmp_type", f->tp_src, wc->masks.tp_src);
format_be16_masked(s, "icmp_code", f->tp_dst, wc->masks.tp_dst);
+ } else if (f->dl_type == htons(ETH_TYPE_IP) &&
+ f->nw_proto == IPPROTO_IGMP) {
+ format_be16_masked(s, "igmp_type", f->tp_src, wc->masks.tp_src);
+ format_be16_masked(s, "igmp_code", f->tp_dst, wc->masks.tp_dst);
} else if (f->dl_type == htons(ETH_TYPE_IPV6) &&
f->nw_proto == IPPROTO_ICMPV6) {
format_be16_masked(s, "icmp_type", f->tp_src, wc->masks.tp_src);
diff --git a/lib/nx-match.c b/lib/nx-match.c
index 295eec0..678e6f3 100644
--- a/lib/nx-match.c
+++ b/lib/nx-match.c
@@ -616,7 +616,7 @@ nx_put_raw(struct ofpbuf *b, enum ofp_version oxm, const struct match *match,
int match_len;
int i;
- BUILD_ASSERT_DECL(FLOW_WC_SEQ == 26);
+ BUILD_ASSERT_DECL(FLOW_WC_SEQ == 27);
/* Metadata. */
if (match->wc.masks.dp_hash) {
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index 09e4438..9037fd4 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -132,7 +132,7 @@ ofputil_netmask_to_wcbits(ovs_be32 netmask)
void
ofputil_wildcard_from_ofpfw10(uint32_t ofpfw, struct flow_wildcards *wc)
{
- BUILD_ASSERT_DECL(FLOW_WC_SEQ == 26);
+ BUILD_ASSERT_DECL(FLOW_WC_SEQ == 27);
/* Initialize most of wc. */
flow_wildcards_init_catchall(wc);
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 068d54f..11f62f9 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -2137,7 +2137,7 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port,
/* If 'struct flow' gets additional metadata, we'll need to zero it out
* before traversing a patch port. */
- BUILD_ASSERT_DECL(FLOW_WC_SEQ == 26);
+ BUILD_ASSERT_DECL(FLOW_WC_SEQ == 27);
if (!xport) {
xlate_report(ctx, "Nonexistent output port");
--
1.9.3
More information about the dev
mailing list