コード例 #1
0
ファイル: dp-packet.c プロジェクト: hisaki/ovs
/* Returns a string that describes some of 'b''s metadata plus a hex dump of up
 * to 'maxbytes' from the start of the buffer. */
char *
dp_packet_to_string(const struct dp_packet *b, size_t maxbytes)
{
    struct ds s;

    ds_init(&s);
    ds_put_format(&s, "size=%"PRIu32", allocated=%"PRIu32", head=%"PRIuSIZE", tail=%"PRIuSIZE"\n",
                  dp_packet_size(b), b->allocated,
                  dp_packet_headroom(b), dp_packet_tailroom(b));
    ds_put_hex_dump(&s, dp_packet_data(b), MIN(dp_packet_size(b), maxbytes), 0, false);
    return ds_cstr(&s);
}
コード例 #2
0
ファイル: dp-packet.c プロジェクト: joestringer/openvswitch
/* Creates and returns a new dp_packet whose data are copied from 'buffer'.   The
 * returned dp_packet will additionally have 'headroom' bytes of headroom. */
struct dp_packet *
dp_packet_clone_with_headroom(const struct dp_packet *buffer, size_t headroom)
{
    struct dp_packet *new_buffer;

    new_buffer = dp_packet_clone_data_with_headroom(dp_packet_data(buffer),
                                                 dp_packet_size(buffer),
                                                 headroom);
    new_buffer->l2_pad_size = buffer->l2_pad_size;
    new_buffer->l2_5_ofs = buffer->l2_5_ofs;
    new_buffer->l3_ofs = buffer->l3_ofs;
    new_buffer->l4_ofs = buffer->l4_ofs;
    new_buffer->md = buffer->md;
    new_buffer->cutlen = buffer->cutlen;
    new_buffer->packet_type = buffer->packet_type;
#ifdef DPDK_NETDEV
    new_buffer->mbuf.ol_flags = buffer->mbuf.ol_flags;
#else
    new_buffer->rss_hash_valid = buffer->rss_hash_valid;
#endif

    if (dp_packet_rss_valid(new_buffer)) {
#ifdef DPDK_NETDEV
        new_buffer->mbuf.hash.rss = buffer->mbuf.hash.rss;
#else
        new_buffer->rss_hash = buffer->rss_hash;
#endif
    }

    return new_buffer;
}
コード例 #3
0
ファイル: dp-packet.c プロジェクト: joestringer/openvswitch
/* Reserves 'size' bytes of headroom so that they can be later allocated with
 * dp_packet_push_uninit() without reallocating the dp_packet. */
void
dp_packet_reserve(struct dp_packet *b, size_t size)
{
    ovs_assert(!dp_packet_size(b));
    dp_packet_prealloc_tailroom(b, size);
    dp_packet_set_data(b, (char*)dp_packet_data(b) + size);
}
コード例 #4
0
ファイル: dp-packet.c プロジェクト: joestringer/openvswitch
/* Reserves 'headroom' bytes at the head and 'tailroom' at the end so that
 * they can be later allocated with dp_packet_push_uninit() or
 * dp_packet_put_uninit() without reallocating the dp_packet. */
void
dp_packet_reserve_with_tailroom(struct dp_packet *b, size_t headroom,
                             size_t tailroom)
{
    ovs_assert(!dp_packet_size(b));
    dp_packet_prealloc_tailroom(b, headroom + tailroom);
    dp_packet_set_data(b, (char*)dp_packet_data(b) + headroom);
}
コード例 #5
0
ファイル: dp-packet.c プロジェクト: joestringer/openvswitch
/* Prefixes 'size' bytes to the head end of 'b', reallocating and copying its
 * data if necessary.  Returns a pointer to the first byte of the data's
 * location in the dp_packet.  The new data is left uninitialized. */
void *
dp_packet_push_uninit(struct dp_packet *b, size_t size)
{
    dp_packet_prealloc_headroom(b, size);
    dp_packet_set_data(b, (char*)dp_packet_data(b) - size);
    dp_packet_set_size(b, dp_packet_size(b) + size);
    return dp_packet_data(b);
}
コード例 #6
0
ファイル: dp-packet.c プロジェクト: joestringer/openvswitch
/* Appends 'size' bytes of data to the tail end of 'b', reallocating and
 * copying its data if necessary.  Returns a pointer to the first byte of the
 * new data, which is left uninitialized. */
