@@ -60,7 +60,7 @@ static int __vlan_add(struct net_port_vlans *v, u16 vid, u16 flags)
60
60
* that ever changes this code will allow tagged
61
61
* traffic to enter the bridge.
62
62
*/
63
- err = vlan_vid_add (dev , htons ( ETH_P_8021Q ) , vid );
63
+ err = vlan_vid_add (dev , br -> vlan_proto , vid );
64
64
if (err )
65
65
return err ;
66
66
}
@@ -80,7 +80,7 @@ static int __vlan_add(struct net_port_vlans *v, u16 vid, u16 flags)
80
80
81
81
out_filt :
82
82
if (p )
83
- vlan_vid_del (dev , htons ( ETH_P_8021Q ) , vid );
83
+ vlan_vid_del (dev , br -> vlan_proto , vid );
84
84
return err ;
85
85
}
86
86
@@ -92,8 +92,10 @@ static int __vlan_del(struct net_port_vlans *v, u16 vid)
92
92
__vlan_delete_pvid (v , vid );
93
93
clear_bit (vid , v -> untagged_bitmap );
94
94
95
- if (v -> port_idx )
96
- vlan_vid_del (v -> parent .port -> dev , htons (ETH_P_8021Q ), vid );
95
+ if (v -> port_idx ) {
96
+ struct net_bridge_port * p = v -> parent .port ;
97
+ vlan_vid_del (p -> dev , p -> br -> vlan_proto , vid );
98
+ }
97
99
98
100
clear_bit (vid , v -> vlan_bitmap );
99
101
v -> num_vlans -- ;
@@ -158,7 +160,8 @@ struct sk_buff *br_handle_vlan(struct net_bridge *br,
158
160
bool br_allowed_ingress (struct net_bridge * br , struct net_port_vlans * v ,
159
161
struct sk_buff * skb , u16 * vid )
160
162
{
161
- int err ;
163
+ bool tagged ;
164
+ __be16 proto ;
162
165
163
166
/* If VLAN filtering is disabled on the bridge, all packets are
164
167
* permitted.
@@ -172,19 +175,41 @@ bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v,
172
175
if (!v )
173
176
goto drop ;
174
177
178
+ proto = br -> vlan_proto ;
179
+
175
180
/* If vlan tx offload is disabled on bridge device and frame was
176
181
* sent from vlan device on the bridge device, it does not have
177
182
* HW accelerated vlan tag.
178
183
*/
179
184
if (unlikely (!vlan_tx_tag_present (skb ) &&
180
- (skb -> protocol == htons (ETH_P_8021Q ) ||
181
- skb -> protocol == htons (ETH_P_8021AD )))) {
185
+ skb -> protocol == proto )) {
182
186
skb = vlan_untag (skb );
183
187
if (unlikely (!skb ))
184
188
return false;
185
189
}
186
190
187
- err = br_vlan_get_tag (skb , vid );
191
+ if (!br_vlan_get_tag (skb , vid )) {
192
+ /* Tagged frame */
193
+ if (skb -> vlan_proto != proto ) {
194
+ /* Protocol-mismatch, empty out vlan_tci for new tag */
195
+ skb_push (skb , ETH_HLEN );
196
+ skb = __vlan_put_tag (skb , skb -> vlan_proto ,
197
+ vlan_tx_tag_get (skb ));
198
+ if (unlikely (!skb ))
199
+ return false;
200
+
201
+ skb_pull (skb , ETH_HLEN );
202
+ skb_reset_mac_len (skb );
203
+ * vid = 0 ;
204
+ tagged = false;
205
+ } else {
206
+ tagged = true;
207
+ }
208
+ } else {
209
+ /* Untagged frame */
210
+ tagged = false;
211
+ }
212
+
188
213
if (!* vid ) {
189
214
u16 pvid = br_get_pvid (v );
190
215
@@ -199,9 +224,9 @@ bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v,
199
224
* ingress frame is considered to belong to this vlan.
200
225
*/
201
226
* vid = pvid ;
202
- if (likely (err ))
227
+ if (likely (! tagged ))
203
228
/* Untagged Frame. */
204
- __vlan_hwaccel_put_tag (skb , htons ( ETH_P_8021Q ) , pvid );
229
+ __vlan_hwaccel_put_tag (skb , proto , pvid );
205
230
else
206
231
/* Priority-tagged Frame.
207
232
* At this point, We know that skb->vlan_tci had
@@ -254,7 +279,9 @@ bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid)
254
279
if (!v )
255
280
return false;
256
281
257
- br_vlan_get_tag (skb , vid );
282
+ if (!br_vlan_get_tag (skb , vid ) && skb -> vlan_proto != br -> vlan_proto )
283
+ * vid = 0 ;
284
+
258
285
if (!* vid ) {
259
286
* vid = br_get_pvid (v );
260
287
if (* vid == VLAN_N_VID )
@@ -367,6 +394,11 @@ int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val)
367
394
return 0 ;
368
395
}
369
396
397
+ void br_vlan_init (struct net_bridge * br )
398
+ {
399
+ br -> vlan_proto = htons (ETH_P_8021Q );
400
+ }
401
+
370
402
/* Must be protected by RTNL.
371
403
* Must be called with vid in range from 1 to 4094 inclusive.
372
404
*/
@@ -433,7 +465,7 @@ void nbp_vlan_flush(struct net_bridge_port *port)
433
465
return ;
434
466
435
467
for_each_set_bit (vid , pv -> vlan_bitmap , VLAN_N_VID )
436
- vlan_vid_del (port -> dev , htons ( ETH_P_8021Q ) , vid );
468
+ vlan_vid_del (port -> dev , port -> br -> vlan_proto , vid );
437
469
438
470
__vlan_flush (pv );
439
471
}
0 commit comments