Module Name:    src
Committed By:   rmind
Date:           Fri Nov  5 01:35:58 UTC 2010

Modified Files:
        src/sys/dist/pf/net: if_pfsync.c pf_norm.c
        src/sys/netinet: in_var.h ip_id.c ip_input.c

Log Message:
ip_randomid: make mechanism MP-safe and more modular.

OK matt@


To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 src/sys/dist/pf/net/if_pfsync.c
cvs rdiff -u -r1.22 -r1.23 src/sys/dist/pf/net/pf_norm.c
cvs rdiff -u -r1.64 -r1.65 src/sys/netinet/in_var.h
cvs rdiff -u -r1.13 -r1.14 src/sys/netinet/ip_id.c
cvs rdiff -u -r1.290 -r1.291 src/sys/netinet/ip_input.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dist/pf/net/if_pfsync.c
diff -u src/sys/dist/pf/net/if_pfsync.c:1.6 src/sys/dist/pf/net/if_pfsync.c:1.7
--- src/sys/dist/pf/net/if_pfsync.c:1.6	Mon Apr  5 07:22:22 2010
+++ src/sys/dist/pf/net/if_pfsync.c	Fri Nov  5 01:35:58 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_pfsync.c,v 1.6 2010/04/05 07:22:22 joerg Exp $	*/
+/*	$NetBSD: if_pfsync.c,v 1.7 2010/11/05 01:35:58 rmind Exp $	*/
 /*	$OpenBSD: if_pfsync.c,v 1.83 2007/06/26 14:44:12 mcbride Exp $	*/
 
 /*
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_pfsync.c,v 1.6 2010/04/05 07:22:22 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_pfsync.c,v 1.7 2010/11/05 01:35:58 rmind Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -1599,7 +1599,7 @@
 		ip->ip_hl = sizeof(*ip) >> 2;
 		ip->ip_tos = IPTOS_LOWDELAY;
 		ip->ip_len = htons(m->m_pkthdr.len);
-		ip->ip_id = htons(ip_randomid(0));
+		ip->ip_id = htons(ip_randomid(ip_ids, 0));
 		ip->ip_off = htons(IP_DF);
 		ip->ip_ttl = PFSYNC_DFLTTL;
 		ip->ip_p = IPPROTO_PFSYNC;

Index: src/sys/dist/pf/net/pf_norm.c
diff -u src/sys/dist/pf/net/pf_norm.c:1.22 src/sys/dist/pf/net/pf_norm.c:1.23
--- src/sys/dist/pf/net/pf_norm.c:1.22	Mon Apr 12 13:57:38 2010
+++ src/sys/dist/pf/net/pf_norm.c	Fri Nov  5 01:35:58 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: pf_norm.c,v 1.22 2010/04/12 13:57:38 ahoka Exp $	*/
+/*	$NetBSD: pf_norm.c,v 1.23 2010/11/05 01:35:58 rmind Exp $	*/
 /*	$OpenBSD: pf_norm.c,v 1.109 2007/05/28 17:16:39 henning Exp $ */
 
 /*
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pf_norm.c,v 1.22 2010/04/12 13:57:38 ahoka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pf_norm.c,v 1.23 2010/11/05 01:35:58 rmind Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -1046,7 +1046,7 @@
 	if (r->rule_flag & PFRULE_RANDOMID) {
 		u_int16_t ip_id = h->ip_id;
 
-		h->ip_id = ip_randomid(0);
+		h->ip_id = ip_randomid(ip_ids, 0);
 		h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_id, h->ip_id, 0);
 	}
 	if ((r->rule_flag & (PFRULE_FRAGCROP|PFRULE_FRAGDROP)) == 0)

Index: src/sys/netinet/in_var.h
diff -u src/sys/netinet/in_var.h:1.64 src/sys/netinet/in_var.h:1.65
--- src/sys/netinet/in_var.h:1.64	Mon Jul 19 14:09:44 2010
+++ src/sys/netinet/in_var.h	Fri Nov  5 01:35:57 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: in_var.h,v 1.64 2010/07/19 14:09:44 rmind Exp $	*/
+/*	$NetBSD: in_var.h,v 1.65 2010/11/05 01:35:57 rmind Exp $	*/
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -302,44 +302,47 @@
 void	in_purgeif(struct ifnet *);
 void	ip_input(struct mbuf *);
 int	ipflow_fastforward(struct mbuf *);
-void	ip_initid(void);
 
-extern uint16_t	ip_id;
-static __inline uint16_t ip_newid(const struct in_ifaddr *);
 
