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


Steffen Klassert says:

====================
pull request (net): ipsec 2019-09-05

1) Several xfrm interface fixes from Nicolas Dichtel:
   - Avoid an interface ID corruption on changelink.
   - Fix wrong intterface names in the logs.
   - Fix a list corruption when changing network namespaces.
   - Fix unregistation of the underying phydev.

2) Fix a potential warning when merging xfrm_plocy nodes.
   From Florian Westphal.

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

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents f4b633b9 769a807d
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -983,7 +983,6 @@ static inline void xfrm_dst_destroy(struct xfrm_dst *xdst)
void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev);

struct xfrm_if_parms {
	char name[IFNAMSIZ];	/* name of XFRM device */
	int link;		/* ifindex of underlying L2 interface */
	u32 if_id;		/* interface identifyer */
};
@@ -991,7 +990,6 @@ struct xfrm_if_parms {
struct xfrm_if {
	struct xfrm_if __rcu *next;	/* next interface in list */
	struct net_device *dev;		/* virtual device associated with interface */
	struct net_device *phydev;	/* physical device */
	struct net *net;		/* netns for packet i/o */
	struct xfrm_if_parms p;		/* interface parms */

+25 −31
Original line number Diff line number Diff line
@@ -145,8 +145,6 @@ static int xfrmi_create(struct net_device *dev)
	if (err < 0)
		goto out;

	strcpy(xi->p.name, dev->name);

	dev_hold(dev);
	xfrmi_link(xfrmn, xi);

@@ -177,7 +175,6 @@ static void xfrmi_dev_uninit(struct net_device *dev)
	struct xfrmi_net *xfrmn = net_generic(xi->net, xfrmi_net_id);

	xfrmi_unlink(xfrmn, xi);
	dev_put(xi->phydev);
	dev_put(dev);
}

@@ -294,7 +291,7 @@ xfrmi_xmit2(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
	if (tdev == dev) {
		stats->collisions++;
		net_warn_ratelimited("%s: Local routing loop detected!\n",
				     xi->p.name);
				     dev->name);
		goto tx_err_dst_release;
	}

@@ -364,7 +361,7 @@ static netdev_tx_t xfrmi_xmit(struct sk_buff *skb, struct net_device *dev)
		goto tx_err;
	}

	fl.flowi_oif = xi->phydev->ifindex;
	fl.flowi_oif = xi->p.link;

	ret = xfrmi_xmit2(skb, dev, &fl);
	if (ret < 0)
@@ -505,7 +502,7 @@ static int xfrmi_change(struct xfrm_if *xi, const struct xfrm_if_parms *p)

static int xfrmi_update(struct xfrm_if *xi, struct xfrm_if_parms *p)
{
	struct net *net = dev_net(xi->dev);
	struct net *net = xi->net;
	struct xfrmi_net *xfrmn = net_generic(net, xfrmi_net_id);
	int err;

@@ -550,7 +547,7 @@ static int xfrmi_get_iflink(const struct net_device *dev)
{
	struct xfrm_if *xi = netdev_priv(dev);

	return xi->phydev->ifindex;
	return xi->p.link;
}


@@ -576,12 +573,14 @@ static void xfrmi_dev_setup(struct net_device *dev)
	dev->needs_free_netdev	= true;
	dev->priv_destructor	= xfrmi_dev_free;
	netif_keep_dst(dev);

	eth_broadcast_addr(dev->broadcast);
}

