diff --git a/net/devif/ipv6_forward.c b/net/devif/ipv6_forward.c index aaaf1dfd115..2c3d0a82658 100644 --- a/net/devif/ipv6_forward.c +++ b/net/devif/ipv6_forward.c @@ -166,7 +166,7 @@ static int ipv6_packet_conversion(FAR struct net_driver_s *dev, static int ipv6_hdrsize(FAR struct ipv6_hdr_s *ipv6) { - /* Copy the following protocol header, */ + /* Size is determined by the following protocol header, */ switch (ipv6->proto) { @@ -211,27 +211,20 @@ static int ipv6_hdrsize(FAR struct ipv6_hdr_s *ipv6) * Description: * Set up to forward the UDP or ICMPv6 packet on the specified device. * This function will set up a send "interrupt" handler that will perform - * the actual send asynchronously. + * the actual send asynchronously and must return without waiting for the + * send to complete. * * Input Parameters: - * dev - The device on which the packet was received and which contains - * the IPv6 packet. - * ipv6 - A convenience pointer to the IPv6 header in within the IPv6 - * packet. This is immeidately followed by the L3 header which may - * be UDP or ICMPv6. + * dev - The device on which the packet should be forwarded. + * ipv6 - A pointer to the IPv6 header in within the IPv6 packet. This + * is immeidately followed by the L3 header which may be UDP or + * ICMPv6. * iob - A list of IOBs containing the data payload to be sent. * - * - * On input: - * - dev->d_buf holds the received packet. - * - dev->d_len holds the length of the received packet MINUS the - * size of the L1 header. That was subtracted out by ipv6_input. - * - ipv6 points to the IPv6 header with dev->d_buf. - * * Returned Value: - * Zero is returned if the packet was successfully forward; A negated + * Zero is returned if the packet was successfully forwarded; A negated * errno value is returned if the packet is not forwardable. In that - * latter case, the caller (ipv6_input()) should drop the packet. + * latter case, the caller should free the IOB list and drop the packet. * ****************************************************************************/ @@ -242,9 +235,7 @@ static int ipv6_dev_forward(FAR struct net_driver_s *dev, { /* Notify the forwarding device that TX data is available */ - /* Set up to send the packet when the selected device polls for TX data. - * If the packet is TCP, it must obey ACK and windowing rules. - */ + /* Set up to send the packet when the selected device polls for TX data. */ #warning Missing logic @@ -252,12 +243,9 @@ static int ipv6_dev_forward(FAR struct net_driver_s *dev, * - source MAC, the MAC of the current device. * - dest MAC, the MAC associated with the destination IPv6 adress. * This will involve ICMPv6 and Neighbor Discovery. - * - Because of TCP window, the packet may have to be sent in smaller - * pieces. */ -# warning Missing logic - nwarn("WARNING: UPD/ICMPv6 packet forwarding not yet supported\n"); + nwarn("WARNING: UPD/ICMPv6 packet forwarding not yet supported\n"); return -ENOSYS; } #endif @@ -280,11 +268,31 @@ static int ipv6_dev_forward(FAR struct net_driver_s *dev, #ifdef CONFIG_NET_STATISTICS static void ipv6_dropstats(FAR struct ipv6_hdr_s *ipv) { -g_netstats.icmpv6.drop++ -g_netstats.udp.drop++; -g_netstats.tcp.drop++; + switch (ipv6->proto) + { +#ifdef CONFIG_NET_TCP + case IP_PROTO_TCP: + g_netstats.tcp.drop++; + break; +#endif -g_netstats.ipv6.drop++ +#ifdef CONFIG_NET_UDP + case IP_PROTO_UDP: + g_netstats.udp.drop++; + break; +#endif + +#ifdef CONFIG_NET_ICMPv6 + case IP_PROTO_ICMP6: + g_netstats.icmpv6.drop++ + break; +#endif + + default: + break; + } + + g_netstats.ipv6.drop++ } #else # define ipv6_dropstats(ipv6) @@ -410,11 +418,11 @@ int ipv6_forward(FAR struct net_driver_s *dev, FAR struct ipv6_hdr_s *ipv6) if (ipv6->proto == IP_PROTO_TCP) { - ret = tcp_ipv6_forward(dev, ipv6, iob); + ret = tcp_ipv6_forward(fwddev, ipv6, iob); } else { - ret = ipv6_dev_forward(dev, ipv6, iob); + ret = ipv6_dev_forward(fwddev, ipv6, iob); } if (ret >= 0) diff --git a/net/tcp/Make.defs b/net/tcp/Make.defs index 29b6167a65f..f9e7c893882 100644 --- a/net/tcp/Make.defs +++ b/net/tcp/Make.defs @@ -60,6 +60,12 @@ NET_CSRCS += tcp_conn.c tcp_seqno.c tcp_devpoll.c tcp_finddev.c tcp_timer.c NET_CSRCS += tcp_send.c tcp_input.c tcp_appsend.c tcp_listen.c NET_CSRCS += tcp_callback.c tcp_backlog.c tcp_ipselect.c +# IP forwarding + +ifeq ($(CONFIG_NET_IPFORWARD),y) +NET_CSRCS += tcp_forward.c +endif + # TCP write buffering ifeq ($(CONFIG_NET_TCP_WRITE_BUFFERS),y) diff --git a/net/tcp/tcp.h b/net/tcp/tcp.h index 83891b10244..a56068b147f 100644 --- a/net/tcp/tcp.h +++ b/net/tcp/tcp.h @@ -794,6 +794,34 @@ int tcp_accept_connection(FAR struct net_driver_s *dev, void tcp_send(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn, uint16_t flags, uint16_t len); +/**************************************************************************** + * Name: tcp_ipv6_forward + * + * Description: + * Set up to forward the TCP packet on the specified device. This + * function will set up a send "interrupt" handler that will perform + * the actual send asynchronously and must return without waiting for the + * send to complete. + * + * Input Parameters: + * dev - The device on which the packet should be forwarded. + * ipv6 - A pointer to the IPv6 header in within the IPv6 packet. This + * is immeidately followed by the TCP header. + * iob - A list of IOBs containing the data payload to be sent. + * + * Returned Value: + * Zero is returned if the packet was successfully forwarded; A negated + * errno value is returned if the packet is not forwardable. In that + * latter case, the caller should free the IOB list and drop the packet. + * + ****************************************************************************/ + +#if defined(CONFIG_NET_IPFORWARD) && defined(CONFIG_NET_IPv6) && \ + defined(CONFIG_NETDEV_MULTINIC) +int tcp_ipv6_forward(FAR struct net_driver_s *dev, + FAR struct ipv6_hdr_s *ipv6, FAR struct iob_s *iob); +#endif + /**************************************************************************** * Name: tcp_reset * diff --git a/net/tcp/tcp_forward.c b/net/tcp/tcp_forward.c new file mode 100644 index 00000000000..11972242291 --- /dev/null +++ b/net/tcp/tcp_forward.c @@ -0,0 +1,101 @@ +/**************************************************************************** + * net/tcp/tcp_forward.c + * + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include + +#include "tcp/tcp.h" + +#if defined(CONFIG_NET) && defined(CONFIG_NET_IPFORWARD) && defined(CONFIG_NET_TCP) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tcp_ipv6_forward + * + * Description: + * Set up to forward the TCP packet on the specified device. This + * function will set up a send "interrupt" handler that will perform + * the actual send asynchronously and must return without waiting for the + * send to complete. + * + * Input Parameters: + * dev - The device on which the packet should be forwarded. + * ipv6 - A pointer to the IPv6 header in within the IPv6 packet. This + * is immeidately followed by the TCP header. + * iob - A list of IOBs containing the data payload to be sent. + * + * Returned Value: + * Zero is returned if the packet was successfully forwarded; A negated + * errno value is returned if the packet is not forwardable. In that + * latter case, the caller should free the IOB list and drop the packet. + * + ****************************************************************************/ + +#if defined(CONFIG_NET_IPv6) && defined(CONFIG_NETDEV_MULTINIC) +int tcp_ipv6_forward(FAR struct net_driver_s *dev, + FAR struct ipv6_hdr_s *ipv6, FAR struct iob_s *iob) +{ + /* Notify the forwarding device that TX data is available */ + + /* Set up to send the packet when the selected device polls for TX data. + * TCP packets must obey ACK and windowing rules. + */ + +#warning Missing logic + + /* REVISIT: For Ethernet we may have to fix up the Ethernet header: + * - source MAC, the MAC of the current device. + * - dest MAC, the MAC associated with the destination IPv6 adress. + * This will involve ICMPv6 and Neighbor Discovery. + * - Because of TCP window, the packet may have to be sent in smaller + * pieces. + */ + + nwarn("WARNING: TCP packet forwarding not yet supported\n"); + return -ENOSYS; +} +#endif /* CONFIG_NET_IPv6 && CONFIG_NETDEV_MULTINIC */ +#endif /* CONFIG_NET && CONFIG_NET_IPFORWARD && CONFIG_NET_TCP */