| @@ -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"); |
3109 | end: | | 3110 | end: |
3110 | return; | | 3111 | return; |
3111 | } | | 3112 | } |
3112 | | | 3113 | |
3113 | static void | | 3114 | static void |
3114 | sppp_lcp_tlu(struct sppp *sp) | | 3115 | sppp_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 | |
3189 | static void | | 3193 | static void |
3190 | sppp_lcp_tld(struct sppp *sp) | | 3194 | sppp_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 | |
3237 | static void | | 3246 | static void |
3238 | sppp_lcp_tls(const struct cp *cp __unused, struct sppp *sp) | | 3247 | sppp_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 */ |
6503 | static void | | 6512 | static void |
6504 | sppp_null(struct sppp *unused) | | 6513 | sppp_null(struct sppp *unused) |
6505 | { | | 6514 | { |
6506 | /* do just nothing */ | | 6515 | /* do just nothing */ |
6507 | } | | 6516 | } |
6508 | | | 6517 | |
6509 | static void | | 6518 | static void |
6510 | sppp_tls(const struct cp *cp, struct sppp *sp) | | 6519 | sppp_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 | |
6520 | static void | | 6528 | static void |
6521 | sppp_tlf(const struct cp *cp, struct sppp *sp) | | 6529 | sppp_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) { |