Skip to content

Commit e8317a4

Browse files
committed
Merge branch 'net-dissection-and-matching-on-tos-and-ttl'
Or Gerlitz says: ==================== net: add support for dissection and matching on ip tos and ttl The 1st two patches enable matching/classifying on ip tos and ttl by the flow dissector and flower. The other two patches offload matching on tcp flags and ip tos in mlx5. The mlx5 patches touch single file/function and not interfere with other inflight mlx5 submissions. V2: repost as asked by Dave. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents f4d0166 + fd7da28 commit e8317a4

File tree

5 files changed

+138
-3
lines changed

5 files changed

+138
-3
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en_tc.c

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,9 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
581581
BIT(FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS) |
582582
BIT(FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS) |
583583
BIT(FLOW_DISSECTOR_KEY_ENC_PORTS) |
584-
BIT(FLOW_DISSECTOR_KEY_ENC_CONTROL))) {
584+
BIT(FLOW_DISSECTOR_KEY_ENC_CONTROL) |
585+
BIT(FLOW_DISSECTOR_KEY_TCP) |
586+
BIT(FLOW_DISSECTOR_KEY_IP))) {
585587
netdev_warn(priv->netdev, "Unsupported key used: 0x%x\n",
586588
f->dissector->used_keys);
587589
return -EOPNOTSUPP;
@@ -808,6 +810,48 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
808810
*min_inline = MLX5_INLINE_MODE_TCP_UDP;
809811
}
810812

813+
if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_IP)) {
814+
struct flow_dissector_key_ip *key =
815+
skb_flow_dissector_target(f->dissector,
816+
FLOW_DISSECTOR_KEY_IP,
817+
f->key);
818+
struct flow_dissector_key_ip *mask =
819+
skb_flow_dissector_target(f->dissector,
820+
FLOW_DISSECTOR_KEY_IP,
821+
f->mask);
822+
823+
MLX5_SET(fte_match_set_lyr_2_4, headers_c, ip_ecn, mask->tos & 0x3);
824+
MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_ecn, key->tos & 0x3);
825+
826+
MLX5_SET(fte_match_set_lyr_2_4, headers_c, ip_dscp, mask->tos >> 2);
827+
MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_dscp, key->tos >> 2);
828+
829+
if (mask->tos)
830+
*min_inline = MLX5_INLINE_MODE_IP;
831+
832+
if (mask->ttl) /* currently not supported */
833+
return -EOPNOTSUPP;
834+
}
835+
836+
if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_TCP)) {
837+
struct flow_dissector_key_tcp *key =
838+
skb_flow_dissector_target(f->dissector,
839+
FLOW_DISSECTOR_KEY_TCP,
840+
f->key);
841+
struct flow_dissector_key_tcp *mask =
842+
skb_flow_dissector_target(f->dissector,
843+
FLOW_DISSECTOR_KEY_TCP,
844+
f->mask);
845+
846+
MLX5_SET(fte_match_set_lyr_2_4, headers_c, tcp_flags,
847+
ntohs(mask->flags));
848+
MLX5_SET(fte_match_set_lyr_2_4, headers_v, tcp_flags,
849+
ntohs(key->flags));
850+
851+
if (mask->flags)
852+
*min_inline = MLX5_INLINE_MODE_TCP_UDP;
853+
}
854+
811855
return 0;
812856
}
813857

include/net/flow_dissector.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,16 @@ struct flow_dissector_key_tcp {
165165
__be16 flags;
166166
};
167167

