Kaynağa Gözat

[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.
tags/v0.9.8
Michael Brown 15 yıl önce
ebeveyn
işleme
f186ada2d3
1 değiştirilmiş dosya ile 42 ekleme ve 15 silme
  1. 42
    15
      src/arch/i386/interface/pxe/pxe_undi.c

+ 42
- 15
src/arch/i386/interface/pxe/pxe_undi.c Dosyayı Görüntüle

@@ -90,6 +90,20 @@ static void pxe_netdev_close ( void ) {
90 90
 	undi_tx_count = 0;
91 91
 }
92 92
 
93
+/**
94
+ * Dump multicast address list
95
+ *
96
+ * @v mcast		PXE multicast address list
97
+ */
98
+static void pxe_dump_mcast_list ( struct s_PXENV_UNDI_MCAST_ADDRESS *mcast ) {
99
+	struct ll_protocol *ll_protocol = pxe_netdev->ll_protocol;
100
+	unsigned int i;
101
+
102
+	for ( i = 0 ; i < mcast->MCastAddrCount ; i++ ) {
103
+		DBG ( " %s", ll_protocol->ntoa ( mcast->McastAddr[i] ) );
104
+	}
105
+}
106
+
93 107
 /* PXENV_UNDI_STARTUP
94 108
  *
95 109
  * Status: working
@@ -135,8 +149,9 @@ PXENV_EXIT_t pxenv_undi_reset_adapter ( struct s_PXENV_UNDI_RESET
135 149
 					*undi_reset_adapter ) {
136 150
 	int rc;
137 151
 
138
-	DBG ( "PXENV_UNDI_RESET_ADAPTER %04x\n",
139
-	      undi_reset_adapter->R_Mcast_Buf.MCastAddrCount );
152
+	DBG ( "PXENV_UNDI_RESET_ADAPTER" );
153
+	pxe_dump_mcast_list ( &undi_reset_adapter->R_Mcast_Buf );
154
+	DBG ( "\n" );
140 155
 
141 156
 	pxe_netdev_close();
142 157
 	if ( ( rc = pxe_netdev_open() ) != 0 ) {
@@ -171,9 +186,10 @@ PXENV_EXIT_t pxenv_undi_shutdown ( struct s_PXENV_UNDI_SHUTDOWN
171 186
 PXENV_EXIT_t pxenv_undi_open ( struct s_PXENV_UNDI_OPEN *undi_open ) {
172 187
 	int rc;
173 188
 
174
-	DBG ( "PXENV_UNDI_OPEN flag %04x filter %04x mcast %04x\n",
175
-	      undi_open->OpenFlag, undi_open->PktFilter,
176
-	      undi_open->R_Mcast_Buf.MCastAddrCount );
189
+	DBG ( "PXENV_UNDI_OPEN flag %04x filter %04x",
190
+	      undi_open->OpenFlag, undi_open->PktFilter );
191
+	pxe_dump_mcast_list ( &undi_open->R_Mcast_Buf );
192
+	DBG ( "\n" );
177 193
 
178 194
 	if ( ( rc = pxe_netdev_open() ) != 0 ) {
179 195
 		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
318 334
 
319 335
 /* PXENV_UNDI_SET_MCAST_ADDRESS
320 336
  *
321
- * Status: stub (no PXE multicast support)
337
+ * Status: working (for NICs that support receive-all-multicast)
322 338
  */
323 339
 PXENV_EXIT_t
324 340
 pxenv_undi_set_mcast_address ( struct s_PXENV_UNDI_SET_MCAST_ADDRESS
325 341
 			       *undi_set_mcast_address ) {
326
-	DBG ( "PXENV_UNDI_SET_MCAST_ADDRESS %04x failed: unsupported\n",
327
-	      undi_set_mcast_address->R_Mcast_Buf.MCastAddrCount );
342
+	DBG ( "PXENV_UNDI_SET_MCAST_ADDRESS" );
343
+	pxe_dump_mcast_list ( &undi_set_mcast_address->R_Mcast_Buf );
344
+	DBG ( "\n" );
328 345
 
329
-	undi_set_mcast_address->Status = PXENV_STATUS_UNSUPPORTED;
330
-	return PXENV_EXIT_FAILURE;
346
+	undi_set_mcast_address->Status = PXENV_STATUS_SUCCESS;
347
+	return PXENV_EXIT_SUCCESS;
331 348
 }
332 349
 
333 350
 /* PXENV_UNDI_SET_STATION_ADDRESS
@@ -491,18 +508,28 @@ PXENV_EXIT_t pxenv_undi_force_interrupt ( struct s_PXENV_UNDI_FORCE_INTERRUPT
491 508
 
492 509
 /* PXENV_UNDI_GET_MCAST_ADDRESS
493 510
  *
494
- * Status: stub (no PXE multicast support)
511
+ * Status: working
495 512
  */
496 513
 PXENV_EXIT_t
497 514
 pxenv_undi_get_mcast_address ( struct s_PXENV_UNDI_GET_MCAST_ADDRESS
498 515
 			       *undi_get_mcast_address ) {
516
+	struct ll_protocol *ll_protocol = pxe_netdev->ll_protocol;
499 517
 	struct in_addr ip = { .s_addr = undi_get_mcast_address->InetAddr };
518
+	int rc;
500 519
 
501
-	DBG ( "PXENV_UNDI_GET_MCAST_ADDRESS %s failed: unsupported\n",
502
-	      inet_ntoa ( ip ) );
520
+	DBG ( "PXENV_UNDI_GET_MCAST_ADDRESS %s", inet_ntoa ( ip ) );
503 521
 
504
-	undi_get_mcast_address->Status = PXENV_STATUS_UNSUPPORTED;
505
-	return PXENV_EXIT_FAILURE;
522
+	if ( ( rc = ll_protocol->mc_hash ( AF_INET, &ip,
523
+				      undi_get_mcast_address->MediaAddr ))!=0){
524
+		DBG ( " failed: %s\n", strerror ( rc ) );
525
+		undi_get_mcast_address->Status = PXENV_STATUS ( rc );
526
+		return PXENV_EXIT_FAILURE;
527
+	}
528
+	DBG ( "=>%s\n",
529
+	      ll_protocol->ntoa ( undi_get_mcast_address->MediaAddr ) );
530
+
531
+	undi_get_mcast_address->Status = PXENV_STATUS_SUCCESS;
532
+	return PXENV_EXIT_SUCCESS;
506 533
 }
507 534
 
508 535
 /* PXENV_UNDI_GET_NIC_TYPE

Loading…
İptal
Kaydet