When geneve_configure() allocates a new geneve_config structure via geneve_config_alloc() and assigns it to geneve->cfg before calling register_netdevice(), if register_netdevice() fails early (for example, in dev_get_valid_name() due to an invalid or duplicate interface name), register_netdevice() exits without calling dev->priv_destructor. The caller (e.g. rtnl_newlink()) subsequently calls free_netdev(), which frees the net_device structure directly via kvfree() because reg_state is NETREG_UNINITIALIZED, bypassing dev->priv_destructor (geneve_free_dev()). As a result, the newly allocated geneve_config and its per-CPU dst_cache are leaked. Fix this by invoking geneve_free_dev(dev) directly on the error path of register_netdevice(). Since geneve_free_dev() sets geneve->cfg to NULL, this call is fully idempotent and safe even if register_netdevice() failed on a later error path that already ran dev->priv_destructor. Fixes: 0ba269933f73 ("geneve: convert config to RCU-protected pointer") Signed-off-by: Eric Dumazet --- drivers/net/geneve.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index 17bd3543d587a9e941737109df82b83023d23711..eb156f33b62751b655178ad4f37d2c66f909ffc7 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c @@ -2043,8 +2043,10 @@ static int geneve_configure(struct net *net, struct net_device *dev, } err = register_netdevice(dev); - if (err) + if (err) { + geneve_free_dev(dev); return err; + } list_add(&geneve->next, &gn->geneve_list); return 0; -- 2.55.0.229.g6434b31f56-goog