]> git.ozlabs.org Git - ppp.git/commitdiff
Add a 'treat as reject' parameter to the nakci functions.
authorPaul Mackerras <paulus@samba.org>
Sat, 13 Nov 2004 02:28:15 +0000 (02:28 +0000)
committerPaul Mackerras <paulus@samba.org>
Sat, 13 Nov 2004 02:28:15 +0000 (02:28 +0000)
Use it to make sure we don't keep requesting the same IP
address over and over when it keeps getting nacked.

pppd/ccp.c
pppd/fsm.c
pppd/fsm.h
pppd/ipcp.c
pppd/ipv6cp.c
pppd/ipxcp.c
pppd/lcp.c

index 60eceb15d5174defc84297cd5e95f4752113fcc5..fd51952e02bb21eaf14339a587db1baaac3ec06b 100644 (file)
@@ -28,7 +28,7 @@
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#define RCSID  "$Id: ccp.c,v 1.47 2004/11/04 10:02:26 paulus Exp $"
+#define RCSID  "$Id: ccp.c,v 1.48 2004/11/13 02:28:15 paulus Exp $"
 
 #include <stdlib.h>
 #include <string.h>
 
 #include <stdlib.h>
 #include <string.h>
@@ -209,7 +209,7 @@ static void ccp_resetci __P((fsm *));
 static int  ccp_cilen __P((fsm *));
 static void ccp_addci __P((fsm *, u_char *, int *));
 static int  ccp_ackci __P((fsm *, u_char *, int));
 static int  ccp_cilen __P((fsm *));
 static void ccp_addci __P((fsm *, u_char *, int *));
 static int  ccp_ackci __P((fsm *, u_char *, int));
-static int  ccp_nakci __P((fsm *, u_char *, int));
+static int  ccp_nakci __P((fsm *, u_char *, int, int));
 static int  ccp_rejci __P((fsm *, u_char *, int));
 static int  ccp_reqci __P((fsm *, u_char *, int *, int));
 static void ccp_up __P((fsm *));
 static int  ccp_rejci __P((fsm *, u_char *, int));
 static int  ccp_reqci __P((fsm *, u_char *, int *, int));
 static void ccp_up __P((fsm *));
@@ -894,7 +894,7 @@ ccp_ackci(f, p, len)
  * Returns 1 iff the nak was OK.
  */
 static int
  * Returns 1 iff the nak was OK.
  */
 static int
-ccp_nakci(f, p, len)
+ccp_nakci(f, p, len, treat_as_reject)
     fsm *f;
     u_char *p;
     int len;
     fsm *f;
     u_char *p;
     int len;
index 043f7f0709192818138d082e536694400e971b5a..c200cc3a84387cefc952bdd37bac6650bf32161d 100644 (file)
@@ -40,7 +40,7 @@
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#define RCSID  "$Id: fsm.c,v 1.22 2004/02/02 03:57:19 carlsonj Exp $"
+#define RCSID  "$Id: fsm.c,v 1.23 2004/11/13 02:28:15 paulus Exp $"
 
 /*
  * TODO:
 
 /*
  * TODO:
@@ -496,6 +496,7 @@ fsm_rconfack(f, id, inp, len)
        return;
     }
     f->seen_ack = 1;
        return;
     }
     f->seen_ack = 1;
+    f->rnakloops = 0;
 
     switch (f->state) {
     case CLOSED:
 
     switch (f->state) {
     case CLOSED:
@@ -544,17 +545,29 @@ fsm_rconfnakrej(f, code, id, inp, len)
     u_char *inp;
     int len;
 {
     u_char *inp;
     int len;
 {
-    int (*proc) __P((fsm *, u_char *, int));
     int ret;
     int ret;
+    int treat_as_reject;
 
     if (id != f->reqid || f->seen_ack) /* Expected id? */
        return;                         /* Nope, toss... */
 
     if (id != f->reqid || f->seen_ack) /* Expected id? */
        return;                         /* Nope, toss... */
