From d53b4ada63773ef1f4c45d31b5b280fd8ed094a8 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Sun, 15 Dec 2024 15:57:05 +1000 Subject: [PATCH 1/2] nrf_modem_lib: lte_net_if: query actual link MTU Update the network interface MTU before raising the connectivity event, so that the MTU as queried by downstream users is correct, instead of an assumed value based on IPv6 required minimums. Signed-off-by: Jordan Yates --- .../releases/release-notes-changelog.rst | 2 ++ lib/nrf_modem_lib/lte_net_if/lte_net_if.c | 18 +++++++++++++++++- lib/nrf_modem_lib/nrf9x_sockets.c | 2 +- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst index 7ff5b78a6829..bcb6d782f5a9 100644 --- a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst +++ b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst @@ -492,6 +492,8 @@ Modem libraries * Fixed an issue with the :c:func:`modem_key_mgmt_clear` function where it returned ``-ENOENT`` when the credential was cleared. +* Updated the :ref:`nrf_modem_lib_lte_net_if` to automatically set the actual link :term:`Maximum Transmission Unit (MTU)` on the network interface when PDN connectivity is gained. + Multiprotocol Service Layer libraries ------------------------------------- diff --git a/lib/nrf_modem_lib/lte_net_if/lte_net_if.c b/lib/nrf_modem_lib/lte_net_if/lte_net_if.c index 15476b1a400b..ec237779e83b 100644 --- a/lib/nrf_modem_lib/lte_net_if/lte_net_if.c +++ b/lib/nrf_modem_lib/lte_net_if/lte_net_if.c @@ -60,13 +60,29 @@ void lte_net_if_modem_fault_handler(void) net_if_dormant_on(iface_bound); } +static uint16_t pdn_mtu(void) +{ + struct pdn_dynamic_info info; + int rc; + + rc = pdn_dynamic_info_get(0, &info); + if ((rc != 0) || (info.ipv4_mtu == 0)) { + LOG_WRN("MTU query failed, error: %d, MTU: %d", rc, info.ipv4_mtu); + /* Fallback to the minimum value that IPv4 is required to support */ + info.ipv4_mtu = NET_IPV4_MTU; + } + LOG_DBG("Network MTU: %d", info.ipv4_mtu); + return info.ipv4_mtu; +} + /* Called when we detect LTE connectivity has been gained. * - * Marks the iface as active and cancels any pending timeout. + * Queries the network MTU, marks the iface as active, and cancels any pending timeout. */ static void become_active(void) { LOG_DBG("Becoming active"); + net_if_set_mtu(iface_bound, pdn_mtu()); net_if_dormant_off(iface_bound); k_work_cancel_delayable(&connection_timeout_work); } diff --git a/lib/nrf_modem_lib/nrf9x_sockets.c b/lib/nrf_modem_lib/nrf9x_sockets.c index a593b22222f0..da8c84266366 100644 --- a/lib/nrf_modem_lib/nrf9x_sockets.c +++ b/lib/nrf_modem_lib/nrf9x_sockets.c @@ -1168,7 +1168,7 @@ static struct offloaded_if_api nrf9x_iface_offload_api = { .enable = nrf9x_iface_enable, }; -/* TODO Get the actual MTU for the nRF9x LTE link. */ +/* Actual MTU for the nRF9x LTE link is handled by `lte_net_if.c` */ NET_DEVICE_OFFLOAD_INIT(nrf9x_socket, "nrf9x_socket", nrf9x_socket_offload_init, NULL, From 7e92493a1dfb83a1f84aef90c97eaf55473d11d4 Mon Sep 17 00:00:00 2001 From: Jordan Yates Date: Thu, 19 Dec 2024 09:51:30 +1000 Subject: [PATCH 2/2] tests: nrf_modem_lib: lte_net_if: test MTU behaviour Test the behaviour of the network interface under the three conditions: 1. MTU successfully queried 2. Function reports success but MTU not set 3. Function reports error Signed-off-by: Jordan Yates --- tests/lib/nrf_modem_lib/lte_net_if/src/main.c | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/lib/nrf_modem_lib/lte_net_if/src/main.c b/tests/lib/nrf_modem_lib/lte_net_if/src/main.c index 89c90ea1fe55..463b6d0bdc0a 100644 --- a/tests/lib/nrf_modem_lib/lte_net_if/src/main.c +++ b/tests/lib/nrf_modem_lib/lte_net_if/src/main.c @@ -44,6 +44,14 @@ static void lte_lc_register_handler_stub(lte_lc_evt_handler_t cb, int num_of_cal lte_lc_event_handler_callback = cb; } +/* Stub used to report a non-default link MTU */ +static int pdn_dynamic_info_get_1000_stub(uint32_t cid, struct pdn_dynamic_info *pdn_info, + int num_of_calls) +{ + pdn_info->ipv4_mtu = 1000; + return 0; +} + static void bring_network_interface_up(void) { struct net_if *net_if = net_if_get_default(); @@ -442,11 +450,17 @@ void test_pdn_act_with_cereg_should_activate_iface(void) "AT+CGPADDR=0", "+CGPADDR: %*d,\"%46[.:0-9A-F]\",\"%46[:0-9A-F]\"", 1); __mock_nrf_modem_at_scanf_ReturnVarg_string("192.9.201.39"); + /* Netowrk MTU is 1000 */ + __cmock_pdn_dynamic_info_get_Stub(&pdn_dynamic_info_get_1000_stub); + /* Fire PDN active */ pdn_event_handler_callback(0, PDN_EVENT_ACTIVATED, 0); /* Check that iface becomes active */ TEST_ASSERT_FALSE(net_if_is_dormant(net_if)); + + /* MTU should have been set to reported value */ + TEST_ASSERT_EQUAL(1000, net_if_get_mtu(net_if)); } @@ -504,6 +518,9 @@ void test_cereg_registered_home_with_pdn_should_activate_iface(void) "AT+CGPADDR=0", "+CGPADDR: %*d,\"%46[.:0-9A-F]\",\"%46[:0-9A-F]\"", 1); __mock_nrf_modem_at_scanf_ReturnVarg_string("192.9.201.39"); + /* MTU query fails */ + __cmock_pdn_dynamic_info_get_IgnoreAndReturn(-1); + /* Fire PDN active */ pdn_event_handler_callback(0, PDN_EVENT_ACTIVATED, 0); @@ -516,6 +533,9 @@ void test_cereg_registered_home_with_pdn_should_activate_iface(void) /* Check that iface becomes active */ TEST_ASSERT_FALSE(net_if_is_dormant(net_if)); + + /* MTU should have reverted to default minimum */ + TEST_ASSERT_EQUAL(NET_IPV4_MTU, net_if_get_mtu(net_if)); } /* Verify that CEREG registration (roaming) does activate iface if PDN is active */ @@ -542,6 +562,9 @@ void test_cereg_registered_roaming_with_pdn_should_activate_iface(void) "AT+CGPADDR=0", "+CGPADDR: %*d,\"%46[.:0-9A-F]\",\"%46[:0-9A-F]\"", 1); __mock_nrf_modem_at_scanf_ReturnVarg_string("192.9.201.39"); + /* MTU not set by function */ + __cmock_pdn_dynamic_info_get_IgnoreAndReturn(0); + /* Fire PDN active */ pdn_event_handler_callback(0, PDN_EVENT_ACTIVATED, 0); @@ -554,6 +577,9 @@ void test_cereg_registered_roaming_with_pdn_should_activate_iface(void) /* Check that iface becomes active */ TEST_ASSERT_FALSE(net_if_is_dormant(net_if)); + + /* MTU should have reverted to default minimum */ + TEST_ASSERT_EQUAL(NET_IPV4_MTU, net_if_get_mtu(net_if)); } /* Verify that CEREG searching does not affect iface activation (from inactive to active) */ @@ -602,6 +628,7 @@ void test_cereg_searching_should_not_deactivate_iface(void) */ __cmock_nrf_modem_is_initialized_IgnoreAndReturn(1); __cmock_lte_lc_func_mode_set_IgnoreAndReturn(0); + __cmock_pdn_dynamic_info_get_IgnoreAndReturn(0); /* Take the iface admin-up */ net_if_up(net_if); @@ -644,6 +671,7 @@ void test_cereg_unregistered_should_deactivate_iface(void) */ __cmock_nrf_modem_is_initialized_IgnoreAndReturn(1); __cmock_lte_lc_func_mode_set_IgnoreAndReturn(0); + __cmock_pdn_dynamic_info_get_IgnoreAndReturn(0); /* Take the iface admin-up */ net_if_up(net_if); @@ -686,6 +714,7 @@ void test_pdn_deact_should_deactivate_iface(void) */ __cmock_nrf_modem_is_initialized_IgnoreAndReturn(1); __cmock_lte_lc_func_mode_set_IgnoreAndReturn(0); + __cmock_pdn_dynamic_info_get_IgnoreAndReturn(0); /* Take the iface admin-up */ net_if_up(net_if);