linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "La Monte H.P. Yarroll" <piggy@em.cig.mot.com>
To: "Matt D. Robinson" <yakker@alacritech.com>
Cc: linux-kernel@vger.kernel.org, sctp-developers-list@cig.mot.com
Subject: Re: [PATCH] sockreg2.4.5-05 inet[6]_create() register/unregister table
Date: Wed,  6 Jun 2001 17:07:01 -0500 (CDT)	[thread overview]
Message-ID: <15134.42714.3365.32233@theor.em.cig.mot.com> (raw)
In-Reply-To: <3B1E5CC1.553B4EF1@alacritech.com>
In-Reply-To: <200106051659.LAA20094@em.cig.mot.com> <3B1E5CC1.553B4EF1@alacritech.com>

Thanks!  I'm glad you like our code.

This patch does allow you to override TCP with a new implementation
for new connections and then back out safely to the old TCP later.

I think the feature you are asking for (replace TCP for EXISTING
connections) is quite dangerous.  You COULD grub around in existing
sock structures and replace the proto_ops, but that would not be
enough.  We are talking about a stateful protocol here--your "TCP2"
module would have to safely extract the state of the existing TCP
connections and replace the control functions all as an atomic
operation...and then undo that at the end.

What was the application you had in mind?  The applications we have
been playing with do not suffer greatly from having to start new
connections.

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?  I guess you could
 > inet_unregister_protosw() of the IPPROTO_TCP, but does that
 > address outstanding connections?  I don't believe so ...
 > 
 > It would be nice if your patch offered that capability.  Nice
 > work, BTW -- not enough compliments go out on lkml these days. :)
 > 
 > --Matt
 > 
 > "La Monte H.P. Yarroll" wrote:
 > > 
 > > 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 majordomo@vger.kernel.org
 > > More majordomo info at  http://vger.kernel.org/majordomo-info.html
 > > Please read the FAQ at  http://www.tux.org/lkml/

  reply	other threads:[~2001-06-06 22:07 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <3B1E5CC1.553B4EF1@alacritech.com>
2001-06-05 16:59 ` [PATCH] sockreg2.4.5-05 inet[6]_create() register/unregister table La Monte H.P. Yarroll
2001-06-06 22:07   ` La Monte H.P. Yarroll [this message]
2001-06-07 19:11     ` Matthias Urlichs
2001-06-11 18:26   ` [PATCH] sockreg2.4.5-06 " La Monte H.P. Yarroll
2001-06-13 16:25   ` David S. Miller
2001-06-06 22:15 ` [PATCH] sockreg2.4.5-05 " David S. Miller
2001-06-06 22:36   ` Alexander Viro
2001-06-06 22:42   ` Richard Gooch
2001-06-06 22:52   ` David S. Miller
2001-06-06 23:21   ` Matt D. Robinson
2001-06-06 23:51     ` Richard Gooch
2001-06-07  0:51       ` David S. Miller
2001-06-07  5:37         ` George Bonser
2001-06-07  5:50         ` David S. Miller
2001-06-07  6:00           ` George Bonser
2001-06-07 15:18           ` watermodem
2001-06-07 15:51             ` Mike Galbraith
2001-06-09 22:09               ` [PATCH] sockreg2.4.5-05 inet[6]_create() register/unregistertable watermodem
2001-06-09 23:15                 ` Alexander Viro
2001-06-10  2:59                 ` Horst von Brand
2001-06-10  4:38                 ` Mike Galbraith
2001-06-07  1:22       ` [PATCH] sockreg2.4.5-05 inet[6]_create() register/unregister table Ben Greear
2001-06-07  5:16       ` Matt D. Robinson
2001-06-07 18:03         ` [PATCH] sockreg2.4.5-05 inet[6]_create() register/unregister Alan Cox
2001-06-07  5:46       ` [PATCH] sockreg2.4.5-05 inet[6]_create() register/unregister table David S. Miller
2001-06-07  6:20       ` Richard Gooch
2001-06-07  6:47         ` Matt D. Robinson
2001-06-07 18:10     ` Alan Cox
2001-06-08  1:31     ` David S. Miller
2001-06-06 23:31   ` David S. Miller
2001-06-06 23:43   ` David S. Miller
2001-06-07 10:03     ` Henning P. Schmiedehausen
2001-06-07 10:50       ` Daniel Phillips
2001-06-07 17:52       ` Alan Cox
2001-06-08  8:29         ` Henning P. Schmiedehausen
2001-06-08 16:42           ` Alan Cox
2001-06-08 22:54           ` Albert D. Cahalan
2001-06-08 23:46             ` David Woodhouse
2001-06-11  8:45             ` Henning P. Schmiedehausen
2001-06-11  9:43               ` Helge Hafting
2001-06-11 16:17               ` Alan Cox
2001-06-11 18:31                 ` Jacob Luna Lundberg
2001-06-11 18:48                   ` [PATCH] sockreg2.4.5-05 inet[6]_create() register/unregister Alan Cox
2001-06-11 20:34                     ` Jacob Luna Lundberg
2001-06-12  7:08                   ` [PATCH] sockreg2.4.5-05 inet[6]_create() register/unregistertable Helge Hafting
2001-06-07 10:05     ` [PATCH] sockreg2.4.5-05 inet[6]_create() register/unregister table Russell King
2001-06-07 15:27       ` Keith Owens
2001-06-07 17:01         ` David Woodhouse
2001-06-07 11:25     ` David S. Miller
2001-06-07 11:25     ` David S. Miller
2001-06-07  0:14   ` Ben Greear

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=15134.42714.3365.32233@theor.em.cig.mot.com \
    --to=piggy@em.cig.mot.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sctp-developers-list@cig.mot.com \
    --cc=yakker@alacritech.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).