remove VServer ipv4root checks in favor of VNET limitations
authorMark Huang <mlhuang@cs.princeton.edu>
Wed, 4 Aug 2004 20:25:34 +0000 (20:25 +0000)
committerMark Huang <mlhuang@cs.princeton.edu>
Wed, 4 Aug 2004 20:25:34 +0000 (20:25 +0000)
18 files changed:
include/linux/netfilter_ipv4/ip_conntrack.h
include/linux/skbuff.h
include/net/route.h
include/net/sock.h
net/core/dev.c
net/core/netfilter.c
net/core/rtnetlink.c
net/core/skbuff.c
net/ipv4/af_inet.c
net/ipv4/devinet.c
net/ipv4/fib_hash.c
net/ipv4/netfilter/ip_conntrack_standalone.c
net/ipv4/netfilter/ipt_MARK.c
net/ipv4/raw.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_minisocks.c
net/ipv4/udp.c
net/packet/af_packet.c

index 1974f16..1ba82b4 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/netfilter_ipv4/ip_conntrack_tuple.h>
 #include <linux/bitops.h>
 #include <linux/compiler.h>
+#include <linux/vserver/context.h>
 #include <asm/atomic.h>
 
 enum ip_conntrack_info
@@ -207,6 +208,9 @@ struct ip_conntrack
        } nat;
 #endif /* CONFIG_IP_NF_NAT_NEEDED */
 
+       /* VServer context id */
+       xid_t xid;
+
 };
 
 /* get master conntrack via master expectation */
index 3d0ba45..f139821 100644 (file)
@@ -272,6 +272,7 @@ struct sk_buff {
  #endif
 
 #endif
+       xid_t                   xid;                    /* VServer context ID */
 
 
        /* These elements must be at the end, see alloc_skb() for details.  */
index 50c8cf0..a5e9c57 100644 (file)
@@ -33,9 +33,6 @@
 #include <linux/route.h>
 #include <linux/ip.h>
 #include <linux/cache.h>
-#include <linux/vs_base.h>
-#include <linux/vs_context.h>
-#include <linux/vs_network.h>
 
 #ifndef __KERNEL__
 #warning This file is not supposed to be used outside of kernel.
@@ -151,59 +148,6 @@ static inline char rt_tos2priority(u8 tos)
        return ip_tos2prio[IPTOS_TOS(tos)>>1];
 }
 
-#define IPI_LOOPBACK   0x0100007f
-
-static inline int ip_find_src(struct nx_info *nxi, struct rtable **rp, struct flowi *fl)
-{
-       int err;
-       int i, n = nxi->nbipv4;
-       u32 ipv4root = nxi->ipv4[0];
-
-       if (ipv4root == 0)
-               return 0;
-
-       if (fl->fl4_src == 0) {
-               if (n > 1) {
-                       u32 foundsrc;
-
-                       err = __ip_route_output_key(rp, fl);
-                       if (err) {
-                               fl->fl4_src = ipv4root;
-                               err = __ip_route_output_key(rp, fl);
-                       }
-                       if (err)
-                               return err;
-
-                       foundsrc = (*rp)->rt_src;
-                       ip_rt_put(*rp);
-
-                       for (i=0; i<n; i++){
-                               u32 mask = nxi->mask[i];
-                               u32 ipv4 = nxi->ipv4[i];
-                               u32 net4 = ipv4 & mask;
-
-                               if (foundsrc == ipv4) {
-                                       fl->fl4_src = ipv4;
-                                       break;
-                               }
-                               if (!fl->fl4_src && (foundsrc & mask) == net4)
-                                       fl->fl4_src = ipv4;
-                       }
-               }
-               if (fl->fl4_src == 0)
-                       fl->fl4_src = (fl->fl4_dst == IPI_LOOPBACK)
-                               ? IPI_LOOPBACK : ipv4root;
-       } else {
-               for (i=0; i<n; i++) {
-                       if (nxi->ipv4[i] == fl->fl4_src)
-                               break;
-               }
-               if (i == n)
-                       return -EPERM;
-       }
-       return 0;
-}
-
 static inline int ip_route_connect(struct rtable **rp, u32 dst,
                                   u32 src, u32 tos, int oif, u8 protocol,
                                   u16 sport, u16 dport, struct sock *sk)
