usb: typec: ucsi: Mark dGPUs as DEVICE scope
[platform/kernel/linux-starfive.git] / net / core / rtnetlink.c
index 74864dc..5625ed3 100644 (file)
@@ -957,24 +957,27 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev,
                         nla_total_size(sizeof(struct ifla_vf_rate)) +
                         nla_total_size(sizeof(struct ifla_vf_link_state)) +
                         nla_total_size(sizeof(struct ifla_vf_rss_query_en)) +
-                        nla_total_size(0) + /* nest IFLA_VF_STATS */
-                        /* IFLA_VF_STATS_RX_PACKETS */
-                        nla_total_size_64bit(sizeof(__u64)) +
-                        /* IFLA_VF_STATS_TX_PACKETS */
-                        nla_total_size_64bit(sizeof(__u64)) +
-                        /* IFLA_VF_STATS_RX_BYTES */
-                        nla_total_size_64bit(sizeof(__u64)) +
-                        /* IFLA_VF_STATS_TX_BYTES */
-                        nla_total_size_64bit(sizeof(__u64)) +
-                        /* IFLA_VF_STATS_BROADCAST */
-                        nla_total_size_64bit(sizeof(__u64)) +
-                        /* IFLA_VF_STATS_MULTICAST */
-                        nla_total_size_64bit(sizeof(__u64)) +
-                        /* IFLA_VF_STATS_RX_DROPPED */
-                        nla_total_size_64bit(sizeof(__u64)) +
-                        /* IFLA_VF_STATS_TX_DROPPED */
-                        nla_total_size_64bit(sizeof(__u64)) +
                         nla_total_size(sizeof(struct ifla_vf_trust)));
+               if (~ext_filter_mask & RTEXT_FILTER_SKIP_STATS) {
+                       size += num_vfs *
+                               (nla_total_size(0) + /* nest IFLA_VF_STATS */
+                                /* IFLA_VF_STATS_RX_PACKETS */
+                                nla_total_size_64bit(sizeof(__u64)) +
+                                /* IFLA_VF_STATS_TX_PACKETS */
+                                nla_total_size_64bit(sizeof(__u64)) +
+                                /* IFLA_VF_STATS_RX_BYTES */
+                                nla_total_size_64bit(sizeof(__u64)) +
+                                /* IFLA_VF_STATS_TX_BYTES */
+                                nla_total_size_64bit(sizeof(__u64)) +
+                                /* IFLA_VF_STATS_BROADCAST */
+                                nla_total_size_64bit(sizeof(__u64)) +
+                                /* IFLA_VF_STATS_MULTICAST */
+                                nla_total_size_64bit(sizeof(__u64)) +
+                                /* IFLA_VF_STATS_RX_DROPPED */
+                                nla_total_size_64bit(sizeof(__u64)) +
+                                /* IFLA_VF_STATS_TX_DROPPED */
+                                nla_total_size_64bit(sizeof(__u64)));
+               }
                return size;
        } else
                return 0;
@@ -1253,7 +1256,8 @@ static noinline_for_stack int rtnl_fill_stats(struct sk_buff *skb,
 static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb,
                                               struct net_device *dev,
                                               int vfs_num,
-                                              struct nlattr *vfinfo)
+                                              struct nlattr *vfinfo,
+                                              u32 ext_filter_mask)
 {
        struct ifla_vf_rss_query_en vf_rss_query_en;
        struct nlattr *vf, *vfstats, *vfvlanlist;
@@ -1359,33 +1363,35 @@ static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb,
                goto nla_put_vf_failure;
        }
        nla_nest_end(skb, vfvlanlist);
