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