[2184] in linux-net channel archive

home help back first fref pref prev next nref lref last post

net module patch

daemon@ATHENA.MIT.EDU (Tom Dyas)
Wed Mar 20 22:06:59 1996

Date: 	Wed, 20 Mar 96 21:44:04 EST
From: Tom Dyas <tdyas@eden.rutgers.edu>
To: linux-net@vger.rutgers.edu
Cc: net-patches@lxorguk.ukuu.org.uk, mvachhar@hardees.rutgers.edu,
        jfree@caldera.com

Here is the merged IPX/Appletalk net module patch. The IPX stuff comes
from Jim Freeman (jfree@caldera.com). The patch is against
1.3.76. Here is a summary of the changes:

* AppleTalk can now compile as a module.

* IPX can also compile as a module. (Jim)

* sys_socket can now ask kerneld to load a missing protocol family by
requesting modules such as net-pf-4 for IPX or net-pf-5 for
AppleTalk.

* Moved all networking symbols from ksyms.c to a new file called
linux/net/netsyms.c. Modified sock_init() to call
export_net_symbols().

* Have started to move some symbols into symbol tables in each
protocol. For example, register_snap_client and unregister_snap_client
are registered by snap_proto_init instead of being shoved into
netsyms.c. I'll be moving some other symbols elsewhere in the
future.

It compiles cleanly and the modules insert without problems and unload
nicely. Use the kerneld stuff at your own risk since I don't use
kerneld myself.

As a sidenote, 1.3.76 seems to have large amounts of latency for TCP
connections that cause intolerable delays. I also encountered the
"Socket destroy delayed" messages for the first time. I had to back
down to 1.3.73 to even send this email. Even then 73 has some werid
delays.

Any ways, here is the patch:

---------------

--- linux/kernel/ksyms.c-	Tue Mar 19 15:06:07 1996
+++ linux/kernel/ksyms.c	Wed Mar 20 18:26:30 1996
@@ -48,32 +48,6 @@
 
 extern unsigned char aux_device_present, kbd_read_mask;
 
-#ifdef CONFIG_NET
-#include <linux/in.h>
-#include <linux/net.h>
-#include <linux/netdevice.h>
-#include <linux/firewall.h>
-#include <linux/trdevice.h>
-
-#ifdef CONFIG_AX25
-#include <net/ax25.h>
-#endif
-#ifdef CONFIG_INET
-#include <linux/ip.h>
-#include <linux/etherdevice.h>
-#include <net/protocol.h>
-#include <net/arp.h>
-#include <net/ip.h>
-#include <net/udp.h>
-#include <net/tcp.h>
-#include <net/icmp.h>
-#include <net/route.h>
-#include <linux/net_alias.h>
-#endif
-#ifdef CONFIG_NET_ALIAS
-#include <linux/net_alias.h>
-#endif
-#endif
 #ifdef CONFIG_PCI
 #include <linux/bios32.h>
 #include <linux/pci.h>
@@ -96,17 +70,9 @@
 
 extern void *sys_call_table;
 
-#if	defined(CONFIG_ULTRA)	||	defined(CONFIG_WD80x3)		|| \
-	defined(CONFIG_EL2)	||	defined(CONFIG_NE2000)		|| \
-	defined(CONFIG_E2100)	||	defined(CONFIG_HPLAN_PLUS)	|| \
-	defined(CONFIG_HPLAN)	||	defined(CONFIG_AC3200)
-#include "../drivers/net/8390.h"
-#endif
-
 extern int sys_tz;
 extern int request_dma(unsigned int dmanr, char * deviceID);
 extern void free_dma(unsigned int dmanr);
