]> git.proxmox.com Git - mirror_frr.git/blob - zebra/dpdk/zebra_dplane_dpdk.c
zebra: initialize hw via DPDK
[mirror_frr.git] / zebra / dpdk / zebra_dplane_dpdk.c
1 /*
2 * Zebra dataplane plugin for DPDK based hw offload
3 *
4 * Copyright (C) 2021 Nvidia
5 * Anuradha Karuppiah
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h" /* Include this explicitly */
24 #endif
25
26 #include "lib/libfrr.h"
27
28 #include "zebra/debug.h"
29 #include "zebra/interface.h"
30 #include "zebra/zebra_dplane.h"
31 #include "zebra/debug.h"
32 #include "zebra/zebra_pbr.h"
33
34 #include "zebra/dpdk/zebra_dplane_dpdk_private.h"
35
36 static const char *plugin_name = "zebra_dplane_dpdk";
37
38 extern struct zebra_privs_t zserv_privs;
39
40 static struct zd_dpdk_ctx dpdk_ctx_buf, *dpdk_ctx = &dpdk_ctx_buf;
41 #define dpdk_stat (&dpdk_ctx->stats)
42
43
44 void zd_dpdk_stat_show(struct vty *vty)
45 {
46 uint32_t tmp_cnt;
47
48 vty_out(vty, "%30s\n%30s\n", "Dataplane DPDK counters",
49 "=======================");
50
51 #define ZD_DPDK_SHOW_COUNTER(label, counter) \
52 do { \
53 tmp_cnt = \
54 atomic_load_explicit(&counter, memory_order_relaxed); \
55 vty_out(vty, "%28s: %u\n", (label), (tmp_cnt)); \
56 } while (0);
57
58 ZD_DPDK_SHOW_COUNTER("PBR rule adds", dpdk_stat->rule_adds);
59 ZD_DPDK_SHOW_COUNTER("PBR rule dels", dpdk_stat->rule_dels);
60 ZD_DPDK_SHOW_COUNTER("Ignored updates", dpdk_stat->ignored_updates);
61 }
62
63
64 static void zd_dpdk_rule_add(struct zebra_dplane_ctx *ctx)
65 {
66 /* XXX - place holder */
67 }
68
69
70 static void zd_dpdk_rule_del(const char *ifname, int in_ifindex,
71 intptr_t dp_flow_ptr)
72 {
73
74 /* XXX - place holder */
75 }
76
77
78 static void zd_dpdk_rule_update(struct zebra_dplane_ctx *ctx)
79 {
80 enum dplane_op_e op;
81 int in_ifindex;
82 intptr_t dp_flow_ptr;
83
84 if (IS_ZEBRA_DEBUG_DPLANE_DPDK_DETAIL) {
85 zlog_debug("Dplane %s", dplane_op2str(dplane_ctx_get_op(ctx)));
86 }
87
88 op = dplane_ctx_get_op(ctx);
89 switch (op) {
90 case DPLANE_OP_RULE_ADD:
91 atomic_fetch_add_explicit(&dpdk_stat->rule_adds, 1,
92 memory_order_relaxed);
93 zd_dpdk_rule_add(ctx);
94 break;
95
96 case DPLANE_OP_RULE_UPDATE:
97 /* delete old rule and install new one */
98 atomic_fetch_add_explicit(&dpdk_stat->rule_adds, 1,
99 memory_order_relaxed);
100 in_ifindex = dplane_ctx_get_ifindex(ctx);
101 dp_flow_ptr = dplane_ctx_rule_get_old_dp_flow_ptr(ctx);
102 zd_dpdk_rule_del(dplane_ctx_rule_get_ifname(ctx), in_ifindex,
103 dp_flow_ptr);
104 zd_dpdk_rule_add(ctx);
105 break;
106
107 case DPLANE_OP_RULE_DELETE:
108 atomic_fetch_add_explicit(&dpdk_stat->rule_dels, 1,
109 memory_order_relaxed);
110 in_ifindex = dplane_ctx_get_ifindex(ctx);
111 dp_flow_ptr = dplane_ctx_rule_get_dp_flow_ptr(ctx);
112 zd_dpdk_rule_del(dplane_ctx_rule_get_ifname(ctx), in_ifindex,
113 dp_flow_ptr);
114 break;
115
116 default:;
117 }
118 }
119
120
121 /* DPDK provider callback.
122 */
123 static void zd_dpdk_process_update(struct zebra_dplane_ctx *ctx)
124 {
125 switch (dplane_ctx_get_op(ctx)) {
126
127 case DPLANE_OP_RULE_ADD:
128 case DPLANE_OP_RULE_UPDATE:
129 case DPLANE_OP_RULE_DELETE:
130 zd_dpdk_rule_update(ctx);
131 break;
132
133 default:
134 atomic_fetch_add_explicit(&dpdk_stat->ignored_updates, 1,
135 memory_order_relaxed);
136
137 break;
138 }
139 }
140
141
142 static int zd_dpdk_process(struct zebra_dplane_provider *prov)
143 {
144 struct zebra_dplane_ctx *ctx;
145 int counter, limit;
146
147 if (IS_ZEBRA_DEBUG_DPLANE_DPDK_DETAIL)
148 zlog_debug("processing %s", dplane_provider_get_name(prov));
149
150 limit = dplane_provider_get_work_limit(prov);
151 for (counter = 0; counter < limit; counter++) {
152 ctx = dplane_provider_dequeue_in_ctx(prov);
153 if (!ctx)
154 break;
155
156 zd_dpdk_process_update(ctx);
157 dplane_ctx_set_status(ctx, ZEBRA_DPLANE_REQUEST_SUCCESS);
158 dplane_provider_enqueue_out_ctx(prov, ctx);
159 }
160
161 return 0;
162 }
163
164 static int zd_dpdk_init(void)
165 {
166 int rc;
167 char *argv[] = {(char *)"/usr/lib/frr/zebra", (char *)"--"};
168
169 zd_dpdk_vty_init();
170
171 frr_with_privs (&zserv_privs) {
172 rc = rte_eal_init(sizeof(argv) / sizeof(argv[0]), argv);
173 }
174 if (rc < 0) {
175 zlog_warn("EAL init failed %s", rte_strerror(rte_errno));
176 return -1;
177 }
178
179 return 0;
180 }
181
182 static int zd_dpdk_start(struct zebra_dplane_provider *prov)
183 {
184 if (IS_ZEBRA_DEBUG_DPLANE_DPDK)
185 zlog_debug("%s start", dplane_provider_get_name(prov));
186
187 return zd_dpdk_init();
188 }
189
190
191 static int zd_dpdk_finish(struct zebra_dplane_provider *prov, bool early)
192 {
193 int rc;
194
195 if (early) {
196 if (IS_ZEBRA_DEBUG_DPLANE_DPDK)
197 zlog_debug("%s early finish",
198 dplane_provider_get_name(prov));
199
200 return 0;
201 }
202
203 if (IS_ZEBRA_DEBUG_DPLANE_DPDK)
204 zlog_debug("%s finish", dplane_provider_get_name(prov));
205
206
207 frr_with_privs (&zserv_privs) {
208 rc = rte_eal_cleanup();
209 }
210 if (rc < 0)
211 zlog_warn("EAL cleanup failed %s", rte_strerror(rte_errno));
212
213 return 0;
214 }
215
216
217 static int zd_dpdk_plugin_init(struct thread_master *tm)
218 {
219 int ret;
220
221 ret = dplane_provider_register(
222 plugin_name, DPLANE_PRIO_KERNEL, DPLANE_PROV_FLAGS_DEFAULT,
223 zd_dpdk_start, zd_dpdk_process, zd_dpdk_finish, dpdk_ctx, NULL);
224
225 if (IS_ZEBRA_DEBUG_DPLANE_DPDK)
226 zlog_debug("%s register status %d", plugin_name, ret);
227
228 return 0;
229 }
230
231
232 static int zd_dpdk_module_init(void)
233 {
234 hook_register(frr_late_init, zd_dpdk_plugin_init);
235 return 0;
236 }
237
238 FRR_MODULE_SETUP(.name = "dplane_dpdk", .version = "0.0.1",
239 .description = "Data plane plugin using dpdk for hw offload",
240 .init = zd_dpdk_module_init, );