net: pmtu: Send net_mgmt event for changed path MTU

Send a network management event for a changed path MTU value.
Both IPv4 and IPv6 have their own events as we cannot mix these
because how the network event numbering space is implemented.

Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
This commit is contained in:
Jukka Rissanen 2024-11-06 14:27:28 +02:00 committed by Anas Nashif
parent 55e582635f
commit 02ccb0e523
3 changed files with 82 additions and 2 deletions

View file

@ -74,6 +74,7 @@ enum net_event_ipv6_cmd {
NET_EVENT_IPV6_CMD_PE_DISABLED,
NET_EVENT_IPV6_CMD_PE_FILTER_ADD,
NET_EVENT_IPV6_CMD_PE_FILTER_DEL,
NET_EVENT_IPV6_CMD_PMTU_CHANGED,
};
/* IPv4 Events*/
@ -99,6 +100,7 @@ enum net_event_ipv4_cmd {
NET_EVENT_IPV4_CMD_ACD_SUCCEED,
NET_EVENT_IPV4_CMD_ACD_FAILED,
NET_EVENT_IPV4_CMD_ACD_CONFLICT,
NET_EVENT_IPV4_CMD_PMTU_CHANGED,
};
/* L4 network events */
@ -237,6 +239,10 @@ enum net_event_l4_cmd {
#define NET_EVENT_IPV6_PE_FILTER_DEL \
(_NET_EVENT_IPV6_BASE | NET_EVENT_IPV6_CMD_PE_FILTER_DEL)
/** IPv6 Path MTU is changed. */
#define NET_EVENT_IPV6_PMTU_CHANGED \
(_NET_EVENT_IPV6_BASE | NET_EVENT_IPV6_CMD_PMTU_CHANGED)
/** Event emitted when an IPv4 address is added to the system. */
#define NET_EVENT_IPV4_ADDR_ADD \
(_NET_EVENT_IPV4_BASE | NET_EVENT_IPV4_CMD_ADDR_ADD)
@ -296,6 +302,10 @@ enum net_event_l4_cmd {
#define NET_EVENT_IPV4_ACD_CONFLICT \
(_NET_EVENT_IPV4_BASE | NET_EVENT_IPV4_CMD_ACD_CONFLICT)
/** IPv4 Path MTU is changed. */
#define NET_EVENT_IPV4_PMTU_CHANGED \
(_NET_EVENT_IPV4_BASE | NET_EVENT_IPV4_CMD_PMTU_CHANGED)
/** Event emitted when the system is considered to be connected.
* The connected in this context means that the network interface is up,
* and the interface has either IPv4 or IPv6 address assigned to it.
@ -441,6 +451,34 @@ struct net_event_ipv6_pe_filter {
bool is_deny_list;
};
/**
* @brief Network Management event information structure
* Used to pass information on network event
* NET_EVENT_IPV4_PMTU_CHANGED
* when CONFIG_NET_MGMT_EVENT_INFO enabled and event generator pass the
* information.
*/
struct net_event_ipv4_pmtu_info {
/** IPv4 address */
struct in_addr dst;
/** New MTU */
uint16_t mtu;
};
/**
* @brief Network Management event information structure
* Used to pass information on network event
* NET_EVENT_IPV6_PMTU_CHANGED
* when CONFIG_NET_MGMT_EVENT_INFO enabled and event generator pass the
* information.
*/
struct net_event_ipv6_pmtu_info {
/** IPv6 address */
struct in6_addr dst;
/** New MTU */
uint32_t mtu;
};
#ifdef __cplusplus
}
#endif

View file

@ -50,6 +50,9 @@ config NET_NATIVE_IPV4
config NET_PMTU
bool
select NET_MGMT
select NET_MGMT_EVENT
select NET_MGMT_EVENT_INFO
default y
depends on NET_IPV6_PMTU || NET_IPV4_PMTU

View file

@ -12,7 +12,9 @@
LOG_MODULE_REGISTER(net_pmtu, CONFIG_NET_PMTU_LOG_LEVEL);
#include <zephyr/kernel.h>
#include <zephyr/net/net_event.h>
#include <zephyr/net/net_mgmt.h>
#include <zephyr/net/net_if.h>
#include "pmtu.h"
#if defined(CONFIG_NET_IPV4_PMTU)
@ -104,8 +106,45 @@ out:
static void update_pmtu_entry(struct net_pmtu_entry *entry, uint16_t mtu)
{
bool changed = false;
if (entry->mtu != mtu) {
changed = true;
entry->mtu = mtu;
}
entry->last_update = k_uptime_get_32();
if (changed) {
struct net_if *iface;
if (IS_ENABLED(CONFIG_NET_IPV4_PMTU) && entry->dst.family == AF_INET) {
struct net_event_ipv4_pmtu_info info;
net_ipaddr_copy(&info.dst, &entry->dst.in_addr);
info.mtu = mtu;
iface = net_if_ipv4_select_src_iface(&info.dst);
net_mgmt_event_notify_with_info(NET_EVENT_IPV4_PMTU_CHANGED,
iface,
(const void *)&info,
sizeof(struct net_event_ipv4_pmtu_info));
} else if (IS_ENABLED(CONFIG_NET_IPV6_PMTU) && entry->dst.family == AF_INET6) {
struct net_event_ipv6_pmtu_info info;
net_ipaddr_copy(&info.dst, &entry->dst.in6_addr);
info.mtu = mtu;
iface = net_if_ipv6_select_src_iface(&info.dst);
net_mgmt_event_notify_with_info(NET_EVENT_IPV6_PMTU_CHANGED,
iface,
(const void *)&info,
sizeof(struct net_event_ipv6_pmtu_info));
}
}
}
struct net_pmtu_entry *net_pmtu_get_entry(const struct sockaddr *dst)