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