From ca8b00a3cc790d22ef331632f2869505fc0bcdb9 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Fri, 19 Jan 2018 19:01:23 +0200 Subject: [PATCH] net: if: Make interface IP configuration more flexible Instead of always allocating both IPv6 and IPv4 address information to every network interface, allow more fine grained address configuration. So it is possible to have IPv6 or IPv4 only network interfaces. This commit introduces two new config options: CONFIG_NET_IF_MAX_IPV4_COUNT and CONFIG_NET_IF_MAX_IPV6_COUNT which tell how many IP address information structs are allocated statically. At runtime when network interface is setup, it is then possible to attach this IP address info struct to a specific network interface. This can save considerable amount of memory as the IP address information struct can be quite large (depends on how many IP addresses user configures in the system). Note that the value of CONFIG_NET_IF_MAX_IPV4_COUNT and CONFIG_NET_IF_MAX_IPV6_COUNT should reflect the estimated number of network interfaces in the system. So if if CONFIG_NET_IF_MAX_IPV6_COUNT is set to 1 and there are two network interfaces that need IPv6 addresses, then the system will not be able to setup IPv6 addresses to the second network interface in this case. This scenario might be just fine if the second network interface is IPv4 only. The net_if.c will print a warning during startup if mismatch about the counts and the actual number of network interface is detected. Signed-off-by: Jukka Rissanen --- include/net/net_if.h | 161 +++-- samples/net/dhcpv4_client/src/main.c | 9 +- subsys/logging/sys_log_net.c | 9 +- subsys/net/ip/Kconfig.ipv4 | 8 + subsys/net/ip/Kconfig.ipv6 | 8 + subsys/net/ip/icmpv4.c | 8 +- subsys/net/ip/ipv4.c | 7 +- subsys/net/ip/ipv6.c | 18 +- subsys/net/ip/l2/arp.c | 21 +- .../net/ip/l2/openthread/openthread_utils.c | 36 +- subsys/net/ip/net_if.c | 589 +++++++++++------- subsys/net/ip/net_shell.c | 85 +-- subsys/net/ip/rpl.c | 4 +- subsys/net/lib/app/client.c | 2 +- subsys/net/lib/app/init.c | 17 +- subsys/net/lib/app/net_app.c | 4 +- tests/net/arp/src/main.c | 12 +- tests/net/checksum_offload/prj.conf | 2 + tests/net/iface/prj.conf | 1 + tests/net/ipv6/src/main.c | 7 +- tests/net/tcp/prj.conf | 2 + tests/net/tcp/src/main.c | 8 +- tests/net/udp/src/main.c | 8 +- 23 files changed, 655 insertions(+), 371 deletions(-) diff --git a/include/net/net_if.h b/include/net/net_if.h index f91aeaa6507..1215a4f2734 100644 --- a/include/net/net_if.h +++ b/include/net/net_if.h @@ -275,17 +275,14 @@ struct net_if_dhcpv4 { /** * @brief Network interface IP address configuration. - * - * TODO: Use pointers here so that we could have IPv6 only interface which - * would save memory by not having IPv4 enabled. */ struct net_if_ip { #if defined(CONFIG_NET_IPV6) - struct net_if_ipv6 ipv6; + struct net_if_ipv6 *ipv6; #endif /* CONFIG_NET_IPV6 */ #if defined(CONFIG_NET_IPV4) - struct net_if_ipv4 ipv4; + struct net_if_ipv4 *ipv4; #endif /* CONFIG_NET_IPV4 */ }; @@ -662,6 +659,28 @@ static inline struct net_if *net_if_get_ieee802154(void) #endif /* CONFIG_NET_L2_IEEE802154 */ #if defined(CONFIG_NET_IPV6) +/** + * @brief Allocate network interface IPv6 config. + * + * @details This function will allocate new IPv6 config. + * + * @param iface Interface to use. + * @param ipv6 Pointer to allocated IPv6 struct is returned to caller. + * + * @return 0 if ok, <0 if error + */ +int net_if_config_ipv6_get(struct net_if *iface, + struct net_if_ipv6 **ipv6); + +/** + * @brief Release network interface IPv6 config. + * + * @param iface Interface to use. + * + * @return 0 if ok, <0 if error + */ +int net_if_config_ipv6_put(struct net_if *iface); + /** * @brief Check if this IPv6 address belongs to one of the interfaces. * @@ -685,19 +704,24 @@ static inline struct net_if_addr *net_if_ipv6_addr_lookup_by_iface(struct net_if *iface, struct in6_addr *addr) { + struct net_if_ipv6 *ipv6 = iface->config.ip.ipv6; int i; + if (!ipv6) { + return NULL; + } + for (i = 0; i < NET_IF_MAX_IPV6_ADDR; i++) { - if (!iface->config.ip.ipv6.unicast[i].is_used || - iface->config.ip.ipv6.unicast[i].address.family - != AF_INET6) { + if (!ipv6->unicast[i].is_used || + ipv6->unicast[i].address.family != AF_INET6) { continue; } - if (net_is_ipv6_prefix(addr->s6_addr, - iface->config.ip.ipv6.unicast[i].address.in6_addr.s6_addr, - 128)) { - return &iface->config.ip.ipv6.unicast[i]; + if (net_is_ipv6_prefix( + addr->s6_addr, + ipv6->unicast[i].address.in6_addr.s6_addr, + 128)) { + return &ipv6->unicast[i]; } } @@ -1019,11 +1043,11 @@ bool net_if_ipv6_router_rm(struct net_if_router *router); */ static inline u8_t net_if_ipv6_get_hop_limit(struct net_if *iface) { - struct net_if_config *config; + if (!iface->config.ip.ipv6) { + return 0; + } - config = net_if_config_get(iface); - - return config->ip.ipv6.hop_limit; + return iface->config.ip.ipv6->hop_limit; } /** @@ -1035,11 +1059,11 @@ static inline u8_t net_if_ipv6_get_hop_limit(struct net_if *iface) static inline void net_ipv6_set_hop_limit(struct net_if *iface, u8_t hop_limit) { - struct net_if_config *config; + if (!iface->config.ip.ipv6) { + return; + } - config = net_if_config_get(iface); - - config->ip.ipv6.hop_limit = hop_limit; + iface->config.ip.ipv6->hop_limit = hop_limit; } /** @@ -1051,11 +1075,11 @@ static inline void net_ipv6_set_hop_limit(struct net_if *iface, static inline void net_if_ipv6_set_base_reachable_time(struct net_if *iface, u32_t reachable_time) { - struct net_if_config *config; + if (!iface->config.ip.ipv6) { + return; + } - config = net_if_config_get(iface); - - config->ip.ipv6.base_reachable_time = reachable_time; + iface->config.ip.ipv6->base_reachable_time = reachable_time; } /** @@ -1067,36 +1091,31 @@ static inline void net_if_ipv6_set_base_reachable_time(struct net_if *iface, */ static inline u32_t net_if_ipv6_get_reachable_time(struct net_if *iface) { - struct net_if_config *config; + if (!iface->config.ip.ipv6) { + return 0; + } - config = net_if_config_get(iface); - - return config->ip.ipv6.reachable_time; + return iface->config.ip.ipv6->reachable_time; } /** * @brief Calculate next reachable time value for IPv6 reachable time * - * @param iface Network interface + * @param ipv6 IPv6 address configuration * * @return Reachable time */ -u32_t net_if_ipv6_calc_reachable_time(struct net_if *iface); +u32_t net_if_ipv6_calc_reachable_time(struct net_if_ipv6 *ipv6); /** * @brief Set IPv6 reachable time for a given interface. This requires * that base reachable time is set for the interface. * - * @param iface Network interface + * @param ipv6 IPv6 address configuration */ -static inline void net_if_ipv6_set_reachable_time(struct net_if *iface) +static inline void net_if_ipv6_set_reachable_time(struct net_if_ipv6 *ipv6) { - struct net_if_config *config; - - config = net_if_config_get(iface); - - config->ip.ipv6.reachable_time = - net_if_ipv6_calc_reachable_time(iface); + ipv6->reachable_time = net_if_ipv6_calc_reachable_time(ipv6); } /** @@ -1108,11 +1127,11 @@ static inline void net_if_ipv6_set_reachable_time(struct net_if *iface) static inline void net_if_ipv6_set_retrans_timer(struct net_if *iface, u32_t retrans_timer) { - struct net_if_config *config; + if (!iface->config.ip.ipv6) { + return; + } - config = net_if_config_get(iface); - - config->ip.ipv6.retrans_timer = retrans_timer; + iface->config.ip.ipv6->retrans_timer = retrans_timer; } /** @@ -1124,11 +1143,11 @@ static inline void net_if_ipv6_set_retrans_timer(struct net_if *iface, */ static inline u32_t net_if_ipv6_get_retrans_timer(struct net_if *iface) { - struct net_if_config *config; + if (!iface->config.ip.ipv6) { + return 0; + } - config = net_if_config_get(iface); - - return config->ip.ipv6.retrans_timer; + return iface->config.ip.ipv6->retrans_timer; } /** @@ -1194,6 +1213,28 @@ struct in6_addr *net_if_ipv6_get_global_addr(struct net_if **iface); #endif /* CONFIG_NET_IPV6 */ #if defined(CONFIG_NET_IPV4) +/** + * @brief Allocate network interface IPv4 config. + * + * @details This function will allocate new IPv4 config. + * + * @param iface Interface to use. + * @param ipv4 Pointer to allocated IPv4 struct is returned to caller. + * + * @return 0 if ok, <0 if error + */ +int net_if_config_ipv4_get(struct net_if *iface, + struct net_if_ipv4 **ipv4); + +/** + * @brief Release network interface IPv4 config. + * + * @param iface Interface to use. + * + * @return 0 if ok, <0 if error + */ +int net_if_config_ipv4_put(struct net_if *iface); + /** * @brief Get IPv4 time-to-live value specified for a given interface * @@ -1203,11 +1244,11 @@ struct in6_addr *net_if_ipv6_get_global_addr(struct net_if **iface); */ static inline u8_t net_if_ipv4_get_ttl(struct net_if *iface) { - struct net_if_config *config; + if (!iface->config.ip.ipv4) { + return 0; + } - config = net_if_config_get(iface); - - return config->ip.ipv4.ttl; + return iface->config.ip.ipv4->ttl; } /** @@ -1327,11 +1368,15 @@ bool net_if_ipv4_addr_mask_cmp(struct net_if *iface, static inline void net_if_ipv4_set_netmask(struct net_if *iface, struct in_addr *netmask) { - struct net_if_config *config; + if (net_if_config_ipv4_get(iface, NULL) < 0) { + return; + } - config = net_if_config_get(iface); + if (!iface->config.ip.ipv4) { + return; + } - net_ipaddr_copy(&config->ip.ipv4.netmask, netmask); + net_ipaddr_copy(&iface->config.ip.ipv4->netmask, netmask); } /** @@ -1343,11 +1388,15 @@ static inline void net_if_ipv4_set_netmask(struct net_if *iface, static inline void net_if_ipv4_set_gw(struct net_if *iface, struct in_addr *gw) { - struct net_if_config *config; + if (net_if_config_ipv4_get(iface, NULL) < 0) { + return; + } - config = net_if_config_get(iface); + if (!iface->config.ip.ipv4) { + return; + } - net_ipaddr_copy(&config->ip.ipv4.gw, gw); + net_ipaddr_copy(&iface->config.ip.ipv4->gw, gw); } #endif /* CONFIG_NET_IPV4 */ diff --git a/samples/net/dhcpv4_client/src/main.c b/samples/net/dhcpv4_client/src/main.c index 220c22d920e..234b91f84c5 100644 --- a/samples/net/dhcpv4_client/src/main.c +++ b/samples/net/dhcpv4_client/src/main.c @@ -38,22 +38,23 @@ static void handler(struct net_mgmt_event_callback *cb, for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { char buf[NET_IPV4_ADDR_LEN]; - if (iface->config.ip.ipv4.unicast[i].addr_type != + if (iface->config.ip.ipv4->unicast[i].addr_type != NET_ADDR_DHCP) { continue; } NET_INFO("Your address: %s", net_addr_ntop(AF_INET, - &iface->config.ip.ipv4.unicast[i].address.in_addr, + &iface->config.ip.ipv4->unicast[i].address.in_addr, buf, sizeof(buf))); NET_INFO("Lease time: %u seconds", iface->config.dhcpv4.lease_time); NET_INFO("Subnet: %s", - net_addr_ntop(AF_INET, &iface->config.ip.ipv4.netmask, + net_addr_ntop(AF_INET, + &iface->config.ip.ipv4->netmask, buf, sizeof(buf))); NET_INFO("Router: %s", - net_addr_ntop(AF_INET, &iface->config.ip.ipv4.gw, + net_addr_ntop(AF_INET, &iface->config.ip.ipv4->gw, buf, sizeof(buf))); } } diff --git a/subsys/logging/sys_log_net.c b/subsys/logging/sys_log_net.c index 7135015b2fa..adc54724801 100644 --- a/subsys/logging/sys_log_net.c +++ b/subsys/logging/sys_log_net.c @@ -190,9 +190,14 @@ void syslog_net_hook_install(void) #endif } else if (server_addr.sa_family == AF_INET) { #if defined(CONFIG_NET_IPV4) - /* FIXME: take the first IPv4 address of an interface */ + /* FIXME: instead of taking the first IPv4 address of an + * interface, take the proper one according to routing + */ + struct net_if_ipv4 *ipv4 = + net_if_get_default()->config.ip.ipv4; + net_ipaddr_copy(&local_addr4.sin_addr, - &net_if_get_default()->ipv4.unicast[0].address.in_addr); + &ipv4->unicast[0].address.in_addr); net_addr_ntop(AF_INET, &local_addr4.sin_addr, hostname, MAX_HOSTNAME_LEN); diff --git a/subsys/net/ip/Kconfig.ipv4 b/subsys/net/ip/Kconfig.ipv4 index e89716bfac9..ee1c9ada563 100644 --- a/subsys/net/ip/Kconfig.ipv4 +++ b/subsys/net/ip/Kconfig.ipv4 @@ -21,6 +21,14 @@ config NET_INITIAL_TTL help The value should be > 0 +config NET_IF_MAX_IPV4_COUNT + int "Max number of IPv4 network interfaces in the system" + default 1 + default NET_VLAN_COUNT if NET_VLAN + help + This tells how many network interfaces there will be in the system + that will have IPv4 enabled. + config NET_IF_UNICAST_IPV4_ADDR_COUNT int "Max number of unicast IPv4 addresses per network interface" default 1 diff --git a/subsys/net/ip/Kconfig.ipv6 b/subsys/net/ip/Kconfig.ipv6 index d4a951abe1e..c6f9430c0b7 100644 --- a/subsys/net/ip/Kconfig.ipv6 +++ b/subsys/net/ip/Kconfig.ipv6 @@ -15,6 +15,14 @@ menuconfig NET_IPV6 if NET_IPV6 +config NET_IF_MAX_IPV6_COUNT + int "Max number of IPv6 network interfaces in the system" + default 1 + default NET_VLAN_COUNT if NET_VLAN + help + This tells how many network interfaces there will be in the system + that will have IPv6 enabled. + config NET_IF_UNICAST_IPV6_ADDR_COUNT int "Max number of unicast IPv6 addresses per network interface" default 2 diff --git a/subsys/net/ip/icmpv4.c b/subsys/net/ip/icmpv4.c index 0be6bc50dd1..02c2a0935da 100644 --- a/subsys/net/ip/icmpv4.c +++ b/subsys/net/ip/icmpv4.c @@ -189,15 +189,17 @@ int net_icmpv4_send_echo_request(struct net_if *iface, u16_t identifier, u16_t sequence) { - struct net_if_config *config; + struct net_if_ipv4 *ipv4 = iface->config.ip.ipv4; const struct in_addr *src; struct net_pkt *pkt; struct net_buf *frag; - config = net_if_config_get(iface); + if (!ipv4) { + return -EINVAL; + } /* Take the first address of the network interface */ - src = &config->ip.ipv4.unicast[0].address.in_addr; + src = &ipv4->unicast[0].address.in_addr; /* We cast to IPv6 address but that should be ok in this case * as IPv4 cannot be used in 802.15.4 where it is the reserve diff --git a/subsys/net/ip/ipv4.c b/subsys/net/ip/ipv4.c index a427eaed1c3..ea262ab229e 100644 --- a/subsys/net/ip/ipv4.c +++ b/subsys/net/ip/ipv4.c @@ -69,10 +69,9 @@ struct net_pkt *net_ipv4_create(struct net_context *context, const struct in_addr *src, const struct in_addr *dst) { - struct net_if_config *config; - - config = net_if_config_get(net_pkt_iface(pkt)); + struct net_if_ipv4 *ipv4 = net_pkt_iface(pkt)->config.ip.ipv4; + NET_ASSERT(ipv4); NET_ASSERT(((struct sockaddr_in_ptr *)&context->local)->sin_addr); if (!src) { @@ -81,7 +80,7 @@ struct net_pkt *net_ipv4_create(struct net_context *context, if (net_is_ipv4_addr_unspecified(src) || net_is_ipv4_addr_mcast(src)) { - src = &config->ip.ipv4.unicast[0].address.in_addr; + src = &ipv4->unicast[0].address.in_addr; } return net_ipv4_create_raw(pkt, diff --git a/subsys/net/ip/ipv6.c b/subsys/net/ip/ipv6.c index 0e4068071aa..f0a74605d93 100644 --- a/subsys/net/ip/ipv6.c +++ b/subsys/net/ip/ipv6.c @@ -2567,7 +2567,6 @@ static enum net_verdict handle_ra_input(struct net_pkt *pkt) struct net_nbr *nbr = NULL; struct net_icmpv6_ra_hdr hdr, *ra_hdr; struct net_if_router *router; - struct net_if_config *config; struct net_buf *frag; u16_t router_lifetime; u32_t reachable_time; @@ -2633,7 +2632,8 @@ static enum net_verdict handle_ra_input(struct net_pkt *pkt) net_if_ipv6_set_base_reachable_time(net_pkt_iface(pkt), reachable_time); - net_if_ipv6_set_reachable_time(net_pkt_iface(pkt)); + net_if_ipv6_set_reachable_time( + net_pkt_iface(pkt)->config.ip.ipv6); } if (retrans_timer) { @@ -2761,10 +2761,8 @@ static enum net_verdict handle_ra_input(struct net_pkt *pkt) nbr_clear_ns_pending(net_ipv6_nbr_data(nbr)); } - config = net_if_config_get(net_pkt_iface(pkt)); - /* Cancel the RS timer on iface */ - k_delayed_work_cancel(&config->ip.ipv6.rs_timer); + k_delayed_work_cancel(&net_pkt_iface(pkt)->config.ip.ipv6->rs_timer); net_pkt_unref(pkt); @@ -2954,11 +2952,11 @@ int net_ipv6_mld_leave(struct net_if *iface, const struct in6_addr *addr) static void send_mld_report(struct net_if *iface) { - struct net_if_config *config; + struct net_if_ipv6 *ipv6 = iface->config.ip.ipv6; struct net_pkt *pkt; int i, count = 0; - config = net_if_config_get(iface); + NET_ASSERT(ipv6); pkt = net_pkt_get_reserve_tx(net_if_get_ll_reserve(iface, NULL), K_FOREVER); @@ -2966,13 +2964,11 @@ static void send_mld_report(struct net_if *iface) net_pkt_append_u8(pkt, 0); /* This will be the record count */ for (i = 0; i < NET_IF_MAX_IPV6_MADDR; i++) { - if (!config->ip.ipv6.mcast[i].is_used || - !config->ip.ipv6.mcast[i].is_joined) { + if (!ipv6->mcast[i].is_used || !ipv6->mcast[i].is_joined) { continue; } - pkt = create_mldv2(pkt, - &config->ip.ipv6.mcast[i].address.in6_addr, + pkt = create_mldv2(pkt, &ipv6->mcast[i].address.in6_addr, NET_IPV6_MLDv2_MODE_IS_EXCLUDE, 0); count++; } diff --git a/subsys/net/ip/l2/arp.c b/subsys/net/ip/l2/arp.c index a3638418640..97009ff274a 100644 --- a/subsys/net/ip/l2/arp.c +++ b/subsys/net/ip/l2/arp.c @@ -78,17 +78,18 @@ static inline struct arp_entry *find_entry(struct net_if *iface, static inline struct in_addr *if_get_addr(struct net_if *iface) { - struct net_if_config *config; + struct net_if_ipv4 *ipv4 = iface->config.ip.ipv4; int i; - config = net_if_config_get(iface); + if (!ipv4) { + return NULL; + } for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { - if (config->ip.ipv4.unicast[i].is_used && - config->ip.ipv4.unicast[i].address.family == AF_INET && - config->ip.ipv4.unicast[i].addr_state == - NET_ADDR_PREFERRED) { - return &config->ip.ipv4.unicast[i].address.in_addr; + if (ipv4->unicast[i].is_used && + ipv4->unicast[i].address.family == AF_INET && + ipv4->unicast[i].addr_state == NET_ADDR_PREFERRED) { + return &ipv4->unicast[i].address.in_addr; } } @@ -230,11 +231,11 @@ struct net_pkt *net_arp_prepare(struct net_pkt *pkt) */ if (!net_if_ipv4_addr_mask_cmp(net_pkt_iface(pkt), &NET_IPV4_HDR(pkt)->dst)) { - struct net_if_config *config; + struct net_if_ipv4 *ipv4 = net_pkt_iface(pkt)->config.ip.ipv4; - config = net_if_config_get(net_pkt_iface(pkt)); + NET_ASSERT(ipv4); - addr = &config->ip.ipv4.gw; + addr = &ipv4->gw; if (net_is_ipv4_addr_unspecified(addr)) { NET_ERR("Gateway not set for iface %p", net_pkt_iface(pkt)); diff --git a/subsys/net/ip/l2/openthread/openthread_utils.c b/subsys/net/ip/l2/openthread/openthread_utils.c index 771f4066e48..966287fd782 100644 --- a/subsys/net/ip/l2/openthread/openthread_utils.c +++ b/subsys/net/ip/l2/openthread/openthread_utils.c @@ -92,15 +92,21 @@ void add_ipv6_addr_to_ot(struct openthread_context *context) { struct net_if *iface = context->iface; struct otNetifAddress addr; + struct net_if_ipv6 *ipv6; int i; memset(&addr, 0, sizeof(addr)); + if (net_if_config_ipv6_get(iface, &ipv6) < 0) { + NET_DBG("Cannot allocate IPv6 address"); + return; + } + /* save the last added IP address for this interface */ for (i = NET_IF_MAX_IPV6_ADDR - 1; i >= 0; i--) { - if (iface->ipv6.unicast[i].is_used) { + if (ipv6->unicast[i].is_used) { memcpy(&addr.mAddress, - &iface->ipv6.unicast[i].address.in6_addr, + &ipv6->unicast[i].address.in6_addr, sizeof(addr.mAddress)); break; } @@ -126,13 +132,19 @@ void add_ipv6_addr_to_ot(struct openthread_context *context) void add_ipv6_maddr_to_ot(struct openthread_context *context) { struct otIp6Address addr; + struct net_if_ipv6 *ipv6; int i; + if (net_if_config_ipv6_get(context->iface, &ipv6) < 0) { + NET_DBG("Cannot allocate IPv6 address"); + return; + } + /* save the last added IP address for this interface */ for (i = NET_IF_MAX_IPV6_MADDR - 1; i >= 0; i--) { - if (context->iface->ipv6.mcast[i].is_used) { + if (ipv6->mcast[i].is_used) { memcpy(&addr, - &context->iface->ipv6.mcast[i].address.in6_addr, + &ipv6->mcast[i].address.in6_addr, sizeof(addr)); break; } @@ -174,13 +186,19 @@ void rm_ipv6_addr_from_zephyr(struct openthread_context *context) { struct in6_addr *ot_addr; struct net_if_addr *zephyr_addr; + struct net_if_ipv6 *ipv6; int i; + if (net_if_config_ipv6_get(context->iface, &ipv6) < 0) { + NET_DBG("Cannot find IPv6 address"); + return; + } + for (i = 0; i < NET_IF_MAX_IPV6_ADDR; i++) { const otNetifAddress *address; bool used = false; - zephyr_addr = &context->iface->ipv6.unicast[i]; + zephyr_addr = &ipv6->unicast[i]; if (!zephyr_addr->is_used) { continue; } @@ -215,13 +233,19 @@ void rm_ipv6_maddr_from_zephyr(struct openthread_context *context) { struct in6_addr *ot_addr; struct net_if_mcast_addr *zephyr_addr; + struct net_if_ipv6 *ipv6; int i; + if (net_if_config_ipv6_get(context->iface, &ipv6) < 0) { + NET_DBG("Cannot find IPv6 address"); + return; + } + for (i = 0; i < NET_IF_MAX_IPV6_MADDR; i++) { const otNetifMulticastAddress *maddress; bool used = false; - zephyr_addr = &context->iface->ipv6.mcast[i]; + zephyr_addr = &ipv6->mcast[i]; if (!zephyr_addr->is_used) { continue; } diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index 29af33ef682..e8e49ede01d 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -45,6 +45,20 @@ extern struct k_poll_event __net_if_event_stop[]; static struct net_if_router routers[CONFIG_NET_MAX_ROUTERS]; +#if defined(CONFIG_NET_IPV6) +static struct { + struct net_if_ipv6 ipv6; + struct net_if *iface; +} ipv6_addresses[CONFIG_NET_IF_MAX_IPV6_COUNT]; +#endif /* CONFIG_NET_IPV6 */ + +#if defined(CONFIG_NET_IPV4) +static struct { + struct net_if_ipv4 ipv4; + struct net_if *iface; +} ipv4_addresses[CONFIG_NET_IF_MAX_IPV4_COUNT]; +#endif /* CONFIG_NET_IPV4 */ + /* We keep track of the link callbacks in this list. */ static sys_slist_t link_callbacks; @@ -417,6 +431,57 @@ struct net_if *net_if_get_first_by_type(const struct net_l2 *l2) } #if defined(CONFIG_NET_IPV6) +int net_if_config_ipv6_get(struct net_if *iface, struct net_if_ipv6 **ipv6) +{ + int i; + + if (iface->config.ip.ipv6) { + if (ipv6) { + *ipv6 = iface->config.ip.ipv6; + } + + return 0; + } + + for (i = 0; i < ARRAY_SIZE(ipv6_addresses); i++) { + if (ipv6_addresses[i].iface) { + continue; + } + + iface->config.ip.ipv6 = &ipv6_addresses[i].ipv6; + ipv6_addresses[i].iface = iface; + + if (ipv6) { + *ipv6 = &ipv6_addresses[i].ipv6; + } + + return 0; + } + + return -ESRCH; +} + +int net_if_config_ipv6_put(struct net_if *iface) +{ + int i; + + if (!iface->config.ip.ipv6) { + return -EALREADY; + } + + for (i = 0; i < ARRAY_SIZE(ipv6_addresses); i++) { + if (ipv6_addresses[i].iface != iface) { + continue; + } + + iface->config.ip.ipv6 = NULL; + ipv6_addresses[i].iface = NULL; + + return 0; + } + + return -ESRCH; +} #if defined(CONFIG_NET_IPV6_MLD) static void join_mcast_allnodes(struct net_if *iface) @@ -451,19 +516,20 @@ static void join_mcast_solicit_node(struct net_if *iface, static void leave_mcast_all(struct net_if *iface) { - struct net_if_config *config; + struct net_if_ipv6 *ipv6 = iface->config.ip.ipv6; int i; - config = net_if_config_get(iface); + if (!ipv6) { + return; + } for (i = 0; i < NET_IF_MAX_IPV6_MADDR; i++) { - if (!config->ip.ipv6.mcast[i].is_used || - !config->ip.ipv6.mcast[i].is_joined) { + if (!ipv6->mcast[i].is_used || + !ipv6->mcast[i].is_joined) { continue; } - net_ipv6_mld_leave(iface, - &config->ip.ipv6.mcast[i].address.in6_addr); + net_ipv6_mld_leave(iface, &ipv6->mcast[i].address.in6_addr); } } #else @@ -528,12 +594,19 @@ static void net_if_ipv6_start_dad(struct net_if *iface, void net_if_start_dad(struct net_if *iface) { - struct net_if_config *config; struct net_if_addr *ifaddr; + struct net_if_ipv6 *ipv6; struct in6_addr addr = { }; int i; - config = net_if_config_get(iface); + if (net_if_config_ipv6_get(iface, &ipv6) < 0) { + NET_WARN("Cannot do DAD IPv6 config is not valid."); + return; + } + + if (!ipv6) { + return; + } net_ipv6_addr_create_iid(&addr, net_if_get_link_addr(iface)); @@ -547,13 +620,13 @@ void net_if_start_dad(struct net_if *iface) * the interface was down. */ for (i = 0; i < NET_IF_MAX_IPV6_ADDR; i++) { - if (!config->ip.ipv6.unicast[i].is_used || - config->ip.ipv6.unicast[i].address.family != AF_INET6 || - &config->ip.ipv6.unicast[i] == ifaddr) { + if (!ipv6->unicast[i].is_used || + ipv6->unicast[i].address.family != AF_INET6 || + &ipv6->unicast[i] == ifaddr) { continue; } - net_if_ipv6_start_dad(iface, &config->ip.ipv6.unicast[i]); + net_if_ipv6_start_dad(iface, &ipv6->unicast[i]); } } @@ -589,41 +662,43 @@ static inline void net_if_ipv6_start_dad(struct net_if *iface, static void rs_timeout(struct k_work *work) { /* Did not receive RA yet. */ - struct net_if_config *config = CONTAINER_OF(work, - struct net_if_config, - ip.ipv6.rs_timer); + struct net_if_ipv6 *ipv6 = CONTAINER_OF(work, + struct net_if_ipv6, + rs_timer); struct net_if *iface; - config->ip.ipv6.rs_count++; + ipv6->rs_count++; for (iface = __net_if_start; iface != __net_if_end; iface++) { - if (&iface->config == config) { + if (iface->config.ip.ipv6 == ipv6) { goto found; } } - NET_DBG("Interface config %p not found", config); + NET_DBG("Interface IPv6 config %p not found", ipv6); return; found: NET_DBG("RS no respond iface %p count %d", iface, - config->ip.ipv6.rs_count); + ipv6->rs_count); - if (config->ip.ipv6.rs_count < RS_COUNT) { + if (ipv6->rs_count < RS_COUNT) { net_if_start_rs(iface); } } void net_if_start_rs(struct net_if *iface) { - struct net_if_config *config; + struct net_if_ipv6 *ipv6 = iface->config.ip.ipv6; - config = net_if_config_get(iface); + if (!ipv6) { + return; + } NET_DBG("Interface %p", iface); if (!net_ipv6_start_rs(iface)) { - k_delayed_work_submit(&config->ip.ipv6.rs_timer, RS_TIMEOUT); + k_delayed_work_submit(&ipv6->rs_timer, RS_TIMEOUT); } } #endif /* CONFIG_NET_IPV6_ND */ @@ -634,27 +709,29 @@ struct net_if_addr *net_if_ipv6_addr_lookup(const struct in6_addr *addr, struct net_if *iface; for (iface = __net_if_start; iface != __net_if_end; iface++) { - struct net_if_config *config; + struct net_if_ipv6 *ipv6 = iface->config.ip.ipv6; int i; - config = &iface->config; + if (!ipv6) { + continue; + } for (i = 0; i < NET_IF_MAX_IPV6_ADDR; i++) { - if (!config->ip.ipv6.unicast[i].is_used || - config->ip.ipv6.unicast[i].address.family - != AF_INET6) { + if (!ipv6->unicast[i].is_used || + ipv6->unicast[i].address.family != AF_INET6) { continue; } - if (net_is_ipv6_prefix(addr->s6_addr, - config->ip.ipv6.unicast[i].address.in6_addr.s6_addr, - 128)) { + if (net_is_ipv6_prefix( + addr->s6_addr, + ipv6->unicast[i].address.in6_addr.s6_addr, + 128)) { if (ret) { *ret = iface; } - return &config->ip.ipv6.unicast[i]; + return &ipv6->unicast[i]; } } } @@ -688,17 +765,18 @@ void net_if_ipv6_addr_update_lifetime(struct net_if_addr *ifaddr, static struct net_if_addr *ipv6_addr_find(struct net_if *iface, struct in6_addr *addr) { + struct net_if_ipv6 *ipv6 = iface->config.ip.ipv6; int i; for (i = 0; i < NET_IF_MAX_IPV6_ADDR; i++) { - if (!iface->config.ip.ipv6.unicast[i].is_used) { + if (!ipv6->unicast[i].is_used) { continue; } - if (net_ipv6_addr_cmp(addr, - &iface->config.ip.ipv6.unicast[i].address.in6_addr)) { + if (net_ipv6_addr_cmp( + addr, &ipv6->unicast[i].address.in6_addr)) { - return &iface->config.ip.ipv6.unicast[i]; + return &ipv6->unicast[i]; } } @@ -737,24 +815,23 @@ static inline void net_if_addr_init(struct net_if_addr *ifaddr, static inline struct in6_addr *check_global_addr(struct net_if *iface) { - struct net_if_config *config; + struct net_if_ipv6 *ipv6 = iface->config.ip.ipv6; int i; - config = &iface->config; + if (!ipv6) { + return NULL; + } for (i = 0; i < NET_IF_MAX_IPV6_ADDR; i++) { - if (!config->ip.ipv6.unicast[i].is_used || - (config->ip.ipv6.unicast[i].addr_state != - NET_ADDR_TENTATIVE && - config->ip.ipv6.unicast[i].addr_state != - NET_ADDR_PREFERRED) || - config->ip.ipv6.unicast[i].address.family != AF_INET6) { + if (!ipv6->unicast[i].is_used || + (ipv6->unicast[i].addr_state != NET_ADDR_TENTATIVE && + ipv6->unicast[i].addr_state != NET_ADDR_PREFERRED) || + ipv6->unicast[i].address.family != AF_INET6) { continue; } - if (!net_is_ipv6_ll_addr( - &config->ip.ipv6.unicast[i].address.in6_addr)) { - return &config->ip.ipv6.unicast[i].address.in6_addr; + if (!net_is_ipv6_ll_addr(&ipv6->unicast[i].address.in6_addr)) { + return &ipv6->unicast[i].address.in6_addr; } } @@ -766,26 +843,28 @@ struct net_if_addr *net_if_ipv6_addr_add(struct net_if *iface, enum net_addr_type addr_type, u32_t vlifetime) { - struct net_if_config *config; struct net_if_addr *ifaddr; + struct net_if_ipv6 *ipv6; int i; + if (net_if_config_ipv6_get(iface, &ipv6) < 0) { + return NULL; + } + ifaddr = ipv6_addr_find(iface, addr); if (ifaddr) { return ifaddr; } - config = net_if_config_get(iface); - for (i = 0; i < NET_IF_MAX_IPV6_ADDR; i++) { #if defined(CONFIG_NET_RPL) struct in6_addr *global; #endif - if (config->ip.ipv6.unicast[i].is_used) { + if (ipv6->unicast[i].is_used) { continue; } - net_if_addr_init(&config->ip.ipv6.unicast[i], addr, addr_type, + net_if_addr_init(&ipv6->unicast[i], addr, addr_type, vlifetime); NET_DBG("[%d] interface %p address %s type %s added", i, @@ -802,22 +881,21 @@ struct net_if_addr *net_if_ipv6_addr_add(struct net_if *iface, */ join_mcast_allnodes(iface); join_mcast_solicit_node(iface, - &config->ip.ipv6.unicast[i].address.in6_addr); + &ipv6->unicast[i].address.in6_addr); #if defined(CONFIG_NET_RPL) /* Do not send DAD for global addresses */ global = check_global_addr(iface); if (!net_ipv6_addr_cmp(global, addr)) { - net_if_ipv6_start_dad(iface, - &config->ip.ipv6.unicast[i]); + net_if_ipv6_start_dad(iface, &ipv6->unicast[i]); } #else - net_if_ipv6_start_dad(iface, &config->ip.ipv6.unicast[i]); + net_if_ipv6_start_dad(iface, &ipv6->unicast[i]); #endif net_mgmt_event_notify(NET_EVENT_IPV6_ADDR_ADD, iface); - return &config->ip.ipv6.unicast[i]; + return &ipv6->unicast[i]; } return NULL; @@ -825,32 +903,32 @@ struct net_if_addr *net_if_ipv6_addr_add(struct net_if *iface, bool net_if_ipv6_addr_rm(struct net_if *iface, const struct in6_addr *addr) { - struct net_if_config *config; + struct net_if_ipv6 *ipv6 = iface->config.ip.ipv6; int i; NET_ASSERT(addr); - config = &iface->config; + if (!ipv6) { + return false; + } for (i = 0; i < NET_IF_MAX_IPV6_ADDR; i++) { struct in6_addr maddr; - if (!config->ip.ipv6.unicast[i].is_used) { + if (!ipv6->unicast[i].is_used) { continue; } - if (!net_ipv6_addr_cmp( - &config->ip.ipv6.unicast[i].address.in6_addr, - addr)) { + if (!net_ipv6_addr_cmp(&ipv6->unicast[i].address.in6_addr, + addr)) { continue; } - if (!config->ip.ipv6.unicast[i].is_infinite) { - k_delayed_work_cancel( - &config->ip.ipv6.unicast[i].lifetime); + if (!ipv6->unicast[i].is_infinite) { + k_delayed_work_cancel(&ipv6->unicast[i].lifetime); } - config->ip.ipv6.unicast[i].is_used = false; + ipv6->unicast[i].is_used = false; net_ipv6_addr_create_solicited_node(addr, &maddr); @@ -858,8 +936,7 @@ bool net_if_ipv6_addr_rm(struct net_if *iface, const struct in6_addr *addr) NET_DBG("[%d] interface %p address %s type %s removed", i, iface, net_sprint_ipv6_addr(addr), - net_addr_type2str( - config->ip.ipv6.unicast[i].addr_type)); + net_addr_type2str(ipv6->unicast[i].addr_type)); net_mgmt_event_notify(NET_EVENT_IPV6_ADDR_DEL, iface); @@ -872,32 +949,34 @@ bool net_if_ipv6_addr_rm(struct net_if *iface, const struct in6_addr *addr) struct net_if_mcast_addr *net_if_ipv6_maddr_add(struct net_if *iface, const struct in6_addr *addr) { - struct net_if_config *config; + struct net_if_ipv6 *ipv6; int i; + if (net_if_config_ipv6_get(iface, &ipv6) < 0) { + return NULL; + } + if (!net_is_ipv6_addr_mcast(addr)) { NET_DBG("Address %s is not a multicast address.", net_sprint_ipv6_addr(addr)); return NULL; } - config = net_if_config_get(iface); - for (i = 0; i < NET_IF_MAX_IPV6_MADDR; i++) { - if (config->ip.ipv6.mcast[i].is_used) { + if (ipv6->mcast[i].is_used) { continue; } - config->ip.ipv6.mcast[i].is_used = true; - config->ip.ipv6.mcast[i].address.family = AF_INET6; - memcpy(&config->ip.ipv6.mcast[i].address.in6_addr, addr, 16); + ipv6->mcast[i].is_used = true; + ipv6->mcast[i].address.family = AF_INET6; + memcpy(&ipv6->mcast[i].address.in6_addr, addr, 16); NET_DBG("[%d] interface %p address %s added", i, iface, net_sprint_ipv6_addr(addr)); net_mgmt_event_notify(NET_EVENT_IPV6_MADDR_ADD, iface); - return &config->ip.ipv6.mcast[i]; + return &ipv6->mcast[i]; } return NULL; @@ -905,23 +984,24 @@ struct net_if_mcast_addr *net_if_ipv6_maddr_add(struct net_if *iface, bool net_if_ipv6_maddr_rm(struct net_if *iface, const struct in6_addr *addr) { - struct net_if_config *config; + struct net_if_ipv6 *ipv6 = iface->config.ip.ipv6; int i; - config = net_if_config_get(iface); + if (!ipv6) { + return false; + } for (i = 0; i < NET_IF_MAX_IPV6_MADDR; i++) { - if (!config->ip.ipv6.mcast[i].is_used) { + if (!ipv6->mcast[i].is_used) { continue; } - if (!net_ipv6_addr_cmp( - &config->ip.ipv6.mcast[i].address.in6_addr, - addr)) { + if (!net_ipv6_addr_cmp(&ipv6->mcast[i].address.in6_addr, + addr)) { continue; } - config->ip.ipv6.mcast[i].is_used = false; + ipv6->mcast[i].is_used = false; NET_DBG("[%d] interface %p address %s removed", i, iface, net_sprint_ipv6_addr(addr)); @@ -940,30 +1020,32 @@ struct net_if_mcast_addr *net_if_ipv6_maddr_lookup(const struct in6_addr *maddr, struct net_if *iface; for (iface = __net_if_start; iface != __net_if_end; iface++) { - struct net_if_config *config; + struct net_if_ipv6 *ipv6 = iface->config.ip.ipv6; int i; if (ret && *ret && iface != *ret) { continue; } - config = &iface->config; + if (!ipv6) { + continue; + } for (i = 0; i < NET_IF_MAX_IPV6_MADDR; i++) { - if (!config->ip.ipv6.mcast[i].is_used || - config->ip.ipv6.mcast[i].address.family != - AF_INET6) { + if (!ipv6->mcast[i].is_used || + ipv6->mcast[i].address.family != AF_INET6) { continue; } - if (net_is_ipv6_prefix(maddr->s6_addr, - config->ip.ipv6.mcast[i].address.in6_addr.s6_addr, - 128)) { + if (net_is_ipv6_prefix( + maddr->s6_addr, + ipv6->mcast[i].address.in6_addr.s6_addr, + 128)) { if (ret) { *ret = iface; } - return &config->ip.ipv6.mcast[i]; + return &ipv6->mcast[i]; } } } @@ -1005,20 +1087,21 @@ static struct net_if_ipv6_prefix *ipv6_prefix_find(struct net_if *iface, struct in6_addr *prefix, u8_t prefix_len) { - struct net_if_config *config; + struct net_if_ipv6 *ipv6 = iface->config.ip.ipv6; int i; - config = &iface->config; + if (!ipv6) { + return NULL; + } for (i = 0; i < NET_IF_MAX_IPV6_PREFIX; i++) { - if (!config->ip.ipv6.unicast[i].is_used) { + if (!ipv6->unicast[i].is_used) { continue; } - if (net_ipv6_addr_cmp(prefix, - &config->ip.ipv6.prefix[i].prefix) && - prefix_len == config->ip.ipv6.prefix[i].len) { - return &config->ip.ipv6.prefix[i]; + if (net_ipv6_addr_cmp(prefix, &ipv6->prefix[i].prefix) && + prefix_len == ipv6->prefix[i].len) { + return &ipv6->prefix[i]; } } @@ -1058,22 +1141,28 @@ struct net_if_ipv6_prefix *net_if_ipv6_prefix_add(struct net_if *iface, u32_t lifetime) { struct net_if_ipv6_prefix *if_prefix; - struct net_if_config *config; + struct net_if_ipv6 *ipv6; int i; + if (net_if_config_ipv6_get(iface, &ipv6) < 0) { + return NULL; + } + if_prefix = ipv6_prefix_find(iface, prefix, len); if (if_prefix) { return if_prefix; } - config = net_if_config_get(iface); + if (!ipv6) { + return NULL; + } for (i = 0; i < NET_IF_MAX_IPV6_PREFIX; i++) { - if (config->ip.ipv6.prefix[i].is_used) { + if (ipv6->prefix[i].is_used) { continue; } - net_if_ipv6_prefix_init(&config->ip.ipv6.prefix[i], prefix, + net_if_ipv6_prefix_init(&ipv6->prefix[i], prefix, len, lifetime); NET_DBG("[%d] interface %p prefix %s/%d added", i, iface, @@ -1081,7 +1170,7 @@ struct net_if_ipv6_prefix *net_if_ipv6_prefix_add(struct net_if *iface, net_mgmt_event_notify(NET_EVENT_IPV6_PREFIX_ADD, iface); - return &config->ip.ipv6.prefix[i]; + return &ipv6->prefix[i]; } return NULL; @@ -1090,25 +1179,26 @@ struct net_if_ipv6_prefix *net_if_ipv6_prefix_add(struct net_if *iface, bool net_if_ipv6_prefix_rm(struct net_if *iface, struct in6_addr *addr, u8_t len) { - struct net_if_config *config; + struct net_if_ipv6 *ipv6 = iface->config.ip.ipv6; int i; - config = &iface->config; + if (!ipv6) { + return false; + } for (i = 0; i < NET_IF_MAX_IPV6_PREFIX; i++) { - if (!config->ip.ipv6.prefix[i].is_used) { + if (!ipv6->prefix[i].is_used) { continue; } - if (!net_ipv6_addr_cmp( - &config->ip.ipv6.prefix[i].prefix, addr) || - config->ip.ipv6.prefix[i].len != len) { + if (!net_ipv6_addr_cmp(&ipv6->prefix[i].prefix, addr) || + ipv6->prefix[i].len != len) { continue; } - net_if_ipv6_prefix_unset_timer(&config->ip.ipv6.prefix[i]); + net_if_ipv6_prefix_unset_timer(&ipv6->prefix[i]); - config->ip.ipv6.prefix[i].is_used = false; + ipv6->prefix[i].is_used = false; net_mgmt_event_notify(NET_EVENT_IPV6_PREFIX_DEL, iface); @@ -1122,20 +1212,21 @@ struct net_if_ipv6_prefix *net_if_ipv6_prefix_lookup(struct net_if *iface, struct in6_addr *addr, u8_t len) { - struct net_if_config *config; + struct net_if_ipv6 *ipv6 = iface->config.ip.ipv6; int i; - config = &iface->config; + if (!ipv6) { + return NULL; + } for (i = 0; i < NET_IF_MAX_IPV6_PREFIX; i++) { - if (!config->ip.ipv6.prefix[i].is_used) { + if (!ipv6->prefix[i].is_used) { continue; } - if (net_is_ipv6_prefix( - config->ip.ipv6.prefix[i].prefix.s6_addr, - addr->s6_addr, len)) { - return &config->ip.ipv6.prefix[i]; + if (net_is_ipv6_prefix(ipv6->prefix[i].prefix.s6_addr, + addr->s6_addr, len)) { + return &ipv6->prefix[i]; } } @@ -1147,21 +1238,22 @@ bool net_if_ipv6_addr_onlink(struct net_if **iface, struct in6_addr *addr) struct net_if *tmp; for (tmp = __net_if_start; tmp != __net_if_end; tmp++) { - struct net_if_config *config; + struct net_if_ipv6 *ipv6 = tmp->config.ip.ipv6; int i; if (iface && *iface && *iface != tmp) { continue; } - config = &tmp->config; + if (!ipv6) { + continue; + } for (i = 0; i < NET_IF_MAX_IPV6_PREFIX; i++) { - if (config->ip.ipv6.prefix[i].is_used && - net_is_ipv6_prefix( - config->ip.ipv6.prefix[i].prefix.s6_addr, - addr->s6_addr, - config->ip.ipv6.prefix[i].len)) { + if (ipv6->prefix[i].is_used && + net_is_ipv6_prefix(ipv6->prefix[i].prefix.s6_addr, + addr->s6_addr, + ipv6->prefix[i].len)) { if (iface) { *iface = tmp; } @@ -1362,22 +1454,23 @@ bool net_if_ipv6_router_rm(struct net_if_router *router) struct in6_addr *net_if_ipv6_get_ll(struct net_if *iface, enum net_addr_state addr_state) { - struct net_if_config *config; + struct net_if_ipv6 *ipv6 = iface->config.ip.ipv6; int i; - config = &iface->config; + if (!ipv6) { + return NULL; + } for (i = 0; i < NET_IF_MAX_IPV6_ADDR; i++) { - if (!config->ip.ipv6.unicast[i].is_used || + if (!ipv6->unicast[i].is_used || (addr_state != NET_ADDR_ANY_STATE && - config->ip.ipv6.unicast[i].addr_state != addr_state) || - config->ip.ipv6.unicast[i].address.family != AF_INET6) { + ipv6->unicast[i].addr_state != addr_state) || + ipv6->unicast[i].address.family != AF_INET6) { continue; } - if (net_is_ipv6_ll_addr( - &config->ip.ipv6.unicast[i].address.in6_addr)) { - return &config->ip.ipv6.unicast[i].address.in6_addr; + if (net_is_ipv6_ll_addr(&ipv6->unicast[i].address.in6_addr)) { + return &ipv6->unicast[i].address.in6_addr; } } @@ -1469,23 +1562,24 @@ static inline struct in6_addr *net_if_ipv6_get_best_match(struct net_if *iface, struct in6_addr *dst, u8_t *best_so_far) { - struct net_if_config *config; + struct net_if_ipv6 *ipv6 = iface->config.ip.ipv6; struct in6_addr *src = NULL; u8_t len; int i; - config = &iface->config; + if (!ipv6) { + return NULL; + } for (i = 0; i < NET_IF_MAX_IPV6_ADDR; i++) { - if (!is_proper_ipv6_address(&config->ip.ipv6.unicast[i])) { + if (!is_proper_ipv6_address(&ipv6->unicast[i])) { continue; } - len = get_length(dst, - &config->ip.ipv6.unicast[i].address.in6_addr); + len = get_length(dst, &ipv6->unicast[i].address.in6_addr); if (len >= *best_so_far) { *best_so_far = len; - src = &config->ip.ipv6.unicast[i].address.in6_addr; + src = &ipv6->unicast[i].address.in6_addr; } } @@ -1544,18 +1638,13 @@ const struct in6_addr *net_if_ipv6_select_src_addr(struct net_if *dst_iface, return src; } -u32_t net_if_ipv6_calc_reachable_time(struct net_if *iface) +u32_t net_if_ipv6_calc_reachable_time(struct net_if_ipv6 *ipv6) { u32_t min_reachable, max_reachable; - struct net_if_config *config; - config = net_if_config_get(iface); - - min_reachable = (MIN_RANDOM_NUMER * - config->ip.ipv6.base_reachable_time) + min_reachable = (MIN_RANDOM_NUMER * ipv6->base_reachable_time) / MIN_RANDOM_DENOM; - max_reachable = (MAX_RANDOM_NUMER * - config->ip.ipv6.base_reachable_time) + max_reachable = (MAX_RANDOM_NUMER * ipv6->base_reachable_time) / MAX_RANDOM_DENOM; NET_DBG("min_reachable:%u max_reachable:%u", min_reachable, @@ -1572,6 +1661,58 @@ u32_t net_if_ipv6_calc_reachable_time(struct net_if *iface) #endif /* CONFIG_NET_IPV6 */ #if defined(CONFIG_NET_IPV4) +int net_if_config_ipv4_get(struct net_if *iface, struct net_if_ipv4 **ipv4) +{ + int i; + + if (iface->config.ip.ipv4) { + if (ipv4) { + *ipv4 = iface->config.ip.ipv4; + } + + return 0; + } + + for (i = 0; i < ARRAY_SIZE(ipv4_addresses); i++) { + if (ipv4_addresses[i].iface) { + continue; + } + + iface->config.ip.ipv4 = &ipv4_addresses[i].ipv4; + ipv4_addresses[i].iface = iface; + + if (ipv4) { + *ipv4 = &ipv4_addresses[i].ipv4; + } + + return 0; + } + + return -ESRCH; +} + +int net_if_config_ipv4_put(struct net_if *iface) +{ + int i; + + if (!iface->config.ip.ipv4) { + return -EALREADY; + } + + for (i = 0; i < ARRAY_SIZE(ipv4_addresses); i++) { + if (ipv4_addresses[i].iface != iface) { + continue; + } + + iface->config.ip.ipv4 = NULL; + ipv4_addresses[i].iface = NULL; + + return 0; + } + + return 0; +} + struct net_if_router *net_if_ipv4_router_lookup(struct net_if *iface, struct in_addr *addr) { @@ -1634,23 +1775,25 @@ struct net_if_router *net_if_ipv4_router_add(struct net_if *iface, bool net_if_ipv4_addr_mask_cmp(struct net_if *iface, struct in_addr *addr) { - struct net_if_config *config; + struct net_if_ipv4 *ipv4 = iface->config.ip.ipv4; u32_t subnet; int i; - config = net_if_config_get(iface); + if (!ipv4) { + return false; + } subnet = ntohl(UNALIGNED_GET(&addr->s_addr)) & - ntohl(config->ip.ipv4.netmask.s_addr); + ntohl(ipv4->netmask.s_addr); for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { - if (!config->ip.ipv4.unicast[i].is_used || - config->ip.ipv4.unicast[i].address.family != AF_INET) { + if (!ipv4->unicast[i].is_used || + ipv4->unicast[i].address.family != AF_INET) { continue; } - if ((ntohl(config->ip.ipv4.unicast[i].address.in_addr.s_addr) & - ntohl(config->ip.ipv4.netmask.s_addr)) == subnet) { + if ((ntohl(ipv4->unicast[i].address.in_addr.s_addr) & + ntohl(ipv4->netmask.s_addr)) == subnet) { return true; } } @@ -1664,26 +1807,27 @@ struct net_if_addr *net_if_ipv4_addr_lookup(const struct in_addr *addr, struct net_if *iface; for (iface = __net_if_start; iface != __net_if_end; iface++) { - struct net_if_config *config; + struct net_if_ipv4 *ipv4 = iface->config.ip.ipv4; int i; - config = &iface->config; + if (!ipv4) { + continue; + } for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { - if (!config->ip.ipv4.unicast[i].is_used || - config->ip.ipv4.unicast[i].address.family - != AF_INET) { + if (!ipv4->unicast[i].is_used || + ipv4->unicast[i].address.family != AF_INET) { continue; } if (UNALIGNED_GET(&addr->s4_addr32[0]) == - config->ip.ipv4.unicast[i].address.in_addr.s_addr) { + ipv4->unicast[i].address.in_addr.s_addr) { if (ret) { *ret = iface; } - return &config->ip.ipv4.unicast[i]; + return &ipv4->unicast[i]; } } } @@ -1694,20 +1838,17 @@ struct net_if_addr *net_if_ipv4_addr_lookup(const struct in_addr *addr, static struct net_if_addr *ipv4_addr_find(struct net_if *iface, struct in_addr *addr) { - struct net_if_config *config; + struct net_if_ipv4 *ipv4 = iface->config.ip.ipv4; int i; - config = &iface->config; - for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { - if (!config->ip.ipv4.unicast[i].is_used) { + if (!ipv4->unicast[i].is_used) { continue; } - if (net_ipv4_addr_cmp( - addr, - &config->ip.ipv4.unicast[i].address.in_addr)) { - return &config->ip.ipv4.unicast[i]; + if (net_ipv4_addr_cmp(addr, + &ipv4->unicast[i].address.in_addr)) { + return &ipv4->unicast[i]; } } @@ -1719,20 +1860,22 @@ struct net_if_addr *net_if_ipv4_addr_add(struct net_if *iface, enum net_addr_type addr_type, u32_t vlifetime) { - struct net_if_config *config; struct net_if_addr *ifaddr; + struct net_if_ipv4 *ipv4; int i; + if (net_if_config_ipv4_get(iface, &ipv4) < 0) { + return NULL; + } + ifaddr = ipv4_addr_find(iface, addr); if (ifaddr) { /* TODO: should set addr_type/vlifetime */ return ifaddr; } - config = net_if_config_get(iface); - for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { - struct net_if_addr *cur = &config->ip.ipv4.unicast[i]; + struct net_if_addr *cur = &ipv4->unicast[i]; if (addr_type == NET_ADDR_DHCP && cur->addr_type == NET_ADDR_OVERRIDABLE) { @@ -1740,7 +1883,7 @@ struct net_if_addr *net_if_ipv4_addr_add(struct net_if *iface, break; } - if (!config->ip.ipv4.unicast[i].is_used) { + if (!ipv4->unicast[i].is_used) { ifaddr = cur; break; } @@ -1780,23 +1923,24 @@ struct net_if_addr *net_if_ipv4_addr_add(struct net_if *iface, bool net_if_ipv4_addr_rm(struct net_if *iface, struct in_addr *addr) { - struct net_if_config *config; + struct net_if_ipv4 *ipv4 = iface->config.ip.ipv4; int i; - config = &iface->config; + if (!ipv4) { + return false; + } for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { - if (!config->ip.ipv4.unicast[i].is_used) { + if (!ipv4->unicast[i].is_used) { continue; } - if (!net_ipv4_addr_cmp( - &config->ip.ipv4.unicast[i].address.in_addr, - addr)) { + if (!net_ipv4_addr_cmp(&ipv4->unicast[i].address.in_addr, + addr)) { continue; } - config->ip.ipv4.unicast[i].is_used = false; + ipv4->unicast[i].is_used = false; NET_DBG("[%d] interface %p address %s removed", i, iface, net_sprint_ipv4_addr(addr)); @@ -1813,26 +1957,27 @@ static struct net_if_mcast_addr *ipv4_maddr_find(struct net_if *iface, bool is_used, const struct in_addr *addr) { - struct net_if_config *config; + struct net_if_ipv4 *ipv4 = iface->config.ip.ipv4; int i; - config = &iface->config; + if (!ipv4) { + return NULL; + } for (i = 0; i < NET_IF_MAX_IPV4_MADDR; i++) { - if ((is_used && !config->ip.ipv4.mcast[i].is_used) || - (!is_used && config->ip.ipv4.mcast[i].is_used)) { + if ((is_used && !ipv4->mcast[i].is_used) || + (!is_used && ipv4->mcast[i].is_used)) { continue; } if (addr) { - if (!net_ipv4_addr_cmp( - &config->ip.ipv4.mcast[i].address.in_addr, - addr)) { + if (!net_ipv4_addr_cmp(&ipv4->mcast[i].address.in_addr, + addr)) { continue; } } - return &config->ip.ipv4.mcast[i]; + return &ipv4->mcast[i]; } return NULL; @@ -1843,6 +1988,10 @@ struct net_if_mcast_addr *net_if_ipv4_maddr_add(struct net_if *iface, { struct net_if_mcast_addr *maddr; + if (net_if_config_ipv4_get(iface, NULL) < 0) { + return NULL; + } + if (!net_is_ipv4_addr_mcast(addr)) { NET_DBG("Address %s is not a multicast address.", net_sprint_ipv4_addr(addr)); @@ -2007,7 +2156,7 @@ done: #else join_mcast_allnodes(iface); join_mcast_solicit_node(iface, - &iface->config.ip.ipv6.mcast[0].address.in6_addr); + &iface->config.ip.ipv6->mcast[0].address.in6_addr); #endif /* CONFIG_NET_IPV6_DAD */ #if defined(CONFIG_NET_IPV6_ND) @@ -2063,27 +2212,13 @@ done: void net_if_init(struct k_sem *startup_sync) { struct net_if *iface; + int i, if_count; NET_DBG(""); - for (iface = __net_if_start; iface != __net_if_end; iface++) { + for (iface = __net_if_start, if_count = 0; iface != __net_if_end; + iface++, if_count++) { init_iface(iface); - -#if defined(CONFIG_NET_IPV4) - iface->config.ip.ipv4.ttl = CONFIG_NET_INITIAL_TTL; -#endif - -#if defined(CONFIG_NET_IPV6) - iface->config.ip.ipv6.hop_limit = CONFIG_NET_INITIAL_HOP_LIMIT; - iface->config.ip.ipv6.base_reachable_time = REACHABLE_TIME; - - net_if_ipv6_set_reachable_time(iface); - -#if defined(CONFIG_NET_IPV6_ND) - k_delayed_work_init(&iface->config.ip.ipv6.rs_timer, - rs_timeout); -#endif -#endif /* CONFIG_NET_IPV6 */ } if (iface == __net_if_start) { @@ -2091,6 +2226,42 @@ void net_if_init(struct k_sem *startup_sync) return; } +#if defined(CONFIG_NET_IPV4) + if (if_count > ARRAY_SIZE(ipv4_addresses)) { + NET_WARN("You have %lu IPv4 net_if addresses but %d " + "network interfaces", ARRAY_SIZE(ipv4_addresses), + if_count); + NET_WARN("Consider increasing CONFIG_NET_IF_MAX_IPV4_COUNT " + "value."); + } + + for (i = 0; i < ARRAY_SIZE(ipv4_addresses); i++) { + ipv4_addresses[i].ipv4.ttl = CONFIG_NET_INITIAL_TTL; + } +#endif + +#if defined(CONFIG_NET_IPV6) + if (if_count > ARRAY_SIZE(ipv6_addresses)) { + NET_WARN("You have %lu IPv6 net_if addresses but %d " + "network interfaces", ARRAY_SIZE(ipv6_addresses), + if_count); + NET_WARN("Consider increasing CONFIG_NET_IF_MAX_IPV6_COUNT " + "value."); + } + + for (i = 0; i < ARRAY_SIZE(ipv6_addresses); i++) { + ipv6_addresses[i].ipv6.hop_limit = CONFIG_NET_INITIAL_HOP_LIMIT; + ipv6_addresses[i].ipv6.base_reachable_time = REACHABLE_TIME; + + net_if_ipv6_set_reachable_time(&ipv6_addresses[i].ipv6); + +#if defined(CONFIG_NET_IPV6_ND) + k_delayed_work_init(&ipv6_addresses[i].ipv6.rs_timer, + rs_timeout); +#endif + } +#endif /* CONFIG_NET_IPV6 */ + k_thread_create(&tx_thread_data, tx_stack, K_THREAD_STACK_SIZEOF(tx_stack), (k_thread_entry_t)net_if_tx_thread, diff --git a/subsys/net/ip/net_shell.c b/subsys/net/ip/net_shell.c index 81136fc6224..d50152e6a16 100644 --- a/subsys/net/ip/net_shell.c +++ b/subsys/net/ip/net_shell.c @@ -161,10 +161,13 @@ static void iface_cb(struct net_if *iface, void *user_data) #if defined(CONFIG_NET_IPV6) struct net_if_ipv6_prefix *prefix; struct net_if_router *router; + struct net_if_ipv6 *ipv6; +#endif +#if defined(CONFIG_NET_IPV4) + struct net_if_ipv4 *ipv4; #endif struct net_if_addr *unicast; struct net_if_mcast_addr *mcast; - struct net_if_config *config; const char *extra; int i, count; @@ -179,19 +182,19 @@ static void iface_cb(struct net_if *iface, void *user_data) return; } - config = &iface->config; - - printk("Link addr : %s\n", net_sprint_ll_addr( - net_if_get_link_addr(iface)->addr, - net_if_get_link_addr(iface)->len)); + printk("Link addr : %s\n", + net_sprint_ll_addr(net_if_get_link_addr(iface)->addr, + net_if_get_link_addr(iface)->len)); printk("MTU : %d\n", net_if_get_mtu(iface)); #if defined(CONFIG_NET_IPV6) count = 0; + ipv6 = iface->config.ip.ipv6; + printk("IPv6 unicast addresses (max %d):\n", NET_IF_MAX_IPV6_ADDR); - for (i = 0; i < NET_IF_MAX_IPV6_ADDR; i++) { - unicast = &config->ip.ipv6.unicast[i]; + for (i = 0; ipv6 && i < NET_IF_MAX_IPV6_ADDR; i++) { + unicast = &ipv6->unicast[i]; if (!unicast->is_used) { continue; @@ -212,8 +215,8 @@ static void iface_cb(struct net_if *iface, void *user_data) count = 0; printk("IPv6 multicast addresses (max %d):\n", NET_IF_MAX_IPV6_MADDR); - for (i = 0; i < NET_IF_MAX_IPV6_MADDR; i++) { - mcast = &config->ip.ipv6.mcast[i]; + for (i = 0; ipv6 && i < NET_IF_MAX_IPV6_MADDR; i++) { + mcast = &ipv6->mcast[i]; if (!mcast->is_used) { continue; @@ -232,8 +235,8 @@ static void iface_cb(struct net_if *iface, void *user_data) count = 0; printk("IPv6 prefixes (max %d):\n", NET_IF_MAX_IPV6_PREFIX); - for (i = 0; i < NET_IF_MAX_IPV6_PREFIX; i++) { - prefix = &config->ip.ipv6.prefix[i]; + for (i = 0; ipv6 && i < NET_IF_MAX_IPV6_PREFIX; i++) { + prefix = &ipv6->prefix[i]; if (!prefix->is_used) { continue; @@ -259,14 +262,16 @@ static void iface_cb(struct net_if *iface, void *user_data) router->is_infinite ? " infinite" : ""); } - printk("IPv6 hop limit : %d\n", - config->ip.ipv6.hop_limit); - printk("IPv6 base reachable time : %d\n", - config->ip.ipv6.base_reachable_time); - printk("IPv6 reachable time : %d\n", - config->ip.ipv6.reachable_time); - printk("IPv6 retransmit timer : %d\n", - config->ip.ipv6.retrans_timer); + if (ipv6) { + printk("IPv6 hop limit : %d\n", + ipv6->hop_limit); + printk("IPv6 base reachable time : %d\n", + ipv6->base_reachable_time); + printk("IPv6 reachable time : %d\n", + ipv6->reachable_time); + printk("IPv6 retransmit timer : %d\n", + ipv6->retrans_timer); + } #endif /* CONFIG_NET_IPV6 */ @@ -288,10 +293,11 @@ static void iface_cb(struct net_if *iface, void *user_data) count = 0; - printk("IPv4 unicast addresses (max %d):\n", - NET_IF_MAX_IPV4_ADDR); - for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { - unicast = &config->ip.ipv4.unicast[i]; + ipv4 = iface->config.ip.ipv4; + + printk("IPv4 unicast addresses (max %d):\n", NET_IF_MAX_IPV4_ADDR); + for (i = 0; ipv4 && i < NET_IF_MAX_IPV4_ADDR; i++) { + unicast = &ipv4->unicast[i]; if (!unicast->is_used) { continue; @@ -312,10 +318,9 @@ static void iface_cb(struct net_if *iface, void *user_data) count = 0; - printk("IPv4 multicast addresses (max %d):\n", - NET_IF_MAX_IPV4_MADDR); - for (i = 0; i < NET_IF_MAX_IPV4_MADDR; i++) { - mcast = &config->ip.ipv4.mcast[i]; + printk("IPv4 multicast addresses (max %d):\n", NET_IF_MAX_IPV4_MADDR); + for (i = 0; ipv4 && i < NET_IF_MAX_IPV4_MADDR; i++) { + mcast = &ipv4->mcast[i]; if (!mcast->is_used) { continue; @@ -331,25 +336,27 @@ static void iface_cb(struct net_if *iface, void *user_data) printk("\t\n"); } - printk("IPv4 gateway : %s\n", - net_sprint_ipv4_addr(&config->ip.ipv4.gw)); - printk("IPv4 netmask : %s\n", - net_sprint_ipv4_addr(&config->ip.ipv4.netmask)); + if (ipv4) { + printk("IPv4 gateway : %s\n", + net_sprint_ipv4_addr(&ipv4->gw)); + printk("IPv4 netmask : %s\n", + net_sprint_ipv4_addr(&ipv4->netmask)); + } #endif /* CONFIG_NET_IPV4 */ #if defined(CONFIG_NET_DHCPV4) printk("DHCPv4 lease time : %u\n", - config->dhcpv4.lease_time); + iface->config.dhcpv4.lease_time); printk("DHCPv4 renew time : %u\n", - config->dhcpv4.renewal_time); + iface->config.dhcpv4.renewal_time); printk("DHCPv4 server : %s\n", - net_sprint_ipv4_addr(&config->dhcpv4.server_id)); + net_sprint_ipv4_addr(&iface->config.dhcpv4.server_id)); printk("DHCPv4 requested : %s\n", - net_sprint_ipv4_addr(&config->dhcpv4.requested_ip)); + net_sprint_ipv4_addr(&iface->config.dhcpv4.requested_ip)); printk("DHCPv4 state : %s\n", - net_dhcpv4_state_name(config->dhcpv4.state)); + net_dhcpv4_state_name(iface->config.dhcpv4.state)); printk("DHCPv4 attempts : %d\n", - config->dhcpv4.attempts); + iface->config.dhcpv4.attempts); #endif /* CONFIG_NET_DHCPV4 */ } @@ -2259,7 +2266,7 @@ static void get_my_ipv4_addr(struct net_if *iface, { /* Just take the first IPv4 address of an interface. */ memcpy(&net_sin(myaddr)->sin_addr, - &iface->config.ip.ipv4.unicast[0].address.in_addr, + &iface->config.ip.ipv4->unicast[0].address.in_addr, sizeof(struct in_addr)); net_sin(myaddr)->sin_port = 0; /* let the IP stack to select */ diff --git a/subsys/net/ip/rpl.c b/subsys/net/ip/rpl.c index c36c257a1e3..6662bc187b0 100644 --- a/subsys/net/ip/rpl.c +++ b/subsys/net/ip/rpl.c @@ -2180,9 +2180,9 @@ static void send_mcast_dao(struct net_rpl_instance *instance) /* Send a DAO for own multicast addresses */ for (i = 0; i < NET_IF_MAX_IPV6_MADDR; i++) { addr = - &instance->iface->config.ip.ipv6.mcast[i].address.in6_addr; + &instance->iface->config.ip.ipv6->mcast[i].address.in6_addr; - if (instance->iface->config.ip.ipv6.mcast[i].is_used && + if (instance->iface->config.ip.ipv6->mcast[i].is_used && net_is_ipv6_addr_mcast_global(addr)) { net_rpl_dao_send(instance->iface, diff --git a/subsys/net/lib/app/client.c b/subsys/net/lib/app/client.c index fb57caf4e1a..67f609eec2d 100644 --- a/subsys/net/lib/app/client.c +++ b/subsys/net/lib/app/client.c @@ -639,7 +639,7 @@ static void check_local_address(struct net_app_ctx *ctx, iface = net_context_get_iface(net_ctx); if (iface) { laddr = - &iface->config.ip.ipv4.unicast[0].address.in_addr; + &iface->config.ip.ipv4->unicast[0].address.in_addr; net_ipaddr_copy(&net_sin(&ctx->ipv4.local)->sin_addr, laddr); } else { diff --git a/subsys/net/lib/app/init.c b/subsys/net/lib/app/init.c index bd4bf98b2c6..36928dda42b 100644 --- a/subsys/net/lib/app/init.c +++ b/subsys/net/lib/app/init.c @@ -51,7 +51,7 @@ static void ipv4_addr_add_handler(struct net_mgmt_event_callback *cb, for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { struct net_if_addr *if_addr = - &iface->config.ip.ipv4.unicast[i]; + &iface->config.ip.ipv4->unicast[i]; if (if_addr->addr_type != NET_ADDR_DHCP || !if_addr->is_used) { continue; @@ -64,10 +64,11 @@ static void ipv4_addr_add_handler(struct net_mgmt_event_callback *cb, NET_INFO("Lease time: %u seconds", iface->config.dhcpv4.lease_time); NET_INFO("Subnet: %s", - net_addr_ntop(AF_INET, &iface->config.ip.ipv4.netmask, + net_addr_ntop(AF_INET, + &iface->config.ip.ipv4->netmask, hr_addr, NET_IPV4_ADDR_LEN)); NET_INFO("Router: %s", - net_addr_ntop(AF_INET, &iface->config.ip.ipv4.gw, + net_addr_ntop(AF_INET, &iface->config.ip.ipv4->gw, hr_addr, NET_IPV4_ADDR_LEN)); #endif break; @@ -178,17 +179,19 @@ static struct in6_addr laddr; static void ipv6_event_handler(struct net_mgmt_event_callback *cb, u32_t mgmt_event, struct net_if *iface) { - struct net_if_config *config; + struct net_if_ipv6 *ipv6 = iface->config.ip.ipv6; int i; - config = net_if_config_get(iface); + if (!ipv6) { + return; + } if (mgmt_event == NET_EVENT_IPV6_ADDR_ADD) { /* save the last added IP address for this interface */ for (i = NET_IF_MAX_IPV6_ADDR - 1; i >= 0; i--) { - if (config->ip.ipv6.unicast[i].is_used) { + if (ipv6->unicast[i].is_used) { memcpy(&laddr, - &config->ip.ipv6.unicast[i].address.in6_addr, + &ipv6->unicast[i].address.in6_addr, sizeof(laddr)); } } diff --git a/subsys/net/lib/app/net_app.c b/subsys/net/lib/app/net_app.c index d84211ce6d3..3ee0c86dbf1 100644 --- a/subsys/net/lib/app/net_app.c +++ b/subsys/net/lib/app/net_app.c @@ -308,9 +308,11 @@ int _net_app_set_local_addr(struct sockaddr *addr, const char *myaddr, #if defined(CONFIG_NET_IPV4) struct net_if *iface = net_if_get_default(); + NET_ASSERT(iface->config.ip.ipv4); + /* For IPv4 we take the first address in the interface */ net_ipaddr_copy(&net_sin(addr)->sin_addr, - &iface->config.ip.ipv4.unicast[0].address.in_addr); + &iface->config.ip.ipv4->unicast[0].address.in_addr); #else return -EPFNOSUPPORT; #endif diff --git a/tests/net/arp/src/main.c b/tests/net/arp/src/main.c index 661bc508702..eb5d030cd02 100644 --- a/tests/net/arp/src/main.c +++ b/tests/net/arp/src/main.c @@ -151,13 +151,13 @@ static inline struct in_addr *if_get_addr(struct net_if *iface) int i; for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { - if (iface->config.ip.ipv4.unicast[i].is_used && - iface->config.ip.ipv4.unicast[i].address.family == + if (iface->config.ip.ipv4->unicast[i].is_used && + iface->config.ip.ipv4->unicast[i].address.family == AF_INET && - iface->config.ip.ipv4.unicast[i].addr_state == + iface->config.ip.ipv4->unicast[i].addr_state == NET_ADDR_PREFERRED) { return - &iface->config.ip.ipv4.unicast[i].address.in_addr; + &iface->config.ip.ipv4->unicast[i].address.in_addr; } } @@ -507,13 +507,13 @@ void run_tests(void) arp_hdr = NET_ARP_HDR(pkt2); if (!net_ipv4_addr_cmp(&arp_hdr->dst_ipaddr, - &iface->config.ip.ipv4.gw)) { + &iface->config.ip.ipv4->gw)) { char out[sizeof("xxx.xxx.xxx.xxx")]; snprintk(out, sizeof(out), "%s", net_sprint_ipv4_addr(&arp_hdr->dst_ipaddr)); printk("ARP IP dst invalid %s, should be %s\n", out, - net_sprint_ipv4_addr(&iface->config.ip.ipv4.gw)); + net_sprint_ipv4_addr(&iface->config.ip.ipv4->gw)); zassert_true(0, "exiting"); } diff --git a/tests/net/checksum_offload/prj.conf b/tests/net/checksum_offload/prj.conf index 457e15e1a32..3356e2f00a8 100644 --- a/tests/net/checksum_offload/prj.conf +++ b/tests/net/checksum_offload/prj.conf @@ -17,6 +17,8 @@ CONFIG_NET_PKT_TX_COUNT=15 CONFIG_NET_PKT_RX_COUNT=15 CONFIG_NET_BUF_RX_COUNT=15 CONFIG_NET_BUF_TX_COUNT=15 +CONFIG_NET_IF_MAX_IPV6_COUNT=2 +CONFIG_NET_IF_MAX_IPV4_COUNT=2 CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=6 CONFIG_NET_IPV6_ND=n CONFIG_ZTEST=y diff --git a/tests/net/iface/prj.conf b/tests/net/iface/prj.conf index 1c43e10f0c2..3d9cc2442bc 100644 --- a/tests/net/iface/prj.conf +++ b/tests/net/iface/prj.conf @@ -16,6 +16,7 @@ CONFIG_NET_PKT_TX_COUNT=10 CONFIG_NET_PKT_RX_COUNT=5 CONFIG_NET_BUF_RX_COUNT=10 CONFIG_NET_BUF_TX_COUNT=10 +CONFIG_NET_IF_MAX_IPV6_COUNT=3 CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=6 CONFIG_NET_MAX_NEXTHOPS=8 CONFIG_NET_IPV6_MAX_NEIGHBORS=8 diff --git a/tests/net/ipv6/src/main.c b/tests/net/ipv6/src/main.c index b1dfeb5ad8a..4976c897721 100644 --- a/tests/net/ipv6/src/main.c +++ b/tests/net/ipv6/src/main.c @@ -244,6 +244,7 @@ static bool test_init(void) struct net_if_mcast_addr *maddr; struct net_if *iface = net_if_get_default(); struct net_if *iface2 = NULL; + struct net_if_ipv6 *ipv6; int i; if (!iface) { @@ -257,12 +258,14 @@ static bool test_init(void) * manually in this special case so that subsequent tests can * pass. */ + net_if_config_ipv6_get(iface, &ipv6); + for (i = 0; i < NET_IF_MAX_IPV6_ADDR; i++) { - if (iface->config.ip.ipv6.unicast[i].is_used) { + if (iface->config.ip.ipv6->unicast[i].is_used) { continue; } - ifaddr = &iface->config.ip.ipv6.unicast[i]; + ifaddr = &iface->config.ip.ipv6->unicast[i]; ifaddr->is_used = true; ifaddr->address.family = AF_INET6; diff --git a/tests/net/tcp/prj.conf b/tests/net/tcp/prj.conf index 01f0f9dfc26..ac358974f26 100644 --- a/tests/net/tcp/prj.conf +++ b/tests/net/tcp/prj.conf @@ -18,6 +18,8 @@ CONFIG_NET_LOG=y CONFIG_SYS_LOG_SHOW_COLOR=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y +CONFIG_NET_IF_MAX_IPV6_COUNT=2 +CONFIG_NET_IF_MAX_IPV4_COUNT=2 CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=5 CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT=3 CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=2 diff --git a/tests/net/tcp/src/main.c b/tests/net/tcp/src/main.c index 0d56e2e7132..93a38a735dc 100644 --- a/tests/net/tcp/src/main.c +++ b/tests/net/tcp/src/main.c @@ -196,13 +196,13 @@ static inline struct in_addr *if_get_addr(struct net_if *iface) int i; for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { - if (iface->config.ip.ipv4.unicast[i].is_used && - iface->config.ip.ipv4.unicast[i].address.family == + if (iface->config.ip.ipv4->unicast[i].is_used && + iface->config.ip.ipv4->unicast[i].address.family == AF_INET && - iface->config.ip.ipv4.unicast[i].addr_state == + iface->config.ip.ipv4->unicast[i].addr_state == NET_ADDR_PREFERRED) { return - &iface->config.ip.ipv4.unicast[i].address.in_addr; + &iface->config.ip.ipv4->unicast[i].address.in_addr; } } diff --git a/tests/net/udp/src/main.c b/tests/net/udp/src/main.c index 37464eb5cad..acb6cfba0fd 100644 --- a/tests/net/udp/src/main.c +++ b/tests/net/udp/src/main.c @@ -106,13 +106,13 @@ static inline struct in_addr *if_get_addr(struct net_if *iface) int i; for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { - if (iface->config.ip.ipv4.unicast[i].is_used && - iface->config.ip.ipv4.unicast[i].address.family == + if (iface->config.ip.ipv4->unicast[i].is_used && + iface->config.ip.ipv4->unicast[i].address.family == AF_INET && - iface->config.ip.ipv4.unicast[i].addr_state == + iface->config.ip.ipv4->unicast[i].addr_state == NET_ADDR_PREFERRED) { return - &iface->config.ip.ipv4.unicast[i].address.in_addr; + &iface->config.ip.ipv4->unicast[i].address.in_addr; } }