Skip to content

Commit d36c0be

Browse files
FacepalmMutekartben
authored andcommitted
net: l2: ppp: Add support for LCP MRU negotiation
Previously, the LCP MRU option sent by the peer was ignored. This could result in the interface MTU remaining at the default (1500), even if the peer requested a smaller MRU, potentially leading to packet loss. This commit adds parsing for the peer's MRU option and updates the network interface MTU accordingly. Signed-off-by: Nik Schewtschuk <[email protected]>
1 parent 614dd57 commit d36c0be

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

subsys/net/l2/ppp/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ config NET_L2_PPP_OPTION_MRU
6060
help
6161
Enable support for LCP MRU option.
6262

63+
config NET_L2_PPP_OPTION_MAX_MRU
64+
int "LCP MRU maximum size"
65+
default 1500
66+
help
67+
Set the maximal MRU size which is allowed while negotiation with peer over LCP.
68+
The default value is defined by RFC 1661.
69+
6370
config NET_L2_PPP_OPTION_SERVE_IP
6471
bool "Serve IP address to peer"
6572
help

subsys/net/l2/ppp/lcp.c

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ struct lcp_option_data {
6161
bool auth_proto_present;
6262
uint32_t async_ctrl_char_map;
6363
uint16_t auth_proto;
64+
uint16_t mru;
6465
};
6566

6667
static const enum ppp_protocol_type lcp_supported_auth_protos[] = {
@@ -121,11 +122,49 @@ static int lcp_async_ctrl_char_map_parse(struct ppp_fsm *fsm, struct net_pkt *pk
121122
return 0;
122123
}
123124

125+
static int lcp_peer_mru_parse(struct ppp_fsm *fsm, struct net_pkt *pkt,
126+
void *user_data)
127+
{
128+
struct lcp_option_data *data = user_data;
129+
uint16_t peer_mru;
130+
int ret;
131+
132+
ret = net_pkt_read_be16(pkt, &peer_mru);
133+
if (ret < 0) {
134+
/* Should not happen, is the pkt corrupt? */
135+
return -EMSGSIZE;
136+
}
137+
138+
NET_DBG("[LCP] Received peer MRU %u", peer_mru);
139+
140+
if (peer_mru > CONFIG_NET_L2_PPP_OPTION_MAX_MRU) {
141+
LOG_WRN("[LCP] Received peer MRU is too big. %u > %u.",
142+
peer_mru, CONFIG_NET_L2_PPP_OPTION_MAX_MRU);
143+
return -EINVAL;
144+
}
145+
146+
data->mru = peer_mru;
147+
148+
return 0;
149+
}
150+
151+
static int lcp_peer_mru_nack(struct ppp_fsm *fsm, struct net_pkt *ret_pkt,
152+
void *user_data)
153+
{
154+
struct ppp_context *ctx = ppp_fsm_ctx(fsm);
155+
156+
(void)net_pkt_write_u8(ret_pkt, LCP_OPTION_MRU);
157+
(void)net_pkt_write_u8(ret_pkt, 4);
158+
return net_pkt_write_be16(ret_pkt, ctx->lcp.my_options.mru);
159+
}
160+
124161
static const struct ppp_peer_option_info lcp_peer_options[] = {
125162
PPP_PEER_OPTION(LCP_OPTION_AUTH_PROTO, lcp_auth_proto_parse,
126163
lcp_auth_proto_nack),
127164
PPP_PEER_OPTION(LCP_OPTION_ASYNC_CTRL_CHAR_MAP, lcp_async_ctrl_char_map_parse,
128165
NULL),
166+
PPP_PEER_OPTION(LCP_OPTION_MRU, lcp_peer_mru_parse,
167+
lcp_peer_mru_nack),
129168
};
130169

131170
static int lcp_config_info_req(struct ppp_fsm *fsm,
@@ -220,7 +259,11 @@ static void lcp_up(struct ppp_fsm *fsm)
220259
struct ppp_context *ctx = CONTAINER_OF(fsm, struct ppp_context,
221260
lcp.fsm);
222261

223-
/* TODO: Set MRU/MTU of the network interface here */
262+
if (ctx->lcp.peer_options.mru > 0) {
263+
NET_DBG("Set MTU size from peer options: %u -> %u",
264+
net_if_get_mtu(ctx->iface), ctx->lcp.peer_options.mru);
265+
net_if_set_mtu(ctx->iface, ctx->lcp.peer_options.mru);
266+
}
224267

225268
ppp_link_established(ctx, fsm);
226269
}

0 commit comments

Comments
 (0)