#include <linux/version.h>
#include <linux/netfilter_ipv4.h>
#include <linux/netfilter/x_tables.h>
+#include <net/ip.h>
+#include <net/route.h>
#include "compat_xtnu.h"
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) && \
EXPORT_SYMBOL_GPL(xtnu_ip_route_me_harder);
#endif
+#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 24)
+static int __xtnu_ip_local_out(struct sk_buff *skb)
+{
+ struct iphdr *iph = ip_hdr(skb);
+
+ iph->tot_len = htons(skb->len);
+ ip_send_check(iph);
+ return nf_hook(PF_INET, NF_IP_LOCAL_OUT, skb, NULL,
+ skb->dst->dev, dst_output);
+}
+
+int xtnu_ip_local_out(struct sk_buff *skb)
+{
+ int err;
+
+ err = __xtnu_ip_local_out(skb);
+ if (likely(err == 1))
+ err = dst_output(skb);
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(xtnu_ip_local_out);
+#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 23)
+static int __xtnu_ip_local_out(struct sk_buff **pskb)
+{
+ struct iphdr *iph = ip_hdr(*pskb);
+
+ iph->tot_len = htons((*pskb)->len);
+ ip_send_check(iph);
+ return nf_hook(PF_INET, NF_IP_LOCAL_OUT, pskb, NULL,
+ (*pskb)->dst->dev, dst_output);
+}
+
+int xtnu_ip_local_out(struct sk_buff *skb)
+{
+ int err;
+
+ err = __xtnu_ip_local_out(&skb);
+ if (likely(err == 1))
+ err = dst_output(skb);
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(xtnu_ip_local_out);
+#endif
+
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
+int xtnu_ip_route_output_key(void *net, struct rtable **rp, struct flowi *flp)
+{
+ return ip_route_output_flow(rp, flp, NULL, 0);
+}
+EXPORT_SYMBOL_GPL(xtnu_ip_route_output_key);
+#endif
+
MODULE_LICENSE("GPL");
# define NF_INET_FORWARD NF_IP_FORWARD
# define NF_INET_LOCAL_OUT NF_IP_LOCAL_OUT
# define NF_INET_POST_ROUTING NF_IP_POST_ROUTING
-#endif
-
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
+# define init_net xtnu_ip_route_output_key /* yes */
+# define ip_route_output_key xtnu_ip_route_output_key
# include "compat_nfinetaddr.h"
#endif
#include <linux/netfilter/x_tables.h>
#include <linux/spinlock.h>
+struct flowi;
struct module;
struct net_device;
+struct rtable;
struct sk_buff;
struct xtnu_match {
extern int xtnu_ip_route_me_harder(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 *);
extern int xtnu_register_matches(struct xtnu_match *, unsigned int);
extern void xtnu_unregister_matches(struct xtnu_match *, unsigned int);