From f1864fd2b6502cc8f092d715655bfaccb4c6d371 Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Thu, 20 Aug 2015 15:09:45 +0200 Subject: [PATCH 1/4] gnrc_ipv6_netif: initialize MTU from device, if possible --- sys/include/net/gnrc/ipv6/netif.h | 17 +++++++++++++---- sys/include/net/ipv6.h | 9 +++++++++ .../network_layer/ipv6/netif/gnrc_ipv6_netif.c | 12 ++++++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/sys/include/net/gnrc/ipv6/netif.h b/sys/include/net/gnrc/ipv6/netif.h index e62989b917..64f0f0602d 100644 --- a/sys/include/net/gnrc/ipv6/netif.h +++ b/sys/include/net/gnrc/ipv6/netif.h @@ -28,6 +28,7 @@ #include "kernel_macros.h" #include "kernel_types.h" #include "mutex.h" +#include "net/ipv6.h" #include "net/ipv6/addr.h" #include "vtimer.h" @@ -51,11 +52,19 @@ extern "C" { /** * @brief Default MTU * - * @see - * RFC 2460, section 5 - * + * An interface will choose this MTU if the link-layer's maximum packet size + * (see @ref NETOPT_MAX_PACKET_SIZE) is lesser than the @ref IPV6_MIN_MTU or if it just not + * provide it. For RFC-compatible communication it must be at least @ref IPV6_MIN_MTU. + * + * @note If the scenario the node is used in allows for it and the packet size is predictable, + * a user might choose to set @ref GNRC_IPV6_NETIF_DEFAULT_MTU to a lesser value than + * @ref IPV6_MIN_MTU to optimize for code size (e.g. because it is then possible to omit + * @ref net_gnrc_sixlowpan_frag) and memory usage (e.g. because @ref GNRC_PKTBUF_SIZE + * can be much smaller). */ -#define GNRC_IPV6_NETIF_DEFAULT_MTU (1280) +#ifndef GNRC_IPV6_NETIF_DEFAULT_MTU +#define GNRC_IPV6_NETIF_DEFAULT_MTU (IPV6_MIN_MTU) +#endif /** * @brief Default hop limit diff --git a/sys/include/net/ipv6.h b/sys/include/net/ipv6.h index 973c82555c..ba3e035d7a 100644 --- a/sys/include/net/ipv6.h +++ b/sys/include/net/ipv6.h @@ -32,6 +32,15 @@ extern "C" { #endif +/** + * @brief minimum **M**aximum **T**ransition **U**nit + * + * @see + * RFC 2460, section 5.3 + * + */ +#define IPV6_MIN_MTU (1280) + #ifdef __cplusplus } #endif diff --git a/sys/net/gnrc/network_layer/ipv6/netif/gnrc_ipv6_netif.c b/sys/net/gnrc/network_layer/ipv6/netif/gnrc_ipv6_netif.c index b0976f7681..15bf3b81d4 100644 --- a/sys/net/gnrc/network_layer/ipv6/netif/gnrc_ipv6_netif.c +++ b/sys/net/gnrc/network_layer/ipv6/netif/gnrc_ipv6_netif.c @@ -695,6 +695,7 @@ void gnrc_ipv6_netif_init_by_dev(void) for (size_t i = 0; i < ifnum; i++) { ipv6_addr_t addr; eui64_t iid; + uint16_t mtu; gnrc_ipv6_netif_t *ipv6_if = gnrc_ipv6_netif_get(ifs[i]); if (ipv6_if == NULL) { @@ -730,6 +731,7 @@ void gnrc_ipv6_netif_init_by_dev(void) } #endif + /* set link-local address */ if ((gnrc_netapi_get(ifs[i], NETOPT_IPV6_IID, 0, &iid, sizeof(eui64_t)) < 0)) { mutex_unlock(&ipv6_if->mutex); @@ -740,6 +742,16 @@ void gnrc_ipv6_netif_init_by_dev(void) ipv6_addr_set_link_local_prefix(&addr); _add_addr_to_entry(ipv6_if, &addr, 64, 0); + /* set link MTU */ + if ((gnrc_netapi_get(ifs[i], NETOPT_MAX_PACKET_SIZE, 0, &mtu, + sizeof(uint16_t)) >= 0)) { + if (mtu >= IPV6_MIN_MTU) { + ipv6_if->mtu = mtu; + } + /* otherwise leave at GNRC_IPV6_NETIF_DEFAULT_MTU as initialized in + * gnrc_ipv6_netif_add() */ + } + mutex_unlock(&ipv6_if->mutex); } } From d88ae14d902e5201dd78ed1790c97ac8d10b1742 Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Thu, 20 Aug 2015 15:25:21 +0200 Subject: [PATCH 2/4] gnrc_ipv6: check link MTU before sending --- sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c | 23 ++++++++++----------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c index 276ce10ea9..cc9c06025a 100644 --- a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c +++ b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c @@ -11,6 +11,7 @@ * * @file */ +#include #include #include #include @@ -192,31 +193,29 @@ static void *_event_loop(void *args) return NULL; } -#ifdef MODULE_GNRC_SIXLOWPAN static void _send_to_iface(kernel_pid_t iface, gnrc_pktsnip_t *pkt) { + ((gnrc_netif_hdr_t *)pkt->data)->if_pid = iface; gnrc_ipv6_netif_t *if_entry = gnrc_ipv6_netif_get(iface); - ((gnrc_netif_hdr_t *)pkt->data)->if_pid = iface; - + assert(if_entry != NULL); + if (gnrc_pkt_len(pkt->next) > if_entry->mtu) { + DEBUG("ipv6: packet too big\n"); + gnrc_pktbuf_release(pkt); + return; + } +#ifdef MODULE_GNRC_SIXLOWPAN if ((if_entry != NULL) && (if_entry->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN)) { DEBUG("ipv6: send to 6LoWPAN instead\n"); if (!gnrc_netapi_dispatch_send(GNRC_NETTYPE_SIXLOWPAN, GNRC_NETREG_DEMUX_CTX_ALL, pkt)) { DEBUG("ipv6: no 6LoWPAN thread found"); gnrc_pktbuf_release(pkt); } + return; } - else { - gnrc_netapi_send(iface, pkt); - } -} -#else -static inline void _send_to_iface(kernel_pid_t iface, gnrc_pktsnip_t *pkt) -{ - ((gnrc_netif_hdr_t *)pkt->data)->if_pid = iface; +#endif gnrc_netapi_send(iface, pkt); } -#endif /* functions for sending */ static void _send_unicast(kernel_pid_t iface, uint8_t *dst_l2addr, From 942d774a447e6f0830e2d42d14518820c947938c Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Thu, 20 Aug 2015 15:37:37 +0200 Subject: [PATCH 3/4] shell: ifconfig: add support for IPv6 MTU --- sys/shell/commands/sc_netif.c | 50 ++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/sys/shell/commands/sc_netif.c b/sys/shell/commands/sc_netif.c index 91e9688454..c550c57a4b 100644 --- a/sys/shell/commands/sc_netif.c +++ b/sys/shell/commands/sc_netif.c @@ -89,6 +89,11 @@ static void _set_usage(char *cmd_name) " * \"state\" - set the device state\n"); } +static void _mtu_usage(char *cmd_name) +{ + printf("usage: %s mtu \n", cmd_name); +} + static void _flag_usage(char *cmd_name) { printf("usage: %s [-]{promisc|autoack|preload|6lo|iphc}\n", cmd_name); @@ -259,8 +264,11 @@ static void _netif_list(kernel_pid_t dev) } #ifdef MODULE_GNRC_IPV6_NETIF - if ((entry != NULL) && (entry->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN)) { - printf("6LO "); + if (entry != NULL) { + printf("MTU:%" PRIu16 " ", entry->mtu); + if (entry->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) { + printf("6LO "); + } linebreak = true; } #endif @@ -269,7 +277,7 @@ static void _netif_list(kernel_pid_t dev) gnrc_sixlowpan_netif_t *sixlo_entry = gnrc_sixlowpan_netif_get(dev); if ((sixlo_entry != NULL) && (sixlo_entry->iphc_enabled)) { - printf("IPHC "); + printf("IPHC "); linebreak = true; } #endif @@ -683,6 +691,33 @@ static int _netif_del(kernel_pid_t dev, char *addr_str) #endif } +static int _netif_mtu(kernel_pid_t dev, char *mtu_str) +{ +#ifdef MODULE_GNRC_IPV6_NETIF + int mtu; + gnrc_ipv6_netif_t *entry; + if (((mtu = atoi(mtu_str)) < IPV6_MIN_MTU) || (mtu > UINT16_MAX)) { + printf("error: MTU must be between %" PRIu16 " and %" PRIu16 "\n", + IPV6_MIN_MTU, UINT16_MAX); + return 1; + } + if ((entry = gnrc_ipv6_netif_get(dev)) == NULL) { + puts("error: unable to set MTU."); + return 1; + } + entry->mtu = IPV6_MIN_MTU; + printf("success: set MTU %" PRIu16 " interface %" PRIkernel_pid "\n", mtu, + dev); + return 0; +#else + (void)dev; + (void)mtu_str; + puts("error: unable to set MTU."); + return 1; +#endif +} + + /* shell commands */ int _netif_send(int argc, char **argv) { @@ -777,6 +812,14 @@ int _netif_config(int argc, char **argv) return _netif_del((kernel_pid_t)dev, argv[3]); } + else if (strcmp(argv[2], "mtu") == 0) { + if (argc < 4) { + _mtu_usage(argv[0]); + return 1; + } + + return _netif_mtu((kernel_pid_t)dev, argv[3]); + } else { return _netif_flag(argv[0], dev, argv[2]); } @@ -789,6 +832,7 @@ int _netif_config(int argc, char **argv) printf("usage: %s []\n", argv[0]); _set_usage(argv[0]); + _mtu_usage(argv[0]); _flag_usage(argv[0]); _add_usage(argv[0]); _del_usage(argv[0]); From e5b03dfdddc7b58757e0550b3e0c2e4f3d749450 Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Thu, 20 Aug 2015 15:38:08 +0200 Subject: [PATCH 4/4] netdev_eth: return payload length instead of frame length --- sys/net/gnrc/link_layer/netdev_eth/gnrc_netdev_eth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/net/gnrc/link_layer/netdev_eth/gnrc_netdev_eth.c b/sys/net/gnrc/link_layer/netdev_eth/gnrc_netdev_eth.c index 0e45e92054..04659180d5 100644 --- a/sys/net/gnrc/link_layer/netdev_eth/gnrc_netdev_eth.c +++ b/sys/net/gnrc/link_layer/netdev_eth/gnrc_netdev_eth.c @@ -223,7 +223,7 @@ static inline int _get_max_pkt_sz(uint16_t *value, size_t max_len) return -EOVERFLOW; } - *value = ETHERNET_MAX_LEN; + *value = ETHERNET_DATA_LEN; return sizeof(uint16_t); }