Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src Add IPv6 support for NPF.



details:   https://anonhg.NetBSD.org/src/rev/5b225746b161
branches:  trunk
changeset: 770955:5b225746b161
user:      zoltan <zoltan%NetBSD.org@localhost>
date:      Fri Nov 04 01:00:27 2011 +0000

description:
Add IPv6 support for NPF.

diffstat:

 lib/libnpf/npf.c                 |   13 +-
 lib/libnpf/npf.h                 |    4 +-
 sys/net/npf/npf.h                |   89 ++++++++++++++++++-
 sys/net/npf/npf_alg_icmp.c       |   20 ++--
 sys/net/npf/npf_ctl.c            |   23 ++--
 sys/net/npf/npf_handler.c        |   49 ++++++++--
 sys/net/npf/npf_impl.h           |   20 ++--
 sys/net/npf/npf_inet.c           |  108 ++++++++++++++++++-----
 sys/net/npf/npf_instr.c          |   32 ++++---
 sys/net/npf/npf_nat.c            |    9 +-
 sys/net/npf/npf_ncode.h          |    5 +-
 sys/net/npf/npf_processor.c      |   26 ++++-
 sys/net/npf/npf_sendpkt.c        |   98 +++++++++++++++------
 sys/net/npf/npf_session.c        |    7 +-
 sys/net/npf/npf_state.c          |    9 +-
 sys/net/npf/npf_tableset.c       |   93 +++++++++++---------
 usr.sbin/npf/npfctl/npf_data.c   |  172 +++++++++++++++++++++++++-------------
 usr.sbin/npf/npfctl/npf_ncgen.c  |   46 ++++++++-
 usr.sbin/npf/npfctl/npf_parser.c |   40 ++++----
 usr.sbin/npf/npfctl/npfctl.c     |    9 +-
 usr.sbin/npf/npfctl/npfctl.h     |   15 ++-
 21 files changed, 604 insertions(+), 283 deletions(-)

diffs (truncated from 2059 to 300 lines):

diff -r af1a37d0fa6a -r 5b225746b161 lib/libnpf/npf.c
--- a/lib/libnpf/npf.c  Fri Nov 04 00:22:33 2011 +0000
+++ b/lib/libnpf/npf.c  Fri Nov 04 01:00:27 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: npf.c,v 1.2 2011/02/02 15:17:37 rmind Exp $    */
+/*     $NetBSD: npf.c,v 1.3 2011/11/04 01:00:28 zoltan Exp $   */
 
 /*-
  * Copyright (c) 2010-2011 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.2 2011/02/02 15:17:37 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.3 2011/11/04 01:00:28 zoltan Exp $");
 
 #include <sys/types.h>
 #include <netinet/in_systm.h>
@@ -429,18 +429,21 @@
 }
 
 int
-npf_table_add_entry(nl_table_t *tl, in_addr_t addr, in_addr_t mask)
+npf_table_add_entry(nl_table_t *tl, npf_addr_t *addr, npf_netmask_t mask)
 {
        prop_dictionary_t tldict = tl->ntl_dict, entdict;
        prop_array_t tblents;
+       prop_data_t addrdata;
 
        /* Create the table entry. */
        entdict = prop_dictionary_create();
        if (entdict) {
                return ENOMEM;
        }
-       prop_dictionary_set_uint32(entdict, "addr", addr);
-       prop_dictionary_set_uint32(entdict, "mask", mask);
+       addrdata = prop_data_create_data(addr, sizeof(npf_addr_t));
+       prop_dictionary_set(entdict, "addr", addrdata);
+       prop_dictionary_set_uint8(entdict, "mask", mask);
+       prop_object_release(addrdata);
 
        /* Insert the entry. */
        tblents = prop_dictionary_get(tldict, "entries");
diff -r af1a37d0fa6a -r 5b225746b161 lib/libnpf/npf.h
--- a/lib/libnpf/npf.h  Fri Nov 04 00:22:33 2011 +0000
+++ b/lib/libnpf/npf.h  Fri Nov 04 01:00:27 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: npf.h,v 1.1 2011/02/02 02:20:25 rmind Exp $    */
+/*     $NetBSD: npf.h,v 1.2 2011/11/04 01:00:28 zoltan Exp $   */
 
 /*-
  * Copyright (c) 2011 The NetBSD Foundation, Inc.
@@ -84,7 +84,7 @@
 int            npf_nat_insert(nl_config_t *, nl_nat_t *, pri_t);
 
 nl_table_t *   npf_table_create(int, int);
-int            npf_table_add_entry(nl_table_t *, in_addr_t, in_addr_t);
+int            npf_table_add_entry(nl_table_t *, npf_addr_t *, npf_netmask_t);
 bool           npf_table_exists_p(nl_config_t *, u_int);
 int            npf_table_insert(nl_config_t *, nl_table_t *);
 void           npf_table_destroy(nl_table_t *);
diff -r af1a37d0fa6a -r 5b225746b161 sys/net/npf/npf.h
--- a/sys/net/npf/npf.h Fri Nov 04 00:22:33 2011 +0000
+++ b/sys/net/npf/npf.h Fri Nov 04 01:00:27 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: npf.h,v 1.8 2011/02/02 23:01:34 rmind Exp $    */
+/*     $NetBSD: npf.h,v 1.9 2011/11/04 01:00:27 zoltan Exp $   */
 
 /*-
  * Copyright (c) 2009-2011 The NetBSD Foundation, Inc.
@@ -55,8 +55,11 @@
  * Public declarations and definitions.
  */
 
