Various fixes to make leased line operation more robust. On lcp_up, start
to negotiate from scratch. Make leased lines survive being put into loopback mode. Bits and pieces and ideas taken from PRs 11238 and 21771. Make it a module so that it can be kldloaded. Whitespace cleanup. (Can be ignored with "cvs diff -b".) PR: 11238 and 21771 (bits and pieces)
This commit is contained in:
parent
9b88faecd3
commit
b4fbe18794
@ -38,6 +38,7 @@
|
||||
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/syslog.h>
|
||||
@ -417,8 +418,29 @@ static const struct cp *cps[IDX_COUNT] = {
|
||||
&chap, /* IDX_CHAP */
|
||||
};
|
||||
|
||||
static int
|
||||
sppp_modevent(module_t mod, int type, void *unused)
|
||||
{
|
||||
switch (type) {
|
||||
case MOD_LOAD:
|
||||
break;
|
||||
case MOD_UNLOAD:
|
||||
return EACCES;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static moduledata_t spppmod = {
|
||||
"sppp",
|
||||
sppp_modevent,
|
||||
0
|
||||
};
|
||||
MODULE_VERSION(sppp, 1);
|
||||
DECLARE_MODULE(sppp, spppmod, SI_SUB_DRIVERS, SI_ORDER_ANY);
|
||||
|
||||
/*
|
||||
/*
|
||||
* Exported functions, comprising our interface to the lower layer.
|
||||
*/
|
||||
|
||||
@ -430,7 +452,6 @@ sppp_input(struct ifnet *ifp, struct mbuf *m)
|
||||
{
|
||||
struct ppp_header *h;
|
||||
struct ifqueue *inq = 0;
|
||||
int s;
|
||||
struct sppp *sp = (struct sppp *)ifp;
|
||||
int debug = ifp->if_flags & IFF_DEBUG;
|
||||
|
||||
@ -647,7 +668,7 @@ sppp_output(struct ifnet *ifp, struct mbuf *m,
|
||||
* become invalid. So we
|
||||
* - don't let packets with src ip addr 0 thru
|
||||
* - we flag TCP packets with src ip 0 as an error
|
||||
*/
|
||||
*/
|
||||
|
||||
if(ip->ip_src.s_addr == INADDR_ANY) /* -hm */
|
||||
{
|
||||
@ -658,7 +679,7 @@ sppp_output(struct ifnet *ifp, struct mbuf *m,
|
||||
else
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Put low delay, telnet, rlogin and ftp control packets
|
||||
* in front of the queue.
|
||||
@ -786,8 +807,9 @@ sppp_attach(struct ifnet *ifp)
|
||||
#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 = 32;
|
||||
sp->pp_fastq.ifq_maxlen = 32;
|
||||
sp->pp_cpq.ifq_maxlen = 20;
|
||||
sp->pp_loopcnt = 0;
|
||||
sp->pp_alivecnt = 0;
|
||||
sp->pp_seq = 0;
|
||||
@ -948,7 +970,7 @@ sppp_ioctl(struct ifnet *ifp, IOCTL_CMD_T cmd, void *data)
|
||||
}
|
||||
|
||||
if (going_down) {
|
||||
if (sp->pp_mode != IFF_CISCO)
|
||||
if (sp->pp_mode != IFF_CISCO)
|
||||
lcp.Close(sp);
|
||||
else if (sp->pp_tlf)
|
||||
(sp->pp_tlf)(sp);
|
||||
@ -958,7 +980,7 @@ sppp_ioctl(struct ifnet *ifp, IOCTL_CMD_T cmd, void *data)
|
||||
}
|
||||
|
||||
if (going_up) {
|
||||
if (sp->pp_mode != IFF_CISCO)
|
||||
if (sp->pp_mode != IFF_CISCO)
|
||||
lcp.Close(sp);
|
||||
sp->pp_mode = newmode;
|
||||
if (sp->pp_mode == 0) {
|
||||
@ -1017,8 +1039,7 @@ sppp_ioctl(struct ifnet *ifp, IOCTL_CMD_T cmd, void *data)
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/*
|
||||
* Cisco framing implementation.
|
||||
*/
|
||||
|
||||
@ -1115,7 +1136,7 @@ sppp_cisco_send(struct sppp *sp, int type, long par1, long par2)
|
||||
#if defined(__FreeBSD__) && __FreeBSD__ >= 3
|
||||
getmicrouptime(&tv);
|
||||
#endif
|
||||
|
||||
|
||||
MGETHDR (m, M_DONTWAIT, MT_DATA);
|
||||
if (! m)
|
||||
return;
|
||||
@ -1151,7 +1172,7 @@ sppp_cisco_send(struct sppp *sp, int type, long par1, long par2)
|
||||
ifp->if_oerrors++;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* PPP protocol implementation.
|
||||
*/
|
||||
|
||||
@ -1260,6 +1281,16 @@ sppp_cp_input(const struct cp *cp, struct sppp *sp, struct mbuf *m)
|
||||
/* fall through... */
|
||||
case STATE_ACK_SENT:
|
||||
case STATE_REQ_SENT:
|
||||
/*
|
||||
* sppp_cp_change_state() have the side effect of
|
||||
* restarting the timeouts. We want to avoid that
|
||||
* if the state don't change, otherwise we won't
|
||||
* ever timeout and resend a configuration request
|
||||
* that got lost.
|
||||
*/
|
||||
if (sp->state[cp->protoidx] == (rv ? STATE_ACK_SENT:
|
||||
STATE_REQ_SENT))
|
||||
break;
|
||||
sppp_cp_change_state(cp, sp, rv?
|
||||
STATE_ACK_SENT: STATE_REQ_SENT);
|
||||
break;
|
||||
@ -1355,6 +1386,13 @@ sppp_cp_input(const struct cp *cp, struct sppp *sp, struct mbuf *m)
|
||||
case STATE_REQ_SENT:
|
||||
case STATE_ACK_SENT:
|
||||
sp->rst_counter[cp->protoidx] = sp->lcp.max_configure;
|
||||
/*
|
||||
* Slow things down a bit if we think we might be
|
||||
* in loopback. Depend on the timeout to send the
|
||||
* next configuration request.
|
||||
*/
|
||||
if (sp->pp_loopcnt)
|
||||
break;
|
||||
(cp->scr)(sp);
|
||||
break;
|
||||
case STATE_OPENED:
|
||||
@ -1493,6 +1531,7 @@ sppp_cp_input(const struct cp *cp, struct sppp *sp, struct mbuf *m)
|
||||
ntohl (*(long*)(h+1)) == sp->lcp.magic) {
|
||||
/* Line loopback mode detected. */
|
||||
printf(SPP_FMT "loopback\n", SPP_ARGS(ifp));
|
||||
sp->pp_loopcnt = MAXALIVECNT * 5;
|
||||
if_down (ifp);
|
||||
sppp_qflush (&sp->pp_cpq);
|
||||
|
||||
@ -1721,7 +1760,7 @@ sppp_to_event(const struct cp *cp, struct sppp *sp)
|
||||
case STATE_STOPPING:
|
||||
sppp_cp_send(sp, cp->proto, TERM_REQ, ++sp->pp_seq,
|
||||
0, 0);
|
||||
TIMEOUT(cp->TO, (void *)sp, sp->lcp.timeout,
|
||||
TIMEOUT(cp->TO, (void *)sp, sp->lcp.timeout,
|
||||
sp->ch[cp->protoidx]);
|
||||
break;
|
||||
case STATE_REQ_SENT:
|
||||
@ -1762,12 +1801,13 @@ sppp_cp_change_state(const struct cp *cp, struct sppp *sp, int newstate)
|
||||
case STATE_REQ_SENT:
|
||||
case STATE_ACK_RCVD:
|
||||
case STATE_ACK_SENT:
|
||||
TIMEOUT(cp->TO, (void *)sp, sp->lcp.timeout,
|
||||
TIMEOUT(cp->TO, (void *)sp, sp->lcp.timeout,
|
||||
sp->ch[cp->protoidx]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
||||
/*
|
||||
*--------------------------------------------------------------------------*
|
||||
* *
|
||||
* The LCP implementation. *
|
||||
@ -1799,6 +1839,11 @@ sppp_lcp_up(struct sppp *sp)
|
||||
{
|
||||
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
|
||||
@ -1845,11 +1890,11 @@ sppp_lcp_down(struct sppp *sp)
|
||||
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
|
||||
@ -1911,10 +1956,14 @@ sppp_lcp_RCR(struct sppp *sp, struct lcp_header *h, int len)
|
||||
switch (*p) {
|
||||
case LCP_OPT_MAGIC:
|
||||
/* Magic number. */
|
||||
/* fall through, both are same length */
|
||||
if (len >= 6 && p[1] == 6)
|
||||
continue;
|
||||
if (debug)
|
||||
log(-1, "[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)
|
||||
log(-1, "[invalid] ");
|
||||
@ -1989,25 +2038,12 @@ sppp_lcp_RCR(struct sppp *sp, struct lcp_header *h, int len)
|
||||
nmagic = (u_long)p[2] << 24 |
|
||||
(u_long)p[3] << 16 | p[4] << 8 | p[5];
|
||||
if (nmagic != sp->lcp.magic) {
|
||||
sp->pp_loopcnt = 0;
|
||||
if (debug)
|
||||
log(-1, "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 && sp->pp_loopcnt < MAXALIVECNT*5)
|
||||
log(-1, "[glitch] ");
|
||||
++sp->pp_loopcnt;
|
||||
/*
|
||||
@ -2072,7 +2108,21 @@ sppp_lcp_RCR(struct sppp *sp, struct lcp_header *h, int len)
|
||||
rlen += p[1];
|
||||
}
|
||||
if (rlen) {
|
||||
if (++sp->fail_counter[IDX_LCP] >= sp->lcp.max_failure) {
|
||||
/*
|
||||
* Local and remote magics equal -- loopback?
|
||||
*/
|
||||
if (sp->pp_loopcnt >= MAXALIVECNT*5) {
|
||||
if (sp->pp_loopcnt == MAXALIVECNT*5)
|
||||
printf (SPP_FMT "loopback\n",
|
||||
SPP_ARGS(ifp));
|
||||
if (ifp->if_flags & IFF_UP) {
|
||||
if_down(ifp);
|
||||
sppp_qflush(&sp->pp_cpq);
|
||||
/* XXX ? */
|
||||
lcp.Down(sp);
|
||||
lcp.Up(sp);
|
||||
}
|
||||
} else if (++sp->fail_counter[IDX_LCP] >= sp->lcp.max_failure) {
|
||||
if (debug)
|
||||
log(-1, " max_failure (%d) exceeded, "
|
||||
"send conf-rej\n",
|
||||
@ -2083,7 +2133,6 @@ sppp_lcp_RCR(struct sppp *sp, struct lcp_header *h, int len)
|
||||
log(-1, " send conf-nak\n");
|
||||
sppp_cp_send (sp, PPP_LCP, CONF_NAK, h->ident, rlen, buf);
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
if (debug)
|
||||
log(-1, " send conf-ack\n");
|
||||
@ -2440,7 +2489,8 @@ sppp_lcp_check_and_close(struct sppp *sp)
|
||||
|
||||
lcp.Close(sp);
|
||||
}
|
||||
/*
|
||||
|
||||
/*
|
||||
*--------------------------------------------------------------------------*
|
||||
* *
|
||||
* The IPCP implementation. *
|
||||
@ -2604,7 +2654,7 @@ sppp_ipcp_RCR(struct sppp *sp, struct lcp_header *h, int len)
|
||||
(hisaddr == 1 && desiredaddr != 0)) {
|
||||
/*
|
||||
* Peer's address is same as our value,
|
||||
* or we have set it to 0.0.0.1 to
|
||||
* or we have set it to 0.0.0.1 to
|
||||
* indicate that we do not really care,
|
||||
* this is agreeable. Gonna conf-ack
|
||||
* it.
|
||||
@ -2834,8 +2884,7 @@ sppp_ipcp_scr(struct sppp *sp)
|
||||
sppp_cp_send(sp, PPP_IPCP, CONF_REQ, sp->confid[IDX_IPCP], i, &opt);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/*
|
||||
*--------------------------------------------------------------------------*
|
||||
* *
|
||||
* The CHAP implementation. *
|
||||
@ -2965,7 +3014,7 @@ sppp_chap_input(struct sppp *sp, struct mbuf *m)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (debug) {
|
||||
log(LOG_DEBUG,
|
||||
SPP_FMT "chap input <%s id=0x%x len=%d name=",
|
||||
@ -3074,7 +3123,7 @@ sppp_chap_input(struct sppp *sp, struct mbuf *m)
|
||||
sppp_print_string(sp->hisauth.name,
|
||||
sppp_strnlen(sp->hisauth.name, AUTHNAMELEN));
|
||||
log(-1, "\n");
|
||||
}
|
||||
}
|
||||
if (debug) {
|
||||
log(LOG_DEBUG, SPP_FMT "chap input(%s) "
|
||||
"<%s id=0x%x len=%d name=",
|
||||
@ -3317,7 +3366,8 @@ sppp_chap_scr(struct sppp *sp)
|
||||
sp->myauth.name,
|
||||
0);
|
||||
}
|
||||
/*
|
||||
|
||||
/*
|
||||
*--------------------------------------------------------------------------*
|
||||
* *
|
||||
* The PAP implementation. *
|
||||
@ -3625,7 +3675,8 @@ sppp_pap_scr(struct sppp *sp)
|
||||
(size_t)pwdlen, sp->myauth.secret,
|
||||
0);
|
||||
}
|
||||
/*
|
||||
|
||||
/*
|
||||
* Random miscellaneous functions.
|
||||
*/
|
||||
|
||||
@ -3884,7 +3935,7 @@ sppp_set_ip_addr(struct sppp *sp, u_long src)
|
||||
si->sin_addr.s_addr = htonl(src);
|
||||
|
||||
/* add new route */
|
||||
error = rtinit(ifa, (int)RTM_ADD, RTF_HOST);
|
||||
error = rtinit(ifa, (int)RTM_ADD, RTF_HOST);
|
||||
if (debug && error)
|
||||
{
|
||||
log(LOG_DEBUG, SPP_FMT "sppp_set_ip_addr: rtinit ADD failed, error=%d",
|
||||
@ -3892,7 +3943,7 @@ sppp_set_ip_addr(struct sppp *sp, u_long src)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
sppp_params(struct sppp *sp, u_long cmd, void *data)
|
||||
@ -4024,7 +4075,7 @@ sppp_phase_network(struct sppp *sp)
|
||||
/* if no NCP is starting, all this was in vain, close down */
|
||||
sppp_lcp_check_and_close(sp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const char *
|
||||
sppp_cp_type_name(u_char type)
|
||||
|
Loading…
Reference in New Issue
Block a user