168+
/**
169+
* struct flow_dissector_key_ip:
170+
* @tos: tos
171+
* @ttl: ttl
172+
*/
173+
struct flow_dissector_key_ip {
174+
__u8 tos;
175+
__u8 ttl;
176+
};
177+
168178
enum flow_dissector_key_id {
169179
FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */
170180
FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
@@ -186,6 +196,7 @@ enum flow_dissector_key_id {
186196
FLOW_DISSECTOR_KEY_ENC_PORTS, /* struct flow_dissector_key_ports */
187197
FLOW_DISSECTOR_KEY_MPLS, /* struct flow_dissector_key_mpls */
188198
FLOW_DISSECTOR_KEY_TCP, /* struct flow_dissector_key_tcp */
199+
FLOW_DISSECTOR_KEY_IP, /* struct flow_dissector_key_ip */
189200

190201
FLOW_DISSECTOR_KEY_MAX,
191202
};

include/uapi/linux/pkt_cls.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,11 @@ enum {
454454
TCA_FLOWER_KEY_TCP_FLAGS, /* be16 */
455455
TCA_FLOWER_KEY_TCP_FLAGS_MASK, /* be16 */
456456

457+
TCA_FLOWER_KEY_IP_TOS, /* u8 */
458+
TCA_FLOWER_KEY_IP_TOS_MASK, /* u8 */
459+
TCA_FLOWER_KEY_IP_TTL, /* u8 */
460+
TCA_FLOWER_KEY_IP_TTL_MASK, /* u8 */
461+
457462
__TCA_FLOWER_MAX,
458463
};
459464

net/core/flow_dissector.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,40 @@ __skb_flow_dissect_tcp(const struct sk_buff *skb,
367367
key_tcp->flags = (*(__be16 *) &tcp_flag_word(th) & htons(0x0FFF));
368368
}
369369

370+
static void
371+
__skb_flow_dissect_ipv4(const struct sk_buff *skb,
372+
struct flow_dissector *flow_dissector,
373+
void *target_container, void *data, const struct iphdr *iph)
374+
{
375+
struct flow_dissector_key_ip *key_ip;
376+
377+
if (!dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_IP))
378+
return;
379+
380+
key_ip = skb_flow_dissector_target(flow_dissector,
381+
FLOW_DISSECTOR_KEY_IP,
382+
target_container);
383+
key_ip->tos = iph->tos;
384+
key_ip->ttl = iph->ttl;
385+
}
386+
387+
static void
388+
__skb_flow_dissect_ipv6(const struct sk_buff *skb,
389+
struct flow_dissector *flow_dissector,
390+
void *target_container, void *data, const struct ipv6hdr *iph)
391+
{
392+
struct flow_dissector_key_ip *key_ip;
393+
394+
if (!dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_IP))
395+
return;
396+
397+
key_ip = skb_flow_dissector_target(flow_dissector,
398+
FLOW_DISSECTOR_KEY_IP,
399+
target_container);
400+
key_ip->tos = ipv6_get_dsfield(iph);
401+
key_ip->ttl = iph->hop_limit;
402+
}
403+
370404
/**
371405
* __skb_flow_dissect - extract the flow_keys struct and return it
372406
* @skb: sk_buff to extract the flow from, can be NULL if the rest are specified
@@ -469,6 +503,9 @@ bool __skb_flow_dissect(const struct sk_buff *skb,
469503
}
470504
}
471505

506+
__skb_flow_dissect_ipv4(skb, flow_dissector,
507+
target_container, data, iph);
508+
472509
if (flags & FLOW_DISSECTOR_F_STOP_AT_L3)
473510
goto out_good;
474511

@@ -514,6 +551,9 @@ bool __skb_flow_dissect(const struct sk_buff *skb,
514551
goto out_good;
515552
}
516553

554+
__skb_flow_dissect_ipv6(skb, flow_dissector,
555+
target_container, data, iph);
556+
517557
if (flags & FLOW_DISSECTOR_F_STOP_AT_L3)
518558
goto out_good;
519559

net/sched/cls_flower.c

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ struct fl_flow_key {
5050
struct flow_dissector_key_ports enc_tp;
5151
struct flow_dissector_key_mpls mpls;
5252
struct flow_dissector_key_tcp tcp;
53+
struct flow_dissector_key_ip ip;
5354
} __aligned(BITS_PER_LONG / 8); /* Ensure that we can do comparisons as longs. */
5455

