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;