Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 8 Apr 1999 17:04:44 +0400 (MSD)
From:      Serge Vakulenko <vak@crox.net.kiae.su>
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   kern/11023: [patch] if_spppsubr.c - critical bug fixes
Message-ID:  <199904081304.RAA03558@crox.net.kiae.su>

next in thread | raw e-mail | index | archive | help

>Number:         11023
>Category:       kern
>Synopsis:       Synchronous PPP not functional in leased line mode
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Apr  8 06:10:01 PDT 1999
>Closed-Date:
>Last-Modified:
>Originator:     Serge Vakulenko
>Release:        FreeBSD 3.1-RELEASE i386
>Organization:
Cronyx Engineering Ltd.
>Environment:

Cronyx-Sigma and Cronyx-Tau synchronous adapters.
HDSL modem link to Cisco router.

>Description:

1) Gated logs the 'no buffer space available' error.
   The reason was in too small output queue length
   (was 32, increased to max 50 packets).
2) LCP options were not reset to default values on
   every new connection. Instead the values from the previous
   connection vere incorrectly used.
3) Line loopback was not detected properly.
4) Cisco/HDLC protocol was not functional.
5) IPCP could lock up in stopped state, up to the next reboot.

>How-To-Repeat:

	cxconfig cx0 hdlc ppp +extclock
	ifconfig cx0 <addr> <addr> up debug

>Fix:

Changes:
1) Output queue length increased to 50 packets.
   Old length (32) was not enough in some cases.
2) Reset LCP options to default values, when starting new session.
3) Fixed line loopback detection.
4) Fixed Cisco/HDLC protocol.
5) Fixed IPCP lock up in stopped state.
___
Serge Vakulenko, <vak@cronyx.ru>
Cronyx Engineering Ltd.

--- z	Fri Apr  2 16:26:21 1999
+++ if_spppsubr.c	Fri Apr  2 16:24:47 1999
@@ -812,8 +812,9 @@
 #if 0
 	sp->pp_flags = PP_KEEPALIVE;
 #endif
-	sp->pp_fastq.ifq_maxlen = 32;
-	sp->pp_cpq.ifq_maxlen = 20;
+ 	sp->pp_if.if_snd.ifq_maxlen = 50;
+ 	sp->pp_fastq.ifq_maxlen = 50;
+ 	sp->pp_cpq.ifq_maxlen = 50;
 	sp->pp_loopcnt = 0;
 	sp->pp_alivecnt = 0;
 	sp->pp_seq = 0;
@@ -963,7 +964,8 @@
 		}

 		if (going_up || going_down)