5556
struct fl_flow_mask_range {
@@ -427,6 +428,10 @@ static const struct nla_policy fl_policy[TCA_FLOWER_MAX + 1] = {
427428
[TCA_FLOWER_KEY_MPLS_LABEL] = { .type = NLA_U32 },
428429
[TCA_FLOWER_KEY_TCP_FLAGS] = { .type = NLA_U16 },
429430
[TCA_FLOWER_KEY_TCP_FLAGS_MASK] = { .type = NLA_U16 },
431+
[TCA_FLOWER_KEY_IP_TOS] = { .type = NLA_U8 },
432+
[TCA_FLOWER_KEY_IP_TOS_MASK] = { .type = NLA_U8 },
433+
[TCA_FLOWER_KEY_IP_TTL] = { .type = NLA_U8 },
434+
[TCA_FLOWER_KEY_IP_TTL_MASK] = { .type = NLA_U8 },
430435
};
431436

432437
static void fl_set_key_val(struct nlattr **tb,
@@ -528,6 +533,19 @@ static int fl_set_key_flags(struct nlattr **tb,
528533
return 0;
529534
}
530535

536+
static void fl_set_key_ip(struct nlattr **tb,
537+
struct flow_dissector_key_ip *key,
538+
struct flow_dissector_key_ip *mask)
539+
{
540+
fl_set_key_val(tb, &key->tos, TCA_FLOWER_KEY_IP_TOS,
541+
&mask->tos, TCA_FLOWER_KEY_IP_TOS_MASK,
542+
sizeof(key->tos));
543+
544+
fl_set_key_val(tb, &key->ttl, TCA_FLOWER_KEY_IP_TTL,
545+
&mask->ttl, TCA_FLOWER_KEY_IP_TTL_MASK,
546+
sizeof(key->ttl));
547+
}
548+
531549
static int fl_set_key(struct net *net, struct nlattr **tb,
532550
struct fl_flow_key *key, struct fl_flow_key *mask)
533551
{
@@ -570,6 +588,7 @@ static int fl_set_key(struct net *net, struct nlattr **tb,
570588
fl_set_key_val(tb, &key->basic.ip_proto, TCA_FLOWER_KEY_IP_PROTO,
571589
&mask->basic.ip_proto, TCA_FLOWER_UNSPEC,
572590
sizeof(key->basic.ip_proto));
591+
fl_set_key_ip(tb, &key->ip, &mask->ip);
573592
}
574593

575594
if (tb[TCA_FLOWER_KEY_IPV4_SRC] || tb[TCA_FLOWER_KEY_IPV4_DST]) {
@@ -772,6 +791,8 @@ static void fl_init_dissector(struct cls_fl_head *head,
772791
FLOW_DISSECTOR_KEY_IPV6_ADDRS, ipv6);
773792
FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
774793
FLOW_DISSECTOR_KEY_PORTS, tp);
794+
FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
795+
FLOW_DISSECTOR_KEY_IP, ip);
775796
FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
776797
FLOW_DISSECTOR_KEY_TCP, tcp);
777798
FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
@@ -1082,6 +1103,19 @@ static int fl_dump_key_mpls(struct sk_buff *skb,
10821103
return 0;
10831104
}
10841105

1106+
static int fl_dump_key_ip(struct sk_buff *skb,
1107+
struct flow_dissector_key_ip *key,
1108+
struct flow_dissector_key_ip *mask)
1109+
{
1110+
if (fl_dump_key_val(skb, &key->tos, TCA_FLOWER_KEY_IP_TOS, &mask->tos,
1111+
TCA_FLOWER_KEY_IP_TOS_MASK, sizeof(key->tos)) ||
1112+
fl_dump_key_val(skb, &key->ttl, TCA_FLOWER_KEY_IP_TTL, &mask->ttl,
1113+
TCA_FLOWER_KEY_IP_TTL_MASK, sizeof(key->ttl)))
1114+
return -1;
1115+
1116+
return 0;
1117+
}
1118+
10851119
static int fl_dump_key_vlan(struct sk_buff *skb,
10861120
struct flow_dissector_key_vlan *vlan_key,
10871121
struct flow_dissector_key_vlan *vlan_mask)
@@ -1195,9 +1229,10 @@ static int fl_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
11951229

11961230
if ((key->basic.n_proto == htons(ETH_P_IP) ||
11971231
key->basic.n_proto == htons(ETH_P_IPV6)) &&
1198-
fl_dump_key_val(skb, &key->basic.ip_proto, TCA_FLOWER_KEY_IP_PROTO,
1232+
(fl_dump_key_val(skb, &key->basic.ip_proto, TCA_FLOWER_KEY_IP_PROTO,
11991233
&mask->basic.ip_proto, TCA_FLOWER_UNSPEC,
1200-
sizeof(key->basic.ip_proto)))
1234+
sizeof(key->basic.ip_proto)) ||
1235+
fl_dump_key_ip(skb, &key->ip, &mask->ip)))
12011236
goto nla_put_failure;
12021237

12031238
if (key->control.addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS &&

0 commit comments

Comments
 (0)