ipv6: Remove external dependency on rt6i_dst and rt6i_src
This patch removes the assumptions that the returned rt is always a RTF_CACHE entry with the rt6i_dst and rt6i_src containing the destination and source address. The dst and src can be recovered from the calling site. We may consider to rename (rt6i_dst, rt6i_src) to (rt6i_key_dst, rt6i_key_src) later. Signed-off-by: Martin KaFai Lau <kafai@fb.com> Reviewed-by: Hannes Frederic Sowa <hannes@stressinduktion.org> Cc: Steffen Klassert <steffen.klassert@secunet.com> Cc: Julian Anastasov <ja@ssi.bg> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
286c2349f6
commit
fd0273d793
@ -728,7 +728,7 @@ static struct cxgbi_sock *cxgbi_check_route6(struct sockaddr *dst_addr)
|
|||||||
}
|
}
|
||||||
ndev = n->dev;
|
ndev = n->dev;
|
||||||
|
|
||||||
if (ipv6_addr_is_multicast(&rt->rt6i_dst.addr)) {
|
if (ipv6_addr_is_multicast(&daddr6->sin6_addr)) {
|
||||||
pr_info("multi-cast route %pI6 port %u, dev %s.\n",
|
pr_info("multi-cast route %pI6 port %u, dev %s.\n",
|
||||||
daddr6->sin6_addr.s6_addr,
|
daddr6->sin6_addr.s6_addr,
|
||||||
ntohs(daddr6->sin6_port), ndev->name);
|
ntohs(daddr6->sin6_port), ndev->name);
|
||||||
|
@ -671,7 +671,9 @@ static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_add
|
|||||||
return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr));
|
return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 ipv6_select_ident(struct net *net, struct rt6_info *rt);
|
u32 ipv6_select_ident(struct net *net,
|
||||||
|
const struct in6_addr *daddr,
|
||||||
|
const struct in6_addr *saddr);
|
||||||
void ipv6_proxy_select_ident(struct net *net, struct sk_buff *skb);
|
void ipv6_proxy_select_ident(struct net *net, struct sk_buff *skb);
|
||||||
|
|
||||||
int ip6_dst_hoplimit(struct dst_entry *dst);
|
int ip6_dst_hoplimit(struct dst_entry *dst);
|
||||||
|
@ -207,7 +207,7 @@ static bool icmpv6_xrlim_allow(struct sock *sk, u8 type,
|
|||||||
struct inet_peer *peer;
|
struct inet_peer *peer;
|
||||||
|
|
||||||
peer = inet_getpeer_v6(net->ipv6.peers,
|
peer = inet_getpeer_v6(net->ipv6.peers,
|
||||||
&rt->rt6i_dst.addr, 1);
|
&fl6->daddr, 1);
|
||||||
res = inet_peer_xrlim_allow(peer, tmo);
|
res = inet_peer_xrlim_allow(peer, tmo);
|
||||||
if (peer)
|
if (peer)
|
||||||
inet_putpeer(peer);
|
inet_putpeer(peer);
|
||||||
|
@ -459,7 +459,7 @@ int ip6_forward(struct sk_buff *skb)
|
|||||||
else
|
else
|
||||||
target = &hdr->daddr;
|
target = &hdr->daddr;
|
||||||
|
|
||||||
peer = inet_getpeer_v6(net->ipv6.peers, &rt->rt6i_dst.addr, 1);
|
peer = inet_getpeer_v6(net->ipv6.peers, &hdr->daddr, 1);
|
||||||
|
|
||||||
/* Limit redirects both by destination (here)
|
/* Limit redirects both by destination (here)
|
||||||
and by source (inside ndisc_send_redirect)
|
and by source (inside ndisc_send_redirect)
|
||||||
@ -584,7 +584,8 @@ int ip6_fragment(struct sock *sk, struct sk_buff *skb,
|
|||||||
}
|
}
|
||||||
mtu -= hlen + sizeof(struct frag_hdr);
|
mtu -= hlen + sizeof(struct frag_hdr);
|
||||||
|
|
||||||
frag_id = ipv6_select_ident(net, rt);
|
frag_id = ipv6_select_ident(net, &ipv6_hdr(skb)->daddr,
|
||||||
|
&ipv6_hdr(skb)->saddr);
|
||||||
|
|
||||||
if (skb_has_frag_list(skb)) {
|
if (skb_has_frag_list(skb)) {
|
||||||
int first_len = skb_pagelen(skb);
|
int first_len = skb_pagelen(skb);
|
||||||
@ -1057,7 +1058,7 @@ static inline int ip6_ufo_append_data(struct sock *sk,
|
|||||||
int odd, struct sk_buff *skb),
|
int odd, struct sk_buff *skb),
|
||||||
void *from, int length, int hh_len, int fragheaderlen,
|
void *from, int length, int hh_len, int fragheaderlen,
|
||||||
int transhdrlen, int mtu, unsigned int flags,
|
int transhdrlen, int mtu, unsigned int flags,
|
||||||
struct rt6_info *rt)
|
const struct flowi6 *fl6)
|
||||||
|
|
||||||
{
|
{
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
@ -1102,7 +1103,9 @@ static inline int ip6_ufo_append_data(struct sock *sk,
|
|||||||
skb_shinfo(skb)->gso_size = (mtu - fragheaderlen -
|
skb_shinfo(skb)->gso_size = (mtu - fragheaderlen -
|
||||||
sizeof(struct frag_hdr)) & ~7;
|
sizeof(struct frag_hdr)) & ~7;
|
||||||
skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
|
skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
|
||||||
skb_shinfo(skb)->ip6_frag_id = ipv6_select_ident(sock_net(sk), rt);
|
skb_shinfo(skb)->ip6_frag_id = ipv6_select_ident(sock_net(sk),
|
||||||
|
&fl6->daddr,
|
||||||
|
&fl6->saddr);
|
||||||
|
|
||||||
append:
|
append:
|
||||||
return skb_append_datato_frags(sk, skb, getfrag, from,
|
return skb_append_datato_frags(sk, skb, getfrag, from,
|
||||||
@ -1327,7 +1330,7 @@ static int __ip6_append_data(struct sock *sk,
|
|||||||
(sk->sk_type == SOCK_DGRAM)) {
|
(sk->sk_type == SOCK_DGRAM)) {
|
||||||
err = ip6_ufo_append_data(sk, queue, getfrag, from, length,
|
err = ip6_ufo_append_data(sk, queue, getfrag, from, length,
|
||||||
hh_len, fragheaderlen,
|
hh_len, fragheaderlen,
|
||||||
transhdrlen, mtu, flags, rt);
|
transhdrlen, mtu, flags, fl6);
|
||||||
if (err)
|
if (err)
|
||||||
goto error;
|
goto error;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1506,7 +1506,7 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
|
|||||||
"Redirect: destination is not a neighbour\n");
|
"Redirect: destination is not a neighbour\n");
|
||||||
goto release;
|
goto release;
|
||||||
}
|
}
|
||||||
peer = inet_getpeer_v6(net->ipv6.peers, &rt->rt6i_dst.addr, 1);
|
peer = inet_getpeer_v6(net->ipv6.peers, &ipv6_hdr(skb)->saddr, 1);
|
||||||
ret = inet_peer_xrlim_allow(peer, 1*HZ);
|
ret = inet_peer_xrlim_allow(peer, 1*HZ);
|
||||||
if (peer)
|
if (peer)
|
||||||
inet_putpeer(peer);
|
inet_putpeer(peer);
|
||||||
|
@ -10,7 +10,8 @@
|
|||||||
#include <net/secure_seq.h>
|
#include <net/secure_seq.h>
|
||||||
|
|
||||||
static u32 __ipv6_select_ident(struct net *net, u32 hashrnd,
|
static u32 __ipv6_select_ident(struct net *net, u32 hashrnd,
|
||||||
struct in6_addr *dst, struct in6_addr *src)
|
const struct in6_addr *dst,
|
||||||
|
const struct in6_addr *src)
|
||||||
{
|
{
|
||||||
u32 hash, id;
|
u32 hash, id;
|
||||||
|
|
||||||
@ -60,15 +61,16 @@ void ipv6_proxy_select_ident(struct net *net, struct sk_buff *skb)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(ipv6_proxy_select_ident);
|
EXPORT_SYMBOL_GPL(ipv6_proxy_select_ident);
|
||||||
|
|
||||||
u32 ipv6_select_ident(struct net *net, struct rt6_info *rt)
|
u32 ipv6_select_ident(struct net *net,
|
||||||
|
const struct in6_addr *daddr,
|
||||||
|
const struct in6_addr *saddr)
|
||||||
{
|
{
|
||||||
static u32 ip6_idents_hashrnd __read_mostly;
|
static u32 ip6_idents_hashrnd __read_mostly;
|
||||||
u32 id;
|
u32 id;
|
||||||
|
|
||||||
net_get_random_once(&ip6_idents_hashrnd, sizeof(ip6_idents_hashrnd));
|
net_get_random_once(&ip6_idents_hashrnd, sizeof(ip6_idents_hashrnd));
|
||||||
|
|
||||||
id = __ipv6_select_ident(net, ip6_idents_hashrnd, &rt->rt6i_dst.addr,
|
id = __ipv6_select_ident(net, ip6_idents_hashrnd, daddr, saddr);
|
||||||
&rt->rt6i_src.addr);
|
|
||||||
return htonl(id);
|
return htonl(id);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ipv6_select_ident);
|
EXPORT_SYMBOL(ipv6_select_ident);
|
||||||
|
@ -262,7 +262,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
|
|||||||
rt = (struct rt6_info *) dst;
|
rt = (struct rt6_info *) dst;
|
||||||
if (tcp_death_row.sysctl_tw_recycle &&
|
if (tcp_death_row.sysctl_tw_recycle &&
|
||||||
!tp->rx_opt.ts_recent_stamp &&
|
!tp->rx_opt.ts_recent_stamp &&
|
||||||
ipv6_addr_equal(&rt->rt6i_dst.addr, &sk->sk_v6_daddr))
|
ipv6_addr_equal(&fl6.daddr, &sk->sk_v6_daddr))
|
||||||
tcp_fetch_timewait_stamp(sk, dst);
|
tcp_fetch_timewait_stamp(sk, dst);
|
||||||
|
|
||||||
icsk->icsk_ext_hdr_len = 0;
|
icsk->icsk_ext_hdr_len = 0;
|
||||||
|
@ -781,7 +781,7 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
|
|||||||
|
|
||||||
/* From world but DNAT to loopback address? */
|
/* From world but DNAT to loopback address? */
|
||||||
if (local && skb->dev && !(skb->dev->flags & IFF_LOOPBACK) &&
|
if (local && skb->dev && !(skb->dev->flags & IFF_LOOPBACK) &&
|
||||||
ipv6_addr_type(&rt->rt6i_dst.addr) & IPV6_ADDR_LOOPBACK) {
|
ipv6_addr_type(&cp->daddr.in6) & IPV6_ADDR_LOOPBACK) {
|
||||||
IP_VS_DBG_RL_PKT(1, AF_INET6, pp, skb, 0,
|
IP_VS_DBG_RL_PKT(1, AF_INET6, pp, skb, 0,
|
||||||
"ip_vs_nat_xmit_v6(): "
|
"ip_vs_nat_xmit_v6(): "
|
||||||
"stopping DNAT to loopback address");
|
"stopping DNAT to loopback address");
|
||||||
@ -1346,7 +1346,7 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
|
|||||||
|
|
||||||
/* From world but DNAT to loopback address? */
|
/* From world but DNAT to loopback address? */
|
||||||
if (local && skb->dev && !(skb->dev->flags & IFF_LOOPBACK) &&
|
if (local && skb->dev && !(skb->dev->flags & IFF_LOOPBACK) &&
|
||||||
ipv6_addr_type(&rt->rt6i_dst.addr) & IPV6_ADDR_LOOPBACK) {
|
ipv6_addr_type(&cp->daddr.in6) & IPV6_ADDR_LOOPBACK) {
|
||||||
IP_VS_DBG(1, "%s(): "
|
IP_VS_DBG(1, "%s(): "
|
||||||
"stopping DNAT to loopback %pI6\n",
|
"stopping DNAT to loopback %pI6\n",
|
||||||
__func__, &cp->daddr.in6);
|
__func__, &cp->daddr.in6);
|
||||||
|
@ -332,7 +332,8 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
|
|||||||
rt = (struct rt6_info *)dst;
|
rt = (struct rt6_info *)dst;
|
||||||
t->dst = dst;
|
t->dst = dst;
|
||||||
t->dst_cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0;
|
t->dst_cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0;
|
||||||
pr_debug("rt6_dst:%pI6 rt6_src:%pI6\n", &rt->rt6i_dst.addr,
|
pr_debug("rt6_dst:%pI6/%d rt6_src:%pI6\n",
|
||||||
|
&rt->rt6i_dst.addr, rt->rt6i_dst.plen,
|
||||||
&fl6->saddr);
|
&fl6->saddr);
|
||||||
} else {
|
} else {
|
||||||
t->dst = NULL;
|
t->dst = NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user