net: add a generic udp protocol
authorPhilippe Reynes <philippe.reynes@softathome.com>
Fri, 18 Sep 2020 12:13:00 +0000 (14:13 +0200)
committerTom Rini <trini@konsulko.com>
Wed, 30 Sep 2020 20:55:03 +0000 (16:55 -0400)
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>
doc/README.udp [new file with mode: 0644]
include/net.h
include/net/udp.h [new file with mode: 0644]
net/Kconfig
net/Makefile
net/net.c
net/udp.c [new file with mode: 0644]

diff --git a/doc/README.udp b/doc/README.udp
new file mode 100644 (file)
index 0000000..da07257
--- /dev/null
@@ -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);
index 1bf9867..2191071 100644 (file)
@@ -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 (file)
index 0000000..2ae56e8
--- /dev/null
@@ -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
index 6874b55..1b3e420 100644 (file)
@@ -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
index fef71b9..76527f7 100644 (file)
@@ -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)
index 28d9eeb..1ce0eb5 100644 (file)
--- a/net/net.c
+++ b/net/net.c
 #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 (file)
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;
+}