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:
> 

Reply via email to