src: move to a pskb-based API

It occurred that skb reallocation does happen on older kernels, and
those kernels should really be supported, since the patch is really
minimal.
This commit is contained in:
Jan Engelhardt
2008-08-11 22:07:41 -04:00
parent 213acdffda
commit ab27472eb4
11 changed files with 75 additions and 82 deletions

View File

@@ -20,15 +20,6 @@
#include "compat_skbuff.h"
#include "compat_xtnu.h"
static inline int unable(const char *cause, unsigned int c)
{
if (net_ratelimit())
printk(KERN_ERR KBUILD_MODNAME
": compat layer limits reached (%s) - "
"dropping packets (%u so far)\n", cause, c);
return -1;
}
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
static int xtnu_match_run(const struct sk_buff *skb,
const struct net_device *in, const struct net_device *out,
@@ -161,15 +152,21 @@ static unsigned int xtnu_target_run(struct sk_buff **pskb,
static unsigned int xtnu_target_run(struct sk_buff **pskb,
const struct net_device *in, const struct net_device *out,
unsigned int hooknum, const struct xt_target *ct, const void *targinfo)
#else
static unsigned int xtnu_target_run(struct sk_buff *skb,
const struct net_device *in, const struct net_device *out,
unsigned int hooknum, const struct xt_target *ct, const void *targinfo)
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
{
struct xtnu_target *nt = xtcompat_nutarget(ct);
if (nt != NULL && nt->target != NULL)
return nt->target(*pskb, in, out, hooknum, nt, targinfo);
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
return nt->target(pskb, in, out, hooknum, nt, targinfo);
#else
return nt->target(&skb, in, out, hooknum, nt, targinfo);
#endif
return XT_CONTINUE;
}
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
static int xtnu_target_check(const char *table, const void *entry,
@@ -178,11 +175,10 @@ static int xtnu_target_check(const char *table, const void *entry,
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
static int xtnu_target_check(const char *table, const void *entry,
const struct xt_target *ct, void *targinfo, unsigned int hook_mask)
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
#else
static bool xtnu_target_check(const char *table, const void *entry,
const struct xt_target *ct, void *targinfo, unsigned int hook_mask)
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
{
struct xtnu_target *nt = xtcompat_nutarget(ct);
if (nt == NULL)
@@ -192,23 +188,19 @@ static bool xtnu_target_check(const char *table, const void *entry,
return true;
return nt->checkentry(table, entry, nt, targinfo, hook_mask);
}
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
static void xtnu_target_destroy(const struct xt_target *ct, void *targinfo,
unsigned int targinfosize)
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
#else
static void xtnu_target_destroy(const struct xt_target *ct, void *targinfo)
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
{
struct xtnu_target *nt = xtcompat_nutarget(ct);
if (nt != NULL && nt->destroy != NULL)
nt->destroy(nt, targinfo);
}
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
int xtnu_register_target(struct xtnu_target *nt)
{
struct xt_target *ct;
@@ -276,7 +268,6 @@ void xtnu_unregister_targets(struct xtnu_target *nt, unsigned int num)
xtnu_unregister_target(&nt[i]);
}
EXPORT_SYMBOL_GPL(xtnu_unregister_targets);
#endif
struct xt_match *xtnu_request_find_match(unsigned int af, const char *name,
uint8_t revision)
@@ -302,38 +293,28 @@ struct xt_match *xtnu_request_find_match(unsigned int af, const char *name,
}
EXPORT_SYMBOL_GPL(xtnu_request_find_match);
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
int xtnu_ip_route_me_harder(struct sk_buff *skb, unsigned int addr_type)
int xtnu_ip_route_me_harder(struct sk_buff **pskb, unsigned int addr_type)
{
static unsigned int rmh_counter;
struct sk_buff *nskb = skb;
int ret;
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 17)
/* Actually this one is valid up to 2.6.18.4, but changed in 2.6.18.5 */
ret = ip_route_me_harder(&skb);
return ip_route_me_harder(pskb);
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
ret = ip_route_me_harder(&nskb, addr_type);
return ip_route_me_harder(pskb, addr_type);
#else
return ip_route_me_harder(*pskb, addr_type);
#endif
if (nskb != skb)
return unable(__func__, ++rmh_counter);
return ret;
}
EXPORT_SYMBOL_GPL(xtnu_ip_route_me_harder);
int xtnu_skb_make_writable(struct sk_buff *skb, unsigned int len)
int xtnu_skb_make_writable(struct sk_buff **pskb, unsigned int len)
{
static unsigned int mkw_counter;
struct sk_buff *nskb = skb;
int ret;
ret = skb_make_writable(&skb, len);
if (nskb != skb)
return unable(__func__, ++mkw_counter) <= 0 ? false : true;
return ret;
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
return skb_make_writable(pskb, len);
#else
return skb_make_writable(*pskb, len);
#endif
}
EXPORT_SYMBOL_GPL(xtnu_skb_make_writable);
#endif
#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 24)
static int __xtnu_ip_local_out(struct sk_buff *skb)

View File

@@ -6,7 +6,7 @@
#include "compat_xtnu.h"
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
# warning Kernels below 2.6.18 not supported.
# warning Kernels below 2.6.18.5 not supported.
#endif
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
@@ -59,15 +59,13 @@
# define xt_unregister_matches xtnu_unregister_matches
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
# define xt_target xtnu_target
# define ip_route_me_harder xtnu_ip_route_me_harder
# define skb_make_writable xtnu_skb_make_writable
# define xt_register_target xtnu_register_target
# define xt_unregister_target xtnu_unregister_target
# define xt_register_targets xtnu_register_targets
# define xt_unregister_targets xtnu_unregister_targets
#endif
#define ip_route_me_harder xtnu_ip_route_me_harder
#define skb_make_writable xtnu_skb_make_writable
#define xt_target xtnu_target
#define xt_register_target xtnu_register_target
#define xt_unregister_target xtnu_unregister_target
#define xt_register_targets xtnu_register_targets
#define xt_unregister_targets xtnu_unregister_targets
#define xt_request_find_match xtnu_request_find_match

View File

@@ -38,7 +38,7 @@ struct xtnu_match {
struct xtnu_target {
struct list_head list;
char name[XT_FUNCTION_MAXNAMELEN - 1 - sizeof(void *)];
unsigned int (*target)(struct sk_buff *, const struct net_device *,
unsigned int (*target)(struct sk_buff **, const struct net_device *,
const struct net_device *, unsigned int,
const struct xtnu_target *, const void *);
bool (*checkentry)(const char *, const void *,
@@ -68,8 +68,8 @@ static inline struct xtnu_target *xtcompat_nutarget(const struct xt_target *t)
}
extern int xtnu_ip_local_out(struct sk_buff *);
extern int xtnu_ip_route_me_harder(struct sk_buff *, unsigned int);
extern int xtnu_skb_make_writable(struct sk_buff *, unsigned int);
extern int xtnu_ip_route_me_harder(struct sk_buff **, unsigned int);
extern int xtnu_skb_make_writable(struct sk_buff **, unsigned int);
extern int xtnu_register_match(struct xtnu_match *);
extern int xtnu_ip_route_output_key(void *, struct rtable **, struct flowi *);
extern void xtnu_unregister_match(struct xtnu_match *);

View File

@@ -75,9 +75,9 @@ static void xt_chaos_total(const struct xt_chaos_tginfo *info,
return;
}
static unsigned int chaos_tg(struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, unsigned int hooknum,
const struct xt_target *target, const void *targinfo)
static unsigned int chaos_tg(struct sk_buff **pskb,
const struct net_device *in, const struct net_device *out,
unsigned int hooknum, const struct xt_target *target, const void *targinfo)
{
/*
* Equivalent to:
@@ -88,18 +88,19 @@ static unsigned int chaos_tg(struct sk_buff *skb, const struct net_device *in,
* -A chaos -j DROP;
*/
const struct xt_chaos_tginfo *info = targinfo;
struct sk_buff *skb = *pskb;
const struct iphdr *iph = ip_hdr(skb);
if ((unsigned int)net_random() <= reject_percentage)
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
return xt_reject->target(&skb, in, out, hooknum,
return xt_reject->target(pskb, in, out, hooknum,
target->__compat_target, &reject_params, NULL);
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
return xt_reject->target(&skb, in, out, hooknum,
return xt_reject->target(pskb, in, out, hooknum,
target->__compat_target, &reject_params);
#else
return xt_reject->target(skb, in, out, hooknum, target,
&reject_params);
return xt_reject->target(skb, in, out, hooknum,
target->__compat_target, &reject_params);
#endif
/* TARPIT/DELUDE may not be called from the OUTPUT chain */

View File

@@ -122,8 +122,10 @@ static void delude_send_reset(struct sk_buff *oldskb, unsigned int hook)
dst_hold(oldskb->dst);
nskb->dst = oldskb->dst;
if (ip_route_me_harder(nskb, addr_type))
if (ip_route_me_harder(&nskb, addr_type))
goto free_nskb;
else
niph = ip_hdr(nskb);
niph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT);
nskb->ip_summed = CHECKSUM_NONE;
@@ -141,14 +143,14 @@ static void delude_send_reset(struct sk_buff *oldskb, unsigned int hook)
kfree_skb(nskb);
}
static unsigned int delude_tg(struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, unsigned int hooknum,
const struct xt_target *target, const void *targinfo)
static unsigned int delude_tg(struct sk_buff **pskb,
const struct net_device *in, const struct net_device *out,
unsigned int hooknum, const struct xt_target *target, const void *targinfo)
{
/* WARNING: This code causes reentry within iptables.
This means that the iptables jump stack is now crap. We
must return an absolute verdict. --RR */
delude_send_reset(skb, hooknum);
delude_send_reset(*pskb, hooknum);
return NF_DROP;
}

View File

@@ -20,10 +20,11 @@
#include <net/ip.h>
#include "compat_xtables.h"
static unsigned int echo_tg4(struct sk_buff *oldskb,
static unsigned int echo_tg4(struct sk_buff **poldskb,
const struct net_device *in, const struct net_device *out,
unsigned int hooknum, const struct xt_target *target, const void *targinfo)
{
const struct sk_buff *oldskb = *poldskb;
const struct udphdr *oldudp;
const struct iphdr *oldip;
struct udphdr *newudp, oldudp_buf;

View File

@@ -25,11 +25,12 @@ MODULE_ALIAS("ipt_IPMARK");
MODULE_ALIAS("ip6t_IPMARK");
static unsigned int
ipmark_tg4(struct sk_buff *skb, const struct net_device *in,
ipmark_tg4(struct sk_buff **pskb, const struct net_device *in,
const struct net_device *out, unsigned int hooknum,
const struct xt_target *target, const void *targinfo)
{
const struct xt_ipmark_tginfo *ipmarkinfo = targinfo;
const struct sk_buff *skb = *pskb;
const struct iphdr *iph = ip_hdr(skb);
__u32 mark;
@@ -62,11 +63,12 @@ static __u32 ipmark_from_ip6(const struct in6_addr *a, unsigned int s)
}
static unsigned int
ipmark_tg6(struct sk_buff *skb, const struct net_device *in,
ipmark_tg6(struct sk_buff **pskb, const struct net_device *in,
const struct net_device *out, unsigned int hooknum,
const struct xt_target *target, const void *targinfo)
{
const struct xt_ipmark_tginfo *info = targinfo;
const struct sk_buff *skb = *pskb;
const struct ipv6hdr *iph = ipv6_hdr(skb);
__u32 mark;

View File

@@ -30,10 +30,11 @@ static const char *const dir_names[] = {
};
static unsigned int
logmark_tg(struct sk_buff *skb, const struct net_device *in,
logmark_tg(struct sk_buff **pskb, const struct net_device *in,
const struct net_device *out, unsigned int hooknum,
const struct xt_target *target, const void *targinfo)
{
const struct sk_buff *skb = *pskb;
const struct xt_logmark_tginfo *info = targinfo;
const struct nf_conn *ct;
enum ip_conntrack_info ctinfo;

View File

@@ -58,10 +58,11 @@ static unsigned int sysrq_tg(const void *pdata, uint16_t len)
return NF_ACCEPT;
}
static unsigned int sysrq_tg4(struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, unsigned int hooknum,
const struct xt_target *target, const void *targinfo)
static unsigned int sysrq_tg4(struct sk_buff **pskb,
const struct net_device *in, const struct net_device *out,
unsigned int hooknum, const struct xt_target *target, const void *targinfo)
{
struct sk_buff *skb = *pskb;
const struct iphdr *iph;
const struct udphdr *udph;
uint16_t len;
@@ -79,10 +80,11 @@ static unsigned int sysrq_tg4(struct sk_buff *skb, const struct net_device *in,
return sysrq_tg((void *)udph + sizeof(struct udphdr), len);
}
static unsigned int sysrq_tg6(struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, unsigned int hooknum,
const struct xt_target *target, const void *targinfo)
static unsigned int sysrq_tg6(struct sk_buff **pskb,
const struct net_device *in, const struct net_device *out,
unsigned int hooknum, const struct xt_target *target, const void *targinfo)
{
struct sk_buff *skb = *pskb;
const struct ipv6hdr *iph;
const struct udphdr *udph;
uint16_t len;

View File

@@ -49,7 +49,7 @@
#include <net/tcp.h>
#include "compat_xtables.h"
static inline void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook)
static void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook)
{
struct tcphdr _otcph, *oth, *tcph;
unsigned int addr_type;
@@ -157,8 +157,10 @@ static inline void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook)
#endif
addr_type = RTN_LOCAL;
if (ip_route_me_harder(nskb, addr_type))
if (ip_route_me_harder(&nskb, addr_type))
goto free_nskb;
else
niph = ip_hdr(nskb);
nskb->ip_summed = CHECKSUM_NONE;
@@ -184,10 +186,11 @@ static inline void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook)
}
static unsigned int
tarpit_tg(struct sk_buff *skb, const struct net_device *in,
tarpit_tg(struct sk_buff **pskb, const struct net_device *in,
const struct net_device *out, unsigned int hooknum,
const struct xt_target *target, const void *targinfo)
{
const struct sk_buff *skb = *pskb;
const struct iphdr *iph = ip_hdr(skb);
const struct rtable *rt = (const void *)skb->dst;
@@ -215,7 +218,7 @@ tarpit_tg(struct sk_buff *skb, const struct net_device *in,
if (iph->frag_off & htons(IP_OFFSET))
return NF_DROP;
tarpit_tcp(skb, hooknum);
tarpit_tcp(*pskb, hooknum);
return NF_DROP;
}

View File

@@ -142,11 +142,12 @@ static void tee_ip_direct_send(struct sk_buff *skb)
* packets when we see they already have that ->nfct.
*/
static unsigned int
tee_tg(struct sk_buff *skb, const struct net_device *in,
tee_tg(struct sk_buff **pskb, const struct net_device *in,
const struct net_device *out, unsigned int hooknum,
const struct xt_target *target, const void *targinfo)
{
const struct xt_tee_tginfo *info = targinfo;
struct sk_buff *skb = *pskb;
#ifdef WITH_CONNTRACK
if (skb->nfct == &tee_track.ct_general) {
@@ -160,8 +161,9 @@ tee_tg(struct sk_buff *skb, const struct net_device *in,
}
#endif
if (!skb_make_writable(skb, sizeof(struct iphdr)))
if (!skb_make_writable(pskb, sizeof(struct iphdr)))
return NF_DROP;
skb = *pskb;
/*
* If we are in INPUT, the checksum must be recalculated since