]> git.proxmox.com Git - mirror_frr.git/blame - ldpd/ldp_zebra.c
Merge pull request #197 from opensourcerouting/pytest_workdir
[mirror_frr.git] / ldpd / ldp_zebra.c
CommitLineData
eac6e3f0
RW
1/*
2 * Copyright (C) 2016 by Open Source Routing.
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
24#include "prefix.h"
25#include "stream.h"
26#include "memory.h"
27#include "zclient.h"
28#include "command.h"
29#include "network.h"
30#include "linklist.h"
ce549947 31#include "mpls.h"
eac6e3f0
RW
32
33#include "ldpd.h"
34#include "ldpe.h"
35#include "lde.h"
36#include "log.h"
37#include "ldp_debug.h"
38
39static void ifp2kif(struct interface *, struct kif *);
40static void ifc2kaddr(struct interface *, struct connected *,
41 struct kaddr *);
ce549947 42static int zebra_send_mpls_labels(int, struct kroute *);
eac6e3f0
RW
43static int ldp_router_id_update(int, struct zclient *, zebra_size_t,
44 vrf_id_t);
45static int ldp_interface_add(int, struct zclient *, zebra_size_t,
46 vrf_id_t);
47static int ldp_interface_delete(int, struct zclient *, zebra_size_t,
48 vrf_id_t);
49static int ldp_interface_status_change(int command, struct zclient *,
50 zebra_size_t, vrf_id_t);
51static int ldp_interface_address_add(int, struct zclient *, zebra_size_t,
52 vrf_id_t);
53static int ldp_interface_address_delete(int, struct zclient *,
54 zebra_size_t, vrf_id_t);
55static int ldp_zebra_read_route(int, struct zclient *, zebra_size_t,
56 vrf_id_t);
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;
67 kif->flags = ifp->flags;
68}
69
70static void
71ifc2kaddr(struct interface *ifp, struct connected *ifc, struct kaddr *ka)
72{
73 memset(ka, 0, sizeof(*ka));
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
ce549947
RW
94static int
95zebra_send_mpls_labels(int cmd, struct kroute *kr)
96{
97 struct stream *s;
98
99 if (kr->local_label < MPLS_LABEL_RESERVED_MAX ||
100 kr->remote_label == NO_LABEL)
101 return (0);
102
88d88a9c 103 debug_zebra_out("prefix %s/%u nexthop %s ifindex %u labels %s/%s (%s)",
ce549947 104 log_addr(kr->af, &kr->prefix), kr->prefixlen,
88d88a9c
RW
105 log_addr(kr->af, &kr->nexthop), kr->ifindex,
106 log_label(kr->local_label), log_label(kr->remote_label),
ce549947
RW
107 (cmd == ZEBRA_MPLS_LABELS_ADD) ? "add" : "delete");
108
109 /* Reset stream. */
110 s = zclient->obuf;
111 stream_reset(s);
112
113 zclient_create_header(s, cmd, VRF_DEFAULT);
114 stream_putc(s, ZEBRA_LSP_LDP);
115 stream_putl(s, kr->af);
116 switch (kr->af) {
117 case AF_INET:
118 stream_put_in_addr(s, &kr->prefix.v4);
119 stream_putc(s, kr->prefixlen);
120 stream_put_in_addr(s, &kr->nexthop.v4);
121 break;
122 case AF_INET6:
123 stream_write(s, (u_char *)&kr->prefix.v6, 16);
124 stream_putc(s, kr->prefixlen);
125 stream_write(s, (u_char *)&kr->nexthop.v6, 16);
126 break;
127 default:
128 fatalx("kr_change: unknown af");
129 }
88d88a9c 130 stream_putl(s, kr->ifindex);
ce549947
RW
131 stream_putc(s, kr->priority);
132 stream_putl(s, kr->local_label);
133 stream_putl(s, kr->remote_label);
134
135 /* Put length at the first point of the stream. */
136 stream_putw_at(s, 0, stream_get_endp(s));
137
138 return (zclient_send_message(zclient));
139}
140
eac6e3f0
RW
141int
142kr_change(struct kroute *kr)
143{
ce549947 144 return (zebra_send_mpls_labels(ZEBRA_MPLS_LABELS_ADD, kr));
eac6e3f0
RW
145}
146
147int
148kr_delete(struct kroute *kr)
149{
ce549947 150 return (zebra_send_mpls_labels(ZEBRA_MPLS_LABELS_DELETE, kr));
eac6e3f0
RW
151}
152
153int
154kmpw_set(struct kpw *kpw)
155{
156 /* TODO */
157 return (0);
158}
159
160int
161kmpw_unset(struct kpw *kpw)
162{
163 /* TODO */
164 return (0);
165}
166
167void
168kif_redistribute(const char *ifname)
169{
170 struct listnode *node, *cnode;
171 struct interface *ifp;
172 struct connected *ifc;
173 struct kif kif;
174 struct kaddr ka;
175
176 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
177 if (ifname && strcmp(ifname, ifp->name) != 0)
178 continue;
179
180 ifp2kif(ifp, &kif);
181 main_imsg_compose_ldpe(IMSG_IFSTATUS, 0, &kif, sizeof(kif));
182
183 for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, ifc)) {
184 ifc2kaddr(ifp, ifc, &ka);
185 main_imsg_compose_ldpe(IMSG_NEWADDR, 0, &ka,
186 sizeof(ka));
187 }
188 }
189}
190
191static int
192ldp_router_id_update(int command, struct zclient *zclient, zebra_size_t length,
193 vrf_id_t vrf_id)
194{
195 struct prefix router_id;
196
197 zebra_router_id_update_read(zclient->ibuf, &router_id);
198
199 if (bad_addr_v4(router_id.u.prefix4))
200 return (0);
201
202 debug_zebra_in("router-id update %s", inet_ntoa(router_id.u.prefix4));
203
204 global.rtr_id.s_addr = router_id.u.prefix4.s_addr;
205 main_imsg_compose_ldpe(IMSG_RTRID_UPDATE, 0, &global.rtr_id,
206 sizeof(global.rtr_id));
207
208 return (0);
209}
210
211static int
212ldp_interface_add(int command, struct zclient *zclient, zebra_size_t length,
213 vrf_id_t vrf_id)
214{
215 struct interface *ifp;
216 struct kif kif;
217
218 ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
219 debug_zebra_in("interface add %s index %d mtu %d", ifp->name,
220 ifp->ifindex, ifp->mtu);
221
222 ifp2kif(ifp, &kif);
223 main_imsg_compose_ldpe(IMSG_IFSTATUS, 0, &kif, sizeof(kif));
224
225 return (0);
226}
227
228static int
229ldp_interface_delete(int command, struct zclient *zclient, zebra_size_t length,
230 vrf_id_t vrf_id)
231{
232 struct interface *ifp;
233
234 /* zebra_interface_state_read() updates interface structure in iflist */
235 ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
236 if (ifp == NULL)
237 return (0);
238
239 debug_zebra_in("interface delete %s index %d mtu %d", ifp->name,
240 ifp->ifindex, ifp->mtu);
241
242 /* To support pseudo interface do not free interface structure. */
243 /* if_delete(ifp); */
244 ifp->ifindex = IFINDEX_INTERNAL;
245
246 return (0);
247}
248
249static int
250ldp_interface_status_change(int command, struct zclient *zclient,
251 zebra_size_t length, vrf_id_t vrf_id)
252{
253 struct interface *ifp;
254 struct listnode *node;
255 struct connected *ifc;
256 struct kif kif;
257 struct kaddr ka;
258 int link_new;
259
260 /*
261 * zebra_interface_state_read() updates interface structure in
262 * iflist.
263 */
264 ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
265 if (ifp == NULL)
266 return (0);
267
268 debug_zebra_in("interface %s state update", ifp->name);
269
270 ifp2kif(ifp, &kif);
271 main_imsg_compose_ldpe(IMSG_IFSTATUS, 0, &kif, sizeof(kif));
272
273 link_new = (ifp->flags & IFF_UP) && (ifp->flags & IFF_RUNNING);
274 if (link_new) {
275 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
276 ifc2kaddr(ifp, ifc, &ka);
277 main_imsg_compose_ldpe(IMSG_NEWADDR, 0, &ka,
278 sizeof(ka));
279 }
280 } else {
281 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
282 ifc2kaddr(ifp, ifc, &ka);
283 main_imsg_compose_ldpe(IMSG_DELADDR, 0, &ka,
284 sizeof(ka));
285 }
286 }
287
288 return (0);
289}
290
291static int
292ldp_interface_address_add(int command, struct zclient *zclient,
293 zebra_size_t length, vrf_id_t vrf_id)
294{
295 struct connected *ifc;
296 struct interface *ifp;
297 struct kaddr ka;
298
299 ifc = zebra_interface_address_read(command, zclient->ibuf, vrf_id);
300 if (ifc == NULL)
301 return (0);
302
303 ifp = ifc->ifp;
304 ifc2kaddr(ifp, ifc, &ka);
305
306 /* Filter invalid addresses. */
307 if (bad_addr(ka.af, &ka.addr))
308 return (0);
309
310 debug_zebra_in("address add %s/%u", log_addr(ka.af, &ka.addr),
311 ka.prefixlen);
312
313 /* notify ldpe about new address */
314 main_imsg_compose_ldpe(IMSG_NEWADDR, 0, &ka, sizeof(ka));
315
316 return (0);
317}
318
319static int
320ldp_interface_address_delete(int command, struct zclient *zclient,
321 zebra_size_t length, vrf_id_t vrf_id)
322{
323 struct connected *ifc;
324 struct interface *ifp;
325 struct kaddr ka;
326
327 ifc = zebra_interface_address_read(command, zclient->ibuf, vrf_id);
328 if (ifc == NULL)
329 return (0);
330
331 ifp = ifc->ifp;
332 ifc2kaddr(ifp, ifc, &ka);
333 connected_free(ifc);
334
335 /* Filter invalid addresses. */
336 if (bad_addr(ka.af, &ka.addr))
337 return (0);
338
339 debug_zebra_in("address delete %s/%u", log_addr(ka.af, &ka.addr),
340 ka.prefixlen);
341
342 /* notify ldpe about removed address */
343 main_imsg_compose_ldpe(IMSG_DELADDR, 0, &ka, sizeof(ka));
344
345 return (0);
346}
347
348static int
349ldp_zebra_read_route(int command, struct zclient *zclient, zebra_size_t length,
350 vrf_id_t vrf_id)
351{
352 struct stream *s;
353 u_char type;
354 u_char message_flags;
355 struct kroute kr;
8cb1fc45 356 int nhnum = 0, nhlen;
eac6e3f0
RW
357 size_t nhmark;
358
359 memset(&kr, 0, sizeof(kr));
360 s = zclient->ibuf;
361
362 type = stream_getc(s);
a695cc7b
RW
363 switch (type) {
364 case ZEBRA_ROUTE_CONNECT:
eac6e3f0 365 kr.flags |= F_CONNECTED;
a695cc7b
RW
366 break;
367 case ZEBRA_ROUTE_BGP:
368 /* LDP should follow the IGP and ignore BGP routes */
369 return (0);
370 default:
371 break;
372 }
373
3f67fb9c 374 stream_getl(s); /* flags, unused */
eac6e3f0
RW
375 stream_getw(s); /* instance, unused */
376 message_flags = stream_getc(s);
eac6e3f0
RW
377
378 switch (command) {
eac6e3f0 379 case ZEBRA_REDISTRIBUTE_IPV4_ADD:
eac6e3f0
RW
380 case ZEBRA_REDISTRIBUTE_IPV4_DEL:
381 kr.af = AF_INET;
382 nhlen = sizeof(struct in_addr);
383 break;
eac6e3f0 384 case ZEBRA_REDISTRIBUTE_IPV6_ADD:
eac6e3f0
RW
385 case ZEBRA_REDISTRIBUTE_IPV6_DEL:
386 kr.af = AF_INET6;
387 nhlen = sizeof(struct in6_addr);
388 break;
389 default:
390 fatalx("ldp_zebra_read_route: unknown command");
391 }
392 kr.prefixlen = stream_getc(s);
393 stream_get(&kr.prefix, s, PSIZE(kr.prefixlen));
394
395 if (bad_addr(kr.af, &kr.prefix) ||
396 (kr.af == AF_INET6 && IN6_IS_SCOPE_EMBED(&kr.prefix.v6)))
397 return (0);
398
81a164e2
CF
399 if (kr.af == AF_INET6 &&
400 CHECK_FLAG(message_flags, ZAPI_MESSAGE_SRCPFX)) {
401 uint8_t src_prefixlen;
402
403 src_prefixlen = stream_getc(s);
404
405 /* we completely ignore srcdest routes for now. */
406 if (src_prefixlen)
407 return (0);
408 }
409
8cb1fc45
RW
410 if (CHECK_FLAG(message_flags, ZAPI_MESSAGE_NEXTHOP)) {
411 nhnum = stream_getc(s);
412 nhmark = stream_get_getp(s);
413 stream_set_getp(s, nhmark + nhnum * (nhlen + 5));
414 }
eac6e3f0
RW
415
416 if (CHECK_FLAG(message_flags, ZAPI_MESSAGE_DISTANCE))
417 kr.priority = stream_getc(s);
418 if (CHECK_FLAG(message_flags, ZAPI_MESSAGE_METRIC))
419 stream_getl(s); /* metric, not used */
420
8cb1fc45
RW
421 if (CHECK_FLAG(message_flags, ZAPI_MESSAGE_NEXTHOP))
422 stream_set_getp(s, nhmark);
423
424 if (nhnum == 0) {
425 switch (command) {
426 case ZEBRA_REDISTRIBUTE_IPV4_ADD:
427 case ZEBRA_REDISTRIBUTE_IPV6_ADD:
428 return (0);
429 case ZEBRA_REDISTRIBUTE_IPV4_DEL:
430 case ZEBRA_REDISTRIBUTE_IPV6_DEL:
431 debug_zebra_in("route delete %s/%d (%s)",
432 log_addr(kr.af, &kr.prefix), kr.prefixlen,
433 zebra_route_string(type));
434 break;
435 default:
436 fatalx("ldp_zebra_read_route: unknown command");
437 }
438 }
eac6e3f0
RW
439
440 /* loop through all the nexthops */
441 for (; nhnum > 0; nhnum--) {
442 switch (kr.af) {
443 case AF_INET:
444 kr.nexthop.v4.s_addr = stream_get_ipv4(s);
445 break;
446 case AF_INET6:
447 stream_get(&kr.nexthop.v6, s, sizeof(kr.nexthop.v6));
448 break;
449 default:
450 break;
451 }
452 stream_getc(s); /* ifindex_num, unused. */
453 kr.ifindex = stream_getl(s);
454
455 switch (command) {
eac6e3f0 456 case ZEBRA_REDISTRIBUTE_IPV4_ADD:
eac6e3f0 457 case ZEBRA_REDISTRIBUTE_IPV6_ADD:
88d88a9c
RW
458 debug_zebra_in("route add %s/%d nexthop %s "
459 "ifindex %u (%s)", log_addr(kr.af, &kr.prefix),
460 kr.prefixlen, log_addr(kr.af, &kr.nexthop),
461 kr.ifindex, zebra_route_string(type));
eac6e3f0
RW
462 main_imsg_compose_lde(IMSG_NETWORK_ADD, 0, &kr,
463 sizeof(kr));
464 break;
eac6e3f0 465 default:
8cb1fc45 466 break;
eac6e3f0
RW
467 }
468 }
469
8cb1fc45 470 main_imsg_compose_lde(IMSG_NETWORK_UPDATE, 0, &kr, sizeof(kr));
134970a2 471
eac6e3f0
RW
472 return (0);
473}
474
475static void
476ldp_zebra_connected(struct zclient *zclient)
477{
eac6e3f0 478 zclient_send_reg_requests(zclient, VRF_DEFAULT);
a695cc7b
RW
479 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP,
480 ZEBRA_ROUTE_ALL, 0, VRF_DEFAULT);
481 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6,
482 ZEBRA_ROUTE_ALL, 0, VRF_DEFAULT);
eac6e3f0
RW
483}
484
485void
486ldp_zebra_init(struct thread_master *master)
487{
488 /* Set default values. */
489 zclient = zclient_new(master);
490 zclient_init(zclient, ZEBRA_ROUTE_LDP, 0);
491
492 /* set callbacks */
493 zclient->zebra_connected = ldp_zebra_connected;
494 zclient->router_id_update = ldp_router_id_update;
495 zclient->interface_add = ldp_interface_add;
496 zclient->interface_delete = ldp_interface_delete;
497 zclient->interface_up = ldp_interface_status_change;
498 zclient->interface_down = ldp_interface_status_change;
499 zclient->interface_address_add = ldp_interface_address_add;
500 zclient->interface_address_delete = ldp_interface_address_delete;
eac6e3f0
RW
501 zclient->redistribute_route_ipv4_add = ldp_zebra_read_route;
502 zclient->redistribute_route_ipv4_del = ldp_zebra_read_route;
eac6e3f0
RW
503 zclient->redistribute_route_ipv6_add = ldp_zebra_read_route;
504 zclient->redistribute_route_ipv6_del = ldp_zebra_read_route;
505}
64dffe25
RW
506
507void
508ldp_zebra_destroy(void)
509{
510 zclient_stop(zclient);
511 zclient_free(zclient);
512 zclient = NULL;
513}