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