1 /*
2 * INET An implementation of the TCP/IP protocol suite for the LINUX
3 * operating system. INET is implemented using the BSD Socket
4 * interface as the means of communication with the user level.
5 *
6 * ROUTE - implementation of the IP router.
7 *
8 * Version: @(#)route.c 1.0.14 05/31/93
9 *
10 * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * Alan Cox, <gw4pts@gw4pts.ampr.org>
13 * Linus Torvalds, <Linus.Torvalds@helsinki.fi>
14 *
15 * Fixes:
16 * Alan Cox : Verify area fixes.
17 * Alan Cox : cli() protects routing changes
18 * Rui Oliveira : ICMP routing table updates
19 * (rco@di.uminho.pt) Routing table insertion and update
20 * Linus Torvalds : Rewrote bits to be sensible
21 * Alan Cox : Added BSD route gw semantics
22 * Alan Cox : Super /proc >4K
23 * Alan Cox : MTU in route table
24 * Alan Cox : MSS actually. Also added the window
25 * clamper.
26 * Sam Lantinga : Fixed route matching in rt_del()
27 *
28 * This program is free software; you can redistribute it and/or
29 * modify it under the terms of the GNU General Public License
30 * as published by the Free Software Foundation; either version
31 * 2 of the License, or (at your option) any later version.
32 */
33
34 #include <asm/segment.h>
35 #include <asm/system.h>
36 #include <linux/types.h>
37 #include <linux/kernel.h>
38 #include <linux/sched.h>
39 #include <linux/mm.h>
40 #include <linux/string.h>
41 #include <linux/socket.h>
42 #include <linux/sockios.h>
43 #include <linux/errno.h>
44 #include <linux/in.h>
45 #include <linux/inet.h>
46 #include <linux/netdevice.h>
47 #include "ip.h"
48 #include "protocol.h"
49 #include "route.h"
50 #include "tcp.h"
51 #include <linux/skbuff.h>
52 #include "sock.h"
53 #include "icmp.h"
54
55 /*
56 * The routing table list
57 */
58
59 static struct rtable *rt_base = NULL;
60
61 /*
62 * Pointer to the loopback route
63 */
64
65 static struct rtable *rt_loopback = NULL;
66
67 /*
68 * Remove a routing table entry.
69 */
70
71 static void rt_del(unsigned long dst, char *devname)
/* ![[previous]](../icons/n_left.png)
![[next]](../icons/right.png)
![[first]](../icons/n_first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
72 {
73 struct rtable *r, **rp;
74 unsigned long flags;
75
76 rp = &rt_base;
77
78 /*
79 * This must be done with interrupts off because we could take
80 * an ICMP_REDIRECT.
81 */
82
83 save_flags(flags);
84 cli();
85 while((r = *rp) != NULL)
86 {
87 /* Make sure both the destination and the device match */
88 if ( r->rt_dst != dst ||
89 (devname != NULL && strcmp((r->rt_dev)->name,devname) != 0) )
90 {
91 rp = &r->rt_next;
92 continue;
93 }
94 *rp = r->rt_next;
95
96 /*
97 * If we delete the loopback route update its pointer.
98 */
99
100 if (rt_loopback == r)
101 rt_loopback = NULL;
102 kfree_s(r, sizeof(struct rtable));
103 }
104 restore_flags(flags);
105 }
106
107
108 /*
109 * Remove all routing table entries for a device. This is called when
110 * a device is downed.
111 */
112
113 void ip_rt_flush(struct device *dev)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
114 {
115 struct rtable *r;
116 struct rtable **rp;
117 unsigned long flags;
118
119 rp = &rt_base;
120 save_flags(flags);
121 cli();
122 while ((r = *rp) != NULL) {
123 if (r->rt_dev != dev) {
124 rp = &r->rt_next;
125 continue;
126 }
127 *rp = r->rt_next;
128 if (rt_loopback == r)
129 rt_loopback = NULL;
130 kfree_s(r, sizeof(struct rtable));
131 }
132 restore_flags(flags);
133 }
134
135 /*
136 * Used by 'rt_add()' when we can't get the netmask any other way..
137 *
138 * If the lower byte or two are zero, we guess the mask based on the
139 * number of zero 8-bit net numbers, otherwise we use the "default"
140 * masks judging by the destination address and our device netmask.
141 */
142
143 static inline unsigned long default_mask(unsigned long dst)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
144 {
145 dst = ntohl(dst);
146 if (IN_CLASSA(dst))
147 return htonl(IN_CLASSA_NET);
148 if (IN_CLASSB(dst))
149 return htonl(IN_CLASSB_NET);
150 return htonl(IN_CLASSC_NET);
151 }
152
153
154 /*
155 * If no mask is specified then generate a default entry.
156 */
157
158 static unsigned long guess_mask(unsigned long dst, struct device * dev)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
159 {
160 unsigned long mask;
161
162 if (!dst)
163 return 0;
164 mask = default_mask(dst);
165 if ((dst ^ dev->pa_addr) & mask)
166 return mask;
167 return dev->pa_mask;
168 }
169
170
171 /*
172 * Find the route entry through which our gateway will be reached
173 */
174
175 static inline struct device * get_gw_dev(unsigned long gw)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
176 {
177 struct rtable * rt;
178
179 for (rt = rt_base ; ; rt = rt->rt_next)
180 {
181 if (!rt)
182 return NULL;
183 if ((gw ^ rt->rt_dst) & rt->rt_mask)
184 continue;
185 /*
186 * Gateways behind gateways are a no-no
187 */
188
189 if (rt->rt_flags & RTF_GATEWAY)
190 return NULL;
191 return rt->rt_dev;
192 }
193 }
194
195 /*
196 * Rewrote rt_add(), as the old one was weird - Linus
197 *
198 * This routine is used to update the IP routing table, either
199 * from the kernel (ICMP_REDIRECT) or via an ioctl call issued
200 * by the superuser.
201 */
202
203 void ip_rt_add(short flags, unsigned long dst, unsigned long mask,
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
204 unsigned long gw, struct device *dev, unsigned short mtu, unsigned long window)
205 {
206 struct rtable *r, *rt;
207 struct rtable **rp;
208 unsigned long cpuflags;
209
210 /*
211 * A host is a unique machine and has no network bits.
212 */
213
214 if (flags & RTF_HOST)
215 {
216 mask = 0xffffffff;
217 }
218
219 /*
220 * Calculate the network mask
221 */
222
223 else if (!mask)
224 {
225 if (!((dst ^ dev->pa_addr) & dev->pa_mask))
226 {
227 mask = dev->pa_mask;
228 flags &= ~RTF_GATEWAY;
229 if (flags & RTF_DYNAMIC)
230 {
231 /*printk("Dynamic route to my own net rejected\n");*/
232 return;
233 }
234 }
235 else
236 mask = guess_mask(dst, dev);
237 dst &= mask;
238 }
239
240 /*
241 * A gateway must be reachable and not a local address
242 */
243
244 if (gw == dev->pa_addr)
245 flags &= ~RTF_GATEWAY;
246
247 if (flags & RTF_GATEWAY)
248 {
249 /*
250 * Don't try to add a gateway we can't reach..
251 */
252
253 if (dev != get_gw_dev(gw))
254 return;
255
256 flags |= RTF_GATEWAY;
257 }
258 else
259 gw = 0;
260
261 /*
262 * Allocate an entry and fill it in.
263 */
264
265 rt = (struct rtable *) kmalloc(sizeof(struct rtable), GFP_ATOMIC);
266 if (rt == NULL)
267 {
268 return;
269 }
270 memset(rt, 0, sizeof(struct rtable));
271 rt->rt_flags = flags | RTF_UP;
272 rt->rt_dst = dst;
273 rt->rt_dev = dev;
274 rt->rt_gateway = gw;
275 rt->rt_mask = mask;
276 rt->rt_mss = dev->mtu - HEADER_SIZE;
277 rt->rt_window = 0; /* Default is no clamping */
278
279 /* Are the MSS/Window valid ? */
280
281 if(rt->rt_flags & RTF_MSS)
282 rt->rt_mss = mtu;
283
284 if(rt->rt_flags & RTF_WINDOW)
285 rt->rt_window = window;
286
287 /*
288 * What we have to do is loop though this until we have
289 * found the first address which has a higher generality than
290 * the one in rt. Then we can put rt in right before it.
291 * The interrupts must be off for this process.
292 */
293
294 save_flags(cpuflags);
295 cli();
296
297 /*
298 * Remove old route if we are getting a duplicate.
299 */
300
301 rp = &rt_base;
302 while ((r = *rp) != NULL)
303 {
304 if (r->rt_dst != dst)
305 {
306 rp = &r->rt_next;
307 continue;
308 }
309 *rp = r->rt_next;
310 if (rt_loopback == r)
311 rt_loopback = NULL;
312 kfree_s(r, sizeof(struct rtable));
313 }
314
315 /*
316 * Add the new route
317 */
318
319 rp = &rt_base;
320 while ((r = *rp) != NULL) {
321 if ((r->rt_mask & mask) != mask)
322 break;
323 rp = &r->rt_next;
324 }
325 rt->rt_next = r;
326 *rp = rt;
327
328 /*
329 * Update the loopback route
330 */
331
332 if ((rt->rt_dev->flags & IFF_LOOPBACK) && !rt_loopback)
333 rt_loopback = rt;
334
335 /*
336 * Restore the interrupts and return
337 */
338
339 restore_flags(cpuflags);
340 return;
341 }
342
343
344 /*
345 * Check if a mask is acceptable.
346 */
347
348 static inline int bad_mask(unsigned long mask, unsigned long addr)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
349 {
350 if (addr & (mask = ~mask))
351 return 1;
352 mask = ntohl(mask);
353 if (mask & (mask+1))
354 return 1;
355 return 0;
356 }
357
358 /*
359 * Process a route add request from the user
360 */
361
362 static int rt_new(struct rtentry *r)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
363 {
364 int err;
365 char * devname;
366 struct device * dev = NULL;
367 unsigned long flags, daddr, mask, gw;
368
369 /*
370 * If a device is specified find it.
371 */
372
373 if ((devname = r->rt_dev) != NULL)
374 {
375 err = getname(devname, &devname);
376 if (err)
377 return err;
378 dev = dev_get(devname);
379 putname(devname);
380 if (!dev)
381 return -EINVAL;
382 }
383
384 /*
385 * If the device isn't INET, don't allow it
386 */
387
388 if (r->rt_dst.sa_family != AF_INET)
389 return -EAFNOSUPPORT;
390
391 /*
392 * Make local copies of the important bits
393 */
394
395 flags = r->rt_flags;
396 daddr = ((struct sockaddr_in *) &r->rt_dst)->sin_addr.s_addr;
397 mask = ((struct sockaddr_in *) &r->rt_genmask)->sin_addr.s_addr;
398 gw = ((struct sockaddr_in *) &r->rt_gateway)->sin_addr.s_addr;
399
400
401 /*
402 * BSD emulation: Permits route add someroute gw one-of-my-addresses
403 * to indicate which iface. Not as clean as the nice Linux dev technique
404 * but people keep using it...
405 */
406
407 if (!dev && (flags & RTF_GATEWAY))
408 {
409 struct device *dev2;
410 for (dev2 = dev_base ; dev2 != NULL ; dev2 = dev2->next)
411 {
412 if ((dev2->flags & IFF_UP) && dev2->pa_addr == gw)
413 {
414 flags &= ~RTF_GATEWAY;
415 dev = dev2;
416 break;
417 }
418 }
419 }
420
421 /*
422 * Ignore faulty masks
423 */
424
425 if (bad_mask(mask, daddr))
426 mask = 0;
427
428 /*
429 * Set the mask to nothing for host routes.
430 */
431
432 if (flags & RTF_HOST)
433 mask = 0xffffffff;
434 else if (mask && r->rt_genmask.sa_family != AF_INET)
435 return -EAFNOSUPPORT;
436
437 /*
438 * You can only gateway IP via IP..
439 */
440
441 if (flags & RTF_GATEWAY)
442 {
443 if (r->rt_gateway.sa_family != AF_INET)
444 return -EAFNOSUPPORT;
445 if (!dev)
446 dev = get_gw_dev(gw);
447 }
448 else if (!dev)
449 dev = ip_dev_check(daddr);
450
451 /*
452 * Unknown device.
453 */
454
455 if (dev == NULL)
456 return -ENETUNREACH;
457
458 /*
459 * Add the route
460 */
461
462 ip_rt_add(flags, daddr, mask, gw, dev, r->rt_mss, r->rt_window);
463 return 0;
464 }
465
466
467 /*
468 * Remove a route, as requested by the user.
469 */
470
471 static int rt_kill(struct rtentry *r)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
472 {
473 struct sockaddr_in *trg;
474 char *devname;
475 int err;
476
477 trg = (struct sockaddr_in *) &r->rt_dst;
478 if ((devname = r->rt_dev) != NULL)
479 {
480 err = getname(devname, &devname);
481 if (err)
482 return err;
483 }
484 rt_del(trg->sin_addr.s_addr, devname);
485 if ( devname != NULL )
486 putname(devname);
487 return 0;
488 }
489
490
491 /*
492 * Called from the PROCfs module. This outputs /proc/net/route.
493 */
494
495 int rt_get_info(char *buffer, char **start, off_t offset, int length)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
496 {
497 struct rtable *r;
498 int len=0;
499 off_t pos=0;
500 off_t begin=0;
501 int size;
502
503 len += sprintf(buffer,
504 "Iface\tDestination\tGateway \tFlags\tRefCnt\tUse\tMetric\tMask\t\tMTU\tWindow\n");
505 pos=len;
506
507 /*
508 * This isn't quite right -- r->rt_dst is a struct!
509 */
510
511 for (r = rt_base; r != NULL; r = r->rt_next)
512 {
513 size = sprintf(buffer+len, "%s\t%08lX\t%08lX\t%02X\t%d\t%lu\t%d\t%08lX\t%d\t%lu\n",
514 r->rt_dev->name, r->rt_dst, r->rt_gateway,
515 r->rt_flags, r->rt_refcnt, r->rt_use, r->rt_metric,
516 r->rt_mask, (int)r->rt_mss, r->rt_window);
517 len+=size;
518 pos+=size;
519 if(pos<offset)
520 {
521 len=0;
522 begin=pos;
523 }
524 if(pos>offset+length)
525 break;
526 }
527
528 *start=buffer+(offset-begin);
529 len-=(offset-begin);
530 if(len>length)
531 len=length;
532 return len;
533 }
534
535 /*
536 * This is hackish, but results in better code. Use "-S" to see why.
537 */
538
539 #define early_out ({ goto no_route; 1; })
540
541 /*
542 * Route a packet. This needs to be fairly quick. Florian & Co.
543 * suggested a unified ARP and IP routing cache. Done right its
544 * probably a brilliant idea. I'd actually suggest a unified
545 * ARP/IP routing/Socket pointer cache. Volunteers welcome
546 */
547
548 struct rtable * ip_rt_route(unsigned long daddr, struct options *opt, unsigned long *src_addr)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
549 {
550 struct rtable *rt;
551
552 for (rt = rt_base; rt != NULL || early_out ; rt = rt->rt_next)
553 {
554 if (!((rt->rt_dst ^ daddr) & rt->rt_mask))
555 break;
556 /*
557 * broadcast addresses can be special cases..
558 */
559 if (rt->rt_flags & RTF_GATEWAY)
560 continue;
561 if ((rt->rt_dev->flags & IFF_BROADCAST) &&
562 (rt->rt_dev->pa_brdaddr == daddr))
563 break;
564 }
565
566 if(src_addr!=NULL)
567 *src_addr= rt->rt_dev->pa_addr;
568
569 if (daddr == rt->rt_dev->pa_addr) {
570 if ((rt = rt_loopback) == NULL)
571 goto no_route;
572 }
573 rt->rt_use++;
574 return rt;
575 no_route:
576 return NULL;
577 }
578
579 struct rtable * ip_rt_local(unsigned long daddr, struct options *opt, unsigned long *src_addr)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
580 {
581 struct rtable *rt;
582
583 for (rt = rt_base; rt != NULL || early_out ; rt = rt->rt_next)
584 {
585 /*
586 * No routed addressing.
587 */
588 if (rt->rt_flags&RTF_GATEWAY)
589 continue;
590
591 if (!((rt->rt_dst ^ daddr) & rt->rt_mask))
592 break;
593 /*
594 * broadcast addresses can be special cases..
595 */
596
597 if ((rt->rt_dev->flags & IFF_BROADCAST) &&
598 rt->rt_dev->pa_brdaddr == daddr)
599 break;
600 }
601
602 if(src_addr!=NULL)
603 *src_addr= rt->rt_dev->pa_addr;
604
605 if (daddr == rt->rt_dev->pa_addr) {
606 if ((rt = rt_loopback) == NULL)
607 goto no_route;
608 }
609 rt->rt_use++;
610 return rt;
611 no_route:
612 return NULL;
613 }
614
615 /*
616 * Backwards compatibility
617 */
618
619 static int ip_get_old_rtent(struct old_rtentry * src, struct rtentry * rt)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
620 {
621 int err;
622 struct old_rtentry tmp;
623
624 err=verify_area(VERIFY_READ, src, sizeof(*src));
625 if (err)
626 return err;
627 memcpy_fromfs(&tmp, src, sizeof(*src));
628 memset(rt, 0, sizeof(*rt));
629 rt->rt_dst = tmp.rt_dst;
630 rt->rt_gateway = tmp.rt_gateway;
631 rt->rt_genmask.sa_family = AF_INET;
632 ((struct sockaddr_in *) &rt->rt_genmask)->sin_addr.s_addr = tmp.rt_genmask;
633 rt->rt_flags = tmp.rt_flags;
634 rt->rt_dev = tmp.rt_dev;
635 printk("Warning: obsolete routing request made.\n");
636 return 0;
637 }
638
639 /*
640 * Handle IP routing ioctl calls. These are used to manipulate the routing tables
641 */
642
643 int ip_rt_ioctl(unsigned int cmd, void *arg)
/* ![[previous]](../icons/left.png)
![[next]](../icons/n_right.png)
![[first]](../icons/first.png)
![[last]](../icons/n_last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
644 {
645 int err;
646 struct rtentry rt;
647
648 switch(cmd)
649 {
650 case SIOCADDRTOLD: /* Old style add route */
651 case SIOCDELRTOLD: /* Old style delete route */
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: /* Add a route */
660 case SIOCDELRT: /* Delete a route */
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 }