LCOV - code coverage report
Current view: top level - net/core - rtnetlink.c (source / functions) Hit Total Coverage
Test: gcov_data_raspi2_real_modules_combined.info Lines: 517 1923 26.9 %
Date: 2020-09-30 20:25:40 Functions: 61 127 48.0 %
Branches: 306 2060 14.9 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0-or-later
       2                 :            : /*
       3                 :            :  * INET         An implementation of the TCP/IP protocol suite for the LINUX
       4                 :            :  *              operating system.  INET is implemented using the  BSD Socket
       5                 :            :  *              interface as the means of communication with the user level.
       6                 :            :  *
       7                 :            :  *              Routing netlink socket interface: protocol independent part.
       8                 :            :  *
       9                 :            :  * Authors:     Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
      10                 :            :  *
      11                 :            :  *      Fixes:
      12                 :            :  *      Vitaly E. Lavrov                RTA_OK arithmetics was wrong.
      13                 :            :  */
      14                 :            : 
      15                 :            : #include <linux/bitops.h>
      16                 :            : #include <linux/errno.h>
      17                 :            : #include <linux/module.h>
      18                 :            : #include <linux/types.h>
      19                 :            : #include <linux/socket.h>
      20                 :            : #include <linux/kernel.h>
      21                 :            : #include <linux/timer.h>
      22                 :            : #include <linux/string.h>
      23                 :            : #include <linux/sockios.h>
      24                 :            : #include <linux/net.h>
      25                 :            : #include <linux/fcntl.h>
      26                 :            : #include <linux/mm.h>
      27                 :            : #include <linux/slab.h>
      28                 :            : #include <linux/interrupt.h>
      29                 :            : #include <linux/capability.h>
      30                 :            : #include <linux/skbuff.h>
      31                 :            : #include <linux/init.h>
      32                 :            : #include <linux/security.h>
      33                 :            : #include <linux/mutex.h>
      34                 :            : #include <linux/if_addr.h>
      35                 :            : #include <linux/if_bridge.h>
      36                 :            : #include <linux/if_vlan.h>
      37                 :            : #include <linux/pci.h>
      38                 :            : #include <linux/etherdevice.h>
      39                 :            : #include <linux/bpf.h>
      40                 :            : 
      41                 :            : #include <linux/uaccess.h>
      42                 :            : 
      43                 :            : #include <linux/inet.h>
      44                 :            : #include <linux/netdevice.h>
      45                 :            : #include <net/ip.h>
      46                 :            : #include <net/protocol.h>
      47                 :            : #include <net/arp.h>
      48                 :            : #include <net/route.h>
      49                 :            : #include <net/udp.h>
      50                 :            : #include <net/tcp.h>
      51                 :            : #include <net/sock.h>
      52                 :            : #include <net/pkt_sched.h>
      53                 :            : #include <net/fib_rules.h>
      54                 :            : #include <net/rtnetlink.h>
      55                 :            : #include <net/net_namespace.h>
      56                 :            : 
      57                 :            : #define RTNL_MAX_TYPE           50
      58                 :            : #define RTNL_SLAVE_MAX_TYPE     36
      59                 :            : 
      60                 :            : struct rtnl_link {
      61                 :            :         rtnl_doit_func          doit;
      62                 :            :         rtnl_dumpit_func        dumpit;
      63                 :            :         struct module           *owner;
      64                 :            :         unsigned int            flags;
      65                 :            :         struct rcu_head         rcu;
      66                 :            : };
      67                 :            : 
      68                 :            : static DEFINE_MUTEX(rtnl_mutex);
      69                 :            : 
      70                 :      11167 : void rtnl_lock(void)
      71                 :            : {
      72                 :      29797 :         mutex_lock(&rtnl_mutex);
      73                 :      11167 : }
      74                 :            : EXPORT_SYMBOL(rtnl_lock);
      75                 :            : 
      76                 :        414 : int rtnl_lock_killable(void)
      77                 :            : {
      78                 :        414 :         return mutex_lock_killable(&rtnl_mutex);
      79                 :            : }
      80                 :            : EXPORT_SYMBOL(rtnl_lock_killable);
      81                 :            : 
      82                 :            : static struct sk_buff *defer_kfree_skb_list;
      83                 :          0 : void rtnl_kfree_skbs(struct sk_buff *head, struct sk_buff *tail)
      84                 :            : {
      85         [ #  # ]:          0 :         if (head && tail) {
      86                 :          0 :                 tail->next = defer_kfree_skb_list;
      87                 :          0 :                 defer_kfree_skb_list = head;
      88                 :            :         }
      89                 :          0 : }
      90                 :            : EXPORT_SYMBOL(rtnl_kfree_skbs);
      91                 :            : 
      92                 :      30211 : void __rtnl_unlock(void)
      93                 :            : {
      94                 :      30211 :         struct sk_buff *head = defer_kfree_skb_list;
      95                 :            : 
      96                 :      30211 :         defer_kfree_skb_list = NULL;
      97                 :            : 
      98                 :      30211 :         mutex_unlock(&rtnl_mutex);
      99                 :            : 
     100         [ -  + ]:      60422 :         while (head) {
     101                 :          0 :                 struct sk_buff *next = head->next;
     102                 :            : 
     103                 :          0 :                 kfree_skb(head);
     104                 :          0 :                 cond_resched();
     105                 :            :                 head = next;
     106                 :            :         }
     107                 :      30211 : }
     108                 :            : 
     109                 :      11581 : void rtnl_unlock(void)
     110                 :            : {
     111                 :            :         /* This fellow will unlock it for us. */
     112                 :      30211 :         netdev_run_todo();
     113                 :      11581 : }
     114                 :            : EXPORT_SYMBOL(rtnl_unlock);
     115                 :            : 
     116                 :          0 : int rtnl_trylock(void)
     117                 :            : {
     118                 :          0 :         return mutex_trylock(&rtnl_mutex);
     119                 :            : }
     120                 :            : EXPORT_SYMBOL(rtnl_trylock);
     121                 :            : 
     122                 :      26714 : int rtnl_is_locked(void)
     123                 :            : {
     124                 :      34994 :         return mutex_is_locked(&rtnl_mutex);
     125                 :            : }
     126                 :            : EXPORT_SYMBOL(rtnl_is_locked);
     127                 :            : 
     128                 :          0 : bool refcount_dec_and_rtnl_lock(refcount_t *r)
     129                 :            : {
     130                 :          0 :         return refcount_dec_and_mutex_lock(r, &rtnl_mutex);
     131                 :            : }
     132                 :            : EXPORT_SYMBOL(refcount_dec_and_rtnl_lock);
     133                 :            : 
     134                 :            : #ifdef CONFIG_PROVE_LOCKING
     135                 :            : bool lockdep_rtnl_is_held(void)
     136                 :            : {
     137                 :            :         return lockdep_is_held(&rtnl_mutex);
     138                 :            : }
     139                 :            : EXPORT_SYMBOL(lockdep_rtnl_is_held);
     140                 :            : #endif /* #ifdef CONFIG_PROVE_LOCKING */
     141                 :            : 
     142                 :            : static struct rtnl_link *__rcu *rtnl_msg_handlers[RTNL_FAMILY_MAX + 1];
     143                 :            : 
     144                 :            : static inline int rtm_msgindex(int msgtype)
     145                 :            : {
     146                 :      15111 :         int msgindex = msgtype - RTM_BASE;
     147                 :            : 
     148                 :            :         /*
     149                 :            :          * msgindex < 0 implies someone tried to register a netlink
     150                 :            :          * control code. msgindex >= RTM_NR_MSGTYPES may indicate that
     151                 :            :          * the message type has not been added to linux/rtnetlink.h
     152                 :            :          */
     153   [ #  #  -  + ]:      15111 :         BUG_ON(msgindex < 0 || msgindex >= RTM_NR_MSGTYPES);
     154                 :            : 
     155                 :            :         return msgindex;
     156                 :            : }
     157                 :            : 
     158                 :            : static struct rtnl_link *rtnl_get_link(int protocol, int msgtype)
     159                 :            : {
     160                 :            :         struct rtnl_link **tab;
     161                 :            : 
     162   [ -  +  -  +  :       8901 :         if (protocol >= ARRAY_SIZE(rtnl_msg_handlers))
                   -  + ]
     163                 :            :                 protocol = PF_UNSPEC;
     164                 :            : 
     165                 :      18423 :         tab = rcu_dereference_rtnl(rtnl_msg_handlers[protocol]);
     166   [ -  +  #  #  :       9522 :         if (!tab)
          -  +  -  +  -  
                      + ]
     167                 :          0 :                 tab = rcu_dereference_rtnl(rtnl_msg_handlers[PF_UNSPEC]);
     168                 :            : 
     169                 :       9522 :         return tab[msgtype];
     170                 :            : }
     171                 :            : 
     172                 :      15111 : static int rtnl_register_internal(struct module *owner,
     173                 :            :                                   int protocol, int msgtype,
     174                 :            :                                   rtnl_doit_func doit, rtnl_dumpit_func dumpit,
     175                 :            :                                   unsigned int flags)
     176                 :            : {
     177                 :            :         struct rtnl_link *link, *old;
     178                 :            :         struct rtnl_link __rcu **tab;
     179                 :            :         int msgindex;
     180                 :            :         int ret = -ENOBUFS;
     181                 :            : 
     182         [ -  + ]:      15111 :         BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX);
     183                 :            :         msgindex = rtm_msgindex(msgtype);
     184                 :            : 
     185                 :            :         rtnl_lock();
     186                 :      15111 :         tab = rtnl_msg_handlers[protocol];
     187         [ +  + ]:      15111 :         if (tab == NULL) {
     188                 :            :                 tab = kcalloc(RTM_NR_MSGTYPES, sizeof(void *), GFP_KERNEL);
     189         [ +  - ]:       1242 :                 if (!tab)
     190                 :            :                         goto unlock;
     191                 :            : 
     192                 :            :                 /* ensures we see the 0 stores */
     193                 :       1242 :                 rcu_assign_pointer(rtnl_msg_handlers[protocol], tab);
     194                 :            :         }
     195                 :            : 
     196                 :      15111 :         old = rtnl_dereference(tab[msgindex]);
     197         [ +  + ]:      15111 :         if (old) {
     198                 :        414 :                 link = kmemdup(old, sizeof(*old), GFP_KERNEL);
     199         [ +  - ]:        414 :                 if (!link)
     200                 :            :                         goto unlock;
     201                 :            :         } else {
     202                 :      14697 :                 link = kzalloc(sizeof(*link), GFP_KERNEL);
     203         [ +  - ]:      14697 :                 if (!link)
     204                 :            :                         goto unlock;
     205                 :            :         }
     206                 :            : 
     207   [ +  +  +  -  :      15111 :         WARN_ON(link->owner && link->owner != owner);
                   -  + ]
     208                 :      15111 :         link->owner = owner;
     209                 :            : 
     210   [ +  +  -  +  :      15111 :         WARN_ON(doit && link->doit && link->doit != doit);
             #  #  -  + ]
     211         [ +  + ]:      15111 :         if (doit)
     212                 :      11799 :                 link->doit = doit;
     213   [ +  +  -  +  :      15111 :         WARN_ON(dumpit && link->dumpit && link->dumpit != dumpit);
             #  #  -  + ]
     214         [ +  + ]:      15111 :         if (dumpit)
     215                 :       6624 :                 link->dumpit = dumpit;
     216                 :            : 
     217                 :      15111 :         link->flags |= flags;
     218                 :            : 
     219                 :            :         /* publish protocol:msgtype */
     220                 :      15111 :         rcu_assign_pointer(tab[msgindex], link);
     221                 :            :         ret = 0;
     222         [ +  + ]:      15111 :         if (old)
     223         [ +  - ]:        414 :                 kfree_rcu(old, rcu);
     224                 :            : unlock:
     225                 :            :         rtnl_unlock();
     226                 :      15111 :         return ret;
     227                 :            : }
     228                 :            : 
     229                 :            : /**
     230                 :            :  * rtnl_register_module - Register a rtnetlink message type
     231                 :            :  *
     232                 :            :  * @owner: module registering the hook (THIS_MODULE)
     233                 :            :  * @protocol: Protocol family or PF_UNSPEC
     234                 :            :  * @msgtype: rtnetlink message type
     235                 :            :  * @doit: Function pointer called for each request message
     236                 :            :  * @dumpit: Function pointer called for each dump request (NLM_F_DUMP) message
     237                 :            :  * @flags: rtnl_link_flags to modifiy behaviour of doit/dumpit functions
     238                 :            :  *
     239                 :            :  * Like rtnl_register, but for use by removable modules.
     240                 :            :  */
     241                 :       3105 : int rtnl_register_module(struct module *owner,
     242                 :            :                          int protocol, int msgtype,
     243                 :            :                          rtnl_doit_func doit, rtnl_dumpit_func dumpit,
     244                 :            :                          unsigned int flags)
     245                 :            : {
     246                 :       3105 :         return rtnl_register_internal(owner, protocol, msgtype,
     247                 :            :                                       doit, dumpit, flags);
     248                 :            : }
     249                 :            : EXPORT_SYMBOL_GPL(rtnl_register_module);
     250                 :            : 
     251                 :            : /**
     252                 :            :  * rtnl_register - Register a rtnetlink message type
     253                 :            :  * @protocol: Protocol family or PF_UNSPEC
     254                 :            :  * @msgtype: rtnetlink message type
     255                 :            :  * @doit: Function pointer called for each request message
     256                 :            :  * @dumpit: Function pointer called for each dump request (NLM_F_DUMP) message
     257                 :            :  * @flags: rtnl_link_flags to modifiy behaviour of doit/dumpit functions
     258                 :            :  *
     259                 :            :  * Registers the specified function pointers (at least one of them has
     260                 :            :  * to be non-NULL) to be called whenever a request message for the
     261                 :            :  * specified protocol family and message type is received.
     262                 :            :  *
     263                 :            :  * The special protocol family PF_UNSPEC may be used to define fallback
     264                 :            :  * function pointers for the case when no entry for the specific protocol
     265                 :            :  * family exists.
     266                 :            :  */
     267                 :      12006 : void rtnl_register(int protocol, int msgtype,
     268                 :            :                    rtnl_doit_func doit, rtnl_dumpit_func dumpit,
     269                 :            :                    unsigned int flags)
     270                 :            : {
     271                 :            :         int err;
     272                 :            : 
     273                 :      12006 :         err = rtnl_register_internal(NULL, protocol, msgtype, doit, dumpit,
     274                 :            :                                      flags);
     275         [ -  + ]:      12006 :         if (err)
     276                 :          0 :                 pr_err("Unable to register rtnetlink message handler, "
     277                 :            :                        "protocol = %d, message type = %d\n", protocol, msgtype);
     278                 :      12006 : }
     279                 :            : 
     280                 :            : /**
     281                 :            :  * rtnl_unregister - Unregister a rtnetlink message type
     282                 :            :  * @protocol: Protocol family or PF_UNSPEC
     283                 :            :  * @msgtype: rtnetlink message type
     284                 :            :  *
     285                 :            :  * Returns 0 on success or a negative error code.
     286                 :            :  */
     287                 :          0 : int rtnl_unregister(int protocol, int msgtype)
     288                 :            : {
     289                 :            :         struct rtnl_link **tab, *link;
     290                 :            :         int msgindex;
     291                 :            : 
     292         [ #  # ]:          0 :         BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX);
     293                 :            :         msgindex = rtm_msgindex(msgtype);
     294                 :            : 
     295                 :            :         rtnl_lock();
     296                 :          0 :         tab = rtnl_dereference(rtnl_msg_handlers[protocol]);
     297         [ #  # ]:          0 :         if (!tab) {
     298                 :            :                 rtnl_unlock();
     299                 :          0 :                 return -ENOENT;
     300                 :            :         }
     301                 :            : 
     302                 :          0 :         link = tab[msgindex];
     303                 :            :         rcu_assign_pointer(tab[msgindex], NULL);
     304                 :            :         rtnl_unlock();
     305                 :            : 
     306         [ #  # ]:          0 :         kfree_rcu(link, rcu);
     307                 :            : 
     308                 :            :         return 0;
     309                 :            : }
     310                 :            : EXPORT_SYMBOL_GPL(rtnl_unregister);
     311                 :            : 
     312                 :            : /**
     313                 :            :  * rtnl_unregister_all - Unregister all rtnetlink message type of a protocol
     314                 :            :  * @protocol : Protocol family or PF_UNSPEC
     315                 :            :  *
     316                 :            :  * Identical to calling rtnl_unregster() for all registered message types
     317                 :            :  * of a certain protocol family.
     318                 :            :  */
     319                 :          0 : void rtnl_unregister_all(int protocol)
     320                 :            : {
     321                 :            :         struct rtnl_link **tab, *link;
     322                 :            :         int msgindex;
     323                 :            : 
     324         [ #  # ]:          0 :         BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX);
     325                 :            : 
     326                 :            :         rtnl_lock();
     327                 :          0 :         tab = rtnl_msg_handlers[protocol];
     328         [ #  # ]:          0 :         if (!tab) {
     329                 :            :                 rtnl_unlock();
     330                 :          0 :                 return;
     331                 :            :         }
     332                 :          0 :         RCU_INIT_POINTER(rtnl_msg_handlers[protocol], NULL);
     333         [ #  # ]:          0 :         for (msgindex = 0; msgindex < RTM_NR_MSGTYPES; msgindex++) {
     334                 :          0 :                 link = tab[msgindex];
     335         [ #  # ]:          0 :                 if (!link)
     336                 :          0 :                         continue;
     337                 :            : 
     338                 :            :                 rcu_assign_pointer(tab[msgindex], NULL);
     339         [ #  # ]:          0 :                 kfree_rcu(link, rcu);
     340                 :            :         }
     341                 :            :         rtnl_unlock();
     342                 :            : 
     343                 :          0 :         synchronize_net();
     344                 :            : 
     345                 :          0 :         kfree(tab);
     346                 :            : }
     347                 :            : EXPORT_SYMBOL_GPL(rtnl_unregister_all);
     348                 :            : 
     349                 :            : static LIST_HEAD(link_ops);
     350                 :            : 
     351                 :        207 : static const struct rtnl_link_ops *rtnl_link_ops_get(const char *kind)
     352                 :            : {
     353                 :            :         const struct rtnl_link_ops *ops;
     354                 :            : 
     355         [ -  + ]:        207 :         list_for_each_entry(ops, &link_ops, list) {
     356         [ #  # ]:          0 :                 if (!strcmp(ops->kind, kind))
     357                 :          0 :                         return ops;
     358                 :            :         }
     359                 :            :         return NULL;
     360                 :            : }
     361                 :            : 
     362                 :            : /**
     363                 :            :  * __rtnl_link_register - Register rtnl_link_ops with rtnetlink.
     364                 :            :  * @ops: struct rtnl_link_ops * to register
     365                 :            :  *
     366                 :            :  * The caller must hold the rtnl_mutex. This function should be used
     367                 :            :  * by drivers that create devices during module initialization. It
     368                 :            :  * must be called before registering the devices.
     369                 :            :  *
     370                 :            :  * Returns 0 on success or a negative error code.
     371                 :            :  */
     372                 :        207 : int __rtnl_link_register(struct rtnl_link_ops *ops)
     373                 :            : {
     374         [ +  - ]:        207 :         if (rtnl_link_ops_get(ops->kind))
     375                 :            :                 return -EEXIST;
     376                 :            : 
     377                 :            :         /* The check for setup is here because if ops
     378                 :            :          * does not have that filled up, it is not possible
     379                 :            :          * to use the ops for creating device. So do not
     380                 :            :          * fill up dellink as well. That disables rtnl_dellink.
     381                 :            :          */
     382   [ +  -  -  + ]:        207 :         if (ops->setup && !ops->dellink)
     383                 :          0 :                 ops->dellink = unregister_netdevice_queue;
     384                 :            : 
     385                 :        207 :         list_add_tail(&ops->list, &link_ops);
     386                 :        207 :         return 0;
     387                 :            : }
     388                 :            : EXPORT_SYMBOL_GPL(__rtnl_link_register);
     389                 :            : 
     390                 :            : /**
     391                 :            :  * rtnl_link_register - Register rtnl_link_ops with rtnetlink.
     392                 :            :  * @ops: struct rtnl_link_ops * to register
     393                 :            :  *
     394                 :            :  * Returns 0 on success or a negative error code.
     395                 :            :  */
     396                 :        207 : int rtnl_link_register(struct rtnl_link_ops *ops)
     397                 :            : {
     398                 :            :         int err;
     399                 :            : 
     400                 :            :         /* Sanity-check max sizes to avoid stack buffer overflow. */
     401   [ +  -  +  -  :        207 :         if (WARN_ON(ops->maxtype > RTNL_MAX_TYPE ||
             -  +  +  - ]
     402                 :            :                     ops->slave_maxtype > RTNL_SLAVE_MAX_TYPE))
     403                 :            :                 return -EINVAL;
     404                 :            : 
     405                 :            :         rtnl_lock();
     406                 :        207 :         err = __rtnl_link_register(ops);
     407                 :            :         rtnl_unlock();
     408                 :        207 :         return err;
     409                 :            : }
     410                 :            : EXPORT_SYMBOL_GPL(rtnl_link_register);
     411                 :            : 
     412                 :          0 : static void __rtnl_kill_links(struct net *net, struct rtnl_link_ops *ops)
     413                 :            : {
     414                 :            :         struct net_device *dev;
     415                 :          0 :         LIST_HEAD(list_kill);
     416                 :            : 
     417         [ #  # ]:          0 :         for_each_netdev(net, dev) {
     418         [ #  # ]:          0 :                 if (dev->rtnl_link_ops == ops)
     419                 :          0 :                         ops->dellink(dev, &list_kill);
     420                 :            :         }
     421                 :          0 :         unregister_netdevice_many(&list_kill);
     422                 :          0 : }
     423                 :            : 
     424                 :            : /**
     425                 :            :  * __rtnl_link_unregister - Unregister rtnl_link_ops from rtnetlink.
     426                 :            :  * @ops: struct rtnl_link_ops * to unregister
     427                 :            :  *
     428                 :            :  * The caller must hold the rtnl_mutex and guarantee net_namespace_list
     429                 :            :  * integrity (hold pernet_ops_rwsem for writing to close the race
     430                 :            :  * with setup_net() and cleanup_net()).
     431                 :            :  */
     432                 :          0 : void __rtnl_link_unregister(struct rtnl_link_ops *ops)
     433                 :            : {
     434                 :            :         struct net *net;
     435                 :            : 
     436         [ #  # ]:          0 :         for_each_net(net) {
     437                 :          0 :                 __rtnl_kill_links(net, ops);
     438                 :            :         }
     439                 :            :         list_del(&ops->list);
     440                 :          0 : }
     441                 :            : EXPORT_SYMBOL_GPL(__rtnl_link_unregister);
     442                 :            : 
     443                 :            : /* Return with the rtnl_lock held when there are no network
     444                 :            :  * devices unregistering in any network namespace.
     445                 :            :  */
     446                 :          0 : static void rtnl_lock_unregistering_all(void)
     447                 :            : {
     448                 :            :         struct net *net;
     449                 :            :         bool unregistering;
     450                 :          0 :         DEFINE_WAIT_FUNC(wait, woken_wake_function);
     451                 :            : 
     452                 :          0 :         add_wait_queue(&netdev_unregistering_wq, &wait);
     453                 :            :         for (;;) {
     454                 :            :                 unregistering = false;
     455                 :            :                 rtnl_lock();
     456                 :            :                 /* We held write locked pernet_ops_rwsem, and parallel
     457                 :            :                  * setup_net() and cleanup_net() are not possible.
     458                 :            :                  */
     459         [ #  # ]:          0 :                 for_each_net(net) {
     460         [ #  # ]:          0 :                         if (net->dev_unreg_count > 0) {
     461                 :            :                                 unregistering = true;
     462                 :            :                                 break;
     463                 :            :                         }
     464                 :            :                 }
     465         [ #  # ]:          0 :                 if (!unregistering)
     466                 :            :                         break;
     467                 :          0 :                 __rtnl_unlock();
     468                 :            : 
     469                 :          0 :                 wait_woken(&wait, TASK_UNINTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT);
     470                 :          0 :         }
     471                 :          0 :         remove_wait_queue(&netdev_unregistering_wq, &wait);
     472                 :          0 : }
     473                 :            : 
     474                 :            : /**
     475                 :            :  * rtnl_link_unregister - Unregister rtnl_link_ops from rtnetlink.
     476                 :            :  * @ops: struct rtnl_link_ops * to unregister
     477                 :            :  */
     478                 :          0 : void rtnl_link_unregister(struct rtnl_link_ops *ops)
     479                 :            : {
     480                 :            :         /* Close the race with setup_net() and cleanup_net() */
     481                 :          0 :         down_write(&pernet_ops_rwsem);
     482                 :          0 :         rtnl_lock_unregistering_all();
     483                 :          0 :         __rtnl_link_unregister(ops);
     484                 :            :         rtnl_unlock();
     485                 :          0 :         up_write(&pernet_ops_rwsem);
     486                 :          0 : }
     487                 :            : EXPORT_SYMBOL_GPL(rtnl_link_unregister);
     488                 :            : 
     489                 :          0 : static size_t rtnl_link_get_slave_info_data_size(const struct net_device *dev)
     490                 :            : {
     491                 :            :         struct net_device *master_dev;
     492                 :            :         const struct rtnl_link_ops *ops;
     493                 :            :         size_t size = 0;
     494                 :            : 
     495                 :            :         rcu_read_lock();
     496                 :            : 
     497                 :          0 :         master_dev = netdev_master_upper_dev_get_rcu((struct net_device *)dev);
     498         [ #  # ]:          0 :         if (!master_dev)
     499                 :            :                 goto out;
     500                 :            : 
     501                 :          0 :         ops = master_dev->rtnl_link_ops;
     502   [ #  #  #  # ]:          0 :         if (!ops || !ops->get_slave_size)
     503                 :            :                 goto out;
     504                 :            :         /* IFLA_INFO_SLAVE_DATA + nested data */
     505                 :          0 :         size = nla_total_size(sizeof(struct nlattr)) +
     506                 :          0 :                ops->get_slave_size(master_dev, dev);
     507                 :            : 
     508                 :            : out:
     509                 :            :         rcu_read_unlock();
     510                 :          0 :         return size;
     511                 :            : }
     512                 :            : 
     513                 :       1656 : static size_t rtnl_link_get_size(const struct net_device *dev)
     514                 :            : {
     515                 :       1656 :         const struct rtnl_link_ops *ops = dev->rtnl_link_ops;
     516                 :            :         size_t size;
     517                 :            : 
     518         [ -  + ]:       1656 :         if (!ops)
     519                 :            :                 return 0;
     520                 :            : 
     521                 :          0 :         size = nla_total_size(sizeof(struct nlattr)) + /* IFLA_LINKINFO */
     522                 :          0 :                nla_total_size(strlen(ops->kind) + 1);  /* IFLA_INFO_KIND */
     523                 :            : 
     524         [ #  # ]:          0 :         if (ops->get_size)
     525                 :            :                 /* IFLA_INFO_DATA + nested data */
     526                 :          0 :                 size += nla_total_size(sizeof(struct nlattr)) +
     527                 :          0 :                         ops->get_size(dev);
     528                 :            : 
     529         [ #  # ]:          0 :         if (ops->get_xstats_size)
     530                 :            :                 /* IFLA_INFO_XSTATS */
     531                 :          0 :                 size += nla_total_size(ops->get_xstats_size(dev));
     532                 :            : 
     533                 :          0 :         size += rtnl_link_get_slave_info_data_size(dev);
     534                 :            : 
     535                 :          0 :         return size;
     536                 :            : }
     537                 :            : 
     538                 :            : static LIST_HEAD(rtnl_af_ops);
     539                 :            : 
     540                 :            : static const struct rtnl_af_ops *rtnl_af_lookup(const int family)
     541                 :            : {
     542                 :            :         const struct rtnl_af_ops *ops;
     543                 :            : 
     544   [ +  -  +  - ]:       3726 :         list_for_each_entry_rcu(ops, &rtnl_af_ops, list) {
     545   [ +  +  +  + ]:       3726 :                 if (ops->family == family)
     546                 :       1863 :                         return ops;
     547                 :            :         }
     548                 :            : 
     549                 :            :         return NULL;
     550                 :            : }
     551                 :            : 
     552                 :            : /**
     553                 :            :  * rtnl_af_register - Register rtnl_af_ops with rtnetlink.
     554                 :            :  * @ops: struct rtnl_af_ops * to register
     555                 :            :  *
     556                 :            :  * Returns 0 on success or a negative error code.
     557                 :            :  */
     558                 :        414 : void rtnl_af_register(struct rtnl_af_ops *ops)
     559                 :            : {
     560                 :            :         rtnl_lock();
     561                 :        414 :         list_add_tail_rcu(&ops->list, &rtnl_af_ops);
     562                 :            :         rtnl_unlock();
     563                 :        414 : }
     564                 :            : EXPORT_SYMBOL_GPL(rtnl_af_register);
     565                 :            : 
     566                 :            : /**
     567                 :            :  * rtnl_af_unregister - Unregister rtnl_af_ops from rtnetlink.
     568                 :            :  * @ops: struct rtnl_af_ops * to unregister
     569                 :            :  */
     570                 :          0 : void rtnl_af_unregister(struct rtnl_af_ops *ops)
     571                 :            : {
     572                 :            :         rtnl_lock();
     573                 :            :         list_del_rcu(&ops->list);
     574                 :            :         rtnl_unlock();
     575                 :            : 
     576                 :          0 :         synchronize_rcu();
     577                 :          0 : }
     578                 :            : EXPORT_SYMBOL_GPL(rtnl_af_unregister);
     579                 :            : 
     580                 :       1656 : static size_t rtnl_link_get_af_size(const struct net_device *dev,
     581                 :            :                                     u32 ext_filter_mask)
     582                 :            : {
     583                 :            :         struct rtnl_af_ops *af_ops;
     584                 :            :         size_t size;
     585                 :            : 
     586                 :            :         /* IFLA_AF_SPEC */
     587                 :            :         size = nla_total_size(sizeof(struct nlattr));
     588                 :            : 
     589                 :            :         rcu_read_lock();
     590         [ +  + ]:       4347 :         list_for_each_entry_rcu(af_ops, &rtnl_af_ops, list) {
     591         [ +  - ]:       2691 :                 if (af_ops->get_link_af_size) {
     592                 :            :                         /* AF_* + nested data */
     593                 :       2691 :                         size += nla_total_size(sizeof(struct nlattr)) +
     594                 :       2691 :                                 af_ops->get_link_af_size(dev, ext_filter_mask);
     595                 :            :                 }
     596                 :            :         }
     597                 :            :         rcu_read_unlock();
     598                 :            : 
     599                 :       1656 :         return size;
     600                 :            : }
     601                 :            : 
     602                 :       4140 : static bool rtnl_have_link_slave_info(const struct net_device *dev)
     603                 :            : {
     604                 :            :         struct net_device *master_dev;
     605                 :            :         bool ret = false;
     606                 :            : 
     607                 :            :         rcu_read_lock();
     608                 :            : 
     609                 :       4140 :         master_dev = netdev_master_upper_dev_get_rcu((struct net_device *)dev);
     610   [ -  +  #  # ]:       4140 :         if (master_dev && master_dev->rtnl_link_ops)
     611                 :            :                 ret = true;
     612                 :            :         rcu_read_unlock();
     613                 :       4140 :         return ret;
     614                 :            : }
     615                 :            : 
     616                 :          0 : static int rtnl_link_slave_info_fill(struct sk_buff *skb,
     617                 :            :                                      const struct net_device *dev)
     618                 :            : {
     619                 :            :         struct net_device *master_dev;
     620                 :            :         const struct rtnl_link_ops *ops;
     621                 :            :         struct nlattr *slave_data;
     622                 :            :         int err;
     623                 :            : 
     624                 :          0 :         master_dev = netdev_master_upper_dev_get((struct net_device *) dev);
     625         [ #  # ]:          0 :         if (!master_dev)
     626                 :            :                 return 0;
     627                 :          0 :         ops = master_dev->rtnl_link_ops;
     628         [ #  # ]:          0 :         if (!ops)
     629                 :            :                 return 0;
     630         [ #  # ]:          0 :         if (nla_put_string(skb, IFLA_INFO_SLAVE_KIND, ops->kind) < 0)
     631                 :            :                 return -EMSGSIZE;
     632         [ #  # ]:          0 :         if (ops->fill_slave_info) {
     633                 :            :                 slave_data = nla_nest_start_noflag(skb, IFLA_INFO_SLAVE_DATA);
     634         [ #  # ]:          0 :                 if (!slave_data)
     635                 :            :                         return -EMSGSIZE;
     636                 :          0 :                 err = ops->fill_slave_info(skb, master_dev, dev);
     637         [ #  # ]:          0 :                 if (err < 0)
     638                 :            :                         goto err_cancel_slave_data;
     639                 :            :                 nla_nest_end(skb, slave_data);
     640                 :            :         }
     641                 :            :         return 0;
     642                 :            : 
     643                 :            : err_cancel_slave_data:
     644                 :            :         nla_nest_cancel(skb, slave_data);
     645                 :          0 :         return err;
     646                 :            : }
     647                 :            : 
     648                 :          0 : static int rtnl_link_info_fill(struct sk_buff *skb,
     649                 :            :                                const struct net_device *dev)
     650                 :            : {
     651                 :          0 :         const struct rtnl_link_ops *ops = dev->rtnl_link_ops;
     652                 :            :         struct nlattr *data;
     653                 :            :         int err;
     654                 :            : 
     655         [ #  # ]:          0 :         if (!ops)
     656                 :            :                 return 0;
     657         [ #  # ]:          0 :         if (nla_put_string(skb, IFLA_INFO_KIND, ops->kind) < 0)
     658                 :            :                 return -EMSGSIZE;
     659         [ #  # ]:          0 :         if (ops->fill_xstats) {
     660                 :          0 :                 err = ops->fill_xstats(skb, dev);
     661         [ #  # ]:          0 :                 if (err < 0)
     662                 :            :                         return err;
     663                 :            :         }
     664         [ #  # ]:          0 :         if (ops->fill_info) {
     665                 :            :                 data = nla_nest_start_noflag(skb, IFLA_INFO_DATA);
     666         [ #  # ]:          0 :                 if (data == NULL)
     667                 :            :                         return -EMSGSIZE;
     668                 :          0 :                 err = ops->fill_info(skb, dev);
     669         [ #  # ]:          0 :                 if (err < 0)
     670                 :            :                         goto err_cancel_data;
     671                 :            :                 nla_nest_end(skb, data);
     672                 :            :         }
     673                 :            :         return 0;
     674                 :            : 
     675                 :            : err_cancel_data:
     676                 :            :         nla_nest_cancel(skb, data);
     677                 :          0 :         return err;
     678                 :            : }
     679                 :            : 
     680                 :          0 : static int rtnl_link_fill(struct sk_buff *skb, const struct net_device *dev)
     681                 :            : {
     682                 :            :         struct nlattr *linkinfo;
     683                 :            :         int err = -EMSGSIZE;
     684                 :            : 
     685                 :            :         linkinfo = nla_nest_start_noflag(skb, IFLA_LINKINFO);
     686         [ #  # ]:          0 :         if (linkinfo == NULL)
     687                 :            :                 goto out;
     688                 :            : 
     689                 :          0 :         err = rtnl_link_info_fill(skb, dev);
     690         [ #  # ]:          0 :         if (err < 0)
     691                 :            :                 goto err_cancel_link;
     692                 :            : 
     693                 :          0 :         err = rtnl_link_slave_info_fill(skb, dev);
     694         [ #  # ]:          0 :         if (err < 0)
     695                 :            :                 goto err_cancel_link;
     696                 :            : 
     697                 :            :         nla_nest_end(skb, linkinfo);
     698                 :          0 :         return 0;
     699                 :            : 
     700                 :            : err_cancel_link:
     701                 :            :         nla_nest_cancel(skb, linkinfo);
     702                 :            : out:
     703                 :          0 :         return err;
     704                 :            : }
     705                 :            : 
     706                 :          0 : int rtnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, unsigned int group, int echo)
     707                 :            : {
     708                 :          0 :         struct sock *rtnl = net->rtnl;
     709                 :            :         int err = 0;
     710                 :            : 
     711                 :          0 :         NETLINK_CB(skb).dst_group = group;
     712         [ #  # ]:          0 :         if (echo)
     713                 :          0 :                 refcount_inc(&skb->users);
     714                 :          0 :         netlink_broadcast(rtnl, skb, pid, group, GFP_KERNEL);
     715         [ #  # ]:          0 :         if (echo)
     716                 :          0 :                 err = netlink_unicast(rtnl, skb, pid, MSG_DONTWAIT);
     717                 :          0 :         return err;
     718                 :            : }
     719                 :            : 
     720                 :          0 : int rtnl_unicast(struct sk_buff *skb, struct net *net, u32 pid)
     721                 :            : {
     722                 :          0 :         struct sock *rtnl = net->rtnl;
     723                 :            : 
     724                 :          0 :         return nlmsg_unicast(rtnl, skb, pid);
     725                 :            : }
     726                 :            : EXPORT_SYMBOL(rtnl_unicast);
     727                 :            : 
     728                 :       8842 : void rtnl_notify(struct sk_buff *skb, struct net *net, u32 pid, u32 group,
     729                 :            :                  struct nlmsghdr *nlh, gfp_t flags)
     730                 :            : {
     731                 :      10498 :         struct sock *rtnl = net->rtnl;
     732                 :            :         int report = 0;
     733                 :            : 
     734         [ +  + ]:       8842 :         if (nlh)
     735                 :            :                 report = nlmsg_report(nlh);
     736                 :            : 
     737                 :      10498 :         nlmsg_notify(rtnl, skb, pid, group, report, flags);
     738                 :       8842 : }
     739                 :            : EXPORT_SYMBOL(rtnl_notify);
     740                 :            : 
     741                 :          0 : void rtnl_set_sk_err(struct net *net, u32 group, int error)
     742                 :            : {
     743                 :          0 :         struct sock *rtnl = net->rtnl;
     744                 :            : 
     745                 :          0 :         netlink_set_err(rtnl, 0, group, error);
     746                 :          0 : }
     747                 :            : EXPORT_SYMBOL(rtnl_set_sk_err);
     748                 :            : 
     749                 :       5404 : int rtnetlink_put_metrics(struct sk_buff *skb, u32 *metrics)
     750                 :            : {
     751                 :            :         struct nlattr *mx;
     752                 :            :         int i, valid = 0;
     753                 :            : 
     754                 :            :         /* nothing is dumped for dst_default_metrics, so just skip the loop */
     755         [ -  + ]:       5404 :         if (metrics == dst_default_metrics.metrics)
     756                 :            :                 return 0;
     757                 :            : 
     758                 :            :         mx = nla_nest_start_noflag(skb, RTA_METRICS);
     759         [ #  # ]:          0 :         if (mx == NULL)
     760                 :            :                 return -ENOBUFS;
     761                 :            : 
     762         [ #  # ]:          0 :         for (i = 0; i < RTAX_MAX; i++) {
     763         [ #  # ]:          0 :                 if (metrics[i]) {
     764         [ #  # ]:          0 :                         if (i == RTAX_CC_ALGO - 1) {
     765                 :            :                                 char tmp[TCP_CA_NAME_MAX], *name;
     766                 :            : 
     767                 :          0 :                                 name = tcp_ca_get_name_by_key(metrics[i], tmp);
     768         [ #  # ]:          0 :                                 if (!name)
     769                 :          0 :                                         continue;
     770         [ #  # ]:          0 :                                 if (nla_put_string(skb, i + 1, name))
     771                 :            :                                         goto nla_put_failure;
     772         [ #  # ]:          0 :                         } else if (i == RTAX_FEATURES - 1) {
     773                 :          0 :                                 u32 user_features = metrics[i] & RTAX_FEATURE_MASK;
     774                 :            : 
     775         [ #  # ]:          0 :                                 if (!user_features)
     776                 :          0 :                                         continue;
     777                 :            :                                 BUILD_BUG_ON(RTAX_FEATURE_MASK & DST_FEATURE_MASK);
     778         [ #  # ]:          0 :                                 if (nla_put_u32(skb, i + 1, user_features))
     779                 :            :                                         goto nla_put_failure;
     780                 :            :                         } else {
     781         [ #  # ]:          0 :                                 if (nla_put_u32(skb, i + 1, metrics[i]))
     782                 :            :                                         goto nla_put_failure;
     783                 :            :                         }
     784                 :          0 :                         valid++;
     785                 :            :                 }
     786                 :            :         }
     787                 :            : 
     788         [ #  # ]:          0 :         if (!valid) {
     789                 :            :                 nla_nest_cancel(skb, mx);
     790                 :          0 :                 return 0;
     791                 :            :         }
     792                 :            : 
     793                 :          0 :         return nla_nest_end(skb, mx);
     794                 :            : 
     795                 :            : nla_put_failure:
     796                 :            :         nla_nest_cancel(skb, mx);
     797                 :          0 :         return -EMSGSIZE;
     798                 :            : }
     799                 :            : EXPORT_SYMBOL(rtnetlink_put_metrics);
     800                 :            : 
     801                 :       2092 : int rtnl_put_cacheinfo(struct sk_buff *skb, struct dst_entry *dst, u32 id,
     802                 :            :                        long expires, u32 error)
     803                 :            : {
     804                 :       2092 :         struct rta_cacheinfo ci = {
     805                 :            :                 .rta_error = error,
     806                 :            :                 .rta_id =  id,
     807                 :            :         };
     808                 :            : 
     809         [ -  + ]:       2092 :         if (dst) {
     810                 :          0 :                 ci.rta_lastuse = jiffies_delta_to_clock_t(jiffies - dst->lastuse);
     811                 :          0 :                 ci.rta_used = dst->__use;
     812                 :          0 :                 ci.rta_clntref = atomic_read(&dst->__refcnt);
     813                 :            :         }
     814         [ -  + ]:       2092 :         if (expires) {
     815                 :            :                 unsigned long clock;
     816                 :            : 
     817                 :          0 :                 clock = jiffies_to_clock_t(abs(expires));
     818                 :          0 :                 clock = min_t(unsigned long, clock, INT_MAX);
     819         [ #  # ]:          0 :                 ci.rta_expires = (expires > 0) ? clock : -clock;
     820                 :            :         }
     821                 :       2092 :         return nla_put(skb, RTA_CACHEINFO, sizeof(ci), &ci);
     822                 :            : }
     823                 :            : EXPORT_SYMBOL_GPL(rtnl_put_cacheinfo);
     824                 :            : 
     825                 :          0 : static void set_operstate(struct net_device *dev, unsigned char transition)
     826                 :            : {
     827                 :          0 :         unsigned char operstate = dev->operstate;
     828                 :            : 
     829      [ #  #  # ]:          0 :         switch (transition) {
     830                 :            :         case IF_OPER_UP:
     831         [ #  # ]:          0 :                 if ((operstate == IF_OPER_DORMANT ||
     832         [ #  # ]:          0 :                      operstate == IF_OPER_UNKNOWN) &&
     833                 :            :                     !netif_dormant(dev))
     834                 :            :                         operstate = IF_OPER_UP;
     835                 :            :                 break;
     836                 :            : 
     837                 :            :         case IF_OPER_DORMANT:
     838         [ #  # ]:          0 :                 if (operstate == IF_OPER_UP ||
     839                 :          0 :                     operstate == IF_OPER_UNKNOWN)
     840                 :            :                         operstate = IF_OPER_DORMANT;
     841                 :            :                 break;
     842                 :            :         }
     843                 :            : 
     844         [ #  # ]:          0 :         if (dev->operstate != operstate) {
     845                 :          0 :                 write_lock_bh(&dev_base_lock);
     846                 :          0 :                 dev->operstate = operstate;
     847                 :          0 :                 write_unlock_bh(&dev_base_lock);
     848                 :          0 :                 netdev_state_change(dev);
     849                 :            :         }
     850                 :          0 : }
     851                 :            : 
     852                 :            : static unsigned int rtnl_dev_get_flags(const struct net_device *dev)
     853                 :            : {
     854                 :        828 :         return (dev->flags & ~(IFF_PROMISC | IFF_ALLMULTI)) |
     855                 :        414 :                (dev->gflags & (IFF_PROMISC | IFF_ALLMULTI));
     856                 :            : }
     857                 :            : 
     858                 :            : static unsigned int rtnl_dev_combine_flags(const struct net_device *dev,
     859                 :            :                                            const struct ifinfomsg *ifm)
     860                 :            : {
     861                 :            :         unsigned int flags = ifm->ifi_flags;
     862                 :            : 
     863                 :            :         /* bugwards compatibility: ifi_change == 0 is treated as ~0 */
     864   [ #  #  +  - ]:        414 :         if (ifm->ifi_change)
     865                 :        828 :                 flags = (flags & ifm->ifi_change) |
     866                 :        414 :                         (rtnl_dev_get_flags(dev) & ~ifm->ifi_change);
     867                 :            : 
     868                 :            :         return flags;
     869                 :            : }
     870                 :            : 
     871                 :       4140 : static void copy_rtnl_link_stats(struct rtnl_link_stats *a,
     872                 :            :                                  const struct rtnl_link_stats64 *b)
     873                 :            : {
     874                 :       4140 :         a->rx_packets = b->rx_packets;
     875                 :       4140 :         a->tx_packets = b->tx_packets;
     876                 :       4140 :         a->rx_bytes = b->rx_bytes;
     877                 :       4140 :         a->tx_bytes = b->tx_bytes;
     878                 :       4140 :         a->rx_errors = b->rx_errors;
     879                 :       4140 :         a->tx_errors = b->tx_errors;
     880                 :       4140 :         a->rx_dropped = b->rx_dropped;
     881                 :       4140 :         a->tx_dropped = b->tx_dropped;
     882                 :            : 
     883                 :       4140 :         a->multicast = b->multicast;
     884                 :       4140 :         a->collisions = b->collisions;
     885                 :            : 
     886                 :       4140 :         a->rx_length_errors = b->rx_length_errors;
     887                 :       4140 :         a->rx_over_errors = b->rx_over_errors;
     888                 :       4140 :         a->rx_crc_errors = b->rx_crc_errors;
     889                 :       4140 :         a->rx_frame_errors = b->rx_frame_errors;
     890                 :       4140 :         a->rx_fifo_errors = b->rx_fifo_errors;
     891                 :       4140 :         a->rx_missed_errors = b->rx_missed_errors;
     892                 :            : 
     893                 :       4140 :         a->tx_aborted_errors = b->tx_aborted_errors;
     894                 :       4140 :         a->tx_carrier_errors = b->tx_carrier_errors;
     895                 :       4140 :         a->tx_fifo_errors = b->tx_fifo_errors;
     896                 :       4140 :         a->tx_heartbeat_errors = b->tx_heartbeat_errors;
     897                 :       4140 :         a->tx_window_errors = b->tx_window_errors;
     898                 :            : 
     899                 :       4140 :         a->rx_compressed = b->rx_compressed;
     900                 :       4140 :         a->tx_compressed = b->tx_compressed;
     901                 :            : 
     902                 :       4140 :         a->rx_nohandler = b->rx_nohandler;
     903                 :       4140 : }
     904                 :            : 
     905                 :            : /* All VF info */
     906                 :       1656 : static inline int rtnl_vfinfo_size(const struct net_device *dev,
     907                 :            :                                    u32 ext_filter_mask)
     908                 :            : {
     909   [ +  +  -  + ]:       1656 :         if (dev->dev.parent && (ext_filter_mask & RTEXT_FILTER_VF)) {
     910                 :            :                 int num_vfs = dev_num_vf(dev->dev.parent);
     911                 :            :                 size_t size = nla_total_size(0);
     912                 :          0 :                 size += num_vfs *
     913                 :            :                         (nla_total_size(0) +
     914                 :            :                          nla_total_size(sizeof(struct ifla_vf_mac)) +
     915                 :            :                          nla_total_size(sizeof(struct ifla_vf_broadcast)) +
     916                 :            :                          nla_total_size(sizeof(struct ifla_vf_vlan)) +
     917                 :            :                          nla_total_size(0) + /* nest IFLA_VF_VLAN_LIST */
     918                 :            :                          nla_total_size(MAX_VLAN_LIST_LEN *
     919                 :            :                                         sizeof(struct ifla_vf_vlan_info)) +
     920                 :            :                          nla_total_size(sizeof(struct ifla_vf_spoofchk)) +
     921                 :            :                          nla_total_size(sizeof(struct ifla_vf_tx_rate)) +
     922                 :            :                          nla_total_size(sizeof(struct ifla_vf_rate)) +
     923                 :            :                          nla_total_size(sizeof(struct ifla_vf_link_state)) +
     924                 :            :                          nla_total_size(sizeof(struct ifla_vf_rss_query_en)) +
     925                 :            :                          nla_total_size(0) + /* nest IFLA_VF_STATS */
     926                 :            :                          /* IFLA_VF_STATS_RX_PACKETS */
     927                 :            :                          nla_total_size_64bit(sizeof(__u64)) +
     928                 :            :                          /* IFLA_VF_STATS_TX_PACKETS */
     929                 :            :                          nla_total_size_64bit(sizeof(__u64)) +
     930                 :            :                          /* IFLA_VF_STATS_RX_BYTES */
     931                 :            :                          nla_total_size_64bit(sizeof(__u64)) +
     932                 :            :                          /* IFLA_VF_STATS_TX_BYTES */
     933                 :            :                          nla_total_size_64bit(sizeof(__u64)) +
     934                 :            :                          /* IFLA_VF_STATS_BROADCAST */
     935                 :            :                          nla_total_size_64bit(sizeof(__u64)) +
     936                 :            :                          /* IFLA_VF_STATS_MULTICAST */
     937                 :            :                          nla_total_size_64bit(sizeof(__u64)) +
     938                 :            :                          /* IFLA_VF_STATS_RX_DROPPED */
     939                 :            :                          nla_total_size_64bit(sizeof(__u64)) +
     940                 :            :                          /* IFLA_VF_STATS_TX_DROPPED */
     941                 :            :                          nla_total_size_64bit(sizeof(__u64)) +
     942                 :            :                          nla_total_size(sizeof(struct ifla_vf_trust)));
     943                 :          0 :                 return size;
     944                 :            :         } else
     945                 :            :                 return 0;
     946                 :            : }
     947                 :            : 
     948                 :       1656 : static size_t rtnl_port_size(const struct net_device *dev,
     949                 :            :                              u32 ext_filter_mask)
     950                 :            : {
     951                 :            :         size_t port_size = nla_total_size(4)            /* PORT_VF */
     952                 :            :                 + nla_total_size(PORT_PROFILE_MAX)      /* PORT_PROFILE */
     953                 :            :                 + nla_total_size(PORT_UUID_MAX)         /* PORT_INSTANCE_UUID */
     954                 :            :                 + nla_total_size(PORT_UUID_MAX)         /* PORT_HOST_UUID */
     955                 :            :                 + nla_total_size(1)                     /* PROT_VDP_REQUEST */
     956                 :            :                 + nla_total_size(2);                    /* PORT_VDP_RESPONSE */
     957                 :            :         size_t vf_ports_size = nla_total_size(sizeof(struct nlattr));
     958                 :            :         size_t vf_port_size = nla_total_size(sizeof(struct nlattr))
     959                 :            :                 + port_size;
     960                 :            :         size_t port_self_size = nla_total_size(sizeof(struct nlattr))
     961                 :            :                 + port_size;
     962                 :            : 
     963   [ -  +  #  #  :       1656 :         if (!dev->netdev_ops->ndo_get_vf_port || !dev->dev.parent ||
                   #  # ]
     964                 :          0 :             !(ext_filter_mask & RTEXT_FILTER_VF))
     965                 :            :                 return 0;
     966         [ #  # ]:          0 :         if (dev_num_vf(dev->dev.parent))
     967                 :          0 :                 return port_self_size + vf_ports_size +
     968                 :          0 :                         vf_port_size * dev_num_vf(dev->dev.parent);
     969                 :            :         else
     970                 :            :                 return port_self_size;
     971                 :            : }
     972                 :            : 
     973                 :            : static size_t rtnl_xdp_size(void)
     974                 :            : {
     975                 :            :         size_t xdp_size = nla_total_size(0) +   /* nest IFLA_XDP */
     976                 :            :                           nla_total_size(1) +   /* XDP_ATTACHED */
     977                 :            :                           nla_total_size(4) +   /* XDP_PROG_ID (or 1st mode) */
     978                 :            :                           nla_total_size(4);    /* XDP_<mode>_PROG_ID */
     979                 :            : 
     980                 :            :         return xdp_size;
     981                 :            : }
     982                 :            : 
     983                 :       1656 : static noinline size_t if_nlmsg_size(const struct net_device *dev,
     984                 :            :                                      u32 ext_filter_mask)
     985                 :            : {
     986                 :       1656 :         return NLMSG_ALIGN(sizeof(struct ifinfomsg))
     987                 :            :                + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
     988                 :            :                + nla_total_size(IFALIASZ) /* IFLA_IFALIAS */
     989                 :            :                + nla_total_size(IFNAMSIZ) /* IFLA_QDISC */
     990                 :            :                + nla_total_size_64bit(sizeof(struct rtnl_link_ifmap))
     991                 :            :                + nla_total_size(sizeof(struct rtnl_link_stats))
     992                 :            :                + nla_total_size_64bit(sizeof(struct rtnl_link_stats64))
     993                 :            :                + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */
     994                 :            :                + nla_total_size(MAX_ADDR_LEN) /* IFLA_BROADCAST */
     995                 :            :                + nla_total_size(4) /* IFLA_TXQLEN */
     996                 :            :                + nla_total_size(4) /* IFLA_WEIGHT */
     997                 :            :                + nla_total_size(4) /* IFLA_MTU */
     998                 :            :                + nla_total_size(4) /* IFLA_LINK */
     999                 :            :                + nla_total_size(4) /* IFLA_MASTER */
    1000                 :            :                + nla_total_size(1) /* IFLA_CARRIER */
    1001                 :            :                + nla_total_size(4) /* IFLA_PROMISCUITY */
    1002                 :            :                + nla_total_size(4) /* IFLA_NUM_TX_QUEUES */
    1003                 :            :                + nla_total_size(4) /* IFLA_NUM_RX_QUEUES */
    1004                 :            :                + nla_total_size(4) /* IFLA_GSO_MAX_SEGS */
    1005                 :            :                + nla_total_size(4) /* IFLA_GSO_MAX_SIZE */
    1006                 :            :                + nla_total_size(1) /* IFLA_OPERSTATE */
    1007                 :            :                + nla_total_size(1) /* IFLA_LINKMODE */
    1008                 :            :                + nla_total_size(4) /* IFLA_CARRIER_CHANGES */
    1009                 :            :                + nla_total_size(4) /* IFLA_LINK_NETNSID */
    1010                 :            :                + nla_total_size(4) /* IFLA_GROUP */
    1011         [ +  - ]:       3312 :                + nla_total_size(ext_filter_mask
    1012                 :       1656 :                                 & RTEXT_FILTER_VF ? 4 : 0) /* IFLA_NUM_VF */
    1013                 :       1656 :                + rtnl_vfinfo_size(dev, ext_filter_mask) /* IFLA_VFINFO_LIST */
    1014                 :       1656 :                + rtnl_port_size(dev, ext_filter_mask) /* IFLA_VF_PORTS + IFLA_PORT_SELF */
    1015                 :       1656 :                + rtnl_link_get_size(dev) /* IFLA_LINKINFO */
    1016                 :       1656 :                + rtnl_link_get_af_size(dev, ext_filter_mask) /* IFLA_AF_SPEC */
    1017                 :            :                + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_PORT_ID */
    1018                 :            :                + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_SWITCH_ID */
    1019                 :            :                + nla_total_size(IFNAMSIZ) /* IFLA_PHYS_PORT_NAME */
    1020                 :            :                + rtnl_xdp_size() /* IFLA_XDP */
    1021                 :            :                + nla_total_size(4)  /* IFLA_EVENT */
    1022                 :            :                + nla_total_size(4)  /* IFLA_NEW_NETNSID */
    1023                 :            :                + nla_total_size(4)  /* IFLA_NEW_IFINDEX */
    1024                 :            :                + nla_total_size(1)  /* IFLA_PROTO_DOWN */
    1025                 :            :                + nla_total_size(4)  /* IFLA_TARGET_NETNSID */
    1026                 :            :                + nla_total_size(4)  /* IFLA_CARRIER_UP_COUNT */
    1027                 :            :                + nla_total_size(4)  /* IFLA_CARRIER_DOWN_COUNT */
    1028                 :            :                + nla_total_size(4)  /* IFLA_MIN_MTU */
    1029                 :            :                + nla_total_size(4)  /* IFLA_MAX_MTU */
    1030                 :            :                + 0;
    1031                 :            : }
    1032                 :            : 
    1033                 :          0 : static int rtnl_vf_ports_fill(struct sk_buff *skb, struct net_device *dev)
    1034                 :            : {
    1035                 :            :         struct nlattr *vf_ports;
    1036                 :            :         struct nlattr *vf_port;
    1037                 :            :         int vf;
    1038                 :            :         int err;
    1039                 :            : 
    1040                 :            :         vf_ports = nla_nest_start_noflag(skb, IFLA_VF_PORTS);
    1041         [ #  # ]:          0 :         if (!vf_ports)
    1042                 :            :                 return -EMSGSIZE;
    1043                 :            : 
    1044         [ #  # ]:          0 :         for (vf = 0; vf < dev_num_vf(dev->dev.parent); vf++) {
    1045                 :            :                 vf_port = nla_nest_start_noflag(skb, IFLA_VF_PORT);
    1046         [ #  # ]:          0 :                 if (!vf_port)
    1047                 :            :                         goto nla_put_failure;
    1048         [ #  # ]:          0 :                 if (nla_put_u32(skb, IFLA_PORT_VF, vf))
    1049                 :            :                         goto nla_put_failure;
    1050                 :          0 :                 err = dev->netdev_ops->ndo_get_vf_port(dev, vf, skb);
    1051         [ #  # ]:          0 :                 if (err == -EMSGSIZE)
    1052                 :            :                         goto nla_put_failure;
    1053         [ #  # ]:          0 :                 if (err) {
    1054                 :            :                         nla_nest_cancel(skb, vf_port);
    1055                 :          0 :                         continue;
    1056                 :            :                 }
    1057                 :            :                 nla_nest_end(skb, vf_port);
    1058                 :            :         }
    1059                 :            : 
    1060                 :            :         nla_nest_end(skb, vf_ports);
    1061                 :            : 
    1062                 :          0 :         return 0;
    1063                 :            : 
    1064                 :            : nla_put_failure:
    1065                 :            :         nla_nest_cancel(skb, vf_ports);
    1066                 :          0 :         return -EMSGSIZE;
    1067                 :            : }
    1068                 :            : 
    1069                 :          0 : static int rtnl_port_self_fill(struct sk_buff *skb, struct net_device *dev)
    1070                 :            : {
    1071                 :            :         struct nlattr *port_self;
    1072                 :            :         int err;
    1073                 :            : 
    1074                 :            :         port_self = nla_nest_start_noflag(skb, IFLA_PORT_SELF);
    1075         [ #  # ]:          0 :         if (!port_self)
    1076                 :            :                 return -EMSGSIZE;
    1077                 :            : 
    1078                 :          0 :         err = dev->netdev_ops->ndo_get_vf_port(dev, PORT_SELF_VF, skb);
    1079         [ #  # ]:          0 :         if (err) {
    1080                 :            :                 nla_nest_cancel(skb, port_self);
    1081         [ #  # ]:          0 :                 return (err == -EMSGSIZE) ? err : 0;
    1082                 :            :         }
    1083                 :            : 
    1084                 :            :         nla_nest_end(skb, port_self);
    1085                 :            : 
    1086                 :          0 :         return 0;
    1087                 :            : }
    1088                 :            : 
    1089                 :       4140 : static int rtnl_port_fill(struct sk_buff *skb, struct net_device *dev,
    1090                 :            :                           u32 ext_filter_mask)
    1091                 :            : {
    1092                 :            :         int err;
    1093                 :            : 
    1094   [ -  +  #  #  :       4140 :         if (!dev->netdev_ops->ndo_get_vf_port || !dev->dev.parent ||
                   #  # ]
    1095                 :          0 :             !(ext_filter_mask & RTEXT_FILTER_VF))
    1096                 :            :                 return 0;
    1097                 :            : 
    1098                 :          0 :         err = rtnl_port_self_fill(skb, dev);
    1099         [ #  # ]:          0 :         if (err)
    1100                 :            :                 return err;
    1101                 :            : 
    1102         [ #  # ]:          0 :         if (dev_num_vf(dev->dev.parent)) {
    1103                 :          0 :                 err = rtnl_vf_ports_fill(skb, dev);
    1104         [ #  # ]:          0 :                 if (err)
    1105                 :          0 :                         return err;
    1106                 :            :         }
    1107                 :            : 
    1108                 :            :         return 0;
    1109                 :            : }
    1110                 :            : 
    1111                 :       4140 : static int rtnl_phys_port_id_fill(struct sk_buff *skb, struct net_device *dev)
    1112                 :            : {
    1113                 :            :         int err;
    1114                 :            :         struct netdev_phys_item_id ppid;
    1115                 :            : 
    1116                 :       4140 :         err = dev_get_phys_port_id(dev, &ppid);
    1117         [ +  - ]:       4140 :         if (err) {
    1118         [ -  + ]:       4140 :                 if (err == -EOPNOTSUPP)
    1119                 :            :                         return 0;
    1120                 :          0 :                 return err;
    1121                 :            :         }
    1122                 :            : 
    1123         [ #  # ]:          0 :         if (nla_put(skb, IFLA_PHYS_PORT_ID, ppid.id_len, ppid.id))
    1124                 :            :                 return -EMSGSIZE;
    1125                 :            : 
    1126                 :          0 :         return 0;
    1127                 :            : }
    1128                 :            : 
    1129                 :       4140 : static int rtnl_phys_port_name_fill(struct sk_buff *skb, struct net_device *dev)
    1130                 :            : {
    1131                 :            :         char name[IFNAMSIZ];
    1132                 :            :         int err;
    1133                 :            : 
    1134                 :       4140 :         err = dev_get_phys_port_name(dev, name, sizeof(name));
    1135         [ +  - ]:       4140 :         if (err) {
    1136         [ -  + ]:       4140 :                 if (err == -EOPNOTSUPP)
    1137                 :            :                         return 0;
    1138                 :          0 :                 return err;
    1139                 :            :         }
    1140                 :            : 
    1141         [ #  # ]:          0 :         if (nla_put_string(skb, IFLA_PHYS_PORT_NAME, name))
    1142                 :            :                 return -EMSGSIZE;
    1143                 :            : 
    1144                 :          0 :         return 0;
    1145                 :            : }
    1146                 :            : 
    1147                 :       4140 : static int rtnl_phys_switch_id_fill(struct sk_buff *skb, struct net_device *dev)
    1148                 :            : {
    1149                 :       4140 :         struct netdev_phys_item_id ppid = { };
    1150                 :            :         int err;
    1151                 :            : 
    1152                 :       4140 :         err = dev_get_port_parent_id(dev, &ppid, false);
    1153         [ +  - ]:       4140 :         if (err) {
    1154         [ -  + ]:       4140 :                 if (err == -EOPNOTSUPP)
    1155                 :            :                         return 0;
    1156                 :          0 :                 return err;
    1157                 :            :         }
    1158                 :            : 
    1159         [ #  # ]:          0 :         if (nla_put(skb, IFLA_PHYS_SWITCH_ID, ppid.id_len, ppid.id))
    1160                 :            :                 return -EMSGSIZE;
    1161                 :            : 
    1162                 :          0 :         return 0;
    1163                 :            : }
    1164                 :            : 
    1165                 :       4140 : static noinline_for_stack int rtnl_fill_stats(struct sk_buff *skb,
    1166                 :            :                                               struct net_device *dev)
    1167                 :            : {
    1168                 :            :         struct rtnl_link_stats64 *sp;
    1169                 :            :         struct nlattr *attr;
    1170                 :            : 
    1171                 :       4140 :         attr = nla_reserve_64bit(skb, IFLA_STATS64,
    1172                 :            :                                  sizeof(struct rtnl_link_stats64), IFLA_PAD);
    1173         [ +  - ]:       4140 :         if (!attr)
    1174                 :            :                 return -EMSGSIZE;
    1175                 :            : 
    1176                 :            :         sp = nla_data(attr);
    1177                 :       4140 :         dev_get_stats(dev, sp);
    1178                 :            : 
    1179                 :       4140 :         attr = nla_reserve(skb, IFLA_STATS,
    1180                 :            :                            sizeof(struct rtnl_link_stats));
    1181         [ +  - ]:       4140 :         if (!attr)
    1182                 :            :                 return -EMSGSIZE;
    1183                 :            : 
    1184                 :       4140 :         copy_rtnl_link_stats(nla_data(attr), sp);
    1185                 :            : 
    1186                 :       4140 :         return 0;
    1187                 :            : }
    1188                 :            : 
    1189                 :          0 : static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb,
    1190                 :            :                                                struct net_device *dev,
    1191                 :            :                                                int vfs_num,
    1192                 :            :                                                struct nlattr *vfinfo)
    1193                 :            : {
    1194                 :            :         struct ifla_vf_rss_query_en vf_rss_query_en;
    1195                 :            :         struct nlattr *vf, *vfstats, *vfvlanlist;
    1196                 :            :         struct ifla_vf_link_state vf_linkstate;
    1197                 :            :         struct ifla_vf_vlan_info vf_vlan_info;
    1198                 :            :         struct ifla_vf_spoofchk vf_spoofchk;
    1199                 :            :         struct ifla_vf_tx_rate vf_tx_rate;
    1200                 :            :         struct ifla_vf_stats vf_stats;
    1201                 :            :         struct ifla_vf_trust vf_trust;
    1202                 :            :         struct ifla_vf_vlan vf_vlan;
    1203                 :            :         struct ifla_vf_rate vf_rate;
    1204                 :            :         struct ifla_vf_mac vf_mac;
    1205                 :            :         struct ifla_vf_broadcast vf_broadcast;
    1206                 :            :         struct ifla_vf_info ivi;
    1207                 :            : 
    1208                 :          0 :         memset(&ivi, 0, sizeof(ivi));
    1209                 :            : 
    1210                 :            :         /* Not all SR-IOV capable drivers support the
    1211                 :            :          * spoofcheck and "RSS query enable" query.  Preset to
    1212                 :            :          * -1 so the user space tool can detect that the driver
    1213                 :            :          * didn't report anything.
    1214                 :            :          */
    1215                 :          0 :         ivi.spoofchk = -1;
    1216                 :          0 :         ivi.rss_query_en = -1;
    1217                 :          0 :         ivi.trusted = -1;
    1218                 :            :         /* The default value for VF link state is "auto"
    1219                 :            :          * IFLA_VF_LINK_STATE_AUTO which equals zero
    1220                 :            :          */
    1221                 :            :         ivi.linkstate = 0;
    1222                 :            :         /* VLAN Protocol by default is 802.1Q */
    1223                 :          0 :         ivi.vlan_proto = htons(ETH_P_8021Q);
    1224         [ #  # ]:          0 :         if (dev->netdev_ops->ndo_get_vf_config(dev, vfs_num, &ivi))
    1225                 :            :                 return 0;
    1226                 :            : 
    1227                 :          0 :         memset(&vf_vlan_info, 0, sizeof(vf_vlan_info));
    1228                 :            : 
    1229                 :          0 :         vf_mac.vf =
    1230                 :          0 :                 vf_vlan.vf =
    1231                 :          0 :                 vf_vlan_info.vf =
    1232                 :          0 :                 vf_rate.vf =
    1233                 :          0 :                 vf_tx_rate.vf =
    1234                 :          0 :                 vf_spoofchk.vf =
    1235                 :          0 :                 vf_linkstate.vf =
    1236                 :          0 :                 vf_rss_query_en.vf =
    1237                 :          0 :                 vf_trust.vf = ivi.vf;
    1238                 :            : 
    1239                 :          0 :         memcpy(vf_mac.mac, ivi.mac, sizeof(ivi.mac));
    1240                 :          0 :         memcpy(vf_broadcast.broadcast, dev->broadcast, dev->addr_len);
    1241                 :          0 :         vf_vlan.vlan = ivi.vlan;
    1242                 :          0 :         vf_vlan.qos = ivi.qos;
    1243                 :          0 :         vf_vlan_info.vlan = ivi.vlan;
    1244                 :          0 :         vf_vlan_info.qos = ivi.qos;
    1245                 :          0 :         vf_vlan_info.vlan_proto = ivi.vlan_proto;
    1246                 :          0 :         vf_tx_rate.rate = ivi.max_tx_rate;
    1247                 :          0 :         vf_rate.min_tx_rate = ivi.min_tx_rate;
    1248                 :          0 :         vf_rate.max_tx_rate = ivi.max_tx_rate;
    1249                 :          0 :         vf_spoofchk.setting = ivi.spoofchk;
    1250                 :          0 :         vf_linkstate.link_state = ivi.linkstate;
    1251                 :          0 :         vf_rss_query_en.setting = ivi.rss_query_en;
    1252                 :          0 :         vf_trust.setting = ivi.trusted;
    1253                 :            :         vf = nla_nest_start_noflag(skb, IFLA_VF_INFO);
    1254         [ #  # ]:          0 :         if (!vf)
    1255                 :            :                 goto nla_put_vfinfo_failure;
    1256   [ #  #  #  # ]:          0 :         if (nla_put(skb, IFLA_VF_MAC, sizeof(vf_mac), &vf_mac) ||
    1257         [ #  # ]:          0 :             nla_put(skb, IFLA_VF_BROADCAST, sizeof(vf_broadcast), &vf_broadcast) ||
    1258         [ #  # ]:          0 :             nla_put(skb, IFLA_VF_VLAN, sizeof(vf_vlan), &vf_vlan) ||
    1259                 :          0 :             nla_put(skb, IFLA_VF_RATE, sizeof(vf_rate),
    1260         [ #  # ]:          0 :                     &vf_rate) ||
    1261                 :          0 :             nla_put(skb, IFLA_VF_TX_RATE, sizeof(vf_tx_rate),
    1262         [ #  # ]:          0 :                     &vf_tx_rate) ||
    1263                 :          0 :             nla_put(skb, IFLA_VF_SPOOFCHK, sizeof(vf_spoofchk),
    1264         [ #  # ]:          0 :                     &vf_spoofchk) ||
    1265                 :          0 :             nla_put(skb, IFLA_VF_LINK_STATE, sizeof(vf_linkstate),
    1266         [ #  # ]:          0 :                     &vf_linkstate) ||
    1267                 :          0 :             nla_put(skb, IFLA_VF_RSS_QUERY_EN,
    1268                 :            :                     sizeof(vf_rss_query_en),
    1269         [ #  # ]:          0 :                     &vf_rss_query_en) ||
    1270                 :          0 :             nla_put(skb, IFLA_VF_TRUST,
    1271                 :            :                     sizeof(vf_trust), &vf_trust))
    1272                 :            :                 goto nla_put_vf_failure;
    1273                 :            :         vfvlanlist = nla_nest_start_noflag(skb, IFLA_VF_VLAN_LIST);
    1274         [ #  # ]:          0 :         if (!vfvlanlist)
    1275                 :            :                 goto nla_put_vf_failure;
    1276         [ #  # ]:          0 :         if (nla_put(skb, IFLA_VF_VLAN_INFO, sizeof(vf_vlan_info),
    1277                 :            :                     &vf_vlan_info)) {
    1278                 :            :                 nla_nest_cancel(skb, vfvlanlist);
    1279                 :            :                 goto nla_put_vf_failure;
    1280                 :            :         }
    1281                 :            :         nla_nest_end(skb, vfvlanlist);
    1282                 :          0 :         memset(&vf_stats, 0, sizeof(vf_stats));
    1283         [ #  # ]:          0 :         if (dev->netdev_ops->ndo_get_vf_stats)
    1284                 :          0 :                 dev->netdev_ops->ndo_get_vf_stats(dev, vfs_num,
    1285                 :            :                                                 &vf_stats);
    1286                 :            :         vfstats = nla_nest_start_noflag(skb, IFLA_VF_STATS);
    1287         [ #  # ]:          0 :         if (!vfstats)
    1288                 :            :                 goto nla_put_vf_failure;
    1289         [ #  # ]:          0 :         if (nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_PACKETS,
    1290         [ #  # ]:          0 :                               vf_stats.rx_packets, IFLA_VF_STATS_PAD) ||
    1291                 :          0 :             nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_PACKETS,
    1292         [ #  # ]:          0 :                               vf_stats.tx_packets, IFLA_VF_STATS_PAD) ||
    1293                 :          0 :             nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_BYTES,
    1294         [ #  # ]:          0 :                               vf_stats.rx_bytes, IFLA_VF_STATS_PAD) ||
    1295                 :          0 :             nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_BYTES,
    1296         [ #  # ]:          0 :                               vf_stats.tx_bytes, IFLA_VF_STATS_PAD) ||
    1297                 :          0 :             nla_put_u64_64bit(skb, IFLA_VF_STATS_BROADCAST,
    1298         [ #  # ]:          0 :                               vf_stats.broadcast, IFLA_VF_STATS_PAD) ||
    1299                 :          0 :             nla_put_u64_64bit(skb, IFLA_VF_STATS_MULTICAST,
    1300         [ #  # ]:          0 :                               vf_stats.multicast, IFLA_VF_STATS_PAD) ||
    1301                 :          0 :             nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_DROPPED,
    1302         [ #  # ]:          0 :                               vf_stats.rx_dropped, IFLA_VF_STATS_PAD) ||
    1303                 :          0 :             nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_DROPPED,
    1304                 :            :                               vf_stats.tx_dropped, IFLA_VF_STATS_PAD)) {
    1305                 :            :                 nla_nest_cancel(skb, vfstats);
    1306                 :            :                 goto nla_put_vf_failure;
    1307                 :            :         }
    1308                 :            :         nla_nest_end(skb, vfstats);
    1309                 :            :         nla_nest_end(skb, vf);
    1310                 :          0 :         return 0;
    1311                 :            : 
    1312                 :            : nla_put_vf_failure:
    1313                 :            :         nla_nest_cancel(skb, vf);
    1314                 :            : nla_put_vfinfo_failure:
    1315                 :            :         nla_nest_cancel(skb, vfinfo);
    1316                 :          0 :         return -EMSGSIZE;
    1317                 :            : }
    1318                 :            : 
    1319                 :       4140 : static noinline_for_stack int rtnl_fill_vf(struct sk_buff *skb,
    1320                 :            :                                            struct net_device *dev,
    1321                 :            :                                            u32 ext_filter_mask)
    1322                 :            : {
    1323                 :            :         struct nlattr *vfinfo;
    1324                 :            :         int i, num_vfs;
    1325                 :            : 
    1326   [ +  +  -  + ]:       4140 :         if (!dev->dev.parent || ((ext_filter_mask & RTEXT_FILTER_VF) == 0))
    1327                 :            :                 return 0;
    1328                 :            : 
    1329                 :            :         num_vfs = dev_num_vf(dev->dev.parent);
    1330         [ #  # ]:          0 :         if (nla_put_u32(skb, IFLA_NUM_VF, num_vfs))
    1331                 :            :                 return -EMSGSIZE;
    1332                 :            : 
    1333         [ #  # ]:          0 :         if (!dev->netdev_ops->ndo_get_vf_config)
    1334                 :            :                 return 0;
    1335                 :            : 
    1336                 :            :         vfinfo = nla_nest_start_noflag(skb, IFLA_VFINFO_LIST);
    1337         [ #  # ]:          0 :         if (!vfinfo)
    1338                 :            :                 return -EMSGSIZE;
    1339                 :            : 
    1340         [ #  # ]:          0 :         for (i = 0; i < num_vfs; i++) {
    1341         [ #  # ]:          0 :                 if (rtnl_fill_vfinfo(skb, dev, i, vfinfo))
    1342                 :            :                         return -EMSGSIZE;
    1343                 :            :         }
    1344                 :            : 
    1345                 :            :         nla_nest_end(skb, vfinfo);
    1346                 :          0 :         return 0;
    1347                 :            : }
    1348                 :            : 
    1349                 :       4140 : static int rtnl_fill_link_ifmap(struct sk_buff *skb, struct net_device *dev)
    1350                 :            : {
    1351                 :            :         struct rtnl_link_ifmap map;
    1352                 :            : 
    1353                 :       4140 :         memset(&map, 0, sizeof(map));
    1354                 :       4140 :         map.mem_start   = dev->mem_start;
    1355                 :       4140 :         map.mem_end     = dev->mem_end;
    1356                 :       4140 :         map.base_addr   = dev->base_addr;
    1357                 :       4140 :         map.irq         = dev->irq;
    1358                 :       4140 :         map.dma         = dev->dma;
    1359                 :       4140 :         map.port        = dev->if_port;
    1360                 :            : 
    1361         [ +  - ]:       4140 :         if (nla_put_64bit(skb, IFLA_MAP, sizeof(map), &map, IFLA_PAD))
    1362                 :            :                 return -EMSGSIZE;
    1363                 :            : 
    1364                 :       4140 :         return 0;
    1365                 :            : }
    1366                 :            : 
    1367                 :       4140 : static u32 rtnl_xdp_prog_skb(struct net_device *dev)
    1368                 :            : {
    1369                 :            :         const struct bpf_prog *generic_xdp_prog;
    1370                 :            : 
    1371   [ -  +  #  # ]:       4140 :         ASSERT_RTNL();
    1372                 :            : 
    1373                 :       4140 :         generic_xdp_prog = rtnl_dereference(dev->xdp_prog);
    1374         [ -  + ]:       4140 :         if (!generic_xdp_prog)
    1375                 :            :                 return 0;
    1376                 :          0 :         return generic_xdp_prog->aux->id;
    1377                 :            : }
    1378                 :            : 
    1379                 :       4140 : static u32 rtnl_xdp_prog_drv(struct net_device *dev)
    1380                 :            : {
    1381                 :       4140 :         return __dev_xdp_query(dev, dev->netdev_ops->ndo_bpf, XDP_QUERY_PROG);
    1382                 :            : }
    1383                 :            : 
    1384                 :       4140 : static u32 rtnl_xdp_prog_hw(struct net_device *dev)
    1385                 :            : {
    1386                 :       4140 :         return __dev_xdp_query(dev, dev->netdev_ops->ndo_bpf,
    1387                 :            :                                XDP_QUERY_PROG_HW);
    1388                 :            : }
    1389                 :            : 
    1390                 :      12420 : static int rtnl_xdp_report_one(struct sk_buff *skb, struct net_device *dev,
    1391                 :            :                                u32 *prog_id, u8 *mode, u8 tgt_mode, u32 attr,
    1392                 :            :                                u32 (*get_prog_id)(struct net_device *dev))
    1393                 :            : {
    1394                 :            :         u32 curr_id;
    1395                 :            :         int err;
    1396                 :            : 
    1397                 :      12420 :         curr_id = get_prog_id(dev);
    1398         [ -  + ]:      12420 :         if (!curr_id)
    1399                 :            :                 return 0;
    1400                 :            : 
    1401                 :          0 :         *prog_id = curr_id;
    1402                 :          0 :         err = nla_put_u32(skb, attr, curr_id);
    1403         [ #  # ]:          0 :         if (err)
    1404                 :            :                 return err;
    1405                 :            : 
    1406         [ #  # ]:          0 :         if (*mode != XDP_ATTACHED_NONE)
    1407                 :          0 :                 *mode = XDP_ATTACHED_MULTI;
    1408                 :            :         else
    1409                 :          0 :                 *mode = tgt_mode;
    1410                 :            : 
    1411                 :            :         return 0;
    1412                 :            : }
    1413                 :            : 
    1414                 :       4140 : static int rtnl_xdp_fill(struct sk_buff *skb, struct net_device *dev)
    1415                 :            : {
    1416                 :            :         struct nlattr *xdp;
    1417                 :            :         u32 prog_id;
    1418                 :            :         int err;
    1419                 :            :         u8 mode;
    1420                 :            : 
    1421                 :            :         xdp = nla_nest_start_noflag(skb, IFLA_XDP);
    1422         [ +  - ]:       4140 :         if (!xdp)
    1423                 :            :                 return -EMSGSIZE;
    1424                 :            : 
    1425                 :       4140 :         prog_id = 0;
    1426                 :       4140 :         mode = XDP_ATTACHED_NONE;
    1427                 :       4140 :         err = rtnl_xdp_report_one(skb, dev, &prog_id, &mode, XDP_ATTACHED_SKB,
    1428                 :            :                                   IFLA_XDP_SKB_PROG_ID, rtnl_xdp_prog_skb);
    1429         [ +  - ]:       4140 :         if (err)
    1430                 :            :                 goto err_cancel;
    1431                 :       4140 :         err = rtnl_xdp_report_one(skb, dev, &prog_id, &mode, XDP_ATTACHED_DRV,
    1432                 :            :                                   IFLA_XDP_DRV_PROG_ID, rtnl_xdp_prog_drv);
    1433         [ +  - ]:       4140 :         if (err)
    1434                 :            :                 goto err_cancel;
    1435                 :       4140 :         err = rtnl_xdp_report_one(skb, dev, &prog_id, &mode, XDP_ATTACHED_HW,
    1436                 :            :                                   IFLA_XDP_HW_PROG_ID, rtnl_xdp_prog_hw);
    1437         [ +  - ]:       4140 :         if (err)
    1438                 :            :                 goto err_cancel;
    1439                 :            : 
    1440                 :       4140 :         err = nla_put_u8(skb, IFLA_XDP_ATTACHED, mode);
    1441         [ +  - ]:       4140 :         if (err)
    1442                 :            :                 goto err_cancel;
    1443                 :            : 
    1444   [ -  +  #  # ]:       4140 :         if (prog_id && mode != XDP_ATTACHED_MULTI) {
    1445                 :            :                 err = nla_put_u32(skb, IFLA_XDP_PROG_ID, prog_id);
    1446         [ #  # ]:          0 :                 if (err)
    1447                 :            :                         goto err_cancel;
    1448                 :            :         }
    1449                 :            : 
    1450                 :            :         nla_nest_end(skb, xdp);
    1451                 :       4140 :         return 0;
    1452                 :            : 
    1453                 :            : err_cancel:
    1454                 :            :         nla_nest_cancel(skb, xdp);
    1455                 :          0 :         return err;
    1456                 :            : }
    1457                 :            : 
    1458                 :            : static u32 rtnl_get_event(unsigned long event)
    1459                 :            : {
    1460                 :            :         u32 rtnl_event_type = IFLA_EVENT_NONE;
    1461                 :            : 
    1462                 :            :         switch (event) {
    1463                 :            :         case NETDEV_REBOOT:
    1464                 :            :                 rtnl_event_type = IFLA_EVENT_REBOOT;
    1465                 :            :                 break;
    1466                 :            :         case NETDEV_FEAT_CHANGE:
    1467                 :            :                 rtnl_event_type = IFLA_EVENT_FEATURES;
    1468                 :            :                 break;
    1469                 :            :         case NETDEV_BONDING_FAILOVER:
    1470                 :            :                 rtnl_event_type = IFLA_EVENT_BONDING_FAILOVER;
    1471                 :            :                 break;
    1472                 :            :         case NETDEV_NOTIFY_PEERS:
    1473                 :            :                 rtnl_event_type = IFLA_EVENT_NOTIFY_PEERS;
    1474                 :            :                 break;
    1475                 :            :         case NETDEV_RESEND_IGMP:
    1476                 :            :                 rtnl_event_type = IFLA_EVENT_IGMP_RESEND;
    1477                 :            :                 break;
    1478                 :            :         case NETDEV_CHANGEINFODATA:
    1479                 :            :                 rtnl_event_type = IFLA_EVENT_BONDING_OPTIONS;
    1480                 :            :                 break;
    1481                 :            :         default:
    1482                 :            :                 break;
    1483                 :            :         }
    1484                 :            : 
    1485                 :            :         return rtnl_event_type;
    1486                 :            : }
    1487                 :            : 
    1488                 :       4140 : static int put_master_ifindex(struct sk_buff *skb, struct net_device *dev)
    1489                 :            : {
    1490                 :            :         const struct net_device *upper_dev;
    1491                 :            :         int ret = 0;
    1492                 :            : 
    1493                 :            :         rcu_read_lock();
    1494                 :            : 
    1495                 :       4140 :         upper_dev = netdev_master_upper_dev_get_rcu(dev);
    1496         [ -  + ]:       4140 :         if (upper_dev)
    1497                 :          0 :                 ret = nla_put_u32(skb, IFLA_MASTER, upper_dev->ifindex);
    1498                 :            : 
    1499                 :            :         rcu_read_unlock();
    1500                 :       4140 :         return ret;
    1501                 :            : }
    1502                 :            : 
    1503                 :       4140 : static int nla_put_iflink(struct sk_buff *skb, const struct net_device *dev,
    1504                 :            :                           bool force)
    1505                 :            : {
    1506                 :       4140 :         int ifindex = dev_get_iflink(dev);
    1507                 :            : 
    1508   [ +  -  -  + ]:       4140 :         if (force || dev->ifindex != ifindex)
    1509                 :          0 :                 return nla_put_u32(skb, IFLA_LINK, ifindex);
    1510                 :            : 
    1511                 :            :         return 0;
    1512                 :            : }
    1513                 :            : 
    1514                 :       4140 : static noinline_for_stack int nla_put_ifalias(struct sk_buff *skb,
    1515                 :            :                                               struct net_device *dev)
    1516                 :            : {
    1517                 :            :         char buf[IFALIASZ];
    1518                 :            :         int ret;
    1519                 :            : 
    1520                 :       4140 :         ret = dev_get_alias(dev, buf, sizeof(buf));
    1521         [ -  + ]:       4140 :         return ret > 0 ? nla_put_string(skb, IFLA_IFALIAS, buf) : 0;
    1522                 :            : }
    1523                 :            : 
    1524                 :       4140 : static int rtnl_fill_link_netnsid(struct sk_buff *skb,
    1525                 :            :                                   const struct net_device *dev,
    1526                 :            :                                   struct net *src_net, gfp_t gfp)
    1527                 :            : {
    1528                 :            :         bool put_iflink = false;
    1529                 :            : 
    1530   [ -  +  #  # ]:       4140 :         if (dev->rtnl_link_ops && dev->rtnl_link_ops->get_link_net) {
    1531                 :          0 :                 struct net *link_net = dev->rtnl_link_ops->get_link_net(dev);
    1532                 :            : 
    1533         [ #  # ]:          0 :                 if (!net_eq(dev_net(dev), link_net)) {
    1534                 :          0 :                         int id = peernet2id_alloc(src_net, link_net, gfp);
    1535                 :            : 
    1536         [ #  # ]:          0 :                         if (nla_put_s32(skb, IFLA_LINK_NETNSID, id))
    1537                 :            :                                 return -EMSGSIZE;
    1538                 :            : 
    1539                 :            :                         put_iflink = true;
    1540                 :            :                 }
    1541                 :            :         }
    1542                 :            : 
    1543                 :       4140 :         return nla_put_iflink(skb, dev, put_iflink);
    1544                 :            : }
    1545                 :            : 
    1546                 :       4140 : static int rtnl_fill_link_af(struct sk_buff *skb,
    1547                 :            :                              const struct net_device *dev,
    1548                 :            :                              u32 ext_filter_mask)
    1549                 :            : {
    1550                 :            :         const struct rtnl_af_ops *af_ops;
    1551                 :            :         struct nlattr *af_spec;
    1552                 :            : 
    1553                 :            :         af_spec = nla_nest_start_noflag(skb, IFLA_AF_SPEC);
    1554         [ +  - ]:       4140 :         if (!af_spec)
    1555                 :            :                 return -EMSGSIZE;
    1556                 :            : 
    1557         [ +  + ]:      11799 :         list_for_each_entry_rcu(af_ops, &rtnl_af_ops, list) {
    1558                 :            :                 struct nlattr *af;
    1559                 :            :                 int err;
    1560                 :            : 
    1561         [ -  + ]:       7659 :                 if (!af_ops->fill_link_af)
    1562                 :          0 :                         continue;
    1563                 :            : 
    1564                 :       7659 :                 af = nla_nest_start_noflag(skb, af_ops->family);
    1565         [ +  - ]:       7659 :                 if (!af)
    1566                 :            :                         return -EMSGSIZE;
    1567                 :            : 
    1568                 :       7659 :                 err = af_ops->fill_link_af(skb, dev, ext_filter_mask);
    1569                 :            :                 /*
    1570                 :            :                  * Caller may return ENODATA to indicate that there
    1571                 :            :                  * was no data to be dumped. This is not an error, it
    1572                 :            :                  * means we should trim the attribute header and
    1573                 :            :                  * continue.
    1574                 :            :                  */
    1575         [ -  + ]:       7659 :                 if (err == -ENODATA)
    1576                 :            :                         nla_nest_cancel(skb, af);
    1577         [ +  - ]:       7659 :                 else if (err < 0)
    1578                 :            :                         return -EMSGSIZE;
    1579                 :            : 
    1580                 :            :                 nla_nest_end(skb, af);
    1581                 :            :         }
    1582                 :            : 
    1583                 :            :         nla_nest_end(skb, af_spec);
    1584                 :       4140 :         return 0;
    1585                 :            : }
    1586                 :            : 
    1587                 :       4140 : static int rtnl_fill_ifinfo(struct sk_buff *skb,
    1588                 :            :                             struct net_device *dev, struct net *src_net,
    1589                 :            :                             int type, u32 pid, u32 seq, u32 change,
    1590                 :            :                             unsigned int flags, u32 ext_filter_mask,
    1591                 :            :                             u32 event, int *new_nsid, int new_ifindex,
    1592                 :            :                             int tgt_netnsid, gfp_t gfp)
    1593                 :            : {
    1594                 :            :         struct ifinfomsg *ifm;
    1595                 :            :         struct nlmsghdr *nlh;
    1596                 :            : 
    1597   [ -  +  #  # ]:       4140 :         ASSERT_RTNL();
    1598                 :       4140 :         nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags);
    1599         [ +  - ]:       4140 :         if (nlh == NULL)
    1600                 :            :                 return -EMSGSIZE;
    1601                 :            : 
    1602                 :            :         ifm = nlmsg_data(nlh);
    1603                 :       4140 :         ifm->ifi_family = AF_UNSPEC;
    1604                 :       4140 :         ifm->__ifi_pad = 0;
    1605                 :       4140 :         ifm->ifi_type = dev->type;
    1606                 :       4140 :         ifm->ifi_index = dev->ifindex;
    1607                 :       4140 :         ifm->ifi_flags = dev_get_flags(dev);
    1608                 :       4140 :         ifm->ifi_change = change;
    1609                 :            : 
    1610   [ -  +  #  # ]:       4140 :         if (tgt_netnsid >= 0 && nla_put_s32(skb, IFLA_TARGET_NETNSID, tgt_netnsid))
    1611                 :            :                 goto nla_put_failure;
    1612                 :            : 
    1613   [ +  -  +  - ]:       8280 :         if (nla_put_string(skb, IFLA_IFNAME, dev->name) ||
    1614         [ +  - ]:       8280 :             nla_put_u32(skb, IFLA_TXQLEN, dev->tx_queue_len) ||
    1615         [ +  + ]:       4140 :             nla_put_u8(skb, IFLA_OPERSTATE,
    1616         [ +  - ]:       4140 :                        netif_running(dev) ? dev->operstate : IF_OPER_DOWN) ||
    1617         [ +  - ]:       8280 :             nla_put_u8(skb, IFLA_LINKMODE, dev->link_mode) ||
    1618         [ +  - ]:       8280 :             nla_put_u32(skb, IFLA_MTU, dev->mtu) ||
    1619         [ +  - ]:       8280 :             nla_put_u32(skb, IFLA_MIN_MTU, dev->min_mtu) ||
    1620         [ +  - ]:       8280 :             nla_put_u32(skb, IFLA_MAX_MTU, dev->max_mtu) ||
    1621         [ +  - ]:       8280 :             nla_put_u32(skb, IFLA_GROUP, dev->group) ||
    1622         [ +  - ]:       8280 :             nla_put_u32(skb, IFLA_PROMISCUITY, dev->promiscuity) ||
    1623         [ +  - ]:       8280 :             nla_put_u32(skb, IFLA_NUM_TX_QUEUES, dev->num_tx_queues) ||
    1624         [ +  - ]:       8280 :             nla_put_u32(skb, IFLA_GSO_MAX_SEGS, dev->gso_max_segs) ||
    1625         [ +  - ]:       8280 :             nla_put_u32(skb, IFLA_GSO_MAX_SIZE, dev->gso_max_size) ||
    1626                 :            : #ifdef CONFIG_RPS
    1627         [ +  - ]:       8280 :             nla_put_u32(skb, IFLA_NUM_RX_QUEUES, dev->num_rx_queues) ||
    1628                 :            : #endif
    1629         [ +  - ]:       8280 :             put_master_ifindex(skb, dev) ||
    1630         [ +  - ]:       8280 :             nla_put_u8(skb, IFLA_CARRIER, netif_carrier_ok(dev)) ||
    1631         [ +  - ]:       8280 :             (dev->qdisc &&
    1632         [ +  - ]:       8280 :              nla_put_string(skb, IFLA_QDISC, dev->qdisc->ops->id)) ||
    1633         [ +  - ]:       8280 :             nla_put_ifalias(skb, dev) ||
    1634                 :       4140 :             nla_put_u32(skb, IFLA_CARRIER_CHANGES,
    1635                 :       8280 :                         atomic_read(&dev->carrier_up_count) +
    1636         [ +  - ]:       8280 :                         atomic_read(&dev->carrier_down_count)) ||
    1637         [ +  - ]:       8280 :             nla_put_u8(skb, IFLA_PROTO_DOWN, dev->proto_down) ||
    1638                 :            :             nla_put_u32(skb, IFLA_CARRIER_UP_COUNT,
    1639         [ +  - ]:       4140 :                         atomic_read(&dev->carrier_up_count)) ||
    1640                 :            :             nla_put_u32(skb, IFLA_CARRIER_DOWN_COUNT,
    1641                 :            :                         atomic_read(&dev->carrier_down_count)))
    1642                 :            :                 goto nla_put_failure;
    1643                 :            : 
    1644         [ -  + ]:       4140 :         if (event != IFLA_EVENT_NONE) {
    1645         [ #  # ]:          0 :                 if (nla_put_u32(skb, IFLA_EVENT, event))
    1646                 :            :                         goto nla_put_failure;
    1647                 :            :         }
    1648                 :            : 
    1649         [ +  - ]:       4140 :         if (rtnl_fill_link_ifmap(skb, dev))
    1650                 :            :                 goto nla_put_failure;
    1651                 :            : 
    1652         [ +  - ]:       4140 :         if (dev->addr_len) {
    1653   [ +  -  +  - ]:       8280 :                 if (nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr) ||
    1654                 :       4140 :                     nla_put(skb, IFLA_BROADCAST, dev->addr_len, dev->broadcast))
    1655                 :            :                         goto nla_put_failure;
    1656                 :            :         }
    1657                 :            : 
    1658         [ +  - ]:       4140 :         if (rtnl_phys_port_id_fill(skb, dev))
    1659                 :            :                 goto nla_put_failure;
    1660                 :            : 
    1661         [ +  - ]:       4140 :         if (rtnl_phys_port_name_fill(skb, dev))
    1662                 :            :                 goto nla_put_failure;
    1663                 :            : 
    1664         [ +  - ]:       4140 :         if (rtnl_phys_switch_id_fill(skb, dev))
    1665                 :            :                 goto nla_put_failure;
    1666                 :            : 
    1667         [ +  - ]:       4140 :         if (rtnl_fill_stats(skb, dev))
    1668                 :            :                 goto nla_put_failure;
    1669                 :            : 
    1670         [ +  - ]:       4140 :         if (rtnl_fill_vf(skb, dev, ext_filter_mask))
    1671                 :            :                 goto nla_put_failure;
    1672                 :            : 
    1673         [ +  - ]:       4140 :         if (rtnl_port_fill(skb, dev, ext_filter_mask))
    1674                 :            :                 goto nla_put_failure;
    1675                 :            : 
    1676         [ +  - ]:       4140 :         if (rtnl_xdp_fill(skb, dev))
    1677                 :            :                 goto nla_put_failure;
    1678                 :            : 
    1679   [ +  -  -  + ]:       4140 :         if (dev->rtnl_link_ops || rtnl_have_link_slave_info(dev)) {
    1680         [ #  # ]:          0 :                 if (rtnl_link_fill(skb, dev) < 0)
    1681                 :            :                         goto nla_put_failure;
    1682                 :            :         }
    1683                 :            : 
    1684         [ +  - ]:       4140 :         if (rtnl_fill_link_netnsid(skb, dev, src_net, gfp))
    1685                 :            :                 goto nla_put_failure;
    1686                 :            : 
    1687   [ -  +  #  # ]:       4140 :         if (new_nsid &&
    1688                 :          0 :             nla_put_s32(skb, IFLA_NEW_NETNSID, *new_nsid) < 0)
    1689                 :            :                 goto nla_put_failure;
    1690   [ -  +  #  # ]:       4140 :         if (new_ifindex &&
    1691                 :            :             nla_put_s32(skb, IFLA_NEW_IFINDEX, new_ifindex) < 0)
    1692                 :            :                 goto nla_put_failure;
    1693                 :            : 
    1694                 :            : 
    1695                 :            :         rcu_read_lock();
    1696         [ +  - ]:       4140 :         if (rtnl_fill_link_af(skb, dev, ext_filter_mask))
    1697                 :            :                 goto nla_put_failure_rcu;
    1698                 :            :         rcu_read_unlock();
    1699                 :            : 
    1700                 :            :         nlmsg_end(skb, nlh);
    1701                 :       4140 :         return 0;
    1702                 :            : 
    1703                 :            : nla_put_failure_rcu:
    1704                 :            :         rcu_read_unlock();
    1705                 :            : nla_put_failure:
    1706                 :            :         nlmsg_cancel(skb, nlh);
    1707                 :          0 :         return -EMSGSIZE;
    1708                 :            : }
    1709                 :            : 
    1710                 :            : static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
    1711                 :            :         [IFLA_IFNAME]           = { .type = NLA_STRING, .len = IFNAMSIZ-1 },
    1712                 :            :         [IFLA_ADDRESS]          = { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
    1713                 :            :         [IFLA_BROADCAST]        = { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
    1714                 :            :         [IFLA_MAP]              = { .len = sizeof(struct rtnl_link_ifmap) },
    1715                 :            :         [IFLA_MTU]              = { .type = NLA_U32 },
    1716                 :            :         [IFLA_LINK]             = { .type = NLA_U32 },
    1717                 :            :         [IFLA_MASTER]           = { .type = NLA_U32 },
    1718                 :            :         [IFLA_CARRIER]          = { .type = NLA_U8 },
    1719                 :            :         [IFLA_TXQLEN]           = { .type = NLA_U32 },
    1720                 :            :         [IFLA_WEIGHT]           = { .type = NLA_U32 },
    1721                 :            :         [IFLA_OPERSTATE]        = { .type = NLA_U8 },
    1722                 :            :         [IFLA_LINKMODE]         = { .type = NLA_U8 },
    1723                 :            :         [IFLA_LINKINFO]         = { .type = NLA_NESTED },
    1724                 :            :         [IFLA_NET_NS_PID]       = { .type = NLA_U32 },
    1725                 :            :         [IFLA_NET_NS_FD]        = { .type = NLA_U32 },
    1726                 :            :         /* IFLA_IFALIAS is a string, but policy is set to NLA_BINARY to
    1727                 :            :          * allow 0-length string (needed to remove an alias).
    1728                 :            :          */
    1729                 :            :         [IFLA_IFALIAS]          = { .type = NLA_BINARY, .len = IFALIASZ - 1 },
    1730                 :            :         [IFLA_VFINFO_LIST]      = {. type = NLA_NESTED },
    1731                 :            :         [IFLA_VF_PORTS]         = { .type = NLA_NESTED },
    1732                 :            :         [IFLA_PORT_SELF]        = { .type = NLA_NESTED },
    1733                 :            :         [IFLA_AF_SPEC]          = { .type = NLA_NESTED },
    1734                 :            :         [IFLA_EXT_MASK]         = { .type = NLA_U32 },
    1735                 :            :         [IFLA_PROMISCUITY]      = { .type = NLA_U32 },
    1736                 :            :         [IFLA_NUM_TX_QUEUES]    = { .type = NLA_U32 },
    1737                 :            :         [IFLA_NUM_RX_QUEUES]    = { .type = NLA_U32 },
    1738                 :            :         [IFLA_GSO_MAX_SEGS]     = { .type = NLA_U32 },
    1739                 :            :         [IFLA_GSO_MAX_SIZE]     = { .type = NLA_U32 },
    1740                 :            :         [IFLA_PHYS_PORT_ID]     = { .type = NLA_BINARY, .len = MAX_PHYS_ITEM_ID_LEN },
    1741                 :            :         [IFLA_CARRIER_CHANGES]  = { .type = NLA_U32 },  /* ignored */
    1742                 :            :         [IFLA_PHYS_SWITCH_ID]   = { .type = NLA_BINARY, .len = MAX_PHYS_ITEM_ID_LEN },
    1743                 :            :         [IFLA_LINK_NETNSID]     = { .type = NLA_S32 },
    1744                 :            :         [IFLA_PROTO_DOWN]       = { .type = NLA_U8 },
    1745                 :            :         [IFLA_XDP]              = { .type = NLA_NESTED },
    1746                 :            :         [IFLA_EVENT]            = { .type = NLA_U32 },
    1747                 :            :         [IFLA_GROUP]            = { .type = NLA_U32 },
    1748                 :            :         [IFLA_TARGET_NETNSID]   = { .type = NLA_S32 },
    1749                 :            :         [IFLA_CARRIER_UP_COUNT] = { .type = NLA_U32 },
    1750                 :            :         [IFLA_CARRIER_DOWN_COUNT] = { .type = NLA_U32 },
    1751                 :            :         [IFLA_MIN_MTU]          = { .type = NLA_U32 },
    1752                 :            :         [IFLA_MAX_MTU]          = { .type = NLA_U32 },
    1753                 :            : };
    1754                 :            : 
    1755                 :            : static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
    1756                 :            :         [IFLA_INFO_KIND]        = { .type = NLA_STRING },
    1757                 :            :         [IFLA_INFO_DATA]        = { .type = NLA_NESTED },
    1758                 :            :         [IFLA_INFO_SLAVE_KIND]  = { .type = NLA_STRING },
    1759                 :            :         [IFLA_INFO_SLAVE_DATA]  = { .type = NLA_NESTED },
    1760                 :            : };
    1761                 :            : 
    1762                 :            : static const struct nla_policy ifla_vf_policy[IFLA_VF_MAX+1] = {
    1763                 :            :         [IFLA_VF_MAC]           = { .len = sizeof(struct ifla_vf_mac) },
    1764                 :            :         [IFLA_VF_BROADCAST]     = { .type = NLA_REJECT },
    1765                 :            :         [IFLA_VF_VLAN]          = { .len = sizeof(struct ifla_vf_vlan) },
    1766                 :            :         [IFLA_VF_VLAN_LIST]     = { .type = NLA_NESTED },
    1767                 :            :         [IFLA_VF_TX_RATE]       = { .len = sizeof(struct ifla_vf_tx_rate) },
    1768                 :            :         [IFLA_VF_SPOOFCHK]      = { .len = sizeof(struct ifla_vf_spoofchk) },
    1769                 :            :         [IFLA_VF_RATE]          = { .len = sizeof(struct ifla_vf_rate) },
    1770                 :            :         [IFLA_VF_LINK_STATE]    = { .len = sizeof(struct ifla_vf_link_state) },
    1771                 :            :         [IFLA_VF_RSS_QUERY_EN]  = { .len = sizeof(struct ifla_vf_rss_query_en) },
    1772                 :            :         [IFLA_VF_STATS]         = { .type = NLA_NESTED },
    1773                 :            :         [IFLA_VF_TRUST]         = { .len = sizeof(struct ifla_vf_trust) },
    1774                 :            :         [IFLA_VF_IB_NODE_GUID]  = { .len = sizeof(struct ifla_vf_guid) },
    1775                 :            :         [IFLA_VF_IB_PORT_GUID]  = { .len = sizeof(struct ifla_vf_guid) },
    1776                 :            : };
    1777                 :            : 
    1778                 :            : static const struct nla_policy ifla_port_policy[IFLA_PORT_MAX+1] = {
    1779                 :            :         [IFLA_PORT_VF]          = { .type = NLA_U32 },
    1780                 :            :         [IFLA_PORT_PROFILE]     = { .type = NLA_STRING,
    1781                 :            :                                     .len = PORT_PROFILE_MAX },
    1782                 :            :         [IFLA_PORT_INSTANCE_UUID] = { .type = NLA_BINARY,
    1783                 :            :                                       .len = PORT_UUID_MAX },
    1784                 :            :         [IFLA_PORT_HOST_UUID]   = { .type = NLA_STRING,
    1785                 :            :                                     .len = PORT_UUID_MAX },
    1786                 :            :         [IFLA_PORT_REQUEST]     = { .type = NLA_U8, },
    1787                 :            :         [IFLA_PORT_RESPONSE]    = { .type = NLA_U16, },
    1788                 :            : 
    1789                 :            :         /* Unused, but we need to keep it here since user space could
    1790                 :            :          * fill it. It's also broken with regard to NLA_BINARY use in
    1791                 :            :          * combination with structs.
    1792                 :            :          */
    1793                 :            :         [IFLA_PORT_VSI_TYPE]    = { .type = NLA_BINARY,
    1794                 :            :                                     .len = sizeof(struct ifla_port_vsi) },
    1795                 :            : };
    1796                 :            : 
    1797                 :            : static const struct nla_policy ifla_xdp_policy[IFLA_XDP_MAX + 1] = {
    1798                 :            :         [IFLA_XDP_FD]           = { .type = NLA_S32 },
    1799                 :            :         [IFLA_XDP_ATTACHED]     = { .type = NLA_U8 },
    1800                 :            :         [IFLA_XDP_FLAGS]        = { .type = NLA_U32 },
    1801                 :            :         [IFLA_XDP_PROG_ID]      = { .type = NLA_U32 },
    1802                 :            : };
    1803                 :            : 
    1804                 :          0 : static const struct rtnl_link_ops *linkinfo_to_kind_ops(const struct nlattr *nla)
    1805                 :            : {
    1806                 :            :         const struct rtnl_link_ops *ops = NULL;
    1807                 :            :         struct nlattr *linfo[IFLA_INFO_MAX + 1];
    1808                 :            : 
    1809         [ #  # ]:          0 :         if (nla_parse_nested_deprecated(linfo, IFLA_INFO_MAX, nla, ifla_info_policy, NULL) < 0)
    1810                 :            :                 return NULL;
    1811                 :            : 
    1812         [ #  # ]:          0 :         if (linfo[IFLA_INFO_KIND]) {
    1813                 :            :                 char kind[MODULE_NAME_LEN];
    1814                 :            : 
    1815                 :          0 :                 nla_strlcpy(kind, linfo[IFLA_INFO_KIND], sizeof(kind));
    1816                 :          0 :                 ops = rtnl_link_ops_get(kind);
    1817                 :            :         }
    1818                 :            : 
    1819                 :          0 :         return ops;
    1820                 :            : }
    1821                 :            : 
    1822                 :       2484 : static bool link_master_filtered(struct net_device *dev, int master_idx)
    1823                 :            : {
    1824                 :            :         struct net_device *master;
    1825                 :            : 
    1826         [ -  + ]:       2484 :         if (!master_idx)
    1827                 :            :                 return false;
    1828                 :            : 
    1829                 :          0 :         master = netdev_master_upper_dev_get(dev);
    1830   [ #  #  #  # ]:          0 :         if (!master || master->ifindex != master_idx)
    1831                 :            :                 return true;
    1832                 :            : 
    1833                 :          0 :         return false;
    1834                 :            : }
    1835                 :            : 
    1836                 :            : static bool link_kind_filtered(const struct net_device *dev,
    1837                 :            :                                const struct rtnl_link_ops *kind_ops)
    1838                 :            : {
    1839   [ -  +  #  # ]:       2484 :         if (kind_ops && dev->rtnl_link_ops != kind_ops)
    1840                 :            :                 return true;
    1841                 :            : 
    1842                 :            :         return false;
    1843                 :            : }
    1844                 :            : 
    1845                 :       2484 : static bool link_dump_filtered(struct net_device *dev,
    1846                 :            :                                int master_idx,
    1847                 :            :                                const struct rtnl_link_ops *kind_ops)
    1848                 :            : {
    1849   [ +  -  +  - ]:       4968 :         if (link_master_filtered(dev, master_idx) ||
    1850                 :            :             link_kind_filtered(dev, kind_ops))
    1851                 :            :                 return true;
    1852                 :            : 
    1853                 :       2484 :         return false;
    1854                 :            : }
    1855                 :            : 
    1856                 :            : /**
    1857                 :            :  * rtnl_get_net_ns_capable - Get netns if sufficiently privileged.
    1858                 :            :  * @sk: netlink socket
    1859                 :            :  * @netnsid: network namespace identifier
    1860                 :            :  *
    1861                 :            :  * Returns the network namespace identified by netnsid on success or an error
    1862                 :            :  * pointer on failure.
    1863                 :            :  */
    1864                 :          0 : struct net *rtnl_get_net_ns_capable(struct sock *sk, int netnsid)
    1865                 :            : {
    1866                 :            :         struct net *net;
    1867                 :            : 
    1868                 :          0 :         net = get_net_ns_by_id(sock_net(sk), netnsid);
    1869         [ #  # ]:          0 :         if (!net)
    1870                 :            :                 return ERR_PTR(-EINVAL);
    1871                 :            : 
    1872                 :            :         /* For now, the caller is required to have CAP_NET_ADMIN in
    1873                 :            :          * the user namespace owning the target net ns.
    1874                 :            :          */
    1875         [ #  # ]:          0 :         if (!sk_ns_capable(sk, net->user_ns, CAP_NET_ADMIN)) {
    1876                 :          0 :                 put_net(net);
    1877                 :          0 :                 return ERR_PTR(-EACCES);
    1878                 :            :         }
    1879                 :            :         return net;
    1880                 :            : }
    1881                 :            : EXPORT_SYMBOL_GPL(rtnl_get_net_ns_capable);
    1882                 :            : 
    1883                 :       2484 : static int rtnl_valid_dump_ifinfo_req(const struct nlmsghdr *nlh,
    1884                 :            :                                       bool strict_check, struct nlattr **tb,
    1885                 :            :                                       struct netlink_ext_ack *extack)
    1886                 :            : {
    1887                 :            :         int hdrlen;
    1888                 :            : 
    1889         [ -  + ]:       2484 :         if (strict_check) {
    1890                 :            :                 struct ifinfomsg *ifm;
    1891                 :            : 
    1892         [ #  # ]:          0 :                 if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ifm))) {
    1893         [ #  # ]:          0 :                         NL_SET_ERR_MSG(extack, "Invalid header for link dump");
    1894                 :            :                         return -EINVAL;
    1895                 :            :                 }
    1896                 :            : 
    1897                 :            :                 ifm = nlmsg_data(nlh);
    1898   [ #  #  #  #  :          0 :                 if (ifm->__ifi_pad || ifm->ifi_type || ifm->ifi_flags ||
                   #  # ]
    1899                 :          0 :                     ifm->ifi_change) {
    1900         [ #  # ]:          0 :                         NL_SET_ERR_MSG(extack, "Invalid values in header for link dump request");
    1901                 :            :                         return -EINVAL;
    1902                 :            :                 }
    1903         [ #  # ]:          0 :                 if (ifm->ifi_index) {
    1904         [ #  # ]:          0 :                         NL_SET_ERR_MSG(extack, "Filter by device index not supported for link dumps");
    1905                 :            :                         return -EINVAL;
    1906                 :            :                 }
    1907                 :            : 
    1908                 :          0 :                 return nlmsg_parse_deprecated_strict(nlh, sizeof(*ifm), tb,
    1909                 :            :                                                      IFLA_MAX, ifla_policy,
    1910                 :            :                                                      extack);
    1911                 :            :         }
    1912                 :            : 
    1913                 :            :         /* A hack to preserve kernel<->userspace interface.
    1914                 :            :          * The correct header is ifinfomsg. It is consistent with rtnl_getlink.
    1915                 :            :          * However, before Linux v3.9 the code here assumed rtgenmsg and that's
    1916                 :            :          * what iproute2 < v3.9.0 used.
    1917                 :            :          * We can detect the old iproute2. Even including the IFLA_EXT_MASK
    1918                 :            :          * attribute, its netlink message is shorter than struct ifinfomsg.
    1919                 :            :          */
    1920         [ -  + ]:       2484 :         hdrlen = nlmsg_len(nlh) < sizeof(struct ifinfomsg) ?
    1921                 :            :                  sizeof(struct rtgenmsg) : sizeof(struct ifinfomsg);
    1922                 :            : 
    1923                 :       2484 :         return nlmsg_parse_deprecated(nlh, hdrlen, tb, IFLA_MAX, ifla_policy,
    1924                 :            :                                       extack);
    1925                 :            : }
    1926                 :            : 
    1927                 :       2484 : static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
    1928                 :            : {
    1929                 :       2484 :         struct netlink_ext_ack *extack = cb->extack;
    1930                 :       2484 :         const struct nlmsghdr *nlh = cb->nlh;
    1931                 :       2484 :         struct net *net = sock_net(skb->sk);
    1932                 :            :         struct net *tgt_net = net;
    1933                 :            :         int h, s_h;
    1934                 :            :         int idx = 0, s_idx;
    1935                 :            :         struct net_device *dev;
    1936                 :            :         struct hlist_head *head;
    1937                 :            :         struct nlattr *tb[IFLA_MAX+1];
    1938                 :            :         u32 ext_filter_mask = 0;
    1939                 :            :         const struct rtnl_link_ops *kind_ops = NULL;
    1940                 :            :         unsigned int flags = NLM_F_MULTI;
    1941                 :            :         int master_idx = 0;
    1942                 :            :         int netnsid = -1;
    1943                 :            :         int err, i;
    1944                 :            : 
    1945                 :       2484 :         s_h = cb->args[0];
    1946                 :       2484 :         s_idx = cb->args[1];
    1947                 :            : 
    1948                 :       2484 :         err = rtnl_valid_dump_ifinfo_req(nlh, cb->strict_check, tb, extack);
    1949         [ +  - ]:       2484 :         if (err < 0) {
    1950         [ #  # ]:          0 :                 if (cb->strict_check)
    1951                 :            :                         return err;
    1952                 :            : 
    1953                 :            :                 goto walk_entries;
    1954                 :            :         }
    1955                 :            : 
    1956         [ +  + ]:     129168 :         for (i = 0; i <= IFLA_MAX; ++i) {
    1957         [ +  - ]:     129168 :                 if (!tb[i])
    1958                 :     129168 :                         continue;
    1959                 :            : 
    1960                 :            :                 /* new attributes should only be added with strict checking */
    1961   [ #  #  #  #  :          0 :                 switch (i) {
                      # ]
    1962                 :            :                 case IFLA_TARGET_NETNSID:
    1963                 :            :                         netnsid = nla_get_s32(tb[i]);
    1964                 :          0 :                         tgt_net = rtnl_get_net_ns_capable(skb->sk, netnsid);
    1965         [ #  # ]:          0 :                         if (IS_ERR(tgt_net)) {
    1966         [ #  # ]:          0 :                                 NL_SET_ERR_MSG(extack, "Invalid target network namespace id");
    1967                 :          0 :                                 return PTR_ERR(tgt_net);
    1968                 :            :                         }
    1969                 :            :                         break;
    1970                 :            :                 case IFLA_EXT_MASK:
    1971                 :            :                         ext_filter_mask = nla_get_u32(tb[i]);
    1972                 :          0 :                         break;
    1973                 :            :                 case IFLA_MASTER:
    1974                 :          0 :                         master_idx = nla_get_u32(tb[i]);
    1975                 :          0 :                         break;
    1976                 :            :                 case IFLA_LINKINFO:
    1977                 :          0 :                         kind_ops = linkinfo_to_kind_ops(tb[i]);
    1978                 :          0 :                         break;
    1979                 :            :                 default:
    1980         [ #  # ]:          0 :                         if (cb->strict_check) {
    1981         [ #  # ]:          0 :                                 NL_SET_ERR_MSG(extack, "Unsupported attribute in link dump request");
    1982                 :            :                                 return -EINVAL;
    1983                 :            :                         }
    1984                 :            :                 }
    1985                 :            :         }
    1986                 :            : 
    1987         [ -  + ]:       2484 :         if (master_idx || kind_ops)
    1988                 :            :                 flags |= NLM_F_DUMP_FILTERED;
    1989                 :            : 
    1990                 :            : walk_entries:
    1991         [ +  + ]:     320436 :         for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
    1992                 :            :                 idx = 0;
    1993                 :     317952 :                 head = &tgt_net->dev_index_head[h];
    1994   [ +  +  -  +  :     320436 :                 hlist_for_each_entry(dev, head, index_hlist) {
                   +  + ]
    1995         [ +  - ]:       2484 :                         if (link_dump_filtered(dev, master_idx, kind_ops))
    1996                 :            :                                 goto cont;
    1997         [ +  - ]:       2484 :                         if (idx < s_idx)
    1998                 :            :                                 goto cont;
    1999                 :       2484 :                         err = rtnl_fill_ifinfo(skb, dev, net,
    2000                 :            :                                                RTM_NEWLINK,
    2001                 :       2484 :                                                NETLINK_CB(cb->skb).portid,
    2002                 :            :                                                nlh->nlmsg_seq, 0, flags,
    2003                 :            :                                                ext_filter_mask, 0, NULL, 0,
    2004                 :            :                                                netnsid, GFP_KERNEL);
    2005                 :            : 
    2006         [ -  + ]:       2484 :                         if (err < 0) {
    2007         [ #  # ]:          0 :                                 if (likely(skb->len))
    2008                 :            :                                         goto out;
    2009                 :            : 
    2010                 :            :                                 goto out_err;
    2011                 :            :                         }
    2012                 :            : cont:
    2013                 :       2484 :                         idx++;
    2014                 :            :                 }
    2015                 :            :         }
    2016                 :            : out:
    2017                 :       2484 :         err = skb->len;
    2018                 :            : out_err:
    2019                 :       2484 :         cb->args[1] = idx;
    2020                 :       2484 :         cb->args[0] = h;
    2021                 :       2484 :         cb->seq = net->dev_base_seq;
    2022                 :            :         nl_dump_check_consistent(cb, nlmsg_hdr(skb));
    2023         [ -  + ]:       2484 :         if (netnsid >= 0)
    2024                 :          0 :                 put_net(tgt_net);
    2025                 :            : 
    2026                 :       2484 :         return err;
    2027                 :            : }
    2028                 :            : 
    2029                 :          0 : int rtnl_nla_parse_ifla(struct nlattr **tb, const struct nlattr *head, int len,
    2030                 :            :                         struct netlink_ext_ack *exterr)
    2031                 :            : {
    2032                 :          0 :         return nla_parse_deprecated(tb, IFLA_MAX, head, len, ifla_policy,
    2033                 :            :                                     exterr);
    2034                 :            : }
    2035                 :            : EXPORT_SYMBOL(rtnl_nla_parse_ifla);
    2036                 :            : 
    2037                 :          0 : struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[])
    2038                 :            : {
    2039                 :            :         struct net *net;
    2040                 :            :         /* Examine the link attributes and figure out which
    2041                 :            :          * network namespace we are talking about.
    2042                 :            :          */
    2043         [ #  # ]:          0 :         if (tb[IFLA_NET_NS_PID])
    2044                 :          0 :                 net = get_net_ns_by_pid(nla_get_u32(tb[IFLA_NET_NS_PID]));
    2045         [ #  # ]:          0 :         else if (tb[IFLA_NET_NS_FD])
    2046                 :          0 :                 net = get_net_ns_by_fd(nla_get_u32(tb[IFLA_NET_NS_FD]));
    2047                 :            :         else
    2048                 :            :                 net = get_net(src_net);
    2049                 :          0 :         return net;
    2050                 :            : }
    2051                 :            : EXPORT_SYMBOL(rtnl_link_get_net);
    2052                 :            : 
    2053                 :            : /* Figure out which network namespace we are talking about by
    2054                 :            :  * examining the link attributes in the following order:
    2055                 :            :  *
    2056                 :            :  * 1. IFLA_NET_NS_PID
    2057                 :            :  * 2. IFLA_NET_NS_FD
    2058                 :            :  * 3. IFLA_TARGET_NETNSID
    2059                 :            :  */
    2060                 :          0 : static struct net *rtnl_link_get_net_by_nlattr(struct net *src_net,
    2061                 :            :                                                struct nlattr *tb[])
    2062                 :            : {
    2063                 :            :         struct net *net;
    2064                 :            : 
    2065   [ #  #  #  # ]:          0 :         if (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD])
    2066                 :          0 :                 return rtnl_link_get_net(src_net, tb);
    2067                 :            : 
    2068         [ #  # ]:          0 :         if (!tb[IFLA_TARGET_NETNSID])
    2069                 :          0 :                 return get_net(src_net);
    2070                 :            : 
    2071                 :          0 :         net = get_net_ns_by_id(src_net, nla_get_u32(tb[IFLA_TARGET_NETNSID]));
    2072         [ #  # ]:          0 :         if (!net)
    2073                 :            :                 return ERR_PTR(-EINVAL);
    2074                 :            : 
    2075                 :          0 :         return net;
    2076                 :            : }
    2077                 :            : 
    2078                 :          0 : static struct net *rtnl_link_get_net_capable(const struct sk_buff *skb,
    2079                 :            :                                              struct net *src_net,
    2080                 :            :                                              struct nlattr *tb[], int cap)
    2081                 :            : {
    2082                 :            :         struct net *net;
    2083                 :            : 
    2084                 :          0 :         net = rtnl_link_get_net_by_nlattr(src_net, tb);
    2085         [ #  # ]:          0 :         if (IS_ERR(net))
    2086                 :            :                 return net;
    2087                 :            : 
    2088         [ #  # ]:          0 :         if (!netlink_ns_capable(skb, net->user_ns, cap)) {
    2089                 :          0 :                 put_net(net);
    2090                 :          0 :                 return ERR_PTR(-EPERM);
    2091                 :            :         }
    2092                 :            : 
    2093                 :            :         return net;
    2094                 :            : }
    2095                 :            : 
    2096                 :            : /* Verify that rtnetlink requests do not pass additional properties
    2097                 :            :  * potentially referring to different network namespaces.
    2098                 :            :  */
    2099                 :       1242 : static int rtnl_ensure_unique_netns(struct nlattr *tb[],
    2100                 :            :                                     struct netlink_ext_ack *extack,
    2101                 :            :                                     bool netns_id_only)
    2102                 :            : {
    2103                 :            : 
    2104         [ -  + ]:       1242 :         if (netns_id_only) {
    2105   [ #  #  #  # ]:          0 :                 if (!tb[IFLA_NET_NS_PID] && !tb[IFLA_NET_NS_FD])
    2106                 :            :                         return 0;
    2107                 :            : 
    2108         [ #  # ]:          0 :                 NL_SET_ERR_MSG(extack, "specified netns attribute not supported");
    2109                 :            :                 return -EOPNOTSUPP;
    2110                 :            :         }
    2111                 :            : 
    2112   [ -  +  #  #  :       1242 :         if (tb[IFLA_TARGET_NETNSID] && (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD]))
                   #  # ]
    2113                 :            :                 goto invalid_attr;
    2114                 :            : 
    2115   [ -  +  #  #  :       1242 :         if (tb[IFLA_NET_NS_PID] && (tb[IFLA_TARGET_NETNSID] || tb[IFLA_NET_NS_FD]))
                   #  # ]
    2116                 :            :                 goto invalid_attr;
    2117                 :            : 
    2118   [ -  +  #  #  :       1242 :         if (tb[IFLA_NET_NS_FD] && (tb[IFLA_TARGET_NETNSID] || tb[IFLA_NET_NS_PID]))
                   #  # ]
    2119                 :            :                 goto invalid_attr;
    2120                 :            : 
    2121                 :            :         return 0;
    2122                 :            : 
    2123                 :            : invalid_attr:
    2124         [ #  # ]:          0 :         NL_SET_ERR_MSG(extack, "multiple netns identifying attributes specified");
    2125                 :            :         return -EINVAL;
    2126                 :            : }
    2127                 :            : 
    2128                 :       2070 : static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[])
    2129                 :            : {
    2130         [ +  + ]:       2070 :         if (dev) {
    2131   [ -  +  #  # ]:       1863 :                 if (tb[IFLA_ADDRESS] &&
    2132                 :          0 :                     nla_len(tb[IFLA_ADDRESS]) < dev->addr_len)
    2133                 :            :                         return -EINVAL;
    2134                 :            : 
    2135   [ -  +  #  # ]:       1863 :                 if (tb[IFLA_BROADCAST] &&
    2136                 :          0 :                     nla_len(tb[IFLA_BROADCAST]) < dev->addr_len)
    2137                 :            :                         return -EINVAL;
    2138                 :            :         }
    2139                 :            : 
    2140         [ +  + ]:       2070 :         if (tb[IFLA_AF_SPEC]) {
    2141                 :            :                 struct nlattr *af;
    2142                 :            :                 int rem, err;
    2143                 :            : 
    2144         [ +  + ]:       3726 :                 nla_for_each_nested(af, tb[IFLA_AF_SPEC], rem) {
    2145                 :            :                         const struct rtnl_af_ops *af_ops;
    2146                 :            : 
    2147                 :            :                         rcu_read_lock();
    2148                 :            :                         af_ops = rtnl_af_lookup(nla_type(af));
    2149         [ -  + ]:       1242 :                         if (!af_ops) {
    2150                 :            :                                 rcu_read_unlock();
    2151                 :          0 :                                 return -EAFNOSUPPORT;
    2152                 :            :                         }
    2153                 :            : 
    2154         [ -  + ]:       1242 :                         if (!af_ops->set_link_af) {
    2155                 :            :                                 rcu_read_unlock();
    2156                 :          0 :                                 return -EOPNOTSUPP;
    2157                 :            :                         }
    2158                 :            : 
    2159         [ +  - ]:       1242 :                         if (af_ops->validate_link_af) {
    2160                 :       1242 :                                 err = af_ops->validate_link_af(dev, af);
    2161         [ -  + ]:       1242 :                                 if (err < 0) {
    2162                 :            :                                         rcu_read_unlock();
    2163                 :          0 :                                         return err;
    2164                 :            :                                 }
    2165                 :            :                         }
    2166                 :            : 
    2167                 :            :                         rcu_read_unlock();
    2168                 :            :                 }
    2169                 :            :         }
    2170                 :            : 
    2171                 :            :         return 0;
    2172                 :            : }
    2173                 :            : 
    2174                 :            : static int handle_infiniband_guid(struct net_device *dev, struct ifla_vf_guid *ivt,
    2175                 :            :                                   int guid_type)
    2176                 :            : {
    2177                 :          0 :         const struct net_device_ops *ops = dev->netdev_ops;
    2178                 :            : 
    2179                 :          0 :         return ops->ndo_set_vf_guid(dev, ivt->vf, ivt->guid, guid_type);
    2180                 :            : }
    2181                 :            : 
    2182                 :            : static int handle_vf_guid(struct net_device *dev, struct ifla_vf_guid *ivt, int guid_type)
    2183                 :            : {
    2184   [ #  #  #  # ]:          0 :         if (dev->type != ARPHRD_INFINIBAND)
    2185                 :            :                 return -EOPNOTSUPP;
    2186                 :            : 
    2187                 :            :         return handle_infiniband_guid(dev, ivt, guid_type);
    2188                 :            : }
    2189                 :            : 
    2190                 :          0 : static int do_setvfinfo(struct net_device *dev, struct nlattr **tb)
    2191                 :            : {
    2192                 :          0 :         const struct net_device_ops *ops = dev->netdev_ops;
    2193                 :            :         int err = -EINVAL;
    2194                 :            : 
    2195         [ #  # ]:          0 :         if (tb[IFLA_VF_MAC]) {
    2196                 :            :                 struct ifla_vf_mac *ivm = nla_data(tb[IFLA_VF_MAC]);
    2197                 :            : 
    2198         [ #  # ]:          0 :                 if (ivm->vf >= INT_MAX)
    2199                 :            :                         return -EINVAL;
    2200                 :            :                 err = -EOPNOTSUPP;
    2201         [ #  # ]:          0 :                 if (ops->ndo_set_vf_mac)
    2202                 :          0 :                         err = ops->ndo_set_vf_mac(dev, ivm->vf,
    2203                 :          0 :                                                   ivm->mac);
    2204         [ #  # ]:          0 :                 if (err < 0)
    2205                 :            :                         return err;
    2206                 :            :         }
    2207                 :            : 
    2208         [ #  # ]:          0 :         if (tb[IFLA_VF_VLAN]) {
    2209                 :            :                 struct ifla_vf_vlan *ivv = nla_data(tb[IFLA_VF_VLAN]);
    2210                 :            : 
    2211         [ #  # ]:          0 :                 if (ivv->vf >= INT_MAX)
    2212                 :            :                         return -EINVAL;
    2213                 :            :                 err = -EOPNOTSUPP;
    2214         [ #  # ]:          0 :                 if (ops->ndo_set_vf_vlan)
    2215                 :          0 :                         err = ops->ndo_set_vf_vlan(dev, ivv->vf, ivv->vlan,
    2216                 :          0 :                                                    ivv->qos,
    2217                 :            :                                                    htons(ETH_P_8021Q));
    2218         [ #  # ]:          0 :                 if (err < 0)
    2219                 :            :                         return err;
    2220                 :            :         }
    2221                 :            : 
    2222         [ #  # ]:          0 :         if (tb[IFLA_VF_VLAN_LIST]) {
    2223                 :            :                 struct ifla_vf_vlan_info *ivvl[MAX_VLAN_LIST_LEN];
    2224                 :            :                 struct nlattr *attr;
    2225                 :            :                 int rem, len = 0;
    2226                 :            : 
    2227                 :            :                 err = -EOPNOTSUPP;
    2228         [ #  # ]:          0 :                 if (!ops->ndo_set_vf_vlan)
    2229                 :            :                         return err;
    2230                 :            : 
    2231         [ #  # ]:          0 :                 nla_for_each_nested(attr, tb[IFLA_VF_VLAN_LIST], rem) {
    2232   [ #  #  #  # ]:          0 :                         if (nla_type(attr) != IFLA_VF_VLAN_INFO ||
    2233                 :            :                             nla_len(attr) < NLA_HDRLEN) {
    2234                 :            :                                 return -EINVAL;
    2235                 :            :                         }
    2236         [ #  # ]:          0 :                         if (len >= MAX_VLAN_LIST_LEN)
    2237                 :            :                                 return -EOPNOTSUPP;
    2238                 :            :                         ivvl[len] = nla_data(attr);
    2239                 :            : 
    2240                 :          0 :                         len++;
    2241                 :            :                 }
    2242         [ #  # ]:          0 :                 if (len == 0)
    2243                 :            :                         return -EINVAL;
    2244                 :            : 
    2245         [ #  # ]:          0 :                 if (ivvl[0]->vf >= INT_MAX)
    2246                 :            :                         return -EINVAL;
    2247                 :          0 :                 err = ops->ndo_set_vf_vlan(dev, ivvl[0]->vf, ivvl[0]->vlan,
    2248                 :          0 :                                            ivvl[0]->qos, ivvl[0]->vlan_proto);
    2249         [ #  # ]:          0 :                 if (err < 0)
    2250                 :            :                         return err;
    2251                 :            :         }
    2252                 :            : 
    2253         [ #  # ]:          0 :         if (tb[IFLA_VF_TX_RATE]) {
    2254                 :            :                 struct ifla_vf_tx_rate *ivt = nla_data(tb[IFLA_VF_TX_RATE]);
    2255                 :            :                 struct ifla_vf_info ivf;
    2256                 :            : 
    2257         [ #  # ]:          0 :                 if (ivt->vf >= INT_MAX)
    2258                 :          0 :                         return -EINVAL;
    2259                 :            :                 err = -EOPNOTSUPP;
    2260         [ #  # ]:          0 :                 if (ops->ndo_get_vf_config)
    2261                 :          0 :                         err = ops->ndo_get_vf_config(dev, ivt->vf, &ivf);
    2262         [ #  # ]:          0 :                 if (err < 0)
    2263                 :            :                         return err;
    2264                 :            : 
    2265                 :            :                 err = -EOPNOTSUPP;
    2266         [ #  # ]:          0 :                 if (ops->ndo_set_vf_rate)
    2267                 :          0 :                         err = ops->ndo_set_vf_rate(dev, ivt->vf,
    2268                 :          0 :                                                    ivf.min_tx_rate,
    2269                 :          0 :                                                    ivt->rate);
    2270         [ #  # ]:          0 :                 if (err < 0)
    2271                 :            :                         return err;
    2272                 :            :         }
    2273                 :            : 
    2274         [ #  # ]:          0 :         if (tb[IFLA_VF_RATE]) {
    2275                 :            :                 struct ifla_vf_rate *ivt = nla_data(tb[IFLA_VF_RATE]);
    2276                 :            : 
    2277         [ #  # ]:          0 :                 if (ivt->vf >= INT_MAX)
    2278                 :            :                         return -EINVAL;
    2279                 :            :                 err = -EOPNOTSUPP;
    2280         [ #  # ]:          0 :                 if (ops->ndo_set_vf_rate)
    2281                 :          0 :                         err = ops->ndo_set_vf_rate(dev, ivt->vf,
    2282                 :          0 :                                                    ivt->min_tx_rate,
    2283                 :          0 :                                                    ivt->max_tx_rate);
    2284         [ #  # ]:          0 :                 if (err < 0)
    2285                 :            :                         return err;
    2286                 :            :         }
    2287                 :            : 
    2288         [ #  # ]:          0 :         if (tb[IFLA_VF_SPOOFCHK]) {
    2289                 :            :                 struct ifla_vf_spoofchk *ivs = nla_data(tb[IFLA_VF_SPOOFCHK]);
    2290                 :            : 
    2291         [ #  # ]:          0 :                 if (ivs->vf >= INT_MAX)
    2292                 :            :                         return -EINVAL;
    2293                 :            :                 err = -EOPNOTSUPP;
    2294         [ #  # ]:          0 :                 if (ops->ndo_set_vf_spoofchk)
    2295                 :          0 :                         err = ops->ndo_set_vf_spoofchk(dev, ivs->vf,
    2296                 :          0 :                                                        ivs->setting);
    2297         [ #  # ]:          0 :                 if (err < 0)
    2298                 :            :                         return err;
    2299                 :            :         }
    2300                 :            : 
    2301         [ #  # ]:          0 :         if (tb[IFLA_VF_LINK_STATE]) {
    2302                 :            :                 struct ifla_vf_link_state *ivl = nla_data(tb[IFLA_VF_LINK_STATE]);
    2303                 :            : 
    2304         [ #  # ]:          0 :                 if (ivl->vf >= INT_MAX)
    2305                 :            :                         return -EINVAL;
    2306                 :            :                 err = -EOPNOTSUPP;
    2307         [ #  # ]:          0 :                 if (ops->ndo_set_vf_link_state)
    2308                 :          0 :                         err = ops->ndo_set_vf_link_state(dev, ivl->vf,
    2309                 :          0 :                                                          ivl->link_state);
    2310         [ #  # ]:          0 :                 if (err < 0)
    2311                 :            :                         return err;
    2312                 :            :         }
    2313                 :            : 
    2314         [ #  # ]:          0 :         if (tb[IFLA_VF_RSS_QUERY_EN]) {
    2315                 :            :                 struct ifla_vf_rss_query_en *ivrssq_en;
    2316                 :            : 
    2317                 :            :                 err = -EOPNOTSUPP;
    2318                 :            :                 ivrssq_en = nla_data(tb[IFLA_VF_RSS_QUERY_EN]);
    2319         [ #  # ]:          0 :                 if (ivrssq_en->vf >= INT_MAX)
    2320                 :            :                         return -EINVAL;
    2321         [ #  # ]:          0 :                 if (ops->ndo_set_vf_rss_query_en)
    2322                 :          0 :                         err = ops->ndo_set_vf_rss_query_en(dev, ivrssq_en->vf,
    2323                 :          0 :                                                            ivrssq_en->setting);
    2324         [ #  # ]:          0 :                 if (err < 0)
    2325                 :            :                         return err;
    2326                 :            :         }
    2327                 :            : 
    2328         [ #  # ]:          0 :         if (tb[IFLA_VF_TRUST]) {
    2329                 :            :                 struct ifla_vf_trust *ivt = nla_data(tb[IFLA_VF_TRUST]);
    2330                 :            : 
    2331         [ #  # ]:          0 :                 if (ivt->vf >= INT_MAX)
    2332                 :            :                         return -EINVAL;
    2333                 :            :                 err = -EOPNOTSUPP;
    2334         [ #  # ]:          0 :                 if (ops->ndo_set_vf_trust)
    2335                 :          0 :                         err = ops->ndo_set_vf_trust(dev, ivt->vf, ivt->setting);
    2336         [ #  # ]:          0 :                 if (err < 0)
    2337                 :            :                         return err;
    2338                 :            :         }
    2339                 :            : 
    2340         [ #  # ]:          0 :         if (tb[IFLA_VF_IB_NODE_GUID]) {
    2341                 :            :                 struct ifla_vf_guid *ivt = nla_data(tb[IFLA_VF_IB_NODE_GUID]);
    2342                 :            : 
    2343         [ #  # ]:          0 :                 if (ivt->vf >= INT_MAX)
    2344                 :            :                         return -EINVAL;
    2345         [ #  # ]:          0 :                 if (!ops->ndo_set_vf_guid)
    2346                 :            :                         return -EOPNOTSUPP;
    2347                 :          0 :                 return handle_vf_guid(dev, ivt, IFLA_VF_IB_NODE_GUID);
    2348                 :            :         }
    2349                 :            : 
    2350         [ #  # ]:          0 :         if (tb[IFLA_VF_IB_PORT_GUID]) {
    2351                 :            :                 struct ifla_vf_guid *ivt = nla_data(tb[IFLA_VF_IB_PORT_GUID]);
    2352                 :            : 
    2353         [ #  # ]:          0 :                 if (ivt->vf >= INT_MAX)
    2354                 :            :                         return -EINVAL;
    2355         [ #  # ]:          0 :                 if (!ops->ndo_set_vf_guid)
    2356                 :            :                         return -EOPNOTSUPP;
    2357                 :            : 
    2358                 :          0 :                 return handle_vf_guid(dev, ivt, IFLA_VF_IB_PORT_GUID);
    2359                 :            :         }
    2360                 :            : 
    2361                 :            :         return err;
    2362                 :            : }
    2363                 :            : 
    2364                 :          0 : static int do_set_master(struct net_device *dev, int ifindex,
    2365                 :            :                          struct netlink_ext_ack *extack)
    2366                 :            : {
    2367                 :          0 :         struct net_device *upper_dev = netdev_master_upper_dev_get(dev);
    2368                 :            :         const struct net_device_ops *ops;
    2369                 :            :         int err;
    2370                 :            : 
    2371         [ #  # ]:          0 :         if (upper_dev) {
    2372         [ #  # ]:          0 :                 if (upper_dev->ifindex == ifindex)
    2373                 :            :                         return 0;
    2374                 :          0 :                 ops = upper_dev->netdev_ops;
    2375         [ #  # ]:          0 :                 if (ops->ndo_del_slave) {
    2376                 :          0 :                         err = ops->ndo_del_slave(upper_dev, dev);
    2377         [ #  # ]:          0 :                         if (err)
    2378                 :            :                                 return err;
    2379                 :          0 :                         netdev_update_lockdep_key(dev);
    2380                 :            :                 } else {
    2381                 :            :                         return -EOPNOTSUPP;
    2382                 :            :                 }
    2383                 :            :         }
    2384                 :            : 
    2385         [ #  # ]:          0 :         if (ifindex) {
    2386                 :          0 :                 upper_dev = __dev_get_by_index(dev_net(dev), ifindex);
    2387         [ #  # ]:          0 :                 if (!upper_dev)
    2388                 :            :                         return -EINVAL;
    2389                 :          0 :                 ops = upper_dev->netdev_ops;
    2390         [ #  # ]:          0 :                 if (ops->ndo_add_slave) {
    2391                 :          0 :                         err = ops->ndo_add_slave(upper_dev, dev, extack);
    2392         [ #  # ]:          0 :                         if (err)
    2393                 :          0 :                                 return err;
    2394                 :            :                 } else {
    2395                 :            :                         return -EOPNOTSUPP;
    2396                 :            :                 }
    2397                 :            :         }
    2398                 :            :         return 0;
    2399                 :            : }
    2400                 :            : 
    2401                 :            : #define DO_SETLINK_MODIFIED     0x01
    2402                 :            : /* notify flag means notify + modified. */
    2403                 :            : #define DO_SETLINK_NOTIFY       0x03
    2404                 :       1035 : static int do_setlink(const struct sk_buff *skb,
    2405                 :            :                       struct net_device *dev, struct ifinfomsg *ifm,
    2406                 :            :                       struct netlink_ext_ack *extack,
    2407                 :            :                       struct nlattr **tb, char *ifname, int status)
    2408                 :            : {
    2409                 :       1035 :         const struct net_device_ops *ops = dev->netdev_ops;
    2410                 :            :         int err;
    2411                 :            : 
    2412                 :       1035 :         err = validate_linkmsg(dev, tb);
    2413         [ +  - ]:       1035 :         if (err < 0)
    2414                 :            :                 return err;
    2415                 :            : 
    2416   [ +  -  +  -  :       1035 :         if (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD] || tb[IFLA_TARGET_NETNSID]) {
                   -  + ]
    2417                 :          0 :                 struct net *net = rtnl_link_get_net_capable(skb, dev_net(dev),
    2418                 :            :                                                             tb, CAP_NET_ADMIN);
    2419         [ #  # ]:          0 :                 if (IS_ERR(net)) {
    2420                 :            :                         err = PTR_ERR(net);
    2421                 :          0 :                         goto errout;
    2422                 :            :                 }
    2423                 :            : 
    2424                 :          0 :                 err = dev_change_net_namespace(dev, net, ifname);
    2425                 :          0 :                 put_net(net);
    2426         [ #  # ]:          0 :                 if (err)
    2427                 :            :                         goto errout;
    2428                 :          0 :                 status |= DO_SETLINK_MODIFIED;
    2429                 :            :         }
    2430                 :            : 
    2431         [ -  + ]:       1035 :         if (tb[IFLA_MAP]) {
    2432                 :            :                 struct rtnl_link_ifmap *u_map;
    2433                 :            :                 struct ifmap k_map;
    2434                 :            : 
    2435         [ #  # ]:          0 :                 if (!ops->ndo_set_config) {
    2436                 :            :                         err = -EOPNOTSUPP;
    2437                 :          0 :                         goto errout;
    2438                 :            :                 }
    2439                 :            : 
    2440         [ #  # ]:          0 :                 if (!netif_device_present(dev)) {
    2441                 :            :                         err = -ENODEV;
    2442                 :            :                         goto errout;
    2443                 :            :                 }
    2444                 :            : 
    2445                 :            :                 u_map = nla_data(tb[IFLA_MAP]);
    2446                 :          0 :                 k_map.mem_start = (unsigned long) u_map->mem_start;
    2447                 :          0 :                 k_map.mem_end = (unsigned long) u_map->mem_end;
    2448                 :          0 :                 k_map.base_addr = (unsigned short) u_map->base_addr;
    2449                 :          0 :                 k_map.irq = (unsigned char) u_map->irq;
    2450                 :          0 :                 k_map.dma = (unsigned char) u_map->dma;
    2451                 :          0 :                 k_map.port = (unsigned char) u_map->port;
    2452                 :            : 
    2453                 :          0 :                 err = ops->ndo_set_config(dev, &k_map);
    2454         [ #  # ]:          0 :                 if (err < 0)
    2455                 :            :                         goto errout;
    2456                 :            : 
    2457                 :          0 :                 status |= DO_SETLINK_NOTIFY;
    2458                 :            :         }
    2459                 :            : 
    2460         [ -  + ]:       1035 :         if (tb[IFLA_ADDRESS]) {
    2461                 :            :                 struct sockaddr *sa;
    2462                 :            :                 int len;
    2463                 :            : 
    2464                 :          0 :                 len = sizeof(sa_family_t) + max_t(size_t, dev->addr_len,
    2465                 :            :                                                   sizeof(*sa));
    2466                 :            :                 sa = kmalloc(len, GFP_KERNEL);
    2467         [ #  # ]:          0 :                 if (!sa) {
    2468                 :            :                         err = -ENOMEM;
    2469                 :            :                         goto errout;
    2470                 :            :                 }
    2471                 :          0 :                 sa->sa_family = dev->type;
    2472                 :          0 :                 memcpy(sa->sa_data, nla_data(tb[IFLA_ADDRESS]),
    2473                 :          0 :                        dev->addr_len);
    2474                 :          0 :                 err = dev_set_mac_address(dev, sa, extack);
    2475                 :          0 :                 kfree(sa);
    2476         [ #  # ]:          0 :                 if (err)
    2477                 :            :                         goto errout;
    2478                 :          0 :                 status |= DO_SETLINK_MODIFIED;
    2479                 :            :         }
    2480                 :            : 
    2481         [ -  + ]:       1035 :         if (tb[IFLA_MTU]) {
    2482                 :          0 :                 err = dev_set_mtu_ext(dev, nla_get_u32(tb[IFLA_MTU]), extack);
    2483         [ #  # ]:          0 :                 if (err < 0)
    2484                 :            :                         goto errout;
    2485                 :          0 :                 status |= DO_SETLINK_MODIFIED;
    2486                 :            :         }
    2487                 :            : 
    2488         [ -  + ]:       1035 :         if (tb[IFLA_GROUP]) {
    2489                 :          0 :                 dev_set_group(dev, nla_get_u32(tb[IFLA_GROUP]));
    2490                 :          0 :                 status |= DO_SETLINK_NOTIFY;
    2491                 :            :         }
    2492                 :            : 
    2493                 :            :         /*
    2494                 :            :          * Interface selected by interface index but interface
    2495                 :            :          * name provided implies that a name change has been
    2496                 :            :          * requested.
    2497                 :            :          */
    2498   [ +  -  -  + ]:       1035 :         if (ifm->ifi_index > 0 && ifname[0]) {
    2499                 :          0 :                 err = dev_change_name(dev, ifname);
    2500         [ #  # ]:          0 :                 if (err < 0)
    2501                 :            :                         goto errout;
    2502                 :          0 :                 status |= DO_SETLINK_MODIFIED;
    2503                 :            :         }
    2504                 :            : 
    2505         [ -  + ]:       1035 :         if (tb[IFLA_IFALIAS]) {
    2506                 :          0 :                 err = dev_set_alias(dev, nla_data(tb[IFLA_IFALIAS]),
    2507                 :            :                                     nla_len(tb[IFLA_IFALIAS]));
    2508         [ #  # ]:          0 :                 if (err < 0)
    2509                 :            :                         goto errout;
    2510                 :          0 :                 status |= DO_SETLINK_NOTIFY;
    2511                 :            :         }
    2512                 :            : 
    2513         [ -  + ]:       1035 :         if (tb[IFLA_BROADCAST]) {
    2514                 :          0 :                 nla_memcpy(dev->broadcast, tb[IFLA_BROADCAST], dev->addr_len);
    2515                 :          0 :                 call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
    2516                 :            :         }
    2517                 :            : 
    2518   [ +  +  -  + ]:       1035 :         if (ifm->ifi_flags || ifm->ifi_change) {
    2519                 :        414 :                 err = dev_change_flags(dev, rtnl_dev_combine_flags(dev, ifm),
    2520                 :            :                                        extack);
    2521         [ +  - ]:        414 :                 if (err < 0)
    2522                 :            :                         goto errout;
    2523                 :            :         }
    2524                 :            : 
    2525         [ -  + ]:       1035 :         if (tb[IFLA_MASTER]) {
    2526                 :          0 :                 err = do_set_master(dev, nla_get_u32(tb[IFLA_MASTER]), extack);
    2527         [ #  # ]:          0 :                 if (err)
    2528                 :            :                         goto errout;
    2529                 :          0 :                 status |= DO_SETLINK_MODIFIED;
    2530                 :            :         }
    2531                 :            : 
    2532         [ -  + ]:       1035 :         if (tb[IFLA_CARRIER]) {
    2533                 :          0 :                 err = dev_change_carrier(dev, nla_get_u8(tb[IFLA_CARRIER]));
    2534         [ #  # ]:          0 :                 if (err)
    2535                 :            :                         goto errout;
    2536                 :          0 :                 status |= DO_SETLINK_MODIFIED;
    2537                 :            :         }
    2538                 :            : 
    2539         [ -  + ]:       1035 :         if (tb[IFLA_TXQLEN]) {
    2540                 :            :                 unsigned int value = nla_get_u32(tb[IFLA_TXQLEN]);
    2541                 :            : 
    2542                 :          0 :                 err = dev_change_tx_queue_len(dev, value);
    2543         [ #  # ]:          0 :                 if (err)
    2544                 :            :                         goto errout;
    2545                 :          0 :                 status |= DO_SETLINK_MODIFIED;
    2546                 :            :         }
    2547                 :            : 
    2548         [ -  + ]:       1035 :         if (tb[IFLA_GSO_MAX_SIZE]) {
    2549                 :            :                 u32 max_size = nla_get_u32(tb[IFLA_GSO_MAX_SIZE]);
    2550                 :            : 
    2551         [ #  # ]:          0 :                 if (max_size > GSO_MAX_SIZE) {
    2552                 :            :                         err = -EINVAL;
    2553                 :            :                         goto errout;
    2554                 :            :                 }
    2555                 :            : 
    2556         [ #  # ]:          0 :                 if (dev->gso_max_size ^ max_size) {
    2557                 :            :                         netif_set_gso_max_size(dev, max_size);
    2558                 :          0 :                         status |= DO_SETLINK_MODIFIED;
    2559                 :            :                 }
    2560                 :            :         }
    2561                 :            : 
    2562         [ -  + ]:       1035 :         if (tb[IFLA_GSO_MAX_SEGS]) {
    2563                 :            :                 u32 max_segs = nla_get_u32(tb[IFLA_GSO_MAX_SEGS]);
    2564                 :            : 
    2565         [ #  # ]:          0 :                 if (max_segs > GSO_MAX_SEGS) {
    2566                 :            :                         err = -EINVAL;
    2567                 :            :                         goto errout;
    2568                 :            :                 }
    2569                 :            : 
    2570         [ #  # ]:          0 :                 if (dev->gso_max_segs ^ max_segs) {
    2571                 :          0 :                         dev->gso_max_segs = max_segs;
    2572                 :          0 :                         status |= DO_SETLINK_MODIFIED;
    2573                 :            :                 }
    2574                 :            :         }
    2575                 :            : 
    2576         [ -  + ]:       1035 :         if (tb[IFLA_OPERSTATE])
    2577                 :          0 :                 set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]));
    2578                 :            : 
    2579         [ -  + ]:       1035 :         if (tb[IFLA_LINKMODE]) {
    2580                 :            :                 unsigned char value = nla_get_u8(tb[IFLA_LINKMODE]);
    2581                 :            : 
    2582                 :          0 :                 write_lock_bh(&dev_base_lock);
    2583         [ #  # ]:          0 :                 if (dev->link_mode ^ value)
    2584                 :          0 :                         status |= DO_SETLINK_NOTIFY;
    2585                 :          0 :                 dev->link_mode = value;
    2586                 :          0 :                 write_unlock_bh(&dev_base_lock);
    2587                 :            :         }
    2588                 :            : 
    2589         [ -  + ]:       1035 :         if (tb[IFLA_VFINFO_LIST]) {
    2590                 :            :                 struct nlattr *vfinfo[IFLA_VF_MAX + 1];
    2591                 :            :                 struct nlattr *attr;
    2592                 :            :                 int rem;
    2593                 :            : 
    2594         [ #  # ]:          0 :                 nla_for_each_nested(attr, tb[IFLA_VFINFO_LIST], rem) {
    2595   [ #  #  #  # ]:          0 :                         if (nla_type(attr) != IFLA_VF_INFO ||
    2596                 :            :                             nla_len(attr) < NLA_HDRLEN) {
    2597                 :            :                                 err = -EINVAL;
    2598                 :          0 :                                 goto errout;
    2599                 :            :                         }
    2600                 :            :                         err = nla_parse_nested_deprecated(vfinfo, IFLA_VF_MAX,
    2601                 :            :                                                           attr,
    2602                 :            :                                                           ifla_vf_policy,
    2603                 :            :                                                           NULL);
    2604         [ #  # ]:          0 :                         if (err < 0)
    2605                 :            :                                 goto errout;
    2606                 :          0 :                         err = do_setvfinfo(dev, vfinfo);
    2607         [ #  # ]:          0 :                         if (err < 0)
    2608                 :            :                                 goto errout;
    2609                 :          0 :                         status |= DO_SETLINK_NOTIFY;
    2610                 :            :                 }
    2611                 :            :         }
    2612                 :            :         err = 0;
    2613                 :            : 
    2614         [ -  + ]:       1035 :         if (tb[IFLA_VF_PORTS]) {
    2615                 :            :                 struct nlattr *port[IFLA_PORT_MAX+1];
    2616                 :            :                 struct nlattr *attr;
    2617                 :            :                 int vf;
    2618                 :            :                 int rem;
    2619                 :            : 
    2620                 :            :                 err = -EOPNOTSUPP;
    2621         [ #  # ]:          0 :                 if (!ops->ndo_set_vf_port)
    2622                 :            :                         goto errout;
    2623                 :            : 
    2624         [ #  # ]:          0 :                 nla_for_each_nested(attr, tb[IFLA_VF_PORTS], rem) {
    2625   [ #  #  #  # ]:          0 :                         if (nla_type(attr) != IFLA_VF_PORT ||
    2626                 :            :                             nla_len(attr) < NLA_HDRLEN) {
    2627                 :            :                                 err = -EINVAL;
    2628                 :            :                                 goto errout;
    2629                 :            :                         }
    2630                 :            :                         err = nla_parse_nested_deprecated(port, IFLA_PORT_MAX,
    2631                 :            :                                                           attr,
    2632                 :            :                                                           ifla_port_policy,
    2633                 :            :                                                           NULL);
    2634         [ #  # ]:          0 :                         if (err < 0)
    2635                 :            :                                 goto errout;
    2636         [ #  # ]:          0 :                         if (!port[IFLA_PORT_VF]) {
    2637                 :            :                                 err = -EOPNOTSUPP;
    2638                 :            :                                 goto errout;
    2639                 :            :                         }
    2640                 :          0 :                         vf = nla_get_u32(port[IFLA_PORT_VF]);
    2641                 :          0 :                         err = ops->ndo_set_vf_port(dev, vf, port);
    2642         [ #  # ]:          0 :                         if (err < 0)
    2643                 :            :                                 goto errout;
    2644                 :          0 :                         status |= DO_SETLINK_NOTIFY;
    2645                 :            :                 }
    2646                 :            :         }
    2647                 :            :         err = 0;
    2648                 :            : 
    2649         [ -  + ]:       1035 :         if (tb[IFLA_PORT_SELF]) {
    2650                 :            :                 struct nlattr *port[IFLA_PORT_MAX+1];
    2651                 :            : 
    2652                 :            :                 err = nla_parse_nested_deprecated(port, IFLA_PORT_MAX,
    2653                 :            :                                                   tb[IFLA_PORT_SELF],
    2654                 :            :                                                   ifla_port_policy, NULL);
    2655         [ #  # ]:          0 :                 if (err < 0)
    2656                 :            :                         goto errout;
    2657                 :            : 
    2658                 :            :                 err = -EOPNOTSUPP;
    2659         [ #  # ]:          0 :                 if (ops->ndo_set_vf_port)
    2660                 :          0 :                         err = ops->ndo_set_vf_port(dev, PORT_SELF_VF, port);
    2661         [ #  # ]:          0 :                 if (err < 0)
    2662                 :            :                         goto errout;
    2663                 :          0 :                 status |= DO_SETLINK_NOTIFY;
    2664                 :            :         }
    2665                 :            : 
    2666         [ +  + ]:       1035 :         if (tb[IFLA_AF_SPEC]) {
    2667                 :            :                 struct nlattr *af;
    2668                 :            :                 int rem;
    2669                 :            : 
    2670         [ +  + ]:       1863 :                 nla_for_each_nested(af, tb[IFLA_AF_SPEC], rem) {
    2671                 :            :                         const struct rtnl_af_ops *af_ops;
    2672                 :            : 
    2673                 :            :                         rcu_read_lock();
    2674                 :            : 
    2675         [ -  + ]:        621 :                         BUG_ON(!(af_ops = rtnl_af_lookup(nla_type(af))));
    2676                 :            : 
    2677                 :        621 :                         err = af_ops->set_link_af(dev, af);
    2678         [ -  + ]:        621 :                         if (err < 0) {
    2679                 :            :                                 rcu_read_unlock();
    2680                 :            :                                 goto errout;
    2681                 :            :                         }
    2682                 :            : 
    2683                 :            :                         rcu_read_unlock();
    2684                 :        621 :                         status |= DO_SETLINK_NOTIFY;
    2685                 :            :                 }
    2686                 :            :         }
    2687                 :            :         err = 0;
    2688                 :            : 
    2689         [ -  + ]:       1035 :         if (tb[IFLA_PROTO_DOWN]) {
    2690                 :          0 :                 err = dev_change_proto_down(dev,
    2691                 :            :                                             nla_get_u8(tb[IFLA_PROTO_DOWN]));
    2692         [ #  # ]:          0 :                 if (err)
    2693                 :            :                         goto errout;
    2694                 :          0 :                 status |= DO_SETLINK_NOTIFY;
    2695                 :            :         }
    2696                 :            : 
    2697         [ -  + ]:       1035 :         if (tb[IFLA_XDP]) {
    2698                 :            :                 struct nlattr *xdp[IFLA_XDP_MAX + 1];
    2699                 :            :                 u32 xdp_flags = 0;
    2700                 :            : 
    2701                 :            :                 err = nla_parse_nested_deprecated(xdp, IFLA_XDP_MAX,
    2702                 :            :                                                   tb[IFLA_XDP],
    2703                 :            :                                                   ifla_xdp_policy, NULL);
    2704         [ #  # ]:          0 :                 if (err < 0)
    2705                 :            :                         goto errout;
    2706                 :            : 
    2707   [ #  #  #  # ]:          0 :                 if (xdp[IFLA_XDP_ATTACHED] || xdp[IFLA_XDP_PROG_ID]) {
    2708                 :            :                         err = -EINVAL;
    2709                 :            :                         goto errout;
    2710                 :            :                 }
    2711                 :            : 
    2712         [ #  # ]:          0 :                 if (xdp[IFLA_XDP_FLAGS]) {
    2713                 :            :                         xdp_flags = nla_get_u32(xdp[IFLA_XDP_FLAGS]);
    2714         [ #  # ]:          0 :                         if (xdp_flags & ~XDP_FLAGS_MASK) {
    2715                 :            :                                 err = -EINVAL;
    2716                 :            :                                 goto errout;
    2717                 :            :                         }
    2718   [ #  #  #  # ]:          0 :                         if (hweight32(xdp_flags & XDP_FLAGS_MODES) > 1) {
    2719                 :            :                                 err = -EINVAL;
    2720                 :            :                                 goto errout;
    2721                 :            :                         }
    2722                 :            :                 }
    2723                 :            : 
    2724         [ #  # ]:          0 :                 if (xdp[IFLA_XDP_FD]) {
    2725                 :          0 :                         err = dev_change_xdp_fd(dev, extack,
    2726                 :            :                                                 nla_get_s32(xdp[IFLA_XDP_FD]),
    2727                 :            :                                                 xdp_flags);
    2728         [ #  # ]:          0 :                         if (err)
    2729                 :            :                                 goto errout;
    2730                 :          0 :                         status |= DO_SETLINK_NOTIFY;
    2731                 :            :                 }
    2732                 :            :         }
    2733                 :            : 
    2734                 :            : errout:
    2735         [ +  + ]:       1035 :         if (status & DO_SETLINK_MODIFIED) {
    2736         [ +  - ]:        621 :                 if ((status & DO_SETLINK_NOTIFY) == DO_SETLINK_NOTIFY)
    2737                 :        621 :                         netdev_state_change(dev);
    2738                 :            : 
    2739         [ -  + ]:        621 :                 if (err < 0)
    2740         [ #  # ]:          0 :                         net_warn_ratelimited("A link change request failed with some changes committed already. Interface %s may have been left with an inconsistent configuration, please check.\n",
    2741                 :            :                                              dev->name);
    2742                 :            :         }
    2743                 :            : 
    2744                 :       1035 :         return err;
    2745                 :            : }
    2746                 :            : 
    2747                 :        207 : static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
    2748                 :            :                         struct netlink_ext_ack *extack)
    2749                 :            : {
    2750                 :        207 :         struct net *net = sock_net(skb->sk);
    2751                 :            :         struct ifinfomsg *ifm;
    2752                 :            :         struct net_device *dev;
    2753                 :            :         int err;
    2754                 :            :         struct nlattr *tb[IFLA_MAX+1];
    2755                 :            :         char ifname[IFNAMSIZ];
    2756                 :            : 
    2757                 :            :         err = nlmsg_parse_deprecated(nlh, sizeof(*ifm), tb, IFLA_MAX,
    2758                 :            :                                      ifla_policy, extack);
    2759         [ +  - ]:        207 :         if (err < 0)
    2760                 :            :                 goto errout;
    2761                 :            : 
    2762                 :        207 :         err = rtnl_ensure_unique_netns(tb, extack, false);
    2763         [ +  - ]:        207 :         if (err < 0)
    2764                 :            :                 goto errout;
    2765                 :            : 
    2766         [ -  + ]:        207 :         if (tb[IFLA_IFNAME])
    2767                 :          0 :                 nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
    2768                 :            :         else
    2769                 :        207 :                 ifname[0] = '\0';
    2770                 :            : 
    2771                 :            :         err = -EINVAL;
    2772                 :            :         ifm = nlmsg_data(nlh);
    2773         [ +  - ]:        207 :         if (ifm->ifi_index > 0)
    2774                 :        207 :                 dev = __dev_get_by_index(net, ifm->ifi_index);
    2775         [ #  # ]:          0 :         else if (tb[IFLA_IFNAME])
    2776                 :          0 :                 dev = __dev_get_by_name(net, ifname);
    2777                 :            :         else
    2778                 :            :                 goto errout;
    2779                 :            : 
    2780         [ +  - ]:        207 :         if (dev == NULL) {
    2781                 :            :                 err = -ENODEV;
    2782                 :            :                 goto errout;
    2783                 :            :         }
    2784                 :            : 
    2785                 :        207 :         err = do_setlink(skb, dev, ifm, extack, tb, ifname, 0);
    2786                 :            : errout:
    2787                 :        207 :         return err;
    2788                 :            : }
    2789                 :            : 
    2790                 :          0 : static int rtnl_group_dellink(const struct net *net, int group)
    2791                 :            : {
    2792                 :            :         struct net_device *dev, *aux;
    2793                 :          0 :         LIST_HEAD(list_kill);
    2794                 :            :         bool found = false;
    2795                 :            : 
    2796         [ #  # ]:          0 :         if (!group)
    2797                 :            :                 return -EPERM;
    2798                 :            : 
    2799         [ #  # ]:          0 :         for_each_netdev(net, dev) {
    2800         [ #  # ]:          0 :                 if (dev->group == group) {
    2801                 :            :                         const struct rtnl_link_ops *ops;
    2802                 :            : 
    2803                 :            :                         found = true;
    2804                 :          0 :                         ops = dev->rtnl_link_ops;
    2805   [ #  #  #  # ]:          0 :                         if (!ops || !ops->dellink)
    2806                 :            :                                 return -EOPNOTSUPP;
    2807                 :            :                 }
    2808                 :            :         }
    2809                 :            : 
    2810         [ #  # ]:          0 :         if (!found)
    2811                 :            :                 return -ENODEV;
    2812                 :            : 
    2813         [ #  # ]:          0 :         for_each_netdev_safe(net, dev, aux) {
    2814         [ #  # ]:          0 :                 if (dev->group == group) {
    2815                 :            :                         const struct rtnl_link_ops *ops;
    2816                 :            : 
    2817                 :          0 :                         ops = dev->rtnl_link_ops;
    2818                 :          0 :                         ops->dellink(dev, &list_kill);
    2819                 :            :                 }
    2820                 :            :         }
    2821                 :          0 :         unregister_netdevice_many(&list_kill);
    2822                 :            : 
    2823                 :          0 :         return 0;
    2824                 :            : }
    2825                 :            : 
    2826                 :          0 : int rtnl_delete_link(struct net_device *dev)
    2827                 :            : {
    2828                 :            :         const struct rtnl_link_ops *ops;
    2829                 :          0 :         LIST_HEAD(list_kill);
    2830                 :            : 
    2831                 :          0 :         ops = dev->rtnl_link_ops;
    2832   [ #  #  #  # ]:          0 :         if (!ops || !ops->dellink)
    2833                 :            :                 return -EOPNOTSUPP;
    2834                 :            : 
    2835                 :          0 :         ops->dellink(dev, &list_kill);
    2836                 :          0 :         unregister_netdevice_many(&list_kill);
    2837                 :            : 
    2838                 :          0 :         return 0;
    2839                 :            : }
    2840                 :            : EXPORT_SYMBOL_GPL(rtnl_delete_link);
    2841                 :            : 
    2842                 :          0 : static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh,
    2843                 :            :                         struct netlink_ext_ack *extack)
    2844                 :            : {
    2845                 :          0 :         struct net *net = sock_net(skb->sk);
    2846                 :            :         struct net *tgt_net = net;
    2847                 :            :         struct net_device *dev = NULL;
    2848                 :            :         struct ifinfomsg *ifm;
    2849                 :            :         char ifname[IFNAMSIZ];
    2850                 :            :         struct nlattr *tb[IFLA_MAX+1];
    2851                 :            :         int err;
    2852                 :            :         int netnsid = -1;
    2853                 :            : 
    2854                 :            :         err = nlmsg_parse_deprecated(nlh, sizeof(*ifm), tb, IFLA_MAX,
    2855                 :            :                                      ifla_policy, extack);
    2856         [ #  # ]:          0 :         if (err < 0)
    2857                 :            :                 return err;
    2858                 :            : 
    2859                 :          0 :         err = rtnl_ensure_unique_netns(tb, extack, true);
    2860         [ #  # ]:          0 :         if (err < 0)
    2861                 :            :                 return err;
    2862                 :            : 
    2863         [ #  # ]:          0 :         if (tb[IFLA_IFNAME])
    2864                 :          0 :                 nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
    2865                 :            : 
    2866         [ #  # ]:          0 :         if (tb[IFLA_TARGET_NETNSID]) {
    2867                 :            :                 netnsid = nla_get_s32(tb[IFLA_TARGET_NETNSID]);
    2868                 :          0 :                 tgt_net = rtnl_get_net_ns_capable(NETLINK_CB(skb).sk, netnsid);
    2869         [ #  # ]:          0 :                 if (IS_ERR(tgt_net))
    2870                 :          0 :                         return PTR_ERR(tgt_net);
    2871                 :            :         }
    2872                 :            : 
    2873                 :            :         err = -EINVAL;
    2874                 :            :         ifm = nlmsg_data(nlh);
    2875         [ #  # ]:          0 :         if (ifm->ifi_index > 0)
    2876                 :          0 :                 dev = __dev_get_by_index(tgt_net, ifm->ifi_index);
    2877         [ #  # ]:          0 :         else if (tb[IFLA_IFNAME])
    2878                 :          0 :                 dev = __dev_get_by_name(tgt_net, ifname);
    2879         [ #  # ]:          0 :         else if (tb[IFLA_GROUP])
    2880                 :          0 :                 err = rtnl_group_dellink(tgt_net, nla_get_u32(tb[IFLA_GROUP]));
    2881                 :            :         else
    2882                 :            :                 goto out;
    2883                 :            : 
    2884         [ #  # ]:          0 :         if (!dev) {
    2885   [ #  #  #  # ]:          0 :                 if (tb[IFLA_IFNAME] || ifm->ifi_index > 0)
    2886                 :            :                         err = -ENODEV;
    2887                 :            : 
    2888                 :            :                 goto out;
    2889                 :            :         }
    2890                 :            : 
    2891                 :          0 :         err = rtnl_delete_link(dev);
    2892                 :            : 
    2893                 :            : out:
    2894         [ #  # ]:          0 :         if (netnsid >= 0)
    2895                 :          0 :                 put_net(tgt_net);
    2896                 :            : 
    2897                 :          0 :         return err;
    2898                 :            : }
    2899                 :            : 
    2900                 :          0 : int rtnl_configure_link(struct net_device *dev, const struct ifinfomsg *ifm)
    2901                 :            : {
    2902                 :            :         unsigned int old_flags;
    2903                 :            :         int err;
    2904                 :            : 
    2905                 :          0 :         old_flags = dev->flags;
    2906   [ #  #  #  #  :          0 :         if (ifm && (ifm->ifi_flags || ifm->ifi_change)) {
                   #  # ]
    2907                 :          0 :                 err = __dev_change_flags(dev, rtnl_dev_combine_flags(dev, ifm),
    2908                 :            :                                          NULL);
    2909         [ #  # ]:          0 :                 if (err < 0)
    2910                 :            :                         return err;
    2911                 :            :         }
    2912                 :            : 
    2913         [ #  # ]:          0 :         if (dev->rtnl_link_state == RTNL_LINK_INITIALIZED) {
    2914                 :          0 :                 __dev_notify_flags(dev, old_flags, (old_flags ^ dev->flags));
    2915                 :            :         } else {
    2916                 :          0 :                 dev->rtnl_link_state = RTNL_LINK_INITIALIZED;
    2917                 :          0 :                 __dev_notify_flags(dev, old_flags, ~0U);
    2918                 :            :         }
    2919                 :            :         return 0;
    2920                 :            : }
    2921                 :            : EXPORT_SYMBOL(rtnl_configure_link);
    2922                 :            : 
    2923                 :          0 : struct net_device *rtnl_create_link(struct net *net, const char *ifname,
    2924                 :            :                                     unsigned char name_assign_type,
    2925                 :            :                                     const struct rtnl_link_ops *ops,
    2926                 :            :                                     struct nlattr *tb[],
    2927                 :            :                                     struct netlink_ext_ack *extack)
    2928                 :            : {
    2929                 :            :         struct net_device *dev;
    2930                 :            :         unsigned int num_tx_queues = 1;
    2931                 :            :         unsigned int num_rx_queues = 1;
    2932                 :            : 
    2933         [ #  # ]:          0 :         if (tb[IFLA_NUM_TX_QUEUES])
    2934                 :            :                 num_tx_queues = nla_get_u32(tb[IFLA_NUM_TX_QUEUES]);
    2935         [ #  # ]:          0 :         else if (ops->get_num_tx_queues)
    2936                 :          0 :                 num_tx_queues = ops->get_num_tx_queues();
    2937                 :            : 
    2938         [ #  # ]:          0 :         if (tb[IFLA_NUM_RX_QUEUES])
    2939                 :            :                 num_rx_queues = nla_get_u32(tb[IFLA_NUM_RX_QUEUES]);
    2940         [ #  # ]:          0 :         else if (ops->get_num_rx_queues)
    2941                 :          0 :                 num_rx_queues = ops->get_num_rx_queues();
    2942                 :            : 
    2943         [ #  # ]:          0 :         if (num_tx_queues < 1 || num_tx_queues > 4096) {
    2944         [ #  # ]:          0 :                 NL_SET_ERR_MSG(extack, "Invalid number of transmit queues");
    2945                 :            :                 return ERR_PTR(-EINVAL);
    2946                 :            :         }
    2947                 :            : 
    2948         [ #  # ]:          0 :         if (num_rx_queues < 1 || num_rx_queues > 4096) {
    2949         [ #  # ]:          0 :                 NL_SET_ERR_MSG(extack, "Invalid number of receive queues");
    2950                 :            :                 return ERR_PTR(-EINVAL);
    2951                 :            :         }
    2952                 :            : 
    2953                 :          0 :         dev = alloc_netdev_mqs(ops->priv_size, ifname, name_assign_type,
    2954                 :            :                                ops->setup, num_tx_queues, num_rx_queues);
    2955         [ #  # ]:          0 :         if (!dev)
    2956                 :            :                 return ERR_PTR(-ENOMEM);
    2957                 :            : 
    2958                 :            :         dev_net_set(dev, net);
    2959                 :          0 :         dev->rtnl_link_ops = ops;
    2960                 :          0 :         dev->rtnl_link_state = RTNL_LINK_INITIALIZING;
    2961                 :            : 
    2962         [ #  # ]:          0 :         if (tb[IFLA_MTU]) {
    2963                 :            :                 u32 mtu = nla_get_u32(tb[IFLA_MTU]);
    2964                 :            :                 int err;
    2965                 :            : 
    2966                 :          0 :                 err = dev_validate_mtu(dev, mtu, extack);
    2967         [ #  # ]:          0 :                 if (err) {
    2968                 :          0 :                         free_netdev(dev);
    2969                 :          0 :                         return ERR_PTR(err);
    2970                 :            :                 }
    2971                 :          0 :                 dev->mtu = mtu;
    2972                 :            :         }
    2973         [ #  # ]:          0 :         if (tb[IFLA_ADDRESS]) {
    2974                 :          0 :                 memcpy(dev->dev_addr, nla_data(tb[IFLA_ADDRESS]),
    2975                 :            :                                 nla_len(tb[IFLA_ADDRESS]));
    2976                 :          0 :                 dev->addr_assign_type = NET_ADDR_SET;
    2977                 :            :         }
    2978         [ #  # ]:          0 :         if (tb[IFLA_BROADCAST])
    2979                 :          0 :                 memcpy(dev->broadcast, nla_data(tb[IFLA_BROADCAST]),
    2980                 :            :                                 nla_len(tb[IFLA_BROADCAST]));
    2981         [ #  # ]:          0 :         if (tb[IFLA_TXQLEN])
    2982                 :          0 :                 dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]);
    2983         [ #  # ]:          0 :         if (tb[IFLA_OPERSTATE])
    2984                 :          0 :                 set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]));
    2985         [ #  # ]:          0 :         if (tb[IFLA_LINKMODE])
    2986                 :          0 :                 dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]);
    2987         [ #  # ]:          0 :         if (tb[IFLA_GROUP])
    2988                 :          0 :                 dev_set_group(dev, nla_get_u32(tb[IFLA_GROUP]));
    2989         [ #  # ]:          0 :         if (tb[IFLA_GSO_MAX_SIZE])
    2990                 :            :                 netif_set_gso_max_size(dev, nla_get_u32(tb[IFLA_GSO_MAX_SIZE]));
    2991         [ #  # ]:          0 :         if (tb[IFLA_GSO_MAX_SEGS])
    2992                 :          0 :                 dev->gso_max_segs = nla_get_u32(tb[IFLA_GSO_MAX_SEGS]);
    2993                 :            : 
    2994                 :          0 :         return dev;
    2995                 :            : }
    2996                 :            : EXPORT_SYMBOL(rtnl_create_link);
    2997                 :            : 
    2998                 :          0 : static int rtnl_group_changelink(const struct sk_buff *skb,
    2999                 :            :                 struct net *net, int group,
    3000                 :            :                 struct ifinfomsg *ifm,
    3001                 :            :                 struct netlink_ext_ack *extack,
    3002                 :            :                 struct nlattr **tb)
    3003                 :            : {
    3004                 :            :         struct net_device *dev, *aux;
    3005                 :            :         int err;
    3006                 :            : 
    3007         [ #  # ]:          0 :         for_each_netdev_safe(net, dev, aux) {
    3008         [ #  # ]:          0 :                 if (dev->group == group) {
    3009                 :          0 :                         err = do_setlink(skb, dev, ifm, extack, tb, NULL, 0);
    3010         [ #  # ]:          0 :                         if (err < 0)
    3011                 :          0 :                                 return err;
    3012                 :            :                 }
    3013                 :            :         }
    3014                 :            : 
    3015                 :            :         return 0;
    3016                 :            : }
    3017                 :            : 
    3018                 :       1035 : static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
    3019                 :            :                           struct nlattr **attr, struct netlink_ext_ack *extack)
    3020                 :            : {
    3021                 :            :         struct nlattr *slave_attr[RTNL_SLAVE_MAX_TYPE + 1];
    3022                 :            :         unsigned char name_assign_type = NET_NAME_USER;
    3023                 :            :         struct nlattr *linkinfo[IFLA_INFO_MAX + 1];
    3024                 :            :         const struct rtnl_link_ops *m_ops = NULL;
    3025                 :            :         struct net_device *master_dev = NULL;
    3026                 :       1035 :         struct net *net = sock_net(skb->sk);
    3027                 :            :         const struct rtnl_link_ops *ops;
    3028                 :            :         struct nlattr *tb[IFLA_MAX + 1];
    3029                 :            :         struct net *dest_net, *link_net;
    3030                 :            :         struct nlattr **slave_data;
    3031                 :            :         char kind[MODULE_NAME_LEN];
    3032                 :            :         struct net_device *dev;
    3033                 :            :         struct ifinfomsg *ifm;
    3034                 :            :         char ifname[IFNAMSIZ];
    3035                 :            :         struct nlattr **data;
    3036                 :            :         int err;
    3037                 :            : 
    3038                 :            : #ifdef CONFIG_MODULES
    3039                 :            : replay:
    3040                 :            : #endif
    3041                 :            :         err = nlmsg_parse_deprecated(nlh, sizeof(*ifm), tb, IFLA_MAX,
    3042                 :            :                                      ifla_policy, extack);
    3043         [ -  + ]:       1035 :         if (err < 0)
    3044                 :          0 :                 return err;
    3045                 :            : 
    3046                 :       1035 :         err = rtnl_ensure_unique_netns(tb, extack, false);
    3047         [ -  + ]:       1035 :         if (err < 0)
    3048                 :          0 :                 return err;
    3049                 :            : 
    3050         [ -  + ]:       1035 :         if (tb[IFLA_IFNAME])
    3051                 :          0 :                 nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
    3052                 :            :         else
    3053                 :       1035 :                 ifname[0] = '\0';
    3054                 :            : 
    3055                 :            :         ifm = nlmsg_data(nlh);
    3056         [ +  + ]:       1035 :         if (ifm->ifi_index > 0)
    3057                 :        828 :                 dev = __dev_get_by_index(net, ifm->ifi_index);
    3058                 :            :         else {
    3059         [ -  + ]:        207 :                 if (ifname[0])
    3060                 :          0 :                         dev = __dev_get_by_name(net, ifname);
    3061                 :            :                 else
    3062                 :            :                         dev = NULL;
    3063                 :            :         }
    3064                 :            : 
    3065         [ +  + ]:       1035 :         if (dev) {
    3066                 :        828 :                 master_dev = netdev_master_upper_dev_get(dev);
    3067         [ -  + ]:        828 :                 if (master_dev)
    3068                 :          0 :                         m_ops = master_dev->rtnl_link_ops;
    3069                 :            :         }
    3070                 :            : 
    3071                 :       1035 :         err = validate_linkmsg(dev, tb);
    3072         [ -  + ]:       1035 :         if (err < 0)
    3073                 :          0 :                 return err;
    3074                 :            : 
    3075         [ -  + ]:       1035 :         if (tb[IFLA_LINKINFO]) {
    3076                 :            :                 err = nla_parse_nested_deprecated(linkinfo, IFLA_INFO_MAX,
    3077                 :            :                                                   tb[IFLA_LINKINFO],
    3078                 :            :                                                   ifla_info_policy, NULL);
    3079         [ #  # ]:          0 :                 if (err < 0)
    3080                 :          0 :                         return err;
    3081                 :            :         } else
    3082                 :       1035 :                 memset(linkinfo, 0, sizeof(linkinfo));
    3083                 :            : 
    3084         [ -  + ]:       1035 :         if (linkinfo[IFLA_INFO_KIND]) {
    3085                 :          0 :                 nla_strlcpy(kind, linkinfo[IFLA_INFO_KIND], sizeof(kind));
    3086                 :          0 :                 ops = rtnl_link_ops_get(kind);
    3087                 :            :         } else {
    3088                 :       1035 :                 kind[0] = '\0';
    3089                 :            :                 ops = NULL;
    3090                 :            :         }
    3091                 :            : 
    3092                 :            :         data = NULL;
    3093         [ -  + ]:       1035 :         if (ops) {
    3094         [ #  # ]:          0 :                 if (ops->maxtype > RTNL_MAX_TYPE)
    3095                 :            :                         return -EINVAL;
    3096                 :            : 
    3097   [ #  #  #  # ]:          0 :                 if (ops->maxtype && linkinfo[IFLA_INFO_DATA]) {
    3098                 :          0 :                         err = nla_parse_nested_deprecated(attr, ops->maxtype,
    3099                 :            :                                                           linkinfo[IFLA_INFO_DATA],
    3100                 :            :                                                           ops->policy, extack);
    3101         [ #  # ]:          0 :                         if (err < 0)
    3102                 :          0 :                                 return err;
    3103                 :            :                         data = attr;
    3104                 :            :                 }
    3105         [ #  # ]:          0 :                 if (ops->validate) {
    3106                 :          0 :                         err = ops->validate(tb, data, extack);
    3107         [ #  # ]:          0 :                         if (err < 0)
    3108                 :          0 :                                 return err;
    3109                 :            :                 }
    3110                 :            :         }
    3111                 :            : 
    3112                 :            :         slave_data = NULL;
    3113         [ -  + ]:       1035 :         if (m_ops) {
    3114         [ #  # ]:          0 :                 if (m_ops->slave_maxtype > RTNL_SLAVE_MAX_TYPE)
    3115                 :            :                         return -EINVAL;
    3116                 :            : 
    3117   [ #  #  #  # ]:          0 :                 if (m_ops->slave_maxtype &&
    3118                 :          0 :                     linkinfo[IFLA_INFO_SLAVE_DATA]) {
    3119                 :          0 :                         err = nla_parse_nested_deprecated(slave_attr,
    3120                 :            :                                                           m_ops->slave_maxtype,
    3121                 :            :                                                           linkinfo[IFLA_INFO_SLAVE_DATA],
    3122                 :            :                                                           m_ops->slave_policy,
    3123                 :            :                                                           extack);
    3124         [ #  # ]:          0 :                         if (err < 0)
    3125                 :          0 :                                 return err;
    3126                 :            :                         slave_data = slave_attr;
    3127                 :            :                 }
    3128                 :            :         }
    3129                 :            : 
    3130         [ +  + ]:       1035 :         if (dev) {
    3131                 :            :                 int status = 0;
    3132                 :            : 
    3133         [ +  - ]:        828 :                 if (nlh->nlmsg_flags & NLM_F_EXCL)
    3134                 :            :                         return -EEXIST;
    3135         [ +  - ]:        828 :                 if (nlh->nlmsg_flags & NLM_F_REPLACE)
    3136                 :            :                         return -EOPNOTSUPP;
    3137                 :            : 
    3138         [ -  + ]:        828 :                 if (linkinfo[IFLA_INFO_DATA]) {
    3139   [ #  #  #  #  :          0 :                         if (!ops || ops != dev->rtnl_link_ops ||
                   #  # ]
    3140                 :          0 :                             !ops->changelink)
    3141                 :            :                                 return -EOPNOTSUPP;
    3142                 :            : 
    3143                 :          0 :                         err = ops->changelink(dev, tb, data, extack);
    3144         [ #  # ]:          0 :                         if (err < 0)
    3145                 :            :                                 return err;
    3146                 :            :                         status |= DO_SETLINK_NOTIFY;
    3147                 :            :                 }
    3148                 :            : 
    3149         [ -  + ]:        828 :                 if (linkinfo[IFLA_INFO_SLAVE_DATA]) {
    3150   [ #  #  #  # ]:          0 :                         if (!m_ops || !m_ops->slave_changelink)
    3151                 :            :                                 return -EOPNOTSUPP;
    3152                 :            : 
    3153                 :          0 :                         err = m_ops->slave_changelink(master_dev, dev, tb,
    3154                 :            :                                                       slave_data, extack);
    3155         [ #  # ]:          0 :                         if (err < 0)
    3156                 :            :                                 return err;
    3157                 :            :                         status |= DO_SETLINK_NOTIFY;
    3158                 :            :                 }
    3159                 :            : 
    3160                 :        828 :                 return do_setlink(skb, dev, ifm, extack, tb, ifname, status);
    3161                 :            :         }
    3162                 :            : 
    3163         [ +  - ]:        207 :         if (!(nlh->nlmsg_flags & NLM_F_CREATE)) {
    3164   [ +  -  -  + ]:        207 :                 if (ifm->ifi_index == 0 && tb[IFLA_GROUP])
    3165                 :          0 :                         return rtnl_group_changelink(skb, net,
    3166                 :            :                                                 nla_get_u32(tb[IFLA_GROUP]),
    3167                 :            :                                                 ifm, extack, tb);
    3168                 :            :                 return -ENODEV;
    3169                 :            :         }
    3170                 :            : 
    3171   [ #  #  #  # ]:          0 :         if (tb[IFLA_MAP] || tb[IFLA_PROTINFO])
    3172                 :            :                 return -EOPNOTSUPP;
    3173                 :            : 
    3174         [ #  # ]:          0 :         if (!ops) {
    3175                 :            : #ifdef CONFIG_MODULES
    3176         [ #  # ]:          0 :                 if (kind[0]) {
    3177                 :          0 :                         __rtnl_unlock();
    3178                 :          0 :                         request_module("rtnl-link-%s", kind);
    3179                 :            :                         rtnl_lock();
    3180                 :          0 :                         ops = rtnl_link_ops_get(kind);
    3181         [ #  # ]:          0 :                         if (ops)
    3182                 :            :                                 goto replay;
    3183                 :            :                 }
    3184                 :            : #endif
    3185         [ #  # ]:          0 :                 NL_SET_ERR_MSG(extack, "Unknown device type");
    3186                 :            :                 return -EOPNOTSUPP;
    3187                 :            :         }
    3188                 :            : 
    3189         [ #  # ]:          0 :         if (!ops->setup)
    3190                 :            :                 return -EOPNOTSUPP;
    3191                 :            : 
    3192         [ #  # ]:          0 :         if (!ifname[0]) {
    3193                 :          0 :                 snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind);
    3194                 :            :                 name_assign_type = NET_NAME_ENUM;
    3195                 :            :         }
    3196                 :            : 
    3197                 :          0 :         dest_net = rtnl_link_get_net_capable(skb, net, tb, CAP_NET_ADMIN);
    3198         [ #  # ]:          0 :         if (IS_ERR(dest_net))
    3199                 :          0 :                 return PTR_ERR(dest_net);
    3200                 :            : 
    3201         [ #  # ]:          0 :         if (tb[IFLA_LINK_NETNSID]) {
    3202                 :            :                 int id = nla_get_s32(tb[IFLA_LINK_NETNSID]);
    3203                 :            : 
    3204                 :          0 :                 link_net = get_net_ns_by_id(dest_net, id);
    3205         [ #  # ]:          0 :                 if (!link_net) {
    3206         [ #  # ]:          0 :                         NL_SET_ERR_MSG(extack, "Unknown network namespace id");
    3207                 :            :                         err =  -EINVAL;
    3208                 :            :                         goto out;
    3209                 :            :                 }
    3210                 :            :                 err = -EPERM;
    3211         [ #  # ]:          0 :                 if (!netlink_ns_capable(skb, link_net->user_ns, CAP_NET_ADMIN))
    3212                 :            :                         goto out;
    3213                 :            :         } else {
    3214                 :            :                 link_net = NULL;
    3215                 :            :         }
    3216                 :            : 
    3217         [ #  # ]:          0 :         dev = rtnl_create_link(link_net ? : dest_net, ifname,
    3218                 :            :                                name_assign_type, ops, tb, extack);
    3219         [ #  # ]:          0 :         if (IS_ERR(dev)) {
    3220                 :            :                 err = PTR_ERR(dev);
    3221                 :          0 :                 goto out;
    3222                 :            :         }
    3223                 :            : 
    3224                 :          0 :         dev->ifindex = ifm->ifi_index;
    3225                 :            : 
    3226         [ #  # ]:          0 :         if (ops->newlink) {
    3227         [ #  # ]:          0 :                 err = ops->newlink(link_net ? : net, dev, tb, data, extack);
    3228                 :            :                 /* Drivers should call free_netdev() in ->destructor
    3229                 :            :                  * and unregister it on failure after registration
    3230                 :            :                  * so that device could be finally freed in rtnl_unlock.
    3231                 :            :                  */
    3232         [ #  # ]:          0 :                 if (err < 0) {
    3233                 :            :                         /* If device is not registered at all, free it now */
    3234         [ #  # ]:          0 :                         if (dev->reg_state == NETREG_UNINITIALIZED ||
    3235                 :            :                             dev->reg_state == NETREG_UNREGISTERED)
    3236                 :          0 :                                 free_netdev(dev);
    3237                 :            :                         goto out;
    3238                 :            :                 }
    3239                 :            :         } else {
    3240                 :          0 :                 err = register_netdevice(dev);
    3241         [ #  # ]:          0 :                 if (err < 0) {
    3242                 :          0 :                         free_netdev(dev);
    3243                 :          0 :                         goto out;
    3244                 :            :                 }
    3245                 :            :         }
    3246                 :          0 :         err = rtnl_configure_link(dev, ifm);
    3247         [ #  # ]:          0 :         if (err < 0)
    3248                 :            :                 goto out_unregister;
    3249         [ #  # ]:          0 :         if (link_net) {
    3250                 :          0 :                 err = dev_change_net_namespace(dev, dest_net, ifname);
    3251         [ #  # ]:          0 :                 if (err < 0)
    3252                 :            :                         goto out_unregister;
    3253                 :            :         }
    3254         [ #  # ]:          0 :         if (tb[IFLA_MASTER]) {
    3255                 :          0 :                 err = do_set_master(dev, nla_get_u32(tb[IFLA_MASTER]), extack);
    3256         [ #  # ]:          0 :                 if (err)
    3257                 :            :                         goto out_unregister;
    3258                 :            :         }
    3259                 :            : out:
    3260         [ #  # ]:          0 :         if (link_net)
    3261                 :          0 :                 put_net(link_net);
    3262                 :          0 :         put_net(dest_net);
    3263                 :          0 :         return err;
    3264                 :            : out_unregister:
    3265         [ #  # ]:          0 :         if (ops->newlink) {
    3266                 :          0 :                 LIST_HEAD(list_kill);
    3267                 :            : 
    3268                 :          0 :                 ops->dellink(dev, &list_kill);
    3269                 :          0 :                 unregister_netdevice_many(&list_kill);
    3270                 :            :         } else {
    3271                 :            :                 unregister_netdevice(dev);
    3272                 :            :         }
    3273                 :            :         goto out;
    3274                 :            : }
    3275                 :            : 
    3276                 :       1035 : static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
    3277                 :            :                         struct netlink_ext_ack *extack)
    3278                 :            : {
    3279                 :            :         struct nlattr **attr;
    3280                 :            :         int ret;
    3281                 :            : 
    3282                 :       1035 :         attr = kmalloc_array(RTNL_MAX_TYPE + 1, sizeof(*attr), GFP_KERNEL);
    3283         [ +  - ]:       1035 :         if (!attr)
    3284                 :            :                 return -ENOMEM;
    3285                 :            : 
    3286                 :       1035 :         ret = __rtnl_newlink(skb, nlh, attr, extack);
    3287                 :       1035 :         kfree(attr);
    3288                 :       1035 :         return ret;
    3289                 :            : }
    3290                 :            : 
    3291                 :          0 : static int rtnl_valid_getlink_req(struct sk_buff *skb,
    3292                 :            :                                   const struct nlmsghdr *nlh,
    3293                 :            :                                   struct nlattr **tb,
    3294                 :            :                                   struct netlink_ext_ack *extack)
    3295                 :            : {
    3296                 :            :         struct ifinfomsg *ifm;
    3297                 :            :         int i, err;
    3298                 :            : 
    3299         [ #  # ]:          0 :         if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ifm))) {
    3300         [ #  # ]:          0 :                 NL_SET_ERR_MSG(extack, "Invalid header for get link");
    3301                 :            :                 return -EINVAL;
    3302                 :            :         }
    3303                 :            : 
    3304         [ #  # ]:          0 :         if (!netlink_strict_get_check(skb))
    3305                 :          0 :                 return nlmsg_parse_deprecated(nlh, sizeof(*ifm), tb, IFLA_MAX,
    3306                 :            :                                               ifla_policy, extack);
    3307                 :            : 
    3308                 :            :         ifm = nlmsg_data(nlh);
    3309   [ #  #  #  #  :          0 :         if (ifm->__ifi_pad || ifm->ifi_type || ifm->ifi_flags ||
                   #  # ]
    3310                 :          0 :             ifm->ifi_change) {
    3311         [ #  # ]:          0 :                 NL_SET_ERR_MSG(extack, "Invalid values in header for get link request");
    3312                 :            :                 return -EINVAL;
    3313                 :            :         }
    3314                 :            : 
    3315                 :            :         err = nlmsg_parse_deprecated_strict(nlh, sizeof(*ifm), tb, IFLA_MAX,
    3316                 :            :                                             ifla_policy, extack);
    3317         [ #  # ]:          0 :         if (err)
    3318                 :            :                 return err;
    3319                 :            : 
    3320         [ #  # ]:          0 :         for (i = 0; i <= IFLA_MAX; i++) {
    3321         [ #  # ]:          0 :                 if (!tb[i])
    3322                 :          0 :                         continue;
    3323                 :            : 
    3324         [ #  # ]:          0 :                 switch (i) {
    3325                 :            :                 case IFLA_IFNAME:
    3326                 :            :                 case IFLA_EXT_MASK:
    3327                 :            :                 case IFLA_TARGET_NETNSID:
    3328                 :            :                         break;
    3329                 :            :                 default:
    3330         [ #  # ]:          0 :                         NL_SET_ERR_MSG(extack, "Unsupported attribute in get link request");
    3331                 :            :                         return -EINVAL;
    3332                 :            :                 }
    3333                 :            :         }
    3334                 :            : 
    3335                 :            :         return 0;
    3336                 :            : }
    3337                 :            : 
    3338                 :          0 : static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr *nlh,
    3339                 :            :                         struct netlink_ext_ack *extack)
    3340                 :            : {
    3341                 :          0 :         struct net *net = sock_net(skb->sk);
    3342                 :            :         struct net *tgt_net = net;
    3343                 :            :         struct ifinfomsg *ifm;
    3344                 :            :         char ifname[IFNAMSIZ];
    3345                 :            :         struct nlattr *tb[IFLA_MAX+1];
    3346                 :            :         struct net_device *dev = NULL;
    3347                 :            :         struct sk_buff *nskb;
    3348                 :            :         int netnsid = -1;
    3349                 :            :         int err;
    3350                 :            :         u32 ext_filter_mask = 0;
    3351                 :            : 
    3352                 :          0 :         err = rtnl_valid_getlink_req(skb, nlh, tb, extack);
    3353         [ #  # ]:          0 :         if (err < 0)
    3354                 :            :                 return err;
    3355                 :            : 
    3356                 :          0 :         err = rtnl_ensure_unique_netns(tb, extack, true);
    3357         [ #  # ]:          0 :         if (err < 0)
    3358                 :            :                 return err;
    3359                 :            : 
    3360         [ #  # ]:          0 :         if (tb[IFLA_TARGET_NETNSID]) {
    3361                 :            :                 netnsid = nla_get_s32(tb[IFLA_TARGET_NETNSID]);
    3362                 :          0 :                 tgt_net = rtnl_get_net_ns_capable(NETLINK_CB(skb).sk, netnsid);
    3363         [ #  # ]:          0 :                 if (IS_ERR(tgt_net))
    3364                 :          0 :                         return PTR_ERR(tgt_net);
    3365                 :            :         }
    3366                 :            : 
    3367         [ #  # ]:          0 :         if (tb[IFLA_IFNAME])
    3368                 :          0 :                 nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
    3369                 :            : 
    3370         [ #  # ]:          0 :         if (tb[IFLA_EXT_MASK])
    3371                 :            :                 ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
    3372                 :            : 
    3373                 :            :         err = -EINVAL;
    3374                 :            :         ifm = nlmsg_data(nlh);
    3375         [ #  # ]:          0 :         if (ifm->ifi_index > 0)
    3376                 :          0 :                 dev = __dev_get_by_index(tgt_net, ifm->ifi_index);
    3377         [ #  # ]:          0 :         else if (tb[IFLA_IFNAME])
    3378                 :          0 :                 dev = __dev_get_by_name(tgt_net, ifname);
    3379                 :            :         else
    3380                 :            :                 goto out;
    3381                 :            : 
    3382                 :            :         err = -ENODEV;
    3383         [ #  # ]:          0 :         if (dev == NULL)
    3384                 :            :                 goto out;
    3385                 :            : 
    3386                 :            :         err = -ENOBUFS;
    3387                 :          0 :         nskb = nlmsg_new(if_nlmsg_size(dev, ext_filter_mask), GFP_KERNEL);
    3388         [ #  # ]:          0 :         if (nskb == NULL)
    3389                 :            :                 goto out;
    3390                 :            : 
    3391                 :          0 :         err = rtnl_fill_ifinfo(nskb, dev, net,
    3392                 :            :                                RTM_NEWLINK, NETLINK_CB(skb).portid,
    3393                 :            :                                nlh->nlmsg_seq, 0, 0, ext_filter_mask,
    3394                 :            :                                0, NULL, 0, netnsid, GFP_KERNEL);
    3395         [ #  # ]:          0 :         if (err < 0) {
    3396                 :            :                 /* -EMSGSIZE implies BUG in if_nlmsg_size */
    3397         [ #  # ]:          0 :                 WARN_ON(err == -EMSGSIZE);
    3398                 :          0 :                 kfree_skb(nskb);
    3399                 :            :         } else
    3400                 :          0 :                 err = rtnl_unicast(nskb, net, NETLINK_CB(skb).portid);
    3401                 :            : out:
    3402         [ #  # ]:          0 :         if (netnsid >= 0)
    3403                 :          0 :                 put_net(tgt_net);
    3404                 :            : 
    3405                 :          0 :         return err;
    3406                 :            : }
    3407                 :            : 
    3408                 :       1242 : static u16 rtnl_calcit(struct sk_buff *skb, struct nlmsghdr *nlh)
    3409                 :            : {
    3410                 :       1242 :         struct net *net = sock_net(skb->sk);
    3411                 :            :         struct net_device *dev;
    3412                 :            :         struct nlattr *tb[IFLA_MAX+1];
    3413                 :            :         u32 ext_filter_mask = 0;
    3414                 :            :         u16 min_ifinfo_dump_size = 0;
    3415                 :            :         int hdrlen;
    3416                 :            : 
    3417                 :            :         /* Same kernel<->userspace interface hack as in rtnl_dump_ifinfo. */
    3418         [ -  + ]:       1242 :         hdrlen = nlmsg_len(nlh) < sizeof(struct ifinfomsg) ?
    3419                 :            :                  sizeof(struct rtgenmsg) : sizeof(struct ifinfomsg);
    3420                 :            : 
    3421         [ +  - ]:       1242 :         if (nlmsg_parse_deprecated(nlh, hdrlen, tb, IFLA_MAX, ifla_policy, NULL) >= 0) {
    3422         [ -  + ]:       1242 :                 if (tb[IFLA_EXT_MASK])
    3423                 :            :                         ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
    3424                 :            :         }
    3425                 :            : 
    3426         [ -  + ]:       1242 :         if (!ext_filter_mask)
    3427                 :            :                 return NLMSG_GOODSIZE;
    3428                 :            :         /*
    3429                 :            :          * traverse the list of net devices and compute the minimum
    3430                 :            :          * buffer size based upon the filter mask.
    3431                 :            :          */
    3432                 :            :         rcu_read_lock();
    3433         [ #  # ]:          0 :         for_each_netdev_rcu(net, dev) {
    3434         [ #  # ]:          0 :                 min_ifinfo_dump_size = max_t(u16, min_ifinfo_dump_size,
    3435                 :            :                                              if_nlmsg_size(dev,
    3436                 :            :                                                            ext_filter_mask));
    3437                 :            :         }
    3438                 :            :         rcu_read_unlock();
    3439                 :            : 
    3440                 :          0 :         return nlmsg_total_size(min_ifinfo_dump_size);
    3441                 :            : }
    3442                 :            : 
    3443                 :       3726 : static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb)
    3444                 :            : {
    3445                 :            :         int idx;
    3446                 :       3726 :         int s_idx = cb->family;
    3447                 :       3726 :         int type = cb->nlh->nlmsg_type - RTM_BASE;
    3448                 :            :         int ret = 0;
    3449                 :            : 
    3450         [ +  + ]:       3726 :         if (s_idx == 0)
    3451                 :            :                 s_idx = 1;
    3452                 :            : 
    3453         [ +  + ]:     176364 :         for (idx = 1; idx <= RTNL_FAMILY_MAX; idx++) {
    3454                 :            :                 struct rtnl_link **tab;
    3455                 :            :                 struct rtnl_link *link;
    3456                 :            :                 rtnl_dumpit_func dumpit;
    3457                 :            : 
    3458         [ +  + ]:     175122 :                 if (idx < s_idx || idx == PF_PACKET)
    3459                 :      13662 :                         continue;
    3460                 :            : 
    3461         [ -  + ]:     161460 :                 if (type < 0 || type >= RTM_NR_MSGTYPES)
    3462                 :          0 :                         continue;
    3463                 :            : 
    3464                 :     322920 :                 tab = rcu_dereference_rtnl(rtnl_msg_handlers[idx]);
    3465         [ +  + ]:     161460 :                 if (!tab)
    3466                 :     152766 :                         continue;
    3467                 :            : 
    3468                 :       8694 :                 link = tab[type];
    3469         [ +  + ]:       8694 :                 if (!link)
    3470                 :       3726 :                         continue;
    3471                 :            : 
    3472                 :       4968 :                 dumpit = link->dumpit;
    3473         [ -  + ]:       4968 :                 if (!dumpit)
    3474                 :          0 :                         continue;
    3475                 :            : 
    3476         [ +  + ]:       4968 :                 if (idx > s_idx) {
    3477                 :       2484 :                         memset(&cb->args[0], 0, sizeof(cb->args));
    3478                 :       2484 :                         cb->prev_seq = 0;
    3479                 :       2484 :                         cb->seq = 0;
    3480                 :            :                 }
    3481                 :       4968 :                 ret = dumpit(skb, cb);
    3482         [ +  + ]:       4968 :                 if (ret)
    3483                 :            :                         break;
    3484                 :            :         }
    3485                 :       3726 :         cb->family = idx;
    3486                 :            : 
    3487         [ +  + ]:       3726 :         return skb->len ? : ret;
    3488                 :            : }
    3489                 :            : 
    3490                 :       1656 : struct sk_buff *rtmsg_ifinfo_build_skb(int type, struct net_device *dev,
    3491                 :            :                                        unsigned int change,
    3492                 :            :                                        u32 event, gfp_t flags, int *new_nsid,
    3493                 :            :                                        int new_ifindex)
    3494                 :            : {
    3495                 :            :         struct net *net = dev_net(dev);
    3496                 :            :         struct sk_buff *skb;
    3497                 :            :         int err = -ENOBUFS;
    3498                 :            :         size_t if_info_size;
    3499                 :            : 
    3500                 :       1656 :         skb = nlmsg_new((if_info_size = if_nlmsg_size(dev, 0)), flags);
    3501         [ +  - ]:       1656 :         if (skb == NULL)
    3502                 :            :                 goto errout;
    3503                 :            : 
    3504                 :       1656 :         err = rtnl_fill_ifinfo(skb, dev, dev_net(dev),
    3505                 :            :                                type, 0, 0, change, 0, 0, event,
    3506                 :            :                                new_nsid, new_ifindex, -1, flags);
    3507         [ -  + ]:       1656 :         if (err < 0) {
    3508                 :            :                 /* -EMSGSIZE implies BUG in if_nlmsg_size() */
    3509         [ #  # ]:          0 :                 WARN_ON(err == -EMSGSIZE);
    3510                 :          0 :                 kfree_skb(skb);
    3511                 :          0 :                 goto errout;
    3512                 :            :         }
    3513                 :            :         return skb;
    3514                 :            : errout:
    3515         [ #  # ]:          0 :         if (err < 0)
    3516                 :            :                 rtnl_set_sk_err(net, RTNLGRP_LINK, err);
    3517                 :            :         return NULL;
    3518                 :            : }
    3519                 :            : 
    3520                 :          0 : void rtmsg_ifinfo_send(struct sk_buff *skb, struct net_device *dev, gfp_t flags)
    3521                 :            : {
    3522                 :            :         struct net *net = dev_net(dev);
    3523                 :            : 
    3524                 :            :         rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, flags);
    3525                 :          0 : }
    3526                 :            : 
    3527                 :       1656 : static void rtmsg_ifinfo_event(int type, struct net_device *dev,
    3528                 :            :                                unsigned int change, u32 event,
    3529                 :            :                                gfp_t flags, int *new_nsid, int new_ifindex)
    3530                 :            : {
    3531                 :            :         struct sk_buff *skb;
    3532                 :            : 
    3533         [ +  - ]:       1656 :         if (dev->reg_state != NETREG_REGISTERED)
    3534                 :       1656 :                 return;
    3535                 :            : 
    3536                 :       1656 :         skb = rtmsg_ifinfo_build_skb(type, dev, change, event, flags, new_nsid,
    3537                 :            :                                      new_ifindex);
    3538         [ +  - ]:       1656 :         if (skb)
    3539                 :            :                 rtmsg_ifinfo_send(skb, dev, flags);
    3540                 :            : }
    3541                 :            : 
    3542                 :       1656 : void rtmsg_ifinfo(int type, struct net_device *dev, unsigned int change,
    3543                 :            :                   gfp_t flags)
    3544                 :            : {
    3545                 :       1656 :         rtmsg_ifinfo_event(type, dev, change, rtnl_get_event(0), flags,
    3546                 :            :                            NULL, 0);
    3547                 :       1656 : }
    3548                 :            : 
    3549                 :          0 : void rtmsg_ifinfo_newnet(int type, struct net_device *dev, unsigned int change,
    3550                 :            :                          gfp_t flags, int *new_nsid, int new_ifindex)
    3551                 :            : {
    3552                 :          0 :         rtmsg_ifinfo_event(type, dev, change, rtnl_get_event(0), flags,
    3553                 :            :                            new_nsid, new_ifindex);
    3554                 :          0 : }
    3555                 :            : 
    3556                 :          0 : static int nlmsg_populate_fdb_fill(struct sk_buff *skb,
    3557                 :            :                                    struct net_device *dev,
    3558                 :            :                                    u8 *addr, u16 vid, u32 pid, u32 seq,
    3559                 :            :                                    int type, unsigned int flags,
    3560                 :            :                                    int nlflags, u16 ndm_state)
    3561                 :            : {
    3562                 :            :         struct nlmsghdr *nlh;
    3563                 :            :         struct ndmsg *ndm;
    3564                 :            : 
    3565                 :          0 :         nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndm), nlflags);
    3566         [ #  # ]:          0 :         if (!nlh)
    3567                 :            :                 return -EMSGSIZE;
    3568                 :            : 
    3569                 :            :         ndm = nlmsg_data(nlh);
    3570                 :          0 :         ndm->ndm_family  = AF_BRIDGE;
    3571                 :          0 :         ndm->ndm_pad1         = 0;
    3572                 :          0 :         ndm->ndm_pad2    = 0;
    3573                 :          0 :         ndm->ndm_flags        = flags;
    3574                 :          0 :         ndm->ndm_type         = 0;
    3575                 :          0 :         ndm->ndm_ifindex = dev->ifindex;
    3576                 :          0 :         ndm->ndm_state   = ndm_state;
    3577                 :            : 
    3578         [ #  # ]:          0 :         if (nla_put(skb, NDA_LLADDR, ETH_ALEN, addr))
    3579                 :            :                 goto nla_put_failure;
    3580         [ #  # ]:          0 :         if (vid)
    3581         [ #  # ]:          0 :                 if (nla_put(skb, NDA_VLAN, sizeof(u16), &vid))
    3582                 :            :                         goto nla_put_failure;
    3583                 :            : 
    3584                 :            :         nlmsg_end(skb, nlh);
    3585                 :          0 :         return 0;
    3586                 :            : 
    3587                 :            : nla_put_failure:
    3588                 :            :         nlmsg_cancel(skb, nlh);
    3589                 :          0 :         return -EMSGSIZE;
    3590                 :            : }
    3591                 :            : 
    3592                 :            : static inline size_t rtnl_fdb_nlmsg_size(void)
    3593                 :            : {
    3594                 :            :         return NLMSG_ALIGN(sizeof(struct ndmsg)) +
    3595                 :            :                nla_total_size(ETH_ALEN) +       /* NDA_LLADDR */
    3596                 :            :                nla_total_size(sizeof(u16)) +    /* NDA_VLAN */
    3597                 :            :                0;
    3598                 :            : }
    3599                 :            : 
    3600                 :          0 : static void rtnl_fdb_notify(struct net_device *dev, u8 *addr, u16 vid, int type,
    3601                 :            :                             u16 ndm_state)
    3602                 :            : {
    3603                 :            :         struct net *net = dev_net(dev);
    3604                 :            :         struct sk_buff *skb;
    3605                 :            :         int err = -ENOBUFS;
    3606                 :            : 
    3607                 :            :         skb = nlmsg_new(rtnl_fdb_nlmsg_size(), GFP_ATOMIC);
    3608         [ #  # ]:          0 :         if (!skb)
    3609                 :            :                 goto errout;
    3610                 :            : 
    3611                 :          0 :         err = nlmsg_populate_fdb_fill(skb, dev, addr, vid,
    3612                 :            :                                       0, 0, type, NTF_SELF, 0, ndm_state);
    3613         [ #  # ]:          0 :         if (err < 0) {
    3614                 :          0 :                 kfree_skb(skb);
    3615                 :          0 :                 goto errout;
    3616                 :            :         }
    3617                 :            : 
    3618                 :            :         rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC);
    3619                 :          0 :         return;
    3620                 :            : errout:
    3621                 :            :         rtnl_set_sk_err(net, RTNLGRP_NEIGH, err);
    3622                 :            : }
    3623                 :            : 
    3624                 :            : /*
    3625                 :            :  * ndo_dflt_fdb_add - default netdevice operation to add an FDB entry
    3626                 :            :  */
    3627                 :          0 : int ndo_dflt_fdb_add(struct ndmsg *ndm,
    3628                 :            :                      struct nlattr *tb[],
    3629                 :            :                      struct net_device *dev,
    3630                 :            :                      const unsigned char *addr, u16 vid,
    3631                 :            :                      u16 flags)
    3632                 :            : {
    3633                 :            :         int err = -EINVAL;
    3634                 :            : 
    3635                 :            :         /* If aging addresses are supported device will need to
    3636                 :            :          * implement its own handler for this.
    3637                 :            :          */
    3638   [ #  #  #  # ]:          0 :         if (ndm->ndm_state && !(ndm->ndm_state & NUD_PERMANENT)) {
    3639                 :          0 :                 pr_info("%s: FDB only supports static addresses\n", dev->name);
    3640                 :          0 :                 return err;
    3641                 :            :         }
    3642                 :            : 
    3643         [ #  # ]:          0 :         if (vid) {
    3644                 :          0 :                 pr_info("%s: vlans aren't supported yet for dev_uc|mc_add()\n", dev->name);
    3645                 :          0 :                 return err;
    3646                 :            :         }
    3647                 :            : 
    3648   [ #  #  #  # ]:          0 :         if (is_unicast_ether_addr(addr) || is_link_local_ether_addr(addr))
    3649                 :          0 :                 err = dev_uc_add_excl(dev, addr);
    3650         [ #  # ]:          0 :         else if (is_multicast_ether_addr(addr))
    3651                 :          0 :                 err = dev_mc_add_excl(dev, addr);
    3652                 :            : 
    3653                 :            :         /* Only return duplicate errors if NLM_F_EXCL is set */
    3654   [ #  #  #  # ]:          0 :         if (err == -EEXIST && !(flags & NLM_F_EXCL))
    3655                 :            :                 err = 0;
    3656                 :            : 
    3657                 :          0 :         return err;
    3658                 :            : }
    3659                 :            : EXPORT_SYMBOL(ndo_dflt_fdb_add);
    3660                 :            : 
    3661                 :            : static int fdb_vid_parse(struct nlattr *vlan_attr, u16 *p_vid,
    3662                 :            :                          struct netlink_ext_ack *extack)
    3663                 :            : {
    3664                 :            :         u16 vid = 0;
    3665                 :            : 
    3666   [ #  #  #  #  :          0 :         if (vlan_attr) {
                   #  # ]
    3667   [ #  #  #  #  :          0 :                 if (nla_len(vlan_attr) != sizeof(u16)) {
                   #  # ]
    3668   [ #  #  #  #  :          0 :                         NL_SET_ERR_MSG(extack, "invalid vlan attribute size");
                   #  # ]
    3669                 :            :                         return -EINVAL;
    3670                 :            :                 }
    3671                 :            : 
    3672                 :            :                 vid = nla_get_u16(vlan_attr);
    3673                 :            : 
    3674   [ #  #  #  #  :          0 :                 if (!vid || vid >= VLAN_VID_MASK) {
                   #  # ]
    3675   [ #  #  #  #  :          0 :                         NL_SET_ERR_MSG(extack, "invalid vlan id");
                   #  # ]
    3676                 :            :                         return -EINVAL;
    3677                 :            :                 }
    3678                 :            :         }
    3679                 :          0 :         *p_vid = vid;
    3680                 :            :         return 0;
    3681                 :            : }
    3682                 :            : 
    3683                 :          0 : static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh,
    3684                 :            :                         struct netlink_ext_ack *extack)
    3685                 :            : {
    3686                 :          0 :         struct net *net = sock_net(skb->sk);
    3687                 :            :         struct ndmsg *ndm;
    3688                 :            :         struct nlattr *tb[NDA_MAX+1];
    3689                 :            :         struct net_device *dev;
    3690                 :            :         u8 *addr;
    3691                 :            :         u16 vid;
    3692                 :            :         int err;
    3693                 :            : 
    3694                 :            :         err = nlmsg_parse_deprecated(nlh, sizeof(*ndm), tb, NDA_MAX, NULL,
    3695                 :            :                                      extack);
    3696         [ #  # ]:          0 :         if (err < 0)
    3697                 :            :                 return err;
    3698                 :            : 
    3699                 :            :         ndm = nlmsg_data(nlh);
    3700         [ #  # ]:          0 :         if (ndm->ndm_ifindex == 0) {
    3701         [ #  # ]:          0 :                 NL_SET_ERR_MSG(extack, "invalid ifindex");
    3702                 :            :                 return -EINVAL;
    3703                 :            :         }
    3704                 :            : 
    3705                 :          0 :         dev = __dev_get_by_index(net, ndm->ndm_ifindex);
    3706         [ #  # ]:          0 :         if (dev == NULL) {
    3707         [ #  # ]:          0 :                 NL_SET_ERR_MSG(extack, "unknown ifindex");
    3708                 :            :                 return -ENODEV;
    3709                 :            :         }
    3710                 :            : 
    3711   [ #  #  #  # ]:          0 :         if (!tb[NDA_LLADDR] || nla_len(tb[NDA_LLADDR]) != ETH_ALEN) {
    3712         [ #  # ]:          0 :                 NL_SET_ERR_MSG(extack, "invalid address");
    3713                 :            :                 return -EINVAL;
    3714                 :            :         }
    3715                 :            : 
    3716         [ #  # ]:          0 :         if (dev->type != ARPHRD_ETHER) {
    3717         [ #  # ]:          0 :                 NL_SET_ERR_MSG(extack, "FDB add only supported for Ethernet devices");
    3718                 :            :                 return -EINVAL;
    3719                 :            :         }
    3720                 :            : 
    3721                 :            :         addr = nla_data(tb[NDA_LLADDR]);
    3722                 :            : 
    3723                 :          0 :         err = fdb_vid_parse(tb[NDA_VLAN], &vid, extack);
    3724         [ #  # ]:          0 :         if (err)
    3725                 :            :                 return err;
    3726                 :            : 
    3727                 :            :         err = -EOPNOTSUPP;
    3728                 :            : 
    3729                 :            :         /* Support fdb on master device the net/bridge default case */
    3730   [ #  #  #  #  :          0 :         if ((!ndm->ndm_flags || ndm->ndm_flags & NTF_MASTER) &&
                   #  # ]
    3731                 :          0 :             (dev->priv_flags & IFF_BRIDGE_PORT)) {
    3732                 :          0 :                 struct net_device *br_dev = netdev_master_upper_dev_get(dev);
    3733                 :          0 :                 const struct net_device_ops *ops = br_dev->netdev_ops;
    3734                 :            : 
    3735                 :          0 :                 err = ops->ndo_fdb_add(ndm, tb, dev, addr, vid,
    3736                 :            :                                        nlh->nlmsg_flags, extack);
    3737         [ #  # ]:          0 :                 if (err)
    3738                 :            :                         goto out;
    3739                 :            :                 else
    3740                 :          0 :                         ndm->ndm_flags &= ~NTF_MASTER;
    3741                 :            :         }
    3742                 :            : 
    3743                 :            :         /* Embedded bridge, macvlan, and any other device support */
    3744         [ #  # ]:          0 :         if ((ndm->ndm_flags & NTF_SELF)) {
    3745         [ #  # ]:          0 :                 if (dev->netdev_ops->ndo_fdb_add)
    3746                 :          0 :                         err = dev->netdev_ops->ndo_fdb_add(ndm, tb, dev, addr,
    3747                 :            :                                                            vid,
    3748                 :            :                                                            nlh->nlmsg_flags,
    3749                 :            :                                                            extack);
    3750                 :            :                 else
    3751                 :          0 :                         err = ndo_dflt_fdb_add(ndm, tb, dev, addr, vid,
    3752                 :            :                                                nlh->nlmsg_flags);
    3753                 :            : 
    3754         [ #  # ]:          0 :                 if (!err) {
    3755                 :          0 :                         rtnl_fdb_notify(dev, addr, vid, RTM_NEWNEIGH,
    3756                 :            :                                         ndm->ndm_state);
    3757                 :          0 :                         ndm->ndm_flags &= ~NTF_SELF;
    3758                 :            :                 }
    3759                 :            :         }
    3760                 :            : out:
    3761                 :          0 :         return err;
    3762                 :            : }
    3763                 :            : 
    3764                 :            : /*
    3765                 :            :  * ndo_dflt_fdb_del - default netdevice operation to delete an FDB entry
    3766                 :            :  */
    3767                 :          0 : int ndo_dflt_fdb_del(struct ndmsg *ndm,
    3768                 :            :                      struct nlattr *tb[],
    3769                 :            :                      struct net_device *dev,
    3770                 :            :                      const unsigned char *addr, u16 vid)
    3771                 :            : {
    3772                 :            :         int err = -EINVAL;
    3773                 :            : 
    3774                 :            :         /* If aging addresses are supported device will need to
    3775                 :            :          * implement its own handler for this.
    3776                 :            :          */
    3777         [ #  # ]:          0 :         if (!(ndm->ndm_state & NUD_PERMANENT)) {
    3778                 :          0 :                 pr_info("%s: FDB only supports static addresses\n", dev->name);
    3779                 :          0 :                 return err;
    3780                 :            :         }
    3781                 :            : 
    3782   [ #  #  #  # ]:          0 :         if (is_unicast_ether_addr(addr) || is_link_local_ether_addr(addr))
    3783                 :          0 :                 err = dev_uc_del(dev, addr);
    3784         [ #  # ]:          0 :         else if (is_multicast_ether_addr(addr))
    3785                 :          0 :                 err = dev_mc_del(dev, addr);
    3786                 :            : 
    3787                 :          0 :         return err;
    3788                 :            : }
    3789                 :            : EXPORT_SYMBOL(ndo_dflt_fdb_del);
    3790                 :            : 
    3791                 :          0 : static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh,
    3792                 :            :                         struct netlink_ext_ack *extack)
    3793                 :            : {
    3794                 :          0 :         struct net *net = sock_net(skb->sk);
    3795                 :            :         struct ndmsg *ndm;
    3796                 :            :         struct nlattr *tb[NDA_MAX+1];
    3797                 :            :         struct net_device *dev;
    3798                 :            :         int err = -EINVAL;
    3799                 :            :         __u8 *addr;
    3800                 :            :         u16 vid;
    3801                 :            : 
    3802         [ #  # ]:          0 :         if (!netlink_capable(skb, CAP_NET_ADMIN))
    3803                 :            :                 return -EPERM;
    3804                 :            : 
    3805                 :            :         err = nlmsg_parse_deprecated(nlh, sizeof(*ndm), tb, NDA_MAX, NULL,
    3806                 :            :                                      extack);
    3807         [ #  # ]:          0 :         if (err < 0)
    3808                 :            :                 return err;
    3809                 :            : 
    3810                 :            :         ndm = nlmsg_data(nlh);
    3811         [ #  # ]:          0 :         if (ndm->ndm_ifindex == 0) {
    3812         [ #  # ]:          0 :                 NL_SET_ERR_MSG(extack, "invalid ifindex");
    3813                 :            :                 return -EINVAL;
    3814                 :            :         }
    3815                 :            : 
    3816                 :          0 :         dev = __dev_get_by_index(net, ndm->ndm_ifindex);
    3817         [ #  # ]:          0 :         if (dev == NULL) {
    3818         [ #  # ]:          0 :                 NL_SET_ERR_MSG(extack, "unknown ifindex");
    3819                 :            :                 return -ENODEV;
    3820                 :            :         }
    3821                 :            : 
    3822   [ #  #  #  # ]:          0 :         if (!tb[NDA_LLADDR] || nla_len(tb[NDA_LLADDR]) != ETH_ALEN) {
    3823         [ #  # ]:          0 :                 NL_SET_ERR_MSG(extack, "invalid address");
    3824                 :            :                 return -EINVAL;
    3825                 :            :         }
    3826                 :            : 
    3827         [ #  # ]:          0 :         if (dev->type != ARPHRD_ETHER) {
    3828         [ #  # ]:          0 :                 NL_SET_ERR_MSG(extack, "FDB delete only supported for Ethernet devices");
    3829                 :            :                 return -EINVAL;
    3830                 :            :         }
    3831                 :            : 
    3832                 :            :         addr = nla_data(tb[NDA_LLADDR]);
    3833                 :            : 
    3834                 :          0 :         err = fdb_vid_parse(tb[NDA_VLAN], &vid, extack);
    3835         [ #  # ]:          0 :         if (err)
    3836                 :            :                 return err;
    3837                 :            : 
    3838                 :            :         err = -EOPNOTSUPP;
    3839                 :            : 
    3840                 :            :         /* Support fdb on master device the net/bridge default case */
    3841   [ #  #  #  #  :          0 :         if ((!ndm->ndm_flags || ndm->ndm_flags & NTF_MASTER) &&
                   #  # ]
    3842                 :          0 :             (dev->priv_flags & IFF_BRIDGE_PORT)) {
    3843                 :          0 :                 struct net_device *br_dev = netdev_master_upper_dev_get(dev);
    3844                 :          0 :                 const struct net_device_ops *ops = br_dev->netdev_ops;
    3845                 :            : 
    3846         [ #  # ]:          0 :                 if (ops->ndo_fdb_del)
    3847                 :          0 :                         err = ops->ndo_fdb_del(ndm, tb, dev, addr, vid);
    3848                 :            : 
    3849         [ #  # ]:          0 :                 if (err)
    3850                 :            :                         goto out;
    3851                 :            :                 else
    3852                 :          0 :                         ndm->ndm_flags &= ~NTF_MASTER;
    3853                 :            :         }
    3854                 :            : 
    3855                 :            :         /* Embedded bridge, macvlan, and any other device support */
    3856         [ #  # ]:          0 :         if (ndm->ndm_flags & NTF_SELF) {
    3857         [ #  # ]:          0 :                 if (dev->netdev_ops->ndo_fdb_del)
    3858                 :          0 :                         err = dev->netdev_ops->ndo_fdb_del(ndm, tb, dev, addr,
    3859                 :            :                                                            vid);
    3860                 :            :                 else
    3861                 :          0 :                         err = ndo_dflt_fdb_del(ndm, tb, dev, addr, vid);
    3862                 :            : 
    3863         [ #  # ]:          0 :                 if (!err) {
    3864                 :          0 :                         rtnl_fdb_notify(dev, addr, vid, RTM_DELNEIGH,
    3865                 :            :                                         ndm->ndm_state);
    3866                 :          0 :                         ndm->ndm_flags &= ~NTF_SELF;
    3867                 :            :                 }
    3868                 :            :         }
    3869                 :            : out:
    3870                 :          0 :         return err;
    3871                 :            : }
    3872                 :            : 
    3873                 :          0 : static int nlmsg_populate_fdb(struct sk_buff *skb,
    3874                 :            :                               struct netlink_callback *cb,
    3875                 :            :                               struct net_device *dev,
    3876                 :            :                               int *idx,
    3877                 :            :                               struct netdev_hw_addr_list *list)
    3878                 :            : {
    3879                 :            :         struct netdev_hw_addr *ha;
    3880                 :            :         int err;
    3881                 :            :         u32 portid, seq;
    3882                 :            : 
    3883                 :          0 :         portid = NETLINK_CB(cb->skb).portid;
    3884                 :          0 :         seq = cb->nlh->nlmsg_seq;
    3885                 :            : 
    3886         [ #  # ]:          0 :         list_for_each_entry(ha, &list->list, list) {
    3887         [ #  # ]:          0 :                 if (*idx < cb->args[2])
    3888                 :            :                         goto skip;
    3889                 :            : 
    3890                 :          0 :                 err = nlmsg_populate_fdb_fill(skb, dev, ha->addr, 0,
    3891                 :            :                                               portid, seq,
    3892                 :            :                                               RTM_NEWNEIGH, NTF_SELF,
    3893                 :            :                                               NLM_F_MULTI, NUD_PERMANENT);
    3894         [ #  # ]:          0 :                 if (err < 0)
    3895                 :          0 :                         return err;
    3896                 :            : skip:
    3897                 :          0 :                 *idx += 1;
    3898                 :            :         }
    3899                 :            :         return 0;
    3900                 :            : }
    3901                 :            : 
    3902                 :            : /**
    3903                 :            :  * ndo_dflt_fdb_dump - default netdevice operation to dump an FDB table.
    3904                 :            :  * @skb: socket buffer to store message in
    3905                 :            :  * @cb: netlink callback
    3906                 :            :  * @dev: netdevice
    3907                 :            :  * @filter_dev: ignored
    3908                 :            :  * @idx: the number of FDB table entries dumped is added to *@idx
    3909                 :            :  *
    3910                 :            :  * Default netdevice operation to dump the existing unicast address list.
    3911                 :            :  * Returns number of addresses from list put in skb.
    3912                 :            :  */
    3913                 :          0 : int ndo_dflt_fdb_dump(struct sk_buff *skb,
    3914                 :            :                       struct netlink_callback *cb,
    3915                 :            :                       struct net_device *dev,
    3916                 :            :                       struct net_device *filter_dev,
    3917                 :            :                       int *idx)
    3918                 :            : {
    3919                 :            :         int err;
    3920                 :            : 
    3921         [ #  # ]:          0 :         if (dev->type != ARPHRD_ETHER)
    3922                 :            :                 return -EINVAL;
    3923                 :            : 
    3924                 :            :         netif_addr_lock_bh(dev);
    3925                 :          0 :         err = nlmsg_populate_fdb(skb, cb, dev, idx, &dev->uc);
    3926         [ #  # ]:          0 :         if (err)
    3927                 :            :                 goto out;
    3928                 :          0 :         err = nlmsg_populate_fdb(skb, cb, dev, idx, &dev->mc);
    3929                 :            : out:
    3930                 :            :         netif_addr_unlock_bh(dev);
    3931                 :          0 :         return err;
    3932                 :            : }
    3933                 :            : EXPORT_SYMBOL(ndo_dflt_fdb_dump);
    3934                 :            : 
    3935                 :          0 : static int valid_fdb_dump_strict(const struct nlmsghdr *nlh,
    3936                 :            :                                  int *br_idx, int *brport_idx,
    3937                 :            :                                  struct netlink_ext_ack *extack)
    3938                 :            : {
    3939                 :            :         struct nlattr *tb[NDA_MAX + 1];
    3940                 :            :         struct ndmsg *ndm;
    3941                 :            :         int err, i;
    3942                 :            : 
    3943         [ #  # ]:          0 :         if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ndm))) {
    3944         [ #  # ]:          0 :                 NL_SET_ERR_MSG(extack, "Invalid header for fdb dump request");
    3945                 :            :                 return -EINVAL;
    3946                 :            :         }
    3947                 :            : 
    3948                 :            :         ndm = nlmsg_data(nlh);
    3949         [ #  # ]:          0 :         if (ndm->ndm_pad1  || ndm->ndm_pad2  || ndm->ndm_state ||
    3950         [ #  # ]:          0 :             ndm->ndm_flags || ndm->ndm_type) {
    3951         [ #  # ]:          0 :                 NL_SET_ERR_MSG(extack, "Invalid values in header for fdb dump request");
    3952                 :            :                 return -EINVAL;
    3953                 :            :         }
    3954                 :            : 
    3955                 :            :         err = nlmsg_parse_deprecated_strict(nlh, sizeof(struct ndmsg), tb,
    3956                 :            :                                             NDA_MAX, NULL, extack);
    3957         [ #  # ]:          0 :         if (err < 0)
    3958                 :            :                 return err;
    3959                 :            : 
    3960                 :          0 :         *brport_idx = ndm->ndm_ifindex;
    3961         [ #  # ]:          0 :         for (i = 0; i <= NDA_MAX; ++i) {
    3962         [ #  # ]:          0 :                 if (!tb[i])
    3963                 :          0 :                         continue;
    3964                 :            : 
    3965      [ #  #  # ]:          0 :                 switch (i) {
    3966                 :            :                 case NDA_IFINDEX:
    3967         [ #  # ]:          0 :                         if (nla_len(tb[i]) != sizeof(u32)) {
    3968         [ #  # ]:          0 :                                 NL_SET_ERR_MSG(extack, "Invalid IFINDEX attribute in fdb dump request");
    3969                 :            :                                 return -EINVAL;
    3970                 :            :                         }
    3971                 :          0 :                         *brport_idx = nla_get_u32(tb[NDA_IFINDEX]);
    3972                 :          0 :                         break;
    3973                 :            :                 case NDA_MASTER:
    3974         [ #  # ]:          0 :                         if (nla_len(tb[i]) != sizeof(u32)) {
    3975         [ #  # ]:          0 :                                 NL_SET_ERR_MSG(extack, "Invalid MASTER attribute in fdb dump request");
    3976                 :            :                                 return -EINVAL;
    3977                 :            :                         }
    3978                 :          0 :                         *br_idx = nla_get_u32(tb[NDA_MASTER]);
    3979                 :          0 :                         break;
    3980                 :            :                 default:
    3981         [ #  # ]:          0 :                         NL_SET_ERR_MSG(extack, "Unsupported attribute in fdb dump request");
    3982                 :            :                         return -EINVAL;
    3983                 :            :                 }
    3984                 :            :         }
    3985                 :            : 
    3986                 :            :         return 0;
    3987                 :            : }
    3988                 :            : 
    3989                 :          0 : static int valid_fdb_dump_legacy(const struct nlmsghdr *nlh,
    3990                 :            :                                  int *br_idx, int *brport_idx,
    3991                 :            :                                  struct netlink_ext_ack *extack)
    3992                 :            : {
    3993                 :            :         struct nlattr *tb[IFLA_MAX+1];
    3994                 :            :         int err;
    3995                 :            : 
    3996                 :            :         /* A hack to preserve kernel<->userspace interface.
    3997                 :            :          * Before Linux v4.12 this code accepted ndmsg since iproute2 v3.3.0.
    3998                 :            :          * However, ndmsg is shorter than ifinfomsg thus nlmsg_parse() bails.
    3999                 :            :          * So, check for ndmsg with an optional u32 attribute (not used here).
    4000                 :            :          * Fortunately these sizes don't conflict with the size of ifinfomsg
    4001                 :            :          * with an optional attribute.
    4002                 :            :          */
    4003   [ #  #  #  # ]:          0 :         if (nlmsg_len(nlh) != sizeof(struct ndmsg) &&
    4004                 :            :             (nlmsg_len(nlh) != sizeof(struct ndmsg) +
    4005                 :            :              nla_attr_size(sizeof(u32)))) {
    4006                 :            :                 struct ifinfomsg *ifm;
    4007                 :            : 
    4008                 :            :                 err = nlmsg_parse_deprecated(nlh, sizeof(struct ifinfomsg),
    4009                 :            :                                              tb, IFLA_MAX, ifla_policy,
    4010                 :            :                                              extack);
    4011         [ #  # ]:          0 :                 if (err < 0) {
    4012                 :            :                         return -EINVAL;
    4013         [ #  # ]:          0 :                 } else if (err == 0) {
    4014         [ #  # ]:          0 :                         if (tb[IFLA_MASTER])
    4015                 :          0 :                                 *br_idx = nla_get_u32(tb[IFLA_MASTER]);
    4016                 :            :                 }
    4017                 :            : 
    4018                 :            :                 ifm = nlmsg_data(nlh);
    4019                 :          0 :                 *brport_idx = ifm->ifi_index;
    4020                 :            :         }
    4021                 :            :         return 0;
    4022                 :            : }
    4023                 :            : 
    4024                 :          0 : static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
    4025                 :            : {
    4026                 :            :         struct net_device *dev;
    4027                 :            :         struct net_device *br_dev = NULL;
    4028                 :            :         const struct net_device_ops *ops = NULL;
    4029                 :            :         const struct net_device_ops *cops = NULL;
    4030                 :          0 :         struct net *net = sock_net(skb->sk);
    4031                 :            :         struct hlist_head *head;
    4032                 :          0 :         int brport_idx = 0;
    4033                 :          0 :         int br_idx = 0;
    4034                 :            :         int h, s_h;
    4035                 :            :         int idx = 0, s_idx;
    4036                 :            :         int err = 0;
    4037                 :          0 :         int fidx = 0;
    4038                 :            : 
    4039         [ #  # ]:          0 :         if (cb->strict_check)
    4040                 :          0 :                 err = valid_fdb_dump_strict(cb->nlh, &br_idx, &brport_idx,
    4041                 :            :                                             cb->extack);
    4042                 :            :         else
    4043                 :          0 :                 err = valid_fdb_dump_legacy(cb->nlh, &br_idx, &brport_idx,
    4044                 :            :                                             cb->extack);
    4045         [ #  # ]:          0 :         if (err < 0)
    4046                 :            :                 return err;
    4047                 :            : 
    4048         [ #  # ]:          0 :         if (br_idx) {
    4049                 :          0 :                 br_dev = __dev_get_by_index(net, br_idx);
    4050         [ #  # ]:          0 :                 if (!br_dev)
    4051                 :            :                         return -ENODEV;
    4052                 :            : 
    4053                 :          0 :                 ops = br_dev->netdev_ops;
    4054                 :            :         }
    4055                 :            : 
    4056                 :          0 :         s_h = cb->args[0];
    4057                 :          0 :         s_idx = cb->args[1];
    4058                 :            : 
    4059         [ #  # ]:          0 :         for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
    4060                 :            :                 idx = 0;
    4061                 :          0 :                 head = &net->dev_index_head[h];
    4062   [ #  #  #  #  :          0 :                 hlist_for_each_entry(dev, head, index_hlist) {
                   #  # ]
    4063                 :            : 
    4064   [ #  #  #  # ]:          0 :                         if (brport_idx && (dev->ifindex != brport_idx))
    4065                 :          0 :                                 continue;
    4066                 :            : 
    4067         [ #  # ]:          0 :                         if (!br_idx) { /* user did not specify a specific bridge */
    4068         [ #  # ]:          0 :                                 if (dev->priv_flags & IFF_BRIDGE_PORT) {
    4069                 :          0 :                                         br_dev = netdev_master_upper_dev_get(dev);
    4070                 :          0 :                                         cops = br_dev->netdev_ops;
    4071                 :            :                                 }
    4072                 :            :                         } else {
    4073   [ #  #  #  # ]:          0 :                                 if (dev != br_dev &&
    4074                 :          0 :                                     !(dev->priv_flags & IFF_BRIDGE_PORT))
    4075                 :          0 :                                         continue;
    4076                 :            : 
    4077   [ #  #  #  # ]:          0 :                                 if (br_dev != netdev_master_upper_dev_get(dev) &&
    4078                 :          0 :                                     !(dev->priv_flags & IFF_EBRIDGE))
    4079                 :          0 :                                         continue;
    4080                 :            :                                 cops = ops;
    4081                 :            :                         }
    4082                 :            : 
    4083         [ #  # ]:          0 :                         if (idx < s_idx)
    4084                 :            :                                 goto cont;
    4085                 :            : 
    4086         [ #  # ]:          0 :                         if (dev->priv_flags & IFF_BRIDGE_PORT) {
    4087   [ #  #  #  # ]:          0 :                                 if (cops && cops->ndo_fdb_dump) {
    4088                 :          0 :                                         err = cops->ndo_fdb_dump(skb, cb,
    4089                 :            :                                                                 br_dev, dev,
    4090                 :            :                                                                 &fidx);
    4091         [ #  # ]:          0 :                                         if (err == -EMSGSIZE)
    4092                 :            :                                                 goto out;
    4093                 :            :                                 }
    4094                 :            :                         }
    4095                 :            : 
    4096         [ #  # ]:          0 :                         if (dev->netdev_ops->ndo_fdb_dump)
    4097                 :          0 :                                 err = dev->netdev_ops->ndo_fdb_dump(skb, cb,
    4098                 :            :                                                                     dev, NULL,
    4099                 :            :                                                                     &fidx);
    4100                 :            :                         else
    4101                 :          0 :                                 err = ndo_dflt_fdb_dump(skb, cb, dev, NULL,
    4102                 :            :                                                         &fidx);
    4103         [ #  # ]:          0 :                         if (err == -EMSGSIZE)
    4104                 :            :                                 goto out;
    4105                 :            : 
    4106                 :            :                         cops = NULL;
    4107                 :            : 
    4108                 :            :                         /* reset fdb offset to 0 for rest of the interfaces */
    4109                 :          0 :                         cb->args[2] = 0;
    4110                 :          0 :                         fidx = 0;
    4111                 :            : cont:
    4112                 :          0 :                         idx++;
    4113                 :            :                 }
    4114                 :            :         }
    4115                 :            : 
    4116                 :            : out:
    4117                 :          0 :         cb->args[0] = h;
    4118                 :          0 :         cb->args[1] = idx;
    4119                 :          0 :         cb->args[2] = fidx;
    4120                 :            : 
    4121                 :          0 :         return skb->len;
    4122                 :            : }
    4123                 :            : 
    4124                 :          0 : static int valid_fdb_get_strict(const struct nlmsghdr *nlh,
    4125                 :            :                                 struct nlattr **tb, u8 *ndm_flags,
    4126                 :            :                                 int *br_idx, int *brport_idx, u8 **addr,
    4127                 :            :                                 u16 *vid, struct netlink_ext_ack *extack)
    4128                 :            : {
    4129                 :            :         struct ndmsg *ndm;
    4130                 :            :         int err, i;
    4131                 :            : 
    4132         [ #  # ]:          0 :         if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ndm))) {
    4133         [ #  # ]:          0 :                 NL_SET_ERR_MSG(extack, "Invalid header for fdb get request");
    4134                 :            :                 return -EINVAL;
    4135                 :            :         }
    4136                 :            : 
    4137                 :            :         ndm = nlmsg_data(nlh);
    4138   [ #  #  #  # ]:          0 :         if (ndm->ndm_pad1  || ndm->ndm_pad2  || ndm->ndm_state ||
    4139                 :            :             ndm->ndm_type) {
    4140         [ #  # ]:          0 :                 NL_SET_ERR_MSG(extack, "Invalid values in header for fdb get request");
    4141                 :            :                 return -EINVAL;
    4142                 :            :         }
    4143                 :            : 
    4144         [ #  # ]:          0 :         if (ndm->ndm_flags & ~(NTF_MASTER | NTF_SELF)) {
    4145         [ #  # ]:          0 :                 NL_SET_ERR_MSG(extack, "Invalid flags in header for fdb get request");
    4146                 :            :                 return -EINVAL;
    4147                 :            :         }
    4148                 :            : 
    4149                 :            :         err = nlmsg_parse_deprecated_strict(nlh, sizeof(struct ndmsg), tb,
    4150                 :            :                                             NDA_MAX, nda_policy, extack);
    4151         [ #  # ]:          0 :         if (err < 0)
    4152                 :            :                 return err;
    4153                 :            : 
    4154                 :          0 :         *ndm_flags = ndm->ndm_flags;
    4155                 :          0 :         *brport_idx = ndm->ndm_ifindex;
    4156         [ #  # ]:          0 :         for (i = 0; i <= NDA_MAX; ++i) {
    4157         [ #  # ]:          0 :                 if (!tb[i])
    4158                 :          0 :                         continue;
    4159                 :            : 
    4160   [ #  #  #  #  :          0 :                 switch (i) {
                      # ]
    4161                 :            :                 case NDA_MASTER:
    4162                 :          0 :                         *br_idx = nla_get_u32(tb[i]);
    4163                 :          0 :                         break;
    4164                 :            :                 case NDA_LLADDR:
    4165         [ #  # ]:          0 :                         if (nla_len(tb[i]) != ETH_ALEN) {
    4166         [ #  # ]:          0 :                                 NL_SET_ERR_MSG(extack, "Invalid address in fdb get request");
    4167                 :            :                                 return -EINVAL;
    4168                 :            :                         }
    4169                 :          0 :                         *addr = nla_data(tb[i]);
    4170                 :          0 :                         break;
    4171                 :            :                 case NDA_VLAN:
    4172                 :            :                         err = fdb_vid_parse(tb[i], vid, extack);
    4173         [ #  # ]:          0 :                         if (err)
    4174                 :          0 :                                 return err;
    4175                 :            :                         break;
    4176                 :            :                 case NDA_VNI:
    4177                 :            :                         break;
    4178                 :            :                 default:
    4179         [ #  # ]:          0 :                         NL_SET_ERR_MSG(extack, "Unsupported attribute in fdb get request");
    4180                 :            :                         return -EINVAL;
    4181                 :            :                 }
    4182                 :            :         }
    4183                 :            : 
    4184                 :            :         return 0;
    4185                 :            : }
    4186                 :            : 
    4187                 :          0 : static int rtnl_fdb_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
    4188                 :            :                         struct netlink_ext_ack *extack)
    4189                 :            : {
    4190                 :            :         struct net_device *dev = NULL, *br_dev = NULL;
    4191                 :            :         const struct net_device_ops *ops = NULL;
    4192                 :          0 :         struct net *net = sock_net(in_skb->sk);
    4193                 :            :         struct nlattr *tb[NDA_MAX + 1];
    4194                 :            :         struct sk_buff *skb;
    4195                 :          0 :         int brport_idx = 0;
    4196                 :          0 :         u8 ndm_flags = 0;
    4197                 :          0 :         int br_idx = 0;
    4198                 :          0 :         u8 *addr = NULL;
    4199                 :          0 :         u16 vid = 0;
    4200                 :            :         int err;
    4201                 :            : 
    4202                 :          0 :         err = valid_fdb_get_strict(nlh, tb, &ndm_flags, &br_idx,
    4203                 :            :                                    &brport_idx, &addr, &vid, extack);
    4204         [ #  # ]:          0 :         if (err < 0)
    4205                 :            :                 return err;
    4206                 :            : 
    4207         [ #  # ]:          0 :         if (!addr) {
    4208         [ #  # ]:          0 :                 NL_SET_ERR_MSG(extack, "Missing lookup address for fdb get request");
    4209                 :            :                 return -EINVAL;
    4210                 :            :         }
    4211                 :            : 
    4212         [ #  # ]:          0 :         if (brport_idx) {
    4213                 :          0 :                 dev = __dev_get_by_index(net, brport_idx);
    4214         [ #  # ]:          0 :                 if (!dev) {
    4215         [ #  # ]:          0 :                         NL_SET_ERR_MSG(extack, "Unknown device ifindex");
    4216                 :            :                         return -ENODEV;
    4217                 :            :                 }
    4218                 :            :         }
    4219                 :            : 
    4220         [ #  # ]:          0 :         if (br_idx) {
    4221         [ #  # ]:          0 :                 if (dev) {
    4222         [ #  # ]:          0 :                         NL_SET_ERR_MSG(extack, "Master and device are mutually exclusive");
    4223                 :            :                         return -EINVAL;
    4224                 :            :                 }
    4225                 :            : 
    4226                 :          0 :                 br_dev = __dev_get_by_index(net, br_idx);
    4227         [ #  # ]:          0 :                 if (!br_dev) {
    4228         [ #  # ]:          0 :                         NL_SET_ERR_MSG(extack, "Invalid master ifindex");
    4229                 :            :                         return -EINVAL;
    4230                 :            :                 }
    4231                 :          0 :                 ops = br_dev->netdev_ops;
    4232                 :            :         }
    4233                 :            : 
    4234         [ #  # ]:          0 :         if (dev) {
    4235   [ #  #  #  # ]:          0 :                 if (!ndm_flags || (ndm_flags & NTF_MASTER)) {
    4236         [ #  # ]:          0 :                         if (!(dev->priv_flags & IFF_BRIDGE_PORT)) {
    4237         [ #  # ]:          0 :                                 NL_SET_ERR_MSG(extack, "Device is not a bridge port");
    4238                 :            :                                 return -EINVAL;
    4239                 :            :                         }
    4240                 :          0 :                         br_dev = netdev_master_upper_dev_get(dev);
    4241         [ #  # ]:          0 :                         if (!br_dev) {
    4242         [ #  # ]:          0 :                                 NL_SET_ERR_MSG(extack, "Master of device not found");
    4243                 :            :                                 return -EINVAL;
    4244                 :            :                         }
    4245                 :          0 :                         ops = br_dev->netdev_ops;
    4246                 :            :                 } else {
    4247         [ #  # ]:          0 :                         if (!(ndm_flags & NTF_SELF)) {
    4248         [ #  # ]:          0 :                                 NL_SET_ERR_MSG(extack, "Missing NTF_SELF");
    4249                 :            :                                 return -EINVAL;
    4250                 :            :                         }
    4251                 :          0 :                         ops = dev->netdev_ops;
    4252                 :            :                 }
    4253                 :            :         }
    4254                 :            : 
    4255         [ #  # ]:          0 :         if (!br_dev && !dev) {
    4256         [ #  # ]:          0 :                 NL_SET_ERR_MSG(extack, "No device specified");
    4257                 :            :                 return -ENODEV;
    4258                 :            :         }
    4259                 :            : 
    4260   [ #  #  #  # ]:          0 :         if (!ops || !ops->ndo_fdb_get) {
    4261         [ #  # ]:          0 :                 NL_SET_ERR_MSG(extack, "Fdb get operation not supported by device");
    4262                 :            :                 return -EOPNOTSUPP;
    4263                 :            :         }
    4264                 :            : 
    4265                 :            :         skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
    4266         [ #  # ]:          0 :         if (!skb)
    4267                 :            :                 return -ENOBUFS;
    4268                 :            : 
    4269         [ #  # ]:          0 :         if (br_dev)
    4270                 :            :                 dev = br_dev;
    4271                 :          0 :         err = ops->ndo_fdb_get(skb, tb, dev, addr, vid,
    4272                 :            :                                NETLINK_CB(in_skb).portid,
    4273                 :            :                                nlh->nlmsg_seq, extack);
    4274         [ #  # ]:          0 :         if (err)
    4275                 :            :                 goto out;
    4276                 :            : 
    4277                 :          0 :         return rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid);
    4278                 :            : out:
    4279                 :          0 :         kfree_skb(skb);
    4280                 :          0 :         return err;
    4281                 :            : }
    4282                 :            : 
    4283                 :            : static int brport_nla_put_flag(struct sk_buff *skb, u32 flags, u32 mask,
    4284                 :            :                                unsigned int attrnum, unsigned int flag)
    4285                 :            : {
    4286   [ #  #  #  #  :          0 :         if (mask & flag)
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
    4287                 :          0 :                 return nla_put_u8(skb, attrnum, !!(flags & flag));
    4288                 :            :         return 0;
    4289                 :            : }
    4290                 :            : 
    4291                 :          0 : int ndo_dflt_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
    4292                 :            :                             struct net_device *dev, u16 mode,
    4293                 :            :                             u32 flags, u32 mask, int nlflags,
    4294                 :            :                             u32 filter_mask,
    4295                 :            :                             int (*vlan_fill)(struct sk_buff *skb,
    4296                 :            :                                              struct net_device *dev,
    4297                 :            :                                              u32 filter_mask))
    4298                 :            : {
    4299                 :            :         struct nlmsghdr *nlh;
    4300                 :            :         struct ifinfomsg *ifm;
    4301                 :            :         struct nlattr *br_afspec;
    4302                 :            :         struct nlattr *protinfo;
    4303         [ #  # ]:          0 :         u8 operstate = netif_running(dev) ? dev->operstate : IF_OPER_DOWN;
    4304                 :          0 :         struct net_device *br_dev = netdev_master_upper_dev_get(dev);
    4305                 :            :         int err = 0;
    4306                 :            : 
    4307                 :          0 :         nlh = nlmsg_put(skb, pid, seq, RTM_NEWLINK, sizeof(*ifm), nlflags);
    4308         [ #  # ]:          0 :         if (nlh == NULL)
    4309                 :            :                 return -EMSGSIZE;
    4310                 :            : 
    4311                 :            :         ifm = nlmsg_data(nlh);
    4312                 :          0 :         ifm->ifi_family = AF_BRIDGE;
    4313                 :          0 :         ifm->__ifi_pad = 0;
    4314                 :          0 :         ifm->ifi_type = dev->type;
    4315                 :          0 :         ifm->ifi_index = dev->ifindex;
    4316                 :          0 :         ifm->ifi_flags = dev_get_flags(dev);
    4317                 :          0 :         ifm->ifi_change = 0;
    4318                 :            : 
    4319                 :            : 
    4320   [ #  #  #  # ]:          0 :         if (nla_put_string(skb, IFLA_IFNAME, dev->name) ||
    4321         [ #  # ]:          0 :             nla_put_u32(skb, IFLA_MTU, dev->mtu) ||
    4322         [ #  # ]:          0 :             nla_put_u8(skb, IFLA_OPERSTATE, operstate) ||
    4323         [ #  # ]:          0 :             (br_dev &&
    4324         [ #  # ]:          0 :              nla_put_u32(skb, IFLA_MASTER, br_dev->ifindex)) ||
    4325         [ #  # ]:          0 :             (dev->addr_len &&
    4326         [ #  # ]:          0 :              nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr)) ||
    4327         [ #  # ]:          0 :             (dev->ifindex != dev_get_iflink(dev) &&
    4328                 :          0 :              nla_put_u32(skb, IFLA_LINK, dev_get_iflink(dev))))
    4329                 :            :                 goto nla_put_failure;
    4330                 :            : 
    4331                 :            :         br_afspec = nla_nest_start_noflag(skb, IFLA_AF_SPEC);
    4332         [ #  # ]:          0 :         if (!br_afspec)
    4333                 :            :                 goto nla_put_failure;
    4334                 :            : 
    4335         [ #  # ]:          0 :         if (nla_put_u16(skb, IFLA_BRIDGE_FLAGS, BRIDGE_FLAGS_SELF)) {
    4336                 :            :                 nla_nest_cancel(skb, br_afspec);
    4337                 :            :                 goto nla_put_failure;
    4338                 :            :         }
    4339                 :            : 
    4340         [ #  # ]:          0 :         if (mode != BRIDGE_MODE_UNDEF) {
    4341         [ #  # ]:          0 :                 if (nla_put_u16(skb, IFLA_BRIDGE_MODE, mode)) {
    4342                 :            :                         nla_nest_cancel(skb, br_afspec);
    4343                 :            :                         goto nla_put_failure;
    4344                 :            :                 }
    4345                 :            :         }
    4346         [ #  # ]:          0 :         if (vlan_fill) {
    4347                 :          0 :                 err = vlan_fill(skb, dev, filter_mask);
    4348         [ #  # ]:          0 :                 if (err) {
    4349                 :            :                         nla_nest_cancel(skb, br_afspec);
    4350                 :            :                         goto nla_put_failure;
    4351                 :            :                 }
    4352                 :            :         }
    4353                 :            :         nla_nest_end(skb, br_afspec);
    4354                 :            : 
    4355                 :          0 :         protinfo = nla_nest_start(skb, IFLA_PROTINFO);
    4356         [ #  # ]:          0 :         if (!protinfo)
    4357                 :            :                 goto nla_put_failure;
    4358                 :            : 
    4359         [ #  # ]:          0 :         if (brport_nla_put_flag(skb, flags, mask,
    4360         [ #  # ]:          0 :                                 IFLA_BRPORT_MODE, BR_HAIRPIN_MODE) ||
    4361                 :            :             brport_nla_put_flag(skb, flags, mask,
    4362         [ #  # ]:          0 :                                 IFLA_BRPORT_GUARD, BR_BPDU_GUARD) ||
    4363                 :            :             brport_nla_put_flag(skb, flags, mask,
    4364                 :            :                                 IFLA_BRPORT_FAST_LEAVE,
    4365         [ #  # ]:          0 :                                 BR_MULTICAST_FAST_LEAVE) ||
    4366                 :            :             brport_nla_put_flag(skb, flags, mask,
    4367         [ #  # ]:          0 :                                 IFLA_BRPORT_PROTECT, BR_ROOT_BLOCK) ||
    4368                 :            :             brport_nla_put_flag(skb, flags, mask,
    4369         [ #  # ]:          0 :                                 IFLA_BRPORT_LEARNING, BR_LEARNING) ||
    4370                 :            :             brport_nla_put_flag(skb, flags, mask,
    4371         [ #  # ]:          0 :                                 IFLA_BRPORT_LEARNING_SYNC, BR_LEARNING_SYNC) ||
    4372                 :            :             brport_nla_put_flag(skb, flags, mask,
    4373         [ #  # ]:          0 :                                 IFLA_BRPORT_UNICAST_FLOOD, BR_FLOOD) ||
    4374                 :            :             brport_nla_put_flag(skb, flags, mask,
    4375                 :            :                                 IFLA_BRPORT_PROXYARP, BR_PROXYARP)) {
    4376                 :            :                 nla_nest_cancel(skb, protinfo);
    4377                 :            :                 goto nla_put_failure;
    4378                 :            :         }
    4379                 :            : 
    4380                 :            :         nla_nest_end(skb, protinfo);
    4381                 :            : 
    4382                 :            :         nlmsg_end(skb, nlh);
    4383                 :          0 :         return 0;
    4384                 :            : nla_put_failure:
    4385                 :            :         nlmsg_cancel(skb, nlh);
    4386         [ #  # ]:          0 :         return err ? err : -EMSGSIZE;
    4387                 :            : }
    4388                 :            : EXPORT_SYMBOL_GPL(ndo_dflt_bridge_getlink);
    4389                 :            : 
    4390                 :          0 : static int valid_bridge_getlink_req(const struct nlmsghdr *nlh,
    4391                 :            :                                     bool strict_check, u32 *filter_mask,
    4392                 :            :                                     struct netlink_ext_ack *extack)
    4393                 :            : {
    4394                 :            :         struct nlattr *tb[IFLA_MAX+1];
    4395                 :            :         int err, i;
    4396                 :            : 
    4397         [ #  # ]:          0 :         if (strict_check) {
    4398                 :            :                 struct ifinfomsg *ifm;
    4399                 :            : 
    4400         [ #  # ]:          0 :                 if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ifm))) {
    4401         [ #  # ]:          0 :                         NL_SET_ERR_MSG(extack, "Invalid header for bridge link dump");
    4402                 :            :                         return -EINVAL;
    4403                 :            :                 }
    4404                 :            : 
    4405                 :            :                 ifm = nlmsg_data(nlh);
    4406   [ #  #  #  #  :          0 :                 if (ifm->__ifi_pad || ifm->ifi_type || ifm->ifi_flags ||
                   #  # ]
    4407         [ #  # ]:          0 :                     ifm->ifi_change || ifm->ifi_index) {
    4408         [ #  # ]:          0 :                         NL_SET_ERR_MSG(extack, "Invalid values in header for bridge link dump request");
    4409                 :            :                         return -EINVAL;
    4410                 :            :                 }
    4411                 :            : 
    4412                 :            :                 err = nlmsg_parse_deprecated_strict(nlh,
    4413                 :            :                                                     sizeof(struct ifinfomsg),
    4414                 :            :                                                     tb, IFLA_MAX, ifla_policy,
    4415                 :            :                                                     extack);
    4416                 :            :         } else {
    4417                 :            :                 err = nlmsg_parse_deprecated(nlh, sizeof(struct ifinfomsg),
    4418                 :            :                                              tb, IFLA_MAX, ifla_policy,
    4419                 :            :                                              extack);
    4420                 :            :         }
    4421         [ #  # ]:          0 :         if (err < 0)
    4422                 :            :                 return err;
    4423                 :            : 
    4424                 :            :         /* new attributes should only be added with strict checking */
    4425         [ #  # ]:          0 :         for (i = 0; i <= IFLA_MAX; ++i) {
    4426         [ #  # ]:          0 :                 if (!tb[i])
    4427                 :          0 :                         continue;
    4428                 :            : 
    4429         [ #  # ]:          0 :                 switch (i) {
    4430                 :            :                 case IFLA_EXT_MASK:
    4431                 :          0 :                         *filter_mask = nla_get_u32(tb[i]);
    4432                 :          0 :                         break;
    4433                 :            :                 default:
    4434         [ #  # ]:          0 :                         if (strict_check) {
    4435         [ #  # ]:          0 :                                 NL_SET_ERR_MSG(extack, "Unsupported attribute in bridge link dump request");
    4436                 :            :                                 return -EINVAL;
    4437                 :            :                         }
    4438                 :            :                 }
    4439                 :            :         }
    4440                 :            : 
    4441                 :            :         return 0;
    4442                 :            : }
    4443                 :            : 
    4444                 :          0 : static int rtnl_bridge_getlink(struct sk_buff *skb, struct netlink_callback *cb)
    4445                 :            : {
    4446                 :          0 :         const struct nlmsghdr *nlh = cb->nlh;
    4447                 :          0 :         struct net *net = sock_net(skb->sk);
    4448                 :            :         struct net_device *dev;
    4449                 :            :         int idx = 0;
    4450                 :          0 :         u32 portid = NETLINK_CB(cb->skb).portid;
    4451                 :          0 :         u32 seq = nlh->nlmsg_seq;
    4452                 :          0 :         u32 filter_mask = 0;
    4453                 :            :         int err;
    4454                 :            : 
    4455                 :          0 :         err = valid_bridge_getlink_req(nlh, cb->strict_check, &filter_mask,
    4456                 :            :                                        cb->extack);
    4457   [ #  #  #  # ]:          0 :         if (err < 0 && cb->strict_check)
    4458                 :            :                 return err;
    4459                 :            : 
    4460                 :            :         rcu_read_lock();
    4461         [ #  # ]:          0 :         for_each_netdev_rcu(net, dev) {
    4462                 :          0 :                 const struct net_device_ops *ops = dev->netdev_ops;
    4463                 :          0 :                 struct net_device *br_dev = netdev_master_upper_dev_get(dev);
    4464                 :            : 
    4465   [ #  #  #  # ]:          0 :                 if (br_dev && br_dev->netdev_ops->ndo_bridge_getlink) {
    4466         [ #  # ]:          0 :                         if (idx >= cb->args[0]) {
    4467                 :          0 :                                 err = br_dev->netdev_ops->ndo_bridge_getlink(
    4468                 :            :                                                 skb, portid, seq, dev,
    4469                 :            :                                                 filter_mask, NLM_F_MULTI);
    4470         [ #  # ]:          0 :                                 if (err < 0 && err != -EOPNOTSUPP) {
    4471         [ #  # ]:          0 :                                         if (likely(skb->len))
    4472                 :            :                                                 break;
    4473                 :            : 
    4474                 :            :                                         goto out_err;
    4475                 :            :                                 }
    4476                 :            :                         }
    4477                 :          0 :                         idx++;
    4478                 :            :                 }
    4479                 :            : 
    4480         [ #  # ]:          0 :                 if (ops->ndo_bridge_getlink) {
    4481         [ #  # ]:          0 :                         if (idx >= cb->args[0]) {
    4482                 :          0 :                                 err = ops->ndo_bridge_getlink(skb, portid,
    4483                 :            :                                                               seq, dev,
    4484                 :            :                                                               filter_mask,
    4485                 :            :                                                               NLM_F_MULTI);
    4486         [ #  # ]:          0 :                                 if (err < 0 && err != -EOPNOTSUPP) {
    4487         [ #  # ]:          0 :                                         if (likely(skb->len))
    4488                 :            :                                                 break;
    4489                 :            : 
    4490                 :            :                                         goto out_err;
    4491                 :            :                                 }
    4492                 :            :                         }
    4493                 :          0 :                         idx++;
    4494                 :            :                 }
    4495                 :            :         }
    4496                 :          0 :         err = skb->len;
    4497                 :            : out_err:
    4498                 :            :         rcu_read_unlock();
    4499                 :          0 :         cb->args[0] = idx;
    4500                 :            : 
    4501                 :          0 :         return err;
    4502                 :            : }
    4503                 :            : 
    4504                 :            : static inline size_t bridge_nlmsg_size(void)
    4505                 :            : {
    4506                 :            :         return NLMSG_ALIGN(sizeof(struct ifinfomsg))
    4507                 :            :                 + nla_total_size(IFNAMSIZ)      /* IFLA_IFNAME */
    4508                 :            :                 + nla_total_size(MAX_ADDR_LEN)  /* IFLA_ADDRESS */
    4509                 :            :                 + nla_total_size(sizeof(u32))   /* IFLA_MASTER */
    4510                 :            :                 + nla_total_size(sizeof(u32))   /* IFLA_MTU */
    4511                 :            :                 + nla_total_size(sizeof(u32))   /* IFLA_LINK */
    4512                 :            :                 + nla_total_size(sizeof(u32))   /* IFLA_OPERSTATE */
    4513                 :            :                 + nla_total_size(sizeof(u8))    /* IFLA_PROTINFO */
    4514                 :            :                 + nla_total_size(sizeof(struct nlattr)) /* IFLA_AF_SPEC */
    4515                 :            :                 + nla_total_size(sizeof(u16))   /* IFLA_BRIDGE_FLAGS */
    4516                 :            :                 + nla_total_size(sizeof(u16));  /* IFLA_BRIDGE_MODE */
    4517                 :            : }
    4518                 :            : 
    4519                 :          0 : static int rtnl_bridge_notify(struct net_device *dev)
    4520                 :            : {
    4521                 :            :         struct net *net = dev_net(dev);
    4522                 :            :         struct sk_buff *skb;
    4523                 :            :         int err = -EOPNOTSUPP;
    4524                 :            : 
    4525         [ #  # ]:          0 :         if (!dev->netdev_ops->ndo_bridge_getlink)
    4526                 :            :                 return 0;
    4527                 :            : 
    4528                 :            :         skb = nlmsg_new(bridge_nlmsg_size(), GFP_ATOMIC);
    4529         [ #  # ]:          0 :         if (!skb) {
    4530                 :            :                 err = -ENOMEM;
    4531                 :            :                 goto errout;
    4532                 :            :         }
    4533                 :            : 
    4534                 :          0 :         err = dev->netdev_ops->ndo_bridge_getlink(skb, 0, 0, dev, 0, 0);
    4535         [ #  # ]:          0 :         if (err < 0)
    4536                 :            :                 goto errout;
    4537                 :            : 
    4538         [ #  # ]:          0 :         if (!skb->len)
    4539                 :            :                 goto errout;
    4540                 :            : 
    4541                 :            :         rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
    4542                 :          0 :         return 0;
    4543                 :            : errout:
    4544         [ #  # ]:          0 :         WARN_ON(err == -EMSGSIZE);
    4545                 :          0 :         kfree_skb(skb);
    4546         [ #  # ]:          0 :         if (err)
    4547                 :            :                 rtnl_set_sk_err(net, RTNLGRP_LINK, err);
    4548                 :          0 :         return err;
    4549                 :            : }
    4550                 :            : 
    4551                 :          0 : static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
    4552                 :            :                                struct netlink_ext_ack *extack)
    4553                 :            : {
    4554                 :          0 :         struct net *net = sock_net(skb->sk);
    4555                 :            :         struct ifinfomsg *ifm;
    4556                 :            :         struct net_device *dev;
    4557                 :            :         struct nlattr *br_spec, *attr = NULL;
    4558                 :            :         int rem, err = -EOPNOTSUPP;
    4559                 :          0 :         u16 flags = 0;
    4560                 :            :         bool have_flags = false;
    4561                 :            : 
    4562         [ #  # ]:          0 :         if (nlmsg_len(nlh) < sizeof(*ifm))
    4563                 :            :                 return -EINVAL;
    4564                 :            : 
    4565                 :            :         ifm = nlmsg_data(nlh);
    4566         [ #  # ]:          0 :         if (ifm->ifi_family != AF_BRIDGE)
    4567                 :            :                 return -EPFNOSUPPORT;
    4568                 :            : 
    4569                 :          0 :         dev = __dev_get_by_index(net, ifm->ifi_index);
    4570         [ #  # ]:          0 :         if (!dev) {
    4571         [ #  # ]:          0 :                 NL_SET_ERR_MSG(extack, "unknown ifindex");
    4572                 :            :                 return -ENODEV;
    4573                 :            :         }
    4574                 :            : 
    4575                 :          0 :         br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
    4576         [ #  # ]:          0 :         if (br_spec) {
    4577         [ #  # ]:          0 :                 nla_for_each_nested(attr, br_spec, rem) {
    4578         [ #  # ]:          0 :                         if (nla_type(attr) == IFLA_BRIDGE_FLAGS) {
    4579         [ #  # ]:          0 :                                 if (nla_len(attr) < sizeof(flags))
    4580                 :            :                                         return -EINVAL;
    4581                 :            : 
    4582                 :            :                                 have_flags = true;
    4583                 :          0 :                                 flags = nla_get_u16(attr);
    4584                 :          0 :                                 break;
    4585                 :            :                         }
    4586                 :            :                 }
    4587                 :            :         }
    4588                 :            : 
    4589   [ #  #  #  # ]:          0 :         if (!flags || (flags & BRIDGE_FLAGS_MASTER)) {
    4590                 :          0 :                 struct net_device *br_dev = netdev_master_upper_dev_get(dev);
    4591                 :            : 
    4592   [ #  #  #  # ]:          0 :                 if (!br_dev || !br_dev->netdev_ops->ndo_bridge_setlink) {
    4593                 :            :                         err = -EOPNOTSUPP;
    4594                 :            :                         goto out;
    4595                 :            :                 }
    4596                 :            : 
    4597                 :          0 :                 err = br_dev->netdev_ops->ndo_bridge_setlink(dev, nlh, flags,
    4598                 :            :                                                              extack);
    4599         [ #  # ]:          0 :                 if (err)
    4600                 :            :                         goto out;
    4601                 :            : 
    4602                 :          0 :                 flags &= ~BRIDGE_FLAGS_MASTER;
    4603                 :            :         }
    4604                 :            : 
    4605         [ #  # ]:          0 :         if ((flags & BRIDGE_FLAGS_SELF)) {
    4606         [ #  # ]:          0 :                 if (!dev->netdev_ops->ndo_bridge_setlink)
    4607                 :            :                         err = -EOPNOTSUPP;
    4608                 :            :                 else
    4609                 :          0 :                         err = dev->netdev_ops->ndo_bridge_setlink(dev, nlh,
    4610                 :            :                                                                   flags,
    4611                 :            :                                                                   extack);
    4612         [ #  # ]:          0 :                 if (!err) {
    4613                 :          0 :                         flags &= ~BRIDGE_FLAGS_SELF;
    4614                 :            : 
    4615                 :            :                         /* Generate event to notify upper layer of bridge
    4616                 :            :                          * change
    4617                 :            :                          */
    4618                 :          0 :                         err = rtnl_bridge_notify(dev);
    4619                 :            :                 }
    4620                 :            :         }
    4621                 :            : 
    4622         [ #  # ]:          0 :         if (have_flags)
    4623                 :          0 :                 memcpy(nla_data(attr), &flags, sizeof(flags));
    4624                 :            : out:
    4625                 :          0 :         return err;
    4626                 :            : }
    4627                 :            : 
    4628                 :          0 : static int rtnl_bridge_dellink(struct sk_buff *skb, struct nlmsghdr *nlh,
    4629                 :            :                                struct netlink_ext_ack *extack)
    4630                 :            : {
    4631                 :          0 :         struct net *net = sock_net(skb->sk);
    4632                 :            :         struct ifinfomsg *ifm;
    4633                 :            :         struct net_device *dev;
    4634                 :            :         struct nlattr *br_spec, *attr = NULL;
    4635                 :            :         int rem, err = -EOPNOTSUPP;
    4636                 :          0 :         u16 flags = 0;
    4637                 :            :         bool have_flags = false;
    4638                 :            : 
    4639         [ #  # ]:          0 :         if (nlmsg_len(nlh) < sizeof(*ifm))
    4640                 :            :                 return -EINVAL;
    4641                 :            : 
    4642                 :            :         ifm = nlmsg_data(nlh);
    4643         [ #  # ]:          0 :         if (ifm->ifi_family != AF_BRIDGE)
    4644                 :            :                 return -EPFNOSUPPORT;
    4645                 :            : 
    4646                 :          0 :         dev = __dev_get_by_index(net, ifm->ifi_index);
    4647         [ #  # ]:          0 :         if (!dev) {
    4648         [ #  # ]:          0 :                 NL_SET_ERR_MSG(extack, "unknown ifindex");
    4649                 :            :                 return -ENODEV;
    4650                 :            :         }
    4651                 :            : 
    4652                 :          0 :         br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
    4653         [ #  # ]:          0 :         if (br_spec) {
    4654         [ #  # ]:          0 :                 nla_for_each_nested(attr, br_spec, rem) {
    4655         [ #  # ]:          0 :                         if (nla_type(attr) == IFLA_BRIDGE_FLAGS) {
    4656         [ #  # ]:          0 :                                 if (nla_len(attr) < sizeof(flags))
    4657                 :            :                                         return -EINVAL;
    4658                 :            : 
    4659                 :            :                                 have_flags = true;
    4660                 :          0 :                                 flags = nla_get_u16(attr);
    4661                 :          0 :                                 break;
    4662                 :            :                         }
    4663                 :            :                 }
    4664                 :            :         }
    4665                 :            : 
    4666   [ #  #  #  # ]:          0 :         if (!flags || (flags & BRIDGE_FLAGS_MASTER)) {
    4667                 :          0 :                 struct net_device *br_dev = netdev_master_upper_dev_get(dev);
    4668                 :            : 
    4669   [ #  #  #  # ]:          0 :                 if (!br_dev || !br_dev->netdev_ops->ndo_bridge_dellink) {
    4670                 :            :                         err = -EOPNOTSUPP;
    4671                 :            :                         goto out;
    4672                 :            :                 }
    4673                 :            : 
    4674                 :          0 :                 err = br_dev->netdev_ops->ndo_bridge_dellink(dev, nlh, flags);
    4675         [ #  # ]:          0 :                 if (err)
    4676                 :            :                         goto out;
    4677                 :            : 
    4678                 :          0 :                 flags &= ~BRIDGE_FLAGS_MASTER;
    4679                 :            :         }
    4680                 :            : 
    4681         [ #  # ]:          0 :         if ((flags & BRIDGE_FLAGS_SELF)) {
    4682         [ #  # ]:          0 :                 if (!dev->netdev_ops->ndo_bridge_dellink)
    4683                 :            :                         err = -EOPNOTSUPP;
    4684                 :            :                 else
    4685                 :          0 :                         err = dev->netdev_ops->ndo_bridge_dellink(dev, nlh,
    4686                 :            :                                                                   flags);
    4687                 :            : 
    4688         [ #  # ]:          0 :                 if (!err) {
    4689                 :          0 :                         flags &= ~BRIDGE_FLAGS_SELF;
    4690                 :            : 
    4691                 :            :                         /* Generate event to notify upper layer of bridge
    4692                 :            :                          * change
    4693                 :            :                          */
    4694                 :          0 :                         err = rtnl_bridge_notify(dev);
    4695                 :            :                 }
    4696                 :            :         }
    4697                 :            : 
    4698         [ #  # ]:          0 :         if (have_flags)
    4699                 :          0 :                 memcpy(nla_data(attr), &flags, sizeof(flags));
    4700                 :            : out:
    4701                 :          0 :         return err;
    4702                 :            : }
    4703                 :            : 
    4704                 :            : static bool stats_attr_valid(unsigned int mask, int attrid, int idxattr)
    4705                 :            : {
    4706   [ #  #  #  #  :          0 :         return (mask & IFLA_STATS_FILTER_BIT(attrid)) &&
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
    4707                 :          0 :                (!idxattr || idxattr == attrid);
    4708                 :            : }
    4709                 :            : 
    4710                 :            : #define IFLA_OFFLOAD_XSTATS_FIRST (IFLA_OFFLOAD_XSTATS_UNSPEC + 1)
    4711                 :            : static int rtnl_get_offload_stats_attr_size(int attr_id)
    4712                 :            : {
    4713   [ #  #  #  # ]:          0 :         switch (attr_id) {
    4714                 :            :         case IFLA_OFFLOAD_XSTATS_CPU_HIT:
    4715                 :            :                 return sizeof(struct rtnl_link_stats64);
    4716                 :            :         }
    4717                 :            : 
    4718                 :            :         return 0;
    4719                 :            : }
    4720                 :            : 
    4721                 :          0 : static int rtnl_get_offload_stats(struct sk_buff *skb, struct net_device *dev,
    4722                 :            :                                   int *prividx)
    4723                 :            : {
    4724                 :            :         struct nlattr *attr = NULL;
    4725                 :            :         int attr_id, size;
    4726                 :            :         void *attr_data;
    4727                 :            :         int err;
    4728                 :            : 
    4729   [ #  #  #  #  :          0 :         if (!(dev->netdev_ops && dev->netdev_ops->ndo_has_offload_stats &&
                   #  # ]
    4730                 :          0 :               dev->netdev_ops->ndo_get_offload_stats))
    4731                 :            :                 return -ENODATA;
    4732                 :            : 
    4733         [ #  # ]:          0 :         for (attr_id = IFLA_OFFLOAD_XSTATS_FIRST;
    4734                 :          0 :              attr_id <= IFLA_OFFLOAD_XSTATS_MAX; attr_id++) {
    4735         [ #  # ]:          0 :                 if (attr_id < *prividx)
    4736                 :          0 :                         continue;
    4737                 :            : 
    4738                 :            :                 size = rtnl_get_offload_stats_attr_size(attr_id);
    4739         [ #  # ]:          0 :                 if (!size)
    4740                 :          0 :                         continue;
    4741                 :            : 
    4742         [ #  # ]:          0 :                 if (!dev->netdev_ops->ndo_has_offload_stats(dev, attr_id))
    4743                 :          0 :                         continue;
    4744                 :            : 
    4745                 :          0 :                 attr = nla_reserve_64bit(skb, attr_id, size,
    4746                 :            :                                          IFLA_OFFLOAD_XSTATS_UNSPEC);
    4747         [ #  # ]:          0 :                 if (!attr)
    4748                 :            :                         goto nla_put_failure;
    4749                 :            : 
    4750                 :            :                 attr_data = nla_data(attr);
    4751                 :          0 :                 memset(attr_data, 0, size);
    4752                 :          0 :                 err = dev->netdev_ops->ndo_get_offload_stats(attr_id, dev,
    4753                 :            :                                                              attr_data);
    4754         [ #  # ]:          0 :                 if (err)
    4755                 :            :                         goto get_offload_stats_failure;
    4756                 :            :         }
    4757                 :            : 
    4758         [ #  # ]:          0 :         if (!attr)
    4759                 :            :                 return -ENODATA;
    4760                 :            : 
    4761                 :          0 :         *prividx = 0;
    4762                 :          0 :         return 0;
    4763                 :            : 
    4764                 :            : nla_put_failure:
    4765                 :            :         err = -EMSGSIZE;
    4766                 :            : get_offload_stats_failure:
    4767                 :          0 :         *prividx = attr_id;
    4768                 :          0 :         return err;
    4769                 :            : }
    4770                 :            : 
    4771                 :          0 : static int rtnl_get_offload_stats_size(const struct net_device *dev)
    4772                 :            : {
    4773                 :            :         int nla_size = 0;
    4774                 :            :         int attr_id;
    4775                 :            :         int size;
    4776                 :            : 
    4777   [ #  #  #  #  :          0 :         if (!(dev->netdev_ops && dev->netdev_ops->ndo_has_offload_stats &&
                   #  # ]
    4778                 :          0 :               dev->netdev_ops->ndo_get_offload_stats))
    4779                 :            :                 return 0;
    4780                 :            : 
    4781         [ #  # ]:          0 :         for (attr_id = IFLA_OFFLOAD_XSTATS_FIRST;
    4782                 :          0 :              attr_id <= IFLA_OFFLOAD_XSTATS_MAX; attr_id++) {
    4783         [ #  # ]:          0 :                 if (!dev->netdev_ops->ndo_has_offload_stats(dev, attr_id))
    4784                 :          0 :                         continue;
    4785                 :            :                 size = rtnl_get_offload_stats_attr_size(attr_id);
    4786                 :          0 :                 nla_size += nla_total_size_64bit(size);
    4787                 :            :         }
    4788                 :            : 
    4789         [ #  # ]:          0 :         if (nla_size != 0)
    4790                 :          0 :                 nla_size += nla_total_size(0);
    4791                 :            : 
    4792                 :          0 :         return nla_size;
    4793                 :            : }
    4794                 :            : 
    4795                 :          0 : static int rtnl_fill_statsinfo(struct sk_buff *skb, struct net_device *dev,
    4796                 :            :                                int type, u32 pid, u32 seq, u32 change,
    4797                 :            :                                unsigned int flags, unsigned int filter_mask,
    4798                 :            :                                int *idxattr, int *prividx)
    4799                 :            : {
    4800                 :            :         struct if_stats_msg *ifsm;
    4801                 :            :         struct nlmsghdr *nlh;
    4802                 :            :         struct nlattr *attr;
    4803                 :          0 :         int s_prividx = *prividx;
    4804                 :            :         int err;
    4805                 :            : 
    4806   [ #  #  #  # ]:          0 :         ASSERT_RTNL();
    4807                 :            : 
    4808                 :          0 :         nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifsm), flags);
    4809         [ #  # ]:          0 :         if (!nlh)
    4810                 :            :                 return -EMSGSIZE;
    4811                 :            : 
    4812                 :            :         ifsm = nlmsg_data(nlh);
    4813                 :          0 :         ifsm->family = PF_UNSPEC;
    4814                 :          0 :         ifsm->pad1 = 0;
    4815                 :          0 :         ifsm->pad2 = 0;
    4816                 :          0 :         ifsm->ifindex = dev->ifindex;
    4817                 :          0 :         ifsm->filter_mask = filter_mask;
    4818                 :            : 
    4819         [ #  # ]:          0 :         if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_64, *idxattr)) {
    4820                 :            :                 struct rtnl_link_stats64 *sp;
    4821                 :            : 
    4822                 :          0 :                 attr = nla_reserve_64bit(skb, IFLA_STATS_LINK_64,
    4823                 :            :                                          sizeof(struct rtnl_link_stats64),
    4824                 :            :                                          IFLA_STATS_UNSPEC);
    4825         [ #  # ]:          0 :                 if (!attr)
    4826                 :            :                         goto nla_put_failure;
    4827                 :            : 
    4828                 :            :                 sp = nla_data(attr);
    4829                 :          0 :                 dev_get_stats(dev, sp);
    4830                 :            :         }
    4831                 :            : 
    4832         [ #  # ]:          0 :         if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_XSTATS, *idxattr)) {
    4833                 :          0 :                 const struct rtnl_link_ops *ops = dev->rtnl_link_ops;
    4834                 :            : 
    4835   [ #  #  #  # ]:          0 :                 if (ops && ops->fill_linkxstats) {
    4836                 :          0 :                         *idxattr = IFLA_STATS_LINK_XSTATS;
    4837                 :            :                         attr = nla_nest_start_noflag(skb,
    4838                 :            :                                                      IFLA_STATS_LINK_XSTATS);
    4839         [ #  # ]:          0 :                         if (!attr)
    4840                 :            :                                 goto nla_put_failure;
    4841                 :            : 
    4842                 :          0 :                         err = ops->fill_linkxstats(skb, dev, prividx, *idxattr);
    4843                 :            :                         nla_nest_end(skb, attr);
    4844         [ #  # ]:          0 :                         if (err)
    4845                 :            :                                 goto nla_put_failure;
    4846                 :          0 :                         *idxattr = 0;
    4847                 :            :                 }
    4848                 :            :         }
    4849                 :            : 
    4850         [ #  # ]:          0 :         if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_XSTATS_SLAVE,
    4851                 :            :                              *idxattr)) {
    4852                 :            :                 const struct rtnl_link_ops *ops = NULL;
    4853                 :            :                 const struct net_device *master;
    4854                 :            : 
    4855                 :          0 :                 master = netdev_master_upper_dev_get(dev);
    4856         [ #  # ]:          0 :                 if (master)
    4857                 :          0 :                         ops = master->rtnl_link_ops;
    4858   [ #  #  #  # ]:          0 :                 if (ops && ops->fill_linkxstats) {
    4859                 :          0 :                         *idxattr = IFLA_STATS_LINK_XSTATS_SLAVE;
    4860                 :            :                         attr = nla_nest_start_noflag(skb,
    4861                 :            :                                                      IFLA_STATS_LINK_XSTATS_SLAVE);
    4862         [ #  # ]:          0 :                         if (!attr)
    4863                 :            :                                 goto nla_put_failure;
    4864                 :            : 
    4865                 :          0 :                         err = ops->fill_linkxstats(skb, dev, prividx, *idxattr);
    4866                 :            :                         nla_nest_end(skb, attr);
    4867         [ #  # ]:          0 :                         if (err)
    4868                 :            :                                 goto nla_put_failure;
    4869                 :          0 :                         *idxattr = 0;
    4870                 :            :                 }
    4871                 :            :         }
    4872                 :            : 
    4873         [ #  # ]:          0 :         if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_OFFLOAD_XSTATS,
    4874                 :            :                              *idxattr)) {
    4875                 :          0 :                 *idxattr = IFLA_STATS_LINK_OFFLOAD_XSTATS;
    4876                 :            :                 attr = nla_nest_start_noflag(skb,
    4877                 :            :                                              IFLA_STATS_LINK_OFFLOAD_XSTATS);
    4878         [ #  # ]:          0 :                 if (!attr)
    4879                 :            :                         goto nla_put_failure;
    4880                 :            : 
    4881                 :          0 :                 err = rtnl_get_offload_stats(skb, dev, prividx);
    4882         [ #  # ]:          0 :                 if (err == -ENODATA)
    4883                 :            :                         nla_nest_cancel(skb, attr);
    4884                 :            :                 else
    4885                 :            :                         nla_nest_end(skb, attr);
    4886                 :            : 
    4887         [ #  # ]:          0 :                 if (err && err != -ENODATA)
    4888                 :            :                         goto nla_put_failure;
    4889                 :          0 :                 *idxattr = 0;
    4890                 :            :         }
    4891                 :            : 
    4892         [ #  # ]:          0 :         if (stats_attr_valid(filter_mask, IFLA_STATS_AF_SPEC, *idxattr)) {
    4893                 :            :                 struct rtnl_af_ops *af_ops;
    4894                 :            : 
    4895                 :          0 :                 *idxattr = IFLA_STATS_AF_SPEC;
    4896                 :            :                 attr = nla_nest_start_noflag(skb, IFLA_STATS_AF_SPEC);
    4897         [ #  # ]:          0 :                 if (!attr)
    4898                 :            :                         goto nla_put_failure;
    4899                 :            : 
    4900                 :            :                 rcu_read_lock();
    4901         [ #  # ]:          0 :                 list_for_each_entry_rcu(af_ops, &rtnl_af_ops, list) {
    4902         [ #  # ]:          0 :                         if (af_ops->fill_stats_af) {
    4903                 :            :                                 struct nlattr *af;
    4904                 :            :                                 int err;
    4905                 :            : 
    4906                 :          0 :                                 af = nla_nest_start_noflag(skb,
    4907                 :            :                                                            af_ops->family);
    4908         [ #  # ]:          0 :                                 if (!af) {
    4909                 :            :                                         rcu_read_unlock();
    4910                 :            :                                         goto nla_put_failure;
    4911                 :            :                                 }
    4912                 :          0 :                                 err = af_ops->fill_stats_af(skb, dev);
    4913                 :            : 
    4914         [ #  # ]:          0 :                                 if (err == -ENODATA) {
    4915                 :            :                                         nla_nest_cancel(skb, af);
    4916         [ #  # ]:          0 :                                 } else if (err < 0) {
    4917                 :            :                                         rcu_read_unlock();
    4918                 :            :                                         goto nla_put_failure;
    4919                 :            :                                 }
    4920                 :            : 
    4921                 :            :                                 nla_nest_end(skb, af);
    4922                 :            :                         }
    4923                 :            :                 }
    4924                 :            :                 rcu_read_unlock();
    4925                 :            : 
    4926                 :            :                 nla_nest_end(skb, attr);
    4927                 :            : 
    4928                 :          0 :                 *idxattr = 0;
    4929                 :            :         }
    4930                 :            : 
    4931                 :            :         nlmsg_end(skb, nlh);
    4932                 :            : 
    4933                 :          0 :         return 0;
    4934                 :            : 
    4935                 :            : nla_put_failure:
    4936                 :            :         /* not a multi message or no progress mean a real error */
    4937   [ #  #  #  # ]:          0 :         if (!(flags & NLM_F_MULTI) || s_prividx == *prividx)
    4938                 :            :                 nlmsg_cancel(skb, nlh);
    4939                 :            :         else
    4940                 :            :                 nlmsg_end(skb, nlh);
    4941                 :            : 
    4942                 :            :         return -EMSGSIZE;
    4943                 :            : }
    4944                 :            : 
    4945                 :          0 : static size_t if_nlmsg_stats_size(const struct net_device *dev,
    4946                 :            :                                   u32 filter_mask)
    4947                 :            : {
    4948                 :            :         size_t size = 0;
    4949                 :            : 
    4950         [ #  # ]:          0 :         if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_64, 0))
    4951                 :            :                 size += nla_total_size_64bit(sizeof(struct rtnl_link_stats64));
    4952                 :            : 
    4953         [ #  # ]:          0 :         if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_XSTATS, 0)) {
    4954                 :          0 :                 const struct rtnl_link_ops *ops = dev->rtnl_link_ops;
    4955                 :            :                 int attr = IFLA_STATS_LINK_XSTATS;
    4956                 :            : 
    4957   [ #  #  #  # ]:          0 :                 if (ops && ops->get_linkxstats_size) {
    4958                 :          0 :                         size += nla_total_size(ops->get_linkxstats_size(dev,
    4959                 :            :                                                                         attr));
    4960                 :            :                         /* for IFLA_STATS_LINK_XSTATS */
    4961                 :          0 :                         size += nla_total_size(0);
    4962                 :            :                 }
    4963                 :            :         }
    4964                 :            : 
    4965         [ #  # ]:          0 :         if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_XSTATS_SLAVE, 0)) {
    4966                 :            :                 struct net_device *_dev = (struct net_device *)dev;
    4967                 :            :                 const struct rtnl_link_ops *ops = NULL;
    4968                 :            :                 const struct net_device *master;
    4969                 :            : 
    4970                 :            :                 /* netdev_master_upper_dev_get can't take const */
    4971                 :          0 :                 master = netdev_master_upper_dev_get(_dev);
    4972         [ #  # ]:          0 :                 if (master)
    4973                 :          0 :                         ops = master->rtnl_link_ops;
    4974   [ #  #  #  # ]:          0 :                 if (ops && ops->get_linkxstats_size) {
    4975                 :            :                         int attr = IFLA_STATS_LINK_XSTATS_SLAVE;
    4976                 :            : 
    4977                 :          0 :                         size += nla_total_size(ops->get_linkxstats_size(dev,
    4978                 :            :                                                                         attr));
    4979                 :            :                         /* for IFLA_STATS_LINK_XSTATS_SLAVE */
    4980                 :          0 :                         size += nla_total_size(0);
    4981                 :            :                 }
    4982                 :            :         }
    4983                 :            : 
    4984         [ #  # ]:          0 :         if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_OFFLOAD_XSTATS, 0))
    4985                 :          0 :                 size += rtnl_get_offload_stats_size(dev);
    4986                 :            : 
    4987         [ #  # ]:          0 :         if (stats_attr_valid(filter_mask, IFLA_STATS_AF_SPEC, 0)) {
    4988                 :            :                 struct rtnl_af_ops *af_ops;
    4989                 :            : 
    4990                 :            :                 /* for IFLA_STATS_AF_SPEC */
    4991                 :          0 :                 size += nla_total_size(0);
    4992                 :            : 
    4993                 :            :                 rcu_read_lock();
    4994         [ #  # ]:          0 :                 list_for_each_entry_rcu(af_ops, &rtnl_af_ops, list) {
    4995         [ #  # ]:          0 :                         if (af_ops->get_stats_af_size) {
    4996                 :          0 :                                 size += nla_total_size(
    4997                 :          0 :                                         af_ops->get_stats_af_size(dev));
    4998                 :            : 
    4999                 :            :                                 /* for AF_* */
    5000                 :          0 :                                 size += nla_total_size(0);
    5001                 :            :                         }
    5002                 :            :                 }
    5003                 :            :                 rcu_read_unlock();
    5004                 :            :         }
    5005                 :            : 
    5006                 :          0 :         return size;
    5007                 :            : }
    5008                 :            : 
    5009                 :          0 : static int rtnl_valid_stats_req(const struct nlmsghdr *nlh, bool strict_check,
    5010                 :            :                                 bool is_dump, struct netlink_ext_ack *extack)
    5011                 :            : {
    5012                 :            :         struct if_stats_msg *ifsm;
    5013                 :            : 
    5014         [ #  # ]:          0 :         if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ifsm))) {
    5015         [ #  # ]:          0 :                 NL_SET_ERR_MSG(extack, "Invalid header for stats dump");
    5016                 :            :                 return -EINVAL;
    5017                 :            :         }
    5018                 :            : 
    5019         [ #  # ]:          0 :         if (!strict_check)
    5020                 :            :                 return 0;
    5021                 :            : 
    5022                 :            :         ifsm = nlmsg_data(nlh);
    5023                 :            : 
    5024                 :            :         /* only requests using strict checks can pass data to influence
    5025                 :            :          * the dump. The legacy exception is filter_mask.
    5026                 :            :          */
    5027   [ #  #  #  #  :          0 :         if (ifsm->pad1 || ifsm->pad2 || (is_dump && ifsm->ifindex)) {
                   #  # ]
    5028         [ #  # ]:          0 :                 NL_SET_ERR_MSG(extack, "Invalid values in header for stats dump request");
    5029                 :            :                 return -EINVAL;
    5030                 :            :         }
    5031         [ #  # ]:          0 :         if (nlmsg_attrlen(nlh, sizeof(*ifsm))) {
    5032         [ #  # ]:          0 :                 NL_SET_ERR_MSG(extack, "Invalid attributes after stats header");
    5033                 :            :                 return -EINVAL;
    5034                 :            :         }
    5035         [ #  # ]:          0 :         if (ifsm->filter_mask >= IFLA_STATS_FILTER_BIT(IFLA_STATS_MAX + 1)) {
    5036         [ #  # ]:          0 :                 NL_SET_ERR_MSG(extack, "Invalid stats requested through filter mask");
    5037                 :            :                 return -EINVAL;
    5038                 :            :         }
    5039                 :            : 
    5040                 :            :         return 0;
    5041                 :            : }
    5042                 :            : 
    5043                 :          0 : static int rtnl_stats_get(struct sk_buff *skb, struct nlmsghdr *nlh,
    5044                 :            :                           struct netlink_ext_ack *extack)
    5045                 :            : {
    5046                 :          0 :         struct net *net = sock_net(skb->sk);
    5047                 :            :         struct net_device *dev = NULL;
    5048                 :          0 :         int idxattr = 0, prividx = 0;
    5049                 :            :         struct if_stats_msg *ifsm;
    5050                 :            :         struct sk_buff *nskb;
    5051                 :            :         u32 filter_mask;
    5052                 :            :         int err;
    5053                 :            : 
    5054                 :          0 :         err = rtnl_valid_stats_req(nlh, netlink_strict_get_check(skb),
    5055                 :            :                                    false, extack);
    5056         [ #  # ]:          0 :         if (err)
    5057                 :            :                 return err;
    5058                 :            : 
    5059                 :            :         ifsm = nlmsg_data(nlh);
    5060         [ #  # ]:          0 :         if (ifsm->ifindex > 0)
    5061                 :          0 :                 dev = __dev_get_by_index(net, ifsm->ifindex);
    5062                 :            :         else
    5063                 :            :                 return -EINVAL;
    5064                 :            : 
    5065         [ #  # ]:          0 :         if (!dev)
    5066                 :            :                 return -ENODEV;
    5067                 :            : 
    5068                 :          0 :         filter_mask = ifsm->filter_mask;
    5069         [ #  # ]:          0 :         if (!filter_mask)
    5070                 :            :                 return -EINVAL;
    5071                 :            : 
    5072                 :          0 :         nskb = nlmsg_new(if_nlmsg_stats_size(dev, filter_mask), GFP_KERNEL);
    5073         [ #  # ]:          0 :         if (!nskb)
    5074                 :            :                 return -ENOBUFS;
    5075                 :            : 
    5076                 :          0 :         err = rtnl_fill_statsinfo(nskb, dev, RTM_NEWSTATS,
    5077                 :            :                                   NETLINK_CB(skb).portid, nlh->nlmsg_seq, 0,
    5078                 :            :                                   0, filter_mask, &idxattr, &prividx);
    5079         [ #  # ]:          0 :         if (err < 0) {
    5080                 :            :                 /* -EMSGSIZE implies BUG in if_nlmsg_stats_size */
    5081         [ #  # ]:          0 :                 WARN_ON(err == -EMSGSIZE);
    5082                 :          0 :                 kfree_skb(nskb);
    5083                 :            :         } else {
    5084                 :          0 :                 err = rtnl_unicast(nskb, net, NETLINK_CB(skb).portid);
    5085                 :            :         }
    5086                 :            : 
    5087                 :          0 :         return err;
    5088                 :            : }
    5089                 :            : 
    5090                 :          0 : static int rtnl_stats_dump(struct sk_buff *skb, struct netlink_callback *cb)
    5091                 :            : {
    5092                 :          0 :         struct netlink_ext_ack *extack = cb->extack;
    5093                 :            :         int h, s_h, err, s_idx, s_idxattr, s_prividx;
    5094                 :          0 :         struct net *net = sock_net(skb->sk);
    5095                 :            :         unsigned int flags = NLM_F_MULTI;
    5096                 :            :         struct if_stats_msg *ifsm;
    5097                 :            :         struct hlist_head *head;
    5098                 :            :         struct net_device *dev;
    5099                 :            :         u32 filter_mask = 0;
    5100                 :            :         int idx = 0;
    5101                 :            : 
    5102                 :          0 :         s_h = cb->args[0];
    5103                 :          0 :         s_idx = cb->args[1];
    5104                 :          0 :         s_idxattr = cb->args[2];
    5105                 :          0 :         s_prividx = cb->args[3];
    5106                 :            : 
    5107                 :          0 :         cb->seq = net->dev_base_seq;
    5108                 :            : 
    5109                 :          0 :         err = rtnl_valid_stats_req(cb->nlh, cb->strict_check, true, extack);
    5110         [ #  # ]:          0 :         if (err)
    5111                 :            :                 return err;
    5112                 :            : 
    5113                 :          0 :         ifsm = nlmsg_data(cb->nlh);
    5114                 :          0 :         filter_mask = ifsm->filter_mask;
    5115         [ #  # ]:          0 :         if (!filter_mask) {
    5116         [ #  # ]:          0 :                 NL_SET_ERR_MSG(extack, "Filter mask must be set for stats dump");
    5117                 :            :                 return -EINVAL;
    5118                 :            :         }
    5119                 :            : 
    5120         [ #  # ]:          0 :         for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
    5121                 :            :                 idx = 0;
    5122                 :          0 :                 head = &net->dev_index_head[h];
    5123   [ #  #  #  #  :          0 :                 hlist_for_each_entry(dev, head, index_hlist) {
                   #  # ]
    5124         [ #  # ]:          0 :                         if (idx < s_idx)
    5125                 :            :                                 goto cont;
    5126                 :          0 :                         err = rtnl_fill_statsinfo(skb, dev, RTM_NEWSTATS,
    5127                 :          0 :                                                   NETLINK_CB(cb->skb).portid,
    5128                 :          0 :                                                   cb->nlh->nlmsg_seq, 0,
    5129                 :            :                                                   flags, filter_mask,
    5130                 :            :                                                   &s_idxattr, &s_prividx);
    5131                 :            :                         /* If we ran out of room on the first message,
    5132                 :            :                          * we're in trouble
    5133                 :            :                          */
    5134   [ #  #  #  #  :          0 :                         WARN_ON((err == -EMSGSIZE) && (skb->len == 0));
                   #  # ]
    5135                 :            : 
    5136         [ #  # ]:          0 :                         if (err < 0)
    5137                 :            :                                 goto out;
    5138                 :          0 :                         s_prividx = 0;
    5139                 :          0 :                         s_idxattr = 0;
    5140                 :            :                         nl_dump_check_consistent(cb, nlmsg_hdr(skb));
    5141                 :            : cont:
    5142                 :          0 :                         idx++;
    5143                 :            :                 }
    5144                 :            :         }
    5145                 :            : out:
    5146                 :          0 :         cb->args[3] = s_prividx;
    5147                 :          0 :         cb->args[2] = s_idxattr;
    5148                 :          0 :         cb->args[1] = idx;
    5149                 :          0 :         cb->args[0] = h;
    5150                 :            : 
    5151                 :          0 :         return skb->len;
    5152                 :            : }
    5153                 :            : 
    5154                 :            : /* Process one rtnetlink message. */
    5155                 :            : 
    5156                 :       6003 : static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
    5157                 :            :                              struct netlink_ext_ack *extack)
    5158                 :            : {
    5159                 :       6003 :         struct net *net = sock_net(skb->sk);
    5160                 :            :         struct rtnl_link *link;
    5161                 :            :         struct module *owner;
    5162                 :            :         int err = -EOPNOTSUPP;
    5163                 :            :         rtnl_doit_func doit;
    5164                 :            :         unsigned int flags;
    5165                 :            :         int kind;
    5166                 :            :         int family;
    5167                 :            :         int type;
    5168                 :            : 
    5169                 :       6003 :         type = nlh->nlmsg_type;
    5170         [ +  - ]:       6003 :         if (type > RTM_MAX)
    5171                 :            :                 return -EOPNOTSUPP;
    5172                 :            : 
    5173                 :       6003 :         type -= RTM_BASE;
    5174                 :            : 
    5175                 :            :         /* All the messages must have at least 1 byte length */
    5176         [ +  + ]:       6003 :         if (nlmsg_len(nlh) < sizeof(struct rtgenmsg))
    5177                 :            :                 return 0;
    5178                 :            : 
    5179                 :       6002 :         family = ((struct rtgenmsg *)nlmsg_data(nlh))->rtgen_family;
    5180                 :       6002 :         kind = type&3;
    5181                 :            : 
    5182   [ +  +  +  - ]:       6002 :         if (kind != 2 && !netlink_net_capable(skb, CAP_NET_ADMIN))
    5183                 :            :                 return -EPERM;
    5184                 :            : 
    5185                 :            :         rcu_read_lock();
    5186   [ +  +  +  - ]:       6003 :         if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) {
    5187                 :            :                 struct sock *rtnl;
    5188                 :            :                 rtnl_dumpit_func dumpit;
    5189                 :            :                 u16 min_dump_alloc = 0;
    5190                 :            : 
    5191                 :            :                 link = rtnl_get_link(family, type);
    5192   [ +  +  -  + ]:       3105 :                 if (!link || !link->dumpit) {
    5193                 :            :                         family = PF_UNSPEC;
    5194                 :            :                         link = rtnl_get_link(family, type);
    5195   [ #  #  #  # ]:          0 :                         if (!link || !link->dumpit)
    5196                 :            :                                 goto err_unlock;
    5197                 :            :                 }
    5198                 :       3105 :                 owner = link->owner;
    5199                 :       3105 :                 dumpit = link->dumpit;
    5200                 :            : 
    5201         [ +  + ]:       3105 :                 if (type == RTM_GETLINK - RTM_BASE)
    5202                 :       1242 :                         min_dump_alloc = rtnl_calcit(skb, nlh);
    5203                 :            : 
    5204                 :            :                 err = 0;
    5205                 :            :                 /* need to do this before rcu_read_unlock() */
    5206         [ -  + ]:       3105 :                 if (!try_module_get(owner))
    5207                 :            :                         err = -EPROTONOSUPPORT;
    5208                 :            : 
    5209                 :            :                 rcu_read_unlock();
    5210                 :            : 
    5211                 :       3105 :                 rtnl = net->rtnl;
    5212         [ +  - ]:       3105 :                 if (err == 0) {
    5213                 :       3105 :                         struct netlink_dump_control c = {
    5214                 :            :                                 .dump           = dumpit,
    5215                 :            :                                 .min_dump_alloc = min_dump_alloc,
    5216                 :            :                                 .module         = owner,
    5217                 :            :                         };
    5218                 :            :                         err = netlink_dump_start(rtnl, skb, nlh, &c);
    5219                 :            :                         /* netlink_dump_start() will keep a reference on
    5220                 :            :                          * module if dump is still in progress.
    5221                 :            :                          */
    5222                 :       3105 :                         module_put(owner);
    5223                 :            :                 }
    5224                 :       3105 :                 return err;
    5225                 :            :         }
    5226                 :            : 
    5227                 :            :         link = rtnl_get_link(family, type);
    5228   [ +  +  -  + ]:       2898 :         if (!link || !link->doit) {
    5229                 :            :                 family = PF_UNSPEC;
    5230                 :            :                 link = rtnl_get_link(PF_UNSPEC, type);
    5231   [ +  -  +  - ]:        621 :                 if (!link || !link->doit)
    5232                 :            :                         goto out_unlock;
    5233                 :            :         }
    5234                 :            : 
    5235                 :       2898 :         owner = link->owner;
    5236         [ +  - ]:       2898 :         if (!try_module_get(owner)) {
    5237                 :            :                 err = -EPROTONOSUPPORT;
    5238                 :            :                 goto out_unlock;
    5239                 :            :         }
    5240                 :            : 
    5241                 :       2898 :         flags = link->flags;
    5242         [ -  + ]:       2898 :         if (flags & RTNL_FLAG_DOIT_UNLOCKED) {
    5243                 :          0 :                 doit = link->doit;
    5244                 :            :                 rcu_read_unlock();
    5245         [ #  # ]:          0 :                 if (doit)
    5246                 :          0 :                         err = doit(skb, nlh, extack);
    5247                 :          0 :                 module_put(owner);
    5248                 :          0 :                 return err;
    5249                 :            :         }
    5250                 :            :         rcu_read_unlock();
    5251                 :            : 
    5252                 :            :         rtnl_lock();
    5253                 :            :         link = rtnl_get_link(family, type);
    5254   [ +  -  +  - ]:       2898 :         if (link && link->doit)
    5255                 :       2898 :                 err = link->doit(skb, nlh, extack);
    5256                 :            :         rtnl_unlock();
    5257                 :            : 
    5258                 :       2898 :         module_put(owner);
    5259                 :            : 
    5260                 :       2898 :         return err;
    5261                 :            : 
    5262                 :            : out_unlock:
    5263                 :            :         rcu_read_unlock();
    5264                 :          0 :         return err;
    5265                 :            : 
    5266                 :            : err_unlock:
    5267                 :            :         rcu_read_unlock();
    5268                 :          0 :         return -EOPNOTSUPP;
    5269                 :            : }
    5270                 :            : 
    5271                 :       6003 : static void rtnetlink_rcv(struct sk_buff *skb)
    5272                 :            : {
    5273                 :       6003 :         netlink_rcv_skb(skb, &rtnetlink_rcv_msg);
    5274                 :       6003 : }
    5275                 :            : 
    5276                 :       1863 : static int rtnetlink_bind(struct net *net, int group)
    5277                 :            : {
    5278         [ -  + ]:       1863 :         switch (group) {
    5279                 :            :         case RTNLGRP_IPV4_MROUTE_R:
    5280                 :            :         case RTNLGRP_IPV6_MROUTE_R:
    5281         [ #  # ]:          0 :                 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
    5282                 :            :                         return -EPERM;
    5283                 :            :                 break;
    5284                 :            :         }
    5285                 :            :         return 0;
    5286                 :            : }
    5287                 :            : 
    5288                 :       2484 : static int rtnetlink_event(struct notifier_block *this, unsigned long event, void *ptr)
    5289                 :            : {
    5290                 :            :         struct net_device *dev = netdev_notifier_info_to_dev(ptr);
    5291                 :            : 
    5292   [ -  +  #  # ]:       2484 :         switch (event) {
    5293                 :            :         case NETDEV_REBOOT:
    5294                 :            :         case NETDEV_CHANGEMTU:
    5295                 :            :         case NETDEV_CHANGEADDR:
    5296                 :            :         case NETDEV_CHANGENAME:
    5297                 :            :         case NETDEV_FEAT_CHANGE:
    5298                 :            :         case NETDEV_BONDING_FAILOVER:
    5299                 :            :         case NETDEV_POST_TYPE_CHANGE:
    5300                 :            :         case NETDEV_NOTIFY_PEERS:
    5301                 :            :         case NETDEV_CHANGEUPPER:
    5302                 :            :         case NETDEV_RESEND_IGMP:
    5303                 :            :         case NETDEV_CHANGEINFODATA:
    5304                 :            :         case NETDEV_CHANGELOWERSTATE:
    5305                 :            :         case NETDEV_CHANGE_TX_QUEUE_LEN:
    5306                 :          0 :                 rtmsg_ifinfo_event(RTM_NEWLINK, dev, 0, rtnl_get_event(event),
    5307                 :            :                                    GFP_KERNEL, NULL, 0);
    5308                 :          0 :                 break;
    5309                 :            :         default:
    5310                 :            :                 break;
    5311                 :            :         }
    5312                 :       2484 :         return NOTIFY_DONE;
    5313                 :            : }
    5314                 :            : 
    5315                 :            : static struct notifier_block rtnetlink_dev_notifier = {
    5316                 :            :         .notifier_call  = rtnetlink_event,
    5317                 :            : };
    5318                 :            : 
    5319                 :            : 
    5320                 :        207 : static int __net_init rtnetlink_net_init(struct net *net)
    5321                 :            : {
    5322                 :            :         struct sock *sk;
    5323                 :        207 :         struct netlink_kernel_cfg cfg = {
    5324                 :            :                 .groups         = RTNLGRP_MAX,
    5325                 :            :                 .input          = rtnetlink_rcv,
    5326                 :            :                 .cb_mutex       = &rtnl_mutex,
    5327                 :            :                 .flags          = NL_CFG_F_NONROOT_RECV,
    5328                 :            :                 .bind           = rtnetlink_bind,
    5329                 :            :         };
    5330                 :            : 
    5331                 :            :         sk = netlink_kernel_create(net, NETLINK_ROUTE, &cfg);
    5332         [ +  - ]:        207 :         if (!sk)
    5333                 :            :                 return -ENOMEM;
    5334                 :        207 :         net->rtnl = sk;
    5335                 :        207 :         return 0;
    5336                 :            : }
    5337                 :            : 
    5338                 :          0 : static void __net_exit rtnetlink_net_exit(struct net *net)
    5339                 :            : {
    5340                 :          0 :         netlink_kernel_release(net->rtnl);
    5341                 :          0 :         net->rtnl = NULL;
    5342                 :          0 : }
    5343                 :            : 
    5344                 :            : static struct pernet_operations rtnetlink_net_ops = {
    5345                 :            :         .init = rtnetlink_net_init,
    5346                 :            :         .exit = rtnetlink_net_exit,
    5347                 :            : };
    5348                 :            : 
    5349                 :        207 : void __init rtnetlink_init(void)
    5350                 :            : {
    5351         [ -  + ]:        207 :         if (register_pernet_subsys(&rtnetlink_net_ops))
    5352                 :          0 :                 panic("rtnetlink_init: cannot initialize rtnetlink\n");
    5353                 :            : 
    5354                 :        207 :         register_netdevice_notifier(&rtnetlink_dev_notifier);
    5355                 :            : 
    5356                 :        207 :         rtnl_register(PF_UNSPEC, RTM_GETLINK, rtnl_getlink,
    5357                 :            :                       rtnl_dump_ifinfo, 0);
    5358                 :        207 :         rtnl_register(PF_UNSPEC, RTM_SETLINK, rtnl_setlink, NULL, 0);
    5359                 :        207 :         rtnl_register(PF_UNSPEC, RTM_NEWLINK, rtnl_newlink, NULL, 0);
    5360                 :        207 :         rtnl_register(PF_UNSPEC, RTM_DELLINK, rtnl_dellink, NULL, 0);
    5361                 :            : 
    5362                 :        207 :         rtnl_register(PF_UNSPEC, RTM_GETADDR, NULL, rtnl_dump_all, 0);
    5363                 :        207 :         rtnl_register(PF_UNSPEC, RTM_GETROUTE, NULL, rtnl_dump_all, 0);
    5364                 :        207 :         rtnl_register(PF_UNSPEC, RTM_GETNETCONF, NULL, rtnl_dump_all, 0);
    5365                 :            : 
    5366                 :        207 :         rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, rtnl_fdb_add, NULL, 0);
    5367                 :        207 :         rtnl_register(PF_BRIDGE, RTM_DELNEIGH, rtnl_fdb_del, NULL, 0);
    5368                 :        207 :         rtnl_register(PF_BRIDGE, RTM_GETNEIGH, rtnl_fdb_get, rtnl_fdb_dump, 0);
    5369                 :            : 
    5370                 :        207 :         rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL, rtnl_bridge_getlink, 0);
    5371                 :        207 :         rtnl_register(PF_BRIDGE, RTM_DELLINK, rtnl_bridge_dellink, NULL, 0);
    5372                 :        207 :         rtnl_register(PF_BRIDGE, RTM_SETLINK, rtnl_bridge_setlink, NULL, 0);
    5373                 :            : 
    5374                 :        207 :         rtnl_register(PF_UNSPEC, RTM_GETSTATS, rtnl_stats_get, rtnl_stats_dump,
    5375                 :            :                       0);
    5376                 :        207 : }

Generated by: LCOV version 1.14