hc
2024-05-10 9999e48639b3cecb08ffb37358bcba3b48161b29
kernel/net/hsr/hsr_netlink.c
....@@ -1,14 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0
12 /* Copyright 2011-2014 Autronica Fire and Security AS
2
- *
3
- * This program is free software; you can redistribute it and/or modify it
4
- * under the terms of the GNU General Public License as published by the Free
5
- * Software Foundation; either version 2 of the License, or (at your option)
6
- * any later version.
73 *
84 * Author(s):
95 * 2011-2014 Arvid Brodin, arvid.brodin@alten.se
106 *
11
- * Routines for handling Netlink messages for HSR.
7
+ * Routines for handling Netlink messages for HSR and PRP.
128 */
139
1410 #include "hsr_netlink.h"
....@@ -26,8 +22,8 @@
2622 [IFLA_HSR_VERSION] = { .type = NLA_U8 },
2723 [IFLA_HSR_SUPERVISION_ADDR] = { .len = ETH_ALEN },
2824 [IFLA_HSR_SEQ_NR] = { .type = NLA_U16 },
25
+ [IFLA_HSR_PROTOCOL] = { .type = NLA_U8 },
2926 };
30
-
3127
3228 /* Here, it seems a netdevice has already been allocated for us, and the
3329 * hsr_dev_setup routine has been executed. Nice!
....@@ -36,77 +32,117 @@
3632 struct nlattr *tb[], struct nlattr *data[],
3733 struct netlink_ext_ack *extack)
3834 {
35
+ enum hsr_version proto_version;
36
+ unsigned char multicast_spec;
37
+ u8 proto = HSR_PROTOCOL_HSR;
3938 struct net_device *link[2];
40
- unsigned char multicast_spec, hsr_version;
4139
4240 if (!data) {
43
- netdev_info(dev, "HSR: No slave devices specified\n");
41
+ NL_SET_ERR_MSG_MOD(extack, "No slave devices specified");
4442 return -EINVAL;
4543 }
4644 if (!data[IFLA_HSR_SLAVE1]) {
47
- netdev_info(dev, "HSR: Slave1 device not specified\n");
45
+ NL_SET_ERR_MSG_MOD(extack, "Slave1 device not specified");
4846 return -EINVAL;
4947 }
50
- link[0] = __dev_get_by_index(src_net, nla_get_u32(data[IFLA_HSR_SLAVE1]));
48
+ link[0] = __dev_get_by_index(src_net,
49
+ nla_get_u32(data[IFLA_HSR_SLAVE1]));
50
+ if (!link[0]) {
51
+ NL_SET_ERR_MSG_MOD(extack, "Slave1 does not exist");
52
+ return -EINVAL;
53
+ }
5154 if (!data[IFLA_HSR_SLAVE2]) {
52
- netdev_info(dev, "HSR: Slave2 device not specified\n");
55
+ NL_SET_ERR_MSG_MOD(extack, "Slave2 device not specified");
5356 return -EINVAL;
5457 }
55
- link[1] = __dev_get_by_index(src_net, nla_get_u32(data[IFLA_HSR_SLAVE2]));
56
-
57
- if (!link[0] || !link[1])
58
- return -ENODEV;
59
- if (link[0] == link[1])
58
+ link[1] = __dev_get_by_index(src_net,
59
+ nla_get_u32(data[IFLA_HSR_SLAVE2]));
60
+ if (!link[1]) {
61
+ NL_SET_ERR_MSG_MOD(extack, "Slave2 does not exist");
6062 return -EINVAL;
63
+ }
64
+
65
+ if (link[0] == link[1]) {
66
+ NL_SET_ERR_MSG_MOD(extack, "Slave1 and Slave2 are same");
67
+ return -EINVAL;
68
+ }
6169
6270 if (!data[IFLA_HSR_MULTICAST_SPEC])
6371 multicast_spec = 0;
6472 else
6573 multicast_spec = nla_get_u8(data[IFLA_HSR_MULTICAST_SPEC]);
6674
75
+ if (data[IFLA_HSR_PROTOCOL])
76
+ proto = nla_get_u8(data[IFLA_HSR_PROTOCOL]);
77
+
78
+ if (proto >= HSR_PROTOCOL_MAX) {
79
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported protocol");
80
+ return -EINVAL;
81
+ }
82
+
6783 if (!data[IFLA_HSR_VERSION]) {
68
- hsr_version = 0;
84
+ proto_version = HSR_V0;
6985 } else {
70
- hsr_version = nla_get_u8(data[IFLA_HSR_VERSION]);
71
- if (hsr_version > 1) {
86
+ if (proto == HSR_PROTOCOL_PRP) {
87
+ NL_SET_ERR_MSG_MOD(extack, "PRP version unsupported");
88
+ return -EINVAL;
89
+ }
90
+
91
+ proto_version = nla_get_u8(data[IFLA_HSR_VERSION]);
92
+ if (proto_version > HSR_V1) {
7293 NL_SET_ERR_MSG_MOD(extack,
73
- "Only versions 0..1 are supported");
94
+ "Only HSR version 0/1 supported");
7495 return -EINVAL;
7596 }
7697 }
7798
78
- return hsr_dev_finalize(dev, link, multicast_spec, hsr_version);
99
+ if (proto == HSR_PROTOCOL_PRP)
100
+ proto_version = PRP_V1;
101
+
102
+ return hsr_dev_finalize(dev, link, multicast_spec, proto_version, extack);
103
+}
104
+
105
+static void hsr_dellink(struct net_device *dev, struct list_head *head)
106
+{
107
+ struct hsr_priv *hsr = netdev_priv(dev);
108
+
109
+ del_timer_sync(&hsr->prune_timer);
110
+ del_timer_sync(&hsr->announce_timer);
111
+
112
+ hsr_debugfs_term(hsr);
113
+ hsr_del_ports(hsr);
114
+
115
+ hsr_del_self_node(hsr);
116
+ hsr_del_nodes(&hsr->node_db);
117
+
118
+ unregister_netdevice_queue(dev, head);
79119 }
80120
81121 static int hsr_fill_info(struct sk_buff *skb, const struct net_device *dev)
82122 {
83
- struct hsr_priv *hsr;
123
+ struct hsr_priv *hsr = netdev_priv(dev);
124
+ u8 proto = HSR_PROTOCOL_HSR;
84125 struct hsr_port *port;
85
- int res;
86126
87
- hsr = netdev_priv(dev);
88
-
89
- res = 0;
90
-
91
- rcu_read_lock();
92127 port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_A);
93
- if (port)
94
- res = nla_put_u32(skb, IFLA_HSR_SLAVE1, port->dev->ifindex);
95
- rcu_read_unlock();
96
- if (res)
97
- goto nla_put_failure;
128
+ if (port) {
129
+ if (nla_put_u32(skb, IFLA_HSR_SLAVE1, port->dev->ifindex))
130
+ goto nla_put_failure;
131
+ }
98132
99
- rcu_read_lock();
100133 port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_B);
101
- if (port)
102
- res = nla_put_u32(skb, IFLA_HSR_SLAVE2, port->dev->ifindex);
103
- rcu_read_unlock();
104
- if (res)
105
- goto nla_put_failure;
134
+ if (port) {
135
+ if (nla_put_u32(skb, IFLA_HSR_SLAVE2, port->dev->ifindex))
136
+ goto nla_put_failure;
137
+ }
106138
107139 if (nla_put(skb, IFLA_HSR_SUPERVISION_ADDR, ETH_ALEN,
108140 hsr->sup_multicast_addr) ||
109141 nla_put_u16(skb, IFLA_HSR_SEQ_NR, hsr->sequence_nr))
142
+ goto nla_put_failure;
143
+ if (hsr->prot_version == PRP_V1)
144
+ proto = HSR_PROTOCOL_PRP;
145
+ if (nla_put_u8(skb, IFLA_HSR_PROTOCOL, proto))
110146 goto nla_put_failure;
111147
112148 return 0;
....@@ -122,10 +158,9 @@
122158 .priv_size = sizeof(struct hsr_priv),
123159 .setup = hsr_dev_setup,
124160 .newlink = hsr_newlink,
161
+ .dellink = hsr_dellink,
125162 .fill_info = hsr_fill_info,
126163 };
127
-
128
-
129164
130165 /* attribute policy */
131166 static const struct nla_policy hsr_genl_policy[HSR_A_MAX + 1] = {
....@@ -144,8 +179,6 @@
144179 { .name = "hsr-network", },
145180 };
146181
147
-
148
-
149182 /* This is called if for some node with MAC address addr, we only get frames
150183 * over one of the slave interfaces. This would indicate an open network ring
151184 * (i.e. a link has failed somewhere).
....@@ -162,7 +195,8 @@
162195 if (!skb)
163196 goto fail;
164197
165
- msg_head = genlmsg_put(skb, 0, 0, &hsr_genl_family, 0, HSR_C_RING_ERROR);
198
+ msg_head = genlmsg_put(skb, 0, 0, &hsr_genl_family, 0,
199
+ HSR_C_RING_ERROR);
166200 if (!msg_head)
167201 goto nla_put_failure;
168202
....@@ -207,7 +241,6 @@
207241 if (!msg_head)
208242 goto nla_put_failure;
209243
210
-
211244 res = nla_put(skb, HSR_A_NODE_ADDR, ETH_ALEN, addr);
212245 if (res < 0)
213246 goto nla_put_failure;
....@@ -226,7 +259,6 @@
226259 netdev_warn(master->dev, "Could not send HSR node down\n");
227260 rcu_read_unlock();
228261 }
229
-
230262
231263 /* HSR_C_GET_NODE_STATUS lets userspace query the internal HSR node table
232264 * about the status of a specific node in the network, defined by its MAC
....@@ -281,8 +313,8 @@
281313 }
282314
283315 msg_head = genlmsg_put(skb_out, NETLINK_CB(skb_in).portid,
284
- info->snd_seq, &hsr_genl_family, 0,
285
- HSR_C_SET_NODE_STATUS);
316
+ info->snd_seq, &hsr_genl_family, 0,
317
+ HSR_C_SET_NODE_STATUS);
286318 if (!msg_head) {
287319 res = -ENOMEM;
288320 goto nla_put_failure;
....@@ -294,28 +326,30 @@
294326
295327 hsr = netdev_priv(hsr_dev);
296328 res = hsr_get_node_data(hsr,
297
- (unsigned char *) nla_data(info->attrs[HSR_A_NODE_ADDR]),
298
- hsr_node_addr_b,
299
- &addr_b_ifindex,
300
- &hsr_node_if1_age,
301
- &hsr_node_if1_seq,
302
- &hsr_node_if2_age,
303
- &hsr_node_if2_seq);
329
+ (unsigned char *)
330
+ nla_data(info->attrs[HSR_A_NODE_ADDR]),
331
+ hsr_node_addr_b,
332
+ &addr_b_ifindex,
333
+ &hsr_node_if1_age,
334
+ &hsr_node_if1_seq,
335
+ &hsr_node_if2_age,
336
+ &hsr_node_if2_seq);
304337 if (res < 0)
305338 goto nla_put_failure;
306339
307340 res = nla_put(skb_out, HSR_A_NODE_ADDR, ETH_ALEN,
308
- nla_data(info->attrs[HSR_A_NODE_ADDR]));
341
+ nla_data(info->attrs[HSR_A_NODE_ADDR]));
309342 if (res < 0)
310343 goto nla_put_failure;
311344
312345 if (addr_b_ifindex > -1) {
313346 res = nla_put(skb_out, HSR_A_NODE_ADDR_B, ETH_ALEN,
314
- hsr_node_addr_b);
347
+ hsr_node_addr_b);
315348 if (res < 0)
316349 goto nla_put_failure;
317350
318
- res = nla_put_u32(skb_out, HSR_A_ADDR_B_IFINDEX, addr_b_ifindex);
351
+ res = nla_put_u32(skb_out, HSR_A_ADDR_B_IFINDEX,
352
+ addr_b_ifindex);
319353 if (res < 0)
320354 goto nla_put_failure;
321355 }
....@@ -406,8 +440,8 @@
406440 }
407441
408442 msg_head = genlmsg_put(skb_out, NETLINK_CB(skb_in).portid,
409
- info->snd_seq, &hsr_genl_family, 0,
410
- HSR_C_SET_NODE_LIST);
443
+ info->snd_seq, &hsr_genl_family, 0,
444
+ HSR_C_SET_NODE_LIST);
411445 if (!msg_head) {
412446 res = -ENOMEM;
413447 goto nla_put_failure;
....@@ -459,19 +493,18 @@
459493 return res;
460494 }
461495
462
-
463
-static const struct genl_ops hsr_ops[] = {
496
+static const struct genl_small_ops hsr_ops[] = {
464497 {
465498 .cmd = HSR_C_GET_NODE_STATUS,
499
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
466500 .flags = 0,
467
- .policy = hsr_genl_policy,
468501 .doit = hsr_get_node_status,
469502 .dumpit = NULL,
470503 },
471504 {
472505 .cmd = HSR_C_GET_NODE_LIST,
506
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
473507 .flags = 0,
474
- .policy = hsr_genl_policy,
475508 .doit = hsr_get_node_list,
476509 .dumpit = NULL,
477510 },
....@@ -482,10 +515,11 @@
482515 .name = "HSR",
483516 .version = 1,
484517 .maxattr = HSR_A_MAX,
518
+ .policy = hsr_genl_policy,
485519 .netnsok = true,
486520 .module = THIS_MODULE,
487
- .ops = hsr_ops,
488
- .n_ops = ARRAY_SIZE(hsr_ops),
521
+ .small_ops = hsr_ops,
522
+ .n_small_ops = ARRAY_SIZE(hsr_ops),
489523 .mcgrps = hsr_mcgrps,
490524 .n_mcgrps = ARRAY_SIZE(hsr_mcgrps),
491525 };
....@@ -502,6 +536,7 @@
502536 if (rc)
503537 goto fail_genl_register_family;
504538
539
+ hsr_debugfs_create_root();
505540 return 0;
506541
507542 fail_genl_register_family: