dccp: don't restart ccid2_hc_tx_rto_expire() if sk in closed state
[pandora-kernel.git] / net / ipv6 / ndisc.c
index bc55358..e5b0f9e 100644 (file)
@@ -446,6 +446,8 @@ struct sk_buff *ndisc_build_skb(struct net_device *dev,
        struct sock *sk = net->ipv6.ndisc_sk;
        struct sk_buff *skb;
        struct icmp6hdr *hdr;
+       int hlen = LL_RESERVED_SPACE(dev);
+       int tlen = dev->needed_tailroom;
        int len;
        u8 *opt;
 
@@ -457,7 +459,7 @@ struct sk_buff *ndisc_build_skb(struct net_device *dev,
                len += ndisc_opt_addr_space(dev);
 
        skb = alloc_skb((MAX_HEADER + sizeof(struct ipv6hdr) +
-                        len + LL_ALLOCATED_SPACE(dev)), GFP_ATOMIC);
+                        len + hlen + tlen), GFP_ATOMIC);
        if (!skb) {
                ND_PRINTK0(KERN_ERR
                           "ICMPv6 ND: %s() failed to allocate an skb.\n",
@@ -465,7 +467,7 @@ struct sk_buff *ndisc_build_skb(struct net_device *dev,
                return NULL;
        }
 
-       skb_reserve(skb, LL_RESERVED_SPACE(dev));
+       skb_reserve(skb, hlen);
        ip6_nd_hdr(sk, skb, dev, saddr, daddr, IPPROTO_ICMPV6, len);
 
        skb->transport_header = skb->tail;
@@ -1274,11 +1276,16 @@ static void ndisc_router_discovery(struct sk_buff *skb)
        if (rt)
                rt->rt6i_expires = jiffies + (HZ * lifetime);
 
-       if (ra_msg->icmph.icmp6_hop_limit) {
-               in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
-               if (rt)
-                       dst_metric_set(&rt->dst, RTAX_HOPLIMIT,
-                                      ra_msg->icmph.icmp6_hop_limit);
+       if (in6_dev->cnf.accept_ra_min_hop_limit < 256 &&
+           ra_msg->icmph.icmp6_hop_limit) {
+               if (in6_dev->cnf.accept_ra_min_hop_limit <= ra_msg->icmph.icmp6_hop_limit) {
+                       in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
+                       if (rt)
+                               dst_metric_set(&rt->dst, RTAX_HOPLIMIT,
+                                              ra_msg->icmph.icmp6_hop_limit);
+               } else {
+                       ND_PRINTK2(KERN_WARNING "RA: Got route advertisement with lower hop_limit than minimum\n");
+               }
        }
 
 skip_defrtr:
@@ -1534,6 +1541,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
        struct inet6_dev *idev;
        struct flowi6 fl6;
        u8 *opt;
+       int hlen, tlen;
        int rd_len;
        int err;
        u8 ha_buf[MAX_ADDR_LEN], *ha = NULL;
@@ -1591,9 +1599,11 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
        rd_len &= ~0x7;
        len += rd_len;
 
+       hlen = LL_RESERVED_SPACE(dev);
+       tlen = dev->needed_tailroom;
        buff = sock_alloc_send_skb(sk,
                                   (MAX_HEADER + sizeof(struct ipv6hdr) +
-                                   len + LL_ALLOCATED_SPACE(dev)),
+                                   len + hlen + tlen),
                                   1, &err);
        if (buff == NULL) {
                ND_PRINTK0(KERN_ERR
@@ -1602,7 +1612,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
                goto release;
        }
 
-       skb_reserve(buff, LL_RESERVED_SPACE(dev));
+       skb_reserve(buff, hlen);
        ip6_nd_hdr(sk, buff, dev, &saddr_buf, &ipv6_hdr(skb)->saddr,
                   IPPROTO_ICMPV6, len);
 
@@ -1731,11 +1741,11 @@ static int ndisc_netdev_event(struct notifier_block *this, unsigned long event,
        switch (event) {
        case NETDEV_CHANGEADDR:
                neigh_changeaddr(&nd_tbl, dev);
-               fib6_run_gc(~0UL, net);
+               fib6_run_gc(0, net, false);
                break;
        case NETDEV_DOWN:
                neigh_ifdown(&nd_tbl, dev);
-               fib6_run_gc(~0UL, net);
+               fib6_run_gc(0, net, false);
                break;
        case NETDEV_NOTIFY_PEERS:
                ndisc_send_unsol_na(dev);