aboutsummaryrefslogtreecommitdiffstats
path: root/net/hsr/hsr_netlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/hsr/hsr_netlink.c')
-rw-r--r--net/hsr/hsr_netlink.c102
1 files changed, 65 insertions, 37 deletions
diff --git a/net/hsr/hsr_netlink.c b/net/hsr/hsr_netlink.c
index 01a5261ac7a5..a2c7e4c0ac1e 100644
--- a/net/hsr/hsr_netlink.c
+++ b/net/hsr/hsr_netlink.c
@@ -1,4 +1,4 @@
1/* Copyright 2011-2013 Autronica Fire and Security AS 1/* Copyright 2011-2014 Autronica Fire and Security AS
2 * 2 *
3 * This program is free software; you can redistribute it and/or modify it 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 4 * under the terms of the GNU General Public License as published by the Free
@@ -6,7 +6,7 @@
6 * any later version. 6 * any later version.
7 * 7 *
8 * Author(s): 8 * Author(s):
9 * 2011-2013 Arvid Brodin, arvid.brodin@xdin.com 9 * 2011-2014 Arvid Brodin, arvid.brodin@alten.se
10 * 10 *
11 * Routines for handling Netlink messages for HSR. 11 * Routines for handling Netlink messages for HSR.
12 */ 12 */
@@ -37,13 +37,17 @@ static int hsr_newlink(struct net *src_net, struct net_device *dev,
37 struct net_device *link[2]; 37 struct net_device *link[2];
38 unsigned char multicast_spec; 38 unsigned char multicast_spec;
39 39
40 if (!data) {
41 netdev_info(dev, "HSR: No slave devices specified\n");
42 return -EINVAL;
43 }
40 if (!data[IFLA_HSR_SLAVE1]) { 44 if (!data[IFLA_HSR_SLAVE1]) {
41 netdev_info(dev, "IFLA_HSR_SLAVE1 missing!\n"); 45 netdev_info(dev, "HSR: Slave1 device not specified\n");
42 return -EINVAL; 46 return -EINVAL;
43 } 47 }
44 link[0] = __dev_get_by_index(src_net, nla_get_u32(data[IFLA_HSR_SLAVE1])); 48 link[0] = __dev_get_by_index(src_net, nla_get_u32(data[IFLA_HSR_SLAVE1]));
45 if (!data[IFLA_HSR_SLAVE2]) { 49 if (!data[IFLA_HSR_SLAVE2]) {
46 netdev_info(dev, "IFLA_HSR_SLAVE2 missing!\n"); 50 netdev_info(dev, "HSR: Slave2 device not specified\n");
47 return -EINVAL; 51 return -EINVAL;
48 } 52 }
49 link[1] = __dev_get_by_index(src_net, nla_get_u32(data[IFLA_HSR_SLAVE2])); 53 link[1] = __dev_get_by_index(src_net, nla_get_u32(data[IFLA_HSR_SLAVE2]));
@@ -63,21 +67,33 @@ static int hsr_newlink(struct net *src_net, struct net_device *dev,
63 67
64static int hsr_fill_info(struct sk_buff *skb, const struct net_device *dev) 68static int hsr_fill_info(struct sk_buff *skb, const struct net_device *dev)
65{ 69{
66 struct hsr_priv *hsr_priv; 70 struct hsr_priv *hsr;
71 struct hsr_port *port;
72 int res;
67 73
68 hsr_priv = netdev_priv(dev); 74 hsr = netdev_priv(dev);
69 75
70 if (hsr_priv->slave[0]) 76 res = 0;
71 if (nla_put_u32(skb, IFLA_HSR_SLAVE1, hsr_priv->slave[0]->ifindex))
72 goto nla_put_failure;
73 77
74 if (hsr_priv->slave[1]) 78 rcu_read_lock();
75 if (nla_put_u32(skb, IFLA_HSR_SLAVE2, hsr_priv->slave[1]->ifindex)) 79 port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_A);
76 goto nla_put_failure; 80 if (port)
81 res = nla_put_u32(skb, IFLA_HSR_SLAVE1, port->dev->ifindex);
82 rcu_read_unlock();
83 if (res)
84 goto nla_put_failure;
85
86 rcu_read_lock();
87 port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_B);
88 if (port)
89 res = nla_put_u32(skb, IFLA_HSR_SLAVE2, port->dev->ifindex);
90 rcu_read_unlock();
91 if (res)
92 goto nla_put_failure;
77 93
78 if (nla_put(skb, IFLA_HSR_SUPERVISION_ADDR, ETH_ALEN, 94 if (nla_put(skb, IFLA_HSR_SUPERVISION_ADDR, ETH_ALEN,
79 hsr_priv->sup_multicast_addr) || 95 hsr->sup_multicast_addr) ||
80 nla_put_u16(skb, IFLA_HSR_SEQ_NR, hsr_priv->sequence_nr)) 96 nla_put_u16(skb, IFLA_HSR_SEQ_NR, hsr->sequence_nr))
81 goto nla_put_failure; 97 goto nla_put_failure;
82 98
83 return 0; 99 return 0;
@@ -128,13 +144,13 @@ static const struct genl_multicast_group hsr_mcgrps[] = {
128 * over one of the slave interfaces. This would indicate an open network ring 144 * over one of the slave interfaces. This would indicate an open network ring
129 * (i.e. a link has failed somewhere). 145 * (i.e. a link has failed somewhere).
130 */ 146 */
131void hsr_nl_ringerror(struct hsr_priv *hsr_priv, unsigned char addr[ETH_ALEN], 147void hsr_nl_ringerror(struct hsr_priv *hsr, unsigned char addr[ETH_ALEN],
132 enum hsr_dev_idx dev_idx) 148 struct hsr_port *port)
133{ 149{
134 struct sk_buff *skb; 150 struct sk_buff *skb;
135 void *msg_head; 151 void *msg_head;
152 struct hsr_port *master;
136 int res; 153 int res;
137 int ifindex;
138 154
139 skb = genlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC); 155 skb = genlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
140 if (!skb) 156 if (!skb)
@@ -148,11 +164,7 @@ void hsr_nl_ringerror(struct hsr_priv *hsr_priv, unsigned char addr[ETH_ALEN],
148 if (res < 0) 164 if (res < 0)
149 goto nla_put_failure; 165 goto nla_put_failure;
150 166
151 if (hsr_priv->slave[dev_idx]) 167 res = nla_put_u32(skb, HSR_A_IFINDEX, port->dev->ifindex);
152 ifindex = hsr_priv->slave[dev_idx]->ifindex;
153 else
154 ifindex = -1;
155 res = nla_put_u32(skb, HSR_A_IFINDEX, ifindex);
156 if (res < 0) 168 if (res < 0)
157 goto nla_put_failure; 169 goto nla_put_failure;
158 170
@@ -165,16 +177,20 @@ nla_put_failure:
165 kfree_skb(skb); 177 kfree_skb(skb);
166 178
167fail: 179fail:
168 netdev_warn(hsr_priv->dev, "Could not send HSR ring error message\n"); 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();
169} 184}
170 185
171/* This is called when we haven't heard from the node with MAC address addr for 186/* This is called when we haven't heard from the node with MAC address addr for
172 * some time (just before the node is removed from the node table/list). 187 * some time (just before the node is removed from the node table/list).
173 */ 188 */
174void hsr_nl_nodedown(struct hsr_priv *hsr_priv, unsigned char addr[ETH_ALEN]) 189void hsr_nl_nodedown(struct hsr_priv *hsr, unsigned char addr[ETH_ALEN])
175{ 190{
176 struct sk_buff *skb; 191 struct sk_buff *skb;
177 void *msg_head; 192 void *msg_head;
193 struct hsr_port *master;
178 int res; 194 int res;
179 195
180 skb = genlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC); 196 skb = genlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
@@ -199,7 +215,10 @@ nla_put_failure:
199 kfree_skb(skb); 215 kfree_skb(skb);
200 216
201fail: 217fail:
202 netdev_warn(hsr_priv->dev, "Could not send HSR node down\n"); 218 rcu_read_lock();
219 master = hsr_port_get_hsr(hsr, HSR_PT_MASTER);
220 netdev_warn(master->dev, "Could not send HSR node down\n");
221 rcu_read_unlock();
203} 222}
204 223
205 224
@@ -220,7 +239,8 @@ static int hsr_get_node_status(struct sk_buff *skb_in, struct genl_info *info)
220 /* For sending */ 239 /* For sending */
221 struct sk_buff *skb_out; 240 struct sk_buff *skb_out;
222 void *msg_head; 241 void *msg_head;
223 struct hsr_priv *hsr_priv; 242 struct hsr_priv *hsr;
243 struct hsr_port *port;
224 unsigned char hsr_node_addr_b[ETH_ALEN]; 244 unsigned char hsr_node_addr_b[ETH_ALEN];
225 int hsr_node_if1_age; 245 int hsr_node_if1_age;
226 u16 hsr_node_if1_seq; 246 u16 hsr_node_if1_seq;
@@ -267,8 +287,8 @@ static int hsr_get_node_status(struct sk_buff *skb_in, struct genl_info *info)
267 if (res < 0) 287 if (res < 0)
268 goto nla_put_failure; 288 goto nla_put_failure;
269 289
270 hsr_priv = netdev_priv(hsr_dev); 290 hsr = netdev_priv(hsr_dev);
271 res = hsr_get_node_data(hsr_priv, 291 res = hsr_get_node_data(hsr,
272 (unsigned char *) nla_data(info->attrs[HSR_A_NODE_ADDR]), 292 (unsigned char *) nla_data(info->attrs[HSR_A_NODE_ADDR]),
273 hsr_node_addr_b, 293 hsr_node_addr_b,
274 &addr_b_ifindex, 294 &addr_b_ifindex,
@@ -301,9 +321,12 @@ static int hsr_get_node_status(struct sk_buff *skb_in, struct genl_info *info)
301 res = nla_put_u16(skb_out, HSR_A_IF1_SEQ, hsr_node_if1_seq); 321 res = nla_put_u16(skb_out, HSR_A_IF1_SEQ, hsr_node_if1_seq);
302 if (res < 0) 322 if (res < 0)
303 goto nla_put_failure; 323 goto nla_put_failure;
304 if (hsr_priv->slave[0]) 324 rcu_read_lock();
325 port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_A);
326 if (port)
305 res = nla_put_u32(skb_out, HSR_A_IF1_IFINDEX, 327 res = nla_put_u32(skb_out, HSR_A_IF1_IFINDEX,
306 hsr_priv->slave[0]->ifindex); 328 port->dev->ifindex);
329 rcu_read_unlock();
307 if (res < 0) 330 if (res < 0)
308 goto nla_put_failure; 331 goto nla_put_failure;
309 332
@@ -313,9 +336,14 @@ static int hsr_get_node_status(struct sk_buff *skb_in, struct genl_info *info)
313 res = nla_put_u16(skb_out, HSR_A_IF2_SEQ, hsr_node_if2_seq); 336 res = nla_put_u16(skb_out, HSR_A_IF2_SEQ, hsr_node_if2_seq);
314 if (res < 0) 337 if (res < 0)
315 goto nla_put_failure; 338 goto nla_put_failure;
316 if (hsr_priv->slave[1]) 339 rcu_read_lock();
340 port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_B);
341 if (port)
317 res = nla_put_u32(skb_out, HSR_A_IF2_IFINDEX, 342 res = nla_put_u32(skb_out, HSR_A_IF2_IFINDEX,
318 hsr_priv->slave[1]->ifindex); 343 port->dev->ifindex);
344 rcu_read_unlock();
345 if (res < 0)
346 goto nla_put_failure;
319 347
320 genlmsg_end(skb_out, msg_head); 348 genlmsg_end(skb_out, msg_head);
321 genlmsg_unicast(genl_info_net(info), skb_out, info->snd_portid); 349 genlmsg_unicast(genl_info_net(info), skb_out, info->snd_portid);
@@ -334,7 +362,7 @@ fail:
334 return res; 362 return res;
335} 363}
336 364
337/* Get a list of MacAddressA of all nodes known to this node (other than self). 365/* Get a list of MacAddressA of all nodes known to this node (including self).
338 */ 366 */
339static int hsr_get_node_list(struct sk_buff *skb_in, struct genl_info *info) 367static int hsr_get_node_list(struct sk_buff *skb_in, struct genl_info *info)
340{ 368{
@@ -345,7 +373,7 @@ static int hsr_get_node_list(struct sk_buff *skb_in, struct genl_info *info)
345 /* For sending */ 373 /* For sending */
346 struct sk_buff *skb_out; 374 struct sk_buff *skb_out;
347 void *msg_head; 375 void *msg_head;
348 struct hsr_priv *hsr_priv; 376 struct hsr_priv *hsr;
349 void *pos; 377 void *pos;
350 unsigned char addr[ETH_ALEN]; 378 unsigned char addr[ETH_ALEN];
351 int res; 379 int res;
@@ -385,17 +413,17 @@ static int hsr_get_node_list(struct sk_buff *skb_in, struct genl_info *info)
385 if (res < 0) 413 if (res < 0)
386 goto nla_put_failure; 414 goto nla_put_failure;
387 415
388 hsr_priv = netdev_priv(hsr_dev); 416 hsr = netdev_priv(hsr_dev);
389 417
390 rcu_read_lock(); 418 rcu_read_lock();
391 pos = hsr_get_next_node(hsr_priv, NULL, addr); 419 pos = hsr_get_next_node(hsr, NULL, addr);
392 while (pos) { 420 while (pos) {
393 res = nla_put(skb_out, HSR_A_NODE_ADDR, ETH_ALEN, addr); 421 res = nla_put(skb_out, HSR_A_NODE_ADDR, ETH_ALEN, addr);
394 if (res < 0) { 422 if (res < 0) {
395 rcu_read_unlock(); 423 rcu_read_unlock();
396 goto nla_put_failure; 424 goto nla_put_failure;
397 } 425 }
398 pos = hsr_get_next_node(hsr_priv, pos, addr); 426 pos = hsr_get_next_node(hsr, pos, addr);
399 } 427 }
400 rcu_read_unlock(); 428 rcu_read_unlock();
401 429