Skip to content

Commit 348e7d7

Browse files
committed
Added APIs to set/get interface mtu
1 parent eb683d7 commit 348e7d7

4 files changed

Lines changed: 147 additions & 0 deletions

File tree

docs/API.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,11 @@ Per-interface versions of the IP configuration helpers. The legacy functions tar
204204
```c
205205
struct wolfIP_ll_dev *wolfIP_getdev(struct wolfIP *s);
206206
struct wolfIP_ll_dev *wolfIP_getdev_ex(struct wolfIP *s, unsigned int if_idx);
207+
int wolfIP_mtu_set(struct wolfIP *s, unsigned int if_idx, uint32_t mtu);
208+
int wolfIP_mtu_get(struct wolfIP *s, unsigned int if_idx, uint32_t *mtu);
207209
```
208210
Access the link-layer descriptor(s) that should be wired to hardware drivers. `_ex` returns `NULL` if `if_idx` exceeds `WOLFIP_MAX_INTERFACES`.
211+
`wolfIP_mtu_set()` updates the effective per-interface MTU, treating `0` as the default `LINK_MTU` and clamping to `[LINK_MTU_MIN, LINK_MTU]`. `wolfIP_mtu_get()` returns the effective MTU currently used by the stack.
209212
210213
## DHCP Client Functions
211214

src/test/unit/unit.c

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1565,6 +1565,45 @@ START_TEST(test_udp_sendto_and_recvfrom)
15651565
}
15661566
END_TEST
15671567

1568+
START_TEST(test_udp_sendto_respects_mtu_api)
1569+
{
1570+
struct wolfIP s;
1571+
int sd;
1572+
struct wolfIP_sockaddr_in sin;
1573+
uint8_t small_payload[38] = {0};
1574+
uint8_t large_payload[39] = {0};
1575+
struct tsocket *ts;
1576+
uint32_t mtu = 0;
1577+
1578+
wolfIP_init(&s);
1579+
mock_link_init(&s);
1580+
wolfIP_ipconfig_set(&s, 0x0A000001U, 0xFFFFFF00U, 0);
1581+
1582+
ck_assert_int_eq(wolfIP_mtu_set(&s, TEST_PRIMARY_IF, 80U), 0);
1583+
ck_assert_int_eq(wolfIP_mtu_get(&s, TEST_PRIMARY_IF, &mtu), 0);
1584+
ck_assert_uint_eq(mtu, 80U);
1585+
1586+
sd = wolfIP_sock_socket(&s, AF_INET, IPSTACK_SOCK_DGRAM, WI_IPPROTO_UDP);
1587+
ck_assert_int_gt(sd, 0);
1588+
ts = &s.udpsockets[SOCKET_UNMARK(sd)];
1589+
fifo_init(&ts->sock.udp.txbuf, ts->txmem, TXBUF_SIZE);
1590+
1591+
memset(&sin, 0, sizeof(sin));
1592+
sin.sin_family = AF_INET;
1593+
sin.sin_port = ee16(5000);
1594+
sin.sin_addr.s_addr = ee32(0x0A000002U);
1595+
1596+
ck_assert_int_eq(wolfIP_sock_sendto(&s, sd, small_payload, sizeof(small_payload), 0,
1597+
(struct wolfIP_sockaddr *)&sin, sizeof(sin)), (int)sizeof(small_payload));
1598+
ck_assert_ptr_nonnull(fifo_peek(&ts->sock.udp.txbuf));
1599+
1600+
fifo_init(&ts->sock.udp.txbuf, ts->txmem, TXBUF_SIZE);
1601+
ck_assert_int_eq(wolfIP_sock_sendto(&s, sd, large_payload, sizeof(large_payload), 0,
1602+
(struct wolfIP_sockaddr *)&sin, sizeof(sin)), -1);
1603+
ck_assert_ptr_null(fifo_peek(&ts->sock.udp.txbuf));
1604+
}
1605+
END_TEST
1606+
15681607
START_TEST(test_udp_recvfrom_sets_remote_ip)
15691608
{
15701609
struct wolfIP s;
@@ -17375,6 +17414,38 @@ START_TEST(test_wolfip_ll_frame_mtu_enforces_minimum)
1737517414
}
1737617415
END_TEST
1737717416