@@ -218,22 +162,7 @@ static inline int ip_route_connect(struct rtable **rp, u32 dst,
                                         .dport = dport } } };
 
        int err;
-       struct nx_info *nx_info = current->nx_info;
-
-       if (sk)
-               nx_info = sk->sk_nx_info;
-       vxdprintk("ip_route_connect(%p) %p,%p;%lx\n",
-               sk, nx_info, sk->sk_socket,
-               (sk->sk_socket?sk->sk_socket->flags:0));
-
-       if (nx_info) {
-               err = ip_find_src(nx_info, rp, &fl);
-               if (err)
-                       return err;
-               if (fl.fl4_dst == IPI_LOOPBACK && !vx_check(0, VX_ADMIN))
-                       fl.fl4_dst = nx_info->ipv4[0];
-       }       
-       if (!fl.fl4_dst || !fl.fl4_src) {
+       if (!dst || !src) {
                err = __ip_route_output_key(rp, &fl);
                if (err)
                        return err;
index 3787663..ec26f83 100644 (file)
@@ -1075,6 +1075,12 @@ static inline int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
        int err = 0;
        int skb_len;
 
+       /* Silently drop if the context is not entitled to read the
+        * packet.
+        */
+       if (sk->sk_xid && sk->sk_xid != skb->xid)
+               goto out;
+
        /* Cast skb->rcvbuf to unsigned... It's pointless, but reduces
           number of warnings when compiling with -W --ANK
         */
index 944cd9a..1e21cd9 100644 (file)
 #include <linux/kallsyms.h>
 #include <linux/netpoll.h>
 #include <linux/rcupdate.h>
-#include <linux/vserver/network.h>
 #ifdef CONFIG_NET_RADIO
 #include <linux/wireless.h>            /* Note : will define WIRELESS_EXT */
 #include <net/iw_handler.h>
@@ -2096,8 +2095,6 @@ static int dev_ifconf(char __user *arg)
 
        total = 0;
        for (dev = dev_base; dev; dev = dev->next) {
-               if (!dev_in_nx_info(dev, current->nx_info))
-                       continue;
                for (i = 0; i < NPROTO; i++) {
                        if (gifconf_list[i]) {
                                int done;
@@ -2158,10 +2155,6 @@ void dev_seq_stop(struct seq_file *seq, void *v)
 
 static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev)
 {
-       struct nx_info *nxi = current->nx_info;
-
-       if (!dev_in_nx_info(dev, nxi))
-               return;
        if (dev->get_stats) {
                struct net_device_stats *stats = dev->get_stats(dev);
 
index 58632d1..e5e32b0 100644 (file)
@@ -204,6 +204,9 @@ void nf_dump_skb(int pf, struct sk_buff *skb)
 
                for (opti = 0; opti < (ip->ihl - sizeof(struct iphdr) / 4); opti++)
                        printk(" O=0x%8.8X", *opt++);
+               printk(" MARK=%lu (0x%lu)",
+                      (long unsigned int)skb->nfmark,
+                      (long unsigned int)skb->nfmark);
                printk("\n");
        }
        }
@@ -831,3 +834,6 @@ EXPORT_SYMBOL(nf_setsockopt);
 EXPORT_SYMBOL(nf_unregister_hook);
 EXPORT_SYMBOL(nf_unregister_queue_handler);
 EXPORT_SYMBOL(nf_unregister_sockopt);
+#ifdef CONFIG_NETFILTER_DEBUG
+EXPORT_SYMBOL(nf_dump_skb);
+#endif
index 95c9718..e652d8f 100644 (file)
@@ -226,8 +226,6 @@ int rtnetlink_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
        for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) {
                if (idx < s_idx)
                        continue;
-               if (!dev_in_nx_info(dev, current->nx_info))
-                       continue;
                if (rtnetlink_fill_ifinfo(skb, dev, RTM_NEWLINK, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, 0) <= 0)
                        break;
        }
@@ -313,8 +311,6 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change)
        struct sk_buff *skb;
        int size = NLMSG_GOODSIZE;
 
-       if (!dev_in_nx_info(dev, current->nx_info))
-               return;
        skb = alloc_skb(size, GFP_KERNEL);
        if (!skb)
                return;
index 0b44c0e..2df876a 100644 (file)
@@ -333,6 +333,7 @@ struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask)
 #endif
 
 #endif
+       C(xid);
        C(truesize);
        atomic_set(&n->users, 1);
        C(head);
@@ -391,6 +392,7 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
 #endif
        new->tc_index   = old->tc_index;
 #endif
+       new->xid        = old->xid;
        atomic_set(&new->users, 1);
 }
 
