diff --git a/CHANGELOG b/CHANGELOG index 656c2109..d435a30a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,6 +6,9 @@ HISTORY ++ New features: + 2017-02-28: Simon Goldschmidt + * Added LWIP_SINGLE_NETIF for small targets with only one netif + 2017-02-17: Simon Goldschmidt * Improved DNS_LOCAL_HOSTLIST interface diff --git a/src/apps/snmp/snmp_mib2_interfaces.c b/src/apps/snmp/snmp_mib2_interfaces.c index 979b5073..f5b8619f 100644 --- a/src/apps/snmp/snmp_mib2_interfaces.c +++ b/src/apps/snmp/snmp_mib2_interfaces.c @@ -65,10 +65,9 @@ interfaces_get_value(struct snmp_node_instance* instance, void* value) s32_t *sint_ptr = (s32_t*)value; s32_t num_netifs = 0; - struct netif *netif = netif_list; - while (netif != NULL) { + struct netif *netif; + NETIF_FOREACH(netif) { num_netifs++; - netif = netif->next; } *sint_ptr = num_netifs; @@ -109,14 +108,12 @@ interfaces_Table_get_cell_instance(const u32_t* column, const u32_t* row_oid, u8 ifIndex = row_oid[0]; /* find netif with index */ - netif = netif_list; - while (netif != NULL) { + NETIF_FOREACH(netif) { if (netif_to_num(netif) == ifIndex) { /* store netif pointer for subsequent operations (get/test/set) */ cell_instance->reference.ptr = netif; return SNMP_ERR_NOERROR; } - netif = netif->next; } /* not found */ @@ -136,15 +133,12 @@ interfaces_Table_get_next_cell_instance(const u32_t* column, struct snmp_obj_id* snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(interfaces_Table_oid_ranges)); /* iterate over all possible OIDs to find the next one */ - netif = netif_list; - while (netif != NULL) { + NETIF_FOREACH(netif) { u32_t test_oid[LWIP_ARRAYSIZE(interfaces_Table_oid_ranges)]; test_oid[0] = netif_to_num(netif); /* check generated OID: is it a candidate for the next one? */ snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(interfaces_Table_oid_ranges), netif); - - netif = netif->next; } /* did we find a next one? */ diff --git a/src/apps/snmp/snmp_mib2_ip.c b/src/apps/snmp/snmp_mib2_ip.c index 4f05180a..671aa2a2 100644 --- a/src/apps/snmp/snmp_mib2_ip.c +++ b/src/apps/snmp/snmp_mib2_ip.c @@ -262,14 +262,11 @@ ip_AddrTable_get_cell_value(const u32_t* column, const u32_t* row_oid, u8_t row_ snmp_oid_to_ip4(&row_oid[0], &ip); /* we know it succeeds because of oid_in_range check above */ /* find netif with requested ip */ - netif = netif_list; - while (netif != NULL) { + NETIF_FOREACH(netif) { if (ip4_addr_cmp(&ip, netif_ip4_addr(netif))) { /* fill in object properties */ return ip_AddrTable_get_cell_value_core(netif, column, value, value_len); } - - netif = netif->next; } /* not found */ @@ -287,15 +284,12 @@ ip_AddrTable_get_next_cell_instance_and_value(const u32_t* column, struct snmp_o snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(ip_AddrTable_oid_ranges)); /* iterate over all possible OIDs to find the next one */ - netif = netif_list; - while (netif != NULL) { + NETIF_FOREACH(netif) { u32_t test_oid[LWIP_ARRAYSIZE(ip_AddrTable_oid_ranges)]; snmp_ip4_to_oid(netif_ip4_addr(netif), &test_oid[0]); /* check generated OID: is it a candidate for the next one? */ snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(ip_AddrTable_oid_ranges), netif); - - netif = netif->next; } /* did we find a next one? */ @@ -419,8 +413,7 @@ ip_RouteTable_get_cell_value(const u32_t* column, const u32_t* row_oid, u8_t row } /* find netif with requested route */ - netif = netif_list; - while (netif != NULL) { + NETIF_FOREACH(netif) { ip4_addr_t dst; ip4_addr_get_network(&dst, netif_ip4_addr(netif), netif_ip4_netmask(netif)); @@ -428,8 +421,6 @@ ip_RouteTable_get_cell_value(const u32_t* column, const u32_t* row_oid, u8_t row /* fill in object properties */ return ip_RouteTable_get_cell_value_core(netif, 0, column, value, value_len); } - - netif = netif->next; } /* not found */ @@ -454,8 +445,7 @@ ip_RouteTable_get_next_cell_instance_and_value(const u32_t* column, struct snmp_ } /* iterate over all possible OIDs to find the next one */ - netif = netif_list; - while (netif != NULL) { + NETIF_FOREACH(netif) { ip4_addr_t dst; ip4_addr_get_network(&dst, netif_ip4_addr(netif), netif_ip4_netmask(netif)); @@ -464,8 +454,6 @@ ip_RouteTable_get_next_cell_instance_and_value(const u32_t* column, struct snmp_ snmp_ip4_to_oid(&dst, &test_oid[0]); snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(ip_RouteTable_oid_ranges), netif); } - - netif = netif->next; } /* did we find a next one? */ diff --git a/src/core/ipv4/autoip.c b/src/core/ipv4/autoip.c index 68e12628..964fa2b7 100644 --- a/src/core/ipv4/autoip.c +++ b/src/core/ipv4/autoip.c @@ -364,9 +364,9 @@ autoip_stop(struct netif *netif) void autoip_tmr(void) { - struct netif *netif = netif_list; + struct netif *netif; /* loop through netif's */ - while (netif != NULL) { + NETIF_FOREACH(netif) { struct autoip* autoip = netif_autoip_data(netif); /* only act on AutoIP configured interfaces */ if (autoip != NULL) { @@ -438,8 +438,6 @@ autoip_tmr(void) break; } } - /* proceed to next network interface */ - netif = netif->next; } } diff --git a/src/core/ipv4/dhcp.c b/src/core/ipv4/dhcp.c index 7cbc03c2..1f16fd80 100644 --- a/src/core/ipv4/dhcp.c +++ b/src/core/ipv4/dhcp.c @@ -408,10 +408,10 @@ dhcp_select(struct netif *netif) void dhcp_coarse_tmr(void) { - struct netif *netif = netif_list; + struct netif *netif; LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_coarse_tmr()\n")); /* iterate through all network interfaces */ - while (netif != NULL) { + NETIF_FOREACH(netif) { /* only act on DHCP configured interfaces */ struct dhcp *dhcp = netif_dhcp_data(netif); if ((dhcp != NULL) && (dhcp->state != DHCP_STATE_OFF)) { @@ -433,8 +433,6 @@ dhcp_coarse_tmr(void) dhcp_t1_timeout(netif); } } - /* proceed to next netif */ - netif = netif->next; } } @@ -448,9 +446,9 @@ dhcp_coarse_tmr(void) void dhcp_fine_tmr(void) { - struct netif *netif = netif_list; + struct netif *netif; /* loop through netif's */ - while (netif != NULL) { + NETIF_FOREACH(netif) { struct dhcp *dhcp = netif_dhcp_data(netif); /* only act on DHCP configured interfaces */ if (dhcp != NULL) { @@ -466,8 +464,6 @@ dhcp_fine_tmr(void) dhcp_timeout(netif); } } - /* proceed to next network interface */ - netif = netif->next; } } diff --git a/src/core/ipv4/igmp.c b/src/core/ipv4/igmp.c index 74a6c377..52c3a111 100644 --- a/src/core/ipv4/igmp.c +++ b/src/core/ipv4/igmp.c @@ -456,8 +456,7 @@ igmp_joingroup(const ip4_addr_t *ifaddr, const ip4_addr_t *groupaddr) LWIP_ERROR("igmp_joingroup: attempt to join allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;); /* loop through netif's */ - netif = netif_list; - while (netif != NULL) { + NETIF_FOREACH(netif) { /* Should we join this interface ? */ if ((netif->flags & NETIF_FLAG_IGMP) && ((ip4_addr_isany(ifaddr) || ip4_addr_cmp(netif_ip4_addr(netif), ifaddr)))) { err = igmp_joingroup_netif(netif, groupaddr); @@ -467,8 +466,6 @@ igmp_joingroup(const ip4_addr_t *ifaddr, const ip4_addr_t *groupaddr) return err; } } - /* proceed to next network interface */ - netif = netif->next; } return err; @@ -552,8 +549,7 @@ igmp_leavegroup(const ip4_addr_t *ifaddr, const ip4_addr_t *groupaddr) LWIP_ERROR("igmp_leavegroup: attempt to leave allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;); /* loop through netif's */ - netif = netif_list; - while (netif != NULL) { + NETIF_FOREACH(netif) { /* Should we leave this interface ? */ if ((netif->flags & NETIF_FLAG_IGMP) && ((ip4_addr_isany(ifaddr) || ip4_addr_cmp(netif_ip4_addr(netif), ifaddr)))) { err_t res = igmp_leavegroup_netif(netif, groupaddr); @@ -562,8 +558,6 @@ igmp_leavegroup(const ip4_addr_t *ifaddr, const ip4_addr_t *groupaddr) err = res; } } - /* proceed to next network interface */ - netif = netif->next; } return err; @@ -638,9 +632,9 @@ igmp_leavegroup_netif(struct netif *netif, const ip4_addr_t *groupaddr) void igmp_tmr(void) { - struct netif *netif = netif_list; + struct netif *netif; - while (netif != NULL) { + NETIF_FOREACH(netif) { struct igmp_group *group = netif_igmp_data(netif); while (group != NULL) { @@ -652,7 +646,6 @@ igmp_tmr(void) } group = group->next; } - netif = netif->next; } } diff --git a/src/core/ipv4/ip4.c b/src/core/ipv4/ip4.c index d9c4ceae..b9de7c34 100644 --- a/src/core/ipv4/ip4.c +++ b/src/core/ipv4/ip4.c @@ -151,6 +151,7 @@ ip4_route_src(const ip4_addr_t *dest, const ip4_addr_t *src) struct netif * ip4_route(const ip4_addr_t *dest) { +#if !LWIP_SINGLE_NETIF struct netif *netif; #if LWIP_MULTICAST_TX_OPTIONS @@ -205,6 +206,7 @@ ip4_route(const ip4_addr_t *dest) return netif; } #endif +#endif /* !LWIP_SINGLE_NETIF */ if ((netif_default == NULL) || !netif_is_up(netif_default) || !netif_is_link_up(netif_default) || ip4_addr_isany_val(*netif_ip4_addr(netif_default))) { @@ -534,7 +536,8 @@ ip4_input(struct pbuf *p, struct netif *inp) if (!ip4_addr_isloopback(ip4_current_dest_addr())) #endif /* !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF */ { - for (netif = netif_list; netif != NULL; netif = netif->next) { +#if ! LWIP_SINGLE_NETIF + NETIF_FOREACH(netif) { if (netif == inp) { /* we checked that before already */ continue; @@ -543,6 +546,7 @@ ip4_input(struct pbuf *p, struct netif *inp) break; } } +#endif /* !LWIP_SINGLE_NETIF */ } } } diff --git a/src/core/ipv6/ip6.c b/src/core/ipv6/ip6.c index 27719286..c2111446 100644 --- a/src/core/ipv6/ip6.c +++ b/src/core/ipv6/ip6.c @@ -85,6 +85,10 @@ struct netif * ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest) { +#if LWIP_SINGLE_NETIF + LWIP_UNUSED_ARG(src); + LWIP_UNUSED_ARG(dest); +#else /* LWIP_SINGLE_NETIF */ struct netif *netif; s8_t i; @@ -239,6 +243,7 @@ ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest) return NULL; } #endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */ +#endif /* !LWIP_SINGLE_NETIF */ /* no matching netif found, use default netif, if up */ if ((netif_default == NULL) || !netif_is_up(netif_default) || !netif_is_link_up(netif_default)) { @@ -636,7 +641,8 @@ ip6_input(struct pbuf *p, struct netif *inp) goto netif_found; } #endif /* !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF */ - for (netif = netif_list; netif != NULL; netif = netif->next) { +#if ! LWIP_SINGLE_NETIF + NETIF_FOREACH(netif) { if (netif == inp) { /* we checked that before already */ continue; @@ -645,6 +651,7 @@ ip6_input(struct pbuf *p, struct netif *inp) break; } } +#endif /* !LWIP_SINGLE_NETIF */ } netif_found: LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet accepted on interface %c%c\n", diff --git a/src/core/ipv6/mld6.c b/src/core/ipv6/mld6.c index 0748c61b..7400a2af 100644 --- a/src/core/ipv6/mld6.c +++ b/src/core/ipv6/mld6.c @@ -313,8 +313,7 @@ mld6_joingroup(const ip6_addr_t *srcaddr, const ip6_addr_t *groupaddr) struct netif *netif; /* loop through netif's */ - netif = netif_list; - while (netif != NULL) { + NETIF_FOREACH(netif) { /* Should we join this interface ? */ if (ip6_addr_isany(srcaddr) || netif_get_ip6_addr_match(netif, srcaddr) >= 0) { @@ -323,9 +322,6 @@ mld6_joingroup(const ip6_addr_t *srcaddr, const ip6_addr_t *groupaddr) return err; } } - - /* proceed to next network interface */ - netif = netif->next; } return err; @@ -402,8 +398,7 @@ mld6_leavegroup(const ip6_addr_t *srcaddr, const ip6_addr_t *groupaddr) struct netif *netif; /* loop through netif's */ - netif = netif_list; - while (netif != NULL) { + NETIF_FOREACH(netif) { /* Should we leave this interface ? */ if (ip6_addr_isany(srcaddr) || netif_get_ip6_addr_match(netif, srcaddr) >= 0) { @@ -413,8 +408,6 @@ mld6_leavegroup(const ip6_addr_t *srcaddr, const ip6_addr_t *groupaddr) err = res; } } - /* proceed to next network interface */ - netif = netif->next; } return err; @@ -489,9 +482,9 @@ mld6_leavegroup_netif(struct netif *netif, const ip6_addr_t *groupaddr) void mld6_tmr(void) { - struct netif *netif = netif_list; + struct netif *netif; - while (netif != NULL) { + NETIF_FOREACH(netif) { struct mld_group *group = netif_mld6_data(netif); while (group != NULL) { @@ -508,7 +501,6 @@ mld6_tmr(void) } group = group->next; } - netif = netif->next; } } diff --git a/src/core/ipv6/nd6.c b/src/core/ipv6/nd6.c index 18b6b755..0122d99c 100644 --- a/src/core/ipv6/nd6.c +++ b/src/core/ipv6/nd6.c @@ -1042,7 +1042,7 @@ nd6_tmr(void) } /* Process our own addresses, updating address lifetimes and/or DAD state. */ - for (netif = netif_list; netif != NULL; netif = netif->next) { + NETIF_FOREACH(netif) { for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) { u8_t addr_state; #if LWIP_IPV6_ADDRESS_LIFETIMES @@ -1121,7 +1121,7 @@ nd6_tmr(void) #if LWIP_IPV6_SEND_ROUTER_SOLICIT /* Send router solicitation messages, if necessary. */ - for (netif = netif_list; netif != NULL; netif = netif->next) { + NETIF_FOREACH(netif) { if ((netif->rs_count > 0) && netif_is_up(netif) && netif_is_link_up(netif) && !ip6_addr_isinvalid(netif_ip6_addr_state(netif, 0)) && diff --git a/src/core/netif.c b/src/core/netif.c index 27fece2b..51044470 100644 --- a/src/core/netif.c +++ b/src/core/netif.c @@ -106,7 +106,9 @@ static netif_ext_callback_t* ext_callback; #endif +#if !LWIP_SINGLE_NETIF struct netif *netif_list; +#endif /* !LWIP_SINGLE_NETIF */ struct netif *netif_default; #define netif_index_to_num(index) ((index) - 1) @@ -250,12 +252,17 @@ netif_add(struct netif *netif, #endif /* LWIP_IPV4 */ void *state, netif_init_fn init, netif_input_fn input) { - struct netif *netif2; - int num_netifs; #if LWIP_IPV6 s8_t i; #endif +#if LWIP_SINGLE_NETIF + if (netif_default != NULL) { + LWIP_ASSERT("single netif already set", 0); + return NULL; + } +#endif + LWIP_ASSERT("No init function given", init != NULL); /* reset new interface configuration state */ @@ -323,30 +330,36 @@ netif_add(struct netif *netif, return NULL; } +#if !LWIP_SINGLE_NETIF /* Assign a unique netif number in the range [0..254], so that (num+1) can serve as an interface index that fits in a u8_t. We assume that the new netif has not yet been added to the list here. This algorithm is O(n^2), but that should be OK for lwIP. */ - do { - if (netif->num == 255) { - netif->num = 0; - } - num_netifs = 0; - for (netif2 = netif_list; netif2 != NULL; netif2 = netif2->next) { - num_netifs++; - LWIP_ASSERT("too many netifs, max. supported number is 255", num_netifs <= 255); - if (netif2->num == netif->num) { - netif->num++; - break; + { + struct netif *netif2; + int num_netifs; + do { + if (netif->num == 255) { + netif->num = 0; } - } - } while (netif2 != NULL); + num_netifs = 0; + for (netif2 = netif_list; netif2 != NULL; netif2 = netif2->next) { + num_netifs++; + LWIP_ASSERT("too many netifs, max. supported number is 255", num_netifs <= 255); + if (netif2->num == netif->num) { + netif->num++; + break; + } + } + } while (netif2 != NULL); + } netif_num = netif->num + 1; /* add this netif to the list */ netif->next = netif_list; netif_list = netif; +#endif /* "LWIP_SINGLE_NETIF */ mib2_netif_added(netif); #if LWIP_IGMP @@ -476,6 +489,7 @@ netif_remove(struct netif *netif) /* reset default netif */ netif_set_default(NULL); } +#if !LWIP_SINGLE_NETIF /* is it the first netif? */ if (netif_list == netif) { netif_list = netif->next; @@ -492,6 +506,7 @@ netif_remove(struct netif *netif) return; /* netif is not on the list */ } } +#endif /* !LWIP_SINGLE_NETIF */ mib2_netif_removed(netif); #if LWIP_NETIF_REMOVE_CALLBACK if (netif->remove_callback) { @@ -1037,12 +1052,10 @@ netif_poll(struct netif *netif) void netif_poll_all(void) { - struct netif *netif = netif_list; + struct netif *netif; /* loop through netifs */ - while (netif != NULL) { + NETIF_FOREACH(netif) { netif_poll(netif); - /* proceed to next network interface */ - netif = netif->next; } } #endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */ @@ -1427,7 +1440,7 @@ netif_get_by_index(u8_t idx) struct netif* netif; if (idx != NETIF_NO_INDEX) { - for (netif = netif_list; netif != NULL; netif = netif->next) { + NETIF_FOREACH(netif) { if (idx == netif_get_index(netif)) { return netif; /* found! */ } @@ -1456,7 +1469,7 @@ netif_find(const char *name) num = (u8_t)atoi(&name[2]); - for (netif = netif_list; netif != NULL; netif = netif->next) { + NETIF_FOREACH(netif) { if (num == netif->num && name[0] == netif->name[0] && name[1] == netif->name[1]) { diff --git a/src/include/lwip/netif.h b/src/include/lwip/netif.h index 37b70b7f..6cdb1ecb 100644 --- a/src/include/lwip/netif.h +++ b/src/include/lwip/netif.h @@ -229,8 +229,10 @@ u8_t netif_alloc_client_data_id(void); * The following fields should be filled in by the initialization * function for the device driver: hwaddr_len, hwaddr[], mtu, flags */ struct netif { +#if !LWIP_SINGLE_NETIF /** pointer to next in linked list */ struct netif *next; +#endif #if LWIP_IPV4 /** IP address configuration in network byte order */ @@ -365,8 +367,13 @@ struct netif { #define IF__NETIF_CHECKSUM_ENABLED(netif, chksumflag) #endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */ +#if LWIP_SINGLE_NETIF +#define NETIF_FOREACH(netif) if (((netif) = netif_default) != NULL) +#else /* LWIP_SINGLE_NETIF */ /** The list of network interfaces. */ extern struct netif *netif_list; +#define NETIF_FOREACH(netif) for (netif = netif_list; netif != NULL; netif = netif->next) +#endif /* LWIP_SINGLE_NETIF */ /** The default network interface. */ extern struct netif *netif_default; diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index d0973e70..e0659f51 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -626,7 +626,7 @@ * (but this should only occur for AutoIP). */ #if !defined ETHARP_TABLE_MATCH_NETIF || defined __DOXYGEN__ -#define ETHARP_TABLE_MATCH_NETIF 0 +#define ETHARP_TABLE_MATCH_NETIF !LWIP_SINGLE_NETIF #endif /** * @} @@ -1417,6 +1417,14 @@ * @ingroup lwip_opts * @{ */ +/** + * LWIP_SINGLE_NETIF==1: use a single netif only. This is the common case for + * small real-life targets. Some code like routing etc. can be left out. + */ +#if !defined LWIP_SINGLE_NETIF || defined __DOXYGEN__ +#define LWIP_SINGLE_NETIF 0 +#endif + /** * LWIP_NETIF_HOSTNAME==1: use DHCP_OPTION_HOSTNAME with netif's hostname * field. @@ -1516,7 +1524,7 @@ * netif is available, loopback traffic uses this netif. */ #if !defined LWIP_HAVE_LOOPIF || defined __DOXYGEN__ -#define LWIP_HAVE_LOOPIF LWIP_NETIF_LOOPBACK +#define LWIP_HAVE_LOOPIF (LWIP_NETIF_LOOPBACK && !LWIP_SINGLE_NETIF) #endif /** @@ -2199,7 +2207,7 @@ * setting only for single-interface configurations. */ #if !defined LWIP_IPV6_SCOPES || defined __DOXYGEN__ -#define LWIP_IPV6_SCOPES (LWIP_IPV6) +#define LWIP_IPV6_SCOPES (LWIP_IPV6 && !LWIP_SINGLE_NETIF) #endif /**