Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-2-0]: src/sys/kern Pull up revision 1.63 (requested by jonathan i...



details:   https://anonhg.NetBSD.org/src/rev/431f331a1e56
branches:  netbsd-2-0
changeset: 561183:431f331a1e56
user:      tron <tron%NetBSD.org@localhost>
date:      Sun May 30 07:02:16 2004 +0000

description:
Pull up revision 1.63 (requested by jonathan in ticket #405):
Rework to make  FAST_IPSEC PF_KEY dumps unicast and reliable:
Introduce new socket-layer function sbappendaddrchain() to
sys/kern/uipc_socket2.c: like sbappendaddr(), only takes a chain of
records and appends the entire chain in one pass. sbappendaddrchain()
also takes an `sbprio' argument, which indicates the caller requires
special `reliable' handling of the socket-buffer.  `sbprio' is
described in sys/sys/socketvar.h, although (for now) the different
levels are not yet implemented.
Rework sys/netipsec/key.c PF_KEY DUMP responses to build a chain of
mbuf records, one record per dump response. Unicast the entire chain
to the requestor, with all-or-none semantics.
Changed files;
        sys/socketvar.h kern/uipc_socket2.c netipsec/key.c
Reviewed by:
        Jason Thorpe, Thor Lancelot Simon, post to tech-kern.
Todo: request pullup to 2.0 branch.  Post-2.0, rework sysctl() API for
dumps to use new record-chain constructors. Actually implement
the distinct service levels in sbappendaddrchain() so we can use them
to make PF_KEY ACQUIRE messages more reliable.

diffstat:

 sys/kern/uipc_socket2.c |  114 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 110 insertions(+), 4 deletions(-)

diffs (149 lines):

diff -r 72c7632b12e4 -r 431f331a1e56 sys/kern/uipc_socket2.c
--- a/sys/kern/uipc_socket2.c   Sat May 29 21:27:06 2004 +0000
+++ b/sys/kern/uipc_socket2.c   Sun May 30 07:02:16 2004 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uipc_socket2.c,v 1.58 2003/10/21 22:55:47 thorpej Exp $        */
+/*     $NetBSD: uipc_socket2.c,v 1.58.2.1 2004/05/30 07:02:16 tron Exp $       */
 
 /*
  * Copyright (c) 1982, 1986, 1988, 1990, 1993
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_socket2.c,v 1.58 2003/10/21 22:55:47 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_socket2.c,v 1.58.2.1 2004/05/30 07:02:16 tron Exp $");
 
 #include "opt_mbuftrace.h"
 #include "opt_sb_max.h"
@@ -495,15 +495,22 @@
 }
 #endif /* SOCKBUF_DEBUG */
 
-#define        SBLINKRECORD(sb, m0)                                            \
+/*
+ * Link a chain of records onto a socket buffer
+ */
+#define        SBLINKRECORDCHAIN(sb, m0, mlast)                                \
 do {                                                                   \
        if ((sb)->sb_lastrecord != NULL)                                \
                (sb)->sb_lastrecord->m_nextpkt = (m0);                  \
        else                                                            \
                (sb)->sb_mb = (m0);                                     \
-       (sb)->sb_lastrecord = (m0);                                     \
+       (sb)->sb_lastrecord = (mlast);                                  \
 } while (/*CONSTCOND*/0)
 
+
+#define        SBLINKRECORD(sb, m0)                                            \
+    SBLINKRECORDCHAIN(sb, m0, m0)
+
 /*
  * Append mbuf chain m to the last record in the
  * socket buffer sb.  The additional space associated
@@ -748,6 +755,105 @@
        return (1);
 }
 
+/*
+ * Helper for sbappendchainaddr: prepend a struct sockaddr* to
+ * an mbuf chain.
+ */
+static __inline struct mbuf *
+m_prepend_sockaddr(struct mbuf *m0, const struct sockaddr *asa)
+{
+       struct mbuf *m;
+       const int mlen = asa->sa_len;
+
+       /* only the first in each chain need be a pkthdr */
+       MGETHDR(m, M_DONTWAIT, MT_SONAME);
+       if (m == 0)
+               return (0);
+       MCLAIM(m, sb->sb_mowner);
+       KASSERT(mlen <= MLEN);
+
+       m->m_len = mlen;
+       bcopy((caddr_t)asa, mtod(m, caddr_t), mlen);
+       m->m_next = m0;
+       m->m_pkthdr.len = mlen + m0->m_pkthdr.len;
+
+       return m;
+}
+
+int
+sbappendaddrchain(struct sockbuf *sb, const struct sockaddr *asa,
+                 struct mbuf *m0, int sbprio)
+{
+       int space;
+       struct mbuf *m, *n, *n0, *nlast;
+       int error;
+
+       /*
+        * XXX sbprio reserved for encoding priority of this* request:
+        *  SB_PRIO_NONE --> honour normal sb limits
+        *  SB_PRIO_ONESHOT_OVERFLOW --> if socket has any space,
+        *      take whole chain. Intended for large requests
+        *      that should be delivered atomically (all, or none).
+        * SB_PRIO_OVERDRAFT -- allow a small (2*MLEN) overflow
+        *       over normal socket limits, for messages indicating
+        *       buffer overflow in earlier normal/lower-priority messages
+        * SB_PRIO_BESTEFFORT -->  ignore limits entirely.
+        *       Intended for  kernel-generated messages only.
+        *        Up to generator to avoid total mbuf resource exhaustion.
+        */
+       (void)sbprio;
+
+       if (m0 && (m0->m_flags & M_PKTHDR) == 0)
+               panic("sbappendaddrchain");
+
+       space = sbspace(sb);
+       
+#ifdef notyet
+       /* 
+        * Enforce SB_PRIO_* limits as described above.
+        */
+#endif
+
+       n0 = NULL;
+       nlast = NULL;
+       for (m = m0; m; m = m->m_nextpkt) {
+               struct mbuf *np;
+
+               /* Prepend sockaddr to this record (m) of input chain m0 */
+               n = m_prepend_sockaddr(m, asa);
+               if (n == NULL) {
+                       error = ENOBUFS;
+                       goto bad;
+               }
+
+               /* Append record (asa+m) to end of new chain n0 */
+               if (n0 == NULL) {
+                       n0 = n;
+               } else {
+                       nlast->m_nextpkt = n;
+               }
+               /* Keep track of last record on new chain */
+               nlast = n;
+
+               for (np = n; np; np = np->m_next)
+                       sballoc(sb, np);
+       }
+
+       /* Drop the entire chain of (asa+m) records onto the socket */
+       SBLINKRECORDCHAIN(sb, n0, nlast);
+       for (m = nlast; m->m_next; m = m->m_next)
+               ;
+       sb->sb_mbtail = m;
+       
+       return (1);
+
+bad:
+       if (n)
+               m_freem(n);
+       return 0;       
+}
+
+
 int
 sbappendcontrol(struct sockbuf *sb, struct mbuf *m0, struct mbuf *control)
 {



Home | Main Index | Thread Index | Old Index