lswitch_create(struct rconn *rconn, const struct lswitch_config *cfg)
{
struct lswitch *sw;
+ uint32_t ofpfw;
sw = xzalloc(sizeof *sw);
sw->rconn = rconn;
: NULL);
sw->action_normal = cfg->mode == LSW_NORMAL;
- flow_wildcards_init_exact(&sw->wc);
- if (cfg->wildcards) {
- uint32_t ofpfw;
-
- if (cfg->wildcards == UINT32_MAX) {
- /* Try to wildcard as many fields as possible, but we cannot
- * wildcard all fields. We need in_port to detect moves. We need
- * Ethernet source and dest and VLAN VID to do L2 learning. */
- ofpfw = (OFPFW10_DL_TYPE | OFPFW10_DL_VLAN_PCP
- | OFPFW10_NW_SRC_ALL | OFPFW10_NW_DST_ALL
- | OFPFW10_NW_TOS | OFPFW10_NW_PROTO
- | OFPFW10_TP_SRC | OFPFW10_TP_DST);
- } else {
- ofpfw = cfg->wildcards;
- }
+ switch (cfg->wildcards) {
+ case 0:
+ ofpfw = 0;
+ break;
- ofputil_wildcard_from_ofpfw10(ofpfw, &sw->wc);
+ case UINT32_MAX:
+ /* Try to wildcard as many fields as possible, but we cannot
+ * wildcard all fields. We need in_port to detect moves. We need
+ * Ethernet source and dest and VLAN VID to do L2 learning. */
+ ofpfw = (OFPFW10_DL_TYPE | OFPFW10_DL_VLAN_PCP
+ | OFPFW10_NW_SRC_ALL | OFPFW10_NW_DST_ALL
+ | OFPFW10_NW_TOS | OFPFW10_NW_PROTO
+ | OFPFW10_TP_SRC | OFPFW10_TP_DST);
+ break;
+
+ default:
+ ofpfw = cfg->wildcards;
+ break;
}
+ ofputil_wildcard_from_ofpfw10(ofpfw, &sw->wc);
sw->default_queue = cfg->default_queue;
hmap_init(&sw->queue_numbers);
/* Extract flow data from 'opi' into 'flow'. */
ofpbuf_use_const(&pkt, pi.packet, pi.packet_len);
- flow_extract(&pkt, 0, pi.fmd.tun_id, pi.fmd.in_port, &flow);
+ flow_extract(&pkt, 0, NULL, pi.fmd.in_port, &flow);
+ flow.tunnel.tun_id = pi.fmd.tun_id;
/* Choose output port. */
out_port = lswitch_choose_destination(sw, &flow);
/* The output port is known, or we always flood everything, so add a
* new flow. */
memset(&fm, 0, sizeof fm);
- cls_rule_init(&flow, &sw->wc, 0, &fm.cr);
+ match_init(&fm.match, &flow, &sw->wc);
+ ofputil_normalize_match_quiet(&fm.match);
+ fm.priority = 0;
fm.table_id = 0xff;
fm.command = OFPFC_ADD;
fm.idle_timeout = sw->max_idle;
/* If the switch didn't buffer the packet, we need to send a copy. */
if (pi.buffer_id == UINT32_MAX && out_port != OFPP_NONE) {
- queue_tx(sw, ofputil_encode_packet_out(&po));
+ queue_tx(sw, ofputil_encode_packet_out(&po, sw->protocol));
}
} else {
/* We don't know that MAC, or we don't set up flows. Send along the
* packet without setting up a flow. */
if (pi.buffer_id != UINT32_MAX || out_port != OFPP_NONE) {
- queue_tx(sw, ofputil_encode_packet_out(&po));
+ queue_tx(sw, ofputil_encode_packet_out(&po, sw->protocol));
}
}
}