summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorAdrian Bunk <bunk@stusta.de>2006-11-14 03:02:22 +0300
committerDavid S. Miller <davem@sunset.davemloft.net>2006-12-03 08:22:23 +0300
commit90833aa4f496d69ca374af6acef7d1614c8693ff (patch)
treedbac818cc40ab12d493c45778febf6b7a768f757 /net
parentd7f7365f5776723da6df73540d855069c2daaa5c (diff)
downloadlinux-90833aa4f496d69ca374af6acef7d1614c8693ff.tar.xz
[NET]: The scheduled removal of the frame diverter.
This patch contains the scheduled removal of the frame diverter. Signed-off-by: Adrian Bunk <bunk@stusta.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/Kconfig27
-rw-r--r--net/core/Makefile1
-rw-r--r--net/core/dev.c20
-rw-r--r--net/core/dv.c546
-rw-r--r--net/core/sysctl_net_core.c14
-rw-r--r--net/socket.c6
6 files changed, 4 insertions, 610 deletions
diff --git a/net/Kconfig b/net/Kconfig
index 67e39ad8b8b6..867f95032513 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -175,33 +175,6 @@ source "net/ipx/Kconfig"
source "drivers/net/appletalk/Kconfig"
source "net/x25/Kconfig"
source "net/lapb/Kconfig"
-
-config NET_DIVERT
- bool "Frame Diverter (EXPERIMENTAL)"
- depends on EXPERIMENTAL && BROKEN
- ---help---
- The Frame Diverter allows you to divert packets from the
- network, that are not aimed at the interface receiving it (in
- promisc. mode). Typically, a Linux box setup as an Ethernet bridge
- with the Frames Diverter on, can do some *really* transparent www
- caching using a Squid proxy for example.
-
- This is very useful when you don't want to change your router's
- config (or if you simply don't have access to it).
-
- The other possible usages of diverting Ethernet Frames are
- numberous:
- - reroute smtp traffic to another interface
- - traffic-shape certain network streams
- - transparently proxy smtp connections
- - etc...
-
- For more informations, please refer to:
- <http://diverter.sourceforge.net/>
- <http://perso.wanadoo.fr/magpie/EtherDivert.html>
-
- If unsure, say N.
-
source "net/econet/Kconfig"
source "net/wanrouter/Kconfig"
source "net/sched/Kconfig"
diff --git a/net/core/Makefile b/net/core/Makefile
index 119568077dab..73272d506e93 100644
--- a/net/core/Makefile
+++ b/net/core/Makefile
@@ -12,7 +12,6 @@ obj-y += dev.o ethtool.o dev_mcast.o dst.o netevent.o \
obj-$(CONFIG_XFRM) += flow.o
obj-$(CONFIG_SYSFS) += net-sysfs.o
-obj-$(CONFIG_NET_DIVERT) += dv.o
obj-$(CONFIG_NET_PKTGEN) += pktgen.o
obj-$(CONFIG_WIRELESS_EXT) += wireless.o
obj-$(CONFIG_NETPOLL) += netpoll.o
diff --git a/net/core/dev.c b/net/core/dev.c
index 411c2428d268..5bf13b132dd7 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -98,7 +98,6 @@
#include <linux/seq_file.h>
#include <linux/stat.h>
#include <linux/if_bridge.h>
-#include <linux/divert.h>
#include <net/dst.h>
#include <net/pkt_sched.h>
#include <net/checksum.h>
@@ -1827,8 +1826,6 @@ int netif_receive_skb(struct sk_buff *skb)
ncls:
#endif
- handle_diverter(skb);
-
if (handle_bridge(&skb, &pt_prev, &ret, orig_dev))
goto out;
@@ -2898,10 +2895,6 @@ int register_netdevice(struct net_device *dev)
spin_lock_init(&dev->ingress_lock);
#endif
- ret = alloc_divert_blk(dev);
- if (ret)
- goto out;
-
dev->iflink = -1;
/* Init, if this function is available */
@@ -2910,13 +2903,13 @@ int register_netdevice(struct net_device *dev)
if (ret) {
if (ret > 0)
ret = -EIO;
- goto out_err;
+ goto out;
}
}
if (!dev_valid_name(dev->name)) {
ret = -EINVAL;
- goto out_err;
+ goto out;
}
dev->ifindex = dev_new_index();
@@ -2930,7 +2923,7 @@ int register_netdevice(struct net_device *dev)
= hlist_entry(p, struct net_device, name_hlist);
if (!strncmp(d->name, dev->name, IFNAMSIZ)) {
ret = -EEXIST;
- goto out_err;
+ goto out;
}
}
@@ -2974,7 +2967,7 @@ int register_netdevice(struct net_device *dev)
ret = netdev_register_sysfs(dev);
if (ret)
- goto out_err;
+ goto out;
dev->reg_state = NETREG_REGISTERED;
/*
@@ -3001,9 +2994,6 @@ int register_netdevice(struct net_device *dev)
out:
return ret;
-out_err:
- free_divert_blk(dev);
- goto out;
}
/**
@@ -3320,8 +3310,6 @@ int unregister_netdevice(struct net_device *dev)
/* Notifier chain MUST detach us from master device. */
BUG_TRAP(!dev->master);
- free_divert_blk(dev);
-
/* Finish processing unregister after unlock */
net_set_todo(dev);
diff --git a/net/core/dv.c b/net/core/dv.c
deleted file mode 100644
index 29ee77f15932..000000000000
--- a/net/core/dv.c
+++ /dev/null
@@ -1,546 +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.
- *
- * Generic frame diversion
- *
- * Authors:
- * Benoit LOCHER: initial integration within the kernel with support for ethernet
- * Dave Miller: improvement on the code (correctness, performance and source files)
- *
- */
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/inet.h>
-#include <linux/ip.h>
-#include <linux/udp.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/capability.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <net/dst.h>
-#include <net/arp.h>
-#include <net/sock.h>
-#include <net/ipv6.h>
-#include <net/ip.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/checksum.h>
-#include <linux/divert.h>
-#include <linux/sockios.h>
-
-const char sysctl_divert_version[32]="0.46"; /* Current version */
-
-static int __init dv_init(void)
-{
- return 0;
-}
-module_init(dv_init);
-
-/*
- * Allocate a divert_blk for a device. This must be an ethernet nic.
- */
-int alloc_divert_blk(struct net_device *dev)
-{
- int alloc_size = (sizeof(struct divert_blk) + 3) & ~3;
-
- dev->divert = NULL;
- if (dev->type == ARPHRD_ETHER) {
- dev->divert = kzalloc(alloc_size, GFP_KERNEL);
- if (dev->divert == NULL) {
- printk(KERN_INFO "divert: unable to allocate divert_blk for %s\n",
- dev->name);
- return -ENOMEM;
- }
- dev_hold(dev);
- }
-
- return 0;
-}
-
-/*
- * Free a divert_blk allocated by the above function, if it was
- * allocated on that device.
- */
-void free_divert_blk(struct net_device *dev)
-{
- if (dev->divert) {
- kfree(dev->divert);
- dev->divert=NULL;
- dev_put(dev);
- }
-}
-
-/*
- * Adds a tcp/udp (source or dest) port to an array
- */
-static int add_port(u16 ports[], u16 port)
-{
- int i;
-
- if (port == 0)
- return -EINVAL;
-
- /* Storing directly in network format for performance,
- * thanks Dave :)
- */
- port = htons(port);
-
- for (i = 0; i < MAX_DIVERT_PORTS; i++) {
- if (ports[i] == port)
- return -EALREADY;
- }
-
- for (i = 0; i < MAX_DIVERT_PORTS; i++) {
- if (ports[i] == 0) {
- ports[i] = port;
- return 0;
- }
- }
-
- return -ENOBUFS;
-}
-
-/*
- * Removes a port from an array tcp/udp (source or dest)
- */
-static int remove_port(u16 ports[], u16 port)
-{
- int i;
-
- if (port == 0)
- return -EINVAL;
-
- /* Storing directly in network format for performance,
- * thanks Dave !
- */
- port = htons(port);
-
- for (i = 0; i < MAX_DIVERT_PORTS; i++) {
- if (ports[i] == port) {
- ports[i] = 0;
- return 0;
- }
- }
-
- return -EINVAL;
-}
-
-/* Some basic sanity checks on the arguments passed to divert_ioctl() */
-static int check_args(struct divert_cf *div_cf, struct net_device **dev)
-{
- char devname[32];
- int ret;
-
- if (dev == NULL)
- return -EFAULT;
-
- /* GETVERSION: all other args are unused */
- if (div_cf->cmd == DIVCMD_GETVERSION)
- return 0;
-
- /* Network device index should reasonably be between 0 and 1000 :) */
- if (div_cf->dev_index < 0 || div_cf->dev_index > 1000)
- return -EINVAL;
-
- /* Let's try to find the ifname */
- sprintf(devname, "eth%d", div_cf->dev_index);
- *dev = dev_get_by_name(devname);
-
- /* dev should NOT be null */
- if (*dev == NULL)
- return -EINVAL;
-
- ret = 0;
-
- /* user issuing the ioctl must be a super one :) */
- if (!capable(CAP_SYS_ADMIN)) {
- ret = -EPERM;
- goto out;
- }
-
- /* Device must have a divert_blk member NOT null */
- if ((*dev)->divert == NULL)
- ret = -EINVAL;
-out:
- dev_put(*dev);
- return ret;
-}
-
-/*
- * control function of the diverter
- */
-#if 0
-#define DVDBG(a) \
- printk(KERN_DEBUG "divert_ioctl() line %d %s\n", __LINE__, (a))
-#else
-#define DVDBG(a)
-#endif
-
-int divert_ioctl(unsigned int cmd, struct divert_cf __user *arg)
-{
- struct divert_cf div_cf;
- struct divert_blk *div_blk;
- struct net_device *dev;
- int ret;
-
- switch (cmd) {
- case SIOCGIFDIVERT:
- DVDBG("SIOCGIFDIVERT, copy_from_user");
- if (copy_from_user(&div_cf, arg, sizeof(struct divert_cf)))
- return -EFAULT;
- DVDBG("before check_args");
- ret = check_args(&div_cf, &dev);
- if (ret)
- return ret;
- DVDBG("after checkargs");
- div_blk = dev->divert;
-
- DVDBG("befre switch()");
- switch (div_cf.cmd) {
- case DIVCMD_GETSTATUS:
- /* Now, just give the user the raw divert block
- * for him to play with :)
- */
- if (copy_to_user(div_cf.arg1.ptr, dev->divert,
- sizeof(struct divert_blk)))
- return -EFAULT;
- break;
-
- case DIVCMD_GETVERSION:
- DVDBG("GETVERSION: checking ptr");
- if (div_cf.arg1.ptr == NULL)
- return -EINVAL;
- DVDBG("GETVERSION: copying data to userland");
- if (copy_to_user(div_cf.arg1.ptr,
- sysctl_divert_version, 32))
- return -EFAULT;
- DVDBG("GETVERSION: data copied");
- break;
-
- default:
- return -EINVAL;
- }
-
- break;
-
- case SIOCSIFDIVERT:
- if (copy_from_user(&div_cf, arg, sizeof(struct divert_cf)))
- return -EFAULT;
-
- ret = check_args(&div_cf, &dev);
- if (ret)
- return ret;
-
- div_blk = dev->divert;
-
- switch(div_cf.cmd) {
- case DIVCMD_RESET:
- div_blk->divert = 0;
- div_blk->protos = DIVERT_PROTO_NONE;
- memset(div_blk->tcp_dst, 0,
- MAX_DIVERT_PORTS * sizeof(u16));
- memset(div_blk->tcp_src, 0,
- MAX_DIVERT_PORTS * sizeof(u16));
- memset(div_blk->udp_dst, 0,
- MAX_DIVERT_PORTS * sizeof(u16));
- memset(div_blk->udp_src, 0,
- MAX_DIVERT_PORTS * sizeof(u16));
- return 0;
-
- case DIVCMD_DIVERT:
- switch(div_cf.arg1.int32) {
- case DIVARG1_ENABLE:
- if (div_blk->divert)
- return -EALREADY;
- div_blk->divert = 1;
- break;
-
- case DIVARG1_DISABLE:
- if (!div_blk->divert)
- return -EALREADY;
- div_blk->divert = 0;
- break;
-
- default:
- return -EINVAL;
- }
-
- break;
-
- case DIVCMD_IP:
- switch(div_cf.arg1.int32) {
- case DIVARG1_ENABLE:
- if (div_blk->protos & DIVERT_PROTO_IP)
- return -EALREADY;
- div_blk->protos |= DIVERT_PROTO_IP;
- break;
-
- case DIVARG1_DISABLE:
- if (!(div_blk->protos & DIVERT_PROTO_IP))
- return -EALREADY;
- div_blk->protos &= ~DIVERT_PROTO_IP;
- break;
-
- default:
- return -EINVAL;
- }
-
- break;
-
- case DIVCMD_TCP:
- switch(div_cf.arg1.int32) {
- case DIVARG1_ENABLE:
- if (div_blk->protos & DIVERT_PROTO_TCP)
- return -EALREADY;
- div_blk->protos |= DIVERT_PROTO_TCP;
- break;
-
- case DIVARG1_DISABLE:
- if (!(div_blk->protos & DIVERT_PROTO_TCP))
- return -EALREADY;
- div_blk->protos &= ~DIVERT_PROTO_TCP;
- break;
-
- default:
- return -EINVAL;
- }
-
- break;
-
- case DIVCMD_TCPDST:
- switch(div_cf.arg1.int32) {
- case DIVARG1_ADD:
- return add_port(div_blk->tcp_dst,
- div_cf.arg2.uint16);
-
- case DIVARG1_REMOVE:
- return remove_port(div_blk->tcp_dst,
- div_cf.arg2.uint16);
-
- default:
- return -EINVAL;
- }
-
- break;
-
- case DIVCMD_TCPSRC:
- switch(div_cf.arg1.int32) {
- case DIVARG1_ADD:
- return add_port(div_blk->tcp_src,
- div_cf.arg2.uint16);
-
- case DIVARG1_REMOVE:
- return remove_port(div_blk->tcp_src,
- div_cf.arg2.uint16);
-
- default:
- return -EINVAL;
- }
-
- break;
-
- case DIVCMD_UDP:
- switch(div_cf.arg1.int32) {
- case DIVARG1_ENABLE:
- if (div_blk->protos & DIVERT_PROTO_UDP)
- return -EALREADY;
- div_blk->protos |= DIVERT_PROTO_UDP;
- break;
-
- case DIVARG1_DISABLE:
- if (!(div_blk->protos & DIVERT_PROTO_UDP))
- return -EALREADY;
- div_blk->protos &= ~DIVERT_PROTO_UDP;
- break;
-
- default:
- return -EINVAL;
- }
-
- break;
-
- case DIVCMD_UDPDST:
- switch(div_cf.arg1.int32) {
- case DIVARG1_ADD:
- return add_port(div_blk->udp_dst,
- div_cf.arg2.uint16);
-
- case DIVARG1_REMOVE:
- return remove_port(div_blk->udp_dst,
- div_cf.arg2.uint16);
-
- default:
- return -EINVAL;
- }
-
- break;
-
- case DIVCMD_UDPSRC:
- switch(div_cf.arg1.int32) {
- case DIVARG1_ADD:
- return add_port(div_blk->udp_src,
- div_cf.arg2.uint16);
-
- case DIVARG1_REMOVE:
- return remove_port(div_blk->udp_src,
- div_cf.arg2.uint16);
-
- default:
- return -EINVAL;
- }
-
- break;
-
- case DIVCMD_ICMP:
- switch(div_cf.arg1.int32) {
- case DIVARG1_ENABLE:
- if (div_blk->protos & DIVERT_PROTO_ICMP)
- return -EALREADY;
- div_blk->protos |= DIVERT_PROTO_ICMP;
- break;
-
- case DIVARG1_DISABLE:
- if (!(div_blk->protos & DIVERT_PROTO_ICMP))
- return -EALREADY;
- div_blk->protos &= ~DIVERT_PROTO_ICMP;
- break;
-
- default:
- return -EINVAL;
- }
-
- break;
-
- default:
- return -EINVAL;
- }
-
- break;
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-
-/*
- * Check if packet should have its dest mac address set to the box itself
- * for diversion
- */
-
-#define ETH_DIVERT_FRAME(skb) \
- memcpy(eth_hdr(skb), skb->dev->dev_addr, ETH_ALEN); \
- skb->pkt_type=PACKET_HOST
-
-void divert_frame(struct sk_buff *skb)
-{
- struct ethhdr *eth = eth_hdr(skb);
- struct iphdr *iph;
- struct tcphdr *tcph;
- struct udphdr *udph;
- struct divert_blk *divert = skb->dev->divert;
- int i, src, dst;
- unsigned char *skb_data_end = skb->data + skb->len;
-
- /* Packet is already aimed at us, return */
- if (!compare_ether_addr(eth->h_dest, skb->dev->dev_addr))
- return;
-
- /* proto is not IP, do nothing */
- if (eth->h_proto != htons(ETH_P_IP))
- return;
-
- /* Divert all IP frames ? */
- if (divert->protos & DIVERT_PROTO_IP) {
- ETH_DIVERT_FRAME(skb);
- return;
- }
-
- /* Check for possible (maliciously) malformed IP frame (thanks Dave) */
- iph = (struct iphdr *) skb->data;
- if (((iph->ihl<<2)+(unsigned char*)(iph)) >= skb_data_end) {
- printk(KERN_INFO "divert: malformed IP packet !\n");
- return;
- }
-
- switch (iph->protocol) {
- /* Divert all ICMP frames ? */
- case IPPROTO_ICMP:
- if (divert->protos & DIVERT_PROTO_ICMP) {
- ETH_DIVERT_FRAME(skb);
- return;
- }
- break;
-
- /* Divert all TCP frames ? */
- case IPPROTO_TCP:
- if (divert->protos & DIVERT_PROTO_TCP) {
- ETH_DIVERT_FRAME(skb);
- return;
- }
-
- /* Check for possible (maliciously) malformed IP
- * frame (thanx Dave)
- */
- tcph = (struct tcphdr *)
- (((unsigned char *)iph) + (iph->ihl<<2));
- if (((unsigned char *)(tcph+1)) >= skb_data_end) {
- printk(KERN_INFO "divert: malformed TCP packet !\n");
- return;
- }
-
- /* Divert some tcp dst/src ports only ?*/
- for (i = 0; i < MAX_DIVERT_PORTS; i++) {
- dst = divert->tcp_dst[i];
- src = divert->tcp_src[i];
- if ((dst && dst == tcph->dest) ||
- (src && src == tcph->source)) {
- ETH_DIVERT_FRAME(skb);
- return;
- }
- }
- break;
-
- /* Divert all UDP frames ? */
- case IPPROTO_UDP:
- if (divert->protos & DIVERT_PROTO_UDP) {
- ETH_DIVERT_FRAME(skb);
- return;
- }
-
- /* Check for possible (maliciously) malformed IP
- * packet (thanks Dave)
- */
- udph = (struct udphdr *)
- (((unsigned char *)iph) + (iph->ihl<<2));
- if (((unsigned char *)(udph+1)) >= skb_data_end) {
- printk(KERN_INFO
- "divert: malformed UDP packet !\n");
- return;
- }
-
- /* Divert some udp dst/src ports only ? */
- for (i = 0; i < MAX_DIVERT_PORTS; i++) {
- dst = divert->udp_dst[i];
- src = divert->udp_src[i];
- if ((dst && dst == udph->dest) ||
- (src && src == udph->source)) {
- ETH_DIVERT_FRAME(skb);
- return;
- }
- }
- break;
- }
-}
diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
index 02534131d88e..1e75b1585460 100644
--- a/net/core/sysctl_net_core.c
+++ b/net/core/sysctl_net_core.c
@@ -21,10 +21,6 @@ extern __u32 sysctl_rmem_max;
extern int sysctl_core_destroy_delay;
-#ifdef CONFIG_NET_DIVERT
-extern char sysctl_divert_version[];
-#endif /* CONFIG_NET_DIVERT */
-
#ifdef CONFIG_XFRM
extern u32 sysctl_xfrm_aevent_etime;
extern u32 sysctl_xfrm_aevent_rseqth;
@@ -105,16 +101,6 @@ ctl_table core_table[] = {
.mode = 0644,
.proc_handler = &proc_dointvec
},
-#ifdef CONFIG_NET_DIVERT
- {
- .ctl_name = NET_CORE_DIVERT_VERSION,
- .procname = "divert_version",
- .data = (void *)sysctl_divert_version,
- .maxlen = 32,
- .mode = 0444,
- .proc_handler = &proc_dostring
- },
-#endif /* CONFIG_NET_DIVERT */
#ifdef CONFIG_XFRM
{
.ctl_name = NET_CORE_AEVENT_ETIME,
diff --git a/net/socket.c b/net/socket.c
index 6c9b9b326d76..e8db54702a69 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -77,7 +77,6 @@
#include <linux/cache.h>
#include <linux/module.h>
#include <linux/highmem.h>
-#include <linux/divert.h>
#include <linux/mount.h>
#include <linux/security.h>
#include <linux/syscalls.h>
@@ -852,11 +851,6 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
err = vlan_ioctl_hook(argp);
mutex_unlock(&vlan_ioctl_mutex);
break;
- case SIOCGIFDIVERT:
- case SIOCSIFDIVERT:
- /* Convert this to call through a hook */
- err = divert_ioctl(cmd, argp);
- break;
case SIOCADDDLCI:
case SIOCDELDLCI:
err = -ENOPKG;