static int xfrmi_dev_init(struct net_device *dev)
{
	struct xfrm_if *xi = netdev_priv(dev);
	struct net_device *phydev = xi->phydev;
	struct net_device *phydev = __dev_get_by_index(xi->net, xi->p.link);
	int err;

	dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
@@ -596,13 +595,19 @@ static int xfrmi_dev_init(struct net_device *dev)

	dev->features |= NETIF_F_LLTX;

	if (phydev) {
		dev->needed_headroom = phydev->needed_headroom;
		dev->needed_tailroom = phydev->needed_tailroom;

		if (is_zero_ether_addr(dev->dev_addr))
			eth_hw_addr_inherit(dev, phydev);
		if (is_zero_ether_addr(dev->broadcast))
		memcpy(dev->broadcast, phydev->broadcast, dev->addr_len);
			memcpy(dev->broadcast, phydev->broadcast,
			       dev->addr_len);
	} else {
		eth_hw_addr_random(dev);
		eth_broadcast_addr(dev->broadcast);
	}

	return 0;
}
@@ -638,12 +643,6 @@ static int xfrmi_newlink(struct net *src_net, struct net_device *dev,
	int err;

	xfrmi_netlink_parms(data, &p);

	if (!tb[IFLA_IFNAME])
		return -EINVAL;

	nla_strlcpy(p.name, tb[IFLA_IFNAME], IFNAMSIZ);

	xi = xfrmi_locate(net, &p);
	if (xi)
		return -EEXIST;
@@ -652,13 +651,8 @@ static int xfrmi_newlink(struct net *src_net, struct net_device *dev,
	xi->p = p;
	xi->net = net;
	xi->dev = dev;
	xi->phydev = dev_get_by_index(net, p.link);
	if (!xi->phydev)
		return -ENODEV;

	err = xfrmi_create(dev);
	if (err < 0)
		dev_put(xi->phydev);
	return err;
}

@@ -672,11 +666,11 @@ static int xfrmi_changelink(struct net_device *dev, struct nlattr *tb[],
			   struct netlink_ext_ack *extack)
{
	struct xfrm_if *xi = netdev_priv(dev);
	struct net *net = dev_net(dev);

	xfrmi_netlink_parms(data, &xi->p);
	struct net *net = xi->net;
	struct xfrm_if_parms p;

	xi = xfrmi_locate(net, &xi->p);
	xfrmi_netlink_parms(data, &p);
	xi = xfrmi_locate(net, &p);
	if (!xi) {
		xi = netdev_priv(dev);
	} else {
@@ -684,7 +678,7 @@ static int xfrmi_changelink(struct net_device *dev, struct nlattr *tb[],
			return -EEXIST;
	}

	return xfrmi_update(xi, &xi->p);
	return xfrmi_update(xi, &p);
}

static size_t xfrmi_get_size(const struct net_device *dev)
@@ -715,7 +709,7 @@ static struct net *xfrmi_get_link_net(const struct net_device *dev)
{
	struct xfrm_if *xi = netdev_priv(dev);

	return dev_net(xi->phydev);
	return xi->net;
}

static const struct nla_policy xfrmi_policy[IFLA_XFRM_MAX + 1] = {
+4 −2
Original line number Diff line number Diff line
@@ -912,6 +912,7 @@ restart:
		} else if (delta > 0) {
			p = &parent->rb_right;
		} else {
			bool same_prefixlen = node->prefixlen == n->prefixlen;
			struct xfrm_policy *tmp;

			hlist_for_each_entry(tmp, &n->hhead, bydst) {
@@ -919,9 +920,11 @@ restart:
				hlist_del_rcu(&tmp->bydst);
			}

			node->prefixlen = prefixlen;

			xfrm_policy_inexact_list_reinsert(net, node, family);

			if (node->prefixlen == n->prefixlen) {
			if (same_prefixlen) {
				kfree_rcu(n, rcu);
				return;
			}
@@ -929,7 +932,6 @@ restart:
			rb_erase(*p, new);
			kfree_rcu(n, rcu);
			n = node;
			n->prefixlen = prefixlen;
			goto restart;
		}
	}
+7 −0
Original line number Diff line number Diff line
@@ -106,6 +106,13 @@ do_overlap()
    #
    # 10.0.0.0/24 and 10.0.1.0/24 nodes have been merged as 10.0.0.0/23.
    ip -net $ns xfrm policy add src 10.1.0.0/24 dst 10.0.0.0/23 dir fwd priority 200 action block

    # similar to above: add policies (with partially random address), with shrinking prefixes.
    for p in 29 28 27;do
      for k in $(seq 1 32); do
       ip -net $ns xfrm policy add src 10.253.1.$((RANDOM%255))/$p dst 10.254.1.$((RANDOM%255))/$p dir fwd priority $((200+k)) action block 2>/dev/null
      done
    done
}

do_esp_policy_get_check() {