aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/addrconf.c6
-rw-r--r--net/ipv6/af_inet6.c6
-rw-r--r--net/ipv6/mcast.c56
-rw-r--r--net/ipv6/netfilter/ip6_tables.c7
-rw-r--r--net/ipv6/netfilter/ip6t_policy.c7
-rw-r--r--net/ipv6/proc.c2
-rw-r--r--net/ipv6/tcp_ipv6.c1
7 files changed, 61 insertions, 24 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index d328d5986143..1db50487916b 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3321,9 +3321,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
3321 3321
3322 switch (event) { 3322 switch (event) {
3323 case RTM_NEWADDR: 3323 case RTM_NEWADDR:
3324 dst_hold(&ifp->rt->u.dst); 3324 ip6_ins_rt(ifp->rt, NULL, NULL, NULL);
3325 if (ip6_ins_rt(ifp->rt, NULL, NULL, NULL))
3326 dst_release(&ifp->rt->u.dst);
3327 if (ifp->idev->cnf.forwarding) 3325 if (ifp->idev->cnf.forwarding)
3328 addrconf_join_anycast(ifp); 3326 addrconf_join_anycast(ifp);
3329 break; 3327 break;
@@ -3334,8 +3332,6 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
3334 dst_hold(&ifp->rt->u.dst); 3332 dst_hold(&ifp->rt->u.dst);
3335 if (ip6_del_rt(ifp->rt, NULL, NULL, NULL)) 3333 if (ip6_del_rt(ifp->rt, NULL, NULL, NULL))
3336 dst_free(&ifp->rt->u.dst); 3334 dst_free(&ifp->rt->u.dst);
3337 else
3338 dst_release(&ifp->rt->u.dst);
3339 break; 3335 break;
3340 } 3336 }
3341} 3337}
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 064ffab82a9f..6c9711ac1c03 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -369,12 +369,6 @@ int inet6_destroy_sock(struct sock *sk)
369 struct sk_buff *skb; 369 struct sk_buff *skb;
370 struct ipv6_txoptions *opt; 370 struct ipv6_txoptions *opt;
371 371
372 /*
373 * Release destination entry
374 */
375
376 sk_dst_reset(sk);
377
378 /* Release rx options */ 372 /* Release rx options */
379 373
380 if ((skb = xchg(&np->pktoptions, NULL)) != NULL) 374 if ((skb = xchg(&np->pktoptions, NULL)) != NULL)
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 6c05c7978bef..4420948a1bfe 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1252,8 +1252,7 @@ int igmp6_event_query(struct sk_buff *skb)
1252 } 1252 }
1253 } else { 1253 } else {
1254 for (ma = idev->mc_list; ma; ma=ma->next) { 1254 for (ma = idev->mc_list; ma; ma=ma->next) {
1255 if (group_type != IPV6_ADDR_ANY && 1255 if (!ipv6_addr_equal(group, &ma->mca_addr))
1256 !ipv6_addr_equal(group, &ma->mca_addr))
1257 continue; 1256 continue;
1258 spin_lock_bh(&ma->mca_lock); 1257 spin_lock_bh(&ma->mca_lock);
1259 if (ma->mca_flags & MAF_TIMER_RUNNING) { 1258 if (ma->mca_flags & MAF_TIMER_RUNNING) {
@@ -1268,11 +1267,10 @@ int igmp6_event_query(struct sk_buff *skb)
1268 ma->mca_flags &= ~MAF_GSQUERY; 1267 ma->mca_flags &= ~MAF_GSQUERY;
1269 } 1268 }
1270 if (!(ma->mca_flags & MAF_GSQUERY) || 1269 if (!(ma->mca_flags & MAF_GSQUERY) ||
1271 mld_marksources(ma, ntohs(mlh2->nsrcs), mlh2->srcs)) 1270 mld_marksources(ma, ntohs(mlh2->nsrcs), mlh2->srcs))
1272 igmp6_group_queried(ma, max_delay); 1271 igmp6_group_queried(ma, max_delay);
1273 spin_unlock_bh(&ma->mca_lock); 1272 spin_unlock_bh(&ma->mca_lock);
1274 if (group_type != IPV6_ADDR_ANY) 1273 break;
1275 break;
1276 } 1274 }
1277 } 1275 }
1278 read_unlock_bh(&idev->lock); 1276 read_unlock_bh(&idev->lock);
@@ -1351,7 +1349,7 @@ static int is_in(struct ifmcaddr6 *pmc, struct ip6_sf_list *psf, int type,
1351 * in all filters 1349 * in all filters
1352 */ 1350 */
1353 if (psf->sf_count[MCAST_INCLUDE]) 1351 if (psf->sf_count[MCAST_INCLUDE])
1354 return 0; 1352 return type == MLD2_MODE_IS_INCLUDE;
1355 return pmc->mca_sfcount[MCAST_EXCLUDE] == 1353 return pmc->mca_sfcount[MCAST_EXCLUDE] ==
1356 psf->sf_count[MCAST_EXCLUDE]; 1354 psf->sf_count[MCAST_EXCLUDE];
1357 } 1355 }
@@ -1966,7 +1964,7 @@ static void sf_markstate(struct ifmcaddr6 *pmc)
1966 1964
1967static int sf_setstate(struct ifmcaddr6 *pmc) 1965static int sf_setstate(struct ifmcaddr6 *pmc)
1968{ 1966{
1969 struct ip6_sf_list *psf; 1967 struct ip6_sf_list *psf, *dpsf;
1970 int mca_xcount = pmc->mca_sfcount[MCAST_EXCLUDE]; 1968 int mca_xcount = pmc->mca_sfcount[MCAST_EXCLUDE];
1971 int qrv = pmc->idev->mc_qrv; 1969 int qrv = pmc->idev->mc_qrv;
1972 int new_in, rv; 1970 int new_in, rv;
@@ -1978,8 +1976,48 @@ static int sf_setstate(struct ifmcaddr6 *pmc)
1978 !psf->sf_count[MCAST_INCLUDE]; 1976 !psf->sf_count[MCAST_INCLUDE];
1979 } else 1977 } else
1980 new_in = psf->sf_count[MCAST_INCLUDE] != 0; 1978 new_in = psf->sf_count[MCAST_INCLUDE] != 0;
1981 if (new_in != psf->sf_oldin) { 1979 if (new_in) {
1982 psf->sf_crcount = qrv; 1980 if (!psf->sf_oldin) {
1981 struct ip6_sf_list *prev = 0;
1982
1983 for (dpsf=pmc->mca_tomb; dpsf;
1984 dpsf=dpsf->sf_next) {
1985 if (ipv6_addr_equal(&dpsf->sf_addr,
1986 &psf->sf_addr))
1987 break;
1988 prev = dpsf;
1989 }
1990 if (dpsf) {
1991 if (prev)
1992 prev->sf_next = dpsf->sf_next;
1993 else
1994 pmc->mca_tomb = dpsf->sf_next;
1995 kfree(dpsf);
1996 }
1997 psf->sf_crcount = qrv;
1998 rv++;
1999 }
2000 } else if (psf->sf_oldin) {
2001 psf->sf_crcount = 0;
2002 /*
2003 * add or update "delete" records if an active filter
2004 * is now inactive
2005 */
2006 for (dpsf=pmc->mca_tomb; dpsf; dpsf=dpsf->sf_next)
2007 if (ipv6_addr_equal(&dpsf->sf_addr,
2008 &psf->sf_addr))
2009 break;
2010 if (!dpsf) {
2011 dpsf = (struct ip6_sf_list *)
2012 kmalloc(sizeof(*dpsf), GFP_ATOMIC);
2013 if (!dpsf)
2014 continue;
2015 *dpsf = *psf;
2016 /* pmc->mca_lock held by callers */
2017 dpsf->sf_next = pmc->mca_tomb;
2018 pmc->mca_tomb = dpsf;
2019 }
2020 dpsf->sf_crcount = qrv;
1983 rv++; 2021 rv++;
1984 } 2022 }
1985 } 2023 }
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 847068fd3367..74ff56c322f4 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -978,6 +978,13 @@ do_replace(void __user *user, unsigned int len)
978 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) 978 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
979 return -EFAULT; 979 return -EFAULT;
980 980
981 /* overflow check */
982 if (tmp.size >= (INT_MAX - sizeof(struct xt_table_info)) / NR_CPUS -
983 SMP_CACHE_BYTES)
984 return -ENOMEM;
985 if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
986 return -ENOMEM;
987
981 newinfo = xt_alloc_table_info(tmp.size); 988 newinfo = xt_alloc_table_info(tmp.size);
982 if (!newinfo) 989 if (!newinfo)
983 return -ENOMEM; 990 return -ENOMEM;
diff --git a/net/ipv6/netfilter/ip6t_policy.c b/net/ipv6/netfilter/ip6t_policy.c
index afe1cc4c18a5..3d39ec924041 100644
--- a/net/ipv6/netfilter/ip6t_policy.c
+++ b/net/ipv6/netfilter/ip6t_policy.c
@@ -26,8 +26,9 @@ MODULE_LICENSE("GPL");
26static inline int 26static inline int
27match_xfrm_state(struct xfrm_state *x, const struct ip6t_policy_elem *e) 27match_xfrm_state(struct xfrm_state *x, const struct ip6t_policy_elem *e)
28{ 28{
29#define MATCH_ADDR(x,y,z) (!e->match.x || \ 29#define MATCH_ADDR(x,y,z) (!e->match.x || \
30 ((ip6_masked_addrcmp((z), &e->x, &e->y)) == 0) ^ e->invert.x) 30 ((!ip6_masked_addrcmp(&e->x.a6, &e->y.a6, z)) \
31 ^ e->invert.x))
31#define MATCH(x,y) (!e->match.x || ((e->x == (y)) ^ e->invert.x)) 32#define MATCH(x,y) (!e->match.x || ((e->x == (y)) ^ e->invert.x))
32 33
33 return MATCH_ADDR(saddr, smask, (struct in6_addr *)&x->props.saddr.a6) && 34 return MATCH_ADDR(saddr, smask, (struct in6_addr *)&x->props.saddr.a6) &&
@@ -91,7 +92,7 @@ match_policy_out(const struct sk_buff *skb, const struct ip6t_policy_info *info)
91 return 0; 92 return 0;
92 } 93 }
93 94
94 return strict ? 1 : 0; 95 return strict ? i == info->len : 0;
95} 96}
96 97
97static int match(const struct sk_buff *skb, 98static int match(const struct sk_buff *skb,
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index 50a13e75d70e..4238b1ed8860 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -38,7 +38,7 @@ static int fold_prot_inuse(struct proto *proto)
38 int res = 0; 38 int res = 0;
39 int cpu; 39 int cpu;
40 40
41 for (cpu=0; cpu<NR_CPUS; cpu++) 41 for_each_cpu(cpu)
42 res += proto->stats[cpu].inuse; 42 res += proto->stats[cpu].inuse;
43 43
44 return res; 44 return res;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 66d04004afda..ca9cf6853755 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -515,6 +515,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
515done: 515done:
516 if (opt && opt != np->opt) 516 if (opt && opt != np->opt)
517 sock_kfree_s(sk, opt, opt->tot_len); 517 sock_kfree_s(sk, opt, opt->tot_len);
518 dst_release(dst);
518 return err; 519 return err;
519} 520}
520 521