Add nbuf_advfetch() and simplify some code slightly. trunk
authorrmind <rmind@NetBSD.org>
Sat, 25 Sep 2010 00:25:31 +0000
branchtrunk
changeset 193729 79f05219c352
parent 193728 6be94c86ebe8
child 193730 e049417a3a93
Add nbuf_advfetch() and simplify some code slightly.
sys/net/npf/npf.h
sys/net/npf/npf_alg_icmp.c
sys/net/npf/npf_inet.c
sys/net/npf/npf_instr.c
sys/net/npf/npf_mbuf.c
sys/net/npf/npf_sendpkt.c
--- a/sys/net/npf/npf.h	Fri Sep 24 22:51:50 2010 +0000
+++ b/sys/net/npf/npf.h	Sat Sep 25 00:25:31 2010 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf.h,v 1.2 2010/09/16 04:53:27 rmind Exp $	*/
+/*	$NetBSD: npf.h,v 1.3 2010/09/25 00:25:31 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2010 The NetBSD Foundation, Inc.
@@ -110,6 +110,7 @@
 /* Network buffer interface. */
 void *		nbuf_dataptr(void *);
 void *		nbuf_advance(nbuf_t **, void *, u_int);
+int		nbuf_advfetch(nbuf_t **, void **, u_int, size_t, void *);
 int		nbuf_fetch_datum(nbuf_t *, void *, size_t, void *);
 int		nbuf_store_datum(nbuf_t *, void *, size_t, void *);
 
--- a/sys/net/npf/npf_alg_icmp.c	Fri Sep 24 22:51:50 2010 +0000
+++ b/sys/net/npf/npf_alg_icmp.c	Sat Sep 25 00:25:31 2010 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_alg_icmp.c,v 1.2 2010/09/16 04:53:27 rmind Exp $	*/
+/*	$NetBSD: npf_alg_icmp.c,v 1.3 2010/09/25 00:25:31 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
 
 #ifdef _KERNEL
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_alg_icmp.c,v 1.2 2010/09/16 04:53:27 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_alg_icmp.c,v 1.3 2010/09/25 00:25:31 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -119,6 +119,8 @@
 {
 	const int proto = npc->npc_proto;
 	void *n_ptr = nbuf_dataptr(nbuf);
+	u_int offby;
+	uint8_t ttl;
 
 	/* Handle TCP/UDP traceroute - check for port range. */
 	if (proto != IPPROTO_TCP && proto != IPPROTO_UDP) {
@@ -131,17 +133,11 @@
 	}
 
 	/* Check for low TTL. */
-	const u_int offby = offsetof(struct ip, ip_ttl);
-	if ((n_ptr = nbuf_advance(&nbuf, n_ptr, offby)) == NULL) {
+	offby = offsetof(struct ip, ip_ttl);
+	if (nbuf_advfetch(&nbuf, &n_ptr, offby, sizeof(uint8_t), &ttl))
 		return false;
-	}
-	uint8_t ttl;
-	if (nbuf_fetch_datum(nbuf, n_ptr, sizeof(uint8_t), &ttl)) {
+	if (ttl > TR_MAX_TTL)
 		return false;
-	}
-	if (ttl > TR_MAX_TTL) {
-		return false;
-	}
 
 	/* Associate ALG with translation entry. */
 	npf_nat_t *nt = ntptr;
@@ -194,10 +190,7 @@
 	case ICMP_IREQREPLY:
 		/* Should contain ICMP query ID. */
 		offby = offsetof(struct icmp, icmp_id);
