On Fri, Jun 09, 2017 at 06:33:46PM +0200, Stefan Sperling wrote:
> Currently, sppp(4) interfaces use a destination address of 0.0.0.1 to
> indicate that the destination address should be assigned by the peer:
>
> inet 0.0.0.0 255.255.255.255 NONE \
> pppoedev em0 authproto pap \
> authname 'testcaller' authkey 'donttell' up
> dest 0.0.0.1
>
> As a side effect a route to 0.0.0.1 is added to the routing table.
>
> Apparently, in 5.7 this still used to work with mulitple pppoe interfaces
> which shared a routing table:
> http://marc.info/?l=openbsd-misc&m=149386503001033&w=2
>
> At present only one pppoe interface can be used in this way because
> setting a dest address of 0.0.0.1 on additional interfaces now causes
> an error: ifconfig: SIOCAIFADDR: File exists
>
> This diff changes the way dynamic addresses are configured in sppp(4).
> Instead of using magic IP addresses as wildcards, we allow userland to
> control behavior via new ifconfig command flags. 'dynaddr' enables a
> dynamic local address, and 'dyndest' enables a dynamic destination address.
> To disable either of these again, prepend a minus (e.g. -dynaddr).
>
> The above example becomes:
>
> inet 0.0.0.0 255.255.255.255 NONE \
> pppoedev em0 authproto pap \
> authname 'testcaller' authkey 'donttell' \
> dynaddr dyndest up
>
hi.
why do you have to specify 0.0.0.0 *and* dynaddr?
jmc
> Tested on my ADSL line and it works as expected.
>
> I cannot test it on multiple links until next week, but since no route
> for 0.0.0.1 is in the routing table anymore, I expect this to work.
>
> 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 9 Jun 2017 16:02:23 -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,16 @@ 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 assigned by the peer.
> +.It Cm -dynaddr
> +Disable dynamic assignment of the local address.
> +This is the default.
> +.It Cm dyndest
> +The destination address will be assigned by the peer.
> +.It Cm -dyndest
> +Disable dynamic assignment 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 9 Jun 2017 15:23:05 -0000
> @@ -2601,44 +2601,16 @@ sppp_ipcp_tld(struct sppp *sp)
> void
> sppp_ipcp_tls(struct sppp *sp)
> {
> - STDDCL;
> 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);
> - /*
> - * If we don't have his address, this probably means our
> - * interface doesn't want to talk IP at all. (This could
> - * be the case if somebody wants to speak only IPX, for
> - * example.) Don't open IPCP in this case.
> - */
> - if (hisaddr == 0) {
> - /* XXX this message should go away */
> - if (debug)
> - log(LOG_DEBUG, SPP_FMT "ipcp_open(): no IP interface\n",
> - SPP_ARGS(ifp));
> - return;
> - }
>
> - if (myaddr == 0) {
> - /*
> - * I don't have an assigned address, so i need to
> - * negotiate my address.
> - */
> - sp->ipcp.flags |= IPCP_MYADDR_DYN;
> + if (sp->ipcp.flags & IPCP_MYADDR_DYN)
> sp->ipcp.opts |= (1 << IPCP_OPT_ADDRESS);
> - }
> - if (hisaddr == 1) {
> - /*
> - * XXX - remove this hack!
> - * remote has no valid address, we need to get one assigned.
> - */
> - sp->ipcp.flags |= IPCP_HISADDR_DYN;
> - }
>
> /* indicate to LCP that it must stay alive */
> sp->lcp.protos |= (1 << IDX_IPCP);
> @@ -4506,6 +4478,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 +4600,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:
>