]> git.proxmox.com Git - mirror_frr.git/blame_incremental - lib/zclient.c
Merge pull request #5793 from ton31337/fix/formatting_show_bgp_summary_failed
[mirror_frr.git] / lib / zclient.c
... / ...
CommitLineData
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
43DEFINE_MTYPE_STATIC(LIB, ZCLIENT, "Zclient")
44DEFINE_MTYPE_STATIC(LIB, REDIST_INST, "Redistribution instance IDs")
45
46/* Zebra client events. */
47enum event { ZCLIENT_SCHEDULE, ZCLIENT_READ, ZCLIENT_CONNECT };
48
49/* Prototype for event manager. */
50static void zclient_event(enum event, struct zclient *);
51
52static void zebra_interface_if_set_value(struct stream *s,
53 struct interface *ifp);
54
55struct zclient_options zclient_options_default = {.receive_notify = false};
56
57struct sockaddr_storage zclient_addr;
58socklen_t zclient_addr_len;
59
60/* This file local debug flag. */
61static int zclient_debug;
62
63/* Allocate zclient structure. */
64struct zclient *zclient_new(struct thread_master *master,
65 struct zclient_options *opt)
66{
67 struct zclient *zclient;
68 size_t stream_size =
69 MAX(ZEBRA_MAX_PACKET_SIZ, sizeof(struct zapi_route));
70
71 zclient = XCALLOC(MTYPE_ZCLIENT, sizeof(struct zclient));
72
73 zclient->ibuf = stream_new(stream_size);
74 zclient->obuf = stream_new(stream_size);
75 zclient->wb = buffer_new(0);
76 zclient->master = master;
77
78 zclient->receive_notify = opt->receive_notify;
79
80 return zclient;
81}
82
83/* This function is only called when exiting, because
84 many parts of the code do not check for I/O errors, so they could
85 reference an invalid pointer if the structure was ever freed.
86
87 Free zclient structure. */
88void zclient_free(struct zclient *zclient)
89{
90 if (zclient->ibuf)
91 stream_free(zclient->ibuf);
92 if (zclient->obuf)
93 stream_free(zclient->obuf);
94 if (zclient->wb)
95 buffer_free(zclient->wb);
96
97 XFREE(MTYPE_ZCLIENT, zclient);
98}
99
100unsigned short *redist_check_instance(struct redist_proto *red,
101 unsigned short instance)
102{
103 struct listnode *node;
104 unsigned short *id;
105
106 if (!red->instances)
107 return NULL;
108
109 for (ALL_LIST_ELEMENTS_RO(red->instances, node, id))
110 if (*id == instance)
111 return id;
112
113 return NULL;
114}
115
116void redist_add_instance(struct redist_proto *red, unsigned short instance)
117{
118 unsigned short *in;
119
120 red->enabled = 1;
121
122 if (!red->instances)
123 red->instances = list_new();
124
125 in = XMALLOC(MTYPE_REDIST_INST, sizeof(unsigned short));
126 *in = instance;
127 listnode_add(red->instances, in);
128}
129
130void redist_del_instance(struct redist_proto *red, unsigned short instance)
131{
132 unsigned short *id;
133
134 id = redist_check_instance(red, instance);
135 if (!id)
136 return;
137
138 listnode_delete(red->instances, id);
139 XFREE(MTYPE_REDIST_INST, id);
140 if (!red->instances->count) {
141 red->enabled = 0;
142 list_delete(&red->instances);
143 }
144}
145
146void redist_del_all_instances(struct redist_proto *red)
147{
148 struct listnode *ln, *nn;
149 unsigned short *id;
150
151 if (!red->instances)
152 return;
153
154 for (ALL_LIST_ELEMENTS(red->instances, ln, nn, id))
155 redist_del_instance(red, *id);
156}
157
158/* Stop zebra client services. */
159void zclient_stop(struct zclient *zclient)
160{
161 afi_t afi;
162 int i;
163
164 if (zclient_debug)
165 zlog_debug("zclient stopped");
166
167 /* Stop threads. */
168 THREAD_OFF(zclient->t_read);
169 THREAD_OFF(zclient->t_connect);
170 THREAD_OFF(zclient->t_write);
171
172 /* Reset streams. */
173 stream_reset(zclient->ibuf);
174 stream_reset(zclient->obuf);
175
176 /* Empty the write buffer. */
177 buffer_reset(zclient->wb);
178
179 /* Close socket. */
180 if (zclient->sock >= 0) {
181 close(zclient->sock);
182 zclient->sock = -1;
183 }
184 zclient->fail = 0;
185
186 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
187 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
188 vrf_bitmap_free(zclient->redist[afi][i]);
189 zclient->redist[afi][i] = VRF_BITMAP_NULL;
190 }
191 redist_del_instance(
192 &zclient->mi_redist[afi][zclient->redist_default],
193 zclient->instance);
194
195 vrf_bitmap_free(zclient->default_information[afi]);
196 zclient->default_information[afi] = VRF_BITMAP_NULL;
197 }
198}
199
200void zclient_reset(struct zclient *zclient)
201{
202 afi_t afi;
203
204 zclient_stop(zclient);
205
206 for (afi = AFI_IP; afi < AFI_MAX; afi++)
207 redist_del_instance(
208 &zclient->mi_redist[afi][zclient->redist_default],
209 zclient->instance);
210
211 zclient_init(zclient, zclient->redist_default, zclient->instance,
212 zclient->privs);
213}
214
215/**
216 * Connect to zebra daemon.
217 * @param zclient a pointer to zclient structure
218 * @return socket fd just to make sure that connection established
219 * @see zclient_init
220 * @see zclient_new
221 */
222int zclient_socket_connect(struct zclient *zclient)
223{
224 int sock;
225 int ret;
226
227 /* We should think about IPv6 connection. */
228 sock = socket(zclient_addr.ss_family, SOCK_STREAM, 0);
229 if (sock < 0)
230 return -1;
231
232 set_cloexec(sock);
233 setsockopt_so_sendbuf(sock, 1048576);
234
235 /* Connect to zebra. */
236 ret = connect(sock, (struct sockaddr *)&zclient_addr, zclient_addr_len);
237 if (ret < 0) {
238 if (zclient_debug)
239 zlog_debug("%s connect failure: %d(%s)",
240 __PRETTY_FUNCTION__, errno,
241 safe_strerror(errno));
242 close(sock);
243 return -1;
244 }
245
246 zclient->sock = sock;
247 return sock;
248}
249
250static int zclient_failed(struct zclient *zclient)
251{
252 zclient->fail++;
253 zclient_stop(zclient);
254 zclient_event(ZCLIENT_CONNECT, zclient);
255 return -1;
256}
257
258static int zclient_flush_data(struct thread *thread)
259{
260 struct zclient *zclient = THREAD_ARG(thread);
261
262 zclient->t_write = NULL;
263 if (zclient->sock < 0)
264 return -1;
265 switch (buffer_flush_available(zclient->wb, zclient->sock)) {
266 case BUFFER_ERROR:
267 flog_err(
268 EC_LIB_ZAPI_SOCKET,
269 "%s: buffer_flush_available failed on zclient fd %d, closing",
270 __func__, zclient->sock);
271 return zclient_failed(zclient);
272 break;
273 case BUFFER_PENDING:
274 zclient->t_write = NULL;
275 thread_add_write(zclient->master, zclient_flush_data, zclient,
276 zclient->sock, &zclient->t_write);
277 break;
278 case BUFFER_EMPTY:
279 break;
280 }
281 return 0;
282}
283
284int zclient_send_message(struct zclient *zclient)
285{
286 if (zclient->sock < 0)
287 return -1;
288 switch (buffer_write(zclient->wb, zclient->sock,
289 STREAM_DATA(zclient->obuf),
290 stream_get_endp(zclient->obuf))) {
291 case BUFFER_ERROR:
292 flog_err(EC_LIB_ZAPI_SOCKET,
293 "%s: buffer_write failed to zclient fd %d, closing",
294 __func__, zclient->sock);
295 return zclient_failed(zclient);
296 break;
297 case BUFFER_EMPTY:
298 THREAD_OFF(zclient->t_write);
299 break;
300 case BUFFER_PENDING:
301 thread_add_write(zclient->master, zclient_flush_data, zclient,
302 zclient->sock, &zclient->t_write);
303 break;
304 }
305 return 0;
306}
307
308/*
309 * If we add more data to this structure please ensure that
310 * struct zmsghdr in lib/zclient.h is updated as appropriate.
311 */
312void zclient_create_header(struct stream *s, uint16_t command, vrf_id_t vrf_id)
313{
314 /* length placeholder, caller can update */
315 stream_putw(s, ZEBRA_HEADER_SIZE);
316 stream_putc(s, ZEBRA_HEADER_MARKER);
317 stream_putc(s, ZSERV_VERSION);
318 stream_putl(s, vrf_id);
319 stream_putw(s, command);
320}
321
322int zclient_read_header(struct stream *s, int sock, uint16_t *size,
323 uint8_t *marker, uint8_t *version, vrf_id_t *vrf_id,
324 uint16_t *cmd)
325{
326 if (stream_read(s, sock, ZEBRA_HEADER_SIZE) != ZEBRA_HEADER_SIZE)
327 return -1;
328
329 STREAM_GETW(s, *size);
330 *size -= ZEBRA_HEADER_SIZE;
331 STREAM_GETC(s, *marker);
332 STREAM_GETC(s, *version);
333 STREAM_GETL(s, *vrf_id);
334 STREAM_GETW(s, *cmd);
335
336 if (*version != ZSERV_VERSION || *marker != ZEBRA_HEADER_MARKER) {
337 flog_err(
338 EC_LIB_ZAPI_MISSMATCH,
339 "%s: socket %d version mismatch, marker %d, version %d",
340 __func__, sock, *marker, *version);
341 return -1;
342 }
343
344 if (*size && stream_read(s, sock, *size) != *size)
345 return -1;
346
347 return 0;
348stream_failure:
349 return -1;
350}
351
352bool zapi_parse_header(struct stream *zmsg, struct zmsghdr *hdr)
353{
354 STREAM_GETW(zmsg, hdr->length);
355 STREAM_GETC(zmsg, hdr->marker);
356 STREAM_GETC(zmsg, hdr->version);
357 STREAM_GETL(zmsg, hdr->vrf_id);
358 STREAM_GETW(zmsg, hdr->command);
359 return true;
360stream_failure:
361 return false;
362}
363
364/* Send simple Zebra message. */
365static int zebra_message_send(struct zclient *zclient, int command,
366 vrf_id_t vrf_id)
367{
368 struct stream *s;
369
370 /* Get zclient output buffer. */
371 s = zclient->obuf;
372 stream_reset(s);
373
374 /* Send very simple command only Zebra message. */
375 zclient_create_header(s, command, vrf_id);
376
377 return zclient_send_message(zclient);
378}
379
380static int zebra_hello_send(struct zclient *zclient)
381{
382 struct stream *s;
383
384 if (zclient->redist_default) {
385 s = zclient->obuf;
386 stream_reset(s);
387
388 /* The VRF ID in the HELLO message is always 0. */
389 zclient_create_header(s, ZEBRA_HELLO, VRF_DEFAULT);
390 stream_putc(s, zclient->redist_default);
391 stream_putw(s, zclient->instance);
392 if (zclient->receive_notify)
393 stream_putc(s, 1);
394 else
395 stream_putc(s, 0);
396
397 stream_putw_at(s, 0, stream_get_endp(s));
398 return zclient_send_message(zclient);
399 }
400
401 return 0;
402}
403
404void zclient_send_vrf_label(struct zclient *zclient, vrf_id_t vrf_id, afi_t afi,
405 mpls_label_t label, enum lsp_types_t ltype)
406{
407 struct stream *s;
408
409 s = zclient->obuf;
410 stream_reset(s);
411
412 zclient_create_header(s, ZEBRA_VRF_LABEL, vrf_id);
413 stream_putl(s, label);
414 stream_putc(s, afi);
415 stream_putc(s, ltype);
416 stream_putw_at(s, 0, stream_get_endp(s));
417 zclient_send_message(zclient);
418}
419
420/* Send register requests to zebra daemon for the information in a VRF. */
421void zclient_send_reg_requests(struct zclient *zclient, vrf_id_t vrf_id)
422{
423 int i;
424 afi_t afi;
425
426 /* If not connected to the zebra yet. */
427 if (zclient->sock < 0)
428 return;
429
430 if (zclient_debug)
431 zlog_debug("%s: send register messages for VRF %u", __func__,
432 vrf_id);
433
434 /* We need router-id information. */
435 zebra_message_send(zclient, ZEBRA_ROUTER_ID_ADD, vrf_id);
436
437 /* We need interface information. */
438 zebra_message_send(zclient, ZEBRA_INTERFACE_ADD, vrf_id);
439
440 /* Set unwanted redistribute route. */
441 for (afi = AFI_IP; afi < AFI_MAX; afi++)
442 vrf_bitmap_set(zclient->redist[afi][zclient->redist_default],
443 vrf_id);
444
445 /* Flush all redistribute request. */
446 if (vrf_id == VRF_DEFAULT) {
447 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
448 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
449 if (!zclient->mi_redist[afi][i].enabled)
450 continue;
451
452 struct listnode *node;
453 unsigned short *id;
454
455 for (ALL_LIST_ELEMENTS_RO(
456 zclient->mi_redist[afi][i]
457 .instances,
458 node, id))
459 if (!(i == zclient->redist_default
460 && *id == zclient->instance))
461 zebra_redistribute_send(
462 ZEBRA_REDISTRIBUTE_ADD,
463 zclient, afi, i, *id,
464 VRF_DEFAULT);
465 }
466 }
467 }
468
469 /* Resend all redistribute request. */
470 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
471 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
472 if (i != zclient->redist_default
473 && vrf_bitmap_check(zclient->redist[afi][i],
474 vrf_id))
475 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD,
476 zclient, afi, i, 0,
477 vrf_id);
478
479 /* If default information is needed. */
480 if (vrf_bitmap_check(zclient->default_information[afi], vrf_id))
481 zebra_redistribute_default_send(
482 ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient, afi,
483 vrf_id);
484 }
485}
486
487/* Send unregister requests to zebra daemon for the information in a VRF. */
488void zclient_send_dereg_requests(struct zclient *zclient, vrf_id_t vrf_id)
489{
490 int i;
491 afi_t afi;
492
493 /* If not connected to the zebra yet. */
494 if (zclient->sock < 0)
495 return;
496
497 if (zclient_debug)
498 zlog_debug("%s: send deregister messages for VRF %u", __func__,
499 vrf_id);
500
501 /* We need router-id information. */
502 zebra_message_send(zclient, ZEBRA_ROUTER_ID_DELETE, vrf_id);
503
504 zebra_message_send(zclient, ZEBRA_INTERFACE_DELETE, vrf_id);
505
506 /* Set unwanted redistribute route. */
507 for (afi = AFI_IP; afi < AFI_MAX; afi++)
508 vrf_bitmap_unset(zclient->redist[afi][zclient->redist_default],
509 vrf_id);
510
511 /* Flush all redistribute request. */
512 if (vrf_id == VRF_DEFAULT) {
513 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
514 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
515 if (!zclient->mi_redist[afi][i].enabled)
516 continue;
517
518 struct listnode *node;
519 unsigned short *id;
520
521 for (ALL_LIST_ELEMENTS_RO(
522 zclient->mi_redist[afi][i]
523 .instances,
524 node, id))
525 if (!(i == zclient->redist_default
526 && *id == zclient->instance))
527 zebra_redistribute_send(
528 ZEBRA_REDISTRIBUTE_DELETE,
529 zclient, afi, i, *id,
530 VRF_DEFAULT);
531 }
532 }
533 }
534
535 /* Flush all redistribute request. */
536 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
537 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
538 if (i != zclient->redist_default
539 && vrf_bitmap_check(zclient->redist[afi][i],
540 vrf_id))
541 zebra_redistribute_send(
542 ZEBRA_REDISTRIBUTE_DELETE, zclient, afi,
543 i, 0, vrf_id);
544
545 /* If default information is needed. */
546 if (vrf_bitmap_check(zclient->default_information[afi], vrf_id))
547 zebra_redistribute_default_send(
548 ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient, afi,
549 vrf_id);
550 }
551}
552
553/* Send request to zebra daemon to start or stop RA. */
554void zclient_send_interface_radv_req(struct zclient *zclient, vrf_id_t vrf_id,
555 struct interface *ifp, int enable,
556 int ra_interval)
557{
558 struct stream *s;
559
560 /* If not connected to the zebra yet. */
561 if (zclient->sock < 0)
562 return;
563
564 /* Form and send message. */
565 s = zclient->obuf;
566 stream_reset(s);
567
568 if (enable)
569 zclient_create_header(s, ZEBRA_INTERFACE_ENABLE_RADV, vrf_id);
570 else
571 zclient_create_header(s, ZEBRA_INTERFACE_DISABLE_RADV, vrf_id);
572
573 stream_putl(s, ifp->ifindex);
574 stream_putl(s, ra_interval);
575
576 stream_putw_at(s, 0, stream_get_endp(s));
577
578 zclient_send_message(zclient);
579}
580
581int zclient_send_interface_protodown(struct zclient *zclient, vrf_id_t vrf_id,
582 struct interface *ifp, bool down)
583{
584 struct stream *s;
585
586 if (zclient->sock < 0)
587 return -1;
588
589 s = zclient->obuf;
590 stream_reset(s);
591 zclient_create_header(s, ZEBRA_INTERFACE_SET_PROTODOWN, vrf_id);
592 stream_putl(s, ifp->ifindex);
593 stream_putc(s, !!down);
594 stream_putw_at(s, 0, stream_get_endp(s));
595 zclient_send_message(zclient);
596
597 return 0;
598}
599
600/* Make connection to zebra daemon. */
601int zclient_start(struct zclient *zclient)
602{
603 if (zclient_debug)
604 zlog_info("zclient_start is called");
605
606 /* If already connected to the zebra. */
607 if (zclient->sock >= 0)
608 return 0;
609
610 /* Check connect thread. */
611 if (zclient->t_connect)
612 return 0;
613
614 if (zclient_socket_connect(zclient) < 0) {
615 if (zclient_debug)
616 zlog_debug("zclient connection fail");
617 zclient->fail++;
618 zclient_event(ZCLIENT_CONNECT, zclient);
619 return -1;
620 }
621
622 if (set_nonblocking(zclient->sock) < 0)
623 flog_err(EC_LIB_ZAPI_SOCKET, "%s: set_nonblocking(%d) failed",
624 __func__, zclient->sock);
625
626 /* Clear fail count. */
627 zclient->fail = 0;
628 if (zclient_debug)
629 zlog_debug("zclient connect success with socket [%d]",
630 zclient->sock);
631
632 /* Create read thread. */
633 zclient_event(ZCLIENT_READ, zclient);
634
635 zebra_hello_send(zclient);
636
637 zebra_message_send(zclient, ZEBRA_INTERFACE_ADD, VRF_DEFAULT);
638
639 /* Inform the successful connection. */
640 if (zclient->zebra_connected)
641 (*zclient->zebra_connected)(zclient);
642
643 return 0;
644}
645
646/* Initialize zebra client. Argument redist_default is unwanted
647 redistribute route type. */
648void zclient_init(struct zclient *zclient, int redist_default,
649 unsigned short instance, struct zebra_privs_t *privs)
650{
651 int afi, i;
652
653 /* Set -1 to the default socket value. */
654 zclient->sock = -1;
655 zclient->privs = privs;
656
657 /* Clear redistribution flags. */
658 for (afi = AFI_IP; afi < AFI_MAX; afi++)
659 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
660 zclient->redist[afi][i] = vrf_bitmap_init();
661
662 /* Set unwanted redistribute route. bgpd does not need BGP route
663 redistribution. */
664 zclient->redist_default = redist_default;
665 zclient->instance = instance;
666 /* Pending: make afi(s) an arg. */
667 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
668 redist_add_instance(&zclient->mi_redist[afi][redist_default],
669 instance);
670
671 /* Set default-information redistribute to zero. */
672 zclient->default_information[afi] = vrf_bitmap_init();
673 }
674
675 if (zclient_debug)
676 zlog_debug("scheduling zclient connection");
677
678 zclient_event(ZCLIENT_SCHEDULE, zclient);
679}
680
681/* This function is a wrapper function for calling zclient_start from
682 timer or event thread. */
683static int zclient_connect(struct thread *t)
684{
685 struct zclient *zclient;
686
687 zclient = THREAD_ARG(t);
688 zclient->t_connect = NULL;
689
690 if (zclient_debug)
691 zlog_debug("zclient_connect is called");
692
693 return zclient_start(zclient);
694}
695
696int zclient_send_rnh(struct zclient *zclient, int command, struct prefix *p,
697 bool exact_match, vrf_id_t vrf_id)
698{
699 struct stream *s;
700
701 s = zclient->obuf;
702 stream_reset(s);
703 zclient_create_header(s, command, vrf_id);
704 stream_putc(s, (exact_match) ? 1 : 0);
705
706 stream_putw(s, PREFIX_FAMILY(p));
707 stream_putc(s, p->prefixlen);
708 switch (PREFIX_FAMILY(p)) {
709 case AF_INET:
710 stream_put_in_addr(s, &p->u.prefix4);
711 break;
712 case AF_INET6:
713 stream_put(s, &(p->u.prefix6), 16);
714 break;
715 default:
716 break;
717 }
718 stream_putw_at(s, 0, stream_get_endp(s));
719
720 return zclient_send_message(zclient);
721}
722
723/*
724 * "xdr_encode"-like interface that allows daemon (client) to send
725 * a message to zebra server for a route that needs to be
726 * added/deleted to the kernel. Info about the route is specified
727 * by the caller in a struct zapi_route. zapi_route_encode() then writes
728 * the info down the zclient socket using the stream_* functions.
729 *
730 * The corresponding read ("xdr_decode") function on the server
731 * side is zapi_route_decode().
732 *
733 * 0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F
734 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
735 * | Length (2) | Command | Route Type |
736 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
737 * | ZEBRA Flags | Message Flags | Prefix length |
738 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
739 * | Destination IPv4 Prefix for route |
740 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
741 * | Nexthop count |
742 * +-+-+-+-+-+-+-+-+
743 *
744 *
745 * A number of IPv4 nexthop(s) or nexthop interface index(es) are then
746 * described, as per the Nexthop count. Each nexthop described as:
747 *
748 * +-+-+-+-+-+-+-+-+
749 * | Nexthop Type | Set to one of ZEBRA_NEXTHOP_*
750 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
751 * | IPv4 Nexthop address or Interface Index number |
752 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
753 *
754 * Alternatively, if the route is a blackhole route, then Nexthop count
755 * is set to 1 and a nexthop of type NEXTHOP_TYPE_BLACKHOLE is the sole
756 * nexthop.
757 *
758 * The original struct zapi_route_*() infrastructure was built around
759 * the traditional (32-bit "gate OR ifindex") nexthop data unit.
760 * A special encoding can be used to feed onlink (64-bit "gate AND ifindex")
761 * nexthops into zapi_route_encode() using the same zapi_route structure.
762 * This is done by setting zapi_route fields as follows:
763 * - .message |= ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_ONLINK
764 * - .nexthop_num == .ifindex_num
765 * - .nexthop and .ifindex are filled with gate and ifindex parts of
766 * each compound nexthop, both in the same order
767 *
768 * If ZAPI_MESSAGE_DISTANCE is set, the distance value is written as a 1
769 * byte value.
770 *
771 * If ZAPI_MESSAGE_METRIC is set, the metric value is written as an 8
772 * byte value.
773 *
774 * If ZAPI_MESSAGE_TAG is set, the tag value is written as a 4 byte value
775 *
776 * If ZAPI_MESSAGE_MTU is set, the mtu value is written as a 4 byte value
777 *
778 * XXX: No attention paid to alignment.
779 */
780int zclient_route_send(uint8_t cmd, struct zclient *zclient,
781 struct zapi_route *api)
782{
783 if (zapi_route_encode(cmd, zclient->obuf, api) < 0)
784 return -1;
785 return zclient_send_message(zclient);
786}
787
788static int zapi_nexthop_labels_cmp(const struct zapi_nexthop *next1,
789 const struct zapi_nexthop *next2)
790{
791 if (next1->label_num > next2->label_num)
792 return 1;
793
794 if (next1->label_num < next2->label_num)
795 return -1;
796
797 return memcmp(next1->labels, next2->labels, next1->label_num);
798}
799
800static int zapi_nexthop_cmp_no_labels(const struct zapi_nexthop *next1,
801 const struct zapi_nexthop *next2)
802{
803 int ret = 0;
804
805 if (next1->vrf_id < next2->vrf_id)
806 return -1;
807
808 if (next1->vrf_id > next2->vrf_id)
809 return 1;
810
811 if (next1->type < next2->type)
812 return -1;
813
814 if (next1->type > next2->type)
815 return 1;
816
817 if (next1->weight < next2->weight)
818 return -1;
819
820 if (next1->weight > next2->weight)
821 return 1;
822
823 switch (next1->type) {
824 case NEXTHOP_TYPE_IPV4:
825 case NEXTHOP_TYPE_IPV6:
826 ret = nexthop_g_addr_cmp(next1->type, &next1->gate,
827 &next2->gate);
828 if (ret != 0)
829 return ret;
830 break;
831 case NEXTHOP_TYPE_IPV4_IFINDEX:
832 case NEXTHOP_TYPE_IPV6_IFINDEX:
833 ret = nexthop_g_addr_cmp(next1->type, &next1->gate,
834 &next2->gate);
835 if (ret != 0)
836 return ret;
837 /* Intentional Fall-Through */
838 case NEXTHOP_TYPE_IFINDEX:
839 if (next1->ifindex < next2->ifindex)
840 return -1;
841
842 if (next1->ifindex > next2->ifindex)
843 return 1;
844 break;
845 case NEXTHOP_TYPE_BLACKHOLE:
846 if (next1->bh_type < next2->bh_type)
847 return -1;
848
849 if (next1->bh_type > next2->bh_type)
850 return 1;
851 break;
852 }
853
854 return 0;
855}
856
857static int zapi_nexthop_cmp(const void *item1, const void *item2)
858{
859 int ret = 0;
860
861 const struct zapi_nexthop *next1 = item1;
862 const struct zapi_nexthop *next2 = item2;
863
864 ret = zapi_nexthop_cmp_no_labels(next1, next2);
865 if (ret != 0)
866 return ret;
867
868 ret = zapi_nexthop_labels_cmp(next1, next2);
869
870 return ret;
871}
872
873static void zapi_nexthop_group_sort(struct zapi_nexthop *nh_grp,
874 uint16_t nexthop_num)
875{
876 qsort(nh_grp, nexthop_num, sizeof(struct zapi_nexthop),
877 &zapi_nexthop_cmp);
878}
879
880/*
881 * Encode a single zapi nexthop
882 */
883int zapi_nexthop_encode(struct stream *s, const struct zapi_nexthop *api_nh,
884 uint32_t api_flags)
885{
886 int ret = 0;
887 int nh_flags = api_nh->flags;
888
889 stream_putl(s, api_nh->vrf_id);
890 stream_putc(s, api_nh->type);
891
892 /* If needed, set 'labelled nexthop' flag */
893 if (api_nh->label_num > 0) {
894 SET_FLAG(nh_flags, ZAPI_NEXTHOP_FLAG_LABEL);
895
896 /* Validate label count */
897 if (api_nh->label_num > MPLS_MAX_LABELS) {
898 ret = -1;
899 goto done;
900 }
901 }
902
903 if (api_nh->weight)
904 SET_FLAG(nh_flags, ZAPI_NEXTHOP_FLAG_WEIGHT);
905
906 /* Note that we're only encoding a single octet */
907 stream_putc(s, nh_flags);
908
909 switch (api_nh->type) {
910 case NEXTHOP_TYPE_BLACKHOLE:
911 stream_putc(s, api_nh->bh_type);
912 break;
913 case NEXTHOP_TYPE_IPV4:
914 case NEXTHOP_TYPE_IPV4_IFINDEX:
915 stream_put_in_addr(s, &api_nh->gate.ipv4);
916 stream_putl(s, api_nh->ifindex);
917 break;
918 case NEXTHOP_TYPE_IFINDEX:
919 stream_putl(s, api_nh->ifindex);
920 break;
921 case NEXTHOP_TYPE_IPV6:
922 case NEXTHOP_TYPE_IPV6_IFINDEX:
923 stream_write(s, (uint8_t *)&api_nh->gate.ipv6,
924 16);
925 stream_putl(s, api_nh->ifindex);
926 break;
927 }
928
929 /* We only encode labels if we have >0 - we use
930 * the per-nexthop flag above to signal that the count
931 * is present in the payload.
932 */
933 if (api_nh->label_num > 0) {
934 stream_putc(s, api_nh->label_num);
935 stream_put(s, &api_nh->labels[0],
936 api_nh->label_num * sizeof(mpls_label_t));
937 }
938
939 if (api_nh->weight)
940 stream_putl(s, api_nh->weight);
941
942 /* Router MAC for EVPN routes. */
943 if (CHECK_FLAG(api_flags, ZEBRA_FLAG_EVPN_ROUTE))
944 stream_put(s, &(api_nh->rmac),
945 sizeof(struct ethaddr));
946
947done:
948 return ret;
949}
950
951int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api)
952{
953 struct zapi_nexthop *api_nh;
954 int i;
955 int psize;
956
957 stream_reset(s);
958 zclient_create_header(s, cmd, api->vrf_id);
959
960 if (api->type >= ZEBRA_ROUTE_MAX) {
961 flog_err(EC_LIB_ZAPI_ENCODE,
962 "%s: Specified route type (%u) is not a legal value\n",
963 __PRETTY_FUNCTION__, api->type);
964 return -1;
965 }
966 stream_putc(s, api->type);
967
968 stream_putw(s, api->instance);
969 stream_putl(s, api->flags);
970 stream_putc(s, api->message);
971
972 if (api->safi < SAFI_UNICAST || api->safi >= SAFI_MAX) {
973 flog_err(EC_LIB_ZAPI_ENCODE,
974 "%s: Specified route SAFI (%u) is not a legal value\n",
975 __PRETTY_FUNCTION__, api->safi);
976 return -1;
977 }
978 stream_putc(s, api->safi);
979
980 /* Put prefix information. */
981 stream_putc(s, api->prefix.family);
982 psize = PSIZE(api->prefix.prefixlen);
983 stream_putc(s, api->prefix.prefixlen);
984 stream_write(s, (uint8_t *)&api->prefix.u.prefix, psize);
985
986 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_SRCPFX)) {
987 psize = PSIZE(api->src_prefix.prefixlen);
988 stream_putc(s, api->src_prefix.prefixlen);
989 stream_write(s, (uint8_t *)&api->src_prefix.prefix, psize);
990 }
991
992 /* Nexthops. */
993 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
994 /* limit the number of nexthops if necessary */
995 if (api->nexthop_num > MULTIPATH_NUM) {
996 char buf[PREFIX2STR_BUFFER];
997
998 prefix2str(&api->prefix, buf, sizeof(buf));
999 flog_err(
1000 EC_LIB_ZAPI_ENCODE,
1001 "%s: prefix %s: can't encode %u nexthops (maximum is %u)",
1002 __func__, buf, api->nexthop_num, MULTIPATH_NUM);
1003 return -1;
1004 }
1005
1006 zapi_nexthop_group_sort(api->nexthops, api->nexthop_num);
1007
1008 stream_putw(s, api->nexthop_num);
1009
1010 for (i = 0; i < api->nexthop_num; i++) {
1011 api_nh = &api->nexthops[i];
1012
1013 /* MPLS labels for BGP-LU or Segment Routing */
1014 if (api_nh->label_num > MPLS_MAX_LABELS) {
1015 char buf[PREFIX2STR_BUFFER];
1016
1017 prefix2str(&api->prefix, buf, sizeof(buf));
1018
1019 flog_err(EC_LIB_ZAPI_ENCODE,
1020 "%s: prefix %s: can't encode %u labels (maximum is %u)",
1021 __func__, buf,
1022 api_nh->label_num,
1023 MPLS_MAX_LABELS);
1024 return -1;
1025 }
1026
1027 if (zapi_nexthop_encode(s, api_nh, api->flags) != 0)
1028 return -1;
1029 }
1030 }
1031
1032 /* Attributes. */
1033 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
1034 stream_putc(s, api->distance);
1035 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
1036 stream_putl(s, api->metric);
1037 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
1038 stream_putl(s, api->tag);
1039 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
1040 stream_putl(s, api->mtu);
1041 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TABLEID))
1042 stream_putl(s, api->tableid);
1043
1044 /* Put length at the first point of the stream. */
1045 stream_putw_at(s, 0, stream_get_endp(s));
1046
1047 return 0;
1048}
1049
1050/*
1051 * Decode a single zapi nexthop object
1052 */
1053static int zapi_nexthop_decode(struct stream *s, struct zapi_nexthop *api_nh,
1054 uint32_t api_flags)
1055{
1056 int ret = -1;
1057
1058 STREAM_GETL(s, api_nh->vrf_id);
1059 STREAM_GETC(s, api_nh->type);
1060
1061 /* Note that we're only using a single octet of flags */
1062 STREAM_GETC(s, api_nh->flags);
1063
1064 switch (api_nh->type) {
1065 case NEXTHOP_TYPE_BLACKHOLE:
1066 STREAM_GETC(s, api_nh->bh_type);
1067 break;
1068 case NEXTHOP_TYPE_IPV4:
1069 case NEXTHOP_TYPE_IPV4_IFINDEX:
1070 STREAM_GET(&api_nh->gate.ipv4.s_addr, s,
1071 IPV4_MAX_BYTELEN);
1072 STREAM_GETL(s, api_nh->ifindex);
1073 break;
1074 case NEXTHOP_TYPE_IFINDEX:
1075 STREAM_GETL(s, api_nh->ifindex);
1076 break;
1077 case NEXTHOP_TYPE_IPV6:
1078 case NEXTHOP_TYPE_IPV6_IFINDEX:
1079 STREAM_GET(&api_nh->gate.ipv6, s, 16);
1080 STREAM_GETL(s, api_nh->ifindex);
1081 break;
1082 }
1083
1084 /* MPLS labels for BGP-LU or Segment Routing */
1085 if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_LABEL)) {
1086 STREAM_GETC(s, api_nh->label_num);
1087 if (api_nh->label_num > MPLS_MAX_LABELS) {
1088 flog_err(
1089 EC_LIB_ZAPI_ENCODE,
1090 "%s: invalid number of MPLS labels (%u)",
1091 __func__, api_nh->label_num);
1092 return -1;
1093 }
1094
1095 STREAM_GET(&api_nh->labels[0], s,
1096 api_nh->label_num * sizeof(mpls_label_t));
1097 }
1098
1099 if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_WEIGHT))
1100 STREAM_GETL(s, api_nh->weight);
1101
1102 /* Router MAC for EVPN routes. */
1103 if (CHECK_FLAG(api_flags, ZEBRA_FLAG_EVPN_ROUTE))
1104 STREAM_GET(&(api_nh->rmac), s,
1105 sizeof(struct ethaddr));
1106
1107 /* Success */
1108 ret = 0;
1109
1110stream_failure:
1111
1112 return ret;
1113}
1114
1115int zapi_route_decode(struct stream *s, struct zapi_route *api)
1116{
1117 struct zapi_nexthop *api_nh;
1118 int i;
1119
1120 memset(api, 0, sizeof(*api));
1121
1122 /* Type, flags, message. */
1123 STREAM_GETC(s, api->type);
1124 if (api->type >= ZEBRA_ROUTE_MAX) {
1125 flog_err(EC_LIB_ZAPI_ENCODE,
1126 "%s: Specified route type: %d is not a legal value\n",
1127 __PRETTY_FUNCTION__, api->type);
1128 return -1;
1129 }
1130
1131 STREAM_GETW(s, api->instance);
1132 STREAM_GETL(s, api->flags);
1133 STREAM_GETC(s, api->message);
1134 STREAM_GETC(s, api->safi);
1135 if (api->safi < SAFI_UNICAST || api->safi >= SAFI_MAX) {
1136 flog_err(EC_LIB_ZAPI_ENCODE,
1137 "%s: Specified route SAFI (%u) is not a legal value\n",
1138 __PRETTY_FUNCTION__, api->safi);
1139 return -1;
1140 }
1141
1142 /* Prefix. */
1143 STREAM_GETC(s, api->prefix.family);
1144 STREAM_GETC(s, api->prefix.prefixlen);
1145 switch (api->prefix.family) {
1146 case AF_INET:
1147 if (api->prefix.prefixlen > IPV4_MAX_PREFIXLEN) {
1148 flog_err(
1149 EC_LIB_ZAPI_ENCODE,
1150 "%s: V4 prefixlen is %d which should not be more than 32",
1151 __PRETTY_FUNCTION__, api->prefix.prefixlen);
1152 return -1;
1153 }
1154 break;
1155 case AF_INET6:
1156 if (api->prefix.prefixlen > IPV6_MAX_PREFIXLEN) {
1157 flog_err(
1158 EC_LIB_ZAPI_ENCODE,
1159 "%s: v6 prefixlen is %d which should not be more than 128",
1160 __PRETTY_FUNCTION__, api->prefix.prefixlen);
1161 return -1;
1162 }
1163 break;
1164 default:
1165 flog_err(EC_LIB_ZAPI_ENCODE,
1166 "%s: Specified family %d is not v4 or v6",
1167 __PRETTY_FUNCTION__, api->prefix.family);
1168 return -1;
1169 }
1170 STREAM_GET(&api->prefix.u.prefix, s, PSIZE(api->prefix.prefixlen));
1171
1172 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_SRCPFX)) {
1173 api->src_prefix.family = AF_INET6;
1174 STREAM_GETC(s, api->src_prefix.prefixlen);
1175 if (api->src_prefix.prefixlen > IPV6_MAX_PREFIXLEN) {
1176 flog_err(
1177 EC_LIB_ZAPI_ENCODE,
1178 "%s: SRC Prefix prefixlen received: %d is too large",
1179 __PRETTY_FUNCTION__, api->src_prefix.prefixlen);
1180 return -1;
1181 }
1182 STREAM_GET(&api->src_prefix.prefix, s,
1183 PSIZE(api->src_prefix.prefixlen));
1184
1185 if (api->prefix.family != AF_INET6
1186 || api->src_prefix.prefixlen == 0) {
1187 flog_err(
1188 EC_LIB_ZAPI_ENCODE,
1189 "%s: SRC prefix specified in some manner that makes no sense",
1190 __PRETTY_FUNCTION__);
1191 return -1;
1192 }
1193 }
1194
1195 /* Nexthops. */
1196 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
1197 STREAM_GETW(s, api->nexthop_num);
1198 if (api->nexthop_num > MULTIPATH_NUM) {
1199 flog_err(EC_LIB_ZAPI_ENCODE,
1200 "%s: invalid number of nexthops (%u)",
1201 __func__, api->nexthop_num);
1202 return -1;
1203 }
1204
1205 for (i = 0; i < api->nexthop_num; i++) {
1206 api_nh = &api->nexthops[i];
1207
1208 if (zapi_nexthop_decode(s, api_nh, api->flags) != 0)
1209 return -1;
1210 }
1211 }
1212
1213 /* Attributes. */
1214 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
1215 STREAM_GETC(s, api->distance);
1216 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
1217 STREAM_GETL(s, api->metric);
1218 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
1219 STREAM_GETL(s, api->tag);
1220 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
1221 STREAM_GETL(s, api->mtu);
1222 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TABLEID))
1223 STREAM_GETL(s, api->tableid);
1224
1225 return 0;
1226stream_failure:
1227 return -1;
1228}
1229
1230static void zapi_encode_prefix(struct stream *s, struct prefix *p,
1231 uint8_t family)
1232{
1233 struct prefix any;
1234
1235 if (!p) {
1236 memset(&any, 0, sizeof(any));
1237 any.family = family;
1238 p = &any;
1239 }
1240
1241 stream_putc(s, p->family);
1242 stream_putc(s, p->prefixlen);
1243 stream_put(s, &p->u.prefix, prefix_blen(p));
1244}
1245
1246int zapi_pbr_rule_encode(uint8_t cmd, struct stream *s, struct pbr_rule *zrule)
1247{
1248 stream_reset(s);
1249 zclient_create_header(s, cmd, zrule->vrf_id);
1250
1251 /*
1252 * We are sending one item at a time at the moment
1253 */
1254 stream_putl(s, 1);
1255
1256 stream_putl(s, zrule->seq);
1257 stream_putl(s, zrule->priority);
1258 stream_putl(s, zrule->unique);
1259
1260 zapi_encode_prefix(s, &(zrule->filter.src_ip),
1261 zrule->filter.src_ip.family);
1262 stream_putw(s, zrule->filter.src_port); /* src port */
1263 zapi_encode_prefix(s, &(zrule->filter.dst_ip),
1264 zrule->filter.src_ip.family);
1265 stream_putw(s, zrule->filter.dst_port); /* dst port */
1266 stream_putw(s, zrule->filter.fwmark); /* fwmark */
1267
1268 stream_putl(s, zrule->action.table);
1269 stream_putl(s, zrule->ifindex);
1270
1271 /* Put length at the first point of the stream. */
1272 stream_putw_at(s, 0, stream_get_endp(s));
1273
1274 return 0;
1275}
1276
1277bool zapi_route_notify_decode(struct stream *s, struct prefix *p,
1278 uint32_t *tableid,
1279 enum zapi_route_notify_owner *note)
1280{
1281 uint32_t t;
1282
1283 STREAM_GET(note, s, sizeof(*note));
1284
1285 STREAM_GETC(s, p->family);
1286 STREAM_GETC(s, p->prefixlen);
1287 STREAM_GET(&p->u.prefix, s, prefix_blen(p));
1288 STREAM_GETL(s, t);
1289
1290 *tableid = t;
1291
1292 return true;
1293
1294stream_failure:
1295 return false;
1296}
1297
1298bool zapi_rule_notify_decode(struct stream *s, uint32_t *seqno,
1299 uint32_t *priority, uint32_t *unique,
1300 ifindex_t *ifindex,
1301 enum zapi_rule_notify_owner *note)
1302{
1303 uint32_t prio, seq, uni;
1304 ifindex_t ifi;
1305
1306 STREAM_GET(note, s, sizeof(*note));
1307
1308 STREAM_GETL(s, seq);
1309 STREAM_GETL(s, prio);
1310 STREAM_GETL(s, uni);
1311 STREAM_GETL(s, ifi);
1312
1313 if (zclient_debug)
1314 zlog_debug("%s: %u %u %u %u", __PRETTY_FUNCTION__, seq, prio,
1315 uni, ifi);
1316 *seqno = seq;
1317 *priority = prio;
1318 *unique = uni;
1319 *ifindex = ifi;
1320
1321 return true;
1322
1323stream_failure:
1324 return false;
1325}
1326
1327bool zapi_ipset_notify_decode(struct stream *s, uint32_t *unique,
1328 enum zapi_ipset_notify_owner *note)
1329{
1330 uint32_t uni;
1331
1332 STREAM_GET(note, s, sizeof(*note));
1333
1334 STREAM_GETL(s, uni);
1335
1336 if (zclient_debug)
1337 zlog_debug("%s: %u", __PRETTY_FUNCTION__, uni);
1338 *unique = uni;
1339
1340 return true;
1341
1342stream_failure:
1343 return false;
1344}
1345
1346bool zapi_ipset_entry_notify_decode(struct stream *s, uint32_t *unique,
1347 char *ipset_name,
1348 enum zapi_ipset_entry_notify_owner *note)
1349{
1350 uint32_t uni;
1351
1352 STREAM_GET(note, s, sizeof(*note));
1353
1354 STREAM_GETL(s, uni);
1355
1356 STREAM_GET(ipset_name, s, ZEBRA_IPSET_NAME_SIZE);
1357
1358 if (zclient_debug)
1359 zlog_debug("%s: %u", __PRETTY_FUNCTION__, uni);
1360 *unique = uni;
1361
1362 return true;
1363
1364stream_failure:
1365 return false;
1366}
1367
1368bool zapi_iptable_notify_decode(struct stream *s,
1369 uint32_t *unique,
1370 enum zapi_iptable_notify_owner *note)
1371{
1372 uint32_t uni;
1373
1374 STREAM_GET(note, s, sizeof(*note));
1375
1376 STREAM_GETL(s, uni);
1377
1378 if (zclient_debug)
1379 zlog_debug("%s: %u", __PRETTY_FUNCTION__, uni);
1380 *unique = uni;
1381
1382 return true;
1383
1384stream_failure:
1385 return false;
1386}
1387
1388struct nexthop *nexthop_from_zapi_nexthop(struct zapi_nexthop *znh)
1389{
1390 struct nexthop *n = nexthop_new();
1391
1392 n->type = znh->type;
1393 n->vrf_id = znh->vrf_id;
1394 n->ifindex = znh->ifindex;
1395 n->gate = znh->gate;
1396
1397 /*
1398 * This function currently handles labels
1399 */
1400 if (znh->label_num) {
1401 nexthop_add_labels(n, ZEBRA_LSP_NONE, znh->label_num,
1402 znh->labels);
1403 }
1404
1405 return n;
1406}
1407
1408/*
1409 * Convert nexthop to zapi nexthop
1410 */
1411int zapi_nexthop_from_nexthop(struct zapi_nexthop *znh,
1412 const struct nexthop *nh)
1413{
1414 int i;
1415
1416 memset(znh, 0, sizeof(*znh));
1417
1418 znh->type = nh->type;
1419 znh->vrf_id = nh->vrf_id;
1420 znh->ifindex = nh->ifindex;
1421 znh->gate = nh->gate;
1422
1423 if (nh->nh_label && (nh->nh_label->num_labels > 0)) {
1424 for (i = 0; i < nh->nh_label->num_labels; i++)
1425 znh->labels[i] = nh->nh_label->label[i];
1426
1427 znh->label_num = i;
1428 SET_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_LABEL);
1429 }
1430
1431 return 0;
1432}
1433
1434/*
1435 * Decode the nexthop-tracking update message
1436 */
1437bool zapi_nexthop_update_decode(struct stream *s, struct zapi_route *nhr)
1438{
1439 uint32_t i;
1440
1441 memset(nhr, 0, sizeof(*nhr));
1442
1443 STREAM_GETW(s, nhr->prefix.family);
1444 STREAM_GETC(s, nhr->prefix.prefixlen);
1445 switch (nhr->prefix.family) {
1446 case AF_INET:
1447 STREAM_GET(&nhr->prefix.u.prefix4.s_addr, s, IPV4_MAX_BYTELEN);
1448 break;
1449 case AF_INET6:
1450 STREAM_GET(&nhr->prefix.u.prefix6, s, IPV6_MAX_BYTELEN);
1451 break;
1452 default:
1453 break;
1454 }
1455
1456 STREAM_GETC(s, nhr->type);
1457 STREAM_GETW(s, nhr->instance);
1458 STREAM_GETC(s, nhr->distance);
1459 STREAM_GETL(s, nhr->metric);
1460 STREAM_GETC(s, nhr->nexthop_num);
1461
1462 for (i = 0; i < nhr->nexthop_num; i++) {
1463 if (zapi_nexthop_decode(s, &(nhr->nexthops[i]), 0) != 0)
1464 return -1;
1465 }
1466
1467 return true;
1468stream_failure:
1469 return false;
1470}
1471
1472bool zapi_error_decode(struct stream *s, enum zebra_error_types *error)
1473{
1474 memset(error, 0, sizeof(*error));
1475
1476 STREAM_GET(error, s, sizeof(*error));
1477
1478 if (zclient_debug)
1479 zlog_debug("%s: type: %s", __func__,
1480 zebra_error_type2str(*error));
1481
1482 return true;
1483stream_failure:
1484 return false;
1485}
1486
1487/*
1488 * send a ZEBRA_REDISTRIBUTE_ADD or ZEBRA_REDISTRIBUTE_DELETE
1489 * for the route type (ZEBRA_ROUTE_KERNEL etc.). The zebra server will
1490 * then set/unset redist[type] in the client handle (a struct zserv) for the
1491 * sending client
1492 */
1493int zebra_redistribute_send(int command, struct zclient *zclient, afi_t afi,
1494 int type, unsigned short instance, vrf_id_t vrf_id)
1495{
1496 struct stream *s;
1497
1498 s = zclient->obuf;
1499 stream_reset(s);
1500
1501 zclient_create_header(s, command, vrf_id);
1502 stream_putc(s, afi);
1503 stream_putc(s, type);
1504 stream_putw(s, instance);
1505
1506 stream_putw_at(s, 0, stream_get_endp(s));
1507
1508 return zclient_send_message(zclient);
1509}
1510
1511int zebra_redistribute_default_send(int command, struct zclient *zclient,
1512 afi_t afi, vrf_id_t vrf_id)
1513{
1514 struct stream *s;
1515
1516 s = zclient->obuf;
1517 stream_reset(s);
1518
1519 zclient_create_header(s, command, vrf_id);
1520 stream_putc(s, afi);
1521
1522 stream_putw_at(s, 0, stream_get_endp(s));
1523
1524 return zclient_send_message(zclient);
1525}
1526
1527/* Get prefix in ZServ format; family should be filled in on prefix */
1528static void zclient_stream_get_prefix(struct stream *s, struct prefix *p)
1529{
1530 size_t plen = prefix_blen(p);
1531 uint8_t c;
1532 p->prefixlen = 0;
1533
1534 if (plen == 0)
1535 return;
1536
1537 stream_get(&p->u.prefix, s, plen);
1538 STREAM_GETC(s, c);
1539 p->prefixlen = MIN(plen * 8, c);
1540
1541stream_failure:
1542 return;
1543}
1544
1545/* Router-id update from zebra daemon. */
1546void zebra_router_id_update_read(struct stream *s, struct prefix *rid)
1547{
1548 /* Fetch interface address. */
1549 STREAM_GETC(s, rid->family);
1550
1551 zclient_stream_get_prefix(s, rid);
1552
1553stream_failure:
1554 return;
1555}
1556
1557/* Interface addition from zebra daemon. */
1558/*
1559 * The format of the message sent with type ZEBRA_INTERFACE_ADD or
1560 * ZEBRA_INTERFACE_DELETE from zebra to the client is:
1561 * 0 1 2 3
1562 * 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
1563 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1564 * | ifname |
1565 * | |
1566 * | |
1567 * | |
1568 * | |
1569 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1570 * | ifindex |
1571 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1572 * | status |
1573 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1574 * | if_flags |
1575 * | |
1576 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1577 * | metric |
1578 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1579 * | speed |
1580 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1581 * | ifmtu |
1582 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1583 * | ifmtu6 |
1584 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1585 * | bandwidth |
1586 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1587 * | parent ifindex |
1588 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1589 * | Link Layer Type |
1590 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1591 * | Harware Address Length |
1592 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1593 * | Hardware Address if HW lenght different from 0 |
1594 * | ... max INTERFACE_HWADDR_MAX |
1595 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1596 * | Link_params? | Whether a link-params follows: 1 or 0.
1597 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1598 * | Link_params 0 or 1 INTERFACE_LINK_PARAMS_SIZE sized |
1599 * | .... (struct if_link_params). |
1600 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1601 */
1602
1603static void zclient_vrf_add(struct zclient *zclient, vrf_id_t vrf_id)
1604{
1605 struct vrf *vrf;
1606 char vrfname_tmp[VRF_NAMSIZ];
1607 struct vrf_data data;
1608
1609 stream_get(&data, zclient->ibuf, sizeof(struct vrf_data));
1610 /* Read interface name. */
1611 stream_get(vrfname_tmp, zclient->ibuf, VRF_NAMSIZ);
1612
1613 /* Lookup/create vrf by vrf_id. */
1614 vrf = vrf_get(vrf_id, vrfname_tmp);
1615 vrf->data.l.table_id = data.l.table_id;
1616 memcpy(vrf->data.l.netns_name, data.l.netns_name, NS_NAMSIZ);
1617 /* overwrite default vrf */
1618 if (vrf_id == VRF_DEFAULT)
1619 vrf_set_default_name(vrfname_tmp, false);
1620 vrf_enable(vrf);
1621}
1622
1623static void zclient_vrf_delete(struct zclient *zclient, vrf_id_t vrf_id)
1624{
1625 struct vrf *vrf;
1626
1627 /* Lookup vrf by vrf_id. */
1628 vrf = vrf_lookup_by_id(vrf_id);
1629
1630 /*
1631 * If a routing protocol doesn't know about a
1632 * vrf that is about to be deleted. There is
1633 * no point in attempting to delete it.
1634 */
1635 if (!vrf)
1636 return;
1637
1638 vrf_delete(vrf);
1639}
1640
1641static void zclient_interface_add(struct zclient *zclient, vrf_id_t vrf_id)
1642{
1643 struct interface *ifp;
1644 char ifname_tmp[INTERFACE_NAMSIZ];
1645 struct stream *s = zclient->ibuf;
1646
1647 /* Read interface name. */
1648 stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
1649
1650 /* Lookup/create interface by name. */
1651 ifp = if_get_by_name(ifname_tmp, vrf_id);
1652
1653 zebra_interface_if_set_value(s, ifp);
1654
1655 if_new_via_zapi(ifp);
1656}
1657
1658/*
1659 * Read interface up/down msg (ZEBRA_INTERFACE_UP/ZEBRA_INTERFACE_DOWN)
1660 * from zebra server. The format of this message is the same as
1661 * that sent for ZEBRA_INTERFACE_ADD/ZEBRA_INTERFACE_DELETE,
1662 * except that no sockaddr_dl is sent at the tail of the message.
1663 */
1664struct interface *zebra_interface_state_read(struct stream *s, vrf_id_t vrf_id)
1665{
1666 struct interface *ifp;
1667 char ifname_tmp[INTERFACE_NAMSIZ];
1668
1669 /* Read interface name. */
1670 stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
1671
1672 /* Lookup this by interface index. */
1673 ifp = if_lookup_by_name(ifname_tmp, vrf_id);
1674 if (ifp == NULL) {
1675 flog_err(EC_LIB_ZAPI_ENCODE,
1676 "INTERFACE_STATE: Cannot find IF %s in VRF %d",
1677 ifname_tmp, vrf_id);
1678 return NULL;
1679 }
1680
1681 zebra_interface_if_set_value(s, ifp);
1682
1683 return ifp;
1684}
1685
1686static void zclient_interface_delete(struct zclient *zclient, vrf_id_t vrf_id)
1687{
1688 struct interface *ifp;
1689 struct stream *s = zclient->ibuf;
1690
1691 ifp = zebra_interface_state_read(s, vrf_id);
1692
1693 if (ifp == NULL)
1694 return;
1695
1696 if_destroy_via_zapi(ifp);
1697 return;
1698}
1699
1700static void zclient_interface_up(struct zclient *zclient, vrf_id_t vrf_id)
1701{
1702 struct interface *ifp;
1703 struct stream *s = zclient->ibuf;
1704
1705 ifp = zebra_interface_state_read(s, vrf_id);
1706
1707 if (!ifp)
1708 return;
1709
1710 if_up_via_zapi(ifp);
1711}
1712
1713static void zclient_interface_down(struct zclient *zclient, vrf_id_t vrf_id)
1714{
1715 struct interface *ifp;
1716 struct stream *s = zclient->ibuf;
1717
1718 ifp = zebra_interface_state_read(s, vrf_id);
1719
1720 if (!ifp)
1721 return;
1722
1723 if_down_via_zapi(ifp);
1724}
1725
1726static void zclient_handle_error(ZAPI_CALLBACK_ARGS)
1727{
1728 enum zebra_error_types error;
1729 struct stream *s = zclient->ibuf;
1730
1731 zapi_error_decode(s, &error);
1732
1733 if (zclient->handle_error)
1734 (*zclient->handle_error)(error);
1735}
1736
1737static void link_params_set_value(struct stream *s, struct if_link_params *iflp)
1738{
1739
1740 if (iflp == NULL)
1741 return;
1742
1743 iflp->lp_status = stream_getl(s);
1744 iflp->te_metric = stream_getl(s);
1745 iflp->max_bw = stream_getf(s);
1746 iflp->max_rsv_bw = stream_getf(s);
1747 uint32_t bwclassnum = stream_getl(s);
1748 {
1749 unsigned int i;
1750 for (i = 0; i < bwclassnum && i < MAX_CLASS_TYPE; i++)
1751 iflp->unrsv_bw[i] = stream_getf(s);
1752 if (i < bwclassnum)
1753 flog_err(
1754 EC_LIB_ZAPI_MISSMATCH,
1755 "%s: received %d > %d (MAX_CLASS_TYPE) bw entries"
1756 " - outdated library?",
1757 __func__, bwclassnum, MAX_CLASS_TYPE);
1758 }
1759 iflp->admin_grp = stream_getl(s);
1760 iflp->rmt_as = stream_getl(s);
1761 iflp->rmt_ip.s_addr = stream_get_ipv4(s);
1762
1763 iflp->av_delay = stream_getl(s);
1764 iflp->min_delay = stream_getl(s);
1765 iflp->max_delay = stream_getl(s);
1766 iflp->delay_var = stream_getl(s);
1767
1768 iflp->pkt_loss = stream_getf(s);
1769 iflp->res_bw = stream_getf(s);
1770 iflp->ava_bw = stream_getf(s);
1771 iflp->use_bw = stream_getf(s);
1772}
1773
1774struct interface *zebra_interface_link_params_read(struct stream *s,
1775 vrf_id_t vrf_id)
1776{
1777 struct if_link_params *iflp;
1778 ifindex_t ifindex;
1779
1780 assert(s);
1781
1782 ifindex = stream_getl(s);
1783
1784 struct interface *ifp = if_lookup_by_index(ifindex, vrf_id);
1785
1786 if (ifp == NULL) {
1787 flog_err(EC_LIB_ZAPI_ENCODE,
1788 "%s: unknown ifindex %u, shouldn't happen", __func__,
1789 ifindex);
1790 return NULL;
1791 }
1792
1793 if ((iflp = if_link_params_get(ifp)) == NULL)
1794 return NULL;
1795
1796 link_params_set_value(s, iflp);
1797
1798 return ifp;
1799}
1800
1801static void zebra_interface_if_set_value(struct stream *s,
1802 struct interface *ifp)
1803{
1804 uint8_t link_params_status = 0;
1805 ifindex_t old_ifindex;
1806
1807 old_ifindex = ifp->ifindex;
1808 /* Read interface's index. */
1809 if_set_index(ifp, stream_getl(s));
1810 ifp->status = stream_getc(s);
1811
1812 /* Read interface's value. */
1813 ifp->flags = stream_getq(s);
1814 ifp->ptm_enable = stream_getc(s);
1815 ifp->ptm_status = stream_getc(s);
1816 ifp->metric = stream_getl(s);
1817 ifp->speed = stream_getl(s);
1818 ifp->mtu = stream_getl(s);
1819 ifp->mtu6 = stream_getl(s);
1820 ifp->bandwidth = stream_getl(s);
1821 ifp->link_ifindex = stream_getl(s);
1822 ifp->ll_type = stream_getl(s);
1823 ifp->hw_addr_len = stream_getl(s);
1824 if (ifp->hw_addr_len)
1825 stream_get(ifp->hw_addr, s,
1826 MIN(ifp->hw_addr_len, INTERFACE_HWADDR_MAX));
1827
1828 /* Read Traffic Engineering status */
1829 link_params_status = stream_getc(s);
1830 /* Then, Traffic Engineering parameters if any */
1831 if (link_params_status) {
1832 struct if_link_params *iflp = if_link_params_get(ifp);
1833 link_params_set_value(s, iflp);
1834 }
1835
1836 nexthop_group_interface_state_change(ifp, old_ifindex);
1837}
1838
1839size_t zebra_interface_link_params_write(struct stream *s,
1840 struct interface *ifp)
1841{
1842 size_t w;
1843 struct if_link_params *iflp;
1844 int i;
1845
1846 if (s == NULL || ifp == NULL || ifp->link_params == NULL)
1847 return 0;
1848
1849 iflp = ifp->link_params;
1850 w = 0;
1851
1852 w += stream_putl(s, iflp->lp_status);
1853
1854 w += stream_putl(s, iflp->te_metric);
1855 w += stream_putf(s, iflp->max_bw);
1856 w += stream_putf(s, iflp->max_rsv_bw);
1857
1858 w += stream_putl(s, MAX_CLASS_TYPE);
1859 for (i = 0; i < MAX_CLASS_TYPE; i++)
1860 w += stream_putf(s, iflp->unrsv_bw[i]);
1861
1862 w += stream_putl(s, iflp->admin_grp);
1863 w += stream_putl(s, iflp->rmt_as);
1864 w += stream_put_in_addr(s, &iflp->rmt_ip);
1865
1866 w += stream_putl(s, iflp->av_delay);
1867 w += stream_putl(s, iflp->min_delay);
1868 w += stream_putl(s, iflp->max_delay);
1869 w += stream_putl(s, iflp->delay_var);
1870
1871 w += stream_putf(s, iflp->pkt_loss);
1872 w += stream_putf(s, iflp->res_bw);
1873 w += stream_putf(s, iflp->ava_bw);
1874 w += stream_putf(s, iflp->use_bw);
1875
1876 return w;
1877}
1878
1879/*
1880 * format of message for address additon is:
1881 * 0
1882 * 0 1 2 3 4 5 6 7
1883 * +-+-+-+-+-+-+-+-+
1884 * | type | ZEBRA_INTERFACE_ADDRESS_ADD or
1885 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_ADDRES_DELETE
1886 * | |
1887 * + +
1888 * | ifindex |
1889 * + +
1890 * | |
1891 * + +
1892 * | |
1893 * +-+-+-+-+-+-+-+-+
1894 * | ifc_flags | flags for connected address
1895 * +-+-+-+-+-+-+-+-+
1896 * | addr_family |
1897 * +-+-+-+-+-+-+-+-+
1898 * | addr... |
1899 * : :
1900 * | |
1901 * +-+-+-+-+-+-+-+-+
1902 * | addr_len | len of addr. E.g., addr_len = 4 for ipv4 addrs.
1903 * +-+-+-+-+-+-+-+-+
1904 * | daddr.. |
1905 * : :
1906 * | |
1907 * +-+-+-+-+-+-+-+-+
1908 */
1909
1910static int memconstant(const void *s, int c, size_t n)
1911{
1912 const uint8_t *p = s;
1913
1914 while (n-- > 0)
1915 if (*p++ != c)
1916 return 0;
1917 return 1;
1918}
1919
1920
1921struct connected *zebra_interface_address_read(int type, struct stream *s,
1922 vrf_id_t vrf_id)
1923{
1924 ifindex_t ifindex;
1925 struct interface *ifp;
1926 struct connected *ifc;
1927 struct prefix p, d, *dp;
1928 int plen;
1929 uint8_t ifc_flags;
1930
1931 memset(&p, 0, sizeof(p));
1932 memset(&d, 0, sizeof(d));
1933
1934 /* Get interface index. */
1935 ifindex = stream_getl(s);
1936
1937 /* Lookup index. */
1938 ifp = if_lookup_by_index(ifindex, vrf_id);
1939 if (ifp == NULL) {
1940 flog_err(EC_LIB_ZAPI_ENCODE,
1941 "INTERFACE_ADDRESS_%s: Cannot find IF %u in VRF %d",
1942 (type == ZEBRA_INTERFACE_ADDRESS_ADD) ? "ADD" : "DEL",
1943 ifindex, vrf_id);
1944 return NULL;
1945 }
1946
1947 /* Fetch flag. */
1948 ifc_flags = stream_getc(s);
1949
1950 /* Fetch interface address. */
1951 d.family = p.family = stream_getc(s);
1952 plen = prefix_blen(&d);
1953
1954 zclient_stream_get_prefix(s, &p);
1955
1956 /* Fetch destination address. */
1957 stream_get(&d.u.prefix, s, plen);
1958
1959 /* N.B. NULL destination pointers are encoded as all zeroes */
1960 dp = memconstant(&d.u.prefix, 0, plen) ? NULL : &d;
1961
1962 if (type == ZEBRA_INTERFACE_ADDRESS_ADD) {
1963 ifc = connected_lookup_prefix_exact(ifp, &p);
1964 if (!ifc) {
1965 /* N.B. NULL destination pointers are encoded as all
1966 * zeroes */
1967 ifc = connected_add_by_prefix(ifp, &p, dp);
1968 }
1969 if (ifc) {
1970 ifc->flags = ifc_flags;
1971 if (ifc->destination)
1972 ifc->destination->prefixlen =
1973 ifc->address->prefixlen;
1974 else if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER)) {
1975 /* carp interfaces on OpenBSD with 0.0.0.0/0 as
1976 * "peer" */
1977 char buf[PREFIX_STRLEN];
1978 flog_err(
1979 EC_LIB_ZAPI_ENCODE,
1980 "warning: interface %s address %s with peer flag set, but no peer address!",
1981 ifp->name,
1982 prefix2str(ifc->address, buf,
1983 sizeof buf));
1984 UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
1985 }
1986 }
1987 } else {
1988 assert(type == ZEBRA_INTERFACE_ADDRESS_DELETE);
1989 ifc = connected_delete_by_prefix(ifp, &p);
1990 }
1991
1992 return ifc;
1993}
1994
1995/*
1996 * format of message for neighbor connected address is:
1997 * 0
1998 * 0 1 2 3 4 5 6 7
1999 * +-+-+-+-+-+-+-+-+
2000 * | type | ZEBRA_INTERFACE_NBR_ADDRESS_ADD or
2001 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_NBR_ADDRES_DELETE
2002 * | |
2003 * + +
2004 * | ifindex |
2005 * + +
2006 * | |
2007 * + +
2008 * | |
2009 * +-+-+-+-+-+-+-+-+
2010 * | addr_family |
2011 * +-+-+-+-+-+-+-+-+
2012 * | addr... |
2013 * : :
2014 * | |
2015 * +-+-+-+-+-+-+-+-+
2016 * | addr_len | len of addr.
2017 * +-+-+-+-+-+-+-+-+
2018 */
2019struct nbr_connected *
2020zebra_interface_nbr_address_read(int type, struct stream *s, vrf_id_t vrf_id)
2021{
2022 unsigned int ifindex;
2023 struct interface *ifp;
2024 struct prefix p;
2025 struct nbr_connected *ifc;
2026
2027 /* Get interface index. */
2028 ifindex = stream_getl(s);
2029
2030 /* Lookup index. */
2031 ifp = if_lookup_by_index(ifindex, vrf_id);
2032 if (ifp == NULL) {
2033 flog_err(EC_LIB_ZAPI_ENCODE,
2034 "INTERFACE_NBR_%s: Cannot find IF %u in VRF %d",
2035 (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD) ? "ADD"
2036 : "DELETE",
2037 ifindex, vrf_id);
2038 return NULL;
2039 }
2040
2041 p.family = stream_getc(s);
2042 stream_get(&p.u.prefix, s, prefix_blen(&p));
2043 p.prefixlen = stream_getc(s);
2044
2045 if (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD) {
2046 /* Currently only supporting P2P links, so any new RA source
2047 address is
2048 considered as the replacement of the previously learnt
2049 Link-Local address. */
2050 if (!(ifc = listnode_head(ifp->nbr_connected))) {
2051 ifc = nbr_connected_new();
2052 ifc->address = prefix_new();
2053 ifc->ifp = ifp;
2054 listnode_add(ifp->nbr_connected, ifc);
2055 }
2056
2057 prefix_copy(ifc->address, &p);
2058 } else {
2059 assert(type == ZEBRA_INTERFACE_NBR_ADDRESS_DELETE);
2060
2061 ifc = nbr_connected_check(ifp, &p);
2062 if (ifc)
2063 listnode_delete(ifp->nbr_connected, ifc);
2064 }
2065
2066 return ifc;
2067}
2068
2069struct interface *zebra_interface_vrf_update_read(struct stream *s,
2070 vrf_id_t vrf_id,
2071 vrf_id_t *new_vrf_id)
2072{
2073 char ifname[INTERFACE_NAMSIZ];
2074 struct interface *ifp;
2075 vrf_id_t new_id;
2076
2077 /* Read interface name. */
2078 stream_get(ifname, s, INTERFACE_NAMSIZ);
2079
2080 /* Lookup interface. */
2081 ifp = if_lookup_by_name(ifname, vrf_id);
2082 if (ifp == NULL) {
2083 flog_err(EC_LIB_ZAPI_ENCODE,
2084 "INTERFACE_VRF_UPDATE: Cannot find IF %s in VRF %d",
2085 ifname, vrf_id);
2086 return NULL;
2087 }
2088
2089 /* Fetch new VRF Id. */
2090 new_id = stream_getl(s);
2091
2092 *new_vrf_id = new_id;
2093 return ifp;
2094}
2095
2096/* filter unwanted messages until the expected one arrives */
2097static int zclient_read_sync_response(struct zclient *zclient,
2098 uint16_t expected_cmd)
2099{
2100 struct stream *s;
2101 uint16_t size = -1;
2102 uint8_t marker;
2103 uint8_t version;
2104 vrf_id_t vrf_id;
2105 uint16_t cmd;
2106 fd_set readfds;
2107 int ret;
2108
2109 ret = 0;
2110 cmd = expected_cmd + 1;
2111 while (ret == 0 && cmd != expected_cmd) {
2112 s = zclient->ibuf;
2113 stream_reset(s);
2114
2115 /* wait until response arrives */
2116 FD_ZERO(&readfds);
2117 FD_SET(zclient->sock, &readfds);
2118 select(zclient->sock + 1, &readfds, NULL, NULL, NULL);
2119 if (!FD_ISSET(zclient->sock, &readfds))
2120 continue;
2121 /* read response */
2122 ret = zclient_read_header(s, zclient->sock, &size, &marker,
2123 &version, &vrf_id, &cmd);
2124 if (zclient_debug)
2125 zlog_debug("%s: Response (%d bytes) received", __func__,
2126 size);
2127 }
2128 if (ret != 0) {
2129 flog_err(EC_LIB_ZAPI_ENCODE, "%s: Invalid Sync Message Reply",
2130 __func__);
2131 return -1;
2132 }
2133
2134 return 0;
2135}
2136/**
2137 * Connect to label manager in a syncronous way
2138 *
2139 * It first writes the request to zcient output buffer and then
2140 * immediately reads the answer from the input buffer.
2141 *
2142 * @param zclient Zclient used to connect to label manager (zebra)
2143 * @param async Synchronous (0) or asynchronous (1) operation
2144 * @result Result of response
2145 */
2146int lm_label_manager_connect(struct zclient *zclient, int async)
2147{
2148 int ret;
2149 struct stream *s;
2150 uint8_t result;
2151 uint16_t cmd = async ? ZEBRA_LABEL_MANAGER_CONNECT_ASYNC :
2152 ZEBRA_LABEL_MANAGER_CONNECT;
2153
2154 if (zclient_debug)
2155 zlog_debug("Connecting to Label Manager (LM)");
2156
2157 if (zclient->sock < 0) {
2158 zlog_debug("%s: invalid zclient socket", __func__);
2159 return -1;
2160 }
2161
2162 /* send request */
2163 s = zclient->obuf;
2164 stream_reset(s);
2165 zclient_create_header(s, cmd, VRF_DEFAULT);
2166
2167 /* proto */
2168 stream_putc(s, zclient->redist_default);
2169 /* instance */
2170 stream_putw(s, zclient->instance);
2171
2172 /* Put length at the first point of the stream. */
2173 stream_putw_at(s, 0, stream_get_endp(s));
2174
2175 ret = writen(zclient->sock, s->data, stream_get_endp(s));
2176 if (ret < 0) {
2177 flog_err(EC_LIB_ZAPI_SOCKET, "Can't write to zclient sock");
2178 close(zclient->sock);
2179 zclient->sock = -1;
2180 return -1;
2181 }
2182 if (ret == 0) {
2183 flog_err(EC_LIB_ZAPI_SOCKET, "Zclient sock closed");
2184 close(zclient->sock);
2185 zclient->sock = -1;
2186 return -1;
2187 }
2188 if (zclient_debug)
2189 zlog_debug("LM connect request sent (%d bytes)", ret);
2190
2191 if (async)
2192 return 0;
2193
2194 /* read response */
2195 if (zclient_read_sync_response(zclient, cmd)
2196 != 0)
2197 return -1;
2198
2199 s = zclient->ibuf;
2200
2201 /* read instance and proto */
2202 uint8_t proto = stream_getc(s);
2203 uint16_t instance = stream_getw(s);
2204
2205 /* sanity */
2206 if (proto != zclient->redist_default)
2207 flog_err(
2208 EC_LIB_ZAPI_ENCODE,
2209 "Wrong proto (%u) in LM connect response. Should be %u",
2210 proto, zclient->redist_default);
2211 if (instance != zclient->instance)
2212 flog_err(
2213 EC_LIB_ZAPI_ENCODE,
2214 "Wrong instId (%u) in LM connect response. Should be %u",
2215 instance, zclient->instance);
2216
2217 /* result code */
2218 result = stream_getc(s);
2219 if (zclient_debug)
2220 zlog_debug("LM connect-response received, result %u", result);
2221
2222 return (int)result;
2223}
2224
2225/*
2226 * Asynchronous label chunk request
2227 *
2228 * @param zclient Zclient used to connect to label manager (zebra)
2229 * @param keep Avoid garbage collection
2230 * @param chunk_size Amount of labels requested
2231 * @param base Base for the label chunk. if MPLS_LABEL_BASE_ANY we do not care
2232 * @result 0 on success, -1 otherwise
2233 */
2234int zclient_send_get_label_chunk(struct zclient *zclient, uint8_t keep,
2235 uint32_t chunk_size, uint32_t base)
2236{
2237 struct stream *s;
2238
2239 if (zclient_debug)
2240 zlog_debug("Getting Label Chunk");
2241
2242 if (zclient->sock < 0)
2243 return -1;
2244
2245 s = zclient->obuf;
2246 stream_reset(s);
2247
2248 zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, VRF_DEFAULT);
2249 /* proto */
2250 stream_putc(s, zclient->redist_default);
2251 /* instance */
2252 stream_putw(s, zclient->instance);
2253 stream_putc(s, keep);
2254 stream_putl(s, chunk_size);
2255 stream_putl(s, base);
2256
2257 /* Put length at the first point of the stream. */
2258 stream_putw_at(s, 0, stream_get_endp(s));
2259
2260 return zclient_send_message(zclient);
2261}
2262
2263/**
2264 * Function to request a label chunk in a syncronous way
2265 *
2266 * It first writes the request to zlcient output buffer and then
2267 * immediately reads the answer from the input buffer.
2268 *
2269 * @param zclient Zclient used to connect to label manager (zebra)
2270 * @param keep Avoid garbage collection
2271 * @param chunk_size Amount of labels requested
2272 * @param start To write first assigned chunk label to
2273 * @param end To write last assigned chunk label to
2274 * @result 0 on success, -1 otherwise
2275 */
2276int lm_get_label_chunk(struct zclient *zclient, uint8_t keep, uint32_t base,
2277 uint32_t chunk_size, uint32_t *start, uint32_t *end)
2278{
2279 int ret;
2280 struct stream *s;
2281 uint8_t response_keep;
2282
2283 if (zclient_debug)
2284 zlog_debug("Getting Label Chunk");
2285
2286 if (zclient->sock < 0)
2287 return -1;
2288
2289 /* send request */
2290 s = zclient->obuf;
2291 stream_reset(s);
2292 zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, VRF_DEFAULT);
2293 /* proto */
2294 stream_putc(s, zclient->redist_default);
2295 /* instance */
2296 stream_putw(s, zclient->instance);
2297 /* keep */
2298 stream_putc(s, keep);
2299 /* chunk size */
2300 stream_putl(s, chunk_size);
2301 /* requested chunk base */
2302 stream_putl(s, base);
2303 /* Put length at the first point of the stream. */
2304 stream_putw_at(s, 0, stream_get_endp(s));
2305
2306 ret = writen(zclient->sock, s->data, stream_get_endp(s));
2307 if (ret < 0) {
2308 flog_err(EC_LIB_ZAPI_SOCKET, "Can't write to zclient sock");
2309 close(zclient->sock);
2310 zclient->sock = -1;
2311 return -1;
2312 }
2313 if (ret == 0) {
2314 flog_err(EC_LIB_ZAPI_SOCKET, "Zclient sock closed");
2315 close(zclient->sock);
2316 zclient->sock = -1;
2317 return -1;
2318 }
2319 if (zclient_debug)
2320 zlog_debug("Label chunk request (%d bytes) sent", ret);
2321
2322 /* read response */
2323 if (zclient_read_sync_response(zclient, ZEBRA_GET_LABEL_CHUNK) != 0)
2324 return -1;
2325
2326 /* parse response */
2327 s = zclient->ibuf;
2328
2329 /* read proto and instance */
2330 uint8_t proto = stream_getc(s);
2331 uint16_t instance = stream_getw(s);
2332
2333 /* sanities */
2334 if (proto != zclient->redist_default)
2335 flog_err(EC_LIB_ZAPI_ENCODE,
2336 "Wrong proto (%u) in get chunk response. Should be %u",
2337 proto, zclient->redist_default);
2338 if (instance != zclient->instance)
2339 flog_err(EC_LIB_ZAPI_ENCODE,
2340 "Wrong instId (%u) in get chunk response Should be %u",
2341 instance, zclient->instance);
2342
2343 /* if we requested a specific chunk and it could not be allocated, the
2344 * response message will end here
2345 */
2346 if (!STREAM_READABLE(s)) {
2347 zlog_info("Unable to assign Label Chunk to %s instance %u",
2348 zebra_route_string(proto), instance);
2349 return -1;
2350 }
2351
2352 /* keep */
2353 response_keep = stream_getc(s);
2354 /* start and end labels */
2355 *start = stream_getl(s);
2356 *end = stream_getl(s);
2357
2358 /* not owning this response */
2359 if (keep != response_keep) {
2360 flog_err(
2361 EC_LIB_ZAPI_ENCODE,
2362 "Invalid Label chunk: %u - %u, keeps mismatch %u != %u",
2363 *start, *end, keep, response_keep);
2364 }
2365 /* sanity */
2366 if (*start > *end || *start < MPLS_LABEL_UNRESERVED_MIN
2367 || *end > MPLS_LABEL_UNRESERVED_MAX) {
2368 flog_err(EC_LIB_ZAPI_ENCODE, "Invalid Label chunk: %u - %u",
2369 *start, *end);
2370 return -1;
2371 }
2372
2373 if (zclient_debug)
2374 zlog_debug("Label Chunk assign: %u - %u (%u)", *start, *end,
2375 response_keep);
2376
2377 return 0;
2378}
2379
2380/**
2381 * Function to release a label chunk
2382 *
2383 * @param zclient Zclient used to connect to label manager (zebra)
2384 * @param start First label of chunk
2385 * @param end Last label of chunk
2386 * @result 0 on success, -1 otherwise
2387 */
2388int lm_release_label_chunk(struct zclient *zclient, uint32_t start,
2389 uint32_t end)
2390{
2391 int ret;
2392 struct stream *s;
2393
2394 if (zclient_debug)
2395 zlog_debug("Releasing Label Chunk %u - %u", start, end);
2396
2397 if (zclient->sock < 0)
2398 return -1;
2399
2400 /* send request */
2401 s = zclient->obuf;
2402 stream_reset(s);
2403 zclient_create_header(s, ZEBRA_RELEASE_LABEL_CHUNK, VRF_DEFAULT);
2404
2405 /* proto */
2406 stream_putc(s, zclient->redist_default);
2407 /* instance */
2408 stream_putw(s, zclient->instance);
2409 /* start */
2410 stream_putl(s, start);
2411 /* end */
2412 stream_putl(s, end);
2413
2414 /* Put length at the first point of the stream. */
2415 stream_putw_at(s, 0, stream_get_endp(s));
2416
2417 ret = writen(zclient->sock, s->data, stream_get_endp(s));
2418 if (ret < 0) {
2419 flog_err(EC_LIB_ZAPI_SOCKET, "Can't write to zclient sock");
2420 close(zclient->sock);
2421 zclient->sock = -1;
2422 return -1;
2423 }
2424 if (ret == 0) {
2425 flog_err(EC_LIB_ZAPI_SOCKET, "Zclient sock connection closed");
2426 close(zclient->sock);
2427 zclient->sock = -1;
2428 return -1;
2429 }
2430
2431 return 0;
2432}
2433
2434/**
2435 * Connect to table manager in a syncronous way
2436 *
2437 * It first writes the request to zcient output buffer and then
2438 * immediately reads the answer from the input buffer.
2439 *
2440 * @param zclient Zclient used to connect to table manager (zebra)
2441 * @result Result of response
2442 */
2443int tm_table_manager_connect(struct zclient *zclient)
2444{
2445 int ret;
2446 struct stream *s;
2447 uint8_t result;
2448
2449 if (zclient_debug)
2450 zlog_debug("Connecting to Table Manager");
2451
2452 if (zclient->sock < 0)
2453 return -1;
2454
2455 /* send request */
2456 s = zclient->obuf;
2457 stream_reset(s);
2458 zclient_create_header(s, ZEBRA_TABLE_MANAGER_CONNECT, VRF_DEFAULT);
2459
2460 /* proto */
2461 stream_putc(s, zclient->redist_default);
2462 /* instance */
2463 stream_putw(s, zclient->instance);
2464
2465 /* Put length at the first point of the stream. */
2466 stream_putw_at(s, 0, stream_get_endp(s));
2467
2468 ret = zclient_send_message(zclient);
2469 if (ret < 0)
2470 return -1;
2471
2472 if (zclient_debug)
2473 zlog_debug("%s: Table manager connect request sent", __func__);
2474
2475 /* read response */
2476 if (zclient_read_sync_response(zclient, ZEBRA_TABLE_MANAGER_CONNECT)
2477 != 0)
2478 return -1;
2479
2480 /* result */
2481 s = zclient->ibuf;
2482 STREAM_GETC(s, result);
2483 if (zclient_debug)
2484 zlog_debug(
2485 "%s: Table Manager connect response received, result %u",
2486 __func__, result);
2487
2488 return (int)result;
2489stream_failure:
2490 return -1;
2491}
2492
2493/**
2494 * Function to request a table chunk in a syncronous way
2495 *
2496 * It first writes the request to zclient output buffer and then
2497 * immediately reads the answer from the input buffer.
2498 *
2499 * @param zclient Zclient used to connect to table manager (zebra)
2500 * @param chunk_size Amount of table requested
2501 * @param start to write first assigned chunk table RT ID to
2502 * @param end To write last assigned chunk table RT ID to
2503 * @result 0 on success, -1 otherwise
2504 */
2505int tm_get_table_chunk(struct zclient *zclient, uint32_t chunk_size,
2506 uint32_t *start, uint32_t *end)
2507{
2508 int ret;
2509 struct stream *s;
2510
2511 if (zclient_debug)
2512 zlog_debug("Getting Table Chunk");
2513
2514 if (zclient->sock < 0)
2515 return -1;
2516
2517 /* send request */
2518 s = zclient->obuf;
2519 stream_reset(s);
2520 zclient_create_header(s, ZEBRA_GET_TABLE_CHUNK, VRF_DEFAULT);
2521 /* chunk size */
2522 stream_putl(s, chunk_size);
2523 /* Put length at the first point of the stream. */
2524 stream_putw_at(s, 0, stream_get_endp(s));
2525
2526 ret = writen(zclient->sock, s->data, stream_get_endp(s));
2527 if (ret < 0) {
2528 flog_err(EC_LIB_ZAPI_SOCKET, "%s: can't write to zclient->sock",
2529 __func__);
2530 close(zclient->sock);
2531 zclient->sock = -1;
2532 return -1;
2533 }
2534 if (ret == 0) {
2535 flog_err(EC_LIB_ZAPI_SOCKET,
2536 "%s: zclient->sock connection closed", __func__);
2537 close(zclient->sock);
2538 zclient->sock = -1;
2539 return -1;
2540 }
2541 if (zclient_debug)
2542 zlog_debug("%s: Table chunk request (%d bytes) sent", __func__,
2543 ret);
2544
2545 /* read response */
2546 if (zclient_read_sync_response(zclient, ZEBRA_GET_TABLE_CHUNK) != 0)
2547 return -1;
2548
2549 s = zclient->ibuf;
2550 /* start and end table IDs */
2551 STREAM_GETL(s, *start);
2552 STREAM_GETL(s, *end);
2553
2554 if (zclient_debug)
2555 zlog_debug("Table Chunk assign: %u - %u ", *start, *end);
2556
2557 return 0;
2558stream_failure:
2559 return -1;
2560}
2561
2562/**
2563 * Function to release a table chunk
2564 *
2565 * @param zclient Zclient used to connect to table manager (zebra)
2566 * @param start First label of table
2567 * @param end Last label of chunk
2568 * @result 0 on success, -1 otherwise
2569 */
2570int tm_release_table_chunk(struct zclient *zclient, uint32_t start,
2571 uint32_t end)
2572{
2573 struct stream *s;
2574
2575 if (zclient_debug)
2576 zlog_debug("Releasing Table Chunk");
2577
2578 if (zclient->sock < 0)
2579 return -1;
2580
2581 /* send request */
2582 s = zclient->obuf;
2583 stream_reset(s);
2584 zclient_create_header(s, ZEBRA_RELEASE_TABLE_CHUNK, VRF_DEFAULT);
2585
2586 /* start */
2587 stream_putl(s, start);
2588 /* end */
2589 stream_putl(s, end);
2590
2591 /* Put length at the first point of the stream. */
2592 stream_putw_at(s, 0, stream_get_endp(s));
2593
2594 return zclient_send_message(zclient);
2595}
2596
2597int zebra_send_mpls_labels(struct zclient *zclient, int cmd,
2598 struct zapi_labels *zl)
2599{
2600 if (zapi_labels_encode(zclient->obuf, cmd, zl) < 0)
2601 return -1;
2602 return zclient_send_message(zclient);
2603}
2604
2605int zapi_labels_encode(struct stream *s, int cmd, struct zapi_labels *zl)
2606{
2607 struct zapi_nexthop_label *znh;
2608
2609 stream_reset(s);
2610
2611 zclient_create_header(s, cmd, VRF_DEFAULT);
2612 stream_putc(s, zl->message);
2613 stream_putc(s, zl->type);
2614 stream_putl(s, zl->local_label);
2615
2616 if (CHECK_FLAG(zl->message, ZAPI_LABELS_FTN)) {
2617 stream_putw(s, zl->route.prefix.family);
2618 stream_put_prefix(s, &zl->route.prefix);
2619 stream_putc(s, zl->route.type);
2620 stream_putw(s, zl->route.instance);
2621 }
2622
2623 if (zl->nexthop_num > MULTIPATH_NUM) {
2624 flog_err(
2625 EC_LIB_ZAPI_ENCODE,
2626 "%s: label %u: can't encode %u nexthops (maximum is %u)",
2627 __func__, zl->local_label, zl->nexthop_num,
2628 MULTIPATH_NUM);
2629 return -1;
2630 }
2631 stream_putw(s, zl->nexthop_num);
2632
2633 for (int i = 0; i < zl->nexthop_num; i++) {
2634 znh = &zl->nexthops[i];
2635
2636 stream_putc(s, znh->type);
2637 stream_putw(s, znh->family);
2638 switch (znh->family) {
2639 case AF_INET:
2640 stream_put_in_addr(s, &znh->address.ipv4);
2641 break;
2642 case AF_INET6:
2643 stream_write(s, (uint8_t *)&znh->address.ipv6, 16);
2644 break;
2645 default:
2646 break;
2647 }
2648 stream_putl(s, znh->ifindex);
2649 stream_putl(s, znh->label);
2650 }
2651
2652 /* Put length at the first point of the stream. */
2653 stream_putw_at(s, 0, stream_get_endp(s));
2654
2655 return 0;
2656}
2657
2658int zapi_labels_decode(struct stream *s, struct zapi_labels *zl)
2659{
2660 struct zapi_nexthop_label *znh;
2661
2662 memset(zl, 0, sizeof(*zl));
2663
2664 /* Get data. */
2665 STREAM_GETC(s, zl->message);
2666 STREAM_GETC(s, zl->type);
2667 STREAM_GETL(s, zl->local_label);
2668
2669 if (CHECK_FLAG(zl->message, ZAPI_LABELS_FTN)) {
2670 size_t psize;
2671
2672 STREAM_GETW(s, zl->route.prefix.family);
2673 STREAM_GETC(s, zl->route.prefix.prefixlen);
2674
2675 psize = PSIZE(zl->route.prefix.prefixlen);
2676 switch (zl->route.prefix.family) {
2677 case AF_INET:
2678 if (zl->route.prefix.prefixlen > IPV4_MAX_BITLEN) {
2679 zlog_debug(
2680 "%s: Specified prefix length %d is greater than a v4 address can support",
2681 __PRETTY_FUNCTION__,
2682 zl->route.prefix.prefixlen);
2683 return -1;
2684 }
2685 STREAM_GET(&zl->route.prefix.u.prefix4.s_addr, s,
2686 psize);
2687 break;
2688 case AF_INET6:
2689 if (zl->route.prefix.prefixlen > IPV6_MAX_BITLEN) {
2690 zlog_debug(
2691 "%s: Specified prefix length %d is greater than a v6 address can support",
2692 __PRETTY_FUNCTION__,
2693 zl->route.prefix.prefixlen);
2694 return -1;
2695 }
2696 STREAM_GET(&zl->route.prefix.u.prefix6, s, psize);
2697 break;
2698 default:
2699 flog_err(EC_LIB_ZAPI_ENCODE,
2700 "%s: Specified family %u is not v4 or v6",
2701 __PRETTY_FUNCTION__, zl->route.prefix.family);
2702 return -1;
2703 }
2704
2705 STREAM_GETC(s, zl->route.type);
2706 STREAM_GETW(s, zl->route.instance);
2707 }
2708
2709 STREAM_GETW(s, zl->nexthop_num);
2710
2711 if (zl->nexthop_num > MULTIPATH_NUM) {
2712 flog_warn(
2713 EC_LIB_ZAPI_ENCODE,
2714 "%s: Prefix %pFX has %d nexthops, but we can only use the first %d",
2715 __func__, &zl->route.prefix, zl->nexthop_num,
2716 MULTIPATH_NUM);
2717 }
2718
2719 zl->nexthop_num = MIN(MULTIPATH_NUM, zl->nexthop_num);
2720
2721 for (int i = 0; i < zl->nexthop_num; i++) {
2722 znh = &zl->nexthops[i];
2723
2724 STREAM_GETC(s, znh->type);
2725 STREAM_GETW(s, znh->family);
2726 switch (znh->family) {
2727 case AF_INET:
2728 STREAM_GET(&znh->address.ipv4.s_addr, s,
2729 IPV4_MAX_BYTELEN);
2730 break;
2731 case AF_INET6:
2732 STREAM_GET(&znh->address.ipv6, s, 16);
2733 break;
2734 default:
2735 break;
2736 }
2737 STREAM_GETL(s, znh->ifindex);
2738 STREAM_GETL(s, znh->label);
2739 }
2740
2741 return 0;
2742stream_failure:
2743 return -1;
2744}
2745
2746int zebra_send_pw(struct zclient *zclient, int command, struct zapi_pw *pw)
2747{
2748 struct stream *s;
2749
2750 /* Reset stream. */
2751 s = zclient->obuf;
2752 stream_reset(s);
2753
2754 zclient_create_header(s, command, VRF_DEFAULT);
2755 stream_write(s, pw->ifname, IF_NAMESIZE);
2756 stream_putl(s, pw->ifindex);
2757
2758 /* Put type */
2759 stream_putl(s, pw->type);
2760
2761 /* Put nexthop */
2762 stream_putl(s, pw->af);
2763 switch (pw->af) {
2764 case AF_INET:
2765 stream_put_in_addr(s, &pw->nexthop.ipv4);
2766 break;
2767 case AF_INET6:
2768 stream_write(s, (uint8_t *)&pw->nexthop.ipv6, 16);
2769 break;
2770 default:
2771 flog_err(EC_LIB_ZAPI_ENCODE, "%s: unknown af", __func__);
2772 return -1;
2773 }
2774
2775 /* Put labels */
2776 stream_putl(s, pw->local_label);
2777 stream_putl(s, pw->remote_label);
2778
2779 /* Put flags */
2780 stream_putc(s, pw->flags);
2781
2782 /* Protocol specific fields */
2783 stream_write(s, &pw->data, sizeof(union pw_protocol_fields));
2784
2785 /* Put length at the first point of the stream. */
2786 stream_putw_at(s, 0, stream_get_endp(s));
2787
2788 return zclient_send_message(zclient);
2789}
2790
2791/*
2792 * Receive PW status update from Zebra and send it to LDE process.
2793 */
2794void zebra_read_pw_status_update(ZAPI_CALLBACK_ARGS, struct zapi_pw_status *pw)
2795{
2796 struct stream *s;
2797
2798 memset(pw, 0, sizeof(struct zapi_pw_status));
2799 s = zclient->ibuf;
2800
2801 /* Get data. */
2802 stream_get(pw->ifname, s, IF_NAMESIZE);
2803 pw->ifindex = stream_getl(s);
2804 pw->status = stream_getl(s);
2805}
2806
2807static void zclient_capability_decode(ZAPI_CALLBACK_ARGS)
2808{
2809 struct zclient_capabilities cap;
2810 struct stream *s = zclient->ibuf;
2811 int vrf_backend;
2812 uint8_t mpls_enabled;
2813
2814 STREAM_GETL(s, vrf_backend);
2815 vrf_configure_backend(vrf_backend);
2816
2817 memset(&cap, 0, sizeof(cap));
2818 STREAM_GETC(s, mpls_enabled);
2819 cap.mpls_enabled = !!mpls_enabled;
2820 STREAM_GETL(s, cap.ecmp);
2821 STREAM_GETC(s, cap.role);
2822
2823 if (zclient->zebra_capabilities)
2824 (*zclient->zebra_capabilities)(&cap);
2825
2826stream_failure:
2827 return;
2828}
2829
2830void zclient_send_mlag_register(struct zclient *client, uint32_t bit_map)
2831{
2832 struct stream *s;
2833
2834 s = client->obuf;
2835 stream_reset(s);
2836
2837 zclient_create_header(s, ZEBRA_MLAG_CLIENT_REGISTER, VRF_DEFAULT);
2838 stream_putl(s, bit_map);
2839
2840 stream_putw_at(s, 0, stream_get_endp(s));
2841 zclient_send_message(client);
2842}
2843
2844void zclient_send_mlag_deregister(struct zclient *client)
2845{
2846 zebra_message_send(client, ZEBRA_MLAG_CLIENT_UNREGISTER, VRF_DEFAULT);
2847}
2848
2849void zclient_send_mlag_data(struct zclient *client, struct stream *client_s)
2850{
2851 struct stream *s;
2852
2853 s = client->obuf;
2854 stream_reset(s);
2855
2856 zclient_create_header(s, ZEBRA_MLAG_FORWARD_MSG, VRF_DEFAULT);
2857 stream_put(s, client_s->data, client_s->endp);
2858
2859 stream_putw_at(s, 0, stream_get_endp(s));
2860 zclient_send_message(client);
2861}
2862
2863static void zclient_mlag_process_up(ZAPI_CALLBACK_ARGS)
2864{
2865 if (zclient->mlag_process_up)
2866 (*zclient->mlag_process_up)();
2867}
2868
2869static void zclient_mlag_process_down(ZAPI_CALLBACK_ARGS)
2870{
2871 if (zclient->mlag_process_down)
2872 (*zclient->mlag_process_down)();
2873}
2874
2875static void zclient_mlag_handle_msg(ZAPI_CALLBACK_ARGS)
2876{
2877 if (zclient->mlag_handle_msg)
2878 (*zclient->mlag_handle_msg)(zclient->ibuf, length);
2879}
2880
2881/* Zebra client message read function. */
2882static int zclient_read(struct thread *thread)
2883{
2884 size_t already;
2885 uint16_t length, command;
2886 uint8_t marker, version;
2887 vrf_id_t vrf_id;
2888 struct zclient *zclient;
2889
2890 /* Get socket to zebra. */
2891 zclient = THREAD_ARG(thread);
2892 zclient->t_read = NULL;
2893
2894 /* Read zebra header (if we don't have it already). */
2895 if ((already = stream_get_endp(zclient->ibuf)) < ZEBRA_HEADER_SIZE) {
2896 ssize_t nbyte;
2897 if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
2898 ZEBRA_HEADER_SIZE - already))
2899 == 0)
2900 || (nbyte == -1)) {
2901 if (zclient_debug)
2902 zlog_debug(
2903 "zclient connection closed socket [%d].",
2904 zclient->sock);
2905 return zclient_failed(zclient);
2906 }
2907 if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE - already)) {
2908 /* Try again later. */
2909 zclient_event(ZCLIENT_READ, zclient);
2910 return 0;
2911 }
2912 already = ZEBRA_HEADER_SIZE;
2913 }
2914
2915 /* Reset to read from the beginning of the incoming packet. */
2916 stream_set_getp(zclient->ibuf, 0);
2917
2918 /* Fetch header values. */
2919 length = stream_getw(zclient->ibuf);
2920 marker = stream_getc(zclient->ibuf);
2921 version = stream_getc(zclient->ibuf);
2922 vrf_id = stream_getl(zclient->ibuf);
2923 command = stream_getw(zclient->ibuf);
2924
2925 if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) {
2926 flog_err(
2927 EC_LIB_ZAPI_MISSMATCH,
2928 "%s: socket %d version mismatch, marker %d, version %d",
2929 __func__, zclient->sock, marker, version);
2930 return zclient_failed(zclient);
2931 }
2932
2933 if (length < ZEBRA_HEADER_SIZE) {
2934 flog_err(EC_LIB_ZAPI_MISSMATCH,
2935 "%s: socket %d message length %u is less than %d ",
2936 __func__, zclient->sock, length, ZEBRA_HEADER_SIZE);
2937 return zclient_failed(zclient);
2938 }
2939
2940 /* Length check. */
2941 if (length > STREAM_SIZE(zclient->ibuf)) {
2942 struct stream *ns;
2943 flog_err(
2944 EC_LIB_ZAPI_ENCODE,
2945 "%s: message size %u exceeds buffer size %lu, expanding...",
2946 __func__, length,
2947 (unsigned long)STREAM_SIZE(zclient->ibuf));
2948 ns = stream_new(length);
2949 stream_copy(ns, zclient->ibuf);
2950 stream_free(zclient->ibuf);
2951 zclient->ibuf = ns;
2952 }
2953
2954 /* Read rest of zebra packet. */
2955 if (already < length) {
2956 ssize_t nbyte;
2957 if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
2958 length - already))
2959 == 0)
2960 || (nbyte == -1)) {
2961 if (zclient_debug)
2962 zlog_debug(
2963 "zclient connection closed socket [%d].",
2964 zclient->sock);
2965 return zclient_failed(zclient);
2966 }
2967 if (nbyte != (ssize_t)(length - already)) {
2968 /* Try again later. */
2969 zclient_event(ZCLIENT_READ, zclient);
2970 return 0;
2971 }
2972 }
2973
2974 length -= ZEBRA_HEADER_SIZE;
2975
2976 if (zclient_debug)
2977 zlog_debug("zclient 0x%p command %s VRF %u",
2978 (void *)zclient, zserv_command_string(command),
2979 vrf_id);
2980
2981 switch (command) {
2982 case ZEBRA_CAPABILITIES:
2983 zclient_capability_decode(command, zclient, length, vrf_id);
2984 break;
2985 case ZEBRA_ROUTER_ID_UPDATE:
2986 if (zclient->router_id_update)
2987 (*zclient->router_id_update)(command, zclient, length,
2988 vrf_id);
2989 break;
2990 case ZEBRA_VRF_ADD:
2991 zclient_vrf_add(zclient, vrf_id);
2992 break;
2993 case ZEBRA_VRF_DELETE:
2994 zclient_vrf_delete(zclient, vrf_id);
2995 break;
2996 case ZEBRA_INTERFACE_ADD:
2997 zclient_interface_add(zclient, vrf_id);
2998 break;
2999 case ZEBRA_INTERFACE_DELETE:
3000 zclient_interface_delete(zclient, vrf_id);
3001 break;
3002 case ZEBRA_INTERFACE_ADDRESS_ADD:
3003 if (zclient->interface_address_add)
3004 (*zclient->interface_address_add)(command, zclient,
3005 length, vrf_id);
3006 break;
3007 case ZEBRA_INTERFACE_ADDRESS_DELETE:
3008 if (zclient->interface_address_delete)
3009 (*zclient->interface_address_delete)(command, zclient,
3010 length, vrf_id);
3011 break;
3012 case ZEBRA_INTERFACE_BFD_DEST_UPDATE:
3013 if (zclient->interface_bfd_dest_update)
3014 (*zclient->interface_bfd_dest_update)(command, zclient,
3015 length, vrf_id);
3016 break;
3017 case ZEBRA_INTERFACE_NBR_ADDRESS_ADD:
3018 if (zclient->interface_nbr_address_add)
3019 (*zclient->interface_nbr_address_add)(command, zclient,
3020 length, vrf_id);
3021 break;
3022 case ZEBRA_INTERFACE_NBR_ADDRESS_DELETE:
3023 if (zclient->interface_nbr_address_delete)
3024 (*zclient->interface_nbr_address_delete)(
3025 command, zclient, length, vrf_id);
3026 break;
3027 case ZEBRA_INTERFACE_UP:
3028 zclient_interface_up(zclient, vrf_id);
3029 break;
3030 case ZEBRA_INTERFACE_DOWN:
3031 zclient_interface_down(zclient, vrf_id);
3032 break;
3033 case ZEBRA_INTERFACE_VRF_UPDATE:
3034 if (zclient->interface_vrf_update)
3035 (*zclient->interface_vrf_update)(command, zclient,
3036 length, vrf_id);
3037 break;
3038 case ZEBRA_NEXTHOP_UPDATE:
3039 if (zclient_debug)
3040 zlog_debug("zclient rcvd nexthop update");
3041 if (zclient->nexthop_update)
3042 (*zclient->nexthop_update)(command, zclient, length,
3043 vrf_id);
3044 break;
3045 case ZEBRA_IMPORT_CHECK_UPDATE:
3046 if (zclient_debug)
3047 zlog_debug("zclient rcvd import check update");
3048 if (zclient->import_check_update)
3049 (*zclient->import_check_update)(command, zclient,
3050 length, vrf_id);
3051 break;
3052 case ZEBRA_BFD_DEST_REPLAY:
3053 if (zclient->bfd_dest_replay)
3054 (*zclient->bfd_dest_replay)(command, zclient, length,
3055 vrf_id);
3056 break;
3057 case ZEBRA_REDISTRIBUTE_ROUTE_ADD:
3058 if (zclient->redistribute_route_add)
3059 (*zclient->redistribute_route_add)(command, zclient,
3060 length, vrf_id);
3061 break;
3062 case ZEBRA_REDISTRIBUTE_ROUTE_DEL:
3063 if (zclient->redistribute_route_del)
3064 (*zclient->redistribute_route_del)(command, zclient,
3065 length, vrf_id);
3066 break;
3067 case ZEBRA_INTERFACE_LINK_PARAMS:
3068 if (zclient->interface_link_params)
3069 (*zclient->interface_link_params)(command, zclient,
3070 length, vrf_id);
3071 break;
3072 case ZEBRA_FEC_UPDATE:
3073 if (zclient_debug)
3074 zlog_debug("zclient rcvd fec update");
3075 if (zclient->fec_update)
3076 (*zclient->fec_update)(command, zclient, length);
3077 break;
3078 case ZEBRA_LOCAL_ES_ADD:
3079 if (zclient->local_es_add)
3080 (*zclient->local_es_add)(command, zclient, length,
3081 vrf_id);
3082 break;
3083 case ZEBRA_LOCAL_ES_DEL:
3084 if (zclient->local_es_del)
3085 (*zclient->local_es_del)(command, zclient, length,
3086 vrf_id);
3087 break;
3088 case ZEBRA_VNI_ADD:
3089 if (zclient->local_vni_add)
3090 (*zclient->local_vni_add)(command, zclient, length,
3091 vrf_id);
3092 break;
3093 case ZEBRA_VNI_DEL:
3094 if (zclient->local_vni_del)
3095 (*zclient->local_vni_del)(command, zclient, length,
3096 vrf_id);
3097 break;
3098 case ZEBRA_L3VNI_ADD:
3099 if (zclient->local_l3vni_add)
3100 (*zclient->local_l3vni_add)(command, zclient, length,
3101 vrf_id);
3102 break;
3103 case ZEBRA_L3VNI_DEL:
3104 if (zclient->local_l3vni_del)
3105 (*zclient->local_l3vni_del)(command, zclient, length,
3106 vrf_id);
3107 break;
3108 case ZEBRA_MACIP_ADD:
3109 if (zclient->local_macip_add)
3110 (*zclient->local_macip_add)(command, zclient, length,
3111 vrf_id);
3112 break;
3113 case ZEBRA_MACIP_DEL:
3114 if (zclient->local_macip_del)
3115 (*zclient->local_macip_del)(command, zclient, length,
3116 vrf_id);
3117 break;
3118 case ZEBRA_IP_PREFIX_ROUTE_ADD:
3119 if (zclient->local_ip_prefix_add)
3120 (*zclient->local_ip_prefix_add)(command, zclient,
3121 length, vrf_id);
3122 break;
3123 case ZEBRA_IP_PREFIX_ROUTE_DEL:
3124 if (zclient->local_ip_prefix_del)
3125 (*zclient->local_ip_prefix_del)(command, zclient,
3126 length, vrf_id);
3127 break;
3128 case ZEBRA_PW_STATUS_UPDATE:
3129 if (zclient->pw_status_update)
3130 (*zclient->pw_status_update)(command, zclient, length,
3131 vrf_id);
3132 break;
3133 case ZEBRA_ROUTE_NOTIFY_OWNER:
3134 if (zclient->route_notify_owner)
3135 (*zclient->route_notify_owner)(command, zclient, length,
3136 vrf_id);
3137 break;
3138 case ZEBRA_RULE_NOTIFY_OWNER:
3139 if (zclient->rule_notify_owner)
3140 (*zclient->rule_notify_owner)(command, zclient, length,
3141 vrf_id);
3142 break;
3143 case ZEBRA_GET_LABEL_CHUNK:
3144 if (zclient->label_chunk)
3145 (*zclient->label_chunk)(command, zclient, length,
3146 vrf_id);
3147 break;
3148 case ZEBRA_IPSET_NOTIFY_OWNER:
3149 if (zclient->ipset_notify_owner)
3150 (*zclient->ipset_notify_owner)(command, zclient, length,
3151 vrf_id);
3152 break;
3153 case ZEBRA_IPSET_ENTRY_NOTIFY_OWNER:
3154 if (zclient->ipset_entry_notify_owner)
3155 (*zclient->ipset_entry_notify_owner)(command,
3156 zclient, length,
3157 vrf_id);
3158 break;
3159 case ZEBRA_IPTABLE_NOTIFY_OWNER:
3160 if (zclient->iptable_notify_owner)
3161 (*zclient->iptable_notify_owner)(command,
3162 zclient, length,
3163 vrf_id);
3164 break;
3165 case ZEBRA_VXLAN_SG_ADD:
3166 if (zclient->vxlan_sg_add)
3167 (*zclient->vxlan_sg_add)(command, zclient, length,
3168 vrf_id);
3169 break;
3170 case ZEBRA_VXLAN_SG_DEL:
3171 if (zclient->vxlan_sg_del)
3172 (*zclient->vxlan_sg_del)(command, zclient, length,
3173 vrf_id);
3174 break;
3175 case ZEBRA_MLAG_PROCESS_UP:
3176 zclient_mlag_process_up(command, zclient, length, vrf_id);
3177 break;
3178 case ZEBRA_MLAG_PROCESS_DOWN:
3179 zclient_mlag_process_down(command, zclient, length, vrf_id);
3180 break;
3181 case ZEBRA_MLAG_FORWARD_MSG:
3182 zclient_mlag_handle_msg(command, zclient, length, vrf_id);
3183 break;
3184 case ZEBRA_ERROR:
3185 zclient_handle_error(command, zclient, length, vrf_id);
3186 default:
3187 break;
3188 }
3189
3190 if (zclient->sock < 0)
3191 /* Connection was closed during packet processing. */
3192 return -1;
3193
3194 /* Register read thread. */
3195 stream_reset(zclient->ibuf);
3196 zclient_event(ZCLIENT_READ, zclient);
3197
3198 return 0;
3199}
3200
3201void zclient_redistribute(int command, struct zclient *zclient, afi_t afi,
3202 int type, unsigned short instance, vrf_id_t vrf_id)
3203{
3204
3205 if (instance) {
3206 if (command == ZEBRA_REDISTRIBUTE_ADD) {
3207 if (redist_check_instance(
3208 &zclient->mi_redist[afi][type], instance))
3209 return;
3210 redist_add_instance(&zclient->mi_redist[afi][type],
3211 instance);
3212 } else {
3213 if (!redist_check_instance(
3214 &zclient->mi_redist[afi][type], instance))
3215 return;
3216 redist_del_instance(&zclient->mi_redist[afi][type],
3217 instance);
3218 }
3219
3220 } else {
3221 if (command == ZEBRA_REDISTRIBUTE_ADD) {
3222 if (vrf_bitmap_check(zclient->redist[afi][type],
3223 vrf_id))
3224 return;
3225 vrf_bitmap_set(zclient->redist[afi][type], vrf_id);
3226 } else {
3227 if (!vrf_bitmap_check(zclient->redist[afi][type],
3228 vrf_id))
3229 return;
3230 vrf_bitmap_unset(zclient->redist[afi][type], vrf_id);
3231 }
3232 }
3233
3234 if (zclient->sock > 0)
3235 zebra_redistribute_send(command, zclient, afi, type, instance,
3236 vrf_id);
3237}
3238
3239
3240void zclient_redistribute_default(int command, struct zclient *zclient,
3241 afi_t afi, vrf_id_t vrf_id)
3242{
3243
3244 if (command == ZEBRA_REDISTRIBUTE_DEFAULT_ADD) {
3245 if (vrf_bitmap_check(zclient->default_information[afi], vrf_id))
3246 return;
3247 vrf_bitmap_set(zclient->default_information[afi], vrf_id);
3248 } else {
3249 if (!vrf_bitmap_check(zclient->default_information[afi],
3250 vrf_id))
3251 return;
3252 vrf_bitmap_unset(zclient->default_information[afi], vrf_id);
3253 }
3254
3255 if (zclient->sock > 0)
3256 zebra_redistribute_default_send(command, zclient, afi, vrf_id);
3257}
3258
3259static void zclient_event(enum event event, struct zclient *zclient)
3260{
3261 switch (event) {
3262 case ZCLIENT_SCHEDULE:
3263 thread_add_event(zclient->master, zclient_connect, zclient, 0,
3264 &zclient->t_connect);
3265 break;
3266 case ZCLIENT_CONNECT:
3267 if (zclient_debug)
3268 zlog_debug(
3269 "zclient connect failures: %d schedule interval is now %d",
3270 zclient->fail, zclient->fail < 3 ? 10 : 60);
3271 thread_add_timer(zclient->master, zclient_connect, zclient,
3272 zclient->fail < 3 ? 10 : 60,
3273 &zclient->t_connect);
3274 break;
3275 case ZCLIENT_READ:
3276 zclient->t_read = NULL;
3277 thread_add_read(zclient->master, zclient_read, zclient,
3278 zclient->sock, &zclient->t_read);
3279 break;
3280 }
3281}
3282
3283void zclient_interface_set_master(struct zclient *client,
3284 struct interface *master,
3285 struct interface *slave)
3286{
3287 struct stream *s;
3288
3289 s = client->obuf;
3290 stream_reset(s);
3291
3292 zclient_create_header(s, ZEBRA_INTERFACE_SET_MASTER, master->vrf_id);
3293
3294 stream_putl(s, master->vrf_id);
3295 stream_putl(s, master->ifindex);
3296 stream_putl(s, slave->vrf_id);
3297 stream_putl(s, slave->ifindex);
3298
3299 stream_putw_at(s, 0, stream_get_endp(s));
3300 zclient_send_message(client);
3301}
3302
3303/*
3304 * Send capabilities message to zebra
3305 */
3306int32_t zclient_capabilities_send(uint32_t cmd, struct zclient *zclient,
3307 struct zapi_cap *api)
3308{
3309
3310 struct stream *s;
3311
3312 if (zclient == NULL)
3313 return -1;
3314
3315 s = zclient->obuf;
3316 stream_reset(s);
3317 zclient_create_header(s, cmd, 0);
3318 stream_putl(s, api->cap);
3319
3320 switch (api->cap) {
3321 case ZEBRA_CLIENT_GR_CAPABILITIES:
3322 case ZEBRA_CLIENT_RIB_STALE_TIME:
3323 stream_putl(s, api->stale_removal_time);
3324 stream_putl(s, api->vrf_id);
3325 break;
3326 case ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE:
3327 case ZEBRA_CLIENT_ROUTE_UPDATE_PENDING:
3328 stream_putl(s, api->afi);
3329 stream_putl(s, api->safi);
3330 stream_putl(s, api->vrf_id);
3331 break;
3332 case ZEBRA_CLIENT_GR_DISABLE:
3333 stream_putl(s, api->vrf_id);
3334 break;
3335 }
3336
3337 /* Put length at the first point of the stream */
3338 stream_putw_at(s, 0, stream_get_endp(s));
3339
3340 return zclient_send_message(zclient);
3341}
3342
3343/*
3344 * Process capabilities message from zebra
3345 */
3346int32_t zapi_capabilities_decode(struct stream *s, struct zapi_cap *api)
3347{
3348
3349 memset(api, 0, sizeof(*api));
3350
3351 STREAM_GETL(s, api->cap);
3352 switch (api->cap) {
3353 case ZEBRA_CLIENT_GR_CAPABILITIES:
3354 case ZEBRA_CLIENT_RIB_STALE_TIME:
3355 STREAM_GETL(s, api->stale_removal_time);
3356 STREAM_GETL(s, api->vrf_id);
3357 break;
3358 case ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE:
3359 case ZEBRA_CLIENT_ROUTE_UPDATE_PENDING:
3360 STREAM_GETL(s, api->afi);
3361 STREAM_GETL(s, api->safi);
3362 STREAM_GETL(s, api->vrf_id);
3363 break;
3364 case ZEBRA_CLIENT_GR_DISABLE:
3365 STREAM_GETL(s, api->vrf_id);
3366 break;
3367 }
3368stream_failure:
3369 return 0;
3370}