Module Name: src
Committed By: bouyer
Date: Sun Jan 15 20:27:34 UTC 2017
Modified Files:
src/sys [bouyer-socketcan]: Makefile
src/sys/conf [bouyer-socketcan]: files
src/sys/net [bouyer-socketcan]: netisr.h netisr_dispatch.h
src/sys/rump/include/opt [bouyer-socketcan]: opt_rumpkernel.h
src/sys/rump/include/rump [bouyer-socketcan]: rumpdefs.h
src/sys/rump/net [bouyer-socketcan]: Makefile.rumpnetcomp
src/sys/sys [bouyer-socketcan]: socket.h
Added Files:
src/sys/netcan [bouyer-socketcan]: Makefile can.c can.h can_pcb.c
can_pcb.h can_proto.c can_var.h files.netcan if_canloop.c
src/sys/rump/net/lib/libnetcan [bouyer-socketcan]: Makefile
NETCAN.ioconf netcan_component.c
Log Message:
Initial commit of a CAN socket layer, compatible with linux SoccketCAN
(but incomplete). Based on work from Robert Swindells.
To generate a diff of this commit:
cvs rdiff -u -r1.79 -r1.79.22.1 src/sys/Makefile
cvs rdiff -u -r1.1168 -r1.1168.2.1 src/sys/conf/files
cvs rdiff -u -r1.44 -r1.44.4.1 src/sys/net/netisr.h
cvs rdiff -u -r1.18 -r1.18.12.1 src/sys/net/netisr_dispatch.h
cvs rdiff -u -r0 -r1.1.2.1 src/sys/netcan/Makefile src/sys/netcan/can.c \
src/sys/netcan/can.h src/sys/netcan/can_pcb.c src/sys/netcan/can_pcb.h \
src/sys/netcan/can_proto.c src/sys/netcan/can_var.h \
src/sys/netcan/files.netcan src/sys/netcan/if_canloop.c
cvs rdiff -u -r1.5 -r1.5.4.1 src/sys/rump/include/opt/opt_rumpkernel.h
cvs rdiff -u -r1.36 -r1.36.4.1 src/sys/rump/include/rump/rumpdefs.h
cvs rdiff -u -r1.16 -r1.16.2.1 src/sys/rump/net/Makefile.rumpnetcomp
cvs rdiff -u -r0 -r1.1.2.1 src/sys/rump/net/lib/libnetcan/Makefile \
src/sys/rump/net/lib/libnetcan/NETCAN.ioconf \
src/sys/rump/net/lib/libnetcan/netcan_component.c
cvs rdiff -u -r1.120 -r1.120.2.1 src/sys/sys/socket.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/Makefile
diff -u src/sys/Makefile:1.79 src/sys/Makefile:1.79.22.1
--- src/sys/Makefile:1.79 Fri Mar 1 18:25:27 2013
+++ src/sys/Makefile Sun Jan 15 20:27:33 2017
@@ -1,9 +1,9 @@
-# $NetBSD: Makefile,v 1.79 2013/03/01 18:25:27 joerg Exp $
+# $NetBSD: Makefile,v 1.79.22.1 2017/01/15 20:27:33 bouyer Exp $
.include <bsd.own.mk>
SUBDIR= altq arch compat dev fs miscfs \
- net net80211 netatalk netbt netipsec netinet netinet6 \
+ net net80211 netatalk netbt netcan netipsec netinet netinet6 \
netisdn netkey netmpls netnatm netsmb \
nfs opencrypto sys ufs uvm
Index: src/sys/conf/files
diff -u src/sys/conf/files:1.1168 src/sys/conf/files:1.1168.2.1
--- src/sys/conf/files:1.1168 Mon Dec 26 23:12:33 2016
+++ src/sys/conf/files Sun Jan 15 20:27:33 2017
@@ -1,4 +1,4 @@
-# $NetBSD: files,v 1.1168 2016/12/26 23:12:33 pgoyette Exp $
+# $NetBSD: files,v 1.1168.2.1 2017/01/15 20:27:33 bouyer Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
version 20150846
@@ -229,6 +229,7 @@ file net/bpfjit.c sljit & bpfjit
include "net80211/files.net80211"
include "netatalk/files.netatalk"
include "netbt/files.netbt"
+include "netcan/files.netcan"
include "netinet/files.netinet"
include "netinet6/files.netinet6"
include "netipsec/files.netipsec"
@@ -1435,6 +1436,7 @@ defpseudo stf: ifnet
defpseudodev tap: ifnet, ether, arp
defpseudo carp: ifnet, ether, arp
defpseudodev etherip: ifnet, ether, arp
+defpseudo canloop: ifnet
defpseudo sequencer
defpseudo clockctl
Index: src/sys/net/netisr.h
diff -u src/sys/net/netisr.h:1.44 src/sys/net/netisr.h:1.44.4.1
--- src/sys/net/netisr.h:1.44 Mon May 25 08:29:01 2015
+++ src/sys/net/netisr.h Sun Jan 15 20:27:33 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: netisr.h,v 1.44 2015/05/25 08:29:01 ozaki-r Exp $ */
+/* $NetBSD: netisr.h,v 1.44.4.1 2017/01/15 20:27:33 bouyer Exp $ */
/*
* Copyright (c) 1980, 1986, 1989, 1993
@@ -53,6 +53,7 @@
#include "opt_atalk.h"
#include "opt_mpls.h"
#include "opt_natm.h"
+#include "opt_can.h"
#include "arp.h"
#endif /* defined(_KERNEL_OPT) */
@@ -90,6 +91,10 @@
#ifdef NETATALK
#include <netatalk/at_extern.h>
#endif
+#ifdef CAN
+#include <netcan/can.h>
+#include <netcan/can_var.h>
+#endif
#endif /* !defined(_LOCORE) */
#endif /* defined(_KERNEL) */
@@ -109,6 +114,7 @@
#define NETISR_NATM 27 /* same as AF_NATM */
#define NETISR_ARP 28 /* same as AF_ARP */
#define NETISR_MPLS 33 /* same as AF_MPLS */
+#define NETISR_CAN 35 /* same as AF_CAN */
#define NETISR_MAX AF_MAX
#if !defined(_LOCORE) && defined(_KERNEL)
Index: src/sys/net/netisr_dispatch.h
diff -u src/sys/net/netisr_dispatch.h:1.18 src/sys/net/netisr_dispatch.h:1.18.12.1
--- src/sys/net/netisr_dispatch.h:1.18 Thu Jun 5 23:48:16 2014
+++ src/sys/net/netisr_dispatch.h Sun Jan 15 20:27:33 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: netisr_dispatch.h,v 1.18 2014/06/05 23:48:16 rmind Exp $ */
+/* $NetBSD: netisr_dispatch.h,v 1.18.12.1 2017/01/15 20:27:33 bouyer Exp $ */
#ifndef _NET_NETISR_DISPATCH_H_
#define _NET_NETISR_DISPATCH_H_
@@ -41,5 +41,8 @@
#ifdef NATM
DONETISR(NETISR_NATM,natmintr);
#endif
+#ifdef CAN
+ DONETISR(NETISR_CAN,canintr);
+#endif
#endif /* !_NET_NETISR_DISPATCH_H_ */
Index: src/sys/rump/include/opt/opt_rumpkernel.h
diff -u src/sys/rump/include/opt/opt_rumpkernel.h:1.5 src/sys/rump/include/opt/opt_rumpkernel.h:1.5.4.1
--- src/sys/rump/include/opt/opt_rumpkernel.h:1.5 Fri Apr 15 01:35:26 2016
+++ src/sys/rump/include/opt/opt_rumpkernel.h Sun Jan 15 20:27:33 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: opt_rumpkernel.h,v 1.5 2016/04/15 01:35:26 ozaki-r Exp $ */
+/* $NetBSD: opt_rumpkernel.h,v 1.5.4.1 2017/01/15 20:27:33 bouyer Exp $ */
#ifndef __NetBSD__
#define __NetBSD__
@@ -22,6 +22,8 @@
#define MPLS 1
+#define CAN 1
+
#define SOSEND_NO_LOAN
#undef PIPE_SOCKETPAIR /* would need uipc_usrreq.c */
Index: src/sys/rump/include/rump/rumpdefs.h
diff -u src/sys/rump/include/rump/rumpdefs.h:1.36 src/sys/rump/include/rump/rumpdefs.h:1.36.4.1
--- src/sys/rump/include/rump/rumpdefs.h:1.36 Tue Feb 2 01:15:58 2016
+++ src/sys/rump/include/rump/rumpdefs.h Sun Jan 15 20:27:33 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: rumpdefs.h,v 1.36 2016/02/02 01:15:58 pooka Exp $ */
+/* $NetBSD: rumpdefs.h,v 1.36.4.1 2017/01/15 20:27:33 bouyer Exp $ */
/*
* AUTOMATICALLY GENERATED. DO NOT EDIT.
@@ -240,7 +240,8 @@ enum rump_vtype { RUMP_VNON, RUMP_VREG,
#define RUMP_AF_IEEE80211 32
#define RUMP_AF_MPLS 33
#define RUMP_AF_ROUTE 34
-#define RUMP_AF_MAX 35
+#define RUMP_AF_CAN 35
+#define RUMP_AF_MAX 36
#define RUMP_PF_UNSPEC RUMP_AF_UNSPEC
#define RUMP_PF_LOCAL RUMP_AF_LOCAL
#define RUMP_PF_UNIX RUMP_PF_LOCAL
@@ -277,6 +278,7 @@ enum rump_vtype { RUMP_VNON, RUMP_VREG,
#define RUMP_PF_BLUETOOTH RUMP_AF_BLUETOOTH
#define RUMP_PF_MPLS RUMP_AF_MPLS
#define RUMP_PF_ROUTE RUMP_AF_ROUTE
+#define RUMP_PF_CAN RUMP_AF_CAN
#define RUMP_PF_MAX RUMP_AF_MAX
#define RUMP_SO_DEBUG 0x0001
#define RUMP_SO_ACCEPTCONN 0x0002
Index: src/sys/rump/net/Makefile.rumpnetcomp
diff -u src/sys/rump/net/Makefile.rumpnetcomp:1.16 src/sys/rump/net/Makefile.rumpnetcomp:1.16.2.1
--- src/sys/rump/net/Makefile.rumpnetcomp:1.16 Sat Nov 26 03:17:58 2016
+++ src/sys/rump/net/Makefile.rumpnetcomp Sun Jan 15 20:27:34 2017
@@ -1,9 +1,9 @@
-# $NetBSD: Makefile.rumpnetcomp,v 1.16 2016/11/26 03:17:58 ozaki-r Exp $
+# $NetBSD: Makefile.rumpnetcomp,v 1.16.2.1 2017/01/15 20:27:34 bouyer Exp $
#
.include <bsd.own.mk>
-RUMPNETCOMP= agr bridge net net80211 netbt netinet netinet6
+RUMPNETCOMP= agr bridge net net80211 netbt netcan netinet netinet6
RUMPNETCOMP+= gif netmpls npf local pppoe shmif tap tun vlan
.if ${MKSLJIT} != "no" || make(rumpdescribe)
Index: src/sys/sys/socket.h
diff -u src/sys/sys/socket.h:1.120 src/sys/sys/socket.h:1.120.2.1
--- src/sys/sys/socket.h:1.120 Wed Sep 21 10:50:23 2016
+++ src/sys/sys/socket.h Sun Jan 15 20:27:34 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: socket.h,v 1.120 2016/09/21 10:50:23 roy Exp $ */
+/* $NetBSD: socket.h,v 1.120.2.1 2017/01/15 20:27:34 bouyer Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -221,7 +221,8 @@ struct accept_filter_arg {
#define AF_IEEE80211 32 /* IEEE80211 */
#define AF_MPLS 33 /* MultiProtocol Label Switching */
#define AF_ROUTE 34 /* Internal Routing Protocol */
-#define AF_MAX 35
+#define AF_CAN 35
+#define AF_MAX 36
/*
* Structure used by kernel to store most
@@ -330,6 +331,7 @@ struct sockaddr_storage {
#define PF_BLUETOOTH AF_BLUETOOTH
#define PF_MPLS AF_MPLS
#define PF_ROUTE AF_ROUTE
+#define PF_CAN AF_CAN
#define PF_MAX AF_MAX
Added files:
Index: src/sys/netcan/Makefile
diff -u /dev/null src/sys/netcan/Makefile:1.1.2.1
--- /dev/null Sun Jan 15 20:27:34 2017
+++ src/sys/netcan/Makefile Sun Jan 15 20:27:33 2017
@@ -0,0 +1,8 @@
+# $NetBSD: Makefile,v 1.1.2.1 2017/01/15 20:27:33 bouyer Exp $
+
+KDIR= /sys/netcan
+INCSDIR= /usr/include/netcan
+
+INCS= can.h
+
+.include <bsd.kinc.mk>
Index: src/sys/netcan/can.c
diff -u /dev/null src/sys/netcan/can.c:1.1.2.1
--- /dev/null Sun Jan 15 20:27:34 2017
+++ src/sys/netcan/can.c Sun Jan 15 20:27:33 2017
@@ -0,0 +1,697 @@
+/* $NetBSD: can.c,v 1.1.2.1 2017/01/15 20:27:33 bouyer Exp $ */
+
+/*-
+ * Copyright (c) 2003, 2017 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Robert Swindells and Manuel Bouyer
+ *
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.1.2.1 2017/01/15 20:27:33 bouyer Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/ioctl.h>
+#include <sys/protosw.h>
+#include <sys/errno.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/proc.h>
+#include <sys/kauth.h>
+
+#include <net/if.h>
+#include <net/netisr.h>
+#include <net/route.h>
+
+#include <netcan/can.h>
+#include <netcan/can_pcb.h>
+#include <netcan/can_var.h>
+
+struct canpcb canpcb;
+#if 0
+struct canpcb canrawpcb;
+#endif
+
+struct canpcbtable cbtable;
+
+struct ifqueue canintrq;
+int canqmaxlen = IFQ_MAXLEN;
+
+int can_copy_output = 0;
+int can_output_cnt = 0;
+struct mbuf *can_lastout;
+
+int can_sendspace = 4096; /* really max datagram size */
+int can_recvspace = 40 * (1024 + sizeof(struct sockaddr_can));
+ /* 40 1K datagrams */
+#ifndef CANHASHSIZE
+#define CANHASHSIZE 128
+#endif
+int canhashsize = CANHASHSIZE;
+
+static int can_output(struct mbuf *, struct canpcb *);
+
+static int can_control(struct socket *, u_long, void *, struct ifnet *);
+
+void
+can_init(void)
+{
+ canintrq.ifq_maxlen = canqmaxlen;
+ IFQ_LOCK_INIT(&canintrq);
+ can_pcbinit(&cbtable, canhashsize, canhashsize);
+}
+
+/*
+ * Generic control operations (ioctl's).
+ */
+/* ARGSUSED */
+static int
+can_control(struct socket *so, u_long cmd, void *data, struct ifnet *ifp)
+{
+#if 0
+ struct can_ifreq *cfr = (struct can_ifreq *)data;
+ int error = 0;
+#endif
+
+
+ switch (cmd) {
+
+ default:
+ if (ifp == 0 || ifp->if_ioctl == 0)
+ return (EOPNOTSUPP);
+ return ((*ifp->if_ioctl)(ifp, cmd, data));
+ }
+ return (0);
+}
+
+static int
+can_purgeif(struct socket *so, struct ifnet *ifp)
+{
+ return 0;
+}
+
+static int
+can_output(struct mbuf *m, struct canpcb *canp)
+{
+ struct ifnet *ifp;
+ int error = 0;
+
+ if (canp == 0) {
+ printf("can_output: no pcb\n");
+ error = EINVAL;
+ goto done;
+ }
+ ifp = canp->canp_ifp;
+ if (ifp == 0) {
+ error = EDESTADDRREQ;
+ goto done;
+ }
+ if (m->m_len <= ifp->if_mtu) {
+ can_output_cnt++;
+ error = (*ifp->if_output)(ifp, m, NULL, 0);
+ goto done;
+ } else error = EMSGSIZE;
+
+ m_freem(m);
+done:
+ return (error);
+}
+
+/*
+ * Process a received CAN frame
+ * the packet is in the mbuf chain m with
+ * the CAN header.
+ */
+void
+can_input(struct ifnet *ifp, struct mbuf *m)
+{
+ struct ifqueue *inq;
+
+ if ((ifp->if_flags & IFF_UP) == 0) {
+ m_freem(m);
+ return;
+ }
+
+ inq = &canintrq;
+
+ IFQ_LOCK(inq);
+ if (IF_QFULL(inq)) {
+ IF_DROP(inq);
+ IFQ_UNLOCK(inq);
+ m_freem(m);
+ } else {
+ IF_ENQUEUE(inq, m);
+ IFQ_UNLOCK(inq);
+ schednetisr(NETISR_CAN);
+ ifp->if_ipackets++;
+ ifp->if_ibytes += m->m_pkthdr.len;
+ }
+}
+
+void
+canintr(void)
+{
+ int rcv_ifindex;
+ struct mbuf *m;
+
+ struct sockaddr_can from;
+ struct canpcb *canp;
+
+ mutex_enter(softnet_lock);
+ for (;;) {
+ IFQ_LOCK(&canintrq);
+ IF_DEQUEUE(&canintrq, m);
+ IFQ_UNLOCK(&canintrq);
+
+ if (m == 0) /* no more queued packets */
+ break;
+
+ memset(&from, 0, sizeof(struct sockaddr_can));
+ rcv_ifindex = m->m_pkthdr.rcvif_index;
+#if 0
+ m_claim(m, &can_rx_mowner);
+#endif
+ from.can_ifindex = rcv_ifindex;
+ from.can_len = sizeof(struct sockaddr_can);
+ from.can_family = AF_CAN;
+
+ TAILQ_FOREACH(canp, &cbtable.canpt_queue, canp_queue) {
+ struct mbuf *mc;
+ if (canp->canp_ifp != NULL &&
+ canp->canp_ifp->if_index != rcv_ifindex) {
+ continue;
+ }
+ if (TAILQ_NEXT(canp, canp_queue) != NULL) {
+ /*
+ * we can't be sure we won't need
+ * the original mbuf later so copy
+ */
+ mc = m_copym(m, 0, M_COPYALL, M_NOWAIT);
+ if (mc == NULL) {
+ /* deliver this mbuf and abort */
+ mc = m;
+ m = NULL;
+ }
+ } else {
+ mc = m;
+ m = NULL;
+ }
+ if (sbappendaddr(&canp->canp_socket->so_rcv,
+ (struct sockaddr *) &from, mc,
+ (struct mbuf *) 0) == 0) {
+ m_freem(mc);
+ } else
+ sorwakeup(canp->canp_socket);
+ if (m == NULL)
+ break;
+ }
+ /* If it didn't go anywhere just delete it */
+ if (m) {
+ m_freem(m);
+ }
+ }
+ mutex_exit(softnet_lock);
+}
+
+static int
+can_attach(struct socket *so, int proto)
+{
+ /*struct canpcb *canp;*/
+ int error;
+
+ KASSERT(sotocanpcb(so) == NULL);
+
+ /* Assign the lock (must happen even if we will error out). */
+ sosetlock(so);
+
+#ifdef MBUFTRACE
+ so->so_mowner = &can_mowner;
+ so->so_rcv.sb_mowner = &can_rx_mowner;
+ so->so_snd.sb_mowner = &can_tx_mowner;
+#endif
+ if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
+ error = soreserve(so, can_sendspace, can_recvspace);
+ if (error) {
+ return error;
+ }
+ }
+
+ error = can_pcballoc(so, &cbtable);
+ if (error) {
+ return error;
+ }
+ /*canp = sotocanpcb(so);*/
+ KASSERT(solocked(so));
+
+ return error;
+}
+
+static void
+can_detach(struct socket *so)
+{
+ struct canpcb *canp;
+
+ KASSERT(solocked(so));
+ canp = sotocanpcb(so);
+ can_pcbdetach(canp);
+}
+
+static int
+can_accept(struct socket *so, struct sockaddr *nam)
+{
+ KASSERT(solocked(so));
+
+ panic("can_accept");
+
+ return EOPNOTSUPP;
+}
+
+static int
+can_bind(struct socket *so, struct sockaddr *nam, struct lwp *l)
+{
+ struct canpcb *canp = sotocanpcb(so);
+ struct sockaddr_can *scan = (struct sockaddr_can *)nam;
+
+ KASSERT(solocked(so));
+ KASSERT(nam != NULL);
+
+ return can_pcbbind(canp, scan, l);
+}
+
+static int
+can_listen(struct socket *so, struct lwp *l)
+{
+ KASSERT(solocked(so));
+
+ return EOPNOTSUPP;
+}
+
+static int
+can_connect(struct socket *so, struct sockaddr *nam, struct lwp *l)
+{
+ struct canpcb *canp = sotocanpcb(so);
+ int error = 0;
+
+ KASSERT(solocked(so));
+ KASSERT(canp != NULL);
+ KASSERT(nam != NULL);
+
+ error = can_pcbconnect(canp, (struct sockaddr_can *)nam);
+ if (! error)
+ soisconnected(so);
+ return error;
+}
+
+static int
+can_connect2(struct socket *so, struct socket *so2)
+{
+ KASSERT(solocked(so));
+
+ return EOPNOTSUPP;
+}
+
+static int
+can_disconnect(struct socket *so)
+{
+ struct canpcb *canp = sotocanpcb(so);
+
+ KASSERT(solocked(so));
+ KASSERT(canp != NULL);
+
+ /*soisdisconnected(so);*/
+ so->so_state &= ~SS_ISCONNECTED; /* XXX */
+ can_pcbdisconnect(canp);
+ can_pcbstate(canp, CANP_BOUND); /* XXX */
+ return 0;
+}
+
+static int
+can_shutdown(struct socket *so)
+{
+ KASSERT(solocked(so));
+
+ socantsendmore(so);
+ return 0;
+}
+
+static int
+can_abort(struct socket *so)
+{
+ KASSERT(solocked(so));
+
+ panic("can_abort");
+
+ return EOPNOTSUPP;
+}
+
+static int
+can_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp)
+{
+ return can_control(so, cmd, nam, ifp);
+}
+
+static int
+can_stat(struct socket *so, struct stat *ub)
+{
+ KASSERT(solocked(so));
+
+ /* stat: don't bother with a blocksize. */
+ return 0;
+}
+
+static int
+can_peeraddr(struct socket *so, struct sockaddr *nam)
+{
+ KASSERT(solocked(so));
+ KASSERT(sotocanpcb(so) != NULL);
+ KASSERT(nam != NULL);
+
+ return EOPNOTSUPP;
+}
+
+static int
+can_sockaddr(struct socket *so, struct sockaddr *nam)
+{
+ KASSERT(solocked(so));
+ KASSERT(sotocanpcb(so) != NULL);
+ KASSERT(nam != NULL);
+
+ can_setsockaddr(sotocanpcb(so), (struct sockaddr_can *)nam);
+
+ return 0;
+}
+
+static int
+can_rcvd(struct socket *so, int flags, struct lwp *l)
+{
+ KASSERT(solocked(so));
+
+ return EOPNOTSUPP;
+}
+
+static int
+can_recvoob(struct socket *so, struct mbuf *m, int flags)
+{
+ KASSERT(solocked(so));
+
+ return EOPNOTSUPP;
+}
+
+static int
+can_send(struct socket *so, struct mbuf *m, struct sockaddr *nam,
+ struct mbuf *control, struct lwp *l)
+{
+ struct canpcb *canp = sotocanpcb(so);
+ int error = 0;
+ int s;
+
+ if (control && control->m_len) {
+ return EINVAL;
+ }
+
+ if (nam) {
+ if ((so->so_state & SS_ISCONNECTED) != 0) {
+ return EISCONN;
+ }
+ s = splnet();
+ error = can_pcbbind(canp, (struct sockaddr_can *)nam, l);
+ if (error) {
+ splx(s);
+ return error;
+ }
+ } else {
+ if ((so->so_state & SS_ISCONNECTED) == 0) {
+ return EDESTADDRREQ;
+ }
+ }
+ error = can_output(m, canp);
+ if (nam) {
+ struct sockaddr_can lscan;
+ memset(&lscan, 0, sizeof(lscan));
+ lscan.can_family = AF_CAN;
+ lscan.can_len = sizeof(lscan);
+ can_pcbbind(canp, &lscan, l);
+ }
+ return error;
+}
+
+static int
+can_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control)
+{
+ KASSERT(solocked(so));
+
+ m_freem(m);
+ m_freem(control);
+
+ return EOPNOTSUPP;
+}
+
+#if 0
+int
+can_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
+ struct mbuf *control, struct lwp *l)
+{
+ struct canpcb *canp;
+ int s;
+ int error = 0;
+
+ if (req == PRU_CONTROL)
+ return (can_control(so, (long)m, nam,
+ (struct ifnet *)control));
+
+ if (req == PRU_PURGEIF) {
+#if 0
+ can_pcbpurgeif0(&udbtable, (struct ifnet *)control);
+ can_purgeif((struct ifnet *)control);
+ can_pcbpurgeif(&udbtable, (struct ifnet *)control);
+#endif
+ return (0);
+ }
+
+ s = splsoftnet();
+ canp = sotocanpcb(so);
+#ifdef DIAGNOSTIC
+ if (req != PRU_SEND && req != PRU_SENDOOB && control)
+ panic("can_usrreq: unexpected control mbuf");
+#endif
+ if (canp == 0 && req != PRU_ATTACH) {
+ printf("can_usrreq: no pcb %p %d\n", canp, req);
+ error = EINVAL;
+ goto release;
+ }
+
+ /*
+ * Note: need to block can_input while changing
+ * the can pcb queue and/or pcb addresses.
+ */
+ switch (req) {
+
+ case PRU_ATTACH:
+ if (canp != 0) {
+ error = EISCONN;
+ break;
+ }
+#ifdef MBUFTRACE
+ so->so_mowner = &can_mowner;
+ so->so_rcv.sb_mowner = &can_rx_mowner;
+ so->so_snd.sb_mowner = &can_tx_mowner;
+#endif
+ if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
+ error = soreserve(so, can_sendspace, can_recvspace);
+ if (error)
+ break;
+ }
+ error = can_pcballoc(so, &cbtable);
+ if (error)
+ break;
+ canp = sotocanpcb(so);
+#if 0
+ inp->inp_ip.ip_ttl = ip_defttl;
+#endif
+ break;
+
+ case PRU_DETACH:
+ can_pcbdetach(canp);
+ break;
+
+ case PRU_BIND:
+ error = can_pcbbind(canp, nam, l);
+ break;
+
+ case PRU_LISTEN:
+ error = EOPNOTSUPP;
+ break;
+
+ case PRU_CONNECT:
+ error = can_pcbconnect(canp, nam);
+ if (error)
+ break;
+ soisconnected(so);
+ break;
+
+ case PRU_CONNECT2:
+ error = EOPNOTSUPP;
+ break;
+
+ case PRU_DISCONNECT:
+ /*soisdisconnected(so);*/
+ so->so_state &= ~SS_ISCONNECTED; /* XXX */
+ can_pcbdisconnect(canp);
+ can_pcbstate(canp, CANP_BOUND); /* XXX */
+ break;
+
+ case PRU_SHUTDOWN:
+ socantsendmore(so);
+ break;
+
+ case PRU_RCVD:
+ error = EOPNOTSUPP;
+ break;
+
+ case PRU_SEND:
+ break;
+
+ case PRU_SENSE:
+ /*
+ * stat: don't bother with a blocksize.
+ */
+ splx(s);
+ return (0);
+
+ case PRU_RCVOOB:
+ error = EOPNOTSUPP;
+ break;
+
+ case PRU_SENDOOB:
+ m_freem(control);
+ m_freem(m);
+ error = EOPNOTSUPP;
+ break;
+
+ case PRU_SOCKADDR:
+
+ break;
+
+ case PRU_PEERADDR:
+ error = EOPNOTSUPP;
+ break;
+
+ default:
+ panic("can_usrreq");
+ }
+
+release:
+ splx(s);
+ return (error);
+}
+#endif
+
+#if 0
+static void
+can_notify(struct canpcb *canp, int errno)
+{
+
+ canp->canp_socket->so_error = errno;
+ sorwakeup(canp->canp_socket);
+ sowwakeup(canp->canp_socket);
+}
+
+void *
+can_ctlinput(int cmd, struct sockaddr *sa, void *v)
+{
+ struct ip *ip = v;
+ struct canhdr *uh;
+ void (*notify) __P((struct inpcb *, int)) = can_notify;
+ int errno;
+
+ if (sa->sa_family != AF_CAN
+ || sa->sa_len != sizeof(struct sockaddr_can))
+ return NULL;
+ if ((unsigned)cmd >= PRC_NCMDS)
+ return NULL;
+ errno = inetctlerrmap[cmd];
+ if (PRC_IS_REDIRECT(cmd))
+ notify = in_rtchange, ip = 0;
+ else if (cmd == PRC_HOSTDEAD)
+ ip = 0;
+ else if (errno == 0)
+ return NULL;
+ if (ip) {
+ uh = (struct canhdr *)((caddr_t)ip + (ip->ip_hl << 2));
+ in_pcbnotify(&udbtable, satosin(sa)->sin_addr, uh->uh_dport,
+ ip->ip_src, uh->uh_sport, errno, notify);
+
+ /* XXX mapped address case */
+ } else
+ can_pcbnotifyall(&cbtable, satoscan(sa)->scan_addr, errno,
+ notify);
+ return NULL;
+}
+#endif
+
+PR_WRAP_USRREQS(can)
+#define can_attach can_attach_wrapper
+#define can_detach can_detach_wrapper
+#define can_accept can_accept_wrapper
+#define can_bind can_bind_wrapper
+#define can_listen can_listen_wrapper
+#define can_connect can_connect_wrapper
+#define can_connect2 can_connect2_wrapper
+#define can_disconnect can_disconnect_wrapper
+#define can_shutdown can_shutdown_wrapper
+#define can_abort can_abort_wrapper
+#define can_ioctl can_ioctl_wrapper
+#define can_stat can_stat_wrapper
+#define can_peeraddr can_peeraddr_wrapper
+#define can_sockaddr can_sockaddr_wrapper
+#define can_rcvd can_rcvd_wrapper
+#define can_recvoob can_recvoob_wrapper
+#define can_send can_send_wrapper
+#define can_sendoob can_sendoob_wrapper
+#define can_purgeif can_purgeif_wrapper
+
+const struct pr_usrreqs can_usrreqs = {
+ .pr_attach = can_attach,
+ .pr_detach = can_detach,
+ .pr_accept = can_accept,
+ .pr_bind = can_bind,
+ .pr_listen = can_listen,
+ .pr_connect = can_connect,
+ .pr_connect2 = can_connect2,
+ .pr_disconnect = can_disconnect,
+ .pr_shutdown = can_shutdown,
+ .pr_abort = can_abort,
+ .pr_ioctl = can_ioctl,
+ .pr_stat = can_stat,
+ .pr_peeraddr = can_peeraddr,
+ .pr_sockaddr = can_sockaddr,
+ .pr_rcvd = can_rcvd,
+ .pr_recvoob = can_recvoob,
+ .pr_send = can_send,
+ .pr_sendoob = can_sendoob,
+ .pr_purgeif = can_purgeif,
+};
Index: src/sys/netcan/can.h
diff -u /dev/null src/sys/netcan/can.h:1.1.2.1
--- /dev/null Sun Jan 15 20:27:34 2017
+++ src/sys/netcan/can.h Sun Jan 15 20:27:33 2017
@@ -0,0 +1,133 @@
+/* $NetBSD: can.h,v 1.1.2.1 2017/01/15 20:27:33 bouyer Exp $ */
+
+/*-
+ * Copyright (c) 2003, 2017 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Robert Swindells and Manuel Bouyer
+ *
+ * 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.
+ */
+
+#ifndef _NETCAN_CAN_H
+#define _NETCAN_CAN_H
+
+#include <sys/featuretest.h>
+#include <machine/int_types.h>
+
+
+/* Definitions compatible (as much as possible) with socketCAN */
+
+/*
+ * CAN id structure
+ * bits 0-28 : CAN identifier (11/29 bits, see bit 31)
+ * bit2 29-31 : see below
+ */
+
+typedef uint32_t canid_t;
+typedef uint32_t can_err_mask_t;
+
+/* canid_t bits 29-31 descriptions */
+#define CAN_EFF_FLAG 0x80000000U /* extended frame format */
+#define CAN_RTR_FLAG 0x40000000U /* remote transmission request */
+#define CAN_ERR_FLAG 0x20000000U /* error message frame */
+
+/* valid bits in CAN ID for frame formats */
+#define CAN_SFF_MASK 0x000007FFU /* standard frame format (SFF) */
+#define CAN_EFF_MASK 0x1FFFFFFFU /* extended frame format (EFF) */
+#define CAN_ERR_MASK 0x1FFFFFFFU /* error frame format */
+
+/* CAN payload length and DLC definitions according to ISO 11898-1 */
+#define CAN_MAX_DLC 8
+#define CAN_MAX_DLEN 8
+
+/* CAN frame */
+struct can_frame {
+ canid_t can_id; /* ID + EFF/RTR/ERR flags */
+ uint8_t can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */
+ uint8_t __pad;
+ uint8_t __res0;
+ uint8_t __res1;
+ uint8_t data[CAN_MAX_DLEN];
+};
+
+#define CAN_MTU (sizeof(struct can_frame))
+
+/* protocols */
+#define CAN_RAW 1 /* RAW sockets */
+#define CAN_NPROTO 2
+
+#define SOL_CAN_BASE 100
+
+/*
+ * Socket address, CAN style
+ */
+struct sockaddr_can {
+ u_int8_t can_len;
+ sa_family_t can_family;
+ int can_ifindex;
+ union {
+ /* transport protocol class address information (e.g. ISOTP) */
+ struct { canid_t rx_id, tx_id; } tp;
+ /* reserved for future CAN protocols address information */
+ } can_addr;
+};
+
+/*
+ * Options for use with [gs]etsockopt
+ * First word of comment is data type; bool is stored in int.
+ */
+
+#define CAN_RAW_FILTER 1 /* struct can_filter: set filter */
+
+/*
+ * CAN ID based filter
+ * checks received can_id & can_filter.can_mask against
+ * can_filter.can_id & can_filter.can_mask
+ * valid flags for can_id:
+ * CAN_INV_FILTER: invert filter
+ * valid flags for can_mask:
+ * CAN_ERR_FLAG: filter for error message frames
+ */
+struct can_filter {
+ canid_t can_id;
+ canid_t can_mask;
+};
+
+#define CAN_INV_FILTER 0x20000000U
+
+#ifdef _NETBSD_SOURCE
+
+/* CAN sockets ioctl */
+
+#define SIOCSCANBAUD _IOW('i', 134, int) /* set interface speed */
+#define SIOCGCANBAUD _IOR('i', 135, int) /* get interface speed */
+
+#ifdef _KERNEL
+
+#define satoscan(sa) ((struct sockaddr_can *)(sa))
+#define scantosa(scan) ((struct sockaddr *)(scan))
+
+#endif /* _KERNEL */
+#endif /* _NETBSD_SOURCE */
+#endif /* _NETCAN_CAN_H */
Index: src/sys/netcan/can_pcb.c
diff -u /dev/null src/sys/netcan/can_pcb.c:1.1.2.1
--- /dev/null Sun Jan 15 20:27:34 2017
+++ src/sys/netcan/can_pcb.c Sun Jan 15 20:27:33 2017
@@ -0,0 +1,283 @@
+/* $NetBSD: can_pcb.c,v 1.1.2.1 2017/01/15 20:27:33 bouyer Exp $ */
+
+/*-
+ * Copyright (c) 2003, 2017 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Robert Swindells and Manuel Bouyer
+ *
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: can_pcb.c,v 1.1.2.1 2017/01/15 20:27:33 bouyer Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/protosw.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/ioctl.h>
+#include <sys/errno.h>
+#include <sys/time.h>
+#include <sys/pool.h>
+#include <sys/proc.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netcan/can.h>
+#include <netcan/can_var.h>
+#include <netcan/can_pcb.h>
+
+#define CANPCBHASH_BIND(table, ifindex) \
+ &(table)->canpt_bindhashtbl[ \
+ (ifindex) & (table)->canpt_bindhash]
+#define CANPCBHASH_CONNECT(table, ifindex) \
+ &(table)->canpt_connecthashtbl[ \
+ (ifindex) & (table)->canpt_bindhash]
+
+struct pool canpcb_pool;
+
+void
+can_pcbinit(struct canpcbtable *table, int bindhashsize, int connecthashsize)
+{
+ static int canpcb_pool_initialized;
+
+ if (canpcb_pool_initialized == 0) {
+ pool_init(&canpcb_pool, sizeof(struct canpcb), 0, 0, 0,
+ "canpcbpl", NULL, IPL_SOFTNET);
+ canpcb_pool_initialized = 1;
+ }
+
+ TAILQ_INIT(&table->canpt_queue);
+ table->canpt_bindhashtbl = hashinit(bindhashsize, HASH_LIST, true,
+ &table->canpt_bindhash);
+ table->canpt_connecthashtbl = hashinit(connecthashsize, HASH_LIST,
+ true, &table->canpt_connecthash);
+}
+
+int
+can_pcballoc(struct socket *so, void *v)
+{
+ struct canpcbtable *table = v;
+ struct canpcb *canp;
+ int s;
+
+ s = splnet();
+ canp = pool_get(&canpcb_pool, PR_NOWAIT);
+ splx(s);
+ if (canp == NULL)
+ return (ENOBUFS);
+ memset(canp, 0, sizeof(*canp));
+ canp->canp_table = table;
+ canp->canp_socket = so;
+
+ so->so_pcb = canp;
+ s = splnet();
+ TAILQ_INSERT_HEAD(&table->canpt_queue, canp, canp_queue);
+ can_pcbstate(canp, CANP_ATTACHED);
+ splx(s);
+ return (0);
+}
+
+int
+can_pcbbind(void *v, struct sockaddr_can *scan, struct lwp *l)
+{
+ struct canpcb *canp = v;
+
+ if (scan->can_family != AF_CAN)
+ return (EAFNOSUPPORT);
+ if (scan->can_ifindex != 0) {
+ canp->canp_ifp = if_byindex(scan->can_ifindex);
+ if (canp->canp_ifp == NULL)
+ return (EADDRNOTAVAIL);
+ soisconnected(canp->canp_socket);
+ } else {
+ canp->canp_ifp = NULL;
+ canp->canp_socket->so_state &= ~SS_ISCONNECTED; /* XXX */
+ }
+ can_pcbstate(canp, CANP_BOUND);
+ return 0;
+}
+
+/*
+ * Connect from a socket to a specified address.
+ */
+int
+can_pcbconnect(void *v, struct sockaddr_can *scan)
+{
+#if 0
+ struct canpcb *canp = v;
+ struct sockaddr_can *ifaddr = NULL;
+ int error;
+#endif
+
+ if (scan->can_family != AF_CAN)
+ return (EAFNOSUPPORT);
+#if 0
+ memcpy(&canp->canp_dst, scan, sizeof(struct sockaddr_can));
+ can_pcbstate(canp, CANP_CONNECTED);
+ return 0;
+#endif
+ return EOPNOTSUPP;
+}
+
+void
+can_pcbdisconnect(void *v)
+{
+ struct canpcb *canp = v;
+
+ can_pcbstate(canp, CANP_BOUND);
+ if (canp->canp_socket->so_state & SS_NOFDREF)
+ can_pcbdetach(canp);
+}
+
+void
+can_pcbdetach(void *v)
+{
+ struct canpcb *canp = v;
+ struct socket *so = canp->canp_socket;
+ int s;
+
+ KASSERT(mutex_owned(softnet_lock));
+ so->so_pcb = NULL;
+ s = splnet();
+ can_pcbstate(canp, CANP_ATTACHED);
+ TAILQ_REMOVE(&canp->canp_table->canpt_queue, canp, canp_queue);
+ splx(s);
+ sofree(so); /* sofree drops the lock */
+ pool_put(&canpcb_pool, canp);
+ mutex_enter(softnet_lock);
+}
+
+void
+can_setsockaddr(struct canpcb *canp, struct sockaddr_can *scan)
+{
+
+ memset(scan, 0, sizeof (*scan));
+ scan->can_family = AF_CAN;
+ scan->can_len = sizeof(*scan);
+ scan->can_ifindex = canp->canp_ifp->if_index;
+}
+
+#if 0
+/*
+ * Pass some notification to all connections of a protocol
+ * associated with address dst. The local address and/or port numbers
+ * may be specified to limit the search. The "usual action" will be
+ * taken, depending on the ctlinput cmd. The caller must filter any
+ * cmds that are uninteresting (e.g., no error in the map).
+ * Call the protocol specific routine (if any) to report
+ * any errors for each matching socket.
+ *
+ * Must be called at splsoftnet.
+ */
+int
+can_pcbnotify(struct canpcbtable *table, u_int32_t faddr, u_int32_t laddr,
+ int errno, void (*notify)(struct canpcb *, int))
+{
+ struct canpcbhead *head;
+ struct canpcb *canp, *ncanp;
+ int nmatch;
+
+ if (faddr == 0 || notify == 0)
+ return (0);
+
+ nmatch = 0;
+ head = CANPCBHASH_CONNECT(table, faddr, laddr);
+ for (canp = LIST_FIRST(head); canp != NULL; canp = ncanp) {
+ ncanp = LIST_NEXT(canp, canp_hash);
+ if (canp->canp_faddr == faddr &&
+ canp->canp_laddr == laddr) {
+ (*notify)(canp, errno);
+ nmatch++;
+ }
+ }
+ return (nmatch);
+}
+
+void
+can_pcbnotifyall(struct canpcbtable *table, u_int32_t faddr, int errno,
+ void (*notify)(struct canpcb *, int))
+{
+ struct canpcb *canp, *ncanp;
+
+ if (faddr == 0 || notify == 0)
+ return;
+
+ TAILQ_FOREACH_SAFE(canp, &table->canpt_queue, canp_queue, ncanp) {
+ if (canp->canp_faddr == faddr)
+ (*notify)(canp, errno);
+ }
+}
+#endif
+
+#if 0
+void
+can_pcbpurgeif0(struct canpcbtable *table, struct ifnet *ifp)
+{
+ struct canpcb *canp, *ncanp;
+ struct ip_moptions *imo;
+ int i, gap;
+
+}
+
+void
+can_pcbpurgeif(struct canpcbtable *table, struct ifnet *ifp)
+{
+ struct canpcb *canp, *ncanp;
+
+ for (canp = CIRCLEQ_FIRST(&table->canpt_queue);
+ canp != (void *)&table->canpt_queue;
+ canp = ncanp) {
+ ncanp = CIRCLEQ_NEXT(canp, canp_queue);
+ }
+}
+#endif
+
+
+
+void
+can_pcbstate(struct canpcb *canp, int state)
+{
+ int ifindex = canp->canp_ifp ? canp->canp_ifp->if_index : 0;
+
+ if (canp->canp_state > CANP_ATTACHED)
+ LIST_REMOVE(canp, canp_hash);
+
+ switch (state) {
+ case CANP_BOUND:
+ LIST_INSERT_HEAD(CANPCBHASH_BIND(canp->canp_table,
+ ifindex), canp, canp_hash);
+ break;
+ case CANP_CONNECTED:
+ LIST_INSERT_HEAD(CANPCBHASH_CONNECT(canp->canp_table,
+ ifindex), canp, canp_hash);
+ break;
+ }
+
+ canp->canp_state = state;
+}
Index: src/sys/netcan/can_pcb.h
diff -u /dev/null src/sys/netcan/can_pcb.h:1.1.2.1
--- /dev/null Sun Jan 15 20:27:34 2017
+++ src/sys/netcan/can_pcb.h Sun Jan 15 20:27:33 2017
@@ -0,0 +1,98 @@
+/* $NetBSD: can_pcb.h,v 1.1.2.1 2017/01/15 20:27:33 bouyer Exp $ */
+
+/*-
+ * Copyright (c) 2003, 2017 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Robert Swindells and Manuel Bouyer
+ *
+ * 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.
+ */
+
+#ifndef _NETCAN_CAN_PCB_H_
+#define _NETCAN_CAN_PCB_H_
+
+#include <sys/queue.h>
+
+/*
+ * Common structure pcb for can protocol implementation.
+ * Here are stored pointers to local and foreign host table
+ * entries, local and foreign socket numbers, and pointers
+ * up (to a socket structure) and down (to a protocol-specific)
+ * control block.
+ */
+struct canpcbpolicy;
+
+
+struct canpcb {
+ LIST_ENTRY(canpcb) canp_hash;
+ LIST_ENTRY(canpcb) canp_lhash;
+ TAILQ_ENTRY(canpcb) canp_queue;
+ int canp_state;
+ struct socket *canp_socket; /* back pointer to socket */
+ struct ifnet *canp_ifp;
+ struct canpcbtable *canp_table;
+};
+
+LIST_HEAD(canpcbhead, canpcb);
+
+#define canp_faddr canp_dst.scan_addr
+
+TAILQ_HEAD(canpcbqueue, canpcb);
+
+struct canpcbtable {
+ struct canpcbqueue canpt_queue;
+ struct canpcbhead *canpt_bindhashtbl;
+ struct canpcbhead *canpt_connecthashtbl;
+ u_long canpt_bindhash;
+ u_long canpt_connecthash;
+};
+
+/* states in inp_state: */
+#define CANP_ATTACHED 0
+#define CANP_BOUND 1
+#define CANP_CONNECTED 2
+
+/* flags in inp_flags: */
+
+#define sotocanpcb(so) ((struct canpcb *)(so)->so_pcb)
+
+#ifdef _KERNEL
+void can_losing(struct canpcb *);
+int can_pcballoc (struct socket *, void *);
+int can_pcbbind(void *, struct sockaddr_can *, struct lwp *);
+int can_pcbconnect(void *, struct sockaddr_can *);
+void can_pcbdetach(void *);
+void can_pcbdisconnect(void *);
+void can_pcbinit(struct canpcbtable *, int, int);
+int can_pcbnotify(struct canpcbtable *, u_int32_t,
+ u_int32_t, int, void (*)(struct canpcb *, int));
+void can_pcbnotifyall(struct canpcbtable *, u_int32_t, int,
+ void (*)(struct canpcb *, int));
+void can_pcbpurgeif0(struct canpcbtable *, struct ifnet *);
+void can_pcbpurgeif(struct canpcbtable *, struct ifnet *);
+void can_pcbstate(struct canpcb *, int);
+void can_setsockaddr(struct canpcb *, struct sockaddr_can *);
+#endif
+
+#endif /* _NETCAN_CAN_PCB_H_ */
Index: src/sys/netcan/can_proto.c
diff -u /dev/null src/sys/netcan/can_proto.c:1.1.2.1
--- /dev/null Sun Jan 15 20:27:34 2017
+++ src/sys/netcan/can_proto.c Sun Jan 15 20:27:33 2017
@@ -0,0 +1,75 @@
+/* $NetBSD: can_proto.c,v 1.1.2.1 2017/01/15 20:27:33 bouyer Exp $ */
+
+/*-
+ * Copyright (c) 2003, 2017 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Robert Swindells and Manuel Bouyer
+ *
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: can_proto.c,v 1.1.2.1 2017/01/15 20:27:33 bouyer Exp $");
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/protosw.h>
+#include <sys/domain.h>
+#include <sys/mbuf.h>
+
+#include <net/if.h>
+#include <net/radix.h>
+#include <net/route.h>
+
+/*
+ * CAN protocol family
+ */
+#include <netcan/can.h>
+#include <netcan/can_var.h>
+
+DOMAIN_DEFINE(candomain); /* forward declare and add to link set */
+
+const struct protosw cansw[] = {
+{
+ .pr_type = SOCK_RAW,
+ .pr_domain = &candomain,
+ .pr_init = can_init,
+ .pr_flags = PR_ATOMIC|PR_ADDR,
+ .pr_usrreqs = &can_usrreqs,
+}
+};
+
+struct domain candomain = {
+ .dom_family = PF_CAN,
+ .dom_name = "can",
+ .dom_init = can_init,
+ .dom_externalize = NULL, .dom_dispose = NULL,
+ .dom_protosw = cansw,
+ .dom_protoswNPROTOSW = &cansw[__arraycount(cansw)],
+ .dom_ifqueues = { &canintrq, NULL },
+ .dom_link = { NULL },
+ .dom_mowner = MOWNER_INIT("",""),
+ .dom_sa_cmpofs = offsetof(struct sockaddr_can, can_ifindex),
+ .dom_sa_cmplen = sizeof(int)
+};
Index: src/sys/netcan/can_var.h
diff -u /dev/null src/sys/netcan/can_var.h:1.1.2.1
--- /dev/null Sun Jan 15 20:27:34 2017
+++ src/sys/netcan/can_var.h Sun Jan 15 20:27:33 2017
@@ -0,0 +1,56 @@
+/* $NetBSD: can_var.h,v 1.1.2.1 2017/01/15 20:27:33 bouyer Exp $ */
+
+/*-
+ * Copyright (c) 2003, 2017 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Robert Swindells and Manuel Bouyer
+ *
+ * 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.
+ */
+
+#ifndef _NETCAN_CAN_VAR_H_
+#define _NETCAN_CAN_VAR_H_
+
+#include <sys/queue.h>
+
+struct can_ifreq {
+ char cfr_name[IFNAMSIZ]; /* if name, e.g. "sja0" */
+};
+
+#ifdef _KERNEL
+
+extern struct ifqueue canintrq;
+extern struct domain candomain;
+
+extern const struct pr_usrreqs can_usrreqs;
+
+void can_input(struct ifnet *, struct mbuf *);
+void *can_ctlinput(int, struct sockaddr *, void *);
+int can_ctloutput(int, struct socket *, int, int, struct mbuf **);
+void can_init(void);
+void canintr(void);
+
+#endif
+
+#endif
Index: src/sys/netcan/files.netcan
diff -u /dev/null src/sys/netcan/files.netcan:1.1.2.1
--- /dev/null Sun Jan 15 20:27:34 2017
+++ src/sys/netcan/files.netcan Sun Jan 15 20:27:33 2017
@@ -0,0 +1,8 @@
+# $NetBSD: files.netcan,v 1.1.2.1 2017/01/15 20:27:33 bouyer Exp $
+
+defflag opt_can.h CAN # ISO-15765 CAN network stack
+
+file netcan/can.c can
+file netcan/can_proto.c can
+file netcan/can_pcb.c can
+file net/if_canloop.c canloop
Index: src/sys/netcan/if_canloop.c
diff -u /dev/null src/sys/netcan/if_canloop.c:1.1.2.1
--- /dev/null Sun Jan 15 20:27:34 2017
+++ src/sys/netcan/if_canloop.c Sun Jan 15 20:27:33 2017
@@ -0,0 +1,232 @@
+/* $NetBSD: if_canloop.c,v 1.1.2.1 2017/01/15 20:27:33 bouyer Exp $ */
+
+/*-
+ * Copyright (c) 2017 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Manuel Bouyer.
+ *
+ * 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.
+ */
+
+
+/*
+ * Loopback interface driver for the CAN protocol
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: if_canloop.c,v 1.1.2.1 2017/01/15 20:27:33 bouyer Exp $");
+
+#ifdef _KERNEL_OPT
+#include "opt_can.h"
+#include "opt_net_mpsafe.h"
+#endif
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/errno.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/device.h>
+#include <sys/module.h>
+
+#include <sys/cpu.h>
+
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/netisr.h>
+
+#ifdef CAN
+#include <netcan/can.h>
+#endif
+#include <net/bpf.h>
+
+void canloopattach(int);
+void canloopinit(void);
+static int canloop_clone_create(struct if_clone *, int);
+static int canloop_clone_destroy(struct ifnet *);
+static int canloop_ioctl(struct ifnet *, u_long, void *);
+static int canloop_output(struct ifnet *,
+ struct mbuf *, const struct sockaddr *, const struct rtentry *);
+
+static int canloop_count;
+
+static struct if_clone canloop_cloner =
+ IF_CLONE_INITIALIZER("canlo", canloop_clone_create, canloop_clone_destroy);
+
+void
+canloopattach(int n)
+{
+
+ /*
+ * Nothing to do here, initialization is handled by the
+ * module initialization code in canloopnit() below).
+ */
+}
+
+void
+canloopinit(void)
+{
+
+ canloop_count = 0;
+ if_clone_attach(&canloop_cloner);
+}
+
+static int
+canloopdetach(void)
+{
+ if (canloop_count > 0)
+ return EBUSY;
+ if_clone_detach(&canloop_cloner);
+ return 0;
+}
+
+static int
+canloop_clone_create(struct if_clone *ifc, int unit)
+{
+ struct ifnet *ifp;
+
+ ifp = if_alloc(IFT_OTHER);
+
+ if_initname(ifp, ifc->ifc_name, unit);
+
+ ifp->if_mtu = sizeof(struct can_frame);
+ ifp->if_flags = IFF_LOOPBACK | IFF_RUNNING;
+ ifp->if_extflags = IFEF_OUTPUT_MPSAFE;
+ ifp->if_ioctl = canloop_ioctl;
+ ifp->if_output = canloop_output;
+ ifp->if_type = IFT_OTHER;
+ ifp->if_hdrlen = 0;
+ ifp->if_addrlen = 0;
+ ifp->if_dlt = DLT_CAN_SOCKETCAN;
+ IFQ_SET_READY(&ifp->if_snd);
+ if_attach(ifp);
+ if_alloc_sadl(ifp);
+ bpf_attach(ifp, DLT_CAN_SOCKETCAN, sizeof(u_int));
+#ifdef MBUFTRACE
+ ifp->if_mowner = malloc(sizeof(struct mowner), M_DEVBUF,
+ M_WAITOK | M_ZERO);
+ strlcpy(ifp->if_mowner->mo_name, ifp->if_xname,
+ sizeof(ifp->if_mowner->mo_name));
+ MOWNER_ATTACH(ifp->if_mowner);
+#endif
+ canloop_count++;
+
+ return (0);
+}
+
+static int
+canloop_clone_destroy(struct ifnet *ifp)
+{
+
+#ifdef MBUFTRACE
+ MOWNER_DETACH(ifp->if_mowner);
+ free(ifp->if_mowner, M_DEVBUF);
+#endif
+
+ bpf_detach(ifp);
+ if_detach(ifp);
+
+ if_free(ifp);
+ canloop_count--;
+ KASSERT(canloop_count >= 0);
+ return (0);
+}
+
+static int
+canloop_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
+ const struct rtentry *rt)
+{
+ int error = 0;
+ size_t pktlen;
+
+ MCLAIM(m, ifp->if_mowner);
+
+ KERNEL_LOCK(1, NULL);
+
+ if ((m->m_flags & M_PKTHDR) == 0)
+ panic("canloop_output: no header mbuf");
+ if (ifp->if_flags & IFF_LOOPBACK)
+ bpf_mtap_af(ifp, AF_CAN, m);
+ m_set_rcvif(m, ifp);
+
+ pktlen = m->m_pkthdr.len;
+ ifp->if_opackets++;
+ ifp->if_obytes += pktlen;
+
+ m_tag_delete_nonpersistent(m);
+
+#ifdef CAN
+ can_input(ifp, m);
+#else
+ printf("%s: can't handle CAN packet\n", ifp->if_xname);
+ m_freem(m);
+ error = EAFNOSUPPORT;
+#endif
+
+ KERNEL_UNLOCK_ONE(NULL);
+ return error;
+}
+
+
+/*
+ * Process an ioctl request.
+ */
+/* ARGSUSED */
+static int
+canloop_ioctl(struct ifnet *ifp, u_long cmd, void *data)
+{
+ struct ifreq *ifr = data;
+ int error = 0;
+
+ switch (cmd) {
+
+ case SIOCINITIFADDR:
+ error = EAFNOSUPPORT;
+ break;
+
+ case SIOCSIFMTU:
+ if ((unsigned)ifr->ifr_mtu != sizeof(struct can_frame))
+ error = EINVAL;
+ break;
+
+ case SIOCADDMULTI:
+ case SIOCDELMULTI:
+ error = EAFNOSUPPORT;
+ break;
+
+ default:
+ error = ifioctl_common(ifp, cmd, data);
+ }
+ return (error);
+}
+
+/*
+ * Module infrastructure
+ */
+#include "../net/if_module.h"
+
+IF_MODULE(MODULE_CLASS_DRIVER, canloop, "")
Index: src/sys/rump/net/lib/libnetcan/Makefile
diff -u /dev/null src/sys/rump/net/lib/libnetcan/Makefile:1.1.2.1
--- /dev/null Sun Jan 15 20:27:34 2017
+++ src/sys/rump/net/lib/libnetcan/Makefile Sun Jan 15 20:27:34 2017
@@ -0,0 +1,20 @@
+# $NetBSD: Makefile,v 1.1.2.1 2017/01/15 20:27:34 bouyer Exp $
+#
+
+NOLINT= #defined
+
+.include <bsd.own.mk>
+
+.PATH: ${.CURDIR}/../../../../netcan
+
+LIB= rumpnet_netcan
+COMMENT=CAN (PF_CAN)
+
+IOCONF= NETCAN.ioconf
+
+SRCS= can.c can_pcb.c can_proto.c if_canloop.c
+
+SRCS+= netcan_component.c
+
+.include <bsd.lib.mk>
+.include <bsd.klinks.mk>
Index: src/sys/rump/net/lib/libnetcan/NETCAN.ioconf
diff -u /dev/null src/sys/rump/net/lib/libnetcan/NETCAN.ioconf:1.1.2.1
--- /dev/null Sun Jan 15 20:27:34 2017
+++ src/sys/rump/net/lib/libnetcan/NETCAN.ioconf Sun Jan 15 20:27:34 2017
@@ -0,0 +1,7 @@
+# $NetBSD: NETCAN.ioconf,v 1.1.2.1 2017/01/15 20:27:34 bouyer Exp $
+
+ioconf netcan
+
+include "conf/files"
+
+pseudo-device canloop
Index: src/sys/rump/net/lib/libnetcan/netcan_component.c
diff -u /dev/null src/sys/rump/net/lib/libnetcan/netcan_component.c:1.1.2.1
--- /dev/null Sun Jan 15 20:27:34 2017
+++ src/sys/rump/net/lib/libnetcan/netcan_component.c Sun Jan 15 20:27:34 2017
@@ -0,0 +1,52 @@
+/* $NetBSD: netcan_component.c,v 1.1.2.1 2017/01/15 20:27:34 bouyer Exp $ */
+
+/*
+ * Copyright (c) 2010 Antti Kantee. 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 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 <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: netcan_component.c,v 1.1.2.1 2017/01/15 20:27:34 bouyer Exp $");
+
+#include <sys/param.h>
+#include <sys/domain.h>
+#include <sys/protosw.h>
+
+#include <rump-sys/kern.h>
+#include <rump-sys/net.h>
+#include <net/netisr.h>
+#include <netcan/can_var.h>
+
+RUMP_COMPONENT(RUMP_COMPONENT_NET)
+{
+ extern struct domain candomain;
+
+ domain_attach(&candomain);
+ rump_netisr_register(NETISR_CAN, canintr);
+}
+
+void canloopinit(void);
+RUMP_COMPONENT(RUMP_COMPONENT_NET_IF)
+{
+ canloopinit();
+}