Re: [PATCH net v2] ip_gre: Reject enabling collect metadata through changelink
From: Hangbin Liu
Date: Tue Sep 22 2026 - 21:06:33 EST
On Mon, Sep 21, 2026 at 11:18:59AM +0800, Xuanqiang Luo wrote:
> From: Xuanqiang Luo <luoxuanqiang@xxxxxxxxxx>
>
> ipgre_netlink_parms() can enable collect_md on an existing GRE, GRETAP
> or ERSPAN device. Unlike newlink, changelink does not enforce metadata
> tunnel uniqueness. Converting a non-metadata device can therefore
> replace the metadata receive entry for another device of the same type
> in the same netns. Deleting either device then clears the shared entry,
> breaking metadata receive lookup for the surviving device.
>
> If parameter validation fails after collect_md is set, deleting the
> modified device can also clear an entry it never owned.
>
> Reject enabling metadata mode in both changelink callbacks before any
> encapsulation or tunnel parameters are modified. Allow requests that
> repeat the metadata attribute on an existing metadata device.
>
> Fixes: 2e15ea390e6f ("ip_gre: Add support to collect tunnel metadata.")
> Signed-off-by: Xuanqiang Luo <luoxuanqiang@xxxxxxxxxx>
> ---
> Changes:
> v2:
> - Add an extack message when rejecting collect_md enablement in both
> changelink callbacks. (Ido Schimmel.)
> - Rebase onto the latest net/main.
>
> v1: https://lore.kernel.org/all/20260917095016.71937-1-xuanqiang.luo@xxxxxxxxx/
>
> The state change on failure can be reproduced without an existing
> metadata tunnel (output abbreviated):
>
> # ip link add g1 type gre local 192.0.2.1 remote 192.0.2.2
> # ip -d link show g1
> link/gre 192.0.2.1 peer 192.0.2.2 ...
> gre remote 192.0.2.2 local 192.0.2.1 ...
>
> # ip link set g1 type gre external
> RTNETLINK answers: Invalid argument
>
> # ip -d link show g1
> link/none c0:00:02:01 peer c0:00:02:02 ...
> gre external remote 192.0.2.2 local 192.0.2.1 ...
>
> # ip link del g1
>
> The request fails, but collect_md and the device type have already
> changed.
>
> If another metadata tunnel exists, deleting this device can clear its
> collect_md_tun entry. A successful conversion can overwrite that entry.
>
> net/ipv4/ip_gre.c | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
> diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
> index 82309efd417e0..e4878e9aa6367 100644
> --- a/net/ipv4/ip_gre.c
> +++ b/net/ipv4/ip_gre.c
> @@ -1464,6 +1464,12 @@ static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[],
> if (!rtnl_dev_link_net_capable(dev, t->net))
> return -EPERM;
>
> + if (data && data[IFLA_GRE_COLLECT_METADATA] && !t->collect_md) {
> + NL_SET_ERR_MSG(extack,
> + "Enabling collect_md on an existing device is not supported");
> + return -EOPNOTSUPP;
> + }
> +
> err = ipgre_newlink_encap_setup(dev, data);
> if (err)
> return err;
> @@ -1496,6 +1502,12 @@ static int erspan_changelink(struct net_device *dev, struct nlattr *tb[],
> if (!rtnl_dev_link_net_capable(dev, t->net))
> return -EPERM;
>
> + if (data && data[IFLA_GRE_COLLECT_METADATA] && !t->collect_md) {
> + NL_SET_ERR_MSG(extack,
> + "Enabling collect_md on an existing device is not supported");
> + return -EOPNOTSUPP;
> + }
> +
> err = ipgre_newlink_encap_setup(dev, data);
> if (err)
> return err;
>
> base-commit: 1e24c4f2ee44be0eee94092b5d13cbdb4bdf0d60
> --
> 2.43.0
>
Reviewed-by: Hangbin Liu <liuhangbin@xxxxxxxxxx>