Skip to content

Commit 9a409d6

Browse files
vytvirkartben
authored andcommitted
net: l2: ppp: Explicitly negotiate ACCM
Many cellular modems attempt to negotiate an ACCM value of 0x00000000. While the PPP driver rejects this by default, it does not propose an alternative. As a result, some modems default to using 0x00000000 after LCP negotiation. Because the PPP driver expects all control characters to be escaped, this causes issues during decoding. This change negotiates an ACCM value of 0xffffffff to ensure compatibility with such modems. Signed-off-by: Vytautas Virvičius <vytautas@virvicius.dev>
1 parent b6be487 commit 9a409d6

File tree

2 files changed

+70
-6
lines changed

2 files changed

+70
-6
lines changed

include/zephyr/net/ppp.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,8 @@ struct lcp_options {
378378
};
379379

380380
#if defined(CONFIG_NET_L2_PPP_OPTION_MRU)
381+
#define LCP_NUM_MY_OPTIONS 2
382+
#else
381383
#define LCP_NUM_MY_OPTIONS 1
382384
#endif
383385

@@ -422,9 +424,9 @@ struct ppp_context {
422424

423425
/** Magic-Number value */
424426
uint32_t magic;
425-
#if defined(CONFIG_NET_L2_PPP_OPTION_MRU)
427+
428+
/** Options data */
426429
struct ppp_my_option_data my_options_data[LCP_NUM_MY_OPTIONS];
427-
#endif
428430
} lcp;
429431

430432
#if defined(CONFIG_NET_IPV4)

subsys/net/l2/ppp/lcp.c

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -268,15 +268,79 @@ static int lcp_nak_mru(struct ppp_context *ctx, struct net_pkt *pkt,
268268

269269
return 0;
270270
}
271+
#endif
272+
273+
#define ASYNC_MAP_OPTION_LEN 6
274+
275+
static int lcp_add_async_map(struct ppp_context *ctx, struct net_pkt *pkt)
276+
{
277+
net_pkt_write_u8(pkt, ASYNC_MAP_OPTION_LEN);
278+
return net_pkt_write_be32(pkt, ctx->lcp.my_options.async_map);
279+
}
280+
281+
static int lcp_ack_async_map(struct ppp_context *ctx, struct net_pkt *pkt,
282+
uint8_t oplen)
283+
{
284+
int ret;
285+
uint32_t async_map;
286+
287+
/* Handle ACK : */
288+
if (oplen != sizeof(async_map)) {
289+
return -EINVAL;
290+
}
291+
292+
ret = net_pkt_read(pkt, &async_map, sizeof(async_map));
293+
if (ret) {
294+
return ret;
295+
}
296+
if (async_map != ctx->lcp.my_options.async_map) {
297+
/* Didn't acked our ASYNC_MAP: */
298+
return -EINVAL;
299+
}
300+
301+
return 0;
302+
}
303+
304+
static int lcp_nak_async_map(struct ppp_context *ctx, struct net_pkt *pkt,
305+
uint8_t oplen)
306+
{
307+
int ret;
308+
uint16_t async_map;
309+
310+
/* Handle NAK: accept only equal to ours */
311+
if (oplen != sizeof(async_map)) {
312+
return -EINVAL;
313+
}
314+
315+
ret = net_pkt_read(pkt, &async_map, sizeof(async_map));
316+
if (ret) {
317+
return ret;
318+
}
319+
320+
if (async_map != ctx->lcp.my_options.async_map) {
321+
return -EINVAL;
322+
}
323+
324+
return 0;
325+
}
326+
271327

272328
static const struct ppp_my_option_info lcp_my_options[] = {
329+
#if defined(CONFIG_NET_L2_PPP_OPTION_MRU)
273330
PPP_MY_OPTION(LCP_OPTION_MRU, lcp_add_mru, lcp_ack_mru, lcp_nak_mru),
331+
#endif
332+
PPP_MY_OPTION(LCP_OPTION_ASYNC_CTRL_CHAR_MAP, lcp_add_async_map,
333+
lcp_ack_async_map, lcp_nak_async_map),
274334
};
275335
BUILD_ASSERT(ARRAY_SIZE(lcp_my_options) == LCP_NUM_MY_OPTIONS);
276336

277337
static struct net_pkt *lcp_config_info_add(struct ppp_fsm *fsm)
278338
{
279-
return ppp_my_options_add(fsm, MRU_OPTION_LEN);
339+
#if defined(CONFIG_NET_L2_PPP_OPTION_MRU)
340+
return ppp_my_options_add(fsm, MRU_OPTION_LEN + ASYNC_MAP_OPTION_LEN);
341+
#else
342+
return ppp_my_options_add(fsm, ASYNC_MAP_OPTION_LEN);
343+
#endif
280344
}
281345

282346
static int lcp_config_info_nack(struct ppp_fsm *fsm, struct net_pkt *pkt,
@@ -297,7 +361,6 @@ static int lcp_config_info_nack(struct ppp_fsm *fsm, struct net_pkt *pkt,
297361

298362
return 0;
299363
}
300-
#endif
301364

302365
static void lcp_init(struct ppp_context *ctx)
303366
{
@@ -311,8 +374,8 @@ static void lcp_init(struct ppp_context *ctx)
311374
ppp_fsm_name_set(&ctx->lcp.fsm, ppp_proto2str(PPP_LCP));
312375

313376
ctx->lcp.my_options.mru = net_if_get_mtu(ctx->iface);
377+
ctx->lcp.my_options.async_map = 0xffffffff;
314378

315-
#if defined(CONFIG_NET_L2_PPP_OPTION_MRU)
316379
ctx->lcp.fsm.my_options.info = lcp_my_options;
317380
ctx->lcp.fsm.my_options.data = ctx->lcp.my_options_data;
318381
ctx->lcp.fsm.my_options.count = ARRAY_SIZE(lcp_my_options);
@@ -321,7 +384,6 @@ static void lcp_init(struct ppp_context *ctx)
321384
ctx->lcp.fsm.cb.config_info_req = lcp_config_info_req;
322385
ctx->lcp.fsm.cb.config_info_nack = lcp_config_info_nack;
323386
ctx->lcp.fsm.cb.config_info_rej = ppp_my_options_parse_conf_rej;
324-
#endif
325387

326388
ctx->lcp.fsm.cb.up = lcp_up;
327389
ctx->lcp.fsm.cb.down = lcp_down;

0 commit comments

Comments
 (0)