refactor ip4/ip6 packet-to-netif matching to remove the ugly 'first' flag

This commit is contained in:
goldsimon 2017-03-01 14:09:18 +01:00
parent ec4f00179d
commit 7c9a6317b9
2 changed files with 113 additions and 105 deletions

View File

@ -356,6 +356,45 @@ return_noroute:
} }
#endif /* IP_FORWARD */ #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 * This function is called by the network interface device driver when
* an IP packet is received. The function does the basic checks of the * 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 */ #endif /* LWIP_IGMP */
} else { } else {
/* start trying with inp. if that's not acceptable, start walking the /* start trying with inp. if that's not acceptable, start walking the
list of configured netifs. list of configured netifs. */
'first' is used as a boolean to mark whether we started walking the list */ netif = ip4_input_accept(inp);
int first = 1; if (netif == NULL) {
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) {
#if !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF #if !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF
/* Packets sent to the loopback address must not be accepted on an /* Packets sent to the loopback address must not be accepted on an
* interface that does not have the loopback address assigned to it, * interface that does not have the loopback address assigned to it,
* unless a non-loopback interface is used for loopback traffic. */ * unless a non-loopback interface is used for loopback traffic. */
if (ip4_addr_isloopback(ip4_current_dest_addr())) { if (!ip4_addr_isloopback(ip4_current_dest_addr()))
netif = NULL;
break;
}
#endif /* !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF */ #endif /* !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF */
first = 0; {
netif = netif_list; NETIF_FOREACH(netif) {
} else { if (netif == inp) {
netif = netif->next; /* 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 #if IP_ACCEPT_LINK_LAYER_ADDRESSING

View File

@ -457,6 +457,33 @@ ip6_forward(struct pbuf *p, struct ip6_hdr *iphdr, struct netif *inp)
} }
#endif /* LWIP_IPV6_FORWARD */ #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 * This function is called by the network interface device driver when
* an IPv6 packet is received. The function does the basic checks of the * 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; struct netif *netif;
u8_t nexth; u8_t nexth;
u16_t hlen; /* the current header length */ u16_t hlen; /* the current header length */
u8_t i;
#if 0 /*IP_ACCEPT_LINK_LAYER_ADDRESSING*/ #if 0 /*IP_ACCEPT_LINK_LAYER_ADDRESSING*/
@todo @todo
int check_ip_src=1; int check_ip_src=1;
@ -565,6 +591,7 @@ ip6_input(struct pbuf *p, struct netif *inp)
} }
#else /* LWIP_IPV6_MLD */ #else /* LWIP_IPV6_MLD */
else if (ip6_addr_issolicitednode(ip6_current_dest_addr())) { else if (ip6_addr_issolicitednode(ip6_current_dest_addr())) {
u8_t i;
/* Filter solicited node packets when MLD is not enabled /* Filter solicited node packets when MLD is not enabled
* (for Neighbor discovery). */ * (for Neighbor discovery). */
netif = NULL; netif = NULL;
@ -584,63 +611,40 @@ ip6_input(struct pbuf *p, struct netif *inp)
} }
} else { } else {
/* start trying with inp. if that's not acceptable, start walking the /* start trying with inp. if that's not acceptable, start walking the
list of configured netifs. list of configured netifs. */
'first' is used as a boolean to mark whether we started walking the list */ netif = ip6_input_accept(inp);
int first = 1; if (netif == NULL) {
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) {
#if !IPV6_CUSTOM_SCOPES #if !IPV6_CUSTOM_SCOPES
/* Shortcut: stop looking for other interfaces if either the source or /* Shortcut: stop looking for other interfaces if either the source or
* the destination has a scope constrained to this interface. Custom * the destination has a scope constrained to this interface. Custom
* scopes may break the 1:1 link/interface mapping, however. */ * scopes may break the 1:1 link/interface mapping, however. */
if (ip6_addr_islinklocal(ip6_current_dest_addr()) || if (ip6_addr_islinklocal(ip6_current_dest_addr()) ||
ip6_addr_islinklocal(ip6_current_src_addr())) { ip6_addr_islinklocal(ip6_current_src_addr())) {
netif = NULL; goto netif_found;
break; }
}
#endif /* !IPV6_CUSTOM_SCOPES */ #endif /* !IPV6_CUSTOM_SCOPES */
#if !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF #if !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF
/* The loopback address is to be considered link-local. Packets to it /* 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. * should be dropped on other interfaces, as per RFC 4291 Sec. 2.5.3.
* Its implied scope means packets *from* the loopback address should * Its implied scope means packets *from* the loopback address should
* not be accepted on other interfaces, either. These requirements * not be accepted on other interfaces, either. These requirements
* cannot be implemented in the case that loopback traffic is sent * cannot be implemented in the case that loopback traffic is sent
* across a non-loopback interface, however. */ * across a non-loopback interface, however. */
if (ip6_addr_isloopback(ip6_current_dest_addr()) || if (ip6_addr_isloopback(ip6_current_dest_addr()) ||
ip6_addr_isloopback(ip6_current_src_addr())) { ip6_addr_isloopback(ip6_current_src_addr())) {
netif = NULL; 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; 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: netif_found:
LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet accepted on interface %c%c\n", LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet accepted on interface %c%c\n",
netif ? netif->name[0] : 'X', netif? netif->name[1] : 'X')); netif ? netif->name[0] : 'X', netif? netif->name[1] : 'X'));