-extern int (*rarp_ioctl_hook)(int,void*);
 
 struct symbol_table symbol_table = {
 #include <linux/symtab_begin.h>
@@ -339,94 +305,7 @@
 
 	/* Miscellaneous access points */
 	X(si_meminfo),
-#ifdef CONFIG_NET
-	/* Socket layer registration */
-	X(sock_register),
-	X(sock_unregister),
-	/* Socket layer support routines */
-	X(skb_recv_datagram),
-	X(skb_free_datagram),
-	X(skb_copy_datagram),
-	X(skb_copy_datagram_iovec),
-	X(datagram_select),
-#ifdef CONFIG_FIREWALL
-	/* Firewall registration */
-	X(register_firewall),
-	X(unregister_firewall),
-#endif
-#ifdef CONFIG_INET	
-	/* Internet layer registration */
-	X(inet_add_protocol),
-	X(inet_del_protocol),
-	X(rarp_ioctl_hook),
-	X(init_etherdev),
-	X(ip_rt_route),
-	X(icmp_send),
-	X(ip_options_compile),
-	X(ip_rt_put),
-	X(arp_send),
-#ifdef CONFIG_IP_FORWARD
-	X(ip_forward),
-#endif
-#if	defined(CONFIG_ULTRA)	||	defined(CONFIG_WD80x3)		|| \
-	defined(CONFIG_EL2)	||	defined(CONFIG_NE2000)		|| \
-	defined(CONFIG_E2100)	||	defined(CONFIG_HPLAN_PLUS)	|| \
-	defined(CONFIG_HPLAN)	||	defined(CONFIG_AC3200)
-	/* If 8390 NIC support is built in, we will need these. */
-	X(ei_open),
-	X(ei_close),
-	X(ei_debug),
-	X(ei_interrupt),
-	X(ethdev_init),
-	X(NS8390_init),
-#endif
-#ifdef CONFIG_NET_ALIAS
-#include <linux/net_alias.h>
-#endif
-#endif
-	/* Device callback registration */
-	X(register_netdevice_notifier),
-	X(unregister_netdevice_notifier),
-#ifdef CONFIG_NET_ALIAS
-	X(register_net_alias_type),
-	X(unregister_net_alias_type),
-#endif
-#endif
-
-	/* support for loadable net drivers */
-#ifdef CONFIG_AX25
-	X(ax25_encapsulate),
-	X(ax25_rebuild_header),	
-#endif	
-#ifdef CONFIG_INET
-	X(register_netdev),
-	X(unregister_netdev),
-	X(ether_setup),
-	X(eth_type_trans),
-	X(eth_copy_and_sum),
-	X(alloc_skb),
-	X(kfree_skb),
-	X(skb_clone),
-	X(dev_alloc_skb),
-	X(dev_kfree_skb),
-	X(netif_rx),
-	X(dev_tint),
-	X(irq2dev_map),
-	X(dev_add_pack),
-	X(dev_remove_pack),
-	X(dev_get),
-	X(dev_ioctl),
-	X(dev_queue_xmit),
-	X(dev_base),
-	X(dev_close),
-	X(arp_find),
-	X(n_tty_ioctl),
-	X(tty_register_ldisc),
-	X(kill_fasync),
-#ifdef CONFIG_FIREWALL
-	X(call_in_firewall),
-#endif
-#endif
+
 #ifndef CONFIG_SCSI
 	/*
 	 * With no scsi configured, we still need to export a few
--- linux/include/linux/atalk.h-	Fri Mar  1 00:22:56 1996
+++ linux/include/linux/atalk.h	Tue Mar 19 15:09:38 1996
@@ -140,5 +140,9 @@
 extern struct at_addr *atalk_find_dev_addr(struct device *dev);
 extern int aarp_send_ddp(struct device *dev,struct sk_buff *skb, struct at_addr *sa, void *hwaddr);
 extern void aarp_send_probe(struct device *dev, struct at_addr *addr);
+#ifdef MODULE
+extern void aarp_cleanup_module(void);
+#endif
+
 #endif
 #endif
--- linux/include/net/p8022.h-	Tue Mar 19 16:35:01 1996
+++ linux/include/net/p8022.h	Wed Mar 20 18:36:56 1996
@@ -1,2 +1,7 @@
-struct datalink_proto *register_8022_client(unsigned char type, int (*rcvfunc)(struct sk_buff *, struct device *, struct packet_type *));
+#ifndef _NET_P8022_H
+#define _NET_P8022_H
 
+extern struct datalink_proto *register_8022_client(unsigned char type, int (*rcvfunc)(struct sk_buff *, struct device *, struct packet_type *));
+extern void unregister_8022_client(unsigned char type);
+
+#endif
--- linux/include/net/ipx.h-	Fri Mar  8 08:53:58 1996
+++ linux/include/net/ipx.h	Wed Mar 20 19:24:51 1996
@@ -11,6 +11,7 @@
 #ifndef _NET_INET_IPX_H_
 #define _NET_INET_IPX_H_
 
+#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <net/datalink.h>
 #include <linux/ipx.h>
--- linux/include/net/psnap.h-	Tue Jun  6 04:22:18 1995
+++ linux/include/net/psnap.h	Wed Mar 20 18:37:12 1996
@@ -1,2 +1,7 @@
-struct datalink_proto *register_snap_client(unsigned char *desc, int (*rcvfunc)(struct sk_buff *, struct device *, struct packet_type *));
+#ifndef _NET_PSNAP_H
+#define _NET_PSNAP_H
 
+extern struct datalink_proto *register_snap_client(unsigned char *desc, int (*rcvfunc)(struct sk_buff *, struct device *, struct packet_type *));
+extern void unregister_snap_client(unsigned char *desc);
+
+#endif
--- linux/include/net/sock.h-	Tue Mar 19 15:06:07 1996
+++ linux/include/net/sock.h	Wed Mar 20 19:24:51 1996
@@ -46,10 +46,12 @@
 #include <net/netrom.h>
 #endif
 #endif
-#ifdef CONFIG_IPX
+
+#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE)
 #include <net/ipx.h>
 #endif
-#ifdef CONFIG_ATALK
+
+#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE)
 #include <linux/atalk.h>
 #endif
 
@@ -90,7 +92,7 @@
  *	Once the IPX ncpd patches are in these are going into protinfo
  */
 
-#ifdef CONFIG_IPX 
+#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE)
 struct ipx_opt
 {
 	ipx_address		dest_addr;
@@ -259,12 +261,12 @@
 	union
 	{
 	  	struct unix_opt	af_unix;
-#ifdef CONFIG_ATALK
+#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE)
 		struct atalk_sock	af_at;
 #endif
-#ifdef CONFIG_IPX
+#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE)
 		struct ipx_opt		af_ipx;
-#endif		
+#endif
 #ifdef CONFIG_INET
 		struct inet_packet_opt  af_packet;
 #ifdef CONFIG_NUTCP		
--- linux/net/802/psnap.c-	Thu Jul 27 12:34:36 1995
+++ linux/net/802/psnap.c	Tue Mar 19 16:15:27 1996
@@ -17,6 +17,7 @@
 #include <net/psnap.h>
 #include <linux/mm.h>
 #include <linux/in.h>
+#include <linux/module.h>
 
 static struct datalink_proto *snap_list = NULL;
 static struct datalink_proto *snap_dl = NULL;		/* 802.2 DL for SNAP */
@@ -81,12 +82,20 @@
 /*
  *	Set up the SNAP layer
  */
+
+static struct symbol_table snap_proto_syms = {
+#include <linux/symtab_begin.h>
+	X(register_snap_client),
+	X(unregister_snap_client),
+#include <linux/symtab_end.h>
+};
  
 void snap_proto_init(struct net_proto *pro)
 {
 	snap_dl=register_8022_client(0xAA, snap_rcv);
 	if(snap_dl==NULL)
 		printk("SNAP - unable to register with 802.2\n");
+	register_symtab(&snap_proto_syms);
 }
 	
 /*
@@ -114,5 +123,32 @@
 	}
 
 	return proto;
+}
+
+/*
+ *	Unregister SNAP clients. Protocols no longer want to play with us ...
+ */
+
+void unregister_snap_client(unsigned char *desc)
+{
+	struct datalink_proto **clients = &snap_list;
+	struct datalink_proto *tmp;
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+
+	while ((tmp = *clients) != NULL)
+	{
+		if (memcmp(tmp->type,desc,5) == 0)
+		{
+			*clients = tmp->next;
+			kfree_s(tmp, sizeof(struct datalink_proto));
+		}
+		else
+			clients = &tmp->next;
+	}
+
+	restore_flags(flags);
 }
 
--- linux/net/802/p8022.c-	Tue Mar 19 16:17:53 1996
+++ linux/net/802/p8022.c	Wed Mar 20 20:15:50 1996
@@ -3,6 +3,8 @@
 #include <net/datalink.h>
 #include <linux/mm.h>
 #include <linux/in.h>
+#include <linux/module.h>
+#include <net/p8022.h>
 
 static struct datalink_proto *p8022_list = NULL;
 
@@ -65,12 +67,20 @@
 	NULL,
 	NULL,
 };
+
+static struct symbol_table p8022_proto_syms = {
+#include <linux/symtab_begin.h>
+	X(register_8022_client),
+	X(unregister_8022_client),
+#include <linux/symtab_end.h>
+};
  
 
 void p8022_proto_init(struct net_proto *pro)
 {
 	p8022_packet_type.type=htons(ETH_P_802_2);
 	dev_add_pack(&p8022_packet_type);
+	register_symtab(&p8022_proto_syms);
 }
 	
 struct datalink_proto *
@@ -96,3 +106,24 @@
 	return proto;
 }
 
+void unregister_8022_client(unsigned char type)
+{
+	struct datalink_proto *tmp, **clients = &p8022_list;
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+
+	while ((tmp = *clients) != NULL)
+	{
+		if (tmp->type[0] == type) {
+			*clients = tmp->next;
+			kfree_s(tmp, sizeof(struct datalink_proto));
+			break;
+		} else {
+			clients = &tmp->next;
+		}
+	}
+
+	restore_flags(flags);
+}
--- linux/net/802/p8023.c-	Wed Mar 20 18:33:35 1996
+++ linux/net/802/p8023.c	Wed Mar 20 18:35:07 1996
@@ -29,3 +29,9 @@
 	return proto;
 }
 
