.. | .. |
---|
| 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 | */ |
---|