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: c12b395a46
("gre: Support GRE over IPv6")
Cc: stable@vger.kernel.org
Signed-off-by: Ghalem Boudour <ghalem.boudour@6wind.com>
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
This commit is contained in:
parent
03a000bfd7
commit
bcf141b2eb
|
@ -755,6 +755,7 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb,
|
||||||
fl6->daddr = key->u.ipv6.dst;
|
fl6->daddr = key->u.ipv6.dst;
|
||||||
fl6->flowlabel = key->label;
|
fl6->flowlabel = key->label;
|
||||||
fl6->flowi6_uid = sock_net_uid(dev_net(dev), NULL);
|
fl6->flowi6_uid = sock_net_uid(dev_net(dev), NULL);
|
||||||
|
fl6->fl6_gre_key = tunnel_id_to_key32(key->tun_id);
|
||||||
|
|
||||||
dsfield = key->tos;
|
dsfield = key->tos;
|
||||||
flags = key->tun_flags &
|
flags = key->tun_flags &
|
||||||
|
@ -990,6 +991,7 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
|
||||||
fl6.daddr = key->u.ipv6.dst;
|
fl6.daddr = key->u.ipv6.dst;
|
||||||
fl6.flowlabel = key->label;
|
fl6.flowlabel = key->label;
|
||||||
fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL);
|
fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL);
|
||||||
|
fl6.fl6_gre_key = tunnel_id_to_key32(key->tun_id);
|
||||||
|
|
||||||
dsfield = key->tos;
|
dsfield = key->tos;
|
||||||
if (!(tun_info->key.tun_flags & TUNNEL_ERSPAN_OPT))
|
if (!(tun_info->key.tun_flags & TUNNEL_ERSPAN_OPT))
|
||||||
|
@ -1098,6 +1100,7 @@ static void ip6gre_tnl_link_config_common(struct ip6_tnl *t)
|
||||||
fl6->flowi6_oif = p->link;
|
fl6->flowi6_oif = p->link;
|
||||||
fl6->flowlabel = 0;
|
fl6->flowlabel = 0;
|
||||||
fl6->flowi6_proto = IPPROTO_GRE;
|
fl6->flowi6_proto = IPPROTO_GRE;
|
||||||
|
fl6->fl6_gre_key = t->parms.o_key;
|
||||||
|
|
||||||
if (!(p->flags&IP6_TNL_F_USE_ORIG_TCLASS))
|
if (!(p->flags&IP6_TNL_F_USE_ORIG_TCLASS))
|
||||||
fl6->flowlabel |= IPV6_TCLASS_MASK & p->flowinfo;
|
fl6->flowlabel |= IPV6_TCLASS_MASK & p->flowinfo;
|
||||||
|
@ -1544,7 +1547,7 @@ static void ip6gre_fb_tunnel_init(struct net_device *dev)
|
||||||
static struct inet6_protocol ip6gre_protocol __read_mostly = {
|
static struct inet6_protocol ip6gre_protocol __read_mostly = {
|
||||||
.handler = gre_rcv,
|
.handler = gre_rcv,
|
||||||
.err_handler = ip6gre_err,
|
.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)
|
static void ip6gre_destroy_tunnels(struct net *net, struct list_head *head)
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include <net/flow.h>
|
#include <net/flow.h>
|
||||||
#include <net/xfrm.h>
|
#include <net/xfrm.h>
|
||||||
#include <net/ip.h>
|
#include <net/ip.h>
|
||||||
|
#include <net/gre.h>
|
||||||
#if IS_ENABLED(CONFIG_IPV6_MIP6)
|
#if IS_ENABLED(CONFIG_IPV6_MIP6)
|
||||||
#include <net/mip6.h>
|
#include <net/mip6.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -3422,6 +3423,26 @@ decode_session6(struct sk_buff *skb, struct flowi *fl, bool reverse)
|
||||||
}
|
}
|
||||||
fl6->flowi6_proto = nexthdr;
|
fl6->flowi6_proto = nexthdr;
|
||||||
return;
|
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)
|
#if IS_ENABLED(CONFIG_IPV6_MIP6)
|
||||||
case IPPROTO_MH:
|
case IPPROTO_MH:
|
||||||
offset += ipv6_optlen(exthdr);
|
offset += ipv6_optlen(exthdr);
|
||||||
|
|
Loading…
Reference in New Issue