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