[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220323120906.42692-3-sunshouxin@chinatelecom.cn>
Date: Wed, 23 Mar 2022 08:09:04 -0400
From: Sun Shouxin <sunshouxin@...natelecom.cn>
To: j.vosburgh@...il.com, vfalico@...il.com, andy@...yhouse.net,
davem@...emloft.net, kuba@...nel.org, pabeni@...hat.com,
yoshfuji@...ux-ipv6.org, dsahern@...nel.org, oliver@...kum.org
Cc: netdev@...r.kernel.org, linux-kernel@...r.kernel.org,
huyd12@...natelecom.cn, sunshouxin@...natelecom.cn
Subject: [PATCH v6 2/4] net:ipv6:Refactor ndisc_send_na to support sending na by slave directly
Refactor ndisc_send_na to support sending na by slave directly.
Signed-off-by: Sun Shouxin <sunshouxin@...natelecom.cn>
---
include/net/ndisc.h | 6 +++++
net/ipv6/ndisc.c | 55 +++++++++++++++++++++++++++++++++------------
2 files changed, 47 insertions(+), 14 deletions(-)
diff --git a/include/net/ndisc.h b/include/net/ndisc.h
index 24cf6e92fecc..e71702a44a3d 100644
--- a/include/net/ndisc.h
+++ b/include/net/ndisc.h
@@ -107,6 +107,12 @@ struct nd_opt_hdr {
__u8 nd_opt_len;
} __packed;
+struct nd_sendinfo {
+ __u16 vlanid;
+ void *mac_dst;
+ const void *mac_src;
+};
+
/* ND options */
struct ndisc_options {
struct nd_opt_hdr *nd_opt_array[__ND_OPT_ARRAY_MAX];
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index f7bd7082abb4..47875aab86e5 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -526,22 +526,29 @@ void ndisc_send_na(struct net_device *dev, const struct in6_addr *daddr,
struct inet6_ifaddr *ifp;
const struct in6_addr *src_addr;
struct nd_msg *msg;
+ struct nd_sendinfo *sendinfo = data;
+ struct net *net = dev_net(dev);
+ struct sock *sk = net->ipv6.ndisc_sk;
int optlen = 0;
- /* for anycast or proxy, solicited_addr != src_addr */
- ifp = ipv6_get_ifaddr(dev_net(dev), solicited_addr, dev, 1);
- if (ifp) {
- src_addr = solicited_addr;
- if (ifp->flags & IFA_F_OPTIMISTIC)
- override = false;
- inc_opt |= ifp->idev->cnf.force_tllao;
- in6_ifa_put(ifp);
+ if (!sendinfo) {
+ /* for anycast or proxy, solicited_addr != src_addr */
+ ifp = ipv6_get_ifaddr(dev_net(dev), solicited_addr, dev, 1);
+ if (ifp) {
+ src_addr = solicited_addr;
+ if (ifp->flags & IFA_F_OPTIMISTIC)
+ override = false;
+ inc_opt |= ifp->idev->cnf.force_tllao;
+ in6_ifa_put(ifp);
+ } else {
+ if (ipv6_dev_get_saddr(dev_net(dev), dev, daddr,
+ inet6_sk(dev_net(dev)->ipv6.ndisc_sk)->srcprefs,
+ &tmpaddr))
+ return;
+ src_addr = &tmpaddr;
+ }
} else {
- if (ipv6_dev_get_saddr(dev_net(dev), dev, daddr,
- inet6_sk(dev_net(dev)->ipv6.ndisc_sk)->srcprefs,
- &tmpaddr))
- return;
- src_addr = &tmpaddr;
+ src_addr = solicited_addr;
}
if (!dev->addr_len)
@@ -569,8 +576,28 @@ void ndisc_send_na(struct net_device *dev, const struct in6_addr *daddr,
ndisc_fill_addr_option(skb, ND_OPT_TARGET_LL_ADDR,
dev->dev_addr,
NDISC_NEIGHBOUR_ADVERTISEMENT);
+ if (!sendinfo) {
+ ndisc_send_skb(skb, daddr, src_addr);
+ } else {
+ if (sendinfo->vlanid)
+ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
+ sendinfo->vlanid);
+
+ msg->icmph.icmp6_cksum = csum_ipv6_magic(src_addr, daddr, skb->len,
+ IPPROTO_ICMPV6,
+ csum_partial(&msg->icmph,
+ skb->len, 0));
- ndisc_send_skb(skb, daddr, src_addr);
+ ip6_nd_hdr(skb, src_addr, daddr, inet6_sk(sk)->hop_limit, skb->len);
+
+ skb->protocol = htons(ETH_P_IPV6);
+ skb->dev = dev;
+ if (dev_hard_header(skb, dev, ETH_P_IPV6, sendinfo->mac_dst,
+ sendinfo->mac_src, skb->len) < 0)
+ return;
+
+ dev_queue_xmit(skb);
+ }
}
static void ndisc_send_unsol_na(struct net_device *dev)
--
2.27.0
Powered by blists - more mailing lists