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