提交 05061d85 编写于 作者: G Guillaume Subiron 提交者: Samuel Thibault

slirp: Adding IPv6 address for DNS relay

This patch adds an IPv6 address to the DNS relay. in6_equal_dns() is
developed using this Slirp attribute.
sotranslate_in/out/accept() are also updated to manage the IPv6 case so the
guest can be able to join the host using one of the Slirp addresses.

For now this only points to localhost. Further development will be needed to
automatically fetch the IPv6 address from resolv.conf, and announce this via
RDNSS.
Signed-off-by: NGuillaume Subiron <maethor@subiron.org>
Signed-off-by: NSamuel Thibault <samuel.thibault@ens-lyon.org>
Reviewed-by: NThomas Huth <thuth@redhat.com>
上级 3feea444
...@@ -72,7 +72,11 @@ static inline bool in6_equal_mach(const struct in6_addr *a, ...@@ -72,7 +72,11 @@ static inline bool in6_equal_mach(const struct in6_addr *a,
|| (in6_equal_net(a, &(struct in6_addr)LINKLOCAL_ADDR, 64)\ || (in6_equal_net(a, &(struct in6_addr)LINKLOCAL_ADDR, 64)\
&& in6_equal_mach(a, &slirp->vhost_addr6, 64))) && in6_equal_mach(a, &slirp->vhost_addr6, 64)))
#define in6_equal_dns(a) 0 #define in6_equal_dns(a)\
((in6_equal_net(a, &slirp->vprefix_addr6, slirp->vprefix_len)\
&& in6_equal_mach(a, &slirp->vnameserver_addr6, slirp->vprefix_len))\
|| (in6_equal_net(a, &(struct in6_addr)LINKLOCAL_ADDR, 64)\
&& in6_equal_mach(a, &slirp->vnameserver_addr6, 64)))
#define in6_equal_host(a)\ #define in6_equal_host(a)\
(in6_equal_router(a) || in6_equal_dns(a)) (in6_equal_router(a) || in6_equal_dns(a))
......
...@@ -231,10 +231,13 @@ Slirp *slirp_init(int restricted, struct in_addr vnetwork, ...@@ -231,10 +231,13 @@ Slirp *slirp_init(int restricted, struct in_addr vnetwork,
slirp->vprefix_len = 64; slirp->vprefix_len = 64;
slirp->vhost_addr6 = slirp->vprefix_addr6; slirp->vhost_addr6 = slirp->vprefix_addr6;
slirp->vhost_addr6.s6_addr[15] = 0x2; slirp->vhost_addr6.s6_addr[15] = 0x2;
slirp->vnameserver_addr6 = slirp->vprefix_addr6;
slirp->vnameserver_addr6.s6_addr[15] = 0x3;
#else #else
inet_pton(AF_INET6, "fec0::0", &slirp->vprefix_addr6); inet_pton(AF_INET6, "fec0::0", &slirp->vprefix_addr6);
slirp->vprefix_len = 64; slirp->vprefix_len = 64;
inet_pton(AF_INET6, "fec0::2", &slirp->vhost_addr6); inet_pton(AF_INET6, "fec0::2", &slirp->vhost_addr6);
inet_pton(AF_INET6, "fec0::3", &slirp->vnameserver_addr6);
#endif #endif
if (vhostname) { if (vhostname) {
pstrcpy(slirp->client_hostname, sizeof(slirp->client_hostname), pstrcpy(slirp->client_hostname, sizeof(slirp->client_hostname),
......
...@@ -212,6 +212,7 @@ struct Slirp { ...@@ -212,6 +212,7 @@ struct Slirp {
struct in6_addr vhost_addr6; struct in6_addr vhost_addr6;
struct in_addr vdhcp_startaddr; struct in_addr vdhcp_startaddr;
struct in_addr vnameserver_addr; struct in_addr vnameserver_addr;
struct in6_addr vnameserver_addr6;
struct in_addr client_ipaddr; struct in_addr client_ipaddr;
char client_hostname[33]; char client_hostname[33];
......
...@@ -771,6 +771,7 @@ void sotranslate_out(struct socket *so, struct sockaddr_storage *addr) ...@@ -771,6 +771,7 @@ void sotranslate_out(struct socket *so, struct sockaddr_storage *addr)
{ {
Slirp *slirp = so->slirp; Slirp *slirp = so->slirp;
struct sockaddr_in *sin = (struct sockaddr_in *)addr; struct sockaddr_in *sin = (struct sockaddr_in *)addr;
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
switch (addr->ss_family) { switch (addr->ss_family) {
case AF_INET: case AF_INET:
...@@ -791,6 +792,19 @@ void sotranslate_out(struct socket *so, struct sockaddr_storage *addr) ...@@ -791,6 +792,19 @@ void sotranslate_out(struct socket *so, struct sockaddr_storage *addr)
ntohs(sin->sin_port), inet_ntoa(sin->sin_addr))); ntohs(sin->sin_port), inet_ntoa(sin->sin_addr)));
break; break;
case AF_INET6:
if (in6_equal_net(&so->so_faddr6, &slirp->vprefix_addr6,
slirp->vprefix_len)) {
if (in6_equal(&so->so_faddr6, &slirp->vnameserver_addr6)) {
/*if (get_dns_addr(&addr) < 0) {*/ /* TODO */
sin6->sin6_addr = in6addr_loopback;
/*}*/
} else {
sin6->sin6_addr = in6addr_loopback;
}
}
break;
default: default:
break; break;
} }
...@@ -800,6 +814,7 @@ void sotranslate_in(struct socket *so, struct sockaddr_storage *addr) ...@@ -800,6 +814,7 @@ void sotranslate_in(struct socket *so, struct sockaddr_storage *addr)
{ {
Slirp *slirp = so->slirp; Slirp *slirp = so->slirp;
struct sockaddr_in *sin = (struct sockaddr_in *)addr; struct sockaddr_in *sin = (struct sockaddr_in *)addr;
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
switch (addr->ss_family) { switch (addr->ss_family) {
case AF_INET: case AF_INET:
...@@ -816,6 +831,16 @@ void sotranslate_in(struct socket *so, struct sockaddr_storage *addr) ...@@ -816,6 +831,16 @@ void sotranslate_in(struct socket *so, struct sockaddr_storage *addr)
} }
break; break;
case AF_INET6:
if (in6_equal_net(&so->so_faddr6, &slirp->vprefix_addr6,
slirp->vprefix_len)) {
if (in6_equal(&sin6->sin6_addr, &in6addr_loopback)
|| !in6_equal(&so->so_faddr6, &slirp->vhost_addr6)) {
sin6->sin6_addr = so->so_faddr6;
}
}
break;
default: default:
break; break;
} }
...@@ -837,6 +862,13 @@ void sotranslate_accept(struct socket *so) ...@@ -837,6 +862,13 @@ void sotranslate_accept(struct socket *so)
} }
break; break;
case AF_INET6:
if (in6_equal(&so->so_faddr6, &in6addr_any) ||
in6_equal(&so->so_faddr6, &in6addr_loopback)) {
so->so_faddr6 = slirp->vhost_addr6;
}
break;
default: default:
break; break;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册