void *
dp_packet_put_uninit(struct dp_packet *b, size_t size)
{
    void *p;
    dp_packet_prealloc_tailroom(b, size);
    p = dp_packet_tail(b);
    dp_packet_set_size(b, dp_packet_size(b) + size);
    return p;
}
コード例 #7
0
ファイル: ipf.c プロジェクト: openvswitch/ovs
/* Called on a sorted complete list of v6 fragments to reassemble them into
 * a single packet that can be processed, such as passing through conntrack.
 */
static struct dp_packet *
ipf_reassemble_v6_frags(struct ipf_list *ipf_list)
    /* OVS_REQUIRES(ipf_lock) */
{
    struct ipf_frag *frag_list = ipf_list->frag_list;
    struct dp_packet *pkt = dp_packet_clone(frag_list[0].pkt);
    dp_packet_set_size(pkt, dp_packet_size(pkt) - dp_packet_l2_pad_size(pkt));
    struct  ovs_16aligned_ip6_hdr *l3 = dp_packet_l3(pkt);
    int pl = ntohs(l3->ip6_plen) - sizeof(struct ovs_16aligned_ip6_frag);

    int rest_len = frag_list[ipf_list->last_inuse_idx].end_data_byte -
                   frag_list[1].start_data_byte + 1;

    if (pl + rest_len > IPV6_PACKET_MAX_DATA) {
        ipf_print_reass_packet(
             "Unsupported big reassembled v6 packet; v6 hdr:", l3);
        dp_packet_delete(pkt);
        return NULL;
    }

    dp_packet_prealloc_tailroom(pkt, rest_len);

    for (int i = 1; i <= ipf_list->last_inuse_idx; i++) {
        size_t add_len = frag_list[i].end_data_byte -
                          frag_list[i].start_data_byte + 1;
        const char *l4 = dp_packet_l4(frag_list[i].pkt);
        dp_packet_put(pkt, l4, add_len);
    }

    pl += rest_len;
    l3 = dp_packet_l3(pkt);

    uint8_t nw_proto = l3->ip6_nxt;
    uint8_t nw_frag = 0;
    const void *data = l3 + 1;
    size_t datasize = pl;

    const struct ovs_16aligned_ip6_frag *frag_hdr = NULL;
    if (!parse_ipv6_ext_hdrs(&data, &datasize, &nw_proto, &nw_frag, &frag_hdr)
        || !nw_frag || !frag_hdr) {

        ipf_print_reass_packet("Unparsed reassembled v6 packet; v6 hdr:", l3);
        dp_packet_delete(pkt);
        return NULL;
    }

    struct ovs_16aligned_ip6_frag *fh =
        CONST_CAST(struct ovs_16aligned_ip6_frag *, frag_hdr);
    fh->ip6f_offlg = 0;
    l3->ip6_plen = htons(pl);
    l3->ip6_ctlun.ip6_un1.ip6_un1_nxt = nw_proto;
    dp_packet_set_l2_pad_size(pkt, 0);
    return pkt;
}
コード例 #8
0
ファイル: dp-packet.c プロジェクト: joestringer/openvswitch
/* Parses as many pairs of hex digits as possible (possibly separated by
 * spaces) from the beginning of 's', appending bytes for their values to 'b'.
 * Returns the first character of 's' that is not the first of a pair of hex
 * digits.  If 'n' is nonnull, stores the number of bytes added to 'b' in
 * '*n'. */
char *
dp_packet_put_hex(struct dp_packet *b, const char *s, size_t *n)
{
    size_t initial_size = dp_packet_size(b);
    for (;;) {
        uint8_t byte;
        bool ok;

        s += strspn(s, " \t\r\n");
        byte = hexits_value(s, 2, &ok);
        if (!ok) {
            if (n) {
                *n = dp_packet_size(b) - initial_size;
            }
            return CONST_CAST(char *, s);
        }

        dp_packet_put(b, &byte, 1);
        s += 2;
    }
}
コード例 #9
0
ファイル: dp-packet.c プロジェクト: joestringer/openvswitch
/* Shifts all of the data within the allocated space in 'b' by 'delta' bytes.
 * For example, a 'delta' of 1 would cause each byte of data to move one byte
 * forward (from address 'p' to 'p+1'), and a 'delta' of -1 would cause each
 * byte to move one byte backward (from 'p' to 'p-1'). */