+void destroy_8023_client(struct datalink_proto *dl)
+{
+	if (dl)
+		kfree_s(dl,sizeof(struct datalink_proto));
+}
+
--- linux/net/appletalk/aarp.c-	Tue Mar 19 15:05:10 1996
+++ linux/net/appletalk/aarp.c	Wed Mar 20 20:30:09 1996
@@ -26,7 +26,6 @@
 #include <asm/segment.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -49,7 +48,6 @@
 #include <net/psnap.h>
 #include <linux/atalk.h>
 
-#ifdef CONFIG_ATALK
 /*
  *	Lists of aarp entries
  */
@@ -790,10 +788,11 @@
 	0
 };
 
+static char aarp_snap_id[]={0x00,0x00,0x00,0x80,0xF3};
+
 
 void aarp_proto_init(void)
 {
-	static char aarp_snap_id[]={0x00,0x00,0x00,0x80,0xF3};
 	if((aarp_dl=register_snap_client(aarp_snap_id, aarp_rcv))==NULL)
 		printk("Unable to register AARP with SNAP.\n");
 	init_timer(&aarp_timer);
@@ -803,4 +802,43 @@
 	add_timer(&aarp_timer);
 	register_netdevice_notifier(&aarp_notifier);
 }
-#endif
+
+
+#ifdef MODULE
+
+/* Free all the entries in an aarp list. Caller should turn off interrupts. */
+static void free_entry_list(struct aarp_entry *list)
+{
+	struct aarp_entry *tmp;
+
+	while (list != NULL)
+	{
+		tmp = list->next;
+		aarp_expire(list);
+		list = tmp;
+	}
+}
+
+/* General module cleanup. Called from cleanup_module() in ddp.c. */
+void aarp_cleanup_module(void)
+{
+	unsigned long flags;
+	int i;
+
+	save_flags(flags);
+	cli();
+
+	del_timer(&aarp_timer);
+	unregister_netdevice_notifier(&aarp_notifier);
+	unregister_snap_client(aarp_snap_id);
+
+	for (i = 0; i < AARP_HASH_SIZE; i++)
+	{
+		free_entry_list(resolved[i]);
+		free_entry_list(unresolved[i]);
+	}
+
+	restore_flags(flags);
+}
+
+#endif  /* MODULE */
--- linux/net/appletalk/ddp.c-	Tue Mar 19 15:05:10 1996
+++ linux/net/appletalk/ddp.c	Wed Mar 20 18:49:47 1996
@@ -20,6 +20,7 @@
  *		Alan Cox		:	Supports new ARPHRD_LOOPBACK
  *		Christer Weinigel	: 	Routing and /proc fixes.
  *		Bradford Johnson	:	Locatalk.
