int offset;
int flower_offset;
int size;
+ int boundary_shift;
};
static struct flower_key_to_pedit flower_pedit_map[] = {
TCA_PEDIT_KEY_EX_HDR_TYPE_IP4,
12,
offsetof(struct tc_flower_key, ipv4.ipv4_src),
- MEMBER_SIZEOF(struct tc_flower_key, ipv4.ipv4_src)
+ MEMBER_SIZEOF(struct tc_flower_key, ipv4.ipv4_src),
+ 0
}, {
TCA_PEDIT_KEY_EX_HDR_TYPE_IP4,
16,
offsetof(struct tc_flower_key, ipv4.ipv4_dst),
- MEMBER_SIZEOF(struct tc_flower_key, ipv4.ipv4_dst)
+ MEMBER_SIZEOF(struct tc_flower_key, ipv4.ipv4_dst),
+ 0
}, {
TCA_PEDIT_KEY_EX_HDR_TYPE_IP4,
8,
offsetof(struct tc_flower_key, ipv4.rewrite_ttl),
- MEMBER_SIZEOF(struct tc_flower_key, ipv4.rewrite_ttl)
+ MEMBER_SIZEOF(struct tc_flower_key, ipv4.rewrite_ttl),
+ 0
}, {
TCA_PEDIT_KEY_EX_HDR_TYPE_IP4,
1,
offsetof(struct tc_flower_key, ipv4.rewrite_tos),
- MEMBER_SIZEOF(struct tc_flower_key, ipv4.rewrite_tos)
+ MEMBER_SIZEOF(struct tc_flower_key, ipv4.rewrite_tos),
+ 0
}, {
TCA_PEDIT_KEY_EX_HDR_TYPE_IP6,
7,
offsetof(struct tc_flower_key, ipv6.rewrite_hlimit),
- MEMBER_SIZEOF(struct tc_flower_key, ipv6.rewrite_hlimit)
+ MEMBER_SIZEOF(struct tc_flower_key, ipv6.rewrite_hlimit),
+ 0
}, {
TCA_PEDIT_KEY_EX_HDR_TYPE_IP6,
8,
offsetof(struct tc_flower_key, ipv6.ipv6_src),
- MEMBER_SIZEOF(struct tc_flower_key, ipv6.ipv6_src)
+ MEMBER_SIZEOF(struct tc_flower_key, ipv6.ipv6_src),
+ 0
}, {
TCA_PEDIT_KEY_EX_HDR_TYPE_IP6,
24,
offsetof(struct tc_flower_key, ipv6.ipv6_dst),
- MEMBER_SIZEOF(struct tc_flower_key, ipv6.ipv6_dst)
+ MEMBER_SIZEOF(struct tc_flower_key, ipv6.ipv6_dst),
+ 0
+ }, {
+ TCA_PEDIT_KEY_EX_HDR_TYPE_IP6,
+ 0,
+ offsetof(struct tc_flower_key, ipv6.rewrite_tclass),
+ MEMBER_SIZEOF(struct tc_flower_key, ipv6.rewrite_tclass),
+ 4
}, {
TCA_PEDIT_KEY_EX_HDR_TYPE_ETH,
6,
offsetof(struct tc_flower_key, src_mac),
- MEMBER_SIZEOF(struct tc_flower_key, src_mac)
+ MEMBER_SIZEOF(struct tc_flower_key, src_mac),
+ 0
}, {
TCA_PEDIT_KEY_EX_HDR_TYPE_ETH,
0,
offsetof(struct tc_flower_key, dst_mac),
- MEMBER_SIZEOF(struct tc_flower_key, dst_mac)
+ MEMBER_SIZEOF(struct tc_flower_key, dst_mac),
+ 0
}, {
TCA_PEDIT_KEY_EX_HDR_TYPE_ETH,
12,
offsetof(struct tc_flower_key, eth_type),
- MEMBER_SIZEOF(struct tc_flower_key, eth_type)
+ MEMBER_SIZEOF(struct tc_flower_key, eth_type),
+ 0
}, {
TCA_PEDIT_KEY_EX_HDR_TYPE_TCP,
0,
offsetof(struct tc_flower_key, tcp_src),
- MEMBER_SIZEOF(struct tc_flower_key, tcp_src)
+ MEMBER_SIZEOF(struct tc_flower_key, tcp_src),
+ 0
}, {
TCA_PEDIT_KEY_EX_HDR_TYPE_TCP,
2,
offsetof(struct tc_flower_key, tcp_dst),
- MEMBER_SIZEOF(struct tc_flower_key, tcp_dst)
+ MEMBER_SIZEOF(struct tc_flower_key, tcp_dst),
+ 0
}, {
TCA_PEDIT_KEY_EX_HDR_TYPE_UDP,
0,
offsetof(struct tc_flower_key, udp_src),
- MEMBER_SIZEOF(struct tc_flower_key, udp_src)
+ MEMBER_SIZEOF(struct tc_flower_key, udp_src),
+ 0
}, {
TCA_PEDIT_KEY_EX_HDR_TYPE_UDP,
2,
offsetof(struct tc_flower_key, udp_dst),
- MEMBER_SIZEOF(struct tc_flower_key, udp_dst)
+ MEMBER_SIZEOF(struct tc_flower_key, udp_dst),
+ 0
},
};
int diff = flower_off + (keys->off - mf);
ovs_be32 *dst = (void *) (rewrite_key + diff);
ovs_be32 *dst_m = (void *) (rewrite_mask + diff);
- ovs_be32 mask = ~(keys->mask);
+ ovs_be32 mask, mask_word, data_word;
uint32_t zero_bits;
+ mask_word = htonl(ntohl(keys->mask) << m->boundary_shift);
+ data_word = htonl(ntohl(keys->val) << m->boundary_shift);
+ mask = ~(mask_word);
+
if (keys->off < mf) {
zero_bits = 8 * (mf - keys->off);
mask &= htonl(UINT32_MAX >> zero_bits);
}
*dst_m |= mask;
- *dst |= keys->val & mask;
+ *dst |= data_word & mask;
}
}
for (j = 0; j < cnt; j++, mask++, data++, cur_offset += 4) {
ovs_be32 mask_word = *mask;
+ ovs_be32 data_word = *data;
if (j == 0) {
mask_word &= first_word_mask;
pedit_key_ex->cmd = TCA_PEDIT_KEY_EX_CMD_SET;
pedit_key_ex->htype = m->htype;
pedit_key->off = cur_offset;
+ mask_word = htonl(ntohl(mask_word) >> m->boundary_shift);
+ data_word = htonl(ntohl(data_word) >> m->boundary_shift);
pedit_key->mask = ~mask_word;
- pedit_key->val = *data & mask_word;
+ pedit_key->val = data_word & mask_word;
sel.sel.nkeys++;
err = csum_update_flag(flower, m->htype);