diff options
Diffstat (limited to 'net/openvswitch/flow_netlink.c')
-rw-r--r-- | net/openvswitch/flow_netlink.c | 186 |
1 files changed, 46 insertions, 140 deletions
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c index 4d000acaed0d..d757848da89c 100644 --- a/net/openvswitch/flow_netlink.c +++ b/net/openvswitch/flow_netlink.c | |||
@@ -16,6 +16,8 @@ | |||
16 | * 02110-1301, USA | 16 | * 02110-1301, USA |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
20 | |||
19 | #include "flow.h" | 21 | #include "flow.h" |
20 | #include "datapath.h" | 22 | #include "datapath.h" |
21 | #include <linux/uaccess.h> | 23 | #include <linux/uaccess.h> |
@@ -202,11 +204,11 @@ static bool match_validate(const struct sw_flow_match *match, | |||
202 | if (match->mask && (match->mask->key.ip.proto == 0xff)) | 204 | if (match->mask && (match->mask->key.ip.proto == 0xff)) |
203 | mask_allowed |= 1 << OVS_KEY_ATTR_ICMPV6; | 205 | mask_allowed |= 1 << OVS_KEY_ATTR_ICMPV6; |
204 | 206 | ||
205 | if (match->key->ipv6.tp.src == | 207 | if (match->key->tp.src == |
206 | htons(NDISC_NEIGHBOUR_SOLICITATION) || | 208 | htons(NDISC_NEIGHBOUR_SOLICITATION) || |
207 | match->key->ipv6.tp.src == htons(NDISC_NEIGHBOUR_ADVERTISEMENT)) { | 209 | match->key->tp.src == htons(NDISC_NEIGHBOUR_ADVERTISEMENT)) { |
208 | key_expected |= 1 << OVS_KEY_ATTR_ND; | 210 | key_expected |= 1 << OVS_KEY_ATTR_ND; |
209 | if (match->mask && (match->mask->key.ipv6.tp.src == htons(0xffff))) | 211 | if (match->mask && (match->mask->key.tp.src == htons(0xffff))) |
210 | mask_allowed |= 1 << OVS_KEY_ATTR_ND; | 212 | mask_allowed |= 1 << OVS_KEY_ATTR_ND; |
211 | } | 213 | } |
212 | } | 214 | } |
@@ -216,14 +218,14 @@ static bool match_validate(const struct sw_flow_match *match, | |||
216 | if ((key_attrs & key_expected) != key_expected) { | 218 | if ((key_attrs & key_expected) != key_expected) { |
217 | /* Key attributes check failed. */ | 219 | /* Key attributes check failed. */ |
218 | OVS_NLERR("Missing expected key attributes (key_attrs=%llx, expected=%llx).\n", | 220 | OVS_NLERR("Missing expected key attributes (key_attrs=%llx, expected=%llx).\n", |
219 | key_attrs, key_expected); | 221 | (unsigned long long)key_attrs, (unsigned long long)key_expected); |
220 | return false; | 222 | return false; |
221 | } | 223 | } |
222 | 224 | ||
223 | if ((mask_attrs & mask_allowed) != mask_attrs) { | 225 | if ((mask_attrs & mask_allowed) != mask_attrs) { |
224 | /* Mask attributes check failed. */ | 226 | /* Mask attributes check failed. */ |
225 | OVS_NLERR("Contain more than allowed mask fields (mask_attrs=%llx, mask_allowed=%llx).\n", | 227 | OVS_NLERR("Contain more than allowed mask fields (mask_attrs=%llx, mask_allowed=%llx).\n", |
226 | mask_attrs, mask_allowed); | 228 | (unsigned long long)mask_attrs, (unsigned long long)mask_allowed); |
227 | return false; | 229 | return false; |
228 | } | 230 | } |
229 | 231 | ||
@@ -266,20 +268,6 @@ static bool is_all_zero(const u8 *fp, size_t size) | |||
266 | return true; | 268 | return true; |
267 | } | 269 | } |
268 | 270 | ||
269 | static bool is_all_set(const u8 *fp, size_t size) | ||
270 | { | ||
271 | int i; | ||
272 | |||
273 | if (!fp) | ||
274 | return false; | ||
275 | |||
276 | for (i = 0; i < size; i++) | ||
277 | if (fp[i] != 0xff) | ||
278 | return false; | ||
279 | |||
280 | return true; | ||
281 | } | ||
282 | |||
283 | static int __parse_flow_nlattrs(const struct nlattr *attr, | 271 | static int __parse_flow_nlattrs(const struct nlattr *attr, |
284 | const struct nlattr *a[], | 272 | const struct nlattr *a[], |
285 | u64 *attrsp, bool nz) | 273 | u64 *attrsp, bool nz) |
@@ -501,9 +489,8 @@ static int metadata_from_nlattrs(struct sw_flow_match *match, u64 *attrs, | |||
501 | return 0; | 489 | return 0; |
502 | } | 490 | } |
503 | 491 | ||
504 | static int ovs_key_from_nlattrs(struct sw_flow_match *match, bool *exact_5tuple, | 492 | static int ovs_key_from_nlattrs(struct sw_flow_match *match, u64 attrs, |
505 | u64 attrs, const struct nlattr **a, | 493 | const struct nlattr **a, bool is_mask) |
506 | bool is_mask) | ||
507 | { | 494 | { |
508 | int err; | 495 | int err; |
509 | u64 orig_attrs = attrs; | 496 | u64 orig_attrs = attrs; |
@@ -560,11 +547,6 @@ static int ovs_key_from_nlattrs(struct sw_flow_match *match, bool *exact_5tuple | |||
560 | SW_FLOW_KEY_PUT(match, eth.type, htons(ETH_P_802_2), is_mask); | 547 | SW_FLOW_KEY_PUT(match, eth.type, htons(ETH_P_802_2), is_mask); |
561 | } | 548 | } |
562 | 549 | ||
563 | if (is_mask && exact_5tuple) { | ||
564 | if (match->mask->key.eth.type != htons(0xffff)) | ||
565 | *exact_5tuple = false; | ||
566 | } | ||
567 | |||
568 | if (attrs & (1 << OVS_KEY_ATTR_IPV4)) { | 550 | if (attrs & (1 << OVS_KEY_ATTR_IPV4)) { |
569 | const struct ovs_key_ipv4 *ipv4_key; | 551 | const struct ovs_key_ipv4 *ipv4_key; |
570 | 552 | ||
@@ -587,13 +569,6 @@ static int ovs_key_from_nlattrs(struct sw_flow_match *match, bool *exact_5tuple | |||
587 | SW_FLOW_KEY_PUT(match, ipv4.addr.dst, | 569 | SW_FLOW_KEY_PUT(match, ipv4.addr.dst, |
588 | ipv4_key->ipv4_dst, is_mask); | 570 | ipv4_key->ipv4_dst, is_mask); |
589 | attrs &= ~(1 << OVS_KEY_ATTR_IPV4); | 571 | attrs &= ~(1 << OVS_KEY_ATTR_IPV4); |
590 | |||
591 | if (is_mask && exact_5tuple && *exact_5tuple) { | ||
592 | if (ipv4_key->ipv4_proto != 0xff || | ||
593 | ipv4_key->ipv4_src != htonl(0xffffffff) || | ||
594 | ipv4_key->ipv4_dst != htonl(0xffffffff)) | ||
595 | *exact_5tuple = false; | ||
596 | } | ||
597 | } | 572 | } |
598 | 573 | ||
599 | if (attrs & (1 << OVS_KEY_ATTR_IPV6)) { | 574 | if (attrs & (1 << OVS_KEY_ATTR_IPV6)) { |
@@ -625,13 +600,6 @@ static int ovs_key_from_nlattrs(struct sw_flow_match *match, bool *exact_5tuple | |||
625 | is_mask); | 600 | is_mask); |
626 | 601 | ||
627 | attrs &= ~(1 << OVS_KEY_ATTR_IPV6); | 602 | attrs &= ~(1 << OVS_KEY_ATTR_IPV6); |
628 | |||
629 | if (is_mask && exact_5tuple && *exact_5tuple) { | ||
630 | if (ipv6_key->ipv6_proto != 0xff || | ||
631 | !is_all_set((u8 *)ipv6_key->ipv6_src, sizeof(match->key->ipv6.addr.src)) || | ||
632 | !is_all_set((u8 *)ipv6_key->ipv6_dst, sizeof(match->key->ipv6.addr.dst))) | ||
633 | *exact_5tuple = false; | ||
634 | } | ||
635 | } | 603 | } |
636 | 604 | ||
637 | if (attrs & (1 << OVS_KEY_ATTR_ARP)) { | 605 | if (attrs & (1 << OVS_KEY_ATTR_ARP)) { |
@@ -662,32 +630,18 @@ static int ovs_key_from_nlattrs(struct sw_flow_match *match, bool *exact_5tuple | |||
662 | const struct ovs_key_tcp *tcp_key; | 630 | const struct ovs_key_tcp *tcp_key; |
663 | 631 | ||
664 | tcp_key = nla_data(a[OVS_KEY_ATTR_TCP]); | 632 | tcp_key = nla_data(a[OVS_KEY_ATTR_TCP]); |
665 | if (orig_attrs & (1 << OVS_KEY_ATTR_IPV4)) { | 633 | SW_FLOW_KEY_PUT(match, tp.src, tcp_key->tcp_src, is_mask); |
666 | SW_FLOW_KEY_PUT(match, ipv4.tp.src, | 634 | SW_FLOW_KEY_PUT(match, tp.dst, tcp_key->tcp_dst, is_mask); |
667 | tcp_key->tcp_src, is_mask); | ||
668 | SW_FLOW_KEY_PUT(match, ipv4.tp.dst, | ||
669 | tcp_key->tcp_dst, is_mask); | ||
670 | } else { | ||
671 | SW_FLOW_KEY_PUT(match, ipv6.tp.src, | ||
672 | tcp_key->tcp_src, is_mask); | ||
673 | SW_FLOW_KEY_PUT(match, ipv6.tp.dst, | ||
674 | tcp_key->tcp_dst, is_mask); | ||
675 | } | ||
676 | attrs &= ~(1 << OVS_KEY_ATTR_TCP); | 635 | attrs &= ~(1 << OVS_KEY_ATTR_TCP); |
677 | |||
678 | if (is_mask && exact_5tuple && *exact_5tuple && | ||
679 | (tcp_key->tcp_src != htons(0xffff) || | ||
680 | tcp_key->tcp_dst != htons(0xffff))) | ||
681 | *exact_5tuple = false; | ||
682 | } | 636 | } |
683 | 637 | ||
684 | if (attrs & (1 << OVS_KEY_ATTR_TCP_FLAGS)) { | 638 | if (attrs & (1 << OVS_KEY_ATTR_TCP_FLAGS)) { |
685 | if (orig_attrs & (1 << OVS_KEY_ATTR_IPV4)) { | 639 | if (orig_attrs & (1 << OVS_KEY_ATTR_IPV4)) { |
686 | SW_FLOW_KEY_PUT(match, ipv4.tp.flags, | 640 | SW_FLOW_KEY_PUT(match, tp.flags, |
687 | nla_get_be16(a[OVS_KEY_ATTR_TCP_FLAGS]), | 641 | nla_get_be16(a[OVS_KEY_ATTR_TCP_FLAGS]), |
688 | is_mask); | 642 | is_mask); |
689 | } else { | 643 | } else { |
690 | SW_FLOW_KEY_PUT(match, ipv6.tp.flags, | 644 | SW_FLOW_KEY_PUT(match, tp.flags, |
691 | nla_get_be16(a[OVS_KEY_ATTR_TCP_FLAGS]), | 645 | nla_get_be16(a[OVS_KEY_ATTR_TCP_FLAGS]), |
692 | is_mask); | 646 | is_mask); |
693 | } | 647 | } |
@@ -698,40 +652,17 @@ static int ovs_key_from_nlattrs(struct sw_flow_match *match, bool *exact_5tuple | |||
698 | const struct ovs_key_udp *udp_key; | 652 | const struct ovs_key_udp *udp_key; |
699 | 653 | ||
700 | udp_key = nla_data(a[OVS_KEY_ATTR_UDP]); | 654 | udp_key = nla_data(a[OVS_KEY_ATTR_UDP]); |
701 | if (orig_attrs & (1 << OVS_KEY_ATTR_IPV4)) { | 655 | SW_FLOW_KEY_PUT(match, tp.src, udp_key->udp_src, is_mask); |
702 | SW_FLOW_KEY_PUT(match, ipv4.tp.src, | 656 | SW_FLOW_KEY_PUT(match, tp.dst, udp_key->udp_dst, is_mask); |
703 | udp_key->udp_src, is_mask); | ||
704 | SW_FLOW_KEY_PUT(match, ipv4.tp.dst, | ||
705 | udp_key->udp_dst, is_mask); | ||
706 | } else { | ||
707 | SW_FLOW_KEY_PUT(match, ipv6.tp.src, | ||
708 | udp_key->udp_src, is_mask); | ||
709 | SW_FLOW_KEY_PUT(match, ipv6.tp.dst, | ||
710 | udp_key->udp_dst, is_mask); | ||
711 | } | ||
712 | attrs &= ~(1 << OVS_KEY_ATTR_UDP); | 657 | attrs &= ~(1 << OVS_KEY_ATTR_UDP); |
713 | |||
714 | if (is_mask && exact_5tuple && *exact_5tuple && | ||
715 | (udp_key->udp_src != htons(0xffff) || | ||
716 | udp_key->udp_dst != htons(0xffff))) | ||
717 | *exact_5tuple = false; | ||
718 | } | 658 | } |
719 | 659 | ||
720 | if (attrs & (1 << OVS_KEY_ATTR_SCTP)) { | 660 | if (attrs & (1 << OVS_KEY_ATTR_SCTP)) { |
721 | const struct ovs_key_sctp *sctp_key; | 661 | const struct ovs_key_sctp *sctp_key; |
722 | 662 | ||
723 | sctp_key = nla_data(a[OVS_KEY_ATTR_SCTP]); | 663 | sctp_key = nla_data(a[OVS_KEY_ATTR_SCTP]); |
724 | if (orig_attrs & (1 << OVS_KEY_ATTR_IPV4)) { | 664 | SW_FLOW_KEY_PUT(match, tp.src, sctp_key->sctp_src, is_mask); |
725 | SW_FLOW_KEY_PUT(match, ipv4.tp.src, | 665 | SW_FLOW_KEY_PUT(match, tp.dst, sctp_key->sctp_dst, is_mask); |
726 | sctp_key->sctp_src, is_mask); | ||
727 | SW_FLOW_KEY_PUT(match, ipv4.tp.dst, | ||
728 | sctp_key->sctp_dst, is_mask); | ||
729 | } else { | ||
730 | SW_FLOW_KEY_PUT(match, ipv6.tp.src, | ||
731 | sctp_key->sctp_src, is_mask); | ||
732 | SW_FLOW_KEY_PUT(match, ipv6.tp.dst, | ||
733 | sctp_key->sctp_dst, is_mask); | ||
734 | } | ||
735 | attrs &= ~(1 << OVS_KEY_ATTR_SCTP); | 666 | attrs &= ~(1 << OVS_KEY_ATTR_SCTP); |
736 | } | 667 | } |
737 | 668 | ||
@@ -739,9 +670,9 @@ static int ovs_key_from_nlattrs(struct sw_flow_match *match, bool *exact_5tuple | |||
739 | const struct ovs_key_icmp *icmp_key; | 670 | const struct ovs_key_icmp *icmp_key; |
740 | 671 | ||
741 | icmp_key = nla_data(a[OVS_KEY_ATTR_ICMP]); | 672 | icmp_key = nla_data(a[OVS_KEY_ATTR_ICMP]); |
742 | SW_FLOW_KEY_PUT(match, ipv4.tp.src, | 673 | SW_FLOW_KEY_PUT(match, tp.src, |
743 | htons(icmp_key->icmp_type), is_mask); | 674 | htons(icmp_key->icmp_type), is_mask); |
744 | SW_FLOW_KEY_PUT(match, ipv4.tp.dst, | 675 | SW_FLOW_KEY_PUT(match, tp.dst, |
745 | htons(icmp_key->icmp_code), is_mask); | 676 | htons(icmp_key->icmp_code), is_mask); |
746 | attrs &= ~(1 << OVS_KEY_ATTR_ICMP); | 677 | attrs &= ~(1 << OVS_KEY_ATTR_ICMP); |
747 | } | 678 | } |
@@ -750,9 +681,9 @@ static int ovs_key_from_nlattrs(struct sw_flow_match *match, bool *exact_5tuple | |||
750 | const struct ovs_key_icmpv6 *icmpv6_key; | 681 | const struct ovs_key_icmpv6 *icmpv6_key; |
751 | 682 | ||
752 | icmpv6_key = nla_data(a[OVS_KEY_ATTR_ICMPV6]); | 683 | icmpv6_key = nla_data(a[OVS_KEY_ATTR_ICMPV6]); |
753 | SW_FLOW_KEY_PUT(match, ipv6.tp.src, | 684 | SW_FLOW_KEY_PUT(match, tp.src, |
754 | htons(icmpv6_key->icmpv6_type), is_mask); | 685 | htons(icmpv6_key->icmpv6_type), is_mask); |
755 | SW_FLOW_KEY_PUT(match, ipv6.tp.dst, | 686 | SW_FLOW_KEY_PUT(match, tp.dst, |
756 | htons(icmpv6_key->icmpv6_code), is_mask); | 687 | htons(icmpv6_key->icmpv6_code), is_mask); |
757 | attrs &= ~(1 << OVS_KEY_ATTR_ICMPV6); | 688 | attrs &= ~(1 << OVS_KEY_ATTR_ICMPV6); |
758 | } | 689 | } |
@@ -800,7 +731,6 @@ static void sw_flow_mask_set(struct sw_flow_mask *mask, | |||
800 | * attribute specifies the mask field of the wildcarded flow. | 731 | * attribute specifies the mask field of the wildcarded flow. |
801 | */ | 732 | */ |
802 | int ovs_nla_get_match(struct sw_flow_match *match, | 733 | int ovs_nla_get_match(struct sw_flow_match *match, |
803 | bool *exact_5tuple, | ||
804 | const struct nlattr *key, | 734 | const struct nlattr *key, |
805 | const struct nlattr *mask) | 735 | const struct nlattr *mask) |
806 | { | 736 | { |
@@ -848,13 +778,10 @@ int ovs_nla_get_match(struct sw_flow_match *match, | |||
848 | } | 778 | } |
849 | } | 779 | } |
850 | 780 | ||
851 | err = ovs_key_from_nlattrs(match, NULL, key_attrs, a, false); | 781 | err = ovs_key_from_nlattrs(match, key_attrs, a, false); |
852 | if (err) | 782 | if (err) |
853 | return err; | 783 | return err; |
854 | 784 | ||
855 | if (exact_5tuple) | ||
856 | *exact_5tuple = true; | ||
857 | |||
858 | if (mask) { | 785 | if (mask) { |
859 | err = parse_flow_mask_nlattrs(mask, a, &mask_attrs); | 786 | err = parse_flow_mask_nlattrs(mask, a, &mask_attrs); |
860 | if (err) | 787 | if (err) |
@@ -892,7 +819,7 @@ int ovs_nla_get_match(struct sw_flow_match *match, | |||
892 | } | 819 | } |
893 | } | 820 | } |
894 | 821 | ||
895 | err = ovs_key_from_nlattrs(match, exact_5tuple, mask_attrs, a, true); | 822 | err = ovs_key_from_nlattrs(match, mask_attrs, a, true); |
896 | if (err) | 823 | if (err) |
897 | return err; | 824 | return err; |
898 | } else { | 825 | } else { |
@@ -982,8 +909,8 @@ int ovs_nla_put_flow(const struct sw_flow_key *swkey, | |||
982 | goto nla_put_failure; | 909 | goto nla_put_failure; |
983 | 910 | ||
984 | eth_key = nla_data(nla); | 911 | eth_key = nla_data(nla); |
985 | memcpy(eth_key->eth_src, output->eth.src, ETH_ALEN); | 912 | ether_addr_copy(eth_key->eth_src, output->eth.src); |
986 | memcpy(eth_key->eth_dst, output->eth.dst, ETH_ALEN); | 913 | ether_addr_copy(eth_key->eth_dst, output->eth.dst); |
987 | 914 | ||
988 | if (swkey->eth.tci || swkey->eth.type == htons(ETH_P_8021Q)) { | 915 | if (swkey->eth.tci || swkey->eth.type == htons(ETH_P_8021Q)) { |
989 | __be16 eth_type; | 916 | __be16 eth_type; |
@@ -1055,8 +982,8 @@ int ovs_nla_put_flow(const struct sw_flow_key *swkey, | |||
1055 | arp_key->arp_sip = output->ipv4.addr.src; | 982 | arp_key->arp_sip = output->ipv4.addr.src; |
1056 | arp_key->arp_tip = output->ipv4.addr.dst; | 983 | arp_key->arp_tip = output->ipv4.addr.dst; |
1057 | arp_key->arp_op = htons(output->ip.proto); | 984 | arp_key->arp_op = htons(output->ip.proto); |
1058 | memcpy(arp_key->arp_sha, output->ipv4.arp.sha, ETH_ALEN); | 985 | ether_addr_copy(arp_key->arp_sha, output->ipv4.arp.sha); |
1059 | memcpy(arp_key->arp_tha, output->ipv4.arp.tha, ETH_ALEN); | 986 | ether_addr_copy(arp_key->arp_tha, output->ipv4.arp.tha); |
1060 | } | 987 | } |
1061 | 988 | ||
1062 | if ((swkey->eth.type == htons(ETH_P_IP) || | 989 | if ((swkey->eth.type == htons(ETH_P_IP) || |
@@ -1070,19 +997,11 @@ int ovs_nla_put_flow(const struct sw_flow_key *swkey, | |||
1070 | if (!nla) | 997 | if (!nla) |
1071 | goto nla_put_failure; | 998 | goto nla_put_failure; |
1072 | tcp_key = nla_data(nla); | 999 | tcp_key = nla_data(nla); |
1073 | if (swkey->eth.type == htons(ETH_P_IP)) { | 1000 | tcp_key->tcp_src = output->tp.src; |
1074 | tcp_key->tcp_src = output->ipv4.tp.src; | 1001 | tcp_key->tcp_dst = output->tp.dst; |
1075 | tcp_key->tcp_dst = output->ipv4.tp.dst; | 1002 | if (nla_put_be16(skb, OVS_KEY_ATTR_TCP_FLAGS, |
1076 | if (nla_put_be16(skb, OVS_KEY_ATTR_TCP_FLAGS, | 1003 | output->tp.flags)) |
1077 | output->ipv4.tp.flags)) | 1004 | goto nla_put_failure; |
1078 | goto nla_put_failure; | ||
1079 | } else if (swkey->eth.type == htons(ETH_P_IPV6)) { | ||
1080 | tcp_key->tcp_src = output->ipv6.tp.src; | ||
1081 | tcp_key->tcp_dst = output->ipv6.tp.dst; | ||
1082 | if (nla_put_be16(skb, OVS_KEY_ATTR_TCP_FLAGS, | ||
1083 | output->ipv6.tp.flags)) | ||
1084 | goto nla_put_failure; | ||
1085 | } | ||
1086 | } else if (swkey->ip.proto == IPPROTO_UDP) { | 1005 | } else if (swkey->ip.proto == IPPROTO_UDP) { |
1087 | struct ovs_key_udp *udp_key; | 1006 | struct ovs_key_udp *udp_key; |
1088 | 1007 | ||
@@ -1090,13 +1009,8 @@ int ovs_nla_put_flow(const struct sw_flow_key *swkey, | |||
1090 | if (!nla) | 1009 | if (!nla) |
1091 | goto nla_put_failure; | 1010 | goto nla_put_failure; |
1092 | udp_key = nla_data(nla); | 1011 | udp_key = nla_data(nla); |
1093 | if (swkey->eth.type == htons(ETH_P_IP)) { | 1012 | udp_key->udp_src = output->tp.src; |
1094 | udp_key->udp_src = output->ipv4.tp.src; | 1013 | udp_key->udp_dst = output->tp.dst; |
1095 | udp_key->udp_dst = output->ipv4.tp.dst; | ||
1096 | } else if (swkey->eth.type == htons(ETH_P_IPV6)) { | ||
1097 | udp_key->udp_src = output->ipv6.tp.src; | ||
1098 | udp_key->udp_dst = output->ipv6.tp.dst; | ||
1099 | } | ||
1100 | } else if (swkey->ip.proto == IPPROTO_SCTP) { | 1014 | } else if (swkey->ip.proto == IPPROTO_SCTP) { |
1101 | struct ovs_key_sctp *sctp_key; | 1015 | struct ovs_key_sctp *sctp_key; |
1102 | 1016 | ||
@@ -1104,13 +1018,8 @@ int ovs_nla_put_flow(const struct sw_flow_key *swkey, | |||
1104 | if (!nla) | 1018 | if (!nla) |
1105 | goto nla_put_failure; | 1019 | goto nla_put_failure; |
1106 | sctp_key = nla_data(nla); | 1020 | sctp_key = nla_data(nla); |
1107 | if (swkey->eth.type == htons(ETH_P_IP)) { | 1021 | sctp_key->sctp_src = output->tp.src; |
1108 | sctp_key->sctp_src = swkey->ipv4.tp.src; | 1022 | sctp_key->sctp_dst = output->tp.dst; |
1109 | sctp_key->sctp_dst = swkey->ipv4.tp.dst; | ||
1110 | } else if (swkey->eth.type == htons(ETH_P_IPV6)) { | ||
1111 | sctp_key->sctp_src = swkey->ipv6.tp.src; | ||
1112 | sctp_key->sctp_dst = swkey->ipv6.tp.dst; | ||
1113 | } | ||
1114 | } else if (swkey->eth.type == htons(ETH_P_IP) && | 1023 | } else if (swkey->eth.type == htons(ETH_P_IP) && |
1115 | swkey->ip.proto == IPPROTO_ICMP) { | 1024 | swkey->ip.proto == IPPROTO_ICMP) { |
1116 | struct ovs_key_icmp *icmp_key; | 1025 | struct ovs_key_icmp *icmp_key; |
@@ -1119,8 +1028,8 @@ int ovs_nla_put_flow(const struct sw_flow_key *swkey, | |||
1119 | if (!nla) | 1028 | if (!nla) |
1120 | goto nla_put_failure; | 1029 | goto nla_put_failure; |
1121 | icmp_key = nla_data(nla); | 1030 | icmp_key = nla_data(nla); |
1122 | icmp_key->icmp_type = ntohs(output->ipv4.tp.src); | 1031 | icmp_key->icmp_type = ntohs(output->tp.src); |
1123 | icmp_key->icmp_code = ntohs(output->ipv4.tp.dst); | 1032 | icmp_key->icmp_code = ntohs(output->tp.dst); |
1124 | } else if (swkey->eth.type == htons(ETH_P_IPV6) && | 1033 | } else if (swkey->eth.type == htons(ETH_P_IPV6) && |
1125 | swkey->ip.proto == IPPROTO_ICMPV6) { | 1034 | swkey->ip.proto == IPPROTO_ICMPV6) { |
1126 | struct ovs_key_icmpv6 *icmpv6_key; | 1035 | struct ovs_key_icmpv6 *icmpv6_key; |
@@ -1130,8 +1039,8 @@ int ovs_nla_put_flow(const struct sw_flow_key *swkey, | |||
1130 | if (!nla) | 1039 | if (!nla) |
1131 | goto nla_put_failure; | 1040 | goto nla_put_failure; |
1132 | icmpv6_key = nla_data(nla); | 1041 | icmpv6_key = nla_data(nla); |
1133 | icmpv6_key->icmpv6_type = ntohs(output->ipv6.tp.src); | 1042 | icmpv6_key->icmpv6_type = ntohs(output->tp.src); |
1134 | icmpv6_key->icmpv6_code = ntohs(output->ipv6.tp.dst); | 1043 | icmpv6_key->icmpv6_code = ntohs(output->tp.dst); |
1135 | 1044 | ||
1136 | if (icmpv6_key->icmpv6_type == NDISC_NEIGHBOUR_SOLICITATION || | 1045 | if (icmpv6_key->icmpv6_type == NDISC_NEIGHBOUR_SOLICITATION || |
1137 | icmpv6_key->icmpv6_type == NDISC_NEIGHBOUR_ADVERTISEMENT) { | 1046 | icmpv6_key->icmpv6_type == NDISC_NEIGHBOUR_ADVERTISEMENT) { |
@@ -1143,8 +1052,8 @@ int ovs_nla_put_flow(const struct sw_flow_key *swkey, | |||
1143 | nd_key = nla_data(nla); | 1052 | nd_key = nla_data(nla); |
1144 | memcpy(nd_key->nd_target, &output->ipv6.nd.target, | 1053 | memcpy(nd_key->nd_target, &output->ipv6.nd.target, |
1145 | sizeof(nd_key->nd_target)); | 1054 | sizeof(nd_key->nd_target)); |
1146 | memcpy(nd_key->nd_sll, output->ipv6.nd.sll, ETH_ALEN); | 1055 | ether_addr_copy(nd_key->nd_sll, output->ipv6.nd.sll); |
1147 | memcpy(nd_key->nd_tll, output->ipv6.nd.tll, ETH_ALEN); | 1056 | ether_addr_copy(nd_key->nd_tll, output->ipv6.nd.tll); |
1148 | } | 1057 | } |
1149 | } | 1058 | } |
1150 | } | 1059 | } |
@@ -1309,13 +1218,10 @@ static int validate_and_copy_sample(const struct nlattr *attr, | |||
1309 | 1218 | ||
1310 | static int validate_tp_port(const struct sw_flow_key *flow_key) | 1219 | static int validate_tp_port(const struct sw_flow_key *flow_key) |
1311 | { | 1220 | { |
1312 | if (flow_key->eth.type == htons(ETH_P_IP)) { | 1221 | if ((flow_key->eth.type == htons(ETH_P_IP) || |
1313 | if (flow_key->ipv4.tp.src || flow_key->ipv4.tp.dst) | 1222 | flow_key->eth.type == htons(ETH_P_IPV6)) && |
1314 | return 0; | 1223 | (flow_key->tp.src || flow_key->tp.dst)) |
1315 | } else if (flow_key->eth.type == htons(ETH_P_IPV6)) { | 1224 | return 0; |
1316 | if (flow_key->ipv6.tp.src || flow_key->ipv6.tp.dst) | ||
1317 | return 0; | ||
1318 | } | ||
1319 | 1225 | ||
1320 | return -EINVAL; | 1226 | return -EINVAL; |
1321 | } | 1227 | } |