aboutsummaryrefslogtreecommitdiffstats
path: root/net/ieee802154
diff options
context:
space:
mode:
Diffstat (limited to 'net/ieee802154')
-rw-r--r--net/ieee802154/6lowpan.c53
-rw-r--r--net/ieee802154/nl-mac.c6
-rw-r--r--net/ieee802154/nl-phy.c6
3 files changed, 51 insertions, 14 deletions
diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
index 6a095225148e..6d42c17af96b 100644
--- a/net/ieee802154/6lowpan.c
+++ b/net/ieee802154/6lowpan.c
@@ -1063,12 +1063,6 @@ out:
1063 return (err < 0 ? NETDEV_TX_BUSY : NETDEV_TX_OK); 1063 return (err < 0 ? NETDEV_TX_BUSY : NETDEV_TX_OK);
1064} 1064}
1065 1065
1066static void lowpan_dev_free(struct net_device *dev)
1067{
1068 dev_put(lowpan_dev_info(dev)->real_dev);
1069 free_netdev(dev);
1070}
1071
1072static struct wpan_phy *lowpan_get_phy(const struct net_device *dev) 1066static struct wpan_phy *lowpan_get_phy(const struct net_device *dev)
1073{ 1067{
1074 struct net_device *real_dev = lowpan_dev_info(dev)->real_dev; 1068 struct net_device *real_dev = lowpan_dev_info(dev)->real_dev;
@@ -1118,7 +1112,7 @@ static void lowpan_setup(struct net_device *dev)
1118 dev->netdev_ops = &lowpan_netdev_ops; 1112 dev->netdev_ops = &lowpan_netdev_ops;
1119 dev->header_ops = &lowpan_header_ops; 1113 dev->header_ops = &lowpan_header_ops;
1120 dev->ml_priv = &lowpan_mlme; 1114 dev->ml_priv = &lowpan_mlme;
1121 dev->destructor = lowpan_dev_free; 1115 dev->destructor = free_netdev;
1122} 1116}
1123 1117
1124static int lowpan_validate(struct nlattr *tb[], struct nlattr *data[]) 1118static int lowpan_validate(struct nlattr *tb[], struct nlattr *data[])
@@ -1133,6 +1127,8 @@ static int lowpan_validate(struct nlattr *tb[], struct nlattr *data[])
1133static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev, 1127static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
1134 struct packet_type *pt, struct net_device *orig_dev) 1128 struct packet_type *pt, struct net_device *orig_dev)
1135{ 1129{
1130 struct sk_buff *local_skb;
1131
1136 if (!netif_running(dev)) 1132 if (!netif_running(dev))
1137 goto drop; 1133 goto drop;
1138 1134
@@ -1144,7 +1140,12 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
1144 case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */ 1140 case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */
1145 case LOWPAN_DISPATCH_FRAG1: /* first fragment header */ 1141 case LOWPAN_DISPATCH_FRAG1: /* first fragment header */
1146 case LOWPAN_DISPATCH_FRAGN: /* next fragments headers */ 1142 case LOWPAN_DISPATCH_FRAGN: /* next fragments headers */
1147 lowpan_process_data(skb); 1143 local_skb = skb_clone(skb, GFP_ATOMIC);
1144 if (!local_skb)
1145 goto drop;
1146 lowpan_process_data(local_skb);
1147
1148 kfree_skb(skb);
1148 break; 1149 break;
1149 default: 1150 default:
1150 break; 1151 break;
@@ -1237,6 +1238,34 @@ static inline void __init lowpan_netlink_fini(void)
1237 rtnl_link_unregister(&lowpan_link_ops); 1238 rtnl_link_unregister(&lowpan_link_ops);
1238} 1239}
1239 1240
1241static int lowpan_device_event(struct notifier_block *unused,
1242 unsigned long event,
1243 void *ptr)
1244{
1245 struct net_device *dev = ptr;
1246 LIST_HEAD(del_list);
1247 struct lowpan_dev_record *entry, *tmp;
1248
1249 if (dev->type != ARPHRD_IEEE802154)
1250 goto out;
1251
1252 if (event == NETDEV_UNREGISTER) {
1253 list_for_each_entry_safe(entry, tmp, &lowpan_devices, list) {
1254 if (lowpan_dev_info(entry->ldev)->real_dev == dev)
1255 lowpan_dellink(entry->ldev, &del_list);
1256 }
1257
1258 unregister_netdevice_many(&del_list);
1259 }
1260
1261out:
1262 return NOTIFY_DONE;
1263}
1264
1265static struct notifier_block lowpan_dev_notifier = {
1266 .notifier_call = lowpan_device_event,
1267};
1268
1240static struct packet_type lowpan_packet_type = { 1269static struct packet_type lowpan_packet_type = {
1241 .type = __constant_htons(ETH_P_IEEE802154), 1270 .type = __constant_htons(ETH_P_IEEE802154),
1242 .func = lowpan_rcv, 1271 .func = lowpan_rcv,
@@ -1251,6 +1280,12 @@ static int __init lowpan_init_module(void)
1251 goto out; 1280 goto out;
1252 1281
1253 dev_add_pack(&lowpan_packet_type); 1282 dev_add_pack(&lowpan_packet_type);
1283
1284 err = register_netdevice_notifier(&lowpan_dev_notifier);
1285 if (err < 0) {
1286 dev_remove_pack(&lowpan_packet_type);
1287 lowpan_netlink_fini();
1288 }
1254out: 1289out:
1255 return err; 1290 return err;
1256} 1291}
@@ -1263,6 +1298,8 @@ static void __exit lowpan_cleanup_module(void)
1263 1298
1264 dev_remove_pack(&lowpan_packet_type); 1299 dev_remove_pack(&lowpan_packet_type);
1265 1300
1301 unregister_netdevice_notifier(&lowpan_dev_notifier);
1302
1266 /* Now 6lowpan packet_type is removed, so no new fragments are 1303 /* Now 6lowpan packet_type is removed, so no new fragments are
1267 * expected on RX, therefore that's the time to clean incomplete 1304 * expected on RX, therefore that's the time to clean incomplete
1268 * fragments. 1305 * fragments.
diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c
index 1e9917124e75..96bb08abece2 100644
--- a/net/ieee802154/nl-mac.c
+++ b/net/ieee802154/nl-mac.c
@@ -246,7 +246,7 @@ nla_put_failure:
246} 246}
247EXPORT_SYMBOL(ieee802154_nl_start_confirm); 247EXPORT_SYMBOL(ieee802154_nl_start_confirm);
248 248
249static int ieee802154_nl_fill_iface(struct sk_buff *msg, u32 pid, 249static int ieee802154_nl_fill_iface(struct sk_buff *msg, u32 portid,
250 u32 seq, int flags, struct net_device *dev) 250 u32 seq, int flags, struct net_device *dev)
251{ 251{
252 void *hdr; 252 void *hdr;
@@ -534,7 +534,7 @@ static int ieee802154_list_iface(struct sk_buff *skb,
534 if (!msg) 534 if (!msg)
535 goto out_dev; 535 goto out_dev;
536 536
537 rc = ieee802154_nl_fill_iface(msg, info->snd_pid, info->snd_seq, 537 rc = ieee802154_nl_fill_iface(msg, info->snd_portid, info->snd_seq,
538 0, dev); 538 0, dev);
539 if (rc < 0) 539 if (rc < 0)
540 goto out_free; 540 goto out_free;
@@ -565,7 +565,7 @@ static int ieee802154_dump_iface(struct sk_buff *skb,
565 if (idx < s_idx || (dev->type != ARPHRD_IEEE802154)) 565 if (idx < s_idx || (dev->type != ARPHRD_IEEE802154))
566 goto cont; 566 goto cont;
567 567
568 if (ieee802154_nl_fill_iface(skb, NETLINK_CB(cb->skb).pid, 568 if (ieee802154_nl_fill_iface(skb, NETLINK_CB(cb->skb).portid,
569 cb->nlh->nlmsg_seq, NLM_F_MULTI, dev) < 0) 569 cb->nlh->nlmsg_seq, NLM_F_MULTI, dev) < 0)
570 break; 570 break;
571cont: 571cont:
diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c
index d54be34cca94..22b1a7058fd3 100644
--- a/net/ieee802154/nl-phy.c
+++ b/net/ieee802154/nl-phy.c
@@ -35,7 +35,7 @@
35 35
36#include "ieee802154.h" 36#include "ieee802154.h"
37 37
38static int ieee802154_nl_fill_phy(struct sk_buff *msg, u32 pid, 38static int ieee802154_nl_fill_phy(struct sk_buff *msg, u32 portid,
39 u32 seq, int flags, struct wpan_phy *phy) 39 u32 seq, int flags, struct wpan_phy *phy)
40{ 40{
41 void *hdr; 41 void *hdr;
@@ -105,7 +105,7 @@ static int ieee802154_list_phy(struct sk_buff *skb,
105 if (!msg) 105 if (!msg)
106 goto out_dev; 106 goto out_dev;
107 107
108 rc = ieee802154_nl_fill_phy(msg, info->snd_pid, info->snd_seq, 108 rc = ieee802154_nl_fill_phy(msg, info->snd_portid, info->snd_seq,
109 0, phy); 109 0, phy);
110 if (rc < 0) 110 if (rc < 0)
111 goto out_free; 111 goto out_free;
@@ -138,7 +138,7 @@ static int ieee802154_dump_phy_iter(struct wpan_phy *phy, void *_data)
138 return 0; 138 return 0;
139 139
140 rc = ieee802154_nl_fill_phy(data->skb, 140 rc = ieee802154_nl_fill_phy(data->skb,
141 NETLINK_CB(data->cb->skb).pid, 141 NETLINK_CB(data->cb->skb).portid,
142 data->cb->nlh->nlmsg_seq, 142 data->cb->nlh->nlmsg_seq,
143 NLM_F_MULTI, 143 NLM_F_MULTI,
144 phy); 144 phy);