index f4f7a57..2c0ac07 100644 (file)
 #ifdef CONFIG_IP_MROUTE
 #include <linux/mroute.h>
 #endif
+#include <linux/vs_base.h>
+#include <linux/vs_context.h>
+#include <linux/vs_network.h>
 
 DEFINE_SNMP_STAT(struct linux_mib, net_statistics);
 
@@ -427,10 +430,6 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        unsigned short snum;
        int chk_addr_ret;
        int err;
-       __u32 s_addr;   /* Address used for validation */
-       __u32 s_addr1;
-       __u32 s_addr2 = 0xffffffffl;    /* Optional address of the socket */
-       struct nx_info *nxi = sk->sk_nx_info;
 
        /* If the socket has its own bind function then use it. (RAW) */
        if (sk->sk_prot->bind) {
@@ -441,36 +440,7 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        if (addr_len < sizeof(struct sockaddr_in))
                goto out;
 
-       s_addr = s_addr1 = addr->sin_addr.s_addr;
-       nxdprintk("inet_bind(%p) %p,%p;%lx\n",
-               sk, nx_info, sk->sk_socket,
-               (sk->sk_socket?sk->sk_socket->flags:0));
-       if (nxi) {
-               __u32 v4_bcast = nxi->v4_bcast;
-               __u32 ipv4root = nxi->ipv4[0];
-               int nbipv4 = nxi->nbipv4;
-               if (s_addr == 0) {
-                       s_addr = ipv4root;
-                       if (nbipv4 > 1)
-                               s_addr1 = 0;
-                       else {
-                               s_addr1 = ipv4root;
-                       }
-                       s_addr2 = v4_bcast;
-               } else if (s_addr == 0x0100007f) {
-                       s_addr = s_addr1 = ipv4root;
-               } else if (s_addr != v4_bcast) {
-                       int i;
-                       for (i=0; i<nbipv4; i++) {
-                               if (s_addr == nxi->ipv4[i])
-                                       break;
-                       }
-                       if (i == nbipv4) {
-                               return -EADDRNOTAVAIL;
-                       }
-               }
-       }
-       chk_addr_ret = inet_addr_type(s_addr);
+       chk_addr_ret = inet_addr_type(addr->sin_addr.s_addr);
 
        /* Not specified by any standard per-se, however it breaks too
         * many applications when removed.  It is unfortunate since
@@ -482,7 +452,7 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        err = -EADDRNOTAVAIL;
        if (!sysctl_ip_nonlocal_bind &&
            !inet->freebind &&
-           s_addr != INADDR_ANY &&
+           addr->sin_addr.s_addr != INADDR_ANY &&
            chk_addr_ret != RTN_LOCAL &&
            chk_addr_ret != RTN_MULTICAST &&
            chk_addr_ret != RTN_BROADCAST)
@@ -507,8 +477,7 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        if (sk->sk_state != TCP_CLOSE || inet->num)
                goto out_release_sock;
 
-       inet->rcv_saddr = inet->saddr = s_addr1;
-       inet->rcv_saddr2 = s_addr2;
+       inet->rcv_saddr = inet->saddr = addr->sin_addr.s_addr;
        if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST)
                inet->saddr = 0;  /* Use device */
 
index 8749432..2dc4e7a 100644 (file)
@@ -488,33 +488,6 @@ static __inline__ int inet_abc_len(u32 addr)
        return rc;
 }
 
