Module Name: src Committed By: yamaguchi Date: Wed Nov 25 09:18:45 UTC 2020
Modified Files: src/sys/net: if_spppsubr.c if_spppvar.h Log Message: Add a function for RCR event To generate a diff of this commit: cvs rdiff -u -r1.193 -r1.194 src/sys/net/if_spppsubr.c cvs rdiff -u -r1.25 -r1.26 src/sys/net/if_spppvar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/net/if_spppsubr.c diff -u src/sys/net/if_spppsubr.c:1.193 src/sys/net/if_spppsubr.c:1.194 --- src/sys/net/if_spppsubr.c:1.193 Wed Nov 25 09:16:20 2020 +++ src/sys/net/if_spppsubr.c Wed Nov 25 09:18:45 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: if_spppsubr.c,v 1.193 2020/11/25 09:16:20 yamaguchi Exp $ */ +/* $NetBSD: if_spppsubr.c,v 1.194 2020/11/25 09:18:45 yamaguchi Exp $ */ /* * Synchronous PPP/Cisco link level subroutines. @@ -41,7 +41,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.193 2020/11/25 09:16:20 yamaguchi Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.194 2020/11/25 09:18:45 yamaguchi Exp $"); #if defined(_KERNEL_OPT) #include "opt_inet.h" @@ -251,6 +251,7 @@ struct cp { void (*tls)(struct sppp *sp); void (*tlf)(struct sppp *sp); void (*scr)(struct sppp *sp); + void (*scan)(const struct cp *, struct sppp *); }; static struct sppp *spppq; @@ -314,8 +315,10 @@ static void sppp_down_event(const struct static void sppp_open_event(const struct cp *, struct sppp *); static void sppp_close_event(const struct cp *, struct sppp *); static void sppp_to_event(const struct cp *, struct sppp *); +static void sppp_rcr_event(const struct cp *, struct sppp *); static void sppp_null(struct sppp *); +static void sppp_sca_scn(const struct cp *, struct sppp *); static void sppp_lcp_init(struct sppp *); static void sppp_lcp_up(struct sppp *); @@ -435,7 +438,7 @@ static const struct cp lcp = { sppp_lcp_up, sppp_lcp_down, sppp_lcp_open, sppp_lcp_close, sppp_lcp_TO, sppp_lcp_RCR, sppp_lcp_RCN_rej, sppp_lcp_RCN_nak, sppp_lcp_tlu, sppp_lcp_tld, sppp_lcp_tls, sppp_lcp_tlf, - sppp_lcp_scr + sppp_lcp_scr, sppp_sca_scn }; static const struct cp ipcp = { @@ -449,7 +452,7 @@ static const struct cp ipcp = { sppp_ipcp_up, sppp_ipcp_down, sppp_ipcp_open, sppp_ipcp_close, sppp_ipcp_TO, sppp_ipcp_RCR, sppp_ipcp_RCN_rej, sppp_ipcp_RCN_nak, sppp_ipcp_tlu, sppp_ipcp_tld, sppp_ipcp_tls, sppp_ipcp_tlf, - sppp_ipcp_scr + sppp_ipcp_scr, sppp_sca_scn }; static const struct cp ipv6cp = { @@ -463,7 +466,7 @@ static const struct cp ipv6cp = { sppp_ipv6cp_up, sppp_ipv6cp_down, sppp_ipv6cp_open, sppp_ipv6cp_close, sppp_ipv6cp_TO, sppp_ipv6cp_RCR, sppp_ipv6cp_RCN_rej, sppp_ipv6cp_RCN_nak, sppp_ipv6cp_tlu, sppp_ipv6cp_tld, sppp_ipv6cp_tls, sppp_ipv6cp_tlf, - sppp_ipv6cp_scr + sppp_ipv6cp_scr, sppp_sca_scn }; static const struct cp pap = { @@ -471,7 +474,7 @@ static const struct cp pap = { sppp_null, sppp_null, sppp_pap_open, sppp_pap_close, sppp_pap_TO, 0, 0, 0, sppp_pap_tlu, sppp_pap_tld, sppp_null, sppp_null, - sppp_pap_scr + sppp_pap_scr, 0 }; static const struct cp chap = { @@ -479,7 +482,7 @@ static const struct cp chap = { sppp_null, sppp_null, sppp_chap_open, sppp_chap_close, sppp_chap_TO, 0, 0, 0, sppp_chap_tlu, sppp_chap_tld, sppp_null, sppp_null, - sppp_chap_scr + sppp_chap_scr, 0 }; static const struct cp *cps[IDX_COUNT] = { @@ -1519,18 +1522,6 @@ sppp_cp_input(const struct cp *cp, struc if_statinc(ifp, if_ierrors); break; } - /* handle states where RCR doesn't get a SCA/SCN */ - switch (sp->scp[cp->protoidx].state) { - case STATE_CLOSING: - case STATE_STOPPING: - SPPP_UNLOCK(sp); - return; - case STATE_CLOSED: - sppp_cp_send(sp, cp->proto, TERM_ACK, h->ident, - 0, 0); - SPPP_UNLOCK(sp); - return; - } rv = (cp->RCR)(sp, h, len); if (rv < 0) { /* fatal error, shut down */ @@ -1539,40 +1530,8 @@ sppp_cp_input(const struct cp *cp, struc SPPP_UNLOCK(sp); return; } - switch (sp->scp[cp->protoidx].state) { - case STATE_OPENED: - (cp->tld)(sp); - (cp->scr)(sp); - /* fall through... */ - case STATE_ACK_SENT: - case STATE_REQ_SENT: - sppp_cp_change_state(cp, sp, rv? - STATE_ACK_SENT: STATE_REQ_SENT); - break; - case STATE_STOPPED: - sp->scp[cp->protoidx].rst_counter = sp->lcp.max_configure; - (cp->scr)(sp); - sppp_cp_change_state(cp, sp, rv? - STATE_ACK_SENT: STATE_REQ_SENT); - break; - case STATE_ACK_RCVD: - if (rv) { - sppp_cp_change_state(cp, sp, STATE_OPENED); - if (debug) - log(LOG_DEBUG, "%s: %s tlu\n", - ifp->if_xname, - cp->name); - (cp->tlu)(sp); - } else - sppp_cp_change_state(cp, sp, STATE_ACK_RCVD); - break; - default: - printf("%s: %s illegal %s in state %s\n", - ifp->if_xname, cp->name, - sppp_cp_type_name(h->type), - sppp_state_name(sp->scp[cp->protoidx].state)); - if_statinc(ifp, if_ierrors); - } + sp->scp[cp->protoidx].rconfid = h->ident; + sppp_rcr_event(cp, sp); break; case CONF_ACK: if (h->ident != sp->scp[cp->protoidx].confid) { @@ -2107,6 +2066,109 @@ sppp_to_event(const struct cp *cp, struc splx(s); } +static void +sppp_rcr_event(const struct cp *cp, struct sppp *sp) +{ + STDDCL; + u_char type; + void *buf; + size_t blen; + + type = sp->scp[cp->protoidx].rcr_type; + buf = sp->scp[cp->protoidx].rcr_buf; + blen = sp->scp[cp->protoidx].rcr_blen; + + if (type == CONF_ACK) { + /* RCR+ event */ + switch (sp->scp[cp->protoidx].state) { + case STATE_OPENED: + sppp_cp_change_state(cp, sp, STATE_ACK_SENT); + cp->tld(sp); + cp->scr(sp); + cp->scan(cp, sp); + break; + case STATE_ACK_SENT: + case STATE_REQ_SENT: + sppp_cp_change_state(cp, sp, STATE_ACK_SENT); + cp->scan(cp, sp); + break; + case STATE_STOPPED: + sppp_cp_change_state(cp, sp, STATE_ACK_SENT); + cp->scr(sp); + cp->scan(cp, sp); + break; + case STATE_ACK_RCVD: + sppp_cp_change_state(cp, sp, STATE_OPENED); + if (debug) + log(LOG_DEBUG, "%s: %s tlu\n", + ifp->if_xname, + cp->name); + cp->tlu(sp); + cp->scan(cp, sp); + break; + case STATE_CLOSING: + case STATE_STOPPING: + if (buf != NULL) { + sp->scp[cp->protoidx].rcr_buf = NULL; + sp->scp[cp->protoidx].rcr_blen = 0; + kmem_free(buf, blen); + } + break; + case STATE_CLOSED: + sppp_cp_send(sp, cp->proto, TERM_ACK, + sp->scp[cp->protoidx].rconfid, 0, 0); + break; + default: + printf("%s: %s illegal RCR+ in state %s\n", + ifp->if_xname, cp->name, + sppp_state_name(sp->scp[cp->protoidx].state)); + if_statinc(ifp, if_ierrors); + } + } else { + /* RCR- event */ + switch (sp->scp[cp->protoidx].state) { + case STATE_OPENED: + sppp_cp_change_state(cp, sp, STATE_REQ_SENT); + cp->tld(sp); + cp->scr(sp); + cp->scan(cp, sp); + break; + case STATE_ACK_SENT: + case STATE_REQ_SENT: + sppp_cp_change_state(cp, sp, STATE_REQ_SENT); + cp->scan(cp, sp); + break; + case STATE_STOPPED: + sppp_cp_change_state(cp, sp, STATE_REQ_SENT); + cp->scr(sp); + cp->scan(cp, sp); + break; + case STATE_ACK_RCVD: + sppp_cp_change_state(cp, sp, STATE_ACK_RCVD); + cp->scan(cp, sp); + break; + case STATE_CLOSING: + case STATE_STOPPING: + if (buf != NULL) { + sp->scp[cp->protoidx].rcr_buf = NULL; + sp->scp[cp->protoidx].rcr_blen = 0; + kmem_free(buf, blen); + } + break; + case STATE_CLOSED: + sppp_cp_change_state(cp, sp, STATE_CLOSED); + sppp_cp_send(sp, cp->proto, TERM_ACK, + sp->scp[cp->protoidx].rconfid, 0, 0); + break; + default: + printf("%s: %s illegal RCR- in state %s\n", + ifp->if_xname, cp->name, + sppp_state_name(sp->scp[cp->protoidx].state)); + if_statinc(ifp, if_ierrors); + } + } +} + /* * Change the state of a control protocol in the state automaton. * Takes care of starting/stopping the restart timer. @@ -2601,19 +2663,26 @@ sppp_lcp_RCR(struct sppp *sp, struct lcp } end: - if (rlen > 0) { - if (debug) - addlog("send %s", sppp_cp_type_name(type)); - sppp_cp_send(sp, PPP_LCP, type, h->ident, rlen, buf); - } - if (debug) addlog("\n"); - kmem_free(buf, blen); + if (sp->scp[IDX_LCP].rcr_buf != NULL) { + kmem_intr_free(sp->scp[IDX_LCP].rcr_buf, + sp->scp[IDX_LCP].rcr_blen); + } - if (rlen > 0) + if (rlen < 0) { + kmem_intr_free(buf, blen); + sp->scp[IDX_IPCP].rcr_buf = NULL; + sp->scp[IDX_IPCP].rcr_rlen = 0; return -1; + } + + sp->scp[IDX_LCP].rcr_type = type; + sp->scp[IDX_LCP].rcr_buf = buf; + sp->scp[IDX_LCP].rcr_blen = blen; + sp->scp[IDX_LCP].rcr_rlen = rlen; + if (type != CONF_ACK) return 0; return 1; @@ -3290,10 +3359,6 @@ sppp_ipcp_RCR(struct sppp *sp, struct lc if (rlen > 0) { type = CONF_NAK; } else { - type = CONF_ACK; - rlen = origlen; - memcpy(r, h + 1, rlen); - if ((sp->ipcp.flags & IPCP_HISADDR_SEEN) == 0) { /* * If we are about to conf-ack the request, but haven't seen @@ -3314,30 +3379,33 @@ sppp_ipcp_RCR(struct sppp *sp, struct lc rlen = 6; if (debug) addlog(" still need hisaddr"); + type = CONF_NAK; + } else { + type = CONF_ACK; + rlen = origlen; + memcpy(r, h + 1, rlen); } } - if (rlen) { - if (debug) - addlog(" send conf-nak\n"); - sppp_cp_send(sp, PPP_IPCP, CONF_NAK, h->ident, rlen, buf); - } else { - if (debug) - addlog(" send conf-ack\n"); - sppp_cp_send(sp, PPP_IPCP, CONF_ACK, h->ident, origlen, h + 1); +end: + if (debug) + addlog("\n"); + + if (rlen < 0) { + kmem_intr_free(buf, blen); + return -1; } -end: - if (rlen > 0) { - if (debug) - addlog(" send %s\n", sppp_cp_type_name(type)); - sppp_cp_send(sp, PPP_IPCP, type, h->ident, rlen, buf); + if (sp->scp[IDX_IPCP].rcr_buf != NULL) { + kmem_intr_free(sp->scp[IDX_IPCP].rcr_buf, + sp->scp[IDX_IPCP].rcr_blen); } - kmem_free(buf, blen); + sp->scp[IDX_IPCP].rcr_type = type; + sp->scp[IDX_IPCP].rcr_buf = buf; + sp->scp[IDX_IPCP].rcr_blen = blen; + sp->scp[IDX_IPCP].rcr_rlen = rlen; - if (rlen < 0) - return -1; if (type != CONF_ACK) return 0; return 1; @@ -3698,7 +3766,7 @@ sppp_ipv6cp_RCR(struct sppp *sp, struct KASSERT(SPPP_WLOCKED(sp)); - if (origlen <= 0) + if (origlen < sizeof(*h)) return 0; origlen -= sizeof(*h); @@ -3875,19 +3943,24 @@ sppp_ipv6cp_RCR(struct sppp *sp, struct } } end: - if (rlen > 0) { - if (debug) - addlog("send %s", sppp_cp_type_name(type)); - sppp_cp_send(sp, PPP_IPV6CP, type, h->ident, rlen, buf); - } - if (debug) addlog("\n"); - kmem_free(buf, blen); - - if (rlen < 0) + if (rlen < 0) { + kmem_intr_free(buf, blen); return -1; + } + + if (sp->scp[IDX_IPV6CP].rcr_buf != NULL) { + kmem_intr_free(sp->scp[IDX_IPV6CP].rcr_buf, + sp->scp[IDX_IPV6CP].rcr_blen); + } + + sp->scp[IDX_IPV6CP].rcr_type = type; + sp->scp[IDX_IPV6CP].rcr_buf = buf; + sp->scp[IDX_IPV6CP].rcr_blen = blen; + sp->scp[IDX_IPV6CP].rcr_rlen = rlen; + if (type != CONF_ACK) return 0; return 0; @@ -6261,6 +6334,35 @@ sppp_null(struct sppp *unused) { /* do just nothing */ } + +static void +sppp_sca_scn(const struct cp *cp, struct sppp *sp) +{ + STDDCL; + u_char rconfid, type, rlen; + void *buf; + size_t blen; + + rconfid = sp->scp[cp->protoidx].rconfid; + type = sp->scp[cp->protoidx].rcr_type; + buf = sp->scp[cp->protoidx].rcr_buf; + rlen = sp->scp[cp->protoidx].rcr_rlen; + blen = sp->scp[cp->protoidx].rcr_blen; + + sp->scp[cp->protoidx].rcr_buf = NULL; + sp->scp[cp->protoidx].rcr_blen = 0; + + if (buf != NULL) { + if (rlen > 0) { + if (debug) { + log(LOG_DEBUG, "%s: send %s\n", + ifp->if_xname, sppp_cp_type_name(type)); + } + sppp_cp_send(sp, cp->proto, type, rconfid, rlen, buf); + } + kmem_free(buf, blen); + } +} /* * This file is large. Tell emacs to highlight it nevertheless. * Index: src/sys/net/if_spppvar.h diff -u src/sys/net/if_spppvar.h:1.25 src/sys/net/if_spppvar.h:1.26 --- src/sys/net/if_spppvar.h:1.25 Wed Nov 25 09:12:50 2020 +++ src/sys/net/if_spppvar.h Wed Nov 25 09:18:45 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: if_spppvar.h,v 1.25 2020/11/25 09:12:50 yamaguchi Exp $ */ +/* $NetBSD: if_spppvar.h,v 1.26 2020/11/25 09:18:45 yamaguchi Exp $ */ #ifndef _NET_IF_SPPPVAR_H_ #define _NET_IF_SPPPVAR_H_ @@ -91,10 +91,15 @@ struct sppp_cp { u_long seq; /* local sequence number */ u_long rseq; /* remote sequence number */ int state; /* state machine */ - u_char confid; /* id of last configuration request */ + u_char confid; /* local id of last configuration request */ + u_char rconfid; /* remote id of last configuration request */ int rst_counter; /* restart counter */ int fail_counter; /* negotiation failure counter */ struct callout ch; /* per-proto and if callouts */ + u_char rcr_type; + void *rcr_buf; + size_t rcr_blen; + int rcr_rlen; }; struct sppp {