-/* Storage of address (both for IPv4 and IPv6). */
+/* Storage of address (both for IPv4 and IPv6) and netmask */
 typedef struct in6_addr                npf_addr_t;
+typedef uint_fast8_t           npf_netmask_t;
+
+#define        NPF_NO_NETMASK          (npf_netmask_t)~0
 
 #if defined(_KERNEL) || defined(_NPF_TESTING)
 
@@ -80,7 +83,7 @@
 
 #define        NPC_IP4         0x01    /* Indicates fetched IPv4 header. */
 #define        NPC_IP6         0x02    /* Indicates IPv6 header. */
-#define        NPC_IPFRAG      0x04    /* IPv4 fragment. */
+#define        NPC_IPFRAG      0x04    /* IPv4/IPv6 fragment. */
 #define        NPC_LAYER4      0x08    /* Layer 4 has been fetched. */
 
 #define        NPC_TCP         0x10    /* TCP header. */
@@ -98,6 +101,8 @@
        npf_addr_t *            npc_dstip;
        /* Size (v4 or v6) of IP addresses. */
        int                     npc_ipsz;
+       size_t                  npc_hlen;
+       int                     npc_next_proto;
        /* IPv4, IPv6. */
        union {
                struct ip       v4;
@@ -111,6 +116,71 @@
        } npc_l4;
 } npf_cache_t;
 
