new VNET
authorDaniel Hokka Zakrisson <dhokka@cs.princeton.edu>
Fri, 6 Jul 2007 14:28:42 +0000 (14:28 +0000)
committerDaniel Hokka Zakrisson <dhokka@cs.princeton.edu>
Fri, 6 Jul 2007 14:28:42 +0000 (14:28 +0000)
21 files changed:
include/linux/netfilter/xt_MARK.h
include/linux/netfilter/xt_SETXID.h [new file with mode: 0644]
include/linux/netfilter_ipv4/ipt_MARK.h
include/linux/netfilter_ipv4/ipt_SETXID.h [new file with mode: 0644]
include/linux/socket.h
include/linux/vs_network.h
include/linux/vserver/base.h
include/linux/vserver/network.h
include/net/raw.h
net/core/skbuff.c
net/core/sock.c
net/ipv4/af_inet.c
net/ipv4/icmp.c
net/ipv4/ip_options.c
net/ipv4/netfilter/ipt_LOG.c
net/ipv4/raw.c
net/netfilter/Makefile
net/netfilter/xt_MARK.c
net/netfilter/xt_OLDMARK.c [new file with mode: 0644]
net/netfilter/xt_SETXID.c [new file with mode: 0644]
net/packet/af_packet.c

index b021e93..976ab68 100644 (file)
@@ -11,6 +11,7 @@ enum {
        XT_MARK_SET=0,
        XT_MARK_AND,
        XT_MARK_OR,
+       XT_MARK_COPYXID
 };
 
 struct xt_mark_target_info_v1 {
diff --git a/include/linux/netfilter/xt_SETXID.h b/include/linux/netfilter/xt_SETXID.h
new file mode 100644 (file)
index 0000000..6b7fcff
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef _XT_SETXID_H_target
+#define _XT_SETXID_H_target
+
+/* Version 1 */
+enum {
+       XT_SET_PACKET_XID=0
+};
+
+struct xt_setxid_target_info_v1 {
+       unsigned long mark;
+       u_int8_t mode;
+};
+
+#endif /*_XT_SETXID_H_target*/
index 697a486..679fab9 100644 (file)
@@ -9,9 +9,10 @@
 #define ipt_mark_target_info xt_mark_target_info
 
 /* Version 1 */
-#define IPT_MARK_SET   XT_MARK_SET
-#define IPT_MARK_AND   XT_MARK_AND
-#define        IPT_MARK_OR     XT_MARK_OR
+#define IPT_MARK_SET           XT_MARK_SET
+#define IPT_MARK_AND           XT_MARK_AND
+#define        IPT_MARK_OR             XT_MARK_OR
+#define IPT_MARK_COPYXID       XT_MARK_COPYXID
 
 #define ipt_mark_target_info_v1 xt_mark_target_info_v1
 
diff --git a/include/linux/netfilter_ipv4/ipt_SETXID.h b/include/linux/netfilter_ipv4/ipt_SETXID.h
new file mode 100644 (file)
index 0000000..39f35a1
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef _IPT_SETXID_H_target
+#define _IPT_SETXID_H_target
+
+/* Backwards compatibility for old userspace */
+
+#include <linux/netfilter/xt_SETXID.h>
+
+/* Version 1 */
+#define IPT_SET_PACKET_XID     XT_SET_PACKET_XID
+
+#define ipt_setxid_target_info_v1 xt_setxid_target_info_v1
+
+#endif /*_IPT_SETXID_H_target*/
index 92cd38e..46e6335 100644 (file)
@@ -283,6 +283,8 @@ struct ucred {
 #define SOL_NETLINK    270
 #define SOL_TIPC       271
 
+#define SO_SETXID      SO_PEERCRED
+
 /* IPX options */
 #define IPX_TYPE       1
 
index f2cf3ab..a99d0e4 100644 (file)
@@ -178,6 +178,12 @@ static inline void exit_nx_info(struct task_struct *p)
 }
 
 
+#ifdef CONFIG_NETWORK_SECMARK
+#define skb_tag secmark
+#else
+#define skb_tag mark
+#endif
+
 #else
 #warning duplicate inclusion
 #endif
index 3261ea0..f68e2cf 100644 (file)
@@ -219,6 +219,9 @@ static inline int __vs_check(int cid, int id, unsigned int mode)
 #define vx_capable(b,c) (capable(b) || \
        (cap_raised(current->cap_effective,b) && vx_ccaps(c)))
 
