Loading net/atm/clip.c +199 −211 Original line number Diff line number Diff line Loading @@ -2,7 +2,6 @@ /* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ #include <linux/config.h> #include <linux/string.h> #include <linux/errno.h> Loading Loading @@ -62,9 +61,11 @@ static int to_atmarpd(enum atmarp_ctrl_type type,int itf,unsigned long ip) struct sk_buff *skb; DPRINTK("to_atmarpd(%d)\n", type); if (!atmarpd) return -EUNATCH; if (!atmarpd) return -EUNATCH; skb = alloc_skb(sizeof(struct atmarp_ctrl),GFP_ATOMIC); if (!skb) return -ENOMEM; if (!skb) return -ENOMEM; ctrl = (struct atmarp_ctrl *) skb_put(skb,sizeof(struct atmarp_ctrl)); ctrl->type = type; ctrl->itf_num = itf; Loading @@ -77,7 +78,6 @@ static int to_atmarpd(enum atmarp_ctrl_type type,int itf,unsigned long ip) return 0; } static void link_vcc(struct clip_vcc *clip_vcc, struct atmarp_entry *entry) { DPRINTK("link_vcc %p to entry %p (neigh %p)\n", clip_vcc, entry, Loading @@ -89,7 +89,6 @@ static void link_vcc(struct clip_vcc *clip_vcc,struct atmarp_entry *entry) entry->neigh->used = jiffies; } static void unlink_clip_vcc(struct clip_vcc *clip_vcc) { struct atmarp_entry *entry = clip_vcc->entry; Loading Loading @@ -191,7 +190,8 @@ static const unsigned char llc_oui[] = { 0x03, /* Ctrl: Unnumbered Information Command PDU */ 0x00, /* OUI: EtherType */ 0x00, 0x00 }; 0x00 }; static void clip_push(struct atm_vcc *vcc, struct sk_buff *skb) { Loading @@ -200,7 +200,8 @@ static void clip_push(struct atm_vcc *vcc,struct sk_buff *skb) DPRINTK("clip push\n"); if (!skb) { DPRINTK("removing VCC %p\n", clip_vcc); if (clip_vcc->entry) unlink_clip_vcc(clip_vcc); if (clip_vcc->entry) unlink_clip_vcc(clip_vcc); clip_vcc->old_push(vcc, NULL); /* pass on the bad news */ kfree(clip_vcc); return; Loading @@ -214,8 +215,10 @@ static void clip_push(struct atm_vcc *vcc,struct sk_buff *skb) } ATM_SKB(skb)->vcc = vcc; skb->mac.raw = skb->data; if (!clip_vcc->encap || skb->len < RFC1483LLC_LEN || memcmp(skb->data, llc_oui,sizeof(llc_oui))) skb->protocol = htons(ETH_P_IP); if (!clip_vcc->encap || skb->len < RFC1483LLC_LEN || memcmp(skb->data, llc_oui, sizeof (llc_oui))) skb->protocol = htons(ETH_P_IP); else { skb->protocol = ((u16 *) skb->data)[3]; skb_pull(skb, RFC1483LLC_LEN); Loading @@ -233,13 +236,11 @@ static void clip_push(struct atm_vcc *vcc,struct sk_buff *skb) netif_rx(skb); } /* * Note: these spinlocks _must_not_ block on non-SMP. The only goal is that * clip_pop is atomic with respect to the critical section in clip_start_xmit. */ static void clip_pop(struct atm_vcc *vcc, struct sk_buff *skb) { struct clip_vcc *clip_vcc = CLIP_VCC(vcc); Loading @@ -250,16 +251,17 @@ static void clip_pop(struct atm_vcc *vcc,struct sk_buff *skb) DPRINTK("clip_pop(vcc %p)\n", vcc); clip_vcc->old_pop(vcc, skb); /* skb->dev == NULL in outbound ARP packets */ if (!dev) return; if (!dev) return; spin_lock_irqsave(&PRIV(dev)->xoff_lock, flags); if (atm_may_send(vcc, 0)) { old = xchg(&clip_vcc->xoff, 0); if (old) netif_wake_queue(dev); if (old) netif_wake_queue(dev); } spin_unlock_irqrestore(&PRIV(dev)->xoff_lock, flags); } static void clip_neigh_destroy(struct neighbour *neigh) { DPRINTK("clip_neigh_destroy (neigh %p)\n", neigh); Loading @@ -268,14 +270,12 @@ static void clip_neigh_destroy(struct neighbour *neigh) NEIGH2ENTRY(neigh)->vccs = (void *) 0xdeadbeef; } static void clip_neigh_solicit(struct neighbour *neigh, struct sk_buff *skb) { DPRINTK("clip_neigh_solicit (neigh %p, skb %p)\n", neigh, skb); to_atmarpd(act_need, PRIV(neigh->dev)->number, NEIGH2ENTRY(neigh)->ip); } static void clip_neigh_error(struct neighbour *neigh, struct sk_buff *skb) { #ifndef CONFIG_ATM_CLIP_NO_ICMP Loading @@ -284,7 +284,6 @@ static void clip_neigh_error(struct neighbour *neigh,struct sk_buff *skb) kfree_skb(skb); } static struct neigh_ops clip_neigh_ops = { .family = AF_INET, .solicit = clip_neigh_solicit, Loading @@ -295,7 +294,6 @@ static struct neigh_ops clip_neigh_ops = { .queue_xmit = dev_queue_xmit, }; static int clip_constructor(struct neighbour *neigh) { struct atmarp_entry *entry = NEIGH2ENTRY(neigh); Loading @@ -305,7 +303,8 @@ static int clip_constructor(struct neighbour *neigh) DPRINTK("clip_constructor (neigh %p, entry %p)\n", neigh, entry); neigh->type = inet_addr_type(entry->ip); if (neigh->type != RTN_UNICAST) return -EINVAL; if (neigh->type != RTN_UNICAST) return -EINVAL; rcu_read_lock(); in_dev = __in_dev_get_rcu(dev); Loading Loading @@ -364,7 +363,6 @@ static struct neigh_table clip_tbl = { .gc_thresh3 = 1024, }; /* @@@ copy bh locking from arp.c -- need to bh-enable atm code before */ /* Loading @@ -374,14 +372,12 @@ static struct neigh_table clip_tbl = { * clip_setentry. */ static int clip_encap(struct atm_vcc *vcc, int mode) { CLIP_VCC(vcc)->encap = mode; return 0; } static int clip_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct clip_priv *clip_priv = PRIV(dev); Loading Loading @@ -465,22 +461,22 @@ static int clip_start_xmit(struct sk_buff *skb,struct net_device *dev) return 0; } static struct net_device_stats *clip_get_stats(struct net_device *dev) { return &PRIV(dev)->stats; } static int clip_mkip(struct atm_vcc *vcc, int timeout) { struct clip_vcc *clip_vcc; struct sk_buff_head copy; struct sk_buff *skb; if (!vcc->push) return -EBADFD; if (!vcc->push) return -EBADFD; clip_vcc = kmalloc(sizeof(struct clip_vcc), GFP_KERNEL); if (!clip_vcc) return -ENOMEM; if (!clip_vcc) return -ENOMEM; DPRINTK("mkip clip_vcc %p vcc %p\n", clip_vcc, vcc); clip_vcc->vcc = vcc; vcc->user_back = clip_vcc; Loading @@ -501,8 +497,7 @@ static int clip_mkip(struct atm_vcc *vcc,int timeout) if (!clip_devs) { atm_return(vcc, skb->truesize); kfree_skb(skb); } else { } else { unsigned int len = skb->len; clip_push(vcc, skb); Loading @@ -512,7 +507,6 @@ static int clip_mkip(struct atm_vcc *vcc,int timeout) return 0; } static int clip_setentry(struct atm_vcc *vcc, u32 ip) { struct neighbour *neigh; Loading @@ -537,14 +531,16 @@ static int clip_setentry(struct atm_vcc *vcc,u32 ip) return 0; } error = ip_route_output_key(&rt, &fl); if (error) return error; if (error) return error; neigh = __neigh_lookup(&clip_tbl, &ip, rt->u.dst.dev, 1); ip_rt_put(rt); if (!neigh) return -ENOMEM; entry = NEIGH2ENTRY(neigh); if (entry != clip_vcc->entry) { if (!clip_vcc->entry) DPRINTK("setentry: add\n"); if (!clip_vcc->entry) DPRINTK("setentry: add\n"); else { DPRINTK("setentry: update\n"); unlink_clip_vcc(clip_vcc); Loading @@ -557,7 +553,6 @@ static int clip_setentry(struct atm_vcc *vcc,u32 ip) return error; } static void clip_setup(struct net_device *dev) { dev->hard_start_xmit = clip_start_xmit; Loading @@ -574,7 +569,6 @@ static void clip_setup(struct net_device *dev) /* against memory hogs. */ } static int clip_create(int number) { struct net_device *dev; Loading @@ -583,9 +577,9 @@ static int clip_create(int number) if (number != -1) { for (dev = clip_devs; dev; dev = PRIV(dev)->next) if (PRIV(dev)->number == number) return -EEXIST; } else { if (PRIV(dev)->number == number) return -EEXIST; } else { number = 0; for (dev = clip_devs; dev; dev = PRIV(dev)->next) if (PRIV(dev)->number >= number) Loading @@ -609,7 +603,6 @@ static int clip_create(int number) return number; } static int clip_device_event(struct notifier_block *this, unsigned long event, void *arg) { Loading Loading @@ -652,7 +645,6 @@ static int clip_device_event(struct notifier_block *this,unsigned long event, return NOTIFY_DONE; } static int clip_inet_event(struct notifier_block *this, unsigned long event, void *ifa) { Loading @@ -667,7 +659,8 @@ static int clip_inet_event(struct notifier_block *this,unsigned long event, * Transitions are of the down-change-up type, so it's sufficient to * handle the change on up. */ if (event != NETDEV_UP) return NOTIFY_DONE; if (event != NETDEV_UP) return NOTIFY_DONE; return clip_device_event(this, NETDEV_CHANGE, in_dev->dev); } Loading Loading @@ -828,8 +821,7 @@ static void atmarp_info(struct seq_file *seq, struct net_device *dev, svc = ((clip_vcc == SEQ_NO_VCC_TOKEN) || (sk_atm(clip_vcc->vcc)->sk_family == AF_ATMSVC)); llc = ((clip_vcc == SEQ_NO_VCC_TOKEN) || clip_vcc->encap); llc = ((clip_vcc == SEQ_NO_VCC_TOKEN) || clip_vcc->encap); if (clip_vcc == SEQ_NO_VCC_TOKEN) exp = entry->neigh->used; Loading @@ -839,10 +831,7 @@ static void atmarp_info(struct seq_file *seq, struct net_device *dev, exp = (jiffies - exp) / HZ; seq_printf(seq, "%-6s%-4s%-4s%5ld ", dev->name, svc ? "SVC" : "PVC", llc ? "LLC" : "NULL", exp); dev->name, svc ? "SVC" : "PVC", llc ? "LLC" : "NULL", exp); off = scnprintf(buf, sizeof(buf) - 1, "%d.%d.%d.%d", NIPQUAD(entry->ip)); Loading @@ -860,8 +849,7 @@ static void atmarp_info(struct seq_file *seq, struct net_device *dev, } else if (!svc) { seq_printf(seq, "%d.%d.%d\n", clip_vcc->vcc->dev->number, clip_vcc->vcc->vpi, clip_vcc->vcc->vci); clip_vcc->vcc->vpi, clip_vcc->vcc->vci); } else { svc_addr(seq, &clip_vcc->vcc->remote); seq_putc(seq, '\n'); Loading Loading
net/atm/clip.c +199 −211 Original line number Diff line number Diff line Loading @@ -2,7 +2,6 @@ /* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ #include <linux/config.h> #include <linux/string.h> #include <linux/errno.h> Loading Loading @@ -62,9 +61,11 @@ static int to_atmarpd(enum atmarp_ctrl_type type,int itf,unsigned long ip) struct sk_buff *skb; DPRINTK("to_atmarpd(%d)\n", type); if (!atmarpd) return -EUNATCH; if (!atmarpd) return -EUNATCH; skb = alloc_skb(sizeof(struct atmarp_ctrl),GFP_ATOMIC); if (!skb) return -ENOMEM; if (!skb) return -ENOMEM; ctrl = (struct atmarp_ctrl *) skb_put(skb,sizeof(struct atmarp_ctrl)); ctrl->type = type; ctrl->itf_num = itf; Loading @@ -77,7 +78,6 @@ static int to_atmarpd(enum atmarp_ctrl_type type,int itf,unsigned long ip) return 0; } static void link_vcc(struct clip_vcc *clip_vcc, struct atmarp_entry *entry) { DPRINTK("link_vcc %p to entry %p (neigh %p)\n", clip_vcc, entry, Loading @@ -89,7 +89,6 @@ static void link_vcc(struct clip_vcc *clip_vcc,struct atmarp_entry *entry) entry->neigh->used = jiffies; } static void unlink_clip_vcc(struct clip_vcc *clip_vcc) { struct atmarp_entry *entry = clip_vcc->entry; Loading Loading @@ -191,7 +190,8 @@ static const unsigned char llc_oui[] = { 0x03, /* Ctrl: Unnumbered Information Command PDU */ 0x00, /* OUI: EtherType */ 0x00, 0x00 }; 0x00 }; static void clip_push(struct atm_vcc *vcc, struct sk_buff *skb) { Loading @@ -200,7 +200,8 @@ static void clip_push(struct atm_vcc *vcc,struct sk_buff *skb) DPRINTK("clip push\n"); if (!skb) { DPRINTK("removing VCC %p\n", clip_vcc); if (clip_vcc->entry) unlink_clip_vcc(clip_vcc); if (clip_vcc->entry) unlink_clip_vcc(clip_vcc); clip_vcc->old_push(vcc, NULL); /* pass on the bad news */ kfree(clip_vcc); return; Loading @@ -214,8 +215,10 @@ static void clip_push(struct atm_vcc *vcc,struct sk_buff *skb) } ATM_SKB(skb)->vcc = vcc; skb->mac.raw = skb->data; if (!clip_vcc->encap || skb->len < RFC1483LLC_LEN || memcmp(skb->data, llc_oui,sizeof(llc_oui))) skb->protocol = htons(ETH_P_IP); if (!clip_vcc->encap || skb->len < RFC1483LLC_LEN || memcmp(skb->data, llc_oui, sizeof (llc_oui))) skb->protocol = htons(ETH_P_IP); else { skb->protocol = ((u16 *) skb->data)[3]; skb_pull(skb, RFC1483LLC_LEN); Loading @@ -233,13 +236,11 @@ static void clip_push(struct atm_vcc *vcc,struct sk_buff *skb) netif_rx(skb); } /* * Note: these spinlocks _must_not_ block on non-SMP. The only goal is that * clip_pop is atomic with respect to the critical section in clip_start_xmit. */ static void clip_pop(struct atm_vcc *vcc, struct sk_buff *skb) { struct clip_vcc *clip_vcc = CLIP_VCC(vcc); Loading @@ -250,16 +251,17 @@ static void clip_pop(struct atm_vcc *vcc,struct sk_buff *skb) DPRINTK("clip_pop(vcc %p)\n", vcc); clip_vcc->old_pop(vcc, skb); /* skb->dev == NULL in outbound ARP packets */ if (!dev) return; if (!dev) return; spin_lock_irqsave(&PRIV(dev)->xoff_lock, flags); if (atm_may_send(vcc, 0)) { old = xchg(&clip_vcc->xoff, 0); if (old) netif_wake_queue(dev); if (old) netif_wake_queue(dev); } spin_unlock_irqrestore(&PRIV(dev)->xoff_lock, flags); } static void clip_neigh_destroy(struct neighbour *neigh) { DPRINTK("clip_neigh_destroy (neigh %p)\n", neigh); Loading @@ -268,14 +270,12 @@ static void clip_neigh_destroy(struct neighbour *neigh) NEIGH2ENTRY(neigh)->vccs = (void *) 0xdeadbeef; } static void clip_neigh_solicit(struct neighbour *neigh, struct sk_buff *skb) { DPRINTK("clip_neigh_solicit (neigh %p, skb %p)\n", neigh, skb); to_atmarpd(act_need, PRIV(neigh->dev)->number, NEIGH2ENTRY(neigh)->ip); } static void clip_neigh_error(struct neighbour *neigh, struct sk_buff *skb) { #ifndef CONFIG_ATM_CLIP_NO_ICMP Loading @@ -284,7 +284,6 @@ static void clip_neigh_error(struct neighbour *neigh,struct sk_buff *skb) kfree_skb(skb); } static struct neigh_ops clip_neigh_ops = { .family = AF_INET, .solicit = clip_neigh_solicit, Loading @@ -295,7 +294,6 @@ static struct neigh_ops clip_neigh_ops = { .queue_xmit = dev_queue_xmit, }; static int clip_constructor(struct neighbour *neigh) { struct atmarp_entry *entry = NEIGH2ENTRY(neigh); Loading @@ -305,7 +303,8 @@ static int clip_constructor(struct neighbour *neigh) DPRINTK("clip_constructor (neigh %p, entry %p)\n", neigh, entry); neigh->type = inet_addr_type(entry->ip); if (neigh->type != RTN_UNICAST) return -EINVAL; if (neigh->type != RTN_UNICAST) return -EINVAL; rcu_read_lock(); in_dev = __in_dev_get_rcu(dev); Loading Loading @@ -364,7 +363,6 @@ static struct neigh_table clip_tbl = { .gc_thresh3 = 1024, }; /* @@@ copy bh locking from arp.c -- need to bh-enable atm code before */ /* Loading @@ -374,14 +372,12 @@ static struct neigh_table clip_tbl = { * clip_setentry. */ static int clip_encap(struct atm_vcc *vcc, int mode) { CLIP_VCC(vcc)->encap = mode; return 0; } static int clip_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct clip_priv *clip_priv = PRIV(dev); Loading Loading @@ -465,22 +461,22 @@ static int clip_start_xmit(struct sk_buff *skb,struct net_device *dev) return 0; } static struct net_device_stats *clip_get_stats(struct net_device *dev) { return &PRIV(dev)->stats; } static int clip_mkip(struct atm_vcc *vcc, int timeout) { struct clip_vcc *clip_vcc; struct sk_buff_head copy; struct sk_buff *skb; if (!vcc->push) return -EBADFD; if (!vcc->push) return -EBADFD; clip_vcc = kmalloc(sizeof(struct clip_vcc), GFP_KERNEL); if (!clip_vcc) return -ENOMEM; if (!clip_vcc) return -ENOMEM; DPRINTK("mkip clip_vcc %p vcc %p\n", clip_vcc, vcc); clip_vcc->vcc = vcc; vcc->user_back = clip_vcc; Loading @@ -501,8 +497,7 @@ static int clip_mkip(struct atm_vcc *vcc,int timeout) if (!clip_devs) { atm_return(vcc, skb->truesize); kfree_skb(skb); } else { } else { unsigned int len = skb->len; clip_push(vcc, skb); Loading @@ -512,7 +507,6 @@ static int clip_mkip(struct atm_vcc *vcc,int timeout) return 0; } static int clip_setentry(struct atm_vcc *vcc, u32 ip) { struct neighbour *neigh; Loading @@ -537,14 +531,16 @@ static int clip_setentry(struct atm_vcc *vcc,u32 ip) return 0; } error = ip_route_output_key(&rt, &fl); if (error) return error; if (error) return error; neigh = __neigh_lookup(&clip_tbl, &ip, rt->u.dst.dev, 1); ip_rt_put(rt); if (!neigh) return -ENOMEM; entry = NEIGH2ENTRY(neigh); if (entry != clip_vcc->entry) { if (!clip_vcc->entry) DPRINTK("setentry: add\n"); if (!clip_vcc->entry) DPRINTK("setentry: add\n"); else { DPRINTK("setentry: update\n"); unlink_clip_vcc(clip_vcc); Loading @@ -557,7 +553,6 @@ static int clip_setentry(struct atm_vcc *vcc,u32 ip) return error; } static void clip_setup(struct net_device *dev) { dev->hard_start_xmit = clip_start_xmit; Loading @@ -574,7 +569,6 @@ static void clip_setup(struct net_device *dev) /* against memory hogs. */ } static int clip_create(int number) { struct net_device *dev; Loading @@ -583,9 +577,9 @@ static int clip_create(int number) if (number != -1) { for (dev = clip_devs; dev; dev = PRIV(dev)->next) if (PRIV(dev)->number == number) return -EEXIST; } else { if (PRIV(dev)->number == number) return -EEXIST; } else { number = 0; for (dev = clip_devs; dev; dev = PRIV(dev)->next) if (PRIV(dev)->number >= number) Loading @@ -609,7 +603,6 @@ static int clip_create(int number) return number; } static int clip_device_event(struct notifier_block *this, unsigned long event, void *arg) { Loading Loading @@ -652,7 +645,6 @@ static int clip_device_event(struct notifier_block *this,unsigned long event, return NOTIFY_DONE; } static int clip_inet_event(struct notifier_block *this, unsigned long event, void *ifa) { Loading @@ -667,7 +659,8 @@ static int clip_inet_event(struct notifier_block *this,unsigned long event, * Transitions are of the down-change-up type, so it's sufficient to * handle the change on up. */ if (event != NETDEV_UP) return NOTIFY_DONE; if (event != NETDEV_UP) return NOTIFY_DONE; return clip_device_event(this, NETDEV_CHANGE, in_dev->dev); } Loading Loading @@ -828,8 +821,7 @@ static void atmarp_info(struct seq_file *seq, struct net_device *dev, svc = ((clip_vcc == SEQ_NO_VCC_TOKEN) || (sk_atm(clip_vcc->vcc)->sk_family == AF_ATMSVC)); llc = ((clip_vcc == SEQ_NO_VCC_TOKEN) || clip_vcc->encap); llc = ((clip_vcc == SEQ_NO_VCC_TOKEN) || clip_vcc->encap); if (clip_vcc == SEQ_NO_VCC_TOKEN) exp = entry->neigh->used; Loading @@ -839,10 +831,7 @@ static void atmarp_info(struct seq_file *seq, struct net_device *dev, exp = (jiffies - exp) / HZ; seq_printf(seq, "%-6s%-4s%-4s%5ld ", dev->name, svc ? "SVC" : "PVC", llc ? "LLC" : "NULL", exp); dev->name, svc ? "SVC" : "PVC", llc ? "LLC" : "NULL", exp); off = scnprintf(buf, sizeof(buf) - 1, "%d.%d.%d.%d", NIPQUAD(entry->ip)); Loading @@ -860,8 +849,7 @@ static void atmarp_info(struct seq_file *seq, struct net_device *dev, } else if (!svc) { seq_printf(seq, "%d.%d.%d\n", clip_vcc->vcc->dev->number, clip_vcc->vcc->vpi, clip_vcc->vcc->vci); clip_vcc->vcc->vpi, clip_vcc->vcc->vci); } else { svc_addr(seq, &clip_vcc->vcc->remote); seq_putc(seq, '\n'); Loading