1 /** @file
2 @brief PPP private header
3
4 This is not to be included by the application.
5 */
6
7 /*
8 * Copyright (c) 2019 Intel Corporation
9 *
10 * SPDX-License-Identifier: Apache-2.0
11 */
12
13 #include <zephyr/net/ppp.h>
14 #include <zephyr/sys/iterable_sections.h>
15
16 /**
17 * FSM flags that control how it operates.
18 */
19 #define FSM_RESTART BIT(0) /**< Treat 2nd OPEN as DOWN followed by UP */
20
21 /**
22 * PPP packet format.
23 */
24 struct ppp_packet {
25 uint8_t code;
26 uint8_t id;
27 uint16_t length;
28 } __packed;
29
30 /** Max Terminate-Request transmissions */
31 #define MAX_TERMINATE_REQ CONFIG_NET_L2_PPP_MAX_TERMINATE_REQ_RETRANSMITS
32
33 /** Max Configure-Request transmissions */
34 #define MAX_CONFIGURE_REQ CONFIG_NET_L2_PPP_MAX_CONFIGURE_REQ_RETRANSMITS
35
36 #define PPP_BUF_ALLOC_TIMEOUT K_MSEC(100)
37
38 /** Protocol handler information. */
39 struct ppp_protocol_handler {
40 /** Protocol init function */
41 void (*init)(struct ppp_context *ctx);
42
43 /** Process a received packet */
44 enum net_verdict (*handler)(struct ppp_context *ctx,
45 struct net_if *iface,
46 struct net_pkt *pkt);
47
48 /** Lower layer up */
49 void (*lower_up)(struct ppp_context *ctx);
50
51 /** Lower layer down */
52 void (*lower_down)(struct ppp_context *ctx);
53
54 /** Enable this protocol */
55 void (*open)(struct ppp_context *ctx);
56
57 /** Disable this protocol */
58 void (*close)(struct ppp_context *ctx, const uint8_t *reason);
59
60 /** PPP protocol number */
61 uint16_t protocol;
62 };
63
64 struct ppp_peer_option_info {
65 uint8_t code;
66 int (*parse)(struct ppp_fsm *fsm, struct net_pkt *pkt,
67 void *user_data);
68 int (*nack)(struct ppp_fsm *fsm, struct net_pkt *ret_pkt,
69 void *user_data);
70 };
71
72 #define PPP_PEER_OPTION(_code, _parse, _nack) \
73 { \
74 .code = _code, \
75 .parse = _parse, \
76 .nack = _nack, \
77 }
78
79 int ppp_config_info_req(struct ppp_fsm *fsm,
80 struct net_pkt *pkt,
81 uint16_t length,
82 struct net_pkt *ret_pkt,
83 enum ppp_protocol_type protocol,
84 const struct ppp_peer_option_info *options_info,
85 size_t num_options_info,
86 void *user_data);
87
88 #define PPP_PROTO_GET_NAME(proto_name) \
89 _CONCAT(ppp_protocol_handler_, proto_name)
90
91 #define PPP_PROTOCOL_REGISTER(name, proto, init_func, proto_handler, \
92 proto_lower_up, proto_lower_down, \
93 proto_open, proto_close) \
94 static const STRUCT_SECTION_ITERABLE(ppp_protocol_handler, \
95 PPP_PROTO_GET_NAME(name)) = { \
96 .protocol = proto, \
97 .init = init_func, \
98 .handler = proto_handler, \
99 .lower_up = proto_lower_up, \
100 .lower_down = proto_lower_down, \
101 .open = proto_open, \
102 .close = proto_close, \
103 }
104
105 void ppp_queue_pkt(struct net_pkt *pkt);
106 const char *ppp_phase_str(enum ppp_phase phase);
107 const char *ppp_state_str(enum ppp_state state);
108 const char *ppp_proto2str(uint16_t proto);
109 const char *ppp_pkt_type2str(enum ppp_packet_type type);
110 const char *ppp_option2str(enum ppp_protocol_type protocol, int type);
111 void ppp_fsm_name_set(struct ppp_fsm *fsm, const char *name);
112
113 #if CONFIG_NET_L2_PPP_LOG_LEVEL < LOG_LEVEL_DBG
114 void ppp_change_phase(struct ppp_context *ctx, enum ppp_phase new_phase);
115 void ppp_change_state(struct ppp_fsm *fsm, enum ppp_state new_state);
116 #else
117 void ppp_change_phase_debug(struct ppp_context *ctx,
118 enum ppp_phase new_phase,
119 const char *caller, int line);
120
121 #define ppp_change_phase(ctx, state) \
122 ppp_change_phase_debug(ctx, state, __func__, __LINE__)
123
124 #define ppp_change_state(fsm, state) \
125 ppp_change_state_debug(fsm, state, __func__, __LINE__)
126
127 void ppp_change_state_debug(struct ppp_fsm *fsm, enum ppp_state new_state,
128 const char *caller, int line);
129 #endif
130
131 struct ppp_context *ppp_fsm_ctx(struct ppp_fsm *fsm);
132 struct net_if *ppp_fsm_iface(struct ppp_fsm *fsm);
133 int ppp_send_pkt(struct ppp_fsm *fsm, struct net_if *iface,
134 enum ppp_packet_type type, uint8_t id,
135 void *data, uint32_t data_len);
136 void ppp_send_proto_rej(struct net_if *iface, struct net_pkt *pkt,
137 uint16_t protocol);
138
139 void ppp_fsm_init(struct ppp_fsm *fsm, uint16_t protocol);
140 void ppp_fsm_lower_up(struct ppp_fsm *fsm);
141 void ppp_fsm_lower_down(struct ppp_fsm *fsm);
142 void ppp_fsm_open(struct ppp_fsm *fsm);
143 void ppp_fsm_close(struct ppp_fsm *fsm, const uint8_t *reason);
144 void ppp_fsm_proto_reject(struct ppp_fsm *fsm);
145 enum net_verdict ppp_fsm_input(struct ppp_fsm *fsm, uint16_t proto,
146 struct net_pkt *pkt);
147 enum net_verdict ppp_fsm_recv_protocol_rej(struct ppp_fsm *fsm,
148 uint8_t id,
149 struct net_pkt *pkt);
150 enum net_verdict ppp_fsm_recv_echo_req(struct ppp_fsm *fsm,
151 uint8_t id,
152 struct net_pkt *pkt);
153 enum net_verdict ppp_fsm_recv_echo_reply(struct ppp_fsm *fsm,
154 uint8_t id,
155 struct net_pkt *pkt);
156 enum net_verdict ppp_fsm_recv_discard_req(struct ppp_fsm *fsm,
157 uint8_t id,
158 struct net_pkt *pkt);
159
160 const struct ppp_protocol_handler *ppp_lcp_get(void);
161 int ppp_parse_options(struct ppp_fsm *fsm, struct net_pkt *pkt,
162 uint16_t length,
163 int (*parse)(struct net_pkt *pkt, uint8_t code,
164 uint8_t len, void *user_data),
165 void *user_data);
166
167 void ppp_link_established(struct ppp_context *ctx, struct ppp_fsm *fsm);
168 void ppp_link_authenticated(struct ppp_context *ctx);
169 void ppp_link_terminated(struct ppp_context *ctx);
170 void ppp_link_down(struct ppp_context *ctx);
171 void ppp_link_needed(struct ppp_context *ctx);
172
173 void ppp_network_up(struct ppp_context *ctx, int proto);
174 void ppp_network_down(struct ppp_context *ctx, int proto);
175 void ppp_network_done(struct ppp_context *ctx, int proto);
176 void ppp_network_all_down(struct ppp_context *ctx);
177
178 struct ppp_my_option_info {
179 uint8_t code;
180 int (*conf_req_add)(struct ppp_context *ctx, struct net_pkt *pkt);
181 int (*conf_ack_handle)(struct ppp_context *ctx, struct net_pkt *pkt,
182 uint8_t oplen);
183 int (*conf_nak_handle)(struct ppp_context *ctx, struct net_pkt *pkt,
184 uint8_t oplen);
185 };
186
187 #define PPP_MY_OPTION(_code, _req_add, _handle_ack, _handle_nak) \
188 { \
189 .code = _code, \
190 .conf_req_add = _req_add, \
191 .conf_ack_handle = _handle_ack, \
192 .conf_nak_handle = _handle_nak, \
193 }
194
195 struct net_pkt *ppp_my_options_add(struct ppp_fsm *fsm, size_t packet_len);
196
197 int ppp_my_options_parse_conf_ack(struct ppp_fsm *fsm,
198 struct net_pkt *pkt,
199 uint16_t length);
200
201 int ppp_my_options_parse_conf_nak(struct ppp_fsm *fsm,
202 struct net_pkt *pkt,
203 uint16_t length);
204
205 int ppp_my_options_parse_conf_rej(struct ppp_fsm *fsm,
206 struct net_pkt *pkt,
207 uint16_t length);
208
209 uint32_t ppp_my_option_flags(struct ppp_fsm *fsm, uint8_t code);
210
ppp_my_option_is_acked(struct ppp_fsm * fsm,uint8_t code)211 static inline bool ppp_my_option_is_acked(struct ppp_fsm *fsm,
212 uint8_t code)
213 {
214 return ppp_my_option_flags(fsm, code) & PPP_MY_OPTION_ACKED;
215 }
216