#include <assert.h>
#include <errno.h>
#include <netinet/in.h>
+#include "byte-order.h"
#include "dynamic-string.h"
#include "flow.h"
#include "hash.h"
rule->priority = priority;
}
+/* Initializes 'rule' as a "catch-all" rule that matches every packet, with
+ * priority 'priority'. */
+void
+cls_rule_init_catchall(struct cls_rule *rule, unsigned int priority)
+{
+ memset(&rule->flow, 0, sizeof rule->flow);
+ flow_wildcards_init(&rule->wc, OVSFW_ALL | FWW_ALL);
+ rule->priority = priority;
+}
+
/* Converts the ofp_match in 'match' (with format 'flow_format', one of NXFF_*)
* into a cls_rule in 'rule', with the given 'priority'. 'cookie' is used
* when 'flow_format' is NXFF_TUN_ID_FROM_COOKIE. */
int flow_format, uint64_t cookie,
struct cls_rule *rule)
{
- flow_from_match(match, flow_format, cookie, &rule->flow, &rule->wc);
- rule->priority = !rule->wc.wildcards ? UINT16_MAX : priority;
+ uint32_t wildcards = ntohl(match->wildcards) & OVSFW_ALL;
+
+ rule->priority = !wildcards ? UINT16_MAX : priority;
+
+ rule->flow.tun_id = 0;
+ if (flow_format != NXFF_TUN_ID_FROM_COOKIE) {
+ wildcards |= NXFW_TUN_ID;
+ } else {
+ if (!(wildcards & NXFW_TUN_ID)) {
+ rule->flow.tun_id = htonl(ntohll(cookie) >> 32);
+ }
+ }
+ if (wildcards & OFPFW_DL_DST) {
+ /* OpenFlow 1.0 OFPFW_DL_DST covers the whole Ethernet destination, but
+ * internally to OVS it excludes the multicast bit, which has to be set
+ * separately with FWW_ETH_MCAST. */
+ wildcards |= FWW_ETH_MCAST;
+ }
+ flow_wildcards_init(&rule->wc, wildcards);
+
+ rule->flow.nw_src = match->nw_src;
+ rule->flow.nw_dst = match->nw_dst;
+ rule->flow.in_port = (match->in_port == htons(OFPP_LOCAL) ? ODPP_LOCAL
+ : ntohs(match->in_port));
+ rule->flow.dl_vlan = match->dl_vlan;
+ rule->flow.dl_vlan_pcp = match->dl_vlan_pcp;
+ rule->flow.dl_type = match->dl_type;
+ rule->flow.tp_src = match->tp_src;
+ rule->flow.tp_dst = match->tp_dst;
+ memcpy(rule->flow.dl_src, match->dl_src, ETH_ADDR_LEN);
+ memcpy(rule->flow.dl_dst, match->dl_dst, ETH_ADDR_LEN);
+ rule->flow.nw_tos = match->nw_tos;
+ rule->flow.nw_proto = match->nw_proto;
+
cls_rule_zero_wildcarded_fields(rule);
}
-/* Initializes 'rule' as a "catch-all" rule that matches every packet, with
- * priority 'priority'. */
+/* Converts 'rule' into an OpenFlow match structure 'match' with the given flow
+ * format 'flow_format' (one of NXFF_*). */
void
-cls_rule_init_catchall(struct cls_rule *rule, unsigned int priority)
-{
- memset(&rule->flow, 0, sizeof rule->flow);
- flow_wildcards_init(&rule->wc, OVSFW_ALL | FWW_ALL);
- rule->priority = priority;
+cls_rule_to_match(const struct cls_rule *rule, int flow_format,
+ struct ofp_match *match)
+{
+ match->wildcards = htonl(rule->wc.wildcards
+ & (flow_format == NXFF_TUN_ID_FROM_COOKIE
+ ? OVSFW_ALL : OFPFW_ALL));
+ match->in_port = htons(rule->flow.in_port == ODPP_LOCAL ? OFPP_LOCAL
+ : rule->flow.in_port);
+ match->dl_vlan = rule->flow.dl_vlan;
+ match->dl_vlan_pcp = rule->flow.dl_vlan_pcp;
+ memcpy(match->dl_src, rule->flow.dl_src, ETH_ADDR_LEN);
+ memcpy(match->dl_dst, rule->flow.dl_dst, ETH_ADDR_LEN);
+ match->dl_type = rule->flow.dl_type;
+ match->nw_src = rule->flow.nw_src;
+ match->nw_dst = rule->flow.nw_dst;
+ match->nw_tos = rule->flow.nw_tos;
+ match->nw_proto = rule->flow.nw_proto;
+ match->tp_src = rule->flow.tp_src;
+ match->tp_dst = rule->flow.tp_dst;
+ memset(match->pad1, '\0', sizeof match->pad1);
+ memset(match->pad2, '\0', sizeof match->pad2);
}
/* For each bit or field wildcarded in 'rule', sets the corresponding bit or
unsigned int priority, struct cls_rule *);
void cls_rule_init_exact(const struct flow *, unsigned int priority,
struct cls_rule *);
+void cls_rule_init_catchall(struct cls_rule *, unsigned int priority);
+
void cls_rule_from_match(const struct ofp_match *, unsigned int priority,
int flow_format, uint64_t cookie, struct cls_rule *);
-void cls_rule_init_catchall(struct cls_rule *, unsigned int priority);
+void cls_rule_to_match(const struct cls_rule *, int flow_format,
+ struct ofp_match *);
void cls_rule_zero_wildcarded_fields(struct cls_rule *);
stats->n_packets = 1;
}
-/* Extract 'flow' with 'wildcards' into the OpenFlow match structure
- * 'match'. 'flow_format' should be one of NXFF_*. */
-void
-flow_to_match(const struct flow *flow, uint32_t wildcards,
- int flow_format, struct ofp_match *match)
-{
- wildcards &= (flow_format == NXFF_TUN_ID_FROM_COOKIE ? OVSFW_ALL
- : OFPFW_ALL);
- match->wildcards = htonl(wildcards);
-
- match->in_port = htons(flow->in_port == ODPP_LOCAL ? OFPP_LOCAL
- : flow->in_port);
- match->dl_vlan = flow->dl_vlan;
- match->dl_vlan_pcp = flow->dl_vlan_pcp;
- memcpy(match->dl_src, flow->dl_src, ETH_ADDR_LEN);
- memcpy(match->dl_dst, flow->dl_dst, ETH_ADDR_LEN);
- match->dl_type = flow->dl_type;
- match->nw_src = flow->nw_src;
- match->nw_dst = flow->nw_dst;
- match->nw_tos = flow->nw_tos;
- match->nw_proto = flow->nw_proto;
- match->tp_src = flow->tp_src;
- match->tp_dst = flow->tp_dst;
- memset(match->pad1, '\0', sizeof match->pad1);
- memset(match->pad2, '\0', sizeof match->pad2);
-}
-
-void
-flow_from_match(const struct ofp_match *match, int flow_format,
- ovs_be64 cookie, struct flow *flow,
- struct flow_wildcards *wc)
-{
- uint32_t wildcards = ntohl(match->wildcards) & OVSFW_ALL;
-
- flow->tun_id = 0;
- if (flow_format != NXFF_TUN_ID_FROM_COOKIE) {
- wildcards |= NXFW_TUN_ID;
- } else {
- if (!(wildcards & NXFW_TUN_ID)) {
- flow->tun_id = htonl(ntohll(cookie) >> 32);
- }
- }
- if (wildcards & OFPFW_DL_DST) {
- /* OpenFlow 1.0 OFPFW_DL_DST covers the whole Ethernet destination, but
- * internally to OVS it excludes the multicast bit, which has to be set
- * separately with FWW_ETH_MCAST. */
- wildcards |= FWW_ETH_MCAST;
- }
- flow_wildcards_init(wc, wildcards);
-
- flow->nw_src = match->nw_src;
- flow->nw_dst = match->nw_dst;
- flow->in_port = (match->in_port == htons(OFPP_LOCAL) ? ODPP_LOCAL
- : ntohs(match->in_port));
- flow->dl_vlan = match->dl_vlan;
- flow->dl_vlan_pcp = match->dl_vlan_pcp;
- flow->dl_type = match->dl_type;
- flow->tp_src = match->tp_src;
- flow->tp_dst = match->tp_dst;
- memcpy(flow->dl_src, match->dl_src, ETH_ADDR_LEN);
- memcpy(flow->dl_dst, match->dl_dst, ETH_ADDR_LEN);
- flow->nw_tos = match->nw_tos;
- flow->nw_proto = match->nw_proto;
-}
-
char *
flow_to_string(const struct flow *flow)
{
struct flow *);
void flow_extract_stats(const struct flow *flow, struct ofpbuf *packet,
struct odp_flow_stats *stats);
-void flow_to_match(const struct flow *, uint32_t wildcards, int flow_format,
- struct ofp_match *);
-void flow_from_match(const struct ofp_match *, int flow_format,
- ovs_be64 cookie, struct flow *, struct flow_wildcards *);
char *flow_to_string(const struct flow *);
void flow_format(struct ds *, const struct flow *);
void flow_print(FILE *, const struct flow *);
parse_ofp_str(&pf, buffer, string);
ofm = buffer->data;
- flow_to_match(&pf.rule.flow, pf.rule.wc.wildcards, NXFF_OPENFLOW10,
- &ofm->match);
+ cls_rule_to_match(&pf.rule, NXFF_OPENFLOW10, &ofm->match);
ofm->command = htons(command);
ofm->cookie = htonll(pf.cookie);
ofm->idle_timeout = htons(pf.idle_timeout);
ofs->length = htons(len);
ofs->table_id = 0;
ofs->pad = 0;
- flow_to_match(&rule->cr.flow, rule->cr.wc.wildcards,
- ofconn->flow_format, &ofs->match);
+ cls_rule_to_match(&rule->cr, ofconn->flow_format, &ofs->match);
calc_flow_duration(rule->created, &ofs->duration_sec, &ofs->duration_nsec);
ofs->cookie = rule->flow_cookie;
ofs->priority = htons(rule->cr.priority);
size_t act_len = sizeof *rule->actions * rule->n_actions;
query_stats(ofproto, rule, &packet_count, &byte_count);
- flow_to_match(&rule->cr.flow, rule->cr.wc.wildcards,
- NXFF_OPENFLOW10, &match);
+ cls_rule_to_match(&rule->cr, NXFF_OPENFLOW10, &match);
ds_put_format(results, "duration=%llds, ",
(time_msec() - rule->created) / 1000);
struct ofpbuf *buf;
ofr = make_openflow(sizeof *ofr, OFPT_FLOW_REMOVED, &buf);
- flow_to_match(&rule->cr.flow, rule->cr.wc.wildcards, ofconn->flow_format,
- &ofr->match);
+ cls_rule_to_match(&rule->cr, ofconn->flow_format, &ofr->match);
ofr->cookie = rule->flow_cookie;
ofr->priority = htons(rule->cr.priority);
ofr->reason = reason;
#include <errno.h>
#include <stdlib.h>
#include <string.h>
+#include "classifier.h"
#include "openflow/openflow.h"
#include "timeval.h"
#include "ofpbuf.h"
#include "ofp-print.h"
+#include "ofp-util.h"
#include "pcap.h"
#include "util.h"
#include "vlog.h"
while (fread(&expected_match, sizeof expected_match, 1, flows)) {
struct ofpbuf *packet;
struct ofp_match extracted_match;
+ struct cls_rule rule;
struct flow flow;
n++;
}
flow_extract(packet, 0, 1, &flow);
- flow_to_match(&flow, 0, false, &extracted_match);
+ cls_rule_init_exact(&flow, 0, &rule);
+ cls_rule_to_match(&rule, NXFF_OPENFLOW10, &extracted_match);
if (memcmp(&expected_match, &extracted_match, sizeof expected_match)) {
char *exp_s = ofp_match_to_string(&expected_match, 2);
req = alloc_stats_request(sizeof *req, OFPST_FLOW, &request);
parse_ofp_str(&pf, NULL, argc > 2 ? argv[2] : "");
- flow_to_match(&pf.rule.flow, pf.rule.wc.wildcards, NXFF_OPENFLOW10,
- &req->match);
+ cls_rule_to_match(&pf.rule, NXFF_OPENFLOW10, &req->match);
memset(&req->pad, 0, sizeof req->pad);
req->out_port = htons(pf.out_port);
req = alloc_stats_request(sizeof *req, OFPST_AGGREGATE, &request);
parse_ofp_str(&pf, NULL, argc > 2 ? argv[2] : "");
- flow_to_match(&pf.rule.flow, pf.rule.wc.wildcards, NXFF_OPENFLOW10,
- &req->match);
+ cls_rule_to_match(&pf.rule, NXFF_OPENFLOW10, &req->match);
memset(&req->pad, 0, sizeof req->pad);
req->out_port = htons(pf.out_port);