-/*
-       Check that a device is not member of the ipv4root assigned to the process
-       Return true if this is the case
-
-       If the process is not bound to specific IP, then it returns 0 (all
-       interface are fine).
-*/
-static inline int devinet_notiproot (struct in_ifaddr *ifa)
-{
-       int ret = 0;
-       struct nx_info *nxi;
-
-       if ((nxi = current->nx_info)) {
-               int i;
-               int nbip = nxi->nbipv4;
-               __u32 addr = ifa->ifa_local;
-               ret = 1;
-               for (i=0; i<nbip; i++) {
-                       if(nxi->ipv4[i] == addr) {
-                               ret = 0;
-                               break;
-                       }
-               }
-       }
-       return ret;
-}
-
 
 int devinet_ioctl(unsigned int cmd, void __user *arg)
 {
@@ -622,8 +595,6 @@ int devinet_ioctl(unsigned int cmd, void __user *arg)
        ret = -EADDRNOTAVAIL;
        if (!ifa && cmd != SIOCSIFADDR && cmd != SIOCSIFFLAGS)
                goto done;
-       if (!ifa_in_nx_info(ifa, current->nx_info))
-               goto done;
 
        switch(cmd) {
        case SIOCGIFADDR:       /* Get interface address */
@@ -767,8 +738,6 @@ static int inet_gifconf(struct net_device *dev, char __user *buf, int len)
                goto out;
 
        for (; ifa; ifa = ifa->ifa_next) {
-               if (!ifa_in_nx_info(ifa, current->nx_info))
-                       continue;
                if (!buf) {
                        done += sizeof(ifr);
                        continue;
@@ -1104,8 +1073,6 @@ static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
                read_lock(&in_dev->lock);
                for (ifa = in_dev->ifa_list, ip_idx = 0; ifa;
                     ifa = ifa->ifa_next, ip_idx++) {
-                       if (!ifa_in_nx_info(ifa, current->nx_info))
-                               continue;
                        if (ip_idx < s_ip_idx)
                                continue;
                        if (inet_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid,
index 3b4f8e3..2316dfa 100644 (file)
@@ -1010,8 +1010,6 @@ static unsigned fib_flag_trans(int type, int dead, u32 mask, struct fib_info *fi
        return flags;
 }
 
-extern int dev_in_nx_info(struct net_device *, struct nx_info *);
-
 /* 
  *     This outputs /proc/net/route.
  *
@@ -1041,7 +1039,7 @@ static int fib_seq_show(struct seq_file *seq, void *v)
        mask    = FZ_MASK(iter->zone);
        flags   = fib_flag_trans(f->fn_type, f->fn_state & FN_S_ZOMBIE,
                                 mask, fi);
-       if (fi && dev_in_nx_info(fi->fib_dev, current->nx_info))
+       if (fi)
                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,
index 80edac9..fe5a980 100644 (file)
@@ -111,6 +111,8 @@ print_conntrack(char *buffer, struct ip_conntrack *conntrack)
                len += sprintf(buffer + len, "[ASSURED] ");
        len += sprintf(buffer + len, "use=%u ",
                       atomic_read(&conntrack->ct_general.use));
+       len += sprintf(buffer + len, "xid=%d ",
+                      conntrack->xid);
        len += sprintf(buffer + len, "\n");
 
        return len;
index 06bcb8d..0931c14 100644 (file)
@@ -50,10 +50,12 @@ checkentry(const char *tablename,
                return 0;
        }
 
+#if 0
        if (strcmp(tablename, "mangle") != 0) {
                printk(KERN_WARNING "MARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
                return 0;
        }
+#endif
 
        return 1;
 }
index b956390..41aaa7c 100644 (file)
@@ -79,6 +79,7 @@
 #include <linux/seq_file.h>
 #include <linux/netfilter.h>
 #include <linux/netfilter_ipv4.h>
+#include <linux/vs_base.h>
 
 struct hlist_head raw_v4_htable[RAWV4_HTABLE_SIZE];
 rwlock_t raw_v4_lock = RW_LOCK_UNLOCKED;
@@ -102,38 +103,6 @@ static void raw_v4_unhash(struct sock *sk)
        write_unlock_bh(&raw_v4_lock);
 }
 
-
-/*
-       Check if an address is in the list
-*/
-static inline int raw_addr_in_list (
-       u32 rcv_saddr1,
-       u32 rcv_saddr2,
-       u32 loc_addr,
-       struct nx_info *nx_info)
-{
-       int ret = 0;
-       if (loc_addr != 0 &&
-               (rcv_saddr1 == loc_addr || rcv_saddr2 == loc_addr))
-               ret = 1;
-       else if (rcv_saddr1 == 0) {
-               /* Accept any address or only the one in the list */
-               if (nx_info == NULL)
-                       ret = 1;
-               else {
-                       int n = nx_info->nbipv4;
-                       int i;
-                       for (i=0; i<n; i++) {
-                               if (nx_info->ipv4[i] == loc_addr) {
-                                       ret = 1;
-                                       break;
-                               }
-                       }
-               }
-       }
-       return ret;
-}
-
 struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num,
                             unsigned long raddr, unsigned long laddr,
                             int dif)
@@ -145,8 +114,7 @@ struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num,
 
                if (inet->num == num                                    &&
                    !(inet->daddr && inet->daddr != raddr)              &&
-                   raw_addr_in_list(inet->rcv_saddr, inet->rcv_saddr2,
-                       laddr, sk->sk_nx_info) &&
+                   !(inet->rcv_saddr && inet->rcv_saddr != laddr)      &&
                    !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
                        goto found; /* gotcha */
        }
@@ -462,13 +430,6 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                                    .proto = inet->hdrincl ? IPPROTO_RAW :
                                                             sk->sk_protocol,
                                  };
-               
-               if (sk->sk_nx_info) {
-                       err = ip_find_src(sk->sk_nx_info, &rt, &fl);
-
-                       if (err)
-                               goto done;
-               }
                err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT));
        }
        if (err)
index 1f268b7..97a0eea 100644 (file)
@@ -75,6 +75,8 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 
+#include <linux/vs_base.h>
+
 extern int sysctl_ip_dynaddr;
 int sysctl_tcp_tw_reuse;
 int sysctl_tcp_low_latency;
@@ -179,63 +181,9 @@ void tcp_bind_hash(struct sock *sk, struct tcp_bind_bucket *tb,
        tcp_sk(sk)->bind_hash = tb;
 }
 
-/*
-       Return 1 if addr match the socket IP list
-       or the socket is INADDR_ANY
-*/
-static inline int tcp_in_list(struct sock *sk, u32 addr)
-{
-       struct nx_info *nxi = sk->sk_nx_info;
-
-       vxdprintk("tcp_in_list(%p) %p,%p;%lx\n",
-               sk, nxi, sk->sk_socket,
-               (sk->sk_socket?sk->sk_socket->flags:0));
-
-       if (nxi) {
-               int n = nxi->nbipv4;
-               int i;
-
-               for (i=0; i<n; i++)
-                       if (nxi->ipv4[i] == addr)
-                               return 1;
-       }
-       else if (!tcp_v4_rcv_saddr(sk) || tcp_v4_rcv_saddr(sk) == addr)
-               return 1;
-       return 0;
-}
-       
-/*
-       Check if the addresses in sk1 conflict with those in sk2
-*/
-int tcp_ipv4_addr_conflict(struct sock *sk1, struct sock *sk2)
-{
-       if (sk1 && sk2)
-       nxdprintk("inet_bind(%p,%p) %p,%p;%lx %p,%p;%lx\n",
-               sk1, sk2,
-               sk1->sk_nx_info, sk1->sk_socket,
-               (sk1->sk_socket?sk1->sk_socket->flags:0),
-               sk2->sk_nx_info, sk2->sk_socket,
-               (sk2->sk_socket?sk2->sk_socket->flags:0));
-
-       if (tcp_v4_rcv_saddr(sk1)) {
-               /* Bind to one address only */
-               return tcp_in_list (sk2, tcp_v4_rcv_saddr(sk1));
-       } else if (sk1->sk_nx_info) {
-               /* A restricted bind(any) */
-               struct nx_info *nxi = sk1->sk_nx_info;
-               int n = nxi->nbipv4;
-               int i;
-
-               for (i=0; i<n; i++)
-                       if (tcp_in_list (sk2, nxi->ipv4[i]))
-                               return 1;
-       } else  /* A bind(any) do not allow other bind on the same port */
-               return 1;
-       return 0;
-}
-
 static inline int tcp_bind_conflict(struct sock *sk, struct tcp_bind_bucket *tb)
 {
+       const u32 sk_rcv_saddr = tcp_v4_rcv_saddr(sk);
        struct sock *sk2;
        struct hlist_node *node;
        int reuse = sk->sk_reuse;
@@ -248,7 +196,9 @@ static inline int tcp_bind_conflict(struct sock *sk, struct tcp_bind_bucket *tb)
                     sk->sk_bound_dev_if == sk2->sk_bound_dev_if)) {
                        if (!reuse || !sk2->sk_reuse ||
                            sk2->sk_state == TCP_LISTEN) {
-                               if (tcp_ipv4_addr_conflict(sk, sk2))
+                               const u32 sk2_rcv_saddr = tcp_v4_rcv_saddr(sk2);
+                               if (!sk2_rcv_saddr || !sk_rcv_saddr ||
+                                   sk2_rcv_saddr == sk_rcv_saddr)
                                        break;
                        }
                }
