#include "ofproto-dpif-governor.h"
#include "ofproto-dpif-ipfix.h"
#include "ofproto-dpif-mirror.h"
+#include "ofproto-dpif-monitor.h"
#include "ofproto-dpif-sflow.h"
#include "ofproto-dpif-upcall.h"
#include "ofproto-dpif-xlate.h"
}
static void port_run(struct ofport_dpif *);
-static void port_run_fast(struct ofport_dpif *);
-static void port_wait(struct ofport_dpif *);
static int set_bfd(struct ofport *, const struct smap *);
static int set_cfm(struct ofport *, const struct cfm_settings *);
static void ofport_update_peer(struct ofport_dpif *);
struct classifier facets; /* Contains 'struct facet's. */
long long int consistency_rl;
- struct netdev_stats stats; /* To account packets generated and consumed in
- * userspace. */
+ struct ovs_mutex stats_mutex;
+ struct netdev_stats stats OVS_GUARDED; /* To account packets generated and
+ * consumed in userspace. */
/* Spanning tree. */
struct stp *stp;
ofproto->ml = mac_learning_create(MAC_ENTRY_DEFAULT_IDLE_TIME);
ofproto->mbridge = mbridge_create();
ofproto->has_bonded_bundles = false;
+ ovs_mutex_init(&ofproto->stats_mutex);
ovs_mutex_init(&ofproto->vsp_mutex);
classifier_init(&ofproto->facets);
sset_destroy(&ofproto->ghost_ports);
sset_destroy(&ofproto->port_poll_set);
+ ovs_mutex_destroy(&ofproto->stats_mutex);
ovs_mutex_destroy(&ofproto->vsp_mutex);
close_dpif_backer(ofproto->backer);
{
struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
struct ofputil_packet_in *pin, *next_pin;
- struct ofport_dpif *ofport;
struct list pins;
/* Do not perform any periodic activity required by 'ofproto' while
free(pin);
}
- HMAP_FOR_EACH (ofport, up.hmap_node, &ofproto->up.ports) {
- port_run_fast(ofport);
- }
-
+ ofproto_dpif_monitor_run_fast();
return 0;
}
dpif_ipfix_run(ofproto->ipfix);
}
+ ofproto_dpif_monitor_run_fast();
+ ofproto_dpif_monitor_run();
+
HMAP_FOR_EACH (ofport, up.hmap_node, &ofproto->up.ports) {
port_run(ofport);
}
wait(struct ofproto *ofproto_)
{
struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
- struct ofport_dpif *ofport;
struct ofbundle *bundle;
if (ofproto_get_flow_restore_wait()) {
if (ofproto->ipfix) {
dpif_ipfix_wait(ofproto->ipfix);
}
- HMAP_FOR_EACH (ofport, up.hmap_node, &ofproto->up.ports) {
- port_wait(ofport);
- }
+ ofproto_dpif_monitor_wait();
HMAP_FOR_EACH (bundle, hmap_node, &ofproto->bundles) {
bundle_wait(bundle);
}
bfd_set_netdev(port->bfd, port->up.netdev);
}
+ ofproto_dpif_monitor_port_update(port, port->bfd, port->cfm,
+ port->up.pp.hw_addr);
+
if (port->is_tunnel && tnl_port_reconfigure(port, port->up.netdev,
port->odp_port)) {
ofproto_dpif_cast(port->up.ofproto)->backer->need_revalidate =
set_cfm(struct ofport *ofport_, const struct cfm_settings *s)
{
struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
- int error;
+ int error = 0;
- if (!s) {
- error = 0;
- } else {
+ if (s) {
if (!ofport->cfm) {
struct ofproto_dpif *ofproto;
}
if (cfm_configure(ofport->cfm, s)) {
- return 0;
+ error = 0;
+ goto out;
}
error = EINVAL;
}
cfm_unref(ofport->cfm);
ofport->cfm = NULL;
+out:
+ ofproto_dpif_monitor_port_update(ofport, ofport->bfd, ofport->cfm,
+ ofport->up.pp.hw_addr);
return error;
}
if (ofport->bfd != old) {
ofproto->backer->need_revalidate = REV_RECONFIGURE;
}
-
+ ofproto_dpif_monitor_port_update(ofport, ofport->bfd, ofport->cfm,
+ ofport->up.pp.hw_addr);
return 0;
}
free(peer_name);
}
-static void
-port_run_fast(struct ofport_dpif *ofport)
-{
- if (ofport->cfm && cfm_should_send_ccm(ofport->cfm)) {
- struct ofpbuf packet;
-
- ofpbuf_init(&packet, 0);
- cfm_compose_ccm(ofport->cfm, &packet, ofport->up.pp.hw_addr);
- ofproto_dpif_send_packet(ofport, &packet);
- ofpbuf_uninit(&packet);
- }
-
- if (ofport->bfd && bfd_should_send_packet(ofport->bfd)) {
- struct ofpbuf packet;
-
- ofpbuf_init(&packet, 0);
- bfd_put_packet(ofport->bfd, &packet, ofport->up.pp.hw_addr);
- ofproto_dpif_send_packet(ofport, &packet);
- ofpbuf_uninit(&packet);
- }
-}
-
static void
port_run(struct ofport_dpif *ofport)
{
ofport->carrier_seq = carrier_seq;
- port_run_fast(ofport);
-
if (ofport->cfm) {
int cfm_opup = cfm_get_opup(ofport->cfm);
- cfm_run(ofport->cfm);
cfm_enable = !cfm_get_fault(ofport->cfm);
if (cfm_opup >= 0) {
}
if (ofport->bfd) {
- bfd_run(ofport->bfd);
bfd_enable = bfd_forwarding(ofport->bfd);
}
ofport->may_enable = enable;
}
-static void
-port_wait(struct ofport_dpif *ofport)
-{
- if (ofport->cfm) {
- cfm_wait(ofport->cfm);
- }
-
- if (ofport->bfd) {
- bfd_wait(ofport->bfd);
- }
-}
-
static int
port_query_by_name(const struct ofproto *ofproto_, const char *devname,
struct ofproto_port *ofproto_port)
if (!error && ofport_->ofp_port == OFPP_LOCAL) {
struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofport->up.ofproto);
+ ovs_mutex_lock(&ofproto->stats_mutex);
/* ofproto->stats.tx_packets represents packets that we created
* internally and sent to some port (e.g. packets sent with
* ofproto_dpif_send_packet()). Account for them as if they had
if (stats->tx_bytes != UINT64_MAX) {
stats->tx_bytes += ofproto->stats.rx_bytes;
}
+ ovs_mutex_unlock(&ofproto->stats_mutex);
}
return error;
struct xlate_out xout;
struct xlate_in xin;
-
- struct rule_dpif *rule;
bool ok;
/* Check the datapath actions for consistency. */
- rule_dpif_lookup(facet->ofproto, &facet->flow, NULL, &rule);
- xlate_in_init(&xin, facet->ofproto, &facet->flow, rule, 0, NULL);
+ xlate_in_init(&xin, facet->ofproto, &facet->flow, NULL, 0, NULL);
xlate_actions(&xin, &xout);
- rule_dpif_unref(rule);
ok = ofpbuf_equal(&facet->xout.odp_actions, &xout.odp_actions)
&& facet->xout.slow == xout.slow;
struct dpif_flow_stats *stats, bool may_learn)
{
struct ofport_dpif *in_port;
- struct rule_dpif *rule;
struct xlate_in xin;
in_port = get_ofp_port(ofproto, flow->in_port.ofp_port);
netdev_vport_inc_rx(in_port->up.netdev, stats);
}
- rule_dpif_lookup(ofproto, flow, NULL, &rule);
- rule_dpif_credit_stats(rule, stats);
- xlate_in_init(&xin, ofproto, flow, rule, stats->tcp_flags, NULL);
+ xlate_in_init(&xin, ofproto, flow, NULL, stats->tcp_flags, NULL);
xin.resubmit_stats = stats;
xin.may_learn = may_learn;
xlate_actions_for_side_effects(&xin);
- rule_dpif_unref(rule);
}
static void
error = xlate_send_packet(ofport, packet);
+ ovs_mutex_lock(&ofproto->stats_mutex);
ofproto->stats.tx_packets++;
ofproto->stats.tx_bytes += packet->size;
+ ovs_mutex_unlock(&ofproto->stats_mutex);
return error;
}