History

bonding: add miimon netlink support

Add IFLA_BOND_MIIMON to allow get/set of bonding parameter miimon via netlink.

sfeldma@cumulusnetworks.com committed 12 years ago

Commit eecdaa61 parent 1cbac015 files · +80 −49Browse files

Unified · Split

5 files
  1. drivers/net/bonding/bond_netlink.c +26 −6
  2. drivers/net/bonding/bond_options.c +42 −0
  3. drivers/net/bonding/bond_sysfs.c +10 −43
  4. drivers/net/bonding/bonding.h +1 −0
  5. include/uapi/linux/if_link.h +1 −0
drivers/net/bonding/bond_netlink.c+26−6
@@ -1,6 +1,7 @@
11 /*
22 * drivers/net/bond/bond_netlink.c - Netlink interface for bonding
33 * Copyright (c) 2013 Jiri Pirko <jiri@resnulli.us>
4+ * Copyright (c) 2013 Scott Feldman <sfeldma@cumulusnetworks.com>
45 *
56 * This program is free software; you can redistribute it and/or modify
67 * it under the terms of the GNU General Public License as published by
@@ -23,6 +24,7 @@ · 16 unmodified lines
2324 static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = {
2425 [IFLA_BOND_MODE] = { .type = NLA_U8 },
2526 [IFLA_BOND_ACTIVE_SLAVE] = { .type = NLA_U32 },
27+ [IFLA_BOND_MIIMON] = { .type = NLA_U32 },
2628 };
2729
2830 static int bond_validate(struct nlattr *tb[], struct nlattr *data[])
@@ -42,14 +44,17 @@ static int bond_changelink(struct net_device *bond_dev, · 13 unmodified lines
4244 struct bonding *bond = netdev_priv(bond_dev);
4345 int err;
4446
45− if (data && data[IFLA_BOND_MODE]) {
47+ if (!data)
48+ return 0;
49+
50+ if (data[IFLA_BOND_MODE]) {
4651 int mode = nla_get_u8(data[IFLA_BOND_MODE]);
4752
4853 err = bond_option_mode_set(bond, mode);
4954 if (err)
5055 return err;
5156 }
52− if (data && data[IFLA_BOND_ACTIVE_SLAVE]) {
57+ if (data[IFLA_BOND_ACTIVE_SLAVE]) {
5358 int ifindex = nla_get_u32(data[IFLA_BOND_ACTIVE_SLAVE]);
5459 struct net_device *slave_dev;
5560
@@ -65,6 +70,13 @@ static int bond_changelink(struct net_device *bond_dev, · 9 unmodified lines
6570 if (err)
6671 return err;
6772 }
73+ if (data[IFLA_BOND_MIIMON]) {
74+ int miimon = nla_get_u32(data[IFLA_BOND_MIIMON]);
75+
76+ err = bond_option_miimon_set(bond, miimon);
77+ if (err)
78+ return err;
79+ }
6880 return 0;
6981 }
7082
@@ -83,7 +95,9 @@ static int bond_newlink(struct net *src_net, struct net_device *bond_dev, · 12 unmodified lines
8395 static size_t bond_get_size(const struct net_device *bond_dev)
8496 {
8597 return nla_total_size(sizeof(u8)) + /* IFLA_BOND_MODE */
86− nla_total_size(sizeof(u32)); /* IFLA_BOND_ACTIVE_SLAVE */
98+ nla_total_size(sizeof(u32)) + /* IFLA_BOND_ACTIVE_SLAVE */
99+ nla_total_size(sizeof(u32)) + /* IFLA_BOND_MIIMON */
100+ 0;
87101 }
88102
89103 static int bond_fill_info(struct sk_buff *skb,
@@ -92,10 +106,16 @@ static int bond_fill_info(struct sk_buff *skb, · 2 unmodified lines
92106 struct bonding *bond = netdev_priv(bond_dev);
93107 struct net_device *slave_dev = bond_option_active_slave_get(bond);
94108
95− if (nla_put_u8(skb, IFLA_BOND_MODE, bond->params.mode) ||
96− (slave_dev &&
97− nla_put_u32(skb, IFLA_BOND_ACTIVE_SLAVE, slave_dev->ifindex)))
109+ if (nla_put_u8(skb, IFLA_BOND_MODE, bond->params.mode))
98110 goto nla_put_failure;
111+
112+ if (slave_dev &&
113+ nla_put_u32(skb, IFLA_BOND_ACTIVE_SLAVE, slave_dev->ifindex))
114+ goto nla_put_failure;
115+
116+ if (nla_put_u32(skb, IFLA_BOND_MIIMON, bond->params.miimon))
117+ goto nla_put_failure;
118+
99119 return 0;
100120
101121 nla_put_failure:
drivers/net/bonding/bond_options.c+42−0
@@ -1,6 +1,7 @@
11 /*
22 * drivers/net/bond/bond_options.c - bonding options
33 * Copyright (c) 2013 Jiri Pirko <jiri@resnulli.us>
4+ * Copyright (c) 2013 Scott Feldman <sfeldma@cumulusnetworks.com>
45 *
56 * This program is free software; you can redistribute it and/or modify
67 * it under the terms of the GNU General Public License as published by
@@ -145,3 +146,44 @@ int bond_option_active_slave_set(struct bonding *bond, · 138 unmodified lines
145146 unblock_netpoll_tx();
146147 return ret;
147148 }
149+
150+int bond_option_miimon_set(struct bonding *bond, int miimon)
151+{
152+ if (miimon < 0) {
153+ pr_err("%s: Invalid miimon value %d not in range %d-%d; rejected.\n",
154+ bond->dev->name, miimon, 0, INT_MAX);
155+ return -EINVAL;
156+ }
157+ pr_info("%s: Setting MII monitoring interval to %d.\n",
158+ bond->dev->name, miimon);
159+ bond->params.miimon = miimon;
160+ if (bond->params.updelay)
161+ pr_info("%s: Note: Updating updelay (to %d) since it is a multiple of the miimon value.\n",
162+ bond->dev->name,
163+ bond->params.updelay * bond->params.miimon);
164+ if (bond->params.downdelay)
165+ pr_info("%s: Note: Updating downdelay (to %d) since it is a multiple of the miimon value.\n",
166+ bond->dev->name,
167+ bond->params.downdelay * bond->params.miimon);
168+ if (miimon && bond->params.arp_interval) {
169+ pr_info("%s: MII monitoring cannot be used with ARP monitoring. Disabling ARP monitoring...\n",
170+ bond->dev->name);
171+ bond->params.arp_interval = 0;
172+ if (bond->params.arp_validate)
173+ bond->params.arp_validate = BOND_ARP_VALIDATE_NONE;
174+ }
175+ if (bond->dev->flags & IFF_UP) {
176+ /* If the interface is up, we may need to fire off
177+ * the MII timer. If the interface is down, the
178+ * timer will get fired off when the open function
179+ * is called.
180+ */
181+ if (!miimon) {
182+ cancel_delayed_work_sync(&bond->mii_work);
183+ } else {
184+ cancel_delayed_work_sync(&bond->arp_work);
185+ queue_delayed_work(bond->wq, &bond->mii_work, 0);
186+ }
187+ }
188+ return 0;
189+}
drivers/net/bonding/bond_sysfs.c+10−43
@@ -970,55 +970,22 @@ static ssize_t bonding_store_miimon(struct device *d, · 969 unmodified lines
970970 struct device_attribute *attr,
971971 const char *buf, size_t count)
972972 {
973− int new_value, ret = count;
973+ int new_value, ret;
974974 struct bonding *bond = to_bond(d);
975975
976− if (!rtnl_trylock())
977− return restart_syscall();
978976 if (sscanf(buf, "%d", &new_value) != 1) {
979977 pr_err("%s: no miimon value specified.\n",
980978 bond->dev->name);
981− ret = -EINVAL;
982− goto out;
983− }
984− if (new_value < 0) {
985− pr_err("%s: Invalid miimon value %d not in range %d-%d; rejected.\n",
986− bond->dev->name, new_value, 0, INT_MAX);
987− ret = -EINVAL;
988− goto out;
989− }
990− pr_info("%s: Setting MII monitoring interval to %d.\n",
991− bond->dev->name, new_value);
992− bond->params.miimon = new_value;
993− if (bond->params.updelay)
994− pr_info("%s: Note: Updating updelay (to %d) since it is a multiple of the miimon value.\n",
995− bond->dev->name,
996− bond->params.updelay * bond->params.miimon);
997− if (bond->params.downdelay)
998− pr_info("%s: Note: Updating downdelay (to %d) since it is a multiple of the miimon value.\n",
999− bond->dev->name,
1000− bond->params.downdelay * bond->params.miimon);
1001− if (new_value && bond->params.arp_interval) {
1002− pr_info("%s: MII monitoring cannot be used with ARP monitoring. Disabling ARP monitoring...\n",
1003− bond->dev->name);
1004− bond->params.arp_interval = 0;
1005− if (bond->params.arp_validate)
1006− bond->params.arp_validate = BOND_ARP_VALIDATE_NONE;
1007− }
1008− if (bond->dev->flags & IFF_UP) {
1009− /* If the interface is up, we may need to fire off
1010− * the MII timer. If the interface is down, the
1011− * timer will get fired off when the open function
1012− * is called.
1013− */
1014− if (!new_value) {
1015− cancel_delayed_work_sync(&bond->mii_work);
1016− } else {
1017− cancel_delayed_work_sync(&bond->arp_work);
1018− queue_delayed_work(bond->wq, &bond->mii_work, 0);
1019− }
979+ return -EINVAL;
1020980 }
1021−out:
981+
982+ if (!rtnl_trylock())
983+ return restart_syscall();
984+
985+ ret = bond_option_miimon_set(bond, new_value);
986+ if (!ret)
987+ ret = count;
988+
1022989 rtnl_unlock();
1023990 return ret;
1024991 }
drivers/net/bonding/bonding.h+1−0
@@ -439,6 +439,7 @@ int bond_netlink_init(void); · 438 unmodified lines
439439 void bond_netlink_fini(void);
440440 int bond_option_mode_set(struct bonding *bond, int mode);
441441 int bond_option_active_slave_set(struct bonding *bond, struct net_device *slave_dev);
442+int bond_option_miimon_set(struct bonding *bond, int miimon);
442443 struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond);
443444 struct net_device *bond_option_active_slave_get(struct bonding *bond);
444445
include/uapi/linux/if_link.h+1−0
@@ -331,6 +331,7 @@ enum { · 330 unmodified lines
331331 IFLA_BOND_UNSPEC,
332332 IFLA_BOND_MODE,
333333 IFLA_BOND_ACTIVE_SLAVE,
334+ IFLA_BOND_MIIMON,
334335 __IFLA_BOND_MAX,
335336 };
336337