]> git.proxmox.com Git - mirror_frr.git/blame - ldpd/ldp_zebra.c
ldpd: remove the interface vty node
[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;
26519d8c
RW
68 if (ifp->ll_type == ZEBRA_LLT_ETHER)
69 memcpy(kif->mac, ifp->hw_addr, ETHER_ADDR_LEN);
eac6e3f0
RW
70}
71
72static void
73ifc2kaddr(struct interface *ifp, struct connected *ifc, struct kaddr *ka)
74{
75 memset(ka, 0, sizeof(*ka));
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);
183 main_imsg_compose_ldpe(IMSG_IFSTATUS, 0, &kif, sizeof(kif));
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);
225 main_imsg_compose_ldpe(IMSG_IFSTATUS, 0, &kif, sizeof(kif));
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;
235
236 /* zebra_interface_state_read() updates interface structure in iflist */
237 ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
238 if (ifp == NULL)
239 return (0);
240
241 debug_zebra_in("interface delete %s index %d mtu %d", ifp->name,
242 ifp->ifindex, ifp->mtu);
243
244 /* To support pseudo interface do not free interface structure. */
245 /* if_delete(ifp); */
246 ifp->ifindex = IFINDEX_INTERNAL;
247
248 return (0);
249}
250
251static int
252ldp_interface_status_change(int command, struct zclient *zclient,
253 zebra_size_t length, vrf_id_t vrf_id)
254{
255 struct interface *ifp;
256 struct listnode *node;
257 struct connected *ifc;
258 struct kif kif;
259 struct kaddr ka;
260 int link_new;
261
262 /*
263 * zebra_interface_state_read() updates interface structure in
264 * iflist.
265 */
266 ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
267 if (ifp == NULL)
268 return (0);
269
270 debug_zebra_in("interface %s state update", ifp->name);
271
272 ifp2kif(ifp, &kif);
273 main_imsg_compose_ldpe(IMSG_IFSTATUS, 0, &kif, sizeof(kif));
274
275 link_new = (ifp->flags & IFF_UP) && (ifp->flags & IFF_RUNNING);
276 if (link_new) {
277 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
278 ifc2kaddr(ifp, ifc, &ka);
279 main_imsg_compose_ldpe(IMSG_NEWADDR, 0, &ka,
280 sizeof(ka));
281 }
282 } else {
283 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
284 ifc2kaddr(ifp, ifc, &ka);
285 main_imsg_compose_ldpe(IMSG_DELADDR, 0, &ka,
286 sizeof(ka));
287 }
288 }
289
290 return (0);
291}
292
293static int
294ldp_interface_address_add(int command, struct zclient *zclient,
295 zebra_size_t length, vrf_id_t vrf_id)
296{
297 struct connected *ifc;
298 struct interface *ifp;
299 struct kaddr ka;
300
301 ifc = zebra_interface_address_read(command, zclient->ibuf, vrf_id);
302 if (ifc == NULL)
303 return (0);
304
305 ifp = ifc->ifp;
306 ifc2kaddr(ifp, ifc, &ka);
307
308 /* Filter invalid addresses. */
309 if (bad_addr(ka.af, &ka.addr))
310 return (0);
311
312 debug_zebra_in("address add %s/%u", log_addr(ka.af, &ka.addr),
313 ka.prefixlen);
314
315 /* notify ldpe about new address */
316 main_imsg_compose_ldpe(IMSG_NEWADDR, 0, &ka, sizeof(ka));
317
318 return (0);
319}
320
321static int
322ldp_interface_address_delete(int command, struct zclient *zclient,
323 zebra_size_t length, vrf_id_t vrf_id)
324{
325 struct connected *ifc;
326 struct interface *ifp;
327 struct kaddr ka;
328
329 ifc = zebra_interface_address_read(command, zclient->ibuf, vrf_id);
330 if (ifc == NULL)
331 return (0);
332
333 ifp = ifc->ifp;
334 ifc2kaddr(ifp, ifc, &ka);
335 connected_free(ifc);
336
337 /* Filter invalid addresses. */
338 if (bad_addr(ka.af, &ka.addr))
339 return (0);
340
341 debug_zebra_in("address delete %s/%u", log_addr(ka.af, &ka.addr),
342 ka.prefixlen);
343
344 /* notify ldpe about removed address */
345 main_imsg_compose_ldpe(IMSG_DELADDR, 0, &ka, sizeof(ka));
346
347 return (0);
348}
349
350static int
351ldp_zebra_read_route(int command, struct zclient *zclient, zebra_size_t length,
352 vrf_id_t vrf_id)
353{
354 struct stream *s;
355 u_char type;
356 u_char message_flags;
357 struct kroute kr;
8cb1fc45 358 int nhnum = 0, nhlen;
eac6e3f0
RW
359 size_t nhmark;
360
361 memset(&kr, 0, sizeof(kr));
362 s = zclient->ibuf;
363
364 type = stream_getc(s);
a695cc7b
RW
365 switch (type) {
366 case ZEBRA_ROUTE_CONNECT:
eac6e3f0 367 kr.flags |= F_CONNECTED;
a695cc7b
RW
368 break;
369 case ZEBRA_ROUTE_BGP:
370 /* LDP should follow the IGP and ignore BGP routes */
371 return (0);
372 default:
373 break;
374 }
375
3f67fb9c 376 stream_getl(s); /* flags, unused */
eac6e3f0
RW
377 stream_getw(s); /* instance, unused */
378 message_flags = stream_getc(s);
eac6e3f0
RW
379
380 switch (command) {
eac6e3f0 381 case ZEBRA_REDISTRIBUTE_IPV4_ADD:
eac6e3f0
RW
382 case ZEBRA_REDISTRIBUTE_IPV4_DEL:
383 kr.af = AF_INET;
384 nhlen = sizeof(struct in_addr);
385 break;
eac6e3f0 386 case ZEBRA_REDISTRIBUTE_IPV6_ADD:
eac6e3f0
RW
387 case ZEBRA_REDISTRIBUTE_IPV6_DEL:
388 kr.af = AF_INET6;
389 nhlen = sizeof(struct in6_addr);
390 break;
391 default:
392 fatalx("ldp_zebra_read_route: unknown command");
393 }
394 kr.prefixlen = stream_getc(s);
395 stream_get(&kr.prefix, s, PSIZE(kr.prefixlen));
396
397 if (bad_addr(kr.af, &kr.prefix) ||
398 (kr.af == AF_INET6 && IN6_IS_SCOPE_EMBED(&kr.prefix.v6)))
399 return (0);
400
81a164e2
CF
401 if (kr.af == AF_INET6 &&
402 CHECK_FLAG(message_flags, ZAPI_MESSAGE_SRCPFX)) {
403 uint8_t src_prefixlen;
404
405 src_prefixlen = stream_getc(s);
406
407 /* we completely ignore srcdest routes for now. */
408 if (src_prefixlen)
409 return (0);
410 }
411
8cb1fc45
RW
412 if (CHECK_FLAG(message_flags, ZAPI_MESSAGE_NEXTHOP)) {
413 nhnum = stream_getc(s);
414 nhmark = stream_get_getp(s);
415 stream_set_getp(s, nhmark + nhnum * (nhlen + 5));
416 }
eac6e3f0
RW
417
418 if (CHECK_FLAG(message_flags, ZAPI_MESSAGE_DISTANCE))
419 kr.priority = stream_getc(s);
420 if (CHECK_FLAG(message_flags, ZAPI_MESSAGE_METRIC))
421 stream_getl(s); /* metric, not used */
422
8cb1fc45
RW
423 if (CHECK_FLAG(message_flags, ZAPI_MESSAGE_NEXTHOP))
424 stream_set_getp(s, nhmark);
425
426 if (nhnum == 0) {
427 switch (command) {
428 case ZEBRA_REDISTRIBUTE_IPV4_ADD:
429 case ZEBRA_REDISTRIBUTE_IPV6_ADD:
430 return (0);
431 case ZEBRA_REDISTRIBUTE_IPV4_DEL:
432 case ZEBRA_REDISTRIBUTE_IPV6_DEL:
433 debug_zebra_in("route delete %s/%d (%s)",
434 log_addr(kr.af, &kr.prefix), kr.prefixlen,
435 zebra_route_string(type));
436 break;
437 default:
438 fatalx("ldp_zebra_read_route: unknown command");
439 }
440 }
eac6e3f0
RW
441
442 /* loop through all the nexthops */
443 for (; nhnum > 0; nhnum--) {
444 switch (kr.af) {
445 case AF_INET:
446 kr.nexthop.v4.s_addr = stream_get_ipv4(s);
447 break;
448 case AF_INET6:
449 stream_get(&kr.nexthop.v6, s, sizeof(kr.nexthop.v6));
450 break;
451 default:
452 break;
453 }
454 stream_getc(s); /* ifindex_num, unused. */
455 kr.ifindex = stream_getl(s);
456
457 switch (command) {
eac6e3f0 458 case ZEBRA_REDISTRIBUTE_IPV4_ADD:
eac6e3f0 459 case ZEBRA_REDISTRIBUTE_IPV6_ADD:
88d88a9c
RW
460 debug_zebra_in("route add %s/%d nexthop %s "
461 "ifindex %u (%s)", log_addr(kr.af, &kr.prefix),
462 kr.prefixlen, log_addr(kr.af, &kr.nexthop),
463 kr.ifindex, zebra_route_string(type));
eac6e3f0
RW
464 main_imsg_compose_lde(IMSG_NETWORK_ADD, 0, &kr,
465 sizeof(kr));
466 break;
eac6e3f0 467 default:
8cb1fc45 468 break;
eac6e3f0
RW
469 }
470 }
471
8cb1fc45 472 main_imsg_compose_lde(IMSG_NETWORK_UPDATE, 0, &kr, sizeof(kr));
134970a2 473
eac6e3f0
RW
474 return (0);
475}
476
477static void
478ldp_zebra_connected(struct zclient *zclient)
479{
eac6e3f0 480 zclient_send_reg_requests(zclient, VRF_DEFAULT);
a695cc7b
RW
481 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP,
482 ZEBRA_ROUTE_ALL, 0, VRF_DEFAULT);
483 zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6,
484 ZEBRA_ROUTE_ALL, 0, VRF_DEFAULT);
eac6e3f0
RW
485}
486
487void
488ldp_zebra_init(struct thread_master *master)
489{
490 /* Set default values. */
491 zclient = zclient_new(master);
492 zclient_init(zclient, ZEBRA_ROUTE_LDP, 0);
493
494 /* set callbacks */
495 zclient->zebra_connected = ldp_zebra_connected;
496 zclient->router_id_update = ldp_router_id_update;
497 zclient->interface_add = ldp_interface_add;
498 zclient->interface_delete = ldp_interface_delete;
499 zclient->interface_up = ldp_interface_status_change;
500 zclient->interface_down = ldp_interface_status_change;
501 zclient->interface_address_add = ldp_interface_address_add;
502 zclient->interface_address_delete = ldp_interface_address_delete;
eac6e3f0
RW
503 zclient->redistribute_route_ipv4_add = ldp_zebra_read_route;
504 zclient->redistribute_route_ipv4_del = ldp_zebra_read_route;
eac6e3f0
RW
505 zclient->redistribute_route_ipv6_add = ldp_zebra_read_route;
506 zclient->redistribute_route_ipv6_del = ldp_zebra_read_route;
507}
64dffe25
RW
508
509void
510ldp_zebra_destroy(void)
511{
512 zclient_stop(zclient);
513 zclient_free(zclient);
514 zclient = NULL;
515}