
Hi Viacheslav,
On Tue, 30 Aug 2022 at 07:01, Viacheslav Mitrofanov v.v.mitrofanov@yadro.com wrote:
Implement basic of NDP. It doesn't include such things as Router Solicitation, Router Advertisement and Redirect. It just has Neighbor Solicitation and Neighbor Advertisement. Only these two features are used in u-boot IPv6. Implementation of some NDP functions uses API that was exposed in "net: ipv6: Add IPv6 basic primitives".
Also this patch inlcudes update in Makefile to build NDP.
Signed-off-by: Viacheslav Mitrofanov v.v.mitrofanov@yadro.com
include/ndisc.h | 65 ++++++++++++ net/Makefile | 1 + net/ndisc.c | 276 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 342 insertions(+) create mode 100644 include/ndisc.h create mode 100644 net/ndisc.c
diff --git a/include/ndisc.h b/include/ndisc.h new file mode 100644 index 0000000000..7debdd79d6 --- /dev/null +++ b/include/ndisc.h @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/*
- Copyright (C) 2013 Allied Telesis Labs NZ
- Chris Packham, judge.packham@gmail.com
- Copyright (C) 2022 YADRO
- Viacheslav Mitrofanov v.v.mitrofanov@yadro.com
- */
+#ifndef __NDISC_H__ +#define __NDISC_H__
+#include <ndisc.h>
+struct nd_msg {
comment
struct icmp6hdr icmph;
struct in6_addr target;
__u8 opt[0];
+};
+struct echo_msg {
comment
struct icmp6hdr icmph;
__u16 id;
__u16 sequence;
+};
+/* IPv6 destination address of packet waiting for ND */ +extern struct in6_addr net_nd_sol_packet_ip6; +/* MAC destination address of packet waiting for ND */ +extern uchar *net_nd_packet_mac; +/* pointer to packet waiting to be transmitted after ND is resolved */ +extern uchar *net_nd_tx_packet; +/* size of packet waiting to be transmitted */ +extern int net_nd_tx_packet_size; +/* the timer for ND resolution */ +extern ulong net_nd_timer_start; +/* the number of requests we have sent so far */ +extern int net_nd_try;
+#ifdef CONFIG_IPV6 +void ndisc_init(void); +void ndisc_receive(struct ethernet_hdr *et, struct ip6_hdr *ip6, int len); +void ndisc_request(void); +int ndisc_timeout_check(void);
comments
+#else +static inline void ndisc_init(void) +{ +}
+static inline void +ndisc_receive(struct ethernet_hdr *et, struct ip6_hdr *ip6, int len) +{ +}
+static inline void ndisc_request(void) +{ +}
+static inline int ndisc_timeout_check(void) +{
return 0;
+} +#endif
+#endif /* __NDISC_H__ */ diff --git a/net/Makefile b/net/Makefile index 4ea2a14f27..766dd04135 100644 --- a/net/Makefile +++ b/net/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_DM_MDIO) += mdio-uclass.o obj-$(CONFIG_DM_MDIO_MUX) += mdio-mux-uclass.o obj-$(CONFIG_NET) += eth_common.o obj-$(CONFIG_CMD_LINK_LOCAL) += link_local.o +obj-$(CONFIG_IPV6) += ndisc.o obj-$(CONFIG_NET) += net.o obj-$(CONFIG_IPV6) += net6.o obj-$(CONFIG_CMD_NFS) += nfs.o diff --git a/net/ndisc.c b/net/ndisc.c new file mode 100644 index 0000000000..1bd06211f1 --- /dev/null +++ b/net/ndisc.c @@ -0,0 +1,276 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (C) 2013 Allied Telesis Labs NZ
- Chris Packham, judge.packham@gmail.com
- Copyright (C) 2022 YADRO
- Viacheslav Mitrofanov v.v.mitrofanov@yadro.com
- */
+/*
- Neighbour Discovery for IPv6
- */
Single-line comment style is /* ... */
+#include <common.h> +#include <net.h> +#include <net6.h> +#include <ndisc.h>
+/* IPv6 destination address of packet waiting for ND */ +struct in6_addr net_nd_sol_packet_ip6 = ZERO_IPV6_ADDR;
Should these be static? Can we put them in a struct and attach them to the uclass or driver?
+/* IPv6 address we are expecting ND advert from */ +static struct in6_addr net_nd_rep_packet_ip6 = ZERO_IPV6_ADDR; +/* MAC destination address of packet waiting for ND */ +uchar *net_nd_packet_mac; +/* pointer to packet waiting to be transmitted after ND is resolved */ +uchar *net_nd_tx_packet; +static uchar net_nd_packet_buf[PKTSIZE_ALIGN + PKTALIGN]; +/* size of packet waiting to be transmitted */ +int net_nd_tx_packet_size; +/* the timer for ND resolution */ +ulong net_nd_timer_start; +/* the number of requests we have sent so far */ +int net_nd_try;
+#define IP6_NDISC_OPT_SPACE(len) (((len) + 2 + 7) & ~7)
+/**
- Insert an option into a neighbor discovery packet.
- Returns the number of bytes inserted (which may be >= len)
Need to document args and use sphinx format (please fix globally)
- */
+static int +ndisc_insert_option(struct nd_msg *ndisc, int type, u8 *data, int len) +{
int space = IP6_NDISC_OPT_SPACE(len);
ndisc->opt[0] = type;
ndisc->opt[1] = space >> 3;
memcpy(&ndisc->opt[2], data, len);
len += 2;
/* fill the remainder with 0 */
if ((space - len) > 0)
(drop extra brackets?)
memset(&ndisc->opt[len], 0, space - len);
'\0'
return space;
+}
+/**
- Extract the Ethernet address from a neighbor discovery packet.
- Note that the link layer address could be anything but the only networking
- media that u-boot supports is Ethernet so we assume we're extracting a 6
- byte Ethernet MAC address.
- */
+static void ndisc_extract_enetaddr(struct nd_msg *ndisc, uchar enetaddr[6]) +{
memcpy(enetaddr, &ndisc->opt[2], 6);
+}
[..]
Regards, Simon