]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[tcpip] Provide tcpip_mtu() to determine the maximum transmission unit
authorMichael Brown <mcb30@ipxe.org>
Tue, 4 Mar 2014 13:10:07 +0000 (13:10 +0000)
committerMichael Brown <mcb30@ipxe.org>
Tue, 4 Mar 2014 13:13:54 +0000 (13:13 +0000)
Provide the function tcpip_mtu() to allow external code to determine
the (transport-layer) maximum transmission unit for a given socket
address.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/include/ipxe/tcpip.h
src/net/ipv4.c
src/net/ipv6.c
src/net/tcpip.c

index d28689a10a8b163a7aa158f8445f6ec31c025eba..200630d6b180bae5b282ad265aab85e1a7fcf933 100644 (file)
@@ -97,6 +97,8 @@ struct tcpip_net_protocol {
        const char *name;
        /** Network address family */
        sa_family_t sa_family;
+       /** Fixed header length */
+       size_t header_len;
        /**
         * Transmit packet
         *
@@ -148,6 +150,7 @@ extern int tcpip_tx ( struct io_buffer *iobuf, struct tcpip_protocol *tcpip,
                      struct net_device *netdev,
                      uint16_t *trans_csum );
 extern struct net_device * tcpip_netdev ( struct sockaddr_tcpip *st_dest );
+extern size_t tcpip_mtu ( struct sockaddr_tcpip *st_dest );
 extern uint16_t generic_tcpip_continue_chksum ( uint16_t partial,
                                                const void *data, size_t len );
 extern uint16_t tcpip_chksum ( const void *data, size_t len );
index 8bda5c86fd0b17c21e9c56b5e579aa20d8c67aba..c5cfd134dbdccba9995f58b663cf860ed056638b 100644 (file)
@@ -621,6 +621,7 @@ struct net_protocol ipv4_protocol __net_protocol = {
 struct tcpip_net_protocol ipv4_tcpip_protocol __tcpip_net_protocol = {
        .name = "IPv4",
        .sa_family = AF_INET,
+       .header_len = sizeof ( struct iphdr ),
        .tx = ipv4_tx,
        .netdev = ipv4_netdev,
 };
index 6f2e94776f69df894aff1da6ace2527b0c7b9dec..f753751dfce11641d94adc38c74a162a29eccee9 100644 (file)
@@ -988,6 +988,7 @@ struct net_protocol ipv6_protocol __net_protocol = {
 struct tcpip_net_protocol ipv6_tcpip_protocol __tcpip_net_protocol = {
        .name = "IPv6",
        .sa_family = AF_INET6,
+       .header_len = sizeof ( struct ipv6_header ),
        .tx = ipv6_tx,
        .netdev = ipv6_netdev,
 };
index 6fac8c52cdda7dc9740ab9423f6863aa1d0f3300..4bcbe64bbfdc823270876c426342ecae8db9d379 100644 (file)
@@ -6,6 +6,7 @@
 #include <ipxe/iobuf.h>
 #include <ipxe/tables.h>
 #include <ipxe/ipstat.h>
+#include <ipxe/netdevice.h>
 #include <ipxe/tcpip.h>
 
 /** @file
@@ -122,6 +123,34 @@ struct net_device * tcpip_netdev ( struct sockaddr_tcpip *st_dest ) {
        return NULL;
 }
 
+/**
+ * Determine maximum transmission unit
+ *
+ * @v st_dest          Destination address
+ * @ret mtu            Maximum transmission unit
+ */
+size_t tcpip_mtu ( struct sockaddr_tcpip *st_dest ) {
+       struct tcpip_net_protocol *tcpip_net;
+       struct net_device *netdev;
+       size_t mtu;
+
+       /* Find appropriate network-layer protocol */
+       tcpip_net = tcpip_net_protocol ( st_dest );
+       if ( ! tcpip_net )
+               return 0;
+
+       /* Find transmitting network device */
+       netdev = tcpip_net->netdev ( st_dest );
+       if ( ! netdev )
+               return 0;
+
+       /* Calculate MTU */
+       mtu = ( netdev->max_pkt_len - netdev->ll_protocol->ll_header_len -
+               tcpip_net->header_len );
+
+       return mtu;
+}
+
 /**
  * Calculate continued TCP/IP checkum
  *