17417+
START_TEST(test_wolfip_mtu_set_get_api)
17418+
{
17419+
struct wolfIP s;
17420+
uint32_t mtu = 0;
17421+
17422+
wolfIP_init(&s);
17423+
mock_link_init(&s);
17424+
17425+
ck_assert_int_eq(wolfIP_mtu_set(NULL, TEST_PRIMARY_IF, 128U), -WOLFIP_EINVAL);
17426+
ck_assert_int_eq(wolfIP_mtu_set(&s, WOLFIP_MAX_INTERFACES, 128U), -WOLFIP_EINVAL);
17427+
ck_assert_int_eq(wolfIP_mtu_get(NULL, TEST_PRIMARY_IF, &mtu), -WOLFIP_EINVAL);
17428+
ck_assert_int_eq(wolfIP_mtu_get(&s, WOLFIP_MAX_INTERFACES, &mtu), -WOLFIP_EINVAL);
17429+
ck_assert_int_eq(wolfIP_mtu_get(&s, TEST_PRIMARY_IF, NULL), -WOLFIP_EINVAL);
17430+
17431+
ck_assert_int_eq(wolfIP_mtu_set(&s, TEST_PRIMARY_IF, 256U), 0);
17432+
ck_assert_int_eq(wolfIP_mtu_get(&s, TEST_PRIMARY_IF, &mtu), 0);
17433+
ck_assert_uint_eq(mtu, 256U);
17434+
17435+
ck_assert_int_eq(wolfIP_mtu_set(&s, TEST_PRIMARY_IF, LINK_MTU_MIN - 1U), 0);
17436+
ck_assert_int_eq(wolfIP_mtu_get(&s, TEST_PRIMARY_IF, &mtu), 0);
17437+
ck_assert_uint_eq(mtu, LINK_MTU_MIN);
17438+
17439+
ck_assert_int_eq(wolfIP_mtu_set(&s, TEST_PRIMARY_IF, LINK_MTU + 1U), 0);
17440+
ck_assert_int_eq(wolfIP_mtu_get(&s, TEST_PRIMARY_IF, &mtu), 0);
17441+
ck_assert_uint_eq(mtu, LINK_MTU);
17442+
17443+
ck_assert_int_eq(wolfIP_mtu_set(&s, TEST_PRIMARY_IF, 0), 0);
17444+
ck_assert_int_eq(wolfIP_mtu_get(&s, TEST_PRIMARY_IF, &mtu), 0);
17445+
ck_assert_uint_eq(mtu, LINK_MTU);
17446+
}
17447+
END_TEST
17448+
1737817449
START_TEST(test_ip_is_local_conf_variants)
1737917450
{
1738017451
struct ipconf conf;
@@ -18439,6 +18510,47 @@ START_TEST(test_icmp_sendto_respects_bound_local_ip_interface)
1843918510
}
1844018511
END_TEST
1844118512

18513+
START_TEST(test_icmp_sendto_respects_mtu_api)
18514+
{
18515+
struct wolfIP s;
18516+
int sd;
18517+
struct wolfIP_sockaddr_in sin;
18518+
uint8_t small_payload[30] = {0};
18519+
uint8_t large_payload[31] = {0};
18520+
struct tsocket *ts;
18521+
uint32_t mtu = 0;
18522+
18523+
wolfIP_init(&s);
18524+
mock_link_init(&s);
18525+
wolfIP_ipconfig_set(&s, 0x0A000001U, 0xFFFFFF00U, 0);
18526+
18527+
ck_assert_int_eq(wolfIP_mtu_set(&s, TEST_PRIMARY_IF, 64U), 0);
18528+
ck_assert_int_eq(wolfIP_mtu_get(&s, TEST_PRIMARY_IF, &mtu), 0);
18529+
ck_assert_uint_eq(mtu, 64U);
18530+
18531+
sd = wolfIP_sock_socket(&s, AF_INET, IPSTACK_SOCK_DGRAM, WI_IPPROTO_ICMP);
18532+
ck_assert_int_gt(sd, 0);
18533+
ts = &s.icmpsockets[SOCKET_UNMARK(sd)];
18534+
fifo_init(&ts->sock.udp.txbuf, ts->txmem, TXBUF_SIZE);
18535+
18536+
memset(&sin, 0, sizeof(sin));
18537+
sin.sin_family = AF_INET;
18538+
sin.sin_addr.s_addr = ee32(0x0A000002U);
18539+
18540+
small_payload[0] = ICMP_ECHO_REQUEST;
18541+
large_payload[0] = ICMP_ECHO_REQUEST;
18542+
18543+
ck_assert_int_eq(wolfIP_sock_sendto(&s, sd, small_payload, sizeof(small_payload), 0,
18544+
(struct wolfIP_sockaddr *)&sin, sizeof(sin)), (int)sizeof(small_payload));
18545+
ck_assert_ptr_nonnull(fifo_peek(&ts->sock.udp.txbuf));
18546+
18547+
fifo_init(&ts->sock.udp.txbuf, ts->txmem, TXBUF_SIZE);
18548+
ck_assert_int_eq(wolfIP_sock_sendto(&s, sd, large_payload, sizeof(large_payload), 0,
18549+
(struct wolfIP_sockaddr *)&sin, sizeof(sin)), -WOLFIP_EINVAL);
18550+
ck_assert_ptr_null(fifo_peek(&ts->sock.udp.txbuf));
18551+
}
18552+
END_TEST
18553+
1844218554
START_TEST(test_regression_snd_una_initialized_on_syn_rcvd)
1844318555
{
1844418556
struct wolfIP s;
@@ -18876,6 +18988,7 @@ Suite *wolf_suite(void)
1887618988
tcase_add_test(tc_utils, test_is_timer_expired_skips_zero_head);
1887718989
tcase_add_test(tc_utils, test_wolfip_getdev_ex_api);
1887818990
tcase_add_test(tc_utils, test_wolfip_ll_frame_mtu_enforces_minimum);
18991+
tcase_add_test(tc_utils, test_wolfip_mtu_set_get_api);
1887918992
tcase_add_test(tc_utils, test_wolfip_ll_at_and_ipconf_at_invalid);
1888018993
tcase_add_test(tc_utils, test_ip_is_local_conf_variants);
1888118994
#if WOLFIP_ENABLE_LOOPBACK
@@ -19217,6 +19330,7 @@ Suite *wolf_suite(void)
1921719330
tcase_add_test(tc_utils, test_tcp_build_ack_options_does_not_write_past_returned_len);
1921819331
tcase_add_test(tc_utils, test_tcp_build_ack_options_omits_ts_when_not_negotiated);
1921919332
tcase_add_test(tc_utils, test_icmp_sendto_respects_bound_local_ip_interface);
19333+
tcase_add_test(tc_utils, test_icmp_sendto_respects_mtu_api);
1922019334
tcase_add_test(tc_utils, test_tcp_sort_sack_blocks_swaps_out_of_order);
1922119335
tcase_add_test(tc_utils, test_tcp_sort_sack_blocks_wrap_order);
1922219336
tcase_add_test(tc_utils, test_tcp_merge_sack_blocks_adjacent_and_disjoint);
@@ -19376,6 +19490,7 @@ Suite *wolf_suite(void)
1937619490
tcase_add_test(tc_proto, test_icmp_input_echo_request_eth_filter_drop);
1937719491
tcase_add_test(tc_proto, test_icmp_input_filter_drop_receiving);
1937819492
tcase_add_test(tc_proto, test_udp_sendto_and_recvfrom);
19493+
tcase_add_test(tc_proto, test_udp_sendto_respects_mtu_api);
1937919494
tcase_add_test(tc_proto, test_udp_recvfrom_sets_remote_ip);
1938019495
tcase_add_test(tc_proto, test_udp_recvfrom_null_src_addr_len);
1938119496
tcase_add_test(tc_proto, test_udp_recvfrom_preserves_remote_ip);

src/wolfip.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5584,6 +5584,33 @@ struct wolfIP_ll_dev *wolfIP_getdev_ex(struct wolfIP *s, unsigned int if_idx)
55845584
return wolfIP_ll_at(s, if_idx);
55855585
}
55865586

