1 /*
2  * Copyright (c) 2016 Intel Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @file
9  * @brief Public API for network L2 interface
10  */
11 
12 #ifndef ZEPHYR_INCLUDE_NET_NET_L2_H_
13 #define ZEPHYR_INCLUDE_NET_NET_L2_H_
14 
15 #include <zephyr/device.h>
16 #include <zephyr/net/buf.h>
17 #include <zephyr/net/capture.h>
18 #include <zephyr/sys/iterable_sections.h>
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23 
24 /**
25  * @brief Network Layer 2 abstraction layer
26  * @defgroup net_l2 Network L2 Abstraction Layer
27  * @ingroup networking
28  * @{
29  */
30 
31 struct net_if;
32 
33 /** L2 flags */
34 enum net_l2_flags {
35 	/** IP multicast supported */
36 	NET_L2_MULTICAST			= BIT(0),
37 
38 	/** Do not join solicited node multicast group */
39 	NET_L2_MULTICAST_SKIP_JOIN_SOLICIT_NODE	= BIT(1),
40 
41 	/** Is promiscuous mode supported */
42 	NET_L2_PROMISC_MODE			= BIT(2),
43 
44 	/** Is this L2 point-to-point with tunneling so no need to have
45 	 * IP address etc to network interface.
46 	 */
47 	NET_L2_POINT_TO_POINT			= BIT(3),
48 } __packed;
49 
50 /**
51  * @brief Network L2 structure
52  *
53  * Used to provide an interface to lower network stack.
54  */
55 struct net_l2 {
56 	/**
57 	 * This function is used by net core to get iface's L2 layer parsing
58 	 * what's relevant to itself.
59 	 */
60 	enum net_verdict (*recv)(struct net_if *iface, struct net_pkt *pkt);
61 
62 	/**
63 	 * This function is used by net core to push a packet to lower layer
64 	 * (interface's L2), which in turn might work on the packet relevantly.
65 	 * (adding proper header etc...)
66 	 * Returns a negative error code, or the number of bytes sent otherwise.
67 	 */
68 	int (*send)(struct net_if *iface, struct net_pkt *pkt);
69 
70 	/**
71 	 * This function is used to enable/disable traffic over a network
72 	 * interface. The function returns <0 if error and >=0 if no error.
73 	 */
74 	int (*enable)(struct net_if *iface, bool state);
75 
76 	/**
77 	 * Return L2 flags for the network interface.
78 	 */
79 	enum net_l2_flags (*get_flags)(struct net_if *iface);
80 };
81 
82 /** @cond INTERNAL_HIDDEN */
83 #define NET_L2_GET_NAME(_name) _net_l2_##_name
84 #define NET_L2_DECLARE_PUBLIC(_name)					\
85 	extern const struct net_l2 NET_L2_GET_NAME(_name)
86 #define NET_L2_GET_CTX_TYPE(_name) _name##_CTX_TYPE
87 
88 #ifdef CONFIG_NET_L2_VIRTUAL
89 #define VIRTUAL_L2		VIRTUAL
90 NET_L2_DECLARE_PUBLIC(VIRTUAL_L2);
91 #endif /* CONFIG_NET_L2_DUMMY */
92 
93 #ifdef CONFIG_NET_L2_DUMMY
94 #define DUMMY_L2		DUMMY
95 #define DUMMY_L2_CTX_TYPE	void*
96 NET_L2_DECLARE_PUBLIC(DUMMY_L2);
97 #endif /* CONFIG_NET_L2_DUMMY */
98 
99 #if defined(CONFIG_NET_OFFLOAD) || defined(CONFIG_NET_SOCKETS_OFFLOAD)
100 #define OFFLOADED_NETDEV_L2 OFFLOADED_NETDEV
101 NET_L2_DECLARE_PUBLIC(OFFLOADED_NETDEV_L2);
102 #endif /* CONFIG_NET_L2_ETHERNET */
103 
104 #ifdef CONFIG_NET_L2_ETHERNET
105 #define ETHERNET_L2		ETHERNET
106 NET_L2_DECLARE_PUBLIC(ETHERNET_L2);
107 #endif /* CONFIG_NET_L2_ETHERNET */
108 
109 #ifdef CONFIG_NET_L2_PPP
110 #define PPP_L2			PPP
111 NET_L2_DECLARE_PUBLIC(PPP_L2);
112 #endif /* CONFIG_NET_L2_PPP */
113 
114 #ifdef CONFIG_NET_L2_IEEE802154
115 #define IEEE802154_L2		IEEE802154
116 NET_L2_DECLARE_PUBLIC(IEEE802154_L2);
117 #endif /* CONFIG_NET_L2_IEEE802154 */
118 
119 #ifdef CONFIG_NET_L2_BT
120 #define BLUETOOTH_L2		BLUETOOTH
121 #define BLUETOOTH_L2_CTX_TYPE	void*
122 NET_L2_DECLARE_PUBLIC(BLUETOOTH_L2);
123 #endif /* CONFIG_NET_L2_BT */
124 
125 #ifdef CONFIG_NET_L2_OPENTHREAD
126 #define OPENTHREAD_L2		OPENTHREAD
127 NET_L2_DECLARE_PUBLIC(OPENTHREAD_L2);
128 #endif /* CONFIG_NET_L2_OPENTHREAD */
129 
130 #ifdef CONFIG_NET_L2_CANBUS_RAW
131 #define CANBUS_RAW_L2		CANBUS_RAW
132 #define CANBUS_RAW_L2_CTX_TYPE	void*
133 NET_L2_DECLARE_PUBLIC(CANBUS_RAW_L2);
134 #endif /* CONFIG_NET_L2_CANBUS_RAW */
135 
136 #ifdef CONFIG_NET_L2_CUSTOM_IEEE802154
137 #ifndef CUSTOM_IEEE802154_L2
138 #define CUSTOM_IEEE802154_L2	CUSTOM_IEEE802154
139 #endif
140 #define CUSTOM_IEEE802154_L2_CTX_TYPE	void*
141 NET_L2_DECLARE_PUBLIC(CUSTOM_IEEE802154_L2);
142 #endif /* CONFIG_NET_L2_CUSTOM_IEEE802154 */
143 
144 #define NET_L2_INIT(_name, _recv_fn, _send_fn, _enable_fn, _get_flags_fn) \
145 	const STRUCT_SECTION_ITERABLE(net_l2,				\
146 				      NET_L2_GET_NAME(_name)) = {	\
147 		.recv = (_recv_fn),					\
148 		.send = (_send_fn),					\
149 		.enable = (_enable_fn),					\
150 		.get_flags = (_get_flags_fn),				\
151 	}
152 
153 #define NET_L2_GET_DATA(name, sfx) _net_l2_data_##name##sfx
154 
155 #define NET_L2_DATA_INIT(name, sfx, ctx_type)				\
156 	static ctx_type NET_L2_GET_DATA(name, sfx) __used;
157 
158 typedef int (*net_l2_send_t)(const struct device *dev, struct net_pkt *pkt);
159 
net_l2_send(net_l2_send_t send_fn,const struct device * dev,struct net_if * iface,struct net_pkt * pkt)160 static inline int net_l2_send(net_l2_send_t send_fn,
161 			      const struct device *dev,
162 			      struct net_if *iface,
163 			      struct net_pkt *pkt)
164 {
165 	net_capture_pkt(iface, pkt);
166 
167 	return send_fn(dev, pkt);
168 }
169 
170 /** @endcond */
171 
172 /**
173  * @}
174  */
175 
176 #ifdef __cplusplus
177 }
178 #endif
179 
180 #endif /* ZEPHYR_INCLUDE_NET_NET_L2_H_ */
181