Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys ip_randomid: make mechanism MP-safe and more modular.
details: https://anonhg.NetBSD.org/src/rev/96a9e1a02fa4
branches: trunk
changeset: 758449:96a9e1a02fa4
user: rmind <rmind%NetBSD.org@localhost>
date: Fri Nov 05 01:35:57 2010 +0000
description:
ip_randomid: make mechanism MP-safe and more modular.
OK matt@
diffstat:
sys/dist/pf/net/if_pfsync.c | 6 +-
sys/dist/pf/net/pf_norm.c | 6 +-
sys/netinet/in_var.h | 37 ++++++++++--------
sys/netinet/ip_id.c | 89 ++++++++++++++++++++++++++------------------
sys/netinet/ip_input.c | 7 ++-
5 files changed, 83 insertions(+), 62 deletions(-)
diffs (truncated from 324 to 300 lines):
diff -r 86c51909efd0 -r 96a9e1a02fa4 sys/dist/pf/net/if_pfsync.c
--- a/sys/dist/pf/net/if_pfsync.c Fri Nov 05 01:34:51 2010 +0000
+++ b/sys/dist/pf/net/if_pfsync.c Fri Nov 05 01:35:57 2010 +0000
@@ -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;
diff -r 86c51909efd0 -r 96a9e1a02fa4 sys/dist/pf/net/pf_norm.c
--- a/sys/dist/pf/net/pf_norm.c Fri Nov 05 01:34:51 2010 +0000
+++ b/sys/dist/pf/net/pf_norm.c Fri Nov 05 01:35:57 2010 +0000
@@ -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)
diff -r 86c51909efd0 -r 96a9e1a02fa4 sys/netinet/in_var.h
--- a/sys/netinet/in_var.h Fri Nov 05 01:34:51 2010 +0000
+++ b/sys/netinet/in_var.h Fri Nov 05 01:35:57 2010 +0000
@@ -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);
+
+
+struct ipid_state;
+typedef struct ipid_state ipid_state_t;
-extern uint16_t ip_id;
-static __inline uint16_t ip_newid(const struct in_ifaddr *);
+ipid_state_t * ip_id_init(void);
+void ip_id_fini(ipid_state_t *);
+uint16_t ip_randomid(ipid_state_t *, uint16_t);
-uint16_t ip_randomid(uint16_t);
-extern int ip_do_randomid;
+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>
diff -r 86c51909efd0 -r 96a9e1a02fa4 sys/netinet/ip_id.c
--- a/sys/netinet/ip_id.c Fri Nov 05 01:34:51 2010 +0000
+++ b/sys/netinet/ip_id.c Fri Nov 05 01:35:57 2010 +0000
@@ -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 = 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);
- 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;
/*
* 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);
}
diff -r 86c51909efd0 -r 96a9e1a02fa4 sys/netinet/ip_input.c
--- a/sys/netinet/ip_input.c Fri Nov 05 01:34:51 2010 +0000
+++ b/sys/netinet/ip_input.c Fri Nov 05 01:35:57 2010 +0000
@@ -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 @@
*/
Home |
Main Index |
Thread Index |
Old Index