mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
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->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 &
|
||||
@ -990,6 +991,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))
|
||||
@ -1098,6 +1100,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;
|
||||
@ -1544,7 +1547,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)
|
||||
|
@ -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
|
||||
@ -3422,6 +3423,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);
|
||||
|
Loading…
Reference in New Issue
Block a user