Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys NPF: implement dynamic handling of interface addresses (...
details: https://anonhg.NetBSD.org/src/rev/c74f51b083fe
branches: trunk
changeset: 350053:c74f51b083fe
user: rmind <rmind%NetBSD.org@localhost>
date: Mon Jan 02 21:49:51 2017 +0000
description:
NPF: implement dynamic handling of interface addresses (the kernel part).
diffstat:
sys/modules/npf/Makefile | 4 +-
sys/net/npf/files.npf | 6 +-
sys/net/npf/npf_ctl.c | 11 +-
sys/net/npf/npf_ifaddr.c | 179 +++++++++++++++++++++++++++++++++++++++++++++
sys/net/npf/npf_impl.h | 8 +-
sys/net/npf/npf_os.c | 43 +++++++++-
sys/net/npf/npf_tableset.c | 28 ++++++-
sys/net/npf/npf_worker.c | 9 +-
8 files changed, 263 insertions(+), 25 deletions(-)
diffs (truncated from 501 to 300 lines):
diff -r a27e9c0fbb47 -r c74f51b083fe sys/modules/npf/Makefile
--- a/sys/modules/npf/Makefile Mon Jan 02 21:46:59 2017 +0000
+++ b/sys/modules/npf/Makefile Mon Jan 02 21:49:51 2017 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.20 2016/12/28 13:50:55 christos Exp $
+# $NetBSD: Makefile,v 1.21 2017/01/02 21:49:51 rmind Exp $
#
# Public Domain.
#
@@ -13,7 +13,7 @@
SRCS+= npf_bpf.c npf_if.c npf_inet.c npf_mbuf.c npf_nat.c
SRCS+= npf_ruleset.c npf_conn.c npf_conndb.c npf_rproc.c
SRCS+= npf_state.c npf_state_tcp.c npf_tableset.c
-SRCS+= lpm.c npf_sendpkt.c npf_worker.c npf_os.c
+SRCS+= lpm.c npf_sendpkt.c npf_worker.c npf_ifaddr.c npf_os.c
CPPFLAGS+= -DINET6
diff -r a27e9c0fbb47 -r c74f51b083fe sys/net/npf/files.npf
--- a/sys/net/npf/files.npf Mon Jan 02 21:46:59 2017 +0000
+++ b/sys/net/npf/files.npf Mon Jan 02 21:49:51 2017 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files.npf,v 1.19 2016/12/26 23:05:06 christos Exp $
+# $NetBSD: files.npf,v 1.20 2017/01/02 21:49:51 rmind Exp $
#
# Public Domain.
#
@@ -11,7 +11,6 @@
# Core
file net/npf/npf.c npf
-file net/npf/npf_os.c npf
file net/npf/npf_conf.c npf
file net/npf/npf_ctl.c npf
file net/npf/npf_handler.c npf
@@ -31,6 +30,9 @@
file net/npf/npf_sendpkt.c npf
file net/npf/npf_worker.c npf
+file net/npf/npf_os.c npf
+file net/npf/npf_ifaddr.c npf
+
# LPM
file net/npf/lpm.c npf
diff -r a27e9c0fbb47 -r c74f51b083fe sys/net/npf/npf_ctl.c
--- a/sys/net/npf/npf_ctl.c Mon Jan 02 21:46:59 2017 +0000
+++ b/sys/net/npf/npf_ctl.c Mon Jan 02 21:49:51 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_ctl.c,v 1.45 2016/12/26 23:05:06 christos Exp $ */
+/* $NetBSD: npf_ctl.c,v 1.46 2017/01/02 21:49:51 rmind Exp $ */
/*-
* Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@
#ifdef _KERNEL
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_ctl.c,v 1.45 2016/12/26 23:05:06 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_ctl.c,v 1.46 2017/01/02 21:49:51 rmind Exp $");
#include <sys/param.h>
#include <sys/conf.h>
@@ -108,7 +108,7 @@
}
static int __noinline
-npf_mk_tables(npf_tableset_t *tblset, prop_array_t tables,
+npf_mk_tables(npf_t *npf, npf_tableset_t *tblset, prop_array_t tables,
prop_dictionary_t errdict)
{
prop_object_iterator_t it;
@@ -160,9 +160,6 @@
error = EINVAL;
break;
}
- if (type == NPF_TABLE_HASH) {
- size = 1024; /* XXX */
- }
/* Create and insert the table. */
t = npf_table_create(name, (u_int)tid, type, blob, size);
@@ -558,7 +555,7 @@
goto fail;
}
tblset = npf_tableset_create(nitems);
- error = npf_mk_tables(tblset, tables, errdict);
+ error = npf_mk_tables(npf, tblset, tables, errdict);
if (error) {
goto fail;
}
diff -r a27e9c0fbb47 -r c74f51b083fe sys/net/npf/npf_ifaddr.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/net/npf/npf_ifaddr.c Mon Jan 02 21:49:51 2017 +0000
@@ -0,0 +1,179 @@
+/* $NetBSD: npf_ifaddr.c,v 1.1 2017/01/02 21:49:51 rmind Exp $ */
+
+/*-
+ * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Mindaugas Rasiukevicius.
+ *
+ * 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.
+ */
+
+/*
+ * NPF network interface handling module.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: npf_ifaddr.c,v 1.1 2017/01/02 21:49:51 rmind Exp $");
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/kmem.h>
+
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet6/in6_var.h>
+
+#include "npf_impl.h"
+
+void
+npf_ifaddr_init(npf_t *npf)
+{
+ ifnet_t *ifp;
+
+ KERNEL_LOCK(1, NULL);
+ IFNET_LOCK();
+ IFNET_WRITER_FOREACH(ifp) {
+ npf_ifaddr_sync(npf, ifp);
+ }
+ IFNET_UNLOCK();
+ KERNEL_UNLOCK_ONE(NULL);
+}
+
+static npf_table_t *
+lookup_ifnet_table(npf_t *npf, ifnet_t *ifp)
+{
+ const npf_ifops_t *ifops = npf->ifops;
+ char tname[NPF_TABLE_MAXNAMELEN];
+ npf_tableset_t *ts;
+ const char *ifname;
+ npf_table_t *t;
+ u_int tid;
+
+ /* Get the interface name and prefix it. */
+ ifname = ifops->getname(ifp);
+ snprintf(tname, sizeof(tname), ".ifnet-%s", ifname);
+
+ KERNEL_LOCK(1, NULL);
+ npf_config_enter(npf);
+ ts = npf_config_tableset(npf);
+
+ /*
+ * Check whether this interface is of any interest to us.
+ */
+ t = npf_tableset_getbyname(ts, tname);
+ if (!t) {
+ goto out;
+ }
+ tid = npf_table_getid(t);
+
+ /* Create a new NPF table for the interface. */
+ t = npf_table_create(tname, tid, NPF_TABLE_HASH, NULL, 16);
+ if (!t) {
+ goto out;
+ }
+ return t;
+out:
+ npf_config_exit(npf);
+ KERNEL_UNLOCK_ONE(NULL);
+ return NULL;
+}
+
+static void
+replace_ifnet_table(npf_t *npf, npf_table_t *newt)
+{
+ npf_tableset_t *ts = npf_config_tableset(npf);
+ npf_table_t *oldt;
+
+ KERNEL_UNLOCK_ONE(NULL);
+
+ /*
+ * Finally, swap the tables and issue a sync barrier.
+ */
+ oldt = npf_tableset_swap(ts, newt);
+ npf_config_sync(npf);
+ npf_config_exit(npf);
+
+ /* At this point, it is safe to destroy the old table. */
+ npf_table_destroy(oldt);
+}
+
+void
+npf_ifaddr_sync(npf_t *npf, ifnet_t *ifp)
+{
+ npf_table_t *t;
+ struct ifaddr *ifa;
+
+ /*
+ * First, check whether this interface is of any interest to us.
+ *
+ * => Acquires npf-config-lock and kernel-lock on success.
+ */
+ t = lookup_ifnet_table(npf, ifp);
+ if (!t)
+ return;
+
+ /*
+ * Populate the table with the interface addresses.
+ * Note: currently, this list is protected by the kernel-lock.
+ */
+ IFADDR_FOREACH(ifa, ifp) {
+ struct sockaddr *sa = ifa->ifa_addr;
+ const void *p = NULL;
+ int alen = 0;
+
+ if (sa->sa_family == AF_INET) {
+ const struct sockaddr_in *sin4 = satosin(sa);
+ alen = sizeof(struct in_addr);
+ p = &sin4->sin_addr;
+ }
+ if (sa->sa_family == AF_INET6) {
+ const struct sockaddr_in6 *sin6 = satosin6(sa);
+ alen = sizeof(struct in6_addr);
+ p = &sin6->sin6_addr;
+ }
+ if (alen) {
+ npf_addr_t addr;
+ memcpy(&addr, p, alen);
+ npf_table_insert(t, alen, &addr, NPF_NO_NETMASK);
+ }
+ }
+
+ /* Publish the new table. */
+ replace_ifnet_table(npf, t);
+}
+
+void
+npf_ifaddr_flush(npf_t *npf, ifnet_t *ifp)
+{
+ npf_table_t *t;
+
+ /*
+ * Flush: just load an empty table.
+ */
+ t = lookup_ifnet_table(npf, ifp);
+ if (!t) {
+ return;
+ }
+ replace_ifnet_table(npf, t);
+}
diff -r a27e9c0fbb47 -r c74f51b083fe sys/net/npf/npf_impl.h
--- a/sys/net/npf/npf_impl.h Mon Jan 02 21:46:59 2017 +0000
+++ b/sys/net/npf/npf_impl.h Mon Jan 02 21:49:51 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_impl.h,v 1.65 2016/12/28 21:55:04 christos Exp $ */
+/* $NetBSD: npf_impl.h,v 1.66 2017/01/02 21:49:51 rmind Exp $ */
/*-
* Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
@@ -247,6 +247,10 @@
u_int npf_ifmap_getid(npf_t *, const ifnet_t *);
const char * npf_ifmap_getname(npf_t *, const u_int);
+void npf_ifaddr_init(npf_t *);
+void npf_ifaddr_sync(npf_t *, ifnet_t *);
+void npf_ifaddr_flush(npf_t *, ifnet_t *);
+
/* Packet filter hooks. */
int npf_pfil_register(bool);
void npf_pfil_unregister(bool);
@@ -297,12 +301,14 @@
int npf_tableset_insert(npf_tableset_t *, npf_table_t *);
npf_table_t * npf_tableset_getbyname(npf_tableset_t *, const char *);
npf_table_t * npf_tableset_getbyid(npf_tableset_t *, u_int);
+npf_table_t * npf_tableset_swap(npf_tableset_t *, npf_table_t *);
void npf_tableset_reload(npf_t *, npf_tableset_t *, npf_tableset_t *);
Home |
Main Index |
Thread Index |
Old Index