+ atomic_read(&udpif->flow_limit, &flow_limit);
+ may_put = udpif_get_n_flows(udpif) < flow_limit;
+
+ /* Initialize each 'struct flow_miss's ->xout.
+ *
+ * We do this per-flow_miss rather than per-packet because, most commonly,
+ * all the packets in a flow can use the same translation.
+ *
+ * We can't do this in the previous loop because we need the TCP flags for
+ * all the packets in each miss. */
+ fail_open = false;
+ HMAP_FOR_EACH (miss, hmap_node, misses) {
+ struct xlate_in xin;
+
+ xlate_in_init(&xin, miss->ofproto, &miss->flow, NULL,
+ miss->stats.tcp_flags, NULL);
+ xin.may_learn = true;
+
+ if (miss->upcall_type == DPIF_UC_MISS) {
+ xin.resubmit_stats = &miss->stats;
+ } else {
+ /* For non-miss upcalls, there's a flow in the datapath which this
+ * packet was accounted to. Presumably the revalidators will deal
+ * with pushing its stats eventually. */
+ }
+
+ xlate_actions(&xin, &miss->xout);
+ fail_open = fail_open || miss->xout.fail_open;
+ }
+
+ /* Now handle the packets individually in order of arrival. In the common
+ * case each packet of a miss can share the same actions, but slow-pathed
+ * packets need to be translated individually:
+ *
+ * - For SLOW_CFM, SLOW_LACP, SLOW_STP, and SLOW_BFD, translation is what
+ * processes received packets for these protocols.
+ *
+ * - For SLOW_CONTROLLER, translation sends the packet to the OpenFlow
+ * controller.
+ *
+ * The loop fills 'ops' with an array of operations to execute in the
+ * datapath. */
+ n_ops = 0;
+ for (i = 0; i < n_upcalls; i++) {
+ struct upcall *upcall = &upcalls[i];
+ struct flow_miss *miss = upcall->flow_miss;
+ struct ofpbuf *packet = &upcall->dpif_upcall.packet;
+ struct dpif_op *op;
+ ovs_be16 flow_vlan_tci;
+
+ /* Save a copy of flow.vlan_tci in case it is changed to
+ * generate proper mega flow masks for VLAN splinter flows. */
+ flow_vlan_tci = miss->flow.vlan_tci;
+
+ if (miss->xout.slow) {
+ struct xlate_in xin;
+
+ xlate_in_init(&xin, miss->ofproto, &miss->flow, NULL, 0, packet);
+ xlate_actions_for_side_effects(&xin);
+ }
+
+ if (miss->flow.in_port.ofp_port
+ != vsp_realdev_to_vlandev(miss->ofproto,
+ miss->flow.in_port.ofp_port,
+ miss->flow.vlan_tci)) {
+ /* This packet was received on a VLAN splinter port. We
+ * added a VLAN to the packet to make the packet resemble
+ * the flow, but the actions were composed assuming that
+ * the packet contained no VLAN. So, we must remove the
+ * VLAN header from the packet before trying to execute the
+ * actions. */
+ if (ofpbuf_size(&miss->xout.odp_actions)) {
+ eth_pop_vlan(packet);
+ }
+
+ /* Remove the flow vlan tags inserted by vlan splinter logic
+ * to ensure megaflow masks generated match the data path flow. */
+ miss->flow.vlan_tci = 0;
+ }
+
+ /* Do not install a flow into the datapath if:
+ *
+ * - The datapath already has too many flows.
+ *
+ * - An earlier iteration of this loop already put the same flow.
+ *
+ * - We received this packet via some flow installed in the kernel
+ * already. */
+ if (may_put
+ && !miss->put
+ && upcall->dpif_upcall.type == DPIF_UC_MISS) {
+ struct ofpbuf mask;
+ bool megaflow;
+
+ miss->put = true;
+
+ atomic_read(&enable_megaflows, &megaflow);
+ ofpbuf_use_stack(&mask, &miss->mask_buf, sizeof miss->mask_buf);
+ if (megaflow) {
+ size_t max_mpls;
+
+ max_mpls = ofproto_dpif_get_max_mpls_depth(miss->ofproto);
+ odp_flow_key_from_mask(&mask, &miss->xout.wc.masks,
+ &miss->flow, UINT32_MAX, max_mpls);
+ }
+
+ op = &ops[n_ops++];
+ op->type = DPIF_OP_FLOW_PUT;
+ op->u.flow_put.flags = DPIF_FP_CREATE | DPIF_FP_MODIFY;
+ op->u.flow_put.key = miss->key;
+ op->u.flow_put.key_len = miss->key_len;
+ op->u.flow_put.mask = ofpbuf_data(&mask);
+ op->u.flow_put.mask_len = ofpbuf_size(&mask);
+ op->u.flow_put.stats = NULL;
+
+ if (!miss->xout.slow) {
+ op->u.flow_put.actions = ofpbuf_data(&miss->xout.odp_actions);
+ op->u.flow_put.actions_len = ofpbuf_size(&miss->xout.odp_actions);
+ } else {
+ struct ofpbuf buf;
+
+ ofpbuf_use_stack(&buf, miss->slow_path_buf,
+ sizeof miss->slow_path_buf);
+ compose_slow_path(udpif, &miss->xout, &miss->flow,
+ miss->odp_in_port, &buf);
+ op->u.flow_put.actions = ofpbuf_data(&buf);
+ op->u.flow_put.actions_len = ofpbuf_size(&buf);
+ }
+ }
+
+ /*
+ * The 'miss' may be shared by multiple upcalls. Restore
+ * the saved flow vlan_tci field before processing the next
+ * upcall. */
+ miss->flow.vlan_tci = flow_vlan_tci;
+
+ if (ofpbuf_size(&miss->xout.odp_actions)) {
+
+ op = &ops[n_ops++];
+ op->type = DPIF_OP_EXECUTE;
+ op->u.execute.packet = packet;
+ odp_key_to_pkt_metadata(miss->key, miss->key_len,
+ &op->u.execute.md);
+ op->u.execute.actions = ofpbuf_data(&miss->xout.odp_actions);
+ op->u.execute.actions_len = ofpbuf_size(&miss->xout.odp_actions);
+ op->u.execute.needs_help = (miss->xout.slow & SLOW_ACTION) != 0;
+ }
+ }
+
+ /* Special case for fail-open mode.
+ *
+ * If we are in fail-open mode, but we are connected to a controller too,
+ * then we should send the packet up to the controller in the hope that it
+ * will try to set up a flow and thereby allow us to exit fail-open.
+ *
+ * See the top-level comment in fail-open.c for more information.
+ *
+ * Copy packets before they are modified by execution. */
+ if (fail_open) {
+ for (i = 0; i < n_upcalls; i++) {
+ struct upcall *upcall = &upcalls[i];
+ struct flow_miss *miss = upcall->flow_miss;
+ struct ofpbuf *packet = &upcall->dpif_upcall.packet;
+ struct ofproto_packet_in *pin;
+
+ pin = xmalloc(sizeof *pin);
+ pin->up.packet = xmemdup(ofpbuf_data(packet), ofpbuf_size(packet));
+ pin->up.packet_len = ofpbuf_size(packet);
+ pin->up.reason = OFPR_NO_MATCH;
+ pin->up.table_id = 0;
+ pin->up.cookie = OVS_BE64_MAX;
+ flow_get_metadata(&miss->flow, &pin->up.fmd);
+ pin->send_len = 0; /* Not used for flow table misses. */
+ pin->miss_type = OFPROTO_PACKET_IN_NO_MISS;
+ ofproto_dpif_send_packet_in(miss->ofproto, pin);