ipv6: icmp: add a force_saddr param to icmp6_send()
authorEric Dumazet <edumazet@google.com>
Sun, 19 Jun 2016 04:52:02 +0000 (21:52 -0700)
committerDavid S. Miller <davem@davemloft.net>
Sun, 19 Jun 2016 05:11:38 +0000 (22:11 -0700)
SIT or GRE tunnels might want to translate an IPV4 address
into a v4mapped one when translating ICMP to ICMPv6.

This patch adds the parameter to icmp6_send() but
does not change icmpv6_send() signature.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/icmpv6.h
net/ipv6/icmp.c
net/ipv6/ip6_icmp.c

index 630f45335c73f8ad2a4e7f082fb0abc947e1405e..432611a297fbc5c8d2359dd15874da6faf7c1cb4 100644 (file)
@@ -14,7 +14,8 @@ static inline struct icmp6hdr *icmp6_hdr(const struct sk_buff *skb)
 #if IS_ENABLED(CONFIG_IPV6)
 extern void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info);
 
-typedef void ip6_icmp_send_t(struct sk_buff *skb, u8 type, u8 code, __u32 info);
+typedef void ip6_icmp_send_t(struct sk_buff *skb, u8 type, u8 code, __u32 info,
+                            const struct in6_addr *force_saddr);
 extern int inet6_register_icmp_sender(ip6_icmp_send_t *fn);
 extern int inet6_unregister_icmp_sender(ip6_icmp_send_t *fn);
 
index e32a72fb9982d374c662a39119408a7d1bc09bdb..6c57e6e90301c87a7ade0982954d15d2a0d24111 100644 (file)
@@ -388,7 +388,8 @@ relookup_failed:
 /*
  *     Send an ICMP message in response to a packet in error
  */
-static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
+static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
+                      const struct in6_addr *force_saddr)
 {
        struct net *net = dev_net(skb->dev);
        struct inet6_dev *idev = NULL;
@@ -475,6 +476,8 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
        memset(&fl6, 0, sizeof(fl6));
        fl6.flowi6_proto = IPPROTO_ICMPV6;
        fl6.daddr = hdr->saddr;
+       if (force_saddr)
+               saddr = force_saddr;
        if (saddr)
                fl6.saddr = *saddr;
        fl6.flowi6_mark = mark;
@@ -551,7 +554,7 @@ out:
  */
 void icmpv6_param_prob(struct sk_buff *skb, u8 code, int pos)
 {
-       icmp6_send(skb, ICMPV6_PARAMPROB, code, pos);
+       icmp6_send(skb, ICMPV6_PARAMPROB, code, pos, NULL);
        kfree_skb(skb);
 }
 
index 14dacc544c3efc06de8ac80f6bbf6a5ee6cf6b35..713676f14a0ee2d3478667a846cfa1b536fe511c 100644 (file)
@@ -39,7 +39,7 @@ void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
 
        if (!send)
                goto out;
-       send(skb, type, code, info);
+       send(skb, type, code, info, NULL);
 out:
        rcu_read_unlock();
 }