.. | .. |
---|
36 | 36 | struct rcu_head rcu; |
---|
37 | 37 | }; |
---|
38 | 38 | |
---|
39 | | -static inline unsigned int vlan_proto_idx(__be16 proto) |
---|
| 39 | +static inline int vlan_proto_idx(__be16 proto) |
---|
40 | 40 | { |
---|
41 | 41 | switch (proto) { |
---|
42 | 42 | case htons(ETH_P_8021Q): |
---|
.. | .. |
---|
44 | 44 | case htons(ETH_P_8021AD): |
---|
45 | 45 | return VLAN_PROTO_8021AD; |
---|
46 | 46 | default: |
---|
47 | | - BUG(); |
---|
48 | | - return 0; |
---|
| 47 | + WARN(1, "invalid VLAN protocol: 0x%04x\n", ntohs(proto)); |
---|
| 48 | + return -EINVAL; |
---|
49 | 49 | } |
---|
50 | 50 | } |
---|
51 | 51 | |
---|
.. | .. |
---|
64 | 64 | __be16 vlan_proto, |
---|
65 | 65 | u16 vlan_id) |
---|
66 | 66 | { |
---|
67 | | - return __vlan_group_get_device(vg, vlan_proto_idx(vlan_proto), vlan_id); |
---|
| 67 | + int pidx = vlan_proto_idx(vlan_proto); |
---|
| 68 | + |
---|
| 69 | + if (pidx < 0) |
---|
| 70 | + return NULL; |
---|
| 71 | + |
---|
| 72 | + return __vlan_group_get_device(vg, pidx, vlan_id); |
---|
68 | 73 | } |
---|
69 | 74 | |
---|
70 | 75 | static inline void vlan_group_set_device(struct vlan_group *vg, |
---|
71 | 76 | __be16 vlan_proto, u16 vlan_id, |
---|
72 | 77 | struct net_device *dev) |
---|
73 | 78 | { |
---|
| 79 | + int pidx = vlan_proto_idx(vlan_proto); |
---|
74 | 80 | struct net_device **array; |
---|
75 | | - if (!vg) |
---|
| 81 | + |
---|
| 82 | + if (!vg || pidx < 0) |
---|
76 | 83 | return; |
---|
77 | | - array = vg->vlan_devices_arrays[vlan_proto_idx(vlan_proto)] |
---|
| 84 | + array = vg->vlan_devices_arrays[pidx] |
---|
78 | 85 | [vlan_id / VLAN_GROUP_ARRAY_PART_LEN]; |
---|
79 | 86 | array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN] = dev; |
---|
80 | 87 | } |
---|
.. | .. |
---|
92 | 99 | return NULL; |
---|
93 | 100 | } |
---|
94 | 101 | |
---|
| 102 | +static inline netdev_features_t vlan_tnl_features(struct net_device *real_dev) |
---|
| 103 | +{ |
---|
| 104 | + netdev_features_t ret; |
---|
| 105 | + |
---|
| 106 | + ret = real_dev->hw_enc_features & |
---|
| 107 | + (NETIF_F_CSUM_MASK | NETIF_F_ALL_TSO | NETIF_F_GSO_ENCAP_ALL); |
---|
| 108 | + |
---|
| 109 | + if ((ret & NETIF_F_GSO_ENCAP_ALL) && (ret & NETIF_F_CSUM_MASK)) |
---|
| 110 | + return (ret & ~NETIF_F_CSUM_MASK) | NETIF_F_HW_CSUM; |
---|
| 111 | + return 0; |
---|
| 112 | +} |
---|
| 113 | + |
---|
95 | 114 | #define vlan_group_for_each_dev(grp, i, dev) \ |
---|
96 | 115 | for ((i) = 0; i < VLAN_PROTO_NUM * VLAN_N_VID; i++) \ |
---|
97 | 116 | if (((dev) = __vlan_group_get_device((grp), (i) / VLAN_N_VID, \ |
---|