[PATCH v4 1/3] net: add a generic udp protocol

This commit adds a generic udp protocol framework in the network loop. So protocol based on udp may be implemented without modifying the network loop (for example custom wait magic packet).
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com Reviewed-by: Simon Glass sjg@chromium.org ---
Changelog: v4: - no change
v3: - add file doc/README.udp - add more comments on function udp_loop - fix sentence in Kconfig - use if (IS_ENABLE(...)) when it is possible - avoid checking null pointer twice
v2: - no change
doc/README.udp | 35 +++++++++++++++++++++++++++++++++++ include/net.h | 2 +- include/net/udp.h | 41 +++++++++++++++++++++++++++++++++++++++++ net/Kconfig | 6 ++++++ net/Makefile | 1 + net/net.c | 13 ++++++++++++- net/udp.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 doc/README.udp create mode 100644 include/net/udp.h create mode 100644 net/udp.c
diff --git a/doc/README.udp b/doc/README.udp new file mode 100644 index 0000000..da07257 --- /dev/null +++ b/doc/README.udp @@ -0,0 +1,35 @@ +Udp framework + +The udp framework is build on top of network framework and is designed +to define new protocol or new command based on udp without modifying +the network framework. + +The udp framework define a function udp_loop that take as argument +a structure udp_ops (defined in include/net/udp.h) : + +struct udp_ops { + int (*prereq)(void *data); + int (*start)(void *data); + void *data; +}; + +The callback prereq define if all the requirements are +valid before running the network/udp loop. + +The callback start define the first step in the network/udp loop, +and it may also be used to configure a timemout and udp handler. + +The pointer data is used to store private data that +could be used by both callback. + +A simple example to use this framework: + +static struct udp_ops udp_ops = { + .prereq = wmp_prereq, + .start = wmp_start, + .data = NULL, +}; + +... + +err = udp_loop(&udp_ops); diff --git a/include/net.h b/include/net.h index 1bf9867..2191071 100644 --- a/include/net.h +++ b/include/net.h @@ -551,7 +551,7 @@ extern int net_restart_wrap; /* Tried all network devices */
enum proto_t { BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP, - TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL + TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT, WOL, UDP };
extern char net_boot_file_name[1024];/* Boot File name */ diff --git a/include/net/udp.h b/include/net/udp.h new file mode 100644 index 0000000..2ae56e8 --- /dev/null +++ b/include/net/udp.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2020 Philippe Reynes philippe.reynes@softathome.com + */ + +#ifndef __UDP +#define __UDP + +/** + * struct udp_ops - function to handle udp packet + * + * This structure provides the function to handle udp packet in + * the network loop. + * + * @prereq: callback called to check the requirement + * @start: callback called to start the protocol/feature + * @data: pointer to store private data (used by prereq and start) + */ +struct udp_ops { + int (*prereq)(void *data); + int (*start)(void *data); + void *data; +}; + +int udp_prereq(void); + +int udp_start(void); + +/** + * udp_loop() - network loop for udp protocol + * + * Launch a network loop for udp protocol and use callbacks + * provided in parameter @ops to initialize the loop, and then + * to handle udp packet. + * + * @ops: udp callback + * @return: 0 if success, otherwise < 0 on error + */ +int udp_loop(struct udp_ops *ops); + +#endif diff --git a/net/Kconfig b/net/Kconfig index 6874b55..1b3e420 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -8,6 +8,12 @@ menuconfig NET
if NET
+config PROT_UDP + bool "Enable generic udp framework" + help + Enable a generic udp framework that allows defining a custom + handler for udp protocol. + config BOOTP_SEND_HOSTNAME bool "Send hostname to DNS server" help diff --git a/net/Makefile b/net/Makefile index fef71b9..76527f7 100644 --- a/net/Makefile +++ b/net/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_CMD_SNTP) += sntp.o obj-$(CONFIG_CMD_TFTPBOOT) += tftp.o obj-$(CONFIG_UDP_FUNCTION_FASTBOOT) += fastboot.o obj-$(CONFIG_CMD_WOL) += wol.o +obj-$(CONFIG_PROT_UDP) += udp.o
# Disable this warning as it is triggered by: # sprintf(buf, index ? "foo%d" : "foo", index) diff --git a/net/net.c b/net/net.c index 28d9eeb..1ce0eb5 100644 --- a/net/net.c +++ b/net/net.c @@ -102,6 +102,7 @@ #if defined(CONFIG_CMD_PCAP) #include <net/pcap.h> #endif +#include <net/udp.h> #if defined(CONFIG_LED_STATUS) #include <miiphy.h> #include <status_led.h> @@ -544,6 +545,9 @@ restart: break; }
+ if (IS_ENABLED(CONFIG_PROT_UDP) && protocol == UDP) + udp_start(); + break; }
@@ -1364,6 +1368,13 @@ static int net_check_prereq(enum proto_t protocol) } goto common; #endif +#if defined(CONFIG_PROT_UDP) + case UDP: + if (udp_prereq()) + return 1; + goto common; +#endif + #if defined(CONFIG_CMD_NFS) case NFS: #endif @@ -1375,7 +1386,7 @@ static int net_check_prereq(enum proto_t protocol) return 1; } #if defined(CONFIG_CMD_PING) || defined(CONFIG_CMD_SNTP) || \ - defined(CONFIG_CMD_DNS) + defined(CONFIG_CMD_DNS) || defined(CONFIG_PROT_UDP) common: #endif /* Fall through */ diff --git a/net/udp.c b/net/udp.c new file mode 100644 index 0000000..a93822f --- /dev/null +++ b/net/udp.c @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 Philippe Reynes philippe.reynes@softathome.com + */ + +#include <common.h> +#include <net.h> +#include <net/udp.h> + +static struct udp_ops *udp_ops; + +int udp_prereq(void) +{ + int ret = 0; + + if (udp_ops->prereq) + ret = udp_ops->prereq(udp_ops->data); + + return ret; +} + +int udp_start(void) +{ + return udp_ops->start(udp_ops->data); +} + +int udp_loop(struct udp_ops *ops) +{ + int ret = -1; + + if (!ops) { + printf("%s: ops should not be null\n", __func__); + goto out; + } + + if (!ops->start) { + printf("%s: no start function defined\n", __func__); + goto out; + } + + udp_ops = ops; + ret = net_loop(UDP); + + out: + return ret; +}

