@@ -386,6 +386,8 @@ static const struct nla_policy fl_policy[TCA_FLOWER_MAX + 1] = {
386
386
[TCA_FLOWER_KEY_ENC_UDP_SRC_PORT_MASK ] = { .type = NLA_U16 },
387
387
[TCA_FLOWER_KEY_ENC_UDP_DST_PORT ] = { .type = NLA_U16 },
388
388
[TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK ] = { .type = NLA_U16 },
389
+ [TCA_FLOWER_KEY_FLAGS ] = { .type = NLA_U32 },
390
+ [TCA_FLOWER_KEY_FLAGS_MASK ] = { .type = NLA_U32 },
389
391
};
390
392
391
393
static void fl_set_key_val (struct nlattr * * tb ,
@@ -420,6 +422,39 @@ static void fl_set_key_vlan(struct nlattr **tb,
420
422
}
421
423
}
422
424
425
+ static void fl_set_key_flag (u32 flower_key , u32 flower_mask ,
426
+ u32 * dissector_key , u32 * dissector_mask ,
427
+ u32 flower_flag_bit , u32 dissector_flag_bit )
428
+ {
429
+ if (flower_mask & flower_flag_bit ) {
430
+ * dissector_mask |= dissector_flag_bit ;
431
+ if (flower_key & flower_flag_bit )
432
+ * dissector_key |= dissector_flag_bit ;
433
+ }
434
+ }
435
+
436
+ static void fl_set_key_flags (struct nlattr * * tb ,
437
+ u32 * flags_key , u32 * flags_mask )
438
+ {
439
+ u32 key , mask ;
440
+
441
+ if (!tb [TCA_FLOWER_KEY_FLAGS ])
442
+ return ;
443
+
444
+ key = be32_to_cpu (nla_get_u32 (tb [TCA_FLOWER_KEY_FLAGS ]));
445
+
446
+ if (!tb [TCA_FLOWER_KEY_FLAGS_MASK ])
447
+ mask = ~0 ;
448
+ else
449
+ mask = be32_to_cpu (nla_get_u32 (tb [TCA_FLOWER_KEY_FLAGS_MASK ]));
450
+
451
+ * flags_key = 0 ;
452
+ * flags_mask = 0 ;
453
+
454
+ fl_set_key_flag (key , mask , flags_key , flags_mask ,
455
+ TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT , FLOW_DIS_IS_FRAGMENT );
456
+ }
457
+
423
458
static int fl_set_key (struct net * net , struct nlattr * * tb ,
424
459
struct fl_flow_key * key , struct fl_flow_key * mask )
425
460
{
@@ -546,6 +581,8 @@ static int fl_set_key(struct net *net, struct nlattr **tb,
546
581
& mask -> enc_tp .dst , TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK ,
547
582
sizeof (key -> enc_tp .dst ));
548
583
584
+ fl_set_key_flags (tb , & key -> control .flags , & mask -> control .flags );
585
+
549
586
return 0 ;
550
587
}
551
588
@@ -880,6 +917,42 @@ static int fl_dump_key_vlan(struct sk_buff *skb,
880
917
return 0 ;
881
918
}
882
919
920
+ static void fl_get_key_flag (u32 dissector_key , u32 dissector_mask ,
921
+ u32 * flower_key , u32 * flower_mask ,
922
+ u32 flower_flag_bit , u32 dissector_flag_bit )
923
+ {
924
+ if (dissector_mask & dissector_flag_bit ) {
925
+ * flower_mask |= flower_flag_bit ;
926
+ if (dissector_key & dissector_flag_bit )
927
+ * flower_key |= flower_flag_bit ;
928
+ }
929
+ }
930
+
931
+ static int fl_dump_key_flags (struct sk_buff * skb , u32 flags_key , u32 flags_mask )
932
+ {
933
+ u32 key , mask ;
934
+ __be32 _key , _mask ;
935
+ int err ;
936
+
937
+ if (!memchr_inv (& flags_mask , 0 , sizeof (flags_mask )))
938
+ return 0 ;
939
+
940
+ key = 0 ;
941
+ mask = 0 ;
942
+
943
+ fl_get_key_flag (flags_key , flags_mask , & key , & mask ,
944
+ TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT , FLOW_DIS_IS_FRAGMENT );
945
+
946
+ _key = cpu_to_be32 (key );
947
+ _mask = cpu_to_be32 (mask );
948
+
949
+ err = nla_put (skb , TCA_FLOWER_KEY_FLAGS , 4 , & _key );
950
+ if (err )
951
+ return err ;
952
+
953
+ return nla_put (skb , TCA_FLOWER_KEY_FLAGS_MASK , 4 , & _mask );
954
+ }
955
+
883
956
static int fl_dump (struct net * net , struct tcf_proto * tp , unsigned long fh ,
884
957
struct sk_buff * skb , struct tcmsg * t )
885
958
{
@@ -1015,6 +1088,9 @@ static int fl_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
1015
1088
sizeof (key -> enc_tp .dst )))
1016
1089
goto nla_put_failure ;
1017
1090
1091
+ if (fl_dump_key_flags (skb , key -> control .flags , mask -> control .flags ))
1092
+ goto nla_put_failure ;
1093
+
1018
1094
nla_put_u32 (skb , TCA_FLOWER_FLAGS , f -> flags );
1019
1095
1020
1096
if (tcf_exts_dump (skb , & f -> exts ))
0 commit comments