Merge branch 'master' of /repos/git/net-next-2.6
authorPatrick McHardy <kaber@trash.net>
Tue, 20 Apr 2010 14:02:01 +0000 (16:02 +0200)
committerPatrick McHardy <kaber@trash.net>
Tue, 20 Apr 2010 14:02:01 +0000 (16:02 +0200)
Conflicts:
Documentation/feature-removal-schedule.txt
net/ipv6/netfilter/ip6t_REJECT.c
net/netfilter/xt_limit.c

Signed-off-by: Patrick McHardy <kaber@trash.net>
149 files changed:
Documentation/Changes
Documentation/feature-removal-schedule.txt
include/linux/ipv6.h
include/linux/kernel.h
include/linux/netfilter/Kbuild
include/linux/netfilter/nf_conntrack_tuple_common.h
include/linux/netfilter/x_tables.h
include/linux/netfilter/xt_CONNMARK.h
include/linux/netfilter/xt_MARK.h
include/linux/netfilter/xt_TEE.h [new file with mode: 0644]
include/linux/netfilter/xt_connmark.h
include/linux/netfilter/xt_mark.h
include/linux/netfilter/xt_recent.h
include/linux/netfilter_bridge.h
include/linux/netfilter_ipv6/ip6_tables.h
include/net/neighbour.h
net/bridge/br_device.c
net/bridge/br_forward.c
net/bridge/br_input.c
net/bridge/br_multicast.c
net/bridge/br_netfilter.c
net/bridge/br_stp_bpdu.c
net/bridge/netfilter/ebt_802_3.c
net/bridge/netfilter/ebt_among.c
net/bridge/netfilter/ebt_arp.c
net/bridge/netfilter/ebt_arpreply.c
net/bridge/netfilter/ebt_dnat.c
net/bridge/netfilter/ebt_ip.c
net/bridge/netfilter/ebt_ip6.c
net/bridge/netfilter/ebt_limit.c
net/bridge/netfilter/ebt_log.c
net/bridge/netfilter/ebt_mark.c
net/bridge/netfilter/ebt_mark_m.c
net/bridge/netfilter/ebt_nflog.c
net/bridge/netfilter/ebt_pkttype.c
net/bridge/netfilter/ebt_redirect.c
net/bridge/netfilter/ebt_snat.c
net/bridge/netfilter/ebt_stp.c
net/bridge/netfilter/ebt_ulog.c
net/bridge/netfilter/ebt_vlan.c
net/bridge/netfilter/ebtables.c
net/decnet/dn_neigh.c
net/decnet/dn_nsp_in.c
net/decnet/dn_route.c
net/ipv4/ip_forward.c
net/ipv4/ip_input.c
net/ipv4/ip_output.c
net/ipv4/ipmr.c
net/ipv4/netfilter/arp_tables.c
net/ipv4/netfilter/arpt_mangle.c
net/ipv4/netfilter/ip_queue.c
net/ipv4/netfilter/ip_tables.c
net/ipv4/netfilter/ipt_CLUSTERIP.c
net/ipv4/netfilter/ipt_ECN.c
net/ipv4/netfilter/ipt_LOG.c
net/ipv4/netfilter/ipt_MASQUERADE.c
net/ipv4/netfilter/ipt_NETMAP.c
net/ipv4/netfilter/ipt_REDIRECT.c
net/ipv4/netfilter/ipt_REJECT.c
net/ipv4/netfilter/ipt_ULOG.c
net/ipv4/netfilter/ipt_addrtype.c
net/ipv4/netfilter/ipt_ah.c
net/ipv4/netfilter/ipt_ecn.c
net/ipv4/netfilter/nf_nat_h323.c
net/ipv4/netfilter/nf_nat_rule.c
net/ipv4/netfilter/nf_nat_standalone.c
net/ipv4/netfilter/nf_nat_tftp.c
net/ipv4/raw.c
net/ipv4/xfrm4_input.c
net/ipv4/xfrm4_output.c
net/ipv6/ip6_input.c
net/ipv6/ip6_output.c
net/ipv6/ip6mr.c
net/ipv6/mcast.c
net/ipv6/ndisc.c
net/ipv6/netfilter.c
net/ipv6/netfilter/ip6_queue.c
net/ipv6/netfilter/ip6_tables.c
net/ipv6/netfilter/ip6t_LOG.c
net/ipv6/netfilter/ip6t_REJECT.c
net/ipv6/netfilter/ip6t_ah.c
net/ipv6/netfilter/ip6t_frag.c
net/ipv6/netfilter/ip6t_hbh.c
net/ipv6/netfilter/ip6t_ipv6header.c
net/ipv6/netfilter/ip6t_mh.c
net/ipv6/netfilter/ip6t_rt.c
net/ipv6/netfilter/nf_conntrack_reasm.c
net/ipv6/raw.c
net/ipv6/xfrm6_input.c
net/ipv6/xfrm6_output.c
net/netfilter/Kconfig
net/netfilter/Makefile
net/netfilter/ipvs/ip_vs_ftp.c
net/netfilter/ipvs/ip_vs_proto.c
net/netfilter/ipvs/ip_vs_proto_ah_esp.c
net/netfilter/ipvs/ip_vs_xmit.c
net/netfilter/nf_conntrack_ecache.c
net/netfilter/nf_conntrack_netlink.c
net/netfilter/nf_conntrack_proto.c
net/netfilter/nf_log.c
net/netfilter/nfnetlink.c
net/netfilter/nfnetlink_queue.c
net/netfilter/x_tables.c
net/netfilter/xt_CONNMARK.c [deleted file]
net/netfilter/xt_CONNSECMARK.c
net/netfilter/xt_CT.c
net/netfilter/xt_DSCP.c
net/netfilter/xt_HL.c
net/netfilter/xt_LED.c
net/netfilter/xt_MARK.c [deleted file]
net/netfilter/xt_NFLOG.c
net/netfilter/xt_NFQUEUE.c
net/netfilter/xt_RATEEST.c
net/netfilter/xt_SECMARK.c
net/netfilter/xt_TCPMSS.c
net/netfilter/xt_TCPOPTSTRIP.c
net/netfilter/xt_TEE.c [new file with mode: 0644]
net/netfilter/xt_TPROXY.c
net/netfilter/xt_cluster.c
net/netfilter/xt_connbytes.c
net/netfilter/xt_connlimit.c
net/netfilter/xt_connmark.c
net/netfilter/xt_conntrack.c
net/netfilter/xt_dccp.c
net/netfilter/xt_dscp.c
net/netfilter/xt_esp.c
net/netfilter/xt_hashlimit.c
net/netfilter/xt_helper.c
net/netfilter/xt_hl.c
net/netfilter/xt_iprange.c
net/netfilter/xt_limit.c
net/netfilter/xt_mac.c
net/netfilter/xt_mark.c
net/netfilter/xt_multiport.c
net/netfilter/xt_osf.c
net/netfilter/xt_physdev.c
net/netfilter/xt_policy.c
net/netfilter/xt_quota.c
net/netfilter/xt_rateest.c
net/netfilter/xt_recent.c
net/netfilter/xt_sctp.c
net/netfilter/xt_socket.c
net/netfilter/xt_state.c
net/netfilter/xt_statistic.c
net/netfilter/xt_string.c
net/netfilter/xt_tcpudp.c
net/netfilter/xt_time.c
net/netfilter/xt_u32.c
net/sched/act_ipt.c

index f08b313..eca9f6e 100644 (file)
@@ -49,7 +49,7 @@ o  oprofile               0.9                     # oprofiled --version
 o  udev                   081                     # udevinfo -V
 o  grub                   0.93                    # grub --version
 o  mcelog                0.6
-o  iptables               1.4.1                   # iptables -V
+o  iptables               1.4.2                   # iptables -V
 
 
 Kernel compilation
index 116a13c..a1c6e92 100644 (file)
@@ -241,16 +241,6 @@ Who:       Thomas Gleixner <tglx@linutronix.de>
 
 ---------------------------
 
-What (Why):
-       - xt_recent: the old ipt_recent proc dir
-         (superseded by /proc/net/xt_recent)
-
-When:  January 2009 or Linux 2.7.0, whichever comes first
-Why:   Superseded by newer revisions or modules
-Who:   Jan Engelhardt <jengelh@computergmbh.de>
-
----------------------------
-
 What:  GPIO autorequest on gpio_direction_{input,output}() in gpiolib
 When:  February 2010
 Why:   All callers should use explicit gpio_request()/gpio_free().
@@ -628,3 +618,11 @@ Why:       Internal alias support has been present in module-init-tools for some
        with no impact.
 
 Who:   Wey-Yi Guy <wey-yi.w.guy@intel.com>
+
+---------------------------
+
+What:  xt_NOTRACK
+Files: net/netfilter/xt_NOTRACK.c
+When:  April 2011
+Why:   Superseded by xt_CT
+Who:   Netfilter developer team <netfilter-devel@vger.kernel.org>
index e0cc9a7..7bdf6ff 100644 (file)
@@ -250,6 +250,7 @@ struct inet6_skb_parm {
 
 #define IP6SKB_XFRM_TRANSFORMED        1
 #define IP6SKB_FORWARDED       2
+#define IP6SKB_REROUTED                4
 };
 
 #define IP6CB(skb)     ((struct inet6_skb_parm*)((skb)->cb))
index 9365227..a38d6bd 100644 (file)
@@ -4,6 +4,8 @@
 /*
  * 'kernel.h' contains some often-used function prototypes etc
  */
+#define __ALIGN_KERNEL(x, a)           __ALIGN_KERNEL_MASK(x, (typeof(x))(a) - 1)
+#define __ALIGN_KERNEL_MASK(x, mask)   (((x) + (mask)) & ~(mask))
 
 #ifdef __KERNEL__
 
@@ -37,8 +39,8 @@ extern const char linux_proc_banner[];
 
 #define STACK_MAGIC    0xdeadbeef
 
-#define ALIGN(x,a)             __ALIGN_MASK(x,(typeof(x))(a)-1)
-#define __ALIGN_MASK(x,mask)   (((x)+(mask))&~(mask))
+#define ALIGN(x, a)            __ALIGN_KERNEL((x), (a))
+#define __ALIGN_MASK(x, mask)  __ALIGN_KERNEL_MASK((x), (mask))
 #define PTR_ALIGN(p, a)                ((typeof(p))ALIGN((unsigned long)(p), (a)))
 #define IS_ALIGNED(x, a)               (((x) & ((typeof(x))(a) - 1)) == 0)
 
index a5a63e4..48767cd 100644 (file)
@@ -16,6 +16,7 @@ header-y += xt_RATEEST.h
 header-y += xt_SECMARK.h
 header-y += xt_TCPMSS.h
 header-y += xt_TCPOPTSTRIP.h
+header-y += xt_TEE.h
 header-y += xt_TPROXY.h
 header-y += xt_comment.h
 header-y += xt_connbytes.h
index 8e145f0..2ea22b0 100644 (file)
@@ -1,8 +1,7 @@
 #ifndef _NF_CONNTRACK_TUPLE_COMMON_H
 #define _NF_CONNTRACK_TUPLE_COMMON_H
 
-enum ip_conntrack_dir
-{
+enum ip_conntrack_dir {
        IP_CT_DIR_ORIGINAL,
        IP_CT_DIR_REPLY,
        IP_CT_DIR_MAX
index 84c7c92..50c8672 100644 (file)
@@ -1,6 +1,6 @@
 #ifndef _X_TABLES_H
 #define _X_TABLES_H
-
+#include <linux/kernel.h>
 #include <linux/types.h>
 
 #define XT_FUNCTION_MAXNAMELEN 30
@@ -93,7 +93,7 @@ struct _xt_align {
        __u64 u64;
 };
 
-#define XT_ALIGN(s) ALIGN((s), __alignof__(struct _xt_align))
+#define XT_ALIGN(s) __ALIGN_KERNEL((s), __alignof__(struct _xt_align))
 
 /* Standard return verdict, or do jump. */
 #define XT_STANDARD_TARGET ""
@@ -197,6 +197,7 @@ struct xt_counters_info {
  * @family:    Actual NFPROTO_* through which the function is invoked
  *             (helpful when match->family == NFPROTO_UNSPEC)
  * @hotdrop:   drop packet if we had inspection problems
+ * Network namespace obtainable using dev_net(in/out)
  */
 struct xt_match_param {
        const struct net_device *in, *out;
@@ -213,12 +214,14 @@ struct xt_match_param {
  * struct xt_mtchk_param - parameters for match extensions'
  * checkentry functions
  *
+ * @net:       network namespace through which the check was invoked
  * @table:     table the rule is tried to be inserted into
  * @entryinfo: the family-specific rule data
- *             (struct ipt_ip, ip6t_ip, ebt_entry)
+ *             (struct ipt_ip, ip6t_ip, arpt_arp or (note) ebt_entry)
  * @match:     struct xt_match through which this function was invoked
  * @matchinfo: per-match data
  * @hook_mask: via which hooks the new rule is reachable
+ * Other fields as above.
  */
 struct xt_mtchk_param {
        struct net *net;
@@ -230,7 +233,10 @@ struct xt_mtchk_param {
        u_int8_t family;
 };
 
-/* Match destructor parameters */
+/**
+ * struct xt_mdtor_param - match destructor parameters
+ * Fields as above.
+ */
 struct xt_mtdtor_param {
        struct net *net;
        const struct xt_match *match;
@@ -297,7 +303,7 @@ struct xt_match {
                      const struct xt_match_param *);
 
        /* Called when user tries to insert an entry of this type. */
-       bool (*checkentry)(const struct xt_mtchk_param *);
+       int (*checkentry)(const struct xt_mtchk_param *);
 
        /* Called when entry of this type deleted. */
        void (*destroy)(const struct xt_mtdtor_param *);
@@ -309,9 +315,6 @@ struct xt_match {
        /* Set this to THIS_MODULE if you are a module, otherwise NULL */
        struct module *me;
 
-       /* Free to use by each match */
-       unsigned long data;
-
        const char *table;
        unsigned int matchsize;
 #ifdef CONFIG_COMPAT
@@ -328,6 +331,7 @@ struct xt_target {
        struct list_head list;
 
        const char name[XT_FUNCTION_MAXNAMELEN-1];
+       u_int8_t revision;
 
        /* Returns verdict. Argument order changed since 2.6.9, as this
           must now handle non-linear skbs, using skb_copy_bits and
@@ -338,8 +342,8 @@ struct xt_target {
        /* Called when user tries to insert an entry of this type:
            hook_mask is a bitmask of hooks from which it can be
            called. */
-       /* Should return true or false. */
-       bool (*checkentry)(const struct xt_tgchk_param *);
+       /* Should return true or false, or an error code (-Exxxx). */
+       int (*checkentry)(const struct xt_tgchk_param *);
 
        /* Called when entry of this type deleted. */
        void (*destroy)(const struct xt_tgdtor_param *);
@@ -360,7 +364,6 @@ struct xt_target {
        unsigned short proto;
 
        unsigned short family;
-       u_int8_t revision;
 };
 
 /* Furniture shopping... */
@@ -398,6 +401,13 @@ struct xt_table_info {
        unsigned int hook_entry[NF_INET_NUMHOOKS];
        unsigned int underflow[NF_INET_NUMHOOKS];
 
+       /*
+        * Number of user chains. Since tables cannot have loops, at most
+        * @stacksize jumps (number of user chains) can possibly be made.
+        */
+       unsigned int stacksize;
+       unsigned int *stackptr;
+       void ***jumpstack;
        /* ipt_entry tables: one per CPU */
        /* Note : this field MUST be the last one, see XT_TABLE_INFO_SZ */
        void *entries[1];
@@ -433,6 +443,8 @@ extern struct xt_table_info *xt_replace_table(struct xt_table *table,
 
 extern struct xt_match *xt_find_match(u8 af, const char *name, u8 revision);
 extern struct xt_target *xt_find_target(u8 af, const char *name, u8 revision);
+extern struct xt_match *xt_request_find_match(u8 af, const char *name,
+                                             u8 revision);
 extern struct xt_target *xt_request_find_target(u8 af, const char *name,
                                                u8 revision);
 extern int xt_find_revision(u8 af, const char *name, u8 revision,
@@ -598,7 +610,7 @@ struct _compat_xt_align {
        compat_u64 u64;
 };
 
-#define COMPAT_XT_ALIGN(s) ALIGN((s), __alignof__(struct _compat_xt_align))
+#define COMPAT_XT_ALIGN(s) __ALIGN_KERNEL((s), __alignof__(struct _compat_xt_align))
 
 extern void xt_compat_lock(u_int8_t af);
 extern void xt_compat_unlock(u_int8_t af);
index 0a85458..2f2e48e 100644 (file)
@@ -1,26 +1,6 @@
 #ifndef _XT_CONNMARK_H_target
 #define _XT_CONNMARK_H_target
 
-#include <linux/types.h>
-
-/* Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
- * by Henrik Nordstrom <hno@marasystems.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-enum {
-       XT_CONNMARK_SET = 0,
-       XT_CONNMARK_SAVE,
-       XT_CONNMARK_RESTORE
-};
-
-struct xt_connmark_tginfo1 {
-       __u32 ctmark, ctmask, nfmask;
-       __u8 mode;
-};
+#include <linux/netfilter/xt_connmark.h>
 
 #endif /*_XT_CONNMARK_H_target*/
index bc9561b..41c456d 100644 (file)
@@ -1,10 +1,6 @@
 #ifndef _XT_MARK_H_target
 #define _XT_MARK_H_target
 
-#include <linux/types.h>
-
-struct xt_mark_tginfo2 {
-       __u32 mark, mask;
-};
+#include <linux/netfilter/xt_mark.h>
 
 #endif /*_XT_MARK_H_target */
diff --git a/include/linux/netfilter/xt_TEE.h b/include/linux/netfilter/xt_TEE.h
new file mode 100644 (file)
index 0000000..5c21d5c
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef _XT_TEE_TARGET_H
+#define _XT_TEE_TARGET_H
+
+struct xt_tee_tginfo {
+       union nf_inet_addr gw;
+       char oif[16];
+
+       /* used internally by the kernel */
+       struct xt_tee_priv *priv __attribute__((aligned(8)));
+};
+
+#endif /* _XT_TEE_TARGET_H */
index 619e47c..efc17a8 100644 (file)
  * (at your option) any later version.
  */
 
+enum {
+       XT_CONNMARK_SET = 0,
+       XT_CONNMARK_SAVE,
+       XT_CONNMARK_RESTORE
+};
+
+struct xt_connmark_tginfo1 {
+       __u32 ctmark, ctmask, nfmask;
+       __u8 mode;
+};
+
 struct xt_connmark_mtinfo1 {
        __u32 mark, mask;
        __u8 invert;
index 6607c8f..ecadc40 100644 (file)
@@ -3,6 +3,10 @@
 
 #include <linux/types.h>
 
+struct xt_mark_tginfo2 {
+       __u32 mark, mask;
+};
+
 struct xt_mark_mtinfo1 {
        __u32 mark, mask;
        __u8 invert;
index d2c2766..83318e0 100644 (file)
@@ -9,6 +9,7 @@ enum {
        XT_RECENT_UPDATE   = 1 << 2,
        XT_RECENT_REMOVE   = 1 << 3,
        XT_RECENT_TTL      = 1 << 4,
+       XT_RECENT_REAP     = 1 << 5,
 
        XT_RECENT_SOURCE   = 0,
        XT_RECENT_DEST     = 1,
@@ -16,6 +17,12 @@ enum {
        XT_RECENT_NAME_LEN = 200,
 };
 
+/* Only allowed with --rcheck and --update */
+#define XT_RECENT_MODIFIERS (XT_RECENT_TTL|XT_RECENT_REAP)
+
+#define XT_RECENT_VALID_FLAGS (XT_RECENT_CHECK|XT_RECENT_SET|XT_RECENT_UPDATE|\
+                              XT_RECENT_REMOVE|XT_RECENT_TTL|XT_RECENT_REAP)
+
 struct xt_recent_mtinfo {
        __u32 seconds;
        __u32 hit_count;
index f8105e5..ea0e44b 100644 (file)
@@ -41,10 +41,10 @@ enum nf_br_hook_priorities {
 
 #define BRNF_PKT_TYPE                  0x01
 #define BRNF_BRIDGED_DNAT              0x02
-#define BRNF_DONT_TAKE_PARENT          0x04
-#define BRNF_BRIDGED                   0x08
-#define BRNF_NF_BRIDGE_PREROUTING      0x10
-
+#define BRNF_BRIDGED                   0x04
+#define BRNF_NF_BRIDGE_PREROUTING      0x08
+#define BRNF_8021Q                     0x10
+#define BRNF_PPPoE                     0x20
 
 /* Only used in br_forward.c */
 extern int nf_bridge_copy_header(struct sk_buff *skb);
@@ -68,6 +68,20 @@ static inline unsigned int nf_bridge_encap_header_len(const struct sk_buff *skb)
        }
 }
 
+extern int br_handle_frame_finish(struct sk_buff *skb);
+/* Only used in br_device.c */
+static inline int br_nf_pre_routing_finish_bridge_slow(struct sk_buff *skb)
+{
+       struct nf_bridge_info *nf_bridge = skb->nf_bridge;
+
+       skb_pull(skb, ETH_HLEN);
+       nf_bridge->mask ^= BRNF_BRIDGED_DNAT;
+       skb_copy_to_linear_data_offset(skb, -(ETH_HLEN-ETH_ALEN),
+                                      skb->nf_bridge->data, ETH_HLEN-ETH_ALEN);
+       skb->dev = nf_bridge->physindev;
+       return br_handle_frame_finish(skb);
+}
+
 /* This is called by the IP fragmenting code and it ensures there is
  * enough room for the encapsulating header (if there is one). */
 static inline unsigned int nf_bridge_pad(const struct sk_buff *skb)
index e5ba03d..18442ff 100644 (file)
@@ -316,10 +316,6 @@ extern int ip6t_ext_hdr(u8 nexthdr);
 extern int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
                         int target, unsigned short *fragoff);
 
-extern int ip6_masked_addrcmp(const struct in6_addr *addr1,
-                             const struct in6_addr *mask,
-                             const struct in6_addr *addr2);
-
 #define IP6T_ALIGN(s) XT_ALIGN(s)
 
 #ifdef CONFIG_COMPAT
index da1d58b..eb21340 100644 (file)
@@ -299,6 +299,20 @@ static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
        return 0;
 }
 
+#ifdef CONFIG_BRIDGE_NETFILTER
+static inline int neigh_hh_bridge(struct hh_cache *hh, struct sk_buff *skb)
+{
+       unsigned seq, hh_alen;
+
+       do {
+               seq = read_seqbegin(&hh->hh_lock);
+               hh_alen = HH_DATA_ALIGN(ETH_HLEN);
+               memcpy(skb->data - hh_alen, hh->hh_data, ETH_ALEN + hh_alen - ETH_HLEN);
+       } while (read_seqretry(&hh->hh_lock, seq));
+       return 0;
+}
+#endif
+
 static inline int neigh_hh_output(struct hh_cache *hh, struct sk_buff *skb)
 {
        unsigned seq;
index 5b8a6e7..007bde8 100644 (file)
@@ -15,7 +15,7 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
-
+#include <linux/netfilter_bridge.h>
 #include <asm/uaccess.h>
 #include "br_private.h"
 
@@ -28,6 +28,13 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
        struct net_bridge_mdb_entry *mdst;
        struct br_cpu_netstats *brstats = this_cpu_ptr(br->stats);
 
+#ifdef CONFIG_BRIDGE_NETFILTER
+       if (skb->nf_bridge && (skb->nf_bridge->mask & BRNF_BRIDGED_DNAT)) {
+               br_nf_pre_routing_finish_bridge_slow(skb);
+               return NETDEV_TX_OK;
+       }
+#endif
+
        brstats->tx_packets++;
        brstats->tx_bytes += skb->len;
 
index 7a241c3..92fb329 100644 (file)
@@ -44,7 +44,7 @@ int br_dev_queue_push_xmit(struct sk_buff *skb)
        if (packet_length(skb) > skb->dev->mtu && !skb_is_gso(skb))
                kfree_skb(skb);
        else {
-               /* ip_refrag calls ip_fragment, doesn't copy the MAC header. */
+               /* ip_fragment doesn't copy the MAC header */
                if (nf_bridge_maybe_copy_header(skb))
                        kfree_skb(skb);
                else {
@@ -59,7 +59,7 @@ int br_dev_queue_push_xmit(struct sk_buff *skb)
 
 int br_forward_finish(struct sk_buff *skb)
 {
-       return NF_HOOK(PF_BRIDGE, NF_BR_POST_ROUTING, skb, NULL, skb->dev,
+       return NF_HOOK(NFPROTO_BRIDGE, NF_BR_POST_ROUTING, skb, NULL, skb->dev,
                       br_dev_queue_push_xmit);
 
 }
@@ -67,8 +67,8 @@ int br_forward_finish(struct sk_buff *skb)
 static void __br_deliver(const struct net_bridge_port *to, struct sk_buff *skb)
 {
        skb->dev = to->dev;
-       NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
-                       br_forward_finish);
+       NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
+               br_forward_finish);
 }
 
 static void __br_forward(const struct net_bridge_port *to, struct sk_buff *skb)
@@ -84,8 +84,8 @@ static void __br_forward(const struct net_bridge_port *to, struct sk_buff *skb)
        skb->dev = to->dev;
        skb_forward_csum(skb);
 
-       NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, indev, skb->dev,
-                       br_forward_finish);
+       NF_HOOK(NFPROTO_BRIDGE, NF_BR_FORWARD, skb, indev, skb->dev,
+               br_forward_finish);
 }
 
 /* called with rcu_read_lock */
index e7f4c1d..d36e700 100644 (file)
@@ -33,7 +33,7 @@ static int br_pass_frame_up(struct sk_buff *skb)
        indev = skb->dev;
        skb->dev = brdev;
 
-       return NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL,
+       return NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL,
                       netif_receive_skb);
 }
 
@@ -156,7 +156,7 @@ struct sk_buff *br_handle_frame(struct net_bridge_port *p, struct sk_buff *skb)
                if (p->br->stp_enabled == BR_NO_STP && dest[5] == 0)
                        goto forward;
 
-               if (NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev,
+               if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev,
                            NULL, br_handle_local_finish))
                        return NULL;    /* frame consumed by filter */
                else
@@ -177,7 +177,7 @@ forward:
                if (!compare_ether_addr(p->br->dev->dev_addr, dest))
                        skb->pkt_type = PACKET_HOST;
 
-               NF_HOOK(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
+               NF_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
                        br_handle_frame_finish);
                break;
        default:
index 3fe86ff..8ccdb8e 100644 (file)
@@ -608,7 +608,7 @@ static void br_multicast_send_query(struct net_bridge *br,
        if (port) {
                __skb_push(skb, sizeof(struct ethhdr));
                skb->dev = port->dev;
-               NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
+               NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
                        dev_queue_xmit);
        } else
                netif_rx(skb);
index 4c4977d..6b80ebc 100644 (file)
@@ -3,15 +3,8 @@
  *     Linux ethernet bridge
  *
  *     Authors:
- *     Lennert Buytenhek               <buytenh@gnu.org>
- *     Bart De Schuymer (maintainer)   <bdschuym@pandora.be>
- *
- *     Changes:
- *     Apr 29 2003: physdev module support (bdschuym)
- *     Jun 19 2003: let arptables see bridged ARP traffic (bdschuym)
- *     Oct 06 2003: filter encapsulated IP/ARP VLAN traffic on untagged bridge
- *                  (bdschuym)
- *     Sep 01 2004: add IPv6 filtering (bdschuym)
+ *     Lennert Buytenhek               <buytenh@gnu.org>
+ *     Bart De Schuymer                <bdschuym@pandora.be>
  *
  *     This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License
@@ -204,15 +197,24 @@ static inline void nf_bridge_save_header(struct sk_buff *skb)
                                         skb->nf_bridge->data, header_size);
 }
 
-/*
- * When forwarding bridge frames, we save a copy of the original
- * header before processing.
+static inline void nf_bridge_update_protocol(struct sk_buff *skb)
+{
+       if (skb->nf_bridge->mask & BRNF_8021Q)
+               skb->protocol = htons(ETH_P_8021Q);
+       else if (skb->nf_bridge->mask & BRNF_PPPoE)
+               skb->protocol = htons(ETH_P_PPP_SES);
+}
+
+/* Fill in the header for fragmented IP packets handled by
+ * the IPv4 connection tracking code.
  */
 int nf_bridge_copy_header(struct sk_buff *skb)
 {
        int err;
-       int header_size = ETH_HLEN + nf_bridge_encap_header_len(skb);
+       unsigned int header_size;
 
+       nf_bridge_update_protocol(skb);
+       header_size = ETH_HLEN + nf_bridge_encap_header_len(skb);
        err = skb_cow_head(skb, header_size);
        if (err)
                return err;
@@ -246,27 +248,48 @@ static int br_nf_pre_routing_finish_ipv6(struct sk_buff *skb)
        skb_dst_set(skb, &rt->u.dst);
 
        skb->dev = nf_bridge->physindev;
+       nf_bridge_update_protocol(skb);
        nf_bridge_push_encap_header(skb);
-       NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
+       NF_HOOK_THRESH(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
                       br_handle_frame_finish, 1);
 
        return 0;
 }
 
-static void __br_dnat_complain(void)
+/* Obtain the correct destination MAC address, while preserving the original
+ * source MAC address. If we already know this address, we just copy it. If we
+ * don't, we use the neighbour framework to find out. In both cases, we make
+ * sure that br_handle_frame_finish() is called afterwards.
+ */
+static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb)
 {
-       static unsigned long last_complaint;
+       struct nf_bridge_info *nf_bridge = skb->nf_bridge;
+       struct dst_entry *dst;
 
-       if (jiffies - last_complaint >= 5 * HZ) {
-               printk(KERN_WARNING "Performing cross-bridge DNAT requires IP "
-                      "forwarding to be enabled\n");
-               last_complaint = jiffies;
+       skb->dev = bridge_parent(skb->dev);
+       if (!skb->dev)
+               goto free_skb;
+       dst = skb_dst(skb);
+       if (dst->hh) {
+               neigh_hh_bridge(dst->hh, skb);
+               skb->dev = nf_bridge->physindev;
+               return br_handle_frame_finish(skb);
+       } else if (dst->neighbour) {
+               /* the neighbour function below overwrites the complete
+                * MAC header, so we save the Ethernet source address and
+                * protocol number. */
+               skb_copy_from_linear_data_offset(skb, -(ETH_HLEN-ETH_ALEN), skb->nf_bridge->data, ETH_HLEN-ETH_ALEN);
+               /* tell br_dev_xmit to continue with forwarding */
+               nf_bridge->mask |= BRNF_BRIDGED_DNAT;
+               return dst->neighbour->output(skb);
        }
+free_skb:
+       kfree_skb(skb);
+       return 0;
 }
 
 /* This requires some explaining. If DNAT has taken place,
- * we will need to fix up the destination Ethernet address,
- * and this is a tricky process.
+ * we will need to fix up the destination Ethernet address.
  *
  * There are two cases to consider:
  * 1. The packet was DNAT'ed to a device in the same bridge
@@ -280,62 +303,29 @@ static void __br_dnat_complain(void)
  * call ip_route_input() and to look at skb->dst->dev, which is
  * changed to the destination device if ip_route_input() succeeds.
  *
- * Let us first consider the case that ip_route_input() succeeds:
- *
- * If skb->dst->dev equals the logical bridge device the packet
- * came in on, we can consider this bridging. The packet is passed
- * through the neighbour output function to build a new destination
- * MAC address, which will make the packet enter br_nf_local_out()
- * not much later. In that function it is assured that the iptables
- * FORWARD chain is traversed for the packet.
+ * Let's first consider the case that ip_route_input() succeeds:
  *
+ * If the output device equals the logical bridge device the packet
+ * came in on, we can consider this bridging. The corresponding MAC
+ * address will be obtained in br_nf_pre_routing_finish_bridge.
  * Otherwise, the packet is considered to be routed and we just
  * change the destination MAC address so that the packet will
  * later be passed up to the IP stack to be routed. For a redirected
  * packet, ip_route_input() will give back the localhost as output device,
  * which differs from the bridge device.
  *
- * Let us now consider the case that ip_route_input() fails:
+ * Let's now consider the case that ip_route_input() fails:
  *
  * This can be because the destination address is martian, in which case
  * the packet will be dropped.
- * After a "echo '0' > /proc/sys/net/ipv4/ip_forward" ip_route_input()
- * will fail, while __ip_route_output_key() will return success. The source
- * address for __ip_route_output_key() is set to zero, so __ip_route_output_key
+ * If IP forwarding is disabled, ip_route_input() will fail, while
+ * ip_route_output_key() can return success. The source
+ * address for ip_route_output_key() is set to zero, so ip_route_output_key()
  * thinks we're handling a locally generated packet and won't care
- * if IP forwarding is allowed. We send a warning message to the users's
- * log telling her to put IP forwarding on.
- *
- * ip_route_input() will also fail if there is no route available.
- * In that case we just drop the packet.
- *
- * --Lennert, 20020411
- * --Bart, 20020416 (updated)
- * --Bart, 20021007 (updated)
- * --Bart, 20062711 (updated) */
-static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb)
-{
-       if (skb->pkt_type == PACKET_OTHERHOST) {
-               skb->pkt_type = PACKET_HOST;
-               skb->nf_bridge->mask |= BRNF_PKT_TYPE;
-       }
-       skb->nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING;
-
-       skb->dev = bridge_parent(skb->dev);
-       if (skb->dev) {
-               struct dst_entry *dst = skb_dst(skb);
-
-               nf_bridge_pull_encap_header(skb);
-
-               if (dst->hh)
-                       return neigh_hh_output(dst->hh, skb);
-               else if (dst->neighbour)
-                       return dst->neighbour->output(skb);
-       }
-       kfree_skb(skb);
-       return 0;
-}
-
+ * if IP forwarding is enabled. If the output device equals the logical bridge
+ * device, we proceed as if ip_route_input() succeeded. If it differs from the
+ * logical bridge port or if ip_route_output_key() fails we drop the packet.
+ */
 static int br_nf_pre_routing_finish(struct sk_buff *skb)
 {
        struct net_device *dev = skb->dev;
@@ -379,11 +369,6 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb)
                                        skb_dst_set(skb, (struct dst_entry *)rt);
                                        goto bridged_dnat;
                                }
-                               /* we are sure that forwarding is disabled, so printing
-                                * this message is no problem. Note that the packet could
-                                * still have a martian destination address, in which case
-                                * the packet could be dropped even if forwarding were enabled */
-                               __br_dnat_complain();
                                dst_release((struct dst_entry *)rt);
                        }
 free_skb:
@@ -392,12 +377,11 @@ free_skb:
                } else {
                        if (skb_dst(skb)->dev == dev) {
 bridged_dnat:
-                               /* Tell br_nf_local_out this is a
-                                * bridged frame */
-                               nf_bridge->mask |= BRNF_BRIDGED_DNAT;
                                skb->dev = nf_bridge->physindev;
+                               nf_bridge_update_protocol(skb);
                                nf_bridge_push_encap_header(skb);
-                               NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING,
+                               NF_HOOK_THRESH(NFPROTO_BRIDGE,
+                                              NF_BR_PRE_ROUTING,
                                               skb, skb->dev, NULL,
                                               br_nf_pre_routing_finish_bridge,
                                               1);
@@ -417,8 +401,9 @@ bridged_dnat:
        }
 
        skb->dev = nf_bridge->physindev;
+       nf_bridge_update_protocol(skb);
        nf_bridge_push_encap_header(skb);
-       NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
+       NF_HOOK_THRESH(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
                       br_handle_frame_finish, 1);
 
        return 0;
@@ -437,6 +422,10 @@ static struct net_device *setup_pre_routing(struct sk_buff *skb)
        nf_bridge->mask |= BRNF_NF_BRIDGE_PREROUTING;
        nf_bridge->physindev = skb->dev;
        skb->dev = bridge_parent(skb->dev);
+       if (skb->protocol == htons(ETH_P_8021Q))
+               nf_bridge->mask |= BRNF_8021Q;
+       else if (skb->protocol == htons(ETH_P_PPP_SES))
+               nf_bridge->mask |= BRNF_PPPoE;
 
        return skb->dev;
 }
@@ -535,7 +524,8 @@ static unsigned int br_nf_pre_routing_ipv6(unsigned int hook,
        if (!setup_pre_routing(skb))
                return NF_DROP;
 
-       NF_HOOK(PF_INET6, NF_INET_PRE_ROUTING, skb, skb->dev, NULL,
+       skb->protocol = htons(ETH_P_IPV6);
+       NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING, skb, skb->dev, NULL,
                br_nf_pre_routing_finish_ipv6);
 
        return NF_STOLEN;
@@ -607,8 +597,9 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff *skb,
        if (!setup_pre_routing(skb))
                return NF_DROP;
        store_orig_dstaddr(skb);
+       skb->protocol = htons(ETH_P_IP);
 
-       NF_HOOK(PF_INET, NF_INET_PRE_ROUTING, skb, skb->dev, NULL,
+       NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, skb, skb->dev, NULL,
                br_nf_pre_routing_finish);
 
        return NF_STOLEN;
@@ -655,8 +646,10 @@ static int br_nf_forward_finish(struct sk_buff *skb)
        } else {
                in = *((struct net_device **)(skb->cb));
        }
+       nf_bridge_update_protocol(skb);
        nf_bridge_push_encap_header(skb);
-       NF_HOOK_THRESH(PF_BRIDGE, NF_BR_FORWARD, skb, in,
+
+       NF_HOOK_THRESH(NFPROTO_BRIDGE, NF_BR_FORWARD, skb, in,
                       skb->dev, br_forward_finish, 1);
        return 0;
 }
@@ -707,6 +700,10 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb,
        /* The physdev module checks on this */
        nf_bridge->mask |= BRNF_BRIDGED;
        nf_bridge->physoutdev = skb->dev;
+       if (pf == PF_INET)
+               skb->protocol = htons(ETH_P_IP);
+       else
+               skb->protocol = htons(ETH_P_IPV6);
 
        NF_HOOK(pf, NF_INET_FORWARD, skb, bridge_parent(in), parent,
                br_nf_forward_finish);
@@ -744,59 +741,10 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff *skb,
        return NF_STOLEN;
 }
 
-/* PF_BRIDGE/LOCAL_OUT ***********************************************
- *
- * This function sees both locally originated IP packets and forwarded
- * IP packets (in both cases the destination device is a bridge
- * device). It also sees bridged-and-DNAT'ed packets.
- *
- * If (nf_bridge->mask & BRNF_BRIDGED_DNAT) then the packet is bridged
- * and we fake the PF_BRIDGE/FORWARD hook. The function br_nf_forward()
- * will then fake the PF_INET/FORWARD hook. br_nf_local_out() has priority
- * NF_BR_PRI_FIRST, so no relevant PF_BRIDGE/INPUT functions have been nor
- * will be executed.
- */
-static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff *skb,
-                                   const struct net_device *in,
-                                   const struct net_device *out,
-                                   int (*okfn)(struct sk_buff *))
-{
-       struct net_device *realindev;
-       struct nf_bridge_info *nf_bridge;
-
-       if (!skb->nf_bridge)
-               return NF_ACCEPT;
-
-       /* Need exclusive nf_bridge_info since we might have multiple
-        * different physoutdevs. */
-       if (!nf_bridge_unshare(skb))
-               return NF_DROP;
-
-       nf_bridge = skb->nf_bridge;
-       if (!(nf_bridge->mask & BRNF_BRIDGED_DNAT))
-               return NF_ACCEPT;
-
-       /* Bridged, take PF_BRIDGE/FORWARD.
-        * (see big note in front of br_nf_pre_routing_finish) */
-       nf_bridge->physoutdev = skb->dev;
-       realindev = nf_bridge->physindev;
-
-       if (nf_bridge->mask & BRNF_PKT_TYPE) {
-               skb->pkt_type = PACKET_OTHERHOST;
-               nf_bridge->mask ^= BRNF_PKT_TYPE;
-       }
-       nf_bridge_push_encap_header(skb);
-
-       NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, realindev, skb->dev,
-               br_forward_finish);
-       return NF_STOLEN;
-}
-
 #if defined(CONFIG_NF_CONNTRACK_IPV4) || defined(CONFIG_NF_CONNTRACK_IPV4_MODULE)
 static int br_nf_dev_queue_xmit(struct sk_buff *skb)
 {
-       if (skb->nfct != NULL &&
-           (skb->protocol == htons(ETH_P_IP) || IS_VLAN_IP(skb)) &&
+       if (skb->nfct != NULL && skb->protocol == htons(ETH_P_IP) &&
            skb->len > skb->dev->mtu &&
            !skb_is_gso(skb))
                return ip_fragment(skb, br_dev_queue_push_xmit);
@@ -820,21 +768,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb,
        struct net_device *realoutdev = bridge_parent(skb->dev);
        u_int8_t pf;
 
-#ifdef CONFIG_NETFILTER_DEBUG
-       /* Be very paranoid. This probably won't happen anymore, but let's
-        * keep the check just to be sure... */
-       if (skb_mac_header(skb) < skb->head ||
-           skb_mac_header(skb) + ETH_HLEN > skb->data) {
-               printk(KERN_CRIT "br_netfilter: Argh!! br_nf_post_routing: "
-                      "bad mac.raw pointer.\n");
-               goto print_error;
-       }
-#endif
-
-       if (!nf_bridge)
-               return NF_ACCEPT;
-
-       if (!(nf_bridge->mask & (BRNF_BRIDGED | BRNF_BRIDGED_DNAT)))
+       if (!nf_bridge || !(nf_bridge->mask & BRNF_BRIDGED))
                return NF_ACCEPT;
 
        if (!realoutdev)
@@ -849,13 +783,6 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb,
        else
                return NF_ACCEPT;
 
-#ifdef CONFIG_NETFILTER_DEBUG
-       if (skb_dst(skb) == NULL) {
-               printk(KERN_INFO "br_netfilter post_routing: skb->dst == NULL\n");
-               goto print_error;
-       }
-#endif
-
        /* We assume any code from br_dev_queue_push_xmit onwards doesn't care
         * about the value of skb->pkt_type. */
        if (skb->pkt_type == PACKET_OTHERHOST) {
@@ -865,24 +792,15 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb,
 
        nf_bridge_pull_encap_header(skb);
        nf_bridge_save_header(skb);
+       if (pf == PF_INET)
+               skb->protocol = htons(ETH_P_IP);
+       else
+               skb->protocol = htons(ETH_P_IPV6);
 
        NF_HOOK(pf, NF_INET_POST_ROUTING, skb, NULL, realoutdev,
                br_nf_dev_queue_xmit);
 
        return NF_STOLEN;
-
-#ifdef CONFIG_NETFILTER_DEBUG
-print_error:
-       if (skb->dev != NULL) {
-               printk("[%s]", skb->dev->name);
-               if (realoutdev)
-                       printk("[%s]", realoutdev->name);
-       }
-       printk(" head:%p, raw:%p, data:%p\n", skb->head, skb_mac_header(skb),
-              skb->data);
-       dump_stack();
-       return NF_ACCEPT;
-#endif
 }
 
 /* IP/SABOTAGE *****************************************************/
@@ -901,10 +819,8 @@ static unsigned int ip_sabotage_in(unsigned int hook, struct sk_buff *skb,
        return NF_ACCEPT;
 }
 
-/* For br_nf_local_out we need (prio = NF_BR_PRI_FIRST), to insure that innocent
- * PF_BRIDGE/NF_BR_LOCAL_OUT functions don't get bridged traffic as input.
- * For br_nf_post_routing, we need (prio = NF_BR_PRI_LAST), because
- * ip_refrag() can return NF_STOLEN. */
+/* For br_nf_post_routing, we need (prio = NF_BR_PRI_LAST), because
+ * br_dev_queue_push_xmit is called afterwards */
 static struct nf_hook_ops br_nf_ops[] __read_mostly = {
        {
                .hook = br_nf_pre_routing,
@@ -934,13 +850,6 @@ static struct nf_hook_ops br_nf_ops[] __read_mostly = {
                .hooknum = NF_BR_FORWARD,
                .priority = NF_BR_PRI_BRNF,
        },
-       {
-               .hook = br_nf_local_out,
-               .owner = THIS_MODULE,
-               .pf = PF_BRIDGE,
-               .hooknum = NF_BR_LOCAL_OUT,
-               .priority = NF_BR_PRI_FIRST,
-       },
        {
                .hook = br_nf_post_routing,
                .owner = THIS_MODULE,
index d66cce1..217bd22 100644 (file)
@@ -50,7 +50,7 @@ static void br_send_bpdu(struct net_bridge_port *p,
 
        llc_mac_hdr_init(skb, p->dev->dev_addr, p->br->group_addr);
 
-       NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
+       NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
                dev_queue_xmit);
 }
 
index 5d11767..f7de8db 100644 (file)
@@ -36,14 +36,14 @@ ebt_802_3_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        return true;
 }
 
-static bool ebt_802_3_mt_check(const struct xt_mtchk_param *par)
+static int ebt_802_3_mt_check(const struct xt_mtchk_param *par)
 {
        const struct ebt_802_3_info *info = par->matchinfo;
 
        if (info->bitmask & ~EBT_802_3_MASK || info->invflags & ~EBT_802_3_MASK)
-               return false;
+               return -EINVAL;
 
-       return true;
+       return 0;
 }
 
 static struct xt_match ebt_802_3_mt_reg __read_mostly = {
index b595f09..20068e0 100644 (file)
@@ -7,6 +7,7 @@
  *  August, 2003
  *
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/ip.h>
 #include <linux/if_arp.h>
 #include <linux/module.h>
@@ -171,7 +172,7 @@ ebt_among_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        return true;
 }
 
-static bool ebt_among_mt_check(const struct xt_mtchk_param *par)
+static int ebt_among_mt_check(const struct xt_mtchk_param *par)
 {
        const struct ebt_among_info *info = par->matchinfo;
        const struct ebt_entry_match *em =
@@ -186,24 +187,20 @@ static bool ebt_among_mt_check(const struct xt_mtchk_param *par)
        expected_length += ebt_mac_wormhash_size(wh_src);
 
        if (em->match_size != EBT_ALIGN(expected_length)) {
-               printk(KERN_WARNING
-                      "ebtables: among: wrong size: %d "
-                      "against expected %d, rounded to %Zd\n",
-                      em->match_size, expected_length,
-                      EBT_ALIGN(expected_length));
-               return false;
+               pr_info("wrong size: %d against expected %d, rounded to %Zd\n",
+                       em->match_size, expected_length,
+                       EBT_ALIGN(expected_length));
+               return -EINVAL;
        }
        if (wh_dst && (err = ebt_mac_wormhash_check_integrity(wh_dst))) {
-               printk(KERN_WARNING
-                      "ebtables: among: dst integrity fail: %x\n", -err);
-               return false;
+               pr_info("dst integrity fail: %x\n", -err);
+               return -EINVAL;
        }
        if (wh_src && (err = ebt_mac_wormhash_check_integrity(wh_src))) {
-               printk(KERN_WARNING
-                      "ebtables: among: src integrity fail: %x\n", -err);
-               return false;
+               pr_info("src integrity fail: %x\n", -err);
+               return -EINVAL;
        }
-       return true;
+       return 0;
 }
 
 static struct xt_match ebt_among_mt_reg __read_mostly = {
index e727697..952150c 100644 (file)
@@ -100,7 +100,7 @@ ebt_arp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        return true;
 }
 
-static bool ebt_arp_mt_check(const struct xt_mtchk_param *par)
+static int ebt_arp_mt_check(const struct xt_mtchk_param *par)
 {
        const struct ebt_arp_info *info = par->matchinfo;
        const struct ebt_entry *e = par->entryinfo;
@@ -108,10 +108,10 @@ static bool ebt_arp_mt_check(const struct xt_mtchk_param *par)
        if ((e->ethproto != htons(ETH_P_ARP) &&
           e->ethproto != htons(ETH_P_RARP)) ||
           e->invflags & EBT_IPROTO)
-               return false;
+               return -EINVAL;
        if (info->bitmask & ~EBT_ARP_MASK || info->invflags & ~EBT_ARP_MASK)
-               return false;
-       return true;
+               return -EINVAL;
+       return 0;
 }
 
 static struct xt_match ebt_arp_mt_reg __read_mostly = {
index f392e9d..4581adb 100644 (file)
@@ -57,17 +57,17 @@ ebt_arpreply_tg(struct sk_buff *skb, const struct xt_target_param *par)
        return info->target;
 }
 
-static bool ebt_arpreply_tg_check(const struct xt_tgchk_param *par)
+static int ebt_arpreply_tg_check(const struct xt_tgchk_param *par)
 {
        const struct ebt_arpreply_info *info = par->targinfo;
        const struct ebt_entry *e = par->entryinfo;
 
        if (BASE_CHAIN && info->target == EBT_RETURN)
-               return false;
+               return -EINVAL;
        if (e->ethproto != htons(ETH_P_ARP) ||
            e->invflags & EBT_IPROTO)
-               return false;
-       return true;
+               return -EINVAL;
+       return 0;
 }
 
 static struct xt_target ebt_arpreply_tg_reg __read_mostly = {
index 2bb40d7..59d5b7c 100644 (file)
@@ -26,13 +26,13 @@ ebt_dnat_tg(struct sk_buff *skb, const struct xt_target_param *par)
        return info->target;
 }
 
-static bool ebt_dnat_tg_check(const struct xt_tgchk_param *par)
+static int ebt_dnat_tg_check(const struct xt_tgchk_param *par)
 {
        const struct ebt_nat_info *info = par->targinfo;
        unsigned int hook_mask;
 
        if (BASE_CHAIN && info->target == EBT_RETURN)
-               return false;
+               return -EINVAL;
 
        hook_mask = par->hook_mask & ~(1 << NF_BR_NUMHOOKS);
        if ((strcmp(par->table, "nat") != 0 ||
@@ -40,10 +40,10 @@ static bool ebt_dnat_tg_check(const struct xt_tgchk_param *par)
            (1 << NF_BR_LOCAL_OUT)))) &&
            (strcmp(par->table, "broute") != 0 ||
            hook_mask & ~(1 << NF_BR_BROUTING)))
-               return false;
+               return -EINVAL;
        if (INVALID_TARGET)
-               return false;
-       return true;
+               return -EINVAL;
+       return 0;
 }
 
 static struct xt_target ebt_dnat_tg_reg __read_mostly = {
index 5de6df6..a1c76c7 100644 (file)
@@ -77,31 +77,31 @@ ebt_ip_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        return true;
 }
 
-static bool ebt_ip_mt_check(const struct xt_mtchk_param *par)
+static int ebt_ip_mt_check(const struct xt_mtchk_param *par)
 {
        const struct ebt_ip_info *info = par->matchinfo;
        const struct ebt_entry *e = par->entryinfo;
 
        if (e->ethproto != htons(ETH_P_IP) ||
           e->invflags & EBT_IPROTO)
-               return false;
+               return -EINVAL;
        if (info->bitmask & ~EBT_IP_MASK || info->invflags & ~EBT_IP_MASK)
-               return false;
+               return -EINVAL;
        if (info->bitmask & (EBT_IP_DPORT | EBT_IP_SPORT)) {
                if (info->invflags & EBT_IP_PROTO)
-                       return false;
+                       return -EINVAL;
                if (info->protocol != IPPROTO_TCP &&
                    info->protocol != IPPROTO_UDP &&
                    info->protocol != IPPROTO_UDPLITE &&
                    info->protocol != IPPROTO_SCTP &&
                    info->protocol != IPPROTO_DCCP)
-                        return false;
+                        return -EINVAL;
        }
        if (info->bitmask & EBT_IP_DPORT && info->dport[0] > info->dport[1])
-               return false;
+               return -EINVAL;
        if (info->bitmask & EBT_IP_SPORT && info->sport[0] > info->sport[1])
-               return false;
-       return true;
+               return -EINVAL;
+       return 0;
 }
 
 static struct xt_match ebt_ip_mt_reg __read_mostly = {
index bbf2534..33f8413 100644 (file)
@@ -4,7 +4,7 @@
  *     Authors:
  *     Manohar Castelino <manohar.r.castelino@intel.com>
  *     Kuo-Lang Tseng <kuo-lang.tseng@intel.com>
- *     Jan Engelhardt <jengelh@computergmbh.de>
+ *     Jan Engelhardt <jengelh@medozas.de>
  *
  * Summary:
  * This is just a modification of the IPv4 code written by
@@ -35,8 +35,6 @@ ebt_ip6_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        struct ipv6hdr _ip6h;
        const struct tcpudphdr *pptr;
        struct tcpudphdr _ports;
-       struct in6_addr tmp_addr;
-       int i;
 
        ih6 = skb_header_pointer(skb, 0, sizeof(_ip6h), &_ip6h);
        if (ih6 == NULL)
@@ -44,18 +42,10 @@ ebt_ip6_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        if (info->bitmask & EBT_IP6_TCLASS &&
           FWINV(info->tclass != ipv6_get_dsfield(ih6), EBT_IP6_TCLASS))
                return false;
-       for (i = 0; i < 4; i++)
-               tmp_addr.in6_u.u6_addr32[i] = ih6->saddr.in6_u.u6_addr32[i] &
-                       info->smsk.in6_u.u6_addr32[i];
-       if (info->bitmask & EBT_IP6_SOURCE &&
-               FWINV((ipv6_addr_cmp(&tmp_addr, &info->saddr) != 0),
-                       EBT_IP6_SOURCE))
-               return false;
-       for (i = 0; i < 4; i++)
-               tmp_addr.in6_u.u6_addr32[i] = ih6->daddr.in6_u.u6_addr32[i] &
-                       info->dmsk.in6_u.u6_addr32[i];
-       if (info->bitmask & EBT_IP6_DEST &&
-          FWINV((ipv6_addr_cmp(&tmp_addr, &info->daddr) != 0), EBT_IP6_DEST))
+       if (FWINV(ipv6_masked_addr_cmp(&ih6->saddr, &info->smsk,
+                                      &info->saddr), EBT_IP6_SOURCE) ||
+           FWINV(ipv6_masked_addr_cmp(&ih6->daddr, &info->dmsk,
+                                      &info->daddr), EBT_IP6_DEST))
                return false;
        if (info->bitmask & EBT_IP6_PROTO) {
                uint8_t nexthdr = ih6->nexthdr;
@@ -90,30 +80,30 @@ ebt_ip6_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        return true;
 }
 
-static bool ebt_ip6_mt_check(const struct xt_mtchk_param *par)
+static int ebt_ip6_mt_check(const struct xt_mtchk_param *par)
 {
        const struct ebt_entry *e = par->entryinfo;
        struct ebt_ip6_info *info = par->matchinfo;
 
        if (e->ethproto != htons(ETH_P_IPV6) || e->invflags & EBT_IPROTO)
-               return false;
+               return -EINVAL;
        if (info->bitmask & ~EBT_IP6_MASK || info->invflags & ~EBT_IP6_MASK)
-               return false;
+               return -EINVAL;
        if (info->bitmask & (EBT_IP6_DPORT | EBT_IP6_SPORT)) {
                if (info->invflags & EBT_IP6_PROTO)
-                       return false;
+                       return -EINVAL;
                if (info->protocol != IPPROTO_TCP &&
                    info->protocol != IPPROTO_UDP &&
                    info->protocol != IPPROTO_UDPLITE &&
                    info->protocol != IPPROTO_SCTP &&
                    info->protocol != IPPROTO_DCCP)
-                       return false;
+                       return -EINVAL;
        }
        if (info->bitmask & EBT_IP6_DPORT && info->dport[0] > info->dport[1])
-               return false;
+               return -EINVAL;
        if (info->bitmask & EBT_IP6_SPORT && info->sport[0] > info->sport[1])
-               return false;
-       return true;
+               return -EINVAL;
+       return 0;
 }
 
 static struct xt_match ebt_ip6_mt_reg __read_mostly = {
@@ -139,4 +129,5 @@ static void __exit ebt_ip6_fini(void)
 module_init(ebt_ip6_init);
 module_exit(ebt_ip6_fini);
 MODULE_DESCRIPTION("Ebtables: IPv6 protocol packet match");
+MODULE_AUTHOR("Kuo-Lang Tseng <kuo-lang.tseng@intel.com>");
 MODULE_LICENSE("GPL");
index 7a81827..4b0e2e5 100644 (file)
@@ -10,6 +10,7 @@
  *  September, 2003
  *
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/spinlock.h>
@@ -64,16 +65,16 @@ user2credits(u_int32_t user)
        return (user * HZ * CREDITS_PER_JIFFY) / EBT_LIMIT_SCALE;
 }
 
-static bool ebt_limit_mt_check(const struct xt_mtchk_param *par)
+static int ebt_limit_mt_check(const struct xt_mtchk_param *par)
 {
        struct ebt_limit_info *info = par->matchinfo;
 
        /* Check for overflow. */
        if (info->burst == 0 ||
            user2credits(info->avg * info->burst) < user2credits(info->avg)) {
-               printk("Overflow in ebt_limit, try lower: %u/%u\n",
+               pr_info("overflow, try lower: %u/%u\n",
                        info->avg, info->burst);
-               return false;
+               return -EINVAL;
        }
 
        /* User avg in seconds * EBT_LIMIT_SCALE: convert to jiffies * 128. */
@@ -81,7 +82,7 @@ static bool ebt_limit_mt_check(const struct xt_mtchk_param *par)
        info->credit = user2credits(info->avg * info->burst);
        info->credit_cap = user2credits(info->avg * info->burst);
        info->cost = user2credits(info->avg);
-       return true;
+       return 0;
 }
 
 
index e873924..c460241 100644 (file)
 
 static DEFINE_SPINLOCK(ebt_log_lock);
 
-static bool ebt_log_tg_check(const struct xt_tgchk_param *par)
+static int ebt_log_tg_check(const struct xt_tgchk_param *par)
 {
        struct ebt_log_info *info = par->targinfo;
 
        if (info->bitmask & ~EBT_LOG_MASK)
-               return false;
+               return -EINVAL;
        if (info->loglevel >= 8)
-               return false;
+               return -EINVAL;
        info->prefix[EBT_LOG_PREFIX_SIZE - 1] = '\0';
-       return true;
+       return 0;
 }
 
 struct tcpudphdr
index 2b5ce53..126e536 100644 (file)
@@ -36,21 +36,21 @@ ebt_mark_tg(struct sk_buff *skb, const struct xt_target_param *par)
        return info->target | ~EBT_VERDICT_BITS;
 }
 
-static bool ebt_mark_tg_check(const struct xt_tgchk_param *par)
+static int ebt_mark_tg_check(const struct xt_tgchk_param *par)
 {
        const struct ebt_mark_t_info *info = par->targinfo;
        int tmp;
 
        tmp = info->target | ~EBT_VERDICT_BITS;
        if (BASE_CHAIN && tmp == EBT_RETURN)
-               return false;
+               return -EINVAL;
        if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0)
-               return false;
+               return -EINVAL;
        tmp = info->target & ~EBT_VERDICT_BITS;
        if (tmp != MARK_SET_VALUE && tmp != MARK_OR_VALUE &&
            tmp != MARK_AND_VALUE && tmp != MARK_XOR_VALUE)
-               return false;
-       return true;
+               return -EINVAL;
+       return 0;
 }
 #ifdef CONFIG_COMPAT
 struct compat_ebt_mark_t_info {
index 8de8c39..e4366c0 100644 (file)
@@ -22,17 +22,17 @@ ebt_mark_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        return ((skb->mark & info->mask) == info->mark) ^ info->invert;
 }
 
-static bool ebt_mark_mt_check(const struct xt_mtchk_param *par)
+static int ebt_mark_mt_check(const struct xt_mtchk_param *par)
 {
        const struct ebt_mark_m_info *info = par->matchinfo;
 
        if (info->bitmask & ~EBT_MARK_MASK)
-               return false;
+               return -EINVAL;
        if ((info->bitmask & EBT_MARK_OR) && (info->bitmask & EBT_MARK_AND))
-               return false;
+               return -EINVAL;
        if (!info->bitmask)
-               return false;
-       return true;
+               return -EINVAL;
+       return 0;
 }
 
 
index 40dbd24..22e2ad5 100644 (file)
@@ -35,14 +35,14 @@ ebt_nflog_tg(struct sk_buff *skb, const struct xt_target_param *par)
        return EBT_CONTINUE;
 }
 
-static bool ebt_nflog_tg_check(const struct xt_tgchk_param *par)
+static int ebt_nflog_tg_check(const struct xt_tgchk_param *par)
 {
        struct ebt_nflog_info *info = par->targinfo;
 
        if (info->flags & ~EBT_NFLOG_MASK)
-               return false;
+               return -EINVAL;
        info->prefix[EBT_NFLOG_PREFIX_SIZE - 1] = '\0';
-       return true;
+       return 0;
 }
 
 static struct xt_target ebt_nflog_tg_reg __read_mostly = {
index e2a07e6..f34bcc3 100644 (file)
@@ -20,14 +20,14 @@ ebt_pkttype_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        return (skb->pkt_type == info->pkt_type) ^ info->invert;
 }
 
-static bool ebt_pkttype_mt_check(const struct xt_mtchk_param *par)
+static int ebt_pkttype_mt_check(const struct xt_mtchk_param *par)
 {
        const struct ebt_pkttype_info *info = par->matchinfo;
 
        if (info->invert != 0 && info->invert != 1)
-               return false;
+               return -EINVAL;
        /* Allow any pkt_type value */
-       return true;
+       return 0;
 }
 
 static struct xt_match ebt_pkttype_mt_reg __read_mostly = {
index 9be8fbc..a6044a6 100644 (file)
@@ -32,23 +32,23 @@ ebt_redirect_tg(struct sk_buff *skb, const struct xt_target_param *par)
        return info->target;
 }
 
-static bool ebt_redirect_tg_check(const struct xt_tgchk_param *par)
+static int ebt_redirect_tg_check(const struct xt_tgchk_param *par)
 {
        const struct ebt_redirect_info *info = par->targinfo;
        unsigned int hook_mask;
 
        if (BASE_CHAIN && info->target == EBT_RETURN)
-               return false;
+               return -EINVAL;
 
        hook_mask = par->hook_mask & ~(1 << NF_BR_NUMHOOKS);
        if ((strcmp(par->table, "nat") != 0 ||
            hook_mask & ~(1 << NF_BR_PRE_ROUTING)) &&
            (strcmp(par->table, "broute") != 0 ||
            hook_mask & ~(1 << NF_BR_BROUTING)))
-               return false;
+               return -EINVAL;
        if (INVALID_TARGET)
-               return false;
-       return true;
+               return -EINVAL;
+       return 0;
 }
 
 static struct xt_target ebt_redirect_tg_reg __read_mostly = {
index 9c7b520..79caca3 100644 (file)
@@ -42,21 +42,21 @@ out:
        return info->target | ~EBT_VERDICT_BITS;
 }
 
-static bool ebt_snat_tg_check(const struct xt_tgchk_param *par)
+static int ebt_snat_tg_check(const struct xt_tgchk_param *par)
 {
        const struct ebt_nat_info *info = par->targinfo;
        int tmp;
 
        tmp = info->target | ~EBT_VERDICT_BITS;
        if (BASE_CHAIN && tmp == EBT_RETURN)
-               return false;
+               return -EINVAL;
 
        if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0)
-               return false;
+               return -EINVAL;
        tmp = info->target | EBT_VERDICT_BITS;
        if ((tmp & ~NAT_ARP_BIT) != ~NAT_ARP_BIT)
-               return false;
-       return true;
+               return -EINVAL;
+       return 0;
 }
 
 static struct xt_target ebt_snat_tg_reg __read_mostly = {
index 92a93d3..02f28fd 100644 (file)
@@ -153,7 +153,7 @@ ebt_stp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        return true;
 }
 
-static bool ebt_stp_mt_check(const struct xt_mtchk_param *par)
+static int ebt_stp_mt_check(const struct xt_mtchk_param *par)
 {
        const struct ebt_stp_info *info = par->matchinfo;
        const uint8_t bridge_ula[6] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x00};
@@ -162,13 +162,13 @@ static bool ebt_stp_mt_check(const struct xt_mtchk_param *par)
 
        if (info->bitmask & ~EBT_STP_MASK || info->invflags & ~EBT_STP_MASK ||
            !(info->bitmask & EBT_STP_MASK))
-               return false;
+               return -EINVAL;
        /* Make sure the match only receives stp frames */
        if (compare_ether_addr(e->destmac, bridge_ula) ||
            compare_ether_addr(e->destmsk, msk) || !(e->bitmask & EBT_DESTMAC))
-               return false;
+               return -EINVAL;
 
-       return true;
+       return 0;
 }
 
 static struct xt_match ebt_stp_mt_reg __read_mostly = {
index f9560f3..852f37c 100644 (file)
@@ -27,7 +27,7 @@
  *   flushed even if it is not full yet.
  *
  */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
@@ -44,9 +44,6 @@
 #include <net/sock.h>
 #include "../br_private.h"
 
-#define PRINTR(format, args...) do { if (net_ratelimit()) \
-                               printk(format , ## args); } while (0)
-
 static unsigned int nlbufsiz = NLMSG_GOODSIZE;
 module_param(nlbufsiz, uint, 0600);
 MODULE_PARM_DESC(nlbufsiz, "netlink buffer size (number of bytes) "
@@ -107,15 +104,14 @@ static struct sk_buff *ulog_alloc_skb(unsigned int size)
        n = max(size, nlbufsiz);
        skb = alloc_skb(n, GFP_ATOMIC);
        if (!skb) {
-               PRINTR(KERN_ERR "ebt_ulog: can't alloc whole buffer "
-                      "of size %ub!\n", n);
+               pr_debug("cannot alloc whole buffer of size %ub!\n", n);
                if (n > size) {
                        /* try to allocate only as much as we need for
                         * current packet */
                        skb = alloc_skb(size, GFP_ATOMIC);
                        if (!skb)
-                               PRINTR(KERN_ERR "ebt_ulog: can't even allocate "
-                                      "buffer of size %ub\n", size);
+                               pr_debug("cannot even allocate "
+                                        "buffer of size %ub\n", size);
                }
        }
 
@@ -142,8 +138,7 @@ static void ebt_ulog_packet(unsigned int hooknr, const struct sk_buff *skb,
 
        size = NLMSG_SPACE(sizeof(*pm) + copy_len);
        if (size > nlbufsiz) {
-               PRINTR("ebt_ulog: Size %Zd needed, but nlbufsiz=%d\n",
-                      size, nlbufsiz);
+               pr_debug("Size %Zd needed, but nlbufsiz=%d\n", size, nlbufsiz);
                return;
        }
 
@@ -217,8 +212,8 @@ unlock:
        return;
 
 nlmsg_failure:
-       printk(KERN_CRIT "ebt_ulog: error during NLMSG_PUT. This should "
-              "not happen, please report to author.\n");
+       pr_debug("error during NLMSG_PUT. This should "
+                "not happen, please report to author.\n");
        goto unlock;
 alloc_failure:
        goto unlock;
@@ -255,19 +250,19 @@ ebt_ulog_tg(struct sk_buff *skb, const struct xt_target_param *par)
        return EBT_CONTINUE;
 }
 
-static bool ebt_ulog_tg_check(const struct xt_tgchk_param *par)
+static int ebt_ulog_tg_check(const struct xt_tgchk_param *par)
 {
        struct ebt_ulog_info *uloginfo = par->targinfo;
 
        if (uloginfo->nlgroup > 31)
-               return false;
+               return -EINVAL;
 
        uloginfo->prefix[EBT_ULOG_PREFIX_LEN - 1] = '\0';
 
        if (uloginfo->qthreshold > EBT_ULOG_MAX_QLEN)
                uloginfo->qthreshold = EBT_ULOG_MAX_QLEN;
 
-       return true;
+       return 0;
 }
 
 static struct xt_target ebt_ulog_tg_reg __read_mostly = {
@@ -292,8 +287,8 @@ static int __init ebt_ulog_init(void)
        int i;
 
        if (nlbufsiz >= 128*1024) {
-               printk(KERN_NOTICE "ebt_ulog: Netlink buffer has to be <= 128kB,"
-                      " please try a smaller nlbufsiz parameter.\n");
+               pr_warning("Netlink buffer has to be <= 128kB,"
+                          " please try a smaller nlbufsiz parameter.\n");
                return -EINVAL;
        }
 
@@ -306,13 +301,10 @@ static int __init ebt_ulog_init(void)
        ebtulognl = netlink_kernel_create(&init_net, NETLINK_NFLOG,
                                          EBT_ULOG_MAXNLGROUPS, NULL, NULL,
                                          THIS_MODULE);
-       if (!ebtulognl) {
-               printk(KERN_WARNING KBUILD_MODNAME ": out of memory trying to "
-                      "call netlink_kernel_create\n");
+       if (!ebtulognl)
                ret = -ENOMEM;
-       } else if ((ret = xt_register_target(&ebt_ulog_tg_reg)) != 0) {
+       else if ((ret = xt_register_target(&ebt_ulog_tg_reg)) != 0)
                netlink_kernel_release(ebtulognl);
-       }
 
        if (ret == 0)
                nf_log_register(NFPROTO_BRIDGE, &ebt_ulog_logger);
index be1dd2e..bf8ae5c 100644 (file)
 #include <linux/netfilter_bridge/ebtables.h>
 #include <linux/netfilter_bridge/ebt_vlan.h>
 
-static int debug;
 #define MODULE_VERS "0.6"
 
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug, "debug=1 is turn on debug messages");
 MODULE_AUTHOR("Nick Fedchik <nick@fedchik.org.ua>");
 MODULE_DESCRIPTION("Ebtables: 802.1Q VLAN tag match");
 MODULE_LICENSE("GPL");
 
-
-#define DEBUG_MSG(args...) if (debug) printk (KERN_DEBUG "ebt_vlan: " args)
 #define GET_BITMASK(_BIT_MASK_) info->bitmask & _BIT_MASK_
 #define EXIT_ON_MISMATCH(_MATCH_,_MASK_) {if (!((info->_MATCH_ == _MATCH_)^!!(info->invflags & _MASK_))) return false; }
 
@@ -84,32 +79,31 @@ ebt_vlan_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        return true;
 }
 
-static bool ebt_vlan_mt_check(const struct xt_mtchk_param *par)
+static int ebt_vlan_mt_check(const struct xt_mtchk_param *par)
 {
        struct ebt_vlan_info *info = par->matchinfo;
        const struct ebt_entry *e = par->entryinfo;
 
        /* Is it 802.1Q frame checked? */
        if (e->ethproto != htons(ETH_P_8021Q)) {
-               DEBUG_MSG
-                   ("passed entry proto %2.4X is not 802.1Q (8100)\n",
-                    (unsigned short) ntohs(e->ethproto));
-               return false;
+               pr_debug("passed entry proto %2.4X is not 802.1Q (8100)\n",
+                        ntohs(e->ethproto));
+               return -EINVAL;
        }
 
        /* Check for bitmask range
         * True if even one bit is out of mask */
        if (info->bitmask & ~EBT_VLAN_MASK) {
-               DEBUG_MSG("bitmask %2X is out of mask (%2X)\n",
-                         info->bitmask, EBT_VLAN_MASK);
-               return false;
+               pr_debug("bitmask %2X is out of mask (%2X)\n",
+                        info->bitmask, EBT_VLAN_MASK);
+               return -EINVAL;
        }
 
        /* Check for inversion flags range */
        if (info->invflags & ~EBT_VLAN_MASK) {
-               DEBUG_MSG("inversion flags %2X is out of mask (%2X)\n",
-                         info->invflags, EBT_VLAN_MASK);
-               return false;
+               pr_debug("inversion flags %2X is out of mask (%2X)\n",
+                        info->invflags, EBT_VLAN_MASK);
+               return -EINVAL;
        }
 
        /* Reserved VLAN ID (VID) values
@@ -121,10 +115,9 @@ static bool ebt_vlan_mt_check(const struct xt_mtchk_param *par)
        if (GET_BITMASK(EBT_VLAN_ID)) {
                if (!!info->id) { /* if id!=0 => check vid range */
                        if (info->id > VLAN_GROUP_ARRAY_LEN) {
-                               DEBUG_MSG
-                                   ("id %d is out of range (1-4096)\n",
-                                    info->id);
-                               return false;
+                               pr_debug("id %d is out of range (1-4096)\n",
+                                        info->id);
+                               return -EINVAL;
                        }
                        /* Note: This is valid VLAN-tagged frame point.
                         * Any value of user_priority are acceptable,
@@ -137,9 +130,9 @@ static bool ebt_vlan_mt_check(const struct xt_mtchk_param *par)
 
        if (GET_BITMASK(EBT_VLAN_PRIO)) {
                if ((unsigned char) info->prio > 7) {
-                       DEBUG_MSG("prio %d is out of range (0-7)\n",
-                            info->prio);
-                       return false;
+                       pr_debug("prio %d is out of range (0-7)\n",
+                                info->prio);
+                       return -EINVAL;
                }
        }
        /* Check for encapsulated proto range - it is possible to be
@@ -147,14 +140,13 @@ static bool ebt_vlan_mt_check(const struct xt_mtchk_param *par)
         * if_ether.h:  ETH_ZLEN        60   -  Min. octets in frame sans FCS */
        if (GET_BITMASK(EBT_VLAN_ENCAP)) {
                if ((unsigned short) ntohs(info->encap) < ETH_ZLEN) {
-                       DEBUG_MSG
-                           ("encap frame length %d is less than minimal\n",
-                            ntohs(info->encap));
-                       return false;
+                       pr_debug("encap frame length %d is less than "
+                                "minimal\n", ntohs(info->encap));
+                       return -EINVAL;
                }
        }
 
-       return true;
+       return 0;
 }
 
 static struct xt_match ebt_vlan_mt_reg __read_mostly = {
@@ -169,9 +161,7 @@ static struct xt_match ebt_vlan_mt_reg __read_mostly = {
 
 static int __init ebt_vlan_init(void)
 {
-       DEBUG_MSG("ebtables 802.1Q extension module v"
-                 MODULE_VERS "\n");
-       DEBUG_MSG("module debug=%d\n", !!debug);
+       pr_debug("ebtables 802.1Q extension module v" MODULE_VERS "\n");
        return xt_register_match(&ebt_vlan_mt_reg);
 }
 
index f0865fd..1d8c2c0 100644 (file)
@@ -14,8 +14,7 @@
  *  as published by the Free Software Foundation; either version
  *  2 of the License, or (at your option) any later version.
  */
-
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/kmod.h>
 #include <linux/module.h>
 #include <linux/vmalloc.h>
@@ -363,12 +362,9 @@ ebt_check_match(struct ebt_entry_match *m, struct xt_mtchk_param *par,
            left - sizeof(struct ebt_entry_match) < m->match_size)
                return -EINVAL;
 
-       match = try_then_request_module(xt_find_match(NFPROTO_BRIDGE,
-               m->u.name, 0), "ebt_%s", m->u.name);
+       match = xt_request_find_match(NFPROTO_BRIDGE, m->u.name, 0);
        if (IS_ERR(match))
                return PTR_ERR(match);
-       if (match == NULL)
-               return -ENOENT;
        m->u.match = match;
 
        par->match     = match;
@@ -397,13 +393,9 @@ ebt_check_watcher(struct ebt_entry_watcher *w, struct xt_tgchk_param *par,
           left - sizeof(struct ebt_entry_watcher) < w->watcher_size)
                return -EINVAL;
 
-       watcher = try_then_request_module(
-                 xt_find_target(NFPROTO_BRIDGE, w->u.name, 0),
-                 "ebt_%s", w->u.name);
+       watcher = xt_request_find_target(NFPROTO_BRIDGE, w->u.name, 0);
        if (IS_ERR(watcher))
                return PTR_ERR(watcher);
-       if (watcher == NULL)
-               return -ENOENT;
        w->u.watcher = watcher;
 
        par->target   = watcher;
@@ -716,15 +708,10 @@ ebt_check_entry(struct ebt_entry *e, struct net *net,
        t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
        gap = e->next_offset - e->target_offset;
 
-       target = try_then_request_module(
-                xt_find_target(NFPROTO_BRIDGE, t->u.name, 0),
-                "ebt_%s", t->u.name);
+       target = xt_request_find_target(NFPROTO_BRIDGE, t->u.name, 0);
        if (IS_ERR(target)) {
                ret = PTR_ERR(target);
                goto cleanup_watchers;
-       } else if (target == NULL) {
-               ret = -ENOENT;
-               goto cleanup_watchers;
        }
 
        t->u.target = target;
@@ -2128,7 +2115,7 @@ static int size_entry_mwt(struct ebt_entry *entry, const unsigned char *base,
                        return ret;
                new_offset += ret;
                if (offsets_update && new_offset) {
-                       pr_debug("ebtables: change offset %d to %d\n",
+                       pr_debug("change offset %d to %d\n",
                                offsets_update[i], offsets[j] + new_offset);
                        offsets_update[i] = offsets[j] + new_offset;
                }
index deb723d..0363bb9 100644 (file)
@@ -266,7 +266,8 @@ static int dn_long_output(struct sk_buff *skb)
 
        skb_reset_network_header(skb);
 
-       return NF_HOOK(PF_DECnet, NF_DN_POST_ROUTING, skb, NULL, neigh->dev, dn_neigh_output_packet);
+       return NF_HOOK(NFPROTO_DECNET, NF_DN_POST_ROUTING, skb, NULL,
+                      neigh->dev, dn_neigh_output_packet);
 }
 
 static int dn_short_output(struct sk_buff *skb)
@@ -305,7 +306,8 @@ static int dn_short_output(struct sk_buff *skb)
 
        skb_reset_network_header(skb);
 
-       return NF_HOOK(PF_DECnet, NF_DN_POST_ROUTING, skb, NULL, neigh->dev, dn_neigh_output_packet);
+       return NF_HOOK(NFPROTO_DECNET, NF_DN_POST_ROUTING, skb, NULL,
+                      neigh->dev, dn_neigh_output_packet);
 }
 
 /*
@@ -347,7 +349,8 @@ static int dn_phase3_output(struct sk_buff *skb)
 
        skb_reset_network_header(skb);
 
-       return NF_HOOK(PF_DECnet, NF_DN_POST_ROUTING, skb, NULL, neigh->dev, dn_neigh_output_packet);
+       return NF_HOOK(NFPROTO_DECNET, NF_DN_POST_ROUTING, skb, NULL,
+                      neigh->dev, dn_neigh_output_packet);
 }
 
 /*
index 25a3729..b430549 100644 (file)
@@ -810,7 +810,8 @@ free_out:
 
 int dn_nsp_rx(struct sk_buff *skb)
 {
-       return NF_HOOK(PF_DECnet, NF_DN_LOCAL_IN, skb, skb->dev, NULL, dn_nsp_rx_packet);
+       return NF_HOOK(NFPROTO_DECNET, NF_DN_LOCAL_IN, skb, skb->dev, NULL,
+                      dn_nsp_rx_packet);
 }
 
 /*
index 70ebe74..a8432e3 100644 (file)
@@ -518,7 +518,8 @@ static int dn_route_rx_long(struct sk_buff *skb)
        ptr++;
        cb->hops = *ptr++; /* Visit Count */
 
-       return NF_HOOK(PF_DECnet, NF_DN_PRE_ROUTING, skb, skb->dev, NULL, dn_route_rx_packet);
+       return NF_HOOK(NFPROTO_DECNET, NF_DN_PRE_ROUTING, skb, skb->dev, NULL,
+                      dn_route_rx_packet);
 
 drop_it:
        kfree_skb(skb);
@@ -544,7 +545,8 @@ static int dn_route_rx_short(struct sk_buff *skb)
        ptr += 2;
        cb->hops = *ptr & 0x3f;
 
-       return NF_HOOK(PF_DECnet, NF_DN_PRE_ROUTING, skb, skb->dev, NULL, dn_route_rx_packet);
+       return NF_HOOK(NFPROTO_DECNET, NF_DN_PRE_ROUTING, skb, skb->dev, NULL,
+                      dn_route_rx_packet);
 
 drop_it:
        kfree_skb(skb);
@@ -646,16 +648,24 @@ int dn_route_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type
 
                switch(flags & DN_RT_CNTL_MSK) {
                        case DN_RT_PKT_HELO:
-                               return NF_HOOK(PF_DECnet, NF_DN_HELLO, skb, skb->dev, NULL, dn_route_ptp_hello);
+                               return NF_HOOK(NFPROTO_DECNET, NF_DN_HELLO,
+                                              skb, skb->dev, NULL,
+                                              dn_route_ptp_hello);
 
                        case DN_RT_PKT_L1RT:
                        case DN_RT_PKT_L2RT:
-                               return NF_HOOK(PF_DECnet, NF_DN_ROUTE, skb, skb->dev, NULL, dn_route_discard);
+                               return NF_HOOK(NFPROTO_DECNET, NF_DN_ROUTE,
+                                              skb, skb->dev, NULL,
+                                              dn_route_discard);
                        case DN_RT_PKT_ERTH:
-                               return NF_HOOK(PF_DECnet, NF_DN_HELLO, skb, skb->dev, NULL, dn_neigh_router_hello);
+                               return NF_HOOK(NFPROTO_DECNET, NF_DN_HELLO,
+                                              skb, skb->dev, NULL,
+                                              dn_neigh_router_hello);
 
                        case DN_RT_PKT_EEDH:
-                               return NF_HOOK(PF_DECnet, NF_DN_HELLO, skb, skb->dev, NULL, dn_neigh_endnode_hello);
+                               return NF_HOOK(NFPROTO_DECNET, NF_DN_HELLO,
+                                              skb, skb->dev, NULL,
+                                              dn_neigh_endnode_hello);
                }
        } else {
                if (dn->parms.state != DN_DEV_S_RU)
@@ -704,7 +714,8 @@ static int dn_output(struct sk_buff *skb)
        cb->rt_flags |= DN_RT_F_IE;
        cb->hops = 0;
 
-       return NF_HOOK(PF_DECnet, NF_DN_LOCAL_OUT, skb, NULL, dev, neigh->output);
+       return NF_HOOK(NFPROTO_DECNET, NF_DN_LOCAL_OUT, skb, NULL, dev,
+                      neigh->output);
 
 error:
        if (net_ratelimit())
@@ -753,7 +764,8 @@ static int dn_forward(struct sk_buff *skb)
        if (rt->rt_flags & RTCF_DOREDIRECT)
                cb->rt_flags |= DN_RT_F_IE;
 
-       return NF_HOOK(PF_DECnet, NF_DN_FORWARD, skb, dev, skb->dev, neigh->output);
+       return NF_HOOK(NFPROTO_DECNET, NF_DN_FORWARD, skb, dev, skb->dev,
+                      neigh->output);
 
 drop:
        kfree_skb(skb);
index af10942..56cdf68 100644 (file)
@@ -112,8 +112,8 @@ int ip_forward(struct sk_buff *skb)
 
        skb->priority = rt_tos2priority(iph->tos);
 
-       return NF_HOOK(PF_INET, NF_INET_FORWARD, skb, skb->dev, rt->u.dst.dev,
-                      ip_forward_finish);
+       return NF_HOOK(NFPROTO_IPV4, NF_INET_FORWARD, skb, skb->dev,
+                      rt->u.dst.dev, ip_forward_finish);
 
 sr_failed:
        /*
index f8ab7a3..af76de5 100644 (file)
@@ -266,7 +266,7 @@ int ip_local_deliver(struct sk_buff *skb)
                        return 0;
        }
 
-       return NF_HOOK(PF_INET, NF_INET_LOCAL_IN, skb, skb->dev, NULL,
+       return NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_IN, skb, skb->dev, NULL,
                       ip_local_deliver_finish);
 }
 
@@ -444,7 +444,7 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
        /* Must drop socket now because of tproxy. */
        skb_orphan(skb);
 
-       return NF_HOOK(PF_INET, NF_INET_PRE_ROUTING, skb, dev, NULL,
+       return NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, skb, dev, NULL,
                       ip_rcv_finish);
 
 inhdr_error:
index 512af81..b0b2e30 100644 (file)
@@ -96,8 +96,8 @@ int __ip_local_out(struct sk_buff *skb)
 
        iph->tot_len = htons(skb->len);
        ip_send_check(iph);
-       return nf_hook(PF_INET, NF_INET_LOCAL_OUT, skb, NULL, skb_dst(skb)->dev,
-                      dst_output);
+       return nf_hook(NFPROTO_IPV4, NF_INET_LOCAL_OUT, skb, NULL,
+                      skb_dst(skb)->dev, dst_output);
 }
 
 int ip_local_out(struct sk_buff *skb)
@@ -272,8 +272,8 @@ int ip_mc_output(struct sk_buff *skb)
                   ) {
                        struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC);
                        if (newskb)
-                               NF_HOOK(PF_INET, NF_INET_POST_ROUTING, newskb,
-                                       NULL, newskb->dev,
+                               NF_HOOK(NFPROTO_IPV4, NF_INET_POST_ROUTING,
+                                       newskb, NULL, newskb->dev,
                                        ip_dev_loopback_xmit);
                }
 
@@ -288,12 +288,12 @@ int ip_mc_output(struct sk_buff *skb)
        if (rt->rt_flags&RTCF_BROADCAST) {
                struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC);
                if (newskb)
-                       NF_HOOK(PF_INET, NF_INET_POST_ROUTING, newskb, NULL,
-                               newskb->dev, ip_dev_loopback_xmit);
+                       NF_HOOK(NFPROTO_IPV4, NF_INET_POST_ROUTING, newskb,
+                               NULL, newskb->dev, ip_dev_loopback_xmit);
        }
 
-       return NF_HOOK_COND(PF_INET, NF_INET_POST_ROUTING, skb, NULL, skb->dev,
-                           ip_finish_output,
+       return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, skb, NULL,
+                           skb->dev, ip_finish_output,
                            !(IPCB(skb)->flags & IPSKB_REROUTED));
 }
 
@@ -306,7 +306,7 @@ int ip_output(struct sk_buff *skb)
        skb->dev = dev;
        skb->protocol = htons(ETH_P_IP);
 
-       return NF_HOOK_COND(PF_INET, NF_INET_POST_ROUTING, skb, NULL, dev,
+       return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, skb, NULL, dev,
                            ip_finish_output,
                            !(IPCB(skb)->flags & IPSKB_REROUTED));
 }
index 7d8a2bc..1aa498d 100644 (file)
@@ -1599,7 +1599,7 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt,
         * not mrouter) cannot join to more than one interface - it will
         * result in receiving multiple packets.
         */
-       NF_HOOK(PF_INET, NF_INET_FORWARD, skb, skb->dev, dev,
+       NF_HOOK(NFPROTO_IPV4, NF_INET_FORWARD, skb, skb->dev, dev,
                ipmr_forward_finish);
        return;
 
index f07d77f..07a6990 100644 (file)
@@ -523,13 +523,11 @@ find_check_entry(struct arpt_entry *e, const char *name, unsigned int size)
                return ret;
 
        t = arpt_get_target(e);
-       target = try_then_request_module(xt_find_target(NFPROTO_ARP,
-                                                       t->u.user.name,
-                                                       t->u.user.revision),
-                                        "arpt_%s", t->u.user.name);
-       if (IS_ERR(target) || !target) {
+       target = xt_request_find_target(NFPROTO_ARP, t->u.user.name,
+                                       t->u.user.revision);
+       if (IS_ERR(target)) {
                duprintf("find_check_entry: `%s' not found\n", t->u.user.name);
-               ret = target ? PTR_ERR(target) : -ENOENT;
+               ret = PTR_ERR(target);
                goto out;
        }
        t->u.kernel.target = target;
@@ -651,6 +649,9 @@ static int translate_table(struct xt_table_info *newinfo, void *entry0,
                if (ret != 0)
                        break;
                ++i;
+               if (strcmp(arpt_get_target(iter)->u.user.name,
+                   XT_ERROR_TARGET) == 0)
+                       ++newinfo->stacksize;
        }
        duprintf("translate_table: ARPT_ENTRY_ITERATE gives %d\n", ret);
        if (ret != 0)
@@ -1252,14 +1253,12 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
        entry_offset = (void *)e - (void *)base;
 
        t = compat_arpt_get_target(e);
-       target = try_then_request_module(xt_find_target(NFPROTO_ARP,
-                                                       t->u.user.name,
-                                                       t->u.user.revision),
-                                        "arpt_%s", t->u.user.name);
-       if (IS_ERR(target) || !target) {
+       target = xt_request_find_target(NFPROTO_ARP, t->u.user.name,
+                                       t->u.user.revision);
+       if (IS_ERR(target)) {
                duprintf("check_compat_entry_size_and_hooks: `%s' not found\n",
                         t->u.user.name);
-               ret = target ? PTR_ERR(target) : -ENOENT;
+               ret = PTR_ERR(target);
                goto out;
        }
        t->u.kernel.target = target;
@@ -1778,8 +1777,7 @@ struct xt_table *arpt_register_table(struct net *net,
 {
        int ret;
        struct xt_table_info *newinfo;
-       struct xt_table_info bootstrap
-               = { 0, 0, 0, { 0 }, { 0 }, { } };
+       struct xt_table_info bootstrap = {0};
        void *loc_cpu_entry;
        struct xt_table *new_table;
 
index b0d5b1d..4b51a02 100644 (file)
@@ -54,7 +54,7 @@ target(struct sk_buff *skb, const struct xt_target_param *par)
        return mangle->target;
 }
 
-static bool checkentry(const struct xt_tgchk_param *par)
+static int checkentry(const struct xt_tgchk_param *par)
 {
        const struct arpt_mangle *mangle = par->targinfo;
 
index e278704..c838238 100644 (file)
@@ -161,8 +161,7 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp)
                break;
 
        case IPQ_COPY_PACKET:
-               if ((entry->skb->ip_summed == CHECKSUM_PARTIAL ||
-                    entry->skb->ip_summed == CHECKSUM_COMPLETE) &&
+               if (entry->skb->ip_summed == CHECKSUM_PARTIAL &&
                    (*errp = skb_checksum_help(entry->skb))) {
                        read_unlock_bh(&queue_lock);
                        return NULL;
index b29c66d..bb5e0d9 100644 (file)
@@ -39,13 +39,13 @@ MODULE_DESCRIPTION("IPv4 packet filter");
 /*#define DEBUG_IP_FIREWALL_USER*/
 
 #ifdef DEBUG_IP_FIREWALL
-#define dprintf(format, args...)  printk(format , ## args)
+#define dprintf(format, args...) pr_info(format , ## args)
 #else
 #define dprintf(format, args...)
 #endif
 
 #ifdef DEBUG_IP_FIREWALL_USER
-#define duprintf(format, args...) printk(format , ## args)
+#define duprintf(format, args...) pr_info(format , ## args)
 #else
 #define duprintf(format, args...)
 #endif
@@ -168,8 +168,7 @@ static unsigned int
 ipt_error(struct sk_buff *skb, const struct xt_target_param *par)
 {
        if (net_ratelimit())
-               printk("ip_tables: error: `%s'\n",
-                      (const char *)par->targinfo);
+               pr_info("error: `%s'\n", (const char *)par->targinfo);
 
        return NF_DROP;
 }
@@ -322,8 +321,6 @@ ipt_do_table(struct sk_buff *skb,
             const struct net_device *out,
             struct xt_table *table)
 {
-#define tb_comefrom ((struct ipt_entry *)table_base)->comefrom
-
        static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
        const struct iphdr *ip;
        bool hotdrop = false;
@@ -331,7 +328,8 @@ ipt_do_table(struct sk_buff *skb,
        unsigned int verdict = NF_DROP;
        const char *indev, *outdev;
        const void *table_base;
-       struct ipt_entry *e, *back;
+       struct ipt_entry *e, **jumpstack;
+       unsigned int *stackptr, origptr, cpu;
        const struct xt_table_info *private;
        struct xt_match_param mtpar;
        struct xt_target_param tgpar;
@@ -357,19 +355,23 @@ ipt_do_table(struct sk_buff *skb,
        IP_NF_ASSERT(table->valid_hooks & (1 << hook));
        xt_info_rdlock_bh();
        private = table->private;
-       table_base = private->entries[smp_processor_id()];
+       cpu        = smp_processor_id();
+       table_base = private->entries[cpu];
+       jumpstack  = (struct ipt_entry **)private->jumpstack[cpu];
+       stackptr   = &private->stackptr[cpu];
+       origptr    = *stackptr;
 
        e = get_entry(table_base, private->hook_entry[hook]);
 
-       /* For return from builtin chain */
-       back = get_entry(table_base, private->underflow[hook]);
+       pr_devel("Entering %s(hook %u); sp at %u (UF %p)\n",
+                table->name, hook, origptr,
+                get_entry(table_base, private->underflow[hook]));
 
        do {
                const struct ipt_entry_target *t;
                const struct xt_entry_match *ematch;
 
                IP_NF_ASSERT(e);
-               IP_NF_ASSERT(back);
                if (!ip_packet_match(ip, indev, outdev,
                    &e->ip, mtpar.fragoff)) {
  no_match:
@@ -404,41 +406,39 @@ ipt_do_table(struct sk_buff *skb,
                                        verdict = (unsigned)(-v) - 1;
                                        break;
                                }
-                               e = back;
-                               back = get_entry(table_base, back->comefrom);
+                               if (*stackptr == 0) {
+                                       e = get_entry(table_base,
+                                           private->underflow[hook]);
+                                       pr_devel("Underflow (this is normal) "
+                                                "to %p\n", e);
+                               } else {
+                                       e = jumpstack[--*stackptr];
+                                       pr_devel("Pulled %p out from pos %u\n",
+                                                e, *stackptr);
+                                       e = ipt_next_entry(e);
+                               }
                                continue;
                        }
                        if (table_base + v != ipt_next_entry(e) &&
                            !(e->ip.flags & IPT_F_GOTO)) {
-                               /* Save old back ptr in next entry */
-                               struct ipt_entry *next = ipt_next_entry(e);
-                               next->comefrom = (void *)back - table_base;
-                               /* set back pointer to next entry */
-                               back = next;
+                               if (*stackptr >= private->stacksize) {
+                                       verdict = NF_DROP;
+                                       break;
+                               }
+                               jumpstack[(*stackptr)++] = e;
+                               pr_devel("Pushed %p into pos %u\n",
+                                        e, *stackptr - 1);
                        }
 
                        e = get_entry(table_base, v);
                        continue;
                }
 
-               /* Targets which reenter must return
-                  abs. verdicts */
                tgpar.target   = t->u.kernel.target;
                tgpar.targinfo = t->data;
 
 
-#ifdef CONFIG_NETFILTER_DEBUG
-               tb_comefrom = 0xeeeeeeec;
-#endif
                verdict = t->u.kernel.target->target(skb, &tgpar);
-#ifdef CONFIG_NETFILTER_DEBUG
-               if (tb_comefrom != 0xeeeeeeec && verdict == IPT_CONTINUE) {
-                       printk("Target %s reentered!\n",
-                              t->u.kernel.target->name);
-                       verdict = NF_DROP;
-               }
-               tb_comefrom = 0x57acc001;
-#endif
                /* Target might have changed stuff. */
                ip = ip_hdr(skb);
                if (verdict == IPT_CONTINUE)
@@ -448,7 +448,9 @@ ipt_do_table(struct sk_buff *skb,
                        break;
        } while (!hotdrop);
        xt_info_rdunlock_bh();
-
+       pr_devel("Exiting %s; resetting sp from %u to %u\n",
+                __func__, *stackptr, origptr);
+       *stackptr = origptr;
 #ifdef DEBUG_ALLOW_ALL
        return NF_ACCEPT;
 #else
@@ -456,8 +458,6 @@ ipt_do_table(struct sk_buff *skb,
                return NF_DROP;
        else return verdict;
 #endif
-
-#undef tb_comefrom
 }
 
 /* Figures out from what hook each rule can be called: returns 0 if
@@ -591,7 +591,7 @@ check_entry(const struct ipt_entry *e, const char *name)
        const struct ipt_entry_target *t;
 
        if (!ip_checkentry(&e->ip)) {
-               duprintf("ip_tables: ip check failed %p %s.\n", e, name);
+               duprintf("ip check failed %p %s.\n", e, name);
                return -EINVAL;
        }
 
@@ -618,8 +618,7 @@ check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par)
        ret = xt_check_match(par, m->u.match_size - sizeof(*m),
              ip->proto, ip->invflags & IPT_INV_PROTO);
        if (ret < 0) {
-               duprintf("ip_tables: check failed for `%s'.\n",
-                        par.match->name);
+               duprintf("check failed for `%s'.\n", par.match->name);
                return ret;
        }
        return 0;
@@ -631,12 +630,11 @@ find_check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par)
        struct xt_match *match;
        int ret;
 
-       match = try_then_request_module(xt_find_match(AF_INET, m->u.user.name,
-                                                     m->u.user.revision),
-                                       "ipt_%s", m->u.user.name);
-       if (IS_ERR(match) || !match) {
+       match = xt_request_find_match(NFPROTO_IPV4, m->u.user.name,
+                                     m->u.user.revision);
+       if (IS_ERR(match)) {
                duprintf("find_check_match: `%s' not found\n", m->u.user.name);
-               return match ? PTR_ERR(match) : -ENOENT;
+               return PTR_ERR(match);
        }
        m->u.kernel.match = match;
 
@@ -667,7 +665,7 @@ static int check_target(struct ipt_entry *e, struct net *net, const char *name)
        ret = xt_check_target(&par, t->u.target_size - sizeof(*t),
              e->ip.proto, e->ip.invflags & IPT_INV_PROTO);
        if (ret < 0) {
-               duprintf("ip_tables: check failed for `%s'.\n",
+               duprintf("check failed for `%s'.\n",
                         t->u.kernel.target->name);
                return ret;
        }
@@ -703,13 +701,11 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name,
        }
 
        t = ipt_get_target(e);
-       target = try_then_request_module(xt_find_target(AF_INET,
-                                                       t->u.user.name,
-                                                       t->u.user.revision),
-                                        "ipt_%s", t->u.user.name);
-       if (IS_ERR(target) || !target) {
+       target = xt_request_find_target(NFPROTO_IPV4, t->u.user.name,
+                                       t->u.user.revision);
+       if (IS_ERR(target)) {
                duprintf("find_check_entry: `%s' not found\n", t->u.user.name);
-               ret = target ? PTR_ERR(target) : -ENOENT;
+               ret = PTR_ERR(target);
                goto cleanup_matches;
        }
        t->u.kernel.target = target;
@@ -843,6 +839,9 @@ translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0,
                if (ret != 0)
                        return ret;
                ++i;
+               if (strcmp(ipt_get_target(iter)->u.user.name,
+                   XT_ERROR_TARGET) == 0)
+                       ++newinfo->stacksize;
        }
 
        if (i != repl->num_entries) {
@@ -1311,7 +1310,7 @@ do_replace(struct net *net, const void __user *user, unsigned int len)
        if (ret != 0)
                goto free_newinfo;
 
-       duprintf("ip_tables: Translated table\n");
+       duprintf("Translated table\n");
 
        ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo,
                           tmp.num_counters, tmp.counters);
@@ -1476,13 +1475,12 @@ compat_find_calc_match(struct ipt_entry_match *m,
 {
        struct xt_match *match;
 
-       match = try_then_request_module(xt_find_match(AF_INET, m->u.user.name,
-                                                     m->u.user.revision),
-                                       "ipt_%s", m->u.user.name);
-       if (IS_ERR(match) || !match) {
+       match = xt_request_find_match(NFPROTO_IPV4, m->u.user.name,
+                                     m->u.user.revision);
+       if (IS_ERR(match)) {
                duprintf("compat_check_calc_match: `%s' not found\n",
                         m->u.user.name);
-               return match ? PTR_ERR(match) : -ENOENT;
+               return PTR_ERR(match);
        }
        m->u.kernel.match = match;
        *size += xt_compat_match_offset(match);
@@ -1549,14 +1547,12 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
        }
 
        t = compat_ipt_get_target(e);
-       target = try_then_request_module(xt_find_target(AF_INET,
-                                                       t->u.user.name,
-                                                       t->u.user.revision),
-                                        "ipt_%s", t->u.user.name);
-       if (IS_ERR(target) || !target) {
+       target = xt_request_find_target(NFPROTO_IPV4, t->u.user.name,
+                                       t->u.user.revision);
+       if (IS_ERR(target)) {
                duprintf("check_compat_entry_size_and_hooks: `%s' not found\n",
                         t->u.user.name);
-               ret = target ? PTR_ERR(target) : -ENOENT;
+               ret = PTR_ERR(target);
                goto release_matches;
        }
        t->u.kernel.target = target;
@@ -2094,8 +2090,7 @@ struct xt_table *ipt_register_table(struct net *net,
 {
        int ret;
        struct xt_table_info *newinfo;
-       struct xt_table_info bootstrap
-               = { 0, 0, 0, { 0 }, { 0 }, { } };
+       struct xt_table_info bootstrap = {0};
        void *loc_cpu_entry;
        struct xt_table *new_table;
 
@@ -2184,12 +2179,12 @@ icmp_match(const struct sk_buff *skb, const struct xt_match_param *par)
                                    !!(icmpinfo->invflags&IPT_ICMP_INV));
 }
 
-static bool icmp_checkentry(const struct xt_mtchk_param *par)
+static int icmp_checkentry(const struct xt_mtchk_param *par)
 {
        const struct ipt_icmp *icmpinfo = par->matchinfo;
 
        /* Must specify no unknown invflags */
-       return !(icmpinfo->invflags & ~IPT_ICMP_INV);
+       return (icmpinfo->invflags & ~IPT_ICMP_INV) ? -EINVAL : 0;
 }
 
 /* The built-in targets: standard (NULL) and error. */
@@ -2276,7 +2271,7 @@ static int __init ip_tables_init(void)
        if (ret < 0)
                goto err5;
 
-       printk(KERN_INFO "ip_tables: (C) 2000-2006 Netfilter Core Team\n");
+       pr_info("(C) 2000-2006 Netfilter Core Team\n");
        return 0;
 
 err5:
index a992dc8..8815d45 100644 (file)
@@ -9,6 +9,7 @@
  * published by the Free Software Foundation.
  *
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
 #include <linux/proc_fs.h>
 #include <linux/jhash.h>
@@ -239,8 +240,7 @@ clusterip_hashfn(const struct sk_buff *skb,
                break;
        default:
                if (net_ratelimit())
-                       printk(KERN_NOTICE "CLUSTERIP: unknown protocol `%u'\n",
-                               iph->protocol);
+                       pr_info("unknown protocol %u\n", iph->protocol);
                sport = dport = 0;
        }
 
@@ -262,7 +262,7 @@ clusterip_hashfn(const struct sk_buff *skb,
                hashval = 0;
                /* This cannot happen, unless the check function wasn't called
                 * at rule load time */
-               printk("CLUSTERIP: unknown mode `%u'\n", config->hash_mode);
+               pr_info("unknown mode %u\n", config->hash_mode);
                BUG();
                break;
        }
@@ -295,7 +295,7 @@ clusterip_tg(struct sk_buff *skb, const struct xt_target_param *par)
 
        ct = nf_ct_get(skb, &ctinfo);
        if (ct == NULL) {
-               printk(KERN_ERR "CLUSTERIP: no conntrack!\n");
+               pr_info("no conntrack!\n");
                        /* FIXME: need to drop invalid ones, since replies
                         * to outgoing connections of other nodes will be
                         * marked as INVALID */
@@ -348,25 +348,24 @@ clusterip_tg(struct sk_buff *skb, const struct xt_target_param *par)
        return XT_CONTINUE;
 }
 
-static bool clusterip_tg_check(const struct xt_tgchk_param *par)
+static int clusterip_tg_check(const struct xt_tgchk_param *par)
 {
        struct ipt_clusterip_tgt_info *cipinfo = par->targinfo;
        const struct ipt_entry *e = par->entryinfo;
-
        struct clusterip_config *config;
+       int ret;
 
        if (cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP &&
            cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP_SPT &&
            cipinfo->hash_mode != CLUSTERIP_HASHMODE_SIP_SPT_DPT) {
-               printk(KERN_WARNING "CLUSTERIP: unknown mode `%u'\n",
-                       cipinfo->hash_mode);
-               return false;
+               pr_info("unknown mode %u\n", cipinfo->hash_mode);
+               return -EINVAL;
 
        }
        if (e->ip.dmsk.s_addr != htonl(0xffffffff) ||
            e->ip.dst.s_addr == 0) {
-               printk(KERN_ERR "CLUSTERIP: Please specify destination IP\n");
-               return false;
+               pr_info("Please specify destination IP\n");
+               return -EINVAL;
        }
 
        /* FIXME: further sanity checks */
@@ -374,41 +373,41 @@ static bool clusterip_tg_check(const struct xt_tgchk_param *par)
        config = clusterip_config_find_get(e->ip.dst.s_addr, 1);
        if (!config) {
                if (!(cipinfo->flags & CLUSTERIP_FLAG_NEW)) {
-                       printk(KERN_WARNING "CLUSTERIP: no config found for %pI4, need 'new'\n", &e->ip.dst.s_addr);
-                       return false;
+                       pr_info("no config found for %pI4, need 'new'\n",
+                               &e->ip.dst.s_addr);
+                       return -EINVAL;
                } else {
                        struct net_device *dev;
 
                        if (e->ip.iniface[0] == '\0') {
-                               printk(KERN_WARNING "CLUSTERIP: Please specify an interface name\n");
-                               return false;
+                               pr_info("Please specify an interface name\n");
+                               return -EINVAL;
                        }
 
                        dev = dev_get_by_name(&init_net, e->ip.iniface);
                        if (!dev) {
-                               printk(KERN_WARNING "CLUSTERIP: no such interface %s\n", e->ip.iniface);
-                               return false;
+                               pr_info("no such interface %s\n",
+                                       e->ip.iniface);
+                               return -ENOENT;
                        }
 
                        config = clusterip_config_init(cipinfo,
                                                        e->ip.dst.s_addr, dev);
                        if (!config) {
-                               printk(KERN_WARNING "CLUSTERIP: cannot allocate config\n");
+                               pr_info("cannot allocate config\n");
                                dev_put(dev);
-                               return false;
+                               return -ENOMEM;
                        }
                        dev_mc_add(config->dev, config->clustermac);
                }
        }
        cipinfo->config = config;
 
-       if (nf_ct_l3proto_try_module_get(par->target->family) < 0) {
-               printk(KERN_WARNING "can't load conntrack support for "
-                                   "proto=%u\n", par->target->family);
-               return false;
-       }
-
-       return true;
+       ret = nf_ct_l3proto_try_module_get(par->family);
+       if (ret < 0)
+               pr_info("cannot load conntrack support for proto=%u\n",
+                       par->family);
+       return ret;
 }
 
 /* drop reference count of cluster config when rule is deleted */
@@ -422,7 +421,7 @@ static void clusterip_tg_destroy(const struct xt_tgdtor_param *par)
 
        clusterip_config_put(cipinfo->config);
 
-       nf_ct_l3proto_module_put(par->target->family);
+       nf_ct_l3proto_module_put(par->family);
 }
 
 #ifdef CONFIG_COMPAT
@@ -479,8 +478,8 @@ static void arp_print(struct arp_payload *payload)
        }
        hbuffer[--k]='\0';
 
-       printk("src %pI4@%s, dst %pI4\n",
-               &payload->src_ip, hbuffer, &payload->dst_ip);
+       pr_debug("src %pI4@%s, dst %pI4\n",
+                &payload->src_ip, hbuffer, &payload->dst_ip);
 }
 #endif
 
@@ -519,7 +518,7 @@ arp_mangle(unsigned int hook,
         * this wouldn't work, since we didn't subscribe the mcast group on
         * other interfaces */
        if (c->dev != out) {
-               pr_debug("CLUSTERIP: not mangling arp reply on different "
+               pr_debug("not mangling arp reply on different "
                         "interface: cip'%s'-skb'%s'\n",
                         c->dev->name, out->name);
                clusterip_config_put(c);
@@ -530,7 +529,7 @@ arp_mangle(unsigned int hook,
        memcpy(payload->src_hw, c->clustermac, arp->ar_hln);
 
 #ifdef DEBUG
-       pr_debug(KERN_DEBUG "CLUSTERIP mangled arp reply: ");
+       pr_debug("mangled arp reply: ");
        arp_print(payload);
 #endif
 
@@ -601,7 +600,8 @@ static void *clusterip_seq_next(struct seq_file *s, void *v, loff_t *pos)
 
 static void clusterip_seq_stop(struct seq_file *s, void *v)
 {
-       kfree(v);
+       if (!IS_ERR(v))
+               kfree(v);
 }
 
 static int clusterip_seq_show(struct seq_file *s, void *v)
@@ -706,13 +706,13 @@ static int __init clusterip_tg_init(void)
 #ifdef CONFIG_PROC_FS
        clusterip_procdir = proc_mkdir("ipt_CLUSTERIP", init_net.proc_net);
        if (!clusterip_procdir) {
-               printk(KERN_ERR "CLUSTERIP: Unable to proc dir entry\n");
+               pr_err("Unable to proc dir entry\n");
                ret = -ENOMEM;
                goto cleanup_hook;
        }
 #endif /* CONFIG_PROC_FS */
 
-       printk(KERN_NOTICE "ClusterIP Version %s loaded successfully\n",
+       pr_info("ClusterIP Version %s loaded successfully\n",
                CLUSTERIP_VERSION);
        return 0;
 
@@ -727,8 +727,7 @@ cleanup_target:
 
 static void __exit clusterip_tg_exit(void)
 {
-       printk(KERN_NOTICE "ClusterIP Version %s unloading\n",
-               CLUSTERIP_VERSION);
+       pr_info("ClusterIP Version %s unloading\n", CLUSTERIP_VERSION);
 #ifdef CONFIG_PROC_FS
        remove_proc_entry(clusterip_procdir->name, clusterip_procdir->parent);
 #endif
index ea5cea2..563049f 100644 (file)
@@ -6,7 +6,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
 */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/in.h>
 #include <linux/module.h>
 #include <linux/skbuff.h>
@@ -93,28 +93,25 @@ ecn_tg(struct sk_buff *skb, const struct xt_target_param *par)
        return XT_CONTINUE;
 }
 
-static bool ecn_tg_check(const struct xt_tgchk_param *par)
+static int ecn_tg_check(const struct xt_tgchk_param *par)
 {
        const struct ipt_ECN_info *einfo = par->targinfo;
        const struct ipt_entry *e = par->entryinfo;
 
        if (einfo->operation & IPT_ECN_OP_MASK) {
-               printk(KERN_WARNING "ECN: unsupported ECN operation %x\n",
-                       einfo->operation);
-               return false;
+               pr_info("unsupported ECN operation %x\n", einfo->operation);
+               return -EINVAL;
        }
        if (einfo->ip_ect & ~IPT_ECN_IP_MASK) {
-               printk(KERN_WARNING "ECN: new ECT codepoint %x out of mask\n",
-                       einfo->ip_ect);
-               return false;
+               pr_info("new ECT codepoint %x out of mask\n", einfo->ip_ect);
+               return -EINVAL;
        }
        if ((einfo->operation & (IPT_ECN_OP_SET_ECE|IPT_ECN_OP_SET_CWR)) &&
            (e->ip.proto != IPPROTO_TCP || (e->ip.invflags & XT_INV_PROTO))) {
-               printk(KERN_WARNING "ECN: cannot use TCP operations on a "
-                      "non-tcp rule\n");
-               return false;
+               pr_info("cannot use TCP operations on a non-tcp rule\n");
+               return -EINVAL;
        }
-       return true;
+       return 0;
 }
 
 static struct xt_target ecn_tg_reg __read_mostly = {
index ee128ef..3bd35f3 100644 (file)
@@ -9,7 +9,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <linux/skbuff.h>
@@ -367,7 +367,7 @@ static struct nf_loginfo default_loginfo = {
        .type   = NF_LOG_TYPE_LOG,
        .u = {
                .log = {
-                       .level    = 0,
+                       .level    = 5,
                        .logflags = NF_LOG_MASK,
                },
        },
@@ -439,20 +439,19 @@ log_tg(struct sk_buff *skb, const struct xt_target_param *par)
        return XT_CONTINUE;
 }
 
-static bool log_tg_check(const struct xt_tgchk_param *par)
+static int log_tg_check(const struct xt_tgchk_param *par)
 {
        const struct ipt_log_info *loginfo = par->targinfo;
 
        if (loginfo->level >= 8) {
-               pr_debug("LOG: level %u >= 8\n", loginfo->level);
-               return false;
+               pr_debug("level %u >= 8\n", loginfo->level);
+               return -EINVAL;
        }
        if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') {
-               pr_debug("LOG: prefix term %i\n",
-                        loginfo->prefix[sizeof(loginfo->prefix)-1]);
-               return false;
+               pr_debug("prefix is not null-terminated\n");
+               return -EINVAL;
        }
-       return true;
+       return 0;
 }
 
 static struct xt_target log_tg_reg __read_mostly = {
index 650b540..02b1bc4 100644 (file)
@@ -8,7 +8,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/types.h>
 #include <linux/inetdevice.h>
 #include <linux/ip.h>
@@ -28,19 +28,19 @@ MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
 MODULE_DESCRIPTION("Xtables: automatic-address SNAT");
 
 /* FIXME: Multiple targets. --RR */
-static bool masquerade_tg_check(const struct xt_tgchk_param *par)
+static int masquerade_tg_check(const struct xt_tgchk_param *par)
 {
        const struct nf_nat_multi_range_compat *mr = par->targinfo;
 
        if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) {
-               pr_debug("masquerade_check: bad MAP_IPS.\n");
-               return false;
+               pr_debug("bad MAP_IPS.\n");
+               return -EINVAL;
        }
        if (mr->rangesize != 1) {
-               pr_debug("masquerade_check: bad rangesize %u\n", mr->rangesize);
-               return false;
+               pr_debug("bad rangesize %u\n", mr->rangesize);
+               return -EINVAL;
        }
-       return true;
+       return 0;
 }
 
 static unsigned int
@@ -72,7 +72,7 @@ masquerade_tg(struct sk_buff *skb, const struct xt_target_param *par)
        rt = skb_rtable(skb);
        newsrc = inet_select_addr(par->out, rt->rt_gateway, RT_SCOPE_UNIVERSE);
        if (!newsrc) {
-               printk("MASQUERADE: %s ate my IP address\n", par->out->name);
+               pr_info("%s ate my IP address\n", par->out->name);
                return NF_DROP;
        }
 
index 7c29582..708c7f8 100644 (file)
@@ -9,7 +9,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/ip.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
@@ -22,19 +22,19 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Svenning Soerensen <svenning@post5.tele.dk>");
 MODULE_DESCRIPTION("Xtables: 1:1 NAT mapping of IPv4 subnets");
 
-static bool netmap_tg_check(const struct xt_tgchk_param *par)
+static int netmap_tg_check(const struct xt_tgchk_param *par)
 {
        const struct nf_nat_multi_range_compat *mr = par->targinfo;
 
        if (!(mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)) {
-               pr_debug("NETMAP:check: bad MAP_IPS.\n");
-               return false;
+               pr_debug("bad MAP_IPS.\n");
+               return -EINVAL;
        }
        if (mr->rangesize != 1) {
-               pr_debug("NETMAP:check: bad rangesize %u.\n", mr->rangesize);
-               return false;
+               pr_debug("bad rangesize %u.\n", mr->rangesize);
+               return -EINVAL;
        }
-       return true;
+       return 0;
 }
 
 static unsigned int
index 698e5e7..3cf1019 100644 (file)
@@ -6,7 +6,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/types.h>
 #include <linux/ip.h>
 #include <linux/timer.h>
@@ -26,19 +26,19 @@ MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
 MODULE_DESCRIPTION("Xtables: Connection redirection to localhost");
 
 /* FIXME: Take multiple ranges --RR */
-static bool redirect_tg_check(const struct xt_tgchk_param *par)
+static int redirect_tg_check(const struct xt_tgchk_param *par)
 {
        const struct nf_nat_multi_range_compat *mr = par->targinfo;
 
        if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) {
-               pr_debug("redirect_check: bad MAP_IPS.\n");
-               return false;
+               pr_debug("bad MAP_IPS.\n");
+               return -EINVAL;
        }
        if (mr->rangesize != 1) {
-               pr_debug("redirect_check: bad rangesize %u.\n", mr->rangesize);
-               return false;
+               pr_debug("bad rangesize %u.\n", mr->rangesize);
+               return -EINVAL;
        }
-       return true;
+       return 0;
 }
 
 static unsigned int
index a0e8bcf..a86135a 100644 (file)
@@ -9,7 +9,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/slab.h>
@@ -140,9 +140,6 @@ reject_tg(struct sk_buff *skb, const struct xt_target_param *par)
 {
        const struct ipt_reject_info *reject = par->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 */
        switch (reject->with) {
        case IPT_ICMP_NET_UNREACHABLE:
                send_unreach(skb, ICMP_NET_UNREACH);
@@ -175,23 +172,23 @@ reject_tg(struct sk_buff *skb, const struct xt_target_param *par)
        return NF_DROP;
 }
 
-static bool reject_tg_check(const struct xt_tgchk_param *par)
+static int reject_tg_check(const struct xt_tgchk_param *par)
 {
        const struct ipt_reject_info *rejinfo = par->targinfo;
        const struct ipt_entry *e = par->entryinfo;
 
        if (rejinfo->with == IPT_ICMP_ECHOREPLY) {
-               printk("ipt_REJECT: ECHOREPLY no longer supported.\n");
-               return false;
+               pr_info("ECHOREPLY no longer supported.\n");
+               return -EINVAL;
        } else if (rejinfo->with == IPT_TCP_RESET) {
                /* Must specify that it's a TCP packet */
                if (e->ip.proto != IPPROTO_TCP ||
                    (e->ip.invflags & XT_INV_PROTO)) {
-                       printk("ipt_REJECT: TCP_RESET invalid for non-tcp\n");
-                       return false;
+                       pr_info("TCP_RESET invalid for non-tcp\n");
+                       return -EINVAL;
                }
        }
-       return true;
+       return 0;
 }
 
 static struct xt_target reject_tg_reg __read_mostly = {
index 0dbe697..8f60749 100644 (file)
@@ -29,7 +29,7 @@
  *   Specify, after how many hundredths of a second the queue should be
  *   flushed even if it is not full yet.
  */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <linux/socket.h>
@@ -57,8 +57,6 @@ MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_NFLOG);
 #define ULOG_NL_EVENT          111             /* Harald's favorite number */
 #define ULOG_MAXNLGROUPS       32              /* numer of nlgroups */
 
-#define PRINTR(format, args...) do { if (net_ratelimit()) printk(format , ## args); } while (0)
-
 static unsigned int nlbufsiz = NLMSG_GOODSIZE;
 module_param(nlbufsiz, uint, 0400);
 MODULE_PARM_DESC(nlbufsiz, "netlink buffer size");
@@ -91,12 +89,12 @@ static void ulog_send(unsigned int nlgroupnum)
        ulog_buff_t *ub = &ulog_buffers[nlgroupnum];
 
        if (timer_pending(&ub->timer)) {
-               pr_debug("ipt_ULOG: ulog_send: timer was pending, deleting\n");
+               pr_debug("ulog_send: timer was pending, deleting\n");
                del_timer(&ub->timer);
        }
 
        if (!ub->skb) {
-               pr_debug("ipt_ULOG: ulog_send: nothing to send\n");
+               pr_debug("ulog_send: nothing to send\n");
                return;
        }
 
@@ -105,7 +103,7 @@ static void ulog_send(unsigned int nlgroupnum)
                ub->lastnlh->nlmsg_type = NLMSG_DONE;
 
        NETLINK_CB(ub->skb).dst_group = nlgroupnum + 1;
-       pr_debug("ipt_ULOG: throwing %d packets to netlink group %u\n",
+       pr_debug("throwing %d packets to netlink group %u\n",
                 ub->qlen, nlgroupnum + 1);
        netlink_broadcast(nflognl, ub->skb, 0, nlgroupnum + 1, GFP_ATOMIC);
 
@@ -118,7 +116,7 @@ static void ulog_send(unsigned int nlgroupnum)
 /* timer function to flush queue in flushtimeout time */
 static void ulog_timer(unsigned long data)
 {
-       pr_debug("ipt_ULOG: timer function called, calling ulog_send\n");
+       pr_debug("timer function called, calling ulog_send\n");
 
        /* lock to protect against somebody modifying our structure
         * from ipt_ulog_target at the same time */
@@ -139,7 +137,7 @@ static struct sk_buff *ulog_alloc_skb(unsigned int size)
        n = max(size, nlbufsiz);
        skb = alloc_skb(n, GFP_ATOMIC);
        if (!skb) {
-               PRINTR("ipt_ULOG: can't alloc whole buffer %ub!\n", n);
+               pr_debug("cannot alloc whole buffer %ub!\n", n);
 
                if (n > size) {
                        /* try to allocate only as much as we need for
@@ -147,8 +145,7 @@ static struct sk_buff *ulog_alloc_skb(unsigned int size)
 
                        skb = alloc_skb(size, GFP_ATOMIC);
                        if (!skb)
-                               PRINTR("ipt_ULOG: can't even allocate %ub\n",
-                                      size);
+                               pr_debug("cannot even allocate %ub\n", size);
                }
        }
 
@@ -199,8 +196,7 @@ static void ipt_ulog_packet(unsigned int hooknum,
                        goto alloc_failure;
        }
 
-       pr_debug("ipt_ULOG: qlen %d, qthreshold %Zu\n", ub->qlen,
-                loginfo->qthreshold);
+       pr_debug("qlen %d, qthreshold %Zu\n", ub->qlen, loginfo->qthreshold);
 
        /* NLMSG_PUT contains a hidden goto nlmsg_failure !!! */
        nlh = NLMSG_PUT(ub->skb, 0, ub->qlen, ULOG_NL_EVENT,
@@ -273,11 +269,9 @@ static void ipt_ulog_packet(unsigned int hooknum,
        return;
 
 nlmsg_failure:
-       PRINTR("ipt_ULOG: error during NLMSG_PUT\n");
-
+       pr_debug("error during NLMSG_PUT\n");
 alloc_failure:
-       PRINTR("ipt_ULOG: Error building netlink message\n");
-
+       pr_debug("Error building netlink message\n");
        spin_unlock_bh(&ulog_lock);
 }
 
@@ -314,21 +308,20 @@ static void ipt_logfn(u_int8_t pf,
        ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
 }
 
-static bool ulog_tg_check(const struct xt_tgchk_param *par)
+static int ulog_tg_check(const struct xt_tgchk_param *par)
 {
        const struct ipt_ulog_info *loginfo = par->targinfo;
 
        if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') {
-               pr_debug("ipt_ULOG: prefix term %i\n",
-                        loginfo->prefix[sizeof(loginfo->prefix) - 1]);
-               return false;
+               pr_debug("prefix not null-terminated\n");
+               return -EINVAL;
        }
        if (loginfo->qthreshold > ULOG_MAX_QLEN) {
-               pr_debug("ipt_ULOG: queue threshold %Zu > MAX_QLEN\n",
+               pr_debug("queue threshold %Zu > MAX_QLEN\n",
                         loginfo->qthreshold);
-               return false;
+               return -EINVAL;
        }
-       return true;
+       return 0;
 }
 
 #ifdef CONFIG_COMPAT
@@ -390,10 +383,10 @@ static int __init ulog_tg_init(void)
 {
        int ret, i;
 
-       pr_debug("ipt_ULOG: init module\n");
+       pr_debug("init module\n");
 
        if (nlbufsiz > 128*1024) {
-               printk("Netlink buffer has to be <= 128kB\n");
+               pr_warning("Netlink buffer has to be <= 128kB\n");
                return -EINVAL;
        }
 
@@ -423,7 +416,7 @@ static void __exit ulog_tg_exit(void)
        ulog_buff_t *ub;
        int i;
 
-       pr_debug("ipt_ULOG: cleanup_module\n");
+       pr_debug("cleanup_module\n");
 
        if (nflog)
                nf_log_unregister(&ipt_ulog_logger);
index 3b216be..e4b8f2b 100644 (file)
@@ -8,7 +8,7 @@
  *  it under the terms of the GNU General Public License version 2 as
  *  published by the Free Software Foundation.
  */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/skbuff.h>
@@ -70,34 +70,34 @@ addrtype_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par)
        return ret;
 }
 
-static bool addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par)
+static int addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par)
 {
        struct ipt_addrtype_info_v1 *info = par->matchinfo;
 
        if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN &&
            info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
-               printk(KERN_ERR "ipt_addrtype: both incoming and outgoing "
-                               "interface limitation cannot be selected\n");
-               return false;
+               pr_info("both incoming and outgoing "
+                       "interface limitation cannot be selected\n");
+               return -EINVAL;
        }
 
        if (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) |
            (1 << NF_INET_LOCAL_IN)) &&
            info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
-               printk(KERN_ERR "ipt_addrtype: output interface limitation "
-                               "not valid in PRE_ROUTING and INPUT\n");
-               return false;
+               pr_info("output interface limitation "
+                       "not valid in PREROUTING and INPUT\n");
+               return -EINVAL;
        }
 
        if (par->hook_mask & ((1 << NF_INET_POST_ROUTING) |
            (1 << NF_INET_LOCAL_OUT)) &&
            info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) {
-               printk(KERN_ERR "ipt_addrtype: input interface limitation "
-                               "not valid in POST_ROUTING and OUTPUT\n");
-               return false;
+               pr_info("input interface limitation "
+                       "not valid in POSTROUTING and OUTPUT\n");
+               return -EINVAL;
        }
 
-       return true;
+       return 0;
 }
 
 static struct xt_match addrtype_mt_reg[] __read_mostly = {
index 0104c0b..9f98102 100644 (file)
@@ -5,7 +5,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/in.h>
 #include <linux/module.h>
 #include <linux/skbuff.h>
@@ -18,21 +18,15 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Yon Uriarte <yon@astaro.de>");
 MODULE_DESCRIPTION("Xtables: IPv4 IPsec-AH SPI match");
 
-#ifdef DEBUG_CONNTRACK
-#define duprintf(format, args...) printk(format , ## args)
-#else
-#define duprintf(format, args...)
-#endif
-
 /* Returns 1 if the spi is matched by the range, 0 otherwise */
 static inline bool
 spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
 {
        bool r;
-       duprintf("ah spi_match:%c 0x%x <= 0x%x <= 0x%x",invert? '!':' ',
-               min,spi,max);
+       pr_debug("spi_match:%c 0x%x <= 0x%x <= 0x%x\n",
+                invert ? '!' : ' ', min, spi, max);
        r=(spi >= min && spi <= max) ^ invert;
-       duprintf(" result %s\n",r? "PASS" : "FAILED");
+       pr_debug(" result %s\n", r ? "PASS" : "FAILED");
        return r;
 }
 
@@ -51,7 +45,7 @@ static bool ah_mt(const struct sk_buff *skb, const struct xt_match_param *par)
                /* We've been asked to examine this packet, and we
                 * can't.  Hence, no choice but to drop.
                 */
-               duprintf("Dropping evil AH tinygram.\n");
+               pr_debug("Dropping evil AH tinygram.\n");
                *par->hotdrop = true;
                return 0;
        }
@@ -61,16 +55,16 @@ static bool ah_mt(const struct sk_buff *skb, const struct xt_match_param *par)
                         !!(ahinfo->invflags & IPT_AH_INV_SPI));
 }
 
-static bool ah_mt_check(const struct xt_mtchk_param *par)
+static int ah_mt_check(const struct xt_mtchk_param *par)
 {
        const struct ipt_ah *ahinfo = par->matchinfo;
 
        /* Must specify no unknown invflags */
        if (ahinfo->invflags & ~IPT_AH_INV_MASK) {
-               duprintf("ipt_ah: unknown flags %X\n", ahinfo->invflags);
-               return false;
+               pr_debug("unknown flags %X\n", ahinfo->invflags);
+               return -EINVAL;
        }
-       return true;
+       return 0;
 }
 
 static struct xt_match ah_mt_reg __read_mostly = {
index 2a1e56b..32e2410 100644 (file)
@@ -6,7 +6,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/in.h>
 #include <linux/ip.h>
 #include <net/ip.h>
@@ -85,25 +85,24 @@ static bool ecn_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        return true;
 }
 
-static bool ecn_mt_check(const struct xt_mtchk_param *par)
+static int ecn_mt_check(const struct xt_mtchk_param *par)
 {
        const struct ipt_ecn_info *info = par->matchinfo;
        const struct ipt_ip *ip = par->entryinfo;
 
        if (info->operation & IPT_ECN_OP_MATCH_MASK)
-               return false;
+               return -EINVAL;
 
        if (info->invert & IPT_ECN_OP_MATCH_MASK)
-               return false;
+               return -EINVAL;
 
        if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR) &&
            ip->proto != IPPROTO_TCP) {
-               printk(KERN_WARNING "ipt_ecn: can't match TCP bits in rule for"
-                      " non-tcp packets\n");
-               return false;
+               pr_info("cannot match TCP bits in rule for non-tcp packets\n");
+               return -EINVAL;
        }
 
-       return true;
+       return 0;
 }
 
 static struct xt_match ecn_mt_reg __read_mostly = {
index 7e8e6fc..d4c0618 100644 (file)
@@ -10,7 +10,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/tcp.h>
 #include <net/tcp.h>
 
index 26de2c1..b48a0fc 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 /* Everything about the rules for NAT. */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/types.h>
 #include <linux/ip.h>
 #include <linux/netfilter.h>
@@ -74,28 +75,28 @@ ipt_dnat_target(struct sk_buff *skb, const struct xt_target_param *par)
        return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_DST);
 }
 
-static bool ipt_snat_checkentry(const struct xt_tgchk_param *par)
+static int ipt_snat_checkentry(const struct xt_tgchk_param *par)
 {
        const struct nf_nat_multi_range_compat *mr = par->targinfo;
 
        /* Must be a valid range */
        if (mr->rangesize != 1) {
-               printk("SNAT: multiple ranges no longer supported\n");
-               return false;
+               pr_info("SNAT: multiple ranges no longer supported\n");
+               return -EINVAL;
        }
-       return true;
+       return 0;
 }
 
-static bool ipt_dnat_checkentry(const struct xt_tgchk_param *par)
+static int ipt_dnat_checkentry(const struct xt_tgchk_param *par)
 {
        const struct nf_nat_multi_range_compat *mr = par->targinfo;
 
        /* Must be a valid range */
        if (mr->rangesize != 1) {
-               printk("DNAT: multiple ranges no longer supported\n");
-               return false;
+               pr_info("DNAT: multiple ranges no longer supported\n");
+               return -EINVAL;
        }
-       return true;
+       return 0;
 }
 
 unsigned int
index c39c9cf..84c7974 100644 (file)
@@ -138,9 +138,8 @@ nf_nat_fn(unsigned int hooknum,
                                ret = nf_nat_rule_find(skb, hooknum, in, out,
                                                       ct);
 
-                       if (ret != NF_ACCEPT) {
+                       if (ret != NF_ACCEPT)
                                return ret;
-                       }
                } else
                        pr_debug("Already setup manip %s for ct %p\n",
                                 maniptype == IP_NAT_MANIP_SRC ? "SRC" : "DST",
index b096e81..7274a43 100644 (file)
@@ -6,7 +6,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/udp.h>
 
 #include <net/netfilter/nf_nat_helper.h>
index cc6f097..bbda0d5 100644 (file)
@@ -381,8 +381,8 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
                icmp_out_count(net, ((struct icmphdr *)
                        skb_transport_header(skb))->type);
 
-       err = NF_HOOK(PF_INET, NF_INET_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
-                     dst_output);
+       err = NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT, skb, NULL,
+                     rt->u.dst.dev, dst_output);
        if (err > 0)
                err = net_xmit_errno(err);
        if (err)
index c791bb6..abcd7ed 100644 (file)
@@ -61,7 +61,7 @@ int xfrm4_transport_finish(struct sk_buff *skb, int async)
        iph->tot_len = htons(skb->len);
        ip_send_check(iph);
 
-       NF_HOOK(PF_INET, NF_INET_PRE_ROUTING, skb, skb->dev, NULL,
+       NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, skb, skb->dev, NULL,
                xfrm4_rcv_encap_finish);
        return 0;
 }
index c908bd9..571aa96 100644 (file)
@@ -86,7 +86,7 @@ static int xfrm4_output_finish(struct sk_buff *skb)
 
 int xfrm4_output(struct sk_buff *skb)
 {
-       return NF_HOOK_COND(PF_INET, NF_INET_POST_ROUTING, skb,
+       return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, skb,
                            NULL, skb_dst(skb)->dev, xfrm4_output_finish,
                            !(IPCB(skb)->flags & IPSKB_REROUTED));
 }
index 6aa7ee1..a83e920 100644 (file)
@@ -143,7 +143,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
        /* Must drop socket now because of tproxy. */
        skb_orphan(skb);
 
-       return NF_HOOK(PF_INET6, NF_INET_PRE_ROUTING, skb, dev, NULL,
+       return NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING, skb, dev, NULL,
                       ip6_rcv_finish);
 err:
        IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INHDRERRORS);
@@ -236,7 +236,7 @@ discard:
 
 int ip6_input(struct sk_buff *skb)
 {
-       return NF_HOOK(PF_INET6, NF_INET_LOCAL_IN, skb, skb->dev, NULL,
+       return NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_IN, skb, skb->dev, NULL,
                       ip6_input_finish);
 }
 
index 5129a16..7f12e30 100644 (file)
@@ -67,8 +67,8 @@ int __ip6_local_out(struct sk_buff *skb)
                len = 0;
        ipv6_hdr(skb)->payload_len = htons(len);
 
-       return nf_hook(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb_dst(skb)->dev,
-                      dst_output);
+       return nf_hook(NFPROTO_IPV6, NF_INET_LOCAL_OUT, skb, NULL,
+                      skb_dst(skb)->dev, dst_output);
 }
 
 int ip6_local_out(struct sk_buff *skb)
@@ -83,22 +83,6 @@ int ip6_local_out(struct sk_buff *skb)
 }
 EXPORT_SYMBOL_GPL(ip6_local_out);
 
-static int ip6_output_finish(struct sk_buff *skb)
-{
-       struct dst_entry *dst = skb_dst(skb);
-
-       if (dst->hh)
-               return neigh_hh_output(dst->hh, skb);
-       else if (dst->neighbour)
-               return dst->neighbour->output(skb);
-
-       IP6_INC_STATS_BH(dev_net(dst->dev),
-                        ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
-       kfree_skb(skb);
-       return -EINVAL;
-
-}
-
 /* dev_loopback_xmit for use with netfilter. */
 static int ip6_dev_loopback_xmit(struct sk_buff *newskb)
 {
@@ -112,8 +96,7 @@ static int ip6_dev_loopback_xmit(struct sk_buff *newskb)
        return 0;
 }
 
-
-static int ip6_output2(struct sk_buff *skb)
+static int ip6_finish_output2(struct sk_buff *skb)
 {
        struct dst_entry *dst = skb_dst(skb);
        struct net_device *dev = dst->dev;
@@ -135,8 +118,8 @@ static int ip6_output2(struct sk_buff *skb)
                           is not supported in any case.
                         */
                        if (newskb)
-                               NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, newskb,
-                                       NULL, newskb->dev,
+                               NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING,
+                                       newskb, NULL, newskb->dev,
                                        ip6_dev_loopback_xmit);
 
                        if (ipv6_hdr(skb)->hop_limit == 0) {
@@ -151,8 +134,15 @@ static int ip6_output2(struct sk_buff *skb)
                                skb->len);
        }
 
-       return NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, skb, NULL, skb->dev,
-                      ip6_output_finish);
+       if (dst->hh)
+               return neigh_hh_output(dst->hh, skb);
+       else if (dst->neighbour)
+               return dst->neighbour->output(skb);
+
+       IP6_INC_STATS_BH(dev_net(dst->dev),
+                        ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
+       kfree_skb(skb);
+       return -EINVAL;
 }
 
 static inline int ip6_skb_dst_mtu(struct sk_buff *skb)
@@ -163,21 +153,29 @@ static inline int ip6_skb_dst_mtu(struct sk_buff *skb)
               skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb));
 }
 
+static int ip6_finish_output(struct sk_buff *skb)
+{
+       if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) ||
+           dst_allfrag(skb_dst(skb)))
+               return ip6_fragment(skb, ip6_finish_output2);
+       else
+               return ip6_finish_output2(skb);
+}
+
 int ip6_output(struct sk_buff *skb)
 {
+       struct net_device *dev = skb_dst(skb)->dev;
        struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
        if (unlikely(idev->cnf.disable_ipv6)) {
-               IP6_INC_STATS(dev_net(skb_dst(skb)->dev), idev,
+               IP6_INC_STATS(dev_net(dev), idev,
                              IPSTATS_MIB_OUTDISCARDS);
                kfree_skb(skb);
                return 0;
        }
 
-       if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) ||
-                               dst_allfrag(skb_dst(skb)))
-               return ip6_fragment(skb, ip6_output2);
-       else
-               return ip6_output2(skb);
+       return NF_HOOK_COND(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb, NULL, dev,
+                           ip6_finish_output,
+                           !(IP6CB(skb)->flags & IP6SKB_REROUTED));
 }
 
 /*
@@ -257,8 +255,8 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
        if ((skb->len <= mtu) || skb->local_df || skb_is_gso(skb)) {
                IP6_UPD_PO_STATS(net, ip6_dst_idev(skb_dst(skb)),
                              IPSTATS_MIB_OUT, skb->len);
-               return NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev,
-                               dst_output);
+               return NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, skb, NULL,
+                              dst->dev, dst_output);
        }
 
        if (net_ratelimit())
@@ -534,7 +532,7 @@ int ip6_forward(struct sk_buff *skb)
        hdr->hop_limit--;
 
        IP6_INC_STATS_BH(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTFORWDATAGRAMS);
-       return NF_HOOK(PF_INET6, NF_INET_FORWARD, skb, skb->dev, dst->dev,
+       return NF_HOOK(NFPROTO_IPV6, NF_INET_FORWARD, skb, skb->dev, dst->dev,
                       ip6_forward_finish);
 
 error:
index 3e33326..e0b530c 100644 (file)
@@ -1570,7 +1570,7 @@ static int ip6mr_forward2(struct sk_buff *skb, struct mfc6_cache *c, int vifi)
 
        IP6CB(skb)->flags |= IP6SKB_FORWARDED;
 
-       return NF_HOOK(PF_INET6, NF_INET_FORWARD, skb, skb->dev, dev,
+       return NF_HOOK(NFPROTO_IPV6, NF_INET_FORWARD, skb, skb->dev, dev,
                       ip6mr_forward2_finish);
 
 out_free:
index 62ed082..f9d05ce 100644 (file)
@@ -1480,7 +1480,7 @@ static void mld_sendpack(struct sk_buff *skb)
 
        payload_len = skb->len;
 
-       err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev,
+       err = NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev,
                      dst_output);
 out:
        if (!err) {
@@ -1848,7 +1848,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
                goto err_out;
 
        skb_dst_set(skb, dst);
-       err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev,
+       err = NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev,
                      dst_output);
 out:
        if (!err) {
index da0a4d2..3f7c12b 100644 (file)
@@ -536,7 +536,7 @@ void ndisc_send_skb(struct sk_buff *skb,
        idev = in6_dev_get(dst->dev);
        IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
 
-       err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev,
+       err = NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev,
                      dst_output);
        if (!err) {
                ICMP6MSGOUT_INC_STATS(net, idev, type);
@@ -1618,7 +1618,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
        skb_dst_set(buff, dst);
        idev = in6_dev_get(dst->dev);
        IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
-       err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, buff, NULL, dst->dev,
+       err = NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, buff, NULL, dst->dev,
                      dst_output);
        if (!err) {
                ICMP6MSGOUT_INC_STATS(net, idev, NDISC_REDIRECT);
index d5ed92b..a74951c 100644 (file)
@@ -25,20 +25,6 @@ int ip6_route_me_harder(struct sk_buff *skb)
        };
 
        dst = ip6_route_output(net, skb->sk, &fl);
-
-#ifdef CONFIG_XFRM
-       if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
-           xfrm_decode_session(skb, &fl, AF_INET6) == 0) {
-               struct dst_entry *dst2 = skb_dst(skb);
-
-               if (xfrm_lookup(net, &dst2, &fl, skb->sk, 0)) {
-                       skb_dst_set(skb, NULL);
-                       return -1;
-               }
-               skb_dst_set(skb, dst2);
-       }
-#endif
-
        if (dst->error) {
                IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
                LIMIT_NETDEBUG(KERN_DEBUG "ip6_route_me_harder: No more route.\n");
@@ -50,6 +36,17 @@ int ip6_route_me_harder(struct sk_buff *skb)
        skb_dst_drop(skb);
 
        skb_dst_set(skb, dst);
+
+#ifdef CONFIG_XFRM
+       if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
+           xfrm_decode_session(skb, &fl, AF_INET6) == 0) {
+               skb_dst_set(skb, NULL);
+               if (xfrm_lookup(net, &dst, &fl, skb->sk, 0))
+                       return -1;
+               skb_dst_set(skb, dst);
+       }
+#endif
+
        return 0;
 }
 EXPORT_SYMBOL(ip6_route_me_harder);
index 6a68a74..8656eb7 100644 (file)
@@ -162,8 +162,7 @@ ipq_build_packet_message(struct nf_queue_entry *entry, int *errp)
                break;
 
        case IPQ_COPY_PACKET:
-               if ((entry->skb->ip_summed == CHECKSUM_PARTIAL ||
-                    entry->skb->ip_summed == CHECKSUM_COMPLETE) &&
+               if (entry->skb->ip_summed == CHECKSUM_PARTIAL &&
                    (*errp = skb_checksum_help(entry->skb))) {
                        read_unlock_bh(&queue_lock);
                        return NULL;
index 9210e31..7afa117 100644 (file)
@@ -40,13 +40,13 @@ MODULE_DESCRIPTION("IPv6 packet filter");
 /*#define DEBUG_IP_FIREWALL_USER*/
 
 #ifdef DEBUG_IP_FIREWALL
-#define dprintf(format, args...)  printk(format , ## args)
+#define dprintf(format, args...) pr_info(format , ## args)
 #else
 #define dprintf(format, args...)
 #endif
 
 #ifdef DEBUG_IP_FIREWALL_USER
-#define duprintf(format, args...) printk(format , ## args)
+#define duprintf(format, args...) pr_info(format , ## args)
 #else
 #define duprintf(format, args...)
 #endif
@@ -200,8 +200,7 @@ static unsigned int
 ip6t_error(struct sk_buff *skb, const struct xt_target_param *par)
 {
        if (net_ratelimit())
-               printk("ip6_tables: error: `%s'\n",
-                      (const char *)par->targinfo);
+               pr_info("error: `%s'\n", (const char *)par->targinfo);
 
        return NF_DROP;
 }
@@ -352,15 +351,14 @@ ip6t_do_table(struct sk_buff *skb,
              const struct net_device *out,
              struct xt_table *table)
 {
-#define tb_comefrom ((struct ip6t_entry *)table_base)->comefrom
-
        static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
        bool hotdrop = false;
        /* Initializing verdict to NF_DROP keeps gcc happy. */
        unsigned int verdict = NF_DROP;
        const char *indev, *outdev;
        const void *table_base;
-       struct ip6t_entry *e, *back;
+       struct ip6t_entry *e, **jumpstack;
+       unsigned int *stackptr, origptr, cpu;
        const struct xt_table_info *private;
        struct xt_match_param mtpar;
        struct xt_target_param tgpar;
@@ -384,19 +382,19 @@ ip6t_do_table(struct sk_buff *skb,
 
        xt_info_rdlock_bh();
        private = table->private;
-       table_base = private->entries[smp_processor_id()];
+       cpu        = smp_processor_id();
+       table_base = private->entries[cpu];
+       jumpstack  = (struct ip6t_entry **)private->jumpstack[cpu];
+       stackptr   = &private->stackptr[cpu];
+       origptr    = *stackptr;
 
        e = get_entry(table_base, private->hook_entry[hook]);
 
-       /* For return from builtin chain */
-       back = get_entry(table_base, private->underflow[hook]);
-
        do {
                const struct ip6t_entry_target *t;
                const struct xt_entry_match *ematch;
 
                IP_NF_ASSERT(e);
-               IP_NF_ASSERT(back);
                if (!ip6_packet_match(skb, indev, outdev, &e->ipv6,
                    &mtpar.thoff, &mtpar.fragoff, &hotdrop)) {
  no_match:
@@ -433,41 +431,30 @@ ip6t_do_table(struct sk_buff *skb,
                                        verdict = (unsigned)(-v) - 1;
                                        break;
                                }
-                               e = back;
-                               back = get_entry(table_base, back->comefrom);
+                               if (*stackptr == 0)
+                                       e = get_entry(table_base,
+                                           private->underflow[hook]);
+                               else
+                                       e = ip6t_next_entry(jumpstack[--*stackptr]);
                                continue;
                        }
                        if (table_base + v != ip6t_next_entry(e) &&
                            !(e->ipv6.flags & IP6T_F_GOTO)) {
-                               /* Save old back ptr in next entry */
-                               struct ip6t_entry *next = ip6t_next_entry(e);
-                               next->comefrom = (void *)back - table_base;
-                               /* set back pointer to next entry */
-                               back = next;
+                               if (*stackptr >= private->stacksize) {
+                                       verdict = NF_DROP;
+                                       break;
+                               }
+                               jumpstack[(*stackptr)++] = e;
                        }
 
                        e = get_entry(table_base, v);
                        continue;
                }
 
-               /* Targets which reenter must return
-                  abs. verdicts */
                tgpar.target   = t->u.kernel.target;
                tgpar.targinfo = t->data;
 
-#ifdef CONFIG_NETFILTER_DEBUG
-               tb_comefrom = 0xeeeeeeec;
-#endif
                verdict = t->u.kernel.target->target(skb, &tgpar);
-
-#ifdef CONFIG_NETFILTER_DEBUG
-               if (tb_comefrom != 0xeeeeeeec && verdict == IP6T_CONTINUE) {
-                       printk("Target %s reentered!\n",
-                              t->u.kernel.target->name);
-                       verdict = NF_DROP;
-               }
-               tb_comefrom = 0x57acc001;
-#endif
                if (verdict == IP6T_CONTINUE)
                        e = ip6t_next_entry(e);
                else
@@ -475,10 +462,8 @@ ip6t_do_table(struct sk_buff *skb,
                        break;
        } while (!hotdrop);
 
-#ifdef CONFIG_NETFILTER_DEBUG
-       tb_comefrom = NETFILTER_LINK_POISON;
-#endif
        xt_info_rdunlock_bh();
+       *stackptr = origptr;
 
 #ifdef DEBUG_ALLOW_ALL
        return NF_ACCEPT;
@@ -487,8 +472,6 @@ ip6t_do_table(struct sk_buff *skb,
                return NF_DROP;
        else return verdict;
 #endif
-
-#undef tb_comefrom
 }
 
 /* Figures out from what hook each rule can be called: returns 0 if
@@ -661,12 +644,11 @@ find_check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par)
        struct xt_match *match;
        int ret;
 
-       match = try_then_request_module(xt_find_match(AF_INET6, m->u.user.name,
-                                                     m->u.user.revision),
-                                       "ip6t_%s", m->u.user.name);
-       if (IS_ERR(match) || !match) {
+       match = xt_request_find_match(NFPROTO_IPV6, m->u.user.name,
+                                     m->u.user.revision);
+       if (IS_ERR(match)) {
                duprintf("find_check_match: `%s' not found\n", m->u.user.name);
-               return match ? PTR_ERR(match) : -ENOENT;
+               return PTR_ERR(match);
        }
        m->u.kernel.match = match;
 
@@ -734,13 +716,11 @@ find_check_entry(struct ip6t_entry *e, struct net *net, const char *name,
        }
 
        t = ip6t_get_target(e);
-       target = try_then_request_module(xt_find_target(AF_INET6,
-                                                       t->u.user.name,
-                                                       t->u.user.revision),
-                                        "ip6t_%s", t->u.user.name);
-       if (IS_ERR(target) || !target) {
+       target = xt_request_find_target(NFPROTO_IPV6, t->u.user.name,
+                                       t->u.user.revision);
+       if (IS_ERR(target)) {
                duprintf("find_check_entry: `%s' not found\n", t->u.user.name);
-               ret = target ? PTR_ERR(target) : -ENOENT;
+               ret = PTR_ERR(target);
                goto cleanup_matches;
        }
        t->u.kernel.target = target;
@@ -873,6 +853,9 @@ translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0,
                if (ret != 0)
                        return ret;
                ++i;
+               if (strcmp(ip6t_get_target(iter)->u.user.name,
+                   XT_ERROR_TARGET) == 0)
+                       ++newinfo->stacksize;
        }
 
        if (i != repl->num_entries) {
@@ -1509,13 +1492,12 @@ compat_find_calc_match(struct ip6t_entry_match *m,
 {
        struct xt_match *match;
 
-       match = try_then_request_module(xt_find_match(AF_INET6, m->u.user.name,
-                                                     m->u.user.revision),
-                                       "ip6t_%s", m->u.user.name);
-       if (IS_ERR(match) || !match) {
+       match = xt_request_find_match(NFPROTO_IPV6, m->u.user.name,
+                                     m->u.user.revision);
+       if (IS_ERR(match)) {
                duprintf("compat_check_calc_match: `%s' not found\n",
                         m->u.user.name);
-               return match ? PTR_ERR(match) : -ENOENT;
+               return PTR_ERR(match);
        }
        m->u.kernel.match = match;
        *size += xt_compat_match_offset(match);
@@ -1582,14 +1564,12 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
        }
 
        t = compat_ip6t_get_target(e);
-       target = try_then_request_module(xt_find_target(AF_INET6,
-                                                       t->u.user.name,
-                                                       t->u.user.revision),
-                                        "ip6t_%s", t->u.user.name);
-       if (IS_ERR(target) || !target) {
+       target = xt_request_find_target(NFPROTO_IPV6, t->u.user.name,
+                                       t->u.user.revision);
+       if (IS_ERR(target)) {
                duprintf("check_compat_entry_size_and_hooks: `%s' not found\n",
                         t->u.user.name);
-               ret = target ? PTR_ERR(target) : -ENOENT;
+               ret = PTR_ERR(target);
                goto release_matches;
        }
        t->u.kernel.target = target;
@@ -2127,8 +2107,7 @@ struct xt_table *ip6t_register_table(struct net *net,
 {
        int ret;
        struct xt_table_info *newinfo;
-       struct xt_table_info bootstrap
-               = { 0, 0, 0, { 0 }, { 0 }, { } };
+       struct xt_table_info bootstrap = {0};
        void *loc_cpu_entry;
        struct xt_table *new_table;
 
@@ -2216,12 +2195,12 @@ icmp6_match(const struct sk_buff *skb, const struct xt_match_param *par)
 }
 
 /* Called when user tries to insert an entry of this type. */
-static bool icmp6_checkentry(const struct xt_mtchk_param *par)
+static int icmp6_checkentry(const struct xt_mtchk_param *par)
 {
        const struct ip6t_icmp *icmpinfo = par->matchinfo;
 
        /* Must specify no unknown invflags */
-       return !(icmpinfo->invflags & ~IP6T_ICMP_INV);
+       return (icmpinfo->invflags & ~IP6T_ICMP_INV) ? -EINVAL : 0;
 }
 
 /* The built-in targets: standard (NULL) and error. */
@@ -2308,7 +2287,7 @@ static int __init ip6_tables_init(void)
        if (ret < 0)
                goto err5;
 
-       printk(KERN_INFO "ip6_tables: (C) 2000-2006 Netfilter Core Team\n");
+       pr_info("(C) 2000-2006 Netfilter Core Team\n");
        return 0;
 
 err5:
index b285fdf..1f47a52 100644 (file)
@@ -9,9 +9,8 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/skbuff.h>
 #include <linux/if_arp.h>
 #include <linux/ip.h>
@@ -378,7 +377,7 @@ static struct nf_loginfo default_loginfo = {
        .type   = NF_LOG_TYPE_LOG,
        .u = {
                .log = {
-                       .level    = 0,
+                       .level    = 5,
                        .logflags = NF_LOG_MASK,
                },
        },
@@ -452,20 +451,19 @@ log_tg6(struct sk_buff *skb, const struct xt_target_param *par)
 }
 
 
-static bool log_tg6_check(const struct xt_tgchk_param *par)
+static int log_tg6_check(const struct xt_tgchk_param *par)
 {
        const struct ip6t_log_info *loginfo = par->targinfo;
 
        if (loginfo->level >= 8) {
-               pr_debug("LOG: level %u >= 8\n", loginfo->level);
-               return false;
+               pr_debug("level %u >= 8\n", loginfo->level);
+               return -EINVAL;
        }
        if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') {
-               pr_debug("LOG: prefix term %i\n",
-                        loginfo->prefix[sizeof(loginfo->prefix)-1]);
-               return false;
+               pr_debug("prefix not null-terminated\n");
+               return -EINVAL;
        }
-       return true;
+       return 0;
 }
 
 static struct xt_target log_tg6_reg __read_mostly = {
index 39b50c3..af1d649 100644 (file)
@@ -14,6 +14,7 @@
  * as published by the Free Software Foundation; either version
  * 2 of the License, or (at your option) any later version.
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/gfp.h>
 #include <linux/module.h>
@@ -50,7 +51,7 @@ static void send_reset(struct net *net, struct sk_buff *oldskb)
 
        if ((!(ipv6_addr_type(&oip6h->saddr) & IPV6_ADDR_UNICAST)) ||
            (!(ipv6_addr_type(&oip6h->daddr) & IPV6_ADDR_UNICAST))) {
-               pr_debug("ip6t_REJECT: addr is not unicast.\n");
+               pr_debug("addr is not unicast.\n");
                return;
        }
 
@@ -58,7 +59,7 @@ static void send_reset(struct net *net, struct sk_buff *oldskb)
        tcphoff = ipv6_skip_exthdr(oldskb, ((u8*)(oip6h+1) - oldskb->data), &proto);
 
        if ((tcphoff < 0) || (tcphoff > oldskb->len)) {
-               pr_debug("ip6t_REJECT: Can't get TCP header.\n");
+               pr_debug("Cannot get TCP header.\n");
                return;
        }
 
@@ -66,7 +67,7 @@ static void send_reset(struct net *net, struct sk_buff *oldskb)
 
        /* IP header checks: fragment, too short. */
        if (proto != IPPROTO_TCP || otcplen < sizeof(struct tcphdr)) {
-               pr_debug("ip6t_REJECT: proto(%d) != IPPROTO_TCP, "
+               pr_debug("proto(%d) != IPPROTO_TCP, "
                         "or too short. otcplen = %d\n",
                         proto, otcplen);
                return;
@@ -77,14 +78,14 @@ static void send_reset(struct net *net, struct sk_buff *oldskb)
 
        /* No RST for RST. */
        if (otcph.rst) {
-               pr_debug("ip6t_REJECT: RST is set\n");
+               pr_debug("RST is set\n");
                return;
        }
 
        /* Check checksum. */
        if (csum_ipv6_magic(&oip6h->saddr, &oip6h->daddr, otcplen, IPPROTO_TCP,
                            skb_checksum(oldskb, tcphoff, otcplen, 0))) {
-               pr_debug("ip6t_REJECT: TCP checksum is invalid\n");
+               pr_debug("TCP checksum is invalid\n");
                return;
        }
 
@@ -108,7 +109,7 @@ static void send_reset(struct net *net, struct sk_buff *oldskb)
 
        if (!nskb) {
                if (net_ratelimit())
-                       printk("ip6t_REJECT: Can't alloc skb\n");
+                       pr_debug("cannot alloc skb\n");
                dst_release(dst);
                return;
        }
@@ -180,9 +181,6 @@ reject_tg6(struct sk_buff *skb, const struct xt_target_param *par)
        struct net *net = dev_net((par->in != NULL) ? par->in : par->out);
 
        pr_debug("%s: medium point\n", __func__);
-       /* WARNING: This code causes reentry within ip6tables.
-          This means that the ip6tables jump stack is now crap.  We
-          must return an absolute verdict. --RR */
        switch (reject->with) {
        case IP6T_ICMP6_NO_ROUTE:
                send_unreach(net, skb, ICMPV6_NOROUTE, par->hooknum);
@@ -207,30 +205,30 @@ reject_tg6(struct sk_buff *skb, const struct xt_target_param *par)
                break;
        default:
                if (net_ratelimit())
-                       printk(KERN_WARNING "ip6t_REJECT: case %u not handled yet\n", reject->with);
+                       pr_info("case %u not handled yet\n", reject->with);
                break;
        }
 
        return NF_DROP;
 }
 
-static bool reject_tg6_check(const struct xt_tgchk_param *par)
+static int reject_tg6_check(const struct xt_tgchk_param *par)
 {
        const struct ip6t_reject_info *rejinfo = par->targinfo;
        const struct ip6t_entry *e = par->entryinfo;
 
        if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) {
-               printk("ip6t_REJECT: ECHOREPLY is not supported.\n");
-               return false;
+               pr_info("ECHOREPLY is not supported.\n");
+               return -EINVAL;
        } else if (rejinfo->with == IP6T_TCP_RESET) {
                /* Must specify that it's a TCP packet */
                if (e->ipv6.proto != IPPROTO_TCP ||
                    (e->ipv6.invflags & XT_INV_PROTO)) {
-                       printk("ip6t_REJECT: TCP_RESET illegal for non-tcp\n");
-                       return false;
+                       pr_info("TCP_RESET illegal for non-tcp\n");
+                       return -EINVAL;
                }
        }
-       return true;
+       return 0;
 }
 
 static struct xt_target reject_tg6_reg __read_mostly = {
index ac0b7c6..1580693 100644 (file)
@@ -6,7 +6,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/ip.h>
@@ -29,7 +29,7 @@ spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
 {
        bool r;
 
-       pr_debug("ah spi_match:%c 0x%x <= 0x%x <= 0x%x",
+       pr_debug("spi_match:%c 0x%x <= 0x%x <= 0x%x\n",
                 invert ? '!' : ' ', min, spi, max);
        r = (spi >= min && spi <= max) ^ invert;
        pr_debug(" result %s\n", r ? "PASS" : "FAILED");
@@ -87,15 +87,15 @@ static bool ah_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
                !(ahinfo->hdrres && ah->reserved);
 }
 
-static bool ah_mt6_check(const struct xt_mtchk_param *par)
+static int ah_mt6_check(const struct xt_mtchk_param *par)
 {
        const struct ip6t_ah *ahinfo = par->matchinfo;
 
        if (ahinfo->invflags & ~IP6T_AH_INV_MASK) {
-               pr_debug("ip6t_ah: unknown flags %X\n", ahinfo->invflags);
-               return false;
+               pr_debug("unknown flags %X\n", ahinfo->invflags);
+               return -EINVAL;
        }
-       return true;
+       return 0;
 }
 
 static struct xt_match ah_mt6_reg __read_mostly = {
index 7b91c25..a5daf0f 100644 (file)
@@ -6,7 +6,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/ipv6.h>
@@ -27,7 +27,7 @@ static inline bool
 id_match(u_int32_t min, u_int32_t max, u_int32_t id, bool invert)
 {
        bool r;
-       pr_debug("frag id_match:%c 0x%x <= 0x%x <= 0x%x", invert ? '!' : ' ',
+       pr_debug("id_match:%c 0x%x <= 0x%x <= 0x%x\n", invert ? '!' : ' ',
                 min, id, max);
        r = (id >= min && id <= max) ^ invert;
        pr_debug(" result %s\n", r ? "PASS" : "FAILED");
@@ -102,15 +102,15 @@ frag_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
                  (ntohs(fh->frag_off) & IP6_MF));
 }
 
-static bool frag_mt6_check(const struct xt_mtchk_param *par)
+static int frag_mt6_check(const struct xt_mtchk_param *par)
 {
        const struct ip6t_frag *fraginfo = par->matchinfo;
 
        if (fraginfo->invflags & ~IP6T_FRAG_INV_MASK) {
-               pr_debug("ip6t_frag: unknown flags %X\n", fraginfo->invflags);
-               return false;
+               pr_debug("unknown flags %X\n", fraginfo->invflags);
+               return -EINVAL;
        }
-       return true;
+       return 0;
 }
 
 static struct xt_match frag_mt6_reg __read_mostly = {
index e606775..e424e7c 100644 (file)
@@ -6,7 +6,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/ipv6.h>
@@ -41,6 +41,8 @@ MODULE_ALIAS("ip6t_dst");
  *     5       -> RTALERT 2 x x
  */
 
+static struct xt_match hbh_mt6_reg[] __read_mostly;
+
 static bool
 hbh_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
 {
@@ -58,7 +60,9 @@ hbh_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
        unsigned int optlen;
        int err;
 
-       err = ipv6_find_hdr(skb, &ptr, par->match->data, NULL);
+       err = ipv6_find_hdr(skb, &ptr,
+                           (par->match == &hbh_mt6_reg[0]) ?
+                           NEXTHDR_HOP : NEXTHDR_DEST, NULL);
        if (err < 0) {
                if (err != -ENOENT)
                        *par->hotdrop = true;
@@ -160,32 +164,32 @@ hbh_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
        return false;
 }
 
-static bool hbh_mt6_check(const struct xt_mtchk_param *par)
+static int hbh_mt6_check(const struct xt_mtchk_param *par)
 {
        const struct ip6t_opts *optsinfo = par->matchinfo;
 
        if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) {
-               pr_debug("ip6t_opts: unknown flags %X\n", optsinfo->invflags);
-               return false;
+               pr_debug("unknown flags %X\n", optsinfo->invflags);
+               return -EINVAL;
        }
 
        if (optsinfo->flags & IP6T_OPTS_NSTRICT) {
-               pr_debug("ip6t_opts: Not strict - not implemented");
-               return false;
+               pr_debug("Not strict - not implemented");
+               return -EINVAL;
        }
 
-       return true;
+       return 0;
 }
 
 static struct xt_match hbh_mt6_reg[] __read_mostly = {
        {
+               /* Note, hbh_mt6 relies on the order of hbh_mt6_reg */
                .name           = "hbh",
                .family         = NFPROTO_IPV6,
                .match          = hbh_mt6,
                .matchsize      = sizeof(struct ip6t_opts),
                .checkentry     = hbh_mt6_check,
                .me             = THIS_MODULE,
-               .data           = NEXTHDR_HOP,
        },
        {
                .name           = "dst",
@@ -194,7 +198,6 @@ static struct xt_match hbh_mt6_reg[] __read_mostly = {
                .matchsize      = sizeof(struct ip6t_opts),
                .checkentry     = hbh_mt6_check,
                .me             = THIS_MODULE,
-               .data           = NEXTHDR_DEST,
        },
 };
 
index 91490ad..46fbabb 100644 (file)
@@ -118,16 +118,16 @@ ipv6header_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
        }
 }
 
-static bool ipv6header_mt6_check(const struct xt_mtchk_param *par)
+static int ipv6header_mt6_check(const struct xt_mtchk_param *par)
 {
        const struct ip6t_ipv6header_info *info = par->matchinfo;
 
        /* invflags is 0 or 0xff in hard mode */
        if ((!info->modeflag) && info->invflags != 0x00 &&
            info->invflags != 0xFF)
-               return false;
+               return -EINVAL;
 
-       return true;
+       return 0;
 }
 
 static struct xt_match ipv6header_mt6_reg __read_mostly = {
index aafe4e6..c9f443e 100644 (file)
@@ -11,6 +11,7 @@
  * Based on net/netfilter/xt_tcpudp.c
  *
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/types.h>
 #include <linux/module.h>
 #include <net/ip.h>
 MODULE_DESCRIPTION("Xtables: IPv6 Mobility Header match");
 MODULE_LICENSE("GPL");
 
-#ifdef DEBUG_IP_FIREWALL_USER
-#define duprintf(format, args...) printk(format , ## args)
-#else
-#define duprintf(format, args...)
-#endif
-
 /* Returns 1 if the type is matched by the range, 0 otherwise */
 static inline bool
 type_match(u_int8_t min, u_int8_t max, u_int8_t type, bool invert)
@@ -51,13 +46,13 @@ static bool mh_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
        if (mh == NULL) {
                /* We've been asked to examine this packet, and we
                   can't.  Hence, no choice but to drop. */
-               duprintf("Dropping evil MH tinygram.\n");
+               pr_debug("Dropping evil MH tinygram.\n");
                *par->hotdrop = true;
                return false;
        }
 
        if (mh->ip6mh_proto != IPPROTO_NONE) {
-               duprintf("Dropping invalid MH Payload Proto: %u\n",
+               pr_debug("Dropping invalid MH Payload Proto: %u\n",
                         mh->ip6mh_proto);
                *par->hotdrop = true;
                return false;
@@ -67,12 +62,12 @@ static bool mh_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
                          !!(mhinfo->invflags & IP6T_MH_INV_TYPE));
 }
 
-static bool mh_mt6_check(const struct xt_mtchk_param *par)
+static int mh_mt6_check(const struct xt_mtchk_param *par)
 {
        const struct ip6t_mh *mhinfo = par->matchinfo;
 
        /* Must specify no unknown invflags */
-       return !(mhinfo->invflags & ~IP6T_MH_INV_MASK);
+       return (mhinfo->invflags & ~IP6T_MH_INV_MASK) ? -EINVAL : 0;
 }
 
 static struct xt_match mh_mt6_reg __read_mostly = {
index b77307f..0932272 100644 (file)
@@ -6,7 +6,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/ipv6.h>
@@ -29,7 +29,7 @@ static inline bool
 segsleft_match(u_int32_t min, u_int32_t max, u_int32_t id, bool invert)
 {
        bool r;
-       pr_debug("rt segsleft_match:%c 0x%x <= 0x%x <= 0x%x",
+       pr_debug("segsleft_match:%c 0x%x <= 0x%x <= 0x%x\n",
                 invert ? '!' : ' ', min, id, max);
        r = (id >= min && id <= max) ^ invert;
        pr_debug(" result %s\n", r ? "PASS" : "FAILED");
@@ -183,23 +183,23 @@ static bool rt_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
        return false;
 }
 
-static bool rt_mt6_check(const struct xt_mtchk_param *par)
+static int rt_mt6_check(const struct xt_mtchk_param *par)
 {
        const struct ip6t_rt *rtinfo = par->matchinfo;
 
        if (rtinfo->invflags & ~IP6T_RT_INV_MASK) {
-               pr_debug("ip6t_rt: unknown flags %X\n", rtinfo->invflags);
-               return false;
+               pr_debug("unknown flags %X\n", rtinfo->invflags);
+               return -EINVAL;
        }
        if ((rtinfo->flags & (IP6T_RT_RES | IP6T_RT_FST_MASK)) &&
            (!(rtinfo->flags & IP6T_RT_TYP) ||
             (rtinfo->rt_type != 0) ||
             (rtinfo->invflags & IP6T_RT_INV_TYP))) {
                pr_debug("`--rt-type 0' required before `--rt-0-*'");
-               return false;
+               return -EINVAL;
        }
 
-       return true;
+       return 0;
 }
 
 static struct xt_match rt_mt6_reg __read_mostly = {
index dd5b9bd..6fb8901 100644 (file)
@@ -644,7 +644,7 @@ void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
                s2 = s->next;
                s->next = NULL;
 
-               NF_HOOK_THRESH(PF_INET6, hooknum, s, in, out, okfn,
+               NF_HOOK_THRESH(NFPROTO_IPV6, hooknum, s, in, out, okfn,
                               NF_IP6_PRI_CONNTRACK_DEFRAG + 1);
                s = s2;
        }
index 8763b1a..554b48b 100644 (file)
@@ -637,8 +637,8 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
                goto error_fault;
 
        IP6_UPD_PO_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUT, skb->len);
-       err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
-                     dst_output);
+       err = NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, skb, NULL,
+                     rt->u.dst.dev, dst_output);
        if (err > 0)
                err = net_xmit_errno(err);
        if (err)
index 2bc98ed..f8c3cf8 100644 (file)
@@ -42,7 +42,7 @@ int xfrm6_transport_finish(struct sk_buff *skb, int async)
        ipv6_hdr(skb)->payload_len = htons(skb->len);
        __skb_push(skb, skb->data - skb_network_header(skb));
 
-       NF_HOOK(PF_INET6, NF_INET_PRE_ROUTING, skb, skb->dev, NULL,
+       NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING, skb, skb->dev, NULL,
                ip6_rcv_finish);
        return -1;
 }
index 0c92112..6434bd5 100644 (file)
@@ -90,6 +90,6 @@ static int xfrm6_output_finish(struct sk_buff *skb)
 
 int xfrm6_output(struct sk_buff *skb)
 {
-       return NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, skb, NULL, skb_dst(skb)->dev,
-                      xfrm6_output_finish);
+       return NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb, NULL,
+                      skb_dst(skb)->dev, xfrm6_output_finish);
 }
index 18d77b5..673a6c8 100644 (file)
@@ -314,8 +314,39 @@ config NETFILTER_XTABLES
 
 if NETFILTER_XTABLES
 
+comment "Xtables combined modules"
+
+config NETFILTER_XT_MARK
+       tristate 'nfmark target and match support'
+       default m if NETFILTER_ADVANCED=n
+       ---help---
+       This option adds the "MARK" target and "mark" match.
+
+       Netfilter mark matching allows you to match packets based on the
+       "nfmark" value in the packet.
+       The target allows you to create rules in the "mangle" table which alter
+       the netfilter mark (nfmark) field associated with the packet.
+
+       Prior to routing, the nfmark can influence the routing method (see
+       "Use netfilter MARK value as routing key") and can also be used by
+       other subsystems to change their behavior.
+
+config NETFILTER_XT_CONNMARK
+       tristate 'ctmark target and match support'
+       depends on NF_CONNTRACK
+       depends on NETFILTER_ADVANCED
+       select NF_CONNTRACK_MARK
+       ---help---
+       This option adds the "CONNMARK" target and "connmark" match.
+
+       Netfilter allows you to store a mark value per connection (a.k.a.
+       ctmark), similarly to the packet mark (nfmark). Using this
+       target and match, you can set and match on this mark.
+
 # alphabetically ordered list of targets
 
+comment "Xtables targets"
+
 config NETFILTER_XT_TARGET_CLASSIFY
        tristate '"CLASSIFY" target support'
        depends on NETFILTER_ADVANCED
@@ -332,15 +363,11 @@ config NETFILTER_XT_TARGET_CONNMARK
        tristate  '"CONNMARK" target support'
        depends on NF_CONNTRACK
        depends on NETFILTER_ADVANCED
-       select NF_CONNTRACK_MARK
-       help
-         This option adds a `CONNMARK' target, which allows one to manipulate
-         the connection mark value.  Similar to the MARK target, but
-         affects the connection mark value rather than the packet mark value.
-
-         If you want to compile it as a module, say M here and read
-         <file:Documentation/kbuild/modules.txt>.  The module will be called
-         ipt_CONNMARK.  If unsure, say `N'.
+       select NETFILTER_XT_CONNMARK
+       ---help---
+       This is a backwards-compat option for the user's convenience
+       (e.g. when running oldconfig). It selects
+       CONFIG_NETFILTER_XT_CONNMARK (combined connmark/CONNMARK module).
 
 config NETFILTER_XT_TARGET_CONNSECMARK
        tristate '"CONNSECMARK" target support'
@@ -423,16 +450,12 @@ config NETFILTER_XT_TARGET_LED
 
 config NETFILTER_XT_TARGET_MARK
        tristate '"MARK" target support'
-       default m if NETFILTER_ADVANCED=n
-       help
-         This option adds a `MARK' target, which allows you to create rules
-         in the `mangle' table which alter the netfilter mark (nfmark) field
-         associated with the packet prior to routing. This can change
-         the routing method (see `Use netfilter MARK value as routing
-         key') and can also be used by other subsystems to change their
-         behavior.
-
-         To compile it as a module, choose M here.  If unsure, say N.
+       depends on NETFILTER_ADVANCED
+       select NETFILTER_XT_MARK
+       ---help---
+       This is a backwards-compat option for the user's convenience
+       (e.g. when running oldconfig). It selects
+       CONFIG_NETFILTER_XT_MARK (combined mark/MARK module).
 
 config NETFILTER_XT_TARGET_NFLOG
        tristate '"NFLOG" target support'
@@ -479,6 +502,13 @@ config NETFILTER_XT_TARGET_RATEEST
 
          To compile it as a module, choose M here.  If unsure, say N.
 
+config NETFILTER_XT_TARGET_TEE
+       tristate '"TEE" - packet cloning to alternate destiantion'
+       depends on NETFILTER_ADVANCED
+       ---help---
+       This option adds a "TEE" target with which a packet can be cloned and
+       this clone be rerouted to another nexthop.
+
 config NETFILTER_XT_TARGET_TPROXY
        tristate '"TPROXY" target support (EXPERIMENTAL)'
        depends on EXPERIMENTAL
@@ -552,6 +582,10 @@ config NETFILTER_XT_TARGET_TCPOPTSTRIP
          This option adds a "TCPOPTSTRIP" target, which allows you to strip
          TCP options from TCP packets.
 
+# alphabetically ordered list of matches
+
+comment "Xtables matches"
+
 config NETFILTER_XT_MATCH_CLUSTER
        tristate '"cluster" match support'
        depends on NF_CONNTRACK
@@ -602,14 +636,11 @@ config NETFILTER_XT_MATCH_CONNMARK
        tristate  '"connmark" connection mark match support'
        depends on NF_CONNTRACK
        depends on NETFILTER_ADVANCED
-       select NF_CONNTRACK_MARK
-       help
-         This option adds a `connmark' match, which allows you to match the
-         connection mark value previously set for the session by `CONNMARK'. 
-
-         If you want to compile it as a module, say M here and read
-         <file:Documentation/kbuild/modules.txt>.  The module will be called
-         ipt_connmark.  If unsure, say `N'.
+       select NETFILTER_XT_CONNMARK
+       ---help---
+       This is a backwards-compat option for the user's convenience
+       (e.g. when running oldconfig). It selects
+       CONFIG_NETFILTER_XT_CONNMARK (combined connmark/CONNMARK module).
 
 config NETFILTER_XT_MATCH_CONNTRACK
        tristate '"conntrack" connection tracking match support'
@@ -733,13 +764,12 @@ config NETFILTER_XT_MATCH_MAC
 
 config NETFILTER_XT_MATCH_MARK
        tristate '"mark" match support'
-       default m if NETFILTER_ADVANCED=n
-       help
-         Netfilter mark matching allows you to match packets based on the
-         `nfmark' value in the packet.  This can be set by the MARK target
-         (see below).
-
-         To compile it as a module, choose M here.  If unsure, say N.
+       depends on NETFILTER_ADVANCED
+       select NETFILTER_XT_MARK
+       ---help---
+       This is a backwards-compat option for the user's convenience
+       (e.g. when running oldconfig). It selects
+       CONFIG_NETFILTER_XT_MARK (combined mark/MARK module).
 
 config NETFILTER_XT_MATCH_MULTIPORT
        tristate '"multiport" Multiple port match support'
@@ -751,6 +781,19 @@ config NETFILTER_XT_MATCH_MULTIPORT
 
          To compile it as a module, choose M here.  If unsure, say N.
 
+config NETFILTER_XT_MATCH_OSF
+       tristate '"osf" Passive OS fingerprint match'
+       depends on NETFILTER_ADVANCED && NETFILTER_NETLINK
+       help
+         This option selects the Passive OS Fingerprinting match module
+         that allows to passively match the remote operating system by
+         analyzing incoming TCP SYN packets.
+
+         Rules and loading software can be downloaded from
+         http://www.ioremap.net/projects/osf
+
+         To compile it as a module, choose M here.  If unsure, say N.
+
 config NETFILTER_XT_MATCH_OWNER
        tristate '"owner" match support'
        depends on NETFILTER_ADVANCED
@@ -836,13 +879,6 @@ config NETFILTER_XT_MATCH_RECENT
        Short options are available by using 'iptables -m recent -h'
        Official Website: <http://snowman.net/projects/ipt_recent/>
 
-config NETFILTER_XT_MATCH_RECENT_PROC_COMPAT
-       bool 'Enable obsolete /proc/net/ipt_recent'
-       depends on NETFILTER_XT_MATCH_RECENT && PROC_FS
-       ---help---
-       This option enables the old /proc/net/ipt_recent interface,
-       which has been obsoleted by /proc/net/xt_recent.
-
 config NETFILTER_XT_MATCH_SCTP
        tristate  '"sctp" protocol match support (EXPERIMENTAL)'
        depends on EXPERIMENTAL
@@ -942,19 +978,6 @@ config NETFILTER_XT_MATCH_U32
 
          Details and examples are in the kernel module source.
 
-config NETFILTER_XT_MATCH_OSF
-       tristate '"osf" Passive OS fingerprint match'
-       depends on NETFILTER_ADVANCED && NETFILTER_NETLINK
-       help
-         This option selects the Passive OS Fingerprinting match module
-         that allows to passively match the remote operating system by
-         analyzing incoming TCP SYN packets.
-
-         Rules and loading software can be downloaded from
-         http://www.ioremap.net/projects/osf
-
-         To compile it as a module, choose M here.  If unsure, say N.
-
 endif # NETFILTER_XTABLES
 
 endmenu
index f873644..14e3a8f 100644 (file)
@@ -40,15 +40,17 @@ obj-$(CONFIG_NETFILTER_TPROXY) += nf_tproxy_core.o
 # generic X tables 
 obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o
 
+# combos
+obj-$(CONFIG_NETFILTER_XT_MARK) += xt_mark.o
+obj-$(CONFIG_NETFILTER_XT_CONNMARK) += xt_connmark.o
+
 # targets
 obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIFY) += xt_CLASSIFY.o
-obj-$(CONFIG_NETFILTER_XT_TARGET_CONNMARK) += xt_CONNMARK.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
-obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o
@@ -57,6 +59,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_TPROXY) += xt_TPROXY.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP) += xt_TCPOPTSTRIP.o
+obj-$(CONFIG_NETFILTER_XT_TARGET_TEE) += xt_TEE.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o
 
 # matches
@@ -64,7 +67,6 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_CLUSTER) += xt_cluster.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_COMMENT) += xt_comment.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_CONNBYTES) += xt_connbytes.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_CONNLIMIT) += xt_connlimit.o
-obj-$(CONFIG_NETFILTER_XT_MATCH_CONNMARK) += xt_connmark.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_CONNTRACK) += xt_conntrack.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_DCCP) += xt_dccp.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_DSCP) += xt_dscp.o
@@ -76,7 +78,6 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_IPRANGE) += xt_iprange.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_LENGTH) += xt_length.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_LIMIT) += xt_limit.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_MAC) += xt_mac.o
-obj-$(CONFIG_NETFILTER_XT_MATCH_MARK) += xt_mark.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_MULTIPORT) += xt_multiport.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_OSF) += xt_osf.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_OWNER) += xt_owner.o
index 2c7f185..2ae747a 100644 (file)
@@ -209,8 +209,14 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
                 */
                from.ip = n_cp->vaddr.ip;
                port = n_cp->vport;
-               sprintf(buf, "%u,%u,%u,%u,%u,%u", NIPQUAD(from.ip),
-                       (ntohs(port)>>8)&255, ntohs(port)&255);
+               snprintf(buf, sizeof(buf), "%u,%u,%u,%u,%u,%u",
+                        ((unsigned char *)&from.ip)[0],
+                        ((unsigned char *)&from.ip)[1],
+                        ((unsigned char *)&from.ip)[2],
+                        ((unsigned char *)&from.ip)[3],
+                        ntohs(port) >> 8,
+                        ntohs(port) & 0xFF);
+
                buf_len = strlen(buf);
 
                /*
index 7fc49f4..2d3d5e4 100644 (file)
@@ -167,26 +167,24 @@ ip_vs_tcpudp_debug_packet_v4(struct ip_vs_protocol *pp,
 
        ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
        if (ih == NULL)
-               sprintf(buf, "%s TRUNCATED", pp->name);
+               sprintf(buf, "TRUNCATED");
        else if (ih->frag_off & htons(IP_OFFSET))
-               sprintf(buf, "%s %pI4->%pI4 frag",
-                       pp->name, &ih->saddr, &ih->daddr);
+               sprintf(buf, "%pI4->%pI4 frag", &ih->saddr, &ih->daddr);
        else {
                __be16 _ports[2], *pptr
 ;
                pptr = skb_header_pointer(skb, offset + ih->ihl*4,
                                          sizeof(_ports), _ports);
                if (pptr == NULL)
-                       sprintf(buf, "%s TRUNCATED %pI4->%pI4",
-                               pp->name, &ih->saddr, &ih->daddr);
+                       sprintf(buf, "TRUNCATED %pI4->%pI4",
+                               &ih->saddr, &ih->daddr);
                else
-                       sprintf(buf, "%s %pI4:%u->%pI4:%u",
-                               pp->name,
+                       sprintf(buf, "%pI4:%u->%pI4:%u",
                                &ih->saddr, ntohs(pptr[0]),
                                &ih->daddr, ntohs(pptr[1]));
        }
 
-       pr_debug("%s: %s\n", msg, buf);
+       pr_debug("%s: %s %s\n", msg, pp->name, buf);
 }
 
 #ifdef CONFIG_IP_VS_IPV6
@@ -201,26 +199,24 @@ ip_vs_tcpudp_debug_packet_v6(struct ip_vs_protocol *pp,
 
        ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
        if (ih == NULL)
-               sprintf(buf, "%s TRUNCATED", pp->name);
+               sprintf(buf, "TRUNCATED");
        else if (ih->nexthdr == IPPROTO_FRAGMENT)
-               sprintf(buf, "%s %pI6->%pI6 frag",
-                       pp->name, &ih->saddr, &ih->daddr);
+               sprintf(buf, "%pI6->%pI6 frag", &ih->saddr, &ih->daddr);
        else {
                __be16 _ports[2], *pptr;
 
                pptr = skb_header_pointer(skb, offset + sizeof(struct ipv6hdr),
                                          sizeof(_ports), _ports);
                if (pptr == NULL)
-                       sprintf(buf, "%s TRUNCATED %pI6->%pI6",
-                               pp->name, &ih->saddr, &ih->daddr);
+                       sprintf(buf, "TRUNCATED %pI6->%pI6",
+                               &ih->saddr, &ih->daddr);
                else
-                       sprintf(buf, "%s %pI6:%u->%pI6:%u",
-                               pp->name,
+                       sprintf(buf, "%pI6:%u->%pI6:%u",
                                &ih->saddr, ntohs(pptr[0]),
                                &ih->daddr, ntohs(pptr[1]));
        }
 
-       pr_debug("%s: %s\n", msg, buf);
+       pr_debug("%s: %s %s\n", msg, pp->name, buf);
 }
 #endif
 
index c30b43c..1892dfc 100644 (file)
@@ -136,12 +136,11 @@ ah_esp_debug_packet_v4(struct ip_vs_protocol *pp, const struct sk_buff *skb,
 
        ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
        if (ih == NULL)
-               sprintf(buf, "%s TRUNCATED", pp->name);
+               sprintf(buf, "TRUNCATED");
        else
-               sprintf(buf, "%s %pI4->%pI4",
-                       pp->name, &ih->saddr, &ih->daddr);
+               sprintf(buf, "%pI4->%pI4", &ih->saddr, &ih->daddr);
 
-       pr_debug("%s: %s\n", msg, buf);
+       pr_debug("%s: %s %s\n", msg, pp->name, buf);
 }
 
 #ifdef CONFIG_IP_VS_IPV6
@@ -154,12 +153,11 @@ ah_esp_debug_packet_v6(struct ip_vs_protocol *pp, const struct sk_buff *skb,
 
        ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
        if (ih == NULL)
-               sprintf(buf, "%s TRUNCATED", pp->name);
+               sprintf(buf, "TRUNCATED");
        else
-               sprintf(buf, "%s %pI6->%pI6",
-                       pp->name, &ih->saddr, &ih->daddr);
+               sprintf(buf, "%pI6->%pI6", &ih->saddr, &ih->daddr);
 
-       pr_debug("%s: %s\n", msg, buf);
+       pr_debug("%s: %s %s\n", msg, pp->name, buf);
 }
 #endif
 
index e450cd6..93c15a1 100644 (file)
@@ -270,7 +270,7 @@ ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
        /* Another hack: avoid icmp_send in ip_fragment */
        skb->local_df = 1;
 
-       IP_VS_XMIT(PF_INET, skb, rt);
+       IP_VS_XMIT(NFPROTO_IPV4, skb, rt);
 
        LeaveFunction(10);
        return NF_STOLEN;
@@ -334,7 +334,7 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
        /* Another hack: avoid icmp_send in ip_fragment */
        skb->local_df = 1;
 
-       IP_VS_XMIT(PF_INET6, skb, rt);
+       IP_VS_XMIT(NFPROTO_IPV6, skb, rt);
 
        LeaveFunction(10);
        return NF_STOLEN;
@@ -410,7 +410,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
        /* Another hack: avoid icmp_send in ip_fragment */
        skb->local_df = 1;
 
-       IP_VS_XMIT(PF_INET, skb, rt);
+       IP_VS_XMIT(NFPROTO_IPV4, skb, rt);
 
        LeaveFunction(10);
        return NF_STOLEN;
@@ -486,7 +486,7 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
        /* Another hack: avoid icmp_send in ip_fragment */
        skb->local_df = 1;
 
-       IP_VS_XMIT(PF_INET6, skb, rt);
+       IP_VS_XMIT(NFPROTO_IPV6, skb, rt);
 
        LeaveFunction(10);
        return NF_STOLEN;
@@ -785,7 +785,7 @@ ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
        /* Another hack: avoid icmp_send in ip_fragment */
        skb->local_df = 1;
 
-       IP_VS_XMIT(PF_INET, skb, rt);
+       IP_VS_XMIT(NFPROTO_IPV4, skb, rt);
 
        LeaveFunction(10);
        return NF_STOLEN;
@@ -838,7 +838,7 @@ ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
        /* Another hack: avoid icmp_send in ip_fragment */
        skb->local_df = 1;
 
-       IP_VS_XMIT(PF_INET6, skb, rt);
+       IP_VS_XMIT(NFPROTO_IPV6, skb, rt);
 
        LeaveFunction(10);
        return NF_STOLEN;
@@ -912,7 +912,7 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
        /* Another hack: avoid icmp_send in ip_fragment */
        skb->local_df = 1;
 
-       IP_VS_XMIT(PF_INET, skb, rt);
+       IP_VS_XMIT(NFPROTO_IPV4, skb, rt);
 
        rc = NF_STOLEN;
        goto out;
@@ -987,7 +987,7 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
        /* Another hack: avoid icmp_send in ip_fragment */
        skb->local_df = 1;
 
-       IP_VS_XMIT(PF_INET6, skb, rt);
+       IP_VS_XMIT(NFPROTO_IPV6, skb, rt);
 
        rc = NF_STOLEN;
        goto out;
index f516961..a94ac3a 100644 (file)
@@ -82,11 +82,9 @@ EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events);
 int nf_conntrack_register_notifier(struct nf_ct_event_notifier *new)
 {
        int ret = 0;
-       struct nf_ct_event_notifier *notify;
 
        mutex_lock(&nf_ct_ecache_mutex);
-       notify = rcu_dereference(nf_conntrack_event_cb);
-       if (notify != NULL) {
+       if (nf_conntrack_event_cb != NULL) {
                ret = -EBUSY;
                goto out_unlock;
        }
@@ -102,11 +100,8 @@ EXPORT_SYMBOL_GPL(nf_conntrack_register_notifier);
 
 void nf_conntrack_unregister_notifier(struct nf_ct_event_notifier *new)
 {
-       struct nf_ct_event_notifier *notify;
-
        mutex_lock(&nf_ct_ecache_mutex);
-       notify = rcu_dereference(nf_conntrack_event_cb);
-       BUG_ON(notify != new);
+       BUG_ON(nf_conntrack_event_cb != new);
        rcu_assign_pointer(nf_conntrack_event_cb, NULL);
        mutex_unlock(&nf_ct_ecache_mutex);
 }
@@ -115,11 +110,9 @@ EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier);
 int nf_ct_expect_register_notifier(struct nf_exp_event_notifier *new)
 {
        int ret = 0;
-       struct nf_exp_event_notifier *notify;
 
        mutex_lock(&nf_ct_ecache_mutex);
-       notify = rcu_dereference(nf_expect_event_cb);
-       if (notify != NULL) {
+       if (nf_expect_event_cb != NULL) {
                ret = -EBUSY;
                goto out_unlock;
        }
@@ -135,11 +128,8 @@ EXPORT_SYMBOL_GPL(nf_ct_expect_register_notifier);
 
 void nf_ct_expect_unregister_notifier(struct nf_exp_event_notifier *new)
 {
-       struct nf_exp_event_notifier *notify;
-
        mutex_lock(&nf_ct_ecache_mutex);
-       notify = rcu_dereference(nf_expect_event_cb);
-       BUG_ON(notify != new);
+       BUG_ON(nf_expect_event_cb != new);
        rcu_assign_pointer(nf_expect_event_cb, NULL);
        mutex_unlock(&nf_ct_ecache_mutex);
 }
index afc52f2..4e55403 100644 (file)
@@ -426,6 +426,17 @@ ctnetlink_proto_size(const struct nf_conn *ct)
        return len;
 }
 
+static inline size_t
+ctnetlink_counters_size(const struct nf_conn *ct)
+{
+       if (!nf_ct_ext_exist(ct, NF_CT_EXT_ACCT))
+               return 0;
+       return 2 * nla_total_size(0) /* CTA_COUNTERS_ORIG|REPL */
+              + 2 * nla_total_size(sizeof(uint64_t)) /* CTA_COUNTERS_PACKETS */
+              + 2 * nla_total_size(sizeof(uint64_t)) /* CTA_COUNTERS_BYTES */
+              ;
+}
+
 static inline size_t
 ctnetlink_nlmsg_size(const struct nf_conn *ct)
 {
@@ -436,11 +447,7 @@ ctnetlink_nlmsg_size(const struct nf_conn *ct)
               + 3 * nla_total_size(sizeof(u_int8_t)) /* CTA_PROTO_NUM */
               + nla_total_size(sizeof(u_int32_t)) /* CTA_ID */
               + nla_total_size(sizeof(u_int32_t)) /* CTA_STATUS */
-#ifdef CONFIG_NF_CT_ACCT
-              + 2 * nla_total_size(0) /* CTA_COUNTERS_ORIG|REPL */
-              + 2 * nla_total_size(sizeof(uint64_t)) /* CTA_COUNTERS_PACKETS */
-              + 2 * nla_total_size(sizeof(uint64_t)) /* CTA_COUNTERS_BYTES */
-#endif
+              + ctnetlink_counters_size(ct)
               + nla_total_size(sizeof(u_int32_t)) /* CTA_TIMEOUT */
               + nla_total_size(0) /* CTA_PROTOINFO */
               + nla_total_size(0) /* CTA_HELP */
index a44fa75..a6defc7 100644 (file)
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/mutex.h>
-#include <linux/skbuff.h>
 #include <linux/vmalloc.h>
 #include <linux/stddef.h>
 #include <linux/err.h>
 #include <linux/percpu.h>
-#include <linux/moduleparam.h>
 #include <linux/notifier.h>
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
index 015725a..908f599 100644 (file)
@@ -35,7 +35,6 @@ static struct nf_logger *__find_logger(int pf, const char *str_logger)
 /* return EEXIST if the same logger is registred, 0 on success. */
 int nf_log_register(u_int8_t pf, struct nf_logger *logger)
 {
-       const struct nf_logger *llog;
        int i;
 
        if (pf >= ARRAY_SIZE(nf_loggers))
@@ -52,8 +51,7 @@ int nf_log_register(u_int8_t pf, struct nf_logger *logger)
        } else {
                /* register at end of list to honor first register win */
                list_add_tail(&logger->list[pf], &nf_loggers_l[pf]);
-               llog = rcu_dereference(nf_loggers[pf]);
-               if (llog == NULL)
+               if (nf_loggers[pf] == NULL)
                        rcu_assign_pointer(nf_loggers[pf], logger);
        }
 
@@ -65,13 +63,11 @@ EXPORT_SYMBOL(nf_log_register);
 
 void nf_log_unregister(struct nf_logger *logger)
 {
-       const struct nf_logger *c_logger;
        int i;
 
        mutex_lock(&nf_log_mutex);
        for (i = 0; i < ARRAY_SIZE(nf_loggers); i++) {
-               c_logger = rcu_dereference(nf_loggers[i]);
-               if (c_logger == logger)
+               if (nf_loggers[i] == logger)
                        rcu_assign_pointer(nf_loggers[i], NULL);
                list_del(&logger->list[i]);
        }
index 6afa3d5..39b0e31 100644 (file)
 #include <linux/types.h>
 #include <linux/socket.h>
 #include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/timer.h>
 #include <linux/string.h>
 #include <linux/sockios.h>
 #include <linux/net.h>
-#include <linux/fcntl.h>
 #include <linux/skbuff.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
index e70a6ef..12e1ab3 100644 (file)
@@ -246,8 +246,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
                break;
 
        case NFQNL_COPY_PACKET:
-               if ((entskb->ip_summed == CHECKSUM_PARTIAL ||
-                    entskb->ip_summed == CHECKSUM_COMPLETE) &&
+               if (entskb->ip_summed == CHECKSUM_PARTIAL &&
                    skb_checksum_help(entskb)) {
                        spin_unlock_bh(&queue->lock);
                        return NULL;
index 665f5be..3ae3234 100644 (file)
@@ -12,7 +12,7 @@
  * published by the Free Software Foundation.
  *
  */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/kernel.h>
 #include <linux/socket.h>
 #include <linux/net.h>
@@ -55,12 +55,6 @@ struct xt_af {
 
 static struct xt_af *xt;
 
-#ifdef DEBUG_IP_FIREWALL_USER
-#define duprintf(format, args...) printk(format , ## args)
-#else
-#define duprintf(format, args...)
-#endif
-
 static const char *const xt_prefix[NFPROTO_NUMPROTO] = {
        [NFPROTO_UNSPEC] = "x",
        [NFPROTO_IPV4]   = "ip",
@@ -69,6 +63,9 @@ static const char *const xt_prefix[NFPROTO_NUMPROTO] = {
        [NFPROTO_IPV6]   = "ip6",
 };
 
+/* Allow this many total (re)entries. */
+static const unsigned int xt_jumpstack_multiplier = 2;
+
 /* Registration hooks for targets. */
 int
 xt_register_target(struct xt_target *target)
@@ -221,6 +218,17 @@ struct xt_match *xt_find_match(u8 af, const char *name, u8 revision)
 }
 EXPORT_SYMBOL(xt_find_match);
 
+struct xt_match *
+xt_request_find_match(uint8_t nfproto, const char *name, uint8_t revision)
+{
+       struct xt_match *match;
+
+       match = try_then_request_module(xt_find_match(nfproto, name, revision),
+                                       "%st_%s", xt_prefix[nfproto], name);
+       return (match != NULL) ? match : ERR_PTR(-ENOENT);
+}
+EXPORT_SYMBOL_GPL(xt_request_find_match);
+
 /* Find target, grabs ref.  Returns ERR_PTR() on error. */
 struct xt_target *xt_find_target(u8 af, const char *name, u8 revision)
 {
@@ -257,9 +265,7 @@ struct xt_target *xt_request_find_target(u8 af, const char *name, u8 revision)
 
        target = try_then_request_module(xt_find_target(af, name, revision),
                                         "%st_%s", xt_prefix[af], name);
-       if (IS_ERR(target) || !target)
-               return NULL;
-       return target;
+       return (target != NULL) ? target : ERR_PTR(-ENOENT);
 }
 EXPORT_SYMBOL_GPL(xt_request_find_target);
 
@@ -361,6 +367,8 @@ static char *textify_hooks(char *buf, size_t size, unsigned int mask)
 int xt_check_match(struct xt_mtchk_param *par,
                   unsigned int size, u_int8_t proto, bool inv_proto)
 {
+       int ret;
+
        if (XT_ALIGN(par->match->matchsize) != size &&
            par->match->matchsize != -1) {
                /*
@@ -397,8 +405,14 @@ int xt_check_match(struct xt_mtchk_param *par,
                       par->match->proto);
                return -EINVAL;
        }
-       if (par->match->checkentry != NULL && !par->match->checkentry(par))
-               return -EINVAL;
+       if (par->match->checkentry != NULL) {
+               ret = par->match->checkentry(par);
+               if (ret < 0)
+                       return ret;
+               else if (ret > 0)
+                       /* Flag up potential errors. */
+                       return -EIO;
+       }
        return 0;
 }
 EXPORT_SYMBOL_GPL(xt_check_match);
@@ -518,6 +532,8 @@ EXPORT_SYMBOL_GPL(xt_compat_match_to_user);
 int xt_check_target(struct xt_tgchk_param *par,
                    unsigned int size, u_int8_t proto, bool inv_proto)
 {
+       int ret;
+
        if (XT_ALIGN(par->target->targetsize) != size) {
                pr_err("%s_tables: %s.%u target: invalid size "
                       "%u (kernel) != (user) %u\n",
@@ -549,8 +565,14 @@ int xt_check_target(struct xt_tgchk_param *par,
                       par->target->proto);
                return -EINVAL;
        }
-       if (par->target->checkentry != NULL && !par->target->checkentry(par))
-               return -EINVAL;
+       if (par->target->checkentry != NULL) {
+               ret = par->target->checkentry(par);
+               if (ret < 0)
+                       return ret;
+               else if (ret > 0)
+                       /* Flag up potential errors. */
+                       return -EIO;
+       }
        return 0;
 }
 EXPORT_SYMBOL_GPL(xt_check_target);
@@ -662,6 +684,26 @@ void xt_free_table_info(struct xt_table_info *info)
                else
                        vfree(info->entries[cpu]);
        }
+
+       if (info->jumpstack != NULL) {
+               if (sizeof(void *) * info->stacksize > PAGE_SIZE) {
+                       for_each_possible_cpu(cpu)
+                               vfree(info->jumpstack[cpu]);
+               } else {
+                       for_each_possible_cpu(cpu)
+                               kfree(info->jumpstack[cpu]);
+               }
+       }
+
+       if (sizeof(void **) * nr_cpu_ids > PAGE_SIZE)
+               vfree(info->jumpstack);
+       else
+               kfree(info->jumpstack);
+       if (sizeof(unsigned int) * nr_cpu_ids > PAGE_SIZE)
+               vfree(info->stackptr);
+       else
+               kfree(info->stackptr);
+
        kfree(info);
 }
 EXPORT_SYMBOL(xt_free_table_info);
@@ -706,6 +748,49 @@ EXPORT_SYMBOL_GPL(xt_compat_unlock);
 DEFINE_PER_CPU(struct xt_info_lock, xt_info_locks);
 EXPORT_PER_CPU_SYMBOL_GPL(xt_info_locks);
 
+static int xt_jumpstack_alloc(struct xt_table_info *i)
+{
+       unsigned int size;
+       int cpu;
+
+       size = sizeof(unsigned int) * nr_cpu_ids;
+       if (size > PAGE_SIZE)
+               i->stackptr = vmalloc(size);
+       else
+               i->stackptr = kmalloc(size, GFP_KERNEL);
+       if (i->stackptr == NULL)
+               return -ENOMEM;
+       memset(i->stackptr, 0, size);
+
+       size = sizeof(void **) * nr_cpu_ids;
+       if (size > PAGE_SIZE)
+               i->jumpstack = vmalloc(size);
+       else
+               i->jumpstack = kmalloc(size, GFP_KERNEL);
+       if (i->jumpstack == NULL)
+               return -ENOMEM;
+       memset(i->jumpstack, 0, size);
+
+       i->stacksize *= xt_jumpstack_multiplier;
+       size = sizeof(void *) * i->stacksize;
+       for_each_possible_cpu(cpu) {
+               if (size > PAGE_SIZE)
+                       i->jumpstack[cpu] = vmalloc_node(size,
+                               cpu_to_node(cpu));
+               else
+                       i->jumpstack[cpu] = kmalloc_node(size,
+                               GFP_KERNEL, cpu_to_node(cpu));
+               if (i->jumpstack[cpu] == NULL)
+                       /*
+                        * Freeing will be done later on by the callers. The
+                        * chain is: xt_replace_table -> __do_replace ->
+                        * do_replace -> xt_free_table_info.
+                        */
+                       return -ENOMEM;
+       }
+
+       return 0;
+}
 
 struct xt_table_info *
 xt_replace_table(struct xt_table *table,
@@ -714,6 +799,7 @@ xt_replace_table(struct xt_table *table,
              int *error)
 {
        struct xt_table_info *private;
+       int ret;
 
        /* Do the substitution. */
        local_bh_disable();
@@ -721,13 +807,19 @@ xt_replace_table(struct xt_table *table,
 
        /* Check inside lock: is the old number correct? */
        if (num_counters != private->number) {
-               duprintf("num_counters != table->private->number (%u/%u)\n",
+               pr_debug("num_counters != table->private->number (%u/%u)\n",
                         num_counters, private->number);
                local_bh_enable();
                *error = -EAGAIN;
                return NULL;
        }
 
+       ret = xt_jumpstack_alloc(newinfo);
+       if (ret < 0) {
+               *error = ret;
+               return NULL;
+       }
+
        table->private = newinfo;
        newinfo->initial_entries = private->initial_entries;
 
@@ -752,6 +844,10 @@ struct xt_table *xt_register_table(struct net *net,
        struct xt_table_info *private;
        struct xt_table *t, *table;
 
+       ret = xt_jumpstack_alloc(newinfo);
+       if (ret < 0)
+               return ERR_PTR(ret);
+
        /* Don't add one object to multiple lists. */
        table = kmemdup(input_table, sizeof(struct xt_table), GFP_KERNEL);
        if (!table) {
@@ -778,7 +874,7 @@ struct xt_table *xt_register_table(struct net *net,
                goto unlock;
 
        private = table->private;
-       duprintf("table->private->number = %u\n", private->number);
+       pr_debug("table->private->number = %u\n", private->number);
 
        /* save number of initial entries */
        private->initial_entries = private->number;
diff --git a/net/netfilter/xt_CONNMARK.c b/net/netfilter/xt_CONNMARK.c
deleted file mode 100644 (file)
index 5934570..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- *     xt_CONNMARK - Netfilter module to modify the connection mark values
- *
- *     Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
- *     by Henrik Nordstrom <hno@marasystems.com>
- *     Copyright © CC Computer Consultants GmbH, 2007 - 2008
- *     Jan Engelhardt <jengelh@computergmbh.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <linux/module.h>
-#include <linux/skbuff.h>
-#include <linux/ip.h>
-#include <net/checksum.h>
-
-MODULE_AUTHOR("Henrik Nordstrom <hno@marasystems.com>");
-MODULE_DESCRIPTION("Xtables: connection mark modification");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("ipt_CONNMARK");
-MODULE_ALIAS("ip6t_CONNMARK");
-
-#include <linux/netfilter/x_tables.h>
-#include <linux/netfilter/xt_CONNMARK.h>
-#include <net/netfilter/nf_conntrack_ecache.h>
-
-static unsigned int
-connmark_tg(struct sk_buff *skb, const struct xt_target_param *par)
-{
-       const struct xt_connmark_tginfo1 *info = par->targinfo;
-       enum ip_conntrack_info ctinfo;
-       struct nf_conn *ct;
-       u_int32_t newmark;
-
-       ct = nf_ct_get(skb, &ctinfo);
-       if (ct == NULL)
-               return XT_CONTINUE;
-
-       switch (info->mode) {
-       case XT_CONNMARK_SET:
-               newmark = (ct->mark & ~info->ctmask) ^ info->ctmark;
-               if (ct->mark != newmark) {
-                       ct->mark = newmark;
-                       nf_conntrack_event_cache(IPCT_MARK, ct);
-               }
-               break;
-       case XT_CONNMARK_SAVE:
-               newmark = (ct->mark & ~info->ctmask) ^
-                         (skb->mark & info->nfmask);
-               if (ct->mark != newmark) {
-                       ct->mark = newmark;
-                       nf_conntrack_event_cache(IPCT_MARK, ct);
-               }
-               break;
-       case XT_CONNMARK_RESTORE:
-               newmark = (skb->mark & ~info->nfmask) ^
-                         (ct->mark & info->ctmask);
-               skb->mark = newmark;
-               break;
-       }
-
-       return XT_CONTINUE;
-}
-
-static bool connmark_tg_check(const struct xt_tgchk_param *par)
-{
-       if (nf_ct_l3proto_try_module_get(par->family) < 0) {
-               printk(KERN_WARNING "cannot load conntrack support for "
-                      "proto=%u\n", par->family);
-               return false;
-       }
-       return true;
-}
-
-static void connmark_tg_destroy(const struct xt_tgdtor_param *par)
-{
-       nf_ct_l3proto_module_put(par->family);
-}
-
-static struct xt_target connmark_tg_reg __read_mostly = {
-       .name           = "CONNMARK",
-       .revision       = 1,
-       .family         = NFPROTO_UNSPEC,
-       .checkentry     = connmark_tg_check,
-       .target         = connmark_tg,
-       .targetsize     = sizeof(struct xt_connmark_tginfo1),
-       .destroy        = connmark_tg_destroy,
-       .me             = THIS_MODULE,
-};
-
-static int __init connmark_tg_init(void)
-{
-       return xt_register_target(&connmark_tg_reg);
-}
-
-static void __exit connmark_tg_exit(void)
-{
-       xt_unregister_target(&connmark_tg_reg);
-}
-
-module_init(connmark_tg_init);
-module_exit(connmark_tg_exit);
index b54c375..e953e30 100644 (file)
@@ -15,6 +15,7 @@
  * published by the Free Software Foundation.
  *
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/netfilter/x_tables.h>
@@ -22,8 +23,6 @@
 #include <net/netfilter/nf_conntrack.h>
 #include <net/netfilter/nf_conntrack_ecache.h>
 
-#define PFX "CONNSECMARK: "
-
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("James Morris <jmorris@redhat.com>");
 MODULE_DESCRIPTION("Xtables: target for copying between connection and security mark");
@@ -85,15 +84,16 @@ connsecmark_tg(struct sk_buff *skb, const struct xt_target_param *par)
        return XT_CONTINUE;
 }
 
-static bool connsecmark_tg_check(const struct xt_tgchk_param *par)
+static int connsecmark_tg_check(const struct xt_tgchk_param *par)
 {
        const struct xt_connsecmark_target_info *info = par->targinfo;
+       int ret;
 
        if (strcmp(par->table, "mangle") != 0 &&
            strcmp(par->table, "security") != 0) {
-               printk(KERN_INFO PFX "target only valid in the \'mangle\' "
-                      "or \'security\' tables, not \'%s\'.\n", par->table);
-               return false;
+               pr_info("target only valid in the \'mangle\' "
+                       "or \'security\' tables, not \'%s\'.\n", par->table);
+               return -EINVAL;
        }
 
        switch (info->mode) {
@@ -102,16 +102,15 @@ static bool connsecmark_tg_check(const struct xt_tgchk_param *par)
                break;
 
        default:
-               printk(KERN_INFO PFX "invalid mode: %hu\n", info->mode);
-               return false;
+               pr_info("invalid mode: %hu\n", info->mode);
+               return -EINVAL;
        }
 
-       if (nf_ct_l3proto_try_module_get(par->family) < 0) {
-               printk(KERN_WARNING "can't load conntrack support for "
-                                   "proto=%u\n", par->family);
-               return false;
-       }
-       return true;
+       ret = nf_ct_l3proto_try_module_get(par->family);
+       if (ret < 0)
+               pr_info("cannot load conntrack support for proto=%u\n",
+                       par->family);
+       return ret;
 }
 
 static void connsecmark_tg_destroy(const struct xt_tgdtor_param *par)
index ee18b23..c8f5478 100644 (file)
@@ -38,13 +38,13 @@ static unsigned int xt_ct_target(struct sk_buff *skb,
 
 static u8 xt_ct_find_proto(const struct xt_tgchk_param *par)
 {
-       if (par->family == AF_INET) {
+       if (par->family == NFPROTO_IPV4) {
                const struct ipt_entry *e = par->entryinfo;
 
                if (e->ip.invflags & IPT_INV_PROTO)
                        return 0;
                return e->ip.proto;
-       } else if (par->family == AF_INET6) {
+       } else if (par->family == NFPROTO_IPV6) {
                const struct ip6t_entry *e = par->entryinfo;
 
                if (e->ipv6.invflags & IP6T_INV_PROTO)
@@ -54,16 +54,17 @@ static u8 xt_ct_find_proto(const struct xt_tgchk_param *par)
                return 0;
 }
 
-static bool xt_ct_tg_check(const struct xt_tgchk_param *par)
+static int xt_ct_tg_check(const struct xt_tgchk_param *par)
 {
        struct xt_ct_target_info *info = par->targinfo;
        struct nf_conntrack_tuple t;
        struct nf_conn_help *help;
        struct nf_conn *ct;
+       int ret = 0;
        u8 proto;
 
        if (info->flags & ~XT_CT_NOTRACK)
-               return false;
+               return -EINVAL;
 
        if (info->flags & XT_CT_NOTRACK) {
                ct = &nf_conntrack_untracked;
@@ -76,28 +77,34 @@ static bool xt_ct_tg_check(const struct xt_tgchk_param *par)
                goto err1;
 #endif
 
-       if (nf_ct_l3proto_try_module_get(par->family) < 0)
+       ret = nf_ct_l3proto_try_module_get(par->family);
+       if (ret < 0)
                goto err1;
 
        memset(&t, 0, sizeof(t));
        ct = nf_conntrack_alloc(par->net, info->zone, &t, &t, GFP_KERNEL);
+       ret = PTR_ERR(ct);
        if (IS_ERR(ct))
                goto err2;
 
+       ret = 0;
        if ((info->ct_events || info->exp_events) &&
            !nf_ct_ecache_ext_add(ct, info->ct_events, info->exp_events,
                                  GFP_KERNEL))
                goto err3;
 
        if (info->helper[0]) {
+               ret = -ENOENT;
                proto = xt_ct_find_proto(par);
                if (!proto)
                        goto err3;
 
+               ret = -ENOMEM;
                help = nf_ct_helper_ext_add(ct, GFP_KERNEL);
                if (help == NULL)
                        goto err3;
 
+               ret = -ENOENT;
                help->helper = nf_conntrack_helper_try_module_get(info->helper,
                                                                  par->family,
                                                                  proto);
@@ -109,14 +116,14 @@ static bool xt_ct_tg_check(const struct xt_tgchk_param *par)
        __set_bit(IPS_CONFIRMED_BIT, &ct->status);
 out:
        info->ct = ct;
-       return true;
+       return 0;
 
 err3:
        nf_conntrack_free(ct);
 err2:
        nf_ct_l3proto_module_put(par->family);
 err1:
-       return false;
+       return ret;
 }
 
 static void xt_ct_tg_destroy(const struct xt_tgdtor_param *par)
@@ -138,7 +145,7 @@ static void xt_ct_tg_destroy(const struct xt_tgdtor_param *par)
 static struct xt_target xt_ct_tg __read_mostly = {
        .name           = "CT",
        .family         = NFPROTO_UNSPEC,
-       .targetsize     = XT_ALIGN(sizeof(struct xt_ct_target_info)),
+       .targetsize     = sizeof(struct xt_ct_target_info),
        .checkentry     = xt_ct_tg_check,
        .destroy        = xt_ct_tg_destroy,
        .target         = xt_ct_target,
index 74ce892..969634f 100644 (file)
@@ -9,7 +9,7 @@
  *
  * See RFC2474 for a description of the DSCP field within the IP Header.
 */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/ip.h>
@@ -60,15 +60,15 @@ dscp_tg6(struct sk_buff *skb, const struct xt_target_param *par)
        return XT_CONTINUE;
 }
 
-static bool dscp_tg_check(const struct xt_tgchk_param *par)
+static int dscp_tg_check(const struct xt_tgchk_param *par)
 {
        const struct xt_DSCP_info *info = par->targinfo;
 
        if (info->dscp > XT_DSCP_MAX) {
-               printk(KERN_WARNING "DSCP: dscp %x out of range\n", info->dscp);
-               return false;
+               pr_info("dscp %x out of range\n", info->dscp);
+               return -EDOM;
        }
-       return true;
+       return 0;
 }
 
 static unsigned int
index 10e789e..77b99f7 100644 (file)
@@ -9,7 +9,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/ip.h>
@@ -101,35 +101,33 @@ hl_tg6(struct sk_buff *skb, const struct xt_target_param *par)
        return XT_CONTINUE;
 }
 
-static bool ttl_tg_check(const struct xt_tgchk_param *par)
+static int ttl_tg_check(const struct xt_tgchk_param *par)
 {
        const struct ipt_TTL_info *info = par->targinfo;
 
        if (info->mode > IPT_TTL_MAXMODE) {
-               printk(KERN_WARNING "ipt_TTL: invalid or unknown Mode %u\n",
-                       info->mode);
-               return false;
+               pr_info("TTL: invalid or unknown mode %u\n", info->mode);
+               return -EINVAL;
        }
        if (info->mode != IPT_TTL_SET && info->ttl == 0)
-               return false;
-       return true;
+               return -EINVAL;
+       return 0;
 }
 
-static bool hl_tg6_check(const struct xt_tgchk_param *par)
+static int hl_tg6_check(const struct xt_tgchk_param *par)
 {
        const struct ip6t_HL_info *info = par->targinfo;
 
        if (info->mode > IP6T_HL_MAXMODE) {
-               printk(KERN_WARNING "ip6t_HL: invalid or unknown Mode %u\n",
-                       info->mode);
-               return false;
+               pr_info("invalid or unknown mode %u\n", info->mode);
+               return -EINVAL;
        }
        if (info->mode != IP6T_HL_SET && info->hop_limit == 0) {
-               printk(KERN_WARNING "ip6t_HL: increment/decrement doesn't "
+               pr_info("increment/decrement does not "
                        "make sense with value 0\n");
-               return false;
+               return -EINVAL;
        }
-       return true;
+       return 0;
 }
 
 static struct xt_target hl_tg_reg[] __read_mostly = {
index 3271c8e..ab6f8ff 100644 (file)
@@ -18,7 +18,7 @@
  * 02110-1301 USA.
  *
  */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/netfilter/x_tables.h>
@@ -32,12 +32,18 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Adam Nielsen <a.nielsen@shikadi.net>");
 MODULE_DESCRIPTION("Xtables: trigger LED devices on packet match");
 
+static LIST_HEAD(xt_led_triggers);
+static DEFINE_MUTEX(xt_led_mutex);
+
 /*
  * This is declared in here (the kernel module) only, to avoid having these
  * dependencies in userspace code.  This is what xt_led_info.internal_data
  * points to.
  */
 struct xt_led_info_internal {
+       struct list_head list;
+       int refcnt;
+       char *trigger_id;
        struct led_trigger netfilter_led_trigger;
        struct timer_list timer;
 };
@@ -54,7 +60,7 @@ led_tg(struct sk_buff *skb, const struct xt_target_param *par)
         */
        if ((ledinfo->delay > 0) && ledinfo->always_blink &&
            timer_pending(&ledinternal->timer))
-               led_trigger_event(&ledinternal->netfilter_led_trigger,LED_OFF);
+               led_trigger_event(&ledinternal->netfilter_led_trigger, LED_OFF);
 
        led_trigger_event(&ledinternal->netfilter_led_trigger, LED_FULL);
 
@@ -75,54 +81,86 @@ led_tg(struct sk_buff *skb, const struct xt_target_param *par)
 
 static void led_timeout_callback(unsigned long data)
 {
-       struct xt_led_info *ledinfo = (struct xt_led_info *)data;
-       struct xt_led_info_internal *ledinternal = ledinfo->internal_data;
+       struct xt_led_info_internal *ledinternal = (struct xt_led_info_internal *)data;
 
        led_trigger_event(&ledinternal->netfilter_led_trigger, LED_OFF);
 }
 
-static bool led_tg_check(const struct xt_tgchk_param *par)
+static struct xt_led_info_internal *led_trigger_lookup(const char *name)
+{
+       struct xt_led_info_internal *ledinternal;
+
+       list_for_each_entry(ledinternal, &xt_led_triggers, list) {
+               if (!strcmp(name, ledinternal->netfilter_led_trigger.name)) {
+                       return ledinternal;
+               }
+       }
+       return NULL;
+}
+
+static int led_tg_check(const struct xt_tgchk_param *par)
 {
        struct xt_led_info *ledinfo = par->targinfo;
        struct xt_led_info_internal *ledinternal;
        int err;
 
        if (ledinfo->id[0] == '\0') {
-               printk(KERN_ERR KBUILD_MODNAME ": No 'id' parameter given.\n");
-               return false;
+               pr_info("No 'id' parameter given.\n");
+               return -EINVAL;
        }
 
-       ledinternal = kzalloc(sizeof(struct xt_led_info_internal), GFP_KERNEL);
-       if (!ledinternal) {
-               printk(KERN_CRIT KBUILD_MODNAME ": out of memory\n");
-               return false;
+       mutex_lock(&xt_led_mutex);
+
+       ledinternal = led_trigger_lookup(ledinfo->id);
+       if (ledinternal) {
+               ledinternal->refcnt++;
+               goto out;
        }
 
-       ledinternal->netfilter_led_trigger.name = ledinfo->id;
+       err = -ENOMEM;
+       ledinternal = kzalloc(sizeof(struct xt_led_info_internal), GFP_KERNEL);
+       if (!ledinternal)
+               goto exit_mutex_only;
+
+       ledinternal->trigger_id = kstrdup(ledinfo->id, GFP_KERNEL);
+       if (!ledinternal->trigger_id)
+               goto exit_internal_alloc;
+
+       ledinternal->refcnt = 1;
+       ledinternal->netfilter_led_trigger.name = ledinternal->trigger_id;
 
        err = led_trigger_register(&ledinternal->netfilter_led_trigger);
        if (err) {
-               printk(KERN_CRIT KBUILD_MODNAME
-                       ": led_trigger_register() failed\n");
+               pr_warning("led_trigger_register() failed\n");
                if (err == -EEXIST)
-                       printk(KERN_ERR KBUILD_MODNAME
-                               ": Trigger name is already in use.\n");
+                       pr_warning("Trigger name is already in use.\n");
                goto exit_alloc;
        }
 
        /* See if we need to set up a timer */
        if (ledinfo->delay > 0)
                setup_timer(&ledinternal->timer, led_timeout_callback,
-                           (unsigned long)ledinfo);
+                           (unsigned long)ledinternal);
+
+       list_add_tail(&ledinternal->list, &xt_led_triggers);
+
+out:
+       mutex_unlock(&xt_led_mutex);
 
        ledinfo->internal_data = ledinternal;
 
-       return true;
+       return 0;
 
 exit_alloc:
+       kfree(ledinternal->trigger_id);
+
+exit_internal_alloc:
        kfree(ledinternal);
 
-       return false;
+exit_mutex_only:
+       mutex_unlock(&xt_led_mutex);
+
+       return err;
 }
 
 static void led_tg_destroy(const struct xt_tgdtor_param *par)
@@ -130,10 +168,23 @@ static void led_tg_destroy(const struct xt_tgdtor_param *par)
        const struct xt_led_info *ledinfo = par->targinfo;
        struct xt_led_info_internal *ledinternal = ledinfo->internal_data;
 
+       mutex_lock(&xt_led_mutex);
+
+       if (--ledinternal->refcnt) {
+               mutex_unlock(&xt_led_mutex);
+               return;
+       }
+
+       list_del(&ledinternal->list);
+
        if (ledinfo->delay > 0)
                del_timer_sync(&ledinternal->timer);
 
        led_trigger_unregister(&ledinternal->netfilter_led_trigger);
+
+       mutex_unlock(&xt_led_mutex);
+
+       kfree(ledinternal->trigger_id);
        kfree(ledinternal);
 }
 
@@ -142,7 +193,7 @@ static struct xt_target led_tg_reg __read_mostly = {
        .revision       = 0,
        .family         = NFPROTO_UNSPEC,
        .target         = led_tg,
-       .targetsize     = XT_ALIGN(sizeof(struct xt_led_info)),
+       .targetsize     = sizeof(struct xt_led_info),
        .checkentry     = led_tg_check,
        .destroy        = led_tg_destroy,
        .me             = THIS_MODULE,
diff --git a/net/netfilter/xt_MARK.c b/net/netfilter/xt_MARK.c
deleted file mode 100644 (file)
index 225f8d1..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- *     xt_MARK - Netfilter module to modify the NFMARK field of an skb
- *
- *     (C) 1999-2001 Marc Boucher <marc@mbsi.ca>
- *     Copyright © CC Computer Consultants GmbH, 2007 - 2008
- *     Jan Engelhardt <jengelh@computergmbh.de>
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License version 2 as
- *     published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/skbuff.h>
-#include <linux/ip.h>
-#include <net/checksum.h>
-
-#include <linux/netfilter/x_tables.h>
-#include <linux/netfilter/xt_MARK.h>
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
-MODULE_DESCRIPTION("Xtables: packet mark modification");
-MODULE_ALIAS("ipt_MARK");
-MODULE_ALIAS("ip6t_MARK");
-
-static unsigned int
-mark_tg(struct sk_buff *skb, const struct xt_target_param *par)
-{
-       const struct xt_mark_tginfo2 *info = par->targinfo;
-
-       skb->mark = (skb->mark & ~info->mask) ^ info->mark;
-       return XT_CONTINUE;
-}
-
-static struct xt_target mark_tg_reg __read_mostly = {
-       .name           = "MARK",
-       .revision       = 2,
-       .family         = NFPROTO_UNSPEC,
-       .target         = mark_tg,
-       .targetsize     = sizeof(struct xt_mark_tginfo2),
-       .me             = THIS_MODULE,
-};
-
-static int __init mark_tg_init(void)
-{
-       return xt_register_target(&mark_tg_reg);
-}
-
-static void __exit mark_tg_exit(void)
-{
-       xt_unregister_target(&mark_tg_reg);
-}
-
-module_init(mark_tg_init);
-module_exit(mark_tg_exit);
index a57c5cf..42dd874 100644 (file)
@@ -37,15 +37,15 @@ nflog_tg(struct sk_buff *skb, const struct xt_target_param *par)
        return XT_CONTINUE;
 }
 
-static bool nflog_tg_check(const struct xt_tgchk_param *par)
+static int nflog_tg_check(const struct xt_tgchk_param *par)
 {
        const struct xt_nflog_info *info = par->targinfo;
 
        if (info->flags & ~XT_NFLOG_MASK)
-               return false;
+               return -EINVAL;
        if (info->prefix[sizeof(info->prefix) - 1] != '\0')
-               return false;
-       return true;
+               return -EINVAL;
+       return 0;
 }
 
 static struct xt_target nflog_tg_reg __read_mostly = {
index 12dcd70..f9217cb 100644 (file)
@@ -49,17 +49,6 @@ static u32 hash_v4(const struct sk_buff *skb)
        return jhash_2words((__force u32)ipaddr, iph->protocol, jhash_initval);
 }
 
-static unsigned int
-nfqueue_tg4_v1(struct sk_buff *skb, const struct xt_target_param *par)
-{
-       const struct xt_NFQ_info_v1 *info = par->targinfo;
-       u32 queue = info->queuenum;
-
-       if (info->queues_total > 1)
-               queue = hash_v4(skb) % info->queues_total + queue;
-       return NF_QUEUE_NR(queue);
-}
-
 #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
 static u32 hash_v6(const struct sk_buff *skb)
 {
@@ -73,20 +62,26 @@ static u32 hash_v6(const struct sk_buff *skb)
 
        return jhash2((__force u32 *)addr, ARRAY_SIZE(addr), jhash_initval);
 }
+#endif
 
 static unsigned int
-nfqueue_tg6_v1(struct sk_buff *skb, const struct xt_target_param *par)
+nfqueue_tg_v1(struct sk_buff *skb, const struct xt_target_param *par)
 {
        const struct xt_NFQ_info_v1 *info = par->targinfo;
        u32 queue = info->queuenum;
 
-       if (info->queues_total > 1)
-               queue = hash_v6(skb) % info->queues_total + queue;
+       if (info->queues_total > 1) {
+               if (par->family == NFPROTO_IPV4)
+                       queue = hash_v4(skb) % info->queues_total + queue;
+#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
+               else if (par->family == NFPROTO_IPV6)
+                       queue = hash_v6(skb) % info->queues_total + queue;
+#endif
+       }
        return NF_QUEUE_NR(queue);
 }
-#endif
 
-static bool nfqueue_tg_v1_check(const struct xt_tgchk_param *par)
+static int nfqueue_tg_v1_check(const struct xt_tgchk_param *par)
 {
        const struct xt_NFQ_info_v1 *info = par->targinfo;
        u32 maxid;
@@ -97,15 +92,15 @@ static bool nfqueue_tg_v1_check(const struct xt_tgchk_param *par)
        }
        if (info->queues_total == 0) {
                pr_err("NFQUEUE: number of total queues is 0\n");
-               return false;
+               return -EINVAL;
        }
        maxid = info->queues_total - 1 + info->queuenum;
        if (maxid > 0xffff) {
                pr_err("NFQUEUE: number of queues (%u) out of range (got %u)\n",
                       info->queues_total, maxid);
-               return false;
+               return -ERANGE;
        }
-       return true;
+       return 0;
 }
 
 static struct xt_target nfqueue_tg_reg[] __read_mostly = {
@@ -119,23 +114,12 @@ static struct xt_target nfqueue_tg_reg[] __read_mostly = {
        {
                .name           = "NFQUEUE",
                .revision       = 1,
-               .family         = NFPROTO_IPV4,
-               .checkentry     = nfqueue_tg_v1_check,
-               .target         = nfqueue_tg4_v1,
-               .targetsize     = sizeof(struct xt_NFQ_info_v1),
-               .me             = THIS_MODULE,
-       },
-#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
-       {
-               .name           = "NFQUEUE",
-               .revision       = 1,
-               .family         = NFPROTO_IPV6,
+               .family         = NFPROTO_UNSPEC,
                .checkentry     = nfqueue_tg_v1_check,
-               .target         = nfqueue_tg6_v1,
+               .target         = nfqueue_tg_v1,
                .targetsize     = sizeof(struct xt_NFQ_info_v1),
                .me             = THIS_MODULE,
        },
-#endif
 };
 
 static int __init nfqueue_tg_init(void)
index d16d55d..a02193f 100644 (file)
@@ -86,7 +86,7 @@ xt_rateest_tg(struct sk_buff *skb, const struct xt_target_param *par)
        return XT_CONTINUE;
 }
 
-static bool xt_rateest_tg_checkentry(const struct xt_tgchk_param *par)
+static int xt_rateest_tg_checkentry(const struct xt_tgchk_param *par)
 {
        struct xt_rateest_target_info *info = par->targinfo;
        struct xt_rateest *est;
@@ -94,6 +94,7 @@ static bool xt_rateest_tg_checkentry(const struct xt_tgchk_param *par)
                struct nlattr           opt;
                struct gnet_estimator   est;
        } cfg;
+       int ret;
 
        if (unlikely(!rnd_inited)) {
                get_random_bytes(&jhash_rnd, sizeof(jhash_rnd));
@@ -110,12 +111,13 @@ static bool xt_rateest_tg_checkentry(const struct xt_tgchk_param *par)
                    (info->interval != est->params.interval ||
                     info->ewma_log != est->params.ewma_log)) {
                        xt_rateest_put(est);
-                       return false;
+                       return -EINVAL;
                }
                info->est = est;
-               return true;
+               return 0;
        }
 
+       ret = -ENOMEM;
        est = kzalloc(sizeof(*est), GFP_KERNEL);
        if (!est)
                goto err1;
@@ -131,19 +133,19 @@ static bool xt_rateest_tg_checkentry(const struct xt_tgchk_param *par)
        cfg.est.interval        = info->interval;
        cfg.est.ewma_log        = info->ewma_log;
 
-       if (gen_new_estimator(&est->bstats, &est->rstats, &est->lock,
-                             &cfg.opt) < 0)
+       ret = gen_new_estimator(&est->bstats, &est->rstats,
+                               &est->lock, &cfg.opt);
+       if (ret < 0)
                goto err2;
 
        info->est = est;
        xt_rateest_hash_insert(est);
-
-       return true;
+       return 0;
 
 err2:
        kfree(est);
 err1:
-       return false;
+       return ret;
 }
 
 static void xt_rateest_tg_destroy(const struct xt_tgdtor_param *par)
index 7a6f9e6..a91d4a7 100644 (file)
@@ -12,6 +12,7 @@
  * published by the Free Software Foundation.
  *
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/selinux.h>
@@ -49,7 +50,7 @@ secmark_tg(struct sk_buff *skb, const struct xt_target_param *par)
        return XT_CONTINUE;
 }
 
-static bool checkentry_selinux(struct xt_secmark_target_info *info)
+static int checkentry_selinux(struct xt_secmark_target_info *info)
 {
        int err;
        struct xt_secmark_target_selinux_info *sel = &info->u.sel;
@@ -59,58 +60,59 @@ static bool checkentry_selinux(struct xt_secmark_target_info *info)
        err = selinux_string_to_sid(sel->selctx, &sel->selsid);
        if (err) {
                if (err == -EINVAL)
-                       printk(KERN_INFO PFX "invalid SELinux context \'%s\'\n",
-                              sel->selctx);
-               return false;
+                       pr_info("invalid SELinux context \'%s\'\n",
+                               sel->selctx);
+               return err;
        }
 
        if (!sel->selsid) {
-               printk(KERN_INFO PFX "unable to map SELinux context \'%s\'\n",
-                      sel->selctx);
-               return false;
+               pr_info("unable to map SELinux context \'%s\'\n", sel->selctx);
+               return -ENOENT;
        }
 
        err = selinux_secmark_relabel_packet_permission(sel->selsid);
        if (err) {
-               printk(KERN_INFO PFX "unable to obtain relabeling permission\n");
-               return false;
+               pr_info("unable to obtain relabeling permission\n");
+               return err;
        }
 
        selinux_secmark_refcount_inc();
-       return true;
+       return 0;
 }
 
-static bool secmark_tg_check(const struct xt_tgchk_param *par)
+static int secmark_tg_check(const struct xt_tgchk_param *par)
 {
        struct xt_secmark_target_info *info = par->targinfo;
+       int err;
 
        if (strcmp(par->table, "mangle") != 0 &&
            strcmp(par->table, "security") != 0) {
-               printk(KERN_INFO PFX "target only valid in the \'mangle\' "
-                      "or \'security\' tables, not \'%s\'.\n", par->table);
-               return false;
+               pr_info("target only valid in the \'mangle\' "
+                       "or \'security\' tables, not \'%s\'.\n", par->table);
+               return -EINVAL;
        }
 
        if (mode && mode != info->mode) {
-               printk(KERN_INFO PFX "mode already set to %hu cannot mix with "
-                      "rules for mode %hu\n", mode, info->mode);
-               return false;
+               pr_info("mode already set to %hu cannot mix with "
+                       "rules for mode %hu\n", mode, info->mode);
+               return -EINVAL;
        }
 
        switch (info->mode) {
        case SECMARK_MODE_SEL:
-               if (!checkentry_selinux(info))
-                       return false;
+               err = checkentry_selinux(info);
+               if (err <= 0)
+                       return err;
                break;
 
        default:
-               printk(KERN_INFO PFX "invalid mode: %hu\n", info->mode);
-               return false;
+               pr_info("invalid mode: %hu\n", info->mode);
+               return -EINVAL;
        }
 
        if (!mode)
                mode = info->mode;
-       return true;
+       return 0;
 }
 
 static void secmark_tg_destroy(const struct xt_tgdtor_param *par)
index c5f4b99..d046064 100644 (file)
@@ -7,7 +7,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/ip.h>
@@ -68,15 +68,14 @@ tcpmss_mangle_packet(struct sk_buff *skb,
        if (info->mss == XT_TCPMSS_CLAMP_PMTU) {
                if (dst_mtu(skb_dst(skb)) <= minlen) {
                        if (net_ratelimit())
-                               printk(KERN_ERR "xt_TCPMSS: "
-                                      "unknown or invalid path-MTU (%u)\n",
+                               pr_err("unknown or invalid path-MTU (%u)\n",
                                       dst_mtu(skb_dst(skb)));
                        return -1;
                }
                if (in_mtu <= minlen) {
                        if (net_ratelimit())
-                               printk(KERN_ERR "xt_TCPMSS: unknown or "
-                                      "invalid path-MTU (%u)\n", in_mtu);
+                               pr_err("unknown or invalid path-MTU (%u)\n",
+                                      in_mtu);
                        return -1;
                }
                newmss = min(dst_mtu(skb_dst(skb)), in_mtu) - minlen;
@@ -236,7 +235,7 @@ static inline bool find_syn_match(const struct xt_entry_match *m)
        return false;
 }
 
-static bool tcpmss_tg4_check(const struct xt_tgchk_param *par)
+static int tcpmss_tg4_check(const struct xt_tgchk_param *par)
 {
        const struct xt_tcpmss_info *info = par->targinfo;
        const struct ipt_entry *e = par->entryinfo;
@@ -246,19 +245,19 @@ static bool tcpmss_tg4_check(const struct xt_tgchk_param *par)
            (par->hook_mask & ~((1 << NF_INET_FORWARD) |
                           (1 << NF_INET_LOCAL_OUT) |
                           (1 << NF_INET_POST_ROUTING))) != 0) {
-               printk("xt_TCPMSS: path-MTU clamping only supported in "
-                      "FORWARD, OUTPUT and POSTROUTING hooks\n");
-               return false;
+               pr_info("path-MTU clamping only supported in "
+                       "FORWARD, OUTPUT and POSTROUTING hooks\n");
+               return -EINVAL;
        }
        xt_ematch_foreach(ematch, e)
                if (find_syn_match(ematch))
-                       return true;
-       printk("xt_TCPMSS: Only works on TCP SYN packets\n");
-       return false;
+                       return 0;
+       pr_info("Only works on TCP SYN packets\n");
+       return -EINVAL;
 }
 
 #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
-static bool tcpmss_tg6_check(const struct xt_tgchk_param *par)
+static int tcpmss_tg6_check(const struct xt_tgchk_param *par)
 {
        const struct xt_tcpmss_info *info = par->targinfo;
        const struct ip6t_entry *e = par->entryinfo;
@@ -268,15 +267,15 @@ static bool tcpmss_tg6_check(const struct xt_tgchk_param *par)
            (par->hook_mask & ~((1 << NF_INET_FORWARD) |
                           (1 << NF_INET_LOCAL_OUT) |
                           (1 << NF_INET_POST_ROUTING))) != 0) {
-               printk("xt_TCPMSS: path-MTU clamping only supported in "
-                      "FORWARD, OUTPUT and POSTROUTING hooks\n");
-               return false;
+               pr_info("path-MTU clamping only supported in "
+                       "FORWARD, OUTPUT and POSTROUTING hooks\n");
+               return -EINVAL;
        }
        xt_ematch_foreach(ematch, e)
                if (find_syn_match(ematch))
-                       return true;
-       printk("xt_TCPMSS: Only works on TCP SYN packets\n");
-       return false;
+                       return 0;
+       pr_info("Only works on TCP SYN packets\n");
+       return -EINVAL;
 }
 #endif
 
index 9dd8c8e..e8b5760 100644 (file)
@@ -3,7 +3,6 @@
  *
  * Copyright (C) 2007 Sven Schnelle <svens@bitebene.org>
  * Copyright © CC Computer Consultants GmbH, 2007
- * Contact: Jan Engelhardt <jengelh@computergmbh.de>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -136,7 +135,7 @@ static void __exit tcpoptstrip_tg_exit(void)
 
 module_init(tcpoptstrip_tg_init);
 module_exit(tcpoptstrip_tg_exit);
-MODULE_AUTHOR("Sven Schnelle <svens@bitebene.org>, Jan Engelhardt <jengelh@computergmbh.de>");
+MODULE_AUTHOR("Sven Schnelle <svens@bitebene.org>, Jan Engelhardt <jengelh@medozas.de>");
 MODULE_DESCRIPTION("Xtables: TCP option stripping");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_TCPOPTSTRIP");
diff --git a/net/netfilter/xt_TEE.c b/net/netfilter/xt_TEE.c
new file mode 100644 (file)
index 0000000..49da6c0
--- /dev/null
@@ -0,0 +1,309 @@
+/*
+ *     "TEE" target extension for Xtables
+ *     Copyright © Sebastian Claßen, 2007
+ *     Jan Engelhardt, 2007-2010
+ *
+ *     based on ipt_ROUTE.c from Cédric de Launois
+ *     <delaunois@info.ucl.be>
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 or later, as published by the Free Software Foundation.
+ */
+#include <linux/ip.h>
+#include <linux/module.h>
+#include <linux/percpu.h>
+#include <linux/route.h>
+#include <linux/skbuff.h>
+#include <linux/notifier.h>
+#include <net/checksum.h>
+#include <net/icmp.h>
+#include <net/ip.h>
+#include <net/ipv6.h>
+#include <net/ip6_route.h>
+#include <net/route.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/xt_TEE.h>
+
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+#      define WITH_CONNTRACK 1
+#      include <net/netfilter/nf_conntrack.h>
+#endif
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+#      define WITH_IPV6 1
+#endif
+
+struct xt_tee_priv {
+       struct notifier_block   notifier;
+       struct xt_tee_tginfo    *tginfo;
+       int                     oif;
+};
+
+static const union nf_inet_addr tee_zero_address;
+static DEFINE_PER_CPU(bool, tee_active);
+
+static struct net *pick_net(struct sk_buff *skb)
+{
+#ifdef CONFIG_NET_NS
+       const struct dst_entry *dst;
+
+       if (skb->dev != NULL)
+               return dev_net(skb->dev);
+       dst = skb_dst(skb);
+       if (dst != NULL && dst->dev != NULL)
+               return dev_net(dst->dev);
+#endif
+       return &init_net;
+}
+
+static bool
+tee_tg_route4(struct sk_buff *skb, const struct xt_tee_tginfo *info)
+{
+       const struct iphdr *iph = ip_hdr(skb);
+       struct net *net = pick_net(skb);
+       struct rtable *rt;
+       struct flowi fl;
+
+       memset(&fl, 0, sizeof(fl));
+       if (info->priv) {
+               if (info->priv->oif == -1)
+                       return false;
+               fl.oif = info->priv->oif;
+       }
+       fl.nl_u.ip4_u.daddr = info->gw.ip;
+       fl.nl_u.ip4_u.tos   = RT_TOS(iph->tos);
+       fl.nl_u.ip4_u.scope = RT_SCOPE_UNIVERSE;
+       if (ip_route_output_key(net, &rt, &fl) != 0)
+               return false;
+
+       dst_release(skb_dst(skb));
+       skb_dst_set(skb, &rt->u.dst);
+       skb->dev      = rt->u.dst.dev;
+       skb->protocol = htons(ETH_P_IP);
+       return true;
+}
+
+static unsigned int
+tee_tg4(struct sk_buff *skb, const struct xt_target_param *par)
+{
+       const struct xt_tee_tginfo *info = par->targinfo;
+       struct iphdr *iph;
+
+       if (percpu_read(tee_active))
+               return XT_CONTINUE;
+       /*
+        * Copy the skb, and route the copy. Will later return %XT_CONTINUE for
+        * the original skb, which should continue on its way as if nothing has
+        * happened. The copy should be independently delivered to the TEE
+        * --gateway.
+        */
+       skb = pskb_copy(skb, GFP_ATOMIC);
+       if (skb == NULL)
+               return XT_CONTINUE;
+
+#ifdef WITH_CONNTRACK
+       /* Avoid counting cloned packets towards the original connection. */
+       nf_conntrack_put(skb->nfct);
+       skb->nfct     = &nf_conntrack_untracked.ct_general;
+       skb->nfctinfo = IP_CT_NEW;
+       nf_conntrack_get(skb->nfct);
+#endif
+       /*
+        * If we are in PREROUTING/INPUT, the checksum must be recalculated
+        * since the length could have changed as a result of defragmentation.
+        *
+        * We also decrease the TTL to mitigate potential TEE loops
+        * between two hosts.
+        *
+        * Set %IP_DF so that the original source is notified of a potentially
+        * decreased MTU on the clone route. IPv6 does this too.
+        */
+       iph = ip_hdr(skb);
+       iph->frag_off |= htons(IP_DF);
+       if (par->hooknum == NF_INET_PRE_ROUTING ||
+           par->hooknum == NF_INET_LOCAL_IN)
+               --iph->ttl;
+       ip_send_check(iph);
+
+       if (tee_tg_route4(skb, info)) {
+               percpu_write(tee_active, true);
+               ip_local_out(skb);
+               percpu_write(tee_active, false);
+       } else {
+               kfree_skb(skb);
+       }
+       return XT_CONTINUE;
+}
+
+#ifdef WITH_IPV6
+static bool
+tee_tg_route6(struct sk_buff *skb, const struct xt_tee_tginfo *info)
+{
+       const struct ipv6hdr *iph = ipv6_hdr(skb);
+       struct net *net = pick_net(skb);
+       struct dst_entry *dst;
+       struct flowi fl;
+
+       memset(&fl, 0, sizeof(fl));
+       if (info->priv) {
+               if (info->priv->oif == -1)
+                       return false;
+               fl.oif = info->priv->oif;
+       }
+       fl.nl_u.ip6_u.daddr = info->gw.in6;
+       fl.nl_u.ip6_u.flowlabel = ((iph->flow_lbl[0] & 0xF) << 16) |
+                                 (iph->flow_lbl[1] << 8) | iph->flow_lbl[2];
+       dst = ip6_route_output(net, NULL, &fl);
+       if (dst == NULL)
+               return false;
+
+       dst_release(skb_dst(skb));
+       skb_dst_set(skb, dst);
+       skb->dev      = dst->dev;
+       skb->protocol = htons(ETH_P_IPV6);
+       return true;
+}
+
+static unsigned int
+tee_tg6(struct sk_buff *skb, const struct xt_target_param *par)
+{
+       const struct xt_tee_tginfo *info = par->targinfo;
+
+       if (percpu_read(tee_active))
+               return XT_CONTINUE;
+       skb = pskb_copy(skb, GFP_ATOMIC);
+       if (skb == NULL)
+               return XT_CONTINUE;
+
+#ifdef WITH_CONNTRACK
+       nf_conntrack_put(skb->nfct);
+       skb->nfct     = &nf_conntrack_untracked.ct_general;
+       skb->nfctinfo = IP_CT_NEW;
+       nf_conntrack_get(skb->nfct);
+#endif
+       if (par->hooknum == NF_INET_PRE_ROUTING ||
+           par->hooknum == NF_INET_LOCAL_IN) {
+               struct ipv6hdr *iph = ipv6_hdr(skb);
+               --iph->hop_limit;
+       }
+       if (tee_tg_route6(skb, info)) {
+               percpu_write(tee_active, true);
+               ip6_local_out(skb);
+               percpu_write(tee_active, false);
+       } else {
+               kfree_skb(skb);
+       }
+       return XT_CONTINUE;
+}
+#endif /* WITH_IPV6 */
+
+static int tee_netdev_event(struct notifier_block *this, unsigned long event,
+                           void *ptr)
+{
+       struct net_device *dev = ptr;
+       struct xt_tee_priv *priv;
+
+       priv = container_of(this, struct xt_tee_priv, notifier);
+       switch (event) {
+       case NETDEV_REGISTER:
+               if (!strcmp(dev->name, priv->tginfo->oif))
+                       priv->oif = dev->ifindex;
+               break;
+       case NETDEV_UNREGISTER:
+               if (dev->ifindex == priv->oif)
+                       priv->oif = -1;
+               break;
+       case NETDEV_CHANGENAME:
+               if (!strcmp(dev->name, priv->tginfo->oif))
+                       priv->oif = dev->ifindex;
+               else if (dev->ifindex == priv->oif)
+                       priv->oif = -1;
+               break;
+       }
+
+       return NOTIFY_DONE;
+}
+
+static int tee_tg_check(const struct xt_tgchk_param *par)
+{
+       struct xt_tee_tginfo *info = par->targinfo;
+       struct xt_tee_priv *priv;
+
+       /* 0.0.0.0 and :: not allowed */
+       if (memcmp(&info->gw, &tee_zero_address,
+                  sizeof(tee_zero_address)) == 0)
+               return -EINVAL;
+
+       if (info->oif[0]) {
+               if (info->oif[sizeof(info->oif)-1] != '\0')
+                       return -EINVAL;
+
+               priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+               if (priv == NULL)
+                       return -ENOMEM;
+
+               priv->tginfo  = info;
+               priv->oif     = -1;
+               priv->notifier.notifier_call = tee_netdev_event;
+               info->priv    = priv;
+
+               register_netdevice_notifier(&priv->notifier);
+       } else
+               info->priv = NULL;
+
+       return 0;
+}
+
+static void tee_tg_destroy(const struct xt_tgdtor_param *par)
+{
+       struct xt_tee_tginfo *info = par->targinfo;
+
+       if (info->priv) {
+               unregister_netdevice_notifier(&info->priv->notifier);
+               kfree(info->priv);
+       }
+}
+
+static struct xt_target tee_tg_reg[] __read_mostly = {
+       {
+               .name       = "TEE",
+               .revision   = 1,
+               .family     = NFPROTO_IPV4,
+               .target     = tee_tg4,
+               .targetsize = sizeof(struct xt_tee_tginfo),
+               .checkentry = tee_tg_check,
+               .destroy    = tee_tg_destroy,
+               .me         = THIS_MODULE,
+       },
+#ifdef WITH_IPV6
+       {
+               .name       = "TEE",
+               .revision   = 1,
+               .family     = NFPROTO_IPV6,
+               .target     = tee_tg6,
+               .targetsize = sizeof(struct xt_tee_tginfo),
+               .checkentry = tee_tg_check,
+               .destroy    = tee_tg_destroy,
+               .me         = THIS_MODULE,
+       },
+#endif
+};
+
+static int __init tee_tg_init(void)
+{
+       return xt_register_targets(tee_tg_reg, ARRAY_SIZE(tee_tg_reg));
+}
+
+static void __exit tee_tg_exit(void)
+{
+       xt_unregister_targets(tee_tg_reg, ARRAY_SIZE(tee_tg_reg));
+}
+
+module_init(tee_tg_init);
+module_exit(tee_tg_exit);
+MODULE_AUTHOR("Sebastian Claßen <sebastian.classen@freenet.ag>");
+MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
+MODULE_DESCRIPTION("Xtables: Reroute packet copy");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ipt_TEE");
+MODULE_ALIAS("ip6t_TEE");
index 1340c2f..4f246dd 100644 (file)
@@ -9,7 +9,7 @@
  * published by the Free Software Foundation.
  *
  */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/ip.h>
@@ -59,17 +59,17 @@ tproxy_tg(struct sk_buff *skb, const struct xt_target_param *par)
        return NF_DROP;
 }
 
-static bool tproxy_tg_check(const struct xt_tgchk_param *par)
+static int tproxy_tg_check(const struct xt_tgchk_param *par)
 {
        const struct ipt_ip *i = par->entryinfo;
 
        if ((i->proto == IPPROTO_TCP || i->proto == IPPROTO_UDP)
            && !(i->invflags & IPT_INV_PROTO))
-               return true;
+               return 0;
 
-       pr_info("xt_TPROXY: Can be used only in combination with "
+       pr_info("Can be used only in combination with "
                "either -p tcp or -p udp\n");
-       return false;
+       return -EINVAL;
 }
 
 static struct xt_target tproxy_tg_reg __read_mostly = {
index 225ee3e..6c941e1 100644 (file)
@@ -5,6 +5,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/jhash.h>
@@ -131,22 +132,22 @@ xt_cluster_mt(const struct sk_buff *skb, const struct xt_match_param *par)
               !!(info->flags & XT_CLUSTER_F_INV);
 }
 
-static bool xt_cluster_mt_checkentry(const struct xt_mtchk_param *par)
+static int xt_cluster_mt_checkentry(const struct xt_mtchk_param *par)
 {
        struct xt_cluster_match_info *info = par->matchinfo;
 
        if (info->total_nodes > XT_CLUSTER_NODES_MAX) {
-               printk(KERN_ERR "xt_cluster: you have exceeded the maximum "
-                               "number of cluster nodes (%u > %u)\n",
-                               info->total_nodes, XT_CLUSTER_NODES_MAX);
-               return false;
+               pr_info("you have exceeded the maximum "
+                       "number of cluster nodes (%u > %u)\n",
+                       info->total_nodes, XT_CLUSTER_NODES_MAX);
+               return -EINVAL;
        }
        if (info->node_mask >= (1ULL << info->total_nodes)) {
-               printk(KERN_ERR "xt_cluster: this node mask cannot be "
-                               "higher than the total number of nodes\n");
-               return false;
+               pr_info("this node mask cannot be "
+                       "higher than the total number of nodes\n");
+               return -EDOM;
        }
-       return true;
+       return 0;
 }
 
 static struct xt_match xt_cluster_match __read_mostly = {
index 955e659..ff738a5 100644 (file)
@@ -1,6 +1,7 @@
 /* Kernel module to match connection tracking byte counter.
  * GPL (C) 2002 Martin Devera (devik@cdi.cz).
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
 #include <linux/bitops.h>
 #include <linux/skbuff.h>
@@ -92,27 +93,26 @@ connbytes_mt(const struct sk_buff *skb, const struct xt_match_param *par)
                return what >= sinfo->count.from;
 }
 
-static bool connbytes_mt_check(const struct xt_mtchk_param *par)
+static int connbytes_mt_check(const struct xt_mtchk_param *par)
 {
        const struct xt_connbytes_info *sinfo = par->matchinfo;
+       int ret;
 
        if (sinfo->what != XT_CONNBYTES_PKTS &&
            sinfo->what != XT_CONNBYTES_BYTES &&
            sinfo->what != XT_CONNBYTES_AVGPKT)
-               return false;
+               return -EINVAL;
 
        if (sinfo->direction != XT_CONNBYTES_DIR_ORIGINAL &&
            sinfo->direction != XT_CONNBYTES_DIR_REPLY &&
            sinfo->direction != XT_CONNBYTES_DIR_BOTH)
-               return false;
-
-       if (nf_ct_l3proto_try_module_get(par->family) < 0) {
-               printk(KERN_WARNING "can't load conntrack support for "
-                                   "proto=%u\n", par->family);
-               return false;
-       }
+               return -EINVAL;
 
-       return true;
+       ret = nf_ct_l3proto_try_module_get(par->family);
+       if (ret < 0)
+               pr_info("cannot load conntrack support for proto=%u\n",
+                       par->family);
+       return ret;
 }
 
 static void connbytes_mt_destroy(const struct xt_mtdtor_param *par)
index 388ca45..326bc1b 100644 (file)
@@ -5,13 +5,13 @@
  *   Nov 2002: Martin Bene <martin.bene@icomedias.com>:
  *             only ignore TIME_WAIT or gone connections
  *   (C) CC Computer Consultants GmbH, 2007
- *   Contact: <jengelh@computergmbh.de>
  *
  * based on ...
  *
  * Kernel module to match connection tracking information.
  * GPL (C) 1999  Rusty Russell (rusty@rustcorp.com.au).
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/in.h>
 #include <linux/in6.h>
 #include <linux/ip.h>
@@ -217,33 +217,35 @@ connlimit_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        return false;
 }
 
-static bool connlimit_mt_check(const struct xt_mtchk_param *par)
+static int connlimit_mt_check(const struct xt_mtchk_param *par)
 {
        struct xt_connlimit_info *info = par->matchinfo;
        unsigned int i;
+       int ret;
 
        if (unlikely(!connlimit_rnd_inited)) {
                get_random_bytes(&connlimit_rnd, sizeof(connlimit_rnd));
                connlimit_rnd_inited = true;
        }
-       if (nf_ct_l3proto_try_module_get(par->family) < 0) {
-               printk(KERN_WARNING "cannot load conntrack support for "
-                      "address family %u\n", par->family);
-               return false;
+       ret = nf_ct_l3proto_try_module_get(par->family);
+       if (ret < 0) {
+               pr_info("cannot load conntrack support for "
+                       "address family %u\n", par->family);
+               return ret;
        }
 
        /* init private data */
        info->data = kmalloc(sizeof(struct xt_connlimit_data), GFP_KERNEL);
        if (info->data == NULL) {
                nf_ct_l3proto_module_put(par->family);
-               return false;
+               return -ENOMEM;
        }
 
        spin_lock_init(&info->data->lock);
        for (i = 0; i < ARRAY_SIZE(info->data->iphash); ++i)
                INIT_LIST_HEAD(&info->data->iphash[i]);
 
-       return true;
+       return 0;
 }
 
 static void connlimit_mt_destroy(const struct xt_mtdtor_param *par)
index 122aa8b..ae10154 100644 (file)
@@ -1,10 +1,10 @@
 /*
- *     xt_connmark - Netfilter module to match connection mark values
+ *     xt_connmark - Netfilter module to operate on connection marks
  *
  *     Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
  *     by Henrik Nordstrom <hno@marasystems.com>
  *     Copyright © CC Computer Consultants GmbH, 2007 - 2008
- *     Jan Engelhardt <jengelh@computergmbh.de>
+ *     Jan Engelhardt <jengelh@medozas.de>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_conntrack_ecache.h>
 #include <linux/netfilter/x_tables.h>
 #include <linux/netfilter/xt_connmark.h>
 
 MODULE_AUTHOR("Henrik Nordstrom <hno@marasystems.com>");
-MODULE_DESCRIPTION("Xtables: connection mark match");
+MODULE_DESCRIPTION("Xtables: connection mark operations");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("ipt_CONNMARK");
+MODULE_ALIAS("ip6t_CONNMARK");
 MODULE_ALIAS("ipt_connmark");
 MODULE_ALIAS("ip6t_connmark");
 
+static unsigned int
+connmark_tg(struct sk_buff *skb, const struct xt_target_param *par)
+{
+       const struct xt_connmark_tginfo1 *info = par->targinfo;
+       enum ip_conntrack_info ctinfo;
+       struct nf_conn *ct;
+       u_int32_t newmark;
+
+       ct = nf_ct_get(skb, &ctinfo);
+       if (ct == NULL)
+               return XT_CONTINUE;
+
+       switch (info->mode) {
+       case XT_CONNMARK_SET:
+               newmark = (ct->mark & ~info->ctmask) ^ info->ctmark;
+               if (ct->mark != newmark) {
+                       ct->mark = newmark;
+                       nf_conntrack_event_cache(IPCT_MARK, ct);
+               }
+               break;
+       case XT_CONNMARK_SAVE:
+               newmark = (ct->mark & ~info->ctmask) ^
+                         (skb->mark & info->nfmask);
+               if (ct->mark != newmark) {
+                       ct->mark = newmark;
+                       nf_conntrack_event_cache(IPCT_MARK, ct);
+               }
+               break;
+       case XT_CONNMARK_RESTORE:
+               newmark = (skb->mark & ~info->nfmask) ^
+                         (ct->mark & info->ctmask);
+               skb->mark = newmark;
+               break;
+       }
+
+       return XT_CONTINUE;
+}
+
+static int connmark_tg_check(const struct xt_tgchk_param *par)
+{
+       int ret;
+
+       ret = nf_ct_l3proto_try_module_get(par->family);
+       if (ret < 0)
+               pr_info("cannot load conntrack support for proto=%u\n",
+                       par->family);
+       return ret;
+}
+
+static void connmark_tg_destroy(const struct xt_tgdtor_param *par)
+{
+       nf_ct_l3proto_module_put(par->family);
+}
+
 static bool
 connmark_mt(const struct sk_buff *skb, const struct xt_match_param *par)
 {
@@ -47,14 +104,15 @@ connmark_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        return ((ct->mark & info->mask) == info->mark) ^ info->invert;
 }
 
-static bool connmark_mt_check(const struct xt_mtchk_param *par)
+static int connmark_mt_check(const struct xt_mtchk_param *par)
 {
-       if (nf_ct_l3proto_try_module_get(par->family) < 0) {
-               printk(KERN_WARNING "cannot load conntrack support for "
-                      "proto=%u\n", par->family);
-               return false;
-       }
-       return true;
+       int ret;
+
+       ret = nf_ct_l3proto_try_module_get(par->family);
+       if (ret < 0)
+               pr_info("cannot load conntrack support for proto=%u\n",
+                       par->family);
+       return ret;
 }
 
 static void connmark_mt_destroy(const struct xt_mtdtor_param *par)
@@ -62,6 +120,17 @@ static void connmark_mt_destroy(const struct xt_mtdtor_param *par)
        nf_ct_l3proto_module_put(par->family);
 }
 
+static struct xt_target connmark_tg_reg __read_mostly = {
+       .name           = "CONNMARK",
+       .revision       = 1,
+       .family         = NFPROTO_UNSPEC,
+       .checkentry     = connmark_tg_check,
+       .target         = connmark_tg,
+       .targetsize     = sizeof(struct xt_connmark_tginfo1),
+       .destroy        = connmark_tg_destroy,
+       .me             = THIS_MODULE,
+};
+
 static struct xt_match connmark_mt_reg __read_mostly = {
        .name           = "connmark",
        .revision       = 1,
@@ -75,12 +144,23 @@ static struct xt_match connmark_mt_reg __read_mostly = {
 
 static int __init connmark_mt_init(void)
 {
-       return xt_register_match(&connmark_mt_reg);
+       int ret;
+
+       ret = xt_register_target(&connmark_tg_reg);
+       if (ret < 0)
+               return ret;
+       ret = xt_register_match(&connmark_mt_reg);
+       if (ret < 0) {
+               xt_unregister_target(&connmark_tg_reg);
+               return ret;
+       }
+       return 0;
 }
 
 static void __exit connmark_mt_exit(void)
 {
        xt_unregister_match(&connmark_mt_reg);
+       xt_unregister_target(&connmark_tg_reg);
 }
 
 module_init(connmark_mt_init);
index ae66305..3348706 100644 (file)
@@ -9,7 +9,7 @@
  *     it under the terms of the GNU General Public License version 2 as
  *     published by the Free Software Foundation.
  */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <net/ipv6.h>
@@ -206,14 +206,15 @@ conntrack_mt_v2(const struct sk_buff *skb, const struct xt_match_param *par)
        return conntrack_mt(skb, par, info->state_mask, info->status_mask);
 }
 
-static bool conntrack_mt_check(const struct xt_mtchk_param *par)
+static int conntrack_mt_check(const struct xt_mtchk_param *par)
 {
-       if (nf_ct_l3proto_try_module_get(par->family) < 0) {
-               printk(KERN_WARNING "can't load conntrack support for "
-                                   "proto=%u\n", par->family);
-               return false;
-       }
-       return true;
+       int ret;
+
+       ret = nf_ct_l3proto_try_module_get(par->family);
+       if (ret < 0)
+               pr_info("cannot load conntrack support for proto=%u\n",
+                       par->family);
+       return ret;
 }
 
 static void conntrack_mt_destroy(const struct xt_mtdtor_param *par)
index 395af59..0d260ae 100644 (file)
@@ -124,13 +124,17 @@ dccp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
                           XT_DCCP_OPTION, info->flags, info->invflags);
 }
 
-static bool dccp_mt_check(const struct xt_mtchk_param *par)
+static int dccp_mt_check(const struct xt_mtchk_param *par)
 {
        const struct xt_dccp_info *info = par->matchinfo;
 
-       return !(info->flags & ~XT_DCCP_VALID_FLAGS)
-               && !(info->invflags & ~XT_DCCP_VALID_FLAGS)
-               && !(info->invflags & ~info->flags);
+       if (info->flags & ~XT_DCCP_VALID_FLAGS)
+               return -EINVAL;
+       if (info->invflags & ~XT_DCCP_VALID_FLAGS)
+               return -EINVAL;
+       if (info->invflags & ~info->flags)
+               return -EINVAL;
+       return 0;
 }
 
 static struct xt_match dccp_mt_reg[] __read_mostly = {
index 0280d3a..9db51fd 100644 (file)
@@ -6,7 +6,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/ip.h>
@@ -42,23 +42,23 @@ dscp_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
        return (dscp == info->dscp) ^ !!info->invert;
 }
 
-static bool dscp_mt_check(const struct xt_mtchk_param *par)
+static int dscp_mt_check(const struct xt_mtchk_param *par)
 {
        const struct xt_dscp_info *info = par->matchinfo;
 
        if (info->dscp > XT_DSCP_MAX) {
-               printk(KERN_ERR "xt_dscp: dscp %x out of range\n", info->dscp);
-               return false;
+               pr_info("dscp %x out of range\n", info->dscp);
+               return -EDOM;
        }
 
-       return true;
+       return 0;
 }
 
 static bool tos_mt(const struct sk_buff *skb, const struct xt_match_param *par)
 {
        const struct xt_tos_match_info *info = par->matchinfo;
 
-       if (par->match->family == NFPROTO_IPV4)
+       if (par->family == NFPROTO_IPV4)
                return ((ip_hdr(skb)->tos & info->tos_mask) ==
                       info->tos_value) ^ !!info->invert;
        else
index 6094399..143bfdc 100644 (file)
@@ -6,7 +6,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/in.h>
@@ -24,21 +24,15 @@ MODULE_DESCRIPTION("Xtables: IPsec-ESP packet match");
 MODULE_ALIAS("ipt_esp");
 MODULE_ALIAS("ip6t_esp");
 
-#if 0
-#define duprintf(format, args...) printk(format , ## args)
-#else
-#define duprintf(format, args...)
-#endif
-
 /* Returns 1 if the spi is matched by the range, 0 otherwise */
 static inline bool
 spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
 {
        bool r;
-       duprintf("esp spi_match:%c 0x%x <= 0x%x <= 0x%x", invert ? '!' : ' ',
-                min, spi, max);
+       pr_debug("spi_match:%c 0x%x <= 0x%x <= 0x%x\n",
+                invert ? '!' : ' ', min, spi, max);
        r = (spi >= min && spi <= max) ^ invert;
-       duprintf(" result %s\n", r ? "PASS" : "FAILED");
+       pr_debug(" result %s\n", r ? "PASS" : "FAILED");
        return r;
 }
 
@@ -57,7 +51,7 @@ static bool esp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
                /* We've been asked to examine this packet, and we
                 * can't.  Hence, no choice but to drop.
                 */
-               duprintf("Dropping evil ESP tinygram.\n");
+               pr_debug("Dropping evil ESP tinygram.\n");
                *par->hotdrop = true;
                return false;
        }
@@ -66,16 +60,16 @@ static bool esp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
                         !!(espinfo->invflags & XT_ESP_INV_SPI));
 }
 
-static bool esp_mt_check(const struct xt_mtchk_param *par)
+static int esp_mt_check(const struct xt_mtchk_param *par)
 {
        const struct xt_esp *espinfo = par->matchinfo;
 
        if (espinfo->invflags & ~XT_ESP_INV_MASK) {
-               duprintf("xt_esp: unknown flags %X\n", espinfo->invflags);
-               return false;
+               pr_debug("unknown flags %X\n", espinfo->invflags);
+               return -EINVAL;
        }
 
-       return true;
+       return 0;
 }
 
 static struct xt_match esp_mt_reg[] __read_mostly = {
index 215a648..0c366d3 100644 (file)
@@ -7,6 +7,7 @@
  *
  * Development of this code was funded by Astaro AG, http://www.astaro.com/
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <linux/random.h>
@@ -36,7 +37,7 @@
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
-MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
+MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
 MODULE_DESCRIPTION("Xtables: per hash-bucket rate-limit match");
 MODULE_ALIAS("ipt_hashlimit");
 MODULE_ALIAS("ip6t_hashlimit");
@@ -80,12 +81,14 @@ struct dsthash_ent {
        struct dsthash_dst dst;
 
        /* modified structure members in the end */
+       spinlock_t lock;
        unsigned long expires;          /* precalculated expiry time */
        struct {
                unsigned long prev;     /* last modification */
                u_int32_t credit;
                u_int32_t credit_cap, cost;
        } rateinfo;
+       struct rcu_head rcu;
 };
 
 struct xt_hashlimit_htable {
@@ -142,9 +145,11 @@ dsthash_find(const struct xt_hashlimit_htable *ht,
        u_int32_t hash = hash_dst(ht, dst);
 
        if (!hlist_empty(&ht->hash[hash])) {
-               hlist_for_each_entry(ent, pos, &ht->hash[hash], node)
-                       if (dst_cmp(ent, dst))
+               hlist_for_each_entry_rcu(ent, pos, &ht->hash[hash], node)
+                       if (dst_cmp(ent, dst)) {
+                               spin_lock(&ent->lock);
                                return ent;
+                       }
        }
        return NULL;
 }
@@ -156,9 +161,10 @@ dsthash_alloc_init(struct xt_hashlimit_htable *ht,
 {
        struct dsthash_ent *ent;
 
+       spin_lock(&ht->lock);
        /* initialize hash with random val at the time we allocate
         * the first hashtable entry */
-       if (!ht->rnd_initialized) {
+       if (unlikely(!ht->rnd_initialized)) {
                get_random_bytes(&ht->rnd, sizeof(ht->rnd));
                ht->rnd_initialized = true;
        }
@@ -166,106 +172,40 @@ dsthash_alloc_init(struct xt_hashlimit_htable *ht,
        if (ht->cfg.max && ht->count >= ht->cfg.max) {
                /* FIXME: do something. question is what.. */
                if (net_ratelimit())
-                       printk(KERN_WARNING
-                               "xt_hashlimit: max count of %u reached\n",
-                               ht->cfg.max);
-               return NULL;
-       }
-
-       ent = kmem_cache_alloc(hashlimit_cachep, GFP_ATOMIC);
+                       pr_err("max count of %u reached\n", ht->cfg.max);
+               ent = NULL;
+       } else
+               ent = kmem_cache_alloc(hashlimit_cachep, GFP_ATOMIC);
        if (!ent) {
                if (net_ratelimit())
-                       printk(KERN_ERR
-                               "xt_hashlimit: can't allocate dsthash_ent\n");
-               return NULL;
-       }
-       memcpy(&ent->dst, dst, sizeof(ent->dst));
+                       pr_err("cannot allocate dsthash_ent\n");
+       } else {
+               memcpy(&ent->dst, dst, sizeof(ent->dst));
+               spin_lock_init(&ent->lock);
 
-       hlist_add_head(&ent->node, &ht->hash[hash_dst(ht, dst)]);
-       ht->count++;
+               spin_lock(&ent->lock);
+               hlist_add_head_rcu(&ent->node, &ht->hash[hash_dst(ht, dst)]);
+               ht->count++;
+       }
+       spin_unlock(&ht->lock);
        return ent;
 }
 
-static inline void
-dsthash_free(struct xt_hashlimit_htable *ht, struct dsthash_ent *ent)
+static void dsthash_free_rcu(struct rcu_head *head)
 {
-       hlist_del(&ent->node);
+       struct dsthash_ent *ent = container_of(head, struct dsthash_ent, rcu);
+
        kmem_cache_free(hashlimit_cachep, ent);
-       ht->count--;
 }
-static void htable_gc(unsigned long htlong);
 
-static int htable_create_v0(struct net *net, struct xt_hashlimit_info *minfo, u_int8_t family)
+static inline void
+dsthash_free(struct xt_hashlimit_htable *ht, struct dsthash_ent *ent)
 {
-       struct hashlimit_net *hashlimit_net = hashlimit_pernet(net);
-       struct xt_hashlimit_htable *hinfo;
-       unsigned int size;
-       unsigned int i;
-
-       if (minfo->cfg.size)
-               size = minfo->cfg.size;
-       else {
-               size = ((totalram_pages << PAGE_SHIFT) / 16384) /
-                      sizeof(struct list_head);
-               if (totalram_pages > (1024 * 1024 * 1024 / PAGE_SIZE))
-                       size = 8192;
-               if (size < 16)
-                       size = 16;
-       }
-       /* FIXME: don't use vmalloc() here or anywhere else -HW */
-       hinfo = vmalloc(sizeof(struct xt_hashlimit_htable) +
-                       sizeof(struct list_head) * size);
-       if (!hinfo) {
-               printk(KERN_ERR "xt_hashlimit: unable to create hashtable\n");
-               return -1;
-       }
-       minfo->hinfo = hinfo;
-
-       /* copy match config into hashtable config */
-       hinfo->cfg.mode        = minfo->cfg.mode;
-       hinfo->cfg.avg         = minfo->cfg.avg;
-       hinfo->cfg.burst       = minfo->cfg.burst;
-       hinfo->cfg.max         = minfo->cfg.max;
-       hinfo->cfg.gc_interval = minfo->cfg.gc_interval;
-       hinfo->cfg.expire      = minfo->cfg.expire;
-
-       if (family == NFPROTO_IPV4)
-               hinfo->cfg.srcmask = hinfo->cfg.dstmask = 32;
-       else
-               hinfo->cfg.srcmask = hinfo->cfg.dstmask = 128;
-
-       hinfo->cfg.size = size;
-       if (!hinfo->cfg.max)
-               hinfo->cfg.max = 8 * hinfo->cfg.size;
-       else if (hinfo->cfg.max < hinfo->cfg.size)
-               hinfo->cfg.max = hinfo->cfg.size;
-
-       for (i = 0; i < hinfo->cfg.size; i++)
-               INIT_HLIST_HEAD(&hinfo->hash[i]);
-
-       hinfo->use = 1;
-       hinfo->count = 0;
-       hinfo->family = family;
-       hinfo->rnd_initialized = false;
-       spin_lock_init(&hinfo->lock);
-       hinfo->pde = proc_create_data(minfo->name, 0,
-               (family == NFPROTO_IPV4) ?
-               hashlimit_net->ipt_hashlimit : hashlimit_net->ip6t_hashlimit,
-               &dl_file_ops, hinfo);
-       if (!hinfo->pde) {
-               vfree(hinfo);
-               return -1;
-       }
-       hinfo->net = net;
-
-       setup_timer(&hinfo->timer, htable_gc, (unsigned long )hinfo);
-       hinfo->timer.expires = jiffies + msecs_to_jiffies(hinfo->cfg.gc_interval);
-       add_timer(&hinfo->timer);
-
-       hlist_add_head(&hinfo->node, &hashlimit_net->htables);
-
-       return 0;
+       hlist_del_rcu(&ent->node);
+       call_rcu_bh(&ent->rcu, dsthash_free_rcu);
+       ht->count--;
 }
+static void htable_gc(unsigned long htlong);
 
 static int htable_create(struct net *net, struct xt_hashlimit_mtinfo1 *minfo,
                         u_int8_t family)
@@ -288,10 +228,8 @@ static int htable_create(struct net *net, struct xt_hashlimit_mtinfo1 *minfo,
        /* FIXME: don't use vmalloc() here or anywhere else -HW */
        hinfo = vmalloc(sizeof(struct xt_hashlimit_htable) +
                        sizeof(struct list_head) * size);
-       if (hinfo == NULL) {
-               printk(KERN_ERR "xt_hashlimit: unable to create hashtable\n");
-               return -1;
-       }
+       if (hinfo == NULL)
+               return -ENOMEM;
        minfo->hinfo = hinfo;
 
        /* copy match config into hashtable config */
@@ -317,7 +255,7 @@ static int htable_create(struct net *net, struct xt_hashlimit_mtinfo1 *minfo,
                &dl_file_ops, hinfo);
        if (hinfo->pde == NULL) {
                vfree(hinfo);
-               return -1;
+               return -ENOMEM;
        }
        hinfo->net = net;
 
@@ -577,57 +515,6 @@ hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo,
        return 0;
 }
 
-static bool
-hashlimit_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
-{
-       const struct xt_hashlimit_info *r = par->matchinfo;
-       struct xt_hashlimit_htable *hinfo = r->hinfo;
-       unsigned long now = jiffies;
-       struct dsthash_ent *dh;
-       struct dsthash_dst dst;
-
-       if (hashlimit_init_dst(hinfo, &dst, skb, par->thoff) < 0)
-               goto hotdrop;
-
-       spin_lock_bh(&hinfo->lock);
-       dh = dsthash_find(hinfo, &dst);
-       if (!dh) {
-               dh = dsthash_alloc_init(hinfo, &dst);
-               if (!dh) {
-                       spin_unlock_bh(&hinfo->lock);
-                       goto hotdrop;
-               }
-
-               dh->expires = jiffies + msecs_to_jiffies(hinfo->cfg.expire);
-               dh->rateinfo.prev = jiffies;
-               dh->rateinfo.credit = user2credits(hinfo->cfg.avg *
-                                                  hinfo->cfg.burst);
-               dh->rateinfo.credit_cap = user2credits(hinfo->cfg.avg *
-                                                      hinfo->cfg.burst);
-               dh->rateinfo.cost = user2credits(hinfo->cfg.avg);
-       } else {
-               /* update expiration timeout */
-               dh->expires = now + msecs_to_jiffies(hinfo->cfg.expire);
-               rateinfo_recalc(dh, now);
-       }
-
-       if (dh->rateinfo.credit >= dh->rateinfo.cost) {
-               /* We're underlimit. */
-               dh->rateinfo.credit -= dh->rateinfo.cost;
-               spin_unlock_bh(&hinfo->lock);
-               return true;
-       }
-
-       spin_unlock_bh(&hinfo->lock);
-
-       /* default case: we're overlimit, thus don't match */
-       return false;
-
-hotdrop:
-       *par->hotdrop = true;
-       return false;
-}
-
 static bool
 hashlimit_mt(const struct sk_buff *skb, const struct xt_match_param *par)
 {
@@ -640,15 +527,14 @@ hashlimit_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        if (hashlimit_init_dst(hinfo, &dst, skb, par->thoff) < 0)
                goto hotdrop;
 
-       spin_lock_bh(&hinfo->lock);
+       rcu_read_lock_bh();
        dh = dsthash_find(hinfo, &dst);
        if (dh == NULL) {
                dh = dsthash_alloc_init(hinfo, &dst);
                if (dh == NULL) {
-                       spin_unlock_bh(&hinfo->lock);
+                       rcu_read_unlock_bh();
                        goto hotdrop;
                }
-
                dh->expires = jiffies + msecs_to_jiffies(hinfo->cfg.expire);
                dh->rateinfo.prev = jiffies;
                dh->rateinfo.credit = user2credits(hinfo->cfg.avg *
@@ -665,11 +551,13 @@ hashlimit_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        if (dh->rateinfo.credit >= dh->rateinfo.cost) {
                /* below the limit */
                dh->rateinfo.credit -= dh->rateinfo.cost;
-               spin_unlock_bh(&hinfo->lock);
+               spin_unlock(&dh->lock);
+               rcu_read_unlock_bh();
                return !(info->cfg.mode & XT_HASHLIMIT_INVERT);
        }
 
-       spin_unlock_bh(&hinfo->lock);
+       spin_unlock(&dh->lock);
+       rcu_read_unlock_bh();
        /* default match is underlimit - so over the limit, we need to invert */
        return info->cfg.mode & XT_HASHLIMIT_INVERT;
 
@@ -678,83 +566,43 @@ hashlimit_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        return false;
 }
 
-static bool hashlimit_mt_check_v0(const struct xt_mtchk_param *par)
-{
-       struct net *net = par->net;
-       struct xt_hashlimit_info *r = par->matchinfo;
-
-       /* Check for overflow. */
-       if (r->cfg.burst == 0 ||
-           user2credits(r->cfg.avg * r->cfg.burst) < user2credits(r->cfg.avg)) {
-               printk(KERN_ERR "xt_hashlimit: overflow, try lower: %u/%u\n",
-                      r->cfg.avg, r->cfg.burst);
-               return false;
-       }
-       if (r->cfg.mode == 0 ||
-           r->cfg.mode > (XT_HASHLIMIT_HASH_DPT |
-                          XT_HASHLIMIT_HASH_DIP |
-                          XT_HASHLIMIT_HASH_SIP |
-                          XT_HASHLIMIT_HASH_SPT))
-               return false;
-       if (!r->cfg.gc_interval)
-               return false;
-       if (!r->cfg.expire)
-               return false;
-       if (r->name[sizeof(r->name) - 1] != '\0')
-               return false;
-
-       mutex_lock(&hashlimit_mutex);
-       r->hinfo = htable_find_get(net, r->name, par->match->family);
-       if (!r->hinfo && htable_create_v0(net, r, par->match->family) != 0) {
-               mutex_unlock(&hashlimit_mutex);
-               return false;
-       }
-       mutex_unlock(&hashlimit_mutex);
-
-       return true;
-}
-
-static bool hashlimit_mt_check(const struct xt_mtchk_param *par)
+static int hashlimit_mt_check(const struct xt_mtchk_param *par)
 {
        struct net *net = par->net;
        struct xt_hashlimit_mtinfo1 *info = par->matchinfo;
+       int ret;
 
        /* Check for overflow. */
        if (info->cfg.burst == 0 ||
            user2credits(info->cfg.avg * info->cfg.burst) <
            user2credits(info->cfg.avg)) {
-               printk(KERN_ERR "xt_hashlimit: overflow, try lower: %u/%u\n",
-                      info->cfg.avg, info->cfg.burst);
-               return false;
+               pr_info("overflow, try lower: %u/%u\n",
+                       info->cfg.avg, info->cfg.burst);
+               return -ERANGE;
        }
        if (info->cfg.gc_interval == 0 || info->cfg.expire == 0)
-               return false;
+               return -EINVAL;
        if (info->name[sizeof(info->name)-1] != '\0')
-               return false;
-       if (par->match->family == NFPROTO_IPV4) {
+               return -EINVAL;
+       if (par->family == NFPROTO_IPV4) {
                if (info->cfg.srcmask > 32 || info->cfg.dstmask > 32)
-                       return false;
+                       return -EINVAL;
        } else {
                if (info->cfg.srcmask > 128 || info->cfg.dstmask > 128)
-                       return false;
+                       return -EINVAL;
        }
 
        mutex_lock(&hashlimit_mutex);
-       info->hinfo = htable_find_get(net, info->name, par->match->family);
-       if (!info->hinfo && htable_create(net, info, par->match->family) != 0) {
-               mutex_unlock(&hashlimit_mutex);
-               return false;
+       info->hinfo = htable_find_get(net, info->name, par->family);
+       if (info->hinfo == NULL) {
+               ret = htable_create(net, info, par->family);
+               if (ret < 0) {
+                       mutex_unlock(&hashlimit_mutex);
+                       return ret;
+               }
        }
        mutex_unlock(&hashlimit_mutex);
-       return true;
-}
-
-static void
-hashlimit_mt_destroy_v0(const struct xt_mtdtor_param *par)
-{
-       const struct xt_hashlimit_info *r = par->matchinfo;
-
-       htable_put(r->hinfo);
+       return 0;
 }
 
 static void hashlimit_mt_destroy(const struct xt_mtdtor_param *par)
@@ -764,46 +612,7 @@ static void hashlimit_mt_destroy(const struct xt_mtdtor_param *par)
        htable_put(info->hinfo);
 }
 
-#ifdef CONFIG_COMPAT
-struct compat_xt_hashlimit_info {
-       char name[IFNAMSIZ];
-       struct hashlimit_cfg cfg;
-       compat_uptr_t hinfo;
-       compat_uptr_t master;
-};
-
-static void hashlimit_mt_compat_from_user(void *dst, const void *src)
-{
-       int off = offsetof(struct compat_xt_hashlimit_info, hinfo);
-
-       memcpy(dst, src, off);
-       memset(dst + off, 0, sizeof(struct compat_xt_hashlimit_info) - off);
-}
-
-static int hashlimit_mt_compat_to_user(void __user *dst, const void *src)
-{
-       int off = offsetof(struct compat_xt_hashlimit_info, hinfo);
-
-       return copy_to_user(dst, src, off) ? -EFAULT : 0;
-}
-#endif
-
 static struct xt_match hashlimit_mt_reg[] __read_mostly = {
-       {
-               .name           = "hashlimit",
-               .revision       = 0,
-               .family         = NFPROTO_IPV4,
-               .match          = hashlimit_mt_v0,
-               .matchsize      = sizeof(struct xt_hashlimit_info),
-#ifdef CONFIG_COMPAT
-               .compatsize     = sizeof(struct compat_xt_hashlimit_info),
-               .compat_from_user = hashlimit_mt_compat_from_user,
-               .compat_to_user = hashlimit_mt_compat_to_user,
-#endif
-               .checkentry     = hashlimit_mt_check_v0,
-               .destroy        = hashlimit_mt_destroy_v0,
-               .me             = THIS_MODULE
-       },
        {
                .name           = "hashlimit",
                .revision       = 1,
@@ -815,20 +624,6 @@ static struct xt_match hashlimit_mt_reg[] __read_mostly = {
                .me             = THIS_MODULE,
        },
 #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
-       {
-               .name           = "hashlimit",
-               .family         = NFPROTO_IPV6,
-               .match          = hashlimit_mt_v0,
-               .matchsize      = sizeof(struct xt_hashlimit_info),
-#ifdef CONFIG_COMPAT
-               .compatsize     = sizeof(struct compat_xt_hashlimit_info),
-               .compat_from_user = hashlimit_mt_compat_from_user,
-               .compat_to_user = hashlimit_mt_compat_to_user,
-#endif
-               .checkentry     = hashlimit_mt_check_v0,
-               .destroy        = hashlimit_mt_destroy_v0,
-               .me             = THIS_MODULE
-       },
        {
                .name           = "hashlimit",
                .revision       = 1,
@@ -888,12 +683,15 @@ static void dl_seq_stop(struct seq_file *s, void *v)
 static int dl_seq_real_show(struct dsthash_ent *ent, u_int8_t family,
                                   struct seq_file *s)
 {
+       int res;
+
+       spin_lock(&ent->lock);
        /* recalculate to show accurate numbers */
        rateinfo_recalc(ent, jiffies);
 
        switch (family) {
        case NFPROTO_IPV4:
-               return seq_printf(s, "%ld %pI4:%u->%pI4:%u %u %u %u\n",
+               res = seq_printf(s, "%ld %pI4:%u->%pI4:%u %u %u %u\n",
                                 (long)(ent->expires - jiffies)/HZ,
                                 &ent->dst.ip.src,
                                 ntohs(ent->dst.src_port),
@@ -901,9 +699,10 @@ static int dl_seq_real_show(struct dsthash_ent *ent, u_int8_t family,
                                 ntohs(ent->dst.dst_port),
                                 ent->rateinfo.credit, ent->rateinfo.credit_cap,
                                 ent->rateinfo.cost);
+               break;
 #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
        case NFPROTO_IPV6:
-               return seq_printf(s, "%ld %pI6:%u->%pI6:%u %u %u %u\n",
+               res = seq_printf(s, "%ld %pI6:%u->%pI6:%u %u %u %u\n",
                                 (long)(ent->expires - jiffies)/HZ,
                                 &ent->dst.ip6.src,
                                 ntohs(ent->dst.src_port),
@@ -911,11 +710,14 @@ static int dl_seq_real_show(struct dsthash_ent *ent, u_int8_t family,
                                 ntohs(ent->dst.dst_port),
                                 ent->rateinfo.credit, ent->rateinfo.credit_cap,
                                 ent->rateinfo.cost);
+               break;
 #endif
        default:
                BUG();
-               return 0;
+               res = 0;
        }
+       spin_unlock(&ent->lock);
+       return res;
 }
 
 static int dl_seq_show(struct seq_file *s, void *v)
@@ -1024,7 +826,7 @@ static int __init hashlimit_mt_init(void)
                                            sizeof(struct dsthash_ent), 0, 0,
                                            NULL);
        if (!hashlimit_cachep) {
-               printk(KERN_ERR "xt_hashlimit: unable to create slab cache\n");
+               pr_warning("unable to create slab cache\n");
                goto err2;
        }
        return 0;
@@ -1039,9 +841,11 @@ err1:
 
 static void __exit hashlimit_mt_exit(void)
 {
-       kmem_cache_destroy(hashlimit_cachep);
        xt_unregister_matches(hashlimit_mt_reg, ARRAY_SIZE(hashlimit_mt_reg));
        unregister_pernet_subsys(&hashlimit_net_ops);
+
+       rcu_barrier_bh();
+       kmem_cache_destroy(hashlimit_cachep);
 }
 
 module_init(hashlimit_mt_init);
index 64fc7f2..b8b3e13 100644 (file)
@@ -6,7 +6,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/netfilter.h>
@@ -54,17 +54,19 @@ helper_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        return ret;
 }
 
-static bool helper_mt_check(const struct xt_mtchk_param *par)
+static int helper_mt_check(const struct xt_mtchk_param *par)
 {
        struct xt_helper_info *info = par->matchinfo;
+       int ret;
 
-       if (nf_ct_l3proto_try_module_get(par->family) < 0) {
-               printk(KERN_WARNING "can't load conntrack support for "
-                                   "proto=%u\n", par->family);
-               return false;
+       ret = nf_ct_l3proto_try_module_get(par->family);
+       if (ret < 0) {
+               pr_info("cannot load conntrack support for proto=%u\n",
+                       par->family);
+               return ret;
        }
        info->name[29] = '\0';
-       return true;
+       return 0;
 }
 
 static void helper_mt_destroy(const struct xt_mtdtor_param *par)
index 7726154..be53f72 100644 (file)
@@ -39,10 +39,6 @@ static bool ttl_mt(const struct sk_buff *skb, const struct xt_match_param *par)
                        return ttl < info->ttl;
                case IPT_TTL_GT:
                        return ttl > info->ttl;
-               default:
-                       printk(KERN_WARNING "ipt_ttl: unknown mode %d\n",
-                               info->mode);
-                       return false;
        }
 
        return false;
@@ -56,20 +52,12 @@ static bool hl_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
        switch (info->mode) {
                case IP6T_HL_EQ:
                        return ip6h->hop_limit == info->hop_limit;
-                       break;
                case IP6T_HL_NE:
                        return ip6h->hop_limit != info->hop_limit;
-                       break;
                case IP6T_HL_LT:
                        return ip6h->hop_limit < info->hop_limit;
-                       break;
                case IP6T_HL_GT:
                        return ip6h->hop_limit > info->hop_limit;
-                       break;
-               default:
-                       printk(KERN_WARNING "ip6t_hl: unknown mode %d\n",
-                               info->mode);
-                       return false;
        }
 
        return false;
index ffc9638..8471d97 100644 (file)
@@ -8,6 +8,7 @@
  *     it under the terms of the GNU General Public License version 2 as
  *     published by the Free Software Foundation.
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/ip.h>
index e5d7e1f..88215dc 100644 (file)
@@ -5,6 +5,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/slab.h>
 #include <linux/module.h>
@@ -98,7 +99,7 @@ user2credits(u_int32_t user)
        return (user * HZ * CREDITS_PER_JIFFY) / XT_LIMIT_SCALE;
 }
 
-static bool limit_mt_check(const struct xt_mtchk_param *par)
+static int limit_mt_check(const struct xt_mtchk_param *par)
 {
        struct xt_rateinfo *r = par->matchinfo;
        struct xt_limit_priv *priv;
@@ -106,14 +107,14 @@ static bool limit_mt_check(const struct xt_mtchk_param *par)
        /* Check for overflow. */
        if (r->burst == 0
            || user2credits(r->avg * r->burst) < user2credits(r->avg)) {
-               printk("Overflow in xt_limit, try lower: %u/%u\n",
-                      r->avg, r->burst);
-               return false;
+               pr_info("Overflow, try lower: %u/%u\n",
+                       r->avg, r->burst);
+               return -ERANGE;
        }
 
        priv = kmalloc(sizeof(*priv), GFP_KERNEL);
        if (priv == NULL)
-               return false;
+               return -ENOMEM;
 
        /* For SMP, we only want to use one set of state. */
        r->master = priv;
@@ -125,7 +126,7 @@ static bool limit_mt_check(const struct xt_mtchk_param *par)
                r->credit_cap = user2credits(r->avg * r->burst); /* Credits full. */
                r->cost = user2credits(r->avg);
        }
-       return true;
+       return 0;
 }
 
 static void limit_mt_destroy(const struct xt_mtdtor_param *par)
index c200711..b971ce9 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/module.h>
 #include <linux/skbuff.h>
+#include <linux/if_arp.h>
 #include <linux/if_ether.h>
 #include <linux/etherdevice.h>
 
@@ -26,14 +27,18 @@ MODULE_ALIAS("ip6t_mac");
 
 static bool mac_mt(const struct sk_buff *skb, const struct xt_match_param *par)
 {
-    const struct xt_mac_info *info = par->matchinfo;
-
-    /* Is mac pointer valid? */
-    return skb_mac_header(skb) >= skb->head &&
-          skb_mac_header(skb) + ETH_HLEN <= skb->data
-          /* If so, compare... */
-          && ((!compare_ether_addr(eth_hdr(skb)->h_source, info->srcaddr))
-               ^ info->invert);
+       const struct xt_mac_info *info = par->matchinfo;
+       bool ret;
+
+       if (skb->dev == NULL || skb->dev->type != ARPHRD_ETHER)
+               return false;
+       if (skb_mac_header(skb) < skb->head)
+               return false;
+       if (skb_mac_header(skb) + ETH_HLEN > skb->data)
+               return false;
+       ret  = compare_ether_addr(eth_hdr(skb)->h_source, info->srcaddr) == 0;
+       ret ^= info->invert;
+       return ret;
 }
 
 static struct xt_match mac_mt_reg __read_mostly = {
index 1db07d8..035c468 100644 (file)
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
-MODULE_DESCRIPTION("Xtables: packet mark match");
+MODULE_DESCRIPTION("Xtables: packet mark operations");
 MODULE_ALIAS("ipt_mark");
 MODULE_ALIAS("ip6t_mark");
+MODULE_ALIAS("ipt_MARK");
+MODULE_ALIAS("ip6t_MARK");
+
+static unsigned int
+mark_tg(struct sk_buff *skb, const struct xt_target_param *par)
+{
+       const struct xt_mark_tginfo2 *info = par->targinfo;
+
+       skb->mark = (skb->mark & ~info->mask) ^ info->mark;
+       return XT_CONTINUE;
+}
 
 static bool
 mark_mt(const struct sk_buff *skb, const struct xt_match_param *par)
@@ -30,6 +41,15 @@ mark_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        return ((skb->mark & info->mask) == info->mark) ^ info->invert;
 }
 
+static struct xt_target mark_tg_reg __read_mostly = {
+       .name           = "MARK",
+       .revision       = 2,
+       .family         = NFPROTO_UNSPEC,
+       .target         = mark_tg,
+       .targetsize     = sizeof(struct xt_mark_tginfo2),
+       .me             = THIS_MODULE,
+};
+
 static struct xt_match mark_mt_reg __read_mostly = {
        .name           = "mark",
        .revision       = 1,
@@ -41,12 +61,23 @@ static struct xt_match mark_mt_reg __read_mostly = {
 
 static int __init mark_mt_init(void)
 {
-       return xt_register_match(&mark_mt_reg);
+       int ret;
+
+       ret = xt_register_target(&mark_tg_reg);
+       if (ret < 0)
+               return ret;
+       ret = xt_register_match(&mark_mt_reg);
+       if (ret < 0) {
+               xt_unregister_target(&mark_tg_reg);
+               return ret;
+       }
+       return 0;
 }
 
 static void __exit mark_mt_exit(void)
 {
        xt_unregister_match(&mark_mt_reg);
+       xt_unregister_target(&mark_tg_reg);
 }
 
 module_init(mark_mt_init);
index d06bb2d..83b77ce 100644 (file)
@@ -8,7 +8,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/udp.h>
@@ -26,29 +26,6 @@ MODULE_DESCRIPTION("Xtables: multiple port matching for TCP, UDP, UDP-Lite, SCTP
 MODULE_ALIAS("ipt_multiport");
 MODULE_ALIAS("ip6t_multiport");
 
-#if 0
-#define duprintf(format, args...) printk(format , ## args)
-#else
-#define duprintf(format, args...)
-#endif
-
-/* Returns 1 if the port is matched by the test, 0 otherwise. */
-static inline bool
-ports_match_v0(const u_int16_t *portlist, enum xt_multiport_flags flags,
-              u_int8_t count, u_int16_t src, u_int16_t dst)
-{
-       unsigned int i;
-       for (i = 0; i < count; i++) {
-               if (flags != XT_MULTIPORT_DESTINATION && portlist[i] == src)
-                       return true;
-
-               if (flags != XT_MULTIPORT_SOURCE && portlist[i] == dst)
-                       return true;
-       }
-
-       return false;
-}
-
 /* Returns 1 if the port is matched by the test, 0 otherwise. */
 static inline bool
 ports_match_v1(const struct xt_multiport_v1 *minfo,
@@ -63,7 +40,7 @@ ports_match_v1(const struct xt_multiport_v1 *minfo,
                if (minfo->pflags[i]) {
                        /* range port matching */
                        e = minfo->ports[++i];
-                       duprintf("src or dst matches with %d-%d?\n", s, e);
+                       pr_debug("src or dst matches with %d-%d?\n", s, e);
 
                        if (minfo->flags == XT_MULTIPORT_SOURCE
                            && src >= s && src <= e)
@@ -77,7 +54,7 @@ ports_match_v1(const struct xt_multiport_v1 *minfo,
                                return true ^ minfo->invert;
                } else {
                        /* exact port matching */
-                       duprintf("src or dst matches with %d?\n", s);
+                       pr_debug("src or dst matches with %d?\n", s);
 
                        if (minfo->flags == XT_MULTIPORT_SOURCE
                            && src == s)
@@ -94,30 +71,6 @@ ports_match_v1(const struct xt_multiport_v1 *minfo,
        return minfo->invert;
 }
 
-static bool
-multiport_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
-{
-       const __be16 *pptr;
-       __be16 _ports[2];
-       const struct xt_multiport *multiinfo = par->matchinfo;
-
-       if (par->fragoff != 0)
-               return false;
-
-       pptr = skb_header_pointer(skb, par->thoff, sizeof(_ports), _ports);
-       if (pptr == NULL) {
-               /* We've been asked to examine this packet, and we
-                * can't.  Hence, no choice but to drop.
-                */
-               duprintf("xt_multiport: Dropping evil offset=0 tinygram.\n");
-               *par->hotdrop = true;
-               return false;
-       }
-
-       return ports_match_v0(multiinfo->ports, multiinfo->flags,
-              multiinfo->count, ntohs(pptr[0]), ntohs(pptr[1]));
-}
-
 static bool
 multiport_mt(const struct sk_buff *skb, const struct xt_match_param *par)
 {
@@ -133,7 +86,7 @@ multiport_mt(const struct sk_buff *skb, const struct xt_match_param *par)
                /* We've been asked to examine this packet, and we
                 * can't.  Hence, no choice but to drop.
                 */
-               duprintf("xt_multiport: Dropping evil offset=0 tinygram.\n");
+               pr_debug("Dropping evil offset=0 tinygram.\n");
                *par->hotdrop = true;
                return false;
        }
@@ -158,16 +111,7 @@ check(u_int16_t proto,
                && count <= XT_MULTI_PORTS;
 }
 
-static bool multiport_mt_check_v0(const struct xt_mtchk_param *par)
-{
-       const struct ipt_ip *ip = par->entryinfo;
-       const struct xt_multiport *multiinfo = par->matchinfo;
-
-       return check(ip->proto, ip->invflags, multiinfo->flags,
-                    multiinfo->count);
-}
-
-static bool multiport_mt_check(const struct xt_mtchk_param *par)
+static int multiport_mt_check(const struct xt_mtchk_param *par)
 {
        const struct ipt_ip *ip = par->entryinfo;
        const struct xt_multiport_v1 *multiinfo = par->matchinfo;
@@ -176,16 +120,7 @@ static bool multiport_mt_check(const struct xt_mtchk_param *par)
                     multiinfo->count);
 }
 
-static bool multiport_mt6_check_v0(const struct xt_mtchk_param *par)
-{
-       const struct ip6t_ip6 *ip = par->entryinfo;
-       const struct xt_multiport *multiinfo = par->matchinfo;
-
-       return check(ip->proto, ip->invflags, multiinfo->flags,
-                    multiinfo->count);
-}
-
-static bool multiport_mt6_check(const struct xt_mtchk_param *par)
+static int multiport_mt6_check(const struct xt_mtchk_param *par)
 {
        const struct ip6t_ip6 *ip = par->entryinfo;
        const struct xt_multiport_v1 *multiinfo = par->matchinfo;
@@ -195,15 +130,6 @@ static bool multiport_mt6_check(const struct xt_mtchk_param *par)
 }
 
 static struct xt_match multiport_mt_reg[] __read_mostly = {
-       {
-               .name           = "multiport",
-               .family         = NFPROTO_IPV4,
-               .revision       = 0,
-               .checkentry     = multiport_mt_check_v0,
-               .match          = multiport_mt_v0,
-               .matchsize      = sizeof(struct xt_multiport),
-               .me             = THIS_MODULE,
-       },
        {
                .name           = "multiport",
                .family         = NFPROTO_IPV4,
@@ -213,15 +139,6 @@ static struct xt_match multiport_mt_reg[] __read_mostly = {
                .matchsize      = sizeof(struct xt_multiport_v1),
                .me             = THIS_MODULE,
        },
-       {
-               .name           = "multiport",
-               .family         = NFPROTO_IPV6,
-               .revision       = 0,
-               .checkentry     = multiport_mt6_check_v0,
-               .match          = multiport_mt_v0,
-               .matchsize      = sizeof(struct xt_multiport),
-               .me             = THIS_MODULE,
-       },
        {
                .name           = "multiport",
                .family         = NFPROTO_IPV6,
index 4169e20..8dcde13 100644 (file)
@@ -16,7 +16,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
 #include <linux/kernel.h>
 
@@ -382,14 +382,14 @@ static int __init xt_osf_init(void)
 
        err = nfnetlink_subsys_register(&xt_osf_nfnetlink);
        if (err < 0) {
-               printk(KERN_ERR "Failed (%d) to register OSF nsfnetlink helper.\n", err);
+               pr_err("Failed to register OSF nsfnetlink helper (%d)\n", err);
                goto err_out_exit;
        }
 
        err = xt_register_match(&xt_osf_match);
        if (err) {
-               printk(KERN_ERR "Failed (%d) to register OS fingerprint "
-                               "matching module.\n", err);
+               pr_err("Failed to register OS fingerprint "
+                      "matching module (%d)\n", err);
                goto err_out_remove;
        }
 
index 8d28ca5..d0bdf3d 100644 (file)
@@ -7,7 +7,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/netfilter_bridge.h>
@@ -83,25 +83,25 @@ match_outdev:
        return (!!ret ^ !(info->invert & XT_PHYSDEV_OP_OUT));
 }
 
-static bool physdev_mt_check(const struct xt_mtchk_param *par)
+static int physdev_mt_check(const struct xt_mtchk_param *par)
 {
        const struct xt_physdev_info *info = par->matchinfo;
 
        if (!(info->bitmask & XT_PHYSDEV_OP_MASK) ||
            info->bitmask & ~XT_PHYSDEV_OP_MASK)
-               return false;
+               return -EINVAL;
        if (info->bitmask & XT_PHYSDEV_OP_OUT &&
            (!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) ||
             info->invert & XT_PHYSDEV_OP_BRIDGED) &&
            par->hook_mask & ((1 << NF_INET_LOCAL_OUT) |
            (1 << NF_INET_FORWARD) | (1 << NF_INET_POST_ROUTING))) {
-               printk(KERN_WARNING "physdev match: using --physdev-out in the "
-                      "OUTPUT, FORWARD and POSTROUTING chains for non-bridged "
-                      "traffic is not supported anymore.\n");
+               pr_info("using --physdev-out in the OUTPUT, FORWARD and "
+                       "POSTROUTING chains for non-bridged traffic is not "
+                       "supported anymore.\n");
                if (par->hook_mask & (1 << NF_INET_LOCAL_OUT))
-                       return false;
+                       return -EINVAL;
        }
-       return true;
+       return 0;
 }
 
 static struct xt_match physdev_mt_reg __read_mostly = {
index 4cbfebd..1fa239c 100644 (file)
@@ -6,7 +6,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/skbuff.h>
@@ -116,9 +116,9 @@ policy_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        int ret;
 
        if (info->flags & XT_POLICY_MATCH_IN)
-               ret = match_policy_in(skb, info, par->match->family);
+               ret = match_policy_in(skb, info, par->family);
        else
-               ret = match_policy_out(skb, info, par->match->family);
+               ret = match_policy_out(skb, info, par->family);
 
        if (ret < 0)
                ret = info->flags & XT_POLICY_MATCH_NONE ? true : false;
@@ -128,32 +128,29 @@ policy_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        return ret;
 }
 
-static bool policy_mt_check(const struct xt_mtchk_param *par)
+static int policy_mt_check(const struct xt_mtchk_param *par)
 {
        const struct xt_policy_info *info = par->matchinfo;
 
        if (!(info->flags & (XT_POLICY_MATCH_IN|XT_POLICY_MATCH_OUT))) {
-               printk(KERN_ERR "xt_policy: neither incoming nor "
-                               "outgoing policy selected\n");
-               return false;
+               pr_info("neither incoming nor outgoing policy selected\n");
+               return -EINVAL;
        }
        if (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) |
            (1 << NF_INET_LOCAL_IN)) && info->flags & XT_POLICY_MATCH_OUT) {
-               printk(KERN_ERR "xt_policy: output policy not valid in "
-                               "PRE_ROUTING and INPUT\n");
-               return false;
+               pr_info("output policy not valid in PREROUTING and INPUT\n");
+               return -EINVAL;
        }
        if (par->hook_mask & ((1 << NF_INET_POST_ROUTING) |
            (1 << NF_INET_LOCAL_OUT)) && info->flags & XT_POLICY_MATCH_IN) {
-               printk(KERN_ERR "xt_policy: input policy not valid in "
-                               "POST_ROUTING and OUTPUT\n");
-               return false;
+               pr_info("input policy not valid in POSTROUTING and OUTPUT\n");
+               return -EINVAL;
        }
        if (info->len > XT_POLICY_MAX_ELEM) {
-               printk(KERN_ERR "xt_policy: too many policy elements\n");
-               return false;
+               pr_info("too many policy elements\n");
+               return -EINVAL;
        }
-       return true;
+       return 0;
 }
 
 static struct xt_match policy_mt_reg[] __read_mostly = {
index 2d55624..7c95d69 100644 (file)
@@ -44,19 +44,19 @@ quota_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        return ret;
 }
 
-static bool quota_mt_check(const struct xt_mtchk_param *par)
+static int quota_mt_check(const struct xt_mtchk_param *par)
 {
        struct xt_quota_info *q = par->matchinfo;
 
        if (q->flags & ~XT_QUOTA_MASK)
-               return false;
+               return -EINVAL;
 
        q->master = kmalloc(sizeof(*q->master), GFP_KERNEL);
        if (q->master == NULL)
-               return false;
+               return -ENOMEM;
 
        q->master->quota = q->quota;
-       return true;
+       return 0;
 }
 
 static void quota_mt_destroy(const struct xt_mtdtor_param *par)
index 4fc6a91..23805f8 100644 (file)
@@ -74,10 +74,11 @@ xt_rateest_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        return ret;
 }
 
-static bool xt_rateest_mt_checkentry(const struct xt_mtchk_param *par)
+static int xt_rateest_mt_checkentry(const struct xt_mtchk_param *par)
 {
        struct xt_rateest_match_info *info = par->matchinfo;
        struct xt_rateest *est1, *est2;
+       int ret = false;
 
        if (hweight32(info->flags & (XT_RATEEST_MATCH_ABS |
                                     XT_RATEEST_MATCH_REL)) != 1)
@@ -95,6 +96,7 @@ static bool xt_rateest_mt_checkentry(const struct xt_mtchk_param *par)
                goto err1;
        }
 
+       ret  = -ENOENT;
        est1 = xt_rateest_lookup(info->name1);
        if (!est1)
                goto err1;
@@ -109,12 +111,12 @@ static bool xt_rateest_mt_checkentry(const struct xt_mtchk_param *par)
 
        info->est1 = est1;
        info->est2 = est2;
-       return true;
+       return 0;
 
 err2:
        xt_rateest_put(est1);
 err1:
-       return false;
+       return -EINVAL;
 }
 
 static void xt_rateest_mt_destroy(const struct xt_mtdtor_param *par)
index 834b736..b88d63b 100644 (file)
@@ -12,6 +12,7 @@
  * Author: Stephen Frost <sfrost@snowman.net>
  * Copyright 2002-2003, Stephen Frost, 2.5.x port by laforge@netfilter.org
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/init.h>
 #include <linux/ip.h>
 #include <linux/ipv6.h>
@@ -35,8 +36,8 @@
 #include <linux/netfilter/xt_recent.h>
 
 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
-MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
-MODULE_DESCRIPTION("Xtables: \"recently-seen\" host matching for IPv4");
+MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
+MODULE_DESCRIPTION("Xtables: \"recently-seen\" host matching");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_recent");
 MODULE_ALIAS("ip6t_recent");
@@ -51,14 +52,14 @@ module_param(ip_list_tot, uint, 0400);
 module_param(ip_pkt_list_tot, uint, 0400);
 module_param(ip_list_hash_size, uint, 0400);
 module_param(ip_list_perms, uint, 0400);
-module_param(ip_list_uid, uint, 0400);
-module_param(ip_list_gid, uint, 0400);
+module_param(ip_list_uid, uint, S_IRUGO | S_IWUSR);
+module_param(ip_list_gid, uint, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(ip_list_tot, "number of IPs to remember per list");
 MODULE_PARM_DESC(ip_pkt_list_tot, "number of packets per IP address to remember (max. 255)");
 MODULE_PARM_DESC(ip_list_hash_size, "size of hash table used to look up IPs");
 MODULE_PARM_DESC(ip_list_perms, "permissions on /proc/net/xt_recent/* files");
-MODULE_PARM_DESC(ip_list_uid,"owner of /proc/net/xt_recent/* files");
-MODULE_PARM_DESC(ip_list_gid,"owning group of /proc/net/xt_recent/* files");
+MODULE_PARM_DESC(ip_list_uid, "default owner of /proc/net/xt_recent/* files");
+MODULE_PARM_DESC(ip_list_gid, "default owning group of /proc/net/xt_recent/* files");
 
 struct recent_entry {
        struct list_head        list;
@@ -84,9 +85,6 @@ struct recent_net {
        struct list_head        tables;
 #ifdef CONFIG_PROC_FS
        struct proc_dir_entry   *xt_recent;
-#ifdef CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT
-       struct proc_dir_entry   *ipt_recent;
-#endif
 #endif
 };
 
@@ -147,6 +145,25 @@ static void recent_entry_remove(struct recent_table *t, struct recent_entry *e)
        t->entries--;
 }
 
+/*
+ * Drop entries with timestamps older then 'time'.
+ */
+static void recent_entry_reap(struct recent_table *t, unsigned long time)
+{
+       struct recent_entry *e;
+
+       /*
+        * The head of the LRU list is always the oldest entry.
+        */
+       e = list_entry(t->lru_list.next, struct recent_entry, lru_list);
+
+       /*
+        * The last time stamp is the most recent.
+        */
+       if (time_after(time, e->stamps[e->index-1]))
+               recent_entry_remove(t, e);
+}
+
 static struct recent_entry *
 recent_entry_init(struct recent_table *t, const union nf_inet_addr *addr,
                  u_int16_t family, u_int8_t ttl)
@@ -218,7 +235,7 @@ recent_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        u_int8_t ttl;
        bool ret = info->invert;
 
-       if (par->match->family == NFPROTO_IPV4) {
+       if (par->family == NFPROTO_IPV4) {
                const struct iphdr *iph = ip_hdr(skb);
 
                if (info->side == XT_RECENT_DEST)
@@ -244,12 +261,12 @@ recent_mt(const struct sk_buff *skb, const struct xt_match_param *par)
 
        spin_lock_bh(&recent_lock);
        t = recent_table_lookup(recent_net, info->name);
-       e = recent_entry_lookup(t, &addr, par->match->family,
+       e = recent_entry_lookup(t, &addr, par->family,
                                (info->check_set & XT_RECENT_TTL) ? ttl : 0);
        if (e == NULL) {
                if (!(info->check_set & XT_RECENT_SET))
                        goto out;
-               e = recent_entry_init(t, &addr, par->match->family, ttl);
+               e = recent_entry_init(t, &addr, par->family, ttl);
                if (e == NULL)
                        *par->hotdrop = true;
                ret = !ret;
@@ -273,6 +290,10 @@ recent_mt(const struct sk_buff *skb, const struct xt_match_param *par)
                                break;
                        }
                }
+
+               /* info->seconds must be non-zero */
+               if (info->check_set & XT_RECENT_REAP)
+                       recent_entry_reap(t, time);
        }
 
        if (info->check_set & XT_RECENT_SET ||
@@ -285,7 +306,7 @@ out:
        return ret;
 }
 
-static bool recent_mt_check(const struct xt_mtchk_param *par)
+static int recent_mt_check(const struct xt_mtchk_param *par)
 {
        struct recent_net *recent_net = recent_pernet(par->net);
        const struct xt_recent_mtinfo *info = par->matchinfo;
@@ -294,41 +315,51 @@ static bool recent_mt_check(const struct xt_mtchk_param *par)
        struct proc_dir_entry *pde;
 #endif
        unsigned i;
-       bool ret = false;
+       int ret = -EINVAL;
 
        if (unlikely(!hash_rnd_inited)) {
                get_random_bytes(&hash_rnd, sizeof(hash_rnd));
                hash_rnd_inited = true;
        }
+       if (info->check_set & ~XT_RECENT_VALID_FLAGS) {
+               pr_info("Unsupported user space flags (%08x)\n",
+                       info->check_set);
+               return -EINVAL;
+       }
        if (hweight8(info->check_set &
                     (XT_RECENT_SET | XT_RECENT_REMOVE |
                      XT_RECENT_CHECK | XT_RECENT_UPDATE)) != 1)
-               return false;
+               return -EINVAL;
        if ((info->check_set & (XT_RECENT_SET | XT_RECENT_REMOVE)) &&
-           (info->seconds || info->hit_count))
-               return false;
+           (info->seconds || info->hit_count ||
+           (info->check_set & XT_RECENT_MODIFIERS)))
+               return -EINVAL;
+       if ((info->check_set & XT_RECENT_REAP) && !info->seconds)
+               return -EINVAL;
        if (info->hit_count > ip_pkt_list_tot) {
-               pr_info(KBUILD_MODNAME ": hitcount (%u) is larger than "
+               pr_info("hitcount (%u) is larger than "
                        "packets to be remembered (%u)\n",
                        info->hit_count, ip_pkt_list_tot);
-               return false;
+               return -EINVAL;
        }
        if (info->name[0] == '\0' ||
            strnlen(info->name, XT_RECENT_NAME_LEN) == XT_RECENT_NAME_LEN)
-               return false;
+               return -EINVAL;
 
        mutex_lock(&recent_mutex);
        t = recent_table_lookup(recent_net, info->name);
        if (t != NULL) {
                t->refcnt++;
-               ret = true;
+               ret = 0;
                goto out;
        }
 
        t = kzalloc(sizeof(*t) + sizeof(t->iphash[0]) * ip_list_hash_size,
                    GFP_KERNEL);
-       if (t == NULL)
+       if (t == NULL) {
+               ret = -ENOMEM;
                goto out;
+       }
        t->refcnt = 1;
        strcpy(t->name, info->name);
        INIT_LIST_HEAD(&t->lru_list);
@@ -339,26 +370,16 @@ static bool recent_mt_check(const struct xt_mtchk_param *par)
                  &recent_mt_fops, t);
        if (pde == NULL) {
                kfree(t);
-               goto out;
-       }
-       pde->uid = ip_list_uid;
-       pde->gid = ip_list_gid;
-#ifdef CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT
-       pde = proc_create_data(t->name, ip_list_perms, recent_net->ipt_recent,
-                     &recent_old_fops, t);
-       if (pde == NULL) {
-               remove_proc_entry(t->name, recent_net->xt_recent);
-               kfree(t);
+               ret = -ENOMEM;
                goto out;
        }
        pde->uid = ip_list_uid;
        pde->gid = ip_list_gid;
-#endif
 #endif
        spin_lock_bh(&recent_lock);
        list_add_tail(&t->list, &recent_net->tables);
        spin_unlock_bh(&recent_lock);
-       ret = true;
+       ret = 0;
 out:
        mutex_unlock(&recent_mutex);
        return ret;
@@ -377,9 +398,6 @@ static void recent_mt_destroy(const struct xt_mtdtor_param *par)
                list_del(&t->list);
                spin_unlock_bh(&recent_lock);
 #ifdef CONFIG_PROC_FS
-#ifdef CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT
-               remove_proc_entry(t->name, recent_net->ipt_recent);
-#endif
                remove_proc_entry(t->name, recent_net->xt_recent);
 #endif
                recent_table_flush(t);
@@ -471,84 +489,6 @@ static int recent_seq_open(struct inode *inode, struct file *file)
        return 0;
 }
 
-#ifdef CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT
-static int recent_old_seq_open(struct inode *inode, struct file *filp)
-{
-       static bool warned_of_old;
-
-       if (unlikely(!warned_of_old)) {
-               printk(KERN_INFO KBUILD_MODNAME ": Use of /proc/net/ipt_recent"
-                      " is deprecated; use /proc/net/xt_recent.\n");
-               warned_of_old = true;
-       }
-       return recent_seq_open(inode, filp);
-}
-
-static ssize_t recent_old_proc_write(struct file *file,
-                                    const char __user *input,
-                                    size_t size, loff_t *loff)
-{
-       const struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode);
-       struct recent_table *t = pde->data;
-       struct recent_entry *e;
-       char buf[sizeof("+255.255.255.255")], *c = buf;
-       union nf_inet_addr addr = {};
-       int add;
-
-       if (size > sizeof(buf))
-               size = sizeof(buf);
-       if (copy_from_user(buf, input, size))
-               return -EFAULT;
-
-       c = skip_spaces(c);
-
-       if (size - (c - buf) < 5)
-               return c - buf;
-       if (!strncmp(c, "clear", 5)) {
-               c += 5;
-               spin_lock_bh(&recent_lock);
-               recent_table_flush(t);
-               spin_unlock_bh(&recent_lock);
-               return c - buf;
-       }
-
-       switch (*c) {
-       case '-':
-               add = 0;
-               c++;
-               break;
-       case '+':
-               c++;
-       default:
-               add = 1;
-               break;
-       }
-       addr.ip = in_aton(c);
-
-       spin_lock_bh(&recent_lock);
-       e = recent_entry_lookup(t, &addr, NFPROTO_IPV4, 0);
-       if (e == NULL) {
-               if (add)
-                       recent_entry_init(t, &addr, NFPROTO_IPV4, 0);
-       } else {
-               if (add)
-                       recent_entry_update(t, e);
-               else
-                       recent_entry_remove(t, e);
-       }
-       spin_unlock_bh(&recent_lock);
-       return size;
-}
-
-static const struct file_operations recent_old_fops = {
-       .open           = recent_old_seq_open,
-       .read           = seq_read,
-       .write          = recent_old_proc_write,
-       .release        = seq_release_private,
-       .owner          = THIS_MODULE,
-};
-#endif
-
 static ssize_t
 recent_mt_proc_write(struct file *file, const char __user *input,
                     size_t size, loff_t *loff)
@@ -585,7 +525,7 @@ recent_mt_proc_write(struct file *file, const char __user *input,
                add = true;
                break;
        default:
-               printk(KERN_INFO KBUILD_MODNAME ": Need +ip, -ip or /\n");
+               pr_info("Need \"+ip\", \"-ip\" or \"/\"\n");
                return -EINVAL;
        }
 
@@ -600,8 +540,7 @@ recent_mt_proc_write(struct file *file, const char __user *input,
        }
 
        if (!succ) {
-               printk(KERN_INFO KBUILD_MODNAME ": illegal address written "
-                      "to procfs\n");
+               pr_info("illegal address written to procfs\n");
                return -EINVAL;
        }
 
@@ -637,21 +576,11 @@ static int __net_init recent_proc_net_init(struct net *net)
        recent_net->xt_recent = proc_mkdir("xt_recent", net->proc_net);
        if (!recent_net->xt_recent)
                return -ENOMEM;
-#ifdef CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT
-       recent_net->ipt_recent = proc_mkdir("ipt_recent", net->proc_net);
-       if (!recent_net->ipt_recent) {
-               proc_net_remove(net, "xt_recent");
-               return -ENOMEM;
-       }
-#endif
        return 0;
 }
 
 static void __net_exit recent_proc_net_exit(struct net *net)
 {
-#ifdef CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT
-       proc_net_remove(net, "ipt_recent");
-#endif
        proc_net_remove(net, "xt_recent");
 }
 #else
index a189ada..c3694df 100644 (file)
@@ -1,3 +1,4 @@
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <net/ip.h>
@@ -15,12 +16,6 @@ MODULE_DESCRIPTION("Xtables: SCTP protocol packet match");
 MODULE_ALIAS("ipt_sctp");
 MODULE_ALIAS("ip6t_sctp");
 
-#ifdef DEBUG_SCTP
-#define duprintf(format, args...) printk(format , ## args)
-#else
-#define duprintf(format, args...)
-#endif
-
 #define SCCHECK(cond, option, flag, invflag) (!((flag) & (option)) \
                                              || (!!((invflag) & (option)) ^ (cond)))
 
@@ -52,7 +47,7 @@ match_packet(const struct sk_buff *skb,
        const struct xt_sctp_flag_info *flag_info = info->flag_info;
        int flag_count = info->flag_count;
 
-#ifdef DEBUG_SCTP
+#ifdef DEBUG
        int i = 0;
 #endif
 
@@ -62,17 +57,19 @@ match_packet(const struct sk_buff *skb,
        do {
                sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch);
                if (sch == NULL || sch->length == 0) {
-                       duprintf("Dropping invalid SCTP packet.\n");
+                       pr_debug("Dropping invalid SCTP packet.\n");
                        *hotdrop = true;
                        return false;
                }
-
-               duprintf("Chunk num: %d\toffset: %d\ttype: %d\tlength: %d\tflags: %x\n",
-                               ++i, offset, sch->type, htons(sch->length), sch->flags);
-
+#ifdef DEBUG
+               pr_debug("Chunk num: %d\toffset: %d\ttype: %d\tlength: %d"
+                        "\tflags: %x\n",
+                        ++i, offset, sch->type, htons(sch->length),
+                        sch->flags);
+#endif
                offset += (ntohs(sch->length) + 3) & ~3;
 
-               duprintf("skb->len: %d\toffset: %d\n", skb->len, offset);
+               pr_debug("skb->len: %d\toffset: %d\n", skb->len, offset);
 
                if (SCTP_CHUNKMAP_IS_SET(info->chunkmap, sch->type)) {
                        switch (chunk_match_type) {
@@ -124,17 +121,17 @@ sctp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        sctp_sctphdr_t _sh;
 
        if (par->fragoff != 0) {
-               duprintf("Dropping non-first fragment.. FIXME\n");
+               pr_debug("Dropping non-first fragment.. FIXME\n");
                return false;
        }
 
        sh = skb_header_pointer(skb, par->thoff, sizeof(_sh), &_sh);
        if (sh == NULL) {
-               duprintf("Dropping evil TCP offset=0 tinygram.\n");
+               pr_debug("Dropping evil TCP offset=0 tinygram.\n");
                *par->hotdrop = true;
                return false;
        }
-       duprintf("spt: %d\tdpt: %d\n", ntohs(sh->source), ntohs(sh->dest));
+       pr_debug("spt: %d\tdpt: %d\n", ntohs(sh->source), ntohs(sh->dest));
 
        return  SCCHECK(ntohs(sh->source) >= info->spts[0]
                        && ntohs(sh->source) <= info->spts[1],
@@ -147,18 +144,22 @@ sctp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
                           XT_SCTP_CHUNK_TYPES, info->flags, info->invflags);
 }
 
-static bool sctp_mt_check(const struct xt_mtchk_param *par)
+static int sctp_mt_check(const struct xt_mtchk_param *par)
 {
        const struct xt_sctp_info *info = par->matchinfo;
 
-       return !(info->flags & ~XT_SCTP_VALID_FLAGS)
-               && !(info->invflags & ~XT_SCTP_VALID_FLAGS)
-               && !(info->invflags & ~info->flags)
-               && ((!(info->flags & XT_SCTP_CHUNK_TYPES)) ||
-                       (info->chunk_match_type &
-                               (SCTP_CHUNK_MATCH_ALL
-                               | SCTP_CHUNK_MATCH_ANY
-                               | SCTP_CHUNK_MATCH_ONLY)));
+       if (info->flags & ~XT_SCTP_VALID_FLAGS)
+               return -EINVAL;
+       if (info->invflags & ~XT_SCTP_VALID_FLAGS)
+               return -EINVAL;
+       if (info->invflags & ~info->flags)
+               return -EINVAL;
+       if (!(info->flags & XT_SCTP_CHUNK_TYPES))
+               return 0;
+       if (info->chunk_match_type & (SCTP_CHUNK_MATCH_ALL |
+           SCTP_CHUNK_MATCH_ANY | SCTP_CHUNK_MATCH_ONLY))
+               return 0;
+       return -EINVAL;
 }
 
 static struct xt_match sctp_mt_reg[] __read_mostly = {
index 6a90256..a9b1686 100644 (file)
@@ -9,7 +9,7 @@
  * published by the Free Software Foundation.
  *
  */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/netfilter/x_tables.h>
@@ -165,8 +165,7 @@ socket_match(const struct sk_buff *skb, const struct xt_match_param *par,
                        sk = NULL;
        }
 
-       pr_debug("socket match: proto %u %08x:%u -> %08x:%u "
-                "(orig %08x:%u) sock %p\n",
+       pr_debug("proto %u %08x:%u -> %08x:%u (orig %08x:%u) sock %p\n",
                 protocol, ntohl(saddr), ntohs(sport),
                 ntohl(daddr), ntohs(dport),
                 ntohl(iph->daddr), hp ? ntohs(hp->dest) : 0, sk);
index 4c946cb..bb12718 100644 (file)
@@ -37,50 +37,40 @@ state_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        return (sinfo->statemask & statebit);
 }
 
-static bool state_mt_check(const struct xt_mtchk_param *par)
+static int state_mt_check(const struct xt_mtchk_param *par)
 {
-       if (nf_ct_l3proto_try_module_get(par->match->family) < 0) {
-               printk(KERN_WARNING "can't load conntrack support for "
-                                   "proto=%u\n", par->match->family);
-               return false;
-       }
-       return true;
+       int ret;
+
+       ret = nf_ct_l3proto_try_module_get(par->family);
+       if (ret < 0)
+               pr_info("cannot load conntrack support for proto=%u\n",
+                       par->family);
+       return ret;
 }
 
 static void state_mt_destroy(const struct xt_mtdtor_param *par)
 {
-       nf_ct_l3proto_module_put(par->match->family);
+       nf_ct_l3proto_module_put(par->family);
 }
 
-static struct xt_match state_mt_reg[] __read_mostly = {
-       {
-               .name           = "state",
-               .family         = NFPROTO_IPV4,
-               .checkentry     = state_mt_check,
-               .match          = state_mt,
-               .destroy        = state_mt_destroy,
-               .matchsize      = sizeof(struct xt_state_info),
-               .me             = THIS_MODULE,
-       },
-       {
-               .name           = "state",
-               .family         = NFPROTO_IPV6,
-               .checkentry     = state_mt_check,
-               .match          = state_mt,
-               .destroy        = state_mt_destroy,
-               .matchsize      = sizeof(struct xt_state_info),
-               .me             = THIS_MODULE,
-       },
+static struct xt_match state_mt_reg __read_mostly = {
+       .name       = "state",
+       .family     = NFPROTO_UNSPEC,
+       .checkentry = state_mt_check,
+       .match      = state_mt,
+       .destroy    = state_mt_destroy,
+       .matchsize  = sizeof(struct xt_state_info),
+       .me         = THIS_MODULE,
 };
 
 static int __init state_mt_init(void)
 {
-       return xt_register_matches(state_mt_reg, ARRAY_SIZE(state_mt_reg));
+       return xt_register_match(&state_mt_reg);
 }
 
 static void __exit state_mt_exit(void)
 {
-       xt_unregister_matches(state_mt_reg, ARRAY_SIZE(state_mt_reg));
+       xt_unregister_match(&state_mt_reg);
 }
 
 module_init(state_mt_init);
index 937ce06..5aeca1d 100644 (file)
@@ -53,22 +53,20 @@ statistic_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        return ret;
 }
 
-static bool statistic_mt_check(const struct xt_mtchk_param *par)
+static int statistic_mt_check(const struct xt_mtchk_param *par)
 {
        struct xt_statistic_info *info = par->matchinfo;
 
        if (info->mode > XT_STATISTIC_MODE_MAX ||
            info->flags & ~XT_STATISTIC_MASK)
-               return false;
+               return -EINVAL;
 
        info->master = kzalloc(sizeof(*info->master), GFP_KERNEL);
-       if (info->master == NULL) {
-               printk(KERN_ERR KBUILD_MODNAME ": Out of memory\n");
-               return false;
-       }
+       if (info->master == NULL)
+               return -ENOMEM;
        info->master->count = info->u.nth.count;
 
-       return true;
+       return 0;
 }
 
 static void statistic_mt_destroy(const struct xt_mtdtor_param *par)
index 96801ff..f6d5112 100644 (file)
@@ -27,12 +27,10 @@ string_mt(const struct sk_buff *skb, const struct xt_match_param *par)
 {
        const struct xt_string_info *conf = par->matchinfo;
        struct ts_state state;
-       int invert;
+       bool invert;
 
        memset(&state, 0, sizeof(struct ts_state));
-
-       invert = (par->match->revision == 0 ? conf->u.v0.invert :
-                                   conf->u.v1.flags & XT_STRING_FLAG_INVERT);
+       invert = conf->u.v1.flags & XT_STRING_FLAG_INVERT;
 
        return (skb_find_text((struct sk_buff *)skb, conf->from_offset,
                             conf->to_offset, conf->config, &state)
@@ -41,7 +39,7 @@ string_mt(const struct sk_buff *skb, const struct xt_match_param *par)
 
 #define STRING_TEXT_PRIV(m) ((struct xt_string_info *)(m))
 
-static bool string_mt_check(const struct xt_mtchk_param *par)
+static int string_mt_check(const struct xt_mtchk_param *par)
 {
        struct xt_string_info *conf = par->matchinfo;
        struct ts_config *ts_conf;
@@ -49,26 +47,23 @@ static bool string_mt_check(const struct xt_mtchk_param *par)
 
        /* Damn, can't handle this case properly with iptables... */
        if (conf->from_offset > conf->to_offset)
-               return false;
+               return -EINVAL;
        if (conf->algo[XT_STRING_MAX_ALGO_NAME_SIZE - 1] != '\0')
-               return false;
+               return -EINVAL;
        if (conf->patlen > XT_STRING_MAX_PATTERN_SIZE)
-               return false;
-       if (par->match->revision == 1) {
-               if (conf->u.v1.flags &
-                   ~(XT_STRING_FLAG_IGNORECASE | XT_STRING_FLAG_INVERT))
-                       return false;
-               if (conf->u.v1.flags & XT_STRING_FLAG_IGNORECASE)
-                       flags |= TS_IGNORECASE;
-       }
+               return -EINVAL;
+       if (conf->u.v1.flags &
+           ~(XT_STRING_FLAG_IGNORECASE | XT_STRING_FLAG_INVERT))
+               return -EINVAL;
+       if (conf->u.v1.flags & XT_STRING_FLAG_IGNORECASE)
+               flags |= TS_IGNORECASE;
        ts_conf = textsearch_prepare(conf->algo, conf->pattern, conf->patlen,
                                     GFP_KERNEL, flags);
        if (IS_ERR(ts_conf))
-               return false;
+               return PTR_ERR(ts_conf);
 
        conf->config = ts_conf;
-
-       return true;
+       return 0;
 }
 
 static void string_mt_destroy(const struct xt_mtdtor_param *par)
@@ -76,38 +71,25 @@ static void string_mt_destroy(const struct xt_mtdtor_param *par)
        textsearch_destroy(STRING_TEXT_PRIV(par->matchinfo)->config);
 }
 
-static struct xt_match xt_string_mt_reg[] __read_mostly = {
-       {
-               .name           = "string",
-               .revision       = 0,
-               .family         = NFPROTO_UNSPEC,
-               .checkentry     = string_mt_check,
-               .match          = string_mt,
-               .destroy        = string_mt_destroy,
-               .matchsize      = sizeof(struct xt_string_info),
-               .me             = THIS_MODULE
-       },
-       {
-               .name           = "string",
-               .revision       = 1,
-               .family         = NFPROTO_UNSPEC,
-               .checkentry     = string_mt_check,
-               .match          = string_mt,
-               .destroy        = string_mt_destroy,
-               .matchsize      = sizeof(struct xt_string_info),
-               .me             = THIS_MODULE
-       },
+static struct xt_match xt_string_mt_reg __read_mostly = {
+       .name       = "string",
+       .revision   = 1,
+       .family     = NFPROTO_UNSPEC,
+       .checkentry = string_mt_check,
+       .match      = string_mt,
+       .destroy    = string_mt_destroy,
+       .matchsize  = sizeof(struct xt_string_info),
+       .me         = THIS_MODULE,
 };
 
 static int __init string_mt_init(void)
 {
-       return xt_register_matches(xt_string_mt_reg,
-                                  ARRAY_SIZE(xt_string_mt_reg));
+       return xt_register_match(&xt_string_mt_reg);
 }
 
 static void __exit string_mt_exit(void)
 {
-       xt_unregister_matches(xt_string_mt_reg, ARRAY_SIZE(xt_string_mt_reg));
+       xt_unregister_match(&xt_string_mt_reg);
 }
 
 module_init(string_mt_init);
index 1ebdc49..efa2ede 100644 (file)
@@ -1,3 +1,4 @@
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #include <linux/types.h>
 #include <linux/module.h>
 #include <net/ip.h>
@@ -19,13 +20,6 @@ MODULE_ALIAS("ipt_tcp");
 MODULE_ALIAS("ip6t_udp");
 MODULE_ALIAS("ip6t_tcp");
 
-#ifdef DEBUG_IP_FIREWALL_USER
-#define duprintf(format, args...) printk(format , ## args)
-#else
-#define duprintf(format, args...)
-#endif
-
-
 /* Returns 1 if the port is matched by the range, 0 otherwise */
 static inline bool
 port_match(u_int16_t min, u_int16_t max, u_int16_t port, bool invert)
@@ -46,7 +40,7 @@ tcp_find_option(u_int8_t option,
        u_int8_t _opt[60 - sizeof(struct tcphdr)];
        unsigned int i;
 
-       duprintf("tcp_match: finding option\n");
+       pr_debug("finding option\n");
 
        if (!optlen)
                return invert;
@@ -82,7 +76,7 @@ static bool tcp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
                   flag overwrite to pass the direction checks.
                */
                if (par->fragoff == 1) {
-                       duprintf("Dropping evil TCP offset=1 frag.\n");
+                       pr_debug("Dropping evil TCP offset=1 frag.\n");
                        *par->hotdrop = true;
                }
                /* Must not be a fragment. */
@@ -95,7 +89,7 @@ static bool tcp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        if (th == NULL) {
                /* We've been asked to examine this packet, and we
                   can't.  Hence, no choice but to drop. */
-               duprintf("Dropping evil TCP offset=0 tinygram.\n");
+               pr_debug("Dropping evil TCP offset=0 tinygram.\n");
                *par->hotdrop = true;
                return false;
        }
@@ -126,12 +120,12 @@ static bool tcp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        return true;
 }
 
-static bool tcp_mt_check(const struct xt_mtchk_param *par)
+static int tcp_mt_check(const struct xt_mtchk_param *par)
 {
        const struct xt_tcp *tcpinfo = par->matchinfo;
 
        /* Must specify no unknown invflags */
-       return !(tcpinfo->invflags & ~XT_TCP_INV_MASK);
+       return (tcpinfo->invflags & ~XT_TCP_INV_MASK) ? -EINVAL : 0;
 }
 
 static bool udp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
@@ -148,7 +142,7 @@ static bool udp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        if (uh == NULL) {
                /* We've been asked to examine this packet, and we
                   can't.  Hence, no choice but to drop. */
-               duprintf("Dropping evil UDP tinygram.\n");
+               pr_debug("Dropping evil UDP tinygram.\n");
                *par->hotdrop = true;
                return false;
        }
@@ -161,12 +155,12 @@ static bool udp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
                              !!(udpinfo->invflags & XT_UDP_INV_DSTPT));
 }
 
-static bool udp_mt_check(const struct xt_mtchk_param *par)
+static int udp_mt_check(const struct xt_mtchk_param *par)
 {
        const struct xt_udp *udpinfo = par->matchinfo;
 
        /* Must specify no unknown invflags */
-       return !(udpinfo->invflags & ~XT_UDP_INV_MASK);
+       return (udpinfo->invflags & ~XT_UDP_INV_MASK) ? -EINVAL : 0;
 }
 
 static struct xt_match tcpudp_mt_reg[] __read_mostly = {
index 93acaa5..d8556fd 100644 (file)
@@ -1,7 +1,6 @@
 /*
  *     xt_time
  *     Copyright © CC Computer Consultants GmbH, 2007
- *     Contact: <jengelh@computergmbh.de>
  *
  *     based on ipt_time by Fabrice MARIE <fabrice@netfilter.org>
  *     This is a module which is used for time matching
@@ -218,18 +217,18 @@ time_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        return true;
 }
 
-static bool time_mt_check(const struct xt_mtchk_param *par)
+static int time_mt_check(const struct xt_mtchk_param *par)
 {
        const struct xt_time_info *info = par->matchinfo;
 
        if (info->daytime_start > XT_TIME_MAX_DAYTIME ||
            info->daytime_stop > XT_TIME_MAX_DAYTIME) {
-               printk(KERN_WARNING "xt_time: invalid argument - start or "
-                      "stop time greater than 23:59:59\n");
-               return false;
+               pr_info("invalid argument - start or "
+                       "stop time greater than 23:59:59\n");
+               return -EDOM;
        }
 
-       return true;
+       return 0;
 }
 
 static struct xt_match xt_time_mt_reg __read_mostly = {
@@ -264,7 +263,7 @@ static void __exit time_mt_exit(void)
 
 module_init(time_mt_init);
 module_exit(time_mt_exit);
-MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
+MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
 MODULE_DESCRIPTION("Xtables: time-based matching");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_time");
index 24a5276..d7c05f0 100644 (file)
@@ -3,7 +3,6 @@
  *
  *     Original author: Don Cohen <don@isis.cs3-inc.com>
  *     (C) CC Computer Consultants GmbH, 2007
- *     Contact: <jengelh@computergmbh.de>
  */
 
 #include <linux/module.h>
@@ -117,7 +116,7 @@ static void __exit u32_mt_exit(void)
 
 module_init(u32_mt_init);
 module_exit(u32_mt_exit);
-MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
+MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
 MODULE_DESCRIPTION("Xtables: arbitrary byte matching");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_u32");
index da27a17..03f80a0 100644 (file)
@@ -47,8 +47,8 @@ static int ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int
 
        target = xt_request_find_target(AF_INET, t->u.user.name,
                                        t->u.user.revision);
-       if (!target)
-               return -ENOENT;
+       if (IS_ERR(target))
+               return PTR_ERR(target);
 
        t->u.kernel.target = target;
        par.table     = table;