]> granicus.if.org Git - ipset/commitdiff
More compatibility checking and simplifications
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Mon, 29 Dec 2014 21:28:17 +0000 (22:28 +0100)
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Tue, 6 Jan 2015 07:25:09 +0000 (08:25 +0100)
Try hard to keep the support of the 2.6.32 kernel tree and
simplify the code with self-referential macros.

configure.ac
kernel/include/linux/netfilter/ipset/ip_set.h
kernel/include/linux/netfilter/ipset/ip_set_compat.h.in
kernel/include/uapi/linux/netfilter/ipset/ip_set.h
kernel/net/netfilter/ipset/ip_set_core.c
kernel/net/netfilter/ipset/ip_set_getport.c
kernel/net/netfilter/ipset/ip_set_hash_ipmark.c
kernel/net/netfilter/xt_set.c

index 74bc7de7bdea1e93be453e578f1412b8e64388c0..0e9d054e28a798e79b688ebb695968f366212feb 100644 (file)
@@ -386,6 +386,16 @@ else
        AC_SUBST(HAVE_LIST_LAST_ENTRY, undef)
 fi
 
+AC_MSG_CHECKING([kernel source for list_next_entry])
+if test -f $ksourcedir/include/linux/list.h && \
+   $GREP -q 'list_next_entry' $ksourcedir/include/linux/list.h; then
+       AC_MSG_RESULT(yes)
+       AC_SUBST(HAVE_LIST_NEXT_ENTRY, define)
+else
+       AC_MSG_RESULT(no)
+       AC_SUBST(HAVE_LIST_NEXT_ENTRY, undef)
+fi
+
 AC_MSG_CHECKING([kernel source for struct net_generic])
 if test -f $ksourcedir/include/net/netns/generic.h && \
    $GREP -q 'struct net_generic' $ksourcedir/include/net/netns/generic.h; then
index c65c21856da82502c3caa0221b7e138c8f0c281f..e62bbe80d2d204d8b6dd944b564a70b30a68836c 100644 (file)
@@ -18,8 +18,8 @@
 #include <linux/stringify.h>
 #include <linux/vmalloc.h>
 #include <net/netlink.h>
-#include <uapi/linux/netfilter/ipset/ip_set.h>
 #include <linux/netfilter/ipset/ip_set_compat.h>
+#include <uapi/linux/netfilter/ipset/ip_set.h>
 
 #define _IP_SET_MODULE_DESC(a, b, c)           \
        MODULE_DESCRIPTION(a " type of IP sets, revisions " b "-" c)
index 64d61699255be28ec1d92fc303bdc5dd0761e8f8..66e830fb8404375b1bd5477758f35de7643810e6 100644 (file)
@@ -41,6 +41,7 @@
 #@HAVE_TCF_EMATCH_OPS_CHANGE_ARG_NET@ HAVE_TCF_EMATCH_OPS_CHANGE_ARG_NET
 #@HAVE_TCF_EMATCH_STRUCT_NET@ HAVE_TCF_EMATCH_STRUCT_NET
 #@HAVE_LIST_LAST_ENTRY@ HAVE_LIST_LAST_ENTRY
