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_skbuff.h"
#include "compat_xtnu.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) #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
static int xtnu_match_run(const struct sk_buff *skb, static int xtnu_match_run(const struct sk_buff *skb,
const struct net_device *in, const struct net_device *out, 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, static unsigned int xtnu_target_run(struct sk_buff **pskb,
const struct net_device *in, const struct net_device *out, const struct net_device *in, const struct net_device *out,
unsigned int hooknum, const struct xt_target *ct, const void *targinfo) 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 #endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
{ {
struct xtnu_target *nt = xtcompat_nutarget(ct); struct xtnu_target *nt = xtcompat_nutarget(ct);
if (nt != NULL && nt->target != NULL) 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; return XT_CONTINUE;
} }
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18) #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
static int xtnu_target_check(const char *table, const void *entry, 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) #elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22)
static int xtnu_target_check(const char *table, const void *entry, static int xtnu_target_check(const char *table, const void *entry,
const struct xt_target *ct, void *targinfo, unsigned int hook_mask) 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, static bool xtnu_target_check(const char *table, const void *entry,
const struct xt_target *ct, void *targinfo, unsigned int hook_mask) const struct xt_target *ct, void *targinfo, unsigned int hook_mask)
#endif #endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
{ {
struct xtnu_target *nt = xtcompat_nutarget(ct); struct xtnu_target *nt = xtcompat_nutarget(ct);
if (nt == NULL) if (nt == NULL)
@@ -192,23 +188,19 @@ static bool xtnu_target_check(const char *table, const void *entry,
return true; return true;
return nt->checkentry(table, entry, nt, targinfo, hook_mask); return nt->checkentry(table, entry, nt, targinfo, hook_mask);
} }
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18) #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18)
static void xtnu_target_destroy(const struct xt_target *ct, void *targinfo, static void xtnu_target_destroy(const struct xt_target *ct, void *targinfo,
unsigned int targinfosize) 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) static void xtnu_target_destroy(const struct xt_target *ct, void *targinfo)
#endif #endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
{ {
struct xtnu_target *nt = xtcompat_nutarget(ct); struct xtnu_target *nt = xtcompat_nutarget(ct);
if (nt != NULL && nt->destroy != NULL) if (nt != NULL && nt->destroy != NULL)
nt->destroy(nt, targinfo); nt->destroy(nt, targinfo);
} }
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
int xtnu_register_target(struct xtnu_target *nt) int xtnu_register_target(struct xtnu_target *nt)
{ {
struct xt_target *ct; struct xt_target *ct;
@@ -276,7 +268,6 @@ void xtnu_unregister_targets(struct xtnu_target *nt, unsigned int num)
xtnu_unregister_target(&nt[i]); xtnu_unregister_target(&nt[i]);
} }
EXPORT_SYMBOL_GPL(xtnu_unregister_targets); EXPORT_SYMBOL_GPL(xtnu_unregister_targets);
#endif
struct xt_match *xtnu_request_find_match(unsigned int af, const char *name, struct xt_match *xtnu_request_find_match(unsigned int af, const char *name,
uint8_t revision) 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); 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 **pskb, unsigned int addr_type)
int xtnu_ip_route_me_harder(struct sk_buff *skb, 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) #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 */ /* 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) #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 #endif
if (nskb != skb)
return unable(__func__, ++rmh_counter);
return ret;
} }
EXPORT_SYMBOL_GPL(xtnu_ip_route_me_harder); 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; #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
struct sk_buff *nskb = skb; return skb_make_writable(pskb, len);
int ret; #else
return skb_make_writable(*pskb, len);
ret = skb_make_writable(&skb, len); #endif
if (nskb != skb)
return unable(__func__, ++mkw_counter) <= 0 ? false : true;
return ret;
} }
EXPORT_SYMBOL_GPL(xtnu_skb_make_writable); EXPORT_SYMBOL_GPL(xtnu_skb_make_writable);
#endif
#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 24) #if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 24)
static int __xtnu_ip_local_out(struct sk_buff *skb) static int __xtnu_ip_local_out(struct sk_buff *skb)

View File