-uint16_t ip_randomid(uint16_t);
-extern int ip_do_randomid;
+struct ipid_state;
+typedef struct ipid_state ipid_state_t;
+
+ipid_state_t *	ip_id_init(void);
+void		ip_id_fini(ipid_state_t *);
+uint16_t	ip_randomid(ipid_state_t *, uint16_t);
+
+extern ipid_state_t *	ip_ids;
+extern uint16_t		ip_id;
+extern int		ip_do_randomid;
 
 /*
- * ip_newid_range: "allocate" num contiguous ip_ids.
+ * ip_newid_range: "allocate" num contiguous IP IDs.
  *
- * => return the first id.
+ * => Return the first ID.
  */
-
 static __inline uint16_t
-ip_newid_range(const struct in_ifaddr *ia, unsigned int num)
+ip_newid_range(const struct in_ifaddr *ia, u_int num)
 {
 	uint16_t id;
 
 	if (ip_do_randomid) {
 		/* XXX ignore num */
-		return ip_randomid(ia ? ia->ia_idsalt : 0);
+		return ip_randomid(ip_ids, ia ? ia->ia_idsalt : 0);
 	}
 
-	/*
-	 * never allow an ip_id of 0. (detect wrap)
-	 */
-	if ((uint16_t)(ip_id + num) < ip_id)
+	/* Never allow an IP ID of 0 (detect wrap). */
+	if ((uint16_t)(ip_id + num) < ip_id) {
 		ip_id = 1;
+	}
 	id = htons(ip_id);
 	ip_id += num;
-
 	return id;
 }
 
 static __inline uint16_t
 ip_newid(const struct in_ifaddr *ia)
 {
+
 	return ip_newid_range(ia, 1);
 }
 
@@ -347,7 +350,7 @@
 int	sysctl_inpcblist(SYSCTLFN_PROTO);
 #endif
 
-#endif
+#endif	/* !_KERNEL */
 
 /* INET6 stuff */
 #include <netinet6/in6_var.h>

Index: src/sys/netinet/ip_id.c
diff -u src/sys/netinet/ip_id.c:1.13 src/sys/netinet/ip_id.c:1.14
--- src/sys/netinet/ip_id.c:1.13	Thu Nov  4 22:00:51 2010
+++ src/sys/netinet/ip_id.c	Fri Nov  5 01:35:57 2010
@@ -1,5 +1,4 @@
-/*	$NetBSD: ip_id.c,v 1.13 2010/11/04 22:00:51 matt Exp $	*/
-/*	$OpenBSD: ip_id.c,v 1.6 2002/03/15 18:19:52 millert Exp $	*/
+/*	$NetBSD: ip_id.c,v 1.14 2010/11/05 01:35:57 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -31,24 +30,26 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_id.c,v 1.13 2010/11/04 22:00:51 matt Exp $");
-
-#include "opt_inet.h"
+__KERNEL_RCSID(0, "$NetBSD: ip_id.c,v 1.14 2010/11/05 01:35:57 rmind Exp $");
 
 #include <sys/param.h>
-#include <lib/libkern/libkern.h>
+#include <sys/kmem.h>
+#include <sys/mutex.h>
 
 #include <net/if.h>
 #include <netinet/in.h>
 #include <netinet/in_var.h>
 
+#include <lib/libkern/libkern.h>
+
 #define	IPID_MAXID	65535
 #define	IPID_NUMIDS	32768
 
-static struct ipid_state {
-	uint16_t ids_start_slot;
-	uint16_t ids_slots[IPID_MAXID];
-} idstate;
+struct ipid_state {
+	kmutex_t	ids_lock;
+	uint16_t	ids_start_slot;
+	uint16_t	ids_slots[IPID_MAXID];
+};
 
 static inline uint32_t
 ipid_random(void)
@@ -64,34 +65,46 @@
  * This function is called from id_randomid() when needed, an
  * application does not have to worry about it.
  */
