Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 33078
b: refs/heads/master
c: 497c615
h: refs/heads/master
v: v3
  • Loading branch information
Herbert Xu authored and David S. Miller committed Aug 2, 2006
1 parent 91da7cf commit fd43235
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 50 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 679e898a4742d4a4a47430b67fd68a789a73dcfd
refs/heads/master: 497c615abad7ee81994dd592194535aea2aad617
12 changes: 9 additions & 3 deletions trunk/include/net/ip6_route.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,16 +139,22 @@ extern rwlock_t rt6_lock;
/*
* Store a destination cache entry in a socket
*/
static inline void ip6_dst_store(struct sock *sk, struct dst_entry *dst,
struct in6_addr *daddr)
static inline void __ip6_dst_store(struct sock *sk, struct dst_entry *dst,
struct in6_addr *daddr)
{
struct ipv6_pinfo *np = inet6_sk(sk);
struct rt6_info *rt = (struct rt6_info *) dst;

write_lock(&sk->sk_dst_lock);
sk_setup_caps(sk, dst);
np->daddr_cache = daddr;
np->dst_cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0;
}

static inline void ip6_dst_store(struct sock *sk, struct dst_entry *dst,
struct in6_addr *daddr)
{
write_lock(&sk->sk_dst_lock);
__ip6_dst_store(sk, dst, daddr);
write_unlock(&sk->sk_dst_lock);
}

Expand Down
3 changes: 3 additions & 0 deletions trunk/include/net/ipv6.h
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,9 @@ extern void ip6_flush_pending_frames(struct sock *sk);
extern int ip6_dst_lookup(struct sock *sk,
struct dst_entry **dst,
struct flowi *fl);
extern int ip6_sk_dst_lookup(struct sock *sk,
struct dst_entry **dst,
struct flowi *fl);

/*
* skb processing functions
Expand Down
4 changes: 2 additions & 2 deletions trunk/net/dccp/ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
ipv6_addr_copy(&np->saddr, saddr);
inet->rcv_saddr = LOOPBACK4_IPV6;

ip6_dst_store(sk, dst, NULL);
__ip6_dst_store(sk, dst, NULL);

icsk->icsk_ext_hdr_len = 0;
if (np->opt != NULL)
Expand Down Expand Up @@ -863,7 +863,7 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
* comment in that function for the gory details. -acme
*/

ip6_dst_store(newsk, dst, NULL);
__ip6_dst_store(newsk, dst, NULL);
newsk->sk_route_caps = dst->dev->features & ~(NETIF_F_IP_CSUM |
NETIF_F_TSO);
newdp6 = (struct dccp6_sock *)newsk;
Expand Down
2 changes: 1 addition & 1 deletion trunk/net/ipv6/af_inet6.c
Original file line number Diff line number Diff line change
Expand Up @@ -658,7 +658,7 @@ int inet6_sk_rebuild_header(struct sock *sk)
return err;
}

ip6_dst_store(sk, dst, NULL);
__ip6_dst_store(sk, dst, NULL);
}

return 0;
Expand Down
2 changes: 1 addition & 1 deletion trunk/net/ipv6/inet6_connection_sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ int inet6_csk_xmit(struct sk_buff *skb, int ipfragok)
return err;
}

ip6_dst_store(sk, dst, NULL);
__ip6_dst_store(sk, dst, NULL);
}

skb->dst = dst_clone(dst);
Expand Down
120 changes: 81 additions & 39 deletions trunk/net/ipv6/ip6_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -723,48 +723,51 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
return err;
}

