The last time I tried the kernel bridging code (~2.1.98), the
kernel would always crash within seconds, and it would take some
time to set up a system for testing with the latest kernels, so
I don't know if this code works or not. I do know that it seems
to load and unload just fine. Anyhow, I would appreciate feedback
from anybody who is using the bridging code on whether these
modularization changes break anything. I hope you find this
software useful.
Adam J. Richter __ ______________ 4880 Stevens Creek Blvd, Suite 205
adam@yggdrasil.com \ / San Jose, California 95129-1034
+1 408 261-6630 | g g d r a s i l United States of America
fax +1 408 261-6631 "Free Software For The Rest Of Us."
---------------------CUT HERE-----------------------------------
--- /tmp/linux-2.1.104pre1/./include/net/br.h Fri Apr 3 17:48:11 1998
+++ linux/./include/net/br.h Sat May 23 22:06:56 1998
@@ -298,4 +298,9 @@
extern struct br_stat br_stats;
+#ifdef CONFIG_BRIDGE_MODULE
+extern void (*handle_bridge_hook)(struct sk_buff *skb, unsigned short type);
+extern int (*br_ioctl_hook)(unsigned int, void *);
+#endif
+
--- /tmp/linux-2.1.104pre1/./net/netsyms.c Thu May 14 10:35:55 1998
+++ linux/./net/netsyms.c Sat May 23 22:40:46 1998
@@ -17,7 +17,7 @@
#include <net/neighbour.h>
#include <net/snmp.h>
-#ifdef CONFIG_BRIDGE
+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
#include <net/br.h>
#endif
@@ -200,6 +200,12 @@
EXPORT_SYMBOL(br_ioctl);
#endif
+#ifdef CONFIG_BRIDGE_MODULE
+EXPORT_SYMBOL(br_ioctl);
+EXPORT_SYMBOL(br_ioctl_hook);
+EXPORT_SYMBOL(handle_bridge_hook);
+#endif
+
#ifdef CONFIG_INET
/* Internet layer registration */
EXPORT_SYMBOL(inet_add_protocol);
@@ -218,6 +224,7 @@
EXPORT_SYMBOL(ip_fragment);
EXPORT_SYMBOL(inet_family_ops);
EXPORT_SYMBOL(in_aton);
+EXPORT_SYMBOL(in_ntoa);
EXPORT_SYMBOL(ip_mc_inc_group);
EXPORT_SYMBOL(ip_mc_dec_group);
EXPORT_SYMBOL(__ip_finish_output);
--- /tmp/linux-2.1.104pre1/./net/core/dev.c Wed May 6 10:56:06 1998
+++ linux/./net/core/dev.c Sat May 23 22:06:57 1998
@@ -94,6 +94,11 @@
NET_PROFILE_DEFINE(net_bh)
NET_PROFILE_DEFINE(net_bh_skb)
+#ifdef CONFIG_BRIDGE
+extern void handle_bridge(struct sk_buff *skb, unsigned short type);
+#elif defined(CONFIG_BRIDGE_MODULE)
+void (*handle_bridge_hook)(struct sk_buff *skb, unsigned short type) = NULL;
+#endif
const char *if_port_text[] = {
"unknown",
@@ -730,35 +735,6 @@
kfree_skb(skb);
}
-#ifdef CONFIG_BRIDGE
-static inline void handle_bridge(struct sk_buff *skb, unsigned short type)
-{
- if (br_stats.flags & BR_UP && br_protocol_ok(ntohs(type)))
- {
- /*
- * We pass the bridge a complete frame. This means
- * recovering the MAC header first.
- */
-
- int offset=skb->data-skb->mac.raw;
- cli();
- skb_push(skb,offset); /* Put header back on for bridge */
- if(br_receive_frame(skb))
- {
- sti();
- return;
- }
- /*
- * Pull the MAC header off for the copy going to
- * the upper layers.
- */
- skb_pull(skb,offset);
- sti();
- }
-}
-#endif
-
-
/*
* When we are called the queue is ready to grab, the interrupts are
* on and hardware can interrupt and queue to the receive queue as we
@@ -849,13 +825,15 @@
type = skb->protocol;
-#ifdef CONFIG_BRIDGE
+#if defined(CONFIG_BRIDGE)
/*
* If we are bridging then pass the frame up to the
* bridging code (if this protocol is to be bridged).
* If it is bridged then move on
*/
- handle_bridge(skb, type);
+ handle_bridge(skb, type);
+#elif defined(CONFIG_BRIDGE_MODULE)
+ if (handle_bridge_hook) (*handle_bridge_hook)(skb,type);
#endif
/*
--- /tmp/linux-2.1.104pre1/./net/ipv4/af_inet.c Thu May 14 10:26:23 1998
+++ linux/./net/ipv4/af_inet.c Sat May 23 21:55:01 1998
@@ -105,7 +105,7 @@
#ifdef CONFIG_IP_MASQUERADE
#include <net/ip_masq.h>
#endif
-#ifdef CONFIG_BRIDGE
+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
#include <net/br.h>
#endif
#ifdef CONFIG_KMOD
@@ -143,6 +143,21 @@
* Destroy an AF_INET socket
*/
+
+#ifdef CONFIG_BRIDGE_MODULE
+
+int (*br_ioctl_hook) (unsigned int cmd, void *arg) = NULL;
+
+int br_ioctl(unsigned int cmd, void *arg) {
+# ifdef CONFIG_KMOD
+ if (br_ioctl_hook == NULL)
+ request_module("bridge");
+# endif/* CONFIG_KMOD */
+ return (br_ioctl_hook == NULL) ? -ENOPKG : (*br_ioctl_hook)(cmd,arg);
+}
+#endif /* CONFIG_BRIDGE_MODULE */
+
+
static __inline__ void kill_sk_queues(struct sock *sk)
{
struct sk_buff *skb;
@@ -855,6 +870,7 @@
* There's a good 20K of config code hanging around the kernel.
*/
+
static int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
struct sock *sk = sock->sk;
@@ -915,12 +931,11 @@
return(devinet_ioctl(cmd,(void *) arg));
case SIOCGIFBR:
case SIOCSIFBR:
-#ifdef CONFIG_BRIDGE
+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
return(br_ioctl(cmd,(void *) arg));
#else
return -ENOPKG;
-#endif
-
+#endif
case SIOCADDDLCI:
case SIOCDELDLCI:
#ifdef CONFIG_DLCI
--- /tmp/linux-2.1.104pre1/./net/packet/af_packet.c Fri May 8 00:08:02 1998
+++ linux/./net/packet/af_packet.c Sat May 23 21:19:13 1998
@@ -71,7 +71,7 @@
#include <net/inet_common.h>
#endif
-#ifdef CONFIG_BRIDGE
+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
#include <net/br.h>
#endif
@@ -1130,12 +1130,12 @@
case SIOCGIFBR:
case SIOCSIFBR:
-#ifdef CONFIG_BRIDGE
+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
return(br_ioctl(cmd,(void *) arg));
#else
return -ENOPKG;
#endif
-
+
#ifdef CONFIG_INET
case SIOCADDRT:
case SIOCDELRT:
--- /tmp/linux-2.1.104pre1/./net/Makefile Sun Nov 30 14:00:39 1997
+++ linux/./net/Makefile Sat May 23 20:42:02 1998
@@ -58,6 +58,10 @@
ifeq ($(CONFIG_BRIDGE),y)
SUB_DIRS += bridge
+else
+ ifeq ($(CONFIG_BRIDGE),m)
+ MOD_SUB_DIRS += bridge
+ endif
endif
ifeq ($(CONFIG_IPX),y)
--- /tmp/linux-2.1.104pre1/./net/bridge/Makefile Tue Apr 28 11:10:10 1998
+++ linux/./net/bridge/Makefile Sat May 23 23:48:28 1998
@@ -8,6 +8,8 @@
# Note 2! The CFLAGS definition is now in the main makefile...
O_TARGET := bridge.o
+MOD_LIST_NAME := NET_MISC_MODULES
+
O_OBJS := br.o br_tree.o
M_OBJS := $(O_TARGET)
--- /tmp/linux-2.1.104pre1/./net/bridge/br.c Wed Apr 1 16:19:57 1998
+++ linux/./net/bridge/br.c Sat May 23 22:55:23 1998
@@ -47,7 +47,10 @@
* Put the path costs in the port info and devices.
* Put the bridge port number in the device structure for speed.
* Bridge SNMP stats.
- *
+ * Add calls to MOD_{INC,DEC}_USE_COUNT rather than leaving
+ * the module marked as "unused" (this is OK, because
+ * "rmmod -a" does not automatically remove modules marked
+ * as "unused").
*/
#include <linux/errno.h>
@@ -71,6 +74,14 @@
#include <asm/uaccess.h>
#include <asm/system.h>
#include <net/br.h>
+#ifdef MODULE
+# include <linux/module.h>
+# include <linux/config.h>
+# ifdef CONFIG_SYSCTL
+# include <linux/sysctl.h>
+# endif
+#endif
+
#ifndef min
#define min(a, b) (((a) <= (b)) ? (a) : (b))
@@ -155,6 +166,19 @@
int max_mcast_per_period = MAX_MCAST_PER_PERIOD;
int mcast_hold_time = MCAST_HOLD_TIME;
+#ifdef MODULE
+extern void (*handle_bridge_hook)(struct sk_buff *skb, unsigned short type);
+extern int (*bridge_ioctl_hook)(unsigned int, void *);
+
+static void handle_bridge(struct sk_buff *skb, unsigned short type);
+static int br_ioctl_local(unsigned int cmd, void *arg);
+
+#ifdef CONFIG_SYSCTL
+extern ctl_table bridge_table[];
+static struct ctl_table_header *ctl_table_header;
+#endif
+#endif
+
/* JRP: next two bpdu are copied to skbuff so we need only 1 of each */
static Config_bpdu config_bpdu;
static Tcn_bpdu tcn_bpdu;
@@ -802,12 +826,35 @@
} /* (4.6.1.2.3) */
}
+
+#ifdef MODULE
+void cleanup_module(void) {
+ handle_bridge_hook = NULL;
+ br_ioctl_hook = NULL;
+#ifdef CONFIG_SYSCTL
+ if (ctl_table_header != NULL) {
+ unregister_sysctl_table(ctl_table_header);
+ }
+#endif
+}
+
+int init_module(void)
+#else
__initfunc(void br_init(void))
+#endif
{ /* (4.8.1) */
int port_no;
printk(KERN_INFO "Ethernet Bridge 005 for NET3.037 (Linux 2.1)\n");
+#ifdef MODULE
+ handle_bridge_hook = handle_bridge;
+ br_ioctl_hook = br_ioctl_local;
+# ifdef CONFIG_SYSCTL
+ ctl_table_header = register_sysctl_table(bridge_table, 0);
+# endif
+#endif
+
/*
* Form initial topology change time.
* The topology change timer is only used if this is the root bridge.
@@ -857,6 +904,9 @@
br_stats.policy = BR_ACCEPT; /* Enable bridge to accpet all protocols */
br_stats.exempt_protocols = 0;
/*start_hello_timer();*/
+#ifdef MODULE
+ return 0;
+#endif
}
static inline unsigned short make_port_id(int port_no)
@@ -1889,7 +1939,11 @@
return fdbis;
}
+#ifdef MODULE
+static int br_ioctl_local(unsigned int cmd, void *arg)
+#else
int br_ioctl(unsigned int cmd, void *arg)
+#endif
{
int err, i;
struct br_cf bcf;
@@ -2059,4 +2113,35 @@
return(1);
}
return(0);
+}
+
+#ifdef MODULE
+static
+#endif
+void
+handle_bridge(struct sk_buff *skb, unsigned short type)
+{
+
+ if (br_stats.flags & BR_UP && br_protocol_ok(ntohs(type)))
+ {
+ /*
+ * We pass the bridge a complete frame. This means
+ * recovering the MAC header first.
+ */
+
+ int offset=skb->data-skb->mac.raw;
+ cli();
+ skb_push(skb,offset); /* Put header back on for bridge */
+ if(br_receive_frame(skb))
+ {
+ sti();
+ return;
+ }
+ /*
+ * Pull the MAC header off for the copy going to
+ * the upper layers.
+ */
+ skb_pull(skb,offset);
+ sti();
+ }
}
--- /tmp/linux-2.1.104pre1/./net/Config.in Tue Apr 28 11:10:10 1998
+++ linux/./net/Config.in Sat May 23 20:41:30 1998
@@ -37,7 +37,7 @@
# fi
tristate 'CCITT X.25 Packet Layer (EXPERIMENTAL)' CONFIG_X25
tristate 'LAPB Data Link Driver (EXPERIMENTAL)' CONFIG_LAPB
- bool 'Bridging (EXPERIMENTAL)' CONFIG_BRIDGE
+ tristate 'Bridging (EXPERIMENTAL)' CONFIG_BRIDGE
bool '802.2 LLC (EXPERIMENTAL)' CONFIG_LLC
# if [ "$CONFIG_LLC" = "y" ]; then
# bool 'Netbeui (EXPERIMENTAL)' CONFIG_NETBEUI
--S.pNyT/970962=_/vger.rutgers.edu--
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu