| .. | .. |
|---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-or-later */ |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * VLAN An implementation of 802.1Q VLAN tagging. |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Authors: Ben Greear <greearb@candelatech.com> |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or |
|---|
| 7 | | - * modify it under the terms of the GNU General Public License |
|---|
| 8 | | - * as published by the Free Software Foundation; either version |
|---|
| 9 | | - * 2 of the License, or (at your option) any later version. |
|---|
| 10 | | - * |
|---|
| 11 | 6 | */ |
|---|
| 12 | 7 | #ifndef _LINUX_IF_VLAN_H_ |
|---|
| 13 | 8 | #define _LINUX_IF_VLAN_H_ |
|---|
| .. | .. |
|---|
| 67 | 62 | |
|---|
| 68 | 63 | #define VLAN_PRIO_MASK 0xe000 /* Priority Code Point */ |
|---|
| 69 | 64 | #define VLAN_PRIO_SHIFT 13 |
|---|
| 70 | | -#define VLAN_CFI_MASK 0x1000 /* Canonical Format Indicator */ |
|---|
| 71 | | -#define VLAN_TAG_PRESENT VLAN_CFI_MASK |
|---|
| 65 | +#define VLAN_CFI_MASK 0x1000 /* Canonical Format Indicator / Drop Eligible Indicator */ |
|---|
| 72 | 66 | #define VLAN_VID_MASK 0x0fff /* VLAN Identifier */ |
|---|
| 73 | 67 | #define VLAN_N_VID 4096 |
|---|
| 74 | 68 | |
|---|
| .. | .. |
|---|
| 80 | 74 | return dev->priv_flags & IFF_802_1Q_VLAN; |
|---|
| 81 | 75 | } |
|---|
| 82 | 76 | |
|---|
| 83 | | -#define skb_vlan_tag_present(__skb) ((__skb)->vlan_tci & VLAN_TAG_PRESENT) |
|---|
| 84 | | -#define skb_vlan_tag_get(__skb) ((__skb)->vlan_tci & ~VLAN_TAG_PRESENT) |
|---|
| 77 | +#define skb_vlan_tag_present(__skb) ((__skb)->vlan_present) |
|---|
| 78 | +#define skb_vlan_tag_get(__skb) ((__skb)->vlan_tci) |
|---|
| 85 | 79 | #define skb_vlan_tag_get_id(__skb) ((__skb)->vlan_tci & VLAN_VID_MASK) |
|---|
| 86 | | -#define skb_vlan_tag_get_prio(__skb) ((__skb)->vlan_tci & VLAN_PRIO_MASK) |
|---|
| 80 | +#define skb_vlan_tag_get_cfi(__skb) (!!((__skb)->vlan_tci & VLAN_CFI_MASK)) |
|---|
| 81 | +#define skb_vlan_tag_get_prio(__skb) (((__skb)->vlan_tci & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT) |
|---|
| 87 | 82 | |
|---|
| 88 | 83 | static inline int vlan_get_rx_ctag_filter_info(struct net_device *dev) |
|---|
| 89 | 84 | { |
|---|
| .. | .. |
|---|
| 135 | 130 | |
|---|
| 136 | 131 | extern struct net_device *__vlan_find_dev_deep_rcu(struct net_device *real_dev, |
|---|
| 137 | 132 | __be16 vlan_proto, u16 vlan_id); |
|---|
| 133 | +extern int vlan_for_each(struct net_device *dev, |
|---|
| 134 | + int (*action)(struct net_device *dev, int vid, |
|---|
| 135 | + void *arg), void *arg); |
|---|
| 138 | 136 | extern struct net_device *vlan_dev_real_dev(const struct net_device *dev); |
|---|
| 139 | 137 | extern u16 vlan_dev_vlan_id(const struct net_device *dev); |
|---|
| 140 | 138 | extern __be16 vlan_dev_vlan_proto(const struct net_device *dev); |
|---|
| .. | .. |
|---|
| 186 | 184 | #ifdef CONFIG_NET_POLL_CONTROLLER |
|---|
| 187 | 185 | struct netpoll *netpoll; |
|---|
| 188 | 186 | #endif |
|---|
| 189 | | - unsigned int nest_level; |
|---|
| 190 | 187 | }; |
|---|
| 191 | 188 | |
|---|
| 192 | 189 | static inline struct vlan_dev_priv *vlan_dev_priv(const struct net_device *dev) |
|---|
| .. | .. |
|---|
| 225 | 222 | |
|---|
| 226 | 223 | extern bool vlan_uses_dev(const struct net_device *dev); |
|---|
| 227 | 224 | |
|---|
| 228 | | -static inline int vlan_get_encap_level(struct net_device *dev) |
|---|
| 229 | | -{ |
|---|
| 230 | | - BUG_ON(!is_vlan_dev(dev)); |
|---|
| 231 | | - return vlan_dev_priv(dev)->nest_level; |
|---|
| 232 | | -} |
|---|
| 233 | 225 | #else |
|---|
| 234 | 226 | static inline struct net_device * |
|---|
| 235 | 227 | __vlan_find_dev_deep_rcu(struct net_device *real_dev, |
|---|
| 236 | 228 | __be16 vlan_proto, u16 vlan_id) |
|---|
| 237 | 229 | { |
|---|
| 238 | 230 | return NULL; |
|---|
| 231 | +} |
|---|
| 232 | + |
|---|
| 233 | +static inline int |
|---|
| 234 | +vlan_for_each(struct net_device *dev, |
|---|
| 235 | + int (*action)(struct net_device *dev, int vid, void *arg), |
|---|
| 236 | + void *arg) |
|---|
| 237 | +{ |
|---|
| 238 | + return 0; |
|---|
| 239 | 239 | } |
|---|
| 240 | 240 | |
|---|
| 241 | 241 | static inline struct net_device *vlan_dev_real_dev(const struct net_device *dev) |
|---|
| .. | .. |
|---|
| 290 | 290 | static inline bool vlan_uses_dev(const struct net_device *dev) |
|---|
| 291 | 291 | { |
|---|
| 292 | 292 | return false; |
|---|
| 293 | | -} |
|---|
| 294 | | -static inline int vlan_get_encap_level(struct net_device *dev) |
|---|
| 295 | | -{ |
|---|
| 296 | | - BUG(); |
|---|
| 297 | | - return 0; |
|---|
| 298 | 293 | } |
|---|
| 299 | 294 | #endif |
|---|
| 300 | 295 | |
|---|
| .. | .. |
|---|
| 463 | 458 | return skb; |
|---|
| 464 | 459 | } |
|---|
| 465 | 460 | |
|---|
| 461 | +/** |
|---|
| 462 | + * __vlan_hwaccel_clear_tag - clear hardware accelerated VLAN info |
|---|
| 463 | + * @skb: skbuff to clear |
|---|
| 464 | + * |
|---|
| 465 | + * Clears the VLAN information from @skb |
|---|
| 466 | + */ |
|---|
| 467 | +static inline void __vlan_hwaccel_clear_tag(struct sk_buff *skb) |
|---|
| 468 | +{ |
|---|
| 469 | + skb->vlan_present = 0; |
|---|
| 470 | +} |
|---|
| 471 | + |
|---|
| 472 | +/** |
|---|
| 473 | + * __vlan_hwaccel_copy_tag - copy hardware accelerated VLAN info from another skb |
|---|
| 474 | + * @dst: skbuff to copy to |
|---|
| 475 | + * @src: skbuff to copy from |
|---|
| 476 | + * |
|---|
| 477 | + * Copies VLAN information from @src to @dst (for branchless code) |
|---|
| 478 | + */ |
|---|
| 479 | +static inline void __vlan_hwaccel_copy_tag(struct sk_buff *dst, const struct sk_buff *src) |
|---|
| 480 | +{ |
|---|
| 481 | + dst->vlan_present = src->vlan_present; |
|---|
| 482 | + dst->vlan_proto = src->vlan_proto; |
|---|
| 483 | + dst->vlan_tci = src->vlan_tci; |
|---|
| 484 | +} |
|---|
| 485 | + |
|---|
| 466 | 486 | /* |
|---|
| 467 | 487 | * __vlan_hwaccel_push_inside - pushes vlan tag to the payload |
|---|
| 468 | 488 | * @skb: skbuff to tag |
|---|
| .. | .. |
|---|
| 477 | 497 | skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, |
|---|
| 478 | 498 | skb_vlan_tag_get(skb)); |
|---|
| 479 | 499 | if (likely(skb)) |
|---|
| 480 | | - skb->vlan_tci = 0; |
|---|
| 500 | + __vlan_hwaccel_clear_tag(skb); |
|---|
| 481 | 501 | return skb; |
|---|
| 482 | 502 | } |
|---|
| 483 | 503 | |
|---|
| .. | .. |
|---|
| 493 | 513 | __be16 vlan_proto, u16 vlan_tci) |
|---|
| 494 | 514 | { |
|---|
| 495 | 515 | skb->vlan_proto = vlan_proto; |
|---|
| 496 | | - skb->vlan_tci = VLAN_TAG_PRESENT | vlan_tci; |
|---|
| 516 | + skb->vlan_tci = vlan_tci; |
|---|
| 517 | + skb->vlan_present = 1; |
|---|
| 497 | 518 | } |
|---|
| 498 | 519 | |
|---|
| 499 | 520 | /** |
|---|
| .. | .. |
|---|
| 532 | 553 | return -EINVAL; |
|---|
| 533 | 554 | } |
|---|
| 534 | 555 | } |
|---|
| 535 | | - |
|---|
| 536 | | -#define HAVE_VLAN_GET_TAG |
|---|
| 537 | 556 | |
|---|
| 538 | 557 | /** |
|---|
| 539 | 558 | * vlan_get_tag - get the VLAN ID from the skb |
|---|
| .. | .. |
|---|
| 607 | 626 | return __vlan_get_protocol(skb, skb->protocol, NULL); |
|---|
| 608 | 627 | } |
|---|
| 609 | 628 | |
|---|
| 629 | +/* This version of __vlan_get_protocol() also pulls mac header in skb->head */ |
|---|
| 630 | +static inline __be16 vlan_get_protocol_and_depth(struct sk_buff *skb, |
|---|
| 631 | + __be16 type, int *depth) |
|---|
| 632 | +{ |
|---|
| 633 | + int maclen; |
|---|
| 634 | + |
|---|
| 635 | + type = __vlan_get_protocol(skb, type, &maclen); |
|---|
| 636 | + |
|---|
| 637 | + if (type) { |
|---|
| 638 | + if (!pskb_may_pull(skb, maclen)) |
|---|
| 639 | + type = 0; |
|---|
| 640 | + else if (depth) |
|---|
| 641 | + *depth = maclen; |
|---|
| 642 | + } |
|---|
| 643 | + return type; |
|---|
| 644 | +} |
|---|
| 645 | + |
|---|
| 610 | 646 | /* A getter for the SKB protocol field which will handle VLAN tags consistently |
|---|
| 611 | 647 | * whether VLAN acceleration is enabled or not. |
|---|
| 612 | 648 | */ |
|---|