@@ -457,34 +407,6 @@ void tcp_unhash(struct sock *sk)
                wake_up(&tcp_lhash_wait);
 }
 
-/*
-       Check if an address is in the list
-*/
-static inline int tcp_addr_in_list(
-       u32 rcv_saddr,
-       u32 daddr,
-       struct nx_info *nx_info)
-{
-       if (rcv_saddr == daddr)
-               return 1;
-       else if (rcv_saddr == 0) {
-               /* Accept any address or check the list */
-               if (!nx_info)
-                       return 1;
-               else {
-                       int n = nx_info->nbipv4;
-                       int i;
-
-                       for (i=0; i<n; i++)
-                               if (nx_info->ipv4[i] == daddr)
-                                       return 1;
-               }
-       }
-       return 0;
-}
-
-
-
 /* Don't inline this cruft.  Here are some nice properties to
  * exploit here.  The BSD API does not allow a listening TCP
  * to specify the remote port nor the remote address for the
@@ -506,10 +428,11 @@ static struct sock *__tcp_v4_lookup_listener(struct hlist_head *head, u32 daddr,
                        __u32 rcv_saddr = inet->rcv_saddr;
 
                        score = (sk->sk_family == PF_INET ? 1 : 0);
-                       if (tcp_addr_in_list(rcv_saddr, daddr, sk->sk_nx_info))
+                       if (rcv_saddr) {
+                               if (rcv_saddr != daddr)
+                                       continue;
                                score+=2;
-                       else
-                               continue;
+                       }
                        if (sk->sk_bound_dev_if) {
                                if (sk->sk_bound_dev_if != dif)
                                        continue;
@@ -538,8 +461,8 @@ inline struct sock *tcp_v4_lookup_listener(u32 daddr, unsigned short hnum,
        if (!hlist_empty(head)) {
                struct inet_opt *inet = inet_sk((sk = __sk_head(head)));
                if (inet->num == hnum && !sk->sk_node.next &&
+                   (!inet->rcv_saddr || inet->rcv_saddr == daddr) &&
                    (sk->sk_family == PF_INET || !ipv6_only_sock(sk)) &&
-                   tcp_addr_in_list(inet->rcv_saddr, daddr, sk->sk_nx_info) &&
                    !sk->sk_bound_dev_if)
                        goto sherry_cache;
                sk = __tcp_v4_lookup_listener(head, daddr, hnum, dif);
@@ -1891,6 +1814,12 @@ int tcp_v4_rcv(struct sk_buff *skb)
                goto no_tcp_socket;
 
 process:
+       /* Silently drop if the context is not entitled to read the
+        * packet.
+        */
+       if (sk->sk_xid && sk->sk_xid != skb->xid)
+               goto discard_it;
+
        if (sk->sk_state == TCP_TIME_WAIT)
                goto do_time_wait;
 
