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


Steffen Klassert says:

====================
pull request (net): ipsec 2020-01-21

1) Fix packet tx through bpf_redirect() for xfrm and vti
   interfaces. From Nicolas Dichtel.

2) Do not confirm neighbor when do pmtu update on a virtual
   xfrm interface. From Xu Wang.

3) Support output_mark for offload ESP packets, this was
   forgotten when the output_mark was added initially.
   From Ulrich Weber.

Please pull or let me know if there are problems.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 80892772 4e4362d2
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -57,6 +57,8 @@ static struct sk_buff *esp4_gro_receive(struct list_head *head,
		if (!x)
			goto out_reset;

		skb->mark = xfrm_smark_get(skb->mark, x);

		sp->xvec[sp->len++] = x;
		sp->olen++;

+11 −2
Original line number Diff line number Diff line
@@ -187,9 +187,18 @@ static netdev_tx_t vti_xmit(struct sk_buff *skb, struct net_device *dev,
	int mtu;

	if (!dst) {
		struct rtable *rt;

		fl->u.ip4.flowi4_oif = dev->ifindex;
		fl->u.ip4.flowi4_flags |= FLOWI_FLAG_ANYSRC;
		rt = __ip_route_output_key(dev_net(dev), &fl->u.ip4);
		if (IS_ERR(rt)) {
			dev->stats.tx_carrier_errors++;
			goto tx_error_icmp;
		}
		dst = &rt->dst;
		skb_dst_set(skb, dst);
	}

	dst_hold(dst);
	dst = xfrm_lookup(tunnel->net, dst, fl, NULL, 0);
+2 −0
Original line number Diff line number Diff line
@@ -79,6 +79,8 @@ static struct sk_buff *esp6_gro_receive(struct list_head *head,
		if (!x)
			goto out_reset;

		skb->mark = xfrm_smark_get(skb->mark, x);

		sp->xvec[sp->len++] = x;
		sp->olen++;

+11 −2
Original line number Diff line number Diff line
@@ -449,8 +449,17 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
	int err = -1;
	int mtu;

	if (!dst)
	if (!dst) {
		fl->u.ip6.flowi6_oif = dev->ifindex;
		fl->u.ip6.flowi6_flags |= FLOWI_FLAG_ANYSRC;
		dst = ip6_route_output(dev_net(dev), NULL, &fl->u.ip6);
		if (dst->error) {
			dst_release(dst);
			dst = NULL;
			goto tx_err_link_failure;
		}
		skb_dst_set(skb, dst);
	}

	dst_hold(dst);
	dst = xfrm_lookup(t->net, dst, fl, NULL, 0);
+26 −8
Original line number Diff line number Diff line
@@ -268,9 +268,6 @@ xfrmi_xmit2(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
	int err = -1;
	int mtu;

	if (!dst)
		goto tx_err_link_failure;

	dst_hold(dst);
	dst = xfrm_lookup_with_ifid(xi->net, dst, fl, NULL, 0, xi->p.if_id);
	if (IS_ERR(dst)) {
@@ -297,7 +294,7 @@ xfrmi_xmit2(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)

	mtu = dst_mtu(dst);
	if (!skb->ignore_df && skb->len > mtu) {
		skb_dst_update_pmtu(skb, mtu);
		skb_dst_update_pmtu_no_confirm(skb, mtu);

		if (skb->protocol == htons(ETH_P_IPV6)) {
			if (mtu < IPV6_MIN_MTU)
@@ -343,6 +340,7 @@ static netdev_tx_t xfrmi_xmit(struct sk_buff *skb, struct net_device *dev)
{
	struct xfrm_if *xi = netdev_priv(dev);
	struct net_device_stats *stats = &xi->dev->stats;
	struct dst_entry *dst = skb_dst(skb);
	struct flowi fl;
	int ret;

@@ -352,10 +350,33 @@ static netdev_tx_t xfrmi_xmit(struct sk_buff *skb, struct net_device *dev)
	case htons(ETH_P_IPV6):
		xfrm_decode_session(skb, &fl, AF_INET6);
		memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
		if (!dst) {
			fl.u.ip6.flowi6_oif = dev->ifindex;
			fl.u.ip6.flowi6_flags |= FLOWI_FLAG_ANYSRC;
			dst = ip6_route_output(dev_net(dev), NULL, &fl.u.ip6);
			if (dst->error) {
				dst_release(dst);
				stats->tx_carrier_errors++;
				goto tx_err;
			}
			skb_dst_set(skb, dst);
		}
		break;
	case htons(ETH_P_IP):
		xfrm_decode_session(skb, &fl, AF_INET);
		memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
		if (!dst) {
			struct rtable *rt;

			fl.u.ip4.flowi4_oif = dev->ifindex;
			fl.u.ip4.flowi4_flags |= FLOWI_FLAG_ANYSRC;
			rt = __ip_route_output_key(dev_net(dev), &fl.u.ip4);
			if (IS_ERR(rt)) {
				stats->tx_carrier_errors++;
				goto tx_err;
			}
			skb_dst_set(skb, &rt->dst);
		}
		break;
	default:
		goto tx_err;
@@ -563,12 +584,9 @@ static void xfrmi_dev_setup(struct net_device *dev)
{
	dev->netdev_ops 	= &xfrmi_netdev_ops;
	dev->type		= ARPHRD_NONE;
	dev->hard_header_len 	= ETH_HLEN;
	dev->min_header_len	= ETH_HLEN;
	dev->mtu		= ETH_DATA_LEN;
	dev->min_mtu		= ETH_MIN_MTU;
	dev->max_mtu		= ETH_DATA_LEN;
	dev->addr_len		= ETH_ALEN;
	dev->max_mtu		= IP_MAX_MTU;
	dev->flags 		= IFF_NOARP;
	dev->needs_free_netdev	= true;
	dev->priv_destructor	= xfrmi_dev_free;