#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/param.h>
#include <string.h>
#include <sys/queue.h>
#include <stdarg.h>
#include <errno.h>
#include <getopt.h>
#define RTE_LOGTYPE_IP_FRAG RTE_LOGTYPE_USER1
#define JUMBO_FRAME_MAX_SIZE    0x2600
#define ROUNDUP_DIV(a, b)   (((a) + (b) - 1) / (b))
#define IPV4_MTU_DEFAULT    ETHER_MTU
#define IPV6_MTU_DEFAULT    ETHER_MTU
#define IPV4_DEFAULT_PAYLOAD    (IPV4_MTU_DEFAULT - sizeof(struct ipv4_hdr))
#define IPV6_DEFAULT_PAYLOAD    (IPV6_MTU_DEFAULT - sizeof(struct ipv6_hdr))
#define MAX_PACKET_FRAG RTE_LIBRTE_IP_FRAG_MAX_FRAG
#define NB_MBUF   8192
#define MAX_PKT_BURST   32
#define BURST_TX_DRAIN_US 100 
#define PREFETCH_OFFSET 3
#define RTE_TEST_RX_DESC_DEFAULT 1024
#define RTE_TEST_TX_DESC_DEFAULT 1024
static uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT;
static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT;
static struct ether_addr ports_eth_addr[RTE_MAX_ETHPORTS];
 
#ifndef IPv4_BYTES
#define IPv4_BYTES_FMT "%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8
#define IPv4_BYTES(addr) \
        (uint8_t) (((addr) >> 24) & 0xFF),\
        (uint8_t) (((addr) >> 16) & 0xFF),\
        (uint8_t) (((addr) >> 8) & 0xFF),\
        (uint8_t) ((addr) & 0xFF)
#endif
#ifndef IPv6_BYTES
#define IPv6_BYTES_FMT "%02x%02x:%02x%02x:%02x%02x:%02x%02x:"\
                       "%02x%02x:%02x%02x:%02x%02x:%02x%02x"
#define IPv6_BYTES(addr) \
    addr[0],  addr[1], addr[2],  addr[3], \
    addr[4],  addr[5], addr[6],  addr[7], \
    addr[8],  addr[9], addr[10], addr[11],\
    addr[12], addr[13],addr[14], addr[15]
