blob: df66dd8c08b56e40c46cbb9d1fd4dc4e3bc12f5d [file] [log] [blame]
Jiri Pirko0a2a78c2013-10-18 17:43:33 +02001/*
2 * drivers/net/bond/bond_netlink.c - Netlink interface for bonding
3 * Copyright (c) 2013 Jiri Pirko <jiri@resnulli.us>
sfeldma@cumulusnetworks.comeecdaa62013-12-12 14:09:55 -08004 * Copyright (c) 2013 Scott Feldman <sfeldma@cumulusnetworks.com>
Jiri Pirko0a2a78c2013-10-18 17:43:33 +02005 *
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>
sfeldma@cumulusnetworks.comc13ab3f2013-12-17 21:30:37 -080022#include <linux/reciprocal_div.h>
Jiri Pirko0a2a78c2013-10-18 17:43:33 +020023#include "bonding.h"
24
Jiri Pirko90af2312013-10-18 17:43:38 +020025static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = {
26 [IFLA_BOND_MODE] = { .type = NLA_U8 },
Jiri Pirkoec76aa42013-10-18 17:43:39 +020027 [IFLA_BOND_ACTIVE_SLAVE] = { .type = NLA_U32 },
sfeldma@cumulusnetworks.comeecdaa62013-12-12 14:09:55 -080028 [IFLA_BOND_MIIMON] = { .type = NLA_U32 },
sfeldma@cumulusnetworks.com25852e22013-12-12 14:10:02 -080029 [IFLA_BOND_UPDELAY] = { .type = NLA_U32 },
sfeldma@cumulusnetworks.comc7461f92013-12-12 14:10:09 -080030 [IFLA_BOND_DOWNDELAY] = { .type = NLA_U32 },
sfeldma@cumulusnetworks.com9f53e142013-12-12 14:10:16 -080031 [IFLA_BOND_USE_CARRIER] = { .type = NLA_U8 },
sfeldma@cumulusnetworks.com06151db2013-12-12 14:10:24 -080032 [IFLA_BOND_ARP_INTERVAL] = { .type = NLA_U32 },
sfeldma@cumulusnetworks.com7f28fa12013-12-12 14:10:31 -080033 [IFLA_BOND_ARP_IP_TARGET] = { .type = NLA_NESTED },
sfeldma@cumulusnetworks.com29c49482013-12-12 14:10:38 -080034 [IFLA_BOND_ARP_VALIDATE] = { .type = NLA_U32 },
sfeldma@cumulusnetworks.comd5c84252013-12-12 14:10:45 -080035 [IFLA_BOND_ARP_ALL_TARGETS] = { .type = NLA_U32 },
sfeldma@cumulusnetworks.com0a98a0d2013-12-15 16:41:51 -080036 [IFLA_BOND_PRIMARY] = { .type = NLA_U32 },
sfeldma@cumulusnetworks.com8a41ae42013-12-15 16:41:58 -080037 [IFLA_BOND_PRIMARY_RESELECT] = { .type = NLA_U8 },
sfeldma@cumulusnetworks.com89901972013-12-15 16:42:05 -080038 [IFLA_BOND_FAIL_OVER_MAC] = { .type = NLA_U8 },
sfeldma@cumulusnetworks.comf70161c2013-12-15 16:42:12 -080039 [IFLA_BOND_XMIT_HASH_POLICY] = { .type = NLA_U8 },
sfeldma@cumulusnetworks.comd8838de72013-12-15 16:42:19 -080040 [IFLA_BOND_RESEND_IGMP] = { .type = NLA_U32 },
sfeldma@cumulusnetworks.com2c9839c2013-12-17 21:30:09 -080041 [IFLA_BOND_NUM_PEER_NOTIF] = { .type = NLA_U8 },
sfeldma@cumulusnetworks.com1cc0b1e2013-12-17 21:30:16 -080042 [IFLA_BOND_ALL_SLAVES_ACTIVE] = { .type = NLA_U8 },
sfeldma@cumulusnetworks.com7d101002013-12-17 21:30:23 -080043 [IFLA_BOND_MIN_LINKS] = { .type = NLA_U32 },
sfeldma@cumulusnetworks.com8d836d02013-12-17 21:30:30 -080044 [IFLA_BOND_LP_INTERVAL] = { .type = NLA_U32 },
sfeldma@cumulusnetworks.comc13ab3f2013-12-17 21:30:37 -080045 [IFLA_BOND_PACKETS_PER_SLAVE] = { .type = NLA_U32 },
sfeldma@cumulusnetworks.com998e40bb2014-01-03 14:18:41 -080046 [IFLA_BOND_AD_LACP_RATE] = { .type = NLA_U8 },
sfeldma@cumulusnetworks.comec029fa2014-01-03 14:18:49 -080047 [IFLA_BOND_AD_SELECT] = { .type = NLA_U8 },
Jiri Pirko90af2312013-10-18 17:43:38 +020048};
49
Jiri Pirko0a2a78c2013-10-18 17:43:33 +020050static int bond_validate(struct nlattr *tb[], struct nlattr *data[])
51{
52 if (tb[IFLA_ADDRESS]) {
53 if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
54 return -EINVAL;
55 if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
56 return -EADDRNOTAVAIL;
57 }
58 return 0;
59}
60
Jiri Pirko90af2312013-10-18 17:43:38 +020061static int bond_changelink(struct net_device *bond_dev,
62 struct nlattr *tb[], struct nlattr *data[])
63{
64 struct bonding *bond = netdev_priv(bond_dev);
sfeldma@cumulusnetworks.com06151db2013-12-12 14:10:24 -080065 int miimon = 0;
Jiri Pirko90af2312013-10-18 17:43:38 +020066 int err;
67
sfeldma@cumulusnetworks.comeecdaa62013-12-12 14:09:55 -080068 if (!data)
69 return 0;
70
71 if (data[IFLA_BOND_MODE]) {
Jiri Pirko90af2312013-10-18 17:43:38 +020072 int mode = nla_get_u8(data[IFLA_BOND_MODE]);
73
74 err = bond_option_mode_set(bond, mode);
75 if (err)
76 return err;
77 }
sfeldma@cumulusnetworks.comeecdaa62013-12-12 14:09:55 -080078 if (data[IFLA_BOND_ACTIVE_SLAVE]) {
Jiri Pirkoec76aa42013-10-18 17:43:39 +020079 int ifindex = nla_get_u32(data[IFLA_BOND_ACTIVE_SLAVE]);
80 struct net_device *slave_dev;
81
82 if (ifindex == 0) {
83 slave_dev = NULL;
84 } else {
85 slave_dev = __dev_get_by_index(dev_net(bond_dev),
86 ifindex);
87 if (!slave_dev)
88 return -ENODEV;
89 }
90 err = bond_option_active_slave_set(bond, slave_dev);
91 if (err)
92 return err;
93 }
sfeldma@cumulusnetworks.comeecdaa62013-12-12 14:09:55 -080094 if (data[IFLA_BOND_MIIMON]) {
sfeldma@cumulusnetworks.com06151db2013-12-12 14:10:24 -080095 miimon = nla_get_u32(data[IFLA_BOND_MIIMON]);
sfeldma@cumulusnetworks.comeecdaa62013-12-12 14:09:55 -080096
97 err = bond_option_miimon_set(bond, miimon);
98 if (err)
99 return err;
100 }
sfeldma@cumulusnetworks.com25852e22013-12-12 14:10:02 -0800101 if (data[IFLA_BOND_UPDELAY]) {
102 int updelay = nla_get_u32(data[IFLA_BOND_UPDELAY]);
103
104 err = bond_option_updelay_set(bond, updelay);
105 if (err)
106 return err;
107 }
sfeldma@cumulusnetworks.comc7461f92013-12-12 14:10:09 -0800108 if (data[IFLA_BOND_DOWNDELAY]) {
109 int downdelay = nla_get_u32(data[IFLA_BOND_DOWNDELAY]);
110
111 err = bond_option_downdelay_set(bond, downdelay);
112 if (err)
113 return err;
114 }
sfeldma@cumulusnetworks.com9f53e142013-12-12 14:10:16 -0800115 if (data[IFLA_BOND_USE_CARRIER]) {
116 int use_carrier = nla_get_u8(data[IFLA_BOND_USE_CARRIER]);
117
118 err = bond_option_use_carrier_set(bond, use_carrier);
119 if (err)
120 return err;
121 }
sfeldma@cumulusnetworks.com06151db2013-12-12 14:10:24 -0800122 if (data[IFLA_BOND_ARP_INTERVAL]) {
123 int arp_interval = nla_get_u32(data[IFLA_BOND_ARP_INTERVAL]);
124
125 if (arp_interval && miimon) {
126 pr_err("%s: ARP monitoring cannot be used with MII monitoring.\n",
127 bond->dev->name);
128 return -EINVAL;
129 }
130
131 err = bond_option_arp_interval_set(bond, arp_interval);
132 if (err)
133 return err;
134 }
sfeldma@cumulusnetworks.com7f28fa12013-12-12 14:10:31 -0800135 if (data[IFLA_BOND_ARP_IP_TARGET]) {
136 __be32 targets[BOND_MAX_ARP_TARGETS] = { 0, };
137 struct nlattr *attr;
138 int i = 0, rem;
139
140 nla_for_each_nested(attr, data[IFLA_BOND_ARP_IP_TARGET], rem) {
Jiri Pirkoe7ef9412013-12-14 12:32:10 +0100141 __be32 target = nla_get_be32(attr);
sfeldma@cumulusnetworks.com7f28fa12013-12-12 14:10:31 -0800142 targets[i++] = target;
143 }
144
145 err = bond_option_arp_ip_targets_set(bond, targets, i);
146 if (err)
147 return err;
148 }
sfeldma@cumulusnetworks.com29c49482013-12-12 14:10:38 -0800149 if (data[IFLA_BOND_ARP_VALIDATE]) {
150 int arp_validate = nla_get_u32(data[IFLA_BOND_ARP_VALIDATE]);
151
152 if (arp_validate && miimon) {
153 pr_err("%s: ARP validating cannot be used with MII monitoring.\n",
154 bond->dev->name);
155 return -EINVAL;
156 }
157
158 err = bond_option_arp_validate_set(bond, arp_validate);
159 if (err)
160 return err;
161 }
sfeldma@cumulusnetworks.comd5c84252013-12-12 14:10:45 -0800162 if (data[IFLA_BOND_ARP_ALL_TARGETS]) {
163 int arp_all_targets =
164 nla_get_u32(data[IFLA_BOND_ARP_ALL_TARGETS]);
165
166 err = bond_option_arp_all_targets_set(bond, arp_all_targets);
167 if (err)
168 return err;
169 }
sfeldma@cumulusnetworks.com0a98a0d2013-12-15 16:41:51 -0800170 if (data[IFLA_BOND_PRIMARY]) {
171 int ifindex = nla_get_u32(data[IFLA_BOND_PRIMARY]);
172 struct net_device *dev;
173 char *primary = "";
174
175 dev = __dev_get_by_index(dev_net(bond_dev), ifindex);
176 if (dev)
177 primary = dev->name;
178
179 err = bond_option_primary_set(bond, primary);
180 if (err)
181 return err;
182 }
sfeldma@cumulusnetworks.com8a41ae42013-12-15 16:41:58 -0800183 if (data[IFLA_BOND_PRIMARY_RESELECT]) {
184 int primary_reselect =
185 nla_get_u8(data[IFLA_BOND_PRIMARY_RESELECT]);
186
187 err = bond_option_primary_reselect_set(bond, primary_reselect);
188 if (err)
189 return err;
190 }
sfeldma@cumulusnetworks.com89901972013-12-15 16:42:05 -0800191 if (data[IFLA_BOND_FAIL_OVER_MAC]) {
192 int fail_over_mac =
193 nla_get_u8(data[IFLA_BOND_FAIL_OVER_MAC]);
194
195 err = bond_option_fail_over_mac_set(bond, fail_over_mac);
196 if (err)
197 return err;
198 }
sfeldma@cumulusnetworks.comf70161c2013-12-15 16:42:12 -0800199 if (data[IFLA_BOND_XMIT_HASH_POLICY]) {
200 int xmit_hash_policy =
201 nla_get_u8(data[IFLA_BOND_XMIT_HASH_POLICY]);
202
203 err = bond_option_xmit_hash_policy_set(bond, xmit_hash_policy);
204 if (err)
205 return err;
206 }
sfeldma@cumulusnetworks.comd8838de72013-12-15 16:42:19 -0800207 if (data[IFLA_BOND_RESEND_IGMP]) {
208 int resend_igmp =
209 nla_get_u32(data[IFLA_BOND_RESEND_IGMP]);
210
211 err = bond_option_resend_igmp_set(bond, resend_igmp);
212 if (err)
213 return err;
214 }
sfeldma@cumulusnetworks.com2c9839c2013-12-17 21:30:09 -0800215 if (data[IFLA_BOND_NUM_PEER_NOTIF]) {
216 int num_peer_notif =
217 nla_get_u8(data[IFLA_BOND_NUM_PEER_NOTIF]);
218
219 err = bond_option_num_peer_notif_set(bond, num_peer_notif);
220 if (err)
221 return err;
222 }
sfeldma@cumulusnetworks.com1cc0b1e2013-12-17 21:30:16 -0800223 if (data[IFLA_BOND_ALL_SLAVES_ACTIVE]) {
224 int all_slaves_active =
225 nla_get_u8(data[IFLA_BOND_ALL_SLAVES_ACTIVE]);
226
227 err = bond_option_all_slaves_active_set(bond,
228 all_slaves_active);
229 if (err)
230 return err;
231 }
sfeldma@cumulusnetworks.com7d101002013-12-17 21:30:23 -0800232 if (data[IFLA_BOND_MIN_LINKS]) {
233 int min_links =
234 nla_get_u32(data[IFLA_BOND_MIN_LINKS]);
235
236 err = bond_option_min_links_set(bond, min_links);
237 if (err)
238 return err;
239 }
sfeldma@cumulusnetworks.com8d836d02013-12-17 21:30:30 -0800240 if (data[IFLA_BOND_LP_INTERVAL]) {
241 int lp_interval =
242 nla_get_u32(data[IFLA_BOND_LP_INTERVAL]);
243
244 err = bond_option_lp_interval_set(bond, lp_interval);
245 if (err)
246 return err;
247 }
sfeldma@cumulusnetworks.comc13ab3f2013-12-17 21:30:37 -0800248 if (data[IFLA_BOND_PACKETS_PER_SLAVE]) {
249 int packets_per_slave =
250 nla_get_u32(data[IFLA_BOND_PACKETS_PER_SLAVE]);
251
252 err = bond_option_packets_per_slave_set(bond,
253 packets_per_slave);
254 if (err)
255 return err;
256 }
sfeldma@cumulusnetworks.com998e40bb2014-01-03 14:18:41 -0800257 if (data[IFLA_BOND_AD_LACP_RATE]) {
258 int lacp_rate =
259 nla_get_u8(data[IFLA_BOND_AD_LACP_RATE]);
260
261 err = bond_option_lacp_rate_set(bond, lacp_rate);
262 if (err)
263 return err;
264 }
sfeldma@cumulusnetworks.comec029fa2014-01-03 14:18:49 -0800265 if (data[IFLA_BOND_AD_SELECT]) {
266 int ad_select =
267 nla_get_u8(data[IFLA_BOND_AD_SELECT]);
268
269 err = bond_option_ad_select_set(bond, ad_select);
270 if (err)
271 return err;
272 }
Jiri Pirko90af2312013-10-18 17:43:38 +0200273 return 0;
274}
275
276static int bond_newlink(struct net *src_net, struct net_device *bond_dev,
277 struct nlattr *tb[], struct nlattr *data[])
278{
279 int err;
280
281 err = bond_changelink(bond_dev, tb, data);
282 if (err < 0)
283 return err;
284
285 return register_netdevice(bond_dev);
286}
287
288static size_t bond_get_size(const struct net_device *bond_dev)
289{
Dan Carpentere1398622013-11-01 13:18:44 +0300290 return nla_total_size(sizeof(u8)) + /* IFLA_BOND_MODE */
sfeldma@cumulusnetworks.comeecdaa62013-12-12 14:09:55 -0800291 nla_total_size(sizeof(u32)) + /* IFLA_BOND_ACTIVE_SLAVE */
292 nla_total_size(sizeof(u32)) + /* IFLA_BOND_MIIMON */
sfeldma@cumulusnetworks.com25852e22013-12-12 14:10:02 -0800293 nla_total_size(sizeof(u32)) + /* IFLA_BOND_UPDELAY */
sfeldma@cumulusnetworks.comc7461f92013-12-12 14:10:09 -0800294 nla_total_size(sizeof(u32)) + /* IFLA_BOND_DOWNDELAY */
sfeldma@cumulusnetworks.com9f53e142013-12-12 14:10:16 -0800295 nla_total_size(sizeof(u8)) + /* IFLA_BOND_USE_CARRIER */
sfeldma@cumulusnetworks.com06151db2013-12-12 14:10:24 -0800296 nla_total_size(sizeof(u32)) + /* IFLA_BOND_ARP_INTERVAL */
sfeldma@cumulusnetworks.com7f28fa12013-12-12 14:10:31 -0800297 /* IFLA_BOND_ARP_IP_TARGET */
298 nla_total_size(sizeof(u32)) * BOND_MAX_ARP_TARGETS +
sfeldma@cumulusnetworks.com29c49482013-12-12 14:10:38 -0800299 nla_total_size(sizeof(u32)) + /* IFLA_BOND_ARP_VALIDATE */
sfeldma@cumulusnetworks.comd5c84252013-12-12 14:10:45 -0800300 nla_total_size(sizeof(u32)) + /* IFLA_BOND_ARP_ALL_TARGETS */
sfeldma@cumulusnetworks.com0a98a0d2013-12-15 16:41:51 -0800301 nla_total_size(sizeof(u32)) + /* IFLA_BOND_PRIMARY */
sfeldma@cumulusnetworks.com8a41ae42013-12-15 16:41:58 -0800302 nla_total_size(sizeof(u8)) + /* IFLA_BOND_PRIMARY_RESELECT */
sfeldma@cumulusnetworks.com89901972013-12-15 16:42:05 -0800303 nla_total_size(sizeof(u8)) + /* IFLA_BOND_FAIL_OVER_MAC */
sfeldma@cumulusnetworks.comf70161c2013-12-15 16:42:12 -0800304 nla_total_size(sizeof(u8)) + /* IFLA_BOND_XMIT_HASH_POLICY */
sfeldma@cumulusnetworks.comd8838de72013-12-15 16:42:19 -0800305 nla_total_size(sizeof(u32)) + /* IFLA_BOND_RESEND_IGMP */
sfeldma@cumulusnetworks.com2c9839c2013-12-17 21:30:09 -0800306 nla_total_size(sizeof(u8)) + /* IFLA_BOND_NUM_PEER_NOTIF */
sfeldma@cumulusnetworks.com1cc0b1e2013-12-17 21:30:16 -0800307 nla_total_size(sizeof(u8)) + /* IFLA_BOND_ALL_SLAVES_ACTIVE */
sfeldma@cumulusnetworks.com7d101002013-12-17 21:30:23 -0800308 nla_total_size(sizeof(u32)) + /* IFLA_BOND_MIN_LINKS */
sfeldma@cumulusnetworks.com8d836d02013-12-17 21:30:30 -0800309 nla_total_size(sizeof(u32)) + /* IFLA_BOND_LP_INTERVAL */
sfeldma@cumulusnetworks.comc13ab3f2013-12-17 21:30:37 -0800310 nla_total_size(sizeof(u32)) + /* IFLA_BOND_PACKETS_PER_SLAVE */
sfeldma@cumulusnetworks.com998e40bb2014-01-03 14:18:41 -0800311 nla_total_size(sizeof(u8)) + /* IFLA_BOND_AD_LACP_RATE */
sfeldma@cumulusnetworks.comec029fa2014-01-03 14:18:49 -0800312 nla_total_size(sizeof(u8)) + /* IFLA_BOND_AD_SELECT */
sfeldma@cumulusnetworks.comeecdaa62013-12-12 14:09:55 -0800313 0;
Jiri Pirko90af2312013-10-18 17:43:38 +0200314}
315
316static int bond_fill_info(struct sk_buff *skb,
317 const struct net_device *bond_dev)
318{
319 struct bonding *bond = netdev_priv(bond_dev);
Jiri Pirkoec76aa42013-10-18 17:43:39 +0200320 struct net_device *slave_dev = bond_option_active_slave_get(bond);
sfeldma@cumulusnetworks.com7f28fa12013-12-12 14:10:31 -0800321 struct nlattr *targets;
sfeldma@cumulusnetworks.comc13ab3f2013-12-17 21:30:37 -0800322 unsigned int packets_per_slave;
sfeldma@cumulusnetworks.com7f28fa12013-12-12 14:10:31 -0800323 int i, targets_added;
Jiri Pirko90af2312013-10-18 17:43:38 +0200324
sfeldma@cumulusnetworks.comeecdaa62013-12-12 14:09:55 -0800325 if (nla_put_u8(skb, IFLA_BOND_MODE, bond->params.mode))
Jiri Pirko90af2312013-10-18 17:43:38 +0200326 goto nla_put_failure;
sfeldma@cumulusnetworks.comeecdaa62013-12-12 14:09:55 -0800327
328 if (slave_dev &&
329 nla_put_u32(skb, IFLA_BOND_ACTIVE_SLAVE, slave_dev->ifindex))
330 goto nla_put_failure;
331
332 if (nla_put_u32(skb, IFLA_BOND_MIIMON, bond->params.miimon))
333 goto nla_put_failure;
334
sfeldma@cumulusnetworks.com25852e22013-12-12 14:10:02 -0800335 if (nla_put_u32(skb, IFLA_BOND_UPDELAY,
336 bond->params.updelay * bond->params.miimon))
337 goto nla_put_failure;
338
sfeldma@cumulusnetworks.comc7461f92013-12-12 14:10:09 -0800339 if (nla_put_u32(skb, IFLA_BOND_DOWNDELAY,
340 bond->params.downdelay * bond->params.miimon))
341 goto nla_put_failure;
342
sfeldma@cumulusnetworks.com9f53e142013-12-12 14:10:16 -0800343 if (nla_put_u8(skb, IFLA_BOND_USE_CARRIER, bond->params.use_carrier))
344 goto nla_put_failure;
345
sfeldma@cumulusnetworks.com06151db2013-12-12 14:10:24 -0800346 if (nla_put_u32(skb, IFLA_BOND_ARP_INTERVAL, bond->params.arp_interval))
347 goto nla_put_failure;
348
sfeldma@cumulusnetworks.com7f28fa12013-12-12 14:10:31 -0800349 targets = nla_nest_start(skb, IFLA_BOND_ARP_IP_TARGET);
350 if (!targets)
351 goto nla_put_failure;
352
353 targets_added = 0;
354 for (i = 0; i < BOND_MAX_ARP_TARGETS; i++) {
355 if (bond->params.arp_targets[i]) {
Jiri Pirkoe7ef9412013-12-14 12:32:10 +0100356 nla_put_be32(skb, i, bond->params.arp_targets[i]);
sfeldma@cumulusnetworks.com7f28fa12013-12-12 14:10:31 -0800357 targets_added = 1;
358 }
359 }
360
361 if (targets_added)
362 nla_nest_end(skb, targets);
363 else
364 nla_nest_cancel(skb, targets);
365
sfeldma@cumulusnetworks.com29c49482013-12-12 14:10:38 -0800366 if (nla_put_u32(skb, IFLA_BOND_ARP_VALIDATE, bond->params.arp_validate))
367 goto nla_put_failure;
368
sfeldma@cumulusnetworks.comd5c84252013-12-12 14:10:45 -0800369 if (nla_put_u32(skb, IFLA_BOND_ARP_ALL_TARGETS,
370 bond->params.arp_all_targets))
371 goto nla_put_failure;
372
sfeldma@cumulusnetworks.com0a98a0d2013-12-15 16:41:51 -0800373 if (bond->primary_slave &&
374 nla_put_u32(skb, IFLA_BOND_PRIMARY,
375 bond->primary_slave->dev->ifindex))
376 goto nla_put_failure;
377
sfeldma@cumulusnetworks.com8a41ae42013-12-15 16:41:58 -0800378 if (nla_put_u8(skb, IFLA_BOND_PRIMARY_RESELECT,
379 bond->params.primary_reselect))
380 goto nla_put_failure;
381
sfeldma@cumulusnetworks.com89901972013-12-15 16:42:05 -0800382 if (nla_put_u8(skb, IFLA_BOND_FAIL_OVER_MAC,
383 bond->params.fail_over_mac))
384 goto nla_put_failure;
385
sfeldma@cumulusnetworks.comf70161c2013-12-15 16:42:12 -0800386 if (nla_put_u8(skb, IFLA_BOND_XMIT_HASH_POLICY,
387 bond->params.xmit_policy))
388 goto nla_put_failure;
389
sfeldma@cumulusnetworks.comd8838de72013-12-15 16:42:19 -0800390 if (nla_put_u32(skb, IFLA_BOND_RESEND_IGMP,
391 bond->params.resend_igmp))
392 goto nla_put_failure;
393
sfeldma@cumulusnetworks.com2c9839c2013-12-17 21:30:09 -0800394 if (nla_put_u8(skb, IFLA_BOND_NUM_PEER_NOTIF,
395 bond->params.num_peer_notif))
396 goto nla_put_failure;
397
sfeldma@cumulusnetworks.com1cc0b1e2013-12-17 21:30:16 -0800398 if (nla_put_u8(skb, IFLA_BOND_ALL_SLAVES_ACTIVE,
399 bond->params.all_slaves_active))
400 goto nla_put_failure;
401
sfeldma@cumulusnetworks.com7d101002013-12-17 21:30:23 -0800402 if (nla_put_u32(skb, IFLA_BOND_MIN_LINKS,
403 bond->params.min_links))
404 goto nla_put_failure;
405
sfeldma@cumulusnetworks.com8d836d02013-12-17 21:30:30 -0800406 if (nla_put_u32(skb, IFLA_BOND_LP_INTERVAL,
407 bond->params.lp_interval))
408 goto nla_put_failure;
409
sfeldma@cumulusnetworks.comc13ab3f2013-12-17 21:30:37 -0800410 packets_per_slave = bond->params.packets_per_slave;
411 if (packets_per_slave > 1)
412 packets_per_slave = reciprocal_value(packets_per_slave);
413
414 if (nla_put_u32(skb, IFLA_BOND_PACKETS_PER_SLAVE,
415 packets_per_slave))
416 goto nla_put_failure;
417
sfeldma@cumulusnetworks.com998e40bb2014-01-03 14:18:41 -0800418 if (nla_put_u8(skb, IFLA_BOND_AD_LACP_RATE,
419 bond->params.lacp_fast))
420 goto nla_put_failure;
421
sfeldma@cumulusnetworks.comec029fa2014-01-03 14:18:49 -0800422 if (nla_put_u8(skb, IFLA_BOND_AD_SELECT,
423 bond->params.ad_select))
424 goto nla_put_failure;
425
Jiri Pirko90af2312013-10-18 17:43:38 +0200426 return 0;
427
428nla_put_failure:
429 return -EMSGSIZE;
430}
431
Jiri Pirko0a2a78c2013-10-18 17:43:33 +0200432struct rtnl_link_ops bond_link_ops __read_mostly = {
433 .kind = "bond",
434 .priv_size = sizeof(struct bonding),
435 .setup = bond_setup,
Jiri Pirko90af2312013-10-18 17:43:38 +0200436 .maxtype = IFLA_BOND_MAX,
437 .policy = bond_policy,
Jiri Pirko0a2a78c2013-10-18 17:43:33 +0200438 .validate = bond_validate,
Jiri Pirko90af2312013-10-18 17:43:38 +0200439 .newlink = bond_newlink,
440 .changelink = bond_changelink,
441 .get_size = bond_get_size,
442 .fill_info = bond_fill_info,
Jiri Pirko0a2a78c2013-10-18 17:43:33 +0200443 .get_num_tx_queues = bond_get_num_tx_queues,
444 .get_num_rx_queues = bond_get_num_tx_queues, /* Use the same number
445 as for TX queues */
446};
447
448int __init bond_netlink_init(void)
449{
450 return rtnl_link_register(&bond_link_ops);
451}
452
David S. Millera729e832013-10-19 19:09:18 -0400453void bond_netlink_fini(void)
Jiri Pirko0a2a78c2013-10-18 17:43:33 +0200454{
455 rtnl_link_unregister(&bond_link_ops);
456}
457
458MODULE_ALIAS_RTNL_LINK("bond");