summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorbenno <benno@FreeBSD.org>2004-03-08 10:54:35 +0000
committerbenno <benno@FreeBSD.org>2004-03-08 10:54:35 +0000
commitb817fe9eca36126df6a72ab12f89fcd290a7f67c (patch)
treebce0cb3ba1781ea849342ab5c2301d5b4807c904 /sys
parent01e90a548b5f067e622ac698d422f0ef5fc67074 (diff)
downloadFreeBSD-src-b817fe9eca36126df6a72ab12f89fcd290a7f67c.zip
FreeBSD-src-b817fe9eca36126df6a72ab12f89fcd290a7f67c.tar.gz
Add a netgraph node to handle ATM LLC encapsulation. This currently handles
ethernet (tested) and FDDI (not tested). The main use for this is on ADSL (or other ATM) connections where bridged ethernet is used, PPPoE being a prime example. There is no manual page as yet, I will write one shortly. Reviewed by: harti
Diffstat (limited to 'sys')
-rw-r--r--sys/conf/NOTES1
-rw-r--r--sys/conf/files1
-rw-r--r--sys/conf/options1
-rw-r--r--sys/modules/netgraph/atmllc/Makefile6
-rw-r--r--sys/netgraph/ng_atmllc.c278
-rw-r--r--sys/netgraph/ng_atmllc.h45
6 files changed, 332 insertions, 0 deletions
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index c898911..1cd934c 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -409,6 +409,7 @@ options LIBMCHAIN
# corresponding man page, e.g., ng_async(8).
options NETGRAPH #netgraph(4) system
options NETGRAPH_ASYNC
+options NETGRAPH_ATMLLC
options NETGRAPH_BPF
options NETGRAPH_BRIDGE
options NETGRAPH_CISCO
diff --git a/sys/conf/files b/sys/conf/files
index 846d192..73d1df7 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1402,6 +1402,7 @@ contrib/ngatm/netnatm/sig/sig_unimsgcpy.c optional ngatm_uni
contrib/ngatm/netnatm/sig/sig_verify.c optional ngatm_uni
netgraph/ng_UI.c optional netgraph_UI
netgraph/ng_async.c optional netgraph_async
+netgraph/ng_atmllc.c optional netgraph_atmllc
netgraph/ng_base.c optional netgraph
netgraph/ng_bpf.c optional netgraph_bpf
net/bpf_filter.c optional netgraph_bpf
diff --git a/sys/conf/options b/sys/conf/options
index ee6b4d0..f163ee3 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -376,6 +376,7 @@ XBONEHACK
# option below. Each type has its own man page, e.g. ng_async(4).
NETGRAPH
NETGRAPH_ASYNC opt_netgraph.h
+NETGRAPH_ATMLLC opt_netgraph.h
NETGRAPH_BPF opt_netgraph.h
NETGRAPH_BRIDGE opt_netgraph.h
NETGRAPH_CISCO opt_netgraph.h
diff --git a/sys/modules/netgraph/atmllc/Makefile b/sys/modules/netgraph/atmllc/Makefile
new file mode 100644
index 0000000..fd47b5c
--- /dev/null
+++ b/sys/modules/netgraph/atmllc/Makefile
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+KMOD= ng_atmllc
+SRCS= ng_atmllc.c
+
+.include <bsd.kmod.mk>
diff --git a/sys/netgraph/ng_atmllc.c b/sys/netgraph/ng_atmllc.c
new file mode 100644
index 0000000..e346c7b
--- /dev/null
+++ b/sys/netgraph/ng_atmllc.c
@@ -0,0 +1,278 @@
+/*
+ * Copyright (c) 2003-2004 Benno Rice <benno@eloquent.com.au>
+ * 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 ``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 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.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+
+#include <netgraph/ng_message.h>
+#include <netgraph/netgraph.h>
+#include <netgraph/ng_atmllc.h>
+
+#include <net/if.h>
+#include <net/ethernet.h> /* for M_HASFCS and ETHER_HDR_LEN */
+#include <net/if_atm.h> /* for struct atmllc */
+
+#define NG_ATMLLC_HEADER "\252\252\3\0\200\302"
+#define NG_ATMLLC_HEADER_LEN (sizeof(struct atmllc))
+#define NG_ATMLLC_TYPE_ETHERNET_FCS 0x0001
+#define NG_ATMLLC_TYPE_FDDI_FCS 0x0004
+#define NG_ATMLLC_TYPE_ETHERNET_NOFCS 0x0007
+#define NG_ATMLLC_TYPE_FDDI_NOFCS 0x000A
+
+struct ng_atmllc_priv {
+ hook_p atm;
+ hook_p ether;
+ hook_p fddi;
+};
+
+/* Netgraph methods. */
+static ng_constructor_t ng_atmllc_constructor;
+static ng_shutdown_t ng_atmllc_shutdown;
+static ng_rcvmsg_t ng_atmllc_rcvmsg;
+static ng_newhook_t ng_atmllc_newhook;
+static ng_rcvdata_t ng_atmllc_rcvdata;
+static ng_disconnect_t ng_atmllc_disconnect;
+
+static struct ng_type ng_atmllc_typestruct = {
+ NG_ABI_VERSION,
+ NG_ATMLLC_NODE_TYPE,
+ NULL,
+ ng_atmllc_constructor,
+ ng_atmllc_rcvmsg,
+ ng_atmllc_shutdown,
+ ng_atmllc_newhook,
+ NULL,
+ NULL,
+ ng_atmllc_rcvdata,
+ ng_atmllc_disconnect,
+ NULL
+};
+NETGRAPH_INIT(atmllc, &ng_atmllc_typestruct);
+
+static int
+ng_atmllc_constructor(node_p node)
+{
+ struct ng_atmllc_priv *priv;
+
+ MALLOC(priv, struct ng_atmllc_priv *, sizeof(*priv), M_NETGRAPH,
+ M_NOWAIT | M_ZERO);
+ if (priv == NULL) {
+ return (ENOMEM);
+ }
+
+ NG_NODE_SET_PRIVATE(node, priv);
+
+ return (0);
+}
+
+static int
+ng_atmllc_rcvmsg(node_p node, item_p item, hook_p lasthook)
+{
+ struct ng_mesg *msg;
+ int error;
+
+ error = 0;
+ NGI_GET_MSG(item, msg);
+ msg->header.flags |= NGF_RESP;
+ NG_RESPOND_MSG(error, node, item, msg);
+ return (error);
+}
+
+static int
+ng_atmllc_shutdown(node_p node)
+{
+ struct ng_atmllc_priv *priv;
+
+ priv = NG_NODE_PRIVATE(node);
+
+ FREE(priv, M_NETGRAPH);
+
+ NG_NODE_UNREF(node);
+
+ return (0);
+}
+
+static int
+ng_atmllc_newhook(node_p node, hook_p hook, const char *name)
+{
+ struct ng_atmllc_priv *priv;
+
+ priv = NG_NODE_PRIVATE(node);
+
+ if (strcmp(name, NG_ATMLLC_HOOK_ATM) == 0) {
+ if (priv->atm != NULL) {
+ return (EISCONN);
+ }
+ priv->atm = hook;
+ } else if (strcmp(name, NG_ATMLLC_HOOK_ETHER) == 0) {
+ if (priv->ether != NULL) {
+ return (EISCONN);
+ }
+ priv->ether = hook;
+ } else if (strcmp(name, NG_ATMLLC_HOOK_FDDI) == 0) {
+ if (priv->fddi != NULL) {
+ return (EISCONN);
+ }
+ priv->fddi = hook;
+ } else {
+ return (EINVAL);
+ }
+
+ return (0);
+}
+
+static int
+ng_atmllc_rcvdata(hook_p hook, item_p item)
+{
+ struct ng_atmllc_priv *priv;
+ struct mbuf *m;
+ struct atmllc *hdr;
+ hook_p outhook;
+ u_int padding;
+ int error;
+
+ priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
+ m = NGI_M(item);
+ outhook = NULL;
+ padding = 0;
+
+ if (hook == priv->atm) {
+ /* Ditch the psuedoheader. */
+ hdr = mtod(m, struct atmllc *);
+ /* m_adj(m, sizeof(struct atm_pseudohdr)); */
+
+ /*
+ * Make sure we have the LLC and ethernet headers.
+ * The ethernet header size is slightly larger than the FDDI
+ * header, which is convenient.
+ */
+ if (m->m_len < sizeof(struct atmllc) + ETHER_HDR_LEN) {
+ m = m_pullup(m, sizeof(struct atmllc) + ETHER_HDR_LEN);
+ if (m == NULL) {
+ return (ENOMEM);
+ }
+ }
+
+ /* Decode the LLC header. */
+ hdr = mtod(m, struct atmllc *);
+ if (ATM_LLC_TYPE(hdr) == NG_ATMLLC_TYPE_ETHERNET_NOFCS) {
+ m->m_flags &= ~M_HASFCS;
+ outhook = priv->ether;
+ padding = 2;
+ } else if (ATM_LLC_TYPE(hdr) == NG_ATMLLC_TYPE_ETHERNET_FCS) {
+ m->m_flags |= M_HASFCS;
+ outhook = priv->ether;
+ padding = 2;
+ } else if (ATM_LLC_TYPE(hdr) == NG_ATMLLC_TYPE_FDDI_NOFCS) {
+ m->m_flags &= ~M_HASFCS;
+ outhook = priv->fddi;
+ padding = 3;
+ } else if (ATM_LLC_TYPE(hdr) == NG_ATMLLC_TYPE_FDDI_FCS) {
+ m->m_flags |= M_HASFCS;
+ outhook = priv->fddi;
+ padding = 3;
+ } else {
+ printf("ng_atmllc: unknown type: %x\n",
+ ATM_LLC_TYPE(hdr));
+ }
+
+ /* Remove the LLC header and any padding*/
+ m_adj(m, sizeof(struct atmllc) + padding);
+ } else if (hook == priv->ether) {
+ /* Add the LLC header */
+ M_PREPEND(m, NG_ATMLLC_HEADER_LEN + 2, M_DONTWAIT);
+ if (m == NULL) {
+ printf("ng_atmllc: M_PREPEND failed\n");
+ NG_FREE_ITEM(item);
+ return (ENOMEM);
+ }
+ hdr = mtod(m, struct atmllc *);
+ bzero((void *)hdr, sizeof(struct atmllc) + 2);
+ bcopy(NG_ATMLLC_HEADER, hdr->llchdr, 6);
+ if ((m->m_flags & M_HASFCS) != 0) {
+ ATM_LLC_SETTYPE(hdr, NG_ATMLLC_TYPE_ETHERNET_FCS);
+ } else {
+ ATM_LLC_SETTYPE(hdr, NG_ATMLLC_TYPE_ETHERNET_NOFCS);
+ }
+ outhook = priv->atm;
+ } else if (hook == priv->fddi) {
+ /* Add the LLC header */
+ M_PREPEND(m, NG_ATMLLC_HEADER_LEN + 3, M_DONTWAIT);
+ if (m == NULL) {
+ printf("ng_atmllc: M_PREPEND failed\n");
+ NG_FREE_ITEM(item);
+ return (ENOMEM);
+ }
+ hdr = mtod(m, struct atmllc *);
+ bzero((void *)hdr, sizeof(struct atmllc) + 3);
+ bcopy(NG_ATMLLC_HEADER, hdr->llchdr, 6);
+ if ((m->m_flags & M_HASFCS) != 0) {
+ ATM_LLC_SETTYPE(hdr, NG_ATMLLC_TYPE_FDDI_FCS);
+ } else {
+ ATM_LLC_SETTYPE(hdr, NG_ATMLLC_TYPE_FDDI_NOFCS);
+ }
+ outhook = priv->atm;
+ }
+
+ if (outhook == NULL) {
+ NG_FREE_ITEM(item);
+ return (0);
+ }
+
+ NG_FWD_NEW_DATA(error, item, outhook, m);
+ return (error);
+}
+
+static int
+ng_atmllc_disconnect(hook_p hook)
+{
+ node_p node;
+ struct ng_atmllc_priv *priv;
+
+ node = NG_HOOK_NODE(hook);
+ priv = NG_NODE_PRIVATE(node);
+
+ if (hook == priv->atm) {
+ priv->atm = NULL;
+ } else if (hook == priv->ether) {
+ priv->ether = NULL;
+ } else if (hook == priv->fddi) {
+ priv->fddi = NULL;
+ }
+
+ if (NG_NODE_NUMHOOKS(node) == 0 && NG_NODE_IS_VALID(node)) {
+ ng_rmnode_self(node);
+ }
+
+ return (0);
+}
diff --git a/sys/netgraph/ng_atmllc.h b/sys/netgraph/ng_atmllc.h
new file mode 100644
index 0000000..f9aed55
--- /dev/null
+++ b/sys/netgraph/ng_atmllc.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2003-2004 Benno Rice <benno@FreeBSD.org>
+ * 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 ``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 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _NETGRAPH_ATMLLC_H_
+#define _NETGRAPH_ATMLLC_H_
+
+/* Node type name and magic cookie. */
+#define NG_ATMLLC_NODE_TYPE "atmllc"
+#define NGM_ATMLLC_COOKIE 1065246274
+
+/* Hook names. */
+#define NG_ATMLLC_HOOK_ATM "atm"
+#define NG_ATMLLC_HOOK_ETHER "ether"
+#define NG_ATMLLC_HOOK_802_4 "ieee8024"
+#define NG_ATMLLC_HOOK_802_5 "ieee8025"
+#define NG_ATMLLC_HOOK_802_6 "ieee8026"
+#define NG_ATMLLC_HOOK_FDDI "fddi"
+#define NG_ATMLLC_HOOK_BPDU "bpdu"
+
+#endif /* _NETGRAPH_ATMLLC_H_ */
OpenPOWER on IntegriCloud