On Fri, Jun 09, 2017 at 06:33:46PM +0200, Stefan Sperling wrote:
> This diff changes the way dynamic addresses are configured in sppp(4).
I was asked in private whether we could avoid a flag day which makes
it inconvenient to upgrade remote boxes only reachable over pppoe(4).
I see no harm in keeping the old magic working for now.
The new mechanism still works, and the goal of allowing more than one pppoe
instance per routing table does not conflict with temporary backwards compat.
So we would release 6.2 with support for both ways, and remove the old way
in 6.3 or later. This gives people some time for the transition.
This diff also contains doc updates requested by jmc@.
Index: sbin/ifconfig/ifconfig.8
===================================================================
RCS file: /cvs/src/sbin/ifconfig/ifconfig.8,v
retrieving revision 1.282
diff -u -p -r1.282 ifconfig.8
--- sbin/ifconfig/ifconfig.8 12 May 2017 15:11:02 -0000 1.282
+++ sbin/ifconfig/ifconfig.8 10 Jun 2017 07:08:01 -0000
@@ -1393,6 +1393,8 @@ Clear a previously set service name.
.Op Cm authkey Ar key
.Op Cm authname Ar name
.Op Cm authproto Ar proto
+.Op Oo Fl Oc Ns Cm dynaddr
+.Op Oo Fl Oc Ns Cm dyndest
.Op Oo Fl Oc Ns Cm peerflag Ar flag
.Op Cm peerkey Ar key
.Op Cm peername Ar name
@@ -1419,6 +1421,21 @@ The protocol name can be either
or
.Ql none .
In the latter case, authentication will be turned off.
+.It Cm dynaddr
+The local address will be changed to an address suggested by the peer.
+A deprecated way of achieving the same effect is setting the local address
+to 0.0.0.0.
+.It Cm -dynaddr
+Disable dynamic updates of the local address.
+This is the default.
+.It Cm dyndest
+The destination address will be changed to an address suggested by the peer.
+A deprecated way of achieving the same effect is setting the destination
+address to 0.0.0.1 (multiple SPPP interfaces configured with this destination
+address cannot share a routing table).
+.It Cm -dyndest
+Disable dynamic updates of the destination address.
+This is the default.
.It Cm peerflag Ar flag
Set a specified PPP flag for the remote authenticator.
The flag name can be either
Index: sbin/ifconfig/ifconfig.c
===================================================================
RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v
retrieving revision 1.342
diff -u -p -r1.342 ifconfig.c
--- sbin/ifconfig/ifconfig.c 5 Jun 2017 05:10:23 -0000 1.342
+++ sbin/ifconfig/ifconfig.c 9 Jun 2017 15:57:40 -0000
@@ -266,6 +266,9 @@ void setsppppeername(const char *, int);
void setsppppeerkey(const char *, int);
void setsppppeerflag(const char *, int);
void unsetsppppeerflag(const char *, int);
+void sipcpinfo(struct sipcpreq *);
+void setspppdynaddr(const char *, int);
+void setspppdyndest(const char *, int);
void sppp_status(void);
void sppp_printproto(const char *, struct sauthreq *);
void setifpriority(const char *, int);
@@ -446,6 +449,10 @@ const struct cmd {
{ "peerkey", NEXTARG, 0, setsppppeerkey },
{ "peerflag", NEXTARG, 0, setsppppeerflag },
{ "-peerflag", NEXTARG, 0, unsetsppppeerflag },
+ { "dynaddr", 1, 0, setspppdynaddr },
+ { "-dynaddr", 0, 0, setspppdynaddr },
+ { "dyndest", 1, 0, setspppdyndest },
+ { "-dyndest", 0, 0, setspppdyndest },
{ "nwflag", NEXTARG, 0, setifnwflag },
{ "-nwflag", NEXTARG, 0, unsetifnwflag },
{ "flowsrc", NEXTARG, 0, setpflow_sender },
@@ -4878,6 +4885,63 @@ unsetsppppeerflag(const char *val, int d
}
void
+sipcpinfo(struct sipcpreq *req)
+{
+ bzero(req, sizeof(*req));
+
+ ifr.ifr_data = (caddr_t)req;
+ req->cmd = SPPPIOGIPCP;
+ if (ioctl(s, SIOCGSPPPPARAMS, &ifr) == -1)
+ err(1, "SIOCGSPPPPARAMS(SPPPIOGIPCP)");
+}
+
+void
+setspppdynaddr(const char *val, int d)
+{
+ struct sipcpreq scp;
+
+ sipcpinfo(&scp);
+
+ if (d == 1) {
+ if (scp.flags & SIPCP_MYADDR_DYN)
+ return;
+ scp.flags |= SIPCP_MYADDR_DYN;
+ } else {
+ if ((scp.flags & SIPCP_MYADDR_DYN) == 0)
+ return;
+ scp.flags &= ~SIPCP_MYADDR_DYN;
+ }
+
+ scp.cmd = SPPPIOSIPCP;
+ if (ioctl(s, SIOCSSPPPPARAMS, &ifr) == -1)
+ err(1, "SIOCSSPPPPARAMS(SPPPIOSIPCP)");
+}
+
+
+void
+setspppdyndest(const char *val, int d)
+{
+ struct sipcpreq scp;
+
+ sipcpinfo(&scp);
+
+ if (d == 1) {
+ if (scp.flags & SIPCP_HISADDR_DYN)
+ return;
+ scp.flags |= SIPCP_HISADDR_DYN;
+ } else {
+ if ((scp.flags & SIPCP_HISADDR_DYN) == 0)
+ return;
+ scp.flags &= ~SIPCP_HISADDR_DYN;
+ }
+
+ scp.cmd = SPPPIOSIPCP;
+ if (ioctl(s, SIOCSSPPPPARAMS, &ifr) == -1)
+ err(1, "SIOCSSPPPPARAMS(SPPPIOSIPCP)");
+}
+
+
+void
sppp_printproto(const char *name, struct sauthreq *auth)
{
if (auth->proto == 0)
@@ -4905,6 +4969,7 @@ sppp_status(void)
{
struct spppreq spr;
struct sauthreq spa;
+ struct sipcpreq scp;
bzero(&spr, sizeof(spr));
@@ -4943,6 +5008,13 @@ sppp_status(void)
printf("callin ");
if (spa.flags & AUTHFLAG_NORECHALLENGE)
printf("norechallenge ");
+
+ sipcpinfo(&scp);
+ if (scp.flags & SIPCP_MYADDR_DYN)
+ printf("dynaddr ");
+ if (scp.flags & SIPCP_HISADDR_DYN)
+ printf("dyndest ");
+
putchar('\n');
}
Index: sys/net/if_sppp.h
===================================================================
RCS file: /cvs/src/sys/net/if_sppp.h,v
retrieving revision 1.26
diff -u -p -r1.26 if_sppp.h
--- sys/net/if_sppp.h 24 Jan 2017 10:08:30 -0000 1.26
+++ sys/net/if_sppp.h 9 Jun 2017 15:17:31 -0000
@@ -82,12 +82,21 @@ struct spppreq {
enum ppp_phase phase; /* phase we're currently in */
};
+struct sipcpreq {
+ int cmd;
+ uint32_t flags; /* controls some flags in struct sipcp */
+#define SIPCP_MYADDR_DYN 1 /* my address will be dynamically assigned */
+#define SIPCP_HISADDR_DYN 2 /* his address will be dynamically assigned */
+};
+
#define SPPPIOGDEFS ((int)(('S' << 24) + (1 << 16) + sizeof(struct spppreq)))
#define SPPPIOSDEFS ((int)(('S' << 24) + (2 << 16) + sizeof(struct spppreq)))
#define SPPPIOGMAUTH ((int)(('S' << 24) + (3 << 16) + sizeof(struct sauthreq)))
#define SPPPIOSMAUTH ((int)(('S' << 24) + (4 << 16) + sizeof(struct sauthreq)))
#define SPPPIOGHAUTH ((int)(('S' << 24) + (5 << 16) + sizeof(struct sauthreq)))
#define SPPPIOSHAUTH ((int)(('S' << 24) + (6 << 16) + sizeof(struct sauthreq)))
+#define SPPPIOGIPCP ((int)(('S' << 24) + (7 << 16) + sizeof(struct sipcpreq)))
+#define SPPPIOSIPCP ((int)(('S' << 24) + (8 << 16) + sizeof(struct sipcpreq)))
#ifdef _KERNEL
Index: sys/net/if_spppsubr.c
===================================================================
RCS file: /cvs/src/sys/net/if_spppsubr.c,v
retrieving revision 1.164
diff -u -p -r1.164 if_spppsubr.c
--- sys/net/if_spppsubr.c 30 May 2017 07:50:37 -0000 1.164
+++ sys/net/if_spppsubr.c 10 Jun 2017 07:21:20 -0000
@@ -72,6 +72,20 @@
#define MAXALIVECNT 3 /* max. missed alive packets */
#define NORECV_TIME 15 /* before we get
worried */
+/*
+ * The IPCP_MYADDR_DYN and IPCP_HISADDR_DYN flags can currently be set
+ * from userspace in two ways:
+ *
+ * 1) via the SIOCSSPPPPARAMS ioctl (SPPPIOSIPCP)
+ * 2) by setting my addr to 0.0.0.0 and/or hisaddr to 0.0.0.1 (DYNADDR_HACK)
+ *
+ * The DYNADDR_HACK is now deprecated but still supported until systems
+ * have had a chance to upgrade to a release which supports the ioctl.
+ * This soft transition helps in cases where the only network interface the
+ * system administrator can reach needs sppp(4) with dynamic addresses.
+ */
+#define SPPP_DYNADDR_HACK /* don't remove before OpenBSD 6.3 is released */
+
/*
* Interface flags that can be set in an ifconfig command.
*
@@ -2601,15 +2615,18 @@ sppp_ipcp_tld(struct sppp *sp)
void
sppp_ipcp_tls(struct sppp *sp)
{
+#ifdef SPPP_DYNADDR_HACK
STDDCL;
+#endif
u_int32_t myaddr, hisaddr;
- sp->ipcp.flags &= ~(IPCP_HISADDR_SEEN|IPCP_MYADDR_SEEN|
- IPCP_MYADDR_DYN|IPCP_HISADDR_DYN);
+ sp->ipcp.flags &= ~(IPCP_HISADDR_SEEN|IPCP_MYADDR_SEEN);
sp->ipcp.req_myaddr = 0;
sp->ipcp.req_hisaddr = 0;
sppp_get_ip_addrs(sp, &myaddr, &hisaddr, 0);
+
+#ifdef SPPP_DYNADDR_HACK
/*
* If we don't have his address, this probably means our
* interface doesn't want to talk IP at all. (This could
@@ -2630,7 +2647,6 @@ sppp_ipcp_tls(struct sppp *sp)
* negotiate my address.
*/
sp->ipcp.flags |= IPCP_MYADDR_DYN;
- sp->ipcp.opts |= (1 << IPCP_OPT_ADDRESS);
}
if (hisaddr == 1) {
/*
@@ -2639,6 +2655,10 @@ sppp_ipcp_tls(struct sppp *sp)
*/
sp->ipcp.flags |= IPCP_HISADDR_DYN;
}
+#endif /* SPPP_DYNADDR_HACK */
+
+ if (sp->ipcp.flags & IPCP_MYADDR_DYN)
+ sp->ipcp.opts |= (1 << IPCP_OPT_ADDRESS);
/* indicate to LCP that it must stay alive */
sp->lcp.protos |= (1 << IDX_IPCP);
@@ -4506,6 +4526,22 @@ sppp_get_params(struct sppp *sp, struct
free(spa, M_DEVBUF, 0);
break;
}
+ case SPPPIOGIPCP: {
+ struct sipcpreq *req;
+
+ req = malloc(sizeof(*req), M_DEVBUF, M_WAITOK | M_ZERO);
+ if (sp->ipcp.flags & IPCP_MYADDR_DYN)
+ req->flags |= SIPCP_MYADDR_DYN;
+ if (sp->ipcp.flags & IPCP_HISADDR_DYN)
+ req->flags |= SIPCP_HISADDR_DYN;
+
+ if (copyout(req, (caddr_t)ifr->ifr_data, sizeof(*req)) != 0) {
+ free(req, M_DEVBUF, 0);
+ return EFAULT;
+ }
+ free(req, M_DEVBUF, 0);
+ break;
+ }
default:
return EINVAL;
}
@@ -4612,6 +4648,28 @@ sppp_set_params(struct sppp *sp, struct
}
}
free(spa, M_DEVBUF, 0);
+ break;
+ }
+ case SPPPIOSIPCP: {
+ struct sipcpreq *req;
+
+ req = malloc(sizeof(*req), M_DEVBUF, M_WAITOK);
+
+ if (copyin((caddr_t)ifr->ifr_data, req, sizeof(*req)) != 0) {
+ free(req, M_DEVBUF, 0);
+ return EFAULT;
+ }
+
+ if (req->flags & SIPCP_MYADDR_DYN)
+ sp->ipcp.flags |= IPCP_MYADDR_DYN;
+ else
+ sp->ipcp.flags &= ~IPCP_MYADDR_DYN;
+
+ if (req->flags & SIPCP_HISADDR_DYN)
+ sp->ipcp.flags |= IPCP_HISADDR_DYN;
+ else
+ sp->ipcp.flags &= ~IPCP_HISADDR_DYN;
+
break;
}
default: