.. | .. |
---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-or-later */ |
---|
1 | 2 | /* |
---|
2 | 3 | * INET An implementation of the TCP/IP protocol suite for the LINUX |
---|
3 | 4 | * operating system. INET is implemented using the BSD Socket |
---|
.. | .. |
---|
15 | 16 | * Alexey Kuznetsov: Major changes for new routing code. |
---|
16 | 17 | * Mike McLagan : Routing by source |
---|
17 | 18 | * Robert Olsson : Added rt_cache statistics |
---|
18 | | - * |
---|
19 | | - * This program is free software; you can redistribute it and/or |
---|
20 | | - * modify it under the terms of the GNU General Public License |
---|
21 | | - * as published by the Free Software Foundation; either version |
---|
22 | | - * 2 of the License, or (at your option) any later version. |
---|
23 | 19 | */ |
---|
24 | 20 | #ifndef _ROUTE_H |
---|
25 | 21 | #define _ROUTE_H |
---|
.. | .. |
---|
29 | 25 | #include <net/flow.h> |
---|
30 | 26 | #include <net/inet_sock.h> |
---|
31 | 27 | #include <net/ip_fib.h> |
---|
| 28 | +#include <net/arp.h> |
---|
| 29 | +#include <net/ndisc.h> |
---|
32 | 30 | #include <linux/in_route.h> |
---|
33 | 31 | #include <linux/rtnetlink.h> |
---|
34 | 32 | #include <linux/rcupdate.h> |
---|
.. | .. |
---|
59 | 57 | |
---|
60 | 58 | int rt_iif; |
---|
61 | 59 | |
---|
| 60 | + u8 rt_gw_family; |
---|
62 | 61 | /* Info on neighbour */ |
---|
63 | | - __be32 rt_gateway; |
---|
| 62 | + union { |
---|
| 63 | + __be32 rt_gw4; |
---|
| 64 | + struct in6_addr rt_gw6; |
---|
| 65 | + }; |
---|
64 | 66 | |
---|
65 | 67 | /* Miscellaneous cached information */ |
---|
66 | 68 | u32 rt_mtu_locked:1, |
---|
.. | .. |
---|
82 | 84 | |
---|
83 | 85 | static inline __be32 rt_nexthop(const struct rtable *rt, __be32 daddr) |
---|
84 | 86 | { |
---|
85 | | - if (rt->rt_gateway) |
---|
86 | | - return rt->rt_gateway; |
---|
| 87 | + if (rt->rt_gw_family == AF_INET) |
---|
| 88 | + return rt->rt_gw4; |
---|
87 | 89 | return daddr; |
---|
88 | 90 | } |
---|
89 | 91 | |
---|
.. | .. |
---|
126 | 128 | |
---|
127 | 129 | struct rtable *ip_route_output_flow(struct net *, struct flowi4 *flp, |
---|
128 | 130 | const struct sock *sk); |
---|
| 131 | +struct rtable *ip_route_output_tunnel(struct sk_buff *skb, |
---|
| 132 | + struct net_device *dev, |
---|
| 133 | + struct net *net, __be32 *saddr, |
---|
| 134 | + const struct ip_tunnel_info *info, |
---|
| 135 | + u8 protocol, bool use_cache); |
---|
| 136 | + |
---|
129 | 137 | struct dst_entry *ipv4_blackhole_route(struct net *net, |
---|
130 | 138 | struct dst_entry *dst_orig); |
---|
131 | 139 | |
---|
.. | .. |
---|
157 | 165 | sk ? inet_sk_flowi_flags(sk) : 0, |
---|
158 | 166 | daddr, saddr, dport, sport, sock_net_uid(net, sk)); |
---|
159 | 167 | if (sk) |
---|
160 | | - security_sk_classify_flow(sk, flowi4_to_flowi(fl4)); |
---|
| 168 | + security_sk_classify_flow(sk, flowi4_to_flowi_common(fl4)); |
---|
161 | 169 | return ip_route_output_flow(net, fl4, sk); |
---|
162 | 170 | } |
---|
163 | 171 | |
---|
.. | .. |
---|
183 | 191 | u8 tos, struct net_device *devin, |
---|
184 | 192 | struct fib_result *res); |
---|
185 | 193 | |
---|
| 194 | +int ip_route_use_hint(struct sk_buff *skb, __be32 dst, __be32 src, |
---|
| 195 | + u8 tos, struct net_device *devin, |
---|
| 196 | + const struct sk_buff *hint); |
---|
| 197 | + |
---|
186 | 198 | static inline int ip_route_input(struct sk_buff *skb, __be32 dst, __be32 src, |
---|
187 | 199 | u8 tos, struct net_device *devin) |
---|
188 | 200 | { |
---|
.. | .. |
---|
201 | 213 | } |
---|
202 | 214 | |
---|
203 | 215 | void ipv4_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu, int oif, |
---|
204 | | - u32 mark, u8 protocol, int flow_flags); |
---|
| 216 | + u8 protocol); |
---|
205 | 217 | void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu); |
---|
206 | | -void ipv4_redirect(struct sk_buff *skb, struct net *net, int oif, u32 mark, |
---|
207 | | - u8 protocol, int flow_flags); |
---|
| 218 | +void ipv4_redirect(struct sk_buff *skb, struct net *net, int oif, u8 protocol); |
---|
208 | 219 | void ipv4_sk_redirect(struct sk_buff *skb, struct sock *sk); |
---|
209 | 220 | void ip_rt_send_redirect(struct sk_buff *skb); |
---|
210 | 221 | |
---|
.. | .. |
---|
220 | 231 | void ip_rt_get_source(u8 *src, struct sk_buff *skb, struct rtable *rt); |
---|
221 | 232 | struct rtable *rt_dst_alloc(struct net_device *dev, |
---|
222 | 233 | unsigned int flags, u16 type, |
---|
223 | | - bool nopolicy, bool noxfrm, bool will_cache); |
---|
| 234 | + bool nopolicy, bool noxfrm); |
---|
| 235 | +struct rtable *rt_dst_clone(struct net_device *dev, struct rtable *rt); |
---|
224 | 236 | |
---|
225 | 237 | struct in_ifaddr; |
---|
226 | 238 | void fib_add_ifaddr(struct in_ifaddr *); |
---|
.. | .. |
---|
229 | 241 | |
---|
230 | 242 | void rt_add_uncached_list(struct rtable *rt); |
---|
231 | 243 | void rt_del_uncached_list(struct rtable *rt); |
---|
| 244 | + |
---|
| 245 | +int fib_dump_info_fnhe(struct sk_buff *skb, struct netlink_callback *cb, |
---|
| 246 | + u32 table_id, struct fib_info *fi, |
---|
| 247 | + int *fa_index, int fa_start, unsigned int flags); |
---|
232 | 248 | |
---|
233 | 249 | static inline void ip_rt_put(struct rtable *rt) |
---|
234 | 250 | { |
---|
.. | .. |
---|
306 | 322 | ip_rt_put(rt); |
---|
307 | 323 | flowi4_update_output(fl4, oif, tos, fl4->daddr, fl4->saddr); |
---|
308 | 324 | } |
---|
309 | | - security_sk_classify_flow(sk, flowi4_to_flowi(fl4)); |
---|
| 325 | + security_sk_classify_flow(sk, flowi4_to_flowi_common(fl4)); |
---|
310 | 326 | return ip_route_output_flow(net, fl4, sk); |
---|
311 | 327 | } |
---|
312 | 328 | |
---|
.. | .. |
---|
322 | 338 | flowi4_update_output(fl4, sk->sk_bound_dev_if, |
---|
323 | 339 | RT_CONN_FLAGS(sk), fl4->daddr, |
---|
324 | 340 | fl4->saddr); |
---|
325 | | - security_sk_classify_flow(sk, flowi4_to_flowi(fl4)); |
---|
| 341 | + security_sk_classify_flow(sk, flowi4_to_flowi_common(fl4)); |
---|
326 | 342 | return ip_route_output_flow(sock_net(sk), fl4, sk); |
---|
327 | 343 | } |
---|
328 | 344 | return rt; |
---|
.. | .. |
---|
348 | 364 | return hoplimit; |
---|
349 | 365 | } |
---|
350 | 366 | |
---|
| 367 | +static inline struct neighbour *ip_neigh_gw4(struct net_device *dev, |
---|
| 368 | + __be32 daddr) |
---|
| 369 | +{ |
---|
| 370 | + struct neighbour *neigh; |
---|
| 371 | + |
---|
| 372 | + neigh = __ipv4_neigh_lookup_noref(dev, (__force u32)daddr); |
---|
| 373 | + if (unlikely(!neigh)) |
---|
| 374 | + neigh = __neigh_create(&arp_tbl, &daddr, dev, false); |
---|
| 375 | + |
---|
| 376 | + return neigh; |
---|
| 377 | +} |
---|
| 378 | + |
---|
| 379 | +static inline struct neighbour *ip_neigh_for_gw(struct rtable *rt, |
---|
| 380 | + struct sk_buff *skb, |
---|
| 381 | + bool *is_v6gw) |
---|
| 382 | +{ |
---|
| 383 | + struct net_device *dev = rt->dst.dev; |
---|
| 384 | + struct neighbour *neigh; |
---|
| 385 | + |
---|
| 386 | + if (likely(rt->rt_gw_family == AF_INET)) { |
---|
| 387 | + neigh = ip_neigh_gw4(dev, rt->rt_gw4); |
---|
| 388 | + } else if (rt->rt_gw_family == AF_INET6) { |
---|
| 389 | + neigh = ip_neigh_gw6(dev, &rt->rt_gw6); |
---|
| 390 | + *is_v6gw = true; |
---|
| 391 | + } else { |
---|
| 392 | + neigh = ip_neigh_gw4(dev, ip_hdr(skb)->daddr); |
---|
| 393 | + } |
---|
| 394 | + return neigh; |
---|
| 395 | +} |
---|
| 396 | + |
---|
351 | 397 | #endif /* _ROUTE_H */ |
---|