示例#1
0
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;
    }
}
示例#2
0
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");
}
示例#3
0
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);
}