void ofputil_encode_bundle_msgs(const struct ofputil_bundle_msg *bms, size_t n_bms, struct ovs_list *requests, enum ofputil_protocol protocol) { enum ofp_version version = ofputil_protocol_to_ofp_version(protocol); for (size_t i = 0; i < n_bms; i++) { struct ofpbuf *request = NULL; switch ((int)bms[i].type) { case OFPTYPE_FLOW_MOD: request = ofputil_encode_flow_mod(&bms[i].fm, protocol); break; case OFPTYPE_GROUP_MOD: request = ofputil_encode_group_mod(version, &bms[i].gm, NULL, -1); break; case OFPTYPE_PACKET_OUT: request = ofputil_encode_packet_out(&bms[i].po, protocol); break; default: break; } if (request) { ovs_list_push_back(requests, &request->list_node); } } }
static void process_packet_in(struct lswitch *sw, const struct ofp_header *oh) { struct ofputil_packet_in pi; uint32_t buffer_id; uint64_t ofpacts_stub[64]; struct ofpbuf ofpacts; struct ofputil_packet_out po; enum ofperr error; uint8_t icmp_packet[128]; const struct mf_field *mf; const struct mf_field *mf_id; union mf_value sf_value, sf_mask; union mf_value sf_value_id, sf_mask_id; error = ofputil_decode_packet_in(oh, true, &pi, NULL, &buffer_id, NULL); if (error) { VLOG_WARN_RL(&rl, "failed to decode packet-in: %s", ofperr_to_string(error)); return; } /* Ignore packets sent via output to OFPP_CONTROLLER. This library never * uses such an action. You never know what experiments might be going on, * though, and it seems best not to interfere with them. */ if (pi.reason != OFPR_ACTION || buffer_id != UINT32_MAX) { return; } struct ethhdr *old_pkt = pi.packet; struct iphdr * old_ipv4 = (struct iphdr*)(old_pkt + 1); uint16_t old_tot_len = ntohs(old_ipv4->tot_len); uint8_t header_len = old_ipv4->ihl*4; if (pi.packet_len < header_len + sizeof(struct ethhdr) + 8 || old_tot_len < header_len + 8) return; if (old_pkt->h_proto != htons(ETH_P_IP)) return; //VLOG_INFO("AFTER MATCH"); uint32_t icmp_packet_len = sizeof(struct ethhdr) + sizeof(struct iphdr) + header_len + sizeof(struct icmphdr) + 8; icmp_unexpect_ttl(icmp_packet, &pi, header_len, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0); ofpbuf_use_stack(&ofpacts, ofpacts_stub, sizeof ofpacts_stub); mf_id = mf_from_name("tun_id"); if (!mf_id) return; sf_value_id.be64 = pi.flow_metadata.flow.tunnel.tun_id; sf_mask_id.be64 = OVS_BE64_MAX; ofpact_put_set_field(&ofpacts, mf_id, &sf_value_id, &sf_mask_id); mf = mf_from_name("tun_dst"); if (!mf) return; sf_value.be32 = pi.flow_metadata.flow.tunnel.ip_src; sf_mask.be32 = OVS_BE32_MAX; ofpact_put_set_field(&ofpacts, mf, &sf_value, &sf_mask); ofpact_put_OUTPUT(&ofpacts)->port = OFPP_IN_PORT; /* Prepare packet_out in case we need one. */ po.buffer_id = buffer_id; po.packet = icmp_packet; po.packet_len = icmp_packet_len; po.in_port = pi.flow_metadata.flow.in_port.ofp_port; po.ofpacts = ofpacts.data; po.ofpacts_len = ofpacts.size; queue_tx(sw, ofputil_encode_packet_out(&po, sw->protocol)); //VLOG_INFO("AFTER MATCH last"); }