examples/ip_pipeline: add TTL stats command
[dpdk.git] / examples / ip_pipeline / kni.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2018 Intel Corporation
3  */
4
5 #include <stdlib.h>
6 #include <string.h>
7
8 #include <rte_ethdev.h>
9 #include <rte_bus_pci.h>
10
11 #include "kni.h"
12 #include "mempool.h"
13 #include "link.h"
14
15 static struct kni_list kni_list;
16
17 #ifndef KNI_MAX
18 #define KNI_MAX                                            16
19 #endif
20
21 int
22 kni_init(void)
23 {
24         TAILQ_INIT(&kni_list);
25
26 #ifdef RTE_LIBRTE_KNI
27         rte_kni_init(KNI_MAX);
28 #endif
29
30         return 0;
31 }
32
33 struct kni *
34 kni_find(const char *name)
35 {
36         struct kni *kni;
37
38         if (name == NULL)
39                 return NULL;
40
41         TAILQ_FOREACH(kni, &kni_list, node)
42                 if (strcmp(kni->name, name) == 0)
43                         return kni;
44
45         return NULL;
46 }
47
48 #ifndef RTE_LIBRTE_KNI
49
50 struct kni *
51 kni_create(const char *name __rte_unused,
52         struct kni_params *params __rte_unused)
53 {
54         return NULL;
55 }
56
57 void
58 kni_handle_request(void)
59 {
60         return;
61 }
62
63 #else
64
65 static int
66 kni_config_network_interface(uint16_t port_id, uint8_t if_up)
67 {
68         int ret = 0;
69
70         if (port_id >= rte_eth_dev_count())
71                 return -EINVAL;
72
73         ret = (if_up) ?
74                 rte_eth_dev_set_link_up(port_id) :
75                 rte_eth_dev_set_link_down(port_id);
76
77         return ret;
78 }
79
80 static int
81 kni_change_mtu(uint16_t port_id, unsigned int new_mtu)
82 {
83         int ret;
84
85         if (port_id >= rte_eth_dev_count())
86                 return -EINVAL;
87
88         if (new_mtu > ETHER_MAX_LEN)
89                 return -EINVAL;
90
91         /* Set new MTU */
92         ret = rte_eth_dev_set_mtu(port_id, new_mtu);
93         if (ret < 0)
94                 return ret;
95
96         return 0;
97 }
98
99 struct kni *
100 kni_create(const char *name, struct kni_params *params)
101 {
102         struct rte_eth_dev_info dev_info;
103         struct rte_kni_conf kni_conf;
104         struct rte_kni_ops kni_ops;
105         struct kni *kni;
106         struct mempool *mempool;
107         struct link *link;
108         struct rte_kni *k;
109
110         /* Check input params */
111         if ((name == NULL) ||
112                 kni_find(name) ||
113                 (params == NULL))
114                 return NULL;
115
116         mempool = mempool_find(params->mempool_name);
117         link = link_find(params->link_name);
118         if ((mempool == NULL) ||
119                 (link == NULL))
120                 return NULL;
121
122         /* Resource create */
123         rte_eth_dev_info_get(link->port_id, &dev_info);
124
125         memset(&kni_conf, 0, sizeof(kni_conf));
126         snprintf(kni_conf.name, RTE_KNI_NAMESIZE, "%s", name);
127         kni_conf.force_bind = params->force_bind;
128         kni_conf.core_id = params->thread_id;
129         kni_conf.group_id = link->port_id;
130         kni_conf.mbuf_size = mempool->buffer_size;
131         kni_conf.addr = dev_info.pci_dev->addr;
132         kni_conf.id = dev_info.pci_dev->id;
133
134         memset(&kni_ops, 0, sizeof(kni_ops));
135         kni_ops.port_id = link->port_id;
136         kni_ops.config_network_if = kni_config_network_interface;
137         kni_ops.change_mtu = kni_change_mtu;
138
139         k = rte_kni_alloc(mempool->m, &kni_conf, &kni_ops);
140         if (k == NULL)
141                 return NULL;
142
143         /* Node allocation */
144         kni = calloc(1, sizeof(struct kni));
145         if (kni == NULL)
146                 return NULL;
147
148         /* Node fill in */
149         strncpy(kni->name, name, sizeof(kni->name));
150         kni->k = k;
151
152         /* Node add to list */
153         TAILQ_INSERT_TAIL(&kni_list, kni, node);
154
155         return kni;
156 }
157
158 void
159 kni_handle_request(void)
160 {
161         struct kni *kni;
162
163         TAILQ_FOREACH(kni, &kni_list, node)
164                 rte_kni_handle_request(kni->k);
165 }
166
167 #endif