From 6bf36f57a0f7a22ffa85ae4995933077df62e309 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Sun, 1 Sep 2013 20:55:18 +0100 Subject: [PATCH] [tcpip] Pass through network device to transport layer protocols NDP requires knowledge of the network device on which a packet was received. Signed-off-by: Michael Brown --- src/include/ipxe/tcpip.h | 8 +++++--- src/net/icmp.c | 5 ++++- src/net/icmpv6.c | 2 +- src/net/ipv4.c | 2 +- src/net/ipv6.c | 7 ++++--- src/net/tcp.c | 2 ++ src/net/tcpip.c | 8 +++++--- src/net/udp.c | 5 ++++- 8 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/include/ipxe/tcpip.h b/src/include/ipxe/tcpip.h index 0cc688a9..b2c559e2 100644 --- a/src/include/ipxe/tcpip.h +++ b/src/include/ipxe/tcpip.h @@ -69,6 +69,7 @@ struct tcpip_protocol { * Process received packet * * @v iobuf I/O buffer + * @v netdev Network device * @v st_src Partially-filled source address * @v st_dest Partially-filled destination address * @v pshdr_csum Pseudo-header checksum @@ -76,7 +77,8 @@ struct tcpip_protocol { * * This method takes ownership of the I/O buffer. */ - int ( * rx ) ( struct io_buffer *iobuf, struct sockaddr_tcpip *st_src, + int ( * rx ) ( struct io_buffer *iobuf, struct net_device *netdev, + struct sockaddr_tcpip *st_src, struct sockaddr_tcpip *st_dest, uint16_t pshdr_csum ); /** * Transport-layer protocol number @@ -128,8 +130,8 @@ struct tcpip_net_protocol { /** Declare a TCP/IP network-layer protocol */ #define __tcpip_net_protocol __table_entry ( TCPIP_NET_PROTOCOLS, 01 ) -extern int tcpip_rx ( struct io_buffer *iobuf, uint8_t tcpip_proto, - struct sockaddr_tcpip *st_src, +extern int tcpip_rx ( struct io_buffer *iobuf, struct net_device *netdev, + uint8_t tcpip_proto, struct sockaddr_tcpip *st_src, struct sockaddr_tcpip *st_dest, uint16_t pshdr_csum ); extern int tcpip_tx ( struct io_buffer *iobuf, struct tcpip_protocol *tcpip, struct sockaddr_tcpip *st_src, diff --git a/src/net/icmp.c b/src/net/icmp.c index 830d8292..6142b748 100644 --- a/src/net/icmp.c +++ b/src/net/icmp.c @@ -38,12 +38,15 @@ struct tcpip_protocol icmp_protocol __tcpip_protocol; * Process a received packet * * @v iobuf I/O buffer + * @v netdev Network device * @v st_src Partially-filled source address * @v st_dest Partially-filled destination address * @v pshdr_csum Pseudo-header checksum * @ret rc Return status code */ -static int icmp_rx ( struct io_buffer *iobuf, struct sockaddr_tcpip *st_src, +static int icmp_rx ( struct io_buffer *iobuf, + struct net_device *netdev __unused, + struct sockaddr_tcpip *st_src, struct sockaddr_tcpip *st_dest, uint16_t pshdr_csum __unused ) { struct icmp_header *icmp = iobuf->data; diff --git a/src/net/icmpv6.c b/src/net/icmpv6.c index 262ffc3f..72423806 100644 --- a/src/net/icmpv6.c +++ b/src/net/icmpv6.c @@ -69,7 +69,7 @@ int icmp6_send_solicit ( struct net_device *netdev, struct in6_addr *src __unuse * @v st_src Source address * @v st_dest Destination address */ -static int icmp6_rx ( struct io_buffer *iobuf, struct sockaddr_tcpip *st_src, +static int icmp6_rx ( struct io_buffer *iobuf, struct net_device *netdev __unused, struct sockaddr_tcpip *st_src, struct sockaddr_tcpip *st_dest, __unused uint16_t pshdr_csum ) { struct icmp6_header *icmp6hdr = iobuf->data; diff --git a/src/net/ipv4.c b/src/net/ipv4.c index 106e8e79..bd318806 100644 --- a/src/net/ipv4.c +++ b/src/net/ipv4.c @@ -469,7 +469,7 @@ static int ipv4_rx ( struct io_buffer *iobuf, dest.sin.sin_addr = iphdr->dest; pshdr_csum = ipv4_pshdr_chksum ( iobuf, TCPIP_EMPTY_CSUM ); iob_pull ( iobuf, hdrlen ); - if ( ( rc = tcpip_rx ( iobuf, iphdr->protocol, &src.st, + if ( ( rc = tcpip_rx ( iobuf, netdev, iphdr->protocol, &src.st, &dest.st, pshdr_csum ) ) != 0 ) { DBGC ( src.sin.sin_addr, "IPv4 received packet rejected by " "stack: %s\n", strerror ( rc ) ); diff --git a/src/net/ipv6.c b/src/net/ipv6.c index d76e59cb..077118df 100644 --- a/src/net/ipv6.c +++ b/src/net/ipv6.c @@ -260,7 +260,8 @@ static int ipv6_tx ( struct io_buffer *iobuf, * * Refer http://www.iana.org/assignments/ipv6-parameters for the numbers */ -static int ipv6_process_nxt_hdr ( struct io_buffer *iobuf, uint8_t nxt_hdr, +static int ipv6_process_nxt_hdr ( struct io_buffer *iobuf, + struct net_device *netdev, uint8_t nxt_hdr, struct sockaddr_tcpip *src, struct sockaddr_tcpip *dest ) { switch ( nxt_hdr ) { case IP6_HOPBYHOP: @@ -278,7 +279,7 @@ static int ipv6_process_nxt_hdr ( struct io_buffer *iobuf, uint8_t nxt_hdr, return 0; } /* Next header is not a IPv6 extension header */ - return tcpip_rx ( iobuf, nxt_hdr, src, dest, 0 /* fixme */ ); + return tcpip_rx ( iobuf, netdev, nxt_hdr, src, dest, 0 /* fixme */ ); } /** @@ -344,7 +345,7 @@ static int ipv6_rx ( struct io_buffer *iobuf, iob_pull ( iobuf, sizeof ( *ip6hdr ) ); /* Send it to the transport layer */ - return ipv6_process_nxt_hdr ( iobuf, ip6hdr->nxt_hdr, &src.st, &dest.st ); + return ipv6_process_nxt_hdr ( iobuf, netdev, ip6hdr->nxt_hdr, &src.st, &dest.st ); drop: DBG ( "Packet dropped\n" ); diff --git a/src/net/tcp.c b/src/net/tcp.c index 0e18c831..1e1968a0 100644 --- a/src/net/tcp.c +++ b/src/net/tcp.c @@ -1115,12 +1115,14 @@ static void tcp_process_rx_queue ( struct tcp_connection *tcp ) { * Process received packet * * @v iobuf I/O buffer + * @v netdev Network device * @v st_src Partially-filled source address * @v st_dest Partially-filled destination address * @v pshdr_csum Pseudo-header checksum * @ret rc Return status code */ static int tcp_rx ( struct io_buffer *iobuf, + struct net_device *netdev __unused, struct sockaddr_tcpip *st_src, struct sockaddr_tcpip *st_dest __unused, uint16_t pshdr_csum ) { diff --git a/src/net/tcpip.c b/src/net/tcpip.c index 721a4e48..0e467144 100644 --- a/src/net/tcpip.c +++ b/src/net/tcpip.c @@ -20,6 +20,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); /** Process a received TCP/IP packet * * @v iobuf I/O buffer + * @v netdev Network device * @v tcpip_proto Transport-layer protocol number * @v st_src Partially-filled source address * @v st_dest Partially-filled destination address @@ -32,8 +33,8 @@ FILE_LICENCE ( GPL2_OR_LATER ); * address family and the network-layer addresses, but leave the ports * and the rest of the structures as zero). */ -int tcpip_rx ( struct io_buffer *iobuf, uint8_t tcpip_proto, - struct sockaddr_tcpip *st_src, +int tcpip_rx ( struct io_buffer *iobuf, struct net_device *netdev, + uint8_t tcpip_proto, struct sockaddr_tcpip *st_src, struct sockaddr_tcpip *st_dest, uint16_t pshdr_csum ) { struct tcpip_protocol *tcpip; @@ -42,7 +43,8 @@ int tcpip_rx ( struct io_buffer *iobuf, uint8_t tcpip_proto, for_each_table_entry ( tcpip, TCPIP_PROTOCOLS ) { if ( tcpip->tcpip_proto == tcpip_proto ) { DBG ( "TCP/IP received %s packet\n", tcpip->name ); - return tcpip->rx ( iobuf, st_src, st_dest, pshdr_csum ); + return tcpip->rx ( iobuf, netdev, st_src, st_dest, + pshdr_csum ); } } diff --git a/src/net/udp.c b/src/net/udp.c index edc7488a..596f242a 100644 --- a/src/net/udp.c +++ b/src/net/udp.c @@ -247,12 +247,15 @@ static struct udp_connection * udp_demux ( struct sockaddr_tcpip *local ) { * Process a received packet * * @v iobuf I/O buffer + * @v netdev Network device * @v st_src Partially-filled source address * @v st_dest Partially-filled destination address * @v pshdr_csum Pseudo-header checksum * @ret rc Return status code */ -static int udp_rx ( struct io_buffer *iobuf, struct sockaddr_tcpip *st_src, +static int udp_rx ( struct io_buffer *iobuf, + struct net_device *netdev __unused, + struct sockaddr_tcpip *st_src, struct sockaddr_tcpip *st_dest, uint16_t pshdr_csum ) { struct udp_header *udphdr = iobuf->data; struct udp_connection *udp;