int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl)
static struct dst_entry *ip6_sk_dst_check(struct sock *sk,
struct dst_entry *dst,
struct flowi *fl)
{
int err = 0;
struct ipv6_pinfo *np = inet6_sk(sk);
struct rt6_info *rt = (struct rt6_info *)dst;

*dst = NULL;
if (sk) {
struct ipv6_pinfo *np = inet6_sk(sk);

*dst = sk_dst_check(sk, np->dst_cookie);
if (*dst) {
struct rt6_info *rt = (struct rt6_info*)*dst;

/* Yes, checking route validity in not connected
* case is not very simple. Take into account,
* that we do not support routing by source, TOS,
* and MSG_DONTROUTE --ANK (980726)
*
* 1. If route was host route, check that
* cached destination is current.
* If it is network route, we still may
* check its validity using saved pointer
* to the last used address: daddr_cache.
* We do not want to save whole address now,
* (because main consumer of this service
* is tcp, which has not this problem),
* so that the last trick works only on connected
* sockets.
* 2. oif also should be the same.
*/
if (((rt->rt6i_dst.plen != 128 ||
!ipv6_addr_equal(&fl->fl6_dst,
&rt->rt6i_dst.addr))
&& (np->daddr_cache == NULL ||
!ipv6_addr_equal(&fl->fl6_dst,
np->daddr_cache)))
|| (fl->oif && fl->oif != (*dst)->dev->ifindex)) {
dst_release(*dst);
*dst = NULL;
}
}
if (!dst)
goto out;

/* Yes, checking route validity in not connected
* case is not very simple. Take into account,
* that we do not support routing by source, TOS,
* and MSG_DONTROUTE --ANK (980726)
*
* 1. If route was host route, check that
* cached destination is current.
* If it is network route, we still may
* check its validity using saved pointer
* to the last used address: daddr_cache.
* We do not want to save whole address now,
* (because main consumer of this service
* is tcp, which has not this problem),
* so that the last trick works only on connected
* sockets.
* 2. oif also should be the same.
*/
if (((rt->rt6i_dst.plen != 128 ||
!ipv6_addr_equal(&fl->fl6_dst, &rt->rt6i_dst.addr))
&& (np->daddr_cache == NULL ||
!ipv6_addr_equal(&fl->fl6_dst, np->daddr_cache)))
|| (fl->oif && fl->oif != dst->dev->ifindex)) {
dst_release(dst);
dst = NULL;
}

out:
return dst;
}

static int ip6_dst_lookup_tail(struct sock *sk,
struct dst_entry **dst, struct flowi *fl)
{
int err;

if (*dst == NULL)
*dst = ip6_route_output(sk, fl);

Expand All @@ -773,7 +776,6 @@ int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl)

if (ipv6_addr_any(&fl->fl6_src)) {
err = ipv6_get_saddr(*dst, &fl->fl6_dst, &fl->fl6_src);

if (err)
goto out_err_release;
}
Expand All @@ -786,8 +788,48 @@ int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl)
return err;
}

/**
* ip6_dst_lookup - perform route lookup on flow
* @sk: socket which provides route info
* @dst: pointer to dst_entry * for result
* @fl: flow to lookup
*
* This function performs a route lookup on the given flow.
*
* It returns zero on success, or a standard errno code on error.
*/
int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl)
{
*dst = NULL;
return ip6_dst_lookup_tail(sk, dst, fl);
}
EXPORT_SYMBOL_GPL(ip6_dst_lookup);

/**
* ip6_sk_dst_lookup - perform socket cached route lookup on flow
* @sk: socket which provides the dst cache and route info
* @dst: pointer to dst_entry * for result
* @fl: flow to lookup
*
* 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.
*
* It returns zero on success, or a standard errno code on error.
*/
int ip6_sk_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl)
{
*dst = NULL;
if (sk) {
*dst = sk_dst_check(sk, inet6_sk(sk)->dst_cookie);
*dst = ip6_sk_dst_check(sk, *dst, fl);
}

return ip6_dst_lookup_tail(sk, dst, fl);
}
EXPORT_SYMBOL_GPL(ip6_sk_dst_lookup);

static inline int ip6_ufo_append_data(struct sock *sk,
int getfrag(void *from, char *to, int offset, int len,
int odd, struct sk_buff *skb),
Expand Down
4 changes: 2 additions & 2 deletions trunk/net/ipv6/tcp_ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
inet->rcv_saddr = LOOPBACK4_IPV6;

sk->sk_gso_type = SKB_GSO_TCPV6;
ip6_dst_store(sk, dst, NULL);
__ip6_dst_store(sk, dst, NULL);

icsk->icsk_ext_hdr_len = 0;
if (np->opt)
Expand Down Expand Up @@ -947,7 +947,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
*/

sk->sk_gso_type = SKB_GSO_TCPV6;
ip6_dst_store(newsk, dst, NULL);
__ip6_dst_store(newsk, dst, NULL);

newtcp6sk = (struct tcp6_sock *)newsk;
inet_sk(newsk)->pinet6 = &newtcp6sk->inet6;
Expand Down
2 changes: 1 addition & 1 deletion trunk/net/ipv6/udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -782,7 +782,7 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
connected = 0;
}

err = ip6_dst_lookup(sk, &dst, fl);
err = ip6_sk_dst_lookup(sk, &dst, fl);
if (err)
goto out;
if (final_p)
Expand Down

0 comments on commit fd43235

Please sign in to comment.