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