diff -Nurb linux-2.6.22-510/include/linux/vserver/network.h linux-2.6.22-520/include/linux/vserver/network.h --- linux-2.6.22-510/include/linux/vserver/network.h 2008-06-06 17:07:48.000000000 -0400 +++ linux-2.6.22-520/include/linux/vserver/network.h 2008-06-06 17:07:56.000000000 -0400 @@ -47,6 +47,8 @@ #define NXC_TUN_CREATE 0x00000001 #define NXC_RAW_ICMP 0x00000100 +#define NXC_RAW_SOCKET 0x00000200 +#define NXC_RAW_SEND 0x00000400 /* address types */ diff -Nurb linux-2.6.22-510/include/net/raw.h linux-2.6.22-520/include/net/raw.h --- linux-2.6.22-510/include/net/raw.h 2007-07-08 19:32:17.000000000 -0400 +++ linux-2.6.22-520/include/net/raw.h 2008-06-06 17:07:56.000000000 -0400 @@ -36,7 +36,7 @@ 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); diff -Nurb linux-2.6.22-510/net/core/sock.c linux-2.6.22-520/net/core/sock.c --- linux-2.6.22-510/net/core/sock.c 2008-06-06 17:07:48.000000000 -0400 +++ linux-2.6.22-520/net/core/sock.c 2008-06-06 17:07:56.000000000 -0400 @@ -444,6 +444,19 @@ } goto set_sndbuf; + case SO_SETXID: + if (current_vx_info()) { + ret = -EPERM; + break; + } + if (val < 0 || val > MAX_S_CONTEXT) { + ret = -EINVAL; + break; + } + sk->sk_xid = val; + sk->sk_nid = 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 @@ -573,7 +586,7 @@ char devname[IFNAMSIZ]; /* Sorry... */ - if (!capable(CAP_NET_RAW)) { + if (!nx_capable(CAP_NET_RAW, NXC_RAW_SOCKET)) { ret = -EPERM; break; } diff -Nurb linux-2.6.22-510/net/ipv4/af_inet.c linux-2.6.22-520/net/ipv4/af_inet.c --- linux-2.6.22-510/net/ipv4/af_inet.c 2008-06-06 17:07:48.000000000 -0400 +++ linux-2.6.22-520/net/ipv4/af_inet.c 2008-06-06 17:07:56.000000000 -0400 @@ -312,6 +314,9 @@ if ((protocol == IPPROTO_ICMP) && nx_capable(answer->capability, NXC_RAW_ICMP)) goto override; + if (sock->type == SOCK_RAW && + nx_capable(answer->capability, NXC_RAW_SOCKET)) + goto override; if (answer->capability > 0 && !capable(answer->capability)) goto out_rcu_unlock; override: diff -Nurb linux-2.6.22-510/net/ipv4/icmp.c linux-2.6.22-520/net/ipv4/icmp.c --- linux-2.6.22-510/net/ipv4/icmp.c 2008-06-06 17:07:55.000000000 -0400 +++ linux-2.6.22-520/net/ipv4/icmp.c 2008-06-06 17:07:56.000000000 -0400 @@ -709,7 +709,7 @@ 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) { + skb->dev->ifindex, skb->skb_tag)) != NULL) { raw_err(raw_sk, skb, info); raw_sk = sk_next(raw_sk); iph = (struct iphdr *)skb->data; diff -Nurb linux-2.6.22-510/net/ipv4/ip_options.c linux-2.6.22-520/net/ipv4/ip_options.c --- linux-2.6.22-510/net/ipv4/ip_options.c 2007-07-08 19:32:17.000000000 -0400 +++ linux-2.6.22-520/net/ipv4/ip_options.c 2008-06-06 17:07:56.000000000 -0400 @@ -409,7 +409,7 @@ 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; } @@ -445,7 +445,7 @@ 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; } @@ -458,7 +458,7 @@ 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; } diff -Nurb linux-2.6.22-510/net/ipv4/raw.c linux-2.6.22-520/net/ipv4/raw.c --- linux-2.6.22-510/net/ipv4/raw.c 2008-06-06 17:07:48.000000000 -0400 +++ linux-2.6.22-520/net/ipv4/raw.c 2008-06-06 17:07:56.000000000 -0400 @@ -103,7 +103,7 @@ 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; @@ -112,6 +112,7 @@ if (inet->num == num && !(inet->daddr && inet->daddr != raddr) && + (!sk->sk_nx_info || tag == 1 || sk->sk_nid == tag) && v4_sock_addr_match(sk->sk_nx_info, inet, laddr) && !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif)) goto found; /* gotcha */ @@ -161,7 +162,7 @@ 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; @@ -174,7 +175,7 @@ } 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); @@ -315,7 +316,7 @@ } 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) && sk->sk_nx_info && !v4_addr_in_nx_info(sk->sk_nx_info, iph->saddr, NXA_MASK_BIND)) goto error_free;