+ *		Tom Dyas		:	Module support.
  *
  *		This program is free software; you can redistribute it and/or
  *		modify it under the terms of the GNU General Public License
@@ -61,8 +62,8 @@
 #include <linux/proc_fs.h>
 #include <linux/stat.h>
 #include <linux/firewall.h>
+#include <linux/module.h>
 
-#ifdef CONFIG_ATALK
 
 #undef APPLETALK_DEBUG
 
@@ -214,7 +215,10 @@
 	}
 	
 	if(sk->wmem_alloc == 0 && sk->rmem_alloc == 0 && sk->dead)
+	{
 		kfree_s(sk,sizeof(*sk));
+		MOD_DEC_USE_COUNT;
+	}
 	else
 	{
 		/*
@@ -1133,6 +1137,9 @@
 			kfree_s((void *)sk,sizeof(*sk));
 			return(-ESOCKTNOSUPPORT);
 	}
+
+	MOD_INC_USE_COUNT;
+
 	sk->dead=0;
 	sk->next=NULL;
 	sk->broadcast=0;
@@ -2005,11 +2012,13 @@
 	NULL
 };
 
+static char ddp_snap_id[]={0x08,0x00,0x07,0x80,0x9B};
+
+
 /* Called by proto.c on kernel start up */
 
 void atalk_proto_init(struct net_proto *pro)
 {
-	static char ddp_snap_id[]={0x08,0x00,0x07,0x80,0x9B};
 	(void) sock_register(atalk_proto_ops.family, &atalk_proto_ops);
 	if ((ddp_dl = register_snap_client(ddp_snap_id, atalk_rcv)) == NULL)
 		printk("Unable to register DDP with SNAP.\n");
@@ -2041,4 +2050,63 @@
 
 	printk("Appletalk 0.16 for Linux NET3.033\n");
 }
-#endif
+
+#ifdef MODULE
+
+int init_module(void)
+{
+	atalk_proto_init(NULL);
+	register_symtab(0);
+	return 0;
+}
+
+/* Remove all route entries. Interrupts must be off. */
+static __inline__ void free_route_list(void)
+{
+	struct atalk_route *list = atalk_router_list, *tmp;
+
+	while (list != NULL)
+	{
+		tmp = list->next;
+		kfree_s(list, sizeof(struct atalk_route));
+		list = tmp;
+	}
+}
+
+/* Remove all interface entries. Interrupts must be off. */
+static __inline__ void free_interface_list(void)
+{
+	struct atalk_iface *list = atalk_iface_list, *tmp;
+
+	while (list != NULL)
+	{
+		tmp = list->next;
+		kfree_s(list, sizeof(struct atalk_iface));
+		list = tmp;
+	}
+}
+
+void cleanup_module(void)
+{
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+
+	aarp_cleanup_module();
+
+	proc_net_unregister(PROC_NET_ATALK);
+	proc_net_unregister(PROC_NET_AT_ROUTE);
+	proc_net_unregister(PROC_NET_ATIF);
+	unregister_netdevice_notifier(&ddp_notifier);
+	dev_remove_pack(&ltalk_packet_type);
+	unregister_snap_client(ddp_snap_id);
+	sock_unregister(atalk_proto_ops.family);
+
+	free_route_list();
+	free_interface_list();
+
+	restore_flags(flags);
+}
+
+#endif  /* MODULE */
--- linux/net/appletalk/Makefile-	Tue Aug 15 08:07:03 1995
+++ linux/net/appletalk/Makefile	Tue Mar 19 15:29:21 1996
@@ -9,6 +9,7 @@
 
 O_TARGET := appletalk.o
 O_OBJS	 := aarp.o ddp.o
+M_OBJS   := $(O_TARGET)
 
 include $(TOPDIR)/Rules.make
 
--- linux/net/ethernet/pe2.c-	Fri Nov 24 09:39:54 1995
+++ linux/net/ethernet/pe2.c	Wed Mar 20 18:36:06 1996
@@ -30,3 +30,8 @@
 	return proto;
 }
 
+void destroy_EII_client(struct datalink_proto *dl)
+{
+	if (dl)
+		kfree_s(dl, sizeof(struct datalink_proto));
+}
--- linux/net/ipx/Makefile-	Tue Mar 19 15:28:37 1996
+++ linux/net/ipx/Makefile	Tue Mar 19 15:29:04 1996
@@ -9,6 +9,7 @@
 
 O_TARGET := ipx.o
 O_OBJS   := af_ipx.o
+M_OBJS   := $(O_TARGET)
 
 include $(TOPDIR)/Rules.make
 
--- linux/net/ipx/af_ipx.c-	Mon Mar  4 02:16:41 1996
+++ linux/net/ipx/af_ipx.c	Wed Mar 20 19:12:13 1996
@@ -41,13 +41,16 @@
  *			Supports sendmsg/recvmsg
  *	Revision 0.33:	Internal network support, routing changes, uses a
  *			protocol private area for ipx data.
+ *	Revision 0.34:	Module support. <Jim Freeman>
  *
  * 	Portions Copyright (c) 1995 Caldera, Inc. <greg@caldera.com>
  *	Neither Greg Page nor Caldera, Inc. admit liability nor provide 
  *	warranty for any of this software. This material is provided 
  *	"AS-IS" and at no charge.		
  */
-  
+
+#include <linux/module.h>
+
 #include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/types.h>
@@ -59,11 +62,10 @@
 #include <linux/string.h>
 #include <linux/sockios.h>
 #include <linux/net.h>
-#include <linux/ipx.h>
-#include <linux/inet.h>
 #include <linux/netdevice.h>
