* [PATCH 1/5][IPTABLES]: Import netfilter.h
@ 2008-01-24 19:01 Jan Engelhardt
2008-01-24 19:01 ` [PATCH 2/5][IPTABLES]: Give preference to iptables header files Jan Engelhardt
` (4 more replies)
0 siblings, 5 replies; 11+ messages in thread
From: Jan Engelhardt @ 2008-01-24 19:01 UTC (permalink / raw)
To: kaber; +Cc: Netfilter Developer Mailing List
Import netfilter.h from kernel to get hold of union nf_inet_addr
and fix a compile error in current iptable tarball releases when
used with non-development kernels.
Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de>
---
include/linux/netfilter.h | 315 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 315 insertions(+)
Index: iptables-modules/include/linux/netfilter.h
===================================================================
--- /dev/null
+++ iptables-modules/include/linux/netfilter.h
@@ -0,0 +1,315 @@
+#ifndef __LINUX_NETFILTER_H
+#define __LINUX_NETFILTER_H
+
+#ifdef __KERNEL__
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/skbuff.h>
+#include <linux/net.h>
+#include <linux/if.h>
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <linux/wait.h>
+#include <linux/list.h>
+#endif
+#include <linux/compiler.h>
+
+/* Responses from hook functions. */
+#define NF_DROP 0
+#define NF_ACCEPT 1
+#define NF_STOLEN 2
+#define NF_QUEUE 3
+#define NF_REPEAT 4
+#define NF_STOP 5
+#define NF_MAX_VERDICT NF_STOP
+
+/* we overload the higher bits for encoding auxiliary data such as the queue
+ * number. Not nice, but better than additional function arguments. */
+#define NF_VERDICT_MASK 0x0000ffff
+#define NF_VERDICT_BITS 16
+
+#define NF_VERDICT_QMASK 0xffff0000
+#define NF_VERDICT_QBITS 16
+
+#define NF_QUEUE_NR(x) (((x << NF_VERDICT_QBITS) & NF_VERDICT_QMASK) | NF_QUEUE)
+
+/* only for userspace compatibility */
+#ifndef __KERNEL__
+/* Generic cache responses from hook functions.
+ <= 0x2000 is used for protocol-flags. */
+#define NFC_UNKNOWN 0x4000
+#define NFC_ALTERED 0x8000
+#endif
+
+enum nf_inet_hooks {
+ NF_INET_PRE_ROUTING,
+ NF_INET_LOCAL_IN,
+ NF_INET_FORWARD,
+ NF_INET_LOCAL_OUT,
+ NF_INET_POST_ROUTING,
+ NF_INET_NUMHOOKS
+};
+
+union nf_inet_addr {
+ u_int32_t all[4];
+ __be32 ip;
+ __be32 ip6[4];
+ struct in_addr in;
+ struct in6_addr in6;
+};
+
+#ifdef __KERNEL__
+#ifdef CONFIG_NETFILTER
+
+extern void netfilter_init(void);
+
+/* Largest hook number + 1 */
+#define NF_MAX_HOOKS 8
+
+struct sk_buff;
+struct net_device;
+
+typedef unsigned int nf_hookfn(unsigned int hooknum,
+ struct sk_buff *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *));
+
+struct nf_hook_ops
+{
+ struct list_head list;
+
+ /* User fills in from here down. */
+ nf_hookfn *hook;
+ struct module *owner;
+ int pf;
+ int hooknum;
+ /* Hooks are ordered in ascending priority. */
+ int priority;
+};
+
+struct nf_sockopt_ops
+{
+ struct list_head list;
+
+ int pf;
+
+ /* Non-inclusive ranges: use 0/0/NULL to never get called. */
+ int set_optmin;
+ int set_optmax;
+ int (*set)(struct sock *sk, int optval, void __user *user, unsigned int len);
+ int (*compat_set)(struct sock *sk, int optval,
+ void __user *user, unsigned int len);
+
+ int get_optmin;
+ int get_optmax;
+ int (*get)(struct sock *sk, int optval, void __user *user, int *len);
+ int (*compat_get)(struct sock *sk, int optval,
+ void __user *user, int *len);
+
+ /* Use the module struct to lock set/get code in place */
+ struct module *owner;
+};
+
+/* Function to register/unregister hook points. */
+int nf_register_hook(struct nf_hook_ops *reg);
+void nf_unregister_hook(struct nf_hook_ops *reg);
+int nf_register_hooks(struct nf_hook_ops *reg, unsigned int n);
+void nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n);
+
+/* Functions to register get/setsockopt ranges (non-inclusive). You
+ need to check permissions yourself! */
+int nf_register_sockopt(struct nf_sockopt_ops *reg);
+void nf_unregister_sockopt(struct nf_sockopt_ops *reg);
+
+#ifdef CONFIG_SYSCTL
+/* Sysctl registration */
+extern struct ctl_path nf_net_netfilter_sysctl_path[];
+extern struct ctl_path nf_net_ipv4_netfilter_sysctl_path[];
+#endif /* CONFIG_SYSCTL */
+
+extern struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS];
+
+int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb,
+ struct net_device *indev, struct net_device *outdev,
+ int (*okfn)(struct sk_buff *), int thresh);
+
+/**
+ * nf_hook_thresh - call a netfilter hook
+ *
+ * Returns 1 if the hook has allowed the packet to pass. The function
+ * okfn must be invoked by the caller in this case. Any other return
+ * value indicates the packet has been consumed by the hook.
+ */
+static inline int nf_hook_thresh(int pf, unsigned int hook,
+ struct sk_buff *skb,
+ struct net_device *indev,
+ struct net_device *outdev,
+ int (*okfn)(struct sk_buff *), int thresh,
+ int cond)
+{
+ if (!cond)
+ return 1;
+#ifndef CONFIG_NETFILTER_DEBUG
+ if (list_empty(&nf_hooks[pf][hook]))
+ return 1;
+#endif
+ return nf_hook_slow(pf, hook, skb, indev, outdev, okfn, thresh);
+}
+
+static inline int nf_hook(int pf, unsigned int hook, struct sk_buff *skb,
+ struct net_device *indev, struct net_device *outdev,
+ int (*okfn)(struct sk_buff *))
+{
+ return nf_hook_thresh(pf, hook, skb, indev, outdev, okfn, INT_MIN, 1);
+}
+
+/* Activate hook; either okfn or kfree_skb called, unless a hook
+ returns NF_STOLEN (in which case, it's up to the hook to deal with
+ the consequences).
+
+ Returns -ERRNO if packet dropped. Zero means queued, stolen or
+ accepted.
+*/
+
+/* RR:
+ > I don't want nf_hook to return anything because people might forget
+ > about async and trust the return value to mean "packet was ok".
+
+ AK:
+ Just document it clearly, then you can expect some sense from kernel
+ coders :)
+*/
+
+/* This is gross, but inline doesn't cut it for avoiding the function
+ call in fast path: gcc doesn't inline (needs value tracking?). --RR */
+
+/* HX: It's slightly less gross now. */
+
+#define NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, thresh) \
+({int __ret; \
+if ((__ret=nf_hook_thresh(pf, hook, (skb), indev, outdev, okfn, thresh, 1)) == 1)\
+ __ret = (okfn)(skb); \
+__ret;})
+
+#define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond) \
+({int __ret; \
+if ((__ret=nf_hook_thresh(pf, hook, (skb), indev, outdev, okfn, INT_MIN, cond)) == 1)\
+ __ret = (okfn)(skb); \
+__ret;})
+
+#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) \
+ NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, INT_MIN)
+
+/* Call setsockopt() */
+int nf_setsockopt(struct sock *sk, int pf, int optval, char __user *opt,
+ int len);
+int nf_getsockopt(struct sock *sk, int pf, int optval, char __user *opt,
+ int *len);
+
+int compat_nf_setsockopt(struct sock *sk, int pf, int optval,
+ char __user *opt, int len);
+int compat_nf_getsockopt(struct sock *sk, int pf, int optval,
+ char __user *opt, int *len);
+
+/* Call this before modifying an existing packet: ensures it is
+ modifiable and linear to the point you care about (writable_len).
+ Returns true or false. */
+extern int skb_make_writable(struct sk_buff *skb, unsigned int writable_len);
+
+struct flowi;
+struct nf_queue_entry;
+
+struct nf_afinfo {
+ unsigned short family;
+ __sum16 (*checksum)(struct sk_buff *skb, unsigned int hook,
+ unsigned int dataoff, u_int8_t protocol);
+ int (*route)(struct dst_entry **dst, struct flowi *fl);
+ void (*saveroute)(const struct sk_buff *skb,
+ struct nf_queue_entry *entry);
+ int (*reroute)(struct sk_buff *skb,
+ const struct nf_queue_entry *entry);
+ int route_key_size;
+};
+
+extern const struct nf_afinfo *nf_afinfo[NPROTO];
+static inline const struct nf_afinfo *nf_get_afinfo(unsigned short family)
+{
+ return rcu_dereference(nf_afinfo[family]);
+}
+
+static inline __sum16
+nf_checksum(struct sk_buff *skb, unsigned int hook, unsigned int dataoff,
+ u_int8_t protocol, unsigned short family)
+{
+ const struct nf_afinfo *afinfo;
+ __sum16 csum = 0;
+
+ rcu_read_lock();
+ afinfo = nf_get_afinfo(family);
+ if (afinfo)
+ csum = afinfo->checksum(skb, hook, dataoff, protocol);
+ rcu_read_unlock();
+ return csum;
+}
+
+extern int nf_register_afinfo(const struct nf_afinfo *afinfo);
+extern void nf_unregister_afinfo(const struct nf_afinfo *afinfo);
+
+#include <net/flow.h>
+extern void (*ip_nat_decode_session)(struct sk_buff *, struct flowi *);
+
+static inline void
+nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, int family)
+{
+#ifdef CONFIG_NF_NAT_NEEDED
+ void (*decodefn)(struct sk_buff *, struct flowi *);
+
+ if (family == AF_INET) {
+ rcu_read_lock();
+ decodefn = rcu_dereference(ip_nat_decode_session);
+ if (decodefn)
+ decodefn(skb, fl);
+ rcu_read_unlock();
+ }
+#endif
+}
+
+#ifdef CONFIG_PROC_FS
+#include <linux/proc_fs.h>
+extern struct proc_dir_entry *proc_net_netfilter;
+#endif
+
+#else /* !CONFIG_NETFILTER */
+#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb)
+#define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond) (okfn)(skb)
+static inline int nf_hook_thresh(int pf, unsigned int hook,
+ struct sk_buff *skb,
+ struct net_device *indev,
+ struct net_device *outdev,
+ int (*okfn)(struct sk_buff *), int thresh,
+ int cond)
+{
+ return okfn(skb);
+}
+static inline int nf_hook(int pf, unsigned int hook, struct sk_buff *skb,
+ struct net_device *indev, struct net_device *outdev,
+ int (*okfn)(struct sk_buff *))
+{
+ return 1;
+}
+struct flowi;
+static inline void
+nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, int family) {}
+#endif /*CONFIG_NETFILTER*/
+
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+extern void (*ip_ct_attach)(struct sk_buff *, struct sk_buff *);
+extern void nf_ct_attach(struct sk_buff *, struct sk_buff *);
+extern void (*nf_ct_destroy)(struct nf_conntrack *);
+#else
+static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {}
+#endif
+
+#endif /*__KERNEL__*/
+#endif /*__LINUX_NETFILTER_H*/
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 2/5][IPTABLES]: Give preference to iptables header files
2008-01-24 19:01 [PATCH 1/5][IPTABLES]: Import netfilter.h Jan Engelhardt
@ 2008-01-24 19:01 ` Jan Engelhardt
2008-01-29 13:15 ` Patrick McHardy
2008-01-24 19:02 ` [PATCH 3/5][IPTABLES]: Build adjustments Jan Engelhardt
` (3 subsequent siblings)
4 siblings, 1 reply; 11+ messages in thread
From: Jan Engelhardt @ 2008-01-24 19:01 UTC (permalink / raw)
To: kaber; +Cc: Netfilter Developer Mailing List
Have the header files in the iptables source tree take precedence
over those from the kernel source. Otherwise, building the current
iptables from subversion just fails with kernels < 2.6.25.
Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de>
---
Makefile.am | 5 ++++-
configure.ac | 6 +++---
extensions/GNUmakefile.in | 5 +++--
3 files changed, 10 insertions(+), 6 deletions(-)
Index: iptables-modules/Makefile.am
===================================================================
--- iptables-modules.orig/Makefile.am
+++ iptables-modules/Makefile.am
@@ -1,7 +1,10 @@
# -*- Makefile -*-
AUTOMAKE_OPTIONS = foreign subdir-objects
-AM_CFLAGS = ${regular_CFLAGS} -I${top_srcdir}/include
+
+regular_CFLAGS := @regular_CFLAGS@
+kinclude_CFLAGS := @kinclude_CFLAGS@
+AM_CFLAGS = ${regular_CFLAGS} -I${top_srcdir}/include ${kinclude_CFLAGS}
SUBDIRS := extensions
if ENABLE_DEVEL
SUBDIRS += libipq
Index: iptables-modules/configure.ac
===================================================================
--- iptables-modules.orig/configure.ac
+++ iptables-modules/configure.ac
@@ -40,15 +40,15 @@ regular_CFLAGS="-D_LARGEFILE_SOURCE=1 -D
-D_REENTRANT -Wall -Waggregate-return -Wmissing-declarations \
-Wmissing-prototypes -Wredundant-decls -Wshadow -Wstrict-prototypes \
-Winline -pipe -DIPTABLES_VERSION=\\\"$PACKAGE_VERSION\\\" \
- -DIPT_LIB_DIR=\\\"\${iptdir}\\\" \
- -I\"$kbuilddir/include\" -I\"$ksourcedir/include\""
+ -DIPT_LIB_DIR=\\\"\${iptdir}\\\"";
+kinclude_CFLAGS="-I\"$kbuilddir/include\" -I\"$ksourcedir/include\"";
# Remove workarounds soon
regular_CFLAGS="$regular_CFLAGS -Wno-aggregate-return \
-Wno-missing-declarations -Wno-missing-prototypes \
-Wno-redundant-decls -Wno-shadow -Wno-strict-prototypes -Wno-inline"
-AC_SUBST([regular_CFLAGS])
+AC_SUBST([regular_CFLAGS kinclude_CFLAGS])
AC_SUBST([kbuilddir])
AC_SUBST([ksourcedir])
AC_SUBST([iptdir])
Index: iptables-modules/extensions/GNUmakefile.in
===================================================================
--- iptables-modules.orig/extensions/GNUmakefile.in
+++ iptables-modules/extensions/GNUmakefile.in
@@ -14,8 +14,9 @@ CCLD := ${CC}
CFLAGS := @CFLAGS@
LDFLAGS := @LDFLAGS@
regular_CFLAGS := @regular_CFLAGS@
+kinclude_CFLAGS := @kinclude_CFLAGS@
-AM_CFLAGS := ${regular_CFLAGS} -I${top_srcdir}/include
+AM_CFLAGS := ${regular_CFLAGS} -I${top_srcdir}/include ${kinclude_CFLAGS}
AM_DEPFLAGS = -Wp,-MMD,$(@D)/.$(@F).d,-MT,$@
ifeq (${V},)
@@ -88,7 +89,7 @@ clean:
rm -f *.o *.oo *.so *.a {matches,targets}[46].man initext4.c initext6.c;
distclean: clean
- rm -f .*.d *.dd;
+ rm -f .*.d .*.dd;
%.o: %.c
${AM_VERBOSE_CC} ${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} -D_INIT=$*_init ${CFLAGS} -o $@ -c $<;
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 3/5][IPTABLES]: Build adjustments
2008-01-24 19:01 [PATCH 1/5][IPTABLES]: Import netfilter.h Jan Engelhardt
2008-01-24 19:01 ` [PATCH 2/5][IPTABLES]: Give preference to iptables header files Jan Engelhardt
@ 2008-01-24 19:02 ` Jan Engelhardt
2008-01-29 13:16 ` Patrick McHardy
2008-01-24 19:02 ` [PATCH 4/5][IPTABLES]: libxt_CONNMARK revision 1 Jan Engelhardt
` (2 subsequent siblings)
4 siblings, 1 reply; 11+ messages in thread
From: Jan Engelhardt @ 2008-01-24 19:02 UTC (permalink / raw)
To: kaber; +Cc: Netfilter Developer Mailing List
A few build system changes.
* ip6tables needs IP6T_LIB_DIR
* correctly trigger rebuild of master manpages when
submanpages have been touched
Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de.
---
configure.ac | 2 +-
extensions/GNUmakefile.in | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
Index: iptables/configure.ac
===================================================================
--- iptables.orig/configure.ac
+++ iptables/configure.ac
@@ -40,7 +40,7 @@ regular_CFLAGS="-D_LARGEFILE_SOURCE=1 -D
-D_REENTRANT -Wall -Waggregate-return -Wmissing-declarations \
-Wmissing-prototypes -Wredundant-decls -Wshadow -Wstrict-prototypes \
-Winline -pipe -DIPTABLES_VERSION=\\\"$PACKAGE_VERSION\\\" \
- -DIPT_LIB_DIR=\\\"\${iptdir}\\\"";
+ -DIPT_LIB_DIR=\\\"\${iptdir}\\\" -DIP6T_LIB_DIR=\\\"\${iptdir}\\\"";
kinclude_CFLAGS="-I\"$kbuilddir/include\" -I\"$ksourcedir/include\"";
# Remove workarounds soon
Index: iptables/extensions/GNUmakefile.in
===================================================================
--- iptables.orig/extensions/GNUmakefile.in
+++ iptables/extensions/GNUmakefile.in
@@ -192,14 +192,14 @@ man_run = \
fi; \
done >$@;
-matches4.man: .initext4.dd $(wildcard lib*.man)
+matches4.man: .initext4.dd $(wildcard ${srcdir}/lib*.man)
$(call man_run,$(call ex_matches,${pfx_build_mod} ${pf4_build_mod}))
-matches6.man: .initext6.dd $(wildcard lib*.man)
+matches6.man: .initext6.dd $(wildcard ${srcdir}/lib*.man)
$(call man_run,$(call ex_matches,${pfx_build_mod} ${pf6_build_mod}))
-targets4.man: .initext4.dd $(wildcard lib*.man)
+targets4.man: .initext4.dd $(wildcard ${srcdir}/lib*.man)
$(call man_run,$(call ex_targets,${pfx_build_mod} ${pf4_build_mod}))
-targets6.man: .initext6.dd $(wildcard lib*.man)
+targets6.man: .initext6.dd $(wildcard ${srcdir}/lib*.man)
$(call man_run,$(call ex_targets,${pfx_build_mod} ${pf6_build_mod}))
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 4/5][IPTABLES]: libxt_CONNMARK revision 1
2008-01-24 19:01 [PATCH 1/5][IPTABLES]: Import netfilter.h Jan Engelhardt
2008-01-24 19:01 ` [PATCH 2/5][IPTABLES]: Give preference to iptables header files Jan Engelhardt
2008-01-24 19:02 ` [PATCH 3/5][IPTABLES]: Build adjustments Jan Engelhardt
@ 2008-01-24 19:02 ` Jan Engelhardt
2008-01-29 13:19 ` Patrick McHardy
2008-01-24 19:02 ` [PATCH 5/5][IPTABLES]: libxt_hashlimit " Jan Engelhardt
2008-01-29 13:10 ` [PATCH 1/5][IPTABLES]: Import netfilter.h Patrick McHardy
4 siblings, 1 reply; 11+ messages in thread
From: Jan Engelhardt @ 2008-01-24 19:02 UTC (permalink / raw)
To: kaber; +Cc: Netfilter Developer Mailing List
Add support for xt_CONNMARK target revision 1.
Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de>
---
extensions/libxt_CONNMARK.c | 267 ++++++++++++++++++++++++++++++++--
extensions/libxt_CONNMARK.man | 65 ++++++--
include/linux/netfilter/xt_CONNMARK.h | 5
3 files changed, 315 insertions(+), 22 deletions(-)
Index: iptables/extensions/libxt_CONNMARK.c
===================================================================
--- iptables.orig/extensions/libxt_CONNMARK.c
+++ iptables/extensions/libxt_CONNMARK.c
@@ -28,12 +28,10 @@
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_CONNMARK.h>
-#if 0
-struct markinfo {
- struct xt_entry_target t;
- struct ipt_connmark_target_info mark;
+enum {
+ F_MARK = 1 << 0,
+ F_SR_MARK = 1 << 1,
};
-#endif
/* Function which prints out usage message. */
static void CONNMARK_help(void)
@@ -55,6 +53,53 @@ static const struct option CONNMARK_opts
{ }
};
+static const struct option connmark_tg_opts[] = {
+ {.name = "set-xmark", .has_arg = true, .val = '='},
+ {.name = "set-mark", .has_arg = true, .val = '-'},
+ {.name = "and-mark", .has_arg = true, .val = '&'},
+ {.name = "or-mark", .has_arg = true, .val = '|'},
+ {.name = "xor-mark", .has_arg = true, .val = '^'},
+ {.name = "save-mark", .has_arg = false, .val = 'S'},
+ {.name = "restore-mark", .has_arg = false, .val = 'R'},
+ {.name = "ctmask", .has_arg = true, .val = 'c'},
+ {.name = "nfmask", .has_arg = true, .val = 'n'},
+ {.name = "mask", .has_arg = true, .val = 'm'},
+ {},
+};
+
+static void connmark_tg_help(void)
+{
+ printf(
+"CONNMARK target options:\n"
+" XOR-based operations:\n"
+" --set-xmark value[/ctmask] Zero mask bits and XOR ctmark with value\n"
+" --save-mark [--ctmask mask] [--nfmask mask]\n"
+" Copy ctmark to nfmark using masks\n"
+" --restore-mark [--ctmask mask] [--nfmask mask]\n"
+" Copy nfmark to ctmark using masks\n"
+" OR-based operations:\n"
+" --set-mark value[/mask] Set conntrack mark value\n"
+" --save-mark [--mask mask] Save the packet nfmark in the connection\n"
+" --restore-mark [--mask mask] Restore saved nfmark value\n"
+" Other operations:\n"
+" --and-mark value Binary AND the ctmark with bits\n"
+" --or-mark value Binary OR the ctmark with bits\n"
+" --xor-mark value Binary XOR the ctmark with bits\n"
+);
+}
+
+static void connmark_tg_init(struct xt_entry_target *target)
+{
+ struct xt_connmark_tginfo1 *info = (void *)target->data;
+
+ /*
+ * Need these defaults for --save-mark/--restore-mark if no
+ * --ctmark or --nfmask is given.
+ */
+ info->ctmask = ~0U;
+ info->nfmask = ~0U;
+}
+
/* Function which parses command options; returns true if it
ate an option */
static int
@@ -110,7 +155,110 @@ CONNMARK_parse(int c, char **argv, int i
return 1;
}
-static void CONNMARK_check(unsigned int flags)
+static int connmark_tg_parse(int c, char **argv, int invert,
+ unsigned int *flags, const void *entry,
+ struct xt_entry_target **target)
+{
+ struct xt_connmark_tginfo1 *info = (void *)(*target)->data;
+ unsigned int value, mask = ~0U;
+ char *end;
+
+ switch (c) {
+ case '=': /* --set-xmark */
+ case '-': /* --set-mark */
+ param_act(P_ONE_ACTION, "CONNMARK", *flags & F_MARK);
+ if (!strtonum(optarg, &end, &value, 0, ~0U))
+ param_act(P_BAD_VALUE, "CONNMARK", "--set-xmark/--set-mark", optarg);
+ if (*end == '/')
+ if (!strtonum(end + 1, &end, &mask, 0, ~0U))
+ param_act(P_BAD_VALUE, "CONNMARK", "--set-xmark/--set-mark", optarg);
+ if (*end != '\0')
+ param_act(P_BAD_VALUE, "CONNMARK", "--set-xmark/--set-mark", optarg);
+ info->mode = XT_CONNMARK_SET;
+ info->ctmark = value;
+ info->ctmask = mask;
+ if (c == '-')
+ info->ctmask |= value;
+ *flags |= F_MARK;
+ return true;
+
+ case '&': /* --and-mark */
+ param_act(P_ONE_ACTION, "CONNMARK", *flags & F_MARK);
+ if (!strtonum(optarg, NULL, &mask, 0, ~0U))
+ param_act(P_BAD_VALUE, "CONNMARK", "--and-mark", optarg);
+ info->mode = XT_CONNMARK_SET;
+ info->ctmark = 0;
+ info->ctmask = ~mask;
+ *flags |= F_MARK;
+ return true;
+
+ case '|': /* --or-mark */
+ param_act(P_ONE_ACTION, "CONNMARK", *flags & F_MARK);
+ if (!strtonum(optarg, NULL, &value, 0, ~0U))
+ param_act(P_BAD_VALUE, "CONNMARK", "--or-mark", optarg);
+ info->mode = XT_CONNMARK_SET;
+ info->ctmark = value;
+ info->ctmask = value;
+ *flags |= F_MARK;
+ return true;
+
+ case '^': /* --xor-mark */
+ param_act(P_ONE_ACTION, "CONNMARK", *flags & F_MARK);
+ if (!strtonum(optarg, NULL, &value, 0, ~0U))
+ param_act(P_BAD_VALUE, "CONNMARK", "--xor-mark", optarg);
+ info->mode = XT_CONNMARK_SET;
+ info->ctmark = value;
+ info->ctmask = 0;
+ *flags |= F_MARK;
+ return true;
+
+ case 'S': /* --save-mark */
+ param_act(P_ONE_ACTION, "CONNMARK", *flags & F_MARK);
+ info->mode = XT_CONNMARK_SAVE;
+ *flags |= F_MARK | F_SR_MARK;
+ return true;
+
+ case 'R': /* --restore-mark */
+ param_act(P_ONE_ACTION, "CONNMARK", *flags & F_MARK);
+ info->mode = XT_CONNMARK_RESTORE;
+ *flags |= F_MARK | F_SR_MARK;
+ return true;
+
+ case 'n': /* --nfmask */
+ if (!(*flags & F_SR_MARK))
+ exit_error(PARAMETER_PROBLEM, "CONNMARK: --save-mark "
+ "or --restore-mark is required for "
+ "--nfmask");
+ if (!strtonum(optarg, NULL, &value, 0, ~0U))
+ param_act(P_BAD_VALUE, "CONNMARK", "--nfmask", optarg);
+ info->nfmask = value;
+ return true;
+
+ case 'c': /* --ctmask */
+ if (!(*flags & F_SR_MARK))
+ exit_error(PARAMETER_PROBLEM, "CONNMARK: --save-mark "
+ "or --restore-mark is required for "
+ "--ctmask");
+ if (!strtonum(optarg, NULL, &value, 0, ~0U))
+ param_act(P_BAD_VALUE, "CONNMARK", "--ctmask", optarg);
+ info->ctmask = value;
+ return true;
+
+ case 'm': /* --mask */
+ if (!(*flags & F_SR_MARK))
+ exit_error(PARAMETER_PROBLEM, "CONNMARK: --save-mark "
+ "or --restore-mark is required for "
+ "--mask");
+ if (!strtonum(optarg, NULL, &value, 0, ~0U))
+ param_act(P_BAD_VALUE, "CONNMARK", "--mask", optarg);
+ info->nfmask = info->ctmask = value;
+ return true;
+ }
+
+ return false;
+}
+
+static void connmark_tg_check(unsigned int flags)
{
if (!flags)
exit_error(PARAMETER_PROBLEM,
@@ -159,6 +307,50 @@ static void CONNMARK_print(const void *i
}
}
+static void
+connmark_tg_print(const void *ip, const struct xt_entry_target *target,
+ int numeric)
+{
+ const struct xt_connmark_tginfo1 *info = (const void *)target->data;
+
+ switch (info->mode) {
+ case XT_CONNMARK_SET:
+ if (info->ctmark == 0)
+ printf("CONNMARK and 0x%x ",
+ (unsigned int)(u_int32_t)~info->ctmask);
+ else if (info->ctmark == info->ctmask)
+ printf("CONNMARK or 0x%x ", info->ctmark);
+ else if (info->ctmask == 0)
+ printf("CONNMARK xor 0x%x ", info->ctmark);
+ else
+ printf("CONNMARK xset 0x%x/0x%x ",
+ info->ctmark, info->ctmask);
+ break;
+ case XT_CONNMARK_SAVE:
+ if (info->nfmask == ~0U && info->ctmask == ~0U)
+ printf("CONNMARK save ");
+ else if (info->nfmask == info->ctmask)
+ printf("CONNMARK save mask 0x%x ", info->nfmask);
+ else
+ printf("CONNMARK save nfmask 0x%x ctmask ~0x%x ",
+ info->nfmask, info->ctmask);
+ break;
+ case XT_CONNMARK_RESTORE:
+ if (info->ctmask == ~0U && info->nfmask == ~0U)
+ printf("CONNMARK restore ");
+ else if (info->ctmask == info->nfmask)
+ printf("CONNMARK restore mask 0x%x ", info->ctmask);
+ else
+ printf("CONNMARK restore ctmask 0x%x nfmask ~0x%x ",
+ info->ctmask, info->nfmask);
+ break;
+
+ default:
+ printf("ERROR: UNKNOWN CONNMARK MODE");
+ break;
+ }
+}
+
/* Saves the target into in parsable form to stdout. */
static void CONNMARK_save(const void *ip, const struct xt_entry_target *target)
{
@@ -194,16 +386,40 @@ static void CONNMARK_init(struct xt_entr
markinfo->mask = 0xffffffffUL;
}
+static void
+connmark_tg_save(const void *ip, const struct xt_entry_target *target)
+{
+ const struct xt_connmark_tginfo1 *info = (const void *)target->data;
+
+ switch (info->mode) {
+ case XT_CONNMARK_SET:
+ printf("--set-xmark 0x%x/0x%x ", info->ctmark, info->ctmask);
+ break;
+ case XT_CONNMARK_SAVE:
+ printf("--save-mark --nfmask 0x%x --ctmask 0x%x ",
+ info->nfmask, info->ctmask);
+ break;
+ case XT_CONNMARK_RESTORE:
+ printf("--restore-mark --nfmask 0x%x --ctmask 0x%x ",
+ info->nfmask, info->ctmask);
+ break;
+ default:
+ printf("ERROR: UNKNOWN CONNMARK MODE");
+ break;
+ }
+}
+
static struct xtables_target connmark_target = {
.family = AF_INET,
.name = "CONNMARK",
+ .revision = 0,
.version = IPTABLES_VERSION,
.size = XT_ALIGN(sizeof(struct xt_connmark_target_info)),
.userspacesize = XT_ALIGN(sizeof(struct xt_connmark_target_info)),
.help = CONNMARK_help,
.init = CONNMARK_init,
.parse = CONNMARK_parse,
- .final_check = CONNMARK_check,
+ .final_check = connmark_tg_check,
.print = CONNMARK_print,
.save = CONNMARK_save,
.extra_opts = CONNMARK_opts,
@@ -212,20 +428,55 @@ static struct xtables_target connmark_ta
static struct xtables_target connmark_target6 = {
.family = AF_INET6,
.name = "CONNMARK",
+ .revision = 0,
.version = IPTABLES_VERSION,
.size = XT_ALIGN(sizeof(struct xt_connmark_target_info)),
.userspacesize = XT_ALIGN(sizeof(struct xt_connmark_target_info)),
.help = CONNMARK_help,
.init = CONNMARK_init,
.parse = CONNMARK_parse,
- .final_check = CONNMARK_check,
+ .final_check = connmark_tg_check,
.print = CONNMARK_print,
.save = CONNMARK_save,
.extra_opts = CONNMARK_opts,
};
+static struct xtables_target connmark_tg_reg = {
+ .version = IPTABLES_VERSION,
+ .name = "CONNMARK",
+ .revision = 1,
+ .family = AF_INET,
+ .size = XT_ALIGN(sizeof(struct xt_connmark_tginfo1)),
+ .userspacesize = XT_ALIGN(sizeof(struct xt_connmark_tginfo1)),
+ .help = connmark_tg_help,
+ .init = connmark_tg_init,
+ .parse = connmark_tg_parse,
+ .final_check = connmark_tg_check,
+ .print = connmark_tg_print,
+ .save = connmark_tg_save,
+ .extra_opts = connmark_tg_opts,
+};
+
+static struct xtables_target connmark_tg6_reg = {
+ .version = IPTABLES_VERSION,
+ .name = "CONNMARK",
+ .revision = 1,
+ .family = AF_INET6,
+ .size = XT_ALIGN(sizeof(struct xt_connmark_tginfo1)),
+ .userspacesize = XT_ALIGN(sizeof(struct xt_connmark_tginfo1)),
+ .help = connmark_tg_help,
+ .init = connmark_tg_init,
+ .parse = connmark_tg_parse,
+ .final_check = connmark_tg_check,
+ .print = connmark_tg_print,
+ .save = connmark_tg_save,
+ .extra_opts = connmark_tg_opts,
+};
+
void _init(void)
{
xtables_register_target(&connmark_target);
xtables_register_target(&connmark_target6);
+ xtables_register_target(&connmark_tg_reg);
+ xtables_register_target(&connmark_tg6_reg);
}
Index: iptables/extensions/libxt_CONNMARK.man
===================================================================
--- iptables.orig/extensions/libxt_CONNMARK.man
+++ iptables/extensions/libxt_CONNMARK.man
@@ -1,15 +1,52 @@
-This module sets the netfilter mark value associated with a connection
+This module sets the netfilter mark value associated with a connection.
.TP
-.B --set-mark mark[/mask]
-Set connection mark. If a mask is specified then only those bits set in the
-mask is modified.
-.TP
-.B --save-mark [--mask mask]
-Copy the netfilter packet mark value to the connection mark. If a mask
-is specified then only those bits are copied.
-.TP
-.B --restore-mark [--mask mask]
-Copy the connection mark value to the packet. If a mask is specified
-then only those bits are copied. This is only valid in the
-.B mangle
-table.
+\fB--set-xmark\fR \fIvalue\fR[\fB/\fR\fImask\fR]
+Zero out the bits given by \fImask\fR and XOR \fIvalue\fR into the ctmark.
+.TP
+\fB--save-mark\fR [\fB--nfmask\fR \fInfmask\fR] [\fB--ctmask\fR \fIctmask\fR]
+Copy the packet mark (nfmark) to the connection mark (ctmark) using the given
+masks. The new nfmark value is determined as follows:
+.IP
+ctmark = (ctmark & ~ctmask) ^ (nfmark & nfmask)
+.IP
+i.e. \fIctmask\fR defines what bits to clear and \fInfmask\fR what bits of the
+nfmark to XOR into the ctmark. \fIctmask\fR and \fInfmask\fR default to
+0xFFFFFFFF.
+.TP
+\fB--restore-mark\fR [\fB--nfmask\fR \fInfmask\fR] [\fB--ctmask\fR \fIctmask\fR]
+Copy the connection mark (ctmark) to the packet mark (nfmark) using the given
+masks. The new ctmark value is determined as follows:
+.IP
+nfmark = (nfmark & ~\fInfmask\fR) ^ (ctmark & \fIctmask\fR);
+.IP
+i.e. \fInfmask\fR defines what bits to clear and \fIctmask\fR what bits of the
+ctmark to XOR into the nfmark. \fIctmask\fR and \fInfmask\fR default to
+0xFFFFFFFF.
+.IP
+\fB--restore-mark\fR is only valid in the \fBmangle\fR table.
+.PP
+The following mnemonics are available for \fB--set-xmark\fR:
+.TP
+\fB--and-mark\fR \fIbits\fR
+Binary AND the ctmark with \fIbits\fR. (Mnemonic for \fB--set-xmark
+0/\fR\fIinvbits\fR, where \fIinvbits\fR is the binary negation of \fIbits\fR.)
+.TP
+\fB--or-mark\fR \fIbits\fR
+Binary OR the ctmark with \fIbits\fR. (Mnemonic for \fB--set-xmark\fR
+\fIbits\fR\fB/\fR\fIbits\fR.)
+.TP
+\fB--xor-mark\fR \fIbits\fR
+Binary XOR the ctmark with \fIbits\fR. (Mnemonic for \fB--set-xmark\fR
+\fIbits\fR\fB/0\fR.)
+.TP
+\fB--set-mark\fR \fIvalue\fR[\fB/\fR\fImask\fR]
+Set the connection mark. If a mask is specified then only those bits set in the
+mask are modified.
+.TP
+\fB--save-mark\fR [\fB--mask\fR \fImask\fR]
+Copy the nfmark to the ctmark. If a mask is specified, only those bits are
+copied.
+.TP
+\fB--restore-mark\fR [\fB--mask\fR \fImask\fR]
+Copy the ctmark to the nfmark. If a mask is specified, only those bits are
+copied. This is only valid in the \fBmangle\fR table.
Index: iptables/include/linux/netfilter/xt_CONNMARK.h
===================================================================
--- iptables.orig/include/linux/netfilter/xt_CONNMARK.h
+++ iptables/include/linux/netfilter/xt_CONNMARK.h
@@ -22,4 +22,9 @@ struct xt_connmark_target_info {
u_int8_t mode;
};
+struct xt_connmark_tginfo1 {
+ u_int32_t ctmark, ctmask, nfmask;
+ u_int8_t mode;
+};
+
#endif /*_XT_CONNMARK_H_target*/
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 5/5][IPTABLES]: libxt_hashlimit revision 1
2008-01-24 19:01 [PATCH 1/5][IPTABLES]: Import netfilter.h Jan Engelhardt
` (2 preceding siblings ...)
2008-01-24 19:02 ` [PATCH 4/5][IPTABLES]: libxt_CONNMARK revision 1 Jan Engelhardt
@ 2008-01-24 19:02 ` Jan Engelhardt
2008-01-29 13:10 ` [PATCH 1/5][IPTABLES]: Import netfilter.h Patrick McHardy
4 siblings, 0 replies; 11+ messages in thread
From: Jan Engelhardt @ 2008-01-24 19:02 UTC (permalink / raw)
To: kaber; +Cc: Netfilter Developer Mailing List
Add support for xt_hashlimit match revision 1.
Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de>
---
extensions/libxt_hashlimit.c | 398 ++++++++++++++++++++++++++++++---
extensions/libxt_hashlimit.man | 80 ++++--
include/linux/netfilter/xt_hashlimit.h | 39 ++-
3 files changed, 456 insertions(+), 61 deletions(-)
Index: iptables/extensions/libxt_hashlimit.c
===================================================================
--- iptables.orig/extensions/libxt_hashlimit.c
+++ iptables/extensions/libxt_hashlimit.c
@@ -10,7 +10,7 @@
*
* Error corections by nmalykh@bilim.com (22.01.2005)
*/
-
+#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -45,6 +45,27 @@ static void hashlimit_help(void)
"\n", IPTABLES_VERSION, XT_HASHLIMIT_BURST);
}
+static void hashlimit_mt_help(void)
+{
+ printf(
+"hashlimit match options:\n"
+" --hashlimit-upto <avg> max average match rate\n"
+" [Packets per second unless followed by \n"
+" /sec /minute /hour /day postfixes]\n"
+" --hashlimit-above <avg> min average match rate\n"
+" --hashlimit-mode <mode> mode is a comma-separated list of\n"
+" dstip,srcip,dstport,srcport (or none)\n"
+" --hashlimit-srcmask <length> source address grouping prefix length\n"
+" --hashlimit-dstmask <length> destination address grouping prefix length\n"
+" --hashlimit-name <name> name for /proc/net/ipt_hashlimit\n"
+" --hashlimit-burst <num> number to match in a burst, default %u\n"
+" --hashlimit-htable-size <num> number of hashtable buckets\n"
+" --hashlimit-htable-max <num> number of hashtable entries\n"
+" --hashlimit-htable-gcinterval interval between garbage collection runs\n"
+" --hashlimit-htable-expire after which time are idle entries expired?\n"
+"\n", XT_HASHLIMIT_BURST);
+}
+
static const struct option hashlimit_opts[] = {
{ "hashlimit", 1, NULL, '%' },
{ "hashlimit-burst", 1, NULL, '$' },
@@ -57,6 +78,22 @@ static const struct option hashlimit_opt
{ }
};
+static const struct option hashlimit_mt_opts[] = {
+ {.name = "hashlimit-upto", .has_arg = true, .val = '%'},
+ {.name = "hashlimit-above", .has_arg = true, .val = '^'},
+ {.name = "hashlimit", .has_arg = true, .val = '%'},
+ {.name = "hashlimit-srcmask", .has_arg = true, .val = '<'},
+ {.name = "hashlimit-dstmask", .has_arg = true, .val = '>'},
+ {.name = "hashlimit-burst", .has_arg = true, .val = '$'},
+ {.name = "hashlimit-htable-size", .has_arg = true, .val = '&'},
+ {.name = "hashlimit-htable-max", .has_arg = true, .val = '*'},
+ {.name = "hashlimit-htable-gcinterval", .has_arg = true, .val = '('},
+ {.name = "hashlimit-htable-expire", .has_arg = true, .val = ')'},
+ {.name = "hashlimit-mode", .has_arg = true, .val = '_'},
+ {.name = "hashlimit-name", .has_arg = true, .val = '"'},
+ {},
+};
+
static
int parse_rate(const char *rate, u_int32_t *val)
{
@@ -98,15 +135,39 @@ static void hashlimit_init(struct xt_ent
{
struct xt_hashlimit_info *r = (struct xt_hashlimit_info *)m->data;
+ r->cfg.mode = 0;
r->cfg.burst = XT_HASHLIMIT_BURST;
r->cfg.gc_interval = XT_HASHLIMIT_GCINTERVAL;
r->cfg.expire = XT_HASHLIMIT_EXPIRE;
}
+static void hashlimit_mt4_init(struct xt_entry_match *match)
+{
+ struct xt_hashlimit_mtinfo1 *info = (void *)match->data;
+
+ info->cfg.mode = 0;
+ info->cfg.burst = XT_HASHLIMIT_BURST;
+ info->cfg.gc_interval = XT_HASHLIMIT_GCINTERVAL;
+ info->cfg.expire = XT_HASHLIMIT_EXPIRE;
+ info->cfg.srcmask = 32;
+ info->cfg.dstmask = 32;
+}
+
+static void hashlimit_mt6_init(struct xt_entry_match *match)
+{
+ struct xt_hashlimit_mtinfo1 *info = (void *)match->data;
+
+ info->cfg.mode = 0;
+ info->cfg.burst = XT_HASHLIMIT_BURST;
+ info->cfg.gc_interval = XT_HASHLIMIT_GCINTERVAL;
+ info->cfg.expire = XT_HASHLIMIT_EXPIRE;
+ info->cfg.srcmask = 128;
+ info->cfg.dstmask = 128;
+}
/* Parse a 'mode' parameter into the required bitmask */
-static int parse_mode(struct xt_hashlimit_info *r, char *optarg)
+static int parse_mode(uint32_t *mode, const char *optarg)
{
char *tok;
char *arg = strdup(optarg);
@@ -114,19 +175,17 @@ static int parse_mode(struct xt_hashlimi
if (!arg)
return -1;
- r->cfg.mode = 0;
-
for (tok = strtok(arg, ",|");
tok;
tok = strtok(NULL, ",|")) {
if (!strcmp(tok, "dstip"))
- r->cfg.mode |= XT_HASHLIMIT_HASH_DIP;
+ *mode |= XT_HASHLIMIT_HASH_DIP;
else if (!strcmp(tok, "srcip"))
- r->cfg.mode |= XT_HASHLIMIT_HASH_SIP;
+ *mode |= XT_HASHLIMIT_HASH_SIP;
else if (!strcmp(tok, "srcport"))
- r->cfg.mode |= XT_HASHLIMIT_HASH_SPT;
+ *mode |= XT_HASHLIMIT_HASH_SPT;
else if (!strcmp(tok, "dstport"))
- r->cfg.mode |= XT_HASHLIMIT_HASH_DPT;
+ *mode |= XT_HASHLIMIT_HASH_DPT;
else {
free(arg);
return -1;
@@ -136,14 +195,18 @@ static int parse_mode(struct xt_hashlimi
return 0;
}
-#define PARAM_LIMIT 0x00000001
-#define PARAM_BURST 0x00000002
-#define PARAM_MODE 0x00000004
-#define PARAM_NAME 0x00000008
-#define PARAM_SIZE 0x00000010
-#define PARAM_MAX 0x00000020
-#define PARAM_GCINTERVAL 0x00000040
-#define PARAM_EXPIRE 0x00000080
+enum {
+ PARAM_LIMIT = 1 << 0,
+ PARAM_BURST = 1 << 1,
+ PARAM_MODE = 1 << 2,
+ PARAM_NAME = 1 << 3,
+ PARAM_SIZE = 1 << 4,
+ PARAM_MAX = 1 << 5,
+ PARAM_GCINTERVAL = 1 << 6,
+ PARAM_EXPIRE = 1 << 7,
+ PARAM_SRCMASK = 1 << 8,
+ PARAM_DSTMASK = 1 << 9,
+};
/* Function which parses command options; returns true if it
ate an option */
@@ -224,7 +287,7 @@ hashlimit_parse(int c, char **argv, int
param_act(P_ONLY_ONCE, "hashlimit", "--hashlimit-mode",
*flags & PARAM_MODE);
if (check_inverse(argv[optind-1], &invert, &optind, 0)) break;
- if (parse_mode(r, optarg) < 0)
+ if (parse_mode(&r->cfg.mode, optarg) < 0)
exit_error(PARAMETER_PROBLEM,
"bad --hashlimit-mode: `%s'\n", optarg);
*flags |= PARAM_MODE;
@@ -249,6 +312,146 @@ hashlimit_parse(int c, char **argv, int
return 1;
}
+static int
+hashlimit_mt_parse(struct xt_hashlimit_mtinfo1 *info, unsigned int *flags,
+ int c, int invert, unsigned int maxmask)
+{
+ unsigned int num;
+
+ switch(c) {
+ case '%': /* --hashlimit / --hashlimit-below */
+ param_act(P_ONLY_ONCE, "hashlimit", "--hashlimit-upto",
+ *flags & PARAM_LIMIT);
+ if (invert)
+ info->cfg.mode |= XT_HASHLIMIT_INVERT;
+ if (!parse_rate(optarg, &info->cfg.avg))
+ param_act(P_BAD_VALUE, "hashlimit",
+ "--hashlimit-upto", optarg);
+ *flags |= PARAM_LIMIT;
+ return true;
+
+ case '^': /* --hashlimit-above == !--hashlimit-below */
+ param_act(P_ONLY_ONCE, "hashlimit", "--hashlimit-above",
+ *flags & PARAM_LIMIT);
+ if (!invert)
+ info->cfg.mode |= XT_HASHLIMIT_INVERT;
+ if (!parse_rate(optarg, &info->cfg.avg))
+ param_act(P_BAD_VALUE, "hashlimit",
+ "--hashlimit-above", optarg);
+ *flags |= PARAM_LIMIT;
+ return true;
+
+ case '$': /* --hashlimit-burst */
+ param_act(P_ONLY_ONCE, "hashlimit", "--hashlimit-burst",
+ *flags & PARAM_BURST);
+ if (!strtonum(optarg, NULL, &num, 0, 10000))
+ param_act(P_BAD_VALUE, "hashlimit",
+ "--hashlimit-burst", optarg);
+ info->cfg.burst = num;
+ *flags |= PARAM_BURST;
+ return true;
+
+ case '&': /* --hashlimit-htable-size */
+ param_act(P_ONLY_ONCE, "hashlimit", "--hashlimit-htable-size",
+ *flags & PARAM_SIZE);
+ if (!strtonum(optarg, NULL, &num, 0, 0xffffffff))
+ param_act(P_BAD_VALUE, "hashlimit",
+ "--hashlimit-htable-size", optarg);
+ info->cfg.size = num;
+ *flags |= PARAM_SIZE;
+ return true;
+
+ case '*': /* --hashlimit-htable-max */
+ param_act(P_ONLY_ONCE, "hashlimit", "--hashlimit-htable-max",
+ *flags & PARAM_MAX);
+ if (!strtonum(optarg, NULL, &num, 0, 0xffffffff))
+ param_act(P_BAD_VALUE, "hashlimit",
+ "--hashlimit-htable-max", optarg);
+ info->cfg.max = num;
+ *flags |= PARAM_MAX;
+ return true;
+
+ case '(': /* --hashlimit-htable-gcinterval */
+ param_act(P_ONLY_ONCE, "hashlimit",
+ "--hashlimit-htable-gcinterval",
+ *flags & PARAM_GCINTERVAL);
+ if (!strtonum(optarg, NULL, &num, 0, 0xffffffff))
+ param_act(P_BAD_VALUE, "hashlimit",
+ "--hashlimit-htable-gcinterval", optarg);
+ /* FIXME: not HZ dependent!! */
+ info->cfg.gc_interval = num;
+ *flags |= PARAM_GCINTERVAL;
+ return true;
+
+ case ')': /* --hashlimit-htable-expire */
+ param_act(P_ONLY_ONCE, "hashlimit",
+ "--hashlimit-htable-expire", *flags & PARAM_EXPIRE);
+ if (!strtonum(optarg, NULL, &num, 0, 0xffffffff))
+ param_act(P_BAD_VALUE, "hashlimit",
+ "--hashlimit-htable-expire", optarg);
+ /* FIXME: not HZ dependent */
+ info->cfg.expire = num;
+ *flags |= PARAM_EXPIRE;
+ return true;
+
+ case '_':
+ param_act(P_ONLY_ONCE, "hashlimit", "--hashlimit-mode",
+ *flags & PARAM_MODE);
+ if (parse_mode(&info->cfg.mode, optarg) < 0)
+ param_act(P_BAD_VALUE, "hashlimit",
+ "--hashlimit-mode", optarg);
+ *flags |= PARAM_MODE;
+ return true;
+
+ case '"': /* --hashlimit-name */
+ param_act(P_ONLY_ONCE, "hashlimit", "--hashlimit-name",
+ *flags & PARAM_NAME);
+ if (strlen(optarg) == 0)
+ exit_error(PARAMETER_PROBLEM, "Zero-length name?");
+ strncpy(info->name, optarg, sizeof(info->name));
+ info->name[sizeof(info->name)-1] = '\0';
+ *flags |= PARAM_NAME;
+ return true;
+
+ case '<': /* --hashlimit-srcmask */
+ param_act(P_ONLY_ONCE, "hashlimit", "--hashlimit-srcmask",
+ *flags & PARAM_SRCMASK);
+ if (!strtonum(optarg, NULL, &num, 0, maxmask))
+ param_act(P_BAD_VALUE, "hashlimit",
+ "--hashlimit-srcmask", optarg);
+ info->cfg.srcmask = num;
+ *flags |= PARAM_SRCMASK;
+ return true;
+
+ case '>': /* --hashlimit-dstmask */
+ param_act(P_ONLY_ONCE, "hashlimit", "--hashlimit-dstmask",
+ *flags & PARAM_DSTMASK);
+ if (!strtonum(optarg, NULL, &num, 0, maxmask))
+ param_act(P_BAD_VALUE, "hashlimit",
+ "--hashlimit-dstmask", optarg);
+ info->cfg.dstmask = num;
+ *flags |= PARAM_DSTMASK;
+ return true;
+ }
+ return false;
+}
+
+static int
+hashlimit_mt4_parse(int c, char **argv, int invert, unsigned int *flags,
+ const void *entry, struct xt_entry_match **match)
+{
+ return hashlimit_mt_parse((void *)(*match)->data,
+ flags, c, invert, 32);
+}
+
+static int
+hashlimit_mt6_parse(int c, char **argv, int invert, unsigned int *flags,
+ const void *entry, struct xt_entry_match **match)
+{
+ return hashlimit_mt_parse((void *)(*match)->data,
+ flags, c, invert, 128);
+}
+
/* Final check; nothing. */
static void hashlimit_check(unsigned int flags)
{
@@ -263,6 +466,16 @@ static void hashlimit_check(unsigned int
"You have to specify --hashlimit-name");
}
+static void hashlimit_mt_check(unsigned int flags)
+{
+ if (!(flags & PARAM_LIMIT))
+ exit_error(PARAMETER_PROBLEM, "You have to specify "
+ "--hashlimit-upto or --hashlimit-above");
+ if (!(flags & PARAM_NAME))
+ exit_error(PARAMETER_PROBLEM,
+ "You have to specify --hashlimit-name");
+}
+
static const struct rates
{
const char *name;
@@ -285,29 +498,27 @@ static void print_rate(u_int32_t period)
printf("%u/%s ", rates[i-1].mult / period, rates[i-1].name);
}
-static void print_mode(const struct xt_hashlimit_info *r, char separator)
+static void print_mode(unsigned int mode, char separator)
{
- int prevmode = 0;
+ bool prevmode = false;
- if (r->cfg.mode & XT_HASHLIMIT_HASH_SIP) {
- if (prevmode)
- putchar(separator);
+ if (mode & XT_HASHLIMIT_HASH_SIP) {
fputs("srcip", stdout);
prevmode = 1;
}
- if (r->cfg.mode & XT_HASHLIMIT_HASH_SPT) {
+ if (mode & XT_HASHLIMIT_HASH_SPT) {
if (prevmode)
putchar(separator);
fputs("srcport", stdout);
prevmode = 1;
}
- if (r->cfg.mode & XT_HASHLIMIT_HASH_DIP) {
+ if (mode & XT_HASHLIMIT_HASH_DIP) {
if (prevmode)
putchar(separator);
fputs("dstip", stdout);
prevmode = 1;
}
- if (r->cfg.mode & XT_HASHLIMIT_HASH_DPT) {
+ if (mode & XT_HASHLIMIT_HASH_DPT) {
if (prevmode)
putchar(separator);
fputs("dstport", stdout);
@@ -324,7 +535,7 @@ static void hashlimit_print(const void *
fputs("limit: avg ", stdout); print_rate(r->cfg.avg);
printf("burst %u ", r->cfg.burst);
fputs("mode ", stdout);
- print_mode(r, '-');
+ print_mode(r->cfg.mode, '-');
if (r->cfg.size)
printf("htable-size %u ", r->cfg.size);
if (r->cfg.max)
@@ -335,6 +546,53 @@ static void hashlimit_print(const void *
printf("htable-expire %u ", r->cfg.expire);
}
+static void
+hashlimit_mt_print(const struct xt_hashlimit_mtinfo1 *info, unsigned int dmask)
+{
+ if (info->cfg.mode & XT_HASHLIMIT_INVERT)
+ fputs("limit: above ", stdout);
+ else
+ fputs("limit: up to ", stdout);
+ print_rate(info->cfg.avg);
+ printf("burst %u ", info->cfg.burst);
+ if (info->cfg.mode & (XT_HASHLIMIT_HASH_SIP | XT_HASHLIMIT_HASH_SPT |
+ XT_HASHLIMIT_HASH_DIP | XT_HASHLIMIT_HASH_DPT)) {
+ fputs("mode ", stdout);
+ print_mode(info->cfg.mode, '-');
+ }
+ if (info->cfg.size != 0)
+ printf("htable-size %u ", info->cfg.size);
+ if (info->cfg.max != 0)
+ printf("htable-max %u ", info->cfg.max);
+ if (info->cfg.gc_interval != XT_HASHLIMIT_GCINTERVAL)
+ printf("htable-gcinterval %u ", info->cfg.gc_interval);
+ if (info->cfg.expire != XT_HASHLIMIT_EXPIRE)
+ printf("htable-expire %u ", info->cfg.expire);
+
+ if (info->cfg.srcmask != dmask)
+ printf("srcmask %u ", info->cfg.srcmask);
+ if (info->cfg.dstmask != dmask)
+ printf("dstmask %u ", info->cfg.dstmask);
+}
+
+static void
+hashlimit_mt4_print(const void *ip, const struct xt_entry_match *match,
+ int numeric)
+{
+ const struct xt_hashlimit_mtinfo1 *info = (const void *)match->data;
+
+ hashlimit_mt_print(info, 32);
+}
+
+static void
+hashlimit_mt6_print(const void *ip, const struct xt_entry_match *match,
+ int numeric)
+{
+ const struct xt_hashlimit_mtinfo1 *info = (const void *)match->data;
+
+ hashlimit_mt_print(info, 128);
+}
+
/* FIXME: Make minimalist: only print rate if not default --RR */
static void hashlimit_save(const void *ip, const struct xt_entry_match *match)
{
@@ -346,7 +604,7 @@ static void hashlimit_save(const void *i
printf("--hashlimit-burst %u ", r->cfg.burst);
fputs("--hashlimit-mode ", stdout);
- print_mode(r, ',');
+ print_mode(r->cfg.mode, ',');
printf("--hashlimit-name %s ", r->name);
@@ -360,10 +618,61 @@ static void hashlimit_save(const void *i
printf("--hashlimit-htable-expire %u ", r->cfg.expire);
}
+static void
+hashlimit_mt_save(const struct xt_hashlimit_mtinfo1 *info, unsigned int dmask)
+{
+ if (info->cfg.mode & XT_HASHLIMIT_INVERT)
+ fputs("--hashlimit-above ", stdout);
+ else
+ fputs("--hashlimit-upto ", stdout);
+ print_rate(info->cfg.avg);
+ if (info->cfg.burst != XT_HASHLIMIT_BURST)
+ printf("--hashlimit-burst %u ", info->cfg.burst);
+
+ if (info->cfg.mode & (XT_HASHLIMIT_HASH_SIP | XT_HASHLIMIT_HASH_SPT |
+ XT_HASHLIMIT_HASH_DIP | XT_HASHLIMIT_HASH_DPT)) {
+ fputs("--hashlimit-mode ", stdout);
+ print_mode(info->cfg.mode, ',');
+ }
+
+ printf("--hashlimit-name %s ", info->name);
+
+ if (info->cfg.size != 0)
+ printf("--hashlimit-htable-size %u ", info->cfg.size);
+ if (info->cfg.max != 0)
+ printf("--hashlimit-htable-max %u ", info->cfg.max);
+ if (info->cfg.gc_interval != XT_HASHLIMIT_GCINTERVAL)
+ printf("--hashlimit-htable-gcinterval %u", info->cfg.gc_interval);
+ if (info->cfg.expire != XT_HASHLIMIT_EXPIRE)
+ printf("--hashlimit-htable-expire %u ", info->cfg.expire);
+
+ if (info->cfg.srcmask != dmask)
+ printf("--hashlimit-srcmask %u ", info->cfg.srcmask);
+ if (info->cfg.dstmask != dmask)
+ printf("--hashlimit-dstmask %u ", info->cfg.dstmask);
+}
+
+static void
+hashlimit_mt4_save(const void *ip, const struct xt_entry_match *match)
+{
+ const struct xt_hashlimit_mtinfo1 *info = (const void *)match->data;
+
+ hashlimit_mt_save(info, 32);
+}
+
+static void
+hashlimit_mt6_save(const void *ip, const struct xt_entry_match *match)
+{
+ const struct xt_hashlimit_mtinfo1 *info = (const void *)match->data;
+
+ hashlimit_mt_save(info, 128);
+}
+
static struct xtables_match hashlimit_match = {
.family = AF_INET,
.name = "hashlimit",
.version = IPTABLES_VERSION,
+ .revision = 0,
.size = XT_ALIGN(sizeof(struct xt_hashlimit_info)),
.userspacesize = offsetof(struct xt_hashlimit_info, hinfo),
.help = hashlimit_help,
@@ -379,6 +688,7 @@ static struct xtables_match hashlimit_ma
.family = AF_INET6,
.name = "hashlimit",
.version = IPTABLES_VERSION,
+ .revision = 0,
.size = XT_ALIGN(sizeof(struct xt_hashlimit_info)),
.userspacesize = offsetof(struct xt_hashlimit_info, hinfo),
.help = hashlimit_help,
@@ -390,8 +700,42 @@ static struct xtables_match hashlimit_ma
.extra_opts = hashlimit_opts,
};
+static struct xtables_match hashlimit_mt_reg = {
+ .version = IPTABLES_VERSION,
+ .name = "hashlimit",
+ .revision = 1,
+ .family = AF_INET,
+ .size = XT_ALIGN(sizeof(struct xt_hashlimit_mtinfo1)),
+ .userspacesize = offsetof(struct xt_hashlimit_mtinfo1, hinfo),
+ .help = hashlimit_mt_help,
+ .init = hashlimit_mt4_init,
+ .parse = hashlimit_mt4_parse,
+ .final_check = hashlimit_mt_check,
+ .print = hashlimit_mt4_print,
+ .save = hashlimit_mt4_save,
+ .extra_opts = hashlimit_mt_opts,
+};
+
+static struct xtables_match hashlimit_mt6_reg = {
+ .version = IPTABLES_VERSION,
+ .name = "hashlimit",
+ .revision = 1,
+ .family = AF_INET6,
+ .size = XT_ALIGN(sizeof(struct xt_hashlimit_mtinfo1)),
+ .userspacesize = offsetof(struct xt_hashlimit_mtinfo1, hinfo),
+ .help = hashlimit_mt_help,
+ .init = hashlimit_mt6_init,
+ .parse = hashlimit_mt6_parse,
+ .final_check = hashlimit_mt_check,
+ .print = hashlimit_mt6_print,
+ .save = hashlimit_mt6_save,
+ .extra_opts = hashlimit_mt_opts,
+};
+
void _init(void)
{
xtables_register_match(&hashlimit_match);
xtables_register_match(&hashlimit_match6);
+ xtables_register_match(&hashlimit_mt_reg);
+ xtables_register_match(&hashlimit_mt6_reg);
}
Index: iptables/extensions/libxt_hashlimit.man
===================================================================
--- iptables.orig/extensions/libxt_hashlimit.man
+++ iptables/extensions/libxt_hashlimit.man
@@ -1,35 +1,59 @@
-This patch adds a new match called 'hashlimit'.
-The idea is to have something like 'limit', but either per
-destination-ip or per (destip,destport) tuple.
-
-It gives you the ability to express
-.IP
- '1000 packets per second for every host in 192.168.0.0/16'
-.IP
- '100 packets per second for every service of 192.168.1.1'
-.P
-with a single iptables rule.
-.TP
-.BI "--hashlimit " "rate"
-A rate just like the limit match
-.TP
-.BI "--hashlimit-burst " "num"
-Burst value, just like limit match
+\fBhashlimit\fR uses hash buckets to express a rate limiting match (like the
+\fBlimit\fR match) for a group of connections using a \fBsingle\fR iptables
+rule. Grouping can be done per-hostgroup (source and/or destination address)
+and/or per-port. It gives you the ability to express "\fIN\fR packets per time
+quantum per group":
+.TP
+matching on source host
+"1000 packets per second for every host in 192.168.0.0/16"
+.TP
+matching on source prot
+"100 packets per second for every service of 192.168.1.1"
+.TP
+matching on subnet
+"10000 packets per minute for every /28 subnet in 10.0.0.0/8"
+.PP
+A hash limit option (\fB--hashlimit-upto\fR, \fB--hashlimit-above\fR) and
+\fB--hashlimit-name\fR are required.
+.TP
+\fB--hashlimit-upto\fR \fIamount\fR[\fB/second\fR|\fB/minute\fR|\fB/hour\fR|\fB/day\fR]
+Match if the rate is below or equal to \fIamount\fR/quantum. It is specified as
+a number, with an optional time quantum suffix; the default is 3/hour.
+.TP
+\fB--hashlimit-above\fR \fIamount\fR[\fB/second\fR|\fB/minute\fR|\fB/hour\fR|\fB/day\fR]
+Match if the rate is above \fIamount\fR/quantum.
+.TP
+\fB--hashlimit-burst\fR \fIamount\fR
+Maximum initial number of packets to match: this number gets recharged by one
+every time the limit specified above is not reached, up to this number; the
+default is 5.
+.TP
+\fB--hashlimit-mode\fR [\fBsrcip\fR|\fBsrcport\fR|\fBdstip\fR|\fBdstport\fR[\fB,\fR...]]
+A comma-separated list of objects to take into consideration. If no
+--hashlimit-mode option is given, hashlimit acts like limit, but at the
+expensive of doing the hash housekeeping.
+.TP
+\fB--hashlimit-srcmask\fR \fIprefix\fR
+When --hashlimit-mode srcip is used, all source addresses encountered will be
+grouped according to the given prefix length and the so-created subnet will be
+subject to hashlimit. \fIprefix\fR must be between (inclusive) 0 and 32. Note
+that --hashlimit-srcmask 0 is basically doing the same thing as not specifying
+srcip for --hashlimit-mode, but is technically more expensive.
.TP
-.BI "--hashlimit-mode " "dstip,srcip,dstport,srcport"
-A comma-separated list of objects to take into consideration
+\fB--hashlimit-dstmask\fR \fIprefix\fR
+Like --hashlimit-srcmask, but for destination addresses.
.TP
-.BI "--hashlimit-name " "foo"
-The name for the /proc/net/ipt_hashlimit/foo entry
+\fB--hashlimit-name\fR \fIfoo\fR
+The name for the /proc/net/ipt_hashlimit/foo entry.
.TP
-.BI "--hashlimit-htable-size " "num"
+\fB--hashlimit-htable-size\fR \fIbuckets\fR
The number of buckets of the hash table
.TP
-.BI "--hashlimit-htable-max " "num"
-Maximum entries in the hash
+\fB--hashlimit-htable-max\fR \fIentries\fR
+Maximum entries in the hash.
.TP
-.BI "--hashlimit-htable-expire " "num"
-After how many miliseconds do hash entries expire
+\fB--hashlimit-htable-expire\fR \fImsec\fR
+After how many miliseconds do hash entries expire.
.TP
-.BI "--hashlimit-htable-gcinterval " "num"
-How many miliseconds between garbage collection intervals
+\fB--hashlimit-htable-gcinterval\fR \fImsec\fR
+How many miliseconds between garbage collection intervals.
Index: iptables/include/linux/netfilter/xt_hashlimit.h
===================================================================
--- iptables.orig/include/linux/netfilter/xt_hashlimit.h
+++ iptables/include/linux/netfilter/xt_hashlimit.h
@@ -9,13 +9,16 @@
/* details of this structure hidden by the implementation */
struct xt_hashlimit_htable;
-#define XT_HASHLIMIT_HASH_DIP 0x0001
-#define XT_HASHLIMIT_HASH_DPT 0x0002
-#define XT_HASHLIMIT_HASH_SIP 0x0004
-#define XT_HASHLIMIT_HASH_SPT 0x0008
+enum {
+ XT_HASHLIMIT_HASH_DIP = 1 << 0,
+ XT_HASHLIMIT_HASH_DPT = 1 << 1,
+ XT_HASHLIMIT_HASH_SIP = 1 << 2,
+ XT_HASHLIMIT_HASH_SPT = 1 << 3,
+ XT_HASHLIMIT_INVERT = 1 << 4,
+};
struct hashlimit_cfg {
- u_int32_t mode; /* bitmask of IPT_HASHLIMIT_HASH_* */
+ u_int32_t mode; /* bitmask of XT_HASHLIMIT_HASH_* */
u_int32_t avg; /* Average secs between packets * scale */
u_int32_t burst; /* Period multiplier for upper limit. */
@@ -29,12 +32,36 @@ struct hashlimit_cfg {
struct xt_hashlimit_info {
char name [IFNAMSIZ]; /* name */
struct hashlimit_cfg cfg;
- struct xt_hashlimit_htable *hinfo;
/* Used internally by the kernel */
+ struct xt_hashlimit_htable *hinfo;
union {
void *ptr;
struct xt_hashlimit_info *master;
} u;
};
+
+struct hashlimit_cfg1 {
+ u_int32_t mode; /* bitmask of XT_HASHLIMIT_HASH_* */
+ u_int32_t avg; /* Average secs between packets * scale */
+ u_int32_t burst; /* Period multiplier for upper limit. */
+
+ /* user specified */
+ u_int32_t size; /* how many buckets */
+ u_int32_t max; /* max number of entries */
+ u_int32_t gc_interval; /* gc interval */
+ u_int32_t expire; /* when do entries expire? */
+
+ u_int8_t srcmask, dstmask;
+};
+
+struct xt_hashlimit_mtinfo1 {
+ char name[IFNAMSIZ];
+ struct hashlimit_cfg1 cfg;
+
+ /* Used internally by the kernel */
+ struct xt_hashlimit_htable *hinfo __attribute__((aligned(8)));
+ struct xt_hashlimit_mtinfo1 *master __attribute__((aligned(8)));
+};
+
#endif /*_XT_HASHLIMIT_H*/
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/5][IPTABLES]: Import netfilter.h
2008-01-24 19:01 [PATCH 1/5][IPTABLES]: Import netfilter.h Jan Engelhardt
` (3 preceding siblings ...)
2008-01-24 19:02 ` [PATCH 5/5][IPTABLES]: libxt_hashlimit " Jan Engelhardt
@ 2008-01-29 13:10 ` Patrick McHardy
2008-01-29 14:31 ` Jan Engelhardt
4 siblings, 1 reply; 11+ messages in thread
From: Patrick McHardy @ 2008-01-29 13:10 UTC (permalink / raw)
To: Jan Engelhardt; +Cc: Netfilter Developer Mailing List
Jan Engelhardt wrote:
> Import netfilter.h from kernel to get hold of union nf_inet_addr
> and fix a compile error in current iptable tarball releases when
> used with non-development kernels.
We already have this exact file in the current sources, without
the #ifdef __KERNEL__ parts.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 2/5][IPTABLES]: Give preference to iptables header files
2008-01-24 19:01 ` [PATCH 2/5][IPTABLES]: Give preference to iptables header files Jan Engelhardt
@ 2008-01-29 13:15 ` Patrick McHardy
0 siblings, 0 replies; 11+ messages in thread
From: Patrick McHardy @ 2008-01-29 13:15 UTC (permalink / raw)
To: Jan Engelhardt; +Cc: Netfilter Developer Mailing List
Jan Engelhardt wrote:
> Have the header files in the iptables source tree take precedence
> over those from the kernel source. Otherwise, building the current
> iptables from subversion just fails with kernels < 2.6.25.
Applied, thanks.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 3/5][IPTABLES]: Build adjustments
2008-01-24 19:02 ` [PATCH 3/5][IPTABLES]: Build adjustments Jan Engelhardt
@ 2008-01-29 13:16 ` Patrick McHardy
0 siblings, 0 replies; 11+ messages in thread
From: Patrick McHardy @ 2008-01-29 13:16 UTC (permalink / raw)
To: Jan Engelhardt; +Cc: Netfilter Developer Mailing List
Jan Engelhardt wrote:
> A few build system changes.
> * ip6tables needs IP6T_LIB_DIR
> * correctly trigger rebuild of master manpages when
> submanpages have been touched
Applied.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 4/5][IPTABLES]: libxt_CONNMARK revision 1
2008-01-24 19:02 ` [PATCH 4/5][IPTABLES]: libxt_CONNMARK revision 1 Jan Engelhardt
@ 2008-01-29 13:19 ` Patrick McHardy
0 siblings, 0 replies; 11+ messages in thread
From: Patrick McHardy @ 2008-01-29 13:19 UTC (permalink / raw)
To: Jan Engelhardt; +Cc: Netfilter Developer Mailing List
Jan Engelhardt wrote:
> +static void connmark_tg_help(void)
> +{
> + printf(
> +"CONNMARK target options:\n"
> +" XOR-based operations:\n"
> +" --set-xmark value[/ctmask] Zero mask bits and XOR ctmark with value\n"
> +" --save-mark [--ctmask mask] [--nfmask mask]\n"
> +" Copy ctmark to nfmark using masks\n"
> +" --restore-mark [--ctmask mask] [--nfmask mask]\n"
> +" Copy nfmark to ctmark using masks\n"
> +" OR-based operations:\n"
> +" --set-mark value[/mask] Set conntrack mark value\n"
> +" --save-mark [--mask mask] Save the packet nfmark in the connection\n"
> +" --restore-mark [--mask mask] Restore saved nfmark value\n"
> +" Other operations:\n"
> +" --and-mark value Binary AND the ctmark with bits\n"
> +" --or-mark value Binary OR the ctmark with bits\n"
> +" --xor-mark value Binary XOR the ctmark with bits\n"
I don't think users need to care how the operations are implemented,
so I removed the "XOR-based/OR-based/Other" lines.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/5][IPTABLES]: Import netfilter.h
2008-01-29 13:10 ` [PATCH 1/5][IPTABLES]: Import netfilter.h Patrick McHardy
@ 2008-01-29 14:31 ` Jan Engelhardt
2008-01-29 14:34 ` Patrick McHardy
0 siblings, 1 reply; 11+ messages in thread
From: Jan Engelhardt @ 2008-01-29 14:31 UTC (permalink / raw)
To: Patrick McHardy; +Cc: Netfilter Developer Mailing List
On Jan 29 2008 14:10, Patrick McHardy wrote:
>Subject: Re: [PATCH 1/5][IPTABLES]: Import netfilter.h
>
> Jan Engelhardt wrote:
>> Import netfilter.h from kernel to get hold of union nf_inet_addr
>> and fix a compile error in current iptable tarball releases when
>> used with non-development kernels.
>
> We already have this exact file in the current sources, without
> the #ifdef __KERNEL__ parts.
>
Where? If you mean the sanitized headers in
/usr/include/linux/netfilter.h -- this file is outdated and does not
ship the nf_inet_addr definition.
Since we copy all xt_{match,target}*.h header files too, I thought doing
the same for netfilter.h is ok.
I do believe it is, because the sanitized headers in
/usr/include/linux/netfilter/ are _also_ out-of-date.
BTW, could we, perhaps, remove headers-y for
/usr/include/linux/netfilter/, since iptables ships it anyway?
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 1/5][IPTABLES]: Import netfilter.h
2008-01-29 14:31 ` Jan Engelhardt
@ 2008-01-29 14:34 ` Patrick McHardy
0 siblings, 0 replies; 11+ messages in thread
From: Patrick McHardy @ 2008-01-29 14:34 UTC (permalink / raw)
To: Jan Engelhardt; +Cc: Netfilter Developer Mailing List
Jan Engelhardt wrote:
> On Jan 29 2008 14:10, Patrick McHardy wrote:
>> Subject: Re: [PATCH 1/5][IPTABLES]: Import netfilter.h
>>
>> Jan Engelhardt wrote:
>>> Import netfilter.h from kernel to get hold of union nf_inet_addr
>>> and fix a compile error in current iptable tarball releases when
>>> used with non-development kernels.
>> We already have this exact file in the current sources, without
>> the #ifdef __KERNEL__ parts.
>>
>
> Where? If you mean the sanitized headers in
> /usr/include/linux/netfilter.h -- this file is outdated and does not
> ship the nf_inet_addr definition.
You're right, I only added it locally, but forgot "svn add" :)
Committed now.
> Since we copy all xt_{match,target}*.h header files too, I thought doing
> the same for netfilter.h is ok.
>
> I do believe it is, because the sanitized headers in
> /usr/include/linux/netfilter/ are _also_ out-of-date.
> BTW, could we, perhaps, remove headers-y for
> /usr/include/linux/netfilter/, since iptables ships it anyway?
No, there are other users of these files. I recall there is
some perl interface for iptables for example.
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2008-01-29 14:34 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-01-24 19:01 [PATCH 1/5][IPTABLES]: Import netfilter.h Jan Engelhardt
2008-01-24 19:01 ` [PATCH 2/5][IPTABLES]: Give preference to iptables header files Jan Engelhardt
2008-01-29 13:15 ` Patrick McHardy
2008-01-24 19:02 ` [PATCH 3/5][IPTABLES]: Build adjustments Jan Engelhardt
2008-01-29 13:16 ` Patrick McHardy
2008-01-24 19:02 ` [PATCH 4/5][IPTABLES]: libxt_CONNMARK revision 1 Jan Engelhardt
2008-01-29 13:19 ` Patrick McHardy
2008-01-24 19:02 ` [PATCH 5/5][IPTABLES]: libxt_hashlimit " Jan Engelhardt
2008-01-29 13:10 ` [PATCH 1/5][IPTABLES]: Import netfilter.h Patrick McHardy
2008-01-29 14:31 ` Jan Engelhardt
2008-01-29 14:34 ` Patrick McHardy
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.