struct cfm *cfm; /* Connectivity Fault Management, if any. */
struct bfd *bfd; /* BFD, if any. */
struct lldp *lldp; /* lldp, if any. */
- bool may_enable; /* May be enabled in bonds. */
bool is_tunnel; /* This port is a tunnel. */
long long int carrier_seq; /* Carrier status changes. */
struct ofport_dpif *peer; /* Peer if patch port. */
ofport->rstp_port, ofport->qdscp,
ofport->n_qdscp, ofport->up.pp.config,
ofport->up.pp.state, ofport->is_tunnel,
- ofport->may_enable);
+ ofport->up.may_enable);
}
}
xlate_txn_commit();
port->cfm = NULL;
port->bfd = NULL;
port->lldp = NULL;
- port->may_enable = false;
port->stp_port = NULL;
port->stp_state = STP_DISABLED;
port->rstp_port = NULL;
bfd_set_netdev(port->bfd, netdev);
}
- /* Set liveness, unless the link is administratively or
- * operationally down or link monitoring false */
- if (!(port->up.pp.config & OFPUTIL_PC_PORT_DOWN) &&
- !(port->up.pp.state & OFPUTIL_PS_LINK_DOWN) &&
- port->may_enable) {
- port->up.pp.state |= OFPUTIL_PS_LIVE;
- } else {
- port->up.pp.state &= ~OFPUTIL_PS_LIVE;
- }
-
ofproto_dpif_monitor_port_update(port, port->bfd, port->cfm,
port->lldp, &port->up.pp.hw_addr);
bundle_update(port->bundle);
}
}
+ port_run(port);
}
static int
ofport, netdev_get_name(ofport->up.netdev));
update_rstp_port_state(ofport);
/* Synchronize operational status. */
- rstp_port_set_mac_operational(rp, ofport->may_enable);
+ rstp_port_set_mac_operational(rp, ofport->up.may_enable);
}
static void
struct ofport_dpif *port;
LIST_FOR_EACH (port, bundle_node, &bundle->ports) {
- bond_slave_set_may_enable(bundle->bond, port, port->may_enable);
+ bond_slave_set_may_enable(bundle->bond, port, port->up.may_enable);
}
if (bond_run(bundle->bond, lacp_status(bundle->lacp))) {
free(peer_name);
}
-static void
-port_run(struct ofport_dpif *ofport)
+static bool
+may_enable_port(struct ofport_dpif *ofport)
{
- long long int carrier_seq = netdev_get_carrier_resets(ofport->up.netdev);
- bool carrier_changed = carrier_seq != ofport->carrier_seq;
- bool enable = netdev_get_carrier(ofport->up.netdev);
- bool cfm_enable = false;
- bool bfd_enable = false;
-
- ofport->carrier_seq = carrier_seq;
-
- if (ofport->cfm) {
- int cfm_opup = cfm_get_opup(ofport->cfm);
-
- cfm_enable = !cfm_get_fault(ofport->cfm);
-
- if (cfm_opup >= 0) {
- cfm_enable = cfm_enable && cfm_opup;
- }
+ /* Carrier must be up. */
+ if (!netdev_get_carrier(ofport->up.netdev)) {
+ return false;
}
- if (ofport->bfd) {
- bfd_enable = bfd_forwarding(ofport->bfd);
+ /* If CFM or BFD is enabled, then at least one of them must report that the
+ * port is up. */
+ if ((ofport->bfd || ofport->cfm)
+ && !(ofport->cfm
+ && !cfm_get_fault(ofport->cfm)
+ && cfm_get_opup(ofport->cfm) != 0)
+ && !(ofport->bfd
+ && bfd_forwarding(ofport->bfd))) {
+ return false;
}
- if (ofport->bfd || ofport->cfm) {
- enable = enable && (cfm_enable || bfd_enable);
+ /* If LACP is enabled, it must report that the link is enabled. */
+ if (ofport->bundle
+ && !lacp_slave_may_enable(ofport->bundle->lacp, ofport)) {
+ return false;
}
- if (ofport->bundle) {
- enable = enable && lacp_slave_may_enable(ofport->bundle->lacp, ofport);
- if (carrier_changed) {
- lacp_slave_carrier_changed(ofport->bundle->lacp, ofport);
- }
+ return true;
+}
+
+static void
+port_run(struct ofport_dpif *ofport)
+{
+ long long int carrier_seq = netdev_get_carrier_resets(ofport->up.netdev);
+ bool carrier_changed = carrier_seq != ofport->carrier_seq;
+ ofport->carrier_seq = carrier_seq;
+ if (carrier_changed && ofport->bundle) {
+ lacp_slave_carrier_changed(ofport->bundle->lacp, ofport);
}
- if (ofport->may_enable != enable) {
- struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofport->up.ofproto);
+ bool enable = may_enable_port(ofport);
+ if (ofport->up.may_enable != enable) {
+ ofproto_port_set_enable(&ofport->up, enable);
+ struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofport->up.ofproto);
ofproto->backer->need_revalidate = REV_PORT_TOGGLED;
if (ofport->rstp_port) {
rstp_port_set_mac_operational(ofport->rstp_port, enable);
}
-
- /* Propagate liveness, unless the link is administratively or
- * operationally down. */
- if (!(ofport->up.pp.config & OFPUTIL_PC_PORT_DOWN) &&
- !(ofport->up.pp.state & OFPUTIL_PS_LINK_DOWN)) {
- enum ofputil_port_state of_state = ofport->up.pp.state;
- if (enable) {
- of_state |= OFPUTIL_PS_LIVE;
- } else {
- of_state &= ~OFPUTIL_PS_LIVE;
- }
- ofproto_port_set_state(&ofport->up, of_state);
- }
}
-
- ofport->may_enable = enable;
}
static int
odp_port_t port_no = ODPP_NONE;
int error = dpif_port_add(ofproto->backer->dpif, netdev, &port_no);
- if (error != EEXIST) {
+ if (error != EEXIST && error != EBUSY) {
if (error) {
return error;
}
const struct ofputil_packet_in_private *pin)
{
struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
+ struct dpif_flow_stats stats;
+ struct xlate_cache xcache;
+ struct flow flow;
+ xlate_cache_init(&xcache);
/* Translate pin into datapath actions. */
uint64_t odp_actions_stub[1024 / 8];
struct ofpbuf odp_actions = OFPBUF_STUB_INITIALIZER(odp_actions_stub);
enum slow_path_reason slow;
- enum ofperr error = xlate_resume(ofproto, pin, &odp_actions, &slow);
+ enum ofperr error = xlate_resume(ofproto, pin, &odp_actions, &slow,
+ &flow, &xcache);
/* Steal 'pin->packet' and put it into a dp_packet. */
struct dp_packet packet;
dp_packet_init(&packet, pin->base.packet_len);
dp_packet_put(&packet, pin->base.packet, pin->base.packet_len);
+ /* Run the side effects from the xcache. */
+ dpif_flow_stats_extract(&flow, &packet, time_msec(), &stats);
+ ovs_mutex_lock(&ofproto_mutex);
+ ofproto_dpif_xcache_execute(ofproto, &xcache, &stats);
+ ovs_mutex_unlock(&ofproto_mutex);
+
pkt_metadata_from_flow(&packet.md, &pin->base.flow_metadata.flow);
/* Fix up in_port. */
NULL);
unixctl_command_register("dpif/show-dp-features", "bridge", 1, 1,
ofproto_unixctl_dpif_show_dp_features, NULL);
- unixctl_command_register("dpif/dump-flows", "[-m] [--names | --no-nmaes] bridge", 1, INT_MAX,
+ unixctl_command_register("dpif/dump-flows",
+ "[-m] [--names | --no-names] bridge", 1, INT_MAX,
ofproto_unixctl_dpif_dump_flows, NULL);
unixctl_command_register("dpif/set-dp-features", "bridge", 1, 3 ,
ofproto_unixctl_dpif_set_dp_features, NULL);
}
}
- switch (dpif_meter_set(ofproto->backer->dpif, meter_id, config)) {
+ switch (dpif_meter_set(ofproto->backer->dpif, *meter_id, config)) {
case 0:
return 0;
case EFBIG: /* meter_id out of range */