Whamcloud - gitweb
b93e2f90b51760eef2c0c019a541f8ffb9636af6
[fs/lustre-release.git] / lustre / kernel_patches / patches / dump_netdev_over_netpoll.patch
1 Index: linux-2.6.0-test6/drivers/dump/dump_netdev.c
2 ===================================================================
3 --- linux-2.6.0-test6.orig/drivers/dump/dump_netdev.c   2003-10-07 16:08:57.000000000 +0800
4 +++ linux-2.6.0-test6/drivers/dump/dump_netdev.c        2003-10-09 17:36:18.000000000 +0800
5 @@ -14,6 +14,7 @@
6   *
7   * Copyright (C) 2001  Ingo Molnar <mingo@redhat.com>
8   * Copyright (C) 2002 International Business Machines Corp. 
9 + * Rewrited with netpoll by wangdi <wangdi@clusterfs.com>
10   *
11   *  This code is released under version 2 of the GNU GPL.
12   */
13 @@ -26,29 +27,19 @@
14  #include <linux/module.h>
15  #include <linux/dump.h>
16  #include <linux/dump_netdev.h>
17 +#include <linux/netpoll.h>
18  
19  #include <asm/unaligned.h>
20  
21  static int startup_handshake;
22  static int page_counter;
23 -static struct net_device *dump_ndev;
24  static struct in_device *dump_in_dev;
25 -static u16 source_port, target_port;
26 -static u32 source_ip, target_ip;
27 -static unsigned char daddr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff} ;
28 -static spinlock_t dump_skb_lock = SPIN_LOCK_UNLOCKED;
29 -static int dump_nr_skbs;
30 -static struct sk_buff *dump_skb;
31  static unsigned long flags_global;
32  static int netdump_in_progress;
33  static char device_name[IFNAMSIZ];
34 +int new_req = 0;
35 +static req_t req;
36  
37 -/*
38 - * security depends on the trusted path between the netconsole
39 - * server and netconsole client, since none of the packets are
40 - * encrypted. The random magic number protects the protocol
41 - * against spoofing.
42 - */
43  static u64 dump_magic;
44  
45  #define MAX_UDP_CHUNK 1460
46 @@ -64,300 +55,28 @@
47  #define MAX_SKB_SIZE \
48                 (MAX_UDP_CHUNK + sizeof(struct udphdr) + \
49                                 sizeof(struct iphdr) + sizeof(struct ethhdr))
50 +static char send_buffer[MAX_UDP_CHUNK];
51  
52 -static void
53 -dump_refill_skbs(void)
54 -{
55 -       struct sk_buff *skb;
56 -       unsigned long flags;
57 -
58 -       spin_lock_irqsave(&dump_skb_lock, flags);
59 -       while (dump_nr_skbs < DUMP_MAX_SKBS) {
60 -               skb = alloc_skb(MAX_SKB_SIZE, GFP_ATOMIC);
61 -               if (!skb)
62 -                       break;
63 -               if (dump_skb)
64 -                       skb->next = dump_skb;
65 -               else
66 -                       skb->next = NULL;
67 -               dump_skb = skb;
68 -               dump_nr_skbs++;
69 -       }
70 -       spin_unlock_irqrestore(&dump_skb_lock, flags);
71 -}
72 -
73 -static struct
74 -sk_buff * dump_get_skb(void)
75 -{
76 -       struct sk_buff *skb;
77 -       unsigned long flags;
78 -
79 -       spin_lock_irqsave(&dump_skb_lock, flags);
80 -       skb = dump_skb;
81 -       if (skb) {
82 -               dump_skb = skb->next;
83 -               skb->next = NULL;
84 -               dump_nr_skbs--;
85 -       }
86 -       spin_unlock_irqrestore(&dump_skb_lock, flags);
87 -        
88 -       return skb;
89 -}
90 -
91 -/*
92 - * Zap completed output skbs.
93 - */
94 -static void
95 -zap_completion_queue(void)
96 -{
97 -       int count;
98 -       unsigned long flags;
99 -       int cpu = smp_processor_id();
100 -       struct softnet_data *softnet_data;
101 -               
102 -
103 -       softnet_data = &__get_cpu_var(softnet_data);
104 -       count=0;
105 -       if (softnet_data[cpu].completion_queue) {
106 -               struct sk_buff *clist;
107 -       
108 -               local_irq_save(flags);
109 -               clist = softnet_data[cpu].completion_queue;
110 -               softnet_data[cpu].completion_queue = NULL;
111 -               local_irq_restore(flags);
112 -
113 -               while (clist != NULL) {
114 -                       struct sk_buff *skb = clist;
115 -                       clist = clist->next;
116 -                       __kfree_skb(skb);
117 -                       count++;
118 -                       if (count > 10000)
119 -                               printk("Error in sk list\n");
120 -               }
121 -       }
122 -}
123 -
124 -static void
125 -dump_send_skb(struct net_device *dev, const char *msg, unsigned int msg_len,
126 -               reply_t *reply)
127 -{
128 -       int once = 1;
129 -       int total_len, eth_len, ip_len, udp_len, count = 0;
130 -       struct sk_buff *skb;
131 -       struct udphdr *udph;
132 -       struct iphdr *iph;
133 -       struct ethhdr *eth; 
134 -
135 -       udp_len = msg_len + HEADER_LEN + sizeof(*udph);
136 -       ip_len = eth_len = udp_len + sizeof(*iph);
137 -       total_len = eth_len + ETH_HLEN;
138 -
139 -repeat_loop:
140 -       zap_completion_queue();
141 -       if (dump_nr_skbs < DUMP_MAX_SKBS)
142 -               dump_refill_skbs();
143 -
144 -       skb = alloc_skb(total_len, GFP_ATOMIC);
145 -       if (!skb) {
146 -               skb = dump_get_skb();
147 -               if (!skb) {
148 -                       count++;
149 -                       if (once && (count == 1000000)) {
150 -                               printk("possibly FATAL: out of netconsole "
151 -                                       "skbs!!! will keep retrying.\n");
152 -                               once = 0;
153 -                       }
154 -                       dev->poll_controller(dev);
155 -                       goto repeat_loop;
156 -               }
157 -       }
158 -
159 -       atomic_set(&skb->users, 1);
160 -       skb_reserve(skb, total_len - msg_len - HEADER_LEN);
161 -       skb->data[0] = NETCONSOLE_VERSION;
162 -
163 -       put_unaligned(htonl(reply->nr), (u32 *) (skb->data + 1));
164 -       put_unaligned(htonl(reply->code), (u32 *) (skb->data + 5));
165 -       put_unaligned(htonl(reply->info), (u32 *) (skb->data + 9));
166 -
167 -       memcpy(skb->data + HEADER_LEN, msg, msg_len);
168 -       skb->len += msg_len + HEADER_LEN;
169 -
170 -       udph = (struct udphdr *) skb_push(skb, sizeof(*udph));
171 -       udph->source = source_port;
172 -       udph->dest = target_port;
173 -       udph->len = htons(udp_len);
174 -       udph->check = 0;
175 -
176 -       iph = (struct iphdr *)skb_push(skb, sizeof(*iph));
177 -
178 -       iph->version  = 4;
179 -       iph->ihl      = 5;
180 -       iph->tos      = 0;
181 -       iph->tot_len  = htons(ip_len);
182 -       iph->id       = 0;
183 -       iph->frag_off = 0;
184 -       iph->ttl      = 64;
185 -       iph->protocol = IPPROTO_UDP;
186 -       iph->check    = 0;
187 -       iph->saddr    = source_ip;
188 -       iph->daddr    = target_ip;
189 -       iph->check    = ip_fast_csum((unsigned char *)iph, iph->ihl);
190 -
191 -       eth = (struct ethhdr *) skb_push(skb, ETH_HLEN);
192 -
193 -       eth->h_proto = htons(ETH_P_IP);
194 -       memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
195 -       memcpy(eth->h_dest, daddr, dev->addr_len);
196 +extern void handle_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty);
197 +static void dump_rx_hook(struct netpoll *np, int port, char *msg, int len);
198  
199 -       count=0;
200 -repeat_poll:
201 -       spin_lock(&dev->xmit_lock);
202 -       dev->xmit_lock_owner = smp_processor_id();
203 -
204 -       count++;
205 -
206 -
207 -       if (netif_queue_stopped(dev)) {
208 -               dev->xmit_lock_owner = -1;
209 -               spin_unlock(&dev->xmit_lock);
210 -
211 -               dev->poll_controller(dev);
212 -               zap_completion_queue();
213 -
214 -
215 -               goto repeat_poll;
216 -       }
217 -
218 -       dev->hard_start_xmit(skb, dev);
219 -
220 -       dev->xmit_lock_owner = -1;
221 -       spin_unlock(&dev->xmit_lock);
222 -}
223 -
224 -static unsigned short
225 -udp_check(struct udphdr *uh, int len, unsigned long saddr, unsigned long daddr,
226 -               unsigned long base)
227 -{
228 -       return csum_tcpudp_magic(saddr, daddr, len, IPPROTO_UDP, base);
229 -}
230 -
231 -static int
232 -udp_checksum_init(struct sk_buff *skb, struct udphdr *uh,
233 -                            unsigned short ulen, u32 saddr, u32 daddr)
234 -{
235 -       if (uh->check == 0) {
236 -               skb->ip_summed = CHECKSUM_UNNECESSARY;
237 -       } else if (skb->ip_summed == CHECKSUM_HW) {
238 -               skb->ip_summed = CHECKSUM_UNNECESSARY;
239 -               if (!udp_check(uh, ulen, saddr, daddr, skb->csum))
240 -                       return 0;
241 -               skb->ip_summed = CHECKSUM_NONE;
242 -       }
243 -       if (skb->ip_summed != CHECKSUM_UNNECESSARY)
244 -               skb->csum = csum_tcpudp_nofold(saddr, daddr, ulen,
245 -                               IPPROTO_UDP, 0);
246 -       /* Probably, we should checksum udp header (it should be in cache
247 -        * in any case) and data in tiny packets (< rx copybreak).
248 -        */
249 -       return 0;
250 -}
251 -
252 -static __inline__ int
253 -__udp_checksum_complete(struct sk_buff *skb)
254 -{
255 -       return (unsigned short)csum_fold(skb_checksum(skb, 0, skb->len,
256 -                               skb->csum));
257 -}
258 -
259 -static __inline__
260 -int udp_checksum_complete(struct sk_buff *skb)
261 -{
262 -       return skb->ip_summed != CHECKSUM_UNNECESSARY &&
263 -               __udp_checksum_complete(skb);
264 -}
265 -
266 -int new_req = 0;
267 -static req_t req;
268 +static struct netpoll np = {
269 +       .name = "netdumpoe",
270 +       .dev_name = "eth0",
271 +       .rx_hook = dump_rx_hook,
272 +       .local_port = 0,
273 +       .remote_port = 0,
274 +       .remote_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
275 +};
276  
277 -static int
278 -dump_rx_hook(struct sk_buff *skb)
279 +static void dump_rx_hook(struct netpoll *np, int port, char *msg, int len)
280  {
281 -       int proto;
282 -       struct iphdr *iph;
283 -       struct udphdr *uh;
284 -       __u32 len, saddr, daddr, ulen;
285         req_t *__req;
286 -
287 -       /* 
288 -        * First check if were are dumping or doing startup handshake, if
289 -        * not quickly return.
290 -        */
291 +       
292         if (!netdump_in_progress)
293 -               return NET_RX_SUCCESS;
294 +               goto out;
295 +       __req = (req_t *)msg;
296  
297 -       if (skb->dev->type != ARPHRD_ETHER)
298 -               goto out;
299 -
300 -       proto = ntohs(skb->mac.ethernet->h_proto);
301 -       if (proto != ETH_P_IP)
302 -               goto out;
303 -
304 -       if (skb->pkt_type == PACKET_OTHERHOST)
305 -               goto out;
306 -
307 -       if (skb_shared(skb))
308 -               goto out;
309 -
310 -        /* IP header correctness testing: */
311 -       iph = (struct iphdr *)skb->data;
312 -       if (!pskb_may_pull(skb, sizeof(struct iphdr)))
313 -               goto out;
314 -
315 -       if (iph->ihl < 5 || iph->version != 4)
316 -               goto out;
317 -
318 -       if (!pskb_may_pull(skb, iph->ihl*4))
319 -               goto out;
320 -
321 -       if (ip_fast_csum((u8 *)iph, iph->ihl) != 0)
322 -               goto out;
323 -
324 -       len = ntohs(iph->tot_len);
325 -       if (skb->len < len || len < iph->ihl*4)
326 -               goto out;
327 -
328 -       saddr = iph->saddr;
329 -       daddr = iph->daddr;
330 -       if (iph->protocol != IPPROTO_UDP)
331 -               goto out;
332 -
333 -       if (source_ip != daddr)
334 -               goto out;
335 -
336 -       if (target_ip != saddr)
337 -               goto out;
338 -
339 -       len -= iph->ihl*4;
340 -       uh = (struct udphdr *)(((char *)iph) + iph->ihl*4);
341 -       ulen = ntohs(uh->len);
342 -
343 -       if (ulen != len || ulen < (sizeof(*uh) + sizeof(*__req)))
344 -               goto out;
345 -
346 -       if (udp_checksum_init(skb, uh, ulen, saddr, daddr) < 0)
347 -               goto out;
348 -
349 -       if (udp_checksum_complete(skb))
350 -               goto out;
351 -
352 -       if (source_port != uh->dest)
353 -               goto out;
354 -
355 -       if (target_port != uh->source)
356 -               goto out;
357 -
358 -       __req = (req_t *)(uh + 1);
359         if ((ntohl(__req->command) != COMM_GET_MAGIC) &&
360             (ntohl(__req->command) != COMM_HELLO) &&
361             (ntohl(__req->command) != COMM_START_WRITE_NETDUMP_ACK) &&
362 @@ -372,11 +91,27 @@
363         req.nr = ntohl(__req->nr);
364         new_req = 1;
365  out:
366 -       return NET_RX_DROP;
367 +       return;
368  }
369  
370  static void
371 -dump_send_mem(struct net_device *dev, req_t *req, const char* buff, size_t len)
372 +dump_send_skb(const char *msg, unsigned int msg_len, reply_t *reply)
373 +{
374 +       /*copy the msg to send buffer*/
375 +       send_buffer[0] = NETCONSOLE_VERSION;
376 +
377 +       put_unaligned(htonl(reply->nr), (u32 *) (send_buffer + 1));
378 +       put_unaligned(htonl(reply->code), (u32 *) (send_buffer + 5));
379 +       put_unaligned(htonl(reply->info), (u32 *) (send_buffer + 9));
380 +       memcpy(send_buffer + 1 + sizeof(reply_t), msg, msg_len);
381 +
382 +       if (!np.dev)
383 +               return;
384 +       netpoll_send_udp(&np, send_buffer, (msg_len + 1 + sizeof(reply_t)));
385 +}
386 +
387 +static void
388 +dump_send_mem( req_t *req, const char* buff, size_t len)
389  {
390         int i;
391  
392 @@ -392,7 +127,7 @@
393                 unsigned int offset = i*1024;
394                 reply.code = REPLY_MEM;
395                 reply.info = offset;
396 -                dump_send_skb(dev, buff + offset, 1024, &reply);
397 +                dump_send_skb(buff + offset, 1024, &reply);
398         }
399  }
400  static void dump_do_sysrq(int key)
401 @@ -400,9 +135,16 @@
402          struct pt_regs regs;
403          
404         get_current_regs(&regs);
405 -       handle_sysrq(key, &regs, NULL, NULL);
406 +       handle_sysrq(key, &regs, NULL);
407  }
408  
409 +static void netdump_netpoll_poll(struct netpoll *np)
410 +{
411 +       /*FIXME netpoll_set_trap(0) may have impacts to other parts */
412 +       netpoll_set_trap(1);
413 +       netpoll_poll(np);
414 +       netpoll_set_trap(0);
415 +}
416  /*
417   * This function waits for the client to acknowledge the receipt
418   * of the netdump startup reply, with the possibility of packets
419 @@ -433,24 +175,27 @@
420         
421         /* send 300 handshake packets before declaring failure */
422         for (i = 0; i < 300; i++) {
423 -               dump_send_skb(dump_ndev, tmp, strlen(tmp), &reply);
424 -
425 +               dump_send_skb(tmp, strlen(tmp), &reply);
426 +#if 0
427                 /* wait 1 sec */
428 +                       udelay(100);
429 +                       netpoll_poll(&np);
430 +                       if (new_req)
431 +                               break;
432 +               }
433 +#endif
434                 for (j = 0; j < 10000; j++) {
435                         udelay(100);
436 -                       dump_ndev->poll_controller(dump_ndev);
437 -                       zap_completion_queue();
438 +                       netdump_netpoll_poll(&np);
439                         if (new_req)
440                                 break;
441                 }
442 -
443                 /* 
444                  * if there is no new request, try sending the handshaking
445                  * packet again
446                  */
447                 if (!new_req)
448                         continue;
449 -
450                 /* 
451                  * check if the new request is of the expected type,
452                  * if so, return, else try sending the handshaking
453 @@ -504,10 +249,12 @@
454         repeatCounter = 0;
455         total_loop = 0;
456         while (1) {
457 -                if (!new_req) {
458 -                       dump_ndev->poll_controller(dump_ndev);
459 -                       zap_completion_queue();
460 +                while (!new_req) {
461 +                       netdump_netpoll_poll(&np);
462 +                       if (new_req)
463 +                               break;
464                 }
465 +#if 0
466                 if (!new_req) {
467                         repeatCounter++;
468  
469 @@ -532,13 +279,15 @@
470                 repeatCounter = 0;
471                 counter = 0;
472                 total_loop = 0;
473 +#endif
474 +               
475                 new_req = 0;
476                 switch (req.command) {
477                 case COMM_NONE:
478                         break;
479  
480                 case COMM_SEND_MEM:
481 -                       dump_send_mem(dump_ndev, &req, buff, len);
482 +                       dump_send_mem(&req, buff, len);
483                         break;
484  
485                 case COMM_EXIT:
486 @@ -549,10 +298,11 @@
487                 case COMM_HELLO:
488                         sprintf(tmp, "Hello, this is netdump version "
489                                         "0.%02d\n", NETCONSOLE_VERSION);
490 +                       
491                         reply.code = REPLY_HELLO;
492                         reply.nr = req.nr;
493                          reply.info = net_dev->curr_offset;
494 -                       dump_send_skb(dump_ndev, tmp, strlen(tmp), &reply);
495 +                       dump_send_skb(tmp, strlen(tmp), &reply);
496                         break;
497  
498                 case COMM_GET_PAGE_SIZE:
499 @@ -560,7 +310,7 @@
500                         reply.code = REPLY_PAGE_SIZE;
501                         reply.nr = req.nr;
502                         reply.info = PAGE_SIZE;
503 -                       dump_send_skb(dump_ndev, tmp, strlen(tmp), &reply);
504 +                       dump_send_skb(tmp, strlen(tmp), &reply);
505                         break;
506  
507                 case COMM_GET_NR_PAGES:
508 @@ -569,15 +319,14 @@
509                         reply.info = num_physpages;
510                          reply.info = page_counter;
511                         sprintf(tmp, "Number of pages: %ld\n", num_physpages);
512 -                       dump_send_skb(dump_ndev, tmp, strlen(tmp), &reply);
513 +                       dump_send_skb(tmp, strlen(tmp), &reply);
514                         break;
515  
516                 case COMM_GET_MAGIC:
517                         reply.code = REPLY_MAGIC;
518                         reply.nr = req.nr;
519                         reply.info = NETCONSOLE_VERSION;
520 -                       dump_send_skb(dump_ndev, (char *)&dump_magic,
521 -                                       sizeof(dump_magic), &reply);
522 +                       dump_send_skb((char *)&dump_magic, sizeof(dump_magic), &reply);
523                         break;
524                  case COMM_SYSRQ:
525                         dump_do_sysrq(req.from);
526 @@ -585,7 +334,7 @@
527                         reply.nr = req.nr;
528                         reply.info = req.from;
529                         sprintf(tmp, "SYSRQ command %d \n", req.from);
530 -                       dump_send_skb(dump_ndev, tmp, strlen(tmp), &reply);
531 +                       dump_send_skb(tmp, strlen(tmp), &reply);
532                         break;
533                 default:
534                         reply.code = REPLY_ERROR;
535 @@ -593,7 +342,7 @@
536                         reply.info = req.command;
537                         sprintf(tmp, "Got unknown command code %d!\n",
538                                         req.command);
539 -                       dump_send_skb(dump_ndev, tmp, strlen(tmp), &reply);
540 +                       dump_send_skb(tmp, strlen(tmp), &reply);
541                         break;
542                 }
543         }
544 @@ -605,45 +354,45 @@
545  static int
546  dump_validate_config(void)
547  {
548 -       source_ip = dump_in_dev->ifa_list->ifa_local;
549 -       if (!source_ip) {
550 +#if 0
551 +       np.local_ip = dump_in_dev->ifa_list->ifa_local;
552 +       if (!np.local_ip) {
553                 printk("network device %s has no local address, "
554                                 "aborting.\n", device_name);
555                 return -1;
556         }
557 -
558 -#define IP(x) ((unsigned char *)&source_ip)[x]
559 +#endif
560 +#define IP(x) ((unsigned char *)&np.local_ip)[x]
561         printk("Source %d.%d.%d.%d", IP(0), IP(1), IP(2), IP(3));
562  #undef IP
563  
564 -       if (!source_port) {
565 +       if (!np.local_port) {
566                 printk("source_port parameter not specified, aborting.\n");
567                 return -1;
568         }
569 -       printk(":%i\n", source_port);
570 -       source_port = htons(source_port);
571 +       printk(":%i\n", np.local_port);
572  
573 -       if (!target_ip) {
574 +       if (!np.remote_ip) {
575                 printk("target_ip parameter not specified, aborting.\n");
576                 return -1;
577         }
578  
579 -#define IP(x) ((unsigned char *)&target_ip)[x]
580 +#define IP(x) ((unsigned char *)&np.remote_ip)[x]
581         printk("Target %d.%d.%d.%d", IP(0), IP(1), IP(2), IP(3));
582  #undef IP
583  
584 -       if (!target_port) {
585 +       if (!np.remote_port) {
586                 printk("target_port parameter not specified, aborting.\n");
587                 return -1;
588         }
589 -       printk(":%i\n", target_port);
590 -       target_port = htons(target_port);
591 +       printk(":%i\n", np.remote_port);
592  
593         printk("Target Ethernet Address %02x:%02x:%02x:%02x:%02x:%02x",
594 -               daddr[0], daddr[1], daddr[2], daddr[3], daddr[4], daddr[5]);
595 +               np.remote_mac[0], np.remote_mac[1], np.remote_mac[2], 
596 +               np.remote_mac[3], np.remote_mac[4], np.remote_mac[5]);
597  
598 -       if ((daddr[0] & daddr[1] & daddr[2] & daddr[3] & daddr[4] & 
599 -                               daddr[5]) == 255)
600 +       if ((np.remote_mac[0] & np.remote_mac[1] & np.remote_mac[2] & 
601 +               np.remote_mac[3] & np.remote_mac[4] & np.remote_mac[5]) == 255)
602                 printk("(Broadcast)");
603         printk("\n");
604         return 0;
605 @@ -659,31 +408,24 @@
606  dump_net_open(struct dump_dev *net_dev, unsigned long arg)
607  {
608         int retval = 0;
609 -
610 +#if 0
611         /* get the interface name */
612         if (copy_from_user(device_name, (void *)arg, IFNAMSIZ))
613                 return -EFAULT;
614  
615 -       if (!(dump_ndev = dev_get_by_name(device_name))) {
616 +       if (!(np.dev = dev_get_by_name(device_name))) {
617                 printk("network device %s does not exist, aborting.\n",
618                                 device_name);
619                 return -ENODEV;
620         }
621 -
622 -       if (!dump_ndev->poll_controller) {
623 -               printk("network device %s does not implement polling yet, "
624 -                               "aborting.\n", device_name);
625 -               retval = -1; /* return proper error */
626 -               goto err1;
627 -       }
628 -
629 -       if (!(dump_in_dev = in_dev_get(dump_ndev))) {
630 +#endif
631 +       if (!(dump_in_dev = in_dev_get(np.dev))) {
632                 printk("network device %s is not an IP protocol device, "
633                                 "aborting.\n", device_name);
634                 retval = -EINVAL;
635                 goto err1;
636         }
637 -
638 +       
639         if ((retval = dump_validate_config()) < 0)
640                 goto err2;
641  
642 @@ -694,7 +436,7 @@
643  err2:
644         in_dev_put(dump_in_dev);
645  err1:
646 -       dev_put(dump_ndev);     
647 +       dev_put(np.dev);        
648         return retval;
649  }
650  
651 @@ -707,8 +449,8 @@
652  {
653         if (dump_in_dev)
654                 in_dev_put(dump_in_dev);
655 -       if (dump_ndev)
656 -               dev_put(dump_ndev);
657 +       if (np.dev)
658 +               dev_put(np.dev);
659         return 0;
660  }
661  
662 @@ -720,7 +462,6 @@
663  dump_net_silence(struct dump_dev *net_dev)
664  {
665         local_irq_save(flags_global);
666 -       dump_ndev->rx_hook = dump_rx_hook;
667          startup_handshake = 1;
668         net_dev->curr_offset = 0;
669         printk("Dumping to network device %s on CPU %d ...\n", device_name,
670 @@ -740,7 +481,7 @@
671         reply_t reply;
672         char tmp[200];
673  
674 -        if (!dump_ndev)
675 +        if (!np.dev)
676                 return (0);
677  
678         sprintf(tmp, "NETDUMP end.\n");
679 @@ -748,11 +489,10 @@
680                 reply.code = REPLY_END_NETDUMP;
681                 reply.nr = 0;
682                 reply.info = 0;
683 -               dump_send_skb(dump_ndev, tmp, strlen(tmp), &reply);
684 +               dump_send_skb(tmp, strlen(tmp), &reply);
685         }
686         printk("NETDUMP END!\n");
687         local_irq_restore(flags_global);
688 -       dump_ndev->rx_hook = NULL;
689         startup_handshake = 0;
690         return 0;
691  }
692 @@ -809,18 +549,19 @@
693  static int
694  dump_net_ioctl(struct dump_dev *net_dev, unsigned int cmd, unsigned long arg)
695  {
696 +       #if 0
697         switch (cmd) {
698         case DIOSTARGETIP:
699 -               target_ip = arg;
700 +               np.remote_ip = arg;
701                 break;
702         case DIOSTARGETPORT:
703 -               target_port = (u16)arg;
704 +               np.remote_port = (u16)arg;
705                 break;
706         case DIOSSOURCEPORT:
707 -               source_port = (u16)arg;
708 +               np.local_port = (u16)arg;
709                 break;
710         case DIOSETHADDR:
711 -               return copy_from_user(daddr, (void *)arg, 6);
712 +               return copy_from_user(np.remote_mac, (void *)arg, 6);
713                 break;
714         case DIOGTARGETIP:
715         case DIOGTARGETPORT:
716 @@ -830,6 +571,7 @@
717         default:
718                 return -EINVAL;
719         }
720 +       #endif
721         return 0;
722  }
723  
724 @@ -851,17 +593,28 @@
725         .curr_offset = 0
726  };
727  
728 +static int option_setup(char *opt)
729 +{
730 +       return netpoll_parse_options(&np, opt);
731 +}
732 +
733 +__setup("netdumpoe=", option_setup);
734 +
735 +
736  static int __init
737  dump_netdev_init(void)
738  {
739          default_dump_netdev.curr_offset = 0;
740  
741 +       if(!np.remote_ip || netpoll_setup(&np))
742 +               return 1;
743 +
744         if (dump_register_device(&default_dump_netdev) < 0) {
745                 printk("network dump device driver registration failed\n");
746                 return -1;
747         }
748         printk("network device driver for LKCD registered\n");
749
750 +
751         get_random_bytes(&dump_magic, sizeof(dump_magic));
752         return 0;
753  }
754 @@ -870,6 +623,7 @@
755  dump_netdev_cleanup(void)
756  {
757         dump_unregister_device(&default_dump_netdev);
758 +       netpoll_cleanup(&np);
759  }
760  
761  MODULE_AUTHOR("LKCD Development Team <lkcd-devel@lists.sourceforge.net>");