Add concept of DHCP option applicators.
authorMichael Brown <mcb30@etherboot.org>
Thu, 5 Jul 2007 17:38:14 +0000 (18:38 +0100)
committerMichael Brown <mcb30@etherboot.org>
Thu, 5 Jul 2007 17:38:14 +0000 (18:38 +0100)
src/include/gpxe/dhcp.h
src/net/dhcpopts.c
src/net/udp/dhcp.c
src/net/udp/dns.c

index 3183a3a..caac914 100644 (file)
@@ -11,6 +11,7 @@
 #include <gpxe/list.h>
 #include <gpxe/in.h>
 #include <gpxe/refcnt.h>
+#include <gpxe/tables.h>
 
 struct net_device;
 struct job_interface;
@@ -438,6 +439,23 @@ struct dhcp_packet {
        struct dhcp_option_block options;
 };
 
+/** A DHCP option applicator */
+struct dhcp_option_applicator {
+       /** DHCP option tag */
+       unsigned int tag;
+       /** Applicator
+        *
+        * @v tag       DHCP option tag
+        * @v option    DHCP option
+        * @ret rc      Return status code
+        */
+       int ( * apply ) ( unsigned int tag, struct dhcp_option *option );
+};
+
+/** Declare a DHCP option applicator */
+#define __dhcp_applicator \
+       __table ( struct dhcp_option_applicator, dhcp_appicators, 01 )
+
 /**
  * Get reference to DHCP options block
  *
@@ -485,6 +503,7 @@ extern void find_global_dhcp_ipv4_option ( unsigned int tag,
                                           struct in_addr *inp );
 extern void delete_dhcp_option ( struct dhcp_option_block *options,
                                 unsigned int tag );
+extern int apply_dhcp_options ( struct dhcp_option_block *options );
 
 extern struct dhcp_option_block dhcp_request_options;
 extern int create_dhcp_packet ( struct net_device *netdev, uint8_t msgtype,
index bb97731..6038709 100644 (file)
@@ -25,6 +25,7 @@
 #include <assert.h>
 #include <gpxe/list.h>
 #include <gpxe/in.h>
+#include <gpxe/uri.h>
 #include <gpxe/dhcp.h>
 
 /** @file
 /** List of registered DHCP option blocks */
 static LIST_HEAD ( option_blocks );
 
+/** Registered DHCP option applicators */
+static struct dhcp_option_applicator dhcp_option_applicators[0]
+       __table_start ( struct dhcp_option_applicator, dhcp_applicators );
+static struct dhcp_option_applicator dhcp_option_applicators_end[0]
+       __table_end ( struct dhcp_option_applicator, dhcp_applicators );
+
 /**
  * Obtain printable version of a DHCP option tag
  *
@@ -560,3 +567,45 @@ void delete_dhcp_option ( struct dhcp_option_block *options,
                          unsigned int tag ) {
        set_dhcp_option ( options, tag, NULL, 0 );
 }
+
+/**
+ * Apply DHCP options
+ *
+ * @v options          DHCP options block, or NULL
+ * @ret rc             Return status code
+ */
+int apply_dhcp_options ( struct dhcp_option_block *options ) {
+       struct dhcp_option_applicator *applicator;
+       struct dhcp_option *option;
+       struct in_addr tftp_server;
+       struct uri *uri;
+       char uri_string[32];
+       unsigned int tag;
+       int rc;
+
+       /* Set current working URI based on TFTP server */
+       find_dhcp_ipv4_option ( options, DHCP_EB_SIADDR, &tftp_server );
+       snprintf ( uri_string, sizeof ( uri_string ),
+                  "tftp://%s/", inet_ntoa ( tftp_server ) );
+       uri = parse_uri ( uri_string );
+       if ( ! uri )
+               return -ENOMEM;
+       churi ( uri );
+       uri_put ( uri );
+
+       /* Call all registered DHCP option applicators */
+       for ( applicator = dhcp_option_applicators ;
+             applicator < dhcp_option_applicators_end ; applicator++ ) {
+               tag = applicator->tag;
+               option = find_dhcp_option ( options, tag );
+               if ( ! option )
+                       continue;
+               if ( ( rc = applicator->apply ( tag, option ) ) != 0 ) {
+                       DBG ( "Could not apply DHCP option %s: %s\n",
+                             dhcp_tag_name ( tag ), strerror ( rc ) );
+                       return rc;
+               }
+       }
+
+       return 0;
+}
index 03e6c9d..a8cb937 100644 (file)
@@ -30,7 +30,6 @@
 #include <gpxe/retry.h>
 #include <gpxe/tcpip.h>
 #include <gpxe/ip.h>
