1 /* Copyright 2011-2013 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-2013 Arvid Brodin, arvid.brodin@xdin.com 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 }; 27 28 29 /* Here, it seems a netdevice has already been allocated for us, and the 30 * hsr_dev_setup routine has been executed. Nice! 31 */ 32 static int hsr_newlink(struct net *src_net, struct net_device *dev, 33 struct nlattr *tb[], struct nlattr *data[]) 34 { 35 struct net_device *link[2]; 36 unsigned char multicast_spec; 37 38 if (!data[IFLA_HSR_SLAVE1]) { 39 netdev_info(dev, "IFLA_HSR_SLAVE1 missing!\n"); 40 return -EINVAL; 41 } 42 link[0] = __dev_get_by_index(src_net, nla_get_u32(data[IFLA_HSR_SLAVE1])); 43 if (!data[IFLA_HSR_SLAVE2]) { 44 netdev_info(dev, "IFLA_HSR_SLAVE2 missing!\n"); 45 return -EINVAL; 46 } 47 link[1] = __dev_get_by_index(src_net, nla_get_u32(data[IFLA_HSR_SLAVE2])); 48 49 if (!link[0] || !link[1]) 50 return -ENODEV; 51 if (link[0] == link[1]) 52 return -EINVAL; 53 54 if (!data[IFLA_HSR_MULTICAST_SPEC]) 55 multicast_spec = 0; 56 else 57 multicast_spec = nla_get_u8(data[IFLA_HSR_MULTICAST_SPEC]); 58 59 return hsr_dev_finalize(dev, link, multicast_spec); 60 } 61 62 static struct rtnl_link_ops hsr_link_ops __read_mostly = { 63 .kind = "hsr", 64 .maxtype = IFLA_HSR_MAX, 65 .policy = hsr_policy, 66 .priv_size = sizeof(struct hsr_priv), 67 .setup = hsr_dev_setup, 68 .newlink = hsr_newlink, 69 }; 70 71 72 73 /* attribute policy */ 74 /* NLA_BINARY missing in libnl; use NLA_UNSPEC in userspace instead. */ 75 static const struct nla_policy hsr_genl_policy[HSR_A_MAX + 1] = { 76 [HSR_A_NODE_ADDR] = { .type = NLA_BINARY, .len = ETH_ALEN }, 77 [HSR_A_NODE_ADDR_B] = { .type = NLA_BINARY, .len = ETH_ALEN }, 78 [HSR_A_IFINDEX] = { .type = NLA_U32 }, 79 [HSR_A_IF1_AGE] = { .type = NLA_U32 }, 80 [HSR_A_IF2_AGE] = { .type = NLA_U32 }, 81 [HSR_A_IF1_SEQ] = { .type = NLA_U16 }, 82 [HSR_A_IF2_SEQ] = { .type = NLA_U16 }, 83 }; 84 85 static struct genl_family hsr_genl_family = { 86 .id = GENL_ID_GENERATE, 87 .hdrsize = 0, 88 .name = "HSR", 89 .version = 1, 90 .maxattr = HSR_A_MAX, 91 }; 92 93 static const struct genl_multicast_group hsr_mcgrps[] = { 94 { .name = "hsr-network", }, 95 }; 96 97 98 99 /* This is called if for some node with MAC address addr, we only get frames 100 * over one of the slave interfaces. This would indicate an open network ring 101 * (i.e. a link has failed somewhere). 102 */ 103 void hsr_nl_ringerror(struct hsr_priv *hsr_priv, unsigned char addr[ETH_ALEN], 104 enum hsr_dev_idx dev_idx) 105 { 106 struct sk_buff *skb; 107 void *msg_head; 108 int res; 109 int ifindex; 110 111 skb = genlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC); 112 if (!skb) 113 goto fail; 114 115 msg_head = genlmsg_put(skb, 0, 0, &hsr_genl_family, 0, HSR_C_RING_ERROR); 116 if (!msg_head) 117 goto nla_put_failure; 118 119 res = nla_put(skb, HSR_A_NODE_ADDR, ETH_ALEN, addr); 120 if (res < 0) 121 goto nla_put_failure; 122 123 if (hsr_priv->slave[dev_idx]) 124 ifindex = hsr_priv->slave[dev_idx]->ifindex; 125 else 126 ifindex = -1; 127 res = nla_put_u32(skb, HSR_A_IFINDEX, ifindex); 128 if (res < 0) 129 goto nla_put_failure; 130 131 genlmsg_end(skb, msg_head); 132 genlmsg_multicast(&hsr_genl_family, skb, 0, 0, GFP_ATOMIC); 133 134 return; 135 136 nla_put_failure: 137 kfree_skb(skb); 138 139 fail: 140 netdev_warn(hsr_priv->dev, "Could not send HSR ring error message\n"); 141 } 142 143 /* This is called when we haven't heard from the node with MAC address addr for 144 * some time (just before the node is removed from the node table/list). 145 */ 146 void hsr_nl_nodedown(struct hsr_priv *hsr_priv, unsigned char addr[ETH_ALEN]) 147 { 148 struct sk_buff *skb; 149 void *msg_head; 150 int res; 151 152 skb = genlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC); 153 if (!skb) 154 goto fail; 155 156 msg_head = genlmsg_put(skb, 0, 0, &hsr_genl_family, 0, HSR_C_NODE_DOWN); 157 if (!msg_head) 158 goto nla_put_failure; 159 160 161 res = nla_put(skb, HSR_A_NODE_ADDR, ETH_ALEN, addr); 162 if (res < 0) 163 goto nla_put_failure; 164 165 genlmsg_end(skb, msg_head); 166 genlmsg_multicast(&hsr_genl_family, skb, 0, 0, GFP_ATOMIC); 167 168 return; 169 170 nla_put_failure: 171 kfree_skb(skb); 172 173 fail: 174 netdev_warn(hsr_priv->dev, "Could not send HSR node down\n"); 175 } 176 177 178 /* HSR_C_GET_NODE_STATUS lets userspace query the internal HSR node table 179 * about the status of a specific node in the network, defined by its MAC 180 * address. 181 * 182 * Input: hsr ifindex, node mac address 183 * Output: hsr ifindex, node mac address (copied from request), 184 * age of latest frame from node over slave 1, slave 2 [ms] 185 */ 186 static int hsr_get_node_status(struct sk_buff *skb_in, struct genl_info *info) 187 { 188 /* For receiving */ 189 struct nlattr *na; 190 struct net_device *hsr_dev; 191 192 /* For sending */ 193 struct sk_buff *skb_out; 194 void *msg_head; 195 struct hsr_priv *hsr_priv; 196 unsigned char hsr_node_addr_b[ETH_ALEN]; 197 int hsr_node_if1_age; 198 u16 hsr_node_if1_seq; 199 int hsr_node_if2_age; 200 u16 hsr_node_if2_seq; 201 int addr_b_ifindex; 202 int res; 203 204 if (!info) 205 goto invalid; 206 207 na = info->attrs[HSR_A_IFINDEX]; 208 if (!na) 209 goto invalid; 210 na = info->attrs[HSR_A_NODE_ADDR]; 211 if (!na) 212 goto invalid; 213 214 hsr_dev = __dev_get_by_index(genl_info_net(info), 215 nla_get_u32(info->attrs[HSR_A_IFINDEX])); 216 if (!hsr_dev) 217 goto invalid; 218 if (!is_hsr_master(hsr_dev)) 219 goto invalid; 220 221 222 /* Send reply */ 223 224 skb_out = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 225 if (!skb_out) { 226 res = -ENOMEM; 227 goto fail; 228 } 229 230 msg_head = genlmsg_put(skb_out, NETLINK_CB(skb_in).portid, 231 info->snd_seq, &hsr_genl_family, 0, 232 HSR_C_SET_NODE_STATUS); 233 if (!msg_head) { 234 res = -ENOMEM; 235 goto nla_put_failure; 236 } 237 238 res = nla_put_u32(skb_out, HSR_A_IFINDEX, hsr_dev->ifindex); 239 if (res < 0) 240 goto nla_put_failure; 241 242 hsr_priv = netdev_priv(hsr_dev); 243 res = hsr_get_node_data(hsr_priv, 244 (unsigned char *) nla_data(info->attrs[HSR_A_NODE_ADDR]), 245 hsr_node_addr_b, 246 &addr_b_ifindex, 247 &hsr_node_if1_age, 248 &hsr_node_if1_seq, 249 &hsr_node_if2_age, 250 &hsr_node_if2_seq); 251 if (res < 0) 252 goto nla_put_failure; 253 254 res = nla_put(skb_out, HSR_A_NODE_ADDR, ETH_ALEN, 255 nla_data(info->attrs[HSR_A_NODE_ADDR])); 256 if (res < 0) 257 goto nla_put_failure; 258 259 if (addr_b_ifindex > -1) { 260 res = nla_put(skb_out, HSR_A_NODE_ADDR_B, ETH_ALEN, 261 hsr_node_addr_b); 262 if (res < 0) 263 goto nla_put_failure; 264 265 res = nla_put_u32(skb_out, HSR_A_ADDR_B_IFINDEX, addr_b_ifindex); 266 if (res < 0) 267 goto nla_put_failure; 268 } 269 270 res = nla_put_u32(skb_out, HSR_A_IF1_AGE, hsr_node_if1_age); 271 if (res < 0) 272 goto nla_put_failure; 273 res = nla_put_u16(skb_out, HSR_A_IF1_SEQ, hsr_node_if1_seq); 274 if (res < 0) 275 goto nla_put_failure; 276 if (hsr_priv->slave[0]) 277 res = nla_put_u32(skb_out, HSR_A_IF1_IFINDEX, 278 hsr_priv->slave[0]->ifindex); 279 if (res < 0) 280 goto nla_put_failure; 281 282 res = nla_put_u32(skb_out, HSR_A_IF2_AGE, hsr_node_if2_age); 283 if (res < 0) 284 goto nla_put_failure; 285 res = nla_put_u16(skb_out, HSR_A_IF2_SEQ, hsr_node_if2_seq); 286 if (res < 0) 287 goto nla_put_failure; 288 if (hsr_priv->slave[1]) 289 res = nla_put_u32(skb_out, HSR_A_IF2_IFINDEX, 290 hsr_priv->slave[1]->ifindex); 291 292 genlmsg_end(skb_out, msg_head); 293 genlmsg_unicast(genl_info_net(info), skb_out, info->snd_portid); 294 295 return 0; 296 297 invalid: 298 netlink_ack(skb_in, nlmsg_hdr(skb_in), -EINVAL); 299 return 0; 300 301 nla_put_failure: 302 kfree_skb(skb_out); 303 /* Fall through */ 304 305 fail: 306 return res; 307 } 308 309 /* Get a list of MacAddressA of all nodes known to this node (other than self). 310 */ 311 static int hsr_get_node_list(struct sk_buff *skb_in, struct genl_info *info) 312 { 313 /* For receiving */ 314 struct nlattr *na; 315 struct net_device *hsr_dev; 316 317 /* For sending */ 318 struct sk_buff *skb_out; 319 void *msg_head; 320 struct hsr_priv *hsr_priv; 321 void *pos; 322 unsigned char addr[ETH_ALEN]; 323 int res; 324 325 if (!info) 326 goto invalid; 327 328 na = info->attrs[HSR_A_IFINDEX]; 329 if (!na) 330 goto invalid; 331 332 hsr_dev = __dev_get_by_index(genl_info_net(info), 333 nla_get_u32(info->attrs[HSR_A_IFINDEX])); 334 if (!hsr_dev) 335 goto invalid; 336 if (!is_hsr_master(hsr_dev)) 337 goto invalid; 338 339 340 /* Send reply */ 341 342 skb_out = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 343 if (!skb_out) { 344 res = -ENOMEM; 345 goto fail; 346 } 347 348 msg_head = genlmsg_put(skb_out, NETLINK_CB(skb_in).portid, 349 info->snd_seq, &hsr_genl_family, 0, 350 HSR_C_SET_NODE_LIST); 351 if (!msg_head) { 352 res = -ENOMEM; 353 goto nla_put_failure; 354 } 355 356 res = nla_put_u32(skb_out, HSR_A_IFINDEX, hsr_dev->ifindex); 357 if (res < 0) 358 goto nla_put_failure; 359 360 hsr_priv = netdev_priv(hsr_dev); 361 362 rcu_read_lock(); 363 pos = hsr_get_next_node(hsr_priv, NULL, addr); 364 while (pos) { 365 res = nla_put(skb_out, HSR_A_NODE_ADDR, ETH_ALEN, addr); 366 if (res < 0) { 367 rcu_read_unlock(); 368 goto nla_put_failure; 369 } 370 pos = hsr_get_next_node(hsr_priv, pos, addr); 371 } 372 rcu_read_unlock(); 373 374 genlmsg_end(skb_out, msg_head); 375 genlmsg_unicast(genl_info_net(info), skb_out, info->snd_portid); 376 377 return 0; 378 379 invalid: 380 netlink_ack(skb_in, nlmsg_hdr(skb_in), -EINVAL); 381 return 0; 382 383 nla_put_failure: 384 kfree_skb(skb_out); 385 /* Fall through */ 386 387 fail: 388 return res; 389 } 390 391 392 static const struct genl_ops hsr_ops[] = { 393 { 394 .cmd = HSR_C_GET_NODE_STATUS, 395 .flags = 0, 396 .policy = hsr_genl_policy, 397 .doit = hsr_get_node_status, 398 .dumpit = NULL, 399 }, 400 { 401 .cmd = HSR_C_GET_NODE_LIST, 402 .flags = 0, 403 .policy = hsr_genl_policy, 404 .doit = hsr_get_node_list, 405 .dumpit = NULL, 406 }, 407 }; 408 409 int __init hsr_netlink_init(void) 410 { 411 int rc; 412 413 rc = rtnl_link_register(&hsr_link_ops); 414 if (rc) 415 goto fail_rtnl_link_register; 416 417 rc = genl_register_family_with_ops_groups(&hsr_genl_family, hsr_ops, 418 hsr_mcgrps); 419 if (rc) 420 goto fail_genl_register_family; 421 422 return 0; 423 424 fail_genl_register_family: 425 rtnl_link_unregister(&hsr_link_ops); 426 fail_rtnl_link_register: 427 428 return rc; 429 } 430 431 void __exit hsr_netlink_exit(void) 432 { 433 genl_unregister_family(&hsr_genl_family); 434 rtnl_link_unregister(&hsr_link_ops); 435 } 436 437 MODULE_ALIAS_RTNL_LINK("hsr"); 438