+void
+cls_rule_set_arp_sha(struct cls_rule *rule, const uint8_t sha[ETH_ADDR_LEN])
+{
+ rule->wc.wildcards &= ~FWW_ARP_SHA;
+ memcpy(rule->flow.arp_sha, sha, ETH_ADDR_LEN);
+}
+
+void
+cls_rule_set_arp_tha(struct cls_rule *rule, const uint8_t tha[ETH_ADDR_LEN])
+{
+ rule->wc.wildcards &= ~FWW_ARP_THA;
+ memcpy(rule->flow.arp_tha, tha, ETH_ADDR_LEN);
+}
+
+void
+cls_rule_set_ipv6_src(struct cls_rule *rule, const struct in6_addr *src)
+{
+ cls_rule_set_ipv6_src_masked(rule, src, &in6addr_exact);
+}
+
+bool
+cls_rule_set_ipv6_src_masked(struct cls_rule *rule, const struct in6_addr *src,
+ const struct in6_addr *mask)
+{
+ if (flow_wildcards_set_ipv6_src_mask(&rule->wc, mask)) {
+ rule->flow.ipv6_src = ipv6_addr_bitand(src, mask);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void
+cls_rule_set_ipv6_dst(struct cls_rule *rule, const struct in6_addr *dst)
+{
+ cls_rule_set_ipv6_dst_masked(rule, dst, &in6addr_exact);
+}
+
+bool
+cls_rule_set_ipv6_dst_masked(struct cls_rule *rule, const struct in6_addr *dst,
+ const struct in6_addr *mask)
+{
+ if (flow_wildcards_set_ipv6_dst_mask(&rule->wc, mask)) {
+ rule->flow.ipv6_dst = ipv6_addr_bitand(dst, mask);
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void
+cls_rule_set_nd_target(struct cls_rule *rule, const struct in6_addr target)
+{
+ rule->wc.wildcards &= ~FWW_ND_TARGET;
+ rule->flow.nd_target = target;
+}
+