+ if (mask && sscanf(s, "ipv6(src="IPV6_SCAN_FMT"/"IPV6_SCAN_FMT",dst="
+ IPV6_SCAN_FMT"/"IPV6_SCAN_FMT","
+ "label=%i/%i,proto=%i/%i,tclass=%i/%i,"
+ "hlimit=%i/%i,frag=%7[a-z]/%i)%n",
+ ipv6_src_s, ipv6_src_mask_s, ipv6_dst_s, ipv6_dst_mask_s,
+ &ipv6_label, &ipv6_label_mask, &ipv6_proto,
+ &ipv6_proto_mask, &ipv6_tclass, &ipv6_tclass_mask,
+ &ipv6_hlimit, &ipv6_hlimit_mask, frag,
+ &ipv6_frag_mask, &n) > 0
+ && n > 0
+ && ovs_frag_type_from_string(frag, &ipv6_frag)) {
+ struct ovs_key_ipv6 ipv6_key;
+ struct ovs_key_ipv6 ipv6_mask;
+
+ if (inet_pton(AF_INET6, ipv6_src_s, &ipv6_key.ipv6_src) != 1 ||
+ inet_pton(AF_INET6, ipv6_dst_s, &ipv6_key.ipv6_dst) != 1 ||
+ inet_pton(AF_INET6, ipv6_src_mask_s, &ipv6_mask.ipv6_src) != 1 ||
+ inet_pton(AF_INET6, ipv6_dst_mask_s, &ipv6_mask.ipv6_dst) != 1) {
+ return -EINVAL;
+ }
+
+ ipv6_key.ipv6_label = htonl(ipv6_label);
+ ipv6_key.ipv6_proto = ipv6_proto;
+ ipv6_key.ipv6_tclass = ipv6_tclass;
+ ipv6_key.ipv6_hlimit = ipv6_hlimit;
+ ipv6_key.ipv6_frag = ipv6_frag;
+ nl_msg_put_unspec(key, OVS_KEY_ATTR_IPV6,
+ &ipv6_key, sizeof ipv6_key);
+
+ ipv6_mask.ipv6_label = htonl(ipv6_label_mask);
+ ipv6_mask.ipv6_proto = ipv6_proto_mask;
+ ipv6_mask.ipv6_tclass = ipv6_tclass_mask;
+ ipv6_mask.ipv6_hlimit = ipv6_hlimit_mask;
+ ipv6_mask.ipv6_frag = ipv6_frag_mask;
+ nl_msg_put_unspec(mask, OVS_KEY_ATTR_IPV6,
+ &ipv6_mask, sizeof ipv6_mask);
+ return n;
+ } else if (sscanf(s, "ipv6(src="IPV6_SCAN_FMT",dst="IPV6_SCAN_FMT","