+/* Max length is 32 for IPv4 and 128 for IPv6 */
+static inline void
+npf_generate_mask(npf_addr_t *dst, const npf_netmask_t omask)
+{
+       uint_fast8_t length = omask;
+
+       KASSERT(length <= 128);
+       memset(dst, 0, sizeof(npf_addr_t));
+       for (int i = 0; i < 4; i++) {
+               if (length >= 32) {
+                       dst->s6_addr32[i] = htonl(0xffffffff);
+                       length -= 32;
+               } else {
+                       dst->s6_addr32[i] = htonl(0xffffffff << (32 - length));
+                       length = 0;
+               }  
+       }
+}
+
+static inline void
+npf_calculate_masked_addr(npf_addr_t *dst, const npf_addr_t *src, const npf_netmask_t omask)
+{
+       npf_addr_t mask;
+
+       npf_generate_mask(&mask, omask);
+       for (int i = 0; i < 4; i++) {
+               dst->s6_addr32[i] =
+                       src->s6_addr32[i] & mask.s6_addr32[i];
+       }
+}
+
+/*
+ * compare two addresses, either v4 or v6
+ * if the mask is NULL, ignore it
+ */
+static inline int
+npf_compare_cidr(const npf_addr_t *addr1, const npf_netmask_t mask1,
+                const npf_addr_t *addr2, const npf_netmask_t mask2)
+{
+       npf_addr_t realmask1, realmask2;
+
+       if (mask1 != NPF_NO_NETMASK) {
+               npf_generate_mask(&realmask1, mask1);
+       }
+       if (mask2 != NPF_NO_NETMASK) {
+               npf_generate_mask(&realmask2, mask2);
+       }
+       for (int i = 0; i < 4; i++) {
+               const uint32_t x = mask1 != NPF_NO_NETMASK ?
+                               addr1->s6_addr32[i] & realmask1.s6_addr32[i] : 
+                               addr1->s6_addr32[i];
+               const uint32_t y = mask2 != NPF_NO_NETMASK ?
+                               addr2->s6_addr32[i] & realmask2.s6_addr32[i] :
+                               addr2->s6_addr32[i];
+               if (x < y) {
+                       return -1;
+               }
+               if (x > y) {
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
 static inline bool
 npf_iscached(const npf_cache_t *npc, const int inf)
 {
@@ -121,10 +191,15 @@
 static inline int
 npf_cache_ipproto(const npf_cache_t *npc)
 {
-       const struct ip *ip = &npc->npc_ip.v4;
+       KASSERT(npf_iscached(npc, NPC_IP46));
+       return npc->npc_next_proto;
+}
 
+static inline int
+npf_cache_hlen(const npf_cache_t *npc, nbuf_t *nbuf)
+{
        KASSERT(npf_iscached(npc, NPC_IP46));
-       return ip->ip_p;
+       return npc->npc_hlen;
 }
 
 /* Network buffer interface. */
@@ -190,8 +265,8 @@
 typedef struct npf_ioctl_table {
        int                     nct_action;
        u_int                   nct_tid;
-       in_addr_t               nct_addr;
-       in_addr_t               nct_mask;
+       npf_addr_t              nct_addr;
+       npf_netmask_t           nct_mask;
        int                     _reserved;
 } npf_ioctl_table_t;
 
diff -r af1a37d0fa6a -r 5b225746b161 sys/net/npf/npf_alg_icmp.c
--- a/sys/net/npf/npf_alg_icmp.c        Fri Nov 04 00:22:33 2011 +0000
+++ b/sys/net/npf/npf_alg_icmp.c        Fri Nov 04 01:00:27 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: npf_alg_icmp.c,v 1.6 2011/01/18 20:33:45 rmind Exp $   */
+/*     $NetBSD: npf_alg_icmp.c,v 1.7 2011/11/04 01:00:27 zoltan Exp $  */
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_alg_icmp.c,v 1.6 2011/01/18 20:33:45 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_alg_icmp.c,v 1.7 2011/11/04 01:00:27 zoltan Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -119,7 +119,8 @@
        struct ip *ip = &npc->npc_ip.v4;
        in_port_t dport;
 
-       KASSERT(npf_iscached(npc, NPC_IP46 | NPC_LAYER4));
+       KASSERT(npf_iscached(npc, NPC_IP46));
+       KASSERT(npf_iscached(npc, NPC_LAYER4));
 
        /* Check for low TTL. */
        if (ip->ip_ttl > TR_MAX_TTL) {
@@ -247,10 +248,10 @@
        KASSERT(npf_iscached(npc, NPC_ICMP));
 
        /* Advance to ICMP header. */
-       struct ip *ip = &npc->npc_ip.v4;
        void *n_ptr = nbuf_dataptr(nbuf);
+       const size_t hlen = npf_cache_hlen(npc, nbuf);
 
-       if ((n_ptr = nbuf_advance(&nbuf, n_ptr, ip->ip_hl << 2)) == NULL) {
+       if ((n_ptr = nbuf_advance(&nbuf, n_ptr, hlen)) == NULL) {
                return false;
        }
 
@@ -297,7 +298,8 @@
                return false;
        }
        /* XXX: Restore inversion (inefficient). */
-       KASSERT(npf_iscached(&enpc, NPC_IP46 | NPC_LAYER4));
+       KASSERT(npf_iscached(&enpc, NPC_IP46));
+       KASSERT(npf_iscached(&enpc, NPC_LAYER4));
        npfa_srcdst_invert(&enpc);
 
        /*
@@ -306,7 +308,7 @@
         * embedded packet changes, while data is not rewritten in the cache.
         */
        const int proto = npf_cache_ipproto(&enpc);
-       const struct ip * const ip = &npc->npc_ip.v4, *eip = &enpc.npc_ip.v4;
+       const struct ip *eip = &enpc.npc_ip.v4;
        const struct icmp * const ic = &npc->npc_l4.icmp;
        uint16_t cksum = ic->icmp_cksum, ecksum = eip->ip_sum, l4cksum;
        npf_nat_t *nt = ntptr;
@@ -331,7 +333,7 @@
         * to the embedded IP header after ICMP header.
         */
        void *n_ptr = nbuf_dataptr(nbuf), *cnbuf = nbuf, *cnptr = n_ptr;
-       u_int offby = (ip->ip_hl << 2) + offsetof(struct icmp, icmp_ip);
+       u_int offby = npf_cache_hlen(npc, nbuf) + offsetof(struct icmp, icmp_ip);
 
        if ((n_ptr = nbuf_advance(&nbuf, n_ptr, offby)) == NULL) {
                return false;
@@ -365,7 +367,7 @@
        }
        cksum = npf_fixup16_cksum(cksum, ecksum, eip->ip_sum);
 
-       offby = (ip->ip_hl << 2) + offsetof(struct icmp, icmp_cksum);
+       offby = npf_cache_hlen(npc, nbuf) + offsetof(struct icmp, icmp_cksum);
        if (nbuf_advstore(&cnbuf, &cnptr, offby, sizeof(uint16_t), &cksum)) {
                return false;
        }
diff -r af1a37d0fa6a -r 5b225746b161 sys/net/npf/npf_ctl.c
--- a/sys/net/npf/npf_ctl.c     Fri Nov 04 00:22:33 2011 +0000
+++ b/sys/net/npf/npf_ctl.c     Fri Nov 04 01:00:27 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: npf_ctl.c,v 1.6 2011/02/02 02:20:25 rmind Exp $        */
+/*     $NetBSD: npf_ctl.c,v 1.7 2011/11/04 01:00:27 zoltan Exp $       */
 
 /*-
  * Copyright (c) 2009-2011 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_ctl.c,v 1.6 2011/02/02 02:20:25 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_ctl.c,v 1.7 2011/11/04 01:00:27 zoltan Exp $");
 
 #include <sys/param.h>
 #include <sys/conf.h>
@@ -120,12 +120,13 @@
                }



Home | Main Index | Thread Index | Old Index