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