diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/addrconf.c | 13 | ||||
-rw-r--r-- | net/ipv6/datagram.c | 6 | ||||
-rw-r--r-- | net/ipv6/esp6.c | 6 | ||||
-rw-r--r-- | net/ipv6/ip6_output.c | 2 | ||||
-rw-r--r-- | net/ipv6/ipv6_sockglue.c | 12 | ||||
-rw-r--r-- | net/ipv6/ndisc.c | 2 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 11 | ||||
-rw-r--r-- | net/ipv6/xfrm6_policy.c | 2 |
8 files changed, 35 insertions, 19 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 1bd8d818f8e..e8c347579da 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -967,7 +967,7 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, if (unlikely(score.addr_type == IPV6_ADDR_ANY || score.addr_type & IPV6_ADDR_MULTICAST)) { LIMIT_NETDEBUG(KERN_DEBUG - "ADDRCONF: unspecified / multicast address" + "ADDRCONF: unspecified / multicast address " "assigned as unicast address on %s", dev->name); continue; @@ -2293,6 +2293,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, break; } + if (!idev && dev->mtu >= IPV6_MIN_MTU) + idev = ipv6_add_dev(dev); + if (idev) idev->if_flags |= IF_READY; } else { @@ -2357,12 +2360,18 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, break; case NETDEV_CHANGEMTU: - if ( idev && dev->mtu >= IPV6_MIN_MTU) { + if (idev && dev->mtu >= IPV6_MIN_MTU) { rt6_mtu_change(dev, dev->mtu); idev->cnf.mtu6 = dev->mtu; break; } + if (!idev && dev->mtu >= IPV6_MIN_MTU) { + idev = ipv6_add_dev(dev); + if (idev) + break; + } + /* MTU falled under IPV6_MIN_MTU. Stop IPv6 on this interface. */ case NETDEV_DOWN: diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 2ed689ac449..5d4245ab418 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -123,11 +123,11 @@ ipv4_connected: goto out; } sk->sk_bound_dev_if = usin->sin6_scope_id; - if (!sk->sk_bound_dev_if && - (addr_type & IPV6_ADDR_MULTICAST)) - fl.oif = np->mcast_oif; } + if (!sk->sk_bound_dev_if && (addr_type & IPV6_ADDR_MULTICAST)) + sk->sk_bound_dev_if = np->mcast_oif; + /* Connect to link-local address requires an interface */ if (!sk->sk_bound_dev_if) { err = -EINVAL; diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index 7db66f10e00..44405325467 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c @@ -230,6 +230,12 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb) } /* ... check padding bits here. Silly. :-) */ + /* RFC4303: Drop dummy packets without any error */ + if (nexthdr[1] == IPPROTO_NONE) { + ret = -EINVAL; + goto out; + } + pskb_trim(skb, skb->len - alen - padlen - 2); ret = nexthdr[1]; } diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 86e1835ce4e..6338a9c1aa1 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -933,6 +933,8 @@ static int ip6_dst_lookup_tail(struct sock *sk, return 0; out_err_release: + if (err == -ENETUNREACH) + IP6_INC_STATS_BH(NULL, IPSTATS_MIB_OUTNOROUTES); dst_release(*dst); *dst = NULL; return err; diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 1334fc174bc..8c5f80fd03a 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -1046,7 +1046,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, break; default: - return -EINVAL; + return -ENOPROTOOPT; } len = min_t(unsigned int, sizeof(int), len); if(put_user(len, optlen)) @@ -1069,9 +1069,8 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname, err = do_ipv6_getsockopt(sk, level, optname, optval, optlen); #ifdef CONFIG_NETFILTER - /* we need to exclude all possible EINVALs except default case */ - if (err == -EINVAL && optname != IPV6_ADDRFORM && - optname != MCAST_MSFILTER) { + /* we need to exclude all possible ENOPROTOOPTs except default case */ + if (err == -ENOPROTOOPT && optname != IPV6_2292PKTOPTIONS) { int len; if (get_user(len, optlen)) @@ -1108,9 +1107,8 @@ int compat_ipv6_getsockopt(struct sock *sk, int level, int optname, err = do_ipv6_getsockopt(sk, level, optname, optval, optlen); #ifdef CONFIG_NETFILTER - /* we need to exclude all possible EINVALs except default case */ - if (err == -EINVAL && optname != IPV6_ADDRFORM && - optname != MCAST_MSFILTER) { + /* we need to exclude all possible ENOPROTOOPTs except default case */ + if (err == -ENOPROTOOPT && optname != IPV6_2292PKTOPTIONS) { int len; if (get_user(len, optlen)) diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 67997a74ddc..777ed733b2d 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -612,7 +612,7 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr, * optimistic addresses, but we may send the solicitation * if we don't include the sllao. So here we check * if our address is optimistic, and if so, we - * supress the inclusion of the sllao. + * suppress the inclusion of the sllao. */ if (send_sllao) { struct inet6_ifaddr *ifp = ipv6_get_ifaddr(saddr, dev, 1); diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 3aad861975a..93980c3b83e 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -581,7 +581,10 @@ static int tcp_v6_md5_do_add(struct sock *sk, struct in6_addr *peer, } sk->sk_route_caps &= ~NETIF_F_GSO_MASK; } - tcp_alloc_md5sig_pool(); + if (tcp_alloc_md5sig_pool() == NULL) { + kfree(newkey); + return -ENOMEM; + } if (tp->md5sig_info->alloced6 == tp->md5sig_info->entries6) { keys = kmalloc((sizeof (tp->md5sig_info->keys6[0]) * (tp->md5sig_info->entries6 + 1)), GFP_ATOMIC); @@ -634,10 +637,6 @@ static int tcp_v6_md5_do_del(struct sock *sk, struct in6_addr *peer) kfree(tp->md5sig_info->keys6); tp->md5sig_info->keys6 = NULL; tp->md5sig_info->alloced6 = 0; - - tcp_free_md5sig_pool(); - - return 0; } else { /* shrink the database */ if (tp->md5sig_info->entries6 != i) @@ -646,6 +645,8 @@ static int tcp_v6_md5_do_del(struct sock *sk, struct in6_addr *peer) (tp->md5sig_info->entries6 - i) * sizeof (tp->md5sig_info->keys6[0])); } + tcp_free_md5sig_pool(); + return 0; } } return -ENOENT; diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 82e27b80d07..b8e9eb445d7 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c @@ -233,7 +233,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int dst_prev->output = dst_prev->xfrm->outer_mode->afinfo->output; /* Sheit... I remember I did this right. Apparently, * it was magically lost, so this code needs audit */ - x->u.rt6.rt6i_flags = rt0->rt6i_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL); + x->u.rt6.rt6i_flags = rt0->rt6i_flags&(RTF_ANYCAST|RTF_LOCAL); x->u.rt6.rt6i_metric = rt0->rt6i_metric; x->u.rt6.rt6i_node = rt0->rt6i_node; x->u.rt6.rt6i_gateway = rt0->rt6i_gateway; |