Commit c4251db3 authored by David S. Miller's avatar David S. Miller
Browse files


Steffen Klassert says:

====================
pull request (net): ipsec 2022-01-06

1) Fix xfrm policy lookups for ipv6 gre packets by initializing
   fl6_gre_key properly. From Ghalem Boudour.

2) Fix the dflt policy check on forwarding when there is no
   policy configured. The check was done for the wrong direction.
   From Nicolas Dichtel.

3) Use the correct 'struct xfrm_user_offload' when calculating
   netlink message lenghts in xfrm_sa_len(). From Eric Dumazet.

4) Tread inserting xfrm interface id 0 as an error.
   From Antony Antony.

5) Fail if xfrm state or policy is inserted with XFRMA_IF_ID 0,
   xfrm interfaces with id 0 are not allowed.
   From Antony Antony.

6) Fix inner_ipproto setting in the sec_path for tunnel mode.
   From  Raed Salem.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 502a2ce9 45a98ef4
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -1162,7 +1162,7 @@ static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family)
{
{
	struct net *net = dev_net(skb->dev);
	struct net *net = dev_net(skb->dev);


	if (xfrm_default_allow(net, XFRM_POLICY_FWD))
	if (xfrm_default_allow(net, XFRM_POLICY_OUT))
		return !net->xfrm.policy_count[XFRM_POLICY_OUT] ||
		return !net->xfrm.policy_count[XFRM_POLICY_OUT] ||
			(skb_dst(skb)->flags & DST_NOXFRM) ||
			(skb_dst(skb)->flags & DST_NOXFRM) ||
			__xfrm_route_forward(skb, family);
			__xfrm_route_forward(skb, family);
+4 −1
Original line number Original line Diff line number Diff line
@@ -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)
+12 −2
Original line number Original line Diff line number Diff line
@@ -637,11 +637,16 @@ static int xfrmi_newlink(struct net *src_net, struct net_device *dev,
			struct netlink_ext_ack *extack)
			struct netlink_ext_ack *extack)
{
{
	struct net *net = dev_net(dev);
	struct net *net = dev_net(dev);
	struct xfrm_if_parms p;
	struct xfrm_if_parms p = {};
	struct xfrm_if *xi;
	struct xfrm_if *xi;
	int err;
	int err;


	xfrmi_netlink_parms(data, &p);
	xfrmi_netlink_parms(data, &p);
	if (!p.if_id) {
		NL_SET_ERR_MSG(extack, "if_id must be non zero");
		return -EINVAL;
	}

	xi = xfrmi_locate(net, &p);
	xi = xfrmi_locate(net, &p);
	if (xi)
	if (xi)
		return -EEXIST;
		return -EEXIST;
@@ -666,7 +671,12 @@ static int xfrmi_changelink(struct net_device *dev, struct nlattr *tb[],
{
{
	struct xfrm_if *xi = netdev_priv(dev);
	struct xfrm_if *xi = netdev_priv(dev);
	struct net *net = xi->net;
	struct net *net = xi->net;
	struct xfrm_if_parms p;
	struct xfrm_if_parms p = {};

	if (!p.if_id) {
		NL_SET_ERR_MSG(extack, "if_id must be non zero");
		return -EINVAL;
	}


	xfrmi_netlink_parms(data, &p);
	xfrmi_netlink_parms(data, &p);
	xi = xfrmi_locate(net, &p);
	xi = xfrmi_locate(net, &p);
+25 −5
Original line number Original line Diff line number Diff line
@@ -647,10 +647,12 @@ static int xfrm_output_gso(struct net *net, struct sock *sk, struct sk_buff *skb
 * This requires hardware to know the inner packet type to calculate
 * This requires hardware to know the inner packet type to calculate
 * the inner header checksum. Save inner ip protocol here to avoid
 * the inner header checksum. Save inner ip protocol here to avoid
 * traversing the packet in the vendor's xmit code.
 * traversing the packet in the vendor's xmit code.
 * If the encap type is IPIP, just save skb->inner_ipproto. Otherwise,
 * For IPsec tunnel mode save the ip protocol from the IP header of the
 * get the ip protocol from the IP header.
 * plain text packet. Otherwise If the encap type is IPIP, just save
 * skb->inner_ipproto in any other case get the ip protocol from the IP
 * header.
 */
 */
static void xfrm_get_inner_ipproto(struct sk_buff *skb)
static void xfrm_get_inner_ipproto(struct sk_buff *skb, struct xfrm_state *x)
{
{
	struct xfrm_offload *xo = xfrm_offload(skb);
	struct xfrm_offload *xo = xfrm_offload(skb);
	const struct ethhdr *eth;
	const struct ethhdr *eth;
@@ -658,6 +660,25 @@ static void xfrm_get_inner_ipproto(struct sk_buff *skb)
	if (!xo)
	if (!xo)
		return;
		return;


	if (x->outer_mode.encap == XFRM_MODE_TUNNEL) {
		switch (x->outer_mode.family) {
		case AF_INET:
			xo->inner_ipproto = ip_hdr(skb)->protocol;
			break;
		case AF_INET6:
			xo->inner_ipproto = ipv6_hdr(skb)->nexthdr;
			break;
		default:
			break;
		}

		return;
	}

	/* non-Tunnel Mode */
	if (!skb->encapsulation)
		return;

	if (skb->inner_protocol_type == ENCAP_TYPE_IPPROTO) {
	if (skb->inner_protocol_type == ENCAP_TYPE_IPPROTO) {
		xo->inner_ipproto = skb->inner_ipproto;
		xo->inner_ipproto = skb->inner_ipproto;
		return;
		return;
@@ -712,8 +733,7 @@ int xfrm_output(struct sock *sk, struct sk_buff *skb)
		sp->xvec[sp->len++] = x;
		sp->xvec[sp->len++] = x;
		xfrm_state_hold(x);
		xfrm_state_hold(x);


		if (skb->encapsulation)
		xfrm_get_inner_ipproto(skb, x);
			xfrm_get_inner_ipproto(skb);
		skb->encapsulation = 1;
		skb->encapsulation = 1;


		if (skb_is_gso(skb)) {
		if (skb_is_gso(skb)) {
+21 −0
Original line number Original line Diff line number Diff line
@@ -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