]> git.proxmox.com Git - mirror_frr.git/blame - ldpd/ldp_zebra.c
Merge pull request #12920 from sri-mohan1/sri-mohan-ldp
[mirror_frr.git] / ldpd / ldp_zebra.c
CommitLineData
acddc0ed 1// SPDX-License-Identifier: GPL-2.0-or-later
eac6e3f0
RW
2/*
3 * Copyright (C) 2016 by Open Source Routing.
eac6e3f0
RW
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"
ce549947 15#include "mpls.h"
eac6e3f0
RW
16
17#include "ldpd.h"
18#include "ldpe.h"
19#include "lde.h"
e1894ff7 20#include "ldp_sync.h"
eac6e3f0
RW
21#include "log.h"
22#include "ldp_debug.h"
23
24static void ifp2kif(struct interface *, struct kif *);
25static void ifc2kaddr(struct interface *, struct connected *,
26 struct kaddr *);
bad6b0e7 27static int ldp_zebra_send_mpls_labels(int, struct kroute *);
121f9dee 28static int ldp_router_id_update(ZAPI_CALLBACK_ARGS);
121f9dee
QY
29static int ldp_interface_address_add(ZAPI_CALLBACK_ARGS);
30static int ldp_interface_address_delete(ZAPI_CALLBACK_ARGS);
31static int ldp_zebra_read_route(ZAPI_CALLBACK_ARGS);
32static int ldp_zebra_read_pw_status_update(ZAPI_CALLBACK_ARGS);
eac6e3f0 33static void ldp_zebra_connected(struct zclient *);
2d1aa1e8 34static void ldp_zebra_filter_update(struct access_list *access);
eac6e3f0 35
e1894ff7
KS
36static void ldp_zebra_opaque_register(void);
37static void ldp_zebra_opaque_unregister(void);
38static int ldp_sync_zebra_send_announce(void);
39static int ldp_zebra_opaque_msg_handler(ZAPI_CALLBACK_ARGS);
e1894ff7
KS
40static void ldp_sync_zebra_init(void);
41
eac6e3f0 42static struct zclient *zclient;
ce510d2e 43static bool zebra_registered = false;
eac6e3f0
RW
44
45static void
46ifp2kif(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;
988ded8d 51 kif->operative = if_is_operative(ifp);
26519d8c 52 if (ifp->ll_type == ZEBRA_LLT_ETHER)
9bff8057 53 memcpy(kif->mac, ifp->hw_addr, ETH_ALEN);
eac6e3f0
RW
54}
55
56static void
57ifc2kaddr(struct interface *ifp, struct connected *ifc, struct kaddr *ka)
58{
59 memset(ka, 0, sizeof(*ka));
9cf67225 60 strlcpy(ka->ifname, ifp->name, sizeof(ka->ifname));
eac6e3f0
RW
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
87b5f1b7
RW
81void
82pw2zpw(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 (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
e1894ff7
KS
100static void
101ldp_zebra_opaque_register(void)
102{
103 zclient_register_opaque(zclient, LDP_IGP_SYNC_IF_STATE_REQUEST);
077d336a
RW
104 zclient_register_opaque(zclient, LDP_RLFA_REGISTER);
105 zclient_register_opaque(zclient, LDP_RLFA_UNREGISTER_ALL);
e1894ff7
KS
106}
107
108static void
109ldp_zebra_opaque_unregister(void)
110{
111 zclient_unregister_opaque(zclient, LDP_IGP_SYNC_IF_STATE_REQUEST);
077d336a
RW
112 zclient_unregister_opaque(zclient, LDP_RLFA_REGISTER);
113 zclient_unregister_opaque(zclient, LDP_RLFA_UNREGISTER_ALL);
e1894ff7
KS
114}
115
116int
117ldp_sync_zebra_send_state_update(struct ldp_igp_sync_if_state *state)
118{
7cfdb485
DS
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;
e1894ff7
KS
125}
126
127static int
128ldp_sync_zebra_send_announce(void)
129{
130 struct ldp_igp_sync_announce announce;
131 announce.proto = ZEBRA_ROUTE_LDP;
132
7cfdb485
DS
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;
e1894ff7
KS
139}
140
077d336a
RW
141int 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
e1894ff7
KS
156static int
157ldp_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;
077d336a
RW
162 struct zapi_rlfa_igp igp;
163 struct zapi_rlfa_request rlfa;
e1894ff7
KS
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;
077d336a
RW
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;
e1894ff7
KS
184 default:
185 break;
186 }
187
188stream_failure:
189 return 0;
190}
191
e1894ff7
KS
192static void
193ldp_sync_zebra_init(void)
194{
195 ldp_sync_zebra_send_announce();
e1894ff7
KS
196}
197
ce549947 198static int
bad6b0e7 199ldp_zebra_send_mpls_labels(int cmd, struct kroute *kr)
ce549947 200{
bad6b0e7 201 struct zapi_labels zl = {};
4945002d 202 struct zapi_nexthop *znh;
ce549947 203
8963e0c8 204 if (kr->local_label < MPLS_LABEL_RESERVED_MAX)
ce549947
RW
205 return (0);
206
88d88a9c 207 debug_zebra_out("prefix %s/%u nexthop %s ifindex %u labels %s/%s (%s)",
ce549947 208 log_addr(kr->af, &kr->prefix), kr->prefixlen,
88d88a9c
RW
209 log_addr(kr->af, &kr->nexthop), kr->ifindex,
210 log_label(kr->local_label), log_label(kr->remote_label),
ce549947
RW
211 (cmd == ZEBRA_MPLS_LABELS_ADD) ? "add" : "delete");
212
bad6b0e7 213 zl.type = ZEBRA_LSP_LDP;
b3c49d0e
RW
214 zl.local_label = kr->local_label;
215
216 /* Set prefix. */
8963e0c8
RW
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;
ce549947 233 }
8963e0c8 234
ff5279ba 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
8963e0c8
RW
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 */
ff5279ba 241 if (kr->remote_label == NO_LABEL
242 && !(ldpd_conf->flags & F_LDPD_ALLOW_BROKEN_LSP)
243 && cmd == ZEBRA_MPLS_LABELS_ADD)
244 return 0;
245
8963e0c8
RW
246 if (kr->remote_label == NO_LABEL)
247 kr->remote_label = MPLS_LABEL_IMPLICIT_NULL;
b3c49d0e
RW
248
249 /* Set nexthop. */
ea6b290b
RW
250 zl.nexthop_num = 1;
251 znh = &zl.nexthops[0];
b3c49d0e
RW
252 switch (kr->af) {
253 case AF_INET:
4945002d 254 znh->gate.ipv4 = kr->nexthop.v4;
b3c49d0e 255 if (kr->ifindex)
ea6b290b 256 znh->type = NEXTHOP_TYPE_IPV4_IFINDEX;
b3c49d0e 257 else
ea6b290b 258 znh->type = NEXTHOP_TYPE_IPV4;
b3c49d0e
RW
259 break;
260 case AF_INET6:
4945002d 261 znh->gate.ipv6 = kr->nexthop.v6;
b3c49d0e 262 if (kr->ifindex)
ea6b290b 263 znh->type = NEXTHOP_TYPE_IPV6_IFINDEX;
b3c49d0e 264 else
ea6b290b 265 znh->type = NEXTHOP_TYPE_IPV6;
b3c49d0e
RW
266 break;
267 default:
268 break;
269 }
ea6b290b 270 znh->ifindex = kr->ifindex;
4945002d
MS
271 znh->label_num = 1;
272 znh->labels[0] = kr->remote_label;
ce549947 273
7cfdb485
DS
274 if (zebra_send_mpls_labels(zclient, cmd, &zl) == ZCLIENT_SEND_FAILURE)
275 return -1;
276
277 return 0;
ce549947
RW
278}
279
eac6e3f0
RW
280int
281kr_change(struct kroute *kr)
282{
bad6b0e7 283 return (ldp_zebra_send_mpls_labels(ZEBRA_MPLS_LABELS_ADD, kr));
eac6e3f0
RW
284}
285
286int
287kr_delete(struct kroute *kr)
288{
bad6b0e7 289 return (ldp_zebra_send_mpls_labels(ZEBRA_MPLS_LABELS_DELETE, kr));
eac6e3f0
RW
290}
291
292int
87b5f1b7 293kmpw_add(struct zapi_pw *zpw)
eac6e3f0 294{
87b5f1b7
RW
295 debug_zebra_out("pseudowire %s nexthop %s (add)",
296 zpw->ifname, log_addr(zpw->af, (union ldpd_addr *)&zpw->nexthop));
297
7cfdb485
DS
298 return zebra_send_pw(zclient, ZEBRA_PW_ADD, zpw)
299 == ZCLIENT_SEND_FAILURE;
eac6e3f0
RW
300}
301
302int
87b5f1b7 303kmpw_del(struct zapi_pw *zpw)
eac6e3f0 304{
87b5f1b7
RW
305 debug_zebra_out("pseudowire %s nexthop %s (del)",
306 zpw->ifname, log_addr(zpw->af, (union ldpd_addr *)&zpw->nexthop));
307
7cfdb485
DS
308 return zebra_send_pw(zclient, ZEBRA_PW_DELETE, zpw)
309 == ZCLIENT_SEND_FAILURE;
87b5f1b7
RW
310}
311
312int
313kmpw_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
7cfdb485
DS
319 return zebra_send_pw(zclient, ZEBRA_PW_SET, zpw)
320 == ZCLIENT_SEND_FAILURE;
87b5f1b7
RW
321}
322
323int
324kmpw_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
7cfdb485
DS
329 return zebra_send_pw(zclient, ZEBRA_PW_UNSET, zpw)
330 == ZCLIENT_SEND_FAILURE;
eac6e3f0
RW
331}
332
333void
334kif_redistribute(const char *ifname)
335{
f4e14fdb
RW
336 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
337 struct listnode *cnode;
eac6e3f0
RW
338 struct interface *ifp;
339 struct connected *ifc;
340 struct kif kif;
341 struct kaddr ka;
342
451fda4f 343 FOR_ALL_INTERFACES (vrf, ifp) {
eac6e3f0
RW
344 if (ifname && strcmp(ifname, ifp->name) != 0)
345 continue;
346
347 ifp2kif(ifp, &kif);
52b530fc 348 main_imsg_compose_both(IMSG_IFSTATUS, &kif, sizeof(kif));
eac6e3f0
RW
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,
353 sizeof(ka));
354 }
355 }
356}
357
358static int
121f9dee 359ldp_router_id_update(ZAPI_CALLBACK_ARGS)
eac6e3f0
RW
360{
361 struct prefix router_id;
362
363 zebra_router_id_update_read(zclient->ibuf, &router_id);
364
365 if (bad_addr_v4(router_id.u.prefix4))
366 return (0);
367
903a7226 368 debug_zebra_in("router-id update %pI4", &router_id.u.prefix4);
eac6e3f0
RW
369
370 global.rtr_id.s_addr = router_id.u.prefix4.s_addr;
371 main_imsg_compose_ldpe(IMSG_RTRID_UPDATE, 0, &global.rtr_id,
372 sizeof(global.rtr_id));
373
374 return (0);
375}
376
377static int
ef7bd2a3 378ldp_ifp_create(struct interface *ifp)
eac6e3f0 379{
eac6e3f0
RW
380 struct kif kif;
381
eac6e3f0
RW
382 debug_zebra_in("interface add %s index %d mtu %d", ifp->name,
383 ifp->ifindex, ifp->mtu);
384
385 ifp2kif(ifp, &kif);
52b530fc 386 main_imsg_compose_both(IMSG_IFSTATUS, &kif, sizeof(kif));
eac6e3f0 387
ef7bd2a3 388 return 0;
eac6e3f0
RW
389}
390
391static int
3c3c3252 392ldp_ifp_destroy(struct interface *ifp)
eac6e3f0 393{
9cf67225 394 struct kif kif;
eac6e3f0 395
eac6e3f0
RW
396 debug_zebra_in("interface delete %s index %d mtu %d", ifp->name,
397 ifp->ifindex, ifp->mtu);
398
9cf67225
RW
399 ifp2kif(ifp, &kif);
400 main_imsg_compose_both(IMSG_IFSTATUS, &kif, sizeof(kif));
eac6e3f0
RW
401
402 return (0);
403}
404
405static int
e1894ff7 406ldp_interface_status_change(struct interface *ifp)
eac6e3f0 407{
eac6e3f0
RW
408 struct listnode *node;
409 struct connected *ifc;
410 struct kif kif;
411 struct kaddr ka;
eac6e3f0 412
eac6e3f0
RW
413 debug_zebra_in("interface %s state update", ifp->name);
414
415 ifp2kif(ifp, &kif);
52b530fc 416 main_imsg_compose_both(IMSG_IFSTATUS, &kif, sizeof(kif));
eac6e3f0 417
988ded8d 418 if (if_is_operative(ifp)) {
eac6e3f0
RW
419 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
420 ifc2kaddr(ifp, ifc, &ka);
421 main_imsg_compose_ldpe(IMSG_NEWADDR, 0, &ka,
422 sizeof(ka));
423 }
424 } else {
425 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
426 ifc2kaddr(ifp, ifc, &ka);
427 main_imsg_compose_ldpe(IMSG_DELADDR, 0, &ka,
428 sizeof(ka));
429 }
430 }
431
432 return (0);
433}
ddbf3e60 434
b0b69e59
DS
435static int ldp_ifp_up(struct interface *ifp)
436{
e1894ff7 437 return ldp_interface_status_change(ifp);
b0b69e59 438}
ddbf3e60 439
b0b69e59
DS
440static int ldp_ifp_down(struct interface *ifp)
441{
e1894ff7 442 return ldp_interface_status_change(ifp);
ddbf3e60 443}
eac6e3f0
RW
444
445static int
121f9dee 446ldp_interface_address_add(ZAPI_CALLBACK_ARGS)
eac6e3f0
RW
447{
448 struct connected *ifc;
449 struct interface *ifp;
450 struct kaddr ka;
451
121f9dee 452 ifc = zebra_interface_address_read(cmd, zclient->ibuf, vrf_id);
eac6e3f0
RW
453 if (ifc == NULL)
454 return (0);
455
456 ifp = ifc->ifp;
457 ifc2kaddr(ifp, ifc, &ka);
458
459 /* Filter invalid addresses. */
460 if (bad_addr(ka.af, &ka.addr))
461 return (0);
462
9cf67225
RW
463 debug_zebra_in("address add %s/%u interface %s",
464 log_addr(ka.af, &ka.addr), ka.prefixlen, ifp->name);
eac6e3f0
RW
465
466 /* notify ldpe about new address */
467 main_imsg_compose_ldpe(IMSG_NEWADDR, 0, &ka, sizeof(ka));
468
469 return (0);
470}
471
472static int
121f9dee 473ldp_interface_address_delete(ZAPI_CALLBACK_ARGS)
eac6e3f0
RW
474{
475 struct connected *ifc;
476 struct interface *ifp;
477 struct kaddr ka;
478
121f9dee 479 ifc = zebra_interface_address_read(cmd, zclient->ibuf, vrf_id);
eac6e3f0
RW
480 if (ifc == NULL)
481 return (0);
482
483 ifp = ifc->ifp;
484 ifc2kaddr(ifp, ifc, &ka);
721c0857 485 connected_free(&ifc);
eac6e3f0
RW
486
487 /* Filter invalid addresses. */
488 if (bad_addr(ka.af, &ka.addr))
489 return (0);
490
9cf67225
RW
491 debug_zebra_in("address delete %s/%u interface %s",
492 log_addr(ka.af, &ka.addr), ka.prefixlen, ifp->name);
eac6e3f0
RW
493
494 /* notify ldpe about removed address */
495 main_imsg_compose_ldpe(IMSG_DELADDR, 0, &ka, sizeof(ka));
496
497 return (0);
498}
499
500static int
121f9dee 501ldp_zebra_read_route(ZAPI_CALLBACK_ARGS)
eac6e3f0 502{
74489921
RW
503 struct zapi_route api;
504 struct zapi_nexthop *api_nh;
eac6e3f0 505 struct kroute kr;
74489921
RW
506 int i, add = 0;
507
508 if (zapi_route_decode(zclient->ibuf, &api) < 0)
509 return -1;
510
511 /* we completely ignore srcdest routes for now. */
512 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX))
513 return (0);
eac6e3f0
RW
514
515 memset(&kr, 0, sizeof(kr));
74489921
RW
516 kr.af = api.prefix.family;
517 switch (kr.af) {
518 case AF_INET:
519 kr.prefix.v4 = api.prefix.u.prefix4;
520 break;
521 case AF_INET6:
522 kr.prefix.v6 = api.prefix.u.prefix6;
523 break;
524 default:
525 break;
526 }
527 kr.prefixlen = api.prefix.prefixlen;
e132dea0
RW
528 kr.route_type = api.type;
529 kr.route_instance = api.instance;
eac6e3f0 530
74489921 531 switch (api.type) {
a695cc7b 532 case ZEBRA_ROUTE_CONNECT:
eac6e3f0 533 kr.flags |= F_CONNECTED;
a695cc7b
RW
534 break;
535 case ZEBRA_ROUTE_BGP:
536 /* LDP should follow the IGP and ignore BGP routes */
537 return (0);
538 default:
539 break;
540 }
541
eac6e3f0
RW
542 if (bad_addr(kr.af, &kr.prefix) ||
543 (kr.af == AF_INET6 && IN6_IS_SCOPE_EMBED(&kr.prefix.v6)))
544 return (0);
545
121f9dee 546 if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD)
1f2ff5b5
RW
547 add = 1;
548
74489921 549 if (api.nexthop_num == 0)
1f2ff5b5
RW
550 debug_zebra_in("route %s %s/%d (%s)", (add) ? "add" : "delete",
551 log_addr(kr.af, &kr.prefix), kr.prefixlen,
74489921 552 zebra_route_string(api.type));
eac6e3f0
RW
553
554 /* loop through all the nexthops */
74489921
RW
555 for (i = 0; i < api.nexthop_num; i++) {
556 api_nh = &api.nexthops[i];
cddef813
RW
557 switch (api_nh->type) {
558 case NEXTHOP_TYPE_IPV4:
559 if (kr.af != AF_INET)
560 continue;
561 kr.nexthop.v4 = api_nh->gate.ipv4;
562 kr.ifindex = 0;
563 break;
564 case NEXTHOP_TYPE_IPV4_IFINDEX:
565 if (kr.af != AF_INET)
566 continue;
74489921 567 kr.nexthop.v4 = api_nh->gate.ipv4;
cddef813 568 kr.ifindex = api_nh->ifindex;
eac6e3f0 569 break;
cddef813
RW
570 case NEXTHOP_TYPE_IPV6:
571 if (kr.af != AF_INET6)
572 continue;
74489921 573 kr.nexthop.v6 = api_nh->gate.ipv6;
cddef813 574 kr.ifindex = 0;
eac6e3f0 575 break;
cddef813
RW
576 case NEXTHOP_TYPE_IPV6_IFINDEX:
577 if (kr.af != AF_INET6)
578 continue;
579 kr.nexthop.v6 = api_nh->gate.ipv6;
580 kr.ifindex = api_nh->ifindex;
581 break;
582 case NEXTHOP_TYPE_IFINDEX:
583 if (!(kr.flags & F_CONNECTED))
584 continue;
eac6e3f0 585 break;
4a055ac2 586 case NEXTHOP_TYPE_BLACKHOLE:
cddef813 587 continue;
eac6e3f0 588 }
eac6e3f0 589
1f2ff5b5
RW
590 debug_zebra_in("route %s %s/%d nexthop %s ifindex %u (%s)",
591 (add) ? "add" : "delete", log_addr(kr.af, &kr.prefix),
592 kr.prefixlen, log_addr(kr.af, &kr.nexthop), kr.ifindex,
74489921 593 zebra_route_string(api.type));
1f2ff5b5
RW
594
595 if (add)
eac6e3f0
RW
596 main_imsg_compose_lde(IMSG_NETWORK_ADD, 0, &kr,
597 sizeof(kr));
eac6e3f0
RW
598 }
599
8cb1fc45 600 main_imsg_compose_lde(IMSG_NETWORK_UPDATE, 0, &kr, sizeof(kr));
134970a2 601
eac6e3f0
RW
602 return (0);
603}
604
87b5f1b7
RW
605/*
606 * Receive PW status update from Zebra and send it to LDE process.
607 */
608static int
121f9dee 609ldp_zebra_read_pw_status_update(ZAPI_CALLBACK_ARGS)
87b5f1b7
RW
610{
611 struct zapi_pw_status zpw;
612
121f9dee 613 zebra_read_pw_status_update(cmd, zclient, length, vrf_id, &zpw);
87b5f1b7 614
fd563cc7
KS
615 debug_zebra_in("pseudowire %s status %s 0x%x", zpw.ifname,
616 (zpw.status == PW_FORWARDING) ? "up" : "down",
617 zpw.status);
87b5f1b7
RW
618
619 main_imsg_compose_lde(IMSG_PW_UPDATE, 0, &zpw, sizeof(zpw));
620
621 return (0);
622}
623
ce510d2e
FR
624void ldp_zebra_regdereg_zebra_info(bool want_register)
625{
626 if (zebra_registered == want_register)
627 return;
628
629 log_debug("%s to receive default VRF information",
630 want_register ? "Register" : "De-register");
631
632 if (want_register) {
633 zclient_send_reg_requests(zclient, VRF_DEFAULT);
634 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP,
635 ZEBRA_ROUTE_ALL, 0, VRF_DEFAULT);
636 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient,
637 AFI_IP6, ZEBRA_ROUTE_ALL, 0,
638 VRF_DEFAULT);
639 } else {
640 zclient_send_dereg_requests(zclient, VRF_DEFAULT);
641 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient,
642 AFI_IP, ZEBRA_ROUTE_ALL, 0,
643 VRF_DEFAULT);
644 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient,
645 AFI_IP6, ZEBRA_ROUTE_ALL, 0,
646 VRF_DEFAULT);
647 }
648 zebra_registered = want_register;
649}
650
eac6e3f0
RW
651static void
652ldp_zebra_connected(struct zclient *zclient)
653{
ce510d2e
FR
654 zebra_registered = false;
655
656 /* if MPLS was already enabled and we are re-connecting, register again
657 */
658 if (vty_conf->flags & F_LDPD_ENABLED)
659 ldp_zebra_regdereg_zebra_info(true);
e1894ff7
KS
660
661 ldp_zebra_opaque_register();
662
663 ldp_sync_zebra_init();
eac6e3f0
RW
664}
665
2d1aa1e8 666static void
667ldp_zebra_filter_update(struct access_list *access)
668{
669 struct ldp_access laccess;
670
671 if (access && access->name[0] != '\0') {
672 strlcpy(laccess.name, access->name, sizeof(laccess.name));
3eff8e2f
IR
673 debug_evt("%s ACL update filter name %s", __func__,
674 access->name);
2d1aa1e8 675
676 main_imsg_compose_both(IMSG_FILTER_UPDATE, &laccess,
677 sizeof(laccess));
678 }
679}
680
342213ea
DS
681extern struct zebra_privs_t ldpd_privs;
682
a243d1db
DL
683static zclient_handler *const ldp_handlers[] = {
684 [ZEBRA_ROUTER_ID_UPDATE] = ldp_router_id_update,
685 [ZEBRA_INTERFACE_ADDRESS_ADD] = ldp_interface_address_add,
686 [ZEBRA_INTERFACE_ADDRESS_DELETE] = ldp_interface_address_delete,
687 [ZEBRA_REDISTRIBUTE_ROUTE_ADD] = ldp_zebra_read_route,
688 [ZEBRA_REDISTRIBUTE_ROUTE_DEL] = ldp_zebra_read_route,
689 [ZEBRA_PW_STATUS_UPDATE] = ldp_zebra_read_pw_status_update,
690 [ZEBRA_OPAQUE_MESSAGE] = ldp_zebra_opaque_msg_handler,
691};
692
eac6e3f0
RW
693void
694ldp_zebra_init(struct thread_master *master)
695{
138c5a74
DS
696 if_zapi_callbacks(ldp_ifp_create, ldp_ifp_up,
697 ldp_ifp_down, ldp_ifp_destroy);
698
eac6e3f0 699 /* Set default values. */
a243d1db
DL
700 zclient = zclient_new(master, &zclient_options_default, ldp_handlers,
701 array_size(ldp_handlers));
342213ea 702 zclient_init(zclient, ZEBRA_ROUTE_LDP, 0, &ldpd_privs);
eac6e3f0
RW
703
704 /* set callbacks */
705 zclient->zebra_connected = ldp_zebra_connected;
2d1aa1e8 706
707 /* Access list initialize. */
708 access_list_add_hook(ldp_zebra_filter_update);
709 access_list_delete_hook(ldp_zebra_filter_update);
eac6e3f0 710}
64dffe25
RW
711
712void
713ldp_zebra_destroy(void)
714{
e1894ff7 715 ldp_zebra_opaque_unregister();
64dffe25
RW
716 zclient_stop(zclient);
717 zclient_free(zclient);
718 zclient = NULL;
719}