[ovs-dev] [PATCH 3/3] meta-flow: Adds arbitrary ethernet mask support

Joe Stringer joe at wand.net.nz
Wed May 16 01:18:08 UTC 2012


Signed-off-by: Joe Stringer <joe at wand.net.nz>
---
Firstly, I'm wondering how meta-flow fits into the OVS architecture?

I'm not sure how relevant this patch is--So disregard if it makes no sense--but
I noticed that there are translations between cls_rule and mf involving
ethernet masks, so I changed a few bits in the light of the new ethernet mask
fields in wildcards_t.

Again I've put some ATTN points, which primarily relates to whether this code
should enforce the four default masks we supported before, or allow arbitrary
ethernet masks.

I haven't tested this beyond running the testsuite, as I wasn't sure how to
go about doing so.
---
 lib/classifier.c |   15 +++++++++++++++
 lib/classifier.h |    2 ++
 lib/meta-flow.c  |   20 +++++++++++++++-----
 3 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/lib/classifier.c b/lib/classifier.c
index 6a1b040..cd8282b 100644
--- a/lib/classifier.c
+++ b/lib/classifier.c
@@ -153,6 +153,21 @@ cls_rule_set_dl_src(struct cls_rule *rule, const uint8_t dl_src[ETH_ADDR_LEN])
     memcpy(rule->flow.dl_src, dl_src, ETH_ADDR_LEN);
 }
 
+/* Modifies 'rule' so that the Ethernet address must match 'dl_src' after each
+ * byte is ANDed with the appropriate byte in 'mask'. */
+void
+cls_rule_set_dl_src_masked(struct cls_rule *rule,
+                           const uint8_t dl_src[ETH_ADDR_LEN],
+                           const uint8_t mask[ETH_ADDR_LEN])
+{
+    size_t i;
+
+    rule->wc.wildcards &= ~FWW_DL_SRC;
+    for (i = 0; i < ETH_ADDR_LEN; i++) {
+        rule->flow.dl_src[i] = dl_src[i] & mask[i];
+    }
+}
+
 /* Modifies 'rule' so that the Ethernet address must match 'dl_dst' exactly. */
 void
 cls_rule_set_dl_dst(struct cls_rule *rule, const uint8_t dl_dst[ETH_ADDR_LEN])
diff --git a/lib/classifier.h b/lib/classifier.h
index 92ccc2f..9e4b33e 100644
--- a/lib/classifier.h
+++ b/lib/classifier.h
@@ -96,6 +96,8 @@ void cls_rule_set_tun_id_masked(struct cls_rule *,
 void cls_rule_set_in_port(struct cls_rule *, uint16_t ofp_port);
 void cls_rule_set_dl_type(struct cls_rule *, ovs_be16);
 void cls_rule_set_dl_src(struct cls_rule *, const uint8_t[6]);
+void cls_rule_set_dl_src_masked(struct cls_rule *, const uint8_t dl_src[6],
+                                const uint8_t mask[6]);
 void cls_rule_set_dl_dst(struct cls_rule *, const uint8_t[6]);
 void cls_rule_set_dl_dst_masked(struct cls_rule *, const uint8_t dl_dst[6],
                                 const uint8_t mask[6]);
diff --git a/lib/meta-flow.c b/lib/meta-flow.c
index 8b60b35..f2d389e 100644
--- a/lib/meta-flow.c
+++ b/lib/meta-flow.c
@@ -651,7 +651,6 @@ mf_get_mask(const struct mf_field *mf, const struct flow_wildcards *wc,
 {
     switch (mf->id) {
     case MFF_IN_PORT:
-    case MFF_ETH_SRC:
     case MFF_ETH_TYPE:
     case MFF_IP_PROTO:
     case MFF_IP_DSCP:
@@ -702,10 +701,15 @@ mf_get_mask(const struct mf_field *mf, const struct flow_wildcards *wc,
         break;
 
     case MFF_ETH_DST:
+        /* ATTN: Do we need to enforce valid masks here? */
         memcpy(mask->mac, flow_wildcards_to_dl_dst_mask(wc->wildcards),
                ETH_ADDR_LEN);
         break;
 
+    case MFF_ETH_SRC:
+        memcpy(mask->mac, wc->dl_src_mask, ETH_ADDR_LEN);
+        break;
+
     case MFF_VLAN_TCI:
         mask->be16 = wc->vlan_tci_mask;
         break;
@@ -1533,12 +1537,14 @@ mf_set_wild(const struct mf_field *mf, struct cls_rule *rule)
 
     case MFF_ETH_SRC:
         rule->wc.wildcards |= FWW_DL_SRC;
-        memset(rule->flow.dl_src, 0, sizeof rule->flow.dl_src);
+        memset(rule->flow.dl_src, 0, ETH_ADDR_LEN);
+        memset(rule->wc.dl_src_mask, 0, ETH_ADDR_LEN);
         break;
 
     case MFF_ETH_DST:
         rule->wc.wildcards |= FWW_DL_DST | FWW_ETH_MCAST;
-        memset(rule->flow.dl_dst, 0, sizeof rule->flow.dl_dst);
+        memset(rule->flow.dl_dst, 0, ETH_ADDR_LEN);
+        memset(rule->wc.dl_dst_mask, 0, ETH_ADDR_LEN);
         break;
 
     case MFF_ETH_TYPE:
@@ -1678,7 +1684,6 @@ mf_set(const struct mf_field *mf,
 
     switch (mf->id) {
     case MFF_IN_PORT:
-    case MFF_ETH_SRC:
     case MFF_ETH_TYPE:
     case MFF_VLAN_VID:
     case MFF_VLAN_PCP:
@@ -1734,11 +1739,16 @@ mf_set(const struct mf_field *mf,
         break;
 
     case MFF_ETH_DST:
+        /* ATTN: Do we need validity check for arbitrary eth support? */
         if (flow_wildcards_is_dl_dst_mask_valid(mask->mac)) {
             cls_rule_set_dl_dst_masked(rule, value->mac, mask->mac);
         }
         break;
 
+    case MFF_ETH_SRC:
+        cls_rule_set_dl_src_masked(rule, value->mac, mask->mac);
+        break;
+
     case MFF_VLAN_TCI:
         cls_rule_set_dl_tci_masked(rule, value->be16, mask->be16);
         break;
@@ -2296,7 +2306,7 @@ mf_format(const struct mf_field *mf,
         NOT_REACHED();
     }
 }
-
+
 /* Makes subfield 'sf' within 'rule' exactly match the 'sf->n_bits'
  * least-significant bits in 'x'.
  *
-- 
1.6.0.1




More information about the dev mailing list