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