• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* 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.
7  *
8  * Author(s):
9  *	2011-2014 Arvid Brodin, arvid.brodin@alten.se
10  *
11  * Routines for handling Netlink messages for HSR.
12  */
13 
14 #include "hsr_netlink.h"
15 #include <linux/kernel.h>
16 #include <net/rtnetlink.h>
17 #include <net/genetlink.h>
18 #include "hsr_main.h"
19 #include "hsr_device.h"
20 #include "hsr_framereg.h"
21 
22 static const struct nla_policy hsr_policy[IFLA_HSR_MAX + 1] = {
23 	[IFLA_HSR_SLAVE1]		= { .type = NLA_U32 },
24 	[IFLA_HSR_SLAVE2]		= { .type = NLA_U32 },
25 	[IFLA_HSR_MULTICAST_SPEC]	= { .type = NLA_U8 },
26 	[IFLA_HSR_VERSION]	= { .type = NLA_U8 },
27 	[IFLA_HSR_SUPERVISION_ADDR]	= { .len = ETH_ALEN },
28 	[IFLA_HSR_SEQ_NR]		= { .type = NLA_U16 },
29 };
30 
31 
32 /* Here, it seems a netdevice has already been allocated for us, and the
33  * hsr_dev_setup routine has been executed. Nice!
34  */
hsr_newlink(struct net * src_net,struct net_device * dev,struct nlattr * tb[],struct nlattr * data[],struct netlink_ext_ack * extack)35 static int hsr_newlink(struct net *src_net, struct net_device *dev,
36 		       struct nlattr *tb[], struct nlattr *data[],
37 		       struct netlink_ext_ack *extack)
38 {
39 	struct net_device *link[2];
40 	unsigned char multicast_spec, hsr_version;
41 
42 	if (!data) {
43 		netdev_info(dev, "HSR: No slave devices specified\n");
44 		return -EINVAL;
45 	}
46 	if (!data[IFLA_HSR_SLAVE1]) {
47 		netdev_info(dev, "HSR: Slave1 device not specified\n");
48 		return -EINVAL;
49 	}
50 	link[0] = __dev_get_by_index(src_net, nla_get_u32(data[IFLA_HSR_SLAVE1]));
51 	if (!data[IFLA_HSR_SLAVE2]) {
52 		netdev_info(dev, "HSR: Slave2 device not specified\n");
53 		return -EINVAL;
54 	}
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])
60 		return -EINVAL;
61 
62 	if (!data[IFLA_HSR_MULTICAST_SPEC])
63 		multicast_spec = 0;
64 	else
65 		multicast_spec = nla_get_u8(data[IFLA_HSR_MULTICAST_SPEC]);
66 
67 	if (!data[IFLA_HSR_VERSION]) {
68 		hsr_version = 0;
69 	} else {
70 		hsr_version = nla_get_u8(data[IFLA_HSR_VERSION]);
71 		if (hsr_version > 1) {
72 			NL_SET_ERR_MSG_MOD(extack,
73 					   "Only versions 0..1 are supported");
74 			return -EINVAL;
75 		}
76 	}
77 
78 	return hsr_dev_finalize(dev, link, multicast_spec, hsr_version);
79 }
80 
hsr_fill_info(struct sk_buff * skb,const struct net_device * dev)81 static int hsr_fill_info(struct sk_buff *skb, const struct net_device *dev)
82 {
83 	struct hsr_priv *hsr;
84 	struct hsr_port *port;
85 	int res;
86 
87 	hsr = netdev_priv(dev);
88 
89 	res = 0;
90 
91 	rcu_read_lock();
92 	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;
98 
99 	rcu_read_lock();
100 	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;
106 
107 	if (nla_put(skb, IFLA_HSR_SUPERVISION_ADDR, ETH_ALEN,
108 		    hsr->sup_multicast_addr) ||
109 	    nla_put_u16(skb, IFLA_HSR_SEQ_NR, hsr->sequence_nr))
110 		goto nla_put_failure;
111 
112 	return 0;
113 
114 nla_put_failure:
115 	return -EMSGSIZE;
116 }
117 
118 static struct rtnl_link_ops hsr_link_ops __read_mostly = {
119 	.kind		= "hsr",
120 	.maxtype	= IFLA_HSR_MAX,
121 	.policy		= hsr_policy,
122 	.priv_size	= sizeof(struct hsr_priv),
123 	.setup		= hsr_dev_setup,
124 	.newlink	= hsr_newlink,
125 	.fill_info	= hsr_fill_info,
126 };
127 
128 
129 
130 /* attribute policy */
131 static const struct nla_policy hsr_genl_policy[HSR_A_MAX + 1] = {
132 	[HSR_A_NODE_ADDR] = { .len = ETH_ALEN },
133 	[HSR_A_NODE_ADDR_B] = { .len = ETH_ALEN },
134 	[HSR_A_IFINDEX] = { .type = NLA_U32 },
135 	[HSR_A_IF1_AGE] = { .type = NLA_U32 },
136 	[HSR_A_IF2_AGE] = { .type = NLA_U32 },
137 	[HSR_A_IF1_SEQ] = { .type = NLA_U16 },
138 	[HSR_A_IF2_SEQ] = { .type = NLA_U16 },
139 };
140 
141 static struct genl_family hsr_genl_family;
142 
143 static const struct genl_multicast_group hsr_mcgrps[] = {
144 	{ .name = "hsr-network", },
145 };
146 
147 
148 
149 /* This is called if for some node with MAC address addr, we only get frames
150  * over one of the slave interfaces. This would indicate an open network ring
151  * (i.e. a link has failed somewhere).
152  */
hsr_nl_ringerror(struct hsr_priv * hsr,unsigned char addr[ETH_ALEN],struct hsr_port * port)153 void hsr_nl_ringerror(struct hsr_priv *hsr, unsigned char addr[ETH_ALEN],
154 		      struct hsr_port *port)
155 {
156 	struct sk_buff *skb;
157 	void *msg_head;
158 	struct hsr_port *master;
159 	int res;
160 
161 	skb = genlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
162 	if (!skb)
163 		goto fail;
164 
165 	msg_head = genlmsg_put(skb, 0, 0, &hsr_genl_family, 0, HSR_C_RING_ERROR);
166 	if (!msg_head)
167 		goto nla_put_failure;
168 
169 	res = nla_put(skb, HSR_A_NODE_ADDR, ETH_ALEN, addr);
170 	if (res < 0)
171 		goto nla_put_failure;
172 
173 	res = nla_put_u32(skb, HSR_A_IFINDEX, port->dev->ifindex);
174 	if (res < 0)
175 		goto nla_put_failure;
176 
177 	genlmsg_end(skb, msg_head);
178 	genlmsg_multicast(&hsr_genl_family, skb, 0, 0, GFP_ATOMIC);
179 
180 	return;
181 
182 nla_put_failure:
183 	kfree_skb(skb);
184 
185 fail:
186 	rcu_read_lock();
187 	master = hsr_port_get_hsr(hsr, HSR_PT_MASTER);
188 	netdev_warn(master->dev, "Could not send HSR ring error message\n");
189 	rcu_read_unlock();
190 }
191 
192 /* This is called when we haven't heard from the node with MAC address addr for
193  * some time (just before the node is removed from the node table/list).
194  */
hsr_nl_nodedown(struct hsr_priv * hsr,unsigned char addr[ETH_ALEN])195 void hsr_nl_nodedown(struct hsr_priv *hsr, unsigned char addr[ETH_ALEN])
196 {
197 	struct sk_buff *skb;
198 	void *msg_head;
199 	struct hsr_port *master;
200 	int res;
201 
202 	skb = genlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
203 	if (!skb)
204 		goto fail;
205 
206 	msg_head = genlmsg_put(skb, 0, 0, &hsr_genl_family, 0, HSR_C_NODE_DOWN);
207 	if (!msg_head)
208 		goto nla_put_failure;
209 
210 
211 	res = nla_put(skb, HSR_A_NODE_ADDR, ETH_ALEN, addr);
212 	if (res < 0)
213 		goto nla_put_failure;
214 
215 	genlmsg_end(skb, msg_head);
216 	genlmsg_multicast(&hsr_genl_family, skb, 0, 0, GFP_ATOMIC);
217 
218 	return;
219 
220 nla_put_failure:
221 	kfree_skb(skb);
222 
223 fail:
224 	rcu_read_lock();
225 	master = hsr_port_get_hsr(hsr, HSR_PT_MASTER);
226 	netdev_warn(master->dev, "Could not send HSR node down\n");
227 	rcu_read_unlock();
228 }
229 
230 
231 /* HSR_C_GET_NODE_STATUS lets userspace query the internal HSR node table
232  * about the status of a specific node in the network, defined by its MAC
233  * address.
234  *
235  * Input: hsr ifindex, node mac address
236  * Output: hsr ifindex, node mac address (copied from request),
237  *	   age of latest frame from node over slave 1, slave 2 [ms]
238  */
hsr_get_node_status(struct sk_buff * skb_in,struct genl_info * info)239 static int hsr_get_node_status(struct sk_buff *skb_in, struct genl_info *info)
240 {
241 	/* For receiving */
242 	struct nlattr *na;
243 	struct net_device *hsr_dev;
244 
245 	/* For sending */
246 	struct sk_buff *skb_out;
247 	void *msg_head;
248 	struct hsr_priv *hsr;
249 	struct hsr_port *port;
250 	unsigned char hsr_node_addr_b[ETH_ALEN];
251 	int hsr_node_if1_age;
252 	u16 hsr_node_if1_seq;
253 	int hsr_node_if2_age;
254 	u16 hsr_node_if2_seq;
255 	int addr_b_ifindex;
256 	int res;
257 
258 	if (!info)
259 		goto invalid;
260 
261 	na = info->attrs[HSR_A_IFINDEX];
262 	if (!na)
263 		goto invalid;
264 	na = info->attrs[HSR_A_NODE_ADDR];
265 	if (!na)
266 		goto invalid;
267 
268 	rcu_read_lock();
269 	hsr_dev = dev_get_by_index_rcu(genl_info_net(info),
270 				       nla_get_u32(info->attrs[HSR_A_IFINDEX]));
271 	if (!hsr_dev)
272 		goto rcu_unlock;
273 	if (!is_hsr_master(hsr_dev))
274 		goto rcu_unlock;
275 
276 	/* Send reply */
277 	skb_out = genlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
278 	if (!skb_out) {
279 		res = -ENOMEM;
280 		goto fail;
281 	}
282 
283 	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);
286 	if (!msg_head) {
287 		res = -ENOMEM;
288 		goto nla_put_failure;
289 	}
290 
291 	res = nla_put_u32(skb_out, HSR_A_IFINDEX, hsr_dev->ifindex);
292 	if (res < 0)
293 		goto nla_put_failure;
294 
295 	hsr = netdev_priv(hsr_dev);
296 	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);
304 	if (res < 0)
305 		goto nla_put_failure;
306 
307 	res = nla_put(skb_out, HSR_A_NODE_ADDR, ETH_ALEN,
308 					nla_data(info->attrs[HSR_A_NODE_ADDR]));
309 	if (res < 0)
310 		goto nla_put_failure;
311 
312 	if (addr_b_ifindex > -1) {
313 		res = nla_put(skb_out, HSR_A_NODE_ADDR_B, ETH_ALEN,
314 								hsr_node_addr_b);
315 		if (res < 0)
316 			goto nla_put_failure;
317 
318 		res = nla_put_u32(skb_out, HSR_A_ADDR_B_IFINDEX, addr_b_ifindex);
319 		if (res < 0)
320 			goto nla_put_failure;
321 	}
322 
323 	res = nla_put_u32(skb_out, HSR_A_IF1_AGE, hsr_node_if1_age);
324 	if (res < 0)
325 		goto nla_put_failure;
326 	res = nla_put_u16(skb_out, HSR_A_IF1_SEQ, hsr_node_if1_seq);
327 	if (res < 0)
328 		goto nla_put_failure;
329 	port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_A);
330 	if (port)
331 		res = nla_put_u32(skb_out, HSR_A_IF1_IFINDEX,
332 				  port->dev->ifindex);
333 	if (res < 0)
334 		goto nla_put_failure;
335 
336 	res = nla_put_u32(skb_out, HSR_A_IF2_AGE, hsr_node_if2_age);
337 	if (res < 0)
338 		goto nla_put_failure;
339 	res = nla_put_u16(skb_out, HSR_A_IF2_SEQ, hsr_node_if2_seq);
340 	if (res < 0)
341 		goto nla_put_failure;
342 	port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_B);
343 	if (port)
344 		res = nla_put_u32(skb_out, HSR_A_IF2_IFINDEX,
345 				  port->dev->ifindex);
346 	if (res < 0)
347 		goto nla_put_failure;
348 
349 	rcu_read_unlock();
350 
351 	genlmsg_end(skb_out, msg_head);
352 	genlmsg_unicast(genl_info_net(info), skb_out, info->snd_portid);
353 
354 	return 0;
355 
356 rcu_unlock:
357 	rcu_read_unlock();
358 invalid:
359 	netlink_ack(skb_in, nlmsg_hdr(skb_in), -EINVAL, NULL);
360 	return 0;
361 
362 nla_put_failure:
363 	kfree_skb(skb_out);
364 	/* Fall through */
365 
366 fail:
367 	rcu_read_unlock();
368 	return res;
369 }
370 
371 /* Get a list of MacAddressA of all nodes known to this node (including self).
372  */
hsr_get_node_list(struct sk_buff * skb_in,struct genl_info * info)373 static int hsr_get_node_list(struct sk_buff *skb_in, struct genl_info *info)
374 {
375 	unsigned char addr[ETH_ALEN];
376 	struct net_device *hsr_dev;
377 	struct sk_buff *skb_out;
378 	struct hsr_priv *hsr;
379 	bool restart = false;
380 	struct nlattr *na;
381 	void *pos = NULL;
382 	void *msg_head;
383 	int res;
384 
385 	if (!info)
386 		goto invalid;
387 
388 	na = info->attrs[HSR_A_IFINDEX];
389 	if (!na)
390 		goto invalid;
391 
392 	rcu_read_lock();
393 	hsr_dev = dev_get_by_index_rcu(genl_info_net(info),
394 				       nla_get_u32(info->attrs[HSR_A_IFINDEX]));
395 	if (!hsr_dev)
396 		goto rcu_unlock;
397 	if (!is_hsr_master(hsr_dev))
398 		goto rcu_unlock;
399 
400 restart:
401 	/* Send reply */
402 	skb_out = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_ATOMIC);
403 	if (!skb_out) {
404 		res = -ENOMEM;
405 		goto fail;
406 	}
407 
408 	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);
411 	if (!msg_head) {
412 		res = -ENOMEM;
413 		goto nla_put_failure;
414 	}
415 
416 	if (!restart) {
417 		res = nla_put_u32(skb_out, HSR_A_IFINDEX, hsr_dev->ifindex);
418 		if (res < 0)
419 			goto nla_put_failure;
420 	}
421 
422 	hsr = netdev_priv(hsr_dev);
423 
424 	if (!pos)
425 		pos = hsr_get_next_node(hsr, NULL, addr);
426 	while (pos) {
427 		res = nla_put(skb_out, HSR_A_NODE_ADDR, ETH_ALEN, addr);
428 		if (res < 0) {
429 			if (res == -EMSGSIZE) {
430 				genlmsg_end(skb_out, msg_head);
431 				genlmsg_unicast(genl_info_net(info), skb_out,
432 						info->snd_portid);
433 				restart = true;
434 				goto restart;
435 			}
436 			goto nla_put_failure;
437 		}
438 		pos = hsr_get_next_node(hsr, pos, addr);
439 	}
440 	rcu_read_unlock();
441 
442 	genlmsg_end(skb_out, msg_head);
443 	genlmsg_unicast(genl_info_net(info), skb_out, info->snd_portid);
444 
445 	return 0;
446 
447 rcu_unlock:
448 	rcu_read_unlock();
449 invalid:
450 	netlink_ack(skb_in, nlmsg_hdr(skb_in), -EINVAL, NULL);
451 	return 0;
452 
453 nla_put_failure:
454 	nlmsg_free(skb_out);
455 	/* Fall through */
456 
457 fail:
458 	rcu_read_unlock();
459 	return res;
460 }
461 
462 
463 static const struct genl_ops hsr_ops[] = {
464 	{
465 		.cmd = HSR_C_GET_NODE_STATUS,
466 		.flags = 0,
467 		.policy = hsr_genl_policy,
468 		.doit = hsr_get_node_status,
469 		.dumpit = NULL,
470 	},
471 	{
472 		.cmd = HSR_C_GET_NODE_LIST,
473 		.flags = 0,
474 		.policy = hsr_genl_policy,
475 		.doit = hsr_get_node_list,
476 		.dumpit = NULL,
477 	},
478 };
479 
480 static struct genl_family hsr_genl_family __ro_after_init = {
481 	.hdrsize = 0,
482 	.name = "HSR",
483 	.version = 1,
484 	.maxattr = HSR_A_MAX,
485 	.netnsok = true,
486 	.module = THIS_MODULE,
487 	.ops = hsr_ops,
488 	.n_ops = ARRAY_SIZE(hsr_ops),
489 	.mcgrps = hsr_mcgrps,
490 	.n_mcgrps = ARRAY_SIZE(hsr_mcgrps),
491 };
492 
hsr_netlink_init(void)493 int __init hsr_netlink_init(void)
494 {
495 	int rc;
496 
497 	rc = rtnl_link_register(&hsr_link_ops);
498 	if (rc)
499 		goto fail_rtnl_link_register;
500 
501 	rc = genl_register_family(&hsr_genl_family);
502 	if (rc)
503 		goto fail_genl_register_family;
504 
505 	return 0;
506 
507 fail_genl_register_family:
508 	rtnl_link_unregister(&hsr_link_ops);
509 fail_rtnl_link_register:
510 
511 	return rc;
512 }
513 
hsr_netlink_exit(void)514 void __exit hsr_netlink_exit(void)
515 {
516 	genl_unregister_family(&hsr_genl_family);
517 	rtnl_link_unregister(&hsr_link_ops);
518 }
519 
520 MODULE_ALIAS_RTNL_LINK("hsr");
521