Commit 696c6544 authored by Hangbin Liu's avatar Hangbin Liu Committed by David S. Miller

ipv6: separate ndisc_ns_create() from ndisc_send_ns()

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: default avatarHangbin Liu <liuhangbin@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 91398a96
...@@ -447,10 +447,15 @@ void ndisc_cleanup(void); ...@@ -447,10 +447,15 @@ void ndisc_cleanup(void);
int ndisc_rcv(struct sk_buff *skb); 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, void ndisc_send_ns(struct net_device *dev, const struct in6_addr *solicit,
const struct in6_addr *daddr, const struct in6_addr *saddr, const struct in6_addr *daddr, const struct in6_addr *saddr,
u64 nonce); 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, void ndisc_send_rs(struct net_device *dev,
const struct in6_addr *saddr, const struct in6_addr *daddr); const struct in6_addr *saddr, const struct in6_addr *daddr);
void ndisc_send_na(struct net_device *dev, const struct in6_addr *daddr, void ndisc_send_na(struct net_device *dev, const struct in6_addr *daddr,
......
...@@ -466,8 +466,7 @@ static void ip6_nd_hdr(struct sk_buff *skb, ...@@ -466,8 +466,7 @@ static void ip6_nd_hdr(struct sk_buff *skb,
hdr->daddr = *daddr; hdr->daddr = *daddr;
} }
static void ndisc_send_skb(struct sk_buff *skb, void ndisc_send_skb(struct sk_buff *skb, const struct in6_addr *daddr,
const struct in6_addr *daddr,
const struct in6_addr *saddr) const struct in6_addr *saddr)
{ {
struct dst_entry *dst = skb_dst(skb); struct dst_entry *dst = skb_dst(skb);
...@@ -515,6 +514,7 @@ static void ndisc_send_skb(struct sk_buff *skb, ...@@ -515,6 +514,7 @@ static void ndisc_send_skb(struct sk_buff *skb,
rcu_read_unlock(); rcu_read_unlock();
} }
EXPORT_SYMBOL(ndisc_send_skb);
void ndisc_send_na(struct net_device *dev, const struct in6_addr *daddr, void ndisc_send_na(struct net_device *dev, const struct in6_addr *daddr,
const struct in6_addr *solicited_addr, const struct in6_addr *solicited_addr,
...@@ -598,22 +598,16 @@ static void ndisc_send_unsol_na(struct net_device *dev) ...@@ -598,22 +598,16 @@ static void ndisc_send_unsol_na(struct net_device *dev)
in6_dev_put(idev); in6_dev_put(idev);
} }
void ndisc_send_ns(struct net_device *dev, const struct in6_addr *solicit, struct sk_buff *ndisc_ns_create(struct net_device *dev, const struct in6_addr *solicit,
const struct in6_addr *daddr, const struct in6_addr *saddr, const struct in6_addr *saddr, u64 nonce)
u64 nonce)
{ {
struct sk_buff *skb;
struct in6_addr addr_buf;
int inc_opt = dev->addr_len; int inc_opt = dev->addr_len;
int optlen = 0; struct sk_buff *skb;
struct nd_msg *msg; struct nd_msg *msg;
int optlen = 0;
if (!saddr) { if (!saddr)
if (ipv6_get_lladdr(dev, &addr_buf, return NULL;
(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC)))
return;
saddr = &addr_buf;
}
if (ipv6_addr_any(saddr)) if (ipv6_addr_any(saddr))
inc_opt = false; inc_opt = false;
...@@ -625,7 +619,7 @@ void ndisc_send_ns(struct net_device *dev, const struct in6_addr *solicit, ...@@ -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); skb = ndisc_alloc_skb(dev, sizeof(*msg) + optlen);
if (!skb) if (!skb)
return; return NULL;
msg = skb_put(skb, sizeof(*msg)); msg = skb_put(skb, sizeof(*msg));
*msg = (struct nd_msg) { *msg = (struct nd_msg) {
...@@ -647,6 +641,27 @@ void ndisc_send_ns(struct net_device *dev, const struct in6_addr *solicit, ...@@ -647,6 +641,27 @@ void ndisc_send_ns(struct net_device *dev, const struct in6_addr *solicit,
memcpy(opt + 2, &nonce, 6); memcpy(opt + 2, &nonce, 6);
} }
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); ndisc_send_skb(skb, daddr, saddr);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment