fix bug in RA MTU validation

Also fix that RA could change IPv4 MTU.
See bug #53696

Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
This commit is contained in:
Simon Goldschmidt 2018-06-14 12:55:18 +02:00
parent 39faa8f61d
commit 944f286d87
4 changed files with 28 additions and 6 deletions

View File

@ -1260,7 +1260,7 @@ ip6_output_if_src(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
#endif /* ENABLE_LOOPBACK */ #endif /* ENABLE_LOOPBACK */
#if LWIP_IPV6_FRAG #if LWIP_IPV6_FRAG
/* don't fragment if interface has mtu set to 0 [loopif] */ /* don't fragment if interface has mtu set to 0 [loopif] */
if (netif->mtu && (p->tot_len > nd6_get_destination_mtu(dest, netif))) { if (netif_mtu6(netif) && (p->tot_len > nd6_get_destination_mtu(dest, netif))) {
return ip6_frag(p, netif, dest); return ip6_frag(p, netif, dest);
} }
#endif /* LWIP_IPV6_FRAG */ #endif /* LWIP_IPV6_FRAG */

View File

@ -687,13 +687,20 @@ nd6_input(struct pbuf *p, struct netif *inp)
case ND6_OPTION_TYPE_MTU: case ND6_OPTION_TYPE_MTU:
{ {
struct mtu_option *mtu_opt; struct mtu_option *mtu_opt;
u32_t mtu32;
if (option_len < sizeof(struct mtu_option)) { if (option_len < sizeof(struct mtu_option)) {
goto lenerr_drop_free_return; goto lenerr_drop_free_return;
} }
mtu_opt = (struct mtu_option *)buffer; mtu_opt = (struct mtu_option *)buffer;
if (lwip_htonl(mtu_opt->mtu) >= 1280) { mtu32 = lwip_htonl(mtu_opt->mtu);
if ((mtu32 >= 1280) && (mtu32 <= 0xffff)) {
#if LWIP_ND6_ALLOW_RA_UPDATES #if LWIP_ND6_ALLOW_RA_UPDATES
inp->mtu = (u16_t)lwip_htonl(mtu_opt->mtu); if (inp->mtu) {
/* don't set the mtu for IPv6 higher than the netif driver supports */
inp->mtu6 = LWIP_MIN(inp->mtu, (u16_t)mtu32);
} else {
inp->mtu6 = (u16_t)mtu32;
}
#endif /* LWIP_ND6_ALLOW_RA_UPDATES */ #endif /* LWIP_ND6_ALLOW_RA_UPDATES */
} }
break; break;
@ -1965,7 +1972,7 @@ nd6_get_next_hop_entry(const ip6_addr_t *ip6addr, struct netif *netif)
if (ip6_addr_islinklocal(ip6addr) || if (ip6_addr_islinklocal(ip6addr) ||
nd6_is_prefix_in_netif(ip6addr, netif)) { nd6_is_prefix_in_netif(ip6addr, netif)) {
/* Destination in local link. */ /* Destination in local link. */
destination_cache[nd6_cached_destination_index].pmtu = netif->mtu; destination_cache[nd6_cached_destination_index].pmtu = netif_mtu6(netif);
ip6_addr_copy(destination_cache[nd6_cached_destination_index].next_hop_addr, destination_cache[nd6_cached_destination_index].destination_addr); ip6_addr_copy(destination_cache[nd6_cached_destination_index].next_hop_addr, destination_cache[nd6_cached_destination_index].destination_addr);
#ifdef LWIP_HOOK_ND6_GET_GW #ifdef LWIP_HOOK_ND6_GET_GW
} else if ((next_hop_addr = LWIP_HOOK_ND6_GET_GW(netif, ip6addr)) != NULL) { } else if ((next_hop_addr = LWIP_HOOK_ND6_GET_GW(netif, ip6addr)) != NULL) {
@ -1981,7 +1988,7 @@ nd6_get_next_hop_entry(const ip6_addr_t *ip6addr, struct netif *netif)
ip6_addr_set_any(&(destination_cache[nd6_cached_destination_index].destination_addr)); ip6_addr_set_any(&(destination_cache[nd6_cached_destination_index].destination_addr));
return ERR_RTE; return ERR_RTE;
} }
destination_cache[nd6_cached_destination_index].pmtu = netif->mtu; /* Start with netif mtu, correct through ICMPv6 if necessary */ destination_cache[nd6_cached_destination_index].pmtu = netif_mtu6(netif); /* Start with netif mtu, correct through ICMPv6 if necessary */
ip6_addr_copy(destination_cache[nd6_cached_destination_index].next_hop_addr, default_router_list[i].neighbor_entry->next_hop_address); ip6_addr_copy(destination_cache[nd6_cached_destination_index].next_hop_addr, default_router_list[i].neighbor_entry->next_hop_address);
} }
} }
@ -2290,7 +2297,7 @@ nd6_get_destination_mtu(const ip6_addr_t *ip6addr, struct netif *netif)
} }
if (netif != NULL) { if (netif != NULL) {
return netif->mtu; return netif_mtu6(netif);
} }
return 1280; /* Minimum MTU */ return 1280; /* Minimum MTU */

