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