2 * Zebra connect library for OSPFd
3 * Copyright (C) 1997, 98, 99, 2000 Kunihiro Ishiguro, Toshiaki Takada
5 * This file is part of GNU Zebra.
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
36 #include "route_opaque.h"
40 #include "ospfd/ospfd.h"
41 #include "ospfd/ospf_interface.h"
42 #include "ospfd/ospf_ism.h"
43 #include "ospfd/ospf_asbr.h"
44 #include "ospfd/ospf_asbr.h"
45 #include "ospfd/ospf_abr.h"
46 #include "ospfd/ospf_lsa.h"
47 #include "ospfd/ospf_dump.h"
48 #include "ospfd/ospf_route.h"
49 #include "ospfd/ospf_lsdb.h"
50 #include "ospfd/ospf_neighbor.h"
51 #include "ospfd/ospf_nsm.h"
52 #include "ospfd/ospf_zebra.h"
53 #include "ospfd/ospf_te.h"
54 #include "ospfd/ospf_sr.h"
55 #include "ospfd/ospf_ldp_sync.h"
57 DEFINE_MTYPE_STATIC(OSPFD
, OSPF_EXTERNAL
, "OSPF External route table");
58 DEFINE_MTYPE_STATIC(OSPFD
, OSPF_REDISTRIBUTE
, "OSPF Redistriute");
61 /* Zebra structure to hold current status. */
62 struct zclient
*zclient
= NULL
;
63 /* and for the Synchronous connection to the Label Manager */
64 static struct zclient
*zclient_sync
;
66 /* For registering threads. */
67 extern struct thread_master
*master
;
69 /* Router-id update message from zebra. */
70 static int ospf_router_id_update_zebra(ZAPI_CALLBACK_ARGS
)
72 struct ospf
*ospf
= NULL
;
73 struct prefix router_id
;
74 zebra_router_id_update_read(zclient
->ibuf
, &router_id
);
76 if (IS_DEBUG_OSPF(zebra
, ZEBRA_INTERFACE
))
77 zlog_debug("Zebra rcvd: router id update %pFX vrf %s id %u",
78 &router_id
, ospf_vrf_id_to_name(vrf_id
), vrf_id
);
80 ospf
= ospf_lookup_by_vrf_id(vrf_id
);
83 ospf
->router_id_zebra
= router_id
.u
.prefix4
;
84 ospf_router_id_update(ospf
);
86 if (IS_DEBUG_OSPF_EVENT
)
88 "%s: ospf instance not found for vrf %s id %u router_id %pFX",
89 __func__
, ospf_vrf_id_to_name(vrf_id
), vrf_id
,
95 static int ospf_interface_address_add(ZAPI_CALLBACK_ARGS
)
98 struct ospf
*ospf
= NULL
;
101 c
= zebra_interface_address_read(cmd
, zclient
->ibuf
, vrf_id
);
106 if (IS_DEBUG_OSPF(zebra
, ZEBRA_INTERFACE
))
107 zlog_debug("Zebra: interface %s address add %pFX vrf %s id %u",
108 c
->ifp
->name
, c
->address
,
109 ospf_vrf_id_to_name(vrf_id
), vrf_id
);
111 ospf
= ospf_lookup_by_vrf_id(vrf_id
);
115 ospf_if_update(ospf
, c
->ifp
);
117 ospf_if_interface(c
->ifp
);
122 static int ospf_interface_address_delete(ZAPI_CALLBACK_ARGS
)
125 struct interface
*ifp
;
126 struct ospf_interface
*oi
;
127 struct route_node
*rn
;
130 c
= zebra_interface_address_read(cmd
, zclient
->ibuf
, vrf_id
);
135 if (IS_DEBUG_OSPF(zebra
, ZEBRA_INTERFACE
))
136 zlog_debug("Zebra: interface %s address delete %pFX",
137 c
->ifp
->name
, c
->address
);
141 p
.prefixlen
= IPV4_MAX_BITLEN
;
143 rn
= route_node_lookup(IF_OIFS(ifp
), &p
);
151 route_unlock_node(rn
);
153 /* Call interface hook functions to clean up */
156 ospf_if_interface(c
->ifp
);
163 static int ospf_interface_link_params(ZAPI_CALLBACK_ARGS
)
165 struct interface
*ifp
;
166 bool changed
= false;
168 ifp
= zebra_interface_link_params_read(zclient
->ibuf
, vrf_id
, &changed
);
170 if (ifp
== NULL
|| !changed
)
174 ospf_mpls_te_update_if(ifp
);
179 /* VRF update for an interface. */
180 static int ospf_interface_vrf_update(ZAPI_CALLBACK_ARGS
)
182 struct interface
*ifp
= NULL
;
185 ifp
= zebra_interface_vrf_update_read(zclient
->ibuf
, vrf_id
,
190 if (IS_DEBUG_OSPF_EVENT
)
192 "%s: Rx Interface %s VRF change vrf_id %u New vrf %s id %u",
193 __func__
, ifp
->name
, vrf_id
,
194 ospf_vrf_id_to_name(new_vrf_id
), new_vrf_id
);
196 /*if_update(ifp, ifp->name, strlen(ifp->name), new_vrf_id);*/
197 if_update_to_new_vrf(ifp
, new_vrf_id
);
202 /* Nexthop, ifindex, distance and metric information. */
203 static void ospf_zebra_add_nexthop(struct ospf
*ospf
, struct ospf_path
*path
,
204 struct zapi_route
*api
)
206 struct zapi_nexthop
*api_nh
;
207 struct zapi_nexthop
*api_nh_backup
;
209 /* TI-LFA backup path label stack comes first, if present */
210 if (path
->srni
.backup_label_stack
) {
211 api_nh_backup
= &api
->backup_nexthops
[api
->backup_nexthop_num
];
212 api_nh_backup
->vrf_id
= ospf
->vrf_id
;
214 api_nh_backup
->type
= NEXTHOP_TYPE_IPV4
;
215 api_nh_backup
->gate
.ipv4
= path
->srni
.backup_nexthop
;
217 api_nh_backup
->label_num
=
218 path
->srni
.backup_label_stack
->num_labels
;
219 memcpy(api_nh_backup
->labels
,
220 path
->srni
.backup_label_stack
->label
,
221 sizeof(mpls_label_t
) * api_nh_backup
->label_num
);
223 api
->backup_nexthop_num
++;
226 /* And here comes the primary nexthop */
227 api_nh
= &api
->nexthops
[api
->nexthop_num
];
230 || (path
->nexthop
.s_addr
!= INADDR_ANY
&& path
->ifindex
!= 0)) {
231 #else /* HAVE_NETLINK */
232 if (path
->nexthop
.s_addr
!= INADDR_ANY
&& path
->ifindex
!= 0) {
233 #endif /* HAVE_NETLINK */
234 api_nh
->gate
.ipv4
= path
->nexthop
;
235 api_nh
->ifindex
= path
->ifindex
;
236 api_nh
->type
= NEXTHOP_TYPE_IPV4_IFINDEX
;
237 } else if (path
->nexthop
.s_addr
!= INADDR_ANY
) {
238 api_nh
->gate
.ipv4
= path
->nexthop
;
239 api_nh
->type
= NEXTHOP_TYPE_IPV4
;
241 api_nh
->ifindex
= path
->ifindex
;
242 api_nh
->type
= NEXTHOP_TYPE_IFINDEX
;
244 api_nh
->vrf_id
= ospf
->vrf_id
;
246 /* Set TI-LFA backup nexthop info if present */
247 if (path
->srni
.backup_label_stack
) {
248 SET_FLAG(api
->message
, ZAPI_MESSAGE_BACKUP_NEXTHOPS
);
249 SET_FLAG(api_nh
->flags
, ZAPI_NEXTHOP_FLAG_HAS_BACKUP
);
251 /* Just care about a single TI-LFA backup path for now */
252 api_nh
->backup_num
= 1;
253 api_nh
->backup_idx
[0] = api
->backup_nexthop_num
- 1;
259 static void ospf_zebra_append_opaque_attr(struct ospf_route
*or,
260 struct zapi_route
*api
)
262 struct ospf_zebra_opaque ospf_opaque
= {};
265 snprintf(ospf_opaque
.path_type
, sizeof(ospf_opaque
.path_type
), "%s",
266 ospf_path_type_name(or->path_type
));
268 switch (or->path_type
) {
269 case OSPF_PATH_INTRA_AREA
:
270 case OSPF_PATH_INTER_AREA
:
272 (void)inet_ntop(AF_INET
, &or->u
.std
.area_id
,
274 sizeof(ospf_opaque
.area_id
));
276 case OSPF_PATH_TYPE1_EXTERNAL
:
277 case OSPF_PATH_TYPE2_EXTERNAL
:
279 snprintf(ospf_opaque
.tag
, sizeof(ospf_opaque
.tag
), "%u",
286 SET_FLAG(api
->message
, ZAPI_MESSAGE_OPAQUE
);
287 api
->opaque
.length
= sizeof(struct ospf_zebra_opaque
);
288 memcpy(api
->opaque
.data
, &ospf_opaque
, api
->opaque
.length
);
291 void ospf_zebra_add(struct ospf
*ospf
, struct prefix_ipv4
*p
,
292 struct ospf_route
* or)
294 struct zapi_route api
;
296 struct ospf_path
*path
;
297 struct listnode
*node
;
299 if (ospf
->gr_info
.restart_in_progress
) {
300 if (IS_DEBUG_OSPF_GR
)
302 "Zebra: Graceful Restart in progress -- not installing %pFX",
307 memset(&api
, 0, sizeof(api
));
308 api
.vrf_id
= ospf
->vrf_id
;
309 api
.type
= ZEBRA_ROUTE_OSPF
;
310 api
.instance
= ospf
->instance
;
311 api
.safi
= SAFI_UNICAST
;
313 memcpy(&api
.prefix
, p
, sizeof(*p
));
314 SET_FLAG(api
.message
, ZAPI_MESSAGE_NEXTHOP
);
317 SET_FLAG(api
.message
, ZAPI_MESSAGE_METRIC
);
318 if (or->path_type
== OSPF_PATH_TYPE1_EXTERNAL
)
319 api
.metric
= or->cost
+ or->u
.ext
.type2_cost
;
320 else if (or->path_type
== OSPF_PATH_TYPE2_EXTERNAL
)
321 api
.metric
= or->u
.ext
.type2_cost
;
323 api
.metric
= or->cost
;
325 /* Check if path type is ASE */
326 if (((or->path_type
== OSPF_PATH_TYPE1_EXTERNAL
)
327 || (or->path_type
== OSPF_PATH_TYPE2_EXTERNAL
))
328 && (or->u
.ext
.tag
> 0) && (or->u
.ext
.tag
<= ROUTE_TAG_MAX
)) {
329 SET_FLAG(api
.message
, ZAPI_MESSAGE_TAG
);
330 api
.tag
= or->u
.ext
.tag
;
333 /* Distance value. */
334 distance
= ospf_distance_apply(ospf
, p
, or);
336 SET_FLAG(api
.message
, ZAPI_MESSAGE_DISTANCE
);
337 api
.distance
= distance
;
340 for (ALL_LIST_ELEMENTS_RO(or->paths
, node
, path
)) {
341 if (api
.nexthop_num
>= ospf
->max_multipath
)
344 ospf_zebra_add_nexthop(ospf
, path
, &api
);
346 if (IS_DEBUG_OSPF(zebra
, ZEBRA_REDISTRIBUTE
)) {
347 struct interface
*ifp
;
349 ifp
= if_lookup_by_index(path
->ifindex
, ospf
->vrf_id
);
352 "Zebra: Route add %pFX nexthop %pI4, ifindex=%d %s",
353 p
, &path
->nexthop
, path
->ifindex
,
354 ifp
? ifp
->name
: " ");
358 if (CHECK_FLAG(ospf
->config
, OSPF_SEND_EXTRA_DATA_TO_ZEBRA
))
359 ospf_zebra_append_opaque_attr(or, &api
);
361 zclient_route_send(ZEBRA_ROUTE_ADD
, zclient
, &api
);
364 void ospf_zebra_delete(struct ospf
*ospf
, struct prefix_ipv4
*p
,
365 struct ospf_route
* or)
367 struct zapi_route api
;
369 if (ospf
->gr_info
.restart_in_progress
) {
370 if (IS_DEBUG_OSPF_GR
)
372 "Zebra: Graceful Restart in progress -- not uninstalling %pFX",
377 memset(&api
, 0, sizeof(api
));
378 api
.vrf_id
= ospf
->vrf_id
;
379 api
.type
= ZEBRA_ROUTE_OSPF
;
380 api
.instance
= ospf
->instance
;
381 api
.safi
= SAFI_UNICAST
;
382 memcpy(&api
.prefix
, p
, sizeof(*p
));
384 if (IS_DEBUG_OSPF(zebra
, ZEBRA_REDISTRIBUTE
))
385 zlog_debug("Zebra: Route delete %pFX", p
);
387 zclient_route_send(ZEBRA_ROUTE_DELETE
, zclient
, &api
);
390 void ospf_zebra_add_discard(struct ospf
*ospf
, struct prefix_ipv4
*p
)
392 struct zapi_route api
;
394 if (ospf
->gr_info
.restart_in_progress
) {
395 if (IS_DEBUG_OSPF_GR
)
397 "Zebra: Graceful Restart in progress -- not installing %pFX",
402 memset(&api
, 0, sizeof(api
));
403 api
.vrf_id
= ospf
->vrf_id
;
404 api
.type
= ZEBRA_ROUTE_OSPF
;
405 api
.instance
= ospf
->instance
;
406 api
.safi
= SAFI_UNICAST
;
407 memcpy(&api
.prefix
, p
, sizeof(*p
));
408 zapi_route_set_blackhole(&api
, BLACKHOLE_NULL
);
410 zclient_route_send(ZEBRA_ROUTE_ADD
, zclient
, &api
);
412 if (IS_DEBUG_OSPF(zebra
, ZEBRA_REDISTRIBUTE
))
413 zlog_debug("Zebra: Route add discard %pFX", p
);
416 void ospf_zebra_delete_discard(struct ospf
*ospf
, struct prefix_ipv4
*p
)
418 struct zapi_route api
;
420 if (ospf
->gr_info
.restart_in_progress
) {
421 if (IS_DEBUG_OSPF_GR
)
423 "Zebra: Graceful Restart in progress -- not uninstalling %pFX",
428 memset(&api
, 0, sizeof(api
));
429 api
.vrf_id
= ospf
->vrf_id
;
430 api
.type
= ZEBRA_ROUTE_OSPF
;
431 api
.instance
= ospf
->instance
;
432 api
.safi
= SAFI_UNICAST
;
433 memcpy(&api
.prefix
, p
, sizeof(*p
));
434 zapi_route_set_blackhole(&api
, BLACKHOLE_NULL
);
436 zclient_route_send(ZEBRA_ROUTE_DELETE
, zclient
, &api
);
438 if (IS_DEBUG_OSPF(zebra
, ZEBRA_REDISTRIBUTE
))
439 zlog_debug("Zebra: Route delete discard %pFX", p
);
442 struct ospf_external
*ospf_external_lookup(struct ospf
*ospf
, uint8_t type
,
443 unsigned short instance
)
445 struct list
*ext_list
;
446 struct listnode
*node
;
447 struct ospf_external
*ext
;
449 ext_list
= ospf
->external
[type
];
453 for (ALL_LIST_ELEMENTS_RO(ext_list
, node
, ext
))
454 if (ext
->instance
== instance
)
460 struct ospf_external
*ospf_external_add(struct ospf
*ospf
, uint8_t type
,
461 unsigned short instance
)
463 struct list
*ext_list
;
464 struct ospf_external
*ext
;
466 ext
= ospf_external_lookup(ospf
, type
, instance
);
470 if (!ospf
->external
[type
])
471 ospf
->external
[type
] = list_new();
473 ext_list
= ospf
->external
[type
];
474 ext
= XCALLOC(MTYPE_OSPF_EXTERNAL
, sizeof(struct ospf_external
));
475 ext
->instance
= instance
;
476 EXTERNAL_INFO(ext
) = route_table_init();
478 listnode_add(ext_list
, ext
);
484 * Walk all the ei received from zebra for a route type and apply
487 bool ospf_external_default_routemap_apply_walk(struct ospf
*ospf
,
488 struct list
*ext_list
,
489 struct external_info
*default_ei
)
491 struct listnode
*node
;
492 struct ospf_external
*ext
;
493 struct route_node
*rn
;
494 struct external_info
*ei
= NULL
;
497 for (ALL_LIST_ELEMENTS_RO(ext_list
, node
, ext
)) {
498 if (!ext
->external_info
)
501 for (rn
= route_top(ext
->external_info
); rn
;
502 rn
= route_next(rn
)) {
506 ret
= ospf_external_info_apply_default_routemap(
507 ospf
, ei
, default_ei
);
514 if (IS_DEBUG_OSPF_DEFAULT_INFO
)
515 zlog_debug("Default originate routemap permit ei: %pI4",
524 * Function to originate or flush default after applying
525 * route-map on all ei.
527 static void ospf_external_lsa_default_routemap_timer(struct thread
*thread
)
529 struct list
*ext_list
;
530 struct ospf
*ospf
= THREAD_ARG(thread
);
531 struct prefix_ipv4 p
;
534 struct ospf_lsa
*lsa
;
535 struct external_info
*default_ei
;
539 p
.prefix
.s_addr
= INADDR_ANY
;
541 /* Get the default extenal info. */
542 default_ei
= ospf_external_info_lookup(ospf
, DEFAULT_ROUTE
,
545 /* Nothing to be done here. */
546 if (IS_DEBUG_OSPF_DEFAULT_INFO
)
547 zlog_debug("Default originate info not present");
551 /* For all the ei apply route-map */
552 for (type
= 0; type
<= ZEBRA_ROUTE_MAX
; type
++) {
553 ext_list
= ospf
->external
[type
];
554 if (!ext_list
|| type
== ZEBRA_ROUTE_OSPF
)
557 ret
= ospf_external_default_routemap_apply_walk(ospf
, ext_list
,
563 /* Get the default LSA. */
564 lsa
= ospf_external_info_find_lsa(ospf
, &p
);
566 /* If permit then originate default. */
568 ospf_external_lsa_originate(ospf
, default_ei
);
569 else if (ret
&& lsa
&& IS_LSA_MAXAGE(lsa
))
570 ospf_external_lsa_refresh(ospf
, lsa
, default_ei
, true, false);
571 else if (!ret
&& lsa
)
572 ospf_external_lsa_flush(ospf
, DEFAULT_ROUTE
, &default_ei
->p
, 0);
576 void ospf_external_del(struct ospf
*ospf
, uint8_t type
, unsigned short instance
)
578 struct ospf_external
*ext
;
580 ext
= ospf_external_lookup(ospf
, type
, instance
);
583 if (EXTERNAL_INFO(ext
))
584 route_table_finish(EXTERNAL_INFO(ext
));
586 listnode_delete(ospf
->external
[type
], ext
);
588 if (!ospf
->external
[type
]->count
)
589 list_delete(&ospf
->external
[type
]);
591 XFREE(MTYPE_OSPF_EXTERNAL
, ext
);
595 * Check if default needs to be flushed too.
597 thread_add_event(master
, ospf_external_lsa_default_routemap_timer
, ospf
,
598 0, &ospf
->t_default_routemap_timer
);
601 /* Update NHLFE for Prefix SID */
602 void ospf_zebra_update_prefix_sid(const struct sr_prefix
*srp
)
604 struct zapi_labels zl
;
605 struct zapi_nexthop
*znh
;
606 struct zapi_nexthop
*znh_backup
;
607 struct listnode
*node
;
608 struct ospf_path
*path
;
610 /* Prepare message. */
611 memset(&zl
, 0, sizeof(zl
));
612 zl
.type
= ZEBRA_LSP_OSPF_SR
;
613 zl
.local_label
= srp
->label_in
;
617 /* Set Label for local Prefix */
618 znh
= &zl
.nexthops
[zl
.nexthop_num
++];
619 znh
->type
= NEXTHOP_TYPE_IFINDEX
;
620 znh
->ifindex
= srp
->nhlfe
.ifindex
;
622 znh
->labels
[0] = srp
->nhlfe
.label_out
;
624 osr_debug("SR (%s): Configure Prefix %pFX with labels %u/%u",
625 __func__
, (struct prefix
*)&srp
->prefv4
,
626 srp
->label_in
, srp
->nhlfe
.label_out
);
631 /* Update route in the RIB too. */
632 SET_FLAG(zl
.message
, ZAPI_LABELS_FTN
);
633 zl
.route
.prefix
.u
.prefix4
= srp
->prefv4
.prefix
;
634 zl
.route
.prefix
.prefixlen
= srp
->prefv4
.prefixlen
;
635 zl
.route
.prefix
.family
= srp
->prefv4
.family
;
636 zl
.route
.type
= ZEBRA_ROUTE_OSPF
;
637 zl
.route
.instance
= 0;
639 /* Check that SRP contains at least one valid path */
640 if (srp
->route
== NULL
) {
644 osr_debug("SR (%s): Configure Prefix %pFX with",
645 __func__
, (struct prefix
*)&srp
->prefv4
);
647 for (ALL_LIST_ELEMENTS_RO(srp
->route
->paths
, node
, path
)) {
648 if (path
->srni
.label_out
== MPLS_INVALID_LABEL
)
651 if (zl
.nexthop_num
>= MULTIPATH_NUM
)
655 * TI-LFA backup path label stack comes first, if
658 if (path
->srni
.backup_label_stack
) {
659 znh_backup
= &zl
.backup_nexthops
660 [zl
.backup_nexthop_num
++];
661 znh_backup
->type
= NEXTHOP_TYPE_IPV4
;
662 znh_backup
->gate
.ipv4
=
663 path
->srni
.backup_nexthop
;
665 memcpy(znh_backup
->labels
,
666 path
->srni
.backup_label_stack
->label
,
668 * path
->srni
.backup_label_stack
671 znh_backup
->label_num
=
672 path
->srni
.backup_label_stack
674 if (path
->srni
.label_out
675 != MPLS_LABEL_IPV4_EXPLICIT_NULL
676 && path
->srni
.label_out
677 != MPLS_LABEL_IMPLICIT_NULL
)
679 [znh_backup
->label_num
++] =
680 path
->srni
.label_out
;
683 znh
= &zl
.nexthops
[zl
.nexthop_num
++];
684 znh
->type
= NEXTHOP_TYPE_IPV4_IFINDEX
;
685 znh
->gate
.ipv4
= path
->nexthop
;
686 znh
->ifindex
= path
->ifindex
;
688 znh
->labels
[0] = path
->srni
.label_out
;
690 osr_debug(" |- labels %u/%u", srp
->label_in
,
691 path
->srni
.label_out
);
693 /* Set TI-LFA backup nexthop info if present */
694 if (path
->srni
.backup_label_stack
) {
695 SET_FLAG(zl
.message
, ZAPI_LABELS_HAS_BACKUPS
);
697 ZAPI_NEXTHOP_FLAG_HAS_BACKUP
);
699 /* Just care about a single TI-LFA backup path
702 znh
->backup_idx
[0] = zl
.backup_nexthop_num
- 1;
711 /* Finally, send message to zebra. */
712 (void)zebra_send_mpls_labels(zclient
, ZEBRA_MPLS_LABELS_REPLACE
, &zl
);
715 /* Remove NHLFE for Prefix-SID */
716 void ospf_zebra_delete_prefix_sid(const struct sr_prefix
*srp
)
718 struct zapi_labels zl
;
720 osr_debug("SR (%s): Delete Labels %u for Prefix %pFX", __func__
,
721 srp
->label_in
, (struct prefix
*)&srp
->prefv4
);
723 /* Prepare message. */
724 memset(&zl
, 0, sizeof(zl
));
725 zl
.type
= ZEBRA_LSP_OSPF_SR
;
726 zl
.local_label
= srp
->label_in
;
728 if (srp
->type
== PREF_SID
) {
729 /* Update route in the RIB too */
730 SET_FLAG(zl
.message
, ZAPI_LABELS_FTN
);
731 zl
.route
.prefix
.u
.prefix4
= srp
->prefv4
.prefix
;
732 zl
.route
.prefix
.prefixlen
= srp
->prefv4
.prefixlen
;
733 zl
.route
.prefix
.family
= srp
->prefv4
.family
;
734 zl
.route
.type
= ZEBRA_ROUTE_OSPF
;
735 zl
.route
.instance
= 0;
738 /* Send message to zebra. */
739 (void)zebra_send_mpls_labels(zclient
, ZEBRA_MPLS_LABELS_DELETE
, &zl
);
742 /* Send MPLS Label entry to Zebra for installation or deletion */
743 void ospf_zebra_send_adjacency_sid(int cmd
, struct sr_nhlfe nhlfe
)
745 struct zapi_labels zl
;
746 struct zapi_nexthop
*znh
;
748 osr_debug("SR (%s): %s Labels %u/%u for Adjacency via %u", __func__
,
749 cmd
== ZEBRA_MPLS_LABELS_ADD
? "Add" : "Delete",
750 nhlfe
.label_in
, nhlfe
.label_out
, nhlfe
.ifindex
);
752 memset(&zl
, 0, sizeof(zl
));
753 zl
.type
= ZEBRA_LSP_OSPF_SR
;
754 zl
.local_label
= nhlfe
.label_in
;
756 znh
= &zl
.nexthops
[0];
757 znh
->type
= NEXTHOP_TYPE_IPV4_IFINDEX
;
758 znh
->gate
.ipv4
= nhlfe
.nexthop
;
759 znh
->ifindex
= nhlfe
.ifindex
;
761 znh
->labels
[0] = nhlfe
.label_out
;
763 (void)zebra_send_mpls_labels(zclient
, cmd
, &zl
);
766 struct ospf_redist
*ospf_redist_lookup(struct ospf
*ospf
, uint8_t type
,
767 unsigned short instance
)
769 struct list
*red_list
;
770 struct listnode
*node
;
771 struct ospf_redist
*red
;
773 red_list
= ospf
->redist
[type
];
777 for (ALL_LIST_ELEMENTS_RO(red_list
, node
, red
))
778 if (red
->instance
== instance
)
784 struct ospf_redist
*ospf_redist_add(struct ospf
*ospf
, uint8_t type
,
785 unsigned short instance
)
787 struct list
*red_list
;
788 struct ospf_redist
*red
;
790 red
= ospf_redist_lookup(ospf
, type
, instance
);
794 if (!ospf
->redist
[type
])
795 ospf
->redist
[type
] = list_new();
797 red_list
= ospf
->redist
[type
];
798 red
= XCALLOC(MTYPE_OSPF_REDISTRIBUTE
, sizeof(struct ospf_redist
));
799 red
->instance
= instance
;
800 red
->dmetric
.type
= -1;
801 red
->dmetric
.value
= -1;
802 ROUTEMAP_NAME(red
) = NULL
;
803 ROUTEMAP(red
) = NULL
;
805 listnode_add(red_list
, red
);
810 void ospf_redist_del(struct ospf
*ospf
, uint8_t type
, unsigned short instance
)
812 struct ospf_redist
*red
;
814 red
= ospf_redist_lookup(ospf
, type
, instance
);
817 listnode_delete(ospf
->redist
[type
], red
);
818 if (!ospf
->redist
[type
]->count
) {
819 list_delete(&ospf
->redist
[type
]);
821 ospf_routemap_unset(red
);
822 XFREE(MTYPE_OSPF_REDISTRIBUTE
, red
);
827 int ospf_is_type_redistributed(struct ospf
*ospf
, int type
,
828 unsigned short instance
)
830 return (DEFAULT_ROUTE_TYPE(type
)
831 ? vrf_bitmap_check(zclient
->default_information
[AFI_IP
],
834 && redist_check_instance(
835 &zclient
->mi_redist
[AFI_IP
][type
],
839 zclient
->redist
[AFI_IP
][type
],
843 int ospf_redistribute_update(struct ospf
*ospf
, struct ospf_redist
*red
,
844 int type
, unsigned short instance
, int mtype
,
849 if (mtype
!= red
->dmetric
.type
) {
850 red
->dmetric
.type
= mtype
;
851 force
= LSA_REFRESH_FORCE
;
853 if (mvalue
!= red
->dmetric
.value
) {
854 red
->dmetric
.value
= mvalue
;
855 force
= LSA_REFRESH_FORCE
;
858 ospf_external_lsa_refresh_type(ospf
, type
, instance
, force
);
860 if (IS_DEBUG_OSPF(zebra
, ZEBRA_REDISTRIBUTE
))
862 "Redistribute[%s][%d]: Refresh Type[%d], Metric[%d]",
863 ospf_redist_string(type
), instance
,
864 metric_type(ospf
, type
, instance
),
865 metric_value(ospf
, type
, instance
));
870 int ospf_redistribute_set(struct ospf
*ospf
, struct ospf_redist
*red
, int type
,
871 unsigned short instance
, int mtype
, int mvalue
)
873 red
->dmetric
.type
= mtype
;
874 red
->dmetric
.value
= mvalue
;
876 ospf_external_add(ospf
, type
, instance
);
878 zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP
, type
,
879 instance
, ospf
->vrf_id
);
881 if (IS_DEBUG_OSPF(zebra
, ZEBRA_REDISTRIBUTE
))
883 "Redistribute[%s][%d] vrf id %u: Start Type[%d], Metric[%d]",
884 ospf_redist_string(type
), instance
, ospf
->vrf_id
,
885 metric_type(ospf
, type
, instance
),
886 metric_value(ospf
, type
, instance
));
888 ospf_asbr_status_update(ospf
, ++ospf
->redistribute
);
893 int ospf_redistribute_unset(struct ospf
*ospf
, int type
,
894 unsigned short instance
)
896 if (type
== zclient
->redist_default
&& instance
== zclient
->instance
)
899 zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE
, zclient
, AFI_IP
, type
,
900 instance
, ospf
->vrf_id
);
902 if (IS_DEBUG_OSPF(zebra
, ZEBRA_REDISTRIBUTE
))
903 zlog_debug("Redistribute[%s][%d] vrf id %u: Stop",
904 ospf_redist_string(type
), instance
, ospf
->vrf_id
);
906 /* Remove the routes from OSPF table. */
907 ospf_redistribute_withdraw(ospf
, type
, instance
);
909 ospf_external_del(ospf
, type
, instance
);
911 ospf_asbr_status_update(ospf
, --ospf
->redistribute
);
916 int ospf_redistribute_default_set(struct ospf
*ospf
, int originate
, int mtype
,
919 struct prefix_ipv4 p
;
920 struct in_addr nexthop
;
921 int cur_originate
= ospf
->default_originate
;
922 const char *type_str
= NULL
;
924 nexthop
.s_addr
= INADDR_ANY
;
926 p
.prefix
.s_addr
= INADDR_ANY
;
929 ospf
->default_originate
= originate
;
931 if (cur_originate
== originate
) {
932 /* Refresh the lsa since metric might different */
933 if (IS_DEBUG_OSPF(zebra
, ZEBRA_REDISTRIBUTE
))
935 "Redistribute[%s]: Refresh Type[%d], Metric[%d]",
936 ospf_redist_string(DEFAULT_ROUTE
),
937 metric_type(ospf
, DEFAULT_ROUTE
, 0),
938 metric_value(ospf
, DEFAULT_ROUTE
, 0));
940 ospf_external_lsa_refresh_default(ospf
);
944 switch (cur_originate
) {
945 case DEFAULT_ORIGINATE_NONE
:
947 case DEFAULT_ORIGINATE_ZEBRA
:
948 zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE
,
949 zclient
, AFI_IP
, ospf
->vrf_id
);
950 ospf
->redistribute
--;
952 case DEFAULT_ORIGINATE_ALWAYS
:
953 ospf_external_info_delete(ospf
, DEFAULT_ROUTE
, 0, p
);
954 ospf_external_del(ospf
, DEFAULT_ROUTE
, 0);
955 ospf
->redistribute
--;
960 case DEFAULT_ORIGINATE_NONE
:
963 case DEFAULT_ORIGINATE_ZEBRA
:
965 ospf
->redistribute
++;
966 zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD
,
967 zclient
, AFI_IP
, ospf
->vrf_id
);
969 case DEFAULT_ORIGINATE_ALWAYS
:
971 ospf
->redistribute
++;
972 ospf_external_add(ospf
, DEFAULT_ROUTE
, 0);
973 ospf_external_info_add(ospf
, DEFAULT_ROUTE
, 0, p
, 0, nexthop
,
978 if (IS_DEBUG_OSPF(zebra
, ZEBRA_REDISTRIBUTE
))
979 zlog_debug("Redistribute[DEFAULT]: %s Type[%d], Metric[%d]",
981 metric_type(ospf
, DEFAULT_ROUTE
, 0),
982 metric_value(ospf
, DEFAULT_ROUTE
, 0));
984 ospf_external_lsa_refresh_default(ospf
);
985 ospf_asbr_status_update(ospf
, ospf
->redistribute
);
989 static int ospf_external_lsa_originate_check(struct ospf
*ospf
,
990 struct external_info
*ei
)
992 /* If prefix is multicast, then do not originate LSA. */
993 if (IN_MULTICAST(htonl(ei
->p
.prefix
.s_addr
))) {
995 "LSA[Type5:%pI4]: Not originate AS-external-LSA, Prefix belongs multicast",
1000 /* Take care of default-originate. */
1001 if (is_default_prefix4(&ei
->p
))
1002 if (ospf
->default_originate
== DEFAULT_ORIGINATE_NONE
) {
1004 "LSA[Type5:0.0.0.0]: Not originate AS-external-LSA for default");
1011 /* If connected prefix is OSPF enable interface, then do not announce. */
1012 int ospf_distribute_check_connected(struct ospf
*ospf
, struct external_info
*ei
)
1014 struct listnode
*node
;
1015 struct ospf_interface
*oi
;
1018 for (ALL_LIST_ELEMENTS_RO(ospf
->oiflist
, node
, oi
))
1019 if (prefix_match(oi
->address
, (struct prefix
*)&ei
->p
))
1025 /* Apply default route-map on ei received. */
1026 int ospf_external_info_apply_default_routemap(struct ospf
*ospf
,
1027 struct external_info
*ei
,
1028 struct external_info
*default_ei
)
1030 struct ospf_redist
*red
;
1031 int type
= default_ei
->type
;
1032 struct prefix_ipv4
*p
= &ei
->p
;
1033 struct route_map_set_values save_values
;
1036 if (!ospf_external_lsa_originate_check(ospf
, default_ei
))
1039 save_values
= default_ei
->route_map_set
;
1040 ospf_reset_route_map_set_values(&default_ei
->route_map_set
);
1042 /* apply route-map if needed */
1043 red
= ospf_redist_lookup(ospf
, type
, ospf
->instance
);
1044 if (red
&& ROUTEMAP_NAME(red
)) {
1045 route_map_result_t ret
;
1047 ret
= route_map_apply(ROUTEMAP(red
), (struct prefix
*)p
, ei
);
1049 if (ret
== RMAP_DENYMATCH
) {
1050 ei
->route_map_set
= save_values
;
1060 * Default originated is based on route-map condition then
1061 * apply route-map on received external info. Originate or
1062 * flush based on route-map condition.
1064 static bool ospf_external_lsa_default_routemap_apply(struct ospf
*ospf
,
1065 struct external_info
*ei
,
1068 struct external_info
*default_ei
;
1069 struct prefix_ipv4 p
;
1070 struct ospf_lsa
*lsa
;
1075 p
.prefix
.s_addr
= INADDR_ANY
;
1078 /* Get the default extenal info. */
1079 default_ei
= ospf_external_info_lookup(ospf
, DEFAULT_ROUTE
,
1080 ospf
->instance
, &p
);
1082 /* Nothing to be done here. */
1086 if (IS_DEBUG_OSPF_DEFAULT_INFO
)
1087 zlog_debug("Apply default originate routemap on ei: %pI4 cmd: %d",
1088 &ei
->p
.prefix
, cmd
);
1090 ret
= ospf_external_info_apply_default_routemap(ospf
, ei
, default_ei
);
1092 /* If deny then nothing to be done both in add and del case. */
1094 if (IS_DEBUG_OSPF_DEFAULT_INFO
)
1095 zlog_debug("Default originte routemap deny for ei: %pI4",
1100 /* Get the default LSA. */
1101 lsa
= ospf_external_info_find_lsa(ospf
, &p
);
1103 /* If this is add route and permit then ooriginate default. */
1104 if (cmd
== ZEBRA_REDISTRIBUTE_ROUTE_ADD
) {
1105 /* If permit and default already advertise then return. */
1106 if (lsa
&& !IS_LSA_MAXAGE(lsa
)) {
1107 if (IS_DEBUG_OSPF_DEFAULT_INFO
)
1108 zlog_debug("Default lsa already originated");
1112 if (IS_DEBUG_OSPF_DEFAULT_INFO
)
1113 zlog_debug("Originating/Refreshing default lsa");
1115 if (lsa
&& IS_LSA_MAXAGE(lsa
))
1117 ospf_external_lsa_refresh(ospf
, lsa
, default_ei
, true,
1120 /* If permit and default not advertised then advertise.
1122 ospf_external_lsa_originate(ospf
, default_ei
);
1124 } else if (cmd
== ZEBRA_REDISTRIBUTE_ROUTE_DEL
) {
1125 /* If deny and lsa is not originated then nothing to be done.*/
1127 if (IS_DEBUG_OSPF_DEFAULT_INFO
)
1129 "Default lsa not originated, not flushing");
1133 if (IS_DEBUG_OSPF_DEFAULT_INFO
)
1135 "Running default route-map again as ei: %pI4 deleted",
1138 * if this route delete was permitted then we need to check
1139 * there are any other external info which can still trigger
1140 * default route origination else flush it.
1142 thread_add_event(master
,
1143 ospf_external_lsa_default_routemap_timer
, ospf
,
1144 0, &ospf
->t_default_routemap_timer
);
1150 /* return 1 if external LSA must be originated, 0 otherwise */
1151 int ospf_redistribute_check(struct ospf
*ospf
, struct external_info
*ei
,
1154 struct route_map_set_values save_values
;
1155 struct prefix_ipv4
*p
= &ei
->p
;
1156 struct ospf_redist
*red
;
1157 uint8_t type
= is_default_prefix4(&ei
->p
) ? DEFAULT_ROUTE
: ei
->type
;
1158 unsigned short instance
= is_default_prefix4(&ei
->p
) ? 0 : ei
->instance
;
1159 route_tag_t saved_tag
= 0;
1161 /* Default is handled differently. */
1162 if (type
== DEFAULT_ROUTE
)
1168 if (!ospf_external_lsa_originate_check(ospf
, ei
))
1171 /* Take care connected route. */
1172 if (type
== ZEBRA_ROUTE_CONNECT
1173 && !ospf_distribute_check_connected(ospf
, ei
))
1176 if (!DEFAULT_ROUTE_TYPE(type
) && DISTRIBUTE_NAME(ospf
, type
))
1177 /* distirbute-list exists, but access-list may not? */
1178 if (DISTRIBUTE_LIST(ospf
, type
))
1179 if (access_list_apply(DISTRIBUTE_LIST(ospf
, type
), p
)
1181 if (IS_DEBUG_OSPF(zebra
, ZEBRA_REDISTRIBUTE
))
1183 "Redistribute[%s]: %pFX filtered by distribute-list.",
1184 ospf_redist_string(type
), p
);
1188 save_values
= ei
->route_map_set
;
1189 ospf_reset_route_map_set_values(&ei
->route_map_set
);
1191 saved_tag
= ei
->tag
;
1192 /* Resetting with original route tag */
1193 ei
->tag
= ei
->orig_tag
;
1195 /* apply route-map if needed */
1196 red
= ospf_redist_lookup(ospf
, type
, instance
);
1197 if (red
&& ROUTEMAP_NAME(red
)) {
1198 route_map_result_t ret
;
1200 ret
= route_map_apply(ROUTEMAP(red
), (struct prefix
*)p
, ei
);
1202 if (ret
== RMAP_DENYMATCH
) {
1203 ei
->route_map_set
= save_values
;
1204 if (IS_DEBUG_OSPF(zebra
, ZEBRA_REDISTRIBUTE
))
1206 "Redistribute[%s]: %pFX filtered by route-map.",
1207 ospf_redist_string(type
), p
);
1211 /* check if 'route-map set' changed something */
1213 *changed
= !ospf_route_map_set_compare(
1214 &ei
->route_map_set
, &save_values
);
1216 /* check if tag is modified */
1217 *changed
|= (saved_tag
!= ei
->tag
);
1224 /* OSPF route-map set for redistribution */
1225 void ospf_routemap_set(struct ospf_redist
*red
, const char *name
)
1227 if (ROUTEMAP_NAME(red
)) {
1228 route_map_counter_decrement(ROUTEMAP(red
));
1229 free(ROUTEMAP_NAME(red
));
1232 ROUTEMAP_NAME(red
) = strdup(name
);
1233 ROUTEMAP(red
) = route_map_lookup_by_name(name
);
1234 route_map_counter_increment(ROUTEMAP(red
));
1237 void ospf_routemap_unset(struct ospf_redist
*red
)
1239 if (ROUTEMAP_NAME(red
)) {
1240 route_map_counter_decrement(ROUTEMAP(red
));
1241 free(ROUTEMAP_NAME(red
));
1244 ROUTEMAP_NAME(red
) = NULL
;
1245 ROUTEMAP(red
) = NULL
;
1248 static int ospf_zebra_gr_update(struct ospf
*ospf
, int command
,
1249 uint32_t stale_time
)
1251 struct zapi_cap api
;
1253 if (!zclient
|| zclient
->sock
< 0 || !ospf
)
1256 memset(&api
, 0, sizeof(api
));
1258 api
.stale_removal_time
= stale_time
;
1259 api
.vrf_id
= ospf
->vrf_id
;
1261 (void)zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES
, zclient
,
1267 int ospf_zebra_gr_enable(struct ospf
*ospf
, uint32_t stale_time
)
1269 return ospf_zebra_gr_update(ospf
, ZEBRA_CLIENT_GR_CAPABILITIES
,
1273 int ospf_zebra_gr_disable(struct ospf
*ospf
)
1275 return ospf_zebra_gr_update(ospf
, ZEBRA_CLIENT_GR_DISABLE
, 0);
1278 /* Zebra route add and delete treatment. */
1279 static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS
)
1281 struct zapi_route api
;
1282 struct prefix_ipv4 p
;
1284 unsigned long ifindex
;
1285 struct in_addr nexthop
;
1286 struct external_info
*ei
;
1291 ospf
= ospf_lookup_by_vrf_id(vrf_id
);
1295 if (zapi_route_decode(zclient
->ibuf
, &api
) < 0)
1298 ifindex
= api
.nexthops
[0].ifindex
;
1299 nexthop
= api
.nexthops
[0].gate
.ipv4
;
1302 memcpy(&p
, &api
.prefix
, sizeof(p
));
1303 if (IPV4_NET127(ntohl(p
.prefix
.s_addr
)))
1306 pgen
.family
= p
.family
;
1307 pgen
.prefixlen
= p
.prefixlen
;
1308 pgen
.u
.prefix4
= p
.prefix
;
1310 /* Re-destributed route is default route.
1311 * Here, route type is used as 'ZEBRA_ROUTE_KERNEL' for
1312 * updating ex-info. But in resetting (no default-info
1313 * originate)ZEBRA_ROUTE_MAX is used to delete the ex-info.
1314 * Resolved this inconsistency by maintaining same route type.
1316 if ((is_default_prefix(&pgen
)) && (api
.type
!= ZEBRA_ROUTE_OSPF
))
1317 rt_type
= DEFAULT_ROUTE
;
1319 if (IS_DEBUG_OSPF(zebra
, ZEBRA_REDISTRIBUTE
))
1320 zlog_debug("%s: cmd %s from client %s: vrf_id %d, p %pFX",
1321 __func__
, zserv_command_string(cmd
),
1322 zebra_route_string(api
.type
), vrf_id
, &api
.prefix
);
1324 if (cmd
== ZEBRA_REDISTRIBUTE_ROUTE_ADD
) {
1325 /* XXX|HACK|TODO|FIXME:
1326 * Maybe we should ignore reject/blackhole routes? Testing
1327 * shows that there is no problems though and this is only way
1328 * to "summarize" routes in ASBR at the moment. Maybe we need
1329 * just a better generalised solution for these types?
1332 /* Protocol tag overwrites all other tag value sent by zebra */
1333 if (ospf
->dtag
[rt_type
] > 0)
1334 api
.tag
= ospf
->dtag
[rt_type
];
1337 * Given zebra sends update for a prefix via ADD message, it
1339 * be considered as an implicit DEL for that prefix with other
1343 for (i
= 0; i
<= ZEBRA_ROUTE_MAX
; i
++)
1345 ospf_external_info_delete(ospf
, i
, api
.instance
,
1348 ei
= ospf_external_info_add(ospf
, rt_type
, api
.instance
, p
,
1349 ifindex
, nexthop
, api
.tag
);
1351 /* Nothing has changed, so nothing to do; return */
1354 if (ospf
->router_id
.s_addr
!= INADDR_ANY
) {
1355 if (is_default_prefix4(&p
))
1356 ospf_external_lsa_refresh_default(ospf
);
1358 struct ospf_external_aggr_rt
*aggr
;
1359 struct as_external_lsa
*al
;
1360 struct ospf_lsa
*lsa
= NULL
;
1361 struct in_addr mask
;
1363 aggr
= ospf_external_aggr_match(ospf
, &ei
->p
);
1366 /* Check the AS-external-LSA
1367 * should be originated.
1369 if (!ospf_redistribute_check(ospf
, ei
,
1373 if (IS_DEBUG_OSPF(lsa
, EXTNL_LSA_AGGR
))
1375 "%s: Send Aggreate LSA (%pI4/%d)",
1380 ospf_originate_summary_lsa(ospf
, aggr
,
1383 /* Handling the case where the
1384 * external route prefix
1385 * and aggegate prefix is same
1386 * If same don't flush the
1391 (struct prefix
*)&aggr
->p
,
1392 (struct prefix
*)&ei
->p
))
1395 lsa
= ospf_external_info_find_lsa(
1399 al
= (struct as_external_lsa
*)
1401 masklen2ip(ei
->p
.prefixlen
,
1408 ospf_external_lsa_flush(
1409 ospf
, ei
->type
, &ei
->p
,
1413 struct ospf_lsa
*current
;
1415 current
= ospf_external_info_find_lsa(
1423 if (!ospf_redistribute_check(
1427 ospf_external_lsa_originate(
1432 ZEBRA_REDISTRIBUTE
))
1434 "%s: %pI4 refreshing LSA",
1437 ospf_external_lsa_refresh(
1447 * Check if default-information originate is
1448 * with some routemap prefix/access list match.
1450 ospf_external_lsa_default_routemap_apply(ospf
, ei
, cmd
);
1452 } else { /* if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_DEL) */
1453 struct ospf_external_aggr_rt
*aggr
;
1455 ei
= ospf_external_info_lookup(ospf
, rt_type
, api
.instance
, &p
);
1460 * Check if default-information originate i
1461 * with some routemap prefix/access list match.
1462 * Apply before ei is deleted.
1464 ospf_external_lsa_default_routemap_apply(ospf
, ei
, cmd
);
1466 aggr
= ospf_external_aggr_match(ospf
, &ei
->p
);
1468 if (aggr
&& (ei
->aggr_route
== aggr
)) {
1469 ospf_unlink_ei_from_aggr(ospf
, aggr
, ei
);
1471 ospf_external_info_delete(ospf
, rt_type
, api
.instance
,
1474 ospf_external_info_delete(ospf
, rt_type
, api
.instance
,
1477 if (is_default_prefix4(&p
))
1478 ospf_external_lsa_refresh_default(ospf
);
1480 ospf_external_lsa_flush(ospf
, rt_type
, &p
,
1481 ifindex
/*, nexthop */);
1489 int ospf_distribute_list_out_set(struct ospf
*ospf
, int type
, const char *name
)
1491 /* Lookup access-list for distribute-list. */
1492 DISTRIBUTE_LIST(ospf
, type
) = access_list_lookup(AFI_IP
, name
);
1494 /* Clear previous distribute-name. */
1495 if (DISTRIBUTE_NAME(ospf
, type
))
1496 free(DISTRIBUTE_NAME(ospf
, type
));
1498 /* Set distribute-name. */
1499 DISTRIBUTE_NAME(ospf
, type
) = strdup(name
);
1501 /* If access-list have been set, schedule update timer. */
1502 if (DISTRIBUTE_LIST(ospf
, type
))
1503 ospf_distribute_list_update(ospf
, type
, 0);
1508 int ospf_distribute_list_out_unset(struct ospf
*ospf
, int type
,
1511 /* Schedule update timer. */
1512 if (DISTRIBUTE_LIST(ospf
, type
))
1513 ospf_distribute_list_update(ospf
, type
, 0);
1515 /* Unset distribute-list. */
1516 DISTRIBUTE_LIST(ospf
, type
) = NULL
;
1518 /* Clear distribute-name. */
1519 if (DISTRIBUTE_NAME(ospf
, type
))
1520 free(DISTRIBUTE_NAME(ospf
, type
));
1522 DISTRIBUTE_NAME(ospf
, type
) = NULL
;
1527 /* distribute-list update timer. */
1528 static void ospf_distribute_list_update_timer(struct thread
*thread
)
1530 struct route_node
*rn
;
1531 struct external_info
*ei
;
1532 struct route_table
*rt
;
1533 struct ospf_lsa
*lsa
;
1534 int type
, default_refresh
= 0;
1535 struct ospf
*ospf
= THREAD_ARG(thread
);
1540 ospf
->t_distribute_update
= NULL
;
1542 zlog_info("Zebra[Redistribute]: distribute-list update timer fired!");
1544 if (IS_DEBUG_OSPF_EVENT
) {
1545 zlog_debug("%s: ospf distribute-list update vrf %s id %d",
1546 __func__
, ospf_vrf_id_to_name(ospf
->vrf_id
),
1550 /* foreach all external info. */
1551 for (type
= 0; type
<= ZEBRA_ROUTE_MAX
; type
++) {
1552 struct list
*ext_list
;
1553 struct listnode
*node
;
1554 struct ospf_external
*ext
;
1556 ext_list
= ospf
->external
[type
];
1560 for (ALL_LIST_ELEMENTS_RO(ext_list
, node
, ext
)) {
1561 rt
= ext
->external_info
;
1564 for (rn
= route_top(rt
); rn
; rn
= route_next(rn
)) {
1569 if (is_default_prefix4(&ei
->p
))
1570 default_refresh
= 1;
1572 struct ospf_external_aggr_rt
*aggr
;
1574 aggr
= ospf_external_aggr_match(ospf
,
1579 * should be originated.
1581 if (!ospf_redistribute_check(
1584 ospf_unlink_ei_from_aggr(
1593 "%s: Send Aggregate LSA (%pI4/%d)",
1598 /* Originate Aggregate
1601 ospf_originate_summary_lsa(
1604 (lsa
= ospf_external_info_find_lsa(
1607 LSA_REFRESH_IF_CHANGED
;
1608 /* If this is a MaxAge
1611 * because distribute
1612 * settings might have
1614 * this LSA needs to be
1615 * originated, not be
1618 * refresh it, it will
1619 * remain a MaxAge LSA
1620 * because it will look
1622 * changed. Neighbors
1624 * updates for this LSA.
1626 if (IS_LSA_MAXAGE(lsa
))
1627 force
= LSA_REFRESH_FORCE
;
1629 ospf_external_lsa_refresh(
1630 ospf
, lsa
, ei
, force
,
1633 if (!ospf_redistribute_check(
1636 ospf_external_lsa_originate(
1643 if (default_refresh
)
1644 ospf_external_lsa_refresh_default(ospf
);
1647 /* Update distribute-list and set timer to apply access-list. */
1648 void ospf_distribute_list_update(struct ospf
*ospf
, int type
,
1649 unsigned short instance
)
1651 struct ospf_external
*ext
;
1653 /* External info does not exist. */
1654 ext
= ospf_external_lookup(ospf
, type
, instance
);
1655 if (!ext
|| !EXTERNAL_INFO(ext
))
1658 /* Set timer. If timer is already started, this call does nothing. */
1659 thread_add_timer_msec(master
, ospf_distribute_list_update_timer
, ospf
,
1660 ospf
->min_ls_interval
,
1661 &ospf
->t_distribute_update
);
1664 /* If access-list is updated, apply some check. */
1665 static void ospf_filter_update(struct access_list
*access
)
1670 struct ospf_area
*area
;
1671 struct listnode
*node
, *n1
;
1673 /* If OSPF instance does not exist, return right now. */
1674 if (listcount(om
->ospf
) == 0)
1677 /* Iterate all ospf [VRF] instances */
1678 for (ALL_LIST_ELEMENTS_RO(om
->ospf
, n1
, ospf
)) {
1679 /* Update distribute-list, and apply filter. */
1680 for (type
= 0; type
<= ZEBRA_ROUTE_MAX
; type
++) {
1681 struct list
*red_list
;
1682 struct ospf_redist
*red
;
1684 red_list
= ospf
->redist
[type
];
1686 for (ALL_LIST_ELEMENTS_RO(red_list
, node
,
1688 if (ROUTEMAP(red
)) {
1689 /* if route-map is not NULL it
1691 * using this access list */
1692 ospf_distribute_list_update(
1698 /* There is place for route-map for default-information
1699 * (ZEBRA_ROUTE_MAX),
1700 * but no distribute list. */
1701 if (type
== ZEBRA_ROUTE_MAX
)
1704 if (DISTRIBUTE_NAME(ospf
, type
)) {
1705 /* Keep old access-list for distribute-list. */
1706 struct access_list
*old
=
1707 DISTRIBUTE_LIST(ospf
, type
);
1709 /* Update access-list for distribute-list. */
1710 DISTRIBUTE_LIST(ospf
, type
) =
1713 DISTRIBUTE_NAME(ospf
, type
));
1715 /* No update for this distribute type. */
1717 && DISTRIBUTE_LIST(ospf
, type
) == NULL
)
1720 /* Schedule distribute-list update timer. */
1721 if (DISTRIBUTE_LIST(ospf
, type
) == NULL
1722 || strcmp(DISTRIBUTE_NAME(ospf
, type
),
1725 ospf_distribute_list_update(ospf
, type
,
1730 /* Update Area access-list. */
1731 for (ALL_LIST_ELEMENTS_RO(ospf
->areas
, node
, area
)) {
1732 if (EXPORT_NAME(area
)) {
1733 EXPORT_LIST(area
) = NULL
;
1737 if (IMPORT_NAME(area
)) {
1738 IMPORT_LIST(area
) = NULL
;
1743 /* Schedule ABR tasks -- this will be changed -- takada. */
1744 if (IS_OSPF_ABR(ospf
) && abr_inv
)
1745 ospf_schedule_abr_task(ospf
);
1749 /* If prefix-list is updated, do some updates. */
1750 static void ospf_prefix_list_update(struct prefix_list
*plist
)
1752 struct ospf
*ospf
= NULL
;
1755 struct ospf_area
*area
;
1756 struct listnode
*node
, *n1
;
1758 /* If OSPF instatnce does not exist, return right now. */
1759 if (listcount(om
->ospf
) == 0)
1762 /* Iterate all ospf [VRF] instances */
1763 for (ALL_LIST_ELEMENTS_RO(om
->ospf
, n1
, ospf
)) {
1765 /* Update all route-maps which are used
1766 * as redistribution filters.
1767 * They might use prefix-list.
1769 for (type
= 0; type
<= ZEBRA_ROUTE_MAX
; type
++) {
1770 struct list
*red_list
;
1771 struct ospf_redist
*red
;
1773 red_list
= ospf
->redist
[type
];
1777 for (ALL_LIST_ELEMENTS_RO(red_list
, node
, red
)) {
1778 if (ROUTEMAP(red
)) {
1779 /* if route-map is not NULL
1781 * this prefix list */
1782 ospf_distribute_list_update(
1783 ospf
, type
, red
->instance
);
1788 /* Update area filter-lists. */
1789 for (ALL_LIST_ELEMENTS_RO(ospf
->areas
, node
, area
)) {
1790 /* Update filter-list in. */
1791 if (PREFIX_NAME_IN(area
)
1792 && strcmp(PREFIX_NAME_IN(area
),
1793 prefix_list_name(plist
))
1795 PREFIX_LIST_IN(area
) = prefix_list_lookup(
1796 AFI_IP
, PREFIX_NAME_IN(area
));
1800 /* Update filter-list out. */
1801 if (PREFIX_NAME_OUT(area
)
1802 && strcmp(PREFIX_NAME_OUT(area
),
1803 prefix_list_name(plist
))
1805 PREFIX_LIST_IN(area
) = prefix_list_lookup(
1806 AFI_IP
, PREFIX_NAME_OUT(area
));
1811 /* Schedule ABR task. */
1812 if (IS_OSPF_ABR(ospf
) && abr_inv
)
1813 ospf_schedule_abr_task(ospf
);
1817 static struct ospf_distance
*ospf_distance_new(void)
1819 return XCALLOC(MTYPE_OSPF_DISTANCE
, sizeof(struct ospf_distance
));
1822 static void ospf_distance_free(struct ospf_distance
*odistance
)
1824 XFREE(MTYPE_OSPF_DISTANCE
, odistance
);
1827 int ospf_distance_set(struct vty
*vty
, struct ospf
*ospf
,
1828 const char *distance_str
, const char *ip_str
,
1829 const char *access_list_str
)
1832 struct prefix_ipv4 p
;
1834 struct route_node
*rn
;
1835 struct ospf_distance
*odistance
;
1837 ret
= str2prefix_ipv4(ip_str
, &p
);
1839 vty_out(vty
, "Malformed prefix\n");
1840 return CMD_WARNING_CONFIG_FAILED
;
1843 distance
= atoi(distance_str
);
1845 /* Get OSPF distance node. */
1846 rn
= route_node_get(ospf
->distance_table
, (struct prefix
*)&p
);
1848 odistance
= rn
->info
;
1849 route_unlock_node(rn
);
1851 odistance
= ospf_distance_new();
1852 rn
->info
= odistance
;
1855 /* Set distance value. */
1856 odistance
->distance
= distance
;
1858 /* Reset access-list configuration. */
1859 if (odistance
->access_list
) {
1860 free(odistance
->access_list
);
1861 odistance
->access_list
= NULL
;
1863 if (access_list_str
)
1864 odistance
->access_list
= strdup(access_list_str
);
1869 int ospf_distance_unset(struct vty
*vty
, struct ospf
*ospf
,
1870 const char *distance_str
, const char *ip_str
,
1871 char const *access_list_str
)
1874 struct prefix_ipv4 p
;
1875 struct route_node
*rn
;
1876 struct ospf_distance
*odistance
;
1878 ret
= str2prefix_ipv4(ip_str
, &p
);
1880 vty_out(vty
, "Malformed prefix\n");
1881 return CMD_WARNING_CONFIG_FAILED
;
1884 rn
= route_node_lookup(ospf
->distance_table
, (struct prefix
*)&p
);
1886 vty_out(vty
, "Can't find specified prefix\n");
1887 return CMD_WARNING_CONFIG_FAILED
;
1890 odistance
= rn
->info
;
1892 if (odistance
->access_list
)
1893 free(odistance
->access_list
);
1894 ospf_distance_free(odistance
);
1897 route_unlock_node(rn
);
1898 route_unlock_node(rn
);
1903 void ospf_distance_reset(struct ospf
*ospf
)
1905 struct route_node
*rn
;
1906 struct ospf_distance
*odistance
;
1908 for (rn
= route_top(ospf
->distance_table
); rn
; rn
= route_next(rn
)) {
1909 odistance
= rn
->info
;
1913 if (odistance
->access_list
)
1914 free(odistance
->access_list
);
1915 ospf_distance_free(odistance
);
1917 route_unlock_node(rn
);
1921 uint8_t ospf_distance_apply(struct ospf
*ospf
, struct prefix_ipv4
*p
,
1922 struct ospf_route
* or)
1928 if (ospf
->distance_intra
&& or->path_type
== OSPF_PATH_INTRA_AREA
)
1929 return ospf
->distance_intra
;
1931 if (ospf
->distance_inter
&& or->path_type
== OSPF_PATH_INTER_AREA
)
1932 return ospf
->distance_inter
;
1934 if (ospf
->distance_external
1935 && (or->path_type
== OSPF_PATH_TYPE1_EXTERNAL
||
1936 or->path_type
== OSPF_PATH_TYPE2_EXTERNAL
))
1937 return ospf
->distance_external
;
1939 if (ospf
->distance_all
)
1940 return ospf
->distance_all
;
1945 void ospf_zebra_vrf_register(struct ospf
*ospf
)
1947 if (!zclient
|| zclient
->sock
< 0 || !ospf
)
1950 if (ospf
->vrf_id
!= VRF_UNKNOWN
) {
1951 if (IS_DEBUG_OSPF_EVENT
)
1952 zlog_debug("%s: Register VRF %s id %u", __func__
,
1953 ospf_vrf_id_to_name(ospf
->vrf_id
),
1955 zclient_send_reg_requests(zclient
, ospf
->vrf_id
);
1959 void ospf_zebra_vrf_deregister(struct ospf
*ospf
)
1961 if (!zclient
|| zclient
->sock
< 0 || !ospf
)
1964 if (ospf
->vrf_id
!= VRF_DEFAULT
&& ospf
->vrf_id
!= VRF_UNKNOWN
) {
1965 if (IS_DEBUG_OSPF_EVENT
)
1966 zlog_debug("%s: De-Register VRF %s id %u to Zebra.",
1967 __func__
, ospf_vrf_id_to_name(ospf
->vrf_id
),
1969 /* Deregister for router-id, interfaces,
1970 * redistributed routes. */
1971 zclient_send_dereg_requests(zclient
, ospf
->vrf_id
);
1975 /* Label Manager Functions */
1978 * Check if Label Manager is Ready or not.
1980 * @return True if Label Manager is ready, False otherwise
1982 bool ospf_zebra_label_manager_ready(void)
1984 return (zclient_sync
->sock
> 0);
1988 * Request Label Range to the Label Manager.
1990 * @param base base label of the label range to request
1991 * @param chunk_size size of the label range to request
1993 * @return 0 on success, -1 on failure
1995 int ospf_zebra_request_label_range(uint32_t base
, uint32_t chunk_size
)
1998 uint32_t start
, end
;
2000 if (zclient_sync
->sock
< 0)
2003 ret
= lm_get_label_chunk(zclient_sync
, 0, base
, chunk_size
, &start
,
2006 zlog_warn("%s: error getting label range!", __func__
);
2014 * Release Label Range to the Label Manager.
2016 * @param start start of label range to release
2017 * @param end end of label range to release
2019 * @return 0 on success, -1 otherwise
2021 int ospf_zebra_release_label_range(uint32_t start
, uint32_t end
)
2025 if (zclient_sync
->sock
< 0)
2028 ret
= lm_release_label_chunk(zclient_sync
, start
, end
);
2030 zlog_warn("%s: error releasing label range!", __func__
);
2038 * Connect to the Label Manager.
2040 * @return 0 on success, -1 otherwise
2042 int ospf_zebra_label_manager_connect(void)
2044 /* Connect to label manager. */
2045 if (zclient_socket_connect(zclient_sync
) < 0) {
2046 zlog_warn("%s: failed connecting synchronous zclient!",
2050 /* make socket non-blocking */
2051 set_nonblocking(zclient_sync
->sock
);
2053 /* Send hello to notify zebra this is a synchronous client */
2054 if (zclient_send_hello(zclient_sync
) == ZCLIENT_SEND_FAILURE
) {
2055 zlog_warn("%s: failed sending hello for synchronous zclient!",
2057 close(zclient_sync
->sock
);
2058 zclient_sync
->sock
= -1;
2062 /* Connect to label manager */
2063 if (lm_label_manager_connect(zclient_sync
, 0) != 0) {
2064 zlog_warn("%s: failed connecting to label manager!", __func__
);
2065 if (zclient_sync
->sock
> 0) {
2066 close(zclient_sync
->sock
);
2067 zclient_sync
->sock
= -1;
2072 osr_debug("SR (%s): Successfully connected to the Label Manager",
2078 static void ospf_zebra_connected(struct zclient
*zclient
)
2080 /* Send the client registration */
2081 bfd_client_sendmsg(zclient
, ZEBRA_BFD_CLIENT_REGISTER
, VRF_DEFAULT
);
2083 zclient_send_reg_requests(zclient
, VRF_DEFAULT
);
2087 * opaque messages between processes
2089 static int ospf_opaque_msg_handler(ZAPI_CALLBACK_ARGS
)
2092 struct zapi_opaque_msg info
;
2093 struct ldp_igp_sync_if_state state
;
2094 struct ldp_igp_sync_announce announce
;
2095 struct zapi_opaque_reg_info dst
;
2100 if (zclient_opaque_decode(s
, &info
) != 0)
2103 switch (info
.type
) {
2104 case LINK_STATE_SYNC
:
2105 STREAM_GETC(s
, dst
.proto
);
2106 STREAM_GETW(s
, dst
.instance
);
2107 STREAM_GETL(s
, dst
.session_id
);
2108 dst
.type
= LINK_STATE_SYNC
;
2109 ret
= ospf_te_sync_ted(dst
);
2111 case LDP_IGP_SYNC_IF_STATE_UPDATE
:
2112 STREAM_GET(&state
, s
, sizeof(state
));
2113 ret
= ospf_ldp_sync_state_update(state
);
2115 case LDP_IGP_SYNC_ANNOUNCE_UPDATE
:
2116 STREAM_GET(&announce
, s
, sizeof(announce
));
2117 ret
= ospf_ldp_sync_announce_update(announce
);
2128 static int ospf_zebra_client_close_notify(ZAPI_CALLBACK_ARGS
)
2132 struct zapi_client_close_info info
;
2134 if (zapi_client_close_notify_decode(zclient
->ibuf
, &info
) < 0)
2137 ospf_ldp_sync_handle_client_close(&info
);
2142 static zclient_handler
*const ospf_handlers
[] = {
2143 [ZEBRA_ROUTER_ID_UPDATE
] = ospf_router_id_update_zebra
,
2144 [ZEBRA_INTERFACE_ADDRESS_ADD
] = ospf_interface_address_add
,
2145 [ZEBRA_INTERFACE_ADDRESS_DELETE
] = ospf_interface_address_delete
,
2146 [ZEBRA_INTERFACE_LINK_PARAMS
] = ospf_interface_link_params
,
2147 [ZEBRA_INTERFACE_VRF_UPDATE
] = ospf_interface_vrf_update
,
2149 [ZEBRA_REDISTRIBUTE_ROUTE_ADD
] = ospf_zebra_read_route
,
2150 [ZEBRA_REDISTRIBUTE_ROUTE_DEL
] = ospf_zebra_read_route
,
2152 [ZEBRA_OPAQUE_MESSAGE
] = ospf_opaque_msg_handler
,
2154 [ZEBRA_CLIENT_CLOSE_NOTIFY
] = ospf_zebra_client_close_notify
,
2157 void ospf_zebra_init(struct thread_master
*master
, unsigned short instance
)
2159 /* Allocate zebra structure. */
2160 zclient
= zclient_new(master
, &zclient_options_default
, ospf_handlers
,
2161 array_size(ospf_handlers
));
2162 zclient_init(zclient
, ZEBRA_ROUTE_OSPF
, instance
, &ospfd_privs
);
2163 zclient
->zebra_connected
= ospf_zebra_connected
;
2165 /* Initialize special zclient for synchronous message exchanges. */
2166 struct zclient_options options
= zclient_options_default
;
2167 options
.synchronous
= true;
2168 zclient_sync
= zclient_new(master
, &options
, NULL
, 0);
2169 zclient_sync
->sock
= -1;
2170 zclient_sync
->redist_default
= ZEBRA_ROUTE_OSPF
;
2171 zclient_sync
->instance
= instance
;
2173 * session_id must be different from default value (0) to distinguish
2174 * the asynchronous socket from the synchronous one
2176 zclient_sync
->session_id
= 1;
2177 zclient_sync
->privs
= &ospfd_privs
;
2179 access_list_add_hook(ospf_filter_update
);
2180 access_list_delete_hook(ospf_filter_update
);
2181 prefix_list_add_hook(ospf_prefix_list_update
);
2182 prefix_list_delete_hook(ospf_prefix_list_update
);
2185 void ospf_zebra_send_arp(const struct interface
*ifp
, const struct prefix
*p
)
2187 zclient_send_neigh_discovery_req(zclient
, ifp
, p
);