1 /*
2 * Copyright (c) 2019 Intel Corporation.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/logging/log.h>
8 LOG_MODULE_DECLARE(net_l2_ppp, CONFIG_NET_L2_PPP_LOG_LEVEL);
9
10 #include <zephyr/net/net_core.h>
11 #include <zephyr/net/net_pkt.h>
12 #include <zephyr/sys/iterable_sections.h>
13 #include <zephyr/net/ppp.h>
14
15 #include "net_private.h"
16
17 #include "ppp_internal.h"
18
lcp_up(struct ppp_context * ctx)19 static void lcp_up(struct ppp_context *ctx)
20 {
21 STRUCT_SECTION_FOREACH(ppp_protocol_handler, proto) {
22 if (proto->protocol == PPP_LCP) {
23 continue;
24 }
25
26 if (proto->lower_up) {
27 proto->lower_up(ctx);
28 }
29 }
30 }
31
do_network(struct ppp_context * ctx)32 static void do_network(struct ppp_context *ctx)
33 {
34 ppp_change_phase(ctx, PPP_NETWORK);
35
36 STRUCT_SECTION_FOREACH(ppp_protocol_handler, proto) {
37 if (proto->protocol == PPP_CCP || proto->protocol == PPP_ECP) {
38 if (proto->open) {
39 proto->open(ctx);
40 }
41 }
42 }
43
44 /* Do the other network protocols if encryption is not needed for
45 * them.
46 */
47 /* TODO possible encryption stuff here*/
48
49 STRUCT_SECTION_FOREACH(ppp_protocol_handler, proto) {
50 if (proto->protocol == PPP_CCP || proto->protocol == PPP_ECP ||
51 proto->protocol >= 0xC000) {
52 continue;
53 }
54
55 if (proto->open) {
56 ctx->network_protos_open++;
57 proto->open(ctx);
58 }
59 }
60
61 if (ctx->network_protos_open == 0) {
62 const struct ppp_protocol_handler *proto = ppp_lcp_get();
63
64 if (proto) {
65 proto->close(ctx, "No network protocols open");
66 }
67 }
68 }
69
do_auth(struct ppp_context * ctx)70 static void do_auth(struct ppp_context *ctx)
71 {
72 uint16_t auth_proto = 0;
73
74 ppp_change_phase(ctx, PPP_AUTH);
75
76 if (IS_ENABLED(CONFIG_NET_L2_PPP_AUTH_SUPPORT)) {
77 auth_proto = ctx->lcp.peer_options.auth_proto;
78 }
79
80 /* If no authentication is need, then we are done */
81 if (!auth_proto) {
82 ppp_link_authenticated(ctx);
83 return;
84 }
85
86 STRUCT_SECTION_FOREACH(ppp_protocol_handler, proto) {
87 if (proto->protocol == auth_proto) {
88 if (proto->open) {
89 proto->open(ctx);
90 }
91
92 break;
93 }
94 }
95 }
96
ppp_link_established(struct ppp_context * ctx,struct ppp_fsm * fsm)97 void ppp_link_established(struct ppp_context *ctx, struct ppp_fsm *fsm)
98 {
99 NET_DBG("[%p] Link established", ctx);
100
101 ppp_change_phase(ctx, PPP_ESTABLISH);
102
103 do_auth(ctx);
104
105 lcp_up(ctx);
106 }
107
ppp_link_authenticated(struct ppp_context * ctx)108 void ppp_link_authenticated(struct ppp_context *ctx)
109 {
110 NET_DBG("[%p] Link authenticated", ctx);
111
112 do_network(ctx);
113 }
114
ppp_link_terminated(struct ppp_context * ctx)115 void ppp_link_terminated(struct ppp_context *ctx)
116 {
117 if (ctx->phase == PPP_DEAD) {
118 return;
119 }
120
121 /* TODO: cleanup things etc here if needed */
122
123 ppp_change_phase(ctx, PPP_DEAD);
124
125 NET_DBG("[%p] Link terminated", ctx);
126 }
127
ppp_link_down(struct ppp_context * ctx)128 void ppp_link_down(struct ppp_context *ctx)
129 {
130 if (ctx->phase == PPP_DEAD) {
131 return;
132 }
133
134 ppp_network_all_down(ctx);
135
136 ppp_change_phase(ctx, PPP_DEAD);
137 }
138
ppp_link_needed(struct ppp_context * ctx)139 void ppp_link_needed(struct ppp_context *ctx)
140 {
141 /* TODO: Try to create link if needed. */
142 }
143