summaryrefslogtreecommitdiffstats
path: root/src/net/tcpip.c
diff options
context:
space:
mode:
authorMichael Brown2014-03-04 13:54:21 +0100
committerMichael Brown2014-03-04 14:02:58 +0100
commitdb67de6f31a062dc1995d4561be83cd51609d6c4 (patch)
tree642ebb50e33c2a720d40769dd59010ce0d5b8e05 /src/net/tcpip.c
parent[prefix] Ignore PCI autoboot device location if set to 00:00.0 (diff)
downloadipxe-db67de6f31a062dc1995d4561be83cd51609d6c4.tar.gz
ipxe-db67de6f31a062dc1995d4561be83cd51609d6c4.tar.xz
ipxe-db67de6f31a062dc1995d4561be83cd51609d6c4.zip
[tcpip] Provide tcpip_netdev() to determine the transmitting network device
Provide the function tcpip_netdev() to allow external code to determine the transmitting network device for a given socket address. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/net/tcpip.c')
-rw-r--r--src/net/tcpip.c56
1 files changed, 46 insertions, 10 deletions
diff --git a/src/net/tcpip.c b/src/net/tcpip.c
index 0b2adfd9..6fac8c52 100644
--- a/src/net/tcpip.c
+++ b/src/net/tcpip.c
@@ -18,7 +18,8 @@
FILE_LICENCE ( GPL2_OR_LATER );
-/** Process a received TCP/IP packet
+/**
+ * Process a received TCP/IP packet
*
* @v iobuf I/O buffer
* @v netdev Network device
@@ -57,7 +58,27 @@ int tcpip_rx ( struct io_buffer *iobuf, struct net_device *netdev,
return -EPROTONOSUPPORT;
}
-/** Transmit a TCP/IP packet
+/**
+ * Find TCP/IP network-layer protocol
+ *
+ * @v st_dest Destination address
+ * @ret tcpip_net TCP/IP network-layer protocol, or NULL if not found
+ */
+static struct tcpip_net_protocol *
+tcpip_net_protocol ( struct sockaddr_tcpip *st_dest ) {
+ struct tcpip_net_protocol *tcpip_net;
+
+ for_each_table_entry ( tcpip_net, TCPIP_NET_PROTOCOLS ) {
+ if ( tcpip_net->sa_family == st_dest->st_family )
+ return tcpip_net;
+ }
+
+ DBG ( "Unrecognised TCP/IP address family %d\n", st_dest->st_family );
+ return NULL;
+}
+
+/**
+ * Transmit a TCP/IP packet
*
* @v iobuf I/O buffer
* @v tcpip_protocol Transport-layer protocol
@@ -73,20 +94,35 @@ int tcpip_tx ( struct io_buffer *iobuf, struct tcpip_protocol *tcpip_protocol,
struct tcpip_net_protocol *tcpip_net;
/* Hand off packet to the appropriate network-layer protocol */
- for_each_table_entry ( tcpip_net, TCPIP_NET_PROTOCOLS ) {
- if ( tcpip_net->sa_family == st_dest->st_family ) {
- DBG ( "TCP/IP sending %s packet\n", tcpip_net->name );
- return tcpip_net->tx ( iobuf, tcpip_protocol, st_src,
- st_dest, netdev, trans_csum );
- }
+ tcpip_net = tcpip_net_protocol ( st_dest );
+ if ( tcpip_net ) {
+ DBG ( "TCP/IP sending %s packet\n", tcpip_net->name );
+ return tcpip_net->tx ( iobuf, tcpip_protocol, st_src, st_dest,
+ netdev, trans_csum );
}
-
- DBG ( "Unrecognised TCP/IP address family %d\n", st_dest->st_family );
+
free_iob ( iobuf );
return -EAFNOSUPPORT;
}
/**
+ * Determine transmitting network device
+ *
+ * @v st_dest Destination address
+ * @ret netdev Network device, or NULL
+ */
+struct net_device * tcpip_netdev ( struct sockaddr_tcpip *st_dest ) {
+ struct tcpip_net_protocol *tcpip_net;
+
+ /* Hand off to the appropriate network-layer protocol */
+ tcpip_net = tcpip_net_protocol ( st_dest );
+ if ( tcpip_net )
+ return tcpip_net->netdev ( st_dest );
+
+ return NULL;
+}
+
+/**
* Calculate continued TCP/IP checkum
*
* @v partial Checksum of already-summed data, in network byte order