Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 58975
b: refs/heads/master
c: ba9dda3
h: refs/heads/master
i:
  58973: 8a47642
  58971: 6a89004
  58967: f2ce8d8
  58959: 7dba3fc
  58943: 2d201ea
v: v3
  • Loading branch information
Jozsef Kadlecsik authored and David S. Miller committed Jul 11, 2007
1 parent 0c7aaaf commit f6bbea9
Show file tree
Hide file tree
Showing 10 changed files with 315 additions and 28 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1b50b8a371e90a5e110f466e4ac02cf6b5f681de
refs/heads/master: ba9dda3ab5a865542e69dfe01edb2436857c9420
4 changes: 3 additions & 1 deletion trunk/include/linux/skbuff.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ typedef unsigned char *sk_buff_data_t;
* @mark: Generic packet mark
* @nfct: Associated connection, if any
* @ipvs_property: skbuff is owned by ipvs
* @nf_trace: netfilter packet trace flag
* @nfctinfo: Relationship of this skb to the connection
* @nfct_reasm: netfilter conntrack re-assembly pointer
* @nf_bridge: Saved data about a bridged frame - see br_netfilter.c
Expand Down Expand Up @@ -278,7 +279,8 @@ struct sk_buff {
nfctinfo:3;
__u8 pkt_type:3,
fclone:2,
ipvs_property:1;
ipvs_property:1,
nf_trace:1;
__be16 protocol;

void (*destructor)(struct sk_buff *skb);
Expand Down
8 changes: 8 additions & 0 deletions trunk/net/core/skbuff.c
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,10 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
n->destructor = NULL;
C(mark);
__nf_copy(n, skb);
#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
C(nf_trace);
#endif
#ifdef CONFIG_NET_SCHED
C(tc_index);
#ifdef CONFIG_NET_CLS_ACT
Expand Down Expand Up @@ -485,6 +489,10 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
new->destructor = NULL;
new->mark = old->mark;
__nf_copy(new, old);
#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
new->nf_trace = old->nf_trace;
#endif
#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
new->ipvs_property = old->ipvs_property;
#endif
Expand Down
4 changes: 4 additions & 0 deletions trunk/net/ipv4/ip_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,10 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from)
to->tc_index = from->tc_index;
#endif
nf_copy(to, from);
#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
to->nf_trace = from->nf_trace;
#endif
#if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
to->ipvs_property = from->ipvs_property;
#endif
Expand Down
127 changes: 114 additions & 13 deletions trunk/net/ipv4/netfilter/ip_tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,112 @@ get_entry(void *base, unsigned int offset)
return (struct ipt_entry *)(base + offset);
}

/* All zeroes == unconditional rule. */
static inline int
unconditional(const struct ipt_ip *ip)
{
unsigned int i;

for (i = 0; i < sizeof(*ip)/sizeof(__u32); i++)
if (((__u32 *)ip)[i])
return 0;

return 1;
}

#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
static const char *hooknames[] = {
[NF_IP_PRE_ROUTING] = "PREROUTING",
[NF_IP_LOCAL_IN] = "INPUT",
[NF_IP_FORWARD] = "FORWARD",
[NF_IP_LOCAL_OUT] = "OUTPUT",
[NF_IP_POST_ROUTING] = "POSTROUTING",
};

enum nf_ip_trace_comments {
NF_IP_TRACE_COMMENT_RULE,
NF_IP_TRACE_COMMENT_RETURN,
NF_IP_TRACE_COMMENT_POLICY,
};

static const char *comments[] = {
[NF_IP_TRACE_COMMENT_RULE] = "rule",
[NF_IP_TRACE_COMMENT_RETURN] = "return",
[NF_IP_TRACE_COMMENT_POLICY] = "policy",
};

static struct nf_loginfo trace_loginfo = {
.type = NF_LOG_TYPE_LOG,
.u = {
.log = {
.level = 4,
.logflags = NF_LOG_MASK,
},
},
};

