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