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/71a029b67d4d
branches:  trunk
changeset: 820195:71a029b67d4d
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 b6456ff408fb -r 71a029b67d4d 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 b6456ff408fb -r 71a029b67d4d 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 b6456ff408fb -r 71a029b67d4d 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 b6456ff408fb -r 71a029b67d4d 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 b6456ff408fb -r 71a029b67d4d 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