5
5
#include <linux/xarray.h>
6
6
#include <net/net_debug.h>
7
7
#include <net/page_pool/types.h>
8
+ #include <net/sock.h>
8
9
9
10
#include "page_pool_priv.h"
11
+ #include "netdev-genl-gen.h"
10
12
11
13
static DEFINE_XARRAY_FLAGS (page_pools , XA_FLAGS_ALLOC1 ) ;
12
14
/* Protects: page_pools, netdevice->page_pools, pool->slow.netdev, pool->user.
@@ -26,6 +28,131 @@ static DEFINE_MUTEX(page_pools_lock);
26
28
* - user.list: unhashed, netdev: unknown
27
29
*/
28
30
31
+ typedef int (* pp_nl_fill_cb )(struct sk_buff * rsp , const struct page_pool * pool ,
32
+ const struct genl_info * info );
33
+
34
+ static int
35
+ netdev_nl_page_pool_get_do (struct genl_info * info , u32 id , pp_nl_fill_cb fill )
36
+ {
37
+ struct page_pool * pool ;
38
+ struct sk_buff * rsp ;
39
+ int err ;
40
+
41
+ mutex_lock (& page_pools_lock );
42
+ pool = xa_load (& page_pools , id );
43
+ if (!pool || hlist_unhashed (& pool -> user .list ) ||
44
+ !net_eq (dev_net (pool -> slow .netdev ), genl_info_net (info ))) {
45
+ err = - ENOENT ;
46
+ goto err_unlock ;
47
+ }
48
+
49
+ rsp = genlmsg_new (GENLMSG_DEFAULT_SIZE , GFP_KERNEL );
50
+ if (!rsp ) {
51
+ err = - ENOMEM ;
52
+ goto err_unlock ;
53
+ }
54
+
55
+ err = fill (rsp , pool , info );
56
+ if (err )
57
+ goto err_free_msg ;
58
+
59
+ mutex_unlock (& page_pools_lock );
60
+
61
+ return genlmsg_reply (rsp , info );
62
+
63
+ err_free_msg :
64
+ nlmsg_free (rsp );
65
+ err_unlock :
66
+ mutex_unlock (& page_pools_lock );
67
+ return err ;
68
+ }
69
+
70
+ struct page_pool_dump_cb {
71
+ unsigned long ifindex ;
72
+ u32 pp_id ;
73
+ };
74
+
75
+ static int
76
+ netdev_nl_page_pool_get_dump (struct sk_buff * skb , struct netlink_callback * cb ,
77
+ pp_nl_fill_cb fill )
78
+ {
79
+ struct page_pool_dump_cb * state = (void * )cb -> ctx ;
80
+ const struct genl_info * info = genl_info_dump (cb );
81
+ struct net * net = sock_net (skb -> sk );
82
+ struct net_device * netdev ;
83
+ struct page_pool * pool ;
84
+ int err = 0 ;
85
+
86
+ rtnl_lock ();
87
+ mutex_lock (& page_pools_lock );
88
+ for_each_netdev_dump (net , netdev , state -> ifindex ) {
89
+ hlist_for_each_entry (pool , & netdev -> page_pools , user .list ) {
90
+ if (state -> pp_id && state -> pp_id < pool -> user .id )
91
+ continue ;
92
+
93
+ state -> pp_id = pool -> user .id ;
94
+ err = fill (skb , pool , info );
95
+ if (err )
96
+ break ;
97
+ }
98
+
99
+ state -> pp_id = 0 ;
100
+ }
101
+ mutex_unlock (& page_pools_lock );
102
+ rtnl_unlock ();
103
+
104
+ if (skb -> len && err == - EMSGSIZE )
105
+ return skb -> len ;
106
+ return err ;
107
+ }
108
+
109
+ static int
110
+ page_pool_nl_fill (struct sk_buff * rsp , const struct page_pool * pool ,
111
+ const struct genl_info * info )
112
+ {
113
+ void * hdr ;
114
+
115
+ hdr = genlmsg_iput (rsp , info );
116
+ if (!hdr )
117
+ return - EMSGSIZE ;
118
+
119
+ if (nla_put_uint (rsp , NETDEV_A_PAGE_POOL_ID , pool -> user .id ))
120
+ goto err_cancel ;
121
+
122
+ if (pool -> slow .netdev -> ifindex != LOOPBACK_IFINDEX &&
123
+ nla_put_u32 (rsp , NETDEV_A_PAGE_POOL_IFINDEX ,
124
+ pool -> slow .netdev -> ifindex ))
125
+ goto err_cancel ;
126
+ if (pool -> user .napi_id &&
127
+ nla_put_uint (rsp , NETDEV_A_PAGE_POOL_NAPI_ID , pool -> user .napi_id ))
128
+ goto err_cancel ;
129
+
130
+ genlmsg_end (rsp , hdr );
131
+
132
+ return 0 ;
133
+ err_cancel :
134
+ genlmsg_cancel (rsp , hdr );
135
+ return - EMSGSIZE ;
136
+ }
137
+
138
+ int netdev_nl_page_pool_get_doit (struct sk_buff * skb , struct genl_info * info )
139
+ {
140
+ u32 id ;
141
+
142
+ if (GENL_REQ_ATTR_CHECK (info , NETDEV_A_PAGE_POOL_ID ))
143
+ return - EINVAL ;
144
+
145
+ id = nla_get_uint (info -> attrs [NETDEV_A_PAGE_POOL_ID ]);
146
+
147
+ return netdev_nl_page_pool_get_do (info , id , page_pool_nl_fill );
148
+ }
149
+
150
+ int netdev_nl_page_pool_get_dumpit (struct sk_buff * skb ,
151
+ struct netlink_callback * cb )
152
+ {
153
+ return netdev_nl_page_pool_get_dump (skb , cb , page_pool_nl_fill );
154
+ }
155
+
29
156
int page_pool_list (struct page_pool * pool )
30
157
{
31
158
static u32 id_alloc_next ;
0 commit comments