summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-11-23 02:00:47 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-11-23 02:00:47 +0000
commit06615f62b17d7de6e12d2f5ec6b88cf30af08413 (patch)
tree8766f208847d4876a6db619aebbf54d53b76eb44 /net
parentfa9bdb574f4febb751848a685d9a9017e04e1d53 (diff)
Merge with Linux 2.4.0-test10.
Diffstat (limited to 'net')
-rw-r--r--net/802/llc_macinit.c17
-rw-r--r--net/802/p8022.c5
-rw-r--r--net/802/psnap.c4
-rw-r--r--net/802/tr.c5
-rw-r--r--net/Config.in1
-rw-r--r--net/Makefile4
-rw-r--r--net/appletalk/ddp.c16
-rw-r--r--net/atm/pvc.c5
-rw-r--r--net/atm/svc.c7
-rw-r--r--net/ax25/Config.in2
-rw-r--r--net/ax25/af_ax25.c22
-rw-r--r--net/ax25/ax25_ds_in.c6
-rw-r--r--net/bridge/br.c4
-rw-r--r--net/bridge/br_if.c5
-rw-r--r--net/bridge/br_ioctl.c4
-rw-r--r--net/bridge/br_private_stp.h4
-rw-r--r--net/core/Makefile4
-rw-r--r--net/core/dev.c195
-rw-r--r--net/core/dev_mcast.c54
-rw-r--r--net/core/dv.c551
-rw-r--r--net/core/sysctl_net_core.c25
-rw-r--r--net/decnet/af_decnet.c66
-rw-r--r--net/econet/af_econet.c2
-rw-r--r--net/ipv4/af_inet.c45
-rw-r--r--net/ipv4/arp.c2
-rw-r--r--net/ipv4/inetpeer.c2
-rw-r--r--net/ipv4/ip_forward.c16
-rw-r--r--net/ipv4/ip_gre.c2
-rw-r--r--net/ipv4/ip_input.c8
-rw-r--r--net/ipv4/ip_nat_dumb.c5
-rw-r--r--net/ipv4/ip_output.c2
-rw-r--r--net/ipv4/ip_sockglue.c34
-rw-r--r--net/ipv4/ipip.c4
-rw-r--r--net/ipv4/netfilter/ip_nat_standalone.c2
-rw-r--r--net/ipv4/protocol.c2
-rw-r--r--net/ipv4/raw.c8
-rw-r--r--net/ipv4/route.c2
-rw-r--r--net/ipv4/sysctl_net_ipv4.c8
-rw-r--r--net/ipv4/tcp.c4
-rw-r--r--net/ipv4/tcp_ipv4.c52
-rw-r--r--net/ipv4/tcp_output.c4
-rw-r--r--net/ipv4/tcp_timer.c2
-rw-r--r--net/ipv4/udp.c29
-rw-r--r--net/ipv4/utils.c2
-rw-r--r--net/ipv6/af_inet6.c27
-rw-r--r--net/ipv6/protocol.c2
-rw-r--r--net/ipv6/raw.c4
-rw-r--r--net/ipv6/sit.c6
-rw-r--r--net/ipv6/tcp_ipv6.c8
-rw-r--r--net/ipv6/udp.c4
-rw-r--r--net/ipx/af_ipx.c22
-rw-r--r--net/irda/af_irda.c21
-rw-r--r--net/irda/irmod.c26
-rw-r--r--net/lapb/lapb_iface.c15
-rw-r--r--net/netlink/af_netlink.c10
-rw-r--r--net/netlink/netlink_dev.c4
-rw-r--r--net/netrom/af_netrom.c21
-rw-r--r--net/netsyms.c20
-rw-r--r--net/packet/af_packet.c30
-rw-r--r--net/protocols.c189
-rw-r--r--net/rose/af_rose.c20
-rw-r--r--net/socket.c35
-rw-r--r--net/sunrpc/auth.c6
-rw-r--r--net/sunrpc/auth_null.c1
-rw-r--r--net/sunrpc/svcsock.c3
-rw-r--r--net/unix/af_unix.c22
-rw-r--r--net/unix/sysctl_net_unix.c2
-rw-r--r--net/x25/af_x25.c32
68 files changed, 1150 insertions, 623 deletions
diff --git a/net/802/llc_macinit.c b/net/802/llc_macinit.c
index 792bfd5e8..987d8a5c4 100644
--- a/net/802/llc_macinit.c
+++ b/net/802/llc_macinit.c
@@ -204,24 +204,11 @@ EXPORT_SYMBOL(llc_cancel_timers);
#define ALL_TYPES_8022 0
-void __init llc_init(struct net_proto *proto)
+static int __init llc_init(void)
{
printk(KERN_NOTICE "IEEE 802.2 LLC for Linux 2.1 (c) 1996 Tim Alpaerts\n");
- return;
-}
-
-#ifdef MODULE
-
-
-int init_module(void)
-{
- llc_init(NULL);
return 0;
}
-void cleanup_module(void)
-{
-
-}
-#endif
+module_init(llc_init);
diff --git a/net/802/p8022.c b/net/802/p8022.c
index 9be3100dd..41a755e88 100644
--- a/net/802/p8022.c
+++ b/net/802/p8022.c
@@ -90,12 +90,15 @@ static struct packet_type p8022_packet_type =
EXPORT_SYMBOL(register_8022_client);
EXPORT_SYMBOL(unregister_8022_client);
-void __init p8022_proto_init(struct net_proto *pro)
+static int __init p8022_init(void)
{
p8022_packet_type.type=htons(ETH_P_802_2);
dev_add_pack(&p8022_packet_type);
+ return 0;
}
+module_init(p8022_init);
+
struct datalink_proto *register_8022_client(unsigned char type, int (*rcvfunc)(struct sk_buff *, struct net_device *, struct packet_type *))
{
struct datalink_proto *proto;
diff --git a/net/802/psnap.c b/net/802/psnap.c
index 3c493d7d9..907ac1b54 100644
--- a/net/802/psnap.c
+++ b/net/802/psnap.c
@@ -89,12 +89,14 @@ static void snap_datalink_header(struct datalink_proto *dl, struct sk_buff *skb,
EXPORT_SYMBOL(register_snap_client);
EXPORT_SYMBOL(unregister_snap_client);
-void __init snap_proto_init(struct net_proto *pro)
+static int __init snap_init(void)
{
snap_dl=register_8022_client(0xAA, snap_rcv);
if(snap_dl==NULL)
printk("SNAP - unable to register with 802.2\n");
+ return 0;
}
+module_init(snap_init);
/*
* Register SNAP clients. We don't yet use this for IP.
diff --git a/net/802/tr.c b/net/802/tr.c
index 097929257..73c938486 100644
--- a/net/802/tr.c
+++ b/net/802/tr.c
@@ -540,7 +540,7 @@ static int rif_get_info(char *buffer,char **start, off_t offset, int length)
* too much for this.
*/
-void __init rif_init(struct net_proto *unused)
+static int __init rif_init(void)
{
rif_timer.expires = RIF_TIMEOUT;
rif_timer.data = 0L;
@@ -549,4 +549,7 @@ void __init rif_init(struct net_proto *unused)
add_timer(&rif_timer);
proc_net_create("tr_rif",0,rif_get_info);
+ return 0;
}
+
+module_init(rif_init);
diff --git a/net/Config.in b/net/Config.in
index f383bbbd2..4d4f6c373 100644
--- a/net/Config.in
+++ b/net/Config.in
@@ -63,6 +63,7 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
tristate 'CCITT X.25 Packet Layer (EXPERIMENTAL)' CONFIG_X25
tristate 'LAPB Data Link Driver (EXPERIMENTAL)' CONFIG_LAPB
bool '802.2 LLC (EXPERIMENTAL)' CONFIG_LLC
+ bool 'Frame Diverter (EXPERIMENTAL)' CONFIG_NET_DIVERT
# if [ "$CONFIG_LLC" = "y" ]; then
# bool ' Netbeui (EXPERIMENTAL)' CONFIG_NETBEUI
# fi
diff --git a/net/Makefile b/net/Makefile
index 44f47fabc..ff79d8584 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -7,7 +7,7 @@
O_TARGET := network.o
-mod-subdirs := ipv4/netfilter ipv6/netfilter ipx irda atm
+mod-subdirs := ipv4/netfilter ipv6/netfilter ipx irda atm netlink
export-objs := netsyms.o
subdir-y := core ethernet
@@ -46,7 +46,7 @@ subdir-$(CONFIG_DECNET) += decnet
subdir-$(CONFIG_ECONET) += econet
-obj-y := socket.o protocols.o $(join $(subdir-y), $(patsubst %,/%.o,$(notdir $(subdir-y))))
+obj-y := socket.o $(join $(subdir-y), $(patsubst %,/%.o,$(notdir $(subdir-y))))
ifeq ($(CONFIG_NET),y)
obj-$(CONFIG_MODULES) += netsyms.o
obj-$(CONFIG_SYSCTL) += sysctl_net.o
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 260a5e530..e7784dabd 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -2120,7 +2120,7 @@ EXPORT_SYMBOL(atalk_find_dev_addr);
/* Called by proto.c on kernel start up */
-void __init atalk_proto_init(struct net_proto *pro)
+static int __init atalk_init(void)
{
(void) sock_register(&atalk_family_ops);
if((ddp_dl = register_snap_client(ddp_snap_id, atalk_rcv)) == NULL)
@@ -2148,16 +2148,11 @@ void __init atalk_proto_init(struct net_proto *pro)
#endif /* CONFIG_SYSCTL */
printk(KERN_INFO "NET4: AppleTalk 0.18 for Linux NET4.0\n");
+ return 0;
}
+module_init(atalk_init);
#ifdef MODULE
-
-int init_module(void)
-{
- atalk_proto_init(NULL);
- return (0);
-}
-
/*
* Note on MOD_{INC,DEC}_USE_COUNT:
*
@@ -2171,7 +2166,7 @@ int init_module(void)
* sockets be closed from user space.
*/
-void cleanup_module(void)
+static void __exit atalk_exit(void)
{
#ifdef CONFIG_SYSCTL
atalk_unregister_sysctl();
@@ -2195,6 +2190,7 @@ void cleanup_module(void)
return;
}
-
+module_exit(atalk_exit);
#endif /* MODULE */
+
#endif /* CONFIG_ATALK || CONFIG_ATALK_MODULE */
diff --git a/net/atm/pvc.c b/net/atm/pvc.c
index fc71c2435..ff28ed551 100644
--- a/net/atm/pvc.c
+++ b/net/atm/pvc.c
@@ -123,7 +123,7 @@ static struct net_proto_family pvc_family_ops = {
*/
-void __init atmpvc_proto_init(struct net_proto *pro)
+static int __init atmpvc_init(void)
{
int error;
@@ -139,4 +139,7 @@ void __init atmpvc_proto_init(struct net_proto *pro)
error = atm_proc_init();
if (error) printk("atm_proc_init fails with %d\n",error);
#endif
+ return 0;
}
+
+module_init(atmpvc_init);
diff --git a/net/atm/svc.c b/net/atm/svc.c
index bffe7aac5..7984cb22a 100644
--- a/net/atm/svc.c
+++ b/net/atm/svc.c
@@ -442,10 +442,13 @@ static struct net_proto_family svc_family_ops = {
* Initialize the ATM SVC protocol family
*/
-void __init atmsvc_proto_init(struct net_proto *pro)
+static int __init atmsvc_init(void)
{
if (sock_register(&svc_family_ops) < 0) {
printk(KERN_ERR "ATMSVC: can't register");
- return;
+ return -1;
}
+ return 0;
}
+
+module_init(atmsvc_init);
diff --git a/net/ax25/Config.in b/net/ax25/Config.in
index 2670528b3..b8e5d7333 100644
--- a/net/ax25/Config.in
+++ b/net/ax25/Config.in
@@ -3,7 +3,7 @@
#
# 19971130 Now in an own category to make correct compilation of the
# AX.25 stuff easier...
-# Joerg Reuter DL1BKE <jreuter@poboxes.com>
+# Joerg Reuter DL1BKE <jreuter@yaina.de>
# 19980129 Moved to net/ax25/Config.in, sourcing device drivers.
mainmenu_option next_comment
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index fc8910f2d..8e34e42e2 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -101,6 +101,7 @@
* ax25_connect() and ax25_sendmsg()
* Joerg(DL1BKE) Added support for SO_BINDTODEVICE
* Arnaldo C. Melo s/suser/capable(CAP_NET_ADMIN)/, some more cleanups
+ * Michal Ostrowski Module initialization cleanup.
*/
#include <linux/config.h>
@@ -137,6 +138,8 @@
#include <net/ip.h>
#include <net/arp.h>
+
+
ax25_cb *volatile ax25_list = NULL;
static struct proto_ops ax25_proto_ops;
@@ -1193,7 +1196,7 @@ static int ax25_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
*/
if (sk->zapped) {
/* check if we can remove this feature. It is broken. */
- printk(KERN_WARNING "ax25_connect(): %s uses autobind, please contact jreuter@poboxes.com\n",
+ printk(KERN_WARNING "ax25_connect(): %s uses autobind, please contact jreuter@yaina.de\n",
current->comm);
if ((err = ax25_rt_autobind(sk->protinfo.ax25, &fsa->fsa_ax25.sax25_call)) < 0)
return err;
@@ -1844,7 +1847,7 @@ EXPORT_SYMBOL(asc2ax);
EXPORT_SYMBOL(null_ax25_address);
EXPORT_SYMBOL(ax25_display_timer);
-void __init ax25_proto_init(struct net_proto *pro)
+static int __init ax25_init(void)
{
sock_register(&ax25_family_ops);
ax25_packet_type.type = htons(ETH_P_AX25);
@@ -1861,20 +1864,16 @@ void __init ax25_proto_init(struct net_proto *pro)
#endif
printk(KERN_INFO "NET4: G4KLX/GW4PTS AX.25 for Linux. Version 0.37 for Linux NET4.0\n");
+ return 0;
}
+module_init(ax25_init);
+
#ifdef MODULE
MODULE_AUTHOR("Jonathan Naylor G4KLX <g4klx@g4klx.demon.co.uk>");
MODULE_DESCRIPTION("The amateur radio AX.25 link layer protocol");
-int init_module(void)
-{
- ax25_proto_init(NULL);
-
- return 0;
-}
-
-void cleanup_module(void)
+static void __exit ax25_exit(void)
{
#ifdef CONFIG_PROC_FS
proc_net_remove("ax25_route");
@@ -1895,6 +1894,7 @@ void cleanup_module(void)
sock_unregister(PF_AX25);
}
-#endif
+module_exit(ax25_exit);
+#endif /* MODULE */
#endif
diff --git a/net/ax25/ax25_ds_in.c b/net/ax25/ax25_ds_in.c
index 464122823..3354206df 100644
--- a/net/ax25/ax25_ds_in.c
+++ b/net/ax25/ax25_ds_in.c
@@ -89,10 +89,8 @@ static int ax25_ds_state1_machine(ax25_cb *ax25, struct sk_buff *skb, int framet
ax25_dama_on(ax25);
/* according to DK4EG´s spec we are required to
- * send a RR RESPONSE FINAL NR=0. Please mail
- * <jreuter@poboxes.com> if this causes problems
- * with the TheNetNode DAMA Master implementation.
- */
+ * send a RR RESPONSE FINAL NR=0.
+ */
ax25_std_enquiry_response(ax25);
break;
diff --git a/net/bridge/br.c b/net/bridge/br.c
index 3c6c9b72d..cda2e570a 100644
--- a/net/bridge/br.c
+++ b/net/bridge/br.c
@@ -5,7 +5,7 @@
* Authors:
* Lennert Buytenhek <buytenh@gnu.org>
*
- * $Id: br.c,v 1.44 2000/08/04 06:08:32 davem Exp $
+ * $Id: br.c,v 1.45 2000/10/22 18:26:07 davem Exp $
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -38,7 +38,7 @@ void br_inc_use_count()
MOD_INC_USE_COUNT;
}
-int __init br_init(void)
+static int __init br_init(void)
{
printk(KERN_INFO "NET4: Ethernet Bridge 008 for NET4.0\n");
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 86355509d..295cfc973 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -5,7 +5,7 @@
* Authors:
* Lennert Buytenhek <buytenh@gnu.org>
*
- * $Id: br_if.c,v 1.3 2000/05/05 02:17:17 davem Exp $
+ * $Id: br_if.c,v 1.4 2000/10/05 01:58:16 davem Exp $
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -14,6 +14,7 @@
*/
#include <linux/kernel.h>
+#include <linux/if_arp.h>
#include <linux/if_bridge.h>
#include <linux/inetdevice.h>
#include <linux/rtnetlink.h>
@@ -222,7 +223,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
if (dev->br_port != NULL)
return -EBUSY;
- if (dev->flags & IFF_LOOPBACK)
+ if (dev->flags & IFF_LOOPBACK || dev->type != ARPHRD_ETHER)
return -EINVAL;
dev_hold(dev);
diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c
index dad96fb99..4d04aec66 100644
--- a/net/bridge/br_ioctl.c
+++ b/net/bridge/br_ioctl.c
@@ -5,7 +5,7 @@
* Authors:
* Lennert Buytenhek <buytenh@gnu.org>
*
- * $Id: br_ioctl.c,v 1.2 2000/02/21 15:51:34 davem Exp $
+ * $Id: br_ioctl.c,v 1.3 2000/10/05 01:58:16 davem Exp $
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -138,7 +138,7 @@ static int br_ioctl_device(struct net_bridge *br,
p.hold_timer_value = br_timer_get_residue(&pt->hold_timer);
if (copy_to_user((void *)arg0, &p, sizeof(p)))
- return -EINVAL;
+ return -EFAULT;
return 0;
}
diff --git a/net/bridge/br_private_stp.h b/net/bridge/br_private_stp.h
index 91faafff5..2857d5c91 100644
--- a/net/bridge/br_private_stp.h
+++ b/net/bridge/br_private_stp.h
@@ -4,7 +4,7 @@
* Authors:
* Lennert Buytenhek <buytenh@gnu.org>
*
- * $Id: br_private_stp.h,v 1.1 2000/02/18 16:47:13 davem Exp $
+ * $Id: br_private_stp.h,v 1.2 2000/10/30 22:03:20 davem Exp $
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -16,7 +16,7 @@
#define _BR_PRIVATE_STP_H
#define BPDU_TYPE_CONFIG 0
-#define BPDU_TYPE_TCN 1
+#define BPDU_TYPE_TCN 0x80
struct br_config_bpdu
{
diff --git a/net/core/Makefile b/net/core/Makefile
index 7ee0db3fd..af3c74091 100644
--- a/net/core/Makefile
+++ b/net/core/Makefile
@@ -29,6 +29,10 @@ ifdef CONFIG_NETFILTER
OX_OBJS += netfilter.o
endif
+ifeq ($(CONFIG_NET_DIVERT),y)
+O_OBJS += dv.o
+endif
+
endif
ifdef CONFIG_NET_PROFILE
diff --git a/net/core/dev.c b/net/core/dev.c
index e6f440cf4..17fae7a1e 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -59,6 +59,8 @@
* Paul Rusty Russell : SIOCSIFNAME
* Pekka Riikonen : Netdev boot-time settings code
* Andrew Morton : Make unregister_netdevice wait indefinitely on dev->refcnt
+ * J Hadi Salim : - Backlog queue sampling
+ * - netif_rx() feedback
*/
#include <asm/uaccess.h>
@@ -85,6 +87,7 @@
#include <linux/proc_fs.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/profile.h>
@@ -97,6 +100,18 @@
extern int plip_init(void);
#endif
+/* This define, if set, will randomly drop a packet when congestion
+ * is more than moderate. It helps fairness in the multi-interface
+ * case when one of them is a hog, but it kills performance for the
+ * single interface case so it is off now by default.
+ */
+#undef RAND_LIE
+
+/* Setting this will sample the queue lengths and thus congestion
+ * via a timer instead of as each packet is received.
+ */
+#undef OFFLINE_SAMPLE
+
NET_PROFILE_DEFINE(dev_queue_xmit)
NET_PROFILE_DEFINE(softnet_process)
@@ -133,6 +148,11 @@ const char *if_port_text[] = {
static struct packet_type *ptype_base[16]; /* 16 way hashed list */
static struct packet_type *ptype_all = NULL; /* Taps */
+#ifdef OFFLINE_SAMPLE
+static void sample_queue(unsigned long dummy);
+static struct timer_list samp_timer = { function: sample_queue };
+#endif
+
/*
* Our notifier list
*/
@@ -933,12 +953,20 @@ int dev_queue_xmit(struct sk_buff *skb)
=======================================================================*/
int netdev_max_backlog = 300;
+/* These numbers are selected based on intuition and some
+ * experimentatiom, if you have more scientific way of doing this
+ * please go ahead and fix things.
+ */
+int no_cong_thresh = 10;
+int no_cong = 20;
+int lo_cong = 100;
+int mod_cong = 290;
struct netif_rx_stats netdev_rx_stat[NR_CPUS];
#ifdef CONFIG_NET_HW_FLOWCONTROL
-static atomic_t netdev_dropping = ATOMIC_INIT(0);
+atomic_t netdev_dropping = ATOMIC_INIT(0);
static unsigned long netdev_fc_mask = 1;
unsigned long netdev_fc_xoff = 0;
spinlock_t netdev_fc_lock = SPIN_LOCK_UNLOCKED;
@@ -996,6 +1024,56 @@ static void netdev_wakeup(void)
}
#endif
+static void get_sample_stats(int cpu)
+{
+#ifdef RAND_LIE
+ unsigned long rd;
+ int rq;
+#endif
+ int blog = softnet_data[cpu].input_pkt_queue.qlen;
+ int avg_blog = softnet_data[cpu].avg_blog;
+
+ avg_blog = (avg_blog >> 1)+ (blog >> 1);
+
+ if (avg_blog > mod_cong) {
+ /* Above moderate congestion levels. */
+ softnet_data[cpu].cng_level = NET_RX_CN_HIGH;
+#ifdef RAND_LIE
+ rd = net_random();
+ rq = rd % netdev_max_backlog;
+ if (rq < avg_blog) /* unlucky bastard */
+ softnet_data[cpu].cng_level = NET_RX_DROP;
+#endif
+ } else if (avg_blog > lo_cong) {
+ softnet_data[cpu].cng_level = NET_RX_CN_MOD;
+#ifdef RAND_LIE
+ rd = net_random();
+ rq = rd % netdev_max_backlog;
+ if (rq < avg_blog) /* unlucky bastard */
+ softnet_data[cpu].cng_level = NET_RX_CN_HIGH;
+#endif
+ } else if (avg_blog > no_cong)
+ softnet_data[cpu].cng_level = NET_RX_CN_LOW;
+ else /* no congestion */
+ softnet_data[cpu].cng_level = NET_RX_SUCCESS;
+
+ softnet_data[cpu].avg_blog = avg_blog;
+}
+
+#ifdef OFFLINE_SAMPLE
+static void sample_queue(unsigned long dummy)
+{
+/* 10 ms 0r 1ms -- i dont care -- JHS */
+ int next_tick = 1;
+ int cpu = smp_processor_id();
+
+ get_sample_stats(cpu);
+ next_tick += jiffies;
+ mod_timer(&samp_timer, next_tick);
+}
+#endif
+
+
/**
* netif_rx - post buffer to the network code
* @skb: buffer to post
@@ -1004,9 +1082,18 @@ static void netdev_wakeup(void)
* the upper (protocol) levels to process. It always succeeds. The buffer
* may be dropped during processing for congestion control or by the
* protocol layers.
+ *
+ * return values:
+ * NET_RX_SUCCESS (no congestion)
+ * NET_RX_CN_LOW (low congestion)
+ * NET_RX_CN_MOD (moderate congestion)
+ * NET_RX_CN_HIGH (high congestion)
+ * NET_RX_DROP (packet was dropped)
+ *
+ *
*/
-void netif_rx(struct sk_buff *skb)
+int netif_rx(struct sk_buff *skb)
{
int this_cpu = smp_processor_id();
struct softnet_data *queue;
@@ -1036,7 +1123,10 @@ enqueue:
__skb_queue_tail(&queue->input_pkt_queue,skb);
__cpu_raise_softirq(this_cpu, NET_RX_SOFTIRQ);
local_irq_restore(flags);
- return;
+#ifndef OFFLINE_SAMPLE
+ get_sample_stats(this_cpu);
+#endif
+ return softnet_data[this_cpu].cng_level;
}
if (queue->throttle) {
@@ -1062,19 +1152,22 @@ drop:
local_irq_restore(flags);
kfree_skb(skb);
+ return NET_RX_DROP;
}
/* Deliver skb to an old protocol, which is not threaded well
or which do not understand shared skbs.
*/
-static void deliver_to_old_ones(struct packet_type *pt, struct sk_buff *skb, int last)
+static int deliver_to_old_ones(struct packet_type *pt, struct sk_buff *skb, int last)
{
static spinlock_t net_bh_lock = SPIN_LOCK_UNLOCKED;
+ int ret = NET_RX_DROP;
+
if (!last) {
skb = skb_clone(skb, GFP_ATOMIC);
if (skb == NULL)
- return;
+ return ret;
}
/* The assumption (correct one) is that old protocols
@@ -1087,10 +1180,11 @@ static void deliver_to_old_ones(struct packet_type *pt, struct sk_buff *skb, int
/* Disable timers and wait for all timers completion */
tasklet_disable(bh_task_vec+TIMER_BH);
- pt->func(skb, skb->dev, pt);
+ ret = pt->func(skb, skb->dev, pt);
tasklet_enable(bh_task_vec+TIMER_BH);
spin_unlock(&net_bh_lock);
+ return ret;
}
/* Reparent skb to master device. This function is called
@@ -1173,22 +1267,35 @@ void net_call_rx_atomic(void (*fn)(void))
void (*br_handle_frame_hook)(struct sk_buff *skb) = NULL;
#endif
-static void __inline__ handle_bridge(struct sk_buff *skb,
+static int __inline__ handle_bridge(struct sk_buff *skb,
struct packet_type *pt_prev)
{
+ int ret = NET_RX_DROP;
+
if (pt_prev) {
if (!pt_prev->data)
- deliver_to_old_ones(pt_prev, skb, 0);
+ ret = deliver_to_old_ones(pt_prev, skb, 0);
else {
atomic_inc(&skb->users);
- pt_prev->func(skb, skb->dev, pt_prev);
+ ret = pt_prev->func(skb, skb->dev, pt_prev);
}
}
br_handle_frame_hook(skb);
+ return ret;
}
+#ifdef CONFIG_NET_DIVERT
+static inline void handle_diverter(struct sk_buff *skb)
+{
+ /* if diversion is supported on device, then divert */
+ if (skb->dev->divert && skb->dev->divert->divert)
+ divert_frame(skb);
+}
+#endif /* CONFIG_NET_DIVERT */
+
+
static void net_rx_action(struct softirq_action *h)
{
int this_cpu = smp_processor_id();
@@ -1239,6 +1346,12 @@ static void net_rx_action(struct softirq_action *h)
}
}
+#ifdef CONFIG_NET_DIVERT
+ if (skb->dev->divert && skb->dev->divert->divert)
+ handle_diverter(skb);
+#endif /* CONFIG_NET_DIVERT */
+
+
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
if (skb->dev->br_port != NULL &&
br_handle_frame_hook != NULL) {
@@ -1275,6 +1388,17 @@ static void net_rx_action(struct softirq_action *h)
if (bugdet-- < 0 || jiffies - start_time > 1)
goto softnet_break;
+
+#ifdef CONFIG_NET_HW_FLOWCONTROL
+ if (queue->throttle && queue->input_pkt_queue.qlen < no_cong_thresh ) {
+ if (atomic_dec_and_test(&netdev_dropping)) {
+ queue->throttle = 0;
+ netdev_wakeup();
+ goto softnet_break;
+ }
+ }
+#endif
+
}
br_read_unlock(BR_NETPROTO_LOCK);
@@ -2113,9 +2237,9 @@ int dev_ioctl(unsigned int cmd, void *arg)
/**
* dev_new_index - allocate an ifindex
*
- * Returns a suitable unique value for a new device interface number.
- * The caller must hold the rtnl semaphore to be sure it remains
- * unique.
+ * Returns a suitable unique value for a new device interface
+ * number. The caller must hold the rtnl semaphore or the
+ * dev_base_lock to be sure it remains unique.
*/
int dev_new_index(void)
@@ -2140,6 +2264,10 @@ static int dev_boot_phase = 1;
* chain. 0 is returned on success. A negative errno code is returned
* on a failure to set up the device, or if the name is a duplicate.
*
+ * Callers must hold the rtnl semaphore. See the comment at the
+ * end of Space.c for details about the locking. You may want
+ * register_netdev() instead of this.
+ *
* BUGS:
* The locking appears insufficient to guarantee two parallel registers
* will not get the same name.
@@ -2148,6 +2276,9 @@ static int dev_boot_phase = 1;
int register_netdevice(struct net_device *dev)
{
struct net_device *d, **dp;
+#ifdef CONFIG_NET_DIVERT
+ int ret;
+#endif
spin_lock_init(&dev->queue_lock);
spin_lock_init(&dev->xmit_lock);
@@ -2182,6 +2313,12 @@ int register_netdevice(struct net_device *dev)
dev_hold(dev);
write_unlock_bh(&dev_base_lock);
+#ifdef CONFIG_NET_DIVERT
+ ret = alloc_divert_blk(dev);
+ if (ret)
+ return ret;
+#endif /* CONFIG_NET_DIVERT */
+
/*
* Default initial state at registry is that the
* device is present.
@@ -2231,6 +2368,12 @@ int register_netdevice(struct net_device *dev)
dev->deadbeaf = 0;
write_unlock_bh(&dev_base_lock);
+#ifdef CONFIG_NET_DIVERT
+ ret = alloc_divert_blk(dev);
+ if (ret)
+ return ret;
+#endif /* CONFIG_NET_DIVERT */
+
/* Notify protocols, that a new device appeared. */
notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev);
@@ -2272,6 +2415,10 @@ int netdev_finish_unregister(struct net_device *dev)
* This function shuts down a device interface and removes it
* from the kernel tables. On success 0 is returned, on a failure
* a negative errno code is returned.
+ *
+ * Callers must hold the rtnl semaphore. See the comment at the
+ * end of Space.c for details about the locking. You may want
+ * unregister_netdev() instead of this.
*/
int unregister_netdevice(struct net_device *dev)
@@ -2325,6 +2472,10 @@ int unregister_netdevice(struct net_device *dev)
/* Notifier chain MUST detach us from master device. */
BUG_TRAP(dev->master==NULL);
+#ifdef CONFIG_NET_DIVERT
+ free_divert_blk(dev);
+#endif
+
if (dev->new_style) {
#ifdef NET_REFCNT_DEBUG
if (atomic_read(&dev->refcnt) != 1)
@@ -2397,7 +2548,15 @@ int unregister_netdevice(struct net_device *dev)
extern void net_device_init(void);
extern void ip_auto_config(void);
+#ifdef CONFIG_NET_DIVERT
+extern void dv_init(void);
+#endif /* CONFIG_NET_DIVERT */
+
+/*
+ * Callers must hold the rtnl semaphore. See the comment at the
+ * end of Space.c for details about the locking.
+ */
int __init net_dev_init(void)
{
struct net_device *dev, **dp;
@@ -2407,6 +2566,10 @@ int __init net_dev_init(void)
pktsched_init();
#endif
+#ifdef CONFIG_NET_DIVERT
+ dv_init();
+#endif /* CONFIG_NET_DIVERT */
+
/*
* Initialise the packet receive queues.
*/
@@ -2417,6 +2580,8 @@ int __init net_dev_init(void)
queue = &softnet_data[i];
skb_queue_head_init(&queue->input_pkt_queue);
queue->throttle = 0;
+ queue->cng_level = 0;
+ queue->avg_blog = 10; /* arbitrary non-zero */
queue->completion_queue = NULL;
}
@@ -2425,6 +2590,12 @@ int __init net_dev_init(void)
NET_PROFILE_REGISTER(dev_queue_xmit);
NET_PROFILE_REGISTER(softnet_process);
#endif
+
+#ifdef OFFLINE_SAMPLE
+ samp_timer.expires = jiffies + (10 * HZ);
+ add_timer(&samp_timer);
+#endif
+
/*
* Add the devices.
* If the call to dev->init fails, the dev is removed
diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c
index cf590db04..6b24a1416 100644
--- a/net/core/dev_mcast.c
+++ b/net/core/dev_mcast.c
@@ -13,6 +13,7 @@
* rather than any time but...
* Alan Cox : IFF_ALLMULTI support.
* Alan Cox : New format set_multicast_list() calls.
+ * Gleb Natapov : Remove dev_mc_lock.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -59,16 +60,14 @@
* Device mc lists are changed by bh at least if IPv6 is enabled,
* so that it must be bh protected.
*
- * We protect all mc lists with global rw lock
- * and block accesses to device mc filters with dev->xmit_lock.
+ * We block accesses to device mc filters with dev->xmit_lock.
*/
-static rwlock_t dev_mc_lock = RW_LOCK_UNLOCKED;
/*
* Update the multicast list into the physical NIC controller.
*/
-void dev_mc_upload(struct net_device *dev)
+static void __dev_mc_upload(struct net_device *dev)
{
/* Don't do anything till we up the interface
* [dev_open will call this function so the list will
@@ -87,13 +86,14 @@ void dev_mc_upload(struct net_device *dev)
!netif_device_present(dev))
return;
- read_lock_bh(&dev_mc_lock);
- spin_lock(&dev->xmit_lock);
- dev->xmit_lock_owner = smp_processor_id();
dev->set_multicast_list(dev);
- dev->xmit_lock_owner = -1;
- spin_unlock(&dev->xmit_lock);
- read_unlock_bh(&dev_mc_lock);
+}
+
+void dev_mc_upload(struct net_device *dev)
+{
+ spin_lock_bh(&dev->xmit_lock);
+ __dev_mc_upload(dev);
+ spin_unlock_bh(&dev->xmit_lock);
}
/*
@@ -105,7 +105,8 @@ int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl)
int err = 0;
struct dev_mc_list *dmi, **dmip;
- write_lock_bh(&dev_mc_lock);
+ spin_lock_bh(&dev->xmit_lock);
+
for (dmip = &dev->mc_list; (dmi = *dmip) != NULL; dmip = &dmi->next) {
/*
* Find the entry we want to delete. The device could
@@ -127,7 +128,6 @@ int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl)
*/
*dmip = dmi->next;
dev->mc_count--;
- write_unlock_bh(&dev_mc_lock);
kfree(dmi);
@@ -135,13 +135,15 @@ int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl)
* We have altered the list, so the card
* loaded filter is now wrong. Fix it
*/
- dev_mc_upload(dev);
+ __dev_mc_upload(dev);
+
+ spin_unlock_bh(&dev->xmit_lock);
return 0;
}
}
err = -ENOENT;
done:
- write_unlock_bh(&dev_mc_lock);
+ spin_unlock_bh(&dev->xmit_lock);
return err;
}
@@ -156,7 +158,7 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl)
dmi1 = (struct dev_mc_list *)kmalloc(sizeof(*dmi), GFP_ATOMIC);
- write_lock_bh(&dev_mc_lock);
+ spin_lock_bh(&dev->xmit_lock);
for (dmi = dev->mc_list; dmi != NULL; dmi = dmi->next) {
if (memcmp(dmi->dmi_addr, addr, dmi->dmi_addrlen) == 0 &&
dmi->dmi_addrlen == alen) {
@@ -172,7 +174,7 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl)
}
if ((dmi = dmi1) == NULL) {
- write_unlock_bh(&dev_mc_lock);
+ spin_unlock_bh(&dev->xmit_lock);
return -ENOMEM;
}
memcpy(dmi->dmi_addr, addr, alen);
@@ -182,12 +184,14 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl)
dmi->dmi_gusers = glbl ? 1 : 0;
dev->mc_list = dmi;
dev->mc_count++;
- write_unlock_bh(&dev_mc_lock);
- dev_mc_upload(dev);
+
+ __dev_mc_upload(dev);
+
+ spin_unlock_bh(&dev->xmit_lock);
return 0;
done:
- write_unlock_bh(&dev_mc_lock);
+ spin_unlock_bh(&dev->xmit_lock);
if (dmi1)
kfree(dmi1);
return err;
@@ -199,7 +203,8 @@ done:
void dev_mc_discard(struct net_device *dev)
{
- write_lock_bh(&dev_mc_lock);
+ spin_lock_bh(&dev->xmit_lock);
+
while (dev->mc_list != NULL) {
struct dev_mc_list *tmp = dev->mc_list;
dev->mc_list = tmp->next;
@@ -208,7 +213,8 @@ void dev_mc_discard(struct net_device *dev)
kfree(tmp);
}
dev->mc_count = 0;
- write_unlock_bh(&dev_mc_lock);
+
+ spin_unlock_bh(&dev->xmit_lock);
}
#ifdef CONFIG_PROC_FS
@@ -222,7 +228,7 @@ static int dev_mc_read_proc(char *buffer, char **start, off_t offset,
read_lock(&dev_base_lock);
for (dev = dev_base; dev; dev = dev->next) {
- read_lock_bh(&dev_mc_lock);
+ spin_lock_bh(&dev->xmit_lock);
for (m = dev->mc_list; m; m = m->next) {
int i;
@@ -240,11 +246,11 @@ static int dev_mc_read_proc(char *buffer, char **start, off_t offset,
begin = pos;
}
if (pos > offset + length) {
- read_unlock_bh(&dev_mc_lock);
+ spin_unlock_bh(&dev->xmit_lock);
goto done;
}
}
- read_unlock_bh(&dev_mc_lock);
+ spin_unlock_bh(&dev->xmit_lock);
}
*eof = 1;
diff --git a/net/core/dv.c b/net/core/dv.c
new file mode 100644
index 000000000..4df7747b8
--- /dev/null
+++ b/net/core/dv.c
@@ -0,0 +1,551 @@
+/*
+ * 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
+ *
+ * Version: @(#)eth.c 0.41 09/09/2000
+ *
+ * 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/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/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 */
+
+int __init dv_init(void)
+{
+ printk(KERN_INFO "NET4: Frame Diverter %s\n", sysctl_divert_version);
+ return 0;
+}
+
+/*
+ * 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;
+
+ if (!strncmp(dev->name, "eth", 3)) {
+ printk(KERN_DEBUG "divert: allocating divert_blk for %s\n",
+ dev->name);
+
+ dev->divert = (struct divert_blk *)
+ kmalloc(alloc_size, GFP_KERNEL);
+ if (dev->divert == NULL) {
+ printk(KERN_DEBUG "divert: unable to allocate divert_blk for %s\n",
+ dev->name);
+ return -EFAULT;
+ } else {
+ memset(dev->divert, 0, sizeof(struct divert_blk));
+ }
+ } else {
+ printk(KERN_DEBUG "divert: not allocating divert_blk for non-ethernet device %s\n",
+ dev->name);
+
+ dev->divert = NULL;
+ }
+ 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;
+ printk(KERN_DEBUG "divert: freeing divert_blk for %s\n",
+ dev->name);
+ } else {
+ printk(KERN_DEBUG "divert: no divert_blk to free, %s not ethernet\n",
+ dev->name);
+ }
+}
+
+/*
+ * Adds a tcp/udp (source or dest) port to an array
+ */
+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)
+ */
+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() */
+int check_args(struct divert_cf *div_cf, struct net_device **dev)
+{
+ char devname[32];
+
+ 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;
+
+ /* user issuing the ioctl must be a super one :) */
+ if (!suser())
+ return -EPERM;
+
+ /* Device must have a divert_blk member NOT null */
+ if ((*dev)->divert == NULL)
+ return -EFAULT;
+
+ return 0;
+}
+
+/*
+ * control function of the diverter
+ */
+#define DVDBG(a) \
+ printk(KERN_DEBUG "divert_ioctl() line %d %s\n", __LINE__, (a))
+
+int divert_ioctl(unsigned int cmd, struct divert_cf *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(skb->mac.ethernet, skb->dev->dev_addr, ETH_ALEN); \
+ skb->pkt_type=PACKET_HOST
+
+void divert_frame(struct sk_buff *skb)
+{
+ struct ethhdr *eth = skb->mac.ethernet;
+ 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 (!memcmp(eth, skb->dev->dev_addr, ETH_ALEN))
+ 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;
+ };
+
+ return;
+}
+
diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
index 4ea599a88..2f6090a2f 100644
--- a/net/core/sysctl_net_core.c
+++ b/net/core/sysctl_net_core.c
@@ -12,6 +12,10 @@
#ifdef CONFIG_SYSCTL
extern int netdev_max_backlog;
+extern int no_cong_thresh;
+extern int no_cong;
+extern int lo_cong;
+extern int mod_cong;
extern int netdev_fastroute;
extern int net_msg_cost;
extern int net_msg_burst;
@@ -25,6 +29,10 @@ extern int sysctl_core_destroy_delay;
extern int sysctl_optmem_max;
extern int sysctl_hot_list_len;
+#ifdef CONFIG_NET_DIVERT
+extern char sysctl_divert_version[];
+#endif /* CONFIG_NET_DIVERT */
+
ctl_table core_table[] = {
#ifdef CONFIG_NET
{NET_CORE_WMEM_MAX, "wmem_max",
@@ -42,6 +50,18 @@ ctl_table core_table[] = {
{NET_CORE_MAX_BACKLOG, "netdev_max_backlog",
&netdev_max_backlog, sizeof(int), 0644, NULL,
&proc_dointvec},
+ {NET_CORE_NO_CONG_THRESH, "no_cong_thresh",
+ &no_cong, sizeof(int), 0644, NULL,
+ &proc_dointvec},
+ {NET_CORE_NO_CONG, "no_cong",
+ &no_cong, sizeof(int), 0644, NULL,
+ &proc_dointvec},
+ {NET_CORE_LO_CONG, "lo_cong",
+ &lo_cong, sizeof(int), 0644, NULL,
+ &proc_dointvec},
+ {NET_CORE_MOD_CONG, "mod_cong",
+ &mod_cong, sizeof(int), 0644, NULL,
+ &proc_dointvec},
#ifdef CONFIG_NET_FASTROUTE
{NET_CORE_FASTROUTE, "netdev_fastroute",
&netdev_fastroute, sizeof(int), 0644, NULL,
@@ -59,6 +79,11 @@ ctl_table core_table[] = {
{NET_CORE_HOT_LIST_LENGTH, "hot_list_length",
&sysctl_hot_list_len, sizeof(int), 0644, NULL,
&proc_dointvec},
+#ifdef CONFIG_NET_DIVERT
+ {NET_CORE_DIVERT_VERSION, "divert_version",
+ (void *)sysctl_divert_version, 32, 0444, NULL,
+ &proc_dostring},
+#endif /* CONFIG_NET_DIVERT */
#endif /* CONFIG_NET */
{ 0 }
};
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
index 348c30fce..8de443979 100644
--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -2053,8 +2053,36 @@ void dn_register_sysctl(void);
void dn_unregister_sysctl(void);
#endif
-void __init decnet_proto_init(struct net_proto *pro)
+
+#ifdef MODULE
+EXPORT_NO_SYMBOLS;
+MODULE_DESCRIPTION("The Linux DECnet Network Protocol");
+MODULE_AUTHOR("Linux DECnet Project Team");
+
+static int addr[2] = {0, 0};
+
+MODULE_PARM(addr, "2i");
+MODULE_PARM_DESC(addr, "The DECnet address of this machine: area,node");
+#endif
+
+
+static int __init decnet_init(void)
{
+#ifdef MODULE
+ if (addr[0] > 63 || addr[0] < 0) {
+ printk(KERN_ERR "DECnet: Area must be between 0 and 63");
+ return 1;
+ }
+
+ if (addr[1] > 1023 || addr[1] < 0) {
+ printk(KERN_ERR "DECnet: Node must be between 0 and 1023");
+ return 1;
+ }
+
+ decnet_address = dn_htons((addr[0] << 10) | addr[1]);
+ dn_dn2eth(decnet_ether_address, dn_ntohs(decnet_address));
+#endif
+
printk(KERN_INFO "NET4: DECnet for Linux: V.2.3.49s (C) 1995-2000 Linux DECnet Project Team\n");
sock_register(&dn_family_ops);
@@ -2074,6 +2102,7 @@ void __init decnet_proto_init(struct net_proto *pro)
#ifdef CONFIG_SYSCTL
dn_register_sysctl();
#endif /* CONFIG_SYSCTL */
+ return 0;
}
@@ -2093,37 +2122,7 @@ static int __init decnet_setup(char *str)
__setup("decnet=", decnet_setup);
#endif
-#ifdef MODULE
-EXPORT_NO_SYMBOLS;
-MODULE_DESCRIPTION("The Linux DECnet Network Protocol");
-MODULE_AUTHOR("Linux DECnet Project Team");
-
-static int addr[2] = {0, 0};
-
-MODULE_PARM(addr, "2i");
-MODULE_PARM_DESC(addr, "The DECnet address of this machine: area,node");
-
-int __init init_module(void)
-{
- if (addr[0] > 63 || addr[0] < 0) {
- printk(KERN_ERR "DECnet: Area must be between 0 and 63");
- return 1;
- }
-
- if (addr[1] > 1023 || addr[1] < 0) {
- printk(KERN_ERR "DECnet: Node must be between 0 and 1023");
- return 1;
- }
-
- decnet_address = dn_htons((addr[0] << 10) | addr[1]);
- dn_dn2eth(decnet_ether_address, dn_ntohs(decnet_address));
-
- decnet_proto_init(NULL);
-
- return 0;
-}
-
-void __exit cleanup_module(void)
+static void __exit decnet_exit(void)
{
#ifdef CONFIG_SYSCTL
dn_unregister_sysctl();
@@ -2145,4 +2144,5 @@ void __exit cleanup_module(void)
sock_unregister(AF_DECnet);
}
-#endif
+module_init(decnet_init);
+module_exit(decnet_exit);
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c
index 7a2a815ce..5d44e1f12 100644
--- a/net/econet/af_econet.c
+++ b/net/econet/af_econet.c
@@ -1143,7 +1143,5 @@ int __init econet_proto_init(void)
return 0;
}
-#ifdef MODULE
module_init(econet_proto_init);
module_exit(econet_proto_exit);
-#endif
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 69c6ff036..584814ad8 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -5,7 +5,7 @@
*
* PF_INET protocol family socket handler.
*
- * Version: $Id: af_inet.c,v 1.114 2000/09/18 05:59:48 davem Exp $
+ * Version: $Id: af_inet.c,v 1.121 2000/10/24 21:26:18 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -107,6 +107,9 @@
#ifdef CONFIG_KMOD
#include <linux/kmod.h>
#endif
+#ifdef CONFIG_NET_DIVERT
+#include <linux/divert.h>
+#endif /* CONFIG_NET_DIVERT */
#if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO)
#include <linux/wireless.h> /* Note : will define WIRELESS_EXT */
#endif /* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */
@@ -444,6 +447,9 @@ int inet_release(struct socket *sock)
return(0);
}
+/* It is off by default, see below. */
+int sysctl_ip_nonlocal_bind;
+
static int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
{
struct sockaddr_in *addr=(struct sockaddr_in *)uaddr;
@@ -461,6 +467,21 @@ static int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr);
+ /* Not specified by any standard per-se, however it breaks too
+ * many applications when removed. It is unfortunate since
+ * allowing applications to make a non-local bind solves
+ * several problems with systems using dynamic addressing.
+ * (ie. your servers still start up even if your ISDN link
+ * is temporarily down)
+ */
+ if (sysctl_ip_nonlocal_bind == 0 &&
+ sk->protinfo.af_inet.freebind == 0 &&
+ addr->sin_addr.s_addr != INADDR_ANY &&
+ chk_addr_ret != RTN_LOCAL &&
+ chk_addr_ret != RTN_MULTICAST &&
+ chk_addr_ret != RTN_BROADCAST)
+ return -EADDRNOTAVAIL;
+
snum = ntohs(addr->sin_port);
if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
return -EACCES;
@@ -750,14 +771,15 @@ int inet_shutdown(struct socket *sock, int how)
}
switch (sk->state) {
- default:
+ case TCP_CLOSE:
+ err = -ENOTCONN;
+ /* Hack to wake up other listeners, who can poll for
+ POLLHUP, even on eg. unconnected UDP sockets -- RR */
+ default:
sk->shutdown |= how;
if (sk->prot->shutdown)
sk->prot->shutdown(sk, how);
break;
- case TCP_CLOSE:
- err = -ENOTCONN;
- break;
/* Remaining two branches are temporary solution for missing
* close() in multithreaded environment. It is _not_ a good idea,
@@ -847,6 +869,13 @@ static int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
if (br_ioctl_hook != NULL)
return br_ioctl_hook(arg);
#endif
+ case SIOCGIFDIVERT:
+ case SIOCSIFDIVERT:
+#ifdef CONFIG_NET_DIVERT
+ return(divert_ioctl(cmd, (struct divert_cf *) arg));
+#else
+ return -ENOPKG;
+#endif /* CONFIG_NET_DIVERT */
return -ENOPKG;
case SIOCADDDLCI:
@@ -946,7 +975,7 @@ extern void tcp_v4_init(struct net_proto_family *);
* Called by socket.c on kernel startup.
*/
-void __init inet_proto_init(struct net_proto *pro)
+static int __init inet_init(void)
{
struct sk_buff *dummy_skb;
struct inet_protocol *p;
@@ -956,7 +985,7 @@ void __init inet_proto_init(struct net_proto *pro)
if (sizeof(struct inet_skb_parm) > sizeof(dummy_skb->cb))
{
printk(KERN_CRIT "inet_proto_init: panic\n");
- return;
+ return -EINVAL;
}
/*
@@ -1030,4 +1059,6 @@ void __init inet_proto_init(struct net_proto *pro)
proc_net_create ("tcp", 0, tcp_get_info);
proc_net_create ("udp", 0, udp_get_info);
#endif /* CONFIG_PROC_FS */
+ return 0;
}
+module_init(inet_init);
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index c173b9eb3..b410d1de4 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -1,6 +1,6 @@
/* linux/net/inet/arp.c
*
- * Version: $Id: arp.c,v 1.88 2000/08/02 06:05:02 davem Exp $
+ * Version: $Id: arp.c,v 1.90 2000/10/04 09:20:56 anton Exp $
*
* Copyright (C) 1994 by Florian La Roche
*
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
index cda89659c..8c103857c 100644
--- a/net/ipv4/inetpeer.c
+++ b/net/ipv4/inetpeer.c
@@ -3,7 +3,7 @@
*
* This source is covered by the GNU GPL, the same as all kernel sources.
*
- * Version: $Id: inetpeer.c,v 1.2 2000/05/03 06:37:06 davem Exp $
+ * Version: $Id: inetpeer.c,v 1.3 2000/10/03 07:29:00 anton Exp $
*
* Authors: Andrey V. Savochkin <saw@msu.ru>
*/
diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c
index 7d8efb6dd..7df6e72e3 100644
--- a/net/ipv4/ip_forward.c
+++ b/net/ipv4/ip_forward.c
@@ -5,7 +5,7 @@
*
* The IP forwarding functionality.
*
- * Version: $Id: ip_forward.c,v 1.46 2000/01/09 02:19:37 davem Exp $
+ * Version: $Id: ip_forward.c,v 1.47 2000/10/24 22:54:26 davem Exp $
*
* Authors: see ip.c
*
@@ -63,13 +63,11 @@ static inline int ip_forward_finish(struct sk_buff *skb)
dst_release(old_dst);
}
#endif
- ip_send(skb);
- return 0;
+ return (ip_send(skb));
}
ip_forward_options(skb);
- ip_send(skb);
- return 0;
+ return (ip_send(skb));
}
int ip_forward(struct sk_buff *skb)
@@ -81,7 +79,7 @@ int ip_forward(struct sk_buff *skb)
unsigned short mtu;
if (IPCB(skb)->opt.router_alert && ip_call_ra_chain(skb))
- return 0;
+ return NET_RX_SUCCESS;
if (skb->pkt_type != PACKET_HOST)
goto drop;
@@ -119,7 +117,7 @@ int ip_forward(struct sk_buff *skb)
/* We are about to mangle packet. Copy it! */
if ((skb = skb_cow(skb, dev2->hard_header_len)) == NULL)
- return -1;
+ return NET_RX_DROP;
iph = skb->nh.iph;
opt = &(IPCB(skb)->opt);
@@ -138,7 +136,7 @@ int ip_forward(struct sk_buff *skb)
if (rt->rt_flags & RTCF_NAT) {
if (ip_do_nat(skb)) {
kfree_skb(skb);
- return -1;
+ return NET_RX_BAD;
}
}
#endif
@@ -163,5 +161,5 @@ too_many_hops:
icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0);
drop:
kfree_skb(skb);
- return -1;
+ return NET_RX_DROP;
}
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index e7167aa65..f7b73adb8 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -1266,7 +1266,9 @@ int __init ipgre_init(void)
#ifdef MODULE
register_netdev(&ipgre_fb_tunnel_dev);
#else
+ rtnl_lock();
register_netdevice(&ipgre_fb_tunnel_dev);
+ rtnl_unlock();
#endif
inet_add_protocol(&ipgre_protocol);
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index bb76f7ce5..873030d0a 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -5,7 +5,7 @@
*
* The Internet Protocol (IP) module.
*
- * Version: $Id: ip_input.c,v 1.49 2000/08/21 20:41:55 davem Exp $
+ * Version: $Id: ip_input.c,v 1.50 2000/10/24 22:54:26 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -341,7 +341,7 @@ static inline int ip_rcv_finish(struct sk_buff *skb)
skb = skb_cow(skb, skb_headroom(skb));
if (skb == NULL)
- return 0;
+ return NET_RX_DROP;
iph = skb->nh.iph;
skb->ip_summed = 0;
@@ -372,7 +372,7 @@ inhdr_error:
IP_INC_STATS_BH(IpInHdrErrors);
drop:
kfree_skb(skb);
- return(0);
+ return NET_RX_DROP;
}
/*
@@ -429,6 +429,6 @@ inhdr_error:
drop:
kfree_skb(skb);
out:
- return(0);
+ return NET_RX_DROP;
}
diff --git a/net/ipv4/ip_nat_dumb.c b/net/ipv4/ip_nat_dumb.c
index b45377af4..88e3ff9e2 100644
--- a/net/ipv4/ip_nat_dumb.c
+++ b/net/ipv4/ip_nat_dumb.c
@@ -5,7 +5,7 @@
*
* Dumb Network Address Translation.
*
- * Version: $Id: ip_nat_dumb.c,v 1.9 1999/08/20 11:05:46 davem Exp $
+ * Version: $Id: ip_nat_dumb.c,v 1.10 2000/10/24 22:54:26 davem Exp $
*
* Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
*
@@ -152,8 +152,9 @@ ip_do_nat(struct sk_buff *skb)
break;
}
}
- return 0;
+ return NET_RX_SUCCESS;
truncated:
+ /* should be return NET_RX_BAD; */
return -EINVAL;
}
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 056767890..ce7618fe1 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -5,7 +5,7 @@
*
* The Internet Protocol (IP) output module.
*
- * Version: $Id: ip_output.c,v 1.85 2000/08/31 23:39:12 davem Exp $
+ * Version: $Id: ip_output.c,v 1.87 2000/10/25 20:07:22 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index a82e4be1f..f87921077 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -5,7 +5,7 @@
*
* The IP to API glue.
*
- * Version: $Id: ip_sockglue.c,v 1.52 2000/09/09 08:26:04 davem Exp $
+ * Version: $Id: ip_sockglue.c,v 1.53 2000/10/22 16:06:56 davem Exp $
*
* Authors: see ip.c
*
@@ -372,21 +372,23 @@ out:
/*
* Socket option code for IP. This is the end of the line after any TCP,UDP etc options on
* an IP socket.
- *
- * We implement IP_TOS (type of service), IP_TTL (time to live).
*/
int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int optlen)
{
int val=0,err;
- if (optname == IP_PKTINFO || optname == IP_RECVTTL ||
- optname == IP_RECVTOS || optname == IP_RECVOPTS ||
- optname == IP_RETOPTS || optname == IP_TOS ||
- optname == IP_TTL || optname == IP_HDRINCL ||
- optname == IP_MTU_DISCOVER || optname == IP_RECVERR ||
- optname == IP_MULTICAST_TTL || optname == IP_MULTICAST_LOOP ||
- optname == IP_ROUTER_ALERT) {
+ if (level != SOL_IP)
+ return -ENOPROTOOPT;
+
+ if (((1<<optname) & ((1<<IP_PKTINFO) | (1<<IP_RECVTTL) |
+ (1<<IP_RECVOPTS) | (1<<IP_RECVTOS) |
+ (1<<IP_RETOPTS) | (1<<IP_TOS) |
+ (1<<IP_TTL) | (1<<IP_HDRINCL) |
+ (1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) |
+ (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND))) ||
+ optname == IP_MULTICAST_TTL ||
+ optname == IP_MULTICAST_LOOP) {
if (optlen >= sizeof(int)) {
if (get_user(val, (int *) optval))
return -EFAULT;
@@ -400,9 +402,6 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int opt
}
/* If optlen==0, it is equivalent to val == 0 */
-
- if (level != SOL_IP)
- return -ENOPROTOOPT;
#ifdef CONFIG_IP_MROUTE
if (optname >= MRT_BASE && optname <= (MRT_BASE + 10))
@@ -612,6 +611,12 @@ int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int opt
case IP_ROUTER_ALERT:
err = ip_ra_control(sk, val ? 1 : 0, NULL);
break;
+
+ case IP_FREEBIND:
+ if (optlen<1)
+ goto e_inval;
+ sk->protinfo.af_inet.freebind = !!val;
+ break;
default:
#ifdef CONFIG_NETFILTER
@@ -771,6 +776,9 @@ int ip_getsockopt(struct sock *sk, int level, int optname, char *optval, int *op
len -= msg.msg_controllen;
return put_user(len, optlen);
}
+ case IP_FREEBIND:
+ val = sk->protinfo.af_inet.freebind;
+ break;
default:
#ifdef CONFIG_NETFILTER
val = nf_getsockopt(sk, PF_INET, optname, optval,
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index eae29c0b0..a8cb239a8 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -1,7 +1,7 @@
/*
* Linux NET3: IP/IP protocol decoder.
*
- * Version: $Id: ipip.c,v 1.39 2000/08/25 02:15:47 davem Exp $
+ * Version: $Id: ipip.c,v 1.40 2000/10/28 17:19:25 davem Exp $
*
* Authors:
* Sam Lantinga (slouken@cs.ucdavis.edu) 02/01/95
@@ -894,7 +894,9 @@ int __init ipip_init(void)
#ifdef MODULE
register_netdev(&ipip_fb_tunnel_dev);
#else
+ rtnl_lock();
register_netdevice(&ipip_fb_tunnel_dev);
+ rtnl_unlock();
#endif
inet_add_protocol(&ipip_protocol);
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index 10d09a6bd..e5fbe41af 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -72,7 +72,7 @@ ip_nat_fn(unsigned int hooknum,
unreliable. */
if (!ct) {
if (net_ratelimit())
- printk("NAT: %u dropping untracked packet %p %u %u.%u.%u.%u -> %u.%u.%u.%u\n",
+ printk(KERN_DEBUG "NAT: %u dropping untracked packet %p %u %u.%u.%u.%u -> %u.%u.%u.%u\n",
hooknum,
*pskb,
(*pskb)->nh.iph->protocol,
diff --git a/net/ipv4/protocol.c b/net/ipv4/protocol.c
index db57fedb9..cacd7a3f8 100644
--- a/net/ipv4/protocol.c
+++ b/net/ipv4/protocol.c
@@ -5,7 +5,7 @@
*
* INET protocol dispatch tables.
*
- * Version: $Id: protocol.c,v 1.11 2000/02/22 23:54:26 davem Exp $
+ * Version: $Id: protocol.c,v 1.12 2000/10/03 07:29:00 anton Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 81f20361a..675154d91 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -5,7 +5,7 @@
*
* RAW - implementation of IP "raw" sockets.
*
- * Version: $Id: raw.c,v 1.53 2000/08/09 11:59:04 davem Exp $
+ * Version: $Id: raw.c,v 1.55 2000/10/24 22:54:26 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -227,11 +227,11 @@ static int raw_rcv_skb(struct sock * sk, struct sk_buff * skb)
{
IP_INC_STATS(IpInDiscards);
kfree_skb(skb);
- return -1;
+ return NET_RX_DROP;
}
IP_INC_STATS(IpInDelivers);
- return 0;
+ return NET_RX_SUCCESS;
}
/*
@@ -653,7 +653,7 @@ int raw_get_info(char *buffer, char **start, off_t offset, int length)
if (sk->family != PF_INET)
continue;
pos += 128;
- if (pos < offset)
+ if (pos <= offset)
continue;
get_raw_sock(sk, tmpbuf, i);
len += sprintf(buffer+len, "%-127s\n", tmpbuf);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 4734d8087..cacf36b71 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -5,7 +5,7 @@
*
* ROUTE - implementation of the IP router.
*
- * Version: $Id: route.c,v 1.90 2000/08/31 23:39:12 davem Exp $
+ * Version: $Id: route.c,v 1.91 2000/10/03 07:29:00 anton Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index d9f05c671..68d536e10 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -1,7 +1,7 @@
/*
* sysctl_net_ipv4.c: sysctl interface to net IPV4 subsystem.
*
- * $Id: sysctl_net_ipv4.c,v 1.46 2000/09/16 09:38:30 davem Exp $
+ * $Id: sysctl_net_ipv4.c,v 1.47 2000/10/19 15:51:02 davem Exp $
*
* Begun April 1, 1996, Mike Shaver.
* Added /proc/sys/net/ipv4 directory entry (empty =) ). [MS]
@@ -15,6 +15,9 @@
#include <net/route.h>
#include <net/tcp.h>
+/* From af_inet.c */
+extern int sysctl_ip_nonlocal_bind;
+
/* From icmp.c */
extern int sysctl_icmp_echo_ignore_all;
extern int sysctl_icmp_echo_ignore_broadcasts;
@@ -110,6 +113,9 @@ ctl_table ipv4_table[] = {
{NET_IPV4_NO_PMTU_DISC, "ip_no_pmtu_disc",
&ipv4_config.no_pmtu_disc, sizeof(int), 0644, NULL,
&proc_dointvec},
+ {NET_IPV4_NONLOCAL_BIND, "ip_nonlocal_bind",
+ &sysctl_ip_nonlocal_bind, sizeof(int), 0644, NULL,
+ &proc_dointvec},
{NET_IPV4_TCP_SYN_RETRIES, "tcp_syn_retries",
&sysctl_tcp_syn_retries, sizeof(int), 0644, NULL, &proc_dointvec},
{NET_TCP_SYNACK_RETRIES, "tcp_synack_retries",
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 05027bc93..0f97c2d27 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -5,7 +5,7 @@
*
* Implementation of the Transmission Control Protocol(TCP).
*
- * Version: $Id: tcp.c,v 1.174 2000/09/18 05:59:48 davem Exp $
+ * Version: $Id: tcp.c,v 1.176 2000/10/06 22:45:41 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -1026,7 +1026,7 @@ int tcp_sendmsg(struct sock *sk, struct msghdr *msg, int size)
skb = NULL;
if (tcp_memory_free(sk))
- skb = tcp_alloc_skb(sk, tmp, GFP_KERNEL);
+ skb = tcp_alloc_skb(sk, tmp, sk->allocation);
if (skb == NULL) {
/* If we didn't get any memory, we need to sleep. */
set_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags);
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index d2a79b4b1..1a0f278b4 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -5,7 +5,7 @@
*
* Implementation of the Transmission Control Protocol(TCP).
*
- * Version: $Id: tcp_ipv4.c,v 1.213 2000/09/18 05:59:48 davem Exp $
+ * Version: $Id: tcp_ipv4.c,v 1.218 2000/10/18 18:04:22 davem Exp $
*
* IPv4 specific functions
*
@@ -75,37 +75,21 @@ static struct socket *tcp_socket=&tcp_inode.u.socket_i;
void tcp_v4_send_check(struct sock *sk, struct tcphdr *th, int len,
struct sk_buff *skb);
-/* This is for sockets with full identity only. Sockets here will always
- * be without wildcards and will have the following invariant:
- * TCP_ESTABLISHED <= sk->state < TCP_CLOSE
- *
- * First half of the table is for sockets not in TIME_WAIT, second half
- * is for TIME_WAIT sockets only.
- */
-struct tcp_ehash_bucket *tcp_ehash;
-
-/* Ok, let's try this, I give up, we do need a local binding
- * TCP hash as well as the others for fast bind/connect.
- */
-struct tcp_bind_hashbucket *tcp_bhash;
-
-int tcp_bhash_size;
-int tcp_ehash_size;
-
-/* All sockets in TCP_LISTEN state will be in here. This is the only table
- * where wildcard'd TCP sockets can exist. Hash function here is just local
- * port number.
+/*
+ * ALL members must be initialised to prevent gcc-2.7.2.3 miscompilation
*/
-struct sock *tcp_listening_hash[TCP_LHTABLE_SIZE];
-char __tcp_clean_cacheline_pad[(SMP_CACHE_BYTES -
- (((sizeof(void *) * (TCP_LHTABLE_SIZE + 2)) +
- (sizeof(int) * 2)) % SMP_CACHE_BYTES))] = { 0, };
-
-rwlock_t tcp_lhash_lock = RW_LOCK_UNLOCKED;
-atomic_t tcp_lhash_users = ATOMIC_INIT(0);
-DECLARE_WAIT_QUEUE_HEAD(tcp_lhash_wait);
-
-spinlock_t tcp_portalloc_lock = SPIN_LOCK_UNLOCKED;
+struct tcp_hashinfo __cacheline_aligned tcp_hashinfo = {
+ __tcp_ehash: NULL,
+ __tcp_bhash: NULL,
+ __tcp_bhash_size: 0,
+ __tcp_ehash_size: 0,
+ __tcp_listening_hash: { NULL, },
+ __tcp_lhash_lock: RW_LOCK_UNLOCKED,
+ __tcp_lhash_users: ATOMIC_INIT(0),
+ __tcp_lhash_wait:
+ __WAIT_QUEUE_HEAD_INITIALIZER(tcp_hashinfo.__tcp_lhash_wait),
+ __tcp_portalloc_lock: SPIN_LOCK_UNLOCKED
+};
/*
* This array holds the first and last local port number.
@@ -2113,7 +2097,7 @@ skip_listen:
continue;
pos += TMPSZ;
- if (pos < offset)
+ if (pos <= offset)
continue;
get_openreq(sk, req, tmpbuf, num, uid);
len += sprintf(buffer+len, "%-*s\n", TMPSZ-1, tmpbuf);
@@ -2145,7 +2129,7 @@ skip_listen:
if (!TCP_INET_FAMILY(sk->family))
continue;
pos += TMPSZ;
- if (pos < offset)
+ if (pos <= offset)
continue;
get_tcp_sock(sk, tmpbuf, num);
len += sprintf(buffer+len, "%-*s\n", TMPSZ-1, tmpbuf);
@@ -2160,7 +2144,7 @@ skip_listen:
if (!TCP_INET_FAMILY(tw->family))
continue;
pos += TMPSZ;
- if (pos < offset)
+ if (pos <= offset)
continue;
get_timewait_sock(tw, tmpbuf, num);
len += sprintf(buffer+len, "%-*s\n", TMPSZ-1, tmpbuf);
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 8dca4474b..7b6f45428 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -5,7 +5,7 @@
*
* Implementation of the Transmission Control Protocol(TCP).
*
- * Version: $Id: tcp_output.c,v 1.127 2000/08/15 20:15:23 davem Exp $
+ * Version: $Id: tcp_output.c,v 1.128 2000/10/29 01:51:09 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -318,7 +318,7 @@ void tcp_send_skb(struct sock *sk, struct sk_buff *skb, int force_queue, unsigne
if (!force_queue && tp->send_head == NULL && tcp_snd_test(tp, skb, cur_mss, 1)) {
/* Send it out now. */
TCP_SKB_CB(skb)->when = tcp_time_stamp;
- if (tcp_transmit_skb(sk, skb_clone(skb, GFP_KERNEL)) == 0) {
+ if (tcp_transmit_skb(sk, skb_clone(skb, sk->allocation)) == 0) {
tp->snd_nxt = TCP_SKB_CB(skb)->end_seq;
tcp_minshall_update(tp, cur_mss, skb);
if (tp->packets_out++ == 0)
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index 5e5af83c2..f57aeb32e 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -5,7 +5,7 @@
*
* Implementation of the Transmission Control Protocol(TCP).
*
- * Version: $Id: tcp_timer.c,v 1.79 2000/08/11 00:13:36 davem Exp $
+ * Version: $Id: tcp_timer.c,v 1.80 2000/10/03 07:29:01 anton Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index ff8a3d109..e098b9ff2 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -5,7 +5,7 @@
*
* The User Datagram Protocol (UDP).
*
- * Version: $Id: udp.c,v 1.87 2000/09/20 02:11:34 davem Exp $
+ * Version: $Id: udp.c,v 1.90 2000/10/18 18:04:22 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -677,8 +677,6 @@ int udp_recvmsg(struct sock *sk, struct msghdr *msg, int len,
if (flags & MSG_ERRQUEUE)
return ip_recv_error(sk, msg, len);
-
- retry:
/*
* From here the generic datagram does a lot of the work. Come
* the finished NET3, it will do _ALL_ the work!
@@ -734,21 +732,22 @@ out:
csum_copy_err:
UDP_INC_STATS_BH(UdpInErrors);
- if (flags&(MSG_PEEK|MSG_DONTWAIT)) {
- struct sk_buff *skb2;
-
+ /* Clear queue. */
+ if (flags&MSG_PEEK) {
+ int clear = 0;
spin_lock_irq(&sk->receive_queue.lock);
- skb2 = skb_peek(&sk->receive_queue);
- if ((flags & MSG_PEEK) && skb == skb2) {
+ if (skb == skb_peek(&sk->receive_queue)) {
__skb_unlink(skb, &sk->receive_queue);
+ clear = 1;
}
spin_unlock_irq(&sk->receive_queue.lock);
- skb_free_datagram(sk, skb);
- if ((flags & MSG_DONTWAIT) && !skb2)
- return -EAGAIN;
- } else
- skb_free_datagram(sk, skb);
- goto retry;
+ if (clear)
+ kfree_skb(skb);
+ }
+
+ skb_free_datagram(sk, skb);
+
+ return -EAGAIN;
}
int udp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
@@ -1029,7 +1028,7 @@ int udp_get_info(char *buffer, char **start, off_t offset, int length)
if (sk->family != PF_INET)
continue;
pos += 128;
- if (pos < offset)
+ if (pos <= offset)
continue;
get_udp_sock(sk, tmpbuf, i);
len += sprintf(buffer+len, "%-127s\n", tmpbuf);
diff --git a/net/ipv4/utils.c b/net/ipv4/utils.c
index c6494d87f..a5a9c3873 100644
--- a/net/ipv4/utils.c
+++ b/net/ipv4/utils.c
@@ -6,7 +6,7 @@
* Various kernel-resident INET utility functions; mainly
* for format conversion and debugging output.
*
- * Version: $Id: utils.c,v 1.7 1999/06/09 10:11:05 davem Exp $
+ * Version: $Id: utils.c,v 1.8 2000/10/03 07:29:01 anton Exp $
*
* Author: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
*
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 869cac689..c243a6ec9 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -7,7 +7,7 @@
*
* Adapted from linux/net/ipv4/af_inet.c
*
- * $Id: af_inet6.c,v 1.58 2000/09/18 05:59:48 davem Exp $
+ * $Id: af_inet6.c,v 1.60 2000/10/19 01:05:34 davem Exp $
*
* Fixes:
* Hideaki YOSHIFUJI : sin6_scope_id support
@@ -502,11 +502,7 @@ extern void ipv6_sysctl_register(void);
extern void ipv6_sysctl_unregister(void);
#endif
-#ifdef MODULE
-int init_module(void)
-#else
-void __init inet6_proto_init(struct net_proto *pro)
-#endif
+static int __init inet6_init(void)
{
struct sk_buff *dummy_skb;
int err;
@@ -523,11 +519,7 @@ void __init inet6_proto_init(struct net_proto *pro)
if (sizeof(struct inet6_skb_parm) > sizeof(dummy_skb->cb))
{
printk(KERN_CRIT "inet6_proto_init: size fault\n");
-#ifdef MODULE
return -EINVAL;
-#else
- return;
-#endif
}
/*
@@ -577,11 +569,7 @@ void __init inet6_proto_init(struct net_proto *pro)
/* Now the userspace is allowed to create INET6 sockets. */
(void) sock_register(&inet6_family_ops);
-#ifdef MODULE
return 0;
-#else
- return;
-#endif
#ifdef CONFIG_PROC_FS
proc_snmp6_fail:
@@ -603,15 +591,13 @@ icmp_fail:
#if defined(MODULE) && defined(CONFIG_SYSCTL)
ipv6_sysctl_unregister();
#endif
-#ifdef MODULE
return err;
-#else
- return;
-#endif
}
+module_init(inet6_init);
+
#ifdef MODULE
-void cleanup_module(void)
+static void inet6_exit(void)
{
/* First of all disallow new sockets creation. */
sock_unregister(PF_INET6);
@@ -636,4 +622,5 @@ void cleanup_module(void)
ipv6_sysctl_unregister();
#endif
}
-#endif /* MODULE */
+module_exit(inet6_exit);
+#endif /* MODULE */
diff --git a/net/ipv6/protocol.c b/net/ipv6/protocol.c
index 43ac35004..df1e9324f 100644
--- a/net/ipv6/protocol.c
+++ b/net/ipv6/protocol.c
@@ -5,7 +5,7 @@
*
* PF_INET6 protocol dispatch tables.
*
- * Version: $Id: protocol.c,v 1.8 2000/02/22 23:54:29 davem Exp $
+ * Version: $Id: protocol.c,v 1.9 2000/10/03 07:29:01 anton Exp $
*
* Authors: Pedro Roque <roque@di.fc.ul.pt>
*
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 0b7e00252..43ef2e87d 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -7,7 +7,7 @@
*
* Adapted from linux/net/ipv4/raw.c
*
- * $Id: raw.c,v 1.40 2000/08/09 11:59:04 davem Exp $
+ * $Id: raw.c,v 1.41 2000/10/18 18:04:23 davem Exp $
*
* Fixes:
* Hideaki YOSHIFUJI : sin6_scope_id support
@@ -793,7 +793,7 @@ int raw6_get_info(char *buffer, char **start, off_t offset, int length)
if (sk->family != PF_INET6)
continue;
pos += LINE_LEN+1;
- if (pos < offset)
+ if (pos <= offset)
continue;
get_raw6_sock(sk, tmpbuf, i);
len += sprintf(buffer+len, LINE_FMT, tmpbuf);
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 59048a22b..f263a3197 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -6,7 +6,7 @@
* Pedro Roque <roque@di.fc.ul.pt>
* Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
*
- * $Id: sit.c,v 1.43 2000/08/25 02:15:47 davem Exp $
+ * $Id: sit.c,v 1.45 2000/10/28 17:19:25 davem Exp $
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -188,7 +188,7 @@ struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int create)
}
if (i==100)
goto failed;
- memcpy(parms->name, dev->name, IFNAMSIZ);
+ memcpy(nt->parms.name, dev->name, IFNAMSIZ);
}
if (register_netdevice(dev) < 0)
goto failed;
@@ -829,7 +829,9 @@ int __init sit_init(void)
#ifdef MODULE
register_netdev(&ipip6_fb_tunnel_dev);
#else
+ rtnl_lock();
register_netdevice(&ipip6_fb_tunnel_dev);
+ rtnl_unlock();
#endif
inet_add_protocol(&sit_protocol);
return 0;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 952e24765..b830884e8 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -5,7 +5,7 @@
* Authors:
* Pedro Roque <roque@di.fc.ul.pt>
*
- * $Id: tcp_ipv6.c,v 1.125 2000/08/09 11:59:04 davem Exp $
+ * $Id: tcp_ipv6.c,v 1.126 2000/10/18 18:04:23 davem Exp $
*
* Based on:
* linux/net/ipv4/tcp.c
@@ -2009,7 +2009,7 @@ int tcp6_get_info(char *buffer, char **start, off_t offset, int length)
if (req->class->family != PF_INET6)
continue;
pos += LINE_LEN+1;
- if (pos < offset)
+ if (pos <= offset)
continue;
get_openreq6(sk, req, tmpbuf, num, uid);
len += sprintf(buffer+len, LINE_FMT, tmpbuf);
@@ -2041,7 +2041,7 @@ int tcp6_get_info(char *buffer, char **start, off_t offset, int length)
if (sk->family != PF_INET6)
continue;
pos += LINE_LEN+1;
- if (pos < offset)
+ if (pos <= offset)
continue;
get_tcp6_sock(sk, tmpbuf, num);
len += sprintf(buffer+len, LINE_FMT, tmpbuf);
@@ -2056,7 +2056,7 @@ int tcp6_get_info(char *buffer, char **start, off_t offset, int length)
if (tw->family != PF_INET6)
continue;
pos += LINE_LEN+1;
- if (pos < offset)
+ if (pos <= offset)
continue;
get_timewait6_sock(tw, tmpbuf, num);
len += sprintf(buffer+len, LINE_FMT, tmpbuf);
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 4d95aa40b..187db4414 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -7,7 +7,7 @@
*
* Based on linux/ipv4/udp.c
*
- * $Id: udp.c,v 1.57 2000/09/18 05:59:48 davem Exp $
+ * $Id: udp.c,v 1.58 2000/10/18 18:04:23 davem Exp $
*
* Fixes:
* Hideaki YOSHIFUJI : sin6_scope_id support
@@ -956,7 +956,7 @@ int udp6_get_info(char *buffer, char **start, off_t offset, int length)
if (sk->family != PF_INET6)
continue;
pos += LINE_LEN+1;
- if (pos < offset)
+ if (pos <= offset)
continue;
get_udp6_sock(sk, tmpbuf, i);
len += sprintf(buffer+len, LINE_FMT, tmpbuf);
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
index bbb2b2630..2fc3ea46c 100644
--- a/net/ipx/af_ipx.c
+++ b/net/ipx/af_ipx.c
@@ -2387,9 +2387,8 @@ static unsigned char ipx_snap_id[5] = { 0x0, 0x0, 0x0, 0x81, 0x37 };
-/* Called by protocols.c on kernel start up */
-void ipx_proto_init(struct net_proto *pro)
+static int __init ipx_init(void)
{
(void) sock_register(&ipx_family_ops);
@@ -2415,7 +2414,9 @@ void ipx_proto_init(struct net_proto *pro)
printk(KERN_INFO "NET4: Linux IPX 0.38 for NET4.0\n");
printk(KERN_INFO "IPX Portions Copyright (c) 1995 Caldera, Inc.\n");
+ return 0;
}
+module_init(ipx_init);
/* Higher layers need this info to prep tx pkts */
int ipx_if_offset(unsigned long ipx_net_number)
@@ -2434,7 +2435,6 @@ EXPORT_SYMBOL(ipx_remove_socket);
EXPORT_SYMBOL(ipx_register_spx);
EXPORT_SYMBOL(ipx_unregister_spx);
-#ifdef MODULE
/* Note on MOD_{INC,DEC}_USE_COUNT:
*
* Use counts are incremented/decremented when
@@ -2448,6 +2448,7 @@ EXPORT_SYMBOL(ipx_unregister_spx);
* sockets be closed from user space.
*/
+#ifdef MODULE
static void ipx_proto_finito(void)
{
ipx_interface *ifc;
@@ -2486,18 +2487,7 @@ static void ipx_proto_finito(void)
return;
}
-
-int init_module(void)
-{
- ipx_proto_init(NULL);
- return (0);
-}
-
-void cleanup_module(void)
-{
- ipx_proto_finito();
- return;
-}
-
+module_exit(ipx_proto_finito);
#endif /* MODULE */
+
#endif /* CONFIG_IPX || CONFIG_IPX_MODULE */
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
index 2ba86afcc..69db79a0e 100644
--- a/net/irda/af_irda.c
+++ b/net/irda/af_irda.c
@@ -43,10 +43,10 @@
********************************************************************/
#include <linux/config.h>
+#include <linux/init.h>
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/sockios.h>
-#include <linux/init.h>
#include <linux/if_arp.h>
#include <linux/net.h>
#include <linux/irda.h>
@@ -2155,17 +2155,19 @@ static struct notifier_block irda_dev_notifier = {
* Initialize IrDA protocol layer
*
*/
-void __init irda_proto_init(struct net_proto *pro)
+static int __init irda_proto_init(void)
{
- sock_register(&irda_family_ops);
-
- irda_packet_type.type = htons(ETH_P_IRDA);
+ sock_register(&irda_family_ops);
+
+ irda_packet_type.type = htons(ETH_P_IRDA);
dev_add_pack(&irda_packet_type);
-
- register_netdevice_notifier(&irda_dev_notifier);
-
- irda_init();
+
+ register_netdevice_notifier(&irda_dev_notifier);
+
+ irda_init();
+ return 0;
}
+module_init(irda_proto_init);
/*
* Function irda_proto_cleanup (void)
@@ -2186,4 +2188,5 @@ void irda_proto_cleanup(void)
return;
}
+module_exit(irda_proto_cleanup);
#endif /* MODULE */
diff --git a/net/irda/irmod.c b/net/irda/irmod.c
index fde6788c3..39257f87a 100644
--- a/net/irda/irmod.c
+++ b/net/irda/irmod.c
@@ -545,28 +545,6 @@ void irda_proc_modcount(struct inode *inode, int fill)
MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
MODULE_DESCRIPTION("The Linux IrDA Protocol Subsystem");
MODULE_PARM(irda_debug, "1l");
-
-/*
- * Function init_module (void)
- *
- * Initialize the irda module
- *
- */
-int init_module(void)
-{
- irda_proto_init(NULL);
-
- return 0;
-}
-
-/*
- * Function cleanup_module (void)
- *
- * Cleanup the irda module
- *
- */
-void cleanup_module(void)
-{
- irda_proto_cleanup();
-}
+module_exit(irda_proto_cleanup);
#endif /* MODULE */
+
diff --git a/net/lapb/lapb_iface.c b/net/lapb/lapb_iface.c
index 587304bca..bdc84d72f 100644
--- a/net/lapb/lapb_iface.c
+++ b/net/lapb/lapb_iface.c
@@ -401,25 +401,18 @@ EXPORT_SYMBOL(lapb_disconnect_request);
EXPORT_SYMBOL(lapb_data_request);
EXPORT_SYMBOL(lapb_data_received);
-void __init lapb_proto_init(struct net_proto *pro)
+static int __init lapb_init(void)
{
printk(KERN_INFO "NET4: LAPB for Linux. Version 0.01 for NET4.0\n");
+ return 0;
}
#ifdef MODULE
MODULE_AUTHOR("Jonathan Naylor <g4klx@g4klx.demon.co.uk>");
MODULE_DESCRIPTION("The X.25 Link Access Procedure B link layer protocol");
+#endif
-int init_module(void)
-{
- lapb_proto_init(NULL);
- return 0;
-}
-
-void cleanup_module(void)
-{
-}
-#endif
+module_init(lapb_init);
#endif
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index be011a234..3927d9c3a 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -15,6 +15,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/init.h>
#include <linux/major.h>
#include <linux/signal.h>
#include <linux/sched.h>
@@ -968,16 +969,19 @@ struct net_proto_family netlink_family_ops = {
netlink_create
};
-void netlink_proto_init(struct net_proto *pro)
+static int __init netlink_proto_init(void)
{
struct sk_buff *dummy_skb;
if (sizeof(struct netlink_skb_parms) > sizeof(dummy_skb->cb)) {
- printk(KERN_CRIT "netlink_proto_init: panic\n");
- return;
+ printk(KERN_CRIT "netlink_init: panic\n");
+ return -1;
}
sock_register(&netlink_family_ops);
#ifdef CONFIG_PROC_FS
create_proc_read_entry("net/netlink", 0, 0, netlink_read_proc, NULL);
#endif
+ return 0;
}
+
+module_init(netlink_proto_init);
diff --git a/net/netlink/netlink_dev.c b/net/netlink/netlink_dev.c
index bc1b378fc..da7598a79 100644
--- a/net/netlink/netlink_dev.c
+++ b/net/netlink/netlink_dev.c
@@ -31,7 +31,7 @@
#include <asm/system.h>
#include <asm/uaccess.h>
-static unsigned open_map = 0;
+static unsigned open_map;
static struct socket *netlink_user[MAX_LINKS];
/*
@@ -178,7 +178,7 @@ static struct file_operations netlink_fops = {
release: netlink_release,
};
-static devfs_handle_t devfs_handle = NULL;
+static devfs_handle_t devfs_handle;
static void __init make_devfs_entries (const char *name, int minor)
{
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index 27d95703b..a0c139b3a 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -1261,13 +1261,13 @@ static struct notifier_block nr_dev_notifier = {
static struct net_device *dev_nr;
-void __init nr_proto_init(struct net_proto *pro)
+static int __init nr_proto_init(void)
{
int i;
if ((dev_nr = kmalloc(nr_ndevs * sizeof(struct net_device), GFP_KERNEL)) == NULL) {
printk(KERN_ERR "NET/ROM: nr_proto_init - unable to allocate device structure\n");
- return;
+ return -1;
}
memset(dev_nr, 0x00, nr_ndevs * sizeof(struct net_device));
@@ -1296,8 +1296,12 @@ void __init nr_proto_init(struct net_proto *pro)
proc_net_create("nr_neigh", 0, nr_neigh_get_info);
proc_net_create("nr_nodes", 0, nr_nodes_get_info);
#endif
+ return 0;
}
+module_init(nr_proto_init);
+
+
#ifdef MODULE
EXPORT_NO_SYMBOLS;
@@ -1307,14 +1311,7 @@ MODULE_PARM_DESC(nr_ndevs, "number of NET/ROM devices");
MODULE_AUTHOR("Jonathan Naylor G4KLX <g4klx@g4klx.demon.co.uk>");
MODULE_DESCRIPTION("The amateur radio NET/ROM network and transport layer protocol");
-int init_module(void)
-{
- nr_proto_init(NULL);
-
- return 0;
-}
-
-void cleanup_module(void)
+static void nr_exit(void)
{
int i;
@@ -1348,7 +1345,9 @@ void cleanup_module(void)
kfree(dev_nr);
}
+module_exit(nr_exit);
+#endif /* MODULE */
+
-#endif
#endif
diff --git a/net/netsyms.c b/net/netsyms.c
index 8579c5b2f..ebe3bbe81 100644
--- a/net/netsyms.c
+++ b/net/netsyms.c
@@ -30,6 +30,9 @@
#include <net/scm.h>
#include <linux/if_bridge.h>
#include <linux/random.h>
+#ifdef CONFIG_NET_DIVERT
+#include <linux/divert.h>
+#endif /* CONFIG_NET_DIVERT */
#ifdef CONFIG_NET
extern __u32 sysctl_wmem_max;
@@ -207,6 +210,12 @@ EXPORT_SYMBOL(br_ioctl_hook);
#endif
#endif
+#ifdef CONFIG_NET_DIVERT
+EXPORT_SYMBOL(alloc_divert_blk);
+EXPORT_SYMBOL(free_divert_blk);
+EXPORT_SYMBOL(divert_ioctl);
+#endif /* CONFIG_NET_DIVERT */
+
#ifdef CONFIG_INET
/* Internet layer registration */
EXPORT_SYMBOL(inetdev_lock);
@@ -276,16 +285,8 @@ EXPORT_SYMBOL(inet_sock_destruct);
EXPORT_SYMBOL(inet_sock_release);
/* Socket demultiplexing. */
-EXPORT_SYMBOL(tcp_ehash);
-EXPORT_SYMBOL(tcp_ehash_size);
-EXPORT_SYMBOL(tcp_listening_hash);
-EXPORT_SYMBOL(tcp_lhash_lock);
-EXPORT_SYMBOL(tcp_lhash_users);
-EXPORT_SYMBOL(tcp_lhash_wait);
+EXPORT_SYMBOL(tcp_hashinfo);
EXPORT_SYMBOL(tcp_listen_wlock);
-EXPORT_SYMBOL(tcp_bhash);
-EXPORT_SYMBOL(tcp_bhash_size);
-EXPORT_SYMBOL(tcp_portalloc_lock);
EXPORT_SYMBOL(udp_hash);
EXPORT_SYMBOL(udp_hash_lock);
@@ -490,6 +491,7 @@ EXPORT_SYMBOL(dev_load);
EXPORT_SYMBOL(dev_ioctl);
EXPORT_SYMBOL(dev_queue_xmit);
#ifdef CONFIG_NET_HW_FLOWCONTROL
+EXPORT_SYMBOL(netdev_dropping);
EXPORT_SYMBOL(netdev_register_fc);
EXPORT_SYMBOL(netdev_unregister_fc);
EXPORT_SYMBOL(netdev_fc_xoff);
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index b7827f09f..6b4c77854 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -5,7 +5,7 @@
*
* PACKET - implements raw packet sockets.
*
- * Version: $Id: af_packet.c,v 1.42 2000/08/29 03:44:56 davem Exp $
+ * Version: $Id: af_packet.c,v 1.46 2000/10/24 21:26:19 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -33,6 +33,7 @@
* Alan Cox : Protocol setting support
* Alexey Kuznetsov : Untied from IPv4 stack.
* Cyrus Durgin : Fixed kerneld for kmod.
+ * Michal Ostrowski : Module initialization cleanup.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -67,6 +68,10 @@
#include <linux/init.h>
#include <linux/if_bridge.h>
+#ifdef CONFIG_NET_DIVERT
+#include <linux/divert.h>
+#endif /* CONFIG_NET_DIVERT */
+
#ifdef CONFIG_INET
#include <net/inet_common.h>
#endif
@@ -1484,6 +1489,14 @@ static int packet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg
#endif
#endif
+ case SIOCGIFDIVERT:
+ case SIOCSIFDIVERT:
+#ifdef CONFIG_NET_DIVERT
+ return(divert_ioctl(cmd, (struct divert_cf *) arg));
+#else
+ return -ENOPKG;
+#endif /* CONFIG_NET_DIVERT */
+
return -ENOPKG;
#ifdef CONFIG_INET
@@ -1860,8 +1873,8 @@ done:
#endif
-#ifdef MODULE
-void cleanup_module(void)
+
+static void __exit packet_exit(void)
{
#ifdef CONFIG_PROC_FS
remove_proc_entry("net/packet", 0);
@@ -1872,17 +1885,16 @@ void cleanup_module(void)
}
-int init_module(void)
-#else
-void __init packet_proto_init(struct net_proto *pro)
-#endif
+static int __init packet_init(void)
{
sock_register(&packet_family_ops);
register_netdevice_notifier(&packet_netdev_notifier);
#ifdef CONFIG_PROC_FS
create_proc_read_entry("net/packet", 0, 0, packet_read_proc, NULL);
#endif
-#ifdef MODULE
return 0;
-#endif
}
+
+
+module_init(packet_init);
+module_exit(packet_exit);
diff --git a/net/protocols.c b/net/protocols.c
deleted file mode 100644
index 7de6a3bcb..000000000
--- a/net/protocols.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Protocol initializer table. Here separately for convenience
- *
- */
-
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/net.h>
-#include <linux/fs.h>
-
-#ifdef CONFIG_UNIX
-#include <linux/un.h>
-#include <net/af_unix.h>
-#endif
-
-#ifdef CONFIG_INET
-#include <linux/inet.h>
-#ifdef CONFIG_IPV6
-extern void inet6_proto_init(struct net_proto *pro);
-#endif
-#endif /* INET */
-
-#ifdef CONFIG_ECONET
-extern void econet_proto_init(struct net_proto *pro);
-#endif
-
-#ifdef CONFIG_NETLINK
-extern void netlink_proto_init(struct net_proto *pro);
-#endif
-
-#ifdef CONFIG_PACKET
-extern void packet_proto_init(struct net_proto *pro);
-#endif
-
-#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE)
-#define NEED_802
-#include <net/ipxcall.h>
-#endif
-
-#ifdef CONFIG_X25
-#include <net/x25call.h>
-#endif
-
-#ifdef CONFIG_LAPB
-#include <net/lapbcall.h>
-#endif
-
-#ifdef CONFIG_AX25
-#include <net/ax25call.h>
-#ifdef CONFIG_NETROM
-#include <net/nrcall.h>
-#endif
-#ifdef CONFIG_ROSE
-#include <net/rosecall.h>
-#endif
-#endif
-
-#ifdef CONFIG_IRDA
-#include <net/irda/irdacall.h>
-#endif
-
-#if defined(CONFIG_DECNET)
-#include <net/decnet_call.h>
-#endif
-
-#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE)
-#define NEED_802
-#include <net/atalkcall.h>
-#endif
-
-#if defined(CONFIG_NETBEUI)
-#define NEED_LLC
-#include <net/netbeuicall.h>
-#endif
-
-#if defined(CONFIG_LLC)
-#define NEED_LLC
-#endif
-
-#include <net/psnapcall.h>
-
-#ifdef CONFIG_TR
-#include <linux/netdevice.h>
-#include <linux/trdevice.h>
-extern void rif_init(struct net_proto *);
-#endif
-
-#ifdef CONFIG_ATM
-#include <linux/atm.h>
-#endif
-
-#ifdef NEED_LLC
-#define NEED_802
-#include <net/llccall.h>
-#endif
-
-#ifdef NEED_802
-#include <net/p8022call.h>
-#endif
-
-
-#ifdef CONFIG_PPPOE
-#include <linux/if_pppox.h>
-#endif
-
-/*
- * Protocol Table
- */
-
-struct net_proto protocols[] = {
-#ifdef CONFIG_NETLINK
- { "NETLINK", netlink_proto_init },
-#endif
-
-#ifdef CONFIG_PACKET
- { "PACKET", packet_proto_init },
-#endif
-
-#ifdef CONFIG_UNIX
- { "UNIX", unix_proto_init }, /* Unix domain socket family */
-#endif
-
-#ifdef NEED_802
- { "802.2", p8022_proto_init }, /* 802.2 demultiplexor */
- { "SNAP", snap_proto_init }, /* SNAP demultiplexor */
-#endif
-
-#ifdef CONFIG_TR
- { "RIF", rif_init }, /* RIF for Token ring */
-#endif
-
-#ifdef CONFIG_ATM
- { "ATMPVC", atmpvc_proto_init }, /* ATM PVCs */
- { "ATMSVC", atmsvc_proto_init }, /* ATM SVCs */
-#endif
-
-#ifdef NEED_LLC
- { "802.2LLC", llc_init }, /* 802.2 LLC */
-#endif
-
-#ifdef CONFIG_AX25
- { "AX.25", ax25_proto_init }, /* Amateur Radio AX.25 */
-#ifdef CONFIG_NETROM
- { "NET/ROM", nr_proto_init }, /* Amateur Radio NET/ROM */
-#endif
-#ifdef CONFIG_ROSE
- { "Rose", rose_proto_init }, /* Amateur Radio X.25 PLP */
-#endif
-#endif
-#ifdef CONFIG_DECNET
- { "DECnet", decnet_proto_init }, /* DECnet */
-#endif
-#ifdef CONFIG_INET
- { "INET", inet_proto_init }, /* TCP/IP */
-#ifdef CONFIG_IPV6
- { "INET6", inet6_proto_init}, /* IPv6 */
-#endif
-#endif
-
-#ifdef CONFIG_IPX
- { "IPX", ipx_proto_init }, /* IPX */
-#endif
-
-#ifdef CONFIG_ATALK
- { "DDP", atalk_proto_init }, /* Netatalk Appletalk driver */
-#endif
-
-#ifdef CONFIG_LAPB
- { "LAPB", lapb_proto_init }, /* LAPB protocols */
-#endif
-
-#ifdef CONFIG_X25
- { "X.25", x25_proto_init }, /* CCITT X.25 Packet Layer */
-#endif
-
-#ifdef CONFIG_ECONET
- { "Econet", econet_proto_init }, /* Acorn Econet */
-#endif
-
-#ifdef CONFIG_IRDA
- { "IrDA", irda_proto_init }, /* IrDA protocols */
-#endif
-#ifdef CONFIG_PPPOE
- { "PPPoX", pppox_proto_init }, /* PPP over Ethernet */
-#endif
- { NULL, NULL } /* End marker */
-};
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index f61d9cd34..f639e578a 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -27,6 +27,7 @@
#include <linux/config.h>
#if defined(CONFIG_ROSE) || defined(CONFIG_ROSE_MODULE)
#include <linux/module.h>
+#include <linux/init.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
@@ -56,7 +57,6 @@
#include <linux/proc_fs.h>
#include <net/ip.h>
#include <net/arp.h>
-#include <linux/init.h>
int rose_ndevs = 10;
@@ -1427,7 +1427,7 @@ static struct notifier_block rose_dev_notifier = {
static struct net_device *dev_rose;
-void __init rose_proto_init(struct net_proto *pro)
+static int __init rose_proto_init(void)
{
int i;
@@ -1435,7 +1435,7 @@ void __init rose_proto_init(struct net_proto *pro)
if ((dev_rose = kmalloc(rose_ndevs * sizeof(struct net_device), GFP_KERNEL)) == NULL) {
printk(KERN_ERR "ROSE: rose_proto_init - unable to allocate device structure\n");
- return;
+ return -1;
}
memset(dev_rose, 0x00, rose_ndevs * sizeof(struct net_device));
@@ -1466,7 +1466,9 @@ void __init rose_proto_init(struct net_proto *pro)
proc_net_create("rose_nodes", 0, rose_nodes_get_info);
proc_net_create("rose_routes", 0, rose_routes_get_info);
#endif
+ return 0;
}
+module_init(rose_proto_init);
#ifdef MODULE
EXPORT_NO_SYMBOLS;
@@ -1477,14 +1479,7 @@ MODULE_PARM_DESC(rose_ndevs, "number of ROSE devices");
MODULE_AUTHOR("Jonathan Naylor G4KLX <g4klx@g4klx.demon.co.uk>");
MODULE_DESCRIPTION("The amateur radio ROSE network layer protocol");
-int init_module(void)
-{
- rose_proto_init(NULL);
-
- return 0;
-}
-
-void cleanup_module(void)
+static void __exit rose_exit(void)
{
int i;
@@ -1522,7 +1517,8 @@ void cleanup_module(void)
kfree(dev_rose);
}
+module_exit(rose_exit);
+#endif /* MODULE */
-#endif
#endif
diff --git a/net/socket.c b/net/socket.c
index 9fdc84fb5..58df6d92e 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1490,7 +1490,7 @@ out:
/*
* Perform a file control on a socket file descriptor.
*
- * Doesn't aquire a fd lock, because no network fcntl
+ * Doesn't acquire a fd lock, because no network fcntl
* function sleeps currently.
*/
@@ -1638,27 +1638,9 @@ int sock_unregister(int family)
return 0;
}
-void __init proto_init(void)
-{
- extern struct net_proto protocols[]; /* Network protocols */
- struct net_proto *pro;
-
- /* Kick all configured protocols. */
- pro = protocols;
- while (pro->name != NULL)
- {
- (*pro->init_func)(pro);
- pro++;
- }
- /* We're all done... */
-}
extern void sk_init(void);
-#ifdef CONFIG_BRIDGE
-extern int br_init(void);
-#endif
-
#ifdef CONFIG_WAN_ROUTER
extern void wanrouter_init(void);
#endif
@@ -1691,14 +1673,6 @@ void __init sock_init(void)
#endif
/*
- * Ethernet bridge layer.
- */
-
-#ifdef CONFIG_BRIDGE
- br_init();
-#endif
-
- /*
* Wan router layer.
*/
@@ -1712,10 +1686,13 @@ void __init sock_init(void)
register_filesystem(&sock_fs_type);
sock_mnt = kern_mount(&sock_fs_type);
- proto_init();
+ /* The real protocol initialization is performed when
+ * do_initcalls is run.
+ */
+
/*
- * The netlink device handler may be needed early.
+ * The netlink device handler may be needed early.
*/
#ifdef CONFIG_RTNETLINK
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index 7eb578a60..a295ecaf7 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -159,7 +159,7 @@ rpcauth_insert_credcache(struct rpc_auth *auth, struct rpc_cred *cred)
{
int nr;
- nr = (cred->cr_uid % RPC_CREDCACHE_NR);
+ nr = (cred->cr_uid & RPC_CREDCACHE_MASK);
spin_lock(&rpc_credcache_lock);
cred->cr_next = auth->au_credcache[nr];
auth->au_credcache[nr] = cred;
@@ -178,7 +178,7 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, int taskflags)
int nr = 0;
if (!(taskflags & RPC_TASK_ROOTCREDS))
- nr = current->uid % RPC_CREDCACHE_NR;
+ nr = current->uid & RPC_CREDCACHE_MASK;
if (time_before(auth->au_nextgc, jiffies))
rpcauth_gc_credcache(auth);
@@ -218,7 +218,7 @@ rpcauth_remove_credcache(struct rpc_auth *auth, struct rpc_cred *cred)
struct rpc_cred **q, *cr;
int nr;
- nr = (cred->cr_uid % RPC_CREDCACHE_NR);
+ nr = (cred->cr_uid & RPC_CREDCACHE_MASK);
spin_lock(&rpc_credcache_lock);
q = &auth->au_credcache[nr];
while ((cr = *q) != NULL) {
diff --git a/net/sunrpc/auth_null.c b/net/sunrpc/auth_null.c
index d2e645acd..a9e42721a 100644
--- a/net/sunrpc/auth_null.c
+++ b/net/sunrpc/auth_null.c
@@ -54,6 +54,7 @@ nul_create_cred(int flags)
return NULL;
cred->cr_count = 0;
cred->cr_flags = RPCAUTH_CRED_UPTODATE;
+ cred->cr_uid = current->uid;
return cred;
}
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index a036faef9..26a140771 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -800,7 +800,6 @@ svc_recv(struct svc_serv *serv, struct svc_rqst *rqstp, long timeout)
"svc_recv: service %p, wait queue active!\n",
rqstp);
-again:
/* Initialize the buffers */
rqstp->rq_argbuf = rqstp->rq_defbuf;
rqstp->rq_resbuf = rqstp->rq_defbuf;
@@ -846,7 +845,7 @@ again:
/* No data, incomplete (TCP) read, or accept() */
if (len == 0 || len == -EAGAIN) {
svc_sock_release(rqstp);
- goto again;
+ return -EAGAIN;
}
rqstp->rq_secure = ntohs(rqstp->rq_addr.sin_port) < 1024;
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 407f8f6b6..7603a9221 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -8,7 +8,7 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
- * Version: $Id: af_unix.c,v 1.105 2000/08/16 10:58:22 davem Exp $
+ * Version: $Id: af_unix.c,v 1.107 2000/10/19 01:05:36 davem Exp $
*
* Fixes:
* Linus Torvalds : Assorted bug cures.
@@ -46,6 +46,7 @@
* Artur Skawina : Hash function optimizations
* Alexey Kuznetsov : Full scale SMP. Lot of bugs are introduced 8)
* Malcolm Beattie : Set peercred for socketpair
+ * Michal Ostrowski : Module initialization cleanup.
*
*
* Known differences from reference BSD that was tested:
@@ -1845,16 +1846,12 @@ struct net_proto_family unix_family_ops = {
unix_create
};
-#ifdef MODULE
#ifdef CONFIG_SYSCTL
extern void unix_sysctl_register(void);
extern void unix_sysctl_unregister(void);
#endif
-int init_module(void)
-#else
-void __init unix_proto_init(struct net_proto *pro)
-#endif
+static int __init af_unix_init(void)
{
struct sk_buff *dummy_skb;
@@ -1862,28 +1859,21 @@ void __init unix_proto_init(struct net_proto *pro)
if (sizeof(struct unix_skb_parms) > sizeof(dummy_skb->cb))
{
printk(KERN_CRIT "unix_proto_init: panic\n");
-#ifdef MODULE
return -1;
-#else
- return;
-#endif
}
sock_register(&unix_family_ops);
#ifdef CONFIG_PROC_FS
create_proc_read_entry("net/unix", 0, 0, unix_read_proc, NULL);
#endif
-#ifdef MODULE
#ifdef CONFIG_SYSCTL
unix_sysctl_register();
#endif
return 0;
-#endif
}
-#ifdef MODULE
-void cleanup_module(void)
+static void __exit af_unix_exit(void)
{
sock_unregister(PF_UNIX);
#ifdef CONFIG_SYSCTL
@@ -1893,7 +1883,9 @@ void cleanup_module(void)
remove_proc_entry("net/unix", 0);
#endif
}
-#endif
+
+module_init(af_unix_init);
+module_exit(af_unix_exit);
/*
* Local variables:
diff --git a/net/unix/sysctl_net_unix.c b/net/unix/sysctl_net_unix.c
index 744a4446a..885119da3 100644
--- a/net/unix/sysctl_net_unix.c
+++ b/net/unix/sysctl_net_unix.c
@@ -26,7 +26,6 @@ ctl_table unix_table[] = {
{0}
};
-#ifdef MODULE
static struct ctl_table_header * unix_sysctl_header;
static struct ctl_table unix_root_table[];
static struct ctl_table unix_net_table[];
@@ -50,6 +49,5 @@ void unix_sysctl_unregister(void)
{
unregister_sysctl_table(unix_sysctl_header);
}
-#endif /* MODULE */
#endif /* CONFIG_SYSCTL */
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index 9af3a0e3d..320722c40 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -1283,8 +1283,11 @@ void x25_kill_by_neigh(struct x25_neigh *neigh)
}
}
-void __init x25_proto_init(struct net_proto *pro)
+static int __init x25_init(void)
{
+#ifdef MODULE
+ struct net_device *dev;
+#endif /* MODULE */
sock_register(&x25_family_ops);
x25_packet_type.type = htons(ETH_P_X25);
@@ -1302,20 +1305,8 @@ void __init x25_proto_init(struct net_proto *pro)
proc_net_create("x25", 0, x25_get_info);
proc_net_create("x25_routes", 0, x25_routes_get_info);
#endif
-}
#ifdef MODULE
-EXPORT_NO_SYMBOLS;
-
-MODULE_AUTHOR("Jonathan Naylor <g4klx@g4klx.demon.co.uk>");
-MODULE_DESCRIPTION("The X.25 Packet Layer network layer protocol");
-
-int init_module(void)
-{
- struct net_device *dev;
-
- x25_proto_init(NULL);
-
/*
* Register any pre existing devices.
*/
@@ -1329,11 +1320,20 @@ int init_module(void)
x25_link_device_up(dev);
}
read_unlock(&dev_base_lock);
-
+#endif /* MODULE */
return 0;
}
+module_init(x25_init);
+
-void cleanup_module(void)
+
+#ifdef MODULE
+EXPORT_NO_SYMBOLS;
+
+MODULE_AUTHOR("Jonathan Naylor <g4klx@g4klx.demon.co.uk>");
+MODULE_DESCRIPTION("The X.25 Packet Layer network layer protocol");
+
+static void __exit x25_exit(void)
{
#ifdef CONFIG_PROC_FS
@@ -1354,7 +1354,7 @@ void cleanup_module(void)
sock_unregister(AF_X25);
}
-
+module_exit(x25_exit);
#endif
#endif