1 /** @file
2  * @brief Route handler
3  *
4  * This is not to be included by the application.
5  */
6 
7 /*
8  * Copyright (c) 2016 Intel Corporation
9  *
10  * SPDX-License-Identifier: Apache-2.0
11  */
12 
13 #ifndef __ROUTE_H
14 #define __ROUTE_H
15 
16 #include <zephyr/kernel.h>
17 #include <zephyr/sys/slist.h>
18 
19 #include <zephyr/net/net_ip.h>
20 #include <zephyr/net/net_timeout.h>
21 
22 #include "nbr.h"
23 
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27 
28 /**
29  * @brief Next hop entry for a given route.
30  */
31 struct net_route_nexthop {
32 	/** Pointer to nexthop that has same route to a specific
33 	 * neighbor.
34 	 */
35 	sys_snode_t node;
36 
37 	/** Next hop neighbor */
38 	struct net_nbr *nbr;
39 };
40 
41 /**
42  * @brief Route entry to a specific neighbor.
43  */
44 struct net_route_entry {
45 	/** Node information. The routes are also in separate list in
46 	 * order to keep track which one of them is the oldest so that
47 	 * we can remove it if we run out of available routes.
48 	 * The oldest one is the last entry in the list.
49 	 */
50 	sys_snode_t node;
51 
52 	/** List of neighbors that the routes go through. */
53 	sys_slist_t nexthop;
54 
55 	/** Network interface for the route. */
56 	struct net_if *iface;
57 
58 	/** Route lifetime timer. */
59 	struct net_timeout lifetime;
60 
61 	/** IPv6 address/prefix of the route. */
62 	struct in6_addr addr;
63 
64 	/** IPv6 address/prefix length. */
65 	uint8_t prefix_len;
66 
67 	uint8_t preference : 2;
68 
69 	/** Is the route valid forever */
70 	uint8_t is_infinite : 1;
71 };
72 
73 /* Route preference values, as defined in RFC 4191 */
74 #define NET_ROUTE_PREFERENCE_HIGH     0x01
75 #define NET_ROUTE_PREFERENCE_MEDIUM   0x00
76 #define NET_ROUTE_PREFERENCE_LOW      0x03 /* -1 if treated as 2 bit signed int */
77 #define NET_ROUTE_PREFERENCE_RESERVED 0x02
78 
79 /**
80  * @brief Lookup route to a given destination.
81  *
82  * @param iface Network interface. If NULL, then check against all interfaces.
83  * @param dst Destination IPv6 address.
84  *
85  * @return Return route entry related to a given destination address, NULL
86  * if not found.
87  */
88 #if defined(CONFIG_NET_NATIVE)
89 struct net_route_entry *net_route_lookup(struct net_if *iface,
90 					 struct in6_addr *dst);
91 #else
net_route_lookup(struct net_if * iface,struct in6_addr * dst)92 static inline struct net_route_entry *net_route_lookup(struct net_if *iface,
93 						       struct in6_addr *dst)
94 {
95 	ARG_UNUSED(iface);
96 	ARG_UNUSED(dst);
97 
98 	return NULL;
99 }
100 #endif
101 
102 /**
103  * @brief Add a route to routing table.
104  *
105  * @param iface Network interface that this route is tied to.
106  * @param addr IPv6 address.
107  * @param prefix_len Length of the IPv6 address/prefix.
108  * @param nexthop IPv6 address of the Next hop device.
109  * @param lifetime Route lifetime in seconds.
110  * @param preference Route preference.
111  *
112  * @return Return created route entry, NULL if could not be created.
113  */
114 struct net_route_entry *net_route_add(struct net_if *iface,
115 				      struct in6_addr *addr,
116 				      uint8_t prefix_len,
117 				      struct in6_addr *nexthop,
118 				      uint32_t lifetime,
119 				      uint8_t preference);
120 
121 /**
122  * @brief Delete a route from routing table.
123  *
124  * @param entry Existing route entry.
125  *
126  * @return 0 if ok, <0 if error
127  */
128 int net_route_del(struct net_route_entry *entry);
129 
130 /**
131  * @brief Delete a route from routing table by nexthop.
132  *
133  * @param iface Network interface to use.
134  * @param nexthop IPv6 address of the nexthop device.
135  *
136  * @return number of routes deleted, <0 if error
137  */
138 int net_route_del_by_nexthop(struct net_if *iface,
139 			     struct in6_addr *nexthop);
140 
141 /**
142  * @brief Update the route lifetime.
143  *
144  * @param route Pointer to routing entry.
145  * @param lifetime Route lifetime in seconds.
146  *
147  * @return 0 if ok, <0 if error
148  */
149 void net_route_update_lifetime(struct net_route_entry *route, uint32_t lifetime);
150 
151 /**
152  * @brief Get nexthop IPv6 address tied to this route.
153  *
154  * There can be multiple routes to a host but this function
155  * will only return the first one in this version.
156  *
157  * @param entry Route entry to use.
158  *
159  * @return IPv6 address of the nexthop, NULL if not found.
160  */
161 struct in6_addr *net_route_get_nexthop(struct net_route_entry *entry);
162 
163 /**
164  * @brief Get generic neighbor entry from route entry.
165  *
166  * @param route Pointer to routing entry.
167  *
168  * @return Generic neighbor entry.
169  */
170 struct net_nbr *net_route_get_nbr(struct net_route_entry *route);
171 
172 typedef void (*net_route_cb_t)(struct net_route_entry *entry,
173 			       void *user_data);
174 
175 /**
176  * @brief Go through all the routing entries and call callback
177  * for each entry that is in use.
178  *
179  * @param cb User supplied callback function to call.
180  * @param user_data User specified data.
181  *
182  * @return Total number of routing entries found.
183  */
184 int net_route_foreach(net_route_cb_t cb, void *user_data);
185 
186 #if defined(CONFIG_NET_ROUTE_MCAST)
187 /**
188  * @brief Multicast route entry.
189  */
190 struct net_route_entry_mcast {
191 	/** Network interfaces for the route. */
192 	struct net_if *ifaces[CONFIG_NET_MCAST_ROUTE_MAX_IFACES];
193 
194 	/** Extra routing engine specific data */
195 	void *data;
196 
197 	/** IPv6 multicast group of the route. */
198 	struct in6_addr group;
199 
200 	/** Routing entry lifetime in seconds. */
201 	uint32_t lifetime;
202 
203 	/** Is this entry in use or not */
204 	bool is_used;
205 
206 	/** IPv6 multicast group prefix length. */
207 	uint8_t prefix_len;
208 };
209 #else
210 struct net_route_entry_mcast;
211 #endif
212 
213 typedef void (*net_route_mcast_cb_t)(struct net_route_entry_mcast *entry,
214 				     void *user_data);
215 
216 /**
217  * @brief Forwards a multicast packet by checking the local multicast
218  * routing table
219  *
220  * @param pkt The original received ipv6 packet to forward
221  * @param hdr The IPv6 header of the packet
222  *
223  * @return Number of interfaces which forwarded the packet, or a negative
224  * value in case of an error.
225  */
226 int net_route_mcast_forward_packet(struct net_pkt *pkt,
227 				   struct net_ipv6_hdr *hdr);
228 
229 /**
230  * @brief Go through all the multicast routing entries and call callback
231  * for each entry that is in use.
232  *
233  * @param cb User supplied callback function to call.
234  * @param skip Do not call callback for this address.
235  * @param user_data User specified data.
236  *
237  * @return Total number of multicast routing entries that are in use.
238  */
239 int net_route_mcast_foreach(net_route_mcast_cb_t cb,
240 			    struct in6_addr *skip,
241 			    void *user_data);
242 
243 /**
244  * @brief Add a multicast routing entry.
245  *
246  * @param iface Network interface to use.
247  * @param group IPv6 multicast address.
248  * @param prefix_len Length of the IPv6 group that must match.
249  *
250  * @return Multicast routing entry.
251  */
252 struct net_route_entry_mcast *net_route_mcast_add(struct net_if *iface,
253 						  struct in6_addr *group,
254 						  uint8_t prefix_len);
255 
256 /**
257  * @brief Delete a multicast routing entry.
258  *
259  * @param route Multicast routing entry.
260  *
261  * @return True if entry was deleted, false otherwise.
262  */
263 bool net_route_mcast_del(struct net_route_entry_mcast *route);
264 
265 /**
266  * @brief Lookup a multicast routing entry.
267  *
268  * @param group IPv6 multicast group address
269  *
270  * @return Routing entry corresponding this multicast group.
271  */
272 struct net_route_entry_mcast *
273 net_route_mcast_lookup(struct in6_addr *group);
274 
275 /**
276  * @brief Add an interface to multicast routing entry.
277  *
278  * @param entry Multicast routing entry.
279  * @param iface Network interface to be added.
280  *
281  * @return True if the interface was added or found on the
282  *         list, false otherwise.
283  */
284 bool net_route_mcast_iface_add(struct net_route_entry_mcast *entry, struct net_if *iface);
285 
286 /**
287  * @brief Delete an interface from multicast routing entry.
288  *
289  * @param entry Multicast routing entry.
290  * @param iface Network interface to be deleted.
291  *
292  * @return True if entry was deleted, false otherwise.
293  */
294 bool net_route_mcast_iface_del(struct net_route_entry_mcast *entry, struct net_if *iface);
295 
296 /**
297  * @brief Return a route to destination via some intermediate host.
298  *
299  * @param iface Network interface
300  * @param dst Destination IPv6 address
301  * @param route Route entry to destination is returned.
302  * @param nexthop Next hop neighbor IPv6 address is returned.
303  *
304  * @return True if there is a route to the destination, False otherwise
305  */
306 bool net_route_get_info(struct net_if *iface,
307 			struct in6_addr *dst,
308 			struct net_route_entry **route,
309 			struct in6_addr **nexthop);
310 
311 /**
312  * @brief Send the network packet to network via some intermediate host.
313  *
314  * @param pkt Network packet to send.
315  * @param nexthop Next hop neighbor IPv6 address.
316  *
317  * @return 0 if there was no error, <0 if the packet could not be sent.
318  */
319 int net_route_packet(struct net_pkt *pkt, struct in6_addr *nexthop);
320 
321 /**
322  * @brief Send the network packet to network via the given interface.
323  *
324  * @param pkt Network packet to send.
325  * @param iface The network interface the packet should be sent on.
326  *
327  * @return 0 if there was no error, <0 if the packet could not be sent.
328  */
329 int net_route_packet_if(struct net_pkt *pkt, struct net_if *iface);
330 
331 #if defined(CONFIG_NET_ROUTE) && defined(CONFIG_NET_NATIVE)
332 void net_route_init(void);
333 #else
334 #define net_route_init(...)
335 #endif /* CONFIG_NET_ROUTE */
336 
337 #ifdef __cplusplus
338 }
339 #endif
340 
341 #endif /* __ROUTE_H */
342