index 1411541..a8da77f 100644 (file)
@@ -26,6 +26,8 @@
 #include <linux/sysctl.h>
 #include <linux/workqueue.h>
 #include <linux/vs_socket.h>
+#include <linux/vs_context.h>
+#include <linux/vs_network.h>
 #include <net/tcp.h>
 #include <net/inet_common.h>
 #include <net/xfrm.h>
index ec17e32..9c64e45 100644 (file)
 #include <net/inet_common.h>
 #include <net/checksum.h>
 #include <net/xfrm.h>
+#include <linux/vs_base.h>
 
 /*
  *     Snmp MIB for the UDP layer
@@ -120,8 +121,6 @@ rwlock_t udp_hash_lock = RW_LOCK_UNLOCKED;
 /* Shared by v4/v6 udp. */
 int udp_port_rover;
 
-int tcp_ipv4_addr_conflict(struct sock *sk1, struct sock *sk2);
-
 static int udp_v4_get_port(struct sock *sk, unsigned short snum)
 {
        struct hlist_node *node;
@@ -181,7 +180,9 @@ gotit:
                            (!sk2->sk_bound_dev_if ||
                             !sk->sk_bound_dev_if ||
                             sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
-                           tcp_ipv4_addr_conflict(sk2, sk) &&
+                           (!inet2->rcv_saddr ||
+                            !inet->rcv_saddr ||
+                            inet2->rcv_saddr == inet->rcv_saddr) &&
                            (!sk2->sk_reuse || !sk->sk_reuse))
                                goto fail;
                }