void
dp_packet_shift(struct dp_packet *b, int delta)
{
    ovs_assert(delta > 0 ? delta <= dp_packet_tailroom(b)
               : delta < 0 ? -delta <= dp_packet_headroom(b)
               : true);

    if (delta != 0) {
        char *dst = (char *) dp_packet_data(b) + delta;
        memmove(dst, dp_packet_data(b), dp_packet_size(b));
        dp_packet_set_data(b, dst);
    }
}
コード例 #10
0
ファイル: dp-packet.c プロジェクト: joestringer/openvswitch
static void
dp_packet_copy__(struct dp_packet *b, uint8_t *new_base,
              size_t new_headroom, size_t new_tailroom)
{
    const uint8_t *old_base = dp_packet_base(b);
    size_t old_headroom = dp_packet_headroom(b);
    size_t old_tailroom = dp_packet_tailroom(b);
    size_t copy_headroom = MIN(old_headroom, new_headroom);
    size_t copy_tailroom = MIN(old_tailroom, new_tailroom);

    memcpy(&new_base[new_headroom - copy_headroom],
           &old_base[old_headroom - copy_headroom],
           copy_headroom + dp_packet_size(b) + copy_tailroom);
}
コード例 #11
0
ファイル: dp-packet.c プロジェクト: hisaki/ovs
/* Reallocates 'b' so that it has exactly 'new_headroom' and 'new_tailroom'
 * bytes of headroom and tailroom, respectively. */
static void
dp_packet_resize__(struct dp_packet *b, size_t new_headroom, size_t new_tailroom)
{
    void *new_base, *new_data;
    size_t new_allocated;

    new_allocated = new_headroom + dp_packet_size(b) + new_tailroom;

    switch (b->source) {
    case DPBUF_DPDK:
        OVS_NOT_REACHED();

    case DPBUF_MALLOC:
        if (new_headroom == dp_packet_headroom(b)) {
            new_base = xrealloc(dp_packet_base(b), new_allocated);
        } else {
            new_base = xmalloc(new_allocated);
            dp_packet_copy__(b, new_base, new_headroom, new_tailroom);
            free(dp_packet_base(b));
        }
        break;

    case DPBUF_STACK:
        OVS_NOT_REACHED();

    case DPBUF_STUB:
        b->source = DPBUF_MALLOC;
        new_base = xmalloc(new_allocated);
        dp_packet_copy__(b, new_base, new_headroom, new_tailroom);
        break;

    default:
        OVS_NOT_REACHED();
    }

    b->allocated = new_allocated;
    dp_packet_set_base(b, new_base);

    new_data = (char *) new_base + new_headroom;
    if (dp_packet_data(b) != new_data) {
        if (b->frame) {
            uintptr_t data_delta = (char *) new_data - (char *) dp_packet_data(b);

            b->frame = (char *) b->frame + data_delta;
        }
        dp_packet_set_data(b, new_data);
    }
}
コード例 #12
0
ファイル: dp-packet.c プロジェクト: AlexanderFroemmgen/ovs
/* Creates and returns a new dp_packet whose data are copied from 'buffer'.   The
 * returned dp_packet will additionally have 'headroom' bytes of headroom. */
struct dp_packet *
dp_packet_clone_with_headroom(const struct dp_packet *buffer, size_t headroom)
{
    struct dp_packet *new_buffer;

    new_buffer = dp_packet_clone_data_with_headroom(dp_packet_data(buffer),
                                                 dp_packet_size(buffer),
                                                 headroom);
    new_buffer->l2_pad_size = buffer->l2_pad_size;
    new_buffer->l2_5_ofs = buffer->l2_5_ofs;
    new_buffer->l3_ofs = buffer->l3_ofs;
    new_buffer->l4_ofs = buffer->l4_ofs;
    new_buffer->md = buffer->md;

    return new_buffer;
}
コード例 #13
0
ファイル: dp-packet.c プロジェクト: joestringer/openvswitch
/* Returns the data in 'b' as a block of malloc()'d memory and frees the buffer
 * within 'b'.  (If 'b' itself was dynamically allocated, e.g. with
 * dp_packet_new(), then it should still be freed with, e.g., dp_packet_delete().) */
