]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[netdevice] Allow MTU to be changed at runtime
authorMichael Brown <mcb30@ipxe.org>
Mon, 23 Jan 2017 17:47:28 +0000 (17:47 +0000)
committerMichael Brown <mcb30@ipxe.org>
Mon, 23 Jan 2017 17:47:28 +0000 (17:47 +0000)
Provide a settings applicator to modify netdev->max_pkt_len in
response to changes to the "mtu" setting (DHCP option 26).

Note that as with MAC address changes, drivers are permitted to
completely ignore any changes in the MTU value.  The net result will
be that iPXE effectively uses the smaller of either the hardware
default MTU or the software configured MTU.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/include/ipxe/dhcp.h
src/net/netdev_settings.c
src/net/udp/dhcp.c

index b699b31f08292dbee996fbf39264c5fb1afc5678..23f16aaa74216d2eb33a33543e44e38190aaa6ba 100644 (file)
@@ -83,6 +83,9 @@ struct dhcp_packet;
 /** Root path */
 #define DHCP_ROOT_PATH 17
 
+/** Maximum transmission unit */
+#define DHCP_MTU 26
+
 /** Vendor encapsulated options */
 #define DHCP_VENDOR_ENCAP 43
 
index 7d893a126582913711c5f8600dc05851df7ae21f..67a45bedee1ce10e25e1a6aff0e15dfba4ba326d 100644 (file)
@@ -70,6 +70,12 @@ const struct setting ifname_setting __setting ( SETTING_NETDEV, ifname ) = {
        .description = "Interface name",
        .type = &setting_type_string,
 };
+const struct setting mtu_setting __setting ( SETTING_NETDEV, mtu ) = {
+       .name = "mtu",
+       .description = "MTU",
+       .type = &setting_type_int16,
+       .tag = DHCP_MTU,
+};
 
 /**
  * Store MAC address setting
@@ -377,3 +383,58 @@ static void netdev_redirect_settings_init ( void ) {
 struct init_fn netdev_redirect_settings_init_fn __init_fn ( INIT_LATE ) = {
        .initialise = netdev_redirect_settings_init,
 };
+
+/**
+ * Apply network device settings
+ *
+ * @ret rc             Return status code
+ */
+static int apply_netdev_settings ( void ) {
+       struct net_device *netdev;
+       struct settings *settings;
+       struct ll_protocol *ll_protocol;
+       size_t old_max_pkt_len;
+       size_t mtu;
+       int rc;
+
+       /* Process settings for each network device */
+       for_each_netdev ( netdev ) {
+
+               /* Get network device settings */
+               settings = netdev_settings ( netdev );
+
+               /* Get MTU */
+               mtu = fetch_uintz_setting ( settings, &mtu_setting );
+
+               /* Do nothing unless MTU is specified */
+               if ( ! mtu )
+                       continue;
+
+               /* Update maximum packet length */
+               ll_protocol = netdev->ll_protocol;
+               old_max_pkt_len = netdev->max_pkt_len;
+               netdev->max_pkt_len = ( mtu + ll_protocol->ll_header_len );
+               if ( netdev->max_pkt_len != old_max_pkt_len ) {
+                       DBGC ( netdev, "NETDEV %s MTU is %zd\n",
+                              netdev->name, mtu );
+               }
+
+               /* Close and reopen network device if MTU has increased */
+               if ( netdev_is_open ( netdev ) &&
+                    ( netdev->max_pkt_len > old_max_pkt_len ) ) {
+                       netdev_close ( netdev );
+                       if ( ( rc = netdev_open ( netdev ) ) != 0 ) {
+                               DBGC ( netdev, "NETDEV %s could not reopen: "
+                                      "%s\n", netdev->name, strerror ( rc ) );
+                               return rc;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+/** Network device settings applicator */
+struct settings_applicator netdev_applicator __settings_applicator = {
+       .apply = apply_netdev_settings,
+};
index b9c1fd90c9375fafab04dcc2a4912bc1cd21d7af..95f80821eb2b896446226a1838b2ee724fcc0087 100644 (file)
@@ -91,9 +91,9 @@ static uint8_t dhcp_request_options_data[] = {
        DHCP_PARAMETER_REQUEST_LIST,
        DHCP_OPTION ( DHCP_SUBNET_MASK, DHCP_ROUTERS, DHCP_DNS_SERVERS,
                      DHCP_LOG_SERVERS, DHCP_HOST_NAME, DHCP_DOMAIN_NAME,
-                     DHCP_ROOT_PATH, DHCP_VENDOR_ENCAP, DHCP_VENDOR_CLASS_ID,
-                     DHCP_TFTP_SERVER_NAME, DHCP_BOOTFILE_NAME,
-                     DHCP_DOMAIN_SEARCH,
+                     DHCP_ROOT_PATH, DHCP_MTU, DHCP_VENDOR_ENCAP,
+                     DHCP_VENDOR_CLASS_ID, DHCP_TFTP_SERVER_NAME,
+                     DHCP_BOOTFILE_NAME, DHCP_DOMAIN_SEARCH,
                      128, 129, 130, 131, 132, 133, 134, 135, /* for PXE */
                      DHCP_EB_ENCAP, DHCP_ISCSI_INITIATOR_IQN ),
        DHCP_END