* [NETFILTER]: xt_conntrack: add port and direction matching
@ 2008-01-24 22:38 Jan Engelhardt
2008-01-24 22:38 ` [IPTABLES]: libxt_conntrack revision 1 Jan Engelhardt
2008-01-29 13:08 ` [NETFILTER]: xt_conntrack: add port and direction matching Patrick McHardy
0 siblings, 2 replies; 17+ messages in thread
From: Jan Engelhardt @ 2008-01-24 22:38 UTC (permalink / raw)
To: kaber; +Cc: Netfilter Developer Mailing List
commit 7f1764fa749032eb8566226bbd1c5a58a8a5efc6
Author: Jan Engelhardt <jengelh@computergmbh.de>
Date: Wed Jan 16 18:58:49 2008 +0100
[NETFILTER]: xt_conntrack: add port and direction matching
Extend the xt_conntrack match revision 1 by port matching (all four
{orig,repl}{src,dst}) and by packet direction matching.
Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de>
diff --git a/include/linux/netfilter/xt_conntrack.h b/include/linux/netfilter/xt_conntrack.h
index d2492a3..f3fd83e 100644
--- a/include/linux/netfilter/xt_conntrack.h
+++ b/include/linux/netfilter/xt_conntrack.h
@@ -6,9 +6,6 @@
#define _XT_CONNTRACK_H
#include <linux/netfilter/nf_conntrack_tuple_common.h>
-#ifdef __KERNEL__
-# include <linux/in.h>
-#endif
#define XT_CONNTRACK_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1))
#define XT_CONNTRACK_STATE_INVALID (1 << 0)
@@ -18,14 +15,21 @@
#define XT_CONNTRACK_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 3))
/* flags, invflags: */
-#define XT_CONNTRACK_STATE 0x01
-#define XT_CONNTRACK_PROTO 0x02
-#define XT_CONNTRACK_ORIGSRC 0x04
-#define XT_CONNTRACK_ORIGDST 0x08
-#define XT_CONNTRACK_REPLSRC 0x10
-#define XT_CONNTRACK_REPLDST 0x20
-#define XT_CONNTRACK_STATUS 0x40
-#define XT_CONNTRACK_EXPIRES 0x80
+enum {
+ XT_CONNTRACK_STATE = 1 << 0,
+ XT_CONNTRACK_PROTO = 1 << 1,
+ XT_CONNTRACK_ORIGSRC = 1 << 2,
+ XT_CONNTRACK_ORIGDST = 1 << 3,
+ XT_CONNTRACK_REPLSRC = 1 << 4,
+ XT_CONNTRACK_REPLDST = 1 << 5,
+ XT_CONNTRACK_STATUS = 1 << 6,
+ XT_CONNTRACK_EXPIRES = 1 << 7,
+ XT_CONNTRACK_ORIGSRC_PORT = 1 << 8,
+ XT_CONNTRACK_ORIGDST_PORT = 1 << 9,
+ XT_CONNTRACK_REPLSRC_PORT = 1 << 10,
+ XT_CONNTRACK_REPLDST_PORT = 1 << 11,
+ XT_CONNTRACK_DIRECTION = 1 << 12,
+};
/* This is exposed to userspace, so remains frozen in time. */
struct ip_conntrack_old_tuple
@@ -70,8 +74,10 @@ struct xt_conntrack_mtinfo1 {
union nf_inet_addr repldst_addr, repldst_mask;
u_int32_t expires_min, expires_max;
u_int16_t l4proto;
+ __be16 origsrc_port, origdst_port;
+ __be16 replsrc_port, repldst_port;
+ u_int16_t match_flags, invert_flags;
u_int8_t state_mask, status_mask;
- u_int8_t match_flags, invert_flags;
};
#endif /*_XT_CONNTRACK_H*/
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c
index e92190e..8533085 100644
--- a/net/netfilter/xt_conntrack.c
+++ b/net/netfilter/xt_conntrack.c
@@ -4,7 +4,6 @@
*
* (C) 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
@@ -20,6 +19,7 @@
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
+MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
MODULE_DESCRIPTION("Xtables: connection tracking state match");
MODULE_ALIAS("ipt_conntrack");
MODULE_ALIAS("ip6t_conntrack");
@@ -166,6 +166,44 @@ conntrack_mt_repldst(const struct nf_conn *ct,
&info->repldst_addr, &info->repldst_mask, family);
}
+static inline bool
+ct_proto_port_check(const struct xt_conntrack_mtinfo1 *info,
+ const struct nf_conn *ct)
+{
+ const struct nf_conntrack_tuple *tuple;
+
+ tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
+ if ((info->match_flags & XT_CONNTRACK_PROTO) &&
+ (tuple->dst.protonum == info->l4proto) ^
+ !(info->invert_flags & XT_CONNTRACK_PROTO))
+ return false;
+
+ /* Shortcut to match all recognized protocols by using ->src.all. */
+ if ((info->match_flags & XT_CONNTRACK_ORIGSRC_PORT) &&
+ (tuple->src.u.all == info->origsrc_port) ^
+ !(info->invert_flags & XT_CONNTRACK_ORIGSRC_PORT))
+ return false;
+
+ if ((info->match_flags & XT_CONNTRACK_ORIGDST_PORT) &&
+ (tuple->dst.u.all == info->origdst_port) ^
+ !(info->invert_flags & XT_CONNTRACK_ORIGDST_PORT))
+ return false;
+
+ tuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;
+
+ if ((info->match_flags & XT_CONNTRACK_REPLSRC_PORT) &&
+ (tuple->src.u.all == info->replsrc_port) ^
+ !(info->invert_flags & XT_CONNTRACK_REPLSRC_PORT))
+ return false;
+
+ if ((info->match_flags & XT_CONNTRACK_REPLDST_PORT) &&
+ (tuple->dst.u.all == info->repldst_port) ^
+ !(info->invert_flags & XT_CONNTRACK_REPLDST_PORT))
+ return false;
+
+ return true;
+}
+
static bool
conntrack_mt(const struct sk_buff *skb, const struct net_device *in,
const struct net_device *out, const struct xt_match *match,
@@ -200,10 +238,9 @@ conntrack_mt(const struct sk_buff *skb, const struct net_device *in,
if (ct == NULL)
return info->match_flags & XT_CONNTRACK_STATE;
-
- if ((info->match_flags & XT_CONNTRACK_PROTO) &&
- ((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum ==
- info->l4proto) ^ !(info->invert_flags & XT_CONNTRACK_PROTO)))
+ if ((info->match_flags & XT_CONNTRACK_DIRECTION) &&
+ (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) ^
+ !!(info->invert_flags & XT_CONNTRACK_DIRECTION))
return false;
if (info->match_flags & XT_CONNTRACK_ORIGSRC)
@@ -226,6 +263,9 @@ conntrack_mt(const struct sk_buff *skb, const struct net_device *in,
!(info->invert_flags & XT_CONNTRACK_REPLDST))
return false;
+ if (!ct_proto_port_check(info, ct))
+ return false;
+
if ((info->match_flags & XT_CONNTRACK_STATUS) &&
(!!(info->status_mask & ct->status) ^
!(info->invert_flags & XT_CONNTRACK_STATUS)))
-
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 17+ messages in thread* [IPTABLES]: libxt_conntrack revision 1 2008-01-24 22:38 [NETFILTER]: xt_conntrack: add port and direction matching Jan Engelhardt @ 2008-01-24 22:38 ` Jan Engelhardt 2008-01-29 13:20 ` Patrick McHardy 2008-01-29 13:08 ` [NETFILTER]: xt_conntrack: add port and direction matching Patrick McHardy 1 sibling, 1 reply; 17+ messages in thread From: Jan Engelhardt @ 2008-01-24 22:38 UTC (permalink / raw) To: kaber; +Cc: Netfilter Developer Mailing List Add support for xt_conntrack match revision 1. Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de> --- extensions/libxt_conntrack.c | 575 ++++++++++++++++++++++++++++++++++++++++- extensions/libxt_conntrack.man | 18 - 2 files changed, 576 insertions(+), 17 deletions(-) Index: iptables/extensions/libxt_conntrack.c =================================================================== --- iptables.orig/extensions/libxt_conntrack.c +++ iptables/extensions/libxt_conntrack.c @@ -1,10 +1,17 @@ -/* Shared library add-on to iptables for conntrack matching support. - * GPL (C) 2001 Marc Boucher (marc@mbsi.ca). +/* + * libxt_conntrack + * Shared library add-on to iptables for conntrack matching support. + * + * GPL (C) 2001 Marc Boucher (marc@mbsi.ca). + * Copyright © CC Computer Consultants GmbH, 2007 - 2008 + * Jan Engelhardt <jengelh@computergmbh.de> */ - +#include <sys/socket.h> +#include <sys/types.h> #include <ctype.h> #include <getopt.h> #include <netdb.h> +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -13,6 +20,7 @@ #include <linux/netfilter.h> #include <linux/netfilter/xt_conntrack.h> #include <linux/netfilter/nf_conntrack_common.h> +#include <arpa/inet.h> /* Function which prints out usage message. */ static void conntrack_mt_help(void) @@ -27,14 +35,20 @@ static void conntrack_mt_help(void) "[!] --ctreplsrc address[/mask]\n" "[!] --ctrepldst address[/mask]\n" " Original/Reply source/destination address\n" +"[!] --ctorigsrcport port\n" +"[!] --ctorigdstport port\n" +"[!] --ctreplsrcport port\n" +"[!] --ctrepldstport port\n" +" TCP/UDP/SCTP orig./reply source/destination port\n" "[!] --ctstatus {NONE|EXPECTED|SEEN_REPLY|ASSURED|CONFIRMED}[,...]\n" " Status(es) to match\n" "[!] --ctexpire time[:time] Match remaining lifetime in seconds against\n" " value or range of values (inclusive)\n" +" --ctdir {ORIGINAL|REPLY} Flow direction of packet\n" "\n"); } -static const struct option conntrack_mt_opts[] = { +static const struct option conntrack_mt_opts_v0[] = { {.name = "ctstate", .has_arg = true, .val = '1'}, {.name = "ctproto", .has_arg = true, .val = '2'}, {.name = "ctorigsrc", .has_arg = true, .val = '3'}, @@ -46,6 +60,23 @@ static const struct option conntrack_mt_ {}, }; +static const struct option conntrack_mt_opts[] = { + {.name = "ctstate", .has_arg = true, .val = '1'}, + {.name = "ctproto", .has_arg = true, .val = '2'}, + {.name = "ctorigsrc", .has_arg = true, .val = '3'}, + {.name = "ctorigdst", .has_arg = true, .val = '4'}, + {.name = "ctreplsrc", .has_arg = true, .val = '5'}, + {.name = "ctrepldst", .has_arg = true, .val = '6'}, + {.name = "ctstatus", .has_arg = true, .val = '7'}, + {.name = "ctexpire", .has_arg = true, .val = '8'}, + {.name = "ctorigsrcport", .has_arg = true, .val = 'a'}, + {.name = "ctorigdstport", .has_arg = true, .val = 'b'}, + {.name = "ctreplsrcport", .has_arg = true, .val = 'c'}, + {.name = "ctrepldstport", .has_arg = true, .val = 'd'}, + {.name = "ctdir", .has_arg = true, .val = 'e'}, + {}, +}; + static int parse_state(const char *state, size_t strlen, struct xt_conntrack_info *sinfo) { @@ -83,6 +114,45 @@ parse_states(const char *arg, struct xt_ exit_error(PARAMETER_PROBLEM, "Bad ctstate `%s'", arg); } +static bool +conntrack_ps_state(struct xt_conntrack_mtinfo1 *info, const char *state, + size_t z) +{ + if (strncasecmp(state, "INVALID", z) == 0) + info->state_mask |= XT_CONNTRACK_STATE_INVALID; + else if (strncasecmp(state, "NEW", z) == 0) + info->state_mask |= XT_CONNTRACK_STATE_BIT(IP_CT_NEW); + else if (strncasecmp(state, "ESTABLISHED", z) == 0) + info->state_mask |= XT_CONNTRACK_STATE_BIT(IP_CT_ESTABLISHED); + else if (strncasecmp(state, "RELATED", z) == 0) + info->state_mask |= XT_CONNTRACK_STATE_BIT(IP_CT_RELATED); + else if (strncasecmp(state, "UNTRACKED", z) == 0) + info->state_mask |= XT_CONNTRACK_STATE_UNTRACKED; + else if (strncasecmp(state, "SNAT", z) == 0) + info->state_mask |= XT_CONNTRACK_STATE_SNAT; + else if (strncasecmp(state, "DNAT", z) == 0) + info->state_mask |= XT_CONNTRACK_STATE_DNAT; + else + return false; + return true; +} + +static void +conntrack_ps_states(struct xt_conntrack_mtinfo1 *info, const char *arg) +{ + const char *comma; + + while ((comma = strchr(arg, ',')) != NULL) { + if (comma == arg || !conntrack_ps_state(info, arg, comma - arg)) + exit_error(PARAMETER_PROBLEM, + "Bad ctstate \"%s\"", arg); + arg = comma + 1; + } + + if (strlen(arg) == 0 || !conntrack_ps_state(info, arg, strlen(arg))) + exit_error(PARAMETER_PROBLEM, "Bad ctstate \"%s\"", arg); +} + static int parse_status(const char *status, size_t strlen, struct xt_conntrack_info *sinfo) { @@ -96,7 +166,7 @@ parse_status(const char *status, size_t sinfo->statusmask |= IPS_ASSURED; #ifdef IPS_CONFIRMED else if (strncasecmp(status, "CONFIRMED", strlen) == 0) - sinfo->stausmask |= IPS_CONFIRMED; + sinfo->statusmask |= IPS_CONFIRMED; #endif else return 0; @@ -118,6 +188,41 @@ parse_statuses(const char *arg, struct x exit_error(PARAMETER_PROBLEM, "Bad ctstatus `%s'", arg); } +static bool +conntrack_ps_status(struct xt_conntrack_mtinfo1 *info, const char *status, + size_t z) +{ + if (strncasecmp(status, "NONE", z) == 0) + info->status_mask |= 0; + else if (strncasecmp(status, "EXPECTED", z) == 0) + info->status_mask |= IPS_EXPECTED; + else if (strncasecmp(status, "SEEN_REPLY", z) == 0) + info->status_mask |= IPS_SEEN_REPLY; + else if (strncasecmp(status, "ASSURED", z) == 0) + info->status_mask |= IPS_ASSURED; + else if (strncasecmp(status, "CONFIRMED", z) == 0) + info->status_mask |= IPS_CONFIRMED; + else + return false; + return true; +} + +static void +conntrack_ps_statuses(struct xt_conntrack_mtinfo1 *info, const char *arg) +{ + const char *comma; + + while ((comma = strchr(arg, ',')) != NULL) { + if (comma == arg || !conntrack_ps_status(info, arg, comma - arg)) + exit_error(PARAMETER_PROBLEM, + "Bad ctstatus \"%s\"", arg); + arg = comma + 1; + } + + if (strlen(arg) == 0 || !conntrack_ps_status(info, arg, strlen(arg))) + exit_error(PARAMETER_PROBLEM, "Bad ctstatus \"%s\"", arg); +} + static unsigned long parse_expire(const char *s) { @@ -138,7 +243,8 @@ parse_expires(const char *s, struct xt_c buffer = strdup(s); if ((cp = strchr(buffer, ':')) == NULL) - sinfo->expires_min = sinfo->expires_max = parse_expire(buffer); + sinfo->expires_min = sinfo->expires_max = + parse_expire(buffer); else { *cp = '\0'; cp++; @@ -154,6 +260,30 @@ parse_expires(const char *s, struct xt_c "range value `%lu'", sinfo->expires_min, sinfo->expires_max); } +static void +conntrack_ps_expires(struct xt_conntrack_mtinfo1 *info, const char *s) +{ + unsigned int min, max; + char *end; + + if (!strtonum(s, &end, &min, 0, ~0)) + param_act(P_BAD_VALUE, "conntrack", "--expires", s); + max = min; + if (*end == ':') + if (!strtonum(s, &end, &max, 0, ~0U)) + param_act(P_BAD_VALUE, "conntrack", "--expires", s); + if (*end != '\0') + param_act(P_BAD_VALUE, "conntrack", "--expires", s); + + if (min > max) + exit_error(PARAMETER_PROBLEM, + "expire min. range value \"%u\" greater than max. " + "range value \"%u\"", min, max); + + info->expires_min = min; + info->expires_max = max; +} + /* Function which parses command options; returns true if it ate an option */ static int conntrack_parse(int c, char **argv, int invert, unsigned int *flags, @@ -305,10 +435,257 @@ static int conntrack_parse(int c, char * return 1; } +static int +conntrack_mt_parse(int c, char **argv, int invert, unsigned int *flags, + struct xt_entry_match **match) +{ + struct xt_conntrack_mtinfo1 *info = (void *)(*match)->data; + unsigned int port; + char *p; + + switch (c) { + case '1': /* --ctstate */ + conntrack_ps_states(info, optarg); + info->match_flags |= XT_CONNTRACK_STATE; + if (invert) + info->invert_flags |= XT_CONNTRACK_STATE; + break; + + case '2': /* --ctproto */ + /* Canonicalize into lower case */ + for (p = optarg; *p != '\0'; ++p) + *p = tolower(*p); + info->l4proto = parse_protocol(optarg); + + if (info->l4proto == 0 && (info->invert_flags & XT_INV_PROTO)) + exit_error(PARAMETER_PROBLEM, "conntrack: rule would " + "never match protocol"); + + info->match_flags |= XT_CONNTRACK_PROTO; + if (invert) + info->invert_flags |= XT_CONNTRACK_PROTO; + break; + + case '7': /* --ctstatus */ + conntrack_ps_statuses(info, optarg); + info->match_flags |= XT_CONNTRACK_STATUS; + if (invert) + info->invert_flags |= XT_CONNTRACK_STATUS; + break; + + case '8': /* --ctexpire */ + conntrack_ps_expires(info, optarg); + info->match_flags |= XT_CONNTRACK_EXPIRES; + if (invert) + info->invert_flags |= XT_CONNTRACK_EXPIRES; + break; + + case 'a': /* --ctorigsrcport */ + if (!strtonum(optarg, NULL, &port, 0, ~(u_int16_t)0)) + param_act(P_BAD_VALUE, "conntrack", + "--ctorigsrcport", optarg); + info->match_flags |= XT_CONNTRACK_ORIGSRC_PORT; + info->origsrc_port = htons(port); + if (invert) + info->invert_flags |= XT_CONNTRACK_ORIGSRC_PORT; + break; + + case 'b': /* --ctorigdstport */ + if (!strtonum(optarg, NULL, &port, 0, ~(u_int16_t)0)) + param_act(P_BAD_VALUE, "conntrack", + "--ctorigdstport", optarg); + info->match_flags |= XT_CONNTRACK_ORIGDST_PORT; + info->origdst_port = htons(port); + if (invert) + info->invert_flags |= XT_CONNTRACK_ORIGDST_PORT; + break; + + case 'c': /* --ctreplsrcport */ + if (!strtonum(optarg, NULL, &port, 0, ~(u_int16_t)0)) + param_act(P_BAD_VALUE, "conntrack", + "--ctreplsrcport", optarg); + info->match_flags |= XT_CONNTRACK_REPLSRC_PORT; + info->replsrc_port = htons(port); + if (invert) + info->invert_flags |= XT_CONNTRACK_REPLSRC_PORT; + break; + + case 'd': /* --ctrepldstport */ + if (!strtonum(optarg, NULL, &port, 0, ~(u_int16_t)0)) + param_act(P_BAD_VALUE, "conntrack", + "--ctrepldstport", optarg); + info->match_flags |= XT_CONNTRACK_REPLDST_PORT; + info->repldst_port = htons(port); + if (invert) + info->invert_flags |= XT_CONNTRACK_REPLDST_PORT; + break; + + case 'e': /* --ctdir */ + param_act(P_NO_INVERT, "conntrack", "--ctdir", invert); + if (strcasecmp(optarg, "ORIGINAL") == 0) { + info->match_flags |= XT_CONNTRACK_DIRECTION; + info->invert_flags &= ~XT_CONNTRACK_DIRECTION; + } else if (strcasecmp(optarg, "REPLY") == 0) { + info->match_flags |= XT_CONNTRACK_DIRECTION; + info->invert_flags |= XT_CONNTRACK_DIRECTION; + } else { + param_act(P_BAD_VALUE, "conntrack", "--ctdir", optarg); + } + break; + + default: + return false; + } + + *flags = info->match_flags; + return true; +} + +static int +conntrack_mt4_parse(int c, char **argv, int invert, unsigned int *flags, + const void *entry, struct xt_entry_match **match) +{ + struct xt_conntrack_mtinfo1 *info = (void *)(*match)->data; + struct in_addr *addr = NULL; + unsigned int naddrs = 0; + + switch (c) { + case '3': /* --ctorigsrc */ + ipparse_hostnetworkmask(optarg, &addr, &info->origsrc_mask.in, + &naddrs); + if (naddrs > 1) + exit_error(PARAMETER_PROBLEM, + "multiple IP addresses not allowed"); + if (naddrs == 1) + memcpy(&info->origsrc_addr.in, addr, sizeof(*addr)); + info->match_flags |= XT_CONNTRACK_ORIGSRC; + if (invert) + info->invert_flags |= XT_CONNTRACK_ORIGSRC; + break; + + case '4': /* --ctorigdst */ + ipparse_hostnetworkmask(optarg, &addr, &info->origdst_mask.in, + &naddrs); + if (naddrs > 1) + exit_error(PARAMETER_PROBLEM, + "multiple IP addresses not allowed"); + if (naddrs == 1) + memcpy(&info->origdst_addr.in, addr, sizeof(*addr)); + info->match_flags |= XT_CONNTRACK_ORIGDST; + if (invert) + info->invert_flags |= XT_CONNTRACK_ORIGDST; + break; + + case '5': /* --ctreplsrc */ + ipparse_hostnetworkmask(optarg, &addr, &info->replsrc_mask.in, + &naddrs); + if (naddrs > 1) + exit_error(PARAMETER_PROBLEM, + "multiple IP addresses not allowed"); + if (naddrs == 1) + memcpy(&info->replsrc_addr.in, addr, sizeof(*addr)); + info->match_flags |= XT_CONNTRACK_REPLSRC; + if (invert) + info->invert_flags |= XT_CONNTRACK_REPLSRC; + break; + + case '6': /* --ctrepldst */ + ipparse_hostnetworkmask(optarg, &addr, &info->repldst_mask.in, + &naddrs); + if (naddrs > 1) + exit_error(PARAMETER_PROBLEM, + "multiple IP addresses not allowed"); + if (naddrs == 1) + memcpy(&info->repldst_addr.in, addr, sizeof(*addr)); + info->match_flags |= XT_CONNTRACK_REPLDST; + if (invert) + info->invert_flags |= XT_CONNTRACK_REPLDST; + break; + + + default: + return conntrack_mt_parse(c, argv, invert, flags, match); + } + + *flags = info->match_flags; + return true; +} + +static int +conntrack_mt6_parse(int c, char **argv, int invert, unsigned int *flags, + const void *entry, struct xt_entry_match **match) +{ + struct xt_conntrack_mtinfo1 *info = (void *)(*match)->data; + struct in6_addr *addr = NULL; + unsigned int naddrs = 0; + + switch (c) { + case '3': /* --ctorigsrc */ + ip6parse_hostnetworkmask(optarg, &addr, + &info->origsrc_mask.in6, &naddrs); + if (naddrs > 1) + exit_error(PARAMETER_PROBLEM, + "multiple IP addresses not allowed"); + if (naddrs == 1) + memcpy(&info->origsrc_addr.in6, addr, sizeof(*addr)); + info->match_flags |= XT_CONNTRACK_ORIGSRC; + if (invert) + info->invert_flags |= XT_CONNTRACK_ORIGSRC; + break; + + case '4': /* --ctorigdst */ + ip6parse_hostnetworkmask(optarg, &addr, + &info->origdst_mask.in6, &naddrs); + if (naddrs > 1) + exit_error(PARAMETER_PROBLEM, + "multiple IP addresses not allowed"); + if (naddrs == 1) + memcpy(&info->origdst_addr.in, addr, sizeof(*addr)); + info->match_flags |= XT_CONNTRACK_ORIGDST; + if (invert) + info->invert_flags |= XT_CONNTRACK_ORIGDST; + break; + + case '5': /* --ctreplsrc */ + ip6parse_hostnetworkmask(optarg, &addr, + &info->replsrc_mask.in6, &naddrs); + if (naddrs > 1) + exit_error(PARAMETER_PROBLEM, + "multiple IP addresses not allowed"); + if (naddrs == 1) + memcpy(&info->replsrc_addr.in, addr, sizeof(*addr)); + info->match_flags |= XT_CONNTRACK_REPLSRC; + if (invert) + info->invert_flags |= XT_CONNTRACK_REPLSRC; + break; + + case '6': /* --ctrepldst */ + ip6parse_hostnetworkmask(optarg, &addr, + &info->repldst_mask.in6, &naddrs); + if (naddrs > 1) + exit_error(PARAMETER_PROBLEM, + "multiple IP addresses not allowed"); + if (naddrs == 1) + memcpy(&info->repldst_addr.in, addr, sizeof(*addr)); + info->match_flags |= XT_CONNTRACK_REPLDST; + if (invert) + info->invert_flags |= XT_CONNTRACK_REPLDST; + break; + + + default: + return conntrack_mt_parse(c, argv, invert, flags, match); + } + + *flags = info->match_flags; + return true; +} + static void conntrack_mt_check(unsigned int flags) { if (flags == 0) - exit_error(PARAMETER_PROBLEM, "You must specify one or more options"); + exit_error(PARAMETER_PROBLEM, "conntrack: At least one option " + "is required"); } static void @@ -364,20 +741,37 @@ print_status(unsigned int statusmask) printf("%sASSURED", sep); sep = ","; } -#ifdef IPS_CONFIRMED if (statusmask & IPS_CONFIRMED) { printf("%sCONFIRMED", sep); - sep =","; - } -#endif - if (statusmask == 0) { - printf("%sNONE", sep); sep = ","; } + if (statusmask == 0) + printf("%sNONE", sep); printf(" "); } static void +conntrack_dump_addr(const union nf_inet_addr *addr, + const union nf_inet_addr *mask, + unsigned int family, bool numeric) +{ + if (family == AF_INET) { + if (!numeric && addr->ip == 0) { + printf("anywhere "); + return; + } + printf("%s ", ipaddr_to_anyname(&addr->in)); + } else if (family == AF_INET6) { + if (!numeric && addr->ip6[0] == 0 && addr->ip6[1] == 0 && + addr->ip6[2] == 0 && addr->ip6[3] == 0) { + printf("anywhere "); + return; + } + printf("%s ", ip6addr_to_anyname(&addr->in6)); + } +} + +static void print_addr(struct in_addr *addr, struct in_addr *mask, int inv, int numeric) { char buf[BUFSIZ]; @@ -484,6 +878,103 @@ matchinfo_print(const void *ip, const st } } +static void +conntrack_dump(const struct xt_conntrack_mtinfo1 *info, const char *prefix, + unsigned int family, bool numeric) +{ + if (info->match_flags & XT_CONNTRACK_STATE) { + if (info->invert_flags & XT_CONNTRACK_STATE) + printf("! "); + printf("%sctstate ", prefix); + print_state(info->state_mask); + } + + if (info->match_flags & XT_CONNTRACK_PROTO) { + if (info->invert_flags & XT_CONNTRACK_PROTO) + printf("! "); + printf("%sctproto %u ", prefix, info->l4proto); + } + + if (info->match_flags & XT_CONNTRACK_ORIGSRC) { + if (info->invert_flags & XT_CONNTRACK_PROTO) + printf("! "); + printf("%sctorigsrc ", prefix); + conntrack_dump_addr(&info->origsrc_addr, &info->origsrc_mask, + family, numeric); + } + + if (info->match_flags & XT_CONNTRACK_ORIGDST) { + if (info->invert_flags & XT_CONNTRACK_PROTO) + printf("! "); + printf("%sctorigdst ", prefix); + conntrack_dump_addr(&info->origdst_addr, &info->origdst_mask, + family, numeric); + } + + if (info->match_flags & XT_CONNTRACK_REPLSRC) { + if (info->invert_flags & XT_CONNTRACK_PROTO) + printf("! "); + printf("%sctreplsrc ", prefix); + conntrack_dump_addr(&info->replsrc_addr, &info->replsrc_mask, + family, numeric); + } + + if (info->match_flags & XT_CONNTRACK_REPLDST) { + if (info->invert_flags & XT_CONNTRACK_PROTO) + printf("! "); + printf("%sctrepldst ", prefix); + conntrack_dump_addr(&info->repldst_addr, &info->repldst_mask, + family, numeric); + } + + if (info->match_flags & XT_CONNTRACK_ORIGSRC_PORT) { + if (info->invert_flags & XT_CONNTRACK_ORIGSRC_PORT) + printf("! "); + printf("%sctorigsrcport %u ", prefix, + ntohs(info->origsrc_port)); + } + + if (info->match_flags & XT_CONNTRACK_ORIGDST_PORT) { + if (info->invert_flags & XT_CONNTRACK_ORIGDST_PORT) + printf("! "); + printf("%sctorigdstport %u ", prefix, + ntohs(info->origdst_port)); + } + + if (info->match_flags & XT_CONNTRACK_REPLSRC_PORT) { + if (info->invert_flags & XT_CONNTRACK_REPLSRC_PORT) + printf("! "); + printf("%sctreplsrcport %u ", prefix, + ntohs(info->replsrc_port)); + } + + if (info->match_flags & XT_CONNTRACK_REPLDST_PORT) { + if (info->invert_flags & XT_CONNTRACK_REPLDST_PORT) + printf("! "); + printf("%sctrepldstport %u ", prefix, + ntohs(info->repldst_port)); + } + + if (info->match_flags & XT_CONNTRACK_STATUS) { + if (info->invert_flags & XT_CONNTRACK_STATUS) + printf("! "); + printf("%sctstatus ", prefix); + print_status(info->status_mask); + } + + if (info->match_flags & XT_CONNTRACK_EXPIRES) { + if (info->invert_flags & XT_CONNTRACK_EXPIRES) + printf("! "); + printf("%sctexpire ", prefix); + + if (info->expires_max == info->expires_min) + printf("%u ", (unsigned int)info->expires_min); + else + printf("%u:%u ", (unsigned int)info->expires_min, + (unsigned int)info->expires_max); + } +} + /* Prints out the matchinfo. */ static void conntrack_print(const void *ip, const struct xt_entry_match *match, int numeric) @@ -491,12 +982,38 @@ static void conntrack_print(const void * matchinfo_print(ip, match, numeric, ""); } +static void +conntrack_mt_print(const void *ip, const struct xt_entry_match *match, + int numeric) +{ + conntrack_dump((const void *)match->data, "", AF_INET, numeric); +} + +static void +conntrack_mt6_print(const void *ip, const struct xt_entry_match *match, + int numeric) +{ + conntrack_dump((const void *)match->data, "", AF_INET6, numeric); +} + /* Saves the matchinfo in parsable form to stdout. */ static void conntrack_save(const void *ip, const struct xt_entry_match *match) { matchinfo_print(ip, match, 1, "--"); } +static void conntrack_mt_save(const void *ip, + const struct xt_entry_match *match) +{ + conntrack_dump((const void *)match->data, "--", AF_INET, true); +} + +static void conntrack_mt6_save(const void *ip, + const struct xt_entry_match *match) +{ + conntrack_dump((const void *)match->data, "--", AF_INET6, true); +} + static struct xtables_match conntrack_match = { .version = IPTABLES_VERSION, .name = "conntrack", @@ -509,10 +1026,42 @@ static struct xtables_match conntrack_ma .final_check = conntrack_mt_check, .print = conntrack_print, .save = conntrack_save, + .extra_opts = conntrack_mt_opts_v0, +}; + +static struct xtables_match conntrack_mt_reg = { + .version = IPTABLES_VERSION, + .name = "conntrack", + .revision = 1, + .family = AF_INET, + .size = XT_ALIGN(sizeof(struct xt_conntrack_mtinfo1)), + .userspacesize = XT_ALIGN(sizeof(struct xt_conntrack_mtinfo1)), + .help = conntrack_mt_help, + .parse = conntrack_mt4_parse, + .final_check = conntrack_mt_check, + .print = conntrack_mt_print, + .save = conntrack_mt_save, + .extra_opts = conntrack_mt_opts, +}; + +static struct xtables_match conntrack_mt6_reg = { + .version = IPTABLES_VERSION, + .name = "conntrack", + .revision = 1, + .family = AF_INET6, + .size = XT_ALIGN(sizeof(struct xt_conntrack_mtinfo1)), + .userspacesize = XT_ALIGN(sizeof(struct xt_conntrack_mtinfo1)), + .help = conntrack_mt_help, + .parse = conntrack_mt6_parse, + .final_check = conntrack_mt_check, + .print = conntrack_mt6_print, + .save = conntrack_mt6_save, .extra_opts = conntrack_mt_opts, }; void _init(void) { xtables_register_match(&conntrack_match); + xtables_register_match(&conntrack_mt_reg); + xtables_register_match(&conntrack_mt6_reg); } Index: iptables/extensions/libxt_conntrack.man =================================================================== --- iptables.orig/extensions/libxt_conntrack.man +++ iptables/extensions/libxt_conntrack.man @@ -9,16 +9,22 @@ Possible states are listed below. Layer-4 protocol to match (by number or name) .TP [\fB!\fR] \fB--ctorigsrc\fR \fIaddress\fR[\fB/\fR\fImask\fR] -Match against original source address .TP [\fB!\fR] \fB--ctorigdst\fR \fIaddress\fR[\fB/\fR\fImask\fR] -Match against original destination address .TP [\fB!\fR] \fB--ctreplsrc\fR \fIaddress\fR[\fB/\fR\fImask\fR] -Match against reply source address .TP [\fB!\fR] \fB--ctrepldst\fR \fIaddress\fR[\fB/\fR\fImask\fR] -Match against reply destination address +Match against original/reply source/destination address +.TP +[\fB!\fR] \fB--ctorigsrcport\fR \fIport\fR +.TP +[\fB!\fR] \fB--ctorigdstport\fR \fIport\fR +.TP +[\fB!\fR] \fB--ctreplsrcport\fR \fIport\fR +.TP +[\fB!\fR] \fB--ctrepldstport\fR \fIport\fR +Match against original/reply source/destination port (TCP/UDP/etc.) or GRE key. .TP [\fB!\fR] \fB--ctstatus\fR \fIstatelist\fR \fIstatuslist\fR is a comma separated list of the connection statuses to match. @@ -27,6 +33,10 @@ Possible statuses are listed below. [\fB!\fR] \fB--ctexpire\fR \fItime\fR[\fB:\fR\fItime\fR] Match remaining lifetime in seconds against given value or range of values (inclusive) +.TP +\fB--ctdir\fR {\fBORIGINAL\fR|\fBREPLY\fR} +Match packets that are flowing in the specified direction. If this flag is not +specified at all, matches packets in both directions. .PP States for \fB--ctstate\fR: .TP - To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [IPTABLES]: libxt_conntrack revision 1 2008-01-24 22:38 ` [IPTABLES]: libxt_conntrack revision 1 Jan Engelhardt @ 2008-01-29 13:20 ` Patrick McHardy 0 siblings, 0 replies; 17+ messages in thread From: Patrick McHardy @ 2008-01-29 13:20 UTC (permalink / raw) To: Jan Engelhardt; +Cc: Netfilter Developer Mailing List Jan Engelhardt wrote: > Add support for xt_conntrack match revision 1. > > Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de> Applied, thanks. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [NETFILTER]: xt_conntrack: add port and direction matching 2008-01-24 22:38 [NETFILTER]: xt_conntrack: add port and direction matching Jan Engelhardt 2008-01-24 22:38 ` [IPTABLES]: libxt_conntrack revision 1 Jan Engelhardt @ 2008-01-29 13:08 ` Patrick McHardy 1 sibling, 0 replies; 17+ messages in thread From: Patrick McHardy @ 2008-01-29 13:08 UTC (permalink / raw) To: Jan Engelhardt; +Cc: Netfilter Developer Mailing List Jan Engelhardt wrote: > commit 7f1764fa749032eb8566226bbd1c5a58a8a5efc6 > Author: Jan Engelhardt <jengelh@computergmbh.de> > Date: Wed Jan 16 18:58:49 2008 +0100 > > [NETFILTER]: xt_conntrack: add port and direction matching > > Extend the xt_conntrack match revision 1 by port matching (all four > {orig,repl}{src,dst}) and by packet direction matching. Applied, thanks. ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 0/27] Netfilter update
@ 2008-01-02 20:18 Jan Engelhardt
2008-01-02 20:28 ` [PATCH 10/27] xt_conntrack match, revision 1 Jan Engelhardt
0 siblings, 1 reply; 17+ messages in thread
From: Jan Engelhardt @ 2008-01-02 20:18 UTC (permalink / raw)
To: kaber; +Cc: Netfilter Developer Mailing List
Hi Patrick,
Please cherrypick (or fetch&merge) from
git://computergmbh.de/linux netfilter
commits b6e9a26f05e83d8058f1dc56a45e5f5d533ad373 to
ff4d6f3afa5c8edb602a50abafb0ae7a2bb6132d (inclusive)
to receive the strawberries listed below (will also be posted as
replies to this mail for easy review from mailclient).
I planned for these to also go in for 2.6.25 already.
Jan Engelhardt (27):
[NETFILTER]: remove ipt_TOS.c
[NETFILTER]: Change semantic of mask value in xt_TOS
[NETFILTER]: Properly set the TOS field in xt_TOS
[NETFILTER]: Annotate start of kernel fields in NF headers
[NETFILTER]: Remove CONFIG_COMPAT code in xt_hashlimit, xt_limit
[NETFILTER]: xt_CONNMARK target, revision 1
[NETFILTER]: xt_MARK target, revision 2
[NETFILTER]: xt_connmark match, revision 1
[NETFILTER]: Extend nf_inet_addr with in{,6}_addr
[NETFILTER}: xt_conntrack match, revision 1
[NETFILTER]: xt_hashlimit: use the new union nf_inet_addr
[NETFILTER]: xt_hashlimit match, revision 1
[NETFILTER]: xt_helper: Do not bypass RCU
[NETFILTER]: xt_helper match, revision 1
[NETFILTER]: xt_length match, revision 1
[NETFILTER]: xt_mark match, revision 1
[NETFILTER]: xt_pkttype: Add explicit check for IPv4
[NETFILTER]: xt_pkttype IPv6 multicast address recognition
[NETFILTER]: xt_policy: use the new unoin nf_inet_addr
[NETFILTER]: Update modules' descriptions
[NETFILTER]: Convert unfixated types to fixated ones.
[NETFILTER]: Rename ipt_iprange to xt_iprange
[NETFILTER]: xt_iprange match, revision 1
[NETFILTER]: Merge ipt_REJECT and ip6t_REJECT into xt_REJECT
[NETFILTER]: Merge ipt_ah and ip6t_ah into xt_ah
[NETFILTER]: Unknot xt_ah IPv6 logic
[NETFILTER]: Update feature-removal-schedule.txt
Documentation/feature-removal-schedule.txt | 44 ++
include/linux/netfilter.h | 4 +
include/linux/netfilter/xt_CONNMARK.h | 5 +
include/linux/netfilter/xt_MARK.h | 4 +
include/linux/netfilter/xt_RATEEST.h | 2 +
include/linux/netfilter/xt_connlimit.h | 4 +-
include/linux/netfilter/xt_connmark.h | 5 +
include/linux/netfilter/xt_conntrack.h | 16 +-
include/linux/netfilter/xt_hashlimit.h | 39 ++-
include/linux/netfilter/xt_helper.h | 6 +
include/linux/netfilter/xt_iprange.h | 17 +
include/linux/netfilter/xt_length.h | 18 +
include/linux/netfilter/xt_mac.h | 4 +-
include/linux/netfilter/xt_mark.h | 5 +
include/linux/netfilter/xt_pkttype.h | 4 +-
include/linux/netfilter/xt_policy.h | 23 +-
include/linux/netfilter/xt_quota.h | 2 +
include/linux/netfilter/xt_rateest.h | 2 +
include/linux/netfilter/xt_sctp.h | 2 +-
include/linux/netfilter/xt_state.h | 2 +-
include/linux/netfilter/xt_statistic.h | 1 +
include/linux/netfilter/xt_string.h | 2 +
include/linux/netfilter_ipv4/ipt_CLUSTERIP.h | 1 +
include/linux/netfilter_ipv4/ipt_LOG.h | 4 +-
include/linux/netfilter_ipv4/ipt_SAME.h | 2 +-
include/linux/netfilter_ipv4/ipt_iprange.h | 6 +-
include/linux/netfilter_ipv4/ipt_sctp.h | 2 +-
include/linux/netfilter_ipv6/ip6t_LOG.h | 4 +-
net/ipv4/netfilter/Kconfig | 31 --
net/ipv4/netfilter/Makefile | 3 -
net/ipv4/netfilter/ipt_CLUSTERIP.c | 2 +-
net/ipv4/netfilter/ipt_ECN.c | 2 +-
net/ipv4/netfilter/ipt_LOG.c | 2 +-
net/ipv4/netfilter/ipt_MASQUERADE.c | 2 +-
net/ipv4/netfilter/ipt_NETMAP.c | 2 +-
net/ipv4/netfilter/ipt_REDIRECT.c | 2 +-
net/ipv4/netfilter/ipt_REJECT.c | 251 ---------
net/ipv4/netfilter/ipt_TOS.c | 82 ---
net/ipv4/netfilter/ipt_TTL.c | 2 +-
net/ipv4/netfilter/ipt_ULOG.c | 2 +-
net/ipv4/netfilter/ipt_addrtype.c | 2 +-
net/ipv4/netfilter/ipt_ah.c | 105 ----
net/ipv4/netfilter/ipt_ecn.c | 2 +-
net/ipv4/netfilter/ipt_iprange.c | 77 ---
net/ipv4/netfilter/ipt_recent.c | 2 +-
net/ipv4/netfilter/ipt_ttl.c | 2 +-
net/ipv6/netfilter/Kconfig | 20 -
net/ipv6/netfilter/Makefile | 2 -
net/ipv6/netfilter/ip6t_HL.c | 2 +-
net/ipv6/netfilter/ip6t_LOG.c | 2 +-
net/ipv6/netfilter/ip6t_REJECT.c | 260 ----------
net/ipv6/netfilter/ip6t_ah.c | 131 -----
net/ipv6/netfilter/ip6t_eui64.c | 2 +-
net/ipv6/netfilter/ip6t_frag.c | 2 +-
net/ipv6/netfilter/ip6t_hbh.c | 2 +-
net/ipv6/netfilter/ip6t_hl.c | 2 +-
net/ipv6/netfilter/ip6t_ipv6header.c | 2 +-
net/ipv6/netfilter/ip6t_mh.c | 2 +-
net/ipv6/netfilter/ip6t_rt.c | 2 +-
net/netfilter/Kconfig | 29 +
net/netfilter/Makefile | 3 +
net/netfilter/xt_CLASSIFY.c | 2 +-
net/netfilter/xt_CONNMARK.c | 119 ++++-
net/netfilter/xt_CONNSECMARK.c | 2 +-
net/netfilter/xt_DSCP.c | 8 +-
net/netfilter/xt_MARK.c | 76 ++-
net/netfilter/xt_NFLOG.c | 2 +-
net/netfilter/xt_NFQUEUE.c | 2 +-
net/netfilter/xt_NOTRACK.c | 1 +
net/netfilter/xt_RATEEST.c | 2 +-
net/netfilter/xt_REJECT.c | 484 ++++++++++++++++++
net/netfilter/xt_SECMARK.c | 2 +-
net/netfilter/xt_TCPMSS.c | 2 +-
net/netfilter/xt_TCPOPTSTRIP.c | 2 +-
net/netfilter/xt_TRACE.c | 1 +
net/netfilter/xt_ah.c | 194 +++++++
net/netfilter/xt_comment.c | 2 +-
net/netfilter/xt_connbytes.c | 2 +-
net/netfilter/xt_connlimit.c | 2 +-
net/netfilter/xt_connmark.c | 86 +++-
net/netfilter/xt_conntrack.c | 209 +++++++-
net/netfilter/xt_dccp.c | 2 +-
net/netfilter/xt_dscp.c | 2 +-
net/netfilter/xt_esp.c | 2 +-
net/netfilter/xt_hashlimit.c | 361 +++++++++++---
net/netfilter/xt_helper.c | 101 ++++-
net/netfilter/xt_iprange.c | 181 +++++++
net/netfilter/xt_length.c | 198 +++++++-
net/netfilter/xt_limit.c | 56 +--
net/netfilter/xt_mac.c | 2 +-
net/netfilter/xt_mark.c | 66 ++-
net/netfilter/xt_multiport.c | 2 +-
net/netfilter/xt_owner.c | 2 +-
net/netfilter/xt_physdev.c | 2 +-
net/netfilter/xt_pkttype.c | 19 +-
net/netfilter/xt_policy.c | 17 +-
net/netfilter/xt_quota.c | 1 +
net/netfilter/xt_realm.c | 2 +-
net/netfilter/xt_sctp.c | 2 +-
net/netfilter/xt_state.c | 2 +
net/netfilter/xt_statistic.c | 2 +-
net/netfilter/xt_string.c | 2 +-
net/netfilter/xt_tcpmss.c | 2 +-
net/netfilter/xt_tcpudp.c | 2 +-
net/netfilter/xt_time.c | 2 +-
net/netfilter/xt_u32.c | 2 +-
106 files changed, 2177 insertions(+), 1321 deletions(-)
create mode 100644 include/linux/netfilter/xt_iprange.h
delete mode 100644 net/ipv4/netfilter/ipt_REJECT.c
delete mode 100644 net/ipv4/netfilter/ipt_TOS.c
delete mode 100644 net/ipv4/netfilter/ipt_ah.c
delete mode 100644 net/ipv4/netfilter/ipt_iprange.c
delete mode 100644 net/ipv6/netfilter/ip6t_REJECT.c
delete mode 100644 net/ipv6/netfilter/ip6t_ah.c
create mode 100644 net/netfilter/xt_REJECT.c
create mode 100644 net/netfilter/xt_ah.c
create mode 100644 net/netfilter/xt_iprange.c
^ permalink raw reply [flat|nested] 17+ messages in thread* [PATCH 10/27] xt_conntrack match, revision 1 2008-01-02 20:18 [PATCH 0/27] Netfilter update Jan Engelhardt @ 2008-01-02 20:28 ` Jan Engelhardt 2008-01-04 14:53 ` Patrick McHardy 0 siblings, 1 reply; 17+ messages in thread From: Jan Engelhardt @ 2008-01-02 20:28 UTC (permalink / raw) To: kaber; +Cc: Netfilter Developer Mailing List commit 7e6ab7f2e7eb220d2ee5ce7f744a22deb10a5144 Author: Jan Engelhardt <jengelh@computergmbh.de> Date: Wed Jan 2 17:55:31 2008 +0100 [NETFILTER]: xt_conntrack match, revision 1 Introduces the xt_conntrack match revision 1. It uses fixed types, the new nf_inet_addr and comes with IPv6 support, thereby completely superseding xt_state. Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de> include/linux/netfilter/xt_conntrack.h | 16 ++- net/netfilter/xt_conntrack.c | 207 +++++++++++++++++++++--- net/netfilter/xt_state.c | 2 + 3 files changed, 199 insertions(+), 26 deletions(-) diff --git a/include/linux/netfilter/xt_conntrack.h b/include/linux/netfilter/xt_conntrack.h index 70b6f71..d2492a3 100644 --- a/include/linux/netfilter/xt_conntrack.h +++ b/include/linux/netfilter/xt_conntrack.h @@ -6,7 +6,9 @@ #define _XT_CONNTRACK_H #include <linux/netfilter/nf_conntrack_tuple_common.h> -#include <linux/in.h> +#ifdef __KERNEL__ +# include <linux/in.h> +#endif #define XT_CONNTRACK_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1)) #define XT_CONNTRACK_STATE_INVALID (1 << 0) @@ -60,4 +62,16 @@ struct xt_conntrack_info /* Inverse flags */ u_int8_t invflags; }; + +struct xt_conntrack_mtinfo1 { + union nf_inet_addr origsrc_addr, origsrc_mask; + union nf_inet_addr origdst_addr, origdst_mask; + union nf_inet_addr replsrc_addr, replsrc_mask; + union nf_inet_addr repldst_addr, repldst_mask; + u_int32_t expires_min, expires_max; + u_int16_t l4proto; + u_int8_t state_mask, status_mask; + u_int8_t match_flags, invert_flags; +}; + #endif /*_XT_CONNTRACK_H*/ diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c index 3f8bfba..dc9e737 100644 --- a/net/netfilter/xt_conntrack.c +++ b/net/netfilter/xt_conntrack.c @@ -1,15 +1,19 @@ -/* Kernel module to match connection tracking information. - * Superset of Rusty's minimalistic state match. +/* + * xt_conntrack - Netfilter module to match connection tracking + * information. (Superset of Rusty's minimalistic state match.) * - * (C) 2001 Marc Boucher (marc@mbsi.ca). + * (C) 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. + * 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 <net/ipv6.h> #include <linux/netfilter/x_tables.h> #include <linux/netfilter/xt_conntrack.h> #include <net/netfilter/nf_conntrack.h> @@ -18,12 +22,13 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); MODULE_DESCRIPTION("iptables connection tracking match module"); MODULE_ALIAS("ipt_conntrack"); +MODULE_ALIAS("ip6t_conntrack"); static bool -conntrack_mt(const struct sk_buff *skb, const struct net_device *in, - const struct net_device *out, const struct xt_match *match, - const void *matchinfo, int offset, unsigned int protoff, - bool *hotdrop) +conntrack_mt_v0(const struct sk_buff *skb, const struct net_device *in, + const struct net_device *out, const struct xt_match *match, + const void *matchinfo, int offset, unsigned int protoff, + bool *hotdrop) { const struct xt_conntrack_info *sinfo = matchinfo; const struct nf_conn *ct; @@ -112,6 +117,134 @@ conntrack_mt(const struct sk_buff *skb, const struct net_device *in, } static bool +conntrack_addrcmp(const union nf_inet_addr *kaddr, + const union nf_inet_addr *uaddr, + const union nf_inet_addr *umask, unsigned int l3proto) +{ + if (l3proto == AF_INET) + return (kaddr->ip & umask->ip) == uaddr->ip; + else if (l3proto == AF_INET6) + return ipv6_masked_addr_cmp(&kaddr->in6, &umask->in6, + &uaddr->in6) == 0; + else + return false; +} + +static inline bool +conntrack_mt_origsrc(const struct nf_conn *ct, + const struct xt_conntrack_mtinfo1 *info, + unsigned int family) +{ + return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3, + &info->origsrc_addr, &info->origsrc_mask, family); +} + +static inline bool +conntrack_mt_origdst(const struct nf_conn *ct, + const struct xt_conntrack_mtinfo1 *info, + unsigned int family) +{ + return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3, + &info->origdst_addr, &info->origdst_mask, family); +} + +static inline bool +conntrack_mt_replsrc(const struct nf_conn *ct, + const struct xt_conntrack_mtinfo1 *info, + unsigned int family) +{ + return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3, + &info->replsrc_addr, &info->replsrc_mask, family); +} + +static inline bool +conntrack_mt_repldst(const struct nf_conn *ct, + const struct xt_conntrack_mtinfo1 *info, + unsigned int family) +{ + return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3, + &info->repldst_addr, &info->repldst_mask, family); +} + +static bool +conntrack_mt(const struct sk_buff *skb, const struct net_device *in, + const struct net_device *out, const struct xt_match *match, + const void *matchinfo, int offset, unsigned int protoff, + bool *hotdrop) +{ + const struct xt_conntrack_mtinfo1 *info = matchinfo; + enum ip_conntrack_info ctinfo; + const struct nf_conn *ct; + unsigned int statebit; + + ct = nf_ct_get(skb, &ctinfo); + + if (ct == &nf_conntrack_untracked) + statebit = XT_CONNTRACK_STATE_UNTRACKED; + else if (ct != NULL) + statebit = XT_CONNTRACK_STATE_BIT(ctinfo); + else + statebit = XT_CONNTRACK_STATE_INVALID; + + if (info->match_flags & XT_CONNTRACK_STATE) { + if (ct != NULL) { + if (test_bit(IPS_SRC_NAT_BIT, &ct->status)) + statebit |= XT_CONNTRACK_STATE_SNAT; + if (test_bit(IPS_DST_NAT_BIT, &ct->status)) + statebit |= XT_CONNTRACK_STATE_DNAT; + } + if ((info->state_mask & statebit) ^ + !(info->invert_flags & XT_CONNTRACK_STATE)) + return false; + } + + if (ct == NULL) + return info->match_flags & XT_CONNTRACK_STATE; + + if ((info->match_flags & XT_CONNTRACK_PROTO) && + ((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum == + info->l4proto) ^ !(info->invert_flags & XT_CONNTRACK_PROTO))) + return false; + + if (info->match_flags & XT_CONNTRACK_ORIGSRC) + if (conntrack_mt_origsrc(ct, info, match->family) ^ + !(info->invert_flags & XT_CONNTRACK_ORIGSRC)) + return false; + + if (info->match_flags & XT_CONNTRACK_ORIGDST) + if (conntrack_mt_origdst(ct, info, match->family) ^ + !(info->invert_flags & XT_CONNTRACK_ORIGDST)) + return false; + + if (info->match_flags & XT_CONNTRACK_REPLSRC) + if (conntrack_mt_replsrc(ct, info, match->family) ^ + !(info->invert_flags & XT_CONNTRACK_REPLSRC)) + return false; + + if (info->match_flags & XT_CONNTRACK_REPLDST) + if (conntrack_mt_repldst(ct, info, match->family) ^ + !(info->invert_flags & XT_CONNTRACK_REPLDST)) + return false; + + if ((info->match_flags & XT_CONNTRACK_STATUS) && + (!!(info->status_mask & ct->status) ^ + !(info->invert_flags & XT_CONNTRACK_STATUS))) + return false; + + if (info->match_flags & XT_CONNTRACK_EXPIRES) { + unsigned long expires = 0; + + if (timer_pending(&ct->timeout)) + expires = (ct->timeout.expires - jiffies) / HZ; + if ((expires >= info->expires_min && + expires <= info->expires_max) ^ + !(info->invert_flags & XT_CONNTRACK_EXPIRES)) + return false; + } + return true; +} + +static bool conntrack_mt_check(const char *tablename, const void *ip, const struct xt_match *match, void *matchinfo, unsigned int hook_mask) @@ -144,7 +277,7 @@ struct compat_xt_conntrack_info u_int8_t invflags; }; -static void conntrack_mt_compat_from_user(void *dst, void *src) +static void conntrack_mt_compat_from_user_v0(void *dst, void *src) { const struct compat_xt_conntrack_info *cm = src; struct xt_conntrack_info m = { @@ -161,7 +294,7 @@ static void conntrack_mt_compat_from_user(void *dst, void *src) memcpy(dst, &m, sizeof(m)); } -static int conntrack_mt_compat_to_user(void __user *dst, void *src) +static int conntrack_mt_compat_to_user_v0(void __user *dst, void *src) { const struct xt_conntrack_info *m = src; struct compat_xt_conntrack_info cm = { @@ -179,29 +312,53 @@ static int conntrack_mt_compat_to_user(void __user *dst, void *src) } #endif -static struct xt_match conntrack_mt_reg __read_mostly = { - .name = "conntrack", - .match = conntrack_mt, - .checkentry = conntrack_mt_check, - .destroy = conntrack_mt_destroy, - .matchsize = sizeof(struct xt_conntrack_info), +static struct xt_match conntrack_mt_reg[] __read_mostly = { + { + .name = "conntrack", + .revision = 0, + .family = AF_INET, + .match = conntrack_mt_v0, + .checkentry = conntrack_mt_check, + .destroy = conntrack_mt_destroy, + .matchsize = sizeof(struct xt_conntrack_info), + .me = THIS_MODULE, #ifdef CONFIG_COMPAT - .compatsize = sizeof(struct compat_xt_conntrack_info), - .compat_from_user = conntrack_mt_compat_from_user, - .compat_to_user = conntrack_mt_compat_to_user, + .compatsize = sizeof(struct compat_xt_conntrack_info), + .compat_from_user = conntrack_mt_compat_from_user_v0, + .compat_to_user = conntrack_mt_compat_to_user_v0, #endif - .family = AF_INET, - .me = THIS_MODULE, + }, + { + .name = "conntrack", + .revision = 1, + .family = AF_INET, + .matchsize = sizeof(struct xt_conntrack_mtinfo1), + .match = conntrack_mt, + .checkentry = conntrack_mt_check, + .destroy = conntrack_mt_destroy, + .me = THIS_MODULE, + }, + { + .name = "conntrack", + .revision = 1, + .family = AF_INET6, + .matchsize = sizeof(struct xt_conntrack_mtinfo1), + .match = conntrack_mt, + .checkentry = conntrack_mt_check, + .destroy = conntrack_mt_destroy, + .me = THIS_MODULE, + }, }; static int __init conntrack_mt_init(void) { - return xt_register_match(&conntrack_mt_reg); + return xt_register_matches(conntrack_mt_reg, + ARRAY_SIZE(conntrack_mt_reg)); } static void __exit conntrack_mt_exit(void) { - xt_unregister_match(&conntrack_mt_reg); + xt_unregister_matches(conntrack_mt_reg, ARRAY_SIZE(conntrack_mt_reg)); } module_init(conntrack_mt_init); diff --git a/net/netfilter/xt_state.c b/net/netfilter/xt_state.c index a776dc3..24804a3 100644 --- a/net/netfilter/xt_state.c +++ b/net/netfilter/xt_state.c @@ -81,6 +81,8 @@ static struct xt_match state_mt_reg[] __read_mostly = { static int __init state_mt_init(void) { + printk(KERN_NOTICE "xt_state is obsolete, please use " + "xt_conntrack instead.\n"); return xt_register_matches(state_mt_reg, ARRAY_SIZE(state_mt_reg)); } - To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH 10/27] xt_conntrack match, revision 1 2008-01-02 20:28 ` [PATCH 10/27] xt_conntrack match, revision 1 Jan Engelhardt @ 2008-01-04 14:53 ` Patrick McHardy 2008-01-15 6:48 ` Patrick McHardy 0 siblings, 1 reply; 17+ messages in thread From: Patrick McHardy @ 2008-01-04 14:53 UTC (permalink / raw) To: Jan Engelhardt; +Cc: Netfilter Developer Mailing List Jan Engelhardt wrote: > commit 7e6ab7f2e7eb220d2ee5ce7f744a22deb10a5144 > Author: Jan Engelhardt <jengelh@computergmbh.de> > Date: Wed Jan 2 17:55:31 2008 +0100 > > [NETFILTER]: xt_conntrack match, revision 1 > > Introduces the xt_conntrack match revision 1. It uses fixed types, the > new nf_inet_addr and comes with IPv6 support, thereby completely > superseding xt_state. Applied, but > diff --git a/include/linux/netfilter/xt_conntrack.h b/include/linux/netfilter/xt_conntrack.h > index 70b6f71..d2492a3 100644 > --- a/include/linux/netfilter/xt_conntrack.h > +++ b/include/linux/netfilter/xt_conntrack.h > @@ -6,7 +6,9 @@ > #define _XT_CONNTRACK_H > > #include <linux/netfilter/nf_conntrack_tuple_common.h> > -#include <linux/in.h> > +#ifdef __KERNEL__ > +# include <linux/in.h> > +#endif Is that really necessary? I would prefer the only in-kernel user of this file to include it directly. Or simply include netfilter.h, which seems necessary for nf_inet_addr anyway. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 10/27] xt_conntrack match, revision 1 2008-01-04 14:53 ` Patrick McHardy @ 2008-01-15 6:48 ` Patrick McHardy 2008-01-15 12:31 ` Jan Engelhardt 0 siblings, 1 reply; 17+ messages in thread From: Patrick McHardy @ 2008-01-15 6:48 UTC (permalink / raw) To: Jan Engelhardt; +Cc: Netfilter Developer Mailing List Patrick McHardy wrote: > Jan Engelhardt wrote: >> commit 7e6ab7f2e7eb220d2ee5ce7f744a22deb10a5144 >> Author: Jan Engelhardt <jengelh@computergmbh.de> >> Date: Wed Jan 2 17:55:31 2008 +0100 >> >> [NETFILTER]: xt_conntrack match, revision 1 >> Introduces the xt_conntrack match revision 1. It uses fixed >> types, the >> new nf_inet_addr and comes with IPv6 support, thereby completely >> superseding xt_state. > > Applied. This reminded me - while we're introducing new revisions, there are two things that have always been missing from xt_conntrack and I know of multiple patches adding this. One is port matching for both directions, the other is matching on the direction itself. Would you be interested in adding this? Otherwise I'm going to take care of it myself. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 10/27] xt_conntrack match, revision 1 2008-01-15 6:48 ` Patrick McHardy @ 2008-01-15 12:31 ` Jan Engelhardt 2008-01-15 14:13 ` Patrick McHardy 0 siblings, 1 reply; 17+ messages in thread From: Jan Engelhardt @ 2008-01-15 12:31 UTC (permalink / raw) To: Patrick McHardy; +Cc: Netfilter Developer Mailing List On Jan 15 2008 07:48, Patrick McHardy wrote: > > This reminded me - while we're introducing new revisions, there > are two things that have always been missing from xt_conntrack > and I know of multiple patches adding this. One is port matching > for both directions, the other is matching on the direction > itself. Would you be interested in adding this? Otherwise I'm > going to take care of it myself. > I will take care of that, yes. While matching the direction is probably a no-brainer (just checking a field), I would be interested in how "direction" is actually defined. Does the first packet in a NEW ct dictate the direction? What values does a direction have - north, south, left, right? I did not name "inbound" and "outbound" on purpose, because routers do not have an "in" or "out" side like most consumer desktop boxes. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 10/27] xt_conntrack match, revision 1 2008-01-15 12:31 ` Jan Engelhardt @ 2008-01-15 14:13 ` Patrick McHardy 2008-01-16 18:02 ` [NETFILTER]: xt_conntrack: add port and direction matching Jan Engelhardt 0 siblings, 1 reply; 17+ messages in thread From: Patrick McHardy @ 2008-01-15 14:13 UTC (permalink / raw) To: Jan Engelhardt; +Cc: Netfilter Developer Mailing List Jan Engelhardt wrote: > On Jan 15 2008 07:48, Patrick McHardy wrote: >> This reminded me - while we're introducing new revisions, there >> are two things that have always been missing from xt_conntrack >> and I know of multiple patches adding this. One is port matching >> for both directions, the other is matching on the direction >> itself. Would you be interested in adding this? Otherwise I'm >> going to take care of it myself. >> > > I will take care of that, yes. Thanks. > While matching the direction is probably a no-brainer (just checking > a field), I would be interested in how "direction" is actually defined. > Does the first packet in a NEW ct dictate the direction? What values > does a direction have - north, south, left, right? > I did not name "inbound" and "outbound" on purpose, because routers > do not have an "in" or "out" side like most consumer desktop boxes. In case of xt_conntrack the directions are relative to the first packet of the connection, as with orig-src, repl-src, ... ^ permalink raw reply [flat|nested] 17+ messages in thread
* [NETFILTER]: xt_conntrack: add port and direction matching 2008-01-15 14:13 ` Patrick McHardy @ 2008-01-16 18:02 ` Jan Engelhardt 2008-01-17 13:52 ` Pablo Neira Ayuso 0 siblings, 1 reply; 17+ messages in thread From: Jan Engelhardt @ 2008-01-16 18:02 UTC (permalink / raw) To: Patrick McHardy; +Cc: Netfilter Developer Mailing List On Jan 15 2008 15:13, Patrick McHardy wrote: > Jan Engelhardt wrote: >> On Jan 15 2008 07:48, Patrick McHardy wrote: >> > This reminded me - while we're introducing new revisions, there >> > are two things that have always been missing from xt_conntrack >> > and I know of multiple patches adding this. One is port matching >> > for both directions, the other is matching on the direction >> > itself. Would you be interested in adding this? Otherwise I'm >> > going to take care of it myself. >> > >> >> I will take care of that, yes. > > Thanks. > This patch also removes the ugly #include <linux/in.h>, which is already found in netfilter.h (which is a better place). === commit 17934f6d825d2a6785cd8d7811997a8620cfd528 Author: Jan Engelhardt <jengelh@computergmbh.de> Date: Wed Jan 16 18:58:49 2008 +0100 [NETFILTER]: xt_conntrack: add port and direction matching Extend the xt_conntrack match revision 1 by port matching (all four {orig,repl}{src,dst}) and by packet direction matching. Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de> diff --git a/include/linux/netfilter/xt_conntrack.h b/include/linux/netfilter/xt_conntrack.h index d2492a3..9e35ccd 100644 --- a/include/linux/netfilter/xt_conntrack.h +++ b/include/linux/netfilter/xt_conntrack.h @@ -6,9 +6,6 @@ #define _XT_CONNTRACK_H #include <linux/netfilter/nf_conntrack_tuple_common.h> -#ifdef __KERNEL__ -# include <linux/in.h> -#endif #define XT_CONNTRACK_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1)) #define XT_CONNTRACK_STATE_INVALID (1 << 0) @@ -18,14 +15,21 @@ #define XT_CONNTRACK_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 3)) /* flags, invflags: */ -#define XT_CONNTRACK_STATE 0x01 -#define XT_CONNTRACK_PROTO 0x02 -#define XT_CONNTRACK_ORIGSRC 0x04 -#define XT_CONNTRACK_ORIGDST 0x08 -#define XT_CONNTRACK_REPLSRC 0x10 -#define XT_CONNTRACK_REPLDST 0x20 -#define XT_CONNTRACK_STATUS 0x40 -#define XT_CONNTRACK_EXPIRES 0x80 +enum { + XT_CONNTRACK_STATE = 1 << 0, + XT_CONNTRACK_PROTO = 1 << 1, + XT_CONNTRACK_ORIGSRC = 1 << 2, + XT_CONNTRACK_ORIGDST = 1 << 3, + XT_CONNTRACK_REPLSRC = 1 << 4, + XT_CONNTRACK_REPLDST = 1 << 5, + XT_CONNTRACK_STATUS = 1 << 6, + XT_CONNTRACK_EXPIRES = 1 << 7, + XT_CONNTRACK_ORIGSRC_PORT = 1 << 8, + XT_CONNTRACK_ORIGDST_PORT = 1 << 9, + XT_CONNTRACK_REPLSRC_PORT = 1 << 10, + XT_CONNTRACK_REPLDST_PORT = 1 << 11, + XT_CONNTRACK_DIRECTION = 1 << 12, +}; /* This is exposed to userspace, so remains frozen in time. */ struct ip_conntrack_old_tuple @@ -70,8 +74,10 @@ struct xt_conntrack_mtinfo1 { union nf_inet_addr repldst_addr, repldst_mask; u_int32_t expires_min, expires_max; u_int16_t l4proto; + u_int16_t origsrc_port, origdst_port; + u_int16_t replsrc_port, repldst_port; + u_int16_t match_flags, invert_flags; u_int8_t state_mask, status_mask; - u_int8_t match_flags, invert_flags; }; #endif /*_XT_CONNTRACK_H*/ diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c index e92190e..851cba6 100644 --- a/net/netfilter/xt_conntrack.c +++ b/net/netfilter/xt_conntrack.c @@ -166,6 +166,67 @@ conntrack_mt_repldst(const struct nf_conn *ct, &info->repldst_addr, &info->repldst_mask, family); } +static inline bool +ct_proto_port_check(const struct xt_conntrack_mtinfo1 *info, + const struct nf_conn *ct) +{ + const struct nf_conntrack_tuple *tuple; + + tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; + if (info->match_flags & XT_CONNTRACK_PROTO) + if ((tuple->dst.protonum == info->l4proto) ^ + !(info->invert_flags & XT_CONNTRACK_PROTO)) + return false; + + switch (tuple->dst.protonum) { + case IPPROTO_TCP: + case IPPROTO_UDP: + case IPPROTO_SCTP: + /* + * shortcut by using .u.all rather than + * .u.tcp.port + .u.udp.port! + */ + if ((info->match_flags & XT_CONNTRACK_ORIGSRC_PORT) && + (tuple->src.u.all != info->origsrc_port) ^ + !(info->invert_flags & XT_CONNTRACK_ORIGSRC_PORT)) + return false; + if ((info->match_flags & XT_CONNTRACK_ORIGDST_PORT) && + (tuple->dst.u.all != info->origdst_port) ^ + !(info->invert_flags & XT_CONNTRACK_ORIGDST_PORT)) + return false; + break; + default: + if ((info->match_flags ^ info->invert_flags) & + (XT_CONNTRACK_ORIGSRC_PORT | XT_CONNTRACK_ORIGDST_PORT)) + return false; + break; + } + + tuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple; + switch (tuple->dst.protonum) { + case IPPROTO_TCP: + case IPPROTO_UDP: + case IPPROTO_SCTP: + /* shortcut by using ->src.all */ + if ((info->match_flags & XT_CONNTRACK_REPLSRC_PORT) && + (tuple->src.u.all != info->replsrc_port) ^ + !(info->invert_flags & XT_CONNTRACK_REPLSRC_PORT)) + return false; + if ((info->match_flags & XT_CONNTRACK_REPLDST_PORT) && + (tuple->dst.u.all != info->repldst_port) ^ + !(info->invert_flags & XT_CONNTRACK_REPLDST_PORT)) + return false; + break; + default: + if ((info->match_flags ^ info->invert_flags) & + (XT_CONNTRACK_REPLSRC_PORT | XT_CONNTRACK_REPLDST_PORT)) + return false; + break; + } + + return true; +} + static bool conntrack_mt(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, const struct xt_match *match, @@ -200,10 +261,11 @@ conntrack_mt(const struct sk_buff *skb, const struct net_device *in, if (ct == NULL) return info->match_flags & XT_CONNTRACK_STATE; - - if ((info->match_flags & XT_CONNTRACK_PROTO) && - ((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum == - info->l4proto) ^ !(info->invert_flags & XT_CONNTRACK_PROTO))) + if (!ct_proto_port_check(info, ct)) + return false; + if ((info->match_flags & XT_CONNTRACK_DIRECTION) && + (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) ^ + !!(info->invert_flags & XT_CONNTRACK_DIRECTION)) return false; if (info->match_flags & XT_CONNTRACK_ORIGSRC) ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [NETFILTER]: xt_conntrack: add port and direction matching 2008-01-16 18:02 ` [NETFILTER]: xt_conntrack: add port and direction matching Jan Engelhardt @ 2008-01-17 13:52 ` Pablo Neira Ayuso 2008-01-17 15:00 ` Jan Engelhardt 0 siblings, 1 reply; 17+ messages in thread From: Pablo Neira Ayuso @ 2008-01-17 13:52 UTC (permalink / raw) To: Jan Engelhardt; +Cc: Patrick McHardy, Netfilter Developer Mailing List Jan Engelhardt wrote: > + switch (tuple->dst.protonum) { > + case IPPROTO_TCP: > + case IPPROTO_UDP: > + case IPPROTO_SCTP: Minor nitpick. Add IPPROTO_UDPLITE. -- "Los honestos son inadaptados sociales" -- Les Luthiers ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [NETFILTER]: xt_conntrack: add port and direction matching 2008-01-17 13:52 ` Pablo Neira Ayuso @ 2008-01-17 15:00 ` Jan Engelhardt 2008-01-20 13:00 ` Patrick McHardy 0 siblings, 1 reply; 17+ messages in thread From: Jan Engelhardt @ 2008-01-17 15:00 UTC (permalink / raw) To: Pablo Neira Ayuso; +Cc: Patrick McHardy, Netfilter Developer Mailing List On Jan 17 2008 14:52, Pablo Neira Ayuso wrote: > Jan Engelhardt wrote: >> + switch (tuple->dst.protonum) { >> + case IPPROTO_TCP: >> + case IPPROTO_UDP: >> + case IPPROTO_SCTP: > > Minor nitpick. Add IPPROTO_UDPLITE. Yeah that can be easily added. I wonder why Netfilter does not support DCCP conntracking? (At least there is no dccp field in struct nf_conn and the tuple things.) ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [NETFILTER]: xt_conntrack: add port and direction matching 2008-01-17 15:00 ` Jan Engelhardt @ 2008-01-20 13:00 ` Patrick McHardy 2008-01-20 13:12 ` Jan Engelhardt 2008-01-21 1:14 ` Pablo Neira Ayuso 0 siblings, 2 replies; 17+ messages in thread From: Patrick McHardy @ 2008-01-20 13:00 UTC (permalink / raw) To: Jan Engelhardt; +Cc: Pablo Neira Ayuso, Netfilter Developer Mailing List Jan Engelhardt wrote: > On Jan 17 2008 14:52, Pablo Neira Ayuso wrote: >> Jan Engelhardt wrote: >>> + switch (tuple->dst.protonum) { >>> + case IPPROTO_TCP: >>> + case IPPROTO_UDP: >>> + case IPPROTO_SCTP: >> Minor nitpick. Add IPPROTO_UDPLITE. > > Yeah that can be easily added. Another nitpick: we support masks for the addresses, ranges of ports would be nice to have here as well. I also don't think the protocol check is very useful in this case since all conntrack entries contain port numbers or something similar. > I wonder why Netfilter does not support > DCCP conntracking? (At least there is no dccp field in struct nf_conn > and the tuple things.) I have an old patch for this, but it was missing proper protocol state tracking. Perhaps I should merge it without it for now since thats still better than no support at all. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [NETFILTER]: xt_conntrack: add port and direction matching 2008-01-20 13:00 ` Patrick McHardy @ 2008-01-20 13:12 ` Jan Engelhardt 2008-01-20 13:15 ` Patrick McHardy 2008-01-21 1:14 ` Pablo Neira Ayuso 1 sibling, 1 reply; 17+ messages in thread From: Jan Engelhardt @ 2008-01-20 13:12 UTC (permalink / raw) To: Patrick McHardy; +Cc: Pablo Neira Ayuso, Netfilter Developer Mailing List On Jan 20 2008 14:00, Patrick McHardy wrote: > > Another nitpick: we support masks for the addresses, ranges of ports > would be nice to have here as well. Well well why don't we just add address ranges too then :p Do we need it so badly? > I also don't think the protocol > check is very useful in this case since all conntrack entries contain > port numbers or something similar. Is IPv4-in-IPv4 or IPv6-in-IPv4 conntracked like UDP is? The protocol check is important though, because IPPROTO_GRE is _not_ included, since, it's not something that has a port. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [NETFILTER]: xt_conntrack: add port and direction matching 2008-01-20 13:12 ` Jan Engelhardt @ 2008-01-20 13:15 ` Patrick McHardy 2008-01-20 16:48 ` Jan Engelhardt 0 siblings, 1 reply; 17+ messages in thread From: Patrick McHardy @ 2008-01-20 13:15 UTC (permalink / raw) To: Jan Engelhardt; +Cc: Pablo Neira Ayuso, Netfilter Developer Mailing List Jan Engelhardt wrote: > On Jan 20 2008 14:00, Patrick McHardy wrote: >> Another nitpick: we support masks for the addresses, ranges of ports >> would be nice to have here as well. > > Well well why don't we just add address ranges too then :p > Do we need it so badly? We already have masks, which is probably good enough. > >> I also don't think the protocol >> check is very useful in this case since all conntrack entries contain >> port numbers or something similar. > > Is IPv4-in-IPv4 or IPv6-in-IPv4 conntracked like UDP is? Sure, by proto_generic, which uses 0 for the port numbers. > The protocol check is important though, because IPPROTO_GRE is > _not_ included, since, it's not something that has a port. It has the keys, which are also just a numerical value. Don't think of it as ports but as "layer 4 protocol keys". ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [NETFILTER]: xt_conntrack: add port and direction matching 2008-01-20 13:15 ` Patrick McHardy @ 2008-01-20 16:48 ` Jan Engelhardt 2008-01-20 16:55 ` Patrick McHardy 0 siblings, 1 reply; 17+ messages in thread From: Jan Engelhardt @ 2008-01-20 16:48 UTC (permalink / raw) To: Patrick McHardy; +Cc: Pablo Neira Ayuso, Netfilter Developer Mailing List On Jan 20 2008 14:15, Patrick McHardy wrote: >> >> > I also don't think the protocol >> > check is very useful in this case since all conntrack entries contain >> > port numbers or something similar. >> >> Is IPv4-in-IPv4 or IPv6-in-IPv4 conntracked like UDP is? > > Sure, by proto_generic, which uses 0 for the port numbers. See, that's another case why we have to explicitly list the protocols. Just consider a stupid invocation of iptables: -m conntrack --ctorigport 0 I'd rather not let that match IPv4-in-IPv4 or so. >> The protocol check is important though, because IPPROTO_GRE is >> _not_ included, since, it's not something that has a port. > > It has the keys, which are also just a numerical value. Don't > think of it as ports but as "layer 4 protocol keys". > But do these keys actually get modified in NAT? ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [NETFILTER]: xt_conntrack: add port and direction matching 2008-01-20 16:48 ` Jan Engelhardt @ 2008-01-20 16:55 ` Patrick McHardy 0 siblings, 0 replies; 17+ messages in thread From: Patrick McHardy @ 2008-01-20 16:55 UTC (permalink / raw) To: Jan Engelhardt; +Cc: Pablo Neira Ayuso, Netfilter Developer Mailing List Jan Engelhardt wrote: > On Jan 20 2008 14:15, Patrick McHardy wrote: >>>> I also don't think the protocol >>>> check is very useful in this case since all conntrack entries contain >>>> port numbers or something similar. >>> Is IPv4-in-IPv4 or IPv6-in-IPv4 conntracked like UDP is? >> Sure, by proto_generic, which uses 0 for the port numbers. > > See, that's another case why we have to explicitly list the protocols. > Just consider a stupid invocation of iptables: > > -m conntrack --ctorigport 0 > > I'd rather not let that match IPv4-in-IPv4 or so. I prefer that to listing all the protocols explicitly. I guess you would not object if it was named "--ctorigprotokey", but --ctorigport is clearer for most protocols. >>> The protocol check is important though, because IPPROTO_GRE is >>> _not_ included, since, it's not something that has a port. >> It has the keys, which are also just a numerical value. Don't >> think of it as ports but as "layer 4 protocol keys". >> > But do these keys actually get modified in NAT? If the protocol is known to NAT and it clashes then yes. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [NETFILTER]: xt_conntrack: add port and direction matching 2008-01-20 13:00 ` Patrick McHardy 2008-01-20 13:12 ` Jan Engelhardt @ 2008-01-21 1:14 ` Pablo Neira Ayuso 2008-01-21 1:15 ` Jan Engelhardt 2008-01-21 1:19 ` Patrick McHardy 1 sibling, 2 replies; 17+ messages in thread From: Pablo Neira Ayuso @ 2008-01-21 1:14 UTC (permalink / raw) To: Jan Engelhardt; +Cc: Patrick McHardy, Netfilter Developer Mailing List Patrick McHardy wrote: > Jan Engelhardt wrote: >> On Jan 17 2008 14:52, Pablo Neira Ayuso wrote: >>> Jan Engelhardt wrote: >>>> + switch (tuple->dst.protonum) { >>>> + case IPPROTO_TCP: >>>> + case IPPROTO_UDP: >>>> + case IPPROTO_SCTP: >>> Minor nitpick. Add IPPROTO_UDPLITE. >> >> Yeah that can be easily added. BTW, it would be great if we add support for layer 4 protocol state matching, e.g. match TCP established. We can use this together with the target that would mark certain events as volatile, e.g. iptables -A 192.168.0.0/24 -m conntrack ! --tcp-state ESTABLISHED -j VOLATILE The idea behind this it that ctnetlink would ignore certain events, thus, reducing CPU load. -- "Los honestos son inadaptados sociales" -- Les Luthiers ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [NETFILTER]: xt_conntrack: add port and direction matching 2008-01-21 1:14 ` Pablo Neira Ayuso @ 2008-01-21 1:15 ` Jan Engelhardt 2008-01-21 1:18 ` Pablo Neira Ayuso 2008-01-21 1:19 ` Patrick McHardy 1 sibling, 1 reply; 17+ messages in thread From: Jan Engelhardt @ 2008-01-21 1:15 UTC (permalink / raw) To: Pablo Neira Ayuso; +Cc: Patrick McHardy, Netfilter Developer Mailing List On Jan 21 2008 02:14, Pablo Neira Ayuso wrote: > >BTW, it would be great if we add support for layer 4 protocol state >matching, e.g. match TCP established. We can use this together with the >target that would mark certain events as volatile, e.g. > >iptables -A 192.168.0.0/24 -m conntrack ! --tcp-state ESTABLISHED -j >VOLATILE And what's xt_VOLATILE do? (Was it hidden in your recent xt_CONNTRACK submission?) >The idea behind this it that ctnetlink would ignore certain events, >thus, reducing CPU load. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [NETFILTER]: xt_conntrack: add port and direction matching 2008-01-21 1:15 ` Jan Engelhardt @ 2008-01-21 1:18 ` Pablo Neira Ayuso 2008-01-21 1:31 ` Jan Engelhardt 0 siblings, 1 reply; 17+ messages in thread From: Pablo Neira Ayuso @ 2008-01-21 1:18 UTC (permalink / raw) To: Jan Engelhardt; +Cc: Patrick McHardy, Netfilter Developer Mailing List Jan Engelhardt wrote: > On Jan 21 2008 02:14, Pablo Neira Ayuso wrote: >> BTW, it would be great if we add support for layer 4 protocol state >> matching, e.g. match TCP established. We can use this together with the >> target that would mark certain events as volatile, e.g. >> >> iptables -A 192.168.0.0/24 -m conntrack ! --tcp-state ESTABLISHED -j >> VOLATILE > > And what's xt_VOLATILE do? (Was it hidden in your recent > xt_CONNTRACK submission?) Indeed. Just set the IPCT_VOLATILE flag to tell ctnetlink to skip that event. It would be a very simple target. I don't know if VOLATILE would be a nice name, perhaps CTNETLINK. -- "Los honestos son inadaptados sociales" -- Les Luthiers ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [NETFILTER]: xt_conntrack: add port and direction matching 2008-01-21 1:18 ` Pablo Neira Ayuso @ 2008-01-21 1:31 ` Jan Engelhardt 0 siblings, 0 replies; 17+ messages in thread From: Jan Engelhardt @ 2008-01-21 1:31 UTC (permalink / raw) To: Pablo Neira Ayuso; +Cc: Patrick McHardy, Netfilter Developer Mailing List On Jan 21 2008 02:18, Pablo Neira Ayuso wrote: >> >> And what's xt_VOLATILE do? (Was it hidden in your recent >> xt_CONNTRACK submission?) > >Indeed. Just set the IPCT_VOLATILE flag to tell ctnetlink to skip that >event. It would be a very simple target. I don't know if VOLATILE would >be a nice name, perhaps CTNETLINK. Oh I would not mind names all that much. At the basic level, there is ACCEPT DROP and REJECT. Then, in the depths of POM-nation there is TARPIT and TEE, (I'm missing COFFEE). Elsewhere, I wrote CHAOS and DELUDE. Most recently, I sampled up STEAL. You see, VOLATILE is not so off after all. :-) ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [NETFILTER]: xt_conntrack: add port and direction matching 2008-01-21 1:14 ` Pablo Neira Ayuso 2008-01-21 1:15 ` Jan Engelhardt @ 2008-01-21 1:19 ` Patrick McHardy 1 sibling, 0 replies; 17+ messages in thread From: Patrick McHardy @ 2008-01-21 1:19 UTC (permalink / raw) To: Pablo Neira Ayuso; +Cc: Jan Engelhardt, Netfilter Developer Mailing List Pablo Neira Ayuso wrote: > Patrick McHardy wrote: >> Jan Engelhardt wrote: >>> On Jan 17 2008 14:52, Pablo Neira Ayuso wrote: >>>> Jan Engelhardt wrote: >>>>> + switch (tuple->dst.protonum) { >>>>> + case IPPROTO_TCP: >>>>> + case IPPROTO_UDP: >>>>> + case IPPROTO_SCTP: >>>> Minor nitpick. Add IPPROTO_UDPLITE. >>> Yeah that can be easily added. > > BTW, it would be great if we add support for layer 4 protocol state > matching, e.g. match TCP established. We can use this together with the > target that would mark certain events as volatile, e.g. > > iptables -A 192.168.0.0/24 -m conntrack ! --tcp-state ESTABLISHED -j > VOLATILE > > The idea behind this it that ctnetlink would ignore certain events, > thus, reducing CPU load. I guess the main question is how to do this properly without running into compatiblity problems at the next opportunity with our crappy userspace interface. Can we trust that a u8 is enough for all relevant states for the forseeable future? For the purpose of avoiding uninteresting state messages it seems like good enough ... ^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2008-01-29 13:36 UTC | newest] Thread overview: 17+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-01-24 22:38 [NETFILTER]: xt_conntrack: add port and direction matching Jan Engelhardt 2008-01-24 22:38 ` [IPTABLES]: libxt_conntrack revision 1 Jan Engelhardt 2008-01-29 13:20 ` Patrick McHardy 2008-01-29 13:08 ` [NETFILTER]: xt_conntrack: add port and direction matching Patrick McHardy -- strict thread matches above, loose matches on Subject: below -- 2008-01-02 20:18 [PATCH 0/27] Netfilter update Jan Engelhardt 2008-01-02 20:28 ` [PATCH 10/27] xt_conntrack match, revision 1 Jan Engelhardt 2008-01-04 14:53 ` Patrick McHardy 2008-01-15 6:48 ` Patrick McHardy 2008-01-15 12:31 ` Jan Engelhardt 2008-01-15 14:13 ` Patrick McHardy 2008-01-16 18:02 ` [NETFILTER]: xt_conntrack: add port and direction matching Jan Engelhardt 2008-01-17 13:52 ` Pablo Neira Ayuso 2008-01-17 15:00 ` Jan Engelhardt 2008-01-20 13:00 ` Patrick McHardy 2008-01-20 13:12 ` Jan Engelhardt 2008-01-20 13:15 ` Patrick McHardy 2008-01-20 16:48 ` Jan Engelhardt 2008-01-20 16:55 ` Patrick McHardy 2008-01-21 1:14 ` Pablo Neira Ayuso 2008-01-21 1:15 ` Jan Engelhardt 2008-01-21 1:18 ` Pablo Neira Ayuso 2008-01-21 1:31 ` Jan Engelhardt 2008-01-21 1:19 ` 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.