[package] fix wprobe build for arm on 3.2
[openwrt.git] / package / wprobe / src / kernel / wprobe-core.c
index d8f5a16..6ec847a 100644 (file)
@@ -24,6 +24,9 @@
 #else
 #include <linux/list.h>
 #endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)
+#include <linux/prefetch.h>
+#endif
 #include <linux/skbuff.h>
 #include <linux/wprobe.h>
 #include <linux/math64.h>
 #define static
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
-#define list_for_each_rcu __list_for_each_rcu
+#define list_for_each_rcu(pos, head) \
+for (pos = rcu_dereference((head)->next); \
+prefetch(pos->next), pos != (head); \
+pos = rcu_dereference(pos->next))
 #endif
 
 #define WPROBE_MIN_INTERVAL            100 /* minimum measurement interval in msecs */
@@ -203,6 +209,7 @@ wprobe_get_dev(struct nlattr *attr)
 int
 wprobe_add_frame(struct wprobe_iface *dev, const struct wprobe_wlan_hdr *hdr, void *data, int len)
 {
+       struct wprobe_wlan_hdr *new_hdr;
        struct wprobe_filter *f;
        struct sk_buff *skb;
        unsigned long flags;
@@ -221,7 +228,10 @@ wprobe_add_frame(struct wprobe_iface *dev, const struct wprobe_wlan_hdr *hdr, vo
        if (len + skb->len > WPROBE_MAX_FRAME_SIZE)
                len = WPROBE_MAX_FRAME_SIZE - skb->len;
 
-       memcpy(skb_put(skb, f->hdrlen), hdr, sizeof(struct wprobe_wlan_hdr));
+       new_hdr = (struct wprobe_wlan_hdr *) skb_put(skb, f->hdrlen);
+       memcpy(new_hdr, hdr, sizeof(struct wprobe_wlan_hdr));
+       new_hdr->len = cpu_to_be16(new_hdr->len);
+
        memcpy(skb_put(skb, len), data, len);
 
        for(i = 0; i < f->n_groups; i++) {
@@ -236,8 +246,13 @@ wprobe_add_frame(struct wprobe_iface *dev, const struct wprobe_wlan_hdr *hdr, vo
                                def = j;
                                continue;
                        }
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
+                       if (sk_run_filter(skb, fi->filter) == 0)
+                               continue;
+#else
                        if (sk_run_filter(skb, fi->filter, fi->hdr.n_items) == 0)
                                continue;
+#endif
 
                        found = true;
                        break;
@@ -844,6 +859,7 @@ wprobe_check_filter(void *data, int datalen, int gs)
 
                hdr->name[31] = 0;
                cur_is = be32_to_cpu(hdr->n_items);
+               hdr->n_items = cur_is;
                is += cur_is;
                for (j = 0; j < cur_is; j++) {
                        struct sock_filter *sf;
@@ -854,11 +870,13 @@ wprobe_check_filter(void *data, int datalen, int gs)
                        if (data > end)
                                goto overrun;
 
-                       if (hdr->n_items > 1024)
+                       hdr->name[31] = 0;
+                       n_items = be32_to_cpu(hdr->n_items);
+                       hdr->n_items = n_items;
+
+                       if (n_items > 1024)
                                goto overrun;
 
-                       hdr->name[31] = 0;
-                       hdr->n_items = n_items = be32_to_cpu(hdr->n_items);
                        sf = data;
                        if (n_items > 0) {
                                for (k = 0; k < n_items; k++) {
@@ -968,7 +986,7 @@ wprobe_set_filter(struct wprobe_iface *dev, void *data, int len)
                for (j = 0; j < g->n_items; j++) {
                        hdr = data;
                        f->items[cur_is++] = data;
-                       data += sizeof(*hdr) + be32_to_cpu(hdr->n_items) * sizeof(struct sock_filter);
+                       data += sizeof(*hdr) + hdr->n_items * sizeof(struct sock_filter);
                }
        }
        rcu_assign_pointer(dev->active_filter, f);
This page took 0.029899 seconds and 4 git commands to generate.