diff options
author | David S. Miller <davem@davemloft.net> | 2011-05-04 15:33:34 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-05-04 15:55:07 -0400 |
commit | cbb1e85f9cfd2bd9b7edfd21d167e89a4279faf0 (patch) | |
tree | 352ce07ff62b9fc38212d72f3d1b0d124dafea39 | |
parent | 9a1b9496cd2b013f74885218947fa7120d53e74c (diff) |
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 <davem@davemloft.net>
-rw-r--r-- | include/net/route.h | 19 | ||||
-rw-r--r-- | net/ipv4/ip_gre.c | 37 |
2 files changed, 30 insertions, 26 deletions
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 | |||
152 | return ip_route_output_flow(net, fl4, sk); | 152 | return ip_route_output_flow(net, fl4, sk); |
153 | } | 153 | } |
154 | 154 | ||
155 | static inline struct rtable *ip_route_output_gre(struct net *net, | 155 | static inline struct rtable *ip_route_output_gre(struct net *net, struct flowi4 *fl4, |
156 | __be32 daddr, __be32 saddr, | 156 | __be32 daddr, __be32 saddr, |
157 | __be32 gre_key, __u8 tos, int oif) | 157 | __be32 gre_key, __u8 tos, int oif) |
158 | { | 158 | { |
159 | struct flowi4 fl4 = { | 159 | memset(fl4, 0, sizeof(*fl4)); |
160 | .flowi4_oif = oif, | 160 | fl4->flowi4_oif = oif; |
161 | .daddr = daddr, | 161 | fl4->daddr = daddr; |
162 | .saddr = saddr, | 162 | fl4->saddr = saddr; |
163 | .flowi4_tos = tos, | 163 | fl4->flowi4_tos = tos; |
164 | .flowi4_proto = IPPROTO_GRE, | 164 | fl4->flowi4_proto = IPPROTO_GRE; |
165 | .fl4_gre_key = gre_key, | 165 | fl4->fl4_gre_key = gre_key; |
166 | }; | 166 | return ip_route_output_key(net, fl4); |
167 | return ip_route_output_key(net, &fl4); | ||
168 | } | 167 | } |
169 | 168 | ||
170 | extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src, | 169 | extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src, |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 24efd353279a..10e9b5aea070 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -699,6 +699,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev | |||
699 | struct pcpu_tstats *tstats; | 699 | struct pcpu_tstats *tstats; |
700 | const struct iphdr *old_iph = ip_hdr(skb); | 700 | const struct iphdr *old_iph = ip_hdr(skb); |
701 | const struct iphdr *tiph; | 701 | const struct iphdr *tiph; |
702 | struct flowi4 fl4; | ||
702 | u8 tos; | 703 | u8 tos; |
703 | __be16 df; | 704 | __be16 df; |
704 | struct rtable *rt; /* Route to the other host */ | 705 | struct rtable *rt; /* Route to the other host */ |
@@ -769,7 +770,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev | |||
769 | tos = ipv6_get_dsfield((const struct ipv6hdr *)old_iph); | 770 | tos = ipv6_get_dsfield((const struct ipv6hdr *)old_iph); |
770 | } | 771 | } |
771 | 772 | ||
772 | rt = ip_route_output_gre(dev_net(dev), dst, tiph->saddr, | 773 | rt = ip_route_output_gre(dev_net(dev), &fl4, dst, tiph->saddr, |
773 | tunnel->parms.o_key, RT_TOS(tos), | 774 | tunnel->parms.o_key, RT_TOS(tos), |
774 | tunnel->parms.link); | 775 | tunnel->parms.link); |
775 | if (IS_ERR(rt)) { | 776 | if (IS_ERR(rt)) { |
@@ -873,8 +874,8 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev | |||
873 | iph->frag_off = df; | 874 | iph->frag_off = df; |
874 | iph->protocol = IPPROTO_GRE; | 875 | iph->protocol = IPPROTO_GRE; |
875 | iph->tos = ipgre_ecn_encapsulate(tos, old_iph, skb); | 876 | iph->tos = ipgre_ecn_encapsulate(tos, old_iph, skb); |
876 | iph->daddr = rt->rt_dst; | 877 | iph->daddr = fl4.daddr; |
877 | iph->saddr = rt->rt_src; | 878 | iph->saddr = fl4.saddr; |
878 | 879 | ||
879 | if ((iph->ttl = tiph->ttl) == 0) { | 880 | if ((iph->ttl = tiph->ttl) == 0) { |
880 | if (skb->protocol == htons(ETH_P_IP)) | 881 | if (skb->protocol == htons(ETH_P_IP)) |
@@ -938,12 +939,14 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev) | |||
938 | /* Guess output device to choose reasonable mtu and needed_headroom */ | 939 | /* Guess output device to choose reasonable mtu and needed_headroom */ |
939 | 940 | ||
940 | if (iph->daddr) { | 941 | if (iph->daddr) { |
941 | struct rtable *rt = ip_route_output_gre(dev_net(dev), | 942 | struct flowi4 fl4; |
942 | iph->daddr, iph->saddr, | 943 | struct rtable *rt; |
943 | tunnel->parms.o_key, | 944 | |
944 | RT_TOS(iph->tos), | 945 | rt = ip_route_output_gre(dev_net(dev), &fl4, |
945 | tunnel->parms.link); | 946 | iph->daddr, iph->saddr, |
946 | 947 | tunnel->parms.o_key, | |
948 | RT_TOS(iph->tos), | ||
949 | tunnel->parms.link); | ||
947 | if (!IS_ERR(rt)) { | 950 | if (!IS_ERR(rt)) { |
948 | tdev = rt->dst.dev; | 951 | tdev = rt->dst.dev; |
949 | ip_rt_put(rt); | 952 | ip_rt_put(rt); |
@@ -1196,13 +1199,15 @@ static int ipgre_open(struct net_device *dev) | |||
1196 | struct ip_tunnel *t = netdev_priv(dev); | 1199 | struct ip_tunnel *t = netdev_priv(dev); |
1197 | 1200 | ||
1198 | if (ipv4_is_multicast(t->parms.iph.daddr)) { | 1201 | if (ipv4_is_multicast(t->parms.iph.daddr)) { |
1199 | struct rtable *rt = ip_route_output_gre(dev_net(dev), | 1202 | struct flowi4 fl4; |
1200 | t->parms.iph.daddr, | 1203 | struct rtable *rt; |
1201 | t->parms.iph.saddr, | 1204 | |
1202 | t->parms.o_key, | 1205 | rt = ip_route_output_gre(dev_net(dev), &fl4, |
1203 | RT_TOS(t->parms.iph.tos), | 1206 | t->parms.iph.daddr, |
1204 | t->parms.link); | 1207 | t->parms.iph.saddr, |
1205 | 1208 | t->parms.o_key, | |
1209 | RT_TOS(t->parms.iph.tos), | ||
1210 | t->parms.link); | ||
1206 | if (IS_ERR(rt)) | 1211 | if (IS_ERR(rt)) |
1207 | return -EADDRNOTAVAIL; | 1212 | return -EADDRNOTAVAIL; |
1208 | dev = rt->dst.dev; | 1213 | dev = rt->dst.dev; |