From 7c9a6317b9340b0f65c839fee51ea1e4266d284d Mon Sep 17 00:00:00 2001 From: goldsimon Date: Wed, 1 Mar 2017 14:09:18 +0100 Subject: [PATCH] refactor ip4/ip6 packet-to-netif matching to remove the ugly 'first' flag --- src/core/ipv4/ip4.c | 110 +++++++++++++++++++++++--------------------- src/core/ipv6/ip6.c | 108 ++++++++++++++++++++++--------------------- 2 files changed, 113 insertions(+), 105 deletions(-) diff --git a/src/core/ipv4/ip4.c b/src/core/ipv4/ip4.c index 4e4eb611..6a5eab64 100644 --- a/src/core/ipv4/ip4.c +++ b/src/core/ipv4/ip4.c @@ -356,6 +356,45 @@ return_noroute: } #endif /* IP_FORWARD */ +/** Return true if the current input packet should be accepted on this netif */ +static struct netif* +ip4_input_accept(struct netif *netif) +{ + LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%"X32_F" netif->ip_addr 0x%"X32_F" (0x%"X32_F", 0x%"X32_F", 0x%"X32_F")\n", + ip4_addr_get_u32(ip4_current_dest_addr()), ip4_addr_get_u32(netif_ip4_addr(netif)), + ip4_addr_get_u32(ip4_current_dest_addr()) & ip4_addr_get_u32(netif_ip4_netmask(netif)), + ip4_addr_get_u32(netif_ip4_addr(netif)) & ip4_addr_get_u32(netif_ip4_netmask(netif)), + ip4_addr_get_u32(ip4_current_dest_addr()) & ~ip4_addr_get_u32(netif_ip4_netmask(netif)))); + + /* interface is up and configured? */ + if ((netif_is_up(netif)) && (!ip4_addr_isany_val(*netif_ip4_addr(netif)))) { + /* unicast to this interface address? */ + if (ip4_addr_cmp(ip4_current_dest_addr(), netif_ip4_addr(netif)) || + /* or broadcast on this interface network address? */ + ip4_addr_isbroadcast(ip4_current_dest_addr(), netif) +#if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF + || (ip4_addr_get_u32(ip4_current_dest_addr()) == PP_HTONL(IPADDR_LOOPBACK)) +#endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */ + ) { + LWIP_DEBUGF(IP_DEBUG, ("ip4_input: packet accepted on interface %c%c\n", + netif->name[0], netif->name[1])); + /* accept on this netif */ + return netif; + } +#if LWIP_AUTOIP + /* connections to link-local addresses must persist after changing + the netif's address (RFC3927 ch. 1.9) */ + if (autoip_accept_packet(netif, ip4_current_dest_addr())) { + LWIP_DEBUGF(IP_DEBUG, ("ip4_input: LLA packet accepted on interface %c%c\n", + netif->name[0], netif->name[1])); + /* accept on this netif */ + return netif; + } +#endif /* LWIP_AUTOIP */ + } + return NULL; +} + /** * This function is called by the network interface device driver when * an IP packet is received. The function does the basic checks of the @@ -484,62 +523,27 @@ ip4_input(struct pbuf *p, struct netif *inp) #endif /* LWIP_IGMP */ } else { /* start trying with inp. if that's not acceptable, start walking the - list of configured netifs. - 'first' is used as a boolean to mark whether we started walking the list */ - int first = 1; - netif = inp; - do { - LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%"X32_F" netif->ip_addr 0x%"X32_F" (0x%"X32_F", 0x%"X32_F", 0x%"X32_F")\n", - ip4_addr_get_u32(&iphdr->dest), ip4_addr_get_u32(netif_ip4_addr(netif)), - ip4_addr_get_u32(&iphdr->dest) & ip4_addr_get_u32(netif_ip4_netmask(netif)), - ip4_addr_get_u32(netif_ip4_addr(netif)) & ip4_addr_get_u32(netif_ip4_netmask(netif)), - ip4_addr_get_u32(&iphdr->dest) & ~ip4_addr_get_u32(netif_ip4_netmask(netif)))); - - /* interface is up and configured? */ - if ((netif_is_up(netif)) && (!ip4_addr_isany_val(*netif_ip4_addr(netif)))) { - /* unicast to this interface address? */ - if (ip4_addr_cmp(ip4_current_dest_addr(), netif_ip4_addr(netif)) || - /* or broadcast on this interface network address? */ - ip4_addr_isbroadcast(ip4_current_dest_addr(), netif) -#if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF - || (ip4_addr_get_u32(ip4_current_dest_addr()) == PP_HTONL(IPADDR_LOOPBACK)) -#endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */ - ) { - LWIP_DEBUGF(IP_DEBUG, ("ip4_input: packet accepted on interface %c%c\n", - netif->name[0], netif->name[1])); - /* break out of for loop */ - break; - } -#if LWIP_AUTOIP - /* connections to link-local addresses must persist after changing - the netif's address (RFC3927 ch. 1.9) */ - if (autoip_accept_packet(netif, ip4_current_dest_addr())) { - LWIP_DEBUGF(IP_DEBUG, ("ip4_input: LLA packet accepted on interface %c%c\n", - netif->name[0], netif->name[1])); - /* break out of for loop */ - break; - } -#endif /* LWIP_AUTOIP */ - } - if (first) { + list of configured netifs. */ + netif = ip4_input_accept(inp); + if (netif == NULL) { #if !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF - /* Packets sent to the loopback address must not be accepted on an - * interface that does not have the loopback address assigned to it, - * unless a non-loopback interface is used for loopback traffic. */ - if (ip4_addr_isloopback(ip4_current_dest_addr())) { - netif = NULL; - break; - } + /* Packets sent to the loopback address must not be accepted on an + * interface that does not have the loopback address assigned to it, + * unless a non-loopback interface is used for loopback traffic. */ + if (!ip4_addr_isloopback(ip4_current_dest_addr())) #endif /* !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF */ - first = 0; - netif = netif_list; - } else { - netif = netif->next; + { + NETIF_FOREACH(netif) { + if (netif == inp) { + /* we checked that before already */ + continue; + } + if (ip4_input_accept(netif)) { + break; + } + } } - if (netif == inp) { - netif = netif->next; - } - } while (netif != NULL); + } } #if IP_ACCEPT_LINK_LAYER_ADDRESSING diff --git a/src/core/ipv6/ip6.c b/src/core/ipv6/ip6.c index 59d112d9..3a5ed835 100644 --- a/src/core/ipv6/ip6.c +++ b/src/core/ipv6/ip6.c @@ -457,6 +457,33 @@ ip6_forward(struct pbuf *p, struct ip6_hdr *iphdr, struct netif *inp) } #endif /* LWIP_IPV6_FORWARD */ +/** Return true if the current input packet should be accepted on this netif */ +static struct netif* +ip6_input_accept(struct netif *netif) +{ + /* interface is up? */ + if (netif_is_up(netif)) { + u8_t i; + /* unicast to this interface address? address configured? */ + /* If custom scopes are used, the destination zone will be tested as + * part of the local-address comparison, but we need to test the source + * scope as well (e.g., is this interface on the same link?). */ + for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { + if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && + ip6_addr_cmp(ip6_current_dest_addr(), netif_ip6_addr(netif, i)) +#if IPV6_CUSTOM_SCOPES + && (!ip6_addr_has_zone(ip6_current_src_addr()) || + ip6_addr_test_zone(ip6_current_src_addr(), netif)) +#endif /* IPV6_CUSTOM_SCOPES */ + ) { + /* accept on this netif */ + return netif; + } + } + } + return NULL; +} + /** * This function is called by the network interface device driver when * an IPv6 packet is received. The function does the basic checks of the @@ -478,7 +505,6 @@ ip6_input(struct pbuf *p, struct netif *inp) struct netif *netif; u8_t nexth; u16_t hlen; /* the current header length */ - u8_t i; #if 0 /*IP_ACCEPT_LINK_LAYER_ADDRESSING*/ @todo int check_ip_src=1; @@ -565,6 +591,7 @@ ip6_input(struct pbuf *p, struct netif *inp) } #else /* LWIP_IPV6_MLD */ else if (ip6_addr_issolicitednode(ip6_current_dest_addr())) { + u8_t i; /* Filter solicited node packets when MLD is not enabled * (for Neighbor discovery). */ netif = NULL; @@ -584,63 +611,40 @@ ip6_input(struct pbuf *p, struct netif *inp) } } else { /* start trying with inp. if that's not acceptable, start walking the - list of configured netifs. - 'first' is used as a boolean to mark whether we started walking the list */ - int first = 1; - netif = inp; - do { - /* interface is up? */ - if (netif_is_up(netif)) { - /* unicast to this interface address? address configured? */ - /* If custom scopes are used, the destination zone will be tested as - * part of the local-address comparison, but we need to test the source - * scope as well (e.g., is this interface on the same link?). */ - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && - ip6_addr_cmp(ip6_current_dest_addr(), netif_ip6_addr(netif, i)) -#if IPV6_CUSTOM_SCOPES - && (!ip6_addr_has_zone(ip6_current_src_addr()) || - ip6_addr_test_zone(ip6_current_src_addr(), netif)) -#endif /* IPV6_CUSTOM_SCOPES */ - ) { - /* exit outer loop */ - goto netif_found; - } - } - } - if (first) { + list of configured netifs. */ + netif = ip6_input_accept(inp); + if (netif == NULL) { #if !IPV6_CUSTOM_SCOPES - /* Shortcut: stop looking for other interfaces if either the source or - * the destination has a scope constrained to this interface. Custom - * scopes may break the 1:1 link/interface mapping, however. */ - if (ip6_addr_islinklocal(ip6_current_dest_addr()) || - ip6_addr_islinklocal(ip6_current_src_addr())) { - netif = NULL; - break; - } + /* Shortcut: stop looking for other interfaces if either the source or + * the destination has a scope constrained to this interface. Custom + * scopes may break the 1:1 link/interface mapping, however. */ + if (ip6_addr_islinklocal(ip6_current_dest_addr()) || + ip6_addr_islinklocal(ip6_current_src_addr())) { + goto netif_found; + } #endif /* !IPV6_CUSTOM_SCOPES */ #if !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF - /* The loopback address is to be considered link-local. Packets to it - * should be dropped on other interfaces, as per RFC 4291 Sec. 2.5.3. - * Its implied scope means packets *from* the loopback address should - * not be accepted on other interfaces, either. These requirements - * cannot be implemented in the case that loopback traffic is sent - * across a non-loopback interface, however. */ - if (ip6_addr_isloopback(ip6_current_dest_addr()) || - ip6_addr_isloopback(ip6_current_src_addr())) { - netif = NULL; + /* The loopback address is to be considered link-local. Packets to it + * should be dropped on other interfaces, as per RFC 4291 Sec. 2.5.3. + * Its implied scope means packets *from* the loopback address should + * not be accepted on other interfaces, either. These requirements + * cannot be implemented in the case that loopback traffic is sent + * across a non-loopback interface, however. */ + if (ip6_addr_isloopback(ip6_current_dest_addr()) || + ip6_addr_isloopback(ip6_current_src_addr())) { + goto netif_found; + } +#endif /* !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF */ + NETIF_FOREACH(netif) { + if (netif == inp) { + /* we checked that before already */ + continue; + } + if (ip6_input_accept(netif)) { break; } -#endif /* !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF */ - first = 0; - netif = netif_list; - } else { - netif = netif->next; } - if (netif == inp) { - netif = netif->next; - } - } while (netif != NULL); + } netif_found: LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet accepted on interface %c%c\n", netif ? netif->name[0] : 'X', netif? netif->name[1] : 'X'));