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