From: Denis Kenzior <denkenz@gmail.com>
To: ofono@lists.linux.dev
Cc: Denis Kenzior <denkenz@gmail.com>
Subject: [PATCH 2/4] rmnet: Default created interfaces to MTU of 1400
Date: Tue, 26 Nov 2024 15:26:16 -0600 [thread overview]
Message-ID: <20241126212703.196003-2-denkenz@gmail.com> (raw)
In-Reply-To: <20241126212703.196003-1-denkenz@gmail.com>
By default the network interface is being created with 16380 byte MTU,
which is excessive for cellular links. Typically, cellular links use a
maximum MTU of around 1430. Set the MTU to something more reasonable by
default.
Unfortunately, the kernel does not support setting the MTU value in the
original NEWLINK message. It must be set separately in a different
transaction. Add support for this and make sure that cancellation logic
still works.
---
src/rmnet.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 68 insertions(+), 9 deletions(-)
diff --git a/src/rmnet.c b/src/rmnet.c
index 83110c33a980..2c000fc33c3c 100644
--- a/src/rmnet.c
+++ b/src/rmnet.c
@@ -25,6 +25,7 @@
#define RMNET_TYPE "rmnet"
#define MAX_MUX_IDS 254U
+#define DEFAULT_MTU 1400U
struct rmnet_request {
uint32_t parent_ifindex;
@@ -195,19 +196,16 @@ next_request:
rmnet_start_next_request();
}
-static void rmnet_new_link_cb(int error, uint16_t type, const void *data,
+static void rmnet_set_mtu_cb(int error, uint16_t type, const void *data,
uint32_t len, void *user_data)
{
struct rmnet_request *req = l_queue_peek_head(request_q);
- DBG("NEWLINK %u (%u/%u) complete, error: %d",
- req->netlink_id, req->current + 1, req->n_interfaces, error);
+ DBG("%u (%u/%u) complete, error: %d",
+ req->netlink_id, req->current, req->n_interfaces, error);
req->netlink_id = 0;
- if (!error)
- req->current += 1;
-
if (error || req->canceled) {
__rmnet_cancel_request();
req->n_interfaces = 0;
@@ -229,6 +227,49 @@ next_request:
rmnet_start_next_request();
}
+static void rmnet_new_link_cb(int error, uint16_t type, const void *data,
+ uint32_t len, void *user_data)
+{
+ struct rmnet_request *req = l_queue_peek_head(request_q);
+ uint32_t ifindex = req->infos[req->current].ifindex;
+
+ DBG("NEWLINK %u (%u/%u) complete, error: %d",
+ req->netlink_id, req->current + 1, req->n_interfaces, error);
+
+ req->netlink_id = 0;
+
+ if (!error)
+ req->current += 1;
+
+ if (error || req->canceled)
+ goto error;
+
+ /*
+ * Unfortunately the kernel does not take IFLA_MTU into account
+ * when creating new RMNet links, so this must be done as a separate
+ * step. Hopefully this is fixed one day
+ */
+ error = -EIO;
+ req->netlink_id = l_rtnl_link_set_mtu(rtnl, ifindex, DEFAULT_MTU,
+ rmnet_set_mtu_cb, NULL, NULL);
+ if (req->netlink_id) {
+ DBG("Set MTU: interface: %u/%u, request: %u",
+ req->current, req->n_interfaces, req->netlink_id);
+ return;
+ }
+error:
+ __rmnet_cancel_request();
+ req->n_interfaces = 0;
+ l_queue_pop_head(request_q);
+
+ if (req->new_cb)
+ req->new_cb(error, req->n_interfaces,
+ req->n_interfaces ? req->infos : NULL,
+ req->user_data);
+
+ rmnet_request_free(req);
+}
+
static void rmnet_start_next_request(void)
{
struct rmnet_request *req = l_queue_peek_head(request_q);
@@ -429,6 +470,7 @@ static int rmnet_parse_link(const void *data, uint32_t len,
bool have_linkinfo = false;
const char *ifname = NULL;
uint16_t ifnamelen = 0;
+ uint32_t mtu = 0;
uint16_t rta_type;
uint16_t rta_len;
const void *rta_data;
@@ -450,10 +492,16 @@ static int rmnet_parse_link(const void *data, uint32_t len,
have_linkinfo = true;
break;
+ case IFLA_MTU:
+ if (rta_len != sizeof(uint32_t))
+ return -EBADMSG;
+
+ mtu = l_get_u32(rta_data);
+ break;
}
}
- if (!have_linkinfo || !ifname || !ifnamelen)
+ if (!have_linkinfo || !ifname || !ifnamelen || !mtu)
return -ENOENT;
r = rmnet_parse_info_data(&linkinfo, out_mux_id);
@@ -466,6 +514,8 @@ static int rmnet_parse_link(const void *data, uint32_t len,
if (out_ifindex)
*out_ifindex = ifa->ifa_index;
+ l_info("MTU: %u", mtu);
+
return 0;
}
@@ -530,14 +580,23 @@ static void update_new_link_ifindex(uint16_t mux_id,
{
struct rmnet_request *req;
struct rmnet_ifinfo *info;
+ unsigned int i;
req = l_queue_peek_head(request_q);
if (!req || req->request_type != RTM_NEWLINK)
return;
- info = req->infos + req->current;
- if (info->mux_id == mux_id && !strcmp(info->ifname, ifname))
+ for (i = 0; i < req->n_interfaces; i++) {
+ info = req->infos + i;
+
+ if (info->mux_id != mux_id)
+ continue;
+
+ if (strcmp(info->ifname, ifname))
+ continue;
+
info->ifindex = ifindex;
+ }
}
static void rmnet_link_notification(uint16_t type, const void *data,
--
2.47.0
next prev parent reply other threads:[~2024-11-26 21:27 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-26 21:26 [PATCH 1/4] provision: Add 311 270 MCC/MNC as Verizon Denis Kenzior
2024-11-26 21:26 ` Denis Kenzior [this message]
2024-11-26 21:26 ` [PATCH 3/4] qrtrqmi: Add multiple bearer support Denis Kenzior
2024-11-26 21:26 ` [PATCH 4/4] qrtrqmi: Manage main netdev as part of .set_online Denis Kenzior
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20241126212703.196003-2-denkenz@gmail.com \
--to=denkenz@gmail.com \
--cc=ofono@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox