On Tue, Aug 14, 2018 at 5:03 AM, Myers, Charles <[email protected]>
wrote:

> It was left as a FIXME because I wasn’t sure how to best address this
> issue.
>
>
>
> AF_INET is just lucky because it is the same for Linux and FreeBSD (2).
>
> AF_INET6 is 28 in FreeBSD and 10 on Linux.
>
>
>
> AF_INET6 could be changed to 10 in FreeBSD code to avoid issues with IPv6
> too.
>
> but if you want to keep FreeBSD IDs unmodified then what you suggested
> makes sense.
>

So I think you addressed it well by using LINUX_AF_INET6, so no need for a
"FIXME" instead perhaps just a
comment where you use LINUX_AF_INET6.


>
>
> Currently when I include linux.h required for linux_socket.h it defines
> ifr_name as
>
>
>
> #define ifr_name        ifr_ifrn.ifrn_name      /* Interface name */
>
>
>
> which causes issues because ifr_name is used to access the freebsd struct.
>

I didn't understand - bsd/sys/compat/linux/linux_socket.h doesn't define
ifr_name. What
do you mean "linux.h is required for linux_socket.h" - why is it required
if all you plan to
use is the LINUX_AF_INET6 macro?


>
>
> $ make
>
> Building into build/release.x64
>
>   GEN gen/include/osv/version.h
>
>   CXX bsd/porting/networking.cc
>
> In file included from bsd/porting/networking.cc:30:0:
>
> bsd/porting/networking.cc: In function ‘int 
> osv::if_set_mtu(std::__cxx11::string,
> u16)’:
>
> ./bsd/sys/compat/linux/linux.h:147:18: error: ‘struct bsd_ifreq’ has no
> member named ‘ifr_ifrn’
>
> #define ifr_name ifr_ifrn.ifrn_name /* Interface name */
>
>                   ^
>
> bsd/porting/networking.cc:63:19: note: in expansion of macro ‘ifr_name’
>
>      strlcpy(ifreq.ifr_name, if_name.c_str(), IFNAMSIZ);
>
>
>
>
>
> I will need to remove the ifr_name macro in linux.h to fix this.
>
>
>
> diff --git a/bsd/sys/compat/linux/linux.h b/bsd/sys/compat/linux/linux.h
>
> index b693d81..1300f15 100644
>
> --- a/bsd/sys/compat/linux/linux.h
>
> +++ b/bsd/sys/compat/linux/linux.h
>
> @@ -124,9 +124,7 @@ struct l_ifmap {
>
> #define        LINUX_IFNAMSIZ          16
>
>
>
> struct l_ifreq {
>
> -       union {
>
> -               char    ifrn_name[LINUX_IFNAMSIZ];
>
> -       } ifr_ifrn;
>
> +       char    ifr_name[LINUX_IFNAMSIZ];
>

And this doesn't break any code which uses ifr_ifrn.ifrn_name? So I wonder
why we had this union in the first place...

>
>
>         union {
>
>                 struct l_sockaddr       ifru_addr;
>
> @@ -144,7 +142,6 @@ struct l_ifreq {
>
>         } ifr_ifru;
>
> } __packed;
>
>
>
> -#define        ifr_name        ifr_ifrn.ifrn_name      /* Interface name
> */
>
> #define        ifr_hwaddr      ifr_ifru.ifru_hwaddr    /* MAC address */
>
>
>
> struct l_ifconf {
>
>
>
> Thanks,
>
> -Charles
>
>
>
> *From:* Nadav Har'El <[email protected]>
> *Sent:* Sunday, August 12, 2018 11:40 AM
> *To:* Myers, Charles <[email protected]>
> *Cc:* Osv Dev <[email protected]>
> *Subject:* Re: [PATCH 08/16] bsd: OSv API support for IPv6
>
>
>
>
>
> On Tue, Aug 7, 2018 at 5:49 AM, Charles Myers <[email protected]>
> wrote:
>
> Signed-off-by: Charles Myers <[email protected]>
> ---
>  bsd/porting/networking.cc | 178 ++++++++++++++++++++++++++++++
> +++++++++++++++-
>  bsd/porting/networking.hh |   8 +++
>  bsd/porting/route.cc      |  86 ++++++++++++++++++----
>  bsd/sys/netinet/in.cc     |  10 +++
>  bsd/sys/netinet/in.h      |   1 +
>  loader.cc                 |  76 +++++++++++++++-----
>  6 files changed, 327 insertions(+), 32 deletions(-)
>
> diff --git a/bsd/porting/networking.cc b/bsd/porting/networking.cc
> index 016106c..e2767a7 100644
> --- a/bsd/porting/networking.cc
> +++ b/bsd/porting/networking.cc
> @@ -17,6 +17,15 @@
>  #include <bsd/sys/net/route.h>
>  #include <bsd/sys/netinet/in.h>
>  #include <bsd/sys/netinet/in_var.h>
> +#ifdef INET6
> +#include <bsd/sys/netinet6/in6.h>
> +#include <bsd/sys/netinet6/in6_var.h>
> +#include <bsd/sys/netinet6/nd6.h>
> +#include <bsd/sys/netinet6/ip6_var.h>
> +
> +// FIXME: inet_pton() is from musl which uses different AF_INET6
>
> +#define LINUX_AF_INET6 10
>
>
>
> We already have this exact #define in bsd/sys/compat/linux/linux_socket.h,
> can we include that instead?
>
>
>
> I think you should remove the "FIXME" - this is the correct behavior of
> inet_pton and other User-facing
>
> functions, which take the Linux versions of the ABI - and unfortunately
> while in Linux and BSD AF_INET
>
> is the same, AF_INET6 is not :-(
>
>
>
> Instead of a "FIXME" here you can explain at the point you use
> LINUX_AF_INET6 below, why you use it.
>
>
>
> +#endif // INET6
>  #include <bsd/sys/sys/socket.h>
>  #include <bsd/sys/sys/socketvar.h>
>
> @@ -61,6 +70,18 @@ int if_set_mtu(std::string if_name, u16 mtu)
>
>  int start_if(std::string if_name, std::string ip_addr, std::string
> mask_addr)
>  {
> +    return if_add_addr(if_name, ip_addr, mask_addr);
> +}
> +
> +int stop_if(std::string if_name, std::string ip_addr)
> +{
> +    std::string mask_addr;
>
>
>
> If you intend to use an empty string, you can (I think) also just use ""
> below, and don't need to name it (but you can, if you want...).
>
> +
> +    return if_del_addr(if_name, ip_addr, mask_addr);
> +}
> +
> +int if_add_ipv4_addr(std::string if_name, std::string ip_addr,
> std::string mask_addr)
> +{
>      int error, success;
>      struct bsd_ifreq oldaddr;
>      struct in_aliasreq ifra;
> @@ -99,7 +120,9 @@ int start_if(std::string if_name, std::string ip_addr,
> std::string mask_addr)
>          error = EINVAL;
>          goto out;
>      }
> +    mask->sin_family = AF_INET;
>      mask->sin_len = sizeof(struct bsd_sockaddr_in);
> +
>      broadcast->sin_family      = AF_INET;
>      broadcast->sin_len         = sizeof(struct bsd_sockaddr_in);
>      broadcast->sin_addr.s_addr = (addr->sin_addr.s_addr &
> @@ -117,7 +140,7 @@ out:
>      return (error);
>  }
>
> -int stop_if(std::string if_name, std::string ip_addr)
> +int if_del_ipv4_addr(std::string if_name, std::string ip_addr)
>  {
>      int error, success;
>      struct in_aliasreq ifra;
> @@ -155,6 +178,157 @@ out:
>      return (error);
>  }
>
> +#ifdef INET6
> +
> +int if_add_ipv6_addr(std::string if_name, std::string ip_addr,
> std::string netmask)
> +{
> +    int error, success;
> +    struct in6_ifreq oldaddr;
> +    struct in6_aliasreq ifra;
> +    struct bsd_sockaddr_in6* addr      = &ifra.ifra_addr;
> +    struct bsd_sockaddr_in6* mask      = &ifra.ifra_prefixmask;
> +    //struct bsd_sockaddr_in6* dst       = &ifra.ifra_dstaddr;
> +    struct ifnet* ifp;
> +
> +    if (if_name.empty() || ip_addr.empty() || netmask.empty()) {
> +        return (EINVAL);
> +    }
> +
> +    bzero(&ifra, sizeof(struct in6_aliasreq));
> +    ifra.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;
> +    ifra.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
> +
> +    /* IF Name */
> +    strncpy(ifra.ifra_name, if_name.c_str(), IFNAMSIZ);
> +    ifp = ifunit_ref(if_name.c_str());
> +    if (!ifp) {
> +        return (ENOENT);
> +    }
> +
> +    /* IP Address */
> +    if ((success = inet_pton(LINUX_AF_INET6, ip_addr.c_str(),
> &addr->sin6_addr)) != 1) {
>
>
>
> Maybe the comment about the peculiar AF parameter of inet_pton belongs
> here, not about (but as a comment, not a FIXME)
>
>
>
> +        bsd_log(ERR, "Failed converting IPv6 address %s\n",
> ip_addr.c_str());
> +        error = EINVAL;
> +        goto out;
> +    }
> +    addr->sin6_family = AF_INET6;
> +    addr->sin6_len = sizeof(struct bsd_sockaddr_in6);
> +
> +    /* Mask */
> +    if (inet_pton(LINUX_AF_INET6, netmask.c_str(), &mask->sin6_addr) !=
> 1) {
> +        /* Interpret it as a prefix length */
> +        long prefix_len = strtol(netmask.c_str(), NULL, 0);
> +        if (prefix_len < 0 || prefix_len > 128) {
> +            error = EINVAL;
> +            goto out;
> +        }
> +        in6_prefixlen2mask(&mask->sin6_addr, prefix_len);
> +    }
> +    mask->sin6_family = AF_INET6;
> +    mask->sin6_len = sizeof(struct bsd_sockaddr_in6);
> +
> +    strncpy(oldaddr.ifr_name, if_name.c_str(), IFNAMSIZ);
> +    error = in6_control(NULL, SIOCGIFADDR_IN6, (caddr_t)&oldaddr, ifp,
> NULL);
> +    if (!error) {
> +        in6_control(NULL, SIOCDIFADDR_IN6, (caddr_t)&oldaddr, ifp, NULL);
> +    }
> +    error = in6_control(NULL, SIOCAIFADDR_IN6, (caddr_t)&ifra, ifp, NULL);
> +
> +out:
> +    if_rele(ifp);
> +    return (error);
> +}
> +
> +int if_del_ipv6_addr(std::string if_name, std::string ip_addr,
> std::string netmask)
> +{
> +    int error, success;
> +    struct in6_aliasreq ifra;
> +    struct bsd_sockaddr_in6* addr      = &ifra.ifra_addr;
> +    struct bsd_sockaddr_in6* mask      = &ifra.ifra_prefixmask;
> +    struct ifnet* ifp;
> +
> +    if (if_name.empty() || ip_addr.empty() || netmask.empty())
> +        return (EINVAL);
> +
> +    bzero(&ifra, sizeof(struct in6_aliasreq));
> +
> +    /* IF Name */
> +    strncpy(ifra.ifra_name, if_name.c_str(), IFNAMSIZ);
> +    ifp = ifunit_ref(if_name.c_str());
> +    if (!ifp) {
> +        return (ENOENT);
> +    }
> +
> +    /* IP Address */
> +    if ((success = inet_pton(LINUX_AF_INET6, ip_addr.c_str(),
> &addr->sin6_addr)) != 1) {
> +        bsd_log(ERR, "Failed converting IPv6 address %s\n",
> ip_addr.c_str());
> +        error = EINVAL;
> +        goto out;
> +    }
> +    addr->sin6_family = AF_INET6;
> +    addr->sin6_len = sizeof(struct bsd_sockaddr_in6);
> +
> +    /* Mask */
> +    if (inet_pton(LINUX_AF_INET6, netmask.c_str(), &mask->sin6_addr) !=
> 1) {
> +        /* Interpret it as a prefix length */
> +        long prefix_len = strtol(netmask.c_str(), NULL, 0);
> +        if (prefix_len < 0 || prefix_len > 128) {
> +            error = EINVAL;
> +            goto out;
> +        }
> +        in6_prefixlen2mask(&mask->sin6_addr, prefix_len);
> +    }
> +    mask->sin6_family = AF_INET6;
> +    mask->sin6_len = sizeof(struct bsd_sockaddr_in6);
> +
> +    error = in6_control(NULL, SIOCDIFADDR_IN6, (caddr_t)&ifra, ifp, NULL);
> +
> +out:
> +    if_rele(ifp);
> +    return (error);
> +}
> +
> +int set_ipv6_accept_rtadv(bool enable)
> +{
> +    V_ip6_accept_rtadv = enable ? 1 : 0;
> +    return 0;
> +}
> +
> +bool get_ipv6_accept_rtadv(void)
> +{
> +    return (V_ip6_accept_rtadv != 0);
> +}
> +
> +#endif // INET6
> +
> +int if_add_addr(std::string if_name, std::string ip_addr, std::string
> mask_addr)
> +{
> +    struct in_addr v4;
> +    if (inet_pton(AF_INET, ip_addr.c_str(), &v4)) {
>
>
>
> This is also supposed to be LINUX_AF_INET, but it's the same :-)
>
>
>
> +        return if_add_ipv4_addr(if_name, ip_addr, mask_addr);
> +    }
> +#ifdef INET6
> +    else {
> +        return if_add_ipv6_addr(if_name, ip_addr, mask_addr);
> +    }
> +#endif
> +    return EINVAL;
> +}
> +
> +int if_del_addr(std::string if_name, std::string ip_addr, std::string
> mask_addr)
> +{
> +    struct in_addr v4;
> +    if (inet_pton(AF_INET, ip_addr.c_str(), &v4)) {
> +        return if_del_ipv4_addr(if_name, ip_addr);
> +    }
> +#ifdef INET6
> +    else {
> +        return if_del_ipv6_addr(if_name, ip_addr, mask_addr);
> +    }
> +#endif
> +    return EINVAL;
> +}
> +
>  int ifup(std::string if_name)
>  {
>      int error;
> @@ -194,4 +368,6 @@ std::string if_ip(std::string if_name) {
>      }
>      return inet_ntoa(((bsd_sockaddr_in*)&(addr.ifr_addr))->sin_addr);
>  }
> +
> +
>  }
> diff --git a/bsd/porting/networking.hh b/bsd/porting/networking.hh
> index 8d06fe2..e25cb00 100644
> --- a/bsd/porting/networking.hh
> +++ b/bsd/porting/networking.hh
> @@ -22,6 +22,14 @@ namespace osv {
>      int stop_if(std::string if_name, std::string ip_addr);
>      int ifup(std::string if_name);
>      std::string if_ip(std::string if_name);
> +
> +    int if_add_addr(std::string if_name, std::string ip_addr, std::string
> netmask);
> +    int if_del_addr(std::string if_name, std::string ip_addr, std::string
> netmask);
> +
> +#ifdef INET6
> +    int set_ipv6_accept_rtadv(bool enable);
> +    bool get_ipv6_accept_rtadv(void);
> +#endif
>  }
>
>  #endif /* __NETWORKING_H__ */
> diff --git a/bsd/porting/route.cc b/bsd/porting/route.cc
> index b1f9d50..794a0a5 100644
> --- a/bsd/porting/route.cc
> +++ b/bsd/porting/route.cc
> @@ -41,6 +41,10 @@
>  #include <bsd/sys/sys/socket.h>
>  #include <bsd/sys/sys/socketvar.h>
>  #include <bsd/sys/sys/sysctl.h>
> +#ifdef INET6
> +#include <bsd/sys/netinet6/in6.h>
> +#include <bsd/sys/netinet6/in6_var.h>
> +#endif
>
>  int sysctl_rtsock(SYSCTL_HANDLER_ARGS) ;
>
> @@ -172,6 +176,59 @@ static struct mbuf*  osv_route_arp_rtmsg(int if_idx,
> int cmd, const char* ip,
>      return (m);
>  }
>
> +static int osv_sockaddr_from_string(struct bsd_sockaddr_storage *addr,
> const char *str)
> +{
> +    struct bsd_sockaddr_in *sa4 = (struct bsd_sockaddr_in*)addr;
> +    if (inet_pton(AF_INET, str, (void*)&sa4->sin_addr)) {
> +        sa4->sin_len = sizeof(*sa4);
> +        sa4->sin_family = AF_INET;
> +        sa4->sin_port = 0;
> +        return 1;
> +    }
> +#ifdef INET6
> +    struct bsd_sockaddr_in6 *sa6 = (struct bsd_sockaddr_in6*)addr;
> +    if (inet_pton(AF_INET6, str, (void*)&sa6->sin6_addr)) {
> +        sa6->sin6_len = sizeof(*sa6);
> +        sa6->sin6_family = AF_INET6;
> +        sa6->sin6_port = 0;
> +        sa6->sin6_flowinfo = 0;
> +        sa6->sin6_scope_id = 0;
> +        return 1;
> +    }
> +#endif
> +    return 0;
> +}
> +
> +static int osv_sockaddr_from_prefix_len(int af, struct
> bsd_sockaddr_storage *addr, int prefix_len)
> +{
> +    switch(af){
> +    case AF_INET:
> +        {
> +            struct bsd_sockaddr_in *sa4 = (struct bsd_sockaddr_in *)addr;
> +            sa4->sin_len = sizeof(*sa4);
> +            sa4->sin_family = AF_INET;
> +            sa4->sin_port = 0;
> +            in_prefixlen2mask(&sa4->sin_addr, prefix_len);
> +        }
> +        return 1;
> +#ifdef INET6
> +    case AF_INET6:
> +        {
> +            struct bsd_sockaddr_in6 *sa6 = (struct bsd_sockaddr_in6
> *)addr;
> +            sa6->sin6_len = sizeof(*sa6);
> +            sa6->sin6_family = AF_INET6;
> +            sa6->sin6_port = 0;
> +            sa6->sin6_flowinfo = 0;
> +            sa6->sin6_scope_id = 0;
> +            in6_prefixlen2mask(&sa6->sin6_addr, prefix_len);
> +        }
> +        return 1;
> +#endif
> +    default:
> +        return 0;
> +    }
> +}
> +
>  /* Compose a routing message to be sent on socket */
>  static struct mbuf*  osv_route_rtmsg(int cmd, const char* destination,
>      const char* gateway, const char* netmask, int flags, gw_type type)
> @@ -185,10 +242,10 @@ static struct mbuf*  osv_route_rtmsg(int cmd, const
> char* destination,
>      struct bsd_ifaddr *ifa;
>      bool is_link = type == gw_type::link;
>
> -    /* IPv4: Addresses */
> -    struct bsd_sockaddr_in dst;
> -    struct bsd_sockaddr_in gw;
> -    struct bsd_sockaddr_in mask;
> +    /* IP: Addresses */
> +    struct bsd_sockaddr_storage dst;
> +    struct bsd_sockaddr_storage gw;
> +    struct bsd_sockaddr_storage mask;
>
>      /* Link: Address*/
>      struct bsd_sockaddr_dl sdl;
> @@ -215,9 +272,7 @@ static struct mbuf*  osv_route_rtmsg(int cmd, const
> char* destination,
>      bzero(&sdl, sizeof(sdl));
>      bzero(&mask, sizeof(mask));
>
> -    dst.sin_family = AF_INET;
> -    dst.sin_len = sizeof(struct bsd_sockaddr_in);
> -    inet_aton(destination, &dst.sin_addr);
> +    osv_sockaddr_from_string(&dst, destination);
>
>      if (is_link) {
>          /* Get ifindex from name */
> @@ -234,15 +289,20 @@ static struct mbuf*  osv_route_rtmsg(int cmd, const
> char* destination,
>          memcpy(ea, IF_LLADDR(ifp), ETHER_ADDR_LEN);
>          if_rele(ifp);
>      } else {
> -        gw.sin_family = AF_INET;
> -        gw.sin_len = sizeof(struct bsd_sockaddr_in);
> -        inet_aton(gateway, &gw.sin_addr);
> +        osv_sockaddr_from_string(&gw, gateway);
>      }
>
>      if (netmask) {
> -        mask.sin_family = AF_INET;
> -        mask.sin_len = sizeof(struct bsd_sockaddr_in);
> -        inet_aton(netmask, &mask.sin_addr);
> +        if (osv_sockaddr_from_string(&mask, netmask) == 0) {
> +            // Try parsing it as a prefix length
> +            char *p_end = NULL;
> +            long prefix_len = strtol(netmask, &p_end, 0);
> +            if (p_end == netmask) {
> +                 // Bad netmask string.  Probably safer to treat it as a
> host route.
> +                 prefix_len = (((struct bsd_sockaddr *)&dst)->sa_family
> == AF_INET6) ? 128 : 32;
> +            }
> +            osv_sockaddr_from_prefix_len(((struct bsd_sockaddr
> *)&dst)->sa_family, &mask, prefix_len);
> +        }
>      }
>
>      /*
> diff --git a/bsd/sys/netinet/in.cc b/bsd/sys/netinet/in.cc
> index f7c1934..c0c37cd 100644
> --- a/bsd/sys/netinet/in.cc
> +++ b/bsd/sys/netinet/in.cc
> @@ -1673,3 +1673,13 @@ in_domifdetach(struct ifnet *ifp, void *aux)
>         lltable_free(ii->ii_llt);
>         free(ii);
>  }
> +
> +void
> +in_prefixlen2mask(struct in_addr *maskp, int plen)
> +{
> +       if (plen == 0)
> +               maskp->s_addr = 0;
> +       else
> +               maskp->s_addr = htonl(0xffffffff << (32 - plen));
> +}
> +
> diff --git a/bsd/sys/netinet/in.h b/bsd/sys/netinet/in.h
> index 43291b7..672e613 100644
> --- a/bsd/sys/netinet/in.h
> +++ b/bsd/sys/netinet/in.h
> @@ -470,6 +470,7 @@ const char *inet_ntoa_r(struct in_addr ina, char *buf,
> socklen_t); /* in libkern
>  const char *inet_ntop(int, const void *, char *, socklen_t); /* in
> libkern */
>  int     inet_pton(int af, const char *, void *); /* in libkern */
>  void    in_ifdetach(struct ifnet *);
> +void in_prefixlen2mask(struct in_addr *maskp, int plen);
>  __END_DECLS
>
>  #define        in_hosteq(s, t) ((s).s_addr == (t).s_addr)
> diff --git a/loader.cc b/loader.cc
> index 3f88ebd..5e04c83 100644
> --- a/loader.cc
> +++ b/loader.cc
> @@ -5,6 +5,8 @@
>   * BSD license as described in the LICENSE file in the top-level
> directory.
>   */
>
> +#include <bsd/porting/netport.h>
> +
>  #include "fs/fs.hh"
>  #include <bsd/init.hh>
>  #include <bsd/net.hh>
> @@ -137,8 +139,8 @@ static bool opt_verbose = false;
>  static std::string opt_chdir;
>  static bool opt_bootchart = false;
>  static std::vector<std::string> opt_ip;
> -static std::string opt_defaultgw;
> -static std::string opt_nameserver;
> +static std::vector<std::string> opt_defaultgw;
> +static std::vector<std::string> opt_nameserver;
>  static std::string opt_redirect;
>  static std::chrono::nanoseconds boot_delay;
>  bool opt_assign_net = false;
> @@ -177,8 +179,8 @@ void parse_options(int loader_argc, char** loader_argv)
>          ("cwd", bpo::value<std::vector<std::string>>(), "set current
> working directory")
>          ("bootchart", "perform a test boot measuring a time distribution
> of the various operations\n")
>          ("ip", bpo::value<std::vector<std::string>>(), "set static IP on
> NIC")
> -        ("defaultgw", bpo::value<std::string>(), "set default gateway
> address")
> -        ("nameserver", bpo::value<std::string>(), "set nameserver
> address")
> +        ("defaultgw", bpo::value<std::vector<std::string>>(), "set
> default gateway address")
>
> +        ("nameserver", bpo::value<std::vector<std::string>>(), "set
> nameserver address")
>
>          ("delay", bpo::value<float>()->default_value(0), "delay in
> seconds before boot")
>          ("redirect", bpo::value<std::string>(), "redirect stdout and
> stderr to file")
>          ("disable_rofs_cache", "disable ROFS memory cache")
> @@ -287,11 +289,11 @@ void parse_options(int loader_argc, char**
> loader_argv)
>      }
>
>      if (vars.count("defaultgw")) {
> -        opt_defaultgw = vars["defaultgw"].as<std::string>();
> +        opt_defaultgw = vars["defaultgw"].as<std::vector<std::string>>();
>      }
>
>      if (vars.count("nameserver")) {
> -        opt_nameserver = vars["nameserver"].as<std::string>();
> +        opt_nameserver = vars["nameserver"].as<std::
> vector<std::string>>();
>      }
>
>      if (vars.count("redirect")) {
> @@ -365,40 +367,77 @@ void* do_main_thread(void *_main_args)
>          }
>      }
>
> +#ifdef INET6
> +    // Enable IPv6 StateLess Address AutoConfiguration (SLAAC)
> +    osv::set_ipv6_accept_rtadv(true);
> +#endif
> +
>      bool has_if = false;
>      osv::for_each_if([&has_if] (std::string if_name) {
>          if (if_name == "lo0")
>              return;
>
>          has_if = true;
> -        // Start DHCP by default and wait for an IP
> -        if (osv::start_if(if_name, "0.0.0.0", "255.255.255.0") != 0 ||
> -            osv::ifup(if_name) != 0)
> +
> +        if (osv::ifup(if_name) != 0)
>              debug("Could not initialize network interface.\n");
> +
> +        if (opt_ip.size() == 0) {
> +            // Start DHCP by default and wait for an IP
> +            if (osv::if_add_addr(if_name, "0.0.0.0", "255.255.255.0") !=
> 0)
> +                debug("Could not add 0.0.0.0 IP to interface.\n");
> +        }
>      });
>      if (has_if) {
>          if (opt_ip.size() == 0) {
>              dhcp_start(true);
>          } else {
> +            // Add interface IP addresses
>              for (auto t : opt_ip) {
>                  std::vector<std::string> tmp;
> -                boost::split(tmp, t, boost::is_any_of(" ,"),
> boost::token_compress_on);
> +                boost::split(tmp, t, boost::is_any_of(" ,/"),
> boost::token_compress_on);
>                  if (tmp.size() != 3)
>                      abort("incorrect parameter on --ip");
>
> -                printf("%s: %s\n",tmp[0].c_str(),tmp[1].c_str());
> +                printf("%s: %s %s\n",tmp[0].c_str(),tmp[1].c_str(),
> tmp[2].c_str());
>
> -                if (osv::start_if(tmp[0], tmp[1], tmp[2]) != 0)
> -                    debug("Could not initialize network interface.\n");
> +                if (osv::if_add_addr(tmp[0], tmp[1], tmp[2]) != 0)
> +                    debug("Could not add IP address to interface.\n");
>              }
> +            // Add default gateway routes
> +            // One default route is allowed for IPv4 and one for IPv6
>              if (opt_defaultgw.size() != 0) {
> -                osv_route_add_network("0.0.0.0",
> -                                      "0.0.0.0",
> -                                      opt_defaultgw.c_str());
> +                bool has_defaultgw_v4=false, has_defaultgw_v6=false;
> +                for (auto t : opt_defaultgw) {
> +                    auto addr = boost::asio::ip::address::from_string(t);
> +                    if (addr.is_v4()) {
> +                        if (!has_defaultgw_v4) {
> +                            osv_route_add_network("0.0.0.0",
> +                                                  "0.0.0.0",
> +                                                  t.c_str());
> +                            has_defaultgw_v4 = true;
> +                        }
> +                    }
> +                    else {
> +                        if (!has_defaultgw_v6) {
> +                            osv_route_add_network("::",
> +                                                  "::",
> +                                                  t.c_str());
> +                            has_defaultgw_v6 = true;
> +                        }
> +                    }
> +                }
>              }
> +            // Add nameserver addresses
>              if (opt_nameserver.size() != 0) {
> -                auto addr = boost::asio::ip::address_v4::
> from_string(opt_nameserver);
> -                osv::set_dns_config({addr}, std::vector<std::string>());
> +                std::vector<boost::asio::ip::address> dns_servers;
> +                for (auto t : opt_nameserver) {
> +                    auto addr = boost::asio::ip::address::from_string(t);
> +                    dns_servers.push_back(addr);
> +                }
> +                if (!dns_servers.empty()) {
> +                    osv::set_dns_config(dns_servers,
> std::vector<std::string>());
> +                }
>              }
>          }
>      }
> @@ -465,6 +504,7 @@ void* do_main_thread(void *_main_args)
>          for (int i = 0; i < count; i++) {
>              if (!strcmp(".", namelist[i]->d_name) ||
>                      !strcmp("..", namelist[i]->d_name)) {
> +                free(namelist[i]);
>
>
>
> Not related to this patch, but looks correct :-)
>
>
>
>                  continue;
>              }
>              std::string fn("/init/");
> --
> 2.7.4
>
> --
> You received this message because you are subscribed to the Google Groups
> "OSv Development" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> For more options, visit https://groups.google.com/d/optout.
>
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "OSv Development" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to