aboutsummaryrefslogtreecommitdiff
path: root/pfinet/linux-inet/route.c
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2000-02-04 06:32:39 +0000
committerRoland McGrath <roland@gnu.org>2000-02-04 06:32:39 +0000
commitdb9a26cbd125ec106e040ea6084911f9bc0c0198 (patch)
tree8394aedf0addf9de2afd46d00c192d20d9eb9092 /pfinet/linux-inet/route.c
parent8880a73970b23f10c720011cb910c0e0e1e02975 (diff)
downloadhurd-db9a26cbd125ec106e040ea6084911f9bc0c0198.tar.gz
hurd-db9a26cbd125ec106e040ea6084911f9bc0c0198.tar.bz2
hurd-db9a26cbd125ec106e040ea6084911f9bc0c0198.zip
2000-02-03 Roland McGrath <roland@baalperazim.frob.com>
Complete overhaul of pfinet based on the IPv4 networking code from the Linux 2.2.12 kernel sources. This page describes a single unified set of interdependent changes, but there are so many changes that I have broken up the log entry into paragraphs based on rough topical divisions of the work involved. Subset of verbatim Linux 2.2.12 sources imported on a vendor branch. * linux-src: New directory, see README for details. * README: New file, describes linux-src layout and procedures for tracking Linux source updates. Light modifications to linux-src files to avoid really bending over backwards with the glue macros. All modifications to files in linux-src are conditionalized by #ifdef _HURD_. * linux-src/include/linux/net.h [_HURD_] (struct socket): New members refcnt and identity; elide members fasync_list, file. * linux-src/include/linux/rtnetlink.h [! CONFIG_RTNETLINK] (rtnl_shlock, rtnl_shunlock) [! _HURD_]: Conditionalize contents on this, making these no-ops #ifdef _HURD_. * linux-src/net/core/dev.c [_HURD_] (dev_ioctl): Don't define the function, instead #define it to 0. * linux-src/net/ipv4/af_inet.c [_HURD_] (inet_ioctl): Likewise. * linux-src/net/ipv4/arp.c [_HURD_] (arp_ioctl): Likewise. * linux-src/net/ipv4/udp.c [_HURD_] (udp_ioctl): Likewise. * linux-src/net/ipv4/tcp.c [_HURD_] (tcp_ioctl): Likewise. [_HURD_] (tcp_tiocinq): New function, TIOCINQ code from tcp_ioctl. * linux-src/net/ipv4/devinet.c [_HURD_] (devinet_ioctl): Don't define the function, instead #define it to 0. [_HURD_] (configure_device): New function, cobbled from SIOCSIFADDR and SIOCSIFNETMASK code from devinet_ioctl. * glue-include/asm, glue-include/linux: New directories. These contain glue kludge headers that replace all of the Linux <asm/*.h> headers except checksum.h, and several of the Linux <linux/*.h> headers (the remainder come from linux-src/include/linux and are mostly unmodified). * glue-include/asm/atomic.h: New file, glue replacement header. * glue-include/asm/bitops.h: New file, glue replacement header. * glue-include/asm/byteorder.h: New file, glue replacement header. * glue-include/asm/checksum.h: New file, glue replacement header. * glue-include/asm/errno.h: New file, glue replacement header. * glue-include/asm/hardirq.h: New file, glue replacement header. * glue-include/asm/init.h: New file, glue replacement header. * glue-include/asm/segment.h: New file, glue replacement header. * glue-include/asm/spinlock.h: New file, glue replacement header. * glue-include/asm/system.h: New file, glue replacement header. * glue-include/asm/types.h: New file, glue replacement header. * glue-include/asm/uaccess.h: New file, glue replacement header. * glue-include/linux/autoconf.h: New file, glue replacement header. * glue-include/linux/binfmts.h: New file, glue replacement header. * glue-include/linux/config.h: New file, glue replacement header. * glue-include/linux/errno.h: New file, glue replacement header. * glue-include/linux/fcntl.h: New file, glue replacement header. * glue-include/linux/fs.h: New file, glue replacement header. * glue-include/linux/in.h: New file, glue replacement header. * glue-include/linux/in6.h: New file, glue replacement header. * glue-include/linux/interrupt.h: New file, glue replacement header. * glue-include/linux/ioctl.h: New file, glue replacement header. * glue-include/linux/ipv6.h: New file, glue replacement header. * glue-include/linux/kernel.h: New file, glue replacement header. * glue-include/linux/limits.h: New file, glue replacement header. * glue-include/linux/major.h: New file, glue replacement header. * glue-include/linux/malloc.h: New file, glue replacement header. * glue-include/linux/mm.h: New file, glue replacement header. * glue-include/linux/param.h: New file, glue replacement header. * glue-include/linux/personality.h: New file, glue replacement header. * glue-include/linux/poll.h: New file, glue replacement header. * glue-include/linux/proc_fs.h: New file, glue replacement header. * glue-include/linux/sched.h: New file, glue replacement header. * glue-include/linux/slab.h: New file, glue replacement header. * glue-include/linux/socket.h: New file, glue replacement header. * glue-include/linux/sockios.h: New file, glue replacement header. * glue-include/linux/stat.h: New file, glue replacement header. * glue-include/linux/string.h: New file, glue replacement header. * glue-include/linux/termios.h: New file, glue replacement header. * glue-include/linux/time.h: New file, glue replacement header. * glue-include/linux/timer.h: New file, glue replacement header. * glue-include/linux/timex.h: New file, glue replacement header. * glue-include/linux/types.h: New file, glue replacement header. * glue-include/linux/un.h: New file, glue replacement header. * glue-include/linux/version.h: New file, glue replacement header. * glue-include/linux/wait.h: New file, glue replacement header. * kmem_cache.c: New file. Glue code replaces Linux kmem_cache_t et al. * stubs.c: New file. No-op functions and stub variables for a few things the Linux networking code needs to link. * Makefile (core-srcs, arch-lib-srcs, ethernet-srcs, ipv4-srcs): New variables, listing sources used from linux-src subdirectories. (LINUXSRCS): Define using those. (SRCS): Remove devices.c; add kmem_cache.c, stubs.c. (UNUSEDSRC): Variable removed. (vpath %.c): Remove vpath for $(srcdir)/linux-inet directory. Add vpaths for $(srcdir)/linux-src subdirectories. (CPPFLAGS): Add -D_HURD_SYSTYPE defining it to $(asm_syntax) as a double-quoted string. Add -I's for glue-include and linux-src/include. * pfinet.h: Include <sys/socket.h>, and not <linux/netdevice.h>. (master_device): Remove decl. (global_lock, packet_queue_lock): Remove common defns. (global_lock, net_bh_lock): Declare them as externs. (struct sockaddr): Remove len member, make address member just a struct sockaddr rather than a 0-length array. (setup_loopback_device, become_task_protid, become_task): Remove decls. (ethernet_initialize): Declare it. (input_work_thread): Remove decl. (net_bh_thread): Declare it. (tcp_readable): Remove decl. (tcp_tiocinq): Declare it. * config.h: Rewritten based on Linux 2.2.12 set of CONFIG_* options. (CONFIG_NET, CONFIG_INET, CONFIG_SKB_LARGE): These are the only Linux config options we set. (CONFIG_IP_NOSIOCRT): New macro (not a proper config option, but used conveniently in the code). * ethernet.c (ethernet_set_multi): Take only one parameter. Remove assert, since we always get passed IGMP_ALL_HOSTS. (ethernet_thread): Make static. (ethernet_demuxer): Use __mutex_lock in place of mutex_lock, so as to get cthreads instead of linux/spinlock.h glue macros. Lock net_bh_lock instead of global_lock. Set SKB->protocol with eth_type_trans before calling netif_rx. (ethernet_initialize): New function, one-time initialization broken out of ethernet_open. (ethernet_open): Ports setup moved to ethernet_initialize. Don't use `errno' to avoid glue conflicts. Use get_privileged_ports here to get the master device port, and deallocate it after calling device_open. (ethernet_xmit): Use assert_perror. Only one arg to dev_kfree_skb now. (setup_ethernet_device): Change initializations for structure changes. Call dev_init_buffers and register_netdevice on the device. * timer-emul.c (all functions): Use __mutex_lock instead of mutex_lock. Adjust for renaming of `prevp' member to `prev' in struct timer_list. (mod_timer): New function. * socket.c (proto_ops): Variable removed. (net_families): New variable replaces it. (sock_register): Rewritten for new calling convention, set net_families rather than proto_ops. (make_sock_user, clean_socketport, sock_alloc, sock_release): Functions moved here from misc.c. * sched.c (packet_queue_lock): Variable removed. (net_bh_lock, net_bh_wakeup): New variables. (current): Variable removed (now a macro in the glue headers). (interruptible_sleep_on, wake_up_interruptible): Functions removed. They are replaced by inlines in the glue headers. (become_task, become_task_protid): Functions removed; they are replaced by macros in glue-include/linux/sched.h. (net_bh_worker): New function. * loopback.c: Completely rewritten, mostly copied from linux-2.2.12's drivers/net/loopback.c source file. * io-ops.c (all functions): Use __mutex_lock in place of mutex_lock. (S_io_write): Call ops->sendmsg instead of ops->write, which no longer exists. If O_NONBLOCK is set, set MSG_DONTWAIT in msg_flags. (S_io_read): Call ops->recvmsg instead of ops->read, which no longer exists If O_NONBLOCK is set, pass MSG_DONTWAIT. (S_io_readable): Use USER->sock->data in place of USER->sock->sk. For SOCK_STREAM and SOCK_SEQPACKET types, call tcp_tiocinq. (S_io_set_all_openmodes, S_io_get_openmodes, S_io_set_some_openmodes, S_io_clear_some_openmodes): Member USER->sock->userflags is now renamed USER->sock->flags. (S_io_select): Completely rewritten using ops->poll. (select_wait): Function removed. (S_io_stat): Set st_mode to reflect S_IFSOCK. * socket-ops.c (all functions): Use __mutex_lock instead of mutex_lock. (S_socket_create): Don't set SOCK->ops or call SOCK->ops->create. Instead, call net_families[PF_INET]->create. (S_socket_listen): Remove extra checks; just call ops->listen. (S_socket_accept): Remove extra checks before ops->accept call. Avoid use of goto. (S_socket_connect): Remove extra checks; just call ops->connect. (S_socket_bind): Adjust for struct sock_addr changes. (S_socket_create_address): Likewise. (S_socket_whatis_address): Likewise. (S_socket_connect2): Don't diddle data structures after ops->socketpair call. (S_socket_getopt): Use sock_getsockopt if LEVEL is SOL_SOCKET. Accept any data size, not just sizeof (int). (S_socket_setopt): Use sock_setsockopt if LEVEL is SOL_SOCKET. (S_socket_send): Always use ops->sendmsg instead of ops->send or ops->sendto, which no longer exist. If O_NONBLOCK is set, set MSG_DONTWAIT in msg_flags. (S_socket_recv): Always use ops->recvmsg instead of ops->recv, which no longer exists. If O_NONBLOCK is set, set MSG_DONTWAIT in flags. Check for error from S_socket_create_address. * main.c (find_device): Don't try to set ether_dev.pa_mask (it's gone). (main): Don't call init_devices. Call ethernet_initialize. Start net_bh_worker instead of input_work_thread. Don't call setup_loopback_device. Instead, take global_lock, do prepare_current, and then call sk_init, skb_init, inet_proto_init, and net_dev_init. Keep global_lock held while calling argp_parse. Call arrange_shutdown_notification only after all that. Fix error call for "contacting parent" to pass ERR instead of errno. * options.c (ADDR): #undef before defining macro. (parse_opt): #if 0 out EDESTADDRREQ check (I don't understand it). To apply settings, call configure_devices. (ADD_ADDR_OPT): #if 0 --address and --netmask options. Needs fixed. * misc.c (make_sock_user, clean_socketport, sock_alloc, sock_release): Functions moved to socket.c. (sock_release_peer): Function removed. (make_sockaddr_port): Use struct sockaddr_storage to size buffer. Fix size calculation for new struct sock_addr layout. Initialize sa_family and sa_len of new struct sock_addr. Remove the old Linux (2.0.??) network stack and the glue code for it. * linux-inet, asm, linux: Directories and all files removed. Some of the new files in glue-include came from the old glue headers in the asm and linux directories, but most were substantially modified. * devices.c: File removed. The equivalent glue is now elsewhere.
Diffstat (limited to 'pfinet/linux-inet/route.c')
-rw-r--r--pfinet/linux-inet/route.c684
1 files changed, 0 insertions, 684 deletions
diff --git a/pfinet/linux-inet/route.c b/pfinet/linux-inet/route.c
deleted file mode 100644
index ce06dcfe..00000000
--- a/pfinet/linux-inet/route.c
+++ /dev/null
@@ -1,684 +0,0 @@
-/*
- * INET An implementation of the TCP/IP protocol suite for the LINUX
- * operating system. INET is implemented using the BSD Socket
- * interface as the means of communication with the user level.
- *
- * ROUTE - implementation of the IP router.
- *
- * Version: @(#)route.c 1.0.14 05/31/93
- *
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
- * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- * Alan Cox, <gw4pts@gw4pts.ampr.org>
- * Linus Torvalds, <Linus.Torvalds@helsinki.fi>
- *
- * Fixes:
- * Alan Cox : Verify area fixes.
- * Alan Cox : cli() protects routing changes
- * Rui Oliveira : ICMP routing table updates
- * (rco@di.uminho.pt) Routing table insertion and update
- * Linus Torvalds : Rewrote bits to be sensible
- * Alan Cox : Added BSD route gw semantics
- * Alan Cox : Super /proc >4K
- * Alan Cox : MTU in route table
- * Alan Cox : MSS actually. Also added the window
- * clamper.
- * Sam Lantinga : Fixed route matching in rt_del()
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <asm/segment.h>
-#include <asm/system.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/errno.h>
-#include <linux/in.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include "ip.h"
-#include "protocol.h"
-#include "route.h"
-#include "tcp.h"
-#include <linux/skbuff.h>
-#include "sock.h"
-#include "icmp.h"
-
-/*
- * The routing table list
- */
-
-static struct rtable *rt_base = NULL;
-
-/*
- * Pointer to the loopback route
- */
-
-static struct rtable *rt_loopback = NULL;
-
-/*
- * Remove a routing table entry.
- */
-
-static void rt_del(unsigned long dst, char *devname)
-{
- struct rtable *r, **rp;
- unsigned long flags;
-
- rp = &rt_base;
-
- /*
- * This must be done with interrupts off because we could take
- * an ICMP_REDIRECT.
- */
-
- save_flags(flags);
- cli();
- while((r = *rp) != NULL)
- {
- /* Make sure both the destination and the device match */
- if ( r->rt_dst != dst ||
- (devname != NULL && strcmp((r->rt_dev)->name,devname) != 0) )
- {
- rp = &r->rt_next;
- continue;
- }
- *rp = r->rt_next;
-
- /*
- * If we delete the loopback route update its pointer.
- */
-
- if (rt_loopback == r)
- rt_loopback = NULL;
- kfree_s(r, sizeof(struct rtable));
- }
- restore_flags(flags);
-}
-
-
-/*
- * Remove all routing table entries for a device. This is called when
- * a device is downed.
- */
-
-void ip_rt_flush(struct device *dev)
-{
- struct rtable *r;
- struct rtable **rp;
- unsigned long flags;
-
- rp = &rt_base;
- save_flags(flags);
- cli();
- while ((r = *rp) != NULL) {
- if (r->rt_dev != dev) {
- rp = &r->rt_next;
- continue;
- }
- *rp = r->rt_next;
- if (rt_loopback == r)
- rt_loopback = NULL;
- kfree_s(r, sizeof(struct rtable));
- }
- restore_flags(flags);
-}
-
-/*
- * Used by 'rt_add()' when we can't get the netmask any other way..
- *
- * If the lower byte or two are zero, we guess the mask based on the
- * number of zero 8-bit net numbers, otherwise we use the "default"
- * masks judging by the destination address and our device netmask.
- */
-
-static inline unsigned long default_mask(unsigned long dst)
-{
- dst = ntohl(dst);
- if (IN_CLASSA(dst))
- return htonl(IN_CLASSA_NET);
- if (IN_CLASSB(dst))
- return htonl(IN_CLASSB_NET);
- return htonl(IN_CLASSC_NET);
-}
-
-
-/*
- * If no mask is specified then generate a default entry.
- */
-
-static unsigned long guess_mask(unsigned long dst, struct device * dev)
-{
- unsigned long mask;
-
- if (!dst)
- return 0;
- mask = default_mask(dst);
- if ((dst ^ dev->pa_addr) & mask)
- return mask;
- return dev->pa_mask;
-}
-
-
-/*
- * Find the route entry through which our gateway will be reached
- */
-
-static inline struct device * get_gw_dev(unsigned long gw)
-{
- struct rtable * rt;
-
- for (rt = rt_base ; ; rt = rt->rt_next)
- {
- if (!rt)
- return NULL;
- if ((gw ^ rt->rt_dst) & rt->rt_mask)
- continue;
- /*
- * Gateways behind gateways are a no-no
- */
-
- if (rt->rt_flags & RTF_GATEWAY)
- return NULL;
- return rt->rt_dev;
- }
-}
-
-/*
- * Rewrote rt_add(), as the old one was weird - Linus
- *
- * This routine is used to update the IP routing table, either
- * from the kernel (ICMP_REDIRECT) or via an ioctl call issued
- * by the superuser.
- */
-
-void ip_rt_add(short flags, unsigned long dst, unsigned long mask,
- unsigned long gw, struct device *dev, unsigned short mtu, unsigned long window)
-{
- struct rtable *r, *rt;
- struct rtable **rp;
- unsigned long cpuflags;
-
- /*
- * A host is a unique machine and has no network bits.
- */
-
- if (flags & RTF_HOST)
- {
- mask = 0xffffffff;
- }
-
- /*
- * Calculate the network mask
- */
-
- else if (!mask)
- {
- if (!((dst ^ dev->pa_addr) & dev->pa_mask))
- {
- mask = dev->pa_mask;
- flags &= ~RTF_GATEWAY;
- if (flags & RTF_DYNAMIC)
- {
- /*printk("Dynamic route to my own net rejected\n");*/
- return;
- }
- }
- else
- mask = guess_mask(dst, dev);
- dst &= mask;
- }
-
- /*
- * A gateway must be reachable and not a local address
- */
-
- if (gw == dev->pa_addr)
- flags &= ~RTF_GATEWAY;
-
- if (flags & RTF_GATEWAY)
- {
- /*
- * Don't try to add a gateway we can't reach..
- */
-
- if (dev != get_gw_dev(gw))
- return;
-
- flags |= RTF_GATEWAY;
- }
- else
- gw = 0;
-
- /*
- * Allocate an entry and fill it in.
- */
-
- rt = (struct rtable *) kmalloc(sizeof(struct rtable), GFP_ATOMIC);
- if (rt == NULL)
- {
- return;
- }
- memset(rt, 0, sizeof(struct rtable));
- rt->rt_flags = flags | RTF_UP;
- rt->rt_dst = dst;
- rt->rt_dev = dev;
- rt->rt_gateway = gw;
- rt->rt_mask = mask;
- rt->rt_mss = dev->mtu - HEADER_SIZE;
- rt->rt_window = 0; /* Default is no clamping */
-
- /* Are the MSS/Window valid ? */
-
- if(rt->rt_flags & RTF_MSS)
- rt->rt_mss = mtu;
-
- if(rt->rt_flags & RTF_WINDOW)
- rt->rt_window = window;
-
- /*
- * What we have to do is loop though this until we have
- * found the first address which has a higher generality than
- * the one in rt. Then we can put rt in right before it.
- * The interrupts must be off for this process.
- */
-
- save_flags(cpuflags);
- cli();
-
- /*
- * Remove old route if we are getting a duplicate.
- */
-
- rp = &rt_base;
- while ((r = *rp) != NULL)
- {
- if (r->rt_dst != dst ||
- r->rt_mask != mask)
- {
- rp = &r->rt_next;
- continue;
- }
- *rp = r->rt_next;
- if (rt_loopback == r)
- rt_loopback = NULL;
- kfree_s(r, sizeof(struct rtable));
- }
-
- /*
- * Add the new route
- */
-
- rp = &rt_base;
- while ((r = *rp) != NULL) {
- if ((r->rt_mask & mask) != mask)
- break;
- rp = &r->rt_next;
- }
- rt->rt_next = r;
- *rp = rt;
-
- /*
- * Update the loopback route
- */
-
- if ((rt->rt_dev->flags & IFF_LOOPBACK) && !rt_loopback)
- rt_loopback = rt;
-
- /*
- * Restore the interrupts and return
- */
-
- restore_flags(cpuflags);
- return;
-}
-
-/*
- * Remove a routing table entry (exported version).
- */
-void ip_rt_del (unsigned long dst, struct device *dev)
-{
- /* Should probably just copy contents of rt_del and replace name
- comparison with device comparsion. */
- rt_del (dst, dev->name);
-}
-
-
-/*
- * Check if a mask is acceptable.
- */
-
-static inline int bad_mask(unsigned long mask, unsigned long addr)
-{
- if (addr & (mask = ~mask))
- return 1;
- mask = ntohl(mask);
- if (mask & (mask+1))
- return 1;
- return 0;
-}
-
-/*
- * Process a route add request from the user
- */
-
-static int rt_new(struct rtentry *r)
-{
- int err;
- char * devname;
- struct device * dev = NULL;
- unsigned long flags, daddr, mask, gw;
-
- /*
- * If a device is specified find it.
- */
-
- if ((devname = r->rt_dev) != NULL)
- {
- err = getname(devname, &devname);
- if (err)
- return err;
- dev = dev_get(devname);
- putname(devname);
- if (!dev)
- return -EINVAL;
- }
-
- /*
- * If the device isn't INET, don't allow it
- */
-
- if (r->rt_dst.sa_family != AF_INET)
- return -EAFNOSUPPORT;
-
- /*
- * Make local copies of the important bits
- */
-
- flags = r->rt_flags;
- daddr = ((struct sockaddr_in *) &r->rt_dst)->sin_addr.s_addr;
- mask = ((struct sockaddr_in *) &r->rt_genmask)->sin_addr.s_addr;
- gw = ((struct sockaddr_in *) &r->rt_gateway)->sin_addr.s_addr;
-
-
- /*
- * BSD emulation: Permits route add someroute gw one-of-my-addresses
- * to indicate which iface. Not as clean as the nice Linux dev technique
- * but people keep using it...
- */
-
- if (!dev && (flags & RTF_GATEWAY))
- {
- struct device *dev2;
- for (dev2 = dev_base ; dev2 != NULL ; dev2 = dev2->next)
- {
- if ((dev2->flags & IFF_UP) && dev2->pa_addr == gw)
- {
- flags &= ~RTF_GATEWAY;
- dev = dev2;
- break;
- }
- }
- }
-
- /*
- * Ignore faulty masks
- */
-
- if (bad_mask(mask, daddr))
- mask = 0;
-
- /*
- * Set the mask to nothing for host routes.
- */
-
- if (flags & RTF_HOST)
- mask = 0xffffffff;
- else if (mask && r->rt_genmask.sa_family != AF_INET)
- return -EAFNOSUPPORT;
-
- /*
- * You can only gateway IP via IP..
- */
-
- if (flags & RTF_GATEWAY)
- {
- if (r->rt_gateway.sa_family != AF_INET)
- return -EAFNOSUPPORT;
- if (!dev)
- dev = get_gw_dev(gw);
- }
- else if (!dev)
- dev = ip_dev_check(daddr);
-
- /*
- * Unknown device.
- */
-
- if (dev == NULL)
- return -ENETUNREACH;
-
- /*
- * Add the route
- */
-
- ip_rt_add(flags, daddr, mask, gw, dev, r->rt_mss, r->rt_window);
- return 0;
-}
-
-
-/*
- * Remove a route, as requested by the user.
- */
-
-static int rt_kill(struct rtentry *r)
-{
- struct sockaddr_in *trg;
- char *devname;
- int err;
-
- trg = (struct sockaddr_in *) &r->rt_dst;
- if ((devname = r->rt_dev) != NULL)
- {
- err = getname(devname, &devname);
- if (err)
- return err;
- }
- rt_del(trg->sin_addr.s_addr, devname);
- if ( devname != NULL )
- putname(devname);
- return 0;
-}
-
-
-/*
- * Called from the PROCfs module. This outputs /proc/net/route.
- */
-
-int rt_get_info(char *buffer, char **start, off_t offset, int length)
-{
- struct rtable *r;
- int len=0;
- off_t pos=0;
- off_t begin=0;
- int size;
-
- len += sprintf(buffer,
- "Iface\tDestination\tGateway \tFlags\tRefCnt\tUse\tMetric\tMask\t\tMTU\tWindow\n");
- pos=len;
-
- /*
- * This isn't quite right -- r->rt_dst is a struct!
- */
-
- for (r = rt_base; r != NULL; r = r->rt_next)
- {
- size = sprintf(buffer+len, "%s\t%08lX\t%08lX\t%02X\t%d\t%lu\t%d\t%08lX\t%d\t%lu\n",
- r->rt_dev->name, r->rt_dst, r->rt_gateway,
- r->rt_flags, r->rt_refcnt, r->rt_use, r->rt_metric,
- r->rt_mask, (int)r->rt_mss, r->rt_window);
- len+=size;
- pos+=size;
- if(pos<offset)
- {
- len=0;
- begin=pos;
- }
- if(pos>offset+length)
- break;
- }
-
- *start=buffer+(offset-begin);
- len-=(offset-begin);
- if(len>length)
- len=length;
- return len;
-}
-
-/*
- * This is hackish, but results in better code. Use "-S" to see why.
- */
-
-#define early_out ({ goto no_route; 1; })
-
-/*
- * Route a packet. This needs to be fairly quick. Florian & Co.
- * suggested a unified ARP and IP routing cache. Done right its
- * probably a brilliant idea. I'd actually suggest a unified
- * ARP/IP routing/Socket pointer cache. Volunteers welcome
- */
-
-struct rtable * ip_rt_route(unsigned long daddr, struct options *opt, unsigned long *src_addr)
-{
- struct rtable *rt;
-
- for (rt = rt_base; rt != NULL || early_out ; rt = rt->rt_next)
- {
- if (!((rt->rt_dst ^ daddr) & rt->rt_mask))
- break;
- /*
- * broadcast addresses can be special cases..
- */
- if (rt->rt_flags & RTF_GATEWAY)
- continue;
- if ((rt->rt_dev->flags & IFF_BROADCAST) &&
- (rt->rt_dev->pa_brdaddr == daddr))
- break;
- }
-
- if(src_addr!=NULL)
- *src_addr= rt->rt_dev->pa_addr;
-
- if (daddr == rt->rt_dev->pa_addr) {
- if ((rt = rt_loopback) == NULL)
- goto no_route;
- }
- rt->rt_use++;
- return rt;
-no_route:
- return NULL;
-}
-
-struct rtable * ip_rt_local(unsigned long daddr, struct options *opt, unsigned long *src_addr)
-{
- struct rtable *rt;
-
- for (rt = rt_base; rt != NULL || early_out ; rt = rt->rt_next)
- {
- /*
- * No routed addressing.
- */
- if (rt->rt_flags&RTF_GATEWAY)
- continue;
-
- if (!((rt->rt_dst ^ daddr) & rt->rt_mask))
- break;
- /*
- * broadcast addresses can be special cases..
- */
-
- if ((rt->rt_dev->flags & IFF_BROADCAST) &&
- rt->rt_dev->pa_brdaddr == daddr)
- break;
- }
-
- if(src_addr!=NULL)
- *src_addr= rt->rt_dev->pa_addr;
-
- if (daddr == rt->rt_dev->pa_addr) {
- if ((rt = rt_loopback) == NULL)
- goto no_route;
- }
- rt->rt_use++;
- return rt;
-no_route:
- return NULL;
-}
-
-/*
- * Backwards compatibility
- */
-
-static int ip_get_old_rtent(struct old_rtentry * src, struct rtentry * rt)
-{
- int err;
- struct old_rtentry tmp;
-
- err=verify_area(VERIFY_READ, src, sizeof(*src));
- if (err)
- return err;
- memcpy_fromfs(&tmp, src, sizeof(*src));
- memset(rt, 0, sizeof(*rt));
- rt->rt_dst = tmp.rt_dst;
- rt->rt_gateway = tmp.rt_gateway;
- rt->rt_genmask.sa_family = AF_INET;
- ((struct sockaddr_in *) &rt->rt_genmask)->sin_addr.s_addr = tmp.rt_genmask;
- rt->rt_flags = tmp.rt_flags;
- rt->rt_dev = tmp.rt_dev;
- printk("Warning: obsolete routing request made.\n");
- return 0;
-}
-
-#ifndef _HURD_
-/*
- * Handle IP routing ioctl calls. These are used to manipulate the routing tables
- */
-
-int ip_rt_ioctl(unsigned int cmd, void *arg)
-{
- int err;
- struct rtentry rt;
-
- switch(cmd)
- {
- case SIOCADDRTOLD: /* Old style add route */
- case SIOCDELRTOLD: /* Old style delete route */
- if (!suser())
- return -EPERM;
- err = ip_get_old_rtent((struct old_rtentry *) arg, &rt);
- if (err)
- return err;
- return (cmd == SIOCDELRTOLD) ? rt_kill(&rt) : rt_new(&rt);
-
- case SIOCADDRT: /* Add a route */
- case SIOCDELRT: /* Delete a route */
- if (!suser())
- return -EPERM;
- err=verify_area(VERIFY_READ, arg, sizeof(struct rtentry));
- if (err)
- return err;
- memcpy_fromfs(&rt, arg, sizeof(struct rtentry));
- return (cmd == SIOCDELRT) ? rt_kill(&rt) : rt_new(&rt);
- }
-
- return -EINVAL;
-}
-#endif