|
@@ -212,11 +212,46 @@ static int mlxsw_sp_flower_parse_tcp(struct mlxsw_sp *mlxsw_sp,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int mlxsw_sp_flower_parse_ip(struct mlxsw_sp *mlxsw_sp,
|
|
|
+ struct mlxsw_sp_acl_rule_info *rulei,
|
|
|
+ struct tc_cls_flower_offload *f,
|
|
|
+ u16 n_proto)
|
|
|
+{
|
|
|
+ struct flow_dissector_key_ip *key, *mask;
|
|
|
+
|
|
|
+ if (!dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_IP))
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ if (n_proto != ETH_P_IP && n_proto != ETH_P_IPV6) {
|
|
|
+ dev_err(mlxsw_sp->bus_info->dev, "IP keys supported only for IPv4/6\n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ key = skb_flow_dissector_target(f->dissector,
|
|
|
+ FLOW_DISSECTOR_KEY_IP,
|
|
|
+ f->key);
|
|
|
+ mask = skb_flow_dissector_target(f->dissector,
|
|
|
+ FLOW_DISSECTOR_KEY_IP,
|
|
|
+ f->mask);
|
|
|
+ mlxsw_sp_acl_rulei_keymask_u32(rulei, MLXSW_AFK_ELEMENT_IP_TTL_,
|
|
|
+ key->ttl, mask->ttl);
|
|
|
+
|
|
|
+ mlxsw_sp_acl_rulei_keymask_u32(rulei, MLXSW_AFK_ELEMENT_IP_ECN,
|
|
|
+ key->tos & 0x3, mask->tos & 0x3);
|
|
|
+
|
|
|
+ mlxsw_sp_acl_rulei_keymask_u32(rulei, MLXSW_AFK_ELEMENT_IP_DSCP,
|
|
|
+ key->tos >> 6, mask->tos >> 6);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static int mlxsw_sp_flower_parse(struct mlxsw_sp *mlxsw_sp,
|
|
|
struct net_device *dev,
|
|
|
struct mlxsw_sp_acl_rule_info *rulei,
|
|
|
struct tc_cls_flower_offload *f)
|
|
|
{
|
|
|
+ u16 n_proto_mask = 0;
|
|
|
+ u16 n_proto_key = 0;
|
|
|
u16 addr_type = 0;
|
|
|
u8 ip_proto = 0;
|
|
|
int err;
|
|
@@ -229,6 +264,7 @@ static int mlxsw_sp_flower_parse(struct mlxsw_sp *mlxsw_sp,
|
|
|
BIT(FLOW_DISSECTOR_KEY_IPV6_ADDRS) |
|
|
|
BIT(FLOW_DISSECTOR_KEY_PORTS) |
|
|
|
BIT(FLOW_DISSECTOR_KEY_TCP) |
|
|
|
+ BIT(FLOW_DISSECTOR_KEY_IP) |
|
|
|
BIT(FLOW_DISSECTOR_KEY_VLAN))) {
|
|
|
dev_err(mlxsw_sp->bus_info->dev, "Unsupported key\n");
|
|
|
return -EOPNOTSUPP;
|
|
@@ -253,8 +289,8 @@ static int mlxsw_sp_flower_parse(struct mlxsw_sp *mlxsw_sp,
|
|
|
skb_flow_dissector_target(f->dissector,
|
|
|
FLOW_DISSECTOR_KEY_BASIC,
|
|
|
f->mask);
|
|
|
- u16 n_proto_key = ntohs(key->n_proto);
|
|
|
- u16 n_proto_mask = ntohs(mask->n_proto);
|
|
|
+ n_proto_key = ntohs(key->n_proto);
|
|
|
+ n_proto_mask = ntohs(mask->n_proto);
|
|
|
|
|
|
if (n_proto_key == ETH_P_ALL) {
|
|
|
n_proto_key = 0;
|
|
@@ -324,6 +360,10 @@ static int mlxsw_sp_flower_parse(struct mlxsw_sp *mlxsw_sp,
|
|
|
if (err)
|
|
|
return err;
|
|
|
|
|
|
+ err = mlxsw_sp_flower_parse_ip(mlxsw_sp, rulei, f, n_proto_key & n_proto_mask);
|
|
|
+ if (err)
|
|
|
+ return err;
|
|
|
+
|
|
|
return mlxsw_sp_flower_parse_actions(mlxsw_sp, dev, rulei, f->exts);
|
|
|
}
|
|
|
|