X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Flearning-switch.c;h=7a60f3c32adb92c5fe9fa0f044f66cc6629d8545;hb=8087f5ff825cae3a699e5a60ca6dd0deb10fc8e5;hp=f52d3c9d2d69b074c5141609f2e9004344b39ab6;hpb=f702893a7cc2380b2640e1ccb3a987d46766c685;p=openvswitch diff --git a/lib/learning-switch.c b/lib/learning-switch.c index f52d3c9d..7a60f3c3 100644 --- a/lib/learning-switch.c +++ b/lib/learning-switch.c @@ -112,6 +112,7 @@ struct lswitch * lswitch_create(struct rconn *rconn, const struct lswitch_config *cfg) { struct lswitch *sw; + uint32_t ofpfw; sw = xzalloc(sizeof *sw); sw->rconn = rconn; @@ -123,24 +124,26 @@ lswitch_create(struct rconn *rconn, const struct lswitch_config *cfg) : 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); @@ -532,7 +535,8 @@ process_packet_in(struct lswitch *sw, const struct ofp_header *oh) /* 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); @@ -572,7 +576,9 @@ process_packet_in(struct lswitch *sw, const struct ofp_header *oh) /* 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; @@ -586,13 +592,13 @@ process_packet_in(struct lswitch *sw, const struct ofp_header *oh) /* 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)); } } }