diff -NurpP --minimal linux-2.6.18-vs2.1.1-rc40/include/linux/vs_network.h linux-2.6.18-vs2.1.1-rc40.1/include/linux/vs_network.h --- linux-2.6.18-vs2.1.1-rc40/include/linux/vs_network.h 2006-09-25 15:40:02 +0200 +++ linux-2.6.18-vs2.1.1-rc40.1/include/linux/vs_network.h 2006-10-16 04:14:46 +0200 @@ -4,6 +4,8 @@ #include "vserver/network.h" #include "vserver/debug.h" +#include + #define get_nx_info(i) __get_nx_info(i,__FILE__,__LINE__) @@ -215,6 +217,26 @@ static inline int __nx_check(nid_t cid, #define nx_ncaps(c) nx_info_ncaps(current->nx_info,(c)) +#define IPI_LOOPBACK htonl(INADDR_LOOPBACK) + +static inline uint32_t nx_map_addr(struct nx_info *nxi, uint32_t addr) +{ + if (!nxi) + return addr; + if (addr == IPI_LOOPBACK) + return (addr ^ (nxi->nx_id << 8)); + return addr; +} + +static inline uint32_t nx_rmap_addr(struct nx_info *nxi, uint32_t addr) +{ + if (!nxi) + return addr; + if ((addr ^ (nxi->nx_id << 8)) == IPI_LOOPBACK) + return IPI_LOOPBACK; + return addr; +} + static inline int addr_in_nx_info(struct nx_info *nxi, uint32_t addr) { int n,i; @@ -225,6 +247,12 @@ static inline int addr_in_nx_info(struct n = nxi->nbipv4; if (n && (nxi->ipv4[0] == 0)) return 1; + /* FIXME: make that conditional */ + if (addr == IPI_LOOPBACK) + return 1; + /* FIXME: hide the first/loopback */ + if (nx_rmap_addr(nxi, addr) == IPI_LOOPBACK) + return 0; for (i=0; iipv4[i] == addr) return 1; diff -NurpP --minimal linux-2.6.18-vs2.1.1-rc40/include/net/route.h linux-2.6.18-vs2.1.1-rc40.1/include/net/route.h --- linux-2.6.18-vs2.1.1-rc40/include/net/route.h 2006-09-20 17:01:45 +0200 +++ linux-2.6.18-vs2.1.1-rc40.1/include/net/route.h 2006-10-16 03:37:39 +0200 @@ -34,7 +34,6 @@ #include #include #include -#include #ifndef __KERNEL__ #warning This file is not supposed to be used outside of kernel. @@ -146,7 +145,6 @@ static inline char rt_tos2priority(u8 to return ip_tos2prio[IPTOS_TOS(tos)>>1]; } -#define IPI_LOOPBACK htonl(INADDR_LOOPBACK) static inline int ip_find_src(struct nx_info *nxi, struct rtable **rp, struct flowi *fl) { @@ -181,10 +179,12 @@ static inline int ip_find_src(struct nx_ fl->fl4_src = ipv4; break; } + /* FIXME: should be replaced by flag */ if (!fl->fl4_src && (foundsrc & mask) == net4) fl->fl4_src = ipv4; } } + /* FIXME: can be removed with loopback ip */ if (fl->fl4_src == 0) fl->fl4_src = (fl->fl4_dst == IPI_LOOPBACK) ? IPI_LOOPBACK : ipv4root; @@ -229,6 +229,7 @@ static inline int ip_route_connect(struc if (fl.fl4_dst == IPI_LOOPBACK && !vx_check(0, VX_ADMIN)) fl.fl4_dst = nx_info->ipv4[0]; #ifdef CONFIG_VSERVER_REMAP_SADDR + /* FIXME: can be removed for performance reasons */ if (fl.fl4_src == IPI_LOOPBACK && !vx_check(0, VX_ADMIN)) fl.fl4_src = nx_info->ipv4[0]; #endif diff -NurpP --minimal linux-2.6.18-vs2.1.1-rc40/net/ipv4/af_inet.c linux-2.6.18-vs2.1.1-rc40.1/net/ipv4/af_inet.c --- linux-2.6.18-vs2.1.1-rc40/net/ipv4/af_inet.c 2006-09-20 17:01:45 +0200 +++ linux-2.6.18-vs2.1.1-rc40.1/net/ipv4/af_inet.c 2006-10-16 04:06:06 +0200 @@ -691,6 +691,8 @@ int inet_getname(struct socket *sock, st sin->sin_port = inet->sport; sin->sin_addr.s_addr = addr; } + /* FIXME: cleanup, maybe reference? */ + sin->sin_addr.s_addr = nx_rmap_addr(current->nx_info, sin->sin_addr.s_addr); memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); *uaddr_len = sizeof(*sin); return 0; diff -NurpP --minimal linux-2.6.18-vs2.1.1-rc40/net/ipv4/tcp_ipv4.c linux-2.6.18-vs2.1.1-rc40.1/net/ipv4/tcp_ipv4.c --- linux-2.6.18-vs2.1.1-rc40/net/ipv4/tcp_ipv4.c 2006-09-25 15:40:02 +0200 +++ linux-2.6.18-vs2.1.1-rc40.1/net/ipv4/tcp_ipv4.c 2006-10-15 16:29:53 +0200 @@ -1745,7 +1747,7 @@ static void get_tcp4_sock(struct sock *s struct tcp_sock *tp = tcp_sk(sp); const struct inet_connection_sock *icsk = inet_csk(sp); struct inet_sock *inet = inet_sk(sp); - unsigned int dest = inet->daddr; + unsigned int dest = nx_rmap_addr(current->nx_info, inet->daddr); unsigned int src = inet->rcv_saddr; __u16 destp = ntohs(inet->dport); __u16 srcp = ntohs(inet->sport); @@ -1792,7 +1794,7 @@ static void get_timewait4_sock(struct in if (ttd < 0) ttd = 0; - dest = tw->tw_daddr; + dest = nx_rmap_addr(current->nx_info, tw->tw_daddr); src = tw->tw_rcv_saddr; destp = ntohs(tw->tw_dport); srcp = ntohs(tw->tw_sport); diff -NurpP --minimal linux-2.6.18-vs2.1.1-rc40/net/ipv4/udp.c linux-2.6.18-vs2.1.1-rc40.1/net/ipv4/udp.c --- linux-2.6.18-vs2.1.1-rc40/net/ipv4/udp.c 2006-09-25 15:40:02 +0200 +++ linux-2.6.18-vs2.1.1-rc40.1/net/ipv4/udp.c 2006-10-16 07:27:11 +0200 @@ -846,6 +848,11 @@ try_again: sin->sin_family = AF_INET; sin->sin_port = skb->h.uh->source; sin->sin_addr.s_addr = skb->nh.iph->saddr; + + /* FIXME: happy hacking */ + if ((sin->sin_addr.s_addr & IPI_LOOPBACK) == IPI_LOOPBACK) + sin->sin_addr.s_addr = IPI_LOOPBACK; + memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); } if (inet->cmsg_flags) @@ -1545,7 +1552,7 @@ void udp_proc_unregister(struct udp_seq_ static void udp4_format_sock(struct sock *sp, char *tmpbuf, int bucket) { struct inet_sock *inet = inet_sk(sp); - unsigned int dest = inet->daddr; + unsigned int dest = nx_rmap_addr(current->nx_info, inet->daddr); unsigned int src = inet->rcv_saddr; __u16 destp = ntohs(inet->dport); __u16 srcp = ntohs(inet->sport);