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
39 #include "ospfd/ospfd.h"
40 #include "ospfd/ospf_interface.h"
41 #include "ospfd/ospf_ism.h"
42 #include "ospfd/ospf_asbr.h"
43 #include "ospfd/ospf_asbr.h"
44 #include "ospfd/ospf_abr.h"
45 #include "ospfd/ospf_lsa.h"
46 #include "ospfd/ospf_dump.h"
47 #include "ospfd/ospf_route.h"
48 #include "ospfd/ospf_lsdb.h"
49 #include "ospfd/ospf_neighbor.h"
50 #include "ospfd/ospf_nsm.h"
51 #include "ospfd/ospf_zebra.h"
52 #include "ospfd/ospf_te.h"
54 DEFINE_MTYPE_STATIC(OSPFD
, OSPF_EXTERNAL
, "OSPF External route table")
55 DEFINE_MTYPE_STATIC(OSPFD
, OSPF_REDISTRIBUTE
, "OSPF Redistriute")
56 DEFINE_MTYPE_STATIC(OSPFD
, OSPF_DIST_ARGS
, "OSPF Distribute arguments")
58 /* Zebra structure to hold current status. */
59 struct zclient
*zclient
= NULL
;
61 /* For registering threads. */
62 extern struct thread_master
*master
;
64 /* Router-id update message from zebra. */
65 static int ospf_router_id_update_zebra(ZAPI_CALLBACK_ARGS
)
67 struct ospf
*ospf
= NULL
;
68 struct prefix router_id
;
69 zebra_router_id_update_read(zclient
->ibuf
, &router_id
);
71 if (IS_DEBUG_OSPF(zebra
, ZEBRA_INTERFACE
)) {
72 char buf
[PREFIX2STR_BUFFER
];
73 prefix2str(&router_id
, buf
, sizeof(buf
));
74 zlog_debug("Zebra rcvd: router id update %s vrf %s id %u", buf
,
75 ospf_vrf_id_to_name(vrf_id
), vrf_id
);
78 ospf
= ospf_lookup_by_vrf_id(vrf_id
);
81 ospf
->router_id_zebra
= router_id
.u
.prefix4
;
82 ospf_router_id_update(ospf
);
84 if (IS_DEBUG_OSPF_EVENT
) {
85 char buf
[PREFIX2STR_BUFFER
];
87 prefix2str(&router_id
, buf
, sizeof(buf
));
89 "%s: ospf instance not found for vrf %s id %u router_id %s",
90 __func__
, ospf_vrf_id_to_name(vrf_id
), vrf_id
,
97 static int ospf_interface_address_add(ZAPI_CALLBACK_ARGS
)
100 struct ospf
*ospf
= NULL
;
103 c
= zebra_interface_address_read(cmd
, zclient
->ibuf
, vrf_id
);
108 if (IS_DEBUG_OSPF(zebra
, ZEBRA_INTERFACE
)) {
109 char buf
[PREFIX2STR_BUFFER
];
110 prefix2str(c
->address
, buf
, sizeof(buf
));
111 zlog_debug("Zebra: interface %s address add %s vrf %s id %u",
112 c
->ifp
->name
, buf
, ospf_vrf_id_to_name(vrf_id
),
116 ospf
= ospf_lookup_by_vrf_id(vrf_id
);
120 ospf_if_update(ospf
, c
->ifp
);
122 ospf_if_interface(c
->ifp
);
127 static int ospf_interface_address_delete(ZAPI_CALLBACK_ARGS
)
130 struct interface
*ifp
;
131 struct ospf_interface
*oi
;
132 struct route_node
*rn
;
135 c
= zebra_interface_address_read(cmd
, zclient
->ibuf
, vrf_id
);
140 if (IS_DEBUG_OSPF(zebra
, ZEBRA_INTERFACE
)) {
141 char buf
[PREFIX2STR_BUFFER
];
142 prefix2str(c
->address
, buf
, sizeof(buf
));
143 zlog_debug("Zebra: interface %s address delete %s",
149 p
.prefixlen
= IPV4_MAX_PREFIXLEN
;
151 rn
= route_node_lookup(IF_OIFS(ifp
), &p
);
159 route_unlock_node(rn
);
161 /* Call interface hook functions to clean up */
164 ospf_if_interface(c
->ifp
);
171 static int ospf_interface_link_params(ZAPI_CALLBACK_ARGS
)
173 struct interface
*ifp
;
175 ifp
= zebra_interface_link_params_read(zclient
->ibuf
, vrf_id
);
181 ospf_mpls_te_update_if(ifp
);
186 /* VRF update for an interface. */
187 static int ospf_interface_vrf_update(ZAPI_CALLBACK_ARGS
)
189 struct interface
*ifp
= NULL
;
192 ifp
= zebra_interface_vrf_update_read(zclient
->ibuf
, vrf_id
,
197 if (IS_DEBUG_OSPF_EVENT
)
199 "%s: Rx Interface %s VRF change vrf_id %u New vrf %s id %u",
200 __func__
, ifp
->name
, vrf_id
,
201 ospf_vrf_id_to_name(new_vrf_id
), new_vrf_id
);
203 /*if_update(ifp, ifp->name, strlen(ifp->name), new_vrf_id);*/
204 if_update_to_new_vrf(ifp
, new_vrf_id
);
209 void ospf_zebra_add(struct ospf
*ospf
, struct prefix_ipv4
*p
,
210 struct ospf_route
* or)
212 struct zapi_route api
;
213 struct zapi_nexthop
*api_nh
;
215 struct ospf_path
*path
;
216 struct listnode
*node
;
219 memset(&api
, 0, sizeof(api
));
220 api
.vrf_id
= ospf
->vrf_id
;
221 api
.type
= ZEBRA_ROUTE_OSPF
;
222 api
.instance
= ospf
->instance
;
223 api
.safi
= SAFI_UNICAST
;
225 memcpy(&api
.prefix
, p
, sizeof(*p
));
226 SET_FLAG(api
.message
, ZAPI_MESSAGE_NEXTHOP
);
229 SET_FLAG(api
.message
, ZAPI_MESSAGE_METRIC
);
230 if (or->path_type
== OSPF_PATH_TYPE1_EXTERNAL
)
231 api
.metric
= or->cost
+ or->u
.ext
.type2_cost
;
232 else if (or->path_type
== OSPF_PATH_TYPE2_EXTERNAL
)
233 api
.metric
= or->u
.ext
.type2_cost
;
235 api
.metric
= or->cost
;
237 /* Check if path type is ASE */
238 if (((or->path_type
== OSPF_PATH_TYPE1_EXTERNAL
)
239 || (or->path_type
== OSPF_PATH_TYPE2_EXTERNAL
))
240 && (or->u
.ext
.tag
> 0) && (or->u
.ext
.tag
<= ROUTE_TAG_MAX
)) {
241 SET_FLAG(api
.message
, ZAPI_MESSAGE_TAG
);
242 api
.tag
= or->u
.ext
.tag
;
245 /* Distance value. */
246 distance
= ospf_distance_apply(ospf
, p
, or);
248 SET_FLAG(api
.message
, ZAPI_MESSAGE_DISTANCE
);
249 api
.distance
= distance
;
252 /* Nexthop, ifindex, distance and metric information. */
253 for (ALL_LIST_ELEMENTS_RO(or->paths
, node
, path
)) {
254 if (count
>= MULTIPATH_NUM
)
256 api_nh
= &api
.nexthops
[count
];
258 if (path
->unnumbered
|| (path
->nexthop
.s_addr
!= INADDR_ANY
259 && path
->ifindex
!= 0)) {
260 #else /* HAVE_NETLINK */
261 if (path
->nexthop
.s_addr
!= INADDR_ANY
&& path
->ifindex
!= 0) {
262 #endif /* HAVE_NETLINK */
263 api_nh
->gate
.ipv4
= path
->nexthop
;
264 api_nh
->ifindex
= path
->ifindex
;
265 api_nh
->type
= NEXTHOP_TYPE_IPV4_IFINDEX
;
266 } else if (path
->nexthop
.s_addr
!= INADDR_ANY
) {
267 api_nh
->gate
.ipv4
= path
->nexthop
;
268 api_nh
->type
= NEXTHOP_TYPE_IPV4
;
270 api_nh
->ifindex
= path
->ifindex
;
271 api_nh
->type
= NEXTHOP_TYPE_IFINDEX
;
273 api_nh
->vrf_id
= ospf
->vrf_id
;
276 if (IS_DEBUG_OSPF(zebra
, ZEBRA_REDISTRIBUTE
)) {
277 char buf
[2][INET_ADDRSTRLEN
];
278 struct interface
*ifp
;
280 ifp
= if_lookup_by_index(path
->ifindex
, ospf
->vrf_id
);
283 "Zebra: Route add %s nexthop %s, ifindex=%d %s",
284 prefix2str(p
, buf
[0], sizeof(buf
[0])),
285 inet_ntop(AF_INET
, &path
->nexthop
,
286 buf
[1], sizeof(buf
[1])),
287 path
->ifindex
, ifp
? ifp
->name
: " ");
290 api
.nexthop_num
= count
;
292 zclient_route_send(ZEBRA_ROUTE_ADD
, zclient
, &api
);
295 void ospf_zebra_delete(struct ospf
*ospf
, struct prefix_ipv4
*p
,
296 struct ospf_route
* or)
298 struct zapi_route api
;
300 memset(&api
, 0, sizeof(api
));
301 api
.vrf_id
= ospf
->vrf_id
;
302 api
.type
= ZEBRA_ROUTE_OSPF
;
303 api
.instance
= ospf
->instance
;
304 api
.safi
= SAFI_UNICAST
;
305 memcpy(&api
.prefix
, p
, sizeof(*p
));
307 if (IS_DEBUG_OSPF(zebra
, ZEBRA_REDISTRIBUTE
)) {
308 char buf
[PREFIX2STR_BUFFER
];
309 zlog_debug("Zebra: Route delete %s",
310 prefix2str(p
, buf
, sizeof(buf
)));
313 zclient_route_send(ZEBRA_ROUTE_DELETE
, zclient
, &api
);
316 void ospf_zebra_add_discard(struct ospf
*ospf
, struct prefix_ipv4
*p
)
318 struct zapi_route api
;
320 memset(&api
, 0, sizeof(api
));
321 api
.vrf_id
= ospf
->vrf_id
;
322 api
.type
= ZEBRA_ROUTE_OSPF
;
323 api
.instance
= ospf
->instance
;
324 api
.safi
= SAFI_UNICAST
;
325 memcpy(&api
.prefix
, p
, sizeof(*p
));
326 zapi_route_set_blackhole(&api
, BLACKHOLE_NULL
);
328 zclient_route_send(ZEBRA_ROUTE_ADD
, zclient
, &api
);
330 if (IS_DEBUG_OSPF(zebra
, ZEBRA_REDISTRIBUTE
)) {
331 char buf
[PREFIX2STR_BUFFER
];
332 zlog_debug("Zebra: Route add discard %s",
333 prefix2str(p
, buf
, sizeof(buf
)));
337 void ospf_zebra_delete_discard(struct ospf
*ospf
, struct prefix_ipv4
*p
)
339 struct zapi_route api
;
341 memset(&api
, 0, sizeof(api
));
342 api
.vrf_id
= ospf
->vrf_id
;
343 api
.type
= ZEBRA_ROUTE_OSPF
;
344 api
.instance
= ospf
->instance
;
345 api
.safi
= SAFI_UNICAST
;
346 memcpy(&api
.prefix
, p
, sizeof(*p
));
347 zapi_route_set_blackhole(&api
, BLACKHOLE_NULL
);
349 zclient_route_send(ZEBRA_ROUTE_DELETE
, zclient
, &api
);
351 if (IS_DEBUG_OSPF(zebra
, ZEBRA_REDISTRIBUTE
)) {
352 char buf
[PREFIX2STR_BUFFER
];
353 zlog_debug("Zebra: Route delete discard %s",
354 prefix2str(p
, buf
, sizeof(buf
)));
358 struct ospf_external
*ospf_external_lookup(struct ospf
*ospf
, uint8_t type
,
359 unsigned short instance
)
361 struct list
*ext_list
;
362 struct listnode
*node
;
363 struct ospf_external
*ext
;
365 ext_list
= ospf
->external
[type
];
369 for (ALL_LIST_ELEMENTS_RO(ext_list
, node
, ext
))
370 if (ext
->instance
== instance
)
376 struct ospf_external
*ospf_external_add(struct ospf
*ospf
, uint8_t type
,
377 unsigned short instance
)
379 struct list
*ext_list
;
380 struct ospf_external
*ext
;
382 ext
= ospf_external_lookup(ospf
, type
, instance
);
386 if (!ospf
->external
[type
])
387 ospf
->external
[type
] = list_new();
389 ext_list
= ospf
->external
[type
];
390 ext
= XCALLOC(MTYPE_OSPF_EXTERNAL
, sizeof(struct ospf_external
));
391 ext
->instance
= instance
;
392 EXTERNAL_INFO(ext
) = route_table_init();
394 listnode_add(ext_list
, ext
);
399 void ospf_external_del(struct ospf
*ospf
, uint8_t type
, unsigned short instance
)
401 struct ospf_external
*ext
;
403 ext
= ospf_external_lookup(ospf
, type
, instance
);
406 if (EXTERNAL_INFO(ext
))
407 route_table_finish(EXTERNAL_INFO(ext
));
409 listnode_delete(ospf
->external
[type
], ext
);
411 if (!ospf
->external
[type
]->count
)
412 list_delete(&ospf
->external
[type
]);
414 XFREE(MTYPE_OSPF_EXTERNAL
, ext
);
418 struct ospf_redist
*ospf_redist_lookup(struct ospf
*ospf
, uint8_t type
,
419 unsigned short instance
)
421 struct list
*red_list
;
422 struct listnode
*node
;
423 struct ospf_redist
*red
;
425 red_list
= ospf
->redist
[type
];
429 for (ALL_LIST_ELEMENTS_RO(red_list
, node
, red
))
430 if (red
->instance
== instance
)
436 struct ospf_redist
*ospf_redist_add(struct ospf
*ospf
, uint8_t type
,
437 unsigned short instance
)
439 struct list
*red_list
;
440 struct ospf_redist
*red
;
442 red
= ospf_redist_lookup(ospf
, type
, instance
);
446 if (!ospf
->redist
[type
])
447 ospf
->redist
[type
] = list_new();
449 red_list
= ospf
->redist
[type
];
450 red
= XCALLOC(MTYPE_OSPF_REDISTRIBUTE
, sizeof(struct ospf_redist
));
451 red
->instance
= instance
;
452 red
->dmetric
.type
= -1;
453 red
->dmetric
.value
= -1;
454 ROUTEMAP_NAME(red
) = NULL
;
455 ROUTEMAP(red
) = NULL
;
457 listnode_add(red_list
, red
);
462 void ospf_redist_del(struct ospf
*ospf
, uint8_t type
, unsigned short instance
)
464 struct ospf_redist
*red
;
466 red
= ospf_redist_lookup(ospf
, type
, instance
);
469 listnode_delete(ospf
->redist
[type
], red
);
470 if (!ospf
->redist
[type
]->count
) {
471 list_delete(&ospf
->redist
[type
]);
473 ospf_routemap_unset(red
);
474 XFREE(MTYPE_OSPF_REDISTRIBUTE
, red
);
479 int ospf_is_type_redistributed(struct ospf
*ospf
, int type
,
480 unsigned short instance
)
482 return (DEFAULT_ROUTE_TYPE(type
)
483 ? vrf_bitmap_check(zclient
->default_information
[AFI_IP
],
486 && redist_check_instance(
487 &zclient
->mi_redist
[AFI_IP
][type
],
491 zclient
->redist
[AFI_IP
][type
],
495 int ospf_redistribute_set(struct ospf
*ospf
, int type
, unsigned short instance
,
496 int mtype
, int mvalue
)
499 struct ospf_redist
*red
;
501 red
= ospf_redist_lookup(ospf
, type
, instance
);
505 "Redistribute[%s][%d]: Lookup failed Type[%d] , Metric[%d]",
506 ospf_redist_string(type
), instance
,
507 metric_type(ospf
, type
, instance
),
508 metric_value(ospf
, type
, instance
));
509 return CMD_WARNING_CONFIG_FAILED
;
512 if (ospf_is_type_redistributed(ospf
, type
, instance
)) {
513 if (mtype
!= red
->dmetric
.type
) {
514 red
->dmetric
.type
= mtype
;
515 force
= LSA_REFRESH_FORCE
;
517 if (mvalue
!= red
->dmetric
.value
) {
518 red
->dmetric
.value
= mvalue
;
519 force
= LSA_REFRESH_FORCE
;
522 ospf_external_lsa_refresh_type(ospf
, type
, instance
, force
);
524 if (IS_DEBUG_OSPF(zebra
, ZEBRA_REDISTRIBUTE
))
526 "Redistribute[%s][%d]: Refresh Type[%d], Metric[%d]",
527 ospf_redist_string(type
), instance
,
528 metric_type(ospf
, type
, instance
),
529 metric_value(ospf
, type
, instance
));
534 red
->dmetric
.type
= mtype
;
535 red
->dmetric
.value
= mvalue
;
537 ospf_external_add(ospf
, type
, instance
);
539 zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD
, zclient
, AFI_IP
, type
,
540 instance
, ospf
->vrf_id
);
542 if (IS_DEBUG_OSPF(zebra
, ZEBRA_REDISTRIBUTE
))
544 "Redistribute[%s][%d] vrf id %u: Start Type[%d], Metric[%d]",
545 ospf_redist_string(type
), instance
, ospf
->vrf_id
,
546 metric_type(ospf
, type
, instance
),
547 metric_value(ospf
, type
, instance
));
549 ospf_asbr_status_update(ospf
, ++ospf
->redistribute
);
554 int ospf_redistribute_unset(struct ospf
*ospf
, int type
,
555 unsigned short instance
)
557 if (type
== zclient
->redist_default
&& instance
== zclient
->instance
)
560 if (!ospf_is_type_redistributed(ospf
, type
, instance
))
563 zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE
, zclient
, AFI_IP
, type
,
564 instance
, ospf
->vrf_id
);
566 if (IS_DEBUG_OSPF(zebra
, ZEBRA_REDISTRIBUTE
))
567 zlog_debug("Redistribute[%s][%d] vrf id %u: Stop",
568 ospf_redist_string(type
), instance
, ospf
->vrf_id
);
570 /* Remove the routes from OSPF table. */
571 ospf_redistribute_withdraw(ospf
, type
, instance
);
573 ospf_external_del(ospf
, type
, instance
);
575 ospf_asbr_status_update(ospf
, --ospf
->redistribute
);
580 int ospf_redistribute_default_set(struct ospf
*ospf
, int originate
, int mtype
,
583 struct prefix_ipv4 p
;
584 struct in_addr nexthop
;
585 int cur_originate
= ospf
->default_originate
;
586 const char *type_str
= NULL
;
588 nexthop
.s_addr
= INADDR_ANY
;
590 p
.prefix
.s_addr
= INADDR_ANY
;
593 ospf
->default_originate
= originate
;
595 if (cur_originate
== originate
) {
596 /* Refresh the lsa since metric might different */
597 if (IS_DEBUG_OSPF(zebra
, ZEBRA_REDISTRIBUTE
))
599 "Redistribute[%s]: Refresh Type[%d], Metric[%d]",
600 ospf_redist_string(DEFAULT_ROUTE
),
601 metric_type(ospf
, DEFAULT_ROUTE
, 0),
602 metric_value(ospf
, DEFAULT_ROUTE
, 0));
604 ospf_external_lsa_refresh_default(ospf
);
608 switch (cur_originate
) {
609 case DEFAULT_ORIGINATE_NONE
:
611 case DEFAULT_ORIGINATE_ZEBRA
:
612 zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE
,
613 zclient
, AFI_IP
, ospf
->vrf_id
);
614 ospf
->redistribute
--;
616 case DEFAULT_ORIGINATE_ALWAYS
:
617 ospf_external_info_delete(ospf
, DEFAULT_ROUTE
, 0, p
);
618 ospf_external_del(ospf
, DEFAULT_ROUTE
, 0);
619 ospf
->redistribute
--;
624 case DEFAULT_ORIGINATE_NONE
:
627 case DEFAULT_ORIGINATE_ZEBRA
:
629 ospf
->redistribute
++;
630 zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD
,
631 zclient
, AFI_IP
, ospf
->vrf_id
);
633 case DEFAULT_ORIGINATE_ALWAYS
:
635 ospf
->redistribute
++;
636 ospf_external_add(ospf
, DEFAULT_ROUTE
, 0);
637 ospf_external_info_add(ospf
, DEFAULT_ROUTE
, 0, p
, 0, nexthop
,
642 if (IS_DEBUG_OSPF(zebra
, ZEBRA_REDISTRIBUTE
))
643 zlog_debug("Redistribute[DEFAULT]: %s Type[%d], Metric[%d]",
645 metric_type(ospf
, DEFAULT_ROUTE
, 0),
646 metric_value(ospf
, DEFAULT_ROUTE
, 0));
648 ospf_external_lsa_refresh_default(ospf
);
649 ospf_asbr_status_update(ospf
, ospf
->redistribute
);
653 static int ospf_external_lsa_originate_check(struct ospf
*ospf
,
654 struct external_info
*ei
)
656 /* If prefix is multicast, then do not originate LSA. */
657 if (IN_MULTICAST(htonl(ei
->p
.prefix
.s_addr
))) {
659 "LSA[Type5:%s]: Not originate AS-external-LSA, "
660 "Prefix belongs multicast",
661 inet_ntoa(ei
->p
.prefix
));
665 /* Take care of default-originate. */
666 if (is_prefix_default(&ei
->p
))
667 if (ospf
->default_originate
== DEFAULT_ORIGINATE_NONE
) {
669 "LSA[Type5:0.0.0.0]: Not originate AS-external-LSA "
677 /* If connected prefix is OSPF enable interface, then do not announce. */
678 int ospf_distribute_check_connected(struct ospf
*ospf
, struct external_info
*ei
)
680 struct listnode
*node
;
681 struct ospf_interface
*oi
;
684 for (ALL_LIST_ELEMENTS_RO(ospf
->oiflist
, node
, oi
))
685 if (prefix_match(oi
->address
, (struct prefix
*)&ei
->p
))
690 /* return 1 if external LSA must be originated, 0 otherwise */
691 int ospf_redistribute_check(struct ospf
*ospf
, struct external_info
*ei
,
694 struct route_map_set_values save_values
;
695 struct prefix_ipv4
*p
= &ei
->p
;
696 struct ospf_redist
*red
;
697 uint8_t type
= is_prefix_default(&ei
->p
) ? DEFAULT_ROUTE
: ei
->type
;
698 unsigned short instance
= is_prefix_default(&ei
->p
) ? 0 : ei
->instance
;
703 if (!ospf_external_lsa_originate_check(ospf
, ei
))
706 /* Take care connected route. */
707 if (type
== ZEBRA_ROUTE_CONNECT
708 && !ospf_distribute_check_connected(ospf
, ei
))
711 if (!DEFAULT_ROUTE_TYPE(type
) && DISTRIBUTE_NAME(ospf
, type
))
712 /* distirbute-list exists, but access-list may not? */
713 if (DISTRIBUTE_LIST(ospf
, type
))
714 if (access_list_apply(DISTRIBUTE_LIST(ospf
, type
), p
)
716 if (IS_DEBUG_OSPF(zebra
, ZEBRA_REDISTRIBUTE
)) {
717 char buf
[PREFIX2STR_BUFFER
];
719 "Redistribute[%s]: %s filtered by distribute-list.",
720 ospf_redist_string(type
),
721 prefix2str(p
, buf
, sizeof(buf
)));
726 save_values
= ei
->route_map_set
;
727 ospf_reset_route_map_set_values(&ei
->route_map_set
);
729 /* apply route-map if needed */
730 red
= ospf_redist_lookup(ospf
, type
, instance
);
731 if (red
&& ROUTEMAP_NAME(red
)) {
732 route_map_result_t ret
;
734 ret
= route_map_apply(ROUTEMAP(red
), (struct prefix
*)p
,
737 if (ret
== RMAP_DENYMATCH
) {
738 ei
->route_map_set
= save_values
;
739 if (IS_DEBUG_OSPF(zebra
, ZEBRA_REDISTRIBUTE
)) {
740 char buf
[PREFIX2STR_BUFFER
];
742 "Redistribute[%s]: %s filtered by route-map.",
743 ospf_redist_string(type
),
744 prefix2str(p
, buf
, sizeof(buf
)));
749 /* check if 'route-map set' changed something */
751 *changed
= !ospf_route_map_set_compare(
752 &ei
->route_map_set
, &save_values
);
758 /* OSPF route-map set for redistribution */
759 void ospf_routemap_set(struct ospf_redist
*red
, const char *name
)
761 if (ROUTEMAP_NAME(red
)) {
762 route_map_counter_decrement(ROUTEMAP(red
));
763 free(ROUTEMAP_NAME(red
));
766 ROUTEMAP_NAME(red
) = strdup(name
);
767 ROUTEMAP(red
) = route_map_lookup_by_name(name
);
768 route_map_counter_increment(ROUTEMAP(red
));
771 void ospf_routemap_unset(struct ospf_redist
*red
)
773 if (ROUTEMAP_NAME(red
)) {
774 route_map_counter_decrement(ROUTEMAP(red
));
775 free(ROUTEMAP_NAME(red
));
778 ROUTEMAP_NAME(red
) = NULL
;
779 ROUTEMAP(red
) = NULL
;
782 /* Zebra route add and delete treatment. */
783 static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS
)
785 struct zapi_route api
;
786 struct prefix_ipv4 p
;
787 unsigned long ifindex
;
788 struct in_addr nexthop
;
789 struct external_info
*ei
;
794 ospf
= ospf_lookup_by_vrf_id(vrf_id
);
798 if (zapi_route_decode(zclient
->ibuf
, &api
) < 0)
801 ifindex
= api
.nexthops
[0].ifindex
;
802 nexthop
= api
.nexthops
[0].gate
.ipv4
;
805 memcpy(&p
, &api
.prefix
, sizeof(p
));
806 if (IPV4_NET127(ntohl(p
.prefix
.s_addr
)))
809 /* Re-destributed route is default route.
810 * Here, route type is used as 'ZEBRA_ROUTE_KERNEL' for
811 * updating ex-info. But in resetting (no default-info
812 * originate)ZEBRA_ROUTE_MAX is used to delete the ex-info.
813 * Resolved this inconsistency by maintaining same route type.
815 if (is_prefix_default(&p
))
816 rt_type
= DEFAULT_ROUTE
;
818 if (IS_DEBUG_OSPF(zebra
, ZEBRA_REDISTRIBUTE
)) {
819 char buf_prefix
[PREFIX_STRLEN
];
820 prefix2str(&api
.prefix
, buf_prefix
, sizeof(buf_prefix
));
822 zlog_debug("%s: cmd %s from client %s: vrf_id %d, p %s",
823 __func__
, zserv_command_string(cmd
),
824 zebra_route_string(api
.type
), vrf_id
, buf_prefix
);
827 if (cmd
== ZEBRA_REDISTRIBUTE_ROUTE_ADD
) {
828 /* XXX|HACK|TODO|FIXME:
829 * Maybe we should ignore reject/blackhole routes? Testing
830 * shows that there is no problems though and this is only way
831 * to "summarize" routes in ASBR at the moment. Maybe we need
832 * just a better generalised solution for these types?
835 /* Protocol tag overwrites all other tag value sent by zebra */
836 if (ospf
->dtag
[rt_type
] > 0)
837 api
.tag
= ospf
->dtag
[rt_type
];
840 * Given zebra sends update for a prefix via ADD message, it
842 * be considered as an implicit DEL for that prefix with other
846 for (i
= 0; i
<= ZEBRA_ROUTE_MAX
; i
++)
848 ospf_external_info_delete(ospf
, i
, api
.instance
,
851 ei
= ospf_external_info_add(ospf
, rt_type
, api
.instance
, p
,
852 ifindex
, nexthop
, api
.tag
);
854 /* Nothing has changed, so nothing to do; return */
857 if (ospf
->router_id
.s_addr
!= INADDR_ANY
) {
859 if (is_prefix_default(&p
))
860 ospf_external_lsa_refresh_default(ospf
);
862 struct ospf_lsa
*current
;
864 current
= ospf_external_info_find_lsa(
867 ospf_external_lsa_originate(
874 "ospf_zebra_read_route() : %s refreshing LSA",
877 ospf_external_lsa_refresh(
884 } else /* if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_DEL) */
886 ospf_external_info_delete(ospf
, rt_type
, api
.instance
, p
);
887 if (is_prefix_default(&p
))
888 ospf_external_lsa_refresh_default(ospf
);
890 ospf_external_lsa_flush(ospf
, rt_type
, &p
,
891 ifindex
/*, nexthop */);
898 int ospf_distribute_list_out_set(struct ospf
*ospf
, int type
, const char *name
)
900 /* Lookup access-list for distribute-list. */
901 DISTRIBUTE_LIST(ospf
, type
) = access_list_lookup(AFI_IP
, name
);
903 /* Clear previous distribute-name. */
904 if (DISTRIBUTE_NAME(ospf
, type
))
905 free(DISTRIBUTE_NAME(ospf
, type
));
907 /* Set distribute-name. */
908 DISTRIBUTE_NAME(ospf
, type
) = strdup(name
);
910 /* If access-list have been set, schedule update timer. */
911 if (DISTRIBUTE_LIST(ospf
, type
))
912 ospf_distribute_list_update(ospf
, type
, 0);
917 int ospf_distribute_list_out_unset(struct ospf
*ospf
, int type
,
920 /* Schedule update timer. */
921 if (DISTRIBUTE_LIST(ospf
, type
))
922 ospf_distribute_list_update(ospf
, type
, 0);
924 /* Unset distribute-list. */
925 DISTRIBUTE_LIST(ospf
, type
) = NULL
;
927 /* Clear distribute-name. */
928 if (DISTRIBUTE_NAME(ospf
, type
))
929 free(DISTRIBUTE_NAME(ospf
, type
));
931 DISTRIBUTE_NAME(ospf
, type
) = NULL
;
936 /* distribute-list update timer. */
937 static int ospf_distribute_list_update_timer(struct thread
*thread
)
939 struct route_node
*rn
;
940 struct external_info
*ei
;
941 struct route_table
*rt
;
942 struct ospf_lsa
*lsa
;
943 int type
, default_refresh
= 0, arg_type
;
944 struct ospf
*ospf
= NULL
;
945 void **arg
= THREAD_ARG(thread
);
947 ospf
= (struct ospf
*)arg
[0];
948 arg_type
= (int)(intptr_t)arg
[1];
953 ospf
->t_distribute_update
= NULL
;
955 zlog_info("Zebra[Redistribute]: distribute-list update timer fired!");
957 if (IS_DEBUG_OSPF_EVENT
) {
959 "%s: ospf distribute-list update arg_type %d vrf %s id %d",
960 __func__
, arg_type
, ospf_vrf_id_to_name(ospf
->vrf_id
),
964 /* foreach all external info. */
965 for (type
= 0; type
<= ZEBRA_ROUTE_MAX
; type
++) {
966 struct list
*ext_list
;
967 struct listnode
*node
;
968 struct ospf_external
*ext
;
970 ext_list
= ospf
->external
[type
];
974 for (ALL_LIST_ELEMENTS_RO(ext_list
, node
, ext
)) {
975 rt
= ext
->external_info
;
978 for (rn
= route_top(rt
); rn
; rn
= route_next(rn
))
979 if ((ei
= rn
->info
) != NULL
) {
980 if (is_prefix_default(&ei
->p
))
983 (lsa
= ospf_external_info_find_lsa(
985 ospf_external_lsa_refresh(
987 LSA_REFRESH_IF_CHANGED
);
989 ospf_external_lsa_originate(
995 ospf_external_lsa_refresh_default(ospf
);
997 XFREE(MTYPE_OSPF_DIST_ARGS
, arg
);
1001 /* Update distribute-list and set timer to apply access-list. */
1002 void ospf_distribute_list_update(struct ospf
*ospf
, int type
,
1003 unsigned short instance
)
1005 struct ospf_external
*ext
;
1006 void **args
= XCALLOC(MTYPE_OSPF_DIST_ARGS
, sizeof(void *) * 2);
1009 args
[1] = (void *)((ptrdiff_t)type
);
1011 /* External info does not exist. */
1012 ext
= ospf_external_lookup(ospf
, type
, instance
);
1013 if (!ext
|| !EXTERNAL_INFO(ext
)) {
1014 XFREE(MTYPE_OSPF_DIST_ARGS
, args
);
1018 /* If exists previously invoked thread, then let it continue. */
1019 if (ospf
->t_distribute_update
) {
1020 XFREE(MTYPE_OSPF_DIST_ARGS
, args
);
1025 ospf
->t_distribute_update
= NULL
;
1026 thread_add_timer_msec(master
, ospf_distribute_list_update_timer
, args
,
1027 ospf
->min_ls_interval
,
1028 &ospf
->t_distribute_update
);
1031 /* If access-list is updated, apply some check. */
1032 static void ospf_filter_update(struct access_list
*access
)
1037 struct ospf_area
*area
;
1038 struct listnode
*node
, *n1
;
1040 /* If OSPF instance does not exist, return right now. */
1041 if (listcount(om
->ospf
) == 0)
1044 /* Iterate all ospf [VRF] instances */
1045 for (ALL_LIST_ELEMENTS_RO(om
->ospf
, n1
, ospf
)) {
1046 /* Update distribute-list, and apply filter. */
1047 for (type
= 0; type
<= ZEBRA_ROUTE_MAX
; type
++) {
1048 struct list
*red_list
;
1049 struct ospf_redist
*red
;
1051 red_list
= ospf
->redist
[type
];
1053 for (ALL_LIST_ELEMENTS_RO(red_list
, node
,
1055 if (ROUTEMAP(red
)) {
1056 /* if route-map is not NULL it
1058 * using this access list */
1059 ospf_distribute_list_update(
1065 /* There is place for route-map for default-information
1066 * (ZEBRA_ROUTE_MAX),
1067 * but no distribute list. */
1068 if (type
== ZEBRA_ROUTE_MAX
)
1071 if (DISTRIBUTE_NAME(ospf
, type
)) {
1072 /* Keep old access-list for distribute-list. */
1073 struct access_list
*old
=
1074 DISTRIBUTE_LIST(ospf
, type
);
1076 /* Update access-list for distribute-list. */
1077 DISTRIBUTE_LIST(ospf
, type
) =
1080 DISTRIBUTE_NAME(ospf
, type
));
1082 /* No update for this distribute type. */
1084 && DISTRIBUTE_LIST(ospf
, type
) == NULL
)
1087 /* Schedule distribute-list update timer. */
1088 if (DISTRIBUTE_LIST(ospf
, type
) == NULL
1089 || strcmp(DISTRIBUTE_NAME(ospf
, type
),
1092 ospf_distribute_list_update(ospf
, type
,
1097 /* Update Area access-list. */
1098 for (ALL_LIST_ELEMENTS_RO(ospf
->areas
, node
, area
)) {
1099 if (EXPORT_NAME(area
)) {
1100 EXPORT_LIST(area
) = NULL
;
1104 if (IMPORT_NAME(area
)) {
1105 IMPORT_LIST(area
) = NULL
;
1110 /* Schedule ABR tasks -- this will be changed -- takada. */
1111 if (IS_OSPF_ABR(ospf
) && abr_inv
)
1112 ospf_schedule_abr_task(ospf
);
1116 /* If prefix-list is updated, do some updates. */
1117 void ospf_prefix_list_update(struct prefix_list
*plist
)
1119 struct ospf
*ospf
= NULL
;
1122 struct ospf_area
*area
;
1123 struct listnode
*node
, *n1
;
1125 /* If OSPF instatnce does not exist, return right now. */
1126 if (listcount(om
->ospf
) == 0)
1129 /* Iterate all ospf [VRF] instances */
1130 for (ALL_LIST_ELEMENTS_RO(om
->ospf
, n1
, ospf
)) {
1132 /* Update all route-maps which are used
1133 * as redistribution filters.
1134 * They might use prefix-list.
1136 for (type
= 0; type
<= ZEBRA_ROUTE_MAX
; type
++) {
1137 struct list
*red_list
;
1138 struct ospf_redist
*red
;
1140 red_list
= ospf
->redist
[type
];
1142 for (ALL_LIST_ELEMENTS_RO(red_list
, node
,
1144 if (ROUTEMAP(red
)) {
1145 /* if route-map is not NULL
1147 * this prefix list */
1148 ospf_distribute_list_update(
1156 /* Update area filter-lists. */
1157 for (ALL_LIST_ELEMENTS_RO(ospf
->areas
, node
, area
)) {
1158 /* Update filter-list in. */
1159 if (PREFIX_NAME_IN(area
))
1160 if (strcmp(PREFIX_NAME_IN(area
),
1161 prefix_list_name(plist
))
1163 PREFIX_LIST_IN(area
) =
1166 PREFIX_NAME_IN(area
));
1170 /* Update filter-list out. */
1171 if (PREFIX_NAME_OUT(area
))
1172 if (strcmp(PREFIX_NAME_OUT(area
),
1173 prefix_list_name(plist
))
1175 PREFIX_LIST_IN(area
) =
1178 PREFIX_NAME_OUT(area
));
1183 /* Schedule ABR task. */
1184 if (IS_OSPF_ABR(ospf
) && abr_inv
)
1185 ospf_schedule_abr_task(ospf
);
1189 static struct ospf_distance
*ospf_distance_new(void)
1191 return XCALLOC(MTYPE_OSPF_DISTANCE
, sizeof(struct ospf_distance
));
1194 static void ospf_distance_free(struct ospf_distance
*odistance
)
1196 XFREE(MTYPE_OSPF_DISTANCE
, odistance
);
1199 int ospf_distance_set(struct vty
*vty
, struct ospf
*ospf
,
1200 const char *distance_str
, const char *ip_str
,
1201 const char *access_list_str
)
1204 struct prefix_ipv4 p
;
1206 struct route_node
*rn
;
1207 struct ospf_distance
*odistance
;
1209 ret
= str2prefix_ipv4(ip_str
, &p
);
1211 vty_out(vty
, "Malformed prefix\n");
1212 return CMD_WARNING_CONFIG_FAILED
;
1215 distance
= atoi(distance_str
);
1217 /* Get OSPF distance node. */
1218 rn
= route_node_get(ospf
->distance_table
, (struct prefix
*)&p
);
1220 odistance
= rn
->info
;
1221 route_unlock_node(rn
);
1223 odistance
= ospf_distance_new();
1224 rn
->info
= odistance
;
1227 /* Set distance value. */
1228 odistance
->distance
= distance
;
1230 /* Reset access-list configuration. */
1231 if (odistance
->access_list
) {
1232 free(odistance
->access_list
);
1233 odistance
->access_list
= NULL
;
1235 if (access_list_str
)
1236 odistance
->access_list
= strdup(access_list_str
);
1241 int ospf_distance_unset(struct vty
*vty
, struct ospf
*ospf
,
1242 const char *distance_str
, const char *ip_str
,
1243 char const *access_list_str
)
1246 struct prefix_ipv4 p
;
1247 struct route_node
*rn
;
1248 struct ospf_distance
*odistance
;
1250 ret
= str2prefix_ipv4(ip_str
, &p
);
1252 vty_out(vty
, "Malformed prefix\n");
1253 return CMD_WARNING_CONFIG_FAILED
;
1256 rn
= route_node_lookup(ospf
->distance_table
, (struct prefix
*)&p
);
1258 vty_out(vty
, "Can't find specified prefix\n");
1259 return CMD_WARNING_CONFIG_FAILED
;
1262 odistance
= rn
->info
;
1264 if (odistance
->access_list
)
1265 free(odistance
->access_list
);
1266 ospf_distance_free(odistance
);
1269 route_unlock_node(rn
);
1270 route_unlock_node(rn
);
1275 void ospf_distance_reset(struct ospf
*ospf
)
1277 struct route_node
*rn
;
1278 struct ospf_distance
*odistance
;
1280 for (rn
= route_top(ospf
->distance_table
); rn
; rn
= route_next(rn
))
1281 if ((odistance
= rn
->info
) != NULL
) {
1282 if (odistance
->access_list
)
1283 free(odistance
->access_list
);
1284 ospf_distance_free(odistance
);
1286 route_unlock_node(rn
);
1290 uint8_t ospf_distance_apply(struct ospf
*ospf
, struct prefix_ipv4
*p
,
1291 struct ospf_route
* or)
1297 if (ospf
->distance_intra
)
1298 if (or->path_type
== OSPF_PATH_INTRA_AREA
)
1299 return ospf
->distance_intra
;
1301 if (ospf
->distance_inter
)
1302 if (or->path_type
== OSPF_PATH_INTER_AREA
)
1303 return ospf
->distance_inter
;
1305 if (ospf
->distance_external
)
1306 if (or->path_type
== OSPF_PATH_TYPE1_EXTERNAL
||
1307 or->path_type
== OSPF_PATH_TYPE2_EXTERNAL
)
1308 return ospf
->distance_external
;
1310 if (ospf
->distance_all
)
1311 return ospf
->distance_all
;
1316 void ospf_zebra_vrf_register(struct ospf
*ospf
)
1318 if (!zclient
|| zclient
->sock
< 0 || !ospf
)
1321 if (ospf
->vrf_id
!= VRF_UNKNOWN
) {
1322 if (IS_DEBUG_OSPF_EVENT
)
1323 zlog_debug("%s: Register VRF %s id %u", __func__
,
1324 ospf_vrf_id_to_name(ospf
->vrf_id
),
1326 zclient_send_reg_requests(zclient
, ospf
->vrf_id
);
1330 void ospf_zebra_vrf_deregister(struct ospf
*ospf
)
1332 if (!zclient
|| zclient
->sock
< 0 || !ospf
)
1335 if (ospf
->vrf_id
!= VRF_DEFAULT
&& ospf
->vrf_id
!= VRF_UNKNOWN
) {
1336 if (IS_DEBUG_OSPF_EVENT
)
1337 zlog_debug("%s: De-Register VRF %s id %u to Zebra.",
1338 __func__
, ospf_vrf_id_to_name(ospf
->vrf_id
),
1340 /* Deregister for router-id, interfaces,
1341 * redistributed routes. */
1342 zclient_send_dereg_requests(zclient
, ospf
->vrf_id
);
1345 static void ospf_zebra_connected(struct zclient
*zclient
)
1347 /* Send the client registration */
1348 bfd_client_sendmsg(zclient
, ZEBRA_BFD_CLIENT_REGISTER
, VRF_DEFAULT
);
1350 zclient_send_reg_requests(zclient
, VRF_DEFAULT
);
1353 void ospf_zebra_init(struct thread_master
*master
, unsigned short instance
)
1355 /* Allocate zebra structure. */
1356 zclient
= zclient_new(master
, &zclient_options_default
);
1357 zclient_init(zclient
, ZEBRA_ROUTE_OSPF
, instance
, &ospfd_privs
);
1358 zclient
->zebra_connected
= ospf_zebra_connected
;
1359 zclient
->router_id_update
= ospf_router_id_update_zebra
;
1360 zclient
->interface_address_add
= ospf_interface_address_add
;
1361 zclient
->interface_address_delete
= ospf_interface_address_delete
;
1362 zclient
->interface_link_params
= ospf_interface_link_params
;
1363 zclient
->interface_vrf_update
= ospf_interface_vrf_update
;
1365 zclient
->redistribute_route_add
= ospf_zebra_read_route
;
1366 zclient
->redistribute_route_del
= ospf_zebra_read_route
;
1368 access_list_add_hook(ospf_filter_update
);
1369 access_list_delete_hook(ospf_filter_update
);
1370 prefix_list_add_hook(ospf_prefix_list_update
);
1371 prefix_list_delete_hook(ospf_prefix_list_update
);