Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-9]: src/sys/netipsec Pull up following revision(s) (requested by ...



details:   https://anonhg.NetBSD.org/src/rev/a29fcb0ce342
branches:  netbsd-9
changeset: 461057:a29fcb0ce342
user:      martin <martin%NetBSD.org@localhost>
date:      Thu Nov 14 15:32:32 2019 +0000

description:
Pull up following revision(s) (requested by knakahara in ticket #423):

        sys/netipsec/key.c: revision 1.268
        sys/netipsec/key.c: revision 1.269

Fix SA can be expaired wrongly when there are many SPs.

When key_timehandler_spd() spent over one second, the "now" argument of
key_timehandler_sad() could be older than sav->created. That caused SA
was expired immediately.

 -

Reduce load for IKE negotiations when the system has many IPv6 addresses.
e.g. the system has many vlan(4), gif(4) or ipsecif(4) with link local address.

diffstat:

 sys/netipsec/key.c |  86 +++++++++++++++++++++++++++++++++++------------------
 1 files changed, 57 insertions(+), 29 deletions(-)

diffs (192 lines):

diff -r 5c440f91903c -r a29fcb0ce342 sys/netipsec/key.c
--- a/sys/netipsec/key.c        Thu Nov 14 15:30:19 2019 +0000
+++ b/sys/netipsec/key.c        Thu Nov 14 15:32:32 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: key.c,v 1.265.2.1 2019/09/01 10:49:37 martin Exp $     */
+/*     $NetBSD: key.c,v 1.265.2.2 2019/11/14 15:32:32 martin Exp $     */
 /*     $FreeBSD: key.c,v 1.3.2.3 2004/02/14 22:23:23 bms Exp $ */
 /*     $KAME: key.c,v 1.191 2001/06/27 10:46:49 sakane Exp $   */
 
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.265.2.1 2019/09/01 10:49:37 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.265.2.2 2019/11/14 15:32:32 martin Exp $");
 
 /*
  * This code is referred to RFC 2367
@@ -4495,30 +4495,34 @@
        bound = curlwp_bind();
        s = pserialize_read_enter();
        IN6_ADDRLIST_READER_FOREACH(ia) {
-               bool ingroup;
-
                if (key_sockaddr_match((const struct sockaddr *)&sin6,
                    (const struct sockaddr *)&ia->ia_addr, 0)) {
                        pserialize_read_exit(s);
                        goto ours;
                }
-               ia6_acquire(ia, &psref);
-               pserialize_read_exit(s);
-
-               /*
-                * XXX Multicast
-                * XXX why do we care about multlicast here while we don't care
-                * about IPv4 multicast??
-                * XXX scope
-                */
-               ingroup = in6_multi_group(&sin6->sin6_addr, ia->ia_ifp);
-               if (ingroup) {
+
+               if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
+                       bool ingroup;
+
+                       ia6_acquire(ia, &psref);
+                       pserialize_read_exit(s);
+
+                       /*
+                        * XXX Multicast
+                        * XXX why do we care about multlicast here while we don't care
+                        * about IPv4 multicast??
+                        * XXX scope
+                        */
+                       ingroup = in6_multi_group(&sin6->sin6_addr, ia->ia_ifp);
+                       if (ingroup) {
+                               ia6_release(ia, &psref);
+                               goto ours;
+                       }
+
+                       s = pserialize_read_enter();
                        ia6_release(ia, &psref);
-                       goto ours;
-               }
-
-               s = pserialize_read_enter();
-               ia6_release(ia, &psref);
+               }
+
        }
        pserialize_read_exit(s);
 
@@ -4876,14 +4880,20 @@
 }
 
 static void
-key_timehandler_spd(time_t now)
+key_timehandler_spd(void)
 {
        u_int dir;
        struct secpolicy *sp;
+       volatile time_t now;
 
        for (dir = 0; dir < IPSEC_DIR_MAX; dir++) {
            retry:
                mutex_enter(&key_spd.lock);
+               /*
+                * To avoid for sp->created to overtake "now" because of
+                * wating mutex, set time_uptime here.
+                */
+               now = time_uptime;
                SPLIST_WRITER_FOREACH(sp, dir) {
                        KASSERT(sp->state != IPSEC_SPSTATE_DEAD);
 
@@ -4917,10 +4927,11 @@
 }
 
 static void
-key_timehandler_sad(time_t now)
+key_timehandler_sad(void)
 {
        struct secashead *sah;
        int s;
+       volatile time_t now;
 
 restart:
        mutex_enter(&key_sad.lock);
@@ -4946,6 +4957,10 @@
                /* if LARVAL entry doesn't become MATURE, delete it. */
                mutex_enter(&key_sad.lock);
        restart_sav_LARVAL:
+               /*
+                * Same as key_timehandler_spd(), set time_uptime here.
+                */
+               now = time_uptime;
                SAVLIST_WRITER_FOREACH(sav, sah, SADB_SASTATE_LARVAL) {
                        if (now - sav->created > key_larval_lifetime) {
                                key_sa_chgstate(sav, SADB_SASTATE_DEAD);
@@ -4960,6 +4975,10 @@
                 */
        restart_sav_MATURE:
                mutex_enter(&key_sad.lock);
+               /*
+                * ditto
+                */
+               now = time_uptime;
                SAVLIST_WRITER_FOREACH(sav, sah, SADB_SASTATE_MATURE) {
                        /* we don't need to check. */
                        if (sav->lft_s == NULL)
@@ -5024,6 +5043,10 @@
                /* check DYING entry to change status to DEAD. */
                mutex_enter(&key_sad.lock);
        restart_sav_DYING:
+               /*
+                * ditto
+                */
+               now = time_uptime;
                SAVLIST_WRITER_FOREACH(sav, sah, SADB_SASTATE_DYING) {
                        /* we don't need to check. */
                        if (sav->lft_h == NULL)
@@ -5090,13 +5113,18 @@
 }
 
 static void
-key_timehandler_acq(time_t now)
+key_timehandler_acq(void)
 {
 #ifndef IPSEC_NONBLOCK_ACQUIRE
        struct secacq *acq, *nextacq;
+       volatile time_t now;
 
     restart:
        mutex_enter(&key_misc.lock);
+       /*
+        * Same as key_timehandler_spd(), set time_uptime here.
+        */
+       now = time_uptime;
        LIST_FOREACH_SAFE(acq, &key_misc.acqlist, chain, nextacq) {
                if (now - acq->created > key_blockacq_lifetime) {
                        LIST_REMOVE(acq, chain);
@@ -5110,10 +5138,11 @@
 }
 
 static void
-key_timehandler_spacq(time_t now)
+key_timehandler_spacq(void)
 {
 #ifdef notyet
        struct secspacq *acq, *nextacq;
+       time_t now = time_uptime;
 
        LIST_FOREACH_SAFE(acq, &key_misc.spacqlist, chain, nextacq) {
                if (now - acq->created > key_blockacq_lifetime) {
@@ -5135,15 +5164,14 @@
 static void
 key_timehandler_work(struct work *wk, void *arg)
 {
-       time_t now = time_uptime;
 
        /* We can allow enqueuing another work at this point */
        atomic_swap_uint(&key_timehandler_work_enqueued, 0);
 
-       key_timehandler_spd(now);
-       key_timehandler_sad(now);
-       key_timehandler_acq(now);
-       key_timehandler_spacq(now);
+       key_timehandler_spd();
+       key_timehandler_sad();
+       key_timehandler_acq();
+       key_timehandler_spacq();
 
        key_acquire_sendup_pending_mbuf();
 



Home | Main Index | Thread Index | Old Index