diff options
author | Vlad Yasevich <vyasevic@redhat.com> | 2013-02-13 07:00:14 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-02-13 19:42:15 -0500 |
commit | 7885198861fc9a3dfdc6bb90dc0ba12689d6cd57 (patch) | |
tree | a75ed0f9b3fe72be08dcb13216c87f4f8e37bb75 /net/bridge/br_private.h | |
parent | 6cbdceeb1cb12c7d620161925a8c3e81daadb2e4 (diff) |
bridge: Implement vlan ingress/egress policy with PVID.
At ingress, any untagged traffic is assigned to the PVID.
Any tagged traffic is filtered according to membership bitmap.
At egress, if the vlan matches the PVID, the frame is sent
untagged. Otherwise the frame is sent tagged.
Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge/br_private.h')
-rw-r--r-- | net/bridge/br_private.h | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index ce2235255c2f..ea8e7efd9137 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
@@ -67,6 +67,7 @@ struct br_ip | |||
67 | 67 | ||
68 | struct net_port_vlans { | 68 | struct net_port_vlans { |
69 | u16 port_idx; | 69 | u16 port_idx; |
70 | u16 pvid; | ||
70 | union { | 71 | union { |
71 | struct net_bridge_port *port; | 72 | struct net_bridge_port *port; |
72 | struct net_bridge *br; | 73 | struct net_bridge *br; |
@@ -554,10 +555,13 @@ static inline void br_mdb_uninit(void) | |||
554 | /* br_vlan.c */ | 555 | /* br_vlan.c */ |
555 | #ifdef CONFIG_BRIDGE_VLAN_FILTERING | 556 | #ifdef CONFIG_BRIDGE_VLAN_FILTERING |
556 | extern bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v, | 557 | extern bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v, |
557 | struct sk_buff *skb); | 558 | struct sk_buff *skb, u16 *vid); |
558 | extern bool br_allowed_egress(struct net_bridge *br, | 559 | extern bool br_allowed_egress(struct net_bridge *br, |
559 | const struct net_port_vlans *v, | 560 | const struct net_port_vlans *v, |
560 | const struct sk_buff *skb); | 561 | const struct sk_buff *skb); |
562 | extern struct sk_buff *br_handle_vlan(struct net_bridge *br, | ||
563 | const struct net_port_vlans *v, | ||
564 | struct sk_buff *skb); | ||
561 | extern int br_vlan_add(struct net_bridge *br, u16 vid); | 565 | extern int br_vlan_add(struct net_bridge *br, u16 vid); |
562 | extern int br_vlan_delete(struct net_bridge *br, u16 vid); | 566 | extern int br_vlan_delete(struct net_bridge *br, u16 vid); |
563 | extern void br_vlan_flush(struct net_bridge *br); | 567 | extern void br_vlan_flush(struct net_bridge *br); |
@@ -594,10 +598,23 @@ static inline int br_vlan_get_tag(const struct sk_buff *skb, u16 *vid) | |||
594 | 598 | ||
595 | return err; | 599 | return err; |
596 | } | 600 | } |
601 | |||
602 | static inline u16 br_get_pvid(const struct net_port_vlans *v) | ||
603 | { | ||
604 | /* Return just the VID if it is set, or VLAN_N_VID (invalid vid) if | ||
605 | * vid wasn't set | ||
606 | */ | ||
607 | smp_rmb(); | ||
608 | return (v->pvid & VLAN_TAG_PRESENT) ? | ||
609 | (v->pvid & ~VLAN_TAG_PRESENT) : | ||
610 | VLAN_N_VID; | ||
611 | } | ||
612 | |||
597 | #else | 613 | #else |
598 | static inline bool br_allowed_ingress(struct net_bridge *br, | 614 | static inline bool br_allowed_ingress(struct net_bridge *br, |
599 | struct net_port_vlans *v, | 615 | struct net_port_vlans *v, |
600 | struct sk_buff *skb) | 616 | struct sk_buff *skb, |
617 | u16 *vid) | ||
601 | { | 618 | { |
602 | return true; | 619 | return true; |
603 | } | 620 | } |
@@ -609,6 +626,13 @@ static inline bool br_allowed_egress(struct net_bridge *br, | |||
609 | return true; | 626 | return true; |
610 | } | 627 | } |
611 | 628 | ||
629 | static inline struct sk_buff *br_handle_vlan(struct net_bridge *br, | ||
630 | const struct net_port_vlans *v, | ||
631 | struct sk_buff *skb) | ||
632 | { | ||
633 | return skb; | ||
634 | } | ||
635 | |||
612 | static inline int br_vlan_add(struct net_bridge *br, u16 vid) | 636 | static inline int br_vlan_add(struct net_bridge *br, u16 vid) |
613 | { | 637 | { |
614 | return -EOPNOTSUPP; | 638 | return -EOPNOTSUPP; |
@@ -648,10 +672,14 @@ static inline struct net_port_vlans *nbp_get_vlan_info( | |||
648 | return NULL; | 672 | return NULL; |
649 | } | 673 | } |
650 | 674 | ||
651 | static inline u16 br_vlan_get_tag(const struct sk_buff *skb) | 675 | static inline u16 br_vlan_get_tag(const struct sk_buff *skb, u16 *tag) |
652 | { | 676 | { |
653 | return 0; | 677 | return 0; |
654 | } | 678 | } |
679 | static inline u16 br_get_pvid(const struct net_port_vlans *v) | ||
680 | { | ||
681 | return VLAN_N_VID; /* Returns invalid vid */ | ||
682 | } | ||
655 | #endif | 683 | #endif |
656 | 684 | ||
657 | /* br_netfilter.c */ | 685 | /* br_netfilter.c */ |