summaryrefslogtreecommitdiffstats
path: root/src/net/udp.c
diff options
context:
space:
mode:
authorMichael Brown2009-01-21 04:40:39 +0100
committerMichael Brown2009-01-21 04:40:39 +0100
commitd230b53df2f44da477742094e5bbcc1b1520347c (patch)
tree4d0c8e9591509360aa7a7b1135ae39d6eab320ee /src/net/udp.c
parent[ethernet] Fix eth_mc_hash() return status (diff)
downloadipxe-d230b53df2f44da477742094e5bbcc1b1520347c.tar.gz
ipxe-d230b53df2f44da477742094e5bbcc1b1520347c.tar.xz
ipxe-d230b53df2f44da477742094e5bbcc1b1520347c.zip
[tcpip] Allow for transmission to multicast IPv4 addresses
When sending to a multicast address, it may be necessary to specify the source address explicitly, since the multicast destination address does not provide enough information to deduce the source address via the miniroute table. Allow the source address specified via the data-xfer metadata to be passed down through the TCP/IP stack to the IPv4 layer, which can use it as a default source address.
Diffstat (limited to 'src/net/udp.c')
-rw-r--r--src/net/udp.c19
1 files changed, 8 insertions, 11 deletions
diff --git a/src/net/udp.c b/src/net/udp.c
index fddf81df..63c2d9ee 100644
--- a/src/net/udp.c
+++ b/src/net/udp.c
@@ -182,13 +182,13 @@ static void udp_close ( struct udp_connection *udp, int rc ) {
*
* @v udp UDP connection
* @v iobuf I/O buffer
- * @v src_port Source port, or 0 to use default
+ * @v src Source address, or NULL to use default
* @v dest Destination address, or NULL to use default
* @v netdev Network device, or NULL to use default
* @ret rc Return status code
*/
static int udp_tx ( struct udp_connection *udp, struct io_buffer *iobuf,
- unsigned int src_port, struct sockaddr_tcpip *dest,
+ struct sockaddr_tcpip *src, struct sockaddr_tcpip *dest,
struct net_device *netdev ) {
struct udp_header *udphdr;
size_t len;
@@ -201,8 +201,8 @@ static int udp_tx ( struct udp_connection *udp, struct io_buffer *iobuf,
}
/* Fill in default values if not explicitly provided */
- if ( ! src_port )
- src_port = udp->local.st_port;
+ if ( ! src )
+ src = &udp->local;
if ( ! dest )
dest = &udp->peer;
@@ -210,7 +210,7 @@ static int udp_tx ( struct udp_connection *udp, struct io_buffer *iobuf,
udphdr = iob_push ( iobuf, sizeof ( *udphdr ) );
len = iob_len ( iobuf );
udphdr->dest = dest->st_port;
- udphdr->src = src_port;
+ udphdr->src = src->st_port;
udphdr->len = htons ( len );
udphdr->chksum = 0;
udphdr->chksum = tcpip_chksum ( udphdr, len );
@@ -221,7 +221,7 @@ static int udp_tx ( struct udp_connection *udp, struct io_buffer *iobuf,
ntohs ( udphdr->len ) );
/* Send it to the next layer for processing */
- if ( ( rc = tcpip_tx ( iobuf, &udp_protocol, dest, netdev,
+ if ( ( rc = tcpip_tx ( iobuf, &udp_protocol, src, dest, netdev,
&udphdr->chksum ) ) != 0 ) {
DBGC ( udp, "UDP %p could not transmit packet: %s\n",
udp, strerror ( rc ) );
@@ -399,22 +399,19 @@ static int udp_xfer_deliver_iob ( struct xfer_interface *xfer,
struct xfer_metadata *meta ) {
struct udp_connection *udp =
container_of ( xfer, struct udp_connection, xfer );
- struct sockaddr_tcpip *src;
+ struct sockaddr_tcpip *src = NULL;
struct sockaddr_tcpip *dest = NULL;
struct net_device *netdev = NULL;
- unsigned int src_port = 0;
/* Apply xfer metadata */
if ( meta ) {
src = ( struct sockaddr_tcpip * ) meta->src;
- if ( src )
- src_port = src->st_port;
dest = ( struct sockaddr_tcpip * ) meta->dest;
netdev = meta->netdev;
}
/* Transmit data, if possible */
- udp_tx ( udp, iobuf, src_port, dest, netdev );
+ udp_tx ( udp, iobuf, src, dest, netdev );
return 0;
}