+#include <net/ipx.h>
+#include <linux/inet.h>
 #include <linux/route.h>
-#include <linux/skbuff.h>
 #include <net/sock.h>
 #include <asm/segment.h>
 #include <asm/system.h>
@@ -77,7 +79,10 @@
 #include <linux/stat.h>
 #include <linux/firewall.h>
 
-#ifdef CONFIG_IPX
+#ifdef MODULE
+static void ipx_proto_finito(void);
+#endif /* def MODULE */
+
 /* Configuration Variables */
 static unsigned char	ipxcfg_max_hops = 16;
 static char		ipxcfg_auto_select_primary = 0;
@@ -89,10 +94,10 @@
 static struct datalink_proto	*p8023_datalink = NULL;
 static struct datalink_proto	*pSNAP_datalink = NULL;
 
-static ipx_interface	*ipx_interfaces = NULL;
 static ipx_route 	*ipx_routes = NULL;
-static ipx_interface	*ipx_internal_net = NULL;
+static ipx_interface	*ipx_interfaces = NULL;
 static ipx_interface	*ipx_primary_net = NULL;
+static ipx_interface	*ipx_internal_net = NULL;
 
 static int
 ipxcfg_set_auto_create(char val)
@@ -187,6 +192,7 @@
 	}
 	
 	kfree_s(sk,sizeof(*sk));
+	MOD_DEC_USE_COUNT;
 }
 	
 /* The following code is used to support IPX Interfaces (IPXITF).  An
@@ -194,7 +200,7 @@
  */
 
 static ipx_route * ipxrtr_lookup(unsigned long);
- 
+
 static void
 ipxitf_clear_primary_net(void)
 {
@@ -324,6 +330,10 @@
 		ipx_internal_net = NULL;
 
 	kfree_s(intrfc, sizeof(*intrfc));
+	/* sockets still dangling
+	 * - must be closed from user space
+	 */
+	return;
 }
 
 static int 
@@ -790,6 +800,7 @@
 
 	if (ipxcfg_auto_select_primary && (ipx_primary_net == NULL))
 		ipx_primary_net = intrfc;
+	return;
 }
 
 static int 
@@ -1155,7 +1166,7 @@
 /*
  *	Route an outgoing frame from a socket.
  */
- 
+
 static int ipxrtr_route_packet(ipx_socket *sk, struct sockaddr_ipx *usipx, struct iovec *iov, int len)
 {
 	struct sk_buff *skb;
@@ -1259,7 +1270,7 @@
 /*
  *	We use a normal struct rtentry for route handling
  */
- 
+
 static int ipxrtr_ioctl(unsigned int cmd, void *arg)
 {
 	int err;
@@ -1483,7 +1494,7 @@
 *	      Handling for system calls applied via the various interfaces to an IPX socket object		    *
 *														    *
 \*******************************************************************************************************************/
- 
+
 static int ipx_fcntl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
 	switch(cmd)
@@ -1642,6 +1653,7 @@
 	sk->error_report=def_callback1;
 
 	sk->zapped=1;
+	MOD_INC_USE_COUNT;
 	return 0;
 }
 
@@ -1830,8 +1842,10 @@
 
 static int ipx_accept(struct socket *sock, struct socket *newsock, int flags)
 {
-	if(newsock->data)
+	if(newsock->data) {
 		kfree_s(newsock->data,sizeof(ipx_socket));
+		MOD_DEC_USE_COUNT;
+	}
 	return -EOPNOTSUPP;
 }
 
@@ -2187,7 +2201,7 @@
 	NULL,
 	NULL,
 };
- 
+
 static struct packet_type ipx_dix_packet_type = 
 {
 	0,	/* MUTTER ntohs(ETH_P_IPX),*/
@@ -2196,7 +2210,7 @@
 	NULL,
 	NULL,
 };
