mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-24 09:50:04 +00:00
Merge branch 'batman-hdlc'
Andrew Lunn says: ==================== Allow BATMAN to use hdlc-eth interfaces BATMAN works over Ethernet like interfaces. hdlc-eth provides the need requirements. However, hdlc devices are often created as raw hdlc devices, which batman cannot use, and are then be transmuted into other types using sethdlc(1). Have the HDLC code emit NETDEV_*_TYPE_CHANGE events when the type changes, and have BATMAN react on these events. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
857e8a6765
10 changed files with 30 additions and 6 deletions
|
@ -266,8 +266,8 @@ struct net_device *alloc_hdlcdev(void *priv)
|
|||
void unregister_hdlc_device(struct net_device *dev)
|
||||
{
|
||||
rtnl_lock();
|
||||
unregister_netdevice(dev);
|
||||
detach_hdlc_protocol(dev);
|
||||
unregister_netdevice(dev);
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
|
@ -276,7 +276,11 @@ void unregister_hdlc_device(struct net_device *dev)
|
|||
int attach_hdlc_protocol(struct net_device *dev, struct hdlc_proto *proto,
|
||||
size_t size)
|
||||
{
|
||||
detach_hdlc_protocol(dev);
|
||||
int err;
|
||||
|
||||
err = detach_hdlc_protocol(dev);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!try_module_get(proto->module))
|
||||
return -ENOSYS;
|
||||
|
@ -289,15 +293,24 @@ int attach_hdlc_protocol(struct net_device *dev, struct hdlc_proto *proto,
|
|||
}
|
||||
}
|
||||
dev_to_hdlc(dev)->proto = proto;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void detach_hdlc_protocol(struct net_device *dev)
|
||||
int detach_hdlc_protocol(struct net_device *dev)
|
||||
{
|
||||
hdlc_device *hdlc = dev_to_hdlc(dev);
|
||||
int err;
|
||||
|
||||
if (hdlc->proto) {
|
||||
err = call_netdevice_notifiers(NETDEV_PRE_TYPE_CHANGE, dev);
|
||||
err = notifier_to_errno(err);
|
||||
if (err) {
|
||||
netdev_err(dev, "Refused to change device type\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
if (hdlc->proto->detach)
|
||||
hdlc->proto->detach(dev);
|
||||
module_put(hdlc->proto->module);
|
||||
|
@ -306,6 +319,8 @@ void detach_hdlc_protocol(struct net_device *dev)
|
|||
kfree(hdlc->state);
|
||||
hdlc->state = NULL;
|
||||
hdlc_setup_dev(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -378,6 +378,7 @@ static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr)
|
|||
spin_lock_init(&state(hdlc)->lock);
|
||||
dev->header_ops = &cisco_header_ops;
|
||||
dev->type = ARPHRD_CISCO;
|
||||
call_netdevice_notifiers(NETDEV_POST_TYPE_CHANGE, dev);
|
||||
netif_dormant_on(dev);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1240,6 +1240,7 @@ static int fr_ioctl(struct net_device *dev, struct ifreq *ifr)
|
|||
}
|
||||
memcpy(&state(hdlc)->settings, &new_settings, size);
|
||||
dev->type = ARPHRD_FRAD;
|
||||
call_netdevice_notifiers(NETDEV_POST_TYPE_CHANGE, dev);
|
||||
return 0;
|
||||
|
||||
case IF_PROTO_FR_ADD_PVC:
|
||||
|
|
|
@ -687,6 +687,7 @@ static int ppp_ioctl(struct net_device *dev, struct ifreq *ifr)
|
|||
dev->hard_header_len = sizeof(struct hdlc_header);
|
||||
dev->header_ops = &ppp_header_ops;
|
||||
dev->type = ARPHRD_PPP;
|
||||
call_netdevice_notifiers(NETDEV_POST_TYPE_CHANGE, dev);
|
||||
netif_dormant_on(dev);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -84,6 +84,7 @@ static int raw_ioctl(struct net_device *dev, struct ifreq *ifr)
|
|||
return result;
|
||||
memcpy(hdlc->state, &new_settings, size);
|
||||
dev->type = ARPHRD_RAWHDLC;
|
||||
call_netdevice_notifiers(NETDEV_POST_TYPE_CHANGE, dev);
|
||||
netif_dormant_off(dev);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -102,6 +102,7 @@ static int raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr)
|
|||
ether_setup(dev);
|
||||
dev->tx_queue_len = old_qlen;
|
||||
eth_hw_addr_random(dev);
|
||||
call_netdevice_notifiers(NETDEV_POST_TYPE_CHANGE, dev);
|
||||
netif_dormant_off(dev);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -213,6 +213,7 @@ static int x25_ioctl(struct net_device *dev, struct ifreq *ifr)
|
|||
if ((result = attach_hdlc_protocol(dev, &proto, 0)))
|
||||
return result;
|
||||
dev->type = ARPHRD_X25;
|
||||
call_netdevice_notifiers(NETDEV_POST_TYPE_CHANGE, dev);
|
||||
netif_dormant_off(dev);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -101,7 +101,7 @@ netdev_tx_t hdlc_start_xmit(struct sk_buff *skb, struct net_device *dev);
|
|||
int attach_hdlc_protocol(struct net_device *dev, struct hdlc_proto *proto,
|
||||
size_t size);
|
||||
/* May be used by hardware driver to gain control over HDLC device */
|
||||
void detach_hdlc_protocol(struct net_device *dev);
|
||||
int detach_hdlc_protocol(struct net_device *dev);
|
||||
|
||||
static __inline__ __be16 hdlc_type_trans(struct sk_buff *skb,
|
||||
struct net_device *dev)
|
||||
|
|
|
@ -709,7 +709,8 @@ static int batadv_hard_if_event(struct notifier_block *this,
|
|||
}
|
||||
|
||||
hard_iface = batadv_hardif_get_by_netdev(net_dev);
|
||||
if (!hard_iface && event == NETDEV_REGISTER)
|
||||
if (!hard_iface && (event == NETDEV_REGISTER ||
|
||||
event == NETDEV_POST_TYPE_CHANGE))
|
||||
hard_iface = batadv_hardif_add_interface(net_dev);
|
||||
|
||||
if (!hard_iface)
|
||||
|
@ -724,6 +725,7 @@ static int batadv_hard_if_event(struct notifier_block *this,
|
|||
batadv_hardif_deactivate_interface(hard_iface);
|
||||
break;
|
||||
case NETDEV_UNREGISTER:
|
||||
case NETDEV_PRE_TYPE_CHANGE:
|
||||
list_del_rcu(&hard_iface->list);
|
||||
|
||||
batadv_hardif_remove_interface(hard_iface);
|
||||
|
|
|
@ -3287,7 +3287,8 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
|
|||
|
||||
case NETDEV_PRE_TYPE_CHANGE:
|
||||
case NETDEV_POST_TYPE_CHANGE:
|
||||
addrconf_type_change(dev, event);
|
||||
if (idev)
|
||||
addrconf_type_change(dev, event);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue