2008-05-15 05:30:48 +04:00
|
|
|
/* $NetBSD: if_gre.c,v 1.133 2008/05/15 01:30:48 dyoung Exp $ */
|
1998-10-08 03:33:02 +04:00
|
|
|
|
1998-09-14 00:27:47 +04:00
|
|
|
/*
|
2008-03-22 00:54:58 +03:00
|
|
|
* Copyright (c) 1998, 2008 The NetBSD Foundation, Inc.
|
1998-09-14 00:27:47 +04:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This code is derived from software contributed to The NetBSD Foundation
|
|
|
|
* by Heiko W.Rupp <hwr@pilhuhn.de>
|
|
|
|
*
|
2005-03-30 20:34:54 +04:00
|
|
|
* IPv6-over-GRE contributed by Gert Doering <gert@greenie.muc.de>
|
|
|
|
*
|
1998-09-14 00:27:47 +04:00
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
|
|
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
|
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
|
|
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Encapsulate L3 protocols into IP
|
|
|
|
* See RFC 1701 and 1702 for more details.
|
|
|
|
* If_gre is compatible with Cisco GRE tunnels, so you can
|
|
|
|
* have a NetBSD box as the other end of a tunnel interface of a Cisco
|
|
|
|
* router. See gre(4) for more details.
|
|
|
|
*/
|
|
|
|
|
2001-11-13 02:49:33 +03:00
|
|
|
#include <sys/cdefs.h>
|
2008-05-15 05:30:48 +04:00
|
|
|
__KERNEL_RCSID(0, "$NetBSD: if_gre.c,v 1.133 2008/05/15 01:30:48 dyoung Exp $");
|
1998-09-14 00:27:47 +04:00
|
|
|
|
2006-08-31 21:46:16 +04:00
|
|
|
#include "opt_gre.h"
|
1998-09-14 00:27:47 +04:00
|
|
|
#include "opt_inet.h"
|
|
|
|
#include "bpfilter.h"
|
|
|
|
|
2004-12-06 05:59:23 +03:00
|
|
|
#ifdef INET
|
1998-09-14 00:27:47 +04:00
|
|
|
#include <sys/param.h>
|
2006-08-31 21:46:16 +04:00
|
|
|
#include <sys/file.h>
|
|
|
|
#include <sys/filedesc.h>
|
1998-09-14 00:27:47 +04:00
|
|
|
#include <sys/malloc.h>
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
#include <sys/mallocvar.h>
|
1998-09-14 00:27:47 +04:00
|
|
|
#include <sys/mbuf.h>
|
2000-11-19 21:48:44 +03:00
|
|
|
#include <sys/proc.h>
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
#include <sys/domain.h>
|
1998-09-14 00:27:47 +04:00
|
|
|
#include <sys/protosw.h>
|
|
|
|
#include <sys/socket.h>
|
2006-08-31 21:46:16 +04:00
|
|
|
#include <sys/socketvar.h>
|
1998-09-14 00:27:47 +04:00
|
|
|
#include <sys/ioctl.h>
|
2000-07-05 22:14:13 +04:00
|
|
|
#include <sys/queue.h>
|
2007-11-07 03:19:54 +03:00
|
|
|
#include <sys/intr.h>
|
1998-09-14 00:27:47 +04:00
|
|
|
#if __NetBSD__
|
|
|
|
#include <sys/systm.h>
|
2006-08-31 21:46:16 +04:00
|
|
|
#include <sys/sysctl.h>
|
2006-05-15 01:19:33 +04:00
|
|
|
#include <sys/kauth.h>
|
1998-09-14 00:27:47 +04:00
|
|
|
#endif
|
|
|
|
|
2007-05-06 06:47:52 +04:00
|
|
|
#include <sys/kernel.h>
|
|
|
|
#include <sys/mutex.h>
|
|
|
|
#include <sys/condvar.h>
|
2006-08-31 21:46:16 +04:00
|
|
|
#include <sys/kthread.h>
|
|
|
|
|
2007-10-19 15:59:34 +04:00
|
|
|
#include <sys/cpu.h>
|
1998-09-14 00:27:47 +04:00
|
|
|
|
|
|
|
#include <net/ethertypes.h>
|
|
|
|
#include <net/if.h>
|
|
|
|
#include <net/if_types.h>
|
|
|
|
#include <net/netisr.h>
|
|
|
|
#include <net/route.h>
|
|
|
|
|
|
|
|
#ifdef INET
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#include <netinet/in_systm.h>
|
|
|
|
#include <netinet/in_var.h>
|
|
|
|
#include <netinet/ip.h>
|
|
|
|
#include <netinet/ip_var.h>
|
|
|
|
#else
|
1998-10-08 03:33:02 +04:00
|
|
|
#error "Huh? if_gre without inet?"
|
1998-09-14 00:27:47 +04:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef NETATALK
|
|
|
|
#include <netatalk/at.h>
|
|
|
|
#include <netatalk/at_var.h>
|
|
|
|
#include <netatalk/at_extern.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if NBPFILTER > 0
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <net/bpf.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <net/if_gre.h>
|
|
|
|
|
2007-08-20 08:49:40 +04:00
|
|
|
#include <compat/sys/socket.h>
|
2007-05-30 01:32:27 +04:00
|
|
|
#include <compat/sys/sockio.h>
|
2001-05-10 05:23:51 +04:00
|
|
|
/*
|
2002-06-09 13:45:39 +04:00
|
|
|
* It is not easy to calculate the right value for a GRE MTU.
|
|
|
|
* We leave this task to the admin and use the same default that
|
|
|
|
* other vendors use.
|
2001-05-10 05:23:51 +04:00
|
|
|
*/
|
2002-06-09 13:45:39 +04:00
|
|
|
#define GREMTU 1476
|
1998-09-14 00:27:47 +04:00
|
|
|
|
2006-08-31 21:46:16 +04:00
|
|
|
#ifdef GRE_DEBUG
|
2007-08-25 03:38:31 +04:00
|
|
|
int gre_debug = 0;
|
2008-05-10 00:14:07 +04:00
|
|
|
#define GRE_DPRINTF(__sc, ...) \
|
|
|
|
do { \
|
|
|
|
if (__predict_false(gre_debug || \
|
|
|
|
((__sc)->sc_if.if_flags & IFF_DEBUG) != 0)) { \
|
|
|
|
printf("%s.%d: ", __func__, __LINE__); \
|
|
|
|
printf(__VA_ARGS__); \
|
|
|
|
} \
|
2006-08-31 21:46:16 +04:00
|
|
|
} while (/*CONSTCOND*/0)
|
|
|
|
#else
|
|
|
|
#define GRE_DPRINTF(__sc, __fmt, ...) do { } while (/*CONSTCOND*/0)
|
|
|
|
#endif /* GRE_DEBUG */
|
|
|
|
|
2002-02-24 20:22:20 +03:00
|
|
|
int ip_gre_ttl = GRE_TTL;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
MALLOC_DEFINE(M_GRE_BUFQ, "gre_bufq", "gre mbuf queue");
|
1998-09-14 00:27:47 +04:00
|
|
|
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
static int gre_clone_create(struct if_clone *, int);
|
|
|
|
static int gre_clone_destroy(struct ifnet *);
|
2000-07-05 22:14:13 +04:00
|
|
|
|
2005-12-12 02:05:24 +03:00
|
|
|
static struct if_clone gre_cloner =
|
2000-07-05 22:14:13 +04:00
|
|
|
IF_CLONE_INITIALIZER("gre", gre_clone_create, gre_clone_destroy);
|
1998-09-14 00:27:47 +04:00
|
|
|
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
static int gre_input(struct gre_softc *, struct mbuf *, int,
|
|
|
|
const struct gre_h *);
|
2007-10-06 07:35:14 +04:00
|
|
|
static bool gre_is_nullconf(const struct gre_soparm *);
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
static int gre_output(struct ifnet *, struct mbuf *,
|
KNF: de-__P, bzero -> memset, bcmp -> memcmp. Remove extraneous
parentheses in return statements.
Cosmetic: don't open-code TAILQ_FOREACH().
Cosmetic: change types of variables to avoid oodles of casts: in
in6_src.c, avoid casts by changing several route_in6 pointers
to struct route pointers. Remove unnecessary casts to caddr_t
elsewhere.
Pave the way for eliminating address family-specific route caches:
soon, struct route will not embed a sockaddr, but it will hold
a reference to an external sockaddr, instead. We will set the
destination sockaddr using rtcache_setdst(). (I created a stub
for it, but it isn't used anywhere, yet.) rtcache_free() will
free the sockaddr. I have extracted from rtcache_free() a helper
subroutine, rtcache_clear(). rtcache_clear() will "forget" a
cached route, but it will not forget the destination by releasing
the sockaddr. I use rtcache_clear() instead of rtcache_free()
in rtcache_update(), because rtcache_update() is not supposed
to forget the destination.
Constify:
1 Introduce const accessor for route->ro_dst, rtcache_getdst().
2 Constify the 'dst' argument to ifnet->if_output(). This
led me to constify a lot of code called by output routines.
3 Constify the sockaddr argument to protosw->pr_ctlinput. This
led me to constify a lot of code called by ctlinput routines.
4 Introduce const macros for converting from a generic sockaddr
to family-specific sockaddrs, e.g., sockaddr_in: satocsin6,
satocsin, et cetera.
2007-02-18 01:34:07 +03:00
|
|
|
const struct sockaddr *, struct rtentry *);
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
static int gre_ioctl(struct ifnet *, u_long, void *);
|
2006-08-31 21:46:16 +04:00
|
|
|
static int gre_getsockname(struct socket *, struct mbuf *, struct lwp *);
|
|
|
|
static int gre_getpeername(struct socket *, struct mbuf *, struct lwp *);
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
static int gre_getnames(struct socket *, struct lwp *,
|
|
|
|
struct sockaddr_storage *, struct sockaddr_storage *);
|
2007-10-06 07:35:14 +04:00
|
|
|
static void gre_clearconf(struct gre_soparm *, bool);
|
2007-10-05 08:55:10 +04:00
|
|
|
static int gre_soreceive(struct socket *, struct mbuf **);
|
2008-05-15 05:30:48 +04:00
|
|
|
static int gre_sosend(struct socket *, struct mbuf *);
|
2008-05-10 00:14:07 +04:00
|
|
|
static struct socket *gre_reconf(struct gre_softc *, const struct gre_soparm *);
|
|
|
|
|
|
|
|
static bool gre_fp_send(struct gre_softc *, enum gre_msg, file_t *);
|
|
|
|
static bool gre_fp_recv(struct gre_softc *);
|
|
|
|
static void gre_fp_recvloop(void *);
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
|
|
|
|
static int
|
|
|
|
nearest_pow2(size_t len0)
|
|
|
|
{
|
|
|
|
size_t len, mid;
|
|
|
|
|
|
|
|
if (len0 == 0)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
for (len = len0; (len & (len - 1)) != 0; len &= len - 1)
|
|
|
|
;
|
|
|
|
|
|
|
|
mid = len | (len >> 1);
|
|
|
|
|
|
|
|
/* avoid overflow */
|
|
|
|
if ((len << 1) < len)
|
|
|
|
return len;
|
|
|
|
if (len0 >= mid)
|
|
|
|
return len << 1;
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct gre_bufq *
|
|
|
|
gre_bufq_init(struct gre_bufq *bq, size_t len0)
|
|
|
|
{
|
|
|
|
size_t len;
|
|
|
|
|
|
|
|
len = nearest_pow2(len0);
|
|
|
|
|
|
|
|
memset(bq, 0, sizeof(*bq));
|
|
|
|
bq->bq_buf = malloc(len * sizeof(struct mbuf *), M_GRE_BUFQ, M_WAITOK);
|
|
|
|
bq->bq_len = len;
|
|
|
|
bq->bq_lenmask = len - 1;
|
|
|
|
|
|
|
|
return bq;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool
|
|
|
|
gre_bufq_empty(struct gre_bufq *bq)
|
|
|
|
{
|
|
|
|
return bq->bq_prodidx == bq->bq_considx;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct mbuf *
|
|
|
|
gre_bufq_dequeue(struct gre_bufq *bq)
|
|
|
|
{
|
|
|
|
struct mbuf *m;
|
|
|
|
|
|
|
|
if (gre_bufq_empty(bq))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
m = bq->bq_buf[bq->bq_considx];
|
|
|
|
bq->bq_considx = (bq->bq_considx + 1) & bq->bq_lenmask;
|
|
|
|
|
|
|
|
return m;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gre_bufq_purge(struct gre_bufq *bq)
|
|
|
|
{
|
|
|
|
struct mbuf *m;
|
|
|
|
|
|
|
|
while ((m = gre_bufq_dequeue(bq)) != NULL)
|
|
|
|
m_freem(m);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
gre_bufq_enqueue(struct gre_bufq *bq, struct mbuf *m)
|
|
|
|
{
|
|
|
|
int next;
|
|
|
|
|
|
|
|
next = (bq->bq_prodidx + 1) & bq->bq_lenmask;
|
|
|
|
|
|
|
|
if (next == bq->bq_considx) {
|
|
|
|
bq->bq_drops++;
|
|
|
|
return ENOBUFS;
|
|
|
|
}
|
|
|
|
|
|
|
|
bq->bq_buf[bq->bq_prodidx] = m;
|
|
|
|
bq->bq_prodidx = next;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
greintr(void *arg)
|
|
|
|
{
|
|
|
|
struct gre_softc *sc = (struct gre_softc *)arg;
|
2008-05-10 00:14:07 +04:00
|
|
|
struct socket *so = sc->sc_soparm.sp_so;
|
2007-10-05 08:55:10 +04:00
|
|
|
int rc;
|
|
|
|
struct mbuf *m;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
|
2008-05-10 00:14:07 +04:00
|
|
|
KASSERT(so != NULL);
|
2007-10-05 08:55:10 +04:00
|
|
|
|
|
|
|
sc->sc_send_ev.ev_count++;
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "enter\n");
|
2007-10-05 08:55:10 +04:00
|
|
|
while ((m = gre_bufq_dequeue(&sc->sc_snd)) != NULL) {
|
|
|
|
/* XXX handle ENOBUFS? */
|
2008-05-15 05:30:48 +04:00
|
|
|
if ((rc = gre_sosend(so, m)) != 0)
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "gre_sosend failed %d\n", rc);
|
2007-10-05 08:55:10 +04:00
|
|
|
}
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Caller must hold sc->sc_mtx. */
|
|
|
|
static void
|
|
|
|
gre_wait(struct gre_softc *sc)
|
|
|
|
{
|
|
|
|
sc->sc_waiters++;
|
|
|
|
cv_wait(&sc->sc_condvar, &sc->sc_mtx);
|
|
|
|
sc->sc_waiters--;
|
|
|
|
}
|
2006-08-31 21:46:16 +04:00
|
|
|
|
|
|
|
static void
|
2008-05-10 00:14:07 +04:00
|
|
|
gre_fp_wait(struct gre_softc *sc)
|
2006-08-31 21:46:16 +04:00
|
|
|
{
|
2008-05-10 00:14:07 +04:00
|
|
|
sc->sc_fp_waiters++;
|
|
|
|
cv_wait(&sc->sc_fp_condvar, &sc->sc_mtx);
|
|
|
|
sc->sc_fp_waiters--;
|
2006-08-31 21:46:16 +04:00
|
|
|
}
|
|
|
|
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
static void
|
|
|
|
gre_evcnt_detach(struct gre_softc *sc)
|
|
|
|
{
|
|
|
|
evcnt_detach(&sc->sc_unsupp_ev);
|
|
|
|
evcnt_detach(&sc->sc_pullup_ev);
|
|
|
|
evcnt_detach(&sc->sc_error_ev);
|
|
|
|
evcnt_detach(&sc->sc_block_ev);
|
|
|
|
evcnt_detach(&sc->sc_recv_ev);
|
|
|
|
|
|
|
|
evcnt_detach(&sc->sc_oflow_ev);
|
|
|
|
evcnt_detach(&sc->sc_send_ev);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gre_evcnt_attach(struct gre_softc *sc)
|
|
|
|
{
|
|
|
|
evcnt_attach_dynamic(&sc->sc_recv_ev, EVCNT_TYPE_MISC,
|
|
|
|
NULL, sc->sc_if.if_xname, "recv");
|
|
|
|
evcnt_attach_dynamic(&sc->sc_block_ev, EVCNT_TYPE_MISC,
|
|
|
|
&sc->sc_recv_ev, sc->sc_if.if_xname, "would block");
|
|
|
|
evcnt_attach_dynamic(&sc->sc_error_ev, EVCNT_TYPE_MISC,
|
|
|
|
&sc->sc_recv_ev, sc->sc_if.if_xname, "error");
|
|
|
|
evcnt_attach_dynamic(&sc->sc_pullup_ev, EVCNT_TYPE_MISC,
|
2007-10-05 08:55:10 +04:00
|
|
|
&sc->sc_recv_ev, sc->sc_if.if_xname, "pullup failed");
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
evcnt_attach_dynamic(&sc->sc_unsupp_ev, EVCNT_TYPE_MISC,
|
|
|
|
&sc->sc_recv_ev, sc->sc_if.if_xname, "unsupported");
|
|
|
|
|
|
|
|
evcnt_attach_dynamic(&sc->sc_send_ev, EVCNT_TYPE_MISC,
|
|
|
|
NULL, sc->sc_if.if_xname, "send");
|
|
|
|
evcnt_attach_dynamic(&sc->sc_oflow_ev, EVCNT_TYPE_MISC,
|
2007-10-05 08:55:10 +04:00
|
|
|
&sc->sc_send_ev, sc->sc_if.if_xname, "overflow");
|
2006-08-31 21:46:16 +04:00
|
|
|
}
|
|
|
|
|
2005-12-12 02:05:24 +03:00
|
|
|
static int
|
|
|
|
gre_clone_create(struct if_clone *ifc, int unit)
|
1998-09-14 00:27:47 +04:00
|
|
|
{
|
2008-05-10 00:14:07 +04:00
|
|
|
int rc;
|
1999-06-28 11:52:38 +04:00
|
|
|
struct gre_softc *sc;
|
2008-05-10 00:14:07 +04:00
|
|
|
struct gre_soparm *sp;
|
2000-07-05 22:14:13 +04:00
|
|
|
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
sc = malloc(sizeof(struct gre_softc), M_DEVBUF, M_WAITOK|M_ZERO);
|
|
|
|
mutex_init(&sc->sc_mtx, MUTEX_DRIVER, IPL_SOFTNET);
|
|
|
|
cv_init(&sc->sc_condvar, "gre wait");
|
2008-05-10 00:14:07 +04:00
|
|
|
cv_init(&sc->sc_fp_condvar, "gre fp");
|
2000-07-05 22:14:13 +04:00
|
|
|
|
2004-04-21 22:40:37 +04:00
|
|
|
snprintf(sc->sc_if.if_xname, sizeof(sc->sc_if.if_xname), "%s%d",
|
|
|
|
ifc->ifc_name, unit);
|
2000-07-05 22:14:13 +04:00
|
|
|
sc->sc_if.if_softc = sc;
|
2004-05-13 15:29:40 +04:00
|
|
|
sc->sc_if.if_type = IFT_TUNNEL;
|
2002-06-09 21:59:45 +04:00
|
|
|
sc->sc_if.if_addrlen = 0;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
sc->sc_if.if_hdrlen = sizeof(struct ip) + sizeof(struct gre_h);
|
2000-12-18 22:44:33 +03:00
|
|
|
sc->sc_if.if_dlt = DLT_NULL;
|
2001-05-10 05:23:51 +04:00
|
|
|
sc->sc_if.if_mtu = GREMTU;
|
2000-07-05 22:14:13 +04:00
|
|
|
sc->sc_if.if_flags = IFF_POINTOPOINT|IFF_MULTICAST;
|
|
|
|
sc->sc_if.if_output = gre_output;
|
|
|
|
sc->sc_if.if_ioctl = gre_ioctl;
|
2008-05-10 00:14:07 +04:00
|
|
|
sp = &sc->sc_soparm;
|
|
|
|
sockaddr_copy(sstosa(&sp->sp_dst), sizeof(sp->sp_dst),
|
|
|
|
sintocsa(&in_any));
|
|
|
|
sockaddr_copy(sstosa(&sp->sp_src), sizeof(sp->sp_src),
|
|
|
|
sintocsa(&in_any));
|
|
|
|
sp->sp_proto = IPPROTO_GRE;
|
|
|
|
sp->sp_type = SOCK_RAW;
|
|
|
|
|
|
|
|
sc->sc_fd = -1;
|
|
|
|
|
|
|
|
rc = kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL, gre_fp_recvloop, sc,
|
|
|
|
NULL, sc->sc_if.if_xname);
|
|
|
|
|
|
|
|
if (rc != 0)
|
|
|
|
return -1;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
|
|
|
|
gre_evcnt_attach(sc);
|
|
|
|
|
|
|
|
gre_bufq_init(&sc->sc_snd, 17);
|
2002-06-09 23:17:43 +04:00
|
|
|
sc->sc_if.if_flags |= IFF_LINK0;
|
2000-07-05 22:14:13 +04:00
|
|
|
if_attach(&sc->sc_if);
|
2001-01-17 03:30:49 +03:00
|
|
|
if_alloc_sadl(&sc->sc_if);
|
1998-09-14 00:27:47 +04:00
|
|
|
#if NBPFILTER > 0
|
2008-02-20 20:05:52 +03:00
|
|
|
bpfattach(&sc->sc_if, DLT_NULL, sizeof(uint32_t));
|
1998-09-14 00:27:47 +04:00
|
|
|
#endif
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
sc->sc_state = GRE_S_IDLE;
|
2007-02-23 09:13:24 +03:00
|
|
|
return 0;
|
1998-09-14 00:27:47 +04:00
|
|
|
}
|
|
|
|
|
2005-12-12 02:05:24 +03:00
|
|
|
static int
|
|
|
|
gre_clone_destroy(struct ifnet *ifp)
|
2000-07-05 22:14:13 +04:00
|
|
|
{
|
2007-11-24 10:43:32 +03:00
|
|
|
int s;
|
2000-07-05 22:14:13 +04:00
|
|
|
struct gre_softc *sc = ifp->if_softc;
|
|
|
|
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "\n");
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
|
2000-07-05 22:14:13 +04:00
|
|
|
#if NBPFILTER > 0
|
|
|
|
bpfdetach(ifp);
|
|
|
|
#endif
|
2007-12-20 21:12:11 +03:00
|
|
|
s = splnet();
|
2006-12-04 04:49:47 +03:00
|
|
|
if_detach(ifp);
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
|
2007-11-24 10:43:32 +03:00
|
|
|
/* Some LWPs may still wait in gre_ioctl_lock(), however,
|
|
|
|
* no new LWP will enter gre_ioctl_lock(), because ifunit()
|
|
|
|
* cannot locate the interface any longer.
|
|
|
|
*/
|
2007-05-06 06:47:52 +04:00
|
|
|
mutex_enter(&sc->sc_mtx);
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "\n");
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
while (sc->sc_state != GRE_S_IDLE)
|
|
|
|
gre_wait(sc);
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "\n");
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
sc->sc_state = GRE_S_DIE;
|
|
|
|
cv_broadcast(&sc->sc_condvar);
|
2008-05-10 00:14:07 +04:00
|
|
|
while (sc->sc_waiters > 0)
|
|
|
|
cv_wait(&sc->sc_condvar, &sc->sc_mtx);
|
2007-11-24 10:43:32 +03:00
|
|
|
/* At this point, no other LWP will access the gre_softc, so
|
|
|
|
* we can release the mutex.
|
|
|
|
*/
|
2007-05-06 06:47:52 +04:00
|
|
|
mutex_exit(&sc->sc_mtx);
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "\n");
|
2007-11-24 10:43:32 +03:00
|
|
|
/* Note that we must not hold the mutex while we call gre_reconf(). */
|
2008-05-10 00:14:07 +04:00
|
|
|
gre_reconf(sc, NULL);
|
|
|
|
|
|
|
|
mutex_enter(&sc->sc_mtx);
|
|
|
|
sc->sc_msg = GRE_M_STOP;
|
|
|
|
cv_signal(&sc->sc_fp_condvar);
|
|
|
|
while (sc->sc_fp_waiters > 0)
|
|
|
|
cv_wait(&sc->sc_fp_condvar, &sc->sc_mtx);
|
|
|
|
mutex_exit(&sc->sc_mtx);
|
|
|
|
|
2007-11-24 10:43:32 +03:00
|
|
|
splx(s);
|
2007-05-06 06:47:52 +04:00
|
|
|
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
cv_destroy(&sc->sc_condvar);
|
2007-05-06 06:47:52 +04:00
|
|
|
mutex_destroy(&sc->sc_mtx);
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
gre_evcnt_detach(sc);
|
2000-07-05 22:14:13 +04:00
|
|
|
free(sc, M_DEVBUF);
|
2004-12-04 21:31:43 +03:00
|
|
|
|
2007-02-23 09:13:24 +03:00
|
|
|
return 0;
|
2000-07-05 22:14:13 +04:00
|
|
|
}
|
1998-09-14 00:27:47 +04:00
|
|
|
|
2006-08-31 21:46:16 +04:00
|
|
|
static void
|
2007-03-04 08:59:00 +03:00
|
|
|
gre_receive(struct socket *so, void *arg, int waitflag)
|
2006-08-31 21:46:16 +04:00
|
|
|
{
|
|
|
|
struct gre_softc *sc = (struct gre_softc *)arg;
|
2007-10-05 08:55:10 +04:00
|
|
|
int rc;
|
|
|
|
const struct gre_h *gh;
|
|
|
|
struct mbuf *m;
|
2006-08-31 21:46:16 +04:00
|
|
|
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "enter\n");
|
2007-10-05 08:55:10 +04:00
|
|
|
|
|
|
|
sc->sc_recv_ev.ev_count++;
|
|
|
|
|
|
|
|
rc = gre_soreceive(so, &m);
|
|
|
|
/* TBD Back off if ECONNREFUSED (indicates
|
|
|
|
* ICMP Port Unreachable)?
|
|
|
|
*/
|
|
|
|
if (rc == EWOULDBLOCK) {
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "EWOULDBLOCK\n");
|
2007-10-05 08:55:10 +04:00
|
|
|
sc->sc_block_ev.ev_count++;
|
|
|
|
return;
|
|
|
|
} else if (rc != 0 || m == NULL) {
|
|
|
|
GRE_DPRINTF(sc, "%s: rc %d m %p\n",
|
|
|
|
sc->sc_if.if_xname, rc, (void *)m);
|
|
|
|
sc->sc_error_ev.ev_count++;
|
|
|
|
return;
|
|
|
|
}
|
2007-11-28 05:40:21 +03:00
|
|
|
if (m->m_len < sizeof(*gh) && (m = m_pullup(m, sizeof(*gh))) == NULL) {
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "m_pullup failed\n");
|
2007-10-05 08:55:10 +04:00
|
|
|
sc->sc_pullup_ev.ev_count++;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
gh = mtod(m, const struct gre_h *);
|
|
|
|
|
|
|
|
if (gre_input(sc, m, 0, gh) == 0) {
|
|
|
|
sc->sc_unsupp_ev.ev_count++;
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "dropping unsupported\n");
|
2007-10-05 08:55:10 +04:00
|
|
|
m_freem(m);
|
|
|
|
}
|
2006-08-31 21:46:16 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2007-03-04 08:59:00 +03:00
|
|
|
gre_upcall_add(struct socket *so, void *arg)
|
2006-08-31 21:46:16 +04:00
|
|
|
{
|
|
|
|
/* XXX What if the kernel already set an upcall? */
|
2007-08-25 03:38:31 +04:00
|
|
|
KASSERT((so->so_rcv.sb_flags & SB_UPCALL) == 0);
|
2006-08-31 21:46:16 +04:00
|
|
|
so->so_upcallarg = arg;
|
|
|
|
so->so_upcall = gre_receive;
|
|
|
|
so->so_rcv.sb_flags |= SB_UPCALL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gre_upcall_remove(struct socket *so)
|
|
|
|
{
|
|
|
|
so->so_rcv.sb_flags &= ~SB_UPCALL;
|
|
|
|
so->so_upcallarg = NULL;
|
|
|
|
so->so_upcall = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2008-05-10 00:14:07 +04:00
|
|
|
gre_socreate(struct gre_softc *sc, const struct gre_soparm *sp, int *fdout)
|
2006-08-31 21:46:16 +04:00
|
|
|
{
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
const struct protosw *pr;
|
|
|
|
int fd, rc;
|
2006-08-31 21:46:16 +04:00
|
|
|
struct mbuf *m;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
struct sockaddr *sa;
|
2006-08-31 21:46:16 +04:00
|
|
|
struct socket *so;
|
2008-05-10 00:14:07 +04:00
|
|
|
sa_family_t af;
|
2006-08-31 21:46:16 +04:00
|
|
|
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "enter\n");
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
|
|
|
|
af = sp->sp_src.ss_family;
|
2008-05-10 00:14:07 +04:00
|
|
|
rc = fsocreate(af, NULL, sp->sp_type, sp->sp_proto, curlwp, &fd);
|
2006-08-31 21:46:16 +04:00
|
|
|
if (rc != 0) {
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "fsocreate failed\n");
|
2006-08-31 21:46:16 +04:00
|
|
|
return rc;
|
|
|
|
}
|
2008-04-03 11:12:16 +04:00
|
|
|
|
2008-04-03 11:19:32 +04:00
|
|
|
if ((rc = fd_getsock(fd, &so)) != 0)
|
2008-03-22 00:54:58 +03:00
|
|
|
return rc;
|
2008-04-03 11:12:16 +04:00
|
|
|
|
2007-11-24 10:49:03 +03:00
|
|
|
if ((m = getsombuf(so, MT_SONAME)) == NULL) {
|
2006-08-31 21:46:16 +04:00
|
|
|
rc = ENOBUFS;
|
|
|
|
goto out;
|
|
|
|
}
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
sa = mtod(m, struct sockaddr *);
|
2008-05-10 00:14:07 +04:00
|
|
|
sockaddr_copy(sa, MIN(MLEN, sizeof(sp->sp_src)), sstocsa(&sp->sp_src));
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
m->m_len = sp->sp_src.ss_len;
|
2006-08-31 21:46:16 +04:00
|
|
|
|
2008-04-03 11:12:16 +04:00
|
|
|
if ((rc = sobind(so, m, curlwp)) != 0) {
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "sobind failed\n");
|
2006-08-31 21:46:16 +04:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2008-05-10 00:14:07 +04:00
|
|
|
sockaddr_copy(sa, MIN(MLEN, sizeof(sp->sp_dst)), sstocsa(&sp->sp_dst));
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
m->m_len = sp->sp_dst.ss_len;
|
2006-08-31 21:46:16 +04:00
|
|
|
|
2008-05-10 00:14:07 +04:00
|
|
|
solock(so);
|
2008-04-03 11:12:16 +04:00
|
|
|
if ((rc = soconnect(so, m, curlwp)) != 0) {
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "soconnect failed\n");
|
|
|
|
sounlock(so);
|
2006-08-31 21:46:16 +04:00
|
|
|
goto out;
|
|
|
|
}
|
2008-05-10 00:14:07 +04:00
|
|
|
sounlock(so);
|
2006-08-31 21:46:16 +04:00
|
|
|
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
/* XXX convert to a (new) SOL_SOCKET call */
|
2006-08-31 21:46:16 +04:00
|
|
|
*mtod(m, int *) = ip_gre_ttl;
|
2006-11-17 01:58:00 +03:00
|
|
|
m->m_len = sizeof(int);
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
pr = so->so_proto;
|
|
|
|
KASSERT(pr != NULL);
|
|
|
|
rc = sosetopt(so, IPPROTO_IP, IP_TTL, m);
|
2006-08-31 21:46:16 +04:00
|
|
|
m = NULL;
|
|
|
|
if (rc != 0) {
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "sosetopt ttl failed\n");
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
rc = 0;
|
|
|
|
}
|
|
|
|
rc = sosetopt(so, SOL_SOCKET, SO_NOHEADER, m_intopt(so, 1));
|
|
|
|
if (rc != 0) {
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "sosetopt SO_NOHEADER failed\n");
|
2006-08-31 21:46:16 +04:00
|
|
|
rc = 0;
|
|
|
|
}
|
|
|
|
out:
|
|
|
|
m_freem(m);
|
|
|
|
|
|
|
|
if (rc != 0)
|
2008-03-22 00:54:58 +03:00
|
|
|
fd_close(fd);
|
|
|
|
else {
|
|
|
|
fd_putfile(fd);
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
*fdout = fd;
|
2008-03-22 00:54:58 +03:00
|
|
|
}
|
2006-08-31 21:46:16 +04:00
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
static int
|
2008-05-15 05:30:48 +04:00
|
|
|
gre_sosend(struct socket *so, struct mbuf *top)
|
2007-08-25 03:38:31 +04:00
|
|
|
{
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
struct mbuf **mp;
|
|
|
|
struct proc *p;
|
|
|
|
long space, resid;
|
2008-04-24 15:38:36 +04:00
|
|
|
int error;
|
2008-05-15 05:30:48 +04:00
|
|
|
struct lwp * const l = curlwp;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
|
|
|
|
p = l->l_proc;
|
|
|
|
|
|
|
|
resid = top->m_pkthdr.len;
|
|
|
|
if (p)
|
2008-03-27 22:06:51 +03:00
|
|
|
l->l_ru.ru_msgsnd++;
|
2008-04-24 15:38:36 +04:00
|
|
|
#define snderr(errno) { error = errno; goto release; }
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
|
2008-04-24 15:38:36 +04:00
|
|
|
solock(so);
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
if ((error = sblock(&so->so_snd, M_NOWAIT)) != 0)
|
|
|
|
goto out;
|
|
|
|
if (so->so_state & SS_CANTSENDMORE)
|
|
|
|
snderr(EPIPE);
|
|
|
|
if (so->so_error) {
|
|
|
|
error = so->so_error;
|
|
|
|
so->so_error = 0;
|
|
|
|
goto release;
|
|
|
|
}
|
|
|
|
if ((so->so_state & SS_ISCONNECTED) == 0) {
|
|
|
|
if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
|
|
|
|
if ((so->so_state & SS_ISCONFIRMING) == 0)
|
|
|
|
snderr(ENOTCONN);
|
2007-08-25 03:38:31 +04:00
|
|
|
} else
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
snderr(EDESTADDRREQ);
|
|
|
|
}
|
|
|
|
space = sbspace(&so->so_snd);
|
|
|
|
if (resid > so->so_snd.sb_hiwat)
|
|
|
|
snderr(EMSGSIZE);
|
|
|
|
if (space < resid)
|
|
|
|
snderr(EWOULDBLOCK);
|
|
|
|
mp = ⊤
|
|
|
|
/*
|
|
|
|
* Data is prepackaged in "top".
|
|
|
|
*/
|
|
|
|
if (so->so_state & SS_CANTSENDMORE)
|
|
|
|
snderr(EPIPE);
|
|
|
|
error = (*so->so_proto->pr_usrreq)(so, PRU_SEND, top, NULL, NULL, l);
|
|
|
|
top = NULL;
|
|
|
|
mp = ⊤
|
|
|
|
release:
|
|
|
|
sbunlock(&so->so_snd);
|
|
|
|
out:
|
2008-04-24 15:38:36 +04:00
|
|
|
sounlock(so);
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
if (top != NULL)
|
|
|
|
m_freem(top);
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* This is a stripped-down version of soreceive() that will never
|
|
|
|
* block. It will support SOCK_DGRAM sockets. It may also support
|
|
|
|
* SOCK_SEQPACKET sockets.
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
gre_soreceive(struct socket *so, struct mbuf **mp0)
|
|
|
|
{
|
2007-10-05 08:55:10 +04:00
|
|
|
struct mbuf *m, **mp;
|
2008-04-24 15:38:36 +04:00
|
|
|
int flags, len, error, type;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
const struct protosw *pr;
|
2007-10-05 08:55:10 +04:00
|
|
|
struct mbuf *nextrecord;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
|
|
|
|
KASSERT(mp0 != NULL);
|
|
|
|
|
|
|
|
flags = MSG_DONTWAIT;
|
|
|
|
pr = so->so_proto;
|
|
|
|
mp = mp0;
|
|
|
|
type = 0;
|
|
|
|
|
|
|
|
*mp = NULL;
|
|
|
|
|
|
|
|
KASSERT(pr->pr_flags & PR_ATOMIC);
|
|
|
|
|
|
|
|
if (so->so_state & SS_ISCONFIRMING)
|
2008-04-03 11:12:16 +04:00
|
|
|
(*pr->pr_usrreq)(so, PRU_RCVD, NULL, NULL, NULL, curlwp);
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
restart:
|
2008-04-24 15:38:36 +04:00
|
|
|
if ((error = sblock(&so->so_rcv, M_NOWAIT)) != 0) {
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
return error;
|
2008-04-24 15:38:36 +04:00
|
|
|
}
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
m = so->so_rcv.sb_mb;
|
|
|
|
/*
|
|
|
|
* If we have less data than requested, do not block awaiting more.
|
|
|
|
*/
|
|
|
|
if (m == NULL) {
|
|
|
|
#ifdef DIAGNOSTIC
|
|
|
|
if (so->so_rcv.sb_cc)
|
|
|
|
panic("receive 1");
|
|
|
|
#endif
|
|
|
|
if (so->so_error) {
|
|
|
|
error = so->so_error;
|
|
|
|
so->so_error = 0;
|
|
|
|
} else if (so->so_state & SS_CANTRCVMORE)
|
|
|
|
;
|
|
|
|
else if ((so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) == 0
|
|
|
|
&& (so->so_proto->pr_flags & PR_CONNREQUIRED))
|
|
|
|
error = ENOTCONN;
|
|
|
|
else
|
|
|
|
error = EWOULDBLOCK;
|
|
|
|
goto release;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* On entry here, m points to the first record of the socket buffer.
|
|
|
|
* While we process the initial mbufs containing address and control
|
|
|
|
* info, we save a copy of m->m_nextpkt into nextrecord.
|
|
|
|
*/
|
2008-04-03 11:12:16 +04:00
|
|
|
if (curlwp != NULL)
|
|
|
|
curlwp->l_ru.ru_msgrcv++;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
KASSERT(m == so->so_rcv.sb_mb);
|
|
|
|
SBLASTRECORDCHK(&so->so_rcv, "soreceive 1");
|
|
|
|
SBLASTMBUFCHK(&so->so_rcv, "soreceive 1");
|
|
|
|
nextrecord = m->m_nextpkt;
|
|
|
|
if (pr->pr_flags & PR_ADDR) {
|
|
|
|
#ifdef DIAGNOSTIC
|
|
|
|
if (m->m_type != MT_SONAME)
|
|
|
|
panic("receive 1a");
|
|
|
|
#endif
|
|
|
|
sbfree(&so->so_rcv, m);
|
|
|
|
MFREE(m, so->so_rcv.sb_mb);
|
|
|
|
m = so->so_rcv.sb_mb;
|
|
|
|
}
|
|
|
|
while (m != NULL && m->m_type == MT_CONTROL && error == 0) {
|
|
|
|
sbfree(&so->so_rcv, m);
|
|
|
|
/*
|
|
|
|
* Dispose of any SCM_RIGHTS message that went
|
|
|
|
* through the read path rather than recv.
|
|
|
|
*/
|
|
|
|
if (pr->pr_domain->dom_dispose &&
|
|
|
|
mtod(m, struct cmsghdr *)->cmsg_type == SCM_RIGHTS)
|
|
|
|
(*pr->pr_domain->dom_dispose)(m);
|
|
|
|
MFREE(m, so->so_rcv.sb_mb);
|
|
|
|
m = so->so_rcv.sb_mb;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If m is non-NULL, we have some data to read. From now on,
|
|
|
|
* make sure to keep sb_lastrecord consistent when working on
|
|
|
|
* the last packet on the chain (nextrecord == NULL) and we
|
|
|
|
* change m->m_nextpkt.
|
|
|
|
*/
|
|
|
|
if (m != NULL) {
|
|
|
|
m->m_nextpkt = nextrecord;
|
|
|
|
/*
|
|
|
|
* If nextrecord == NULL (this is a single chain),
|
|
|
|
* then sb_lastrecord may not be valid here if m
|
|
|
|
* was changed earlier.
|
|
|
|
*/
|
|
|
|
if (nextrecord == NULL) {
|
|
|
|
KASSERT(so->so_rcv.sb_mb == m);
|
|
|
|
so->so_rcv.sb_lastrecord = m;
|
2007-08-25 03:38:31 +04:00
|
|
|
}
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
type = m->m_type;
|
|
|
|
if (type == MT_OOBDATA)
|
|
|
|
flags |= MSG_OOB;
|
|
|
|
} else {
|
|
|
|
KASSERT(so->so_rcv.sb_mb == m);
|
|
|
|
so->so_rcv.sb_mb = nextrecord;
|
|
|
|
SB_EMPTY_FIXUP(&so->so_rcv);
|
|
|
|
}
|
|
|
|
SBLASTRECORDCHK(&so->so_rcv, "soreceive 2");
|
|
|
|
SBLASTMBUFCHK(&so->so_rcv, "soreceive 2");
|
2007-08-25 03:38:31 +04:00
|
|
|
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
while (m != NULL) {
|
|
|
|
if (m->m_type == MT_OOBDATA) {
|
|
|
|
if (type != MT_OOBDATA)
|
|
|
|
break;
|
|
|
|
} else if (type == MT_OOBDATA)
|
|
|
|
break;
|
|
|
|
#ifdef DIAGNOSTIC
|
|
|
|
else if (m->m_type != MT_DATA && m->m_type != MT_HEADER)
|
|
|
|
panic("receive 3");
|
|
|
|
#endif
|
|
|
|
so->so_state &= ~SS_RCVATMARK;
|
|
|
|
if (so->so_oobmark != 0 && so->so_oobmark < m->m_len)
|
|
|
|
break;
|
|
|
|
len = m->m_len;
|
|
|
|
/*
|
|
|
|
* mp is set, just pass back the mbufs.
|
|
|
|
* Sockbuf must be consistent here (points to current mbuf,
|
|
|
|
* it points to next record) when we drop priority;
|
|
|
|
* we must note any additions to the sockbuf when we
|
|
|
|
* block interrupts again.
|
|
|
|
*/
|
|
|
|
if (m->m_flags & M_EOR)
|
|
|
|
flags |= MSG_EOR;
|
|
|
|
nextrecord = m->m_nextpkt;
|
|
|
|
sbfree(&so->so_rcv, m);
|
|
|
|
*mp = m;
|
|
|
|
mp = &m->m_next;
|
|
|
|
so->so_rcv.sb_mb = m = m->m_next;
|
|
|
|
*mp = NULL;
|
|
|
|
/*
|
|
|
|
* If m != NULL, we also know that
|
|
|
|
* so->so_rcv.sb_mb != NULL.
|
|
|
|
*/
|
|
|
|
KASSERT(so->so_rcv.sb_mb == m);
|
|
|
|
if (m) {
|
|
|
|
m->m_nextpkt = nextrecord;
|
|
|
|
if (nextrecord == NULL)
|
|
|
|
so->so_rcv.sb_lastrecord = m;
|
|
|
|
} else {
|
|
|
|
so->so_rcv.sb_mb = nextrecord;
|
|
|
|
SB_EMPTY_FIXUP(&so->so_rcv);
|
|
|
|
}
|
|
|
|
SBLASTRECORDCHK(&so->so_rcv, "soreceive 3");
|
|
|
|
SBLASTMBUFCHK(&so->so_rcv, "soreceive 3");
|
|
|
|
if (so->so_oobmark) {
|
|
|
|
so->so_oobmark -= len;
|
|
|
|
if (so->so_oobmark == 0) {
|
|
|
|
so->so_state |= SS_RCVATMARK;
|
|
|
|
break;
|
|
|
|
}
|
2007-08-25 03:38:31 +04:00
|
|
|
}
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
if (flags & MSG_EOR)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m != NULL) {
|
|
|
|
m_freem(*mp);
|
|
|
|
*mp = NULL;
|
|
|
|
error = ENOMEM;
|
|
|
|
(void) sbdroprecord(&so->so_rcv);
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* First part is an inline SB_EMPTY_FIXUP(). Second
|
|
|
|
* part makes sure sb_lastrecord is up-to-date if
|
|
|
|
* there is still data in the socket buffer.
|
|
|
|
*/
|
|
|
|
so->so_rcv.sb_mb = nextrecord;
|
|
|
|
if (so->so_rcv.sb_mb == NULL) {
|
|
|
|
so->so_rcv.sb_mbtail = NULL;
|
|
|
|
so->so_rcv.sb_lastrecord = NULL;
|
|
|
|
} else if (nextrecord->m_nextpkt == NULL)
|
|
|
|
so->so_rcv.sb_lastrecord = nextrecord;
|
|
|
|
}
|
|
|
|
SBLASTRECORDCHK(&so->so_rcv, "soreceive 4");
|
|
|
|
SBLASTMBUFCHK(&so->so_rcv, "soreceive 4");
|
|
|
|
if (pr->pr_flags & PR_WANTRCVD && so->so_pcb)
|
|
|
|
(*pr->pr_usrreq)(so, PRU_RCVD, NULL,
|
2008-04-03 11:12:16 +04:00
|
|
|
(struct mbuf *)(long)flags, NULL, curlwp);
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
if (*mp0 == NULL && (flags & MSG_EOR) == 0 &&
|
|
|
|
(so->so_state & SS_CANTRCVMORE) == 0) {
|
|
|
|
sbunlock(&so->so_rcv);
|
|
|
|
goto restart;
|
|
|
|
}
|
|
|
|
|
|
|
|
release:
|
|
|
|
sbunlock(&so->so_rcv);
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
2007-08-25 03:38:31 +04:00
|
|
|
static struct socket *
|
2008-05-10 00:14:07 +04:00
|
|
|
gre_reconf(struct gre_softc *sc, const struct gre_soparm *newsoparm)
|
2006-08-31 21:46:16 +04:00
|
|
|
{
|
|
|
|
struct ifnet *ifp = &sc->sc_if;
|
|
|
|
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "enter\n");
|
2006-08-31 21:46:16 +04:00
|
|
|
|
2007-08-25 03:38:31 +04:00
|
|
|
shutdown:
|
2008-05-10 00:14:07 +04:00
|
|
|
if (sc->sc_soparm.sp_so != NULL) {
|
|
|
|
GRE_DPRINTF(sc, "\n");
|
|
|
|
gre_upcall_remove(sc->sc_soparm.sp_so);
|
2007-11-07 03:19:54 +03:00
|
|
|
softint_disestablish(sc->sc_si);
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
sc->sc_si = NULL;
|
2008-05-10 00:14:07 +04:00
|
|
|
gre_fp_send(sc, GRE_M_DELFP, NULL);
|
2007-10-06 07:35:14 +04:00
|
|
|
gre_clearconf(&sc->sc_soparm, false);
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
}
|
|
|
|
|
2007-10-06 07:30:25 +04:00
|
|
|
if (newsoparm != NULL) {
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "\n");
|
2007-10-06 07:30:25 +04:00
|
|
|
sc->sc_soparm = *newsoparm;
|
2008-04-04 01:40:59 +04:00
|
|
|
newsoparm = NULL;
|
2007-10-06 07:30:25 +04:00
|
|
|
}
|
|
|
|
|
2008-05-10 00:14:07 +04:00
|
|
|
if (sc->sc_soparm.sp_so != NULL) {
|
|
|
|
GRE_DPRINTF(sc, "\n");
|
2007-11-07 03:19:54 +03:00
|
|
|
sc->sc_si = softint_establish(SOFTINT_NET, greintr, sc);
|
2008-05-10 00:14:07 +04:00
|
|
|
gre_upcall_add(sc->sc_soparm.sp_so, sc);
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
if ((ifp->if_flags & IFF_UP) == 0) {
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "down\n");
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
goto shutdown;
|
|
|
|
}
|
2007-08-25 03:38:31 +04:00
|
|
|
}
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "\n");
|
|
|
|
if (sc->sc_soparm.sp_so != NULL)
|
2007-08-25 03:38:31 +04:00
|
|
|
sc->sc_if.if_flags |= IFF_RUNNING;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
else {
|
|
|
|
gre_bufq_purge(&sc->sc_snd);
|
2007-08-25 03:38:31 +04:00
|
|
|
sc->sc_if.if_flags &= ~IFF_RUNNING;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
}
|
2008-05-10 00:14:07 +04:00
|
|
|
return sc->sc_soparm.sp_so;
|
2007-08-25 03:38:31 +04:00
|
|
|
}
|
2006-08-31 21:46:16 +04:00
|
|
|
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
static int
|
|
|
|
gre_input(struct gre_softc *sc, struct mbuf *m, int hlen,
|
|
|
|
const struct gre_h *gh)
|
2006-08-31 21:46:16 +04:00
|
|
|
{
|
2008-02-20 20:05:52 +03:00
|
|
|
uint16_t flags;
|
|
|
|
uint32_t af; /* af passed to BPF tap */
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
int isr, s;
|
2006-08-31 21:46:16 +04:00
|
|
|
struct ifqueue *ifq;
|
|
|
|
|
|
|
|
sc->sc_if.if_ipackets++;
|
|
|
|
sc->sc_if.if_ibytes += m->m_pkthdr.len;
|
|
|
|
|
2007-03-21 04:56:05 +03:00
|
|
|
hlen += sizeof(struct gre_h);
|
|
|
|
|
|
|
|
/* process GRE flags as packet can be of variable len */
|
|
|
|
flags = ntohs(gh->flags);
|
|
|
|
|
|
|
|
/* Checksum & Offset are present */
|
|
|
|
if ((flags & GRE_CP) | (flags & GRE_RP))
|
|
|
|
hlen += 4;
|
|
|
|
/* We don't support routing fields (variable length) */
|
|
|
|
if (flags & GRE_RP) {
|
|
|
|
sc->sc_if.if_ierrors++;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (flags & GRE_KP)
|
|
|
|
hlen += 4;
|
|
|
|
if (flags & GRE_SP)
|
|
|
|
hlen += 4;
|
|
|
|
|
|
|
|
switch (ntohs(gh->ptype)) { /* ethertypes */
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
case ETHERTYPE_IP:
|
|
|
|
ifq = &ipintrq;
|
2007-03-21 04:56:05 +03:00
|
|
|
isr = NETISR_IP;
|
2007-10-05 09:15:58 +04:00
|
|
|
af = AF_INET;
|
2007-03-21 04:56:05 +03:00
|
|
|
break;
|
2006-08-31 21:46:16 +04:00
|
|
|
#ifdef NETATALK
|
2007-03-21 04:56:05 +03:00
|
|
|
case ETHERTYPE_ATALK:
|
|
|
|
ifq = &atintrq1;
|
|
|
|
isr = NETISR_ATALK;
|
|
|
|
af = AF_APPLETALK;
|
|
|
|
break;
|
2006-08-31 21:46:16 +04:00
|
|
|
#endif
|
|
|
|
#ifdef INET6
|
2007-03-21 04:56:05 +03:00
|
|
|
case ETHERTYPE_IPV6:
|
|
|
|
ifq = &ip6intrq;
|
|
|
|
isr = NETISR_IPV6;
|
|
|
|
af = AF_INET6;
|
2006-08-31 21:46:16 +04:00
|
|
|
break;
|
2007-03-21 04:56:05 +03:00
|
|
|
#endif
|
|
|
|
default: /* others not yet supported */
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "unhandled ethertype 0x%04x\n",
|
2007-03-21 04:56:05 +03:00
|
|
|
ntohs(gh->ptype));
|
|
|
|
sc->sc_if.if_noproto++;
|
2007-02-23 09:13:24 +03:00
|
|
|
return 0;
|
2006-08-31 21:46:16 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (hlen > m->m_pkthdr.len) {
|
|
|
|
m_freem(m);
|
|
|
|
sc->sc_if.if_ierrors++;
|
2007-02-23 09:13:24 +03:00
|
|
|
return EINVAL;
|
2006-08-31 21:46:16 +04:00
|
|
|
}
|
|
|
|
m_adj(m, hlen);
|
|
|
|
|
|
|
|
#if NBPFILTER > 0
|
|
|
|
if (sc->sc_if.if_bpf != NULL)
|
|
|
|
bpf_mtap_af(sc->sc_if.if_bpf, af, m);
|
|
|
|
#endif /*NBPFILTER > 0*/
|
|
|
|
|
|
|
|
m->m_pkthdr.rcvif = &sc->sc_if;
|
|
|
|
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
s = splnet();
|
2006-08-31 21:46:16 +04:00
|
|
|
if (IF_QFULL(ifq)) {
|
|
|
|
IF_DROP(ifq);
|
|
|
|
m_freem(m);
|
|
|
|
} else {
|
|
|
|
IF_ENQUEUE(ifq, m);
|
|
|
|
}
|
|
|
|
/* we need schednetisr since the address family may change */
|
|
|
|
schednetisr(isr);
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
splx(s);
|
2006-08-31 21:46:16 +04:00
|
|
|
|
2007-02-23 09:13:24 +03:00
|
|
|
return 1; /* packet is done, no further processing needed */
|
2006-08-31 21:46:16 +04:00
|
|
|
}
|
|
|
|
|
2001-05-10 05:23:51 +04:00
|
|
|
/*
|
1998-09-14 00:27:47 +04:00
|
|
|
* The output routine. Takes a packet and encapsulates it in the protocol
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
* given by sc->sc_soparm.sp_proto. See also RFC 1701 and RFC 2004
|
1998-09-14 00:27:47 +04:00
|
|
|
*/
|
2005-12-12 02:05:24 +03:00
|
|
|
static int
|
KNF: de-__P, bzero -> memset, bcmp -> memcmp. Remove extraneous
parentheses in return statements.
Cosmetic: don't open-code TAILQ_FOREACH().
Cosmetic: change types of variables to avoid oodles of casts: in
in6_src.c, avoid casts by changing several route_in6 pointers
to struct route pointers. Remove unnecessary casts to caddr_t
elsewhere.
Pave the way for eliminating address family-specific route caches:
soon, struct route will not embed a sockaddr, but it will hold
a reference to an external sockaddr, instead. We will set the
destination sockaddr using rtcache_setdst(). (I created a stub
for it, but it isn't used anywhere, yet.) rtcache_free() will
free the sockaddr. I have extracted from rtcache_free() a helper
subroutine, rtcache_clear(). rtcache_clear() will "forget" a
cached route, but it will not forget the destination by releasing
the sockaddr. I use rtcache_clear() instead of rtcache_free()
in rtcache_update(), because rtcache_update() is not supposed
to forget the destination.
Constify:
1 Introduce const accessor for route->ro_dst, rtcache_getdst().
2 Constify the 'dst' argument to ifnet->if_output(). This
led me to constify a lot of code called by output routines.
3 Constify the sockaddr argument to protosw->pr_ctlinput. This
led me to constify a lot of code called by ctlinput routines.
4 Introduce const macros for converting from a generic sockaddr
to family-specific sockaddrs, e.g., sockaddr_in: satocsin6,
satocsin, et cetera.
2007-02-18 01:34:07 +03:00
|
|
|
gre_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
|
2006-11-16 04:32:37 +03:00
|
|
|
struct rtentry *rt)
|
1998-09-14 00:27:47 +04:00
|
|
|
{
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
int error = 0;
|
2000-07-05 22:14:13 +04:00
|
|
|
struct gre_softc *sc = ifp->if_softc;
|
2006-08-31 21:46:16 +04:00
|
|
|
struct gre_h *gh;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
struct ip *ip;
|
2008-02-20 20:05:52 +03:00
|
|
|
uint8_t ip_tos = 0;
|
|
|
|
uint16_t etype = 0;
|
1998-09-14 00:27:47 +04:00
|
|
|
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) {
|
2002-06-10 21:12:22 +04:00
|
|
|
m_freem(m);
|
2002-06-10 21:30:16 +04:00
|
|
|
error = ENETDOWN;
|
|
|
|
goto end;
|
2002-06-10 21:12:22 +04:00
|
|
|
}
|
2001-11-24 03:21:27 +03:00
|
|
|
|
2007-10-05 09:15:58 +04:00
|
|
|
#if NBPFILTER > 0
|
|
|
|
if (ifp->if_bpf != NULL)
|
2004-08-20 00:58:23 +04:00
|
|
|
bpf_mtap_af(ifp->if_bpf, dst->sa_family, m);
|
1998-09-14 00:27:47 +04:00
|
|
|
#endif
|
|
|
|
|
2002-02-24 20:22:20 +03:00
|
|
|
m->m_flags &= ~(M_BCAST|M_MCAST);
|
1998-09-14 00:27:47 +04:00
|
|
|
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "dst->sa_family=%d\n", dst->sa_family);
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
switch (dst->sa_family) {
|
|
|
|
case AF_INET:
|
2007-03-21 04:56:05 +03:00
|
|
|
ip = mtod(m, struct ip *);
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
ip_tos = ip->ip_tos;
|
|
|
|
etype = htons(ETHERTYPE_IP);
|
2006-08-31 21:46:16 +04:00
|
|
|
break;
|
1998-09-14 00:27:47 +04:00
|
|
|
#ifdef NETATALK
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
case AF_APPLETALK:
|
|
|
|
etype = htons(ETHERTYPE_ATALK);
|
|
|
|
break;
|
1998-09-14 00:27:47 +04:00
|
|
|
#endif
|
2005-03-30 20:34:54 +04:00
|
|
|
#ifdef INET6
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
case AF_INET6:
|
|
|
|
etype = htons(ETHERTYPE_IPV6);
|
2006-08-31 21:46:16 +04:00
|
|
|
break;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
#endif
|
2006-08-31 21:46:16 +04:00
|
|
|
default:
|
1998-09-14 00:27:47 +04:00
|
|
|
IF_DROP(&ifp->if_snd);
|
|
|
|
m_freem(m);
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
error = EAFNOSUPPORT;
|
2002-06-10 21:30:16 +04:00
|
|
|
goto end;
|
1998-09-14 00:27:47 +04:00
|
|
|
}
|
|
|
|
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
M_PREPEND(m, sizeof(*gh), M_DONTWAIT);
|
2006-08-31 21:46:16 +04:00
|
|
|
|
|
|
|
if (m == NULL) {
|
1998-09-14 00:27:47 +04:00
|
|
|
IF_DROP(&ifp->if_snd);
|
2002-06-10 21:30:16 +04:00
|
|
|
error = ENOBUFS;
|
|
|
|
goto end;
|
1998-09-14 00:27:47 +04:00
|
|
|
}
|
|
|
|
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
gh = mtod(m, struct gre_h *);
|
|
|
|
gh->flags = 0;
|
|
|
|
gh->ptype = etype;
|
|
|
|
/* XXX Need to handle IP ToS. Look at how I handle IP TTL. */
|
1998-09-14 00:27:47 +04:00
|
|
|
|
|
|
|
ifp->if_opackets++;
|
1999-06-28 11:52:38 +04:00
|
|
|
ifp->if_obytes += m->m_pkthdr.len;
|
2006-08-31 21:46:16 +04:00
|
|
|
|
1998-09-14 00:27:47 +04:00
|
|
|
/* send it off */
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
if ((error = gre_bufq_enqueue(&sc->sc_snd, m)) != 0) {
|
|
|
|
sc->sc_oflow_ev.ev_count++;
|
2007-04-15 02:41:42 +04:00
|
|
|
m_freem(m);
|
2007-10-05 08:55:10 +04:00
|
|
|
} else
|
2007-11-07 03:19:54 +03:00
|
|
|
softint_schedule(sc->sc_si);
|
2002-06-10 21:30:16 +04:00
|
|
|
end:
|
1999-06-28 11:52:38 +04:00
|
|
|
if (error)
|
1998-09-14 00:27:47 +04:00
|
|
|
ifp->if_oerrors++;
|
2007-02-23 09:13:24 +03:00
|
|
|
return error;
|
1998-09-14 00:27:47 +04:00
|
|
|
}
|
|
|
|
|
2006-08-31 21:46:16 +04:00
|
|
|
static int
|
|
|
|
gre_getname(struct socket *so, int req, struct mbuf *nam, struct lwp *l)
|
|
|
|
{
|
2007-05-06 06:47:52 +04:00
|
|
|
return (*so->so_proto->pr_usrreq)(so, req, NULL, nam, NULL, l);
|
2006-08-31 21:46:16 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
gre_getsockname(struct socket *so, struct mbuf *nam, struct lwp *l)
|
|
|
|
{
|
|
|
|
return gre_getname(so, PRU_SOCKADDR, nam, l);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
gre_getpeername(struct socket *so, struct mbuf *nam, struct lwp *l)
|
|
|
|
{
|
|
|
|
return gre_getname(so, PRU_PEERADDR, nam, l);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
gre_getnames(struct socket *so, struct lwp *l, struct sockaddr_storage *src,
|
|
|
|
struct sockaddr_storage *dst)
|
2006-08-31 21:46:16 +04:00
|
|
|
{
|
|
|
|
struct mbuf *m;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
struct sockaddr_storage *ss;
|
2006-08-31 21:46:16 +04:00
|
|
|
int rc;
|
|
|
|
|
2007-11-24 10:49:03 +03:00
|
|
|
if ((m = getsombuf(so, MT_SONAME)) == NULL)
|
2006-08-31 21:46:16 +04:00
|
|
|
return ENOBUFS;
|
|
|
|
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
ss = mtod(m, struct sockaddr_storage *);
|
2006-08-31 21:46:16 +04:00
|
|
|
|
2008-04-24 15:38:36 +04:00
|
|
|
solock(so);
|
2006-08-31 21:46:16 +04:00
|
|
|
if ((rc = gre_getsockname(so, m, l)) != 0)
|
|
|
|
goto out;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
*src = *ss;
|
2006-08-31 21:46:16 +04:00
|
|
|
|
|
|
|
if ((rc = gre_getpeername(so, m, l)) != 0)
|
|
|
|
goto out;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
*dst = *ss;
|
2006-08-31 21:46:16 +04:00
|
|
|
out:
|
2008-04-24 15:38:36 +04:00
|
|
|
sounlock(so);
|
2006-08-31 21:46:16 +04:00
|
|
|
m_freem(m);
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2007-05-06 06:47:52 +04:00
|
|
|
static void
|
2008-05-10 00:14:07 +04:00
|
|
|
gre_fp_recvloop(void *arg)
|
2007-05-06 06:47:52 +04:00
|
|
|
{
|
2008-05-10 00:14:07 +04:00
|
|
|
struct gre_softc *sc = arg;
|
2007-05-06 06:47:52 +04:00
|
|
|
|
2008-05-10 00:14:07 +04:00
|
|
|
mutex_enter(&sc->sc_mtx);
|
|
|
|
while (gre_fp_recv(sc))
|
|
|
|
;
|
|
|
|
mutex_exit(&sc->sc_mtx);
|
|
|
|
kthread_exit(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool
|
|
|
|
gre_fp_recv(struct gre_softc *sc)
|
|
|
|
{
|
|
|
|
int fd, ofd, rc;
|
|
|
|
file_t *fp;
|
|
|
|
|
|
|
|
fp = sc->sc_fp;
|
|
|
|
ofd = sc->sc_fd;
|
|
|
|
fd = -1;
|
|
|
|
|
|
|
|
switch (sc->sc_msg) {
|
|
|
|
case GRE_M_STOP:
|
|
|
|
cv_signal(&sc->sc_fp_condvar);
|
|
|
|
return false;
|
|
|
|
case GRE_M_SETFP:
|
|
|
|
mutex_exit(&sc->sc_mtx);
|
|
|
|
rc = fd_dup(fp, 0, &fd, 0);
|
|
|
|
mutex_enter(&sc->sc_mtx);
|
|
|
|
if (rc != 0) {
|
|
|
|
sc->sc_msg = GRE_M_ERR;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/*FALLTHROUGH*/
|
|
|
|
case GRE_M_DELFP:
|
|
|
|
mutex_exit(&sc->sc_mtx);
|
|
|
|
if (ofd != -1 && fd_getfile(ofd) != NULL)
|
|
|
|
fd_close(ofd);
|
|
|
|
mutex_enter(&sc->sc_mtx);
|
|
|
|
sc->sc_fd = fd;
|
|
|
|
sc->sc_msg = GRE_M_OK;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
gre_fp_wait(sc);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
cv_signal(&sc->sc_fp_condvar);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool
|
|
|
|
gre_fp_send(struct gre_softc *sc, enum gre_msg msg, file_t *fp)
|
|
|
|
{
|
|
|
|
bool rc;
|
|
|
|
|
|
|
|
mutex_enter(&sc->sc_mtx);
|
|
|
|
while (sc->sc_msg != GRE_M_NONE)
|
|
|
|
gre_fp_wait(sc);
|
|
|
|
sc->sc_fp = fp;
|
|
|
|
sc->sc_msg = msg;
|
|
|
|
cv_signal(&sc->sc_fp_condvar);
|
|
|
|
while (sc->sc_msg != GRE_M_STOP && sc->sc_msg != GRE_M_OK &&
|
|
|
|
sc->sc_msg != GRE_M_ERR)
|
|
|
|
gre_fp_wait(sc);
|
|
|
|
rc = (sc->sc_msg != GRE_M_ERR);
|
|
|
|
sc->sc_msg = GRE_M_NONE;
|
|
|
|
cv_signal(&sc->sc_fp_condvar);
|
|
|
|
mutex_exit(&sc->sc_mtx);
|
|
|
|
return rc;
|
2007-05-06 06:47:52 +04:00
|
|
|
}
|
|
|
|
|
2005-12-12 02:05:24 +03:00
|
|
|
static int
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
gre_ssock(struct ifnet *ifp, struct gre_soparm *sp, int fd)
|
1998-09-14 00:27:47 +04:00
|
|
|
{
|
2008-05-10 00:14:07 +04:00
|
|
|
int error = 0;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
const struct protosw *pr;
|
2008-03-22 00:54:58 +03:00
|
|
|
file_t *fp;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
struct gre_softc *sc = ifp->if_softc;
|
2006-08-31 21:46:16 +04:00
|
|
|
struct socket *so;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
struct sockaddr_storage dst, src;
|
|
|
|
|
2008-05-10 00:14:07 +04:00
|
|
|
if ((error = getsock(fd, &fp)) != 0)
|
|
|
|
return error;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "\n");
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
|
|
|
|
so = (struct socket *)fp->f_data;
|
|
|
|
pr = so->so_proto;
|
2008-05-10 00:14:07 +04:00
|
|
|
|
|
|
|
GRE_DPRINTF(sc, "type %d, proto %d\n", pr->pr_type, pr->pr_protocol);
|
|
|
|
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
if ((pr->pr_flags & PR_ATOMIC) == 0 ||
|
|
|
|
(sp->sp_type != 0 && pr->pr_type != sp->sp_type) ||
|
|
|
|
(sp->sp_proto != 0 && pr->pr_protocol != 0 &&
|
|
|
|
pr->pr_protocol != sp->sp_proto)) {
|
|
|
|
error = EINVAL;
|
2008-05-10 00:14:07 +04:00
|
|
|
goto err;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
}
|
|
|
|
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "\n");
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
|
|
|
|
/* check address */
|
2008-04-03 11:12:16 +04:00
|
|
|
if ((error = gre_getnames(so, curlwp, &src, &dst)) != 0)
|
2008-05-10 00:14:07 +04:00
|
|
|
goto err;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "\n");
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
|
2008-05-10 00:14:07 +04:00
|
|
|
if (!gre_fp_send(sc, GRE_M_SETFP, fp)) {
|
|
|
|
error = EBUSY;
|
|
|
|
goto err;
|
|
|
|
}
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "\n");
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
|
|
|
|
sp->sp_src = src;
|
|
|
|
sp->sp_dst = dst;
|
|
|
|
|
2008-05-10 00:14:07 +04:00
|
|
|
sp->sp_so = so;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
|
2008-05-10 00:14:07 +04:00
|
|
|
err:
|
|
|
|
fd_putfile(fd);
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool
|
|
|
|
sockaddr_is_anyaddr(const struct sockaddr *sa)
|
|
|
|
{
|
|
|
|
socklen_t anylen, salen;
|
|
|
|
const void *anyaddr, *addr;
|
|
|
|
|
|
|
|
if ((anyaddr = sockaddr_anyaddr(sa, &anylen)) == NULL ||
|
|
|
|
(addr = sockaddr_const_addr(sa, &salen)) == NULL)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (salen > anylen)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return memcmp(anyaddr, addr, MIN(anylen, salen)) == 0;
|
|
|
|
}
|
|
|
|
|
2007-10-06 07:35:14 +04:00
|
|
|
static bool
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
gre_is_nullconf(const struct gre_soparm *sp)
|
|
|
|
{
|
|
|
|
return sockaddr_is_anyaddr(sstocsa(&sp->sp_src)) ||
|
|
|
|
sockaddr_is_anyaddr(sstocsa(&sp->sp_dst));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2007-10-06 07:35:14 +04:00
|
|
|
gre_clearconf(struct gre_soparm *sp, bool force)
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
{
|
|
|
|
if (sp->sp_bysock || force) {
|
|
|
|
sockaddr_copy(sstosa(&sp->sp_src), sizeof(sp->sp_src),
|
|
|
|
sockaddr_any(sstosa(&sp->sp_src)));
|
|
|
|
sockaddr_copy(sstosa(&sp->sp_dst), sizeof(sp->sp_dst),
|
|
|
|
sockaddr_any(sstosa(&sp->sp_dst)));
|
2008-05-10 00:14:07 +04:00
|
|
|
sp->sp_bysock = false;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
}
|
2008-05-10 00:14:07 +04:00
|
|
|
sp->sp_so = NULL; /* XXX */
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
}
|
|
|
|
|
2007-11-24 10:43:32 +03:00
|
|
|
static int
|
|
|
|
gre_ioctl_lock(struct gre_softc *sc)
|
|
|
|
{
|
|
|
|
mutex_enter(&sc->sc_mtx);
|
|
|
|
|
|
|
|
while (sc->sc_state == GRE_S_IOCTL)
|
|
|
|
gre_wait(sc);
|
|
|
|
|
|
|
|
if (sc->sc_state != GRE_S_IDLE) {
|
|
|
|
cv_signal(&sc->sc_condvar);
|
|
|
|
mutex_exit(&sc->sc_mtx);
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "\n");
|
2007-11-24 10:43:32 +03:00
|
|
|
return ENXIO;
|
|
|
|
}
|
|
|
|
|
|
|
|
sc->sc_state = GRE_S_IOCTL;
|
|
|
|
|
|
|
|
mutex_exit(&sc->sc_mtx);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gre_ioctl_unlock(struct gre_softc *sc)
|
|
|
|
{
|
|
|
|
mutex_enter(&sc->sc_mtx);
|
|
|
|
|
|
|
|
KASSERT(sc->sc_state == GRE_S_IOCTL);
|
|
|
|
sc->sc_state = GRE_S_IDLE;
|
|
|
|
cv_signal(&sc->sc_condvar);
|
|
|
|
|
|
|
|
mutex_exit(&sc->sc_mtx);
|
|
|
|
}
|
|
|
|
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
static int
|
|
|
|
gre_ioctl(struct ifnet *ifp, const u_long cmd, void *data)
|
|
|
|
{
|
2007-05-30 01:32:27 +04:00
|
|
|
struct ifreq *ifr;
|
2002-06-09 21:10:09 +04:00
|
|
|
struct if_laddrreq *lifr = (struct if_laddrreq *)data;
|
1999-06-28 11:52:38 +04:00
|
|
|
struct gre_softc *sc = ifp->if_softc;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
struct gre_soparm *sp;
|
2007-11-24 10:43:32 +03:00
|
|
|
int fd, error = 0, oproto, otype, s;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
struct gre_soparm sp0;
|
2007-09-02 05:50:58 +04:00
|
|
|
|
|
|
|
ifr = data;
|
|
|
|
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "cmd %lu\n", cmd);
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
|
2006-07-24 02:06:03 +04:00
|
|
|
switch (cmd) {
|
|
|
|
case SIOCSIFFLAGS:
|
|
|
|
case SIOCSIFMTU:
|
|
|
|
case GRESPROTO:
|
|
|
|
case GRESADDRD:
|
|
|
|
case GRESADDRS:
|
2006-08-31 21:46:16 +04:00
|
|
|
case GRESSOCK:
|
|
|
|
case GREDSOCK:
|
2006-07-24 02:06:03 +04:00
|
|
|
case SIOCSLIFPHYADDR:
|
|
|
|
case SIOCDIFPHYADDR:
|
2008-04-03 11:12:16 +04:00
|
|
|
if (kauth_authorize_network(curlwp->l_cred,
|
|
|
|
KAUTH_NETWORK_INTERFACE,
|
2006-10-26 00:28:45 +04:00
|
|
|
KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, (void *)cmd,
|
|
|
|
NULL) != 0)
|
2007-02-23 09:13:24 +03:00
|
|
|
return EPERM;
|
2006-07-24 02:06:03 +04:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
1998-09-14 00:27:47 +04:00
|
|
|
|
2007-11-24 10:43:32 +03:00
|
|
|
if ((error = gre_ioctl_lock(sc)) != 0) {
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "\n");
|
2007-11-24 10:43:32 +03:00
|
|
|
return error;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
}
|
2007-11-24 10:43:32 +03:00
|
|
|
s = splnet();
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
|
|
|
|
sp0 = sc->sc_soparm;
|
2008-05-10 00:14:07 +04:00
|
|
|
sp0.sp_so = NULL;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
sp = &sp0;
|
|
|
|
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "\n");
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
|
2001-05-10 05:23:51 +04:00
|
|
|
switch (cmd) {
|
|
|
|
case SIOCSIFADDR:
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "\n");
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
if ((ifp->if_flags & IFF_UP) != 0)
|
|
|
|
break;
|
2007-10-06 07:35:14 +04:00
|
|
|
gre_clearconf(sp, false);
|
2002-06-10 21:07:51 +04:00
|
|
|
ifp->if_flags |= IFF_UP;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
goto mksocket;
|
2005-02-27 01:45:09 +03:00
|
|
|
case SIOCSIFDSTADDR:
|
1998-09-14 00:27:47 +04:00
|
|
|
break;
|
|
|
|
case SIOCSIFFLAGS:
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
oproto = sp->sp_proto;
|
|
|
|
otype = sp->sp_type;
|
2006-08-31 21:46:16 +04:00
|
|
|
switch (ifr->ifr_flags & (IFF_LINK0|IFF_LINK2)) {
|
|
|
|
case IFF_LINK0|IFF_LINK2:
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
sp->sp_proto = IPPROTO_UDP;
|
|
|
|
sp->sp_type = SOCK_DGRAM;
|
|
|
|
break;
|
|
|
|
case IFF_LINK2:
|
|
|
|
sp->sp_proto = 0;
|
|
|
|
sp->sp_type = 0;
|
2006-08-31 21:46:16 +04:00
|
|
|
break;
|
|
|
|
case IFF_LINK0:
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
sp->sp_proto = IPPROTO_GRE;
|
|
|
|
sp->sp_type = SOCK_RAW;
|
|
|
|
break;
|
|
|
|
default:
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "\n");
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
error = EINVAL;
|
|
|
|
goto out;
|
|
|
|
}
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "\n");
|
2007-10-06 07:35:14 +04:00
|
|
|
gre_clearconf(sp, false);
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) ==
|
|
|
|
(IFF_UP|IFF_RUNNING) &&
|
|
|
|
(oproto == sp->sp_proto || sp->sp_proto == 0) &&
|
|
|
|
(otype == sp->sp_type || sp->sp_type == 0))
|
|
|
|
break;
|
|
|
|
switch (sp->sp_proto) {
|
|
|
|
case IPPROTO_UDP:
|
|
|
|
case IPPROTO_GRE:
|
|
|
|
goto mksocket;
|
|
|
|
default:
|
|
|
|
break;
|
2006-08-31 21:46:16 +04:00
|
|
|
}
|
1998-09-14 00:27:47 +04:00
|
|
|
break;
|
2001-05-10 05:23:51 +04:00
|
|
|
case SIOCSIFMTU:
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
/* XXX determine MTU automatically by probing w/
|
|
|
|
* XXX do-not-fragment packets?
|
|
|
|
*/
|
2002-06-09 13:45:39 +04:00
|
|
|
if (ifr->ifr_mtu < 576) {
|
1998-09-14 00:27:47 +04:00
|
|
|
error = EINVAL;
|
|
|
|
break;
|
|
|
|
}
|
2008-02-07 04:21:52 +03:00
|
|
|
/*FALLTHROUGH*/
|
1998-09-14 00:27:47 +04:00
|
|
|
case SIOCGIFMTU:
|
2008-02-07 04:21:52 +03:00
|
|
|
if ((error = ifioctl_common(ifp, cmd, data)) == ENETRESET)
|
|
|
|
error = 0;
|
1998-09-14 00:27:47 +04:00
|
|
|
break;
|
|
|
|
case SIOCADDMULTI:
|
|
|
|
case SIOCDELMULTI:
|
2007-09-02 05:49:49 +04:00
|
|
|
if (ifr == NULL) {
|
1998-09-14 00:27:47 +04:00
|
|
|
error = EAFNOSUPPORT;
|
|
|
|
break;
|
|
|
|
}
|
2007-09-02 05:49:49 +04:00
|
|
|
switch (ifreq_getaddr(cmd, ifr)->sa_family) {
|
1998-09-14 00:27:47 +04:00
|
|
|
#ifdef INET
|
|
|
|
case AF_INET:
|
|
|
|
break;
|
2005-03-30 20:34:54 +04:00
|
|
|
#endif
|
|
|
|
#ifdef INET6
|
|
|
|
case AF_INET6:
|
|
|
|
break;
|
1998-09-14 00:27:47 +04:00
|
|
|
#endif
|
|
|
|
default:
|
|
|
|
error = EAFNOSUPPORT;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case GRESPROTO:
|
2007-10-06 07:35:14 +04:00
|
|
|
gre_clearconf(sp, false);
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
oproto = sp->sp_proto;
|
|
|
|
otype = sp->sp_type;
|
|
|
|
sp->sp_proto = ifr->ifr_flags;
|
|
|
|
switch (sp->sp_proto) {
|
2006-08-31 21:46:16 +04:00
|
|
|
case IPPROTO_UDP:
|
|
|
|
ifp->if_flags |= IFF_LINK0|IFF_LINK2;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
sp->sp_type = SOCK_DGRAM;
|
2006-08-31 21:46:16 +04:00
|
|
|
break;
|
2002-06-10 21:40:26 +04:00
|
|
|
case IPPROTO_GRE:
|
1998-09-30 09:59:27 +04:00
|
|
|
ifp->if_flags |= IFF_LINK0;
|
2006-08-31 21:46:16 +04:00
|
|
|
ifp->if_flags &= ~IFF_LINK2;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
sp->sp_type = SOCK_RAW;
|
|
|
|
break;
|
|
|
|
case 0:
|
|
|
|
ifp->if_flags &= ~IFF_LINK0;
|
|
|
|
ifp->if_flags |= IFF_LINK2;
|
|
|
|
sp->sp_type = 0;
|
|
|
|
break;
|
1998-09-14 00:27:47 +04:00
|
|
|
default:
|
2002-06-10 21:40:26 +04:00
|
|
|
error = EPROTONOSUPPORT;
|
2002-06-09 23:17:43 +04:00
|
|
|
break;
|
1998-09-14 00:27:47 +04:00
|
|
|
}
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
if ((oproto == sp->sp_proto || sp->sp_proto == 0) &&
|
|
|
|
(otype == sp->sp_type || sp->sp_type == 0))
|
|
|
|
break;
|
|
|
|
switch (sp->sp_proto) {
|
|
|
|
case IPPROTO_UDP:
|
|
|
|
case IPPROTO_GRE:
|
|
|
|
goto mksocket;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
1998-09-14 00:27:47 +04:00
|
|
|
break;
|
|
|
|
case GREGPROTO:
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
ifr->ifr_flags = sp->sp_proto;
|
1998-09-14 00:27:47 +04:00
|
|
|
break;
|
|
|
|
case GRESADDRS:
|
|
|
|
case GRESADDRD:
|
2007-10-06 07:35:14 +04:00
|
|
|
gre_clearconf(sp, false);
|
2008-05-10 00:14:07 +04:00
|
|
|
/* set tunnel endpoints and mark interface as up */
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
switch (cmd) {
|
|
|
|
case GRESADDRS:
|
|
|
|
sockaddr_copy(sstosa(&sp->sp_src),
|
|
|
|
sizeof(sp->sp_src), ifreq_getaddr(cmd, ifr));
|
2007-05-06 06:47:52 +04:00
|
|
|
break;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
case GRESADDRD:
|
|
|
|
sockaddr_copy(sstosa(&sp->sp_dst),
|
|
|
|
sizeof(sp->sp_dst), ifreq_getaddr(cmd, ifr));
|
2007-05-06 06:47:52 +04:00
|
|
|
break;
|
|
|
|
}
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
checkaddr:
|
|
|
|
if (sockaddr_any(sstosa(&sp->sp_src)) == NULL ||
|
|
|
|
sockaddr_any(sstosa(&sp->sp_dst)) == NULL) {
|
2007-08-25 03:38:31 +04:00
|
|
|
error = EINVAL;
|
2006-08-31 21:46:16 +04:00
|
|
|
break;
|
2007-08-25 03:38:31 +04:00
|
|
|
}
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
/* let gre_socreate() check the rest */
|
|
|
|
mksocket:
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "\n");
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
/* If we're administratively down, or the configuration
|
|
|
|
* is empty, there's no use creating a socket.
|
|
|
|
*/
|
|
|
|
if ((ifp->if_flags & IFF_UP) == 0 || gre_is_nullconf(sp))
|
|
|
|
goto sendconf;
|
|
|
|
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "\n");
|
2008-04-03 11:12:16 +04:00
|
|
|
fd = 0;
|
|
|
|
error = gre_socreate(sc, sp, &fd);
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
if (error != 0)
|
2006-08-31 21:46:16 +04:00
|
|
|
break;
|
|
|
|
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
setsock:
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "\n");
|
2007-05-06 06:47:52 +04:00
|
|
|
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
error = gre_ssock(ifp, sp, fd);
|
2007-05-06 06:47:52 +04:00
|
|
|
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
if (cmd != GRESSOCK) {
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "\n");
|
2008-03-22 00:54:58 +03:00
|
|
|
/* XXX v. dodgy */
|
|
|
|
if (fd_getfile(fd) != NULL)
|
|
|
|
fd_close(fd);
|
2007-05-06 06:47:52 +04:00
|
|
|
}
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
|
2007-05-06 06:47:52 +04:00
|
|
|
if (error == 0) {
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
sendconf:
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "\n");
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
ifp->if_flags &= ~IFF_RUNNING;
|
2008-05-10 00:14:07 +04:00
|
|
|
gre_reconf(sc, sp);
|
2007-05-06 06:47:52 +04:00
|
|
|
}
|
2006-08-31 21:46:16 +04:00
|
|
|
|
|
|
|
break;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
case GREGADDRS:
|
|
|
|
ifreq_setaddr(cmd, ifr, sstosa(&sp->sp_src));
|
|
|
|
break;
|
|
|
|
case GREGADDRD:
|
|
|
|
ifreq_setaddr(cmd, ifr, sstosa(&sp->sp_dst));
|
|
|
|
break;
|
|
|
|
case GREDSOCK:
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "\n");
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
if (sp->sp_bysock)
|
|
|
|
ifp->if_flags &= ~IFF_UP;
|
2007-10-06 07:35:14 +04:00
|
|
|
gre_clearconf(sp, false);
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
goto mksocket;
|
|
|
|
case GRESSOCK:
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "\n");
|
2007-10-06 07:35:14 +04:00
|
|
|
gre_clearconf(sp, true);
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
fd = (int)ifr->ifr_value;
|
2008-05-10 00:14:07 +04:00
|
|
|
sp->sp_bysock = true;
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
ifp->if_flags |= IFF_UP;
|
|
|
|
goto setsock;
|
2002-06-09 21:10:09 +04:00
|
|
|
case SIOCSLIFPHYADDR:
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "\n");
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
if (lifr->addr.ss_family != lifr->dstaddr.ss_family) {
|
2002-06-09 21:18:32 +04:00
|
|
|
error = EAFNOSUPPORT;
|
|
|
|
break;
|
|
|
|
}
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
sockaddr_copy(sstosa(&sp->sp_src), sizeof(sp->sp_src),
|
|
|
|
sstosa(&lifr->addr));
|
|
|
|
sockaddr_copy(sstosa(&sp->sp_dst), sizeof(sp->sp_dst),
|
|
|
|
sstosa(&lifr->dstaddr));
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "\n");
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
goto checkaddr;
|
2002-06-09 21:10:09 +04:00
|
|
|
case SIOCDIFPHYADDR:
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "\n");
|
2007-10-06 07:35:14 +04:00
|
|
|
gre_clearconf(sp, true);
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
ifp->if_flags &= ~IFF_UP;
|
|
|
|
goto mksocket;
|
2002-06-09 21:10:09 +04:00
|
|
|
case SIOCGLIFPHYADDR:
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "\n");
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
if (gre_is_nullconf(sp)) {
|
2002-06-09 21:10:09 +04:00
|
|
|
error = EADDRNOTAVAIL;
|
|
|
|
break;
|
|
|
|
}
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
sockaddr_copy(sstosa(&lifr->addr), sizeof(lifr->addr),
|
|
|
|
sstosa(&sp->sp_src));
|
|
|
|
sockaddr_copy(sstosa(&lifr->dstaddr), sizeof(lifr->dstaddr),
|
|
|
|
sstosa(&sp->sp_dst));
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "\n");
|
2002-06-09 21:10:09 +04:00
|
|
|
break;
|
1998-09-14 00:27:47 +04:00
|
|
|
default:
|
|
|
|
error = EINVAL;
|
2002-06-09 21:18:32 +04:00
|
|
|
break;
|
1998-09-14 00:27:47 +04:00
|
|
|
}
|
Work in progress: use a raw socket for GRE in IP encapsulation
instead of adding/subtracting our own IPv4 header.
There are many benefits: gre(4) needn't grok the outer encapsulation
header any longer, so this simplifies the gre(4) code. The IP
stack needn't grok GRE, so it is simplified, too. gre(4) will
benefit from optimizations in the socket code. Eventually, gre(4)
will gain an IPv6 encapsulation with very few new lines of code.
There is a small performance loss. A 133 MHz, 486-class AMD Elan
sinks/sources a TCP stream over GRE with about 93% the throughput
of the old code. TCP throughput on a 266 MHz, 586-class AMD Geode
is about 96% the throughput of the old code. A 175-MHz ADM5120
(MIPS) only sinks a TCP stream over GRE at about 90% of the old
code; I am still investigating that.
I produced stripped-down versions of sosend() and soreceive() for
gre(4) to use. They are guaranteed not to block, so they can be
called from a software interrupt and from a socket upcall,
respectively.
A kernel thread is no longer necessary for socket transmit/receive,
but I didn't get around to removing it, yet.
Thanks to Matt Thomas for suggesting the use of stripped-down socket
code and software interrupts, and to Andrew Doran for advice and
answers concerning software interrupts, threads, and performance.
2007-10-05 07:28:12 +04:00
|
|
|
out:
|
2008-05-10 00:14:07 +04:00
|
|
|
GRE_DPRINTF(sc, "\n");
|
2007-11-24 10:43:32 +03:00
|
|
|
splx(s);
|
|
|
|
gre_ioctl_unlock(sc);
|
2007-02-23 09:13:24 +03:00
|
|
|
return error;
|
1998-09-14 00:27:47 +04:00
|
|
|
}
|
|
|
|
|
2004-12-06 05:59:23 +03:00
|
|
|
#endif
|
|
|
|
|
2005-12-12 02:05:24 +03:00
|
|
|
void greattach(int);
|
2004-12-06 05:59:23 +03:00
|
|
|
|
|
|
|
/* ARGSUSED */
|
|
|
|
void
|
2006-11-16 04:32:37 +03:00
|
|
|
greattach(int count)
|
2004-12-06 05:59:23 +03:00
|
|
|
{
|
|
|
|
#ifdef INET
|
|
|
|
if_clone_attach(&gre_cloner);
|
|
|
|
#endif
|
|
|
|
}
|