The following functions are extended with a netlink_ext_ack argument to
allow extended error reporting:

* validate
* newlink
* changelink
* slave_validate
* slave_changelink

Signed-off-by: Matthias Schiffer <mschif...@universe-factory.net>
---

Checkpatch is unhappy about the long lines in include/net/rtnetlink.h, but
I guess it's as readable as it gets...

Most work was done by the following Coccinelle snippet, the original
version of which was provided by Johannes Berg:

@ops1@
identifier newfn, ops;
@@
struct rtnl_link_ops ops = {
        .newlink = newfn,
...
};

@@
identifier ops1.newfn;
identifier src_net, dev, tb, data;
@@
-int newfn(struct net *src_net, struct net_device *dev,
-          struct nlattr *tb[], struct nlattr *data[])
+int newfn(struct net *src_net, struct net_device *dev,
+          struct nlattr *tb[], struct nlattr *data[],
+          struct netlink_ext_ack *extack)
{...}

@ops2@
identifier chfn, ops;
@@
struct rtnl_link_ops ops = {
        .changelink = chfn,
...
};

@@
identifier ops2.chfn;
identifier dev, tb, data;
@@
-int chfn(struct net_device *dev,
-         struct nlattr *tb[], struct nlattr *data[])
+int chfn(struct net_device *dev,
+         struct nlattr *tb[], struct nlattr *data[],
+         struct netlink_ext_ack *extack)
{...}

@ops3@
identifier valfn, ops;
@@
struct rtnl_link_ops ops = {
        .validate = valfn,
...
};

@@
identifier ops3.valfn;
identifier tb, data;
@@
-int valfn(struct nlattr *tb[], struct nlattr *data[])
+int valfn(struct nlattr *tb[], struct nlattr *data[],
+          struct netlink_ext_ack *extack)
{...}

@ops4@
identifier chfn, ops;
@@
struct rtnl_link_ops ops = {
        .slave_changelink = chfn,
...
};

@@
identifier ops4.chfn;
identifier dev, slave_dev, tb, data;
@@
-int chfn(struct net_device *dev, struct net_device *slave_dev,
-         struct nlattr *tb[], struct nlattr *data[])
+int chfn(struct net_device *dev, struct net_device *slave_dev,
+         struct nlattr *tb[], struct nlattr *data[],
+         struct netlink_ext_ack *extack)
{...}

@ops5@
identifier valfn, ops;
@@
struct rtnl_link_ops ops = {
        .slave_validate = valfn,
...
};

@@
identifier ops5.valfn;
identifier tb, data;
@@
-int valfn(struct nlattr *tb[], struct nlattr *data[])
+int valfn(struct nlattr *tb[], struct nlattr *data[],
+          struct netlink_ext_ack *extack)
{...}

 drivers/infiniband/ulp/ipoib/ipoib_netlink.c | 10 ++++++----
 drivers/net/bonding/bond_netlink.c           | 16 ++++++++++------
 drivers/net/caif/caif_hsi.c                  |  6 ++++--
 drivers/net/can/dev.c                        | 11 +++++++----
 drivers/net/can/vxcan.c                      |  3 ++-
 drivers/net/dummy.c                          |  3 ++-
 drivers/net/geneve.c                         |  6 ++++--
 drivers/net/gtp.c                            |  6 ++++--
 drivers/net/ifb.c                            |  3 ++-
 drivers/net/ipvlan/ipvlan.h                  |  3 ++-
 drivers/net/ipvlan/ipvlan_main.c             |  9 ++++++---
 drivers/net/ipvlan/ipvtap.c                  |  9 ++++-----
 drivers/net/macsec.c                         |  9 ++++++---
 drivers/net/macvlan.c                        |  9 ++++++---
 drivers/net/macvtap.c                        |  7 +++----
 drivers/net/nlmon.c                          |  3 ++-
 drivers/net/ppp/ppp_generic.c                |  6 ++++--
 drivers/net/team/team.c                      |  6 ++++--
 drivers/net/tun.c                            |  3 ++-
 drivers/net/veth.c                           |  8 +++++---
 drivers/net/vrf.c                            |  6 ++++--
 drivers/net/vxlan.c                          |  9 ++++++---
 include/net/rtnetlink.h                      | 15 ++++++++++-----
 net/8021q/vlan_netlink.c                     | 13 ++++++++-----
 net/bridge/br_netlink.c                      | 15 ++++++++++-----
 net/caif/chnl_net.c                          |  6 ++++--
 net/core/rtnetlink.c                         | 13 ++++++++-----
 net/hsr/hsr_netlink.c                        |  3 ++-
 net/ieee802154/6lowpan/core.c                |  6 ++++--
 net/ipv4/ip_gre.c                            | 16 ++++++++++------
 net/ipv4/ip_vti.c                            |  9 ++++++---
 net/ipv4/ipip.c                              |  9 ++++++---
 net/ipv6/ip6_gre.c                           | 14 +++++++++-----
 net/ipv6/ip6_tunnel.c                        |  9 ++++++---
 net/ipv6/ip6_vti.c                           |  9 ++++++---
 net/ipv6/sit.c                               |  9 ++++++---
 36 files changed, 190 insertions(+), 107 deletions(-)

diff --git a/drivers/infiniband/ulp/ipoib/ipoib_netlink.c 
b/drivers/infiniband/ulp/ipoib/ipoib_netlink.c
index 28884781311b..3e44087935ae 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_netlink.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_netlink.c
@@ -64,8 +64,9 @@ static int ipoib_fill_info(struct sk_buff *skb, const struct 
net_device *dev)
        return -EMSGSIZE;
 }
 
-static int ipoib_changelink(struct net_device *dev,
-                           struct nlattr *tb[], struct nlattr *data[])
+static int ipoib_changelink(struct net_device *dev, struct nlattr *tb[],
+                           struct nlattr *data[],
+                           struct netlink_ext_ack *extack)
 {
        u16 mode, umcast;
        int ret = 0;
@@ -93,7 +94,8 @@ static int ipoib_changelink(struct net_device *dev,
 }
 
 static int ipoib_new_child_link(struct net *src_net, struct net_device *dev,
-                              struct nlattr *tb[], struct nlattr *data[])
+                               struct nlattr *tb[], struct nlattr *data[],
+                               struct netlink_ext_ack *extack)
 {
        struct net_device *pdev;
        struct ipoib_dev_priv *ppriv;
@@ -133,7 +135,7 @@ static int ipoib_new_child_link(struct net *src_net, struct 
net_device *dev,
                               child_pkey, IPOIB_RTNL_CHILD);
 
        if (!err && data)
-               err = ipoib_changelink(dev, tb, data);
+               err = ipoib_changelink(dev, tb, data, extack);
        return err;
 }
 
