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