@@ -216,17 +217,6 @@ static void udp_v4_unhash(struct sock *sk)
        write_unlock_bh(&udp_hash_lock);
 }
 
-static inline int udp_in_list(struct nx_info *nx_info, u32 addr)
-{
-       int n = nx_info->nbipv4;
-       int i;
-
-       for (i=0; i<n; i++)
-               if (nx_info->ipv4[i] == addr)
-                       return 1;
-       return 0;
-}
-
 /* UDP is nearly always wildcards out the wazoo, it makes no sense to try
  * harder than this. -DaveM
  */
@@ -246,11 +236,6 @@ struct sock *udp_v4_lookup_longway(u32 saddr, u16 sport, u32 daddr, u16 dport, i
                                if (inet->rcv_saddr != daddr)
                                        continue;
                                score+=2;
-                       } else if (sk->sk_nx_info) {
-                               if (udp_in_list(sk->sk_nx_info, daddr))
-                                       score+=2;
-                               else
-                                       continue;
                        }
                        if (inet->daddr) {
                                if (inet->daddr != saddr)
@@ -306,8 +291,7 @@ static inline struct sock *udp_v4_mcast_next(struct sock *sk,
                if (inet->num != hnum                                   ||
                    (inet->daddr && inet->daddr != rmt_addr)            ||
                    (inet->dport != rmt_port && inet->dport)            ||
-                   (inet->rcv_saddr && inet->rcv_saddr != loc_addr &&
-                    inet->rcv_saddr2 && inet->rcv_saddr2 != loc_addr)  ||
+                   (inet->rcv_saddr && inet->rcv_saddr != loc_addr)    ||
                    ipv6_only_sock(s)                                   ||
                    (s->sk_bound_dev_if && s->sk_bound_dev_if != dif))
                        continue;
@@ -616,15 +600,6 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                                    .uli_u = { .ports =
                                               { .sport = inet->sport,
                                                 .dport = dport } } };
-               struct nx_info *nxi = sk->sk_nx_info;
-
-               if (nxi) {
-                       err = ip_find_src(nxi, &rt, &fl);
-                       if (err)
-                               goto out;
-                       if (daddr == IPI_LOOPBACK && !vx_check(0, VX_ADMIN))
-                               daddr = fl.fl4_dst = nxi->ipv4[0];
-               }
                err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT));
                if (err)
                        goto out;