- 
+
 static struct notifier_block ipx_dev_notifier={
 	ipxitf_device_event,
 	NULL,
@@ -2206,12 +2220,30 @@
 
 extern struct datalink_proto	*make_EII_client(void);
 extern struct datalink_proto	*make_8023_client(void);
+extern void	destroy_EII_client(struct datalink_proto *);
+extern void	destroy_8023_client(struct datalink_proto *);
 
-void ipx_proto_init(struct net_proto *pro)
-{
-	unsigned char	val = 0xE0;
-	unsigned char	snapval[5] =  { 0x0, 0x0, 0x0, 0x81, 0x37 };
+struct proc_dir_entry ipx_procinfo = {
+	PROC_NET_IPX, 3, "ipx", S_IFREG | S_IRUGO,
+	1, 0, 0, 0, &proc_net_inode_operations, ipx_get_info
+};
 
+struct proc_dir_entry ipx_if_procinfo = {
+	PROC_NET_IPX_INTERFACE, 13, "ipx_interface", S_IFREG | S_IRUGO,
+	1, 0, 0, 0, &proc_net_inode_operations, ipx_interface_get_info
+};
+
+struct proc_dir_entry ipx_rt_procinfo = {
+	PROC_NET_IPX_ROUTE, 9, "ipx_route", S_IFREG | S_IRUGO,
+	1, 0, 0, 0, &proc_net_inode_operations, ipx_rt_get_info
+};
+
+static unsigned char	ipx_8022_type = 0xE0;
+static unsigned char	ipx_snap_id[5] =  { 0x0, 0x0, 0x0, 0x81, 0x37 };
+
+void
+ipx_proto_init(struct net_proto *pro)
+{
 	(void) sock_register(ipx_proto_ops.family, &ipx_proto_ops);
 
 	pEII_datalink = make_EII_client();
@@ -2222,34 +2254,82 @@
 	ipx_8023_packet_type.type=htons(ETH_P_802_3);
 	dev_add_pack(&ipx_8023_packet_type);
 	
-	if ((p8022_datalink = register_8022_client(val, ipx_rcv)) == NULL)
+	if ((p8022_datalink = register_8022_client(ipx_8022_type, ipx_rcv)) == NULL)
 		printk("IPX: Unable to register with 802.2\n");
 
-	if ((pSNAP_datalink = register_snap_client(snapval, ipx_rcv)) == NULL)
+	if ((pSNAP_datalink = register_snap_client(ipx_snap_id, ipx_rcv)) == NULL)
 		printk("IPX: Unable to register with SNAP\n");
 	
 	register_netdevice_notifier(&ipx_dev_notifier);
 
-	proc_net_register(&(struct proc_dir_entry) {
-		PROC_NET_IPX, 3, "ipx",
-		S_IFREG | S_IRUGO, 1, 0, 0,
-		0, &proc_net_inode_operations,
-		ipx_get_info
-	});
-	proc_net_register(&(struct proc_dir_entry) {
-		PROC_NET_IPX_INTERFACE, 13, "ipx_interface",
-		S_IFREG | S_IRUGO, 1, 0, 0,
-		0, &proc_net_inode_operations,
-		ipx_interface_get_info
-	});
-	proc_net_register(&(struct proc_dir_entry) {
-		PROC_NET_IPX_ROUTE, 9, "ipx_route",
-		S_IFREG | S_IRUGO, 1, 0, 0,
-		0, &proc_net_inode_operations,
-		ipx_rt_get_info
-	});
+	proc_net_register(&ipx_procinfo);
+	proc_net_register(&ipx_if_procinfo);
+	proc_net_register(&ipx_rt_procinfo);
 		
 	printk("Swansea University Computer Society IPX 0.33 for NET3.032\n");
 	printk("IPX Portions Copyright (c) 1995 Caldera, Inc.\n");
 }
-#endif
+
+#ifdef MODULE
+/* Note on MOD_{INC,DEC}_USE_COUNT:
+ *
+ * Use counts are incremented/decremented when
+ * sockets are created/deleted.
+ * 
+ * Routes are always associated with an interface, and
+ * allocs/frees will remain properly accounted for by
+ * their associated interfaces.
+ * 
+ * Ergo, before the ipx module can be removed, all IPX
+ * sockets be closed from user space. 
+ */
+
+static void
+ipx_proto_finito(void)
+{	ipx_interface	*ifc;
+
+	while (ipx_interfaces) {
+		ifc = ipx_interfaces;
+		ipx_interfaces = ifc->if_next;
+		ifc->if_next = NULL;
+		ipxitf_down(ifc);
+	}
+
+	proc_net_unregister(PROC_NET_IPX_ROUTE);
+	proc_net_unregister(PROC_NET_IPX_INTERFACE);
+	proc_net_unregister(PROC_NET_IPX);
+
+	unregister_netdevice_notifier(&ipx_dev_notifier);
+
+	unregister_snap_client(ipx_snap_id);
+	pSNAP_datalink = NULL;
+
+	unregister_8022_client(ipx_8022_type);
+	p8022_datalink = NULL;
+
+	dev_remove_pack(&ipx_8023_packet_type);
+	destroy_8023_client(p8023_datalink);
+	p8023_datalink = NULL;
+
+	dev_remove_pack(&ipx_dix_packet_type);
+	destroy_EII_client(pEII_datalink);
+	pEII_datalink = NULL;
+
+	(void) sock_unregister(ipx_proto_ops.family);
+
+	return;
+}
+
+int init_module(void)
+{
+	ipx_proto_init(NULL);
+	register_symtab(0);
+	return 0;
+}
+
+void cleanup_module(void)
+{
+	ipx_proto_finito();
+	return;
+}
+#endif /* def MODULE */
--- linux/net/Makefile-	Wed Nov  8 05:40:50 1995
+++ linux/net/Makefile	Wed Mar 20 20:40:40 1996
@@ -10,6 +10,7 @@
 MOD_SUB_DIRS := ipv4
 ALL_SUB_DIRS := 802 ax25 core ethernet ipv4 ipx unix appletalk netrom
 SUB_DIRS     := 802 core ethernet unix
+MOD_LIST_NAME := NET_MISC_MODULES
 
 ifeq ($(CONFIG_INET),y)
 SUB_DIRS += ipv4
@@ -17,10 +18,18 @@
 
 ifeq ($(CONFIG_IPX),y)
 SUB_DIRS += ipx
+else
+  ifeq ($(CONFIG_IPX),m)
+  MOD_SUB_DIRS += ipx
+  endif
 endif
 
 ifeq ($(CONFIG_ATALK),y)
 SUB_DIRS += appletalk
+else
+  ifeq ($(CONFIG_ATALK),m)
+  MOD_SUB_DIRS += appletalk
+  endif
 endif
 
 ifeq ($(CONFIG_NETROM),y)
@@ -32,7 +41,7 @@
 endif
 
 L_TARGET     := network.a
-L_OBJS	     := socket.o protocols.o $(join $(SUB_DIRS),$(SUB_DIRS:%=/%.o))
+L_OBJS	     := netsyms.o socket.o protocols.o $(join $(SUB_DIRS),$(SUB_DIRS:%=/%.o))
 M_OBJS	     :=
 
 ifeq ($(CONFIG_NETLINK),y)
--- linux/net/Config.in-	Wed Feb  7 01:55:43 1996
+++ linux/net/Config.in	Tue Mar 19 16:00:19 1996
@@ -10,11 +10,11 @@
   source net/ipv4/Config.in
 fi
 comment ' '
-bool 'The IPX protocol' CONFIG_IPX
-if [ "$CONFIG_IPX" = "y" ]; then
+tristate 'The IPX protocol' CONFIG_IPX
+if [ ! "$CONFIG_IPX" = "n" ]; then
   bool 'Full internal IPX network' CONFIG_IPX_INTERN
 fi
-bool 'Appletalk DDP' CONFIG_ATALK
+tristate 'Appletalk DDP' CONFIG_ATALK
 bool 'Amateur Radio AX.25 Level 2' CONFIG_AX25
 if [ "$CONFIG_AX25" = "y" ]; then
   bool 'AX.25 over Ethernet' CONFIG_BPQETHER
--- linux/net/protocols.c-	Mon Mar  4 03:37:53 1996
+++ linux/net/protocols.c	Wed Mar 20 19:10:37 1996
@@ -18,7 +18,7 @@
 #ifdef	CONFIG_INET
 #include <linux/inet.h>
 #endif
-#ifdef CONFIG_IPX
+#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE)
 #include <net/ipxcall.h>
 #include <net/p8022call.h>
 #endif
@@ -28,8 +28,8 @@
 #include <net/nrcall.h>
 #endif
 #endif
-#ifdef CONFIG_ATALK
-#ifndef CONFIG_IPX
+#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE)
+#if ! ( defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE) )
 #include <net/p8022call.h>
 #endif
 #include <net/atalkcall.h>
@@ -48,7 +48,8 @@
 #ifdef	CONFIG_UNIX
   { "UNIX",	unix_proto_init	},			/* Unix domain socket family 	*/
 #endif
-#if defined(CONFIG_IPX)||defined(CONFIG_ATALK)  
+#if defined(CONFIG_IPX)   || defined(CONFIG_IPX_MODULE) || \
+    defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE)
   { "802.2",	p8022_proto_init },			/* 802.2 demultiplexor		*/
   { "SNAP",	snap_proto_init },			/* SNAP demultiplexor		*/
 #endif
@@ -72,5 +73,3 @@
 #endif
   { NULL,	NULL		}			/* End marker			*/
 };