View File

@ -324,6 +324,7 @@ netif_add(struct netif *netif,
netif->output_ip6 = netif_null_output_ip6; netif->output_ip6 = netif_null_output_ip6;
#endif /* LWIP_IPV6 */ #endif /* LWIP_IPV6 */
NETIF_SET_CHECKSUM_CTRL(netif, NETIF_CHECKSUM_ENABLE_ALL); NETIF_SET_CHECKSUM_CTRL(netif, NETIF_CHECKSUM_ENABLE_ALL);
netif->mtu = 0;
netif->flags = 0; netif->flags = 0;
#ifdef netif_get_client_data #ifdef netif_get_client_data
memset(netif->client_data, 0, sizeof(netif->client_data)); memset(netif->client_data, 0, sizeof(netif->client_data));
@ -370,6 +371,11 @@ netif_add(struct netif *netif,
if (init(netif) != ERR_OK) { if (init(netif) != ERR_OK) {
return NULL; return NULL;
} }
#if LWIP_IPV6 && LWIP_ND6_ALLOW_RA_UPDATES
/* Initialize the MTU for IPv6 to the one set by the netif driver.
This can be updated later by RA. */
netif->mtu6 = netif->mtu;
#endif /* LWIP_IPV6 && LWIP_ND6_ALLOW_RA_UPDATES */
#if !LWIP_SINGLE_NETIF #if !LWIP_SINGLE_NETIF
/* Assign a unique netif number in the range [0..254], so that (num+1) can /* Assign a unique netif number in the range [0..254], so that (num+1) can

View File

@ -333,6 +333,10 @@ struct netif {
#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF*/ #endif /* LWIP_CHECKSUM_CTRL_PER_NETIF*/
/** maximum transfer unit (in bytes) */ /** maximum transfer unit (in bytes) */
u16_t mtu; u16_t mtu;
#if LWIP_IPV6 && LWIP_ND6_ALLOW_RA_UPDATES
/** maximum transfer unit (in bytes), updated by RA */
u16_t mtu6;
#endif /* LWIP_IPV6 && LWIP_ND6_ALLOW_RA_UPDATES */
/** link level hardware address of this interface */ /** link level hardware address of this interface */
u8_t hwaddr[NETIF_MAX_HWADDR_LEN]; u8_t hwaddr[NETIF_MAX_HWADDR_LEN];
/** number of bytes used in hwaddr */ /** number of bytes used in hwaddr */
@ -529,6 +533,11 @@ err_t netif_add_ip6_address(struct netif *netif, const ip6_addr_t *ip6addr, s8_t
#else /* !LWIP_IPV6_ADDRESS_LIFETIMES */ #else /* !LWIP_IPV6_ADDRESS_LIFETIMES */
#define netif_ip6_addr_isstatic(netif, i) (1) /* all addresses are static */ #define netif_ip6_addr_isstatic(netif, i) (1) /* all addresses are static */
#endif /* !LWIP_IPV6_ADDRESS_LIFETIMES */ #endif /* !LWIP_IPV6_ADDRESS_LIFETIMES */
#if LWIP_ND6_ALLOW_RA_UPDATES
#define netif_mtu6(netif) ((netif)->mtu6)
#else /* LWIP_ND6_ALLOW_RA_UPDATES */
#define netif_mtu6(netif) ((netif)->mtu)
#endif /* LWIP_ND6_ALLOW_RA_UPDATES */
#endif /* LWIP_IPV6 */ #endif /* LWIP_IPV6 */
#if LWIP_NETIF_USE_HINTS #if LWIP_NETIF_USE_HINTS