This source file includes following definitions.
- rt_print
- rt_del
- ip_rt_flush
- default_mask
- guess_mask
- get_gw_dev
- ip_rt_add
- bad_mask
- rt_new
- rt_kill
- rt_get_info
- ip_rt_route
- ip_rt_local
- ip_get_old_rtent
- ip_rt_ioctl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 #include <asm/segment.h>
31 #include <asm/system.h>
32 #include <linux/types.h>
33 #include <linux/kernel.h>
34 #include <linux/sched.h>
35 #include <linux/string.h>
36 #include <linux/socket.h>
37 #include <linux/sockios.h>
38 #include <linux/errno.h>
39 #include <linux/in.h>
40 #include <linux/inet.h>
41 #include <linux/netdevice.h>
42 #include "ip.h"
43 #include "protocol.h"
44 #include "route.h"
45 #include "tcp.h"
46 #include <linux/skbuff.h>
47 #include "sock.h"
48 #include "icmp.h"
49
50
51
52
53
54 static struct rtable *rt_base = NULL;
55
56
57
58
59
60 static struct rtable *rt_loopback = NULL;
61
62
63
64
65
66 static void rt_print(struct rtable *rt)
67 {
68
69 if (rt == NULL || inet_debug != DBG_RT)
70 return;
71
72 printk("RT: %06lx NXT=%06lx FLAGS=0x%02x\n",
73 (long) rt, (long) rt->rt_next, rt->rt_flags);
74 printk(" TARGET=%s ", in_ntoa(rt->rt_dst));
75 printk("GW=%s ", in_ntoa(rt->rt_gateway));
76 printk(" DEV=%s USE=%ld REF=%d\n",
77 (rt->rt_dev == NULL) ? "NONE" : rt->rt_dev->name,
78 rt->rt_use, rt->rt_refcnt);
79 }
80
81
82
83
84
85
86 static void rt_del(unsigned long dst)
87 {
88 struct rtable *r, **rp;
89 unsigned long flags;
90
91 DPRINTF((DBG_RT, "RT: flushing for dst %s\n", in_ntoa(dst)));
92 rp = &rt_base;
93
94
95
96
97
98
99 save_flags(flags);
100 cli();
101 while((r = *rp) != NULL)
102 {
103 if (r->rt_dst != dst)
104 {
105 rp = &r->rt_next;
106 continue;
107 }
108 *rp = r->rt_next;
109
110
111
112
113
114 if (rt_loopback == r)
115 rt_loopback = NULL;
116 kfree_s(r, sizeof(struct rtable));
117 }
118 restore_flags(flags);
119 }
120
121
122
123
124
125
126
127 void ip_rt_flush(struct device *dev)
128 {
129 struct rtable *r;
130 struct rtable **rp;
131 unsigned long flags;
132
133 DPRINTF((DBG_RT, "RT: flushing for dev 0x%08lx (%s)\n", (long)dev, dev->name));
134 rp = &rt_base;
135 cli();
136 save_flags(flags);
137 while ((r = *rp) != NULL) {
138 if (r->rt_dev != dev) {
139 rp = &r->rt_next;
140 continue;
141 }
142 *rp = r->rt_next;
143 if (rt_loopback == r)
144 rt_loopback = NULL;
145 kfree_s(r, sizeof(struct rtable));
146 }
147 restore_flags(flags);
148 }
149
150
151
152
153
154
155
156
157
158 static inline unsigned long default_mask(unsigned long dst)
159 {
160 dst = ntohl(dst);
161 if (IN_CLASSA(dst))
162 return htonl(IN_CLASSA_NET);
163 if (IN_CLASSB(dst))
164 return htonl(IN_CLASSB_NET);
165 return htonl(IN_CLASSC_NET);
166 }
167
168
169
170
171
172
173 static unsigned long guess_mask(unsigned long dst, struct device * dev)
174 {
175 unsigned long mask;
176
177 if (!dst)
178 return 0;
179 mask = default_mask(dst);
180 if ((dst ^ dev->pa_addr) & mask)
181 return mask;
182 return dev->pa_mask;
183 }
184
185
186
187
188
189
190 static inline struct device * get_gw_dev(unsigned long gw)
191 {
192 struct rtable * rt;
193
194 for (rt = rt_base ; ; rt = rt->rt_next)
195 {
196 if (!rt)
197 return NULL;
198 if ((gw ^ rt->rt_dst) & rt->rt_mask)
199 continue;
200
201
202
203
204 if (rt->rt_flags & RTF_GATEWAY)
205 return NULL;
206 return rt->rt_dev;
207 }
208 }
209
210
211
212
213
214
215
216
217
218 void ip_rt_add(short flags, unsigned long dst, unsigned long mask,
219 unsigned long gw, struct device *dev)
220 {
221 struct rtable *r, *rt;
222 struct rtable **rp;
223 unsigned long cpuflags;
224
225
226
227
228
229 if (flags & RTF_HOST)
230 {
231 mask = 0xffffffff;
232 }
233
234
235
236
237
238 else if (!mask)
239 {
240 if (!((dst ^ dev->pa_addr) & dev->pa_mask))
241 {
242 mask = dev->pa_mask;
243 flags &= ~RTF_GATEWAY;
244 if (flags & RTF_DYNAMIC)
245 {
246
247 return;
248 }
249 }
250 else
251 mask = guess_mask(dst, dev);
252 dst &= mask;
253 }
254
255
256
257
258
259 if (gw == dev->pa_addr)
260 flags &= ~RTF_GATEWAY;
261
262 if (flags & RTF_GATEWAY)
263 {
264
265
266
267
268 if (dev != get_gw_dev(gw))
269 return;
270
271 flags |= RTF_GATEWAY;
272 }
273 else
274 gw = 0;
275
276
277
278
279
280 rt = (struct rtable *) kmalloc(sizeof(struct rtable), GFP_ATOMIC);
281 if (rt == NULL)
282 {
283 DPRINTF((DBG_RT, "RT: no memory for new route!\n"));
284 return;
285 }
286 memset(rt, 0, sizeof(struct rtable));
287 rt->rt_flags = flags | RTF_UP;
288 rt->rt_dst = dst;
289 rt->rt_dev = dev;
290 rt->rt_gateway = gw;
291 rt->rt_mask = mask;
292 rt->rt_mtu = dev->mtu;
293 rt_print(rt);
294
295
296
297
298
299
300
301
302 save_flags(cpuflags);
303 cli();
304
305
306
307
308
309 rp = &rt_base;
310 while ((r = *rp) != NULL)
311 {
312 if (r->rt_dst != dst)
313 {
314 rp = &r->rt_next;
315 continue;
316 }
317 *rp = r->rt_next;
318 if (rt_loopback == r)
319 rt_loopback = NULL;
320 kfree_s(r, sizeof(struct rtable));
321 }
322
323
324
325
326
327 rp = &rt_base;
328 while ((r = *rp) != NULL) {
329 if ((r->rt_mask & mask) != mask)
330 break;
331 rp = &r->rt_next;
332 }
333 rt->rt_next = r;
334 *rp = rt;
335
336
337
338
339
340 if (rt->rt_dev->flags & IFF_LOOPBACK)
341 rt_loopback = rt;
342
343
344
345
346
347 restore_flags(cpuflags);
348 return;
349 }
350
351
352
353
354
355
356 static inline int bad_mask(unsigned long mask, unsigned long addr)
357 {
358 if (addr & (mask = ~mask))
359 return 1;
360 mask = ntohl(mask);
361 if (mask & (mask+1))
362 return 1;
363 return 0;
364 }
365
366
367
368
369
370 static int rt_new(struct rtentry *r)
371 {
372 int err;
373 char * devname;
374 struct device * dev = NULL;
375 unsigned long flags, daddr, mask, gw;
376
377
378
379
380
381 if ((devname = r->rt_dev) != NULL)
382 {
383 err = getname(devname, &devname);
384 if (err)
385 return err;
386 dev = dev_get(devname);
387 putname(devname);
388 if (!dev)
389 return -EINVAL;
390 }
391
392
393
394
395
396 if (r->rt_dst.sa_family != AF_INET)
397 return -EAFNOSUPPORT;
398
399
400
401
402
403 flags = r->rt_flags;
404 daddr = ((struct sockaddr_in *) &r->rt_dst)->sin_addr.s_addr;
405 mask = ((struct sockaddr_in *) &r->rt_genmask)->sin_addr.s_addr;
406 gw = ((struct sockaddr_in *) &r->rt_gateway)->sin_addr.s_addr;
407
408
409
410
411
412
413
414
415 if (!dev && (flags & RTF_GATEWAY))
416 {
417 struct device *dev2;
418 for (dev2 = dev_base ; dev2 != NULL ; dev2 = dev2->next)
419 {
420 if ((dev2->flags & IFF_UP) && dev2->pa_addr == gw)
421 {
422 flags &= ~RTF_GATEWAY;
423 dev = dev2;
424 break;
425 }
426 }
427 }
428
429
430
431
432
433 if (bad_mask(mask, daddr))
434 mask = 0;
435
436
437
438
439
440 if (flags & RTF_HOST)
441 mask = 0xffffffff;
442 else if (mask && r->rt_genmask.sa_family != AF_INET)
443 return -EAFNOSUPPORT;
444
445
446
447
448
449 if (flags & RTF_GATEWAY)
450 {
451 if (r->rt_gateway.sa_family != AF_INET)
452 return -EAFNOSUPPORT;
453 if (!dev)
454 dev = get_gw_dev(gw);
455 }
456 else if (!dev)
457 dev = ip_dev_check(daddr);
458
459
460
461
462
463 if (dev == NULL)
464 return -ENETUNREACH;
465
466
467
468
469
470 ip_rt_add(flags, daddr, mask, gw, dev);
471 return 0;
472 }
473
474
475
476
477
478
479 static int rt_kill(struct rtentry *r)
480 {
481 struct sockaddr_in *trg;
482
483 trg = (struct sockaddr_in *) &r->rt_dst;
484 rt_del(trg->sin_addr.s_addr);
485 return 0;
486 }
487
488
489
490
491
492
493 int rt_get_info(char *buffer, char **start, off_t offset, int length)
494 {
495 struct rtable *r;
496 int len=0;
497 off_t pos=0;
498 off_t begin=0;
499 int size;
500
501 len += sprintf(buffer,
502 "Iface\tDestination\tGateway \tFlags\tRefCnt\tUse\tMetric\tMask\n");
503 pos=len;
504
505
506
507
508
509 for (r = rt_base; r != NULL; r = r->rt_next)
510 {
511 size = sprintf(buffer+len, "%s\t%08lX\t%08lX\t%02X\t%d\t%lu\t%d\t%08lX\n",
512 r->rt_dev->name, r->rt_dst, r->rt_gateway,
513 r->rt_flags, r->rt_refcnt, r->rt_use, r->rt_metric,
514 r->rt_mask);
515 len+=size;
516 pos+=size;
517 if(pos<offset)
518 {
519 len=0;
520 begin=pos;
521 }
522 if(pos>offset+length)
523 break;
524 }
525
526 *start=buffer+(offset-begin);
527 len-=(offset-begin);
528 if(len>length)
529 len=length;
530 return len;
531 }
532
533
534
535
536
537 #define early_out ({ goto no_route; 1; })
538
539
540
541
542
543
544
545
546 struct rtable * ip_rt_route(unsigned long daddr, struct options *opt, unsigned long *src_addr)
547 {
548 struct rtable *rt;
549
550 for (rt = rt_base; rt != NULL || early_out ; rt = rt->rt_next)
551 {
552 if (!((rt->rt_dst ^ daddr) & rt->rt_mask))
553 break;
554
555
556
557
558 if ((rt->rt_dev->flags & IFF_BROADCAST) &&
559 rt->rt_dev->pa_brdaddr == daddr)
560 break;
561 }
562
563 if(src_addr!=NULL)
564 *src_addr= rt->rt_dev->pa_addr;
565
566 if (daddr == rt->rt_dev->pa_addr) {
567 if ((rt = rt_loopback) == NULL)
568 goto no_route;
569 }
570 rt->rt_use++;
571 return rt;
572 no_route:
573 return NULL;
574 }
575
576 struct rtable * ip_rt_local(unsigned long daddr, struct options *opt, unsigned long *src_addr)
577 {
578 struct rtable *rt;
579
580 for (rt = rt_base; rt != NULL || early_out ; rt = rt->rt_next)
581 {
582
583
584
585 if (rt->rt_flags&RTF_GATEWAY)
586 continue;
587
588 if (!((rt->rt_dst ^ daddr) & rt->rt_mask))
589 break;
590
591
592
593
594 if ((rt->rt_dev->flags & IFF_BROADCAST) &&
595 rt->rt_dev->pa_brdaddr == daddr)
596 break;
597 }
598
599 if(src_addr!=NULL)
600 *src_addr= rt->rt_dev->pa_addr;
601
602 if (daddr == rt->rt_dev->pa_addr) {
603 if ((rt = rt_loopback) == NULL)
604 goto no_route;
605 }
606 rt->rt_use++;
607 return rt;
608 no_route:
609 return NULL;
610 }
611
612
613
614
615
616 static int ip_get_old_rtent(struct old_rtentry * src, struct rtentry * rt)
617 {
618 int err;
619 struct old_rtentry tmp;
620
621 err=verify_area(VERIFY_READ, src, sizeof(*src));
622 if (err)
623 return err;
624 memcpy_fromfs(&tmp, src, sizeof(*src));
625 memset(rt, 0, sizeof(*rt));
626 rt->rt_dst = tmp.rt_dst;
627 rt->rt_gateway = tmp.rt_gateway;
628 rt->rt_genmask.sa_family = AF_INET;
629 ((struct sockaddr_in *) &rt->rt_genmask)->sin_addr.s_addr = tmp.rt_genmask;
630 rt->rt_flags = tmp.rt_flags;
631 rt->rt_dev = tmp.rt_dev;
632 printk("Warning: obsolete routing request made.\n");
633 return 0;
634 }
635
636
637
638
639
640 int ip_rt_ioctl(unsigned int cmd, void *arg)
641 {
642 int err;
643 struct rtentry rt;
644
645 switch(cmd)
646 {
647 case DDIOCSDBG:
648 return dbg_ioctl(arg, DBG_RT);
649
650 case SIOCADDRTOLD:
651 case SIOCDELRTOLD:
652 if (!suser())
653 return -EPERM;
654 err = ip_get_old_rtent((struct old_rtentry *) arg, &rt);
655 if (err)
656 return err;
657 return (cmd == SIOCDELRTOLD) ? rt_kill(&rt) : rt_new(&rt);
658
659 case SIOCADDRT:
660 case SIOCDELRT:
661 if (!suser())
662 return -EPERM;
663 err=verify_area(VERIFY_READ, arg, sizeof(struct rtentry));
664 if (err)
665 return err;
666 memcpy_fromfs(&rt, arg, sizeof(struct rtentry));
667 return (cmd == SIOCDELRT) ? rt_kill(&rt) : rt_new(&rt);
668 }
669
670 return -EINVAL;
671 }