vserver 1.9.5.x5
[linux-2.6.git] / net / core / netfilter.c
index 3aabe12..0416161 100644 (file)
@@ -47,7 +47,7 @@ static DECLARE_MUTEX(nf_sockopt_mutex);
 
 struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS];
 static LIST_HEAD(nf_sockopts);
-static spinlock_t nf_hook_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(nf_hook_lock);
 
 /* 
  * A queue handler may be registered for each protocol.  Each is protected by
@@ -58,7 +58,7 @@ static struct nf_queue_handler_t {
        nf_queue_outfn_t outfn;
        void *data;
 } queue_handler[NPROTO];
-static rwlock_t queue_handler_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(queue_handler_lock);
 
 int nf_register_hook(struct nf_hook_ops *reg)
 {
@@ -173,7 +173,7 @@ static void debug_print_hooks_ip(unsigned int nf_debug)
        printk("\n");
 }
 
-void nf_dump_skb(int pf, struct sk_buff *skb)
+static void nf_dump_skb(int pf, struct sk_buff *skb)
 {
        printk("skb: pf=%i %s dev=%s len=%u\n", 
               pf,
@@ -286,7 +286,7 @@ void nf_debug_ip_finish_output2(struct sk_buff *skb)
 
 /* Call get/setsockopt() */
 static int nf_sockopt(struct sock *sk, int pf, int val, 
-                     char *opt, int *len, int get)
+                     char __user *opt, int *len, int get)
 {
        struct list_head *i;
        struct nf_sockopt_ops *ops;
@@ -329,13 +329,13 @@ static int nf_sockopt(struct sock *sk, int pf, int val,
        return ret;
 }
 
-int nf_setsockopt(struct sock *sk, int pf, int val, char *opt,
+int nf_setsockopt(struct sock *sk, int pf, int val, char __user *opt,
                  int len)
 {
        return nf_sockopt(sk, pf, val, opt, &len, 0);
 }
 
-int nf_getsockopt(struct sock *sk, int pf, int val, char *opt, int *len)
+int nf_getsockopt(struct sock *sk, int pf, int val, char __user *opt, int *len)
 {
        return nf_sockopt(sk, pf, val, opt, len, 1);
 }
@@ -504,14 +504,6 @@ int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb,
        unsigned int verdict;
        int ret = 0;
 
-       if (skb->ip_summed == CHECKSUM_HW) {
-               if (outdev == NULL) {
-                       skb->ip_summed = CHECKSUM_NONE;
-               } else {
-                       skb_checksum_help(skb);
-               }
-       }
-
        /* We may already have this, but read-locks nest anyway */
        rcu_read_lock();
 
@@ -681,6 +673,7 @@ int ip_route_me_harder(struct sk_buff **pskb)
 
        return 0;
 }
+EXPORT_SYMBOL(ip_route_me_harder);
 
 int skb_ip_make_writable(struct sk_buff **pskb, unsigned int writable_len)
 {
@@ -703,11 +696,12 @@ int skb_ip_make_writable(struct sk_buff **pskb, unsigned int writable_len)
        /* DaveM says protocol headers are also modifiable. */
        switch ((*pskb)->nh.iph->protocol) {
        case IPPROTO_TCP: {
-               struct tcphdr hdr;
-               if (skb_copy_bits(*pskb, (*pskb)->nh.iph->ihl*4,
-                                 &hdr, sizeof(hdr)) != 0)
+               struct tcphdr _hdr, *hp;
+               hp = skb_header_pointer(*pskb, (*pskb)->nh.iph->ihl*4,
+                                       sizeof(_hdr), &_hdr);
+               if (hp == NULL)
                        goto copy_skb;
-               if (writable_len <= (*pskb)->nh.iph->ihl*4 + hdr.doff*4)
+               if (writable_len <= (*pskb)->nh.iph->ihl*4 + hp->doff*4)
                        goto pull_skb;
                goto copy_skb;
        }
@@ -750,7 +744,7 @@ EXPORT_SYMBOL(skb_ip_make_writable);
 
 static nf_logfn *nf_logging[NPROTO]; /* = NULL */
 static int reported = 0;
-static spinlock_t nf_log_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(nf_log_lock);
 
 int nf_log_register(int pf, nf_logfn *logfn)
 {
@@ -758,10 +752,9 @@ int nf_log_register(int pf, nf_logfn *logfn)
 
        /* Any setup of logging members must be done before
         * substituting pointer. */
-       smp_wmb();
        spin_lock(&nf_log_lock);
        if (!nf_logging[pf]) {
-               nf_logging[pf] = logfn;
+               rcu_assign_pointer(nf_logging[pf], logfn);
                ret = 0;
        }
        spin_unlock(&nf_log_lock);
@@ -791,13 +784,12 @@ void nf_log_packet(int pf,
        nf_logfn *logfn;
        
        rcu_read_lock();
-       logfn = nf_logging[pf];
+       logfn = rcu_dereference(nf_logging[pf]);
        if (logfn) {
                va_start(args, fmt);
                vsnprintf(prefix, sizeof(prefix), fmt, args);
                va_end(args);
                /* We must read logging before nf_logfn[pf] */
-               smp_read_barrier_depends();
                logfn(hooknum, skb, in, out, prefix);
        } else if (!reported) {
                printk(KERN_WARNING "nf_log_packet: can\'t log yet, "
@@ -810,11 +802,20 @@ EXPORT_SYMBOL(nf_log_register);
 EXPORT_SYMBOL(nf_log_unregister);
 EXPORT_SYMBOL(nf_log_packet);
 
-/* This does not belong here, but ipt_REJECT needs it if connection
-   tracking in use: without this, connection may not be in hash table,
-   and hence manufactured ICMP or RST packets will not be associated
-   with it. */
-void (*ip_ct_attach)(struct sk_buff *, struct nf_ct_info *);
+/* This does not belong here, but locally generated errors need it if connection
+   tracking in use: without this, connection may not be in hash table, and hence
+   manufactured ICMP or RST packets will not be associated with it. */
+void (*ip_ct_attach)(struct sk_buff *, struct sk_buff *);
+
+void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb)
+{
+       void (*attach)(struct sk_buff *, struct sk_buff *);
+
+       if (skb->nfct && (attach = ip_ct_attach) != NULL) {
+               mb(); /* Just to be sure: must be read before executing this */
+               attach(new, skb);
+       }
+}
 
 void __init netfilter_init(void)
 {
@@ -827,7 +828,7 @@ void __init netfilter_init(void)
 }
 
 EXPORT_SYMBOL(ip_ct_attach);
-EXPORT_SYMBOL(ip_route_me_harder);
+EXPORT_SYMBOL(nf_ct_attach);
 EXPORT_SYMBOL(nf_getsockopt);
 EXPORT_SYMBOL(nf_hook_slow);
 EXPORT_SYMBOL(nf_hooks);