-#include <gpxe/uri.h>
 #include <gpxe/dhcp.h>
 
 /** @file
@@ -826,12 +825,6 @@ int start_dhcp ( struct job_interface *job, struct net_device *netdev,
  *
  */
 
-/* Avoid dragging in dns.o */
-struct sockaddr_tcpip nameserver;
-
-/* Avoid dragging in syslog.o */
-struct in_addr syslogserver;
-
 /**
  * Configure network device from DHCP options
  *
@@ -844,10 +837,6 @@ int dhcp_configure_netdev ( struct net_device *netdev,
        struct in_addr address = { 0 };
        struct in_addr netmask = { 0 };
        struct in_addr gateway = { INADDR_NONE };
-       struct sockaddr_in *sin_nameserver;
-       struct in_addr tftp_server;
-       struct uri *uri;
-       char uri_string[32];
        int rc;
 
        /* Clear any existing routing table entry */
@@ -866,23 +855,12 @@ int dhcp_configure_netdev ( struct net_device *netdev,
                return rc;
        }
 
-       /* Retrieve other DHCP options that we care about */
-       sin_nameserver = ( struct sockaddr_in * ) &nameserver;
-       sin_nameserver->sin_family = AF_INET;
-       find_dhcp_ipv4_option ( options, DHCP_DNS_SERVERS,
-                               &sin_nameserver->sin_addr );
-       find_dhcp_ipv4_option ( options, DHCP_LOG_SERVERS,
-                               &syslogserver );
-
-       /* Set current working URI based on TFTP server */
-       find_dhcp_ipv4_option ( options, DHCP_EB_SIADDR, &tftp_server );
-       snprintf ( uri_string, sizeof ( uri_string ),
-                  "tftp://%s/", inet_ntoa ( tftp_server ) );
-       uri = parse_uri ( uri_string );
-       if ( ! uri )
-               return -ENOMEM;
-       churi ( uri );
-       uri_put ( uri );
+       /* Apply other DHCP options */
+       if ( ( rc = apply_dhcp_options ( options ) ) != 0 ) {
+               DBG ( "Could not apply %s DHCP result options: %s\n",
+                     netdev->name, strerror ( rc ) );
+               return rc;
+       }
 
        return 0;
 }
index ff28c7e..bd519a2 100644 (file)
@@ -30,6 +30,7 @@
 #include <gpxe/resolv.h>
 #include <gpxe/retry.h>
 #include <gpxe/tcpip.h>
+#include <gpxe/dhcp.h>
 #include <gpxe/dns.h>
 
 /** @file
@@ -503,3 +504,25 @@ struct resolver dns_resolver __resolver ( RESOLV_NORMAL ) = {
        .name = "DNS",
        .resolv = dns_resolv,
 };
+
+/**
+ * Apply DHCP nameserver option
+ *
+ * @v tag              DHCP option tag
+ * @v option           DHCP option
+ */
+static int apply_dhcp_nameserver ( unsigned int tag __unused,
+                                  struct dhcp_option *option ) {
+       struct sockaddr_in *sin_nameserver;
+
+       sin_nameserver = ( struct sockaddr_in * ) &nameserver;
+       sin_nameserver->sin_family = AF_INET;
+       dhcp_ipv4_option ( option, &sin_nameserver->sin_addr );
+       return 0;
+}
+
+/** DHCP nameserver applicator */
+struct dhcp_option_applicator dhcp_nameserver_applicator __dhcp_applicator = {
+       .tag = DHCP_DNS_SERVERS,
+       .apply = apply_dhcp_nameserver,
+};