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.