summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authorbrian <brian@FreeBSD.org>2001-06-18 14:59:36 +0000
committerbrian <brian@FreeBSD.org>2001-06-18 14:59:36 +0000
commit14263ff751db1d878bad974a406737533ea6b70c (patch)
tree5bb2d9ee08d5ff16a973109f6f61899430eeb81e /usr.sbin
parentfd0a00a7295105bd1c94ad22b13d090c15c702a4 (diff)
downloadFreeBSD-src-14263ff751db1d878bad974a406737533ea6b70c.zip
FreeBSD-src-14263ff751db1d878bad974a406737533ea6b70c.tar.gz
Handle hardware-imposed MTU/MRU limitations. PPPoE will no longer
allow MRU/MTU negotiations to exceed 1492. Add an optional ``max'' specifier to ``set m[rt]u'', ie. set mtu max 1480 Bump the ppp version number. Sponsored by: Monzoon Networks AG and FreeBSD Services Limited
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/ppp/atm.c1
-rw-r--r--usr.sbin/ppp/bundle.c21
-rw-r--r--usr.sbin/ppp/bundle.h2
-rw-r--r--usr.sbin/ppp/command.c77
-rw-r--r--usr.sbin/ppp/ether.c11
-rw-r--r--usr.sbin/ppp/exec.c1
-rw-r--r--usr.sbin/ppp/i4b.c1
-rw-r--r--usr.sbin/ppp/iface.c5
-rw-r--r--usr.sbin/ppp/iface.h1
-rw-r--r--usr.sbin/ppp/lcp.c79
-rw-r--r--usr.sbin/ppp/lcp.h3
-rw-r--r--usr.sbin/ppp/physical.c6
-rw-r--r--usr.sbin/ppp/physical.h2
-rw-r--r--usr.sbin/ppp/ppp.846
-rw-r--r--usr.sbin/ppp/ppp.8.m446
-rw-r--r--usr.sbin/ppp/route.c7
-rw-r--r--usr.sbin/ppp/tcp.c1
-rw-r--r--usr.sbin/ppp/tcpmss.c5
-rw-r--r--usr.sbin/ppp/tty.c1
-rw-r--r--usr.sbin/ppp/tun.c9
-rw-r--r--usr.sbin/ppp/udp.c1
21 files changed, 246 insertions, 80 deletions
diff --git a/usr.sbin/ppp/atm.c b/usr.sbin/ppp/atm.c
index 30ce98a..6d6aba9 100644
--- a/usr.sbin/ppp/atm.c
+++ b/usr.sbin/ppp/atm.c
@@ -122,6 +122,7 @@ atm_device2iov(struct device *d, struct iovec *iov, int *niov,
static const struct device baseatmdevice = {
ATM_DEVICE,
"atm",
+ 0,
{ CD_NOTREQUIRED, 0 },
NULL,
NULL,
diff --git a/usr.sbin/ppp/bundle.c b/usr.sbin/ppp/bundle.c
index f8d8ad6..7e48499 100644
--- a/usr.sbin/ppp/bundle.c
+++ b/usr.sbin/ppp/bundle.c
@@ -802,7 +802,6 @@ bundle_Create(const char *prefix, int type, int unit)
log_Printf(LogPHASE, "Using interface: %s\n", ifname);
bundle.bandwidth = 0;
- bundle.mtu = 1500;
bundle.routing_seq = 0;
bundle.phase = PHASE_DEAD;
bundle.CleaningUp = 0;
@@ -821,7 +820,6 @@ bundle_Create(const char *prefix, int type, int unit)
bundle.cfg.opt = OPT_SROUTES | OPT_IDCHECK | OPT_LOOPBACK | OPT_TCPMSSFIXUP |
OPT_THROUGHPUT | OPT_UTMP;
*bundle.cfg.label = '\0';
- bundle.cfg.mtu = DEF_MTU;
bundle.cfg.ifqueue = DEF_IFQUEUE;
bundle.cfg.choked.timeout = CHOKED_TIMEOUT;
bundle.phys_type.all = type;
@@ -1096,11 +1094,6 @@ bundle_ShowStatus(struct cmdargs const *arg)
prompt_Printf(arg->prompt, "\n");
} else
prompt_Printf(arg->prompt, "disabled\n");
- prompt_Printf(arg->prompt, " MTU: ");
- if (arg->bundle->cfg.mtu)
- prompt_Printf(arg->prompt, "%d\n", arg->bundle->cfg.mtu);
- else
- prompt_Printf(arg->prompt, "unspecified\n");
prompt_Printf(arg->prompt, " sendpipe: ");
if (arg->bundle->ncp.ipcp.cfg.sendpipe > 0)
@@ -1826,7 +1819,7 @@ bundle_CalculateBandwidth(struct bundle *bundle)
int sp;
bundle->bandwidth = 0;
- bundle->mtu = 0;
+ bundle->iface->mtu = 0;
for (dl = bundle->links; dl; dl = dl->next)
if (dl->state == DATALINK_OPEN) {
if ((sp = dl->mp.bandwidth) == 0 &&
@@ -1836,7 +1829,7 @@ bundle_CalculateBandwidth(struct bundle *bundle)
else
bundle->bandwidth += sp;
if (!bundle->ncp.mp.active) {
- bundle->mtu = dl->physical->link.lcp.his_mru;
+ bundle->iface->mtu = dl->physical->link.lcp.his_mru;
break;
}
}
@@ -1845,16 +1838,16 @@ bundle_CalculateBandwidth(struct bundle *bundle)
bundle->bandwidth = 115200; /* Shrug */
if (bundle->ncp.mp.active)
- bundle->mtu = bundle->ncp.mp.peer_mrru;
- else if (!bundle->mtu)
- bundle->mtu = 1500;
+ bundle->iface->mtu = bundle->ncp.mp.peer_mrru;
+ else if (!bundle->iface->mtu)
+ bundle->iface->mtu = DEF_MRU;
#ifndef NORADIUS
if (bundle->radius.valid && bundle->radius.mtu &&
- bundle->radius.mtu < bundle->mtu) {
+ bundle->radius.mtu < bundle->iface->mtu) {
log_Printf(LogLCP, "Reducing MTU to radius value %lu\n",
bundle->radius.mtu);
- bundle->mtu = bundle->radius.mtu;
+ bundle->iface->mtu = bundle->radius.mtu;
}
#endif
diff --git a/usr.sbin/ppp/bundle.h b/usr.sbin/ppp/bundle.h
index 2953631..de8cb13 100644
--- a/usr.sbin/ppp/bundle.h
+++ b/usr.sbin/ppp/bundle.h
@@ -73,7 +73,6 @@ struct bundle {
} dev;
u_long bandwidth; /* struct tuninfo speed */
- int mtu; /* struct tuninfo MTU */
struct iface *iface; /* Interface information */
int routing_seq; /* The current routing sequence number */
@@ -103,7 +102,6 @@ struct bundle {
} auth;
unsigned opt; /* Uses OPT_ bits from above */
char label[50]; /* last thing `load'ed */
- u_short mtu; /* Required interface MTU */
u_short ifqueue; /* Interface queue size */
struct {
diff --git a/usr.sbin/ppp/command.c b/usr.sbin/ppp/command.c
index 4f205f5..62415b1 100644
--- a/usr.sbin/ppp/command.c
+++ b/usr.sbin/ppp/command.c
@@ -159,7 +159,7 @@
#define NEG_MPPE 54
#define NEG_CHAP81 55
-const char Version[] = "2.3.1";
+const char Version[] = "2.3.2";
static int ShowCommand(struct cmdargs const *);
static int TerminalCommand(struct cmdargs const *);
@@ -1489,6 +1489,7 @@ SetVariable(struct cmdargs const *arg)
{
long long_val, param = (long)arg->cmd->args;
int mode, dummyint, f, first;
+ u_short *change;
const char *argp;
struct datalink *cx = arg->cx; /* LOCAL_CX uses this */
const char *err = NULL;
@@ -1678,9 +1679,36 @@ SetVariable(struct cmdargs const *arg)
break;
case VAR_MRU:
- long_val = atol(argp);
+ switch(arg->argc - arg->argn) {
+ case 1:
+ if (argp[strspn(argp, "0123456789")] != '\0')
+ return -1;
+ case 0:
+ long_val = atol(argp);
+ change = &l->lcp.cfg.mru;
+ if (long_val > l->lcp.cfg.max_mru) {
+ log_Printf(LogWARN, "MRU %ld: too large - max set to %d\n", long_val,
+ l->lcp.cfg.max_mru);
+ return 1;
+ }
+ break;
+ case 2:
+ if (strcasecmp(argp, "max") && strcasecmp(argp, "maximum"))
+ return -1;
+ long_val = atol(arg->argv[arg->argn + 1]);
+ change = &l->lcp.cfg.max_mru;
+ if (long_val > MAX_MRU) {
+ log_Printf(LogWARN, "MRU %ld: too large - maximum is %d\n", long_val,
+ MAX_MRU);
+ return 1;
+ }
+ break;
+ default:
+ return -1;
+ }
+
if (long_val == 0)
- l->lcp.cfg.mru = DEF_MRU;
+ *change = DEF_MRU;
else if (long_val < MIN_MRU) {
log_Printf(LogWARN, "MRU %ld: too small - min %d\n", long_val, MIN_MRU);
return 1;
@@ -1688,11 +1716,40 @@ SetVariable(struct cmdargs const *arg)
log_Printf(LogWARN, "MRU %ld: too big - max %d\n", long_val, MAX_MRU);
return 1;
} else
- l->lcp.cfg.mru = long_val;
+ *change = long_val;
+ if (l->lcp.cfg.mru > *change)
+ l->lcp.cfg.mru = *change;
break;
case VAR_MTU:
- long_val = atol(argp);
+ switch(arg->argc - arg->argn) {
+ case 1:
+ if (argp[strspn(argp, "0123456789")] != '\0')
+ return -1;
+ case 0:
+ long_val = atol(argp);
+ change = &l->lcp.cfg.mtu;
+ if (long_val > l->lcp.cfg.max_mtu) {
+ log_Printf(LogWARN, "MTU %ld: too large - max set to %d\n", long_val,
+ l->lcp.cfg.max_mtu);
+ return 1;
+ }
+ break;
+ case 2:
+ if (strcasecmp(argp, "max") && strcasecmp(argp, "maximum"))
+ return -1;
+ long_val = atol(arg->argv[arg->argn + 1]);
+ change = &l->lcp.cfg.max_mtu;
+ if (long_val > MAX_MTU) {
+ log_Printf(LogWARN, "MTU %ld: too large - maximum is %d\n", long_val,
+ MAX_MTU);
+ return 1;
+ }
+ break;
+ default:
+ return -1;
+ }
+
if (long_val && long_val < MIN_MTU) {
log_Printf(LogWARN, "MTU %ld: too small - min %d\n", long_val, MIN_MTU);
return 1;
@@ -1700,7 +1757,9 @@ SetVariable(struct cmdargs const *arg)
log_Printf(LogWARN, "MTU %ld: too big - max %d\n", long_val, MAX_MTU);
return 1;
} else
- arg->bundle->cfg.mtu = long_val;
+ *change = long_val;
+ if (l->lcp.cfg.mtu > *change)
+ l->lcp.cfg.mtu = *change;
break;
case VAR_OPENMODE:
@@ -2064,9 +2123,9 @@ static struct cmdtab const SetCommands[] = {
{"mrru", NULL, SetVariable, LOCAL_AUTH, "MRRU value",
"set mrru value", (const void *)VAR_MRRU},
{"mru", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX_OPT,
- "MRU value", "set mru value", (const void *)VAR_MRU},
- {"mtu", NULL, SetVariable, LOCAL_AUTH,
- "interface MTU value", "set mtu value", (const void *)VAR_MTU},
+ "MRU value", "set mru [max[imum]] [value]", (const void *)VAR_MRU},
+ {"mtu", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX,
+ "interface MTU value", "set mtu [max[imum]] [value]", (const void *)VAR_MTU},
{"nbns", NULL, SetVariable, LOCAL_AUTH, "NetBIOS Name Server",
"set nbns pri-addr [sec-addr]", (const void *)VAR_NBNS},
{"openmode", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX, "open mode",
diff --git a/usr.sbin/ppp/ether.c b/usr.sbin/ppp/ether.c
index 0af8ff5..1e8d53c 100644
--- a/usr.sbin/ppp/ether.c
+++ b/usr.sbin/ppp/ether.c
@@ -285,6 +285,7 @@ ether_AwaitCarrier(struct physical *p)
static const struct device baseetherdevice = {
ETHER_DEVICE,
"ether",
+ 1492,
{ CD_REQUIRED, DEF_ETHERCDDELAY },
ether_AwaitCarrier,
ether_RemoveFromSet,
@@ -675,16 +676,6 @@ ether_Create(struct physical *p)
if (dev) {
physical_SetupStack(p, dev->dev.name, PHYSICAL_FORCE_SYNCNOACF);
- /* Moan about (and fix) invalid LCP configurations */
- if (p->link.lcp.cfg.mru > 1492) {
- log_Printf(LogWARN, "%s: Reducing MRU to 1492\n", p->link.name);
- p->link.lcp.cfg.mru = 1492;
- }
- if (p->dl->bundle->cfg.mtu > 1492) {
- log_Printf(LogWARN, "%s: Reducing MTU to 1492\n", p->link.name);
- p->dl->bundle->cfg.mtu = 1492;
- }
-
if (path != NULL) {
/* Mark the interface as UP if it's not already */
diff --git a/usr.sbin/ppp/exec.c b/usr.sbin/ppp/exec.c
index 1ca9665..2522653 100644
--- a/usr.sbin/ppp/exec.c
+++ b/usr.sbin/ppp/exec.c
@@ -68,6 +68,7 @@
static struct device execdevice = {
EXEC_DEVICE,
"exec",
+ 0,
{ CD_NOTREQUIRED, 0 },
NULL,
NULL,
diff --git a/usr.sbin/ppp/i4b.c b/usr.sbin/ppp/i4b.c
index fe82fae..855bfce 100644
--- a/usr.sbin/ppp/i4b.c
+++ b/usr.sbin/ppp/i4b.c
@@ -293,6 +293,7 @@ i4b_device2iov(struct device *d, struct iovec *iov, int *niov,
static struct device basei4bdevice = {
I4B_DEVICE,
"i4b",
+ 0,
{ CD_REQUIRED, DEF_I4BCDDELAY },
i4b_AwaitCarrier,
NULL,
diff --git a/usr.sbin/ppp/iface.c b/usr.sbin/ppp/iface.c
index 5384340..9676b38 100644
--- a/usr.sbin/ppp/iface.c
+++ b/usr.sbin/ppp/iface.c
@@ -163,8 +163,9 @@ iface_Create(const char *name)
return NULL;
}
iface->name = strdup(name);
- iface->flags = ifm->ifm_flags;
iface->index = ifm->ifm_index;
+ iface->flags = ifm->ifm_flags;
+ iface->mtu = 0;
iface->in_addrs = 0;
iface->in_addr = NULL;
}
@@ -540,7 +541,7 @@ iface_Show(struct cmdargs const *arg)
if_flags[f].value);
flags &= ~if_flags[f].flag;
}
- prompt_Printf(arg->prompt, "> mtu %d has %d address%s:\n", arg->bundle->mtu,
+ prompt_Printf(arg->prompt, "> mtu %d has %d address%s:\n", iface->mtu,
iface->in_addrs, iface->in_addrs == 1 ? "" : "es");
for (f = 0; f < iface->in_addrs; f++) {
diff --git a/usr.sbin/ppp/iface.h b/usr.sbin/ppp/iface.h
index 6de1b50..d520e84 100644
--- a/usr.sbin/ppp/iface.h
+++ b/usr.sbin/ppp/iface.h
@@ -39,6 +39,7 @@ struct iface {
char *name; /* Interface name (malloc'd) */
int index; /* Interface index */
int flags; /* Interface flags (IFF_*) */
+ int mtu; /* struct tuninfo MTU */
int in_addrs; /* How many in_addr's */
struct iface_addr *in_addr; /* Array of addresses (malloc'd) */
diff --git a/usr.sbin/ppp/lcp.c b/usr.sbin/ppp/lcp.c
index f4bfee4..25c893b 100644
--- a/usr.sbin/ppp/lcp.c
+++ b/usr.sbin/ppp/lcp.c
@@ -177,7 +177,13 @@ lcp_ReportStatus(struct cmdargs const *arg)
(u_long)lcp->want_magic, lcp->want_mrru,
lcp->want_shortseq ? "on" : "off", lcp->my_reject);
- prompt_Printf(arg->prompt, "\n Defaults: MRU = %d, ", lcp->cfg.mru);
+ prompt_Printf(arg->prompt, "\n Defaults: MRU = %d (max %d), ",
+ lcp->cfg.mru, lcp->cfg.max_mru);
+ if (lcp->cfg.mtu)
+ prompt_Printf(arg->prompt, "MTU = %d (max %d), ",
+ lcp->cfg.mtu, lcp->cfg.max_mtu);
+ else
+ prompt_Printf(arg->prompt, "MTU = any (max %d), ", lcp->cfg.max_mtu);
prompt_Printf(arg->prompt, "ACCMAP = %08lx\n", (u_long)lcp->cfg.accmap);
prompt_Printf(arg->prompt, " LQR period = %us, ",
lcp->cfg.lqrperiod);
@@ -241,6 +247,9 @@ lcp_Init(struct lcp *lcp, struct bundle *bundle, struct link *l,
bundle, l, parent, &lcp_Callbacks, lcp_TimerNames);
lcp->cfg.mru = DEF_MRU;
+ lcp->cfg.max_mru = MAX_MRU;
+ lcp->cfg.mtu = 0;
+ lcp->cfg.max_mtu = MAX_MTU;
lcp->cfg.accmap = 0;
lcp->cfg.openmode = 1;
lcp->cfg.lqrperiod = DEF_LQRPERIOD;
@@ -266,11 +275,12 @@ lcp_Init(struct lcp *lcp, struct bundle *bundle, struct link *l,
void
lcp_Setup(struct lcp *lcp, int openmode)
{
+ struct physical *p = link2physical(lcp->fsm.link);
+ int phmtu = p ? physical_DeviceMTU(p) : 0;
+
lcp->fsm.open_mode = openmode;
- lcp->his_mru = lcp->fsm.bundle->cfg.mtu;
- if (!lcp->his_mru || lcp->his_mru > DEF_MRU)
- lcp->his_mru = DEF_MRU;
+ lcp->his_mru = DEF_MRU;
lcp->his_mrru = 0;
lcp->his_magic = 0;
lcp->his_lqrperiod = 0;
@@ -281,13 +291,13 @@ lcp_Setup(struct lcp *lcp, int openmode)
lcp->his_shortseq = 0;
lcp->want_mru = lcp->cfg.mru;
+ if (phmtu && lcp->want_mru > phmtu)
+ lcp->want_mru = phmtu;
lcp->want_mrru = lcp->fsm.bundle->ncp.mp.cfg.mrru;
lcp->want_shortseq = IsEnabled(lcp->fsm.bundle->ncp.mp.cfg.shortseq) ? 1 : 0;
lcp->want_acfcomp = IsEnabled(lcp->cfg.acfcomp) ? 1 : 0;
if (lcp->fsm.parent) {
- struct physical *p = link2physical(lcp->fsm.link);
-
lcp->his_accmap = 0xffffffff;
lcp->want_accmap = lcp->cfg.accmap;
lcp->his_protocomp = 0;
@@ -592,15 +602,15 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type,
{
/* Deal with incoming PROTO_LCP */
struct lcp *lcp = fsm2lcp(fp);
- int type, length, sz, pos, op, callback_req;
+ int type, length, sz, pos, op, callback_req, mru_req;
u_int32_t magic, accmap;
- u_short mtu, mru, proto;
+ u_short mru, phmtu, proto;
struct lqrreq *req;
char request[20], desc[22];
struct mp *mp;
struct physical *p = link2physical(fp->link);
- sz = op = callback_req = 0;
+ sz = op = callback_req = mru_req = 0;
while (plen >= sizeof(struct fsmconfig)) {
type = *cp;
@@ -626,7 +636,13 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type,
/* Ignore his previous reject so that we REQ next time */
lcp->his_reject &= ~(1 << type);
- if (mru < MIN_MRU) {
+ if (mru > MAX_MRU) {
+ /* Push him down to MAX_MRU */
+ lcp->his_mrru = MAX_MRU;
+ memcpy(dec->nakend, cp, 2);
+ ua_htons(&lcp->his_mrru, dec->nakend + 2);
+ dec->nakend += 4;
+ } else if (mru < MIN_MRU) {
/* Push him up to MIN_MRU */
lcp->his_mrru = MIN_MRU;
memcpy(dec->nakend, cp, 2);
@@ -664,28 +680,41 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type,
break;
case TY_MRU:
+ mru_req = 1;
ua_ntohs(cp + 2, &mru);
log_Printf(LogLCP, "%s %d\n", request, mru);
switch (mode_type) {
case MODE_REQ:
- mtu = lcp->fsm.bundle->cfg.mtu;
- if (mru < MIN_MRU || (!lcp->want_mrru && mru < mtu)) {
+ phmtu = p ? physical_DeviceMTU(p) : 0;
+ if (phmtu && mru > phmtu) {
+ lcp->his_mru = lcp->cfg.mtu ? lcp->cfg.mtu : phmtu;
+ memcpy(dec->nakend, cp, 2);
+ ua_htons(&lcp->his_mru, dec->nakend + 2);
+ dec->nakend += 4;
+ } if (mru > lcp->cfg.max_mtu) {
+ lcp->his_mru = lcp->cfg.mtu ? lcp->cfg.mtu : lcp->cfg.max_mtu;
+ memcpy(dec->nakend, cp, 2);
+ ua_htons(&lcp->his_mru, dec->nakend + 2);
+ dec->nakend += 4;
+ } else if (mru < MIN_MRU || mru < lcp->cfg.mtu) {
/* Push him up to MTU or MIN_MRU */
- lcp->his_mru = mru < mtu ? mtu : MIN_MRU;
+ lcp->his_mru = mru < lcp->cfg.mtu ? lcp->cfg.mtu : MIN_MRU;
memcpy(dec->nakend, cp, 2);
ua_htons(&lcp->his_mru, dec->nakend + 2);
dec->nakend += 4;
} else {
- lcp->his_mru = mtu ? mtu : mru;
+ lcp->his_mru = lcp->cfg.mtu ? lcp->cfg.mtu : mru;
memcpy(dec->ackend, cp, 4);
dec->ackend += 4;
}
break;
case MODE_NAK:
- if (mru > MAX_MRU)
- lcp->want_mru = MAX_MRU;
- else if (mru < MIN_MRU)
+ if (mru > lcp->cfg.max_mru) {
+ lcp->want_mru = lcp->cfg.max_mru;
+ if (p && lcp->want_mru > physical_DeviceMTU(p))
+ lcp->want_mru = physical_DeviceMTU(p);
+ } else if (mru < MIN_MRU)
lcp->want_mru = MIN_MRU;
else
lcp->want_mru = mru;
@@ -1217,6 +1246,22 @@ reqreject:
dec->nakend[-1] = 2; /* XXX: Silly ! */
}
}
+ if (mode_type == MODE_REQ && !mru_req) {
+ mru = DEF_MRU;
+ phmtu = p ? physical_DeviceMTU(p) : 0;
+ if (phmtu && mru > phmtu)
+ mru = phmtu;
+ if (mru > lcp->cfg.max_mtu)
+ mru = lcp->cfg.max_mtu;
+ if (mru < DEF_MRU) {
+ /* Don't let the peer use the default MRU */
+ lcp->his_mru = lcp->cfg.mtu && lcp->cfg.mtu < mru ? lcp->cfg.mtu : mru;
+ *dec->nakend++ = TY_MRU;
+ *dec->nakend++ = 4;
+ ua_htons(&lcp->his_mru, dec->nakend);
+ dec->nakend += 2;
+ }
+ }
if (dec->rejend != dec->rej) {
/* rejects are preferred */
dec->ackend = dec->ack;
diff --git a/usr.sbin/ppp/lcp.h b/usr.sbin/ppp/lcp.h
index e86e3be..3e0e8b2 100644
--- a/usr.sbin/ppp/lcp.h
+++ b/usr.sbin/ppp/lcp.h
@@ -82,6 +82,9 @@ struct lcp {
struct {
u_short mru; /* Preferred MRU value */
+ u_short max_mru; /* Preferred MRU value */
+ u_short mtu; /* Preferred MTU */
+ u_short max_mtu; /* Preferred MTU */
u_int32_t accmap; /* Initial ACCMAP value */
int openmode; /* when to start CFG REQs */
u_int32_t lqrperiod; /* LQR frequency (seconds) */
diff --git a/usr.sbin/ppp/physical.c b/usr.sbin/ppp/physical.c
index e426890..76937e7 100644
--- a/usr.sbin/ppp/physical.c
+++ b/usr.sbin/ppp/physical.c
@@ -758,6 +758,12 @@ physical_IsSync(struct physical *p)
return p->cfg.speed == 0;
}
+u_short
+physical_DeviceMTU(struct physical *p)
+{
+ return p->handler ? p->handler->mtu : 0;
+}
+
const char *physical_GetDevice(struct physical *p)
{
return p->name.full;
diff --git a/usr.sbin/ppp/physical.h b/usr.sbin/ppp/physical.h
index 90b8e7f..988b730 100644
--- a/usr.sbin/ppp/physical.h
+++ b/usr.sbin/ppp/physical.h
@@ -56,6 +56,7 @@ struct cd {
struct device {
int type;
const char *name;
+ u_short mtu;
struct cd cd;
int (*awaitcarrier)(struct physical *);
@@ -143,6 +144,7 @@ extern const char *physical_LockedDevice(struct physical *);
extern void physical_ChangedPid(struct physical *, pid_t);
extern int physical_IsSync(struct physical *);
+extern u_short physical_DeviceMTU(struct physical *);
extern const char *physical_GetDevice(struct physical *);
extern void physical_SetDeviceList(struct physical *, int, const char *const *);
extern void physical_SetDevice(struct physical *, const char *);
diff --git a/usr.sbin/ppp/ppp.8 b/usr.sbin/ppp/ppp.8
index acfd8fc..42743be 100644
--- a/usr.sbin/ppp/ppp.8
+++ b/usr.sbin/ppp/ppp.8
@@ -4917,32 +4917,60 @@ Setting this option enables Multi-link PPP negotiations, also known as
Multi-link Protocol or MP.
There is no default MRRU (Maximum Reconstructed Receive Unit) value.
If no argument is given, multi-link mode is disabled.
-.It set mru Op Ar value
+.It set mru Oo max Ns Oo imum Oc Oc Op Ar value
The default MRU (Maximum Receive Unit) is 1500.
If it is increased, the other side *may* increase its MTU.
-There is no point in decreasing the MRU to below the default as the
+In theory there is no point in decreasing the MRU to below the default as the
.Em PPP
-protocol *must* be able to accept packets of at least 1500 octets.
+protocol says implementations *must* be able to accept packets of at
+least 1500 octets.
+.Pp
+If the
+.Dq maximum
+keyword is used,
+.Nm
+will refuse to negotiate a higher value.
+The maximum MRU can be set to 2048 at most.
+Setting a maximum of less than 1500 violates the
+.Em PPP
+rfc, but may sometimes be necessary.
+For example,
+.Em PPPoE
+imposes a maximum of 1492 due to hardware limitations.
+.Pp
If no argument is given, 1500 is assumed.
-.It set mtu Op Ar value
+A value must be given when
+.Dq maximum
+is specified.
+.It set mtu Oo max Ns Oo imum Oc Oc Op Ar value
The default MTU is 1500.
At negotiation time,
.Nm
-will accept whatever MRU or MRRU that the peer wants (assuming it's
-not less than 296 bytes).
+will accept whatever MRU the peer requests (assuming it's
+not less than 296 bytes or greater than the assigned maximum).
If the MTU is set,
.Nm
-will not accept MRU/MRRU values less than
+will not accept MRU values less than
.Ar value .
-When negotiations are complete, the MTU is assigned to the interface, even
-if the peer requested a higher value MRU/MRRU.
+When negotiations are complete, the MTU is used when writing to the
+interface, even if the peer requested a higher value MRU.
This can be useful for
limiting your packet size (giving better bandwidth sharing at the expense
of more header data).
.Pp
+If the
+.Dq maximum
+keyword is used,
+.Nm
+will refuse to negotiate a higher value.
+The maximum MTU can be set to 2048 at most.
+.Pp
If no
.Ar value
is given, 1500, or whatever the peer asks for is used.
+A value must be given when
+.Dq maximum
+is specified.
.It set nbns Op Ar x.x.x.x Op Ar y.y.y.y
This option allows the setting of the Microsoft NetBIOS name server
values to be returned at the peers request.
diff --git a/usr.sbin/ppp/ppp.8.m4 b/usr.sbin/ppp/ppp.8.m4
index acfd8fc..42743be 100644
--- a/usr.sbin/ppp/ppp.8.m4
+++ b/usr.sbin/ppp/ppp.8.m4
@@ -4917,32 +4917,60 @@ Setting this option enables Multi-link PPP negotiations, also known as
Multi-link Protocol or MP.
There is no default MRRU (Maximum Reconstructed Receive Unit) value.
If no argument is given, multi-link mode is disabled.
-.It set mru Op Ar value
+.It set mru Oo max Ns Oo imum Oc Oc Op Ar value
The default MRU (Maximum Receive Unit) is 1500.
If it is increased, the other side *may* increase its MTU.
-There is no point in decreasing the MRU to below the default as the
+In theory there is no point in decreasing the MRU to below the default as the
.Em PPP
-protocol *must* be able to accept packets of at least 1500 octets.
+protocol says implementations *must* be able to accept packets of at
+least 1500 octets.
+.Pp
+If the
+.Dq maximum
+keyword is used,
+.Nm
+will refuse to negotiate a higher value.
+The maximum MRU can be set to 2048 at most.
+Setting a maximum of less than 1500 violates the
+.Em PPP
+rfc, but may sometimes be necessary.
+For example,
+.Em PPPoE
+imposes a maximum of 1492 due to hardware limitations.
+.Pp
If no argument is given, 1500 is assumed.
-.It set mtu Op Ar value
+A value must be given when
+.Dq maximum
+is specified.
+.It set mtu Oo max Ns Oo imum Oc Oc Op Ar value
The default MTU is 1500.
At negotiation time,
.Nm
-will accept whatever MRU or MRRU that the peer wants (assuming it's
-not less than 296 bytes).
+will accept whatever MRU the peer requests (assuming it's
+not less than 296 bytes or greater than the assigned maximum).
If the MTU is set,
.Nm
-will not accept MRU/MRRU values less than
+will not accept MRU values less than
.Ar value .
-When negotiations are complete, the MTU is assigned to the interface, even
-if the peer requested a higher value MRU/MRRU.
+When negotiations are complete, the MTU is used when writing to the
+interface, even if the peer requested a higher value MRU.
This can be useful for
limiting your packet size (giving better bandwidth sharing at the expense
of more header data).
.Pp
+If the
+.Dq maximum
+keyword is used,
+.Nm
+will refuse to negotiate a higher value.
+The maximum MTU can be set to 2048 at most.
+.Pp
If no
.Ar value
is given, 1500, or whatever the peer asks for is used.
+A value must be given when
+.Dq maximum
+is specified.
.It set nbns Op Ar x.x.x.x Op Ar y.y.y.y
This option allows the setting of the Microsoft NetBIOS name server
values to be returned at the peers request.
diff --git a/usr.sbin/ppp/route.c b/usr.sbin/ppp/route.c
index 2b63253..54f585a 100644
--- a/usr.sbin/ppp/route.c
+++ b/usr.sbin/ppp/route.c
@@ -577,9 +577,8 @@ route_UpdateMTU(struct bundle *bundle)
log_Printf(LogTCPIP, "route_UpdateMTU: Netif: %d (%s), dst %s, mtu %d\n",
rtm->rtm_index, Index2Nam(rtm->rtm_index),
inet_ntoa(((struct sockaddr_in *)sa[RTAX_DST])->sin_addr),
- bundle->mtu);
- rt_Update(bundle, in[RTAX_DST]->sin_addr,
- in[RTAX_GATEWAY]->sin_addr);
+ bundle->iface->mtu);
+ rt_Update(bundle, in[RTAX_DST]->sin_addr, in[RTAX_GATEWAY]->sin_addr);
}
}
@@ -890,7 +889,7 @@ rt_Update(struct bundle *bundle, struct in_addr dst, struct in_addr gw)
rtmes.m_rtm.rtm_inits |= RTV_RPIPE;
}
- rtmes.m_rtm.rtm_rmx.rmx_mtu = bundle->mtu;
+ rtmes.m_rtm.rtm_rmx.rmx_mtu = bundle->iface->mtu;
rtmes.m_rtm.rtm_inits |= RTV_MTU;
memset(&rtdata, '\0', sizeof rtdata);
diff --git a/usr.sbin/ppp/tcp.c b/usr.sbin/ppp/tcp.c
index b7482d1..567072a 100644
--- a/usr.sbin/ppp/tcp.c
+++ b/usr.sbin/ppp/tcp.c
@@ -100,6 +100,7 @@ tcp_OpenConnection(const char *name, char *host, char *port)
static struct device tcpdevice = {
TCP_DEVICE,
"tcp",
+ 0,
{ CD_NOTREQUIRED, 0 },
NULL,
NULL,
diff --git a/usr.sbin/ppp/tcpmss.c b/usr.sbin/ppp/tcpmss.c
index ed7ef46..f8debc8 100644
--- a/usr.sbin/ppp/tcpmss.c
+++ b/usr.sbin/ppp/tcpmss.c
@@ -28,6 +28,8 @@
#include <sys/param.h>
+#include <sys/socket.h>
+#include <net/route.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
@@ -54,6 +56,7 @@
#include "filter.h"
#include "descriptor.h"
#include "mp.h"
+#include "iface.h"
#ifndef NORADIUS
#include "radius.h"
#endif
@@ -93,7 +96,7 @@ tcpmss_LayerPush(struct bundle *bundle, struct link *l, struct mbuf *bp,
ntohs(pip->ip_len) == plen && hlen <= plen &&
plen - hlen >= sizeof(struct tcphdr))
MSSFixup((struct tcphdr *)(MBUF_CTOP(bp) + hlen), plen - hlen,
- MAXMSS(bundle->mtu));
+ MAXMSS(bundle->iface->mtu));
return bp;
}
diff --git a/usr.sbin/ppp/tty.c b/usr.sbin/ppp/tty.c
index 2727fec..773525c 100644
--- a/usr.sbin/ppp/tty.c
+++ b/usr.sbin/ppp/tty.c
@@ -333,6 +333,7 @@ tty_device2iov(struct device *d, struct iovec *iov, int *niov,
static struct device basettydevice = {
TTY_DEVICE,
"tty",
+ 0,
{ CD_VARIABLE, DEF_TTYCDDELAY },
tty_AwaitCarrier,
NULL,
diff --git a/usr.sbin/ppp/tun.c b/usr.sbin/ppp/tun.c
index f61f1f2..480e6c2 100644
--- a/usr.sbin/ppp/tun.c
+++ b/usr.sbin/ppp/tun.c
@@ -27,10 +27,12 @@
*/
#include <sys/param.h>
-#ifndef __FreeBSD__
+
#include <sys/socket.h> /* For IFF_ defines */
+#ifndef __FreeBSD__
#include <net/if.h> /* For IFF_ defines */
#endif
+#include <net/route.h>
#include <netinet/in.h>
#include <net/if_types.h>
#include <net/if_tun.h>
@@ -68,6 +70,7 @@
#include "ccp.h"
#include "link.h"
#include "mp.h"
+#include "iface.h"
#ifndef NORADIUS
#include "radius.h"
#endif
@@ -89,7 +92,7 @@ tun_configure(struct bundle *bundle)
}
sprintf(ifr.ifr_name, "tun%d", bundle->unit);
- ifr.ifr_mtu = bundle->mtu;
+ ifr.ifr_mtu = bundle->iface->mtu;
if (ioctl(s, SIOCSIFMTU, &ifr) < 0)
log_Printf(LogERROR, "tun_configure: ioctl(SIOCSIFMTU): %s\n",
strerror(errno));
@@ -100,7 +103,7 @@ tun_configure(struct bundle *bundle)
memset(&info, '\0', sizeof info);
info.type = IFT_PPP;
- info.mtu = bundle->mtu;
+ info.mtu = bundle->iface->mtu;
info.baudrate = bundle->bandwidth;
#ifdef __OpenBSD__
diff --git a/usr.sbin/ppp/udp.c b/usr.sbin/ppp/udp.c
index 6894e1e..8307a4a 100644
--- a/usr.sbin/ppp/udp.c
+++ b/usr.sbin/ppp/udp.c
@@ -154,6 +154,7 @@ udp_device2iov(struct device *d, struct iovec *iov, int *niov,
static const struct device baseudpdevice = {
UDP_DEVICE,
"udp",
+ 0,
{ CD_NOTREQUIRED, 0 },
NULL,
NULL,
OpenPOWER on IntegriCloud