147 lines
2.7 KiB
C
147 lines
2.7 KiB
C
/*
|
|
* Copyright (c) 2019 Intel Corporation.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <zephyr/logging/log.h>
|
|
LOG_MODULE_DECLARE(net_l2_ppp, CONFIG_NET_L2_PPP_LOG_LEVEL);
|
|
|
|
#include <zephyr/net/net_core.h>
|
|
#include <zephyr/net/net_pkt.h>
|
|
#include <zephyr/sys/iterable_sections.h>
|
|
#include <zephyr/net/ppp.h>
|
|
|
|
#include "net_private.h"
|
|
|
|
#include "ppp_internal.h"
|
|
|
|
static void lcp_up(struct ppp_context *ctx)
|
|
{
|
|
STRUCT_SECTION_FOREACH(ppp_protocol_handler, proto) {
|
|
if (proto->protocol == PPP_LCP) {
|
|
continue;
|
|
}
|
|
|
|
if (proto->lower_up) {
|
|
proto->lower_up(ctx);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void do_network(struct ppp_context *ctx)
|
|
{
|
|
ppp_change_phase(ctx, PPP_NETWORK);
|
|
|
|
STRUCT_SECTION_FOREACH(ppp_protocol_handler, proto) {
|
|
if (proto->protocol == PPP_CCP || proto->protocol == PPP_ECP) {
|
|
if (proto->open) {
|
|
proto->open(ctx);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Do the other network protocols if encryption is not needed for
|
|
* them.
|
|
*/
|
|
/* TODO possible encryption stuff here*/
|
|
|
|
STRUCT_SECTION_FOREACH(ppp_protocol_handler, proto) {
|
|
if (proto->protocol == PPP_CCP || proto->protocol == PPP_ECP ||
|
|
proto->protocol >= 0xC000) {
|
|
continue;
|
|
}
|
|
|
|
if (proto->open) {
|
|
ctx->network_protos_open++;
|
|
proto->open(ctx);
|
|
}
|
|
}
|
|
|
|
if (ctx->network_protos_open == 0) {
|
|
const struct ppp_protocol_handler *proto = ppp_lcp_get();
|
|
|
|
if (proto) {
|
|
proto->close(ctx, "No network protocols open");
|
|
}
|
|
}
|
|
}
|
|
|
|
static void do_auth(struct ppp_context *ctx)
|
|
{
|
|
uint16_t auth_proto = 0;
|
|
|
|
ppp_change_phase(ctx, PPP_AUTH);
|
|
|
|
if (IS_ENABLED(CONFIG_NET_L2_PPP_AUTH_SUPPORT)) {
|
|
auth_proto = ctx->lcp.peer_options.auth_proto;
|
|
}
|
|
|
|
/* If no authentication is need, then we are done */
|
|
if (!auth_proto) {
|
|
ppp_link_authenticated(ctx);
|
|
return;
|
|
}
|
|
|
|
STRUCT_SECTION_FOREACH(ppp_protocol_handler, proto) {
|
|
if (proto->protocol == auth_proto) {
|
|
if (proto->open) {
|
|
proto->open(ctx);
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void ppp_link_established(struct ppp_context *ctx, struct ppp_fsm *fsm)
|
|
{
|
|
NET_DBG("[%p] Link established", ctx);
|
|
|
|
ppp_change_phase(ctx, PPP_ESTABLISH);
|
|
|
|
do_auth(ctx);
|
|
|
|
lcp_up(ctx);
|
|
}
|
|
|
|
void ppp_link_authenticated(struct ppp_context *ctx)
|
|
{
|
|
NET_DBG("[%p] Link authenticated", ctx);
|
|
|
|
do_network(ctx);
|
|
}
|
|
|
|
void ppp_link_terminated(struct ppp_context *ctx)
|
|
{
|
|
k_sem_give(&ctx->wait_ppp_link_terminated);
|
|
|
|
if (ctx->phase == PPP_DEAD) {
|
|
return;
|
|
}
|
|
|
|
/* TODO: cleanup things etc here if needed */
|
|
|
|
ppp_change_phase(ctx, PPP_DEAD);
|
|
|
|
NET_DBG("[%p] Link terminated", ctx);
|
|
}
|
|
|
|
void ppp_link_down(struct ppp_context *ctx)
|
|
{
|
|
k_sem_give(&ctx->wait_ppp_link_down);
|
|
|
|
if (ctx->phase == PPP_DEAD) {
|
|
return;
|
|
}
|
|
|
|
ppp_network_all_down(ctx);
|
|
|
|
ppp_change_phase(ctx, PPP_DEAD);
|
|
}
|
|
|
|
void ppp_link_needed(struct ppp_context *ctx)
|
|
{
|
|
/* TODO: Try to create link if needed. */
|
|
}
|