|
@@ -1201,7 +1201,7 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
|
|
u16 addr_type = 0;
|
|
u16 addr_type = 0;
|
|
u8 ip_proto = 0;
|
|
u8 ip_proto = 0;
|
|
|
|
|
|
- *min_inline = MLX5_INLINE_MODE_L2;
|
|
|
|
|
|
+ *min_inline = MLX5_INLINE_MODE_NONE;
|
|
|
|
|
|
if (f->dissector->used_keys &
|
|
if (f->dissector->used_keys &
|
|
~(BIT(FLOW_DISSECTOR_KEY_CONTROL) |
|
|
~(BIT(FLOW_DISSECTOR_KEY_CONTROL) |
|
|
@@ -1251,58 +1251,6 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
|
|
inner_headers);
|
|
inner_headers);
|
|
}
|
|
}
|
|
|
|
|
|
- if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_CONTROL)) {
|
|
|
|
- struct flow_dissector_key_control *key =
|
|
|
|
- skb_flow_dissector_target(f->dissector,
|
|
|
|
- FLOW_DISSECTOR_KEY_CONTROL,
|
|
|
|
- f->key);
|
|
|
|
-
|
|
|
|
- struct flow_dissector_key_control *mask =
|
|
|
|
- skb_flow_dissector_target(f->dissector,
|
|
|
|
- FLOW_DISSECTOR_KEY_CONTROL,
|
|
|
|
- f->mask);
|
|
|
|
- addr_type = key->addr_type;
|
|
|
|
-
|
|
|
|
- /* the HW doesn't support frag first/later */
|
|
|
|
- if (mask->flags & FLOW_DIS_FIRST_FRAG)
|
|
|
|
- return -EOPNOTSUPP;
|
|
|
|
-
|
|
|
|
- if (mask->flags & FLOW_DIS_IS_FRAGMENT) {
|
|
|
|
- MLX5_SET(fte_match_set_lyr_2_4, headers_c, frag, 1);
|
|
|
|
- MLX5_SET(fte_match_set_lyr_2_4, headers_v, frag,
|
|
|
|
- key->flags & FLOW_DIS_IS_FRAGMENT);
|
|
|
|
-
|
|
|
|
- /* the HW doesn't need L3 inline to match on frag=no */
|
|
|
|
- if (key->flags & FLOW_DIS_IS_FRAGMENT)
|
|
|
|
- *min_inline = MLX5_INLINE_MODE_IP;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
|
|
|
|
- struct flow_dissector_key_basic *key =
|
|
|
|
- skb_flow_dissector_target(f->dissector,
|
|
|
|
- FLOW_DISSECTOR_KEY_BASIC,
|
|
|
|
- f->key);
|
|
|
|
- struct flow_dissector_key_basic *mask =
|
|
|
|
- skb_flow_dissector_target(f->dissector,
|
|
|
|
- FLOW_DISSECTOR_KEY_BASIC,
|
|
|
|
- f->mask);
|
|
|
|
- ip_proto = key->ip_proto;
|
|
|
|
-
|
|
|
|
- MLX5_SET(fte_match_set_lyr_2_4, headers_c, ethertype,
|
|
|
|
- ntohs(mask->n_proto));
|
|
|
|
- MLX5_SET(fte_match_set_lyr_2_4, headers_v, ethertype,
|
|
|
|
- ntohs(key->n_proto));
|
|
|
|
-
|
|
|
|
- MLX5_SET(fte_match_set_lyr_2_4, headers_c, ip_protocol,
|
|
|
|
- mask->ip_proto);
|
|
|
|
- MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_protocol,
|
|
|
|
- key->ip_proto);
|
|
|
|
-
|
|
|
|
- if (mask->ip_proto)
|
|
|
|
- *min_inline = MLX5_INLINE_MODE_IP;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
|
|
if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
|
|
struct flow_dissector_key_eth_addrs *key =
|
|
struct flow_dissector_key_eth_addrs *key =
|
|
skb_flow_dissector_target(f->dissector,
|
|
skb_flow_dissector_target(f->dissector,
|
|
@@ -1326,6 +1274,9 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
|
|
ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v,
|
|
ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v,
|
|
smac_47_16),
|
|
smac_47_16),
|
|
key->src);
|
|
key->src);
|
|
|
|
+
|
|
|
|
+ if (!is_zero_ether_addr(mask->src) || !is_zero_ether_addr(mask->dst))
|
|
|
|
+ *min_inline = MLX5_INLINE_MODE_L2;
|
|
}
|
|
}
|
|
|
|
|
|
if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_VLAN)) {
|
|
if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_VLAN)) {
|
|
@@ -1346,9 +1297,79 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
|
|
|
|
|
|
MLX5_SET(fte_match_set_lyr_2_4, headers_c, first_prio, mask->vlan_priority);
|
|
MLX5_SET(fte_match_set_lyr_2_4, headers_c, first_prio, mask->vlan_priority);
|
|
MLX5_SET(fte_match_set_lyr_2_4, headers_v, first_prio, key->vlan_priority);
|
|
MLX5_SET(fte_match_set_lyr_2_4, headers_v, first_prio, key->vlan_priority);
|
|
|
|
+
|
|
|
|
+ *min_inline = MLX5_INLINE_MODE_L2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
|
|
|
|
+ struct flow_dissector_key_basic *key =
|
|
|
|
+ skb_flow_dissector_target(f->dissector,
|
|
|
|
+ FLOW_DISSECTOR_KEY_BASIC,
|
|
|
|
+ f->key);
|
|
|
|
+ struct flow_dissector_key_basic *mask =
|
|
|
|
+ skb_flow_dissector_target(f->dissector,
|
|
|
|
+ FLOW_DISSECTOR_KEY_BASIC,
|
|
|
|
+ f->mask);
|
|
|
|
+ MLX5_SET(fte_match_set_lyr_2_4, headers_c, ethertype,
|
|
|
|
+ ntohs(mask->n_proto));
|
|
|
|
+ MLX5_SET(fte_match_set_lyr_2_4, headers_v, ethertype,
|
|
|
|
+ ntohs(key->n_proto));
|
|
|
|
+
|
|
|
|
+ if (mask->n_proto)
|
|
|
|
+ *min_inline = MLX5_INLINE_MODE_L2;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_CONTROL)) {
|
|
|
|
+ struct flow_dissector_key_control *key =
|
|
|
|
+ skb_flow_dissector_target(f->dissector,
|
|
|
|
+ FLOW_DISSECTOR_KEY_CONTROL,
|
|
|
|
+ f->key);
|
|
|
|
+
|
|
|
|
+ struct flow_dissector_key_control *mask =
|
|
|
|
+ skb_flow_dissector_target(f->dissector,
|
|
|
|
+ FLOW_DISSECTOR_KEY_CONTROL,
|
|
|
|
+ f->mask);
|
|
|
|
+ addr_type = key->addr_type;
|
|
|
|
+
|
|
|
|
+ /* the HW doesn't support frag first/later */
|
|
|
|
+ if (mask->flags & FLOW_DIS_FIRST_FRAG)
|
|
|
|
+ return -EOPNOTSUPP;
|
|
|
|
+
|
|
|
|
+ if (mask->flags & FLOW_DIS_IS_FRAGMENT) {
|
|
|
|
+ MLX5_SET(fte_match_set_lyr_2_4, headers_c, frag, 1);
|
|
|
|
+ MLX5_SET(fte_match_set_lyr_2_4, headers_v, frag,
|
|
|
|
+ key->flags & FLOW_DIS_IS_FRAGMENT);
|
|
|
|
+
|
|
|
|
+ /* the HW doesn't need L3 inline to match on frag=no */
|
|
|
|
+ if (!(key->flags & FLOW_DIS_IS_FRAGMENT))
|
|
|
|
+ *min_inline = MLX5_INLINE_MODE_L2;
|
|
|
|
+ /* *** L2 attributes parsing up to here *** */
|
|
|
|
+ else
|
|
|
|
+ *min_inline = MLX5_INLINE_MODE_IP;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
|
|
|
|
+ struct flow_dissector_key_basic *key =
|
|
|
|
+ skb_flow_dissector_target(f->dissector,
|
|
|
|
+ FLOW_DISSECTOR_KEY_BASIC,
|
|
|
|
+ f->key);
|
|
|
|
+ struct flow_dissector_key_basic *mask =
|
|
|
|
+ skb_flow_dissector_target(f->dissector,
|
|
|
|
+ FLOW_DISSECTOR_KEY_BASIC,
|
|
|
|
+ f->mask);
|
|
|
|
+ ip_proto = key->ip_proto;
|
|
|
|
+
|
|
|
|
+ MLX5_SET(fte_match_set_lyr_2_4, headers_c, ip_protocol,
|
|
|
|
+ mask->ip_proto);
|
|
|
|
+ MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_protocol,
|
|
|
|
+ key->ip_proto);
|
|
|
|
+
|
|
|
|
+ if (mask->ip_proto)
|
|
|
|
+ *min_inline = MLX5_INLINE_MODE_IP;
|
|
|
|
+ }
|
|
|
|
+
|
|
if (addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) {
|
|
if (addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) {
|
|
struct flow_dissector_key_ipv4_addrs *key =
|
|
struct flow_dissector_key_ipv4_addrs *key =
|
|
skb_flow_dissector_target(f->dissector,
|
|
skb_flow_dissector_target(f->dissector,
|
|
@@ -1433,6 +1454,8 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
|
|
*min_inline = MLX5_INLINE_MODE_IP;
|
|
*min_inline = MLX5_INLINE_MODE_IP;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /* *** L3 attributes parsing up to here *** */
|
|
|
|
+
|
|
if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_PORTS)) {
|
|
if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_PORTS)) {
|
|
struct flow_dissector_key_ports *key =
|
|
struct flow_dissector_key_ports *key =
|
|
skb_flow_dissector_target(f->dissector,
|
|
skb_flow_dissector_target(f->dissector,
|