Skip to content

Commit bcf141b

Browse files
GhalemBoudourklassert
authored andcommitted
xfrm: fix policy lookup for ipv6 gre packets
On egress side, xfrm lookup is called from __gre6_xmit() with the fl6_gre_key field not initialized leading to policies selectors check failure. Consequently, gre packets are sent without encryption. On ingress side, INET6_PROTO_NOPOLICY was set, thus packets were not checked against xfrm policies. Like for egress side, fl6_gre_key should be correctly set, this is now done in decode_session6(). Fixes: c12b395 ("gre: Support GRE over IPv6") Cc: [email protected] Signed-off-by: Ghalem Boudour <[email protected]> Signed-off-by: Nicolas Dichtel <[email protected]> Signed-off-by: Steffen Klassert <[email protected]>
1 parent 03a000b commit bcf141b

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

net/ipv6/ip6_gre.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,7 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb,
755755
fl6->daddr = key->u.ipv6.dst;
756756
fl6->flowlabel = key->label;
757757
fl6->flowi6_uid = sock_net_uid(dev_net(dev), NULL);
758+
fl6->fl6_gre_key = tunnel_id_to_key32(key->tun_id);
758759

759760
dsfield = key->tos;
760761
flags = key->tun_flags &
@@ -990,6 +991,7 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
990991
fl6.daddr = key->u.ipv6.dst;
991992
fl6.flowlabel = key->label;
992993
fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL);
994+
fl6.fl6_gre_key = tunnel_id_to_key32(key->tun_id);
993995

994996
dsfield = key->tos;
995997
if (!(tun_info->key.tun_flags & TUNNEL_ERSPAN_OPT))
@@ -1098,6 +1100,7 @@ static void ip6gre_tnl_link_config_common(struct ip6_tnl *t)
10981100
fl6->flowi6_oif = p->link;
10991101
fl6->flowlabel = 0;
11001102
fl6->flowi6_proto = IPPROTO_GRE;
1103+
fl6->fl6_gre_key = t->parms.o_key;
11011104

11021105
if (!(p->flags&IP6_TNL_F_USE_ORIG_TCLASS))
11031106
fl6->flowlabel |= IPV6_TCLASS_MASK & p->flowinfo;
@@ -1544,7 +1547,7 @@ static void ip6gre_fb_tunnel_init(struct net_device *dev)
15441547
static struct inet6_protocol ip6gre_protocol __read_mostly = {
15451548
.handler = gre_rcv,
15461549
.err_handler = ip6gre_err,
1547-
.flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
1550+
.flags = INET6_PROTO_FINAL,
15481551
};
15491552

15501553
static void ip6gre_destroy_tunnels(struct net *net, struct list_head *head)

net/xfrm/xfrm_policy.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include <net/flow.h>
3434
#include <net/xfrm.h>
3535
#include <net/ip.h>
36+
#include <net/gre.h>
3637
#if IS_ENABLED(CONFIG_IPV6_MIP6)
3738
#include <net/mip6.h>
3839
#endif
@@ -3422,6 +3423,26 @@ decode_session6(struct sk_buff *skb, struct flowi *fl, bool reverse)
34223423
}
34233424
fl6->flowi6_proto = nexthdr;
34243425
return;
3426+
case IPPROTO_GRE:
3427+
if (!onlyproto &&
3428+
(nh + offset + 12 < skb->data ||
3429+
pskb_may_pull(skb, nh + offset + 12 - skb->data))) {
3430+
struct gre_base_hdr *gre_hdr;
3431+
__be32 *gre_key;
3432+
3433+
nh = skb_network_header(skb);
3434+
gre_hdr = (struct gre_base_hdr *)(nh + offset);
3435+
gre_key = (__be32 *)(gre_hdr + 1);
3436+
3437+
if (gre_hdr->flags & GRE_KEY) {
3438+
if (gre_hdr->flags & GRE_CSUM)
3439+
gre_key++;
3440+
fl6->fl6_gre_key = *gre_key;
3441+
}
3442+
}
3443+
fl6->flowi6_proto = nexthdr;
3444+
return;
3445+
34253446
#if IS_ENABLED(CONFIG_IPV6_MIP6)
34263447
case IPPROTO_MH:
34273448
offset += ipv6_optlen(exthdr);

0 commit comments

Comments
 (0)