summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin KaFai Lau <kafai@fb.com>2015-05-22 23:55:57 -0400
committerDavid S. Miller <davem@davemloft.net>2015-05-25 13:25:32 -0400
commitfd0273d7939f2ce3247f6aac5f6b9a0135d4cd39 (patch)
treeddc154611a679e85f1db7440752001d40794e710
parent286c2349f6665c3e67f464a5faa14a0e28be4842 (diff)
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>
-rw-r--r--drivers/scsi/cxgbi/libcxgbi.c2
-rw-r--r--include/net/ipv6.h4
-rw-r--r--net/ipv6/icmp.c2
-rw-r--r--net/ipv6/ip6_output.c13
-rw-r--r--net/ipv6/ndisc.c2
-rw-r--r--net/ipv6/output_core.c10
-rw-r--r--net/ipv6/tcp_ipv6.c2
-rw-r--r--net/netfilter/ipvs/ip_vs_xmit.c4
-rw-r--r--net/sctp/ipv6.c3
9 files changed, 25 insertions, 17 deletions
diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c
index eb58afcfb73b..45d30398d7c3 100644
--- a/drivers/scsi/cxgbi/libcxgbi.c
+++ b/drivers/scsi/cxgbi/libcxgbi.c
@@ -728,7 +728,7 @@ static struct cxgbi_sock *cxgbi_check_route6(struct sockaddr *dst_addr)
728 } 728 }
729 ndev = n->dev; 729 ndev = n->dev;
730 730
731 if (ipv6_addr_is_multicast(&rt->rt6i_dst.addr)) { 731 if (ipv6_addr_is_multicast(&daddr6->sin6_addr)) {
732 pr_info("multi-cast route %pI6 port %u, dev %s.\n", 732 pr_info("multi-cast route %pI6 port %u, dev %s.\n",
733 daddr6->sin6_addr.s6_addr, 733 daddr6->sin6_addr.s6_addr,
734 ntohs(daddr6->sin6_port), ndev->name); 734 ntohs(daddr6->sin6_port), ndev->name);
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 8c4f881edbd2..b950a2000b7f 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -671,7 +671,9 @@ static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_add
671 return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr)); 671 return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr));
672} 672}
673 673
674u32 ipv6_select_ident(struct net *net, struct rt6_info *rt); 674u32 ipv6_select_ident(struct net *net,
675 const struct in6_addr *daddr,
676 const struct in6_addr *saddr);
675void ipv6_proxy_select_ident(struct net *net, struct sk_buff *skb); 677void ipv6_proxy_select_ident(struct net *net, struct sk_buff *skb);
676 678
677int ip6_dst_hoplimit(struct dst_entry *dst); 679int ip6_dst_hoplimit(struct dst_entry *dst);
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 2c2b5d51f15c..24b359d1425b 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -207,7 +207,7 @@ static bool icmpv6_xrlim_allow(struct sock *sk, u8 type,
207 struct inet_peer *peer; 207 struct inet_peer *peer;
208 208
209 peer = inet_getpeer_v6(net->ipv6.peers, 209 peer = inet_getpeer_v6(net->ipv6.peers,
210 &rt->rt6i_dst.addr, 1); 210 &fl6->daddr, 1);
211 res = inet_peer_xrlim_allow(peer, tmo); 211 res = inet_peer_xrlim_allow(peer, tmo);
212 if (peer) 212 if (peer)
213 inet_putpeer(peer); 213 inet_putpeer(peer);
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 05e2cdf938bd..3097f2c5e890 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -459,7 +459,7 @@ int ip6_forward(struct sk_buff *skb)
459 else 459 else
460 target = &hdr->daddr; 460 target = &hdr->daddr;
461 461
462 peer = inet_getpeer_v6(net->ipv6.peers, &rt->rt6i_dst.addr, 1); 462 peer = inet_getpeer_v6(net->ipv6.peers, &hdr->daddr, 1);
463 463
464 /* Limit redirects both by destination (here) 464 /* Limit redirects both by destination (here)
465 and by source (inside ndisc_send_redirect) 465 and by source (inside ndisc_send_redirect)
@@ -584,7 +584,8 @@ int ip6_fragment(struct sock *sk, struct sk_buff *skb,
584 } 584 }
585 mtu -= hlen + sizeof(struct frag_hdr); 585 mtu -= hlen + sizeof(struct frag_hdr);
586 586
587 frag_id = ipv6_select_ident(net, rt); 587 frag_id = ipv6_select_ident(net, &ipv6_hdr(skb)->daddr,
588 &ipv6_hdr(skb)->saddr);
588 589
589 if (skb_has_frag_list(skb)) { 590 if (skb_has_frag_list(skb)) {
590 int first_len = skb_pagelen(skb); 591 int first_len = skb_pagelen(skb);
@@ -1057,7 +1058,7 @@ static inline int ip6_ufo_append_data(struct sock *sk,
1057 int odd, struct sk_buff *skb), 1058 int odd, struct sk_buff *skb),
1058 void *from, int length, int hh_len, int fragheaderlen, 1059 void *from, int length, int hh_len, int fragheaderlen,
1059 int transhdrlen, int mtu, unsigned int flags, 1060 int transhdrlen, int mtu, unsigned int flags,
1060 struct rt6_info *rt) 1061 const struct flowi6 *fl6)
1061 1062
1062{ 1063{
1063 struct sk_buff *skb; 1064 struct sk_buff *skb;
@@ -1102,7 +1103,9 @@ static inline int ip6_ufo_append_data(struct sock *sk,
1102 skb_shinfo(skb)->gso_size = (mtu - fragheaderlen - 1103 skb_shinfo(skb)->gso_size = (mtu - fragheaderlen -
1103 sizeof(struct frag_hdr)) & ~7; 1104 sizeof(struct frag_hdr)) & ~7;
1104 skb_shinfo(skb)->gso_type = SKB_GSO_UDP; 1105 skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
1105 skb_shinfo(skb)->ip6_frag_id = ipv6_select_ident(sock_net(sk), rt); 1106 skb_shinfo(skb)->ip6_frag_id = ipv6_select_ident(sock_net(sk),
1107 &fl6->daddr,
1108 &fl6->saddr);
1106 1109
1107append: 1110append:
1108 return skb_append_datato_frags(sk, skb, getfrag, from, 1111 return skb_append_datato_frags(sk, skb, getfrag, from,
@@ -1327,7 +1330,7 @@ emsgsize:
1327 (sk->sk_type == SOCK_DGRAM)) { 1330 (sk->sk_type == SOCK_DGRAM)) {
1328 err = ip6_ufo_append_data(sk, queue, getfrag, from, length, 1331 err = ip6_ufo_append_data(sk, queue, getfrag, from, length,
1329 hh_len, fragheaderlen, 1332 hh_len, fragheaderlen,
1330 transhdrlen, mtu, flags, rt); 1333 transhdrlen, mtu, flags, fl6);
1331 if (err) 1334 if (err)
1332 goto error; 1335 goto error;
1333 return 0; 1336 return 0;
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 96f153c0846b..0a05b35a90fc 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1506,7 +1506,7 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target)
1506 "Redirect: destination is not a neighbour\n"); 1506 "Redirect: destination is not a neighbour\n");
1507 goto release; 1507 goto release;
1508 } 1508 }
1509 peer = inet_getpeer_v6(net->ipv6.peers, &rt->rt6i_dst.addr, 1); 1509 peer = inet_getpeer_v6(net->ipv6.peers, &ipv6_hdr(skb)->saddr, 1);
1510 ret = inet_peer_xrlim_allow(peer, 1*HZ); 1510 ret = inet_peer_xrlim_allow(peer, 1*HZ);
1511 if (peer) 1511 if (peer)
1512 inet_putpeer(peer); 1512 inet_putpeer(peer);
diff --git a/net/ipv6/output_core.c b/net/ipv6/output_core.c
index ef0e2326496b..055e85cb7b65 100644
--- a/net/ipv6/output_core.c
+++ b/net/ipv6/output_core.c
@@ -10,7 +10,8 @@
10#include <net/secure_seq.h> 10#include <net/secure_seq.h>
11 11
12static u32 __ipv6_select_ident(struct net *net, u32 hashrnd, 12static u32 __ipv6_select_ident(struct net *net, u32 hashrnd,
13 struct in6_addr *dst, struct in6_addr *src) 13 const struct in6_addr *dst,
14 const struct in6_addr *src)
14{ 15{
15 u32 hash, id; 16 u32 hash, id;
16 17
@@ -60,15 +61,16 @@ void ipv6_proxy_select_ident(struct net *net, struct sk_buff *skb)
60} 61}
61EXPORT_SYMBOL_GPL(ipv6_proxy_select_ident); 62EXPORT_SYMBOL_GPL(ipv6_proxy_select_ident);
62 63
63u32 ipv6_select_ident(struct net *net, struct rt6_info *rt) 64u32 ipv6_select_ident(struct net *net,
65 const struct in6_addr *daddr,
66 const struct in6_addr *saddr)
64{ 67{
65 static u32 ip6_idents_hashrnd __read_mostly; 68 static u32 ip6_idents_hashrnd __read_mostly;
66 u32 id; 69 u32 id;
67 70
68 net_get_random_once(&ip6_idents_hashrnd, sizeof(ip6_idents_hashrnd)); 71 net_get_random_once(&ip6_idents_hashrnd, sizeof(ip6_idents_hashrnd));
69 72
70 id = __ipv6_select_ident(net, ip6_idents_hashrnd, &rt->rt6i_dst.addr, 73 id = __ipv6_select_ident(net, ip6_idents_hashrnd, daddr, saddr);
71 &rt->rt6i_src.addr);
72 return htonl(id); 74 return htonl(id);
73} 75}
74EXPORT_SYMBOL(ipv6_select_ident); 76EXPORT_SYMBOL(ipv6_select_ident);
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index fefe4455e1f3..1a9390a370c0 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -262,7 +262,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
262 rt = (struct rt6_info *) dst; 262 rt = (struct rt6_info *) dst;
263 if (tcp_death_row.sysctl_tw_recycle && 263 if (tcp_death_row.sysctl_tw_recycle &&
264 !tp->rx_opt.ts_recent_stamp && 264 !tp->rx_opt.ts_recent_stamp &&
265 ipv6_addr_equal(&rt->rt6i_dst.addr, &sk->sk_v6_daddr)) 265 ipv6_addr_equal(&fl6.daddr, &sk->sk_v6_daddr))
266 tcp_fetch_timewait_stamp(sk, dst); 266 tcp_fetch_timewait_stamp(sk, dst);
267 267
268 icsk->icsk_ext_hdr_len = 0; 268 icsk->icsk_ext_hdr_len = 0;
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index 19986ec5f21a..38f862728f75 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -781,7 +781,7 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
781 781
782 /* From world but DNAT to loopback address? */ 782 /* From world but DNAT to loopback address? */
783 if (local && skb->dev && !(skb->dev->flags & IFF_LOOPBACK) && 783 if (local && skb->dev && !(skb->dev->flags & IFF_LOOPBACK) &&
784 ipv6_addr_type(&rt->rt6i_dst.addr) & IPV6_ADDR_LOOPBACK) { 784 ipv6_addr_type(&cp->daddr.in6) & IPV6_ADDR_LOOPBACK) {
785 IP_VS_DBG_RL_PKT(1, AF_INET6, pp, skb, 0, 785 IP_VS_DBG_RL_PKT(1, AF_INET6, pp, skb, 0,
786 "ip_vs_nat_xmit_v6(): " 786 "ip_vs_nat_xmit_v6(): "
787 "stopping DNAT to loopback address"); 787 "stopping DNAT to loopback address");
@@ -1346,7 +1346,7 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
1346 1346
1347 /* From world but DNAT to loopback address? */ 1347 /* From world but DNAT to loopback address? */
1348 if (local && skb->dev && !(skb->dev->flags & IFF_LOOPBACK) && 1348 if (local && skb->dev && !(skb->dev->flags & IFF_LOOPBACK) &&
1349 ipv6_addr_type(&rt->rt6i_dst.addr) & IPV6_ADDR_LOOPBACK) { 1349 ipv6_addr_type(&cp->daddr.in6) & IPV6_ADDR_LOOPBACK) {
1350 IP_VS_DBG(1, "%s(): " 1350 IP_VS_DBG(1, "%s(): "
1351 "stopping DNAT to loopback %pI6\n", 1351 "stopping DNAT to loopback %pI6\n",
1352 __func__, &cp->daddr.in6); 1352 __func__, &cp->daddr.in6);
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index e703ff7fed40..17a0120ae5a5 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -332,7 +332,8 @@ out:
332 rt = (struct rt6_info *)dst; 332 rt = (struct rt6_info *)dst;
333 t->dst = dst; 333 t->dst = dst;
334 t->dst_cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0; 334 t->dst_cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0;
335 pr_debug("rt6_dst:%pI6 rt6_src:%pI6\n", &rt->rt6i_dst.addr, 335 pr_debug("rt6_dst:%pI6/%d rt6_src:%pI6\n",
336 &rt->rt6i_dst.addr, rt->rt6i_dst.plen,
336 &fl6->saddr); 337 &fl6->saddr);
337 } else { 338 } else {
338 t->dst = NULL; 339 t->dst = NULL;