#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/queue.h>
#include <netinet/in.h>
#include <setjmp.h>
#include <stdarg.h>
#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <signal.h>
#include <stdbool.h>
#include <rte_net.h>
static volatile bool force_quit;
static uint16_t port_id;
static uint16_t nr_queues = 5;
static uint8_t selected_queue = 1;
struct rte_flow *flow;
#define SRC_IP ((0<<24) + (0<<16) + (0<<8) + 0) 
#define DEST_IP ((192<<24) + (168<<16) + (1<<8) + 1) 
#define FULL_MASK 0xffffffff 
#define EMPTY_MASK 0x0 
#include "flow_blocks.c"
static inline void
print_ether_addr(
const char *what, 
struct ether_addr *eth_addr)
{
    char buf[ETHER_ADDR_FMT_SIZE];
    printf("%s%s", what, buf);
}
static void
main_loop(void)
{
    uint16_t nb_rx;
    uint16_t i;
    uint16_t j;
    while (!force_quit) {
        for (i = 0; i < nr_queues; i++) {
                        i, mbufs, 32);
            if (nb_rx) {
                for (j = 0; j < nb_rx; j++) {
                    print_ether_addr("src=",
                    print_ether_addr(" - dst=",
                    printf(" - queue=0x%x",
                            (unsigned int)i);
                    printf("\n");
                }
            }
        }
    }
    
}
#define CHECK_INTERVAL 1000  
#define MAX_REPEAT_TIMES 90  
static void
assert_link_status(void)
{
    uint8_t rep_cnt = MAX_REPEAT_TIMES;
    memset(&link, 0, sizeof(link));
    do {
            break;
    } while (--rep_cnt);
        rte_exit(EXIT_FAILURE, 
":: error: link is still down\n");
 
}
static void
init_port(void)
{
    int ret;
    uint16_t i;
        },
        .txmode = {
            .offloads =
                DEV_TX_OFFLOAD_IPV4_CKSUM  |
                DEV_TX_OFFLOAD_UDP_CKSUM   |
                DEV_TX_OFFLOAD_TCP_CKSUM   |
                DEV_TX_OFFLOAD_SCTP_CKSUM  |
                DEV_TX_OFFLOAD_TCP_TSO,
        },
    };
    printf(":: initializing port: %d\n", port_id);
                nr_queues, nr_queues, &port_conf);
    if (ret < 0) {
            ":: cannot configure device: err=%d, port=%u\n",
            ret, port_id);
    }
    rxq_conf = dev_info.default_rxconf;
    
    for (i = 0; i < nr_queues; i++) {
                     &rxq_conf,
                     mbuf_pool);
        if (ret < 0) {
                ":: Rx queue setup failed: err=%d, port=%u\n",
                ret, port_id);
        }
    }
    txq_conf = dev_info.default_txconf;
    for (i = 0; i < nr_queues; i++) {
                &txq_conf);
        if (ret < 0) {
                ":: Tx queue setup failed: err=%d, port=%u\n",
                ret, port_id);
        }
    }
    if (ret < 0) {
            "rte_eth_dev_start:err=%d, port=%u\n",
            ret, port_id);
    }
    assert_link_status();
    printf(":: initializing port: %d done\n", port_id);
}
static void
signal_handler(int signum)
{
    if (signum == SIGINT || signum == SIGTERM) {
        printf("\n\nSignal %d received, preparing to exit...\n",
                signum);
        force_quit = true;
    }
}
int
main(int argc, char **argv)
{
    int ret;
    uint16_t nr_ports;
    if (ret < 0)
        rte_exit(EXIT_FAILURE, 
":: invalid EAL arguments\n");
 
    force_quit = false;
    signal(SIGINT, signal_handler);
    signal(SIGTERM, signal_handler);
    if (nr_ports == 0)
        rte_exit(EXIT_FAILURE, 
":: no Ethernet ports found\n");
 
    port_id = 0;
    if (nr_ports != 1) {
        printf(":: warn: %d ports detected, but we use only one: port %u\n",
            nr_ports, port_id);
    }
                        RTE_MBUF_DEFAULT_BUF_SIZE,
    if (mbuf_pool == NULL)
        rte_exit(EXIT_FAILURE, 
"Cannot init mbuf pool\n");
 
    init_port();
    
    flow = generate_ipv4_flow(port_id, selected_queue,
                SRC_IP, EMPTY_MASK,
                DEST_IP, FULL_MASK, &error);
    if (!flow) {
        printf("Flow can't be created %d message: %s\n",
            error.type,
            error.message ? error.message : "(no stated reason)");
        rte_exit(EXIT_FAILURE, 
"error in creating flow");
 
    }
    main_loop();
    return 0;
}