xref: /openbmc/linux/net/bridge/br_vlan.c (revision 6cbdceeb)
1 #include <linux/kernel.h>
2 #include <linux/netdevice.h>
3 #include <linux/rtnetlink.h>
4 #include <linux/slab.h>
5 
6 #include "br_private.h"
7 
8 static int __vlan_add(struct net_port_vlans *v, u16 vid)
9 {
10 	int err;
11 
12 	if (test_bit(vid, v->vlan_bitmap))
13 		return -EEXIST;
14 
15 	if (v->port_idx && vid) {
16 		struct net_device *dev = v->parent.port->dev;
17 
18 		/* Add VLAN to the device filter if it is supported.
19 		 * Stricly speaking, this is not necessary now, since devices
20 		 * are made promiscuous by the bridge, but if that ever changes
21 		 * this code will allow tagged traffic to enter the bridge.
22 		 */
23 		if (dev->features & NETIF_F_HW_VLAN_FILTER) {
24 			err = dev->netdev_ops->ndo_vlan_rx_add_vid(dev, vid);
25 			if (err)
26 				return err;
27 		}
28 	}
29 
30 	set_bit(vid, v->vlan_bitmap);
31 	v->num_vlans++;
32 	return 0;
33 }
34 
35 static int __vlan_del(struct net_port_vlans *v, u16 vid)
36 {
37 	if (!test_bit(vid, v->vlan_bitmap))
38 		return -EINVAL;
39 
40 	if (v->port_idx && vid) {
41 		struct net_device *dev = v->parent.port->dev;
42 
43 		if (dev->features & NETIF_F_HW_VLAN_FILTER)
44 			dev->netdev_ops->ndo_vlan_rx_kill_vid(dev, vid);
45 	}
46 
47 	clear_bit(vid, v->vlan_bitmap);
48 	v->num_vlans--;
49 	if (bitmap_empty(v->vlan_bitmap, BR_VLAN_BITMAP_LEN)) {
50 		if (v->port_idx)
51 			rcu_assign_pointer(v->parent.port->vlan_info, NULL);
52 		else
53 			rcu_assign_pointer(v->parent.br->vlan_info, NULL);
54 		kfree_rcu(v, rcu);
55 	}
56 	return 0;
57 }
58 
59 static void __vlan_flush(struct net_port_vlans *v)
60 {
61 	bitmap_zero(v->vlan_bitmap, BR_VLAN_BITMAP_LEN);
62 	if (v->port_idx)
63 		rcu_assign_pointer(v->parent.port->vlan_info, NULL);
64 	else
65 		rcu_assign_pointer(v->parent.br->vlan_info, NULL);
66 	kfree_rcu(v, rcu);
67 }
68 
69 /* Called under RCU */
70 bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v,
71 			struct sk_buff *skb)
72 {
73 	u16 vid;
74 
75 	/* If VLAN filtering is disabled on the bridge, all packets are
76 	 * permitted.
77 	 */
78 	if (!br->vlan_enabled)
79 		return true;
80 
81 	/* If there are no vlan in the permitted list, all packets are
82 	 * rejected.
83 	 */
84 	if (!v)
85 		return false;
86 
87 	br_vlan_get_tag(skb, &vid);
88 	if (test_bit(vid, v->vlan_bitmap))
89 		return true;
90 
91 	return false;
92 }
93 
94 /* Called under RCU. */
95 bool br_allowed_egress(struct net_bridge *br,
96 		       const struct net_port_vlans *v,
97 		       const struct sk_buff *skb)
98 {
99 	u16 vid;
100 
101 	if (!br->vlan_enabled)
102 		return true;
103 
104 	if (!v)
105 		return false;
106 
107 	br_vlan_get_tag(skb, &vid);
108 	if (test_bit(vid, v->vlan_bitmap))
109 		return true;
110 
111 	return false;
112 }
113 
114 /* Must be protected by RTNL */
115 int br_vlan_add(struct net_bridge *br, u16 vid)
116 {
117 	struct net_port_vlans *pv = NULL;
118 	int err;
119 
120 	ASSERT_RTNL();
121 
122 	pv = rtnl_dereference(br->vlan_info);
123 	if (pv)
124 		return __vlan_add(pv, vid);
125 
126 	/* Create port vlan infomration
127 	 */
128 	pv = kzalloc(sizeof(*pv), GFP_KERNEL);
129 	if (!pv)
130 		return -ENOMEM;
131 
132 	pv->parent.br = br;
133 	err = __vlan_add(pv, vid);
134 	if (err)
135 		goto out;
136 
137 	rcu_assign_pointer(br->vlan_info, pv);
138 	return 0;
139 out:
140 	kfree(pv);
141 	return err;
142 }
143 
144 /* Must be protected by RTNL */
145 int br_vlan_delete(struct net_bridge *br, u16 vid)
146 {
147 	struct net_port_vlans *pv;
148 
149 	ASSERT_RTNL();
150 
151 	pv = rtnl_dereference(br->vlan_info);
152 	if (!pv)
153 		return -EINVAL;
154 
155 	__vlan_del(pv, vid);
156 	return 0;
157 }
158 
159 void br_vlan_flush(struct net_bridge *br)
160 {
161 	struct net_port_vlans *pv;
162 
163 	ASSERT_RTNL();
164 
165 	pv = rtnl_dereference(br->vlan_info);
166 	if (!pv)
167 		return;
168 
169 	__vlan_flush(pv);
170 }
171 
172 int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val)
173 {
174 	if (!rtnl_trylock())
175 		return restart_syscall();
176 
177 	if (br->vlan_enabled == val)
178 		goto unlock;
179 
180 	br->vlan_enabled = val;
181 
182 unlock:
183 	rtnl_unlock();
184 	return 0;
185 }
186 
187 /* Must be protected by RTNL */
188 int nbp_vlan_add(struct net_bridge_port *port, u16 vid)
189 {
190 	struct net_port_vlans *pv = NULL;
191 	int err;
192 
193 	ASSERT_RTNL();
194 
195 	pv = rtnl_dereference(port->vlan_info);
196 	if (pv)
197 		return __vlan_add(pv, vid);
198 
199 	/* Create port vlan infomration
200 	 */
201 	pv = kzalloc(sizeof(*pv), GFP_KERNEL);
202 	if (!pv) {
203 		err = -ENOMEM;
204 		goto clean_up;
205 	}
206 
207 	pv->port_idx = port->port_no;
208 	pv->parent.port = port;
209 	err = __vlan_add(pv, vid);
210 	if (err)
211 		goto clean_up;
212 
213 	rcu_assign_pointer(port->vlan_info, pv);
214 	return 0;
215 
216 clean_up:
217 	kfree(pv);
218 	return err;
219 }
220 
221 /* Must be protected by RTNL */
222 int nbp_vlan_delete(struct net_bridge_port *port, u16 vid)
223 {
224 	struct net_port_vlans *pv;
225 
226 	ASSERT_RTNL();
227 
228 	pv = rtnl_dereference(port->vlan_info);
229 	if (!pv)
230 		return -EINVAL;
231 
232 	return __vlan_del(pv, vid);
233 }
234 
235 void nbp_vlan_flush(struct net_bridge_port *port)
236 {
237 	struct net_port_vlans *pv;
238 
239 	ASSERT_RTNL();
240 
241 	pv = rtnl_dereference(port->vlan_info);
242 	if (!pv)
243 		return;
244 
245 	__vlan_flush(pv);
246 }
247