david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

[pxe] Implement PXENV_UNDI_{GET,SET}_MCAST_ADDRESS

Symantec Ghost requires working multicast support.  gPXE configures
all (sufficiently supported) network adapters into "receive all
multicasts" mode, which means that PXENV_UNDI_SET_MCAST_ADDRESS is
actually a no-op, but the current implementation returns
PXENV_STATUS_UNSUPPORTED instead.

Fix by making PXENV_UNDI_SET_MCAST_ADDRESS return success.  For good
measure, also implement PXENV_UNDI_GET_MCAST_ADDRESS, since the
relevant functionality is now exposed by the net device core.

Note that this will silently fail if the gPXE driver for the NIC being
used fails to configure the NIC in "receive all multicasts" mode.
This commit is contained in:
Michael Brown 2009-06-27 15:45:27 +01:00
parent 9580f9d5cd
commit f186ada2d3
1 changed files with 42 additions and 15 deletions

View File

@ -90,6 +90,20 @@ static void pxe_netdev_close ( void ) {
undi_tx_count = 0;
}
/**
* Dump multicast address list
*
* @v mcast PXE multicast address list
*/
static void pxe_dump_mcast_list ( struct s_PXENV_UNDI_MCAST_ADDRESS *mcast ) {
struct ll_protocol *ll_protocol = pxe_netdev->ll_protocol;
unsigned int i;
for ( i = 0 ; i < mcast->MCastAddrCount ; i++ ) {
DBG ( " %s", ll_protocol->ntoa ( mcast->McastAddr[i] ) );
}
}
/* PXENV_UNDI_STARTUP
*
* Status: working
@ -135,8 +149,9 @@ PXENV_EXIT_t pxenv_undi_reset_adapter ( struct s_PXENV_UNDI_RESET
*undi_reset_adapter ) {
int rc;
DBG ( "PXENV_UNDI_RESET_ADAPTER %04x\n",
undi_reset_adapter->R_Mcast_Buf.MCastAddrCount );
DBG ( "PXENV_UNDI_RESET_ADAPTER" );
pxe_dump_mcast_list ( &undi_reset_adapter->R_Mcast_Buf );
DBG ( "\n" );
pxe_netdev_close();
if ( ( rc = pxe_netdev_open() ) != 0 ) {
@ -171,9 +186,10 @@ PXENV_EXIT_t pxenv_undi_shutdown ( struct s_PXENV_UNDI_SHUTDOWN
PXENV_EXIT_t pxenv_undi_open ( struct s_PXENV_UNDI_OPEN *undi_open ) {
int rc;
DBG ( "PXENV_UNDI_OPEN flag %04x filter %04x mcast %04x\n",
undi_open->OpenFlag, undi_open->PktFilter,
undi_open->R_Mcast_Buf.MCastAddrCount );
DBG ( "PXENV_UNDI_OPEN flag %04x filter %04x",
undi_open->OpenFlag, undi_open->PktFilter );
pxe_dump_mcast_list ( &undi_open->R_Mcast_Buf );
DBG ( "\n" );
if ( ( rc = pxe_netdev_open() ) != 0 ) {
DBG ( "PXENV_UNDI_OPEN could not open %s: %s\n",
@ -318,16 +334,17 @@ PXENV_EXIT_t pxenv_undi_transmit ( struct s_PXENV_UNDI_TRANSMIT
/* PXENV_UNDI_SET_MCAST_ADDRESS
*
* Status: stub (no PXE multicast support)
* Status: working (for NICs that support receive-all-multicast)
*/
PXENV_EXIT_t
pxenv_undi_set_mcast_address ( struct s_PXENV_UNDI_SET_MCAST_ADDRESS
*undi_set_mcast_address ) {
DBG ( "PXENV_UNDI_SET_MCAST_ADDRESS %04x failed: unsupported\n",
undi_set_mcast_address->R_Mcast_Buf.MCastAddrCount );
DBG ( "PXENV_UNDI_SET_MCAST_ADDRESS" );
pxe_dump_mcast_list ( &undi_set_mcast_address->R_Mcast_Buf );
DBG ( "\n" );
undi_set_mcast_address->Status = PXENV_STATUS_UNSUPPORTED;
return PXENV_EXIT_FAILURE;
undi_set_mcast_address->Status = PXENV_STATUS_SUCCESS;
return PXENV_EXIT_SUCCESS;
}
/* PXENV_UNDI_SET_STATION_ADDRESS
@ -491,18 +508,28 @@ PXENV_EXIT_t pxenv_undi_force_interrupt ( struct s_PXENV_UNDI_FORCE_INTERRUPT
/* PXENV_UNDI_GET_MCAST_ADDRESS
*
* Status: stub (no PXE multicast support)
* Status: working
*/
PXENV_EXIT_t
pxenv_undi_get_mcast_address ( struct s_PXENV_UNDI_GET_MCAST_ADDRESS
*undi_get_mcast_address ) {
struct ll_protocol *ll_protocol = pxe_netdev->ll_protocol;
struct in_addr ip = { .s_addr = undi_get_mcast_address->InetAddr };
int rc;
DBG ( "PXENV_UNDI_GET_MCAST_ADDRESS %s failed: unsupported\n",
inet_ntoa ( ip ) );
DBG ( "PXENV_UNDI_GET_MCAST_ADDRESS %s", inet_ntoa ( ip ) );
undi_get_mcast_address->Status = PXENV_STATUS_UNSUPPORTED;
return PXENV_EXIT_FAILURE;
if ( ( rc = ll_protocol->mc_hash ( AF_INET, &ip,
undi_get_mcast_address->MediaAddr ))!=0){
DBG ( " failed: %s\n", strerror ( rc ) );
undi_get_mcast_address->Status = PXENV_STATUS ( rc );
return PXENV_EXIT_FAILURE;
}
DBG ( "=>%s\n",
ll_protocol->ntoa ( undi_get_mcast_address->MediaAddr ) );
undi_get_mcast_address->Status = PXENV_STATUS_SUCCESS;
return PXENV_EXIT_SUCCESS;
}
/* PXENV_UNDI_GET_NIC_TYPE