#endif
#define IPV6_ADDR_LEN 16
static int enabled_port_mask = 0;
static int rx_queue_per_lcore = 1;
#define MBUF_TABLE_SIZE  (2 * MAX(MAX_PKT_BURST, MAX_PACKET_FRAG))
struct mbuf_table {
    uint16_t len;
    struct rte_mbuf *m_table[MBUF_TABLE_SIZE];
 
};
struct rx_queue {
    struct rte_lpm *lpm;
    struct rte_lpm6 *lpm6;
    uint16_t portid;
};
#define MAX_RX_QUEUE_PER_LCORE 16
#define MAX_TX_QUEUE_PER_PORT 16
struct lcore_queue_conf {
    uint16_t n_rx_queue;
    uint16_t tx_queue_id[RTE_MAX_ETHPORTS];
    struct rx_queue rx_queue_list[MAX_RX_QUEUE_PER_LCORE];
    struct mbuf_table tx_mbufs[RTE_MAX_ETHPORTS];
struct lcore_queue_conf lcore_queue_conf[RTE_MAX_LCORE];
        .split_hdr_size = 0,
        .offloads = (DEV_RX_OFFLOAD_CHECKSUM |
                 DEV_RX_OFFLOAD_JUMBO_FRAME),
    },
        .offloads = (DEV_TX_OFFLOAD_IPV4_CKSUM |
    },
};
struct l3fwd_ipv4_route {
    uint32_t ip;
    uint8_t  depth;
    uint8_t  if_out;
};
struct l3fwd_ipv4_route l3fwd_ipv4_route_array[] = {
        {
IPv4(100,10,0,0), 16, 0},
        {
IPv4(100,20,0,0), 16, 1},
        {
IPv4(100,30,0,0), 16, 2},
        {
IPv4(100,40,0,0), 16, 3},
        {
IPv4(100,50,0,0), 16, 4},
        {
IPv4(100,60,0,0), 16, 5},
        {
IPv4(100,70,0,0), 16, 6},
        {
IPv4(100,80,0,0), 16, 7},
};
struct l3fwd_ipv6_route {
    uint8_t ip[IPV6_ADDR_LEN];
    uint8_t depth;
    uint8_t if_out;
};
static struct l3fwd_ipv6_route l3fwd_ipv6_route_array[] = {
    {{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, 48, 0},
    {{2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, 48, 1},
    {{3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, 48, 2},
    {{4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, 48, 3},
    {{5,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, 48, 4},
    {{6,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, 48, 5},
    {{7,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, 48, 6},
    {{8,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, 48, 7},
};
#define LPM_MAX_RULES         1024
#define LPM6_MAX_RULES         1024
#define LPM6_NUMBER_TBL8S (1 << 16)
        .number_tbl8s = LPM6_NUMBER_TBL8S,
        .flags = 0
};
static struct rte_mempool *socket_direct_pool[RTE_MAX_NUMA_NODES];
 
static struct rte_mempool *socket_indirect_pool[RTE_MAX_NUMA_NODES];
 
static struct rte_lpm *socket_lpm[RTE_MAX_NUMA_NODES];
static struct rte_lpm6 *socket_lpm6[RTE_MAX_NUMA_NODES];
static inline int
send_burst(
struct lcore_queue_conf *qconf, uint16_t n, uint16_t 
port)
{
    int ret;
    uint16_t queueid;
    queueid = qconf->tx_queue_id[
port];
    m_table = (
struct rte_mbuf **)qconf->tx_mbufs[port].m_table;
        do {
        } while (++ret < n);
    }
    return 0;
}
static inline void
l3fwd_simple_forward(
struct rte_mbuf *m, 
struct lcore_queue_conf *qconf,
        uint8_t queueid, uint16_t port_in)
{
    struct rx_queue *rxq;
    uint32_t i, len, next_hop;
    uint16_t port_out, ether_type;
    int32_t len2;
    rxq = &qconf->rx_queue_list[queueid];
    
    port_out = port_in;
    
    
    
    len = qconf->tx_mbufs[port_out].len;
    
        uint32_t ip_dst;
        
        
                (enabled_port_mask & 1 << next_hop) != 0) {
            port_out = next_hop;
            
            len = qconf->tx_mbufs[port_out].len;
        }
        
            qconf->tx_mbufs[port_out].m_table[len] = m;
            len2 = 1;
        } else {
                &qconf->tx_mbufs[port_out].m_table[len],
                (uint16_t)(MBUF_TABLE_SIZE - len),
                IPV4_MTU_DEFAULT,
                rxq->direct_pool, rxq->indirect_pool);
            
            
                return;
        }
        
        
        
                        &next_hop) == 0 &&
                (enabled_port_mask & 1 << next_hop) != 0) {
            port_out = next_hop;
            
            len = qconf->tx_mbufs[port_out].len;
        }
        
