Merge tag 'keys-pkcs7-20140708' into keys-next
[cascardo/linux.git] / net / ipv6 / icmp.c
index 7b32652..f6c84a6 100644 (file)
@@ -400,6 +400,7 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
        int len;
        int hlimit;
        int err = 0;
+       u32 mark = IP6_REPLY_MARK(net, skb->mark);
 
        if ((u8 *)hdr < skb->head ||
            (skb_network_header(skb) + sizeof(*hdr)) > skb_tail_pointer(skb))
@@ -466,6 +467,7 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
        fl6.daddr = hdr->saddr;
        if (saddr)
                fl6.saddr = *saddr;
+       fl6.flowi6_mark = mark;
        fl6.flowi6_oif = iif;
        fl6.fl6_icmp_type = type;
        fl6.fl6_icmp_code = code;
@@ -474,6 +476,7 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
        sk = icmpv6_xmit_lock(net);
        if (sk == NULL)
                return;
+       sk->sk_mark = mark;
        np = inet6_sk(sk);
 
        if (!icmpv6_xrlim_allow(sk, type, &fl6))
@@ -493,12 +496,7 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
        if (IS_ERR(dst))
                goto out;
 
-       if (ipv6_addr_is_multicast(&fl6.daddr))
-               hlimit = np->mcast_hops;
-       else
-               hlimit = np->hop_limit;
-       if (hlimit < 0)
-               hlimit = ip6_dst_hoplimit(dst);
+       hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
 
        msg.skb = skb;
        msg.offset = skb_network_offset(skb);
@@ -556,6 +554,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
        int err = 0;
        int hlimit;
        u8 tclass;
+       u32 mark = IP6_REPLY_MARK(net, skb->mark);
 
        saddr = &ipv6_hdr(skb)->daddr;
 
@@ -574,11 +573,13 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
                fl6.saddr = *saddr;
        fl6.flowi6_oif = skb->dev->ifindex;
        fl6.fl6_icmp_type = ICMPV6_ECHO_REPLY;
+       fl6.flowi6_mark = mark;
        security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
 
        sk = icmpv6_xmit_lock(net);
        if (sk == NULL)
                return;
+       sk->sk_mark = mark;
        np = inet6_sk(sk);
 
        if (!fl6.flowi6_oif && ipv6_addr_is_multicast(&fl6.daddr))
@@ -593,12 +594,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
        if (IS_ERR(dst))
                goto out;
 
-       if (ipv6_addr_is_multicast(&fl6.daddr))
-               hlimit = np->mcast_hops;
-       else
-               hlimit = np->hop_limit;
-       if (hlimit < 0)
-               hlimit = ip6_dst_hoplimit(dst);
+       hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
 
        idev = __in6_dev_get(skb->dev);
 
@@ -702,22 +698,11 @@ static int icmpv6_rcv(struct sk_buff *skb)
        saddr = &ipv6_hdr(skb)->saddr;
        daddr = &ipv6_hdr(skb)->daddr;
 
-       /* Perform checksum. */
-       switch (skb->ip_summed) {
-       case CHECKSUM_COMPLETE:
-               if (!csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_ICMPV6,
-                                    skb->csum))
-                       break;
-               /* fall through */
-       case CHECKSUM_NONE:
-               skb->csum = ~csum_unfold(csum_ipv6_magic(saddr, daddr, skb->len,
-                                            IPPROTO_ICMPV6, 0));
-               if (__skb_checksum_complete(skb)) {
-                       LIMIT_NETDEBUG(KERN_DEBUG
-                                      "ICMPv6 checksum failed [%pI6c > %pI6c]\n",
-                                      saddr, daddr);
-                       goto csum_error;
-               }
+       if (skb_checksum_validate(skb, IPPROTO_ICMPV6, ip6_compute_pseudo)) {
+               LIMIT_NETDEBUG(KERN_DEBUG
+                              "ICMPv6 checksum failed [%pI6c > %pI6c]\n",
+                              saddr, daddr);
+               goto csum_error;
        }
 
        if (!pskb_pull(skb, sizeof(*hdr)))