Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[PATCH] sockreg2.4.5-05 inet[6]_create() register/unregister table

0 views
Skip to first unread message

La Monte H.P. Yarroll

unread,
Jun 5, 2001, 1:03:18 PM6/5/01
to
Here is the register/unregister inet[6]_create() table patch revised
for 2.4.5. We thank Dave Miller for his helpful feedback on earlier
versions of this patch.

DESCRIPTION
This patch adds a mechanism for registering new IP transport protocols
for the socket() system call. It replaces the hard-coded switch
tables in inet_create() and inet6_create() with explicit data
structures.

The new calls are:
void inet_register_protosw(struct inet_protosw *p);
void inet_unregister_protosw(struct inet_protosw *p);
void inet6_register_protosw(struct inet_protosw *p);
void inet6_unregister_protosw(struct inet_protosw *p);

This is the first of a series of proposed changes to support IP
transport modules.

MOTIVATION
As part of the effort to create the Linux Kernel implementation of
SCTP <www.sourceforge.net/projects/lksctp>, we seek to make it
possible to load a new IP transport protocol as a kernel module.

It is already possible to register new address families. It is even
possible to register new transport protocols with IP. However, in
order to be able to open a socket with a new transport protocol, you
must replace the whole AF_INET address family.

In addition to SCTP, there are other protocols which could find it
useful to be in a kernel module. For example, TCP extensions like TCP
framing and TCP over satellite, multicast protocols, and RTP/ROHC
(robust header compression). In general, support for IP transport
modules makes transport layer experimentation easier.

CHANGES SINCE sockreg2.4.3-04
We noticed that inet6_protocol_base went away in 2.4.5, so we changed
our v6 initialization to parallel the inet6_protocol initialization.
We now call inet6_register_protosw() from *v6_init() instead of having
a static array of struct protosw's. Since other protocols depend on
raw sockets (e.g. ICMP, IGMP, NDISC) we still register rawv6_protosw
in inet6_init().

piggy (La Monte H.P. Yarroll)
Karl O. Knutson

PATCH FOLLOWS
diff -u -r linux-2.4.5/include/asm-alpha/socket.h linux/include/asm-alpha/socket.h
--- linux-2.4.5/include/asm-alpha/socket.h Sat Feb 3 13:26:44 2001
+++ linux/include/asm-alpha/socket.h Mon Jun 4 11:11:30 2001
@@ -66,6 +66,7 @@
/* level. For writing rarp and */
/* other similar things on the */
/* user level. */
+#define SOCK_MAX (SOCK_PACKET+1)
#endif

#endif /* _ASM_SOCKET_H */
diff -u -r linux-2.4.5/include/asm-arm/socket.h linux/include/asm-arm/socket.h
--- linux-2.4.5/include/asm-arm/socket.h Sat Feb 3 13:26:44 2001
+++ linux/include/asm-arm/socket.h Mon Jun 4 11:11:30 2001
@@ -58,6 +58,7 @@
/* level. For writing rarp and */
/* other similar things on the */
/* user level. */
+#define SOCK_MAX (SOCK_PACKET+1)
#endif

#endif /* _ASM_SOCKET_H */
diff -u -r linux-2.4.5/include/asm-cris/socket.h linux/include/asm-cris/socket.h
--- linux-2.4.5/include/asm-cris/socket.h Fri Apr 6 12:51:19 2001
+++ linux/include/asm-cris/socket.h Mon Jun 4 11:11:30 2001
@@ -59,6 +59,7 @@
/* level. For writing rarp and */
/* other similar things on the */
/* user level. */
+#define SOCK_MAX (SOCK_PACKET+1)
#endif

#endif /* _ASM_SOCKET_H */
diff -u -r linux-2.4.5/include/asm-i386/socket.h linux/include/asm-i386/socket.h
--- linux-2.4.5/include/asm-i386/socket.h Sat Feb 3 13:26:44 2001
+++ linux/include/asm-i386/socket.h Mon Jun 4 11:11:30 2001
@@ -58,6 +58,7 @@
/* level. For writing rarp and */
/* other similar things on the */
/* user level. */
+#define SOCK_MAX (SOCK_PACKET+1)
#endif

#endif /* _ASM_SOCKET_H */
diff -u -r linux-2.4.5/include/asm-ia64/socket.h linux/include/asm-ia64/socket.h
--- linux-2.4.5/include/asm-ia64/socket.h Sat Feb 3 13:26:44 2001
+++ linux/include/asm-ia64/socket.h Mon Jun 4 11:11:30 2001
@@ -65,6 +65,7 @@
/* level. For writing rarp and */
/* other similar things on the */
/* user level. */
+#define SOCK_MAX (SOCK_PACKET+1)
#endif

#endif /* _ASM_IA64_SOCKET_H */
diff -u -r linux-2.4.5/include/asm-m68k/socket.h linux/include/asm-m68k/socket.h
--- linux-2.4.5/include/asm-m68k/socket.h Sat Feb 3 13:26:44 2001
+++ linux/include/asm-m68k/socket.h Mon Jun 4 11:11:30 2001
@@ -58,6 +58,7 @@
/* level. For writing rarp and */
/* other similar things on the */
/* user level. */
+#define SOCK_MAX (SOCK_PACKET+1)
#endif

