aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch/flow_netlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/openvswitch/flow_netlink.c')
-rw-r--r--net/openvswitch/flow_netlink.c186
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
269static 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
283static int __parse_flow_nlattrs(const struct nlattr *attr, 271static 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
504static int ovs_key_from_nlattrs(struct sw_flow_match *match, bool *exact_5tuple, 492static 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 */
802int ovs_nla_get_match(struct sw_flow_match *match, 733int 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
1310static int validate_tp_port(const struct sw_flow_key *flow_key) 1219static 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}