-			lcp.Close(sp);
+			if (!(sp->pp_flags & PP_CISCO))
+				lcp.Close(sp);
 		if (going_up && newmode == 0) {
 			/* neither auto-dial nor passive */
 			ifp->if_flags |= IFF_RUNNING;
@@ -1511,13 +1513,8 @@
 		if (ntohl (*(long*)(h+1)) == sp->lcp.magic) {
 			/* Line loopback mode detected. */
 			printf(SPP_FMT "loopback\n", SPP_ARGS(ifp));
-			if_down (ifp);
-			sppp_qflush (&sp->pp_cpq);
-
 			/* Shut down the PPP link. */
-			/* XXX */
-			lcp.Down(sp);
-			lcp.Up(sp);
+			lcp.Close(sp);
 			break;
 		}
 		*(long*)(h+1) = htonl (sp->lcp.magic);
@@ -1822,6 +1819,11 @@
 {
 	STDDCL;

+	sp->pp_alivecnt = 0;
+	sp->lcp.opts = (1 << LCP_OPT_MAGIC);
+	sp->lcp.magic = 0;
+	sp->lcp.protos = 0;
+	sp->lcp.mru = sp->lcp.their_mru = PP_MTU;
 	/*
 	 * If this interface is passive or dial-on-demand, and we are
 	 * still in Initial state, it means we've got an incoming
@@ -1860,19 +1862,18 @@
 	 */
 	if ((ifp->if_flags & (IFF_AUTO | IFF_PASSIVE)) == 0) {
 		log(LOG_INFO,
-		    SPP_FMT "Down event, taking interface down.\n",
+		    SPP_FMT "Down event, continuing.\n",
 		    SPP_ARGS(ifp));
-		if_down(ifp);
 	} else {
 		if (debug)
 			log(LOG_DEBUG,
 			    SPP_FMT "Down event (carrier loss)\n",
 			    SPP_ARGS(ifp));
+		sp->pp_flags &= ~PP_CALLIN;
+		if (sp->state[IDX_LCP] != STATE_INITIAL)
+			lcp.Close(sp);
+		ifp->if_flags &= ~IFF_RUNNING;
 	}
-	sp->pp_flags &= ~PP_CALLIN;
-	if (sp->state[IDX_LCP] != STATE_INITIAL)
-		lcp.Close(sp);
-	ifp->if_flags &= ~IFF_RUNNING;
 }

 static void
@@ -1934,10 +1935,14 @@
 		switch (*p) {
 		case LCP_OPT_MAGIC:
 			/* Magic number. */
-			/* fall through, both are same length */
+			if (len >= 6 && p[1] == 6)
+				continue;
+			if (debug)
+				addlog("[invalid] ");
+			break;
 		case LCP_OPT_ASYNC_MAP:
 			/* Async control character map. */
-			if (len >= 6 || p[1] == 6)
+			if (len >= 6 && p[1] == 6)
 				continue;
 			if (debug)
 				addlog("[invalid] ");
@@ -2016,21 +2021,7 @@
 					addlog("0x%lx ", nmagic);
 				continue;
 			}
-			/*
-			 * Local and remote magics equal -- loopback?
-			 */
-			if (sp->pp_loopcnt >= MAXALIVECNT*5) {
-				printf (SPP_FMT "loopback\n",
-					SPP_ARGS(ifp));
-				sp->pp_loopcnt = 0;
-				if (ifp->if_flags & IFF_UP) {
-					if_down(ifp);
-					sppp_qflush(&sp->pp_cpq);
-					/* XXX ? */
-					lcp.Down(sp);
-					lcp.Up(sp);
-				}
-			} else if (debug)
+			if (debug)
 				addlog("[glitch] ");
 			++sp->pp_loopcnt;
 			/*
@@ -2095,17 +2086,21 @@
 		rlen += p[1];
 	}
 	if (rlen) {
-		if (++sp->fail_counter[IDX_LCP] >= sp->lcp.max_failure) {
+		if (++sp->fail_counter[IDX_LCP] < sp->lcp.max_failure) {
 			if (debug)
-				addlog(" max_failure (%d) exceeded, "
-				       "send conf-rej\n",
-				       sp->lcp.max_failure);
-			sppp_cp_send(sp, PPP_LCP, CONF_REJ, h->ident, rlen, buf);
-		} else {
-			if (debug)
-				addlog(" send conf-nak\n");
+				addlog("send conf-nak\n");
 			sppp_cp_send (sp, PPP_LCP, CONF_NAK, h->ident, rlen, buf);
+			return 0;
 		}
+		if (debug)
+			addlog("max_failure (%d) exceeded, closing\n",
+			       sp->lcp.max_failure);
+		if (sp->pp_loopcnt >= MAXALIVECNT)
+			printf ("%s%d: loopback\n",
+				ifp->if_name, ifp->if_unit);
+		lcp.Close(sp);
+		sp->fail_counter[IDX_LCP] = 0;
+		sp->pp_loopcnt = 0;
 		return 0;
 	} else {
 		if (debug)
@@ -2498,6 +2498,10 @@

 	sp->ipcp.flags &= ~(IPCP_HISADDR_SEEN|IPCP_MYADDR_SEEN|IPCP_MYADDR_DYN);

+	/* To prevent IPCP lock up in stopped state. */
+	if (sp->state[IDX_IPCP] == STATE_STOPPED)
+		sp->state[IDX_IPCP] = STATE_CLOSED;
+
 	sppp_get_ip_addrs(sp, &myaddr, &hisaddr, 0);
 	/*
 	 * If we don't have his address, this probably means our
@@ -3820,14 +3815,12 @@
 		if (sp->pp_alivecnt == MAXALIVECNT) {
 			/* No keepalive packets got.  Stop the interface. */
 			printf (SPP_FMT "down\n", SPP_ARGS(ifp));
+			if (sp->pp_flags & PP_CISCO) {
 			if_down (ifp);
 			sppp_qflush (&sp->pp_cpq);
-			if (! (sp->pp_flags & PP_CISCO)) {
-				/* XXX */
+			} else {
 				/* Shut down the PPP link. */
-				lcp.Down(sp);
-				/* Initiate negotiation. XXX */
-				lcp.Up(sp);
+				lcp.Close(sp);
 			}
 		}
 		if (sp->pp_alivecnt <= MAXALIVECNT)

>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199904081304.RAA03558>