[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