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>
This commit is contained in:
Родитель
9a1b9496cd
Коммит
cbb1e85f9c
|
@ -152,19 +152,18 @@ static inline struct rtable *ip_route_output_ports(struct net *net, struct flowi
|
||||||
return ip_route_output_flow(net, fl4, sk);
|
return ip_route_output_flow(net, fl4, sk);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct rtable *ip_route_output_gre(struct net *net,
|
static inline struct rtable *ip_route_output_gre(struct net *net, struct flowi4 *fl4,
|
||||||
__be32 daddr, __be32 saddr,
|
__be32 daddr, __be32 saddr,
|
||||||
__be32 gre_key, __u8 tos, int oif)
|
__be32 gre_key, __u8 tos, int oif)
|
||||||
{
|
{
|
||||||
struct flowi4 fl4 = {
|
memset(fl4, 0, sizeof(*fl4));
|
||||||
.flowi4_oif = oif,
|
fl4->flowi4_oif = oif;
|
||||||
.daddr = daddr,
|
fl4->daddr = daddr;
|
||||||
.saddr = saddr,
|
fl4->saddr = saddr;
|
||||||
.flowi4_tos = tos,
|
fl4->flowi4_tos = tos;
|
||||||
.flowi4_proto = IPPROTO_GRE,
|
fl4->flowi4_proto = IPPROTO_GRE;
|
||||||
.fl4_gre_key = gre_key,
|
fl4->fl4_gre_key = gre_key;
|
||||||
};
|
return ip_route_output_key(net, fl4);
|
||||||
return ip_route_output_key(net, &fl4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src,
|
extern int ip_route_input_common(struct sk_buff *skb, __be32 dst, __be32 src,
|
||||||
|
|
|
@ -699,6 +699,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
|
||||||
struct pcpu_tstats *tstats;
|
struct pcpu_tstats *tstats;
|
||||||
const struct iphdr *old_iph = ip_hdr(skb);
|
const struct iphdr *old_iph = ip_hdr(skb);
|
||||||
const struct iphdr *tiph;
|
const struct iphdr *tiph;
|
||||||
|
struct flowi4 fl4;
|
||||||
u8 tos;
|
u8 tos;
|
||||||
__be16 df;
|
__be16 df;
|
||||||
struct rtable *rt; /* Route to the other host */
|
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
|
||||||
tos = ipv6_get_dsfield((const struct ipv6hdr *)old_iph);
|
tos = ipv6_get_dsfield((const struct ipv6hdr *)old_iph);
|
||||||
}
|
}
|
||||||
|
|
||||||
rt = ip_route_output_gre(dev_net(dev), dst, tiph->saddr,
|
rt = ip_route_output_gre(dev_net(dev), &fl4, dst, tiph->saddr,
|
||||||
tunnel->parms.o_key, RT_TOS(tos),
|
tunnel->parms.o_key, RT_TOS(tos),
|
||||||
tunnel->parms.link);
|
tunnel->parms.link);
|
||||||
if (IS_ERR(rt)) {
|
if (IS_ERR(rt)) {
|
||||||
|
@ -873,8 +874,8 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
|
||||||
iph->frag_off = df;
|
iph->frag_off = df;
|
||||||
iph->protocol = IPPROTO_GRE;
|
iph->protocol = IPPROTO_GRE;
|
||||||
iph->tos = ipgre_ecn_encapsulate(tos, old_iph, skb);
|
iph->tos = ipgre_ecn_encapsulate(tos, old_iph, skb);
|
||||||
iph->daddr = rt->rt_dst;
|
iph->daddr = fl4.daddr;
|
||||||
iph->saddr = rt->rt_src;
|
iph->saddr = fl4.saddr;
|
||||||
|
|
||||||
if ((iph->ttl = tiph->ttl) == 0) {
|
if ((iph->ttl = tiph->ttl) == 0) {
|
||||||
if (skb->protocol == htons(ETH_P_IP))
|
if (skb->protocol == htons(ETH_P_IP))
|
||||||
|
@ -938,12 +939,14 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev)
|
||||||
/* Guess output device to choose reasonable mtu and needed_headroom */
|
/* Guess output device to choose reasonable mtu and needed_headroom */
|
||||||
|
|
||||||
if (iph->daddr) {
|
if (iph->daddr) {
|
||||||
struct rtable *rt = ip_route_output_gre(dev_net(dev),
|
struct flowi4 fl4;
|
||||||
iph->daddr, iph->saddr,
|
struct rtable *rt;
|
||||||
tunnel->parms.o_key,
|
|
||||||
RT_TOS(iph->tos),
|
|
||||||
tunnel->parms.link);
|
|
||||||
|
|
||||||
|
rt = ip_route_output_gre(dev_net(dev), &fl4,
|
||||||
|
iph->daddr, iph->saddr,
|
||||||
|
tunnel->parms.o_key,
|
||||||
|
RT_TOS(iph->tos),
|
||||||
|
tunnel->parms.link);
|
||||||
if (!IS_ERR(rt)) {
|
if (!IS_ERR(rt)) {
|
||||||
tdev = rt->dst.dev;
|
tdev = rt->dst.dev;
|
||||||
ip_rt_put(rt);
|
ip_rt_put(rt);
|
||||||
|
@ -1196,13 +1199,15 @@ static int ipgre_open(struct net_device *dev)
|
||||||
struct ip_tunnel *t = netdev_priv(dev);
|
struct ip_tunnel *t = netdev_priv(dev);
|
||||||
|
|
||||||
if (ipv4_is_multicast(t->parms.iph.daddr)) {
|
if (ipv4_is_multicast(t->parms.iph.daddr)) {
|
||||||
struct rtable *rt = ip_route_output_gre(dev_net(dev),
|
struct flowi4 fl4;
|
||||||
t->parms.iph.daddr,
|
struct rtable *rt;
|
||||||
t->parms.iph.saddr,
|
|
||||||
t->parms.o_key,
|
|
||||||
RT_TOS(t->parms.iph.tos),
|
|
||||||
t->parms.link);
|
|
||||||
|
|
||||||
|
rt = ip_route_output_gre(dev_net(dev), &fl4,
|
||||||
|
t->parms.iph.daddr,
|
||||||
|
t->parms.iph.saddr,
|
||||||
|
t->parms.o_key,
|
||||||
|
RT_TOS(t->parms.iph.tos),
|
||||||
|
t->parms.link);
|
||||||
if (IS_ERR(rt))
|
if (IS_ERR(rt))
|
||||||
return -EADDRNOTAVAIL;
|
return -EADDRNOTAVAIL;
|
||||||
dev = rt->dst.dev;
|
dev = rt->dst.dev;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче