From 521c92764dc12d9fed4dc36ab31f2731a71fa435 Mon Sep 17 00:00:00 2001 From: sg Date: Tue, 24 Mar 2015 21:22:19 +0100 Subject: [PATCH] loopif is not required for loopback traffic any more but passed through any netif (ENABLE_LOOPBACK has to be enabled) (task #13515) --- CHANGELOG | 3 +++ src/core/ipv4/ip4.c | 33 +++++++++++++++++++++++++++++++-- src/core/ipv6/ip6.c | 22 ++++++++++++++++++++++ src/include/lwip/ip4_addr.h | 2 ++ src/include/lwip/opt.h | 4 +++- 5 files changed, 61 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 26f56e6c..0a393b56 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,6 +6,9 @@ HISTORY ++ New features: + * opt.h, ip4_addr.h, ip4.c, ip6.c: loopif is not required for loopback traffic + any more but passed through any netif (ENABLE_LOOPBACK has to be enabled) + 2015-03-23: Simon Goldschmidt * opt.h, etharp.c: with ETHARP_TABLE_MATCH_NETIF== 1, duplicate (Auto)-IP addresses on multiple netifs should now be working correctly (if correctly diff --git a/src/core/ipv4/ip4.c b/src/core/ipv4/ip4.c index eccf0df3..88e905cd 100644 --- a/src/core/ipv4/ip4.c +++ b/src/core/ipv4/ip4.c @@ -160,7 +160,28 @@ ip_route(const ip_addr_t *dest) snmp_inc_ipoutnoroutes(); return NULL; } + +#if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF + /* loopif is disabled, looopback traffic is passed through any netif */ + if (ip_addr_isloopback(dest)) { + /* don't check for link on loopback traffic */ + if (netif_is_up(netif_default)) { + return netif_default; + } + /* default netif is not up, just use any netif for loopback traffic */ + for (netif = netif_list; netif != NULL; netif = netif->next) { + if (netif_is_up(netif)) { + return netif; + } + } + return NULL; + } +#endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */ + /* no matching netif found, use default netif */ + if (!netif_is_up(netif_default) || !netif_is_link_up(netif_default)) { + return NULL; + } return netif_default; } @@ -431,7 +452,11 @@ ip_input(struct pbuf *p, struct netif *inp) /* unicast to this interface address? */ if (ip_addr_cmp(ip_current_dest_addr(), &(netif->ip_addr)) || /* or broadcast on this interface network address? */ - ip_addr_isbroadcast(ip_current_dest_addr(), netif)) { + ip_addr_isbroadcast(ip_current_dest_addr(), netif) +#if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF + || (ip4_addr_get_u32(ip_current_dest_addr()) == PP_HTONL(IPADDR_LOOPBACK)) +#endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */ + ) { LWIP_DEBUGF(IP_DEBUG, ("ip_input: packet accepted on interface %c%c\n", netif->name[0], netif->name[1])); /* break out of for loop */ @@ -841,7 +866,11 @@ err_t ip_output_if_opt_src(struct pbuf *p, const ip_addr_t *src, const ip_addr_t ip_debug_print(p); #if ENABLE_LOOPBACK - if (ip_addr_cmp(dest, &netif->ip_addr)) { + if (ip_addr_cmp(dest, &netif->ip_addr) +#if !LWIP_HAVE_LOOPIF + || ip_addr_isloopback(dest) +#endif /* !LWIP_HAVE_LOOPIF */ + ) { /* Packet to self, enqueue it for loopback */ LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()")); return netif_loop_output(netif, p); diff --git a/src/core/ipv6/ip6.c b/src/core/ipv6/ip6.c index 358640e8..c381a2f4 100644 --- a/src/core/ipv6/ip6.c +++ b/src/core/ipv6/ip6.c @@ -168,6 +168,23 @@ ip6_route(const struct ip6_addr *src, const struct ip6_addr *dest) } } +#if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF + /* loopif is disabled, loopback traffic is passed through any netif */ + if (ip6_addr_isloopback(dest)) { + /* don't check for link on loopback traffic */ + if (netif_is_up(netif_default)) { + return netif_default; + } + /* default netif is not up, just use any netif for loopback traffic */ + for (netif = netif_list; netif != NULL; netif = netif->next) { + if (netif_is_up(netif)) { + return netif; + } + } + return NULL; + } +#endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */ + /* no matching netif found, use default netif, if up */ if (!netif_is_up(netif_default) || !netif_is_link_up(netif_default)) { return NULL; @@ -855,6 +872,11 @@ ip6_output_if_src(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, #if ENABLE_LOOPBACK { int i; +#if !LWIP_HAVE_LOOPIF + if (ip6_addr_isloopback(dest)) { + return netif_loop_output(netif, p); + } +#endif /* !LWIP_HAVE_LOOPIF */ for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && ip6_addr_cmp(dest, netif_ip6_addr(netif, i))) { diff --git a/src/include/lwip/ip4_addr.h b/src/include/lwip/ip4_addr.h index e46314c2..e6245e6b 100644 --- a/src/include/lwip/ip4_addr.h +++ b/src/include/lwip/ip4_addr.h @@ -170,6 +170,8 @@ extern const ip_addr_t ip_addr_broadcast; #define ip_addr_set_any(ipaddr) ((ipaddr)->addr = IPADDR_ANY) /** Set address to loopback address */ #define ip_addr_set_loopback(ipaddr) ((ipaddr)->addr = PP_HTONL(IPADDR_LOOPBACK)) +/** Check if an address is in the loopback region */ +#define ip_addr_isloopback(ipaddr) (((ipaddr)->addr & PP_HTONL(IP_CLASSA_NET)) == PP_HTONL(((u32_t)IP_LOOPBACKNET) << 24)) /** Safely copy one IP address to another and change byte order * from host- to network-order. */ #define ip_addr_set_hton(dest, src) ((dest)->addr = \ diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index 89b2afd6..2af84e4b 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -1375,7 +1375,9 @@ ------------------------------------ */ /** - * LWIP_HAVE_LOOPIF==1: Support loop interface (127.0.0.1) + * LWIP_HAVE_LOOPIF==1: Support loop interface (127.0.0.1). + * This is only needed when no real netifs are available. If at least one other + * netif is available, loopback traffic uses this netif. */ #ifndef LWIP_HAVE_LOOPIF #define LWIP_HAVE_LOOPIF 0