Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
#include <linux/capability.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/skbuff.h>
|
||||
@@ -222,16 +222,11 @@ get_entry(void *base, unsigned int offset)
|
||||
|
||||
/* All zeroes == unconditional rule. */
|
||||
/* Mildly perf critical (only if packet tracing is on) */
|
||||
static inline int
|
||||
unconditional(const struct ip6t_ip6 *ipv6)
|
||||
static inline bool unconditional(const struct ip6t_ip6 *ipv6)
|
||||
{
|
||||
unsigned int i;
|
||||
static const struct ip6t_ip6 uncond;
|
||||
|
||||
for (i = 0; i < sizeof(*ipv6); i++)
|
||||
if (((char *)ipv6)[i])
|
||||
break;
|
||||
|
||||
return (i == sizeof(*ipv6));
|
||||
return memcmp(ipv6, &uncond, sizeof(uncond)) == 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
|
||||
@@ -745,6 +740,21 @@ find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool check_underflow(struct ip6t_entry *e)
|
||||
{
|
||||
const struct ip6t_entry_target *t;
|
||||
unsigned int verdict;
|
||||
|
||||
if (!unconditional(&e->ipv6))
|
||||
return false;
|
||||
t = ip6t_get_target(e);
|
||||
if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0)
|
||||
return false;
|
||||
verdict = ((struct ip6t_standard_target *)t)->verdict;
|
||||
verdict = -verdict - 1;
|
||||
return verdict == NF_DROP || verdict == NF_ACCEPT;
|
||||
}
|
||||
|
||||
static int
|
||||
check_entry_size_and_hooks(struct ip6t_entry *e,
|
||||
struct xt_table_info *newinfo,
|
||||
@@ -752,6 +762,7 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
|
||||
unsigned char *limit,
|
||||
const unsigned int *hook_entries,
|
||||
const unsigned int *underflows,
|
||||
unsigned int valid_hooks,
|
||||
unsigned int *i)
|
||||
{
|
||||
unsigned int h;
|
||||
@@ -771,15 +782,21 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
|
||||
|
||||
/* Check hooks & underflows */
|
||||
for (h = 0; h < NF_INET_NUMHOOKS; h++) {
|
||||
if (!(valid_hooks & (1 << h)))
|
||||
continue;
|
||||
if ((unsigned char *)e - base == hook_entries[h])
|
||||
newinfo->hook_entry[h] = hook_entries[h];
|
||||
if ((unsigned char *)e - base == underflows[h])
|
||||
if ((unsigned char *)e - base == underflows[h]) {
|
||||
if (!check_underflow(e)) {
|
||||
pr_err("Underflows must be unconditional and "
|
||||
"use the STANDARD target with "
|
||||
"ACCEPT/DROP\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
newinfo->underflow[h] = underflows[h];
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: underflows must be unconditional, standard verdicts
|
||||
< 0 (not IP6T_RETURN). --RR */
|
||||
|
||||
/* Clear counters and comefrom */
|
||||
e->counters = ((struct xt_counters) { 0, 0 });
|
||||
e->comefrom = 0;
|
||||
@@ -842,7 +859,7 @@ translate_table(const char *name,
|
||||
newinfo,
|
||||
entry0,
|
||||
entry0 + size,
|
||||
hook_entries, underflows, &i);
|
||||
hook_entries, underflows, valid_hooks, &i);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
@@ -2083,7 +2100,8 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct xt_table *ip6t_register_table(struct net *net, struct xt_table *table,
|
||||
struct xt_table *ip6t_register_table(struct net *net,
|
||||
const struct xt_table *table,
|
||||
const struct ip6t_replace *repl)
|
||||
{
|
||||
int ret;
|
||||
|
@@ -23,7 +23,6 @@ static bool
|
||||
eui64_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
|
||||
{
|
||||
unsigned char eui64[8];
|
||||
int i = 0;
|
||||
|
||||
if (!(skb_mac_header(skb) >= skb->head &&
|
||||
skb_mac_header(skb) + ETH_HLEN <= skb->data) &&
|
||||
@@ -42,12 +41,8 @@ eui64_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
|
||||
eui64[4] = 0xfe;
|
||||
eui64[0] ^= 0x02;
|
||||
|
||||
i = 0;
|
||||
while (ipv6_hdr(skb)->saddr.s6_addr[8 + i] == eui64[i]
|
||||
&& i < 8)
|
||||
i++;
|
||||
|
||||
if (i == 8)
|
||||
if (!memcmp(ipv6_hdr(skb)->saddr.s6_addr + 8, eui64,
|
||||
sizeof(eui64)))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@@ -51,11 +51,11 @@ static struct
|
||||
.term = IP6T_ERROR_INIT, /* ERROR */
|
||||
};
|
||||
|
||||
static struct xt_table packet_filter = {
|
||||
static const struct xt_table packet_filter = {
|
||||
.name = "filter",
|
||||
.valid_hooks = FILTER_VALID_HOOKS,
|
||||
.me = THIS_MODULE,
|
||||
.af = AF_INET6,
|
||||
.af = NFPROTO_IPV6,
|
||||
};
|
||||
|
||||
/* The work comes in here from netfilter.c. */
|
||||
@@ -95,21 +95,21 @@ static struct nf_hook_ops ip6t_ops[] __read_mostly = {
|
||||
{
|
||||
.hook = ip6t_in_hook,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET6,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_LOCAL_IN,
|
||||
.priority = NF_IP6_PRI_FILTER,
|
||||
},
|
||||
{
|
||||
.hook = ip6t_in_hook,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET6,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_FORWARD,
|
||||
.priority = NF_IP6_PRI_FILTER,
|
||||
},
|
||||
{
|
||||
.hook = ip6t_local_out_hook,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET6,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_LOCAL_OUT,
|
||||
.priority = NF_IP6_PRI_FILTER,
|
||||
},
|
||||
|
@@ -21,7 +21,7 @@ MODULE_DESCRIPTION("ip6tables mangle table");
|
||||
(1 << NF_INET_LOCAL_OUT) | \
|
||||
(1 << NF_INET_POST_ROUTING))
|
||||
|
||||
static struct
|
||||
static const struct
|
||||
{
|
||||
struct ip6t_replace repl;
|
||||
struct ip6t_standard entries[5];
|
||||
@@ -57,11 +57,11 @@ static struct
|
||||
.term = IP6T_ERROR_INIT, /* ERROR */
|
||||
};
|
||||
|
||||
static struct xt_table packet_mangler = {
|
||||
static const struct xt_table packet_mangler = {
|
||||
.name = "mangle",
|
||||
.valid_hooks = MANGLE_VALID_HOOKS,
|
||||
.me = THIS_MODULE,
|
||||
.af = AF_INET6,
|
||||
.af = NFPROTO_IPV6,
|
||||
};
|
||||
|
||||
/* The work comes in here from netfilter.c. */
|
||||
@@ -136,35 +136,35 @@ static struct nf_hook_ops ip6t_ops[] __read_mostly = {
|
||||
{
|
||||
.hook = ip6t_in_hook,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET6,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_PRE_ROUTING,
|
||||
.priority = NF_IP6_PRI_MANGLE,
|
||||
},
|
||||
{
|
||||
.hook = ip6t_in_hook,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET6,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_LOCAL_IN,
|
||||
.priority = NF_IP6_PRI_MANGLE,
|
||||
},
|
||||
{
|
||||
.hook = ip6t_in_hook,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET6,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_FORWARD,
|
||||
.priority = NF_IP6_PRI_MANGLE,
|
||||
},
|
||||
{
|
||||
.hook = ip6t_local_out_hook,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET6,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_LOCAL_OUT,
|
||||
.priority = NF_IP6_PRI_MANGLE,
|
||||
},
|
||||
{
|
||||
.hook = ip6t_post_routing_hook,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET6,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_POST_ROUTING,
|
||||
.priority = NF_IP6_PRI_MANGLE,
|
||||
},
|
||||
|
@@ -8,7 +8,7 @@
|
||||
|
||||
#define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT))
|
||||
|
||||
static struct
|
||||
static const struct
|
||||
{
|
||||
struct ip6t_replace repl;
|
||||
struct ip6t_standard entries[2];
|
||||
@@ -35,11 +35,11 @@ static struct
|
||||
.term = IP6T_ERROR_INIT, /* ERROR */
|
||||
};
|
||||
|
||||
static struct xt_table packet_raw = {
|
||||
static const struct xt_table packet_raw = {
|
||||
.name = "raw",
|
||||
.valid_hooks = RAW_VALID_HOOKS,
|
||||
.me = THIS_MODULE,
|
||||
.af = AF_INET6,
|
||||
.af = NFPROTO_IPV6,
|
||||
};
|
||||
|
||||
/* The work comes in here from netfilter.c. */
|
||||
@@ -68,14 +68,14 @@ ip6t_local_out_hook(unsigned int hook,
|
||||
static struct nf_hook_ops ip6t_ops[] __read_mostly = {
|
||||
{
|
||||
.hook = ip6t_pre_routing_hook,
|
||||
.pf = PF_INET6,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_PRE_ROUTING,
|
||||
.priority = NF_IP6_PRI_FIRST,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
{
|
||||
.hook = ip6t_local_out_hook,
|
||||
.pf = PF_INET6,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_LOCAL_OUT,
|
||||
.priority = NF_IP6_PRI_FIRST,
|
||||
.owner = THIS_MODULE,
|
||||
|
@@ -26,7 +26,7 @@ MODULE_DESCRIPTION("ip6tables security table, for MAC rules");
|
||||
(1 << NF_INET_FORWARD) | \
|
||||
(1 << NF_INET_LOCAL_OUT)
|
||||
|
||||
static struct
|
||||
static const struct
|
||||
{
|
||||
struct ip6t_replace repl;
|
||||
struct ip6t_standard entries[3];
|
||||
@@ -56,11 +56,11 @@ static struct
|
||||
.term = IP6T_ERROR_INIT, /* ERROR */
|
||||
};
|
||||
|
||||
static struct xt_table security_table = {
|
||||
static const struct xt_table security_table = {
|
||||
.name = "security",
|
||||
.valid_hooks = SECURITY_VALID_HOOKS,
|
||||
.me = THIS_MODULE,
|
||||
.af = AF_INET6,
|
||||
.af = NFPROTO_IPV6,
|
||||
};
|
||||
|
||||
static unsigned int
|
||||
@@ -101,21 +101,21 @@ static struct nf_hook_ops ip6t_ops[] __read_mostly = {
|
||||
{
|
||||
.hook = ip6t_local_in_hook,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET6,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_LOCAL_IN,
|
||||
.priority = NF_IP6_PRI_SECURITY,
|
||||
},
|
||||
{
|
||||
.hook = ip6t_forward_hook,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET6,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_FORWARD,
|
||||
.priority = NF_IP6_PRI_SECURITY,
|
||||
},
|
||||
{
|
||||
.hook = ip6t_local_out_hook,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET6,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_LOCAL_OUT,
|
||||
.priority = NF_IP6_PRI_SECURITY,
|
||||
},
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#include <net/netfilter/nf_conntrack_l3proto.h>
|
||||
#include <net/netfilter/nf_conntrack_core.h>
|
||||
#include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
|
||||
#include <net/netfilter/nf_log.h>
|
||||
|
||||
static bool ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
|
||||
struct nf_conntrack_tuple *tuple)
|
||||
@@ -176,8 +177,11 @@ static unsigned int ipv6_confirm(unsigned int hooknum,
|
||||
}
|
||||
|
||||
ret = helper->help(skb, protoff, ct, ctinfo);
|
||||
if (ret != NF_ACCEPT)
|
||||
if (ret != NF_ACCEPT) {
|
||||
nf_log_packet(NFPROTO_IPV6, hooknum, skb, in, out, NULL,
|
||||
"nf_ct_%s: dropping packet", helper->name);
|
||||
return ret;
|
||||
}
|
||||
out:
|
||||
/* We've seen it coming out the other side: confirm it */
|
||||
return nf_conntrack_confirm(skb);
|
||||
@@ -265,42 +269,42 @@ static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = {
|
||||
{
|
||||
.hook = ipv6_defrag,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET6,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_PRE_ROUTING,
|
||||
.priority = NF_IP6_PRI_CONNTRACK_DEFRAG,
|
||||
},
|
||||
{
|
||||
.hook = ipv6_conntrack_in,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET6,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_PRE_ROUTING,
|
||||
.priority = NF_IP6_PRI_CONNTRACK,
|
||||
},
|
||||
{
|
||||
.hook = ipv6_conntrack_local,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET6,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_LOCAL_OUT,
|
||||
.priority = NF_IP6_PRI_CONNTRACK,
|
||||
},
|
||||
{
|
||||
.hook = ipv6_defrag,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET6,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_LOCAL_OUT,
|
||||
.priority = NF_IP6_PRI_CONNTRACK_DEFRAG,
|
||||
},
|
||||
{
|
||||
.hook = ipv6_confirm,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET6,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_POST_ROUTING,
|
||||
.priority = NF_IP6_PRI_LAST,
|
||||
},
|
||||
{
|
||||
.hook = ipv6_confirm,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET6,
|
||||
.pf = NFPROTO_IPV6,
|
||||
.hooknum = NF_INET_LOCAL_IN,
|
||||
.priority = NF_IP6_PRI_LAST-1,
|
||||
},
|
||||
|
Reference in New Issue
Block a user