+#define nx_capable(b,c) (capable(b) || \
+       (cap_raised(current->cap_effective,b) && nx_ncaps(c)))
+
 
 #define vx_current_initpid(n) \
        (current->vx_info && \
index 77f6a8d..0866bc8 100644 (file)
 #define NXF_INIT_SET           (NXF_STATE_ADMIN)
 
 
+/* network caps */
+
+#define NXC_RAW_ICMP           0x00000100
+#define NXC_RAW_SOCKET         0x00000200
+#define NXC_RAW_SEND           0x00000400
+
+
 /* address types */
 
 #define NXA_TYPE_IPV4          1
index e4af597..d69c90f 100644 (file)
@@ -36,7 +36,7 @@ extern rwlock_t raw_v4_lock;
 
 extern struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num,
                                    __be32 raddr, __be32 laddr,
-                                   int dif);
+                                   int dif, int tag);
 
 extern int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash);
 
index 830b607..cfc4c07 100644 (file)
@@ -171,6 +171,7 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
        skb->data = data;
        skb->tail = data;
        skb->end  = data + size;
+       skb->skb_tag = nx_current_nid();
        /* make sure we initialize shinfo sequentially */
        shinfo = skb_shinfo(skb);
        atomic_set(&shinfo->dataref, 1);
@@ -242,6 +243,7 @@ struct sk_buff *alloc_skb_from_cache(struct kmem_cache *cp,
        skb->data = data;
        skb->tail = data;
        skb->end  = data + size;
+       skb->skb_tag = nx_current_nid();
 
        atomic_set(&(skb_shinfo(skb)->dataref), 1);
        skb_shinfo(skb)->nr_frags  = 0;
@@ -527,6 +529,8 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
        C(tail);
        C(end);
 
+       /* Sapan: Cloned skbs aren't owned by anyone. Let the cloner decide who it belongs to. */
+
        atomic_inc(&(skb_shinfo(skb)->dataref));
        skb->cloned = 1;
 
@@ -581,6 +585,8 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
        new->tc_index   = old->tc_index;
 #endif
        skb_copy_secmark(new, old);
+       new->skb_tag = old->skb_tag;
+
        atomic_set(&new->users, 1);
        skb_shinfo(new)->gso_size = skb_shinfo(old)->gso_size;
        skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs;
index 3ca5f8d..f48c116 100644 (file)
@@ -431,6 +431,18 @@ set_sndbuf:
                        }
                        goto set_sndbuf;
 
+               case SO_SETXID:
+                       if (current->xid) {
+                               ret = -EPERM;
+                               break;
+                       }
+                       if (val < 0 || val > MAX_S_CONTEXT) {
+                               ret = -EINVAL;
+                               break;
+                       }
+                       sk->sk_xid = val;
+                       break;
+
                case SO_RCVBUF:
                        /* Don't error on this BSD doesn't and if you think
                           about it this is right. Otherwise apps have to
@@ -553,7 +565,7 @@ set_rcvbuf:
                        char devname[IFNAMSIZ]; 
 
                        /* Sorry... */ 
-                       if (!capable(CAP_NET_RAW)) {
+                       if (!nx_capable(CAP_NET_RAW, NXC_RAW_SOCKET)) {
                                ret = -EPERM;
                                break;
                        }
@@ -764,6 +776,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
                                len = sizeof(sk->sk_peercred);
                        if (copy_to_user(optval, &sk->sk_peercred, len))
                                return -EFAULT;
+
                        goto lenout;
 
                case SO_PEERNAME:
index 35be3ed..865c850 100644 (file)
@@ -178,6 +178,8 @@ static int inet_autobind(struct sock *sk)
                        return -EAGAIN;
                }
                inet->sport = htons(inet->num);
