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