ipv6: allow to cache dst for a connected sk in ip6_sk_dst_lookup_flow()
Add 'connected' parameter to ip6_sk_dst_lookup_flow() and update the cache only if ip6_sk_dst_check() returns NULL and a socket is connected. The function is used as before, the new behavior for UDP sockets in udpv6_sendmsg() will be enabled in the next patch. Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
7d6850f7c6
Коммит
96818159c3
|
@ -965,7 +965,8 @@ int ip6_dst_lookup(struct net *net, struct sock *sk, struct dst_entry **dst,
|
|||
struct dst_entry *ip6_dst_lookup_flow(const struct sock *sk, struct flowi6 *fl6,
|
||||
const struct in6_addr *final_dst);
|
||||
struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6,
|
||||
const struct in6_addr *final_dst);
|
||||
const struct in6_addr *final_dst,
|
||||
bool connected);
|
||||
struct dst_entry *ip6_blackhole_route(struct net *net,
|
||||
struct dst_entry *orig_dst);
|
||||
|
||||
|
|
|
@ -1105,23 +1105,32 @@ EXPORT_SYMBOL_GPL(ip6_dst_lookup_flow);
|
|||
* @sk: socket which provides the dst cache and route info
|
||||
* @fl6: flow to lookup
|
||||
* @final_dst: final destination address for ipsec lookup
|
||||
* @connected: whether @sk is connected or not
|
||||
*
|
||||
* This function performs a route lookup on the given flow with the
|
||||
* possibility of using the cached route in the socket if it is valid.
|
||||
* It will take the socket dst lock when operating on the dst cache.
|
||||
* As a result, this function can only be used in process context.
|
||||
*
|
||||
* In addition, for a connected socket, cache the dst in the socket
|
||||
* if the current cache is not valid.
|
||||
*
|
||||
* It returns a valid dst pointer on success, or a pointer encoded
|
||||
* error code.
|
||||
*/
|
||||
struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6,
|
||||
const struct in6_addr *final_dst)
|
||||
const struct in6_addr *final_dst,
|
||||
bool connected)
|
||||
{
|
||||
struct dst_entry *dst = sk_dst_check(sk, inet6_sk(sk)->dst_cookie);
|
||||
|
||||
dst = ip6_sk_dst_check(sk, dst, fl6);
|
||||
if (!dst)
|
||||
dst = ip6_dst_lookup_flow(sk, fl6, final_dst);
|
||||
if (dst)
|
||||
return dst;
|
||||
|
||||
dst = ip6_dst_lookup_flow(sk, fl6, final_dst);
|
||||
if (connected && !IS_ERR(dst))
|
||||
ip6_sk_dst_store_flow(sk, dst_clone(dst), fl6);
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
|
|
@ -121,7 +121,7 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
|||
ipc6.tclass = np->tclass;
|
||||
fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel);
|
||||
|
||||
dst = ip6_sk_dst_lookup_flow(sk, &fl6, daddr);
|
||||
dst = ip6_sk_dst_lookup_flow(sk, &fl6, daddr, false);
|
||||
if (IS_ERR(dst))
|
||||
return PTR_ERR(dst);
|
||||
rt = (struct rt6_info *) dst;
|
||||
|
|
|
@ -1308,7 +1308,7 @@ do_udp_sendmsg:
|
|||
|
||||
fl6.flowlabel = ip6_make_flowinfo(ipc6.tclass, fl6.flowlabel);
|
||||
|
||||
dst = ip6_sk_dst_lookup_flow(sk, &fl6, final_p);
|
||||
dst = ip6_sk_dst_lookup_flow(sk, &fl6, final_p, false);
|
||||
if (IS_ERR(dst)) {
|
||||
err = PTR_ERR(dst);
|
||||
dst = NULL;
|
||||
|
|
Загрузка…
Ссылка в новой задаче