aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch
diff options
context:
space:
mode:
authorEric Garver <e@erig.me>2016-09-07 12:56:59 -0400
committerDavid S. Miller <davem@davemloft.net>2016-09-08 20:10:28 -0400
commit018c1dda5ff1e7bd1fe2d9fd1d0f5b82dc6fc0cd (patch)
treeccedb1acda9922d975903894776dcfb853fc3c2d /net/openvswitch
parentfe19c4f971a55cea3be442d8032a5f6021702791 (diff)
openvswitch: 802.1AD Flow handling, actions, vlan parsing, netlink attributes
Add support for 802.1ad including the ability to push and pop double tagged vlans. Add support for 802.1ad to netlink parsing and flow conversion. Uses double nested encap attributes to represent double tagged vlan. Inner TPID encoded along with ctci in nested attributes. This is based on Thomas F Herbert's original v20 patch. I made some small clean ups and bug fixes. Signed-off-by: Thomas F Herbert <thomasfherbert@gmail.com> Signed-off-by: Eric Garver <e@erig.me> Acked-by: Pravin B Shelar <pshelar@ovn.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/openvswitch')
-rw-r--r--net/openvswitch/actions.c16
-rw-r--r--net/openvswitch/flow.c65
-rw-r--r--net/openvswitch/flow.h8
-rw-r--r--net/openvswitch/flow_netlink.c310
-rw-r--r--net/openvswitch/vport.c7
5 files changed, 282 insertions, 124 deletions
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
index ca91fc33f8a9..4fe9032b1160 100644
--- a/net/openvswitch/actions.c
+++ b/net/openvswitch/actions.c
@@ -246,20 +246,24 @@ static int pop_vlan(struct sk_buff *skb, struct sw_flow_key *key)
246 int err; 246 int err;
247 247
248 err = skb_vlan_pop(skb); 248 err = skb_vlan_pop(skb);
249 if (skb_vlan_tag_present(skb)) 249 if (skb_vlan_tag_present(skb)) {
250 invalidate_flow_key(key); 250 invalidate_flow_key(key);
251 else 251 } else {
252 key->eth.tci = 0; 252 key->eth.vlan.tci = 0;
253 key->eth.vlan.tpid = 0;
254 }
253 return err; 255 return err;
254} 256}
255 257
256static int push_vlan(struct sk_buff *skb, struct sw_flow_key *key, 258static int push_vlan(struct sk_buff *skb, struct sw_flow_key *key,
257 const struct ovs_action_push_vlan *vlan) 259 const struct ovs_action_push_vlan *vlan)
258{ 260{
259 if (skb_vlan_tag_present(skb)) 261 if (skb_vlan_tag_present(skb)) {
260 invalidate_flow_key(key); 262 invalidate_flow_key(key);
261 else 263 } else {
262 key->eth.tci = vlan->vlan_tci; 264 key->eth.vlan.tci = vlan->vlan_tci;
265 key->eth.vlan.tpid = vlan->vlan_tpid;
266 }
263 return skb_vlan_push(skb, vlan->vlan_tpid, 267 return skb_vlan_push(skb, vlan->vlan_tpid,
264 ntohs(vlan->vlan_tci) & ~VLAN_TAG_PRESENT); 268 ntohs(vlan->vlan_tci) & ~VLAN_TAG_PRESENT);
265} 269}
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
index 0ea128eeeab2..1240ae3b88d2 100644
--- a/net/openvswitch/flow.c
+++ b/net/openvswitch/flow.c
@@ -302,24 +302,57 @@ static bool icmp6hdr_ok(struct sk_buff *skb)
302 sizeof(struct icmp6hdr)); 302 sizeof(struct icmp6hdr));
303} 303}
304 304
305static int parse_vlan(struct sk_buff *skb, struct sw_flow_key *key) 305/**
306 * Parse vlan tag from vlan header.
307 * Returns ERROR on memory error.
308 * Returns 0 if it encounters a non-vlan or incomplete packet.
309 * Returns 1 after successfully parsing vlan tag.
310 */
311static int parse_vlan_tag(struct sk_buff *skb, struct vlan_head *key_vh)
306{ 312{
307 struct qtag_prefix { 313 struct vlan_head *vh = (struct vlan_head *)skb->data;
308 __be16 eth_type; /* ETH_P_8021Q */
309 __be16 tci;
310 };
311 struct qtag_prefix *qp;
312 314
313 if (unlikely(skb->len < sizeof(struct qtag_prefix) + sizeof(__be16))) 315 if (likely(!eth_type_vlan(vh->tpid)))
314 return 0; 316 return 0;
315 317
316 if (unlikely(!pskb_may_pull(skb, sizeof(struct qtag_prefix) + 318 if (unlikely(skb->len < sizeof(struct vlan_head) + sizeof(__be16)))
317 sizeof(__be16)))) 319 return 0;
320
321 if (unlikely(!pskb_may_pull(skb, sizeof(struct vlan_head) +
322 sizeof(__be16))))
318 return -ENOMEM; 323 return -ENOMEM;
319 324
320 qp = (struct qtag_prefix *) skb->data; 325 vh = (struct vlan_head *)skb->data;
321 key->eth.tci = qp->tci | htons(VLAN_TAG_PRESENT); 326 key_vh->tci = vh->tci | htons(VLAN_TAG_PRESENT);
322 __skb_pull(skb, sizeof(struct qtag_prefix)); 327 key_vh->tpid = vh->tpid;
328
329 __skb_pull(skb, sizeof(struct vlan_head));
330 return 1;
331}
332
333static int parse_vlan(struct sk_buff *skb, struct sw_flow_key *key)
334{
335 int res;
336
337 key->eth.vlan.tci = 0;
338 key->eth.vlan.tpid = 0;
339 key->eth.cvlan.tci = 0;
340 key->eth.cvlan.tpid = 0;
341
342 if (likely(skb_vlan_tag_present(skb))) {
343 key->eth.vlan.tci = htons(skb->vlan_tci);
344 key->eth.vlan.tpid = skb->vlan_proto;
345 } else {
346 /* Parse outer vlan tag in the non-accelerated case. */
347 res = parse_vlan_tag(skb, &key->eth.vlan);
348 if (res <= 0)
349 return res;
350 }
351
352 /* Parse inner vlan tag. */
353 res = parse_vlan_tag(skb, &key->eth.cvlan);
354 if (res <= 0)
355 return res;
323 356
324 return 0; 357 return 0;
325} 358}
@@ -480,12 +513,8 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
480 * update skb->csum here. 513 * update skb->csum here.
481 */ 514 */
482 515
483 key->eth.tci = 0; 516 if (unlikely(parse_vlan(skb, key)))
484 if (skb_vlan_tag_present(skb)) 517 return -ENOMEM;
485 key->eth.tci = htons(skb->vlan_tci);
486 else if (eth->h_proto == htons(ETH_P_8021Q))
487 if (unlikely(parse_vlan(skb, key)))
488 return -ENOMEM;
489 518
490 key->eth.type = parse_ethertype(skb); 519 key->eth.type = parse_ethertype(skb);
491 if (unlikely(key->eth.type == htons(0))) 520 if (unlikely(key->eth.type == htons(0)))
diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h
index 03378e75a67c..156a3029c17b 100644
--- a/net/openvswitch/flow.h
+++ b/net/openvswitch/flow.h
@@ -50,6 +50,11 @@ struct ovs_tunnel_info {
50 struct metadata_dst *tun_dst; 50 struct metadata_dst *tun_dst;
51}; 51};
52 52
53struct vlan_head {
54 __be16 tpid; /* Vlan type. Generally 802.1q or 802.1ad.*/
55 __be16 tci; /* 0 if no VLAN, VLAN_TAG_PRESENT set otherwise. */
56};
57
53#define OVS_SW_FLOW_KEY_METADATA_SIZE \ 58#define OVS_SW_FLOW_KEY_METADATA_SIZE \
54 (offsetof(struct sw_flow_key, recirc_id) + \ 59 (offsetof(struct sw_flow_key, recirc_id) + \
55 FIELD_SIZEOF(struct sw_flow_key, recirc_id)) 60 FIELD_SIZEOF(struct sw_flow_key, recirc_id))
@@ -69,7 +74,8 @@ struct sw_flow_key {
69 struct { 74 struct {
70 u8 src[ETH_ALEN]; /* Ethernet source address. */ 75 u8 src[ETH_ALEN]; /* Ethernet source address. */
71 u8 dst[ETH_ALEN]; /* Ethernet destination address. */ 76 u8 dst[ETH_ALEN]; /* Ethernet destination address. */
72 __be16 tci; /* 0 if no VLAN, VLAN_TAG_PRESENT set otherwise. */ 77 struct vlan_head vlan;
78 struct vlan_head cvlan;
73 __be16 type; /* Ethernet frame type. */ 79 __be16 type; /* Ethernet frame type. */
74 } eth; 80 } eth;
75 union { 81 union {
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
index c78a6a1476fb..8efa718ddb5e 100644
--- a/net/openvswitch/flow_netlink.c
+++ b/net/openvswitch/flow_netlink.c
@@ -808,6 +808,167 @@ int ovs_nla_put_tunnel_info(struct sk_buff *skb,
808 ip_tunnel_info_af(tun_info)); 808 ip_tunnel_info_af(tun_info));
809} 809}
810 810
811static int encode_vlan_from_nlattrs(struct sw_flow_match *match,
812 const struct nlattr *a[],
813 bool is_mask, bool inner)
814{
815 __be16 tci = 0;
816 __be16 tpid = 0;
817
818 if (a[OVS_KEY_ATTR_VLAN])
819 tci = nla_get_be16(a[OVS_KEY_ATTR_VLAN]);
820
821 if (a[OVS_KEY_ATTR_ETHERTYPE])
822 tpid = nla_get_be16(a[OVS_KEY_ATTR_ETHERTYPE]);
823
824 if (likely(!inner)) {
825 SW_FLOW_KEY_PUT(match, eth.vlan.tpid, tpid, is_mask);
826 SW_FLOW_KEY_PUT(match, eth.vlan.tci, tci, is_mask);
827 } else {
828 SW_FLOW_KEY_PUT(match, eth.cvlan.tpid, tpid, is_mask);
829 SW_FLOW_KEY_PUT(match, eth.cvlan.tci, tci, is_mask);
830 }
831 return 0;
832}
833
834static int validate_vlan_from_nlattrs(const struct sw_flow_match *match,
835 u64 key_attrs, bool inner,
836 const struct nlattr **a, bool log)
837{
838 __be16 tci = 0;
839
840 if (!((key_attrs & (1 << OVS_KEY_ATTR_ETHERNET)) &&
841 (key_attrs & (1 << OVS_KEY_ATTR_ETHERTYPE)) &&
842 eth_type_vlan(nla_get_be16(a[OVS_KEY_ATTR_ETHERTYPE])))) {
843 /* Not a VLAN. */
844 return 0;
845 }
846
847 if (!((key_attrs & (1 << OVS_KEY_ATTR_VLAN)) &&
848 (key_attrs & (1 << OVS_KEY_ATTR_ENCAP)))) {
849 OVS_NLERR(log, "Invalid %s frame", (inner) ? "C-VLAN" : "VLAN");
850 return -EINVAL;
851 }
852
853 if (a[OVS_KEY_ATTR_VLAN])
854 tci = nla_get_be16(a[OVS_KEY_ATTR_VLAN]);
855
856 if (!(tci & htons(VLAN_TAG_PRESENT))) {
857 if (tci) {
858 OVS_NLERR(log, "%s TCI does not have VLAN_TAG_PRESENT bit set.",
859 (inner) ? "C-VLAN" : "VLAN");
860 return -EINVAL;
861 } else if (nla_len(a[OVS_KEY_ATTR_ENCAP])) {
862 /* Corner case for truncated VLAN header. */
863 OVS_NLERR(log, "Truncated %s header has non-zero encap attribute.",
864 (inner) ? "C-VLAN" : "VLAN");
865 return -EINVAL;
866 }
867 }
868
869 return 1;
870}
871
872static int validate_vlan_mask_from_nlattrs(const struct sw_flow_match *match,
873 u64 key_attrs, bool inner,
874 const struct nlattr **a, bool log)
875{
876 __be16 tci = 0;
877 __be16 tpid = 0;
878 bool encap_valid = !!(match->key->eth.vlan.tci &
879 htons(VLAN_TAG_PRESENT));
880 bool i_encap_valid = !!(match->key->eth.cvlan.tci &
881 htons(VLAN_TAG_PRESENT));
882
883 if (!(key_attrs & (1 << OVS_KEY_ATTR_ENCAP))) {
884 /* Not a VLAN. */
885 return 0;
886 }
887
888 if ((!inner && !encap_valid) || (inner && !i_encap_valid)) {
889 OVS_NLERR(log, "Encap mask attribute is set for non-%s frame.",
890 (inner) ? "C-VLAN" : "VLAN");
891 return -EINVAL;
892 }
893
894 if (a[OVS_KEY_ATTR_VLAN])
895 tci = nla_get_be16(a[OVS_KEY_ATTR_VLAN]);
896
897 if (a[OVS_KEY_ATTR_ETHERTYPE])
898 tpid = nla_get_be16(a[OVS_KEY_ATTR_ETHERTYPE]);
899
900 if (tpid != htons(0xffff)) {
901 OVS_NLERR(log, "Must have an exact match on %s TPID (mask=%x).",
902 (inner) ? "C-VLAN" : "VLAN", ntohs(tpid));
903 return -EINVAL;
904 }
905 if (!(tci & htons(VLAN_TAG_PRESENT))) {
906 OVS_NLERR(log, "%s TCI mask does not have exact match for VLAN_TAG_PRESENT bit.",
907 (inner) ? "C-VLAN" : "VLAN");
908 return -EINVAL;
909 }
910
911 return 1;
912}
913
914static int __parse_vlan_from_nlattrs(struct sw_flow_match *match,
915 u64 *key_attrs, bool inner,
916 const struct nlattr **a, bool is_mask,
917 bool log)
918{
919 int err;
920 const struct nlattr *encap;
921
922 if (!is_mask)
923 err = validate_vlan_from_nlattrs(match, *key_attrs, inner,
924 a, log);
925 else
926 err = validate_vlan_mask_from_nlattrs(match, *key_attrs, inner,
927 a, log);
928 if (err <= 0)
929 return err;
930
931 err = encode_vlan_from_nlattrs(match, a, is_mask, inner);
932 if (err)
933 return err;
934
935 *key_attrs &= ~(1 << OVS_KEY_ATTR_ENCAP);
936 *key_attrs &= ~(1 << OVS_KEY_ATTR_VLAN);
937 *key_attrs &= ~(1 << OVS_KEY_ATTR_ETHERTYPE);
938
939 encap = a[OVS_KEY_ATTR_ENCAP];
940
941 if (!is_mask)
942 err = parse_flow_nlattrs(encap, a, key_attrs, log);
943 else
944 err = parse_flow_mask_nlattrs(encap, a, key_attrs, log);
945
946 return err;
947}
948
949static int parse_vlan_from_nlattrs(struct sw_flow_match *match,
950 u64 *key_attrs, const struct nlattr **a,
951 bool is_mask, bool log)
952{
953 int err;
954 bool encap_valid = false;
955
956 err = __parse_vlan_from_nlattrs(match, key_attrs, false, a,
957 is_mask, log);
958 if (err)
959 return err;
960
961 encap_valid = !!(match->key->eth.vlan.tci & htons(VLAN_TAG_PRESENT));
962 if (encap_valid) {
963 err = __parse_vlan_from_nlattrs(match, key_attrs, true, a,
964 is_mask, log);
965 if (err)
966 return err;
967 }
968
969 return 0;
970}
971
811static int metadata_from_nlattrs(struct net *net, struct sw_flow_match *match, 972static int metadata_from_nlattrs(struct net *net, struct sw_flow_match *match,
812 u64 *attrs, const struct nlattr **a, 973 u64 *attrs, const struct nlattr **a,
813 bool is_mask, bool log) 974 bool is_mask, bool log)
@@ -923,20 +1084,11 @@ static int ovs_key_from_nlattrs(struct net *net, struct sw_flow_match *match,
923 } 1084 }
924 1085
925 if (attrs & (1 << OVS_KEY_ATTR_VLAN)) { 1086 if (attrs & (1 << OVS_KEY_ATTR_VLAN)) {
926 __be16 tci; 1087 /* VLAN attribute is always parsed before getting here since it
927 1088 * may occur multiple times.
928 tci = nla_get_be16(a[OVS_KEY_ATTR_VLAN]); 1089 */
929 if (!(tci & htons(VLAN_TAG_PRESENT))) { 1090 OVS_NLERR(log, "VLAN attribute unexpected.");
930 if (is_mask) 1091 return -EINVAL;
931 OVS_NLERR(log, "VLAN TCI mask does not have exact match for VLAN_TAG_PRESENT bit.");
932 else
933 OVS_NLERR(log, "VLAN TCI does not have VLAN_TAG_PRESENT bit set.");
934
935 return -EINVAL;
936 }
937
938 SW_FLOW_KEY_PUT(match, eth.tci, tci, is_mask);
939 attrs &= ~(1 << OVS_KEY_ATTR_VLAN);
940 } 1092 }
941 1093
942 if (attrs & (1 << OVS_KEY_ATTR_ETHERTYPE)) { 1094 if (attrs & (1 << OVS_KEY_ATTR_ETHERTYPE)) {
@@ -1182,49 +1334,18 @@ int ovs_nla_get_match(struct net *net, struct sw_flow_match *match,
1182 bool log) 1334 bool log)
1183{ 1335{
1184 const struct nlattr *a[OVS_KEY_ATTR_MAX + 1]; 1336 const struct nlattr *a[OVS_KEY_ATTR_MAX + 1];
1185 const struct nlattr *encap;
1186 struct nlattr *newmask = NULL; 1337 struct nlattr *newmask = NULL;
1187 u64 key_attrs = 0; 1338 u64 key_attrs = 0;
1188 u64 mask_attrs = 0; 1339 u64 mask_attrs = 0;
1189 bool encap_valid = false;
1190 int err; 1340 int err;
1191 1341
1192 err = parse_flow_nlattrs(nla_key, a, &key_attrs, log); 1342 err = parse_flow_nlattrs(nla_key, a, &key_attrs, log);
1193 if (err) 1343 if (err)
1194 return err; 1344 return err;
1195 1345
1196 if ((key_attrs & (1 << OVS_KEY_ATTR_ETHERNET)) && 1346 err = parse_vlan_from_nlattrs(match, &key_attrs, a, false, log);
1197 (key_attrs & (1 << OVS_KEY_ATTR_ETHERTYPE)) && 1347 if (err)
1198 (nla_get_be16(a[OVS_KEY_ATTR_ETHERTYPE]) == htons(ETH_P_8021Q))) { 1348 return err;
1199 __be16 tci;
1200
1201 if (!((key_attrs & (1 << OVS_KEY_ATTR_VLAN)) &&
1202 (key_attrs & (1 << OVS_KEY_ATTR_ENCAP)))) {
1203 OVS_NLERR(log, "Invalid Vlan frame.");
1204 return -EINVAL;
1205 }
1206
1207 key_attrs &= ~(1 << OVS_KEY_ATTR_ETHERTYPE);
1208 tci = nla_get_be16(a[OVS_KEY_ATTR_VLAN]);
1209 encap = a[OVS_KEY_ATTR_ENCAP];
1210 key_attrs &= ~(1 << OVS_KEY_ATTR_ENCAP);
1211 encap_valid = true;
1212
1213 if (tci & htons(VLAN_TAG_PRESENT)) {
1214 err = parse_flow_nlattrs(encap, a, &key_attrs, log);
1215 if (err)
1216 return err;
1217 } else if (!tci) {
1218 /* Corner case for truncated 802.1Q header. */
1219 if (nla_len(encap)) {
1220 OVS_NLERR(log, "Truncated 802.1Q header has non-zero encap attribute.");
1221 return -EINVAL;
1222 }
1223 } else {
1224 OVS_NLERR(log, "Encap attr is set for non-VLAN frame");
1225 return -EINVAL;
1226 }
1227 }
1228 1349
1229 err = ovs_key_from_nlattrs(net, match, key_attrs, a, false, log); 1350 err = ovs_key_from_nlattrs(net, match, key_attrs, a, false, log);
1230 if (err) 1351 if (err)
@@ -1265,46 +1386,12 @@ int ovs_nla_get_match(struct net *net, struct sw_flow_match *match,
1265 goto free_newmask; 1386 goto free_newmask;
1266 1387
1267 /* Always match on tci. */ 1388 /* Always match on tci. */
1268 SW_FLOW_KEY_PUT(match, eth.tci, htons(0xffff), true); 1389 SW_FLOW_KEY_PUT(match, eth.vlan.tci, htons(0xffff), true);
1269 1390 SW_FLOW_KEY_PUT(match, eth.cvlan.tci, htons(0xffff), true);
1270 if (mask_attrs & 1 << OVS_KEY_ATTR_ENCAP) {
1271 __be16 eth_type = 0;
1272 __be16 tci = 0;
1273
1274 if (!encap_valid) {
1275 OVS_NLERR(log, "Encap mask attribute is set for non-VLAN frame.");
1276 err = -EINVAL;
1277 goto free_newmask;
1278 }
1279
1280 mask_attrs &= ~(1 << OVS_KEY_ATTR_ENCAP);
1281 if (a[OVS_KEY_ATTR_ETHERTYPE])
1282 eth_type = nla_get_be16(a[OVS_KEY_ATTR_ETHERTYPE]);
1283
1284 if (eth_type == htons(0xffff)) {
1285 mask_attrs &= ~(1 << OVS_KEY_ATTR_ETHERTYPE);
1286 encap = a[OVS_KEY_ATTR_ENCAP];
1287 err = parse_flow_mask_nlattrs(encap, a,
1288 &mask_attrs, log);
1289 if (err)
1290 goto free_newmask;
1291 } else {
1292 OVS_NLERR(log, "VLAN frames must have an exact match on the TPID (mask=%x).",
1293 ntohs(eth_type));
1294 err = -EINVAL;
1295 goto free_newmask;
1296 }
1297
1298 if (a[OVS_KEY_ATTR_VLAN])
1299 tci = nla_get_be16(a[OVS_KEY_ATTR_VLAN]);
1300 1391
1301 if (!(tci & htons(VLAN_TAG_PRESENT))) { 1392 err = parse_vlan_from_nlattrs(match, &mask_attrs, a, true, log);
1302 OVS_NLERR(log, "VLAN tag present bit must have an exact match (tci_mask=%x).", 1393 if (err)
1303 ntohs(tci)); 1394 goto free_newmask;
1304 err = -EINVAL;
1305 goto free_newmask;
1306 }
1307 }
1308 1395
1309 err = ovs_key_from_nlattrs(net, match, mask_attrs, a, true, 1396 err = ovs_key_from_nlattrs(net, match, mask_attrs, a, true,
1310 log); 1397 log);
@@ -1410,12 +1497,25 @@ int ovs_nla_get_flow_metadata(struct net *net, const struct nlattr *attr,
1410 return metadata_from_nlattrs(net, &match, &attrs, a, false, log); 1497 return metadata_from_nlattrs(net, &match, &attrs, a, false, log);
1411} 1498}
1412 1499
1500static int ovs_nla_put_vlan(struct sk_buff *skb, const struct vlan_head *vh,
1501 bool is_mask)
1502{
1503 __be16 eth_type = !is_mask ? vh->tpid : htons(0xffff);
1504
1505 if (nla_put_be16(skb, OVS_KEY_ATTR_ETHERTYPE, eth_type) ||
1506 nla_put_be16(skb, OVS_KEY_ATTR_VLAN, vh->tci))
1507 return -EMSGSIZE;
1508 return 0;
1509}
1510
1413static int __ovs_nla_put_key(const struct sw_flow_key *swkey, 1511static int __ovs_nla_put_key(const struct sw_flow_key *swkey,
1414 const struct sw_flow_key *output, bool is_mask, 1512 const struct sw_flow_key *output, bool is_mask,
1415 struct sk_buff *skb) 1513 struct sk_buff *skb)
1416{ 1514{
1417 struct ovs_key_ethernet *eth_key; 1515 struct ovs_key_ethernet *eth_key;
1418 struct nlattr *nla, *encap; 1516 struct nlattr *nla;
1517 struct nlattr *encap = NULL;
1518 struct nlattr *in_encap = NULL;
1419 1519
1420 if (nla_put_u32(skb, OVS_KEY_ATTR_RECIRC_ID, output->recirc_id)) 1520 if (nla_put_u32(skb, OVS_KEY_ATTR_RECIRC_ID, output->recirc_id))
1421 goto nla_put_failure; 1521 goto nla_put_failure;
@@ -1464,17 +1564,21 @@ static int __ovs_nla_put_key(const struct sw_flow_key *swkey,
1464 ether_addr_copy(eth_key->eth_src, output->eth.src); 1564 ether_addr_copy(eth_key->eth_src, output->eth.src);
1465 ether_addr_copy(eth_key->eth_dst, output->eth.dst); 1565 ether_addr_copy(eth_key->eth_dst, output->eth.dst);
1466 1566
1467 if (swkey->eth.tci || swkey->eth.type == htons(ETH_P_8021Q)) { 1567 if (swkey->eth.vlan.tci || eth_type_vlan(swkey->eth.type)) {
1468 __be16 eth_type; 1568 if (ovs_nla_put_vlan(skb, &output->eth.vlan, is_mask))
1469 eth_type = !is_mask ? htons(ETH_P_8021Q) : htons(0xffff);
1470 if (nla_put_be16(skb, OVS_KEY_ATTR_ETHERTYPE, eth_type) ||
1471 nla_put_be16(skb, OVS_KEY_ATTR_VLAN, output->eth.tci))
1472 goto nla_put_failure; 1569 goto nla_put_failure;
1473 encap = nla_nest_start(skb, OVS_KEY_ATTR_ENCAP); 1570 encap = nla_nest_start(skb, OVS_KEY_ATTR_ENCAP);
1474 if (!swkey->eth.tci) 1571 if (!swkey->eth.vlan.tci)
1475 goto unencap; 1572 goto unencap;
1476 } else 1573
1477 encap = NULL; 1574 if (swkey->eth.cvlan.tci || eth_type_vlan(swkey->eth.type)) {
1575 if (ovs_nla_put_vlan(skb, &output->eth.cvlan, is_mask))
1576 goto nla_put_failure;
1577 in_encap = nla_nest_start(skb, OVS_KEY_ATTR_ENCAP);
1578 if (!swkey->eth.cvlan.tci)
1579 goto unencap;
1580 }
1581 }
1478 1582
1479 if (swkey->eth.type == htons(ETH_P_802_2)) { 1583 if (swkey->eth.type == htons(ETH_P_802_2)) {
1480 /* 1584 /*
@@ -1493,6 +1597,14 @@ static int __ovs_nla_put_key(const struct sw_flow_key *swkey,
1493 if (nla_put_be16(skb, OVS_KEY_ATTR_ETHERTYPE, output->eth.type)) 1597 if (nla_put_be16(skb, OVS_KEY_ATTR_ETHERTYPE, output->eth.type))
1494 goto nla_put_failure; 1598 goto nla_put_failure;
1495 1599
1600 if (eth_type_vlan(swkey->eth.type)) {
1601 /* There are 3 VLAN tags, we don't know anything about the rest
1602 * of the packet, so truncate here.
1603 */
1604 WARN_ON_ONCE(!(encap && in_encap));
1605 goto unencap;
1606 }
1607
1496 if (swkey->eth.type == htons(ETH_P_IP)) { 1608 if (swkey->eth.type == htons(ETH_P_IP)) {
1497 struct ovs_key_ipv4 *ipv4_key; 1609 struct ovs_key_ipv4 *ipv4_key;
1498 1610
@@ -1619,6 +1731,8 @@ static int __ovs_nla_put_key(const struct sw_flow_key *swkey,
1619 } 1731 }
1620 1732
1621unencap: 1733unencap:
1734 if (in_encap)
1735 nla_nest_end(skb, in_encap);
1622 if (encap) 1736 if (encap)
1623 nla_nest_end(skb, encap); 1737 nla_nest_end(skb, encap);
1624 1738
@@ -2283,7 +2397,7 @@ static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
2283 2397
2284 case OVS_ACTION_ATTR_PUSH_VLAN: 2398 case OVS_ACTION_ATTR_PUSH_VLAN:
2285 vlan = nla_data(a); 2399 vlan = nla_data(a);
2286 if (vlan->vlan_tpid != htons(ETH_P_8021Q)) 2400 if (!eth_type_vlan(vlan->vlan_tpid))
2287 return -EINVAL; 2401 return -EINVAL;
2288 if (!(vlan->vlan_tci & htons(VLAN_TAG_PRESENT))) 2402 if (!(vlan->vlan_tci & htons(VLAN_TAG_PRESENT)))
2289 return -EINVAL; 2403 return -EINVAL;
@@ -2388,7 +2502,7 @@ int ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
2388 2502
2389 (*sfa)->orig_len = nla_len(attr); 2503 (*sfa)->orig_len = nla_len(attr);
2390 err = __ovs_nla_copy_actions(net, attr, key, 0, sfa, key->eth.type, 2504 err = __ovs_nla_copy_actions(net, attr, key, 0, sfa, key->eth.type,
2391 key->eth.tci, log); 2505 key->eth.vlan.tci, log);
2392 if (err) 2506 if (err)
2393 ovs_nla_free_flow_actions(*sfa); 2507 ovs_nla_free_flow_actions(*sfa);
2394 2508
diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c
index 6b21fd068d87..8f198437c724 100644
--- a/net/openvswitch/vport.c
+++ b/net/openvswitch/vport.c
@@ -485,9 +485,14 @@ static unsigned int packet_length(const struct sk_buff *skb)
485{ 485{
486 unsigned int length = skb->len - ETH_HLEN; 486 unsigned int length = skb->len - ETH_HLEN;
487 487
488 if (skb->protocol == htons(ETH_P_8021Q)) 488 if (skb_vlan_tagged(skb))
489 length -= VLAN_HLEN; 489 length -= VLAN_HLEN;
490 490
491 /* Don't subtract for multiple VLAN tags. Most (all?) drivers allow
492 * (ETH_LEN + VLAN_HLEN) in addition to the mtu value, but almost none
493 * account for 802.1ad. e.g. is_skb_forwardable().
494 */
495
491 return length; 496 return length;
492} 497}
493 498