hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/include/net/ip6_route.h
....@@ -16,7 +16,7 @@
1616 reserved_h:3;
1717 #endif
1818 __be32 lifetime;
19
- __u8 prefix[0]; /* 0,8 or 16 */
19
+ __u8 prefix[]; /* 0,8 or 16 */
2020 };
2121
2222 #include <net/addrconf.h>
....@@ -27,6 +27,7 @@
2727 #include <linux/ip.h>
2828 #include <linux/ipv6.h>
2929 #include <linux/route.h>
30
+#include <net/nexthop.h>
3031
3132 #define RT6_LOOKUP_F_IFACE 0x00000001
3233 #define RT6_LOOKUP_F_REACHABLE 0x00000002
....@@ -35,6 +36,7 @@
3536 #define RT6_LOOKUP_F_SRCPREF_PUBLIC 0x00000010
3637 #define RT6_LOOKUP_F_SRCPREF_COA 0x00000020
3738 #define RT6_LOOKUP_F_IGNORE_LINKSTATE 0x00000040
39
+#define RT6_LOOKUP_F_DST_NOREF 0x00000080
3840
3941 /* We do not (yet ?) support IPv6 jumbograms (RFC 2675)
4042 * Unlike IPv4, hdr->seg_len doesn't include the IPv6 header
....@@ -66,10 +68,14 @@
6668 (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK);
6769 }
6870
71
+/* fib entries using a nexthop object can not be coalesced into
72
+ * a multipath route
73
+ */
6974 static inline bool rt6_qualify_for_ecmp(const struct fib6_info *f6i)
7075 {
71
- return (f6i->fib6_flags & (RTF_GATEWAY|RTF_ADDRCONF|RTF_DYNAMIC)) ==
72
- RTF_GATEWAY;
76
+ /* the RTF_ADDRCONF flag filters out RA's */
77
+ return !(f6i->fib6_flags & RTF_ADDRCONF) && !f6i->nh &&
78
+ f6i->fib6_nh->fib_nh_gw_family;
7379 }
7480
7581 void ip6_route_input(struct sk_buff *skb);
....@@ -77,6 +83,10 @@
7783 struct net_device *dev,
7884 struct flowi6 *fl6,
7985 const struct sk_buff *skb, int flags);
86
+
87
+struct dst_entry *ip6_route_output_flags_noref(struct net *net,
88
+ const struct sock *sk,
89
+ struct flowi6 *fl6, int flags);
8090
8191 struct dst_entry *ip6_route_output_flags(struct net *net, const struct sock *sk,
8292 struct flowi6 *fl6, int flags);
....@@ -86,6 +96,16 @@
8696 struct flowi6 *fl6)
8797 {
8898 return ip6_route_output_flags(net, sk, fl6, 0);
99
+}
100
+
101
+/* Only conditionally release dst if flags indicates
102
+ * !RT6_LOOKUP_F_DST_NOREF or dst is in uncached_list.
103
+ */
104
+static 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);
89109 }
90110
91111 struct dst_entry *ip6_route_lookup(struct net *net, struct flowi6 *fl6,
....@@ -98,12 +118,13 @@
98118 int ip6_route_init(void);
99119 void ip6_route_cleanup(void);
100120
101
-int ipv6_route_ioctl(struct net *net, unsigned int cmd, void __user *arg);
121
+int ipv6_route_ioctl(struct net *net, unsigned int cmd,
122
+ struct in6_rtmsg *rtmsg);
102123
103124 int ip6_route_add(struct fib6_config *cfg, gfp_t gfp_flags,
104125 struct netlink_ext_ack *extack);
105126 int ip6_ins_rt(struct net *net, struct fib6_info *f6i);
106
-int ip6_del_rt(struct net *net, struct fib6_info *f6i);
127
+int ip6_del_rt(struct net *net, struct fib6_info *f6i, bool skip_notify);
107128
108129 void rt6_flush_exceptions(struct fib6_info *f6i);
109130 void rt6_age_exceptions(struct fib6_info *f6i, struct fib6_gc_args *gc_args,
....@@ -165,8 +186,7 @@
165186 void ip6_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, __be32 mtu);
166187 void ip6_redirect(struct sk_buff *skb, struct net *net, int oif, u32 mark,
167188 kuid_t uid);
168
-void ip6_redirect_no_header(struct sk_buff *skb, struct net *net, int oif,
169
- u32 mark);
189
+void ip6_redirect_no_header(struct sk_buff *skb, struct net *net, int oif);
170190 void ip6_sk_redirect(struct sk_buff *skb, struct sock *sk);
171191
172192 struct netlink_callback;
....@@ -175,13 +195,14 @@
175195 struct sk_buff *skb;
176196 struct netlink_callback *cb;
177197 struct net *net;
198
+ struct fib_dump_filter filter;
178199 };
179200
180
-int rt6_dump_route(struct fib6_info *f6i, void *p_arg);
201
+int rt6_dump_route(struct fib6_info *f6i, void *p_arg, unsigned int skip);
181202 void rt6_mtu_change(struct net_device *dev, unsigned int mtu);
182203 void rt6_remove_prefsrc(struct inet6_ifaddr *ifp);
183204 void rt6_clean_tohost(struct net *net, struct in6_addr *gateway);
184
-void rt6_sync_up(struct net_device *dev, unsigned int nh_flags);
205
+void rt6_sync_up(struct net_device *dev, unsigned char nh_flags);
185206 void rt6_disable_ip(struct net_device *dev, unsigned long event);
186207 void rt6_sync_down_dev(struct net_device *dev, unsigned long event);
187208 void rt6_multipath_rebalance(struct fib6_info *f6i);
....@@ -269,8 +290,8 @@
269290 inet6_sk(sk)->pmtudisc == IPV6_PMTUDISC_OMIT;
270291 }
271292
272
-static inline struct in6_addr *rt6_nexthop(struct rt6_info *rt,
273
- struct in6_addr *daddr)
293
+static inline const struct in6_addr *rt6_nexthop(const struct rt6_info *rt,
294
+ const struct in6_addr *daddr)
274295 {
275296 if (rt->rt6i_flags & RTF_GATEWAY)
276297 return &rt->rt6i_gateway;
....@@ -282,9 +303,16 @@
282303
283304 static inline bool rt6_duplicate_nexthop(struct fib6_info *a, struct fib6_info *b)
284305 {
285
- return a->fib6_nh.nh_dev == b->fib6_nh.nh_dev &&
286
- ipv6_addr_equal(&a->fib6_nh.nh_gw, &b->fib6_nh.nh_gw) &&
287
- !lwtunnel_cmp_encap(a->fib6_nh.nh_lwtstate, b->fib6_nh.nh_lwtstate);
306
+ struct fib6_nh *nha, *nhb;
307
+
308
+ if (a->nh || b->nh)
309
+ return nexthop_cmp(a->nh, b->nh);
310
+
311
+ nha = a->fib6_nh;
312
+ nhb = b->fib6_nh;
313
+ return nha->fib_nh_dev == nhb->fib_nh_dev &&
314
+ ipv6_addr_equal(&nha->fib_nh_gw6, &nhb->fib_nh_gw6) &&
315
+ !lwtunnel_cmp_encap(nha->fib_nh_lws, nhb->fib_nh_lws);
288316 }
289317
290318 static inline unsigned int ip6_dst_mtu_forward(const struct dst_entry *dst)
....@@ -309,8 +337,9 @@
309337 return mtu - lwtunnel_headroom(dst->lwtstate, mtu);
310338 }
311339
312
-u32 ip6_mtu_from_fib6(struct fib6_info *f6i, struct in6_addr *daddr,
313
- struct in6_addr *saddr);
340
+u32 ip6_mtu_from_fib6(const struct fib6_result *res,
341
+ const struct in6_addr *daddr,
342
+ const struct in6_addr *saddr);
314343
315344 struct neighbour *ip6_neigh_lookup(const struct in6_addr *gw,
316345 struct net_device *dev, struct sk_buff *skb,