diff --git a/drivers/net/bonding/bond_netlink.c 
b/drivers/net/bonding/bond_netlink.c
index 47a8103610bc..a1b33aa6054a 100644
--- a/drivers/net/bonding/bond_netlink.c
+++ b/drivers/net/bonding/bond_netlink.c
@@ -118,7 +118,8 @@ static const struct nla_policy 
bond_slave_policy[IFLA_BOND_SLAVE_MAX + 1] = {
        [IFLA_BOND_SLAVE_QUEUE_ID]      = { .type = NLA_U16 },
 };
 
-static int bond_validate(struct nlattr *tb[], struct nlattr *data[])
+static int bond_validate(struct nlattr *tb[], struct nlattr *data[],
+                        struct netlink_ext_ack *extack)
 {
        if (tb[IFLA_ADDRESS]) {
                if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
@@ -131,7 +132,8 @@ static int bond_validate(struct nlattr *tb[], struct nlattr 
*data[])
 
 static int bond_slave_changelink(struct net_device *bond_dev,
                                 struct net_device *slave_dev,
-                                struct nlattr *tb[], struct nlattr *data[])
+                                struct nlattr *tb[], struct nlattr *data[],
+                                struct netlink_ext_ack *extack)
 {
        struct bonding *bond = netdev_priv(bond_dev);
        struct bond_opt_value newval;
@@ -156,8 +158,9 @@ static int bond_slave_changelink(struct net_device 
*bond_dev,
        return 0;
 }
 
-static int bond_changelink(struct net_device *bond_dev,
-                          struct nlattr *tb[], struct nlattr *data[])
+static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[],
+                          struct nlattr *data[],
+                          struct netlink_ext_ack *extack)
 {
        struct bonding *bond = netdev_priv(bond_dev);
        struct bond_opt_value newval;
@@ -438,11 +441,12 @@ static int bond_changelink(struct net_device *bond_dev,
 }
 
 static int bond_newlink(struct net *src_net, struct net_device *bond_dev,
-                       struct nlattr *tb[], struct nlattr *data[])
+                       struct nlattr *tb[], struct nlattr *data[],
+                       struct netlink_ext_ack *extack)
 {
        int err;
 
-       err = bond_changelink(bond_dev, tb, data);
+       err = bond_changelink(bond_dev, tb, data, extack);
        if (err < 0)
                return err;
 
diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c
index 11ba6e3eea22..438966bf51c2 100644
--- a/drivers/net/caif/caif_hsi.c
+++ b/drivers/net/caif/caif_hsi.c
@@ -1352,7 +1352,8 @@ static void cfhsi_netlink_parms(struct nlattr *data[], 
struct cfhsi *cfhsi)
 }
 
 static int caif_hsi_changelink(struct net_device *dev, struct nlattr *tb[],
-                               struct nlattr *data[])
+                              struct nlattr *data[],
+                              struct netlink_ext_ack *extack)
 {
        cfhsi_netlink_parms(data, netdev_priv(dev));
        netdev_state_change(dev);
@@ -1399,7 +1400,8 @@ static int caif_hsi_fill_info(struct sk_buff *skb, const 
struct net_device *dev)
 }
 
 static int caif_hsi_newlink(struct net *src_net, struct net_device *dev,
-                         struct nlattr *tb[], struct nlattr *data[])
+                           struct nlattr *tb[], struct nlattr *data[],
+                           struct netlink_ext_ack *extack)
 {
        struct cfhsi *cfhsi = NULL;
        struct cfhsi_ops *(*get_ops)(void);
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
index a3011c001080..365a8cc62405 100644
--- a/drivers/net/can/dev.c
+++ b/drivers/net/can/dev.c
@@ -848,7 +848,8 @@ static const struct nla_policy can_policy[IFLA_CAN_MAX + 1] 
= {
                                = { .len = sizeof(struct can_bittiming_const) },
 };
 
-static int can_validate(struct nlattr *tb[], struct nlattr *data[])
+static int can_validate(struct nlattr *tb[], struct nlattr *data[],
+                       struct netlink_ext_ack *extack)
 {
        bool is_can_fd = false;
 
@@ -880,8 +881,9 @@ static int can_validate(struct nlattr *tb[], struct nlattr 
*data[])
        return 0;
 }
 
-static int can_changelink(struct net_device *dev,
-                         struct nlattr *tb[], struct nlattr *data[])
+static int can_changelink(struct net_device *dev, struct nlattr *tb[],
+                         struct nlattr *data[],
+                         struct netlink_ext_ack *extack)
 {
        struct can_priv *priv = netdev_priv(dev);
        int err;
@@ -1146,7 +1148,8 @@ static int can_fill_xstats(struct sk_buff *skb, const 
struct net_device *dev)
 }
 
 static int can_newlink(struct net *src_net, struct net_device *dev,
-                      struct nlattr *tb[], struct nlattr *data[])
+                      struct nlattr *tb[], struct nlattr *data[],
+                      struct netlink_ext_ack *extack)
 {
        return -EOPNOTSUPP;
 }
diff --git a/drivers/net/can/vxcan.c b/drivers/net/can/vxcan.c
index cfe889e8f172..8404e8852a0f 100644
--- a/drivers/net/can/vxcan.c
+++ b/drivers/net/can/vxcan.c
@@ -163,7 +163,8 @@ static void vxcan_setup(struct net_device *dev)
 static struct rtnl_link_ops vxcan_link_ops;
 
 static int vxcan_newlink(struct net *net, struct net_device *dev,
-                        struct nlattr *tb[], struct nlattr *data[])
+                        struct nlattr *tb[], struct nlattr *data[],
+                        struct netlink_ext_ack *extack)
 {
        struct vxcan_priv *priv;
        struct net_device *peer;
diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c
index 9905b52fe293..d0c165d2086e 100644
--- a/drivers/net/dummy.c
+++ b/drivers/net/dummy.c
@@ -356,7 +356,8 @@ static void dummy_setup(struct net_device *dev)
        dev->max_mtu = ETH_MAX_MTU;
 }
 
