#include "autopath.h"
#include "bond.h"
+#include "bundle.h"
#include "byte-order.h"
#include "connmgr.h"
#include "coverage.h"
/* Support for debugging async flow mods. */
struct list completions;
+
+ bool has_bundle_action; /* True when the first bundle action appears. */
};
/* Defer flow mod completion until "ovs-appctl ofproto/unclog"? (Useful only
ofproto_dpif_unixctl_init();
+ ofproto->has_bundle_action = false;
+
return 0;
}
port->bundle = NULL;
port->cfm = NULL;
port->tag = tag_create_random();
+ port->may_enable = true;
if (ofproto->sflow) {
dpif_sflow_add_port(ofproto->sflow, port->odp_port,
enable = enable && lacp_slave_may_enable(ofport->bundle->lacp, ofport);
}
+ if (ofport->may_enable != enable) {
+ struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofport->up.ofproto);
+
+ if (ofproto->has_bundle_action) {
+ ofproto->need_revalidate = true;
+ }
+ }
+
ofport->may_enable = enable;
}
base->nw_dst = flow->nw_dst;
}
+ if (base->nw_tos != flow->nw_tos) {
+ nl_msg_put_u8(odp_actions, ODP_ACTION_ATTR_SET_NW_TOS, flow->nw_tos);
+ base->nw_tos = flow->nw_tos;
+ }
+
if (base->vlan_tci != flow->vlan_tci) {
if (!(flow->vlan_tci & htons(VLAN_CFI))) {
nl_msg_put_flag(odp_actions, ODP_ACTION_ATTR_STRIP_VLAN);
autopath_execute(naa, &ctx->flow, ofp_port);
}
+static bool
+slave_enabled_cb(uint16_t ofp_port, void *ofproto_)
+{
+ struct ofproto_dpif *ofproto = ofproto_;
+ struct ofport_dpif *port;
+
+ switch (ofp_port) {
+ case OFPP_IN_PORT:
+ case OFPP_TABLE:
+ case OFPP_NORMAL:
+ case OFPP_FLOOD:
+ case OFPP_ALL:
+ case OFPP_LOCAL:
+ return true;
+ case OFPP_CONTROLLER: /* Not supported by the bundle action. */
+ return false;
+ default:
+ port = get_ofp_port(ofproto, ofp_port);
+ return port ? port->may_enable : false;
+ }
+}
+
static void
do_xlate_actions(const union ofp_action *in, size_t n_in,
struct action_xlate_ctx *ctx)
const struct nx_action_set_queue *nasq;
const struct nx_action_multipath *nam;
const struct nx_action_autopath *naa;
+ const struct nx_action_bundle *nab;
enum ofputil_action_code code;
ovs_be64 tun_id;
break;
case OFPUTIL_OFPAT_SET_NW_TOS:
- ctx->flow.nw_tos = ia->nw_tos.nw_tos;
+ ctx->flow.nw_tos = ia->nw_tos.nw_tos & IP_DSCP_MASK;
break;
case OFPUTIL_OFPAT_SET_TP_SRC:
naa = (const struct nx_action_autopath *) ia;
xlate_autopath(ctx, naa);
break;
+
+ case OFPUTIL_NXAST_BUNDLE:
+ ctx->ofproto->has_bundle_action = true;
+ nab = (const struct nx_action_bundle *) ia;
+ xlate_output_action__(ctx, bundle_execute(nab, &ctx->flow,
+ slave_enabled_cb,
+ ctx->ofproto), 0);
+ break;
+
+ case OFPUTIL_NXAST_BUNDLE_LOAD:
+ ctx->ofproto->has_bundle_action = true;
+ nab = (const struct nx_action_bundle *) ia;
+ bundle_execute_load(nab, &ctx->flow, slave_enabled_cb,
+ ctx->ofproto);
+ break;
}
}
}
static bool
ofbundle_trunks_vlan(const struct ofbundle *bundle, uint16_t vlan)
{
- return bundle->vlan < 0 && vlan_bitmap_contains(bundle->trunks, vlan);
+ return (bundle->vlan < 0
+ && (!bundle->trunks || bitmap_is_set(bundle->trunks, vlan)));
}
static bool
static bool
vlan_is_mirrored(const struct ofmirror *m, int vlan)
{
- return vlan_bitmap_contains(m->vlans, vlan);
+ return !m->vlans || bitmap_is_set(m->vlans, vlan);
}
/* Returns true if a packet with Ethernet destination MAC 'dst' may be mirrored