Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys Add an in-kernel PPPoE (ppp over ethernet, RFC 2516) imp...
details: https://anonhg.NetBSD.org/src/rev/1e7d56bf0325
branches: trunk
changeset: 509198:1e7d56bf0325
user: martin <martin%NetBSD.org@localhost>
date: Sun Apr 29 09:50:36 2001 +0000
description:
Add an in-kernel PPPoE (ppp over ethernet, RFC 2516) implementation,
based on the existing net/if_spppsubr.c stuff.
While there are completely userland (bpf based) implementations available,
those have a vastly larger per packet overhead thus causing major CPU
overhead and higher latency. On an i386 base router, running a 486DX at 50MHz
my line (768kBit/s downstream) was limited to something (varying) between 10
and 20 kByte/s effective download rate. With this implementation I get full
bandwidth (~85kByte/s).
This is client side only. Arguably the right way to add full PPPoE support
(including server side) would be a variation of the ppp line discipline and
appropriate modifications to pppd. I promise every help I can give to anyone
doing that - but I needed this realy fast. Besids, on low memory NAT boxes
with typically a single PPPoE connection, this implementation is more
lightweight than a pppd based one, which nicely fits my needs.
diffstat:
sys/conf/files | 6 +-
sys/net/Makefile | 4 +-
sys/net/dlt.h | 4 +-
sys/net/if_ethersubr.c | 30 +-
sys/net/if_pppoe.c | 965 +++++++++++++++++++++++++++++++++++++++++++++++++
sys/net/if_pppoe.h | 54 ++
6 files changed, 1056 insertions(+), 7 deletions(-)
diffs (truncated from 1161 to 300 lines):
diff -r 0342763e4fec -r 1e7d56bf0325 sys/conf/files
--- a/sys/conf/files Sun Apr 29 08:37:04 2001 +0000
+++ b/sys/conf/files Sun Apr 29 09:50:36 2001 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files,v 1.434 2001/04/20 16:39:22 fredette Exp $
+# $NetBSD: files,v 1.435 2001/04/29 09:50:36 martin Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
@@ -633,6 +633,7 @@
defpseudo loop: ifnet
defpseudo sl: ifnet
defpseudo ppp: ifnet, bpf_filter
+defpseudo pppoe: ifnet, ether, sppp
defpseudo sppp: ifnet
defpseudo tun: ifnet
defpseudo vlan: ifnet, ether
@@ -923,7 +924,7 @@
file net/if_bridge.c bridge needs-flag
file net/bridgestp.c bridge
file net/if_ethersubr.c ether | fddi | netatalk | token |
- wlan | vlan
+ wlan | vlan | pppoe
file net/if_faith.c faith needs-flag
file net/if_fddisubr.c fddi needs-flag
file net/if_gif.c gif needs-flag
@@ -940,6 +941,7 @@
file net/if_tokensubr.c token needs-flag
file net/if_tun.c tun needs-count
file net/if_vlan.c vlan needs-flag
+file net/if_pppoe.c pppoe needs-count
#file net/net_osdep.c
file net/pfil.c pfil_hooks | ipfilter
file net/ppp-deflate.c ppp & ppp_deflate
diff -r 0342763e4fec -r 1e7d56bf0325 sys/net/Makefile
--- a/sys/net/Makefile Sun Apr 29 08:37:04 2001 +0000
+++ b/sys/net/Makefile Sun Apr 29 09:50:36 2001 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.9 2000/12/12 17:53:00 thorpej Exp $
+# $NetBSD: Makefile,v 1.10 2001/04/29 09:50:36 martin Exp $
KDIR= /sys/net
INCSDIR= /usr/include/net
@@ -6,7 +6,7 @@
INCS= bpf.h bpfdesc.h dlt.h ethertypes.h if.h if_arc.h if_arp.h \
if_atm.h if_dl.h if_ether.h if_fddi.h if_gif.h \
if_gre.h if_hippi.h if_ieee80211.h if_llc.h if_media.h \
- if_ppp.h if_pppvar.h if_slvar.h if_sppp.h if_stf.h \
+ if_ppp.h if_pppvar.h if_pppoe.h if_slvar.h if_sppp.h if_stf.h \
if_stripvar.h if_token.h if_tun.h if_types.h if_vlanvar.h \
netisr.h pfil.h pfkeyv2.h ppp-comp.h ppp_defs.h radix.h \
raw_cb.h route.h slcompress.h slip.h zlib.h
diff -r 0342763e4fec -r 1e7d56bf0325 sys/net/dlt.h
--- a/sys/net/dlt.h Sun Apr 29 08:37:04 2001 +0000
+++ b/sys/net/dlt.h Sun Apr 29 09:50:36 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: dlt.h,v 1.1 2000/12/12 17:53:00 thorpej Exp $ */
+/* $NetBSD: dlt.h,v 1.2 2001/04/29 09:50:37 martin Exp $ */
/*
* Copyright (c) 1990, 1991, 1993
@@ -67,7 +67,7 @@
/* NetBSD-specific types */
#define DLT_PPP_SERIAL 50 /* PPP over serial (async and sync) */
-#define DLT_PPP_ETHER 51 /* PPP over Ethernet */
+#define DLT_PPP_ETHER 51 /* XXX - depreceated! PPP over Ethernet; session only, w/o ether header */
/*
* NetBSD-specific generic "raw" link type. The upper 16-bits indicate
diff -r 0342763e4fec -r 1e7d56bf0325 sys/net/if_ethersubr.c
--- a/sys/net/if_ethersubr.c Sun Apr 29 08:37:04 2001 +0000
+++ b/sys/net/if_ethersubr.c Sun Apr 29 09:50:36 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_ethersubr.c,v 1.80 2001/04/27 00:14:02 marcus Exp $ */
+/* $NetBSD: if_ethersubr.c,v 1.81 2001/04/29 09:50:37 martin Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -73,12 +73,14 @@
#include "opt_gateway.h"
#include "opt_pfil_hooks.h"
#include "vlan.h"
+#include "pppoe.h"
#include "bridge.h"
#include "bpfilter.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
+#include <sys/callout.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/protosw.h>
@@ -105,6 +107,10 @@
#include <net/if_vlanvar.h>
#endif
+#if NPPPOE > 0
+#include <net/if_pppoe.h>
+#endif
+
#if NBRIDGE > 0
#include <net/if_bridgevar.h>
#endif
@@ -748,6 +754,28 @@
m_freem(m);
return;
#endif /* NVLAN > 0 */
+#if NPPPOE > 0
+ case ETHERTYPE_PPPOEDISC:
+ case ETHERTYPE_PPPOE:
+ if (etype == ETHERTYPE_PPPOEDISC)
+ inq = &ppoediscinq;
+ else
+ inq = &ppoeinq;
+ s = splnet();
+ if (IF_QFULL(inq)) {
+ IF_DROP(inq);
+ m_freem(m);
+ } else
+ IF_ENQUEUE(inq, m);
+ splx(s);
+#ifndef __HAVE_GENERIC_SOFT_INTERRUPTS
+ if (!callout_active(&pppoe_softintr))
+ callout_reset(&pppoe_softintr, 1, pppoe_softintr_handler, NULL);
+#else
+ softintr_schedule(pppoe_softintr);
+#endif
+ return;
+#endif /* NPPPOE > 0 */
default:
; /* Nothing. */
}
diff -r 0342763e4fec -r 1e7d56bf0325 sys/net/if_pppoe.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/net/if_pppoe.c Sun Apr 29 09:50:36 2001 +0000
@@ -0,0 +1,965 @@
+/* $NetBSD: if_pppoe.c,v 1.1 2001/04/29 09:50:37 martin Exp $ */
+
+/*
+ * Copyright (c) 2001 Martin Husemann. All rights reserved.
+ *
+ * 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 AUTHOR 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 AUTHOR 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.
+ *
+ */
+
+#include "pppoe.h"
+#include "bpfilter.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/callout.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/proc.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/if_ether.h>
+#include <net/if_sppp.h>
+#include <net/if_pppoe.h>
+
+#if NBPFILTER > 0
+#include <net/bpf.h>
+#endif
+
+#if NPPPOE > 0
+
+#undef PPPOE_DEBUG /* XXX - remove this or make it an option */
+/* #define PPPOE_DEBUG 1 */
+
+#define PPPOE_HEADERLEN 6
+#define PPPOE_VERTYPE 0x11 /* VER=1, TYPE = 1 */
+
+#define PPPOE_TAG_EOL 0x0000 /* end of list */
+#define PPPOE_TAG_SNAME 0x0101 /* service name */
+#define PPPOE_TAG_ACNAME 0x0102 /* access concentrator name */
+#define PPPOE_TAG_HUNIQUE 0x0103 /* host unique */
+#define PPPOE_TAG_ACCOOKIE 0x0104 /* AC cookie */
+#define PPPOE_TAG_VENDOR 0x0105 /* vendor specific */
+#define PPPOE_TAG_RELAYSID 0x0110 /* relay session id */
+#define PPPOE_TAG_SNAME_ERR 0x0201 /* service name error */
+#define PPPOE_TAG_ACSYS_ERR 0x0202 /* AC system error */
+#define PPPOE_TAG_GENERIC_ERR 0x0203 /* gerneric error */
+
+#define PPPOE_CODE_PADI 0x09 /* Active Discovery Initiation */
+#define PPPOE_CODE_PADO 0x07 /* Active Discovery Offer */
+#define PPPOE_CODE_PADR 0x19 /* Active Discovery Request */
+#define PPPOE_CODE_PADS 0x65 /* Active Discovery Session confirmation */
+#define PPPOE_CODE_PADT 0xA7 /* Active Discovery Terminate */
+
+/* Read a 16 bit unsigned value from a buffer */
+#define PPPOE_READ_16(PTR, VAL) \
+ (VAL) = ((PTR)[0] << 8) | (PTR)[1]; \
+ (PTR)+=2
+
+/* Add a 16 bit unsigned value to a buffer pointed to by PTR */
+#define PPPOE_ADD_16(PTR, VAL) \
+ *(PTR)++ = (VAL) / 256; \
+ *(PTR)++ = (VAL) % 256
+
+/* Add a complete PPPoE header to the buffer pointed to by PTR */
+#define PPPOE_ADD_HEADER(PTR, CODE, SESS, LEN) \
+ *(PTR)++ = PPPOE_VERTYPE; \
+ *(PTR)++ = (CODE); \
+ PPPOE_ADD_16(PTR, SESS); \
+ PPPOE_ADD_16(PTR, LEN)
+
+struct pppoe_softc {
+ struct sppp sc_sppp; /* contains a struct ifnet as first element */
+ struct ifnet *sc_eth_if; /* ethernet interface we are using */
+
+#define PPPOE_DISC_TIMEOUT hz/5
+#define PPPOE_DISC_MAXPADI 4 /* retry PADI four times */
+#define PPPOE_DISC_MAXPADR 2 /* retry PADR twice */
+
+#define PPPOE_STATE_INITIAL 0
+#define PPPOE_STATE_PADI_SENT 1
+#define PPPOE_STATE_PADR_SENT 2
+#define PPPOE_STATE_SESSION 3
+#define PPPOE_STATE_CLOSING 4
+ int sc_state; /* discovery phase or session connected */
+ struct ether_addr sc_dest; /* hardware address of concentrator */
+ u_int16_t sc_session; /* PPPoE session id */
+
+ char *sc_service_name; /* if != NULL: requested name of service */
+ char *sc_concentrator_name; /* if != NULL: requested concentrator id */
+ u_int8_t *sc_ac_cookie; /* content of AC cookie we must echo back */
+ size_t sc_ac_cookie_len; /* length of cookie data */
+ struct callout sc_timeout; /* timeout while not in session state */
+ int sc_padi_retried; /* number of PADI retries already done */
+ int sc_padr_retried; /* number of PADR retries already done */
+};
+
+/* incoming traffic will be queued here */
+struct ifqueue ppoediscinq = { NULL };
+struct ifqueue ppoeinq = { NULL };
+
+#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
+void * pppoe_softintr = NULL;
+static void pppoe_softintr_handler(void *);
+#else
+struct callout pppoe_softintr = CALLOUT_INITIALIZER;
+void pppoe_softintr_handler(void*);
+#endif
+
+extern int sppp_ioctl(struct ifnet *ifp, unsigned long cmd, void *data);
+
+/* input routines */
+static void pppoe_input(void);
+static void pppoe_disc_input(struct mbuf *m);
+static void pppoe_dispatch_disc_pkt(u_int8_t *p, size_t size, struct ifnet *rcvif, struct ether_header *eh);
+static void pppoe_data_input(struct mbuf *m);
+
+/* management routines */
+void pppoeattach(void);
+static int pppoe_connect(struct pppoe_softc *sc);
+static int pppoe_disconnect(struct pppoe_softc *sc);
+static void pppoe_abort_connect(struct pppoe_softc *sc);
+static int pppoe_ioctl(struct ifnet *ifp, unsigned long cmd, caddr_t data);
+static void pppoe_tls(struct sppp *sp);
+static void pppoe_tlf(struct sppp *sp);
+static void pppoe_start(struct ifnet *ifp);
+
+/* internal timeout handling */
+static void pppoe_timeout(void*);
+
+/* sending actual protocol controll packets */
+static int pppoe_send_padi(struct pppoe_softc *sc);
+static int pppoe_send_padr(struct pppoe_softc *sc);
+static int pppoe_send_padt(struct pppoe_softc *sc);
+
+/* raw output */
+static int pppoe_output(struct pppoe_softc *sc, struct mbuf *m);
+
+/* internal helper functions */
+static struct pppoe_softc * pppoe_find_softc_by_session(u_int session, struct ifnet *rcvif);
+static struct pppoe_softc * pppoe_find_softc_by_hunique(u_int8_t *token, size_t len, struct ifnet *rcvif);
Home |
Main Index |
Thread Index |
Old Index