Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]

Diff markup

Differences between /linux/net/atm/clip.c (Version 2.6.11.8) and /linux/net/atm/clip.c (Version 2.6.25)


  1 /* net/atm/clip.c - RFC1577 Classical IP over       1 /* net/atm/clip.c - RFC1577 Classical IP over ATM */
  2                                                     2 
  3 /* Written 1995-2000 by Werner Almesberger, EP      3 /* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
  4                                                     4 
  5                                                << 
  6 #include <linux/config.h>                      << 
  7 #include <linux/string.h>                           5 #include <linux/string.h>
  8 #include <linux/errno.h>                            6 #include <linux/errno.h>
  9 #include <linux/kernel.h> /* for UINT_MAX */        7 #include <linux/kernel.h> /* for UINT_MAX */
 10 #include <linux/module.h>                           8 #include <linux/module.h>
 11 #include <linux/init.h>                             9 #include <linux/init.h>
 12 #include <linux/netdevice.h>                       10 #include <linux/netdevice.h>
 13 #include <linux/skbuff.h>                          11 #include <linux/skbuff.h>
 14 #include <linux/wait.h>                            12 #include <linux/wait.h>
 15 #include <linux/timer.h>                           13 #include <linux/timer.h>
 16 #include <linux/if_arp.h> /* for some manifest     14 #include <linux/if_arp.h> /* for some manifest constants */
 17 #include <linux/notifier.h>                        15 #include <linux/notifier.h>
 18 #include <linux/atm.h>                             16 #include <linux/atm.h>
 19 #include <linux/atmdev.h>                          17 #include <linux/atmdev.h>
 20 #include <linux/atmclip.h>                         18 #include <linux/atmclip.h>
 21 #include <linux/atmarp.h>                          19 #include <linux/atmarp.h>
                                                   >>  20 #include <linux/capability.h>
 22 #include <linux/ip.h> /* for net/route.h */        21 #include <linux/ip.h> /* for net/route.h */
 23 #include <linux/in.h> /* for struct sockaddr_i     22 #include <linux/in.h> /* for struct sockaddr_in */
 24 #include <linux/if.h> /* for IFF_UP */             23 #include <linux/if.h> /* for IFF_UP */
 25 #include <linux/inetdevice.h>                      24 #include <linux/inetdevice.h>
 26 #include <linux/bitops.h>                          25 #include <linux/bitops.h>
                                                   >>  26 #include <linux/poison.h>
 27 #include <linux/proc_fs.h>                         27 #include <linux/proc_fs.h>
 28 #include <linux/seq_file.h>                        28 #include <linux/seq_file.h>
 29 #include <linux/rcupdate.h>                        29 #include <linux/rcupdate.h>
 30 #include <linux/jhash.h>                           30 #include <linux/jhash.h>
 31 #include <net/route.h> /* for struct rtable an     31 #include <net/route.h> /* for struct rtable and routing */
 32 #include <net/icmp.h> /* icmp_send */              32 #include <net/icmp.h> /* icmp_send */
 33 #include <asm/param.h> /* for HZ */                33 #include <asm/param.h> /* for HZ */
 34 #include <asm/byteorder.h> /* for htons etc. *     34 #include <asm/byteorder.h> /* for htons etc. */
 35 #include <asm/system.h> /* save/restore_flags      35 #include <asm/system.h> /* save/restore_flags */
 36 #include <asm/uaccess.h>                           36 #include <asm/uaccess.h>
 37 #include <asm/atomic.h>                            37 #include <asm/atomic.h>
 38                                                    38 
 39 #include "common.h"                                39 #include "common.h"
 40 #include "resources.h"                             40 #include "resources.h"
 41 #include "ipcommon.h"                          << 
 42 #include <net/atmclip.h>                           41 #include <net/atmclip.h>
 43                                                    42 
 44                                                << 
 45 #if 0                                          << 
 46 #define DPRINTK(format,args...) printk(format, << 
 47 #else                                          << 
 48 #define DPRINTK(format,args...)                << 
 49 #endif                                         << 
 50                                                << 
 51                                                << 
 52 static struct net_device *clip_devs;               43 static struct net_device *clip_devs;
 53 static struct atm_vcc *atmarpd;                    44 static struct atm_vcc *atmarpd;
 54 static struct neigh_table clip_tbl;                45 static struct neigh_table clip_tbl;
 55 static struct timer_list idle_timer;               46 static struct timer_list idle_timer;
 56 static int start_timer = 1;                    << 
 57                                                    47 
 58                                                !!  48 static int to_atmarpd(enum atmarp_ctrl_type type, int itf, __be32 ip)
 59 static int to_atmarpd(enum atmarp_ctrl_type ty << 
 60 {                                                  49 {
                                                   >>  50         struct sock *sk;
 61         struct atmarp_ctrl *ctrl;                  51         struct atmarp_ctrl *ctrl;
 62         struct sk_buff *skb;                       52         struct sk_buff *skb;
 63                                                    53 
 64         DPRINTK("to_atmarpd(%d)\n",type);      !!  54         pr_debug("to_atmarpd(%d)\n", type);
 65         if (!atmarpd) return -EUNATCH;         !!  55         if (!atmarpd)
                                                   >>  56                 return -EUNATCH;
 66         skb = alloc_skb(sizeof(struct atmarp_c     57         skb = alloc_skb(sizeof(struct atmarp_ctrl),GFP_ATOMIC);
 67         if (!skb) return -ENOMEM;              !!  58         if (!skb)
                                                   >>  59                 return -ENOMEM;
 68         ctrl = (struct atmarp_ctrl *) skb_put(     60         ctrl = (struct atmarp_ctrl *) skb_put(skb,sizeof(struct atmarp_ctrl));
 69         ctrl->type = type;                         61         ctrl->type = type;
 70         ctrl->itf_num = itf;                       62         ctrl->itf_num = itf;
 71         ctrl->ip = ip;                             63         ctrl->ip = ip;
 72         atm_force_charge(atmarpd,skb->truesize !!  64         atm_force_charge(atmarpd, skb->truesize);
 73         skb_queue_tail(&atmarpd->sk->sk_receiv !!  65 
 74         atmarpd->sk->sk_data_ready(atmarpd->sk !!  66         sk = sk_atm(atmarpd);
                                                   >>  67         skb_queue_tail(&sk->sk_receive_queue, skb);
                                                   >>  68         sk->sk_data_ready(sk, skb->len);
 75         return 0;                                  69         return 0;
 76 }                                                  70 }
 77                                                    71 
 78                                                !!  72 static void link_vcc(struct clip_vcc *clip_vcc, struct atmarp_entry *entry)
 79 static void link_vcc(struct clip_vcc *clip_vcc << 
 80 {                                                  73 {
 81         DPRINTK("link_vcc %p to entry %p (neig !!  74         pr_debug("link_vcc %p to entry %p (neigh %p)\n", clip_vcc, entry,
 82             entry->neigh);                     !!  75                 entry->neigh);
 83         clip_vcc->entry = entry;                   76         clip_vcc->entry = entry;
 84         clip_vcc->xoff = 0; /* @@@ may overrun !!  77         clip_vcc->xoff = 0;     /* @@@ may overrun buffer by one packet */
 85         clip_vcc->next = entry->vccs;              78         clip_vcc->next = entry->vccs;
 86         entry->vccs = clip_vcc;                    79         entry->vccs = clip_vcc;
 87         entry->neigh->used = jiffies;              80         entry->neigh->used = jiffies;
 88 }                                                  81 }
 89                                                    82 
 90                                                << 
 91 static void unlink_clip_vcc(struct clip_vcc *c     83 static void unlink_clip_vcc(struct clip_vcc *clip_vcc)
 92 {                                                  84 {
 93         struct atmarp_entry *entry = clip_vcc-     85         struct atmarp_entry *entry = clip_vcc->entry;
 94         struct clip_vcc **walk;                    86         struct clip_vcc **walk;
 95                                                    87 
 96         if (!entry) {                              88         if (!entry) {
 97                 printk(KERN_CRIT "!clip_vcc->e !!  89                 printk(KERN_CRIT "!clip_vcc->entry (clip_vcc %p)\n", clip_vcc);
 98                 return;                            90                 return;
 99         }                                          91         }
100         spin_lock_bh(&entry->neigh->dev->xmit_ !!  92         netif_tx_lock_bh(entry->neigh->dev);    /* block clip_start_xmit() */
101         entry->neigh->used = jiffies;              93         entry->neigh->used = jiffies;
102         for (walk = &entry->vccs; *walk; walk      94         for (walk = &entry->vccs; *walk; walk = &(*walk)->next)
103                 if (*walk == clip_vcc) {           95                 if (*walk == clip_vcc) {
104                         int error;                 96                         int error;
105                                                    97 
106                         *walk = clip_vcc->next !!  98                         *walk = clip_vcc->next; /* atomic */
107                         clip_vcc->entry = NULL     99                         clip_vcc->entry = NULL;
108                         if (clip_vcc->xoff)       100                         if (clip_vcc->xoff)
109                                 netif_wake_que    101                                 netif_wake_queue(entry->neigh->dev);
110                         if (entry->vccs)          102                         if (entry->vccs)
111                                 goto out;         103                                 goto out;
112                         entry->expires = jiffi !! 104                         entry->expires = jiffies - 1;
113                                 /* force resol !! 105                         /* force resolution or expiration */
114                         error = neigh_update(e    106                         error = neigh_update(entry->neigh, NULL, NUD_NONE,
115                                              N    107                                              NEIGH_UPDATE_F_ADMIN);
116                         if (error)                108                         if (error)
117                                 printk(KERN_CR    109                                 printk(KERN_CRIT "unlink_clip_vcc: "
118                                     "neigh_upd !! 110                                        "neigh_update failed with %d\n", error);
119                         goto out;                 111                         goto out;
120                 }                                 112                 }
121         printk(KERN_CRIT "ATMARP: unlink_clip_    113         printk(KERN_CRIT "ATMARP: unlink_clip_vcc failed (entry %p, vcc "
122           "0x%p)\n",entry,clip_vcc);           !! 114                "0x%p)\n", entry, clip_vcc);
123 out:                                           !! 115       out:
124         spin_unlock_bh(&entry->neigh->dev->xmi !! 116         netif_tx_unlock_bh(entry->neigh->dev);
125 }                                                 117 }
126                                                   118 
127 /* The neighbour entry n->lock is held. */        119 /* The neighbour entry n->lock is held. */
128 static int neigh_check_cb(struct neighbour *n)    120 static int neigh_check_cb(struct neighbour *n)
129 {                                                 121 {
130         struct atmarp_entry *entry = NEIGH2ENT    122         struct atmarp_entry *entry = NEIGH2ENTRY(n);
131         struct clip_vcc *cv;                      123         struct clip_vcc *cv;
132                                                   124 
133         for (cv = entry->vccs; cv; cv = cv->ne    125         for (cv = entry->vccs; cv; cv = cv->next) {
134                 unsigned long exp = cv->last_u    126                 unsigned long exp = cv->last_use + cv->idle_timeout;
135                                                   127 
136                 if (cv->idle_timeout && time_a    128                 if (cv->idle_timeout && time_after(jiffies, exp)) {
137                         DPRINTK("releasing vcc !! 129                         pr_debug("releasing vcc %p->%p of entry %p\n",
138                                 cv, cv->vcc, e    130                                 cv, cv->vcc, entry);
139                         vcc_release_async(cv->    131                         vcc_release_async(cv->vcc, -ETIMEDOUT);
140                 }                                 132                 }
141         }                                         133         }
142                                                   134 
143         if (entry->vccs || time_before(jiffies    135         if (entry->vccs || time_before(jiffies, entry->expires))
144                 return 0;                         136                 return 0;
145                                                   137 
146         if (atomic_read(&n->refcnt) > 1) {        138         if (atomic_read(&n->refcnt) > 1) {
147                 struct sk_buff *skb;              139                 struct sk_buff *skb;
148                                                   140 
149                 DPRINTK("destruction postponed !! 141                 pr_debug("destruction postponed with ref %d\n",
150                         atomic_read(&n->refcnt    142                         atomic_read(&n->refcnt));
151                                                   143 
152                 while ((skb = skb_dequeue(&n-> !! 144                 while ((skb = skb_dequeue(&n->arp_queue)) != NULL)
153                         dev_kfree_skb(skb);       145                         dev_kfree_skb(skb);
154                                                   146 
155                 return 0;                         147                 return 0;
156         }                                         148         }
157                                                   149 
158         DPRINTK("expired neigh %p\n",n);       !! 150         pr_debug("expired neigh %p\n", n);
159         return 1;                                 151         return 1;
160 }                                                 152 }
161                                                   153 
162 static void idle_timer_check(unsigned long dum    154 static void idle_timer_check(unsigned long dummy)
163 {                                                 155 {
164         write_lock(&clip_tbl.lock);               156         write_lock(&clip_tbl.lock);
165         __neigh_for_each_release(&clip_tbl, ne    157         __neigh_for_each_release(&clip_tbl, neigh_check_cb);
166         mod_timer(&idle_timer, jiffies+CLIP_CH !! 158         mod_timer(&idle_timer, jiffies + CLIP_CHECK_INTERVAL * HZ);
167         write_unlock(&clip_tbl.lock);             159         write_unlock(&clip_tbl.lock);
168 }                                                 160 }
169                                                   161 
170 static int clip_arp_rcv(struct sk_buff *skb)      162 static int clip_arp_rcv(struct sk_buff *skb)
171 {                                                 163 {
172         struct atm_vcc *vcc;                      164         struct atm_vcc *vcc;
173                                                   165 
174         DPRINTK("clip_arp_rcv\n");             !! 166         pr_debug("clip_arp_rcv\n");
175         vcc = ATM_SKB(skb)->vcc;                  167         vcc = ATM_SKB(skb)->vcc;
176         if (!vcc || !atm_charge(vcc,skb->trues !! 168         if (!vcc || !atm_charge(vcc, skb->truesize)) {
177                 dev_kfree_skb_any(skb);           169                 dev_kfree_skb_any(skb);
178                 return 0;                         170                 return 0;
179         }                                         171         }
180         DPRINTK("pushing to %p\n",vcc);        !! 172         pr_debug("pushing to %p\n", vcc);
181         DPRINTK("using %p\n",CLIP_VCC(vcc)->ol !! 173         pr_debug("using %p\n", CLIP_VCC(vcc)->old_push);
182         CLIP_VCC(vcc)->old_push(vcc,skb);      !! 174         CLIP_VCC(vcc)->old_push(vcc, skb);
183         return 0;                                 175         return 0;
184 }                                                 176 }
185                                                   177 
186 static const unsigned char llc_oui[] = {          178 static const unsigned char llc_oui[] = {
187         0xaa,   /* DSAP: non-ISO */               179         0xaa,   /* DSAP: non-ISO */
188         0xaa,   /* SSAP: non-ISO */               180         0xaa,   /* SSAP: non-ISO */
189         0x03,   /* Ctrl: Unnumbered Informatio    181         0x03,   /* Ctrl: Unnumbered Information Command PDU */
190         0x00,   /* OUI: EtherType */              182         0x00,   /* OUI: EtherType */
191         0x00,                                     183         0x00,
192         0x00 };                                !! 184         0x00
                                                   >> 185 };
193                                                   186 
194 static void clip_push(struct atm_vcc *vcc,stru !! 187 static void clip_push(struct atm_vcc *vcc, struct sk_buff *skb)
195 {                                                 188 {
196         struct clip_vcc *clip_vcc = CLIP_VCC(v    189         struct clip_vcc *clip_vcc = CLIP_VCC(vcc);
197                                                   190 
198         DPRINTK("clip push\n");                !! 191         pr_debug("clip push\n");
199         if (!skb) {                               192         if (!skb) {
200                 DPRINTK("removing VCC %p\n",cl !! 193                 pr_debug("removing VCC %p\n", clip_vcc);
201                 if (clip_vcc->entry) unlink_cl !! 194                 if (clip_vcc->entry)
202                 clip_vcc->old_push(vcc,NULL);  !! 195                         unlink_clip_vcc(clip_vcc);
                                                   >> 196                 clip_vcc->old_push(vcc, NULL);  /* pass on the bad news */
203                 kfree(clip_vcc);                  197                 kfree(clip_vcc);
204                 return;                           198                 return;
205         }                                         199         }
206         atm_return(vcc,skb->truesize);         !! 200         atm_return(vcc, skb->truesize);
207         skb->dev = clip_vcc->entry ? clip_vcc-    201         skb->dev = clip_vcc->entry ? clip_vcc->entry->neigh->dev : clip_devs;
208                 /* clip_vcc->entry == NULL if  !! 202         /* clip_vcc->entry == NULL if we don't have an IP address yet */
209         if (!skb->dev) {                          203         if (!skb->dev) {
210                 dev_kfree_skb_any(skb);           204                 dev_kfree_skb_any(skb);
211                 return;                           205                 return;
212         }                                         206         }
213         ATM_SKB(skb)->vcc = vcc;                  207         ATM_SKB(skb)->vcc = vcc;
214         skb->mac.raw = skb->data;              !! 208         skb_reset_mac_header(skb);
215         if (!clip_vcc->encap || skb->len < RFC !! 209         if (!clip_vcc->encap
216             llc_oui,sizeof(llc_oui))) skb->pro !! 210             || skb->len < RFC1483LLC_LEN
                                                   >> 211             || memcmp(skb->data, llc_oui, sizeof (llc_oui)))
                                                   >> 212                 skb->protocol = htons(ETH_P_IP);
217         else {                                    213         else {
218                 skb->protocol = ((u16 *) skb-> !! 214                 skb->protocol = ((__be16 *) skb->data)[3];
219                 skb_pull(skb,RFC1483LLC_LEN);  !! 215                 skb_pull(skb, RFC1483LLC_LEN);
220                 if (skb->protocol == htons(ETH    216                 if (skb->protocol == htons(ETH_P_ARP)) {
221                         PRIV(skb->dev)->stats.    217                         PRIV(skb->dev)->stats.rx_packets++;
222                         PRIV(skb->dev)->stats.    218                         PRIV(skb->dev)->stats.rx_bytes += skb->len;
223                         clip_arp_rcv(skb);        219                         clip_arp_rcv(skb);
224                         return;                   220                         return;
225                 }                                 221                 }
226         }                                         222         }
227         clip_vcc->last_use = jiffies;             223         clip_vcc->last_use = jiffies;
228         PRIV(skb->dev)->stats.rx_packets++;       224         PRIV(skb->dev)->stats.rx_packets++;
229         PRIV(skb->dev)->stats.rx_bytes += skb-    225         PRIV(skb->dev)->stats.rx_bytes += skb->len;
230         memset(ATM_SKB(skb), 0, sizeof(struct     226         memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data));
231         netif_rx(skb);                            227         netif_rx(skb);
232 }                                                 228 }
233                                                   229 
234                                                << 
235 /*                                                230 /*
236  * Note: these spinlocks _must_not_ block on n    231  * Note: these spinlocks _must_not_ block on non-SMP. The only goal is that
237  * clip_pop is atomic with respect to the crit    232  * clip_pop is atomic with respect to the critical section in clip_start_xmit.
238  */                                               233  */
239                                                   234 
240                                                !! 235 static void clip_pop(struct atm_vcc *vcc, struct sk_buff *skb)
241 static void clip_pop(struct atm_vcc *vcc,struc << 
242 {                                                 236 {
243         struct clip_vcc *clip_vcc = CLIP_VCC(v    237         struct clip_vcc *clip_vcc = CLIP_VCC(vcc);
244         struct net_device *dev = skb->dev;        238         struct net_device *dev = skb->dev;
245         int old;                                  239         int old;
246         unsigned long flags;                      240         unsigned long flags;
247                                                   241 
248         DPRINTK("clip_pop(vcc %p)\n",vcc);     !! 242         pr_debug("clip_pop(vcc %p)\n", vcc);
249         clip_vcc->old_pop(vcc,skb);            !! 243         clip_vcc->old_pop(vcc, skb);
250         /* skb->dev == NULL in outbound ARP pa    244         /* skb->dev == NULL in outbound ARP packets */
251         if (!dev) return;                      !! 245         if (!dev)
252         spin_lock_irqsave(&PRIV(dev)->xoff_loc !! 246                 return;
253         if (atm_may_send(vcc,0)) {             !! 247         spin_lock_irqsave(&PRIV(dev)->xoff_lock, flags);
254                 old = xchg(&clip_vcc->xoff,0); !! 248         if (atm_may_send(vcc, 0)) {
255                 if (old) netif_wake_queue(dev) !! 249                 old = xchg(&clip_vcc->xoff, 0);
                                                   >> 250                 if (old)
                                                   >> 251                         netif_wake_queue(dev);
256         }                                         252         }
257         spin_unlock_irqrestore(&PRIV(dev)->xof !! 253         spin_unlock_irqrestore(&PRIV(dev)->xoff_lock, flags);
258 }                                                 254 }
259                                                   255 
260                                                !! 256 static void clip_neigh_solicit(struct neighbour *neigh, struct sk_buff *skb)
261 static void clip_neigh_destroy(struct neighbou << 
262 {                                              << 
263         DPRINTK("clip_neigh_destroy (neigh %p) << 
264         if (NEIGH2ENTRY(neigh)->vccs)          << 
265                 printk(KERN_CRIT "clip_neigh_d << 
266         NEIGH2ENTRY(neigh)->vccs = (void *) 0x << 
267 }                                              << 
268                                                << 
269                                                << 
270 static void clip_neigh_solicit(struct neighbou << 
271 {                                                 257 {
272         DPRINTK("clip_neigh_solicit (neigh %p, !! 258         pr_debug("clip_neigh_solicit (neigh %p, skb %p)\n", neigh, skb);
273         to_atmarpd(act_need,PRIV(neigh->dev)-> !! 259         to_atmarpd(act_need, PRIV(neigh->dev)->number, NEIGH2ENTRY(neigh)->ip);
274 }                                                 260 }
275                                                   261 
276                                                !! 262 static void clip_neigh_error(struct neighbour *neigh, struct sk_buff *skb)
277 static void clip_neigh_error(struct neighbour  << 
278 {                                                 263 {
279 #ifndef CONFIG_ATM_CLIP_NO_ICMP                   264 #ifndef CONFIG_ATM_CLIP_NO_ICMP
280         icmp_send(skb,ICMP_DEST_UNREACH,ICMP_H !! 265         icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
281 #endif                                            266 #endif
282         kfree_skb(skb);                           267         kfree_skb(skb);
283 }                                                 268 }
284                                                   269 
285                                                << 
286 static struct neigh_ops clip_neigh_ops = {        270 static struct neigh_ops clip_neigh_ops = {
287         .family =               AF_INET,          271         .family =               AF_INET,
288         .destructor =           clip_neigh_des << 
289         .solicit =              clip_neigh_sol    272         .solicit =              clip_neigh_solicit,
290         .error_report =         clip_neigh_err    273         .error_report =         clip_neigh_error,
291         .output =               dev_queue_xmit    274         .output =               dev_queue_xmit,
292         .connected_output =     dev_queue_xmit    275         .connected_output =     dev_queue_xmit,
293         .hh_output =            dev_queue_xmit    276         .hh_output =            dev_queue_xmit,
294         .queue_xmit =           dev_queue_xmit    277         .queue_xmit =           dev_queue_xmit,
295 };                                                278 };
296                                                   279 
297                                                << 
298 static int clip_constructor(struct neighbour *    280 static int clip_constructor(struct neighbour *neigh)
299 {                                                 281 {
300         struct atmarp_entry *entry = NEIGH2ENT    282         struct atmarp_entry *entry = NEIGH2ENTRY(neigh);
301         struct net_device *dev = neigh->dev;      283         struct net_device *dev = neigh->dev;
302         struct in_device *in_dev;                 284         struct in_device *in_dev;
303         struct neigh_parms *parms;                285         struct neigh_parms *parms;
304                                                   286 
305         DPRINTK("clip_constructor (neigh %p, e !! 287         pr_debug("clip_constructor (neigh %p, entry %p)\n", neigh, entry);
306         neigh->type = inet_addr_type(entry->ip !! 288         neigh->type = inet_addr_type(&init_net, entry->ip);
307         if (neigh->type != RTN_UNICAST) return !! 289         if (neigh->type != RTN_UNICAST)
                                                   >> 290                 return -EINVAL;
308                                                   291 
309         rcu_read_lock();                          292         rcu_read_lock();
310         in_dev = rcu_dereference(__in_dev_get( !! 293         in_dev = __in_dev_get_rcu(dev);
311         if (!in_dev) {                            294         if (!in_dev) {
312                 rcu_read_unlock();                295                 rcu_read_unlock();
313                 return -EINVAL;                   296                 return -EINVAL;
314         }                                         297         }
315                                                   298 
316         parms = in_dev->arp_parms;                299         parms = in_dev->arp_parms;
317         __neigh_parms_put(neigh->parms);          300         __neigh_parms_put(neigh->parms);
318         neigh->parms = neigh_parms_clone(parms    301         neigh->parms = neigh_parms_clone(parms);
319         rcu_read_unlock();                        302         rcu_read_unlock();
320                                                   303 
321         neigh->ops = &clip_neigh_ops;             304         neigh->ops = &clip_neigh_ops;
322         neigh->output = neigh->nud_state & NUD    305         neigh->output = neigh->nud_state & NUD_VALID ?
323             neigh->ops->connected_output : nei    306             neigh->ops->connected_output : neigh->ops->output;
324         entry->neigh = neigh;                     307         entry->neigh = neigh;
325         entry->vccs = NULL;                       308         entry->vccs = NULL;
326         entry->expires = jiffies-1;            !! 309         entry->expires = jiffies - 1;
327         return 0;                                 310         return 0;
328 }                                                 311 }
329                                                   312 
330 static u32 clip_hash(const void *pkey, const s    313 static u32 clip_hash(const void *pkey, const struct net_device *dev)
331 {                                                 314 {
332         return jhash_2words(*(u32 *)pkey, dev- !! 315         return jhash_2words(*(u32 *) pkey, dev->ifindex, clip_tbl.hash_rnd);
333 }                                                 316 }
334                                                   317 
335 static struct neigh_table clip_tbl = {            318 static struct neigh_table clip_tbl = {
336         .family         = AF_INET,                319         .family         = AF_INET,
337         .entry_size     = sizeof(struct neighb    320         .entry_size     = sizeof(struct neighbour)+sizeof(struct atmarp_entry),
338         .key_len        = 4,                      321         .key_len        = 4,
339         .hash           = clip_hash,              322         .hash           = clip_hash,
340         .constructor    = clip_constructor,       323         .constructor    = clip_constructor,
341         .id             = "clip_arp_cache",       324         .id             = "clip_arp_cache",
342                                                   325 
343         /* parameters are copied from ARP ...     326         /* parameters are copied from ARP ... */
344         .parms = {                                327         .parms = {
345                 .tbl                    = &cli    328                 .tbl                    = &clip_tbl,
346                 .base_reachable_time    = 30 *    329                 .base_reachable_time    = 30 * HZ,
347                 .retrans_time           = 1 *     330                 .retrans_time           = 1 * HZ,
348                 .gc_staletime           = 60 *    331                 .gc_staletime           = 60 * HZ,
349                 .reachable_time         = 30 *    332                 .reachable_time         = 30 * HZ,
350                 .delay_probe_time       = 5 *     333                 .delay_probe_time       = 5 * HZ,
351                 .queue_len              = 3,      334                 .queue_len              = 3,
352                 .ucast_probes           = 3,      335                 .ucast_probes           = 3,
353                 .mcast_probes           = 3,      336                 .mcast_probes           = 3,
354                 .anycast_delay          = 1 *     337                 .anycast_delay          = 1 * HZ,
355                 .proxy_delay            = (8 *    338                 .proxy_delay            = (8 * HZ) / 10,
356                 .proxy_qlen             = 64,     339                 .proxy_qlen             = 64,
357                 .locktime               = 1 *     340                 .locktime               = 1 * HZ,
358         },                                        341         },
359         .gc_interval    = 30 * HZ,                342         .gc_interval    = 30 * HZ,
360         .gc_thresh1     = 128,                    343         .gc_thresh1     = 128,
361         .gc_thresh2     = 512,                    344         .gc_thresh2     = 512,
362         .gc_thresh3     = 1024,                   345         .gc_thresh3     = 1024,
363 };                                                346 };
364                                                   347 
365                                                << 
366 /* @@@ copy bh locking from arp.c -- need to b    348 /* @@@ copy bh locking from arp.c -- need to bh-enable atm code before */
367                                                   349 
368 /*                                                350 /*
369  * We play with the resolve flag: 0 and 1 have    351  * We play with the resolve flag: 0 and 1 have the usual meaning, but -1 means
370  * to allocate the neighbour entry but not to     352  * to allocate the neighbour entry but not to ask atmarpd for resolution. Also,
371  * don't increment the usage count. This is us    353  * don't increment the usage count. This is used to create entries in
372  * clip_setentry.                                 354  * clip_setentry.
373  */                                               355  */
374                                                   356 
375                                                !! 357 static int clip_encap(struct atm_vcc *vcc, int mode)
376 static int clip_encap(struct atm_vcc *vcc,int  << 
377 {                                                 358 {
378         CLIP_VCC(vcc)->encap = mode;              359         CLIP_VCC(vcc)->encap = mode;
379         return 0;                                 360         return 0;
380 }                                                 361 }
381                                                   362 
382                                                !! 363 static int clip_start_xmit(struct sk_buff *skb, struct net_device *dev)
383 static int clip_start_xmit(struct sk_buff *skb << 
384 {                                                 364 {
385         struct clip_priv *clip_priv = PRIV(dev    365         struct clip_priv *clip_priv = PRIV(dev);
386         struct atmarp_entry *entry;               366         struct atmarp_entry *entry;
387         struct atm_vcc *vcc;                      367         struct atm_vcc *vcc;
388         int old;                                  368         int old;
389         unsigned long flags;                      369         unsigned long flags;
390                                                   370 
391         DPRINTK("clip_start_xmit (skb %p)\n",s !! 371         pr_debug("clip_start_xmit (skb %p)\n", skb);
392         if (!skb->dst) {                          372         if (!skb->dst) {
393                 printk(KERN_ERR "clip_start_xm    373                 printk(KERN_ERR "clip_start_xmit: skb->dst == NULL\n");
394                 dev_kfree_skb(skb);               374                 dev_kfree_skb(skb);
395                 clip_priv->stats.tx_dropped++;    375                 clip_priv->stats.tx_dropped++;
396                 return 0;                         376                 return 0;
397         }                                         377         }
398         if (!skb->dst->neighbour) {               378         if (!skb->dst->neighbour) {
399 #if 0                                             379 #if 0
400                 skb->dst->neighbour = clip_fin !! 380                 skb->dst->neighbour = clip_find_neighbour(skb->dst, 1);
401                 if (!skb->dst->neighbour) {       381                 if (!skb->dst->neighbour) {
402                         dev_kfree_skb(skb); /* !! 382                         dev_kfree_skb(skb);     /* lost that one */
403                         clip_priv->stats.tx_dr    383                         clip_priv->stats.tx_dropped++;
404                         return 0;                 384                         return 0;
405                 }                                 385                 }
406 #endif                                            386 #endif
407                 printk(KERN_ERR "clip_start_xm    387                 printk(KERN_ERR "clip_start_xmit: NO NEIGHBOUR !\n");
408                 dev_kfree_skb(skb);               388                 dev_kfree_skb(skb);
409                 clip_priv->stats.tx_dropped++;    389                 clip_priv->stats.tx_dropped++;
410                 return 0;                         390                 return 0;
411         }                                         391         }
412         entry = NEIGH2ENTRY(skb->dst->neighbou    392         entry = NEIGH2ENTRY(skb->dst->neighbour);
413         if (!entry->vccs) {                       393         if (!entry->vccs) {
414                 if (time_after(jiffies, entry-    394                 if (time_after(jiffies, entry->expires)) {
415                         /* should be resolved     395                         /* should be resolved */
416                         entry->expires = jiffi !! 396                         entry->expires = jiffies + ATMARP_RETRY_DELAY * HZ;
417                         to_atmarpd(act_need,PR !! 397                         to_atmarpd(act_need, PRIV(dev)->number, entry->ip);
418                 }                                 398                 }
419                 if (entry->neigh->arp_queue.ql    399                 if (entry->neigh->arp_queue.qlen < ATMARP_MAX_UNRES_PACKETS)
420                         skb_queue_tail(&entry- !! 400                         skb_queue_tail(&entry->neigh->arp_queue, skb);
421                 else {                            401                 else {
422                         dev_kfree_skb(skb);       402                         dev_kfree_skb(skb);
423                         clip_priv->stats.tx_dr    403                         clip_priv->stats.tx_dropped++;
424                 }                                 404                 }
425                 return 0;                         405                 return 0;
426         }                                         406         }
427         DPRINTK("neigh %p, vccs %p\n",entry,en !! 407         pr_debug("neigh %p, vccs %p\n", entry, entry->vccs);
428         ATM_SKB(skb)->vcc = vcc = entry->vccs-    408         ATM_SKB(skb)->vcc = vcc = entry->vccs->vcc;
429         DPRINTK("using neighbour %p, vcc %p\n" !! 409         pr_debug("using neighbour %p, vcc %p\n", skb->dst->neighbour, vcc);
430         if (entry->vccs->encap) {                 410         if (entry->vccs->encap) {
431                 void *here;                       411                 void *here;
432                                                   412 
433                 here = skb_push(skb,RFC1483LLC !! 413                 here = skb_push(skb, RFC1483LLC_LEN);
434                 memcpy(here,llc_oui,sizeof(llc !! 414                 memcpy(here, llc_oui, sizeof(llc_oui));
435                 ((u16 *) here)[3] = skb->proto !! 415                 ((__be16 *) here)[3] = skb->protocol;
436         }                                         416         }
437         atomic_add(skb->truesize, &vcc->sk->sk !! 417         atomic_add(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc);
438         ATM_SKB(skb)->atm_options = vcc->atm_o    418         ATM_SKB(skb)->atm_options = vcc->atm_options;
439         entry->vccs->last_use = jiffies;          419         entry->vccs->last_use = jiffies;
440         DPRINTK("atm_skb(%p)->vcc(%p)->dev(%p) !! 420         pr_debug("atm_skb(%p)->vcc(%p)->dev(%p)\n", skb, vcc, vcc->dev);
441         old = xchg(&entry->vccs->xoff,1); /* a !! 421         old = xchg(&entry->vccs->xoff, 1);      /* assume XOFF ... */
442         if (old) {                                422         if (old) {
443                 printk(KERN_WARNING "clip_star    423                 printk(KERN_WARNING "clip_start_xmit: XOFF->XOFF transition\n");
444                 return 0;                         424                 return 0;
445         }                                         425         }
446         clip_priv->stats.tx_packets++;            426         clip_priv->stats.tx_packets++;
447         clip_priv->stats.tx_bytes += skb->len;    427         clip_priv->stats.tx_bytes += skb->len;
448         (void) vcc->send(vcc,skb);             !! 428         vcc->send(vcc, skb);
449         if (atm_may_send(vcc,0)) {             !! 429         if (atm_may_send(vcc, 0)) {
450                 entry->vccs->xoff = 0;            430                 entry->vccs->xoff = 0;
451                 return 0;                         431                 return 0;
452         }                                         432         }
453         spin_lock_irqsave(&clip_priv->xoff_loc !! 433         spin_lock_irqsave(&clip_priv->xoff_lock, flags);
454         netif_stop_queue(dev); /* XOFF -> thro !! 434         netif_stop_queue(dev);  /* XOFF -> throttle immediately */
455         barrier();                                435         barrier();
456         if (!entry->vccs->xoff)                   436         if (!entry->vccs->xoff)
457                 netif_start_queue(dev);           437                 netif_start_queue(dev);
458                 /* Oh, we just raced with clip !! 438         /* Oh, we just raced with clip_pop. netif_start_queue should be
459                    good enough, because nothin !! 439            good enough, because nothing should really be asleep because
460                    of the brief netif_stop_que !! 440            of the brief netif_stop_queue. If this isn't true or if it
461                    changes, use netif_wake_que !! 441            changes, use netif_wake_queue instead. */
462         spin_unlock_irqrestore(&clip_priv->xof !! 442         spin_unlock_irqrestore(&clip_priv->xoff_lock, flags);
463         return 0;                                 443         return 0;
464 }                                                 444 }
465                                                   445 
466                                                << 
467 static struct net_device_stats *clip_get_stats    446 static struct net_device_stats *clip_get_stats(struct net_device *dev)
468 {                                                 447 {
469         return &PRIV(dev)->stats;                 448         return &PRIV(dev)->stats;
470 }                                                 449 }
471                                                   450 
472                                                !! 451 static int clip_mkip(struct atm_vcc *vcc, int timeout)
473 static int clip_mkip(struct atm_vcc *vcc,int t << 
474 {                                                 452 {
475         struct clip_vcc *clip_vcc;                453         struct clip_vcc *clip_vcc;
476         struct sk_buff_head copy;              << 
477         struct sk_buff *skb;                      454         struct sk_buff *skb;
                                                   >> 455         struct sk_buff_head *rq;
                                                   >> 456         unsigned long flags;
478                                                   457 
479         if (!vcc->push) return -EBADFD;        !! 458         if (!vcc->push)
480         clip_vcc = kmalloc(sizeof(struct clip_ !! 459                 return -EBADFD;
481         if (!clip_vcc) return -ENOMEM;         !! 460         clip_vcc = kmalloc(sizeof(struct clip_vcc), GFP_KERNEL);
482         DPRINTK("mkip clip_vcc %p vcc %p\n",cl !! 461         if (!clip_vcc)
                                                   >> 462                 return -ENOMEM;
                                                   >> 463         pr_debug("mkip clip_vcc %p vcc %p\n", clip_vcc, vcc);
483         clip_vcc->vcc = vcc;                      464         clip_vcc->vcc = vcc;
484         vcc->user_back = clip_vcc;                465         vcc->user_back = clip_vcc;
485         set_bit(ATM_VF_IS_CLIP, &vcc->flags);     466         set_bit(ATM_VF_IS_CLIP, &vcc->flags);
486         clip_vcc->entry = NULL;                   467         clip_vcc->entry = NULL;
487         clip_vcc->xoff = 0;                       468         clip_vcc->xoff = 0;
488         clip_vcc->encap = 1;                      469         clip_vcc->encap = 1;
489         clip_vcc->last_use = jiffies;             470         clip_vcc->last_use = jiffies;
490         clip_vcc->idle_timeout = timeout*HZ;   !! 471         clip_vcc->idle_timeout = timeout * HZ;
491         clip_vcc->old_push = vcc->push;           472         clip_vcc->old_push = vcc->push;
492         clip_vcc->old_pop = vcc->pop;             473         clip_vcc->old_pop = vcc->pop;
493         vcc->push = clip_push;                    474         vcc->push = clip_push;
494         vcc->pop = clip_pop;                      475         vcc->pop = clip_pop;
495         skb_queue_head_init(&copy);            !! 476 
496         skb_migrate(&vcc->sk->sk_receive_queue !! 477         rq = &sk_atm(vcc)->sk_receive_queue;
                                                   >> 478 
                                                   >> 479         spin_lock_irqsave(&rq->lock, flags);
                                                   >> 480         if (skb_queue_empty(rq)) {
                                                   >> 481                 skb = NULL;
                                                   >> 482         } else {
                                                   >> 483                 /* NULL terminate the list.  */
                                                   >> 484                 rq->prev->next = NULL;
                                                   >> 485                 skb = rq->next;
                                                   >> 486         }
                                                   >> 487         rq->prev = rq->next = (struct sk_buff *)rq;
                                                   >> 488         rq->qlen = 0;
                                                   >> 489         spin_unlock_irqrestore(&rq->lock, flags);
                                                   >> 490 
497         /* re-process everything received betw    491         /* re-process everything received between connection setup and MKIP */
498         while ((skb = skb_dequeue(&copy)) != N !! 492         while (skb) {
                                                   >> 493                 struct sk_buff *next = skb->next;
                                                   >> 494 
                                                   >> 495                 skb->next = skb->prev = NULL;
499                 if (!clip_devs) {                 496                 if (!clip_devs) {
500                         atm_return(vcc,skb->tr !! 497                         atm_return(vcc, skb->truesize);
501                         kfree_skb(skb);           498                         kfree_skb(skb);
502                 }                              !! 499                 } else {
503                 else {                         << 
504                         unsigned int len = skb    500                         unsigned int len = skb->len;
505                                                   501 
506                         clip_push(vcc,skb);    !! 502                         skb_get(skb);
                                                   >> 503                         clip_push(vcc, skb);
507                         PRIV(skb->dev)->stats.    504                         PRIV(skb->dev)->stats.rx_packets--;
508                         PRIV(skb->dev)->stats.    505                         PRIV(skb->dev)->stats.rx_bytes -= len;
                                                   >> 506                         kfree_skb(skb);
509                 }                                 507                 }
                                                   >> 508 
                                                   >> 509                 skb = next;
                                                   >> 510         }
510         return 0;                                 511         return 0;
511 }                                                 512 }
512                                                   513 
513                                                !! 514 static int clip_setentry(struct atm_vcc *vcc, __be32 ip)
514 static int clip_setentry(struct atm_vcc *vcc,u << 
515 {                                                 515 {
516         struct neighbour *neigh;                  516         struct neighbour *neigh;
517         struct atmarp_entry *entry;               517         struct atmarp_entry *entry;
518         int error;                                518         int error;
519         struct clip_vcc *clip_vcc;                519         struct clip_vcc *clip_vcc;
520         struct flowi fl = { .nl_u = { .ip4_u = !! 520         struct flowi fl = { .nl_u = { .ip4_u = { .daddr = ip, .tos = 1}} };
521         struct rtable *rt;                        521         struct rtable *rt;
522                                                   522 
523         if (vcc->push != clip_push) {             523         if (vcc->push != clip_push) {
524                 printk(KERN_WARNING "clip_sete    524                 printk(KERN_WARNING "clip_setentry: non-CLIP VCC\n");
525                 return -EBADF;                    525                 return -EBADF;
526         }                                         526         }
527         clip_vcc = CLIP_VCC(vcc);                 527         clip_vcc = CLIP_VCC(vcc);
528         if (!ip) {                                528         if (!ip) {
529                 if (!clip_vcc->entry) {           529                 if (!clip_vcc->entry) {
530                         printk(KERN_ERR "hidin    530                         printk(KERN_ERR "hiding hidden ATMARP entry\n");
531                         return 0;                 531                         return 0;
532                 }                                 532                 }
533                 DPRINTK("setentry: remove\n"); !! 533                 pr_debug("setentry: remove\n");
534                 unlink_clip_vcc(clip_vcc);        534                 unlink_clip_vcc(clip_vcc);
535                 return 0;                         535                 return 0;
536         }                                         536         }
537         error = ip_route_output_key(&rt,&fl);  !! 537         error = ip_route_output_key(&init_net, &rt, &fl);
538         if (error) return error;               !! 538         if (error)
539         neigh = __neigh_lookup(&clip_tbl,&ip,r !! 539                 return error;
                                                   >> 540         neigh = __neigh_lookup(&clip_tbl, &ip, rt->u.dst.dev, 1);
540         ip_rt_put(rt);                            541         ip_rt_put(rt);
541         if (!neigh)                               542         if (!neigh)
542                 return -ENOMEM;                   543                 return -ENOMEM;
543         entry = NEIGH2ENTRY(neigh);               544         entry = NEIGH2ENTRY(neigh);
544         if (entry != clip_vcc->entry) {           545         if (entry != clip_vcc->entry) {
545                 if (!clip_vcc->entry) DPRINTK( !! 546                 if (!clip_vcc->entry)
                                                   >> 547                         pr_debug("setentry: add\n");
546                 else {                            548                 else {
547                         DPRINTK("setentry: upd !! 549                         pr_debug("setentry: update\n");
548                         unlink_clip_vcc(clip_v    550                         unlink_clip_vcc(clip_vcc);
549                 }                                 551                 }
550                 link_vcc(clip_vcc,entry);      !! 552                 link_vcc(clip_vcc, entry);
551         }                                         553         }
552         error = neigh_update(neigh, llc_oui, N !! 554         error = neigh_update(neigh, llc_oui, NUD_PERMANENT,
553                              NEIGH_UPDATE_F_OV !! 555                              NEIGH_UPDATE_F_OVERRIDE | NEIGH_UPDATE_F_ADMIN);
554         neigh_release(neigh);                     556         neigh_release(neigh);
555         return error;                             557         return error;
556 }                                                 558 }
557                                                   559 
558                                                << 
559 static void clip_setup(struct net_device *dev)    560 static void clip_setup(struct net_device *dev)
560 {                                                 561 {
561         dev->hard_start_xmit = clip_start_xmit    562         dev->hard_start_xmit = clip_start_xmit;
562         /* sg_xmit ... */                         563         /* sg_xmit ... */
563         dev->get_stats = clip_get_stats;          564         dev->get_stats = clip_get_stats;
564         dev->type = ARPHRD_ATM;                   565         dev->type = ARPHRD_ATM;
565         dev->hard_header_len = RFC1483LLC_LEN;    566         dev->hard_header_len = RFC1483LLC_LEN;
566         dev->mtu = RFC1626_MTU;                   567         dev->mtu = RFC1626_MTU;
567         dev->tx_queue_len = 100; /* "normal" q !! 568         dev->tx_queue_len = 100;        /* "normal" queue (packets) */
568             /* When using a "real" qdisc, the  !! 569         /* When using a "real" qdisc, the qdisc determines the queue */
569             /* length. tx_queue_len is only us !! 570         /* length. tx_queue_len is only used for the default case, */
570             /* without any more elaborate queu !! 571         /* without any more elaborate queuing. 100 is a reasonable */
571             /* compromise between decent burst !! 572         /* compromise between decent burst-tolerance and protection */
572             /* against memory hogs. */         !! 573         /* against memory hogs. */
573 }                                                 574 }
574                                                   575 
575                                                << 
576 static int clip_create(int number)                576 static int clip_create(int number)
577 {                                                 577 {
578         struct net_device *dev;                   578         struct net_device *dev;
579         struct clip_priv *clip_priv;              579         struct clip_priv *clip_priv;
580         int error;                                580         int error;
581                                                   581 
582         if (number != -1) {                       582         if (number != -1) {
583                 for (dev = clip_devs; dev; dev    583                 for (dev = clip_devs; dev; dev = PRIV(dev)->next)
584                         if (PRIV(dev)->number  !! 584                         if (PRIV(dev)->number == number)
585         }                                      !! 585                                 return -EEXIST;
586         else {                                 !! 586         } else {
587                 number = 0;                       587                 number = 0;
588                 for (dev = clip_devs; dev; dev    588                 for (dev = clip_devs; dev; dev = PRIV(dev)->next)
589                         if (PRIV(dev)->number     589                         if (PRIV(dev)->number >= number)
590                                 number = PRIV( !! 590                                 number = PRIV(dev)->number + 1;
591         }                                         591         }
592         dev = alloc_netdev(sizeof(struct clip_    592         dev = alloc_netdev(sizeof(struct clip_priv), "", clip_setup);
593         if (!dev)                                 593         if (!dev)
594                 return -ENOMEM;                   594                 return -ENOMEM;
595         clip_priv = PRIV(dev);                    595         clip_priv = PRIV(dev);
596         sprintf(dev->name,"atm%d",number);     !! 596         sprintf(dev->name, "atm%d", number);
597         spin_lock_init(&clip_priv->xoff_lock);    597         spin_lock_init(&clip_priv->xoff_lock);
598         clip_priv->number = number;               598         clip_priv->number = number;
599         error = register_netdev(dev);             599         error = register_netdev(dev);
600         if (error) {                              600         if (error) {
601                 free_netdev(dev);                 601                 free_netdev(dev);
602                 return error;                     602                 return error;
603         }                                         603         }
604         clip_priv->next = clip_devs;              604         clip_priv->next = clip_devs;
605         clip_devs = dev;                          605         clip_devs = dev;
606         DPRINTK("registered (net:%s)\n",dev->n !! 606         pr_debug("registered (net:%s)\n", dev->name);
607         return number;                            607         return number;
608 }                                                 608 }
609                                                   609 
610                                                !! 610 static int clip_device_event(struct notifier_block *this, unsigned long event,
611 static int clip_device_event(struct notifier_b !! 611                              void *arg)
612     void *dev)                                 << 
613 {                                                 612 {
                                                   >> 613         struct net_device *dev = arg;
                                                   >> 614 
                                                   >> 615         if (dev->nd_net != &init_net)
                                                   >> 616                 return NOTIFY_DONE;
                                                   >> 617 
                                                   >> 618         if (event == NETDEV_UNREGISTER) {
                                                   >> 619                 neigh_ifdown(&clip_tbl, dev);
                                                   >> 620                 return NOTIFY_DONE;
                                                   >> 621         }
                                                   >> 622 
614         /* ignore non-CLIP devices */             623         /* ignore non-CLIP devices */
615         if (((struct net_device *) dev)->type  !! 624         if (dev->type != ARPHRD_ATM || dev->hard_start_xmit != clip_start_xmit)
616             ((struct net_device *) dev)->hard_ << 
617                 return NOTIFY_DONE;               625                 return NOTIFY_DONE;
                                                   >> 626 
618         switch (event) {                          627         switch (event) {
619                 case NETDEV_UP:                !! 628         case NETDEV_UP:
620                         DPRINTK("clip_device_e !! 629                 pr_debug("clip_device_event NETDEV_UP\n");
621                         (void) to_atmarpd(act_ !! 630                 to_atmarpd(act_up, PRIV(dev)->number, 0);
622                         break;                 !! 631                 break;
623                 case NETDEV_GOING_DOWN:        !! 632         case NETDEV_GOING_DOWN:
624                         DPRINTK("clip_device_e !! 633                 pr_debug("clip_device_event NETDEV_DOWN\n");
625                         (void) to_atmarpd(act_ !! 634                 to_atmarpd(act_down, PRIV(dev)->number, 0);
626                         break;                 !! 635                 break;
627                 case NETDEV_CHANGE:            !! 636         case NETDEV_CHANGE:
628                 case NETDEV_CHANGEMTU:         !! 637         case NETDEV_CHANGEMTU:
629                         DPRINTK("clip_device_e !! 638                 pr_debug("clip_device_event NETDEV_CHANGE*\n");
630                         (void) to_atmarpd(act_ !! 639                 to_atmarpd(act_change, PRIV(dev)->number, 0);
631                         break;                 !! 640                 break;
632                 case NETDEV_REBOOT:            << 
633                 case NETDEV_REGISTER:          << 
634                 case NETDEV_DOWN:              << 
635                         DPRINTK("clip_device_e << 
636                         /* ignore */           << 
637                         break;                 << 
638                 default:                       << 
639                         printk(KERN_WARNING "c << 
640                             "%ld\n",event);    << 
641                         break;                 << 
642         }                                         641         }
643         return NOTIFY_DONE;                       642         return NOTIFY_DONE;
644 }                                                 643 }
645                                                   644 
646                                                !! 645 static int clip_inet_event(struct notifier_block *this, unsigned long event,
647 static int clip_inet_event(struct notifier_blo !! 646                            void *ifa)
648     void *ifa)                                 << 
649 {                                                 647 {
650         struct in_device *in_dev;                 648         struct in_device *in_dev;
651                                                   649 
652         in_dev = ((struct in_ifaddr *) ifa)->i !! 650         in_dev = ((struct in_ifaddr *)ifa)->ifa_dev;
653         if (!in_dev || !in_dev->dev) {            651         if (!in_dev || !in_dev->dev) {
654                 printk(KERN_WARNING "clip_inet    652                 printk(KERN_WARNING "clip_inet_event: no device\n");
655                 return NOTIFY_DONE;               653                 return NOTIFY_DONE;
656         }                                         654         }
657         /*                                        655         /*
658          * Transitions are of the down-change-    656          * Transitions are of the down-change-up type, so it's sufficient to
659          * handle the change on up.               657          * handle the change on up.
660          */                                       658          */
661         if (event != NETDEV_UP) return NOTIFY_ !! 659         if (event != NETDEV_UP)
662         return clip_device_event(this,NETDEV_C !! 660                 return NOTIFY_DONE;
                                                   >> 661         return clip_device_event(this, NETDEV_CHANGE, in_dev->dev);
663 }                                                 662 }
664                                                   663 
665                                                   664 
666 static struct notifier_block clip_dev_notifier    665 static struct notifier_block clip_dev_notifier = {
667         clip_device_event,                     !! 666         .notifier_call = clip_device_event,
668         NULL,                                  << 
669         0                                      << 
670 };                                                667 };
671                                                   668 
672                                                   669 
673                                                   670 
674 static struct notifier_block clip_inet_notifie    671 static struct notifier_block clip_inet_notifier = {
675         clip_inet_event,                       !! 672         .notifier_call = clip_inet_event,
676         NULL,                                  << 
677         0                                      << 
678 };                                                673 };
679                                                   674 
680                                                   675 
681                                                   676 
682 static void atmarpd_close(struct atm_vcc *vcc)    677 static void atmarpd_close(struct atm_vcc *vcc)
683 {                                                 678 {
684         DPRINTK("atmarpd_close\n");            !! 679         pr_debug("atmarpd_close\n");
685         atmarpd = NULL; /* assumed to be atomi !! 680 
686         barrier();                             !! 681         rtnl_lock();
687         unregister_inetaddr_notifier(&clip_ine !! 682         atmarpd = NULL;
688         unregister_netdevice_notifier(&clip_de !! 683         skb_queue_purge(&sk_atm(vcc)->sk_receive_queue);
689         if (skb_peek(&vcc->sk->sk_receive_queu !! 684         rtnl_unlock();
690                 printk(KERN_ERR "atmarpd_close !! 685 
691                     "pending\n");              !! 686         pr_debug("(done)\n");
692         skb_queue_purge(&vcc->sk->sk_receive_q << 
693         DPRINTK("(done)\n");                   << 
694         module_put(THIS_MODULE);                  687         module_put(THIS_MODULE);
695 }                                                 688 }
696                                                   689 
697                                                   690 
698 static struct atmdev_ops atmarpd_dev_ops = {      691 static struct atmdev_ops atmarpd_dev_ops = {
699         .close = atmarpd_close                    692         .close = atmarpd_close
700 };                                                693 };
701                                                   694 
702                                                   695 
703 static struct atm_dev atmarpd_dev = {             696 static struct atm_dev atmarpd_dev = {
704         .ops =                  &atmarpd_dev_o    697         .ops =                  &atmarpd_dev_ops,
705         .type =                 "arpd",           698         .type =                 "arpd",
706         .number =               999,              699         .number =               999,
707         .lock =                 SPIN_LOCK_UNLO !! 700         .lock =                 __SPIN_LOCK_UNLOCKED(atmarpd_dev.lock)
708 };                                                701 };
709                                                   702 
710                                                   703 
711 static int atm_init_atmarp(struct atm_vcc *vcc    704 static int atm_init_atmarp(struct atm_vcc *vcc)
712 {                                                 705 {
713         if (atmarpd) return -EADDRINUSE;       !! 706         rtnl_lock();
714         if (start_timer) {                     !! 707         if (atmarpd) {
715                 start_timer = 0;               !! 708                 rtnl_unlock();
716                 init_timer(&idle_timer);       !! 709                 return -EADDRINUSE;
717                 idle_timer.expires = jiffies+C << 
718                 idle_timer.function = idle_tim << 
719                 add_timer(&idle_timer);        << 
720         }                                         710         }
                                                   >> 711 
                                                   >> 712         mod_timer(&idle_timer, jiffies+CLIP_CHECK_INTERVAL*HZ);
                                                   >> 713 
721         atmarpd = vcc;                            714         atmarpd = vcc;
722         set_bit(ATM_VF_META,&vcc->flags);         715         set_bit(ATM_VF_META,&vcc->flags);
723         set_bit(ATM_VF_READY,&vcc->flags);        716         set_bit(ATM_VF_READY,&vcc->flags);
724             /* allow replies and avoid getting    717             /* allow replies and avoid getting closed if signaling dies */
725         vcc->dev = &atmarpd_dev;                  718         vcc->dev = &atmarpd_dev;
726         vcc_insert_socket(vcc->sk);            !! 719         vcc_insert_socket(sk_atm(vcc));
727         vcc->push = NULL;                         720         vcc->push = NULL;
728         vcc->pop = NULL; /* crash */              721         vcc->pop = NULL; /* crash */
729         vcc->push_oam = NULL; /* crash */         722         vcc->push_oam = NULL; /* crash */
730         if (register_netdevice_notifier(&clip_ !! 723         rtnl_unlock();
731                 printk(KERN_ERR "register_netd << 
732         if (register_inetaddr_notifier(&clip_i << 
733                 printk(KERN_ERR "register_inet << 
734         return 0;                                 724         return 0;
735 }                                                 725 }
736                                                   726 
737 static int clip_ioctl(struct socket *sock, uns    727 static int clip_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
738 {                                                 728 {
739         struct atm_vcc *vcc = ATM_SD(sock);       729         struct atm_vcc *vcc = ATM_SD(sock);
740         int err = 0;                              730         int err = 0;
741                                                   731 
742         switch (cmd) {                            732         switch (cmd) {
743                 case SIOCMKCLIP:               !! 733         case SIOCMKCLIP:
744                 case ATMARPD_CTRL:             !! 734         case ATMARPD_CTRL:
745                 case ATMARP_MKIP:              !! 735         case ATMARP_MKIP:
746                 case ATMARP_SETENTRY:          !! 736         case ATMARP_SETENTRY:
747                 case ATMARP_ENCAP:             !! 737         case ATMARP_ENCAP:
748                         if (!capable(CAP_NET_A !! 738                 if (!capable(CAP_NET_ADMIN))
749                                 return -EPERM; !! 739                         return -EPERM;
750                         break;                 !! 740                 break;
751                 default:                       !! 741         default:
752                         return -ENOIOCTLCMD;   !! 742                 return -ENOIOCTLCMD;
753         }                                         743         }
754                                                   744 
755         switch (cmd) {                            745         switch (cmd) {
756                 case SIOCMKCLIP:               !! 746         case SIOCMKCLIP:
757                         err = clip_create(arg) !! 747                 err = clip_create(arg);
758                         break;                 !! 748                 break;
759                 case ATMARPD_CTRL:             !! 749         case ATMARPD_CTRL:
760                         err = atm_init_atmarp( !! 750                 err = atm_init_atmarp(vcc);
761                         if (!err) {            !! 751                 if (!err) {
762                                 sock->state =  !! 752                         sock->state = SS_CONNECTED;
763                                 __module_get(T !! 753                         __module_get(THIS_MODULE);
764                         }                      !! 754                 }
765                         break;                 !! 755                 break;
766                 case ATMARP_MKIP:              !! 756         case ATMARP_MKIP:
767                         err = clip_mkip(vcc ,a !! 757                 err = clip_mkip(vcc, arg);
768                         break;                 !! 758                 break;
769                 case ATMARP_SETENTRY:          !! 759         case ATMARP_SETENTRY:
770                         err = clip_setentry(vc !! 760                 err = clip_setentry(vcc, (__force __be32)arg);
771                         break;                 !! 761                 break;
772                 case ATMARP_ENCAP:             !! 762         case ATMARP_ENCAP:
773                         err = clip_encap(vcc,  !! 763                 err = clip_encap(vcc, arg);
774                         break;                 !! 764                 break;
775         }                                         765         }
776         return err;                               766         return err;
777 }                                                 767 }
778                                                   768 
779 static struct atm_ioctl clip_ioctl_ops = {        769 static struct atm_ioctl clip_ioctl_ops = {
780         .owner  = THIS_MODULE,                 !! 770         .owner = THIS_MODULE,
781         .ioctl  = clip_ioctl,                  !! 771         .ioctl = clip_ioctl,
782 };                                                772 };
783                                                   773 
784 #ifdef CONFIG_PROC_FS                             774 #ifdef CONFIG_PROC_FS
785                                                   775 
786 static void svc_addr(struct seq_file *seq, str    776 static void svc_addr(struct seq_file *seq, struct sockaddr_atmsvc *addr)
787 {                                                 777 {
788         static int code[] = { 1,2,10,6,1,0 };  !! 778         static int code[] = { 1, 2, 10, 6, 1, 0 };
789         static int e164[] = { 1,8,4,6,1,0 };   !! 779         static int e164[] = { 1, 8, 4, 6, 1, 0 };
790                                                   780 
791         if (*addr->sas_addr.pub) {                781         if (*addr->sas_addr.pub) {
792                 seq_printf(seq, "%s", addr->sa    782                 seq_printf(seq, "%s", addr->sas_addr.pub);
793                 if (*addr->sas_addr.prv)          783                 if (*addr->sas_addr.prv)
794                         seq_putc(seq, '+');       784                         seq_putc(seq, '+');
795         } else if (!*addr->sas_addr.prv) {        785         } else if (!*addr->sas_addr.prv) {
796                 seq_printf(seq, "%s", "(none)"    786                 seq_printf(seq, "%s", "(none)");
797                 return;                           787                 return;
798         }                                         788         }
799         if (*addr->sas_addr.prv) {                789         if (*addr->sas_addr.prv) {
800                 unsigned char *prv = addr->sas    790                 unsigned char *prv = addr->sas_addr.prv;
801                 int *fields;                      791                 int *fields;
802                 int i, j;                         792                 int i, j;
803                                                   793 
804                 fields = *prv == ATM_AFI_E164     794                 fields = *prv == ATM_AFI_E164 ? e164 : code;
805                 for (i = 0; fields[i]; i++) {     795                 for (i = 0; fields[i]; i++) {
806                         for (j = fields[i]; j;    796                         for (j = fields[i]; j; j--)
807                                 seq_printf(seq    797                                 seq_printf(seq, "%02X", *prv++);
808                         if (fields[i+1])       !! 798                         if (fields[i + 1])
809                                 seq_putc(seq,     799                                 seq_putc(seq, '.');
810                 }                                 800                 }
811         }                                         801         }
812 }                                                 802 }
813                                                   803 
814 /* This means the neighbour entry has no attac    804 /* This means the neighbour entry has no attached VCC objects. */
815 #define SEQ_NO_VCC_TOKEN        ((void *) 2)      805 #define SEQ_NO_VCC_TOKEN        ((void *) 2)
816                                                   806 
817 static void atmarp_info(struct seq_file *seq,     807 static void atmarp_info(struct seq_file *seq, struct net_device *dev,
818                         struct atmarp_entry *e    808                         struct atmarp_entry *entry, struct clip_vcc *clip_vcc)
819 {                                                 809 {
820         unsigned long exp;                        810         unsigned long exp;
821         char buf[17];                             811         char buf[17];
822         int svc, llc, off;                        812         int svc, llc, off;
823                                                   813 
824         svc = ((clip_vcc == SEQ_NO_VCC_TOKEN)     814         svc = ((clip_vcc == SEQ_NO_VCC_TOKEN) ||
825                (clip_vcc->vcc->sk->sk_family = !! 815                (sk_atm(clip_vcc->vcc)->sk_family == AF_ATMSVC));
826                                                   816 
827         llc = ((clip_vcc == SEQ_NO_VCC_TOKEN)  !! 817         llc = ((clip_vcc == SEQ_NO_VCC_TOKEN) || clip_vcc->encap);
828                clip_vcc->encap);               << 
829                                                   818 
830         if (clip_vcc == SEQ_NO_VCC_TOKEN)         819         if (clip_vcc == SEQ_NO_VCC_TOKEN)
831                 exp = entry->neigh->used;         820                 exp = entry->neigh->used;
832         else                                      821         else
833                 exp = clip_vcc->last_use;         822                 exp = clip_vcc->last_use;
834                                                   823 
835         exp = (jiffies - exp) / HZ;               824         exp = (jiffies - exp) / HZ;
836                                                   825 
837         seq_printf(seq, "%-6s%-4s%-4s%5ld ",      826         seq_printf(seq, "%-6s%-4s%-4s%5ld ",
838                    dev->name,                  !! 827                    dev->name, svc ? "SVC" : "PVC", llc ? "LLC" : "NULL", exp);
839                    svc ? "SVC" : "PVC",        << 
840                    llc ? "LLC" : "NULL",       << 
841                    exp);                       << 
842                                                   828 
843         off = scnprintf(buf, sizeof(buf) - 1,     829         off = scnprintf(buf, sizeof(buf) - 1, "%d.%d.%d.%d",
844                         NIPQUAD(entry->ip));      830                         NIPQUAD(entry->ip));
845         while (off < 16)                          831         while (off < 16)
846                 buf[off++] = ' ';                 832                 buf[off++] = ' ';
847         buf[off] = '\0';                          833         buf[off] = '\0';
848         seq_printf(seq, "%s", buf);               834         seq_printf(seq, "%s", buf);
849                                                   835 
850         if (clip_vcc == SEQ_NO_VCC_TOKEN) {       836         if (clip_vcc == SEQ_NO_VCC_TOKEN) {
851                 if (time_before(jiffies, entry    837                 if (time_before(jiffies, entry->expires))
852                         seq_printf(seq, "(reso    838                         seq_printf(seq, "(resolving)\n");
853                 else                              839                 else
854                         seq_printf(seq, "(expi    840                         seq_printf(seq, "(expired, ref %d)\n",
855                                    atomic_read    841                                    atomic_read(&entry->neigh->refcnt));
856         } else if (!svc) {                        842         } else if (!svc) {
857                 seq_printf(seq, "%d.%d.%d\n",     843                 seq_printf(seq, "%d.%d.%d\n",
858                            clip_vcc->vcc->dev-    844                            clip_vcc->vcc->dev->number,
859                            clip_vcc->vcc->vpi, !! 845                            clip_vcc->vcc->vpi, clip_vcc->vcc->vci);
860                            clip_vcc->vcc->vci) << 
861         } else {                                  846         } else {
862                 svc_addr(seq, &clip_vcc->vcc->    847                 svc_addr(seq, &clip_vcc->vcc->remote);
863                 seq_putc(seq, '\n');              848                 seq_putc(seq, '\n');
864         }                                         849         }
865 }                                                 850 }
866                                                   851 
867 struct clip_seq_state {                           852 struct clip_seq_state {
868         /* This member must be first. */          853         /* This member must be first. */
869         struct neigh_seq_state ns;                854         struct neigh_seq_state ns;
870                                                   855 
871         /* Local to clip specific iteration. *    856         /* Local to clip specific iteration. */
872         struct clip_vcc *vcc;                     857         struct clip_vcc *vcc;
873 };                                                858 };
874                                                   859 
875 static struct clip_vcc *clip_seq_next_vcc(stru    860 static struct clip_vcc *clip_seq_next_vcc(struct atmarp_entry *e,
876                                           stru    861                                           struct clip_vcc *curr)
877 {                                                 862 {
878         if (!curr) {                              863         if (!curr) {
879                 curr = e->vccs;                   864                 curr = e->vccs;
880                 if (!curr)                        865                 if (!curr)
881                         return SEQ_NO_VCC_TOKE    866                         return SEQ_NO_VCC_TOKEN;
882                 return curr;                      867                 return curr;
883         }                                         868         }
884         if (curr == SEQ_NO_VCC_TOKEN)             869         if (curr == SEQ_NO_VCC_TOKEN)
885                 return NULL;                      870                 return NULL;
886                                                   871 
887         curr = curr->next;                        872         curr = curr->next;
888                                                   873 
889         return curr;                              874         return curr;
890 }                                                 875 }
891                                                   876 
892 static void *clip_seq_vcc_walk(struct clip_seq    877 static void *clip_seq_vcc_walk(struct clip_seq_state *state,
893                                struct atmarp_e !! 878                                struct atmarp_entry *e, loff_t * pos)
894 {                                                 879 {
895         struct clip_vcc *vcc = state->vcc;        880         struct clip_vcc *vcc = state->vcc;
896                                                   881 
897         vcc = clip_seq_next_vcc(e, vcc);          882         vcc = clip_seq_next_vcc(e, vcc);
898         if (vcc && pos != NULL) {                 883         if (vcc && pos != NULL) {
899                 while (*pos) {                    884                 while (*pos) {
900                         vcc = clip_seq_next_vc    885                         vcc = clip_seq_next_vcc(e, vcc);
901                         if (!vcc)                 886                         if (!vcc)
902                                 break;            887                                 break;
903                         --(*pos);                 888                         --(*pos);
904                 }                                 889                 }
905         }                                         890         }
906         state->vcc = vcc;                         891         state->vcc = vcc;
907                                                   892 
908         return vcc;                               893         return vcc;
909 }                                                 894 }
910                                                !! 895 
911 static void *clip_seq_sub_iter(struct neigh_se    896 static void *clip_seq_sub_iter(struct neigh_seq_state *_state,
912                                struct neighbou !! 897                                struct neighbour *n, loff_t * pos)
913 {                                                 898 {
914         struct clip_seq_state *state = (struct !! 899         struct clip_seq_state *state = (struct clip_seq_state *)_state;
915                                                   900 
916         return clip_seq_vcc_walk(state, NEIGH2    901         return clip_seq_vcc_walk(state, NEIGH2ENTRY(n), pos);
917 }                                                 902 }
918                                                   903 
919 static void *clip_seq_start(struct seq_file *s !! 904 static void *clip_seq_start(struct seq_file *seq, loff_t * pos)
920 {                                                 905 {
                                                   >> 906         struct clip_seq_state *state = seq->private;
                                                   >> 907         state->ns.neigh_sub_iter = clip_seq_sub_iter;
921         return neigh_seq_start(seq, pos, &clip    908         return neigh_seq_start(seq, pos, &clip_tbl, NEIGH_SEQ_NEIGH_ONLY);
922 }                                                 909 }
923                                                   910 
924 static int clip_seq_show(struct seq_file *seq,    911 static int clip_seq_show(struct seq_file *seq, void *v)
925 {                                                 912 {
926         static char atm_arp_banner[] =         !! 913         static char atm_arp_banner[] =
927                 "IPitf TypeEncp Idle IP addres !! 914             "IPitf TypeEncp Idle IP address      ATM address\n";
928                                                   915 
929         if (v == SEQ_START_TOKEN) {               916         if (v == SEQ_START_TOKEN) {
930                 seq_puts(seq, atm_arp_banner);    917                 seq_puts(seq, atm_arp_banner);
931         } else {                                  918         } else {
932                 struct clip_seq_state *state =    919                 struct clip_seq_state *state = seq->private;
933                 struct neighbour *n = v;          920                 struct neighbour *n = v;
934                 struct clip_vcc *vcc = state->    921                 struct clip_vcc *vcc = state->vcc;
935                                                   922 
936                 atmarp_info(seq, n->dev, NEIGH    923                 atmarp_info(seq, n->dev, NEIGH2ENTRY(n), vcc);
937         }                                         924         }
938         return 0;                              !! 925         return 0;
939 }                                                 926 }
940                                                   927 
941 static struct seq_operations arp_seq_ops = {   !! 928 static const struct seq_operations arp_seq_ops = {
942         .start  = clip_seq_start,                 929         .start  = clip_seq_start,
943         .next   = neigh_seq_next,                 930         .next   = neigh_seq_next,
944         .stop   = neigh_seq_stop,                 931         .stop   = neigh_seq_stop,
945         .show   = clip_seq_show,                  932         .show   = clip_seq_show,
946 };                                                933 };
947                                                   934 
948 static int arp_seq_open(struct inode *inode, s    935 static int arp_seq_open(struct inode *inode, struct file *file)
949 {                                                 936 {
950         struct clip_seq_state *state;          !! 937         return seq_open_net(inode, file, &arp_seq_ops,
951         struct seq_file *seq;                  !! 938                             sizeof(struct clip_seq_state));
952         int rc = -EAGAIN;                      << 
953                                                << 
954         state = kmalloc(sizeof(*state), GFP_KE << 
955         if (!state) {                          << 
956                 rc = -ENOMEM;                  << 
957                 goto out_kfree;                << 
958         }                                      << 
959         memset(state, 0, sizeof(*state));      << 
960         state->ns.neigh_sub_iter = clip_seq_su << 
961                                                << 
962         rc = seq_open(file, &arp_seq_ops);     << 
963         if (rc)                                << 
964                 goto out_kfree;                << 
965                                                << 
966         seq = file->private_data;              << 
967         seq->private = state;                  << 
968 out:                                           << 
969         return rc;                             << 
970                                                << 
971 out_kfree:                                     << 
972         kfree(state);                          << 
973         goto out;                              << 
974 }                                                 939 }
975                                                   940 
976 static struct file_operations arp_seq_fops = { !! 941 static const struct file_operations arp_seq_fops = {
977         .open           = arp_seq_open,           942         .open           = arp_seq_open,
978         .read           = seq_read,               943         .read           = seq_read,
979         .llseek         = seq_lseek,              944         .llseek         = seq_lseek,
980         .release        = seq_release_private, !! 945         .release        = seq_release_net,
981         .owner          = THIS_MODULE             946         .owner          = THIS_MODULE
982 };                                                947 };
983 #endif                                            948 #endif
984                                                   949 
                                                   >> 950 static void atm_clip_exit_noproc(void);
                                                   >> 951 
985 static int __init atm_clip_init(void)             952 static int __init atm_clip_init(void)
986 {                                                 953 {
987         neigh_table_init(&clip_tbl);           !! 954         neigh_table_init_no_netlink(&clip_tbl);
988                                                   955 
989         clip_tbl_hook = &clip_tbl;                956         clip_tbl_hook = &clip_tbl;
990         register_atm_ioctl(&clip_ioctl_ops);      957         register_atm_ioctl(&clip_ioctl_ops);
                                                   >> 958         register_netdevice_notifier(&clip_dev_notifier);
                                                   >> 959         register_inetaddr_notifier(&clip_inet_notifier);
                                                   >> 960 
                                                   >> 961         setup_timer(&idle_timer, idle_timer_check, 0);
991                                                   962 
992 #ifdef CONFIG_PROC_FS                             963 #ifdef CONFIG_PROC_FS
993 {                                              !! 964         {
994         struct proc_dir_entry *p;              !! 965                 struct proc_dir_entry *p;
995                                                   966 
996         p = create_proc_entry("arp", S_IRUGO,  !! 967                 p = proc_create("arp", S_IRUGO, atm_proc_root, &arp_seq_fops);
997         if (p)                                 !! 968                 if (!p) {
998                 p->proc_fops = &arp_seq_fops;  !! 969                         printk(KERN_ERR "Unable to initialize "
999 }                                              !! 970                                "/proc/net/atm/arp\n");
                                                   >> 971                         atm_clip_exit_noproc();
                                                   >> 972                         return -ENOMEM;
                                                   >> 973                 }
                                                   >> 974         }
1000 #endif                                           975 #endif
1001                                                  976 
1002         return 0;                                977         return 0;
1003 }                                                978 }
1004                                                  979 
1005 static void __exit atm_clip_exit(void)        !! 980 static void atm_clip_exit_noproc(void)
1006 {                                                981 {
1007         struct net_device *dev, *next;           982         struct net_device *dev, *next;
1008                                                  983 
1009         remove_proc_entry("arp", atm_proc_roo !! 984         unregister_inetaddr_notifier(&clip_inet_notifier);
                                                   >> 985         unregister_netdevice_notifier(&clip_dev_notifier);
1010                                                  986 
1011         deregister_atm_ioctl(&clip_ioctl_ops)    987         deregister_atm_ioctl(&clip_ioctl_ops);
1012                                                  988 
1013         /* First, stop the idle timer, so it     989         /* First, stop the idle timer, so it stops banging
1014          * on the table.                         990          * on the table.
1015          */                                      991          */
1016         if (start_timer == 0)                 !! 992         del_timer_sync(&idle_timer);
1017                 del_timer(&idle_timer);       << 
1018                                                  993 
1019         /* Next, purge the table, so that the    994         /* Next, purge the table, so that the device
1020          * unregister loop below does not han    995          * unregister loop below does not hang due to
1021          * device references remaining in the    996          * device references remaining in the table.
1022          */                                      997          */
1023         neigh_ifdown(&clip_tbl, NULL);           998         neigh_ifdown(&clip_tbl, NULL);
1024                                                  999 
1025         dev = clip_devs;                         1000         dev = clip_devs;
1026         while (dev) {                            1001         while (dev) {
1027                 next = PRIV(dev)->next;          1002                 next = PRIV(dev)->next;
1028                 unregister_netdev(dev);          1003                 unregister_netdev(dev);
1029                 free_netdev(dev);                1004                 free_netdev(dev);
1030                 dev = next;                      1005                 dev = next;
1031         }                                        1006         }
1032                                                  1007 
1033         /* Now it is safe to fully shutdown w    1008         /* Now it is safe to fully shutdown whole table. */
1034         neigh_table_clear(&clip_tbl);            1009         neigh_table_clear(&clip_tbl);
1035                                                  1010 
1036         clip_tbl_hook = NULL;                    1011         clip_tbl_hook = NULL;
1037 }                                                1012 }
1038                                                  1013 
                                                   >> 1014 static void __exit atm_clip_exit(void)
                                                   >> 1015 {
                                                   >> 1016         remove_proc_entry("arp", atm_proc_root);
                                                   >> 1017 
                                                   >> 1018         atm_clip_exit_noproc();
                                                   >> 1019 }
                                                   >> 1020 
1039 module_init(atm_clip_init);                      1021 module_init(atm_clip_init);
1040 module_exit(atm_clip_exit);                      1022 module_exit(atm_clip_exit);
1041                                               !! 1023 MODULE_AUTHOR("Werner Almesberger");
                                                   >> 1024 MODULE_DESCRIPTION("Classical/IP over ATM interface");
1042 MODULE_LICENSE("GPL");                           1025 MODULE_LICENSE("GPL");
1043                                                  1026 
  This page was automatically generated by the LXR engine.