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