aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/ip6_route.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/net/ip6_route.h')
-rw-r--r--include/net/ip6_route.h32
1 files changed, 28 insertions, 4 deletions
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index ee7405e759ba..b69c16cbbf71 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -27,6 +27,7 @@ struct route_info {
27#include <linux/ip.h> 27#include <linux/ip.h>
28#include <linux/ipv6.h> 28#include <linux/ipv6.h>
29#include <linux/route.h> 29#include <linux/route.h>
30#include <net/nexthop.h>
30 31
31#define RT6_LOOKUP_F_IFACE 0x00000001 32#define RT6_LOOKUP_F_IFACE 0x00000001
32#define RT6_LOOKUP_F_REACHABLE 0x00000002 33#define RT6_LOOKUP_F_REACHABLE 0x00000002
@@ -35,6 +36,7 @@ struct route_info {
35#define RT6_LOOKUP_F_SRCPREF_PUBLIC 0x00000010 36#define RT6_LOOKUP_F_SRCPREF_PUBLIC 0x00000010
36#define RT6_LOOKUP_F_SRCPREF_COA 0x00000020 37#define RT6_LOOKUP_F_SRCPREF_COA 0x00000020
37#define RT6_LOOKUP_F_IGNORE_LINKSTATE 0x00000040 38#define RT6_LOOKUP_F_IGNORE_LINKSTATE 0x00000040
39#define RT6_LOOKUP_F_DST_NOREF 0x00000080
38 40
39/* We do not (yet ?) support IPv6 jumbograms (RFC 2675) 41/* We do not (yet ?) support IPv6 jumbograms (RFC 2675)
40 * Unlike IPv4, hdr->seg_len doesn't include the IPv6 header 42 * Unlike IPv4, hdr->seg_len doesn't include the IPv6 header
@@ -66,11 +68,14 @@ static inline bool rt6_need_strict(const struct in6_addr *daddr)
66 (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK); 68 (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK);
67} 69}
68 70
71/* fib entries using a nexthop object can not be coalesced into
72 * a multipath route
73 */
69static inline bool rt6_qualify_for_ecmp(const struct fib6_info *f6i) 74static inline bool rt6_qualify_for_ecmp(const struct fib6_info *f6i)
70{ 75{
71 /* the RTF_ADDRCONF flag filters out RA's */ 76 /* the RTF_ADDRCONF flag filters out RA's */
72 return !(f6i->fib6_flags & RTF_ADDRCONF) && 77 return !(f6i->fib6_flags & RTF_ADDRCONF) && !f6i->nh &&
73 f6i->fib6_nh.fib_nh_gw_family; 78 f6i->fib6_nh->fib_nh_gw_family;
74} 79}
75 80
76void ip6_route_input(struct sk_buff *skb); 81void ip6_route_input(struct sk_buff *skb);
@@ -79,6 +84,10 @@ struct dst_entry *ip6_route_input_lookup(struct net *net,
79 struct flowi6 *fl6, 84 struct flowi6 *fl6,
80 const struct sk_buff *skb, int flags); 85 const struct sk_buff *skb, int flags);
81 86
87struct dst_entry *ip6_route_output_flags_noref(struct net *net,
88 const struct sock *sk,
89 struct flowi6 *fl6, int flags);
90
82struct dst_entry *ip6_route_output_flags(struct net *net, const struct sock *sk, 91struct dst_entry *ip6_route_output_flags(struct net *net, const struct sock *sk,
83 struct flowi6 *fl6, int flags); 92 struct flowi6 *fl6, int flags);
84 93
@@ -89,6 +98,16 @@ static inline struct dst_entry *ip6_route_output(struct net *net,
89 return ip6_route_output_flags(net, sk, fl6, 0); 98 return ip6_route_output_flags(net, sk, fl6, 0);
90} 99}
91 100
101/* Only conditionally release dst if flags indicates
102 * !RT6_LOOKUP_F_DST_NOREF or dst is in uncached_list.
103 */
104static inline void ip6_rt_put_flags(struct rt6_info *rt, int flags)
105{
106 if (!(flags & RT6_LOOKUP_F_DST_NOREF) ||
107 !list_empty(&rt->rt6i_uncached))
108 ip6_rt_put(rt);
109}
110
92struct dst_entry *ip6_route_lookup(struct net *net, struct flowi6 *fl6, 111struct dst_entry *ip6_route_lookup(struct net *net, struct flowi6 *fl6,
93 const struct sk_buff *skb, int flags); 112 const struct sk_buff *skb, int flags);
94struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, 113struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
@@ -178,7 +197,7 @@ struct rt6_rtnl_dump_arg {
178 struct fib_dump_filter filter; 197 struct fib_dump_filter filter;
179}; 198};
180 199
181int rt6_dump_route(struct fib6_info *f6i, void *p_arg); 200int rt6_dump_route(struct fib6_info *f6i, void *p_arg, unsigned int skip);
182void rt6_mtu_change(struct net_device *dev, unsigned int mtu); 201void rt6_mtu_change(struct net_device *dev, unsigned int mtu);
183void rt6_remove_prefsrc(struct inet6_ifaddr *ifp); 202void rt6_remove_prefsrc(struct inet6_ifaddr *ifp);
184void rt6_clean_tohost(struct net *net, struct in6_addr *gateway); 203void rt6_clean_tohost(struct net *net, struct in6_addr *gateway);
@@ -275,8 +294,13 @@ static inline const struct in6_addr *rt6_nexthop(const struct rt6_info *rt,
275 294
276static inline bool rt6_duplicate_nexthop(struct fib6_info *a, struct fib6_info *b) 295static inline bool rt6_duplicate_nexthop(struct fib6_info *a, struct fib6_info *b)
277{ 296{
278 struct fib6_nh *nha = &a->fib6_nh, *nhb = &b->fib6_nh; 297 struct fib6_nh *nha, *nhb;
298
299 if (a->nh || b->nh)
300 return nexthop_cmp(a->nh, b->nh);
279 301
302 nha = a->fib6_nh;
303 nhb = b->fib6_nh;
280 return nha->fib_nh_dev == nhb->fib_nh_dev && 304 return nha->fib_nh_dev == nhb->fib_nh_dev &&
281 ipv6_addr_equal(&nha->fib_nh_gw6, &nhb->fib_nh_gw6) && 305 ipv6_addr_equal(&nha->fib_nh_gw6, &nhb->fib_nh_gw6) &&
282 !lwtunnel_cmp_encap(nha->fib_nh_lws, nhb->fib_nh_lws); 306 !lwtunnel_cmp_encap(nha->fib_nh_lws, nhb->fib_nh_lws);