[PATCH 04/17] net: ipv6: Add Neighbor Discovery Protocol (NDP)
Simon Glass
sjg at chromium.org
Thu Sep 1 04:26:46 CEST 2022
Hi Viacheslav,
On Tue, 30 Aug 2022 at 07:01, Viacheslav Mitrofanov
<v.v.mitrofanov at 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 at 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 at gmail.com>
> + *
> + * Copyright (C) 2022 YADRO
> + * Viacheslav Mitrofanov <v.v.mitrofanov at 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 at gmail.com>
> + *
> + * Copyright (C) 2022 YADRO
> + * Viacheslav Mitrofanov <v.v.mitrofanov at 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
More information about the U-Boot
mailing list