Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nrf_modem_lib: lte_net_if: query actual link MTU #19537

Merged
merged 2 commits into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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
-------------------------------------

Expand Down
18 changes: 17 additions & 1 deletion lib/nrf_modem_lib/lte_net_if/lte_net_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/nrf_modem_lib/nrf9x_sockets.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
29 changes: 29 additions & 0 deletions tests/lib/nrf_modem_lib/lte_net_if/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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));
}


Expand Down Expand Up @@ -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);

Expand All @@ -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 */
Expand All @@ -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);

Expand All @@ -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) */
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down