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