-static int dummy_validate(struct nlattr *tb[], struct nlattr *data[])
+static int dummy_validate(struct nlattr *tb[], struct nlattr *data[],
+                         struct netlink_ext_ack *extack)
 {
        if (tb[IFLA_ADDRESS]) {
                if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
index d586ad93aaff..eb77201cb718 100644
--- a/drivers/net/geneve.c
+++ b/drivers/net/geneve.c
@@ -1058,7 +1058,8 @@ static const struct nla_policy 
geneve_policy[IFLA_GENEVE_MAX + 1] = {
        [IFLA_GENEVE_UDP_ZERO_CSUM6_RX] = { .type = NLA_U8 },
 };
 
-static int geneve_validate(struct nlattr *tb[], struct nlattr *data[])
+static int geneve_validate(struct nlattr *tb[], struct nlattr *data[],
+                          struct netlink_ext_ack *extack)
 {
        if (tb[IFLA_ADDRESS]) {
                if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
@@ -1181,7 +1182,8 @@ static void init_tnl_info(struct ip_tunnel_info *info, 
__u16 dst_port)
 }
 
 static int geneve_newlink(struct net *net, struct net_device *dev,
-                         struct nlattr *tb[], struct nlattr *data[])
+                         struct nlattr *tb[], struct nlattr *data[],
+                         struct netlink_ext_ack *extack)
 {
        bool use_udp6_rx_checksums = false;
        struct ip_tunnel_info info;
diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
index 8e333a8a2295..1542e837fdfa 100644
--- a/drivers/net/gtp.c
+++ b/drivers/net/gtp.c
@@ -636,7 +636,8 @@ static void gtp_hashtable_free(struct gtp_dev *gtp);
 static int gtp_encap_enable(struct gtp_dev *gtp, struct nlattr *data[]);
 
 static int gtp_newlink(struct net *src_net, struct net_device *dev,
-                       struct nlattr *tb[], struct nlattr *data[])
+                      struct nlattr *tb[], struct nlattr *data[],
+                      struct netlink_ext_ack *extack)
 {
        struct gtp_dev *gtp;
        struct gtp_net *gn;
@@ -697,7 +698,8 @@ static const struct nla_policy gtp_policy[IFLA_GTP_MAX + 1] 
= {
        [IFLA_GTP_ROLE]                 = { .type = NLA_U32 },
 };
 
-static int gtp_validate(struct nlattr *tb[], struct nlattr *data[])
+static int gtp_validate(struct nlattr *tb[], struct nlattr *data[],
+                       struct netlink_ext_ack *extack)
 {
        if (!data)
                return -EINVAL;
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index 144ea5ae8ab4..8870bd2a2e8a 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -273,7 +273,8 @@ static int ifb_open(struct net_device *dev)
        return 0;
 }
 
-static int ifb_validate(struct nlattr *tb[], struct nlattr *data[])
+static int ifb_validate(struct nlattr *tb[], struct nlattr *data[],
+                       struct netlink_ext_ack *extack)
 {
        if (tb[IFLA_ADDRESS]) {
                if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
diff --git a/drivers/net/ipvlan/ipvlan.h b/drivers/net/ipvlan/ipvlan.h
index 7919369c0a72..ba8173a0b62e 100644
--- a/drivers/net/ipvlan/ipvlan.h
+++ b/drivers/net/ipvlan/ipvlan.h
@@ -140,7 +140,8 @@ unsigned int ipvlan_nf_input(void *priv, struct sk_buff 
*skb,
 void ipvlan_count_rx(const struct ipvl_dev *ipvlan,
                     unsigned int len, bool success, bool mcast);
 int ipvlan_link_new(struct net *src_net, struct net_device *dev,
-                   struct nlattr *tb[], struct nlattr *data[]);
+                   struct nlattr *tb[], struct nlattr *data[],
+                   struct netlink_ext_ack *extack);
 void ipvlan_link_delete(struct net_device *dev, struct list_head *head);
 void ipvlan_link_setup(struct net_device *dev);
 int ipvlan_link_register(struct rtnl_link_ops *ops);
diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c
index dc888dd344eb..f37e3c1fd4e7 100644
--- a/drivers/net/ipvlan/ipvlan_main.c
+++ b/drivers/net/ipvlan/ipvlan_main.c
@@ -455,7 +455,8 @@ static const struct ethtool_ops ipvlan_ethtool_ops = {
 };
 
 static int ipvlan_nl_changelink(struct net_device *dev,
-                               struct nlattr *tb[], struct nlattr *data[])
+                               struct nlattr *tb[], struct nlattr *data[],
+                               struct netlink_ext_ack *extack)
 {
        struct ipvl_dev *ipvlan = netdev_priv(dev);
        struct ipvl_port *port = ipvlan_port_get_rtnl(ipvlan->phy_dev);
@@ -476,7 +477,8 @@ static size_t ipvlan_nl_getsize(const struct net_device 
*dev)
                );
 }
 
-static int ipvlan_nl_validate(struct nlattr *tb[], struct nlattr *data[])
+static int ipvlan_nl_validate(struct nlattr *tb[], struct nlattr *data[],
+                             struct netlink_ext_ack *extack)
 {
        if (data && data[IFLA_IPVLAN_MODE]) {
                u16 mode = nla_get_u16(data[IFLA_IPVLAN_MODE]);
@@ -508,7 +510,8 @@ static int ipvlan_nl_fillinfo(struct sk_buff *skb,
 }
 
 int ipvlan_link_new(struct net *src_net, struct net_device *dev,
-                   struct nlattr *tb[], struct nlattr *data[])
+                   struct nlattr *tb[], struct nlattr *data[],
+                   struct netlink_ext_ack *extack)
 {
        struct ipvl_dev *ipvlan = netdev_priv(dev);
        struct ipvl_port *port;
diff --git a/drivers/net/ipvlan/ipvtap.c b/drivers/net/ipvlan/ipvtap.c
index 2b713b63b62c..22f133ea8d7b 100644
--- a/drivers/net/ipvlan/ipvtap.c
+++ b/drivers/net/ipvlan/ipvtap.c
@@ -73,10 +73,9 @@ static void ipvtap_update_features(struct tap_dev *tap,
        netdev_update_features(vlan->dev);
 }
 
-static int ipvtap_newlink(struct net *src_net,
-                         struct net_device *dev,
-                         struct nlattr *tb[],
-                         struct nlattr *data[])
+static int ipvtap_newlink(struct net *src_net, struct net_device *dev,
+                         struct nlattr *tb[], struct nlattr *data[],
+                         struct netlink_ext_ack *extack)
 {
        struct ipvtap_dev *vlantap = netdev_priv(dev);
        int err;
@@ -98,7 +97,7 @@ static int ipvtap_newlink(struct net *src_net,
        /* Don't put anything that may fail after macvlan_common_newlink
         * because we can't undo what it does.
         */
-       err =  ipvlan_link_new(src_net, dev, tb, data);
+       err =  ipvlan_link_new(src_net, dev, tb, data, extack);
        if (err) {
                netdev_rx_handler_unregister(dev);
                return err;
diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
index e370d7c894cb..5e1ab1160856 100644
--- a/drivers/net/macsec.c
+++ b/drivers/net/macsec.c
@@ -3056,7 +3056,8 @@ static void macsec_changelink_common(struct net_device 
*dev,
 }
 
 static int macsec_changelink(struct net_device *dev, struct nlattr *tb[],
-                            struct nlattr *data[])
+                            struct nlattr *data[],
+                            struct netlink_ext_ack *extack)
 {
        if (!data)
                return 0;
@@ -3203,7 +3204,8 @@ static int macsec_add_dev(struct net_device *dev, sci_t 
sci, u8 icv_len)
 }
 
 static int macsec_newlink(struct net *net, struct net_device *dev,
-                         struct nlattr *tb[], struct nlattr *data[])
+                         struct nlattr *tb[], struct nlattr *data[],
+                         struct netlink_ext_ack *extack)
 {
        struct macsec_dev *macsec = macsec_priv(dev);
        struct net_device *real_dev;
@@ -3285,7 +3287,8 @@ static int macsec_newlink(struct net *net, struct 
net_device *dev,
        return err;
 }
 
-static int macsec_validate_attr(struct nlattr *tb[], struct nlattr *data[])
+static int macsec_validate_attr(struct nlattr *tb[], struct nlattr *data[],
+                               struct netlink_ext_ack *extack)
 {
        u64 csid = MACSEC_DEFAULT_CIPHER_ID;
        u8 icv_len = DEFAULT_ICV_LEN;
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 8ca274c6df3d..9ffff0362a11 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -1162,7 +1162,8 @@ static void macvlan_port_destroy(struct net_device *dev)
        kfree(port);
 }
 
-static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[])
+static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[],
+                           struct netlink_ext_ack *extack)
 {
        if (tb[IFLA_ADDRESS]) {
                if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
@@ -1390,7 +1391,8 @@ int macvlan_common_newlink(struct net *src_net, struct 
net_device *dev,
 EXPORT_SYMBOL_GPL(macvlan_common_newlink);
 
 static int macvlan_newlink(struct net *src_net, struct net_device *dev,
-                          struct nlattr *tb[], struct nlattr *data[])
+                          struct nlattr *tb[], struct nlattr *data[],
+                          struct netlink_ext_ack *extack)
 {
        return macvlan_common_newlink(src_net, dev, tb, data);
 }
@@ -1408,7 +1410,8 @@ void macvlan_dellink(struct net_device *dev, struct 
list_head *head)
 EXPORT_SYMBOL_GPL(macvlan_dellink);
 
 static int macvlan_changelink(struct net_device *dev,
-               struct nlattr *tb[], struct nlattr *data[])
+                             struct nlattr *tb[], struct nlattr *data[],
+                             struct netlink_ext_ack *extack)
 {
        struct macvlan_dev *vlan = netdev_priv(dev);
        enum macvlan_mode mode;
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index da85057680d6..91e7b19bbf86 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -77,10 +77,9 @@ static void macvtap_update_features(struct tap_dev *tap,
        netdev_update_features(vlan->dev);
 }
 
-static int macvtap_newlink(struct net *src_net,
-                          struct net_device *dev,
-                          struct nlattr *tb[],
-                          struct nlattr *data[])
+static int macvtap_newlink(struct net *src_net, struct net_device *dev,
+                          struct nlattr *tb[], struct nlattr *data[],
+                          struct netlink_ext_ack *extack)
 {
        struct macvtap_dev *vlantap = netdev_priv(dev);
        int err;
diff --git a/drivers/net/nlmon.c b/drivers/net/nlmon.c
index c4b3362da4a2..4b22955de191 100644
--- a/drivers/net/nlmon.c
+++ b/drivers/net/nlmon.c
@@ -127,7 +127,8 @@ static void nlmon_setup(struct net_device *dev)
        dev->min_mtu = sizeof(struct nlmsghdr);
 }
 
-static int nlmon_validate(struct nlattr *tb[], struct nlattr *data[])
+static int nlmon_validate(struct nlattr *tb[], struct nlattr *data[],
+                         struct netlink_ext_ack *extack)
 {
        if (tb[IFLA_ADDRESS])
                return -EINVAL;
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index d42091f11eb8..13028833bee3 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -1061,7 +1061,8 @@ static const struct nla_policy ppp_nl_policy[IFLA_PPP_MAX 
+ 1] = {
        [IFLA_PPP_DEV_FD]       = { .type = NLA_S32 },
 };
 
-static int ppp_nl_validate(struct nlattr *tb[], struct nlattr *data[])
+static int ppp_nl_validate(struct nlattr *tb[], struct nlattr *data[],
+                          struct netlink_ext_ack *extack)
 {
        if (!data)
                return -EINVAL;
@@ -1075,7 +1076,8 @@ static int ppp_nl_validate(struct nlattr *tb[], struct 
nlattr *data[])
 }
 
 static int ppp_nl_newlink(struct net *src_net, struct net_device *dev,
-                         struct nlattr *tb[], struct nlattr *data[])
+                         struct nlattr *tb[], struct nlattr *data[],
+                         struct netlink_ext_ack *extack)
 {
        struct ppp_config conf = {
                .unit = -1,
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 629a412dc690..464570409796 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -2101,7 +2101,8 @@ static void team_setup(struct net_device *dev)
 }
 
 static int team_newlink(struct net *src_net, struct net_device *dev,
-                       struct nlattr *tb[], struct nlattr *data[])
+                       struct nlattr *tb[], struct nlattr *data[],
+                       struct netlink_ext_ack *extack)
 {
        if (tb[IFLA_ADDRESS] == NULL)
                eth_hw_addr_random(dev);
@@ -2109,7 +2110,8 @@ static int team_newlink(struct net *src_net, struct 
net_device *dev,
        return register_netdevice(dev);
 }
 
-static int team_validate(struct nlattr *tb[], struct nlattr *data[])
+static int team_validate(struct nlattr *tb[], struct nlattr *data[],
+                        struct netlink_ext_ack *extack)
 {
        if (tb[IFLA_ADDRESS]) {
                if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index ae49f4b99b67..3d4c24572ecd 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1580,7 +1580,8 @@ static void tun_setup(struct net_device *dev)
 /* Trivial set of netlink ops to allow deleting tun or tap
  * device with netlink.
  */
-static int tun_validate(struct nlattr *tb[], struct nlattr *data[])
+static int tun_validate(struct nlattr *tb[], struct nlattr *data[],
+                       struct netlink_ext_ack *extack)
 {
        return -EINVAL;
 }
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 0156fe8cac17..b33553b1e19c 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -329,7 +329,8 @@ static void veth_setup(struct net_device *dev)
  * netlink interface
  */
 
-static int veth_validate(struct nlattr *tb[], struct nlattr *data[])
+static int veth_validate(struct nlattr *tb[], struct nlattr *data[],
+                        struct netlink_ext_ack *extack)
 {
        if (tb[IFLA_ADDRESS]) {
                if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
@@ -347,7 +348,8 @@ static int veth_validate(struct nlattr *tb[], struct nlattr 
*data[])
 static struct rtnl_link_ops veth_link_ops;
 
 static int veth_newlink(struct net *src_net, struct net_device *dev,
-                        struct nlattr *tb[], struct nlattr *data[])
+                       struct nlattr *tb[], struct nlattr *data[],
+                       struct netlink_ext_ack *extack)
 {
        int err;
        struct net_device *peer;
@@ -373,7 +375,7 @@ static int veth_newlink(struct net *src_net, struct 
net_device *dev,
                if (err < 0)
                        return err;
 
-               err = veth_validate(peer_tb, NULL);
+               err = veth_validate(peer_tb, NULL, extack);
                if (err < 0)
                        return err;
 
diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
index 997ef25189fd..f4d0054981c6 100644
--- a/drivers/net/vrf.c
+++ b/drivers/net/vrf.c
@@ -1372,7 +1372,8 @@ static void vrf_setup(struct net_device *dev)
        dev->priv_flags |= IFF_NO_QUEUE;
 }
 
-static int vrf_validate(struct nlattr *tb[], struct nlattr *data[])
+static int vrf_validate(struct nlattr *tb[], struct nlattr *data[],
+                       struct netlink_ext_ack *extack)
 {
        if (tb[IFLA_ADDRESS]) {
                if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
@@ -1389,7 +1390,8 @@ static void vrf_dellink(struct net_device *dev, struct 
list_head *head)
 }
 
 static int vrf_newlink(struct net *src_net, struct net_device *dev,
-                      struct nlattr *tb[], struct nlattr *data[])
+                      struct nlattr *tb[], struct nlattr *data[],
+                      struct netlink_ext_ack *extack)
 {
        struct net_vrf *vrf = netdev_priv(dev);
        bool *add_fib_rules;
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 653b2bb32be1..0dafd8e6c665 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -2711,7 +2711,8 @@ static const struct nla_policy 
vxlan_policy[IFLA_VXLAN_MAX + 1] = {
        [IFLA_VXLAN_REMCSUM_NOPARTIAL]  = { .type = NLA_FLAG },
 };
 
-static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[])
+static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[],
+                         struct netlink_ext_ack *extack)
 {
        if (tb[IFLA_ADDRESS]) {
                if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN) {
@@ -3333,7 +3334,8 @@ static int vxlan_nl2conf(struct nlattr *tb[], struct 
nlattr *data[],
 }
 
 static int vxlan_newlink(struct net *src_net, struct net_device *dev,
-                        struct nlattr *tb[], struct nlattr *data[])
+                        struct nlattr *tb[], struct nlattr *data[],
+                        struct netlink_ext_ack *extack)
 {
        struct vxlan_config conf;
        int err;
@@ -3346,7 +3348,8 @@ static int vxlan_newlink(struct net *src_net, struct 
net_device *dev,
 }
 
 static int vxlan_changelink(struct net_device *dev, struct nlattr *tb[],
-                           struct nlattr *data[])
+                           struct nlattr *data[],
+                           struct netlink_ext_ack *extack)
 {
        struct vxlan_dev *vxlan = netdev_priv(dev);
        struct vxlan_rdst *dst = &vxlan->default_dst;
diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h
index 78fa5fe32947..abe6b733d473 100644
--- a/include/net/rtnetlink.h
+++ b/include/net/rtnetlink.h
@@ -63,15 +63,18 @@ struct rtnl_link_ops {
        int                     maxtype;
        const struct nla_policy *policy;
        int                     (*validate)(struct nlattr *tb[],
-                                           struct nlattr *data[]);
+                                           struct nlattr *data[],
+                                           struct netlink_ext_ack *extack);
 
        int                     (*newlink)(struct net *src_net,
                                           struct net_device *dev,
                                           struct nlattr *tb[],
-                                          struct nlattr *data[]);
+                                          struct nlattr *data[],
+                                          struct netlink_ext_ack *extack);
        int                     (*changelink)(struct net_device *dev,
                                              struct nlattr *tb[],
-                                             struct nlattr *data[]);
+                                             struct nlattr *data[],
+                                             struct netlink_ext_ack *extack);
        void                    (*dellink)(struct net_device *dev,
                                           struct list_head *head);
 
@@ -88,11 +91,13 @@ struct rtnl_link_ops {
        int                     slave_maxtype;
        const struct nla_policy *slave_policy;
        int                     (*slave_validate)(struct nlattr *tb[],
-                                                 struct nlattr *data[]);
+                                                 struct nlattr *data[],
+                                                 struct netlink_ext_ack 
*extack);
        int                     (*slave_changelink)(struct net_device *dev,
                                                    struct net_device 
*slave_dev,
                                                    struct nlattr *tb[],
-                                                   struct nlattr *data[]);
+                                                   struct nlattr *data[],
+                                                   struct netlink_ext_ack 
*extack);
        size_t                  (*get_slave_size)(const struct net_device *dev,
                                                  const struct net_device 
*slave_dev);
        int                     (*fill_slave_info)(struct sk_buff *skb,
diff --git a/net/8021q/vlan_netlink.c b/net/8021q/vlan_netlink.c
index 9c94aad153b3..5e831de3103e 100644
--- a/net/8021q/vlan_netlink.c
+++ b/net/8021q/vlan_netlink.c
@@ -39,7 +39,8 @@ static inline int vlan_validate_qos_map(struct nlattr *attr)
                                   NULL);
 }
 
-static int vlan_validate(struct nlattr *tb[], struct nlattr *data[])
+static int vlan_validate(struct nlattr *tb[], struct nlattr *data[],
+                        struct netlink_ext_ack *extack)
 {
        struct ifla_vlan_flags *flags;
        u16 id;
@@ -87,8 +88,9 @@ static int vlan_validate(struct nlattr *tb[], struct nlattr 
*data[])
        return 0;
 }
 
-static int vlan_changelink(struct net_device *dev,
-                          struct nlattr *tb[], struct nlattr *data[])
+static int vlan_changelink(struct net_device *dev, struct nlattr *tb[],
+                          struct nlattr *data[],
+                          struct netlink_ext_ack *extack)
 {
        struct ifla_vlan_flags *flags;
        struct ifla_vlan_qos_mapping *m;
@@ -115,7 +117,8 @@ static int vlan_changelink(struct net_device *dev,
 }
 
 static int vlan_newlink(struct net *src_net, struct net_device *dev,
-                       struct nlattr *tb[], struct nlattr *data[])
+                       struct nlattr *tb[], struct nlattr *data[],
+                       struct netlink_ext_ack *extack)
 {
        struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
        struct net_device *real_dev;
@@ -153,7 +156,7 @@ static int vlan_newlink(struct net *src_net, struct 
net_device *dev,
        else if (dev->mtu > max_mtu)
                return -EINVAL;
 
-       err = vlan_changelink(dev, tb, data);
+       err = vlan_changelink(dev, tb, data, extack);
        if (err < 0)
                return err;
 
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index 63dca347b73b..3bc890716c89 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -858,7 +858,9 @@ int br_dellink(struct net_device *dev, struct nlmsghdr 
*nlh, u16 flags)
 
        return err;
 }
-static int br_validate(struct nlattr *tb[], struct nlattr *data[])
+
+static int br_validate(struct nlattr *tb[], struct nlattr *data[],
+                      struct netlink_ext_ack *extack)
 {
        if (tb[IFLA_ADDRESS]) {
                if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
@@ -895,7 +897,8 @@ static int br_validate(struct nlattr *tb[], struct nlattr 
*data[])
 static int br_port_slave_changelink(struct net_device *brdev,
                                    struct net_device *dev,
                                    struct nlattr *tb[],
-                                   struct nlattr *data[])
+                                   struct nlattr *data[],
+                                   struct netlink_ext_ack *extack)
 {
        struct net_bridge *br = netdev_priv(brdev);
        int ret;
@@ -960,7 +963,8 @@ static const struct nla_policy br_policy[IFLA_BR_MAX + 1] = 
{
 };
 
 static int br_changelink(struct net_device *brdev, struct nlattr *tb[],
-                        struct nlattr *data[])
+                        struct nlattr *data[],
+                        struct netlink_ext_ack *extack)
 {
        struct net_bridge *br = netdev_priv(brdev);
        int err;
@@ -1213,7 +1217,8 @@ static int br_changelink(struct net_device *brdev, struct 
nlattr *tb[],
 }
 
 static int br_dev_newlink(struct net *src_net, struct net_device *dev,
-                         struct nlattr *tb[], struct nlattr *data[])
+                         struct nlattr *tb[], struct nlattr *data[],
+                         struct netlink_ext_ack *extack)
 {
        struct net_bridge *br = netdev_priv(dev);
        int err;
@@ -1228,7 +1233,7 @@ static int br_dev_newlink(struct net *src_net, struct 
net_device *dev,
        if (err)
                return err;
 
-       err = br_changelink(dev, tb, data);
+       err = br_changelink(dev, tb, data, extack);
        if (err)
                unregister_netdevice(dev);
        return err;
diff --git a/net/caif/chnl_net.c b/net/caif/chnl_net.c
index fe3c53efb949..922ac1d605b3 100644
--- a/net/caif/chnl_net.c
+++ b/net/caif/chnl_net.c
@@ -461,7 +461,8 @@ static void caif_netlink_parms(struct nlattr *data[],
 }
 
 static int ipcaif_newlink(struct net *src_net, struct net_device *dev,
-                         struct nlattr *tb[], struct nlattr *data[])
+                         struct nlattr *tb[], struct nlattr *data[],
+                         struct netlink_ext_ack *extack)
 {
        int ret;
        struct chnl_net *caifdev;
@@ -484,7 +485,8 @@ static int ipcaif_newlink(struct net *src_net, struct 
net_device *dev,
 }
 
 static int ipcaif_changelink(struct net_device *dev, struct nlattr *tb[],
-                            struct nlattr *data[])
+                            struct nlattr *data[],
+                            struct netlink_ext_ack *extack)
 {
        struct chnl_net *caifdev;
        ASSERT_RTNL();
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 9a1bd510c812..ed51de525a88 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2582,7 +2582,7 @@ static int rtnl_newlink(struct sk_buff *skb, struct 
nlmsghdr *nlh,
                                data = attr;
                        }
                        if (ops->validate) {
-                               err = ops->validate(tb, data);
+                               err = ops->validate(tb, data, extack);
                                if (err < 0)
                                        return err;
                        }
@@ -2601,7 +2601,8 @@ static int rtnl_newlink(struct sk_buff *skb, struct 
nlmsghdr *nlh,
                                slave_data = slave_attr;
                        }
                        if (m_ops->slave_validate) {
-                               err = m_ops->slave_validate(tb, slave_data);
+                               err = m_ops->slave_validate(tb, slave_data,
+                                                           extack);
                                if (err < 0)
                                        return err;
                        }
@@ -2620,7 +2621,7 @@ static int rtnl_newlink(struct sk_buff *skb, struct 
nlmsghdr *nlh,
                                    !ops->changelink)
                                        return -EOPNOTSUPP;
 
-                               err = ops->changelink(dev, tb, data);
+                               err = ops->changelink(dev, tb, data, extack);
                                if (err < 0)
                                        return err;
                                status |= DO_SETLINK_NOTIFY;
@@ -2631,7 +2632,8 @@ static int rtnl_newlink(struct sk_buff *skb, struct 
nlmsghdr *nlh,
                                        return -EOPNOTSUPP;
 
                                err = m_ops->slave_changelink(master_dev, dev,
-                                                             tb, slave_data);
+                                                             tb, slave_data,
+                                                             extack);
                                if (err < 0)
                                        return err;
                                status |= DO_SETLINK_NOTIFY;
@@ -2705,7 +2707,8 @@ static int rtnl_newlink(struct sk_buff *skb, struct 
nlmsghdr *nlh,
                dev->ifindex = ifm->ifi_index;
 
                if (ops->newlink) {
-                       err = ops->newlink(link_net ? : net, dev, tb, data);
+                       err = ops->newlink(link_net ? : net, dev, tb, data,
+                                          extack);
                        /* Drivers should call free_netdev() in ->destructor
                         * and unregister it on failure after registration
                         * so that device could be finally freed in rtnl_unlock.
diff --git a/net/hsr/hsr_netlink.c b/net/hsr/hsr_netlink.c
index 81dac16933fc..b9cce0fd5696 100644
--- a/net/hsr/hsr_netlink.c
+++ b/net/hsr/hsr_netlink.c
@@ -33,7 +33,8 @@ static const struct nla_policy hsr_policy[IFLA_HSR_MAX + 1] = 
{
  * hsr_dev_setup routine has been executed. Nice!
  */
 static int hsr_newlink(struct net *src_net, struct net_device *dev,
-                      struct nlattr *tb[], struct nlattr *data[])
+                      struct nlattr *tb[], struct nlattr *data[],
+                      struct netlink_ext_ack *extack)
 {
        struct net_device *link[2];
        unsigned char multicast_spec, hsr_version;
diff --git a/net/ieee802154/6lowpan/core.c b/net/ieee802154/6lowpan/core.c
index 0a866f332290..de2661cd0328 100644
--- a/net/ieee802154/6lowpan/core.c
+++ b/net/ieee802154/6lowpan/core.c
@@ -111,7 +111,8 @@ static void lowpan_setup(struct net_device *ldev)
        ldev->features          |= NETIF_F_NETNS_LOCAL;
 }
 
-static int lowpan_validate(struct nlattr *tb[], struct nlattr *data[])
+static int lowpan_validate(struct nlattr *tb[], struct nlattr *data[],
+                          struct netlink_ext_ack *extack)
 {
        if (tb[IFLA_ADDRESS]) {
                if (nla_len(tb[IFLA_ADDRESS]) != IEEE802154_ADDR_LEN)
@@ -121,7 +122,8 @@ static int lowpan_validate(struct nlattr *tb[], struct 
nlattr *data[])
 }
 
 static int lowpan_newlink(struct net *src_net, struct net_device *ldev,
-                         struct nlattr *tb[], struct nlattr *data[])
+                         struct nlattr *tb[], struct nlattr *data[],
+                         struct netlink_ext_ack *extack)
 {
        struct net_device *wdev;
        int ret;
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 41394a4b9af9..7a7829e839c2 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -779,7 +779,8 @@ static struct pernet_operations ipgre_net_ops = {
        .size = sizeof(struct ip_tunnel_net),
 };
 
-static int ipgre_tunnel_validate(struct nlattr *tb[], struct nlattr *data[])
+static int ipgre_tunnel_validate(struct nlattr *tb[], struct nlattr *data[],
+                                struct netlink_ext_ack *extack)
 {
        __be16 flags;
 
@@ -802,7 +803,8 @@ static int ipgre_tunnel_validate(struct nlattr *tb[], 
struct nlattr *data[])
        return 0;
 }
 
-static int ipgre_tap_validate(struct nlattr *tb[], struct nlattr *data[])
+static int ipgre_tap_validate(struct nlattr *tb[], struct nlattr *data[],
+                             struct netlink_ext_ack *extack)
 {
        __be32 daddr;
 
@@ -823,7 +825,7 @@ static int ipgre_tap_validate(struct nlattr *tb[], struct 
nlattr *data[])
        }
 
 out:
-       return ipgre_tunnel_validate(tb, data);
+       return ipgre_tunnel_validate(tb, data, extack);
 }
 
 static int ipgre_netlink_parms(struct net_device *dev,
@@ -957,7 +959,8 @@ static void ipgre_tap_setup(struct net_device *dev)
 }
 
 static int ipgre_newlink(struct net *src_net, struct net_device *dev,
-                        struct nlattr *tb[], struct nlattr *data[])
+                        struct nlattr *tb[], struct nlattr *data[],
+                        struct netlink_ext_ack *extack)
 {
        struct ip_tunnel_parm p;
        struct ip_tunnel_encap ipencap;
@@ -979,7 +982,8 @@ static int ipgre_newlink(struct net *src_net, struct 
net_device *dev,
 }
 
 static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[],
-                           struct nlattr *data[])
+                           struct nlattr *data[],
+                           struct netlink_ext_ack *extack)
 {
        struct ip_tunnel *t = netdev_priv(dev);
        struct ip_tunnel_parm p;
@@ -1155,7 +1159,7 @@ struct net_device *gretap_fb_dev_create(struct net *net, 
const char *name,
        t = netdev_priv(dev);
        t->collect_md = true;
 
-       err = ipgre_newlink(net, dev, tb, NULL);
+       err = ipgre_newlink(net, dev, tb, NULL, NULL);
        if (err < 0) {
                free_netdev(dev);
                return ERR_PTR(err);
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c
index 4ec9affb2252..0192c255e508 100644
--- a/net/ipv4/ip_vti.c
+++ b/net/ipv4/ip_vti.c
@@ -465,7 +465,8 @@ static struct pernet_operations vti_net_ops = {
        .size = sizeof(struct ip_tunnel_net),
 };
 
-static int vti_tunnel_validate(struct nlattr *tb[], struct nlattr *data[])
+static int vti_tunnel_validate(struct nlattr *tb[], struct nlattr *data[],
+                              struct netlink_ext_ack *extack)
 {
        return 0;
 }
@@ -503,7 +504,8 @@ static void vti_netlink_parms(struct nlattr *data[],
 }
 
 static int vti_newlink(struct net *src_net, struct net_device *dev,
-                      struct nlattr *tb[], struct nlattr *data[])
+                      struct nlattr *tb[], struct nlattr *data[],
+                      struct netlink_ext_ack *extack)
 {
        struct ip_tunnel_parm parms;
        __u32 fwmark = 0;
@@ -513,7 +515,8 @@ static int vti_newlink(struct net *src_net, struct 
net_device *dev,
 }
 
 static int vti_changelink(struct net_device *dev, struct nlattr *tb[],
-                         struct nlattr *data[])
+                         struct nlattr *data[],
+                         struct netlink_ext_ack *extack)
 {
        struct ip_tunnel *t = netdev_priv(dev);
        __u32 fwmark = t->fwmark;
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 1e441c6f2160..fb1ad22b5e29 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -375,7 +375,8 @@ static int ipip_tunnel_init(struct net_device *dev)
        return ip_tunnel_init(dev);
 }
 
-static int ipip_tunnel_validate(struct nlattr *tb[], struct nlattr *data[])
+static int ipip_tunnel_validate(struct nlattr *tb[], struct nlattr *data[],
+                               struct netlink_ext_ack *extack)
 {
        u8 proto;
 
@@ -469,7 +470,8 @@ static bool ipip_netlink_encap_parms(struct nlattr *data[],
 }
 
 static int ipip_newlink(struct net *src_net, struct net_device *dev,
-                       struct nlattr *tb[], struct nlattr *data[])
+                       struct nlattr *tb[], struct nlattr *data[],
+                       struct netlink_ext_ack *extack)
 {
        struct ip_tunnel *t = netdev_priv(dev);
        struct ip_tunnel_parm p;
@@ -488,7 +490,8 @@ static int ipip_newlink(struct net *src_net, struct 
net_device *dev,
 }
 
 static int ipip_changelink(struct net_device *dev, struct nlattr *tb[],
-                          struct nlattr *data[])
+                          struct nlattr *data[],
+                          struct netlink_ext_ack *extack)
 {
        struct ip_tunnel *t = netdev_priv(dev);
        struct ip_tunnel_parm p;
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index e0e726c338a7..67ff2aaf5dcb 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -1170,7 +1170,8 @@ static struct pernet_operations ip6gre_net_ops = {
        .size = sizeof(struct ip6gre_net),
 };
 
-static int ip6gre_tunnel_validate(struct nlattr *tb[], struct nlattr *data[])
+static int ip6gre_tunnel_validate(struct nlattr *tb[], struct nlattr *data[],
+                                 struct netlink_ext_ack *extack)
 {
        __be16 flags;
 
@@ -1188,7 +1189,8 @@ static int ip6gre_tunnel_validate(struct nlattr *tb[], 
struct nlattr *data[])
        return 0;
 }
 
-static int ip6gre_tap_validate(struct nlattr *tb[], struct nlattr *data[])
+static int ip6gre_tap_validate(struct nlattr *tb[], struct nlattr *data[],
+                              struct netlink_ext_ack *extack)
 {
        struct in6_addr daddr;
 
@@ -1209,7 +1211,7 @@ static int ip6gre_tap_validate(struct nlattr *tb[], 
struct nlattr *data[])
        }
 
 out:
-       return ip6gre_tunnel_validate(tb, data);
+       return ip6gre_tunnel_validate(tb, data, extack);
 }
 
 
@@ -1342,7 +1344,8 @@ static bool ip6gre_netlink_encap_parms(struct nlattr 
*data[],
 }
 
 static int ip6gre_newlink(struct net *src_net, struct net_device *dev,
-       struct nlattr *tb[], struct nlattr *data[])
+                         struct nlattr *tb[], struct nlattr *data[],
+                         struct netlink_ext_ack *extack)
 {
        struct ip6_tnl *nt;
        struct net *net = dev_net(dev);
@@ -1403,7 +1406,8 @@ static int ip6gre_newlink(struct net *src_net, struct 
net_device *dev,
 }
 
 static int ip6gre_changelink(struct net_device *dev, struct nlattr *tb[],
-                           struct nlattr *data[])
+                            struct nlattr *data[],
+                            struct netlink_ext_ack *extack)
 {
        struct ip6_tnl *t, *nt = netdev_priv(dev);
        struct net *net = nt->net;
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 8c6c3c8e7eef..3a0ba2ae4b0f 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1885,7 +1885,8 @@ static int __net_init ip6_fb_tnl_dev_init(struct 
net_device *dev)
        return 0;
 }
 
-static int ip6_tnl_validate(struct nlattr *tb[], struct nlattr *data[])
+static int ip6_tnl_validate(struct nlattr *tb[], struct nlattr *data[],
+                           struct netlink_ext_ack *extack)
 {
        u8 proto;
 
@@ -1974,7 +1975,8 @@ static bool ip6_tnl_netlink_encap_parms(struct nlattr 
*data[],
 }
 
 static int ip6_tnl_newlink(struct net *src_net, struct net_device *dev,
-                          struct nlattr *tb[], struct nlattr *data[])
+                          struct nlattr *tb[], struct nlattr *data[],
+                          struct netlink_ext_ack *extack)
 {
        struct net *net = dev_net(dev);
        struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
@@ -2005,7 +2007,8 @@ static int ip6_tnl_newlink(struct net *src_net, struct 
net_device *dev,
 }
 
 static int ip6_tnl_changelink(struct net_device *dev, struct nlattr *tb[],
-                             struct nlattr *data[])
+                             struct nlattr *data[],
+                             struct netlink_ext_ack *extack)
 {
        struct ip6_tnl *t = netdev_priv(dev);
        struct __ip6_tnl_parm p;
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
index 837ea1eefe7f..486c2305f53c 100644
--- a/net/ipv6/ip6_vti.c
+++ b/net/ipv6/ip6_vti.c
@@ -907,7 +907,8 @@ static int __net_init vti6_fb_tnl_dev_init(struct 
net_device *dev)
        return 0;
 }
 
-static int vti6_validate(struct nlattr *tb[], struct nlattr *data[])
+static int vti6_validate(struct nlattr *tb[], struct nlattr *data[],
+                        struct netlink_ext_ack *extack)
 {
        return 0;
 }
@@ -940,7 +941,8 @@ static void vti6_netlink_parms(struct nlattr *data[],
 }
 
 static int vti6_newlink(struct net *src_net, struct net_device *dev,
-                       struct nlattr *tb[], struct nlattr *data[])
+                       struct nlattr *tb[], struct nlattr *data[],
+                       struct netlink_ext_ack *extack)
 {
        struct net *net = dev_net(dev);
        struct ip6_tnl *nt;
@@ -966,7 +968,8 @@ static void vti6_dellink(struct net_device *dev, struct 
list_head *head)
 }
 
 static int vti6_changelink(struct net_device *dev, struct nlattr *tb[],
-                          struct nlattr *data[])
+                          struct nlattr *data[],
+                          struct netlink_ext_ack *extack)
 {
        struct ip6_tnl *t;
        struct __ip6_tnl_parm p;
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 2378503577b0..e9958b1398cb 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -1406,7 +1406,8 @@ static void __net_init ipip6_fb_tunnel_init(struct 
net_device *dev)
        rcu_assign_pointer(sitn->tunnels_wc[0], tunnel);
 }
 
-static int ipip6_validate(struct nlattr *tb[], struct nlattr *data[])
+static int ipip6_validate(struct nlattr *tb[], struct nlattr *data[],
+                         struct netlink_ext_ack *extack)
 {
        u8 proto;
 
@@ -1537,7 +1538,8 @@ static bool ipip6_netlink_6rd_parms(struct nlattr *data[],
 #endif
 
 static int ipip6_newlink(struct net *src_net, struct net_device *dev,
-                        struct nlattr *tb[], struct nlattr *data[])
+                        struct nlattr *tb[], struct nlattr *data[],
+                        struct netlink_ext_ack *extack)
 {
        struct net *net = dev_net(dev);
        struct ip_tunnel *nt;
@@ -1573,7 +1575,8 @@ static int ipip6_newlink(struct net *src_net, struct 
net_device *dev,
 }
 
 static int ipip6_changelink(struct net_device *dev, struct nlattr *tb[],
-                         struct nlattr *data[])
+                           struct nlattr *data[],
+                           struct netlink_ext_ack *extack)
 {
        struct ip_tunnel *t = netdev_priv(dev);
        struct ip_tunnel_parm p;
-- 
2.13.1

Reply via email to