diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/addrconf.c | 6 | ||||
-rw-r--r-- | net/ipv6/af_inet6.c | 6 | ||||
-rw-r--r-- | net/ipv6/mcast.c | 56 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6_tables.c | 7 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_policy.c | 7 | ||||
-rw-r--r-- | net/ipv6/proc.c | 2 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 1 |
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 | ||
1967 | static int sf_setstate(struct ifmcaddr6 *pmc) | 1965 | static 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"); | |||
26 | static inline int | 26 | static inline int |
27 | match_xfrm_state(struct xfrm_state *x, const struct ip6t_policy_elem *e) | 27 | match_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 | ||
97 | static int match(const struct sk_buff *skb, | 98 | static 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, | |||
515 | done: | 515 | done: |
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 | ||