[pxe] Skip PXE boot server discovery if directed to do so
authorMichael Brown <mcb30@etherboot.org>
Tue, 3 Feb 2009 02:46:06 +0000 (02:46 +0000)
committerMichael Brown <mcb30@etherboot.org>
Thu, 5 Feb 2009 09:34:05 +0000 (09:34 +0000)
Option 43.6 can direct us to skip PXE boot server discovery and just
perform a standard DHCP filename boot.

src/include/gpxe/dhcp.h
src/usr/autoboot.c

index d84d55d..44edd64 100644 (file)
@@ -82,6 +82,21 @@ struct dhcp_packet;
 /** Vendor encapsulated options */
 #define DHCP_VENDOR_ENCAP 43
 
+/** PXE boot server discovery control */
+#define DHCP_PXE_DISCOVERY_CONTROL DHCP_ENCAP_OPT ( DHCP_VENDOR_ENCAP, 6 )
+
+/** PXE boot server discovery control bits */
+enum dhcp_pxe_discovery_control {
+       /** Inhibit broadcast discovery */
+       PXEBS_NO_BROADCAST = 1,
+       /** Inhibit multicast discovery */
+       PXEBS_NO_MULTICAST = 2,
+       /** Accept only servers in DHCP_PXE_BOOT_SERVERS list */
+       PXEBS_NO_UNKNOWN_SERVERS = 4,
+       /** Skip discovery if filename present */
+       PXEBS_SKIP = 8,
+};
+
 /** PXE boot server multicast address */
 #define DHCP_PXE_BOOT_SERVER_MCAST DHCP_ENCAP_OPT ( DHCP_VENDOR_ENCAP, 7 )
 
index 41f1341..cad625e 100644 (file)
@@ -167,9 +167,15 @@ int boot_root_path ( const char *root_path ) {
  * @ret rc             Return status code
  */
 static int netboot ( struct net_device *netdev ) {
-       struct setting tmp_setting = { .name = NULL };
+       struct setting vendor_class_id_setting
+               = { .tag = DHCP_VENDOR_CLASS_ID };
+       struct setting pxe_discovery_control_setting
+               = { .tag = DHCP_PXE_DISCOVERY_CONTROL };
+       struct setting pxe_boot_menu_setting
+               = { .tag = DHCP_PXE_BOOT_MENU };
        char buf[256];
        struct in_addr next_server;
+       unsigned int pxe_discovery_control;
        int rc;
 
        /* Open device and display device status */
@@ -195,12 +201,15 @@ static int netboot ( struct net_device *netdev ) {
        if ( rc != ENOENT )
                return rc;
 
-       /* Try PXE menu boot, if we have PXE menu options */
-       tmp_setting.tag = DHCP_VENDOR_CLASS_ID;
-       fetch_string_setting ( NULL, &tmp_setting, buf, sizeof ( buf ) );
-       tmp_setting.tag = DHCP_PXE_BOOT_MENU;
+       /* Try PXE menu boot, if applicable */
+       fetch_string_setting ( NULL, &vendor_class_id_setting,
+                              buf, sizeof ( buf ) );
+       pxe_discovery_control =
+               fetch_uintz_setting ( NULL, &pxe_discovery_control_setting );
        if ( ( strcmp ( buf, "PXEClient" ) == 0 ) &&
-            setting_exists ( NULL, &tmp_setting ) ) {
+            setting_exists ( NULL, &pxe_boot_menu_setting ) &&
+            ( ! ( ( pxe_discovery_control & PXEBS_SKIP ) &&
+                  setting_exists ( NULL, &filename_setting ) ) ) ) {
                printf ( "Booting from PXE menu\n" );
                return pxe_menu_boot ( netdev );
        }