LCOV - code coverage report
Current view: top level - net/8021q - vlan.c (source / functions) Hit Total Coverage
Test: gcov_data_raspi2_real_modules_combined.info Lines: 36 255 14.1 %
Date: 2020-09-30 20:25:40 Functions: 4 14 28.6 %
Branches: 15 215 7.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0-or-later
       2                 :            : /*
       3                 :            :  * INET         802.1Q VLAN
       4                 :            :  *              Ethernet-type device handling.
       5                 :            :  *
       6                 :            :  * Authors:     Ben Greear <greearb@candelatech.com>
       7                 :            :  *              Please send support related email to: netdev@vger.kernel.org
       8                 :            :  *              VLAN Home Page: http://www.candelatech.com/~greear/vlan.html
       9                 :            :  *
      10                 :            :  * Fixes:
      11                 :            :  *              Fix for packet capture - Nick Eggleston <nick@dccinc.com>;
      12                 :            :  *              Add HW acceleration hooks - David S. Miller <davem@redhat.com>;
      13                 :            :  *              Correct all the locking - David S. Miller <davem@redhat.com>;
      14                 :            :  *              Use hash table for VLAN groups - David S. Miller <davem@redhat.com>
      15                 :            :  */
      16                 :            : 
      17                 :            : #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
      18                 :            : 
      19                 :            : #include <linux/capability.h>
      20                 :            : #include <linux/module.h>
      21                 :            : #include <linux/netdevice.h>
      22                 :            : #include <linux/skbuff.h>
      23                 :            : #include <linux/slab.h>
      24                 :            : #include <linux/init.h>
      25                 :            : #include <linux/rculist.h>
      26                 :            : #include <net/p8022.h>
      27                 :            : #include <net/arp.h>
      28                 :            : #include <linux/rtnetlink.h>
      29                 :            : #include <linux/notifier.h>
      30                 :            : #include <net/rtnetlink.h>
      31                 :            : #include <net/net_namespace.h>
      32                 :            : #include <net/netns/generic.h>
      33                 :            : #include <linux/uaccess.h>
      34                 :            : 
      35                 :            : #include <linux/if_vlan.h>
      36                 :            : #include "vlan.h"
      37                 :            : #include "vlanproc.h"
      38                 :            : 
      39                 :            : #define DRV_VERSION "1.8"
      40                 :            : 
      41                 :            : /* Global VLAN variables */
      42                 :            : 
      43                 :            : unsigned int vlan_net_id __read_mostly;
      44                 :            : 
      45                 :            : const char vlan_fullname[] = "802.1Q VLAN Support";
      46                 :            : const char vlan_version[] = DRV_VERSION;
      47                 :            : 
      48                 :            : /* End of global variables definitions. */
      49                 :            : 
      50                 :          0 : static int vlan_group_prealloc_vid(struct vlan_group *vg,
      51                 :            :                                    __be16 vlan_proto, u16 vlan_id)
      52                 :            : {
      53                 :            :         struct net_device **array;
      54                 :            :         unsigned int pidx, vidx;
      55                 :            :         unsigned int size;
      56                 :            : 
      57   [ #  #  #  # ]:          0 :         ASSERT_RTNL();
      58                 :            : 
      59                 :          0 :         pidx  = vlan_proto_idx(vlan_proto);
      60                 :          0 :         vidx  = vlan_id / VLAN_GROUP_ARRAY_PART_LEN;
      61                 :          0 :         array = vg->vlan_devices_arrays[pidx][vidx];
      62         [ #  # ]:          0 :         if (array != NULL)
      63                 :            :                 return 0;
      64                 :            : 
      65                 :            :         size = sizeof(struct net_device *) * VLAN_GROUP_ARRAY_PART_LEN;
      66                 :          0 :         array = kzalloc(size, GFP_KERNEL);
      67         [ #  # ]:          0 :         if (array == NULL)
      68                 :            :                 return -ENOBUFS;
      69                 :            : 
      70                 :          0 :         vg->vlan_devices_arrays[pidx][vidx] = array;
      71                 :          0 :         return 0;
      72                 :            : }
      73                 :            : 
      74                 :            : static void vlan_stacked_transfer_operstate(const struct net_device *rootdev,
      75                 :            :                                             struct net_device *dev,
      76                 :            :                                             struct vlan_dev_priv *vlan)
      77                 :            : {
      78   [ #  #  #  #  :          0 :         if (!(vlan->flags & VLAN_FLAG_BRIDGE_BINDING))
             #  #  #  # ]
      79                 :          0 :                 netif_stacked_transfer_operstate(rootdev, dev);
      80                 :            : }
      81                 :            : 
      82                 :          0 : void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
      83                 :            : {
      84                 :            :         struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
      85                 :          0 :         struct net_device *real_dev = vlan->real_dev;
      86                 :            :         struct vlan_info *vlan_info;
      87                 :            :         struct vlan_group *grp;
      88                 :          0 :         u16 vlan_id = vlan->vlan_id;
      89                 :            : 
      90   [ #  #  #  # ]:          0 :         ASSERT_RTNL();
      91                 :            : 
      92                 :          0 :         vlan_info = rtnl_dereference(real_dev->vlan_info);
      93         [ #  # ]:          0 :         BUG_ON(!vlan_info);
      94                 :            : 
      95                 :          0 :         grp = &vlan_info->grp;
      96                 :            : 
      97                 :          0 :         grp->nr_vlan_devs--;
      98                 :            : 
      99                 :            :         if (vlan->flags & VLAN_FLAG_MVRP)
     100                 :            :                 vlan_mvrp_request_leave(dev);
     101         [ #  # ]:          0 :         if (vlan->flags & VLAN_FLAG_GVRP)
     102                 :          0 :                 vlan_gvrp_request_leave(dev);
     103                 :            : 
     104                 :          0 :         vlan_group_set_device(grp, vlan->vlan_proto, vlan_id, NULL);
     105                 :            : 
     106                 :          0 :         netdev_upper_dev_unlink(real_dev, dev);
     107                 :            :         /* Because unregister_netdevice_queue() makes sure at least one rcu
     108                 :            :          * grace period is respected before device freeing,
     109                 :            :          * we dont need to call synchronize_net() here.
     110                 :            :          */
     111                 :          0 :         unregister_netdevice_queue(dev, head);
     112                 :            : 
     113         [ #  # ]:          0 :         if (grp->nr_vlan_devs == 0) {
     114                 :            :                 vlan_mvrp_uninit_applicant(real_dev);
     115                 :          0 :                 vlan_gvrp_uninit_applicant(real_dev);
     116                 :            :         }
     117                 :            : 
     118                 :          0 :         vlan_vid_del(real_dev, vlan->vlan_proto, vlan_id);
     119                 :            : 
     120                 :            :         /* Get rid of the vlan's reference to real_dev */
     121                 :          0 :         dev_put(real_dev);
     122                 :          0 : }
     123                 :            : 
     124                 :          0 : int vlan_check_real_dev(struct net_device *real_dev,
     125                 :            :                         __be16 protocol, u16 vlan_id,
     126                 :            :                         struct netlink_ext_ack *extack)
     127                 :            : {
     128                 :          0 :         const char *name = real_dev->name;
     129                 :            : 
     130         [ #  # ]:          0 :         if (real_dev->features & NETIF_F_VLAN_CHALLENGED) {
     131                 :          0 :                 pr_info("VLANs not supported on %s\n", name);
     132         [ #  # ]:          0 :                 NL_SET_ERR_MSG_MOD(extack, "VLANs not supported on device");
     133                 :            :                 return -EOPNOTSUPP;
     134                 :            :         }
     135                 :            : 
     136         [ #  # ]:          0 :         if (vlan_find_dev(real_dev, protocol, vlan_id) != NULL) {
     137         [ #  # ]:          0 :                 NL_SET_ERR_MSG_MOD(extack, "VLAN device already exists");
     138                 :            :                 return -EEXIST;
     139                 :            :         }
     140                 :            : 
     141                 :            :         return 0;
     142                 :            : }
     143                 :            : 
     144                 :          0 : int register_vlan_dev(struct net_device *dev, struct netlink_ext_ack *extack)
     145                 :            : {
     146                 :            :         struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
     147                 :          0 :         struct net_device *real_dev = vlan->real_dev;
     148                 :          0 :         u16 vlan_id = vlan->vlan_id;
     149                 :            :         struct vlan_info *vlan_info;
     150                 :            :         struct vlan_group *grp;
     151                 :            :         int err;
     152                 :            : 
     153                 :          0 :         err = vlan_vid_add(real_dev, vlan->vlan_proto, vlan_id);
     154         [ #  # ]:          0 :         if (err)
     155                 :            :                 return err;
     156                 :            : 
     157                 :          0 :         vlan_info = rtnl_dereference(real_dev->vlan_info);
     158                 :            :         /* vlan_info should be there now. vlan_vid_add took care of it */
     159         [ #  # ]:          0 :         BUG_ON(!vlan_info);
     160                 :            : 
     161                 :          0 :         grp = &vlan_info->grp;
     162         [ #  # ]:          0 :         if (grp->nr_vlan_devs == 0) {
     163                 :          0 :                 err = vlan_gvrp_init_applicant(real_dev);
     164         [ #  # ]:          0 :                 if (err < 0)
     165                 :            :                         goto out_vid_del;
     166                 :            :                 err = vlan_mvrp_init_applicant(real_dev);
     167                 :            :                 if (err < 0)
     168                 :            :                         goto out_uninit_gvrp;
     169                 :            :         }
     170                 :            : 
     171                 :          0 :         err = vlan_group_prealloc_vid(grp, vlan->vlan_proto, vlan_id);
     172         [ #  # ]:          0 :         if (err < 0)
     173                 :            :                 goto out_uninit_mvrp;
     174                 :            : 
     175                 :          0 :         err = register_netdevice(dev);
     176         [ #  # ]:          0 :         if (err < 0)
     177                 :            :                 goto out_uninit_mvrp;
     178                 :            : 
     179                 :          0 :         err = netdev_upper_dev_link(real_dev, dev, extack);
     180         [ #  # ]:          0 :         if (err)
     181                 :            :                 goto out_unregister_netdev;
     182                 :            : 
     183                 :            :         /* Account for reference in struct vlan_dev_priv */
     184                 :          0 :         dev_hold(real_dev);
     185                 :            : 
     186                 :            :         vlan_stacked_transfer_operstate(real_dev, dev, vlan);
     187                 :          0 :         linkwatch_fire_event(dev); /* _MUST_ call rfc2863_policy() */
     188                 :            : 
     189                 :            :         /* So, got the sucker initialized, now lets place
     190                 :            :          * it into our local structure.
     191                 :            :          */
     192                 :          0 :         vlan_group_set_device(grp, vlan->vlan_proto, vlan_id, dev);
     193                 :          0 :         grp->nr_vlan_devs++;
     194                 :            : 
     195                 :          0 :         return 0;
     196                 :            : 
     197                 :            : out_unregister_netdev:
     198                 :            :         unregister_netdevice(dev);
     199                 :            : out_uninit_mvrp:
     200                 :            :         if (grp->nr_vlan_devs == 0)
     201                 :            :                 vlan_mvrp_uninit_applicant(real_dev);
     202                 :            : out_uninit_gvrp:
     203         [ #  # ]:          0 :         if (grp->nr_vlan_devs == 0)
     204                 :          0 :                 vlan_gvrp_uninit_applicant(real_dev);
     205                 :            : out_vid_del:
     206                 :          0 :         vlan_vid_del(real_dev, vlan->vlan_proto, vlan_id);
     207                 :          0 :         return err;
     208                 :            : }
     209                 :            : 
     210                 :            : /*  Attach a VLAN device to a mac address (ie Ethernet Card).
     211                 :            :  *  Returns 0 if the device was created or a negative error code otherwise.
     212                 :            :  */
     213                 :          0 : static int register_vlan_device(struct net_device *real_dev, u16 vlan_id)
     214                 :            : {
     215                 :            :         struct net_device *new_dev;
     216                 :            :         struct vlan_dev_priv *vlan;
     217                 :            :         struct net *net = dev_net(real_dev);
     218                 :          0 :         struct vlan_net *vn = net_generic(net, vlan_net_id);
     219                 :            :         char name[IFNAMSIZ];
     220                 :            :         int err;
     221                 :            : 
     222         [ #  # ]:          0 :         if (vlan_id >= VLAN_VID_MASK)
     223                 :            :                 return -ERANGE;
     224                 :            : 
     225                 :          0 :         err = vlan_check_real_dev(real_dev, htons(ETH_P_8021Q), vlan_id,
     226                 :            :                                   NULL);
     227         [ #  # ]:          0 :         if (err < 0)
     228                 :            :                 return err;
     229                 :            : 
     230                 :            :         /* Gotta set up the fields for the device. */
     231   [ #  #  #  # ]:          0 :         switch (vn->name_type) {
     232                 :            :         case VLAN_NAME_TYPE_RAW_PLUS_VID:
     233                 :            :                 /* name will look like:  eth1.0005 */
     234                 :          0 :                 snprintf(name, IFNAMSIZ, "%s.%.4i", real_dev->name, vlan_id);
     235                 :          0 :                 break;
     236                 :            :         case VLAN_NAME_TYPE_PLUS_VID_NO_PAD:
     237                 :            :                 /* Put our vlan.VID in the name.
     238                 :            :                  * Name will look like:  vlan5
     239                 :            :                  */
     240                 :          0 :                 snprintf(name, IFNAMSIZ, "vlan%i", vlan_id);
     241                 :          0 :                 break;
     242                 :            :         case VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD:
     243                 :            :                 /* Put our vlan.VID in the name.
     244                 :            :                  * Name will look like:  eth0.5
     245                 :            :                  */
     246                 :          0 :                 snprintf(name, IFNAMSIZ, "%s.%i", real_dev->name, vlan_id);
     247                 :          0 :                 break;
     248                 :            :         case VLAN_NAME_TYPE_PLUS_VID:
     249                 :            :                 /* Put our vlan.VID in the name.
     250                 :            :                  * Name will look like:  vlan0005
     251                 :            :                  */
     252                 :            :         default:
     253                 :          0 :                 snprintf(name, IFNAMSIZ, "vlan%.4i", vlan_id);
     254                 :            :         }
     255                 :            : 
     256                 :          0 :         new_dev = alloc_netdev(sizeof(struct vlan_dev_priv), name,
     257                 :            :                                NET_NAME_UNKNOWN, vlan_setup);
     258                 :            : 
     259         [ #  # ]:          0 :         if (new_dev == NULL)
     260                 :            :                 return -ENOBUFS;
     261                 :            : 
     262                 :            :         dev_net_set(new_dev, net);
     263                 :            :         /* need 4 bytes for extra VLAN header info,
     264                 :            :          * hope the underlying device can handle it.
     265                 :            :          */
     266                 :          0 :         new_dev->mtu = real_dev->mtu;
     267                 :            : 
     268                 :            :         vlan = vlan_dev_priv(new_dev);
     269                 :          0 :         vlan->vlan_proto = htons(ETH_P_8021Q);
     270                 :          0 :         vlan->vlan_id = vlan_id;
     271                 :          0 :         vlan->real_dev = real_dev;
     272                 :          0 :         vlan->dent = NULL;
     273                 :          0 :         vlan->flags = VLAN_FLAG_REORDER_HDR;
     274                 :            : 
     275                 :          0 :         new_dev->rtnl_link_ops = &vlan_link_ops;
     276                 :          0 :         err = register_vlan_dev(new_dev, NULL);
     277         [ #  # ]:          0 :         if (err < 0)
     278                 :            :                 goto out_free_newdev;
     279                 :            : 
     280                 :            :         return 0;
     281                 :            : 
     282                 :            : out_free_newdev:
     283         [ #  # ]:          0 :         if (new_dev->reg_state == NETREG_UNINITIALIZED)
     284                 :          0 :                 free_netdev(new_dev);
     285                 :          0 :         return err;
     286                 :            : }
     287                 :            : 
     288                 :          0 : static void vlan_sync_address(struct net_device *dev,
     289                 :            :                               struct net_device *vlandev)
     290                 :            : {
     291                 :            :         struct vlan_dev_priv *vlan = vlan_dev_priv(vlandev);
     292                 :            : 
     293                 :            :         /* May be called without an actual change */
     294         [ #  # ]:          0 :         if (ether_addr_equal(vlan->real_dev_addr, dev->dev_addr))
     295                 :          0 :                 return;
     296                 :            : 
     297                 :            :         /* vlan continues to inherit address of lower device */
     298         [ #  # ]:          0 :         if (vlan_dev_inherit_address(vlandev, dev))
     299                 :            :                 goto out;
     300                 :            : 
     301                 :            :         /* vlan address was different from the old address and is equal to
     302                 :            :          * the new address */
     303   [ #  #  #  # ]:          0 :         if (!ether_addr_equal(vlandev->dev_addr, vlan->real_dev_addr) &&
     304                 :          0 :             ether_addr_equal(vlandev->dev_addr, dev->dev_addr))
     305                 :          0 :                 dev_uc_del(dev, vlandev->dev_addr);
     306                 :            : 
     307                 :            :         /* vlan address was equal to the old address and is different from
     308                 :            :          * the new address */
     309   [ #  #  #  # ]:          0 :         if (ether_addr_equal(vlandev->dev_addr, vlan->real_dev_addr) &&
     310                 :          0 :             !ether_addr_equal(vlandev->dev_addr, dev->dev_addr))
     311                 :          0 :                 dev_uc_add(dev, vlandev->dev_addr);
     312                 :            : 
     313                 :            : out:
     314                 :          0 :         ether_addr_copy(vlan->real_dev_addr, dev->dev_addr);
     315                 :            : }
     316                 :            : 
     317                 :          0 : static void vlan_transfer_features(struct net_device *dev,
     318                 :            :                                    struct net_device *vlandev)
     319                 :            : {
     320                 :            :         struct vlan_dev_priv *vlan = vlan_dev_priv(vlandev);
     321                 :            : 
     322                 :          0 :         vlandev->gso_max_size = dev->gso_max_size;
     323                 :          0 :         vlandev->gso_max_segs = dev->gso_max_segs;
     324                 :            : 
     325         [ #  # ]:          0 :         if (vlan_hw_offload_capable(dev->features, vlan->vlan_proto))
     326                 :          0 :                 vlandev->hard_header_len = dev->hard_header_len;
     327                 :            :         else
     328                 :          0 :                 vlandev->hard_header_len = dev->hard_header_len + VLAN_HLEN;
     329                 :            : 
     330                 :            : #if IS_ENABLED(CONFIG_FCOE)
     331                 :            :         vlandev->fcoe_ddp_xid = dev->fcoe_ddp_xid;
     332                 :            : #endif
     333                 :            : 
     334                 :          0 :         vlandev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
     335                 :          0 :         vlandev->priv_flags |= (vlan->real_dev->priv_flags & IFF_XMIT_DST_RELEASE);
     336                 :          0 :         vlandev->hw_enc_features = vlan_tnl_features(vlan->real_dev);
     337                 :            : 
     338                 :          0 :         netdev_update_features(vlandev);
     339                 :          0 : }
     340                 :            : 
     341                 :          0 : static int __vlan_device_event(struct net_device *dev, unsigned long event)
     342                 :            : {
     343                 :            :         int err = 0;
     344                 :            : 
     345   [ #  #  #  # ]:          0 :         switch (event) {
     346                 :            :         case NETDEV_CHANGENAME:
     347                 :          0 :                 vlan_proc_rem_dev(dev);
     348                 :          0 :                 err = vlan_proc_add_dev(dev);
     349                 :          0 :                 break;
     350                 :            :         case NETDEV_REGISTER:
     351                 :          0 :                 err = vlan_proc_add_dev(dev);
     352                 :          0 :                 break;
     353                 :            :         case NETDEV_UNREGISTER:
     354                 :          0 :                 vlan_proc_rem_dev(dev);
     355                 :          0 :                 break;
     356                 :            :         }
     357                 :            : 
     358                 :          0 :         return err;
     359                 :            : }
     360                 :            : 
     361                 :       1863 : static int vlan_device_event(struct notifier_block *unused, unsigned long event,
     362                 :            :                              void *ptr)
     363                 :            : {
     364                 :            :         struct netlink_ext_ack *extack = netdev_notifier_info_to_extack(ptr);
     365                 :            :         struct net_device *dev = netdev_notifier_info_to_dev(ptr);
     366                 :            :         struct vlan_group *grp;
     367                 :            :         struct vlan_info *vlan_info;
     368                 :            :         int i, flgs;
     369                 :            :         struct net_device *vlandev;
     370                 :            :         struct vlan_dev_priv *vlan;
     371                 :            :         bool last = false;
     372                 :       1863 :         LIST_HEAD(list);
     373                 :            :         int err;
     374                 :            : 
     375         [ -  + ]:       1863 :         if (is_vlan_dev(dev)) {
     376                 :          0 :                 int err = __vlan_device_event(dev, event);
     377                 :            : 
     378         [ #  # ]:          0 :                 if (err)
     379                 :          0 :                         return notifier_from_errno(err);
     380                 :            :         }
     381                 :            : 
     382   [ +  +  -  + ]:       2277 :         if ((event == NETDEV_UP) &&
     383                 :        414 :             (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)) {
     384                 :          0 :                 pr_info("adding VLAN 0 to HW filter on device %s\n",
     385                 :            :                         dev->name);
     386                 :          0 :                 vlan_vid_add(dev, htons(ETH_P_8021Q), 0);
     387                 :            :         }
     388   [ -  +  #  # ]:       1863 :         if (event == NETDEV_DOWN &&
     389                 :          0 :             (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER))
     390                 :          0 :                 vlan_vid_del(dev, htons(ETH_P_8021Q), 0);
     391                 :            : 
     392                 :       1863 :         vlan_info = rtnl_dereference(dev->vlan_info);
     393         [ -  + ]:       1863 :         if (!vlan_info)
     394                 :            :                 goto out;
     395                 :            :         grp = &vlan_info->grp;
     396                 :            : 
     397                 :            :         /* It is OK that we do not hold the group lock right now,
     398                 :            :          * as we run under the RTNL lock.
     399                 :            :          */
     400                 :            : 
     401   [ #  #  #  #  :          0 :         switch (event) {
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     402                 :            :         case NETDEV_CHANGE:
     403                 :            :                 /* Propagate real device state to vlan devices */
     404   [ #  #  #  # ]:          0 :                 vlan_group_for_each_dev(grp, i, vlandev)
     405                 :            :                         vlan_stacked_transfer_operstate(dev, vlandev,
     406                 :            :                                                         vlan_dev_priv(vlandev));
     407                 :            :                 break;
     408                 :            : 
     409                 :            :         case NETDEV_CHANGEADDR:
     410                 :            :                 /* Adjust unicast filters on underlying device */
     411   [ #  #  #  # ]:          0 :                 vlan_group_for_each_dev(grp, i, vlandev) {
     412                 :          0 :                         flgs = vlandev->flags;
     413         [ #  # ]:          0 :                         if (!(flgs & IFF_UP))
     414                 :          0 :                                 continue;
     415                 :            : 
     416                 :          0 :                         vlan_sync_address(dev, vlandev);
     417                 :            :                 }
     418                 :            :                 break;
     419                 :            : 
     420                 :            :         case NETDEV_CHANGEMTU:
     421   [ #  #  #  # ]:          0 :                 vlan_group_for_each_dev(grp, i, vlandev) {
     422         [ #  # ]:          0 :                         if (vlandev->mtu <= dev->mtu)
     423                 :          0 :                                 continue;
     424                 :            : 
     425                 :          0 :                         dev_set_mtu(vlandev, dev->mtu);
     426                 :            :                 }
     427                 :            :                 break;
     428                 :            : 
     429                 :            :         case NETDEV_FEAT_CHANGE:
     430                 :            :                 /* Propagate device features to underlying device */
     431   [ #  #  #  # ]:          0 :                 vlan_group_for_each_dev(grp, i, vlandev)
     432                 :          0 :                         vlan_transfer_features(dev, vlandev);
     433                 :            :                 break;
     434                 :            : 
     435                 :            :         case NETDEV_DOWN: {
     436                 :            :                 struct net_device *tmp;
     437                 :          0 :                 LIST_HEAD(close_list);
     438                 :            : 
     439                 :            :                 /* Put all VLANs for this dev in the down state too.  */
     440   [ #  #  #  # ]:          0 :                 vlan_group_for_each_dev(grp, i, vlandev) {
     441                 :          0 :                         flgs = vlandev->flags;
     442         [ #  # ]:          0 :                         if (!(flgs & IFF_UP))
     443                 :          0 :                                 continue;
     444                 :            : 
     445                 :            :                         vlan = vlan_dev_priv(vlandev);
     446         [ #  # ]:          0 :                         if (!(vlan->flags & VLAN_FLAG_LOOSE_BINDING))
     447                 :          0 :                                 list_add(&vlandev->close_list, &close_list);
     448                 :            :                 }
     449                 :            : 
     450                 :          0 :                 dev_close_many(&close_list, false);
     451                 :            : 
     452         [ #  # ]:          0 :                 list_for_each_entry_safe(vlandev, tmp, &close_list, close_list) {
     453                 :            :                         vlan_stacked_transfer_operstate(dev, vlandev,
     454                 :            :                                                         vlan_dev_priv(vlandev));
     455                 :            :                         list_del_init(&vlandev->close_list);
     456                 :            :                 }
     457                 :            :                 list_del(&close_list);
     458                 :            :                 break;
     459                 :            :         }
     460                 :            :         case NETDEV_UP:
     461                 :            :                 /* Put all VLANs for this dev in the up state too.  */
     462   [ #  #  #  # ]:          0 :                 vlan_group_for_each_dev(grp, i, vlandev) {
     463                 :          0 :                         flgs = dev_get_flags(vlandev);
     464         [ #  # ]:          0 :                         if (flgs & IFF_UP)
     465                 :          0 :                                 continue;
     466                 :            : 
     467                 :            :                         vlan = vlan_dev_priv(vlandev);
     468         [ #  # ]:          0 :                         if (!(vlan->flags & VLAN_FLAG_LOOSE_BINDING))
     469                 :          0 :                                 dev_change_flags(vlandev, flgs | IFF_UP,
     470                 :            :                                                  extack);
     471                 :            :                         vlan_stacked_transfer_operstate(dev, vlandev, vlan);
     472                 :            :                 }
     473                 :            :                 break;
     474                 :            : 
     475                 :            :         case NETDEV_UNREGISTER:
     476                 :            :                 /* twiddle thumbs on netns device moves */
     477         [ #  # ]:          0 :                 if (dev->reg_state != NETREG_UNREGISTERING)
     478                 :            :                         break;
     479                 :            : 
     480   [ #  #  #  # ]:          0 :                 vlan_group_for_each_dev(grp, i, vlandev) {
     481                 :            :                         /* removal of last vid destroys vlan_info, abort
     482                 :            :                          * afterwards */
     483         [ #  # ]:          0 :                         if (vlan_info->nr_vids == 1)
     484                 :            :                                 last = true;
     485                 :            : 
     486                 :          0 :                         unregister_vlan_dev(vlandev, &list);
     487         [ #  # ]:          0 :                         if (last)
     488                 :            :                                 break;
     489                 :            :                 }
     490                 :          0 :                 unregister_netdevice_many(&list);
     491                 :          0 :                 break;
     492                 :            : 
     493                 :            :         case NETDEV_PRE_TYPE_CHANGE:
     494                 :            :                 /* Forbid underlaying device to change its type. */
     495         [ #  # ]:          0 :                 if (vlan_uses_dev(dev))
     496                 :            :                         return NOTIFY_BAD;
     497                 :            :                 break;
     498                 :            : 
     499                 :            :         case NETDEV_NOTIFY_PEERS:
     500                 :            :         case NETDEV_BONDING_FAILOVER:
     501                 :            :         case NETDEV_RESEND_IGMP:
     502                 :            :                 /* Propagate to vlan devices */
     503   [ #  #  #  # ]:          0 :                 vlan_group_for_each_dev(grp, i, vlandev)
     504                 :          0 :                         call_netdevice_notifiers(event, vlandev);
     505                 :            :                 break;
     506                 :            : 
     507                 :            :         case NETDEV_CVLAN_FILTER_PUSH_INFO:
     508                 :          0 :                 err = vlan_filter_push_vids(vlan_info, htons(ETH_P_8021Q));
     509         [ #  # ]:          0 :                 if (err)
     510                 :          0 :                         return notifier_from_errno(err);
     511                 :            :                 break;
     512                 :            : 
     513                 :            :         case NETDEV_CVLAN_FILTER_DROP_INFO:
     514                 :          0 :                 vlan_filter_drop_vids(vlan_info, htons(ETH_P_8021Q));
     515                 :          0 :                 break;
     516                 :            : 
     517                 :            :         case NETDEV_SVLAN_FILTER_PUSH_INFO:
     518                 :          0 :                 err = vlan_filter_push_vids(vlan_info, htons(ETH_P_8021AD));
     519         [ #  # ]:          0 :                 if (err)
     520                 :          0 :                         return notifier_from_errno(err);
     521                 :            :                 break;
     522                 :            : 
     523                 :            :         case NETDEV_SVLAN_FILTER_DROP_INFO:
     524                 :          0 :                 vlan_filter_drop_vids(vlan_info, htons(ETH_P_8021AD));
     525                 :          0 :                 break;
     526                 :            :         }
     527                 :            : 
     528                 :            : out:
     529                 :            :         return NOTIFY_DONE;
     530                 :            : }
     531                 :            : 
     532                 :            : static struct notifier_block vlan_notifier_block __read_mostly = {
     533                 :            :         .notifier_call = vlan_device_event,
     534                 :            : };
     535                 :            : 
     536                 :            : /*
     537                 :            :  *      VLAN IOCTL handler.
     538                 :            :  *      o execute requested action or pass command to the device driver
     539                 :            :  *   arg is really a struct vlan_ioctl_args __user *.
     540                 :            :  */
     541                 :        414 : static int vlan_ioctl_handler(struct net *net, void __user *arg)
     542                 :            : {
     543                 :            :         int err;
     544                 :            :         struct vlan_ioctl_args args;
     545                 :            :         struct net_device *dev = NULL;
     546                 :            : 
     547         [ +  - ]:        414 :         if (copy_from_user(&args, arg, sizeof(struct vlan_ioctl_args)))
     548                 :            :                 return -EFAULT;
     549                 :            : 
     550                 :            :         /* Null terminate this sucker, just in case. */
     551                 :        414 :         args.device1[sizeof(args.device1) - 1] = 0;
     552                 :        414 :         args.u.device2[sizeof(args.u.device2) - 1] = 0;
     553                 :            : 
     554                 :        414 :         rtnl_lock();
     555                 :            : 
     556         [ +  - ]:        414 :         switch (args.cmd) {
     557                 :            :         case SET_VLAN_INGRESS_PRIORITY_CMD:
     558                 :            :         case SET_VLAN_EGRESS_PRIORITY_CMD:
     559                 :            :         case SET_VLAN_FLAG_CMD:
     560                 :            :         case ADD_VLAN_CMD:
     561                 :            :         case DEL_VLAN_CMD:
     562                 :            :         case GET_VLAN_REALDEV_NAME_CMD:
     563                 :            :         case GET_VLAN_VID_CMD:
     564                 :            :                 err = -ENODEV;
     565                 :        414 :                 dev = __dev_get_by_name(net, args.device1);
     566         [ +  - ]:        414 :                 if (!dev)
     567                 :            :                         goto out;
     568                 :            : 
     569                 :            :                 err = -EINVAL;
     570   [ +  -  -  + ]:        828 :                 if (args.cmd != ADD_VLAN_CMD && !is_vlan_dev(dev))
     571                 :            :                         goto out;
     572                 :            :         }
     573                 :            : 
     574   [ #  #  #  #  :          0 :         switch (args.cmd) {
             #  #  #  #  
                      # ]
     575                 :            :         case SET_VLAN_INGRESS_PRIORITY_CMD:
     576                 :            :                 err = -EPERM;
     577         [ #  # ]:          0 :                 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
     578                 :            :                         break;
     579                 :          0 :                 vlan_dev_set_ingress_priority(dev,
     580                 :            :                                               args.u.skb_priority,
     581                 :          0 :                                               args.vlan_qos);
     582                 :            :                 err = 0;
     583                 :          0 :                 break;
     584                 :            : 
     585                 :            :         case SET_VLAN_EGRESS_PRIORITY_CMD:
     586                 :            :                 err = -EPERM;
     587         [ #  # ]:          0 :                 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
     588                 :            :                         break;
     589                 :          0 :                 err = vlan_dev_set_egress_priority(dev,
     590                 :            :                                                    args.u.skb_priority,
     591                 :          0 :                                                    args.vlan_qos);
     592                 :          0 :                 break;
     593                 :            : 
     594                 :            :         case SET_VLAN_FLAG_CMD:
     595                 :            :                 err = -EPERM;
     596         [ #  # ]:          0 :                 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
     597                 :            :                         break;
     598         [ #  # ]:          0 :                 err = vlan_dev_change_flags(dev,
     599                 :          0 :                                             args.vlan_qos ? args.u.flag : 0,
     600                 :            :                                             args.u.flag);
     601                 :          0 :                 break;
     602                 :            : 
     603                 :            :         case SET_VLAN_NAME_TYPE_CMD:
     604                 :            :                 err = -EPERM;
     605         [ #  # ]:          0 :                 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
     606                 :            :                         break;
     607         [ #  # ]:          0 :                 if (args.u.name_type < VLAN_NAME_TYPE_HIGHEST) {
     608                 :            :                         struct vlan_net *vn;
     609                 :            : 
     610                 :          0 :                         vn = net_generic(net, vlan_net_id);
     611                 :          0 :                         vn->name_type = args.u.name_type;
     612                 :            :                         err = 0;
     613                 :            :                 } else {
     614                 :            :                         err = -EINVAL;
     615                 :            :                 }
     616                 :            :                 break;
     617                 :            : 
     618                 :            :         case ADD_VLAN_CMD:
     619                 :            :                 err = -EPERM;
     620         [ #  # ]:          0 :                 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
     621                 :            :                         break;
     622                 :          0 :                 err = register_vlan_device(dev, args.u.VID);
     623                 :          0 :                 break;
     624                 :            : 
     625                 :            :         case DEL_VLAN_CMD:
     626                 :            :                 err = -EPERM;
     627         [ #  # ]:          0 :                 if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
     628                 :            :                         break;
     629                 :          0 :                 unregister_vlan_dev(dev, NULL);
     630                 :            :                 err = 0;
     631                 :          0 :                 break;
     632                 :            : 
     633                 :            :         case GET_VLAN_REALDEV_NAME_CMD:
     634                 :            :                 err = 0;
     635                 :          0 :                 vlan_dev_get_realdev_name(dev, args.u.device2);
     636         [ #  # ]:          0 :                 if (copy_to_user(arg, &args,
     637                 :            :                                  sizeof(struct vlan_ioctl_args)))
     638                 :            :                         err = -EFAULT;
     639                 :            :                 break;
     640                 :            : 
     641                 :            :         case GET_VLAN_VID_CMD:
     642                 :            :                 err = 0;
     643                 :          0 :                 args.u.VID = vlan_dev_vlan_id(dev);
     644         [ #  # ]:          0 :                 if (copy_to_user(arg, &args,
     645                 :            :                                  sizeof(struct vlan_ioctl_args)))
     646                 :            :                       err = -EFAULT;
     647                 :            :                 break;
     648                 :            : 
     649                 :            :         default:
     650                 :            :                 err = -EOPNOTSUPP;
     651                 :            :                 break;
     652                 :            :         }
     653                 :            : out:
     654                 :        414 :         rtnl_unlock();
     655                 :        414 :         return err;
     656                 :            : }
     657                 :            : 
     658                 :        207 : static int __net_init vlan_init_net(struct net *net)
     659                 :            : {
     660                 :        207 :         struct vlan_net *vn = net_generic(net, vlan_net_id);
     661                 :            :         int err;
     662                 :            : 
     663                 :        207 :         vn->name_type = VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD;
     664                 :            : 
     665                 :        207 :         err = vlan_proc_init(net);
     666                 :            : 
     667                 :        207 :         return err;
     668                 :            : }
     669                 :            : 
     670                 :          0 : static void __net_exit vlan_exit_net(struct net *net)
     671                 :            : {
     672                 :          0 :         vlan_proc_cleanup(net);
     673                 :          0 : }
     674                 :            : 
     675                 :            : static struct pernet_operations vlan_net_ops = {
     676                 :            :         .init = vlan_init_net,
     677                 :            :         .exit = vlan_exit_net,
     678                 :            :         .id   = &vlan_net_id,
     679                 :            :         .size = sizeof(struct vlan_net),
     680                 :            : };
     681                 :            : 
     682                 :        207 : static int __init vlan_proto_init(void)
     683                 :            : {
     684                 :            :         int err;
     685                 :            : 
     686                 :        207 :         pr_info("%s v%s\n", vlan_fullname, vlan_version);
     687                 :            : 
     688                 :        207 :         err = register_pernet_subsys(&vlan_net_ops);
     689         [ +  - ]:        207 :         if (err < 0)
     690                 :            :                 goto err0;
     691                 :            : 
     692                 :        207 :         err = register_netdevice_notifier(&vlan_notifier_block);
     693         [ +  - ]:        207 :         if (err < 0)
     694                 :            :                 goto err2;
     695                 :            : 
     696                 :        207 :         err = vlan_gvrp_init();
     697         [ +  - ]:        207 :         if (err < 0)
     698                 :            :                 goto err3;
     699                 :            : 
     700                 :            :         err = vlan_mvrp_init();
     701                 :            :         if (err < 0)
     702                 :            :                 goto err4;
     703                 :            : 
     704                 :        207 :         err = vlan_netlink_init();
     705         [ +  - ]:        207 :         if (err < 0)
     706                 :            :                 goto err5;
     707                 :            : 
     708                 :        207 :         vlan_ioctl_set(vlan_ioctl_handler);
     709                 :        207 :         return 0;
     710                 :            : 
     711                 :            : err5:
     712                 :            :         vlan_mvrp_uninit();
     713                 :            : err4:
     714                 :          0 :         vlan_gvrp_uninit();
     715                 :            : err3:
     716                 :          0 :         unregister_netdevice_notifier(&vlan_notifier_block);
     717                 :            : err2:
     718                 :          0 :         unregister_pernet_subsys(&vlan_net_ops);
     719                 :            : err0:
     720                 :          0 :         return err;
     721                 :            : }
     722                 :            : 
     723                 :          0 : static void __exit vlan_cleanup_module(void)
     724                 :            : {
     725                 :          0 :         vlan_ioctl_set(NULL);
     726                 :            : 
     727                 :          0 :         vlan_netlink_fini();
     728                 :            : 
     729                 :          0 :         unregister_netdevice_notifier(&vlan_notifier_block);
     730                 :            : 
     731                 :          0 :         unregister_pernet_subsys(&vlan_net_ops);
     732                 :          0 :         rcu_barrier(); /* Wait for completion of call_rcu()'s */
     733                 :            : 
     734                 :            :         vlan_mvrp_uninit();
     735                 :          0 :         vlan_gvrp_uninit();
     736                 :          0 : }
     737                 :            : 
     738                 :            : module_init(vlan_proto_init);
     739                 :            : module_exit(vlan_cleanup_module);
     740                 :            : 
     741                 :            : MODULE_LICENSE("GPL");
     742                 :            : MODULE_VERSION(DRV_VERSION);

Generated by: LCOV version 1.14