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