]> git.proxmox.com Git - mirror_frr.git/blame - ldpd/ldp_zebra.c
Merge pull request #5985 from Naveenaidu/5984-cleanup-is_selfroute
[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"
34#include "log.h"
35#include "ldp_debug.h"
36
37static void ifp2kif(struct interface *, struct kif *);
38static void ifc2kaddr(struct interface *, struct connected *,
39 struct kaddr *);
bad6b0e7 40static int ldp_zebra_send_mpls_labels(int, struct kroute *);
121f9dee 41static int ldp_router_id_update(ZAPI_CALLBACK_ARGS);
121f9dee
QY
42static int ldp_interface_address_add(ZAPI_CALLBACK_ARGS);
43static int ldp_interface_address_delete(ZAPI_CALLBACK_ARGS);
44static int ldp_zebra_read_route(ZAPI_CALLBACK_ARGS);
45static int ldp_zebra_read_pw_status_update(ZAPI_CALLBACK_ARGS);
eac6e3f0
RW
46static void ldp_zebra_connected(struct zclient *);
47
48static struct zclient *zclient;
49
50static void
51ifp2kif(struct interface *ifp, struct kif *kif)
52{
53 memset(kif, 0, sizeof(*kif));
54 strlcpy(kif->ifname, ifp->name, sizeof(kif->ifname));
55 kif->ifindex = ifp->ifindex;
988ded8d 56 kif->operative = if_is_operative(ifp);
26519d8c 57 if (ifp->ll_type == ZEBRA_LLT_ETHER)
9bff8057 58 memcpy(kif->mac, ifp->hw_addr, ETH_ALEN);
eac6e3f0
RW
59}
60
61static void
62ifc2kaddr(struct interface *ifp, struct connected *ifc, struct kaddr *ka)
63{
64 memset(ka, 0, sizeof(*ka));
9cf67225 65 strlcpy(ka->ifname, ifp->name, sizeof(ka->ifname));
eac6e3f0
RW
66 ka->ifindex = ifp->ifindex;
67 ka->af = ifc->address->family;
68 ka->prefixlen = ifc->address->prefixlen;
69
70 switch (ka->af) {
71 case AF_INET:
72 ka->addr.v4 = ifc->address->u.prefix4;
73 if (ifc->destination)
74 ka->dstbrd.v4 = ifc->destination->u.prefix4;
75 break;
76 case AF_INET6:
77 ka->addr.v6 = ifc->address->u.prefix6;
78 if (ifc->destination)
79 ka->dstbrd.v6 = ifc->destination->u.prefix6;
80 break;
81 default:
82 break;
83 }
84}
85
87b5f1b7
RW
86void
87pw2zpw(struct l2vpn_pw *pw, struct zapi_pw *zpw)
88{
89 memset(zpw, 0, sizeof(*zpw));
90 strlcpy(zpw->ifname, pw->ifname, sizeof(zpw->ifname));
91 zpw->ifindex = pw->ifindex;
92 zpw->type = pw->l2vpn->pw_type;
93 zpw->af = pw->af;
94 zpw->nexthop.ipv6 = pw->addr.v6;
95 zpw->local_label = NO_LABEL;
96 zpw->remote_label = NO_LABEL;
97 if (pw->flags & F_PW_CWORD)
98 zpw->flags = F_PSEUDOWIRE_CWORD;
99 zpw->data.ldp.lsr_id = pw->lsr_id;
100 zpw->data.ldp.pwid = pw->pwid;
101 strlcpy(zpw->data.ldp.vpn_name, pw->l2vpn->name,
102 sizeof(zpw->data.ldp.vpn_name));
103}
104
ce549947 105static int
bad6b0e7 106ldp_zebra_send_mpls_labels(int cmd, struct kroute *kr)
ce549947 107{
bad6b0e7 108 struct zapi_labels zl = {};
4945002d 109 struct zapi_nexthop *znh;
ce549947
RW
110
111 if (kr->local_label < MPLS_LABEL_RESERVED_MAX ||
112 kr->remote_label == NO_LABEL)
113 return (0);
114
88d88a9c 115 debug_zebra_out("prefix %s/%u nexthop %s ifindex %u labels %s/%s (%s)",
ce549947 116 log_addr(kr->af, &kr->prefix), kr->prefixlen,
88d88a9c
RW
117 log_addr(kr->af, &kr->nexthop), kr->ifindex,
118 log_label(kr->local_label), log_label(kr->remote_label),
ce549947
RW
119 (cmd == ZEBRA_MPLS_LABELS_ADD) ? "add" : "delete");
120
bad6b0e7 121 zl.type = ZEBRA_LSP_LDP;
b3c49d0e
RW
122 zl.local_label = kr->local_label;
123
124 /* Set prefix. */
125 SET_FLAG(zl.message, ZAPI_LABELS_FTN);
126 zl.route.prefix.family = kr->af;
ce549947
RW
127 switch (kr->af) {
128 case AF_INET:
b3c49d0e 129 zl.route.prefix.u.prefix4 = kr->prefix.v4;
ce549947
RW
130 break;
131 case AF_INET6:
b3c49d0e 132 zl.route.prefix.u.prefix6 = kr->prefix.v6;
ce549947
RW
133 break;
134 default:
b3c49d0e 135 fatalx("ldp_zebra_send_mpls_labels: unknown af");
ce549947 136 }
b3c49d0e
RW
137 zl.route.prefix.prefixlen = kr->prefixlen;
138 zl.route.type = kr->route_type;
139 zl.route.instance = kr->route_instance;
140
141 /* Set nexthop. */
ea6b290b
RW
142 zl.nexthop_num = 1;
143 znh = &zl.nexthops[0];
b3c49d0e
RW
144 switch (kr->af) {
145 case AF_INET:
4945002d 146 znh->gate.ipv4 = kr->nexthop.v4;
b3c49d0e 147 if (kr->ifindex)
ea6b290b 148 znh->type = NEXTHOP_TYPE_IPV4_IFINDEX;
b3c49d0e 149 else
ea6b290b 150 znh->type = NEXTHOP_TYPE_IPV4;
b3c49d0e
RW
151 break;
152 case AF_INET6:
4945002d 153 znh->gate.ipv6 = kr->nexthop.v6;
b3c49d0e 154 if (kr->ifindex)
ea6b290b 155 znh->type = NEXTHOP_TYPE_IPV6_IFINDEX;
b3c49d0e 156 else
ea6b290b 157 znh->type = NEXTHOP_TYPE_IPV6;
b3c49d0e
RW
158 break;
159 default:
160 break;
161 }
ea6b290b 162 znh->ifindex = kr->ifindex;
4945002d
MS
163 znh->label_num = 1;
164 znh->labels[0] = kr->remote_label;
ce549947 165
bad6b0e7 166 return zebra_send_mpls_labels(zclient, cmd, &zl);
ce549947
RW
167}
168
eac6e3f0
RW
169int
170kr_change(struct kroute *kr)
171{
bad6b0e7 172 return (ldp_zebra_send_mpls_labels(ZEBRA_MPLS_LABELS_ADD, kr));
eac6e3f0
RW
173}
174
175int
176kr_delete(struct kroute *kr)
177{
bad6b0e7 178 return (ldp_zebra_send_mpls_labels(ZEBRA_MPLS_LABELS_DELETE, kr));
eac6e3f0
RW
179}
180
181int
87b5f1b7 182kmpw_add(struct zapi_pw *zpw)
eac6e3f0 183{
87b5f1b7
RW
184 debug_zebra_out("pseudowire %s nexthop %s (add)",
185 zpw->ifname, log_addr(zpw->af, (union ldpd_addr *)&zpw->nexthop));
186
187 return (zebra_send_pw(zclient, ZEBRA_PW_ADD, zpw));
eac6e3f0
RW
188}
189
190int
87b5f1b7 191kmpw_del(struct zapi_pw *zpw)
eac6e3f0 192{
87b5f1b7
RW
193 debug_zebra_out("pseudowire %s nexthop %s (del)",
194 zpw->ifname, log_addr(zpw->af, (union ldpd_addr *)&zpw->nexthop));
195
196 return (zebra_send_pw(zclient, ZEBRA_PW_DELETE, zpw));
197}
198
199int
200kmpw_set(struct zapi_pw *zpw)
201{
202 debug_zebra_out("pseudowire %s nexthop %s labels %u/%u (set)",
203 zpw->ifname, log_addr(zpw->af, (union ldpd_addr *)&zpw->nexthop),
204 zpw->local_label, zpw->remote_label);
205
206 return (zebra_send_pw(zclient, ZEBRA_PW_SET, zpw));
207}
208
209int
210kmpw_unset(struct zapi_pw *zpw)
211{
212 debug_zebra_out("pseudowire %s nexthop %s (unset)",
213 zpw->ifname, log_addr(zpw->af, (union ldpd_addr *)&zpw->nexthop));
214
215 return (zebra_send_pw(zclient, ZEBRA_PW_UNSET, zpw));
eac6e3f0
RW
216}
217
218void
219kif_redistribute(const char *ifname)
220{
f4e14fdb
RW
221 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
222 struct listnode *cnode;
eac6e3f0
RW
223 struct interface *ifp;
224 struct connected *ifc;
225 struct kif kif;
226 struct kaddr ka;
227
451fda4f 228 FOR_ALL_INTERFACES (vrf, ifp) {
eac6e3f0
RW
229 if (ifname && strcmp(ifname, ifp->name) != 0)
230 continue;
231
232 ifp2kif(ifp, &kif);
52b530fc 233 main_imsg_compose_both(IMSG_IFSTATUS, &kif, sizeof(kif));
eac6e3f0
RW
234
235 for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, ifc)) {
236 ifc2kaddr(ifp, ifc, &ka);
237 main_imsg_compose_ldpe(IMSG_NEWADDR, 0, &ka,
238 sizeof(ka));
239 }
240 }
241}
242
243static int
121f9dee 244ldp_router_id_update(ZAPI_CALLBACK_ARGS)
eac6e3f0
RW
245{
246 struct prefix router_id;
247
248 zebra_router_id_update_read(zclient->ibuf, &router_id);
249
250 if (bad_addr_v4(router_id.u.prefix4))
251 return (0);
252
253 debug_zebra_in("router-id update %s", inet_ntoa(router_id.u.prefix4));
254
255 global.rtr_id.s_addr = router_id.u.prefix4.s_addr;
256 main_imsg_compose_ldpe(IMSG_RTRID_UPDATE, 0, &global.rtr_id,
257 sizeof(global.rtr_id));
258
259 return (0);
260}
261
262static int
ef7bd2a3 263ldp_ifp_create(struct interface *ifp)
eac6e3f0 264{
eac6e3f0
RW
265 struct kif kif;
266
eac6e3f0
RW
267 debug_zebra_in("interface add %s index %d mtu %d", ifp->name,
268 ifp->ifindex, ifp->mtu);
269
270 ifp2kif(ifp, &kif);
52b530fc 271 main_imsg_compose_both(IMSG_IFSTATUS, &kif, sizeof(kif));
eac6e3f0 272
ef7bd2a3 273 return 0;
eac6e3f0
RW
274}
275
276static int
3c3c3252 277ldp_ifp_destroy(struct interface *ifp)
eac6e3f0 278{
9cf67225 279 struct kif kif;
eac6e3f0 280
eac6e3f0
RW
281 debug_zebra_in("interface delete %s index %d mtu %d", ifp->name,
282 ifp->ifindex, ifp->mtu);
283
9cf67225
RW
284 ifp2kif(ifp, &kif);
285 main_imsg_compose_both(IMSG_IFSTATUS, &kif, sizeof(kif));
eac6e3f0
RW
286
287 return (0);
288}
289
290static int
ddbf3e60 291ldp_interface_status_change_helper(struct interface *ifp)
eac6e3f0 292{
eac6e3f0
RW
293 struct listnode *node;
294 struct connected *ifc;
295 struct kif kif;
296 struct kaddr ka;
eac6e3f0 297
eac6e3f0
RW
298 debug_zebra_in("interface %s state update", ifp->name);
299
300 ifp2kif(ifp, &kif);
52b530fc 301 main_imsg_compose_both(IMSG_IFSTATUS, &kif, sizeof(kif));
eac6e3f0 302
988ded8d 303 if (if_is_operative(ifp)) {
eac6e3f0
RW
304 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
305 ifc2kaddr(ifp, ifc, &ka);
306 main_imsg_compose_ldpe(IMSG_NEWADDR, 0, &ka,
307 sizeof(ka));
308 }
309 } else {
310 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
311 ifc2kaddr(ifp, ifc, &ka);
312 main_imsg_compose_ldpe(IMSG_DELADDR, 0, &ka,
313 sizeof(ka));
314 }
315 }
316
317 return (0);
318}
ddbf3e60 319
b0b69e59
DS
320static int ldp_ifp_up(struct interface *ifp)
321{
322 return ldp_interface_status_change_helper(ifp);
323}
ddbf3e60 324
b0b69e59
DS
325static int ldp_ifp_down(struct interface *ifp)
326{
ddbf3e60
DS
327 return ldp_interface_status_change_helper(ifp);
328}
eac6e3f0
RW
329
330static int
121f9dee 331ldp_interface_address_add(ZAPI_CALLBACK_ARGS)
eac6e3f0
RW
332{
333 struct connected *ifc;
334 struct interface *ifp;
335 struct kaddr ka;
336
121f9dee 337 ifc = zebra_interface_address_read(cmd, zclient->ibuf, vrf_id);
eac6e3f0
RW
338 if (ifc == NULL)
339 return (0);
340
341 ifp = ifc->ifp;
342 ifc2kaddr(ifp, ifc, &ka);
343
344 /* Filter invalid addresses. */
345 if (bad_addr(ka.af, &ka.addr))
346 return (0);
347
9cf67225
RW
348 debug_zebra_in("address add %s/%u interface %s",
349 log_addr(ka.af, &ka.addr), ka.prefixlen, ifp->name);
eac6e3f0
RW
350
351 /* notify ldpe about new address */
352 main_imsg_compose_ldpe(IMSG_NEWADDR, 0, &ka, sizeof(ka));
353
354 return (0);
355}
356
357static int
121f9dee 358ldp_interface_address_delete(ZAPI_CALLBACK_ARGS)
eac6e3f0
RW
359{
360 struct connected *ifc;
361 struct interface *ifp;
362 struct kaddr ka;
363
121f9dee 364 ifc = zebra_interface_address_read(cmd, zclient->ibuf, vrf_id);
eac6e3f0
RW
365 if (ifc == NULL)
366 return (0);
367
368 ifp = ifc->ifp;
369 ifc2kaddr(ifp, ifc, &ka);
721c0857 370 connected_free(&ifc);
eac6e3f0
RW
371
372 /* Filter invalid addresses. */
373 if (bad_addr(ka.af, &ka.addr))
374 return (0);
375
9cf67225
RW
376 debug_zebra_in("address delete %s/%u interface %s",
377 log_addr(ka.af, &ka.addr), ka.prefixlen, ifp->name);
eac6e3f0
RW
378
379 /* notify ldpe about removed address */
380 main_imsg_compose_ldpe(IMSG_DELADDR, 0, &ka, sizeof(ka));
381
382 return (0);
383}
384
385static int
121f9dee 386ldp_zebra_read_route(ZAPI_CALLBACK_ARGS)
eac6e3f0 387{
74489921
RW
388 struct zapi_route api;
389 struct zapi_nexthop *api_nh;
eac6e3f0 390 struct kroute kr;
74489921
RW
391 int i, add = 0;
392
393 if (zapi_route_decode(zclient->ibuf, &api) < 0)
394 return -1;
395
396 /* we completely ignore srcdest routes for now. */
397 if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX))
398 return (0);
eac6e3f0
RW
399
400 memset(&kr, 0, sizeof(kr));
74489921
RW
401 kr.af = api.prefix.family;
402 switch (kr.af) {
403 case AF_INET:
404 kr.prefix.v4 = api.prefix.u.prefix4;
405 break;
406 case AF_INET6:
407 kr.prefix.v6 = api.prefix.u.prefix6;
408 break;
409 default:
410 break;
411 }
412 kr.prefixlen = api.prefix.prefixlen;
e132dea0
RW
413 kr.route_type = api.type;
414 kr.route_instance = api.instance;
eac6e3f0 415
74489921 416 switch (api.type) {
a695cc7b 417 case ZEBRA_ROUTE_CONNECT:
eac6e3f0 418 kr.flags |= F_CONNECTED;
a695cc7b
RW
419 break;
420 case ZEBRA_ROUTE_BGP:
421 /* LDP should follow the IGP and ignore BGP routes */
422 return (0);
423 default:
424 break;
425 }
426
eac6e3f0
RW
427 if (bad_addr(kr.af, &kr.prefix) ||
428 (kr.af == AF_INET6 && IN6_IS_SCOPE_EMBED(&kr.prefix.v6)))
429 return (0);
430
121f9dee 431 if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD)
1f2ff5b5
RW
432 add = 1;
433
74489921 434 if (api.nexthop_num == 0)
1f2ff5b5
RW
435 debug_zebra_in("route %s %s/%d (%s)", (add) ? "add" : "delete",
436 log_addr(kr.af, &kr.prefix), kr.prefixlen,
74489921 437 zebra_route_string(api.type));
eac6e3f0
RW
438
439 /* loop through all the nexthops */
74489921
RW
440 for (i = 0; i < api.nexthop_num; i++) {
441 api_nh = &api.nexthops[i];
cddef813
RW
442 switch (api_nh->type) {
443 case NEXTHOP_TYPE_IPV4:
444 if (kr.af != AF_INET)
445 continue;
446 kr.nexthop.v4 = api_nh->gate.ipv4;
447 kr.ifindex = 0;
448 break;
449 case NEXTHOP_TYPE_IPV4_IFINDEX:
450 if (kr.af != AF_INET)
451 continue;
74489921 452 kr.nexthop.v4 = api_nh->gate.ipv4;
cddef813 453 kr.ifindex = api_nh->ifindex;
eac6e3f0 454 break;
cddef813
RW
455 case NEXTHOP_TYPE_IPV6:
456 if (kr.af != AF_INET6)
457 continue;
74489921 458 kr.nexthop.v6 = api_nh->gate.ipv6;
cddef813 459 kr.ifindex = 0;
eac6e3f0 460 break;
cddef813
RW
461 case NEXTHOP_TYPE_IPV6_IFINDEX:
462 if (kr.af != AF_INET6)
463 continue;
464 kr.nexthop.v6 = api_nh->gate.ipv6;
465 kr.ifindex = api_nh->ifindex;
466 break;
467 case NEXTHOP_TYPE_IFINDEX:
468 if (!(kr.flags & F_CONNECTED))
469 continue;
eac6e3f0 470 break;
cddef813
RW
471 default:
472 continue;
eac6e3f0 473 }
eac6e3f0 474
1f2ff5b5
RW
475 debug_zebra_in("route %s %s/%d nexthop %s ifindex %u (%s)",
476 (add) ? "add" : "delete", log_addr(kr.af, &kr.prefix),
477 kr.prefixlen, log_addr(kr.af, &kr.nexthop), kr.ifindex,
74489921 478 zebra_route_string(api.type));
1f2ff5b5
RW
479
480 if (add)
eac6e3f0
RW
481 main_imsg_compose_lde(IMSG_NETWORK_ADD, 0, &kr,
482 sizeof(kr));
eac6e3f0
RW
483 }
484
8cb1fc45 485 main_imsg_compose_lde(IMSG_NETWORK_UPDATE, 0, &kr, sizeof(kr));
134970a2 486
eac6e3f0
RW
487 return (0);
488}
489
87b5f1b7
RW
490/*
491 * Receive PW status update from Zebra and send it to LDE process.
492 */
493static int
121f9dee 494ldp_zebra_read_pw_status_update(ZAPI_CALLBACK_ARGS)
87b5f1b7
RW
495{
496 struct zapi_pw_status zpw;
497
121f9dee 498 zebra_read_pw_status_update(cmd, zclient, length, vrf_id, &zpw);
87b5f1b7
RW
499
500 debug_zebra_in("pseudowire %s status %s", zpw.ifname,
501 (zpw.status == PW_STATUS_UP) ? "up" : "down");
502
503 main_imsg_compose_lde(IMSG_PW_UPDATE, 0, &zpw, sizeof(zpw));
504
505 return (0);
506}
507
eac6e3f0
RW
508static void
509ldp_zebra_connected(struct zclient *zclient)
510{
eac6e3f0 511 zclient_send_reg_requests(zclient, VRF_DEFAULT);
a695cc7b
RW
512 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP,
513 ZEBRA_ROUTE_ALL, 0, VRF_DEFAULT);
514 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6,
515 ZEBRA_ROUTE_ALL, 0, VRF_DEFAULT);
eac6e3f0
RW
516}
517
342213ea
DS
518extern struct zebra_privs_t ldpd_privs;
519
eac6e3f0
RW
520void
521ldp_zebra_init(struct thread_master *master)
522{
138c5a74
DS
523 if_zapi_callbacks(ldp_ifp_create, ldp_ifp_up,
524 ldp_ifp_down, ldp_ifp_destroy);
525
eac6e3f0 526 /* Set default values. */
26f63a1e 527 zclient = zclient_new(master, &zclient_options_default);
342213ea 528 zclient_init(zclient, ZEBRA_ROUTE_LDP, 0, &ldpd_privs);
eac6e3f0
RW
529
530 /* set callbacks */
531 zclient->zebra_connected = ldp_zebra_connected;
532 zclient->router_id_update = ldp_router_id_update;
eac6e3f0
RW
533 zclient->interface_address_add = ldp_interface_address_add;
534 zclient->interface_address_delete = ldp_interface_address_delete;
74489921
RW
535 zclient->redistribute_route_add = ldp_zebra_read_route;
536 zclient->redistribute_route_del = ldp_zebra_read_route;
87b5f1b7 537 zclient->pw_status_update = ldp_zebra_read_pw_status_update;
eac6e3f0 538}
64dffe25
RW
539
540void
541ldp_zebra_destroy(void)
542{
543 zclient_stop(zclient);
544 zclient_free(zclient);
545 zclient = NULL;
546}