CVS commit: [bouyer-socketcan] src/sys/netcan
Module Name:src Committed By: bouyer Date: Thu May 25 18:21:01 UTC 2017 Modified Files: src/sys/netcan [bouyer-socketcan]: can.c can_var.h if_canloop.c Log Message: Allow can_bpf_mtap() to call bpf_mtap_softint() when needed. To generate a diff of this commit: cvs rdiff -u -r1.1.2.14 -r1.1.2.15 src/sys/netcan/can.c cvs rdiff -u -r1.1.2.8 -r1.1.2.9 src/sys/netcan/can_var.h cvs rdiff -u -r1.1.2.7 -r1.1.2.8 src/sys/netcan/if_canloop.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/netcan/can.c diff -u src/sys/netcan/can.c:1.1.2.14 src/sys/netcan/can.c:1.1.2.15 --- src/sys/netcan/can.c:1.1.2.14 Mon May 22 16:11:23 2017 +++ src/sys/netcan/can.c Thu May 25 18:21:00 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: can.c,v 1.1.2.14 2017/05/22 16:11:23 bouyer Exp $ */ +/* $NetBSD: can.c,v 1.1.2.15 2017/05/25 18:21:00 bouyer Exp $ */ /*- * Copyright (c) 2003, 2017 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.1.2.14 2017/05/22 16:11:23 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.1.2.15 2017/05/25 18:21:00 bouyer Exp $"); #include #include @@ -416,7 +416,7 @@ canintr(void) } void -can_bpf_mtap(struct ifnet *ifp, struct mbuf *m) +can_bpf_mtap(struct ifnet *ifp, struct mbuf *m, bool do_softint) { /* bpf wants the CAN id in network byte order */ struct can_frame *cf; @@ -425,7 +425,10 @@ can_bpf_mtap(struct ifnet *ifp, struct m cf = mtod(m, struct can_frame *); oid = cf->can_id; cf->can_id = htonl(oid); - bpf_mtap(ifp, m); + if (do_softint) + bpf_mtap_softint(ifp, m); + else + bpf_mtap(ifp, m); cf->can_id = oid; } Index: src/sys/netcan/can_var.h diff -u src/sys/netcan/can_var.h:1.1.2.8 src/sys/netcan/can_var.h:1.1.2.9 --- src/sys/netcan/can_var.h:1.1.2.8 Mon May 22 16:11:23 2017 +++ src/sys/netcan/can_var.h Thu May 25 18:21:00 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: can_var.h,v 1.1.2.8 2017/05/22 16:11:23 bouyer Exp $ */ +/* $NetBSD: can_var.h,v 1.1.2.9 2017/05/25 18:21:00 bouyer Exp $ */ /*- * Copyright (c) 2003, 2017 The NetBSD Foundation, Inc. @@ -68,7 +68,7 @@ void *can_ctlinput(int, struct sockaddr int can_ctloutput(int, struct socket *, struct sockopt *); void can_init(void); void canintr(void); -void can_bpf_mtap(struct ifnet *, struct mbuf *); +void can_bpf_mtap(struct ifnet *, struct mbuf *, bool); #endif Index: src/sys/netcan/if_canloop.c diff -u src/sys/netcan/if_canloop.c:1.1.2.7 src/sys/netcan/if_canloop.c:1.1.2.8 --- src/sys/netcan/if_canloop.c:1.1.2.7 Mon May 22 16:11:23 2017 +++ src/sys/netcan/if_canloop.c Thu May 25 18:21:00 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: if_canloop.c,v 1.1.2.7 2017/05/22 16:11:23 bouyer Exp $ */ +/* $NetBSD: if_canloop.c,v 1.1.2.8 2017/05/25 18:21:00 bouyer Exp $ */ /*- * Copyright (c) 2017 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: if_canloop.c,v 1.1.2.7 2017/05/22 16:11:23 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_canloop.c,v 1.1.2.8 2017/05/25 18:21:00 bouyer Exp $"); #ifdef _KERNEL_OPT #include "opt_can.h" @@ -162,7 +162,7 @@ canloop_ifstart(struct ifnet *ifp) panic("canloop_output: no header mbuf"); m_set_rcvif(m, ifp); if (ifp->if_flags & IFF_LOOPBACK) - can_bpf_mtap(ifp, m); + can_bpf_mtap(ifp, m, 0); pktlen = m->m_pkthdr.len; ifp->if_opackets++;
CVS commit: [bouyer-socketcan] src/sys/netcan
Module Name:src Committed By: bouyer Date: Mon Apr 24 13:38:33 UTC 2017 Modified Files: src/sys/netcan [bouyer-socketcan]: if_canloop.c Log Message: Use bpf_mtap() not bpf_mtap_af(). Now files produced by tcpdump can be decoded by wireshark. To generate a diff of this commit: cvs rdiff -u -r1.1.2.5 -r1.1.2.6 src/sys/netcan/if_canloop.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/netcan/if_canloop.c diff -u src/sys/netcan/if_canloop.c:1.1.2.5 src/sys/netcan/if_canloop.c:1.1.2.6 --- src/sys/netcan/if_canloop.c:1.1.2.5 Wed Apr 19 22:17:56 2017 +++ src/sys/netcan/if_canloop.c Mon Apr 24 13:38:33 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: if_canloop.c,v 1.1.2.5 2017/04/19 22:17:56 bouyer Exp $ */ +/* $NetBSD: if_canloop.c,v 1.1.2.6 2017/04/24 13:38:33 bouyer Exp $ */ /*- * Copyright (c) 2017 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: if_canloop.c,v 1.1.2.5 2017/04/19 22:17:56 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_canloop.c,v 1.1.2.6 2017/04/24 13:38:33 bouyer Exp $"); #ifdef _KERNEL_OPT #include "opt_can.h" @@ -166,7 +166,7 @@ canloop_ifstart(struct ifnet *ifp) panic("canloop_output: no header mbuf"); m_set_rcvif(m, ifp); if (ifp->if_flags & IFF_LOOPBACK) - bpf_mtap_af(ifp, AF_CAN, m); + bpf_mtap(ifp, m); pktlen = m->m_pkthdr.len; ifp->if_opackets++;
CVS commit: [bouyer-socketcan] src/sys/netcan
Module Name:src Committed By: bouyer Date: Sun Apr 23 21:05:09 UTC 2017 Modified Files: src/sys/netcan [bouyer-socketcan]: can.c can_pcb.c can_pcb.h Log Message: Add locking and refcounting to canpcb. Store the canpcb in the in the mbuf tag on send instead of the socket's address. This should protect against a race where the socket cloud be closed before we get back the mbuf from the adapter's driver. To generate a diff of this commit: cvs rdiff -u -r1.1.2.12 -r1.1.2.13 src/sys/netcan/can.c cvs rdiff -u -r1.1.2.3 -r1.1.2.4 src/sys/netcan/can_pcb.c \ src/sys/netcan/can_pcb.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/netcan/can.c diff -u src/sys/netcan/can.c:1.1.2.12 src/sys/netcan/can.c:1.1.2.13 --- src/sys/netcan/can.c:1.1.2.12 Thu Apr 20 17:29:10 2017 +++ src/sys/netcan/can.c Sun Apr 23 21:05:09 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: can.c,v 1.1.2.12 2017/04/20 17:29:10 bouyer Exp $ */ +/* $NetBSD: can.c,v 1.1.2.13 2017/04/23 21:05:09 bouyer Exp $ */ /*- * Copyright (c) 2003, 2017 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.1.2.12 2017/04/20 17:29:10 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.1.2.13 2017/04/23 21:05:09 bouyer Exp $"); #include #include @@ -235,7 +235,10 @@ can_output(struct mbuf *m, struct canpcb ifp->if_oerrors++; return ENOMEM; } - *(struct socket **)(sotag + 1) = canp->canp_socket; + mutex_enter(&canp->canp_mtx); + canp_ref(canp); + mutex_exit(&canp->canp_mtx); + *(struct canpcb **)(sotag + 1) = canp; m_tag_prepend(m, sotag); if (m->m_len <= ifp->if_mtu) { @@ -302,7 +305,6 @@ canintr(void) struct sockaddr_can from; struct canpcb *canp; struct m_tag *sotag; - struct socket *so; struct canpcb *sender_canp; mutex_enter(softnet_lock); @@ -319,13 +321,13 @@ canintr(void) #endif sotag = m_tag_find(m, PACKET_TAG_SO, NULL); if (sotag) { - so = *(struct socket **)(sotag + 1); - sender_canp = sotocanpcb(so); + sender_canp = *(struct canpcb **)(sotag + 1); m_tag_delete(m, sotag); + KASSERT(sender_canp != NULL); /* if the sender doesn't want loopback, don't do it */ - if (sender_canp && - (sender_canp->canp_flags & CANP_NO_LOOPBACK) != 0) { + if ((sender_canp->canp_flags & CANP_NO_LOOPBACK) != 0) { m_freem(m); +canp_unref(sender_canp); continue; } } else { @@ -340,19 +342,31 @@ canintr(void) TAILQ_FOREACH(canp, &cbtable.canpt_queue, canp_queue) { struct mbuf *mc; + mutex_enter(&canp->canp_mtx); + /* skip if we're detached */ + if (canp->canp_state == CANP_DETACHED) { +mutex_exit(&canp->canp_mtx); +continue; + } + /* don't loop back to sockets on other interfaces */ if (canp->canp_ifp != NULL && canp->canp_ifp->if_index != rcv_ifindex) { +mutex_exit(&canp->canp_mtx); continue; } /* don't loop back to myself if I don't want it */ if (canp == sender_canp && - (canp->canp_flags & CANP_RECEIVE_OWN) == 0) + (canp->canp_flags & CANP_RECEIVE_OWN) == 0) { +mutex_exit(&canp->canp_mtx); continue; + } /* skip if the accept filter doen't match this pkt */ - if (!can_pcbfilter(canp, m)) + if (!can_pcbfilter(canp, m)) { +mutex_exit(&canp->canp_mtx); continue; + } if (TAILQ_NEXT(canp, canp_queue) != NULL) { /* @@ -375,9 +389,13 @@ canintr(void) m_freem(mc); } else sorwakeup(canp->canp_socket); + mutex_exit(&canp->canp_mtx); if (m == NULL) break; } + if (sender_canp) { + canp_unref(sender_canp); + } /* If it didn't go anywhere just delete it */ if (m) { m_freem(m); @@ -492,7 +510,6 @@ can_disconnect(struct socket *so) /*soisdisconnected(so);*/ so->so_state &= ~SS_ISCONNECTED; /* XXX */ can_pcbdisconnect(canp); - can_pcbstate(canp, CANP_BOUND); /* XXX */ return 0; } @@ -877,7 +894,9 @@ can_raw_setop(struct canpcb *canp, struc int nfilters = sopt->sopt_size / sizeof(struct can_filter); if (sopt->sopt_size % sizeof(struct can_filter) != 0) return EINVAL; + mutex_enter(&canp->canp_mtx); error = can_pcbsetfilter(canp, sopt->sopt_data, nfilters); + mutex_exit(&canp->canp_mtx); break; } default: Index: src/sys/netcan/can_pcb.c diff -u src/sys/netcan/can_pcb.c:1.1.2.3 src/sys/netcan/can_pcb.c:1.1.2.4 --- src/sys/netcan/can_pcb.c:1.1.2.3 Sun Feb 5 19:44:53 2017 +++ src/sys/netcan/can_pcb.c Sun Apr 23 21:05:09 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: can_pcb.c,v 1.1.2.3 2017/02/05 19:44:53 bouyer Exp $ */ +/* $NetBSD: can_pcb.c,v 1.1.2.4 2017/04/23 21:05:09 bouyer Exp $ */ /*- * Copyright (c) 2003, 2017 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: can_pcb.c,v 1.1.2.3 2017/02/05 19:44:53 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: can_pcb.c,v 1.1.2.4 2017/04/23 21:05:09 bouyer Exp $"); #include
CVS commit: [bouyer-socketcan] src/sys/netcan
Module Name:src Committed By: bouyer Date: Thu Apr 20 17:29:10 UTC 2017 Modified Files: src/sys/netcan [bouyer-socketcan]: can.c Log Message: If a packet was sent using sendto, the socket pointed to by the tag may be unbound. Check for this in canintr(). XXX possibly the socket can completely dissapear before we get here. This needs to be revisited. To generate a diff of this commit: cvs rdiff -u -r1.1.2.11 -r1.1.2.12 src/sys/netcan/can.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/netcan/can.c diff -u src/sys/netcan/can.c:1.1.2.11 src/sys/netcan/can.c:1.1.2.12 --- src/sys/netcan/can.c:1.1.2.11 Thu Apr 20 12:59:11 2017 +++ src/sys/netcan/can.c Thu Apr 20 17:29:10 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: can.c,v 1.1.2.11 2017/04/20 12:59:11 bouyer Exp $ */ +/* $NetBSD: can.c,v 1.1.2.12 2017/04/20 17:29:10 bouyer Exp $ */ /*- * Copyright (c) 2003, 2017 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.1.2.11 2017/04/20 12:59:11 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.1.2.12 2017/04/20 17:29:10 bouyer Exp $"); #include #include @@ -323,7 +323,8 @@ canintr(void) sender_canp = sotocanpcb(so); m_tag_delete(m, sotag); /* if the sender doesn't want loopback, don't do it */ - if (sender_canp->canp_flags & CANP_NO_LOOPBACK) { + if (sender_canp && + (sender_canp->canp_flags & CANP_NO_LOOPBACK) != 0) { m_freem(m); continue; }
CVS commit: [bouyer-socketcan] src/sys/netcan
Module Name:src Committed By: bouyer Date: Thu Apr 20 12:59:11 UTC 2017 Modified Files: src/sys/netcan [bouyer-socketcan]: can.c Log Message: Fix LINKMODE Refuse to send packets if LISTENONLY is set Don't forget to unbind in error case. To generate a diff of this commit: cvs rdiff -u -r1.1.2.10 -r1.1.2.11 src/sys/netcan/can.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/netcan/can.c diff -u src/sys/netcan/can.c:1.1.2.10 src/sys/netcan/can.c:1.1.2.11 --- src/sys/netcan/can.c:1.1.2.10 Wed Apr 19 22:19:12 2017 +++ src/sys/netcan/can.c Thu Apr 20 12:59:11 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: can.c,v 1.1.2.10 2017/04/19 22:19:12 bouyer Exp $ */ +/* $NetBSD: can.c,v 1.1.2.11 2017/04/20 12:59:11 bouyer Exp $ */ /*- * Copyright (c) 2003, 2017 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.1.2.10 2017/04/19 22:19:12 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.1.2.11 2017/04/20 12:59:11 bouyer Exp $"); #include #include @@ -146,7 +146,7 @@ can_set_netlink(struct ifnet *ifp, struc case CANCLINKMODE: if (ifd->ifd_len != sizeof(uint32_t)) return EINVAL; - error = copyout(ifd->ifd_data, &mode, ifd->ifd_len); + error = copyin(ifd->ifd_data, &mode, ifd->ifd_len); if (error) return error; if ((mode & csc->csc_timecaps.cltc_linkmode_caps) != mode) @@ -215,6 +215,7 @@ can_output(struct mbuf *m, struct canpcb { struct ifnet *ifp; struct m_tag *sotag; + struct canif_softc *csc; if (canp == NULL) { printf("can_output: no pcb\n"); @@ -224,6 +225,11 @@ can_output(struct mbuf *m, struct canpcb if (ifp == 0) { return EDESTADDRREQ; } + csc = ifp->if_softc; + if (csc && (csc->csc_linkmodes & CAN_LINKMODE_LISTENONLY)) { + return ENETUNREACH; + } + sotag = m_tag_get(PACKET_TAG_SO, sizeof(struct socket *), PR_NOWAIT); if (sotag == NULL) { ifp->if_oerrors++; @@ -602,8 +608,6 @@ can_send(struct socket *so, struct mbuf } } error = can_output(m, canp); - if (error) - goto err; if (nam) { struct sockaddr_can lscan; memset(&lscan, 0, sizeof(lscan)); @@ -611,6 +615,8 @@ can_send(struct socket *so, struct mbuf lscan.can_len = sizeof(lscan); can_pcbbind(canp, &lscan, l); } + if (error) + goto err; return 0; err:
CVS commit: [bouyer-socketcan] src/sys/netcan
Module Name:src Committed By: bouyer Date: Wed Apr 19 22:19:12 UTC 2017 Modified Files: src/sys/netcan [bouyer-socketcan]: can.c Log Message: can_mbuf_tag_clean(): make sure we won't free the tag we will reuse. Avoid mbuf leak in error paths. To generate a diff of this commit: cvs rdiff -u -r1.1.2.9 -r1.1.2.10 src/sys/netcan/can.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/netcan/can.c diff -u src/sys/netcan/can.c:1.1.2.9 src/sys/netcan/can.c:1.1.2.10 --- src/sys/netcan/can.c:1.1.2.9 Wed Apr 19 17:52:37 2017 +++ src/sys/netcan/can.c Wed Apr 19 22:19:12 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: can.c,v 1.1.2.9 2017/04/19 17:52:37 bouyer Exp $ */ +/* $NetBSD: can.c,v 1.1.2.10 2017/04/19 22:19:12 bouyer Exp $ */ /*- * Copyright (c) 2003, 2017 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.1.2.9 2017/04/19 17:52:37 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.1.2.10 2017/04/19 22:19:12 bouyer Exp $"); #include #include @@ -214,24 +214,20 @@ static int can_output(struct mbuf *m, struct canpcb *canp) { struct ifnet *ifp; - int error = 0; struct m_tag *sotag; if (canp == NULL) { printf("can_output: no pcb\n"); - error = EINVAL; - return error; + return EINVAL; } ifp = canp->canp_ifp; if (ifp == 0) { - error = EDESTADDRREQ; - goto bad; + return EDESTADDRREQ; } sotag = m_tag_get(PACKET_TAG_SO, sizeof(struct socket *), PR_NOWAIT); if (sotag == NULL) { ifp->if_oerrors++; - error = ENOMEM; - goto bad; + return ENOMEM; } *(struct socket **)(sotag + 1) = canp->canp_socket; m_tag_prepend(m, sotag); @@ -240,10 +236,7 @@ can_output(struct mbuf *m, struct canpcb can_output_cnt++; return ifq_enqueue(ifp, m); } else - error = EMSGSIZE; -bad: - m_freem(m); - return (error); + return EMSGSIZE; } /* @@ -255,6 +248,9 @@ can_mbuf_tag_clean(struct mbuf *m) struct m_tag *sotag; sotag = m_tag_find(m, PACKET_TAG_SO, NULL); + if (sotag) + m_tag_unlink(m, sotag); + m_tag_delete_nonpersistent(m); if (sotag) m_tag_prepend(m, sotag); @@ -285,9 +281,9 @@ can_input(struct ifnet *ifp, struct mbuf } else { IF_ENQUEUE(inq, m); IFQ_UNLOCK(inq); - schednetisr(NETISR_CAN); ifp->if_ipackets++; ifp->if_ibytes += m->m_pkthdr.len; + schednetisr(NETISR_CAN); } } @@ -356,7 +352,7 @@ canintr(void) * we can't be sure we won't need * the original mbuf later so copy */ -mc = m_copym(m, 0, M_COPYALL, M_NOWAIT); +mc = m_copypacket(m, M_NOWAIT); if (mc == NULL) { /* deliver this mbuf and abort */ mc = m; @@ -574,11 +570,15 @@ can_send(struct socket *so, struct mbuf int s; if (control && control->m_len) { - return EINVAL; + m_freem(control); + error = EINVAL; + goto err; } if (m->m_len > sizeof(struct can_frame) || - m->m_len < offsetof(struct can_frame, can_dlc)) - return EINVAL; + m->m_len < offsetof(struct can_frame, can_dlc)) { + error = EINVAL; + goto err; + } /* we expect all data in the first mbuf */ KASSERT((m->m_flags & M_PKTHDR) != 0); @@ -586,20 +586,24 @@ can_send(struct socket *so, struct mbuf if (nam) { if ((so->so_state & SS_ISCONNECTED) != 0) { - return EISCONN; + error = EISCONN; + goto err; } s = splnet(); error = can_pcbbind(canp, (struct sockaddr_can *)nam, l); if (error) { splx(s); - return error; + goto err; } } else { if ((so->so_state & SS_ISCONNECTED) == 0) { - return EDESTADDRREQ; + error = EDESTADDRREQ; + goto err; } } error = can_output(m, canp); + if (error) + goto err; if (nam) { struct sockaddr_can lscan; memset(&lscan, 0, sizeof(lscan)); @@ -607,6 +611,10 @@ can_send(struct socket *so, struct mbuf lscan.can_len = sizeof(lscan); can_pcbbind(canp, &lscan, l); } + return 0; + +err: + m_freem(m); return error; }
CVS commit: [bouyer-socketcan] src/sys/netcan
Module Name:src Committed By: bouyer Date: Wed Apr 19 22:17:57 UTC 2017 Modified Files: src/sys/netcan [bouyer-socketcan]: if_canloop.c Log Message: Set rcvif before bpf_mtap To generate a diff of this commit: cvs rdiff -u -r1.1.2.4 -r1.1.2.5 src/sys/netcan/if_canloop.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/netcan/if_canloop.c diff -u src/sys/netcan/if_canloop.c:1.1.2.4 src/sys/netcan/if_canloop.c:1.1.2.5 --- src/sys/netcan/if_canloop.c:1.1.2.4 Sun Feb 5 17:37:10 2017 +++ src/sys/netcan/if_canloop.c Wed Apr 19 22:17:56 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: if_canloop.c,v 1.1.2.4 2017/02/05 17:37:10 bouyer Exp $ */ +/* $NetBSD: if_canloop.c,v 1.1.2.5 2017/04/19 22:17:56 bouyer Exp $ */ /*- * Copyright (c) 2017 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: if_canloop.c,v 1.1.2.4 2017/02/05 17:37:10 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_canloop.c,v 1.1.2.5 2017/04/19 22:17:56 bouyer Exp $"); #ifdef _KERNEL_OPT #include "opt_can.h" @@ -164,9 +164,9 @@ canloop_ifstart(struct ifnet *ifp) if ((m->m_flags & M_PKTHDR) == 0) panic("canloop_output: no header mbuf"); + m_set_rcvif(m, ifp); 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++; @@ -178,7 +178,6 @@ canloop_ifstart(struct ifnet *ifp) #else printf("%s: can't handle CAN packet\n", ifp->if_xname); m_freem(m); - error = EAFNOSUPPORT; #endif }
CVS commit: [bouyer-socketcan] src/sys/netcan
Module Name:src Committed By: bouyer Date: Wed Apr 19 17:52:38 UTC 2017 Modified Files: src/sys/netcan [bouyer-socketcan]: can.c Log Message: Call if_alloc_sadl() for the interface, so that getifaddrs() will find them. To generate a diff of this commit: cvs rdiff -u -r1.1.2.8 -r1.1.2.9 src/sys/netcan/can.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/netcan/can.c diff -u src/sys/netcan/can.c:1.1.2.8 src/sys/netcan/can.c:1.1.2.9 --- src/sys/netcan/can.c:1.1.2.8 Tue Apr 18 20:37:38 2017 +++ src/sys/netcan/can.c Wed Apr 19 17:52:37 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: can.c,v 1.1.2.8 2017/04/18 20:37:38 bouyer Exp $ */ +/* $NetBSD: can.c,v 1.1.2.9 2017/04/19 17:52:37 bouyer Exp $ */ /*- * Copyright (c) 2003, 2017 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.1.2.8 2017/04/18 20:37:38 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.1.2.9 2017/04/19 17:52:37 bouyer Exp $"); #include #include @@ -200,6 +200,7 @@ can_ifattach(struct ifnet *ifp) { ifp->if_dlt = DLT_CAN_SOCKETCAN; ifp->if_output = NULL; /* unused */ IFQ_SET_READY(&ifp->if_snd); + if_alloc_sadl(ifp); } void
CVS commit: [bouyer-socketcan] src/sys/netcan
Module Name:src Committed By: bouyer Date: Tue Apr 18 21:29:40 UTC 2017 Modified Files: src/sys/netcan [bouyer-socketcan]: can_var.h Log Message: include socketvar.h, so avoid a warning on struct sockopt * To generate a diff of this commit: cvs rdiff -u -r1.1.2.6 -r1.1.2.7 src/sys/netcan/can_var.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/netcan/can_var.h diff -u src/sys/netcan/can_var.h:1.1.2.6 src/sys/netcan/can_var.h:1.1.2.7 --- src/sys/netcan/can_var.h:1.1.2.6 Tue Apr 18 20:37:38 2017 +++ src/sys/netcan/can_var.h Tue Apr 18 21:29:40 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: can_var.h,v 1.1.2.6 2017/04/18 20:37:38 bouyer Exp $ */ +/* $NetBSD: can_var.h,v 1.1.2.7 2017/04/18 21:29:40 bouyer Exp $ */ /*- * Copyright (c) 2003, 2017 The NetBSD Foundation, Inc. @@ -41,6 +41,7 @@ struct can_ifreq { }; #ifdef _KERNEL +#include /* * common structure for CAN interface drivers. Should be at the start of
CVS commit: [bouyer-socketcan] src/sys/netcan
Module Name:src Committed By: bouyer Date: Tue Apr 18 20:48:07 UTC 2017 Modified Files: src/sys/netcan [bouyer-socketcan]: files.netcan Log Message: if_canloop.c is in netcan/ To generate a diff of this commit: cvs rdiff -u -r1.1.2.1 -r1.1.2.2 src/sys/netcan/files.netcan Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/netcan/files.netcan diff -u src/sys/netcan/files.netcan:1.1.2.1 src/sys/netcan/files.netcan:1.1.2.2 --- src/sys/netcan/files.netcan:1.1.2.1 Sun Jan 15 20:27:33 2017 +++ src/sys/netcan/files.netcan Tue Apr 18 20:48:07 2017 @@ -1,8 +1,8 @@ -# $NetBSD: files.netcan,v 1.1.2.1 2017/01/15 20:27:33 bouyer Exp $ +# $NetBSD: files.netcan,v 1.1.2.2 2017/04/18 20:48:07 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 +file netcan/if_canloop.c canloop
CVS commit: [bouyer-socketcan] src/sys/netcan
Module Name:src Committed By: bouyer Date: Tue Apr 18 20:37:38 UTC 2017 Modified Files: src/sys/netcan [bouyer-socketcan]: can.c can_var.h Log Message: Add can_ifinit_timings() helper function, which initialise timing parameters to known invalid values. To generate a diff of this commit: cvs rdiff -u -r1.1.2.7 -r1.1.2.8 src/sys/netcan/can.c cvs rdiff -u -r1.1.2.5 -r1.1.2.6 src/sys/netcan/can_var.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/netcan/can.c diff -u src/sys/netcan/can.c:1.1.2.7 src/sys/netcan/can.c:1.1.2.8 --- src/sys/netcan/can.c:1.1.2.7 Mon Apr 17 20:32:27 2017 +++ src/sys/netcan/can.c Tue Apr 18 20:37:38 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: can.c,v 1.1.2.7 2017/04/17 20:32:27 bouyer Exp $ */ +/* $NetBSD: can.c,v 1.1.2.8 2017/04/18 20:37:38 bouyer Exp $ */ /*- * Copyright (c) 2003, 2017 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.1.2.7 2017/04/17 20:32:27 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.1.2.8 2017/04/18 20:37:38 bouyer Exp $"); #include #include @@ -202,6 +202,13 @@ can_ifattach(struct ifnet *ifp) { IFQ_SET_READY(&ifp->if_snd); } +void +can_ifinit_timings(struct canif_softc *csc) +{ + /* uninitialized parameters is all-one */ + memset(&csc->csc_timings, 0xff, sizeof(struct can_link_timings)); +} + static int can_output(struct mbuf *m, struct canpcb *canp) { Index: src/sys/netcan/can_var.h diff -u src/sys/netcan/can_var.h:1.1.2.5 src/sys/netcan/can_var.h:1.1.2.6 --- src/sys/netcan/can_var.h:1.1.2.5 Mon Apr 17 20:32:27 2017 +++ src/sys/netcan/can_var.h Tue Apr 18 20:37:38 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: can_var.h,v 1.1.2.5 2017/04/17 20:32:27 bouyer Exp $ */ +/* $NetBSD: can_var.h,v 1.1.2.6 2017/04/18 20:37:38 bouyer Exp $ */ /*- * Copyright (c) 2003, 2017 The NetBSD Foundation, Inc. @@ -59,6 +59,7 @@ extern struct domain candomain; extern const struct pr_usrreqs can_usrreqs; void can_ifattach(struct ifnet *); +void can_ifinit_timings(struct canif_softc *); void can_mbuf_tag_clean(struct mbuf *); void can_input(struct ifnet *, struct mbuf *); void *can_ctlinput(int, struct sockaddr *, void *);
CVS commit: [bouyer-socketcan] src/sys/netcan
Module Name:src Committed By: bouyer Date: Tue Apr 18 20:36:27 UTC 2017 Modified Files: src/sys/netcan [bouyer-socketcan]: can_link.h Log Message: Remove clt_clock_freq from user-supplied timing informations, it is defined by the brp. To generate a diff of this commit: cvs rdiff -u -r1.1.2.1 -r1.1.2.2 src/sys/netcan/can_link.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/netcan/can_link.h diff -u src/sys/netcan/can_link.h:1.1.2.1 src/sys/netcan/can_link.h:1.1.2.2 --- src/sys/netcan/can_link.h:1.1.2.1 Mon Apr 17 20:32:27 2017 +++ src/sys/netcan/can_link.h Tue Apr 18 20:36:27 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: can_link.h,v 1.1.2.1 2017/04/17 20:32:27 bouyer Exp $ */ +/* $NetBSD: can_link.h,v 1.1.2.2 2017/04/18 20:36:27 bouyer Exp $ */ /*- * Copyright (c) 2017 The NetBSD Foundation, Inc. @@ -55,7 +55,6 @@ struct can_link_timecaps { /* get/set timing parameters */ struct can_link_timings { - uint32_t clt_clock_freq; /* prescaler input clock, in hz */ uint32_t clt_brp; /* prescaler value */ uint32_t clt_prop; /* Propagation segment in tq */ uint32_t clt_ps1; /* Phase segment 1 in tq */
CVS commit: [bouyer-socketcan] src/sys/netcan
Module Name:src Committed By: bouyer Date: Mon Apr 17 20:32:27 UTC 2017 Modified Files: src/sys/netcan [bouyer-socketcan]: Makefile can.c can.h can_var.h Added Files: src/sys/netcan [bouyer-socketcan]: can_link.h Log Message: Add infranstructure to configure timings from userland on a can interface. This uses the SIOCGDRVSPEC/SIOCSDRVSPEC ioctls. Compile-tested only. To generate a diff of this commit: cvs rdiff -u -r1.1.2.1 -r1.1.2.2 src/sys/netcan/Makefile cvs rdiff -u -r1.1.2.6 -r1.1.2.7 src/sys/netcan/can.c cvs rdiff -u -r1.1.2.3 -r1.1.2.4 src/sys/netcan/can.h cvs rdiff -u -r0 -r1.1.2.1 src/sys/netcan/can_link.h cvs rdiff -u -r1.1.2.4 -r1.1.2.5 src/sys/netcan/can_var.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/netcan/Makefile diff -u src/sys/netcan/Makefile:1.1.2.1 src/sys/netcan/Makefile:1.1.2.2 --- src/sys/netcan/Makefile:1.1.2.1 Sun Jan 15 20:27:33 2017 +++ src/sys/netcan/Makefile Mon Apr 17 20:32:27 2017 @@ -1,8 +1,8 @@ -# $NetBSD: Makefile,v 1.1.2.1 2017/01/15 20:27:33 bouyer Exp $ +# $NetBSD: Makefile,v 1.1.2.2 2017/04/17 20:32:27 bouyer Exp $ KDIR= /sys/netcan INCSDIR= /usr/include/netcan -INCS= can.h +INCS= can.h can_link.h .include Index: src/sys/netcan/can.c diff -u src/sys/netcan/can.c:1.1.2.6 src/sys/netcan/can.c:1.1.2.7 --- src/sys/netcan/can.c:1.1.2.6 Sun Feb 5 19:44:53 2017 +++ src/sys/netcan/can.c Mon Apr 17 20:32:27 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: can.c,v 1.1.2.6 2017/02/05 19:44:53 bouyer Exp $ */ +/* $NetBSD: can.c,v 1.1.2.7 2017/04/17 20:32:27 bouyer Exp $ */ /*- * Copyright (c) 2003, 2017 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.1.2.6 2017/02/05 19:44:53 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.1.2.7 2017/04/17 20:32:27 bouyer Exp $"); #include #include @@ -90,6 +90,77 @@ can_init(void) /* * Generic control operations (ioctl's). */ +static int +can_get_netlink(struct ifnet *ifp, struct ifdrv *ifd) +{ + struct canif_softc *csc = ifp->if_softc; + + if (ifp->if_dlt != DLT_CAN_SOCKETCAN || csc == NULL) + return EOPNOTSUPP; + + switch(ifd->ifd_cmd) { + case CANGLINKTIMECAP: + if (ifd->ifd_len != sizeof(struct can_link_timecaps)) + return EINVAL; + return copyout(&csc->csc_timecaps, ifd->ifd_data, ifd->ifd_len); + case CANGLINKTIMINGS: + if (ifd->ifd_len != sizeof(struct can_link_timings)) + return EINVAL; + return copyout(&csc->csc_timings, ifd->ifd_data, ifd->ifd_len); + case CANGLINKMODE: + if (ifd->ifd_len != sizeof(uint32_t)) + return EINVAL; + return copyout(&csc->csc_linkmodes, ifd->ifd_data, ifd->ifd_len); + } + return EOPNOTSUPP; +} + +static int +can_set_netlink(struct ifnet *ifp, struct ifdrv *ifd) +{ + struct canif_softc *csc = ifp->if_softc; + uint32_t mode; + int error; + + if (ifp->if_dlt != DLT_CAN_SOCKETCAN || csc == NULL) + return EOPNOTSUPP; + + error = kauth_authorize_network(curlwp->l_cred, + KAUTH_NETWORK_INTERFACE, + KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, + (void *)SIOCSDRVSPEC, NULL); + if (error != 0) + return error; + + if ((ifp->if_flags & IFF_UP) != 0) { + return EBUSY; + } + + switch(ifd->ifd_cmd) { + case CANSLINKTIMINGS: + if (ifd->ifd_len != sizeof(struct can_link_timings)) + return EINVAL; + return copyin(ifd->ifd_data, &csc->csc_timings, ifd->ifd_len); + + case CANSLINKMODE: + case CANCLINKMODE: + if (ifd->ifd_len != sizeof(uint32_t)) + return EINVAL; + error = copyout(ifd->ifd_data, &mode, ifd->ifd_len); + if (error) + return error; + if ((mode & csc->csc_timecaps.cltc_linkmode_caps) != mode) + return EINVAL; + /* XXX locking */ + if (ifd->ifd_cmd == CANSLINKMODE) + csc->csc_linkmodes |= mode; + else + csc->csc_linkmodes &= ~mode; + return 0; + } + return EOPNOTSUPP; +} + /* ARGSUSED */ static int can_control(struct socket *so, u_long cmd, void *data, struct ifnet *ifp) @@ -98,12 +169,16 @@ can_control(struct socket *so, u_long cm struct can_ifreq *cfr = (struct can_ifreq *)data; int error = 0; #endif - + if (ifp == NULL) + return (EOPNOTSUPP); switch (cmd) { - + case SIOCGDRVSPEC: + return can_get_netlink(ifp, (struct ifdrv *) data); + case SIOCSDRVSPEC: + return can_set_netlink(ifp, (struct ifdrv *) data); default: - if (ifp == 0 || ifp->if_ioctl == 0) + if (ifp->if_ioctl == 0) return (EOPNOTSUPP); return ((*ifp->if_ioctl)(ifp, cmd, data)); } Index: src/sys/netcan/can.h diff -u src/sys/netcan/can.h:1.1.2.3 src/sys/netcan/can.h:1.1.2.4 --- src/sys/netcan/can.h:1.1.2.3 Mon Jan 16 18:03:38 2017 +++ src/sys/netcan/can.h Mon Apr 17 20:32:27 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: can.h,v 1.1.2.3 2017/01/16 18:03:38 bouyer Exp $ */ +/* $NetBSD: can.h,v 1.1.2.4 2017/04/17 20:32:27 bouyer Exp $ */ /*- * Copyright (c) 2003, 2017 The NetBSD Foundation, Inc. @@ -118,12 +118,6 @@ struct can_filter { #define CAN_INV_FILTER 0x2000U
CVS commit: [bouyer-socketcan] src/sys/netcan
Module Name:src Committed By: bouyer Date: Sun Feb 5 19:44:53 UTC 2017 Modified Files: src/sys/netcan [bouyer-socketcan]: can.c can_pcb.c Log Message: more sanity checks on the mbuf we get. To generate a diff of this commit: cvs rdiff -u -r1.1.2.5 -r1.1.2.6 src/sys/netcan/can.c cvs rdiff -u -r1.1.2.2 -r1.1.2.3 src/sys/netcan/can_pcb.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/netcan/can.c diff -u src/sys/netcan/can.c:1.1.2.5 src/sys/netcan/can.c:1.1.2.6 --- src/sys/netcan/can.c:1.1.2.5 Sun Feb 5 17:37:10 2017 +++ src/sys/netcan/can.c Sun Feb 5 19:44:53 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: can.c,v 1.1.2.5 2017/02/05 17:37:10 bouyer Exp $ */ +/* $NetBSD: can.c,v 1.1.2.6 2017/02/05 19:44:53 bouyer Exp $ */ /*- * Copyright (c) 2003, 2017 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.1.2.5 2017/02/05 17:37:10 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.1.2.6 2017/02/05 19:44:53 bouyer Exp $"); #include #include @@ -493,6 +493,13 @@ can_send(struct socket *so, struct mbuf if (control && control->m_len) { return EINVAL; } + if (m->m_len > sizeof(struct can_frame) || + m->m_len < offsetof(struct can_frame, can_dlc)) + return EINVAL; + + /* we expect all data in the first mbuf */ + KASSERT((m->m_flags & M_PKTHDR) != 0); + KASSERT(m->m_len == m->m_pkthdr.len); if (nam) { if ((so->so_state & SS_ISCONNECTED) != 0) { Index: src/sys/netcan/can_pcb.c diff -u src/sys/netcan/can_pcb.c:1.1.2.2 src/sys/netcan/can_pcb.c:1.1.2.3 --- src/sys/netcan/can_pcb.c:1.1.2.2 Sun Feb 5 10:56:12 2017 +++ src/sys/netcan/can_pcb.c Sun Feb 5 19:44:53 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: can_pcb.c,v 1.1.2.2 2017/02/05 10:56:12 bouyer Exp $ */ +/* $NetBSD: can_pcb.c,v 1.1.2.3 2017/02/05 19:44:53 bouyer Exp $ */ /*- * Copyright (c) 2003, 2017 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: can_pcb.c,v 1.1.2.2 2017/02/05 10:56:12 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: can_pcb.c,v 1.1.2.3 2017/02/05 19:44:53 bouyer Exp $"); #include #include @@ -332,6 +332,9 @@ can_pcbfilter(struct canpcb *canp, struc struct can_frame *fmp; struct can_filter *fip; + KASSERT((m->m_flags & M_PKTHDR) != 0); + KASSERT(m->m_len == m->m_pkthdr.len); + fmp = mtod(m, struct can_frame *); for (i = 0; i < canp->canp_nfilters; i++) { fip = &canp->canp_filters[i];
CVS commit: [bouyer-socketcan] src/sys/netcan
Module Name:src Committed By: bouyer Date: Sun Feb 5 17:37:10 UTC 2017 Modified Files: src/sys/netcan [bouyer-socketcan]: can.c can_var.h if_canloop.c Log Message: Introduce can_ifattach(), for common setups of can interfaces. Convert output to a ifq and change canloop_output to canloop_ifstart To generate a diff of this commit: cvs rdiff -u -r1.1.2.4 -r1.1.2.5 src/sys/netcan/can.c cvs rdiff -u -r1.1.2.3 -r1.1.2.4 src/sys/netcan/can_var.h \ src/sys/netcan/if_canloop.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/netcan/can.c diff -u src/sys/netcan/can.c:1.1.2.4 src/sys/netcan/can.c:1.1.2.5 --- src/sys/netcan/can.c:1.1.2.4 Sun Feb 5 11:45:11 2017 +++ src/sys/netcan/can.c Sun Feb 5 17:37:10 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: can.c,v 1.1.2.4 2017/02/05 11:45:11 bouyer Exp $ */ +/* $NetBSD: can.c,v 1.1.2.5 2017/02/05 17:37:10 bouyer Exp $ */ /*- * Copyright (c) 2003, 2017 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.1.2.4 2017/02/05 11:45:11 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.1.2.5 2017/02/05 17:37:10 bouyer Exp $"); #include #include @@ -45,6 +45,7 @@ __KERNEL_RCSID(0, "$NetBSD: can.c,v 1.1. #include #include +#include #include #include @@ -115,6 +116,17 @@ can_purgeif(struct socket *so, struct if return 0; } +void +can_ifattach(struct ifnet *ifp) { + ifp->if_mtu = sizeof(struct can_frame); + ifp->if_type = IFT_OTHER; + ifp->if_hdrlen = 0; + ifp->if_addrlen = 0; + ifp->if_dlt = DLT_CAN_SOCKETCAN; + ifp->if_output = NULL; /* unused */ + IFQ_SET_READY(&ifp->if_snd); +} + static int can_output(struct mbuf *m, struct canpcb *canp) { @@ -143,8 +155,7 @@ can_output(struct mbuf *m, struct canpcb if (m->m_len <= ifp->if_mtu) { can_output_cnt++; - error = (*ifp->if_output)(ifp, m, NULL, 0); - return error; + return ifq_enqueue(ifp, m); } else error = EMSGSIZE; bad: Index: src/sys/netcan/can_var.h diff -u src/sys/netcan/can_var.h:1.1.2.3 src/sys/netcan/can_var.h:1.1.2.4 --- src/sys/netcan/can_var.h:1.1.2.3 Sun Feb 5 11:45:11 2017 +++ src/sys/netcan/can_var.h Sun Feb 5 17:37:10 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: can_var.h,v 1.1.2.3 2017/02/05 11:45:11 bouyer Exp $ */ +/* $NetBSD: can_var.h,v 1.1.2.4 2017/02/05 17:37:10 bouyer Exp $ */ /*- * Copyright (c) 2003, 2017 The NetBSD Foundation, Inc. @@ -45,6 +45,7 @@ extern struct domain candomain; extern const struct pr_usrreqs can_usrreqs; +void can_ifattach(struct ifnet *); void can_mbuf_tag_clean(struct mbuf *); void can_input(struct ifnet *, struct mbuf *); void *can_ctlinput(int, struct sockaddr *, void *); Index: src/sys/netcan/if_canloop.c diff -u src/sys/netcan/if_canloop.c:1.1.2.3 src/sys/netcan/if_canloop.c:1.1.2.4 --- src/sys/netcan/if_canloop.c:1.1.2.3 Sun Feb 5 11:45:11 2017 +++ src/sys/netcan/if_canloop.c Sun Feb 5 17:37:10 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: if_canloop.c,v 1.1.2.3 2017/02/05 11:45:11 bouyer Exp $ */ +/* $NetBSD: if_canloop.c,v 1.1.2.4 2017/02/05 17:37:10 bouyer Exp $ */ /*- * Copyright (c) 2017 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: if_canloop.c,v 1.1.2.3 2017/02/05 11:45:11 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_canloop.c,v 1.1.2.4 2017/02/05 17:37:10 bouyer Exp $"); #ifdef _KERNEL_OPT #include "opt_can.h" @@ -69,8 +69,7 @@ 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 void canloop_ifstart(struct ifnet *); static int canloop_count; @@ -113,19 +112,13 @@ canloop_clone_create(struct if_clone *if 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); + ifp->if_start = canloop_ifstart; if_attach(ifp); - if_alloc_sadl(ifp); - bpf_attach(ifp, DLT_CAN_SOCKETCAN, sizeof(u_int)); + can_ifattach(ifp); + bpf_attach(ifp, DLT_CAN_SOCKETCAN, 0); #ifdef MBUFTRACE ifp->if_mowner = malloc(sizeof(struct mowner), M_DEVBUF, M_WAITOK | M_ZERO); @@ -156,41 +149,42 @@ canloop_clone_destroy(struct ifnet *ifp) return (0); } -static int -canloop_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, -const struct rtentry *rt) +static void +canloop_ifstart(struct ifnet *ifp) { - int error = 0; size_t pktlen; - - MCLAIM(m, ifp->if_mowner); + struct mbuf *m; KERNEL_LOCK(1, NULL); - - if ((m->m_flags & M_PKT
CVS commit: [bouyer-socketcan] src/sys/netcan
Module Name:src Committed By: bouyer Date: Sun Feb 5 11:45:11 UTC 2017 Modified Files: src/sys/netcan [bouyer-socketcan]: can.c can_var.h if_canloop.c Log Message: Centralize mbuf tag cleanup, it will be used by real interface drivers too. To generate a diff of this commit: cvs rdiff -u -r1.1.2.3 -r1.1.2.4 src/sys/netcan/can.c cvs rdiff -u -r1.1.2.2 -r1.1.2.3 src/sys/netcan/can_var.h \ src/sys/netcan/if_canloop.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. Modified files: Index: src/sys/netcan/can.c diff -u src/sys/netcan/can.c:1.1.2.3 src/sys/netcan/can.c:1.1.2.4 --- src/sys/netcan/can.c:1.1.2.3 Sun Feb 5 10:56:12 2017 +++ src/sys/netcan/can.c Sun Feb 5 11:45:11 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: can.c,v 1.1.2.3 2017/02/05 10:56:12 bouyer Exp $ */ +/* $NetBSD: can.c,v 1.1.2.4 2017/02/05 11:45:11 bouyer Exp $ */ /*- * Copyright (c) 2003, 2017 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.1.2.3 2017/02/05 10:56:12 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.1.2.4 2017/02/05 11:45:11 bouyer Exp $"); #include #include @@ -153,6 +153,20 @@ bad: } /* + * cleanup mbuf tag, keeping the PACKET_TAG_SO tag + */ +void +can_mbuf_tag_clean(struct mbuf *m) +{ + struct m_tag *sotag; + + sotag = m_tag_find(m, PACKET_TAG_SO, NULL); + m_tag_delete_nonpersistent(m); + if (sotag) + m_tag_prepend(m, sotag); +} + +/* * Process a received CAN frame * the packet is in the mbuf chain m with * the CAN header. Index: src/sys/netcan/can_var.h diff -u src/sys/netcan/can_var.h:1.1.2.2 src/sys/netcan/can_var.h:1.1.2.3 --- src/sys/netcan/can_var.h:1.1.2.2 Mon Jan 16 18:03:38 2017 +++ src/sys/netcan/can_var.h Sun Feb 5 11:45:11 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: can_var.h,v 1.1.2.2 2017/01/16 18:03:38 bouyer Exp $ */ +/* $NetBSD: can_var.h,v 1.1.2.3 2017/02/05 11:45:11 bouyer Exp $ */ /*- * Copyright (c) 2003, 2017 The NetBSD Foundation, Inc. @@ -45,6 +45,7 @@ extern struct domain candomain; extern const struct pr_usrreqs can_usrreqs; +void can_mbuf_tag_clean(struct mbuf *); void can_input(struct ifnet *, struct mbuf *); void *can_ctlinput(int, struct sockaddr *, void *); int can_ctloutput(int, struct socket *, struct sockopt *); Index: src/sys/netcan/if_canloop.c diff -u src/sys/netcan/if_canloop.c:1.1.2.2 src/sys/netcan/if_canloop.c:1.1.2.3 --- src/sys/netcan/if_canloop.c:1.1.2.2 Mon Jan 16 18:03:38 2017 +++ src/sys/netcan/if_canloop.c Sun Feb 5 11:45:11 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: if_canloop.c,v 1.1.2.2 2017/01/16 18:03:38 bouyer Exp $ */ +/* $NetBSD: if_canloop.c,v 1.1.2.3 2017/02/05 11:45:11 bouyer Exp $ */ /*- * Copyright (c) 2017 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: if_canloop.c,v 1.1.2.2 2017/01/16 18:03:38 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_canloop.c,v 1.1.2.3 2017/02/05 11:45:11 bouyer Exp $"); #ifdef _KERNEL_OPT #include "opt_can.h" @@ -83,7 +83,7 @@ canloopattach(int n) /* * Nothing to do here, initialization is handled by the - * module initialization code in canloopnit() below). + * module initialization code in canloopinit() below). */ } @@ -162,7 +162,6 @@ canloop_output(struct ifnet *ifp, struct { int error = 0; size_t pktlen; - struct m_tag *sotag; MCLAIM(m, ifp->if_mowner); @@ -178,12 +177,8 @@ canloop_output(struct ifnet *ifp, struct ifp->if_opackets++; ifp->if_obytes += pktlen; - /* we have to preserve the socket tag */ - sotag = m_tag_find(m, PACKET_TAG_SO, NULL); - m_tag_delete_nonpersistent(m); - if (sotag) - m_tag_prepend(m, sotag); #ifdef CAN + can_mbuf_tag_clean(m); can_input(ifp, m); #else printf("%s: can't handle CAN packet\n", ifp->if_xname);
CVS commit: [bouyer-socketcan] src/sys/netcan
Module Name:src Committed By: bouyer Date: Mon Jan 16 18:03:38 UTC 2017 Modified Files: src/sys/netcan [bouyer-socketcan]: can.c can.h can_pcb.h can_proto.c can_var.h if_canloop.c Log Message: Use PACKET_TAG_SO to store the sender's struct socket pointer, and use it to implement socket options CAN_RAW_LOOPBACK and CAN_RAW_RECV_OWN_MSGS. To generate a diff of this commit: cvs rdiff -u -r1.1.2.1 -r1.1.2.2 src/sys/netcan/can.c \ src/sys/netcan/can_pcb.h src/sys/netcan/can_proto.c \ src/sys/netcan/can_var.h src/sys/netcan/if_canloop.c cvs rdiff -u -r1.1.2.2 -r1.1.2.3 src/sys/netcan/can.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/netcan/can.c diff -u src/sys/netcan/can.c:1.1.2.1 src/sys/netcan/can.c:1.1.2.2 --- src/sys/netcan/can.c:1.1.2.1 Sun Jan 15 20:27:33 2017 +++ src/sys/netcan/can.c Mon Jan 16 18:03:38 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: can.c,v 1.1.2.1 2017/01/15 20:27:33 bouyer Exp $ */ +/* $NetBSD: can.c,v 1.1.2.2 2017/01/16 18:03:38 bouyer Exp $ */ /*- * Copyright (c) 2003, 2017 The NetBSD Foundation, Inc. @@ -30,12 +30,13 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.1.2.1 2017/01/15 20:27:33 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.1.2.2 2017/01/16 18:03:38 bouyer Exp $"); #include #include #include #include +#include #include #include #include @@ -119,25 +120,35 @@ can_output(struct mbuf *m, struct canpcb { struct ifnet *ifp; int error = 0; + struct m_tag *sotag; - if (canp == 0) { + if (canp == NULL) { printf("can_output: no pcb\n"); error = EINVAL; - goto done; + return error; } ifp = canp->canp_ifp; if (ifp == 0) { error = EDESTADDRREQ; - goto done; + goto bad; + } + sotag = m_tag_get(PACKET_TAG_SO, sizeof(struct socket *), PR_NOWAIT); + if (sotag == NULL) { + ifp->if_oerrors++; + error = ENOMEM; + goto bad; } + *(struct socket **)(sotag + 1) = canp->canp_socket; + m_tag_prepend(m, sotag); + if (m->m_len <= ifp->if_mtu) { can_output_cnt++; error = (*ifp->if_output)(ifp, m, NULL, 0); - goto done; - } else error = EMSGSIZE; - + return error; + } else + error = EMSGSIZE; +bad: m_freem(m); -done: return (error); } @@ -180,6 +191,9 @@ canintr(void) struct sockaddr_can from; struct canpcb *canp; + struct m_tag *sotag; + struct socket *so; + struct canpcb *sender_canp; mutex_enter(softnet_lock); for (;;) { @@ -187,9 +201,22 @@ canintr(void) IF_DEQUEUE(&canintrq, m); IFQ_UNLOCK(&canintrq); - if (m == 0) /* no more queued packets */ + if (m == NULL) /* no more queued packets */ break; + sotag = m_tag_find(m, PACKET_TAG_SO, NULL); + if (sotag) { + so = *(struct socket **)(sotag + 1); + sender_canp = sotocanpcb(so); + m_tag_delete(m, sotag); + /* if the sender doesn't want loopback, don't do it */ + if (sender_canp->canp_flags & CANP_NO_LOOPBACK) { +m_freem(m); +continue; + } + } else { + sender_canp = NULL; + } memset(&from, 0, sizeof(struct sockaddr_can)); rcv_ifindex = m->m_pkthdr.rcvif_index; #if 0 @@ -201,10 +228,17 @@ canintr(void) TAILQ_FOREACH(canp, &cbtable.canpt_queue, canp_queue) { struct mbuf *mc; + + /* don't loop back to sockets on other interfaces */ if (canp->canp_ifp != NULL && canp->canp_ifp->if_index != rcv_ifindex) { continue; } + /* don't loop back to myself if I don't want it */ + if (canp == sender_canp && + (canp->canp_flags & CANP_RECEIVE_OWN) == 0) +continue; + if (TAILQ_NEXT(canp, canp_queue) != NULL) { /* * we can't be sure we won't need @@ -653,6 +687,97 @@ can_ctlinput(int cmd, struct sockaddr *s } #endif +static int +can_raw_getop(struct canpcb *canp, struct sockopt *sopt) +{ + int optval = 0; + int error; + + switch (sopt->sopt_name) { + case CAN_RAW_LOOPBACK: + optval = (canp->canp_flags & CANP_NO_LOOPBACK) ? 0 : 1; + error = sockopt_set(sopt, &optval, sizeof(optval)); + break; + case CAN_RAW_RECV_OWN_MSGS: + optval = (canp->canp_flags & CANP_RECEIVE_OWN) ? 1 : 0; + error = sockopt_set(sopt, &optval, sizeof(optval)); + break; + default: + error = ENOPROTOOPT; + break; + } + return error; +} + +static int +can_raw_setop(struct canpcb *canp, struct sockopt *sopt) +{ + int optval = 0; + int error; + + switch (sopt->sopt_name) { + case CAN_RAW_LOOPBACK: + error = sockopt_getint(sopt, &optval); + if (error == 0) { + if (optval) { +canp->canp_flags &= ~CANP_NO_LOOPBACK; + } else { +canp->canp_flags |= CANP_NO_LOOPBACK; + } + } + break; + case CAN_RAW_RECV_OWN_MSGS: + error = sockopt_getint(sopt, &optval); + if (error == 0) { + if (optval) { +canp->canp_flags |= CANP_RECEIVE_OWN; + } else { +canp->canp_flags &= ~CANP_RECEIVE_OWN; + } + } + break; + default: + error = ENOPROTOOPT; + break; + } + return error; +} + +/* + * Called by getsockopt and setsockopt. + * +
CVS commit: [bouyer-socketcan] src/sys/netcan
Module Name:src Committed By: bouyer Date: Sun Jan 15 21:01:34 UTC 2017 Modified Files: src/sys/netcan [bouyer-socketcan]: can.h Log Message: Align can_frame.data to 8 bytes, per SocketCAN spec. To generate a diff of this commit: cvs rdiff -u -r1.1.2.1 -r1.1.2.2 src/sys/netcan/can.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/netcan/can.h diff -u src/sys/netcan/can.h:1.1.2.1 src/sys/netcan/can.h:1.1.2.2 --- src/sys/netcan/can.h:1.1.2.1 Sun Jan 15 20:27:33 2017 +++ src/sys/netcan/can.h Sun Jan 15 21:01:34 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: can.h,v 1.1.2.1 2017/01/15 20:27:33 bouyer Exp $ */ +/* $NetBSD: can.h,v 1.1.2.2 2017/01/15 21:01:34 bouyer Exp $ */ /*- * Copyright (c) 2003, 2017 The NetBSD Foundation, Inc. @@ -68,7 +68,7 @@ struct can_frame { uint8_t __pad; uint8_t __res0; uint8_t __res1; - uint8_t data[CAN_MAX_DLEN]; + uint8_t data[CAN_MAX_DLEN] __aligned(8); }; #define CAN_MTU (sizeof(struct can_frame))