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