+#@HAVE_LIST_NEXT_ENTRY@ HAVE_LIST_NEXT_ENTRY
 
 /* Not everything could be moved here. Compatibility stuffs can be found in
  * xt_set.c, ip_set_core.c, ip_set_getport.c, pfxlen.c too.
 #endif
 #endif
 
+#ifndef kfree_rcu
+
+static inline void kfree_call_rcu(struct rcu_head *head,
+                                 void (*func)(struct rcu_head *rcu))
+{
+       call_rcu(head, func);
+}
+
+#define __is_kfree_rcu_offset(offset) ((offset) < 4096)
+
+#define __kfree_rcu(head, offset)      \
+do {                           \
+       BUILD_BUG_ON(!__is_kfree_rcu_offset(offset));   \
+       kfree_call_rcu(head, (void (*)(struct rcu_head *))(unsigned long)(offset)); \
+} while (0)
+
+#define kfree_rcu(ptr, rcu_head)       \
+       __kfree_rcu(&((ptr)->rcu_head), offsetof(typeof(*(ptr)), rcu_head))
+#endif
+
 #ifdef CHECK_KCONFIG
 #ifndef CONFIG_SPARSE_RCU_POINTER
 #error "CONFIG_SPARSE_RCU_POINTER must be enabled"
@@ -126,16 +147,18 @@ static inline int nla_put_net64(struct sk_buff *skb, int attrtype, __be64 value)
 #define NETLINK_PORTID(skb)    NETLINK_CB(skb).pid
 #endif
 
-#ifndef HAVE_NS_CAPABLE
+#ifndef HAVE_USER_NS_IN_STRUCT_NET
 #define ns_capable(ns, cap)    capable(cap)
 #endif
 
-#ifdef HAVE_NFNL_LOCK_SUBSYS
-#define lock_nfnl()            nfnl_lock(NFNL_SUBSYS_IPSET)
-#define unlock_nfnl()          nfnl_unlock(NFNL_SUBSYS_IPSET)
-#else
-#define lock_nfnl()            nfnl_lock()
-#define unlock_nfnl()          nfnl_unlock()
+#ifndef HAVE_NFNL_LOCK_SUBSYS
+#define nfnl_lock(x)           nfnl_lock()
+#define nfnl_unlock(x)         nfnl_unlock()
+#endif
+
+#if HAVE_IPV6_SKIP_EXTHDR_ARGS == 3
+#define ipv6_skip_exthdr(skbuff, start, nexthdrp, frag_offp)   \
+       ipv6_skip_exthdr(skbuff, start, nexthdrp)
 #endif
 
 #ifndef HAVE_KVFREE
@@ -174,5 +197,23 @@ static inline int nla_put_net32(struct sk_buff *skb, int attrtype, __be32 value)
 #define list_last_entry(ptr, type, member) \
        list_entry((ptr)->prev, type, member)
 #endif
+#ifndef HAVE_LIST_NEXT_ENTRY
+#define list_next_entry(pos, member)   \
+       list_entry((pos)->member.next, typeof(*(pos)), member)
+#define list_prev_entry(pos, member)   \
+       list_entry((pos)->member.prev, typeof(*(pos)), member)
+#endif
+
+#ifndef __aligned_u64
+#define __aligned_u64 __u64
+#endif
+
+#ifndef pr_warn
+#define pr_warn        pr_warning
+#endif
+
+#ifndef SIZE_MAX
+#define SIZE_MAX       (~(size_t)0)
+#endif
 
 #endif /* __IP_SET_COMPAT_H */
index 93549ef840310c1248bd846e4454c4cd2beeb9ef..63b2e34f1b60393b9593513f899d3243055c1e7e 100644 (file)
@@ -10,7 +10,6 @@
 #ifndef _UAPI_IP_SET_H
 #define _UAPI_IP_SET_H
 
-
 #include <linux/types.h>
 
 /* The protocol version */
index 5869d6905d1009d5d51afab84cd0402b284f856f..ab4110a5f2c3a299747dc91b7a2369ced1189eb6 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/ip.h>
 #include <linux/skbuff.h>
 #include <linux/spinlock.h>
-#include <linux/netlink.h>
 #include <linux/rculist.h>
 #include <net/netlink.h>
 #include <net/net_namespace.h>
@@ -104,14 +103,14 @@ find_set_type(const char *name, u8 family, u8 revision)
 static bool
 load_settype(const char *name)
 {
-       unlock_nfnl();
+       nfnl_unlock(NFNL_SUBSYS_IPSET);
        pr_debug("try to load ip_set_%s\n", name);
        if (request_module("ip_set_%s", name) < 0) {
                pr_warn("Can't find ip_set type %s\n", name);
-               lock_nfnl();
+               nfnl_lock(NFNL_SUBSYS_IPSET);
                return false;
        }
-       lock_nfnl();
+       nfnl_lock(NFNL_SUBSYS_IPSET);
        return true;
 }
 
@@ -663,13 +662,13 @@ ip_set_nfnl_get_byindex(struct net *net, ip_set_id_t index)
        if (index >= inst->ip_set_max)
                return IPSET_INVALID_ID;
 
-       lock_nfnl();
+       nfnl_lock(NFNL_SUBSYS_IPSET);
        set = ip_set(inst, index);
        if (set)
                __ip_set_get(set);
        else
                index = IPSET_INVALID_ID;
-       unlock_nfnl();
+       nfnl_unlock(NFNL_SUBSYS_IPSET);
 
        return index;
 }
@@ -687,13 +686,13 @@ ip_set_nfnl_put(struct net *net, ip_set_id_t index)
        struct ip_set *set;
        struct ip_set_net *inst = ip_set_pernet(net);
 
-       lock_nfnl();
+       nfnl_lock(NFNL_SUBSYS_IPSET);
        if (!inst->is_deleted) { /* already deleted from ip_set_net_exit() */
                set = ip_set(inst, index);
                if (set != NULL)
                        __ip_set_put(set);
        }
