summaryrefslogtreecommitdiffstats
path: root/drivers/net/wan
diff options
context:
space:
mode:
authorAndrew Lunn <andrew@lunn.ch>2015-12-03 15:12:31 -0500
committerDavid S. Miller <davem@davemloft.net>2015-12-05 17:41:42 -0500
commit2f8364a291e8adde25c93f97a76abbcaf4b1ed3f (patch)
tree7b7e3de286880cf4938c00803df3a1ec32d22997 /drivers/net/wan
parentff3516442768f0babe7ea2db62e34aee1d76e969 (diff)
WAN: HDLC: Call notifiers before and after changing device type
An HDLC device can change type when the protocol driver is changed. Calling the notifier change allows potential users of the interface know about this planned change, and even block it. After the change has occurred, send a second notification to users can evaluate the new device type etc. Signed-off-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/wan')
-rw-r--r--drivers/net/wan/hdlc.c19
-rw-r--r--drivers/net/wan/hdlc_cisco.c1
-rw-r--r--drivers/net/wan/hdlc_fr.c1
-rw-r--r--drivers/net/wan/hdlc_ppp.c1
-rw-r--r--drivers/net/wan/hdlc_raw.c1
-rw-r--r--drivers/net/wan/hdlc_raw_eth.c1
-rw-r--r--drivers/net/wan/hdlc_x25.c1
7 files changed, 23 insertions, 2 deletions
diff --git a/drivers/net/wan/hdlc.c b/drivers/net/wan/hdlc.c
index 2a6595b4ae15..9bd4aa8083ce 100644
--- a/drivers/net/wan/hdlc.c
+++ b/drivers/net/wan/hdlc.c
@@ -276,7 +276,11 @@ void unregister_hdlc_device(struct net_device *dev)
276int attach_hdlc_protocol(struct net_device *dev, struct hdlc_proto *proto, 276int attach_hdlc_protocol(struct net_device *dev, struct hdlc_proto *proto,
277 size_t size) 277 size_t size)
278{ 278{
279 detach_hdlc_protocol(dev); 279 int err;
280
281 err = detach_hdlc_protocol(dev);
282 if (err)
283 return err;
280 284
281 if (!try_module_get(proto->module)) 285 if (!try_module_get(proto->module))
282 return -ENOSYS; 286 return -ENOSYS;
@@ -289,15 +293,24 @@ int attach_hdlc_protocol(struct net_device *dev, struct hdlc_proto *proto,
289 } 293 }
290 } 294 }
291 dev_to_hdlc(dev)->proto = proto; 295 dev_to_hdlc(dev)->proto = proto;
296
292 return 0; 297 return 0;
293} 298}
294 299
295 300
296void detach_hdlc_protocol(struct net_device *dev) 301int detach_hdlc_protocol(struct net_device *dev)
297{ 302{
298 hdlc_device *hdlc = dev_to_hdlc(dev); 303 hdlc_device *hdlc = dev_to_hdlc(dev);
304 int err;
299 305
300 if (hdlc->proto) { 306 if (hdlc->proto) {
307 err = call_netdevice_notifiers(NETDEV_PRE_TYPE_CHANGE, dev);
308 err = notifier_to_errno(err);
309 if (err) {
310 netdev_err(dev, "Refused to change device type\n");
311 return err;
312 }
313
301 if (hdlc->proto->detach) 314 if (hdlc->proto->detach)
302 hdlc->proto->detach(dev); 315 hdlc->proto->detach(dev);
303 module_put(hdlc->proto->module); 316 module_put(hdlc->proto->module);
@@ -306,6 +319,8 @@ void detach_hdlc_protocol(struct net_device *dev)
306 kfree(hdlc->state); 319 kfree(hdlc->state);
307 hdlc->state = NULL; 320 hdlc->state = NULL;
308 hdlc_setup_dev(dev); 321 hdlc_setup_dev(dev);
322
323 return 0;
309} 324}
310 325
311 326
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c
index 3f20808b5ff8..a408abc25512 100644
--- a/drivers/net/wan/hdlc_cisco.c
+++ b/drivers/net/wan/hdlc_cisco.c
@@ -378,6 +378,7 @@ static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr)
378 spin_lock_init(&state(hdlc)->lock); 378 spin_lock_init(&state(hdlc)->lock);
379 dev->header_ops = &cisco_header_ops; 379 dev->header_ops = &cisco_header_ops;
380 dev->type = ARPHRD_CISCO; 380 dev->type = ARPHRD_CISCO;
381 call_netdevice_notifiers(NETDEV_POST_TYPE_CHANGE, dev);
381 netif_dormant_on(dev); 382 netif_dormant_on(dev);
382 return 0; 383 return 0;
383 } 384 }
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index 89541cc90e87..b6e0cfb095d3 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -1240,6 +1240,7 @@ static int fr_ioctl(struct net_device *dev, struct ifreq *ifr)
1240 } 1240 }
1241 memcpy(&state(hdlc)->settings, &new_settings, size); 1241 memcpy(&state(hdlc)->settings, &new_settings, size);
1242 dev->type = ARPHRD_FRAD; 1242 dev->type = ARPHRD_FRAD;
1243 call_netdevice_notifiers(NETDEV_POST_TYPE_CHANGE, dev);
1243 return 0; 1244 return 0;
1244 1245
1245 case IF_PROTO_FR_ADD_PVC: 1246 case IF_PROTO_FR_ADD_PVC:
diff --git a/drivers/net/wan/hdlc_ppp.c b/drivers/net/wan/hdlc_ppp.c
index 0d7645581f91..47fdb87d3567 100644
--- a/drivers/net/wan/hdlc_ppp.c
+++ b/drivers/net/wan/hdlc_ppp.c
@@ -687,6 +687,7 @@ static int ppp_ioctl(struct net_device *dev, struct ifreq *ifr)
687 dev->hard_header_len = sizeof(struct hdlc_header); 687 dev->hard_header_len = sizeof(struct hdlc_header);
688 dev->header_ops = &ppp_header_ops; 688 dev->header_ops = &ppp_header_ops;
689 dev->type = ARPHRD_PPP; 689 dev->type = ARPHRD_PPP;
690 call_netdevice_notifiers(NETDEV_POST_TYPE_CHANGE, dev);
690 netif_dormant_on(dev); 691 netif_dormant_on(dev);
691 return 0; 692 return 0;
692 } 693 }
diff --git a/drivers/net/wan/hdlc_raw.c b/drivers/net/wan/hdlc_raw.c
index 5dc153e8a29d..4feb45001aac 100644
--- a/drivers/net/wan/hdlc_raw.c
+++ b/drivers/net/wan/hdlc_raw.c
@@ -84,6 +84,7 @@ static int raw_ioctl(struct net_device *dev, struct ifreq *ifr)
84 return result; 84 return result;
85 memcpy(hdlc->state, &new_settings, size); 85 memcpy(hdlc->state, &new_settings, size);
86 dev->type = ARPHRD_RAWHDLC; 86 dev->type = ARPHRD_RAWHDLC;
87 call_netdevice_notifiers(NETDEV_POST_TYPE_CHANGE, dev);
87 netif_dormant_off(dev); 88 netif_dormant_off(dev);
88 return 0; 89 return 0;
89 } 90 }
diff --git a/drivers/net/wan/hdlc_raw_eth.c b/drivers/net/wan/hdlc_raw_eth.c
index 3ab72b3082de..2f11836078ab 100644
--- a/drivers/net/wan/hdlc_raw_eth.c
+++ b/drivers/net/wan/hdlc_raw_eth.c
@@ -102,6 +102,7 @@ static int raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr)
102 ether_setup(dev); 102 ether_setup(dev);
103 dev->tx_queue_len = old_qlen; 103 dev->tx_queue_len = old_qlen;
104 eth_hw_addr_random(dev); 104 eth_hw_addr_random(dev);
105 call_netdevice_notifiers(NETDEV_POST_TYPE_CHANGE, dev);
105 netif_dormant_off(dev); 106 netif_dormant_off(dev);
106 return 0; 107 return 0;
107 } 108 }
diff --git a/drivers/net/wan/hdlc_x25.c b/drivers/net/wan/hdlc_x25.c
index a49aec5efd20..e867638067a6 100644
--- a/drivers/net/wan/hdlc_x25.c
+++ b/drivers/net/wan/hdlc_x25.c
@@ -213,6 +213,7 @@ static int x25_ioctl(struct net_device *dev, struct ifreq *ifr)
213 if ((result = attach_hdlc_protocol(dev, &proto, 0))) 213 if ((result = attach_hdlc_protocol(dev, &proto, 0)))
214 return result; 214 return result;
215 dev->type = ARPHRD_X25; 215 dev->type = ARPHRD_X25;
216 call_netdevice_notifiers(NETDEV_POST_TYPE_CHANGE, dev);
216 netif_dormant_off(dev); 217 netif_dormant_off(dev);
217 return 0; 218 return 0;
218 } 219 }