2121#include <linux/workqueue.h>
2222#include <linux/netlink.h>
2323#include <linux/net_dropmon.h>
24+ #include <linux/bitfield.h>
2425#include <linux/percpu.h>
2526#include <linux/timer.h>
2627#include <linux/bitops.h>
2930#include <net/genetlink.h>
3031#include <net/netevent.h>
3132#include <net/flow_offload.h>
33+ #include <net/dropreason.h>
3234#include <net/devlink.h>
3335
3436#include <trace/events/skb.h>
@@ -504,8 +506,6 @@ static void net_dm_packet_trace_kfree_skb_hit(void *ignore,
504506 if (!nskb )
505507 return ;
506508
507- if (unlikely (reason >= SKB_DROP_REASON_MAX || reason <= 0 ))
508- reason = SKB_DROP_REASON_NOT_SPECIFIED ;
509509 cb = NET_DM_SKB_CB (nskb );
510510 cb -> reason = reason ;
511511 cb -> pc = location ;
@@ -552,9 +552,9 @@ static size_t net_dm_in_port_size(void)
552552}
553553
554554#define NET_DM_MAX_SYMBOL_LEN 40
555+ #define NET_DM_MAX_REASON_LEN 50
555556
556- static size_t net_dm_packet_report_size (size_t payload_len ,
557- enum skb_drop_reason reason )
557+ static size_t net_dm_packet_report_size (size_t payload_len )
558558{
559559 size_t size ;
560560
@@ -576,7 +576,7 @@ static size_t net_dm_packet_report_size(size_t payload_len,
576576 /* NET_DM_ATTR_PROTO */
577577 nla_total_size (sizeof (u16 )) +
578578 /* NET_DM_ATTR_REASON */
579- nla_total_size (strlen ( drop_reasons [ reason ]) + 1 ) +
579+ nla_total_size (NET_DM_MAX_REASON_LEN + 1 ) +
580580 /* NET_DM_ATTR_PAYLOAD */
581581 nla_total_size (payload_len );
582582}
@@ -610,6 +610,8 @@ static int net_dm_packet_report_fill(struct sk_buff *msg, struct sk_buff *skb,
610610 size_t payload_len )
611611{
612612 struct net_dm_skb_cb * cb = NET_DM_SKB_CB (skb );
613+ const struct drop_reason_list * list = NULL ;
614+ unsigned int subsys , subsys_reason ;
613615 char buf [NET_DM_MAX_SYMBOL_LEN ];
614616 struct nlattr * attr ;
615617 void * hdr ;
@@ -627,9 +629,24 @@ static int net_dm_packet_report_fill(struct sk_buff *msg, struct sk_buff *skb,
627629 NET_DM_ATTR_PAD ))
628630 goto nla_put_failure ;
629631
632+ rcu_read_lock ();
633+ subsys = u32_get_bits (cb -> reason , SKB_DROP_REASON_SUBSYS_MASK );
634+ if (subsys < SKB_DROP_REASON_SUBSYS_NUM )
635+ list = rcu_dereference (drop_reasons_by_subsys [subsys ]);
636+ subsys_reason = cb -> reason & ~SKB_DROP_REASON_SUBSYS_MASK ;
637+ if (!list ||
638+ subsys_reason >= list -> n_reasons ||
639+ !list -> reasons [subsys_reason ] ||
640+ strlen (list -> reasons [subsys_reason ]) > NET_DM_MAX_REASON_LEN ) {
641+ list = rcu_dereference (drop_reasons_by_subsys [SKB_DROP_REASON_SUBSYS_CORE ]);
642+ subsys_reason = SKB_DROP_REASON_NOT_SPECIFIED ;
643+ }
630644 if (nla_put_string (msg , NET_DM_ATTR_REASON ,
631- drop_reasons [cb -> reason ]))
645+ list -> reasons [subsys_reason ])) {
646+ rcu_read_unlock ();
632647 goto nla_put_failure ;
648+ }
649+ rcu_read_unlock ();
633650
634651 snprintf (buf , sizeof (buf ), "%pS" , cb -> pc );
635652 if (nla_put_string (msg , NET_DM_ATTR_SYMBOL , buf ))
@@ -687,9 +704,7 @@ static void net_dm_packet_report(struct sk_buff *skb)
687704 if (net_dm_trunc_len )
688705 payload_len = min_t (size_t , net_dm_trunc_len , payload_len );
689706
690- msg = nlmsg_new (net_dm_packet_report_size (payload_len ,
691- NET_DM_SKB_CB (skb )-> reason ),
692- GFP_KERNEL );
707+ msg = nlmsg_new (net_dm_packet_report_size (payload_len ), GFP_KERNEL );
693708 if (!msg )
694709 goto out ;
695710
0 commit comments