git.openpandora.org
/
pandora-kernel.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
tcp: make challenge acks less predictable
[pandora-kernel.git]
/
net
/
ipv6
/
ip6mr.c
diff --git
a/net/ipv6/ip6mr.c
b/net/ipv6/ip6mr.c
index
def0538
..
02b3c82
100644
(file)
--- a/
net/ipv6/ip6mr.c
+++ b/
net/ipv6/ip6mr.c
@@
-51,6
+51,7
@@
#include <linux/pim.h>
#include <net/addrconf.h>
#include <linux/netfilter_ipv6.h>
#include <linux/pim.h>
#include <net/addrconf.h>
#include <linux/netfilter_ipv6.h>
+#include <linux/export.h>
#include <net/ip6_checksum.h>
struct mr6_table {
#include <net/ip6_checksum.h>
struct mr6_table {
@@
-117,7
+118,7
@@
static int __ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb,
struct mfc6_cache *c, struct rtmsg *rtm);
static int ip6mr_rtm_dumproute(struct sk_buff *skb,
struct netlink_callback *cb);
struct mfc6_cache *c, struct rtmsg *rtm);
static int ip6mr_rtm_dumproute(struct sk_buff *skb,
struct netlink_callback *cb);
-static void mroute_clean_tables(struct mr6_table *mrt);
+static void mroute_clean_tables(struct mr6_table *mrt
, bool all
);
static void ipmr_expire_process(unsigned long arg);
#ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES
static void ipmr_expire_process(unsigned long arg);
#ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES
@@
-138,9
+139,12
@@
static struct mr6_table *ip6mr_get_table(struct net *net, u32 id)
static int ip6mr_fib_lookup(struct net *net, struct flowi6 *flp6,
struct mr6_table **mrt)
{
static int ip6mr_fib_lookup(struct net *net, struct flowi6 *flp6,
struct mr6_table **mrt)
{
- struct ip6mr_result res;
- struct fib_lookup_arg arg = { .result = &res, };
int err;
int err;
+ struct ip6mr_result res;
+ struct fib_lookup_arg arg = {
+ .result = &res,
+ .flags = FIB_LOOKUP_NOREF,
+ };
err = fib_rules_lookup(net->ipv6.mr6_rules_ops,
flowi6_to_flowi(flp6), 0, &arg);
err = fib_rules_lookup(net->ipv6.mr6_rules_ops,
flowi6_to_flowi(flp6), 0, &arg);
@@
-256,10
+260,12
@@
static void __net_exit ip6mr_rules_exit(struct net *net)
{
struct mr6_table *mrt, *next;
{
struct mr6_table *mrt, *next;
+ rtnl_lock();
list_for_each_entry_safe(mrt, next, &net->ipv6.mr6_tables, list) {
list_del(&mrt->list);
ip6mr_free_table(mrt);
}
list_for_each_entry_safe(mrt, next, &net->ipv6.mr6_tables, list) {
list_del(&mrt->list);
ip6mr_free_table(mrt);
}
+ rtnl_unlock();
fib_rules_unregister(net->ipv6.mr6_rules_ops);
}
#else
fib_rules_unregister(net->ipv6.mr6_rules_ops);
}
#else
@@
-286,7
+292,10
@@
static int __net_init ip6mr_rules_init(struct net *net)
static void __net_exit ip6mr_rules_exit(struct net *net)
{
static void __net_exit ip6mr_rules_exit(struct net *net)
{
+ rtnl_lock();
ip6mr_free_table(net->ipv6.mrt6);
ip6mr_free_table(net->ipv6.mrt6);
+ net->ipv6.mrt6 = NULL;
+ rtnl_unlock();
}
#endif
}
#endif
@@
-325,8
+334,8
@@
static struct mr6_table *ip6mr_new_table(struct net *net, u32 id)
static void ip6mr_free_table(struct mr6_table *mrt)
{
static void ip6mr_free_table(struct mr6_table *mrt)
{
- del_timer(&mrt->ipmr_expire_timer);
- mroute_clean_tables(mrt);
+ del_timer
_sync
(&mrt->ipmr_expire_timer);
+ mroute_clean_tables(mrt
, true
);
kfree(mrt);
}
kfree(mrt);
}
@@
-541,7
+550,7
@@
static void ipmr_mfc_seq_stop(struct seq_file *seq, void *v)
if (it->cache == &mrt->mfc6_unres_queue)
spin_unlock_bh(&mfc_unres_lock);
if (it->cache == &mrt->mfc6_unres_queue)
spin_unlock_bh(&mfc_unres_lock);
- else if (it->cache ==
mrt->mfc6_cache_array
)
+ else if (it->cache ==
&mrt->mfc6_cache_array[it->ct]
)
read_unlock(&mrt_lock);
}
read_unlock(&mrt_lock);
}
@@
-1464,7
+1473,7
@@
static int ip6mr_mfc_add(struct net *net, struct mr6_table *mrt,
* Close the multicast socket, and clear the vif tables etc
*/
* Close the multicast socket, and clear the vif tables etc
*/
-static void mroute_clean_tables(struct mr6_table *mrt)
+static void mroute_clean_tables(struct mr6_table *mrt
, bool all
)
{
int i;
LIST_HEAD(list);
{
int i;
LIST_HEAD(list);
@@
-1474,8
+1483,9
@@
static void mroute_clean_tables(struct mr6_table *mrt)
* Shut down all active vif entries
*/
for (i = 0; i < mrt->maxvif; i++) {
* Shut down all active vif entries
*/
for (i = 0; i < mrt->maxvif; i++) {
- if (!(mrt->vif6_table[i].flags & VIFF_STATIC))
- mif6_delete(mrt, i, &list);
+ if (!all && (mrt->vif6_table[i].flags & VIFF_STATIC))
+ continue;
+ mif6_delete(mrt, i, &list);
}
unregister_netdevice_many(&list);
}
unregister_netdevice_many(&list);
@@
-1484,7
+1494,7
@@
static void mroute_clean_tables(struct mr6_table *mrt)
*/
for (i = 0; i < MFC6_LINES; i++) {
list_for_each_entry_safe(c, next, &mrt->mfc6_cache_array[i], list) {
*/
for (i = 0; i < MFC6_LINES; i++) {
list_for_each_entry_safe(c, next, &mrt->mfc6_cache_array[i], list) {
- if (
c->mfc_flags & MFC_STATIC
)
+ if (
!all && (c->mfc_flags & MFC_STATIC)
)
continue;
write_lock_bh(&mrt_lock);
list_del(&c->list);
continue;
write_lock_bh(&mrt_lock);
list_del(&c->list);
@@
-1538,7
+1548,7
@@
int ip6mr_sk_done(struct sock *sk)
net->ipv6.devconf_all->mc_forwarding--;
write_unlock_bh(&mrt_lock);
net->ipv6.devconf_all->mc_forwarding--;
write_unlock_bh(&mrt_lock);
- mroute_clean_tables(mrt);
+ mroute_clean_tables(mrt
, false
);
err = 0;
break;
}
err = 0;
break;
}