diff --git a/CHANGELOG b/CHANGELOG index ba8e8c97..672e3ee2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -202,6 +202,14 @@ HISTORY ++ Bugfixes: + 2015-02-25: Simon Goldschmidt + * ip4.h/.c, udp.c: fixed bug #38061 (wrong multicast routing in IPv4) by + adding an optional default netif for multicast routing + + 2015-02-25: Simon Goldschmidt + * netconn API: fixed that netconn_connect still used message passing for + LWIP_TCPIP_CORE_LOCKING==1 + 2015-02-22: patch by Jens Nielsen * icmp.c: fixed bug #38803 (Source address in broadcast ping reply) @@ -239,17 +247,17 @@ HISTORY 2015-02-11: patch by hichard * tcpip.c: fixed bug #43094 "The function tcpip_input() forget to handle IPv6" - 2014-02-10: Simon Goldschmidt + 2015-02-10: Simon Goldschmidt * netconn API: fixed that netconn_close/netconn_delete still used message passing for LWIP_TCPIP_CORE_LOCKING==1 - 2014-02-10: Simon Goldschmidt + 2015-02-10: Simon Goldschmidt * netconn/socket api: fixed bug #44225 "closing TCP socket should time out eventually", implemented task #6930 "Implement SO_LINGER": closing TCP sockets times out after 20 seconds or after the configured SND_TIMEOUT or depending on the linger settings. - 2014-01-27: Simon Goldschmidt + 2015-01-27: Simon Goldschmidt * api_msg.c: fixed that SHUT_RD followed by SHUT_WR was different to SHUT_RDWR, fixed return value of lwip_netconn_do_close on unconnected netconns diff --git a/src/core/ipv4/ip4.c b/src/core/ipv4/ip4.c index 3693e2f9..4571ac26 100644 --- a/src/core/ipv4/ip4.c +++ b/src/core/ipv4/ip4.c @@ -98,6 +98,18 @@ struct ip_globals ip_data; /** The IP header ID of the next outgoing IP packet */ static u16_t ip_id; +#if LWIP_IGMP +/** The default netif used for multicast */ +static struct netif* ip_default_multicast_netif; + +/** Set a default netif for IPv4 multicast. */ +void +ip_set_default_multicast_netif(struct netif* default_multicast_netif) +{ + ip_default_multicast_netif = default_multicast_netif; +} +#endif /* LWIP_IGMP */ + /** * Finds the appropriate network interface for a given IP address. It * searches the list of network interfaces linearly. A match is found @@ -119,6 +131,13 @@ ip_route(const ip_addr_t *dest) } #endif +#if LWIP_IGMP + /* Use administratively selected interface for multicast by default */ + if (ip_addr_ismulticast(dest) && ip_default_multicast_netif) { + return ip_default_multicast_netif; + } +#endif /* LWIP_IGMP */ + /* iterate through netifs */ for (netif = netif_list; netif != NULL; netif = netif->next) { /* network mask matches? */ diff --git a/src/core/udp.c b/src/core/udp.c index 1f58a891..155d8b5e 100644 --- a/src/core/udp.c +++ b/src/core/udp.c @@ -559,15 +559,22 @@ udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip, #if LWIP_IPV6 || LWIP_IGMP if (ipX_addr_ismulticast(PCB_ISIPV6(pcb), dst_ip_route)) { - /* For multicast, find a netif based on source address. */ #if LWIP_IPV6 if (PCB_ISIPV6(pcb)) { + /* For multicast, find a netif based on source address. */ dst_ip_route = &pcb->local_ip; } else #endif /* LWIP_IPV6 */ { #if LWIP_IGMP - dst_ip_route = ip_2_ipX(&pcb->multicast_ip); + /* IPv4 does not use source-based routing by default, so we use an + administratively selected interface for multicast by default. + However, this can be overridden by setting an interface address + in pcb->multicast_ip that is used for routing. */ + if (!ip_addr_isany(&pcb->multicast_ip) && + !ip_addr_cmp(&pcb->multicast_ip, IP_ADDR_BROADCAST)) { + dst_ip_route = ip_2_ipX(&pcb->multicast_ip); + } #endif /* LWIP_IGMP */ } } diff --git a/src/include/lwip/ip4.h b/src/include/lwip/ip4.h index 1c1eea29..d461c085 100644 --- a/src/include/lwip/ip4.h +++ b/src/include/lwip/ip4.h @@ -133,6 +133,10 @@ err_t ip_output_if_opt_src(struct pbuf *p, const ip_addr_t *src, const ip_addr_t u16_t optlen); #endif /* IP_OPTIONS_SEND */ +#if LWIP_IGMP +void ip_set_default_multicast_netif(struct netif* default_multicast_netif); +#endif /* LWIP_IGMP */ + #define ip_netif_get_local_ipX(netif) (((netif) != NULL) ? ip_2_ipX(&((netif)->ip_addr)) : NULL) #if IP_DEBUG