]> git.proxmox.com Git - mirror_frr.git/blob - ldpd/ldp_zebra.c
Merge pull request #12698 from Orange-OpenSource/isisd
[mirror_frr.git] / ldpd / ldp_zebra.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (C) 2016 by Open Source Routing.
4 */
5
6 #include <zebra.h>
7
8 #include "prefix.h"
9 #include "stream.h"
10 #include "memory.h"
11 #include "zclient.h"
12 #include "command.h"
13 #include "network.h"
14 #include "linklist.h"
15 #include "mpls.h"
16
17 #include "ldpd.h"
18 #include "ldpe.h"
19 #include "lde.h"
20 #include "ldp_sync.h"
21 #include "log.h"
22 #include "ldp_debug.h"
23
24 static void ifp2kif(struct interface *, struct kif *);
25 static void ifc2kaddr(struct interface *, struct connected *,
26 struct kaddr *);
27 static int ldp_zebra_send_mpls_labels(int, struct kroute *);
28 static int ldp_router_id_update(ZAPI_CALLBACK_ARGS);
29 static int ldp_interface_address_add(ZAPI_CALLBACK_ARGS);
30 static int ldp_interface_address_delete(ZAPI_CALLBACK_ARGS);
31 static int ldp_zebra_read_route(ZAPI_CALLBACK_ARGS);
32 static int ldp_zebra_read_pw_status_update(ZAPI_CALLBACK_ARGS);
33 static void ldp_zebra_connected(struct zclient *);
34 static void ldp_zebra_filter_update(struct access_list *access);
35
36 static void ldp_zebra_opaque_register(void);
37 static void ldp_zebra_opaque_unregister(void);
38 static int ldp_sync_zebra_send_announce(void);
39 static int ldp_zebra_opaque_msg_handler(ZAPI_CALLBACK_ARGS);
40 static void ldp_sync_zebra_init(void);
41
42 static struct zclient *zclient;
43 static bool zebra_registered = false;
44
45 static void
46 ifp2kif(struct interface *ifp, struct kif *kif)
47 {
48 memset(kif, 0, sizeof(*kif));
49 strlcpy(kif->ifname, ifp->name, sizeof(kif->ifname));
50 kif->ifindex = ifp->ifindex;
51 kif->operative = if_is_operative(ifp);
52 if (ifp->ll_type == ZEBRA_LLT_ETHER)
53 memcpy(kif->mac, ifp->hw_addr, ETH_ALEN);
54 }
55
56 static void
57 ifc2kaddr(struct interface *ifp, struct connected *ifc, struct kaddr *ka)
58 {
59 memset(ka, 0, sizeof(*ka));
60 strlcpy(ka->ifname, ifp->name, sizeof(ka->ifname));
61 ka->ifindex = ifp->ifindex;
62 ka->af = ifc->address->family;
63 ka->prefixlen = ifc->address->prefixlen;
64
65 switch (ka->af) {
66 case AF_INET:
67 ka->addr.v4 = ifc->address->u.prefix4;
68 if (ifc->destination)
69 ka->dstbrd.v4 = ifc->destination->u.prefix4;
70 break;
71 case AF_INET6:
72 ka->addr.v6 = ifc->address->u.prefix6;
73 if (ifc->destination)
74 ka->dstbrd.v6 = ifc->destination->u.prefix6;
75 break;
76 default:
77 break;
78 }
79 }
80
81 void
82 pw2zpw(struct l2vpn_pw *pw, struct zapi_pw *zpw)
83 {
84 memset(zpw, 0, sizeof(*zpw));
85 strlcpy(zpw->ifname, pw->ifname, sizeof(zpw->ifname));
86 zpw->ifindex = pw->ifindex;
87 zpw->type = pw->l2vpn->pw_type;
88 zpw->af = pw->af;
89 zpw->nexthop.ipv6 = pw->addr.v6;
90 zpw->local_label = NO_LABEL;
91 zpw->remote_label = NO_LABEL;
92 if (CHECK_FLAG(pw->flags, F_PW_CWORD))
93 zpw->flags = F_PSEUDOWIRE_CWORD;
94 zpw->data.ldp.lsr_id = pw->lsr_id;
95 zpw->data.ldp.pwid = pw->pwid;
96 strlcpy(zpw->data.ldp.vpn_name, pw->l2vpn->name,
97 sizeof(zpw->data.ldp.vpn_name));
98 }
99
100 static void
101 ldp_zebra_opaque_register(void)
102 {
103 zclient_register_opaque(zclient, LDP_IGP_SYNC_IF_STATE_REQUEST);
104 zclient_register_opaque(zclient, LDP_RLFA_REGISTER);
105 zclient_register_opaque(zclient, LDP_RLFA_UNREGISTER_ALL);
106 }
107
108 static void
109 ldp_zebra_opaque_unregister(void)
110 {
111 zclient_unregister_opaque(zclient, LDP_IGP_SYNC_IF_STATE_REQUEST);
112 zclient_unregister_opaque(zclient, LDP_RLFA_REGISTER);
113 zclient_unregister_opaque(zclient, LDP_RLFA_UNREGISTER_ALL);
114 }
115
116 int
117 ldp_sync_zebra_send_state_update(struct ldp_igp_sync_if_state *state)
118 {
119 if (zclient_send_opaque(zclient, LDP_IGP_SYNC_IF_STATE_UPDATE,
120 (const uint8_t *)state, sizeof(*state))
121 == ZCLIENT_SEND_FAILURE)
122 return -1;
123 else
124 return 0;
125 }
126
127 static int
128 ldp_sync_zebra_send_announce(void)
129 {
130 struct ldp_igp_sync_announce announce;
131 announce.proto = ZEBRA_ROUTE_LDP;
132
133 if (zclient_send_opaque(zclient, LDP_IGP_SYNC_ANNOUNCE_UPDATE,
134 (const uint8_t *)&announce, sizeof(announce))
135 == ZCLIENT_SEND_FAILURE)
136 return -1;
137 else
138 return 0;
139 }
140
141 int ldp_zebra_send_rlfa_labels(struct zapi_rlfa_response *rlfa_labels)
142 {
143 int ret;
144
145 ret = zclient_send_opaque(zclient, LDP_RLFA_LABELS,
146 (const uint8_t *)rlfa_labels,
147 sizeof(*rlfa_labels));
148 if (ret == ZCLIENT_SEND_FAILURE) {
149 log_warn("failed to send RLFA labels to IGP");
150 return -1;
151 }
152
153 return 0;
154 }
155
156 static int
157 ldp_zebra_opaque_msg_handler(ZAPI_CALLBACK_ARGS)
158 {
159 struct stream *s;
160 struct zapi_opaque_msg info;
161 struct ldp_igp_sync_if_state_req state_req;
162 struct zapi_rlfa_igp igp;
163 struct zapi_rlfa_request rlfa;
164
165 s = zclient->ibuf;
166
167 if(zclient_opaque_decode(s, &info) != 0)
168 return -1;
169
170 switch (info.type) {
171 case LDP_IGP_SYNC_IF_STATE_REQUEST:
172 STREAM_GET(&state_req, s, sizeof(state_req));
173 main_imsg_compose_ldpe(IMSG_LDP_SYNC_IF_STATE_REQUEST, 0, &state_req,
174 sizeof(state_req));
175 break;
176 case LDP_RLFA_REGISTER:
177 STREAM_GET(&rlfa, s, sizeof(rlfa));
178 main_imsg_compose_both(IMSG_RLFA_REG, &rlfa, sizeof(rlfa));
179 break;
180 case LDP_RLFA_UNREGISTER_ALL:
181 STREAM_GET(&igp, s, sizeof(igp));
182 main_imsg_compose_both(IMSG_RLFA_UNREG_ALL, &igp, sizeof(igp));
183 break;
184 default:
185 break;
186 }
187
188 stream_failure:
189 return 0;
190 }
191
192 static void
193 ldp_sync_zebra_init(void)
194 {
195 ldp_sync_zebra_send_announce();
196 }
197
198 static int
199 ldp_zebra_send_mpls_labels(int cmd, struct kroute *kr)
200 {
201 struct zapi_labels zl = {};
202 struct zapi_nexthop *znh;
203
204 if (kr->local_label < MPLS_LABEL_RESERVED_MAX)
205 return (0);
206
207 debug_zebra_out("prefix %s/%u nexthop %s ifindex %u labels %s/%s (%s)",
208 log_addr(kr->af, &kr->prefix), kr->prefixlen,
209 log_addr(kr->af, &kr->nexthop), kr->ifindex,
210 log_label(kr->local_label), log_label(kr->remote_label),
211 (cmd == ZEBRA_MPLS_LABELS_ADD) ? "add" : "delete");
212
213 zl.type = ZEBRA_LSP_LDP;
214 zl.local_label = kr->local_label;
215
216 /* Set prefix. */
217 if (kr->remote_label != NO_LABEL) {
218 SET_FLAG(zl.message, ZAPI_LABELS_FTN);
219 zl.route.prefix.family = kr->af;
220 switch (kr->af) {
221 case AF_INET:
222 zl.route.prefix.u.prefix4 = kr->prefix.v4;
223 break;
224 case AF_INET6:
225 zl.route.prefix.u.prefix6 = kr->prefix.v6;
226 break;
227 default:
228 fatalx("ldp_zebra_send_mpls_labels: unknown af");
229 }
230 zl.route.prefix.prefixlen = kr->prefixlen;
231 zl.route.type = kr->route_type;
232 zl.route.instance = kr->route_instance;
233 }
234
235 /* If allow-broken-lsps is enabled then if an lsp is received with
236 * no remote label, instruct the forwarding plane to pop the top-level
237 * label and forward packets normally. This is a best-effort attempt
238 * to deliver labeled IP packets to their final destination (instead of
239 * dropping them).
240 */
241 if (kr->remote_label == NO_LABEL
242 && !CHECK_FLAG(ldpd_conf->flags, F_LDPD_ALLOW_BROKEN_LSP)
243 && cmd == ZEBRA_MPLS_LABELS_ADD)
244 return 0;
245
246 if (kr->remote_label == NO_LABEL)
247 kr->remote_label = MPLS_LABEL_IMPLICIT_NULL;
248
249 /* Set nexthop. */
250 zl.nexthop_num = 1;
251 znh = &zl.nexthops[0];
252 switch (kr->af) {
253 case AF_INET:
254 znh->gate.ipv4 = kr->nexthop.v4;
255 if (kr->ifindex)
256 znh->type = NEXTHOP_TYPE_IPV4_IFINDEX;
257 else
258 znh->type = NEXTHOP_TYPE_IPV4;
259 break;
260 case AF_INET6:
261 znh->gate.ipv6 = kr->nexthop.v6;
262 if (kr->ifindex)
263 znh->type = NEXTHOP_TYPE_IPV6_IFINDEX;
264 else
265 znh->type = NEXTHOP_TYPE_IPV6;
266 break;
267 default:
268 break;
269 }
270 znh->ifindex = kr->ifindex;
271 znh->label_num = 1;
272 znh->labels[0] = kr->remote_label;
273
274 if (zebra_send_mpls_labels(zclient, cmd, &zl) == ZCLIENT_SEND_FAILURE)
275 return -1;
276
277 return 0;
278 }
279
280 int
281 kr_change(struct kroute *kr)
282 {
283 return (ldp_zebra_send_mpls_labels(ZEBRA_MPLS_LABELS_ADD, kr));
284 }
285
286 int
287 kr_delete(struct kroute *kr)
288 {
289 return (ldp_zebra_send_mpls_labels(ZEBRA_MPLS_LABELS_DELETE, kr));
290 }
291
292 int
293 kmpw_add(struct zapi_pw *zpw)
294 {
295 debug_zebra_out("pseudowire %s nexthop %s (add)",
296 zpw->ifname, log_addr(zpw->af, (union ldpd_addr *)&zpw->nexthop));
297
298 return zebra_send_pw(zclient, ZEBRA_PW_ADD, zpw)
299 == ZCLIENT_SEND_FAILURE;
300 }
301
302 int
303 kmpw_del(struct zapi_pw *zpw)
304 {
305 debug_zebra_out("pseudowire %s nexthop %s (del)",
306 zpw->ifname, log_addr(zpw->af, (union ldpd_addr *)&zpw->nexthop));
307
308 return zebra_send_pw(zclient, ZEBRA_PW_DELETE, zpw)
309 == ZCLIENT_SEND_FAILURE;
310 }
311
312 int
313 kmpw_set(struct zapi_pw *zpw)
314 {
315 debug_zebra_out("pseudowire %s nexthop %s labels %u/%u (set)",
316 zpw->ifname, log_addr(zpw->af, (union ldpd_addr *)&zpw->nexthop),
317 zpw->local_label, zpw->remote_label);
318
319 return zebra_send_pw(zclient, ZEBRA_PW_SET, zpw)
320 == ZCLIENT_SEND_FAILURE;
321 }
322
323 int
324 kmpw_unset(struct zapi_pw *zpw)
325 {
326 debug_zebra_out("pseudowire %s nexthop %s (unset)",
327 zpw->ifname, log_addr(zpw->af, (union ldpd_addr *)&zpw->nexthop));
328
329 return zebra_send_pw(zclient, ZEBRA_PW_UNSET, zpw)
330 == ZCLIENT_SEND_FAILURE;
331 }
332
333 void
334 kif_redistribute(const char *ifname)
335 {
336 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
337 struct listnode *cnode;
338 struct interface *ifp;
339 struct connected *ifc;
340 struct kif kif;
341 struct kaddr ka;
342
343 FOR_ALL_INTERFACES (vrf, ifp) {
344 if (ifname && strcmp(ifname, ifp->name) != 0)
345 continue;
346
347 ifp2kif(ifp, &kif);
348 main_imsg_compose_both(IMSG_IFSTATUS, &kif, sizeof(kif));
349
350 for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, ifc)) {
351 ifc2kaddr(ifp, ifc, &ka);
352 main_imsg_compose_ldpe(IMSG_NEWADDR, 0, &ka, sizeof(ka));
353 }
354 }
355 }
356
357 static int
358 ldp_router_id_update(ZAPI_CALLBACK_ARGS)
359 {
360 struct prefix router_id;
361
362 zebra_router_id_update_read(zclient->ibuf, &router_id);
363
364 if (bad_addr_v4(router_id.u.prefix4))
365 return (0);
366
367 debug_zebra_in("router-id update %pI4", &router_id.u.prefix4);
368
369 global.rtr_id.s_addr = router_id.u.prefix4.s_addr;
370 main_imsg_compose_ldpe(IMSG_RTRID_UPDATE, 0, &global.rtr_id,
371 sizeof(global.rtr_id));
372
373 return (0);
374 }
375
376 static int
377 ldp_ifp_create(struct interface *ifp)
378 {
379 struct kif kif;
380
381 debug_zebra_in("interface add %s index %d mtu %d", ifp->name,
382 ifp->ifindex, ifp->mtu);
383
384 ifp2kif(ifp, &kif);
385 main_imsg_compose_both(IMSG_IFSTATUS, &kif, sizeof(kif));
386
387 return 0;
388 }
389
390 static int
391 ldp_ifp_destroy(struct interface *ifp)
392 {
393 struct kif kif;
394
395 debug_zebra_in("interface delete %s index %d mtu %d", ifp->name,
396 ifp->ifindex, ifp->mtu);
397
398 ifp2kif(ifp, &kif);
399 main_imsg_compose_both(IMSG_IFSTATUS, &kif, sizeof(kif));
400
401 return (0);
402 }
403
404 static int
405 ldp_interface_status_change(struct interface *ifp)
406 {
407 struct listnode *node;
408 struct connected *ifc;
409 struct kif kif;
410 struct kaddr ka;
411
412 debug_zebra_in("interface %s state update", ifp->name);
413
414 ifp2kif(ifp, &kif);
415 main_imsg_compose_both(IMSG_IFSTATUS, &kif, sizeof(kif));
416
417 if (if_is_operative(ifp)) {
418 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
419 ifc2kaddr(ifp, ifc, &ka);
420 main_imsg_compose_ldpe(IMSG_NEWADDR, 0, &ka, sizeof(ka));
421 }
422 } else {
423 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
424 ifc2kaddr(ifp, ifc, &ka);
425 main_imsg_compose_ldpe(IMSG_DELADDR, 0, &ka, sizeof(ka));
426 }
427 }
428
429 return (0);
430 }
431
432 static int ldp_ifp_up(struct interface *ifp)
433 {
434 return ldp_interface_status_change(ifp);
435 }
436
437 static int ldp_ifp_down(struct interface *ifp)
438 {
439 return ldp_interface_status_change(ifp);
440 }
441
442 static int
443 ldp_interface_address_add(ZAPI_CALLBACK_ARGS)
444 {
445 struct connected *ifc;
446 struct interface *ifp;
447 struct kaddr ka;
448
449 ifc = zebra_interface_address_read(cmd, zclient->ibuf, vrf_id);
450 if (ifc == NULL)
451 return (0);
452
453 ifp = ifc->ifp;
454 ifc2kaddr(ifp, ifc, &ka);
455
456 /* Filter invalid addresses. */
457 if (bad_addr(ka.af, &ka.addr))
458 return (0);
459
460 debug_zebra_in("address add %s/%u interface %s",
461 log_addr(ka.af, &ka.addr), ka.prefixlen, ifp->name);
462
463 /* notify ldpe about new address */
464 main_imsg_compose_ldpe(IMSG_NEWADDR, 0, &ka, sizeof(ka));
465
466 return (0);
467 }
468
469 static int
470 ldp_interface_address_delete(ZAPI_CALLBACK_ARGS)
471 {
472 struct connected *ifc;
473 struct interface *ifp;
474 struct kaddr ka;
475
476 ifc = zebra_interface_address_read(cmd, zclient->ibuf, vrf_id);
477 if (ifc == NULL)
478 return (0);
479
480 ifp = ifc->ifp;
481 ifc2kaddr(ifp, ifc, &ka);
482 connected_free(&ifc);
483
484 /* Filter invalid addresses. */
485 if (bad_addr(ka.af, &ka.addr))
486 return (0);
487
488 debug_zebra_in("address delete %s/%u interface %s",
489 log_addr(ka.af, &ka.addr), ka.prefixlen, ifp->name);
490
491 /* notify ldpe about removed address */
492 main_imsg_compose_ldpe(IMSG_DELADDR, 0, &ka, sizeof(ka));
493
494 return (0);
495 }
496
497 static int
498 ldp_zebra_read_route(ZAPI_CALLBACK_ARGS)
499 {
500 struct zapi_route api;
501 struct zapi_nexthop *api_nh;
502 struct kroute kr;
503 int i, add = 0;
504
505 if (zapi_route_decode(zclient->ibuf, &api) < 0)
506 return -1;
507
508 /* we completely ignore srcdest routes for now. */
509 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX))
510 return (0);
511
512 memset(&kr, 0, sizeof(kr));
513 kr.af = api.prefix.family;
514 switch (kr.af) {
515 case AF_INET:
516 kr.prefix.v4 = api.prefix.u.prefix4;
517 break;
518 case AF_INET6:
519 kr.prefix.v6 = api.prefix.u.prefix6;
520 break;
521 default:
522 break;
523 }
524 kr.prefixlen = api.prefix.prefixlen;
525 kr.route_type = api.type;
526 kr.route_instance = api.instance;
527
528 switch (api.type) {
529 case ZEBRA_ROUTE_CONNECT:
530 SET_FLAG(kr.flags, F_CONNECTED);
531 break;
532 case ZEBRA_ROUTE_BGP:
533 /* LDP should follow the IGP and ignore BGP routes */
534 return (0);
535 default:
536 break;
537 }
538
539 if (bad_addr(kr.af, &kr.prefix) ||
540 (kr.af == AF_INET6 && IN6_IS_SCOPE_EMBED(&kr.prefix.v6)))
541 return (0);
542
543 if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD)
544 add = 1;
545
546 if (api.nexthop_num == 0)
547 debug_zebra_in("route %s %s/%d (%s)", (add) ? "add" : "delete",
548 log_addr(kr.af, &kr.prefix), kr.prefixlen,
549 zebra_route_string(api.type));
550
551 /* loop through all the nexthops */
552 for (i = 0; i < api.nexthop_num; i++) {
553 api_nh = &api.nexthops[i];
554 switch (api_nh->type) {
555 case NEXTHOP_TYPE_IPV4:
556 if (kr.af != AF_INET)
557 continue;
558 kr.nexthop.v4 = api_nh->gate.ipv4;
559 kr.ifindex = 0;
560 break;
561 case NEXTHOP_TYPE_IPV4_IFINDEX:
562 if (kr.af != AF_INET)
563 continue;
564 kr.nexthop.v4 = api_nh->gate.ipv4;
565 kr.ifindex = api_nh->ifindex;
566 break;
567 case NEXTHOP_TYPE_IPV6:
568 if (kr.af != AF_INET6)
569 continue;
570 kr.nexthop.v6 = api_nh->gate.ipv6;
571 kr.ifindex = 0;
572 break;
573 case NEXTHOP_TYPE_IPV6_IFINDEX:
574 if (kr.af != AF_INET6)
575 continue;
576 kr.nexthop.v6 = api_nh->gate.ipv6;
577 kr.ifindex = api_nh->ifindex;
578 break;
579 case NEXTHOP_TYPE_IFINDEX:
580 if (!CHECK_FLAG(kr.flags, F_CONNECTED))
581 continue;
582 break;
583 case NEXTHOP_TYPE_BLACKHOLE:
584 continue;
585 }
586
587 debug_zebra_in("route %s %s/%d nexthop %s ifindex %u (%s)",
588 (add) ? "add" : "delete", log_addr(kr.af, &kr.prefix),
589 kr.prefixlen, log_addr(kr.af, &kr.nexthop), kr.ifindex,
590 zebra_route_string(api.type));
591
592 if (add)
593 main_imsg_compose_lde(IMSG_NETWORK_ADD, 0, &kr, sizeof(kr));
594 }
595
596 main_imsg_compose_lde(IMSG_NETWORK_UPDATE, 0, &kr, sizeof(kr));
597
598 return (0);
599 }
600
601 /*
602 * Receive PW status update from Zebra and send it to LDE process.
603 */
604 static int
605 ldp_zebra_read_pw_status_update(ZAPI_CALLBACK_ARGS)
606 {
607 struct zapi_pw_status zpw;
608
609 zebra_read_pw_status_update(cmd, zclient, length, vrf_id, &zpw);
610
611 debug_zebra_in("pseudowire %s status %s 0x%x", zpw.ifname,
612 (zpw.status == PW_FORWARDING) ? "up" : "down",
613 zpw.status);
614
615 main_imsg_compose_lde(IMSG_PW_UPDATE, 0, &zpw, sizeof(zpw));
616
617 return (0);
618 }
619
620 void ldp_zebra_regdereg_zebra_info(bool want_register)
621 {
622 if (zebra_registered == want_register)
623 return;
624
625 log_debug("%s to receive default VRF information",
626 want_register ? "Register" : "De-register");
627
628 if (want_register) {
629 zclient_send_reg_requests(zclient, VRF_DEFAULT);
630 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP,
631 ZEBRA_ROUTE_ALL, 0, VRF_DEFAULT);
632 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient,
633 AFI_IP6, ZEBRA_ROUTE_ALL, 0,
634 VRF_DEFAULT);
635 } else {
636 zclient_send_dereg_requests(zclient, VRF_DEFAULT);
637 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient,
638 AFI_IP, ZEBRA_ROUTE_ALL, 0,
639 VRF_DEFAULT);
640 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient,
641 AFI_IP6, ZEBRA_ROUTE_ALL, 0,
642 VRF_DEFAULT);
643 }
644 zebra_registered = want_register;
645 }
646
647 static void
648 ldp_zebra_connected(struct zclient *zclient)
649 {
650 zebra_registered = false;
651
652 /* if MPLS was already enabled and we are re-connecting, register again
653 */
654 if (CHECK_FLAG(vty_conf->flags, F_LDPD_ENABLED))
655 ldp_zebra_regdereg_zebra_info(true);
656
657 ldp_zebra_opaque_register();
658
659 ldp_sync_zebra_init();
660 }
661
662 static void
663 ldp_zebra_filter_update(struct access_list *access)
664 {
665 struct ldp_access laccess;
666
667 if (access && access->name[0] != '\0') {
668 strlcpy(laccess.name, access->name, sizeof(laccess.name));
669 debug_evt("%s ACL update filter name %s", __func__, access->name);
670
671 main_imsg_compose_both(IMSG_FILTER_UPDATE, &laccess, sizeof(laccess));
672 }
673 }
674
675 extern struct zebra_privs_t ldpd_privs;
676
677 static zclient_handler *const ldp_handlers[] = {
678 [ZEBRA_ROUTER_ID_UPDATE] = ldp_router_id_update,
679 [ZEBRA_INTERFACE_ADDRESS_ADD] = ldp_interface_address_add,
680 [ZEBRA_INTERFACE_ADDRESS_DELETE] = ldp_interface_address_delete,
681 [ZEBRA_REDISTRIBUTE_ROUTE_ADD] = ldp_zebra_read_route,
682 [ZEBRA_REDISTRIBUTE_ROUTE_DEL] = ldp_zebra_read_route,
683 [ZEBRA_PW_STATUS_UPDATE] = ldp_zebra_read_pw_status_update,
684 [ZEBRA_OPAQUE_MESSAGE] = ldp_zebra_opaque_msg_handler,
685 };
686
687 void ldp_zebra_init(struct event_loop *master)
688 {
689 if_zapi_callbacks(ldp_ifp_create, ldp_ifp_up, ldp_ifp_down, ldp_ifp_destroy);
690
691 /* Set default values. */
692 zclient = zclient_new(master, &zclient_options_default, ldp_handlers,
693 array_size(ldp_handlers));
694 zclient_init(zclient, ZEBRA_ROUTE_LDP, 0, &ldpd_privs);
695
696 /* set callbacks */
697 zclient->zebra_connected = ldp_zebra_connected;
698
699 /* Access list initialize. */
700 access_list_add_hook(ldp_zebra_filter_update);
701 access_list_delete_hook(ldp_zebra_filter_update);
702 }
703
704 void
705 ldp_zebra_destroy(void)
706 {
707 ldp_zebra_opaque_unregister();
708 zclient_stop(zclient);
709 zclient_free(zclient);
710 zclient = NULL;
711 }