+               sk->sk_xid = vx_current_xid();
+               sk->sk_nid = nx_current_nid();
        }
        release_sock(sk);
        return 0;
index da6fe73..7e8dfb2 100644 (file)
@@ -701,8 +701,8 @@ static void icmp_unreach(struct sk_buff *skb)
        read_lock(&raw_v4_lock);
        if ((raw_sk = sk_head(&raw_v4_htable[hash])) != NULL) {
                while ((raw_sk = __raw_v4_lookup(raw_sk, protocol, iph->daddr,
-                                                iph->saddr,
-                                                skb->dev->ifindex)) != NULL) {
+                                                iph->saddr, skb->dev->ifindex,
+                                                skb->skb_tag)) != NULL) {
                        raw_err(raw_sk, skb, info);
                        raw_sk = sk_next(raw_sk);
                        iph = (struct iphdr *)skb->data;
index 9f02917..ae4ca9c 100644 (file)
@@ -407,7 +407,7 @@ int ip_options_compile(struct ip_options * opt, struct sk_buff * skb)
                                        optptr[2] += 8;
                                        break;
                                      default:
-                                       if (!skb && !capable(CAP_NET_RAW)) {
+                                       if (!skb && !nx_capable(CAP_NET_RAW, NXC_RAW_SOCKET)) {
                                                pp_ptr = optptr + 3;
                                                goto error;
                                        }
@@ -443,7 +443,7 @@ int ip_options_compile(struct ip_options * opt, struct sk_buff * skb)
                                opt->router_alert = optptr - iph;
                        break;
                      case IPOPT_CIPSO:
-                       if ((!skb && !capable(CAP_NET_RAW)) || opt->cipso) {
+                       if ((!skb && !nx_capable(CAP_NET_RAW, NXC_RAW_SOCKET)) || opt->cipso) {
                                pp_ptr = optptr;
                                goto error;
                        }
@@ -456,7 +456,7 @@ int ip_options_compile(struct ip_options * opt, struct sk_buff * skb)
                      case IPOPT_SEC:
                      case IPOPT_SID:
                      default:
-                       if (!skb && !capable(CAP_NET_RAW)) {
+                       if (!skb && !nx_capable(CAP_NET_RAW, NXC_RAW_SOCKET)) {
                                pp_ptr = optptr;
                                goto error;
                        }
index c96de16..0225254 100644 (file)
@@ -49,6 +49,8 @@ static void dump_packet(const struct nf_loginfo *info,
        else
                logflags = NF_LOG_MASK;
 
+       printk("TAG=%d ", skb->skb_tag);
+
        ih = skb_header_pointer(skb, iphoff, sizeof(_iph), &_iph);
        if (ih == NULL) {
                printk("TRUNCATED");
index e5effed..619d242 100644 (file)
@@ -113,8 +113,17 @@ static inline int raw_addr_match (
        struct nx_info *nxi,
        uint32_t addr,
        uint32_t saddr,
-       uint32_t baddr)
-{
+       uint32_t baddr,
+       uint32_t tag)
+{
+       vxdprintk(VXD_CBIT(net, 8),
+               "raw_addr_match: %p[#%u] #%d"
+               " %u.%u.%u.%u/%u.%u.%u.%u/%u.%u.%u.%u",
+               nxi, nxi?nxi->nx_id:0, tag,
+               NIPQUAD(addr), NIPQUAD(saddr), NIPQUAD(baddr));
+       
+       if (nxi && !((tag == 1) || (nxi->nx_id == tag)))
+               return 0;
        if (addr && (saddr == addr || baddr == addr))
                return 1;
        if (!saddr)
@@ -124,7 +133,7 @@ static inline int raw_addr_match (
 
 struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num,
                             __be32 raddr, __be32 laddr,
-                            int dif)
+                            int dif, int tag)
 {
        struct hlist_node *node;
 
@@ -134,7 +143,7 @@ struct sock *__raw_v4_lookup(struct sock *sk, unsigned short num,
                if (inet->num == num                                    &&
                    !(inet->daddr && inet->daddr != raddr)              &&
                    raw_addr_match(sk->sk_nx_info, laddr,
-                       inet->rcv_saddr, inet->rcv_saddr2)              &&
+                       inet->rcv_saddr, inet->rcv_saddr2, tag)         &&
                    !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
                        goto found; /* gotcha */
        }
@@ -183,7 +192,7 @@ int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash)
                goto out;
        sk = __raw_v4_lookup(__sk_head(head), iph->protocol,
                             iph->saddr, iph->daddr,
-                            skb->dev->ifindex);
+                            skb->dev->ifindex, skb->skb_tag);
 
        while (sk) {
                delivered = 1;
@@ -196,7 +205,7 @@ int raw_v4_input(struct sk_buff *skb, struct iphdr *iph, int hash)
                }
                sk = __raw_v4_lookup(sk_next(sk), iph->protocol,
                                     iph->saddr, iph->daddr,
-                                    skb->dev->ifindex);
+                                    skb->dev->ifindex, skb->skb_tag);
        }
 out:
        read_unlock(&raw_v4_lock);
@@ -335,7 +344,7 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
        }
 
        err = -EPERM;
-       if (!nx_check(0, VS_ADMIN) && !capable(CAP_NET_RAW)
+       if (!nx_check(0, VS_ADMIN) && !nx_capable(CAP_NET_RAW, NXC_RAW_SOCKET)
                && (!addr_in_nx_info(sk->sk_nx_info, iph->saddr)))
                goto error_free;
 
index 5dc5574..a27e7a1 100644 (file)
@@ -36,6 +36,7 @@ obj-$(CONFIG_NF_CONNTRACK_TFTP) += nf_conntrack_tftp.o
 obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o
 
 # targets
+obj-m += xt_SETXID.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIFY) += xt_CLASSIFY.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_CONNMARK) += xt_CONNMARK.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o
index 0b48547..3b40a60 100644 (file)
@@ -5,13 +5,18 @@
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
+ *
  */
 
 #include <linux/module.h>
+#include <linux/version.h>
 #include <linux/skbuff.h>
 #include <linux/ip.h>
 #include <net/checksum.h>
+#include <net/route.h>
+#include <net/inet_hashtables.h>
 
+#include <linux/netfilter_ipv4/ip_conntrack.h>
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter/xt_MARK.h>
 
@@ -21,6 +26,48 @@ MODULE_DESCRIPTION("ip[6]tables MARK modification module");
 MODULE_ALIAS("ipt_MARK");
 MODULE_ALIAS("ip6t_MARK");
 
+static inline u_int16_t
+get_dst_port(struct ip_conntrack_tuple *tuple)
+{
+       switch (tuple->dst.protonum) {
+       case IPPROTO_GRE:
+               /* XXX Truncate 32-bit GRE key to 16 bits */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11)
+               return tuple->dst.u.gre.key;
+#else
+               return htons(ntohl(tuple->dst.u.gre.key));
+#endif  
+       case IPPROTO_ICMP:
+               /* Bind on ICMP echo ID */
+               return tuple->src.u.icmp.id;
+       case IPPROTO_TCP:
+               return tuple->dst.u.tcp.port;
+       case IPPROTO_UDP:
+               return tuple->dst.u.udp.port;
+       default:
+               return tuple->dst.u.all;
+       }
+}
+
+static inline u_int16_t
+get_src_port(struct ip_conntrack_tuple *tuple)
+{
+       switch (tuple->dst.protonum) {
+       case IPPROTO_GRE:
+               /* XXX Truncate 32-bit GRE key to 16 bits */
+               return htons(ntohl(tuple->src.u.gre.key));
+       case IPPROTO_ICMP:
+               /* Bind on ICMP echo ID */
+               return tuple->src.u.icmp.id;
+       case IPPROTO_TCP:
+               return tuple->src.u.tcp.port;
+       case IPPROTO_UDP:
+               return tuple->src.u.udp.port;
+       default:
+               return tuple->src.u.all;
+       }
+}
+
 static unsigned int
 target_v0(struct sk_buff **pskb,
          const struct net_device *in,
@@ -46,7 +93,7 @@ target_v1(struct sk_buff **pskb,
          const void *targinfo)
 {
        const struct xt_mark_target_info_v1 *markinfo = targinfo;
-       int mark = 0;
+       int mark = -1;
 
        switch (markinfo->mode) {
        case XT_MARK_SET:
@@ -60,9 +107,51 @@ target_v1(struct sk_buff **pskb,
        case XT_MARK_OR:
                mark = (*pskb)->mark | markinfo->mark;
                break;
+
+       case XT_MARK_COPYXID: 
+               {
+               enum ip_conntrack_info ctinfo;
+               struct sock *connection_sk;
+               int dif;
+
+               struct ip_conntrack *ct = ip_conntrack_get((*pskb), &ctinfo);
+               extern struct inet_hashinfo tcp_hashinfo;
+               enum ip_conntrack_dir dir;
+
+               if (!ct) 
+                       break;
+               dir= CTINFO2DIR(ctinfo);
+               u_int32_t src_ip = ct->tuplehash[dir].tuple.src.ip;
+               u_int16_t src_port = get_src_port(&ct->tuplehash[dir].tuple);
+
+               u_int32_t ip;
+               u_int16_t port;
+
+               dif = ((struct rtable *)(*pskb)->dst)->rt_iif;
+               ip = ct->tuplehash[dir].tuple.dst.ip;
+               port = get_dst_port(&ct->tuplehash[dir].tuple);
+
+               if ((*pskb)->sk) 
+                       connection_sk = (*pskb)->sk;
+               else {
+                       connection_sk = inet_lookup(&tcp_hashinfo, src_ip, src_port, ip, port, dif);
+               }
+
+               if (connection_sk) {
+                       /* XXX:
+                       connection_sk->sk_peercred.gid = connection_sk->sk_peercred.uid = ct->xid[dir];
+                       ct->xid[!dir]=connection_sk->sk_xid;
+                       */
+                       if (connection_sk->sk_xid != 0) 
+                               mark = connection_sk->sk_xid;
+                       if (connection_sk != (*pskb)->sk)
+                               sock_put(connection_sk);
+               }
+               }
+               break;
        }
 
-       if((*pskb)->mark != mark)
+       if((*pskb)->mark != mark && mark != -1)
                (*pskb)->mark = mark;
 
        return XT_CONTINUE;
@@ -96,7 +185,8 @@ checkentry_v1(const char *tablename,
 
        if (markinfo->mode != XT_MARK_SET
            && markinfo->mode != XT_MARK_AND
-           && markinfo->mode != XT_MARK_OR) {
+           && markinfo->mode != XT_MARK_OR
+           && markinfo->mode != XT_MARK_COPYXID) {
                printk(KERN_WARNING "MARK: unknown mode %u\n",
                       markinfo->mode);
                return 0;
diff --git a/net/netfilter/xt_OLDMARK.c b/net/netfilter/xt_OLDMARK.c
new file mode 100644 (file)
index 0000000..0b48547
--- /dev/null
@@ -0,0 +1,189 @@
+/* This is a module which is used for setting the NFMARK field of an skb. */
+
+/* (C) 1999-2001 Marc Boucher <marc@mbsi.ca>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ip.h>
+#include <net/checksum.h>
+
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/xt_MARK.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
+MODULE_DESCRIPTION("ip[6]tables MARK modification module");
+MODULE_ALIAS("ipt_MARK");
+MODULE_ALIAS("ip6t_MARK");
+
+static unsigned int
+target_v0(struct sk_buff **pskb,
+         const struct net_device *in,
+         const struct net_device *out,
+         unsigned int hooknum,
+         const struct xt_target *target,
+         const void *targinfo)
+{
+       const struct xt_mark_target_info *markinfo = targinfo;
+
+       if((*pskb)->mark != markinfo->mark)
+               (*pskb)->mark = markinfo->mark;
+
+       return XT_CONTINUE;
+}
+
+static unsigned int
+target_v1(struct sk_buff **pskb,
+         const struct net_device *in,
+         const struct net_device *out,
+         unsigned int hooknum,
+         const struct xt_target *target,
+         const void *targinfo)
+{
+       const struct xt_mark_target_info_v1 *markinfo = targinfo;
+       int mark = 0;
+
+       switch (markinfo->mode) {
+       case XT_MARK_SET:
+               mark = markinfo->mark;
+               break;
+               
+       case XT_MARK_AND:
+               mark = (*pskb)->mark & markinfo->mark;
+               break;
+               
+       case XT_MARK_OR:
+               mark = (*pskb)->mark | markinfo->mark;
+               break;
+       }
+
+       if((*pskb)->mark != mark)
+               (*pskb)->mark = mark;
+
+       return XT_CONTINUE;
+}
+
+
+static int
+checkentry_v0(const char *tablename,
+             const void *entry,
+             const struct xt_target *target,
+             void *targinfo,
+             unsigned int hook_mask)
+{
+       struct xt_mark_target_info *markinfo = targinfo;
+
+       if (markinfo->mark > 0xffffffff) {
+               printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n");
+               return 0;
+       }
+       return 1;
+}
+
+static int
+checkentry_v1(const char *tablename,
+             const void *entry,
+             const struct xt_target *target,
+             void *targinfo,
+             unsigned int hook_mask)
+{
+       struct xt_mark_target_info_v1 *markinfo = targinfo;
+
+       if (markinfo->mode != XT_MARK_SET
+           && markinfo->mode != XT_MARK_AND
+           && markinfo->mode != XT_MARK_OR) {
+               printk(KERN_WARNING "MARK: unknown mode %u\n",
+                      markinfo->mode);
+               return 0;
+       }
+       if (markinfo->mark > 0xffffffff) {
+               printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n");
+               return 0;
+       }
+       return 1;
+}
+
+#ifdef CONFIG_COMPAT
+struct compat_xt_mark_target_info_v1 {
+       compat_ulong_t  mark;
+       u_int8_t        mode;
+       u_int8_t        __pad1;
+       u_int16_t       __pad2;
+};
+
+static void compat_from_user_v1(void *dst, void *src)
+{
+       struct compat_xt_mark_target_info_v1 *cm = src;
+       struct xt_mark_target_info_v1 m = {
+               .mark   = cm->mark,
+               .mode   = cm->mode,
+       };
+       memcpy(dst, &m, sizeof(m));
+}
+
+static int compat_to_user_v1(void __user *dst, void *src)
+{
+       struct xt_mark_target_info_v1 *m = src;
+       struct compat_xt_mark_target_info_v1 cm = {
+               .mark   = m->mark,
+               .mode   = m->mode,
+       };
+       return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0;
+}
+#endif /* CONFIG_COMPAT */
+
+static struct xt_target xt_mark_target[] = {
+       {
+               .name           = "MARK",
+               .family         = AF_INET,
+               .revision       = 0,
+               .checkentry     = checkentry_v0,
+               .target         = target_v0,
+               .targetsize     = sizeof(struct xt_mark_target_info),
+               .table          = "mangle",
+               .me             = THIS_MODULE,
+       },
+       {
+               .name           = "MARK",
+               .family         = AF_INET,
+               .revision       = 1,
+               .checkentry     = checkentry_v1,
+               .target         = target_v1,
+               .targetsize     = sizeof(struct xt_mark_target_info_v1),
+#ifdef CONFIG_COMPAT
+               .compatsize     = sizeof(struct compat_xt_mark_target_info_v1),
+               .compat_from_user = compat_from_user_v1,
+               .compat_to_user = compat_to_user_v1,
+#endif
+               .table          = "mangle",
+               .me             = THIS_MODULE,
+       },
+       {
+               .name           = "MARK",
+               .family         = AF_INET6,
+               .revision       = 0,
+               .checkentry     = checkentry_v0,
+               .target         = target_v0,
+               .targetsize     = sizeof(struct xt_mark_target_info),
+               .table          = "mangle",
+               .me             = THIS_MODULE,
+       },
+};
+
+static int __init xt_mark_init(void)
+{
+       return xt_register_targets(xt_mark_target, ARRAY_SIZE(xt_mark_target));
+}
+
+static void __exit xt_mark_fini(void)
+{
+       xt_unregister_targets(xt_mark_target, ARRAY_SIZE(xt_mark_target));
+}
+
+module_init(xt_mark_init);
+module_exit(xt_mark_fini);
diff --git a/net/netfilter/xt_SETXID.c b/net/netfilter/xt_SETXID.c
new file mode 100644 (file)
index 0000000..d8503f9
--- /dev/null
@@ -0,0 +1,79 @@
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ip.h>
+#include <net/checksum.h>
+#include <linux/vs_network.h>
+
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/xt_SETXID.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("");
+MODULE_DESCRIPTION("");
+MODULE_ALIAS("ipt_SETXID");
+
+static unsigned int
+target_v1(struct sk_buff **pskb,
+         const struct net_device *in,
+         const struct net_device *out,
+         unsigned int hooknum,
+         const struct xt_target *target,
+         const void *targinfo)
+{
+       const struct xt_setxid_target_info_v1 *setxidinfo = targinfo;
+
+       switch (setxidinfo->mode) {
+       case XT_SET_PACKET_XID:
+                (*pskb)->skb_tag = setxidinfo->mark;
+               break;
+       }
+       return XT_CONTINUE;
+}
+
+
+static int
+checkentry_v1(const char *tablename,
+             const void *entry,
+             const struct xt_target *target,
+             void *targinfo,
+             unsigned int hook_mask)
+{
+       struct xt_setxid_target_info_v1 *setxidinfo = targinfo;
+
+       if (setxidinfo->mode != XT_SET_PACKET_XID) {
+               printk(KERN_WARNING "SETXID: unknown mode %u\n",
+                      setxidinfo->mode);
+               return 0;
+       }
+
+       return 1;
+}
+
+static struct xt_target xt_setxid_target[] = {
+       {
+               .name           = "SETXID",
+               .family         = AF_INET,
+               .revision       = 1,
+               .checkentry     = checkentry_v1,
+               .target         = target_v1,
+               .targetsize     = sizeof(struct xt_setxid_target_info_v1),
+               .table          = "mangle",
+               .me             = THIS_MODULE,
+       }
+};
+
+static int __init init(void)
+{
+       int err;
+
+       err = xt_register_targets(xt_setxid_target, ARRAY_SIZE(xt_setxid_target));
+       return err;
+}
+
+static void __exit fini(void)
+{
+       xt_unregister_targets(xt_setxid_target, ARRAY_SIZE(xt_setxid_target));
+}
+
+module_init(init);
+module_exit(fini);
index a6fa487..e0e301c 100644 (file)
@@ -79,6 +79,7 @@
 #include <linux/poll.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/vs_network.h>
 
 #ifdef CONFIG_INET
 #include <net/inet_common.h>
@@ -444,6 +445,15 @@ static inline unsigned int run_filter(struct sk_buff *skb, struct sock *sk,
                                      unsigned int res)
 {
        struct sk_filter *filter;
+       struct nx_info *nxi = sk->sk_nx_info;
+       int tag = skb->skb_tag;
+
+       vxdprintk(VXD_CBIT(net, 8),
+               "run_filter: %p[#%u] #%d %d",
+               nxi, nxi?nxi->nx_id:0, tag, res);
+       
+       if (nxi && !((tag == 1) || (nxi->nx_id == tag)))
+               return 0;
 
        rcu_read_lock_bh();
        filter = rcu_dereference(sk->sk_filter);
@@ -1005,7 +1015,7 @@ static int packet_create(struct socket *sock, int protocol)
        __be16 proto = (__force __be16)protocol; /* weird, but documented */
        int err;
 
-       if (!capable(CAP_NET_RAW))
+       if (!nx_capable(CAP_NET_RAW, NXC_RAW_SEND))
                return -EPERM;
        if (sock->type != SOCK_DGRAM && sock->type != SOCK_RAW
 #ifdef CONFIG_SOCK_PACKET