#endif /* _ASM_SOCKET_H */
diff -u -r linux-2.4.5/include/asm-mips/socket.h linux/include/asm-mips/socket.h
--- linux-2.4.5/include/asm-mips/socket.h Sat Feb 3 13:26:44 2001
+++ linux/include/asm-mips/socket.h Mon Jun 4 11:11:30 2001
@@ -71,6 +71,7 @@
/* level. For writing rarp and */
/* other similar things on the */
/* user level. */
+#define SOCK_MAX (SOCK_PACKET+1)
#endif

#endif /* _ASM_SOCKET_H */
diff -u -r linux-2.4.5/include/asm-mips64/socket.h linux/include/asm-mips64/socket.h
--- linux-2.4.5/include/asm-mips64/socket.h Sat Feb 3 13:26:44 2001
+++ linux/include/asm-mips64/socket.h Mon Jun 4 11:11:30 2001
@@ -79,6 +79,7 @@
/* level. For writing rarp and */
/* other similar things on the */
/* user level. */
+#define SOCK_MAX (SOCK_PACKET+1)
#endif

#endif /* _ASM_SOCKET_H */
diff -u -r linux-2.4.5/include/asm-parisc/socket.h linux/include/asm-parisc/socket.h
--- linux-2.4.5/include/asm-parisc/socket.h Sat Feb 3 13:26:44 2001
+++ linux/include/asm-parisc/socket.h Mon Jun 4 11:11:30 2001
@@ -56,6 +56,7 @@
/* level. For writing rarp and */
/* other similar things on the */
/* user level. */
+#define SOCK_MAX (SOCK_PACKET+1)
#endif

#endif /* _ASM_SOCKET_H */
diff -u -r linux-2.4.5/include/asm-ppc/socket.h linux/include/asm-ppc/socket.h
--- linux-2.4.5/include/asm-ppc/socket.h Mon May 21 17:02:06 2001
+++ linux/include/asm-ppc/socket.h Mon Jun 4 11:11:30 2001
@@ -67,6 +67,7 @@
/* level. For writing rarp and */
/* other similar things on the */
/* user level. */
+#define SOCK_MAX (SOCK_PACKET+1)
#endif

#endif /* _ASM_SOCKET_H */
diff -u -r linux-2.4.5/include/asm-s390/socket.h linux/include/asm-s390/socket.h
--- linux-2.4.5/include/asm-s390/socket.h Sat Feb 3 13:26:44 2001
+++ linux/include/asm-s390/socket.h Mon Jun 4 11:11:30 2001
@@ -66,6 +66,7 @@
/* level. For writing rarp and */
/* other similar things on the */
/* user level. */
+#define SOCK_MAX (SOCK_PACKET+1)
#endif

#endif /* _ASM_SOCKET_H */
diff -u -r linux-2.4.5/include/asm-s390x/socket.h linux/include/asm-s390x/socket.h
--- linux-2.4.5/include/asm-s390x/socket.h Fri Mar 2 13:12:06 2001
+++ linux/include/asm-s390x/socket.h Mon Jun 4 11:11:30 2001
@@ -65,6 +65,7 @@
/* level. For writing rarp and */
/* other similar things on the */
/* user level. */
+#define SOCK_MAX (SOCK_PACKET+1)
#endif

#endif /* _ASM_SOCKET_H */
diff -u -r linux-2.4.5/include/asm-sh/socket.h linux/include/asm-sh/socket.h
--- linux-2.4.5/include/asm-sh/socket.h Sat Feb 3 13:26:44 2001
+++ linux/include/asm-sh/socket.h Mon Jun 4 11:11:30 2001
@@ -58,6 +58,7 @@
/* level. For writing rarp and */
/* other similar things on the */
/* user level. */
+#define SOCK_MAX (SOCK_PACKET+1)
#endif

#endif /* __ASM_SH_SOCKET_H */
diff -u -r linux-2.4.5/include/asm-sparc/socket.h linux/include/asm-sparc/socket.h
--- linux-2.4.5/include/asm-sparc/socket.h Sat Feb 3 13:26:44 2001
+++ linux/include/asm-sparc/socket.h Mon Jun 4 11:11:30 2001
@@ -63,6 +63,7 @@
/* level. For writing rarp and */
/* other similar things on the */
/* user level. */
+#define SOCK_MAX (SOCK_PACKET+1)
#endif

#endif /* _ASM_SOCKET_H */
diff -u -r linux-2.4.5/include/asm-sparc64/socket.h linux/include/asm-sparc64/socket.h
--- linux-2.4.5/include/asm-sparc64/socket.h Sat Feb 3 13:26:44 2001
+++ linux/include/asm-sparc64/socket.h Mon Jun 4 11:11:30 2001
@@ -63,6 +63,7 @@
/* level. For writing rarp and */
/* other similar things on the */
/* user level. */
+#define SOCK_MAX (SOCK_PACKET+1)
#endif

#endif /* _ASM_SOCKET_H */
diff -u -r linux-2.4.5/include/net/protocol.h linux/include/net/protocol.h
--- linux-2.4.5/include/net/protocol.h Fri May 25 20:01:27 2001
+++ linux/include/net/protocol.h Mon Jun 4 18:28:00 2001
@@ -63,19 +63,45 @@

#endif

+/* This is used to register socket interfaces for IP protocols. */
+struct inet_protosw {
+ struct list_head list;
+
+ /* These two fields form the lookup key. */
+ unsigned short type; /* This is the 2nd argument to socket(2). */
+ int protocol; /* This is the L4 protocol number. */
+
+ struct proto *prot;
+ struct proto_ops *ops;
+
+ char no_check; /* checksum on rcv/xmit/none? */
+ unsigned char reuse; /* Are ports automatically reusable? */
+ int capability; /* Which (if any) capability do
+ * we need to use this socket
+ * interface?
+ */
+};
+
+
extern struct inet_protocol *inet_protocol_base;
extern struct inet_protocol *inet_protos[MAX_INET_PROTOS];
+extern struct list_head inetsw[SOCK_MAX];

