aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/addrconf.c24
-rw-r--r--net/ipv6/addrconf_core.c19
-rw-r--r--net/ipv6/netfilter/ip6t_rpfilter.c8
-rw-r--r--net/ipv6/reassembly.c12
4 files changed, 39 insertions, 24 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 28b61e89bbb8..d1ab6ab29a55 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -169,8 +169,6 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev,
169static bool ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr, 169static bool ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr,
170 struct net_device *dev); 170 struct net_device *dev);
171 171
172static ATOMIC_NOTIFIER_HEAD(inet6addr_chain);
173
174static struct ipv6_devconf ipv6_devconf __read_mostly = { 172static struct ipv6_devconf ipv6_devconf __read_mostly = {
175 .forwarding = 0, 173 .forwarding = 0,
176 .hop_limit = IPV6_DEFAULT_HOPLIMIT, 174 .hop_limit = IPV6_DEFAULT_HOPLIMIT,
@@ -910,7 +908,7 @@ out2:
910 rcu_read_unlock_bh(); 908 rcu_read_unlock_bh();
911 909
912 if (likely(err == 0)) 910 if (likely(err == 0))
913 atomic_notifier_call_chain(&inet6addr_chain, NETDEV_UP, ifa); 911 inet6addr_notifier_call_chain(NETDEV_UP, ifa);
914 else { 912 else {
915 kfree(ifa); 913 kfree(ifa);
916 ifa = ERR_PTR(err); 914 ifa = ERR_PTR(err);
@@ -1000,7 +998,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
1000 998
1001 ipv6_ifa_notify(RTM_DELADDR, ifp); 999 ipv6_ifa_notify(RTM_DELADDR, ifp);
1002 1000
1003 atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifp); 1001 inet6addr_notifier_call_chain(NETDEV_DOWN, ifp);
1004 1002
1005 /* 1003 /*
1006 * Purge or update corresponding prefix 1004 * Purge or update corresponding prefix
@@ -3087,7 +3085,7 @@ static int addrconf_ifdown(struct net_device *dev, int how)
3087 3085
3088 if (state != INET6_IFADDR_STATE_DEAD) { 3086 if (state != INET6_IFADDR_STATE_DEAD) {
3089 __ipv6_ifa_notify(RTM_DELADDR, ifa); 3087 __ipv6_ifa_notify(RTM_DELADDR, ifa);
3090 atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa); 3088 inet6addr_notifier_call_chain(NETDEV_DOWN, ifa);
3091 } 3089 }
3092 in6_ifa_put(ifa); 3090 in6_ifa_put(ifa);
3093 3091
@@ -5054,22 +5052,6 @@ static struct pernet_operations addrconf_ops = {
5054 .exit = addrconf_exit_net, 5052 .exit = addrconf_exit_net,
5055}; 5053};
5056 5054
5057/*
5058 * Device notifier
5059 */
5060
5061int register_inet6addr_notifier(struct notifier_block *nb)
5062{
5063 return atomic_notifier_chain_register(&inet6addr_chain, nb);
5064}
5065EXPORT_SYMBOL(register_inet6addr_notifier);
5066
5067int unregister_inet6addr_notifier(struct notifier_block *nb)
5068{
5069 return atomic_notifier_chain_unregister(&inet6addr_chain, nb);
5070}
5071EXPORT_SYMBOL(unregister_inet6addr_notifier);
5072
5073static struct rtnl_af_ops inet6_ops = { 5055static struct rtnl_af_ops inet6_ops = {
5074 .family = AF_INET6, 5056 .family = AF_INET6,
5075 .fill_link_af = inet6_fill_link_af, 5057 .fill_link_af = inet6_fill_link_af,
diff --git a/net/ipv6/addrconf_core.c b/net/ipv6/addrconf_core.c
index d051e5f4bf34..72104562c864 100644
--- a/net/ipv6/addrconf_core.c
+++ b/net/ipv6/addrconf_core.c
@@ -78,3 +78,22 @@ int __ipv6_addr_type(const struct in6_addr *addr)
78} 78}
79EXPORT_SYMBOL(__ipv6_addr_type); 79EXPORT_SYMBOL(__ipv6_addr_type);
80 80
81static ATOMIC_NOTIFIER_HEAD(inet6addr_chain);
82
83int register_inet6addr_notifier(struct notifier_block *nb)
84{
85 return atomic_notifier_chain_register(&inet6addr_chain, nb);
86}
87EXPORT_SYMBOL(register_inet6addr_notifier);
88
89int unregister_inet6addr_notifier(struct notifier_block *nb)
90{
91 return atomic_notifier_chain_unregister(&inet6addr_chain, nb);
92}
93EXPORT_SYMBOL(unregister_inet6addr_notifier);
94
95int inet6addr_notifier_call_chain(unsigned long val, void *v)
96{
97 return atomic_notifier_call_chain(&inet6addr_chain, val, v);
98}
99EXPORT_SYMBOL(inet6addr_notifier_call_chain);
diff --git a/net/ipv6/netfilter/ip6t_rpfilter.c b/net/ipv6/netfilter/ip6t_rpfilter.c
index 5060d54199ab..e0983f3648a6 100644
--- a/net/ipv6/netfilter/ip6t_rpfilter.c
+++ b/net/ipv6/netfilter/ip6t_rpfilter.c
@@ -71,6 +71,12 @@ static bool rpfilter_lookup_reverse6(const struct sk_buff *skb,
71 return ret; 71 return ret;
72} 72}
73 73
74static bool rpfilter_is_local(const struct sk_buff *skb)
75{
76 const struct rt6_info *rt = (const void *) skb_dst(skb);
77 return rt && (rt->rt6i_flags & RTF_LOCAL);
78}
79
74static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par) 80static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par)
75{ 81{
76 const struct xt_rpfilter_info *info = par->matchinfo; 82 const struct xt_rpfilter_info *info = par->matchinfo;
@@ -78,7 +84,7 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par)
78 struct ipv6hdr *iph; 84 struct ipv6hdr *iph;
79 bool invert = info->flags & XT_RPFILTER_INVERT; 85 bool invert = info->flags & XT_RPFILTER_INVERT;
80 86
81 if (par->in->flags & IFF_LOOPBACK) 87 if (rpfilter_is_local(skb))
82 return true ^ invert; 88 return true ^ invert;
83 89
84 iph = ipv6_hdr(skb); 90 iph = ipv6_hdr(skb);
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index e6e44cef8db2..790d9f4b8b0b 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -342,9 +342,17 @@ found:
342 } 342 }
343 343
344 if (fq->q.last_in == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) && 344 if (fq->q.last_in == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) &&
345 fq->q.meat == fq->q.len) 345 fq->q.meat == fq->q.len) {
346 return ip6_frag_reasm(fq, prev, dev); 346 int res;
347 unsigned long orefdst = skb->_skb_refdst;
348
349 skb->_skb_refdst = 0UL;
350 res = ip6_frag_reasm(fq, prev, dev);
351 skb->_skb_refdst = orefdst;
352 return res;
353 }
347 354
355 skb_dst_drop(skb);
348 inet_frag_lru_move(&fq->q); 356 inet_frag_lru_move(&fq->q);
349 return -1; 357 return -1;
350 358