2
0
mirror of https://github.com/openvswitch/ovs synced 2025-10-11 13:57:52 +00:00

ofproto: Change ofproto_add_flow(), ofproto_delete_flow() to take cls_rule.

This is a small cleanup that will make later changes to wildcards easier.
This commit is contained in:
Ben Pfaff
2010-10-20 16:46:48 -07:00
parent 3052b0c5e5
commit cf3fad8a1b
7 changed files with 64 additions and 73 deletions

View File

@@ -134,6 +134,16 @@ cls_rule_from_match(const struct ofp_match *match, unsigned int priority,
rule->priority = rule->wc.wildcards ? priority : UINT16_MAX; rule->priority = rule->wc.wildcards ? priority : UINT16_MAX;
} }
/* 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);
rule->priority = priority;
}
/* For each bit or field wildcarded in 'rule', sets the corresponding bit or /* For each bit or field wildcarded in 'rule', sets the corresponding bit or
* field in 'flow' to all-0-bits. It is important to maintain this invariant * field in 'flow' to all-0-bits. It is important to maintain this invariant
* in a clr_rule that might be inserted into a classifier. * in a clr_rule that might be inserted into a classifier.

View File

@@ -77,6 +77,7 @@ void cls_rule_from_flow(const struct flow *, uint32_t wildcards,
unsigned int priority, struct cls_rule *); unsigned int priority, struct cls_rule *);
void cls_rule_from_match(const struct ofp_match *, unsigned int priority, void cls_rule_from_match(const struct ofp_match *, unsigned int priority,
int flow_format, uint64_t cookie, struct cls_rule *); int flow_format, uint64_t cookie, struct cls_rule *);
void cls_rule_init_catchall(struct cls_rule *, unsigned int priority);
void cls_rule_zero_wildcarded_fields(struct cls_rule *); void cls_rule_zero_wildcarded_fields(struct cls_rule *);

View File

@@ -18,6 +18,7 @@
#include "fail-open.h" #include "fail-open.h"
#include <inttypes.h> #include <inttypes.h>
#include <stdlib.h> #include <stdlib.h>
#include "classifier.h"
#include "flow.h" #include "flow.h"
#include "mac-learning.h" #include "mac-learning.h"
#include "odp-util.h" #include "odp-util.h"
@@ -257,14 +258,14 @@ static void
fail_open_recover(struct fail_open *fo) fail_open_recover(struct fail_open *fo)
{ {
if (fail_open_is_active(fo)) { if (fail_open_is_active(fo)) {
struct flow flow; struct cls_rule rule;
VLOG_WARN("No longer in fail-open mode"); VLOG_WARN("No longer in fail-open mode");
fo->last_disconn_secs = 0; fo->last_disconn_secs = 0;
fo->next_bogus_packet_in = LLONG_MAX; fo->next_bogus_packet_in = LLONG_MAX;
memset(&flow, 0, sizeof flow); cls_rule_init_catchall(&rule, FAIL_OPEN_PRIORITY);
ofproto_delete_flow(fo->ofproto, &flow, OVSFW_ALL, FAIL_OPEN_PRIORITY); ofproto_delete_flow(fo->ofproto, &rule);
} }
} }
@@ -283,7 +284,7 @@ fail_open_flushed(struct fail_open *fo)
bool open = disconn_secs >= trigger_duration(fo); bool open = disconn_secs >= trigger_duration(fo);
if (open) { if (open) {
union ofp_action action; union ofp_action action;
struct flow flow; struct cls_rule rule;
/* Set up a flow that matches every packet and directs them to /* Set up a flow that matches every packet and directs them to
* OFPP_NORMAL. */ * OFPP_NORMAL. */
@@ -291,9 +292,9 @@ fail_open_flushed(struct fail_open *fo)
action.type = htons(OFPAT_OUTPUT); action.type = htons(OFPAT_OUTPUT);
action.output.len = htons(sizeof action); action.output.len = htons(sizeof action);
action.output.port = htons(OFPP_NORMAL); action.output.port = htons(OFPP_NORMAL);
memset(&flow, 0, sizeof flow);
ofproto_add_flow(fo->ofproto, &flow, OVSFW_ALL, FAIL_OPEN_PRIORITY, cls_rule_init_catchall(&rule, FAIL_OPEN_PRIORITY);
&action, 1, 0); ofproto_add_flow(fo->ofproto, &rule, &action, 1, 0);
} }
} }