@@ -6,7 +6,7 @@
#include "compat_xtnu.h" #include "compat_xtnu.h"
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) #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 #endif
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
@@ -59,15 +59,13 @@
# define xt_unregister_matches xtnu_unregister_matches # define xt_unregister_matches xtnu_unregister_matches
#endif #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 ip_route_me_harder xtnu_ip_route_me_harder
#define skb_make_writable xtnu_skb_make_writable #define skb_make_writable xtnu_skb_make_writable
#define xt_target xtnu_target
#define xt_register_target xtnu_register_target #define xt_register_target xtnu_register_target
#define xt_unregister_target xtnu_unregister_target #define xt_unregister_target xtnu_unregister_target
#define xt_register_targets xtnu_register_targets #define xt_register_targets xtnu_register_targets
#define xt_unregister_targets xtnu_unregister_targets #define xt_unregister_targets xtnu_unregister_targets
#endif
#define xt_request_find_match xtnu_request_find_match #define xt_request_find_match xtnu_request_find_match

View File

@@ -38,7 +38,7 @@ struct xtnu_match {
struct xtnu_target { struct xtnu_target {
struct list_head list; struct list_head list;
char name[XT_FUNCTION_MAXNAMELEN - 1 - sizeof(void *)]; 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 net_device *, unsigned int,
const struct xtnu_target *, const void *); const struct xtnu_target *, const void *);
bool (*checkentry)(const char *, 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_local_out(struct sk_buff *);
extern int xtnu_ip_route_me_harder(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_skb_make_writable(struct sk_buff **, unsigned int);
extern int xtnu_register_match(struct xtnu_match *); extern int xtnu_register_match(struct xtnu_match *);
extern int xtnu_ip_route_output_key(void *, struct rtable **, struct flowi *); extern int xtnu_ip_route_output_key(void *, struct rtable **, struct flowi *);
extern void xtnu_unregister_match(struct xtnu_match *); 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; return;
} }
static unsigned int chaos_tg(struct sk_buff *skb, const struct net_device *in, static unsigned int chaos_tg(struct sk_buff **pskb,
const struct net_device *out, unsigned int hooknum, const struct net_device *in, const struct net_device *out,
const struct xt_target *target, const void *targinfo) unsigned int hooknum, const struct xt_target *target, const void *targinfo)
{ {
/* /*
* Equivalent to: * Equivalent to:
@@ -88,18 +88,19 @@ static unsigned int chaos_tg(struct sk_buff *skb, const struct net_device *in,
* -A chaos -j DROP; * -A chaos -j DROP;
*/ */
const struct xt_chaos_tginfo *info = targinfo; const struct xt_chaos_tginfo *info = targinfo;
struct sk_buff *skb = *pskb;
const struct iphdr *iph = ip_hdr(skb); const struct iphdr *iph = ip_hdr(skb);
if ((unsigned int)net_random() <= reject_percentage) if ((unsigned int)net_random() <= reject_percentage)
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18) #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); target->__compat_target, &reject_params, NULL);
#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23) #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); target->__compat_target, &reject_params);
#else #else
return xt_reject->target(skb, in, out, hooknum, target, return xt_reject->target(skb, in, out, hooknum,
&reject_params); target->__compat_target, &reject_params);
#endif #endif
/* TARPIT/DELUDE may not be called from the OUTPUT chain */ /* 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); dst_hold(oldskb->dst);
nskb->dst = 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; goto free_nskb;
else
niph = ip_hdr(nskb);
niph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT); niph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT);
nskb->ip_summed = CHECKSUM_NONE; nskb->ip_summed = CHECKSUM_NONE;
@@ -141,14 +143,14 @@ static void delude_send_reset(struct sk_buff *oldskb, unsigned int hook)
kfree_skb(nskb); kfree_skb(nskb);
} }
static unsigned int delude_tg(struct sk_buff *skb, const struct net_device *in, static unsigned int delude_tg(struct sk_buff **pskb,
const struct net_device *out, unsigned int hooknum, const struct net_device *in, const struct net_device *out,
const struct xt_target *target, const void *targinfo) unsigned int hooknum, const struct xt_target *target, const void *targinfo)
{ {
/* WARNING: This code causes reentry within iptables. /* WARNING: This code causes reentry within iptables.
This means that the iptables jump stack is now crap. We This means that the iptables jump stack is now crap. We
must return an absolute verdict. --RR */ must return an absolute verdict. --RR */
delude_send_reset(skb, hooknum); delude_send_reset(*pskb, hooknum);
return NF_DROP; return NF_DROP;
} }

