* (Cleanup) Split up the VNET+ patch into its 5 component patches
[linux-2.6.git] / linux-2.6-523-raw-sockets.patch
diff --git a/linux-2.6-523-raw-sockets.patch b/linux-2.6-523-raw-sockets.patch
new file mode 100644 (file)
index 0000000..24b05bd
--- /dev/null
@@ -0,0 +1,160 @@
+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;
+
+