Browse Source

[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 years ago
parent
commit
f186ada2d3
1 changed files with 42 additions and 15 deletions
  1. 42
    15
      src/arch/i386/interface/pxe/pxe_undi.c

+ 42
- 15
src/arch/i386/interface/pxe/pxe_undi.c View File

90
 	undi_tx_count = 0;
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
 /* PXENV_UNDI_STARTUP
107
 /* PXENV_UNDI_STARTUP
94
  *
108
  *
95
  * Status: working
109
  * Status: working
135
 					*undi_reset_adapter ) {
149
 					*undi_reset_adapter ) {
136
 	int rc;
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
 	pxe_netdev_close();
156
 	pxe_netdev_close();
142
 	if ( ( rc = pxe_netdev_open() ) != 0 ) {
157
 	if ( ( rc = pxe_netdev_open() ) != 0 ) {
171
 PXENV_EXIT_t pxenv_undi_open ( struct s_PXENV_UNDI_OPEN *undi_open ) {
186
 PXENV_EXIT_t pxenv_undi_open ( struct s_PXENV_UNDI_OPEN *undi_open ) {
172
 	int rc;
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
 	if ( ( rc = pxe_netdev_open() ) != 0 ) {
194
 	if ( ( rc = pxe_netdev_open() ) != 0 ) {
179
 		DBG ( "PXENV_UNDI_OPEN could not open %s: %s\n",
195
 		DBG ( "PXENV_UNDI_OPEN could not open %s: %s\n",
318
 
334
 
319
 /* PXENV_UNDI_SET_MCAST_ADDRESS
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
 PXENV_EXIT_t
339
 PXENV_EXIT_t
324
 pxenv_undi_set_mcast_address ( struct s_PXENV_UNDI_SET_MCAST_ADDRESS
340
 pxenv_undi_set_mcast_address ( struct s_PXENV_UNDI_SET_MCAST_ADDRESS
325
 			       *undi_set_mcast_address ) {
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
 /* PXENV_UNDI_SET_STATION_ADDRESS
350
 /* PXENV_UNDI_SET_STATION_ADDRESS
491
 
508
 
492
 /* PXENV_UNDI_GET_MCAST_ADDRESS
509
 /* PXENV_UNDI_GET_MCAST_ADDRESS
493
  *
510
  *
494
- * Status: stub (no PXE multicast support)
511
+ * Status: working
495
  */
512
  */
496
 PXENV_EXIT_t
513
 PXENV_EXIT_t
497
 pxenv_undi_get_mcast_address ( struct s_PXENV_UNDI_GET_MCAST_ADDRESS
514
 pxenv_undi_get_mcast_address ( struct s_PXENV_UNDI_GET_MCAST_ADDRESS
498
 			       *undi_get_mcast_address ) {
515
 			       *undi_get_mcast_address ) {
516
+	struct ll_protocol *ll_protocol = pxe_netdev->ll_protocol;
499
 	struct in_addr ip = { .s_addr = undi_get_mcast_address->InetAddr };
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
 /* PXENV_UNDI_GET_NIC_TYPE
535
 /* PXENV_UNDI_GET_NIC_TYPE

Loading…
Cancel
Save