OSDN Git Service

Merge branch 'bonding_nl'
[uclinux-h8/linux.git] / drivers / net / bonding / bond_netlink.c
1 /*
2  * drivers/net/bond/bond_netlink.c - Netlink interface for bonding
3  * Copyright (c) 2013 Jiri Pirko <jiri@resnulli.us>
4  * Copyright (c) 2013 Scott Feldman <sfeldma@cumulusnetworks.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  */
11
12 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
13
14 #include <linux/module.h>
15 #include <linux/errno.h>
16 #include <linux/netdevice.h>
17 #include <linux/etherdevice.h>
18 #include <linux/if_link.h>
19 #include <linux/if_ether.h>
20 #include <net/netlink.h>
21 #include <net/rtnetlink.h>
22 #include <linux/reciprocal_div.h>
23 #include "bonding.h"
24
25 static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = {
26         [IFLA_BOND_MODE]                = { .type = NLA_U8 },
27         [IFLA_BOND_ACTIVE_SLAVE]        = { .type = NLA_U32 },
28         [IFLA_BOND_MIIMON]              = { .type = NLA_U32 },
29         [IFLA_BOND_UPDELAY]             = { .type = NLA_U32 },
30         [IFLA_BOND_DOWNDELAY]           = { .type = NLA_U32 },
31         [IFLA_BOND_USE_CARRIER]         = { .type = NLA_U8 },
32         [IFLA_BOND_ARP_INTERVAL]        = { .type = NLA_U32 },
33         [IFLA_BOND_ARP_IP_TARGET]       = { .type = NLA_NESTED },
34         [IFLA_BOND_ARP_VALIDATE]        = { .type = NLA_U32 },
35         [IFLA_BOND_ARP_ALL_TARGETS]     = { .type = NLA_U32 },
36         [IFLA_BOND_PRIMARY]             = { .type = NLA_U32 },
37         [IFLA_BOND_PRIMARY_RESELECT]    = { .type = NLA_U8 },
38         [IFLA_BOND_FAIL_OVER_MAC]       = { .type = NLA_U8 },
39         [IFLA_BOND_XMIT_HASH_POLICY]    = { .type = NLA_U8 },
40         [IFLA_BOND_RESEND_IGMP]         = { .type = NLA_U32 },
41         [IFLA_BOND_NUM_PEER_NOTIF]      = { .type = NLA_U8 },
42         [IFLA_BOND_ALL_SLAVES_ACTIVE]   = { .type = NLA_U8 },
43         [IFLA_BOND_MIN_LINKS]           = { .type = NLA_U32 },
44         [IFLA_BOND_LP_INTERVAL]         = { .type = NLA_U32 },
45         [IFLA_BOND_PACKETS_PER_SLAVE]   = { .type = NLA_U32 },
46 };
47
48 static int bond_validate(struct nlattr *tb[], struct nlattr *data[])
49 {
50         if (tb[IFLA_ADDRESS]) {
51                 if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
52                         return -EINVAL;
53                 if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
54                         return -EADDRNOTAVAIL;
55         }
56         return 0;
57 }
58
59 static int bond_changelink(struct net_device *bond_dev,
60                            struct nlattr *tb[], struct nlattr *data[])
61 {
62         struct bonding *bond = netdev_priv(bond_dev);
63         int miimon = 0;
64         int err;
65
66         if (!data)
67                 return 0;
68
69         if (data[IFLA_BOND_MODE]) {
70                 int mode = nla_get_u8(data[IFLA_BOND_MODE]);
71
72                 err = bond_option_mode_set(bond, mode);
73                 if (err)
74                         return err;
75         }
76         if (data[IFLA_BOND_ACTIVE_SLAVE]) {
77                 int ifindex = nla_get_u32(data[IFLA_BOND_ACTIVE_SLAVE]);
78                 struct net_device *slave_dev;
79
80                 if (ifindex == 0) {
81                         slave_dev = NULL;
82                 } else {
83                         slave_dev = __dev_get_by_index(dev_net(bond_dev),
84                                                        ifindex);
85                         if (!slave_dev)
86                                 return -ENODEV;
87                 }
88                 err = bond_option_active_slave_set(bond, slave_dev);
89                 if (err)
90                         return err;
91         }
92         if (data[IFLA_BOND_MIIMON]) {
93                 miimon = nla_get_u32(data[IFLA_BOND_MIIMON]);
94
95                 err = bond_option_miimon_set(bond, miimon);
96                 if (err)
97                         return err;
98         }
99         if (data[IFLA_BOND_UPDELAY]) {
100                 int updelay = nla_get_u32(data[IFLA_BOND_UPDELAY]);
101
102                 err = bond_option_updelay_set(bond, updelay);
103                 if (err)
104                         return err;
105         }
106         if (data[IFLA_BOND_DOWNDELAY]) {
107                 int downdelay = nla_get_u32(data[IFLA_BOND_DOWNDELAY]);
108
109                 err = bond_option_downdelay_set(bond, downdelay);
110                 if (err)
111                         return err;
112         }
113         if (data[IFLA_BOND_USE_CARRIER]) {
114                 int use_carrier = nla_get_u8(data[IFLA_BOND_USE_CARRIER]);
115
116                 err = bond_option_use_carrier_set(bond, use_carrier);
117                 if (err)
118                         return err;
119         }
120         if (data[IFLA_BOND_ARP_INTERVAL]) {
121                 int arp_interval = nla_get_u32(data[IFLA_BOND_ARP_INTERVAL]);
122
123                 if (arp_interval && miimon) {
124                         pr_err("%s: ARP monitoring cannot be used with MII monitoring.\n",
125                                bond->dev->name);
126                         return -EINVAL;
127                 }
128
129                 err = bond_option_arp_interval_set(bond, arp_interval);
130                 if (err)
131                         return err;
132         }
133         if (data[IFLA_BOND_ARP_IP_TARGET]) {
134                 __be32 targets[BOND_MAX_ARP_TARGETS] = { 0, };
135                 struct nlattr *attr;
136                 int i = 0, rem;
137
138                 nla_for_each_nested(attr, data[IFLA_BOND_ARP_IP_TARGET], rem) {
139                         __be32 target = nla_get_be32(attr);
140                         targets[i++] = target;
141                 }
142
143                 err = bond_option_arp_ip_targets_set(bond, targets, i);
144                 if (err)
145                         return err;
146         }
147         if (data[IFLA_BOND_ARP_VALIDATE]) {
148                 int arp_validate = nla_get_u32(data[IFLA_BOND_ARP_VALIDATE]);
149
150                 if (arp_validate && miimon) {
151                         pr_err("%s: ARP validating cannot be used with MII monitoring.\n",
152                                bond->dev->name);
153                         return -EINVAL;
154                 }
155
156                 err = bond_option_arp_validate_set(bond, arp_validate);
157                 if (err)
158                         return err;
159         }
160         if (data[IFLA_BOND_ARP_ALL_TARGETS]) {
161                 int arp_all_targets =
162                         nla_get_u32(data[IFLA_BOND_ARP_ALL_TARGETS]);
163
164                 err = bond_option_arp_all_targets_set(bond, arp_all_targets);
165                 if (err)
166                         return err;
167         }
168         if (data[IFLA_BOND_PRIMARY]) {
169                 int ifindex = nla_get_u32(data[IFLA_BOND_PRIMARY]);
170                 struct net_device *dev;
171                 char *primary = "";
172
173                 dev = __dev_get_by_index(dev_net(bond_dev), ifindex);
174                 if (dev)
175                         primary = dev->name;
176
177                 err = bond_option_primary_set(bond, primary);
178                 if (err)
179                         return err;
180         }
181         if (data[IFLA_BOND_PRIMARY_RESELECT]) {
182                 int primary_reselect =
183                         nla_get_u8(data[IFLA_BOND_PRIMARY_RESELECT]);
184
185                 err = bond_option_primary_reselect_set(bond, primary_reselect);
186                 if (err)
187                         return err;
188         }
189         if (data[IFLA_BOND_FAIL_OVER_MAC]) {
190                 int fail_over_mac =
191                         nla_get_u8(data[IFLA_BOND_FAIL_OVER_MAC]);
192
193                 err = bond_option_fail_over_mac_set(bond, fail_over_mac);
194                 if (err)
195                         return err;
196         }
197         if (data[IFLA_BOND_XMIT_HASH_POLICY]) {
198                 int xmit_hash_policy =
199                         nla_get_u8(data[IFLA_BOND_XMIT_HASH_POLICY]);
200
201                 err = bond_option_xmit_hash_policy_set(bond, xmit_hash_policy);
202                 if (err)
203                         return err;
204         }
205         if (data[IFLA_BOND_RESEND_IGMP]) {
206                 int resend_igmp =
207                         nla_get_u32(data[IFLA_BOND_RESEND_IGMP]);
208
209                 err = bond_option_resend_igmp_set(bond, resend_igmp);
210                 if (err)
211                         return err;
212         }
213         if (data[IFLA_BOND_NUM_PEER_NOTIF]) {
214                 int num_peer_notif =
215                         nla_get_u8(data[IFLA_BOND_NUM_PEER_NOTIF]);
216
217                 err = bond_option_num_peer_notif_set(bond, num_peer_notif);
218                 if (err)
219                         return err;
220         }
221         if (data[IFLA_BOND_ALL_SLAVES_ACTIVE]) {
222                 int all_slaves_active =
223                         nla_get_u8(data[IFLA_BOND_ALL_SLAVES_ACTIVE]);
224
225                 err = bond_option_all_slaves_active_set(bond,
226                                                         all_slaves_active);
227                 if (err)
228                         return err;
229         }
230         if (data[IFLA_BOND_MIN_LINKS]) {
231                 int min_links =
232                         nla_get_u32(data[IFLA_BOND_MIN_LINKS]);
233
234                 err = bond_option_min_links_set(bond, min_links);
235                 if (err)
236                         return err;
237         }
238         if (data[IFLA_BOND_LP_INTERVAL]) {
239                 int lp_interval =
240                         nla_get_u32(data[IFLA_BOND_LP_INTERVAL]);
241
242                 err = bond_option_lp_interval_set(bond, lp_interval);
243                 if (err)
244                         return err;
245         }
246         if (data[IFLA_BOND_PACKETS_PER_SLAVE]) {
247                 int packets_per_slave =
248                         nla_get_u32(data[IFLA_BOND_PACKETS_PER_SLAVE]);
249
250                 err = bond_option_packets_per_slave_set(bond,
251                                                         packets_per_slave);
252                 if (err)
253                         return err;
254         }
255         return 0;
256 }
257
258 static int bond_newlink(struct net *src_net, struct net_device *bond_dev,
259                         struct nlattr *tb[], struct nlattr *data[])
260 {
261         int err;
262
263         err = bond_changelink(bond_dev, tb, data);
264         if (err < 0)
265                 return err;
266
267         return register_netdevice(bond_dev);
268 }
269
270 static size_t bond_get_size(const struct net_device *bond_dev)
271 {
272         return nla_total_size(sizeof(u8)) +     /* IFLA_BOND_MODE */
273                 nla_total_size(sizeof(u32)) +   /* IFLA_BOND_ACTIVE_SLAVE */
274                 nla_total_size(sizeof(u32)) +   /* IFLA_BOND_MIIMON */
275                 nla_total_size(sizeof(u32)) +   /* IFLA_BOND_UPDELAY */
276                 nla_total_size(sizeof(u32)) +   /* IFLA_BOND_DOWNDELAY */
277                 nla_total_size(sizeof(u8)) +    /* IFLA_BOND_USE_CARRIER */
278                 nla_total_size(sizeof(u32)) +   /* IFLA_BOND_ARP_INTERVAL */
279                                                 /* IFLA_BOND_ARP_IP_TARGET */
280                 nla_total_size(sizeof(u32)) * BOND_MAX_ARP_TARGETS +
281                 nla_total_size(sizeof(u32)) +   /* IFLA_BOND_ARP_VALIDATE */
282                 nla_total_size(sizeof(u32)) +   /* IFLA_BOND_ARP_ALL_TARGETS */
283                 nla_total_size(sizeof(u32)) +   /* IFLA_BOND_PRIMARY */
284                 nla_total_size(sizeof(u8)) +    /* IFLA_BOND_PRIMARY_RESELECT */
285                 nla_total_size(sizeof(u8)) +    /* IFLA_BOND_FAIL_OVER_MAC */
286                 nla_total_size(sizeof(u8)) +    /* IFLA_BOND_XMIT_HASH_POLICY */
287                 nla_total_size(sizeof(u32)) +   /* IFLA_BOND_RESEND_IGMP */
288                 nla_total_size(sizeof(u8)) +    /* IFLA_BOND_NUM_PEER_NOTIF */
289                 nla_total_size(sizeof(u8)) +   /* IFLA_BOND_ALL_SLAVES_ACTIVE */
290                 nla_total_size(sizeof(u32)) +   /* IFLA_BOND_MIN_LINKS */
291                 nla_total_size(sizeof(u32)) +   /* IFLA_BOND_LP_INTERVAL */
292                 nla_total_size(sizeof(u32)) +  /* IFLA_BOND_PACKETS_PER_SLAVE */
293                 0;
294 }
295
296 static int bond_fill_info(struct sk_buff *skb,
297                           const struct net_device *bond_dev)
298 {
299         struct bonding *bond = netdev_priv(bond_dev);
300         struct net_device *slave_dev = bond_option_active_slave_get(bond);
301         struct nlattr *targets;
302         unsigned int packets_per_slave;
303         int i, targets_added;
304
305         if (nla_put_u8(skb, IFLA_BOND_MODE, bond->params.mode))
306                 goto nla_put_failure;
307
308         if (slave_dev &&
309             nla_put_u32(skb, IFLA_BOND_ACTIVE_SLAVE, slave_dev->ifindex))
310                 goto nla_put_failure;
311
312         if (nla_put_u32(skb, IFLA_BOND_MIIMON, bond->params.miimon))
313                 goto nla_put_failure;
314
315         if (nla_put_u32(skb, IFLA_BOND_UPDELAY,
316                         bond->params.updelay * bond->params.miimon))
317                 goto nla_put_failure;
318
319         if (nla_put_u32(skb, IFLA_BOND_DOWNDELAY,
320                         bond->params.downdelay * bond->params.miimon))
321                 goto nla_put_failure;
322
323         if (nla_put_u8(skb, IFLA_BOND_USE_CARRIER, bond->params.use_carrier))
324                 goto nla_put_failure;
325
326         if (nla_put_u32(skb, IFLA_BOND_ARP_INTERVAL, bond->params.arp_interval))
327                 goto nla_put_failure;
328
329         targets = nla_nest_start(skb, IFLA_BOND_ARP_IP_TARGET);
330         if (!targets)
331                 goto nla_put_failure;
332
333         targets_added = 0;
334         for (i = 0; i < BOND_MAX_ARP_TARGETS; i++) {
335                 if (bond->params.arp_targets[i]) {
336                         nla_put_be32(skb, i, bond->params.arp_targets[i]);
337                         targets_added = 1;
338                 }
339         }
340
341         if (targets_added)
342                 nla_nest_end(skb, targets);
343         else
344                 nla_nest_cancel(skb, targets);
345
346         if (nla_put_u32(skb, IFLA_BOND_ARP_VALIDATE, bond->params.arp_validate))
347                 goto nla_put_failure;
348
349         if (nla_put_u32(skb, IFLA_BOND_ARP_ALL_TARGETS,
350                         bond->params.arp_all_targets))
351                 goto nla_put_failure;
352
353         if (bond->primary_slave &&
354             nla_put_u32(skb, IFLA_BOND_PRIMARY,
355                         bond->primary_slave->dev->ifindex))
356                 goto nla_put_failure;
357
358         if (nla_put_u8(skb, IFLA_BOND_PRIMARY_RESELECT,
359                        bond->params.primary_reselect))
360                 goto nla_put_failure;
361
362         if (nla_put_u8(skb, IFLA_BOND_FAIL_OVER_MAC,
363                        bond->params.fail_over_mac))
364                 goto nla_put_failure;
365
366         if (nla_put_u8(skb, IFLA_BOND_XMIT_HASH_POLICY,
367                        bond->params.xmit_policy))
368                 goto nla_put_failure;
369
370         if (nla_put_u32(skb, IFLA_BOND_RESEND_IGMP,
371                         bond->params.resend_igmp))
372                 goto nla_put_failure;
373
374         if (nla_put_u8(skb, IFLA_BOND_NUM_PEER_NOTIF,
375                        bond->params.num_peer_notif))
376                 goto nla_put_failure;
377
378         if (nla_put_u8(skb, IFLA_BOND_ALL_SLAVES_ACTIVE,
379                        bond->params.all_slaves_active))
380                 goto nla_put_failure;
381
382         if (nla_put_u32(skb, IFLA_BOND_MIN_LINKS,
383                         bond->params.min_links))
384                 goto nla_put_failure;
385
386         if (nla_put_u32(skb, IFLA_BOND_LP_INTERVAL,
387                         bond->params.lp_interval))
388                 goto nla_put_failure;
389
390         packets_per_slave = bond->params.packets_per_slave;
391         if (packets_per_slave > 1)
392                 packets_per_slave = reciprocal_value(packets_per_slave);
393
394         if (nla_put_u32(skb, IFLA_BOND_PACKETS_PER_SLAVE,
395                         packets_per_slave))
396                 goto nla_put_failure;
397
398         return 0;
399
400 nla_put_failure:
401         return -EMSGSIZE;
402 }
403
404 struct rtnl_link_ops bond_link_ops __read_mostly = {
405         .kind                   = "bond",
406         .priv_size              = sizeof(struct bonding),
407         .setup                  = bond_setup,
408         .maxtype                = IFLA_BOND_MAX,
409         .policy                 = bond_policy,
410         .validate               = bond_validate,
411         .newlink                = bond_newlink,
412         .changelink             = bond_changelink,
413         .get_size               = bond_get_size,
414         .fill_info              = bond_fill_info,
415         .get_num_tx_queues      = bond_get_num_tx_queues,
416         .get_num_rx_queues      = bond_get_num_tx_queues, /* Use the same number
417                                                              as for TX queues */
418 };
419
420 int __init bond_netlink_init(void)
421 {
422         return rtnl_link_register(&bond_link_ops);
423 }
424
425 void bond_netlink_fini(void)
426 {
427         rtnl_link_unregister(&bond_link_ops);
428 }
429
430 MODULE_ALIAS_RTNL_LINK("bond");