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:

Reply via email to