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 {

Reply via email to