Date: Thu, 04 Feb 1999 00:18:46 +0100 From: Poul-Henning Kamp <phk@FreeBSD.ORG> To: isdn@FreeBSD.ORG Subject: I4B PPP users, please test... Message-ID: <26029.918083926@critter.freebsd.dk>
next in thread | raw e-mail | index | archive | help
I'm trying to get the sppp code to behave less erratically in various corner cases (loopbacks, leased lines and whatsnot). This patch should hopefully not make things worse for ISDN use of the sppp implementation, but to make sure before I commit it, I'd like to hear back from a few people first. Don't worry about the "b6" you will see in ifconfig, it means that the isppp driver is "SMART" about the flags now, and a minor patch to ifconfig will make it look smarter there too. Poul-Henning Index: i386/isa/if_ar.c =================================================================== RCS file: /home/ncvs/src/sys/i386/isa/if_ar.c,v retrieving revision 1.24 diff -u -r1.24 if_ar.c --- if_ar.c 1998/12/16 18:42:38 1.24 +++ if_ar.c 1999/02/03 23:14:25 @@ -600,13 +600,6 @@ TRC(printf("ar%d: arioctl.\n", ifp->if_unit);) - if(cmd == SIOCSIFFLAGS) { - if(ifp->if_flags & IFF_LINK2) - sp->pp_flags |= PP_CISCO; - else - sp->pp_flags &= ~PP_CISCO; - } - was_up = ifp->if_flags & IFF_RUNNING; error = sppp_ioctl(ifp, cmd, data); Index: i386/isa/if_cx.c =================================================================== RCS file: /home/ncvs/src/sys/i386/isa/if_cx.c,v retrieving revision 1.26 diff -u -r1.26 if_cx.c --- if_cx.c 1998/12/16 18:42:38 1.26 +++ if_cx.c 1999/02/03 23:15:21 @@ -827,10 +827,6 @@ if (! new.ext) { struct sppp *sp = (struct sppp*) c->ifp; - if (new.cisco) - sp->pp_flags |= PP_CISCO; - else - sp->pp_flags &= ~PP_CISCO; if (new.keepalive) sp->pp_flags |= PP_KEEPALIVE; else Index: i386/isa/if_sr.c =================================================================== RCS file: /home/ncvs/src/sys/i386/isa/if_sr.c,v retrieving revision 1.21 diff -u -r1.21 if_sr.c --- if_sr.c 1999/01/18 21:27:03 1.21 +++ if_sr.c 1999/02/03 23:15:32 @@ -1275,13 +1275,6 @@ ifp->if_flags &= ~IFF_LINK1; #endif - /* - * Next we can handle minor protocol point(s) - */ - if (ifp->if_flags & IFF_LINK2) - sp->pp_flags |= PP_CISCO; - else - sp->pp_flags &= ~PP_CISCO; } /* * Next, we'll allow the network service layer we've called process Index: net/if.c =================================================================== RCS file: /home/ncvs/src/sys/net/if.c,v retrieving revision 1.65 diff -u -r1.65 if.c --- if.c 1999/02/01 20:03:27 1.65 +++ if.c 1999/02/03 21:01:39 @@ -604,6 +604,13 @@ error = suser(p->p_ucred, &p->p_acflag); if (error) return (error); + ifr->ifr_flags &= ~IFF_CANTCHANGE; + if (ifp->if_flags & IFF_SMART) { + if (ifp->if_ioctl) + (void) (*ifp->if_ioctl)(ifp, cmd, data); + getmicrotime(&ifp->if_lastchange); + break; + } if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) { int s = splimp(); if_down(ifp); @@ -615,7 +622,7 @@ splx(s); } ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) | - (ifr->ifr_flags &~ IFF_CANTCHANGE); + ifr->ifr_flags; if (ifp->if_ioctl) (void) (*ifp->if_ioctl)(ifp, cmd, data); getmicrotime(&ifp->if_lastchange); Index: net/if.h =================================================================== RCS file: /home/ncvs/src/sys/net/if.h,v retrieving revision 1.49 diff -u -r1.49 if.h --- if.h 1998/03/21 13:36:20 1.49 +++ if.h 1999/02/03 21:00:25 @@ -82,7 +82,7 @@ #define IFF_DEBUG 0x4 /* turn on debugging */ #define IFF_LOOPBACK 0x8 /* is a loopback net */ #define IFF_POINTOPOINT 0x10 /* interface is point-to-point link */ -/*#define IFF_NOTRAILERS 0x20 * obsolete: avoid use of trailers */ +#define IFF_SMART 0x20 /* smart interface, don't muck with flags */ #define IFF_RUNNING 0x40 /* resources allocated */ #define IFF_NOARP 0x80 /* no address resolution protocol */ #define IFF_PROMISC 0x100 /* receive all packets */ @@ -97,7 +97,7 @@ /* flags set internally only: */ #define IFF_CANTCHANGE \ - (IFF_BROADCAST|IFF_POINTOPOINT|IFF_RUNNING|IFF_OACTIVE|\ + (IFF_BROADCAST|IFF_POINTOPOINT|IFF_SMART|IFF_RUNNING|IFF_OACTIVE|\ IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI) #define IFQ_MAXLEN 50 Index: net/if_sppp.h =================================================================== RCS file: /home/ncvs/src/sys/net/if_sppp.h,v retrieving revision 1.13 diff -u -r1.13 if_sppp.h --- if_sppp.h 1998/12/27 21:30:44 1.13 +++ if_sppp.h 1999/02/03 21:42:25 @@ -83,7 +83,8 @@ struct ifqueue pp_fastq; /* fast output queue */ struct ifqueue pp_cpq; /* PPP control protocol queue */ struct sppp *pp_next; /* next interface in keepalive list */ - u_int pp_flags; /* use Cisco protocol instead of PPP */ + u_short pp_mode; /* operating mode */ + u_short pp_flags; /* various bits */ u_short pp_alivecnt; /* keepalive packets counter */ u_short pp_loopcnt; /* loopback detection counter */ u_long pp_seq; /* local sequence number */ @@ -132,11 +133,13 @@ }; #define PP_KEEPALIVE 0x01 /* use keepalive protocol */ -#define PP_CISCO 0x02 /* use Cisco protocol instead of PPP */ - /* 0x04 was PP_TIMO */ #define PP_CALLIN 0x08 /* we are being called */ #define PP_NEEDAUTH 0x10 /* remote requested authentication */ +#define PPM_LEASED 0x00 +#define PPM_CISCO 0x01 +#define PPM_AUTO 0x02 +#define PPM_PASSIVE 0x03 #define PP_MTU 1500 /* default/minimal MRU */ #define PP_MAX_MRU 2048 /* maximal MRU we want to negotiate */ Index: net/if_spppsubr.c =================================================================== RCS file: /home/ncvs/src/sys/net/if_spppsubr.c,v retrieving revision 1.52 diff -u -r1.52 if_spppsubr.c --- if_spppsubr.c 1998/12/27 21:30:44 1.52 +++ if_spppsubr.c 1999/02/03 22:50:49 @@ -134,6 +134,7 @@ #define IFF_PASSIVE IFF_LINK0 /* wait passively for connection */ #define IFF_AUTO IFF_LINK1 /* auto-dial on output */ +#define IFF_CISCO IFF_LINK2 /* cisco protocol */ #define PPP_ALLSTATIONS 0xff /* All-Stations broadcast address */ #define PPP_UI 0x03 /* Unnumbered Information */ @@ -466,7 +467,7 @@ case PPP_ALLSTATIONS: if (h->control != PPP_UI) goto invalid; - if (sp->pp_flags & PP_CISCO) { + if (sp->pp_mode == PPM_CISCO) { if (debug) log(LOG_DEBUG, SPP_FMT "PPP packet in Cisco mode " @@ -548,7 +549,7 @@ case CISCO_MULTICAST: case CISCO_UNICAST: /* Don't check the control field here (RFC 1547). */ - if (! (sp->pp_flags & PP_CISCO)) { + if (sp->pp_mode != PPM_CISCO) { if (debug) log(LOG_DEBUG, SPP_FMT "Cisco packet in PPP mode " @@ -711,7 +712,7 @@ * (albeit due to the implementation it's always enough) */ h = mtod (m, struct ppp_header*); - if (sp->pp_flags & PP_CISCO) { + if (sp->pp_mode == PPM_CISCO) { h->address = CISCO_UNICAST; /* unicast address */ h->control = 0; } else { @@ -722,7 +723,7 @@ switch (dst->sa_family) { #ifdef INET case AF_INET: /* Internet Protocol */ - if (sp->pp_flags & PP_CISCO) + if (sp->pp_mode == PPM_CISCO) h->protocol = htons (ETHERTYPE_IP); else { /* @@ -742,19 +743,19 @@ #endif #ifdef NS case AF_NS: /* Xerox NS Protocol */ - h->protocol = htons ((sp->pp_flags & PP_CISCO) ? + h->protocol = htons ((sp->pp_mode == PPM_CISCO) ? ETHERTYPE_NS : PPP_XNS); break; #endif #ifdef IPX case AF_IPX: /* Novell IPX Protocol */ - h->protocol = htons ((sp->pp_flags & PP_CISCO) ? + h->protocol = htons ((sp->pp_mode == PPM_CISCO) ? ETHERTYPE_IPX : PPP_IPX); break; #endif #ifdef ISO case AF_ISO: /* ISO OSI Protocol */ - if (sp->pp_flags & PP_CISCO) + if (sp->pp_mode == PPM_CISCO) goto nosupport; h->protocol = htons (PPP_ISO); break; @@ -806,7 +807,7 @@ spppq = sp; sp->pp_if.if_mtu = PP_MTU; - sp->pp_if.if_flags = IFF_POINTOPOINT | IFF_MULTICAST; + sp->pp_if.if_flags = IFF_POINTOPOINT | IFF_MULTICAST | IFF_SMART; sp->pp_if.if_type = IFT_PPP; sp->pp_if.if_output = sppp_output; #if 0 @@ -898,7 +899,7 @@ */ IF_DEQUEUE(&sp->pp_cpq, m); if (m == NULL && - (sppp_ncp_check(sp) || (sp->pp_flags & PP_CISCO) != 0)) { + (sppp_ncp_check(sp) || (sp->pp_mode == PPM_CISCO))) { IF_DEQUEUE(&sp->pp_fastq, m); if (m == NULL) IF_DEQUEUE (&sp->pp_if.if_snd, m); @@ -922,7 +923,7 @@ m = sp->pp_cpq.ifq_head; if (m == NULL && (sp->pp_phase == PHASE_NETWORK || - (sp->pp_flags & PP_CISCO) != 0)) + sp->pp_mode == PPM_CISCO)) if ((m = sp->pp_fastq.ifq_head) == NULL) m = sp->pp_if.if_snd.ifq_head; splx (s); @@ -937,7 +938,7 @@ { struct ifreq *ifr = (struct ifreq*) data; struct sppp *sp = (struct sppp*) ifp; - int s, rv, going_up, going_down, newmode; + int s, rv; s = splimp(); rv = 0; @@ -947,33 +948,56 @@ break; case SIOCSIFADDR: - if_up(ifp); - /* fall through... */ + break; case SIOCSIFFLAGS: - going_up = ifp->if_flags & IFF_UP && - (ifp->if_flags & IFF_RUNNING) == 0; - going_down = (ifp->if_flags & IFF_UP) == 0 && - ifp->if_flags & IFF_RUNNING; - newmode = ifp->if_flags & (IFF_AUTO | IFF_PASSIVE); - if (newmode == (IFF_AUTO | IFF_PASSIVE)) { - /* sanity */ - newmode = IFF_PASSIVE; - ifp->if_flags &= ~IFF_AUTO; - } - if (going_up || going_down) + printf("Flags %08x/%08x mode %d\n", + ifp->if_flags, ifr->ifr_flags, sp->pp_mode); + if (sp->pp_mode != PPM_CISCO) lcp.Close(sp); - if (going_up && newmode == 0) { - /* neither auto-dial nor passive */ - ifp->if_flags |= IFF_RUNNING; - if (!(sp->pp_flags & PP_CISCO)) - lcp.Open(sp); - } else if (going_down) { - sppp_flush(ifp); - ifp->if_flags &= ~IFF_RUNNING; + + ifp->if_flags &= ~(IFF_PASSIVE|IFF_AUTO|IFF_CISCO); + sp->pp_mode = PPM_LEASED; + if (ifr->ifr_flags & IFF_PASSIVE) { + sp->pp_mode = PPM_PASSIVE; + ifp->if_flags |= IFF_PASSIVE; + } else if (ifr->ifr_flags & IFF_AUTO) { + sp->pp_mode = PPM_AUTO; + ifp->if_flags |= IFF_AUTO; + } else if (ifr->ifr_flags & IFF_CISCO) { + sp->pp_mode = PPM_CISCO; + ifp->if_flags |= IFF_CISCO; } + printf("Flags %08x/%08x mode %d\n", + ifp->if_flags, ifr->ifr_flags, sp->pp_mode); + + if ((ifr->ifr_flags & IFF_UP) && (ifp->if_flags & IFF_UP)) { + if (sp->pp_mode == PPM_LEASED) + lcp.Open(sp); + } else if ((ifr->ifr_flags & IFF_UP) != + (ifp->if_flags & IFF_UP)) { + s = splimp(); + if (ifr->ifr_flags & IFF_UP) + if_route(ifp, IFF_UP, AF_UNSPEC); + else + if_unroute(ifp, IFF_UP, AF_UNSPEC); + splx(s); + if (!(ifr->ifr_flags & IFF_UP)) { + sppp_flush(ifp); + ifp->if_flags &= ~IFF_RUNNING; + } else if (sp->pp_mode == PPM_LEASED) { + lcp.Open(sp); + ifp->if_flags |= IFF_RUNNING; + } else if (sp->pp_mode == PPM_CISCO) { + ifp->if_flags |= IFF_RUNNING; + } + } + ifp->if_flags &= ~(IFF_UP|IFF_DEBUG); + ifp->if_flags |= ifr->ifr_flags & (IFF_UP|IFF_DEBUG); + printf("Flags %08x/%08x mode %d\n", + ifp->if_flags, ifr->ifr_flags, sp->pp_mode); break; #ifdef SIOCSIFMTU @@ -1511,13 +1535,12 @@ 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); + if (sp->pp_mode == PPM_LEASED) { + lcp.Down(sp); + lcp.Up(sp); + } else if (sp->pp_mode != PPM_CISCO) { + lcp.Close(sp); + } break; } *(long*)(h+1) = htonl (sp->lcp.magic); @@ -1822,23 +1845,18 @@ { STDDCL; + log(LOG_INFO, SPP_FMT "Up event\n", SPP_ARGS(ifp)); /* * If this interface is passive or dial-on-demand, and we are * still in Initial state, it means we've got an incoming * call. Activate the interface. */ - if ((ifp->if_flags & (IFF_AUTO | IFF_PASSIVE)) != 0) { - if (debug) - log(LOG_DEBUG, - SPP_FMT "Up event", SPP_ARGS(ifp)); + if (sp->pp_mode == PPM_AUTO || sp->pp_mode == PPM_PASSIVE) { ifp->if_flags |= IFF_RUNNING; if (sp->state[IDX_LCP] == STATE_INITIAL) { - if (debug) - addlog("(incoming call)\n"); sp->pp_flags |= PP_CALLIN; lcp.Open(sp); - } else if (debug) - addlog("\n"); + } } sppp_up_event(&lcp, sp); @@ -1849,30 +1867,14 @@ { STDDCL; + log(LOG_INFO, SPP_FMT "Down event\n", SPP_ARGS(ifp)); + sppp_down_event(&lcp, sp); - /* - * If this is neither a dial-on-demand nor a passive - * interface, simulate an ``ifconfig down'' action, so the - * administrator can force a redial by another ``ifconfig - * up''. XXX For leased line operation, should we immediately - * try to reopen the connection here? - */ - if ((ifp->if_flags & (IFF_AUTO | IFF_PASSIVE)) == 0) { - log(LOG_INFO, - SPP_FMT "Down event, taking interface down.\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) + if (sp->pp_mode == PPM_AUTO || sp->pp_mode == PPM_PASSIVE) { + sp->pp_flags &= ~PP_CALLIN; lcp.Close(sp); - ifp->if_flags &= ~IFF_RUNNING; + } } static void @@ -1892,7 +1894,14 @@ static void sppp_lcp_close(struct sppp *sp) { + STDDCL; + sppp_close_event(&lcp, sp); + if (sp->pp_mode == PPM_AUTO || sp->pp_mode == PPM_PASSIVE) { + if_down(ifp); + ifp->if_flags &= ~IFF_RUNNING; + sppp_qflush (&sp->pp_cpq); + } } static void @@ -2018,32 +2027,17 @@ } /* * 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) - addlog("[glitch] "); - ++sp->pp_loopcnt; - /* - * We negate our magic here, and NAK it. If - * we see it later in an NAK packet, we - * suggest a new one. + * Choose new magic and ignore this packet... */ - nmagic = ~sp->lcp.magic; - /* Gonna NAK it. */ - p[2] = nmagic >> 24; - p[3] = nmagic >> 16; - p[4] = nmagic >> 8; - p[5] = nmagic; + if (debug) + addlog("loopback ? \n"); +#if defined(__FreeBSD__) && __FreeBSD__ >= 3 + sp->lcp.magic = random(); +#else + sp->lcp.magic = time.tv_sec + time.tv_usec; +#endif + free (buf, M_TEMP); + return (0); break; case LCP_OPT_ASYNC_MAP: @@ -2221,7 +2215,7 @@ */ if (magic == ~sp->lcp.magic) { if (debug) - addlog("magic glitch "); + addlog("glitch "); #if defined(__FreeBSD__) && __FreeBSD__ >= 3 sp->lcp.magic = random(); #else @@ -3813,26 +3807,23 @@ continue; /* No keepalive in PPP mode if LCP not opened yet. */ - if (! (sp->pp_flags & PP_CISCO) && + if (sp->pp_mode != PPM_CISCO && sp->pp_phase < PHASE_AUTHENTICATE) continue; if (sp->pp_alivecnt == MAXALIVECNT) { /* No keepalive packets got. Stop the interface. */ - printf (SPP_FMT "down\n", SPP_ARGS(ifp)); - if_down (ifp); - sppp_qflush (&sp->pp_cpq); - if (! (sp->pp_flags & PP_CISCO)) { - /* XXX */ - /* Shut down the PPP link. */ + printf (SPP_FMT "no keepalives\n", SPP_ARGS(ifp)); + if (sp->pp_mode == PPM_LEASED) { lcp.Down(sp); - /* Initiate negotiation. XXX */ lcp.Up(sp); + } else if (sp->pp_mode != PPM_CISCO) { + lcp.Close(sp); } } if (sp->pp_alivecnt <= MAXALIVECNT) ++sp->pp_alivecnt; - if (sp->pp_flags & PP_CISCO) + if (sp->pp_mode == PPM_CISCO) sppp_cisco_send (sp, CISCO_KEEPALIVE_REQ, ++sp->pp_seq, sp->pp_rseq); else if (sp->pp_phase >= PHASE_AUTHENTICATE) { -- Poul-Henning Kamp FreeBSD coreteam member phk@FreeBSD.ORG "Real hackers run -current on their laptop." FreeBSD -- It will take a long time before progress goes too far! To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-isdn" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?26029.918083926>