            qconf->tx_mbufs[port_out].m_table[len] = m;
            len2 = 1;
        } else {
                &qconf->tx_mbufs[port_out].m_table[len],
                (uint16_t)(MBUF_TABLE_SIZE - len),
                IPV6_MTU_DEFAULT,
                rxq->direct_pool, rxq->indirect_pool);
            
            
                return;
        }
    }
    
    else {
        qconf->tx_mbufs[port_out].m_table[len] = m;
        len2 = 1;
    }
    for (i = len; i < len + len2; i ++) {
        void *d_addr_bytes;
        m = qconf->tx_mbufs[port_out].m_table[i];
        if (eth_hdr == NULL) {
        }
        
        *((uint64_t *)d_addr_bytes) = 0x000000000002 + ((uint64_t)port_out << 40);
        
    }
    len += len2;
    if (
likely(len < MAX_PKT_BURST)) {
 
        qconf->tx_mbufs[port_out].len = (uint16_t)len;
        return;
    }
    
    send_burst(qconf, (uint16_t)len, port_out);
    qconf->tx_mbufs[port_out].len = 0;
}
static int
main_loop(__attribute__((unused)) void *dummy)
{
    struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
 
    unsigned lcore_id;
    uint64_t prev_tsc, diff_tsc, cur_tsc;
    int i, j, nb_rx;
    uint16_t portid;
    struct lcore_queue_conf *qconf;
    const uint64_t drain_tsc = (
rte_get_tsc_hz() + US_PER_S - 1) / US_PER_S * BURST_TX_DRAIN_US;
 
    prev_tsc = 0;
    qconf = &lcore_queue_conf[lcore_id];
    if (qconf->n_rx_queue == 0) {
        RTE_LOG(INFO, IP_FRAG, 
"lcore %u has nothing to do\n", lcore_id);
 
        return 0;
    }
    RTE_LOG(INFO, IP_FRAG, 
"entering main loop on lcore %u\n", lcore_id);
 
    for (i = 0; i < qconf->n_rx_queue; i++) {
        portid = qconf->rx_queue_list[i].portid;
        RTE_LOG(INFO, IP_FRAG, 
" -- lcoreid=%u portid=%d\n", lcore_id,
 
                portid);
    }
    while (1) {
        cur_tsc = rte_rdtsc();
        
        diff_tsc = cur_tsc - prev_tsc;
            
            for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) {
                if (qconf->tx_mbufs[portid].len == 0)
                    continue;
                send_burst(&lcore_queue_conf[lcore_id],
                       qconf->tx_mbufs[portid].len,
                       portid);
                qconf->tx_mbufs[portid].len = 0;
            }
            prev_tsc = cur_tsc;
        }
        
        for (i = 0; i < qconf->n_rx_queue; i++) {
            portid = qconf->rx_queue_list[i].portid;
                         MAX_PKT_BURST);
            
            for (j = 0; j < PREFETCH_OFFSET && j < nb_rx; j++) {
                        pkts_burst[j], void *));
            }
            
            for (j = 0; j < (nb_rx - PREFETCH_OFFSET); j++) {
                        j + PREFETCH_OFFSET], void *));
                l3fwd_simple_forward(pkts_burst[j], qconf, i, portid);
            }
            
            for (; j < nb_rx; j++) {
                l3fwd_simple_forward(pkts_burst[j], qconf, i, portid);
            }
        }
    }
}
static void
print_usage(const char *prgname)
{
    printf("%s [EAL options] -- -p PORTMASK [-q NQ]\n"
           "  -p PORTMASK: hexadecimal bitmask of ports to configure\n"
           "  -q NQ: number of queue (=ports) per lcore (default is 1)\n",
           prgname);
}
static int
parse_portmask(const char *portmask)
{
    char *end = NULL;
    unsigned long pm;
    
    pm = strtoul(portmask, &end, 16);
    if ((portmask[0] == '\0') || (end == NULL) || (*end != '\0'))
        return -1;
    if (pm == 0)
        return -1;
    return pm;
}
static int
parse_nqueue(const char *q_arg)
{
    char *end = NULL;
    unsigned long n;
    
    n = strtoul(q_arg, &end, 10);
    if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0'))
        return -1;
    if (n == 0)
        return -1;
    if (n >= MAX_RX_QUEUE_PER_LCORE)
        return -1;
    return n;
}
static int
parse_args(int argc, char **argv)
{
    int opt, ret;
    char **argvopt;
    int option_index;
    char *prgname = argv[0];
    static struct option lgopts[] = {
        {NULL, 0, 0, 0}
    };
    argvopt = argv;
    while ((opt = getopt_long(argc, argvopt, "p:q:",
                  lgopts, &option_index)) != EOF) {
        switch (opt) {
        
        case 'p':
            enabled_port_mask = parse_portmask(optarg);
            if (enabled_port_mask < 0) {
                printf("invalid portmask\n");
                print_usage(prgname);
                return -1;
            }
            break;
        
        case 'q':
            rx_queue_per_lcore = parse_nqueue(optarg);
            if (rx_queue_per_lcore < 0) {
                printf("invalid queue number\n");
                print_usage(prgname);
                return -1;
            }
            break;
        
        case 0:
            print_usage(prgname);
            return -1;
        default:
            print_usage(prgname);
            return -1;
        }
    }
    if (enabled_port_mask == 0) {
        printf("portmask not specified\n");
        print_usage(prgname);
        return -1;
    }
    if (optind >= 0)
        argv[optind-1] = prgname;
    ret = optind-1;
    optind = 1; 
    return ret;
}
static void
print_ethaddr(
const char *name, 
struct ether_addr *eth_addr)
{
    char buf[ETHER_ADDR_FMT_SIZE];
    printf("%s%s", name, buf);
}
static void
check_all_ports_link_status(uint32_t port_mask)
{
#define CHECK_INTERVAL 100 
#define MAX_CHECK_TIME 90 
    uint16_t portid;
    uint8_t count, all_ports_up, print_flag = 0;
    printf("\nChecking link status");
    fflush(stdout);
    for (count = 0; count <= MAX_CHECK_TIME; count++) {
        all_ports_up = 1;
            if ((port_mask & (1 << portid)) == 0)
                continue;
            memset(&link, 0, sizeof(link));
            
            if (print_flag == 1) {
                if (link.link_status)
                    printf(
                    "Port%d Link Up .Speed %u Mbps - %s\n",
                        portid, link.link_speed,
                    ("full-duplex") : ("half-duplex"));
                else
                    printf("Port %d Link Down\n", portid);
                continue;
            }
            
                all_ports_up = 0;
                break;
            }
        }
        
        if (print_flag == 1)
            break;
        if (all_ports_up == 0) {
            printf(".");
            fflush(stdout);
        }
        
        if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
            print_flag = 1;
            printf("\ndone\n");
        }
    }
}
static int
check_ptype(int portid)
{
    int i, ret;
    int ptype_l3_ipv4 = 0, ptype_l3_ipv6 = 0;
    if (ret <= 0)
        return 0;
    uint32_t ptypes[ret];
    for (i = 0; i < ret; ++i) {
            ptype_l3_ipv4 = 1;
            ptype_l3_ipv6 = 1;
    }
    if (ptype_l3_ipv4 == 0)
        printf("port %d cannot parse RTE_PTYPE_L3_IPV4\n", portid);
    if (ptype_l3_ipv6 == 0)
        printf("port %d cannot parse RTE_PTYPE_L3_IPV6\n", portid);
    if (ptype_l3_ipv4 && ptype_l3_ipv6)
        return 1;
    return 0;
}
static inline void
{
}
static uint16_t
cb_parse_ptype(uint16_t port 
__rte_unused, uint16_t queue __rte_unused,
           struct rte_mbuf *pkts[], uint16_t nb_pkts,
 
           uint16_t max_pkts __rte_unused,
           void *user_param __rte_unused)
{
    uint16_t i;
    for (i = 0; i < nb_pkts; ++i)
        parse_ptype(pkts[i]);
    return nb_pkts;
}
static int
init_routing_table(void)
{
    struct rte_lpm *lpm;
    struct rte_lpm6 *lpm6;
    int socket, ret;
    unsigned i;
    for (socket = 0; socket < RTE_MAX_NUMA_NODES; socket++) {
        if (socket_lpm[socket]) {
            lpm = socket_lpm[socket];
            
            for (i = 0; i < 
RTE_DIM(l3fwd_ipv4_route_array); i++) {
 
                    l3fwd_ipv4_route_array[i].ip,
                    l3fwd_ipv4_route_array[i].depth,
                    l3fwd_ipv4_route_array[i].if_out);
                if (ret < 0) {
                    RTE_LOG(ERR, IP_FRAG, 
"Unable to add entry %i to the l3fwd " 
                        "LPM table\n", i);
                    return -1;
                }
                RTE_LOG(INFO, IP_FRAG, 
"Socket %i: adding route " IPv4_BYTES_FMT
 
                        "/%d (port %d)\n",
                    socket,
                    IPv4_BYTES(l3fwd_ipv4_route_array[i].ip),
                    l3fwd_ipv4_route_array[i].depth,
                    l3fwd_ipv4_route_array[i].if_out);
            }
        }
        if (socket_lpm6[socket]) {
            lpm6 = socket_lpm6[socket];
            
            for (i = 0; i < 
RTE_DIM(l3fwd_ipv6_route_array); i++) {
 
                    l3fwd_ipv6_route_array[i].ip,
                    l3fwd_ipv6_route_array[i].depth,
                    l3fwd_ipv6_route_array[i].if_out);
                if (ret < 0) {
                    RTE_LOG(ERR, IP_FRAG, 
"Unable to add entry %i to the l3fwd " 
                        "LPM6 table\n", i);
                    return -1;
                }
                RTE_LOG(INFO, IP_FRAG, 
"Socket %i: adding route " IPv6_BYTES_FMT
 
                        "/%d (port %d)\n",
                    socket,
                    IPv6_BYTES(l3fwd_ipv6_route_array[i].ip),
                    l3fwd_ipv6_route_array[i].depth,
                    l3fwd_ipv6_route_array[i].if_out);
            }
        }
    }
    return 0;
}
static int
init_mem(void)
{
    char buf[PATH_MAX];
    struct rte_lpm *lpm;
    struct rte_lpm6 *lpm6;
    int socket;
    unsigned lcore_id;
    
    for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
            continue;
            socket = 0;
        if (socket_direct_pool[socket] == NULL) {
            RTE_LOG(INFO, IP_FRAG, 
"Creating direct mempool on socket %i\n",
 
                    socket);
            snprintf(buf, sizeof(buf), "pool_direct_%i", socket);
                0, RTE_MBUF_DEFAULT_BUF_SIZE, socket);
            if (mp == NULL) {
                RTE_LOG(ERR, IP_FRAG, 
"Cannot create direct mempool\n");
 
                return -1;
            }
            socket_direct_pool[socket] = mp;
        }
        if (socket_indirect_pool[socket] == NULL) {
            RTE_LOG(INFO, IP_FRAG, 
"Creating indirect mempool on socket %i\n",
 
                    socket);
            snprintf(buf, sizeof(buf), "pool_indirect_%i", socket);
                socket);
            if (mp == NULL) {
                RTE_LOG(ERR, IP_FRAG, 
"Cannot create indirect mempool\n");
 
                return -1;
            }
            socket_indirect_pool[socket] = mp;
        }
        if (socket_lpm[socket] == NULL) {
            RTE_LOG(INFO, IP_FRAG, 
"Creating LPM table on socket %i\n", socket);
 
            snprintf(buf, sizeof(buf), "IP_FRAG_LPM_%i", socket);
            lpm_config.max_rules = LPM_MAX_RULES;
            lpm_config.number_tbl8s = 256;
            lpm_config.flags = 0;
            if (lpm == NULL) {
                RTE_LOG(ERR, IP_FRAG, 
"Cannot create LPM table\n");
 
                return -1;
            }
            socket_lpm[socket] = lpm;
        }
        if (socket_lpm6[socket] == NULL) {
            RTE_LOG(INFO, IP_FRAG, 
"Creating LPM6 table on socket %i\n", socket);
 
            snprintf(buf, sizeof(buf), "IP_FRAG_LPM_%i", socket);
            if (lpm6 == NULL) {
                RTE_LOG(ERR, IP_FRAG, 
"Cannot create LPM table\n");
 
                return -1;
            }
            socket_lpm6[socket] = lpm6;
        }
    }
    return 0;
}
int
main(int argc, char **argv)
{
    struct lcore_queue_conf *qconf;
    struct rx_queue *rxq;
    int socket, ret;
    uint16_t nb_ports;
    uint16_t queueid = 0;
    unsigned lcore_id = 0, rx_lcore_id = 0;
    uint32_t n_tx_queue, nb_lcores;
    uint16_t portid;
    
    if (ret < 0)
        rte_exit(EXIT_FAILURE, 
"rte_eal_init failed");
 
    argc -= ret;
    argv += ret;
    
    ret = parse_args(argc, argv);
    if (ret < 0)
        rte_exit(EXIT_FAILURE, 
"Invalid arguments");
 
    if (nb_ports == 0)
        rte_exit(EXIT_FAILURE, 
"No ports found!\n");
 
    
    if (init_mem() < 0)
        rte_panic(
"Cannot initialize memory structures!\n");
 
    
    if (enabled_port_mask & ~(
RTE_LEN2MASK(nb_ports, 
unsigned)))
 
        rte_exit(EXIT_FAILURE, 
"Non-existent ports in portmask!\n");
 
    
        
        if ((enabled_port_mask & (1 << portid)) == 0) {
            printf("Skipping disabled port %d\n", portid);
            continue;
        }
        qconf = &lcore_queue_conf[rx_lcore_id];
        
            dev_info.max_rx_pktlen,
        
               qconf->n_rx_queue == (unsigned)rx_queue_per_lcore) {
            rx_lcore_id ++;
            if (rx_lcore_id >= RTE_MAX_LCORE)
                rte_exit(EXIT_FAILURE, 
"Not enough cores\n");
 
            qconf = &lcore_queue_conf[rx_lcore_id];
        }
            socket = 0;
        rxq = &qconf->rx_queue_list[qconf->n_rx_queue];
        rxq->portid = portid;
        rxq->direct_pool = socket_direct_pool[socket];
        rxq->indirect_pool = socket_indirect_pool[socket];
        rxq->lpm = socket_lpm[socket];
        rxq->lpm6 = socket_lpm6[socket];
        qconf->n_rx_queue++;
        
        printf("Initializing port %d on lcore %u...", portid,
               rx_lcore_id);
        fflush(stdout);
        n_tx_queue = nb_lcores;
        if (n_tx_queue > MAX_TX_QUEUE_PER_PORT)
            n_tx_queue = MAX_TX_QUEUE_PER_PORT;
                        &local_port_conf);
        if (ret < 0) {
            printf("\n");
            rte_exit(EXIT_FAILURE, 
"Cannot configure device: " 
                "err=%d, port=%d\n",
                ret, portid);
        }
                        &nb_txd);
        if (ret < 0) {
            printf("\n");
            rte_exit(EXIT_FAILURE, 
"Cannot adjust number of " 
                "descriptors: err=%d, port=%d\n", ret, portid);
        }
        
        rxq_conf = dev_info.default_rxconf;
                         socket, &rxq_conf,
                         socket_direct_pool[socket]);
        if (ret < 0) {
            printf("\n");
            rte_exit(EXIT_FAILURE, 
"rte_eth_rx_queue_setup: " 
                "err=%d, port=%d\n",
                ret, portid);
        }
        print_ethaddr(" Address:", &ports_eth_addr[portid]);
        printf("\n");
        
        queueid = 0;
        for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
                continue;
            if (queueid >= dev_info.nb_tx_queues)
                break;
            printf("txq=%u,%d ", lcore_id, queueid);
            fflush(stdout);
            txconf = &dev_info.default_txconf;
                             socket, txconf);
            if (ret < 0) {
                printf("\n");
                rte_exit(EXIT_FAILURE, 
"rte_eth_tx_queue_setup: " 
                    "err=%d, port=%d\n", ret, portid);
            }
            qconf = &lcore_queue_conf[lcore_id];
            qconf->tx_queue_id[portid] = queueid;
            queueid++;
        }
        printf("\n");
    }
    printf("\n");
    
        if ((enabled_port_mask & (1 << portid)) == 0) {
            continue;
        }
        
        if (ret < 0)
            rte_exit(EXIT_FAILURE, 
"rte_eth_dev_start: err=%d, port=%d\n",
 
                ret, portid);
        if (check_ptype(portid) == 0) {
            printf("Add Rx callback function to detect L3 packet type by SW :"
                " port = %d\n", portid);
        }
    }
    if (init_routing_table() < 0)
        rte_exit(EXIT_FAILURE, 
"Cannot init routing table\n");
 
    check_all_ports_link_status(enabled_port_mask);
    
            return -1;
    }
    return 0;
}