1 /*
2  * Copyright (c) 2016 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @file
9  *
10  * SLIP driver using uart_pipe. This is meant for network connectivity between
11  * host and qemu. The host will need to run tunslip process.
12  */
13 
14 #define LOG_MODULE_NAME slip
15 #define LOG_LEVEL CONFIG_SLIP_LOG_LEVEL
16 
17 #include <logging/log.h>
18 LOG_MODULE_REGISTER(LOG_MODULE_NAME);
19 
20 #include <stdio.h>
21 
22 #include <kernel.h>
23 
24 #include <stdbool.h>
25 #include <errno.h>
26 #include <stddef.h>
27 #include <sys/util.h>
28 #include <net/ethernet.h>
29 #include <net/buf.h>
30 #include <net/net_pkt.h>
31 #include <net/net_if.h>
32 #include <net/net_core.h>
33 #include <net/dummy.h>
34 #include <drivers/console/uart_pipe.h>
35 #include <random/rand32.h>
36 
37 #define SLIP_END     0300
38 #define SLIP_ESC     0333
39 #define SLIP_ESC_END 0334
40 #define SLIP_ESC_ESC 0335
41 
42 enum slip_state {
43 	STATE_GARBAGE,
44 	STATE_OK,
45 	STATE_ESC,
46 };
47 
48 struct slip_context {
49 	bool init_done;
50 	bool first;		/* SLIP received it's byte or not after
51 				 * driver initialization or SLIP_END byte.
52 				 */
53 	uint8_t buf[1];		/* SLIP data is read into this buf */
54 	struct net_pkt *rx;	/* and then placed into this net_pkt */
55 	struct net_buf *last;	/* Pointer to last buffer in the list */
56 	uint8_t *ptr;		/* Where in net_pkt to add data */
57 	struct net_if *iface;
58 	uint8_t state;
59 
60 	uint8_t mac_addr[6];
61 	struct net_linkaddr ll_addr;
62 
63 #if defined(CONFIG_SLIP_STATISTICS)
64 #define SLIP_STATS(statement)
65 #else
66 	uint16_t garbage;
67 #define SLIP_STATS(statement) statement
68 #endif
69 };
70 
slip_writeb(unsigned char c)71 static inline void slip_writeb(unsigned char c)
72 {
73 	uint8_t buf[1] = { c };
74 
75 	uart_pipe_send(&buf[0], 1);
76 }
77 
78 /**
79  *  @brief Write byte to SLIP, escape if it is END or ESC character
80  *
81  *  @param c  a byte to write
82  */
slip_writeb_esc(unsigned char c)83 static void slip_writeb_esc(unsigned char c)
84 {
85 	switch (c) {
86 	case SLIP_END:
87 		/* If it's the same code as an END character,
88 		 * we send a special two character code so as
89 		 * not to make the receiver think we sent
90 		 * an END.
91 		 */
92 		slip_writeb(SLIP_ESC);
93 		slip_writeb(SLIP_ESC_END);
94 		break;
95 	case SLIP_ESC:
96 		/* If it's the same code as an ESC character,
97 		 * we send a special two character code so as
98 		 * not to make the receiver think we sent
99 		 * an ESC.
100 		 */
101 		slip_writeb(SLIP_ESC);
102 		slip_writeb(SLIP_ESC_ESC);
103 		break;
104 	default:
105 		slip_writeb(c);
106 	}
107 }
108 
slip_send(const struct device * dev,struct net_pkt * pkt)109 static int slip_send(const struct device *dev, struct net_pkt *pkt)
110 {
111 	struct net_buf *buf;
112 	uint8_t *ptr;
113 	uint16_t i;
114 	uint8_t c;
115 
116 	ARG_UNUSED(dev);
117 
118 	if (!pkt->buffer) {
119 		/* No data? */
120 		return -ENODATA;
121 	}
122 
123 	slip_writeb(SLIP_END);
124 
125 	for (buf = pkt->buffer; buf; buf = buf->frags) {
126 		ptr = buf->data;
127 		for (i = 0U; i < buf->len; ++i) {
128 			c = *ptr++;
129 			slip_writeb_esc(c);
130 		}
131 
132 		if (LOG_LEVEL >= LOG_LEVEL_DBG) {
133 			LOG_DBG("sent data %d bytes", buf->len);
134 
135 			if (buf->len) {
136 				LOG_HEXDUMP_DBG(buf->data,
137 						buf->len, "<slip ");
138 			}
139 		}
140 	}
141 
142 	slip_writeb(SLIP_END);
143 
144 	return 0;
145 }
146 
slip_poll_handler(struct slip_context * slip)147 static struct net_pkt *slip_poll_handler(struct slip_context *slip)
148 {
149 	if (slip->last && slip->last->len) {
150 		return slip->rx;
151 	}
152 
153 	return NULL;
154 }
155 
get_iface(struct slip_context * context,uint16_t vlan_tag)156 static inline struct net_if *get_iface(struct slip_context *context,
157 				       uint16_t vlan_tag)
158 {
159 #if defined(CONFIG_NET_VLAN)
160 	struct net_if *iface;
161 
162 	iface = net_eth_get_vlan_iface(context->iface, vlan_tag);
163 	if (!iface) {
164 		return context->iface;
165 	}
166 
167 	return iface;
168 #else
169 	ARG_UNUSED(vlan_tag);
170 
171 	return context->iface;
172 #endif
173 }
174 
process_msg(struct slip_context * slip)175 static void process_msg(struct slip_context *slip)
176 {
177 	uint16_t vlan_tag = NET_VLAN_TAG_UNSPEC;
178 	struct net_pkt *pkt;
179 
180 	pkt = slip_poll_handler(slip);
181 	if (!pkt || !pkt->buffer) {
182 		return;
183 	}
184 
185 #if defined(CONFIG_NET_VLAN)
186 	{
187 		struct net_eth_hdr *hdr = NET_ETH_HDR(pkt);
188 
189 		if (ntohs(hdr->type) == NET_ETH_PTYPE_VLAN) {
190 			struct net_eth_vlan_hdr *hdr_vlan =
191 				(struct net_eth_vlan_hdr *)NET_ETH_HDR(pkt);
192 
193 			net_pkt_set_vlan_tci(pkt, ntohs(hdr_vlan->vlan.tci));
194 			vlan_tag = net_pkt_vlan_tag(pkt);
195 		}
196 	}
197 #endif
198 
199 	if (net_recv_data(get_iface(slip, vlan_tag), pkt) < 0) {
200 		net_pkt_unref(pkt);
201 	}
202 
203 	slip->rx = NULL;
204 	slip->last = NULL;
205 }
206 
slip_input_byte(struct slip_context * slip,unsigned char c)207 static inline int slip_input_byte(struct slip_context *slip,
208 				  unsigned char c)
209 {
210 	switch (slip->state) {
211 	case STATE_GARBAGE:
212 		if (c == SLIP_END) {
213 			slip->state = STATE_OK;
214 		}
215 
216 		return 0;
217 	case STATE_ESC:
218 		if (c == SLIP_ESC_END) {
219 			c = SLIP_END;
220 		} else if (c == SLIP_ESC_ESC) {
221 			c = SLIP_ESC;
222 		} else {
223 			slip->state = STATE_GARBAGE;
224 			SLIP_STATS(slip->garbage++);
225 			return 0;
226 		}
227 
228 		slip->state = STATE_OK;
229 
230 		break;
231 	case STATE_OK:
232 		if (c == SLIP_ESC) {
233 			slip->state = STATE_ESC;
234 			return 0;
235 		}
236 
237 		if (c == SLIP_END) {
238 			slip->state = STATE_OK;
239 			slip->first = false;
240 
241 			if (slip->rx) {
242 				return 1;
243 			}
244 
245 			return 0;
246 		}
247 
248 		if (slip->first && !slip->rx) {
249 			/* Must have missed buffer allocation on first byte. */
250 			return 0;
251 		}
252 
253 		if (!slip->first) {
254 			slip->first = true;
255 
256 			slip->rx = net_pkt_rx_alloc_on_iface(slip->iface,
257 							     K_NO_WAIT);
258 			if (!slip->rx) {
259 				LOG_ERR("[%p] cannot allocate pkt", slip);
260 				return 0;
261 			}
262 
263 			slip->last = net_pkt_get_frag(slip->rx, K_NO_WAIT);
264 			if (!slip->last) {
265 				LOG_ERR("[%p] cannot allocate 1st data buffer",
266 					slip);
267 				net_pkt_unref(slip->rx);
268 				slip->rx = NULL;
269 				return 0;
270 			}
271 
272 			net_pkt_append_buffer(slip->rx, slip->last);
273 			slip->ptr = net_pkt_ip_data(slip->rx);
274 		}
275 
276 		break;
277 	}
278 
279 	/* It is possible that slip->last is not set during the startup
280 	 * of the device. If this happens do not continue and overwrite
281 	 * some random memory.
282 	 */
283 	if (!slip->last) {
284 		return 0;
285 	}
286 
287 	if (!net_buf_tailroom(slip->last)) {
288 		/* We need to allocate a new buffer */
289 		struct net_buf *buf;
290 
291 		buf = net_pkt_get_reserve_rx_data(K_NO_WAIT);
292 		if (!buf) {
293 			LOG_ERR("[%p] cannot allocate next data buf", slip);
294 			net_pkt_unref(slip->rx);
295 			slip->rx = NULL;
296 			slip->last = NULL;
297 
298 			return 0;
299 		}
300 
301 		net_buf_frag_insert(slip->last, buf);
302 		slip->last = buf;
303 		slip->ptr = slip->last->data;
304 	}
305 
306 	/* The net_buf_add_u8() cannot add data to ll header so we need
307 	 * a way to do it.
308 	 */
309 	if (slip->ptr < slip->last->data) {
310 		*slip->ptr = c;
311 	} else {
312 		slip->ptr = net_buf_add_u8(slip->last, c);
313 	}
314 
315 	slip->ptr++;
316 
317 	return 0;
318 }
319 
recv_cb(uint8_t * buf,size_t * off)320 static uint8_t *recv_cb(uint8_t *buf, size_t *off)
321 {
322 	struct slip_context *slip =
323 		CONTAINER_OF(buf, struct slip_context, buf);
324 	size_t i;
325 
326 	if (!slip->init_done) {
327 		*off = 0;
328 		return buf;
329 	}
330 
331 	for (i = 0; i < *off; i++) {
332 		if (slip_input_byte(slip, buf[i])) {
333 
334 			if (LOG_LEVEL >= LOG_LEVEL_DBG) {
335 				struct net_buf *buf = slip->rx->buffer;
336 				int bytes = net_buf_frags_len(buf);
337 				int count = 0;
338 
339 				while (bytes && buf) {
340 					char msg[8 + 1];
341 
342 					snprintk(msg, sizeof(msg),
343 						 ">slip %2d", count);
344 
345 					LOG_HEXDUMP_DBG(buf->data, buf->len,
346 							msg);
347 
348 					buf = buf->frags;
349 					count++;
350 				}
351 
352 				LOG_DBG("[%p] received data %d bytes", slip,
353 					bytes);
354 			}
355 
356 			process_msg(slip);
357 			break;
358 		}
359 	}
360 
361 	*off = 0;
362 
363 	return buf;
364 }
365 
slip_init(const struct device * dev)366 static int slip_init(const struct device *dev)
367 {
368 	struct slip_context *slip = dev->data;
369 
370 	LOG_DBG("[%p] dev %p", slip, dev);
371 
372 	slip->state = STATE_OK;
373 	slip->rx = NULL;
374 	slip->first = false;
375 
376 #if defined(CONFIG_SLIP_TAP) && defined(CONFIG_NET_IPV4)
377 	LOG_DBG("ARP enabled");
378 #endif
379 
380 	uart_pipe_register(slip->buf, sizeof(slip->buf), recv_cb);
381 
382 	return 0;
383 }
384 
slip_get_mac(struct slip_context * slip)385 static inline struct net_linkaddr *slip_get_mac(struct slip_context *slip)
386 {
387 	slip->ll_addr.addr = slip->mac_addr;
388 	slip->ll_addr.len = sizeof(slip->mac_addr);
389 
390 	return &slip->ll_addr;
391 }
392 
slip_iface_init(struct net_if * iface)393 static void slip_iface_init(struct net_if *iface)
394 {
395 	struct slip_context *slip = net_if_get_device(iface)->data;
396 	struct net_linkaddr *ll_addr;
397 
398 #if defined(CONFIG_SLIP_TAP) && defined(CONFIG_NET_L2_ETHERNET)
399 	ethernet_init(iface);
400 #endif
401 
402 #if defined(CONFIG_NET_LLDP)
403 	net_lldp_set_lldpdu(iface);
404 #endif
405 
406 	if (slip->init_done) {
407 		return;
408 	}
409 
410 	ll_addr = slip_get_mac(slip);
411 
412 	slip->init_done = true;
413 	slip->iface = iface;
414 
415 	if (CONFIG_SLIP_MAC_ADDR[0] != 0) {
416 		if (net_bytes_from_str(slip->mac_addr, sizeof(slip->mac_addr),
417 				       CONFIG_SLIP_MAC_ADDR) < 0) {
418 			goto use_random_mac;
419 		}
420 	} else {
421 use_random_mac:
422 		/* 00-00-5E-00-53-xx Documentation RFC 7042 */
423 		slip->mac_addr[0] = 0x00;
424 		slip->mac_addr[1] = 0x00;
425 		slip->mac_addr[2] = 0x5E;
426 		slip->mac_addr[3] = 0x00;
427 		slip->mac_addr[4] = 0x53;
428 		slip->mac_addr[5] = sys_rand32_get();
429 	}
430 	net_if_set_link_addr(iface, ll_addr->addr, ll_addr->len,
431 			     NET_LINK_ETHERNET);
432 }
433 
434 static struct slip_context slip_context_data;
435 
436 #if defined(CONFIG_SLIP_TAP)
eth_capabilities(const struct device * dev)437 static enum ethernet_hw_caps eth_capabilities(const struct device *dev)
438 {
439 	ARG_UNUSED(dev);
440 
441 	return ETHERNET_HW_VLAN
442 #if defined(CONFIG_NET_LLDP)
443 		| ETHERNET_LLDP
444 #endif
445 		;
446 }
447 
448 static const struct ethernet_api slip_if_api = {
449 	.iface_api.init = slip_iface_init,
450 
451 	.get_capabilities = eth_capabilities,
452 	.send = slip_send,
453 };
454 
455 #define _SLIP_L2_LAYER ETHERNET_L2
456 #define _SLIP_L2_CTX_TYPE NET_L2_GET_CTX_TYPE(ETHERNET_L2)
457 #define _SLIP_MTU 1500
458 
459 ETH_NET_DEVICE_INIT(slip, CONFIG_SLIP_DRV_NAME,
460 		    slip_init, NULL,
461 		    &slip_context_data, NULL,
462 		    CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
463 		    &slip_if_api, _SLIP_MTU);
464 #else
465 
466 static const struct dummy_api slip_if_api = {
467 	.iface_api.init = slip_iface_init,
468 
469 	.send = slip_send,
470 };
471 
472 #define _SLIP_L2_LAYER DUMMY_L2
473 #define _SLIP_L2_CTX_TYPE NET_L2_GET_CTX_TYPE(DUMMY_L2)
474 #define _SLIP_MTU 576
475 
476 NET_DEVICE_INIT(slip, CONFIG_SLIP_DRV_NAME, slip_init, NULL,
477 		&slip_context_data, NULL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
478 		&slip_if_api, _SLIP_L2_LAYER, _SLIP_L2_CTX_TYPE, _SLIP_MTU);
479 #endif
480