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 "bonding.h"
23 
24 static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = {
25 	[IFLA_BOND_MODE]		= { .type = NLA_U8 },
26 	[IFLA_BOND_ACTIVE_SLAVE]	= { .type = NLA_U32 },
27 	[IFLA_BOND_MIIMON]		= { .type = NLA_U32 },
28 	[IFLA_BOND_UPDELAY]		= { .type = NLA_U32 },
29 };
30 
31 static int bond_validate(struct nlattr *tb[], struct nlattr *data[])
32 {
33 	if (tb[IFLA_ADDRESS]) {
34 		if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
35 			return -EINVAL;
36 		if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
37 			return -EADDRNOTAVAIL;
38 	}
39 	return 0;
40 }
41 
42 static int bond_changelink(struct net_device *bond_dev,
43 			   struct nlattr *tb[], struct nlattr *data[])
44 {
45 	struct bonding *bond = netdev_priv(bond_dev);
46 	int err;
47 
48 	if (!data)
49 		return 0;
50 
51 	if (data[IFLA_BOND_MODE]) {
52 		int mode = nla_get_u8(data[IFLA_BOND_MODE]);
53 
54 		err = bond_option_mode_set(bond, mode);
55 		if (err)
56 			return err;
57 	}
58 	if (data[IFLA_BOND_ACTIVE_SLAVE]) {
59 		int ifindex = nla_get_u32(data[IFLA_BOND_ACTIVE_SLAVE]);
60 		struct net_device *slave_dev;
61 
62 		if (ifindex == 0) {
63 			slave_dev = NULL;
64 		} else {
65 			slave_dev = __dev_get_by_index(dev_net(bond_dev),
66 						       ifindex);
67 			if (!slave_dev)
68 				return -ENODEV;
69 		}
70 		err = bond_option_active_slave_set(bond, slave_dev);
71 		if (err)
72 			return err;
73 	}
74 	if (data[IFLA_BOND_MIIMON]) {
75 		int miimon = nla_get_u32(data[IFLA_BOND_MIIMON]);
76 
77 		err = bond_option_miimon_set(bond, miimon);
78 		if (err)
79 			return err;
80 	}
81 	if (data[IFLA_BOND_UPDELAY]) {
82 		int updelay = nla_get_u32(data[IFLA_BOND_UPDELAY]);
83 
84 		err = bond_option_updelay_set(bond, updelay);
85 		if (err)
86 			return err;
87 	}
88 	return 0;
89 }
90 
91 static int bond_newlink(struct net *src_net, struct net_device *bond_dev,
92 			struct nlattr *tb[], struct nlattr *data[])
93 {
94 	int err;
95 
96 	err = bond_changelink(bond_dev, tb, data);
97 	if (err < 0)
98 		return err;
99 
100 	return register_netdevice(bond_dev);
101 }
102 
103 static size_t bond_get_size(const struct net_device *bond_dev)
104 {
105 	return nla_total_size(sizeof(u8)) +	/* IFLA_BOND_MODE */
106 		nla_total_size(sizeof(u32)) +	/* IFLA_BOND_ACTIVE_SLAVE */
107 		nla_total_size(sizeof(u32)) +	/* IFLA_BOND_MIIMON */
108 		nla_total_size(sizeof(u32)) +	/* IFLA_BOND_UPDELAY */
109 		0;
110 }
111 
112 static int bond_fill_info(struct sk_buff *skb,
113 			  const struct net_device *bond_dev)
114 {
115 	struct bonding *bond = netdev_priv(bond_dev);
116 	struct net_device *slave_dev = bond_option_active_slave_get(bond);
117 
118 	if (nla_put_u8(skb, IFLA_BOND_MODE, bond->params.mode))
119 		goto nla_put_failure;
120 
121 	if (slave_dev &&
122 	    nla_put_u32(skb, IFLA_BOND_ACTIVE_SLAVE, slave_dev->ifindex))
123 		goto nla_put_failure;
124 
125 	if (nla_put_u32(skb, IFLA_BOND_MIIMON, bond->params.miimon))
126 		goto nla_put_failure;
127 
128 	if (nla_put_u32(skb, IFLA_BOND_UPDELAY,
129 			bond->params.updelay * bond->params.miimon))
130 		goto nla_put_failure;
131 
132 	return 0;
133 
134 nla_put_failure:
135 	return -EMSGSIZE;
136 }
137 
138 struct rtnl_link_ops bond_link_ops __read_mostly = {
139 	.kind			= "bond",
140 	.priv_size		= sizeof(struct bonding),
141 	.setup			= bond_setup,
142 	.maxtype		= IFLA_BOND_MAX,
143 	.policy			= bond_policy,
144 	.validate		= bond_validate,
145 	.newlink		= bond_newlink,
146 	.changelink		= bond_changelink,
147 	.get_size		= bond_get_size,
148 	.fill_info		= bond_fill_info,
149 	.get_num_tx_queues	= bond_get_num_tx_queues,
150 	.get_num_rx_queues	= bond_get_num_tx_queues, /* Use the same number
151 							     as for TX queues */
152 };
153 
154 int __init bond_netlink_init(void)
155 {
156 	return rtnl_link_register(&bond_link_ops);
157 }
158 
159 void bond_netlink_fini(void)
160 {
161 	rtnl_link_unregister(&bond_link_ops);
162 }
163 
164 MODULE_ALIAS_RTNL_LINK("bond");
165