View File

@@ -23,6 +23,7 @@
#include <net/if.h> #include <net/if.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include "classifier.h"
#include "dhcp.h" #include "dhcp.h"
#include "dpif.h" #include "dpif.h"
#include "flow.h" #include "flow.h"
@@ -223,12 +224,6 @@ enum {
IBR_FROM_REMOTE_TCP /* (i) From remote IP, TCP port. */ IBR_FROM_REMOTE_TCP /* (i) From remote IP, TCP port. */
}; };
struct in_band_rule {
struct flow flow;
uint32_t wildcards;
unsigned int priority;
};
/* Track one remote IP and next hop information. */ /* Track one remote IP and next hop information. */
struct in_band_remote { struct in_band_remote {
struct sockaddr_in remote_addr; /* IP address, in network byte order. */ struct sockaddr_in remote_addr; /* IP address, in network byte order. */
@@ -459,88 +454,78 @@ in_band_rule_check(struct in_band *in_band, const struct flow *flow,
} }
static void static void
init_rule(struct in_band_rule *rule, unsigned int priority) set_in_port(struct cls_rule *rule, uint16_t odp_port)
{ {
rule->wildcards = OVSFW_ALL; rule->wc.wildcards &= ~OFPFW_IN_PORT;
rule->priority = priority;
/* Not strictly necessary but seems cleaner. */
memset(&rule->flow, 0, sizeof rule->flow);
}
static void
set_in_port(struct in_band_rule *rule, uint16_t odp_port)
{
rule->wildcards &= ~OFPFW_IN_PORT;
rule->flow.in_port = odp_port; rule->flow.in_port = odp_port;
} }
static void static void
set_dl_type(struct in_band_rule *rule, uint16_t dl_type) set_dl_type(struct cls_rule *rule, uint16_t dl_type)
{ {
rule->wildcards &= ~OFPFW_DL_TYPE; rule->wc.wildcards &= ~OFPFW_DL_TYPE;
rule->flow.dl_type = dl_type; rule->flow.dl_type = dl_type;
} }
static void static void
set_dl_src(struct in_band_rule *rule, const uint8_t dl_src[ETH_ADDR_LEN]) set_dl_src(struct cls_rule *rule, const uint8_t dl_src[ETH_ADDR_LEN])
{ {
rule->wildcards &= ~OFPFW_DL_SRC; rule->wc.wildcards &= ~OFPFW_DL_SRC;
memcpy(rule->flow.dl_src, dl_src, ETH_ADDR_LEN); memcpy(rule->flow.dl_src, dl_src, ETH_ADDR_LEN);
} }
static void static void
set_dl_dst(struct in_band_rule *rule, const uint8_t dl_dst[ETH_ADDR_LEN]) set_dl_dst(struct cls_rule *rule, const uint8_t dl_dst[ETH_ADDR_LEN])
{ {
rule->wildcards &= ~OFPFW_DL_DST; rule->wc.wildcards &= ~OFPFW_DL_DST;
memcpy(rule->flow.dl_dst, dl_dst, ETH_ADDR_LEN); memcpy(rule->flow.dl_dst, dl_dst, ETH_ADDR_LEN);
} }
static void static void
set_tp_src(struct in_band_rule *rule, uint16_t tp_src) set_tp_src(struct cls_rule *rule, uint16_t tp_src)
{ {
rule->wildcards &= ~OFPFW_TP_SRC; rule->wc.wildcards &= ~OFPFW_TP_SRC;
rule->flow.tp_src = tp_src; rule->flow.tp_src = tp_src;
} }
static void static void
set_tp_dst(struct in_band_rule *rule, uint16_t tp_dst) set_tp_dst(struct cls_rule *rule, uint16_t tp_dst)
{ {
rule->wildcards &= ~OFPFW_TP_DST; rule->wc.wildcards &= ~OFPFW_TP_DST;
rule->flow.tp_dst = tp_dst; rule->flow.tp_dst = tp_dst;
} }
static void static void
set_nw_proto(struct in_band_rule *rule, uint8_t nw_proto) set_nw_proto(struct cls_rule *rule, uint8_t nw_proto)
{ {
rule->wildcards &= ~OFPFW_NW_PROTO; rule->wc.wildcards &= ~OFPFW_NW_PROTO;
rule->flow.nw_proto = nw_proto; rule->flow.nw_proto = nw_proto;
} }
static void static void
set_nw_src(struct in_band_rule *rule, const struct in_addr nw_src) set_nw_src(struct cls_rule *rule, const struct in_addr nw_src)
{ {
rule->wildcards &= ~OFPFW_NW_SRC_MASK; rule->wc.wildcards &= ~OFPFW_NW_SRC_MASK;
rule->flow.nw_src = nw_src.s_addr; rule->flow.nw_src = nw_src.s_addr;
} }
static void static void
set_nw_dst(struct in_band_rule *rule, const struct in_addr nw_dst) set_nw_dst(struct cls_rule *rule, const struct in_addr nw_dst)
{ {
rule->wildcards &= ~OFPFW_NW_DST_MASK; rule->wc.wildcards &= ~OFPFW_NW_DST_MASK;
rule->flow.nw_dst = nw_dst.s_addr; rule->flow.nw_dst = nw_dst.s_addr;
} }
static void static void
make_rules(struct in_band *ib, make_rules(struct in_band *ib,
void (*cb)(struct in_band *, const struct in_band_rule *)) void (*cb)(struct in_band *, const struct cls_rule *))
{ {
struct in_band_rule rule; struct cls_rule rule;
size_t i; size_t i;
if (!eth_addr_is_zero(ib->installed_local_mac)) { if (!eth_addr_is_zero(ib->installed_local_mac)) {
/* (a) Allow DHCP requests sent from the local port. */ /* (a) Allow DHCP requests sent from the local port. */
init_rule(&rule, IBR_FROM_LOCAL_DHCP); cls_rule_init_catchall(&rule, IBR_FROM_LOCAL_DHCP);
set_in_port(&rule, ODPP_LOCAL); set_in_port(&rule, ODPP_LOCAL);
set_dl_type(&rule, htons(ETH_TYPE_IP)); set_dl_type(&rule, htons(ETH_TYPE_IP));
set_dl_src(&rule, ib->installed_local_mac); set_dl_src(&rule, ib->installed_local_mac);
@@ -550,14 +535,14 @@ make_rules(struct in_band *ib,
cb(ib, &rule); cb(ib, &rule);
/* (b) Allow ARP replies to the local port's MAC address. */ /* (b) Allow ARP replies to the local port's MAC address. */
init_rule(&rule, IBR_TO_LOCAL_ARP); cls_rule_init_catchall(&rule, IBR_TO_LOCAL_ARP);
set_dl_type(&rule, htons(ETH_TYPE_ARP)); set_dl_type(&rule, htons(ETH_TYPE_ARP));
set_dl_dst(&rule, ib->installed_local_mac); set_dl_dst(&rule, ib->installed_local_mac);
set_nw_proto(&rule, ARP_OP_REPLY); set_nw_proto(&rule, ARP_OP_REPLY);
cb(ib, &rule); cb(ib, &rule);
/* (c) Allow ARP requests from the local port's MAC address. */ /* (c) Allow ARP requests from the local port's MAC address. */
init_rule(&rule, IBR_FROM_LOCAL_ARP); cls_rule_init_catchall(&rule, IBR_FROM_LOCAL_ARP);
set_dl_type(&rule, htons(ETH_TYPE_ARP)); set_dl_type(&rule, htons(ETH_TYPE_ARP));
set_dl_src(&rule, ib->installed_local_mac); set_dl_src(&rule, ib->installed_local_mac);
set_nw_proto(&rule, ARP_OP_REQUEST); set_nw_proto(&rule, ARP_OP_REQUEST);
@@ -576,14 +561,14 @@ make_rules(struct in_band *ib,
} }
/* (d) Allow ARP replies to the next hop's MAC address. */ /* (d) Allow ARP replies to the next hop's MAC address. */
init_rule(&rule, IBR_TO_NEXT_HOP_ARP); cls_rule_init_catchall(&rule, IBR_TO_NEXT_HOP_ARP);
set_dl_type(&rule, htons(ETH_TYPE_ARP)); set_dl_type(&rule, htons(ETH_TYPE_ARP));
set_dl_dst(&rule, remote_mac); set_dl_dst(&rule, remote_mac);
set_nw_proto(&rule, ARP_OP_REPLY); set_nw_proto(&rule, ARP_OP_REPLY);
cb(ib, &rule); cb(ib, &rule);
/* (e) Allow ARP requests from the next hop's MAC address. */ /* (e) Allow ARP requests from the next hop's MAC address. */
init_rule(&rule, IBR_FROM_NEXT_HOP_ARP); cls_rule_init_catchall(&rule, IBR_FROM_NEXT_HOP_ARP);
set_dl_type(&rule, htons(ETH_TYPE_ARP)); set_dl_type(&rule, htons(ETH_TYPE_ARP));
set_dl_src(&rule, remote_mac); set_dl_src(&rule, remote_mac);
set_nw_proto(&rule, ARP_OP_REQUEST); set_nw_proto(&rule, ARP_OP_REQUEST);
@@ -596,7 +581,7 @@ make_rules(struct in_band *ib,
if (!i || a->sin_addr.s_addr != a[-1].sin_addr.s_addr) { if (!i || a->sin_addr.s_addr != a[-1].sin_addr.s_addr) {
/* (f) Allow ARP replies containing the remote's IP address as a /* (f) Allow ARP replies containing the remote's IP address as a
* target. */ * target. */
init_rule(&rule, IBR_TO_REMOTE_ARP); cls_rule_init_catchall(&rule, IBR_TO_REMOTE_ARP);
set_dl_type(&rule, htons(ETH_TYPE_ARP)); set_dl_type(&rule, htons(ETH_TYPE_ARP));
set_nw_proto(&rule, ARP_OP_REPLY); set_nw_proto(&rule, ARP_OP_REPLY);
set_nw_dst(&rule, a->sin_addr); set_nw_dst(&rule, a->sin_addr);
@@ -604,7 +589,7 @@ make_rules(struct in_band *ib,
/* (g) Allow ARP requests containing the remote's IP address as a /* (g) Allow ARP requests containing the remote's IP address as a
* source. */ * source. */
init_rule(&rule, IBR_FROM_REMOTE_ARP); cls_rule_init_catchall(&rule, IBR_FROM_REMOTE_ARP);
set_dl_type(&rule, htons(ETH_TYPE_ARP)); set_dl_type(&rule, htons(ETH_TYPE_ARP));
set_nw_proto(&rule, ARP_OP_REQUEST); set_nw_proto(&rule, ARP_OP_REQUEST);
set_nw_src(&rule, a->sin_addr); set_nw_src(&rule, a->sin_addr);
@@ -615,7 +600,7 @@ make_rules(struct in_band *ib,
|| a->sin_addr.s_addr != a[-1].sin_addr.s_addr || a->sin_addr.s_addr != a[-1].sin_addr.s_addr
|| a->sin_port != a[-1].sin_port) { || a->sin_port != a[-1].sin_port) {
/* (h) Allow TCP traffic to the remote's IP and port. */ /* (h) Allow TCP traffic to the remote's IP and port. */
init_rule(&rule, IBR_TO_REMOTE_TCP); cls_rule_init_catchall(&rule, IBR_TO_REMOTE_TCP);
set_dl_type(&rule, htons(ETH_TYPE_IP)); set_dl_type(&rule, htons(ETH_TYPE_IP));
set_nw_proto(&rule, IP_TYPE_TCP); set_nw_proto(&rule, IP_TYPE_TCP);
set_nw_dst(&rule, a->sin_addr); set_nw_dst(&rule, a->sin_addr);
@@ -623,7 +608,7 @@ make_rules(struct in_band *ib,
cb(ib, &rule); cb(ib, &rule);
/* (i) Allow TCP traffic from the remote's IP and port. */ /* (i) Allow TCP traffic from the remote's IP and port. */
init_rule(&rule, IBR_FROM_REMOTE_TCP); cls_rule_init_catchall(&rule, IBR_FROM_REMOTE_TCP);
set_dl_type(&rule, htons(ETH_TYPE_IP)); set_dl_type(&rule, htons(ETH_TYPE_IP));
set_nw_proto(&rule, IP_TYPE_TCP); set_nw_proto(&rule, IP_TYPE_TCP);
set_nw_src(&rule, a->sin_addr); set_nw_src(&rule, a->sin_addr);
@@ -634,10 +619,9 @@ make_rules(struct in_band *ib,
} }
static void static void
drop_rule(struct in_band *ib, const struct in_band_rule *rule) drop_rule(struct in_band *ib, const struct cls_rule *rule)
{ {
ofproto_delete_flow(ib->ofproto, &rule->flow, ofproto_delete_flow(ib->ofproto, rule);
rule->wildcards, rule->priority);
} }
/* Drops from the flow table all of the flows set up by 'ib', then clears out /* Drops from the flow table all of the flows set up by 'ib', then clears out
@@ -662,7 +646,7 @@ drop_rules(struct in_band *ib)
} }
static void static void
add_rule(struct in_band *ib, const struct in_band_rule *rule) add_rule(struct in_band *ib, const struct cls_rule *rule)
{ {
union ofp_action action; union ofp_action action;
@@ -670,8 +654,7 @@ add_rule(struct in_band *ib, const struct in_band_rule *rule)
action.output.len = htons(sizeof action); action.output.len = htons(sizeof action);
action.output.port = htons(OFPP_NORMAL); action.output.port = htons(OFPP_NORMAL);
action.output.max_len = htons(0); action.output.max_len = htons(0);
ofproto_add_flow(ib->ofproto, &rule->flow, rule->wildcards, ofproto_add_flow(ib->ofproto, rule, &action, 1, 0);
rule->priority, &action, 1, 0);
} }
/* Inserts flows into the flow table for the current state of 'ib'. */ /* Inserts flows into the flow table for the current state of 'ib'. */

View File

@@ -1298,8 +1298,7 @@ ofproto_send_packet(struct ofproto *p, const struct flow *flow,
} }
void void
ofproto_add_flow(struct ofproto *p, const struct flow *flow, ofproto_add_flow(struct ofproto *p, const struct cls_rule *cls_rule,
uint32_t wildcards, unsigned int priority,
const union ofp_action *actions, size_t n_actions, const union ofp_action *actions, size_t n_actions,
int idle_timeout) int idle_timeout)
{ {
@@ -1307,20 +1306,17 @@ ofproto_add_flow(struct ofproto *p, const struct flow *flow,
rule = rule_create(p, NULL, actions, n_actions, rule = rule_create(p, NULL, actions, n_actions,
idle_timeout >= 0 ? idle_timeout : 5 /* XXX */, idle_timeout >= 0 ? idle_timeout : 5 /* XXX */,
0, 0, false); 0, 0, false);
cls_rule_from_flow(flow, wildcards, priority, &rule->cr); rule->cr = *cls_rule;
rule_insert(p, rule, NULL, 0); rule_insert(p, rule, NULL, 0);
} }
void void
ofproto_delete_flow(struct ofproto *ofproto, const struct flow *flow, ofproto_delete_flow(struct ofproto *ofproto, const struct cls_rule *target)
uint32_t wildcards, unsigned int priority)
{ {
struct cls_rule target;
struct rule *rule; struct rule *rule;
cls_rule_from_flow(flow, wildcards, priority, &target);
rule = rule_from_cls_rule(classifier_find_rule_exactly(&ofproto->cls, rule = rule_from_cls_rule(classifier_find_rule_exactly(&ofproto->cls,
&target)); target));
if (rule) { if (rule) {
rule_remove(ofproto, rule); rule_remove(ofproto, rule);
} }

View File

@@ -30,6 +30,7 @@
extern "C" { extern "C" {
#endif #endif
struct cls_rule;
struct odp_actions; struct odp_actions;
struct ofhooks; struct ofhooks;
struct ofproto; struct ofproto;
@@ -126,12 +127,10 @@ void ofproto_get_all_flows(struct ofproto *p, struct ds *);
int ofproto_send_packet(struct ofproto *, const struct flow *, int ofproto_send_packet(struct ofproto *, const struct flow *,
const union ofp_action *, size_t n_actions, const union ofp_action *, size_t n_actions,
const struct ofpbuf *); const struct ofpbuf *);
void ofproto_add_flow(struct ofproto *, const struct flow *, void ofproto_add_flow(struct ofproto *, const struct cls_rule *,
uint32_t wildcards, unsigned int priority,
const union ofp_action *, size_t n_actions, const union ofp_action *, size_t n_actions,
int idle_timeout); int idle_timeout);
void ofproto_delete_flow(struct ofproto *, const struct flow *, void ofproto_delete_flow(struct ofproto *, const struct cls_rule *);
uint32_t wildcards, unsigned int priority);
void ofproto_flush_flows(struct ofproto *); void ofproto_flush_flows(struct ofproto *);
/* Hooks for ovs-vswitchd. */ /* Hooks for ovs-vswitchd. */

View File

@@ -32,6 +32,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include "bitmap.h" #include "bitmap.h"
#include "classifier.h"
#include "coverage.h" #include "coverage.h"
#include "dirs.h" #include "dirs.h"
#include "dpif.h" #include "dpif.h"
@@ -1792,14 +1793,14 @@ bridge_reconfigure_remotes(struct bridge *br,
if (!n_controllers if (!n_controllers
&& ofproto_get_fail_mode(br->ofproto) == OFPROTO_FAIL_STANDALONE) { && ofproto_get_fail_mode(br->ofproto) == OFPROTO_FAIL_STANDALONE) {
union ofp_action action; union ofp_action action;
struct flow flow; struct cls_rule rule;
memset(&action, 0, sizeof action); memset(&action, 0, sizeof action);
action.type = htons(OFPAT_OUTPUT); action.type = htons(OFPAT_OUTPUT);
action.output.len = htons(sizeof action); action.output.len = htons(sizeof action);
action.output.port = htons(OFPP_NORMAL); action.output.port = htons(OFPP_NORMAL);
memset(&flow, 0, sizeof flow); cls_rule_init_catchall(&rule, 0);
ofproto_add_flow(br->ofproto, &flow, OVSFW_ALL, 0, &action, 1, 0); ofproto_add_flow(br->ofproto, &rule, &action, 1, 0);
} }
} }