]> git.proxmox.com Git - mirror_frr.git/blob - lib/zclient.c
Merge pull request #7898 from donaldsharp/pim_igmp_crash
[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 static 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 if (api_nhg->nexthop_num >= MULTIPATH_NUM ||
1011 api_nhg->backup_nexthop_num >= MULTIPATH_NUM) {
1012 flog_err(EC_LIB_ZAPI_ENCODE,
1013 "%s: zapi NHG encode with invalid input\n", __func__);
1014 return -1;
1015 }
1016
1017 stream_reset(s);
1018 zclient_create_header(s, cmd, VRF_DEFAULT);
1019
1020 stream_putw(s, api_nhg->proto);
1021 stream_putl(s, api_nhg->id);
1022
1023 if (cmd == ZEBRA_NHG_ADD) {
1024 /* Nexthops */
1025 zapi_nexthop_group_sort(api_nhg->nexthops,
1026 api_nhg->nexthop_num);
1027
1028 stream_putw(s, api_nhg->nexthop_num);
1029
1030 for (i = 0; i < api_nhg->nexthop_num; i++)
1031 zapi_nexthop_encode(s, &api_nhg->nexthops[i], 0, 0);
1032
1033 /* Backup nexthops */
1034 stream_putw(s, api_nhg->backup_nexthop_num);
1035
1036 for (i = 0; i < api_nhg->backup_nexthop_num; i++)
1037 zapi_nexthop_encode(s, &api_nhg->backup_nexthops[i], 0,
1038 0);
1039 }
1040
1041 stream_putw_at(s, 0, stream_get_endp(s));
1042
1043 return 0;
1044 }
1045
1046 enum zclient_send_status zclient_nhg_send(struct zclient *zclient, int cmd,
1047 struct zapi_nhg *api_nhg)
1048 {
1049 api_nhg->proto = zclient->redist_default;
1050
1051 if (zapi_nhg_encode(zclient->obuf, cmd, api_nhg))
1052 return -1;
1053
1054 return zclient_send_message(zclient);
1055 }
1056
1057 int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api)
1058 {
1059 struct zapi_nexthop *api_nh;
1060 int i;
1061 int psize;
1062
1063 stream_reset(s);
1064 zclient_create_header(s, cmd, api->vrf_id);
1065
1066 if (api->type >= ZEBRA_ROUTE_MAX) {
1067 flog_err(EC_LIB_ZAPI_ENCODE,
1068 "%s: Specified route type (%u) is not a legal value\n",
1069 __func__, api->type);
1070 return -1;
1071 }
1072 stream_putc(s, api->type);
1073
1074 stream_putw(s, api->instance);
1075 stream_putl(s, api->flags);
1076 stream_putl(s, api->message);
1077
1078 if (api->safi < SAFI_UNICAST || api->safi >= SAFI_MAX) {
1079 flog_err(EC_LIB_ZAPI_ENCODE,
1080 "%s: Specified route SAFI (%u) is not a legal value\n",
1081 __func__, api->safi);
1082 return -1;
1083 }
1084 stream_putc(s, api->safi);
1085
1086 /* Put prefix information. */
1087 stream_putc(s, api->prefix.family);
1088 psize = PSIZE(api->prefix.prefixlen);
1089 stream_putc(s, api->prefix.prefixlen);
1090 stream_write(s, &api->prefix.u.prefix, psize);
1091
1092 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_SRCPFX)) {
1093 psize = PSIZE(api->src_prefix.prefixlen);
1094 stream_putc(s, api->src_prefix.prefixlen);
1095 stream_write(s, (uint8_t *)&api->src_prefix.prefix, psize);
1096 }
1097
1098 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NHG))
1099 stream_putl(s, api->nhgid);
1100
1101 /* Nexthops. */
1102 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
1103 /* limit the number of nexthops if necessary */
1104 if (api->nexthop_num > MULTIPATH_NUM) {
1105 flog_err(
1106 EC_LIB_ZAPI_ENCODE,
1107 "%s: prefix %pFX: can't encode %u nexthops (maximum is %u)",
1108 __func__, &api->prefix, api->nexthop_num,
1109 MULTIPATH_NUM);
1110 return -1;
1111 }
1112
1113 /* We canonicalize the nexthops by sorting them; this allows
1114 * zebra to resolve the list of nexthops to a nexthop-group
1115 * more efficiently.
1116 */
1117 zapi_nexthop_group_sort(api->nexthops, api->nexthop_num);
1118
1119 stream_putw(s, api->nexthop_num);
1120
1121 for (i = 0; i < api->nexthop_num; i++) {
1122 api_nh = &api->nexthops[i];
1123
1124 /* MPLS labels for BGP-LU or Segment Routing */
1125 if (api_nh->label_num > MPLS_MAX_LABELS) {
1126 flog_err(
1127 EC_LIB_ZAPI_ENCODE,
1128 "%s: prefix %pFX: can't encode %u labels (maximum is %u)",
1129 __func__, &api->prefix,
1130 api_nh->label_num, MPLS_MAX_LABELS);
1131 return -1;
1132 }
1133
1134 if (zapi_nexthop_encode(s, api_nh, api->flags,
1135 api->message)
1136 != 0)
1137 return -1;
1138 }
1139 }
1140
1141 /* Backup nexthops */
1142 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_BACKUP_NEXTHOPS)) {
1143 /* limit the number of nexthops if necessary */
1144 if (api->backup_nexthop_num > MULTIPATH_NUM) {
1145 flog_err(
1146 EC_LIB_ZAPI_ENCODE,
1147 "%s: prefix %pFX: can't encode %u backup nexthops (maximum is %u)",
1148 __func__, &api->prefix, api->backup_nexthop_num,
1149 MULTIPATH_NUM);
1150 return -1;
1151 }
1152
1153 /* Note that we do not sort the list of backup nexthops -
1154 * this list is treated as an array and indexed by each
1155 * primary nexthop that is associated with a backup.
1156 */
1157
1158 stream_putw(s, api->backup_nexthop_num);
1159
1160 for (i = 0; i < api->backup_nexthop_num; i++) {
1161 api_nh = &api->backup_nexthops[i];
1162
1163 /* MPLS labels for BGP-LU or Segment Routing */
1164 if (api_nh->label_num > MPLS_MAX_LABELS) {
1165 flog_err(
1166 EC_LIB_ZAPI_ENCODE,
1167 "%s: prefix %pFX: backup: can't encode %u labels (maximum is %u)",
1168 __func__, &api->prefix,
1169 api_nh->label_num, MPLS_MAX_LABELS);
1170 return -1;
1171 }
1172
1173 if (zapi_nexthop_encode(s, api_nh, api->flags,
1174 api->message)
1175 != 0)
1176 return -1;
1177 }
1178 }
1179
1180 /* Attributes. */
1181 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
1182 stream_putc(s, api->distance);
1183 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
1184 stream_putl(s, api->metric);
1185 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
1186 stream_putl(s, api->tag);
1187 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
1188 stream_putl(s, api->mtu);
1189 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TABLEID))
1190 stream_putl(s, api->tableid);
1191
1192 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_OPAQUE)) {
1193 assert(api->opaque.length <= ZAPI_MESSAGE_OPAQUE_LENGTH);
1194
1195 stream_putw(s, api->opaque.length);
1196 stream_write(s, api->opaque.data, api->opaque.length);
1197 }
1198 /* Put length at the first point of the stream. */
1199 stream_putw_at(s, 0, stream_get_endp(s));
1200
1201 return 0;
1202 }
1203
1204 /*
1205 * Decode a single zapi nexthop object
1206 */
1207 int zapi_nexthop_decode(struct stream *s, struct zapi_nexthop *api_nh,
1208 uint32_t api_flags, uint32_t api_message)
1209 {
1210 int i, ret = -1;
1211
1212 STREAM_GETL(s, api_nh->vrf_id);
1213 STREAM_GETC(s, api_nh->type);
1214
1215 /* Note that we're only using a single octet of flags */
1216 STREAM_GETC(s, api_nh->flags);
1217
1218 switch (api_nh->type) {
1219 case NEXTHOP_TYPE_BLACKHOLE:
1220 STREAM_GETC(s, api_nh->bh_type);
1221 break;
1222 case NEXTHOP_TYPE_IPV4:
1223 case NEXTHOP_TYPE_IPV4_IFINDEX:
1224 STREAM_GET(&api_nh->gate.ipv4.s_addr, s,
1225 IPV4_MAX_BYTELEN);
1226 STREAM_GETL(s, api_nh->ifindex);
1227 break;
1228 case NEXTHOP_TYPE_IFINDEX:
1229 STREAM_GETL(s, api_nh->ifindex);
1230 break;
1231 case NEXTHOP_TYPE_IPV6:
1232 case NEXTHOP_TYPE_IPV6_IFINDEX:
1233 STREAM_GET(&api_nh->gate.ipv6, s, 16);
1234 STREAM_GETL(s, api_nh->ifindex);
1235 break;
1236 }
1237
1238 /* MPLS labels for BGP-LU or Segment Routing */
1239 if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_LABEL)) {
1240 STREAM_GETC(s, api_nh->label_num);
1241 if (api_nh->label_num > MPLS_MAX_LABELS) {
1242 flog_err(
1243 EC_LIB_ZAPI_ENCODE,
1244 "%s: invalid number of MPLS labels (%u)",
1245 __func__, api_nh->label_num);
1246 return -1;
1247 }
1248
1249 STREAM_GET(&api_nh->labels[0], s,
1250 api_nh->label_num * sizeof(mpls_label_t));
1251 }
1252
1253 if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_WEIGHT))
1254 STREAM_GETL(s, api_nh->weight);
1255
1256 /* Router MAC for EVPN routes. */
1257 if (CHECK_FLAG(api_flags, ZEBRA_FLAG_EVPN_ROUTE))
1258 STREAM_GET(&(api_nh->rmac), s,
1259 sizeof(struct ethaddr));
1260
1261 /* Color for Segment Routing TE. */
1262 if (CHECK_FLAG(api_message, ZAPI_MESSAGE_SRTE))
1263 STREAM_GETL(s, api_nh->srte_color);
1264
1265 /* Backup nexthop index */
1266 if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_HAS_BACKUP)) {
1267 STREAM_GETC(s, api_nh->backup_num);
1268
1269 if (api_nh->backup_num > NEXTHOP_MAX_BACKUPS)
1270 return -1;
1271
1272 for (i = 0; i < api_nh->backup_num; i++)
1273 STREAM_GETC(s, api_nh->backup_idx[i]);
1274 }
1275
1276 /* Success */
1277 ret = 0;
1278
1279 stream_failure:
1280
1281 return ret;
1282 }
1283
1284 int zapi_route_decode(struct stream *s, struct zapi_route *api)
1285 {
1286 struct zapi_nexthop *api_nh;
1287 int i;
1288
1289 memset(api, 0, sizeof(*api));
1290
1291 /* Type, flags, message. */
1292 STREAM_GETC(s, api->type);
1293 if (api->type >= ZEBRA_ROUTE_MAX) {
1294 flog_err(EC_LIB_ZAPI_ENCODE,
1295 "%s: Specified route type: %d is not a legal value\n",
1296 __func__, api->type);
1297 return -1;
1298 }
1299
1300 STREAM_GETW(s, api->instance);
1301 STREAM_GETL(s, api->flags);
1302 STREAM_GETL(s, api->message);
1303 STREAM_GETC(s, api->safi);
1304 if (api->safi < SAFI_UNICAST || api->safi >= SAFI_MAX) {
1305 flog_err(EC_LIB_ZAPI_ENCODE,
1306 "%s: Specified route SAFI (%u) is not a legal value\n",
1307 __func__, api->safi);
1308 return -1;
1309 }
1310
1311 /* Prefix. */
1312 STREAM_GETC(s, api->prefix.family);
1313 STREAM_GETC(s, api->prefix.prefixlen);
1314 switch (api->prefix.family) {
1315 case AF_INET:
1316 if (api->prefix.prefixlen > IPV4_MAX_PREFIXLEN) {
1317 flog_err(
1318 EC_LIB_ZAPI_ENCODE,
1319 "%s: V4 prefixlen is %d which should not be more than 32",
1320 __func__, api->prefix.prefixlen);
1321 return -1;
1322 }
1323 break;
1324 case AF_INET6:
1325 if (api->prefix.prefixlen > IPV6_MAX_PREFIXLEN) {
1326 flog_err(
1327 EC_LIB_ZAPI_ENCODE,
1328 "%s: v6 prefixlen is %d which should not be more than 128",
1329 __func__, api->prefix.prefixlen);
1330 return -1;
1331 }
1332 break;
1333 default:
1334 flog_err(EC_LIB_ZAPI_ENCODE,
1335 "%s: Specified family %d is not v4 or v6", __func__,
1336 api->prefix.family);
1337 return -1;
1338 }
1339 STREAM_GET(&api->prefix.u.prefix, s, PSIZE(api->prefix.prefixlen));
1340
1341 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_SRCPFX)) {
1342 api->src_prefix.family = AF_INET6;
1343 STREAM_GETC(s, api->src_prefix.prefixlen);
1344 if (api->src_prefix.prefixlen > IPV6_MAX_PREFIXLEN) {
1345 flog_err(
1346 EC_LIB_ZAPI_ENCODE,
1347 "%s: SRC Prefix prefixlen received: %d is too large",
1348 __func__, api->src_prefix.prefixlen);
1349 return -1;
1350 }
1351 STREAM_GET(&api->src_prefix.prefix, s,
1352 PSIZE(api->src_prefix.prefixlen));
1353
1354 if (api->prefix.family != AF_INET6
1355 || api->src_prefix.prefixlen == 0) {
1356 flog_err(
1357 EC_LIB_ZAPI_ENCODE,
1358 "%s: SRC prefix specified in some manner that makes no sense",
1359 __func__);
1360 return -1;
1361 }
1362 }
1363
1364 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NHG))
1365 STREAM_GETL(s, api->nhgid);
1366
1367 /* Nexthops. */
1368 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
1369 STREAM_GETW(s, api->nexthop_num);
1370 if (api->nexthop_num > MULTIPATH_NUM) {
1371 flog_err(EC_LIB_ZAPI_ENCODE,
1372 "%s: invalid number of nexthops (%u)",
1373 __func__, api->nexthop_num);
1374 return -1;
1375 }
1376
1377 for (i = 0; i < api->nexthop_num; i++) {
1378 api_nh = &api->nexthops[i];
1379
1380 if (zapi_nexthop_decode(s, api_nh, api->flags,
1381 api->message)
1382 != 0)
1383 return -1;
1384 }
1385 }
1386
1387 /* Backup nexthops. */
1388 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_BACKUP_NEXTHOPS)) {
1389 STREAM_GETW(s, api->backup_nexthop_num);
1390 if (api->backup_nexthop_num > MULTIPATH_NUM) {
1391 flog_err(EC_LIB_ZAPI_ENCODE,
1392 "%s: invalid number of backup nexthops (%u)",
1393 __func__, api->backup_nexthop_num);
1394 return -1;
1395 }
1396
1397 for (i = 0; i < api->backup_nexthop_num; i++) {
1398 api_nh = &api->backup_nexthops[i];
1399
1400 if (zapi_nexthop_decode(s, api_nh, api->flags,
1401 api->message)
1402 != 0)
1403 return -1;
1404 }
1405 }
1406
1407 /* Attributes. */
1408 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
1409 STREAM_GETC(s, api->distance);
1410 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
1411 STREAM_GETL(s, api->metric);
1412 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
1413 STREAM_GETL(s, api->tag);
1414 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
1415 STREAM_GETL(s, api->mtu);
1416 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TABLEID))
1417 STREAM_GETL(s, api->tableid);
1418
1419 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_OPAQUE)) {
1420 STREAM_GETW(s, api->opaque.length);
1421 assert(api->opaque.length < ZAPI_MESSAGE_OPAQUE_LENGTH);
1422
1423 STREAM_GET(api->opaque.data, s, api->opaque.length);
1424 }
1425
1426 return 0;
1427 stream_failure:
1428 return -1;
1429 }
1430
1431 static void zapi_encode_prefix(struct stream *s, struct prefix *p,
1432 uint8_t family)
1433 {
1434 struct prefix any;
1435
1436 if (!p) {
1437 memset(&any, 0, sizeof(any));
1438 any.family = family;
1439 p = &any;
1440 }
1441
1442 stream_putc(s, p->family);
1443 stream_putc(s, p->prefixlen);
1444 stream_put(s, &p->u.prefix, prefix_blen(p));
1445 }
1446
1447 int zapi_pbr_rule_encode(uint8_t cmd, struct stream *s, struct pbr_rule *zrule)
1448 {
1449 stream_reset(s);
1450 zclient_create_header(s, cmd, zrule->vrf_id);
1451
1452 /*
1453 * We are sending one item at a time at the moment
1454 */
1455 stream_putl(s, 1);
1456
1457 stream_putl(s, zrule->seq);
1458 stream_putl(s, zrule->priority);
1459 stream_putl(s, zrule->unique);
1460
1461 zapi_encode_prefix(s, &(zrule->filter.src_ip),
1462 zrule->filter.src_ip.family);
1463 stream_putw(s, zrule->filter.src_port); /* src port */
1464 zapi_encode_prefix(s, &(zrule->filter.dst_ip),
1465 zrule->filter.src_ip.family);
1466 stream_putw(s, zrule->filter.dst_port); /* dst port */
1467 stream_putw(s, zrule->filter.fwmark); /* fwmark */
1468
1469 stream_putl(s, zrule->action.table);
1470 stream_put(s, zrule->ifname, INTERFACE_NAMSIZ);
1471
1472 /* Put length at the first point of the stream. */
1473 stream_putw_at(s, 0, stream_get_endp(s));
1474
1475 return 0;
1476 }
1477
1478 bool zapi_nhg_notify_decode(struct stream *s, uint32_t *id,
1479 enum zapi_nhg_notify_owner *note)
1480 {
1481 uint32_t read_id;
1482
1483 STREAM_GET(note, s, sizeof(*note));
1484 STREAM_GETL(s, read_id);
1485
1486 *id = read_id;
1487
1488 return true;
1489
1490 stream_failure:
1491 return false;
1492 }
1493
1494 bool zapi_route_notify_decode(struct stream *s, struct prefix *p,
1495 uint32_t *tableid,
1496 enum zapi_route_notify_owner *note,
1497 afi_t *afi, safi_t *safi)
1498 {
1499 uint32_t t;
1500 afi_t afi_val;
1501 safi_t safi_val;
1502
1503 STREAM_GET(note, s, sizeof(*note));
1504
1505 STREAM_GETC(s, p->family);
1506 STREAM_GETC(s, p->prefixlen);
1507 STREAM_GET(&p->u.prefix, s, prefix_blen(p));
1508 STREAM_GETL(s, t);
1509 STREAM_GETC(s, afi_val);
1510 STREAM_GETC(s, safi_val);
1511
1512 *tableid = t;
1513
1514 if (afi)
1515 *afi = afi_val;
1516 if (safi)
1517 *safi = safi_val;
1518
1519 return true;
1520
1521 stream_failure:
1522 return false;
1523 }
1524
1525 bool zapi_rule_notify_decode(struct stream *s, uint32_t *seqno,
1526 uint32_t *priority, uint32_t *unique, char *ifname,
1527 enum zapi_rule_notify_owner *note)
1528 {
1529 uint32_t prio, seq, uni;
1530
1531 STREAM_GET(note, s, sizeof(*note));
1532
1533 STREAM_GETL(s, seq);
1534 STREAM_GETL(s, prio);
1535 STREAM_GETL(s, uni);
1536 STREAM_GET(ifname, s, INTERFACE_NAMSIZ);
1537
1538 if (zclient_debug)
1539 zlog_debug("%s: %u %u %u %s", __func__, seq, prio, uni, ifname);
1540 *seqno = seq;
1541 *priority = prio;
1542 *unique = uni;
1543
1544 return true;
1545
1546 stream_failure:
1547 return false;
1548 }
1549
1550 bool zapi_ipset_notify_decode(struct stream *s, uint32_t *unique,
1551 enum zapi_ipset_notify_owner *note)
1552 {
1553 uint32_t uni;
1554
1555 STREAM_GET(note, s, sizeof(*note));
1556
1557 STREAM_GETL(s, uni);
1558
1559 if (zclient_debug)
1560 zlog_debug("%s: %u", __func__, uni);
1561 *unique = uni;
1562
1563 return true;
1564
1565 stream_failure:
1566 return false;
1567 }
1568
1569 bool zapi_ipset_entry_notify_decode(struct stream *s, uint32_t *unique,
1570 char *ipset_name,
1571 enum zapi_ipset_entry_notify_owner *note)
1572 {
1573 uint32_t uni;
1574
1575 STREAM_GET(note, s, sizeof(*note));
1576
1577 STREAM_GETL(s, uni);
1578
1579 STREAM_GET(ipset_name, s, ZEBRA_IPSET_NAME_SIZE);
1580
1581 if (zclient_debug)
1582 zlog_debug("%s: %u", __func__, uni);
1583 *unique = uni;
1584
1585 return true;
1586
1587 stream_failure:
1588 return false;
1589 }
1590
1591 bool zapi_iptable_notify_decode(struct stream *s,
1592 uint32_t *unique,
1593 enum zapi_iptable_notify_owner *note)
1594 {
1595 uint32_t uni;
1596
1597 STREAM_GET(note, s, sizeof(*note));
1598
1599 STREAM_GETL(s, uni);
1600
1601 if (zclient_debug)
1602 zlog_debug("%s: %u", __func__, uni);
1603 *unique = uni;
1604
1605 return true;
1606
1607 stream_failure:
1608 return false;
1609 }
1610
1611 struct nexthop *nexthop_from_zapi_nexthop(const struct zapi_nexthop *znh)
1612 {
1613 struct nexthop *n = nexthop_new();
1614
1615 n->type = znh->type;
1616 n->vrf_id = znh->vrf_id;
1617 n->ifindex = znh->ifindex;
1618 n->gate = znh->gate;
1619 n->srte_color = znh->srte_color;
1620
1621 /*
1622 * This function currently handles labels
1623 */
1624 if (znh->label_num) {
1625 nexthop_add_labels(n, ZEBRA_LSP_NONE, znh->label_num,
1626 znh->labels);
1627 }
1628
1629 if (CHECK_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_HAS_BACKUP)) {
1630 SET_FLAG(n->flags, NEXTHOP_FLAG_HAS_BACKUP);
1631 n->backup_num = znh->backup_num;
1632 memcpy(n->backup_idx, znh->backup_idx, n->backup_num);
1633 }
1634
1635 return n;
1636 }
1637
1638 /*
1639 * Convert nexthop to zapi nexthop
1640 */
1641 int zapi_nexthop_from_nexthop(struct zapi_nexthop *znh,
1642 const struct nexthop *nh)
1643 {
1644 int i;
1645
1646 memset(znh, 0, sizeof(*znh));
1647
1648 znh->type = nh->type;
1649 znh->vrf_id = nh->vrf_id;
1650 znh->weight = nh->weight;
1651 znh->ifindex = nh->ifindex;
1652 znh->gate = nh->gate;
1653
1654 if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_ONLINK))
1655 SET_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_ONLINK);
1656
1657 if (nh->nh_label && (nh->nh_label->num_labels > 0)) {
1658
1659 /* Validate */
1660 if (nh->nh_label->num_labels > MPLS_MAX_LABELS)
1661 return -1;
1662
1663 for (i = 0; i < nh->nh_label->num_labels; i++)
1664 znh->labels[i] = nh->nh_label->label[i];
1665
1666 znh->label_num = i;
1667 SET_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_LABEL);
1668 }
1669
1670 if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_HAS_BACKUP)) {
1671 if (nh->backup_num > NEXTHOP_MAX_BACKUPS)
1672 return -1;
1673
1674 SET_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_HAS_BACKUP);
1675 znh->backup_num = nh->backup_num;
1676 memcpy(znh->backup_idx, nh->backup_idx, znh->backup_num);
1677 }
1678
1679 return 0;
1680 }
1681
1682 /*
1683 * Wrapper that converts backup nexthop
1684 */
1685 int zapi_backup_nexthop_from_nexthop(struct zapi_nexthop *znh,
1686 const struct nexthop *nh)
1687 {
1688 int ret;
1689
1690 /* Ensure that zapi flags are correct: backups don't have backups */
1691 ret = zapi_nexthop_from_nexthop(znh, nh);
1692 if (ret == 0)
1693 UNSET_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_HAS_BACKUP);
1694
1695 return ret;
1696 }
1697
1698 /*
1699 * Format some info about a zapi nexthop, for debug or logging.
1700 */
1701 const char *zapi_nexthop2str(const struct zapi_nexthop *znh, char *buf,
1702 int bufsize)
1703 {
1704 char tmp[INET6_ADDRSTRLEN];
1705
1706 switch (znh->type) {
1707 case NEXTHOP_TYPE_IFINDEX:
1708 snprintf(buf, bufsize, "if %u", znh->ifindex);
1709 break;
1710 case NEXTHOP_TYPE_IPV4:
1711 case NEXTHOP_TYPE_IPV4_IFINDEX:
1712 inet_ntop(AF_INET, &znh->gate.ipv4, tmp, sizeof(tmp));
1713 snprintf(buf, bufsize, "%s if %u", tmp, znh->ifindex);
1714 break;
1715 case NEXTHOP_TYPE_IPV6:
1716 case NEXTHOP_TYPE_IPV6_IFINDEX:
1717 inet_ntop(AF_INET6, &znh->gate.ipv6, tmp, sizeof(tmp));
1718 snprintf(buf, bufsize, "%s if %u", tmp, znh->ifindex);
1719 break;
1720 case NEXTHOP_TYPE_BLACKHOLE:
1721 snprintf(buf, bufsize, "blackhole");
1722 break;
1723 default:
1724 snprintf(buf, bufsize, "unknown");
1725 break;
1726 }
1727
1728 return buf;
1729 }
1730
1731 /*
1732 * Decode the nexthop-tracking update message
1733 */
1734 bool zapi_nexthop_update_decode(struct stream *s, struct zapi_route *nhr)
1735 {
1736 uint32_t i;
1737
1738 memset(nhr, 0, sizeof(*nhr));
1739
1740 STREAM_GETL(s, nhr->message);
1741 STREAM_GETW(s, nhr->prefix.family);
1742 STREAM_GETC(s, nhr->prefix.prefixlen);
1743 switch (nhr->prefix.family) {
1744 case AF_INET:
1745 STREAM_GET(&nhr->prefix.u.prefix4.s_addr, s, IPV4_MAX_BYTELEN);
1746 break;
1747 case AF_INET6:
1748 STREAM_GET(&nhr->prefix.u.prefix6, s, IPV6_MAX_BYTELEN);
1749 break;
1750 default:
1751 break;
1752 }
1753 if (CHECK_FLAG(nhr->message, ZAPI_MESSAGE_SRTE))
1754 STREAM_GETL(s, nhr->srte_color);
1755
1756 STREAM_GETC(s, nhr->type);
1757 STREAM_GETW(s, nhr->instance);
1758 STREAM_GETC(s, nhr->distance);
1759 STREAM_GETL(s, nhr->metric);
1760 STREAM_GETC(s, nhr->nexthop_num);
1761
1762 for (i = 0; i < nhr->nexthop_num; i++) {
1763 if (zapi_nexthop_decode(s, &(nhr->nexthops[i]), 0, 0) != 0)
1764 return false;
1765 }
1766
1767 return true;
1768 stream_failure:
1769 return false;
1770 }
1771
1772 bool zapi_error_decode(struct stream *s, enum zebra_error_types *error)
1773 {
1774 memset(error, 0, sizeof(*error));
1775
1776 STREAM_GET(error, s, sizeof(*error));
1777
1778 if (zclient_debug)
1779 zlog_debug("%s: type: %s", __func__,
1780 zebra_error_type2str(*error));
1781
1782 return true;
1783 stream_failure:
1784 return false;
1785 }
1786
1787 /*
1788 * send a ZEBRA_REDISTRIBUTE_ADD or ZEBRA_REDISTRIBUTE_DELETE
1789 * for the route type (ZEBRA_ROUTE_KERNEL etc.). The zebra server will
1790 * then set/unset redist[type] in the client handle (a struct zserv) for the
1791 * sending client
1792 */
1793 enum zclient_send_status
1794 zebra_redistribute_send(int command, struct zclient *zclient, afi_t afi,
1795 int type, unsigned short instance, vrf_id_t vrf_id)
1796 {
1797 struct stream *s;
1798
1799 s = zclient->obuf;
1800 stream_reset(s);
1801
1802 zclient_create_header(s, command, vrf_id);
1803 stream_putc(s, afi);
1804 stream_putc(s, type);
1805 stream_putw(s, instance);
1806
1807 stream_putw_at(s, 0, stream_get_endp(s));
1808
1809 return zclient_send_message(zclient);
1810 }
1811
1812 enum zclient_send_status
1813 zebra_redistribute_default_send(int command, struct zclient *zclient, afi_t afi,
1814 vrf_id_t vrf_id)
1815 {
1816 struct stream *s;
1817
1818 s = zclient->obuf;
1819 stream_reset(s);
1820
1821 zclient_create_header(s, command, vrf_id);
1822 stream_putc(s, afi);
1823
1824 stream_putw_at(s, 0, stream_get_endp(s));
1825
1826 return zclient_send_message(zclient);
1827 }
1828
1829 /* Send route notify request to zebra */
1830 int zebra_route_notify_send(int command, struct zclient *zclient, bool set)
1831 {
1832 struct stream *s;
1833
1834 s = zclient->obuf;
1835 stream_reset(s);
1836
1837 zclient_create_header(s, command, 0);
1838 stream_putc(s, !!set);
1839
1840 stream_putw_at(s, 0, stream_get_endp(s));
1841
1842 return zclient_send_message(zclient);
1843 }
1844
1845 /* Get prefix in ZServ format; family should be filled in on prefix */
1846 static int zclient_stream_get_prefix(struct stream *s, struct prefix *p)
1847 {
1848 size_t plen = prefix_blen(p);
1849 uint8_t c;
1850 p->prefixlen = 0;
1851
1852 if (plen == 0)
1853 return -1;
1854
1855 STREAM_GET(&p->u.prefix, s, plen);
1856 STREAM_GETC(s, c);
1857 p->prefixlen = MIN(plen * 8, c);
1858
1859 return 0;
1860 stream_failure:
1861 return -1;
1862 }
1863
1864 /* Router-id update from zebra daemon. */
1865 int zebra_router_id_update_read(struct stream *s, struct prefix *rid)
1866 {
1867 /* Fetch interface address. */
1868 STREAM_GETC(s, rid->family);
1869
1870 return zclient_stream_get_prefix(s, rid);
1871
1872 stream_failure:
1873 return -1;
1874 }
1875
1876 /* Interface addition from zebra daemon. */
1877 /*
1878 * The format of the message sent with type ZEBRA_INTERFACE_ADD or
1879 * ZEBRA_INTERFACE_DELETE from zebra to the client is:
1880 * 0 1 2 3
1881 * 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
1882 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1883 * | ifname |
1884 * | |
1885 * | |
1886 * | |
1887 * | |
1888 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1889 * | ifindex |
1890 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1891 * | status |
1892 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1893 * | if_flags |
1894 * | |
1895 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1896 * | metric |
1897 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1898 * | speed |
1899 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1900 * | ifmtu |
1901 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1902 * | ifmtu6 |
1903 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1904 * | bandwidth |
1905 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1906 * | parent ifindex |
1907 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1908 * | Link Layer Type |
1909 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1910 * | Harware Address Length |
1911 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1912 * | Hardware Address if HW lenght different from 0 |
1913 * | ... max INTERFACE_HWADDR_MAX |
1914 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1915 * | Link_params? | Whether a link-params follows: 1 or 0.
1916 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1917 * | Link_params 0 or 1 INTERFACE_LINK_PARAMS_SIZE sized |
1918 * | .... (struct if_link_params). |
1919 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1920 */
1921
1922 static int zclient_vrf_add(struct zclient *zclient, vrf_id_t vrf_id)
1923 {
1924 struct vrf *vrf;
1925 char vrfname_tmp[VRF_NAMSIZ + 1] = {};
1926 struct vrf_data data;
1927
1928 STREAM_GET(&data, zclient->ibuf, sizeof(struct vrf_data));
1929 /* Read interface name. */
1930 STREAM_GET(vrfname_tmp, zclient->ibuf, VRF_NAMSIZ);
1931
1932 if (strlen(vrfname_tmp) == 0)
1933 goto stream_failure;
1934
1935 /* Lookup/create vrf by name, then vrf_id. */
1936 vrf = vrf_get(vrf_id, vrfname_tmp);
1937
1938 /* If there's already a VRF with this name, don't create vrf */
1939 if (!vrf)
1940 return 0;
1941
1942 vrf->data.l.table_id = data.l.table_id;
1943 memcpy(vrf->data.l.netns_name, data.l.netns_name, NS_NAMSIZ);
1944 /* overwrite default vrf */
1945 if (vrf_id == VRF_DEFAULT)
1946 vrf_set_default_name(vrfname_tmp, false);
1947 vrf_enable(vrf);
1948
1949 return 0;
1950 stream_failure:
1951 return -1;
1952 }
1953
1954 static void zclient_vrf_delete(struct zclient *zclient, vrf_id_t vrf_id)
1955 {
1956 struct vrf *vrf;
1957
1958 /* Lookup vrf by vrf_id. */
1959 vrf = vrf_lookup_by_id(vrf_id);
1960
1961 /*
1962 * If a routing protocol doesn't know about a
1963 * vrf that is about to be deleted. There is
1964 * no point in attempting to delete it.
1965 */
1966 if (!vrf)
1967 return;
1968
1969 vrf_delete(vrf);
1970 }
1971
1972 static int zclient_interface_add(struct zclient *zclient, vrf_id_t vrf_id)
1973 {
1974 struct interface *ifp;
1975 char ifname_tmp[INTERFACE_NAMSIZ + 1] = {};
1976 struct stream *s = zclient->ibuf;
1977
1978 /* Read interface name. */
1979 STREAM_GET(ifname_tmp, s, INTERFACE_NAMSIZ);
1980
1981 /* Lookup/create interface by name. */
1982 if (!vrf_get(vrf_id, NULL)) {
1983 zlog_debug(
1984 "Rx'd interface add from Zebra, but VRF %u does not exist",
1985 vrf_id);
1986 return -1;
1987 }
1988
1989 ifp = if_get_by_name(ifname_tmp, vrf_id);
1990
1991 zebra_interface_if_set_value(s, ifp);
1992
1993 if_new_via_zapi(ifp);
1994
1995 return 0;
1996 stream_failure:
1997 return -1;
1998 }
1999
2000 /*
2001 * Read interface up/down msg (ZEBRA_INTERFACE_UP/ZEBRA_INTERFACE_DOWN)
2002 * from zebra server. The format of this message is the same as
2003 * that sent for ZEBRA_INTERFACE_ADD/ZEBRA_INTERFACE_DELETE,
2004 * except that no sockaddr_dl is sent at the tail of the message.
2005 */
2006 struct interface *zebra_interface_state_read(struct stream *s, vrf_id_t vrf_id)
2007 {
2008 struct interface *ifp;
2009 char ifname_tmp[INTERFACE_NAMSIZ + 1] = {};
2010
2011 /* Read interface name. */
2012 STREAM_GET(ifname_tmp, s, INTERFACE_NAMSIZ);
2013
2014 /* Lookup this by interface index. */
2015 ifp = if_lookup_by_name(ifname_tmp, vrf_id);
2016 if (ifp == NULL) {
2017 flog_err(EC_LIB_ZAPI_ENCODE,
2018 "INTERFACE_STATE: Cannot find IF %s in VRF %d",
2019 ifname_tmp, vrf_id);
2020 return NULL;
2021 }
2022
2023 zebra_interface_if_set_value(s, ifp);
2024
2025 return ifp;
2026 stream_failure:
2027 return NULL;
2028 }
2029
2030 static void zclient_interface_delete(struct zclient *zclient, vrf_id_t vrf_id)
2031 {
2032 struct interface *ifp;
2033 struct stream *s = zclient->ibuf;
2034
2035 ifp = zebra_interface_state_read(s, vrf_id);
2036
2037 if (ifp == NULL)
2038 return;
2039
2040 if_destroy_via_zapi(ifp);
2041 return;
2042 }
2043
2044 static void zclient_interface_up(struct zclient *zclient, vrf_id_t vrf_id)
2045 {
2046 struct interface *ifp;
2047 struct stream *s = zclient->ibuf;
2048
2049 ifp = zebra_interface_state_read(s, vrf_id);
2050
2051 if (!ifp)
2052 return;
2053
2054 if_up_via_zapi(ifp);
2055 }
2056
2057 static void zclient_interface_down(struct zclient *zclient, vrf_id_t vrf_id)
2058 {
2059 struct interface *ifp;
2060 struct stream *s = zclient->ibuf;
2061
2062 ifp = zebra_interface_state_read(s, vrf_id);
2063
2064 if (!ifp)
2065 return;
2066
2067 if_down_via_zapi(ifp);
2068 }
2069
2070 static void zclient_handle_error(ZAPI_CALLBACK_ARGS)
2071 {
2072 enum zebra_error_types error;
2073 struct stream *s = zclient->ibuf;
2074
2075 zapi_error_decode(s, &error);
2076
2077 if (zclient->handle_error)
2078 (*zclient->handle_error)(error);
2079 }
2080
2081 static int link_params_set_value(struct stream *s, struct if_link_params *iflp)
2082 {
2083
2084 if (iflp == NULL)
2085 return -1;
2086
2087 uint32_t bwclassnum;
2088
2089 STREAM_GETL(s, iflp->lp_status);
2090 STREAM_GETL(s, iflp->te_metric);
2091 STREAM_GETF(s, iflp->max_bw);
2092 STREAM_GETF(s, iflp->max_rsv_bw);
2093 STREAM_GETL(s, bwclassnum);
2094 {
2095 unsigned int i;
2096 for (i = 0; i < bwclassnum && i < MAX_CLASS_TYPE; i++)
2097 STREAM_GETF(s, iflp->unrsv_bw[i]);
2098 if (i < bwclassnum)
2099 flog_err(
2100 EC_LIB_ZAPI_MISSMATCH,
2101 "%s: received %d > %d (MAX_CLASS_TYPE) bw entries - outdated library?",
2102 __func__, bwclassnum, MAX_CLASS_TYPE);
2103 }
2104 STREAM_GETL(s, iflp->admin_grp);
2105 STREAM_GETL(s, iflp->rmt_as);
2106 iflp->rmt_ip.s_addr = stream_get_ipv4(s);
2107
2108 STREAM_GETL(s, iflp->av_delay);
2109 STREAM_GETL(s, iflp->min_delay);
2110 STREAM_GETL(s, iflp->max_delay);
2111 STREAM_GETL(s, iflp->delay_var);
2112
2113 STREAM_GETF(s, iflp->pkt_loss);
2114 STREAM_GETF(s, iflp->res_bw);
2115 STREAM_GETF(s, iflp->ava_bw);
2116 STREAM_GETF(s, iflp->use_bw);
2117
2118 return 0;
2119 stream_failure:
2120 return -1;
2121 }
2122
2123 struct interface *zebra_interface_link_params_read(struct stream *s,
2124 vrf_id_t vrf_id)
2125 {
2126 struct if_link_params *iflp;
2127 ifindex_t ifindex;
2128
2129 STREAM_GETL(s, ifindex);
2130
2131 struct interface *ifp = if_lookup_by_index(ifindex, vrf_id);
2132
2133 if (ifp == NULL) {
2134 flog_err(EC_LIB_ZAPI_ENCODE,
2135 "%s: unknown ifindex %u, shouldn't happen", __func__,
2136 ifindex);
2137 return NULL;
2138 }
2139
2140 if ((iflp = if_link_params_get(ifp)) == NULL)
2141 return NULL;
2142
2143 if (link_params_set_value(s, iflp) != 0)
2144 goto stream_failure;
2145
2146 return ifp;
2147
2148 stream_failure:
2149 return NULL;
2150 }
2151
2152 static void zebra_interface_if_set_value(struct stream *s,
2153 struct interface *ifp)
2154 {
2155 uint8_t link_params_status = 0;
2156 ifindex_t old_ifindex, new_ifindex;
2157
2158 old_ifindex = ifp->oldifindex;
2159 /* Read interface's index. */
2160 STREAM_GETL(s, new_ifindex);
2161 if_set_index(ifp, new_ifindex);
2162 STREAM_GETC(s, ifp->status);
2163
2164 /* Read interface's value. */
2165 STREAM_GETQ(s, ifp->flags);
2166 STREAM_GETC(s, ifp->ptm_enable);
2167 STREAM_GETC(s, ifp->ptm_status);
2168 STREAM_GETL(s, ifp->metric);
2169 STREAM_GETL(s, ifp->speed);
2170 STREAM_GETL(s, ifp->mtu);
2171 STREAM_GETL(s, ifp->mtu6);
2172 STREAM_GETL(s, ifp->bandwidth);
2173 STREAM_GETL(s, ifp->link_ifindex);
2174 STREAM_GETL(s, ifp->ll_type);
2175 STREAM_GETL(s, ifp->hw_addr_len);
2176 if (ifp->hw_addr_len)
2177 STREAM_GET(ifp->hw_addr, s,
2178 MIN(ifp->hw_addr_len, INTERFACE_HWADDR_MAX));
2179
2180 /* Read Traffic Engineering status */
2181 link_params_status = stream_getc(s);
2182 /* Then, Traffic Engineering parameters if any */
2183 if (link_params_status) {
2184 struct if_link_params *iflp = if_link_params_get(ifp);
2185 link_params_set_value(s, iflp);
2186 }
2187
2188 nexthop_group_interface_state_change(ifp, old_ifindex);
2189
2190 return;
2191 stream_failure:
2192 zlog_err("Could not parse interface values; aborting");
2193 assert(!"Failed to parse interface values");
2194 }
2195
2196 size_t zebra_interface_link_params_write(struct stream *s,
2197 struct interface *ifp)
2198 {
2199 size_t w;
2200 struct if_link_params *iflp;
2201 int i;
2202
2203 if (s == NULL || ifp == NULL || ifp->link_params == NULL)
2204 return 0;
2205
2206 iflp = ifp->link_params;
2207 w = 0;
2208
2209 w += stream_putl(s, iflp->lp_status);
2210
2211 w += stream_putl(s, iflp->te_metric);
2212 w += stream_putf(s, iflp->max_bw);
2213 w += stream_putf(s, iflp->max_rsv_bw);
2214
2215 w += stream_putl(s, MAX_CLASS_TYPE);
2216 for (i = 0; i < MAX_CLASS_TYPE; i++)
2217 w += stream_putf(s, iflp->unrsv_bw[i]);
2218
2219 w += stream_putl(s, iflp->admin_grp);
2220 w += stream_putl(s, iflp->rmt_as);
2221 w += stream_put_in_addr(s, &iflp->rmt_ip);
2222
2223 w += stream_putl(s, iflp->av_delay);
2224 w += stream_putl(s, iflp->min_delay);
2225 w += stream_putl(s, iflp->max_delay);
2226 w += stream_putl(s, iflp->delay_var);
2227
2228 w += stream_putf(s, iflp->pkt_loss);
2229 w += stream_putf(s, iflp->res_bw);
2230 w += stream_putf(s, iflp->ava_bw);
2231 w += stream_putf(s, iflp->use_bw);
2232
2233 return w;
2234 }
2235
2236 /*
2237 * format of message for address additon is:
2238 * 0
2239 * 0 1 2 3 4 5 6 7
2240 * +-+-+-+-+-+-+-+-+
2241 * | type | ZEBRA_INTERFACE_ADDRESS_ADD or
2242 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_ADDRES_DELETE
2243 * | |
2244 * + +
2245 * | ifindex |
2246 * + +
2247 * | |
2248 * + +
2249 * | |
2250 * +-+-+-+-+-+-+-+-+
2251 * | ifc_flags | flags for connected address
2252 * +-+-+-+-+-+-+-+-+
2253 * | addr_family |
2254 * +-+-+-+-+-+-+-+-+
2255 * | addr... |
2256 * : :
2257 * | |
2258 * +-+-+-+-+-+-+-+-+
2259 * | addr_len | len of addr. E.g., addr_len = 4 for ipv4 addrs.
2260 * +-+-+-+-+-+-+-+-+
2261 * | daddr.. |
2262 * : :
2263 * | |
2264 * +-+-+-+-+-+-+-+-+
2265 */
2266
2267 static int memconstant(const void *s, int c, size_t n)
2268 {
2269 const uint8_t *p = s;
2270
2271 while (n-- > 0)
2272 if (*p++ != c)
2273 return 0;
2274 return 1;
2275 }
2276
2277
2278 struct connected *zebra_interface_address_read(int type, struct stream *s,
2279 vrf_id_t vrf_id)
2280 {
2281 ifindex_t ifindex;
2282 struct interface *ifp;
2283 struct connected *ifc;
2284 struct prefix p, d, *dp;
2285 int plen;
2286 uint8_t ifc_flags;
2287
2288 memset(&p, 0, sizeof(p));
2289 memset(&d, 0, sizeof(d));
2290
2291 /* Get interface index. */
2292 STREAM_GETL(s, ifindex);
2293
2294 /* Lookup index. */
2295 ifp = if_lookup_by_index(ifindex, vrf_id);
2296 if (ifp == NULL) {
2297 flog_err(EC_LIB_ZAPI_ENCODE,
2298 "INTERFACE_ADDRESS_%s: Cannot find IF %u in VRF %d",
2299 (type == ZEBRA_INTERFACE_ADDRESS_ADD) ? "ADD" : "DEL",
2300 ifindex, vrf_id);
2301 return NULL;
2302 }
2303
2304 /* Fetch flag. */
2305 STREAM_GETC(s, ifc_flags);
2306
2307 /* Fetch interface address. */
2308 STREAM_GETC(s, d.family);
2309 p.family = d.family;
2310 plen = prefix_blen(&d);
2311
2312 if (zclient_stream_get_prefix(s, &p) != 0)
2313 goto stream_failure;
2314
2315 /* Fetch destination address. */
2316 STREAM_GET(&d.u.prefix, s, plen);
2317
2318 /* N.B. NULL destination pointers are encoded as all zeroes */
2319 dp = memconstant(&d.u.prefix, 0, plen) ? NULL : &d;
2320
2321 if (type == ZEBRA_INTERFACE_ADDRESS_ADD) {
2322 ifc = connected_lookup_prefix_exact(ifp, &p);
2323 if (!ifc) {
2324 /* N.B. NULL destination pointers are encoded as all
2325 * zeroes */
2326 ifc = connected_add_by_prefix(ifp, &p, dp);
2327 }
2328 if (ifc) {
2329 ifc->flags = ifc_flags;
2330 if (ifc->destination)
2331 ifc->destination->prefixlen =
2332 ifc->address->prefixlen;
2333 else if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER)) {
2334 /* carp interfaces on OpenBSD with 0.0.0.0/0 as
2335 * "peer" */
2336 flog_err(
2337 EC_LIB_ZAPI_ENCODE,
2338 "warning: interface %s address %pFX with peer flag set, but no peer address!",
2339 ifp->name, ifc->address);
2340 UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
2341 }
2342 }
2343 } else {
2344 assert(type == ZEBRA_INTERFACE_ADDRESS_DELETE);
2345 ifc = connected_delete_by_prefix(ifp, &p);
2346 }
2347
2348 return ifc;
2349
2350 stream_failure:
2351 return NULL;
2352 }
2353
2354 /*
2355 * format of message for neighbor connected address is:
2356 * 0
2357 * 0 1 2 3 4 5 6 7
2358 * +-+-+-+-+-+-+-+-+
2359 * | type | ZEBRA_INTERFACE_NBR_ADDRESS_ADD or
2360 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_NBR_ADDRES_DELETE
2361 * | |
2362 * + +
2363 * | ifindex |
2364 * + +
2365 * | |
2366 * + +
2367 * | |
2368 * +-+-+-+-+-+-+-+-+
2369 * | addr_family |
2370 * +-+-+-+-+-+-+-+-+
2371 * | addr... |
2372 * : :
2373 * | |
2374 * +-+-+-+-+-+-+-+-+
2375 * | addr_len | len of addr.
2376 * +-+-+-+-+-+-+-+-+
2377 */
2378 struct nbr_connected *
2379 zebra_interface_nbr_address_read(int type, struct stream *s, vrf_id_t vrf_id)
2380 {
2381 unsigned int ifindex;
2382 struct interface *ifp;
2383 struct prefix p;
2384 struct nbr_connected *ifc;
2385
2386 /* Get interface index. */
2387 STREAM_GETL(s, ifindex);
2388
2389 /* Lookup index. */
2390 ifp = if_lookup_by_index(ifindex, vrf_id);
2391 if (ifp == NULL) {
2392 flog_err(EC_LIB_ZAPI_ENCODE,
2393 "INTERFACE_NBR_%s: Cannot find IF %u in VRF %d",
2394 (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD) ? "ADD"
2395 : "DELETE",
2396 ifindex, vrf_id);
2397 return NULL;
2398 }
2399
2400 STREAM_GETC(s, p.family);
2401 STREAM_GET(&p.u.prefix, s, prefix_blen(&p));
2402 STREAM_GETC(s, p.prefixlen);
2403
2404 if (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD) {
2405 /* Currently only supporting P2P links, so any new RA source
2406 address is
2407 considered as the replacement of the previously learnt
2408 Link-Local address. */
2409 if (!(ifc = listnode_head(ifp->nbr_connected))) {
2410 ifc = nbr_connected_new();
2411 ifc->address = prefix_new();
2412 ifc->ifp = ifp;
2413 listnode_add(ifp->nbr_connected, ifc);
2414 }
2415
2416 prefix_copy(ifc->address, &p);
2417 } else {
2418 assert(type == ZEBRA_INTERFACE_NBR_ADDRESS_DELETE);
2419
2420 ifc = nbr_connected_check(ifp, &p);
2421 if (ifc)
2422 listnode_delete(ifp->nbr_connected, ifc);
2423 }
2424
2425 return ifc;
2426
2427 stream_failure:
2428 return NULL;
2429 }
2430
2431 struct interface *zebra_interface_vrf_update_read(struct stream *s,
2432 vrf_id_t vrf_id,
2433 vrf_id_t *new_vrf_id)
2434 {
2435 char ifname[INTERFACE_NAMSIZ + 1] = {};
2436 struct interface *ifp;
2437 vrf_id_t new_id;
2438
2439 /* Read interface name. */
2440 STREAM_GET(ifname, s, INTERFACE_NAMSIZ);
2441
2442 /* Lookup interface. */
2443 ifp = if_lookup_by_name(ifname, vrf_id);
2444 if (ifp == NULL) {
2445 flog_err(EC_LIB_ZAPI_ENCODE,
2446 "INTERFACE_VRF_UPDATE: Cannot find IF %s in VRF %d",
2447 ifname, vrf_id);
2448 return NULL;
2449 }
2450
2451 /* Fetch new VRF Id. */
2452 STREAM_GETL(s, new_id);
2453
2454 *new_vrf_id = new_id;
2455 return ifp;
2456
2457 stream_failure:
2458 return NULL;
2459 }
2460
2461 /* filter unwanted messages until the expected one arrives */
2462 static int zclient_read_sync_response(struct zclient *zclient,
2463 uint16_t expected_cmd)
2464 {
2465 struct stream *s;
2466 uint16_t size = -1;
2467 uint8_t marker;
2468 uint8_t version;
2469 vrf_id_t vrf_id;
2470 uint16_t cmd;
2471 fd_set readfds;
2472 int ret;
2473
2474 ret = 0;
2475 cmd = expected_cmd + 1;
2476 while (ret == 0 && cmd != expected_cmd) {
2477 s = zclient->ibuf;
2478 stream_reset(s);
2479
2480 /* wait until response arrives */
2481 FD_ZERO(&readfds);
2482 FD_SET(zclient->sock, &readfds);
2483 select(zclient->sock + 1, &readfds, NULL, NULL, NULL);
2484 if (!FD_ISSET(zclient->sock, &readfds))
2485 continue;
2486 /* read response */
2487 ret = zclient_read_header(s, zclient->sock, &size, &marker,
2488 &version, &vrf_id, &cmd);
2489 if (zclient_debug)
2490 zlog_debug("%s: Response (%d bytes) received", __func__,
2491 size);
2492 }
2493 if (ret != 0) {
2494 flog_err(EC_LIB_ZAPI_ENCODE, "%s: Invalid Sync Message Reply",
2495 __func__);
2496 return -1;
2497 }
2498
2499 return 0;
2500 }
2501 /**
2502 * Connect to label manager in a syncronous way
2503 *
2504 * It first writes the request to zcient output buffer and then
2505 * immediately reads the answer from the input buffer.
2506 *
2507 * @param zclient Zclient used to connect to label manager (zebra)
2508 * @param async Synchronous (0) or asynchronous (1) operation
2509 * @result Result of response
2510 */
2511 int lm_label_manager_connect(struct zclient *zclient, int async)
2512 {
2513 int ret;
2514 struct stream *s;
2515 uint8_t result;
2516 uint16_t cmd = async ? ZEBRA_LABEL_MANAGER_CONNECT_ASYNC :
2517 ZEBRA_LABEL_MANAGER_CONNECT;
2518
2519 if (zclient_debug)
2520 zlog_debug("Connecting to Label Manager (LM)");
2521
2522 if (zclient->sock < 0) {
2523 zlog_debug("%s: invalid zclient socket", __func__);
2524 return -1;
2525 }
2526
2527 /* send request */
2528 s = zclient->obuf;
2529 stream_reset(s);
2530 zclient_create_header(s, cmd, VRF_DEFAULT);
2531
2532 /* proto */
2533 stream_putc(s, zclient->redist_default);
2534 /* instance */
2535 stream_putw(s, zclient->instance);
2536
2537 /* Put length at the first point of the stream. */
2538 stream_putw_at(s, 0, stream_get_endp(s));
2539
2540 ret = writen(zclient->sock, s->data, stream_get_endp(s));
2541 if (ret < 0) {
2542 flog_err(EC_LIB_ZAPI_SOCKET, "Can't write to zclient sock");
2543 close(zclient->sock);
2544 zclient->sock = -1;
2545 return -1;
2546 }
2547 if (ret == 0) {
2548 flog_err(EC_LIB_ZAPI_SOCKET, "Zclient sock closed");
2549 close(zclient->sock);
2550 zclient->sock = -1;
2551 return -1;
2552 }
2553 if (zclient_debug)
2554 zlog_debug("LM connect request sent (%d bytes)", ret);
2555
2556 if (async)
2557 return 0;
2558
2559 /* read response */
2560 if (zclient_read_sync_response(zclient, cmd)
2561 != 0)
2562 return -1;
2563
2564 s = zclient->ibuf;
2565
2566 /* read instance and proto */
2567 uint8_t proto;
2568 uint16_t instance;
2569
2570 STREAM_GETC(s, proto);
2571 STREAM_GETW(s, instance);
2572
2573 /* sanity */
2574 if (proto != zclient->redist_default)
2575 flog_err(
2576 EC_LIB_ZAPI_ENCODE,
2577 "Wrong proto (%u) in LM connect response. Should be %u",
2578 proto, zclient->redist_default);
2579 if (instance != zclient->instance)
2580 flog_err(
2581 EC_LIB_ZAPI_ENCODE,
2582 "Wrong instId (%u) in LM connect response. Should be %u",
2583 instance, zclient->instance);
2584
2585 /* result code */
2586 STREAM_GETC(s, result);
2587 if (zclient_debug)
2588 zlog_debug("LM connect-response received, result %u", result);
2589
2590 return (int)result;
2591
2592 stream_failure:
2593 return -1;
2594 }
2595
2596 /*
2597 * Asynchronous label chunk request
2598 *
2599 * @param zclient Zclient used to connect to label manager (zebra)
2600 * @param keep Avoid garbage collection
2601 * @param chunk_size Amount of labels requested
2602 * @param base Base for the label chunk. if MPLS_LABEL_BASE_ANY we do not care
2603 * @result 0 on success, -1 otherwise
2604 */
2605 enum zclient_send_status zclient_send_get_label_chunk(struct zclient *zclient,
2606 uint8_t keep,
2607 uint32_t chunk_size,
2608 uint32_t base)
2609 {
2610 struct stream *s;
2611
2612 if (zclient_debug)
2613 zlog_debug("Getting Label Chunk");
2614
2615 if (zclient->sock < 0)
2616 return ZCLIENT_SEND_FAILURE;
2617
2618 s = zclient->obuf;
2619 stream_reset(s);
2620
2621 zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, VRF_DEFAULT);
2622 /* proto */
2623 stream_putc(s, zclient->redist_default);
2624 /* instance */
2625 stream_putw(s, zclient->instance);
2626 stream_putc(s, keep);
2627 stream_putl(s, chunk_size);
2628 stream_putl(s, base);
2629
2630 /* Put length at the first point of the stream. */
2631 stream_putw_at(s, 0, stream_get_endp(s));
2632
2633 return zclient_send_message(zclient);
2634 }
2635
2636 /**
2637 * Function to request a label chunk in a syncronous way
2638 *
2639 * It first writes the request to zlcient output buffer and then
2640 * immediately reads the answer from the input buffer.
2641 *
2642 * @param zclient Zclient used to connect to label manager (zebra)
2643 * @param keep Avoid garbage collection
2644 * @param chunk_size Amount of labels requested
2645 * @param start To write first assigned chunk label to
2646 * @param end To write last assigned chunk label to
2647 * @result 0 on success, -1 otherwise
2648 */
2649 int lm_get_label_chunk(struct zclient *zclient, uint8_t keep, uint32_t base,
2650 uint32_t chunk_size, uint32_t *start, uint32_t *end)
2651 {
2652 int ret;
2653 struct stream *s;
2654 uint8_t response_keep;
2655
2656 if (zclient_debug)
2657 zlog_debug("Getting Label Chunk");
2658
2659 if (zclient->sock < 0)
2660 return -1;
2661
2662 /* send request */
2663 s = zclient->obuf;
2664 stream_reset(s);
2665 zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, VRF_DEFAULT);
2666 /* proto */
2667 stream_putc(s, zclient->redist_default);
2668 /* instance */
2669 stream_putw(s, zclient->instance);
2670 /* keep */
2671 stream_putc(s, keep);
2672 /* chunk size */
2673 stream_putl(s, chunk_size);
2674 /* requested chunk base */
2675 stream_putl(s, base);
2676 /* Put length at the first point of the stream. */
2677 stream_putw_at(s, 0, stream_get_endp(s));
2678
2679 ret = writen(zclient->sock, s->data, stream_get_endp(s));
2680 if (ret < 0) {
2681 flog_err(EC_LIB_ZAPI_SOCKET, "Can't write to zclient sock");
2682 close(zclient->sock);
2683 zclient->sock = -1;
2684 return -1;
2685 }
2686 if (ret == 0) {
2687 flog_err(EC_LIB_ZAPI_SOCKET, "Zclient sock closed");
2688 close(zclient->sock);
2689 zclient->sock = -1;
2690 return -1;
2691 }
2692 if (zclient_debug)
2693 zlog_debug("Label chunk request (%d bytes) sent", ret);
2694
2695 /* read response */
2696 if (zclient_read_sync_response(zclient, ZEBRA_GET_LABEL_CHUNK) != 0)
2697 return -1;
2698
2699 /* parse response */
2700 s = zclient->ibuf;
2701
2702 /* read proto and instance */
2703 uint8_t proto;
2704 uint8_t instance;
2705
2706 STREAM_GETC(s, proto);
2707 STREAM_GETW(s, instance);
2708
2709 /* sanities */
2710 if (proto != zclient->redist_default)
2711 flog_err(EC_LIB_ZAPI_ENCODE,
2712 "Wrong proto (%u) in get chunk response. Should be %u",
2713 proto, zclient->redist_default);
2714 if (instance != zclient->instance)
2715 flog_err(EC_LIB_ZAPI_ENCODE,
2716 "Wrong instId (%u) in get chunk response Should be %u",
2717 instance, zclient->instance);
2718
2719 /* if we requested a specific chunk and it could not be allocated, the
2720 * response message will end here
2721 */
2722 if (!STREAM_READABLE(s)) {
2723 zlog_info("Unable to assign Label Chunk to %s instance %u",
2724 zebra_route_string(proto), instance);
2725 return -1;
2726 }
2727
2728 /* keep */
2729 STREAM_GETC(s, response_keep);
2730 /* start and end labels */
2731 STREAM_GETL(s, *start);
2732 STREAM_GETL(s, *end);
2733
2734 /* not owning this response */
2735 if (keep != response_keep) {
2736 flog_err(
2737 EC_LIB_ZAPI_ENCODE,
2738 "Invalid Label chunk: %u - %u, keeps mismatch %u != %u",
2739 *start, *end, keep, response_keep);
2740 }
2741 /* sanity */
2742 if (*start > *end || *start < MPLS_LABEL_UNRESERVED_MIN
2743 || *end > MPLS_LABEL_UNRESERVED_MAX) {
2744 flog_err(EC_LIB_ZAPI_ENCODE, "Invalid Label chunk: %u - %u",
2745 *start, *end);
2746 return -1;
2747 }
2748
2749 if (zclient_debug)
2750 zlog_debug("Label Chunk assign: %u - %u (%u)", *start, *end,
2751 response_keep);
2752
2753 return 0;
2754
2755 stream_failure:
2756 return -1;
2757 }
2758
2759 /**
2760 * Function to release a label chunk
2761 *
2762 * @param zclient Zclient used to connect to label manager (zebra)
2763 * @param start First label of chunk
2764 * @param end Last label of chunk
2765 * @result 0 on success, -1 otherwise
2766 */
2767 int lm_release_label_chunk(struct zclient *zclient, uint32_t start,
2768 uint32_t end)
2769 {
2770 int ret;
2771 struct stream *s;
2772
2773 if (zclient_debug)
2774 zlog_debug("Releasing Label Chunk %u - %u", start, end);
2775
2776 if (zclient->sock < 0)
2777 return -1;
2778
2779 /* send request */
2780 s = zclient->obuf;
2781 stream_reset(s);
2782 zclient_create_header(s, ZEBRA_RELEASE_LABEL_CHUNK, VRF_DEFAULT);
2783
2784 /* proto */
2785 stream_putc(s, zclient->redist_default);
2786 /* instance */
2787 stream_putw(s, zclient->instance);
2788 /* start */
2789 stream_putl(s, start);
2790 /* end */
2791 stream_putl(s, end);
2792
2793 /* Put length at the first point of the stream. */
2794 stream_putw_at(s, 0, stream_get_endp(s));
2795
2796 ret = writen(zclient->sock, s->data, stream_get_endp(s));
2797 if (ret < 0) {
2798 flog_err(EC_LIB_ZAPI_SOCKET, "Can't write to zclient sock");
2799 close(zclient->sock);
2800 zclient->sock = -1;
2801 return -1;
2802 }
2803 if (ret == 0) {
2804 flog_err(EC_LIB_ZAPI_SOCKET, "Zclient sock connection closed");
2805 close(zclient->sock);
2806 zclient->sock = -1;
2807 return -1;
2808 }
2809
2810 return 0;
2811 }
2812
2813 /**
2814 * Connect to table manager in a syncronous way
2815 *
2816 * It first writes the request to zcient output buffer and then
2817 * immediately reads the answer from the input buffer.
2818 *
2819 * @param zclient Zclient used to connect to table manager (zebra)
2820 * @result Result of response
2821 */
2822 int tm_table_manager_connect(struct zclient *zclient)
2823 {
2824 int ret;
2825 struct stream *s;
2826 uint8_t result;
2827
2828 if (zclient_debug)
2829 zlog_debug("Connecting to Table Manager");
2830
2831 if (zclient->sock < 0)
2832 return ZCLIENT_SEND_FAILURE;
2833
2834 /* send request */
2835 s = zclient->obuf;
2836 stream_reset(s);
2837 zclient_create_header(s, ZEBRA_TABLE_MANAGER_CONNECT, VRF_DEFAULT);
2838
2839 /* proto */
2840 stream_putc(s, zclient->redist_default);
2841 /* instance */
2842 stream_putw(s, zclient->instance);
2843
2844 /* Put length at the first point of the stream. */
2845 stream_putw_at(s, 0, stream_get_endp(s));
2846
2847 ret = zclient_send_message(zclient);
2848 if (ret == ZCLIENT_SEND_FAILURE)
2849 return -1;
2850
2851 if (zclient_debug)
2852 zlog_debug("%s: Table manager connect request sent", __func__);
2853
2854 /* read response */
2855 if (zclient_read_sync_response(zclient, ZEBRA_TABLE_MANAGER_CONNECT)
2856 != 0)
2857 return -1;
2858
2859 /* result */
2860 s = zclient->ibuf;
2861 STREAM_GETC(s, result);
2862 if (zclient_debug)
2863 zlog_debug(
2864 "%s: Table Manager connect response received, result %u",
2865 __func__, result);
2866
2867 return (int)result;
2868 stream_failure:
2869 return -1;
2870 }
2871
2872 /**
2873 * Function to request a table chunk in a syncronous way
2874 *
2875 * It first writes the request to zclient output buffer and then
2876 * immediately reads the answer from the input buffer.
2877 *
2878 * @param zclient Zclient used to connect to table manager (zebra)
2879 * @param chunk_size Amount of table requested
2880 * @param start to write first assigned chunk table RT ID to
2881 * @param end To write last assigned chunk table RT ID to
2882 * @result 0 on success, -1 otherwise
2883 */
2884 int tm_get_table_chunk(struct zclient *zclient, uint32_t chunk_size,
2885 uint32_t *start, uint32_t *end)
2886 {
2887 int ret;
2888 struct stream *s;
2889
2890 if (zclient_debug)
2891 zlog_debug("Getting Table Chunk");
2892
2893 if (zclient->sock < 0)
2894 return -1;
2895
2896 /* send request */
2897 s = zclient->obuf;
2898 stream_reset(s);
2899 zclient_create_header(s, ZEBRA_GET_TABLE_CHUNK, VRF_DEFAULT);
2900 /* chunk size */
2901 stream_putl(s, chunk_size);
2902 /* Put length at the first point of the stream. */
2903 stream_putw_at(s, 0, stream_get_endp(s));
2904
2905 ret = writen(zclient->sock, s->data, stream_get_endp(s));
2906 if (ret < 0) {
2907 flog_err(EC_LIB_ZAPI_SOCKET, "%s: can't write to zclient->sock",
2908 __func__);
2909 close(zclient->sock);
2910 zclient->sock = -1;
2911 return -1;
2912 }
2913 if (ret == 0) {
2914 flog_err(EC_LIB_ZAPI_SOCKET,
2915 "%s: zclient->sock connection closed", __func__);
2916 close(zclient->sock);
2917 zclient->sock = -1;
2918 return -1;
2919 }
2920 if (zclient_debug)
2921 zlog_debug("%s: Table chunk request (%d bytes) sent", __func__,
2922 ret);
2923
2924 /* read response */
2925 if (zclient_read_sync_response(zclient, ZEBRA_GET_TABLE_CHUNK) != 0)
2926 return -1;
2927
2928 s = zclient->ibuf;
2929 /* start and end table IDs */
2930 STREAM_GETL(s, *start);
2931 STREAM_GETL(s, *end);
2932
2933 if (zclient_debug)
2934 zlog_debug("Table Chunk assign: %u - %u ", *start, *end);
2935
2936 return 0;
2937 stream_failure:
2938 return -1;
2939 }
2940
2941 /**
2942 * Function to release a table chunk
2943 *
2944 * @param zclient Zclient used to connect to table manager (zebra)
2945 * @param start First label of table
2946 * @param end Last label of chunk
2947 * @result 0 on success, -1 otherwise
2948 */
2949 int tm_release_table_chunk(struct zclient *zclient, uint32_t start,
2950 uint32_t end)
2951 {
2952 struct stream *s;
2953
2954 if (zclient_debug)
2955 zlog_debug("Releasing Table Chunk");
2956
2957 if (zclient->sock < 0)
2958 return -1;
2959
2960 /* send request */
2961 s = zclient->obuf;
2962 stream_reset(s);
2963 zclient_create_header(s, ZEBRA_RELEASE_TABLE_CHUNK, VRF_DEFAULT);
2964
2965 /* start */
2966 stream_putl(s, start);
2967 /* end */
2968 stream_putl(s, end);
2969
2970 /* Put length at the first point of the stream. */
2971 stream_putw_at(s, 0, stream_get_endp(s));
2972
2973 if (zclient_send_message(zclient) == ZCLIENT_SEND_FAILURE)
2974 return -1;
2975
2976 return 0;
2977 }
2978
2979 enum zclient_send_status zebra_send_sr_policy(struct zclient *zclient, int cmd,
2980 struct zapi_sr_policy *zp)
2981 {
2982 if (zapi_sr_policy_encode(zclient->obuf, cmd, zp) < 0)
2983 return ZCLIENT_SEND_FAILURE;
2984 return zclient_send_message(zclient);
2985 }
2986
2987 int zapi_sr_policy_encode(struct stream *s, int cmd, struct zapi_sr_policy *zp)
2988 {
2989 struct zapi_srte_tunnel *zt = &zp->segment_list;
2990
2991 stream_reset(s);
2992
2993 zclient_create_header(s, cmd, VRF_DEFAULT);
2994 stream_putl(s, zp->color);
2995 stream_put_ipaddr(s, &zp->endpoint);
2996 stream_write(s, &zp->name, SRTE_POLICY_NAME_MAX_LENGTH);
2997
2998 stream_putc(s, zt->type);
2999 stream_putl(s, zt->local_label);
3000
3001 if (zt->label_num > MPLS_MAX_LABELS) {
3002 flog_err(EC_LIB_ZAPI_ENCODE,
3003 "%s: label %u: can't encode %u labels (maximum is %u)",
3004 __func__, zt->local_label, zt->label_num,
3005 MPLS_MAX_LABELS);
3006 return -1;
3007 }
3008 stream_putw(s, zt->label_num);
3009
3010 for (int i = 0; i < zt->label_num; i++)
3011 stream_putl(s, zt->labels[i]);
3012
3013 /* Put length at the first point of the stream. */
3014 stream_putw_at(s, 0, stream_get_endp(s));
3015
3016 return 0;
3017 }
3018
3019 int zapi_sr_policy_decode(struct stream *s, struct zapi_sr_policy *zp)
3020 {
3021 memset(zp, 0, sizeof(*zp));
3022
3023 struct zapi_srte_tunnel *zt = &zp->segment_list;
3024
3025 STREAM_GETL(s, zp->color);
3026 STREAM_GET_IPADDR(s, &zp->endpoint);
3027 STREAM_GET(&zp->name, s, SRTE_POLICY_NAME_MAX_LENGTH);
3028
3029 /* segment list of active candidate path */
3030 STREAM_GETC(s, zt->type);
3031 STREAM_GETL(s, zt->local_label);
3032 STREAM_GETW(s, zt->label_num);
3033 if (zt->label_num > MPLS_MAX_LABELS) {
3034 flog_err(EC_LIB_ZAPI_ENCODE,
3035 "%s: label %u: can't decode %u labels (maximum is %u)",
3036 __func__, zt->local_label, zt->label_num,
3037 MPLS_MAX_LABELS);
3038 return -1;
3039 }
3040 for (int i = 0; i < zt->label_num; i++)
3041 STREAM_GETL(s, zt->labels[i]);
3042
3043 return 0;
3044
3045 stream_failure:
3046 return -1;
3047 }
3048
3049 int zapi_sr_policy_notify_status_decode(struct stream *s,
3050 struct zapi_sr_policy *zp)
3051 {
3052 memset(zp, 0, sizeof(*zp));
3053
3054 STREAM_GETL(s, zp->color);
3055 STREAM_GET_IPADDR(s, &zp->endpoint);
3056 STREAM_GET(&zp->name, s, SRTE_POLICY_NAME_MAX_LENGTH);
3057 STREAM_GETL(s, zp->status);
3058
3059 return 0;
3060
3061 stream_failure:
3062 return -1;
3063 }
3064
3065 enum zclient_send_status zebra_send_mpls_labels(struct zclient *zclient,
3066 int cmd, struct zapi_labels *zl)
3067 {
3068 if (zapi_labels_encode(zclient->obuf, cmd, zl) < 0)
3069 return ZCLIENT_SEND_FAILURE;
3070 return zclient_send_message(zclient);
3071 }
3072
3073 int zapi_labels_encode(struct stream *s, int cmd, struct zapi_labels *zl)
3074 {
3075 struct zapi_nexthop *znh;
3076
3077 stream_reset(s);
3078
3079 zclient_create_header(s, cmd, VRF_DEFAULT);
3080 stream_putc(s, zl->message);
3081 stream_putc(s, zl->type);
3082 stream_putl(s, zl->local_label);
3083
3084 if (CHECK_FLAG(zl->message, ZAPI_LABELS_FTN)) {
3085 stream_putw(s, zl->route.prefix.family);
3086 stream_put_prefix(s, &zl->route.prefix);
3087 stream_putc(s, zl->route.type);
3088 stream_putw(s, zl->route.instance);
3089 }
3090
3091 if (zl->nexthop_num > MULTIPATH_NUM) {
3092 flog_err(
3093 EC_LIB_ZAPI_ENCODE,
3094 "%s: label %u: can't encode %u nexthops (maximum is %u)",
3095 __func__, zl->local_label, zl->nexthop_num,
3096 MULTIPATH_NUM);
3097 return -1;
3098 }
3099 stream_putw(s, zl->nexthop_num);
3100
3101 for (int i = 0; i < zl->nexthop_num; i++) {
3102 znh = &zl->nexthops[i];
3103
3104 if (zapi_nexthop_encode(s, znh, 0, 0) < 0)
3105 return -1;
3106 }
3107
3108 if (CHECK_FLAG(zl->message, ZAPI_LABELS_HAS_BACKUPS)) {
3109
3110 if (zl->backup_nexthop_num > MULTIPATH_NUM) {
3111 flog_err(
3112 EC_LIB_ZAPI_ENCODE,
3113 "%s: label %u: can't encode %u nexthops (maximum is %u)",
3114 __func__, zl->local_label, zl->nexthop_num,
3115 MULTIPATH_NUM);
3116 return -1;
3117 }
3118 stream_putw(s, zl->backup_nexthop_num);
3119
3120 for (int i = 0; i < zl->backup_nexthop_num; i++) {
3121 znh = &zl->backup_nexthops[i];
3122
3123 if (zapi_nexthop_encode(s, znh, 0, 0) < 0)
3124 return -1;
3125 }
3126
3127 }
3128
3129 /* Put length at the first point of the stream. */
3130 stream_putw_at(s, 0, stream_get_endp(s));
3131
3132 return 0;
3133 }
3134
3135 int zapi_labels_decode(struct stream *s, struct zapi_labels *zl)
3136 {
3137 struct zapi_nexthop *znh;
3138
3139 memset(zl, 0, sizeof(*zl));
3140
3141 /* Get data. */
3142 STREAM_GETC(s, zl->message);
3143 STREAM_GETC(s, zl->type);
3144 STREAM_GETL(s, zl->local_label);
3145
3146 if (CHECK_FLAG(zl->message, ZAPI_LABELS_FTN)) {
3147 size_t psize;
3148
3149 STREAM_GETW(s, zl->route.prefix.family);
3150 STREAM_GETC(s, zl->route.prefix.prefixlen);
3151
3152 psize = PSIZE(zl->route.prefix.prefixlen);
3153 switch (zl->route.prefix.family) {
3154 case AF_INET:
3155 if (zl->route.prefix.prefixlen > IPV4_MAX_BITLEN) {
3156 zlog_debug(
3157 "%s: Specified prefix length %d is greater than a v4 address can support",
3158 __func__, zl->route.prefix.prefixlen);
3159 return -1;
3160 }
3161 STREAM_GET(&zl->route.prefix.u.prefix4.s_addr, s,
3162 psize);
3163 break;
3164 case AF_INET6:
3165 if (zl->route.prefix.prefixlen > IPV6_MAX_BITLEN) {
3166 zlog_debug(
3167 "%s: Specified prefix length %d is greater than a v6 address can support",
3168 __func__, zl->route.prefix.prefixlen);
3169 return -1;
3170 }
3171 STREAM_GET(&zl->route.prefix.u.prefix6, s, psize);
3172 break;
3173 default:
3174 flog_err(EC_LIB_ZAPI_ENCODE,
3175 "%s: Specified family %u is not v4 or v6",
3176 __func__, zl->route.prefix.family);
3177 return -1;
3178 }
3179
3180 STREAM_GETC(s, zl->route.type);
3181 STREAM_GETW(s, zl->route.instance);
3182 }
3183
3184 STREAM_GETW(s, zl->nexthop_num);
3185
3186 if (zl->nexthop_num > MULTIPATH_NUM) {
3187 flog_warn(
3188 EC_LIB_ZAPI_ENCODE,
3189 "%s: Prefix %pFX has %d nexthops, but we can only use the first %d",
3190 __func__, &zl->route.prefix, zl->nexthop_num,
3191 MULTIPATH_NUM);
3192 }
3193
3194 zl->nexthop_num = MIN(MULTIPATH_NUM, zl->nexthop_num);
3195
3196 for (int i = 0; i < zl->nexthop_num; i++) {
3197 znh = &zl->nexthops[i];
3198
3199 if (zapi_nexthop_decode(s, znh, 0, 0) < 0)
3200 return -1;
3201 }
3202
3203 if (CHECK_FLAG(zl->message, ZAPI_LABELS_HAS_BACKUPS)) {
3204 STREAM_GETW(s, zl->backup_nexthop_num);
3205
3206 if (zl->backup_nexthop_num > MULTIPATH_NUM) {
3207 flog_warn(
3208 EC_LIB_ZAPI_ENCODE,
3209 "%s: Prefix %pFX has %d backup nexthops, but we can only use the first %d",
3210 __func__, &zl->route.prefix,
3211 zl->backup_nexthop_num, MULTIPATH_NUM);
3212 }
3213
3214 zl->backup_nexthop_num = MIN(MULTIPATH_NUM,
3215 zl->backup_nexthop_num);
3216
3217 for (int i = 0; i < zl->backup_nexthop_num; i++) {
3218 znh = &zl->backup_nexthops[i];
3219
3220 if (zapi_nexthop_decode(s, znh, 0, 0) < 0)
3221 return -1;
3222 }
3223 }
3224
3225 return 0;
3226 stream_failure:
3227 return -1;
3228 }
3229
3230 enum zclient_send_status zebra_send_pw(struct zclient *zclient, int command,
3231 struct zapi_pw *pw)
3232 {
3233 struct stream *s;
3234
3235 /* Reset stream. */
3236 s = zclient->obuf;
3237 stream_reset(s);
3238
3239 zclient_create_header(s, command, VRF_DEFAULT);
3240 stream_write(s, pw->ifname, IF_NAMESIZE);
3241 stream_putl(s, pw->ifindex);
3242
3243 /* Put type */
3244 stream_putl(s, pw->type);
3245
3246 /* Put nexthop */
3247 stream_putl(s, pw->af);
3248 switch (pw->af) {
3249 case AF_INET:
3250 stream_put_in_addr(s, &pw->nexthop.ipv4);
3251 break;
3252 case AF_INET6:
3253 stream_write(s, (uint8_t *)&pw->nexthop.ipv6, 16);
3254 break;
3255 default:
3256 flog_err(EC_LIB_ZAPI_ENCODE, "%s: unknown af", __func__);
3257 return ZCLIENT_SEND_FAILURE;
3258 }
3259
3260 /* Put labels */
3261 stream_putl(s, pw->local_label);
3262 stream_putl(s, pw->remote_label);
3263
3264 /* Put flags */
3265 stream_putc(s, pw->flags);
3266
3267 /* Protocol specific fields */
3268 stream_write(s, &pw->data, sizeof(union pw_protocol_fields));
3269
3270 /* Put length at the first point of the stream. */
3271 stream_putw_at(s, 0, stream_get_endp(s));
3272
3273 return zclient_send_message(zclient);
3274 }
3275
3276 /*
3277 * Receive PW status update from Zebra and send it to LDE process.
3278 */
3279 int zebra_read_pw_status_update(ZAPI_CALLBACK_ARGS, struct zapi_pw_status *pw)
3280 {
3281 struct stream *s;
3282
3283 memset(pw, 0, sizeof(struct zapi_pw_status));
3284 s = zclient->ibuf;
3285
3286 /* Get data. */
3287 stream_get(pw->ifname, s, IF_NAMESIZE);
3288 STREAM_GETL(s, pw->ifindex);
3289 STREAM_GETL(s, pw->status);
3290
3291 return 0;
3292 stream_failure:
3293 return -1;
3294 }
3295
3296 static void zclient_capability_decode(ZAPI_CALLBACK_ARGS)
3297 {
3298 struct zclient_capabilities cap;
3299 struct stream *s = zclient->ibuf;
3300 int vrf_backend;
3301 uint8_t mpls_enabled;
3302
3303 STREAM_GETL(s, vrf_backend);
3304
3305 if (vrf_backend < 0 || vrf_configure_backend(vrf_backend)) {
3306 flog_err(EC_LIB_ZAPI_ENCODE,
3307 "%s: Garbage VRF backend type: %d\n", __func__,
3308 vrf_backend);
3309 goto stream_failure;
3310 }
3311
3312
3313 memset(&cap, 0, sizeof(cap));
3314 STREAM_GETC(s, mpls_enabled);
3315 cap.mpls_enabled = !!mpls_enabled;
3316 STREAM_GETL(s, cap.ecmp);
3317 STREAM_GETC(s, cap.role);
3318
3319 if (zclient->zebra_capabilities)
3320 (*zclient->zebra_capabilities)(&cap);
3321
3322 stream_failure:
3323 return;
3324 }
3325
3326 enum zclient_send_status zclient_send_mlag_register(struct zclient *client,
3327 uint32_t bit_map)
3328 {
3329 struct stream *s;
3330
3331 s = client->obuf;
3332 stream_reset(s);
3333
3334 zclient_create_header(s, ZEBRA_MLAG_CLIENT_REGISTER, VRF_DEFAULT);
3335 stream_putl(s, bit_map);
3336
3337 stream_putw_at(s, 0, stream_get_endp(s));
3338 return zclient_send_message(client);
3339 }
3340
3341 enum zclient_send_status zclient_send_mlag_deregister(struct zclient *client)
3342 {
3343 return zebra_message_send(client, ZEBRA_MLAG_CLIENT_UNREGISTER, VRF_DEFAULT);
3344 }
3345
3346 enum zclient_send_status zclient_send_mlag_data(struct zclient *client,
3347 struct stream *client_s)
3348 {
3349 struct stream *s;
3350
3351 s = client->obuf;
3352 stream_reset(s);
3353
3354 zclient_create_header(s, ZEBRA_MLAG_FORWARD_MSG, VRF_DEFAULT);
3355 stream_put(s, client_s->data, client_s->endp);
3356
3357 stream_putw_at(s, 0, stream_get_endp(s));
3358 return zclient_send_message(client);
3359 }
3360
3361 static void zclient_mlag_process_up(ZAPI_CALLBACK_ARGS)
3362 {
3363 if (zclient->mlag_process_up)
3364 (*zclient->mlag_process_up)();
3365 }
3366
3367 static void zclient_mlag_process_down(ZAPI_CALLBACK_ARGS)
3368 {
3369 if (zclient->mlag_process_down)
3370 (*zclient->mlag_process_down)();
3371 }
3372
3373 static void zclient_mlag_handle_msg(ZAPI_CALLBACK_ARGS)
3374 {
3375 if (zclient->mlag_handle_msg)
3376 (*zclient->mlag_handle_msg)(zclient->ibuf, length);
3377 }
3378
3379 /*
3380 * Send an OPAQUE message, contents opaque to zebra. The message header
3381 * is a message subtype.
3382 */
3383 enum zclient_send_status zclient_send_opaque(struct zclient *zclient,
3384 uint32_t type, const uint8_t *data,
3385 size_t datasize)
3386 {
3387 struct stream *s;
3388 uint16_t flags = 0;
3389
3390 /* Check buffer size */
3391 if (STREAM_SIZE(zclient->obuf) <
3392 (ZEBRA_HEADER_SIZE + sizeof(type) + datasize))
3393 return ZCLIENT_SEND_FAILURE;
3394
3395 s = zclient->obuf;
3396 stream_reset(s);
3397
3398 zclient_create_header(s, ZEBRA_OPAQUE_MESSAGE, VRF_DEFAULT);
3399
3400 /* Send sub-type and flags */
3401 stream_putl(s, type);
3402 stream_putw(s, flags);
3403
3404 /* Send opaque data */
3405 stream_write(s, data, datasize);
3406
3407 /* Put length into the header at the start of the stream. */
3408 stream_putw_at(s, 0, stream_get_endp(s));
3409
3410 return zclient_send_message(zclient);
3411 }
3412
3413 /*
3414 * Send an OPAQUE message to a specific zclient. The contents are opaque
3415 * to zebra.
3416 */
3417 enum zclient_send_status
3418 zclient_send_opaque_unicast(struct zclient *zclient, uint32_t type,
3419 uint8_t proto, uint16_t instance,
3420 uint32_t session_id, const uint8_t *data,
3421 size_t datasize)
3422 {
3423 struct stream *s;
3424 uint16_t flags = 0;
3425
3426 /* Check buffer size */
3427 if (STREAM_SIZE(zclient->obuf) <
3428 (ZEBRA_HEADER_SIZE + sizeof(struct zapi_opaque_msg) + datasize))
3429 return ZCLIENT_SEND_FAILURE;
3430
3431 s = zclient->obuf;
3432 stream_reset(s);
3433
3434 zclient_create_header(s, ZEBRA_OPAQUE_MESSAGE, VRF_DEFAULT);
3435
3436 /* Send sub-type and flags */
3437 SET_FLAG(flags, ZAPI_OPAQUE_FLAG_UNICAST);
3438 stream_putl(s, type);
3439 stream_putw(s, flags);
3440
3441 /* Send destination client info */
3442 stream_putc(s, proto);
3443 stream_putw(s, instance);
3444 stream_putl(s, session_id);
3445
3446 /* Send opaque data */
3447 stream_write(s, data, datasize);
3448
3449 /* Put length into the header at the start of the stream. */
3450 stream_putw_at(s, 0, stream_get_endp(s));
3451
3452 return zclient_send_message(zclient);
3453 }
3454
3455 /*
3456 * Decode incoming opaque message into info struct
3457 */
3458 int zclient_opaque_decode(struct stream *s, struct zapi_opaque_msg *info)
3459 {
3460 memset(info, 0, sizeof(*info));
3461
3462 /* Decode subtype and flags */
3463 STREAM_GETL(s, info->type);
3464 STREAM_GETW(s, info->flags);
3465
3466 /* Decode unicast client info if present */
3467 if (CHECK_FLAG(info->flags, ZAPI_OPAQUE_FLAG_UNICAST)) {
3468 STREAM_GETC(s, info->proto);
3469 STREAM_GETW(s, info->instance);
3470 STREAM_GETL(s, info->session_id);
3471 }
3472
3473 info->len = STREAM_READABLE(s);
3474
3475 return 0;
3476
3477 stream_failure:
3478
3479 return -1;
3480 }
3481
3482 /*
3483 * Send a registration request for opaque messages with a specified subtype.
3484 */
3485 enum zclient_send_status zclient_register_opaque(struct zclient *zclient,
3486 uint32_t type)
3487 {
3488 struct stream *s;
3489
3490 s = zclient->obuf;
3491 stream_reset(s);
3492
3493 zclient_create_header(s, ZEBRA_OPAQUE_REGISTER, VRF_DEFAULT);
3494
3495 /* Send sub-type */
3496 stream_putl(s, type);
3497
3498 /* Add zclient info */
3499 stream_putc(s, zclient->redist_default);
3500 stream_putw(s, zclient->instance);
3501 stream_putl(s, zclient->session_id);
3502
3503 /* Put length at the first point of the stream. */
3504 stream_putw_at(s, 0, stream_get_endp(s));
3505
3506 return zclient_send_message(zclient);
3507 }
3508
3509 /*
3510 * Send an un-registration request for a specified opaque subtype.
3511 */
3512 enum zclient_send_status zclient_unregister_opaque(struct zclient *zclient,
3513 uint32_t type)
3514 {
3515 struct stream *s;
3516
3517 s = zclient->obuf;
3518 stream_reset(s);
3519
3520 zclient_create_header(s, ZEBRA_OPAQUE_UNREGISTER, VRF_DEFAULT);
3521
3522 /* Send sub-type */
3523 stream_putl(s, type);
3524
3525 /* Add zclient info */
3526 stream_putc(s, zclient->redist_default);
3527 stream_putw(s, zclient->instance);
3528 stream_putl(s, zclient->session_id);
3529
3530 /* Put length at the first point of the stream. */
3531 stream_putw_at(s, 0, stream_get_endp(s));
3532
3533 return zclient_send_message(zclient);
3534 }
3535
3536 /* Utility to decode opaque registration info */
3537 int zapi_opaque_reg_decode(struct stream *s, struct zapi_opaque_reg_info *info)
3538 {
3539 STREAM_GETL(s, info->type);
3540 STREAM_GETC(s, info->proto);
3541 STREAM_GETW(s, info->instance);
3542 STREAM_GETL(s, info->session_id);
3543
3544 return 0;
3545
3546 stream_failure:
3547
3548 return -1;
3549 }
3550
3551 /* Utility to decode client close notify info */
3552 int zapi_client_close_notify_decode(struct stream *s,
3553 struct zapi_client_close_info *info)
3554 {
3555 memset(info, 0, sizeof(*info));
3556
3557 STREAM_GETC(s, info->proto);
3558 STREAM_GETW(s, info->instance);
3559 STREAM_GETL(s, info->session_id);
3560
3561 return 0;
3562
3563 stream_failure:
3564
3565 return -1;
3566 }
3567
3568 /* Zebra client message read function. */
3569 static int zclient_read(struct thread *thread)
3570 {
3571 size_t already;
3572 uint16_t length, command;
3573 uint8_t marker, version;
3574 vrf_id_t vrf_id;
3575 struct zclient *zclient;
3576
3577 /* Get socket to zebra. */
3578 zclient = THREAD_ARG(thread);
3579 zclient->t_read = NULL;
3580
3581 /* Read zebra header (if we don't have it already). */
3582 if ((already = stream_get_endp(zclient->ibuf)) < ZEBRA_HEADER_SIZE) {
3583 ssize_t nbyte;
3584 if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
3585 ZEBRA_HEADER_SIZE - already))
3586 == 0)
3587 || (nbyte == -1)) {
3588 if (zclient_debug)
3589 zlog_debug(
3590 "zclient connection closed socket [%d].",
3591 zclient->sock);
3592 return zclient_failed(zclient);
3593 }
3594 if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE - already)) {
3595 /* Try again later. */
3596 zclient_event(ZCLIENT_READ, zclient);
3597 return 0;
3598 }
3599 already = ZEBRA_HEADER_SIZE;
3600 }
3601
3602 /* Reset to read from the beginning of the incoming packet. */
3603 stream_set_getp(zclient->ibuf, 0);
3604
3605 /* Fetch header values. */
3606 length = stream_getw(zclient->ibuf);
3607 marker = stream_getc(zclient->ibuf);
3608 version = stream_getc(zclient->ibuf);
3609 vrf_id = stream_getl(zclient->ibuf);
3610 command = stream_getw(zclient->ibuf);
3611
3612 if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) {
3613 flog_err(
3614 EC_LIB_ZAPI_MISSMATCH,
3615 "%s: socket %d version mismatch, marker %d, version %d",
3616 __func__, zclient->sock, marker, version);
3617 return zclient_failed(zclient);
3618 }
3619
3620 if (length < ZEBRA_HEADER_SIZE) {
3621 flog_err(EC_LIB_ZAPI_MISSMATCH,
3622 "%s: socket %d message length %u is less than %d ",
3623 __func__, zclient->sock, length, ZEBRA_HEADER_SIZE);
3624 return zclient_failed(zclient);
3625 }
3626
3627 /* Length check. */
3628 if (length > STREAM_SIZE(zclient->ibuf)) {
3629 struct stream *ns;
3630 flog_err(
3631 EC_LIB_ZAPI_ENCODE,
3632 "%s: message size %u exceeds buffer size %lu, expanding...",
3633 __func__, length,
3634 (unsigned long)STREAM_SIZE(zclient->ibuf));
3635 ns = stream_new(length);
3636 stream_copy(ns, zclient->ibuf);
3637 stream_free(zclient->ibuf);
3638 zclient->ibuf = ns;
3639 }
3640
3641 /* Read rest of zebra packet. */
3642 if (already < length) {
3643 ssize_t nbyte;
3644 if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
3645 length - already))
3646 == 0)
3647 || (nbyte == -1)) {
3648 if (zclient_debug)
3649 zlog_debug(
3650 "zclient connection closed socket [%d].",
3651 zclient->sock);
3652 return zclient_failed(zclient);
3653 }
3654 if (nbyte != (ssize_t)(length - already)) {
3655 /* Try again later. */
3656 zclient_event(ZCLIENT_READ, zclient);
3657 return 0;
3658 }
3659 }
3660
3661 length -= ZEBRA_HEADER_SIZE;
3662
3663 if (zclient_debug)
3664 zlog_debug("zclient 0x%p command %s VRF %u",
3665 (void *)zclient, zserv_command_string(command),
3666 vrf_id);
3667
3668 switch (command) {
3669 case ZEBRA_CAPABILITIES:
3670 zclient_capability_decode(command, zclient, length, vrf_id);
3671 break;
3672 case ZEBRA_ROUTER_ID_UPDATE:
3673 if (zclient->router_id_update)
3674 (*zclient->router_id_update)(command, zclient, length,
3675 vrf_id);
3676 break;
3677 case ZEBRA_VRF_ADD:
3678 zclient_vrf_add(zclient, vrf_id);
3679 break;
3680 case ZEBRA_VRF_DELETE:
3681 zclient_vrf_delete(zclient, vrf_id);
3682 break;
3683 case ZEBRA_INTERFACE_ADD:
3684 zclient_interface_add(zclient, vrf_id);
3685 break;
3686 case ZEBRA_INTERFACE_DELETE:
3687 zclient_interface_delete(zclient, vrf_id);
3688 break;
3689 case ZEBRA_INTERFACE_ADDRESS_ADD:
3690 if (zclient->interface_address_add)
3691 (*zclient->interface_address_add)(command, zclient,
3692 length, vrf_id);
3693 break;
3694 case ZEBRA_INTERFACE_ADDRESS_DELETE:
3695 if (zclient->interface_address_delete)
3696 (*zclient->interface_address_delete)(command, zclient,
3697 length, vrf_id);
3698 break;
3699 case ZEBRA_INTERFACE_BFD_DEST_UPDATE:
3700 if (zclient->interface_bfd_dest_update)
3701 (*zclient->interface_bfd_dest_update)(command, zclient,
3702 length, vrf_id);
3703 break;
3704 case ZEBRA_INTERFACE_NBR_ADDRESS_ADD:
3705 if (zclient->interface_nbr_address_add)
3706 (*zclient->interface_nbr_address_add)(command, zclient,
3707 length, vrf_id);
3708 break;
3709 case ZEBRA_INTERFACE_NBR_ADDRESS_DELETE:
3710 if (zclient->interface_nbr_address_delete)
3711 (*zclient->interface_nbr_address_delete)(
3712 command, zclient, length, vrf_id);
3713 break;
3714 case ZEBRA_INTERFACE_UP:
3715 zclient_interface_up(zclient, vrf_id);
3716 break;
3717 case ZEBRA_INTERFACE_DOWN:
3718 zclient_interface_down(zclient, vrf_id);
3719 break;
3720 case ZEBRA_INTERFACE_VRF_UPDATE:
3721 if (zclient->interface_vrf_update)
3722 (*zclient->interface_vrf_update)(command, zclient,
3723 length, vrf_id);
3724 break;
3725 case ZEBRA_NEXTHOP_UPDATE:
3726 if (zclient_debug)
3727 zlog_debug("zclient rcvd nexthop update");
3728 if (zclient->nexthop_update)
3729 (*zclient->nexthop_update)(command, zclient, length,
3730 vrf_id);
3731 break;
3732 case ZEBRA_IMPORT_CHECK_UPDATE:
3733 if (zclient_debug)
3734 zlog_debug("zclient rcvd import check update");
3735 if (zclient->import_check_update)
3736 (*zclient->import_check_update)(command, zclient,
3737 length, vrf_id);
3738 break;
3739 case ZEBRA_BFD_DEST_REPLAY:
3740 if (zclient->bfd_dest_replay)
3741 (*zclient->bfd_dest_replay)(command, zclient, length,
3742 vrf_id);
3743 break;
3744 case ZEBRA_REDISTRIBUTE_ROUTE_ADD:
3745 if (zclient->redistribute_route_add)
3746 (*zclient->redistribute_route_add)(command, zclient,
3747 length, vrf_id);
3748 break;
3749 case ZEBRA_REDISTRIBUTE_ROUTE_DEL:
3750 if (zclient->redistribute_route_del)
3751 (*zclient->redistribute_route_del)(command, zclient,
3752 length, vrf_id);
3753 break;
3754 case ZEBRA_INTERFACE_LINK_PARAMS:
3755 if (zclient->interface_link_params)
3756 (*zclient->interface_link_params)(command, zclient,
3757 length, vrf_id);
3758 break;
3759 case ZEBRA_FEC_UPDATE:
3760 if (zclient_debug)
3761 zlog_debug("zclient rcvd fec update");
3762 if (zclient->fec_update)
3763 (*zclient->fec_update)(command, zclient, length);
3764 break;
3765 case ZEBRA_LOCAL_ES_ADD:
3766 if (zclient->local_es_add)
3767 (*zclient->local_es_add)(command, zclient, length,
3768 vrf_id);
3769 break;
3770 case ZEBRA_LOCAL_ES_DEL:
3771 if (zclient->local_es_del)
3772 (*zclient->local_es_del)(command, zclient, length,
3773 vrf_id);
3774 break;
3775 case ZEBRA_LOCAL_ES_EVI_ADD:
3776 if (zclient->local_es_evi_add)
3777 (*zclient->local_es_evi_add)(command, zclient, length,
3778 vrf_id);
3779 break;
3780 case ZEBRA_LOCAL_ES_EVI_DEL:
3781 if (zclient->local_es_evi_del)
3782 (*zclient->local_es_evi_del)(command, zclient, length,
3783 vrf_id);
3784 break;
3785 case ZEBRA_VNI_ADD:
3786 if (zclient->local_vni_add)
3787 (*zclient->local_vni_add)(command, zclient, length,
3788 vrf_id);
3789 break;
3790 case ZEBRA_VNI_DEL:
3791 if (zclient->local_vni_del)
3792 (*zclient->local_vni_del)(command, zclient, length,
3793 vrf_id);
3794 break;
3795 case ZEBRA_L3VNI_ADD:
3796 if (zclient->local_l3vni_add)
3797 (*zclient->local_l3vni_add)(command, zclient, length,
3798 vrf_id);
3799 break;
3800 case ZEBRA_L3VNI_DEL:
3801 if (zclient->local_l3vni_del)
3802 (*zclient->local_l3vni_del)(command, zclient, length,
3803 vrf_id);
3804 break;
3805 case ZEBRA_MACIP_ADD:
3806 if (zclient->local_macip_add)
3807 (*zclient->local_macip_add)(command, zclient, length,
3808 vrf_id);
3809 break;
3810 case ZEBRA_MACIP_DEL:
3811 if (zclient->local_macip_del)
3812 (*zclient->local_macip_del)(command, zclient, length,
3813 vrf_id);
3814 break;
3815 case ZEBRA_IP_PREFIX_ROUTE_ADD:
3816 if (zclient->local_ip_prefix_add)
3817 (*zclient->local_ip_prefix_add)(command, zclient,
3818 length, vrf_id);
3819 break;
3820 case ZEBRA_IP_PREFIX_ROUTE_DEL:
3821 if (zclient->local_ip_prefix_del)
3822 (*zclient->local_ip_prefix_del)(command, zclient,
3823 length, vrf_id);
3824 break;
3825 case ZEBRA_PW_STATUS_UPDATE:
3826 if (zclient->pw_status_update)
3827 (*zclient->pw_status_update)(command, zclient, length,
3828 vrf_id);
3829 break;
3830 case ZEBRA_ROUTE_NOTIFY_OWNER:
3831 if (zclient->route_notify_owner)
3832 (*zclient->route_notify_owner)(command, zclient, length,
3833 vrf_id);
3834 break;
3835 case ZEBRA_RULE_NOTIFY_OWNER:
3836 if (zclient->rule_notify_owner)
3837 (*zclient->rule_notify_owner)(command, zclient, length,
3838 vrf_id);
3839 break;
3840 case ZEBRA_NHG_NOTIFY_OWNER:
3841 if (zclient->nhg_notify_owner)
3842 (*zclient->nhg_notify_owner)(command, zclient, length,
3843 vrf_id);
3844 break;
3845 case ZEBRA_GET_LABEL_CHUNK:
3846 if (zclient->label_chunk)
3847 (*zclient->label_chunk)(command, zclient, length,
3848 vrf_id);
3849 break;
3850 case ZEBRA_IPSET_NOTIFY_OWNER:
3851 if (zclient->ipset_notify_owner)
3852 (*zclient->ipset_notify_owner)(command, zclient, length,
3853 vrf_id);
3854 break;
3855 case ZEBRA_IPSET_ENTRY_NOTIFY_OWNER:
3856 if (zclient->ipset_entry_notify_owner)
3857 (*zclient->ipset_entry_notify_owner)(command,
3858 zclient, length,
3859 vrf_id);
3860 break;
3861 case ZEBRA_IPTABLE_NOTIFY_OWNER:
3862 if (zclient->iptable_notify_owner)
3863 (*zclient->iptable_notify_owner)(command,
3864 zclient, length,
3865 vrf_id);
3866 break;
3867 case ZEBRA_VXLAN_SG_ADD:
3868 if (zclient->vxlan_sg_add)
3869 (*zclient->vxlan_sg_add)(command, zclient, length,
3870 vrf_id);
3871 break;
3872 case ZEBRA_VXLAN_SG_DEL:
3873 if (zclient->vxlan_sg_del)
3874 (*zclient->vxlan_sg_del)(command, zclient, length,
3875 vrf_id);
3876 break;
3877 case ZEBRA_MLAG_PROCESS_UP:
3878 zclient_mlag_process_up(command, zclient, length, vrf_id);
3879 break;
3880 case ZEBRA_MLAG_PROCESS_DOWN:
3881 zclient_mlag_process_down(command, zclient, length, vrf_id);
3882 break;
3883 case ZEBRA_MLAG_FORWARD_MSG:
3884 zclient_mlag_handle_msg(command, zclient, length, vrf_id);
3885 break;
3886 case ZEBRA_ERROR:
3887 zclient_handle_error(command, zclient, length, vrf_id);
3888 break;
3889 case ZEBRA_OPAQUE_MESSAGE:
3890 if (zclient->opaque_msg_handler)
3891 (*zclient->opaque_msg_handler)(command, zclient, length,
3892 vrf_id);
3893 break;
3894 case ZEBRA_OPAQUE_REGISTER:
3895 if (zclient->opaque_register_handler)
3896 (*zclient->opaque_register_handler)(command, zclient,
3897 length, vrf_id);
3898 break;
3899 case ZEBRA_OPAQUE_UNREGISTER:
3900 if (zclient->opaque_unregister_handler)
3901 (*zclient->opaque_unregister_handler)(command, zclient,
3902 length, vrf_id);
3903 break;
3904 case ZEBRA_SR_POLICY_NOTIFY_STATUS:
3905 if (zclient->sr_policy_notify_status)
3906 (*zclient->sr_policy_notify_status)(command, zclient,
3907 length, vrf_id);
3908 break;
3909 case ZEBRA_CLIENT_CLOSE_NOTIFY:
3910 if (zclient->zebra_client_close_notify)
3911 (*zclient->zebra_client_close_notify)(command, zclient,
3912 length, vrf_id);
3913 break;
3914 default:
3915 break;
3916 }
3917
3918 if (zclient->sock < 0)
3919 /* Connection was closed during packet processing. */
3920 return -1;
3921
3922 /* Register read thread. */
3923 stream_reset(zclient->ibuf);
3924 zclient_event(ZCLIENT_READ, zclient);
3925
3926 return 0;
3927 }
3928
3929 void zclient_redistribute(int command, struct zclient *zclient, afi_t afi,
3930 int type, unsigned short instance, vrf_id_t vrf_id)
3931 {
3932
3933 if (instance) {
3934 if (command == ZEBRA_REDISTRIBUTE_ADD) {
3935 if (redist_check_instance(
3936 &zclient->mi_redist[afi][type], instance))
3937 return;
3938 redist_add_instance(&zclient->mi_redist[afi][type],
3939 instance);
3940 } else {
3941 if (!redist_check_instance(
3942 &zclient->mi_redist[afi][type], instance))
3943 return;
3944 redist_del_instance(&zclient->mi_redist[afi][type],
3945 instance);
3946 }
3947
3948 } else {
3949 if (command == ZEBRA_REDISTRIBUTE_ADD) {
3950 if (vrf_bitmap_check(zclient->redist[afi][type],
3951 vrf_id))
3952 return;
3953 vrf_bitmap_set(zclient->redist[afi][type], vrf_id);
3954 } else {
3955 if (!vrf_bitmap_check(zclient->redist[afi][type],
3956 vrf_id))
3957 return;
3958 vrf_bitmap_unset(zclient->redist[afi][type], vrf_id);
3959 }
3960 }
3961
3962 if (zclient->sock > 0)
3963 zebra_redistribute_send(command, zclient, afi, type, instance,
3964 vrf_id);
3965 }
3966
3967
3968 void zclient_redistribute_default(int command, struct zclient *zclient,
3969 afi_t afi, vrf_id_t vrf_id)
3970 {
3971
3972 if (command == ZEBRA_REDISTRIBUTE_DEFAULT_ADD) {
3973 if (vrf_bitmap_check(zclient->default_information[afi], vrf_id))
3974 return;
3975 vrf_bitmap_set(zclient->default_information[afi], vrf_id);
3976 } else {
3977 if (!vrf_bitmap_check(zclient->default_information[afi],
3978 vrf_id))
3979 return;
3980 vrf_bitmap_unset(zclient->default_information[afi], vrf_id);
3981 }
3982
3983 if (zclient->sock > 0)
3984 zebra_redistribute_default_send(command, zclient, afi, vrf_id);
3985 }
3986
3987 static void zclient_event(enum event event, struct zclient *zclient)
3988 {
3989 switch (event) {
3990 case ZCLIENT_SCHEDULE:
3991 thread_add_event(zclient->master, zclient_connect, zclient, 0,
3992 &zclient->t_connect);
3993 break;
3994 case ZCLIENT_CONNECT:
3995 if (zclient_debug)
3996 zlog_debug(
3997 "zclient connect failures: %d schedule interval is now %d",
3998 zclient->fail, zclient->fail < 3 ? 10 : 60);
3999 thread_add_timer(zclient->master, zclient_connect, zclient,
4000 zclient->fail < 3 ? 10 : 60,
4001 &zclient->t_connect);
4002 break;
4003 case ZCLIENT_READ:
4004 zclient->t_read = NULL;
4005 thread_add_read(zclient->master, zclient_read, zclient,
4006 zclient->sock, &zclient->t_read);
4007 break;
4008 }
4009 }
4010
4011 enum zclient_send_status zclient_interface_set_master(struct zclient *client,
4012 struct interface *master,
4013 struct interface *slave)
4014 {
4015 struct stream *s;
4016
4017 s = client->obuf;
4018 stream_reset(s);
4019
4020 zclient_create_header(s, ZEBRA_INTERFACE_SET_MASTER, master->vrf_id);
4021
4022 stream_putl(s, master->vrf_id);
4023 stream_putl(s, master->ifindex);
4024 stream_putl(s, slave->vrf_id);
4025 stream_putl(s, slave->ifindex);
4026
4027 stream_putw_at(s, 0, stream_get_endp(s));
4028 return zclient_send_message(client);
4029 }
4030
4031 /*
4032 * Send capabilities message to zebra
4033 */
4034 enum zclient_send_status zclient_capabilities_send(uint32_t cmd,
4035 struct zclient *zclient,
4036 struct zapi_cap *api)
4037 {
4038
4039 struct stream *s;
4040
4041 if (zclient == NULL)
4042 return ZCLIENT_SEND_FAILURE;
4043
4044 s = zclient->obuf;
4045 stream_reset(s);
4046 zclient_create_header(s, cmd, 0);
4047 stream_putl(s, api->cap);
4048
4049 switch (api->cap) {
4050 case ZEBRA_CLIENT_GR_CAPABILITIES:
4051 case ZEBRA_CLIENT_RIB_STALE_TIME:
4052 stream_putl(s, api->stale_removal_time);
4053 stream_putl(s, api->vrf_id);
4054 break;
4055 case ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE:
4056 case ZEBRA_CLIENT_ROUTE_UPDATE_PENDING:
4057 stream_putl(s, api->afi);
4058 stream_putl(s, api->safi);
4059 stream_putl(s, api->vrf_id);
4060 break;
4061 case ZEBRA_CLIENT_GR_DISABLE:
4062 stream_putl(s, api->vrf_id);
4063 break;
4064 }
4065
4066 /* Put length at the first point of the stream */
4067 stream_putw_at(s, 0, stream_get_endp(s));
4068
4069 return zclient_send_message(zclient);
4070 }
4071
4072 /*
4073 * Process capabilities message from zebra
4074 */
4075 int32_t zapi_capabilities_decode(struct stream *s, struct zapi_cap *api)
4076 {
4077
4078 memset(api, 0, sizeof(*api));
4079
4080 STREAM_GETL(s, api->cap);
4081 switch (api->cap) {
4082 case ZEBRA_CLIENT_GR_CAPABILITIES:
4083 case ZEBRA_CLIENT_RIB_STALE_TIME:
4084 STREAM_GETL(s, api->stale_removal_time);
4085 STREAM_GETL(s, api->vrf_id);
4086 break;
4087 case ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE:
4088 case ZEBRA_CLIENT_ROUTE_UPDATE_PENDING:
4089 STREAM_GETL(s, api->afi);
4090 STREAM_GETL(s, api->safi);
4091 STREAM_GETL(s, api->vrf_id);
4092 break;
4093 case ZEBRA_CLIENT_GR_DISABLE:
4094 STREAM_GETL(s, api->vrf_id);
4095 break;
4096 }
4097 stream_failure:
4098 return 0;
4099 }
4100
4101 enum zclient_send_status
4102 zclient_send_neigh_discovery_req(struct zclient *zclient,
4103 const struct interface *ifp,
4104 const struct prefix *p)
4105 {
4106 struct stream *s;
4107
4108 s = zclient->obuf;
4109 stream_reset(s);
4110
4111 zclient_create_header(s, ZEBRA_NEIGH_DISCOVER, ifp->vrf_id);
4112 stream_putl(s, ifp->ifindex);
4113
4114 stream_putc(s, p->family);
4115 stream_putc(s, p->prefixlen);
4116 stream_put(s, &p->u.prefix, prefix_blen(p));
4117
4118 stream_putw_at(s, 0, stream_get_endp(s));
4119 return zclient_send_message(zclient);
4120 }
4121
4122 /*
4123 * Get a starting nhg point for a routing protocol
4124 */
4125 uint32_t zclient_get_nhg_start(uint32_t proto)
4126 {
4127 assert(proto < ZEBRA_ROUTE_MAX);
4128
4129 return ZEBRA_NHG_PROTO_SPACING * proto;
4130 }
4131
4132 char *zclient_dump_route_flags(uint32_t flags, char *buf, size_t len)
4133 {
4134 if (flags == 0) {
4135 snprintfrr(buf, len, "None ");
4136 return buf;
4137 }
4138
4139 snprintfrr(
4140 buf, len, "%s%s%s%s%s%s%s%s%s%s",
4141 CHECK_FLAG(flags, ZEBRA_FLAG_ALLOW_RECURSION) ? "Recursion "
4142 : "",
4143 CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE) ? "Self " : "",
4144 CHECK_FLAG(flags, ZEBRA_FLAG_IBGP) ? "iBGP " : "",
4145 CHECK_FLAG(flags, ZEBRA_FLAG_SELECTED) ? "Selected " : "",
4146 CHECK_FLAG(flags, ZEBRA_FLAG_FIB_OVERRIDE) ? "Override " : "",
4147 CHECK_FLAG(flags, ZEBRA_FLAG_EVPN_ROUTE) ? "Evpn " : "",
4148 CHECK_FLAG(flags, ZEBRA_FLAG_RR_USE_DISTANCE) ? "RR Distance "
4149 : "",
4150 CHECK_FLAG(flags, ZEBRA_FLAG_TRAPPED) ? "Trapped " : "",
4151 CHECK_FLAG(flags, ZEBRA_FLAG_OFFLOADED) ? "Offloaded " : "",
4152 CHECK_FLAG(flags, ZEBRA_FLAG_OFFLOAD_FAILED) ? "Offload Failed "
4153 : "");
4154 return buf;
4155 }
4156
4157 char *zclient_evpn_dump_macip_flags(uint8_t flags, char *buf, size_t len)
4158 {
4159 if (flags == 0) {
4160 snprintfrr(buf, len, "None ");
4161 return buf;
4162 }
4163
4164 snprintfrr(
4165 buf, len, "%s%s%s%s%s%s%s",
4166 CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY) ? "Sticky MAC " : "",
4167 CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW) ? "Gateway MAC " : "",
4168 CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG) ? "Router "
4169 : "",
4170 CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_OVERRIDE_FLAG) ? "Override "
4171 : "",
4172 CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_SVI_IP) ? "SVI MAC " : "",
4173 CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT) ? "Proxy "
4174 : "",
4175 CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_SYNC_PATH) ? "Sync " : "");
4176
4177 return buf;
4178 }