#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
extern struct inet6_protocol *inet6_protos[MAX_INET_PROTOS];
+extern struct list_head inetsw6[SOCK_MAX];
#endif

extern void inet_add_protocol(struct inet_protocol *prot);
extern int inet_del_protocol(struct inet_protocol *prot);
+extern void inet_register_protosw(struct inet_protosw *p);
+extern void inet_unregister_protosw(struct inet_protosw *p);

#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
extern void inet6_add_protocol(struct inet6_protocol *prot);
extern int inet6_del_protocol(struct inet6_protocol *prot);
+extern void inet6_register_protosw(struct inet_protosw *p);
+extern void inet6_unregister_protosw(struct inet_protosw *p);
#endif

#endif /* _PROTOCOL_H */
diff -u -r linux-2.4.5/net/ipv4/af_inet.c linux/net/ipv4/af_inet.c
--- linux-2.4.5/net/ipv4/af_inet.c Tue May 1 22:59:24 2001
+++ linux/net/ipv4/af_inet.c Mon Jun 4 11:16:27 2001
@@ -14,6 +14,8 @@
*
* Changes (see also sock.c)
*
+ * piggy,
+ * Karl Knutson : Socket protocol table
* A.N.Kuznetsov : Socket death error in accept().
* John Richardson : Fix non blocking error in connect()
* so sockets that fail to connect
@@ -88,6 +90,7 @@
#include <linux/smp_lock.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
+#include <linux/brlock.h>
#include <net/ip.h>
#include <net/protocol.h>
#include <net/arp.h>
@@ -142,6 +145,11 @@
int (*br_ioctl_hook)(unsigned long);
#endif

+/* The inetsw table contains everything that inet_create needs to
+ * build a new socket.
+ */
+struct list_head inetsw[SOCK_MAX];
+
/* New destruction routine */

