#include "ofproto/ofproto-dpif-xlate.h"
+#include "bfd.h"
#include "bitmap.h"
#include "bond.h"
#include "bundle.h"
#include "byte-order.h"
+#include "cfm.h"
#include "connmgr.h"
#include "coverage.h"
#include "dpif.h"
#include "dynamic-string.h"
+#include "lacp.h"
#include "learn.h"
#include "mac-learning.h"
#include "meta-flow.h"
ctx->sflow_odp_port, ctx->sflow_n_outputs, cookie);
}
+static enum slow_path_reason
+process_special(struct xlate_ctx *ctx, const struct flow *flow,
+ const struct ofport_dpif *ofport, const struct ofpbuf *packet)
+{
+ struct ofproto_dpif *ofproto = ctx->ofproto;
+ struct flow_wildcards *wc = &ctx->xout->wc;
+
+ if (!ofport) {
+ return 0;
+ } else if (ofport->cfm && cfm_should_process_flow(ofport->cfm, flow, wc)) {
+ if (packet) {
+ cfm_process_heartbeat(ofport->cfm, packet);
+ }
+ return SLOW_CFM;
+ } else if (ofport->bfd && bfd_should_process_flow(flow, wc)) {
+ if (packet) {
+ bfd_process_packet(ofport->bfd, flow, packet);
+ }
+ return SLOW_BFD;
+ } else if (ofport->bundle && ofport->bundle->lacp
+ && flow->dl_type == htons(ETH_TYPE_LACP)) {
+ if (packet) {
+ lacp_process_packet(ofport->bundle->lacp, ofport, packet);
+ }
+ return SLOW_LACP;
+ } else if (ofproto->stp && stp_should_process_flow(flow, wc)) {
+ if (packet) {
+ stp_process_packet(ofport, packet);
+ }
+ return SLOW_STP;
+ } else {
+ return 0;
+ }
+}
+
static void
compose_output_action__(struct xlate_ctx *ctx, uint16_t ofp_port,
bool check_stp)
memset(&flow->tunnel, 0, sizeof flow->tunnel);
memset(flow->regs, 0, sizeof flow->regs);
- special = process_special(ctx->ofproto, &ctx->xin->flow, peer,
+ special = process_special(ctx, &ctx->xin->flow, peer,
ctx->xin->packet);
if (special) {
ctx->xout->slow = special;
}
in_port = get_ofp_port(ctx.ofproto, flow->in_port);
- special = process_special(ctx.ofproto, flow, in_port, ctx.xin->packet);
+ special = process_special(&ctx, flow, in_port, ctx.xin->packet);
if (special) {
ctx.xout->slow = special;
} else {