tunnel: Accept 'set options:tos' as hex value.
[sliver-openvswitch.git] / lib / meta-flow.c
index 3db528f..8b60b35 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012 Nicira Networks.
+ * Copyright (c) 2011, 2012 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -407,7 +407,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = {
     {
         MFF_ND_TARGET, "nd_target", NULL,
         MF_FIELD_SIZES(ipv6),
-        MFM_NONE, FWW_ND_TARGET,
+        MFM_CIDR, 0,
         MFS_IPV6,
         MFP_ND,
         false,
@@ -553,7 +553,6 @@ mf_is_all_wild(const struct mf_field *mf, const struct flow_wildcards *wc)
     case MFF_ARP_OP:
     case MFF_ARP_SHA:
     case MFF_ARP_THA:
-    case MFF_ND_TARGET:
     case MFF_ND_SLL:
     case MFF_ND_TLL:
         assert(mf->fww_bit != 0);
@@ -612,6 +611,9 @@ mf_is_all_wild(const struct mf_field *mf, const struct flow_wildcards *wc)
     case MFF_IPV6_DST:
         return ipv6_mask_is_any(&wc->ipv6_dst_mask);
 
+    case MFF_ND_TARGET:
+        return ipv6_mask_is_any(&wc->nd_target_mask);
+
     case MFF_IP_FRAG:
         return !(wc->nw_frag_mask & FLOW_NW_FRAG_MASK);
 
@@ -659,7 +661,6 @@ mf_get_mask(const struct mf_field *mf, const struct flow_wildcards *wc,
     case MFF_ARP_OP:
     case MFF_ARP_SHA:
     case MFF_ARP_THA:
-    case MFF_ND_TARGET:
     case MFF_ND_SLL:
     case MFF_ND_TLL:
         assert(mf->fww_bit != 0);
@@ -729,6 +730,10 @@ mf_get_mask(const struct mf_field *mf, const struct flow_wildcards *wc,
         mask->ipv6 = wc->ipv6_dst_mask;
         break;
 
+    case MFF_ND_TARGET:
+        mask->ipv6 = wc->nd_target_mask;
+        break;
+
     case MFF_IP_FRAG:
         mask->u8 = wc->nw_frag_mask & FLOW_NW_FRAG_MASK;
         break;
@@ -1339,7 +1344,7 @@ mf_set_flow_value(const struct mf_field *mf,
         break;
 
     case MFF_ETH_DST:
-        memcpy(flow->dl_src, value->mac, ETH_ADDR_LEN);
+        memcpy(flow->dl_dst, value->mac, ETH_ADDR_LEN);
         break;
 
     case MFF_ETH_TYPE:
@@ -1452,6 +1457,19 @@ mf_set_flow_value(const struct mf_field *mf,
     }
 }
 
+/* Returns true if 'mf' has a zero value in 'flow', false if it is nonzero.
+ *
+ * The caller is responsible for ensuring that 'flow' meets 'mf''s
+ * prerequisites. */
+bool
+mf_is_zero(const struct mf_field *mf, const struct flow *flow)
+{
+    union mf_value value;
+
+    mf_get_value(mf, flow, &value);
+    return is_all_zeros((const uint8_t *) &value, mf->n_bytes);
+}
+
 /* Makes 'rule' wildcard field 'mf'.
  *
  * The caller is responsible for ensuring that 'rule' meets 'mf''s
@@ -1624,7 +1642,7 @@ mf_set_wild(const struct mf_field *mf, struct cls_rule *rule)
         break;
 
     case MFF_ND_TARGET:
-        rule->wc.wildcards |= FWW_ND_TARGET;
+        memset(&rule->wc.nd_target_mask, 0, sizeof rule->wc.nd_target_mask);
         memset(&rule->flow.nd_target, 0, sizeof rule->flow.nd_target);
         break;
 
@@ -1676,7 +1694,6 @@ mf_set(const struct mf_field *mf,
     case MFF_ICMPV4_CODE:
     case MFF_ICMPV6_TYPE:
     case MFF_ICMPV6_CODE:
-    case MFF_ND_TARGET:
     case MFF_ND_SLL:
     case MFF_ND_TLL:
         NOT_REACHED();
@@ -1742,6 +1759,10 @@ mf_set(const struct mf_field *mf,
         cls_rule_set_ipv6_dst_masked(rule, &value->ipv6, &mask->ipv6);
         break;
 
+    case MFF_ND_TARGET:
+        cls_rule_set_nd_target_masked(rule, &value->ipv6, &mask->ipv6);
+        break;
+
     case MFF_IP_FRAG:
         cls_rule_set_nw_frag_masked(rule, value->u8, mask->u8);
         break;