void inet_sock_destruct(struct sock *sk)
@@ -309,46 +317,56 @@
static int inet_create(struct socket *sock, int protocol)
{
struct sock *sk;
- struct proto *prot;
+ struct list_head *p;
+ struct inet_protosw *answer;

sock->state = SS_UNCONNECTED;
sk = sk_alloc(PF_INET, GFP_KERNEL, 1);
if (sk == NULL)
goto do_oom;
-
- switch (sock->type) {
- case SOCK_STREAM:
- if (protocol && protocol != IPPROTO_TCP)
- goto free_and_noproto;
- protocol = IPPROTO_TCP;
- prot = &tcp_prot;
- sock->ops = &inet_stream_ops;
- break;
- case SOCK_SEQPACKET:
- goto free_and_badtype;
- case SOCK_DGRAM:
- if (protocol && protocol != IPPROTO_UDP)
- goto free_and_noproto;
- protocol = IPPROTO_UDP;
- sk->no_check = UDP_CSUM_DEFAULT;
- prot=&udp_prot;
- sock->ops = &inet_dgram_ops;
- break;
- case SOCK_RAW:
- if (!capable(CAP_NET_RAW))
- goto free_and_badperm;
- if (!protocol)
- goto free_and_noproto;
- prot = &raw_prot;
- sk->reuse = 1;
- sk->num = protocol;
- sock->ops = &inet_dgram_ops;
- if (protocol == IPPROTO_RAW)
- sk->protinfo.af_inet.hdrincl = 1;
- break;
- default:
- goto free_and_badtype;
- }
+
+ /* Look for the requested type/protocol pair. */
+ answer = NULL;
+ br_read_lock_bh(BR_NETPROTO_LOCK);
+ list_for_each(p, &inetsw[sock->type]) {
+ answer = list_entry(p, struct inet_protosw, list);
+ /* Check the non-wild match. */
+ if (protocol == answer->protocol) {
+ if (protocol != IPPROTO_IP) {
+ break;
+ }
+ } else {
+ /* Check for the two wild cases. */
+ if (IPPROTO_IP == protocol) {
+ protocol = answer->protocol;
+ break;
+ }
+ if (IPPROTO_IP == answer->protocol) {
+ break;
+ }
+ }
+ answer = NULL;
+ }
+ br_read_unlock_bh(BR_NETPROTO_LOCK);
+
+ if (!answer)
+ goto free_and_badtype;
+ if (answer->capability > 0 && !capable(answer->capability))
+ goto free_and_badperm;
+ if (!protocol)
+ goto free_and_noproto;
+
+ sock->ops = answer->ops;
+ sk->prot = answer->prot;
+ sk->no_check = answer->no_check;
+ if (answer->reuse)
+ sk->reuse = answer->reuse;
+
+ if (SOCK_RAW == sock->type) {
+ sk->num = protocol;
+ if (IPPROTO_RAW == protocol)
+ sk->protinfo.af_inet.hdrincl = 1;
+ }

if (ipv4_config.no_pmtu_disc)
sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_DONT;
@@ -365,8 +383,7 @@
sk->family = PF_INET;
sk->protocol = protocol;

- sk->prot = prot;
- sk->backlog_rcv = prot->backlog_rcv;
+ sk->backlog_rcv = sk->prot->backlog_rcv;

sk->protinfo.af_inet.ttl = sysctl_ip_default_ttl;

@@ -969,6 +986,70 @@
extern void tcp_init(void);
extern void tcp_v4_init(struct net_proto_family *);

+/* Upon startup we insert all the elements in inetsw_array[] into
+ * the linked list inetsw.
+ */
+static struct inet_protosw inetsw_array[] =
+{
+ {
+ type: SOCK_STREAM,
+ protocol: IPPROTO_TCP,
+ prot: &tcp_prot,
+ ops: &inet_stream_ops,
+ no_check: 0,
+ reuse: 0,
+ capability: -1,
+ },
+
+ {
+ type: SOCK_DGRAM,
+ protocol: IPPROTO_UDP,
+ prot: &udp_prot,
+ ops: &inet_dgram_ops,
+ no_check: UDP_CSUM_DEFAULT,
+ reuse: 0,
+ capability: -1,
+ },
+
+
+ {
+ type: SOCK_RAW,
+ protocol: IPPROTO_IP, /* wild card */
+ prot: &raw_prot,
+ ops: &inet_dgram_ops,
+ no_check: UDP_CSUM_DEFAULT,
+ reuse: 1,
+ capability: CAP_NET_RAW,
+ }
+}; /* struct inet_protosw inetsw_array[] */
+
+#define INETSW_ARRAY_LEN (sizeof(inetsw_array) / sizeof(struct inet_protosw))
+
+void
+inet_register_protosw(struct inet_protosw *p)
+{
+ /* Add to the BEGINNING so that we override any existing
+ * entry. This means that when we remove this entry, the
+ * system automatically returns to the old behavior.
+ */
+ if (p->type < SOCK_MAX) {
+ br_write_lock_bh(BR_NETPROTO_LOCK);
+ list_add(&p->list, &inetsw[p->type]);
+ br_write_unlock_bh(BR_NETPROTO_LOCK);
+ } else {
+ printk(KERN_DEBUG "Ignoring attempt to register illegal socket type %d.\n",
+ p->type);
+ }
+} /* inet_protosw_register() */
+
+void
+inet_unregister_protosw(struct inet_protosw *p)
+{
+ br_write_lock_bh(BR_NETPROTO_LOCK);
+ list_del(&p->list);
+ br_write_unlock_bh(BR_NETPROTO_LOCK);
+} /* inet_protosw_unregister() */
+

/*
* Called by socket.c on kernel startup.
@@ -978,6 +1059,8 @@
{
struct sk_buff *dummy_skb;
struct inet_protocol *p;
+ struct inet_protosw *q;
+ struct list_head *r;

printk(KERN_INFO "NET4: Linux TCP/IP 1.0 for NET4.0\n");

@@ -1003,6 +1086,14 @@
printk("%s%s",p->name,tmp?", ":"\n");
p = tmp;
}
+
+ /* Register the socket-side information for inet_create. */
+ for(r = &inetsw[0]; r < &inetsw[SOCK_MAX]; ++r) {
+ INIT_LIST_HEAD(r);
+ }
+ for(q = inetsw_array; q < &inetsw_array[INETSW_ARRAY_LEN]; ++q) {
+ inet_register_protosw(q);
+ }

/*
* Set the ARP module up
diff -u -r linux-2.4.5/net/ipv6/af_inet6.c linux/net/ipv6/af_inet6.c
--- linux-2.4.5/net/ipv6/af_inet6.c Thu Apr 12 14:11:39 2001
+++ linux/net/ipv6/af_inet6.c Mon Jun 4 18:39:53 2001
@@ -10,6 +10,7 @@
* $Id: af_inet6.c,v 1.63 2001/03/02 03:13:05 davem Exp $
*
* Fixes:
+ * piggy, Karl Knutson : Socket protocol table
* Hideaki YOSHIFUJI : sin6_scope_id support
* Arnaldo Melo : check proc_net_create return, cleanups
*
@@ -44,6 +45,7 @@
#include <linux/inet.h>
#include <linux/netdevice.h>
#include <linux/icmpv6.h>
+#include <linux/brlock.h>
#include <linux/smp_lock.h>

#include <net/ip.h>
@@ -71,9 +73,6 @@
MODULE_PARM(unloadable, "i");
#endif

-extern struct proto_ops inet6_stream_ops;
-extern struct proto_ops inet6_dgram_ops;
-
/* IPv6 procfs goodies... */

#ifdef CONFIG_PROC_FS
@@ -93,6 +92,11 @@
atomic_t inet6_sock_nr;
#endif

+/* The inetsw table contains everything that inet_create needs to
+ * build a new socket.
+ */
+struct list_head inetsw6[SOCK_MAX];
+
static void inet6_sock_destruct(struct sock *sk)
{
inet_sock_destruct(sk);
@@ -106,47 +110,64 @@
static int inet6_create(struct socket *sock, int protocol)
{
struct sock *sk;
- struct proto *prot;
+ struct list_head *p;
+ struct inet_protosw *answer;

sk = sk_alloc(PF_INET6, GFP_KERNEL, 1);
if (sk == NULL)
goto do_oom;

- if(sock->type == SOCK_STREAM || sock->type == SOCK_SEQPACKET) {
- if (protocol && protocol != IPPROTO_TCP)
- goto free_and_noproto;
- protocol = IPPROTO_TCP;
- prot = &tcpv6_prot;
- sock->ops = &inet6_stream_ops;
- } else if(sock->type == SOCK_DGRAM) {
- if (protocol && protocol != IPPROTO_UDP)
- goto free_and_noproto;
- protocol = IPPROTO_UDP;
- sk->no_check = UDP_CSUM_DEFAULT;
- prot=&udpv6_prot;
- sock->ops = &inet6_dgram_ops;
- } else if(sock->type == SOCK_RAW) {
- if (!capable(CAP_NET_RAW))
- goto free_and_badperm;
- if (!protocol)
- goto free_and_noproto;
- prot = &rawv6_prot;
- sock->ops = &inet6_dgram_ops;
- sk->reuse = 1;
- sk->num = protocol;
- } else {
- goto free_and_badtype;
- }
-
+ /* Look for the requested type/protocol pair. */
+ answer = NULL;
+ br_read_lock_bh(BR_NETPROTO_LOCK);
+ list_for_each(p, &inetsw6[sock->type]) {
+ answer = list_entry(p, struct inet_protosw, list);
+ /* Check the non-wild match. */
+ if (protocol == answer->protocol) {
+ if (protocol != IPPROTO_IP) {
+ break;
+ }
+ } else {
+ /* Check for the two wild cases. */
+ if (IPPROTO_IP == protocol) {
+ protocol = answer->protocol;
+ break;
+ }
+ if (IPPROTO_IP == answer->protocol) {
+ break;
+ }
+ }
+ answer = NULL;
+ }
+ br_read_unlock_bh(BR_NETPROTO_LOCK);
+
+ if (!answer)
+ goto free_and_badtype;
+ if (answer->capability > 0 && !capable(answer->capability))
+ goto free_and_badperm;
+ if (!protocol)
+ goto free_and_noproto;
+
+ sock->ops = answer->ops;
sock_init_data(sock, sk);

+ sk->prot = answer->prot;
+ sk->no_check = answer->no_check;
+ if (answer->reuse)
+ sk->reuse = answer->reuse;
+
+ if (SOCK_RAW == sock->type) {
+ sk->num = protocol;
+ if (IPPROTO_RAW == protocol)
+ sk->protinfo.af_inet.hdrincl = 1;
+ }
+
sk->destruct = inet6_sock_destruct;
sk->zapped = 0;
sk->family = PF_INET6;
sk->protocol = protocol;

- sk->prot = prot;
- sk->backlog_rcv = prot->backlog_rcv;
+ sk->backlog_rcv = answer->prot->backlog_rcv;

sk->net_pinfo.af_inet6.hop_limit = -1;
sk->net_pinfo.af_inet6.mcast_hops = -1;
@@ -175,9 +196,6 @@
#endif
MOD_INC_USE_COUNT;

- if (sk->type==SOCK_RAW && protocol==IPPROTO_RAW)
- sk->protinfo.af_inet.hdrincl=1;
-
if (sk->num) {
/* It assumes that any protocol which allows
* the user to assign a number at socket
@@ -186,7 +204,6 @@
sk->sport = ntohs(sk->num);
sk->prot->hash(sk);
}
-
if (sk->prot->init) {
int err = sk->prot->init(sk);
if (err != 0) {
@@ -504,9 +521,47 @@
extern void ipv6_sysctl_unregister(void);
#endif

+static struct inet_protosw rawv6_protosw = {
+ type: SOCK_RAW,
+ protocol: IPPROTO_IP, /* wild card */
+ prot: &rawv6_prot,
+ ops: &inet6_dgram_ops,
+ no_check: UDP_CSUM_DEFAULT,
+ reuse: 1,
+ capability: CAP_NET_RAW,
+};
+
+#define INETSW6_ARRAY_LEN (sizeof(inetsw6_array) / sizeof(struct inet_protosw))
+
+void
+inet6_register_protosw(struct inet_protosw *p)
+{
+ /* Add to the BEGINNING so that we override any existing
+ * entry. This means that when we remove this entry, the
+ * system automatically returns to the old behavior.
+ */
+ if (p->type < SOCK_MAX) {
+ br_write_lock_bh(BR_NETPROTO_LOCK);
+ list_add(&p->list, &inetsw6[p->type]);
+ br_write_unlock_bh(BR_NETPROTO_LOCK);
+ } else {
+ printk(KERN_DEBUG "Ignoring attempt to register illegal socket type %d.\n",
+ p->type);
+ }
+} /* inet_protosw_register() */
+
+void
+inet6_unregister_protosw(struct inet_protosw *p)
+{
+ br_write_lock_bh(BR_NETPROTO_LOCK);
+ list_del(&p->list);
+ br_write_unlock_bh(BR_NETPROTO_LOCK);
+} /* inet_protosw_unregister() */
+
static int __init inet6_init(void)
{
struct sk_buff *dummy_skb;
+ struct list_head *r;
int err;

#ifdef MODULE
@@ -523,6 +578,16 @@
printk(KERN_CRIT "inet6_proto_init: size fault\n");
return -EINVAL;
}
+
+ /* Register the socket-side information for inet6_create. */
+ for(r = &inetsw6[0]; r < &inetsw6[SOCK_MAX]; ++r) {
+ INIT_LIST_HEAD(r);
+ }
+
+ /* We MUST register RAW sockets before we create the ICMP6,
+ * IGMP6, or NDISC control sockets.
+ */
+ inet6_register_protosw(&rawv6_protosw);

/*
* ipngwg API draft makes clear that the correct semantics
diff -u -r linux-2.4.5/net/ipv6/tcp_ipv6.c linux/net/ipv6/tcp_ipv6.c
--- linux-2.4.5/net/ipv6/tcp_ipv6.c Wed Apr 25 16:57:39 2001
+++ linux/net/ipv6/tcp_ipv6.c Mon Jun 4 18:35:31 2001
@@ -2125,8 +2125,21 @@
"TCPv6" /* name */
};

+extern struct proto_ops inet6_stream_ops;
+
+static struct inet_protosw tcpv6_protosw = {
+ type: SOCK_STREAM,
+ protocol: IPPROTO_TCP,
+ prot: &tcpv6_prot,
+ ops: &inet6_stream_ops,
+ no_check: 0,
+ reuse: 0,
+ capability: -1,
+};
+
void __init tcpv6_init(void)
{
/* register inet6 protocol */
inet6_add_protocol(&tcpv6_protocol);
+ inet6_register_protosw(&tcpv6_protosw);
}
diff -u -r linux-2.4.5/net/ipv6/udp.c linux/net/ipv6/udp.c
--- linux-2.4.5/net/ipv6/udp.c Thu Apr 12 14:11:39 2001
+++ linux/net/ipv6/udp.c Mon Jun 4 18:36:03 2001
@@ -992,7 +992,21 @@
get_port: udp_v6_get_port,
};

+extern struct proto_ops inet6_dgram_ops;
+
+static struct inet_protosw udpv6_protosw = {
+ type: SOCK_DGRAM,
+ protocol: IPPROTO_UDP,
+ prot: &udpv6_prot,
+ ops: &inet6_dgram_ops,
+ no_check: UDP_CSUM_DEFAULT,
+ reuse: 0,
+ capability: -1,
+};
+
+
void __init udpv6_init(void)
{
inet6_add_protocol(&udpv6_protocol);
+ inet6_register_protosw(&udpv6_protosw);
}
diff -u -r linux-2.4.5/net/netsyms.c linux/net/netsyms.c
--- linux-2.4.5/net/netsyms.c Fri Apr 27 16:15:01 2001
+++ linux/net/netsyms.c Mon Jun 4 11:11:30 2001
@@ -234,6 +234,8 @@
EXPORT_SYMBOL(inetdev_lock);
EXPORT_SYMBOL(inet_add_protocol);
EXPORT_SYMBOL(inet_del_protocol);
+EXPORT_SYMBOL(inet_register_protosw);
+EXPORT_SYMBOL(inet_unregister_protosw);
EXPORT_SYMBOL(ip_route_output_key);
EXPORT_SYMBOL(ip_route_input);
EXPORT_SYMBOL(icmp_send);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majo...@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

David S. Miller

unread,
Jun 6, 2001, 6:18:45 PM6/6/01
to

La Monte H.P. Yarroll writes:
> Matt D. Robinson writes:
> > Is there any way to add in the capability to _replace_ TCP with
> > your own, so you can use your own layer?

ABSOLUTELY NOT!

And I will never in my lifetime allow such a facility to be added to
the Linux kernel.

This allows people to make proprietary implementations of TCP under
Linux. And we don't want this just as we don't want to add a way to
allow someone to do a proprietary Linux VM.

Later,
David S. Miller
da...@redhat.com

Alexander Viro

unread,
Jun 6, 2001, 6:42:25 PM6/6/01
to

On Wed, 6 Jun 2001, David S. Miller wrote:

> This allows people to make proprietary implementations of TCP under
> Linux. And we don't want this just as we don't want to add a way to
> allow someone to do a proprietary Linux VM.

Erm... What stops those who want to do such implementations
from using AF_PACKET and handling the whole thing in userland?

Richard Gooch

unread,
Jun 6, 2001, 6:47:07 PM6/6/01
to
Alexander Viro writes:
>
>
> On Wed, 6 Jun 2001, David S. Miller wrote:
>
> > This allows people to make proprietary implementations of TCP under
> > Linux. And we don't want this just as we don't want to add a way to
> > allow someone to do a proprietary Linux VM.
>
> Erm... What stops those who want to do such implementations
> from using AF_PACKET and handling the whole thing in userland?

Just that their performance will suck. People are far less likely to
adopt a product (with an "embrace and extend" side effect) if said
product sucks performance.

Besides, it's better if people send patches to speed up our stack,
rather than having a proprietary product. Patches benefit all
mankind. Products benefit the vendor.

Regards,

Richard....
Permanent: rgo...@atnf.csiro.au
Current: rgo...@ras.ucalgary.ca

David S. Miller

unread,
Jun 6, 2001, 6:55:18 PM6/6/01
to

Alexander Viro writes:
> Erm... What stops those who want to do such implementations
> from using AF_PACKET and handling the whole thing in userland?

Nothing stops them, except the fact that this would be inefficient as
hell. Streams would be quicker :-)

