Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/bouyer-socketcan]: src Implement CAN_RAW_FILTER socket option, and add t...
details: https://anonhg.NetBSD.org/src/rev/46c81238cd24
branches: bouyer-socketcan
changeset: 820821:46c81238cd24
user: bouyer <bouyer%NetBSD.org@localhost>
date: Sun Feb 05 10:56:12 2017 +0000
description:
Implement CAN_RAW_FILTER socket option, and add tests for it.
diffstat:
sys/netcan/can.c | 28 +-
sys/netcan/can_pcb.c | 66 +++++-
sys/netcan/can_pcb.h | 9 +-
tests/net/can/Makefile | 9 +-
tests/net/can/t_canfilter.c | 537 ++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 633 insertions(+), 16 deletions(-)
diffs (truncated from 807 to 300 lines):
diff -r d6d3dfd21081 -r 46c81238cd24 sys/netcan/can.c
--- a/sys/netcan/can.c Sat Feb 04 22:26:16 2017 +0000
+++ b/sys/netcan/can.c Sun Feb 05 10:56:12 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: can.c,v 1.1.2.2 2017/01/16 18:03:38 bouyer Exp $ */
+/* $NetBSD: can.c,v 1.1.2.3 2017/02/05 10:56:12 bouyer Exp $ */
/*-
* Copyright (c) 2003, 2017 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.1.2.2 2017/01/16 18:03:38 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.1.2.3 2017/02/05 10:56:12 bouyer Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -204,6 +204,9 @@
if (m == NULL) /* no more queued packets */
break;
+#if 0
+ m_claim(m, &can_rx_mowner);
+#endif
sotag = m_tag_find(m, PACKET_TAG_SO, NULL);
if (sotag) {
so = *(struct socket **)(sotag + 1);
@@ -219,9 +222,6 @@
}
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;
@@ -239,6 +239,10 @@
(canp->canp_flags & CANP_RECEIVE_OWN) == 0)
continue;
+ /* skip if the accept filter doen't match this pkt */
+ if (!can_pcbfilter(canp, m))
+ continue;
+
if (TAILQ_NEXT(canp, canp_queue) != NULL) {
/*
* we can't be sure we won't need
@@ -274,7 +278,6 @@
static int
can_attach(struct socket *so, int proto)
{
- /*struct canpcb *canp;*/
int error;
KASSERT(sotocanpcb(so) == NULL);
@@ -298,7 +301,6 @@
if (error) {
return error;
}
- /*canp = sotocanpcb(so);*/
KASSERT(solocked(so));
return error;
@@ -702,6 +704,10 @@
optval = (canp->canp_flags & CANP_RECEIVE_OWN) ? 1 : 0;
error = sockopt_set(sopt, &optval, sizeof(optval));
break;
+ case CAN_RAW_FILTER:
+ error = sockopt_set(sopt, canp->canp_filters,
+ sizeof(struct can_filter) * canp->canp_nfilters);
+ break;
default:
error = ENOPROTOOPT;
break;
@@ -736,6 +742,14 @@
}
}
break;
+ case CAN_RAW_FILTER:
+ {
+ int nfilters = sopt->sopt_size / sizeof(struct can_filter);
+ if (sopt->sopt_size % sizeof(struct can_filter) != 0)
+ return EINVAL;
+ error = can_pcbsetfilter(canp, sopt->sopt_data, nfilters);
+ break;
+ }
default:
error = ENOPROTOOPT;
break;
diff -r d6d3dfd21081 -r 46c81238cd24 sys/netcan/can_pcb.c
--- a/sys/netcan/can_pcb.c Sat Feb 04 22:26:16 2017 +0000
+++ b/sys/netcan/can_pcb.c Sun Feb 05 10:56:12 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: can_pcb.c,v 1.1.2.1 2017/01/15 20:27:33 bouyer Exp $ */
+/* $NetBSD: can_pcb.c,v 1.1.2.2 2017/02/05 10:56:12 bouyer Exp $ */
/*-
* Copyright (c) 2003, 2017 The NetBSD Foundation, Inc.
@@ -30,11 +30,12 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: can_pcb.c,v 1.1.2.1 2017/01/15 20:27:33 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: can_pcb.c,v 1.1.2.2 2017/02/05 10:56:12 bouyer Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
+#include <sys/kmem.h>
#include <sys/mbuf.h>
#include <sys/protosw.h>
#include <sys/socket.h>
@@ -84,16 +85,27 @@
{
struct canpcbtable *table = v;
struct canpcb *canp;
+ struct can_filter *can_init_filter;
int s;
+ can_init_filter = kmem_alloc(sizeof(struct can_filter), KM_NOSLEEP);
+ if (can_init_filter == NULL)
+ return (ENOBUFS);
+ can_init_filter->can_id = 0;
+ can_init_filter->can_mask = 0; /* accept all by default */
+
s = splnet();
canp = pool_get(&canpcb_pool, PR_NOWAIT);
splx(s);
- if (canp == NULL)
+ if (canp == NULL) {
+ kmem_free(can_init_filter, sizeof(struct can_filter));
return (ENOBUFS);
+ }
memset(canp, 0, sizeof(*canp));
canp->canp_table = table;
canp->canp_socket = so;
+ canp->canp_filters = can_init_filter;
+ canp->canp_nfilters = 1;
so->so_pcb = canp;
s = splnet();
@@ -169,6 +181,7 @@
TAILQ_REMOVE(&canp->canp_table->canpt_queue, canp, canp_queue);
splx(s);
sofree(so); /* sofree drops the lock */
+ can_pcbsetfilter(canp, NULL, 0);
pool_put(&canpcb_pool, canp);
mutex_enter(softnet_lock);
}
@@ -183,6 +196,32 @@
scan->can_ifindex = canp->canp_ifp->if_index;
}
+int
+can_pcbsetfilter(struct canpcb *canp, struct can_filter *fp, int nfilters)
+{
+
+ struct can_filter *newf;
+
+ if (nfilters > 0) {
+ newf =
+ kmem_alloc(sizeof(struct can_filter) * nfilters, KM_SLEEP);
+ if (newf == NULL)
+ return ENOMEM;
+ memcpy(newf, fp, sizeof(struct can_filter) * nfilters);
+ } else {
+ newf = NULL;
+ }
+ if (canp->canp_filters != NULL) {
+ kmem_free(canp->canp_filters,
+ sizeof(struct can_filter) * canp->canp_nfilters);
+ }
+ canp->canp_filters = newf;
+ canp->canp_nfilters = nfilters;
+ return 0;
+}
+
+
+
#if 0
/*
* Pass some notification to all connections of a protocol
@@ -281,3 +320,24 @@
canp->canp_state = state;
}
+
+/*
+ * check mbuf against socket accept filter.
+ * returns true if mbuf is accepted, false otherwise
+ */
+bool
+can_pcbfilter(struct canpcb *canp, struct mbuf *m)
+{
+ int i;
+ struct can_frame *fmp;
+ struct can_filter *fip;
+
+ fmp = mtod(m, struct can_frame *);
+ for (i = 0; i < canp->canp_nfilters; i++) {
+ fip = &canp->canp_filters[i];
+ if ((fmp->can_id & fip->can_mask) == fip->can_id)
+ return true;
+ }
+ /* no match */
+ return false;
+}
diff -r d6d3dfd21081 -r 46c81238cd24 sys/netcan/can_pcb.h
--- a/sys/netcan/can_pcb.h Sat Feb 04 22:26:16 2017 +0000
+++ b/sys/netcan/can_pcb.h Sun Feb 05 10:56:12 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: can_pcb.h,v 1.1.2.2 2017/01/16 18:03:38 bouyer Exp $ */
+/* $NetBSD: can_pcb.h,v 1.1.2.3 2017/02/05 10:56:12 bouyer Exp $ */
/*-
* Copyright (c) 2003, 2017 The NetBSD Foundation, Inc.
@@ -52,13 +52,14 @@
int canp_flags;
struct socket *canp_socket; /* back pointer to socket */
struct ifnet *canp_ifp; /* interface this socket is bound to */
+
struct canpcbtable *canp_table;
+ struct can_filter *canp_filters; /* filter array */
+ int canp_nfilters; /* size of canp_filters */
};
LIST_HEAD(canpcbhead, canpcb);
-#define canp_faddr canp_dst.scan_addr
-
TAILQ_HEAD(canpcbqueue, canpcb);
struct canpcbtable {
@@ -97,6 +98,8 @@
void can_pcbpurgeif(struct canpcbtable *, struct ifnet *);
void can_pcbstate(struct canpcb *, int);
void can_setsockaddr(struct canpcb *, struct sockaddr_can *);
+int can_pcbsetfilter(struct canpcb *, struct can_filter *, int);
+bool can_pcbfilter(struct canpcb *, struct mbuf *);
#endif
#endif /* _NETCAN_CAN_PCB_H_ */
diff -r d6d3dfd21081 -r 46c81238cd24 tests/net/can/Makefile
--- a/tests/net/can/Makefile Sat Feb 04 22:26:16 2017 +0000
+++ b/tests/net/can/Makefile Sun Feb 05 10:56:12 2017 +0000
@@ -1,12 +1,15 @@
-# $NetBSD: Makefile,v 1.1.2.2 2017/02/04 22:26:16 bouyer Exp $
+# $NetBSD: Makefile,v 1.1.2.3 2017/02/05 10:56:12 bouyer Exp $
#
.include <bsd.own.mk>
TESTSDIR= ${TESTSBASE}/net/can
-TESTS_C= t_can
-SRCS.t_can= t_can.c h_canutils.c
+TESTS_C= t_can t_canfilter
+
+SRCS.t_can= t_can.c h_canutils.c
+
+SRCS.t_canfilter= t_canfilter.c h_canutils.c
# XXX we don't use INET here, but we need rumpnet_netinet anyway:
# common code in if.c is compiled with -DINET and will dereference ip_pktq,
diff -r d6d3dfd21081 -r 46c81238cd24 tests/net/can/t_canfilter.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/net/can/t_canfilter.c Sun Feb 05 10:56:12 2017 +0000
@@ -0,0 +1,537 @@
+/* $NetBSD: t_canfilter.c,v 1.1.2.1 2017/02/05 10:56:12 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.
Home |
Main Index |
Thread Index |
Old Index