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