--- olpc-2.6-master.00/net/core/dev.c 2007-02-28 20:05:29.000000000 -0500 +++ olpc-2.6-master-vs22x.02/net/core/dev.c 2007-03-01 17:09:59.000000000 -0500 @@ -2048,6 +2049,8 @@ static int dev_ifconf(char __user *arg) total = 0; for (dev = dev_base; dev; dev = dev->next) { + if (!nx_dev_visible(current->nx_info, dev)) + continue; for (i = 0; i < NPROTO; i++) { if (gifconf_list[i]) { int done; --- olpc-2.6-master.00/net/core/dev.c 2007-02-28 20:05:29.000000000 -0500 +++ olpc-2.6-master-vs22x.02/net/core/dev.c 2007-03-01 17:09:59.000000000 -0500 @@ -2108,6 +2111,8 @@ void dev_seq_stop(struct seq_file *seq, static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev) { + if (!nx_dev_visible(current->nx_info, dev)) + return; if (dev->get_stats) { struct net_device_stats *stats = dev->get_stats(dev); --- olpc-2.6-master.00/net/core/rtnetlink.c 2007-02-28 20:05:29.000000000 -0500 +++ olpc-2.6-master-vs22x.02/net/core/rtnetlink.c 2007-03-01 17:09:59.000000000 -0500 @@ -397,6 +397,8 @@ static int rtnl_dump_ifinfo(struct sk_bu for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) { if (idx < s_idx) continue; + if (!nx_dev_visible(skb->sk->sk_nx_info, dev)) + continue; if (rtnl_fill_ifinfo(skb, dev, NULL, 0, RTM_NEWLINK, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, 0, NLM_F_MULTI) <= 0) --- olpc-2.6-master.00/net/core/rtnetlink.c 2007-02-28 20:05:29.000000000 -0500 +++ olpc-2.6-master-vs22x.02/net/core/rtnetlink.c 2007-03-01 17:09:59.000000000 -0500 @@ -676,6 +678,9 @@ void rtmsg_ifinfo(int type, struct net_d struct sk_buff *skb; int err = -ENOBUFS; + if (!nx_dev_visible(current->nx_info, dev)) + return; + skb = nlmsg_new(if_nlmsg_size(0), GFP_KERNEL); if (skb == NULL) goto errout; --- olpc-2.6-master.00/net/ipv4/devinet.c 2007-02-28 20:05:29.000000000 -0500 +++ olpc-2.6-master-vs22x.02/net/ipv4/devinet.c 2007-03-01 17:09:59.000000000 -0500 @@ -676,6 +676,8 @@ int devinet_ioctl(unsigned int cmd, void *colon = ':'; if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) { + struct nx_info *nxi = current->nx_info; + if (tryaddrmatch) { /* Matthias Andree */ /* compare label and address (4.4BSD style) */ --- olpc-2.6-master.00/net/ipv4/devinet.c 2007-02-28 20:05:29.000000000 -0500 +++ olpc-2.6-master-vs22x.02/net/ipv4/devinet.c 2007-03-01 17:09:59.000000000 -0500 @@ -684,6 +686,8 @@ int devinet_ioctl(unsigned int cmd, void This is checked above. */ for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; ifap = &ifa->ifa_next) { + if (!nx_ifa_visible(nxi, ifa)) + continue; if (!strcmp(ifr.ifr_name, ifa->ifa_label) && sin_orig.sin_addr.s_addr == ifa->ifa_address) { --- olpc-2.6-master.00/net/ipv4/devinet.c 2007-02-28 20:05:29.000000000 -0500 +++ olpc-2.6-master-vs22x.02/net/ipv4/devinet.c 2007-03-01 17:09:59.000000000 -0500 @@ -696,9 +700,12 @@ int devinet_ioctl(unsigned int cmd, void comparing just the label */ if (!ifa) { for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; - ifap = &ifa->ifa_next) + ifap = &ifa->ifa_next) { + if (!nx_ifa_visible(nxi, ifa)) + continue; if (!strcmp(ifr.ifr_name, ifa->ifa_label)) break; + } } } --- olpc-2.6-master.00/net/ipv4/devinet.c 2007-02-28 20:05:29.000000000 -0500 +++ olpc-2.6-master-vs22x.02/net/ipv4/devinet.c 2007-03-01 17:09:59.000000000 -0500 @@ -849,6 +856,8 @@ static int inet_gifconf(struct net_devic goto out; for (; ifa; ifa = ifa->ifa_next) { + if (!nx_ifa_visible(current->nx_info, ifa)) + continue; if (!buf) { done += sizeof(ifr); continue; --- olpc-2.6-master.00/net/ipv4/devinet.c 2007-02-28 20:05:29.000000000 -0500 +++ olpc-2.6-master-vs22x.02/net/ipv4/devinet.c 2007-03-01 17:09:59.000000000 -0500 @@ -1178,6 +1187,7 @@ static int inet_dump_ifaddr(struct sk_bu struct net_device *dev; struct in_device *in_dev; struct in_ifaddr *ifa; + struct sock *sk = skb->sk; int s_ip_idx, s_idx = cb->args[0]; s_ip_idx = ip_idx = cb->args[1]; --- olpc-2.6-master.00/net/ipv4/devinet.c 2007-02-28 20:05:29.000000000 -0500 +++ olpc-2.6-master-vs22x.02/net/ipv4/devinet.c 2007-03-01 17:09:59.000000000 -0500 @@ -1195,6 +1205,8 @@ static int inet_dump_ifaddr(struct sk_bu for (ifa = in_dev->ifa_list, ip_idx = 0; ifa; ifa = ifa->ifa_next, ip_idx++) { + if (sk && !nx_ifa_visible(sk->sk_nx_info, ifa)) + continue; if (ip_idx < s_ip_idx) continue; if (inet_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid, --- olpc-2.6-master.00/net/ipv4/fib_hash.c 2007-02-28 20:05:29.000000000 -0500 +++ olpc-2.6-master-vs22x.02/net/ipv4/fib_hash.c 2007-03-01 17:09:59.000000000 -0500 @@ -1010,7 +1010,7 @@ static int fib_seq_show(struct seq_file prefix = f->fn_key; mask = FZ_MASK(iter->zone); flags = fib_flag_trans(fa->fa_type, mask, fi); - if (fi) + if (fi && nx_dev_visible(current->nx_info, fi->fib_dev)) snprintf(bf, sizeof(bf), "%s\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u", fi->fib_dev ? fi->fib_dev->name : "*", prefix, --- olpc-2.6-master.00/net/ipv4/inet_diag.c 2007-02-28 20:05:29.000000000 -0500 +++ olpc-2.6-master-vs22x.02/net/ipv4/inet_diag.c 2007-03-01 11:52:20.000000000 -0500 @@ -696,6 +696,8 @@ static int inet_diag_dump(struct sk_buff sk_for_each(sk, node, &hashinfo->listening_hash[i]) { struct inet_sock *inet = inet_sk(sk); + if (!nx_check(sk->sk_nid, VS_WATCH_P|VS_IDENT)) + continue; if (num < s_num) { num++; continue; --- olpc-2.6-master.00/net/ipv4/inet_diag.c 2007-02-28 20:05:29.000000000 -0500 +++ olpc-2.6-master-vs22x.02/net/ipv4/inet_diag.c 2007-03-01 11:52:20.000000000 -0500 @@ -756,6 +758,8 @@ skip_listen_ht: sk_for_each(sk, node, &head->chain) { struct inet_sock *inet = inet_sk(sk); + if (!nx_check(sk->sk_nid, VS_WATCH_P|VS_IDENT)) + continue; if (num < s_num) goto next_normal; if (!(r->idiag_states & (1 << sk->sk_state))) --- olpc-2.6-master.00/net/ipv4/inet_diag.c 2007-02-28 20:05:29.000000000 -0500 +++ olpc-2.6-master-vs22x.02/net/ipv4/inet_diag.c 2007-03-01 11:52:20.000000000 -0500 @@ -780,6 +784,8 @@ next_normal: inet_twsk_for_each(tw, node, &head->twchain) { + if (!nx_check(tw->tw_nid, VS_WATCH_P|VS_IDENT)) + continue; if (num < s_num) goto next_dying; if (r->id.idiag_sport != tw->tw_sport && --- olpc-2.6-master.00/net/ipv4/raw.c 2007-02-28 20:05:29.000000000 -0500 +++ olpc-2.6-master-vs22x.02/net/ipv4/raw.c 2007-03-01 17:09:59.000000000 -0500 @@ -793,7 +807,8 @@ static struct sock *raw_get_first(struct struct hlist_node *node; sk_for_each(sk, node, &raw_v4_htable[state->bucket]) - if (sk->sk_family == PF_INET) + if (sk->sk_family == PF_INET && + nx_check(sk->sk_nid, VS_WATCH_P|VS_IDENT)) goto found; } sk = NULL; --- olpc-2.6-master.00/net/ipv4/raw.c 2007-02-28 20:05:29.000000000 -0500 +++ olpc-2.6-master-vs22x.02/net/ipv4/raw.c 2007-03-01 17:09:59.000000000 -0500 @@ -809,7 +824,8 @@ static struct sock *raw_get_next(struct sk = sk_next(sk); try_again: ; - } while (sk && sk->sk_family != PF_INET); + } while (sk && (sk->sk_family != PF_INET || + !nx_check(sk->sk_nid, VS_WATCH_P|VS_IDENT))); if (!sk && ++state->bucket < RAWV4_HTABLE_SIZE) { sk = sk_head(&raw_v4_htable[state->bucket]); --- olpc-2.6-master.00/net/ipv4/tcp_ipv4.c 2007-02-28 20:05:29.000000000 -0500 +++ olpc-2.6-master-vs22x.02/net/ipv4/tcp_ipv4.c 2007-03-01 11:52:20.000000000 -0500 @@ -1968,6 +1969,12 @@ static void *listening_get_next(struct s req = req->dl_next; while (1) { while (req) { + vxdprintk(VXD_CBIT(net, 6), + "sk,req: %p [#%d] (from %d)", req->sk, + (req->sk)?req->sk->sk_nid:0, nx_current_nid()); + if (req->sk && + !nx_check(req->sk->sk_nid, VS_WATCH_P|VS_IDENT)) + continue; if (req->rsk_ops->family == st->family) { cur = req; goto out; --- olpc-2.6-master.00/net/ipv4/tcp_ipv4.c 2007-02-28 20:05:29.000000000 -0500 +++ olpc-2.6-master-vs22x.02/net/ipv4/tcp_ipv4.c 2007-03-01 11:52:20.000000000 -0500 @@ -1992,6 +1999,10 @@ get_req: } get_sk: sk_for_each_from(sk, node) { + vxdprintk(VXD_CBIT(net, 6), "sk: %p [#%d] (from %d)", + sk, sk->sk_nid, nx_current_nid()); + if (!nx_check(sk->sk_nid, VS_WATCH_P|VS_IDENT)) + continue; if (sk->sk_family == st->family) { cur = sk; goto out; --- olpc-2.6-master.00/net/ipv4/tcp_ipv4.c 2007-02-28 20:05:29.000000000 -0500 +++ olpc-2.6-master-vs22x.02/net/ipv4/tcp_ipv4.c 2007-03-01 11:52:20.000000000 -0500 @@ -2043,9 +2054,13 @@ static void *established_get_first(struc read_lock(&tcp_hashinfo.ehash[st->bucket].lock); sk_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) { - if (sk->sk_family != st->family) { + vxdprintk(VXD_CBIT(net, 6), + "sk,egf: %p [#%d] (from %d)", + sk, sk->sk_nid, nx_current_nid()); + if (!nx_check(sk->sk_nid, VS_WATCH_P|VS_IDENT)) + continue; + if (sk->sk_family != st->family) continue; - } rc = sk; goto out; } --- olpc-2.6-master.00/net/ipv4/tcp_ipv4.c 2007-02-28 20:05:29.000000000 -0500 +++ olpc-2.6-master-vs22x.02/net/ipv4/tcp_ipv4.c 2007-03-01 11:52:20.000000000 -0500 @@ -2052,9 +2067,13 @@ ***** st->state = TCP_SEQ_STATE_TIME_WAIT; inet_twsk_for_each(tw, node, &tcp_hashinfo.ehash[st->bucket].twchain) { - if (tw->tw_family != st->family) { + vxdprintk(VXD_CBIT(net, 6), + "tw: %p [#%d] (from %d)", + tw, tw->tw_nid, nx_current_nid()); + if (!nx_check(tw->tw_nid, VS_WATCH_P|VS_IDENT)) + continue; + if (tw->tw_family != st->family) continue; - } rc = tw; goto out; } --- olpc-2.6-master.00/net/ipv4/tcp_ipv4.c 2007-02-28 20:05:29.000000000 -0500 +++ olpc-2.6-master-vs22x.02/net/ipv4/tcp_ipv4.c 2007-03-01 11:52:20.000000000 -0500 @@ -2078,7 +2097,8 @@ static void *established_get_next(struct tw = cur; tw = tw_next(tw); get_tw: - while (tw && tw->tw_family != st->family) { + while (tw && (tw->tw_family != st->family || + !nx_check(tw->tw_nid, VS_WATCH_P|VS_IDENT))) { tw = tw_next(tw); } if (tw) { --- olpc-2.6-master.00/net/ipv4/tcp_ipv4.c 2007-02-28 20:05:29.000000000 -0500 +++ olpc-2.6-master-vs22x.02/net/ipv4/tcp_ipv4.c 2007-03-01 11:52:20.000000000 -0500 @@ -2102,6 +2122,11 @@ get_tw: sk = sk_next(sk); sk_for_each_from(sk, node) { + vxdprintk(VXD_CBIT(net, 6), + "sk,egn: %p [#%d] (from %d)", + sk, sk->sk_nid, nx_current_nid()); + if (!nx_check(sk->sk_nid, VS_WATCH_P|VS_IDENT)) + continue; if (sk->sk_family == st->family) goto found; } --- olpc-2.6-master.00/net/ipv4/udp.c 2007-02-28 20:05:29.000000000 -0500 +++ olpc-2.6-master-vs22x.02/net/ipv4/udp.c 2007-03-01 17:12:45.000000000 -0500 @@ -1541,7 +1550,8 @@ static struct sock *udp_get_first(struct for (state->bucket = 0; state->bucket < UDP_HTABLE_SIZE; ++state->bucket) { struct hlist_node *node; sk_for_each(sk, node, state->hashtable + state->bucket) { - if (sk->sk_family == state->family) + if (sk->sk_family == state->family && + nx_check(sk->sk_nid, VS_WATCH_P|VS_IDENT)) goto found; } } --- olpc-2.6-master.00/net/ipv4/udp.c 2007-02-28 20:05:29.000000000 -0500 +++ olpc-2.6-master-vs22x.02/net/ipv4/udp.c 2007-03-01 17:12:45.000000000 -0500 @@ -1558,7 +1568,8 @@ static struct sock *udp_get_next(struct sk = sk_next(sk); try_again: ; - } while (sk && sk->sk_family != state->family); + } while (sk && (sk->sk_family != state->family || + !nx_check(sk->sk_nid, VS_WATCH_P|VS_IDENT))); if (!sk && ++state->bucket < UDP_HTABLE_SIZE) { sk = sk_head(state->hashtable + state->bucket); --- olpc-2.6-master.00/kernel/vserver/inet.c 1969-12-31 19:00:00.000000000 -0500 +++ olpc-2.6-master-vs22x.02/kernel/vserver/inet.c 2007-03-01 17:09:59.000000000 -0500 @@ -0,0 +1,56 @@ + +#include +#include + + +int nx_addr_conflict(struct nx_info *nxi, uint32_t addr, const struct sock *sk) +{ + vxdprintk(VXD_CBIT(net, 2), + "nx_addr_conflict(%p,%p) %d.%d,%d.%d", + nxi, sk, VXD_QUAD(addr)); + + if (addr) { + /* check real address */ + return __addr_in_socket(sk, addr); + } else if (nxi) { + /* check against nx_info */ + int i, n = nxi->nbipv4; + + for (i=0; iipv4[i])) + return 1; + return 0; + } else { + /* check against any */ + return 1; + } +} + + +int dev_in_nx_info(struct net_device *dev, struct nx_info *nxi) +{ + struct in_device *in_dev; + struct in_ifaddr **ifap; + struct in_ifaddr *ifa; + int ret = 0; + + if (!nxi) + return 1; + + in_dev = in_dev_get(dev); + if (!in_dev) + goto out; + + for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; + ifap = &ifa->ifa_next) { + if (addr_in_nx_info(nxi, ifa->ifa_local)) { + ret = 1; + break; + } + } + in_dev_put(in_dev); +out: + return ret; +} + +