-       memset(&vf_stats, 0, sizeof(vf_stats));
-       if (dev->netdev_ops->ndo_get_vf_stats)
-               dev->netdev_ops->ndo_get_vf_stats(dev, vfs_num,
-                                               &vf_stats);
-       vfstats = nla_nest_start_noflag(skb, IFLA_VF_STATS);
-       if (!vfstats)
-               goto nla_put_vf_failure;
-       if (nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_PACKETS,
-                             vf_stats.rx_packets, IFLA_VF_STATS_PAD) ||
-           nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_PACKETS,
-                             vf_stats.tx_packets, IFLA_VF_STATS_PAD) ||
-           nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_BYTES,
-                             vf_stats.rx_bytes, IFLA_VF_STATS_PAD) ||
-           nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_BYTES,
-                             vf_stats.tx_bytes, IFLA_VF_STATS_PAD) ||
-           nla_put_u64_64bit(skb, IFLA_VF_STATS_BROADCAST,
-                             vf_stats.broadcast, IFLA_VF_STATS_PAD) ||
-           nla_put_u64_64bit(skb, IFLA_VF_STATS_MULTICAST,
-                             vf_stats.multicast, IFLA_VF_STATS_PAD) ||
-           nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_DROPPED,
-                             vf_stats.rx_dropped, IFLA_VF_STATS_PAD) ||
-           nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_DROPPED,
-                             vf_stats.tx_dropped, IFLA_VF_STATS_PAD)) {
-               nla_nest_cancel(skb, vfstats);
-               goto nla_put_vf_failure;
+       if (~ext_filter_mask & RTEXT_FILTER_SKIP_STATS) {
+               memset(&vf_stats, 0, sizeof(vf_stats));
+               if (dev->netdev_ops->ndo_get_vf_stats)
+                       dev->netdev_ops->ndo_get_vf_stats(dev, vfs_num,
+                                                         &vf_stats);
+               vfstats = nla_nest_start_noflag(skb, IFLA_VF_STATS);
+               if (!vfstats)
+                       goto nla_put_vf_failure;
+               if (nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_PACKETS,
+                                     vf_stats.rx_packets, IFLA_VF_STATS_PAD) ||
+                   nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_PACKETS,
+                                     vf_stats.tx_packets, IFLA_VF_STATS_PAD) ||
+                   nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_BYTES,
+                                     vf_stats.rx_bytes, IFLA_VF_STATS_PAD) ||
+                   nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_BYTES,
+                                     vf_stats.tx_bytes, IFLA_VF_STATS_PAD) ||
+                   nla_put_u64_64bit(skb, IFLA_VF_STATS_BROADCAST,
+                                     vf_stats.broadcast, IFLA_VF_STATS_PAD) ||
+                   nla_put_u64_64bit(skb, IFLA_VF_STATS_MULTICAST,
+                                     vf_stats.multicast, IFLA_VF_STATS_PAD) ||
+                   nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_DROPPED,
+                                     vf_stats.rx_dropped, IFLA_VF_STATS_PAD) ||
+                   nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_DROPPED,
+                                     vf_stats.tx_dropped, IFLA_VF_STATS_PAD)) {
+                       nla_nest_cancel(skb, vfstats);
+                       goto nla_put_vf_failure;
+               }
+               nla_nest_end(skb, vfstats);
        }
-       nla_nest_end(skb, vfstats);
        nla_nest_end(skb, vf);
        return 0;
 
@@ -1418,7 +1424,7 @@ static noinline_for_stack int rtnl_fill_vf(struct sk_buff *skb,
                return -EMSGSIZE;
 
        for (i = 0; i < num_vfs; i++) {
-               if (rtnl_fill_vfinfo(skb, dev, i, vfinfo))
+               if (rtnl_fill_vfinfo(skb, dev, i, vfinfo, ext_filter_mask))
                        return -EMSGSIZE;
        }
 
@@ -3212,6 +3218,7 @@ struct net_device *rtnl_create_link(struct net *net, const char *ifname,
        struct net_device *dev;
        unsigned int num_tx_queues = 1;
        unsigned int num_rx_queues = 1;
+       int err;
 
        if (tb[IFLA_NUM_TX_QUEUES])
                num_tx_queues = nla_get_u32(tb[IFLA_NUM_TX_QUEUES]);
@@ -3247,13 +3254,18 @@ struct net_device *rtnl_create_link(struct net *net, const char *ifname,
        if (!dev)
                return ERR_PTR(-ENOMEM);
 
+       err = validate_linkmsg(dev, tb, extack);
+       if (err < 0) {
+               free_netdev(dev);
+               return ERR_PTR(err);
+       }
+
        dev_net_set(dev, net);
        dev->rtnl_link_ops = ops;
        dev->rtnl_link_state = RTNL_LINK_INITIALIZING;
 
        if (tb[IFLA_MTU]) {
                u32 mtu = nla_get_u32(tb[IFLA_MTU]);
-               int err;
 
                err = dev_validate_mtu(dev, mtu, extack);
                if (err) {
@@ -3980,7 +3992,7 @@ static int nlmsg_populate_fdb_fill(struct sk_buff *skb,
        ndm->ndm_ifindex = dev->ifindex;
        ndm->ndm_state   = ndm_state;
 
-       if (nla_put(skb, NDA_LLADDR, ETH_ALEN, addr))
+       if (nla_put(skb, NDA_LLADDR, dev->addr_len, addr))
                goto nla_put_failure;
        if (vid)
                if (nla_put(skb, NDA_VLAN, sizeof(u16), &vid))
@@ -3994,10 +4006,10 @@ nla_put_failure:
        return -EMSGSIZE;
 }
 
-static inline size_t rtnl_fdb_nlmsg_size(void)
+static inline size_t rtnl_fdb_nlmsg_size(const struct net_device *dev)
 {
        return NLMSG_ALIGN(sizeof(struct ndmsg)) +
-              nla_total_size(ETH_ALEN) +       /* NDA_LLADDR */
+              nla_total_size(dev->addr_len) +  /* NDA_LLADDR */
               nla_total_size(sizeof(u16)) +    /* NDA_VLAN */
               0;
 }
@@ -4009,7 +4021,7 @@ static void rtnl_fdb_notify(struct net_device *dev, u8 *addr, u16 vid, int type,
        struct sk_buff *skb;
        int err = -ENOBUFS;
 
-       skb = nlmsg_new(rtnl_fdb_nlmsg_size(), GFP_ATOMIC);
+       skb = nlmsg_new(rtnl_fdb_nlmsg_size(dev), GFP_ATOMIC);
        if (!skb)
                goto errout;