Skip to content

Commit

Permalink
net: Fix vti use case with oif in dst lookups
Browse files Browse the repository at this point in the history
Steffen reported that the recent change to add oif to dst lookups breaks
the VTI use case. The problem is that with the oif set in the flow struct
the comparison to the nh_oif is triggered. Fix by splitting the
FLOWI_FLAG_VRFSRC into 2 flags -- one that triggers the vrf device cache
bypass (FLOWI_FLAG_VRFSRC) and another telling the lookup to not compare
nh oif (FLOWI_FLAG_SKIP_NH_OIF).

Fixes: 42a7b32 ("xfrm: Add oif to dst lookups")

Signed-off-by: David Ahern <[email protected]>
Acked-by: Steffen Klassert <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
David Ahern authored and davem330 committed Sep 17, 2015
1 parent d828755 commit 58189ca
Show file tree
Hide file tree
Showing 6 changed files with 9 additions and 4 deletions.
3 changes: 2 additions & 1 deletion drivers/net/vrf.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,8 @@ static netdev_tx_t vrf_process_v4_outbound(struct sk_buff *skb,
.flowi4_oif = vrf_dev->ifindex,
.flowi4_iif = LOOPBACK_IFINDEX,
.flowi4_tos = RT_TOS(ip4h->tos),
.flowi4_flags = FLOWI_FLAG_ANYSRC | FLOWI_FLAG_VRFSRC,
.flowi4_flags = FLOWI_FLAG_ANYSRC | FLOWI_FLAG_VRFSRC |
FLOWI_FLAG_SKIP_NH_OIF,
.daddr = ip4h->daddr,
};

Expand Down
1 change: 1 addition & 0 deletions include/net/flow.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ struct flowi_common {
#define FLOWI_FLAG_ANYSRC 0x01
#define FLOWI_FLAG_KNOWN_NH 0x02
#define FLOWI_FLAG_VRFSRC 0x04
#define FLOWI_FLAG_SKIP_NH_OIF 0x08
__u32 flowic_secid;
struct flowi_tunnel flowic_tun_key;
};
Expand Down
2 changes: 1 addition & 1 deletion include/net/route.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ static inline void ip_route_connect_init(struct flowi4 *fl4, __be32 dst, __be32
flow_flags |= FLOWI_FLAG_ANYSRC;

if (netif_index_is_vrf(sock_net(sk), oif))
flow_flags |= FLOWI_FLAG_VRFSRC;
flow_flags |= FLOWI_FLAG_VRFSRC | FLOWI_FLAG_SKIP_NH_OIF;

flowi4_init_output(fl4, oif, sk->sk_mark, tos, RT_SCOPE_UNIVERSE,
protocol, flow_flags, dst, src, dport, sport);
Expand Down
2 changes: 1 addition & 1 deletion net/ipv4/fib_trie.c
Original file line number Diff line number Diff line change
Expand Up @@ -1426,7 +1426,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp,
nh->nh_flags & RTNH_F_LINKDOWN &&
!(fib_flags & FIB_LOOKUP_IGNORE_LINKSTATE))
continue;
if (!(flp->flowi4_flags & FLOWI_FLAG_VRFSRC)) {
if (!(flp->flowi4_flags & FLOWI_FLAG_SKIP_NH_OIF)) {
if (flp->flowi4_oif &&
flp->flowi4_oif != nh->nh_oif)
continue;
Expand Down
3 changes: 2 additions & 1 deletion net/ipv4/udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1024,7 +1024,8 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
if (netif_index_is_vrf(net, ipc.oif)) {
flowi4_init_output(fl4, ipc.oif, sk->sk_mark, tos,
RT_SCOPE_UNIVERSE, sk->sk_protocol,
(flow_flags | FLOWI_FLAG_VRFSRC),
(flow_flags | FLOWI_FLAG_VRFSRC |
FLOWI_FLAG_SKIP_NH_OIF),
faddr, saddr, dport,
inet->inet_sport);

Expand Down
2 changes: 2 additions & 0 deletions net/ipv4/xfrm4_policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ static struct dst_entry *__xfrm4_dst_lookup(struct net *net, struct flowi4 *fl4,
if (saddr)
fl4->saddr = saddr->a4;

fl4->flowi4_flags = FLOWI_FLAG_SKIP_NH_OIF;

rt = __ip_route_output_key(net, fl4);
if (!IS_ERR(rt))
return &rt->dst;
Expand Down

0 comments on commit 58189ca

Please sign in to comment.