Bump tag level
[linux-2.6.git] / linux-2.6-525-sknid-elevator.patch
1 diff -NurpP --exclude '*.orig' --exclude '*.rej' linux-2.6.27.10-vs2.3.x-PS-522-523-524/include/linux/netdevice.h linux-2.6.27.10-vs2.3.x-PS-522-523-524-525/include/linux/netdevice.h
2 --- linux-2.6.27.10-vs2.3.x-PS-522-523-524/include/linux/netdevice.h    2008-10-13 14:52:09.000000000 +0200
3 +++ linux-2.6.27.10-vs2.3.x-PS-522-523-524-525/include/linux/netdevice.h        2009-01-21 03:38:41.000000000 +0100
4 @@ -857,6 +857,7 @@ static inline void netif_napi_del(struct
5  struct packet_type {
6         __be16                  type;   /* This is really htons(ether_type). */
7         struct net_device       *dev;   /* NULL is wildcarded here           */
8 +       unsigned char           sknid_elevator; 
9         int                     (*func) (struct sk_buff *,
10                                          struct net_device *,
11                                          struct packet_type *,
12 diff -NurpP --exclude '*.orig' --exclude '*.rej' linux-2.6.27.10-vs2.3.x-PS-522-523-524/net/core/dev.c linux-2.6.27.10-vs2.3.x-PS-522-523-524-525/net/core/dev.c
13 --- linux-2.6.27.10-vs2.3.x-PS-522-523-524/net/core/dev.c       2008-12-19 12:09:14.000000000 +0100
14 +++ linux-2.6.27.10-vs2.3.x-PS-522-523-524-525/net/core/dev.c   2009-01-21 03:43:19.000000000 +0100
15 @@ -99,6 +99,8 @@
16  #include <linux/proc_fs.h>
17  #include <linux/seq_file.h>
18  #include <linux/stat.h>
19 +#include <linux/ip.h>
20 +#include <linux/tcp.h>
21  #include <linux/if_bridge.h>
22  #include <linux/if_macvlan.h>
23  #include <net/dst.h>
24 @@ -1318,7 +1320,7 @@ static void dev_queue_xmit_nit(struct sk
25                 if ((ptype->dev == dev || !ptype->dev) &&
26                     (ptype->af_packet_priv == NULL ||
27                      (struct sock *)ptype->af_packet_priv != skb->sk)) {
28 -                       struct sk_buff *skb2= skb_clone(skb, GFP_ATOMIC);
29 +                       struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
30                         if (!skb2)
31                                 break;
32  
33 @@ -2170,6 +2172,10 @@ void netif_nit_deliver(struct sk_buff *s
34         rcu_read_unlock();
35  }
36  
37 +/* The code already makes the assumption that packet handlers run
38 + * sequentially on the same CPU. -Sapan */
39 +DEFINE_PER_CPU(int, sknid_elevator) = 0;
40 +
41  /**
42   *     netif_receive_skb - process receive buffer from network
43   *     @skb: buffer to process
44 @@ -2191,8 +2197,11 @@ int netif_receive_skb(struct sk_buff *sk
45         struct net_device *orig_dev;
46         struct net_device *null_or_orig;
47         int ret = NET_RX_DROP;
48 +       int *cur_elevator = &__get_cpu_var(sknid_elevator);
49         __be16 type;
50  
51 +       *cur_elevator = 0;
52 +
53         /* if we've gotten here through NAPI, check netpoll */
54         if (netpoll_receive_skb(skb))
55                 return NET_RX_DROP;
56 @@ -2269,7 +2278,27 @@ ncls:
57         }
58  
59         if (pt_prev) {
60 +               /* At this point, cur_elevator may be -2 or a positive value, in
61 +                * case a previous protocol handler marked it */
62 +               if (*cur_elevator) {
63 +                       atomic_inc(&skb->users);
64 +               }
65 +               
66                 ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
67 +
68 +               if ((*cur_elevator)>0) {
69 +                       skb->skb_tag = *cur_elevator;
70 +                       list_for_each_entry_rcu(ptype, &ptype_all, list) {
71 +                               if ((!ptype->dev || ptype->dev == skb->dev) && (ptype->sknid_elevator)) {
72 +                                       ret = deliver_skb(skb, ptype, orig_dev);
73 +                               }
74 +                       }
75 +               }
76 +
77 +               if (*cur_elevator) {
78 +                       /* We have a packet */
79 +                       kfree_skb(skb);
80 +               }
81         } else {
82                 kfree_skb(skb);
83                 /* Jamal, now you will not able to escape explaining
84 @@ -4892,6 +4921,7 @@ EXPORT_SYMBOL(unregister_netdevice_notif
85  EXPORT_SYMBOL(net_enable_timestamp);
86  EXPORT_SYMBOL(net_disable_timestamp);
87  EXPORT_SYMBOL(dev_get_flags);
88 +EXPORT_PER_CPU_SYMBOL(sknid_elevator);
89  
90  #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
91  EXPORT_SYMBOL(br_handle_frame_hook);
92 diff -NurpP --exclude '*.orig' --exclude '*.rej' linux-2.6.27.10-vs2.3.x-PS-522-523-524/net/packet/af_packet.c linux-2.6.27.10-vs2.3.x-PS-522-523-524-525/net/packet/af_packet.c
93 --- linux-2.6.27.10-vs2.3.x-PS-522-523-524/net/packet/af_packet.c       2008-10-13 14:52:09.000000000 +0200
94 +++ linux-2.6.27.10-vs2.3.x-PS-522-523-524-525/net/packet/af_packet.c   2009-01-21 03:38:41.000000000 +0100
95 @@ -77,6 +77,7 @@
96  #include <linux/poll.h>
97  #include <linux/module.h>
98  #include <linux/init.h>
99 +#include <linux/vs_network.h>
100  
101  #ifdef CONFIG_INET
102  #include <net/inet_common.h>
103 @@ -276,10 +277,53 @@ static const struct proto_ops packet_ops
104  
105  static const struct proto_ops packet_ops_spkt;
106  
107 +extern DEFINE_PER_CPU(int, sknid_elevator);
108 +
109 +static inline unsigned int slice_check_and_elevate(struct sk_buff *skb, struct sock *sk) {
110 +       /* This mechanism is quite involved, and caused us a lot of pain
111 +        * including crashes and packet loss during the 4.2 rollout. This
112 +        * function decides if a slice is allowed to see a given packet.
113 +        * Unfortunately, the first time it is invoked for a packet it does not
114 +        * have enough information to make this call, since xt_MARK has not had
115 +        * a chance to tag it with the slice id.  There is also no way of
116 +        * passing state between xt_MARK and this function through a packet --
117 +        * because the skb gets cloned quite a few times between these two
118 +        * points.  I'd rather not use skb_shared_info because it's treated as
119 +        * a blob of memory, and so it would be quite hard to maintain.
120 +        *
121 +        * What we do is to keep a global variable (per CPU) that transfers the
122 +        * required state between xt_MARK and af_packet.c. As an optimization,
123 +        * this state transfer and the step that follows is only executed for
124 +        * packets that first get dropped here. When we drop a packet, we mark
125 +        * it for 'elevation' (that's what this trick is called). When xt_MARK
126 +        * tags the packet with the right slice, it intercepts this mark and
127 +        * sets the value of sknid_elevator. Next, the packet is sent back here
128 +        * for a second round, this time with the xid tag set.
129 +        */
130 +
131 +       int *elevator=&__get_cpu_var(sknid_elevator);
132 +       int tag = skb->skb_tag;
133 +
134 +       if (sk->sk_nx_info && !(tag == 1 || sk->sk_nid == tag)) {
135 +               if (skb->pkt_type==PACKET_HOST) {
136 +                       *elevator=-2; /* Rejecting this packet. Mark it for elevation in xt_MARK */
137 +               }
138 +               return 0;
139 +       }
140 +       else if (!sk->sk_nx_info && (*elevator>0)) {
141 +               /* Root has already seen this packet once, since it has been elevated */
142 +               return 0;
143 +       }
144 +
145 +       return 1;
146 +}
147 +
148  static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev,  struct packet_type *pt, struct net_device *orig_dev)
149  {
150         struct sock *sk;
151         struct sockaddr_pkt *spkt;
152 +       int tag = skb->skb_tag;
153 +
154  
155         /*
156          *      When we registered the protocol we saved the socket in the data
157 @@ -299,6 +343,16 @@ static int packet_rcv_spkt(struct sk_buf
158          *      so that this procedure is noop.
159          */
160  
161 +       /* 
162 +        * (18:05:41) daniel_hozac: where?
163 +        * (18:05:58) daniel_hozac: we already have filters on PF_PACKET, don't we?
164 +        * (18:05:58) er: in packet_rcv_skpt
165 +        * (18:07:33) daniel_hozac: oh, that's evil. 
166 +        */
167 +
168 +       if (!slice_check_and_elevate(skb, sk))
169 +               return 0;
170 +
171         if (skb->pkt_type == PACKET_LOOPBACK)
172                 goto out;
173  
174 @@ -357,6 +411,9 @@ static int packet_sendmsg_spkt(struct ki
175         __be16 proto=0;
176         int err;
177  
178 +       if (!nx_capable(CAP_NET_RAW, NXC_RAW_SEND))
179 +               return -EPERM;
180 +
181         /*
182          *      Get and verify the address.
183          */
184 @@ -449,11 +506,16 @@ out_unlock:
185         return err;
186  }
187  
188 +
189 +
190  static inline unsigned int run_filter(struct sk_buff *skb, struct sock *sk,
191                                       unsigned int res)
192  {
193         struct sk_filter *filter;
194  
195 +       if (!slice_check_and_elevate(skb, sk)) 
196 +               return 0;
197 +
198         rcu_read_lock_bh();
199         filter = rcu_dereference(sk->sk_filter);
200         if (filter != NULL)
201 @@ -773,6 +835,9 @@ static int packet_sendmsg(struct kiocb *
202         unsigned char *addr;
203         int ifindex, err, reserve = 0;
204  
205 +       if (!nx_capable(CAP_NET_RAW, NXC_RAW_SEND)) 
206 +               return -EPERM;
207 +
208         /*
209          *      Get and verify the address.
210          */
211 @@ -939,6 +1004,7 @@ static int packet_do_bind(struct sock *s
212  
213         po->num = protocol;
214         po->prot_hook.type = protocol;
215 +       po->prot_hook.sknid_elevator = 1;
216         po->prot_hook.dev = dev;
217  
218         po->ifindex = dev ? dev->ifindex : 0;
219 @@ -1037,8 +1103,9 @@ static int packet_create(struct net *net
220         __be16 proto = (__force __be16)protocol; /* weird, but documented */
221         int err;
222  
223 -       if (!capable(CAP_NET_RAW))
224 +       if (!nx_capable(CAP_NET_RAW, NXC_RAW_SOCKET))
225                 return -EPERM;
226 +               
227         if (sock->type != SOCK_DGRAM && sock->type != SOCK_RAW &&
228             sock->type != SOCK_PACKET)
229                 return -ESOCKTNOSUPPORT;
230 @@ -1069,6 +1136,7 @@ static int packet_create(struct net *net
231  
232         spin_lock_init(&po->bind_lock);
233         po->prot_hook.func = packet_rcv;
234 +       po->prot_hook.sknid_elevator = 1;
235  
236         if (sock->type == SOCK_PACKET)
237                 po->prot_hook.func = packet_rcv_spkt;