[2120] in linux-net channel archive
appletalk module
daemon@ATHENA.MIT.EDU (Tom Dyas)
Fri Mar 15 23:59:44 1996
Date: Fri, 15 Mar 96 23:52:04 EST
From: Tom Dyas <tdyas@eden.rutgers.edu>
To: linux-net@vger.rutgers.edu
The patch attached to the end of message allows the appletalk code to
be compiled as a module. The patch was made against kernel 1.3.74.
The usage count should be correct. It is incremented when a socket is
made and only decremented when the memory for the socket struct is
freed. Since all access to the protocol code goes through a socket in
some way (ioctl or otherwise), this should keep the usage count
correct.
I did encounter one problem which is more general than modularizing
appltetalk. Code in one subsystem (spec. the SNAP code) that is
conditionally compiled based on the inclusion of entirely separate
subsystem (the atalk code) may not be included because the CONFIG_*
macros will not be defined for a module.
The solution is to have a macro defined when something is a
module. Thus, I had to change the Configure script to define a macro
called M_ plus the normal macro name when something is made a
module. This problem has also been mentioned on the kernel list I
think in form of the call to slhc_install().
I would be grateful if somebody who uses AppleTalk could test this
patch out.
Tom
--------------- atalk.module-1.3.74.diff
--- linux/kernel/ksyms.c.orig Fri Mar 15 21:17:52 1996
+++ linux/kernel/ksyms.c Fri Mar 15 21:38:06 1996
@@ -54,6 +54,7 @@
#include <linux/netdevice.h>
#include <linux/firewall.h>
#include <linux/trdevice.h>
+#include <net/psnap.h>
#ifdef CONFIG_AX25
#include <net/ax25.h>
@@ -341,12 +342,20 @@
/* 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),
+ X(register_snap_client),
+ X(unregister_snap_client),
#ifdef CONFIG_FIREWALL
/* Firewall registration */
X(register_firewall),
@@ -417,6 +426,7 @@
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),
--- linux/include/linux/atalk.h.orig Fri Mar 1 00:22:56 1996
+++ linux/include/linux/atalk.h Fri Mar 15 21:38:06 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/psnap.h.orig Tue Jun 6 04:22:18 1995
+++ linux/include/net/psnap.h Fri Mar 15 21:38:06 1996
@@ -1,2 +1,3 @@
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);
--- linux/include/net/sock.h.orig Fri Mar 8 08:53:58 1996
+++ linux/include/net/sock.h Fri Mar 15 23:06:02 1996
@@ -49,9 +49,7 @@
#ifdef CONFIG_IPX
#include <net/ipx.h>
#endif
-#ifdef CONFIG_ATALK
#include <linux/atalk.h>
-#endif
#include <linux/igmp.h>
@@ -259,9 +257,7 @@
union
{
struct unix_opt af_unix;
-#ifdef CONFIG_ATALK
struct atalk_sock af_at;
-#endif
#ifdef CONFIG_IPX
struct ipx_opt af_ipx;
#endif
--- linux/net/802/psnap.c.orig Thu Jul 27 12:34:36 1995
+++ linux/net/802/psnap.c Fri Mar 15 22:24:31 1996
@@ -116,3 +116,30 @@
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/appletalk/aarp.c.orig Fri Mar 15 21:17:53 1996
+++ linux/net/appletalk/aarp.c Fri Mar 15 21:38:06 1996
@@ -49,7 +49,6 @@
#include <net/psnap.h>
#include <linux/atalk.h>
-#ifdef CONFIG_ATALK
/*
* Lists of aarp entries
*/
@@ -790,10 +789,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 +803,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.orig Fri Mar 15 21:17:53 1996
+++ linux/net/appletalk/ddp.c Fri Mar 15 21:38:07 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 from the given list. */
+static void free_route_list(struct atalk_route *ptr)
+{
+ struct atalk_route *tmp;
+
+ while (ptr != NULL)
+ {
+ tmp = ptr->next;
+ kfree_s(ptr, sizeof(struct atalk_route));
+ ptr = tmp;
+ }
+}
+
+/* Remove all interface entries from the given list. */
+static void free_interface_list(struct atalk_iface *ptr)
+{
+ struct atalk_iface *tmp;
+
+ while (ptr != NULL)
+ {
+ tmp = ptr->next;
+ kfree_s(ptr, sizeof(struct atalk_iface));
+ ptr = 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(<alk_packet_type);
+ unregister_snap_client(ddp_snap_id);
+ sock_unregister(atalk_proto_ops.family);
+
+ free_route_list(atalk_router_list);
+ free_interface_list(atalk_iface_list);
+
+ restore_flags(flags);
+}
+
+#endif /* MODULE */
--- linux/net/appletalk/Makefile.orig Tue Aug 15 08:07:03 1995
+++ linux/net/appletalk/Makefile Fri Mar 15 21:38:07 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/Makefile.orig Wed Nov 8 05:40:50 1995
+++ linux/net/Makefile Fri Mar 15 21:38:07 1996
@@ -21,6 +21,10 @@
ifeq ($(CONFIG_ATALK),y)
SUB_DIRS += appletalk
+else
+ ifeq ($(CONFIG_ATALK),m)
+ MOD_SUB_DIRS := appletalk
+ endif
endif
ifeq ($(CONFIG_NETROM),y)
--- linux/net/Config.in.orig Wed Feb 7 01:55:43 1996
+++ linux/net/Config.in Fri Mar 15 21:38:07 1996
@@ -14,7 +14,7 @@
if [ "$CONFIG_IPX" = "y" ]; 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.orig Fri Mar 15 23:03:53 1996
+++ linux/net/protocols.c Fri Mar 15 23:09:18 1996
@@ -28,7 +28,7 @@
#include <net/nrcall.h>
#endif
#endif
-#ifdef CONFIG_ATALK
+#if defined(CONFIG_ATALK) || defined(M_CONFIG_ATALK)
#ifndef CONFIG_IPX
#include <net/p8022call.h>
#endif
@@ -48,7 +48,7 @@
#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_ATALK)||defined(M_CONFIG_ATALK)
{ "802.2", p8022_proto_init }, /* 802.2 demultiplexor */
{ "SNAP", snap_proto_init }, /* SNAP demultiplexor */
#endif
--- linux/scripts/Configure.orig Fri Mar 15 22:59:51 1996
+++ linux/scripts/Configure Fri Mar 15 23:03:19 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"
+#
+# 150396 Tom Dyas (tdyas@eden.rutgers.edu) - define the macro M_* when
+# the user chooses to make somthing a module
#
# Make sure we're really running bash.
@@ -141,6 +144,7 @@
"m")
echo "$1=m" >>$CONFIG
echo "#undef $1" >>$CONFIG_H
+ echo "#define M_$1 1" >>$CONFIG_H
;;
"n")