root/net/hsr/hsr_netlink.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hsr_newlink
  2. hsr_fill_info
  3. hsr_nl_ringerror
  4. hsr_nl_nodedown
  5. hsr_get_node_status
  6. hsr_get_node_list
  7. hsr_netlink_init
  8. hsr_netlink_exit

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

/* [<][>][^][v][top][bottom][index][help] */