[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>
This commit is contained in:
parent
ff1e7fc72b
commit
db67de6f31
@ -116,6 +116,13 @@ struct tcpip_net_protocol {
|
|||||||
struct sockaddr_tcpip *st_dest,
|
struct sockaddr_tcpip *st_dest,
|
||||||
struct net_device *netdev,
|
struct net_device *netdev,
|
||||||
uint16_t *trans_csum );
|
uint16_t *trans_csum );
|
||||||
|
/**
|
||||||
|
* Determine transmitting network device
|
||||||
|
*
|
||||||
|
* @v st_dest Destination address
|
||||||
|
* @ret netdev Network device, or NULL
|
||||||
|
*/
|
||||||
|
struct net_device * ( * netdev ) ( struct sockaddr_tcpip *dest );
|
||||||
};
|
};
|
||||||
|
|
||||||
/** TCP/IP transport-layer protocol table */
|
/** TCP/IP transport-layer protocol table */
|
||||||
@ -140,6 +147,7 @@ extern int tcpip_tx ( struct io_buffer *iobuf, struct tcpip_protocol *tcpip,
|
|||||||
struct sockaddr_tcpip *st_dest,
|
struct sockaddr_tcpip *st_dest,
|
||||||
struct net_device *netdev,
|
struct net_device *netdev,
|
||||||
uint16_t *trans_csum );
|
uint16_t *trans_csum );
|
||||||
|
extern struct net_device * tcpip_netdev ( struct sockaddr_tcpip *st_dest );
|
||||||
extern uint16_t generic_tcpip_continue_chksum ( uint16_t partial,
|
extern uint16_t generic_tcpip_continue_chksum ( uint16_t partial,
|
||||||
const void *data, size_t len );
|
const void *data, size_t len );
|
||||||
extern uint16_t tcpip_chksum ( const void *data, size_t len );
|
extern uint16_t tcpip_chksum ( const void *data, size_t len );
|
||||||
|
@ -137,6 +137,25 @@ static struct ipv4_miniroute * ipv4_route ( struct in_addr *dest ) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine transmitting network device
|
||||||
|
*
|
||||||
|
* @v st_dest Destination network-layer address
|
||||||
|
* @ret netdev Transmitting network device, or NULL
|
||||||
|
*/
|
||||||
|
static struct net_device * ipv4_netdev ( struct sockaddr_tcpip *st_dest ) {
|
||||||
|
struct sockaddr_in *sin_dest = ( ( struct sockaddr_in * ) st_dest );
|
||||||
|
struct in_addr dest = sin_dest->sin_addr;
|
||||||
|
struct ipv4_miniroute *miniroute;
|
||||||
|
|
||||||
|
/* Find routing table entry */
|
||||||
|
miniroute = ipv4_route ( &dest );
|
||||||
|
if ( ! miniroute )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return miniroute->netdev;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if IPv4 fragment matches fragment reassembly buffer
|
* Check if IPv4 fragment matches fragment reassembly buffer
|
||||||
*
|
*
|
||||||
@ -603,6 +622,7 @@ struct tcpip_net_protocol ipv4_tcpip_protocol __tcpip_net_protocol = {
|
|||||||
.name = "IPv4",
|
.name = "IPv4",
|
||||||
.sa_family = AF_INET,
|
.sa_family = AF_INET,
|
||||||
.tx = ipv4_tx,
|
.tx = ipv4_tx,
|
||||||
|
.netdev = ipv4_netdev,
|
||||||
};
|
};
|
||||||
|
|
||||||
/** IPv4 ARP protocol */
|
/** IPv4 ARP protocol */
|
||||||
|
@ -321,6 +321,25 @@ static struct ipv6_miniroute * ipv6_route ( unsigned int scope_id,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine transmitting network device
|
||||||
|
*
|
||||||
|
* @v st_dest Destination network-layer address
|
||||||
|
* @ret netdev Transmitting network device, or NULL
|
||||||
|
*/
|
||||||
|
static struct net_device * ipv6_netdev ( struct sockaddr_tcpip *st_dest ) {
|
||||||
|
struct sockaddr_in6 *sin6_dest = ( ( struct sockaddr_in6 * ) st_dest );
|
||||||
|
struct in6_addr *dest = &sin6_dest->sin6_addr;
|
||||||
|
struct ipv6_miniroute *miniroute;
|
||||||
|
|
||||||
|
/* Find routing table entry */
|
||||||
|
miniroute = ipv6_route ( sin6_dest->sin6_scope_id, &dest );
|
||||||
|
if ( ! miniroute )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return miniroute->netdev;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check that received options can be safely ignored
|
* Check that received options can be safely ignored
|
||||||
*
|
*
|
||||||
@ -970,6 +989,7 @@ struct tcpip_net_protocol ipv6_tcpip_protocol __tcpip_net_protocol = {
|
|||||||
.name = "IPv6",
|
.name = "IPv6",
|
||||||
.sa_family = AF_INET6,
|
.sa_family = AF_INET6,
|
||||||
.tx = ipv6_tx,
|
.tx = ipv6_tx,
|
||||||
|
.netdev = ipv6_netdev,
|
||||||
};
|
};
|
||||||
|
|
||||||
/** IPv6 socket address converter */
|
/** IPv6 socket address converter */
|
||||||
|
@ -18,7 +18,8 @@
|
|||||||
|
|
||||||
FILE_LICENCE ( GPL2_OR_LATER );
|
FILE_LICENCE ( GPL2_OR_LATER );
|
||||||
|
|
||||||
/** Process a received TCP/IP packet
|
/**
|
||||||
|
* Process a received TCP/IP packet
|
||||||
*
|
*
|
||||||
* @v iobuf I/O buffer
|
* @v iobuf I/O buffer
|
||||||
* @v netdev Network device
|
* @v netdev Network device
|
||||||
@ -57,7 +58,27 @@ int tcpip_rx ( struct io_buffer *iobuf, struct net_device *netdev,
|
|||||||
return -EPROTONOSUPPORT;
|
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 iobuf I/O buffer
|
||||||
* @v tcpip_protocol Transport-layer protocol
|
* @v tcpip_protocol Transport-layer protocol
|
||||||
@ -73,19 +94,34 @@ int tcpip_tx ( struct io_buffer *iobuf, struct tcpip_protocol *tcpip_protocol,
|
|||||||
struct tcpip_net_protocol *tcpip_net;
|
struct tcpip_net_protocol *tcpip_net;
|
||||||
|
|
||||||
/* Hand off packet to the appropriate network-layer protocol */
|
/* Hand off packet to the appropriate network-layer protocol */
|
||||||
for_each_table_entry ( tcpip_net, TCPIP_NET_PROTOCOLS ) {
|
tcpip_net = tcpip_net_protocol ( st_dest );
|
||||||
if ( tcpip_net->sa_family == st_dest->st_family ) {
|
if ( tcpip_net ) {
|
||||||
DBG ( "TCP/IP sending %s packet\n", tcpip_net->name );
|
DBG ( "TCP/IP sending %s packet\n", tcpip_net->name );
|
||||||
return tcpip_net->tx ( iobuf, tcpip_protocol, st_src,
|
return tcpip_net->tx ( iobuf, tcpip_protocol, st_src, st_dest,
|
||||||
st_dest, netdev, trans_csum );
|
netdev, trans_csum );
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG ( "Unrecognised TCP/IP address family %d\n", st_dest->st_family );
|
|
||||||
free_iob ( iobuf );
|
free_iob ( iobuf );
|
||||||
return -EAFNOSUPPORT;
|
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
|
* Calculate continued TCP/IP checkum
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user