Later,
David S. Miller
da...@redhat.com

Ben Greear

unread,
Jun 6, 2001, 7:42:18 PM6/6/01
to
"David S. Miller" wrote:
>
> La Monte H.P. Yarroll writes:
> > Matt D. Robinson writes:
> > > Is there any way to add in the capability to _replace_ TCP with
> > > your own, so you can use your own layer?
>
> ABSOLUTELY NOT!
>
> And I will never in my lifetime allow such a facility to be added to
> the Linux kernel.
>
> This allows people to make proprietary implementations of TCP under
> Linux. And we don't want this just as we don't want to add a way to
> allow someone to do a proprietary Linux VM.

Then again, maybe someone has a reason to use a different
TCP stack, ie to support something like a high-availiblity stack
between two different machines...

Why would you be scared of a proprietary TCP stack? If Open Source
is so much better (and I believe it is), then there would be nothing
to lose. And if the new stack helped a small subset of people who would
otherwise have an even sorrier life implementing it on some other
platform, then that is better, right?


--
Ben Greear <gre...@candelatech.com> <Ben_G...@excite.com>
President of Candela Technologies Inc http://www.candelatech.com
ScryMUD: http://scry.wanfear.com http://scry.wanfear.com/~greear

David S. Miller

unread,
Jun 6, 2001, 8:54:33 PM6/6/01
to

