LCOV - code coverage report
Current view: top level - net/core - rtnetlink.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 746 2782 26.8 %
Date: 2022-03-28 15:32:58 Functions: 59 125 47.2 %
Branches: 310 2102 14.7 %

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

Generated by: LCOV version 1.14