diff options
author | brian <brian@FreeBSD.org> | 1998-06-12 17:45:10 +0000 |
---|---|---|
committer | brian <brian@FreeBSD.org> | 1998-06-12 17:45:10 +0000 |
commit | 0cb00afb55f57f563f31446c912021e60f8b11ce (patch) | |
tree | 48298fba1b71a67ec155ca148df8d9bf63054235 | |
parent | 669024d8256e3492a6a1758a953d26e68c222f6c (diff) | |
download | FreeBSD-src-0cb00afb55f57f563f31446c912021e60f8b11ce.zip FreeBSD-src-0cb00afb55f57f563f31446c912021e60f8b11ce.tar.gz |
o Maintain a link-type mask for open datalinks as well as
for all datalinks in a bundle. Ppp now deals correctly
with link types that are changed while open
o When changing the type of the last AUTO link, only clear
the interface if we're not in PHASE_NETWORK. This allows
us to switch to -ddial mode while we have a connection
without suddenly unexpectedly throttling ourselves by
clearing the interface configuration.
Problem area noted by: Aaron Jeremias Luz <aaron@csh.rit.edu>
-rw-r--r-- | usr.sbin/ppp/bundle.c | 132 | ||||
-rw-r--r-- | usr.sbin/ppp/bundle.h | 8 | ||||
-rw-r--r-- | usr.sbin/ppp/command.c | 10 | ||||
-rw-r--r-- | usr.sbin/ppp/datalink.c | 3 | ||||
-rw-r--r-- | usr.sbin/ppp/ipcp.c | 4 |
5 files changed, 92 insertions, 65 deletions
diff --git a/usr.sbin/ppp/bundle.c b/usr.sbin/ppp/bundle.c index d65c322..fecd2fb 100644 --- a/usr.sbin/ppp/bundle.c +++ b/usr.sbin/ppp/bundle.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: bundle.c,v 1.13 1998/06/06 20:50:54 brian Exp $ + * $Id: bundle.c,v 1.14 1998/06/07 00:16:37 brian Exp $ */ #include <sys/param.h> @@ -300,12 +300,46 @@ bundle_RemainingAutoLoadTime(struct bundle *bundle) return -1; } +static void +bundle_LinkAdded(struct bundle *bundle, struct datalink *dl) +{ + bundle->phys_type.all |= dl->physical->type; + if (dl->state == DATALINK_OPEN) + bundle->phys_type.open |= dl->physical->type; + + /* Note: We only re-add links that are DATALINK_OPEN */ + if (dl->physical->type == PHYS_AUTO && + bundle->autoload.timer.state == TIMER_STOPPED && + dl->state != DATALINK_OPEN && + bundle->phase == PHASE_NETWORK) + bundle->autoload.running = 1; + + if ((bundle->phys_type.open & (PHYS_DEDICATED|PHYS_DDIAL)) + != bundle->phys_type.open && bundle->idle.timer.state == TIMER_STOPPED) + /* We may need to start our idle timer */ + bundle_StartIdleTimer(bundle); +} + +static void +bundle_LinksRemoved(struct bundle *bundle) +{ + struct datalink *dl; + + bundle->phys_type.all = bundle->phys_type.open = 0; + for (dl = bundle->links; dl; dl = dl->next) + bundle_LinkAdded(bundle, dl); + + if ((bundle->phys_type.open & (PHYS_DEDICATED|PHYS_DDIAL)) + == bundle->phys_type.open) + bundle_StopIdleTimer(bundle); +} static void bundle_LayerUp(void *v, struct fsm *fp) { /* * The given fsm is now up + * If it's an LCP, adjust our phys_mode.open value. * If it's an LCP set our mtu (if we're multilink, add up the link * speeds and set the MRRU) and start our autoload timer. * If it's an NCP, tell our -background parent to go away. @@ -314,6 +348,9 @@ bundle_LayerUp(void *v, struct fsm *fp) struct bundle *bundle = (struct bundle *)v; if (fp->proto == PROTO_LCP) { + struct physical *p = link2physical(fp->link); + + bundle_LinkAdded(bundle, p->dl); if (bundle->ncp.mp.active) { struct datalink *dl; @@ -324,7 +361,7 @@ bundle_LayerUp(void *v, struct fsm *fp) tun_configure(bundle, bundle->ncp.mp.peer_mrru); bundle->autoload.running = 1; } else { - bundle->ifp.Speed = modem_Speed(link2physical(fp->link)); + bundle->ifp.Speed = modem_Speed(p); tun_configure(bundle, fsm2lcp(fp)->his_mru); } } else if (fp->proto == PROTO_IPCP) { @@ -339,6 +376,7 @@ bundle_LayerDown(void *v, struct fsm *fp) /* * The given FSM has been told to come down. * If it's our last NCP, stop the idle timer. + * If it's an LCP, adjust our phys_type.open value and any timers. * If it's an LCP and we're in multilink mode, adjust our tun * speed and make sure our minimum sequence number is adjusted. */ @@ -347,27 +385,30 @@ bundle_LayerDown(void *v, struct fsm *fp) if (fp->proto == PROTO_IPCP) bundle_StopIdleTimer(bundle); - else if (fp->proto == PROTO_LCP && bundle->ncp.mp.active) { - struct datalink *dl; - struct datalink *lost; + else if (fp->proto == PROTO_LCP) { + bundle_LinksRemoved(bundle); /* adjust timers & phys_type values */ + if (bundle->ncp.mp.active) { + struct datalink *dl; + struct datalink *lost; - bundle->ifp.Speed = 0; - lost = NULL; - for (dl = bundle->links; dl; dl = dl->next) - if (fp == &dl->physical->link.lcp.fsm) - lost = dl; - else if (dl->state == DATALINK_OPEN) - bundle->ifp.Speed += modem_Speed(dl->physical); + bundle->ifp.Speed = 0; + lost = NULL; + for (dl = bundle->links; dl; dl = dl->next) + if (fp == &dl->physical->link.lcp.fsm) + lost = dl; + else if (dl->state == DATALINK_OPEN) + bundle->ifp.Speed += modem_Speed(dl->physical); - if (bundle->ifp.Speed) - /* Don't configure down to a speed of 0 */ - tun_configure(bundle, bundle->ncp.mp.link.lcp.his_mru); + if (bundle->ifp.Speed) + /* Don't configure down to a speed of 0 */ + tun_configure(bundle, bundle->ncp.mp.link.lcp.his_mru); - if (lost) - mp_LinkLost(&bundle->ncp.mp, lost); - else - log_Printf(LogERROR, "Oops, lost an unrecognised datalink (%s) !\n", - fp->link->name); + if (lost) + mp_LinkLost(&bundle->ncp.mp, lost); + else + log_Printf(LogERROR, "Oops, lost an unrecognised datalink (%s) !\n", + fp->link->name); + } } } @@ -501,8 +542,8 @@ bundle_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) bundle_StartAutoLoadTimer(bundle, 1); } - if (r && - (bundle->phase == PHASE_NETWORK || bundle->phys_type & PHYS_AUTO)) { + if (r && (bundle->phase == PHASE_NETWORK || + bundle->phys_type.all & PHYS_AUTO)) { /* enough surplus so that we can tell if we're getting swamped */ want = bundle->cfg.autoload.max.packets + nlinks * 2; /* but at least 20 packets ! */ @@ -792,7 +833,8 @@ bundle_Create(const char *prefix, int type, const char **argv) bundle.cfg.autoload.max.timeout = 0; bundle.cfg.autoload.min.packets = 0; bundle.cfg.autoload.min.timeout = 0; - bundle.phys_type = type; + bundle.phys_type.all = type; + bundle.phys_type.open = 0; bundle.links = datalink_Create("deflink", &bundle, type); if (bundle.links == NULL) { @@ -1223,8 +1265,8 @@ void bundle_StartIdleTimer(struct bundle *bundle) { timer_Stop(&bundle->idle.timer); - if ((bundle->phys_type & (PHYS_DEDICATED|PHYS_DDIAL)) != bundle->phys_type && - bundle->cfg.idle_timeout) { + if ((bundle->phys_type.open & (PHYS_DEDICATED|PHYS_DDIAL)) != + bundle->phys_type.open && bundle->cfg.idle_timeout) { bundle->idle.timer.func = bundle_IdleTimeout; bundle->idle.timer.name = "idle"; bundle->idle.timer.load = bundle->cfg.idle_timeout * SECTICKS; @@ -1263,29 +1305,6 @@ bundle_IsDead(struct bundle *bundle) return !bundle->links || (bundle->phase == PHASE_DEAD && bundle->CleaningUp); } -static void -bundle_LinkAdded(struct bundle *bundle, struct datalink *dl) -{ - bundle->phys_type |= dl->physical->type; - if (dl->physical->type == PHYS_AUTO && - bundle->autoload.timer.state == TIMER_STOPPED && - bundle->phase == PHASE_NETWORK) - bundle->autoload.running = 1; -} - -static void -bundle_LinksRemoved(struct bundle *bundle) -{ - struct datalink *dl; - - bundle->phys_type = 0; - for (dl = bundle->links; dl; dl = dl->next) - bundle_LinkAdded(bundle, dl); - - if ((bundle->phys_type & (PHYS_DEDICATED|PHYS_DDIAL)) == bundle->phys_type) - timer_Stop(&bundle->idle.timer); -} - static struct datalink * bundle_DatalinkLinkout(struct bundle *bundle, struct datalink *dl) { @@ -1547,25 +1566,28 @@ bundle_SetMode(struct bundle *bundle, struct datalink *dl, int mode) if (omode == mode) return 1; - if (mode == PHYS_AUTO && !(bundle->phys_type & PHYS_AUTO)) - /* Changing to demand-dial mode */ + if (mode == PHYS_AUTO && !(bundle->phys_type.all & PHYS_AUTO)) + /* First auto link */ if (bundle->ncp.ipcp.peer_ip.s_addr == INADDR_ANY) { - log_Printf(LogWARN, "You must `set ifaddr' before changing mode to %s\n", - mode2Nam(mode)); + log_Printf(LogWARN, "You must `set ifaddr' or `open' before" + " changing mode to %s\n", mode2Nam(mode)); return 0; } if (!datalink_SetMode(dl, mode)) return 0; - if (mode == PHYS_AUTO && !(bundle->phys_type & PHYS_AUTO)) + if (mode == PHYS_AUTO && !(bundle->phys_type.all & PHYS_AUTO) && + bundle->phase != PHASE_NETWORK) + /* First auto link, we need an interface */ ipcp_InterfaceUp(&bundle->ncp.ipcp); /* Regenerate phys_type and adjust autoload & idle timers */ bundle_LinksRemoved(bundle); - if (omode == PHYS_AUTO && !(bundle->phys_type & PHYS_AUTO)) - /* Changing from demand-dial mode */ + if (omode == PHYS_AUTO && !(bundle->phys_type.all & PHYS_AUTO) && + bundle->phase != PHASE_NETWORK) + /* No auto links left */ ipcp_CleanInterface(&bundle->ncp.ipcp); return 1; diff --git a/usr.sbin/ppp/bundle.h b/usr.sbin/ppp/bundle.h index d91237b..6a8042c 100644 --- a/usr.sbin/ppp/bundle.h +++ b/usr.sbin/ppp/bundle.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: bundle.h,v 1.5 1998/05/29 18:33:08 brian Exp $ + * $Id: bundle.h,v 1.6 1998/06/06 20:50:56 brian Exp $ */ #define PHASE_DEAD 0 /* Link is dead */ @@ -70,7 +70,11 @@ struct bundle { int routing_seq; /* The current routing sequence number */ u_int phase; /* Curent phase */ - int phys_type; /* Union of all physical::type's */ + + struct { + int all; /* Union of all physical::type's */ + int open; /* Union of all open physical::type's */ + } phys_type; unsigned CleaningUp : 1; /* Going to exit.... */ diff --git a/usr.sbin/ppp/command.c b/usr.sbin/ppp/command.c index eb0a7d0..bb04bf5 100644 --- a/usr.sbin/ppp/command.c +++ b/usr.sbin/ppp/command.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: command.c,v 1.138 1998/06/08 20:23:44 brian Exp $ + * $Id: command.c,v 1.139 1998/06/10 00:16:06 brian Exp $ * */ #include <sys/types.h> @@ -124,7 +124,7 @@ #define NEG_DNS 50 const char Version[] = "2.0-beta"; -const char VersionDate[] = "$Date: 1998/06/08 20:23:44 $"; +const char VersionDate[] = "$Date: 1998/06/10 00:16:06 $"; static int ShowCommand(struct cmdargs const *); static int TerminalCommand(struct cmdargs const *); @@ -265,7 +265,7 @@ LoadCommand(struct cmdargs const *arg) else name = "default"; - if (!system_IsValid(name, arg->prompt, arg->bundle->phys_type)) { + if (!system_IsValid(name, arg->prompt, arg->bundle->phys_type.all)) { log_Printf(LogERROR, "%s: Label not allowed\n", name); return 1; } else { @@ -298,7 +298,7 @@ DialCommand(struct cmdargs const *arg) if ((arg->cx && !(arg->cx->physical->type & (PHYS_INTERACTIVE|PHYS_AUTO))) || (!arg->cx && - (arg->bundle->phys_type & ~(PHYS_INTERACTIVE|PHYS_AUTO)))) { + (arg->bundle->phys_type.all & ~(PHYS_INTERACTIVE|PHYS_AUTO)))) { log_Printf(LogWARN, "Manual dial is only available for auto and" " interactive links\n"); return 1; @@ -1141,7 +1141,7 @@ SetInterfaceAddr(struct cmdargs const *arg) } if (hisaddr && !ipcp_UseHisaddr(arg->bundle, hisaddr, - arg->bundle->phys_type & PHYS_AUTO)) + arg->bundle->phys_type.all & PHYS_AUTO)) return 4; return 0; diff --git a/usr.sbin/ppp/datalink.c b/usr.sbin/ppp/datalink.c index a754c75..06aa739 100644 --- a/usr.sbin/ppp/datalink.c +++ b/usr.sbin/ppp/datalink.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: datalink.c,v 1.6 1998/05/28 23:15:33 brian Exp $ + * $Id: datalink.c,v 1.7 1998/05/29 18:32:10 brian Exp $ */ #include <sys/types.h> @@ -509,6 +509,7 @@ datalink_LayerDown(void *v, struct fsm *fp) peerid_Init(&dl->peer); fsm_Down(&dl->physical->link.ccp.fsm); fsm_Close(&dl->physical->link.ccp.fsm); + datalink_NewState(dl, DATALINK_LCP); /* before parent TLD */ (*dl->parent->LayerDown)(dl->parent->object, fp); /* fall through */ diff --git a/usr.sbin/ppp/ipcp.c b/usr.sbin/ppp/ipcp.c index e7ce60b..65e975b 100644 --- a/usr.sbin/ppp/ipcp.c +++ b/usr.sbin/ppp/ipcp.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: ipcp.c,v 1.52 1998/05/23 22:24:39 brian Exp $ + * $Id: ipcp.c,v 1.53 1998/05/29 18:32:11 brian Exp $ * * TODO: * o More RFC1772 backwoard compatibility @@ -685,7 +685,7 @@ IpcpLayerDown(struct fsm *fp) system_Select(fp->bundle, "MYADDR", LINKDOWNFILE, NULL); } - if (!(ipcp->fsm.bundle->phys_type & PHYS_AUTO)) + if (!(ipcp->fsm.bundle->phys_type.all & PHYS_AUTO)) ipcp_CleanInterface(ipcp); } |