Ben Greear writes:
> a modular TCP stack might be a really
> good option for making $$ though support fees... If there is a
> need to keep certain (proprietary) code out of the kernel, let
> lawyers & public pressure do it, not overly broad technical restrictions.

There is a legal restriction, basically "Linus and the copyright
holders of the networking say no."

Later,
David S. Miller
da...@redhat.com

George Bonser

unread,
Jun 7, 2001, 2:03:09 AM6/7/01
to

> What matters is the API under which a binary-only module may interface
> to the kernel. Linus specifies that only the module exports in his
> tree fall into this API.

Ok, I was not aware of that stipulation. So to be very strict in the
interpretation, if there is a module export that is in the -ac kernels, ACME
could not make a binary module that depends on it until/if it makes it to
Linus' tree. Hmmm, Ok.

> As I stated in another email, the allowance of binary-only kernel
> modules is a special exception to the licensing of the kernel made by
> Linus. The GPL by itself, does not allow this at all.

Right. The GPL still allows one to "embrace and extend" it :-)

George Bonser

unread,
Jun 7, 2001, 2:06:29 AM6/7/01
to
> Ben Greear writes:
> > a modular TCP stack might be a really
> > good option for making $$ though support fees... If there is a
> > need to keep certain (proprietary) code out of the kernel, let
> > lawyers & public pressure do it, not overly broad technical
> restrictions.
>
> There is a legal restriction, basically "Linus and the copyright
> holders of the networking say no."
>
> Later,
> David S. Miller
> da...@redhat.com

