diff options
| author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
|---|---|---|
| committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
| commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
| tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /net/8021q | |
| parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) | |
Patched in Tegra support.
Diffstat (limited to 'net/8021q')
| -rw-r--r-- | net/8021q/vlan.c | 158 | ||||
| -rw-r--r-- | net/8021q/vlan.h | 43 | ||||
| -rw-r--r-- | net/8021q/vlan_core.c | 295 | ||||
| -rw-r--r-- | net/8021q/vlan_dev.c | 183 | ||||
| -rw-r--r-- | net/8021q/vlan_gvrp.c | 4 | ||||
| -rw-r--r-- | net/8021q/vlan_netlink.c | 25 | ||||
| -rw-r--r-- | net/8021q/vlanproc.c | 44 |
7 files changed, 236 insertions, 516 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index a292e8050ef..8970ba139d7 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c | |||
| @@ -51,6 +51,27 @@ const char vlan_version[] = DRV_VERSION; | |||
| 51 | 51 | ||
| 52 | /* End of global variables definitions. */ | 52 | /* End of global variables definitions. */ |
| 53 | 53 | ||
| 54 | static void vlan_group_free(struct vlan_group *grp) | ||
| 55 | { | ||
| 56 | int i; | ||
| 57 | |||
| 58 | for (i = 0; i < VLAN_GROUP_ARRAY_SPLIT_PARTS; i++) | ||
| 59 | kfree(grp->vlan_devices_arrays[i]); | ||
| 60 | kfree(grp); | ||
| 61 | } | ||
| 62 | |||
| 63 | static struct vlan_group *vlan_group_alloc(struct net_device *real_dev) | ||
| 64 | { | ||
| 65 | struct vlan_group *grp; | ||
| 66 | |||
| 67 | grp = kzalloc(sizeof(struct vlan_group), GFP_KERNEL); | ||
| 68 | if (!grp) | ||
| 69 | return NULL; | ||
| 70 | |||
| 71 | grp->real_dev = real_dev; | ||
| 72 | return grp; | ||
| 73 | } | ||
| 74 | |||
| 54 | static int vlan_group_prealloc_vid(struct vlan_group *vg, u16 vlan_id) | 75 | static int vlan_group_prealloc_vid(struct vlan_group *vg, u16 vlan_id) |
| 55 | { | 76 | { |
| 56 | struct net_device **array; | 77 | struct net_device **array; |
| @@ -71,29 +92,32 @@ static int vlan_group_prealloc_vid(struct vlan_group *vg, u16 vlan_id) | |||
| 71 | return 0; | 92 | return 0; |
| 72 | } | 93 | } |
| 73 | 94 | ||
| 95 | static void vlan_rcu_free(struct rcu_head *rcu) | ||
| 96 | { | ||
| 97 | vlan_group_free(container_of(rcu, struct vlan_group, rcu)); | ||
| 98 | } | ||
| 99 | |||
| 74 | void unregister_vlan_dev(struct net_device *dev, struct list_head *head) | 100 | void unregister_vlan_dev(struct net_device *dev, struct list_head *head) |
| 75 | { | 101 | { |
| 76 | struct vlan_dev_priv *vlan = vlan_dev_priv(dev); | 102 | struct vlan_dev_info *vlan = vlan_dev_info(dev); |
| 77 | struct net_device *real_dev = vlan->real_dev; | 103 | struct net_device *real_dev = vlan->real_dev; |
| 78 | struct vlan_info *vlan_info; | 104 | const struct net_device_ops *ops = real_dev->netdev_ops; |
| 79 | struct vlan_group *grp; | 105 | struct vlan_group *grp; |
| 80 | u16 vlan_id = vlan->vlan_id; | 106 | u16 vlan_id = vlan->vlan_id; |
| 81 | 107 | ||
| 82 | ASSERT_RTNL(); | 108 | ASSERT_RTNL(); |
| 83 | 109 | ||
| 84 | vlan_info = rtnl_dereference(real_dev->vlan_info); | 110 | grp = rtnl_dereference(real_dev->vlgrp); |
| 85 | BUG_ON(!vlan_info); | 111 | BUG_ON(!grp); |
| 86 | |||
| 87 | grp = &vlan_info->grp; | ||
| 88 | 112 | ||
| 89 | /* Take it out of our own structures, but be sure to interlock with | 113 | /* Take it out of our own structures, but be sure to interlock with |
| 90 | * HW accelerating devices or SW vlan input packet processing if | 114 | * HW accelerating devices or SW vlan input packet processing if |
| 91 | * VLAN is not 0 (leave it there for 802.1p). | 115 | * VLAN is not 0 (leave it there for 802.1p). |
| 92 | */ | 116 | */ |
| 93 | if (vlan_id) | 117 | if (vlan_id && (real_dev->features & NETIF_F_HW_VLAN_FILTER)) |
| 94 | vlan_vid_del(real_dev, vlan_id); | 118 | ops->ndo_vlan_rx_kill_vid(real_dev, vlan_id); |
| 95 | 119 | ||
| 96 | grp->nr_vlan_devs--; | 120 | grp->nr_vlans--; |
| 97 | 121 | ||
| 98 | if (vlan->flags & VLAN_FLAG_GVRP) | 122 | if (vlan->flags & VLAN_FLAG_GVRP) |
| 99 | vlan_gvrp_request_leave(dev); | 123 | vlan_gvrp_request_leave(dev); |
| @@ -105,9 +129,16 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head) | |||
| 105 | */ | 129 | */ |
| 106 | unregister_netdevice_queue(dev, head); | 130 | unregister_netdevice_queue(dev, head); |
| 107 | 131 | ||
| 108 | if (grp->nr_vlan_devs == 0) | 132 | /* If the group is now empty, kill off the group. */ |
| 133 | if (grp->nr_vlans == 0) { | ||
| 109 | vlan_gvrp_uninit_applicant(real_dev); | 134 | vlan_gvrp_uninit_applicant(real_dev); |
| 110 | 135 | ||
| 136 | rcu_assign_pointer(real_dev->vlgrp, NULL); | ||
| 137 | |||
| 138 | /* Free the group, after all cpu's are done. */ | ||
| 139 | call_rcu(&grp->rcu, vlan_rcu_free); | ||
| 140 | } | ||
| 141 | |||
| 111 | /* Get rid of the vlan's reference to real_dev */ | 142 | /* Get rid of the vlan's reference to real_dev */ |
| 112 | dev_put(real_dev); | 143 | dev_put(real_dev); |
| 113 | } | 144 | } |
| @@ -136,26 +167,21 @@ int vlan_check_real_dev(struct net_device *real_dev, u16 vlan_id) | |||
| 136 | 167 | ||
| 137 | int register_vlan_dev(struct net_device *dev) | 168 | int register_vlan_dev(struct net_device *dev) |
| 138 | { | 169 | { |
| 139 | struct vlan_dev_priv *vlan = vlan_dev_priv(dev); | 170 | struct vlan_dev_info *vlan = vlan_dev_info(dev); |
| 140 | struct net_device *real_dev = vlan->real_dev; | 171 | struct net_device *real_dev = vlan->real_dev; |
| 172 | const struct net_device_ops *ops = real_dev->netdev_ops; | ||
| 141 | u16 vlan_id = vlan->vlan_id; | 173 | u16 vlan_id = vlan->vlan_id; |
| 142 | struct vlan_info *vlan_info; | 174 | struct vlan_group *grp, *ngrp = NULL; |
| 143 | struct vlan_group *grp; | ||
| 144 | int err; | 175 | int err; |
| 145 | 176 | ||
| 146 | err = vlan_vid_add(real_dev, vlan_id); | 177 | grp = rtnl_dereference(real_dev->vlgrp); |
| 147 | if (err) | 178 | if (!grp) { |
| 148 | return err; | 179 | ngrp = grp = vlan_group_alloc(real_dev); |
| 149 | 180 | if (!grp) | |
| 150 | vlan_info = rtnl_dereference(real_dev->vlan_info); | 181 | return -ENOBUFS; |
| 151 | /* vlan_info should be there now. vlan_vid_add took care of it */ | ||
| 152 | BUG_ON(!vlan_info); | ||
| 153 | |||
| 154 | grp = &vlan_info->grp; | ||
| 155 | if (grp->nr_vlan_devs == 0) { | ||
| 156 | err = vlan_gvrp_init_applicant(real_dev); | 182 | err = vlan_gvrp_init_applicant(real_dev); |
| 157 | if (err < 0) | 183 | if (err < 0) |
| 158 | goto out_vid_del; | 184 | goto out_free_group; |
| 159 | } | 185 | } |
| 160 | 186 | ||
| 161 | err = vlan_group_prealloc_vid(grp, vlan_id); | 187 | err = vlan_group_prealloc_vid(grp, vlan_id); |
| @@ -166,7 +192,7 @@ int register_vlan_dev(struct net_device *dev) | |||
| 166 | if (err < 0) | 192 | if (err < 0) |
| 167 | goto out_uninit_applicant; | 193 | goto out_uninit_applicant; |
| 168 | 194 | ||
| 169 | /* Account for reference in struct vlan_dev_priv */ | 195 | /* Account for reference in struct vlan_dev_info */ |
| 170 | dev_hold(real_dev); | 196 | dev_hold(real_dev); |
| 171 | 197 | ||
| 172 | netif_stacked_transfer_operstate(real_dev, dev); | 198 | netif_stacked_transfer_operstate(real_dev, dev); |
| @@ -176,15 +202,24 @@ int register_vlan_dev(struct net_device *dev) | |||
| 176 | * it into our local structure. | 202 | * it into our local structure. |
| 177 | */ | 203 | */ |
| 178 | vlan_group_set_device(grp, vlan_id, dev); | 204 | vlan_group_set_device(grp, vlan_id, dev); |
| 179 | grp->nr_vlan_devs++; | 205 | grp->nr_vlans++; |
| 206 | |||
| 207 | if (ngrp) { | ||
| 208 | rcu_assign_pointer(real_dev->vlgrp, ngrp); | ||
| 209 | } | ||
| 210 | if (real_dev->features & NETIF_F_HW_VLAN_FILTER) | ||
| 211 | ops->ndo_vlan_rx_add_vid(real_dev, vlan_id); | ||
| 180 | 212 | ||
| 181 | return 0; | 213 | return 0; |
| 182 | 214 | ||
| 183 | out_uninit_applicant: | 215 | out_uninit_applicant: |
| 184 | if (grp->nr_vlan_devs == 0) | 216 | if (ngrp) |
| 185 | vlan_gvrp_uninit_applicant(real_dev); | 217 | vlan_gvrp_uninit_applicant(real_dev); |
| 186 | out_vid_del: | 218 | out_free_group: |
| 187 | vlan_vid_del(real_dev, vlan_id); | 219 | if (ngrp) { |
| 220 | /* Free the group, after all cpu's are done. */ | ||
| 221 | call_rcu(&ngrp->rcu, vlan_rcu_free); | ||
| 222 | } | ||
| 188 | return err; | 223 | return err; |
| 189 | } | 224 | } |
| 190 | 225 | ||
| @@ -232,7 +267,7 @@ static int register_vlan_device(struct net_device *real_dev, u16 vlan_id) | |||
| 232 | snprintf(name, IFNAMSIZ, "vlan%.4i", vlan_id); | 267 | snprintf(name, IFNAMSIZ, "vlan%.4i", vlan_id); |
| 233 | } | 268 | } |
| 234 | 269 | ||
| 235 | new_dev = alloc_netdev(sizeof(struct vlan_dev_priv), name, vlan_setup); | 270 | new_dev = alloc_netdev(sizeof(struct vlan_dev_info), name, vlan_setup); |
| 236 | 271 | ||
| 237 | if (new_dev == NULL) | 272 | if (new_dev == NULL) |
| 238 | return -ENOBUFS; | 273 | return -ENOBUFS; |
| @@ -242,12 +277,11 @@ static int register_vlan_device(struct net_device *real_dev, u16 vlan_id) | |||
| 242 | * hope the underlying device can handle it. | 277 | * hope the underlying device can handle it. |
| 243 | */ | 278 | */ |
| 244 | new_dev->mtu = real_dev->mtu; | 279 | new_dev->mtu = real_dev->mtu; |
| 245 | new_dev->priv_flags |= (real_dev->priv_flags & IFF_UNICAST_FLT); | ||
| 246 | 280 | ||
| 247 | vlan_dev_priv(new_dev)->vlan_id = vlan_id; | 281 | vlan_dev_info(new_dev)->vlan_id = vlan_id; |
| 248 | vlan_dev_priv(new_dev)->real_dev = real_dev; | 282 | vlan_dev_info(new_dev)->real_dev = real_dev; |
| 249 | vlan_dev_priv(new_dev)->dent = NULL; | 283 | vlan_dev_info(new_dev)->dent = NULL; |
| 250 | vlan_dev_priv(new_dev)->flags = VLAN_FLAG_REORDER_HDR; | 284 | vlan_dev_info(new_dev)->flags = VLAN_FLAG_REORDER_HDR; |
| 251 | 285 | ||
| 252 | new_dev->rtnl_link_ops = &vlan_link_ops; | 286 | new_dev->rtnl_link_ops = &vlan_link_ops; |
| 253 | err = register_vlan_dev(new_dev); | 287 | err = register_vlan_dev(new_dev); |
| @@ -264,22 +298,22 @@ out_free_newdev: | |||
| 264 | static void vlan_sync_address(struct net_device *dev, | 298 | static void vlan_sync_address(struct net_device *dev, |
| 265 | struct net_device *vlandev) | 299 | struct net_device *vlandev) |
| 266 | { | 300 | { |
| 267 | struct vlan_dev_priv *vlan = vlan_dev_priv(vlandev); | 301 | struct vlan_dev_info *vlan = vlan_dev_info(vlandev); |
| 268 | 302 | ||
| 269 | /* May be called without an actual change */ | 303 | /* May be called without an actual change */ |
| 270 | if (ether_addr_equal(vlan->real_dev_addr, dev->dev_addr)) | 304 | if (!compare_ether_addr(vlan->real_dev_addr, dev->dev_addr)) |
| 271 | return; | 305 | return; |
| 272 | 306 | ||
| 273 | /* vlan address was different from the old address and is equal to | 307 | /* vlan address was different from the old address and is equal to |
| 274 | * the new address */ | 308 | * the new address */ |
| 275 | if (!ether_addr_equal(vlandev->dev_addr, vlan->real_dev_addr) && | 309 | if (compare_ether_addr(vlandev->dev_addr, vlan->real_dev_addr) && |
| 276 | ether_addr_equal(vlandev->dev_addr, dev->dev_addr)) | 310 | !compare_ether_addr(vlandev->dev_addr, dev->dev_addr)) |
| 277 | dev_uc_del(dev, vlandev->dev_addr); | 311 | dev_uc_del(dev, vlandev->dev_addr); |
| 278 | 312 | ||
| 279 | /* vlan address was equal to the old address and is different from | 313 | /* vlan address was equal to the old address and is different from |
| 280 | * the new address */ | 314 | * the new address */ |
| 281 | if (ether_addr_equal(vlandev->dev_addr, vlan->real_dev_addr) && | 315 | if (!compare_ether_addr(vlandev->dev_addr, vlan->real_dev_addr) && |
| 282 | !ether_addr_equal(vlandev->dev_addr, dev->dev_addr)) | 316 | compare_ether_addr(vlandev->dev_addr, dev->dev_addr)) |
| 283 | dev_uc_add(dev, vlandev->dev_addr); | 317 | dev_uc_add(dev, vlandev->dev_addr); |
| 284 | 318 | ||
| 285 | memcpy(vlan->real_dev_addr, dev->dev_addr, ETH_ALEN); | 319 | memcpy(vlan->real_dev_addr, dev->dev_addr, ETH_ALEN); |
| @@ -295,7 +329,7 @@ static void vlan_transfer_features(struct net_device *dev, | |||
| 295 | else | 329 | else |
| 296 | vlandev->hard_header_len = dev->hard_header_len + VLAN_HLEN; | 330 | vlandev->hard_header_len = dev->hard_header_len + VLAN_HLEN; |
| 297 | 331 | ||
| 298 | #if IS_ENABLED(CONFIG_FCOE) | 332 | #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) |
| 299 | vlandev->fcoe_ddp_xid = dev->fcoe_ddp_xid; | 333 | vlandev->fcoe_ddp_xid = dev->fcoe_ddp_xid; |
| 300 | #endif | 334 | #endif |
| 301 | 335 | ||
| @@ -326,26 +360,25 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, | |||
| 326 | { | 360 | { |
| 327 | struct net_device *dev = ptr; | 361 | struct net_device *dev = ptr; |
| 328 | struct vlan_group *grp; | 362 | struct vlan_group *grp; |
| 329 | struct vlan_info *vlan_info; | ||
| 330 | int i, flgs; | 363 | int i, flgs; |
| 331 | struct net_device *vlandev; | 364 | struct net_device *vlandev; |
| 332 | struct vlan_dev_priv *vlan; | 365 | struct vlan_dev_info *vlan; |
| 333 | LIST_HEAD(list); | 366 | LIST_HEAD(list); |
| 334 | 367 | ||
| 335 | if (is_vlan_dev(dev)) | 368 | if (is_vlan_dev(dev)) |
| 336 | __vlan_device_event(dev, event); | 369 | __vlan_device_event(dev, event); |
| 337 | 370 | ||
| 338 | if ((event == NETDEV_UP) && | 371 | if ((event == NETDEV_UP) && |
| 339 | (dev->features & NETIF_F_HW_VLAN_FILTER)) { | 372 | (dev->features & NETIF_F_HW_VLAN_FILTER) && |
| 373 | dev->netdev_ops->ndo_vlan_rx_add_vid) { | ||
| 340 | pr_info("adding VLAN 0 to HW filter on device %s\n", | 374 | pr_info("adding VLAN 0 to HW filter on device %s\n", |
| 341 | dev->name); | 375 | dev->name); |
| 342 | vlan_vid_add(dev, 0); | 376 | dev->netdev_ops->ndo_vlan_rx_add_vid(dev, 0); |
| 343 | } | 377 | } |
| 344 | 378 | ||
| 345 | vlan_info = rtnl_dereference(dev->vlan_info); | 379 | grp = rtnl_dereference(dev->vlgrp); |
| 346 | if (!vlan_info) | 380 | if (!grp) |
| 347 | goto out; | 381 | goto out; |
| 348 | grp = &vlan_info->grp; | ||
| 349 | 382 | ||
| 350 | /* It is OK that we do not hold the group lock right now, | 383 | /* It is OK that we do not hold the group lock right now, |
| 351 | * as we run under the RTNL lock. | 384 | * as we run under the RTNL lock. |
| @@ -404,9 +437,6 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, | |||
| 404 | break; | 437 | break; |
| 405 | 438 | ||
| 406 | case NETDEV_DOWN: | 439 | case NETDEV_DOWN: |
| 407 | if (dev->features & NETIF_F_HW_VLAN_FILTER) | ||
| 408 | vlan_vid_del(dev, 0); | ||
| 409 | |||
| 410 | /* Put all VLANs for this dev in the down state too. */ | 440 | /* Put all VLANs for this dev in the down state too. */ |
| 411 | for (i = 0; i < VLAN_N_VID; i++) { | 441 | for (i = 0; i < VLAN_N_VID; i++) { |
| 412 | vlandev = vlan_group_get_device(grp, i); | 442 | vlandev = vlan_group_get_device(grp, i); |
| @@ -417,7 +447,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, | |||
| 417 | if (!(flgs & IFF_UP)) | 447 | if (!(flgs & IFF_UP)) |
| 418 | continue; | 448 | continue; |
| 419 | 449 | ||
| 420 | vlan = vlan_dev_priv(vlandev); | 450 | vlan = vlan_dev_info(vlandev); |
| 421 | if (!(vlan->flags & VLAN_FLAG_LOOSE_BINDING)) | 451 | if (!(vlan->flags & VLAN_FLAG_LOOSE_BINDING)) |
| 422 | dev_change_flags(vlandev, flgs & ~IFF_UP); | 452 | dev_change_flags(vlandev, flgs & ~IFF_UP); |
| 423 | netif_stacked_transfer_operstate(dev, vlandev); | 453 | netif_stacked_transfer_operstate(dev, vlandev); |
| @@ -435,7 +465,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, | |||
| 435 | if (flgs & IFF_UP) | 465 | if (flgs & IFF_UP) |
| 436 | continue; | 466 | continue; |
| 437 | 467 | ||
| 438 | vlan = vlan_dev_priv(vlandev); | 468 | vlan = vlan_dev_info(vlandev); |
| 439 | if (!(vlan->flags & VLAN_FLAG_LOOSE_BINDING)) | 469 | if (!(vlan->flags & VLAN_FLAG_LOOSE_BINDING)) |
| 440 | dev_change_flags(vlandev, flgs | IFF_UP); | 470 | dev_change_flags(vlandev, flgs | IFF_UP); |
| 441 | netif_stacked_transfer_operstate(dev, vlandev); | 471 | netif_stacked_transfer_operstate(dev, vlandev); |
| @@ -452,9 +482,9 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, | |||
| 452 | if (!vlandev) | 482 | if (!vlandev) |
| 453 | continue; | 483 | continue; |
| 454 | 484 | ||
| 455 | /* removal of last vid destroys vlan_info, abort | 485 | /* unregistration of last vlan destroys group, abort |
| 456 | * afterwards */ | 486 | * afterwards */ |
| 457 | if (vlan_info->nr_vids == 1) | 487 | if (grp->nr_vlans == 1) |
| 458 | i = VLAN_N_VID; | 488 | i = VLAN_N_VID; |
| 459 | 489 | ||
| 460 | unregister_vlan_dev(vlandev, &list); | 490 | unregister_vlan_dev(vlandev, &list); |
| @@ -464,9 +494,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, | |||
| 464 | 494 | ||
| 465 | case NETDEV_PRE_TYPE_CHANGE: | 495 | case NETDEV_PRE_TYPE_CHANGE: |
| 466 | /* Forbid underlaying device to change its type. */ | 496 | /* Forbid underlaying device to change its type. */ |
| 467 | if (vlan_uses_dev(dev)) | 497 | return NOTIFY_BAD; |
| 468 | return NOTIFY_BAD; | ||
| 469 | break; | ||
| 470 | 498 | ||
| 471 | case NETDEV_NOTIFY_PEERS: | 499 | case NETDEV_NOTIFY_PEERS: |
| 472 | case NETDEV_BONDING_FAILOVER: | 500 | case NETDEV_BONDING_FAILOVER: |
| @@ -530,7 +558,7 @@ static int vlan_ioctl_handler(struct net *net, void __user *arg) | |||
| 530 | switch (args.cmd) { | 558 | switch (args.cmd) { |
| 531 | case SET_VLAN_INGRESS_PRIORITY_CMD: | 559 | case SET_VLAN_INGRESS_PRIORITY_CMD: |
| 532 | err = -EPERM; | 560 | err = -EPERM; |
| 533 | if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) | 561 | if (!capable(CAP_NET_ADMIN)) |
| 534 | break; | 562 | break; |
| 535 | vlan_dev_set_ingress_priority(dev, | 563 | vlan_dev_set_ingress_priority(dev, |
| 536 | args.u.skb_priority, | 564 | args.u.skb_priority, |
| @@ -540,7 +568,7 @@ static int vlan_ioctl_handler(struct net *net, void __user *arg) | |||
| 540 | 568 | ||
| 541 | case SET_VLAN_EGRESS_PRIORITY_CMD: | 569 | case SET_VLAN_EGRESS_PRIORITY_CMD: |
| 542 | err = -EPERM; | 570 | err = -EPERM; |
| 543 | if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) | 571 | if (!capable(CAP_NET_ADMIN)) |
| 544 | break; | 572 | break; |
| 545 | err = vlan_dev_set_egress_priority(dev, | 573 | err = vlan_dev_set_egress_priority(dev, |
| 546 | args.u.skb_priority, | 574 | args.u.skb_priority, |
| @@ -549,7 +577,7 @@ static int vlan_ioctl_handler(struct net *net, void __user *arg) | |||
| 549 | 577 | ||
| 550 | case SET_VLAN_FLAG_CMD: | 578 | case SET_VLAN_FLAG_CMD: |
| 551 | err = -EPERM; | 579 | err = -EPERM; |
| 552 | if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) | 580 | if (!capable(CAP_NET_ADMIN)) |
| 553 | break; | 581 | break; |
| 554 | err = vlan_dev_change_flags(dev, | 582 | err = vlan_dev_change_flags(dev, |
| 555 | args.vlan_qos ? args.u.flag : 0, | 583 | args.vlan_qos ? args.u.flag : 0, |
| @@ -558,7 +586,7 @@ static int vlan_ioctl_handler(struct net *net, void __user *arg) | |||
| 558 | 586 | ||
| 559 | case SET_VLAN_NAME_TYPE_CMD: | 587 | case SET_VLAN_NAME_TYPE_CMD: |
| 560 | err = -EPERM; | 588 | err = -EPERM; |
| 561 | if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) | 589 | if (!capable(CAP_NET_ADMIN)) |
| 562 | break; | 590 | break; |
| 563 | if ((args.u.name_type >= 0) && | 591 | if ((args.u.name_type >= 0) && |
| 564 | (args.u.name_type < VLAN_NAME_TYPE_HIGHEST)) { | 592 | (args.u.name_type < VLAN_NAME_TYPE_HIGHEST)) { |
| @@ -574,14 +602,14 @@ static int vlan_ioctl_handler(struct net *net, void __user *arg) | |||
| 574 | 602 | ||
| 575 | case ADD_VLAN_CMD: | 603 | case ADD_VLAN_CMD: |
| 576 | err = -EPERM; | 604 | err = -EPERM; |
| 577 | if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) | 605 | if (!capable(CAP_NET_ADMIN)) |
| 578 | break; | 606 | break; |
| 579 | err = register_vlan_device(dev, args.u.VID); | 607 | err = register_vlan_device(dev, args.u.VID); |
| 580 | break; | 608 | break; |
| 581 | 609 | ||
| 582 | case DEL_VLAN_CMD: | 610 | case DEL_VLAN_CMD: |
| 583 | err = -EPERM; | 611 | err = -EPERM; |
| 584 | if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) | 612 | if (!capable(CAP_NET_ADMIN)) |
| 585 | break; | 613 | break; |
| 586 | unregister_vlan_dev(dev, NULL); | 614 | unregister_vlan_dev(dev, NULL); |
| 587 | err = 0; | 615 | err = 0; |
diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h index a4886d94c40..9fd45f3571f 100644 --- a/net/8021q/vlan.h +++ b/net/8021q/vlan.h | |||
| @@ -3,7 +3,6 @@ | |||
| 3 | 3 | ||
| 4 | #include <linux/if_vlan.h> | 4 | #include <linux/if_vlan.h> |
| 5 | #include <linux/u64_stats_sync.h> | 5 | #include <linux/u64_stats_sync.h> |
| 6 | #include <linux/list.h> | ||
| 7 | 6 | ||
| 8 | 7 | ||
| 9 | /** | 8 | /** |
| @@ -41,10 +40,8 @@ struct vlan_pcpu_stats { | |||
| 41 | u32 tx_dropped; | 40 | u32 tx_dropped; |
| 42 | }; | 41 | }; |
| 43 | 42 | ||
| 44 | struct netpoll; | ||
| 45 | |||
| 46 | /** | 43 | /** |
| 47 | * struct vlan_dev_priv - VLAN private device data | 44 | * struct vlan_dev_info - VLAN private device data |
| 48 | * @nr_ingress_mappings: number of ingress priority mappings | 45 | * @nr_ingress_mappings: number of ingress priority mappings |
| 49 | * @ingress_priority_map: ingress priority mappings | 46 | * @ingress_priority_map: ingress priority mappings |
| 50 | * @nr_egress_mappings: number of egress priority mappings | 47 | * @nr_egress_mappings: number of egress priority mappings |
| @@ -56,7 +53,7 @@ struct netpoll; | |||
| 56 | * @dent: proc dir entry | 53 | * @dent: proc dir entry |
| 57 | * @vlan_pcpu_stats: ptr to percpu rx stats | 54 | * @vlan_pcpu_stats: ptr to percpu rx stats |
| 58 | */ | 55 | */ |
| 59 | struct vlan_dev_priv { | 56 | struct vlan_dev_info { |
| 60 | unsigned int nr_ingress_mappings; | 57 | unsigned int nr_ingress_mappings; |
| 61 | u32 ingress_priority_map[8]; | 58 | u32 ingress_priority_map[8]; |
| 62 | unsigned int nr_egress_mappings; | 59 | unsigned int nr_egress_mappings; |
| @@ -70,39 +67,13 @@ struct vlan_dev_priv { | |||
| 70 | 67 | ||
| 71 | struct proc_dir_entry *dent; | 68 | struct proc_dir_entry *dent; |
| 72 | struct vlan_pcpu_stats __percpu *vlan_pcpu_stats; | 69 | struct vlan_pcpu_stats __percpu *vlan_pcpu_stats; |
| 73 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
| 74 | struct netpoll *netpoll; | ||
| 75 | #endif | ||
| 76 | }; | 70 | }; |
| 77 | 71 | ||
| 78 | static inline struct vlan_dev_priv *vlan_dev_priv(const struct net_device *dev) | 72 | static inline struct vlan_dev_info *vlan_dev_info(const struct net_device *dev) |
| 79 | { | 73 | { |
| 80 | return netdev_priv(dev); | 74 | return netdev_priv(dev); |
| 81 | } | 75 | } |
| 82 | 76 | ||
| 83 | /* if this changes, algorithm will have to be reworked because this | ||
| 84 | * depends on completely exhausting the VLAN identifier space. Thus | ||
| 85 | * it gives constant time look-up, but in many cases it wastes memory. | ||
| 86 | */ | ||
| 87 | #define VLAN_GROUP_ARRAY_SPLIT_PARTS 8 | ||
| 88 | #define VLAN_GROUP_ARRAY_PART_LEN (VLAN_N_VID/VLAN_GROUP_ARRAY_SPLIT_PARTS) | ||
| 89 | |||
| 90 | struct vlan_group { | ||
| 91 | unsigned int nr_vlan_devs; | ||
| 92 | struct hlist_node hlist; /* linked list */ | ||
| 93 | struct net_device **vlan_devices_arrays[VLAN_GROUP_ARRAY_SPLIT_PARTS]; | ||
| 94 | }; | ||
| 95 | |||
| 96 | struct vlan_info { | ||
| 97 | struct net_device *real_dev; /* The ethernet(like) device | ||
| 98 | * the vlan is attached to. | ||
| 99 | */ | ||
| 100 | struct vlan_group grp; | ||
| 101 | struct list_head vid_list; | ||
| 102 | unsigned int nr_vids; | ||
| 103 | struct rcu_head rcu; | ||
| 104 | }; | ||
| 105 | |||
| 106 | static inline struct net_device *vlan_group_get_device(struct vlan_group *vg, | 77 | static inline struct net_device *vlan_group_get_device(struct vlan_group *vg, |
| 107 | u16 vlan_id) | 78 | u16 vlan_id) |
| 108 | { | 79 | { |
| @@ -126,10 +97,10 @@ static inline void vlan_group_set_device(struct vlan_group *vg, | |||
| 126 | static inline struct net_device *vlan_find_dev(struct net_device *real_dev, | 97 | static inline struct net_device *vlan_find_dev(struct net_device *real_dev, |
| 127 | u16 vlan_id) | 98 | u16 vlan_id) |
| 128 | { | 99 | { |
| 129 | struct vlan_info *vlan_info = rcu_dereference_rtnl(real_dev->vlan_info); | 100 | struct vlan_group *grp = rcu_dereference_rtnl(real_dev->vlgrp); |
| 130 | 101 | ||
| 131 | if (vlan_info) | 102 | if (grp) |
| 132 | return vlan_group_get_device(&vlan_info->grp, vlan_id); | 103 | return vlan_group_get_device(grp, vlan_id); |
| 133 | 104 | ||
| 134 | return NULL; | 105 | return NULL; |
| 135 | } | 106 | } |
| @@ -150,7 +121,7 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head); | |||
| 150 | static inline u32 vlan_get_ingress_priority(struct net_device *dev, | 121 | static inline u32 vlan_get_ingress_priority(struct net_device *dev, |
| 151 | u16 vlan_tci) | 122 | u16 vlan_tci) |
| 152 | { | 123 | { |
| 153 | struct vlan_dev_priv *vip = vlan_dev_priv(dev); | 124 | struct vlan_dev_info *vip = vlan_dev_info(dev); |
| 154 | 125 | ||
| 155 | return vip->ingress_priority_map[(vlan_tci >> VLAN_PRIO_SHIFT) & 0x7]; | 126 | return vip->ingress_priority_map[(vlan_tci >> VLAN_PRIO_SHIFT) & 0x7]; |
| 156 | } | 127 | } |
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index 65e06abe023..f1f2f7bb666 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | #include <linux/netdevice.h> | 2 | #include <linux/netdevice.h> |
| 3 | #include <linux/if_vlan.h> | 3 | #include <linux/if_vlan.h> |
| 4 | #include <linux/netpoll.h> | 4 | #include <linux/netpoll.h> |
| 5 | #include <linux/export.h> | ||
| 6 | #include "vlan.h" | 5 | #include "vlan.h" |
| 7 | 6 | ||
| 8 | bool vlan_do_receive(struct sk_buff **skbp) | 7 | bool vlan_do_receive(struct sk_buff **skbp) |
| @@ -13,8 +12,11 @@ bool vlan_do_receive(struct sk_buff **skbp) | |||
| 13 | struct vlan_pcpu_stats *rx_stats; | 12 | struct vlan_pcpu_stats *rx_stats; |
| 14 | 13 | ||
| 15 | vlan_dev = vlan_find_dev(skb->dev, vlan_id); | 14 | vlan_dev = vlan_find_dev(skb->dev, vlan_id); |
| 16 | if (!vlan_dev) | 15 | if (!vlan_dev) { |
| 16 | if (vlan_id) | ||
| 17 | skb->pkt_type = PACKET_OTHERHOST; | ||
| 17 | return false; | 18 | return false; |
| 19 | } | ||
| 18 | 20 | ||
| 19 | skb = *skbp = skb_share_check(skb, GFP_ATOMIC); | 21 | skb = *skbp = skb_share_check(skb, GFP_ATOMIC); |
| 20 | if (unlikely(!skb)) | 22 | if (unlikely(!skb)) |
| @@ -25,11 +27,12 @@ bool vlan_do_receive(struct sk_buff **skbp) | |||
| 25 | /* Our lower layer thinks this is not local, let's make sure. | 27 | /* Our lower layer thinks this is not local, let's make sure. |
| 26 | * This allows the VLAN to have a different MAC than the | 28 | * This allows the VLAN to have a different MAC than the |
| 27 | * underlying device, and still route correctly. */ | 29 | * underlying device, and still route correctly. */ |
| 28 | if (ether_addr_equal(eth_hdr(skb)->h_dest, vlan_dev->dev_addr)) | 30 | if (!compare_ether_addr(eth_hdr(skb)->h_dest, |
| 31 | vlan_dev->dev_addr)) | ||
| 29 | skb->pkt_type = PACKET_HOST; | 32 | skb->pkt_type = PACKET_HOST; |
| 30 | } | 33 | } |
| 31 | 34 | ||
| 32 | if (!(vlan_dev_priv(vlan_dev)->flags & VLAN_FLAG_REORDER_HDR)) { | 35 | if (!(vlan_dev_info(vlan_dev)->flags & VLAN_FLAG_REORDER_HDR)) { |
| 33 | unsigned int offset = skb->data - skb_mac_header(skb); | 36 | unsigned int offset = skb->data - skb_mac_header(skb); |
| 34 | 37 | ||
| 35 | /* | 38 | /* |
| @@ -48,7 +51,7 @@ bool vlan_do_receive(struct sk_buff **skbp) | |||
| 48 | skb->priority = vlan_get_ingress_priority(vlan_dev, skb->vlan_tci); | 51 | skb->priority = vlan_get_ingress_priority(vlan_dev, skb->vlan_tci); |
| 49 | skb->vlan_tci = 0; | 52 | skb->vlan_tci = 0; |
| 50 | 53 | ||
| 51 | rx_stats = this_cpu_ptr(vlan_dev_priv(vlan_dev)->vlan_pcpu_stats); | 54 | rx_stats = this_cpu_ptr(vlan_dev_info(vlan_dev)->vlan_pcpu_stats); |
| 52 | 55 | ||
| 53 | u64_stats_update_begin(&rx_stats->syncp); | 56 | u64_stats_update_begin(&rx_stats->syncp); |
| 54 | rx_stats->rx_packets++; | 57 | rx_stats->rx_packets++; |
| @@ -64,10 +67,10 @@ bool vlan_do_receive(struct sk_buff **skbp) | |||
| 64 | struct net_device *__vlan_find_dev_deep(struct net_device *real_dev, | 67 | struct net_device *__vlan_find_dev_deep(struct net_device *real_dev, |
| 65 | u16 vlan_id) | 68 | u16 vlan_id) |
| 66 | { | 69 | { |
| 67 | struct vlan_info *vlan_info = rcu_dereference_rtnl(real_dev->vlan_info); | 70 | struct vlan_group *grp = rcu_dereference_rtnl(real_dev->vlgrp); |
| 68 | 71 | ||
| 69 | if (vlan_info) { | 72 | if (grp) { |
| 70 | return vlan_group_get_device(&vlan_info->grp, vlan_id); | 73 | return vlan_group_get_device(grp, vlan_id); |
| 71 | } else { | 74 | } else { |
| 72 | /* | 75 | /* |
| 73 | * Bonding slaves do not have grp assigned to themselves. | 76 | * Bonding slaves do not have grp assigned to themselves. |
| @@ -83,13 +86,13 @@ EXPORT_SYMBOL(__vlan_find_dev_deep); | |||
| 83 | 86 | ||
| 84 | struct net_device *vlan_dev_real_dev(const struct net_device *dev) | 87 | struct net_device *vlan_dev_real_dev(const struct net_device *dev) |
| 85 | { | 88 | { |
| 86 | return vlan_dev_priv(dev)->real_dev; | 89 | return vlan_dev_info(dev)->real_dev; |
| 87 | } | 90 | } |
| 88 | EXPORT_SYMBOL(vlan_dev_real_dev); | 91 | EXPORT_SYMBOL(vlan_dev_real_dev); |
| 89 | 92 | ||
| 90 | u16 vlan_dev_vlan_id(const struct net_device *dev) | 93 | u16 vlan_dev_vlan_id(const struct net_device *dev) |
| 91 | { | 94 | { |
| 92 | return vlan_dev_priv(dev)->vlan_id; | 95 | return vlan_dev_info(dev)->vlan_id; |
| 93 | } | 96 | } |
| 94 | EXPORT_SYMBOL(vlan_dev_vlan_id); | 97 | EXPORT_SYMBOL(vlan_dev_vlan_id); |
| 95 | 98 | ||
| @@ -99,9 +102,43 @@ static struct sk_buff *vlan_reorder_header(struct sk_buff *skb) | |||
| 99 | return NULL; | 102 | return NULL; |
| 100 | memmove(skb->data - ETH_HLEN, skb->data - VLAN_ETH_HLEN, 2 * ETH_ALEN); | 103 | memmove(skb->data - ETH_HLEN, skb->data - VLAN_ETH_HLEN, 2 * ETH_ALEN); |
| 101 | skb->mac_header += VLAN_HLEN; | 104 | skb->mac_header += VLAN_HLEN; |
| 105 | skb_reset_mac_len(skb); | ||
| 102 | return skb; | 106 | return skb; |
| 103 | } | 107 | } |
| 104 | 108 | ||
| 109 | static void vlan_set_encap_proto(struct sk_buff *skb, struct vlan_hdr *vhdr) | ||
| 110 | { | ||
| 111 | __be16 proto; | ||
| 112 | unsigned char *rawp; | ||
| 113 | |||
| 114 | /* | ||
| 115 | * Was a VLAN packet, grab the encapsulated protocol, which the layer | ||
| 116 | * three protocols care about. | ||
| 117 | */ | ||
| 118 | |||
| 119 | proto = vhdr->h_vlan_encapsulated_proto; | ||
| 120 | if (ntohs(proto) >= 1536) { | ||
| 121 | skb->protocol = proto; | ||
| 122 | return; | ||
| 123 | } | ||
| 124 | |||
| 125 | rawp = skb->data; | ||
| 126 | if (*(unsigned short *) rawp == 0xFFFF) | ||
| 127 | /* | ||
| 128 | * This is a magic hack to spot IPX packets. Older Novell | ||
| 129 | * breaks the protocol design and runs IPX over 802.3 without | ||
| 130 | * an 802.2 LLC layer. We look for FFFF which isn't a used | ||
| 131 | * 802.2 SSAP/DSAP. This won't work for fault tolerant netware | ||
| 132 | * but does for the rest. | ||
| 133 | */ | ||
| 134 | skb->protocol = htons(ETH_P_802_3); | ||
| 135 | else | ||
| 136 | /* | ||
| 137 | * Real 802.2 LLC | ||
| 138 | */ | ||
| 139 | skb->protocol = htons(ETH_P_802_2); | ||
| 140 | } | ||
| 141 | |||
| 105 | struct sk_buff *vlan_untag(struct sk_buff *skb) | 142 | struct sk_buff *vlan_untag(struct sk_buff *skb) |
| 106 | { | 143 | { |
| 107 | struct vlan_hdr *vhdr; | 144 | struct vlan_hdr *vhdr; |
| @@ -132,247 +169,9 @@ struct sk_buff *vlan_untag(struct sk_buff *skb) | |||
| 132 | 169 | ||
| 133 | skb_reset_network_header(skb); | 170 | skb_reset_network_header(skb); |
| 134 | skb_reset_transport_header(skb); | 171 | skb_reset_transport_header(skb); |
| 135 | skb_reset_mac_len(skb); | ||
| 136 | |||
| 137 | return skb; | 172 | return skb; |
| 138 | 173 | ||
| 139 | err_free: | 174 | err_free: |
| 140 | kfree_skb(skb); | 175 | kfree_skb(skb); |
| 141 | return NULL; | 176 | return NULL; |
| 142 | } | 177 | } |
| 143 | |||
| 144 | |||
| 145 | /* | ||
| 146 | * vlan info and vid list | ||
| 147 | */ | ||
| 148 | |||
| 149 | static void vlan_group_free(struct vlan_group *grp) | ||
| 150 | { | ||
| 151 | int i; | ||
| 152 | |||
| 153 | for (i = 0; i < VLAN_GROUP_ARRAY_SPLIT_PARTS; i++) | ||
| 154 | kfree(grp->vlan_devices_arrays[i]); | ||
| 155 | } | ||
| 156 | |||
| 157 | static void vlan_info_free(struct vlan_info *vlan_info) | ||
| 158 | { | ||
| 159 | vlan_group_free(&vlan_info->grp); | ||
| 160 | kfree(vlan_info); | ||
| 161 | } | ||
| 162 | |||
| 163 | static void vlan_info_rcu_free(struct rcu_head *rcu) | ||
| 164 | { | ||
| 165 | vlan_info_free(container_of(rcu, struct vlan_info, rcu)); | ||
| 166 | } | ||
| 167 | |||
| 168 | static struct vlan_info *vlan_info_alloc(struct net_device *dev) | ||
| 169 | { | ||
| 170 | struct vlan_info *vlan_info; | ||
| 171 | |||
| 172 | vlan_info = kzalloc(sizeof(struct vlan_info), GFP_KERNEL); | ||
| 173 | if (!vlan_info) | ||
| 174 | return NULL; | ||
| 175 | |||
| 176 | vlan_info->real_dev = dev; | ||
| 177 | INIT_LIST_HEAD(&vlan_info->vid_list); | ||
| 178 | return vlan_info; | ||
| 179 | } | ||
| 180 | |||
| 181 | struct vlan_vid_info { | ||
| 182 | struct list_head list; | ||
| 183 | unsigned short vid; | ||
| 184 | int refcount; | ||
| 185 | }; | ||
| 186 | |||
| 187 | static struct vlan_vid_info *vlan_vid_info_get(struct vlan_info *vlan_info, | ||
| 188 | unsigned short vid) | ||
| 189 | { | ||
| 190 | struct vlan_vid_info *vid_info; | ||
| 191 | |||
| 192 | list_for_each_entry(vid_info, &vlan_info->vid_list, list) { | ||
| 193 | if (vid_info->vid == vid) | ||
| 194 | return vid_info; | ||
| 195 | } | ||
| 196 | return NULL; | ||
| 197 | } | ||
| 198 | |||
| 199 | static struct vlan_vid_info *vlan_vid_info_alloc(unsigned short vid) | ||
| 200 | { | ||
| 201 | struct vlan_vid_info *vid_info; | ||
| 202 | |||
| 203 | vid_info = kzalloc(sizeof(struct vlan_vid_info), GFP_KERNEL); | ||
| 204 | if (!vid_info) | ||
| 205 | return NULL; | ||
| 206 | vid_info->vid = vid; | ||
| 207 | |||
| 208 | return vid_info; | ||
| 209 | } | ||
| 210 | |||
| 211 | static int __vlan_vid_add(struct vlan_info *vlan_info, unsigned short vid, | ||
| 212 | struct vlan_vid_info **pvid_info) | ||
| 213 | { | ||
| 214 | struct net_device *dev = vlan_info->real_dev; | ||
| 215 | const struct net_device_ops *ops = dev->netdev_ops; | ||
| 216 | struct vlan_vid_info *vid_info; | ||
| 217 | int err; | ||
| 218 | |||
| 219 | vid_info = vlan_vid_info_alloc(vid); | ||
| 220 | if (!vid_info) | ||
| 221 | return -ENOMEM; | ||
| 222 | |||
| 223 | if ((dev->features & NETIF_F_HW_VLAN_FILTER) && | ||
| 224 | ops->ndo_vlan_rx_add_vid) { | ||
| 225 | err = ops->ndo_vlan_rx_add_vid(dev, vid); | ||
| 226 | if (err) { | ||
| 227 | kfree(vid_info); | ||
| 228 | return err; | ||
| 229 | } | ||
| 230 | } | ||
| 231 | list_add(&vid_info->list, &vlan_info->vid_list); | ||
| 232 | vlan_info->nr_vids++; | ||
| 233 | *pvid_info = vid_info; | ||
| 234 | return 0; | ||
| 235 | } | ||
| 236 | |||
| 237 | int vlan_vid_add(struct net_device *dev, unsigned short vid) | ||
| 238 | { | ||
| 239 | struct vlan_info *vlan_info; | ||
| 240 | struct vlan_vid_info *vid_info; | ||
| 241 | bool vlan_info_created = false; | ||
| 242 | int err; | ||
| 243 | |||
| 244 | ASSERT_RTNL(); | ||
| 245 | |||
| 246 | vlan_info = rtnl_dereference(dev->vlan_info); | ||
| 247 | if (!vlan_info) { | ||
| 248 | vlan_info = vlan_info_alloc(dev); | ||
| 249 | if (!vlan_info) | ||
| 250 | return -ENOMEM; | ||
| 251 | vlan_info_created = true; | ||
| 252 | } | ||
| 253 | vid_info = vlan_vid_info_get(vlan_info, vid); | ||
| 254 | if (!vid_info) { | ||
| 255 | err = __vlan_vid_add(vlan_info, vid, &vid_info); | ||
| 256 | if (err) | ||
| 257 | goto out_free_vlan_info; | ||
| 258 | } | ||
| 259 | vid_info->refcount++; | ||
| 260 | |||
| 261 | if (vlan_info_created) | ||
| 262 | rcu_assign_pointer(dev->vlan_info, vlan_info); | ||
| 263 | |||
| 264 | return 0; | ||
| 265 | |||
| 266 | out_free_vlan_info: | ||
| 267 | if (vlan_info_created) | ||
| 268 | kfree(vlan_info); | ||
| 269 | return err; | ||
| 270 | } | ||
| 271 | EXPORT_SYMBOL(vlan_vid_add); | ||
| 272 | |||
| 273 | static void __vlan_vid_del(struct vlan_info *vlan_info, | ||
| 274 | struct vlan_vid_info *vid_info) | ||
| 275 | { | ||
| 276 | struct net_device *dev = vlan_info->real_dev; | ||
| 277 | const struct net_device_ops *ops = dev->netdev_ops; | ||
| 278 | unsigned short vid = vid_info->vid; | ||
| 279 | int err; | ||
| 280 | |||
| 281 | if ((dev->features & NETIF_F_HW_VLAN_FILTER) && | ||
| 282 | ops->ndo_vlan_rx_kill_vid) { | ||
| 283 | err = ops->ndo_vlan_rx_kill_vid(dev, vid); | ||
| 284 | if (err) { | ||
| 285 | pr_warn("failed to kill vid %d for device %s\n", | ||
| 286 | vid, dev->name); | ||
| 287 | } | ||
| 288 | } | ||
| 289 | list_del(&vid_info->list); | ||
| 290 | kfree(vid_info); | ||
| 291 | vlan_info->nr_vids--; | ||
| 292 | } | ||
| 293 | |||
| 294 | void vlan_vid_del(struct net_device *dev, unsigned short vid) | ||
| 295 | { | ||
| 296 | struct vlan_info *vlan_info; | ||
| 297 | struct vlan_vid_info *vid_info; | ||
| 298 | |||
| 299 | ASSERT_RTNL(); | ||
| 300 | |||
| 301 | vlan_info = rtnl_dereference(dev->vlan_info); | ||
| 302 | if (!vlan_info) | ||
| 303 | return; | ||
| 304 | |||
| 305 | vid_info = vlan_vid_info_get(vlan_info, vid); | ||
| 306 | if (!vid_info) | ||
| 307 | return; | ||
| 308 | vid_info->refcount--; | ||
| 309 | if (vid_info->refcount == 0) { | ||
| 310 | __vlan_vid_del(vlan_info, vid_info); | ||
| 311 | if (vlan_info->nr_vids == 0) { | ||
| 312 | RCU_INIT_POINTER(dev->vlan_info, NULL); | ||
| 313 | call_rcu(&vlan_info->rcu, vlan_info_rcu_free); | ||
| 314 | } | ||
| 315 | } | ||
| 316 | } | ||
| 317 | EXPORT_SYMBOL(vlan_vid_del); | ||
| 318 | |||
| 319 | int vlan_vids_add_by_dev(struct net_device *dev, | ||
| 320 | const struct net_device *by_dev) | ||
| 321 | { | ||
| 322 | struct vlan_vid_info *vid_info; | ||
| 323 | struct vlan_info *vlan_info; | ||
| 324 | int err; | ||
| 325 | |||
| 326 | ASSERT_RTNL(); | ||
| 327 | |||
| 328 | vlan_info = rtnl_dereference(by_dev->vlan_info); | ||
| 329 | if (!vlan_info) | ||
| 330 | return 0; | ||
| 331 | |||
| 332 | list_for_each_entry(vid_info, &vlan_info->vid_list, list) { | ||
| 333 | err = vlan_vid_add(dev, vid_info->vid); | ||
| 334 | if (err) | ||
| 335 | goto unwind; | ||
| 336 | } | ||
| 337 | return 0; | ||
| 338 | |||
| 339 | unwind: | ||
| 340 | list_for_each_entry_continue_reverse(vid_info, | ||
| 341 | &vlan_info->vid_list, | ||
| 342 | list) { | ||
| 343 | vlan_vid_del(dev, vid_info->vid); | ||
| 344 | } | ||
| 345 | |||
| 346 | return err; | ||
| 347 | } | ||
| 348 | EXPORT_SYMBOL(vlan_vids_add_by_dev); | ||
| 349 | |||
| 350 | void vlan_vids_del_by_dev(struct net_device *dev, | ||
| 351 | const struct net_device *by_dev) | ||
| 352 | { | ||
| 353 | struct vlan_vid_info *vid_info; | ||
| 354 | struct vlan_info *vlan_info; | ||
| 355 | |||
| 356 | ASSERT_RTNL(); | ||
| 357 | |||
| 358 | vlan_info = rtnl_dereference(by_dev->vlan_info); | ||
| 359 | if (!vlan_info) | ||
| 360 | return; | ||
| 361 | |||
| 362 | list_for_each_entry(vid_info, &vlan_info->vid_list, list) | ||
| 363 | vlan_vid_del(dev, vid_info->vid); | ||
| 364 | } | ||
| 365 | EXPORT_SYMBOL(vlan_vids_del_by_dev); | ||
| 366 | |||
| 367 | bool vlan_uses_dev(const struct net_device *dev) | ||
| 368 | { | ||
| 369 | struct vlan_info *vlan_info; | ||
| 370 | |||
| 371 | ASSERT_RTNL(); | ||
| 372 | |||
| 373 | vlan_info = rtnl_dereference(dev->vlan_info); | ||
| 374 | if (!vlan_info) | ||
| 375 | return false; | ||
| 376 | return vlan_info->grp.nr_vlan_devs ? true : false; | ||
| 377 | } | ||
| 378 | EXPORT_SYMBOL(vlan_uses_dev); | ||
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 4a6d31a082b..9d40a071d03 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
| @@ -33,7 +33,6 @@ | |||
| 33 | #include "vlan.h" | 33 | #include "vlan.h" |
| 34 | #include "vlanproc.h" | 34 | #include "vlanproc.h" |
| 35 | #include <linux/if_vlan.h> | 35 | #include <linux/if_vlan.h> |
| 36 | #include <linux/netpoll.h> | ||
| 37 | 36 | ||
| 38 | /* | 37 | /* |
| 39 | * Rebuild the Ethernet MAC header. This is called after an ARP | 38 | * Rebuild the Ethernet MAC header. This is called after an ARP |
| @@ -73,7 +72,7 @@ vlan_dev_get_egress_qos_mask(struct net_device *dev, struct sk_buff *skb) | |||
| 73 | { | 72 | { |
| 74 | struct vlan_priority_tci_mapping *mp; | 73 | struct vlan_priority_tci_mapping *mp; |
| 75 | 74 | ||
| 76 | mp = vlan_dev_priv(dev)->egress_priority_map[(skb->priority & 0xF)]; | 75 | mp = vlan_dev_info(dev)->egress_priority_map[(skb->priority & 0xF)]; |
| 77 | while (mp) { | 76 | while (mp) { |
| 78 | if (mp->priority == skb->priority) { | 77 | if (mp->priority == skb->priority) { |
| 79 | return mp->vlan_qos; /* This should already be shifted | 78 | return mp->vlan_qos; /* This should already be shifted |
| @@ -104,10 +103,10 @@ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev, | |||
| 104 | u16 vlan_tci = 0; | 103 | u16 vlan_tci = 0; |
| 105 | int rc; | 104 | int rc; |
| 106 | 105 | ||
| 107 | if (!(vlan_dev_priv(dev)->flags & VLAN_FLAG_REORDER_HDR)) { | 106 | if (!(vlan_dev_info(dev)->flags & VLAN_FLAG_REORDER_HDR)) { |
| 108 | vhdr = (struct vlan_hdr *) skb_push(skb, VLAN_HLEN); | 107 | vhdr = (struct vlan_hdr *) skb_push(skb, VLAN_HLEN); |
| 109 | 108 | ||
| 110 | vlan_tci = vlan_dev_priv(dev)->vlan_id; | 109 | vlan_tci = vlan_dev_info(dev)->vlan_id; |
| 111 | vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb); | 110 | vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb); |
| 112 | vhdr->h_vlan_TCI = htons(vlan_tci); | 111 | vhdr->h_vlan_TCI = htons(vlan_tci); |
| 113 | 112 | ||
| @@ -130,28 +129,16 @@ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev, | |||
| 130 | saddr = dev->dev_addr; | 129 | saddr = dev->dev_addr; |
| 131 | 130 | ||
| 132 | /* Now make the underlying real hard header */ | 131 | /* Now make the underlying real hard header */ |
| 133 | dev = vlan_dev_priv(dev)->real_dev; | 132 | dev = vlan_dev_info(dev)->real_dev; |
| 134 | rc = dev_hard_header(skb, dev, type, daddr, saddr, len + vhdrlen); | 133 | rc = dev_hard_header(skb, dev, type, daddr, saddr, len + vhdrlen); |
| 135 | if (rc > 0) | 134 | if (rc > 0) |
| 136 | rc += vhdrlen; | 135 | rc += vhdrlen; |
| 137 | return rc; | 136 | return rc; |
| 138 | } | 137 | } |
| 139 | 138 | ||
| 140 | static inline netdev_tx_t vlan_netpoll_send_skb(struct vlan_dev_priv *vlan, struct sk_buff *skb) | ||
| 141 | { | ||
| 142 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
| 143 | if (vlan->netpoll) | ||
| 144 | netpoll_send_skb(vlan->netpoll, skb); | ||
| 145 | #else | ||
| 146 | BUG(); | ||
| 147 | #endif | ||
| 148 | return NETDEV_TX_OK; | ||
| 149 | } | ||
| 150 | |||
| 151 | static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, | 139 | static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, |
| 152 | struct net_device *dev) | 140 | struct net_device *dev) |
| 153 | { | 141 | { |
| 154 | struct vlan_dev_priv *vlan = vlan_dev_priv(dev); | ||
| 155 | struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data); | 142 | struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data); |
| 156 | unsigned int len; | 143 | unsigned int len; |
| 157 | int ret; | 144 | int ret; |
| @@ -162,30 +149,27 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, | |||
| 162 | * OTHER THINGS LIKE FDDI/TokenRing/802.3 SNAPs... | 149 | * OTHER THINGS LIKE FDDI/TokenRing/802.3 SNAPs... |
| 163 | */ | 150 | */ |
| 164 | if (veth->h_vlan_proto != htons(ETH_P_8021Q) || | 151 | if (veth->h_vlan_proto != htons(ETH_P_8021Q) || |
| 165 | vlan->flags & VLAN_FLAG_REORDER_HDR) { | 152 | vlan_dev_info(dev)->flags & VLAN_FLAG_REORDER_HDR) { |
| 166 | u16 vlan_tci; | 153 | u16 vlan_tci; |
| 167 | vlan_tci = vlan->vlan_id; | 154 | vlan_tci = vlan_dev_info(dev)->vlan_id; |
| 168 | vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb); | 155 | vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb); |
| 169 | skb = __vlan_hwaccel_put_tag(skb, vlan_tci); | 156 | skb = __vlan_hwaccel_put_tag(skb, vlan_tci); |
| 170 | } | 157 | } |
| 171 | 158 | ||
| 172 | skb->dev = vlan->real_dev; | 159 | skb_set_dev(skb, vlan_dev_info(dev)->real_dev); |
| 173 | len = skb->len; | 160 | len = skb->len; |
| 174 | if (unlikely(netpoll_tx_running(dev))) | ||
| 175 | return vlan_netpoll_send_skb(vlan, skb); | ||
| 176 | |||
| 177 | ret = dev_queue_xmit(skb); | 161 | ret = dev_queue_xmit(skb); |
| 178 | 162 | ||
| 179 | if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) { | 163 | if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) { |
| 180 | struct vlan_pcpu_stats *stats; | 164 | struct vlan_pcpu_stats *stats; |
| 181 | 165 | ||
| 182 | stats = this_cpu_ptr(vlan->vlan_pcpu_stats); | 166 | stats = this_cpu_ptr(vlan_dev_info(dev)->vlan_pcpu_stats); |
| 183 | u64_stats_update_begin(&stats->syncp); | 167 | u64_stats_update_begin(&stats->syncp); |
| 184 | stats->tx_packets++; | 168 | stats->tx_packets++; |
| 185 | stats->tx_bytes += len; | 169 | stats->tx_bytes += len; |
| 186 | u64_stats_update_end(&stats->syncp); | 170 | u64_stats_update_end(&stats->syncp); |
| 187 | } else { | 171 | } else { |
| 188 | this_cpu_inc(vlan->vlan_pcpu_stats->tx_dropped); | 172 | this_cpu_inc(vlan_dev_info(dev)->vlan_pcpu_stats->tx_dropped); |
| 189 | } | 173 | } |
| 190 | 174 | ||
| 191 | return ret; | 175 | return ret; |
| @@ -196,7 +180,7 @@ static int vlan_dev_change_mtu(struct net_device *dev, int new_mtu) | |||
| 196 | /* TODO: gotta make sure the underlying layer can handle it, | 180 | /* TODO: gotta make sure the underlying layer can handle it, |
| 197 | * maybe an IFF_VLAN_CAPABLE flag for devices? | 181 | * maybe an IFF_VLAN_CAPABLE flag for devices? |
| 198 | */ | 182 | */ |
| 199 | if (vlan_dev_priv(dev)->real_dev->mtu < new_mtu) | 183 | if (vlan_dev_info(dev)->real_dev->mtu < new_mtu) |
| 200 | return -ERANGE; | 184 | return -ERANGE; |
| 201 | 185 | ||
| 202 | dev->mtu = new_mtu; | 186 | dev->mtu = new_mtu; |
| @@ -207,7 +191,7 @@ static int vlan_dev_change_mtu(struct net_device *dev, int new_mtu) | |||
| 207 | void vlan_dev_set_ingress_priority(const struct net_device *dev, | 191 | void vlan_dev_set_ingress_priority(const struct net_device *dev, |
| 208 | u32 skb_prio, u16 vlan_prio) | 192 | u32 skb_prio, u16 vlan_prio) |
| 209 | { | 193 | { |
| 210 | struct vlan_dev_priv *vlan = vlan_dev_priv(dev); | 194 | struct vlan_dev_info *vlan = vlan_dev_info(dev); |
| 211 | 195 | ||
| 212 | if (vlan->ingress_priority_map[vlan_prio & 0x7] && !skb_prio) | 196 | if (vlan->ingress_priority_map[vlan_prio & 0x7] && !skb_prio) |
| 213 | vlan->nr_ingress_mappings--; | 197 | vlan->nr_ingress_mappings--; |
| @@ -220,7 +204,7 @@ void vlan_dev_set_ingress_priority(const struct net_device *dev, | |||
| 220 | int vlan_dev_set_egress_priority(const struct net_device *dev, | 204 | int vlan_dev_set_egress_priority(const struct net_device *dev, |
| 221 | u32 skb_prio, u16 vlan_prio) | 205 | u32 skb_prio, u16 vlan_prio) |
| 222 | { | 206 | { |
| 223 | struct vlan_dev_priv *vlan = vlan_dev_priv(dev); | 207 | struct vlan_dev_info *vlan = vlan_dev_info(dev); |
| 224 | struct vlan_priority_tci_mapping *mp = NULL; | 208 | struct vlan_priority_tci_mapping *mp = NULL; |
| 225 | struct vlan_priority_tci_mapping *np; | 209 | struct vlan_priority_tci_mapping *np; |
| 226 | u32 vlan_qos = (vlan_prio << VLAN_PRIO_SHIFT) & VLAN_PRIO_MASK; | 210 | u32 vlan_qos = (vlan_prio << VLAN_PRIO_SHIFT) & VLAN_PRIO_MASK; |
| @@ -257,7 +241,7 @@ int vlan_dev_set_egress_priority(const struct net_device *dev, | |||
| 257 | /* Flags are defined in the vlan_flags enum in include/linux/if_vlan.h file. */ | 241 | /* Flags are defined in the vlan_flags enum in include/linux/if_vlan.h file. */ |
| 258 | int vlan_dev_change_flags(const struct net_device *dev, u32 flags, u32 mask) | 242 | int vlan_dev_change_flags(const struct net_device *dev, u32 flags, u32 mask) |
| 259 | { | 243 | { |
| 260 | struct vlan_dev_priv *vlan = vlan_dev_priv(dev); | 244 | struct vlan_dev_info *vlan = vlan_dev_info(dev); |
| 261 | u32 old_flags = vlan->flags; | 245 | u32 old_flags = vlan->flags; |
| 262 | 246 | ||
| 263 | if (mask & ~(VLAN_FLAG_REORDER_HDR | VLAN_FLAG_GVRP | | 247 | if (mask & ~(VLAN_FLAG_REORDER_HDR | VLAN_FLAG_GVRP | |
| @@ -277,12 +261,12 @@ int vlan_dev_change_flags(const struct net_device *dev, u32 flags, u32 mask) | |||
| 277 | 261 | ||
| 278 | void vlan_dev_get_realdev_name(const struct net_device *dev, char *result) | 262 | void vlan_dev_get_realdev_name(const struct net_device *dev, char *result) |
| 279 | { | 263 | { |
| 280 | strncpy(result, vlan_dev_priv(dev)->real_dev->name, 23); | 264 | strncpy(result, vlan_dev_info(dev)->real_dev->name, 23); |
| 281 | } | 265 | } |
| 282 | 266 | ||
| 283 | static int vlan_dev_open(struct net_device *dev) | 267 | static int vlan_dev_open(struct net_device *dev) |
| 284 | { | 268 | { |
| 285 | struct vlan_dev_priv *vlan = vlan_dev_priv(dev); | 269 | struct vlan_dev_info *vlan = vlan_dev_info(dev); |
| 286 | struct net_device *real_dev = vlan->real_dev; | 270 | struct net_device *real_dev = vlan->real_dev; |
| 287 | int err; | 271 | int err; |
| 288 | 272 | ||
| @@ -290,7 +274,7 @@ static int vlan_dev_open(struct net_device *dev) | |||
| 290 | !(vlan->flags & VLAN_FLAG_LOOSE_BINDING)) | 274 | !(vlan->flags & VLAN_FLAG_LOOSE_BINDING)) |
| 291 | return -ENETDOWN; | 275 | return -ENETDOWN; |
| 292 | 276 | ||
| 293 | if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr)) { | 277 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) { |
| 294 | err = dev_uc_add(real_dev, dev->dev_addr); | 278 | err = dev_uc_add(real_dev, dev->dev_addr); |
| 295 | if (err < 0) | 279 | if (err < 0) |
| 296 | goto out; | 280 | goto out; |
| @@ -320,7 +304,7 @@ clear_allmulti: | |||
| 320 | if (dev->flags & IFF_ALLMULTI) | 304 | if (dev->flags & IFF_ALLMULTI) |
| 321 | dev_set_allmulti(real_dev, -1); | 305 | dev_set_allmulti(real_dev, -1); |
| 322 | del_unicast: | 306 | del_unicast: |
| 323 | if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr)) | 307 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) |
| 324 | dev_uc_del(real_dev, dev->dev_addr); | 308 | dev_uc_del(real_dev, dev->dev_addr); |
| 325 | out: | 309 | out: |
| 326 | netif_carrier_off(dev); | 310 | netif_carrier_off(dev); |
| @@ -329,7 +313,7 @@ out: | |||
| 329 | 313 | ||
| 330 | static int vlan_dev_stop(struct net_device *dev) | 314 | static int vlan_dev_stop(struct net_device *dev) |
| 331 | { | 315 | { |
| 332 | struct vlan_dev_priv *vlan = vlan_dev_priv(dev); | 316 | struct vlan_dev_info *vlan = vlan_dev_info(dev); |
| 333 | struct net_device *real_dev = vlan->real_dev; | 317 | struct net_device *real_dev = vlan->real_dev; |
| 334 | 318 | ||
| 335 | dev_mc_unsync(real_dev, dev); | 319 | dev_mc_unsync(real_dev, dev); |
| @@ -339,7 +323,7 @@ static int vlan_dev_stop(struct net_device *dev) | |||
| 339 | if (dev->flags & IFF_PROMISC) | 323 | if (dev->flags & IFF_PROMISC) |
| 340 | dev_set_promiscuity(real_dev, -1); | 324 | dev_set_promiscuity(real_dev, -1); |
| 341 | 325 | ||
| 342 | if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr)) | 326 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) |
| 343 | dev_uc_del(real_dev, dev->dev_addr); | 327 | dev_uc_del(real_dev, dev->dev_addr); |
| 344 | 328 | ||
| 345 | netif_carrier_off(dev); | 329 | netif_carrier_off(dev); |
| @@ -348,7 +332,7 @@ static int vlan_dev_stop(struct net_device *dev) | |||
| 348 | 332 | ||
| 349 | static int vlan_dev_set_mac_address(struct net_device *dev, void *p) | 333 | static int vlan_dev_set_mac_address(struct net_device *dev, void *p) |
| 350 | { | 334 | { |
| 351 | struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; | 335 | struct net_device *real_dev = vlan_dev_info(dev)->real_dev; |
| 352 | struct sockaddr *addr = p; | 336 | struct sockaddr *addr = p; |
| 353 | int err; | 337 | int err; |
| 354 | 338 | ||
| @@ -358,13 +342,13 @@ static int vlan_dev_set_mac_address(struct net_device *dev, void *p) | |||
| 358 | if (!(dev->flags & IFF_UP)) | 342 | if (!(dev->flags & IFF_UP)) |
| 359 | goto out; | 343 | goto out; |
| 360 | 344 | ||
| 361 | if (!ether_addr_equal(addr->sa_data, real_dev->dev_addr)) { | 345 | if (compare_ether_addr(addr->sa_data, real_dev->dev_addr)) { |
| 362 | err = dev_uc_add(real_dev, addr->sa_data); | 346 | err = dev_uc_add(real_dev, addr->sa_data); |
| 363 | if (err < 0) | 347 | if (err < 0) |
| 364 | return err; | 348 | return err; |
| 365 | } | 349 | } |
| 366 | 350 | ||
| 367 | if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr)) | 351 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) |
| 368 | dev_uc_del(real_dev, dev->dev_addr); | 352 | dev_uc_del(real_dev, dev->dev_addr); |
| 369 | 353 | ||
| 370 | out: | 354 | out: |
| @@ -374,7 +358,7 @@ out: | |||
| 374 | 358 | ||
| 375 | static int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | 359 | static int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) |
| 376 | { | 360 | { |
| 377 | struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; | 361 | struct net_device *real_dev = vlan_dev_info(dev)->real_dev; |
| 378 | const struct net_device_ops *ops = real_dev->netdev_ops; | 362 | const struct net_device_ops *ops = real_dev->netdev_ops; |
| 379 | struct ifreq ifrr; | 363 | struct ifreq ifrr; |
| 380 | int err = -EOPNOTSUPP; | 364 | int err = -EOPNOTSUPP; |
| @@ -399,7 +383,7 @@ static int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
| 399 | 383 | ||
| 400 | static int vlan_dev_neigh_setup(struct net_device *dev, struct neigh_parms *pa) | 384 | static int vlan_dev_neigh_setup(struct net_device *dev, struct neigh_parms *pa) |
| 401 | { | 385 | { |
| 402 | struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; | 386 | struct net_device *real_dev = vlan_dev_info(dev)->real_dev; |
| 403 | const struct net_device_ops *ops = real_dev->netdev_ops; | 387 | const struct net_device_ops *ops = real_dev->netdev_ops; |
| 404 | int err = 0; | 388 | int err = 0; |
| 405 | 389 | ||
| @@ -409,11 +393,11 @@ static int vlan_dev_neigh_setup(struct net_device *dev, struct neigh_parms *pa) | |||
| 409 | return err; | 393 | return err; |
| 410 | } | 394 | } |
| 411 | 395 | ||
| 412 | #if IS_ENABLED(CONFIG_FCOE) | 396 | #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) |
| 413 | static int vlan_dev_fcoe_ddp_setup(struct net_device *dev, u16 xid, | 397 | static int vlan_dev_fcoe_ddp_setup(struct net_device *dev, u16 xid, |
| 414 | struct scatterlist *sgl, unsigned int sgc) | 398 | struct scatterlist *sgl, unsigned int sgc) |
| 415 | { | 399 | { |
| 416 | struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; | 400 | struct net_device *real_dev = vlan_dev_info(dev)->real_dev; |
| 417 | const struct net_device_ops *ops = real_dev->netdev_ops; | 401 | const struct net_device_ops *ops = real_dev->netdev_ops; |
| 418 | int rc = 0; | 402 | int rc = 0; |
| 419 | 403 | ||
| @@ -425,7 +409,7 @@ static int vlan_dev_fcoe_ddp_setup(struct net_device *dev, u16 xid, | |||
| 425 | 409 | ||
| 426 | static int vlan_dev_fcoe_ddp_done(struct net_device *dev, u16 xid) | 410 | static int vlan_dev_fcoe_ddp_done(struct net_device *dev, u16 xid) |
| 427 | { | 411 | { |
| 428 | struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; | 412 | struct net_device *real_dev = vlan_dev_info(dev)->real_dev; |
| 429 | const struct net_device_ops *ops = real_dev->netdev_ops; | 413 | const struct net_device_ops *ops = real_dev->netdev_ops; |
| 430 | int len = 0; | 414 | int len = 0; |
| 431 | 415 | ||
| @@ -437,7 +421,7 @@ static int vlan_dev_fcoe_ddp_done(struct net_device *dev, u16 xid) | |||
| 437 | 421 | ||
| 438 | static int vlan_dev_fcoe_enable(struct net_device *dev) | 422 | static int vlan_dev_fcoe_enable(struct net_device *dev) |
| 439 | { | 423 | { |
| 440 | struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; | 424 | struct net_device *real_dev = vlan_dev_info(dev)->real_dev; |
| 441 | const struct net_device_ops *ops = real_dev->netdev_ops; | 425 | const struct net_device_ops *ops = real_dev->netdev_ops; |
| 442 | int rc = -EINVAL; | 426 | int rc = -EINVAL; |
| 443 | 427 | ||
| @@ -448,7 +432,7 @@ static int vlan_dev_fcoe_enable(struct net_device *dev) | |||
| 448 | 432 | ||
| 449 | static int vlan_dev_fcoe_disable(struct net_device *dev) | 433 | static int vlan_dev_fcoe_disable(struct net_device *dev) |
| 450 | { | 434 | { |
| 451 | struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; | 435 | struct net_device *real_dev = vlan_dev_info(dev)->real_dev; |
| 452 | const struct net_device_ops *ops = real_dev->netdev_ops; | 436 | const struct net_device_ops *ops = real_dev->netdev_ops; |
| 453 | int rc = -EINVAL; | 437 | int rc = -EINVAL; |
| 454 | 438 | ||
| @@ -459,7 +443,7 @@ static int vlan_dev_fcoe_disable(struct net_device *dev) | |||
| 459 | 443 | ||
| 460 | static int vlan_dev_fcoe_get_wwn(struct net_device *dev, u64 *wwn, int type) | 444 | static int vlan_dev_fcoe_get_wwn(struct net_device *dev, u64 *wwn, int type) |
| 461 | { | 445 | { |
| 462 | struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; | 446 | struct net_device *real_dev = vlan_dev_info(dev)->real_dev; |
| 463 | const struct net_device_ops *ops = real_dev->netdev_ops; | 447 | const struct net_device_ops *ops = real_dev->netdev_ops; |
| 464 | int rc = -EINVAL; | 448 | int rc = -EINVAL; |
| 465 | 449 | ||
| @@ -471,7 +455,7 @@ static int vlan_dev_fcoe_get_wwn(struct net_device *dev, u64 *wwn, int type) | |||
| 471 | static int vlan_dev_fcoe_ddp_target(struct net_device *dev, u16 xid, | 455 | static int vlan_dev_fcoe_ddp_target(struct net_device *dev, u16 xid, |
| 472 | struct scatterlist *sgl, unsigned int sgc) | 456 | struct scatterlist *sgl, unsigned int sgc) |
| 473 | { | 457 | { |
| 474 | struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; | 458 | struct net_device *real_dev = vlan_dev_info(dev)->real_dev; |
| 475 | const struct net_device_ops *ops = real_dev->netdev_ops; | 459 | const struct net_device_ops *ops = real_dev->netdev_ops; |
| 476 | int rc = 0; | 460 | int rc = 0; |
| 477 | 461 | ||
| @@ -484,20 +468,18 @@ static int vlan_dev_fcoe_ddp_target(struct net_device *dev, u16 xid, | |||
| 484 | 468 | ||
| 485 | static void vlan_dev_change_rx_flags(struct net_device *dev, int change) | 469 | static void vlan_dev_change_rx_flags(struct net_device *dev, int change) |
| 486 | { | 470 | { |
| 487 | struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; | 471 | struct net_device *real_dev = vlan_dev_info(dev)->real_dev; |
| 488 | 472 | ||
| 489 | if (dev->flags & IFF_UP) { | 473 | if (change & IFF_ALLMULTI) |
| 490 | if (change & IFF_ALLMULTI) | 474 | dev_set_allmulti(real_dev, dev->flags & IFF_ALLMULTI ? 1 : -1); |
| 491 | dev_set_allmulti(real_dev, dev->flags & IFF_ALLMULTI ? 1 : -1); | 475 | if (change & IFF_PROMISC) |
| 492 | if (change & IFF_PROMISC) | 476 | dev_set_promiscuity(real_dev, dev->flags & IFF_PROMISC ? 1 : -1); |
| 493 | dev_set_promiscuity(real_dev, dev->flags & IFF_PROMISC ? 1 : -1); | ||
| 494 | } | ||
| 495 | } | 477 | } |
| 496 | 478 | ||
| 497 | static void vlan_dev_set_rx_mode(struct net_device *vlan_dev) | 479 | static void vlan_dev_set_rx_mode(struct net_device *vlan_dev) |
| 498 | { | 480 | { |
| 499 | dev_mc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev); | 481 | dev_mc_sync(vlan_dev_info(vlan_dev)->real_dev, vlan_dev); |
| 500 | dev_uc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev); | 482 | dev_uc_sync(vlan_dev_info(vlan_dev)->real_dev, vlan_dev); |
| 501 | } | 483 | } |
| 502 | 484 | ||
| 503 | /* | 485 | /* |
| @@ -531,15 +513,11 @@ static const struct header_ops vlan_header_ops = { | |||
| 531 | .parse = eth_header_parse, | 513 | .parse = eth_header_parse, |
| 532 | }; | 514 | }; |
| 533 | 515 | ||
| 534 | static struct device_type vlan_type = { | ||
| 535 | .name = "vlan", | ||
| 536 | }; | ||
| 537 | |||
| 538 | static const struct net_device_ops vlan_netdev_ops; | 516 | static const struct net_device_ops vlan_netdev_ops; |
| 539 | 517 | ||
| 540 | static int vlan_dev_init(struct net_device *dev) | 518 | static int vlan_dev_init(struct net_device *dev) |
| 541 | { | 519 | { |
| 542 | struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; | 520 | struct net_device *real_dev = vlan_dev_info(dev)->real_dev; |
| 543 | int subclass = 0; | 521 | int subclass = 0; |
| 544 | 522 | ||
| 545 | netif_carrier_off(dev); | 523 | netif_carrier_off(dev); |
| @@ -568,7 +546,7 @@ static int vlan_dev_init(struct net_device *dev) | |||
| 568 | if (is_zero_ether_addr(dev->broadcast)) | 546 | if (is_zero_ether_addr(dev->broadcast)) |
| 569 | memcpy(dev->broadcast, real_dev->broadcast, dev->addr_len); | 547 | memcpy(dev->broadcast, real_dev->broadcast, dev->addr_len); |
| 570 | 548 | ||
| 571 | #if IS_ENABLED(CONFIG_FCOE) | 549 | #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) |
| 572 | dev->fcoe_ddp_xid = real_dev->fcoe_ddp_xid; | 550 | dev->fcoe_ddp_xid = real_dev->fcoe_ddp_xid; |
| 573 | #endif | 551 | #endif |
| 574 | 552 | ||
| @@ -583,15 +561,13 @@ static int vlan_dev_init(struct net_device *dev) | |||
| 583 | 561 | ||
| 584 | dev->netdev_ops = &vlan_netdev_ops; | 562 | dev->netdev_ops = &vlan_netdev_ops; |
| 585 | 563 | ||
| 586 | SET_NETDEV_DEVTYPE(dev, &vlan_type); | ||
| 587 | |||
| 588 | if (is_vlan_dev(real_dev)) | 564 | if (is_vlan_dev(real_dev)) |
| 589 | subclass = 1; | 565 | subclass = 1; |
| 590 | 566 | ||
| 591 | vlan_dev_set_lockdep_class(dev, subclass); | 567 | vlan_dev_set_lockdep_class(dev, subclass); |
| 592 | 568 | ||
| 593 | vlan_dev_priv(dev)->vlan_pcpu_stats = alloc_percpu(struct vlan_pcpu_stats); | 569 | vlan_dev_info(dev)->vlan_pcpu_stats = alloc_percpu(struct vlan_pcpu_stats); |
| 594 | if (!vlan_dev_priv(dev)->vlan_pcpu_stats) | 570 | if (!vlan_dev_info(dev)->vlan_pcpu_stats) |
| 595 | return -ENOMEM; | 571 | return -ENOMEM; |
| 596 | 572 | ||
| 597 | return 0; | 573 | return 0; |
| @@ -600,7 +576,7 @@ static int vlan_dev_init(struct net_device *dev) | |||
| 600 | static void vlan_dev_uninit(struct net_device *dev) | 576 | static void vlan_dev_uninit(struct net_device *dev) |
| 601 | { | 577 | { |
| 602 | struct vlan_priority_tci_mapping *pm; | 578 | struct vlan_priority_tci_mapping *pm; |
| 603 | struct vlan_dev_priv *vlan = vlan_dev_priv(dev); | 579 | struct vlan_dev_info *vlan = vlan_dev_info(dev); |
| 604 | int i; | 580 | int i; |
| 605 | 581 | ||
| 606 | free_percpu(vlan->vlan_pcpu_stats); | 582 | free_percpu(vlan->vlan_pcpu_stats); |
| @@ -613,17 +589,18 @@ static void vlan_dev_uninit(struct net_device *dev) | |||
| 613 | } | 589 | } |
| 614 | } | 590 | } |
| 615 | 591 | ||
| 616 | static netdev_features_t vlan_dev_fix_features(struct net_device *dev, | 592 | static u32 vlan_dev_fix_features(struct net_device *dev, u32 features) |
| 617 | netdev_features_t features) | ||
| 618 | { | 593 | { |
| 619 | struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; | 594 | struct net_device *real_dev = vlan_dev_info(dev)->real_dev; |
| 620 | u32 old_features = features; | 595 | u32 old_features = features; |
| 621 | 596 | ||
| 622 | features &= real_dev->vlan_features; | ||
| 623 | features |= NETIF_F_RXCSUM; | ||
| 624 | features &= real_dev->features; | 597 | features &= real_dev->features; |
| 598 | features &= real_dev->vlan_features; | ||
| 625 | 599 | ||
| 626 | features |= old_features & NETIF_F_SOFT_FEATURES; | 600 | features |= old_features & NETIF_F_SOFT_FEATURES; |
| 601 | |||
| 602 | if (dev_ethtool_get_rx_csum(real_dev)) | ||
| 603 | features |= NETIF_F_RXCSUM; | ||
| 627 | features |= NETIF_F_LLTX; | 604 | features |= NETIF_F_LLTX; |
| 628 | 605 | ||
| 629 | return features; | 606 | return features; |
| @@ -632,9 +609,8 @@ static netdev_features_t vlan_dev_fix_features(struct net_device *dev, | |||
| 632 | static int vlan_ethtool_get_settings(struct net_device *dev, | 609 | static int vlan_ethtool_get_settings(struct net_device *dev, |
| 633 | struct ethtool_cmd *cmd) | 610 | struct ethtool_cmd *cmd) |
| 634 | { | 611 | { |
| 635 | const struct vlan_dev_priv *vlan = vlan_dev_priv(dev); | 612 | const struct vlan_dev_info *vlan = vlan_dev_info(dev); |
| 636 | 613 | return dev_ethtool_get_settings(vlan->real_dev, cmd); | |
| 637 | return __ethtool_get_settings(vlan->real_dev, cmd); | ||
| 638 | } | 614 | } |
| 639 | 615 | ||
| 640 | static void vlan_ethtool_get_drvinfo(struct net_device *dev, | 616 | static void vlan_ethtool_get_drvinfo(struct net_device *dev, |
| @@ -648,7 +624,7 @@ static void vlan_ethtool_get_drvinfo(struct net_device *dev, | |||
| 648 | static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) | 624 | static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) |
| 649 | { | 625 | { |
| 650 | 626 | ||
| 651 | if (vlan_dev_priv(dev)->vlan_pcpu_stats) { | 627 | if (vlan_dev_info(dev)->vlan_pcpu_stats) { |
| 652 | struct vlan_pcpu_stats *p; | 628 | struct vlan_pcpu_stats *p; |
| 653 | u32 rx_errors = 0, tx_dropped = 0; | 629 | u32 rx_errors = 0, tx_dropped = 0; |
| 654 | int i; | 630 | int i; |
| @@ -657,7 +633,7 @@ static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, st | |||
| 657 | u64 rxpackets, rxbytes, rxmulticast, txpackets, txbytes; | 633 | u64 rxpackets, rxbytes, rxmulticast, txpackets, txbytes; |
| 658 | unsigned int start; | 634 | unsigned int start; |
| 659 | 635 | ||
| 660 | p = per_cpu_ptr(vlan_dev_priv(dev)->vlan_pcpu_stats, i); | 636 | p = per_cpu_ptr(vlan_dev_info(dev)->vlan_pcpu_stats, i); |
| 661 | do { | 637 | do { |
| 662 | start = u64_stats_fetch_begin_bh(&p->syncp); | 638 | start = u64_stats_fetch_begin_bh(&p->syncp); |
| 663 | rxpackets = p->rx_packets; | 639 | rxpackets = p->rx_packets; |
| @@ -682,51 +658,6 @@ static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, st | |||
| 682 | return stats; | 658 | return stats; |
| 683 | } | 659 | } |
| 684 | 660 | ||
| 685 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
| 686 | static void vlan_dev_poll_controller(struct net_device *dev) | ||
| 687 | { | ||
| 688 | return; | ||
| 689 | } | ||
| 690 | |||
| 691 | static int vlan_dev_netpoll_setup(struct net_device *dev, struct netpoll_info *npinfo, | ||
| 692 | gfp_t gfp) | ||
| 693 | { | ||
| 694 | struct vlan_dev_priv *vlan = vlan_dev_priv(dev); | ||
| 695 | struct net_device *real_dev = vlan->real_dev; | ||
| 696 | struct netpoll *netpoll; | ||
| 697 | int err = 0; | ||
| 698 | |||
| 699 | netpoll = kzalloc(sizeof(*netpoll), gfp); | ||
| 700 | err = -ENOMEM; | ||
| 701 | if (!netpoll) | ||
| 702 | goto out; | ||
| 703 | |||
| 704 | err = __netpoll_setup(netpoll, real_dev, gfp); | ||
| 705 | if (err) { | ||
| 706 | kfree(netpoll); | ||
| 707 | goto out; | ||
| 708 | } | ||
| 709 | |||
| 710 | vlan->netpoll = netpoll; | ||
| 711 | |||
| 712 | out: | ||
| 713 | return err; | ||
| 714 | } | ||
| 715 | |||
| 716 | static void vlan_dev_netpoll_cleanup(struct net_device *dev) | ||
| 717 | { | ||
| 718 | struct vlan_dev_priv *vlan= vlan_dev_priv(dev); | ||
| 719 | struct netpoll *netpoll = vlan->netpoll; | ||
| 720 | |||
| 721 | if (!netpoll) | ||
| 722 | return; | ||
| 723 | |||
| 724 | vlan->netpoll = NULL; | ||
| 725 | |||
| 726 | __netpoll_free_rcu(netpoll); | ||
| 727 | } | ||
| 728 | #endif /* CONFIG_NET_POLL_CONTROLLER */ | ||
| 729 | |||
| 730 | static const struct ethtool_ops vlan_ethtool_ops = { | 661 | static const struct ethtool_ops vlan_ethtool_ops = { |
| 731 | .get_settings = vlan_ethtool_get_settings, | 662 | .get_settings = vlan_ethtool_get_settings, |
| 732 | .get_drvinfo = vlan_ethtool_get_drvinfo, | 663 | .get_drvinfo = vlan_ethtool_get_drvinfo, |
| @@ -743,11 +674,12 @@ static const struct net_device_ops vlan_netdev_ops = { | |||
| 743 | .ndo_validate_addr = eth_validate_addr, | 674 | .ndo_validate_addr = eth_validate_addr, |
| 744 | .ndo_set_mac_address = vlan_dev_set_mac_address, | 675 | .ndo_set_mac_address = vlan_dev_set_mac_address, |
| 745 | .ndo_set_rx_mode = vlan_dev_set_rx_mode, | 676 | .ndo_set_rx_mode = vlan_dev_set_rx_mode, |
| 677 | .ndo_set_multicast_list = vlan_dev_set_rx_mode, | ||
| 746 | .ndo_change_rx_flags = vlan_dev_change_rx_flags, | 678 | .ndo_change_rx_flags = vlan_dev_change_rx_flags, |
| 747 | .ndo_do_ioctl = vlan_dev_ioctl, | 679 | .ndo_do_ioctl = vlan_dev_ioctl, |
| 748 | .ndo_neigh_setup = vlan_dev_neigh_setup, | 680 | .ndo_neigh_setup = vlan_dev_neigh_setup, |
| 749 | .ndo_get_stats64 = vlan_dev_get_stats64, | 681 | .ndo_get_stats64 = vlan_dev_get_stats64, |
| 750 | #if IS_ENABLED(CONFIG_FCOE) | 682 | #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) |
| 751 | .ndo_fcoe_ddp_setup = vlan_dev_fcoe_ddp_setup, | 683 | .ndo_fcoe_ddp_setup = vlan_dev_fcoe_ddp_setup, |
| 752 | .ndo_fcoe_ddp_done = vlan_dev_fcoe_ddp_done, | 684 | .ndo_fcoe_ddp_done = vlan_dev_fcoe_ddp_done, |
| 753 | .ndo_fcoe_enable = vlan_dev_fcoe_enable, | 685 | .ndo_fcoe_enable = vlan_dev_fcoe_enable, |
| @@ -755,11 +687,6 @@ static const struct net_device_ops vlan_netdev_ops = { | |||
| 755 | .ndo_fcoe_get_wwn = vlan_dev_fcoe_get_wwn, | 687 | .ndo_fcoe_get_wwn = vlan_dev_fcoe_get_wwn, |
| 756 | .ndo_fcoe_ddp_target = vlan_dev_fcoe_ddp_target, | 688 | .ndo_fcoe_ddp_target = vlan_dev_fcoe_ddp_target, |
| 757 | #endif | 689 | #endif |
| 758 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
| 759 | .ndo_poll_controller = vlan_dev_poll_controller, | ||
| 760 | .ndo_netpoll_setup = vlan_dev_netpoll_setup, | ||
| 761 | .ndo_netpoll_cleanup = vlan_dev_netpoll_cleanup, | ||
| 762 | #endif | ||
| 763 | .ndo_fix_features = vlan_dev_fix_features, | 690 | .ndo_fix_features = vlan_dev_fix_features, |
| 764 | }; | 691 | }; |
| 765 | 692 | ||
diff --git a/net/8021q/vlan_gvrp.c b/net/8021q/vlan_gvrp.c index 6f975535276..061ceceeef1 100644 --- a/net/8021q/vlan_gvrp.c +++ b/net/8021q/vlan_gvrp.c | |||
| @@ -29,7 +29,7 @@ static struct garp_application vlan_gvrp_app __read_mostly = { | |||
| 29 | 29 | ||
| 30 | int vlan_gvrp_request_join(const struct net_device *dev) | 30 | int vlan_gvrp_request_join(const struct net_device *dev) |
| 31 | { | 31 | { |
| 32 | const struct vlan_dev_priv *vlan = vlan_dev_priv(dev); | 32 | const struct vlan_dev_info *vlan = vlan_dev_info(dev); |
| 33 | __be16 vlan_id = htons(vlan->vlan_id); | 33 | __be16 vlan_id = htons(vlan->vlan_id); |
| 34 | 34 | ||
| 35 | return garp_request_join(vlan->real_dev, &vlan_gvrp_app, | 35 | return garp_request_join(vlan->real_dev, &vlan_gvrp_app, |
| @@ -38,7 +38,7 @@ int vlan_gvrp_request_join(const struct net_device *dev) | |||
| 38 | 38 | ||
| 39 | void vlan_gvrp_request_leave(const struct net_device *dev) | 39 | void vlan_gvrp_request_leave(const struct net_device *dev) |
| 40 | { | 40 | { |
| 41 | const struct vlan_dev_priv *vlan = vlan_dev_priv(dev); | 41 | const struct vlan_dev_info *vlan = vlan_dev_info(dev); |
| 42 | __be16 vlan_id = htons(vlan->vlan_id); | 42 | __be16 vlan_id = htons(vlan->vlan_id); |
| 43 | 43 | ||
| 44 | garp_request_leave(vlan->real_dev, &vlan_gvrp_app, | 44 | garp_request_leave(vlan->real_dev, &vlan_gvrp_app, |
diff --git a/net/8021q/vlan_netlink.c b/net/8021q/vlan_netlink.c index 708c80ea187..be9a5c19a77 100644 --- a/net/8021q/vlan_netlink.c +++ b/net/8021q/vlan_netlink.c | |||
| @@ -11,7 +11,6 @@ | |||
| 11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
| 12 | #include <linux/netdevice.h> | 12 | #include <linux/netdevice.h> |
| 13 | #include <linux/if_vlan.h> | 13 | #include <linux/if_vlan.h> |
| 14 | #include <linux/module.h> | ||
| 15 | #include <net/net_namespace.h> | 14 | #include <net/net_namespace.h> |
| 16 | #include <net/netlink.h> | 15 | #include <net/netlink.h> |
| 17 | #include <net/rtnetlink.h> | 16 | #include <net/rtnetlink.h> |
| @@ -105,7 +104,7 @@ static int vlan_changelink(struct net_device *dev, | |||
| 105 | static int vlan_newlink(struct net *src_net, struct net_device *dev, | 104 | static int vlan_newlink(struct net *src_net, struct net_device *dev, |
| 106 | struct nlattr *tb[], struct nlattr *data[]) | 105 | struct nlattr *tb[], struct nlattr *data[]) |
| 107 | { | 106 | { |
| 108 | struct vlan_dev_priv *vlan = vlan_dev_priv(dev); | 107 | struct vlan_dev_info *vlan = vlan_dev_info(dev); |
| 109 | struct net_device *real_dev; | 108 | struct net_device *real_dev; |
| 110 | int err; | 109 | int err; |
| 111 | 110 | ||
| @@ -149,7 +148,7 @@ static inline size_t vlan_qos_map_size(unsigned int n) | |||
| 149 | 148 | ||
| 150 | static size_t vlan_get_size(const struct net_device *dev) | 149 | static size_t vlan_get_size(const struct net_device *dev) |
| 151 | { | 150 | { |
| 152 | struct vlan_dev_priv *vlan = vlan_dev_priv(dev); | 151 | struct vlan_dev_info *vlan = vlan_dev_info(dev); |
| 153 | 152 | ||
| 154 | return nla_total_size(2) + /* IFLA_VLAN_ID */ | 153 | return nla_total_size(2) + /* IFLA_VLAN_ID */ |
| 155 | sizeof(struct ifla_vlan_flags) + /* IFLA_VLAN_FLAGS */ | 154 | sizeof(struct ifla_vlan_flags) + /* IFLA_VLAN_FLAGS */ |
| @@ -159,20 +158,18 @@ static size_t vlan_get_size(const struct net_device *dev) | |||
| 159 | 158 | ||
| 160 | static int vlan_fill_info(struct sk_buff *skb, const struct net_device *dev) | 159 | static int vlan_fill_info(struct sk_buff *skb, const struct net_device *dev) |
| 161 | { | 160 | { |
| 162 | struct vlan_dev_priv *vlan = vlan_dev_priv(dev); | 161 | struct vlan_dev_info *vlan = vlan_dev_info(dev); |
| 163 | struct vlan_priority_tci_mapping *pm; | 162 | struct vlan_priority_tci_mapping *pm; |
| 164 | struct ifla_vlan_flags f; | 163 | struct ifla_vlan_flags f; |
| 165 | struct ifla_vlan_qos_mapping m; | 164 | struct ifla_vlan_qos_mapping m; |
| 166 | struct nlattr *nest; | 165 | struct nlattr *nest; |
| 167 | unsigned int i; | 166 | unsigned int i; |
| 168 | 167 | ||
| 169 | if (nla_put_u16(skb, IFLA_VLAN_ID, vlan_dev_priv(dev)->vlan_id)) | 168 | NLA_PUT_U16(skb, IFLA_VLAN_ID, vlan_dev_info(dev)->vlan_id); |
| 170 | goto nla_put_failure; | ||
| 171 | if (vlan->flags) { | 169 | if (vlan->flags) { |
| 172 | f.flags = vlan->flags; | 170 | f.flags = vlan->flags; |
| 173 | f.mask = ~0; | 171 | f.mask = ~0; |
| 174 | if (nla_put(skb, IFLA_VLAN_FLAGS, sizeof(f), &f)) | 172 | NLA_PUT(skb, IFLA_VLAN_FLAGS, sizeof(f), &f); |
| 175 | goto nla_put_failure; | ||
| 176 | } | 173 | } |
| 177 | if (vlan->nr_ingress_mappings) { | 174 | if (vlan->nr_ingress_mappings) { |
| 178 | nest = nla_nest_start(skb, IFLA_VLAN_INGRESS_QOS); | 175 | nest = nla_nest_start(skb, IFLA_VLAN_INGRESS_QOS); |
| @@ -185,9 +182,8 @@ static int vlan_fill_info(struct sk_buff *skb, const struct net_device *dev) | |||
| 185 | 182 | ||
| 186 | m.from = i; | 183 | m.from = i; |
| 187 | m.to = vlan->ingress_priority_map[i]; | 184 | m.to = vlan->ingress_priority_map[i]; |
| 188 | if (nla_put(skb, IFLA_VLAN_QOS_MAPPING, | 185 | NLA_PUT(skb, IFLA_VLAN_QOS_MAPPING, |
| 189 | sizeof(m), &m)) | 186 | sizeof(m), &m); |
| 190 | goto nla_put_failure; | ||
| 191 | } | 187 | } |
| 192 | nla_nest_end(skb, nest); | 188 | nla_nest_end(skb, nest); |
| 193 | } | 189 | } |
| @@ -205,9 +201,8 @@ static int vlan_fill_info(struct sk_buff *skb, const struct net_device *dev) | |||
| 205 | 201 | ||
| 206 | m.from = pm->priority; | 202 | m.from = pm->priority; |
| 207 | m.to = (pm->vlan_qos >> 13) & 0x7; | 203 | m.to = (pm->vlan_qos >> 13) & 0x7; |
| 208 | if (nla_put(skb, IFLA_VLAN_QOS_MAPPING, | 204 | NLA_PUT(skb, IFLA_VLAN_QOS_MAPPING, |
| 209 | sizeof(m), &m)) | 205 | sizeof(m), &m); |
| 210 | goto nla_put_failure; | ||
| 211 | } | 206 | } |
| 212 | } | 207 | } |
| 213 | nla_nest_end(skb, nest); | 208 | nla_nest_end(skb, nest); |
| @@ -222,7 +217,7 @@ struct rtnl_link_ops vlan_link_ops __read_mostly = { | |||
| 222 | .kind = "vlan", | 217 | .kind = "vlan", |
| 223 | .maxtype = IFLA_VLAN_MAX, | 218 | .maxtype = IFLA_VLAN_MAX, |
| 224 | .policy = vlan_policy, | 219 | .policy = vlan_policy, |
| 225 | .priv_size = sizeof(struct vlan_dev_priv), | 220 | .priv_size = sizeof(struct vlan_dev_info), |
| 226 | .setup = vlan_setup, | 221 | .setup = vlan_setup, |
| 227 | .validate = vlan_validate, | 222 | .validate = vlan_validate, |
| 228 | .newlink = vlan_newlink, | 223 | .newlink = vlan_newlink, |
diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c index 4de77ea5fa3..d34b6daf893 100644 --- a/net/8021q/vlanproc.c +++ b/net/8021q/vlanproc.c | |||
| @@ -105,7 +105,7 @@ static const struct file_operations vlandev_fops = { | |||
| 105 | }; | 105 | }; |
| 106 | 106 | ||
| 107 | /* | 107 | /* |
| 108 | * Proc filesystem directory entries. | 108 | * Proc filesystem derectory entries. |
| 109 | */ | 109 | */ |
| 110 | 110 | ||
| 111 | /* Strings */ | 111 | /* Strings */ |
| @@ -168,13 +168,13 @@ err: | |||
| 168 | 168 | ||
| 169 | int vlan_proc_add_dev(struct net_device *vlandev) | 169 | int vlan_proc_add_dev(struct net_device *vlandev) |
| 170 | { | 170 | { |
| 171 | struct vlan_dev_priv *vlan = vlan_dev_priv(vlandev); | 171 | struct vlan_dev_info *dev_info = vlan_dev_info(vlandev); |
| 172 | struct vlan_net *vn = net_generic(dev_net(vlandev), vlan_net_id); | 172 | struct vlan_net *vn = net_generic(dev_net(vlandev), vlan_net_id); |
| 173 | 173 | ||
| 174 | vlan->dent = | 174 | dev_info->dent = |
| 175 | proc_create_data(vlandev->name, S_IFREG|S_IRUSR|S_IWUSR, | 175 | proc_create_data(vlandev->name, S_IFREG|S_IRUSR|S_IWUSR, |
| 176 | vn->proc_vlan_dir, &vlandev_fops, vlandev); | 176 | vn->proc_vlan_dir, &vlandev_fops, vlandev); |
| 177 | if (!vlan->dent) | 177 | if (!dev_info->dent) |
| 178 | return -ENOBUFS; | 178 | return -ENOBUFS; |
| 179 | return 0; | 179 | return 0; |
| 180 | } | 180 | } |
| @@ -187,10 +187,10 @@ int vlan_proc_rem_dev(struct net_device *vlandev) | |||
| 187 | struct vlan_net *vn = net_generic(dev_net(vlandev), vlan_net_id); | 187 | struct vlan_net *vn = net_generic(dev_net(vlandev), vlan_net_id); |
| 188 | 188 | ||
| 189 | /** NOTE: This will consume the memory pointed to by dent, it seems. */ | 189 | /** NOTE: This will consume the memory pointed to by dent, it seems. */ |
| 190 | if (vlan_dev_priv(vlandev)->dent) { | 190 | if (vlan_dev_info(vlandev)->dent) { |
| 191 | remove_proc_entry(vlan_dev_priv(vlandev)->dent->name, | 191 | remove_proc_entry(vlan_dev_info(vlandev)->dent->name, |
| 192 | vn->proc_vlan_dir); | 192 | vn->proc_vlan_dir); |
| 193 | vlan_dev_priv(vlandev)->dent = NULL; | 193 | vlan_dev_info(vlandev)->dent = NULL; |
| 194 | } | 194 | } |
| 195 | return 0; | 195 | return 0; |
| 196 | } | 196 | } |
| @@ -268,10 +268,10 @@ static int vlan_seq_show(struct seq_file *seq, void *v) | |||
| 268 | nmtype ? nmtype : "UNKNOWN"); | 268 | nmtype ? nmtype : "UNKNOWN"); |
| 269 | } else { | 269 | } else { |
| 270 | const struct net_device *vlandev = v; | 270 | const struct net_device *vlandev = v; |
| 271 | const struct vlan_dev_priv *vlan = vlan_dev_priv(vlandev); | 271 | const struct vlan_dev_info *dev_info = vlan_dev_info(vlandev); |
| 272 | 272 | ||
| 273 | seq_printf(seq, "%-15s| %d | %s\n", vlandev->name, | 273 | seq_printf(seq, "%-15s| %d | %s\n", vlandev->name, |
| 274 | vlan->vlan_id, vlan->real_dev->name); | 274 | dev_info->vlan_id, dev_info->real_dev->name); |
| 275 | } | 275 | } |
| 276 | return 0; | 276 | return 0; |
| 277 | } | 277 | } |
| @@ -279,7 +279,7 @@ static int vlan_seq_show(struct seq_file *seq, void *v) | |||
| 279 | static int vlandev_seq_show(struct seq_file *seq, void *offset) | 279 | static int vlandev_seq_show(struct seq_file *seq, void *offset) |
| 280 | { | 280 | { |
| 281 | struct net_device *vlandev = (struct net_device *) seq->private; | 281 | struct net_device *vlandev = (struct net_device *) seq->private; |
| 282 | const struct vlan_dev_priv *vlan = vlan_dev_priv(vlandev); | 282 | const struct vlan_dev_info *dev_info = vlan_dev_info(vlandev); |
| 283 | struct rtnl_link_stats64 temp; | 283 | struct rtnl_link_stats64 temp; |
| 284 | const struct rtnl_link_stats64 *stats; | 284 | const struct rtnl_link_stats64 *stats; |
| 285 | static const char fmt64[] = "%30s %12llu\n"; | 285 | static const char fmt64[] = "%30s %12llu\n"; |
| @@ -291,8 +291,8 @@ static int vlandev_seq_show(struct seq_file *seq, void *offset) | |||
| 291 | stats = dev_get_stats(vlandev, &temp); | 291 | stats = dev_get_stats(vlandev, &temp); |
| 292 | seq_printf(seq, | 292 | seq_printf(seq, |
| 293 | "%s VID: %d REORDER_HDR: %i dev->priv_flags: %hx\n", | 293 | "%s VID: %d REORDER_HDR: %i dev->priv_flags: %hx\n", |
| 294 | vlandev->name, vlan->vlan_id, | 294 | vlandev->name, dev_info->vlan_id, |
| 295 | (int)(vlan->flags & 1), vlandev->priv_flags); | 295 | (int)(dev_info->flags & 1), vlandev->priv_flags); |
| 296 | 296 | ||
| 297 | seq_printf(seq, fmt64, "total frames received", stats->rx_packets); | 297 | seq_printf(seq, fmt64, "total frames received", stats->rx_packets); |
| 298 | seq_printf(seq, fmt64, "total bytes received", stats->rx_bytes); | 298 | seq_printf(seq, fmt64, "total bytes received", stats->rx_bytes); |
| @@ -300,23 +300,23 @@ static int vlandev_seq_show(struct seq_file *seq, void *offset) | |||
| 300 | seq_puts(seq, "\n"); | 300 | seq_puts(seq, "\n"); |
| 301 | seq_printf(seq, fmt64, "total frames transmitted", stats->tx_packets); | 301 | seq_printf(seq, fmt64, "total frames transmitted", stats->tx_packets); |
| 302 | seq_printf(seq, fmt64, "total bytes transmitted", stats->tx_bytes); | 302 | seq_printf(seq, fmt64, "total bytes transmitted", stats->tx_bytes); |
| 303 | seq_printf(seq, "Device: %s", vlan->real_dev->name); | 303 | seq_printf(seq, "Device: %s", dev_info->real_dev->name); |
| 304 | /* now show all PRIORITY mappings relating to this VLAN */ | 304 | /* now show all PRIORITY mappings relating to this VLAN */ |
| 305 | seq_printf(seq, "\nINGRESS priority mappings: " | 305 | seq_printf(seq, "\nINGRESS priority mappings: " |
| 306 | "0:%u 1:%u 2:%u 3:%u 4:%u 5:%u 6:%u 7:%u\n", | 306 | "0:%u 1:%u 2:%u 3:%u 4:%u 5:%u 6:%u 7:%u\n", |
| 307 | vlan->ingress_priority_map[0], | 307 | dev_info->ingress_priority_map[0], |
| 308 | vlan->ingress_priority_map[1], | 308 | dev_info->ingress_priority_map[1], |
| 309 | vlan->ingress_priority_map[2], | 309 | dev_info->ingress_priority_map[2], |
| 310 | vlan->ingress_priority_map[3], | 310 | dev_info->ingress_priority_map[3], |
| 311 | vlan->ingress_priority_map[4], | 311 | dev_info->ingress_priority_map[4], |
| 312 | vlan->ingress_priority_map[5], | 312 | dev_info->ingress_priority_map[5], |
| 313 | vlan->ingress_priority_map[6], | 313 | dev_info->ingress_priority_map[6], |
| 314 | vlan->ingress_priority_map[7]); | 314 | dev_info->ingress_priority_map[7]); |
| 315 | 315 | ||
| 316 | seq_printf(seq, " EGRESS priority mappings: "); | 316 | seq_printf(seq, " EGRESS priority mappings: "); |
| 317 | for (i = 0; i < 16; i++) { | 317 | for (i = 0; i < 16; i++) { |
| 318 | const struct vlan_priority_tci_mapping *mp | 318 | const struct vlan_priority_tci_mapping *mp |
| 319 | = vlan->egress_priority_map[i]; | 319 | = dev_info->egress_priority_map[i]; |
| 320 | while (mp) { | 320 | while (mp) { |
| 321 | seq_printf(seq, "%u:%hu ", | 321 | seq_printf(seq, "%u:%hu ", |
| 322 | mp->priority, ((mp->vlan_qos >> 13) & 0x7)); | 322 | mp->priority, ((mp->vlan_qos >> 13) & 0x7)); |
