2
0
mirror of https://github.com/openvswitch/ovs synced 2025-10-27 15:18:06 +00:00

ofp-util: Make make_flow_mod() take cls_rule instead of struct flow.

This reduces code duplication, by eliminating a function that translates
from "struct flow" to "struct ofp_match" in favor of the existing function
ofputil_cls_rule_to_match().  It also allows the caller to specify the
desired priority (as part of the cls_rule).
This commit is contained in:
Ben Pfaff
2010-11-10 14:51:49 -08:00
parent d8ae4d6726
commit daa68e9f29
3 changed files with 27 additions and 35 deletions

View File

@@ -24,6 +24,7 @@
#include <time.h> #include <time.h>
#include "byte-order.h" #include "byte-order.h"
#include "classifier.h"
#include "flow.h" #include "flow.h"
#include "hmap.h" #include "hmap.h"
#include "mac-learning.h" #include "mac-learning.h"
@@ -57,7 +58,7 @@ struct lswitch {
unsigned long long int datapath_id; unsigned long long int datapath_id;
time_t last_features_request; time_t last_features_request;
struct mac_learning *ml; /* NULL to act as hub instead of switch. */ struct mac_learning *ml; /* NULL to act as hub instead of switch. */
uint32_t wildcards; /* Wildcards to apply to flows. */ struct flow_wildcards wc; /* Wildcards to apply to flows. */
bool action_normal; /* Use OFPP_NORMAL? */ bool action_normal; /* Use OFPP_NORMAL? */
/* Queue distribution. */ /* Queue distribution. */
@@ -97,15 +98,16 @@ lswitch_create(struct rconn *rconn, const struct lswitch_config *cfg)
sw->last_features_request = time_now() - 1; sw->last_features_request = time_now() - 1;
sw->ml = cfg->mode == LSW_LEARN ? mac_learning_create() : NULL; sw->ml = cfg->mode == LSW_LEARN ? mac_learning_create() : NULL;
sw->action_normal = cfg->mode == LSW_NORMAL; sw->action_normal = cfg->mode == LSW_NORMAL;
if (cfg->exact_flows) {
/* Exact match. */ flow_wildcards_init_exact(&sw->wc);
sw->wildcards = 0; if (!cfg->exact_flows) {
} else {
/* We cannot wildcard all fields. /* We cannot wildcard all fields.
* We need in_port to detect moves. * We need in_port to detect moves.
* We need both SA and DA to do learning. */ * We need both SA and DA to do learning. */
sw->wildcards = (OFPFW_DL_TYPE | OFPFW_NW_SRC_MASK | OFPFW_NW_DST_MASK sw->wc.wildcards = (FWW_DL_TYPE | FWW_NW_PROTO
| OFPFW_NW_PROTO | OFPFW_TP_SRC | OFPFW_TP_DST); | FWW_TP_SRC | FWW_TP_DST);
sw->wc.nw_src_mask = htonl(0);
sw->wc.nw_dst_mask = htonl(0);
} }
sw->default_queue = cfg->default_queue; sw->default_queue = cfg->default_queue;
@@ -423,14 +425,15 @@ process_packet_in(struct lswitch *sw, struct rconn *rconn, void *opi_)
if (sw->max_idle >= 0 && (!sw->ml || out_port != OFPP_FLOOD)) { if (sw->max_idle >= 0 && (!sw->ml || out_port != OFPP_FLOOD)) {
struct ofpbuf *buffer; struct ofpbuf *buffer;
struct ofp_flow_mod *ofm; struct ofp_flow_mod *ofm;
struct cls_rule rule;
/* The output port is known, or we always flood everything, so add a /* The output port is known, or we always flood everything, so add a
* new flow. */ * new flow. */
buffer = make_add_flow(&flow, ntohl(opi->buffer_id), cls_rule_init(&flow, &sw->wc, 0, &rule);
buffer = make_add_flow(&rule, ntohl(opi->buffer_id),
sw->max_idle, actions_len); sw->max_idle, actions_len);
ofpbuf_put(buffer, actions, actions_len); ofpbuf_put(buffer, actions, actions_len);
ofm = buffer->data; ofm = buffer->data;
ofm->match.wildcards = htonl(sw->wildcards);
queue_tx(sw, rconn, buffer); queue_tx(sw, rconn, buffer);
/* If the switch didn't buffer the packet, we need to send a copy. */ /* If the switch didn't buffer the packet, we need to send a copy. */

View File

@@ -328,7 +328,8 @@ update_openflow_length(struct ofpbuf *buffer)
} }
struct ofpbuf * struct ofpbuf *
make_flow_mod(uint16_t command, const struct flow *flow, size_t actions_len) make_flow_mod(uint16_t command, const struct cls_rule *rule,
size_t actions_len)
{ {
struct ofp_flow_mod *ofm; struct ofp_flow_mod *ofm;
size_t size = sizeof *ofm + actions_len; size_t size = sizeof *ofm + actions_len;
@@ -338,29 +339,17 @@ make_flow_mod(uint16_t command, const struct flow *flow, size_t actions_len)
ofm->header.type = OFPT_FLOW_MOD; ofm->header.type = OFPT_FLOW_MOD;
ofm->header.length = htons(size); ofm->header.length = htons(size);
ofm->cookie = 0; ofm->cookie = 0;
ofm->match.wildcards = htonl(0); ofm->priority = htons(MIN(rule->priority, UINT16_MAX));
ofm->match.in_port = htons(flow->in_port == ODPP_LOCAL ? OFPP_LOCAL ofputil_cls_rule_to_match(rule, NXFF_OPENFLOW10, &ofm->match);
: flow->in_port);
memcpy(ofm->match.dl_src, flow->dl_src, sizeof ofm->match.dl_src);
memcpy(ofm->match.dl_dst, flow->dl_dst, sizeof ofm->match.dl_dst);
ofm->match.dl_vlan = flow->dl_vlan;
ofm->match.dl_vlan_pcp = flow->dl_vlan_pcp;
ofm->match.dl_type = flow->dl_type;
ofm->match.nw_src = flow->nw_src;
ofm->match.nw_dst = flow->nw_dst;
ofm->match.nw_proto = flow->nw_proto;
ofm->match.nw_tos = flow->nw_tos;
ofm->match.tp_src = flow->tp_src;
ofm->match.tp_dst = flow->tp_dst;
ofm->command = htons(command); ofm->command = htons(command);
return out; return out;
} }
struct ofpbuf * struct ofpbuf *
make_add_flow(const struct flow *flow, uint32_t buffer_id, make_add_flow(const struct cls_rule *rule, uint32_t buffer_id,
uint16_t idle_timeout, size_t actions_len) uint16_t idle_timeout, size_t actions_len)
{ {
struct ofpbuf *out = make_flow_mod(OFPFC_ADD, flow, actions_len); struct ofpbuf *out = make_flow_mod(OFPFC_ADD, rule, actions_len);
struct ofp_flow_mod *ofm = out->data; struct ofp_flow_mod *ofm = out->data;
ofm->idle_timeout = htons(idle_timeout); ofm->idle_timeout = htons(idle_timeout);
ofm->hard_timeout = htons(OFP_FLOW_PERMANENT); ofm->hard_timeout = htons(OFP_FLOW_PERMANENT);
@@ -369,16 +358,16 @@ make_add_flow(const struct flow *flow, uint32_t buffer_id,
} }
struct ofpbuf * struct ofpbuf *
make_del_flow(const struct flow *flow) make_del_flow(const struct cls_rule *rule)
{ {
struct ofpbuf *out = make_flow_mod(OFPFC_DELETE_STRICT, flow, 0); struct ofpbuf *out = make_flow_mod(OFPFC_DELETE_STRICT, rule, 0);
struct ofp_flow_mod *ofm = out->data; struct ofp_flow_mod *ofm = out->data;
ofm->out_port = htons(OFPP_NONE); ofm->out_port = htons(OFPP_NONE);
return out; return out;
} }
struct ofpbuf * struct ofpbuf *
make_add_simple_flow(const struct flow *flow, make_add_simple_flow(const struct cls_rule *rule,
uint32_t buffer_id, uint16_t out_port, uint32_t buffer_id, uint16_t out_port,
uint16_t idle_timeout) uint16_t idle_timeout)
{ {
@@ -386,14 +375,14 @@ make_add_simple_flow(const struct flow *flow,
struct ofp_action_output *oao; struct ofp_action_output *oao;
struct ofpbuf *buffer; struct ofpbuf *buffer;
buffer = make_add_flow(flow, buffer_id, idle_timeout, sizeof *oao); buffer = make_add_flow(rule, buffer_id, idle_timeout, sizeof *oao);
oao = ofpbuf_put_zeros(buffer, sizeof *oao); oao = ofpbuf_put_zeros(buffer, sizeof *oao);
oao->type = htons(OFPAT_OUTPUT); oao->type = htons(OFPAT_OUTPUT);
oao->len = htons(sizeof *oao); oao->len = htons(sizeof *oao);
oao->port = htons(out_port); oao->port = htons(out_port);
return buffer; return buffer;
} else { } else {
return make_add_flow(flow, buffer_id, idle_timeout, 0); return make_add_flow(rule, buffer_id, idle_timeout, 0);
} }
} }

View File

@@ -56,12 +56,12 @@ void *put_openflow(size_t openflow_len, uint8_t type, struct ofpbuf *);
void *put_openflow_xid(size_t openflow_len, uint8_t type, ovs_be32 xid, void *put_openflow_xid(size_t openflow_len, uint8_t type, ovs_be32 xid,
struct ofpbuf *); struct ofpbuf *);
void update_openflow_length(struct ofpbuf *); void update_openflow_length(struct ofpbuf *);
struct ofpbuf *make_flow_mod(uint16_t command, const struct flow *, struct ofpbuf *make_flow_mod(uint16_t command, const struct cls_rule *,
size_t actions_len); size_t actions_len);
struct ofpbuf *make_add_flow(const struct flow *, uint32_t buffer_id, struct ofpbuf *make_add_flow(const struct cls_rule *, uint32_t buffer_id,
uint16_t max_idle, size_t actions_len); uint16_t max_idle, size_t actions_len);
struct ofpbuf *make_del_flow(const struct flow *); struct ofpbuf *make_del_flow(const struct cls_rule *);
struct ofpbuf *make_add_simple_flow(const struct flow *, struct ofpbuf *make_add_simple_flow(const struct cls_rule *,
uint32_t buffer_id, uint16_t out_port, uint32_t buffer_id, uint16_t out_port,
uint16_t max_idle); uint16_t max_idle);
struct ofpbuf *make_packet_in(uint32_t buffer_id, uint16_t in_port, struct ofpbuf *make_packet_in(uint32_t buffer_id, uint16_t in_port,