There is, of course, one basic problem with that argument. While you can say
(and probably rightly so) that such a change would not be included in Linus'
kernel, I think anyone is allowed to post a patch that might make it
possible to add protocols as modules. If anyone chooses to use it is each
individual's decision but you could not prevent ACME from creating a patch
that allows protocol modules as long as they distributed the patch. Also, I
know that you are allowed to distribute proprietary modules in binary form
but are there any restrictions on what function these modules can perform?
I don't remember seeing any such restrictions.

In short, while you can refuse to accept such patches or support any
problems arising from their use, I would think that ACME has the right to
patch the kernel to make such a thing possible if they want to and there is
nothing (as far as I know) that anyone can do about it as long as they make
those patches public. So, ACME can say that to use ACME Super FooWare you
will need the ACME Super FooKernel with our FooModule that is distributed in
binary format. If you want to build the FooKernel, here is the patch but the
module is still binary.

David S. Miller

unread,
Jun 7, 2001, 2:06:31 AM6/7/01
to

Matt D. Robinson writes:
> P.S. I guess the next thing on the list for the Linux kernel is to
> create WHQL-like process for drivers before the code can end up
> in newer kernel revisions. Then I'll really know things have gone
> into the toilet.

Just remember that the allowance of proprietary device driver kernel
modules is a special exception to the licensing of the kernel, not the
rule. And some days even this exception becomes close to regrettable.

Other people seem to appreciate when the GPL camp isn't telling them
how to license their own code. And just as fairly it'd be nice if
people didn't tell us what to do with the licensing of the Linux
sources.

(I'm not a "use opensource or you're a maggot" person, I just choose
to not assosciate myself with sources not using that kind of
licensing. Linux is one of those safe havens for myself and
others. How would you like it if I were to jeapordize your own
legitimate paradise?).

Later,
David S. Miller
da...@redhat.com

-

Richard Gooch

unread,
Jun 7, 2001, 2:24:04 AM6/7/01
to
Matt D. Robinson writes:
> Richard Gooch wrote:

> > David S. Miller writes:
> > > Matt D. Robinson writes:
> > > > > This allows people to make proprietary implementations of TCP under
> > > > > Linux. And we don't want this just as we don't want to add a way to
> > > > > allow someone to do a proprietary Linux VM.
> > > >
> > > > And if as Joe User I don't want Linux TCP, but Joe's TCP, they can't
> > > > do that (in a supportable way)? Are you saying Linux is, "do it my
> > > > way, or it's the highway"?
> >
> > Pardon my cynicism, but this reads more like "I'm an ACME Inc. and I
> > want to sell a proprietary TCP stack for Linux, please change Linux to
> > make this possible/easy". I doubt there are many Joe Users out there
> > who want to replace their TCP stack. I bet they would be much happier
> > to see patches go in which improve the performance of the generic
> > kernel.

I can see this thread is degenerating. I don't plan on responding
after this. I've said my piece.

> Performance Improvements != Innovation. If the maintainers of the
> Linux kernel only want evolution, not revolution, then that's fine,
> but it should be a bit more clear to everyone.
>
> Let's say someone wanted to come in and completely restructure devfs.
> And let's say 75% of the people out there loved it, but you didn't.
> Are you willing to stand in the way of allowing the new code to come
> into the kernel for sake of your exclusive opinion? And if you
> are willing to promote the changes, what does the community say if
> they don't like it? And is this thought process consistent among
> all maintainers?