-    proc = (code == CONFNAK)? f->callbacks->nakci: f->callbacks->rejci;
-    if (!proc || !(ret = proc(f, inp, len))) {
-       /* Nak/reject is bad - ignore it */
-       error("Received bad configure-nak/rej: %P", inp, len);
-       return;
+
+    if (code == CONFNAK) {
+       ++f->rnakloops;
+       treat_as_reject = (f->rnakloops >= f->maxnakloops);
+       if (f->callbacks->nakci == NULL
+           || !(ret = f->callbacks->nakci(f, inp, len, treat_as_reject))) {
+           error("Received bad configure-nak: %P", inp, len);
+           return;
+       }
+    } else {
+       f->rnakloops = 0;
+       if (f->callbacks->rejci == NULL
+           || !(ret = f->callbacks->rejci(f, inp, len))) {
+           error("Received bad configure-rej: %P", inp, len);
+           return;
+       }
     }
     }
+
     f->seen_ack = 1;
 
     switch (f->state) {
     f->seen_ack = 1;
 
     switch (f->state) {
@@ -741,6 +754,7 @@ fsm_sconfreq(f, retransmit)
        if( f->callbacks->resetci )
            (*f->callbacks->resetci)(f);
        f->nakloops = 0;
        if( f->callbacks->resetci )
            (*f->callbacks->resetci)(f);
        f->nakloops = 0;
+       f->rnakloops = 0;
     }
 
     if( !retransmit ){
     }
 
     if( !retransmit ){
index 2627fbf65864297a517968cc7fca91d1ece6b178..87a78d38e8b2b48b1dfcf9c67d819bfc752d1253 100644 (file)
@@ -39,7 +39,7 @@
  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * $Id: fsm.h,v 1.9 2002/12/04 23:03:32 paulus Exp $
+ * $Id: fsm.h,v 1.10 2004/11/13 02:28:15 paulus Exp $
  */
 
 /*
  */
 
 /*
@@ -76,6 +76,7 @@ typedef struct fsm {
     int retransmits;           /* Number of retransmissions left */
     int maxtermtransmits;      /* Maximum Terminate-Request transmissions */
     int nakloops;              /* Number of nak loops since last ack */
     int retransmits;           /* Number of retransmissions left */
     int maxtermtransmits;      /* Maximum Terminate-Request transmissions */
     int nakloops;              /* Number of nak loops since last ack */
+    int rnakloops;             /* Number of naks received */
     int maxnakloops;           /* Maximum number of nak loops tolerated */
     struct fsm_callbacks *callbacks;   /* Callback routines */
     char *term_reason;         /* Reason for closing protocol */
     int maxnakloops;           /* Maximum number of nak loops tolerated */
     struct fsm_callbacks *callbacks;   /* Callback routines */
     char *term_reason;         /* Reason for closing protocol */
@@ -93,7 +94,7 @@ typedef struct fsm_callbacks {
     int  (*ackci)              /* ACK our Configuration Information */
                __P((fsm *, u_char *, int));
     int  (*nakci)              /* NAK our Configuration Information */
     int  (*ackci)              /* ACK our Configuration Information */
                __P((fsm *, u_char *, int));
     int  (*nakci)              /* NAK our Configuration Information */
-               __P((fsm *, u_char *, int));
+               __P((fsm *, u_char *, int, int));
     int  (*rejci)              /* Reject our Configuration Information */
                __P((fsm *, u_char *, int));
     int  (*reqci)              /* Request peer's Configuration Information */
     int  (*rejci)              /* Reject our Configuration Information */
                __P((fsm *, u_char *, int));
     int  (*reqci)              /* Request peer's Configuration Information */
index efc1af8d87c87abf98678cddf8658008942a915a..874d68523feb6b4fa92bdd75e98616acdae56ba4 100644 (file)
@@ -40,7 +40,7 @@
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#define RCSID  "$Id: ipcp.c,v 1.67 2004/11/08 11:45:59 paulus Exp $"
+#define RCSID  "$Id: ipcp.c,v 1.68 2004/11/13 02:28:15 paulus Exp $"
 
 /*
  * TODO:
 
 /*
  * TODO:
@@ -103,7 +103,7 @@ static void ipcp_resetci __P((fsm *));      /* Reset our CI */
 static int  ipcp_cilen __P((fsm *));           /* Return length of our CI */
 static void ipcp_addci __P((fsm *, u_char *, int *)); /* Add our CI */
 static int  ipcp_ackci __P((fsm *, u_char *, int));    /* Peer ack'd our CI */
 static int  ipcp_cilen __P((fsm *));           /* Return length of our CI */
 static void ipcp_addci __P((fsm *, u_char *, int *)); /* Add our CI */
 static int  ipcp_ackci __P((fsm *, u_char *, int));    /* Peer ack'd our CI */
-static int  ipcp_nakci __P((fsm *, u_char *, int));    /* Peer nak'd our CI */
+static int  ipcp_nakci __P((fsm *, u_char *, int, int));/* Peer nak'd our CI */
 static int  ipcp_rejci __P((fsm *, u_char *, int));    /* Peer rej'd our CI */
 static int  ipcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */
 static void ipcp_up __P((fsm *));              /* We're UP */
 static int  ipcp_rejci __P((fsm *, u_char *, int));    /* Peer rej'd our CI */
 static int  ipcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */
 static void ipcp_up __P((fsm *));              /* We're UP */
@@ -961,10 +961,11 @@ bad:
  *     1 - Nak was good.
  */
 static int
  *     1 - Nak was good.
  */
 static int
-ipcp_nakci(f, p, len)
+ipcp_nakci(f, p, len, treat_as_reject)
     fsm *f;
     u_char *p;
     int len;
     fsm *f;
     u_char *p;
     int len;
+    int treat_as_reject;
 {
     ipcp_options *go = &ipcp_gotoptions[f->unit];
     u_char cimaxslotindex, cicflag;
 {
     ipcp_options *go = &ipcp_gotoptions[f->unit];
     u_char cimaxslotindex, cicflag;
@@ -1040,11 +1041,17 @@ ipcp_nakci(f, p, len)
      * from our idea, only if the accept_{local,remote} flag is set.
      */
     NAKCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs,
      * from our idea, only if the accept_{local,remote} flag is set.
      */
     NAKCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs,
-              if (go->accept_local && ciaddr1) { /* Do we know our address? */
-                  try.ouraddr = ciaddr1;
-              }
-              if (go->accept_remote && ciaddr2) { /* Does he know his? */
-                  try.hisaddr = ciaddr2;
+              if (treat_as_reject) {
+                  try.old_addrs = 0;
+              } else {
+                  if (go->accept_local && ciaddr1) {
+                      /* take his idea of our address */
+                      try.ouraddr = ciaddr1;
+                  }
+                  if (go->accept_remote && ciaddr2) {
+                      /* take his idea of his address */
+                      try.hisaddr = ciaddr2;
+                  }
               }
        );
 
               }
        );
 
@@ -1055,7 +1062,9 @@ ipcp_nakci(f, p, len)
      * the peer wants.
      */
     NAKCIVJ(CI_COMPRESSTYPE, neg_vj,
      * the peer wants.
      */
     NAKCIVJ(CI_COMPRESSTYPE, neg_vj,
-           if (cilen == CILEN_VJ) {
+           if (treat_as_reject) {
+               try.neg_vj = 0;
+           } else if (cilen == CILEN_VJ) {
                GETCHAR(cimaxslotindex, p);
                GETCHAR(cicflag, p);
                if (cishort == IPCP_VJ_COMP) {
                GETCHAR(cimaxslotindex, p);
                GETCHAR(cicflag, p);
                if (cishort == IPCP_VJ_COMP) {
@@ -1078,18 +1087,29 @@ ipcp_nakci(f, p, len)
            );
 
     NAKCIADDR(CI_ADDR, neg_addr,
            );
 
     NAKCIADDR(CI_ADDR, neg_addr,
-             if (go->accept_local && ciaddr1) { /* Do we know our address? */
+             if (treat_as_reject) {
+                 try.neg_addr = 0;
+             } else if (go->accept_local && ciaddr1) {
+                 /* take his idea of our address */
                  try.ouraddr = ciaddr1;
              }
              );
 
     NAKCIDNS(CI_MS_DNS1, req_dns1,
                  try.ouraddr = ciaddr1;
              }
              );
 
     NAKCIDNS(CI_MS_DNS1, req_dns1,
-           try.dnsaddr[0] = cidnsaddr;
-           );
+            if (treat_as_reject) {
+                try.req_dns1 = 0;
+            } else {
+                try.dnsaddr[0] = cidnsaddr;
+            }
+            );
 
     NAKCIDNS(CI_MS_DNS2, req_dns2,
 
     NAKCIDNS(CI_MS_DNS2, req_dns2,
-           try.dnsaddr[1] = cidnsaddr;
-           );
+            if (treat_as_reject) {
+                try.req_dns2 = 0;
+            } else {
+                try.dnsaddr[1] = cidnsaddr;
+            }
+            );
 
     /*
      * There may be remaining CIs, if the peer is requesting negotiation
 
     /*
      * There may be remaining CIs, if the peer is requesting negotiation
index 000c863a3466a754d2f6d7b3125833b098d450d1..ce9b1385a444a90f7e2b5ba61edf547d83a31f04 100644 (file)
  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * $Id: ipv6cp.c,v 1.19 2004/01/13 03:59:37 paulus Exp $ 
+ * $Id: ipv6cp.c,v 1.20 2004/11/13 02:28:15 paulus Exp $ 
  */
 
  */
 
-#define RCSID  "$Id: ipv6cp.c,v 1.19 2004/01/13 03:59:37 paulus Exp $"
+#define RCSID  "$Id: ipv6cp.c,v 1.20 2004/11/13 02:28:15 paulus Exp $"
 
 /*
  * TODO: 
 
 /*
  * TODO: 
@@ -186,7 +186,7 @@ static void ipv6cp_resetci __P((fsm *));    /* Reset our CI */
 static int  ipv6cp_cilen __P((fsm *));         /* Return length of our CI */
 static void ipv6cp_addci __P((fsm *, u_char *, int *)); /* Add our CI */
 static int  ipv6cp_ackci __P((fsm *, u_char *, int));  /* Peer ack'd our CI */
 static int  ipv6cp_cilen __P((fsm *));         /* Return length of our CI */
 static void ipv6cp_addci __P((fsm *, u_char *, int *)); /* Add our CI */
 static int  ipv6cp_ackci __P((fsm *, u_char *, int));  /* Peer ack'd our CI */
-static int  ipv6cp_nakci __P((fsm *, u_char *, int));  /* Peer nak'd our CI */
+static int  ipv6cp_nakci __P((fsm *, u_char *, int, int));/* Peer nak'd our CI */
 static int  ipv6cp_rejci __P((fsm *, u_char *, int));  /* Peer rej'd our CI */
 static int  ipv6cp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */
 static void ipv6cp_up __P((fsm *));            /* We're UP */
 static int  ipv6cp_rejci __P((fsm *, u_char *, int));  /* Peer rej'd our CI */
 static int  ipv6cp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */
 static void ipv6cp_up __P((fsm *));            /* We're UP */
@@ -670,10 +670,11 @@ bad:
  *     1 - Nak was good.
  */
 static int
  *     1 - Nak was good.
  */
 static int
-ipv6cp_nakci(f, p, len)
+ipv6cp_nakci(f, p, len, treat_as_reject)
     fsm *f;
     u_char *p;
     int len;
     fsm *f;
     u_char *p;
     int len;
+    int treat_as_reject;
 {
     ipv6cp_options *go = &ipv6cp_gotoptions[f->unit];
     u_char citype, cilen, *next;
 {
     ipv6cp_options *go = &ipv6cp_gotoptions[f->unit];
     u_char citype, cilen, *next;
@@ -719,19 +720,21 @@ ipv6cp_nakci(f, p, len)
      * from our idea, only if the accept_{local,remote} flag is set.
      */
     NAKCIIFACEID(CI_IFACEID, neg_ifaceid,
      * from our idea, only if the accept_{local,remote} flag is set.
      */
     NAKCIIFACEID(CI_IFACEID, neg_ifaceid,
-             if (go->accept_local) {
-                 while (eui64_iszero(ifaceid) || 
-                        eui64_equals(ifaceid, go->hisid)) /* bad luck */
-                     eui64_magic(ifaceid);
-                 try.ourid = ifaceid;
-                 IPV6CPDEBUG(("local LL address %s", llv6_ntoa(ifaceid)));
-             }
-             );
+                if (treat_as_reject) {
+                    try.neg_ifaceid = 0;
+                } else if (go->accept_local) {
+                    while (eui64_iszero(ifaceid) || 
+                           eui64_equals(ifaceid, go->hisid)) /* bad luck */
+                        eui64_magic(ifaceid);
+                    try.ourid = ifaceid;
+                    IPV6CPDEBUG(("local LL address %s", llv6_ntoa(ifaceid)));
+                }
+                );
 
 #ifdef IPV6CP_COMP
     NAKCIVJ(CI_COMPRESSTYPE, neg_vj,
            {
 
 #ifdef IPV6CP_COMP
     NAKCIVJ(CI_COMPRESSTYPE, neg_vj,
            {
-               if (cishort == IPV6CP_COMP) {
+               if (cishort == IPV6CP_COMP && !treat_as_reject) {
                    try.vj_protocol = cishort;
                } else {
                    try.neg_vj = 0;
                    try.vj_protocol = cishort;
                } else {
                    try.neg_vj = 0;
index 0cbd9da19990bffbdfc43f0e3c4990af079f5f73..a78456d8cdedfe553c6094e989414d5c72d2278c 100644 (file)
@@ -42,7 +42,7 @@
 
 #ifdef IPX_CHANGE
 
 
 #ifdef IPX_CHANGE
 
-#define RCSID  "$Id: ipxcp.c,v 1.22 2003/07/28 12:25:41 carlsonj Exp $"
+#define RCSID  "$Id: ipxcp.c,v 1.23 2004/11/13 02:28:15 paulus Exp $"
 
 /*
  * TODO:
 
 /*
  * TODO:
@@ -82,7 +82,7 @@ static void ipxcp_resetci __P((fsm *));       /* Reset our CI */
 static int  ipxcp_cilen __P((fsm *));          /* Return length of our CI */
 static void ipxcp_addci __P((fsm *, u_char *, int *)); /* Add our CI */
 static int  ipxcp_ackci __P((fsm *, u_char *, int));   /* Peer ack'd our CI */
 static int  ipxcp_cilen __P((fsm *));          /* Return length of our CI */
 static void ipxcp_addci __P((fsm *, u_char *, int *)); /* Add our CI */
 static int  ipxcp_ackci __P((fsm *, u_char *, int));   /* Peer ack'd our CI */
-static int  ipxcp_nakci __P((fsm *, u_char *, int));   /* Peer nak'd our CI */
+static int  ipxcp_nakci __P((fsm *, u_char *, int, int));/* Peer nak'd our CI */
 static int  ipxcp_rejci __P((fsm *, u_char *, int));   /* Peer rej'd our CI */
 static int  ipxcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */
 static void ipxcp_up __P((fsm *));             /* We're UP */
 static int  ipxcp_rejci __P((fsm *, u_char *, int));   /* Peer rej'd our CI */
 static int  ipxcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */
 static void ipxcp_up __P((fsm *));             /* We're UP */
@@ -763,10 +763,11 @@ ipxcp_ackci(f, p, len)
  */
 
 static int
  */
 
 static int
-ipxcp_nakci(f, p, len)
+ipxcp_nakci(f, p, len, treat_as_reject)
     fsm *f;
     u_char *p;
     int len;
     fsm *f;
     u_char *p;
     int len;
+    int treat_as_reject;
 {
     u_char citype, cilen, *next;
     u_short s;
 {
     u_char citype, cilen, *next;
     u_short s;
@@ -792,7 +793,9 @@ ipxcp_nakci(f, p, len)
            no.neg_nn = 1;
 
            GETLONG(l, p);
            no.neg_nn = 1;
 
            GETLONG(l, p);
-           if (l && ao->accept_network)
+           if (treat_as_reject)
+               try.neg_nn = 0;
+           else if (l && ao->accept_network)
                try.our_network = l;
            break;
 
                try.our_network = l;
            break;
 
@@ -801,8 +804,10 @@ ipxcp_nakci(f, p, len)
                goto bad;
            no.neg_node = 1;
 
                goto bad;
            no.neg_node = 1;
 
-           if (!zero_node (p) && ao->accept_local &&
-               ! compare_node (p, ho->his_node))
+           if (treat_as_reject)
+               try.neg_node = 0;
+           else if (!zero_node (p) && ao->accept_local &&
+                    ! compare_node (p, ho->his_node))
                copy_node (p, try.our_node);
            break;
 
                copy_node (p, try.our_node);
            break;
 
index 7a5ae2f49e7fc9613211d779f4e1246c86ea2b11..23f69fe5f0360a10f7c1b34a16b90da19037cf4a 100644 (file)
@@ -40,7 +40,7 @@
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#define RCSID  "$Id: lcp.c,v 1.73 2004/11/12 11:42:46 paulus Exp $"
+#define RCSID  "$Id: lcp.c,v 1.74 2004/11/13 02:28:15 paulus Exp $"
 
 /*
  * TODO:
 
 /*
  * TODO:
@@ -206,7 +206,7 @@ static void lcp_resetci __P((fsm *));       /* Reset our CI */
 static int  lcp_cilen __P((fsm *));            /* Return length of our CI */
 static void lcp_addci __P((fsm *, u_char *, int *)); /* Add our CI to pkt */
 static int  lcp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */
 static int  lcp_cilen __P((fsm *));            /* Return length of our CI */
 static void lcp_addci __P((fsm *, u_char *, int *)); /* Add our CI to pkt */
 static int  lcp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */
-static int  lcp_nakci __P((fsm *, u_char *, int)); /* Peer nak'd our CI */
+static int  lcp_nakci __P((fsm *, u_char *, int, int)); /* Peer nak'd our CI */
 static int  lcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */
 static int  lcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv peer CI */
 static void lcp_up __P((fsm *));               /* We're UP */
 static int  lcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */
 static int  lcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv peer CI */
 static void lcp_up __P((fsm *));               /* We're UP */
@@ -924,10 +924,11 @@ bad:
  *     1 - Nak was good.
  */
 static int
  *     1 - Nak was good.
  */
 static int
-lcp_nakci(f, p, len)
+lcp_nakci(f, p, len, treat_as_reject)
     fsm *f;
     u_char *p;
     int len;
     fsm *f;
     u_char *p;
     int len;
+    int treat_as_reject;
 {
     lcp_options *go = &lcp_gotoptions[f->unit];
     lcp_options *wo = &lcp_wantoptions[f->unit];
 {
     lcp_options *go = &lcp_gotoptions[f->unit];
     lcp_options *wo = &lcp_wantoptions[f->unit];
@@ -1184,7 +1185,9 @@ lcp_nakci(f, p, len)
      */
     if (go->neg_mrru) {
        NAKCISHORT(CI_MRRU, neg_mrru,
      */
     if (go->neg_mrru) {
        NAKCISHORT(CI_MRRU, neg_mrru,
-                  if (cishort <= wo->mrru)
+                  if (treat_as_reject)
+                      try.neg_mrru = 0;
+                  else if (cishort <= wo->mrru)
                       try.mrru = cishort;
                   );
     }
                       try.mrru = cishort;
                   );
     }