@@ -359,7 +359,7 @@ size_t ovs_key_attr_size(void)
/* Whenever adding new OVS_KEY_ FIELDS, we should consider
* updating this function.
*/
- BUILD_BUG_ON(OVS_KEY_ATTR_MAX != 31);
+ BUILD_BUG_ON(OVS_KEY_ATTR_MAX != 32);
return nla_total_size(4) /* OVS_KEY_ATTR_PRIORITY */
+ nla_total_size(0) /* OVS_KEY_ATTR_TUNNEL */
@@ -401,6 +401,7 @@ enum ovs_key_attr {
OVS_KEY_ATTR_TUNNEL_INFO, /* struct ip_tunnel_info.
* For in-kernel use only.
*/
+ OVS_KEY_ATTR_IPV6_EXTHDRS, /* struct ovs_key_ipv6_exthdr */
__OVS_KEY_ATTR_MAX
};
@@ -500,6 +501,11 @@ struct ovs_key_ipv6 {
__u8 ipv6_frag; /* One of OVS_FRAG_TYPE_*. */
};
+/* separate structure to support backward compatibility with older user space */
+struct ovs_key_ipv6_exthdrs {
+ __u16 hdrs;
+};
+
struct ovs_key_tcp {
__be16 tcp_src;
__be16 tcp_dst;
@@ -554,6 +554,7 @@ odp_execute_set_action(struct dp_packet *packet, const struct nlattr *a)
case OVS_KEY_ATTR_CT_MARK:
case OVS_KEY_ATTR_CT_LABELS:
case OVS_KEY_ATTR_TUNNEL_INFO:
+ case OVS_KEY_ATTR_IPV6_EXTHDRS:
case __OVS_KEY_ATTR_MAX:
default:
OVS_NOT_REACHED();
@@ -667,6 +668,7 @@ odp_execute_masked_set_action(struct dp_packet *packet,
case OVS_KEY_ATTR_ICMPV6:
case OVS_KEY_ATTR_TCP_FLAGS:
case OVS_KEY_ATTR_TUNNEL_INFO:
+ case OVS_KEY_ATTR_IPV6_EXTHDRS:
case __OVS_KEY_ATTR_MAX:
default:
OVS_NOT_REACHED();
@@ -192,6 +192,7 @@ ovs_key_attr_to_string(enum ovs_key_attr attr, char *namebuf, size_t bufsize)
case OVS_KEY_ATTR_RECIRC_ID: return "recirc_id";
case OVS_KEY_ATTR_PACKET_TYPE: return "packet_type";
case OVS_KEY_ATTR_NSH: return "nsh";
+ case OVS_KEY_ATTR_IPV6_EXTHDRS: return "ipv6_exthdrs";
case OVS_KEY_ATTR_TUNNEL_INFO: return "<error: kernel-only tunnel_info>";
case __OVS_KEY_ATTR_MAX:
@@ -2747,6 +2748,7 @@ const struct attr_len_tbl ovs_flow_key_attr_lens[OVS_KEY_ATTR_MAX + 1] = {
[OVS_KEY_ATTR_NSH] = { .len = ATTR_LEN_NESTED,
.next = ovs_nsh_key_attr_lens,
.next_max = OVS_NSH_KEY_ATTR_MAX },
+ [OVS_KEY_ATTR_IPV6_EXTHDRS] = { .len = sizeof(struct ovs_key_ipv6_exthdrs) },
};
/* Returns the correct length of the payload for a flow key attribute of the
@@ -3263,6 +3265,7 @@ odp_mask_is_constant__(enum ovs_key_attr attr, const void *mask, size_t size,
case OVS_KEY_ATTR_UNSPEC:
case OVS_KEY_ATTR_ENCAP:
case OVS_KEY_ATTR_TUNNEL_INFO:
+ case OVS_KEY_ATTR_IPV6_EXTHDRS:
case __OVS_KEY_ATTR_MAX:
default:
return false;
@@ -4415,6 +4418,7 @@ format_odp_key_attr__(const struct nlattr *a, const struct nlattr *ma,
}
case OVS_KEY_ATTR_UNSPEC:
case OVS_KEY_ATTR_TUNNEL_INFO:
+ case OVS_KEY_ATTR_IPV6_EXTHDRS:
case __OVS_KEY_ATTR_MAX:
default:
format_generic_odp_key(a, ds);
@@ -6620,6 +6624,7 @@ odp_key_to_dp_packet(const struct nlattr *key, size_t key_len,
case OVS_KEY_ATTR_PACKET_TYPE:
case OVS_KEY_ATTR_NSH:
case OVS_KEY_ATTR_TUNNEL_INFO:
+ case OVS_KEY_ATTR_IPV6_EXTHDRS:
case __OVS_KEY_ATTR_MAX:
default:
break;
@@ -6979,6 +6984,12 @@ parse_l2_5_onward(const struct nlattr *attrs[OVS_KEY_ATTR_MAX + 1],
expected_bit = OVS_KEY_ATTR_IPV6;
}
}
+ if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_IPV6_EXTHDRS)) {
+ if (!is_mask) {
+ *expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_IPV6_EXTHDRS;
+ VLOG_WARN_RL(&rl, "not parsing ipv6 exthdrs");
+ }
+ }
} else if (src_flow->dl_type == htons(ETH_TYPE_ARP) ||
src_flow->dl_type == htons(ETH_TYPE_RARP)) {
if (!is_mask) {
@@ -1067,6 +1067,7 @@ sflow_read_set_action(const struct nlattr *attr,
case OVS_KEY_ATTR_PACKET_TYPE:
case OVS_KEY_ATTR_NSH:
case OVS_KEY_ATTR_TUNNEL_INFO:
+ case OVS_KEY_ATTR_IPV6_EXTHDRS:
case __OVS_KEY_ATTR_MAX:
default:
break;