fix ethdev port id validation
[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 (!rte_eth_dev_is_valid_port(port_id))
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 (!rte_eth_dev_is_valid_port(port_id))
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         const struct rte_pci_device *pci_dev;
110         const struct rte_bus *bus = NULL;
111
112         /* Check input params */
113         if ((name == NULL) ||
114                 kni_find(name) ||
115                 (params == NULL))
116                 return NULL;
117
118         mempool = mempool_find(params->mempool_name);
119         link = link_find(params->link_name);
120         if ((mempool == NULL) ||
121                 (link == NULL))
122                 return NULL;
123
124         /* Resource create */
125         rte_eth_dev_info_get(link->port_id, &dev_info);
126
127         memset(&kni_conf, 0, sizeof(kni_conf));
128         snprintf(kni_conf.name, RTE_KNI_NAMESIZE, "%s", name);
129         kni_conf.force_bind = params->force_bind;
130         kni_conf.core_id = params->thread_id;
131         kni_conf.group_id = link->port_id;
132         kni_conf.mbuf_size = mempool->buffer_size;
133         if (dev_info.device)
134                 bus = rte_bus_find_by_device(dev_info.device);
135         if (bus && !strcmp(bus->name, "pci")) {
136                 pci_dev = RTE_DEV_TO_PCI(dev_info.device);
137                 kni_conf.addr = pci_dev->addr;
138                 kni_conf.id = pci_dev->id;
139         }
140
141         memset(&kni_ops, 0, sizeof(kni_ops));
142         kni_ops.port_id = link->port_id;
143         kni_ops.config_network_if = kni_config_network_interface;
144         kni_ops.change_mtu = kni_change_mtu;
145
146         k = rte_kni_alloc(mempool->m, &kni_conf, &kni_ops);
147         if (k == NULL)
148                 return NULL;
149
150         /* Node allocation */
151         kni = calloc(1, sizeof(struct kni));
152         if (kni == NULL)
153                 return NULL;
154
155         /* Node fill in */
156         strncpy(kni->name, name, sizeof(kni->name));
157         kni->k = k;
158
159         /* Node add to list */
160         TAILQ_INSERT_TAIL(&kni_list, kni, node);
161
162         return kni;
163 }
164
165 void
166 kni_handle_request(void)
167 {
168         struct kni *kni;
169
170         TAILQ_FOREACH(kni, &kni_list, node)
171                 rte_kni_handle_request(kni->k);
172 }
173
174 #endif