~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/bridge/br_mrp_netlink.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 
  3 #include <net/genetlink.h>
  4 
  5 #include <uapi/linux/mrp_bridge.h>
  6 #include "br_private.h"
  7 #include "br_private_mrp.h"
  8 
  9 static const struct nla_policy br_mrp_policy[IFLA_BRIDGE_MRP_MAX + 1] = {
 10         [IFLA_BRIDGE_MRP_UNSPEC]        = { .type = NLA_REJECT },
 11         [IFLA_BRIDGE_MRP_INSTANCE]      = { .type = NLA_NESTED },
 12         [IFLA_BRIDGE_MRP_PORT_STATE]    = { .type = NLA_NESTED },
 13         [IFLA_BRIDGE_MRP_PORT_ROLE]     = { .type = NLA_NESTED },
 14         [IFLA_BRIDGE_MRP_RING_STATE]    = { .type = NLA_NESTED },
 15         [IFLA_BRIDGE_MRP_RING_ROLE]     = { .type = NLA_NESTED },
 16         [IFLA_BRIDGE_MRP_START_TEST]    = { .type = NLA_NESTED },
 17         [IFLA_BRIDGE_MRP_IN_ROLE]       = { .type = NLA_NESTED },
 18         [IFLA_BRIDGE_MRP_IN_STATE]      = { .type = NLA_NESTED },
 19         [IFLA_BRIDGE_MRP_START_IN_TEST] = { .type = NLA_NESTED },
 20 };
 21 
 22 static const struct nla_policy
 23 br_mrp_instance_policy[IFLA_BRIDGE_MRP_INSTANCE_MAX + 1] = {
 24         [IFLA_BRIDGE_MRP_INSTANCE_UNSPEC]       = { .type = NLA_REJECT },
 25         [IFLA_BRIDGE_MRP_INSTANCE_RING_ID]      = { .type = NLA_U32 },
 26         [IFLA_BRIDGE_MRP_INSTANCE_P_IFINDEX]    = { .type = NLA_U32 },
 27         [IFLA_BRIDGE_MRP_INSTANCE_S_IFINDEX]    = { .type = NLA_U32 },
 28         [IFLA_BRIDGE_MRP_INSTANCE_PRIO]         = { .type = NLA_U16 },
 29 };
 30 
 31 static int br_mrp_instance_parse(struct net_bridge *br, struct nlattr *attr,
 32                                  int cmd, struct netlink_ext_ack *extack)
 33 {
 34         struct nlattr *tb[IFLA_BRIDGE_MRP_INSTANCE_MAX + 1];
 35         struct br_mrp_instance inst;
 36         int err;
 37 
 38         err = nla_parse_nested(tb, IFLA_BRIDGE_MRP_INSTANCE_MAX, attr,
 39                                br_mrp_instance_policy, extack);
 40         if (err)
 41                 return err;
 42 
 43         if (!tb[IFLA_BRIDGE_MRP_INSTANCE_RING_ID] ||
 44             !tb[IFLA_BRIDGE_MRP_INSTANCE_P_IFINDEX] ||
 45             !tb[IFLA_BRIDGE_MRP_INSTANCE_S_IFINDEX]) {
 46                 NL_SET_ERR_MSG_MOD(extack,
 47                                    "Missing attribute: RING_ID or P_IFINDEX or S_IFINDEX");
 48                 return -EINVAL;
 49         }
 50 
 51         memset(&inst, 0, sizeof(inst));
 52 
 53         inst.ring_id = nla_get_u32(tb[IFLA_BRIDGE_MRP_INSTANCE_RING_ID]);
 54         inst.p_ifindex = nla_get_u32(tb[IFLA_BRIDGE_MRP_INSTANCE_P_IFINDEX]);
 55         inst.s_ifindex = nla_get_u32(tb[IFLA_BRIDGE_MRP_INSTANCE_S_IFINDEX]);
 56         inst.prio = MRP_DEFAULT_PRIO;
 57 
 58         if (tb[IFLA_BRIDGE_MRP_INSTANCE_PRIO])
 59                 inst.prio = nla_get_u16(tb[IFLA_BRIDGE_MRP_INSTANCE_PRIO]);
 60 
 61         if (cmd == RTM_SETLINK)
 62                 return br_mrp_add(br, &inst);
 63         else
 64                 return br_mrp_del(br, &inst);
 65 
 66         return 0;
 67 }
 68 
 69 static const struct nla_policy
 70 br_mrp_port_state_policy[IFLA_BRIDGE_MRP_PORT_STATE_MAX + 1] = {
 71         [IFLA_BRIDGE_MRP_PORT_STATE_UNSPEC]     = { .type = NLA_REJECT },
 72         [IFLA_BRIDGE_MRP_PORT_STATE_STATE]      = { .type = NLA_U32 },
 73 };
 74 
 75 static int br_mrp_port_state_parse(struct net_bridge_port *p,
 76                                    struct nlattr *attr,
 77                                    struct netlink_ext_ack *extack)
 78 {
 79         struct nlattr *tb[IFLA_BRIDGE_MRP_PORT_STATE_MAX + 1];
 80         enum br_mrp_port_state_type state;
 81         int err;
 82 
 83         err = nla_parse_nested(tb, IFLA_BRIDGE_MRP_PORT_STATE_MAX, attr,
 84                                br_mrp_port_state_policy, extack);
 85         if (err)
 86                 return err;
 87 
 88         if (!tb[IFLA_BRIDGE_MRP_PORT_STATE_STATE]) {
 89                 NL_SET_ERR_MSG_MOD(extack, "Missing attribute: STATE");
 90                 return -EINVAL;
 91         }
 92 
 93         state = nla_get_u32(tb[IFLA_BRIDGE_MRP_PORT_STATE_STATE]);
 94 
 95         return br_mrp_set_port_state(p, state);
 96 }
 97 
 98 static const struct nla_policy
 99 br_mrp_port_role_policy[IFLA_BRIDGE_MRP_PORT_ROLE_MAX + 1] = {
100         [IFLA_BRIDGE_MRP_PORT_ROLE_UNSPEC]      = { .type = NLA_REJECT },
101         [IFLA_BRIDGE_MRP_PORT_ROLE_ROLE]        = { .type = NLA_U32 },
102 };
103 
104 static int br_mrp_port_role_parse(struct net_bridge_port *p,
105                                   struct nlattr *attr,
106                                   struct netlink_ext_ack *extack)
107 {
108         struct nlattr *tb[IFLA_BRIDGE_MRP_PORT_ROLE_MAX + 1];
109         enum br_mrp_port_role_type role;
110         int err;
111 
112         err = nla_parse_nested(tb, IFLA_BRIDGE_MRP_PORT_ROLE_MAX, attr,
113                                br_mrp_port_role_policy, extack);
114         if (err)
115                 return err;
116 
117         if (!tb[IFLA_BRIDGE_MRP_PORT_ROLE_ROLE]) {
118                 NL_SET_ERR_MSG_MOD(extack, "Missing attribute: ROLE");
119                 return -EINVAL;
120         }
121 
122         role = nla_get_u32(tb[IFLA_BRIDGE_MRP_PORT_ROLE_ROLE]);
123 
124         return br_mrp_set_port_role(p, role);
125 }
126 
127 static const struct nla_policy
128 br_mrp_ring_state_policy[IFLA_BRIDGE_MRP_RING_STATE_MAX + 1] = {
129         [IFLA_BRIDGE_MRP_RING_STATE_UNSPEC]     = { .type = NLA_REJECT },
130         [IFLA_BRIDGE_MRP_RING_STATE_RING_ID]    = { .type = NLA_U32 },
131         [IFLA_BRIDGE_MRP_RING_STATE_STATE]      = { .type = NLA_U32 },
132 };
133 
134 static int br_mrp_ring_state_parse(struct net_bridge *br, struct nlattr *attr,
135                                    struct netlink_ext_ack *extack)
136 {
137         struct nlattr *tb[IFLA_BRIDGE_MRP_RING_STATE_MAX + 1];
138         struct br_mrp_ring_state state;
139         int err;
140 
141         err = nla_parse_nested(tb, IFLA_BRIDGE_MRP_RING_STATE_MAX, attr,
142                                br_mrp_ring_state_policy, extack);
143         if (err)
144                 return err;
145 
146         if (!tb[IFLA_BRIDGE_MRP_RING_STATE_RING_ID] ||
147             !tb[IFLA_BRIDGE_MRP_RING_STATE_STATE]) {
148                 NL_SET_ERR_MSG_MOD(extack,
149                                    "Missing attribute: RING_ID or STATE");
150                 return -EINVAL;
151         }
152 
153         memset(&state, 0x0, sizeof(state));
154 
155         state.ring_id = nla_get_u32(tb[IFLA_BRIDGE_MRP_RING_STATE_RING_ID]);
156         state.ring_state = nla_get_u32(tb[IFLA_BRIDGE_MRP_RING_STATE_STATE]);
157 
158         return br_mrp_set_ring_state(br, &state);
159 }
160 
161 static const struct nla_policy
162 br_mrp_ring_role_policy[IFLA_BRIDGE_MRP_RING_ROLE_MAX + 1] = {
163         [IFLA_BRIDGE_MRP_RING_ROLE_UNSPEC]      = { .type = NLA_REJECT },
164         [IFLA_BRIDGE_MRP_RING_ROLE_RING_ID]     = { .type = NLA_U32 },
165         [IFLA_BRIDGE_MRP_RING_ROLE_ROLE]        = { .type = NLA_U32 },
166 };
167 
168 static int br_mrp_ring_role_parse(struct net_bridge *br, struct nlattr *attr,
169                                   struct netlink_ext_ack *extack)
170 {
171         struct nlattr *tb[IFLA_BRIDGE_MRP_RING_ROLE_MAX + 1];
172         struct br_mrp_ring_role role;
173         int err;
174 
175         err = nla_parse_nested(tb, IFLA_BRIDGE_MRP_RING_ROLE_MAX, attr,
176                                br_mrp_ring_role_policy, extack);
177         if (err)
178                 return err;
179 
180         if (!tb[IFLA_BRIDGE_MRP_RING_ROLE_RING_ID] ||
181             !tb[IFLA_BRIDGE_MRP_RING_ROLE_ROLE]) {
182                 NL_SET_ERR_MSG_MOD(extack,
183                                    "Missing attribute: RING_ID or ROLE");
184                 return -EINVAL;
185         }
186 
187         memset(&role, 0x0, sizeof(role));
188 
189         role.ring_id = nla_get_u32(tb[IFLA_BRIDGE_MRP_RING_ROLE_RING_ID]);
190         role.ring_role = nla_get_u32(tb[IFLA_BRIDGE_MRP_RING_ROLE_ROLE]);
191 
192         return br_mrp_set_ring_role(br, &role);
193 }
194 
195 static const struct nla_policy
196 br_mrp_start_test_policy[IFLA_BRIDGE_MRP_START_TEST_MAX + 1] = {
197         [IFLA_BRIDGE_MRP_START_TEST_UNSPEC]     = { .type = NLA_REJECT },
198         [IFLA_BRIDGE_MRP_START_TEST_RING_ID]    = { .type = NLA_U32 },
199         [IFLA_BRIDGE_MRP_START_TEST_INTERVAL]   = { .type = NLA_U32 },
200         [IFLA_BRIDGE_MRP_START_TEST_MAX_MISS]   = { .type = NLA_U32 },
201         [IFLA_BRIDGE_MRP_START_TEST_PERIOD]     = { .type = NLA_U32 },
202         [IFLA_BRIDGE_MRP_START_TEST_MONITOR]    = { .type = NLA_U32 },
203 };
204 
205 static int br_mrp_start_test_parse(struct net_bridge *br, struct nlattr *attr,
206                                    struct netlink_ext_ack *extack)
207 {
208         struct nlattr *tb[IFLA_BRIDGE_MRP_START_TEST_MAX + 1];
209         struct br_mrp_start_test test;
210         int err;
211 
212         err = nla_parse_nested(tb, IFLA_BRIDGE_MRP_START_TEST_MAX, attr,
213                                br_mrp_start_test_policy, extack);
214         if (err)
215                 return err;
216 
217         if (!tb[IFLA_BRIDGE_MRP_START_TEST_RING_ID] ||
218             !tb[IFLA_BRIDGE_MRP_START_TEST_INTERVAL] ||
219             !tb[IFLA_BRIDGE_MRP_START_TEST_MAX_MISS] ||
220             !tb[IFLA_BRIDGE_MRP_START_TEST_PERIOD]) {
221                 NL_SET_ERR_MSG_MOD(extack,
222                                    "Missing attribute: RING_ID or INTERVAL or MAX_MISS or PERIOD");
223                 return -EINVAL;
224         }
225 
226         memset(&test, 0x0, sizeof(test));
227 
228         test.ring_id = nla_get_u32(tb[IFLA_BRIDGE_MRP_START_TEST_RING_ID]);
229         test.interval = nla_get_u32(tb[IFLA_BRIDGE_MRP_START_TEST_INTERVAL]);
230         test.max_miss = nla_get_u32(tb[IFLA_BRIDGE_MRP_START_TEST_MAX_MISS]);
231         test.period = nla_get_u32(tb[IFLA_BRIDGE_MRP_START_TEST_PERIOD]);
232         test.monitor = false;
233 
234         if (tb[IFLA_BRIDGE_MRP_START_TEST_MONITOR])
235                 test.monitor =
236                         nla_get_u32(tb[IFLA_BRIDGE_MRP_START_TEST_MONITOR]);
237 
238         return br_mrp_start_test(br, &test);
239 }
240 
241 static const struct nla_policy
242 br_mrp_in_state_policy[IFLA_BRIDGE_MRP_IN_STATE_MAX + 1] = {
243         [IFLA_BRIDGE_MRP_IN_STATE_UNSPEC]       = { .type = NLA_REJECT },
244         [IFLA_BRIDGE_MRP_IN_STATE_IN_ID]        = { .type = NLA_U32 },
245         [IFLA_BRIDGE_MRP_IN_STATE_STATE]        = { .type = NLA_U32 },
246 };
247 
248 static int br_mrp_in_state_parse(struct net_bridge *br, struct nlattr *attr,
249                                  struct netlink_ext_ack *extack)
250 {
251         struct nlattr *tb[IFLA_BRIDGE_MRP_IN_STATE_MAX + 1];
252         struct br_mrp_in_state state;
253         int err;
254 
255         err = nla_parse_nested(tb, IFLA_BRIDGE_MRP_IN_STATE_MAX, attr,
256                                br_mrp_in_state_policy, extack);
257         if (err)
258                 return err;
259 
260         if (!tb[IFLA_BRIDGE_MRP_IN_STATE_IN_ID] ||
261             !tb[IFLA_BRIDGE_MRP_IN_STATE_STATE]) {
262                 NL_SET_ERR_MSG_MOD(extack,
263                                    "Missing attribute: IN_ID or STATE");
264                 return -EINVAL;
265         }
266 
267         memset(&state, 0x0, sizeof(state));
268 
269         state.in_id = nla_get_u32(tb[IFLA_BRIDGE_MRP_IN_STATE_IN_ID]);
270         state.in_state = nla_get_u32(tb[IFLA_BRIDGE_MRP_IN_STATE_STATE]);
271 
272         return br_mrp_set_in_state(br, &state);
273 }
274 
275 static const struct nla_policy
276 br_mrp_in_role_policy[IFLA_BRIDGE_MRP_IN_ROLE_MAX + 1] = {
277         [IFLA_BRIDGE_MRP_IN_ROLE_UNSPEC]        = { .type = NLA_REJECT },
278         [IFLA_BRIDGE_MRP_IN_ROLE_RING_ID]       = { .type = NLA_U32 },
279         [IFLA_BRIDGE_MRP_IN_ROLE_IN_ID]         = { .type = NLA_U16 },
280         [IFLA_BRIDGE_MRP_IN_ROLE_ROLE]          = { .type = NLA_U32 },
281         [IFLA_BRIDGE_MRP_IN_ROLE_I_IFINDEX]     = { .type = NLA_U32 },
282 };
283 
284 static int br_mrp_in_role_parse(struct net_bridge *br, struct nlattr *attr,
285                                 struct netlink_ext_ack *extack)
286 {
287         struct nlattr *tb[IFLA_BRIDGE_MRP_IN_ROLE_MAX + 1];
288         struct br_mrp_in_role role;
289         int err;
290 
291         err = nla_parse_nested(tb, IFLA_BRIDGE_MRP_IN_ROLE_MAX, attr,
292                                br_mrp_in_role_policy, extack);
293         if (err)
294                 return err;
295 
296         if (!tb[IFLA_BRIDGE_MRP_IN_ROLE_RING_ID] ||
297             !tb[IFLA_BRIDGE_MRP_IN_ROLE_IN_ID] ||
298             !tb[IFLA_BRIDGE_MRP_IN_ROLE_I_IFINDEX] ||
299             !tb[IFLA_BRIDGE_MRP_IN_ROLE_ROLE]) {
300                 NL_SET_ERR_MSG_MOD(extack,
301                                    "Missing attribute: RING_ID or ROLE or IN_ID or I_IFINDEX");
302                 return -EINVAL;
303         }
304 
305         memset(&role, 0x0, sizeof(role));
306 
307         role.ring_id = nla_get_u32(tb[IFLA_BRIDGE_MRP_IN_ROLE_RING_ID]);
308         role.in_id = nla_get_u16(tb[IFLA_BRIDGE_MRP_IN_ROLE_IN_ID]);
309         role.i_ifindex = nla_get_u32(tb[IFLA_BRIDGE_MRP_IN_ROLE_I_IFINDEX]);
310         role.in_role = nla_get_u32(tb[IFLA_BRIDGE_MRP_IN_ROLE_ROLE]);
311 
312         return br_mrp_set_in_role(br, &role);
313 }
314 
315 static const struct nla_policy
316 br_mrp_start_in_test_policy[IFLA_BRIDGE_MRP_START_IN_TEST_MAX + 1] = {
317         [IFLA_BRIDGE_MRP_START_IN_TEST_UNSPEC]  = { .type = NLA_REJECT },
318         [IFLA_BRIDGE_MRP_START_IN_TEST_IN_ID]   = { .type = NLA_U32 },
319         [IFLA_BRIDGE_MRP_START_IN_TEST_INTERVAL]        = { .type = NLA_U32 },
320         [IFLA_BRIDGE_MRP_START_IN_TEST_MAX_MISS]        = { .type = NLA_U32 },
321         [IFLA_BRIDGE_MRP_START_IN_TEST_PERIOD]  = { .type = NLA_U32 },
322 };
323 
324 static int br_mrp_start_in_test_parse(struct net_bridge *br,
325                                       struct nlattr *attr,
326                                       struct netlink_ext_ack *extack)
327 {
328         struct nlattr *tb[IFLA_BRIDGE_MRP_START_IN_TEST_MAX + 1];
329         struct br_mrp_start_in_test test;
330         int err;
331 
332         err = nla_parse_nested(tb, IFLA_BRIDGE_MRP_START_IN_TEST_MAX, attr,
333                                br_mrp_start_in_test_policy, extack);
334         if (err)
335                 return err;
336 
337         if (!tb[IFLA_BRIDGE_MRP_START_IN_TEST_IN_ID] ||
338             !tb[IFLA_BRIDGE_MRP_START_IN_TEST_INTERVAL] ||
339             !tb[IFLA_BRIDGE_MRP_START_IN_TEST_MAX_MISS] ||
340             !tb[IFLA_BRIDGE_MRP_START_IN_TEST_PERIOD]) {
341                 NL_SET_ERR_MSG_MOD(extack,
342                                    "Missing attribute: RING_ID or INTERVAL or MAX_MISS or PERIOD");
343                 return -EINVAL;
344         }
345 
346         memset(&test, 0x0, sizeof(test));
347 
348         test.in_id = nla_get_u32(tb[IFLA_BRIDGE_MRP_START_IN_TEST_IN_ID]);
349         test.interval = nla_get_u32(tb[IFLA_BRIDGE_MRP_START_IN_TEST_INTERVAL]);
350         test.max_miss = nla_get_u32(tb[IFLA_BRIDGE_MRP_START_IN_TEST_MAX_MISS]);
351         test.period = nla_get_u32(tb[IFLA_BRIDGE_MRP_START_IN_TEST_PERIOD]);
352 
353         return br_mrp_start_in_test(br, &test);
354 }
355 
356 int br_mrp_parse(struct net_bridge *br, struct net_bridge_port *p,
357                  struct nlattr *attr, int cmd, struct netlink_ext_ack *extack)
358 {
359         struct nlattr *tb[IFLA_BRIDGE_MRP_MAX + 1];
360         int err;
361 
362         /* When this function is called for a port then the br pointer is
363          * invalid, therefor set the br to point correctly
364          */
365         if (p)
366                 br = p->br;
367 
368         if (br->stp_enabled != BR_NO_STP) {
369                 NL_SET_ERR_MSG_MOD(extack, "MRP can't be enabled if STP is already enabled");
370                 return -EINVAL;
371         }
372 
373         err = nla_parse_nested(tb, IFLA_BRIDGE_MRP_MAX, attr,
374                                br_mrp_policy, extack);
375         if (err)
376                 return err;
377 
378         if (tb[IFLA_BRIDGE_MRP_INSTANCE]) {
379                 err = br_mrp_instance_parse(br, tb[IFLA_BRIDGE_MRP_INSTANCE],
380                                             cmd, extack);
381                 if (err)
382                         return err;
383         }
384 
385         if (tb[IFLA_BRIDGE_MRP_PORT_STATE]) {
386                 err = br_mrp_port_state_parse(p, tb[IFLA_BRIDGE_MRP_PORT_STATE],
387                                               extack);
388                 if (err)
389                         return err;
390         }
391 
392         if (tb[IFLA_BRIDGE_MRP_PORT_ROLE]) {
393                 err = br_mrp_port_role_parse(p, tb[IFLA_BRIDGE_MRP_PORT_ROLE],
394                                              extack);
395                 if (err)
396                         return err;
397         }
398 
399         if (tb[IFLA_BRIDGE_MRP_RING_STATE]) {
400                 err = br_mrp_ring_state_parse(br,
401                                               tb[IFLA_BRIDGE_MRP_RING_STATE],
402                                               extack);
403                 if (err)
404                         return err;
405         }
406 
407         if (tb[IFLA_BRIDGE_MRP_RING_ROLE]) {
408                 err = br_mrp_ring_role_parse(br, tb[IFLA_BRIDGE_MRP_RING_ROLE],
409                                              extack);
410                 if (err)
411                         return err;
412         }
413 
414         if (tb[IFLA_BRIDGE_MRP_START_TEST]) {
415                 err = br_mrp_start_test_parse(br,
416                                               tb[IFLA_BRIDGE_MRP_START_TEST],
417                                               extack);
418                 if (err)
419                         return err;
420         }
421 
422         if (tb[IFLA_BRIDGE_MRP_IN_STATE]) {
423                 err = br_mrp_in_state_parse(br, tb[IFLA_BRIDGE_MRP_IN_STATE],
424                                             extack);
425                 if (err)
426                         return err;
427         }
428 
429         if (tb[IFLA_BRIDGE_MRP_IN_ROLE]) {
430                 err = br_mrp_in_role_parse(br, tb[IFLA_BRIDGE_MRP_IN_ROLE],
431                                            extack);
432                 if (err)
433                         return err;
434         }
435 
436         if (tb[IFLA_BRIDGE_MRP_START_IN_TEST]) {
437                 err = br_mrp_start_in_test_parse(br,
438                                                  tb[IFLA_BRIDGE_MRP_START_IN_TEST],
439                                                  extack);
440                 if (err)
441                         return err;
442         }
443 
444         return 0;
445 }
446 
447 int br_mrp_fill_info(struct sk_buff *skb, struct net_bridge *br)
448 {
449         struct nlattr *tb, *mrp_tb;
450         struct br_mrp *mrp;
451 
452         mrp_tb = nla_nest_start_noflag(skb, IFLA_BRIDGE_MRP);
453         if (!mrp_tb)
454                 return -EMSGSIZE;
455 
456         hlist_for_each_entry_rcu(mrp, &br->mrp_list, list) {
457                 struct net_bridge_port *p;
458 
459                 tb = nla_nest_start_noflag(skb, IFLA_BRIDGE_MRP_INFO);
460                 if (!tb)
461                         goto nla_info_failure;
462 
463                 if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_RING_ID,
464                                 mrp->ring_id))
465                         goto nla_put_failure;
466 
467                 p = rcu_dereference(mrp->p_port);
468                 if (p && nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_P_IFINDEX,
469                                      p->dev->ifindex))
470                         goto nla_put_failure;
471 
472                 p = rcu_dereference(mrp->s_port);
473                 if (p && nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_S_IFINDEX,
474                                      p->dev->ifindex))
475                         goto nla_put_failure;
476 
477                 p = rcu_dereference(mrp->i_port);
478                 if (p && nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_I_IFINDEX,
479                                      p->dev->ifindex))
480                         goto nla_put_failure;
481 
482                 if (nla_put_u16(skb, IFLA_BRIDGE_MRP_INFO_PRIO,
483                                 mrp->prio))
484                         goto nla_put_failure;
485                 if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_RING_STATE,
486                                 mrp->ring_state))
487                         goto nla_put_failure;
488                 if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_RING_ROLE,
489                                 mrp->ring_role))
490                         goto nla_put_failure;
491                 if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_TEST_INTERVAL,
492                                 mrp->test_interval))
493                         goto nla_put_failure;
494                 if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_TEST_MAX_MISS,
495                                 mrp->test_max_miss))
496                         goto nla_put_failure;
497                 if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_TEST_MONITOR,
498                                 mrp->test_monitor))
499                         goto nla_put_failure;
500 
501                 if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_IN_STATE,
502                                 mrp->in_state))
503                         goto nla_put_failure;
504                 if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_IN_ROLE,
505                                 mrp->in_role))
506                         goto nla_put_failure;
507                 if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_IN_TEST_INTERVAL,
508                                 mrp->in_test_interval))
509                         goto nla_put_failure;
510                 if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_IN_TEST_MAX_MISS,
511                                 mrp->in_test_max_miss))
512                         goto nla_put_failure;
513 
514                 nla_nest_end(skb, tb);
515         }
516         nla_nest_end(skb, mrp_tb);
517 
518         return 0;
519 
520 nla_put_failure:
521         nla_nest_cancel(skb, tb);
522 
523 nla_info_failure:
524         nla_nest_cancel(skb, mrp_tb);
525 
526         return -EMSGSIZE;
527 }
528 
529 int br_mrp_ring_port_open(struct net_device *dev, u8 loc)
530 {
531         struct net_bridge_port *p;
532         int err = 0;
533 
534         p = br_port_get_rcu(dev);
535         if (!p) {
536                 err = -EINVAL;
537                 goto out;
538         }
539 
540         if (loc)
541                 p->flags |= BR_MRP_LOST_CONT;
542         else
543                 p->flags &= ~BR_MRP_LOST_CONT;
544 
545         br_ifinfo_notify(RTM_NEWLINK, NULL, p);
546 
547 out:
548         return err;
549 }
550 
551 int br_mrp_in_port_open(struct net_device *dev, u8 loc)
552 {
553         struct net_bridge_port *p;
554         int err = 0;
555 
556         p = br_port_get_rcu(dev);
557         if (!p) {
558                 err = -EINVAL;
559                 goto out;
560         }
561 
562         if (loc)
563                 p->flags |= BR_MRP_LOST_IN_CONT;
564         else
565                 p->flags &= ~BR_MRP_LOST_IN_CONT;
566 
567         br_ifinfo_notify(RTM_NEWLINK, NULL, p);
568 
569 out:
570         return err;
571 }
572 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php