Tue Jun 1 05:16:46 2021 UTC ()
Send Up event in tlu action of LCP

When LCP is stopping, the layer send Down event and Close event
(Down -> Close). To align the sequence, Up event is moved
before Open event.


(yamaguchi)
diff -r1.255 -r1.256 src/sys/net/if_spppsubr.c

cvs diff -r1.255 -r1.256 src/sys/net/if_spppsubr.c (expand / switch to unified diff)

--- src/sys/net/if_spppsubr.c 2021/06/01 05:11:22 1.255
+++ src/sys/net/if_spppsubr.c 2021/06/01 05:16:46 1.256
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: if_spppsubr.c,v 1.255 2021/06/01 05:11:22 yamaguchi Exp $ */ 1/* $NetBSD: if_spppsubr.c,v 1.256 2021/06/01 05:16:46 yamaguchi Exp $ */
2 2
3/* 3/*
4 * Synchronous PPP/Cisco link level subroutines. 4 * Synchronous PPP/Cisco link level subroutines.
5 * Keepalive protocol implemented in both Cisco and PPP modes. 5 * Keepalive protocol implemented in both Cisco and PPP modes.
6 * 6 *
7 * Copyright (C) 1994-1996 Cronyx Engineering Ltd. 7 * Copyright (C) 1994-1996 Cronyx Engineering Ltd.
8 * Author: Serge Vakulenko, <vak@cronyx.ru> 8 * Author: Serge Vakulenko, <vak@cronyx.ru>
9 * 9 *
10 * Heavily revamped to conform to RFC 1661. 10 * Heavily revamped to conform to RFC 1661.
11 * Copyright (C) 1997, Joerg Wunsch. 11 * Copyright (C) 1997, Joerg Wunsch.
12 * 12 *
13 * RFC2472 IPv6CP support. 13 * RFC2472 IPv6CP support.
14 * Copyright (C) 2000, Jun-ichiro itojun Hagino <itojun@iijlab.net>. 14 * Copyright (C) 2000, Jun-ichiro itojun Hagino <itojun@iijlab.net>.
@@ -31,27 +31,27 @@ @@ -31,27 +31,27 @@
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE. 34 * POSSIBILITY OF SUCH DAMAGE.
35 * 35 *
36 * From: Version 2.4, Thu Apr 30 17:17:21 MSD 1997 36 * From: Version 2.4, Thu Apr 30 17:17:21 MSD 1997
37 * 37 *
38 * From: if_spppsubr.c,v 1.39 1998/04/04 13:26:03 phk Exp 38 * From: if_spppsubr.c,v 1.39 1998/04/04 13:26:03 phk Exp
39 * 39 *
40 * From: Id: if_spppsubr.c,v 1.23 1999/02/23 14:47:50 hm Exp 40 * From: Id: if_spppsubr.c,v 1.23 1999/02/23 14:47:50 hm Exp
41 */ 41 */
42 42
43#include <sys/cdefs.h> 43#include <sys/cdefs.h>
44__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.255 2021/06/01 05:11:22 yamaguchi Exp $"); 44__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.256 2021/06/01 05:16:46 yamaguchi Exp $");
45 45
46#if defined(_KERNEL_OPT) 46#if defined(_KERNEL_OPT)
47#include "opt_inet.h" 47#include "opt_inet.h"
48#include "opt_modular.h" 48#include "opt_modular.h"
49#include "opt_compat_netbsd.h" 49#include "opt_compat_netbsd.h"
50#include "opt_net_mpsafe.h" 50#include "opt_net_mpsafe.h"
51#include "opt_sppp.h" 51#include "opt_sppp.h"
52#endif 52#endif
53 53
54#include <sys/param.h> 54#include <sys/param.h>
55#include <sys/proc.h> 55#include <sys/proc.h>
56#include <sys/systm.h> 56#include <sys/systm.h>
57#include <sys/kernel.h> 57#include <sys/kernel.h>
@@ -1888,26 +1888,27 @@ sppp_open_event(struct sppp *sp, void *x @@ -1888,26 +1888,27 @@ sppp_open_event(struct sppp *sp, void *x
1888 1888
1889 SPPP_DLOG(sp, "%s open(%s)\n", cp->name, 1889 SPPP_DLOG(sp, "%s open(%s)\n", cp->name,
1890 sppp_state_name(sp->scp[cp->protoidx].state)); 1890 sppp_state_name(sp->scp[cp->protoidx].state));
1891 1891
1892 switch (sp->scp[cp->protoidx].state) { 1892 switch (sp->scp[cp->protoidx].state) {
1893 case STATE_INITIAL: 1893 case STATE_INITIAL:
1894 sppp_cp_change_state(cp, sp, STATE_STARTING); 1894 sppp_cp_change_state(cp, sp, STATE_STARTING);
1895 (cp->tls)(cp, sp); 1895 (cp->tls)(cp, sp);
1896 break; 1896 break;
1897 case STATE_STARTING: 1897 case STATE_STARTING:
1898 break; 1898 break;
1899 case STATE_CLOSED: 1899 case STATE_CLOSED:
1900 sp->scp[cp->protoidx].rst_counter = sp->lcp.max_configure; 1900 sp->scp[cp->protoidx].rst_counter = sp->lcp.max_configure;
 1901 sp->lcp.protos |= (1 << cp->protoidx);
1901 (cp->scr)(sp); 1902 (cp->scr)(sp);
1902 sppp_cp_change_state(cp, sp, STATE_REQ_SENT); 1903 sppp_cp_change_state(cp, sp, STATE_REQ_SENT);
1903 break; 1904 break;
1904 case STATE_STOPPED: 1905 case STATE_STOPPED:
1905 case STATE_STOPPING: 1906 case STATE_STOPPING:
1906 case STATE_REQ_SENT: 1907 case STATE_REQ_SENT:
1907 case STATE_ACK_RCVD: 1908 case STATE_ACK_RCVD:
1908 case STATE_ACK_SENT: 1909 case STATE_ACK_SENT:
1909 case STATE_OPENED: 1910 case STATE_OPENED:
1910 break; 1911 break;
1911 case STATE_CLOSING: 1912 case STATE_CLOSING:
1912 sppp_cp_change_state(cp, sp, STATE_STOPPING); 1913 sppp_cp_change_state(cp, sp, STATE_STOPPING);
1913 break; 1914 break;
@@ -3104,26 +3105,27 @@ sppp_lcp_confnak(struct sppp *sp, struct @@ -3104,26 +3105,27 @@ sppp_lcp_confnak(struct sppp *sp, struct
3104 break; 3105 break;
3105 } 3106 }
3106 } 3107 }
3107 if (debug) 3108 if (debug)
3108 addlog("\n"); 3109 addlog("\n");
3109end: 3110end:
3110 return; 3111 return;
3111} 3112}
3112 3113
3113static void 3114static void
3114sppp_lcp_tlu(struct sppp *sp) 3115sppp_lcp_tlu(struct sppp *sp)
3115{ 3116{
3116 struct ifnet *ifp; 3117 struct ifnet *ifp;
 3118 struct sppp_cp *scp;
3117 int i; 3119 int i;
3118 bool going_up; 3120 bool going_up;
3119 3121
3120 KASSERT(SPPP_WLOCKED(sp)); 3122 KASSERT(SPPP_WLOCKED(sp));
3121 3123
3122 ifp = &sp->pp_if; 3124 ifp = &sp->pp_if;
3123 3125
3124 /* unlock for IFNET_LOCK and if_up() */ 3126 /* unlock for IFNET_LOCK and if_up() */
3125 SPPP_UNLOCK(sp); 3127 SPPP_UNLOCK(sp);
3126 3128
3127 if (! (ifp->if_flags & IFF_UP) && 3129 if (! (ifp->if_flags & IFF_UP) &&
3128 (ifp->if_flags & IFF_RUNNING)) { 3130 (ifp->if_flags & IFF_RUNNING)) {
3129 /* Coming out of loopback mode. */ 3131 /* Coming out of loopback mode. */
@@ -3150,57 +3152,60 @@ sppp_lcp_tlu(struct sppp *sp) @@ -3150,57 +3152,60 @@ sppp_lcp_tlu(struct sppp *sp)
3150 ifp->if_mtu = sp->lcp.their_mru; 3152 ifp->if_mtu = sp->lcp.their_mru;
3151 SPPP_DLOG(sp, "setting MTU " 3153 SPPP_DLOG(sp, "setting MTU "
3152 "from %"PRIu64" bytes to %"PRIu64" bytes\n", 3154 "from %"PRIu64" bytes to %"PRIu64" bytes\n",
3153 sp->pp_saved_mtu, ifp->if_mtu); 3155 sp->pp_saved_mtu, ifp->if_mtu);
3154 } 3156 }
3155 IFNET_UNLOCK(ifp); 3157 IFNET_UNLOCK(ifp);
3156 3158
3157 if (ISSET(sp->lcp.opts, SPPP_LCP_OPT_AUTH_PROTO) || 3159 if (ISSET(sp->lcp.opts, SPPP_LCP_OPT_AUTH_PROTO) ||
3158 (sp->pp_flags & PP_NEEDAUTH) != 0) 3160 (sp->pp_flags & PP_NEEDAUTH) != 0)
3159 sppp_change_phase(sp, SPPP_PHASE_AUTHENTICATE); 3161 sppp_change_phase(sp, SPPP_PHASE_AUTHENTICATE);
3160 else 3162 else
3161 sppp_change_phase(sp, SPPP_PHASE_NETWORK); 3163 sppp_change_phase(sp, SPPP_PHASE_NETWORK);
3162 3164
3163 /* 
3164 * Open all authentication protocols. This is even required 
3165 * if we already proceeded to network phase, since it might be 
3166 * that remote wants us to authenticate, so we might have to 
3167 * send a PAP request. Undesired authentication protocols 
3168 * don't do anything when they get an Open event. 
3169 */ 
3170 for (i = 0; i < IDX_COUNT; i++) 
3171 if ((cps[i])->flags & CP_AUTH) { 
3172 sppp_wq_add(sp->wq_cp, 
3173 &sp->scp[(cps[i])->protoidx].work_open); 
3174 } 
3175 3165
3176 if (sp->pp_phase == SPPP_PHASE_NETWORK) { 3166 for (i = 0; i < IDX_COUNT; i++) {
3177 /* Notify all NCPs. */ 3167 scp = &sp->scp[(cps[i])->protoidx];
3178 for (i = 0; i < IDX_COUNT; i++) 3168
3179 if ((cps[i])->flags & CP_NCP) { 3169 if (((cps[i])->flags & CP_LCP) == 0)
3180 sppp_wq_add(sp->wq_cp, 3170 sppp_wq_add(sp->wq_cp, &scp->work_up);
3181 &sp->scp[(cps[i])->protoidx].work_open); 3171
3182 } 3172 /*
 3173 * Open all authentication protocols. This is even required
 3174 * if we already proceeded to network phase, since it might be
 3175 * that remote wants us to authenticate, so we might have to
 3176 * send a PAP request. Undesired authentication protocols
 3177 * don't do anything when they get an Open event.
 3178 */
 3179 if ((cps[i])->flags & CP_AUTH)
 3180 sppp_wq_add(sp->wq_cp, &scp->work_open);
 3181
 3182 /* Open all NCPs. */
 3183 if (sp->pp_phase == SPPP_PHASE_NETWORK &&
 3184 ((cps[i])->flags & CP_NCP) != 0) {
 3185 sppp_wq_add(sp->wq_cp, &scp->work_open);
 3186 }
3183 } 3187 }
3184 3188
3185 /* notify low-level driver of state change */ 3189 /* notify low-level driver of state change */
3186 sppp_notify_chg_wlocked(sp); 3190 sppp_notify_chg_wlocked(sp);
3187} 3191}
3188 3192
3189static void 3193static void
3190sppp_lcp_tld(struct sppp *sp) 3194sppp_lcp_tld(struct sppp *sp)
3191{ 3195{
3192 struct ifnet *ifp; 3196 struct ifnet *ifp;
3193 int i, pi, phase; 3197 struct sppp_cp *scp;
 3198 int i, phase;
3194 3199
3195 KASSERT(SPPP_WLOCKED(sp)); 3200 KASSERT(SPPP_WLOCKED(sp));
3196 3201
3197 phase = sp->pp_phase; 3202 phase = sp->pp_phase;
3198 3203
3199 sppp_change_phase(sp, SPPP_PHASE_TERMINATE); 3204 sppp_change_phase(sp, SPPP_PHASE_TERMINATE);
3200 3205
3201 if (sp->pp_saved_mtu > 0) { 3206 if (sp->pp_saved_mtu > 0) {
3202 ifp = &sp->pp_if; 3207 ifp = &sp->pp_if;
3203 3208
3204 SPPP_UNLOCK(sp); 3209 SPPP_UNLOCK(sp);
3205 IFNET_LOCK(ifp); 3210 IFNET_LOCK(ifp);
3206 SPPP_LOCK(sp, RW_WRITER); 3211 SPPP_LOCK(sp, RW_WRITER);
@@ -3211,35 +3216,39 @@ sppp_lcp_tld(struct sppp *sp) @@ -3211,35 +3216,39 @@ sppp_lcp_tld(struct sppp *sp)
3211 3216
3212 ifp->if_mtu = sp->pp_saved_mtu; 3217 ifp->if_mtu = sp->pp_saved_mtu;
3213 sp->pp_saved_mtu = 0; 3218 sp->pp_saved_mtu = 0;
3214 IFNET_UNLOCK(ifp); 3219 IFNET_UNLOCK(ifp);
3215 } 3220 }
3216 3221
3217 /* 3222 /*
3218 * Take upper layers down. We send the Down event first and 3223 * Take upper layers down. We send the Down event first and
3219 * the Close second to prevent the upper layers from sending 3224 * the Close second to prevent the upper layers from sending
3220 * ``a flurry of terminate-request packets'', as the RFC 3225 * ``a flurry of terminate-request packets'', as the RFC
3221 * describes it. 3226 * describes it.
3222 */ 3227 */
3223 for (i = 0; i < IDX_COUNT; i++) { 3228 for (i = 0; i < IDX_COUNT; i++) {
3224 pi = (cps[i])->protoidx; 3229 scp = &sp->scp[(cps[i])->protoidx];
3225 if (((cps[i])->flags & CP_LCP) == 0) { 
3226 /* skip if ncp was not started */ 
3227 if (phase != SPPP_PHASE_NETWORK && 
3228 ((cps[i])->flags & CP_NCP) != 0) 
3229 continue; 
3230 3230
3231 sppp_wq_add(sp->wq_cp, &sp->scp[pi].work_down); 3231 if (((cps[i])->flags & CP_LCP) == 0)
3232 sppp_wq_add(sp->wq_cp, &sp->scp[pi].work_close); 3232 sppp_wq_add(sp->wq_cp, &scp->work_down);
 3233
 3234 if ((cps[i])->flags & CP_AUTH) {
 3235 sppp_wq_add(sp->wq_cp, &scp->work_close);
 3236 }
 3237
 3238 /* Close all NCPs. */
 3239 if (phase == SPPP_PHASE_NETWORK &&
 3240 ((cps[i])->flags & CP_NCP) != 0) {
 3241 sppp_wq_add(sp->wq_cp, &scp->work_close);
3233 } 3242 }
3234 } 3243 }
3235} 3244}
3236 3245
3237static void 3246static void
3238sppp_lcp_tls(const struct cp *cp __unused, struct sppp *sp) 3247sppp_lcp_tls(const struct cp *cp __unused, struct sppp *sp)
3239{ 3248{
3240 3249
3241 KASSERT(SPPP_WLOCKED(sp)); 3250 KASSERT(SPPP_WLOCKED(sp));
3242 3251
3243 sppp_change_phase(sp, SPPP_PHASE_ESTABLISH); 3252 sppp_change_phase(sp, SPPP_PHASE_ESTABLISH);
3244 3253
3245 /* Notify lower layer if desired. */ 3254 /* Notify lower layer if desired. */
@@ -6500,31 +6509,30 @@ sppp_dotted_quad(char *buf, size_t bufle @@ -6500,31 +6509,30 @@ sppp_dotted_quad(char *buf, size_t bufle
6500} 6509}
6501 6510
6502/* a dummy, used to drop uninteresting events */ 6511/* a dummy, used to drop uninteresting events */
6503static void 6512static void
6504sppp_null(struct sppp *unused) 6513sppp_null(struct sppp *unused)
6505{ 6514{
6506 /* do just nothing */ 6515 /* do just nothing */
6507} 6516}
6508 6517
6509static void 6518static void
6510sppp_tls(const struct cp *cp, struct sppp *sp) 6519sppp_tls(const struct cp *cp, struct sppp *sp)
6511{ 6520{
6512 6521
 6522 SPPP_DLOG(sp, "%s tls\n", cp->name);
 6523
6513 /* notify lcp that is lower layer */ 6524 /* notify lcp that is lower layer */
6514 sp->lcp.protos |= (1 << cp->protoidx); 6525 sp->lcp.protos |= (1 << cp->protoidx);
6515 
6516 if (sp->scp[IDX_LCP].state == STATE_OPENED) 
6517 sppp_wq_add(sp->wq_cp, &sp->scp[cp->protoidx].work_up); 
6518} 6526}
6519 6527
6520static void 6528static void
6521sppp_tlf(const struct cp *cp, struct sppp *sp) 6529sppp_tlf(const struct cp *cp, struct sppp *sp)
6522{ 6530{
6523 6531
6524 SPPP_DLOG(sp, "%s tlf\n", cp->name); 6532 SPPP_DLOG(sp, "%s tlf\n", cp->name);
6525 6533
6526 /* notify lcp that is lower layer */ 6534 /* notify lcp that is lower layer */
6527 sp->lcp.protos &= ~(1 << cp->protoidx); 6535 sp->lcp.protos &= ~(1 << cp->protoidx);
6528 6536
6529 /* cleanup */ 6537 /* cleanup */
6530 if (sp->scp[cp->protoidx].mbuf_confreq != NULL) { 6538 if (sp->scp[cp->protoidx].mbuf_confreq != NULL) {