-       unlock_nfnl();
+       nfnl_unlock(NFNL_SUBSYS_IPSET);
 }
 EXPORT_SYMBOL_GPL(ip_set_nfnl_put);
 
@@ -1856,11 +1855,7 @@ ip_set_sockfn_get(struct sock *sk, int optval, void __user *user, int *len)
        struct net *net = sock_net(sk);
        struct ip_set_net *inst = ip_set_pernet(net);
 
-#ifdef HAVE_USER_NS_IN_STRUCT_NET
        if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
-#else
-       if (!capable(CAP_NET_ADMIN))
-#endif
                return -EPERM;
        if (optval != SO_IP_SET)
                return -EBADF;
@@ -1914,10 +1909,10 @@ ip_set_sockfn_get(struct sock *sk, int optval, void __user *user, int *len)
                        goto done;
                }
                req_get->set.name[IPSET_MAXNAMELEN - 1] = '\0';
-               lock_nfnl();
+               nfnl_lock(NFNL_SUBSYS_IPSET);
                find_set_and_id(inst, req_get->set.name, &id);
                req_get->set.index = id;
-               unlock_nfnl();
+               nfnl_unlock(NFNL_SUBSYS_IPSET);
                goto copy;
        }
        case IP_SET_OP_GET_FNAME: {
@@ -1929,12 +1924,12 @@ ip_set_sockfn_get(struct sock *sk, int optval, void __user *user, int *len)
                        goto done;
                }
                req_get->set.name[IPSET_MAXNAMELEN - 1] = '\0';
-               lock_nfnl();
+               nfnl_lock(NFNL_SUBSYS_IPSET);
                find_set_and_id(inst, req_get->set.name, &id);
                req_get->set.index = id;
                if (id != IPSET_INVALID_ID)
                        req_get->family = ip_set(inst, id)->family;
-               unlock_nfnl();
+               nfnl_unlock(NFNL_SUBSYS_IPSET);
                goto copy;
        }
        case IP_SET_OP_GET_BYINDEX: {
@@ -1946,11 +1941,11 @@ ip_set_sockfn_get(struct sock *sk, int optval, void __user *user, int *len)
                        ret = -EINVAL;
                        goto done;
                }
-               lock_nfnl();
+               nfnl_lock(NFNL_SUBSYS_IPSET);
                set = ip_set(inst, req_get->set.index);
                strncpy(req_get->set.name, set ? set->name : "",
                        IPSET_MAXNAMELEN);
-               unlock_nfnl();
+               nfnl_unlock(NFNL_SUBSYS_IPSET);
                goto copy;
        }
        default:
index 956c84ae8aa98a9e2ace7d218344488a901ea2d1..4d9a2c037ae906f79a8ffa1162686da3ffd7062a 100644 (file)
@@ -140,12 +140,8 @@ ip_set_get_ip6_port(const struct sk_buff *skb, bool src,
        __be16 frag_off = 0;
 
        nexthdr = ipv6_hdr(skb)->nexthdr;
-#if HAVE_IPV6_SKIP_EXTHDR_ARGS == 4
        protoff = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr,
                                   &frag_off);
-#else
-       protoff = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr);
-#endif
        if (protoff < 0 || (frag_off & htons(~0x7)) != 0)
                return false;
 
index c96a61c30bdfa920796108f4a85932d7c6444f55..71468d51589288732234166522acd0c5d01210bb 100644 (file)
@@ -215,7 +215,6 @@ hash_ipmark6_data_next(struct hash_ipmark4_elem *next,
 #define        IP_SET_EMIT_CREATE
 #include "ip_set_hash_gen.h"
 
-
 static int
 hash_ipmark6_kadt(struct ip_set *set, const struct sk_buff *skb,
                  const struct xt_action_param *par,
index 9953a7b7194203e03fe141b7b55d721e268d18b0..6e2ab1178ceaa54f2fea59d96f7326df3a177ada 100644 (file)
@@ -486,7 +486,8 @@ set_target_v3(struct sk_buff *skb, const struct xt_action_param *par)
                map_opt.cmdflags |= info->flags & (IPSET_FLAG_MAP_SKBMARK |
                                                   IPSET_FLAG_MAP_SKBPRIO |
                                                   IPSET_FLAG_MAP_SKBQUEUE);
-               ret = match_set(info->map_set.index, skb, par, &map_opt,
+               ret = match_set(info->map_set.index, skb, CAST_TO_MATCH par,
+                               &map_opt,
                                info->map_set.flags & IPSET_INV_MATCH);
                if (!ret)
                        return XT_CONTINUE;