Process RARP packets with ethertype 0x8035 similar to ARP packets.
[openvswitch] / lib / meta-flow.c
index 0de9b4557b2551aec35b2c72b19a327e65c1706b..0b97049a4bd23c5fb49a44b8c2e30321cc2b0af2 100644 (file)
@@ -574,7 +574,7 @@ mf_is_all_wild(const struct mf_field *mf, const struct flow_wildcards *wc)
 {
     switch (mf->id) {
     case MFF_TUN_ID:
-        return !wc->masks.tun_id;
+        return !wc->masks.tunnel.tun_id;
     case MFF_METADATA:
         return !wc->masks.metadata;
     case MFF_IN_PORT:
@@ -671,7 +671,7 @@ mf_get_mask(const struct mf_field *mf, const struct flow_wildcards *wc,
 {
     switch (mf->id) {
     case MFF_TUN_ID:
-        mask->be64 = wc->masks.tun_id;
+        mask->be64 = wc->masks.tunnel.tun_id;
         break;
     case MFF_METADATA:
         mask->be64 = wc->masks.metadata;
@@ -834,7 +834,8 @@ mf_are_prereqs_ok(const struct mf_field *mf, const struct flow *flow)
         return true;
 
     case MFP_ARP:
-        return flow->dl_type == htons(ETH_TYPE_ARP);
+      return (flow->dl_type == htons(ETH_TYPE_ARP) ||
+              flow->dl_type == htons(ETH_TYPE_RARP));
     case MFP_IPV4:
         return flow->dl_type == htons(ETH_TYPE_IP);
     case MFP_IPV6:
@@ -952,7 +953,7 @@ mf_get_value(const struct mf_field *mf, const struct flow *flow,
 {
     switch (mf->id) {
     case MFF_TUN_ID:
-        value->be64 = flow->tun_id;
+        value->be64 = flow->tunnel.tun_id;
         break;
     case MFF_METADATA:
         value->be64 = flow->metadata;
@@ -1238,7 +1239,7 @@ mf_set_flow_value(const struct mf_field *mf,
 {
     switch (mf->id) {
     case MFF_TUN_ID:
-        flow->tun_id = value->be64;
+        flow->tunnel.tun_id = value->be64;
         break;
     case MFF_METADATA:
         flow->metadata = value->be64;
@@ -2153,6 +2154,22 @@ mf_format(const struct mf_field *mf,
     }
 }
 \f
+/* Makes subfield 'sf' within 'flow' exactly match the 'sf->n_bits'
+ * least-significant bits in 'x'.
+ */
+void
+mf_write_subfield_flow(const struct mf_subfield *sf,
+                       const union mf_subvalue *x, struct flow *flow)
+{
+    const struct mf_field *field = sf->field;
+    union mf_value value;
+
+    mf_get_value(field, flow, &value);
+    bitwise_copy(x, sizeof *x, 0, &value, field->n_bytes,
+                 sf->ofs, sf->n_bits);
+    mf_set_flow_value(field, &value, flow);
+}
+
 /* Makes subfield 'sf' within 'match' exactly match the 'sf->n_bits'
  * least-significant bits in 'x'.
  */
@@ -2335,3 +2352,20 @@ mf_parse_subfield(struct mf_subfield *sf, const char *s)
     }
     return s;
 }
+
+void
+mf_format_subvalue(const union mf_subvalue *subvalue, struct ds *s)
+{
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(subvalue->u8); i++) {
+        if (subvalue->u8[i]) {
+            ds_put_format(s, "0x%"PRIx8, subvalue->u8[i]);
+            for (i++; i < ARRAY_SIZE(subvalue->u8); i++) {
+                ds_put_format(s, "%02"PRIx8, subvalue->u8[i]);
+            }
+            return;
+        }
+    }
+    ds_put_char(s, '0');
+}