ipv6: separate ndisc_ns_create() from ndisc_send_ns()
authorHangbin Liu <liuhangbin@gmail.com>
Mon, 21 Feb 2022 05:54:53 +0000 (13:54 +0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 21 Feb 2022 12:13:45 +0000 (12:13 +0000)
This patch separate NS message allocation steps from ndisc_send_ns(),
so it could be used in other places, like bonding, to allocate and
send IPv6 NS message.

Also export ndisc_send_skb() and ndisc_ns_create() for later bonding usage.

Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/ndisc.h
net/ipv6/ndisc.c

index 53cb8de..aac3a42 100644 (file)
@@ -447,10 +447,15 @@ void ndisc_cleanup(void);
 
 int ndisc_rcv(struct sk_buff *skb);
 
+struct sk_buff *ndisc_ns_create(struct net_device *dev, const struct in6_addr *solicit,
+                               const struct in6_addr *saddr, u64 nonce);
 void ndisc_send_ns(struct net_device *dev, const struct in6_addr *solicit,
                   const struct in6_addr *daddr, const struct in6_addr *saddr,
                   u64 nonce);
 
+void ndisc_send_skb(struct sk_buff *skb, const struct in6_addr *daddr,
+                   const struct in6_addr *saddr);
+
 void ndisc_send_rs(struct net_device *dev,
                   const struct in6_addr *saddr, const struct in6_addr *daddr);
 void ndisc_send_na(struct net_device *dev, const struct in6_addr *daddr,
index 1c06d0c..fcb288b 100644 (file)
@@ -466,9 +466,8 @@ static void ip6_nd_hdr(struct sk_buff *skb,
        hdr->daddr = *daddr;
 }
 
-static void ndisc_send_skb(struct sk_buff *skb,
-                          const struct in6_addr *daddr,
-                          const struct in6_addr *saddr)
+void ndisc_send_skb(struct sk_buff *skb, const struct in6_addr *daddr,
+                   const struct in6_addr *saddr)
 {
        struct dst_entry *dst = skb_dst(skb);
        struct net *net = dev_net(skb->dev);
@@ -515,6 +514,7 @@ static void ndisc_send_skb(struct sk_buff *skb,
 
        rcu_read_unlock();
 }
+EXPORT_SYMBOL(ndisc_send_skb);
 
 void ndisc_send_na(struct net_device *dev, const struct in6_addr *daddr,
                   const struct in6_addr *solicited_addr,
@@ -598,22 +598,16 @@ static void ndisc_send_unsol_na(struct net_device *dev)
        in6_dev_put(idev);
 }
 
-void ndisc_send_ns(struct net_device *dev, const struct in6_addr *solicit,
-                  const struct in6_addr *daddr, const struct in6_addr *saddr,
-                  u64 nonce)
+struct sk_buff *ndisc_ns_create(struct net_device *dev, const struct in6_addr *solicit,
+                               const struct in6_addr *saddr, u64 nonce)
 {
-       struct sk_buff *skb;
-       struct in6_addr addr_buf;
        int inc_opt = dev->addr_len;
-       int optlen = 0;
+       struct sk_buff *skb;
        struct nd_msg *msg;
+       int optlen = 0;
 
-       if (!saddr) {
-               if (ipv6_get_lladdr(dev, &addr_buf,
-                                  (IFA_F_TENTATIVE|IFA_F_OPTIMISTIC)))
-                       return;
-               saddr = &addr_buf;
-       }
+       if (!saddr)
+               return NULL;
 
        if (ipv6_addr_any(saddr))
                inc_opt = false;
@@ -625,7 +619,7 @@ void ndisc_send_ns(struct net_device *dev, const struct in6_addr *solicit,
 
        skb = ndisc_alloc_skb(dev, sizeof(*msg) + optlen);
        if (!skb)
-               return;
+               return NULL;
 
        msg = skb_put(skb, sizeof(*msg));
        *msg = (struct nd_msg) {
@@ -647,7 +641,28 @@ void ndisc_send_ns(struct net_device *dev, const struct in6_addr *solicit,
                memcpy(opt + 2, &nonce, 6);
        }
 
-       ndisc_send_skb(skb, daddr, saddr);
+       return skb;
+}
+EXPORT_SYMBOL(ndisc_ns_create);
+
+void ndisc_send_ns(struct net_device *dev, const struct in6_addr *solicit,
+                  const struct in6_addr *daddr, const struct in6_addr *saddr,
+                  u64 nonce)
+{
+       struct in6_addr addr_buf;
+       struct sk_buff *skb;
+
+       if (!saddr) {
+               if (ipv6_get_lladdr(dev, &addr_buf,
+                                   (IFA_F_TENTATIVE | IFA_F_OPTIMISTIC)))
+                       return;
+               saddr = &addr_buf;
+       }
+
+       skb = ndisc_ns_create(dev, solicit, saddr, nonce);
+
+       if (skb)
+               ndisc_send_skb(skb, daddr, saddr);
 }
 
 void ndisc_send_rs(struct net_device *dev, const struct in6_addr *saddr,