[ovs-discuss] [ACLv2 12/19] flow: Allow matching on additional ARP payload fields.
Jesse Gross
jesse at nicira.com
Sat Aug 15 02:13:20 UTC 2009
This allows the ARP SHA and THA (source and destination MAC addresses)
to be matched in flows. This currently can only be done in
userspace.
---
lib/classifier.h | 7 +++++--
lib/flow.c | 21 +++++++++++++--------
lib/flow.h | 9 +++++++++
3 files changed, 27 insertions(+), 10 deletions(-)
diff --git a/lib/classifier.h b/lib/classifier.h
index 8b095e9..983eaab 100644
--- a/lib/classifier.h
+++ b/lib/classifier.h
@@ -33,7 +33,7 @@
#include "openflow/openflow.h"
/* Number of bytes of fields in a rule. */
-#define CLS_N_BYTES 31
+#define CLS_N_BYTES 43
/* Fields in a rule.
*
@@ -53,7 +53,10 @@
CLS_FIELD(OFPFW_NW_DST_MASK, nw_dst, NW_DST) \
CLS_FIELD(OFPFW_NW_PROTO, nw_proto, NW_PROTO) \
CLS_FIELD(OFPFW_TP_SRC, tp_src, TP_SRC) \
- CLS_FIELD(OFPFW_TP_DST, tp_dst, TP_DST)
+ CLS_FIELD(OFPFW_TP_DST, tp_dst, TP_DST) \
+ CLS_FIELD(NICFW_AR_SHA, ar_sha, AR_SHA) \
+ CLS_FIELD(NICFW_AR_THA, ar_tha, AR_THA)
+
/* Field indexes.
*
diff --git a/lib/flow.c b/lib/flow.c
index 6952392..6b8e4a6 100644
--- a/lib/flow.c
+++ b/lib/flow.c
@@ -206,6 +206,8 @@ flow_extract(struct ofpbuf *packet, uint16_t in_port, flow_t *flow)
|| (flow->nw_proto == ARP_OP_REPLY)) {
flow->nw_src = arp->ar_spa;
flow->nw_dst = arp->ar_tpa;
+ memcpy(flow->ar_sha, arp->ar_sha, ETH_ADDR_LEN);
+ memcpy(flow->ar_tha, arp->ar_tha, ETH_ADDR_LEN);
}
}
}
@@ -238,13 +240,13 @@ flow_extract_stats(const flow_t *flow, const struct ofpbuf *packet,
void
flow_to_match(const flow_t *flow, uint32_t wildcards, struct ofp_match *match)
{
- /* The datapath supports matching on an ARP's opcode and IP addresses,
- * but OpenFlow does not. We need to clear the appropriate wildcard
- * bits so that OpenFlow is unaware of our trickery. */
+ /* We support matching on an ARP's payload, but OpenFlow does not.
+ * We need to clear the appropriate wildcard bits so that OpenFlow
+ * is unaware of our trickery. */
if (flow->dl_type == htons(ETH_TYPE_ARP)) {
- wildcards = ~(OFPFW_NW_PROTO | OFPFW_NW_SRC_ALL | OFPFW_NW_DST_ALL)
- & wildcards;
+ wildcards &= ~(OFPFW_NW_PROTO | OFPFW_NW_SRC_ALL | OFPFW_NW_DST_ALL);
}
+ wildcards &= ~(NICFW_AR_SHA | NICFW_AR_THA);
match->wildcards = htonl(wildcards);
match->in_port = htons(flow->in_port == ODPP_LOCAL ? OFPP_LOCAL
@@ -268,12 +270,13 @@ flow_from_match(flow_t *flow, uint32_t *wildcards,
if (wildcards) {
*wildcards = ntohl(match->wildcards);
}
- /* The datapath supports matching on an ARP's opcode and IP addresses,
- * but OpenFlow does not. We need to set the appropriate wildcard
- * bits so that OpenFlow's wishes are obeyed. */
+ /* We support matching on an ARP's payload, but OpenFlow does not.
+ * We need to set the appropriate wildcard bits so that OpenFlow's
+ * wishes are obeyed. */
if (match->dl_type == htons(ETH_TYPE_ARP)) {
*wildcards |= (OFPFW_NW_PROTO | OFPFW_NW_SRC_ALL | OFPFW_NW_DST_ALL);
}
+ *wildcards |= (NICFW_AR_SHA | NICFW_AR_THA);
flow->nw_src = match->nw_src;
flow->nw_dst = match->nw_dst;
@@ -287,6 +290,8 @@ flow_from_match(flow_t *flow, uint32_t *wildcards,
memcpy(flow->dl_dst, match->dl_dst, ETH_ADDR_LEN);
flow->nw_proto = match->nw_proto;
flow->reserved = 0;
+ memset(&flow->ar_sha, 0, sizeof flow->ar_sha);
+ memset(&flow->ar_tha, 0, sizeof flow->ar_tha);
}
void
diff --git a/lib/flow.h b/lib/flow.h
index 0932746..d110213 100644
--- a/lib/flow.h
+++ b/lib/flow.h
@@ -30,6 +30,13 @@ struct ds;
struct ofp_match;
struct ofpbuf;
+enum nicira_flow_wildcards {
+ NICFW_AR_SHA = 1 << 25, /* ARP sender hardware address. */
+ NICFW_AR_THA = 1 << 26 /* ARP target hardware address. */
+};
+
+#define OFPFW_ALL (OFPFW_ALL | NICFW_AR_SHA | NICFW_AR_THA)
+
struct userspace_flow {
union {
struct {
@@ -47,6 +54,8 @@ struct userspace_flow {
};
struct odp_flow_key odp;
};
+ uint8_t ar_sha[ETH_ALEN]; /* ARP sender hardware address. */
+ uint8_t ar_tha[ETH_ALEN]; /* ARP target hardware address. */
};
typedef struct userspace_flow flow_t;
--
1.6.0.4
More information about the discuss
mailing list