[U-Boot] [PATCH] This patch is the Interfaces changes for, net.h, net.c, ping.c files for introducing TCP and wget into u-boot.
DH at synoia.com
DH at synoia.com
Wed Feb 28 23:48:22 UTC 2018
From: Duncan Hare <DuncanCHare at yahoo.com>
All the code is new, and not copied from any source.
>>>>>
<<<<
Commit-notes
Why netboot:
Central management, including logs and change control,
coupled with with enhanced security and unauthorized
change detection and remediation by exposing a
small attack surface.
Why TCP:
Currently file transfer are done using tftp or NFS both
over udp. This requires a request to be sent from client
(u-boot) to the boot server.
For a 4 Mbyte kernel, with a 1k block size this requires
4,000 request for a block.
Using a large block size, one greater than the Ethernet
maximum frame size limitation, would require fragmentation,
which u-boot supports. However missing fragment recovery
requires timeout detection and re-transmission requests
for missing fragments.
UDP is ideally suited to fast single packet exchanges,
inquiry/response, for example dns, becuse of the lack of
connection overhead.
UDP as a file transport mechanism is slow, even in low
latency networks, because file transfer with udp requires
poll/response mechanism to provide transfer integrity.
In networks with large latency, for example: the internet,
UDP is even slower. What is a 30 second transfer on a local
boot server and LAN increase to over 3 minutes, because of
all the requests/response traffic.
This was anticipated in the evolution of the IP protocols
and TCP was developed and then enhanced for high latency high
bandwidth networks.
The current standard is TCP with selective acknowledgment.
In our testing we have reduce kernel transmission time to
around 0.4 seconds for a 4Mbyte kernel, with a 100 Mbps
downlink.
Why http and wget:
HTTP is the most efficient file retrieval protocol in common
use. The client send a single request, after TCP connection,
to receive a file of any length.
WGET is the application which implements http file transfer
outside browsers as a file transfer protocol. Versions of
wget exists on many operating systems.
END
Signed-off-by: Duncan Hare <DuncanCHare at yahoo.com>
---
Changes in v7:
Revised to meet patch review
Patch 1 Interfaces
patch 2 TCP
Patch 3 wget
include/net.h | 25 +++++++++++++++++++------
net/net.c | 10 +++++++---
net/ping.c | 9 ++-------
3 files changed, 28 insertions(+), 16 deletions(-)
diff --git a/include/net.h b/include/net.h
index 455b48f6c7..7e5f5a6a5b 100644
--- a/include/net.h
+++ b/include/net.h
@@ -15,17 +15,26 @@
#include <asm/cache.h>
#include <asm/byteorder.h> /* for nton* / ntoh* stuff */
-#define DEBUG_LL_STATE 0 /* Link local state machine changes */
-#define DEBUG_DEV_PKT 0 /* Packets or info directed to the device */
-#define DEBUG_NET_PKT 0 /* Packets on info on the network at large */
+#define DEBUG_LL_STATE 0 /* Link local state machine changes */
+#define DEBUG_DEV_PKT 0 /* Packets or info directed to the device */
+#define DEBUG_NET_PKT 0 /* Packets on info on the network at large */
#define DEBUG_INT_STATE 0 /* Internal network state changes */
/*
* The number of receive packet buffers, and the required packet buffer
* alignment in memory.
*
+ * The number of buffers for TCP is used to calculate a static TCP window
+ * size, becuse TCP window size is a promise to the sending TCP to be able
+ * to buffer up to the window size of data.
+ * When the sending TCP has a window size of outstanding unacknowledged
+ * data, the sending TCP will stop sending.
*/
+#if defined(CONFIG_TCP)
+#define CONFIG_SYS_RX_ETH_BUFFER 12 /* For TCP */
+#endif
+
#ifdef CONFIG_SYS_RX_ETH_BUFFER
# define PKTBUFSRX CONFIG_SYS_RX_ETH_BUFFER
#else
@@ -354,6 +363,7 @@ struct vlan_ethernet_hdr {
#define IPPROTO_ICMP 1 /* Internet Control Message Protocol */
#define IPPROTO_UDP 17 /* User Datagram Protocol */
+#define IPPROTO_TCP 6 /* Transmission Control Protocol */
/*
* Internet Protocol (IP) header.
@@ -596,10 +606,10 @@ int net_set_ether(uchar *xet, const uchar *dest_ethaddr, uint prot);
int net_update_ether(struct ethernet_hdr *et, uchar *addr, uint prot);
/* Set IP header */
-void net_set_ip_header(uchar *pkt, struct in_addr dest, struct in_addr source);
+void net_set_ip_header(uchar *pkt, struct in_addr dest, struct in_addr source,
+ u16 pkt_len, u8 prot);
void net_set_udp_header(uchar *pkt, struct in_addr dest, int dport,
- int sport, int len);
-
+ int sport, int len);
/**
* compute_ip_checksum() - Compute IP checksum
*
@@ -670,6 +680,9 @@ static inline void net_send_packet(uchar *pkt, int len)
* @param sport Source UDP port
* @param payload_len Length of data after the UDP header
*/
+int net_send_ip_packet(uchar *ether, struct in_addr dest, int dport, int sport,
+ int payload_len, int proto);
+
int net_send_udp_packet(uchar *ether, struct in_addr dest, int dport,
int sport, int payload_len);
diff --git a/net/net.c b/net/net.c
index 4259c9e321..26aab1f30f 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1426,7 +1426,9 @@ int net_update_ether(struct ethernet_hdr *et, uchar *addr, uint prot)
}
}
-void net_set_ip_header(uchar *pkt, struct in_addr dest, struct in_addr source)
+void net_set_ip_header(uchar *pkt, struct in_addr dest, struct in_addr source,
+ u16 pkt_len, u8 prot)
+
{
struct ip_udp_hdr *ip = (struct ip_udp_hdr *)pkt;
@@ -1436,10 +1438,11 @@ void net_set_ip_header(uchar *pkt, struct in_addr dest, struct in_addr source)
/* IP_HDR_SIZE / 4 (not including UDP) */
ip->ip_hl_v = 0x45;
ip->ip_tos = 0;
- ip->ip_len = htons(IP_HDR_SIZE);
+ ip->ip_len = htons(pkt_len);
ip->ip_id = htons(net_ip_id++);
ip->ip_off = htons(IP_FLAGS_DFRAG); /* Don't fragment */
ip->ip_ttl = 255;
+ ip->ip_p = prot;
ip->ip_sum = 0;
/* already in network byte order */
net_copy_ip((void *)&ip->ip_src, &source);
@@ -1460,7 +1463,8 @@ void net_set_udp_header(uchar *pkt, struct in_addr dest, int dport, int sport,
if (len & 1)
pkt[IP_UDP_HDR_SIZE + len] = 0;
- net_set_ip_header(pkt, dest, net_ip);
+ net_set_ip_header(pkt, dest, net_ip, IP_UDP_HDR_SIZE + len,
+ IPPROTO_UDP);
ip->ip_len = htons(IP_UDP_HDR_SIZE + len);
ip->ip_p = IPPROTO_UDP;
ip->ip_sum = compute_ip_checksum(ip, IP_HDR_SIZE);
diff --git a/net/ping.c b/net/ping.c
index 9508cf1160..254b646193 100644
--- a/net/ping.c
+++ b/net/ping.c
@@ -20,16 +20,11 @@ struct in_addr net_ping_ip;
static void set_icmp_header(uchar *pkt, struct in_addr dest)
{
/*
- * Construct an IP and ICMP header.
+ * Construct an ICMP header.
*/
- struct ip_hdr *ip = (struct ip_hdr *)pkt;
struct icmp_hdr *icmp = (struct icmp_hdr *)(pkt + IP_HDR_SIZE);
- net_set_ip_header(pkt, dest, net_ip);
-
- ip->ip_len = htons(IP_ICMP_HDR_SIZE);
- ip->ip_p = IPPROTO_ICMP;
- ip->ip_sum = compute_ip_checksum(ip, IP_HDR_SIZE);
+ net_set_ip_header(pkt, dest, net_ip, IP_ICMP_HDR_SIZE, IPPROTO_ICMP);
icmp->type = ICMP_ECHO_REQUEST;
icmp->code = 0;
--
2.11.0
More information about the U-Boot
mailing list