-void
-ip_initid(void)
+ipid_state_t *
+ip_id_init(void)
 {
+	ipid_state_t *ids;
 	size_t i;
 
-	idstate.ids_start_slot = ipid_random();
-	for (i = 0; i < __arraycount(idstate.ids_slots); i++)
-		idstate.ids_slots[i] = i;
+	ids = kmem_alloc(sizeof(ipid_state_t), KM_SLEEP);
+	mutex_init(&ids->ids_lock, MUTEX_DEFAULT, IPL_SOFTNET);
+
+	ids->ids_start_slot = ipid_random();
+	for (i = 0; i < __arraycount(ids->ids_slots); i++) {
+		ids->ids_slots[i] = i;
+	}
 
 	/*
 	 * Shuffle the array.
 	 */
-	for (i = __arraycount(idstate.ids_slots); --i > 0;) {
+	for (i = __arraycount(ids->ids_slots); --i > 0;) {
 		size_t k = ipid_random() % (i + 1);
-		uint16_t t = idstate.ids_slots[i];
-		idstate.ids_slots[i] = idstate.ids_slots[k];
-		idstate.ids_slots[k] = t;
+		uint16_t t = ids->ids_slots[i];
+		ids->ids_slots[i] = ids->ids_slots[k];
+		ids->ids_slots[k] = t;
 	}
+	return ids;
+}
+
+void
+ip_id_fini(ipid_state_t *ids)
+{
+
+	mutex_destroy(&ids->ids_lock);
+	kmem_free(ids, sizeof(ipid_state_t));
 }
 
 uint16_t
-ip_randomid(uint16_t salt)
+ip_randomid(ipid_state_t *ids, uint16_t salt)
 {
 	uint32_t r, k, id;
 
-	/*
-	 * We need a random number 
-	 */
+	/* A random number. */
 	r = ipid_random();
 
 	/*
@@ -100,7 +113,7 @@
 	 * then advance the start of the window by 1.  The next time that 
 	 * swapped-out entry can be used is at least 32768 iterations in the
 	 * future.
- 	 *
+	 *
 	 * The easiest way to visual this is to imagine a card deck with 52
 	 * cards.  First thing we do is split that into two sets, each with
 	 * half of the cards; call them deck A and deck B.  Pick a card
@@ -108,23 +121,27 @@
 	 * bottom of deck B.  Then take the top card from deck B and add it
 	 * to deck A.  Pick another card randomly from deck A and ...
 	 */
-	k = (r & (IPID_NUMIDS-1)) + idstate.ids_start_slot;
-	if (k >= IPID_MAXID)
+	mutex_enter(&ids->ids_lock);
+	k = (r & (IPID_NUMIDS - 1)) + ids->ids_start_slot;
+	if (k >= IPID_MAXID) {
 		k -= IPID_MAXID;
-
-	id = idstate.ids_slots[k];
-	if (k != idstate.ids_start_slot) {
-		idstate.ids_slots[k] = idstate.ids_slots[idstate.ids_start_slot];
-		idstate.ids_slots[idstate.ids_start_slot] = id;
 	}
-	if (++idstate.ids_start_slot == IPID_MAXID)
-		idstate.ids_start_slot = 0;
+	id = ids->ids_slots[k];
+	if (k != ids->ids_start_slot) {
+		ids->ids_slots[k] = ids->ids_slots[ids->ids_start_slot];
+		ids->ids_slots[ids->ids_start_slot] = id;
+	}
+	if (++ids->ids_start_slot == IPID_MAXID) {
+		ids->ids_start_slot = 0;
+	}
+	mutex_exit(&ids->ids_lock);
+
 	/*
 	 * Add an optional salt to the id to further obscure it.
 	 */
 	id += salt;
-	if (id >= IPID_MAXID)
+	if (id >= IPID_MAXID) {
 		id -= IPID_MAXID;
-
-	return (uint16_t) htons(id + 1);
+	}
+	return (uint16_t)htons(id + 1);
 }

Index: src/sys/netinet/ip_input.c
diff -u src/sys/netinet/ip_input.c:1.290 src/sys/netinet/ip_input.c:1.291
--- src/sys/netinet/ip_input.c:1.290	Fri Nov  5 00:21:51 2010
+++ src/sys/netinet/ip_input.c	Fri Nov  5 01:35:57 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_input.c,v 1.290 2010/11/05 00:21:51 rmind Exp $	*/
+/*	$NetBSD: ip_input.c,v 1.291 2010/11/05 01:35:57 rmind Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -91,7 +91,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.290 2010/11/05 00:21:51 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.291 2010/11/05 01:35:57 rmind Exp $");
 
 #include "opt_inet.h"
 #include "opt_compat_netbsd.h"
@@ -231,6 +231,7 @@
 struct	in_multihashhead *in_multihashtbl;
 struct	ifqueue ipintrq;
 
+ipid_state_t *		ip_ids;
 uint16_t ip_id;
 
 percpu_t *ipstat_percpu;
@@ -315,7 +316,7 @@
 
 	ip_reass_init();
 
-	ip_initid();
+	ip_ids = ip_id_init();
 	ip_id = time_second & 0xfffff;
 
 	ipintrq.ifq_maxlen = ipqmaxlen;

Reply via email to