I'm the maintainer of devfs, so I'll judge things on their merits as I
see them. If I think something is a bad idea, I'll reject it. If 75%
of people disagree with me, then so be it. I'll listen to others, but
in the and I'll do what I think is right. Devfs had plenty of
opposition. I thought I was right so I went ahead and implemented it.

Ultimately, Linus decides, of course.

> Mr. Yarroll has a great patch, one that offers some help to all kinds
> of developers. I worry now that it'll either not be accepted or
> it'll end up changing enough that developers using it will have a
> hard time taking advantage of its benefits.

Perhaps if lots of OSS developers call for the changes to be included,
Dave and Linus will change their minds. Or perhaps someone will figure
out a way of give the OSS people what they want without sacrificing
the policy that Dave expressed. Or perhaps few people will really want
to replace the TCP stack. Time will tell.

> > But I'm sure there are plenty of ACME Inc.'s out there who would love
> > to sell a replacement TCP stack. And suck users down a proprietary
> > solution path. But I don't see why the Linux community should help the
> > ACME's of this world. And Linux is doing very nicely in the corporate
> > world, so we needn't to lose any sleep over what our current policies
> > do for our acceptance levels.
> >
> > If it bothers you that Linux caters more the the users and less to the
> > vendors, then use another OS. We don't mind. The door is over there.
> > Please don't slam it on your way out.
>
> I'm sorry, I normally wouldn't respond, but there are so many points
> to make. I don't mean to make this into a OSS religious war, but I'm
> curious:
>
> 1) Why would you limit people's ability to use solutions that are
> not open source? I mean, you don't do it in user space, so why
> bother doing it in the kernel? Doesn't the eventual goal of
> opening up solutions to everyone also provide room for companies
> to make a profit, if it does nothing to hurt the kernel's
> eventual dominance over other kernels? And if not, why not?

Actually, it is done in user-space. See GPL'ed libraries (c.f. LGPL'ed
libraries).

> 2) Why won't Linux take FreeBSD OSL'd code into the kernel without
> also requiring a dual license which also allows for the GNU GPL?
> I mean, the FreeBSD license is OSL certified, right? Or is it so
> important to use GPL over other OSL's that you'd rather styme
> innovation for the sake of purity?

Yep, the Linux crowd prefer the GPL and the *BSD crowd prefer their
license. Different philosophy. We think the GPL is better for the
greater good, they think the BSD license is better.

> 3) Why take the position that if you don't like it, go to some other
> OS? What if I like Linux? Does that mean I have to give up all
> thought of using Linux because I want a proprietary solution for
> one or two things? Doesn't that seem completely counterintuitive
> to being "open"?

Look, the GPL is the license that Linux was written under, and is the
license that attracted all these developers. We're already being more
friendly to proprietary solutions than the GPL strictly allows. Be
happy with that. A line has been drawn. Live with it. Either Linux
provides sufficient benefit that it's worth it for your company to
continue working with it, or you decide you can't live with the
restrictions and change to another OS. It's your choice. Don't bitch
about it. No-one is forcing you to use Linux.

People have to make all sorts of choices. Chosing to use proprietary
software means you have to give up certain freedoms. People do it
every day, and pay money for the privilege.

> 4) Why are Linux kernel developers turning into a community of
> gatekeepers who are increasingly less "open" about changes to the
> product? Is it really these days only what Linus wants? By that
> I mean, does he really control the majority of changes, or just
> those things he has time to look at or really cares about? All
> those other tree components are now maintained, some loosely,
> some in a draconian fashion. If someone isn't flexible, how is
> innovation maintained?

If the community thinks someone isn't performing, they get replaced.
It's happened in the kernel, and it's happened in other OSS
projects. Innovation doesn't appear to be suffering.

> > > If Joe's TCP is opensource, they are more than welcome to publish
> > > such changes.
> >
> > Yep. And then we can all benefit.
>
> And if it's released under the FreeBSD OSL, it won't be placed into
> the Linux kernel (at least according to one rather important
> maintainer). So Linux users as a whole won't benefit. And that's a
> real shame.

Quite a few developers are happy to dual license their code, if the
original license was BSD.

> Just my opinion. I just get the feeling that some of the
> maintainers are taking a "I'd rather cut off my nose to spite my
> face" stand on their beliefs rather than considering how the Linux
> kernel can evolve to help everyone -- even those that want to make
> money. The kernel can allow for both, but they (meaning the
> maintainers) just choose not to permit it.

This isn't about spite. You just don't get what Linux is about. It's a
hackers' OS. Made by hackers for hackers. It's great that many other
people can use it, and that people can make money off it, more power
to them. But ultimately, we *don't care* if others use it. Sure, it's
nice if others do, and we try and help them. But not by sacrificing
what we believe in. And no-one should ask us to.

> Maybe they just want some more of those RedHat stock options ...

How dare you! This isn't about RedHat stock options. I don't have any
myself, and people like Alan and Dave have shown their integrity and
their commitment to the community and don't deserve to have mud slung
at them. Maybe the problem is that you're trying to push a proprietary
product, and want the kernel to be changed to suit your narrow,
commercial interests, and the "gatekeepers" aren't rolling out the red
carpet for you.

Get real, mate.

Regards,

Richard....
Permanent: rgo...@atnf.csiro.au
Current: rgo...@ras.ucalgary.ca

0 new messages