static inline int
get_chainname_rulenum(struct ipt_entry *s, struct ipt_entry *e,
char *hookname, char **chainname,
char **comment, unsigned int *rulenum)
{
struct ipt_standard_target *t = (void *)ipt_get_target(s);

if (strcmp(t->target.u.kernel.target->name, IPT_ERROR_TARGET) == 0) {
/* Head of user chain: ERROR target with chainname */
*chainname = t->target.data;
(*rulenum) = 0;
} else if (s == e) {
(*rulenum)++;

if (s->target_offset == sizeof(struct ipt_entry)
&& strcmp(t->target.u.kernel.target->name,
IPT_STANDARD_TARGET) == 0
&& t->verdict < 0
&& unconditional(&s->ip)) {
/* Tail of chains: STANDARD target (return/policy) */
*comment = *chainname == hookname
? (char *)comments[NF_IP_TRACE_COMMENT_POLICY]
: (char *)comments[NF_IP_TRACE_COMMENT_RETURN];
}
return 1;
} else
(*rulenum)++;

return 0;
}

static void trace_packet(struct sk_buff *skb,
unsigned int hook,
const struct net_device *in,
const struct net_device *out,
char *tablename,
struct xt_table_info *private,
struct ipt_entry *e)
{
void *table_base;
struct ipt_entry *root;
char *hookname, *chainname, *comment;
unsigned int rulenum = 0;

table_base = (void *)private->entries[smp_processor_id()];
root = get_entry(table_base, private->hook_entry[hook]);

hookname = chainname = (char *)hooknames[hook];
comment = (char *)comments[NF_IP_TRACE_COMMENT_RULE];

IPT_ENTRY_ITERATE(root,
private->size - private->hook_entry[hook],
get_chainname_rulenum,
e, hookname, &chainname, &comment, &rulenum);

nf_log_packet(AF_INET, hook, skb, in, out, &trace_loginfo,
"TRACE: %s:%s:%s:%u ",
tablename, chainname, comment, rulenum);
}
#endif

/* Returns one of the generic firewall policies, like NF_ACCEPT. */
unsigned int
ipt_do_table(struct sk_buff **pskb,
Expand Down Expand Up @@ -261,6 +367,14 @@ ipt_do_table(struct sk_buff **pskb,

t = ipt_get_target(e);
IP_NF_ASSERT(t->u.kernel.target);

#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
/* The packet is traced: log it */
if (unlikely((*pskb)->nf_trace))
trace_packet(*pskb, hook, in, out,
table->name, private, e);
#endif
/* Standard target? */
if (!t->u.kernel.target->target) {
int v;
Expand Down Expand Up @@ -341,19 +455,6 @@ ipt_do_table(struct sk_buff **pskb,
#endif
}

/* All zeroes == unconditional rule. */
static inline int
unconditional(const struct ipt_ip *ip)
{
unsigned int i;

for (i = 0; i < sizeof(*ip)/sizeof(__u32); i++)
if (((__u32 *)ip)[i])
return 0;

return 1;
}

/* Figures out from what hook each rule can be called: returns 0 if
there are loops. Puts hook bitmask in comefrom. */
static int
Expand Down
4 changes: 4 additions & 0 deletions trunk/net/ipv6/ip6_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,10 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from)
to->tc_index = from->tc_index;
#endif
nf_copy(to, from);
#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
to->nf_trace = from->nf_trace;
#endif
skb_copy_secmark(to, from);
}

Expand Down
128 changes: 115 additions & 13 deletions trunk/net/ipv6/netfilter/ip6_tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,113 @@ get_entry(void *base, unsigned int offset)
return (struct ip6t_entry *)(base + offset);
}

/* All zeroes == unconditional rule. */
static inline int
unconditional(const struct ip6t_ip6 *ipv6)
{
unsigned int i;

for (i = 0; i < sizeof(*ipv6); i++)
if (((char *)ipv6)[i])
break;

return (i == sizeof(*ipv6));
}

#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
/* This cries for unification! */
static const char *hooknames[] = {
[NF_IP6_PRE_ROUTING] = "PREROUTING",
[NF_IP6_LOCAL_IN] = "INPUT",
[NF_IP6_FORWARD] = "FORWARD",
[NF_IP6_LOCAL_OUT] = "OUTPUT",
[NF_IP6_POST_ROUTING] = "POSTROUTING",
};

enum nf_ip_trace_comments {
NF_IP6_TRACE_COMMENT_RULE,
NF_IP6_TRACE_COMMENT_RETURN,
NF_IP6_TRACE_COMMENT_POLICY,
};

static const char *comments[] = {
[NF_IP6_TRACE_COMMENT_RULE] = "rule",
[NF_IP6_TRACE_COMMENT_RETURN] = "return",
[NF_IP6_TRACE_COMMENT_POLICY] = "policy",
};

