]> git.proxmox.com Git - mirror_frr.git/blob - lib/zclient.c
Merge pull request #7840 from pguibert6WIND/bfd_misc_fixes_vrflite
[mirror_frr.git] / lib / zclient.c
1 /* Zebra's client library.
2 * Copyright (C) 1999 Kunihiro Ishiguro
3 * Copyright (C) 2005 Andrew J. Schorr
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published
9 * by the Free Software Foundation; either version 2, or (at your
10 * option) any later version.
11 *
12 * GNU Zebra 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 #include <zebra.h>
23
24 #include "prefix.h"
25 #include "stream.h"
26 #include "buffer.h"
27 #include "network.h"
28 #include "vrf.h"
29 #include "vrf_int.h"
30 #include "if.h"
31 #include "log.h"
32 #include "thread.h"
33 #include "zclient.h"
34 #include "memory.h"
35 #include "table.h"
36 #include "nexthop.h"
37 #include "mpls.h"
38 #include "sockopt.h"
39 #include "pbr.h"
40 #include "nexthop_group.h"
41 #include "lib_errors.h"
42 #include "srte.h"
43 #include "printfrr.h"
44
45 DEFINE_MTYPE_STATIC(LIB, ZCLIENT, "Zclient")
46 DEFINE_MTYPE_STATIC(LIB, REDIST_INST, "Redistribution instance IDs")
47
48 /* Zebra client events. */
49 enum event { ZCLIENT_SCHEDULE, ZCLIENT_READ, ZCLIENT_CONNECT };
50
51 /* Prototype for event manager. */
52 static void zclient_event(enum event, struct zclient *);
53
54 static void zebra_interface_if_set_value(struct stream *s,
55 struct interface *ifp);
56
57 struct zclient_options zclient_options_default = {.receive_notify = false,
58 .synchronous = false};
59
60 struct sockaddr_storage zclient_addr;
61 socklen_t zclient_addr_len;
62
63 /* This file local debug flag. */
64 static int zclient_debug;
65
66 /* Allocate zclient structure. */
67 struct zclient *zclient_new(struct thread_master *master,
68 struct zclient_options *opt)
69 {
70 struct zclient *zclient;
71 size_t stream_size =
72 MAX(ZEBRA_MAX_PACKET_SIZ, sizeof(struct zapi_route));
73
74 zclient = XCALLOC(MTYPE_ZCLIENT, sizeof(struct zclient));
75
76 zclient->ibuf = stream_new(stream_size);
77 zclient->obuf = stream_new(stream_size);
78 zclient->wb = buffer_new(0);
79 zclient->master = master;
80
81 zclient->receive_notify = opt->receive_notify;
82 zclient->synchronous = opt->synchronous;
83
84 return zclient;
85 }
86
87 /* This function is only called when exiting, because
88 many parts of the code do not check for I/O errors, so they could
89 reference an invalid pointer if the structure was ever freed.
90
91 Free zclient structure. */
92 void zclient_free(struct zclient *zclient)
93 {
94 if (zclient->ibuf)
95 stream_free(zclient->ibuf);
96 if (zclient->obuf)
97 stream_free(zclient->obuf);
98 if (zclient->wb)
99 buffer_free(zclient->wb);
100
101 XFREE(MTYPE_ZCLIENT, zclient);
102 }
103
104 unsigned short *redist_check_instance(struct redist_proto *red,
105 unsigned short instance)
106 {
107 struct listnode *node;
108 unsigned short *id;
109
110 if (!red->instances)
111 return NULL;
112
113 for (ALL_LIST_ELEMENTS_RO(red->instances, node, id))
114 if (*id == instance)
115 return id;
116
117 return NULL;
118 }
119
120 void redist_add_instance(struct redist_proto *red, unsigned short instance)
121 {
122 unsigned short *in;
123
124 red->enabled = 1;
125
126 if (!red->instances)
127 red->instances = list_new();
128
129 in = XMALLOC(MTYPE_REDIST_INST, sizeof(unsigned short));
130 *in = instance;
131 listnode_add(red->instances, in);
132 }
133
134 void redist_del_instance(struct redist_proto *red, unsigned short instance)
135 {
136 unsigned short *id;
137
138 id = redist_check_instance(red, instance);
139 if (!id)
140 return;
141
142 listnode_delete(red->instances, id);
143 XFREE(MTYPE_REDIST_INST, id);
144 if (!red->instances->count) {
145 red->enabled = 0;
146 list_delete(&red->instances);
147 }
148 }
149
150 void redist_del_all_instances(struct redist_proto *red)
151 {
152 struct listnode *ln, *nn;
153 unsigned short *id;
154
155 if (!red->instances)
156 return;
157
158 for (ALL_LIST_ELEMENTS(red->instances, ln, nn, id))
159 redist_del_instance(red, *id);
160 }
161
162 /* Stop zebra client services. */
163 void zclient_stop(struct zclient *zclient)
164 {
165 afi_t afi;
166 int i;
167
168 if (zclient_debug)
169 zlog_debug("zclient %p stopped", zclient);
170
171 /* Stop threads. */
172 THREAD_OFF(zclient->t_read);
173 THREAD_OFF(zclient->t_connect);
174 THREAD_OFF(zclient->t_write);
175
176 /* Reset streams. */
177 stream_reset(zclient->ibuf);
178 stream_reset(zclient->obuf);
179
180 /* Empty the write buffer. */
181 buffer_reset(zclient->wb);
182
183 /* Close socket. */
184 if (zclient->sock >= 0) {
185 close(zclient->sock);
186 zclient->sock = -1;
187 }
188 zclient->fail = 0;
189
190 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
191 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
192 vrf_bitmap_free(zclient->redist[afi][i]);
193 zclient->redist[afi][i] = VRF_BITMAP_NULL;
194 }
195 redist_del_instance(
196 &zclient->mi_redist[afi][zclient->redist_default],
197 zclient->instance);
198
199 vrf_bitmap_free(zclient->default_information[afi]);
200 zclient->default_information[afi] = VRF_BITMAP_NULL;
201 }
202 }
203
204 void zclient_reset(struct zclient *zclient)
205 {
206 afi_t afi;
207
208 zclient_stop(zclient);
209
210 for (afi = AFI_IP; afi < AFI_MAX; afi++)
211 redist_del_instance(
212 &zclient->mi_redist[afi][zclient->redist_default],
213 zclient->instance);
214
215 zclient_init(zclient, zclient->redist_default, zclient->instance,
216 zclient->privs);
217 }
218
219 /**
220 * Connect to zebra daemon.
221 * @param zclient a pointer to zclient structure
222 * @return socket fd just to make sure that connection established
223 * @see zclient_init
224 * @see zclient_new
225 */
226 int zclient_socket_connect(struct zclient *zclient)
227 {
228 int sock;
229 int ret;
230
231 /* We should think about IPv6 connection. */
232 sock = socket(zclient_addr.ss_family, SOCK_STREAM, 0);
233 if (sock < 0)
234 return -1;
235
236 set_cloexec(sock);
237 setsockopt_so_sendbuf(sock, 1048576);
238
239 /* Connect to zebra. */
240 ret = connect(sock, (struct sockaddr *)&zclient_addr, zclient_addr_len);
241 if (ret < 0) {
242 if (zclient_debug)
243 zlog_debug("%s connect failure: %d(%s)", __func__,
244 errno, safe_strerror(errno));
245 close(sock);
246 return -1;
247 }
248
249 zclient->sock = sock;
250 return sock;
251 }
252
253 static enum zclient_send_status zclient_failed(struct zclient *zclient)
254 {
255 zclient->fail++;
256 zclient_stop(zclient);
257 zclient_event(ZCLIENT_CONNECT, zclient);
258 return ZCLIENT_SEND_FAILURE;
259 }
260
261 static int zclient_flush_data(struct thread *thread)
262 {
263 struct zclient *zclient = THREAD_ARG(thread);
264
265 zclient->t_write = NULL;
266 if (zclient->sock < 0)
267 return -1;
268 switch (buffer_flush_available(zclient->wb, zclient->sock)) {
269 case BUFFER_ERROR:
270 flog_err(
271 EC_LIB_ZAPI_SOCKET,
272 "%s: buffer_flush_available failed on zclient fd %d, closing",
273 __func__, zclient->sock);
274 return zclient_failed(zclient);
275 case BUFFER_PENDING:
276 zclient->t_write = NULL;
277 thread_add_write(zclient->master, zclient_flush_data, zclient,
278 zclient->sock, &zclient->t_write);
279 break;
280 case BUFFER_EMPTY:
281 if (zclient->zebra_buffer_write_ready)
282 (*zclient->zebra_buffer_write_ready)();
283 break;
284 }
285 return 0;
286 }
287
288 /*
289 * Returns:
290 * ZCLIENT_SEND_FAILED - is a failure
291 * ZCLIENT_SEND_SUCCESS - means we sent data to zebra
292 * ZCLIENT_SEND_BUFFERED - means we are buffering
293 */
294 enum zclient_send_status zclient_send_message(struct zclient *zclient)
295 {
296 if (zclient->sock < 0)
297 return ZCLIENT_SEND_FAILURE;
298 switch (buffer_write(zclient->wb, zclient->sock,
299 STREAM_DATA(zclient->obuf),
300 stream_get_endp(zclient->obuf))) {
301 case BUFFER_ERROR:
302 flog_err(EC_LIB_ZAPI_SOCKET,
303 "%s: buffer_write failed to zclient fd %d, closing",
304 __func__, zclient->sock);
305 return zclient_failed(zclient);
306 case BUFFER_EMPTY:
307 THREAD_OFF(zclient->t_write);
308 return ZCLIENT_SEND_SUCCESS;
309 case BUFFER_PENDING:
310 thread_add_write(zclient->master, zclient_flush_data, zclient,
311 zclient->sock, &zclient->t_write);
312 return ZCLIENT_SEND_BUFFERED;
313 }
314
315 /* should not get here */
316 return ZCLIENT_SEND_SUCCESS;
317 }
318
319 /*
320 * If we add more data to this structure please ensure that
321 * struct zmsghdr in lib/zclient.h is updated as appropriate.
322 */
323 void zclient_create_header(struct stream *s, uint16_t command, vrf_id_t vrf_id)
324 {
325 /* length placeholder, caller can update */
326 stream_putw(s, ZEBRA_HEADER_SIZE);
327 stream_putc(s, ZEBRA_HEADER_MARKER);
328 stream_putc(s, ZSERV_VERSION);
329 stream_putl(s, vrf_id);
330 stream_putw(s, command);
331 }
332
333 int zclient_read_header(struct stream *s, int sock, uint16_t *size,
334 uint8_t *marker, uint8_t *version, vrf_id_t *vrf_id,
335 uint16_t *cmd)
336 {
337 if (stream_read(s, sock, ZEBRA_HEADER_SIZE) != ZEBRA_HEADER_SIZE)
338 return -1;
339
340 STREAM_GETW(s, *size);
341 *size -= ZEBRA_HEADER_SIZE;
342 STREAM_GETC(s, *marker);
343 STREAM_GETC(s, *version);
344 STREAM_GETL(s, *vrf_id);
345 STREAM_GETW(s, *cmd);
346
347 if (*version != ZSERV_VERSION || *marker != ZEBRA_HEADER_MARKER) {
348 flog_err(
349 EC_LIB_ZAPI_MISSMATCH,
350 "%s: socket %d version mismatch, marker %d, version %d",
351 __func__, sock, *marker, *version);
352 return -1;
353 }
354
355 if (*size && stream_read(s, sock, *size) != *size)
356 return -1;
357
358 return 0;
359 stream_failure:
360 return -1;
361 }
362
363 bool zapi_parse_header(struct stream *zmsg, struct zmsghdr *hdr)
364 {
365 STREAM_GETW(zmsg, hdr->length);
366 STREAM_GETC(zmsg, hdr->marker);
367 STREAM_GETC(zmsg, hdr->version);
368 STREAM_GETL(zmsg, hdr->vrf_id);
369 STREAM_GETW(zmsg, hdr->command);
370 return true;
371 stream_failure:
372 return false;
373 }
374
375 /* Send simple Zebra message. */
376 static enum zclient_send_status zebra_message_send(struct zclient *zclient,
377 int command, vrf_id_t vrf_id)
378 {
379 struct stream *s;
380
381 /* Get zclient output buffer. */
382 s = zclient->obuf;
383 stream_reset(s);
384
385 /* Send very simple command only Zebra message. */
386 zclient_create_header(s, command, vrf_id);
387
388 return zclient_send_message(zclient);
389 }
390
391 enum zclient_send_status zclient_send_hello(struct zclient *zclient)
392 {
393 struct stream *s;
394
395 if (zclient->redist_default || zclient->synchronous) {
396 s = zclient->obuf;
397 stream_reset(s);
398
399 /* The VRF ID in the HELLO message is always 0. */
400 zclient_create_header(s, ZEBRA_HELLO, VRF_DEFAULT);
401 stream_putc(s, zclient->redist_default);
402 stream_putw(s, zclient->instance);
403 stream_putl(s, zclient->session_id);
404 if (zclient->receive_notify)
405 stream_putc(s, 1);
406 else
407 stream_putc(s, 0);
408 if (zclient->synchronous)
409 stream_putc(s, 1);
410 else
411 stream_putc(s, 0);
412
413 stream_putw_at(s, 0, stream_get_endp(s));
414 return zclient_send_message(zclient);
415 }
416
417 return ZCLIENT_SEND_SUCCESS;
418 }
419
420 enum zclient_send_status zclient_send_vrf_label(struct zclient *zclient,
421 vrf_id_t vrf_id, afi_t afi,
422 mpls_label_t label,
423 enum lsp_types_t ltype)
424 {
425 struct stream *s;
426
427 s = zclient->obuf;
428 stream_reset(s);
429
430 zclient_create_header(s, ZEBRA_VRF_LABEL, vrf_id);
431 stream_putl(s, label);
432 stream_putc(s, afi);
433 stream_putc(s, ltype);
434 stream_putw_at(s, 0, stream_get_endp(s));
435 return zclient_send_message(zclient);
436 }
437
438 /* Send register requests to zebra daemon for the information in a VRF. */
439 void zclient_send_reg_requests(struct zclient *zclient, vrf_id_t vrf_id)
440 {
441 int i;
442 afi_t afi;
443
444 /* If not connected to the zebra yet. */
445 if (zclient->sock < 0)
446 return;
447
448 if (zclient_debug)
449 zlog_debug("%s: send register messages for VRF %u", __func__,
450 vrf_id);
451
452 /* We need router-id information. */
453 zclient_send_router_id_update(zclient, ZEBRA_ROUTER_ID_ADD, AFI_IP,
454 vrf_id);
455
456 /* We need interface information. */
457 zebra_message_send(zclient, ZEBRA_INTERFACE_ADD, vrf_id);
458
459 /* Set unwanted redistribute route. */
460 for (afi = AFI_IP; afi < AFI_MAX; afi++)
461 vrf_bitmap_set(zclient->redist[afi][zclient->redist_default],
462 vrf_id);
463
464 /* Flush all redistribute request. */
465 if (vrf_id == VRF_DEFAULT) {
466 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
467 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
468 if (!zclient->mi_redist[afi][i].enabled)
469 continue;
470
471 struct listnode *node;
472 unsigned short *id;
473
474 for (ALL_LIST_ELEMENTS_RO(
475 zclient->mi_redist[afi][i]
476 .instances,
477 node, id))
478 if (!(i == zclient->redist_default
479 && *id == zclient->instance))
480 zebra_redistribute_send(
481 ZEBRA_REDISTRIBUTE_ADD,
482 zclient, afi, i, *id,
483 VRF_DEFAULT);
484 }
485 }
486 }
487
488 /* Resend all redistribute request. */
489 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
490 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
491 if (i != zclient->redist_default
492 && vrf_bitmap_check(zclient->redist[afi][i],
493 vrf_id))
494 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD,
495 zclient, afi, i, 0,
496 vrf_id);
497
498 /* If default information is needed. */
499 if (vrf_bitmap_check(zclient->default_information[afi], vrf_id))
500 zebra_redistribute_default_send(
501 ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient, afi,
502 vrf_id);
503 }
504 }
505
506 /* Send unregister requests to zebra daemon for the information in a VRF. */
507 void zclient_send_dereg_requests(struct zclient *zclient, vrf_id_t vrf_id)
508 {
509 int i;
510 afi_t afi;
511
512 /* If not connected to the zebra yet. */
513 if (zclient->sock < 0)
514 return;
515
516 if (zclient_debug)
517 zlog_debug("%s: send deregister messages for VRF %u", __func__,
518 vrf_id);
519
520 /* We need router-id information. */
521 zclient_send_router_id_update(zclient, ZEBRA_ROUTER_ID_DELETE, AFI_IP,
522 vrf_id);
523
524 zebra_message_send(zclient, ZEBRA_INTERFACE_DELETE, vrf_id);
525
526 /* Set unwanted redistribute route. */
527 for (afi = AFI_IP; afi < AFI_MAX; afi++)
528 vrf_bitmap_unset(zclient->redist[afi][zclient->redist_default],
529 vrf_id);
530
531 /* Flush all redistribute request. */
532 if (vrf_id == VRF_DEFAULT) {
533 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
534 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
535 if (!zclient->mi_redist[afi][i].enabled)
536 continue;
537
538 struct listnode *node;
539 unsigned short *id;
540
541 for (ALL_LIST_ELEMENTS_RO(
542 zclient->mi_redist[afi][i]
543 .instances,
544 node, id))
545 if (!(i == zclient->redist_default
546 && *id == zclient->instance))
547 zebra_redistribute_send(
548 ZEBRA_REDISTRIBUTE_DELETE,
549 zclient, afi, i, *id,
550 VRF_DEFAULT);
551 }
552 }
553 }
554
555 /* Flush all redistribute request. */
556 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
557 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
558 if (i != zclient->redist_default
559 && vrf_bitmap_check(zclient->redist[afi][i],
560 vrf_id))
561 zebra_redistribute_send(
562 ZEBRA_REDISTRIBUTE_DELETE, zclient, afi,
563 i, 0, vrf_id);
564
565 /* If default information is needed. */
566 if (vrf_bitmap_check(zclient->default_information[afi], vrf_id))
567 zebra_redistribute_default_send(
568 ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient, afi,
569 vrf_id);
570 }
571 }
572
573 enum zclient_send_status
574 zclient_send_router_id_update(struct zclient *zclient,
575 zebra_message_types_t type, afi_t afi,
576 vrf_id_t vrf_id)
577 {
578 struct stream *s = zclient->obuf;
579 stream_reset(s);
580 zclient_create_header(s, type, vrf_id);
581 stream_putw(s, afi);
582 stream_putw_at(s, 0, stream_get_endp(s));
583 return zclient_send_message(zclient);
584 }
585
586 /* Send request to zebra daemon to start or stop RA. */
587 enum zclient_send_status
588 zclient_send_interface_radv_req(struct zclient *zclient, vrf_id_t vrf_id,
589 struct interface *ifp, int enable,
590 int ra_interval)
591 {
592 struct stream *s;
593
594 /* If not connected to the zebra yet. */
595 if (zclient->sock < 0)
596 return ZCLIENT_SEND_FAILURE;
597
598 /* Form and send message. */
599 s = zclient->obuf;
600 stream_reset(s);
601
602 if (enable)
603 zclient_create_header(s, ZEBRA_INTERFACE_ENABLE_RADV, vrf_id);
604 else
605 zclient_create_header(s, ZEBRA_INTERFACE_DISABLE_RADV, vrf_id);
606
607 stream_putl(s, ifp->ifindex);
608 stream_putl(s, ra_interval);
609
610 stream_putw_at(s, 0, stream_get_endp(s));
611
612 return zclient_send_message(zclient);
613 }
614
615 enum zclient_send_status
616 zclient_send_interface_protodown(struct zclient *zclient, vrf_id_t vrf_id,
617 struct interface *ifp, bool down)
618 {
619 struct stream *s;
620
621 if (zclient->sock < 0)
622 return ZCLIENT_SEND_FAILURE;
623
624 s = zclient->obuf;
625 stream_reset(s);
626 zclient_create_header(s, ZEBRA_INTERFACE_SET_PROTODOWN, vrf_id);
627 stream_putl(s, ifp->ifindex);
628 stream_putc(s, !!down);
629 stream_putw_at(s, 0, stream_get_endp(s));
630 return zclient_send_message(zclient);
631 }
632
633 /* Make connection to zebra daemon. */
634 int zclient_start(struct zclient *zclient)
635 {
636 if (zclient_debug)
637 zlog_info("zclient_start is called");
638
639 /* If already connected to the zebra. */
640 if (zclient->sock >= 0)
641 return 0;
642
643 /* Check connect thread. */
644 if (zclient->t_connect)
645 return 0;
646
647 if (zclient_socket_connect(zclient) < 0) {
648 if (zclient_debug)
649 zlog_debug("zclient connection fail");
650 zclient->fail++;
651 zclient_event(ZCLIENT_CONNECT, zclient);
652 return -1;
653 }
654
655 if (set_nonblocking(zclient->sock) < 0)
656 flog_err(EC_LIB_ZAPI_SOCKET, "%s: set_nonblocking(%d) failed",
657 __func__, zclient->sock);
658
659 /* Clear fail count. */
660 zclient->fail = 0;
661 if (zclient_debug)
662 zlog_debug("zclient connect success with socket [%d]",
663 zclient->sock);
664
665 /* Create read thread. */
666 zclient_event(ZCLIENT_READ, zclient);
667
668 zclient_send_hello(zclient);
669
670 zebra_message_send(zclient, ZEBRA_INTERFACE_ADD, VRF_DEFAULT);
671
672 /* Inform the successful connection. */
673 if (zclient->zebra_connected)
674 (*zclient->zebra_connected)(zclient);
675
676 return 0;
677 }
678
679 /* Initialize zebra client. Argument redist_default is unwanted
680 redistribute route type. */
681 void zclient_init(struct zclient *zclient, int redist_default,
682 unsigned short instance, struct zebra_privs_t *privs)
683 {
684 int afi, i;
685
686 /* Set -1 to the default socket value. */
687 zclient->sock = -1;
688 zclient->privs = privs;
689
690 /* Clear redistribution flags. */
691 for (afi = AFI_IP; afi < AFI_MAX; afi++)
692 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
693 zclient->redist[afi][i] = vrf_bitmap_init();
694
695 /* Set unwanted redistribute route. bgpd does not need BGP route
696 redistribution. */
697 zclient->redist_default = redist_default;
698 zclient->instance = instance;
699 /* Pending: make afi(s) an arg. */
700 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
701 redist_add_instance(&zclient->mi_redist[afi][redist_default],
702 instance);
703
704 /* Set default-information redistribute to zero. */
705 zclient->default_information[afi] = vrf_bitmap_init();
706 }
707
708 if (zclient_debug)
709 zlog_debug("scheduling zclient connection");
710
711 zclient_event(ZCLIENT_SCHEDULE, zclient);
712 }
713
714 /* This function is a wrapper function for calling zclient_start from
715 timer or event thread. */
716 static int zclient_connect(struct thread *t)
717 {
718 struct zclient *zclient;
719
720 zclient = THREAD_ARG(t);
721 zclient->t_connect = NULL;
722
723 if (zclient_debug)
724 zlog_debug("zclient_connect is called");
725
726 return zclient_start(zclient);
727 }
728
729 enum zclient_send_status zclient_send_rnh(struct zclient *zclient, int command,
730 const struct prefix *p,
731 bool exact_match, vrf_id_t vrf_id)
732 {
733 struct stream *s;
734
735 s = zclient->obuf;
736 stream_reset(s);
737 zclient_create_header(s, command, vrf_id);
738 stream_putc(s, (exact_match) ? 1 : 0);
739
740 stream_putw(s, PREFIX_FAMILY(p));
741 stream_putc(s, p->prefixlen);
742 switch (PREFIX_FAMILY(p)) {
743 case AF_INET:
744 stream_put_in_addr(s, &p->u.prefix4);
745 break;
746 case AF_INET6:
747 stream_put(s, &(p->u.prefix6), 16);
748 break;
749 default:
750 break;
751 }
752 stream_putw_at(s, 0, stream_get_endp(s));
753
754 return zclient_send_message(zclient);
755 }
756
757 /*
758 * "xdr_encode"-like interface that allows daemon (client) to send
759 * a message to zebra server for a route that needs to be
760 * added/deleted to the kernel. Info about the route is specified
761 * by the caller in a struct zapi_route. zapi_route_encode() then writes
762 * the info down the zclient socket using the stream_* functions.
763 *
764 * The corresponding read ("xdr_decode") function on the server
765 * side is zapi_route_decode().
766 *
767 * If ZAPI_MESSAGE_DISTANCE is set, the distance value is written as a 1
768 * byte value.
769 *
770 * If ZAPI_MESSAGE_METRIC is set, the metric value is written as a 4
771 * byte value.
772 *
773 * If ZAPI_MESSAGE_TAG is set, the tag value is written as a 4 byte value
774 *
775 * If ZAPI_MESSAGE_MTU is set, the mtu value is written as a 4 byte value
776 *
777 * XXX: No attention paid to alignment.
778 */
779 enum zclient_send_status
780 zclient_route_send(uint8_t cmd, struct zclient *zclient, struct zapi_route *api)
781 {
782 if (zapi_route_encode(cmd, zclient->obuf, api) < 0)
783 return ZCLIENT_SEND_FAILURE;
784 return zclient_send_message(zclient);
785 }
786
787 static int zapi_nexthop_labels_cmp(const struct zapi_nexthop *next1,
788 const struct zapi_nexthop *next2)
789 {
790 if (next1->label_num > next2->label_num)
791 return 1;
792
793 if (next1->label_num < next2->label_num)
794 return -1;
795
796 return memcmp(next1->labels, next2->labels, next1->label_num);
797 }
798
799 static int zapi_nexthop_cmp_no_labels(const struct zapi_nexthop *next1,
800 const struct zapi_nexthop *next2)
801 {
802 int ret = 0;
803
804 if (next1->vrf_id < next2->vrf_id)
805 return -1;
806
807 if (next1->vrf_id > next2->vrf_id)
808 return 1;
809
810 if (next1->type < next2->type)
811 return -1;
812
813 if (next1->type > next2->type)
814 return 1;
815
816 if (next1->weight < next2->weight)
817 return -1;
818
819 if (next1->weight > next2->weight)
820 return 1;
821
822 switch (next1->type) {
823 case NEXTHOP_TYPE_IPV4:
824 case NEXTHOP_TYPE_IPV6:
825 ret = nexthop_g_addr_cmp(next1->type, &next1->gate,
826 &next2->gate);
827 if (ret != 0)
828 return ret;
829 break;
830 case NEXTHOP_TYPE_IPV4_IFINDEX:
831 case NEXTHOP_TYPE_IPV6_IFINDEX:
832 ret = nexthop_g_addr_cmp(next1->type, &next1->gate,
833 &next2->gate);
834 if (ret != 0)
835 return ret;
836 /* Intentional Fall-Through */
837 case NEXTHOP_TYPE_IFINDEX:
838 if (next1->ifindex < next2->ifindex)
839 return -1;
840
841 if (next1->ifindex > next2->ifindex)
842 return 1;
843 break;
844 case NEXTHOP_TYPE_BLACKHOLE:
845 if (next1->bh_type < next2->bh_type)
846 return -1;
847
848 if (next1->bh_type > next2->bh_type)
849 return 1;
850 break;
851 }
852
853 if (next1->srte_color < next2->srte_color)
854 return -1;
855 if (next1->srte_color > next2->srte_color)
856 return 1;
857
858 if (CHECK_FLAG(next1->flags, NEXTHOP_FLAG_HAS_BACKUP) ||
859 CHECK_FLAG(next2->flags, NEXTHOP_FLAG_HAS_BACKUP)) {
860
861 if (!CHECK_FLAG(next1->flags, NEXTHOP_FLAG_HAS_BACKUP) &&
862 CHECK_FLAG(next2->flags, NEXTHOP_FLAG_HAS_BACKUP))
863 return -1;
864
865 if (CHECK_FLAG(next1->flags, NEXTHOP_FLAG_HAS_BACKUP) &&
866 !CHECK_FLAG(next2->flags, NEXTHOP_FLAG_HAS_BACKUP))
867 return 1;
868
869 if (next1->backup_num > 0 || next2->backup_num > 0) {
870
871 if (next1->backup_num < next2->backup_num)
872 return -1;
873
874 if (next1->backup_num > next2->backup_num)
875 return 1;
876
877 ret = memcmp(next1->backup_idx,
878 next2->backup_idx, next1->backup_num);
879 if (ret != 0)
880 return ret;
881 }
882 }
883
884 return 0;
885 }
886
887 static int zapi_nexthop_cmp(const void *item1, const void *item2)
888 {
889 int ret = 0;
890
891 const struct zapi_nexthop *next1 = item1;
892 const struct zapi_nexthop *next2 = item2;
893
894 ret = zapi_nexthop_cmp_no_labels(next1, next2);
895 if (ret != 0)
896 return ret;
897
898 ret = zapi_nexthop_labels_cmp(next1, next2);
899
900 return ret;
901 }
902
903 static void zapi_nexthop_group_sort(struct zapi_nexthop *nh_grp,
904 uint16_t nexthop_num)
905 {
906 qsort(nh_grp, nexthop_num, sizeof(struct zapi_nexthop),
907 &zapi_nexthop_cmp);
908 }
909
910 /*
911 * Encode a single zapi nexthop
912 */
913 int zapi_nexthop_encode(struct stream *s, const struct zapi_nexthop *api_nh,
914 uint32_t api_flags, uint32_t api_message)
915 {
916 int i, ret = 0;
917 int nh_flags = api_nh->flags;
918
919 stream_putl(s, api_nh->vrf_id);
920 stream_putc(s, api_nh->type);
921
922 /* If needed, set 'labelled nexthop' flag */
923 if (api_nh->label_num > 0) {
924 SET_FLAG(nh_flags, ZAPI_NEXTHOP_FLAG_LABEL);
925
926 /* Validate label count */
927 if (api_nh->label_num > MPLS_MAX_LABELS) {
928 ret = -1;
929 goto done;
930 }
931 }
932
933 /* If present, set 'weight' flag before encoding flags */
934 if (api_nh->weight)
935 SET_FLAG(nh_flags, ZAPI_NEXTHOP_FLAG_WEIGHT);
936
937 /* Note that we're only encoding a single octet */
938 stream_putc(s, nh_flags);
939
940 switch (api_nh->type) {
941 case NEXTHOP_TYPE_BLACKHOLE:
942 stream_putc(s, api_nh->bh_type);
943 break;
944 case NEXTHOP_TYPE_IPV4:
945 case NEXTHOP_TYPE_IPV4_IFINDEX:
946 stream_put_in_addr(s, &api_nh->gate.ipv4);
947 stream_putl(s, api_nh->ifindex);
948 break;
949 case NEXTHOP_TYPE_IFINDEX:
950 stream_putl(s, api_nh->ifindex);
951 break;
952 case NEXTHOP_TYPE_IPV6:
953 case NEXTHOP_TYPE_IPV6_IFINDEX:
954 stream_write(s, (uint8_t *)&api_nh->gate.ipv6,
955 16);
956 stream_putl(s, api_nh->ifindex);
957 break;
958 }
959
960 /* We only encode labels if we have >0 - we use
961 * the per-nexthop flag above to signal that the count
962 * is present in the payload.
963 */
964 if (api_nh->label_num > 0) {
965 stream_putc(s, api_nh->label_num);
966 stream_put(s, &api_nh->labels[0],
967 api_nh->label_num * sizeof(mpls_label_t));
968 }
969
970 if (api_nh->weight)
971 stream_putl(s, api_nh->weight);
972
973 /* Router MAC for EVPN routes. */
974 if (CHECK_FLAG(api_flags, ZEBRA_FLAG_EVPN_ROUTE))
975 stream_put(s, &(api_nh->rmac),
976 sizeof(struct ethaddr));
977
978 /* Color for Segment Routing TE. */
979 if (CHECK_FLAG(api_message, ZAPI_MESSAGE_SRTE))
980 stream_putl(s, api_nh->srte_color);
981
982 /* Index of backup nexthop */
983 if (CHECK_FLAG(nh_flags, ZAPI_NEXTHOP_FLAG_HAS_BACKUP)) {
984 /* Validate backup count */
985 if (api_nh->backup_num > NEXTHOP_MAX_BACKUPS) {
986 ret = -1;
987 goto done;
988 }
989
990 stream_putc(s, api_nh->backup_num);
991 for (i = 0; i < api_nh->backup_num; i++)
992 stream_putc(s, api_nh->backup_idx[i]);
993 }
994
995 done:
996 return ret;
997 }
998
999 int zapi_nhg_encode(struct stream *s, int cmd, struct zapi_nhg *api_nhg)
1000 {
1001 int i;
1002
1003 if (cmd != ZEBRA_NHG_DEL && cmd != ZEBRA_NHG_ADD) {
1004 flog_err(EC_LIB_ZAPI_ENCODE,
1005 "%s: Specified zapi NHG command (%d) doesn't exist\n",
1006 __func__, cmd);
1007 return -1;
1008 }
1009
1010 stream_reset(s);
1011 zclient_create_header(s, cmd, VRF_DEFAULT);
1012
1013 stream_putw(s, api_nhg->proto);
1014 stream_putl(s, api_nhg->id);
1015
1016 if (cmd == ZEBRA_NHG_ADD) {
1017 /* Nexthops */
1018 zapi_nexthop_group_sort(api_nhg->nexthops,
1019 api_nhg->nexthop_num);
1020
1021 stream_putw(s, api_nhg->nexthop_num);
1022
1023 for (i = 0; i < api_nhg->nexthop_num; i++)
1024 zapi_nexthop_encode(s, &api_nhg->nexthops[i], 0, 0);
1025
1026 /* Backup nexthops */
1027
1028 stream_putw(s, api_nhg->backup_nexthop_num);
1029
1030 for (i = 0; i < api_nhg->backup_nexthop_num; i++)
1031 zapi_nexthop_encode(s, &api_nhg->backup_nexthops[i], 0,
1032 0);
1033 }
1034
1035 stream_putw_at(s, 0, stream_get_endp(s));
1036
1037 return 0;
1038 }
1039
1040 enum zclient_send_status zclient_nhg_send(struct zclient *zclient, int cmd,
1041 struct zapi_nhg *api_nhg)
1042 {
1043 api_nhg->proto = zclient->redist_default;
1044
1045 if (zapi_nhg_encode(zclient->obuf, cmd, api_nhg))
1046 return -1;
1047
1048 return zclient_send_message(zclient);
1049 }
1050
1051 int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api)
1052 {
1053 struct zapi_nexthop *api_nh;
1054 int i;
1055 int psize;
1056
1057 stream_reset(s);
1058 zclient_create_header(s, cmd, api->vrf_id);
1059
1060 if (api->type >= ZEBRA_ROUTE_MAX) {
1061 flog_err(EC_LIB_ZAPI_ENCODE,
1062 "%s: Specified route type (%u) is not a legal value\n",
1063 __func__, api->type);
1064 return -1;
1065 }
1066 stream_putc(s, api->type);
1067
1068 stream_putw(s, api->instance);
1069 stream_putl(s, api->flags);
1070 stream_putl(s, api->message);
1071
1072 if (api->safi < SAFI_UNICAST || api->safi >= SAFI_MAX) {
1073 flog_err(EC_LIB_ZAPI_ENCODE,
1074 "%s: Specified route SAFI (%u) is not a legal value\n",
1075 __func__, api->safi);
1076 return -1;
1077 }
1078 stream_putc(s, api->safi);
1079
1080 /* Put prefix information. */
1081 stream_putc(s, api->prefix.family);
1082 psize = PSIZE(api->prefix.prefixlen);
1083 stream_putc(s, api->prefix.prefixlen);
1084 stream_write(s, &api->prefix.u.prefix, psize);
1085
1086 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_SRCPFX)) {
1087 psize = PSIZE(api->src_prefix.prefixlen);
1088 stream_putc(s, api->src_prefix.prefixlen);
1089 stream_write(s, (uint8_t *)&api->src_prefix.prefix, psize);
1090 }
1091
1092 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NHG))
1093 stream_putl(s, api->nhgid);
1094
1095 /* Nexthops. */
1096 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
1097 /* limit the number of nexthops if necessary */
1098 if (api->nexthop_num > MULTIPATH_NUM) {
1099 flog_err(
1100 EC_LIB_ZAPI_ENCODE,
1101 "%s: prefix %pFX: can't encode %u nexthops (maximum is %u)",
1102 __func__, &api->prefix, api->nexthop_num,
1103 MULTIPATH_NUM);
1104 return -1;
1105 }
1106
1107 /* We canonicalize the nexthops by sorting them; this allows
1108 * zebra to resolve the list of nexthops to a nexthop-group
1109 * more efficiently.
1110 */
1111 zapi_nexthop_group_sort(api->nexthops, api->nexthop_num);
1112
1113 stream_putw(s, api->nexthop_num);
1114
1115 for (i = 0; i < api->nexthop_num; i++) {
1116 api_nh = &api->nexthops[i];
1117
1118 /* MPLS labels for BGP-LU or Segment Routing */
1119 if (api_nh->label_num > MPLS_MAX_LABELS) {
1120 flog_err(
1121 EC_LIB_ZAPI_ENCODE,
1122 "%s: prefix %pFX: can't encode %u labels (maximum is %u)",
1123 __func__, &api->prefix,
1124 api_nh->label_num, MPLS_MAX_LABELS);
1125 return -1;
1126 }
1127
1128 if (zapi_nexthop_encode(s, api_nh, api->flags,
1129 api->message)
1130 != 0)
1131 return -1;
1132 }
1133 }
1134
1135 /* Backup nexthops */
1136 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_BACKUP_NEXTHOPS)) {
1137 /* limit the number of nexthops if necessary */
1138 if (api->backup_nexthop_num > MULTIPATH_NUM) {
1139 flog_err(
1140 EC_LIB_ZAPI_ENCODE,
1141 "%s: prefix %pFX: can't encode %u backup nexthops (maximum is %u)",
1142 __func__, &api->prefix, api->backup_nexthop_num,
1143 MULTIPATH_NUM);
1144 return -1;
1145 }
1146
1147 /* Note that we do not sort the list of backup nexthops -
1148 * this list is treated as an array and indexed by each
1149 * primary nexthop that is associated with a backup.
1150 */
1151
1152 stream_putw(s, api->backup_nexthop_num);
1153
1154 for (i = 0; i < api->backup_nexthop_num; i++) {
1155 api_nh = &api->backup_nexthops[i];
1156
1157 /* MPLS labels for BGP-LU or Segment Routing */
1158 if (api_nh->label_num > MPLS_MAX_LABELS) {
1159 flog_err(
1160 EC_LIB_ZAPI_ENCODE,
1161 "%s: prefix %pFX: backup: can't encode %u labels (maximum is %u)",
1162 __func__, &api->prefix,
1163 api_nh->label_num, MPLS_MAX_LABELS);
1164 return -1;
1165 }
1166
1167 if (zapi_nexthop_encode(s, api_nh, api->flags,
1168 api->message)
1169 != 0)
1170 return -1;
1171 }
1172 }
1173
1174 /* Attributes. */
1175 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
1176 stream_putc(s, api->distance);
1177 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
1178 stream_putl(s, api->metric);
1179 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
1180 stream_putl(s, api->tag);
1181 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
1182 stream_putl(s, api->mtu);
1183 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TABLEID))
1184 stream_putl(s, api->tableid);
1185
1186 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_OPAQUE)) {
1187 assert(api->opaque.length <= ZAPI_MESSAGE_OPAQUE_LENGTH);
1188
1189 stream_putw(s, api->opaque.length);
1190 stream_write(s, api->opaque.data, api->opaque.length);
1191 }
1192 /* Put length at the first point of the stream. */
1193 stream_putw_at(s, 0, stream_get_endp(s));
1194
1195 return 0;
1196 }
1197
1198 /*
1199 * Decode a single zapi nexthop object
1200 */
1201 int zapi_nexthop_decode(struct stream *s, struct zapi_nexthop *api_nh,
1202 uint32_t api_flags, uint32_t api_message)
1203 {
1204 int i, ret = -1;
1205
1206 STREAM_GETL(s, api_nh->vrf_id);
1207 STREAM_GETC(s, api_nh->type);
1208
1209 /* Note that we're only using a single octet of flags */
1210 STREAM_GETC(s, api_nh->flags);
1211
1212 switch (api_nh->type) {
1213 case NEXTHOP_TYPE_BLACKHOLE:
1214 STREAM_GETC(s, api_nh->bh_type);
1215 break;
1216 case NEXTHOP_TYPE_IPV4:
1217 case NEXTHOP_TYPE_IPV4_IFINDEX:
1218 STREAM_GET(&api_nh->gate.ipv4.s_addr, s,
1219 IPV4_MAX_BYTELEN);
1220 STREAM_GETL(s, api_nh->ifindex);
1221 break;
1222 case NEXTHOP_TYPE_IFINDEX:
1223 STREAM_GETL(s, api_nh->ifindex);
1224 break;
1225 case NEXTHOP_TYPE_IPV6:
1226 case NEXTHOP_TYPE_IPV6_IFINDEX:
1227 STREAM_GET(&api_nh->gate.ipv6, s, 16);
1228 STREAM_GETL(s, api_nh->ifindex);
1229 break;
1230 }
1231
1232 /* MPLS labels for BGP-LU or Segment Routing */
1233 if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_LABEL)) {
1234 STREAM_GETC(s, api_nh->label_num);
1235 if (api_nh->label_num > MPLS_MAX_LABELS) {
1236 flog_err(
1237 EC_LIB_ZAPI_ENCODE,
1238 "%s: invalid number of MPLS labels (%u)",
1239 __func__, api_nh->label_num);
1240 return -1;
1241 }
1242
1243 STREAM_GET(&api_nh->labels[0], s,
1244 api_nh->label_num * sizeof(mpls_label_t));
1245 }
1246
1247 if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_WEIGHT))
1248 STREAM_GETL(s, api_nh->weight);
1249
1250 /* Router MAC for EVPN routes. */
1251 if (CHECK_FLAG(api_flags, ZEBRA_FLAG_EVPN_ROUTE))
1252 STREAM_GET(&(api_nh->rmac), s,
1253 sizeof(struct ethaddr));
1254
1255 /* Color for Segment Routing TE. */
1256 if (CHECK_FLAG(api_message, ZAPI_MESSAGE_SRTE))
1257 STREAM_GETL(s, api_nh->srte_color);
1258
1259 /* Backup nexthop index */
1260 if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_HAS_BACKUP)) {
1261 STREAM_GETC(s, api_nh->backup_num);
1262
1263 if (api_nh->backup_num > NEXTHOP_MAX_BACKUPS)
1264 return -1;
1265
1266 for (i = 0; i < api_nh->backup_num; i++)
1267 STREAM_GETC(s, api_nh->backup_idx[i]);
1268 }
1269
1270 /* Success */
1271 ret = 0;
1272
1273 stream_failure:
1274
1275 return ret;
1276 }
1277
1278 int zapi_route_decode(struct stream *s, struct zapi_route *api)
1279 {
1280 struct zapi_nexthop *api_nh;
1281 int i;
1282
1283 memset(api, 0, sizeof(*api));
1284
1285 /* Type, flags, message. */
1286 STREAM_GETC(s, api->type);
1287 if (api->type >= ZEBRA_ROUTE_MAX) {
1288 flog_err(EC_LIB_ZAPI_ENCODE,
1289 "%s: Specified route type: %d is not a legal value\n",
1290 __func__, api->type);
1291 return -1;
1292 }
1293
1294 STREAM_GETW(s, api->instance);
1295 STREAM_GETL(s, api->flags);
1296 STREAM_GETL(s, api->message);
1297 STREAM_GETC(s, api->safi);
1298 if (api->safi < SAFI_UNICAST || api->safi >= SAFI_MAX) {
1299 flog_err(EC_LIB_ZAPI_ENCODE,
1300 "%s: Specified route SAFI (%u) is not a legal value\n",
1301 __func__, api->safi);
1302 return -1;
1303 }
1304
1305 /* Prefix. */
1306 STREAM_GETC(s, api->prefix.family);
1307 STREAM_GETC(s, api->prefix.prefixlen);
1308 switch (api->prefix.family) {
1309 case AF_INET:
1310 if (api->prefix.prefixlen > IPV4_MAX_PREFIXLEN) {
1311 flog_err(
1312 EC_LIB_ZAPI_ENCODE,
1313 "%s: V4 prefixlen is %d which should not be more than 32",
1314 __func__, api->prefix.prefixlen);
1315 return -1;
1316 }
1317 break;
1318 case AF_INET6:
1319 if (api->prefix.prefixlen > IPV6_MAX_PREFIXLEN) {
1320 flog_err(
1321 EC_LIB_ZAPI_ENCODE,
1322 "%s: v6 prefixlen is %d which should not be more than 128",
1323 __func__, api->prefix.prefixlen);
1324 return -1;
1325 }
1326 break;
1327 default:
1328 flog_err(EC_LIB_ZAPI_ENCODE,
1329 "%s: Specified family %d is not v4 or v6", __func__,
1330 api->prefix.family);
1331 return -1;
1332 }
1333 STREAM_GET(&api->prefix.u.prefix, s, PSIZE(api->prefix.prefixlen));
1334
1335 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_SRCPFX)) {
1336 api->src_prefix.family = AF_INET6;
1337 STREAM_GETC(s, api->src_prefix.prefixlen);
1338 if (api->src_prefix.prefixlen > IPV6_MAX_PREFIXLEN) {
1339 flog_err(
1340 EC_LIB_ZAPI_ENCODE,
1341 "%s: SRC Prefix prefixlen received: %d is too large",
1342 __func__, api->src_prefix.prefixlen);
1343 return -1;
1344 }
1345 STREAM_GET(&api->src_prefix.prefix, s,
1346 PSIZE(api->src_prefix.prefixlen));
1347
1348 if (api->prefix.family != AF_INET6
1349 || api->src_prefix.prefixlen == 0) {
1350 flog_err(
1351 EC_LIB_ZAPI_ENCODE,
1352 "%s: SRC prefix specified in some manner that makes no sense",
1353 __func__);
1354 return -1;
1355 }
1356 }
1357
1358 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NHG))
1359 STREAM_GETL(s, api->nhgid);
1360
1361 /* Nexthops. */
1362 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
1363 STREAM_GETW(s, api->nexthop_num);
1364 if (api->nexthop_num > MULTIPATH_NUM) {
1365 flog_err(EC_LIB_ZAPI_ENCODE,
1366 "%s: invalid number of nexthops (%u)",
1367 __func__, api->nexthop_num);
1368 return -1;
1369 }
1370
1371 for (i = 0; i < api->nexthop_num; i++) {
1372 api_nh = &api->nexthops[i];
1373
1374 if (zapi_nexthop_decode(s, api_nh, api->flags,
1375 api->message)
1376 != 0)
1377 return -1;
1378 }
1379 }
1380
1381 /* Backup nexthops. */
1382 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_BACKUP_NEXTHOPS)) {
1383 STREAM_GETW(s, api->backup_nexthop_num);
1384 if (api->backup_nexthop_num > MULTIPATH_NUM) {
1385 flog_err(EC_LIB_ZAPI_ENCODE,
1386 "%s: invalid number of backup nexthops (%u)",
1387 __func__, api->backup_nexthop_num);
1388 return -1;
1389 }
1390
1391 for (i = 0; i < api->backup_nexthop_num; i++) {
1392 api_nh = &api->backup_nexthops[i];
1393
1394 if (zapi_nexthop_decode(s, api_nh, api->flags,
1395 api->message)
1396 != 0)
1397 return -1;
1398 }
1399 }
1400
1401 /* Attributes. */
1402 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
1403 STREAM_GETC(s, api->distance);
1404 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
1405 STREAM_GETL(s, api->metric);
1406 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
1407 STREAM_GETL(s, api->tag);
1408 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
1409 STREAM_GETL(s, api->mtu);
1410 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TABLEID))
1411 STREAM_GETL(s, api->tableid);
1412
1413 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_OPAQUE)) {
1414 STREAM_GETW(s, api->opaque.length);
1415 assert(api->opaque.length < ZAPI_MESSAGE_OPAQUE_LENGTH);
1416
1417 STREAM_GET(api->opaque.data, s, api->opaque.length);
1418 }
1419
1420 return 0;
1421 stream_failure:
1422 return -1;
1423 }
1424
1425 static void zapi_encode_prefix(struct stream *s, struct prefix *p,
1426 uint8_t family)
1427 {
1428 struct prefix any;
1429
1430 if (!p) {
1431 memset(&any, 0, sizeof(any));
1432 any.family = family;
1433 p = &any;
1434 }
1435
1436 stream_putc(s, p->family);
1437 stream_putc(s, p->prefixlen);
1438 stream_put(s, &p->u.prefix, prefix_blen(p));
1439 }
1440
1441 int zapi_pbr_rule_encode(uint8_t cmd, struct stream *s, struct pbr_rule *zrule)
1442 {
1443 stream_reset(s);
1444 zclient_create_header(s, cmd, zrule->vrf_id);
1445
1446 /*
1447 * We are sending one item at a time at the moment
1448 */
1449 stream_putl(s, 1);
1450
1451 stream_putl(s, zrule->seq);
1452 stream_putl(s, zrule->priority);
1453 stream_putl(s, zrule->unique);
1454
1455 zapi_encode_prefix(s, &(zrule->filter.src_ip),
1456 zrule->filter.src_ip.family);
1457 stream_putw(s, zrule->filter.src_port); /* src port */
1458 zapi_encode_prefix(s, &(zrule->filter.dst_ip),
1459 zrule->filter.src_ip.family);
1460 stream_putw(s, zrule->filter.dst_port); /* dst port */
1461 stream_putw(s, zrule->filter.fwmark); /* fwmark */
1462
1463 stream_putl(s, zrule->action.table);
1464 stream_put(s, zrule->ifname, INTERFACE_NAMSIZ);
1465
1466 /* Put length at the first point of the stream. */
1467 stream_putw_at(s, 0, stream_get_endp(s));
1468
1469 return 0;
1470 }
1471
1472 bool zapi_nhg_notify_decode(struct stream *s, uint32_t *id,
1473 enum zapi_nhg_notify_owner *note)
1474 {
1475 uint32_t read_id;
1476
1477 STREAM_GET(note, s, sizeof(*note));
1478 STREAM_GETL(s, read_id);
1479
1480 *id = read_id;
1481
1482 return true;
1483
1484 stream_failure:
1485 return false;
1486 }
1487
1488 bool zapi_route_notify_decode(struct stream *s, struct prefix *p,
1489 uint32_t *tableid,
1490 enum zapi_route_notify_owner *note,
1491 afi_t *afi, safi_t *safi)
1492 {
1493 uint32_t t;
1494 afi_t afi_val;
1495 safi_t safi_val;
1496
1497 STREAM_GET(note, s, sizeof(*note));
1498
1499 STREAM_GETC(s, p->family);
1500 STREAM_GETC(s, p->prefixlen);
1501 STREAM_GET(&p->u.prefix, s, prefix_blen(p));
1502 STREAM_GETL(s, t);
1503 STREAM_GETC(s, afi_val);
1504 STREAM_GETC(s, safi_val);
1505
1506 *tableid = t;
1507
1508 if (afi)
1509 *afi = afi_val;
1510 if (safi)
1511 *safi = safi_val;
1512
1513 return true;
1514
1515 stream_failure:
1516 return false;
1517 }
1518
1519 bool zapi_rule_notify_decode(struct stream *s, uint32_t *seqno,
1520 uint32_t *priority, uint32_t *unique, char *ifname,
1521 enum zapi_rule_notify_owner *note)
1522 {
1523 uint32_t prio, seq, uni;
1524
1525 STREAM_GET(note, s, sizeof(*note));
1526
1527 STREAM_GETL(s, seq);
1528 STREAM_GETL(s, prio);
1529 STREAM_GETL(s, uni);
1530 STREAM_GET(ifname, s, INTERFACE_NAMSIZ);
1531
1532 if (zclient_debug)
1533 zlog_debug("%s: %u %u %u %s", __func__, seq, prio, uni, ifname);
1534 *seqno = seq;
1535 *priority = prio;
1536 *unique = uni;
1537
1538 return true;
1539
1540 stream_failure:
1541 return false;
1542 }
1543
1544 bool zapi_ipset_notify_decode(struct stream *s, uint32_t *unique,
1545 enum zapi_ipset_notify_owner *note)
1546 {
1547 uint32_t uni;
1548
1549 STREAM_GET(note, s, sizeof(*note));
1550
1551 STREAM_GETL(s, uni);
1552
1553 if (zclient_debug)
1554 zlog_debug("%s: %u", __func__, uni);
1555 *unique = uni;
1556
1557 return true;
1558
1559 stream_failure:
1560 return false;
1561 }
1562
1563 bool zapi_ipset_entry_notify_decode(struct stream *s, uint32_t *unique,
1564 char *ipset_name,
1565 enum zapi_ipset_entry_notify_owner *note)
1566 {
1567 uint32_t uni;
1568
1569 STREAM_GET(note, s, sizeof(*note));
1570
1571 STREAM_GETL(s, uni);
1572
1573 STREAM_GET(ipset_name, s, ZEBRA_IPSET_NAME_SIZE);
1574
1575 if (zclient_debug)
1576 zlog_debug("%s: %u", __func__, uni);
1577 *unique = uni;
1578
1579 return true;
1580
1581 stream_failure:
1582 return false;
1583 }
1584
1585 bool zapi_iptable_notify_decode(struct stream *s,
1586 uint32_t *unique,
1587 enum zapi_iptable_notify_owner *note)
1588 {
1589 uint32_t uni;
1590
1591 STREAM_GET(note, s, sizeof(*note));
1592
1593 STREAM_GETL(s, uni);
1594
1595 if (zclient_debug)
1596 zlog_debug("%s: %u", __func__, uni);
1597 *unique = uni;
1598
1599 return true;
1600
1601 stream_failure:
1602 return false;
1603 }
1604
1605 struct nexthop *nexthop_from_zapi_nexthop(const struct zapi_nexthop *znh)
1606 {
1607 struct nexthop *n = nexthop_new();
1608
1609 n->type = znh->type;
1610 n->vrf_id = znh->vrf_id;
1611 n->ifindex = znh->ifindex;
1612 n->gate = znh->gate;
1613 n->srte_color = znh->srte_color;
1614
1615 /*
1616 * This function currently handles labels
1617 */
1618 if (znh->label_num) {
1619 nexthop_add_labels(n, ZEBRA_LSP_NONE, znh->label_num,
1620 znh->labels);
1621 }
1622
1623 if (CHECK_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_HAS_BACKUP)) {
1624 SET_FLAG(n->flags, NEXTHOP_FLAG_HAS_BACKUP);
1625 n->backup_num = znh->backup_num;
1626 memcpy(n->backup_idx, znh->backup_idx, n->backup_num);
1627 }
1628
1629 return n;
1630 }
1631
1632 /*
1633 * Convert nexthop to zapi nexthop
1634 */
1635 int zapi_nexthop_from_nexthop(struct zapi_nexthop *znh,
1636 const struct nexthop *nh)
1637 {
1638 int i;
1639
1640 memset(znh, 0, sizeof(*znh));
1641
1642 znh->type = nh->type;
1643 znh->vrf_id = nh->vrf_id;
1644 znh->weight = nh->weight;
1645 znh->ifindex = nh->ifindex;
1646 znh->gate = nh->gate;
1647
1648 if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_ONLINK))
1649 SET_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_ONLINK);
1650
1651 if (nh->nh_label && (nh->nh_label->num_labels > 0)) {
1652
1653 /* Validate */
1654 if (nh->nh_label->num_labels > MPLS_MAX_LABELS)
1655 return -1;
1656
1657 for (i = 0; i < nh->nh_label->num_labels; i++)
1658 znh->labels[i] = nh->nh_label->label[i];
1659
1660 znh->label_num = i;
1661 SET_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_LABEL);
1662 }
1663
1664 if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_HAS_BACKUP)) {
1665 if (nh->backup_num > NEXTHOP_MAX_BACKUPS)
1666 return -1;
1667
1668 SET_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_HAS_BACKUP);
1669 znh->backup_num = nh->backup_num;
1670 memcpy(znh->backup_idx, nh->backup_idx, znh->backup_num);
1671 }
1672
1673 return 0;
1674 }
1675
1676 /*
1677 * Wrapper that converts backup nexthop
1678 */
1679 int zapi_backup_nexthop_from_nexthop(struct zapi_nexthop *znh,
1680 const struct nexthop *nh)
1681 {
1682 int ret;
1683
1684 /* Ensure that zapi flags are correct: backups don't have backups */
1685 ret = zapi_nexthop_from_nexthop(znh, nh);
1686 if (ret == 0)
1687 UNSET_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_HAS_BACKUP);
1688
1689 return ret;
1690 }
1691
1692 /*
1693 * Format some info about a zapi nexthop, for debug or logging.
1694 */
1695 const char *zapi_nexthop2str(const struct zapi_nexthop *znh, char *buf,
1696 int bufsize)
1697 {
1698 char tmp[INET6_ADDRSTRLEN];
1699
1700 switch (znh->type) {
1701 case NEXTHOP_TYPE_IFINDEX:
1702 snprintf(buf, bufsize, "if %u", znh->ifindex);
1703 break;
1704 case NEXTHOP_TYPE_IPV4:
1705 case NEXTHOP_TYPE_IPV4_IFINDEX:
1706 inet_ntop(AF_INET, &znh->gate.ipv4, tmp, sizeof(tmp));
1707 snprintf(buf, bufsize, "%s if %u", tmp, znh->ifindex);
1708 break;
1709 case NEXTHOP_TYPE_IPV6:
1710 case NEXTHOP_TYPE_IPV6_IFINDEX:
1711 inet_ntop(AF_INET6, &znh->gate.ipv6, tmp, sizeof(tmp));
1712 snprintf(buf, bufsize, "%s if %u", tmp, znh->ifindex);
1713 break;
1714 case NEXTHOP_TYPE_BLACKHOLE:
1715 snprintf(buf, bufsize, "blackhole");
1716 break;
1717 default:
1718 snprintf(buf, bufsize, "unknown");
1719 break;
1720 }
1721
1722 return buf;
1723 }
1724
1725 /*
1726 * Decode the nexthop-tracking update message
1727 */
1728 bool zapi_nexthop_update_decode(struct stream *s, struct zapi_route *nhr)
1729 {
1730 uint32_t i;
1731
1732 memset(nhr, 0, sizeof(*nhr));
1733
1734 STREAM_GETL(s, nhr->message);
1735 STREAM_GETW(s, nhr->prefix.family);
1736 STREAM_GETC(s, nhr->prefix.prefixlen);
1737 switch (nhr->prefix.family) {
1738 case AF_INET:
1739 STREAM_GET(&nhr->prefix.u.prefix4.s_addr, s, IPV4_MAX_BYTELEN);
1740 break;
1741 case AF_INET6:
1742 STREAM_GET(&nhr->prefix.u.prefix6, s, IPV6_MAX_BYTELEN);
1743 break;
1744 default:
1745 break;
1746 }
1747 if (CHECK_FLAG(nhr->message, ZAPI_MESSAGE_SRTE))
1748 STREAM_GETL(s, nhr->srte_color);
1749
1750 STREAM_GETC(s, nhr->type);
1751 STREAM_GETW(s, nhr->instance);
1752 STREAM_GETC(s, nhr->distance);
1753 STREAM_GETL(s, nhr->metric);
1754 STREAM_GETC(s, nhr->nexthop_num);
1755
1756 for (i = 0; i < nhr->nexthop_num; i++) {
1757 if (zapi_nexthop_decode(s, &(nhr->nexthops[i]), 0, 0) != 0)
1758 return false;
1759 }
1760
1761 return true;
1762 stream_failure:
1763 return false;
1764 }
1765
1766 bool zapi_error_decode(struct stream *s, enum zebra_error_types *error)
1767 {
1768 memset(error, 0, sizeof(*error));
1769
1770 STREAM_GET(error, s, sizeof(*error));
1771
1772 if (zclient_debug)
1773 zlog_debug("%s: type: %s", __func__,
1774 zebra_error_type2str(*error));
1775
1776 return true;
1777 stream_failure:
1778 return false;
1779 }
1780
1781 /*
1782 * send a ZEBRA_REDISTRIBUTE_ADD or ZEBRA_REDISTRIBUTE_DELETE
1783 * for the route type (ZEBRA_ROUTE_KERNEL etc.). The zebra server will
1784 * then set/unset redist[type] in the client handle (a struct zserv) for the
1785 * sending client
1786 */
1787 enum zclient_send_status
1788 zebra_redistribute_send(int command, struct zclient *zclient, afi_t afi,
1789 int type, unsigned short instance, vrf_id_t vrf_id)
1790 {
1791 struct stream *s;
1792
1793 s = zclient->obuf;
1794 stream_reset(s);
1795
1796 zclient_create_header(s, command, vrf_id);
1797 stream_putc(s, afi);
1798 stream_putc(s, type);
1799 stream_putw(s, instance);
1800
1801 stream_putw_at(s, 0, stream_get_endp(s));
1802
1803 return zclient_send_message(zclient);
1804 }
1805
1806 enum zclient_send_status
1807 zebra_redistribute_default_send(int command, struct zclient *zclient, afi_t afi,
1808 vrf_id_t vrf_id)
1809 {
1810 struct stream *s;
1811
1812 s = zclient->obuf;
1813 stream_reset(s);
1814
1815 zclient_create_header(s, command, vrf_id);
1816 stream_putc(s, afi);
1817
1818 stream_putw_at(s, 0, stream_get_endp(s));
1819
1820 return zclient_send_message(zclient);
1821 }
1822
1823 /* Send route notify request to zebra */
1824 int zebra_route_notify_send(int command, struct zclient *zclient, bool set)
1825 {
1826 struct stream *s;
1827
1828 s = zclient->obuf;
1829 stream_reset(s);
1830
1831 zclient_create_header(s, command, 0);
1832 stream_putc(s, !!set);
1833
1834 stream_putw_at(s, 0, stream_get_endp(s));
1835
1836 return zclient_send_message(zclient);
1837 }
1838
1839 /* Get prefix in ZServ format; family should be filled in on prefix */
1840 static int zclient_stream_get_prefix(struct stream *s, struct prefix *p)
1841 {
1842 size_t plen = prefix_blen(p);
1843 uint8_t c;
1844 p->prefixlen = 0;
1845
1846 if (plen == 0)
1847 return -1;
1848
1849 STREAM_GET(&p->u.prefix, s, plen);
1850 STREAM_GETC(s, c);
1851 p->prefixlen = MIN(plen * 8, c);
1852
1853 return 0;
1854 stream_failure:
1855 return -1;
1856 }
1857
1858 /* Router-id update from zebra daemon. */
1859 int zebra_router_id_update_read(struct stream *s, struct prefix *rid)
1860 {
1861 /* Fetch interface address. */
1862 STREAM_GETC(s, rid->family);
1863
1864 return zclient_stream_get_prefix(s, rid);
1865
1866 stream_failure:
1867 return -1;
1868 }
1869
1870 /* Interface addition from zebra daemon. */
1871 /*
1872 * The format of the message sent with type ZEBRA_INTERFACE_ADD or
1873 * ZEBRA_INTERFACE_DELETE from zebra to the client is:
1874 * 0 1 2 3
1875 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1876 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1877 * | ifname |
1878 * | |
1879 * | |
1880 * | |
1881 * | |
1882 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1883 * | ifindex |
1884 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1885 * | status |
1886 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1887 * | if_flags |
1888 * | |
1889 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1890 * | metric |
1891 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1892 * | speed |
1893 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1894 * | ifmtu |
1895 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1896 * | ifmtu6 |
1897 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1898 * | bandwidth |
1899 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1900 * | parent ifindex |
1901 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1902 * | Link Layer Type |
1903 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1904 * | Harware Address Length |
1905 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1906 * | Hardware Address if HW lenght different from 0 |
1907 * | ... max INTERFACE_HWADDR_MAX |
1908 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1909 * | Link_params? | Whether a link-params follows: 1 or 0.
1910 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1911 * | Link_params 0 or 1 INTERFACE_LINK_PARAMS_SIZE sized |
1912 * | .... (struct if_link_params). |
1913 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1914 */
1915
1916 static int zclient_vrf_add(struct zclient *zclient, vrf_id_t vrf_id)
1917 {
1918 struct vrf *vrf;
1919 char vrfname_tmp[VRF_NAMSIZ + 1] = {};
1920 struct vrf_data data;
1921
1922 STREAM_GET(&data, zclient->ibuf, sizeof(struct vrf_data));
1923 /* Read interface name. */
1924 STREAM_GET(vrfname_tmp, zclient->ibuf, VRF_NAMSIZ);
1925
1926 if (strlen(vrfname_tmp) == 0)
1927 goto stream_failure;
1928
1929 /* Lookup/create vrf by name, then vrf_id. */
1930 vrf = vrf_get(vrf_id, vrfname_tmp);
1931
1932 /* If there's already a VRF with this name, don't create vrf */
1933 if (!vrf)
1934 return 0;
1935
1936 vrf->data.l.table_id = data.l.table_id;
1937 memcpy(vrf->data.l.netns_name, data.l.netns_name, NS_NAMSIZ);
1938 /* overwrite default vrf */
1939 if (vrf_id == VRF_DEFAULT)
1940 vrf_set_default_name(vrfname_tmp, false);
1941 vrf_enable(vrf);
1942
1943 return 0;
1944 stream_failure:
1945 return -1;
1946 }
1947
1948 static void zclient_vrf_delete(struct zclient *zclient, vrf_id_t vrf_id)
1949 {
1950 struct vrf *vrf;
1951
1952 /* Lookup vrf by vrf_id. */
1953 vrf = vrf_lookup_by_id(vrf_id);
1954
1955 /*
1956 * If a routing protocol doesn't know about a
1957 * vrf that is about to be deleted. There is
1958 * no point in attempting to delete it.
1959 */
1960 if (!vrf)
1961 return;
1962
1963 vrf_delete(vrf);
1964 }
1965
1966 static int zclient_interface_add(struct zclient *zclient, vrf_id_t vrf_id)
1967 {
1968 struct interface *ifp;
1969 char ifname_tmp[INTERFACE_NAMSIZ + 1] = {};
1970 struct stream *s = zclient->ibuf;
1971
1972 /* Read interface name. */
1973 STREAM_GET(ifname_tmp, s, INTERFACE_NAMSIZ);
1974
1975 /* Lookup/create interface by name. */
1976 if (!vrf_get(vrf_id, NULL)) {
1977 zlog_debug(
1978 "Rx'd interface add from Zebra, but VRF %u does not exist",
1979 vrf_id);
1980 return -1;
1981 }
1982
1983 ifp = if_get_by_name(ifname_tmp, vrf_id);
1984
1985 zebra_interface_if_set_value(s, ifp);
1986
1987 if_new_via_zapi(ifp);
1988
1989 return 0;
1990 stream_failure:
1991 return -1;
1992 }
1993
1994 /*
1995 * Read interface up/down msg (ZEBRA_INTERFACE_UP/ZEBRA_INTERFACE_DOWN)
1996 * from zebra server. The format of this message is the same as
1997 * that sent for ZEBRA_INTERFACE_ADD/ZEBRA_INTERFACE_DELETE,
1998 * except that no sockaddr_dl is sent at the tail of the message.
1999 */
2000 struct interface *zebra_interface_state_read(struct stream *s, vrf_id_t vrf_id)
2001 {
2002 struct interface *ifp;
2003 char ifname_tmp[INTERFACE_NAMSIZ + 1] = {};
2004
2005 /* Read interface name. */
2006 STREAM_GET(ifname_tmp, s, INTERFACE_NAMSIZ);
2007
2008 /* Lookup this by interface index. */
2009 ifp = if_lookup_by_name(ifname_tmp, vrf_id);
2010 if (ifp == NULL) {
2011 flog_err(EC_LIB_ZAPI_ENCODE,
2012 "INTERFACE_STATE: Cannot find IF %s in VRF %d",
2013 ifname_tmp, vrf_id);
2014 return NULL;
2015 }
2016
2017 zebra_interface_if_set_value(s, ifp);
2018
2019 return ifp;
2020 stream_failure:
2021 return NULL;
2022 }
2023
2024 static void zclient_interface_delete(struct zclient *zclient, vrf_id_t vrf_id)
2025 {
2026 struct interface *ifp;
2027 struct stream *s = zclient->ibuf;
2028
2029 ifp = zebra_interface_state_read(s, vrf_id);
2030
2031 if (ifp == NULL)
2032 return;
2033
2034 if_destroy_via_zapi(ifp);
2035 return;
2036 }
2037
2038 static void zclient_interface_up(struct zclient *zclient, vrf_id_t vrf_id)
2039 {
2040 struct interface *ifp;
2041 struct stream *s = zclient->ibuf;
2042
2043 ifp = zebra_interface_state_read(s, vrf_id);
2044
2045 if (!ifp)
2046 return;
2047
2048 if_up_via_zapi(ifp);
2049 }
2050
2051 static void zclient_interface_down(struct zclient *zclient, vrf_id_t vrf_id)
2052 {
2053 struct interface *ifp;
2054 struct stream *s = zclient->ibuf;
2055
2056 ifp = zebra_interface_state_read(s, vrf_id);
2057
2058 if (!ifp)
2059 return;
2060
2061 if_down_via_zapi(ifp);
2062 }
2063
2064 static void zclient_handle_error(ZAPI_CALLBACK_ARGS)
2065 {
2066 enum zebra_error_types error;
2067 struct stream *s = zclient->ibuf;
2068
2069 zapi_error_decode(s, &error);
2070
2071 if (zclient->handle_error)
2072 (*zclient->handle_error)(error);
2073 }
2074
2075 static int link_params_set_value(struct stream *s, struct if_link_params *iflp)
2076 {
2077
2078 if (iflp == NULL)
2079 return -1;
2080
2081 uint32_t bwclassnum;
2082
2083 STREAM_GETL(s, iflp->lp_status);
2084 STREAM_GETL(s, iflp->te_metric);
2085 STREAM_GETF(s, iflp->max_bw);
2086 STREAM_GETF(s, iflp->max_rsv_bw);
2087 STREAM_GETL(s, bwclassnum);
2088 {
2089 unsigned int i;
2090 for (i = 0; i < bwclassnum && i < MAX_CLASS_TYPE; i++)
2091 STREAM_GETF(s, iflp->unrsv_bw[i]);
2092 if (i < bwclassnum)
2093 flog_err(
2094 EC_LIB_ZAPI_MISSMATCH,
2095 "%s: received %d > %d (MAX_CLASS_TYPE) bw entries - outdated library?",
2096 __func__, bwclassnum, MAX_CLASS_TYPE);
2097 }
2098 STREAM_GETL(s, iflp->admin_grp);
2099 STREAM_GETL(s, iflp->rmt_as);
2100 iflp->rmt_ip.s_addr = stream_get_ipv4(s);
2101
2102 STREAM_GETL(s, iflp->av_delay);
2103 STREAM_GETL(s, iflp->min_delay);
2104 STREAM_GETL(s, iflp->max_delay);
2105 STREAM_GETL(s, iflp->delay_var);
2106
2107 STREAM_GETF(s, iflp->pkt_loss);
2108 STREAM_GETF(s, iflp->res_bw);
2109 STREAM_GETF(s, iflp->ava_bw);
2110 STREAM_GETF(s, iflp->use_bw);
2111
2112 return 0;
2113 stream_failure:
2114 return -1;
2115 }
2116
2117 struct interface *zebra_interface_link_params_read(struct stream *s,
2118 vrf_id_t vrf_id)
2119 {
2120 struct if_link_params *iflp;
2121 ifindex_t ifindex;
2122
2123 STREAM_GETL(s, ifindex);
2124
2125 struct interface *ifp = if_lookup_by_index(ifindex, vrf_id);
2126
2127 if (ifp == NULL) {
2128 flog_err(EC_LIB_ZAPI_ENCODE,
2129 "%s: unknown ifindex %u, shouldn't happen", __func__,
2130 ifindex);
2131 return NULL;
2132 }
2133
2134 if ((iflp = if_link_params_get(ifp)) == NULL)
2135 return NULL;
2136
2137 if (link_params_set_value(s, iflp) != 0)
2138 goto stream_failure;
2139
2140 return ifp;
2141
2142 stream_failure:
2143 return NULL;
2144 }
2145
2146 static void zebra_interface_if_set_value(struct stream *s,
2147 struct interface *ifp)
2148 {
2149 uint8_t link_params_status = 0;
2150 ifindex_t old_ifindex, new_ifindex;
2151
2152 old_ifindex = ifp->oldifindex;
2153 /* Read interface's index. */
2154 STREAM_GETL(s, new_ifindex);
2155 if_set_index(ifp, new_ifindex);
2156 STREAM_GETC(s, ifp->status);
2157
2158 /* Read interface's value. */
2159 STREAM_GETQ(s, ifp->flags);
2160 STREAM_GETC(s, ifp->ptm_enable);
2161 STREAM_GETC(s, ifp->ptm_status);
2162 STREAM_GETL(s, ifp->metric);
2163 STREAM_GETL(s, ifp->speed);
2164 STREAM_GETL(s, ifp->mtu);
2165 STREAM_GETL(s, ifp->mtu6);
2166 STREAM_GETL(s, ifp->bandwidth);
2167 STREAM_GETL(s, ifp->link_ifindex);
2168 STREAM_GETL(s, ifp->ll_type);
2169 STREAM_GETL(s, ifp->hw_addr_len);
2170 if (ifp->hw_addr_len)
2171 STREAM_GET(ifp->hw_addr, s,
2172 MIN(ifp->hw_addr_len, INTERFACE_HWADDR_MAX));
2173
2174 /* Read Traffic Engineering status */
2175 link_params_status = stream_getc(s);
2176 /* Then, Traffic Engineering parameters if any */
2177 if (link_params_status) {
2178 struct if_link_params *iflp = if_link_params_get(ifp);
2179 link_params_set_value(s, iflp);
2180 }
2181
2182 nexthop_group_interface_state_change(ifp, old_ifindex);
2183
2184 return;
2185 stream_failure:
2186 zlog_err("Could not parse interface values; aborting");
2187 assert(!"Failed to parse interface values");
2188 }
2189
2190 size_t zebra_interface_link_params_write(struct stream *s,
2191 struct interface *ifp)
2192 {
2193 size_t w;
2194 struct if_link_params *iflp;
2195 int i;
2196
2197 if (s == NULL || ifp == NULL || ifp->link_params == NULL)
2198 return 0;
2199
2200 iflp = ifp->link_params;
2201 w = 0;
2202
2203 w += stream_putl(s, iflp->lp_status);
2204
2205 w += stream_putl(s, iflp->te_metric);
2206 w += stream_putf(s, iflp->max_bw);
2207 w += stream_putf(s, iflp->max_rsv_bw);
2208
2209 w += stream_putl(s, MAX_CLASS_TYPE);
2210 for (i = 0; i < MAX_CLASS_TYPE; i++)
2211 w += stream_putf(s, iflp->unrsv_bw[i]);
2212
2213 w += stream_putl(s, iflp->admin_grp);
2214 w += stream_putl(s, iflp->rmt_as);
2215 w += stream_put_in_addr(s, &iflp->rmt_ip);
2216
2217 w += stream_putl(s, iflp->av_delay);
2218 w += stream_putl(s, iflp->min_delay);
2219 w += stream_putl(s, iflp->max_delay);
2220 w += stream_putl(s, iflp->delay_var);
2221
2222 w += stream_putf(s, iflp->pkt_loss);
2223 w += stream_putf(s, iflp->res_bw);
2224 w += stream_putf(s, iflp->ava_bw);
2225 w += stream_putf(s, iflp->use_bw);
2226
2227 return w;
2228 }
2229
2230 /*
2231 * format of message for address additon is:
2232 * 0
2233 * 0 1 2 3 4 5 6 7
2234 * +-+-+-+-+-+-+-+-+
2235 * | type | ZEBRA_INTERFACE_ADDRESS_ADD or
2236 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_ADDRES_DELETE
2237 * | |
2238 * + +
2239 * | ifindex |
2240 * + +
2241 * | |
2242 * + +
2243 * | |
2244 * +-+-+-+-+-+-+-+-+
2245 * | ifc_flags | flags for connected address
2246 * +-+-+-+-+-+-+-+-+
2247 * | addr_family |
2248 * +-+-+-+-+-+-+-+-+
2249 * | addr... |
2250 * : :
2251 * | |
2252 * +-+-+-+-+-+-+-+-+
2253 * | addr_len | len of addr. E.g., addr_len = 4 for ipv4 addrs.
2254 * +-+-+-+-+-+-+-+-+
2255 * | daddr.. |
2256 * : :
2257 * | |
2258 * +-+-+-+-+-+-+-+-+
2259 */
2260
2261 static int memconstant(const void *s, int c, size_t n)
2262 {
2263 const uint8_t *p = s;
2264
2265 while (n-- > 0)
2266 if (*p++ != c)
2267 return 0;
2268 return 1;
2269 }
2270
2271
2272 struct connected *zebra_interface_address_read(int type, struct stream *s,
2273 vrf_id_t vrf_id)
2274 {
2275 ifindex_t ifindex;
2276 struct interface *ifp;
2277 struct connected *ifc;
2278 struct prefix p, d, *dp;
2279 int plen;
2280 uint8_t ifc_flags;
2281
2282 memset(&p, 0, sizeof(p));
2283 memset(&d, 0, sizeof(d));
2284
2285 /* Get interface index. */
2286 STREAM_GETL(s, ifindex);
2287
2288 /* Lookup index. */
2289 ifp = if_lookup_by_index(ifindex, vrf_id);
2290 if (ifp == NULL) {
2291 flog_err(EC_LIB_ZAPI_ENCODE,
2292 "INTERFACE_ADDRESS_%s: Cannot find IF %u in VRF %d",
2293 (type == ZEBRA_INTERFACE_ADDRESS_ADD) ? "ADD" : "DEL",
2294 ifindex, vrf_id);
2295 return NULL;
2296 }
2297
2298 /* Fetch flag. */
2299 STREAM_GETC(s, ifc_flags);
2300
2301 /* Fetch interface address. */
2302 STREAM_GETC(s, d.family);
2303 p.family = d.family;
2304 plen = prefix_blen(&d);
2305
2306 if (zclient_stream_get_prefix(s, &p) != 0)
2307 goto stream_failure;
2308
2309 /* Fetch destination address. */
2310 STREAM_GET(&d.u.prefix, s, plen);
2311
2312 /* N.B. NULL destination pointers are encoded as all zeroes */
2313 dp = memconstant(&d.u.prefix, 0, plen) ? NULL : &d;
2314
2315 if (type == ZEBRA_INTERFACE_ADDRESS_ADD) {
2316 ifc = connected_lookup_prefix_exact(ifp, &p);
2317 if (!ifc) {
2318 /* N.B. NULL destination pointers are encoded as all
2319 * zeroes */
2320 ifc = connected_add_by_prefix(ifp, &p, dp);
2321 }
2322 if (ifc) {
2323 ifc->flags = ifc_flags;
2324 if (ifc->destination)
2325 ifc->destination->prefixlen =
2326 ifc->address->prefixlen;
2327 else if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER)) {
2328 /* carp interfaces on OpenBSD with 0.0.0.0/0 as
2329 * "peer" */
2330 flog_err(
2331 EC_LIB_ZAPI_ENCODE,
2332 "warning: interface %s address %pFX with peer flag set, but no peer address!",
2333 ifp->name, ifc->address);
2334 UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
2335 }
2336 }
2337 } else {
2338 assert(type == ZEBRA_INTERFACE_ADDRESS_DELETE);
2339 ifc = connected_delete_by_prefix(ifp, &p);
2340 }
2341
2342 return ifc;
2343
2344 stream_failure:
2345 return NULL;
2346 }
2347
2348 /*
2349 * format of message for neighbor connected address is:
2350 * 0
2351 * 0 1 2 3 4 5 6 7
2352 * +-+-+-+-+-+-+-+-+
2353 * | type | ZEBRA_INTERFACE_NBR_ADDRESS_ADD or
2354 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_NBR_ADDRES_DELETE
2355 * | |
2356 * + +
2357 * | ifindex |
2358 * + +
2359 * | |
2360 * + +
2361 * | |
2362 * +-+-+-+-+-+-+-+-+
2363 * | addr_family |
2364 * +-+-+-+-+-+-+-+-+
2365 * | addr... |
2366 * : :
2367 * | |
2368 * +-+-+-+-+-+-+-+-+
2369 * | addr_len | len of addr.
2370 * +-+-+-+-+-+-+-+-+
2371 */
2372 struct nbr_connected *
2373 zebra_interface_nbr_address_read(int type, struct stream *s, vrf_id_t vrf_id)
2374 {
2375 unsigned int ifindex;
2376 struct interface *ifp;
2377 struct prefix p;
2378 struct nbr_connected *ifc;
2379
2380 /* Get interface index. */
2381 STREAM_GETL(s, ifindex);
2382
2383 /* Lookup index. */
2384 ifp = if_lookup_by_index(ifindex, vrf_id);
2385 if (ifp == NULL) {
2386 flog_err(EC_LIB_ZAPI_ENCODE,
2387 "INTERFACE_NBR_%s: Cannot find IF %u in VRF %d",
2388 (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD) ? "ADD"
2389 : "DELETE",
2390 ifindex, vrf_id);
2391 return NULL;
2392 }
2393
2394 STREAM_GETC(s, p.family);
2395 STREAM_GET(&p.u.prefix, s, prefix_blen(&p));
2396 STREAM_GETC(s, p.prefixlen);
2397
2398 if (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD) {
2399 /* Currently only supporting P2P links, so any new RA source
2400 address is
2401 considered as the replacement of the previously learnt
2402 Link-Local address. */
2403 if (!(ifc = listnode_head(ifp->nbr_connected))) {
2404 ifc = nbr_connected_new();
2405 ifc->address = prefix_new();
2406 ifc->ifp = ifp;
2407 listnode_add(ifp->nbr_connected, ifc);
2408 }
2409
2410 prefix_copy(ifc->address, &p);
2411 } else {
2412 assert(type == ZEBRA_INTERFACE_NBR_ADDRESS_DELETE);
2413
2414 ifc = nbr_connected_check(ifp, &p);
2415 if (ifc)
2416 listnode_delete(ifp->nbr_connected, ifc);
2417 }
2418
2419 return ifc;
2420
2421 stream_failure:
2422 return NULL;
2423 }
2424
2425 struct interface *zebra_interface_vrf_update_read(struct stream *s,
2426 vrf_id_t vrf_id,
2427 vrf_id_t *new_vrf_id)
2428 {
2429 char ifname[INTERFACE_NAMSIZ + 1] = {};
2430 struct interface *ifp;
2431 vrf_id_t new_id;
2432
2433 /* Read interface name. */
2434 STREAM_GET(ifname, s, INTERFACE_NAMSIZ);
2435
2436 /* Lookup interface. */
2437 ifp = if_lookup_by_name(ifname, vrf_id);
2438 if (ifp == NULL) {
2439 flog_err(EC_LIB_ZAPI_ENCODE,
2440 "INTERFACE_VRF_UPDATE: Cannot find IF %s in VRF %d",
2441 ifname, vrf_id);
2442 return NULL;
2443 }
2444
2445 /* Fetch new VRF Id. */
2446 STREAM_GETL(s, new_id);
2447
2448 *new_vrf_id = new_id;
2449 return ifp;
2450
2451 stream_failure:
2452 return NULL;
2453 }
2454
2455 /* filter unwanted messages until the expected one arrives */
2456 static int zclient_read_sync_response(struct zclient *zclient,
2457 uint16_t expected_cmd)
2458 {
2459 struct stream *s;
2460 uint16_t size = -1;
2461 uint8_t marker;
2462 uint8_t version;
2463 vrf_id_t vrf_id;
2464 uint16_t cmd;
2465 fd_set readfds;
2466 int ret;
2467
2468 ret = 0;
2469 cmd = expected_cmd + 1;
2470 while (ret == 0 && cmd != expected_cmd) {
2471 s = zclient->ibuf;
2472 stream_reset(s);
2473
2474 /* wait until response arrives */
2475 FD_ZERO(&readfds);
2476 FD_SET(zclient->sock, &readfds);
2477 select(zclient->sock + 1, &readfds, NULL, NULL, NULL);
2478 if (!FD_ISSET(zclient->sock, &readfds))
2479 continue;
2480 /* read response */
2481 ret = zclient_read_header(s, zclient->sock, &size, &marker,
2482 &version, &vrf_id, &cmd);
2483 if (zclient_debug)
2484 zlog_debug("%s: Response (%d bytes) received", __func__,
2485 size);
2486 }
2487 if (ret != 0) {
2488 flog_err(EC_LIB_ZAPI_ENCODE, "%s: Invalid Sync Message Reply",
2489 __func__);
2490 return -1;
2491 }
2492
2493 return 0;
2494 }
2495 /**
2496 * Connect to label manager in a syncronous way
2497 *
2498 * It first writes the request to zcient output buffer and then
2499 * immediately reads the answer from the input buffer.
2500 *
2501 * @param zclient Zclient used to connect to label manager (zebra)
2502 * @param async Synchronous (0) or asynchronous (1) operation
2503 * @result Result of response
2504 */
2505 int lm_label_manager_connect(struct zclient *zclient, int async)
2506 {
2507 int ret;
2508 struct stream *s;
2509 uint8_t result;
2510 uint16_t cmd = async ? ZEBRA_LABEL_MANAGER_CONNECT_ASYNC :
2511 ZEBRA_LABEL_MANAGER_CONNECT;
2512
2513 if (zclient_debug)
2514 zlog_debug("Connecting to Label Manager (LM)");
2515
2516 if (zclient->sock < 0) {
2517 zlog_debug("%s: invalid zclient socket", __func__);
2518 return -1;
2519 }
2520
2521 /* send request */
2522 s = zclient->obuf;
2523 stream_reset(s);
2524 zclient_create_header(s, cmd, VRF_DEFAULT);
2525
2526 /* proto */
2527 stream_putc(s, zclient->redist_default);
2528 /* instance */
2529 stream_putw(s, zclient->instance);
2530
2531 /* Put length at the first point of the stream. */
2532 stream_putw_at(s, 0, stream_get_endp(s));
2533
2534 ret = writen(zclient->sock, s->data, stream_get_endp(s));
2535 if (ret < 0) {
2536 flog_err(EC_LIB_ZAPI_SOCKET, "Can't write to zclient sock");
2537 close(zclient->sock);
2538 zclient->sock = -1;
2539 return -1;
2540 }
2541 if (ret == 0) {
2542 flog_err(EC_LIB_ZAPI_SOCKET, "Zclient sock closed");
2543 close(zclient->sock);
2544 zclient->sock = -1;
2545 return -1;
2546 }
2547 if (zclient_debug)
2548 zlog_debug("LM connect request sent (%d bytes)", ret);
2549
2550 if (async)
2551 return 0;
2552
2553 /* read response */
2554 if (zclient_read_sync_response(zclient, cmd)
2555 != 0)
2556 return -1;
2557
2558 s = zclient->ibuf;
2559
2560 /* read instance and proto */
2561 uint8_t proto;
2562 uint16_t instance;
2563
2564 STREAM_GETC(s, proto);
2565 STREAM_GETW(s, instance);
2566
2567 /* sanity */
2568 if (proto != zclient->redist_default)
2569 flog_err(
2570 EC_LIB_ZAPI_ENCODE,
2571 "Wrong proto (%u) in LM connect response. Should be %u",
2572 proto, zclient->redist_default);
2573 if (instance != zclient->instance)
2574 flog_err(
2575 EC_LIB_ZAPI_ENCODE,
2576 "Wrong instId (%u) in LM connect response. Should be %u",
2577 instance, zclient->instance);
2578
2579 /* result code */
2580 STREAM_GETC(s, result);
2581 if (zclient_debug)
2582 zlog_debug("LM connect-response received, result %u", result);
2583
2584 return (int)result;
2585
2586 stream_failure:
2587 return -1;
2588 }
2589
2590 /*
2591 * Asynchronous label chunk request
2592 *
2593 * @param zclient Zclient used to connect to label manager (zebra)
2594 * @param keep Avoid garbage collection
2595 * @param chunk_size Amount of labels requested
2596 * @param base Base for the label chunk. if MPLS_LABEL_BASE_ANY we do not care
2597 * @result 0 on success, -1 otherwise
2598 */
2599 enum zclient_send_status zclient_send_get_label_chunk(struct zclient *zclient,
2600 uint8_t keep,
2601 uint32_t chunk_size,
2602 uint32_t base)
2603 {
2604 struct stream *s;
2605
2606 if (zclient_debug)
2607 zlog_debug("Getting Label Chunk");
2608
2609 if (zclient->sock < 0)
2610 return ZCLIENT_SEND_FAILURE;
2611
2612 s = zclient->obuf;
2613 stream_reset(s);
2614
2615 zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, VRF_DEFAULT);
2616 /* proto */
2617 stream_putc(s, zclient->redist_default);
2618 /* instance */
2619 stream_putw(s, zclient->instance);
2620 stream_putc(s, keep);
2621 stream_putl(s, chunk_size);
2622 stream_putl(s, base);
2623
2624 /* Put length at the first point of the stream. */
2625 stream_putw_at(s, 0, stream_get_endp(s));
2626
2627 return zclient_send_message(zclient);
2628 }
2629
2630 /**
2631 * Function to request a label chunk in a syncronous way
2632 *
2633 * It first writes the request to zlcient output buffer and then
2634 * immediately reads the answer from the input buffer.
2635 *
2636 * @param zclient Zclient used to connect to label manager (zebra)
2637 * @param keep Avoid garbage collection
2638 * @param chunk_size Amount of labels requested
2639 * @param start To write first assigned chunk label to
2640 * @param end To write last assigned chunk label to
2641 * @result 0 on success, -1 otherwise
2642 */
2643 int lm_get_label_chunk(struct zclient *zclient, uint8_t keep, uint32_t base,
2644 uint32_t chunk_size, uint32_t *start, uint32_t *end)
2645 {
2646 int ret;
2647 struct stream *s;
2648 uint8_t response_keep;
2649
2650 if (zclient_debug)
2651 zlog_debug("Getting Label Chunk");
2652
2653 if (zclient->sock < 0)
2654 return -1;
2655
2656 /* send request */
2657 s = zclient->obuf;
2658 stream_reset(s);
2659 zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, VRF_DEFAULT);
2660 /* proto */
2661 stream_putc(s, zclient->redist_default);
2662 /* instance */
2663 stream_putw(s, zclient->instance);
2664 /* keep */
2665 stream_putc(s, keep);
2666 /* chunk size */
2667 stream_putl(s, chunk_size);
2668 /* requested chunk base */
2669 stream_putl(s, base);
2670 /* Put length at the first point of the stream. */
2671 stream_putw_at(s, 0, stream_get_endp(s));
2672
2673 ret = writen(zclient->sock, s->data, stream_get_endp(s));
2674 if (ret < 0) {
2675 flog_err(EC_LIB_ZAPI_SOCKET, "Can't write to zclient sock");
2676 close(zclient->sock);
2677 zclient->sock = -1;
2678 return -1;
2679 }
2680 if (ret == 0) {
2681 flog_err(EC_LIB_ZAPI_SOCKET, "Zclient sock closed");
2682 close(zclient->sock);
2683 zclient->sock = -1;
2684 return -1;
2685 }
2686 if (zclient_debug)
2687 zlog_debug("Label chunk request (%d bytes) sent", ret);
2688
2689 /* read response */
2690 if (zclient_read_sync_response(zclient, ZEBRA_GET_LABEL_CHUNK) != 0)
2691 return -1;
2692
2693 /* parse response */
2694 s = zclient->ibuf;
2695
2696 /* read proto and instance */
2697 uint8_t proto;
2698 uint8_t instance;
2699
2700 STREAM_GETC(s, proto);
2701 STREAM_GETW(s, instance);
2702
2703 /* sanities */
2704 if (proto != zclient->redist_default)
2705 flog_err(EC_LIB_ZAPI_ENCODE,
2706 "Wrong proto (%u) in get chunk response. Should be %u",
2707 proto, zclient->redist_default);
2708 if (instance != zclient->instance)
2709 flog_err(EC_LIB_ZAPI_ENCODE,
2710 "Wrong instId (%u) in get chunk response Should be %u",
2711 instance, zclient->instance);
2712
2713 /* if we requested a specific chunk and it could not be allocated, the
2714 * response message will end here
2715 */
2716 if (!STREAM_READABLE(s)) {
2717 zlog_info("Unable to assign Label Chunk to %s instance %u",
2718 zebra_route_string(proto), instance);
2719 return -1;
2720 }
2721
2722 /* keep */
2723 STREAM_GETC(s, response_keep);
2724 /* start and end labels */
2725 STREAM_GETL(s, *start);
2726 STREAM_GETL(s, *end);
2727
2728 /* not owning this response */
2729 if (keep != response_keep) {
2730 flog_err(
2731 EC_LIB_ZAPI_ENCODE,
2732 "Invalid Label chunk: %u - %u, keeps mismatch %u != %u",
2733 *start, *end, keep, response_keep);
2734 }
2735 /* sanity */
2736 if (*start > *end || *start < MPLS_LABEL_UNRESERVED_MIN
2737 || *end > MPLS_LABEL_UNRESERVED_MAX) {
2738 flog_err(EC_LIB_ZAPI_ENCODE, "Invalid Label chunk: %u - %u",
2739 *start, *end);
2740 return -1;
2741 }
2742
2743 if (zclient_debug)
2744 zlog_debug("Label Chunk assign: %u - %u (%u)", *start, *end,
2745 response_keep);
2746
2747 return 0;
2748
2749 stream_failure:
2750 return -1;
2751 }
2752
2753 /**
2754 * Function to release a label chunk
2755 *
2756 * @param zclient Zclient used to connect to label manager (zebra)
2757 * @param start First label of chunk
2758 * @param end Last label of chunk
2759 * @result 0 on success, -1 otherwise
2760 */
2761 int lm_release_label_chunk(struct zclient *zclient, uint32_t start,
2762 uint32_t end)
2763 {
2764 int ret;
2765 struct stream *s;
2766
2767 if (zclient_debug)
2768 zlog_debug("Releasing Label Chunk %u - %u", start, end);
2769
2770 if (zclient->sock < 0)
2771 return -1;
2772
2773 /* send request */
2774 s = zclient->obuf;
2775 stream_reset(s);
2776 zclient_create_header(s, ZEBRA_RELEASE_LABEL_CHUNK, VRF_DEFAULT);
2777
2778 /* proto */
2779 stream_putc(s, zclient->redist_default);
2780 /* instance */
2781 stream_putw(s, zclient->instance);
2782 /* start */
2783 stream_putl(s, start);
2784 /* end */
2785 stream_putl(s, end);
2786
2787 /* Put length at the first point of the stream. */
2788 stream_putw_at(s, 0, stream_get_endp(s));
2789
2790 ret = writen(zclient->sock, s->data, stream_get_endp(s));
2791 if (ret < 0) {
2792 flog_err(EC_LIB_ZAPI_SOCKET, "Can't write to zclient sock");
2793 close(zclient->sock);
2794 zclient->sock = -1;
2795 return -1;
2796 }
2797 if (ret == 0) {
2798 flog_err(EC_LIB_ZAPI_SOCKET, "Zclient sock connection closed");
2799 close(zclient->sock);
2800 zclient->sock = -1;
2801 return -1;
2802 }
2803
2804 return 0;
2805 }
2806
2807 /**
2808 * Connect to table manager in a syncronous way
2809 *
2810 * It first writes the request to zcient output buffer and then
2811 * immediately reads the answer from the input buffer.
2812 *
2813 * @param zclient Zclient used to connect to table manager (zebra)
2814 * @result Result of response
2815 */
2816 int tm_table_manager_connect(struct zclient *zclient)
2817 {
2818 int ret;
2819 struct stream *s;
2820 uint8_t result;
2821
2822 if (zclient_debug)
2823 zlog_debug("Connecting to Table Manager");
2824
2825 if (zclient->sock < 0)
2826 return ZCLIENT_SEND_FAILURE;
2827
2828 /* send request */
2829 s = zclient->obuf;
2830 stream_reset(s);
2831 zclient_create_header(s, ZEBRA_TABLE_MANAGER_CONNECT, VRF_DEFAULT);
2832
2833 /* proto */
2834 stream_putc(s, zclient->redist_default);
2835 /* instance */
2836 stream_putw(s, zclient->instance);
2837
2838 /* Put length at the first point of the stream. */
2839 stream_putw_at(s, 0, stream_get_endp(s));
2840
2841 ret = zclient_send_message(zclient);
2842 if (ret == ZCLIENT_SEND_FAILURE)
2843 return -1;
2844
2845 if (zclient_debug)
2846 zlog_debug("%s: Table manager connect request sent", __func__);
2847
2848 /* read response */
2849 if (zclient_read_sync_response(zclient, ZEBRA_TABLE_MANAGER_CONNECT)
2850 != 0)
2851 return -1;
2852
2853 /* result */
2854 s = zclient->ibuf;
2855 STREAM_GETC(s, result);
2856 if (zclient_debug)
2857 zlog_debug(
2858 "%s: Table Manager connect response received, result %u",
2859 __func__, result);
2860
2861 return (int)result;
2862 stream_failure:
2863 return -1;
2864 }
2865
2866 /**
2867 * Function to request a table chunk in a syncronous way
2868 *
2869 * It first writes the request to zclient output buffer and then
2870 * immediately reads the answer from the input buffer.
2871 *
2872 * @param zclient Zclient used to connect to table manager (zebra)
2873 * @param chunk_size Amount of table requested
2874 * @param start to write first assigned chunk table RT ID to
2875 * @param end To write last assigned chunk table RT ID to
2876 * @result 0 on success, -1 otherwise
2877 */
2878 int tm_get_table_chunk(struct zclient *zclient, uint32_t chunk_size,
2879 uint32_t *start, uint32_t *end)
2880 {
2881 int ret;
2882 struct stream *s;
2883
2884 if (zclient_debug)
2885 zlog_debug("Getting Table Chunk");
2886
2887 if (zclient->sock < 0)
2888 return -1;
2889
2890 /* send request */
2891 s = zclient->obuf;
2892 stream_reset(s);
2893 zclient_create_header(s, ZEBRA_GET_TABLE_CHUNK, VRF_DEFAULT);
2894 /* chunk size */
2895 stream_putl(s, chunk_size);
2896 /* Put length at the first point of the stream. */
2897 stream_putw_at(s, 0, stream_get_endp(s));
2898
2899 ret = writen(zclient->sock, s->data, stream_get_endp(s));
2900 if (ret < 0) {
2901 flog_err(EC_LIB_ZAPI_SOCKET, "%s: can't write to zclient->sock",
2902 __func__);
2903 close(zclient->sock);
2904 zclient->sock = -1;
2905 return -1;
2906 }
2907 if (ret == 0) {
2908 flog_err(EC_LIB_ZAPI_SOCKET,
2909 "%s: zclient->sock connection closed", __func__);
2910 close(zclient->sock);
2911 zclient->sock = -1;
2912 return -1;
2913 }
2914 if (zclient_debug)
2915 zlog_debug("%s: Table chunk request (%d bytes) sent", __func__,
2916 ret);
2917
2918 /* read response */
2919 if (zclient_read_sync_response(zclient, ZEBRA_GET_TABLE_CHUNK) != 0)
2920 return -1;
2921
2922 s = zclient->ibuf;
2923 /* start and end table IDs */
2924 STREAM_GETL(s, *start);
2925 STREAM_GETL(s, *end);
2926
2927 if (zclient_debug)
2928 zlog_debug("Table Chunk assign: %u - %u ", *start, *end);
2929
2930 return 0;
2931 stream_failure:
2932 return -1;
2933 }
2934
2935 /**
2936 * Function to release a table chunk
2937 *
2938 * @param zclient Zclient used to connect to table manager (zebra)
2939 * @param start First label of table
2940 * @param end Last label of chunk
2941 * @result 0 on success, -1 otherwise
2942 */
2943 int tm_release_table_chunk(struct zclient *zclient, uint32_t start,
2944 uint32_t end)
2945 {
2946 struct stream *s;
2947
2948 if (zclient_debug)
2949 zlog_debug("Releasing Table Chunk");
2950
2951 if (zclient->sock < 0)
2952 return -1;
2953
2954 /* send request */
2955 s = zclient->obuf;
2956 stream_reset(s);
2957 zclient_create_header(s, ZEBRA_RELEASE_TABLE_CHUNK, VRF_DEFAULT);
2958
2959 /* start */
2960 stream_putl(s, start);
2961 /* end */
2962 stream_putl(s, end);
2963
2964 /* Put length at the first point of the stream. */
2965 stream_putw_at(s, 0, stream_get_endp(s));
2966
2967 if (zclient_send_message(zclient) == ZCLIENT_SEND_FAILURE)
2968 return -1;
2969
2970 return 0;
2971 }
2972
2973 enum zclient_send_status zebra_send_sr_policy(struct zclient *zclient, int cmd,
2974 struct zapi_sr_policy *zp)
2975 {
2976 if (zapi_sr_policy_encode(zclient->obuf, cmd, zp) < 0)
2977 return ZCLIENT_SEND_FAILURE;
2978 return zclient_send_message(zclient);
2979 }
2980
2981 int zapi_sr_policy_encode(struct stream *s, int cmd, struct zapi_sr_policy *zp)
2982 {
2983 struct zapi_srte_tunnel *zt = &zp->segment_list;
2984
2985 stream_reset(s);
2986
2987 zclient_create_header(s, cmd, VRF_DEFAULT);
2988 stream_putl(s, zp->color);
2989 stream_put_ipaddr(s, &zp->endpoint);
2990 stream_write(s, &zp->name, SRTE_POLICY_NAME_MAX_LENGTH);
2991
2992 stream_putc(s, zt->type);
2993 stream_putl(s, zt->local_label);
2994
2995 if (zt->label_num > MPLS_MAX_LABELS) {
2996 flog_err(EC_LIB_ZAPI_ENCODE,
2997 "%s: label %u: can't encode %u labels (maximum is %u)",
2998 __func__, zt->local_label, zt->label_num,
2999 MPLS_MAX_LABELS);
3000 return -1;
3001 }
3002 stream_putw(s, zt->label_num);
3003
3004 for (int i = 0; i < zt->label_num; i++)
3005 stream_putl(s, zt->labels[i]);
3006
3007 /* Put length at the first point of the stream. */
3008 stream_putw_at(s, 0, stream_get_endp(s));
3009
3010 return 0;
3011 }
3012
3013 int zapi_sr_policy_decode(struct stream *s, struct zapi_sr_policy *zp)
3014 {
3015 memset(zp, 0, sizeof(*zp));
3016
3017 struct zapi_srte_tunnel *zt = &zp->segment_list;
3018
3019 STREAM_GETL(s, zp->color);
3020 STREAM_GET_IPADDR(s, &zp->endpoint);
3021 STREAM_GET(&zp->name, s, SRTE_POLICY_NAME_MAX_LENGTH);
3022
3023 /* segment list of active candidate path */
3024 STREAM_GETC(s, zt->type);
3025 STREAM_GETL(s, zt->local_label);
3026 STREAM_GETW(s, zt->label_num);
3027 if (zt->label_num > MPLS_MAX_LABELS) {
3028 flog_err(EC_LIB_ZAPI_ENCODE,
3029 "%s: label %u: can't decode %u labels (maximum is %u)",
3030 __func__, zt->local_label, zt->label_num,
3031 MPLS_MAX_LABELS);
3032 return -1;
3033 }
3034 for (int i = 0; i < zt->label_num; i++)
3035 STREAM_GETL(s, zt->labels[i]);
3036
3037 return 0;
3038
3039 stream_failure:
3040 return -1;
3041 }
3042
3043 int zapi_sr_policy_notify_status_decode(struct stream *s,
3044 struct zapi_sr_policy *zp)
3045 {
3046 memset(zp, 0, sizeof(*zp));
3047
3048 STREAM_GETL(s, zp->color);
3049 STREAM_GET_IPADDR(s, &zp->endpoint);
3050 STREAM_GET(&zp->name, s, SRTE_POLICY_NAME_MAX_LENGTH);
3051 STREAM_GETL(s, zp->status);
3052
3053 return 0;
3054
3055 stream_failure:
3056 return -1;
3057 }
3058
3059 enum zclient_send_status zebra_send_mpls_labels(struct zclient *zclient,
3060 int cmd, struct zapi_labels *zl)
3061 {
3062 if (zapi_labels_encode(zclient->obuf, cmd, zl) < 0)
3063 return ZCLIENT_SEND_FAILURE;
3064 return zclient_send_message(zclient);
3065 }
3066
3067 int zapi_labels_encode(struct stream *s, int cmd, struct zapi_labels *zl)
3068 {
3069 struct zapi_nexthop *znh;
3070
3071 stream_reset(s);
3072
3073 zclient_create_header(s, cmd, VRF_DEFAULT);
3074 stream_putc(s, zl->message);
3075 stream_putc(s, zl->type);
3076 stream_putl(s, zl->local_label);
3077
3078 if (CHECK_FLAG(zl->message, ZAPI_LABELS_FTN)) {
3079 stream_putw(s, zl->route.prefix.family);
3080 stream_put_prefix(s, &zl->route.prefix);
3081 stream_putc(s, zl->route.type);
3082 stream_putw(s, zl->route.instance);
3083 }
3084
3085 if (zl->nexthop_num > MULTIPATH_NUM) {
3086 flog_err(
3087 EC_LIB_ZAPI_ENCODE,
3088 "%s: label %u: can't encode %u nexthops (maximum is %u)",
3089 __func__, zl->local_label, zl->nexthop_num,
3090 MULTIPATH_NUM);
3091 return -1;
3092 }
3093 stream_putw(s, zl->nexthop_num);
3094
3095 for (int i = 0; i < zl->nexthop_num; i++) {
3096 znh = &zl->nexthops[i];
3097
3098 if (zapi_nexthop_encode(s, znh, 0, 0) < 0)
3099 return -1;
3100 }
3101
3102 if (CHECK_FLAG(zl->message, ZAPI_LABELS_HAS_BACKUPS)) {
3103
3104 if (zl->backup_nexthop_num > MULTIPATH_NUM) {
3105 flog_err(
3106 EC_LIB_ZAPI_ENCODE,
3107 "%s: label %u: can't encode %u nexthops (maximum is %u)",
3108 __func__, zl->local_label, zl->nexthop_num,
3109 MULTIPATH_NUM);
3110 return -1;
3111 }
3112 stream_putw(s, zl->backup_nexthop_num);
3113
3114 for (int i = 0; i < zl->backup_nexthop_num; i++) {
3115 znh = &zl->backup_nexthops[i];
3116
3117 if (zapi_nexthop_encode(s, znh, 0, 0) < 0)
3118 return -1;
3119 }
3120
3121 }
3122
3123 /* Put length at the first point of the stream. */
3124 stream_putw_at(s, 0, stream_get_endp(s));
3125
3126 return 0;
3127 }
3128
3129 int zapi_labels_decode(struct stream *s, struct zapi_labels *zl)
3130 {
3131 struct zapi_nexthop *znh;
3132
3133 memset(zl, 0, sizeof(*zl));
3134
3135 /* Get data. */
3136 STREAM_GETC(s, zl->message);
3137 STREAM_GETC(s, zl->type);
3138 STREAM_GETL(s, zl->local_label);
3139
3140 if (CHECK_FLAG(zl->message, ZAPI_LABELS_FTN)) {
3141 size_t psize;
3142
3143 STREAM_GETW(s, zl->route.prefix.family);
3144 STREAM_GETC(s, zl->route.prefix.prefixlen);
3145
3146 psize = PSIZE(zl->route.prefix.prefixlen);
3147 switch (zl->route.prefix.family) {
3148 case AF_INET:
3149 if (zl->route.prefix.prefixlen > IPV4_MAX_BITLEN) {
3150 zlog_debug(
3151 "%s: Specified prefix length %d is greater than a v4 address can support",
3152 __func__, zl->route.prefix.prefixlen);
3153 return -1;
3154 }
3155 STREAM_GET(&zl->route.prefix.u.prefix4.s_addr, s,
3156 psize);
3157 break;
3158 case AF_INET6:
3159 if (zl->route.prefix.prefixlen > IPV6_MAX_BITLEN) {
3160 zlog_debug(
3161 "%s: Specified prefix length %d is greater than a v6 address can support",
3162 __func__, zl->route.prefix.prefixlen);
3163 return -1;
3164 }
3165 STREAM_GET(&zl->route.prefix.u.prefix6, s, psize);
3166 break;
3167 default:
3168 flog_err(EC_LIB_ZAPI_ENCODE,
3169 "%s: Specified family %u is not v4 or v6",
3170 __func__, zl->route.prefix.family);
3171 return -1;
3172 }
3173
3174 STREAM_GETC(s, zl->route.type);
3175 STREAM_GETW(s, zl->route.instance);
3176 }
3177
3178 STREAM_GETW(s, zl->nexthop_num);
3179
3180 if (zl->nexthop_num > MULTIPATH_NUM) {
3181 flog_warn(
3182 EC_LIB_ZAPI_ENCODE,
3183 "%s: Prefix %pFX has %d nexthops, but we can only use the first %d",
3184 __func__, &zl->route.prefix, zl->nexthop_num,
3185 MULTIPATH_NUM);
3186 }
3187
3188 zl->nexthop_num = MIN(MULTIPATH_NUM, zl->nexthop_num);
3189
3190 for (int i = 0; i < zl->nexthop_num; i++) {
3191 znh = &zl->nexthops[i];
3192
3193 if (zapi_nexthop_decode(s, znh, 0, 0) < 0)
3194 return -1;
3195 }
3196
3197 if (CHECK_FLAG(zl->message, ZAPI_LABELS_HAS_BACKUPS)) {
3198 STREAM_GETW(s, zl->backup_nexthop_num);
3199
3200 if (zl->backup_nexthop_num > MULTIPATH_NUM) {
3201 flog_warn(
3202 EC_LIB_ZAPI_ENCODE,
3203 "%s: Prefix %pFX has %d backup nexthops, but we can only use the first %d",
3204 __func__, &zl->route.prefix,
3205 zl->backup_nexthop_num, MULTIPATH_NUM);
3206 }
3207
3208 zl->backup_nexthop_num = MIN(MULTIPATH_NUM,
3209 zl->backup_nexthop_num);
3210
3211 for (int i = 0; i < zl->backup_nexthop_num; i++) {
3212 znh = &zl->backup_nexthops[i];
3213
3214 if (zapi_nexthop_decode(s, znh, 0, 0) < 0)
3215 return -1;
3216 }
3217 }
3218
3219 return 0;
3220 stream_failure:
3221 return -1;
3222 }
3223
3224 enum zclient_send_status zebra_send_pw(struct zclient *zclient, int command,
3225 struct zapi_pw *pw)
3226 {
3227 struct stream *s;
3228
3229 /* Reset stream. */
3230 s = zclient->obuf;
3231 stream_reset(s);
3232
3233 zclient_create_header(s, command, VRF_DEFAULT);
3234 stream_write(s, pw->ifname, IF_NAMESIZE);
3235 stream_putl(s, pw->ifindex);
3236
3237 /* Put type */
3238 stream_putl(s, pw->type);
3239
3240 /* Put nexthop */
3241 stream_putl(s, pw->af);
3242 switch (pw->af) {
3243 case AF_INET:
3244 stream_put_in_addr(s, &pw->nexthop.ipv4);
3245 break;
3246 case AF_INET6:
3247 stream_write(s, (uint8_t *)&pw->nexthop.ipv6, 16);
3248 break;
3249 default:
3250 flog_err(EC_LIB_ZAPI_ENCODE, "%s: unknown af", __func__);
3251 return ZCLIENT_SEND_FAILURE;
3252 }
3253
3254 /* Put labels */
3255 stream_putl(s, pw->local_label);
3256 stream_putl(s, pw->remote_label);
3257
3258 /* Put flags */
3259 stream_putc(s, pw->flags);
3260
3261 /* Protocol specific fields */
3262 stream_write(s, &pw->data, sizeof(union pw_protocol_fields));
3263
3264 /* Put length at the first point of the stream. */
3265 stream_putw_at(s, 0, stream_get_endp(s));
3266
3267 return zclient_send_message(zclient);
3268 }
3269
3270 /*
3271 * Receive PW status update from Zebra and send it to LDE process.
3272 */
3273 int zebra_read_pw_status_update(ZAPI_CALLBACK_ARGS, struct zapi_pw_status *pw)
3274 {
3275 struct stream *s;
3276
3277 memset(pw, 0, sizeof(struct zapi_pw_status));
3278 s = zclient->ibuf;
3279
3280 /* Get data. */
3281 stream_get(pw->ifname, s, IF_NAMESIZE);
3282 STREAM_GETL(s, pw->ifindex);
3283 STREAM_GETL(s, pw->status);
3284
3285 return 0;
3286 stream_failure:
3287 return -1;
3288 }
3289
3290 static void zclient_capability_decode(ZAPI_CALLBACK_ARGS)
3291 {
3292 struct zclient_capabilities cap;
3293 struct stream *s = zclient->ibuf;
3294 int vrf_backend;
3295 uint8_t mpls_enabled;
3296
3297 STREAM_GETL(s, vrf_backend);
3298
3299 if (vrf_backend < 0 || vrf_configure_backend(vrf_backend)) {
3300 flog_err(EC_LIB_ZAPI_ENCODE,
3301 "%s: Garbage VRF backend type: %d\n", __func__,
3302 vrf_backend);
3303 goto stream_failure;
3304 }
3305
3306
3307 memset(&cap, 0, sizeof(cap));
3308 STREAM_GETC(s, mpls_enabled);
3309 cap.mpls_enabled = !!mpls_enabled;
3310 STREAM_GETL(s, cap.ecmp);
3311 STREAM_GETC(s, cap.role);
3312
3313 if (zclient->zebra_capabilities)
3314 (*zclient->zebra_capabilities)(&cap);
3315
3316 stream_failure:
3317 return;
3318 }
3319
3320 enum zclient_send_status zclient_send_mlag_register(struct zclient *client,
3321 uint32_t bit_map)
3322 {
3323 struct stream *s;
3324
3325 s = client->obuf;
3326 stream_reset(s);
3327
3328 zclient_create_header(s, ZEBRA_MLAG_CLIENT_REGISTER, VRF_DEFAULT);
3329 stream_putl(s, bit_map);
3330
3331 stream_putw_at(s, 0, stream_get_endp(s));
3332 return zclient_send_message(client);
3333 }
3334
3335 enum zclient_send_status zclient_send_mlag_deregister(struct zclient *client)
3336 {
3337 return zebra_message_send(client, ZEBRA_MLAG_CLIENT_UNREGISTER, VRF_DEFAULT);
3338 }
3339
3340 enum zclient_send_status zclient_send_mlag_data(struct zclient *client,
3341 struct stream *client_s)
3342 {
3343 struct stream *s;
3344
3345 s = client->obuf;
3346 stream_reset(s);
3347
3348 zclient_create_header(s, ZEBRA_MLAG_FORWARD_MSG, VRF_DEFAULT);
3349 stream_put(s, client_s->data, client_s->endp);
3350
3351 stream_putw_at(s, 0, stream_get_endp(s));
3352 return zclient_send_message(client);
3353 }
3354
3355 static void zclient_mlag_process_up(ZAPI_CALLBACK_ARGS)
3356 {
3357 if (zclient->mlag_process_up)
3358 (*zclient->mlag_process_up)();
3359 }
3360
3361 static void zclient_mlag_process_down(ZAPI_CALLBACK_ARGS)
3362 {
3363 if (zclient->mlag_process_down)
3364 (*zclient->mlag_process_down)();
3365 }
3366
3367 static void zclient_mlag_handle_msg(ZAPI_CALLBACK_ARGS)
3368 {
3369 if (zclient->mlag_handle_msg)
3370 (*zclient->mlag_handle_msg)(zclient->ibuf, length);
3371 }
3372
3373 /*
3374 * Send an OPAQUE message, contents opaque to zebra. The message header
3375 * is a message subtype.
3376 */
3377 enum zclient_send_status zclient_send_opaque(struct zclient *zclient,
3378 uint32_t type, const uint8_t *data,
3379 size_t datasize)
3380 {
3381 struct stream *s;
3382 uint16_t flags = 0;
3383
3384 /* Check buffer size */
3385 if (STREAM_SIZE(zclient->obuf) <
3386 (ZEBRA_HEADER_SIZE + sizeof(type) + datasize))
3387 return ZCLIENT_SEND_FAILURE;
3388
3389 s = zclient->obuf;
3390 stream_reset(s);
3391
3392 zclient_create_header(s, ZEBRA_OPAQUE_MESSAGE, VRF_DEFAULT);
3393
3394 /* Send sub-type and flags */
3395 stream_putl(s, type);
3396 stream_putw(s, flags);
3397
3398 /* Send opaque data */
3399 stream_write(s, data, datasize);
3400
3401 /* Put length into the header at the start of the stream. */
3402 stream_putw_at(s, 0, stream_get_endp(s));
3403
3404 return zclient_send_message(zclient);
3405 }
3406
3407 /*
3408 * Send an OPAQUE message to a specific zclient. The contents are opaque
3409 * to zebra.
3410 */
3411 enum zclient_send_status
3412 zclient_send_opaque_unicast(struct zclient *zclient, uint32_t type,
3413 uint8_t proto, uint16_t instance,
3414 uint32_t session_id, const uint8_t *data,
3415 size_t datasize)
3416 {
3417 struct stream *s;
3418 uint16_t flags = 0;
3419
3420 /* Check buffer size */
3421 if (STREAM_SIZE(zclient->obuf) <
3422 (ZEBRA_HEADER_SIZE + sizeof(struct zapi_opaque_msg) + datasize))
3423 return ZCLIENT_SEND_FAILURE;
3424
3425 s = zclient->obuf;
3426 stream_reset(s);
3427
3428 zclient_create_header(s, ZEBRA_OPAQUE_MESSAGE, VRF_DEFAULT);
3429
3430 /* Send sub-type and flags */
3431 SET_FLAG(flags, ZAPI_OPAQUE_FLAG_UNICAST);
3432 stream_putl(s, type);
3433 stream_putw(s, flags);
3434
3435 /* Send destination client info */
3436 stream_putc(s, proto);
3437 stream_putw(s, instance);
3438 stream_putl(s, session_id);
3439
3440 /* Send opaque data */
3441 stream_write(s, data, datasize);
3442
3443 /* Put length into the header at the start of the stream. */
3444 stream_putw_at(s, 0, stream_get_endp(s));
3445
3446 return zclient_send_message(zclient);
3447 }
3448
3449 /*
3450 * Decode incoming opaque message into info struct
3451 */
3452 int zclient_opaque_decode(struct stream *s, struct zapi_opaque_msg *info)
3453 {
3454 memset(info, 0, sizeof(*info));
3455
3456 /* Decode subtype and flags */
3457 STREAM_GETL(s, info->type);
3458 STREAM_GETW(s, info->flags);
3459
3460 /* Decode unicast client info if present */
3461 if (CHECK_FLAG(info->flags, ZAPI_OPAQUE_FLAG_UNICAST)) {
3462 STREAM_GETC(s, info->proto);
3463 STREAM_GETW(s, info->instance);
3464 STREAM_GETL(s, info->session_id);
3465 }
3466
3467 info->len = STREAM_READABLE(s);
3468
3469 return 0;
3470
3471 stream_failure:
3472
3473 return -1;
3474 }
3475
3476 /*
3477 * Send a registration request for opaque messages with a specified subtype.
3478 */
3479 enum zclient_send_status zclient_register_opaque(struct zclient *zclient,
3480 uint32_t type)
3481 {
3482 struct stream *s;
3483
3484 s = zclient->obuf;
3485 stream_reset(s);
3486
3487 zclient_create_header(s, ZEBRA_OPAQUE_REGISTER, VRF_DEFAULT);
3488
3489 /* Send sub-type */
3490 stream_putl(s, type);
3491
3492 /* Add zclient info */
3493 stream_putc(s, zclient->redist_default);
3494 stream_putw(s, zclient->instance);
3495 stream_putl(s, zclient->session_id);
3496
3497 /* Put length at the first point of the stream. */
3498 stream_putw_at(s, 0, stream_get_endp(s));
3499
3500 return zclient_send_message(zclient);
3501 }
3502
3503 /*
3504 * Send an un-registration request for a specified opaque subtype.
3505 */
3506 enum zclient_send_status zclient_unregister_opaque(struct zclient *zclient,
3507 uint32_t type)
3508 {
3509 struct stream *s;
3510
3511 s = zclient->obuf;
3512 stream_reset(s);
3513
3514 zclient_create_header(s, ZEBRA_OPAQUE_UNREGISTER, VRF_DEFAULT);
3515
3516 /* Send sub-type */
3517 stream_putl(s, type);
3518
3519 /* Add zclient info */
3520 stream_putc(s, zclient->redist_default);
3521 stream_putw(s, zclient->instance);
3522 stream_putl(s, zclient->session_id);
3523
3524 /* Put length at the first point of the stream. */
3525 stream_putw_at(s, 0, stream_get_endp(s));
3526
3527 return zclient_send_message(zclient);
3528 }
3529
3530 /* Utility to decode opaque registration info */
3531 int zapi_opaque_reg_decode(struct stream *s, struct zapi_opaque_reg_info *info)
3532 {
3533 STREAM_GETL(s, info->type);
3534 STREAM_GETC(s, info->proto);
3535 STREAM_GETW(s, info->instance);
3536 STREAM_GETL(s, info->session_id);
3537
3538 return 0;
3539
3540 stream_failure:
3541
3542 return -1;
3543 }
3544
3545 /* Utility to decode client close notify info */
3546 int zapi_client_close_notify_decode(struct stream *s,
3547 struct zapi_client_close_info *info)
3548 {
3549 memset(info, 0, sizeof(*info));
3550
3551 STREAM_GETC(s, info->proto);
3552 STREAM_GETW(s, info->instance);
3553 STREAM_GETL(s, info->session_id);
3554
3555 return 0;
3556
3557 stream_failure:
3558
3559 return -1;
3560 }
3561
3562 /* Zebra client message read function. */
3563 static int zclient_read(struct thread *thread)
3564 {
3565 size_t already;
3566 uint16_t length, command;
3567 uint8_t marker, version;
3568 vrf_id_t vrf_id;
3569 struct zclient *zclient;
3570
3571 /* Get socket to zebra. */
3572 zclient = THREAD_ARG(thread);
3573 zclient->t_read = NULL;
3574
3575 /* Read zebra header (if we don't have it already). */
3576 if ((already = stream_get_endp(zclient->ibuf)) < ZEBRA_HEADER_SIZE) {
3577 ssize_t nbyte;
3578 if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
3579 ZEBRA_HEADER_SIZE - already))
3580 == 0)
3581 || (nbyte == -1)) {
3582 if (zclient_debug)
3583 zlog_debug(
3584 "zclient connection closed socket [%d].",
3585 zclient->sock);
3586 return zclient_failed(zclient);
3587 }
3588 if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE - already)) {
3589 /* Try again later. */
3590 zclient_event(ZCLIENT_READ, zclient);
3591 return 0;
3592 }
3593 already = ZEBRA_HEADER_SIZE;
3594 }
3595
3596 /* Reset to read from the beginning of the incoming packet. */
3597 stream_set_getp(zclient->ibuf, 0);
3598
3599 /* Fetch header values. */
3600 length = stream_getw(zclient->ibuf);
3601 marker = stream_getc(zclient->ibuf);
3602 version = stream_getc(zclient->ibuf);
3603 vrf_id = stream_getl(zclient->ibuf);
3604 command = stream_getw(zclient->ibuf);
3605
3606 if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) {
3607 flog_err(
3608 EC_LIB_ZAPI_MISSMATCH,
3609 "%s: socket %d version mismatch, marker %d, version %d",
3610 __func__, zclient->sock, marker, version);
3611 return zclient_failed(zclient);
3612 }
3613
3614 if (length < ZEBRA_HEADER_SIZE) {
3615 flog_err(EC_LIB_ZAPI_MISSMATCH,
3616 "%s: socket %d message length %u is less than %d ",
3617 __func__, zclient->sock, length, ZEBRA_HEADER_SIZE);
3618 return zclient_failed(zclient);
3619 }
3620
3621 /* Length check. */
3622 if (length > STREAM_SIZE(zclient->ibuf)) {
3623 struct stream *ns;
3624 flog_err(
3625 EC_LIB_ZAPI_ENCODE,
3626 "%s: message size %u exceeds buffer size %lu, expanding...",
3627 __func__, length,
3628 (unsigned long)STREAM_SIZE(zclient->ibuf));
3629 ns = stream_new(length);
3630 stream_copy(ns, zclient->ibuf);
3631 stream_free(zclient->ibuf);
3632 zclient->ibuf = ns;
3633 }
3634
3635 /* Read rest of zebra packet. */
3636 if (already < length) {
3637 ssize_t nbyte;
3638 if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
3639 length - already))
3640 == 0)
3641 || (nbyte == -1)) {
3642 if (zclient_debug)
3643 zlog_debug(
3644 "zclient connection closed socket [%d].",
3645 zclient->sock);
3646 return zclient_failed(zclient);
3647 }
3648 if (nbyte != (ssize_t)(length - already)) {
3649 /* Try again later. */
3650 zclient_event(ZCLIENT_READ, zclient);
3651 return 0;
3652 }
3653 }
3654
3655 length -= ZEBRA_HEADER_SIZE;
3656
3657 if (zclient_debug)
3658 zlog_debug("zclient 0x%p command %s VRF %u",
3659 (void *)zclient, zserv_command_string(command),
3660 vrf_id);
3661
3662 switch (command) {
3663 case ZEBRA_CAPABILITIES:
3664 zclient_capability_decode(command, zclient, length, vrf_id);
3665 break;
3666 case ZEBRA_ROUTER_ID_UPDATE:
3667 if (zclient->router_id_update)
3668 (*zclient->router_id_update)(command, zclient, length,
3669 vrf_id);
3670 break;
3671 case ZEBRA_VRF_ADD:
3672 zclient_vrf_add(zclient, vrf_id);
3673 break;
3674 case ZEBRA_VRF_DELETE:
3675 zclient_vrf_delete(zclient, vrf_id);
3676 break;
3677 case ZEBRA_INTERFACE_ADD:
3678 zclient_interface_add(zclient, vrf_id);
3679 break;
3680 case ZEBRA_INTERFACE_DELETE:
3681 zclient_interface_delete(zclient, vrf_id);
3682 break;
3683 case ZEBRA_INTERFACE_ADDRESS_ADD:
3684 if (zclient->interface_address_add)
3685 (*zclient->interface_address_add)(command, zclient,
3686 length, vrf_id);
3687 break;
3688 case ZEBRA_INTERFACE_ADDRESS_DELETE:
3689 if (zclient->interface_address_delete)
3690 (*zclient->interface_address_delete)(command, zclient,
3691 length, vrf_id);
3692 break;
3693 case ZEBRA_INTERFACE_BFD_DEST_UPDATE:
3694 if (zclient->interface_bfd_dest_update)
3695 (*zclient->interface_bfd_dest_update)(command, zclient,
3696 length, vrf_id);
3697 break;
3698 case ZEBRA_INTERFACE_NBR_ADDRESS_ADD:
3699 if (zclient->interface_nbr_address_add)
3700 (*zclient->interface_nbr_address_add)(command, zclient,
3701 length, vrf_id);
3702 break;
3703 case ZEBRA_INTERFACE_NBR_ADDRESS_DELETE:
3704 if (zclient->interface_nbr_address_delete)
3705 (*zclient->interface_nbr_address_delete)(
3706 command, zclient, length, vrf_id);
3707 break;
3708 case ZEBRA_INTERFACE_UP:
3709 zclient_interface_up(zclient, vrf_id);
3710 break;
3711 case ZEBRA_INTERFACE_DOWN:
3712 zclient_interface_down(zclient, vrf_id);
3713 break;
3714 case ZEBRA_INTERFACE_VRF_UPDATE:
3715 if (zclient->interface_vrf_update)
3716 (*zclient->interface_vrf_update)(command, zclient,
3717 length, vrf_id);
3718 break;
3719 case ZEBRA_NEXTHOP_UPDATE:
3720 if (zclient_debug)
3721 zlog_debug("zclient rcvd nexthop update");
3722 if (zclient->nexthop_update)
3723 (*zclient->nexthop_update)(command, zclient, length,
3724 vrf_id);
3725 break;
3726 case ZEBRA_IMPORT_CHECK_UPDATE:
3727 if (zclient_debug)
3728 zlog_debug("zclient rcvd import check update");
3729 if (zclient->import_check_update)
3730 (*zclient->import_check_update)(command, zclient,
3731 length, vrf_id);
3732 break;
3733 case ZEBRA_BFD_DEST_REPLAY:
3734 if (zclient->bfd_dest_replay)
3735 (*zclient->bfd_dest_replay)(command, zclient, length,
3736 vrf_id);
3737 break;
3738 case ZEBRA_REDISTRIBUTE_ROUTE_ADD:
3739 if (zclient->redistribute_route_add)
3740 (*zclient->redistribute_route_add)(command, zclient,
3741 length, vrf_id);
3742 break;
3743 case ZEBRA_REDISTRIBUTE_ROUTE_DEL:
3744 if (zclient->redistribute_route_del)
3745 (*zclient->redistribute_route_del)(command, zclient,
3746 length, vrf_id);
3747 break;
3748 case ZEBRA_INTERFACE_LINK_PARAMS:
3749 if (zclient->interface_link_params)
3750 (*zclient->interface_link_params)(command, zclient,
3751 length, vrf_id);
3752 break;
3753 case ZEBRA_FEC_UPDATE:
3754 if (zclient_debug)
3755 zlog_debug("zclient rcvd fec update");
3756 if (zclient->fec_update)
3757 (*zclient->fec_update)(command, zclient, length);
3758 break;
3759 case ZEBRA_LOCAL_ES_ADD:
3760 if (zclient->local_es_add)
3761 (*zclient->local_es_add)(command, zclient, length,
3762 vrf_id);
3763 break;
3764 case ZEBRA_LOCAL_ES_DEL:
3765 if (zclient->local_es_del)
3766 (*zclient->local_es_del)(command, zclient, length,
3767 vrf_id);
3768 break;
3769 case ZEBRA_LOCAL_ES_EVI_ADD:
3770 if (zclient->local_es_evi_add)
3771 (*zclient->local_es_evi_add)(command, zclient, length,
3772 vrf_id);
3773 break;
3774 case ZEBRA_LOCAL_ES_EVI_DEL:
3775 if (zclient->local_es_evi_del)
3776 (*zclient->local_es_evi_del)(command, zclient, length,
3777 vrf_id);
3778 break;
3779 case ZEBRA_VNI_ADD:
3780 if (zclient->local_vni_add)
3781 (*zclient->local_vni_add)(command, zclient, length,
3782 vrf_id);
3783 break;
3784 case ZEBRA_VNI_DEL:
3785 if (zclient->local_vni_del)
3786 (*zclient->local_vni_del)(command, zclient, length,
3787 vrf_id);
3788 break;
3789 case ZEBRA_L3VNI_ADD:
3790 if (zclient->local_l3vni_add)
3791 (*zclient->local_l3vni_add)(command, zclient, length,
3792 vrf_id);
3793 break;
3794 case ZEBRA_L3VNI_DEL:
3795 if (zclient->local_l3vni_del)
3796 (*zclient->local_l3vni_del)(command, zclient, length,
3797 vrf_id);
3798 break;
3799 case ZEBRA_MACIP_ADD:
3800 if (zclient->local_macip_add)
3801 (*zclient->local_macip_add)(command, zclient, length,
3802 vrf_id);
3803 break;
3804 case ZEBRA_MACIP_DEL:
3805 if (zclient->local_macip_del)
3806 (*zclient->local_macip_del)(command, zclient, length,
3807 vrf_id);
3808 break;
3809 case ZEBRA_IP_PREFIX_ROUTE_ADD:
3810 if (zclient->local_ip_prefix_add)
3811 (*zclient->local_ip_prefix_add)(command, zclient,
3812 length, vrf_id);
3813 break;
3814 case ZEBRA_IP_PREFIX_ROUTE_DEL:
3815 if (zclient->local_ip_prefix_del)
3816 (*zclient->local_ip_prefix_del)(command, zclient,
3817 length, vrf_id);
3818 break;
3819 case ZEBRA_PW_STATUS_UPDATE:
3820 if (zclient->pw_status_update)
3821 (*zclient->pw_status_update)(command, zclient, length,
3822 vrf_id);
3823 break;
3824 case ZEBRA_ROUTE_NOTIFY_OWNER:
3825 if (zclient->route_notify_owner)
3826 (*zclient->route_notify_owner)(command, zclient, length,
3827 vrf_id);
3828 break;
3829 case ZEBRA_RULE_NOTIFY_OWNER:
3830 if (zclient->rule_notify_owner)
3831 (*zclient->rule_notify_owner)(command, zclient, length,
3832 vrf_id);
3833 break;
3834 case ZEBRA_NHG_NOTIFY_OWNER:
3835 if (zclient->nhg_notify_owner)
3836 (*zclient->nhg_notify_owner)(command, zclient, length,
3837 vrf_id);
3838 break;
3839 case ZEBRA_GET_LABEL_CHUNK:
3840 if (zclient->label_chunk)
3841 (*zclient->label_chunk)(command, zclient, length,
3842 vrf_id);
3843 break;
3844 case ZEBRA_IPSET_NOTIFY_OWNER:
3845 if (zclient->ipset_notify_owner)
3846 (*zclient->ipset_notify_owner)(command, zclient, length,
3847 vrf_id);
3848 break;
3849 case ZEBRA_IPSET_ENTRY_NOTIFY_OWNER:
3850 if (zclient->ipset_entry_notify_owner)
3851 (*zclient->ipset_entry_notify_owner)(command,
3852 zclient, length,
3853 vrf_id);
3854 break;
3855 case ZEBRA_IPTABLE_NOTIFY_OWNER:
3856 if (zclient->iptable_notify_owner)
3857 (*zclient->iptable_notify_owner)(command,
3858 zclient, length,
3859 vrf_id);
3860 break;
3861 case ZEBRA_VXLAN_SG_ADD:
3862 if (zclient->vxlan_sg_add)
3863 (*zclient->vxlan_sg_add)(command, zclient, length,
3864 vrf_id);
3865 break;
3866 case ZEBRA_VXLAN_SG_DEL:
3867 if (zclient->vxlan_sg_del)
3868 (*zclient->vxlan_sg_del)(command, zclient, length,
3869 vrf_id);
3870 break;
3871 case ZEBRA_MLAG_PROCESS_UP:
3872 zclient_mlag_process_up(command, zclient, length, vrf_id);
3873 break;
3874 case ZEBRA_MLAG_PROCESS_DOWN:
3875 zclient_mlag_process_down(command, zclient, length, vrf_id);
3876 break;
3877 case ZEBRA_MLAG_FORWARD_MSG:
3878 zclient_mlag_handle_msg(command, zclient, length, vrf_id);
3879 break;
3880 case ZEBRA_ERROR:
3881 zclient_handle_error(command, zclient, length, vrf_id);
3882 break;
3883 case ZEBRA_OPAQUE_MESSAGE:
3884 if (zclient->opaque_msg_handler)
3885 (*zclient->opaque_msg_handler)(command, zclient, length,
3886 vrf_id);
3887 break;
3888 case ZEBRA_OPAQUE_REGISTER:
3889 if (zclient->opaque_register_handler)
3890 (*zclient->opaque_register_handler)(command, zclient,
3891 length, vrf_id);
3892 break;
3893 case ZEBRA_OPAQUE_UNREGISTER:
3894 if (zclient->opaque_unregister_handler)
3895 (*zclient->opaque_unregister_handler)(command, zclient,
3896 length, vrf_id);
3897 break;
3898 case ZEBRA_SR_POLICY_NOTIFY_STATUS:
3899 if (zclient->sr_policy_notify_status)
3900 (*zclient->sr_policy_notify_status)(command, zclient,
3901 length, vrf_id);
3902 break;
3903 case ZEBRA_CLIENT_CLOSE_NOTIFY:
3904 if (zclient->zebra_client_close_notify)
3905 (*zclient->zebra_client_close_notify)(command, zclient,
3906 length, vrf_id);
3907 break;
3908 default:
3909 break;
3910 }
3911
3912 if (zclient->sock < 0)
3913 /* Connection was closed during packet processing. */
3914 return -1;
3915
3916 /* Register read thread. */
3917 stream_reset(zclient->ibuf);
3918 zclient_event(ZCLIENT_READ, zclient);
3919
3920 return 0;
3921 }
3922
3923 void zclient_redistribute(int command, struct zclient *zclient, afi_t afi,
3924 int type, unsigned short instance, vrf_id_t vrf_id)
3925 {
3926
3927 if (instance) {
3928 if (command == ZEBRA_REDISTRIBUTE_ADD) {
3929 if (redist_check_instance(
3930 &zclient->mi_redist[afi][type], instance))
3931 return;
3932 redist_add_instance(&zclient->mi_redist[afi][type],
3933 instance);
3934 } else {
3935 if (!redist_check_instance(
3936 &zclient->mi_redist[afi][type], instance))
3937 return;
3938 redist_del_instance(&zclient->mi_redist[afi][type],
3939 instance);
3940 }
3941
3942 } else {
3943 if (command == ZEBRA_REDISTRIBUTE_ADD) {
3944 if (vrf_bitmap_check(zclient->redist[afi][type],
3945 vrf_id))
3946 return;
3947 vrf_bitmap_set(zclient->redist[afi][type], vrf_id);
3948 } else {
3949 if (!vrf_bitmap_check(zclient->redist[afi][type],
3950 vrf_id))
3951 return;
3952 vrf_bitmap_unset(zclient->redist[afi][type], vrf_id);
3953 }
3954 }
3955
3956 if (zclient->sock > 0)
3957 zebra_redistribute_send(command, zclient, afi, type, instance,
3958 vrf_id);
3959 }
3960
3961
3962 void zclient_redistribute_default(int command, struct zclient *zclient,
3963 afi_t afi, vrf_id_t vrf_id)
3964 {
3965
3966 if (command == ZEBRA_REDISTRIBUTE_DEFAULT_ADD) {
3967 if (vrf_bitmap_check(zclient->default_information[afi], vrf_id))
3968 return;
3969 vrf_bitmap_set(zclient->default_information[afi], vrf_id);
3970 } else {
3971 if (!vrf_bitmap_check(zclient->default_information[afi],
3972 vrf_id))
3973 return;
3974 vrf_bitmap_unset(zclient->default_information[afi], vrf_id);
3975 }
3976
3977 if (zclient->sock > 0)
3978 zebra_redistribute_default_send(command, zclient, afi, vrf_id);
3979 }
3980
3981 static void zclient_event(enum event event, struct zclient *zclient)
3982 {
3983 switch (event) {
3984 case ZCLIENT_SCHEDULE:
3985 thread_add_event(zclient->master, zclient_connect, zclient, 0,
3986 &zclient->t_connect);
3987 break;
3988 case ZCLIENT_CONNECT:
3989 if (zclient_debug)
3990 zlog_debug(
3991 "zclient connect failures: %d schedule interval is now %d",
3992 zclient->fail, zclient->fail < 3 ? 10 : 60);
3993 thread_add_timer(zclient->master, zclient_connect, zclient,
3994 zclient->fail < 3 ? 10 : 60,
3995 &zclient->t_connect);
3996 break;
3997 case ZCLIENT_READ:
3998 zclient->t_read = NULL;
3999 thread_add_read(zclient->master, zclient_read, zclient,
4000 zclient->sock, &zclient->t_read);
4001 break;
4002 }
4003 }
4004
4005 enum zclient_send_status zclient_interface_set_master(struct zclient *client,
4006 struct interface *master,
4007 struct interface *slave)
4008 {
4009 struct stream *s;
4010
4011 s = client->obuf;
4012 stream_reset(s);
4013
4014 zclient_create_header(s, ZEBRA_INTERFACE_SET_MASTER, master->vrf_id);
4015
4016 stream_putl(s, master->vrf_id);
4017 stream_putl(s, master->ifindex);
4018 stream_putl(s, slave->vrf_id);
4019 stream_putl(s, slave->ifindex);
4020
4021 stream_putw_at(s, 0, stream_get_endp(s));
4022 return zclient_send_message(client);
4023 }
4024
4025 /*
4026 * Send capabilities message to zebra
4027 */
4028 enum zclient_send_status zclient_capabilities_send(uint32_t cmd,
4029 struct zclient *zclient,
4030 struct zapi_cap *api)
4031 {
4032
4033 struct stream *s;
4034
4035 if (zclient == NULL)
4036 return ZCLIENT_SEND_FAILURE;
4037
4038 s = zclient->obuf;
4039 stream_reset(s);
4040 zclient_create_header(s, cmd, 0);
4041 stream_putl(s, api->cap);
4042
4043 switch (api->cap) {
4044 case ZEBRA_CLIENT_GR_CAPABILITIES:
4045 case ZEBRA_CLIENT_RIB_STALE_TIME:
4046 stream_putl(s, api->stale_removal_time);
4047 stream_putl(s, api->vrf_id);
4048 break;
4049 case ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE:
4050 case ZEBRA_CLIENT_ROUTE_UPDATE_PENDING:
4051 stream_putl(s, api->afi);
4052 stream_putl(s, api->safi);
4053 stream_putl(s, api->vrf_id);
4054 break;
4055 case ZEBRA_CLIENT_GR_DISABLE:
4056 stream_putl(s, api->vrf_id);
4057 break;
4058 }
4059
4060 /* Put length at the first point of the stream */
4061 stream_putw_at(s, 0, stream_get_endp(s));
4062
4063 return zclient_send_message(zclient);
4064 }
4065
4066 /*
4067 * Process capabilities message from zebra
4068 */
4069 int32_t zapi_capabilities_decode(struct stream *s, struct zapi_cap *api)
4070 {
4071
4072 memset(api, 0, sizeof(*api));
4073
4074 STREAM_GETL(s, api->cap);
4075 switch (api->cap) {
4076 case ZEBRA_CLIENT_GR_CAPABILITIES:
4077 case ZEBRA_CLIENT_RIB_STALE_TIME:
4078 STREAM_GETL(s, api->stale_removal_time);
4079 STREAM_GETL(s, api->vrf_id);
4080 break;
4081 case ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE:
4082 case ZEBRA_CLIENT_ROUTE_UPDATE_PENDING:
4083 STREAM_GETL(s, api->afi);
4084 STREAM_GETL(s, api->safi);
4085 STREAM_GETL(s, api->vrf_id);
4086 break;
4087 case ZEBRA_CLIENT_GR_DISABLE:
4088 STREAM_GETL(s, api->vrf_id);
4089 break;
4090 }
4091 stream_failure:
4092 return 0;
4093 }
4094
4095 enum zclient_send_status
4096 zclient_send_neigh_discovery_req(struct zclient *zclient,
4097 const struct interface *ifp,
4098 const struct prefix *p)
4099 {
4100 struct stream *s;
4101
4102 s = zclient->obuf;
4103 stream_reset(s);
4104
4105 zclient_create_header(s, ZEBRA_NEIGH_DISCOVER, ifp->vrf_id);
4106 stream_putl(s, ifp->ifindex);
4107
4108 stream_putc(s, p->family);
4109 stream_putc(s, p->prefixlen);
4110 stream_put(s, &p->u.prefix, prefix_blen(p));
4111
4112 stream_putw_at(s, 0, stream_get_endp(s));
4113 return zclient_send_message(zclient);
4114 }
4115
4116 /*
4117 * Get a starting nhg point for a routing protocol
4118 */
4119 uint32_t zclient_get_nhg_start(uint32_t proto)
4120 {
4121 assert(proto < ZEBRA_ROUTE_MAX);
4122
4123 return ZEBRA_NHG_PROTO_SPACING * proto;
4124 }
4125
4126 char *zclient_dump_route_flags(uint32_t flags, char *buf, size_t len)
4127 {
4128 if (flags == 0) {
4129 snprintfrr(buf, len, "None ");
4130 return buf;
4131 }
4132
4133 snprintfrr(
4134 buf, len, "%s%s%s%s%s%s%s%s%s%s",
4135 CHECK_FLAG(flags, ZEBRA_FLAG_ALLOW_RECURSION) ? "Recursion "
4136 : "",
4137 CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE) ? "Self " : "",
4138 CHECK_FLAG(flags, ZEBRA_FLAG_IBGP) ? "iBGP " : "",
4139 CHECK_FLAG(flags, ZEBRA_FLAG_SELECTED) ? "Selected " : "",
4140 CHECK_FLAG(flags, ZEBRA_FLAG_FIB_OVERRIDE) ? "Override " : "",
4141 CHECK_FLAG(flags, ZEBRA_FLAG_EVPN_ROUTE) ? "Evpn " : "",
4142 CHECK_FLAG(flags, ZEBRA_FLAG_RR_USE_DISTANCE) ? "RR Distance "
4143 : "",
4144 CHECK_FLAG(flags, ZEBRA_FLAG_TRAPPED) ? "Trapped " : "",
4145 CHECK_FLAG(flags, ZEBRA_FLAG_OFFLOADED) ? "Offloaded " : "",
4146 CHECK_FLAG(flags, ZEBRA_FLAG_OFFLOAD_FAILED) ? "Offload Failed "
4147 : "");
4148 return buf;
4149 }
4150
4151 char *zclient_evpn_dump_macip_flags(uint8_t flags, char *buf, size_t len)
4152 {
4153 if (flags == 0) {
4154 snprintfrr(buf, len, "None ");
4155 return buf;
4156 }
4157
4158 snprintfrr(
4159 buf, len, "%s%s%s%s%s%s%s",
4160 CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY) ? "Sticky MAC " : "",
4161 CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW) ? "Gateway MAC " : "",
4162 CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG) ? "Router "
4163 : "",
4164 CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_OVERRIDE_FLAG) ? "Override "
4165 : "",
4166 CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_SVI_IP) ? "SVI MAC " : "",
4167 CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT) ? "Proxy "
4168 : "",
4169 CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_SYNC_PATH) ? "Sync " : "");
4170
4171 return buf;
4172 }