-		if ((n_ptr = nbuf_advance(&nbuf, n_ptr, offby)) == NULL) {
-			return false;
-		}
-		if (nbuf_fetch_datum(nbuf, n_ptr, sizeof(uint16_t),
+		if (nbuf_advfetch(&nbuf, &n_ptr, offby, sizeof(uint16_t),
 		    &npc->npc_icmp_id)) {
 			return false;
 		}
@@ -286,10 +279,7 @@
 
 	/* Advance to ICMP checksum and fetch it. */
 	offby = npc->npc_hlen + offsetof(struct icmp, icmp_cksum);
-	if ((n_ptr = nbuf_advance(&nbuf, n_ptr, offby)) == NULL) {
-		return false;
-	}
-	if (nbuf_fetch_datum(nbuf, n_ptr, sizeof(uint16_t), &cksum)) {
+	if (nbuf_advfetch(&nbuf, &n_ptr, offby, sizeof(uint16_t), &cksum)) {
 		return false;
 	}
 
--- a/sys/net/npf/npf_inet.c	Fri Sep 24 22:51:50 2010 +0000
+++ b/sys/net/npf/npf_inet.c	Sat Sep 25 00:25:31 2010 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_inet.c,v 1.2 2010/09/16 04:53:27 rmind Exp $	*/
+/*	$NetBSD: npf_inet.c,v 1.3 2010/09/25 00:25:31 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2010 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
 
 #ifdef _KERNEL
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_inet.c,v 1.2 2010/09/16 04:53:27 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_inet.c,v 1.3 2010/09/25 00:25:31 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -106,28 +106,23 @@
 	hlen = (val8 & 0xf) << 2;
 	if (hlen < sizeof(struct ip))
 		return false;
-	offby = offsetof(struct ip, ip_off);
-	if ((n_ptr = nbuf_advance(&nbuf, n_ptr, offby)) == NULL)
-		return false;
 
 	/* IPv4 header: check fragment offset. */
-	error = nbuf_fetch_datum(nbuf, n_ptr, sizeof(uint8_t), &val8);
+	offby = offsetof(struct ip, ip_off);
+	error = nbuf_advfetch(&nbuf, &n_ptr, offby, sizeof(uint8_t), &val8);
 	if (error || (val8 & ~htons(IP_DF | IP_RF)))
 		return false;
 
 	/* Get and match protocol. */
 	KASSERT(offsetof(struct ip, ip_p) > offby);
 	offby = offsetof(struct ip, ip_p) - offby;
-	if ((n_ptr = nbuf_advance(&nbuf, n_ptr, offby)) == NULL)
-		return false;
-	if (nbuf_fetch_datum(nbuf, n_ptr, sizeof(uint8_t), &val8))
+	if (nbuf_advfetch(&nbuf, &n_ptr, offby, sizeof(uint8_t), &val8))
 		return false;
 
 	/* IP checksum. */
 	offby = offsetof(struct ip, ip_sum) - offsetof(struct ip, ip_p);
-	if ((n_ptr = nbuf_advance(&nbuf, n_ptr, offby)) == NULL)
-		return false;
-	if (nbuf_fetch_datum(nbuf, n_ptr, sizeof(uint16_t), &npc->npc_ipsum))
+	if (nbuf_advfetch(&nbuf, &n_ptr, offby,
+	    sizeof(uint16_t), &npc->npc_ipsum))
 		return false;
 
 	/* Cache: IPv4, protocol, header length. */
@@ -145,20 +140,17 @@
 bool
 npf_fetch_ip4addrs(npf_cache_t *npc, nbuf_t *nbuf, void *n_ptr)
 {
+	in_addr_t *src = &npc->npc_srcip, *dst = &npc->npc_dstip;
 	u_int offby;
 
 	/* Source address. */
 	offby = offsetof(struct ip, ip_src);
-	if ((n_ptr = nbuf_advance(&nbuf, n_ptr, offby)) == NULL)
-		return false;
-	if (nbuf_fetch_datum(nbuf, n_ptr, sizeof(in_addr_t), &npc->npc_srcip))
+	if (nbuf_advfetch(&nbuf, &n_ptr, offby, sizeof(in_addr_t), src))
 		return false;
 
 	/* Destination address. */
 	offby = offsetof(struct ip, ip_dst) - offby;
-	if ((n_ptr = nbuf_advance(&nbuf, n_ptr, offby)) == NULL)
-		return false;
-	if (nbuf_fetch_datum(nbuf, n_ptr, sizeof(in_addr_t), &npc->npc_dstip))
+	if (nbuf_advfetch(&nbuf, &n_ptr, offby, sizeof(in_addr_t), dst))
 		return false;
 
 	/* Both addresses are cached. */
@@ -216,28 +208,23 @@
 bool
 npf_fetch_icmp(npf_cache_t *npc, nbuf_t *nbuf, void *n_ptr)
 {
+	uint8_t *type = &npc->npc_icmp_type, *code = &npc->npc_icmp_code;
 	u_int offby;
-	uint8_t type;
 
 	KASSERT(npf_iscached(npc, NPC_IP46));
 
 	/* ICMP type. */
 	offby = npc->npc_hlen;
 	CTASSERT(offsetof(struct icmp, icmp_type) == 0);
-	if ((n_ptr = nbuf_advance(&nbuf, n_ptr, offby)) == NULL)
-		return false;
-	if (nbuf_fetch_datum(nbuf, n_ptr, sizeof(uint8_t), &type))
+	if (nbuf_advfetch(&nbuf, &n_ptr, offby, sizeof(uint8_t), type))
 		return false;
 
 	/* ICMP code. */
 	offby = offsetof(struct icmp, icmp_code);
-	if ((n_ptr = nbuf_advance(&nbuf, n_ptr, offby)) == NULL)
-		return false;
-	if (nbuf_fetch_datum(nbuf, n_ptr, sizeof(uint8_t), &npc->npc_icmp_code))
+	if (nbuf_advfetch(&nbuf, &n_ptr, offby, sizeof(uint8_t), code))
 		return false;
 
 	/* Mark as cached. */
-	npc->npc_icmp_type = type;
 	npc->npc_info |= NPC_ICMP;
 	return true;
 }
@@ -248,14 +235,12 @@
 bool
 npf_fetch_tcpfl(npf_cache_t *npc, nbuf_t *nbuf, void *n_ptr)
 {
-	u_int offby;
+	const u_int offby = npc->npc_hlen + offsetof(struct tcphdr, th_flags);
+	uint8_t *tcpfl = &npc->npc_tcp_flags;
 
-	/* Get TCP flags. */
-	offby = npc->npc_hlen + offsetof(struct tcphdr, th_flags);
-	if ((n_ptr = nbuf_advance(&nbuf, n_ptr, offby)) == NULL)
+	if (nbuf_advfetch(&nbuf, &n_ptr, offby, sizeof(uint8_t), tcpfl)) {
 		return false;
-	if (nbuf_fetch_datum(nbuf, n_ptr, sizeof(uint8_t), &npc->npc_tcp_flags))
-		return false;
+	}
 	return true;
 }
 
@@ -346,10 +331,9 @@
 		return false;
 
 	/* Advance and update TCP/UDP checksum. */
-	if ((n_ptr = nbuf_advance(&nbuf, n_ptr, toff)) == NULL)
+	if (nbuf_advfetch(&nbuf, &n_ptr, toff, sizeof(uint16_t), &cksum)) {
 		return false;
-	if (nbuf_fetch_datum(nbuf, n_ptr, sizeof(uint16_t), &cksum))
-		return false;
+	}
 	if (__predict_true(cksum || proto == IPPROTO_TCP)) {
 		cksum = npf_fixup32_cksum(cksum, oaddr, naddr);
 		cksum = npf_fixup16_cksum(cksum, oport, port);
--- a/sys/net/npf/npf_instr.c	Fri Sep 24 22:51:50 2010 +0000
+++ b/sys/net/npf/npf_instr.c	Sat Sep 25 00:25:31 2010 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_instr.c,v 1.2 2010/09/16 04:53:27 rmind Exp $	*/
+/*	$NetBSD: npf_instr.c,v 1.3 2010/09/25 00:25:31 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2010 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
 
 #ifdef _KERNEL
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_instr.c,v 1.2 2010/09/16 04:53:27 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_instr.c,v 1.3 2010/09/25 00:25:31 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -71,10 +71,7 @@
 	/* Ethernet header: check EtherType. */
 	offby = offsetof(struct ether_header, ether_type);
 again:
-	if ((n_ptr = nbuf_advance(&nbuf, n_ptr, offby)) == NULL) {
-		return -1;
-	}
-	if (nbuf_fetch_datum(nbuf, n_ptr, sizeof(uint16_t), &val16)) {
+	if (nbuf_advfetch(&nbuf, &n_ptr, offby, sizeof(uint16_t), &val16)) {
 		return -1;
 	}
 	val16 = ntohs(val16);
--- a/sys/net/npf/npf_mbuf.c	Fri Sep 24 22:51:50 2010 +0000
+++ b/sys/net/npf/npf_mbuf.c	Sat Sep 25 00:25:31 2010 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_mbuf.c,v 1.2 2010/09/16 04:53:27 rmind Exp $	*/
+/*	$NetBSD: npf_mbuf.c,v 1.3 2010/09/25 00:25:31 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2009-2010 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@
 
 #ifdef _KERNEL
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_mbuf.c,v 1.2 2010/09/16 04:53:27 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_mbuf.c,v 1.3 2010/09/25 00:25:31 rmind Exp $");
 #endif
 
 #include <sys/param.h>
@@ -188,6 +188,21 @@
 }
 
 /*
+ * nbuf_advfetch: advance and fetch the datum.
+ * WARNING: Values of nbuf and n_ptr are undefined on error.
+ */
+int
+nbuf_advfetch(nbuf_t **nbuf, void **n_ptr, u_int n, size_t len, void *buf)
+{
+
+	*n_ptr = nbuf_advance(nbuf, *n_ptr, n);
+	if (__predict_false(*n_ptr == NULL)) {
+		return EINVAL;
+	}
+	return nbuf_fetch_datum(*nbuf, n_ptr, len, buf);
+}
+
+/*
  * nbuf_add_tag: add a tag to specified network buffer.
  *
  * => Returns 0 on success, or errno on failure.
--- a/sys/net/npf/npf_sendpkt.c	Fri Sep 24 22:51:50 2010 +0000
+++ b/sys/net/npf/npf_sendpkt.c	Sat Sep 25 00:25:31 2010 +0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_sendpkt.c,v 1.1 2010/09/16 04:53:27 rmind Exp $	*/
+/*	$NetBSD: npf_sendpkt.c,v 1.2 2010/09/25 00:25:31 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
 
 #ifdef _KERNEL
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_sendpkt.c,v 1.1 2010/09/16 04:53:27 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_sendpkt.c,v 1.2 2010/09/25 00:25:31 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -70,23 +70,17 @@
 
 	/* Fetch total length of IP. */
 	offby = offsetof(struct ip, ip_len);
-	if ((n_ptr = nbuf_advance(&nbuf, n_ptr, offby)) == NULL)
-		return false;
-	if (nbuf_fetch_datum(nbuf, n_ptr, sizeof(uint16_t), &iplen))
+	if (nbuf_advfetch(&nbuf, &n_ptr, offby, sizeof(uint16_t), &iplen))
 		return false;
 
 	/* Fetch SEQ and ACK numbers. */
 	offby = (npc->npc_hlen - offby) + offsetof(struct tcphdr, th_seq);
-	if ((n_ptr = nbuf_advance(&nbuf, n_ptr, offby)) == NULL)
-		return false;
-	if (nbuf_fetch_datum(nbuf, n_ptr, sizeof(seqack), seqack))
+	if (nbuf_advfetch(&nbuf, &n_ptr, offby, sizeof(seqack), seqack))
 		return false;
 
 	/* Fetch TCP data offset (header length) value. */
 	offby = sizeof(seqack);
-	if ((n_ptr = nbuf_advance(&nbuf, n_ptr, offby)) == NULL)
-		return false;
-	if (nbuf_fetch_datum(nbuf, n_ptr, sizeof(uint8_t), &toff))
+	if (nbuf_advfetch(&nbuf, &n_ptr, offby, sizeof(uint8_t), &toff))
 		return false;
 	toff >>= 4;