-
-
--- linux/net/socket.c-	Tue Mar 19 15:12:53 1996
+++ linux/net/socket.c	Wed Mar 20 20:23:29 1996
@@ -33,6 +33,7 @@
  *					for NetROM and future kernel nfsd type
  *					stuff.
  *		Alan Cox	:	sendmsg/recvmsg basics.
+ *		Tom Dyas	:	Export net symbols.
  *
  *
  *		This program is free software; you can redistribute it and/or
@@ -64,12 +65,15 @@
 #include <linux/netdevice.h>
 #include <linux/proc_fs.h>
 #include <linux/firewall.h>
+#include <linux/kerneld.h>
 
 #include <net/netlink.h>
 
 #include <asm/system.h>
 #include <asm/segment.h>
 
+extern void export_net_symbols(void);
+
 static int sock_lseek(struct inode *inode, struct file *file, off_t offset,
 		      int whence);
 static int sock_read(struct inode *inode, struct file *file, char *buf,
@@ -506,6 +510,19 @@
  *	family, then create a fresh socket.
  */
 
+static int find_protocol_family(int family)
+{
+	register int i;
+	for (i = 0; i < NPROTO; i++)
+	{
+		if (pops[i] == NULL)
+			continue;
+		if (pops[i]->family == family)
+			return i;
+	}
+	return -1;
+}
+
 asmlinkage int sys_socket(int family, int type, int protocol)
 {
 	int i, fd;
@@ -513,14 +530,20 @@
 	struct proto_ops *ops;
 
 	/* Locate the correct protocol family. */
-	for (i = 0; i < NPROTO; ++i) 
-	{
-		if (pops[i] == NULL) continue;
-		if (pops[i]->family == family) 
-			break;
+	i = find_protocol_family(family);
+
+#ifdef CONFIG_KERNELD
+	/* Attempt to load a protocol module if the find failed. */
+	if (i < 0)
+	{
+		char module_name[30];
+		sprintf(module_name,"net-pf-%d",family);
+		request_module(module_name);
+		i = find_protocol_family(family);
 	}
+#endif
 
-	if (i == NPROTO) 
+	if (i < 0)
 	{
   		return -EINVAL;
 	}
@@ -1383,6 +1406,12 @@
 	 */
 
 	proto_init();
+
+	/*
+	 *	Export networking symbols to the world.
+	 */
+
+	export_net_symbols();
 }
 
 int socket_get_info(char *buffer, char **start, off_t offset, int length)
--- linux/net/netsyms.c-	Tue Mar 19 15:58:24 1996
+++ linux/net/netsyms.c	Wed Mar 20 20:29:45 1996
@@ -0,0 +1,173 @@
+/*
+ *  linux/net/netsyms.c
+ *
+ *  Symbol table for the linux networking subsystem. Moved here to
+ *  make life simpler in ksyms.c.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/in.h>
+#include <linux/net.h>
+#include <linux/netdevice.h>
+#include <linux/firewall.h>
+#include <linux/trdevice.h>
+#include <linux/ioport.h>
+
+#ifdef CONFIG_AX25
+#include <net/ax25.h>
+#endif
+
+#ifdef CONFIG_INET
+#include <linux/ip.h>
+#include <linux/etherdevice.h>
+#include <net/protocol.h>
+#include <net/arp.h>
+#include <net/ip.h>
+#include <net/udp.h>
+#include <net/tcp.h>
+#include <net/icmp.h>
+#include <net/route.h>
+#include <linux/net_alias.h>
+#endif
+
+#ifdef CONFIG_NET_ALIAS
+#include <linux/net_alias.h>
+#endif
+
+#if     defined(CONFIG_ULTRA)   ||      defined(CONFIG_WD80x3)          || \
+        defined(CONFIG_EL2)     ||      defined(CONFIG_NE2000)          || \
+        defined(CONFIG_E2100)   ||      defined(CONFIG_HPLAN_PLUS)      || \
+        defined(CONFIG_HPLAN)   ||      defined(CONFIG_AC3200)
+#include "../drivers/net/8390.h"
+#endif
+
+extern int (*rarp_ioctl_hook)(int,void*);
+
+#ifdef CONFIG_IPX_MODULE
+extern struct datalink_proto   *make_EII_client(void);
+extern struct datalink_proto   *make_8023_client(void);
+extern void destroy_EII_client(struct datalink_proto *);
+extern void destroy_8023_client(struct datalink_proto *);
+#endif
+
+
+static struct symbol_table net_syms = {
+#include <linux/symtab_begin.h>
+
+        /* Socket layer registration */
+        X(sock_register),
+        X(sock_unregister),
+
+        /* Socket layer support routines */
+	X(memcpy_fromiovec),
+	X(sock_setsockopt),
+	X(sock_getsockopt),
+	X(sock_wake_async),
+	X(sock_alloc_send_skb),
+	X(skb_recv_datagram),
+	X(skb_free_datagram),
+	X(skb_copy_datagram),
+	X(skb_copy_datagram_iovec),
+	X(datagram_select),
+
+#ifdef CONFIG_IPX_MODULE
+	X(make_8023_client),
+	X(destroy_8023_client),
+	X(make_EII_client),
+	X(destroy_EII_client),
+#endif
+
+#ifdef CONFIG_FIREWALL
+	/* Firewall registration */
+	X(register_firewall),
+	X(unregister_firewall),
+#endif
+
+#ifdef CONFIG_INET
+	/* Internet layer registration */
+	X(inet_add_protocol),
+	X(inet_del_protocol),
+	X(rarp_ioctl_hook),
+	X(init_etherdev),
+	X(ip_rt_route),
+	X(icmp_send),
+	X(ip_options_compile),
+	X(ip_rt_put),
+	X(arp_send),
+#ifdef CONFIG_IP_FORWARD
+	X(ip_forward),
+#endif
+
+#if	defined(CONFIG_ULTRA)	||	defined(CONFIG_WD80x3)		|| \
+	defined(CONFIG_EL2)	||	defined(CONFIG_NE2000)		|| \
+	defined(CONFIG_E2100)	||	defined(CONFIG_HPLAN_PLUS)	|| \
+	defined(CONFIG_HPLAN)	||	defined(CONFIG_AC3200)
+	/* If 8390 NIC support is built in, we will need these. */
+	X(ei_open),
+	X(ei_close),
+	X(ei_debug),
+	X(ei_interrupt),
+	X(ethdev_init),
+	X(NS8390_init),
+#endif
+
+#ifdef CONFIG_NET_ALIAS
+#include <linux/net_alias.h>
+#endif
+
+#endif  /* CONFIG_INET */
+
+	/* Device callback registration */
+	X(register_netdevice_notifier),
+	X(unregister_netdevice_notifier),
+
+#ifdef CONFIG_NET_ALIAS
+	X(register_net_alias_type),
+	X(unregister_net_alias_type),
+#endif
+
+        /* support for loadable net drivers */
+#ifdef CONFIG_AX25
+	X(ax25_encapsulate),
+	X(ax25_rebuild_header),
+#endif
+#ifdef CONFIG_INET
+	X(register_netdev),
+	X(unregister_netdev),
+	X(ether_setup),
+	X(eth_type_trans),
+	X(eth_copy_and_sum),
+	X(alloc_skb),
+	X(kfree_skb),
+	X(skb_clone),
+	X(dev_alloc_skb),
+	X(dev_kfree_skb),
+	X(netif_rx),
+	X(dev_tint),
+	X(irq2dev_map),
+	X(dev_add_pack),
+	X(dev_remove_pack),
+	X(dev_get),
+	X(dev_ioctl),
+	X(dev_queue_xmit),
+	X(dev_base),
+	X(dev_close),
+	X(dev_mc_add),
+	X(arp_find),
+	X(n_tty_ioctl),
+	X(tty_register_ldisc),
+	X(kill_fasync),
+#ifdef CONFIG_FIREWALL
+	X(call_in_firewall),
+#endif
+#endif  /* CONFIG_INET */
+
+#include <linux/symtab_end.h>
+};
+
+void export_net_symbols(void)
+{
+	register_symtab(&net_syms);
+}
--- linux/scripts/Configure-	Thu Feb 22 07:40:02 1996
+++ linux/scripts/Configure	Wed Mar 20 18:40:46 1996
@@ -39,6 +39,9 @@
 #
 # 150296 Dick Streefland (dicks@tasking.nl) - report new configuration
 # items and ask for a value even when doing a "make oldconfig"
+#
+# 200396 Tom Dyas (tdyas@eden.rutgers.edu) - when the module option is
+# chosen for an item, define the macro <option_name>_MODULE
 
 #
 # Make sure we're really running bash.
@@ -141,6 +144,7 @@
 	 "m")
 		echo "$1=m" >>$CONFIG
 		echo "#undef  $1" >>$CONFIG_H
+		echo "#define $1_MODULE 1" >>$CONFIG_H
 		;;
 
 	 "n")


home help back first fref pref prev next nref lref last post