static struct nf_loginfo trace_loginfo = {
.type = NF_LOG_TYPE_LOG,
.u = {
.log = {
.level = 4,
.logflags = NF_LOG_MASK,
},
},
};

static inline int
get_chainname_rulenum(struct ip6t_entry *s, struct ip6t_entry *e,
char *hookname, char **chainname,
char **comment, unsigned int *rulenum)
{
struct ip6t_standard_target *t = (void *)ip6t_get_target(s);

if (strcmp(t->target.u.kernel.target->name, IP6T_ERROR_TARGET) == 0) {
/* Head of user chain: ERROR target with chainname */
*chainname = t->target.data;
(*rulenum) = 0;
} else if (s == e) {
(*rulenum)++;

if (s->target_offset == sizeof(struct ip6t_entry)
&& strcmp(t->target.u.kernel.target->name,
IP6T_STANDARD_TARGET) == 0
&& t->verdict < 0
&& unconditional(&s->ipv6)) {
/* Tail of chains: STANDARD target (return/policy) */
*comment = *chainname == hookname
? (char *)comments[NF_IP6_TRACE_COMMENT_POLICY]
: (char *)comments[NF_IP6_TRACE_COMMENT_RETURN];
}
return 1;
} else
(*rulenum)++;

return 0;
}

static void trace_packet(struct sk_buff *skb,
unsigned int hook,
const struct net_device *in,
const struct net_device *out,
char *tablename,
struct xt_table_info *private,
struct ip6t_entry *e)
{
void *table_base;
struct ip6t_entry *root;
char *hookname, *chainname, *comment;
unsigned int rulenum = 0;

table_base = (void *)private->entries[smp_processor_id()];
root = get_entry(table_base, private->hook_entry[hook]);

hookname = chainname = (char *)hooknames[hook];
comment = (char *)comments[NF_IP6_TRACE_COMMENT_RULE];

IP6T_ENTRY_ITERATE(root,
private->size - private->hook_entry[hook],
get_chainname_rulenum,
e, hookname, &chainname, &comment, &rulenum);

nf_log_packet(AF_INET6, hook, skb, in, out, &trace_loginfo,
"TRACE: %s:%s:%s:%u ",
tablename, chainname, comment, rulenum);
}
#endif

/* Returns one of the generic firewall policies, like NF_ACCEPT. */
unsigned int
ip6t_do_table(struct sk_buff **pskb,
Expand Down Expand Up @@ -298,6 +405,14 @@ ip6t_do_table(struct sk_buff **pskb,

t = ip6t_get_target(e);
IP_NF_ASSERT(t->u.kernel.target);

#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
/* The packet is traced: log it */
if (unlikely((*pskb)->nf_trace))
trace_packet(*pskb, hook, in, out,
table->name, private, e);
#endif
/* Standard target? */
if (!t->u.kernel.target->target) {
int v;
Expand Down Expand Up @@ -377,19 +492,6 @@ ip6t_do_table(struct sk_buff **pskb,
#endif
}

/* All zeroes == unconditional rule. */
static inline int
unconditional(const struct ip6t_ip6 *ipv6)
{
unsigned int i;

for (i = 0; i < sizeof(*ipv6); i++)
if (((char *)ipv6)[i])
break;

return (i == sizeof(*ipv6));
}

/* Figures out from what hook each rule can be called: returns 0 if
there are loops. Puts hook bitmask in comefrom. */
static int
Expand Down
12 changes: 12 additions & 0 deletions trunk/net/netfilter/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,18 @@ config NETFILTER_XT_TARGET_NOTRACK
If you want to compile it as a module, say M here and read
<file:Documentation/kbuild/modules.txt>. If unsure, say `N'.

config NETFILTER_XT_TARGET_TRACE
tristate '"TRACE" target support'
depends on NETFILTER_XTABLES
depends on IP_NF_RAW || IP6_NF_RAW
help
The TRACE target allows you to mark packets so that the kernel
will log every rule which match the packets as those traverse
the tables, chains, rules.

If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>. If unsure, say `N'.

config NETFILTER_XT_TARGET_SECMARK
tristate '"SECMARK" target support'
depends on NETFILTER_XTABLES && NETWORK_SECMARK
Expand Down
1 change: 1 addition & 0 deletions trunk/net/netfilter/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o
obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o
obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o
obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o
obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o
obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o
obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o
obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o
Expand Down
Loading

0 comments on commit f6bbea9

Please sign in to comment.