diff options
Diffstat (limited to 'net/openvswitch/flow_netlink.c')
-rw-r--r-- | net/openvswitch/flow_netlink.c | 303 |
1 files changed, 164 insertions, 139 deletions
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c index 98a3e96b7d93..c0d066def228 100644 --- a/net/openvswitch/flow_netlink.c +++ b/net/openvswitch/flow_netlink.c | |||
@@ -112,7 +112,7 @@ static void update_range(struct sw_flow_match *match, | |||
112 | } while (0) | 112 | } while (0) |
113 | 113 | ||
114 | static bool match_validate(const struct sw_flow_match *match, | 114 | static bool match_validate(const struct sw_flow_match *match, |
115 | u64 key_attrs, u64 mask_attrs) | 115 | u64 key_attrs, u64 mask_attrs, bool log) |
116 | { | 116 | { |
117 | u64 key_expected = 1 << OVS_KEY_ATTR_ETHERNET; | 117 | u64 key_expected = 1 << OVS_KEY_ATTR_ETHERNET; |
118 | u64 mask_allowed = key_attrs; /* At most allow all key attributes */ | 118 | u64 mask_allowed = key_attrs; /* At most allow all key attributes */ |
@@ -230,15 +230,17 @@ static bool match_validate(const struct sw_flow_match *match, | |||
230 | 230 | ||
231 | if ((key_attrs & key_expected) != key_expected) { | 231 | if ((key_attrs & key_expected) != key_expected) { |
232 | /* Key attributes check failed. */ | 232 | /* Key attributes check failed. */ |
233 | OVS_NLERR("Missing expected key attributes (key_attrs=%llx, expected=%llx).\n", | 233 | OVS_NLERR(log, "Missing key (keys=%llx, expected=%llx)", |
234 | (unsigned long long)key_attrs, (unsigned long long)key_expected); | 234 | (unsigned long long)key_attrs, |
235 | (unsigned long long)key_expected); | ||
235 | return false; | 236 | return false; |
236 | } | 237 | } |
237 | 238 | ||
238 | if ((mask_attrs & mask_allowed) != mask_attrs) { | 239 | if ((mask_attrs & mask_allowed) != mask_attrs) { |
239 | /* Mask attributes check failed. */ | 240 | /* Mask attributes check failed. */ |
240 | OVS_NLERR("Contain more than allowed mask fields (mask_attrs=%llx, mask_allowed=%llx).\n", | 241 | OVS_NLERR(log, "Unexpected mask (mask=%llx, allowed=%llx)", |
241 | (unsigned long long)mask_attrs, (unsigned long long)mask_allowed); | 242 | (unsigned long long)mask_attrs, |
243 | (unsigned long long)mask_allowed); | ||
242 | return false; | 244 | return false; |
243 | } | 245 | } |
244 | 246 | ||
@@ -328,7 +330,7 @@ static bool is_all_zero(const u8 *fp, size_t size) | |||
328 | 330 | ||
329 | static int __parse_flow_nlattrs(const struct nlattr *attr, | 331 | static int __parse_flow_nlattrs(const struct nlattr *attr, |
330 | const struct nlattr *a[], | 332 | const struct nlattr *a[], |
331 | u64 *attrsp, bool nz) | 333 | u64 *attrsp, bool log, bool nz) |
332 | { | 334 | { |
333 | const struct nlattr *nla; | 335 | const struct nlattr *nla; |
334 | u64 attrs; | 336 | u64 attrs; |
@@ -340,21 +342,20 @@ static int __parse_flow_nlattrs(const struct nlattr *attr, | |||
340 | int expected_len; | 342 | int expected_len; |
341 | 343 | ||
342 | if (type > OVS_KEY_ATTR_MAX) { | 344 | if (type > OVS_KEY_ATTR_MAX) { |
343 | OVS_NLERR("Unknown key attribute (type=%d, max=%d).\n", | 345 | OVS_NLERR(log, "Key type %d is out of range max %d", |
344 | type, OVS_KEY_ATTR_MAX); | 346 | type, OVS_KEY_ATTR_MAX); |
345 | return -EINVAL; | 347 | return -EINVAL; |
346 | } | 348 | } |
347 | 349 | ||
348 | if (attrs & (1 << type)) { | 350 | if (attrs & (1 << type)) { |
349 | OVS_NLERR("Duplicate key attribute (type %d).\n", type); | 351 | OVS_NLERR(log, "Duplicate key (type %d).", type); |
350 | return -EINVAL; | 352 | return -EINVAL; |
351 | } | 353 | } |
352 | 354 | ||
353 | expected_len = ovs_key_lens[type]; | 355 | expected_len = ovs_key_lens[type]; |
354 | if (nla_len(nla) != expected_len && expected_len != -1) { | 356 | if (nla_len(nla) != expected_len && expected_len != -1) { |
355 | OVS_NLERR("Key attribute has unexpected length (type=%d" | 357 | OVS_NLERR(log, "Key %d has unexpected len %d expected %d", |
356 | ", length=%d, expected=%d).\n", type, | 358 | type, nla_len(nla), expected_len); |
357 | nla_len(nla), expected_len); | ||
358 | return -EINVAL; | 359 | return -EINVAL; |
359 | } | 360 | } |
360 | 361 | ||
@@ -364,7 +365,7 @@ static int __parse_flow_nlattrs(const struct nlattr *attr, | |||
364 | } | 365 | } |
365 | } | 366 | } |
366 | if (rem) { | 367 | if (rem) { |
367 | OVS_NLERR("Message has %d unknown bytes.\n", rem); | 368 | OVS_NLERR(log, "Message has %d unknown bytes.", rem); |
368 | return -EINVAL; | 369 | return -EINVAL; |
369 | } | 370 | } |
370 | 371 | ||
@@ -373,28 +374,84 @@ static int __parse_flow_nlattrs(const struct nlattr *attr, | |||
373 | } | 374 | } |
374 | 375 | ||
375 | static int parse_flow_mask_nlattrs(const struct nlattr *attr, | 376 | static int parse_flow_mask_nlattrs(const struct nlattr *attr, |
376 | const struct nlattr *a[], u64 *attrsp) | 377 | const struct nlattr *a[], u64 *attrsp, |
378 | bool log) | ||
377 | { | 379 | { |
378 | return __parse_flow_nlattrs(attr, a, attrsp, true); | 380 | return __parse_flow_nlattrs(attr, a, attrsp, log, true); |
379 | } | 381 | } |
380 | 382 | ||
381 | static int parse_flow_nlattrs(const struct nlattr *attr, | 383 | static int parse_flow_nlattrs(const struct nlattr *attr, |
382 | const struct nlattr *a[], u64 *attrsp) | 384 | const struct nlattr *a[], u64 *attrsp, |
385 | bool log) | ||
383 | { | 386 | { |
384 | return __parse_flow_nlattrs(attr, a, attrsp, false); | 387 | return __parse_flow_nlattrs(attr, a, attrsp, log, false); |
388 | } | ||
389 | |||
390 | static int genev_tun_opt_from_nlattr(const struct nlattr *a, | ||
391 | struct sw_flow_match *match, bool is_mask, | ||
392 | bool log) | ||
393 | { | ||
394 | unsigned long opt_key_offset; | ||
395 | |||
396 | if (nla_len(a) > sizeof(match->key->tun_opts)) { | ||
397 | OVS_NLERR(log, "Geneve option length err (len %d, max %zu).", | ||
398 | nla_len(a), sizeof(match->key->tun_opts)); | ||
399 | return -EINVAL; | ||
400 | } | ||
401 | |||
402 | if (nla_len(a) % 4 != 0) { | ||
403 | OVS_NLERR(log, "Geneve opt len %d is not a multiple of 4.", | ||
404 | nla_len(a)); | ||
405 | return -EINVAL; | ||
406 | } | ||
407 | |||
408 | /* We need to record the length of the options passed | ||
409 | * down, otherwise packets with the same format but | ||
410 | * additional options will be silently matched. | ||
411 | */ | ||
412 | if (!is_mask) { | ||
413 | SW_FLOW_KEY_PUT(match, tun_opts_len, nla_len(a), | ||
414 | false); | ||
415 | } else { | ||
416 | /* This is somewhat unusual because it looks at | ||
417 | * both the key and mask while parsing the | ||
418 | * attributes (and by extension assumes the key | ||
419 | * is parsed first). Normally, we would verify | ||
420 | * that each is the correct length and that the | ||
421 | * attributes line up in the validate function. | ||
422 | * However, that is difficult because this is | ||
423 | * variable length and we won't have the | ||
424 | * information later. | ||
425 | */ | ||
426 | if (match->key->tun_opts_len != nla_len(a)) { | ||
427 | OVS_NLERR(log, "Geneve option len %d != mask len %d", | ||
428 | match->key->tun_opts_len, nla_len(a)); | ||
429 | return -EINVAL; | ||
430 | } | ||
431 | |||
432 | SW_FLOW_KEY_PUT(match, tun_opts_len, 0xff, true); | ||
433 | } | ||
434 | |||
435 | opt_key_offset = (unsigned long)GENEVE_OPTS((struct sw_flow_key *)0, | ||
436 | nla_len(a)); | ||
437 | SW_FLOW_KEY_MEMCPY_OFFSET(match, opt_key_offset, nla_data(a), | ||
438 | nla_len(a), is_mask); | ||
439 | return 0; | ||
385 | } | 440 | } |
386 | 441 | ||
387 | static int ipv4_tun_from_nlattr(const struct nlattr *attr, | 442 | static int ipv4_tun_from_nlattr(const struct nlattr *attr, |
388 | struct sw_flow_match *match, bool is_mask) | 443 | struct sw_flow_match *match, bool is_mask, |
444 | bool log) | ||
389 | { | 445 | { |
390 | struct nlattr *a; | 446 | struct nlattr *a; |
391 | int rem; | 447 | int rem; |
392 | bool ttl = false; | 448 | bool ttl = false; |
393 | __be16 tun_flags = 0; | 449 | __be16 tun_flags = 0; |
394 | unsigned long opt_key_offset; | ||
395 | 450 | ||
396 | nla_for_each_nested(a, attr, rem) { | 451 | nla_for_each_nested(a, attr, rem) { |
397 | int type = nla_type(a); | 452 | int type = nla_type(a); |
453 | int err; | ||
454 | |||
398 | static const u32 ovs_tunnel_key_lens[OVS_TUNNEL_KEY_ATTR_MAX + 1] = { | 455 | static const u32 ovs_tunnel_key_lens[OVS_TUNNEL_KEY_ATTR_MAX + 1] = { |
399 | [OVS_TUNNEL_KEY_ATTR_ID] = sizeof(u64), | 456 | [OVS_TUNNEL_KEY_ATTR_ID] = sizeof(u64), |
400 | [OVS_TUNNEL_KEY_ATTR_IPV4_SRC] = sizeof(u32), | 457 | [OVS_TUNNEL_KEY_ATTR_IPV4_SRC] = sizeof(u32), |
@@ -410,15 +467,14 @@ static int ipv4_tun_from_nlattr(const struct nlattr *attr, | |||
410 | }; | 467 | }; |
411 | 468 | ||
412 | if (type > OVS_TUNNEL_KEY_ATTR_MAX) { | 469 | if (type > OVS_TUNNEL_KEY_ATTR_MAX) { |
413 | OVS_NLERR("Unknown IPv4 tunnel attribute (type=%d, max=%d).\n", | 470 | OVS_NLERR(log, "Tunnel attr %d out of range max %d", |
414 | type, OVS_TUNNEL_KEY_ATTR_MAX); | 471 | type, OVS_TUNNEL_KEY_ATTR_MAX); |
415 | return -EINVAL; | 472 | return -EINVAL; |
416 | } | 473 | } |
417 | 474 | ||
418 | if (ovs_tunnel_key_lens[type] != nla_len(a) && | 475 | if (ovs_tunnel_key_lens[type] != nla_len(a) && |
419 | ovs_tunnel_key_lens[type] != -1) { | 476 | ovs_tunnel_key_lens[type] != -1) { |
420 | OVS_NLERR("IPv4 tunnel attribute type has unexpected " | 477 | OVS_NLERR(log, "Tunnel attr %d has unexpected len %d expected %d", |
421 | " length (type=%d, length=%d, expected=%d).\n", | ||
422 | type, nla_len(a), ovs_tunnel_key_lens[type]); | 478 | type, nla_len(a), ovs_tunnel_key_lens[type]); |
423 | return -EINVAL; | 479 | return -EINVAL; |
424 | } | 480 | } |
@@ -464,58 +520,14 @@ static int ipv4_tun_from_nlattr(const struct nlattr *attr, | |||
464 | tun_flags |= TUNNEL_OAM; | 520 | tun_flags |= TUNNEL_OAM; |
465 | break; | 521 | break; |
466 | case OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS: | 522 | case OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS: |
467 | tun_flags |= TUNNEL_OPTIONS_PRESENT; | 523 | err = genev_tun_opt_from_nlattr(a, match, is_mask, log); |
468 | if (nla_len(a) > sizeof(match->key->tun_opts)) { | 524 | if (err) |
469 | OVS_NLERR("Geneve option length exceeds maximum size (len %d, max %zu).\n", | 525 | return err; |
470 | nla_len(a), | ||
471 | sizeof(match->key->tun_opts)); | ||
472 | return -EINVAL; | ||
473 | } | ||
474 | |||
475 | if (nla_len(a) % 4 != 0) { | ||
476 | OVS_NLERR("Geneve option length is not a multiple of 4 (len %d).\n", | ||
477 | nla_len(a)); | ||
478 | return -EINVAL; | ||
479 | } | ||
480 | |||
481 | /* We need to record the length of the options passed | ||
482 | * down, otherwise packets with the same format but | ||
483 | * additional options will be silently matched. | ||
484 | */ | ||
485 | if (!is_mask) { | ||
486 | SW_FLOW_KEY_PUT(match, tun_opts_len, nla_len(a), | ||
487 | false); | ||
488 | } else { | ||
489 | /* This is somewhat unusual because it looks at | ||
490 | * both the key and mask while parsing the | ||
491 | * attributes (and by extension assumes the key | ||
492 | * is parsed first). Normally, we would verify | ||
493 | * that each is the correct length and that the | ||
494 | * attributes line up in the validate function. | ||
495 | * However, that is difficult because this is | ||
496 | * variable length and we won't have the | ||
497 | * information later. | ||
498 | */ | ||
499 | if (match->key->tun_opts_len != nla_len(a)) { | ||
500 | OVS_NLERR("Geneve option key length (%d) is different from mask length (%d).", | ||
501 | match->key->tun_opts_len, | ||
502 | nla_len(a)); | ||
503 | return -EINVAL; | ||
504 | } | ||
505 | |||
506 | SW_FLOW_KEY_PUT(match, tun_opts_len, 0xff, | ||
507 | true); | ||
508 | } | ||
509 | 526 | ||
510 | opt_key_offset = (unsigned long)GENEVE_OPTS( | 527 | tun_flags |= TUNNEL_OPTIONS_PRESENT; |
511 | (struct sw_flow_key *)0, | ||
512 | nla_len(a)); | ||
513 | SW_FLOW_KEY_MEMCPY_OFFSET(match, opt_key_offset, | ||
514 | nla_data(a), nla_len(a), | ||
515 | is_mask); | ||
516 | break; | 528 | break; |
517 | default: | 529 | default: |
518 | OVS_NLERR("Unknown IPv4 tunnel attribute (%d).\n", | 530 | OVS_NLERR(log, "Unknown IPv4 tunnel attribute %d", |
519 | type); | 531 | type); |
520 | return -EINVAL; | 532 | return -EINVAL; |
521 | } | 533 | } |
@@ -524,18 +536,19 @@ static int ipv4_tun_from_nlattr(const struct nlattr *attr, | |||
524 | SW_FLOW_KEY_PUT(match, tun_key.tun_flags, tun_flags, is_mask); | 536 | SW_FLOW_KEY_PUT(match, tun_key.tun_flags, tun_flags, is_mask); |
525 | 537 | ||
526 | if (rem > 0) { | 538 | if (rem > 0) { |
527 | OVS_NLERR("IPv4 tunnel attribute has %d unknown bytes.\n", rem); | 539 | OVS_NLERR(log, "IPv4 tunnel attribute has %d unknown bytes.", |
540 | rem); | ||
528 | return -EINVAL; | 541 | return -EINVAL; |
529 | } | 542 | } |
530 | 543 | ||
531 | if (!is_mask) { | 544 | if (!is_mask) { |
532 | if (!match->key->tun_key.ipv4_dst) { | 545 | if (!match->key->tun_key.ipv4_dst) { |
533 | OVS_NLERR("IPv4 tunnel destination address is zero.\n"); | 546 | OVS_NLERR(log, "IPv4 tunnel dst address is zero"); |
534 | return -EINVAL; | 547 | return -EINVAL; |
535 | } | 548 | } |
536 | 549 | ||
537 | if (!ttl) { | 550 | if (!ttl) { |
538 | OVS_NLERR("IPv4 tunnel TTL not specified.\n"); | 551 | OVS_NLERR(log, "IPv4 tunnel TTL not specified."); |
539 | return -EINVAL; | 552 | return -EINVAL; |
540 | } | 553 | } |
541 | } | 554 | } |
@@ -614,7 +627,8 @@ int ovs_nla_put_egress_tunnel_key(struct sk_buff *skb, | |||
614 | } | 627 | } |
615 | 628 | ||
616 | static int metadata_from_nlattrs(struct sw_flow_match *match, u64 *attrs, | 629 | static int metadata_from_nlattrs(struct sw_flow_match *match, u64 *attrs, |
617 | const struct nlattr **a, bool is_mask) | 630 | const struct nlattr **a, bool is_mask, |
631 | bool log) | ||
618 | { | 632 | { |
619 | if (*attrs & (1 << OVS_KEY_ATTR_DP_HASH)) { | 633 | if (*attrs & (1 << OVS_KEY_ATTR_DP_HASH)) { |
620 | u32 hash_val = nla_get_u32(a[OVS_KEY_ATTR_DP_HASH]); | 634 | u32 hash_val = nla_get_u32(a[OVS_KEY_ATTR_DP_HASH]); |
@@ -642,7 +656,7 @@ static int metadata_from_nlattrs(struct sw_flow_match *match, u64 *attrs, | |||
642 | if (is_mask) { | 656 | if (is_mask) { |
643 | in_port = 0xffffffff; /* Always exact match in_port. */ | 657 | in_port = 0xffffffff; /* Always exact match in_port. */ |
644 | } else if (in_port >= DP_MAX_PORTS) { | 658 | } else if (in_port >= DP_MAX_PORTS) { |
645 | OVS_NLERR("Port (%d) exceeds maximum allowable (%d).\n", | 659 | OVS_NLERR(log, "Port %d exceeds max allowable %d", |
646 | in_port, DP_MAX_PORTS); | 660 | in_port, DP_MAX_PORTS); |
647 | return -EINVAL; | 661 | return -EINVAL; |
648 | } | 662 | } |
@@ -661,7 +675,7 @@ static int metadata_from_nlattrs(struct sw_flow_match *match, u64 *attrs, | |||
661 | } | 675 | } |
662 | if (*attrs & (1 << OVS_KEY_ATTR_TUNNEL)) { | 676 | if (*attrs & (1 << OVS_KEY_ATTR_TUNNEL)) { |
663 | if (ipv4_tun_from_nlattr(a[OVS_KEY_ATTR_TUNNEL], match, | 677 | if (ipv4_tun_from_nlattr(a[OVS_KEY_ATTR_TUNNEL], match, |
664 | is_mask)) | 678 | is_mask, log)) |
665 | return -EINVAL; | 679 | return -EINVAL; |
666 | *attrs &= ~(1 << OVS_KEY_ATTR_TUNNEL); | 680 | *attrs &= ~(1 << OVS_KEY_ATTR_TUNNEL); |
667 | } | 681 | } |
@@ -669,11 +683,12 @@ static int metadata_from_nlattrs(struct sw_flow_match *match, u64 *attrs, | |||
669 | } | 683 | } |
670 | 684 | ||
671 | static int ovs_key_from_nlattrs(struct sw_flow_match *match, u64 attrs, | 685 | static int ovs_key_from_nlattrs(struct sw_flow_match *match, u64 attrs, |
672 | const struct nlattr **a, bool is_mask) | 686 | const struct nlattr **a, bool is_mask, |
687 | bool log) | ||
673 | { | 688 | { |
674 | int err; | 689 | int err; |
675 | 690 | ||
676 | err = metadata_from_nlattrs(match, &attrs, a, is_mask); | 691 | err = metadata_from_nlattrs(match, &attrs, a, is_mask, log); |
677 | if (err) | 692 | if (err) |
678 | return err; | 693 | return err; |
679 | 694 | ||
@@ -694,9 +709,9 @@ static int ovs_key_from_nlattrs(struct sw_flow_match *match, u64 attrs, | |||
694 | tci = nla_get_be16(a[OVS_KEY_ATTR_VLAN]); | 709 | tci = nla_get_be16(a[OVS_KEY_ATTR_VLAN]); |
695 | if (!(tci & htons(VLAN_TAG_PRESENT))) { | 710 | if (!(tci & htons(VLAN_TAG_PRESENT))) { |
696 | if (is_mask) | 711 | if (is_mask) |
697 | OVS_NLERR("VLAN TCI mask does not have exact match for VLAN_TAG_PRESENT bit.\n"); | 712 | OVS_NLERR(log, "VLAN TCI mask does not have exact match for VLAN_TAG_PRESENT bit."); |
698 | else | 713 | else |
699 | OVS_NLERR("VLAN TCI does not have VLAN_TAG_PRESENT bit set.\n"); | 714 | OVS_NLERR(log, "VLAN TCI does not have VLAN_TAG_PRESENT bit set."); |
700 | 715 | ||
701 | return -EINVAL; | 716 | return -EINVAL; |
702 | } | 717 | } |
@@ -713,8 +728,8 @@ static int ovs_key_from_nlattrs(struct sw_flow_match *match, u64 attrs, | |||
713 | /* Always exact match EtherType. */ | 728 | /* Always exact match EtherType. */ |
714 | eth_type = htons(0xffff); | 729 | eth_type = htons(0xffff); |
715 | } else if (ntohs(eth_type) < ETH_P_802_3_MIN) { | 730 | } else if (ntohs(eth_type) < ETH_P_802_3_MIN) { |
716 | OVS_NLERR("EtherType is less than minimum (type=%x, min=%x).\n", | 731 | OVS_NLERR(log, "EtherType %x is less than min %x", |
717 | ntohs(eth_type), ETH_P_802_3_MIN); | 732 | ntohs(eth_type), ETH_P_802_3_MIN); |
718 | return -EINVAL; | 733 | return -EINVAL; |
719 | } | 734 | } |
720 | 735 | ||
@@ -729,8 +744,8 @@ static int ovs_key_from_nlattrs(struct sw_flow_match *match, u64 attrs, | |||
729 | 744 | ||
730 | ipv4_key = nla_data(a[OVS_KEY_ATTR_IPV4]); | 745 | ipv4_key = nla_data(a[OVS_KEY_ATTR_IPV4]); |
731 | if (!is_mask && ipv4_key->ipv4_frag > OVS_FRAG_TYPE_MAX) { | 746 | if (!is_mask && ipv4_key->ipv4_frag > OVS_FRAG_TYPE_MAX) { |
732 | OVS_NLERR("Unknown IPv4 fragment type (value=%d, max=%d).\n", | 747 | OVS_NLERR(log, "IPv4 frag type %d is out of range max %d", |
733 | ipv4_key->ipv4_frag, OVS_FRAG_TYPE_MAX); | 748 | ipv4_key->ipv4_frag, OVS_FRAG_TYPE_MAX); |
734 | return -EINVAL; | 749 | return -EINVAL; |
735 | } | 750 | } |
736 | SW_FLOW_KEY_PUT(match, ip.proto, | 751 | SW_FLOW_KEY_PUT(match, ip.proto, |
@@ -753,8 +768,8 @@ static int ovs_key_from_nlattrs(struct sw_flow_match *match, u64 attrs, | |||
753 | 768 | ||
754 | ipv6_key = nla_data(a[OVS_KEY_ATTR_IPV6]); | 769 | ipv6_key = nla_data(a[OVS_KEY_ATTR_IPV6]); |
755 | if (!is_mask && ipv6_key->ipv6_frag > OVS_FRAG_TYPE_MAX) { | 770 | if (!is_mask && ipv6_key->ipv6_frag > OVS_FRAG_TYPE_MAX) { |
756 | OVS_NLERR("Unknown IPv6 fragment type (value=%d, max=%d).\n", | 771 | OVS_NLERR(log, "IPv6 frag type %d is out of range max %d", |
757 | ipv6_key->ipv6_frag, OVS_FRAG_TYPE_MAX); | 772 | ipv6_key->ipv6_frag, OVS_FRAG_TYPE_MAX); |
758 | return -EINVAL; | 773 | return -EINVAL; |
759 | } | 774 | } |
760 | SW_FLOW_KEY_PUT(match, ipv6.label, | 775 | SW_FLOW_KEY_PUT(match, ipv6.label, |
@@ -784,7 +799,7 @@ static int ovs_key_from_nlattrs(struct sw_flow_match *match, u64 attrs, | |||
784 | 799 | ||
785 | arp_key = nla_data(a[OVS_KEY_ATTR_ARP]); | 800 | arp_key = nla_data(a[OVS_KEY_ATTR_ARP]); |
786 | if (!is_mask && (arp_key->arp_op & htons(0xff00))) { | 801 | if (!is_mask && (arp_key->arp_op & htons(0xff00))) { |
787 | OVS_NLERR("Unknown ARP opcode (opcode=%d).\n", | 802 | OVS_NLERR(log, "Unknown ARP opcode (opcode=%d).", |
788 | arp_key->arp_op); | 803 | arp_key->arp_op); |
789 | return -EINVAL; | 804 | return -EINVAL; |
790 | } | 805 | } |
@@ -885,7 +900,7 @@ static int ovs_key_from_nlattrs(struct sw_flow_match *match, u64 attrs, | |||
885 | } | 900 | } |
886 | 901 | ||
887 | if (attrs != 0) { | 902 | if (attrs != 0) { |
888 | OVS_NLERR("Unknown key attributes (%llx).\n", | 903 | OVS_NLERR(log, "Unknown key attributes %llx", |
889 | (unsigned long long)attrs); | 904 | (unsigned long long)attrs); |
890 | return -EINVAL; | 905 | return -EINVAL; |
891 | } | 906 | } |
@@ -926,10 +941,14 @@ static void mask_set_nlattr(struct nlattr *attr, u8 val) | |||
926 | * of this flow. | 941 | * of this flow. |
927 | * @mask: Optional. Netlink attribute holding nested %OVS_KEY_ATTR_* Netlink | 942 | * @mask: Optional. Netlink attribute holding nested %OVS_KEY_ATTR_* Netlink |
928 | * attribute specifies the mask field of the wildcarded flow. | 943 | * attribute specifies the mask field of the wildcarded flow. |
944 | * @log: Boolean to allow kernel error logging. Normally true, but when | ||
945 | * probing for feature compatibility this should be passed in as false to | ||
946 | * suppress unnecessary error logging. | ||
929 | */ | 947 | */ |
930 | int ovs_nla_get_match(struct sw_flow_match *match, | 948 | int ovs_nla_get_match(struct sw_flow_match *match, |
931 | const struct nlattr *nla_key, | 949 | const struct nlattr *nla_key, |
932 | const struct nlattr *nla_mask) | 950 | const struct nlattr *nla_mask, |
951 | bool log) | ||
933 | { | 952 | { |
934 | const struct nlattr *a[OVS_KEY_ATTR_MAX + 1]; | 953 | const struct nlattr *a[OVS_KEY_ATTR_MAX + 1]; |
935 | const struct nlattr *encap; | 954 | const struct nlattr *encap; |
@@ -939,7 +958,7 @@ int ovs_nla_get_match(struct sw_flow_match *match, | |||
939 | bool encap_valid = false; | 958 | bool encap_valid = false; |
940 | int err; | 959 | int err; |
941 | 960 | ||
942 | err = parse_flow_nlattrs(nla_key, a, &key_attrs); | 961 | err = parse_flow_nlattrs(nla_key, a, &key_attrs, log); |
943 | if (err) | 962 | if (err) |
944 | return err; | 963 | return err; |
945 | 964 | ||
@@ -950,7 +969,7 @@ int ovs_nla_get_match(struct sw_flow_match *match, | |||
950 | 969 | ||
951 | if (!((key_attrs & (1 << OVS_KEY_ATTR_VLAN)) && | 970 | if (!((key_attrs & (1 << OVS_KEY_ATTR_VLAN)) && |
952 | (key_attrs & (1 << OVS_KEY_ATTR_ENCAP)))) { | 971 | (key_attrs & (1 << OVS_KEY_ATTR_ENCAP)))) { |
953 | OVS_NLERR("Invalid Vlan frame.\n"); | 972 | OVS_NLERR(log, "Invalid Vlan frame."); |
954 | return -EINVAL; | 973 | return -EINVAL; |
955 | } | 974 | } |
956 | 975 | ||
@@ -961,22 +980,22 @@ int ovs_nla_get_match(struct sw_flow_match *match, | |||
961 | encap_valid = true; | 980 | encap_valid = true; |
962 | 981 | ||
963 | if (tci & htons(VLAN_TAG_PRESENT)) { | 982 | if (tci & htons(VLAN_TAG_PRESENT)) { |
964 | err = parse_flow_nlattrs(encap, a, &key_attrs); | 983 | err = parse_flow_nlattrs(encap, a, &key_attrs, log); |
965 | if (err) | 984 | if (err) |
966 | return err; | 985 | return err; |
967 | } else if (!tci) { | 986 | } else if (!tci) { |
968 | /* Corner case for truncated 802.1Q header. */ | 987 | /* Corner case for truncated 802.1Q header. */ |
969 | if (nla_len(encap)) { | 988 | if (nla_len(encap)) { |
970 | OVS_NLERR("Truncated 802.1Q header has non-zero encap attribute.\n"); | 989 | OVS_NLERR(log, "Truncated 802.1Q header has non-zero encap attribute."); |
971 | return -EINVAL; | 990 | return -EINVAL; |
972 | } | 991 | } |
973 | } else { | 992 | } else { |
974 | OVS_NLERR("Encap attribute is set for a non-VLAN frame.\n"); | 993 | OVS_NLERR(log, "Encap attr is set for non-VLAN frame"); |
975 | return -EINVAL; | 994 | return -EINVAL; |
976 | } | 995 | } |
977 | } | 996 | } |
978 | 997 | ||
979 | err = ovs_key_from_nlattrs(match, key_attrs, a, false); | 998 | err = ovs_key_from_nlattrs(match, key_attrs, a, false, log); |
980 | if (err) | 999 | if (err) |
981 | return err; | 1000 | return err; |
982 | 1001 | ||
@@ -1010,7 +1029,7 @@ int ovs_nla_get_match(struct sw_flow_match *match, | |||
1010 | nla_mask = newmask; | 1029 | nla_mask = newmask; |
1011 | } | 1030 | } |
1012 | 1031 | ||
1013 | err = parse_flow_mask_nlattrs(nla_mask, a, &mask_attrs); | 1032 | err = parse_flow_mask_nlattrs(nla_mask, a, &mask_attrs, log); |
1014 | if (err) | 1033 | if (err) |
1015 | goto free_newmask; | 1034 | goto free_newmask; |
1016 | 1035 | ||
@@ -1022,7 +1041,7 @@ int ovs_nla_get_match(struct sw_flow_match *match, | |||
1022 | __be16 tci = 0; | 1041 | __be16 tci = 0; |
1023 | 1042 | ||
1024 | if (!encap_valid) { | 1043 | if (!encap_valid) { |
1025 | OVS_NLERR("Encap mask attribute is set for non-VLAN frame.\n"); | 1044 | OVS_NLERR(log, "Encap mask attribute is set for non-VLAN frame."); |
1026 | err = -EINVAL; | 1045 | err = -EINVAL; |
1027 | goto free_newmask; | 1046 | goto free_newmask; |
1028 | } | 1047 | } |
@@ -1034,12 +1053,13 @@ int ovs_nla_get_match(struct sw_flow_match *match, | |||
1034 | if (eth_type == htons(0xffff)) { | 1053 | if (eth_type == htons(0xffff)) { |
1035 | mask_attrs &= ~(1 << OVS_KEY_ATTR_ETHERTYPE); | 1054 | mask_attrs &= ~(1 << OVS_KEY_ATTR_ETHERTYPE); |
1036 | encap = a[OVS_KEY_ATTR_ENCAP]; | 1055 | encap = a[OVS_KEY_ATTR_ENCAP]; |
1037 | err = parse_flow_mask_nlattrs(encap, a, &mask_attrs); | 1056 | err = parse_flow_mask_nlattrs(encap, a, |
1057 | &mask_attrs, log); | ||
1038 | if (err) | 1058 | if (err) |
1039 | goto free_newmask; | 1059 | goto free_newmask; |
1040 | } else { | 1060 | } else { |
1041 | OVS_NLERR("VLAN frames must have an exact match on the TPID (mask=%x).\n", | 1061 | OVS_NLERR(log, "VLAN frames must have an exact match on the TPID (mask=%x).", |
1042 | ntohs(eth_type)); | 1062 | ntohs(eth_type)); |
1043 | err = -EINVAL; | 1063 | err = -EINVAL; |
1044 | goto free_newmask; | 1064 | goto free_newmask; |
1045 | } | 1065 | } |
@@ -1048,18 +1068,19 @@ int ovs_nla_get_match(struct sw_flow_match *match, | |||
1048 | tci = nla_get_be16(a[OVS_KEY_ATTR_VLAN]); | 1068 | tci = nla_get_be16(a[OVS_KEY_ATTR_VLAN]); |
1049 | 1069 | ||
1050 | if (!(tci & htons(VLAN_TAG_PRESENT))) { | 1070 | if (!(tci & htons(VLAN_TAG_PRESENT))) { |
1051 | OVS_NLERR("VLAN tag present bit must have an exact match (tci_mask=%x).\n", ntohs(tci)); | 1071 | OVS_NLERR(log, "VLAN tag present bit must have an exact match (tci_mask=%x).", |
1072 | ntohs(tci)); | ||
1052 | err = -EINVAL; | 1073 | err = -EINVAL; |
1053 | goto free_newmask; | 1074 | goto free_newmask; |
1054 | } | 1075 | } |
1055 | } | 1076 | } |
1056 | 1077 | ||
1057 | err = ovs_key_from_nlattrs(match, mask_attrs, a, true); | 1078 | err = ovs_key_from_nlattrs(match, mask_attrs, a, true, log); |
1058 | if (err) | 1079 | if (err) |
1059 | goto free_newmask; | 1080 | goto free_newmask; |
1060 | } | 1081 | } |
1061 | 1082 | ||
1062 | if (!match_validate(match, key_attrs, mask_attrs)) | 1083 | if (!match_validate(match, key_attrs, mask_attrs, log)) |
1063 | err = -EINVAL; | 1084 | err = -EINVAL; |
1064 | 1085 | ||
1065 | free_newmask: | 1086 | free_newmask: |
@@ -1072,6 +1093,9 @@ free_newmask: | |||
1072 | * @key: Receives extracted in_port, priority, tun_key and skb_mark. | 1093 | * @key: Receives extracted in_port, priority, tun_key and skb_mark. |
1073 | * @attr: Netlink attribute holding nested %OVS_KEY_ATTR_* Netlink attribute | 1094 | * @attr: Netlink attribute holding nested %OVS_KEY_ATTR_* Netlink attribute |
1074 | * sequence. | 1095 | * sequence. |
1096 | * @log: Boolean to allow kernel error logging. Normally true, but when | ||
1097 | * probing for feature compatibility this should be passed in as false to | ||
1098 | * suppress unnecessary error logging. | ||
1075 | * | 1099 | * |
1076 | * This parses a series of Netlink attributes that form a flow key, which must | 1100 | * This parses a series of Netlink attributes that form a flow key, which must |
1077 | * take the same form accepted by flow_from_nlattrs(), but only enough of it to | 1101 | * take the same form accepted by flow_from_nlattrs(), but only enough of it to |
@@ -1080,14 +1104,15 @@ free_newmask: | |||
1080 | */ | 1104 | */ |
1081 | 1105 | ||
1082 | int ovs_nla_get_flow_metadata(const struct nlattr *attr, | 1106 | int ovs_nla_get_flow_metadata(const struct nlattr *attr, |
1083 | struct sw_flow_key *key) | 1107 | struct sw_flow_key *key, |
1108 | bool log) | ||
1084 | { | 1109 | { |
1085 | const struct nlattr *a[OVS_KEY_ATTR_MAX + 1]; | 1110 | const struct nlattr *a[OVS_KEY_ATTR_MAX + 1]; |
1086 | struct sw_flow_match match; | 1111 | struct sw_flow_match match; |
1087 | u64 attrs = 0; | 1112 | u64 attrs = 0; |
1088 | int err; | 1113 | int err; |
1089 | 1114 | ||
1090 | err = parse_flow_nlattrs(attr, a, &attrs); | 1115 | err = parse_flow_nlattrs(attr, a, &attrs, log); |
1091 | if (err) | 1116 | if (err) |
1092 | return -EINVAL; | 1117 | return -EINVAL; |
1093 | 1118 | ||
@@ -1096,7 +1121,7 @@ int ovs_nla_get_flow_metadata(const struct nlattr *attr, | |||
1096 | 1121 | ||
1097 | key->phy.in_port = DP_MAX_PORTS; | 1122 | key->phy.in_port = DP_MAX_PORTS; |
1098 | 1123 | ||
1099 | return metadata_from_nlattrs(&match, &attrs, a, false); | 1124 | return metadata_from_nlattrs(&match, &attrs, a, false, log); |
1100 | } | 1125 | } |
1101 | 1126 | ||
1102 | int ovs_nla_put_flow(const struct sw_flow_key *swkey, | 1127 | int ovs_nla_put_flow(const struct sw_flow_key *swkey, |
@@ -1316,12 +1341,12 @@ nla_put_failure: | |||
1316 | 1341 | ||
1317 | #define MAX_ACTIONS_BUFSIZE (32 * 1024) | 1342 | #define MAX_ACTIONS_BUFSIZE (32 * 1024) |
1318 | 1343 | ||
1319 | static struct sw_flow_actions *nla_alloc_flow_actions(int size) | 1344 | static struct sw_flow_actions *nla_alloc_flow_actions(int size, bool log) |
1320 | { | 1345 | { |
1321 | struct sw_flow_actions *sfa; | 1346 | struct sw_flow_actions *sfa; |
1322 | 1347 | ||
1323 | if (size > MAX_ACTIONS_BUFSIZE) { | 1348 | if (size > MAX_ACTIONS_BUFSIZE) { |
1324 | OVS_NLERR("Flow action size (%u bytes) exceeds maximum", size); | 1349 | OVS_NLERR(log, "Flow action size %u bytes exceeds max", size); |
1325 | return ERR_PTR(-EINVAL); | 1350 | return ERR_PTR(-EINVAL); |
1326 | } | 1351 | } |
1327 | 1352 | ||
@@ -1341,7 +1366,7 @@ void ovs_nla_free_flow_actions(struct sw_flow_actions *sf_acts) | |||
1341 | } | 1366 | } |
1342 | 1367 | ||
1343 | static struct nlattr *reserve_sfa_size(struct sw_flow_actions **sfa, | 1368 | static struct nlattr *reserve_sfa_size(struct sw_flow_actions **sfa, |
1344 | int attr_len) | 1369 | int attr_len, bool log) |
1345 | { | 1370 | { |
1346 | 1371 | ||
1347 | struct sw_flow_actions *acts; | 1372 | struct sw_flow_actions *acts; |
@@ -1361,7 +1386,7 @@ static struct nlattr *reserve_sfa_size(struct sw_flow_actions **sfa, | |||
1361 | new_acts_size = MAX_ACTIONS_BUFSIZE; | 1386 | new_acts_size = MAX_ACTIONS_BUFSIZE; |
1362 | } | 1387 | } |
1363 | 1388 | ||
1364 | acts = nla_alloc_flow_actions(new_acts_size); | 1389 | acts = nla_alloc_flow_actions(new_acts_size, log); |
1365 | if (IS_ERR(acts)) | 1390 | if (IS_ERR(acts)) |
1366 | return (void *)acts; | 1391 | return (void *)acts; |
1367 | 1392 | ||
@@ -1376,11 +1401,11 @@ out: | |||
1376 | } | 1401 | } |
1377 | 1402 | ||
1378 | static struct nlattr *__add_action(struct sw_flow_actions **sfa, | 1403 | static struct nlattr *__add_action(struct sw_flow_actions **sfa, |
1379 | int attrtype, void *data, int len) | 1404 | int attrtype, void *data, int len, bool log) |
1380 | { | 1405 | { |
1381 | struct nlattr *a; | 1406 | struct nlattr *a; |
1382 | 1407 | ||
1383 | a = reserve_sfa_size(sfa, nla_attr_size(len)); | 1408 | a = reserve_sfa_size(sfa, nla_attr_size(len), log); |
1384 | if (IS_ERR(a)) | 1409 | if (IS_ERR(a)) |
1385 | return a; | 1410 | return a; |
1386 | 1411 | ||
@@ -1395,11 +1420,11 @@ static struct nlattr *__add_action(struct sw_flow_actions **sfa, | |||
1395 | } | 1420 | } |
1396 | 1421 | ||
1397 | static int add_action(struct sw_flow_actions **sfa, int attrtype, | 1422 | static int add_action(struct sw_flow_actions **sfa, int attrtype, |
1398 | void *data, int len) | 1423 | void *data, int len, bool log) |
1399 | { | 1424 | { |
1400 | struct nlattr *a; | 1425 | struct nlattr *a; |
1401 | 1426 | ||
1402 | a = __add_action(sfa, attrtype, data, len); | 1427 | a = __add_action(sfa, attrtype, data, len, log); |
1403 | if (IS_ERR(a)) | 1428 | if (IS_ERR(a)) |
1404 | return PTR_ERR(a); | 1429 | return PTR_ERR(a); |
1405 | 1430 | ||
@@ -1407,12 +1432,12 @@ static int add_action(struct sw_flow_actions **sfa, int attrtype, | |||
1407 | } | 1432 | } |
1408 | 1433 | ||
1409 | static inline int add_nested_action_start(struct sw_flow_actions **sfa, | 1434 | static inline int add_nested_action_start(struct sw_flow_actions **sfa, |
1410 | int attrtype) | 1435 | int attrtype, bool log) |
1411 | { | 1436 | { |
1412 | int used = (*sfa)->actions_len; | 1437 | int used = (*sfa)->actions_len; |
1413 | int err; | 1438 | int err; |
1414 | 1439 | ||
1415 | err = add_action(sfa, attrtype, NULL, 0); | 1440 | err = add_action(sfa, attrtype, NULL, 0, log); |
1416 | if (err) | 1441 | if (err) |
1417 | return err; | 1442 | return err; |
1418 | 1443 | ||
@@ -1431,12 +1456,12 @@ static inline void add_nested_action_end(struct sw_flow_actions *sfa, | |||
1431 | static int __ovs_nla_copy_actions(const struct nlattr *attr, | 1456 | static int __ovs_nla_copy_actions(const struct nlattr *attr, |
1432 | const struct sw_flow_key *key, | 1457 | const struct sw_flow_key *key, |
1433 | int depth, struct sw_flow_actions **sfa, | 1458 | int depth, struct sw_flow_actions **sfa, |
1434 | __be16 eth_type, __be16 vlan_tci); | 1459 | __be16 eth_type, __be16 vlan_tci, bool log); |
1435 | 1460 | ||
1436 | static int validate_and_copy_sample(const struct nlattr *attr, | 1461 | static int validate_and_copy_sample(const struct nlattr *attr, |
1437 | const struct sw_flow_key *key, int depth, | 1462 | const struct sw_flow_key *key, int depth, |
1438 | struct sw_flow_actions **sfa, | 1463 | struct sw_flow_actions **sfa, |
1439 | __be16 eth_type, __be16 vlan_tci) | 1464 | __be16 eth_type, __be16 vlan_tci, bool log) |
1440 | { | 1465 | { |
1441 | const struct nlattr *attrs[OVS_SAMPLE_ATTR_MAX + 1]; | 1466 | const struct nlattr *attrs[OVS_SAMPLE_ATTR_MAX + 1]; |
1442 | const struct nlattr *probability, *actions; | 1467 | const struct nlattr *probability, *actions; |
@@ -1462,19 +1487,19 @@ static int validate_and_copy_sample(const struct nlattr *attr, | |||
1462 | return -EINVAL; | 1487 | return -EINVAL; |
1463 | 1488 | ||
1464 | /* validation done, copy sample action. */ | 1489 | /* validation done, copy sample action. */ |
1465 | start = add_nested_action_start(sfa, OVS_ACTION_ATTR_SAMPLE); | 1490 | start = add_nested_action_start(sfa, OVS_ACTION_ATTR_SAMPLE, log); |
1466 | if (start < 0) | 1491 | if (start < 0) |
1467 | return start; | 1492 | return start; |
1468 | err = add_action(sfa, OVS_SAMPLE_ATTR_PROBABILITY, | 1493 | err = add_action(sfa, OVS_SAMPLE_ATTR_PROBABILITY, |
1469 | nla_data(probability), sizeof(u32)); | 1494 | nla_data(probability), sizeof(u32), log); |
1470 | if (err) | 1495 | if (err) |
1471 | return err; | 1496 | return err; |
1472 | st_acts = add_nested_action_start(sfa, OVS_SAMPLE_ATTR_ACTIONS); | 1497 | st_acts = add_nested_action_start(sfa, OVS_SAMPLE_ATTR_ACTIONS, log); |
1473 | if (st_acts < 0) | 1498 | if (st_acts < 0) |
1474 | return st_acts; | 1499 | return st_acts; |
1475 | 1500 | ||
1476 | err = __ovs_nla_copy_actions(actions, key, depth + 1, sfa, | 1501 | err = __ovs_nla_copy_actions(actions, key, depth + 1, sfa, |
1477 | eth_type, vlan_tci); | 1502 | eth_type, vlan_tci, log); |
1478 | if (err) | 1503 | if (err) |
1479 | return err; | 1504 | return err; |
1480 | 1505 | ||
@@ -1511,7 +1536,7 @@ void ovs_match_init(struct sw_flow_match *match, | |||
1511 | } | 1536 | } |
1512 | 1537 | ||
1513 | static int validate_and_copy_set_tun(const struct nlattr *attr, | 1538 | static int validate_and_copy_set_tun(const struct nlattr *attr, |
1514 | struct sw_flow_actions **sfa) | 1539 | struct sw_flow_actions **sfa, bool log) |
1515 | { | 1540 | { |
1516 | struct sw_flow_match match; | 1541 | struct sw_flow_match match; |
1517 | struct sw_flow_key key; | 1542 | struct sw_flow_key key; |
@@ -1520,7 +1545,7 @@ static int validate_and_copy_set_tun(const struct nlattr *attr, | |||
1520 | int err, start; | 1545 | int err, start; |
1521 | 1546 | ||
1522 | ovs_match_init(&match, &key, NULL); | 1547 | ovs_match_init(&match, &key, NULL); |
1523 | err = ipv4_tun_from_nlattr(nla_data(attr), &match, false); | 1548 | err = ipv4_tun_from_nlattr(nla_data(attr), &match, false, log); |
1524 | if (err) | 1549 | if (err) |
1525 | return err; | 1550 | return err; |
1526 | 1551 | ||
@@ -1549,12 +1574,12 @@ static int validate_and_copy_set_tun(const struct nlattr *attr, | |||
1549 | key.tun_key.tun_flags |= crit_opt ? TUNNEL_CRIT_OPT : 0; | 1574 | key.tun_key.tun_flags |= crit_opt ? TUNNEL_CRIT_OPT : 0; |
1550 | }; | 1575 | }; |
1551 | 1576 | ||
1552 | start = add_nested_action_start(sfa, OVS_ACTION_ATTR_SET); | 1577 | start = add_nested_action_start(sfa, OVS_ACTION_ATTR_SET, log); |
1553 | if (start < 0) | 1578 | if (start < 0) |
1554 | return start; | 1579 | return start; |
1555 | 1580 | ||
1556 | a = __add_action(sfa, OVS_KEY_ATTR_TUNNEL_INFO, NULL, | 1581 | a = __add_action(sfa, OVS_KEY_ATTR_TUNNEL_INFO, NULL, |
1557 | sizeof(*tun_info) + key.tun_opts_len); | 1582 | sizeof(*tun_info) + key.tun_opts_len, log); |
1558 | if (IS_ERR(a)) | 1583 | if (IS_ERR(a)) |
1559 | return PTR_ERR(a); | 1584 | return PTR_ERR(a); |
1560 | 1585 | ||
@@ -1582,7 +1607,7 @@ static int validate_and_copy_set_tun(const struct nlattr *attr, | |||
1582 | static int validate_set(const struct nlattr *a, | 1607 | static int validate_set(const struct nlattr *a, |
1583 | const struct sw_flow_key *flow_key, | 1608 | const struct sw_flow_key *flow_key, |
1584 | struct sw_flow_actions **sfa, | 1609 | struct sw_flow_actions **sfa, |
1585 | bool *set_tun, __be16 eth_type) | 1610 | bool *set_tun, __be16 eth_type, bool log) |
1586 | { | 1611 | { |
1587 | const struct nlattr *ovs_key = nla_data(a); | 1612 | const struct nlattr *ovs_key = nla_data(a); |
1588 | int key_type = nla_type(ovs_key); | 1613 | int key_type = nla_type(ovs_key); |
@@ -1611,7 +1636,7 @@ static int validate_set(const struct nlattr *a, | |||
1611 | return -EINVAL; | 1636 | return -EINVAL; |
1612 | 1637 | ||
1613 | *set_tun = true; | 1638 | *set_tun = true; |
1614 | err = validate_and_copy_set_tun(a, sfa); | 1639 | err = validate_and_copy_set_tun(a, sfa, log); |
1615 | if (err) | 1640 | if (err) |
1616 | return err; | 1641 | return err; |
1617 | break; | 1642 | break; |
@@ -1704,12 +1729,12 @@ static int validate_userspace(const struct nlattr *attr) | |||
1704 | } | 1729 | } |
1705 | 1730 | ||
1706 | static int copy_action(const struct nlattr *from, | 1731 | static int copy_action(const struct nlattr *from, |
1707 | struct sw_flow_actions **sfa) | 1732 | struct sw_flow_actions **sfa, bool log) |
1708 | { | 1733 | { |
1709 | int totlen = NLA_ALIGN(from->nla_len); | 1734 | int totlen = NLA_ALIGN(from->nla_len); |
1710 | struct nlattr *to; | 1735 | struct nlattr *to; |
1711 | 1736 | ||
1712 | to = reserve_sfa_size(sfa, from->nla_len); | 1737 | to = reserve_sfa_size(sfa, from->nla_len, log); |
1713 | if (IS_ERR(to)) | 1738 | if (IS_ERR(to)) |
1714 | return PTR_ERR(to); | 1739 | return PTR_ERR(to); |
1715 | 1740 | ||
@@ -1720,7 +1745,7 @@ static int copy_action(const struct nlattr *from, | |||
1720 | static int __ovs_nla_copy_actions(const struct nlattr *attr, | 1745 | static int __ovs_nla_copy_actions(const struct nlattr *attr, |
1721 | const struct sw_flow_key *key, | 1746 | const struct sw_flow_key *key, |
1722 | int depth, struct sw_flow_actions **sfa, | 1747 | int depth, struct sw_flow_actions **sfa, |
1723 | __be16 eth_type, __be16 vlan_tci) | 1748 | __be16 eth_type, __be16 vlan_tci, bool log) |
1724 | { | 1749 | { |
1725 | const struct nlattr *a; | 1750 | const struct nlattr *a; |
1726 | bool out_tnl_port = false; | 1751 | bool out_tnl_port = false; |
@@ -1843,7 +1868,7 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr, | |||
1843 | 1868 | ||
1844 | case OVS_ACTION_ATTR_SET: | 1869 | case OVS_ACTION_ATTR_SET: |
1845 | err = validate_set(a, key, sfa, | 1870 | err = validate_set(a, key, sfa, |
1846 | &out_tnl_port, eth_type); | 1871 | &out_tnl_port, eth_type, log); |
1847 | if (err) | 1872 | if (err) |
1848 | return err; | 1873 | return err; |
1849 | 1874 | ||
@@ -1852,18 +1877,18 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr, | |||
1852 | 1877 | ||
1853 | case OVS_ACTION_ATTR_SAMPLE: | 1878 | case OVS_ACTION_ATTR_SAMPLE: |
1854 | err = validate_and_copy_sample(a, key, depth, sfa, | 1879 | err = validate_and_copy_sample(a, key, depth, sfa, |
1855 | eth_type, vlan_tci); | 1880 | eth_type, vlan_tci, log); |
1856 | if (err) | 1881 | if (err) |
1857 | return err; | 1882 | return err; |
1858 | skip_copy = true; | 1883 | skip_copy = true; |
1859 | break; | 1884 | break; |
1860 | 1885 | ||
1861 | default: | 1886 | default: |
1862 | OVS_NLERR("Unknown tunnel attribute (%d).\n", type); | 1887 | OVS_NLERR(log, "Unknown Action type %d", type); |
1863 | return -EINVAL; | 1888 | return -EINVAL; |
1864 | } | 1889 | } |
1865 | if (!skip_copy) { | 1890 | if (!skip_copy) { |
1866 | err = copy_action(a, sfa); | 1891 | err = copy_action(a, sfa, log); |
1867 | if (err) | 1892 | if (err) |
1868 | return err; | 1893 | return err; |
1869 | } | 1894 | } |
@@ -1877,16 +1902,16 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr, | |||
1877 | 1902 | ||
1878 | int ovs_nla_copy_actions(const struct nlattr *attr, | 1903 | int ovs_nla_copy_actions(const struct nlattr *attr, |
1879 | const struct sw_flow_key *key, | 1904 | const struct sw_flow_key *key, |
1880 | struct sw_flow_actions **sfa) | 1905 | struct sw_flow_actions **sfa, bool log) |
1881 | { | 1906 | { |
1882 | int err; | 1907 | int err; |
1883 | 1908 | ||
1884 | *sfa = nla_alloc_flow_actions(nla_len(attr)); | 1909 | *sfa = nla_alloc_flow_actions(nla_len(attr), log); |
1885 | if (IS_ERR(*sfa)) | 1910 | if (IS_ERR(*sfa)) |
1886 | return PTR_ERR(*sfa); | 1911 | return PTR_ERR(*sfa); |
1887 | 1912 | ||
1888 | err = __ovs_nla_copy_actions(attr, key, 0, sfa, key->eth.type, | 1913 | err = __ovs_nla_copy_actions(attr, key, 0, sfa, key->eth.type, |
1889 | key->eth.tci); | 1914 | key->eth.tci, log); |
1890 | if (err) | 1915 | if (err) |
1891 | kfree(*sfa); | 1916 | kfree(*sfa); |
1892 | 1917 | ||