index 93ac3b3..429cb4b 100644 (file)
@@ -70,6 +70,9 @@
 #include <linux/poll.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/vs_base.h>
+#include <linux/vs_context.h>
+#include <linux/vs_network.h>
 
 #ifdef CONFIG_INET
 #include <net/inet_common.h>
@@ -217,6 +220,8 @@ void packet_sock_destruct(struct sock *sk)
 {
        BUG_TRAP(!atomic_read(&sk->sk_rmem_alloc));
        BUG_TRAP(!atomic_read(&sk->sk_wmem_alloc));
+       BUG_ON(sk->sk_nx_info);
+       BUG_ON(sk->sk_vx_info);
 
        if (!sock_flag(sk, SOCK_DEAD)) {
                printk("Attempt to release alive packet socket: %p\n", sk);
@@ -449,6 +454,9 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev,  struct packe
        sk = pt->af_packet_priv;
        po = pkt_sk(sk);
 
+       if (sk->sk_xid && sk->sk_xid != skb->xid)
+               goto drop;
+
        skb->dev = dev;
 
        if (dev->hard_header) {
@@ -819,6 +827,9 @@ static int packet_release(struct socket *sock)
        }
 #endif
 
+       clr_vx_info(&sk->sk_vx_info);
+       clr_nx_info(&sk->sk_nx_info);
+
        /*
         *      Now the socket is dead. No more input will appear.
         */
@@ -994,6 +1005,11 @@ static int packet_create(struct socket *sock, int protocol)
        sk->sk_destruct = packet_sock_destruct;
        atomic_inc(&packet_socks_nr);
 
+       set_vx_info(&sk->sk_vx_info, current->vx_info);
+       sk->sk_xid = vx_current_xid();
+       set_nx_info(&sk->sk_nx_info, current->nx_info);
+       sk->sk_nid = nx_current_nid();
+
        /*
         *      Attach a protocol block
         */
@@ -1779,12 +1795,14 @@ struct proto_ops packet_ops = {
        .mmap =         packet_mmap,
        .sendpage =     sock_no_sendpage,
 };
+EXPORT_SYMBOL(packet_ops);
 
-static struct net_proto_family packet_family_ops = {
+struct net_proto_family packet_family_ops = {
        .family =       PF_PACKET,
        .create =       packet_create,
        .owner  =       THIS_MODULE,
 };
+EXPORT_SYMBOL(packet_family_ops);
 
 static struct notifier_block packet_netdev_notifier = {
        .notifier_call =packet_notifier,