From 72cdd1d971c0deb1619c5c339270570c43647a78 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 11 Nov 2010 07:14:07 +0000 Subject: net: get rid of rtable->idev It seems idev field in struct rtable has no special purpose, but adding extra atomic ops. We hold refcounts on the device itself (using percpu data, so pretty cheap in current kernel). infiniband case is solved using dst.dev instead of idev->dev Removal of this field means routing without route cache is now using shared data, percpu data, and only potential contention is a pair of atomic ops on struct neighbour per forwarded packet. About 5% speedup on routing test. Signed-off-by: Eric Dumazet Cc: Herbert Xu Cc: Roland Dreier Cc: Sean Hefty Cc: Hal Rosenstock Signed-off-by: David S. Miller --- include/net/route.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index 7e5e73bfa4de..cea533eaa853 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -55,8 +55,6 @@ struct rtable { /* Cache lookup keys */ struct flowi fl; - struct in_device *idev; - int rt_genid; unsigned rt_flags; __u16 rt_type; -- cgit v1.2.2 From c753796769e4fb0cd813b6e5801b3c01f4681d4f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 11 Nov 2010 17:07:48 -0800 Subject: ipv4: Make rt->fl.iif tests lest obscure. When we test rt->fl.iif against zero, we're seeing if it's an output or an input route. Make that explicit with some helper functions. Signed-off-by: David S. Miller --- include/net/route.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index cea533eaa853..5cd46d1c0e14 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -71,6 +71,16 @@ struct rtable { struct inet_peer *peer; /* long-living peer info */ }; +static inline bool rt_is_input_route(struct rtable *rt) +{ + return rt->fl.iif != 0; +} + +static inline bool rt_is_output_route(struct rtable *rt) +{ + return rt->fl.iif == 0; +} + struct ip_rt_acct { __u32 o_bytes; __u32 o_packets; -- cgit v1.2.2 From 5811662b15db018c740c57d037523683fd3e6123 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Fri, 12 Nov 2010 18:43:55 +0000 Subject: net: use the macros defined for the members of flowi Use the macros defined for the members of flowi to clean the code up. Signed-off-by: Changli Gao Signed-off-by: David S. Miller --- include/net/route.h | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index 5cd46d1c0e14..b8c1f7703fc6 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -169,14 +169,12 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst, { struct flowi fl = { .oif = oif, .mark = sk->sk_mark, - .nl_u = { .ip4_u = { .daddr = dst, - .saddr = src, - .tos = tos } }, + .fl4_dst = dst, + .fl4_src = src, + .fl4_tos = tos, .proto = protocol, - .uli_u = { .ports = - { .sport = sport, - .dport = dport } } }; - + .fl_ip_sport = sport, + .fl_ip_dport = dport }; int err; struct net *net = sock_net(sk); -- cgit v1.2.2 From 323e126f0c5995f779d7df7fd035f6e8fed8764d Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 12 Dec 2010 21:55:08 -0800 Subject: ipv4: Don't pre-seed hoplimit metric. Always go through a new ip4_dst_hoplimit() helper, just like ipv6. This allowed several simplifications: 1) The interim dst_metric_hoplimit() can go as it's no longer userd. 2) The sysctl_ip_default_ttl entry no longer needs to use ipv4_doint_and_flush, since the sysctl is not cached in routing cache metrics any longer. 3) ipv4_doint_and_flush no longer needs to be exported and therefore can be marked static. When ipv4_doint_and_flush_strategy was removed some time ago, the external declaration in ip.h was mistakenly left around so kill that off too. We have to move the sysctl_ip_default_ttl declaration into ipv4's route cache definition header net/route.h, because currently net/ip.h (where the declaration lives now) has a back dependency on net/route.h Signed-off-by: David S. Miller --- include/net/route.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index b8c1f7703fc6..27002362944a 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -231,4 +231,15 @@ static inline int inet_iif(const struct sk_buff *skb) return skb_rtable(skb)->rt_iif; } +extern int sysctl_ip_default_ttl; + +static inline int ip4_dst_hoplimit(const struct dst_entry *dst) +{ + int hoplimit = dst_metric_raw(dst, RTAX_HOPLIMIT); + + if (hoplimit == 0) + hoplimit = sysctl_ip_default_ttl; + return hoplimit; +} + #endif /* _ROUTE_H */ -- cgit v1.2.2 From 6561a3b12d62ed5317e6ac32182d87a03f62c8dc Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 19 Dec 2010 21:11:20 -0800 Subject: ipv4: Flush per-ns routing cache more sanely. Flush the routing cache only of entries that match the network namespace in which the purge event occurred. Signed-off-by: David S. Miller Acked-by: Eric Dumazet --- include/net/route.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index 27002362944a..93e10c453f6b 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -114,7 +114,7 @@ extern int ip_rt_init(void); extern void ip_rt_redirect(__be32 old_gw, __be32 dst, __be32 new_gw, __be32 src, struct net_device *dev); extern void rt_cache_flush(struct net *net, int how); -extern void rt_cache_flush_batch(void); +extern void rt_cache_flush_batch(struct net *net); extern int __ip_route_output_key(struct net *, struct rtable **, const struct flowi *flp); extern int ip_route_output_key(struct net *, struct rtable **, struct flowi *flp); extern int ip_route_output_flow(struct net *, struct rtable **rp, struct flowi *flp, struct sock *sk, int flags); -- cgit v1.2.2 From 62fa8a846d7de4b299232e330c74b7783539df76 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 26 Jan 2011 20:51:05 -0800 Subject: net: Implement read-only protection and COW'ing of metrics. Routing metrics are now copy-on-write. Initially a route entry points it's metrics at a read-only location. If a routing table entry exists, it will point there. Else it will point at the all zero metric place-holder called 'dst_default_metrics'. The writeability state of the metrics is stored in the low bits of the metrics pointer, we have two bits left to spare if we want to store more states. For the initial implementation, COW is implemented simply via kmalloc. However future enhancements will change this to place the writable metrics somewhere else, in order to increase sharing. Very likely this "somewhere else" will be the inetpeer cache. Note also that this means that metrics updates may transiently fail if we cannot COW the metrics successfully. But even by itself, this patch should decrease memory usage and increase cache locality especially for routing workloads. In those cases the read-only metric copies stay in place and never get written to. TCP workloads where metrics get updated, and those rare cases where PMTU triggers occur, will take a very slight performance hit. But that hit will be alleviated when the long-term writable metrics move to a more sharable location. Since the metrics storage went from a u32 array of RTAX_MAX entries to what is essentially a pointer, some retooling of the dst_entry layout was necessary. Most importantly, we need to preserve the alignment of the reference count so that it doesn't share cache lines with the read-mostly state, as per Eric Dumazet's alignment assertion checks. The only non-trivial bit here is the move of the 'flags' member into the writeable cacheline. This is OK since we are always accessing the flags around the same moment when we made a modification to the reference count. Signed-off-by: David S. Miller --- include/net/route.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index 93e10c453f6b..5677cbf0c6e6 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -49,6 +49,7 @@ struct fib_nh; struct inet_peer; +struct fib_info; struct rtable { struct dst_entry dst; @@ -69,6 +70,7 @@ struct rtable { /* Miscellaneous cached information */ __be32 rt_spec_dst; /* RFC1122 specific destination */ struct inet_peer *peer; /* long-living peer info */ + struct fib_info *fi; /* for client ref to shared metrics */ }; static inline bool rt_is_input_route(struct rtable *rt) -- cgit v1.2.2 From a4daad6b0923030fbd3b00a01f570e4c3eef446b Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 27 Jan 2011 22:01:53 -0800 Subject: net: Pre-COW metrics for TCP. TCP is going to record metrics for the connection, so pre-COW the route metrics at route cache entry creation time. This avoids several atomic operations that have to occur if we COW the metrics after the entry reaches global visibility. Signed-off-by: David S. Miller --- include/net/route.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index 5677cbf0c6e6..e5864658dc76 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -182,6 +182,8 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst, if (inet_sk(sk)->transparent) fl.flags |= FLOWI_FLAG_ANYSRC; + if (protocol == IPPROTO_TCP) + fl.flags |= FLOWI_FLAG_PRECOW_METRICS; if (!dst || !src) { err = __ip_route_output_key(net, rp, &fl); @@ -209,6 +211,8 @@ static inline int ip_route_newports(struct rtable **rp, u8 protocol, fl.proto = protocol; if (inet_sk(sk)->transparent) fl.flags |= FLOWI_FLAG_ANYSRC; + if (protocol == IPPROTO_TCP) + fl.flags |= FLOWI_FLAG_PRECOW_METRICS; ip_rt_put(*rp); *rp = NULL; security_sk_classify_flow(sk, &fl); -- cgit v1.2.2 From 6431cbc25fa21635ee04eb0516ba6c51389fbfac Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 7 Feb 2011 20:38:06 -0800 Subject: inet: Create a mechanism for upward inetpeer propagation into routes. If we didn't have a routing cache, we would not be able to properly propagate certain kinds of dynamic path attributes, for example PMTU information and redirects. The reason is that if we didn't have a routing cache, then there would be no way to lookup all of the active cached routes hanging off of sockets, tunnels, IPSEC bundles, etc. Consider the case where we created a cached route, but no inetpeer entry existed and also we were not asked to pre-COW the route metrics and therefore did not force the creation a new inetpeer entry. If we later get a PMTU message, or a redirect, and store this information in a new inetpeer entry, there is no way to teach that cached route about the newly existing inetpeer entry. The facilities implemented here handle this problem. First we create a generation ID. When we create a cached route of any kind, we remember the generation ID at the time of attachment. Any time we force-create an inetpeer entry in response to new path information, we bump that generation ID. The dst_ops->check() callback is where the knowledge of this event is propagated. If the global generation ID does not equal the one stored in the cached route, and the cached route has not attached to an inetpeer yet, we look it up and attach if one is found. Now that we've updated the cached route's information, we update the route's generation ID too. This clears the way for implementing PMTU and redirects directly in the inetpeer cache. There is absolutely no need to consult cached route information in order to maintain this information. At this point nothing bumps the inetpeer genids, that comes in the later changes which handle PMTUs and redirects using inetpeers. Signed-off-by: David S. Miller --- include/net/route.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index e5864658dc76..bf790c1c6ac8 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -69,6 +69,7 @@ struct rtable { /* Miscellaneous cached information */ __be32 rt_spec_dst; /* RFC1122 specific destination */ + u32 rt_peer_genid; struct inet_peer *peer; /* long-living peer info */ struct fib_info *fi; /* for client ref to shared metrics */ }; -- cgit v1.2.2 From dca8b089c95d94afa1d715df257de0286350e99d Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 24 Feb 2011 13:38:12 -0800 Subject: ipv4: Rearrange how ip_route_newports() gets port keys. ip_route_newports() is the only place in the entire kernel that cares about the port members in the routing cache entry's lookup flow key. Therefore the only reason we store an entire flow inside of the struct rtentry is for this one special case. Rewrite ip_route_newports() such that: 1) The caller passes in the original port values, so we don't need to use the rth->fl.fl_ip_{s,d}port values to remember them. 2) The lookup flow is constructed by hand instead of being copied from the routing cache entry's flow. Signed-off-by: David S. Miller --- include/net/route.h | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index bf790c1c6ac8..b3f89ad04e0b 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -200,16 +200,19 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst, } static inline int ip_route_newports(struct rtable **rp, u8 protocol, + __be16 orig_sport, __be16 orig_dport, __be16 sport, __be16 dport, struct sock *sk) { - if (sport != (*rp)->fl.fl_ip_sport || - dport != (*rp)->fl.fl_ip_dport) { - struct flowi fl; - - memcpy(&fl, &(*rp)->fl, sizeof(fl)); - fl.fl_ip_sport = sport; - fl.fl_ip_dport = dport; - fl.proto = protocol; + if (sport != orig_sport || dport != orig_dport) { + struct flowi fl = { .oif = (*rp)->fl.oif, + .mark = (*rp)->fl.mark, + .fl4_dst = (*rp)->fl.fl4_dst, + .fl4_src = (*rp)->fl.fl4_src, + .fl4_tos = (*rp)->fl.fl4_tos, + .proto = (*rp)->fl.proto, + .fl_ip_sport = sport, + .fl_ip_dport = dport }; + if (inet_sk(sk)->transparent) fl.flags |= FLOWI_FLAG_ANYSRC; if (protocol == IPPROTO_TCP) -- cgit v1.2.2 From abdf7e7239da270e68262728f125ea94b9b7d42d Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 1 Mar 2011 14:15:24 -0800 Subject: ipv4: Can final ip_route_connect() arg to boolean "can_sleep". Since that's what the current vague "flags" thing means. Signed-off-by: David S. Miller --- include/net/route.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index b3f89ad04e0b..5e0826d1c0e0 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -168,7 +168,7 @@ static inline char rt_tos2priority(u8 tos) static inline int ip_route_connect(struct rtable **rp, __be32 dst, __be32 src, u32 tos, int oif, u8 protocol, __be16 sport, __be16 dport, struct sock *sk, - int flags) + bool can_sleep) { struct flowi fl = { .oif = oif, .mark = sk->sk_mark, @@ -196,7 +196,7 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst, *rp = NULL; } security_sk_classify_flow(sk, &fl); - return ip_route_output_flow(net, rp, &fl, sk, flags); + return ip_route_output_flow(net, rp, &fl, sk, can_sleep ? 1 : 0); } static inline int ip_route_newports(struct rtable **rp, u8 protocol, -- cgit v1.2.2 From 420d44daa7aa1cc847e9e527f0a27a9ce61768ca Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 1 Mar 2011 14:19:23 -0800 Subject: ipv4: Make final arg to ip_route_output_flow to be boolean "can_sleep" Since that is what the current vague "flags" argument means. Signed-off-by: David S. Miller --- include/net/route.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index 5e0826d1c0e0..6de4333d6002 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -120,7 +120,7 @@ extern void rt_cache_flush(struct net *net, int how); extern void rt_cache_flush_batch(struct net *net); extern int __ip_route_output_key(struct net *, struct rtable **, const struct flowi *flp); extern int ip_route_output_key(struct net *, struct rtable **, struct flowi *flp); -extern int ip_route_output_flow(struct net *, struct rtable **rp, struct flowi *flp, struct sock *sk, int flags); +extern int ip_route_output_flow(struct net *, struct rtable **rp, struct flowi *flp, struct sock *sk, bool can_sleep); extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src, u8 tos, struct net_device *devin, bool noref); @@ -196,7 +196,7 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst, *rp = NULL; } security_sk_classify_flow(sk, &fl); - return ip_route_output_flow(net, rp, &fl, sk, can_sleep ? 1 : 0); + return ip_route_output_flow(net, rp, &fl, sk, can_sleep); } static inline int ip_route_newports(struct rtable **rp, u8 protocol, @@ -220,7 +220,7 @@ static inline int ip_route_newports(struct rtable **rp, u8 protocol, ip_rt_put(*rp); *rp = NULL; security_sk_classify_flow(sk, &fl); - return ip_route_output_flow(sock_net(sk), rp, &fl, sk, 0); + return ip_route_output_flow(sock_net(sk), rp, &fl, sk, false); } return 0; } -- cgit v1.2.2 From 5df65e5567a497a28067019b8ff08f98fb026629 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 1 Mar 2011 14:22:19 -0800 Subject: net: Add FLOWI_FLAG_CAN_SLEEP. And set is in contexts where the route resolution can sleep. Signed-off-by: David S. Miller --- include/net/route.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index 6de4333d6002..1be5c05a0905 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -185,6 +185,8 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst, fl.flags |= FLOWI_FLAG_ANYSRC; if (protocol == IPPROTO_TCP) fl.flags |= FLOWI_FLAG_PRECOW_METRICS; + if (can_sleep) + fl.flags |= FLOWI_FLAG_CAN_SLEEP; if (!dst || !src) { err = __ip_route_output_key(net, rp, &fl); -- cgit v1.2.2 From 273447b352e69c327efdecfd6e1d6fe3edbdcd14 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 1 Mar 2011 14:27:04 -0800 Subject: ipv4: Kill can_sleep arg to ip_route_output_flow() This boolean state is now available in the flow flags. Signed-off-by: David S. Miller --- include/net/route.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index 1be5c05a0905..923e670586d4 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -120,7 +120,7 @@ extern void rt_cache_flush(struct net *net, int how); extern void rt_cache_flush_batch(struct net *net); extern int __ip_route_output_key(struct net *, struct rtable **, const struct flowi *flp); extern int ip_route_output_key(struct net *, struct rtable **, struct flowi *flp); -extern int ip_route_output_flow(struct net *, struct rtable **rp, struct flowi *flp, struct sock *sk, bool can_sleep); +extern int ip_route_output_flow(struct net *, struct rtable **rp, struct flowi *flp, struct sock *sk); extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src, u8 tos, struct net_device *devin, bool noref); @@ -198,7 +198,7 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst, *rp = NULL; } security_sk_classify_flow(sk, &fl); - return ip_route_output_flow(net, rp, &fl, sk, can_sleep); + return ip_route_output_flow(net, rp, &fl, sk); } static inline int ip_route_newports(struct rtable **rp, u8 protocol, @@ -222,7 +222,7 @@ static inline int ip_route_newports(struct rtable **rp, u8 protocol, ip_rt_put(*rp); *rp = NULL; security_sk_classify_flow(sk, &fl); - return ip_route_output_flow(sock_net(sk), rp, &fl, sk, false); + return ip_route_output_flow(sock_net(sk), rp, &fl, sk); } return 0; } -- cgit v1.2.2 From 2774c131b1d19920b4587db1cfbd6f0750ad1f15 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 1 Mar 2011 14:59:04 -0800 Subject: xfrm: Handle blackhole route creation via afinfo. That way we don't have to potentially do this in every xfrm_lookup() caller. Signed-off-by: David S. Miller --- include/net/route.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index 923e670586d4..707cfc8eccdc 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -121,6 +121,7 @@ extern void rt_cache_flush_batch(struct net *net); extern int __ip_route_output_key(struct net *, struct rtable **, const struct flowi *flp); extern int ip_route_output_key(struct net *, struct rtable **, struct flowi *flp); extern int ip_route_output_flow(struct net *, struct rtable **rp, struct flowi *flp, struct sock *sk); +extern struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig); extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src, u8 tos, struct net_device *devin, bool noref); -- cgit v1.2.2 From b23dd4fe42b455af5c6e20966b7d6959fa8352ea Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 2 Mar 2011 14:31:35 -0800 Subject: ipv4: Make output route lookup return rtable directly. Instead of on the stack. Signed-off-by: David S. Miller --- include/net/route.h | 58 ++++++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index 707cfc8eccdc..088a1867348f 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -118,9 +118,10 @@ extern void ip_rt_redirect(__be32 old_gw, __be32 dst, __be32 new_gw, __be32 src, struct net_device *dev); extern void rt_cache_flush(struct net *net, int how); extern void rt_cache_flush_batch(struct net *net); -extern int __ip_route_output_key(struct net *, struct rtable **, const struct flowi *flp); -extern int ip_route_output_key(struct net *, struct rtable **, struct flowi *flp); -extern int ip_route_output_flow(struct net *, struct rtable **rp, struct flowi *flp, struct sock *sk); +extern struct rtable *__ip_route_output_key(struct net *, const struct flowi *flp); +extern struct rtable *ip_route_output_key(struct net *, struct flowi *flp); +extern struct rtable *ip_route_output_flow(struct net *, struct flowi *flp, + struct sock *sk); extern struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig); extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src, @@ -166,10 +167,10 @@ static inline char rt_tos2priority(u8 tos) return ip_tos2prio[IPTOS_TOS(tos)>>1]; } -static inline int ip_route_connect(struct rtable **rp, __be32 dst, - __be32 src, u32 tos, int oif, u8 protocol, - __be16 sport, __be16 dport, struct sock *sk, - bool can_sleep) +static inline struct rtable *ip_route_connect(__be32 dst, __be32 src, u32 tos, + int oif, u8 protocol, + __be16 sport, __be16 dport, + struct sock *sk, bool can_sleep) { struct flowi fl = { .oif = oif, .mark = sk->sk_mark, @@ -179,8 +180,8 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst, .proto = protocol, .fl_ip_sport = sport, .fl_ip_dport = dport }; - int err; struct net *net = sock_net(sk); + struct rtable *rt; if (inet_sk(sk)->transparent) fl.flags |= FLOWI_FLAG_ANYSRC; @@ -190,29 +191,29 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst, fl.flags |= FLOWI_FLAG_CAN_SLEEP; if (!dst || !src) { - err = __ip_route_output_key(net, rp, &fl); - if (err) - return err; - fl.fl4_dst = (*rp)->rt_dst; - fl.fl4_src = (*rp)->rt_src; - ip_rt_put(*rp); - *rp = NULL; + rt = __ip_route_output_key(net, &fl); + if (IS_ERR(rt)) + return rt; + fl.fl4_dst = rt->rt_dst; + fl.fl4_src = rt->rt_src; + ip_rt_put(rt); } security_sk_classify_flow(sk, &fl); - return ip_route_output_flow(net, rp, &fl, sk); + return ip_route_output_flow(net, &fl, sk); } -static inline int ip_route_newports(struct rtable **rp, u8 protocol, - __be16 orig_sport, __be16 orig_dport, - __be16 sport, __be16 dport, struct sock *sk) +static inline struct rtable *ip_route_newports(struct rtable *rt, + u8 protocol, __be16 orig_sport, + __be16 orig_dport, __be16 sport, + __be16 dport, struct sock *sk) { if (sport != orig_sport || dport != orig_dport) { - struct flowi fl = { .oif = (*rp)->fl.oif, - .mark = (*rp)->fl.mark, - .fl4_dst = (*rp)->fl.fl4_dst, - .fl4_src = (*rp)->fl.fl4_src, - .fl4_tos = (*rp)->fl.fl4_tos, - .proto = (*rp)->fl.proto, + struct flowi fl = { .oif = rt->fl.oif, + .mark = rt->fl.mark, + .fl4_dst = rt->fl.fl4_dst, + .fl4_src = rt->fl.fl4_src, + .fl4_tos = rt->fl.fl4_tos, + .proto = rt->fl.proto, .fl_ip_sport = sport, .fl_ip_dport = dport }; @@ -220,12 +221,11 @@ static inline int ip_route_newports(struct rtable **rp, u8 protocol, fl.flags |= FLOWI_FLAG_ANYSRC; if (protocol == IPPROTO_TCP) fl.flags |= FLOWI_FLAG_PRECOW_METRICS; - ip_rt_put(*rp); - *rp = NULL; + ip_rt_put(rt); security_sk_classify_flow(sk, &fl); - return ip_route_output_flow(sock_net(sk), rp, &fl, sk); + return ip_route_output_flow(sock_net(sk), &fl, sk); } - return 0; + return rt; } extern void rt_bind_peer(struct rtable *rt, int create); -- cgit v1.2.2 From 5bfa787fb2c29cce0722500f90df29e049ff07fc Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 2 Mar 2011 14:56:30 -0800 Subject: ipv4: ip_route_output_key() is better as an inline. This avoid a stack frame at zero cost. Signed-off-by: David S. Miller --- include/net/route.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index 088a1867348f..60daf745216a 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -119,11 +119,15 @@ extern void ip_rt_redirect(__be32 old_gw, __be32 dst, __be32 new_gw, extern void rt_cache_flush(struct net *net, int how); extern void rt_cache_flush_batch(struct net *net); extern struct rtable *__ip_route_output_key(struct net *, const struct flowi *flp); -extern struct rtable *ip_route_output_key(struct net *, struct flowi *flp); extern struct rtable *ip_route_output_flow(struct net *, struct flowi *flp, struct sock *sk); extern struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig); +static inline struct rtable *ip_route_output_key(struct net *net, struct flowi *flp) +{ + return ip_route_output_flow(net, flp, NULL); +} + extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src, u8 tos, struct net_device *devin, bool noref); -- cgit v1.2.2 From 4157434c23f8f5126a2ffd3cc7b2c3bd928be075 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 4 Mar 2011 21:31:48 -0800 Subject: ipv4: Use passed-in protocol in ip_route_newports(). Signed-off-by: David S. Miller --- include/net/route.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index 60daf745216a..8905d90e0044 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -217,7 +217,7 @@ static inline struct rtable *ip_route_newports(struct rtable *rt, .fl4_dst = rt->fl.fl4_dst, .fl4_src = rt->fl.fl4_src, .fl4_tos = rt->fl.fl4_tos, - .proto = rt->fl.proto, + .proto = protocol, .fl_ip_sport = sport, .fl_ip_dport = dport }; -- cgit v1.2.2 From 5e2b61f78411be25f0b84f97d5b5d312f184dfd1 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 4 Mar 2011 21:47:09 -0800 Subject: ipv4: Remove flowi from struct rtable. The only necessary parts are the src/dst addresses, the interface indexes, the TOS, and the mark. The rest is unnecessary bloat, which amounts to nearly 50 bytes on 64-bit. Signed-off-by: David S. Miller --- include/net/route.h | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index 8905d90e0044..9257f5f17337 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -53,16 +53,20 @@ struct fib_info; struct rtable { struct dst_entry dst; - /* Cache lookup keys */ - struct flowi fl; + /* Lookup key. */ + __be32 rt_key_dst; + __be32 rt_key_src; int rt_genid; unsigned rt_flags; __u16 rt_type; + __u8 rt_tos; __be32 rt_dst; /* Path destination */ __be32 rt_src; /* Path source */ int rt_iif; + int rt_oif; + __u32 rt_mark; /* Info on neighbour */ __be32 rt_gateway; @@ -76,12 +80,12 @@ struct rtable { static inline bool rt_is_input_route(struct rtable *rt) { - return rt->fl.iif != 0; + return rt->rt_iif != 0; } static inline bool rt_is_output_route(struct rtable *rt) { - return rt->fl.iif == 0; + return rt->rt_iif == 0; } struct ip_rt_acct { @@ -212,11 +216,11 @@ static inline struct rtable *ip_route_newports(struct rtable *rt, __be16 dport, struct sock *sk) { if (sport != orig_sport || dport != orig_dport) { - struct flowi fl = { .oif = rt->fl.oif, - .mark = rt->fl.mark, - .fl4_dst = rt->fl.fl4_dst, - .fl4_src = rt->fl.fl4_src, - .fl4_tos = rt->fl.fl4_tos, + struct flowi fl = { .oif = rt->rt_oif, + .mark = rt->rt_mark, + .fl4_dst = rt->rt_key_dst, + .fl4_src = rt->rt_key_src, + .fl4_tos = rt->rt_tos, .proto = protocol, .fl_ip_sport = sport, .fl_ip_dport = dport }; -- cgit v1.2.2 From 78fbfd8a653ca972afe479517a40661bfff6d8c3 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 12 Mar 2011 00:00:52 -0500 Subject: ipv4: Create and use route lookup helpers. The idea here is this minimizes the number of places one has to edit in order to make changes to how flows are defined and used. Signed-off-by: David S. Miller --- include/net/route.h | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index 9257f5f17337..f140f4130fea 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -132,6 +132,54 @@ static inline struct rtable *ip_route_output_key(struct net *net, struct flowi * return ip_route_output_flow(net, flp, NULL); } +static inline struct rtable *ip_route_output(struct net *net, __be32 daddr, + __be32 saddr, u8 tos, int oif) +{ + struct flowi fl = { + .oif = oif, + .fl4_dst = daddr, + .fl4_src = saddr, + .fl4_tos = tos, + }; + return ip_route_output_key(net, &fl); +} + +static inline struct rtable *ip_route_output_ports(struct net *net, struct sock *sk, + __be32 daddr, __be32 saddr, + __be16 dport, __be16 sport, + __u8 proto, __u8 tos, int oif) +{ + struct flowi fl = { + .oif = oif, + .flags = sk ? inet_sk_flowi_flags(sk) : 0, + .mark = sk ? sk->sk_mark : 0, + .fl4_dst = daddr, + .fl4_src = saddr, + .fl4_tos = tos, + .proto = proto, + .fl_ip_dport = dport, + .fl_ip_sport = sport, + }; + if (sk) + security_sk_classify_flow(sk, &fl); + return ip_route_output_flow(net, &fl, sk); +} + +static inline struct rtable *ip_route_output_gre(struct net *net, + __be32 daddr, __be32 saddr, + __be32 gre_key, __u8 tos, int oif) +{ + struct flowi fl = { + .oif = oif, + .fl4_dst = daddr, + .fl4_src = saddr, + .fl4_tos = tos, + .proto = IPPROTO_GRE, + .fl_gre_key = gre_key, + }; + return ip_route_output_key(net, &fl); +} + extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src, u8 tos, struct net_device *devin, bool noref); -- cgit v1.2.2 From 1d28f42c1bd4bb2363d88df74d0128b4da135b4a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 12 Mar 2011 00:29:39 -0500 Subject: net: Put flowi_* prefix on AF independent members of struct flowi I intend to turn struct flowi into a union of AF specific flowi structs. There will be a common structure that each variant includes first, much like struct sock_common. This is the first step to move in that direction. Signed-off-by: David S. Miller --- include/net/route.h | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index f140f4130fea..3d814f84abd0 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -136,7 +136,7 @@ static inline struct rtable *ip_route_output(struct net *net, __be32 daddr, __be32 saddr, u8 tos, int oif) { struct flowi fl = { - .oif = oif, + .flowi_oif = oif, .fl4_dst = daddr, .fl4_src = saddr, .fl4_tos = tos, @@ -150,13 +150,13 @@ static inline struct rtable *ip_route_output_ports(struct net *net, struct sock __u8 proto, __u8 tos, int oif) { struct flowi fl = { - .oif = oif, - .flags = sk ? inet_sk_flowi_flags(sk) : 0, - .mark = sk ? sk->sk_mark : 0, + .flowi_oif = oif, + .flowi_flags = sk ? inet_sk_flowi_flags(sk) : 0, + .flowi_mark = sk ? sk->sk_mark : 0, .fl4_dst = daddr, .fl4_src = saddr, .fl4_tos = tos, - .proto = proto, + .flowi_proto = proto, .fl_ip_dport = dport, .fl_ip_sport = sport, }; @@ -170,11 +170,11 @@ static inline struct rtable *ip_route_output_gre(struct net *net, __be32 gre_key, __u8 tos, int oif) { struct flowi fl = { - .oif = oif, + .flowi_oif = oif, .fl4_dst = daddr, .fl4_src = saddr, .fl4_tos = tos, - .proto = IPPROTO_GRE, + .flowi_proto = IPPROTO_GRE, .fl_gre_key = gre_key, }; return ip_route_output_key(net, &fl); @@ -228,23 +228,23 @@ static inline struct rtable *ip_route_connect(__be32 dst, __be32 src, u32 tos, __be16 sport, __be16 dport, struct sock *sk, bool can_sleep) { - struct flowi fl = { .oif = oif, - .mark = sk->sk_mark, + struct flowi fl = { .flowi_oif = oif, + .flowi_mark = sk->sk_mark, .fl4_dst = dst, .fl4_src = src, .fl4_tos = tos, - .proto = protocol, + .flowi_proto = protocol, .fl_ip_sport = sport, .fl_ip_dport = dport }; struct net *net = sock_net(sk); struct rtable *rt; if (inet_sk(sk)->transparent) - fl.flags |= FLOWI_FLAG_ANYSRC; + fl.flowi_flags |= FLOWI_FLAG_ANYSRC; if (protocol == IPPROTO_TCP) - fl.flags |= FLOWI_FLAG_PRECOW_METRICS; + fl.flowi_flags |= FLOWI_FLAG_PRECOW_METRICS; if (can_sleep) - fl.flags |= FLOWI_FLAG_CAN_SLEEP; + fl.flowi_flags |= FLOWI_FLAG_CAN_SLEEP; if (!dst || !src) { rt = __ip_route_output_key(net, &fl); @@ -264,19 +264,19 @@ static inline struct rtable *ip_route_newports(struct rtable *rt, __be16 dport, struct sock *sk) { if (sport != orig_sport || dport != orig_dport) { - struct flowi fl = { .oif = rt->rt_oif, - .mark = rt->rt_mark, + struct flowi fl = { .flowi_oif = rt->rt_oif, + .flowi_mark = rt->rt_mark, .fl4_dst = rt->rt_key_dst, .fl4_src = rt->rt_key_src, .fl4_tos = rt->rt_tos, - .proto = protocol, + .flowi_proto = protocol, .fl_ip_sport = sport, .fl_ip_dport = dport }; if (inet_sk(sk)->transparent) - fl.flags |= FLOWI_FLAG_ANYSRC; + fl.flowi_flags |= FLOWI_FLAG_ANYSRC; if (protocol == IPPROTO_TCP) - fl.flags |= FLOWI_FLAG_PRECOW_METRICS; + fl.flowi_flags |= FLOWI_FLAG_PRECOW_METRICS; ip_rt_put(rt); security_sk_classify_flow(sk, &fl); return ip_route_output_flow(sock_net(sk), &fl, sk); -- cgit v1.2.2 From 6281dcc94a96bd73017b2baa8fa83925405109ef Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 12 Mar 2011 00:43:55 -0500 Subject: net: Make flowi ports AF dependent. Create two sets of port member accessors, one set prefixed by fl4_* and the other prefixed by fl6_* This will let us to create AF optimal flow instances. It will work because every context in which we access the ports, we have to be fully aware of which AF the flowi is anyways. Signed-off-by: David S. Miller --- include/net/route.h | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index 3d814f84abd0..4c207f9fe0cb 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -157,8 +157,8 @@ static inline struct rtable *ip_route_output_ports(struct net *net, struct sock .fl4_src = saddr, .fl4_tos = tos, .flowi_proto = proto, - .fl_ip_dport = dport, - .fl_ip_sport = sport, + .fl4_dport = dport, + .fl4_sport = sport, }; if (sk) security_sk_classify_flow(sk, &fl); @@ -175,7 +175,7 @@ static inline struct rtable *ip_route_output_gre(struct net *net, .fl4_src = saddr, .fl4_tos = tos, .flowi_proto = IPPROTO_GRE, - .fl_gre_key = gre_key, + .fl4_gre_key = gre_key, }; return ip_route_output_key(net, &fl); } @@ -228,14 +228,16 @@ static inline struct rtable *ip_route_connect(__be32 dst, __be32 src, u32 tos, __be16 sport, __be16 dport, struct sock *sk, bool can_sleep) { - struct flowi fl = { .flowi_oif = oif, - .flowi_mark = sk->sk_mark, - .fl4_dst = dst, - .fl4_src = src, - .fl4_tos = tos, - .flowi_proto = protocol, - .fl_ip_sport = sport, - .fl_ip_dport = dport }; + struct flowi fl = { + .flowi_oif = oif, + .flowi_mark = sk->sk_mark, + .fl4_dst = dst, + .fl4_src = src, + .fl4_tos = tos, + .flowi_proto = protocol, + .fl4_sport = sport, + .fl4_dport = dport, + }; struct net *net = sock_net(sk); struct rtable *rt; @@ -264,15 +266,16 @@ static inline struct rtable *ip_route_newports(struct rtable *rt, __be16 dport, struct sock *sk) { if (sport != orig_sport || dport != orig_dport) { - struct flowi fl = { .flowi_oif = rt->rt_oif, - .flowi_mark = rt->rt_mark, - .fl4_dst = rt->rt_key_dst, - .fl4_src = rt->rt_key_src, - .fl4_tos = rt->rt_tos, - .flowi_proto = protocol, - .fl_ip_sport = sport, - .fl_ip_dport = dport }; - + struct flowi fl = { + .flowi_oif = rt->rt_oif, + .flowi_mark = rt->rt_mark, + .fl4_dst = rt->rt_key_dst, + .fl4_src = rt->rt_key_src, + .fl4_tos = rt->rt_tos, + .flowi_proto = protocol, + .fl4_sport = sport, + .fl4_dport = dport + }; if (inet_sk(sk)->transparent) fl.flowi_flags |= FLOWI_FLAG_ANYSRC; if (protocol == IPPROTO_TCP) -- cgit v1.2.2 From 9d6ec938019c6b16cb9ec96598ebe8f20de435fe Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 12 Mar 2011 01:12:47 -0500 Subject: ipv4: Use flowi4 in public route lookup interfaces. Signed-off-by: David S. Miller --- include/net/route.h | 118 ++++++++++++++++++++++++++-------------------------- 1 file changed, 59 insertions(+), 59 deletions(-) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index 4c207f9fe0cb..80b0353f4f41 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -122,12 +122,12 @@ extern void ip_rt_redirect(__be32 old_gw, __be32 dst, __be32 new_gw, __be32 src, struct net_device *dev); extern void rt_cache_flush(struct net *net, int how); extern void rt_cache_flush_batch(struct net *net); -extern struct rtable *__ip_route_output_key(struct net *, const struct flowi *flp); -extern struct rtable *ip_route_output_flow(struct net *, struct flowi *flp, +extern struct rtable *__ip_route_output_key(struct net *, const struct flowi4 *flp); +extern struct rtable *ip_route_output_flow(struct net *, struct flowi4 *flp, struct sock *sk); extern struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig); -static inline struct rtable *ip_route_output_key(struct net *net, struct flowi *flp) +static inline struct rtable *ip_route_output_key(struct net *net, struct flowi4 *flp) { return ip_route_output_flow(net, flp, NULL); } @@ -135,13 +135,13 @@ static inline struct rtable *ip_route_output_key(struct net *net, struct flowi * static inline struct rtable *ip_route_output(struct net *net, __be32 daddr, __be32 saddr, u8 tos, int oif) { - struct flowi fl = { - .flowi_oif = oif, - .fl4_dst = daddr, - .fl4_src = saddr, - .fl4_tos = tos, + struct flowi4 fl4 = { + .flowi4_oif = oif, + .daddr = daddr, + .saddr = saddr, + .flowi4_tos = tos, }; - return ip_route_output_key(net, &fl); + return ip_route_output_key(net, &fl4); } static inline struct rtable *ip_route_output_ports(struct net *net, struct sock *sk, @@ -149,35 +149,35 @@ static inline struct rtable *ip_route_output_ports(struct net *net, struct sock __be16 dport, __be16 sport, __u8 proto, __u8 tos, int oif) { - struct flowi fl = { - .flowi_oif = oif, - .flowi_flags = sk ? inet_sk_flowi_flags(sk) : 0, - .flowi_mark = sk ? sk->sk_mark : 0, - .fl4_dst = daddr, - .fl4_src = saddr, - .fl4_tos = tos, - .flowi_proto = proto, - .fl4_dport = dport, - .fl4_sport = sport, + struct flowi4 fl4 = { + .flowi4_oif = oif, + .flowi4_flags = sk ? inet_sk_flowi_flags(sk) : 0, + .flowi4_mark = sk ? sk->sk_mark : 0, + .daddr = daddr, + .saddr = saddr, + .flowi4_tos = tos, + .flowi4_proto = proto, + .uli.ports.dport = dport, + .uli.ports.sport = sport, }; if (sk) - security_sk_classify_flow(sk, &fl); - return ip_route_output_flow(net, &fl, sk); + security_sk_classify_flow(sk, flowi4_to_flowi(&fl4)); + return ip_route_output_flow(net, &fl4, sk); } static inline struct rtable *ip_route_output_gre(struct net *net, __be32 daddr, __be32 saddr, __be32 gre_key, __u8 tos, int oif) { - struct flowi fl = { - .flowi_oif = oif, - .fl4_dst = daddr, - .fl4_src = saddr, - .fl4_tos = tos, - .flowi_proto = IPPROTO_GRE, - .fl4_gre_key = gre_key, + struct flowi4 fl4 = { + .flowi4_oif = oif, + .daddr = daddr, + .saddr = saddr, + .flowi4_tos = tos, + .flowi4_proto = IPPROTO_GRE, + .uli.gre_key = gre_key, }; - return ip_route_output_key(net, &fl); + return ip_route_output_key(net, &fl4); } extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src, @@ -228,36 +228,36 @@ static inline struct rtable *ip_route_connect(__be32 dst, __be32 src, u32 tos, __be16 sport, __be16 dport, struct sock *sk, bool can_sleep) { - struct flowi fl = { - .flowi_oif = oif, - .flowi_mark = sk->sk_mark, - .fl4_dst = dst, - .fl4_src = src, - .fl4_tos = tos, - .flowi_proto = protocol, - .fl4_sport = sport, - .fl4_dport = dport, + struct flowi4 fl4 = { + .flowi4_oif = oif, + .flowi4_mark = sk->sk_mark, + .daddr = dst, + .saddr = src, + .flowi4_tos = tos, + .flowi4_proto = protocol, + .uli.ports.sport = sport, + .uli.ports.dport = dport, }; struct net *net = sock_net(sk); struct rtable *rt; if (inet_sk(sk)->transparent) - fl.flowi_flags |= FLOWI_FLAG_ANYSRC; + fl4.flowi4_flags |= FLOWI_FLAG_ANYSRC; if (protocol == IPPROTO_TCP) - fl.flowi_flags |= FLOWI_FLAG_PRECOW_METRICS; + fl4.flowi4_flags |= FLOWI_FLAG_PRECOW_METRICS; if (can_sleep) - fl.flowi_flags |= FLOWI_FLAG_CAN_SLEEP; + fl4.flowi4_flags |= FLOWI_FLAG_CAN_SLEEP; if (!dst || !src) { - rt = __ip_route_output_key(net, &fl); + rt = __ip_route_output_key(net, &fl4); if (IS_ERR(rt)) return rt; - fl.fl4_dst = rt->rt_dst; - fl.fl4_src = rt->rt_src; + fl4.daddr = rt->rt_dst; + fl4.saddr = rt->rt_src; ip_rt_put(rt); } - security_sk_classify_flow(sk, &fl); - return ip_route_output_flow(net, &fl, sk); + security_sk_classify_flow(sk, flowi4_to_flowi(&fl4)); + return ip_route_output_flow(net, &fl4, sk); } static inline struct rtable *ip_route_newports(struct rtable *rt, @@ -266,23 +266,23 @@ static inline struct rtable *ip_route_newports(struct rtable *rt, __be16 dport, struct sock *sk) { if (sport != orig_sport || dport != orig_dport) { - struct flowi fl = { - .flowi_oif = rt->rt_oif, - .flowi_mark = rt->rt_mark, - .fl4_dst = rt->rt_key_dst, - .fl4_src = rt->rt_key_src, - .fl4_tos = rt->rt_tos, - .flowi_proto = protocol, - .fl4_sport = sport, - .fl4_dport = dport + struct flowi4 fl4 = { + .flowi4_oif = rt->rt_oif, + .flowi4_mark = rt->rt_mark, + .daddr = rt->rt_key_dst, + .saddr = rt->rt_key_src, + .flowi4_tos = rt->rt_tos, + .flowi4_proto = protocol, + .uli.ports.sport = sport, + .uli.ports.dport = dport }; if (inet_sk(sk)->transparent) - fl.flowi_flags |= FLOWI_FLAG_ANYSRC; + fl4.flowi4_flags |= FLOWI_FLAG_ANYSRC; if (protocol == IPPROTO_TCP) - fl.flowi_flags |= FLOWI_FLAG_PRECOW_METRICS; + fl4.flowi4_flags |= FLOWI_FLAG_PRECOW_METRICS; ip_rt_put(rt); - security_sk_classify_flow(sk, &fl); - return ip_route_output_flow(sock_net(sk), &fl, sk); + security_sk_classify_flow(sk, flowi4_to_flowi(&fl4)); + return ip_route_output_flow(sock_net(sk), &fl4, sk); } return rt; } -- cgit v1.2.2 From 9cce96df5b76691712dba22e83ff5efe900361e1 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 12 Mar 2011 03:00:33 -0500 Subject: net: Put fl4_* macros to struct flowi4 and use them again. Signed-off-by: David S. Miller --- include/net/route.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index 80b0353f4f41..30d6cae3841a 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -157,8 +157,8 @@ static inline struct rtable *ip_route_output_ports(struct net *net, struct sock .saddr = saddr, .flowi4_tos = tos, .flowi4_proto = proto, - .uli.ports.dport = dport, - .uli.ports.sport = sport, + .fl4_dport = dport, + .fl4_sport = sport, }; if (sk) security_sk_classify_flow(sk, flowi4_to_flowi(&fl4)); @@ -175,7 +175,7 @@ static inline struct rtable *ip_route_output_gre(struct net *net, .saddr = saddr, .flowi4_tos = tos, .flowi4_proto = IPPROTO_GRE, - .uli.gre_key = gre_key, + .fl4_gre_key = gre_key, }; return ip_route_output_key(net, &fl4); } @@ -235,8 +235,8 @@ static inline struct rtable *ip_route_connect(__be32 dst, __be32 src, u32 tos, .saddr = src, .flowi4_tos = tos, .flowi4_proto = protocol, - .uli.ports.sport = sport, - .uli.ports.dport = dport, + .fl4_sport = sport, + .fl4_dport = dport, }; struct net *net = sock_net(sk); struct rtable *rt; @@ -273,8 +273,8 @@ static inline struct rtable *ip_route_newports(struct rtable *rt, .saddr = rt->rt_key_src, .flowi4_tos = rt->rt_tos, .flowi4_proto = protocol, - .uli.ports.sport = sport, - .uli.ports.dport = dport + .fl4_sport = sport, + .fl4_dport = dport }; if (inet_sk(sk)->transparent) fl4.flowi4_flags |= FLOWI_FLAG_ANYSRC; -- cgit v1.2.2 From e6abbaa2725a43cf5d26c4c2a5dc6c0f6029ea19 Mon Sep 17 00:00:00 2001 From: Julian Anastasov Date: Sat, 19 Mar 2011 12:13:49 +0000 Subject: ipv4: fix route deletion for IPs on many subnets Alex Sidorenko reported for problems with local routes left after IP addresses are deleted. It happens when same IPs are used in more than one subnet for the device. Fix fib_del_ifaddr to restrict the checks for duplicate local and broadcast addresses only to the IFAs that use our primary IFA or another primary IFA with same address. And we expect the prefsrc to be matched when the routes are deleted because it is possible they to differ only by prefsrc. This patch prevents local and broadcast routes to be leaked until their primary IP is deleted finally from the box. As the secondary address promotion needs to delete the routes for all secondaries that used the old primary IFA, add option to ignore these secondaries from the checks and to assume they are already deleted, so that we can safely delete the route while these IFAs are still on the device list. Reported-by: Alex Sidorenko Signed-off-by: Julian Anastasov Signed-off-by: David S. Miller --- include/net/route.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index 30d6cae3841a..dc102445ec47 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -207,6 +207,7 @@ extern int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb); struct in_ifaddr; extern void fib_add_ifaddr(struct in_ifaddr *); +extern void fib_del_ifaddr(struct in_ifaddr *, struct in_ifaddr *); static inline void ip_rt_put(struct rtable * rt) { -- cgit v1.2.2 From 6df59a84eccd4cad7fcefda3e0c5e55239a3b2dd Mon Sep 17 00:00:00 2001 From: Steffen Klassert Date: Fri, 25 Mar 2011 01:28:45 -0700 Subject: route: Take the right src and dst addresses in ip_route_newports When we set up the flow informations in ip_route_newports(), we take the address informations from the the rt_key_src and rt_key_dst fields of the rtable. They appear to be empty. So take the address informations from rt_src and rt_dst instead. This issue was introduced by commit 5e2b61f78411be25f0b84f97d5b5d312f184dfd1 ("ipv4: Remove flowi from struct rtable.") Signed-off-by: Steffen Klassert Signed-off-by: David S. Miller --- include/net/route.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index dc102445ec47..f88429cad52a 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -270,8 +270,8 @@ static inline struct rtable *ip_route_newports(struct rtable *rt, struct flowi4 fl4 = { .flowi4_oif = rt->rt_oif, .flowi4_mark = rt->rt_mark, - .daddr = rt->rt_key_dst, - .saddr = rt->rt_key_src, + .daddr = rt->rt_dst, + .saddr = rt->rt_src, .flowi4_tos = rt->rt_tos, .flowi4_proto = protocol, .fl4_sport = sport, -- cgit v1.2.2 From 94b92b88344641dbeadd2ef371549b7663a48fb1 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 31 Mar 2011 04:52:59 -0700 Subject: ipv4: Use flowi4_init_output() in net/route.h Signed-off-by: David S. Miller --- include/net/route.h | 60 +++++++++++++++++++++-------------------------------- 1 file changed, 24 insertions(+), 36 deletions(-) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index f88429cad52a..b24288595e58 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -149,17 +149,12 @@ static inline struct rtable *ip_route_output_ports(struct net *net, struct sock __be16 dport, __be16 sport, __u8 proto, __u8 tos, int oif) { - struct flowi4 fl4 = { - .flowi4_oif = oif, - .flowi4_flags = sk ? inet_sk_flowi_flags(sk) : 0, - .flowi4_mark = sk ? sk->sk_mark : 0, - .daddr = daddr, - .saddr = saddr, - .flowi4_tos = tos, - .flowi4_proto = proto, - .fl4_dport = dport, - .fl4_sport = sport, - }; + struct flowi4 fl4; + + flowi4_init_output(&fl4, oif, sk ? sk->sk_mark : 0, tos, + RT_SCOPE_UNIVERSE, proto, + sk ? inet_sk_flowi_flags(sk) : 0, + daddr, saddr, dport, sport); if (sk) security_sk_classify_flow(sk, flowi4_to_flowi(&fl4)); return ip_route_output_flow(net, &fl4, sk); @@ -229,25 +224,21 @@ static inline struct rtable *ip_route_connect(__be32 dst, __be32 src, u32 tos, __be16 sport, __be16 dport, struct sock *sk, bool can_sleep) { - struct flowi4 fl4 = { - .flowi4_oif = oif, - .flowi4_mark = sk->sk_mark, - .daddr = dst, - .saddr = src, - .flowi4_tos = tos, - .flowi4_proto = protocol, - .fl4_sport = sport, - .fl4_dport = dport, - }; struct net *net = sock_net(sk); struct rtable *rt; + struct flowi4 fl4; + __u8 flow_flags; + flow_flags = 0; if (inet_sk(sk)->transparent) - fl4.flowi4_flags |= FLOWI_FLAG_ANYSRC; + flow_flags |= FLOWI_FLAG_ANYSRC; if (protocol == IPPROTO_TCP) - fl4.flowi4_flags |= FLOWI_FLAG_PRECOW_METRICS; + flow_flags |= FLOWI_FLAG_PRECOW_METRICS; if (can_sleep) - fl4.flowi4_flags |= FLOWI_FLAG_CAN_SLEEP; + flow_flags |= FLOWI_FLAG_CAN_SLEEP; + + flowi4_init_output(&fl4, oif, sk->sk_mark, tos, RT_SCOPE_UNIVERSE, + protocol, flow_flags, dst, src, dport, sport); if (!dst || !src) { rt = __ip_route_output_key(net, &fl4); @@ -267,20 +258,17 @@ static inline struct rtable *ip_route_newports(struct rtable *rt, __be16 dport, struct sock *sk) { if (sport != orig_sport || dport != orig_dport) { - struct flowi4 fl4 = { - .flowi4_oif = rt->rt_oif, - .flowi4_mark = rt->rt_mark, - .daddr = rt->rt_dst, - .saddr = rt->rt_src, - .flowi4_tos = rt->rt_tos, - .flowi4_proto = protocol, - .fl4_sport = sport, - .fl4_dport = dport - }; + struct flowi4 fl4; + __u8 flow_flags; + + flow_flags = 0; if (inet_sk(sk)->transparent) - fl4.flowi4_flags |= FLOWI_FLAG_ANYSRC; + flow_flags |= FLOWI_FLAG_ANYSRC; if (protocol == IPPROTO_TCP) - fl4.flowi4_flags |= FLOWI_FLAG_PRECOW_METRICS; + flow_flags |= FLOWI_FLAG_PRECOW_METRICS; + flowi4_init_output(&fl4, rt->rt_oif, rt->rt_mark, rt->rt_tos, + RT_SCOPE_UNIVERSE, protocol, flow_flags, + rt->rt_dst, rt->rt_src, dport, sport); ip_rt_put(rt); security_sk_classify_flow(sk, flowi4_to_flowi(&fl4)); return ip_route_output_flow(sock_net(sk), &fl4, sk); -- cgit v1.2.2 From 1b86a58f9d7ce4fe2377687f378fbfb53bdc9b6c Mon Sep 17 00:00:00 2001 From: OGAWA Hirofumi Date: Thu, 7 Apr 2011 14:04:08 -0700 Subject: ipv4: Fix "Set rt->rt_iif more sanely on output routes." Commit 1018b5c01636c7c6bda31a719bda34fc631db29a ("Set rt->rt_iif more sanely on output routes.") breaks rt_is_{output,input}_route. This became the cause to return "IP_PKTINFO's ->ipi_ifindex == 0". To fix it, this does: 1) Add "int rt_route_iif;" to struct rtable 2) For input routes, always set rt_route_iif to same value as rt_iif 3) For output routes, always set rt_route_iif to zero. Set rt_iif as it is done currently. 4) Change rt_is_{output,input}_route() to test rt_route_iif Signed-off-by: OGAWA Hirofumi Signed-off-by: David S. Miller --- include/net/route.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index f88429cad52a..8fce0621cad1 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -64,6 +64,7 @@ struct rtable { __be32 rt_dst; /* Path destination */ __be32 rt_src; /* Path source */ + int rt_route_iif; int rt_iif; int rt_oif; __u32 rt_mark; @@ -80,12 +81,12 @@ struct rtable { static inline bool rt_is_input_route(struct rtable *rt) { - return rt->rt_iif != 0; + return rt->rt_route_iif != 0; } static inline bool rt_is_output_route(struct rtable *rt) { - return rt->rt_iif == 0; + return rt->rt_route_iif == 0; } struct ip_rt_acct { -- cgit v1.2.2 From b71d1d426d263b0b6cb5760322efebbfc89d4463 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 22 Apr 2011 04:53:02 +0000 Subject: inet: constify ip headers and in6_addr Add const qualifiers to structs iphdr, ipv6hdr and in6_addr pointers where possible, to make code intention more obvious. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/route.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index 3782cddd1383..b3962e249e14 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -191,7 +191,8 @@ static inline int ip_route_input_noref(struct sk_buff *skb, __be32 dst, __be32 s return ip_route_input_common(skb, dst, src, tos, devin, true); } -extern unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph, unsigned short new_mtu, struct net_device *dev); +extern unsigned short ip_rt_frag_needed(struct net *net, const struct iphdr *iph, + unsigned short new_mtu, struct net_device *dev); extern void ip_rt_send_redirect(struct sk_buff *skb); extern unsigned inet_addr_type(struct net *net, __be32 addr); -- cgit v1.2.2 From 2a9e9507011440a57d6356ded630ba0c0f5d4b77 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 24 Apr 2011 10:54:56 -0700 Subject: net: Remove __KERNEL__ cpp checks from include/net These header files are never installed to user consumption, so any __KERNEL__ cpp checks are superfluous. Projects should also not copy these files into their userland utility sources and try to use them there. If they insist on doing so, the onus is on them to sanitize the headers as needed. Signed-off-by: David S. Miller --- include/net/route.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index b3962e249e14..3684c3edbae4 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -35,10 +35,6 @@ #include #include -#ifndef __KERNEL__ -#warning This file is not supposed to be used outside of kernel. -#endif - #define RTO_ONLINK 0x01 #define RTO_CONN 0 -- cgit v1.2.2 From 2d7192d6cbab20e153c47fa1559ffd41ceef0e79 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 26 Apr 2011 13:28:44 -0700 Subject: ipv4: Sanitize and simplify ip_route_{connect,newports}() These functions are used together as a unit for route resolution during connect(). They address the chicken-and-egg problem that exists when ports need to be allocated during connect() processing, yet such port allocations require addressing information from the routing code. It's currently more heavy handed than it needs to be, and in particular we allocate and initialize a flow object twice. Let the callers provide the on-stack flow object. That way we only need to initialize it once in the ip_route_connect() call. Later, if ip_route_newports() needs to do anything, it re-uses that flow object as-is except for the ports which it updates before the route re-lookup. Also, describe why this set of facilities are needed and how it works in a big comment. Signed-off-by: David S. Miller Reviewed-by: Eric Dumazet --- include/net/route.h | 88 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 32 deletions(-) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index 3684c3edbae4..79530da31b34 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -217,17 +217,37 @@ static inline char rt_tos2priority(u8 tos) return ip_tos2prio[IPTOS_TOS(tos)>>1]; } -static inline struct rtable *ip_route_connect(__be32 dst, __be32 src, u32 tos, - int oif, u8 protocol, - __be16 sport, __be16 dport, - struct sock *sk, bool can_sleep) +/* ip_route_connect() and ip_route_newports() work in tandem whilst + * binding a socket for a new outgoing connection. + * + * In order to use IPSEC properly, we must, in the end, have a + * route that was looked up using all available keys including source + * and destination ports. + * + * However, if a source port needs to be allocated (the user specified + * a wildcard source port) we need to obtain addressing information + * in order to perform that allocation. + * + * So ip_route_connect() looks up a route using wildcarded source and + * destination ports in the key, simply so that we can get a pair of + * addresses to use for port allocation. + * + * Later, once the ports are allocated, ip_route_newports() will make + * another route lookup if needed to make sure we catch any IPSEC + * rules keyed on the port information. + * + * The callers allocate the flow key on their stack, and must pass in + * the same flowi4 object to both the ip_route_connect() and the + * ip_route_newports() calls. + */ + +static inline void ip_route_connect_init(struct flowi4 *fl4, __be32 dst, __be32 src, + u32 tos, int oif, u8 protocol, + __be16 sport, __be16 dport, + struct sock *sk, bool can_sleep) { - struct net *net = sock_net(sk); - struct rtable *rt; - struct flowi4 fl4; - __u8 flow_flags; + __u8 flow_flags = 0; - flow_flags = 0; if (inet_sk(sk)->transparent) flow_flags |= FLOWI_FLAG_ANYSRC; if (protocol == IPPROTO_TCP) @@ -235,41 +255,45 @@ static inline struct rtable *ip_route_connect(__be32 dst, __be32 src, u32 tos, if (can_sleep) flow_flags |= FLOWI_FLAG_CAN_SLEEP; - flowi4_init_output(&fl4, oif, sk->sk_mark, tos, RT_SCOPE_UNIVERSE, + flowi4_init_output(fl4, oif, sk->sk_mark, tos, RT_SCOPE_UNIVERSE, protocol, flow_flags, dst, src, dport, sport); +} + +static inline struct rtable *ip_route_connect(struct flowi4 *fl4, + __be32 dst, __be32 src, u32 tos, + int oif, u8 protocol, + __be16 sport, __be16 dport, + struct sock *sk, bool can_sleep) +{ + struct net *net = sock_net(sk); + struct rtable *rt; + + ip_route_connect_init(fl4, dst, src, tos, oif, protocol, + sport, dport, sk, can_sleep); if (!dst || !src) { - rt = __ip_route_output_key(net, &fl4); + rt = __ip_route_output_key(net, fl4); if (IS_ERR(rt)) return rt; - fl4.daddr = rt->rt_dst; - fl4.saddr = rt->rt_src; + fl4->daddr = rt->rt_dst; + fl4->saddr = rt->rt_src; ip_rt_put(rt); } - security_sk_classify_flow(sk, flowi4_to_flowi(&fl4)); - return ip_route_output_flow(net, &fl4, sk); + security_sk_classify_flow(sk, flowi4_to_flowi(fl4)); + return ip_route_output_flow(net, fl4, sk); } -static inline struct rtable *ip_route_newports(struct rtable *rt, - u8 protocol, __be16 orig_sport, - __be16 orig_dport, __be16 sport, - __be16 dport, struct sock *sk) +static inline struct rtable *ip_route_newports(struct flowi4 *fl4, struct rtable *rt, + __be16 orig_sport, __be16 orig_dport, + __be16 sport, __be16 dport, + struct sock *sk) { if (sport != orig_sport || dport != orig_dport) { - struct flowi4 fl4; - __u8 flow_flags; - - flow_flags = 0; - if (inet_sk(sk)->transparent) - flow_flags |= FLOWI_FLAG_ANYSRC; - if (protocol == IPPROTO_TCP) - flow_flags |= FLOWI_FLAG_PRECOW_METRICS; - flowi4_init_output(&fl4, rt->rt_oif, rt->rt_mark, rt->rt_tos, - RT_SCOPE_UNIVERSE, protocol, flow_flags, - rt->rt_dst, rt->rt_src, dport, sport); + fl4->fl4_dport = dport; + fl4->fl4_sport = sport; ip_rt_put(rt); - security_sk_classify_flow(sk, flowi4_to_flowi(&fl4)); - return ip_route_output_flow(sock_net(sk), &fl4, sk); + security_sk_classify_flow(sk, flowi4_to_flowi(fl4)); + return ip_route_output_flow(sock_net(sk), fl4, sk); } return rt; } -- cgit v1.2.2 From b678027cb77b079bc8e5b94172995d173bdb494b Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 26 Apr 2011 14:58:35 -0700 Subject: ipv4: Kill RTO_CONN. It's not used by anything in the kernel, and defined in net/route.h so never exported to userspace. Therefore we can safely remove it. Signed-off-by: David S. Miller --- include/net/route.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index 79530da31b34..fdbdb9271d7f 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -37,10 +37,6 @@ #define RTO_ONLINK 0x01 -#define RTO_CONN 0 -/* RTO_CONN is not used (being alias for 0), but preserved not to break - * some modules referring to it. */ - #define RT_CONN_FLAGS(sk) (RT_TOS(inet_sk(sk)->tos) | sock_flag(sk, SOCK_LOCALROUTE)) struct fib_nh; -- cgit v1.2.2 From 813b3b5db831ddbd92b5ce0fdeb74e3368f1323c Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 28 Apr 2011 14:48:42 -0700 Subject: ipv4: Use caller's on-stack flowi as-is in output route lookups. Signed-off-by: David S. Miller --- include/net/route.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index fdbdb9271d7f..81b6cf276549 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -115,7 +115,7 @@ extern void ip_rt_redirect(__be32 old_gw, __be32 dst, __be32 new_gw, __be32 src, struct net_device *dev); extern void rt_cache_flush(struct net *net, int how); extern void rt_cache_flush_batch(struct net *net); -extern struct rtable *__ip_route_output_key(struct net *, const struct flowi4 *flp); +extern struct rtable *__ip_route_output_key(struct net *, struct flowi4 *flp); extern struct rtable *ip_route_output_flow(struct net *, struct flowi4 *flp, struct sock *sk); extern struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig); -- cgit v1.2.2 From 6706b6ebab85dfca4e2886e35ec9c3c4ee13e27e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 28 Apr 2011 23:13:17 -0700 Subject: ipv4: Remove now superfluous code in ip_route_connect(). Now that output route lookups update the flow with source address et al. selections, the fl4->{saddr,daddr} assignments here are no longer necessary. Signed-off-by: David S. Miller --- include/net/route.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index 81b6cf276549..16eb59cd7080 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -271,8 +271,6 @@ static inline struct rtable *ip_route_connect(struct flowi4 *fl4, rt = __ip_route_output_key(net, fl4); if (IS_ERR(rt)) return rt; - fl4->daddr = rt->rt_dst; - fl4->saddr = rt->rt_src; ip_rt_put(rt); } security_sk_classify_flow(sk, flowi4_to_flowi(fl4)); -- cgit v1.2.2 From 475949d8e86bbde5ea3ffa4d95e022ca69233b14 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 3 May 2011 19:45:15 -0700 Subject: ipv4: Renamt struct rtable's rt_tos to rt_key_tos. To more accurately reflect that it is purely a routing cache lookup key and is used in no other context. Signed-off-by: David S. Miller --- include/net/route.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index 16eb59cd7080..f07609e83141 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -52,7 +52,7 @@ struct rtable { int rt_genid; unsigned rt_flags; __u16 rt_type; - __u8 rt_tos; + __u8 rt_key_tos; __be32 rt_dst; /* Path destination */ __be32 rt_src; /* Path source */ -- cgit v1.2.2 From 31e4543db29fb85496a122b965d6482c8d1a2bfe Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 3 May 2011 20:25:42 -0700 Subject: ipv4: Make caller provide on-stack flow key to ip_route_output_ports(). Signed-off-by: David S. Miller --- include/net/route.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index f07609e83141..8c02c871a8ce 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -137,20 +137,19 @@ static inline struct rtable *ip_route_output(struct net *net, __be32 daddr, return ip_route_output_key(net, &fl4); } -static inline struct rtable *ip_route_output_ports(struct net *net, struct sock *sk, +static inline struct rtable *ip_route_output_ports(struct net *net, struct flowi4 *fl4, + struct sock *sk, __be32 daddr, __be32 saddr, __be16 dport, __be16 sport, __u8 proto, __u8 tos, int oif) { - struct flowi4 fl4; - - flowi4_init_output(&fl4, oif, sk ? sk->sk_mark : 0, tos, + flowi4_init_output(fl4, oif, sk ? sk->sk_mark : 0, tos, RT_SCOPE_UNIVERSE, proto, sk ? inet_sk_flowi_flags(sk) : 0, daddr, saddr, dport, sport); if (sk) - security_sk_classify_flow(sk, flowi4_to_flowi(&fl4)); - return ip_route_output_flow(net, &fl4, sk); + security_sk_classify_flow(sk, flowi4_to_flowi(fl4)); + return ip_route_output_flow(net, fl4, sk); } static inline struct rtable *ip_route_output_gre(struct net *net, -- cgit v1.2.2 From cbb1e85f9cfd2bd9b7edfd21d167e89a4279faf0 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 4 May 2011 12:33:34 -0700 Subject: ipv4: Kill rt->rt_{src, dst} usage in IP GRE tunnels. First, make callers pass on-stack flowi4 to ip_route_output_gre() so they can get at the fully resolved flow key. Next, use that in ipgre_tunnel_xmit() to avoid the need to use rt->rt_{dst,src}. Signed-off-by: David S. Miller --- include/net/route.h | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index 8c02c871a8ce..9f8070b251fb 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -152,19 +152,18 @@ static inline struct rtable *ip_route_output_ports(struct net *net, struct flowi return ip_route_output_flow(net, fl4, sk); } -static inline struct rtable *ip_route_output_gre(struct net *net, +static inline struct rtable *ip_route_output_gre(struct net *net, struct flowi4 *fl4, __be32 daddr, __be32 saddr, __be32 gre_key, __u8 tos, int oif) { - struct flowi4 fl4 = { - .flowi4_oif = oif, - .daddr = daddr, - .saddr = saddr, - .flowi4_tos = tos, - .flowi4_proto = IPPROTO_GRE, - .fl4_gre_key = gre_key, - }; - return ip_route_output_key(net, &fl4); + memset(fl4, 0, sizeof(*fl4)); + fl4->flowi4_oif = oif; + fl4->daddr = daddr; + fl4->saddr = saddr; + fl4->flowi4_tos = tos; + fl4->flowi4_proto = IPPROTO_GRE; + fl4->fl4_gre_key = gre_key; + return ip_route_output_key(net, fl4); } extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src, -- cgit v1.2.2 From 8e36360ae876995e92d3a7538dda70548e64e685 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 13 May 2011 17:29:41 -0400 Subject: ipv4: Remove route key identity dependencies in ip_rt_get_source(). Pass in the sk_buff so that we can fetch the necessary keys from the packet header when working with input routes. Signed-off-by: David S. Miller --- include/net/route.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index 9f8070b251fb..ba0e0840370c 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -189,7 +189,7 @@ extern unsigned inet_addr_type(struct net *net, __be32 addr); extern unsigned inet_dev_addr_type(struct net *net, const struct net_device *dev, __be32 addr); extern void ip_rt_multicast_event(struct in_device *); extern int ip_rt_ioctl(struct net *, unsigned int cmd, void __user *arg); -extern void ip_rt_get_source(u8 *src, struct rtable *rt); +extern void ip_rt_get_source(u8 *src, struct sk_buff *skb, struct rtable *rt); extern int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb); struct in_ifaddr; -- cgit v1.2.2 From ed2361e66eec60645f8e4715fe39a42235ef43ae Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 18 May 2011 18:38:54 -0400 Subject: ipv4: Pass explicit destination address to rt_get_peer(). This will next trickle down to rt_bind_peer(). Signed-off-by: David S. Miller --- include/net/route.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index ba0e0840370c..600d0f2ef8d6 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -292,7 +292,7 @@ static inline struct rtable *ip_route_newports(struct flowi4 *fl4, struct rtable extern void rt_bind_peer(struct rtable *rt, int create); -static inline struct inet_peer *rt_get_peer(struct rtable *rt) +static inline struct inet_peer *rt_get_peer(struct rtable *rt, __be32 daddr) { if (rt->peer) return rt->peer; -- cgit v1.2.2 From a48eff128865aa20520fa6e0e0c5fbd2ac50d712 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 18 May 2011 18:42:43 -0400 Subject: ipv4: Pass explicit destination address to rt_bind_peer(). Signed-off-by: David S. Miller --- include/net/route.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/net/route.h') diff --git a/include/net/route.h b/include/net/route.h index 600d0f2ef8d6..db7b3432f07c 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -290,14 +290,14 @@ static inline struct rtable *ip_route_newports(struct flowi4 *fl4, struct rtable return rt; } -extern void rt_bind_peer(struct rtable *rt, int create); +extern void rt_bind_peer(struct rtable *rt, __be32 daddr, int create); static inline struct inet_peer *rt_get_peer(struct rtable *rt, __be32 daddr) { if (rt->peer) return rt->peer; - rt_bind_peer(rt, 0); + rt_bind_peer(rt, daddr, 0); return rt->peer; } -- cgit v1.2.2