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