@@ -63,44 +63,85 @@ static int add_policy(struct netlink_policy_dump_state **statep,
63
63
return 0 ;
64
64
}
65
65
66
- static unsigned int get_policy_idx (struct netlink_policy_dump_state * state ,
67
- const struct nla_policy * policy ,
68
- unsigned int maxtype )
66
+ /**
67
+ * netlink_policy_dump_get_policy_idx - retrieve policy index
68
+ * @state: the policy dump state
69
+ * @policy: the policy to find
70
+ * @maxtype: the policy's maxattr
71
+ *
72
+ * Returns: the index of the given policy in the dump state
73
+ *
74
+ * Call this to find a policy index when you've added multiple and e.g.
75
+ * need to tell userspace which command has which policy (by index).
76
+ *
77
+ * Note: this will WARN and return 0 if the policy isn't found, which
78
+ * means it wasn't added in the first place, which would be an
79
+ * internal consistency bug.
80
+ */
81
+ int netlink_policy_dump_get_policy_idx (struct netlink_policy_dump_state * state ,
82
+ const struct nla_policy * policy ,
83
+ unsigned int maxtype )
69
84
{
70
85
unsigned int i ;
71
86
87
+ if (WARN_ON (!policy || !maxtype ))
88
+ return 0 ;
89
+
72
90
for (i = 0 ; i < state -> n_alloc ; i ++ ) {
73
91
if (state -> policies [i ].policy == policy &&
74
92
state -> policies [i ].maxtype == maxtype )
75
93
return i ;
76
94
}
77
95
78
- WARN_ON_ONCE (1 );
79
- return -1 ;
96
+ WARN_ON (1 );
97
+ return 0 ;
80
98
}
81
99
82
- int netlink_policy_dump_start (const struct nla_policy * policy ,
83
- unsigned int maxtype ,
84
- struct netlink_policy_dump_state * * statep )
100
+ static struct netlink_policy_dump_state * alloc_state (void )
85
101
{
86
102
struct netlink_policy_dump_state * state ;
103
+
104
+ state = kzalloc (struct_size (state , policies , INITIAL_POLICIES_ALLOC ),
105
+ GFP_KERNEL );
106
+ if (!state )
107
+ return ERR_PTR (- ENOMEM );
108
+ state -> n_alloc = INITIAL_POLICIES_ALLOC ;
109
+
110
+ return state ;
111
+ }
112
+
113
+ /**
114
+ * netlink_policy_dump_add_policy - add a policy to the dump
115
+ * @pstate: state to add to, may be reallocated, must be %NULL the first time
116
+ * @policy: the new policy to add to the dump
117
+ * @maxtype: the new policy's max attr type
118
+ *
119
+ * Returns: 0 on success, a negative error code otherwise.
120
+ *
121
+ * Call this to allocate a policy dump state, and to add policies to it. This
122
+ * should be called from the dump start() callback.
123
+ *
124
+ * Note: on failures, any previously allocated state is freed.
125
+ */
126
+ int netlink_policy_dump_add_policy (struct netlink_policy_dump_state * * pstate ,
127
+ const struct nla_policy * policy ,
128
+ unsigned int maxtype )
129
+ {
130
+ struct netlink_policy_dump_state * state = * pstate ;
87
131
unsigned int policy_idx ;
88
132
int err ;
89
133
90
- if (* statep )
91
- return 0 ;
134
+ if (!state ) {
135
+ state = alloc_state ();
136
+ if (IS_ERR (state ))
137
+ return PTR_ERR (state );
138
+ }
92
139
93
140
/*
94
141
* walk the policies and nested ones first, and build
95
142
* a linear list of them.
96
143
*/
97
144
98
- state = kzalloc (struct_size (state , policies , INITIAL_POLICIES_ALLOC ),
99
- GFP_KERNEL );
100
- if (!state )
101
- return - ENOMEM ;
102
- state -> n_alloc = INITIAL_POLICIES_ALLOC ;
103
-
104
145
err = add_policy (& state , policy , maxtype );
105
146
if (err )
106
147
return err ;
@@ -131,8 +172,7 @@ int netlink_policy_dump_start(const struct nla_policy *policy,
131
172
}
132
173
}
133
174
134
- * statep = state ;
135
-
175
+ * pstate = state ;
136
176
return 0 ;
137
177
}
138
178
@@ -143,11 +183,26 @@ netlink_policy_dump_finished(struct netlink_policy_dump_state *state)
143
183
!state -> policies [state -> policy_idx ].policy ;
144
184
}
145
185
186
+ /**
187
+ * netlink_policy_dump_loop - dumping loop indicator
188
+ * @state: the policy dump state
189
+ *
190
+ * Returns: %true if the dump continues, %false otherwise
191
+ *
192
+ * Note: this frees the dump state when finishing
193
+ */
146
194
bool netlink_policy_dump_loop (struct netlink_policy_dump_state * state )
147
195
{
148
196
return !netlink_policy_dump_finished (state );
149
197
}
150
198
199
+ /**
200
+ * netlink_policy_dump_write - write current policy dump attributes
201
+ * @skb: the message skb to write to
202
+ * @state: the policy dump state
203
+ *
204
+ * Returns: 0 on success, an error code otherwise
205
+ */
151
206
int netlink_policy_dump_write (struct sk_buff * skb ,
152
207
struct netlink_policy_dump_state * state )
153
208
{
@@ -185,8 +240,9 @@ int netlink_policy_dump_write(struct sk_buff *skb,
185
240
type = NL_ATTR_TYPE_NESTED_ARRAY ;
186
241
if (pt -> nested_policy && pt -> len &&
187
242
(nla_put_u32 (skb , NL_POLICY_TYPE_ATTR_POLICY_IDX ,
188
- get_policy_idx (state , pt -> nested_policy ,
189
- pt -> len )) ||
243
+ netlink_policy_dump_get_policy_idx (state ,
244
+ pt -> nested_policy ,
245
+ pt -> len )) ||
190
246
nla_put_u32 (skb , NL_POLICY_TYPE_ATTR_POLICY_MAXTYPE ,
191
247
pt -> len )))
192
248
goto nla_put_failure ;
@@ -309,6 +365,12 @@ int netlink_policy_dump_write(struct sk_buff *skb,
309
365
return - ENOBUFS ;
310
366
}
311
367
368
+ /**
369
+ * netlink_policy_dump_free - free policy dump state
370
+ * @state: the policy dump state to free
371
+ *
372
+ * Call this from the done() method to ensure dump state is freed.
373
+ */
312
374
void netlink_policy_dump_free (struct netlink_policy_dump_state * state )
313
375
{
314
376
kfree (state );
0 commit comments