void *
dp_packet_steal_data(struct dp_packet *b)
{
    void *p;
    ovs_assert(b->source != DPBUF_DPDK);

    if (b->source == DPBUF_MALLOC && dp_packet_data(b) == dp_packet_base(b)) {
        p = dp_packet_data(b);
    } else {
        p = xmemdup(dp_packet_data(b), dp_packet_size(b));
        if (b->source == DPBUF_MALLOC) {
            free(dp_packet_base(b));
        }
    }
    dp_packet_set_base(b, NULL);
    dp_packet_set_data(b, NULL);
    return p;
}
コード例 #14
0
ファイル: ipf.c プロジェクト: openvswitch/ovs
/* Called on a sorted complete list of v4 fragments to reassemble them into
 * a single packet that can be processed, such as passing through conntrack.
 */
static struct dp_packet *
ipf_reassemble_v4_frags(struct ipf_list *ipf_list)
    /* OVS_REQUIRES(ipf_lock) */
{
    struct ipf_frag *frag_list = ipf_list->frag_list;
    struct dp_packet *pkt = dp_packet_clone(frag_list[0].pkt);
    dp_packet_set_size(pkt, dp_packet_size(pkt) - dp_packet_l2_pad_size(pkt));
    struct ip_header *l3 = dp_packet_l3(pkt);
    int len = ntohs(l3->ip_tot_len);

    int rest_len = frag_list[ipf_list->last_inuse_idx].end_data_byte -
                   frag_list[1].start_data_byte + 1;

    if (len + rest_len > IPV4_PACKET_MAX_SIZE) {
        ipf_print_reass_packet(
            "Unsupported big reassembled v4 packet; v4 hdr:", l3);
        dp_packet_delete(pkt);
        return NULL;
    }

    dp_packet_prealloc_tailroom(pkt, rest_len);

    for (int i = 1; i <= ipf_list->last_inuse_idx; i++) {
        size_t add_len = frag_list[i].end_data_byte -
                         frag_list[i].start_data_byte + 1;
        const char *l4 = dp_packet_l4(frag_list[i].pkt);
        dp_packet_put(pkt, l4, add_len);
    }

    len += rest_len;
    l3 = dp_packet_l3(pkt);
    ovs_be16 new_ip_frag_off = l3->ip_frag_off & ~htons(IP_MORE_FRAGMENTS);
    l3->ip_csum = recalc_csum16(l3->ip_csum, l3->ip_frag_off,
                                new_ip_frag_off);
    l3->ip_csum = recalc_csum16(l3->ip_csum, l3->ip_tot_len, htons(len));
    l3->ip_tot_len = htons(len);
    l3->ip_frag_off = new_ip_frag_off;
    dp_packet_set_l2_pad_size(pkt, 0);

    return pkt;
}
コード例 #15
0
ファイル: dp-packet.c プロジェクト: hisaki/ovs
/* Creates and returns a new dp_packet whose data are copied from 'buffer'.   The
 * returned dp_packet will additionally have 'headroom' bytes of headroom. */
struct dp_packet *
dp_packet_clone_with_headroom(const struct dp_packet *buffer, size_t headroom)
{
    struct dp_packet *new_buffer;

    new_buffer = dp_packet_clone_data_with_headroom(dp_packet_data(buffer),
                                                 dp_packet_size(buffer),
                                                 headroom);
    if (buffer->frame) {
        uintptr_t data_delta
            = (char *)dp_packet_data(new_buffer) - (char *)dp_packet_data(buffer);

        new_buffer->frame = (char *) buffer->frame + data_delta;
    }
    new_buffer->l2_pad_size = buffer->l2_pad_size;
    new_buffer->l2_5_ofs = buffer->l2_5_ofs;
    new_buffer->l3_ofs = buffer->l3_ofs;
    new_buffer->l4_ofs = buffer->l4_ofs;
    new_buffer->md = buffer->md;

    return new_buffer;
}
コード例 #16
0
ファイル: lldp.c プロジェクト: AlexanderFroemmgen/ovs
static void
lldp_tlv_start(struct dp_packet *p, uint8_t tlv, unsigned int *start)
{
    *start = dp_packet_size(p);
    lldp_tlv_put_u16(p, tlv << 9);
}
コード例 #17
0
ファイル: lldp.c プロジェクト: AlexanderFroemmgen/ovs
    lldp_tlv_put_u16(p, tlv << 9);
}

