[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1325516801-25488-2-git-send-email-hans.schillstrom@ericsson.com>
Date: Mon, 2 Jan 2012 16:06:39 +0100
From: Hans Schillstrom <hans.schillstrom@...csson.com>
To: <kaber@...sh.net>, <pablo@...filter.org>, <jengelh@...ozas.de>,
<netfilter-devel@...r.kernel.org>, <netdev@...r.kernel.org>
CC: <hans@...illstrom.com>,
Hans Schillstrom <hans.schillstrom@...csson.com>
Subject: [v5 PATCH 1/3] NETFILTER added flags to __ipv6_find_hdr()
Two new flags to __ipv6_find_hdr,
One that tells us that this is a fragemnt.
One that stops at AH if any i.e. treat it like a transport header.
i.e. make handling of ESP and AH the same.
Signed-off-by: Hans Schillstrom <hans.schillstrom@...csson.com>
---
include/linux/netfilter_ipv6/ip6_tables.h | 16 ++++++++++++++--
net/ipv6/netfilter/ip6_tables.c | 19 ++++++++++++++-----
2 files changed, 28 insertions(+), 7 deletions(-)
diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h
index f549adc..ee0c68e 100644
--- a/include/linux/netfilter_ipv6/ip6_tables.h
+++ b/include/linux/netfilter_ipv6/ip6_tables.h
@@ -288,9 +288,21 @@ extern unsigned int ip6t_do_table(struct sk_buff *skb,
/* Check for an extension */
extern int ip6t_ext_hdr(u8 nexthdr);
+enum {
+ IP6T_FH_FRAG,
+ IP6T_FH_AUTH,
+ IP6T_FH_F_FRAG = 1 << IP6T_FH_FRAG,
+ IP6T_FH_F_AUTH = 1 << IP6T_FH_AUTH,
+};
/* find specified header and get offset to it */
-extern int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
- int target, unsigned short *fragoff);
+extern int __ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
+ int target, unsigned short *fragoff, int *fragflg);
+
+static inline int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
+ int target, unsigned short *fragoff)
+{
+ return __ipv6_find_hdr(skb, offset, target, fragoff, NULL);
+}
#ifdef CONFIG_COMPAT
#include <net/compat.h>
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 94874b0..8729bff 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -2302,9 +2302,13 @@ static void __exit ip6_tables_fini(void)
* *offset is meaningless and fragment offset is stored in *fragoff if fragoff
* isn't NULL.
*
+ * if flags != NULL AND
+ * it's a fragment the frag flag "IP6T_FH_F_FRAG" will be set
+ * it's an AH header and IP6T_FH_F_AUTH is set and target < 0
+ * stop at AH (i.e. treat is as a transport header)
*/
-int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
- int target, unsigned short *fragoff)
+int __ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
+ int target, unsigned short *fragoff, int *flags)
{
unsigned int start = skb_network_offset(skb) + sizeof(struct ipv6hdr);
u8 nexthdr = ipv6_hdr(skb)->nexthdr;
@@ -2329,6 +2333,9 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
if (nexthdr == NEXTHDR_FRAGMENT) {
unsigned short _frag_off;
__be16 *fp;
+
+ if (flags) /* Indicate that this is a fragment */
+ *flags |= IP6T_FH_F_FRAG;
fp = skb_header_pointer(skb,
start+offsetof(struct frag_hdr,
frag_off),
@@ -2349,9 +2356,11 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
return -ENOENT;
}
hdrlen = 8;
- } else if (nexthdr == NEXTHDR_AUTH)
+ } else if (nexthdr == NEXTHDR_AUTH) {
+ if (flags && (*flags & IP6T_FH_F_AUTH) && (target < 0))
+ break;
hdrlen = (hp->hdrlen + 2) << 2;
- else
+ } else
hdrlen = ipv6_optlen(hp);
nexthdr = hp->nexthdr;
@@ -2367,7 +2376,7 @@ EXPORT_SYMBOL(ip6t_register_table);
EXPORT_SYMBOL(ip6t_unregister_table);
EXPORT_SYMBOL(ip6t_do_table);
EXPORT_SYMBOL(ip6t_ext_hdr);
-EXPORT_SYMBOL(ipv6_find_hdr);
+EXPORT_SYMBOL(__ipv6_find_hdr);
module_init(ip6_tables_init);
module_exit(ip6_tables_fini);
--
1.7.2.3
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists