void act_eth_dst(struct ofpbuf* buf, const uint8_t *dstMac, int flowHasVlan) { if (dstMac) { uint8_t mask[6]; memset(mask, 0xff, sizeof(mask)); struct ofpact_set_field *sf = ofpact_put_set_field(buf, mf_from_id(MFF_ETH_DST), dstMac, mask); sf->flow_has_vlan = flowHasVlan; } }
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"); }
void act_ip_dst_v6(struct ofpbuf* buf, uint8_t* addr) { uint8_t mask[16]; memset(mask, 0xff, sizeof(mask)); ofpact_put_set_field(buf, mf_from_id(MFF_IPV6_DST), addr, mask); }