aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Eremin-Solenikov <dbaryshkov@gmail.com>2010-03-18 12:26:23 -0400
committerDmitry Eremin-Solenikov <dbaryshkov@gmail.com>2011-06-30 08:18:09 -0400
commit060e41794e3f09f0b28f79b8d6c7ac1a9641d672 (patch)
tree20aeda68993b5ee07459e339222c7d3b8f88d88b
parent6e10c469f0997a5ebaffa955d8716c59ba102a1f (diff)
ieee802154: support specifying hw address for created devices
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
-rw-r--r--net/ieee802154/nl-phy.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c
index 02548b292b53..c64a38d57aa3 100644
--- a/net/ieee802154/nl-phy.c
+++ b/net/ieee802154/nl-phy.c
@@ -24,6 +24,7 @@
24 24
25#include <linux/kernel.h> 25#include <linux/kernel.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/if_arp.h>
27#include <net/netlink.h> 28#include <net/netlink.h>
28#include <net/genetlink.h> 29#include <net/genetlink.h>
29#include <net/wpan-phy.h> 30#include <net/wpan-phy.h>
@@ -213,12 +214,37 @@ static int ieee802154_add_iface(struct sk_buff *skb,
213 goto nla_put_failure; 214 goto nla_put_failure;
214 } 215 }
215 216
217 if (info->attrs[IEEE802154_ATTR_HW_ADDR] &&
218 nla_len(info->attrs[IEEE802154_ATTR_HW_ADDR]) !=
219 IEEE802154_ADDR_LEN) {
220 rc = -EINVAL;
221 goto nla_put_failure;
222 }
223
216 dev = phy->add_iface(phy, devname); 224 dev = phy->add_iface(phy, devname);
217 if (IS_ERR(dev)) { 225 if (IS_ERR(dev)) {
218 rc = PTR_ERR(dev); 226 rc = PTR_ERR(dev);
219 goto nla_put_failure; 227 goto nla_put_failure;
220 } 228 }
221 229
230 if (info->attrs[IEEE802154_ATTR_HW_ADDR]) {
231 struct sockaddr addr;
232
233 addr.sa_family = ARPHRD_IEEE802154;
234 nla_memcpy(&addr.sa_data, info->attrs[IEEE802154_ATTR_HW_ADDR],
235 IEEE802154_ADDR_LEN);
236
237 /*
238 * strangely enough, some callbacks (inetdev_event) from
239 * dev_set_mac_address require RTNL_LOCK
240 */
241 rtnl_lock();
242 rc = dev_set_mac_address(dev, &addr);
243 rtnl_unlock();
244 if (rc)
245 goto dev_unregister;
246 }
247
222 NLA_PUT_STRING(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy)); 248 NLA_PUT_STRING(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy));
223 NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name); 249 NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
224 250
@@ -228,6 +254,11 @@ static int ieee802154_add_iface(struct sk_buff *skb,
228 254
229 return ieee802154_nl_reply(msg, info); 255 return ieee802154_nl_reply(msg, info);
230 256
257dev_unregister:
258 rtnl_lock(); /* del_iface must be called with RTNL lock */
259 phy->del_iface(phy, dev);
260 dev_put(dev);
261 rtnl_unlock();
231nla_put_failure: 262nla_put_failure:
232 nlmsg_free(msg); 263 nlmsg_free(msg);
233out_dev: 264out_dev: