瀏覽代碼

[pxe] Obey lists of PXE Boot Servers and associated Discovery Control bits

Various combinations of options 43.6, 43.7 and 43.8 dictate which
servers we send Boot Server Discovery requests to, and which servers
we should accept responses from.  Obey these options, and remove the
explicit specification of a single Boot Server from start_pxebs() and
dependent functions.
tags/v0.9.7
Michael Brown 16 年之前
父節點
當前提交
881f1f59ef
共有 6 個文件被更改,包括 195 次插入62 次删除
  1. 4
    13
      src/hci/commands/dhcp_cmd.c
  2. 17
    1
      src/include/gpxe/dhcp.h
  3. 1
    2
      src/include/usr/dhcpmgmt.h
  4. 169
    29
      src/net/udp/dhcp.c
  5. 3
    6
      src/usr/dhcpmgmt.c
  6. 1
    11
      src/usr/pxemenu.c

+ 4
- 13
src/hci/commands/dhcp_cmd.c 查看文件

@@ -109,7 +109,7 @@ static int dhcp_exec ( int argc, char **argv ) {
109 109
  */
110 110
 static void pxebs_syntax ( char **argv ) {
111 111
 	printf ( "Usage:\n"
112
-		 "  %s <interface> <discovery_ip> <server_type>\n"
112
+		 "  %s <interface> <server_type>\n"
113 113
 		 "\n"
114 114
 		 "Perform PXE Boot Server discovery\n",
115 115
 		 argv[0] );
@@ -128,10 +128,8 @@ static int pxebs_exec ( int argc, char **argv ) {
128 128
 		{ NULL, 0, NULL, 0 },
129 129
 	};
130 130
 	const char *netdev_txt;
131
-	const char *pxe_server_txt;
132 131
 	const char *pxe_type_txt;
133 132
 	struct net_device *netdev;
134
-	struct in_addr pxe_server;
135 133
 	unsigned int pxe_type;
136 134
 	char *end;
137 135
 	int c;
@@ -148,15 +146,12 @@ static int pxebs_exec ( int argc, char **argv ) {
148 146
 			return 1;
149 147
 		}
150 148
 	}
151
-
152
-	/* Need exactly one interface name remaining after the options */
153
-	if ( optind != ( argc - 3 ) ) {
149
+	if ( optind != ( argc - 2 ) ) {
154 150
 		pxebs_syntax ( argv );
155 151
 		return 1;
156 152
 	}
157 153
 	netdev_txt = argv[optind];
158
-	pxe_server_txt = argv[ optind + 1 ];
159
-	pxe_type_txt = argv[ optind + 2 ];
154
+	pxe_type_txt = argv[ optind + 1 ];
160 155
 
161 156
 	/* Parse arguments */
162 157
 	netdev = find_netdev ( netdev_txt );
@@ -164,10 +159,6 @@ static int pxebs_exec ( int argc, char **argv ) {
164 159
 		printf ( "No such interface: %s\n", netdev_txt );
165 160
 		return 1;
166 161
 	}
167
-	if ( inet_aton ( pxe_server_txt, &pxe_server ) == 0 ) {
168
-		printf ( "Bad discovery IP address: %s\n", pxe_server_txt );
169
-		return 1;
170
-	}
171 162
 	pxe_type = strtoul ( pxe_type_txt, &end, 0 );
172 163
 	if ( *end ) {
173 164
 		printf ( "Bad server type: %s\n", pxe_type_txt );
@@ -175,7 +166,7 @@ static int pxebs_exec ( int argc, char **argv ) {
175 166
 	}
176 167
 
177 168
 	/* Perform Boot Server Discovery */
178
-	if ( ( rc = pxebs ( netdev, pxe_server, pxe_type ) ) != 0 ) {
169
+	if ( ( rc = pxebs ( netdev, pxe_type ) ) != 0 ) {
179 170
 		printf ( "Could not discover boot server on %s: %s\n",
180 171
 			 netdev->name, strerror ( rc ) );
181 172
 		return 1;

+ 17
- 1
src/include/gpxe/dhcp.h 查看文件

@@ -100,6 +100,19 @@ enum dhcp_pxe_discovery_control {
100 100
 /** PXE boot server multicast address */
101 101
 #define DHCP_PXE_BOOT_SERVER_MCAST DHCP_ENCAP_OPT ( DHCP_VENDOR_ENCAP, 7 )
102 102
 
103
+/** PXE boot servers */
104
+#define DHCP_PXE_BOOT_SERVERS DHCP_ENCAP_OPT ( DHCP_VENDOR_ENCAP, 8 )
105
+
106
+/** PXE boot server */
107
+struct dhcp_pxe_boot_server {
108
+	/** "Type" */
109
+	uint16_t type;
110
+	/** Number of IPv4 addresses */
111
+	uint8_t num_ip;
112
+	/** IPv4 addresses */
113
+	struct in_addr ip[0];
114
+} __attribute__ (( packed ));
115
+
103 116
 /** PXE boot menu */
104 117
 #define DHCP_PXE_BOOT_MENU DHCP_ENCAP_OPT ( DHCP_VENDOR_ENCAP, 9 )
105 118
 
@@ -574,6 +587,9 @@ struct dhcphdr {
574 587
 /** Maximum time that we will wait for ProxyDHCP responses */
575 588
 #define PROXYDHCP_MAX_TIMEOUT ( 2 * TICKS_PER_SEC )
576 589
 
590
+/** Maximum time that we will wait for Boot Server responses */
591
+#define PXEBS_MAX_TIMEOUT ( 3 * TICKS_PER_SEC )
592
+
577 593
 /** Settings block name used for DHCP responses */
578 594
 #define DHCP_SETTINGS_NAME "dhcp"
579 595
 
@@ -593,6 +609,6 @@ extern int dhcp_create_request ( struct dhcp_packet *dhcppkt,
593 609
 				 void *data, size_t max_len );
594 610
 extern int start_dhcp ( struct job_interface *job, struct net_device *netdev );
595 611
 extern int start_pxebs ( struct job_interface *job, struct net_device *netdev,
596
-			 struct in_addr pxe_server, unsigned int pxe_type );
612
+			 unsigned int pxe_type );
597 613
 
598 614
 #endif /* _GPXE_DHCP_H */

+ 1
- 2
src/include/usr/dhcpmgmt.h 查看文件

@@ -10,7 +10,6 @@
10 10
 struct net_device;
11 11
 
12 12
 extern int dhcp ( struct net_device *netdev );
13
-extern int pxebs ( struct net_device *netdev, struct in_addr pxe_server,
14
-		   unsigned int pxe_type );
13
+extern int pxebs ( struct net_device *netdev, unsigned int pxe_type );
15 14
 
16 15
 #endif /* _USR_DHCPMGMT_H */

+ 169
- 29
src/net/udp/dhcp.c 查看文件

@@ -175,11 +175,12 @@ struct dhcp_session_state {
175 175
 	 * @v dhcppkt		DHCP packet
176 176
 	 * @v peer		DHCP server address
177 177
 	 * @v msgtype		DHCP message type
178
+	 * @v server_id		DHCP server ID
178 179
 	 */
179 180
 	void ( * rx ) ( struct dhcp_session *dhcp,
180 181
 			struct dhcp_packet *dhcppkt,
181 182
 			struct sockaddr_in *peer,
182
-			uint8_t msgtype );
183
+			uint8_t msgtype, struct in_addr server_id );
183 184
 	/** Handle timer expiry
184 185
 	 *
185 186
 	 * @v dhcp		DHCP session
@@ -226,10 +227,12 @@ struct dhcp_session {
226 227
 	/** ProxyDHCP server priority */
227 228
 	int proxy_priority;
228 229
 
229
-	/** PXE Boot Server */
230
-	struct in_addr pxe_server;
231 230
 	/** PXE Boot Server type */
232 231
 	uint16_t pxe_type;
232
+	/** List of PXE Boot Servers to attempt */
233
+	struct in_addr *pxe_attempt;
234
+	/** List of PXE Boot Servers to accept */
235
+	struct in_addr *pxe_accept;
233 236
 
234 237
 	/** Retransmission timer */
235 238
 	struct retry_timer timer;
@@ -322,11 +325,12 @@ static int dhcp_discovery_tx ( struct dhcp_session *dhcp,
322 325
  * @v dhcppkt		DHCP packet
323 326
  * @v peer		DHCP server address
324 327
  * @v msgtype		DHCP message type
328
+ * @v server_id		DHCP server ID
325 329
  */
326 330
 static void dhcp_discovery_rx ( struct dhcp_session *dhcp,
327 331
 				struct dhcp_packet *dhcppkt,
328
-				struct sockaddr_in *peer, uint8_t msgtype ) {
329
-	struct in_addr server_id = { 0 };
332
+				struct sockaddr_in *peer, uint8_t msgtype,
333
+				struct in_addr server_id ) {
330 334
 	struct in_addr ip;
331 335
 	char vci[9]; /* "PXEClient" */
332 336
 	int vci_len;
@@ -338,10 +342,6 @@ static void dhcp_discovery_rx ( struct dhcp_session *dhcp,
338 342
 	DBGC ( dhcp, "DHCP %p %s from %s:%d", dhcp,
339 343
 	       dhcp_msgtype_name ( msgtype ), inet_ntoa ( peer->sin_addr ),
340 344
 	       ntohs ( peer->sin_port ) );
341
-
342
-	/* Identify server ID */
343
-	dhcppkt_fetch ( dhcppkt, DHCP_SERVER_IDENTIFIER,
344
-			&server_id, sizeof ( server_id ) );
345 345
 	if ( server_id.s_addr != peer->sin_addr.s_addr )
346 346
 		DBGC ( dhcp, " (%s)", inet_ntoa ( server_id ) );
347 347
 
@@ -480,11 +480,12 @@ static int dhcp_request_tx ( struct dhcp_session *dhcp,
480 480
  * @v dhcppkt		DHCP packet
481 481
  * @v peer		DHCP server address
482 482
  * @v msgtype		DHCP message type
483
+ * @v server_id		DHCP server ID
483 484
  */
484 485
 static void dhcp_request_rx ( struct dhcp_session *dhcp,
485 486
 			      struct dhcp_packet *dhcppkt,
486
-			      struct sockaddr_in *peer, uint8_t msgtype ) {
487
-	struct in_addr server_id = { 0 };
487
+			      struct sockaddr_in *peer, uint8_t msgtype,
488
+			      struct in_addr server_id ) {
488 489
 	struct in_addr ip;
489 490
 	struct settings *parent;
490 491
 	int rc;
@@ -492,10 +493,6 @@ static void dhcp_request_rx ( struct dhcp_session *dhcp,
492 493
 	DBGC ( dhcp, "DHCP %p %s from %s:%d", dhcp,
493 494
 	       dhcp_msgtype_name ( msgtype ), inet_ntoa ( peer->sin_addr ),
494 495
 	       ntohs ( peer->sin_port ) );
495
-
496
-	/* Identify server ID */
497
-	dhcppkt_fetch ( dhcppkt, DHCP_SERVER_IDENTIFIER,
498
-			&server_id, sizeof ( server_id ) );
499 496
 	if ( server_id.s_addr != peer->sin_addr.s_addr )
500 497
 		DBGC ( dhcp, " (%s)", inet_ntoa ( server_id ) );
501 498
 
@@ -591,20 +588,17 @@ static int dhcp_proxy_tx ( struct dhcp_session *dhcp,
591 588
  * @v dhcppkt		DHCP packet
592 589
  * @v peer		DHCP server address
593 590
  * @v msgtype		DHCP message type
591
+ * @v server_id		DHCP server ID
594 592
  */
595 593
 static void dhcp_proxy_rx ( struct dhcp_session *dhcp,
596 594
 			    struct dhcp_packet *dhcppkt,
597
-			    struct sockaddr_in *peer, uint8_t msgtype ) {
598
-	struct in_addr server_id = { 0 };
595
+			    struct sockaddr_in *peer, uint8_t msgtype,
596
+			    struct in_addr server_id ) {
599 597
 	int rc;
600 598
 
601 599
 	DBGC ( dhcp, "DHCP %p %s from %s:%d", dhcp,
602 600
 	       dhcp_msgtype_name ( msgtype ), inet_ntoa ( peer->sin_addr ),
603 601
 	       ntohs ( peer->sin_port ) );
604
-
605
-	/* Identify server ID */
606
-	dhcppkt_fetch ( dhcppkt, DHCP_SERVER_IDENTIFIER,
607
-			&server_id, sizeof ( server_id ) );
608 602
 	if ( server_id.s_addr != peer->sin_addr.s_addr )
609 603
 		DBGC ( dhcp, " (%s)", inet_ntoa ( server_id ) );
610 604
 	DBGC ( dhcp, "\n" );
@@ -673,7 +667,7 @@ static int dhcp_pxebs_tx ( struct dhcp_session *dhcp,
673 667
 	int rc;
674 668
 
675 669
 	DBGC ( dhcp, "DHCP %p PXEBS REQUEST to %s:%d for type %d\n",
676
-	       dhcp, inet_ntoa ( dhcp->pxe_server ), PXE_PORT,
670
+	       dhcp, inet_ntoa ( *(dhcp->pxe_attempt) ), PXE_PORT,
677 671
 	       ntohs ( dhcp->pxe_type ) );
678 672
 
679 673
 	/* Set boot menu item */
@@ -683,12 +677,38 @@ static int dhcp_pxebs_tx ( struct dhcp_session *dhcp,
683 677
 		return rc;
684 678
 
685 679
 	/* Set server address */
686
-	peer->sin_addr = dhcp->pxe_server;
680
+	peer->sin_addr = *(dhcp->pxe_attempt);
687 681
 	peer->sin_port = htons ( PXE_PORT );
688 682
 
689 683
 	return 0;
690 684
 }
691 685
 
686
+/**
687
+ * Check to see if PXE Boot Server address is acceptable
688
+ *
689
+ * @v dhcp		DHCP session
690
+ * @v bs		Boot Server address
691
+ * @ret accept		Boot Server is acceptable
692
+ */
693
+static int dhcp_pxebs_accept ( struct dhcp_session *dhcp,
694
+			       struct in_addr bs ) {
695
+	struct in_addr *accept;
696
+
697
+	/* Accept if we have no acceptance filter */
698
+	if ( ! dhcp->pxe_accept )
699
+		return 1;
700
+
701
+	/* Scan through acceptance list */
702
+	for ( accept = dhcp->pxe_accept ; accept->s_addr ; accept++ ) {
703
+		if ( accept->s_addr == bs.s_addr )
704
+			return 1;
705
+	}
706
+
707
+	DBGC ( dhcp, "DHCP %p rejecting server %s\n",
708
+	       dhcp, inet_ntoa ( bs ) );
709
+	return 0;
710
+}
711
+
692 712
 /**
693 713
  * Handle received packet during PXE Boot Server Discovery
694 714
  *
@@ -696,16 +716,20 @@ static int dhcp_pxebs_tx ( struct dhcp_session *dhcp,
696 716
  * @v dhcppkt		DHCP packet
697 717
  * @v peer		DHCP server address
698 718
  * @v msgtype		DHCP message type
719
+ * @v server_id		DHCP server ID
699 720
  */
700 721
 static void dhcp_pxebs_rx ( struct dhcp_session *dhcp,
701 722
 			    struct dhcp_packet *dhcppkt,
702
-			    struct sockaddr_in *peer, uint8_t msgtype ) {
723
+			    struct sockaddr_in *peer, uint8_t msgtype,
724
+			    struct in_addr server_id ) {
703 725
 	struct dhcp_pxe_boot_menu_item menu_item = { 0, 0 };
704 726
 	int rc;
705 727
 
706 728
 	DBGC ( dhcp, "DHCP %p %s from %s:%d", dhcp,
707 729
 	       dhcp_msgtype_name ( msgtype ), inet_ntoa ( peer->sin_addr ),
708 730
 	       ntohs ( peer->sin_port ) );
731
+	if ( server_id.s_addr != peer->sin_addr.s_addr )
732
+		DBGC ( dhcp, " (%s)", inet_ntoa ( server_id ) );
709 733
 
710 734
 	/* Identify boot menu item */
711 735
 	dhcppkt_fetch ( dhcppkt, DHCP_PXE_BOOT_MENU_ITEM,
@@ -721,6 +745,9 @@ static void dhcp_pxebs_rx ( struct dhcp_session *dhcp,
721 745
 		return;
722 746
 	if ( menu_item.type != dhcp->pxe_type )
723 747
 		return;
748
+	if ( ! dhcp_pxebs_accept ( dhcp, ( server_id.s_addr ?
749
+					   server_id : peer->sin_addr ) ) )
750
+		return;
724 751
 
725 752
 	/* Register settings */
726 753
 	dhcppkt->settings.name = PXEBS_SETTINGS_NAME;
@@ -741,6 +768,21 @@ static void dhcp_pxebs_rx ( struct dhcp_session *dhcp,
741 768
  * @v dhcp		DHCP session
742 769
  */
743 770
 static void dhcp_pxebs_expired ( struct dhcp_session *dhcp ) {
771
+	unsigned long elapsed = ( currticks() - dhcp->start );
772
+
773
+	/* Give up waiting before we reach the failure point, and fail
774
+	 * over to the next server in the attempt list
775
+	 */
776
+	if ( elapsed > PXEBS_MAX_TIMEOUT ) {
777
+		dhcp->pxe_attempt++;
778
+		if ( dhcp->pxe_attempt->s_addr ) {
779
+			dhcp_set_state ( dhcp, &dhcp_state_pxebs );
780
+			return;
781
+		} else {
782
+			dhcp_finished ( dhcp, -ETIMEDOUT );
783
+			return;
784
+		}
785
+	}
744 786
 
745 787
 	/* Retransmit current packet */
746 788
 	dhcp_tx ( dhcp );
@@ -1006,6 +1048,7 @@ static int dhcp_deliver_iob ( struct xfer_interface *xfer,
1006 1048
 	struct dhcp_packet *dhcppkt;
1007 1049
 	struct dhcphdr *dhcphdr;
1008 1050
 	uint8_t msgtype = 0;
1051
+	struct in_addr server_id = { 0 };
1009 1052
 	int rc = 0;
1010 1053
 
1011 1054
 	/* Sanity checks */
@@ -1042,6 +1085,10 @@ static int dhcp_deliver_iob ( struct xfer_interface *xfer,
1042 1085
 	dhcppkt_fetch ( dhcppkt, DHCP_MESSAGE_TYPE, &msgtype,
1043 1086
 			sizeof ( msgtype ) );
1044 1087
 
1088
+	/* Identify server ID */
1089
+	dhcppkt_fetch ( dhcppkt, DHCP_SERVER_IDENTIFIER,
1090
+			&server_id, sizeof ( server_id ) );
1091
+
1045 1092
 	/* Check for matching transaction ID */
1046 1093
 	if ( dhcphdr->xid != dhcp_xid ( dhcp->netdev ) ) {
1047 1094
 		DBGC ( dhcp, "DHCP %p %s from %s:%d has bad transaction "
@@ -1053,7 +1100,7 @@ static int dhcp_deliver_iob ( struct xfer_interface *xfer,
1053 1100
 	};
1054 1101
 
1055 1102
 	/* Handle packet based on current state */
1056
-	dhcp->state->rx ( dhcp, dhcppkt, peer, msgtype );
1103
+	dhcp->state->rx ( dhcp, dhcppkt, peer, msgtype, server_id );
1057 1104
 
1058 1105
  err_xid:
1059 1106
 	dhcppkt_put ( dhcppkt );
@@ -1183,12 +1230,50 @@ int start_dhcp ( struct job_interface *job, struct net_device *netdev ) {
1183 1230
 	return rc;
1184 1231
 }
1185 1232
 
1233
+/**
1234
+ * Retrieve list of PXE boot servers for a given server type
1235
+ *
1236
+ * @v dhcp		DHCP session
1237
+ * @v raw		DHCP PXE boot server list
1238
+ * @v raw_len		Length of DHCP PXE boot server list
1239
+ * @v ip		IP address list to fill in
1240
+ *
1241
+ * The caller must ensure that the IP address list has sufficient
1242
+ * space.
1243
+ */
1244
+static void pxebs_list ( struct dhcp_session *dhcp, void *raw,
1245
+			 size_t raw_len, struct in_addr *ip ) {
1246
+	struct dhcp_pxe_boot_server *server = raw;
1247
+	size_t server_len;
1248
+	unsigned int i;
1249
+
1250
+	while ( raw_len ) {
1251
+		if ( raw_len < sizeof ( *server ) ) {
1252
+			DBGC ( dhcp, "DHCP %p malformed PXE server list\n",
1253
+			       dhcp );
1254
+			break;
1255
+		}
1256
+		server_len = offsetof ( typeof ( *server ),
1257
+					ip[ server->num_ip ] );
1258
+		if ( raw_len < server_len ) {
1259
+			DBGC ( dhcp, "DHCP %p malformed PXE server list\n",
1260
+			       dhcp );
1261
+			break;
1262
+		}
1263
+		if ( server->type == dhcp->pxe_type ) {
1264
+			for ( i = 0 ; i < server->num_ip ; i++ )
1265
+				*(ip++) = server->ip[i];
1266
+		}
1267
+		server = ( ( ( void * ) server ) + server_len );
1268
+		raw_len -= server_len;
1269
+	}
1270
+}
1271
+
1186 1272
 /**
1187 1273
  * Start PXE Boot Server Discovery on a network device
1188 1274
  *
1189 1275
  * @v job		Job control interface
1190 1276
  * @v netdev		Network device
1191
- * @v pxe_server	PXE server (may be a multicast address)
1192 1277
  * @v pxe_type		PXE server type
1193 1278
  * @ret rc		Return status code
1194 1279
  *
@@ -1197,12 +1282,28 @@ int start_dhcp ( struct job_interface *job, struct net_device *netdev ) {
1197 1282
  * source.
1198 1283
  */
1199 1284
 int start_pxebs ( struct job_interface *job, struct net_device *netdev,
1200
-		  struct in_addr pxe_server, unsigned int pxe_type ) {
1285
+		  unsigned int pxe_type ) {
1286
+	struct setting pxe_discovery_control_setting =
1287
+		{ .tag = DHCP_PXE_DISCOVERY_CONTROL };
1288
+	struct setting pxe_boot_servers_setting =
1289
+		{ .tag = DHCP_PXE_BOOT_SERVERS };
1290
+	struct setting pxe_boot_server_mcast_setting =
1291
+		{ .tag = DHCP_PXE_BOOT_SERVER_MCAST };
1292
+	ssize_t pxebs_list_len;
1201 1293
 	struct dhcp_session *dhcp;
1294
+	struct in_addr *ip;
1295
+	unsigned int pxe_discovery_control;
1202 1296
 	int rc;
1203 1297
 
1298
+	/* Get upper bound for PXE boot server IP address list */
1299
+	pxebs_list_len = fetch_setting_len ( NULL, &pxe_boot_servers_setting );
1300
+	if ( pxebs_list_len < 0 )
1301
+		pxebs_list_len = 0;
1302
+
1204 1303
 	/* Allocate and initialise structure */
1205
-	dhcp = zalloc ( sizeof ( *dhcp ) );
1304
+	dhcp = zalloc ( sizeof ( *dhcp ) + sizeof ( *ip ) /* mcast */ +
1305
+			sizeof ( *ip ) /* bcast */ + pxebs_list_len +
1306
+			sizeof ( *ip ) /* terminator */ );
1206 1307
 	if ( ! dhcp )
1207 1308
 		return -ENOMEM;
1208 1309
 	dhcp->refcnt.free = dhcp_free;
@@ -1213,10 +1314,49 @@ int start_pxebs ( struct job_interface *job, struct net_device *netdev,
1213 1314
 	fetch_ipv4_setting ( netdev_settings ( netdev ), &ip_setting,
1214 1315
 			     &dhcp->local.sin_addr );
1215 1316
 	dhcp->local.sin_port = htons ( BOOTPC_PORT );
1216
-	dhcp->pxe_server = pxe_server;
1217 1317
 	dhcp->pxe_type = htons ( pxe_type );
1218 1318
 	dhcp->timer.expired = dhcp_timer_expired;
1219 1319
 
1320
+	/* Construct PXE boot server IP address lists */
1321
+	pxe_discovery_control =
1322
+		fetch_uintz_setting ( NULL, &pxe_discovery_control_setting );
1323
+	ip = ( ( ( void * ) dhcp ) + sizeof ( *dhcp ) );
1324
+	dhcp->pxe_attempt = ip;
1325
+	if ( ! ( pxe_discovery_control & PXEBS_NO_MULTICAST ) ) {
1326
+		fetch_ipv4_setting ( NULL, &pxe_boot_server_mcast_setting, ip);
1327
+		if ( ip->s_addr )
1328
+			ip++;
1329
+	}
1330
+	if ( ! ( pxe_discovery_control & PXEBS_NO_BROADCAST ) )
1331
+		(ip++)->s_addr = INADDR_BROADCAST;
1332
+	if ( pxe_discovery_control & PXEBS_NO_UNKNOWN_SERVERS )
1333
+		dhcp->pxe_accept = ip;
1334
+	if ( pxebs_list_len ) {
1335
+		uint8_t buf[pxebs_list_len];
1336
+
1337
+		fetch_setting ( NULL, &pxe_boot_servers_setting,
1338
+				buf, sizeof ( buf ) );
1339
+		pxebs_list ( dhcp, buf, sizeof ( buf ), ip );
1340
+	}
1341
+	if ( ! dhcp->pxe_attempt->s_addr ) {
1342
+		DBGC ( dhcp, "DHCP %p has no PXE boot servers for type %04x\n",
1343
+		       dhcp, pxe_type );
1344
+		rc = -EINVAL;
1345
+		goto err;
1346
+	}
1347
+
1348
+	/* Dump out PXE server lists */
1349
+	DBGC ( dhcp, "DHCP %p attempting", dhcp );
1350
+	for ( ip = dhcp->pxe_attempt ; ip->s_addr ; ip++ )
1351
+		DBGC ( dhcp, " %s", inet_ntoa ( *ip ) );
1352
+	DBGC ( dhcp, "\n" );
1353
+	if ( dhcp->pxe_accept ) {
1354
+		DBGC ( dhcp, "DHCP %p accepting", dhcp );
1355
+		for ( ip = dhcp->pxe_accept ; ip->s_addr ; ip++ )
1356
+			DBGC ( dhcp, " %s", inet_ntoa ( *ip ) );
1357
+		DBGC ( dhcp, "\n" );
1358
+	}
1359
+
1220 1360
 	/* Instantiate child objects and attach to our interfaces */
1221 1361
 	if ( ( rc = xfer_open_socket ( &dhcp->xfer, SOCK_DGRAM, &dhcp_peer,
1222 1362
 				  ( struct sockaddr * ) &dhcp->local ) ) != 0 )

+ 3
- 6
src/usr/dhcpmgmt.c 查看文件

@@ -47,15 +47,12 @@ int dhcp ( struct net_device *netdev ) {
47 47
 	return rc;
48 48
 }
49 49
 
50
-int pxebs ( struct net_device *netdev, struct in_addr pxe_server,
51
-	    unsigned int pxe_type ) {
50
+int pxebs ( struct net_device *netdev, unsigned int pxe_type ) {
52 51
 	int rc;
53 52
 
54 53
 	/* Perform PXE Boot Server Discovery */
55
-	printf ( "PXEBS (%s %s type %d)",
56
-		 netdev->name, inet_ntoa ( pxe_server ), pxe_type );
57
-	if ( ( rc = start_pxebs ( &monojob, netdev, pxe_server,
58
-				  pxe_type ) ) == 0 )
54
+	printf ( "PXEBS (%s type %d)", netdev->name, pxe_type );
55
+	if ( ( rc = start_pxebs ( &monojob, netdev, pxe_type ) ) == 0 )
59 56
 		rc = monojob_wait ( "" );
60 57
 
61 58
 	return rc;

+ 1
- 11
src/usr/pxemenu.c 查看文件

@@ -57,8 +57,6 @@ struct pxe_menu_item {
57 57
  * options.
58 58
  */
59 59
 struct pxe_menu {
60
-	/** Boot Server address */
61
-	struct in_addr server;
62 60
 	/** Timeout (in seconds)
63 61
 	 *
64 62
 	 * Negative indicates no timeout (i.e. wait indefinitely)
@@ -83,7 +81,6 @@ struct pxe_menu {
83 81
  */
84 82
 static int pxe_menu_parse ( struct pxe_menu **menu ) {
85 83
 	struct setting tmp_setting = { .name = NULL };
86
-	struct in_addr server;
87 84
 	struct dhcp_pxe_boot_menu_prompt prompt = { .timeout = 0 };
88 85
 	uint8_t raw_menu[256];
89 86
 	int raw_menu_len;
@@ -94,10 +91,6 @@ static int pxe_menu_parse ( struct pxe_menu **menu ) {
94 91
 	int rc;
95 92
 
96 93
 	/* Fetch relevant settings */
97
-	tmp_setting.tag = DHCP_PXE_BOOT_SERVER_MCAST;
98
-	fetch_ipv4_setting ( NULL, &tmp_setting, &server );
99
-	if ( ! server.s_addr )
100
-		server.s_addr = INADDR_BROADCAST;
101 94
 	tmp_setting.tag = DHCP_PXE_BOOT_MENU_PROMPT;
102 95
 	fetch_setting ( NULL, &tmp_setting, &prompt, sizeof ( prompt ) );
103 96
 	tmp_setting.tag = DHCP_PXE_BOOT_MENU;
@@ -142,7 +135,6 @@ static int pxe_menu_parse ( struct pxe_menu **menu ) {
142 135
 	}
143 136
 
144 137
 	/* Fill in parsed menu */
145
-	(*menu)->server = server;
146 138
 	(*menu)->timeout =
147 139
 		( ( prompt.timeout == 0xff ) ? -1 : prompt.timeout );
148 140
 	(*menu)->num_items = num_menu_items;
@@ -296,7 +288,6 @@ int pxe_menu_select ( struct pxe_menu *menu ) {
296 288
  */
297 289
 int pxe_menu_boot ( struct net_device *netdev ) {
298 290
 	struct pxe_menu *menu;
299
-	struct in_addr pxe_server;
300 291
 	unsigned int pxe_type;
301 292
 	struct settings *pxebs_settings;
302 293
 	struct in_addr next_server;
@@ -312,7 +303,6 @@ int pxe_menu_boot ( struct net_device *netdev ) {
312 303
 		free ( menu );
313 304
 		return rc;
314 305
 	}
315
-	pxe_server = menu->server;
316 306
 	pxe_type = menu->items[menu->selection].type;
317 307
 
318 308
 	/* Free boot menu */
@@ -323,7 +313,7 @@ int pxe_menu_boot ( struct net_device *netdev ) {
323 313
 		return 0;
324 314
 
325 315
 	/* Attempt PXE Boot Server Discovery */
326
-	if ( ( rc = pxebs ( netdev, pxe_server, pxe_type ) ) != 0 )
316
+	if ( ( rc = pxebs ( netdev, pxe_type ) ) != 0 )
327 317
 		return rc;
328 318
 
329 319
 	/* Attempt boot */

Loading…
取消
儲存