- if (in_port == out_port) {
- /* Don't send out packets on their input ports. */
- goto drop_it;
- } else if (sw->max_idle >= 0 && (!sw->ml || out_port != OFPP_FLOOD)) {
+ /* Check if we need to use "NORMAL" action. */
+ if (sw->action_normal && out_port != OFPP_FLOOD) {
+ return OFPP_NORMAL;
+ }
+
+ return out_port;
+}
+
+static void
+process_packet_in(struct lswitch *sw, struct rconn *rconn, void *opi_)
+{
+ struct ofp_packet_in *opi = opi_;
+ uint16_t in_port = ntohs(opi->in_port);
+ uint16_t out_port;
+
+ size_t pkt_ofs, pkt_len;
+ struct ofpbuf pkt;
+ flow_t flow;
+
+ /* Extract flow data from 'opi' into 'flow'. */
+ pkt_ofs = offsetof(struct ofp_packet_in, data);
+ pkt_len = ntohs(opi->header.length) - pkt_ofs;
+ pkt.data = opi->data;
+ pkt.size = pkt_len;
+ flow_extract(&pkt, 0, in_port, &flow);
+
+ /* Choose output port. */
+ out_port = lswitch_choose_destination(sw, &flow);
+
+ /* Send the packet, and possibly the whole flow, to the output port. */
+ if (sw->max_idle >= 0 && (!sw->ml || out_port != OFPP_FLOOD)) {