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 <jukka.rissanen@nordicsemi.no>
This commit is contained in:
Jukka Rissanen 2024-01-31 17:39:44 +02:00 committed by Carles Cufí
parent 2e2cfb063d
commit 1b0f9e865e
11 changed files with 289 additions and 74 deletions

View File

@ -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.
*

View File

@ -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;
}

View File

@ -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 <syscalls/net_if_ipv4_addr_lookup_by_index_mrsh.c>
#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 <syscalls/net_if_ipv4_set_netmask_by_index_mrsh.c>
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 <syscalls/net_if_ipv4_set_netmask_by_addr_by_index_mrsh.c>
#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;

View File

@ -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;
}
}

View File

@ -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 {

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */