]> git.proxmox.com Git - mirror_frr.git/blame - lib/zclient.c
Merge pull request #1554 from opensourcerouting/cover-fix1
[mirror_frr.git] / lib / zclient.c
CommitLineData
718e3744 1/* Zebra's client library.
2 * Copyright (C) 1999 Kunihiro Ishiguro
634f9ea2 3 * Copyright (C) 2005 Andrew J. Schorr
718e3744 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 *
896014f4
DL
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
718e3744 20 */
21
22#include <zebra.h>
23
24#include "prefix.h"
25#include "stream.h"
634f9ea2 26#include "buffer.h"
718e3744 27#include "network.h"
7922fc65
DS
28#include "vrf.h"
29#include "vrf_int.h"
718e3744 30#include "if.h"
31#include "log.h"
32#include "thread.h"
33#include "zclient.h"
34#include "memory.h"
35#include "table.h"
5b30316e 36#include "nexthop.h"
fea12efb 37#include "mpls.h"
342213ea 38#include "sockopt.h"
6b0655a2 39
4a1ab8e4 40DEFINE_MTYPE_STATIC(LIB, ZCLIENT, "Zclient")
14878121 41DEFINE_MTYPE_STATIC(LIB, REDIST_INST, "Redistribution instance IDs")
4a1ab8e4 42
718e3744 43/* Zebra client events. */
d62a17ae 44enum event { ZCLIENT_SCHEDULE, ZCLIENT_READ, ZCLIENT_CONNECT };
718e3744 45
46/* Prototype for event manager. */
d62a17ae 47static void zclient_event(enum event, struct zclient *);
718e3744 48
689f5a8c
DL
49struct sockaddr_storage zclient_addr;
50socklen_t zclient_addr_len;
b5114685 51
718e3744 52/* This file local debug flag. */
53int zclient_debug = 0;
6b0655a2 54
e1a1880d
DS
55struct zclient_options zclient_options_default = { .receive_notify = false };
56
718e3744 57/* Allocate zclient structure. */
e1a1880d
DS
58struct zclient *zclient_new_notify(struct thread_master *master,
59 struct zclient_options *opt)
718e3744 60{
d62a17ae 61 struct zclient *zclient;
62 zclient = XCALLOC(MTYPE_ZCLIENT, sizeof(struct zclient));
718e3744 63
d62a17ae 64 zclient->ibuf = stream_new(ZEBRA_MAX_PACKET_SIZ);
65 zclient->obuf = stream_new(ZEBRA_MAX_PACKET_SIZ);
66 zclient->wb = buffer_new(0);
67 zclient->master = master;
718e3744 68
e1a1880d
DS
69 zclient->receive_notify = opt->receive_notify;
70
d62a17ae 71 return zclient;
718e3744 72}
73
228da428 74/* This function is only called when exiting, because
634f9ea2 75 many parts of the code do not check for I/O errors, so they could
76 reference an invalid pointer if the structure was ever freed.
634f9ea2 77
228da428 78 Free zclient structure. */
d62a17ae 79void zclient_free(struct zclient *zclient)
718e3744 80{
d62a17ae 81 if (zclient->ibuf)
82 stream_free(zclient->ibuf);
83 if (zclient->obuf)
84 stream_free(zclient->obuf);
85 if (zclient->wb)
86 buffer_free(zclient->wb);
87
88 XFREE(MTYPE_ZCLIENT, zclient);
718e3744 89}
90
d62a17ae 91u_short *redist_check_instance(struct redist_proto *red, u_short instance)
7c8ff89e 92{
d62a17ae 93 struct listnode *node;
94 u_short *id;
7c8ff89e 95
d62a17ae 96 if (!red->instances)
97 return NULL;
7c8ff89e 98
d62a17ae 99 for (ALL_LIST_ELEMENTS_RO(red->instances, node, id))
100 if (*id == instance)
101 return id;
7c8ff89e 102
d62a17ae 103 return NULL;
7c8ff89e
DS
104}
105
d62a17ae 106void redist_add_instance(struct redist_proto *red, u_short instance)
7c8ff89e 107{
d62a17ae 108 u_short *in;
7c8ff89e 109
d62a17ae 110 red->enabled = 1;
7c8ff89e 111
d62a17ae 112 if (!red->instances)
113 red->instances = list_new();
7c8ff89e 114
d62a17ae 115 in = XMALLOC(MTYPE_REDIST_INST, sizeof(u_short));
116 *in = instance;
117 listnode_add(red->instances, in);
7c8ff89e
DS
118}
119
d62a17ae 120void redist_del_instance(struct redist_proto *red, u_short instance)
7c8ff89e 121{
d62a17ae 122 u_short *id;
123
124 id = redist_check_instance(red, instance);
125 if (!id)
126 return;
127
128 listnode_delete(red->instances, id);
129 XFREE(MTYPE_REDIST_INST, id);
130 if (!red->instances->count) {
131 red->enabled = 0;
acdf5e25 132 list_delete_and_null(&red->instances);
d62a17ae 133 }
7c8ff89e
DS
134}
135
718e3744 136/* Stop zebra client services. */
d62a17ae 137void zclient_stop(struct zclient *zclient)
718e3744 138{
d62a17ae 139 afi_t afi;
140 int i;
141
142 if (zclient_debug)
143 zlog_debug("zclient stopped");
144
145 /* Stop threads. */
146 THREAD_OFF(zclient->t_read);
147 THREAD_OFF(zclient->t_connect);
148 THREAD_OFF(zclient->t_write);
149
150 /* Reset streams. */
151 stream_reset(zclient->ibuf);
152 stream_reset(zclient->obuf);
153
154 /* Empty the write buffer. */
155 buffer_reset(zclient->wb);
156
157 /* Close socket. */
158 if (zclient->sock >= 0) {
159 close(zclient->sock);
160 zclient->sock = -1;
161 }
162 zclient->fail = 0;
163
164 for (afi = AFI_IP; afi < AFI_MAX; afi++) {
165 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
166 vrf_bitmap_free(zclient->redist[afi][i]);
167 zclient->redist[afi][i] = VRF_BITMAP_NULL;
168 }
169 redist_del_instance(
170 &zclient->mi_redist[afi][zclient->redist_default],
171 zclient->instance);
41246cb6 172 }
41246cb6 173
d62a17ae 174 vrf_bitmap_free(zclient->default_information);
175 zclient->default_information = VRF_BITMAP_NULL;
718e3744 176}
177
d62a17ae 178void zclient_reset(struct zclient *zclient)
718e3744 179{
d62a17ae 180 afi_t afi;
3d68677e 181
d62a17ae 182 zclient_stop(zclient);
3d68677e 183
d62a17ae 184 for (afi = AFI_IP; afi < AFI_MAX; afi++)
185 redist_del_instance(
186 &zclient->mi_redist[afi][zclient->redist_default],
187 zclient->instance);
3d68677e 188
342213ea
DS
189 zclient_init(zclient, zclient->redist_default,
190 zclient->instance, zclient->privs);
718e3744 191}
192
689f5a8c
DL
193/**
194 * Connect to zebra daemon.
195 * @param zclient a pointer to zclient structure
196 * @return socket fd just to make sure that connection established
197 * @see zclient_init
e1a1880d 198 * @see zclient_new_notify
689f5a8c
DL
199 */
200int zclient_socket_connect(struct zclient *zclient)
718e3744 201{
d62a17ae 202 int sock;
203 int ret;
d62a17ae 204
205 /* We should think about IPv6 connection. */
689f5a8c 206 sock = socket(zclient_addr.ss_family, SOCK_STREAM, 0);
d62a17ae 207 if (sock < 0)
208 return -1;
209
689f5a8c 210 set_cloexec(sock);
d62a17ae 211
342213ea
DS
212 zclient->privs->change(ZPRIVS_RAISE);
213 setsockopt_so_sendbuf(sock, 1048576);
214 zclient->privs->change(ZPRIVS_LOWER);
215
d62a17ae 216 /* Connect to zebra. */
689f5a8c
DL
217 ret = connect(sock, (struct sockaddr *)&zclient_addr,
218 zclient_addr_len);
d62a17ae 219 if (ret < 0) {
220 if (zclient_debug)
221 zlog_warn("%s connect failure: %d(%s)",
222 __PRETTY_FUNCTION__, errno,
223 safe_strerror(errno));
224 close(sock);
225 return -1;
226 }
718e3744 227
689f5a8c 228 zclient->sock = sock;
d62a17ae 229 return sock;
718e3744 230}
231
d62a17ae 232static int zclient_failed(struct zclient *zclient)
634f9ea2 233{
d62a17ae 234 zclient->fail++;
235 zclient_stop(zclient);
236 zclient_event(ZCLIENT_CONNECT, zclient);
237 return -1;
634f9ea2 238}
239
d62a17ae 240static int zclient_flush_data(struct thread *thread)
634f9ea2 241{
d62a17ae 242 struct zclient *zclient = THREAD_ARG(thread);
243
244 zclient->t_write = NULL;
245 if (zclient->sock < 0)
246 return -1;
247 switch (buffer_flush_available(zclient->wb, zclient->sock)) {
248 case BUFFER_ERROR:
249 zlog_warn(
250 "%s: buffer_flush_available failed on zclient fd %d, closing",
251 __func__, zclient->sock);
252 return zclient_failed(zclient);
253 break;
254 case BUFFER_PENDING:
255 zclient->t_write = NULL;
256 thread_add_write(zclient->master, zclient_flush_data, zclient,
257 zclient->sock, &zclient->t_write);
258 break;
259 case BUFFER_EMPTY:
260 break;
261 }
262 return 0;
634f9ea2 263}
264
d62a17ae 265int zclient_send_message(struct zclient *zclient)
634f9ea2 266{
d62a17ae 267 if (zclient->sock < 0)
268 return -1;
269 switch (buffer_write(zclient->wb, zclient->sock,
270 STREAM_DATA(zclient->obuf),
271 stream_get_endp(zclient->obuf))) {
272 case BUFFER_ERROR:
273 zlog_warn("%s: buffer_write failed to zclient fd %d, closing",
274 __func__, zclient->sock);
275 return zclient_failed(zclient);
276 break;
277 case BUFFER_EMPTY:
278 THREAD_OFF(zclient->t_write);
279 break;
280 case BUFFER_PENDING:
281 thread_add_write(zclient->master, zclient_flush_data, zclient,
282 zclient->sock, &zclient->t_write);
283 break;
284 }
285 return 0;
634f9ea2 286}
287
d62a17ae 288void zclient_create_header(struct stream *s, uint16_t command, vrf_id_t vrf_id)
c1b9800a 289{
d62a17ae 290 /* length placeholder, caller can update */
291 stream_putw(s, ZEBRA_HEADER_SIZE);
292 stream_putc(s, ZEBRA_HEADER_MARKER);
293 stream_putc(s, ZSERV_VERSION);
294 stream_putw(s, vrf_id);
295 stream_putw(s, command);
c1b9800a 296}
297
d62a17ae 298int zclient_read_header(struct stream *s, int sock, u_int16_t *size,
299 u_char *marker, u_char *version, vrf_id_t *vrf_id,
300 u_int16_t *cmd)
55119089 301{
d62a17ae 302 if (stream_read(s, sock, ZEBRA_HEADER_SIZE) != ZEBRA_HEADER_SIZE)
303 return -1;
304
ec93aa12
DS
305 STREAM_GETW(s, *size);
306 *size -= ZEBRA_HEADER_SIZE;
307 STREAM_GETC(s, *marker);
308 STREAM_GETC(s, *version);
309 STREAM_GETW(s, *vrf_id);
310 STREAM_GETW(s, *cmd);
d62a17ae 311
312 if (*version != ZSERV_VERSION || *marker != ZEBRA_HEADER_MARKER) {
313 zlog_err(
314 "%s: socket %d version mismatch, marker %d, version %d",
315 __func__, sock, *marker, *version);
316 return -1;
317 }
318
319 if (*size && stream_read(s, sock, *size) != *size)
320 return -1;
321
ec93aa12 322stream_failure:
d62a17ae 323 return 0;
55119089
ND
324}
325
634f9ea2 326/* Send simple Zebra message. */
d62a17ae 327static int zebra_message_send(struct zclient *zclient, int command,
328 vrf_id_t vrf_id)
718e3744 329{
d62a17ae 330 struct stream *s;
718e3744 331
d62a17ae 332 /* Get zclient output buffer. */
333 s = zclient->obuf;
334 stream_reset(s);
718e3744 335
d62a17ae 336 /* Send very simple command only Zebra message. */
337 zclient_create_header(s, command, vrf_id);
338
339 return zclient_send_message(zclient);
718e3744 340}
341
d62a17ae 342static int zebra_hello_send(struct zclient *zclient)
2ea1ab1c 343{
d62a17ae 344 struct stream *s;
345
346 if (zclient->redist_default) {
347 s = zclient->obuf;
348 stream_reset(s);
349
350 /* The VRF ID in the HELLO message is always 0. */
351 zclient_create_header(s, ZEBRA_HELLO, VRF_DEFAULT);
352 stream_putc(s, zclient->redist_default);
353 stream_putw(s, zclient->instance);
e1a1880d
DS
354 if (zclient->receive_notify)
355 stream_putc(s, 1);
356 else
357 stream_putc(s, 0);
358
d62a17ae 359 stream_putw_at(s, 0, stream_get_endp(s));
360 return zclient_send_message(zclient);
361 }
362
363 return 0;
2ea1ab1c
VT
364}
365
0e5223e7 366/* Send register requests to zebra daemon for the information in a VRF. */
d62a17ae 367void zclient_send_reg_requests(struct zclient *zclient, vrf_id_t vrf_id)
7076bb2f 368{
d62a17ae 369 int i;
370 afi_t afi;
371
d62a17ae 372 /* If not connected to the zebra yet. */
373 if (zclient->sock < 0)
374 return;
375
376 if (zclient_debug)
377 zlog_debug("%s: send register messages for VRF %u", __func__,
378 vrf_id);
379
380 /* We need router-id information. */
381 zebra_message_send(zclient, ZEBRA_ROUTER_ID_ADD, vrf_id);
382
383 /* We need interface information. */
384 zebra_message_send(zclient, ZEBRA_INTERFACE_ADD, vrf_id);
385
386 /* Set unwanted redistribute route. */
387 for (afi = AFI_IP; afi < AFI_MAX; afi++)
388 vrf_bitmap_set(zclient->redist[afi][zclient->redist_default],
389 vrf_id);
390
391 /* Flush all redistribute request. */
392 if (vrf_id == VRF_DEFAULT)
393 for (afi = AFI_IP; afi < AFI_MAX; afi++)
394 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
395 if (zclient->mi_redist[afi][i].enabled) {
396 struct listnode *node;
397 u_short *id;
398
399 for (ALL_LIST_ELEMENTS_RO(
400 zclient->mi_redist[afi][i]
401 .instances,
402 node, id))
403 if (!(i == zclient->redist_default
404 && *id == zclient->instance))
405 zebra_redistribute_send(
406 ZEBRA_REDISTRIBUTE_ADD,
407 zclient, afi, i,
408 *id,
409 VRF_DEFAULT);
410 }
411
412 /* Flush all redistribute request. */
413 for (afi = AFI_IP; afi < AFI_MAX; afi++)
414 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
415 if (i != zclient->redist_default
416 && vrf_bitmap_check(zclient->redist[afi][i],
417 vrf_id))
418 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD,
419 zclient, afi, i, 0,
420 vrf_id);
421
422 /* If default information is needed. */
423 if (vrf_bitmap_check(zclient->default_information, VRF_DEFAULT))
424 zebra_message_send(zclient, ZEBRA_REDISTRIBUTE_DEFAULT_ADD,
425 vrf_id);
7076bb2f
FL
426}
427
0e5223e7 428/* Send unregister requests to zebra daemon for the information in a VRF. */
d62a17ae 429void zclient_send_dereg_requests(struct zclient *zclient, vrf_id_t vrf_id)
0e5223e7 430{
d62a17ae 431 int i;
432 afi_t afi;
433
d62a17ae 434 /* If not connected to the zebra yet. */
435 if (zclient->sock < 0)
436 return;
437
438 if (zclient_debug)
439 zlog_debug("%s: send deregister messages for VRF %u", __func__,
440 vrf_id);
441
442 /* We need router-id information. */
443 zebra_message_send(zclient, ZEBRA_ROUTER_ID_DELETE, vrf_id);
444
445 /* We need interface information. */
446 zebra_message_send(zclient, ZEBRA_INTERFACE_DELETE, vrf_id);
447
448 /* Set unwanted redistribute route. */
449 for (afi = AFI_IP; afi < AFI_MAX; afi++)
450 vrf_bitmap_set(zclient->redist[afi][zclient->redist_default],
451 vrf_id);
452
453 /* Flush all redistribute request. */
454 if (vrf_id == VRF_DEFAULT)
455 for (afi = AFI_IP; afi < AFI_MAX; afi++)
456 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
457 if (zclient->mi_redist[afi][i].enabled) {
458 struct listnode *node;
459 u_short *id;
460
461 for (ALL_LIST_ELEMENTS_RO(
462 zclient->mi_redist[afi][i]
463 .instances,
464 node, id))
465 if (!(i == zclient->redist_default
466 && *id == zclient->instance))
467 zebra_redistribute_send(
468 ZEBRA_REDISTRIBUTE_DELETE,
469 zclient, afi, i,
470 *id,
471 VRF_DEFAULT);
472 }
473
474 /* Flush all redistribute request. */
475 for (afi = AFI_IP; afi < AFI_MAX; afi++)
476 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
477 if (i != zclient->redist_default
478 && vrf_bitmap_check(zclient->redist[afi][i],
479 vrf_id))
480 zebra_redistribute_send(
481 ZEBRA_REDISTRIBUTE_DELETE, zclient, afi,
482 i, 0, vrf_id);
483
484 /* If default information is needed. */
485 if (vrf_bitmap_check(zclient->default_information, VRF_DEFAULT))
486 zebra_message_send(zclient, ZEBRA_REDISTRIBUTE_DEFAULT_DELETE,
487 vrf_id);
0e5223e7 488}
489
4a04e5f7 490/* Send request to zebra daemon to start or stop RA. */
d62a17ae 491void zclient_send_interface_radv_req(struct zclient *zclient, vrf_id_t vrf_id,
492 struct interface *ifp, int enable,
493 int ra_interval)
4a04e5f7 494{
d62a17ae 495 struct stream *s;
4a04e5f7 496
d62a17ae 497 /* If not connected to the zebra yet. */
498 if (zclient->sock < 0)
499 return;
4a04e5f7 500
d62a17ae 501 /* Form and send message. */
502 s = zclient->obuf;
503 stream_reset(s);
4a04e5f7 504
d62a17ae 505 if (enable)
506 zclient_create_header(s, ZEBRA_INTERFACE_ENABLE_RADV, vrf_id);
507 else
508 zclient_create_header(s, ZEBRA_INTERFACE_DISABLE_RADV, vrf_id);
4a04e5f7 509
d62a17ae 510 stream_putl(s, ifp->ifindex);
511 stream_putl(s, ra_interval);
4a04e5f7 512
d62a17ae 513 stream_putw_at(s, 0, stream_get_endp(s));
4a04e5f7 514
d62a17ae 515 zclient_send_message(zclient);
4a04e5f7 516}
517
718e3744 518/* Make connection to zebra daemon. */
d62a17ae 519int zclient_start(struct zclient *zclient)
718e3744 520{
d62a17ae 521 if (zclient_debug)
522 zlog_info("zclient_start is called");
523
d62a17ae 524 /* If already connected to the zebra. */
525 if (zclient->sock >= 0)
526 return 0;
527
528 /* Check connect thread. */
529 if (zclient->t_connect)
530 return 0;
531
532 if (zclient_socket_connect(zclient) < 0) {
533 if (zclient_debug)
534 zlog_debug("zclient connection fail");
535 zclient->fail++;
536 zclient_event(ZCLIENT_CONNECT, zclient);
537 return -1;
538 }
718e3744 539
d62a17ae 540 if (set_nonblocking(zclient->sock) < 0)
541 zlog_warn("%s: set_nonblocking(%d) failed", __func__,
542 zclient->sock);
718e3744 543
d62a17ae 544 /* Clear fail count. */
545 zclient->fail = 0;
546 if (zclient_debug)
547 zlog_debug("zclient connect success with socket [%d]",
548 zclient->sock);
718e3744 549
d62a17ae 550 /* Create read thread. */
551 zclient_event(ZCLIENT_READ, zclient);
718e3744 552
d62a17ae 553 zebra_hello_send(zclient);
718e3744 554
d62a17ae 555 /* Inform the successful connection. */
556 if (zclient->zebra_connected)
557 (*zclient->zebra_connected)(zclient);
718e3744 558
d62a17ae 559 return 0;
718e3744 560}
6b0655a2 561
078430f6
DS
562/* Initialize zebra client. Argument redist_default is unwanted
563 redistribute route type. */
342213ea
DS
564void zclient_init(struct zclient *zclient, int redist_default,
565 u_short instance, struct zebra_privs_t *privs)
078430f6 566{
d62a17ae 567 int afi, i;
568
d62a17ae 569 /* Set -1 to the default socket value. */
570 zclient->sock = -1;
342213ea 571 zclient->privs = privs;
d62a17ae 572
573 /* Clear redistribution flags. */
574 for (afi = AFI_IP; afi < AFI_MAX; afi++)
575 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
576 zclient->redist[afi][i] = vrf_bitmap_init();
577
578 /* Set unwanted redistribute route. bgpd does not need BGP route
579 redistribution. */
580 zclient->redist_default = redist_default;
581 zclient->instance = instance;
582 /* Pending: make afi(s) an arg. */
583 for (afi = AFI_IP; afi < AFI_MAX; afi++)
584 redist_add_instance(&zclient->mi_redist[afi][redist_default],
585 instance);
586
587 /* Set default-information redistribute to zero. */
588 zclient->default_information = vrf_bitmap_init();
d62a17ae 589
590 if (zclient_debug)
591 zlog_debug("zclient_start is called");
592
593 zclient_event(ZCLIENT_SCHEDULE, zclient);
7076bb2f 594}
078430f6 595
7076bb2f
FL
596/* This function is a wrapper function for calling zclient_start from
597 timer or event thread. */
d62a17ae 598static int zclient_connect(struct thread *t)
7076bb2f 599{
d62a17ae 600 struct zclient *zclient;
078430f6 601
d62a17ae 602 zclient = THREAD_ARG(t);
603 zclient->t_connect = NULL;
078430f6 604
d62a17ae 605 if (zclient_debug)
606 zlog_debug("zclient_connect is called");
078430f6 607
d62a17ae 608 return zclient_start(zclient);
078430f6
DS
609}
610
d62a17ae 611/*
612 * "xdr_encode"-like interface that allows daemon (client) to send
613 * a message to zebra server for a route that needs to be
614 * added/deleted to the kernel. Info about the route is specified
615 * by the caller in a struct zapi_ipv4. zapi_ipv4_read() then writes
616 * the info down the zclient socket using the stream_* functions.
617 *
618 * The corresponding read ("xdr_decode") function on the server
619 * side is zread_ipv4_add()/zread_ipv4_delete().
620 *
621 * 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
622 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
623 * | Length (2) | Command | Route Type |
624 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
625 * | ZEBRA Flags | Message Flags | Prefix length |
626 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
627 * | Destination IPv4 Prefix for route |
628 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
629 * | Nexthop count |
630 * +-+-+-+-+-+-+-+-+
631 *
632 *
633 * A number of IPv4 nexthop(s) or nexthop interface index(es) are then
634 * described, as per the Nexthop count. Each nexthop described as:
635 *
636 * +-+-+-+-+-+-+-+-+
637 * | Nexthop Type | Set to one of ZEBRA_NEXTHOP_*
638 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
639 * | IPv4 Nexthop address or Interface Index number |
640 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
641 *
09a484dd
DL
642 * Alternatively, if the route is a blackhole route, then Nexthop count
643 * is set to 1 and a nexthop of type NEXTHOP_TYPE_BLACKHOLE is the sole
644 * nexthop.
d62a17ae 645 *
646 * The original struct zapi_ipv4, zapi_ipv4_route() and zread_ipv4_*()
647 * infrastructure was built around the traditional (32-bit "gate OR
648 * ifindex") nexthop data unit. A special encoding can be used to feed
649 * onlink (64-bit "gate AND ifindex") nexthops into zapi_ipv4_route()
650 * using the same zapi_ipv4 structure. This is done by setting zapi_ipv4
651 * fields as follows:
652 * - .message |= ZAPI_MESSAGE_NEXTHOP | ZAPI_MESSAGE_ONLINK
653 * - .nexthop_num == .ifindex_num
654 * - .nexthop and .ifindex are filled with gate and ifindex parts of
655 * each compound nexthop, both in the same order
656 *
657 * zapi_ipv4_route() will produce two nexthop data units for each such
658 * interleaved 64-bit nexthop. On the zserv side of the socket it will be
659 * mapped to a singlle NEXTHOP_TYPE_IPV4_IFINDEX_OL RIB nexthop structure.
660 *
661 * If ZAPI_MESSAGE_DISTANCE is set, the distance value is written as a 1
662 * byte value.
663 *
664 * If ZAPI_MESSAGE_METRIC is set, the metric value is written as an 8
665 * byte value.
666 *
667 * If ZAPI_MESSAGE_TAG is set, the tag value is written as a 4 byte value
668 *
669 * If ZAPI_MESSAGE_MTU is set, the mtu value is written as a 4 byte value
670 *
671 * XXX: No attention paid to alignment.
672 */
673int zapi_ipv4_route(u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p,
674 struct zapi_ipv4 *api)
718e3744 675{
d62a17ae 676 int i;
677 int psize;
678 struct stream *s;
679
680 /* Reset stream. */
681 s = zclient->obuf;
682 stream_reset(s);
683
684 /* Some checks for labeled-unicast. The current expectation is that each
685 * nexthop is accompanied by a label in the case of labeled-unicast.
686 */
687 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL)
688 && CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
689 /* We expect prefixes installed with labels and the number to
690 * match
691 * the number of nexthops.
692 */
693 assert(api->label_num == api->nexthop_num);
694 }
695
696 zclient_create_header(s, cmd, api->vrf_id);
697
698 /* Put type and nexthop. */
699 stream_putc(s, api->type);
700 stream_putw(s, api->instance);
701 stream_putl(s, api->flags);
702 stream_putc(s, api->message);
703 stream_putw(s, api->safi);
704
705 /* Put prefix information. */
706 psize = PSIZE(p->prefixlen);
707 stream_putc(s, p->prefixlen);
708 stream_write(s, (u_char *)&p->prefix, psize);
709
710 /* Nexthop, ifindex, distance and metric information. */
711 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
09a484dd 712 stream_putc(s, api->nexthop_num + api->ifindex_num);
d62a17ae 713
714 for (i = 0; i < api->nexthop_num; i++) {
715 stream_putc(s, NEXTHOP_TYPE_IPV4);
716 stream_put_in_addr(s, api->nexthop[i]);
717 /* For labeled-unicast, each nexthop is followed by
718 * label. */
719 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL))
720 stream_putl(s, api->label[i]);
721 }
722 for (i = 0; i < api->ifindex_num; i++) {
723 stream_putc(s, NEXTHOP_TYPE_IFINDEX);
724 stream_putl(s, api->ifindex[i]);
725 }
726 }
727
728 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
729 stream_putc(s, api->distance);
730 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
731 stream_putl(s, api->metric);
732 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
733 stream_putl(s, api->tag);
734 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
735 stream_putl(s, api->mtu);
736
737 /* Put length at the first point of the stream. */
738 stream_putw_at(s, 0, stream_get_endp(s));
739
740 return zclient_send_message(zclient);
718e3744 741}
742
d62a17ae 743int zapi_ipv4_route_ipv6_nexthop(u_char cmd, struct zclient *zclient,
744 struct prefix_ipv4 *p, struct zapi_ipv6 *api)
8a92a8a0 745{
d62a17ae 746 int i;
747 int psize;
748 struct stream *s;
749
750 /* Reset stream. */
751 s = zclient->obuf;
752 stream_reset(s);
753
754 /* Some checks for labeled-unicast. The current expectation is that each
755 * nexthop is accompanied by a label in the case of labeled-unicast.
756 */
757 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL)
758 && CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
759 /* We expect prefixes installed with labels and the number to
760 * match
761 * the number of nexthops.
762 */
763 assert(api->label_num == api->nexthop_num);
8a92a8a0 764 }
d62a17ae 765
766 zclient_create_header(s, cmd, api->vrf_id);
767
768 /* Put type and nexthop. */
769 stream_putc(s, api->type);
770 stream_putw(s, api->instance);
771 stream_putl(s, api->flags);
772 stream_putc(s, api->message);
773 stream_putw(s, api->safi);
774
775 /* Put prefix information. */
776 psize = PSIZE(p->prefixlen);
777 stream_putc(s, p->prefixlen);
778 stream_write(s, (u_char *)&p->prefix, psize);
779
780 /* Nexthop, ifindex, distance and metric information. */
781 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
09a484dd 782 stream_putc(s, api->nexthop_num + api->ifindex_num);
d62a17ae 783
784 for (i = 0; i < api->nexthop_num; i++) {
785 stream_putc(s, NEXTHOP_TYPE_IPV6);
786 stream_write(s, (u_char *)api->nexthop[i], 16);
787 /* For labeled-unicast, each nexthop is followed by
788 * label. */
789 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL))
790 stream_putl(s, api->label[i]);
791 }
792 for (i = 0; i < api->ifindex_num; i++) {
793 stream_putc(s, NEXTHOP_TYPE_IFINDEX);
794 stream_putl(s, api->ifindex[i]);
795 }
8a92a8a0 796 }
8a92a8a0 797
d62a17ae 798 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
799 stream_putc(s, api->distance);
800 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
801 stream_putl(s, api->metric);
802 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
803 stream_putl(s, api->tag);
804 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
805 stream_putl(s, api->mtu);
8a92a8a0 806
d62a17ae 807 /* Put length at the first point of the stream. */
808 stream_putw_at(s, 0, stream_get_endp(s));
8a92a8a0 809
d62a17ae 810 return zclient_send_message(zclient);
8a92a8a0
DS
811}
812
d62a17ae 813int zapi_ipv6_route(u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p,
814 struct prefix_ipv6 *src_p, struct zapi_ipv6 *api)
718e3744 815{
d62a17ae 816 int i;
817 int psize;
818 struct stream *s;
819
820 /* either we have !SRCPFX && src_p == NULL, or SRCPFX && src_p != NULL
821 */
822 assert(!(api->message & ZAPI_MESSAGE_SRCPFX) == !src_p);
823
824 /* Reset stream. */
825 s = zclient->obuf;
826 stream_reset(s);
827
828 /* Some checks for labeled-unicast. The current expectation is that each
829 * nexthop is accompanied by a label in the case of labeled-unicast.
830 */
831 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL)
832 && CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
833 /* We expect prefixes installed with labels and the number to
834 * match
835 * the number of nexthops.
836 */
837 assert(api->label_num == api->nexthop_num);
718e3744 838 }
d62a17ae 839
840 zclient_create_header(s, cmd, api->vrf_id);
841
842 /* Put type and nexthop. */
843 stream_putc(s, api->type);
844 stream_putw(s, api->instance);
845 stream_putl(s, api->flags);
846 stream_putc(s, api->message);
847 stream_putw(s, api->safi);
848
849 /* Put prefix information. */
850 psize = PSIZE(p->prefixlen);
851 stream_putc(s, p->prefixlen);
852 stream_write(s, (u_char *)&p->prefix, psize);
853
854 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_SRCPFX)) {
855 psize = PSIZE(src_p->prefixlen);
856 stream_putc(s, src_p->prefixlen);
857 stream_write(s, (u_char *)&src_p->prefix, psize);
718e3744 858 }
718e3744 859
d62a17ae 860 /* Nexthop, ifindex, distance and metric information. */
861 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
09a484dd 862 stream_putc(s, api->nexthop_num + api->ifindex_num);
d62a17ae 863
864 for (i = 0; i < api->nexthop_num; i++) {
865 stream_putc(s, NEXTHOP_TYPE_IPV6);
866 stream_write(s, (u_char *)api->nexthop[i], 16);
867 /* For labeled-unicast, each nexthop is followed by
868 * label. */
869 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL))
870 stream_putl(s, api->label[i]);
871 }
872 for (i = 0; i < api->ifindex_num; i++) {
873 stream_putc(s, NEXTHOP_TYPE_IFINDEX);
874 stream_putl(s, api->ifindex[i]);
875 }
876 }
718e3744 877
d62a17ae 878 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
879 stream_putc(s, api->distance);
880 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
881 stream_putl(s, api->metric);
882 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
883 stream_putl(s, api->tag);
884 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
885 stream_putl(s, api->mtu);
718e3744 886
d62a17ae 887 /* Put length at the first point of the stream. */
888 stream_putw_at(s, 0, stream_get_endp(s));
889
890 return zclient_send_message(zclient);
718e3744 891}
718e3744 892
0e51b4a3
RW
893int zclient_route_send(u_char cmd, struct zclient *zclient,
894 struct zapi_route *api)
657cde12 895{
0e51b4a3
RW
896 if (zapi_route_encode(cmd, zclient->obuf, api) < 0)
897 return -1;
898 return zclient_send_message(zclient);
899}
900
901int zapi_route_encode(u_char cmd, struct stream *s, struct zapi_route *api)
902{
903 struct zapi_nexthop *api_nh;
d62a17ae 904 int i;
905 int psize;
d62a17ae 906
d62a17ae 907 stream_reset(s);
d62a17ae 908 zclient_create_header(s, cmd, api->vrf_id);
909
d62a17ae 910 stream_putc(s, api->type);
911 stream_putw(s, api->instance);
912 stream_putl(s, api->flags);
913 stream_putc(s, api->message);
832d0f56 914 stream_putc(s, api->safi);
d62a17ae 915
916 /* Put prefix information. */
0e51b4a3 917 stream_putc(s, api->prefix.family);
bb1b9c47
RW
918 psize = PSIZE(api->prefix.prefixlen);
919 stream_putc(s, api->prefix.prefixlen);
920 stream_write(s, (u_char *)&api->prefix.u.prefix, psize);
d62a17ae 921
922 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_SRCPFX)) {
bb1b9c47
RW
923 psize = PSIZE(api->src_prefix.prefixlen);
924 stream_putc(s, api->src_prefix.prefixlen);
925 stream_write(s, (u_char *)&api->src_prefix.prefix, psize);
d62a17ae 926 }
927
0e51b4a3 928 /* Nexthops. */
d62a17ae 929 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
bb1b9c47
RW
930 /* limit the number of nexthops if necessary */
931 if (api->nexthop_num > MULTIPATH_NUM) {
932 char buf[PREFIX2STR_BUFFER];
933
934 prefix2str(&api->prefix, buf, sizeof(buf));
935 zlog_warn(
a74e593b
RW
936 "%s: prefix %s: can't encode %u nexthops "
937 "(maximum is %u)",
938 __func__, buf, api->nexthop_num, MULTIPATH_NUM);
939 return -1;
bb1b9c47
RW
940 }
941
b5f79651 942 stream_putw(s, api->nexthop_num);
d62a17ae 943
944 for (i = 0; i < api->nexthop_num; i++) {
bb1b9c47
RW
945 api_nh = &api->nexthops[i];
946
947 stream_putc(s, api_nh->type);
948 switch (api_nh->type) {
d62a17ae 949 case NEXTHOP_TYPE_BLACKHOLE:
94758e66 950 stream_putc(s, api_nh->bh_type);
d62a17ae 951 break;
952 case NEXTHOP_TYPE_IPV4:
bb1b9c47 953 stream_put_in_addr(s, &api_nh->gate.ipv4);
d62a17ae 954 break;
955 case NEXTHOP_TYPE_IPV4_IFINDEX:
bb1b9c47
RW
956 stream_put_in_addr(s, &api_nh->gate.ipv4);
957 stream_putl(s, api_nh->ifindex);
d62a17ae 958 break;
959 case NEXTHOP_TYPE_IFINDEX:
bb1b9c47 960 stream_putl(s, api_nh->ifindex);
d62a17ae 961 break;
962 case NEXTHOP_TYPE_IPV6:
bb1b9c47
RW
963 stream_write(s, (u_char *)&api_nh->gate.ipv6,
964 16);
d62a17ae 965 break;
966 case NEXTHOP_TYPE_IPV6_IFINDEX:
bb1b9c47
RW
967 stream_write(s, (u_char *)&api_nh->gate.ipv6,
968 16);
969 stream_putl(s, api_nh->ifindex);
d62a17ae 970 break;
ec93aa12
DS
971 default:
972 zlog_warn("%s: Specified Nexthop type %d does not exist",
973 __PRETTY_FUNCTION__, api_nh->type);
974 return -1;
d62a17ae 975 }
bb1b9c47 976
52dd3aa4
RW
977 /* MPLS labels for BGP-LU or Segment Routing */
978 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL)) {
979 if (api_nh->label_num > MPLS_MAX_LABELS) {
980 char buf[PREFIX2STR_BUFFER];
981 prefix2str(&api->prefix, buf,
982 sizeof(buf));
983 zlog_err(
984 "%s: prefix %s: can't encode "
985 "%u labels (maximum is %u)",
986 __func__, buf,
987 api_nh->label_num,
988 MPLS_MAX_LABELS);
989 return -1;
990 }
991
992 stream_putc(s, api_nh->label_num);
993 stream_put(s, &api_nh->labels[0],
994 api_nh->label_num
995 * sizeof(mpls_label_t));
996 }
d62a17ae 997 }
998 }
999
0e51b4a3 1000 /* Attributes. */
d62a17ae 1001 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
1002 stream_putc(s, api->distance);
1003 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
1004 stream_putl(s, api->metric);
1005 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
1006 stream_putl(s, api->tag);
1007 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
1008 stream_putl(s, api->mtu);
1009
1010 /* Put length at the first point of the stream. */
1011 stream_putw_at(s, 0, stream_get_endp(s));
1012
0e51b4a3
RW
1013 return 0;
1014}
1015
1016int zapi_route_decode(struct stream *s, struct zapi_route *api)
1017{
1018 struct zapi_nexthop *api_nh;
1019 int i;
1020
1021 memset(api, 0, sizeof(*api));
1022
1023 /* Type, flags, message. */
ec93aa12
DS
1024 STREAM_GETC(s, api->type);
1025 if (api->type > ZEBRA_ROUTE_MAX) {
1026 zlog_warn("%s: Specified route type: %d is not a legal value\n",
1027 __PRETTY_FUNCTION__, api->type);
1028 return -1;
1029 }
1030
1031 STREAM_GETW(s, api->instance);
1032 STREAM_GETL(s, api->flags);
1033 STREAM_GETC(s, api->message);
832d0f56 1034 STREAM_GETC(s, api->safi);
0e51b4a3
RW
1035
1036 /* Prefix. */
ec93aa12
DS
1037 STREAM_GETC(s, api->prefix.family);
1038 STREAM_GETC(s, api->prefix.prefixlen);
0e51b4a3
RW
1039 switch (api->prefix.family) {
1040 case AF_INET:
ec93aa12
DS
1041 if (api->prefix.prefixlen > IPV4_MAX_PREFIXLEN) {
1042 zlog_warn("%s: V4 prefixlen is %d which should not be more than 32",
1043 __PRETTY_FUNCTION__, api->prefix.prefixlen);
1044 return -1;
1045 }
0e51b4a3
RW
1046 break;
1047 case AF_INET6:
ec93aa12
DS
1048 if (api->prefix.prefixlen > IPV6_MAX_PREFIXLEN) {
1049 zlog_warn("%s: v6 prefixlen is %d which should not be more than 128",
1050 __PRETTY_FUNCTION__, api->prefix.prefixlen);
1051 return -1;
1052 }
0e51b4a3 1053 break;
ec93aa12
DS
1054 default:
1055 zlog_warn("%s: Specified family %d is not v4 or v6",
1056 __PRETTY_FUNCTION__, api->prefix.family);
1057 return -1;
0e51b4a3 1058 }
ec93aa12
DS
1059 STREAM_GET(&api->prefix.u.prefix, s, PSIZE(api->prefix.prefixlen));
1060
0e51b4a3
RW
1061 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_SRCPFX)) {
1062 api->src_prefix.family = AF_INET6;
ec93aa12
DS
1063 STREAM_GETC(s, api->src_prefix.prefixlen);
1064 if (api->src_prefix.prefixlen > IPV6_MAX_PREFIXLEN) {
1065 zlog_warn("%s: SRC Prefix prefixlen received: %d is too large",
1066 __PRETTY_FUNCTION__,
1067 api->src_prefix.prefixlen);
1068 return -1;
1069 }
1070 STREAM_GET(&api->src_prefix.prefix, s,
0e51b4a3
RW
1071 PSIZE(api->src_prefix.prefixlen));
1072
1073 if (api->prefix.family != AF_INET6
ec93aa12
DS
1074 || api->src_prefix.prefixlen == 0) {
1075 zlog_warn("%s: SRC prefix specified in some manner that makes no sense",
1076 __PRETTY_FUNCTION__);
1077 return -1;
1078 }
0e51b4a3
RW
1079 }
1080
1081 /* Nexthops. */
1082 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
ec93aa12 1083 STREAM_GETW(s, api->nexthop_num);
0e51b4a3
RW
1084 if (api->nexthop_num > MULTIPATH_NUM) {
1085 zlog_warn("%s: invalid number of nexthops (%u)",
1086 __func__, api->nexthop_num);
1087 return -1;
1088 }
1089
1090 for (i = 0; i < api->nexthop_num; i++) {
1091 api_nh = &api->nexthops[i];
1092
ec93aa12 1093 STREAM_GETC(s, api_nh->type);
0e51b4a3
RW
1094 switch (api_nh->type) {
1095 case NEXTHOP_TYPE_BLACKHOLE:
ec93aa12 1096 STREAM_GETC(s, api_nh->bh_type);
0e51b4a3
RW
1097 break;
1098 case NEXTHOP_TYPE_IPV4:
ec93aa12
DS
1099 STREAM_GET(&api_nh->gate.ipv4.s_addr, s,
1100 IPV4_MAX_BYTELEN);
0e51b4a3
RW
1101 break;
1102 case NEXTHOP_TYPE_IPV4_IFINDEX:
ec93aa12
DS
1103 STREAM_GET(&api_nh->gate.ipv4.s_addr, s,
1104 IPV4_MAX_BYTELEN);
1105 STREAM_GETL(s, api_nh->ifindex);
0e51b4a3
RW
1106 break;
1107 case NEXTHOP_TYPE_IFINDEX:
ec93aa12 1108 STREAM_GETL(s, api_nh->ifindex);
0e51b4a3
RW
1109 break;
1110 case NEXTHOP_TYPE_IPV6:
ec93aa12 1111 STREAM_GET(&api_nh->gate.ipv6, s, 16);
0e51b4a3
RW
1112 break;
1113 case NEXTHOP_TYPE_IPV6_IFINDEX:
ec93aa12
DS
1114 STREAM_GET(&api_nh->gate.ipv6, s, 16);
1115 STREAM_GETL(s, api_nh->ifindex);
0e51b4a3 1116 break;
ec93aa12
DS
1117 default:
1118 zlog_warn("%s: Specified nexthop type %d does not exist",
1119 __PRETTY_FUNCTION__,
1120 api_nh->type);
1121 return -1;
0e51b4a3
RW
1122 }
1123
52dd3aa4 1124 /* MPLS labels for BGP-LU or Segment Routing */
0e51b4a3 1125 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_LABEL)) {
ec93aa12 1126 STREAM_GETC(s, api_nh->label_num);
52dd3aa4
RW
1127
1128 if (api_nh->label_num > MPLS_MAX_LABELS) {
1129 zlog_warn(
1130 "%s: invalid number of MPLS "
1131 "labels (%u)",
1132 __func__, api_nh->label_num);
1133 return -1;
1134 }
1135
ec93aa12 1136 STREAM_GET(&api_nh->labels[0], s,
52dd3aa4
RW
1137 api_nh->label_num
1138 * sizeof(mpls_label_t));
0e51b4a3
RW
1139 }
1140 }
1141 }
1142
1143 /* Attributes. */
1144 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DISTANCE))
ec93aa12 1145 STREAM_GETC(s, api->distance);
0e51b4a3 1146 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
ec93aa12 1147 STREAM_GETL(s, api->metric);
0e51b4a3 1148 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
ec93aa12 1149 STREAM_GETL(s, api->tag);
0e51b4a3 1150 if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
ec93aa12 1151 STREAM_GETL(s, api->mtu);
0e51b4a3 1152
ec93aa12 1153stream_failure:
0e51b4a3 1154 return 0;
657cde12
DS
1155}
1156
7ea7b86e
DS
1157bool zapi_route_notify_decode(struct stream *s, struct prefix *p,
1158 enum zapi_route_notify_owner *note)
1159{
1160 STREAM_GET(note, s, sizeof(*note));
1161
1162 STREAM_GETC(s, p->family);
1163 STREAM_GETC(s, p->prefixlen);
1164 STREAM_GET(&p->u.prefix, s,
1165 PSIZE(p->prefixlen));
1166
1167 return true;
1168
1169stream_failure:
1170 return false;
1171}
1172
d62a17ae 1173/*
0a589359 1174 * send a ZEBRA_REDISTRIBUTE_ADD or ZEBRA_REDISTRIBUTE_DELETE
1175 * for the route type (ZEBRA_ROUTE_KERNEL etc.). The zebra server will
d62a17ae 1176 * then set/unset redist[type] in the client handle (a struct zserv) for the
0a589359 1177 * sending client
1178 */
d62a17ae 1179int zebra_redistribute_send(int command, struct zclient *zclient, afi_t afi,
1180 int type, u_short instance, vrf_id_t vrf_id)
718e3744 1181{
d62a17ae 1182 struct stream *s;
1183
1184 s = zclient->obuf;
1185 stream_reset(s);
1186
1187 zclient_create_header(s, command, vrf_id);
1188 stream_putc(s, afi);
1189 stream_putc(s, type);
1190 stream_putw(s, instance);
1191
1192 stream_putw_at(s, 0, stream_get_endp(s));
1193
1194 return zclient_send_message(zclient);
718e3744 1195}
1196
d9178828 1197/* Get prefix in ZServ format; family should be filled in on prefix */
d62a17ae 1198static void zclient_stream_get_prefix(struct stream *s, struct prefix *p)
d9178828 1199{
d62a17ae 1200 size_t plen = prefix_blen(p);
1201 u_char c;
1202 p->prefixlen = 0;
1203
1204 if (plen == 0)
1205 return;
1206
1207 stream_get(&p->u.prefix, s, plen);
ec93aa12 1208 STREAM_GETC(s, c);
d62a17ae 1209 p->prefixlen = MIN(plen * 8, c);
ec93aa12
DS
1210
1211stream_failure:
1212 return;
d9178828
PJ
1213}
1214
18a6dce6 1215/* Router-id update from zebra daemon. */
d62a17ae 1216void zebra_router_id_update_read(struct stream *s, struct prefix *rid)
18a6dce6 1217{
d62a17ae 1218 /* Fetch interface address. */
ec93aa12 1219 STREAM_GETC(s, rid->family);
d62a17ae 1220
1221 zclient_stream_get_prefix(s, rid);
ec93aa12
DS
1222
1223stream_failure:
1224 return;
18a6dce6 1225}
1226
718e3744 1227/* Interface addition from zebra daemon. */
d62a17ae 1228/*
0a589359 1229 * The format of the message sent with type ZEBRA_INTERFACE_ADD or
1230 * ZEBRA_INTERFACE_DELETE from zebra to the client is:
1231 * 0 1 2 3
1232 * 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
0a589359 1233 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1234 * | ifname |
1235 * | |
1236 * | |
1237 * | |
1238 * | |
1239 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
1240 * | ifindex |
1241 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1242 * | status |
0a589359 1243 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee 1244 * | if_flags |
c77d4546 1245 * | |
0a589359 1246 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
1247 * | metric |
1248 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2d7f0d76
DS
1249 * | speed |
1250 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
1251 * | ifmtu |
1252 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1253 * | ifmtu6 |
1254 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1255 * | bandwidth |
1256 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1257 * | Link Layer Type |
0a589359 1258 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee 1259 * | Harware Address Length |
0a589359 1260 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
1261 * | Hardware Address if HW lenght different from 0 |
1262 * | ... max INTERFACE_HWADDR_MAX |
0a589359 1263 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee 1264 * | Link_params? | Whether a link-params follows: 1 or 0.
0a589359 1265 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
16f1b9ee
OD
1266 * | Link_params 0 or 1 INTERFACE_LINK_PARAMS_SIZE sized |
1267 * | .... (struct if_link_params). |
0a589359 1268 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1269 */
1270
d62a17ae 1271static void zclient_vrf_add(struct zclient *zclient, vrf_id_t vrf_id)
1892f15e 1272{
d62a17ae 1273 struct vrf *vrf;
1274 char vrfname_tmp[VRF_NAMSIZ];
1275 struct vrf_data data;
1892f15e 1276
d62a17ae 1277 stream_get(&data, zclient->ibuf, sizeof(struct vrf_data));
1278 /* Read interface name. */
1279 stream_get(vrfname_tmp, zclient->ibuf, VRF_NAMSIZ);
1892f15e 1280
d62a17ae 1281 /* Lookup/create vrf by vrf_id. */
1282 vrf = vrf_get(vrf_id, vrfname_tmp);
1283 vrf->data = data;
1892f15e 1284
d62a17ae 1285 vrf_enable(vrf);
1892f15e
DS
1286}
1287
d62a17ae 1288static void zclient_vrf_delete(struct zclient *zclient, vrf_id_t vrf_id)
1892f15e 1289{
d62a17ae 1290 struct vrf *vrf;
1892f15e 1291
d62a17ae 1292 /* Lookup vrf by vrf_id. */
1293 vrf = vrf_lookup_by_id(vrf_id);
1892f15e 1294
d62a17ae 1295 /*
1296 * If a routing protocol doesn't know about a
1297 * vrf that is about to be deleted. There is
1298 * no point in attempting to delete it.
1299 */
1300 if (!vrf)
1301 return;
beef1990 1302
d62a17ae 1303 vrf_delete(vrf);
1892f15e
DS
1304}
1305
d62a17ae 1306struct interface *zebra_interface_add_read(struct stream *s, vrf_id_t vrf_id)
718e3744 1307{
d62a17ae 1308 struct interface *ifp;
1309 char ifname_tmp[INTERFACE_NAMSIZ];
718e3744 1310
d62a17ae 1311 /* Read interface name. */
1312 stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
718e3744 1313
d62a17ae 1314 /* Lookup/create interface by name. */
bcc24579 1315 ifp = if_get_by_name(ifname_tmp, vrf_id, 0);
718e3744 1316
d62a17ae 1317 zebra_interface_if_set_value(s, ifp);
718e3744 1318
d62a17ae 1319 return ifp;
718e3744 1320}
1321
d62a17ae 1322/*
0a589359 1323 * Read interface up/down msg (ZEBRA_INTERFACE_UP/ZEBRA_INTERFACE_DOWN)
1324 * from zebra server. The format of this message is the same as
1325 * that sent for ZEBRA_INTERFACE_ADD/ZEBRA_INTERFACE_DELETE (see
1326 * comments for zebra_interface_add_read), except that no sockaddr_dl
1327 * is sent at the tail of the message.
1328 */
d62a17ae 1329struct interface *zebra_interface_state_read(struct stream *s, vrf_id_t vrf_id)
718e3744 1330{
d62a17ae 1331 struct interface *ifp;
1332 char ifname_tmp[INTERFACE_NAMSIZ];
1333
1334 /* Read interface name. */
1335 stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
1336
1337 /* Lookup this by interface index. */
bcc24579 1338 ifp = if_lookup_by_name(ifname_tmp, vrf_id);
d62a17ae 1339 if (ifp == NULL) {
1340 zlog_warn("INTERFACE_STATE: Cannot find IF %s in VRF %d",
1341 ifname_tmp, vrf_id);
1342 return NULL;
1343 }
1344
1345 zebra_interface_if_set_value(s, ifp);
1346
1347 return ifp;
718e3744 1348}
1349
d62a17ae 1350static void link_params_set_value(struct stream *s, struct if_link_params *iflp)
16f1b9ee
OD
1351{
1352
d62a17ae 1353 if (iflp == NULL)
1354 return;
1355
1356 iflp->lp_status = stream_getl(s);
1357 iflp->te_metric = stream_getl(s);
1358 iflp->max_bw = stream_getf(s);
1359 iflp->max_rsv_bw = stream_getf(s);
1360 uint32_t bwclassnum = stream_getl(s);
1361 {
1362 unsigned int i;
1363 for (i = 0; i < bwclassnum && i < MAX_CLASS_TYPE; i++)
1364 iflp->unrsv_bw[i] = stream_getf(s);
1365 if (i < bwclassnum)
1366 zlog_err(
1367 "%s: received %d > %d (MAX_CLASS_TYPE) bw entries"
1368 " - outdated library?",
1369 __func__, bwclassnum, MAX_CLASS_TYPE);
1370 }
1371 iflp->admin_grp = stream_getl(s);
1372 iflp->rmt_as = stream_getl(s);
1373 iflp->rmt_ip.s_addr = stream_get_ipv4(s);
1374
1375 iflp->av_delay = stream_getl(s);
1376 iflp->min_delay = stream_getl(s);
1377 iflp->max_delay = stream_getl(s);
1378 iflp->delay_var = stream_getl(s);
1379
1380 iflp->pkt_loss = stream_getf(s);
1381 iflp->res_bw = stream_getf(s);
1382 iflp->ava_bw = stream_getf(s);
1383 iflp->use_bw = stream_getf(s);
16f1b9ee
OD
1384}
1385
d62a17ae 1386struct interface *zebra_interface_link_params_read(struct stream *s)
16f1b9ee 1387{
d62a17ae 1388 struct if_link_params *iflp;
1389 ifindex_t ifindex;
c28e5b2a 1390
d62a17ae 1391 assert(s);
c28e5b2a 1392
d62a17ae 1393 ifindex = stream_getl(s);
16f1b9ee 1394
d62a17ae 1395 struct interface *ifp = if_lookup_by_index(ifindex, VRF_DEFAULT);
16f1b9ee 1396
d62a17ae 1397 if (ifp == NULL) {
1398 zlog_err("%s: unknown ifindex %u, shouldn't happen", __func__,
1399 ifindex);
1400 return NULL;
1401 }
16f1b9ee 1402
d62a17ae 1403 if ((iflp = if_link_params_get(ifp)) == NULL)
1404 return NULL;
16f1b9ee 1405
d62a17ae 1406 link_params_set_value(s, iflp);
16f1b9ee 1407
d62a17ae 1408 return ifp;
16f1b9ee
OD
1409}
1410
d62a17ae 1411void zebra_interface_if_set_value(struct stream *s, struct interface *ifp)
16f1b9ee 1412{
d62a17ae 1413 u_char link_params_status = 0;
1414
1415 /* Read interface's index. */
ff880b78 1416 if_set_index(ifp, stream_getl(s));
d62a17ae 1417 ifp->status = stream_getc(s);
1418
1419 /* Read interface's value. */
1420 ifp->flags = stream_getq(s);
1421 ifp->ptm_enable = stream_getc(s);
1422 ifp->ptm_status = stream_getc(s);
1423 ifp->metric = stream_getl(s);
1424 ifp->speed = stream_getl(s);
1425 ifp->mtu = stream_getl(s);
1426 ifp->mtu6 = stream_getl(s);
1427 ifp->bandwidth = stream_getl(s);
1428 ifp->ll_type = stream_getl(s);
1429 ifp->hw_addr_len = stream_getl(s);
1430 if (ifp->hw_addr_len)
1431 stream_get(ifp->hw_addr, s,
1432 MIN(ifp->hw_addr_len, INTERFACE_HWADDR_MAX));
1433
1434 /* Read Traffic Engineering status */
1435 link_params_status = stream_getc(s);
1436 /* Then, Traffic Engineering parameters if any */
1437 if (link_params_status) {
1438 struct if_link_params *iflp = if_link_params_get(ifp);
1439 link_params_set_value(s, iflp);
1440 }
16f1b9ee
OD
1441}
1442
d62a17ae 1443size_t zebra_interface_link_params_write(struct stream *s,
1444 struct interface *ifp)
16f1b9ee 1445{
d62a17ae 1446 size_t w;
1447 struct if_link_params *iflp;
1448 int i;
16f1b9ee 1449
d62a17ae 1450 if (s == NULL || ifp == NULL || ifp->link_params == NULL)
1451 return 0;
16f1b9ee 1452
d62a17ae 1453 iflp = ifp->link_params;
1454 w = 0;
16f1b9ee 1455
d62a17ae 1456 w += stream_putl(s, iflp->lp_status);
16f1b9ee 1457
d62a17ae 1458 w += stream_putl(s, iflp->te_metric);
1459 w += stream_putf(s, iflp->max_bw);
1460 w += stream_putf(s, iflp->max_rsv_bw);
16f1b9ee 1461
d62a17ae 1462 w += stream_putl(s, MAX_CLASS_TYPE);
1463 for (i = 0; i < MAX_CLASS_TYPE; i++)
1464 w += stream_putf(s, iflp->unrsv_bw[i]);
16f1b9ee 1465
d62a17ae 1466 w += stream_putl(s, iflp->admin_grp);
1467 w += stream_putl(s, iflp->rmt_as);
1468 w += stream_put_in_addr(s, &iflp->rmt_ip);
16f1b9ee 1469
d62a17ae 1470 w += stream_putl(s, iflp->av_delay);
1471 w += stream_putl(s, iflp->min_delay);
1472 w += stream_putl(s, iflp->max_delay);
1473 w += stream_putl(s, iflp->delay_var);
16f1b9ee 1474
d62a17ae 1475 w += stream_putf(s, iflp->pkt_loss);
1476 w += stream_putf(s, iflp->res_bw);
1477 w += stream_putf(s, iflp->ava_bw);
1478 w += stream_putf(s, iflp->use_bw);
16f1b9ee 1479
d62a17ae 1480 return w;
16f1b9ee
OD
1481}
1482
1483/*
0a589359 1484 * format of message for address additon is:
1485 * 0
1486 * 0 1 2 3 4 5 6 7
1487 * +-+-+-+-+-+-+-+-+
1488 * | type | ZEBRA_INTERFACE_ADDRESS_ADD or
1489 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_ADDRES_DELETE
1490 * | |
1491 * + +
1492 * | ifindex |
1493 * + +
1494 * | |
1495 * + +
1496 * | |
1497 * +-+-+-+-+-+-+-+-+
1498 * | ifc_flags | flags for connected address
1499 * +-+-+-+-+-+-+-+-+
1500 * | addr_family |
1501 * +-+-+-+-+-+-+-+-+
1502 * | addr... |
1503 * : :
1504 * | |
1505 * +-+-+-+-+-+-+-+-+
1506 * | addr_len | len of addr. E.g., addr_len = 4 for ipv4 addrs.
1507 * +-+-+-+-+-+-+-+-+
1508 * | daddr.. |
1509 * : :
1510 * | |
1511 * +-+-+-+-+-+-+-+-+
0a589359 1512 */
1513
d62a17ae 1514static int memconstant(const void *s, int c, size_t n)
3fb9cd6e 1515{
d62a17ae 1516 const u_char *p = s;
3fb9cd6e 1517
d62a17ae 1518 while (n-- > 0)
1519 if (*p++ != c)
1520 return 0;
1521 return 1;
3fb9cd6e 1522}
1523
d5a5c8f0 1524
d62a17ae 1525struct connected *zebra_interface_address_read(int type, struct stream *s,
1526 vrf_id_t vrf_id)
718e3744 1527{
d62a17ae 1528 ifindex_t ifindex;
1529 struct interface *ifp;
1530 struct connected *ifc;
1531 struct prefix p, d, *dp;
1532 int plen;
1533 u_char ifc_flags;
1534
1535 memset(&p, 0, sizeof(p));
1536 memset(&d, 0, sizeof(d));
1537
1538 /* Get interface index. */
1539 ifindex = stream_getl(s);
1540
1541 /* Lookup index. */
1542 ifp = if_lookup_by_index(ifindex, vrf_id);
1543 if (ifp == NULL) {
1544 zlog_warn("INTERFACE_ADDRESS_%s: Cannot find IF %u in VRF %d",
1545 (type == ZEBRA_INTERFACE_ADDRESS_ADD) ? "ADD" : "DEL",
1546 ifindex, vrf_id);
1547 return NULL;
1548 }
1549
1550 /* Fetch flag. */
1551 ifc_flags = stream_getc(s);
1552
1553 /* Fetch interface address. */
1554 d.family = p.family = stream_getc(s);
1555 plen = prefix_blen(&d);
1556
1557 zclient_stream_get_prefix(s, &p);
1558
1559 /* Fetch destination address. */
1560 stream_get(&d.u.prefix, s, plen);
1561
1562 /* N.B. NULL destination pointers are encoded as all zeroes */
1563 dp = memconstant(&d.u.prefix, 0, plen) ? NULL : &d;
1564
1565 if (type == ZEBRA_INTERFACE_ADDRESS_ADD) {
1566 ifc = connected_lookup_prefix_exact(ifp, &p);
1567 if (!ifc) {
1568 /* N.B. NULL destination pointers are encoded as all
1569 * zeroes */
1570 ifc = connected_add_by_prefix(ifp, &p, dp);
1571 }
1572 if (ifc) {
1573 ifc->flags = ifc_flags;
1574 if (ifc->destination)
1575 ifc->destination->prefixlen =
1576 ifc->address->prefixlen;
1577 else if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER)) {
1578 /* carp interfaces on OpenBSD with 0.0.0.0/0 as
1579 * "peer" */
1580 char buf[PREFIX_STRLEN];
1581 zlog_warn(
1582 "warning: interface %s address %s "
1583 "with peer flag set, but no peer address!",
9d303b37
DL
1584 ifp->name, prefix2str(ifc->address, buf,
1585 sizeof buf));
d62a17ae 1586 UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
1587 }
1588 }
1589 } else {
1590 assert(type == ZEBRA_INTERFACE_ADDRESS_DELETE);
1591 ifc = connected_delete_by_prefix(ifp, &p);
1592 }
1593
1594 return ifc;
718e3744 1595}
0a589359 1596
a80beece
DS
1597/*
1598 * format of message for neighbor connected address is:
1599 * 0
1600 * 0 1 2 3 4 5 6 7
1601 * +-+-+-+-+-+-+-+-+
1602 * | type | ZEBRA_INTERFACE_NBR_ADDRESS_ADD or
1603 * +-+-+-+-+-+-+-+-+ ZEBRA_INTERFACE_NBR_ADDRES_DELETE
1604 * | |
1605 * + +
1606 * | ifindex |
1607 * + +
1608 * | |
1609 * + +
1610 * | |
1611 * +-+-+-+-+-+-+-+-+
1612 * | addr_family |
1613 * +-+-+-+-+-+-+-+-+
1614 * | addr... |
1615 * : :
1616 * | |
1617 * +-+-+-+-+-+-+-+-+
1618 * | addr_len | len of addr.
1619 * +-+-+-+-+-+-+-+-+
1620 */
1621struct nbr_connected *
d62a17ae 1622zebra_interface_nbr_address_read(int type, struct stream *s, vrf_id_t vrf_id)
a80beece 1623{
d62a17ae 1624 unsigned int ifindex;
1625 struct interface *ifp;
1626 struct prefix p;
1627 struct nbr_connected *ifc;
1628
1629 /* Get interface index. */
1630 ifindex = stream_getl(s);
1631
1632 /* Lookup index. */
1633 ifp = if_lookup_by_index(ifindex, vrf_id);
1634 if (ifp == NULL) {
1635 zlog_warn("INTERFACE_NBR_%s: Cannot find IF %u in VRF %d",
1636 (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD) ? "ADD"
1637 : "DELETE",
1638 ifindex, vrf_id);
1639 return NULL;
1640 }
1641
1642 p.family = stream_getc(s);
1643 stream_get(&p.u.prefix, s, prefix_blen(&p));
1644 p.prefixlen = stream_getc(s);
1645
1646 if (type == ZEBRA_INTERFACE_NBR_ADDRESS_ADD) {
1647 /* Currently only supporting P2P links, so any new RA source
1648 address is
1649 considered as the replacement of the previously learnt
1650 Link-Local address. */
1651 if (!(ifc = listnode_head(ifp->nbr_connected))) {
1652 ifc = nbr_connected_new();
1653 ifc->address = prefix_new();
1654 ifc->ifp = ifp;
1655 listnode_add(ifp->nbr_connected, ifc);
1656 }
1657
1658 prefix_copy(ifc->address, &p);
1659 } else {
1660 assert(type == ZEBRA_INTERFACE_NBR_ADDRESS_DELETE);
1661
1662 ifc = nbr_connected_check(ifp, &p);
1663 if (ifc)
1664 listnode_delete(ifp->nbr_connected, ifc);
1665 }
1666
1667 return ifc;
a80beece 1668}
6b0655a2 1669
d62a17ae 1670struct interface *zebra_interface_vrf_update_read(struct stream *s,
1671 vrf_id_t vrf_id,
1672 vrf_id_t *new_vrf_id)
c8e264b6 1673{
d62a17ae 1674 unsigned int ifindex;
1675 struct interface *ifp;
1676 vrf_id_t new_id = VRF_DEFAULT;
1677
1678 /* Get interface index. */
1679 ifindex = stream_getl(s);
1680
1681 /* Lookup interface. */
1682 ifp = if_lookup_by_index(ifindex, vrf_id);
1683 if (ifp == NULL) {
1684 zlog_warn("INTERFACE_VRF_UPDATE: Cannot find IF %u in VRF %d",
1685 ifindex, vrf_id);
1686 return NULL;
1687 }
1688
1689 /* Fetch new VRF Id. */
1690 new_id = stream_getw(s);
1691
1692 *new_vrf_id = new_id;
1693 return ifp;
c8e264b6 1694}
5c7ef8dc 1695
1696/* filter unwanted messages until the expected one arrives */
d62a17ae 1697static int zclient_read_sync_response(struct zclient *zclient,
1698 u_int16_t expected_cmd)
5c7ef8dc 1699{
d62a17ae 1700 struct stream *s;
c31a793b 1701 u_int16_t size = -1;
d62a17ae 1702 u_char marker;
1703 u_char version;
1704 vrf_id_t vrf_id;
1705 u_int16_t cmd;
1706 fd_set readfds;
1707 int ret;
1708
1709 ret = 0;
1710 cmd = expected_cmd + 1;
1711 while (ret == 0 && cmd != expected_cmd) {
1712 s = zclient->ibuf;
1713 stream_reset(s);
1714
1715 /* wait until response arrives */
1716 FD_ZERO(&readfds);
1717 FD_SET(zclient->sock, &readfds);
1718 select(zclient->sock + 1, &readfds, NULL, NULL, NULL);
1719 if (!FD_ISSET(zclient->sock, &readfds))
1720 continue;
1721 /* read response */
1722 ret = zclient_read_header(s, zclient->sock, &size, &marker,
1723 &version, &vrf_id, &cmd);
1724 if (zclient_debug)
1725 zlog_debug("%s: Response (%d bytes) received", __func__,
1726 size);
1727 }
1728 if (ret != 0) {
1729 zlog_err("%s: Invalid Sync Message Reply", __func__);
1730 return -1;
1731 }
1732
1733 return 0;
5c7ef8dc 1734}
fea12efb 1735/**
1736 * Connect to label manager in a syncronous way
1737 *
1738 * It first writes the request to zcient output buffer and then
1739 * immediately reads the answer from the input buffer.
1740 *
1741 * @param zclient Zclient used to connect to label manager (zebra)
1742 * @result Result of response
1743 */
d62a17ae 1744int lm_label_manager_connect(struct zclient *zclient)
fea12efb 1745{
d62a17ae 1746 int ret;
1747 struct stream *s;
1748 u_char result;
1749
1750 if (zclient_debug)
1751 zlog_debug("Connecting to Label Manager");
1752
1753 if (zclient->sock < 0)
1754 return -1;
1755
1756 /* send request */
1757 s = zclient->obuf;
1758 stream_reset(s);
1759 zclient_create_header(s, ZEBRA_LABEL_MANAGER_CONNECT, VRF_DEFAULT);
1760
1761 /* proto */
1762 stream_putc(s, zclient->redist_default);
1763 /* instance */
1764 stream_putw(s, zclient->instance);
1765
1766 /* Put length at the first point of the stream. */
1767 stream_putw_at(s, 0, stream_get_endp(s));
1768
1769 ret = writen(zclient->sock, s->data, stream_get_endp(s));
1770 if (ret < 0) {
1771 zlog_err("%s: can't write to zclient->sock", __func__);
1772 close(zclient->sock);
1773 zclient->sock = -1;
1774 return -1;
1775 }
1776 if (ret == 0) {
1777 zlog_err("%s: zclient->sock connection closed", __func__);
1778 close(zclient->sock);
1779 zclient->sock = -1;
1780 return -1;
1781 }
1782 if (zclient_debug)
1783 zlog_debug("%s: Label manager connect request (%d bytes) sent",
1784 __func__, ret);
1785
1786 /* read response */
1787 if (zclient_read_sync_response(zclient, ZEBRA_LABEL_MANAGER_CONNECT)
1788 != 0)
1789 return -1;
1790
1791 /* result */
1792 s = zclient->ibuf;
1793 result = stream_getc(s);
1794 if (zclient_debug)
1795 zlog_debug(
1796 "%s: Label Manager connect response received, result %u",
1797 __func__, result);
1798
1799 return (int)result;
fea12efb 1800}
1801
1802/**
1803 * Function to request a label chunk in a syncronous way
1804 *
1805 * It first writes the request to zlcient output buffer and then
1806 * immediately reads the answer from the input buffer.
1807 *
1808 * @param zclient Zclient used to connect to label manager (zebra)
1809 * @param keep Avoid garbage collection
1810 * @param chunk_size Amount of labels requested
1811 * @param start To write first assigned chunk label to
1812 * @param end To write last assigned chunk label to
1813 * @result 0 on success, -1 otherwise
1814 */
d62a17ae 1815int lm_get_label_chunk(struct zclient *zclient, u_char keep,
1816 uint32_t chunk_size, uint32_t *start, uint32_t *end)
fea12efb 1817{
d62a17ae 1818 int ret;
1819 struct stream *s;
1820 u_char response_keep;
1821
1822 if (zclient_debug)
1823 zlog_debug("Getting Label Chunk");
1824
1825 if (zclient->sock < 0)
1826 return -1;
1827
1828 /* send request */
1829 s = zclient->obuf;
1830 stream_reset(s);
1831 zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, VRF_DEFAULT);
1832 /* keep */
1833 stream_putc(s, keep);
1834 /* chunk size */
1835 stream_putl(s, chunk_size);
1836 /* Put length at the first point of the stream. */
1837 stream_putw_at(s, 0, stream_get_endp(s));
1838
1839 ret = writen(zclient->sock, s->data, stream_get_endp(s));
1840 if (ret < 0) {
1841 zlog_err("%s: can't write to zclient->sock", __func__);
1842 close(zclient->sock);
1843 zclient->sock = -1;
1844 return -1;
1845 }
1846 if (ret == 0) {
1847 zlog_err("%s: zclient->sock connection closed", __func__);
1848 close(zclient->sock);
1849 zclient->sock = -1;
1850 return -1;
1851 }
1852 if (zclient_debug)
1853 zlog_debug("%s: Label chunk request (%d bytes) sent", __func__,
1854 ret);
1855
1856 /* read response */
1857 if (zclient_read_sync_response(zclient, ZEBRA_GET_LABEL_CHUNK) != 0)
1858 return -1;
1859
1860 s = zclient->ibuf;
1861 /* keep */
1862 response_keep = stream_getc(s);
1863 /* start and end labels */
1864 *start = stream_getl(s);
1865 *end = stream_getl(s);
1866
1867 /* not owning this response */
1868 if (keep != response_keep) {
1869 zlog_err(
1870 "%s: Invalid Label chunk: %u - %u, keeps mismatch %u != %u",
1871 __func__, *start, *end, keep, response_keep);
1872 }
1873 /* sanity */
1874 if (*start > *end || *start < MPLS_MIN_UNRESERVED_LABEL
1875 || *end > MPLS_MAX_UNRESERVED_LABEL) {
1876 zlog_err("%s: Invalid Label chunk: %u - %u", __func__, *start,
1877 *end);
1878 return -1;
1879 }
1880
1881 if (zclient_debug)
1882 zlog_debug("Label Chunk assign: %u - %u (%u) ", *start, *end,
1883 response_keep);
1884
1885 return 0;
fea12efb 1886}
1887
1888/**
1889 * Function to release a label chunk
1890 *
1891 * @param zclient Zclient used to connect to label manager (zebra)
1892 * @param start First label of chunk
1893 * @param end Last label of chunk
1894 * @result 0 on success, -1 otherwise
1895 */
d62a17ae 1896int lm_release_label_chunk(struct zclient *zclient, uint32_t start,
1897 uint32_t end)
fea12efb 1898{
d62a17ae 1899 int ret;
1900 struct stream *s;
1901
1902 if (zclient_debug)
1903 zlog_debug("Releasing Label Chunk");
1904
1905 if (zclient->sock < 0)
1906 return -1;
1907
1908 /* send request */
1909 s = zclient->obuf;
1910 stream_reset(s);
1911 zclient_create_header(s, ZEBRA_RELEASE_LABEL_CHUNK, VRF_DEFAULT);
1912
1913 /* start */
1914 stream_putl(s, start);
1915 /* end */
1916 stream_putl(s, end);
1917
1918 /* Put length at the first point of the stream. */
1919 stream_putw_at(s, 0, stream_get_endp(s));
1920
1921 ret = writen(zclient->sock, s->data, stream_get_endp(s));
1922 if (ret < 0) {
1923 zlog_err("%s: can't write to zclient->sock", __func__);
1924 close(zclient->sock);
1925 zclient->sock = -1;
1926 return -1;
1927 }
1928 if (ret == 0) {
1929 zlog_err("%s: zclient->sock connection closed", __func__);
1930 close(zclient->sock);
1931 zclient->sock = -1;
1932 return -1;
1933 }
1934
1935 return 0;
fea12efb 1936}
c8e264b6 1937
6833ae01 1938int zebra_send_pw(struct zclient *zclient, int command, struct zapi_pw *pw)
1939{
1940 struct stream *s;
1941
1942 /* Reset stream. */
1943 s = zclient->obuf;
1944 stream_reset(s);
1945
1946 zclient_create_header(s, command, VRF_DEFAULT);
1947 stream_write(s, pw->ifname, IF_NAMESIZE);
1948 stream_putl(s, pw->ifindex);
1949
1950 /* Put type */
1951 stream_putl(s, pw->type);
1952
1953 /* Put nexthop */
1954 stream_putl(s, pw->af);
1955 switch (pw->af) {
1956 case AF_INET:
1957 stream_put_in_addr(s, &pw->nexthop.ipv4);
1958 break;
1959 case AF_INET6:
1960 stream_write(s, (u_char *)&pw->nexthop.ipv6, 16);
1961 break;
1962 default:
1963 zlog_err("%s: unknown af", __func__);
1964 return -1;
1965 }
1966
1967 /* Put labels */
1968 stream_putl(s, pw->local_label);
1969 stream_putl(s, pw->remote_label);
1970
1971 /* Put flags */
1972 stream_putc(s, pw->flags);
1973
1974 /* Protocol specific fields */
1975 stream_write(s, &pw->data, sizeof(union pw_protocol_fields));
1976
1977 /* Put length at the first point of the stream. */
1978 stream_putw_at(s, 0, stream_get_endp(s));
1979
1980 return zclient_send_message(zclient);
1981}
1982
1983/*
1984 * Receive PW status update from Zebra and send it to LDE process.
1985 */
1986void zebra_read_pw_status_update(int command, struct zclient *zclient,
1987 zebra_size_t length, vrf_id_t vrf_id,
1988 struct zapi_pw_status *pw)
1989{
1990 struct stream *s;
1991
1992 memset(pw, 0, sizeof(struct zapi_pw_status));
1993 s = zclient->ibuf;
1994
1995 /* Get data. */
1996 stream_get(pw->ifname, s, IF_NAMESIZE);
1997 pw->ifindex = stream_getl(s);
1998 pw->status = stream_getl(s);
1999}
2000
718e3744 2001/* Zebra client message read function. */
d62a17ae 2002static int zclient_read(struct thread *thread)
718e3744 2003{
d62a17ae 2004 size_t already;
2005 uint16_t length, command;
2006 uint8_t marker, version;
2007 vrf_id_t vrf_id;
2008 struct zclient *zclient;
2009
2010 /* Get socket to zebra. */
2011 zclient = THREAD_ARG(thread);
2012 zclient->t_read = NULL;
2013
2014 /* Read zebra header (if we don't have it already). */
2015 if ((already = stream_get_endp(zclient->ibuf)) < ZEBRA_HEADER_SIZE) {
2016 ssize_t nbyte;
2017 if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
2018 ZEBRA_HEADER_SIZE - already))
2019 == 0)
2020 || (nbyte == -1)) {
2021 if (zclient_debug)
2022 zlog_debug(
2023 "zclient connection closed socket [%d].",
2024 zclient->sock);
2025 return zclient_failed(zclient);
2026 }
2027 if (nbyte != (ssize_t)(ZEBRA_HEADER_SIZE - already)) {
2028 /* Try again later. */
2029 zclient_event(ZCLIENT_READ, zclient);
2030 return 0;
2031 }
2032 already = ZEBRA_HEADER_SIZE;
634f9ea2 2033 }
d62a17ae 2034
2035 /* Reset to read from the beginning of the incoming packet. */
2036 stream_set_getp(zclient->ibuf, 0);
2037
2038 /* Fetch header values. */
2039 length = stream_getw(zclient->ibuf);
2040 marker = stream_getc(zclient->ibuf);
2041 version = stream_getc(zclient->ibuf);
2042 vrf_id = stream_getw(zclient->ibuf);
2043 command = stream_getw(zclient->ibuf);
2044
2045 if (marker != ZEBRA_HEADER_MARKER || version != ZSERV_VERSION) {
2046 zlog_err(
2047 "%s: socket %d version mismatch, marker %d, version %d",
2048 __func__, zclient->sock, marker, version);
2049 return zclient_failed(zclient);
634f9ea2 2050 }
d62a17ae 2051
2052 if (length < ZEBRA_HEADER_SIZE) {
2053 zlog_err("%s: socket %d message length %u is less than %d ",
2054 __func__, zclient->sock, length, ZEBRA_HEADER_SIZE);
2055 return zclient_failed(zclient);
634f9ea2 2056 }
d62a17ae 2057
2058 /* Length check. */
2059 if (length > STREAM_SIZE(zclient->ibuf)) {
2060 struct stream *ns;
2061 zlog_warn(
2062 "%s: message size %u exceeds buffer size %lu, expanding...",
2063 __func__, length, (u_long)STREAM_SIZE(zclient->ibuf));
2064 ns = stream_new(length);
2065 stream_copy(ns, zclient->ibuf);
2066 stream_free(zclient->ibuf);
2067 zclient->ibuf = ns;
2068 }
2069
2070 /* Read rest of zebra packet. */
2071 if (already < length) {
2072 ssize_t nbyte;
2073 if (((nbyte = stream_read_try(zclient->ibuf, zclient->sock,
2074 length - already))
2075 == 0)
2076 || (nbyte == -1)) {
2077 if (zclient_debug)
2078 zlog_debug(
2079 "zclient connection closed socket [%d].",
2080 zclient->sock);
2081 return zclient_failed(zclient);
2082 }
2083 if (nbyte != (ssize_t)(length - already)) {
2084 /* Try again later. */
2085 zclient_event(ZCLIENT_READ, zclient);
2086 return 0;
2087 }
2088 }
2089
2090 length -= ZEBRA_HEADER_SIZE;
2091
2092 if (zclient_debug)
2093 zlog_debug("zclient 0x%p command 0x%x VRF %u\n",
2094 (void *)zclient, command, vrf_id);
2095
2096 switch (command) {
2097 case ZEBRA_ROUTER_ID_UPDATE:
2098 if (zclient->router_id_update)
2099 (*zclient->router_id_update)(command, zclient, length,
2100 vrf_id);
2101 break;
2102 case ZEBRA_VRF_ADD:
2103 zclient_vrf_add(zclient, vrf_id);
2104 break;
2105 case ZEBRA_VRF_DELETE:
2106 zclient_vrf_delete(zclient, vrf_id);
2107 break;
2108 case ZEBRA_INTERFACE_ADD:
2109 if (zclient->interface_add)
2110 (*zclient->interface_add)(command, zclient, length,
2111 vrf_id);
2112 break;
2113 case ZEBRA_INTERFACE_DELETE:
2114 if (zclient->interface_delete)
2115 (*zclient->interface_delete)(command, zclient, length,
2116 vrf_id);
2117 break;
2118 case ZEBRA_INTERFACE_ADDRESS_ADD:
2119 if (zclient->interface_address_add)
2120 (*zclient->interface_address_add)(command, zclient,
2121 length, vrf_id);
2122 break;
2123 case ZEBRA_INTERFACE_ADDRESS_DELETE:
2124 if (zclient->interface_address_delete)
2125 (*zclient->interface_address_delete)(command, zclient,
2126 length, vrf_id);
2127 break;
2128 case ZEBRA_INTERFACE_BFD_DEST_UPDATE:
2129 if (zclient->interface_bfd_dest_update)
2130 (*zclient->interface_bfd_dest_update)(command, zclient,
2131 length, vrf_id);
2132 break;
2133 case ZEBRA_INTERFACE_NBR_ADDRESS_ADD:
2134 if (zclient->interface_nbr_address_add)
2135 (*zclient->interface_nbr_address_add)(command, zclient,
2136 length, vrf_id);
2137 break;
2138 case ZEBRA_INTERFACE_NBR_ADDRESS_DELETE:
2139 if (zclient->interface_nbr_address_delete)
2140 (*zclient->interface_nbr_address_delete)(
2141 command, zclient, length, vrf_id);
2142 break;
2143 case ZEBRA_INTERFACE_UP:
2144 if (zclient->interface_up)
2145 (*zclient->interface_up)(command, zclient, length,
2146 vrf_id);
2147 break;
2148 case ZEBRA_INTERFACE_DOWN:
2149 if (zclient->interface_down)
2150 (*zclient->interface_down)(command, zclient, length,
2151 vrf_id);
2152 break;
2153 case ZEBRA_INTERFACE_VRF_UPDATE:
2154 if (zclient->interface_vrf_update)
2155 (*zclient->interface_vrf_update)(command, zclient,
2156 length, vrf_id);
2157 break;
2158 case ZEBRA_NEXTHOP_UPDATE:
2159 if (zclient_debug)
2160 zlog_debug("zclient rcvd nexthop update\n");
2161 if (zclient->nexthop_update)
2162 (*zclient->nexthop_update)(command, zclient, length,
2163 vrf_id);
2164 break;
2165 case ZEBRA_IMPORT_CHECK_UPDATE:
2166 if (zclient_debug)
2167 zlog_debug("zclient rcvd import check update\n");
2168 if (zclient->import_check_update)
2169 (*zclient->import_check_update)(command, zclient,
2170 length, vrf_id);
2171 break;
2172 case ZEBRA_BFD_DEST_REPLAY:
2173 if (zclient->bfd_dest_replay)
2174 (*zclient->bfd_dest_replay)(command, zclient, length,
2175 vrf_id);
2176 break;
74489921
RW
2177 case ZEBRA_REDISTRIBUTE_ROUTE_ADD:
2178 if (zclient->redistribute_route_add)
2179 (*zclient->redistribute_route_add)(command, zclient,
2180 length, vrf_id);
d62a17ae 2181 break;
74489921
RW
2182 case ZEBRA_REDISTRIBUTE_ROUTE_DEL:
2183 if (zclient->redistribute_route_del)
2184 (*zclient->redistribute_route_del)(command, zclient,
2185 length, vrf_id);
d62a17ae 2186 break;
2187 case ZEBRA_INTERFACE_LINK_PARAMS:
2188 if (zclient->interface_link_params)
2189 (*zclient->interface_link_params)(command, zclient,
2190 length);
2191 break;
2192 case ZEBRA_FEC_UPDATE:
2193 if (zclient_debug)
2194 zlog_debug("zclient rcvd fec update\n");
2195 if (zclient->fec_update)
2196 (*zclient->fec_update)(command, zclient, length);
2197 break;
2198 case ZEBRA_VNI_ADD:
2199 if (zclient->local_vni_add)
2200 (*zclient->local_vni_add)(command, zclient, length,
2201 vrf_id);
2202 break;
2203 case ZEBRA_VNI_DEL:
2204 if (zclient->local_vni_del)
2205 (*zclient->local_vni_del)(command, zclient, length,
2206 vrf_id);
2207 break;
2208 case ZEBRA_MACIP_ADD:
2209 if (zclient->local_macip_add)
2210 (*zclient->local_macip_add)(command, zclient, length,
2211 vrf_id);
2212 break;
2213 case ZEBRA_MACIP_DEL:
2214 if (zclient->local_macip_del)
2215 (*zclient->local_macip_del)(command, zclient, length,
2216 vrf_id);
2217 break;
6833ae01 2218 case ZEBRA_PW_STATUS_UPDATE:
2219 if (zclient->pw_status_update)
2220 (*zclient->pw_status_update)(command, zclient, length,
2221 vrf_id);
2222 break;
7ea7b86e
DS
2223 case ZEBRA_ROUTE_NOTIFY_OWNER:
2224 if (zclient->notify_owner)
2225 (*zclient->notify_owner)(command, zclient,
2226 length, vrf_id);
2227 break;
d62a17ae 2228 default:
2229 break;
634f9ea2 2230 }
d62a17ae 2231
2232 if (zclient->sock < 0)
2233 /* Connection was closed during packet processing. */
2234 return -1;
2235
2236 /* Register read thread. */
2237 stream_reset(zclient->ibuf);
2238 zclient_event(ZCLIENT_READ, zclient);
2239
2240 return 0;
718e3744 2241}
2242
d62a17ae 2243void zclient_redistribute(int command, struct zclient *zclient, afi_t afi,
2244 int type, u_short instance, vrf_id_t vrf_id)
718e3744 2245{
718e3744 2246
d62a17ae 2247 if (instance) {
2248 if (command == ZEBRA_REDISTRIBUTE_ADD) {
2249 if (redist_check_instance(
2250 &zclient->mi_redist[afi][type], instance))
2251 return;
2252 redist_add_instance(&zclient->mi_redist[afi][type],
2253 instance);
2254 } else {
2255 if (!redist_check_instance(
2256 &zclient->mi_redist[afi][type], instance))
2257 return;
2258 redist_del_instance(&zclient->mi_redist[afi][type],
2259 instance);
2260 }
2261
2262 } else {
2263 if (command == ZEBRA_REDISTRIBUTE_ADD) {
2264 if (vrf_bitmap_check(zclient->redist[afi][type],
2265 vrf_id))
2266 return;
2267 vrf_bitmap_set(zclient->redist[afi][type], vrf_id);
2268 } else {
2269 if (!vrf_bitmap_check(zclient->redist[afi][type],
2270 vrf_id))
2271 return;
2272 vrf_bitmap_unset(zclient->redist[afi][type], vrf_id);
2273 }
2274 }
2275
2276 if (zclient->sock > 0)
2277 zebra_redistribute_send(command, zclient, afi, type, instance,
2278 vrf_id);
718e3744 2279}
2280
718e3744 2281
d62a17ae 2282void zclient_redistribute_default(int command, struct zclient *zclient,
2283 vrf_id_t vrf_id)
718e3744 2284{
718e3744 2285
d62a17ae 2286 if (command == ZEBRA_REDISTRIBUTE_DEFAULT_ADD) {
2287 if (vrf_bitmap_check(zclient->default_information, vrf_id))
2288 return;
2289 vrf_bitmap_set(zclient->default_information, vrf_id);
2290 } else {
2291 if (!vrf_bitmap_check(zclient->default_information, vrf_id))
2292 return;
2293 vrf_bitmap_unset(zclient->default_information, vrf_id);
2294 }
2295
2296 if (zclient->sock > 0)
2297 zebra_message_send(zclient, command, vrf_id);
718e3744 2298}
2299
d62a17ae 2300static void zclient_event(enum event event, struct zclient *zclient)
718e3744 2301{
d62a17ae 2302 switch (event) {
2303 case ZCLIENT_SCHEDULE:
2304 thread_add_event(zclient->master, zclient_connect, zclient, 0,
2305 &zclient->t_connect);
2306 break;
2307 case ZCLIENT_CONNECT:
2308 if (zclient_debug)
2309 zlog_debug(
2310 "zclient connect failures: %d schedule interval is now %d",
2311 zclient->fail, zclient->fail < 3 ? 10 : 60);
2312 thread_add_timer(zclient->master, zclient_connect, zclient,
2313 zclient->fail < 3 ? 10 : 60,
2314 &zclient->t_connect);
2315 break;
2316 case ZCLIENT_READ:
2317 zclient->t_read = NULL;
2318 thread_add_read(zclient->master, zclient_read, zclient,
2319 zclient->sock, &zclient->t_read);
2320 break;
2321 }
718e3744 2322}
b5114685 2323
e0ae31b8
DS
2324void zclient_interface_set_master(struct zclient *client,
2325 struct interface *master,
2326 struct interface *slave)
2327{
2328 struct stream *s;
2329
2330 s = client->obuf;
2331 stream_reset(s);
2332
2333 zclient_create_header(s, ZEBRA_INTERFACE_SET_MASTER, master->vrf_id);
2334
2335 stream_putw(s, master->vrf_id);
2336 stream_putl(s, master->ifindex);
2337 stream_putw(s, slave->vrf_id);
2338 stream_putl(s, slave->ifindex);
2339
2340 stream_putw_at(s, 0, stream_get_endp(s));
2341 zclient_send_message(client);
2342}