From 1b0f9e865e35a6b3e1ca8aad7a67f7cfbfc2e666 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Wed, 31 Jan 2024 17:39:44 +0200 Subject: [PATCH] net: ipv4: Make netmask IPv4 address specific The netmask should be tied to the IPv4 address instead of being global for the network interface. If there is only one IPv4 address specified to the network interface, nothing changes from user point of view. But if there are more than one IPv4 address / network interface, the netmask must be specified to each address separately. This means that net_if_ipv4_get_netmask() and net_if_ipv4_set_netmask() functions should not be used as they only work reliably if there is only one IPv4 address in the network interface. The new net_if_ipv4_get_netmask_by_addr() and net_if_ipv4_set_netmask_by_addr() functions should be used as they make sure that the netmask is tied to correct IPv4 address in the network interface. Signed-off-by: Jukka Rissanen --- include/zephyr/net/net_if.h | 55 +++++- subsys/net/ip/ipv4_autoconf.c | 4 +- subsys/net/ip/net_if.c | 247 +++++++++++++++++++++----- subsys/net/l2/ethernet/arp.c | 10 +- subsys/net/lib/capture/capture.c | 4 +- subsys/net/lib/config/init.c | 10 +- subsys/net/lib/dhcpv4/dhcpv4.c | 4 +- subsys/net/lib/dhcpv4/dhcpv4_server.c | 2 +- subsys/net/lib/shell/iface.c | 8 +- subsys/net/lib/shell/ipv4.c | 17 +- subsys/net/lib/shell/tcp.c | 2 +- 11 files changed, 289 insertions(+), 74 deletions(-) diff --git a/include/zephyr/net/net_if.h b/include/zephyr/net/net_if.h index b0478eee9ae..387e742d0b9 100644 --- a/include/zephyr/net/net_if.h +++ b/include/zephyr/net/net_if.h @@ -368,9 +368,21 @@ struct net_if_dhcpv6 { #endif /** @endcond */ +/** + * @brief Network Interface unicast IPv4 address and netmask + * + * Stores the unicast IPv4 address and related netmask. + */ +struct net_if_addr_ipv4 { + /** IPv4 address */ + struct net_if_addr ipv4; + /** Netmask */ + struct in_addr netmask; +}; + struct net_if_ipv4 { /** Unicast IP addresses */ - struct net_if_addr unicast[NET_IF_MAX_IPV4_ADDR]; + struct net_if_addr_ipv4 unicast[NET_IF_MAX_IPV4_ADDR]; /** Multicast IP addresses */ struct net_if_mcast_addr mcast[NET_IF_MAX_IPV4_MADDR]; @@ -378,9 +390,6 @@ struct net_if_ipv4 { /** Gateway */ struct in_addr gw; - /** Netmask */ - struct in_addr netmask; - /** IPv4 time-to-live */ uint8_t ttl; @@ -2341,6 +2350,18 @@ struct in_addr *net_if_ipv4_get_ll(struct net_if *iface, struct in_addr *net_if_ipv4_get_global_addr(struct net_if *iface, enum net_addr_state addr_state); +/** + * @brief Get IPv4 netmask related to an address of an interface. + * + * @param iface Interface to use. + * @param addr IPv4 address to check. + * + * @return The netmask set on the interface related to the give address, + * unspecified address if not found. + */ +struct in_addr net_if_ipv4_get_netmask_by_addr(struct net_if *iface, + const struct in_addr *addr); + /** * @brief Get IPv4 netmask of an interface. * @@ -2370,6 +2391,32 @@ void net_if_ipv4_set_netmask(struct net_if *iface, __syscall bool net_if_ipv4_set_netmask_by_index(int index, const struct in_addr *netmask); +/** + * @brief Set IPv4 netmask for an interface index for a given address. + * + * @param index Network interface index + * @param addr IPv4 address related to this netmask + * @param netmask IPv4 netmask + * + * @return True if netmask was added, false otherwise. + */ +__syscall bool net_if_ipv4_set_netmask_by_addr_by_index(int index, + const struct in_addr *addr, + const struct in_addr *netmask); + +/** + * @brief Set IPv4 netmask for an interface index for a given address. + * + * @param iface Network interface + * @param addr IPv4 address related to this netmask + * @param netmask IPv4 netmask + * + * @return True if netmask was added, false otherwise. + */ +bool net_if_ipv4_set_netmask_by_addr(struct net_if *iface, + const struct in_addr *addr, + const struct in_addr *netmask); + /** * @brief Set IPv4 gateway for an interface. * diff --git a/subsys/net/ip/ipv4_autoconf.c b/subsys/net/ip/ipv4_autoconf.c index aa18a27ef63..e34b51523c3 100644 --- a/subsys/net/ip/ipv4_autoconf.c +++ b/subsys/net/ip/ipv4_autoconf.c @@ -182,7 +182,9 @@ static inline void ipv4_autoconf_addr_set(struct net_if_ipv4_autoconf *ipv4auto) return; } - net_if_ipv4_set_netmask(ipv4auto->iface, &netmask); + net_if_ipv4_set_netmask_by_addr(ipv4auto->iface, + &ipv4auto->requested_ip, + &netmask); ipv4auto->state = NET_IPV4_AUTOCONF_ASSIGNED; } diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index 5bb862896ed..7a6cfc34821 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -3361,16 +3361,17 @@ bool net_if_ipv4_addr_mask_cmp(struct net_if *iface, goto out; } - subnet = UNALIGNED_GET(&addr->s_addr) & ipv4->netmask.s_addr; - for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { - if (!ipv4->unicast[i].is_used || - ipv4->unicast[i].address.family != AF_INET) { + if (!ipv4->unicast[i].ipv4.is_used || + ipv4->unicast[i].ipv4.address.family != AF_INET) { continue; } - if ((ipv4->unicast[i].address.in_addr.s_addr & - ipv4->netmask.s_addr) == subnet) { + subnet = UNALIGNED_GET(&addr->s_addr) & + ipv4->unicast[i].netmask.s_addr; + + if ((ipv4->unicast[i].ipv4.address.in_addr.s_addr & + ipv4->unicast[i].netmask.s_addr) == subnet) { ret = true; goto out; } @@ -3387,6 +3388,7 @@ static bool ipv4_is_broadcast_address(struct net_if *iface, { struct net_if_ipv4 *ipv4; bool ret = false; + struct in_addr bcast; net_if_lock(iface); @@ -3396,15 +3398,19 @@ static bool ipv4_is_broadcast_address(struct net_if *iface, goto out; } - if (!net_if_ipv4_addr_mask_cmp(iface, addr)) { - ret = false; - goto out; - } + for (int i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { + if (!ipv4->unicast[i].ipv4.is_used || + ipv4->unicast[i].ipv4.address.family != AF_INET) { + continue; + } - if ((UNALIGNED_GET(&addr->s_addr) & ~ipv4->netmask.s_addr) == - ~ipv4->netmask.s_addr) { - ret = true; - goto out; + bcast.s_addr = ipv4->unicast[i].ipv4.address.in_addr.s_addr | + ~ipv4->unicast[i].netmask.s_addr; + + if (bcast.s_addr == addr->s_addr) { + ret = true; + goto out; + } } out: @@ -3489,14 +3495,14 @@ static struct in_addr *net_if_ipv4_get_best_match(struct net_if *iface, } for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { - if (!is_proper_ipv4_address(&ipv4->unicast[i])) { + if (!is_proper_ipv4_address(&ipv4->unicast[i].ipv4)) { continue; } - len = get_diff_ipv4(dst, &ipv4->unicast[i].address.in_addr); + len = get_diff_ipv4(dst, &ipv4->unicast[i].ipv4.address.in_addr); if (len >= *best_so_far) { *best_so_far = len; - src = &ipv4->unicast[i].address.in_addr; + src = &ipv4->unicast[i].ipv4.address.in_addr; } } @@ -3525,14 +3531,14 @@ static struct in_addr *if_ipv4_get_addr(struct net_if *iface, } for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { - if (!ipv4->unicast[i].is_used || + if (!ipv4->unicast[i].ipv4.is_used || (addr_state != NET_ADDR_ANY_STATE && - ipv4->unicast[i].addr_state != addr_state) || - ipv4->unicast[i].address.family != AF_INET) { + ipv4->unicast[i].ipv4.addr_state != addr_state) || + ipv4->unicast[i].ipv4.address.family != AF_INET) { continue; } - if (net_ipv4_is_ll_addr(&ipv4->unicast[i].address.in_addr)) { + if (net_ipv4_is_ll_addr(&ipv4->unicast[i].ipv4.address.in_addr)) { if (!ll) { continue; } @@ -3542,7 +3548,7 @@ static struct in_addr *if_ipv4_get_addr(struct net_if *iface, } } - addr = &ipv4->unicast[i].address.in_addr; + addr = &ipv4->unicast[i].ipv4.address.in_addr; goto out; } @@ -3651,19 +3657,19 @@ struct net_if_addr *net_if_ipv4_addr_lookup(const struct in_addr *addr, } for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { - if (!ipv4->unicast[i].is_used || - ipv4->unicast[i].address.family != AF_INET) { + if (!ipv4->unicast[i].ipv4.is_used || + ipv4->unicast[i].ipv4.address.family != AF_INET) { continue; } if (UNALIGNED_GET(&addr->s4_addr32[0]) == - ipv4->unicast[i].address.in_addr.s_addr) { + ipv4->unicast[i].ipv4.address.in_addr.s_addr) { if (ret) { *ret = iface; } - ifaddr = &ipv4->unicast[i]; + ifaddr = &ipv4->unicast[i].ipv4; net_if_unlock(iface); goto out; } @@ -3702,9 +3708,12 @@ static inline int z_vrfy_net_if_ipv4_addr_lookup_by_index( #include #endif -struct in_addr net_if_ipv4_get_netmask(struct net_if *iface) +struct in_addr net_if_ipv4_get_netmask_by_addr(struct net_if *iface, + const struct in_addr *addr) { struct in_addr netmask = { 0 }; + struct net_if_ipv4 *ipv4; + uint32_t subnet; net_if_lock(iface); @@ -3712,31 +3721,143 @@ struct in_addr net_if_ipv4_get_netmask(struct net_if *iface) goto out; } - if (!iface->config.ip.ipv4) { + ipv4 = iface->config.ip.ipv4; + if (ipv4 == NULL) { goto out; } - netmask = iface->config.ip.ipv4->netmask; + for (int i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { + if (!ipv4->unicast[i].ipv4.is_used || + ipv4->unicast[i].ipv4.address.family != AF_INET) { + continue; + } + + subnet = UNALIGNED_GET(&addr->s_addr) & + ipv4->unicast[i].netmask.s_addr; + + if ((ipv4->unicast[i].ipv4.address.in_addr.s_addr & + ipv4->unicast[i].netmask.s_addr) == subnet) { + netmask = ipv4->unicast[i].netmask; + goto out; + } + } + out: net_if_unlock(iface); return netmask; } -void net_if_ipv4_set_netmask(struct net_if *iface, - const struct in_addr *netmask) +bool net_if_ipv4_set_netmask_by_addr(struct net_if *iface, + const struct in_addr *addr, + const struct in_addr *netmask) { + struct net_if_ipv4 *ipv4; + uint32_t subnet; + bool ret = false; + net_if_lock(iface); if (net_if_config_ipv4_get(iface, NULL) < 0) { goto out; } - if (!iface->config.ip.ipv4) { + ipv4 = iface->config.ip.ipv4; + if (ipv4 == NULL) { goto out; } - net_ipaddr_copy(&iface->config.ip.ipv4->netmask, netmask); + for (int i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { + if (!ipv4->unicast[i].ipv4.is_used || + ipv4->unicast[i].ipv4.address.family != AF_INET) { + continue; + } + + subnet = UNALIGNED_GET(&addr->s_addr) & + ipv4->unicast[i].netmask.s_addr; + + if ((ipv4->unicast[i].ipv4.address.in_addr.s_addr & + ipv4->unicast[i].netmask.s_addr) == subnet) { + ipv4->unicast[i].netmask = *netmask; + ret = true; + goto out; + } + } + +out: + net_if_unlock(iface); + + return ret; +} + +/* Using this function is problematic as if we have multiple + * addresses configured, which one to return. Use heuristic + * in this case and return the first one found. Please use + * net_if_ipv4_get_netmask_by_addr() instead. + */ +struct in_addr net_if_ipv4_get_netmask(struct net_if *iface) +{ + struct in_addr netmask = { 0 }; + struct net_if_ipv4 *ipv4; + + net_if_lock(iface); + + if (net_if_config_ipv4_get(iface, NULL) < 0) { + goto out; + } + + ipv4 = iface->config.ip.ipv4; + if (ipv4 == NULL) { + goto out; + } + + for (int i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { + if (!ipv4->unicast[i].ipv4.is_used || + ipv4->unicast[i].ipv4.address.family != AF_INET) { + continue; + } + + netmask = iface->config.ip.ipv4->unicast[i].netmask; + break; + } + +out: + net_if_unlock(iface); + + return netmask; +} + +/* Using this function is problematic as if we have multiple + * addresses configured, which one to set. Use heuristic + * in this case and set the first one found. Please use + * net_if_ipv4_set_netmask_by_addr() instead. + */ +void net_if_ipv4_set_netmask(struct net_if *iface, + const struct in_addr *netmask) +{ + struct net_if_ipv4 *ipv4; + + net_if_lock(iface); + + if (net_if_config_ipv4_get(iface, NULL) < 0) { + goto out; + } + + ipv4 = iface->config.ip.ipv4; + if (ipv4 == NULL) { + goto out; + } + + for (int i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { + if (!ipv4->unicast[i].ipv4.is_used || + ipv4->unicast[i].ipv4.address.family != AF_INET) { + continue; + } + + net_ipaddr_copy(&ipv4->unicast[i].netmask, netmask); + break; + } + out: net_if_unlock(iface); } @@ -3756,6 +3877,22 @@ bool z_impl_net_if_ipv4_set_netmask_by_index(int index, return true; } +bool z_impl_net_if_ipv4_set_netmask_by_addr_by_index(int index, + const struct in_addr *addr, + const struct in_addr *netmask) +{ + struct net_if *iface; + + iface = net_if_get_by_index(index); + if (!iface) { + return false; + } + + net_if_ipv4_set_netmask_by_addr(iface, addr, netmask); + + return true; +} + #ifdef CONFIG_USERSPACE bool z_vrfy_net_if_ipv4_set_netmask_by_index(int index, const struct in_addr *netmask) @@ -3775,6 +3912,30 @@ bool z_vrfy_net_if_ipv4_set_netmask_by_index(int index, } #include + +bool z_vrfy_net_if_ipv4_set_netmask_by_addr_by_index(int index, + const struct in_addr *addr, + const struct in_addr *netmask) +{ + struct in_addr ipv4_addr, netmask_addr; + struct net_if *iface; + + iface = z_vrfy_net_if_get_by_index(index); + if (!iface) { + return false; + } + + K_OOPS(k_usermode_from_copy(&ipv4_addr, (void *)addr, + sizeof(ipv4_addr))); + K_OOPS(k_usermode_from_copy(&netmask_addr, (void *)netmask, + sizeof(netmask_addr))); + + return z_impl_net_if_ipv4_set_netmask_by_addr_by_index(index, + &ipv4_addr, + &netmask_addr); +} + +#include #endif /* CONFIG_USERSPACE */ void net_if_ipv4_set_gw(struct net_if *iface, const struct in_addr *gw) @@ -3836,13 +3997,13 @@ static struct net_if_addr *ipv4_addr_find(struct net_if *iface, int i; for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { - if (!ipv4->unicast[i].is_used) { + if (!ipv4->unicast[i].ipv4.is_used) { continue; } if (net_ipv4_addr_cmp(addr, - &ipv4->unicast[i].address.in_addr)) { - return &ipv4->unicast[i]; + &ipv4->unicast[i].ipv4.address.in_addr)) { + return &ipv4->unicast[i].ipv4; } } @@ -3871,7 +4032,7 @@ struct net_if_addr *net_if_ipv4_addr_add(struct net_if *iface, } for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { - struct net_if_addr *cur = &ipv4->unicast[i]; + struct net_if_addr *cur = &ipv4->unicast[i].ipv4; if (addr_type == NET_ADDR_DHCP && cur->addr_type == NET_ADDR_OVERRIDABLE) { @@ -3879,7 +4040,7 @@ struct net_if_addr *net_if_ipv4_addr_add(struct net_if *iface, break; } - if (!ipv4->unicast[i].is_used) { + if (!ipv4->unicast[i].ipv4.is_used) { ifaddr = cur; break; } @@ -3935,23 +4096,23 @@ bool net_if_ipv4_addr_rm(struct net_if *iface, const struct in_addr *addr) } for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { - if (!ipv4->unicast[i].is_used) { + if (!ipv4->unicast[i].ipv4.is_used) { continue; } - if (!net_ipv4_addr_cmp(&ipv4->unicast[i].address.in_addr, + if (!net_ipv4_addr_cmp(&ipv4->unicast[i].ipv4.address.in_addr, addr)) { continue; } - ipv4->unicast[i].is_used = false; + ipv4->unicast[i].ipv4.is_used = false; NET_DBG("[%d] interface %p address %s removed", i, iface, net_sprint_ipv4_addr(addr)); net_mgmt_event_notify_with_info( NET_EVENT_IPV4_ADDR_DEL, iface, - &ipv4->unicast[i].address.in_addr, + &ipv4->unicast[i].ipv4.address.in_addr, sizeof(struct in_addr)); ret = true; @@ -4056,7 +4217,7 @@ void net_if_ipv4_addr_foreach(struct net_if *iface, net_if_ip_addr_cb_t cb, } for (int i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { - struct net_if_addr *if_addr = &ipv4->unicast[i]; + struct net_if_addr *if_addr = &ipv4->unicast[i].ipv4; if (!if_addr->is_used) { continue; diff --git a/subsys/net/l2/ethernet/arp.c b/subsys/net/l2/ethernet/arp.c index 27fb70a6aaf..93b63f246ad 100644 --- a/subsys/net/l2/ethernet/arp.c +++ b/subsys/net/l2/ethernet/arp.c @@ -227,13 +227,13 @@ static inline struct in_addr *if_get_addr(struct net_if *iface, } for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { - if (ipv4->unicast[i].is_used && - ipv4->unicast[i].address.family == AF_INET && - ipv4->unicast[i].addr_state == NET_ADDR_PREFERRED && + if (ipv4->unicast[i].ipv4.is_used && + ipv4->unicast[i].ipv4.address.family == AF_INET && + ipv4->unicast[i].ipv4.addr_state == NET_ADDR_PREFERRED && (!addr || net_ipv4_addr_cmp(addr, - &ipv4->unicast[i].address.in_addr))) { - return &ipv4->unicast[i].address.in_addr; + &ipv4->unicast[i].ipv4.address.in_addr))) { + return &ipv4->unicast[i].ipv4.address.in_addr; } } diff --git a/subsys/net/lib/capture/capture.c b/subsys/net/lib/capture/capture.c index 91ed775ad45..27114ca7e67 100644 --- a/subsys/net/lib/capture/capture.c +++ b/subsys/net/lib/capture/capture.c @@ -230,7 +230,9 @@ static int setup_iface(struct net_if *iface, const char *ipaddr, /* Set the netmask so that we do not get IPv4 traffic routed * into this interface. */ - net_if_ipv4_set_netmask(iface, &netmask); + net_if_ipv4_set_netmask_by_addr(iface, + &net_sin(addr)->sin_addr, + &netmask); *addr_len = sizeof(struct sockaddr_in); } else { diff --git a/subsys/net/lib/config/init.c b/subsys/net/lib/config/init.c index fcd379c1559..a54fc0ed5c9 100644 --- a/subsys/net/lib/config/init.c +++ b/subsys/net/lib/config/init.c @@ -70,7 +70,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].ipv4; if (if_addr->addr_type != NET_ADDR_DHCP || !if_addr->is_used) { continue; @@ -85,7 +85,7 @@ static void ipv4_addr_add_handler(struct net_mgmt_event_callback *cb, iface->config.dhcpv4.lease_time); NET_INFO("Subnet: %s", net_addr_ntop(AF_INET, - &iface->config.ip.ipv4->netmask, + &iface->config.ip.ipv4->unicast[i].netmask, hr_addr, sizeof(hr_addr))); NET_INFO("Router: %s", net_addr_ntop(AF_INET, @@ -141,7 +141,7 @@ static void setup_ipv4(struct net_if *iface) #if CONFIG_NET_CONFIG_LOG_LEVEL >= LOG_LEVEL_INF char hr_addr[NET_IPV4_ADDR_LEN]; #endif - struct in_addr addr; + struct in_addr addr, netmask; if (sizeof(CONFIG_NET_CONFIG_MY_IPV4_ADDR) == 1) { /* Empty address, skip setting ANY address in this case */ @@ -177,11 +177,11 @@ static void setup_ipv4(struct net_if *iface) if (sizeof(CONFIG_NET_CONFIG_MY_IPV4_NETMASK) > 1) { /* If not empty */ if (net_addr_pton(AF_INET, CONFIG_NET_CONFIG_MY_IPV4_NETMASK, - &addr)) { + &netmask)) { NET_ERR("Invalid netmask: %s", CONFIG_NET_CONFIG_MY_IPV4_NETMASK); } else { - net_if_ipv4_set_netmask(iface, &addr); + net_if_ipv4_set_netmask_by_addr(iface, &addr, &netmask); } } diff --git a/subsys/net/lib/dhcpv4/dhcpv4.c b/subsys/net/lib/dhcpv4/dhcpv4.c index e916d3f86c6..bfcd7c5f4ce 100644 --- a/subsys/net/lib/dhcpv4/dhcpv4.c +++ b/subsys/net/lib/dhcpv4/dhcpv4.c @@ -823,7 +823,9 @@ static bool dhcpv4_parse_options(struct net_pkt *pkt, return false; } - net_if_ipv4_set_netmask(iface, &netmask); + net_if_ipv4_set_netmask_by_addr(iface, + &iface->config.dhcpv4.requested_ip, + &netmask); NET_DBG("options_subnet_mask %s", net_sprint_ipv4_addr(&netmask)); break; diff --git a/subsys/net/lib/dhcpv4/dhcpv4_server.c b/subsys/net/lib/dhcpv4/dhcpv4_server.c index 4b232323a78..49ffe012834 100644 --- a/subsys/net/lib/dhcpv4/dhcpv4_server.c +++ b/subsys/net/lib/dhcpv4/dhcpv4_server.c @@ -1466,7 +1466,7 @@ int net_dhcpv4_server_start(struct net_if *iface, struct in_addr *base_addr) return -EINVAL; } - netmask = net_if_ipv4_get_netmask(iface); + netmask = net_if_ipv4_get_netmask_by_addr(iface, server_addr); if (net_ipv4_is_addr_unspecified(&netmask)) { LOG_ERR("Failed to obtain subnet mask."); return -EINVAL; diff --git a/subsys/net/lib/shell/iface.c b/subsys/net/lib/shell/iface.c index fb0ed4e00fd..b238846ba19 100644 --- a/subsys/net/lib/shell/iface.c +++ b/subsys/net/lib/shell/iface.c @@ -437,14 +437,16 @@ skip_ipv6: PR("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]; + unicast = &ipv4->unicast[i].ipv4; if (!unicast->is_used) { continue; } - PR("\t%s %s %s%s\n", + PR("\t%s/%s %s %s%s\n", net_sprint_ipv4_addr(&unicast->address.in_addr), + net_sprint_ipv4_addr(&ipv4->unicast[i].netmask), + addrtype2str(unicast->addr_type), addrstate2str(unicast->addr_state), unicast->is_infinite ? " infinite" : ""); @@ -480,8 +482,6 @@ skip_ipv4: if (ipv4) { PR("IPv4 gateway : %s\n", net_sprint_ipv4_addr(&ipv4->gw)); - PR("IPv4 netmask : %s\n", - net_sprint_ipv4_addr(&ipv4->netmask)); } #endif /* CONFIG_NET_IPV4 */ diff --git a/subsys/net/lib/shell/ipv4.c b/subsys/net/lib/shell/ipv4.c index b23b691ed69..f5c6ea71734 100644 --- a/subsys/net/lib/shell/ipv4.c +++ b/subsys/net/lib/shell/ipv4.c @@ -36,18 +36,18 @@ static void ip_address_lifetime_cb(struct net_if *iface, void *user_data) PR("Type \tState \tLifetime (sec)\tAddress\n"); for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { - if (!ipv4->unicast[i].is_used || - ipv4->unicast[i].address.family != AF_INET) { + if (!ipv4->unicast[i].ipv4.is_used || + ipv4->unicast[i].ipv4.address.family != AF_INET) { continue; } PR("%s \t%s \t%12s/%12s\n", - addrtype2str(ipv4->unicast[i].addr_type), - addrstate2str(ipv4->unicast[i].addr_state), + addrtype2str(ipv4->unicast[i].ipv4.addr_type), + addrstate2str(ipv4->unicast[i].ipv4.addr_state), net_sprint_ipv4_addr( - &ipv4->unicast[i].address.in_addr), + &ipv4->unicast[i].ipv4.address.in_addr), net_sprint_ipv4_addr( - &ipv4->netmask)); + &ipv4->unicast[i].netmask)); } } #endif /* CONFIG_NET_NATIVE_IPV4 */ @@ -126,6 +126,7 @@ static int cmd_net_ip_add(const struct shell *sh, size_t argc, char *argv[]) } } else { struct net_if_addr *ifaddr; + struct in_addr netmask; if (argc < 4) { PR_ERROR("Netmask is missing.\n"); @@ -139,12 +140,12 @@ static int cmd_net_ip_add(const struct shell *sh, size_t argc, char *argv[]) return -ENOMEM; } - if (net_addr_pton(AF_INET, argv[3], &addr)) { + if (net_addr_pton(AF_INET, argv[3], &netmask)) { PR_ERROR("Invalid netmask: %s", argv[3]); return -EINVAL; } - net_if_ipv4_set_netmask(iface, &addr); + net_if_ipv4_set_netmask_by_addr(iface, &addr, &netmask); } #else /* CONFIG_NET_NATIVE_IPV4 */ diff --git a/subsys/net/lib/shell/tcp.c b/subsys/net/lib/shell/tcp.c index e2839af36ba..300f0f3fa52 100644 --- a/subsys/net/lib/shell/tcp.c +++ b/subsys/net/lib/shell/tcp.c @@ -51,7 +51,7 @@ static void get_my_ipv4_addr(struct net_if *iface, #if defined(CONFIG_NET_NATIVE_IPV4) /* 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].ipv4.address.in_addr, sizeof(struct in_addr)); net_sin(myaddr)->sin_port = 0U; /* let the IP stack to select */