}
bool
-bfd_should_process_flow(const struct flow *flow)
+bfd_should_process_flow(const struct flow *flow, struct flow_wildcards *wc)
{
+ memset(&wc->masks.dl_type, 0xff, sizeof wc->masks.dl_type);
+ memset(&wc->masks.nw_proto, 0xff, sizeof wc->masks.nw_proto);
+ memset(&wc->masks.tp_dst, 0xff, sizeof wc->masks.tp_dst);
return (flow->dl_type == htons(ETH_TYPE_IP)
&& flow->nw_proto == IPPROTO_UDP
&& flow->tp_dst == htons(3784));
struct bfd;
struct flow;
+struct flow_wildcards;
struct ofpbuf;
struct smap;
void bfd_put_packet(struct bfd *bfd, struct ofpbuf *packet,
uint8_t eth_src[6]);
-bool bfd_should_process_flow(const struct flow *);
+bool bfd_should_process_flow(const struct flow *, struct flow_wildcards *);
void bfd_process_packet(struct bfd *, const struct flow *,
const struct ofpbuf *);
}
}
-/* Returns true if 'cfm' should process packets from 'flow'. */
+/* Returns true if 'cfm' should process packets from 'flow'. Sets
+ * fields in 'wc' that were used to make the determination. */
bool
-cfm_should_process_flow(const struct cfm *cfm, const struct flow *flow)
+cfm_should_process_flow(const struct cfm *cfm, const struct flow *flow,
+ struct flow_wildcards *wc)
{
+ memset(&wc->masks.dl_dst, 0xff, sizeof wc->masks.dl_dst);
+ memset(&wc->masks.dl_type, 0xff, sizeof wc->masks.dl_type);
+ if (cfm->check_tnl_key) {
+ memset(&wc->masks.tunnel.tun_id, 0xff, sizeof wc->masks.tunnel.tun_id);
+ }
return (ntohs(flow->dl_type) == ETH_TYPE_CFM
&& eth_addr_equals(flow->dl_dst, cfm_ccm_addr(cfm))
&& (!cfm->check_tnl_key || flow->tunnel.tun_id == htonll(0)));
struct flow;
struct ofpbuf;
struct netdev;
+struct flow_wildcards;
#define CFM_RANDOM_VLAN UINT16_MAX
void cfm_wait(struct cfm *);
bool cfm_configure(struct cfm *, const struct cfm_settings *);
void cfm_set_netdev(struct cfm *, const struct netdev *);
-bool cfm_should_process_flow(const struct cfm *cfm, const struct flow *);
+bool cfm_should_process_flow(const struct cfm *cfm, const struct flow *,
+ struct flow_wildcards *);
void cfm_process_heartbeat(struct cfm *, const struct ofpbuf *packet);
int cfm_get_fault(const struct cfm *);
int cfm_get_health(const struct cfm *);
}
static enum slow_path_reason
-process_special(struct ofproto_dpif *ofproto, const struct flow *flow,
+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)) {
+ } 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)) {
+ } else if (ofport->bfd && bfd_should_process_flow(flow, wc)) {
if (packet) {
bfd_process_packet(ofport->bfd, flow, packet);
}
lacp_process_packet(ofport->bundle->lacp, ofport, packet);
}
return SLOW_LACP;
- } else if (ofproto->stp && stp_should_process_flow(flow)) {
+ } else if (ofproto->stp && stp_should_process_flow(flow, wc)) {
if (packet) {
stp_process_packet(ofport, packet);
}
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 {
}
}
-/* Returns true if STP should process 'flow'. */
+/* Returns true if STP should process 'flow'. Sets fields in 'wc' that
+ * were used to make the determination.*/
bool
-stp_should_process_flow(const struct flow *flow)
+stp_should_process_flow(const struct flow *flow, struct flow_wildcards *wc)
{
+ memset(&wc->masks.dl_dst, 0xff, sizeof wc->masks.dl_dst);
return eth_addr_equals(flow->dl_dst, eth_addr_stp);
}
const union user_action_cookie *,
const size_t cookie_size);
-bool stp_should_process_flow(const struct flow *);
+bool stp_should_process_flow(const struct flow *, struct flow_wildcards *);
void stp_process_packet(const struct ofport_dpif *,
const struct ofpbuf *packet);