View File

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

View File

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

View File

@@ -30,10 +30,11 @@ static const char *const dir_names[] = {
}; };
static unsigned int 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 net_device *out, unsigned int hooknum,
const struct xt_target *target, const void *targinfo) const struct xt_target *target, const void *targinfo)
{ {
const struct sk_buff *skb = *pskb;
const struct xt_logmark_tginfo *info = targinfo; const struct xt_logmark_tginfo *info = targinfo;
const struct nf_conn *ct; const struct nf_conn *ct;
enum ip_conntrack_info ctinfo; 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; return NF_ACCEPT;
} }
static unsigned int sysrq_tg4(struct sk_buff *skb, const struct net_device *in, static unsigned int sysrq_tg4(struct sk_buff **pskb,
const struct net_device *out, unsigned int hooknum, const struct net_device *in, const struct net_device *out,
const struct xt_target *target, const void *targinfo) unsigned int hooknum, const struct xt_target *target, const void *targinfo)
{ {
struct sk_buff *skb = *pskb;
const struct iphdr *iph; const struct iphdr *iph;
const struct udphdr *udph; const struct udphdr *udph;
uint16_t len; 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); return sysrq_tg((void *)udph + sizeof(struct udphdr), len);
} }
static unsigned int sysrq_tg6(struct sk_buff *skb, const struct net_device *in, static unsigned int sysrq_tg6(struct sk_buff **pskb,
const struct net_device *out, unsigned int hooknum, const struct net_device *in, const struct net_device *out,
const struct xt_target *target, const void *targinfo) unsigned int hooknum, const struct xt_target *target, const void *targinfo)
{ {
struct sk_buff *skb = *pskb;
const struct ipv6hdr *iph; const struct ipv6hdr *iph;
const struct udphdr *udph; const struct udphdr *udph;
uint16_t len; uint16_t len;

View File

@@ -49,7 +49,7 @@
#include <net/tcp.h> #include <net/tcp.h>
#include "compat_xtables.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; struct tcphdr _otcph, *oth, *tcph;
unsigned int addr_type; unsigned int addr_type;
@@ -157,8 +157,10 @@ static inline void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook)
#endif #endif
addr_type = RTN_LOCAL; addr_type = RTN_LOCAL;
if (ip_route_me_harder(nskb, addr_type)) if (ip_route_me_harder(&nskb, addr_type))
goto free_nskb; goto free_nskb;
else
niph = ip_hdr(nskb);
nskb->ip_summed = CHECKSUM_NONE; nskb->ip_summed = CHECKSUM_NONE;
@@ -184,10 +186,11 @@ static inline void tarpit_tcp(struct sk_buff *oldskb, unsigned int hook)
} }
static unsigned int 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 net_device *out, unsigned int hooknum,
const struct xt_target *target, const void *targinfo) const struct xt_target *target, const void *targinfo)
{ {
const struct sk_buff *skb = *pskb;
const struct iphdr *iph = ip_hdr(skb); const struct iphdr *iph = ip_hdr(skb);
const struct rtable *rt = (const void *)skb->dst; 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)) if (iph->frag_off & htons(IP_OFFSET))
return NF_DROP; return NF_DROP;
tarpit_tcp(skb, hooknum); tarpit_tcp(*pskb, hooknum);
return NF_DROP; 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. * packets when we see they already have that ->nfct.
*/ */
static unsigned int 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 net_device *out, unsigned int hooknum,
const struct xt_target *target, const void *targinfo) const struct xt_target *target, const void *targinfo)
{ {
const struct xt_tee_tginfo *info = targinfo; const struct xt_tee_tginfo *info = targinfo;
struct sk_buff *skb = *pskb;
#ifdef WITH_CONNTRACK #ifdef WITH_CONNTRACK
if (skb->nfct == &tee_track.ct_general) { if (skb->nfct == &tee_track.ct_general) {
@@ -160,8 +161,9 @@ tee_tg(struct sk_buff *skb, const struct net_device *in,
} }
#endif #endif
if (!skb_make_writable(skb, sizeof(struct iphdr))) if (!skb_make_writable(pskb, sizeof(struct iphdr)))
return NF_DROP; return NF_DROP;
skb = *pskb;
/* /*
* If we are in INPUT, the checksum must be recalculated since * If we are in INPUT, the checksum must be recalculated since