From f1d7b4b97f82c5fb912e0857818cbec07d264b23 Mon Sep 17 00:00:00 2001 From: Jozsef Kadlecsik Date: Mon, 29 Dec 2014 22:28:17 +0100 Subject: More compatibility checking and simplifications Try hard to keep the support of the 2.6.32 kernel tree and simplify the code with self-referential macros. --- kernel/include/linux/netfilter/ipset/ip_set.h | 2 +- .../linux/netfilter/ipset/ip_set_compat.h.in | 55 +++++++++++++++++++--- kernel/include/uapi/linux/netfilter/ipset/ip_set.h | 1 - kernel/net/netfilter/ipset/ip_set_core.c | 31 +++++------- kernel/net/netfilter/ipset/ip_set_getport.c | 4 -- kernel/net/netfilter/ipset/ip_set_hash_ipmark.c | 1 - kernel/net/netfilter/xt_set.c | 3 +- 7 files changed, 64 insertions(+), 33 deletions(-) (limited to 'kernel') diff --git a/kernel/include/linux/netfilter/ipset/ip_set.h b/kernel/include/linux/netfilter/ipset/ip_set.h index c65c218..e62bbe8 100644 --- a/kernel/include/linux/netfilter/ipset/ip_set.h +++ b/kernel/include/linux/netfilter/ipset/ip_set.h @@ -18,8 +18,8 @@ #include #include #include -#include #include +#include #define _IP_SET_MODULE_DESC(a, b, c) \ MODULE_DESCRIPTION(a " type of IP sets, revisions " b "-" c) diff --git a/kernel/include/linux/netfilter/ipset/ip_set_compat.h.in b/kernel/include/linux/netfilter/ipset/ip_set_compat.h.in index 64d6169..66e830f 100644 --- a/kernel/include/linux/netfilter/ipset/ip_set_compat.h.in +++ b/kernel/include/linux/netfilter/ipset/ip_set_compat.h.in @@ -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. @@ -78,6 +79,26 @@ #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 */ diff --git a/kernel/include/uapi/linux/netfilter/ipset/ip_set.h b/kernel/include/uapi/linux/netfilter/ipset/ip_set.h index 93549ef..63b2e34 100644 --- a/kernel/include/uapi/linux/netfilter/ipset/ip_set.h +++ b/kernel/include/uapi/linux/netfilter/ipset/ip_set.h @@ -10,7 +10,6 @@ #ifndef _UAPI_IP_SET_H #define _UAPI_IP_SET_H - #include /* The protocol version */ diff --git a/kernel/net/netfilter/ipset/ip_set_core.c b/kernel/net/netfilter/ipset/ip_set_core.c index 5869d69..ab4110a 100644 --- a/kernel/net/netfilter/ipset/ip_set_core.c +++ b/kernel/net/netfilter/ipset/ip_set_core.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -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: diff --git a/kernel/net/netfilter/ipset/ip_set_getport.c b/kernel/net/netfilter/ipset/ip_set_getport.c index 956c84a..4d9a2c0 100644 --- a/kernel/net/netfilter/ipset/ip_set_getport.c +++ b/kernel/net/netfilter/ipset/ip_set_getport.c @@ -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; diff --git a/kernel/net/netfilter/ipset/ip_set_hash_ipmark.c b/kernel/net/netfilter/ipset/ip_set_hash_ipmark.c index c96a61c..71468d5 100644 --- a/kernel/net/netfilter/ipset/ip_set_hash_ipmark.c +++ b/kernel/net/netfilter/ipset/ip_set_hash_ipmark.c @@ -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, diff --git a/kernel/net/netfilter/xt_set.c b/kernel/net/netfilter/xt_set.c index 9953a7b..6e2ab11 100644 --- a/kernel/net/netfilter/xt_set.c +++ b/kernel/net/netfilter/xt_set.c @@ -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; -- cgit v1.2.3