]> git.proxmox.com Git - mirror_frr.git/blame - ldpd/ldp_zebra.c
ldpd: add vtysh support
[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"
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 *);
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);
55static void ldp_zebra_connected(struct zclient *);
56
57static struct zclient *zclient;
58
59static void
60ifp2kif(struct interface *ifp, struct kif *kif)
61{
62 memset(kif, 0, sizeof(*kif));
63 strlcpy(kif->ifname, ifp->name, sizeof(kif->ifname));
64 kif->ifindex = ifp->ifindex;
65 kif->flags = ifp->flags;
66}
67
68static void
69ifc2kaddr(struct interface *ifp, struct connected *ifc, struct kaddr *ka)
70{
71 memset(ka, 0, sizeof(*ka));
72 ka->ifindex = ifp->ifindex;
73 ka->af = ifc->address->family;
74 ka->prefixlen = ifc->address->prefixlen;
75
76 switch (ka->af) {
77 case AF_INET:
78 ka->addr.v4 = ifc->address->u.prefix4;
79 if (ifc->destination)
80 ka->dstbrd.v4 = ifc->destination->u.prefix4;
81 break;
82 case AF_INET6:
83 ka->addr.v6 = ifc->address->u.prefix6;
84 if (ifc->destination)
85 ka->dstbrd.v6 = ifc->destination->u.prefix6;
86 break;
87 default:
88 break;
89 }
90}
91
92int
93kr_change(struct kroute *kr)
94{
95 /* TODO */
96 return (0);
97}
98
99int
100kr_delete(struct kroute *kr)
101{
102 /* TODO */
103 return (0);
104}
105
106int
107kmpw_set(struct kpw *kpw)
108{
109 /* TODO */
110 return (0);
111}
112
113int
114kmpw_unset(struct kpw *kpw)
115{
116 /* TODO */
117 return (0);
118}
119
120void
121kif_redistribute(const char *ifname)
122{
123 struct listnode *node, *cnode;
124 struct interface *ifp;
125 struct connected *ifc;
126 struct kif kif;
127 struct kaddr ka;
128
129 for (ALL_LIST_ELEMENTS_RO(vrf_iflist(VRF_DEFAULT), node, ifp)) {
130 if (ifname && strcmp(ifname, ifp->name) != 0)
131 continue;
132
133 ifp2kif(ifp, &kif);
134 main_imsg_compose_ldpe(IMSG_IFSTATUS, 0, &kif, sizeof(kif));
135
136 for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, ifc)) {
137 ifc2kaddr(ifp, ifc, &ka);
138 main_imsg_compose_ldpe(IMSG_NEWADDR, 0, &ka,
139 sizeof(ka));
140 }
141 }
142}
143
144static int
145ldp_router_id_update(int command, struct zclient *zclient, zebra_size_t length,
146 vrf_id_t vrf_id)
147{
148 struct prefix router_id;
149
150 zebra_router_id_update_read(zclient->ibuf, &router_id);
151
152 if (bad_addr_v4(router_id.u.prefix4))
153 return (0);
154
155 debug_zebra_in("router-id update %s", inet_ntoa(router_id.u.prefix4));
156
157 global.rtr_id.s_addr = router_id.u.prefix4.s_addr;
158 main_imsg_compose_ldpe(IMSG_RTRID_UPDATE, 0, &global.rtr_id,
159 sizeof(global.rtr_id));
160
161 return (0);
162}
163
164static int
165ldp_interface_add(int command, struct zclient *zclient, zebra_size_t length,
166 vrf_id_t vrf_id)
167{
168 struct interface *ifp;
169 struct kif kif;
170
171 ifp = zebra_interface_add_read(zclient->ibuf, vrf_id);
172 debug_zebra_in("interface add %s index %d mtu %d", ifp->name,
173 ifp->ifindex, ifp->mtu);
174
175 ifp2kif(ifp, &kif);
176 main_imsg_compose_ldpe(IMSG_IFSTATUS, 0, &kif, sizeof(kif));
177
178 return (0);
179}
180
181static int
182ldp_interface_delete(int command, struct zclient *zclient, zebra_size_t length,
183 vrf_id_t vrf_id)
184{
185 struct interface *ifp;
186
187 /* zebra_interface_state_read() updates interface structure in iflist */
188 ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
189 if (ifp == NULL)
190 return (0);
191
192 debug_zebra_in("interface delete %s index %d mtu %d", ifp->name,
193 ifp->ifindex, ifp->mtu);
194
195 /* To support pseudo interface do not free interface structure. */
196 /* if_delete(ifp); */
197 ifp->ifindex = IFINDEX_INTERNAL;
198
199 return (0);
200}
201
202static int
203ldp_interface_status_change(int command, struct zclient *zclient,
204 zebra_size_t length, vrf_id_t vrf_id)
205{
206 struct interface *ifp;
207 struct listnode *node;
208 struct connected *ifc;
209 struct kif kif;
210 struct kaddr ka;
211 int link_new;
212
213 /*
214 * zebra_interface_state_read() updates interface structure in
215 * iflist.
216 */
217 ifp = zebra_interface_state_read(zclient->ibuf, vrf_id);
218 if (ifp == NULL)
219 return (0);
220
221 debug_zebra_in("interface %s state update", ifp->name);
222
223 ifp2kif(ifp, &kif);
224 main_imsg_compose_ldpe(IMSG_IFSTATUS, 0, &kif, sizeof(kif));
225
226 link_new = (ifp->flags & IFF_UP) && (ifp->flags & IFF_RUNNING);
227 if (link_new) {
228 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
229 ifc2kaddr(ifp, ifc, &ka);
230 main_imsg_compose_ldpe(IMSG_NEWADDR, 0, &ka,
231 sizeof(ka));
232 }
233 } else {
234 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
235 ifc2kaddr(ifp, ifc, &ka);
236 main_imsg_compose_ldpe(IMSG_DELADDR, 0, &ka,
237 sizeof(ka));
238 }
239 }
240
241 return (0);
242}
243
244static int
245ldp_interface_address_add(int command, struct zclient *zclient,
246 zebra_size_t length, vrf_id_t vrf_id)
247{
248 struct connected *ifc;
249 struct interface *ifp;
250 struct kaddr ka;
251
252 ifc = zebra_interface_address_read(command, zclient->ibuf, vrf_id);
253 if (ifc == NULL)
254 return (0);
255
256 ifp = ifc->ifp;
257 ifc2kaddr(ifp, ifc, &ka);
258
259 /* Filter invalid addresses. */
260 if (bad_addr(ka.af, &ka.addr))
261 return (0);
262
263 debug_zebra_in("address add %s/%u", log_addr(ka.af, &ka.addr),
264 ka.prefixlen);
265
266 /* notify ldpe about new address */
267 main_imsg_compose_ldpe(IMSG_NEWADDR, 0, &ka, sizeof(ka));
268
269 return (0);
270}
271
272static int
273ldp_interface_address_delete(int command, struct zclient *zclient,
274 zebra_size_t length, vrf_id_t vrf_id)
275{
276 struct connected *ifc;
277 struct interface *ifp;
278 struct kaddr ka;
279
280 ifc = zebra_interface_address_read(command, zclient->ibuf, vrf_id);
281 if (ifc == NULL)
282 return (0);
283
284 ifp = ifc->ifp;
285 ifc2kaddr(ifp, ifc, &ka);
286 connected_free(ifc);
287
288 /* Filter invalid addresses. */
289 if (bad_addr(ka.af, &ka.addr))
290 return (0);
291
292 debug_zebra_in("address delete %s/%u", log_addr(ka.af, &ka.addr),
293 ka.prefixlen);
294
295 /* notify ldpe about removed address */
296 main_imsg_compose_ldpe(IMSG_DELADDR, 0, &ka, sizeof(ka));
297
298 return (0);
299}
300
301static int
302ldp_zebra_read_route(int command, struct zclient *zclient, zebra_size_t length,
303 vrf_id_t vrf_id)
304{
305 struct stream *s;
306 u_char type;
307 u_char message_flags;
308 struct kroute kr;
309 int nhnum, nhlen;
310 size_t nhmark;
311
312 memset(&kr, 0, sizeof(kr));
313 s = zclient->ibuf;
314
315 type = stream_getc(s);
316 if (type == ZEBRA_ROUTE_CONNECT)
317 kr.flags |= F_CONNECTED;
318 stream_getc(s); /* flags, unused */
319 stream_getw(s); /* instance, unused */
320 message_flags = stream_getc(s);
321 if (!CHECK_FLAG(message_flags, ZAPI_MESSAGE_NEXTHOP))
322 return (0);
323
324 switch (command) {
325 case ZEBRA_IPV4_ROUTE_ADD:
326 case ZEBRA_REDISTRIBUTE_IPV4_ADD:
327 case ZEBRA_IPV4_ROUTE_DELETE:
328 case ZEBRA_REDISTRIBUTE_IPV4_DEL:
329 kr.af = AF_INET;
330 nhlen = sizeof(struct in_addr);
331 break;
332 case ZEBRA_IPV6_ROUTE_ADD:
333 case ZEBRA_REDISTRIBUTE_IPV6_ADD:
334 case ZEBRA_IPV6_ROUTE_DELETE:
335 case ZEBRA_REDISTRIBUTE_IPV6_DEL:
336 kr.af = AF_INET6;
337 nhlen = sizeof(struct in6_addr);
338 break;
339 default:
340 fatalx("ldp_zebra_read_route: unknown command");
341 }
342 kr.prefixlen = stream_getc(s);
343 stream_get(&kr.prefix, s, PSIZE(kr.prefixlen));
344
345 if (bad_addr(kr.af, &kr.prefix) ||
346 (kr.af == AF_INET6 && IN6_IS_SCOPE_EMBED(&kr.prefix.v6)))
347 return (0);
348
349 nhnum = stream_getc(s);
350 nhmark = stream_get_getp(s);
351 stream_set_getp(s, nhmark + nhnum * (nhlen + 5));
352
353 if (CHECK_FLAG(message_flags, ZAPI_MESSAGE_DISTANCE))
354 kr.priority = stream_getc(s);
355 if (CHECK_FLAG(message_flags, ZAPI_MESSAGE_METRIC))
356 stream_getl(s); /* metric, not used */
357
358 stream_set_getp(s, nhmark);
359
360 /* loop through all the nexthops */
361 for (; nhnum > 0; nhnum--) {
362 switch (kr.af) {
363 case AF_INET:
364 kr.nexthop.v4.s_addr = stream_get_ipv4(s);
365 break;
366 case AF_INET6:
367 stream_get(&kr.nexthop.v6, s, sizeof(kr.nexthop.v6));
368 break;
369 default:
370 break;
371 }
372 stream_getc(s); /* ifindex_num, unused. */
373 kr.ifindex = stream_getl(s);
374
375 switch (command) {
376 case ZEBRA_IPV4_ROUTE_ADD:
377 case ZEBRA_REDISTRIBUTE_IPV4_ADD:
378 case ZEBRA_IPV6_ROUTE_ADD:
379 case ZEBRA_REDISTRIBUTE_IPV6_ADD:
380 debug_zebra_in("route add %s/%d nexthop %s (%s)",
381 log_addr(kr.af, &kr.prefix), kr.prefixlen,
382 log_addr(kr.af, &kr.nexthop),
383 zebra_route_string(type));
384 main_imsg_compose_lde(IMSG_NETWORK_ADD, 0, &kr,
385 sizeof(kr));
386 break;
387 case ZEBRA_IPV4_ROUTE_DELETE:
388 case ZEBRA_REDISTRIBUTE_IPV4_DEL:
389 case ZEBRA_IPV6_ROUTE_DELETE:
390 case ZEBRA_REDISTRIBUTE_IPV6_DEL:
391 debug_zebra_in("route delete %s/%d nexthop %s (%s)",
392 log_addr(kr.af, &kr.prefix), kr.prefixlen,
393 log_addr(kr.af, &kr.nexthop),
394 zebra_route_string(type));
395 main_imsg_compose_lde(IMSG_NETWORK_DEL, 0, &kr,
396 sizeof(kr));
397 break;
398 default:
399 fatalx("ldp_zebra_read_route: unknown command");
400 }
401 }
402
403 return (0);
404}
405
406static void
407ldp_zebra_connected(struct zclient *zclient)
408{
409 int i;
410
411 zclient_send_reg_requests(zclient, VRF_DEFAULT);
412
413 for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
414 switch (i) {
415 case ZEBRA_ROUTE_KERNEL:
416 case ZEBRA_ROUTE_CONNECT:
417 case ZEBRA_ROUTE_STATIC:
418 case ZEBRA_ROUTE_ISIS:
419 zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient,
420 AFI_IP, i, 0, VRF_DEFAULT);
421 zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient,
422 AFI_IP6, i, 0, VRF_DEFAULT);
423 break;
424 case ZEBRA_ROUTE_RIP:
425 case ZEBRA_ROUTE_OSPF:
426 zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient,
427 AFI_IP, i, 0, VRF_DEFAULT);
428 break;
429 case ZEBRA_ROUTE_RIPNG:
430 case ZEBRA_ROUTE_OSPF6:
431 zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient,
432 AFI_IP6, i, 0, VRF_DEFAULT);
433 break;
434 case ZEBRA_ROUTE_BGP:
435 /* LDP should follow the IGP and ignore BGP routes */
436 default:
437 break;
438 }
439 }
440}
441
442void
443ldp_zebra_init(struct thread_master *master)
444{
445 /* Set default values. */
446 zclient = zclient_new(master);
447 zclient_init(zclient, ZEBRA_ROUTE_LDP, 0);
448
449 /* set callbacks */
450 zclient->zebra_connected = ldp_zebra_connected;
451 zclient->router_id_update = ldp_router_id_update;
452 zclient->interface_add = ldp_interface_add;
453 zclient->interface_delete = ldp_interface_delete;
454 zclient->interface_up = ldp_interface_status_change;
455 zclient->interface_down = ldp_interface_status_change;
456 zclient->interface_address_add = ldp_interface_address_add;
457 zclient->interface_address_delete = ldp_interface_address_delete;
458 zclient->ipv4_route_add = ldp_zebra_read_route;
459 zclient->ipv4_route_delete = ldp_zebra_read_route;
460 zclient->redistribute_route_ipv4_add = ldp_zebra_read_route;
461 zclient->redistribute_route_ipv4_del = ldp_zebra_read_route;
462 zclient->ipv6_route_add = ldp_zebra_read_route;
463 zclient->ipv6_route_delete = ldp_zebra_read_route;
464 zclient->redistribute_route_ipv6_add = ldp_zebra_read_route;
465 zclient->redistribute_route_ipv6_del = ldp_zebra_read_route;
466}