Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e8951408 authored by Ghalem Boudour's avatar Ghalem Boudour Committed by Greg Kroah-Hartman
Browse files

xfrm: fix policy lookup for ipv6 gre packets



commit bcf141b2eb551b3477b24997ebc09c65f117a803 upstream.

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: c12b395a ("gre: Support GRE over IPv6")
Cc: stable@vger.kernel.org
Signed-off-by: default avatarGhalem Boudour <ghalem.boudour@6wind.com>
Signed-off-by: default avatarNicolas Dichtel <nicolas.dichtel@6wind.com>
Signed-off-by: default avatarSteffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 09af1495
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -743,6 +743,7 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb,
		fl6->daddr = key->u.ipv6.dst;
		fl6->flowlabel = key->label;
		fl6->flowi6_uid = sock_net_uid(dev_net(dev), NULL);
		fl6->fl6_gre_key = tunnel_id_to_key32(key->tun_id);

		dsfield = key->tos;
		flags = key->tun_flags &
@@ -978,6 +979,7 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
		fl6.daddr = key->u.ipv6.dst;
		fl6.flowlabel = key->label;
		fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL);
		fl6.fl6_gre_key = tunnel_id_to_key32(key->tun_id);

		dsfield = key->tos;
		if (!(tun_info->key.tun_flags & TUNNEL_ERSPAN_OPT))
@@ -1085,6 +1087,7 @@ static void ip6gre_tnl_link_config_common(struct ip6_tnl *t)
	fl6->flowi6_oif = p->link;
	fl6->flowlabel = 0;
	fl6->flowi6_proto = IPPROTO_GRE;
	fl6->fl6_gre_key = t->parms.o_key;

	if (!(p->flags&IP6_TNL_F_USE_ORIG_TCLASS))
		fl6->flowlabel |= IPV6_TCLASS_MASK & p->flowinfo;
@@ -1530,7 +1533,7 @@ static void ip6gre_fb_tunnel_init(struct net_device *dev)
static struct inet6_protocol ip6gre_protocol __read_mostly = {
	.handler     = gre_rcv,
	.err_handler = ip6gre_err,
	.flags       = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
	.flags       = INET6_PROTO_FINAL,
};

static void ip6gre_destroy_tunnels(struct net *net, struct list_head *head)
+21 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@
#include <net/flow.h>
#include <net/xfrm.h>
#include <net/ip.h>
#include <net/gre.h>
#if IS_ENABLED(CONFIG_IPV6_MIP6)
#include <net/mip6.h>
#endif
@@ -3443,6 +3444,26 @@ decode_session6(struct sk_buff *skb, struct flowi *fl, bool reverse)
			}
			fl6->flowi6_proto = nexthdr;
			return;
		case IPPROTO_GRE:
			if (!onlyproto &&
			    (nh + offset + 12 < skb->data ||
			     pskb_may_pull(skb, nh + offset + 12 - skb->data))) {
				struct gre_base_hdr *gre_hdr;
				__be32 *gre_key;

				nh = skb_network_header(skb);
				gre_hdr = (struct gre_base_hdr *)(nh + offset);
				gre_key = (__be32 *)(gre_hdr + 1);

				if (gre_hdr->flags & GRE_KEY) {
					if (gre_hdr->flags & GRE_CSUM)
						gre_key++;
					fl6->fl6_gre_key = *gre_key;
				}
			}
			fl6->flowi6_proto = nexthdr;
			return;

#if IS_ENABLED(CONFIG_IPV6_MIP6)
		case IPPROTO_MH:
			offset += ipv6_optlen(exthdr);