5587+
int wolfIP_mtu_set(struct wolfIP *s, unsigned int if_idx, uint32_t mtu)
5588+
{
5589+
struct wolfIP_ll_dev *ll = wolfIP_ll_at(s, if_idx);
5590+
5591+
if (!ll)
5592+
return -WOLFIP_EINVAL;
5593+
if (mtu == 0)
5594+
ll->mtu = LINK_MTU;
5595+
else if (mtu < LINK_MTU_MIN)
5596+
ll->mtu = LINK_MTU_MIN;
5597+
else if (mtu > LINK_MTU)
5598+
ll->mtu = LINK_MTU;
5599+
else
5600+
ll->mtu = mtu;
5601+
return 0;
5602+
}
5603+
5604+
int wolfIP_mtu_get(struct wolfIP *s, unsigned int if_idx, uint32_t *mtu)
5605+
{
5606+
struct wolfIP_ll_dev *ll = wolfIP_ll_at(s, if_idx);
5607+
5608+
if (!ll || !mtu)
5609+
return -WOLFIP_EINVAL;
5610+
*mtu = wolfIP_ll_frame_mtu(ll);
5611+
return 0;
5612+
}
5613+
55875614
#ifndef WOLFIP_NOSTATIC
55885615
static struct wolfIP wolfIP_static;
55895616
void wolfIP_init_static(struct wolfIP **s)

wolfip.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,8 @@ void wolfIP_ipconfig_get(struct wolfIP *s, ip4 *ip, ip4 *mask, ip4 *gw);
254254

255255
struct wolfIP_ll_dev *wolfIP_getdev(struct wolfIP *s);
256256
struct wolfIP_ll_dev *wolfIP_getdev_ex(struct wolfIP *s, unsigned int if_idx);
257+
int wolfIP_mtu_set(struct wolfIP *s, unsigned int if_idx, uint32_t mtu);
258+
int wolfIP_mtu_get(struct wolfIP *s, unsigned int if_idx, uint32_t *mtu);
257259
void wolfIP_ipconfig_set_ex(struct wolfIP *s, unsigned int if_idx, ip4 ip, ip4 mask, ip4 gw);
258260
void wolfIP_ipconfig_get_ex(struct wolfIP *s, unsigned int if_idx, ip4 *ip, ip4 *mask, ip4 *gw);
259261

0 commit comments

Comments
 (0)