Release 4.11 net/ipv6/netfilter.c
/*
* IPv6 specific functions of netfilter core
*
* Rusty Russell (C) 2000 -- This code is GPL.
* Patrick McHardy (C) 2006-2012
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/ipv6.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv6.h>
#include <linux/export.h>
#include <net/addrconf.h>
#include <net/dst.h>
#include <net/ipv6.h>
#include <net/ip6_route.h>
#include <net/xfrm.h>
#include <net/ip6_checksum.h>
#include <net/netfilter/nf_queue.h>
int ip6_route_me_harder(struct net *net, struct sk_buff *skb)
{
const struct ipv6hdr *iph = ipv6_hdr(skb);
unsigned int hh_len;
struct dst_entry *dst;
struct flowi6 fl6 = {
.flowi6_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0,
.flowi6_mark = skb->mark,
.flowi6_uid = sock_net_uid(net, skb->sk),
.daddr = iph->daddr,
.saddr = iph->saddr,
};
int err;
dst = ip6_route_output(net, skb->sk, &fl6);
err = dst->error;
if (err) {
IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
net_dbg_ratelimited("ip6_route_me_harder: No more route\n");
dst_release(dst);
return err;
}
/* Drop old route. */
skb_dst_drop(skb);
skb_dst_set(skb, dst);
#ifdef CONFIG_XFRM
if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
xfrm_decode_session(skb, flowi6_to_flowi(&fl6), AF_INET6) == 0) {
skb_dst_set(skb, NULL);
dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), skb->sk, 0);
if (IS_ERR(dst))
return PTR_ERR(dst);
skb_dst_set(skb, dst);
}
#endif
/* Change in oif may mean change in hh_len. */
hh_len = skb_dst(skb)->dev->hard_header_len;
if (skb_headroom(skb) < hh_len &&
pskb_expand_head(skb, HH_DATA_ALIGN(hh_len - skb_headroom(skb)),
0, GFP_ATOMIC))
return -ENOMEM;
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Patrick McHardy | 96 | 33.45% | 3 | 16.67% |
Harald Welte | 65 | 22.65% | 1 | 5.56% |
Ulrich Weber | 47 | 16.38% | 1 | 5.56% |
David S. Miller | 24 | 8.36% | 2 | 11.11% |
Lorenzo Colitti | 12 | 4.18% | 1 | 5.56% |
Eric Dumazet | 12 | 4.18% | 2 | 11.11% |
Sergey Popovich | 10 | 3.48% | 1 | 5.56% |
Yasuyuki Kozakai | 6 | 2.09% | 1 | 5.56% |
Eric W. Biedermann | 5 | 1.74% | 1 | 5.56% |
Alexey Dobriyan | 4 | 1.39% | 2 | 11.11% |
Arnaldo Carvalho de Melo | 3 | 1.05% | 1 | 5.56% |
Joe Perches | 2 | 0.70% | 1 | 5.56% |
Daniel Lezcano | 1 | 0.35% | 1 | 5.56% |
Total | 287 | 100.00% | 18 | 100.00% |
EXPORT_SYMBOL(ip6_route_me_harder);
/*
* Extra routing may needed on local out, as the QUEUE target never
* returns control to the table.
*/
struct ip6_rt_info {
struct in6_addr daddr;
struct in6_addr saddr;
u_int32_t mark;
};
static void nf_ip6_saveroute(const struct sk_buff *skb,
struct nf_queue_entry *entry)
{
struct ip6_rt_info *rt_info = nf_queue_entry_reroute(entry);
if (entry->state.hook == NF_INET_LOCAL_OUT) {
const struct ipv6hdr *iph = ipv6_hdr(skb);
rt_info->daddr = iph->daddr;
rt_info->saddr = iph->saddr;
rt_info->mark = skb->mark;
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Harald Welte | 53 | 71.62% | 1 | 12.50% |
Eric Leblond | 8 | 10.81% | 1 | 12.50% |
Patrick McHardy | 7 | 9.46% | 3 | 37.50% |
Arnaldo Carvalho de Melo | 3 | 4.05% | 1 | 12.50% |
David S. Miller | 2 | 2.70% | 1 | 12.50% |
Eric Dumazet | 1 | 1.35% | 1 | 12.50% |
Total | 74 | 100.00% | 8 | 100.00% |
static int nf_ip6_reroute(struct net *net, struct sk_buff *skb,
const struct nf_queue_entry *entry)
{
struct ip6_rt_info *rt_info = nf_queue_entry_reroute(entry);
if (entry->state.hook == NF_INET_LOCAL_OUT) {
const struct ipv6hdr *iph = ipv6_hdr(skb);
if (!ipv6_addr_equal(&iph->daddr, &rt_info->daddr) ||
!ipv6_addr_equal(&iph->saddr, &rt_info->saddr) ||
skb->mark != rt_info->mark)
return ip6_route_me_harder(net, skb);
}
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Harald Welte | 73 | 70.19% | 1 | 9.09% |
Eric Leblond | 8 | 7.69% | 1 | 9.09% |
Eric W. Biedermann | 7 | 6.73% | 2 | 18.18% |
Patrick McHardy | 7 | 6.73% | 3 | 27.27% |
Herbert Xu | 3 | 2.88% | 1 | 9.09% |
Arnaldo Carvalho de Melo | 3 | 2.88% | 1 | 9.09% |
David S. Miller | 2 | 1.92% | 1 | 9.09% |
Eric Dumazet | 1 | 0.96% | 1 | 9.09% |
Total | 104 | 100.00% | 11 | 100.00% |
static int nf_ip6_route(struct net *net, struct dst_entry **dst,
struct flowi *fl, bool strict)
{
static const struct ipv6_pinfo fake_pinfo;
static const struct inet_sock fake_sk = {
/* makes ip6_route_output set RT6_LOOKUP_F_IFACE: */
.sk.sk_bound_dev_if = 1,
.pinet6 = (struct ipv6_pinfo *) &fake_pinfo,
};
const void *sk = strict ? &fake_sk : NULL;
struct dst_entry *result;
int err;
result = ip6_route_output(net, sk, &fl->u.ip6);
err = result->error;
if (err)
dst_release(result);
else
*dst = result;
return err;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Florian Westphal | 85 | 72.03% | 3 | 50.00% |
Patrick McHardy | 27 | 22.88% | 1 | 16.67% |
David S. Miller | 5 | 4.24% | 1 | 16.67% |
Daniel Lezcano | 1 | 0.85% | 1 | 16.67% |
Total | 118 | 100.00% | 6 | 100.00% |
__sum16 nf_ip6_checksum(struct sk_buff *skb, unsigned int hook,
unsigned int dataoff, u_int8_t protocol)
{
const struct ipv6hdr *ip6h = ipv6_hdr(skb);
__sum16 csum = 0;
switch (skb->ip_summed) {
case CHECKSUM_COMPLETE:
if (hook != NF_INET_PRE_ROUTING && hook != NF_INET_LOCAL_IN)
break;
if (!csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr,
skb->len - dataoff, protocol,
csum_sub(skb->csum,
skb_checksum(skb, 0,
dataoff, 0)))) {
skb->ip_summed = CHECKSUM_UNNECESSARY;
break;
}
/* fall through */
case CHECKSUM_NONE:
skb->csum = ~csum_unfold(
csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr,
skb->len - dataoff,
protocol,
csum_sub(0,
skb_checksum(skb, 0,
dataoff, 0))));
csum = __skb_checksum_complete(skb);
}
return csum;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Patrick McHardy | 160 | 94.67% | 3 | 42.86% |
Al Viro | 5 | 2.96% | 2 | 28.57% |
Arnaldo Carvalho de Melo | 3 | 1.78% | 1 | 14.29% |
Eric Dumazet | 1 | 0.59% | 1 | 14.29% |
Total | 169 | 100.00% | 7 | 100.00% |
EXPORT_SYMBOL(nf_ip6_checksum);
static __sum16 nf_ip6_checksum_partial(struct sk_buff *skb, unsigned int hook,
unsigned int dataoff, unsigned int len,
u_int8_t protocol)
{
const struct ipv6hdr *ip6h = ipv6_hdr(skb);
__wsum hsum;
__sum16 csum = 0;
switch (skb->ip_summed) {
case CHECKSUM_COMPLETE:
if (len == skb->len - dataoff)
return nf_ip6_checksum(skb, hook, dataoff, protocol);
/* fall through */
case CHECKSUM_NONE:
hsum = skb_checksum(skb, 0, dataoff, 0);
skb->csum = ~csum_unfold(csum_ipv6_magic(&ip6h->saddr,
&ip6h->daddr,
skb->len - dataoff,
protocol,
csum_sub(0, hsum)));
skb->ip_summed = CHECKSUM_NONE;
return __skb_checksum_complete_head(skb, dataoff + len);
}
return csum;
}Contributors
Person | Tokens | Prop | Commits | CommitProp |
Patrick McHardy | 147 | 98.00% | 1 | 33.33% |
Shan Wei | 2 | 1.33% | 1 | 33.33% |
Eric Dumazet | 1 | 0.67% | 1 | 33.33% |
Total | 150 | 100.00% | 3 | 100.00% |
;
static const struct nf_ipv6_ops ipv6ops = {
.chk_addr = ipv6_chk_addr,
.route_input = ip6_route_input,
.fragment = ip6_fragment
};
static const struct nf_afinfo nf_ip6_afinfo = {
.family = AF_INET6,
.checksum = nf_ip6_checksum,
.checksum_partial = nf_ip6_checksum_partial,
.route = nf_ip6_route,
.saveroute = nf_ip6_saveroute,
.reroute = nf_ip6_reroute,
.route_key_size = sizeof(struct ip6_rt_info),
};
int __init ipv6_netfilter_init(void)
{
RCU_INIT_POINTER(nf_ipv6_ops, &ipv6ops);
return nf_register_afinfo(&nf_ip6_afinfo);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Harald Welte | 13 | 56.52% | 1 | 33.33% |
Florian Westphal | 8 | 34.78% | 1 | 33.33% |
Patrick McHardy | 2 | 8.70% | 1 | 33.33% |
Total | 23 | 100.00% | 3 | 100.00% |
/* This can be called from inet6_init() on errors, so it cannot
* be marked __exit. -DaveM
*/
void ipv6_netfilter_fini(void)
{
RCU_INIT_POINTER(nf_ipv6_ops, NULL);
nf_unregister_afinfo(&nf_ip6_afinfo);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Harald Welte | 10 | 50.00% | 1 | 33.33% |
Florian Westphal | 7 | 35.00% | 1 | 33.33% |
Patrick McHardy | 3 | 15.00% | 1 | 33.33% |
Total | 20 | 100.00% | 3 | 100.00% |
Overall Contributors
Person | Tokens | Prop | Commits | CommitProp |
Patrick McHardy | 495 | 45.66% | 14 | 30.43% |
Harald Welte | 272 | 25.09% | 2 | 4.35% |
Florian Westphal | 115 | 10.61% | 4 | 8.70% |
Ulrich Weber | 47 | 4.34% | 1 | 2.17% |
David S. Miller | 34 | 3.14% | 4 | 8.70% |
Eric Leblond | 19 | 1.75% | 1 | 2.17% |
Eric Dumazet | 16 | 1.48% | 2 | 4.35% |
Arnaldo Carvalho de Melo | 12 | 1.11% | 1 | 2.17% |
Eric W. Biedermann | 12 | 1.11% | 2 | 4.35% |
Lorenzo Colitti | 12 | 1.11% | 1 | 2.17% |
Bernhard Thaler | 11 | 1.01% | 2 | 4.35% |
Sergey Popovich | 10 | 0.92% | 1 | 2.17% |
Yasuyuki Kozakai | 6 | 0.55% | 1 | 2.17% |
Al Viro | 5 | 0.46% | 2 | 4.35% |
Alexey Dobriyan | 4 | 0.37% | 2 | 4.35% |
Herbert Xu | 3 | 0.28% | 1 | 2.17% |
Brian Haley | 3 | 0.28% | 1 | 2.17% |
Shan Wei | 2 | 0.18% | 1 | 2.17% |
Daniel Lezcano | 2 | 0.18% | 1 | 2.17% |
Paul Gortmaker | 2 | 0.18% | 1 | 2.17% |
Joe Perches | 2 | 0.18% | 1 | 2.17% |
Total | 1084 | 100.00% | 46 | 100.00% |
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.