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