static void
lldp_tlv_end(struct dp_packet *p, unsigned int start)
{
    ovs_be16 *tlv = dp_packet_at_assert(p, start, 2);
    *tlv |= htons((dp_packet_size(p) - (start + 2)) & 0x1ff);
}

int
lldp_send(struct lldpd *global OVS_UNUSED,
          struct lldpd_hardware *hardware,
          struct dp_packet *p)
{
    unsigned int orig_size = dp_packet_size(p);
    unsigned int start;

    struct lldpd_port *port;
    struct lldpd_chassis *chassis;
    struct lldpd_mgmt *mgmt;
    const uint8_t avaya[] = LLDP_TLV_ORG_AVAYA;
    struct lldpd_aa_isid_vlan_maps_tlv *vlan_isid_map;
    uint8_t msg_auth_digest[LLDP_TLV_AA_ISID_VLAN_DIGEST_LENGTH];

    port = &hardware->h_lport;
    chassis = port->p_chassis;

    /* The ethernet header is filled in elsewhere, we must save room for it. */
    VLOG_DBG("LLDP PDU send to %s mtu %d incoming",
              hardware->h_ifname, hardware->h_mtu);
コード例 #18
0
ファイル: lldp.c プロジェクト: AlexanderFroemmgen/ovs
static void
lldp_tlv_end(struct dp_packet *p, unsigned int start)
{
    ovs_be16 *tlv = dp_packet_at_assert(p, start, 2);
    *tlv |= htons((dp_packet_size(p) - (start + 2)) & 0x1ff);
}
コード例 #19
0
ファイル: expr_parse_target.c プロジェクト: blp/ovs-reviews
static void
test_parse_actions(const char *input)
{
    struct shash symtab;
    struct hmap dhcp_opts;
    struct hmap dhcpv6_opts;
    struct hmap nd_ra_opts;
    struct simap ports;

    create_symtab(&symtab);
    create_gen_opts(&dhcp_opts, &dhcpv6_opts, &nd_ra_opts);

    /* Initialize group ids. */
    struct ovn_extend_table group_table;
    ovn_extend_table_init(&group_table);

    /* Initialize meter ids for QoS. */
    struct ovn_extend_table meter_table;
    ovn_extend_table_init(&meter_table);

    simap_init(&ports);
    simap_put(&ports, "eth0", 5);
    simap_put(&ports, "eth1", 6);
    simap_put(&ports, "LOCAL", ofp_to_u16(OFPP_LOCAL));

    struct ofpbuf ovnacts;
    struct expr *prereqs;
    char *error;

    puts(input);

    ofpbuf_init(&ovnacts, 0);

    const struct ovnact_parse_params pp = {
        .symtab = &symtab,
        .dhcp_opts = &dhcp_opts,
        .dhcpv6_opts = &dhcpv6_opts,
        .nd_ra_opts = &nd_ra_opts,
        .n_tables = 24,
        .cur_ltable = 10,
    };
    error = ovnacts_parse_string(input, &pp, &ovnacts, &prereqs);
    if (!error) {
        /* Convert the parsed representation back to a string and print it,
         * if it's different from the input. */
        struct ds ovnacts_s = DS_EMPTY_INITIALIZER;
        ovnacts_format(ovnacts.data, ovnacts.size, &ovnacts_s);
        if (strcmp(input, ds_cstr(&ovnacts_s))) {
            printf("    formats as %s\n", ds_cstr(&ovnacts_s));
        }

        /* Encode the actions into OpenFlow and print. */
        const struct ovnact_encode_params ep = {
            .lookup_port = lookup_port_cb,
            .aux = &ports,
            .is_switch = true,
            .group_table = &group_table,
            .meter_table = &meter_table,

            .pipeline = OVNACT_P_INGRESS,
            .ingress_ptable = 8,
            .egress_ptable = 40,
            .output_ptable = 64,
            .mac_bind_ptable = 65,
        };
        struct ofpbuf ofpacts;
        ofpbuf_init(&ofpacts, 0);
        ovnacts_encode(ovnacts.data, ovnacts.size, &ep, &ofpacts);
        struct ds ofpacts_s = DS_EMPTY_INITIALIZER;
        struct ofpact_format_params fp = { .s = &ofpacts_s };
        ofpacts_format(ofpacts.data, ofpacts.size, &fp);
        printf("    encodes as %s\n", ds_cstr(&ofpacts_s));
        ds_destroy(&ofpacts_s);
        ofpbuf_uninit(&ofpacts);

        /* Print prerequisites if any. */
        if (prereqs) {
            struct ds prereqs_s = DS_EMPTY_INITIALIZER;
            expr_format(prereqs, &prereqs_s);
            printf("    has prereqs %s\n", ds_cstr(&prereqs_s));
            ds_destroy(&prereqs_s);
        }

        /* Now re-parse and re-format the string to verify that it's
         * round-trippable. */
        struct ofpbuf ovnacts2;
        struct expr *prereqs2;
        ofpbuf_init(&ovnacts2, 0);
        error = ovnacts_parse_string(ds_cstr(&ovnacts_s), &pp, &ovnacts2,
                                     &prereqs2);
        if (!error) {
            struct ds ovnacts2_s = DS_EMPTY_INITIALIZER;
            ovnacts_format(ovnacts2.data, ovnacts2.size, &ovnacts2_s);
            if (strcmp(ds_cstr(&ovnacts_s), ds_cstr(&ovnacts2_s))) {
                printf("    bad reformat: %s\n", ds_cstr(&ovnacts2_s));
            }
            ds_destroy(&ovnacts2_s);
        } else {
            printf("    reparse error: %s\n", error);
            free(error);
        }
        expr_destroy(prereqs2);

        ovnacts_free(ovnacts2.data, ovnacts2.size);
        ofpbuf_uninit(&ovnacts2);
        ds_destroy(&ovnacts_s);
    } else {
        printf("    %s\n", error);
        free(error);
    }

    expr_destroy(prereqs);
    ovnacts_free(ovnacts.data, ovnacts.size);
    ofpbuf_uninit(&ovnacts);

    simap_destroy(&ports);
    expr_symtab_destroy(&symtab);
    shash_destroy(&symtab);
    dhcp_opts_destroy(&dhcp_opts);
    dhcp_opts_destroy(&dhcpv6_opts);
    nd_ra_opts_destroy(&nd_ra_opts);
    ovn_extend_table_destroy(&group_table);
    ovn_extend_table_destroy(&meter_table);
}

static void
test_parse_expr(const char *input)
{
    struct shash symtab;
    struct shash addr_sets;
    struct shash port_groups;
    struct simap ports;
    struct expr *expr;
    char *error;

    create_symtab(&symtab);
    create_addr_sets(&addr_sets);
    create_port_groups(&port_groups);

    simap_init(&ports);
    simap_put(&ports, "eth0", 5);
    simap_put(&ports, "eth1", 6);
    simap_put(&ports, "LOCAL", ofp_to_u16(OFPP_LOCAL));
    simap_put(&ports, "lsp1", 0x11);
    simap_put(&ports, "lsp2", 0x12);
    simap_put(&ports, "lsp3", 0x13);

    expr = expr_parse_string(input, &symtab, &addr_sets,
                             &port_groups, &error);
    if (!error) {
        expr = expr_annotate(expr, &symtab, &error);
    }
    if (!error) {
        expr = expr_simplify(expr, is_chassis_resident_cb, &ports);
        expr = expr_normalize(expr);
        ovs_assert(expr_is_normalized(expr));
    }
    if (!error) {
        struct hmap matches;

        expr_to_matches(expr, lookup_port_cb, &ports, &matches);
        expr_matches_print(&matches, stdout);
        expr_matches_destroy(&matches);
    } else {
        puts(error);
        free(error);
    }
    expr_destroy(expr);
    simap_destroy(&ports);
    expr_symtab_destroy(&symtab);
    shash_destroy(&symtab);
    expr_const_sets_destroy(&addr_sets);
    shash_destroy(&addr_sets);
    expr_const_sets_destroy(&port_groups);
    shash_destroy(&port_groups);
}

static bool
lookup_atoi_cb(const void *aux OVS_UNUSED, const char *port_name,
               unsigned int *portp)
{
    *portp = atoi(port_name);
    return true;
}

static void
test_expr_to_packets(const char *input)
{
    struct shash symtab;
    create_symtab(&symtab);

    struct flow uflow;
    char *error = expr_parse_microflow(input, &symtab, NULL, NULL,
                                       lookup_atoi_cb, NULL, &uflow);
    if (error) {
        puts(error);
        free(error);
        expr_symtab_destroy(&symtab);
        shash_destroy(&symtab);
        return;
    }

    uint64_t packet_stub[128 / 8];
    struct dp_packet packet;
    dp_packet_use_stub(&packet, packet_stub, sizeof packet_stub);
    flow_compose(&packet, &uflow, NULL, 64);

    struct ds output = DS_EMPTY_INITIALIZER;
    const uint8_t *buf = dp_packet_data(&packet);
    for (int i = 0; i < dp_packet_size(&packet); i++) {
        uint8_t val = buf[i];
        ds_put_format(&output, "%02"PRIx8, val);
    }
    puts(ds_cstr(&output));
    ds_destroy(&output);
    dp_packet_uninit(&packet);
    expr_symtab_destroy(&symtab);
    shash_destroy(&symtab);
}

int
LLVMFuzzerTestOneInput(const uint8_t *input_, size_t size)
{
    /* Bail out if we cannot construct at least a 1 char string. */
    const char *input = (const char *) input_;
    if (size < 2 || input[size - 1] != '\0' || strchr(input, '\n') ||
        strlen(input) != size - 1) {
        return 0;
    }

    /* Disable logging to avoid write to disk. */
    static bool isInit = false;
    if (!isInit) {
        vlog_set_verbosity("off");
        isInit = true;
    }

    /* Parse, annotate, simplify, normalize expr and convert to flows. */
    test_parse_expr(input);

    /* Parse actions. */
    test_parse_actions(input);

    /* Test OVN lexer. */
    test_lex(input);

    /* Expr to packets. */
    test_expr_to_packets(input);

    return 0;
}
コード例 #20
0
ファイル: netdev-native-tnl.c プロジェクト: ALutzG/ovs
void *
netdev_tnl_ip_extract_tnl_md(struct dp_packet *packet, struct flow_tnl *tnl,
                  unsigned int *hlen)
{
    void *nh;
    struct ip_header *ip;
    struct ovs_16aligned_ip6_hdr *ip6;
    void *l4;
    int l3_size;

    nh = dp_packet_l3(packet);
    ip = nh;
    ip6 = nh;
    l4 = dp_packet_l4(packet);

    if (!nh || !l4) {
        return NULL;
    }

    *hlen = sizeof(struct eth_header);

    l3_size = dp_packet_size(packet) -
              ((char *)nh - (char *)dp_packet_data(packet));

    if (IP_VER(ip->ip_ihl_ver) == 4) {

        ovs_be32 ip_src, ip_dst;

        if (csum(ip, IP_IHL(ip->ip_ihl_ver) * 4)) {
            VLOG_WARN_RL(&err_rl, "ip packet has invalid checksum");
            return NULL;
        }

        if (ntohs(ip->ip_tot_len) > l3_size) {
            VLOG_WARN_RL(&err_rl, "ip packet is truncated (IP length %d, actual %d)",
                         ntohs(ip->ip_tot_len), l3_size);
            return NULL;
        }
        if (IP_IHL(ip->ip_ihl_ver) * 4 > sizeof(struct ip_header)) {
            VLOG_WARN_RL(&err_rl, "ip options not supported on tunnel packets "
                         "(%d bytes)", IP_IHL(ip->ip_ihl_ver) * 4);
            return NULL;
        }

        ip_src = get_16aligned_be32(&ip->ip_src);
        ip_dst = get_16aligned_be32(&ip->ip_dst);

        tnl->ip_src = ip_src;
        tnl->ip_dst = ip_dst;
        tnl->ip_tos = ip->ip_tos;
        tnl->ip_ttl = ip->ip_ttl;

        *hlen += IP_HEADER_LEN;

    } else if (IP_VER(ip->ip_ihl_ver) == 6) {
        ovs_be32 tc_flow = get_16aligned_be32(&ip6->ip6_flow);

        memcpy(tnl->ipv6_src.s6_addr, ip6->ip6_src.be16, sizeof ip6->ip6_src);
        memcpy(tnl->ipv6_dst.s6_addr, ip6->ip6_dst.be16, sizeof ip6->ip6_dst);

        tnl->ip_tos = ntohl(tc_flow) >> 20;
        tnl->ip_ttl = ip6->ip6_hlim;

        *hlen += IPV6_HEADER_LEN;

    } else {
コード例 #21
0
ファイル: ovs-shim.c プロジェクト: noironetworks/opflex
uint32_t dpp_size(const struct dp_packet* pkt) {
    return dp_packet_size(pkt);
}