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