Add IGMP info to struct flow, flow compose and flow extract.
Signed-off-by: Flavio Leitner <fbl@redhat.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
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;
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;
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);
}
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;
/* 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);
/* 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 */
uint32_t dp_hash; /* Datapath computed hash value. The exact
- computation is opaque to the user space.*/
+ * computation is opaque to the user space.
+ * Keep last for BUILD_ASSERT_DECL below. */
};
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.
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);
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) {
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);
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) {
* add another field and forget to adjust this value.
*/
#define ODPUTIL_FLOW_KEY_BYTES 512
-BUILD_ASSERT_DECL(FLOW_WC_SEQ == 26);
+BUILD_ASSERT_DECL(FLOW_WC_SEQ == 27);
/* A buffer with sufficient size and alignment to hold an nlattr-formatted flow
* key. An array of "struct nlattr" might not, in theory, be sufficiently
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);
/* 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");