This commit enable the support of the generic udp protocol.
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com Reviewed-by: Simon Glass sjg@chromium.org ---
Changelog: v4: - no change v3: - no change v2: - new patch in the serie
configs/sandbox_defconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 6e9f029..5ceff7d 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -102,6 +102,7 @@ CONFIG_ENV_IS_NOWHERE=y CONFIG_ENV_IS_IN_EXT4=y CONFIG_ENV_EXT4_INTERFACE="host" CONFIG_ENV_EXT4_DEVICE_AND_PART="0:0" +CONFIG_PROT_UDP=y CONFIG_BOOTP_SEND_HOSTNAME=y CONFIG_NETCONSOLE=y CONFIG_IP_DEFRAG=y

On Fri, Sep 18, 2020 at 02:13:01PM +0200, Philippe Reynes wrote:
This commit enable the support of the generic udp protocol.
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com Reviewed-by: Simon Glass sjg@chromium.org
Applied to u-boot/next, thanks!

This commits update the support of sntp to use the framework udp. This change allows to remove all the reference to sntp in the main network file net/net.c.
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com ---
Changelog: v4: - new patch in the serie
cmd/Kconfig | 1 + cmd/net.c | 10 +++++++++- include/net/sntp.h | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ net/net.c | 31 +---------------------------- net/sntp.c | 29 +++++++++++++++++++++++++-- net/sntp.h | 57 ----------------------------------------------------- 6 files changed, 96 insertions(+), 90 deletions(-) create mode 100644 include/net/sntp.h delete mode 100644 net/sntp.h
diff --git a/cmd/Kconfig b/cmd/Kconfig index 0761dbb..169c16a 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -1633,6 +1633,7 @@ config CMD_CDP
config CMD_SNTP bool "sntp" + select PROT_UDP help Synchronize RTC via network
diff --git a/cmd/net.c b/cmd/net.c index 9bbcdbc..beb2877 100644 --- a/cmd/net.c +++ b/cmd/net.c @@ -13,6 +13,8 @@ #include <env.h> #include <image.h> #include <net.h> +#include <net/udp.h> +#include <net/sntp.h>
static int netboot_common(enum proto_t, struct cmd_tbl *, int, char * const []);
@@ -356,6 +358,12 @@ U_BOOT_CMD( #endif
#if defined(CONFIG_CMD_SNTP) +static struct udp_ops sntp_ops = { + .prereq = sntp_prereq, + .start = sntp_start, + .data = NULL, +}; + int do_sntp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { char *toff; @@ -380,7 +388,7 @@ int do_sntp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) else net_ntp_time_offset = simple_strtol(toff, NULL, 10);
- if (net_loop(SNTP) < 0) { + if (udp_loop(&sntp_ops) < 0) { printf("SNTP failed: host %pI4 not responding\n", &net_ntp_server); return CMD_RET_FAILURE; diff --git a/include/net/sntp.h b/include/net/sntp.h new file mode 100644 index 0000000..30b44d1 --- /dev/null +++ b/include/net/sntp.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Masami Komiya mkomiya@sonare.it 2005 + */ + +#ifndef __SNTP_H__ +#define __SNTP_H__ + +#define NTP_SERVICE_PORT 123 +#define SNTP_PACKET_LEN 48 + + +/* Leap Indicator */ +#define NTP_LI_NOLEAP 0x0 +#define NTP_LI_61SECS 0x1 +#define NTP_LI_59SECS 0x2 +#define NTP_LI_ALARM 0x3 + +/* Version */ + +#define NTP_VERSION 4 + +/* Mode */ +#define NTP_MODE_RESERVED 0 +#define NTP_MODE_SYMACTIVE 1 /* Symmetric Active */ +#define NTP_MODE_SYMPASSIVE 2 /* Symmetric Passive */ +#define NTP_MODE_CLIENT 3 +#define NTP_MODE_SERVER 4 +#define NTP_MODE_BROADCAST 5 +#define NTP_MODE_NTPCTRL 6 /* Reserved for NTP control message */ +#define NTP_MODE_PRIVATE 7 /* Reserved for private use */ + +struct sntp_pkt_t { +#if __LITTLE_ENDIAN + uchar mode:3; + uchar vn:3; + uchar li:2; +#else + uchar li:2; + uchar vn:3; + uchar mode:3; +#endif + uchar stratum; + uchar poll; + uchar precision; + uint root_delay; + uint root_dispersion; + uint reference_id; + unsigned long long reference_timestamp; + unsigned long long originate_timestamp; + unsigned long long receive_timestamp; + unsigned long long transmit_timestamp; +} __attribute__((packed)); + +int sntp_prereq(void *data); +int sntp_start(void *data); /* Begin SNTP */ + +#endif /* __SNTP_H__ */ diff --git a/net/net.c b/net/net.c index 1ce0eb5..197fde3 100644 --- a/net/net.c +++ b/net/net.c @@ -72,12 +72,6 @@ * We want: - load the boot file * Next step: none * - * SNTP: - * - * Prerequisites: - own ethernet address - * - own IP address - * We want: - network time - * Next step: none * * WOL: * @@ -119,9 +113,6 @@ #include "nfs.h" #include "ping.h" #include "rarp.h" -#if defined(CONFIG_CMD_SNTP) -#include "sntp.h" -#endif #if defined(CONFIG_CMD_WOL) #include "wol.h" #endif @@ -185,13 +176,6 @@ u32 net_boot_file_size; /* Boot file size in blocks as reported by the DHCP server */ u32 net_boot_file_expected_size_in_blocks;
-#if defined(CONFIG_CMD_SNTP) -/* NTP server IP address */ -struct in_addr net_ntp_server; -/* offset time from UTC */ -int net_ntp_time_offset; -#endif - static uchar net_pkt_buf[(PKTBUFSRX+1) * PKTSIZE_ALIGN + PKTALIGN]; /* Receive packets */ uchar *net_rx_packets[PKTBUFSRX]; @@ -521,11 +505,6 @@ restart: nc_start(); break; #endif -#if defined(CONFIG_CMD_SNTP) - case SNTP: - sntp_start(); - break; -#endif #if defined(CONFIG_CMD_DNS) case DNS: dns_start(); @@ -1352,14 +1331,6 @@ static int net_check_prereq(enum proto_t protocol) } goto common; #endif -#if defined(CONFIG_CMD_SNTP) - case SNTP: - if (net_ntp_server.s_addr == 0) { - puts("*** ERROR: NTP server address not given\n"); - return 1; - } - goto common; -#endif #if defined(CONFIG_CMD_DNS) case DNS: if (net_dns_server.s_addr == 0) { @@ -1385,7 +1356,7 @@ static int net_check_prereq(enum proto_t protocol) puts("*** ERROR: `serverip' not set\n"); return 1; } -#if defined(CONFIG_CMD_PING) || defined(CONFIG_CMD_SNTP) || \ +#if defined(CONFIG_CMD_PING) || \ defined(CONFIG_CMD_DNS) || defined(CONFIG_PROT_UDP) common: #endif diff --git a/net/sntp.c b/net/sntp.c index 39d7664..d5d5671 100644 --- a/net/sntp.c +++ b/net/sntp.c @@ -12,12 +12,17 @@ #include <net.h> #include <rtc.h>
-#include "sntp.h" +#include <net/sntp.h>
#define SNTP_TIMEOUT 10000UL
static int sntp_our_port;
+/* NTP server IP address */ +struct in_addr net_ntp_server; +/* offset time from UTC */ +int net_ntp_time_offset; + static void sntp_send(void) { struct sntp_pkt_t pkt; @@ -93,7 +98,25 @@ static void sntp_handler(uchar *pkt, unsigned dest, struct in_addr sip, net_set_state(NETLOOP_SUCCESS); }
-void sntp_start(void) +/* + * SNTP: + * + * Prerequisites: - own ethernet address + * - own IP address + * We want: - network time + * Next step: none + */ +int sntp_prereq(void *data) +{ + if (net_ntp_server.s_addr == 0) { + puts("*** ERROR: NTP server address not given\n"); + return 1; + } + + return 0; +} + +int sntp_start(void *data) { debug("%s\n", __func__);
@@ -102,4 +125,6 @@ void sntp_start(void) memset(net_server_ethaddr, 0, sizeof(net_server_ethaddr));
sntp_send(); + + return 0; } diff --git a/net/sntp.h b/net/sntp.h deleted file mode 100644 index d3cbfbc..0000000 --- a/net/sntp.h +++ /dev/null @@ -1,57 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * (C) Masami Komiya mkomiya@sonare.it 2005 - */ - -#ifndef __SNTP_H__ -#define __SNTP_H__ - -#define NTP_SERVICE_PORT 123 -#define SNTP_PACKET_LEN 48 - - -/* Leap Indicator */ -#define NTP_LI_NOLEAP 0x0 -#define NTP_LI_61SECS 0x1 -#define NTP_LI_59SECS 0x2 -#define NTP_LI_ALARM 0x3 - -/* Version */ - -#define NTP_VERSION 4 - -/* Mode */ -#define NTP_MODE_RESERVED 0 -#define NTP_MODE_SYMACTIVE 1 /* Symmetric Active */ -#define NTP_MODE_SYMPASSIVE 2 /* Symmetric Passive */ -#define NTP_MODE_CLIENT 3 -#define NTP_MODE_SERVER 4 -#define NTP_MODE_BROADCAST 5 -#define NTP_MODE_NTPCTRL 6 /* Reserved for NTP control message */ -#define NTP_MODE_PRIVATE 7 /* Reserved for private use */ - -struct sntp_pkt_t { -#if __LITTLE_ENDIAN - uchar mode:3; - uchar vn:3; - uchar li:2; -#else - uchar li:2; - uchar vn:3; - uchar mode:3; -#endif - uchar stratum; - uchar poll; - uchar precision; - uint root_delay; - uint root_dispersion; - uint reference_id; - unsigned long long reference_timestamp; - unsigned long long originate_timestamp; - unsigned long long receive_timestamp; - unsigned long long transmit_timestamp; -} __attribute__((packed)); - -void sntp_start(void); /* Begin SNTP */ - -#endif /* __SNTP_H__ */

Hi Philippe,
On Fri, 18 Sep 2020 at 06:13, Philippe Reynes philippe.reynes@softathome.com wrote:
This commits update the support of sntp to use the framework udp. This change allows to remove all the reference to sntp in the main network file net/net.c.
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com
Changelog: v4:
- new patch in the serie
cmd/Kconfig | 1 + cmd/net.c | 10 +++++++++- include/net/sntp.h | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ net/net.c | 31 +---------------------------- net/sntp.c | 29 +++++++++++++++++++++++++-- net/sntp.h | 57 ----------------------------------------------------- 6 files changed, 96 insertions(+), 90 deletions(-) create mode 100644 include/net/sntp.h delete mode 100644 net/sntp.h
Reviewed-by: Simon Glass sjg@chromium.org
I wonder if we should use driver model to have a network-protocol uclass?
Regards, Simon

On Fri, Sep 18, 2020 at 02:13:02PM +0200, Philippe Reynes wrote:
This commits update the support of sntp to use the framework udp. This change allows to remove all the reference to sntp in the main network file net/net.c.
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com Reviewed-by: Simon Glass sjg@chromium.org
Applied to u-boot/next, thanks!

On Fri, Sep 18, 2020 at 02:13:00PM +0200, Philippe Reynes wrote:
This commit adds a generic udp protocol framework in the network loop. So protocol based on udp may be implemented without modifying the network loop (for example custom wait magic packet).
Signed-off-by: Philippe Reynes philippe.reynes@softathome.com Reviewed-by: Simon Glass sjg@chromium.org
Applied to u-boot/next, thanks!
participants (3)
-
Philippe Reynes
-
Simon Glass
-
Tom Rini