#include <linux/atmdev.h>
#include <linux/atmclip.h>
#include <linux/atmarp.h>
+#include <linux/capability.h>
#include <linux/ip.h> /* for net/route.h */
#include <linux/in.h> /* for struct sockaddr_in */
#include <linux/if.h> /* for IFF_UP */
static int to_atmarpd(enum atmarp_ctrl_type type,int itf,unsigned long ip)
{
+ struct sock *sk;
struct atmarp_ctrl *ctrl;
struct sk_buff *skb;
ctrl->itf_num = itf;
ctrl->ip = ip;
atm_force_charge(atmarpd,skb->truesize);
- skb_queue_tail(&atmarpd->sk->sk_receive_queue, skb);
- atmarpd->sk->sk_data_ready(atmarpd->sk, skb->len);
+
+ sk = sk_atm(atmarpd);
+ skb_queue_tail(&sk->sk_receive_queue, skb);
+ sk->sk_data_ready(sk, skb->len);
return 0;
}
if (neigh->type != RTN_UNICAST) return -EINVAL;
rcu_read_lock();
- in_dev = rcu_dereference(__in_dev_get(dev));
+ in_dev = __in_dev_get_rcu(dev);
if (!in_dev) {
rcu_read_unlock();
return -EINVAL;
memcpy(here,llc_oui,sizeof(llc_oui));
((u16 *) here)[3] = skb->protocol;
}
- atomic_add(skb->truesize, &vcc->sk->sk_wmem_alloc);
+ atomic_add(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc);
ATM_SKB(skb)->atm_options = vcc->atm_options;
entry->vccs->last_use = jiffies;
DPRINTK("atm_skb(%p)->vcc(%p)->dev(%p)\n",skb,vcc,vcc->dev);
vcc->push = clip_push;
vcc->pop = clip_pop;
skb_queue_head_init(©);
- skb_migrate(&vcc->sk->sk_receive_queue, ©);
+ skb_migrate(&sk_atm(vcc)->sk_receive_queue, ©);
/* re-process everything received between connection setup and MKIP */
while ((skb = skb_dequeue(©)) != NULL)
if (!clip_devs) {
else {
unsigned int len = skb->len;
+ skb_get(skb);
clip_push(vcc,skb);
PRIV(skb->dev)->stats.rx_packets--;
PRIV(skb->dev)->stats.rx_bytes -= len;
+ kfree_skb(skb);
}
return 0;
}
static int clip_device_event(struct notifier_block *this,unsigned long event,
- void *dev)
+ void *arg)
{
+ struct net_device *dev = arg;
+
+ if (event == NETDEV_UNREGISTER) {
+ neigh_ifdown(&clip_tbl, dev);
+ return NOTIFY_DONE;
+ }
+
/* ignore non-CLIP devices */
- if (((struct net_device *) dev)->type != ARPHRD_ATM ||
- ((struct net_device *) dev)->hard_start_xmit != clip_start_xmit)
+ if (dev->type != ARPHRD_ATM || dev->hard_start_xmit != clip_start_xmit)
return NOTIFY_DONE;
+
switch (event) {
case NETDEV_UP:
DPRINTK("clip_device_event NETDEV_UP\n");
static void atmarpd_close(struct atm_vcc *vcc)
{
DPRINTK("atmarpd_close\n");
- atmarpd = NULL; /* assumed to be atomic */
- barrier();
- unregister_inetaddr_notifier(&clip_inet_notifier);
- unregister_netdevice_notifier(&clip_dev_notifier);
- if (skb_peek(&vcc->sk->sk_receive_queue))
- printk(KERN_ERR "atmarpd_close: closing with requests "
- "pending\n");
- skb_queue_purge(&vcc->sk->sk_receive_queue);
+
+ rtnl_lock();
+ atmarpd = NULL;
+ skb_queue_purge(&sk_atm(vcc)->sk_receive_queue);
+ rtnl_unlock();
+
DPRINTK("(done)\n");
module_put(THIS_MODULE);
}
static int atm_init_atmarp(struct atm_vcc *vcc)
{
- if (atmarpd) return -EADDRINUSE;
+ rtnl_lock();
+ if (atmarpd) {
+ rtnl_unlock();
+ return -EADDRINUSE;
+ }
+
if (start_timer) {
start_timer = 0;
init_timer(&idle_timer);
set_bit(ATM_VF_READY,&vcc->flags);
/* allow replies and avoid getting closed if signaling dies */
vcc->dev = &atmarpd_dev;
- vcc_insert_socket(vcc->sk);
+ vcc_insert_socket(sk_atm(vcc));
vcc->push = NULL;
vcc->pop = NULL; /* crash */
vcc->push_oam = NULL; /* crash */
- if (register_netdevice_notifier(&clip_dev_notifier))
- printk(KERN_ERR "register_netdevice_notifier failed\n");
- if (register_inetaddr_notifier(&clip_inet_notifier))
- printk(KERN_ERR "register_inetaddr_notifier failed\n");
+ rtnl_unlock();
return 0;
}
int svc, llc, off;
svc = ((clip_vcc == SEQ_NO_VCC_TOKEN) ||
- (clip_vcc->vcc->sk->sk_family == AF_ATMSVC));
+ (sk_atm(clip_vcc->vcc)->sk_family == AF_ATMSVC));
llc = ((clip_vcc == SEQ_NO_VCC_TOKEN) ||
clip_vcc->encap);
clip_tbl_hook = &clip_tbl;
register_atm_ioctl(&clip_ioctl_ops);
+ register_netdevice_notifier(&clip_dev_notifier);
+ register_inetaddr_notifier(&clip_inet_notifier);
#ifdef CONFIG_PROC_FS
{
remove_proc_entry("arp", atm_proc_root);
+ unregister_inetaddr_notifier(&clip_inet_notifier);
+ unregister_netdevice_notifier(&clip_dev_notifier);
+
deregister_atm_ioctl(&clip_ioctl_ops);
/* First, stop the idle timer, so it stops banging