diff options
Diffstat (limited to 'ospf6d/ospf6_zebra.c')
| -rw-r--r-- | ospf6d/ospf6_zebra.c | 165 |
1 files changed, 136 insertions, 29 deletions
diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c index 72bc3a2f3a..5e50a6cc55 100644 --- a/ospf6d/ospf6_zebra.c +++ b/ospf6d/ospf6_zebra.c @@ -37,9 +37,11 @@ #include "ospf6_lsa.h" #include "ospf6_lsdb.h" #include "ospf6_asbr.h" +#include "ospf6_nssa.h" #include "ospf6_zebra.h" #include "ospf6d.h" #include "ospf6_area.h" +#include "ospf6_gr.h" #include "lib/json.h" DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_DISTANCE, "OSPF6 distance"); @@ -101,7 +103,7 @@ static int ospf6_router_id_update_zebra(ZAPI_CALLBACK_ARGS) o->router_id_zebra = router_id.u.prefix4.s_addr; - ospf6_router_id_update(o); + ospf6_router_id_update(o, false); return 0; } @@ -128,41 +130,76 @@ void ospf6_zebra_no_redistribute(int type, vrf_id_t vrf_id) AFI_IP6, type, 0, vrf_id); } +void ospf6_zebra_import_default_route(struct ospf6 *ospf6, bool unreg) +{ + struct prefix prefix = {}; + int command; + + if (zclient->sock < 0) { + if (IS_OSPF6_DEBUG_ZEBRA(SEND)) + zlog_debug(" Not connected to Zebra"); + return; + } + + prefix.family = AF_INET6; + prefix.prefixlen = 0; + + if (unreg) + command = ZEBRA_NEXTHOP_UNREGISTER; + else + command = ZEBRA_NEXTHOP_REGISTER; + + if (IS_OSPF6_DEBUG_ZEBRA(SEND)) + zlog_debug("%s: sending cmd %s for %pFX (vrf %u)", __func__, + zserv_command_string(command), &prefix, + ospf6->vrf_id); + + if (zclient_send_rnh(zclient, command, &prefix, false, true, + ospf6->vrf_id) + == ZCLIENT_SEND_FAILURE) + flog_err(EC_LIB_ZAPI_SOCKET, "%s: zclient_send_rnh() failed", + __func__); +} + +static int ospf6_zebra_import_check_update(ZAPI_CALLBACK_ARGS) +{ + struct ospf6 *ospf6; + struct zapi_route nhr; + + ospf6 = ospf6_lookup_by_vrf_id(vrf_id); + if (ospf6 == NULL || !IS_OSPF6_ASBR(ospf6)) + return 0; + + if (!zapi_nexthop_update_decode(zclient->ibuf, &nhr)) { + zlog_err("%s[%u]: Failure to decode route", __func__, + ospf6->vrf_id); + return -1; + } + + if (nhr.prefix.family != AF_INET6 || nhr.prefix.prefixlen != 0 + || nhr.type == ZEBRA_ROUTE_OSPF6) + return 0; + + ospf6->nssa_default_import_check.status = !!nhr.nexthop_num; + ospf6_abr_nssa_type_7_defaults(ospf6); + + return 0; +} + static int ospf6_zebra_if_address_update_add(ZAPI_CALLBACK_ARGS) { struct connected *c; - struct ospf6_interface *oi; - int ipv6_count = 0; c = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD, zclient->ibuf, vrf_id); if (c == NULL) return 0; - oi = (struct ospf6_interface *)c->ifp->info; - if (oi == NULL) - oi = ospf6_interface_create(c->ifp); - assert(oi); - if (IS_OSPF6_DEBUG_ZEBRA(RECV)) zlog_debug("Zebra Interface address add: %s %5s %pFX", c->ifp->name, prefix_family_str(c->address), c->address); - ipv6_count = connected_count_by_family(c->ifp, AF_INET6); - if (oi->ifmtu == OSPF6_DEFAULT_MTU && ipv6_count > OSPF6_MAX_IF_ADDRS) { - zlog_warn( - "Zebra Interface : %s has too many interface addresses %d only support %d, increase MTU", - c->ifp->name, ipv6_count, OSPF6_MAX_IF_ADDRS); - return 0; - } else if (oi->ifmtu >= OSPF6_JUMBO_MTU - && ipv6_count > OSPF6_MAX_IF_ADDRS_JUMBO) { - zlog_warn( - "Zebra Interface : %s has too many interface addresses %d only support %d", - c->ifp->name, ipv6_count, OSPF6_MAX_IF_ADDRS_JUMBO); - return 0; - } - if (c->address->family == AF_INET6) { ospf6_interface_state_update(c->ifp); ospf6_interface_connected_route_update(c->ifp); @@ -194,6 +231,36 @@ static int ospf6_zebra_if_address_update_delete(ZAPI_CALLBACK_ARGS) return 0; } +static int ospf6_zebra_gr_update(struct ospf6 *ospf6, int command, + uint32_t stale_time) +{ + struct zapi_cap api; + + if (!zclient || zclient->sock < 0 || !ospf6) + return 1; + + memset(&api, 0, sizeof(struct zapi_cap)); + api.cap = command; + api.stale_removal_time = stale_time; + api.vrf_id = ospf6->vrf_id; + + (void)zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, zclient, + &api); + + return 0; +} + +int ospf6_zebra_gr_enable(struct ospf6 *ospf6, uint32_t stale_time) +{ + return ospf6_zebra_gr_update(ospf6, ZEBRA_CLIENT_GR_CAPABILITIES, + stale_time); +} + +int ospf6_zebra_gr_disable(struct ospf6 *ospf6) +{ + return ospf6_zebra_gr_update(ospf6, ZEBRA_CLIENT_GR_DISABLE, 0); +} + static int ospf6_zebra_read_route(ZAPI_CALLBACK_ARGS) { struct zapi_route api; @@ -405,12 +472,30 @@ static void ospf6_zebra_route_update(int type, struct ospf6_route *request, void ospf6_zebra_route_update_add(struct ospf6_route *request, struct ospf6 *ospf6) { + if (ospf6->gr_info.restart_in_progress + || ospf6->gr_info.prepare_in_progress) { + if (IS_DEBUG_OSPF6_GR) + zlog_debug( + "Zebra: Graceful Restart in progress -- not installing %pFX", + &request->prefix); + return; + } + ospf6_zebra_route_update(ADD, request, ospf6); } void ospf6_zebra_route_update_remove(struct ospf6_route *request, struct ospf6 *ospf6) { + if (ospf6->gr_info.restart_in_progress + || ospf6->gr_info.prepare_in_progress) { + if (IS_DEBUG_OSPF6_GR) + zlog_debug( + "Zebra: Graceful Restart in progress -- not uninstalling %pFX", + &request->prefix); + return; + } + ospf6_zebra_route_update(REM, request, ospf6); } @@ -419,6 +504,15 @@ void ospf6_zebra_add_discard(struct ospf6_route *request, struct ospf6 *ospf6) struct zapi_route api; struct prefix *dest = &request->prefix; + if (ospf6->gr_info.restart_in_progress + || ospf6->gr_info.prepare_in_progress) { + if (IS_DEBUG_OSPF6_GR) + zlog_debug( + "Zebra: Graceful Restart in progress -- not installing %pFX", + &request->prefix); + return; + } + if (!CHECK_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) { memset(&api, 0, sizeof(api)); api.vrf_id = ospf6->vrf_id; @@ -447,6 +541,15 @@ void ospf6_zebra_delete_discard(struct ospf6_route *request, struct zapi_route api; struct prefix *dest = &request->prefix; + if (ospf6->gr_info.restart_in_progress + || ospf6->gr_info.prepare_in_progress) { + if (IS_DEBUG_OSPF6_GR) + zlog_debug( + "Zebra: Graceful Restart in progress -- not uninstalling %pFX", + &request->prefix); + return; + } + if (CHECK_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) { memset(&api, 0, sizeof(api)); api.vrf_id = ospf6->vrf_id; @@ -606,18 +709,22 @@ static void ospf6_zebra_connected(struct zclient *zclient) zclient_send_reg_requests(zclient, VRF_DEFAULT); } +static zclient_handler *const ospf6_handlers[] = { + [ZEBRA_ROUTER_ID_UPDATE] = ospf6_router_id_update_zebra, + [ZEBRA_INTERFACE_ADDRESS_ADD] = ospf6_zebra_if_address_update_add, + [ZEBRA_INTERFACE_ADDRESS_DELETE] = ospf6_zebra_if_address_update_delete, + [ZEBRA_REDISTRIBUTE_ROUTE_ADD] = ospf6_zebra_read_route, + [ZEBRA_REDISTRIBUTE_ROUTE_DEL] = ospf6_zebra_read_route, + [ZEBRA_NEXTHOP_UPDATE] = ospf6_zebra_import_check_update, +}; + void ospf6_zebra_init(struct thread_master *master) { /* Allocate zebra structure. */ - zclient = zclient_new(master, &zclient_options_default); + zclient = zclient_new(master, &zclient_options_default, ospf6_handlers, + array_size(ospf6_handlers)); zclient_init(zclient, ZEBRA_ROUTE_OSPF6, 0, &ospf6d_privs); zclient->zebra_connected = ospf6_zebra_connected; - zclient->router_id_update = ospf6_router_id_update_zebra; - zclient->interface_address_add = ospf6_zebra_if_address_update_add; - zclient->interface_address_delete = - ospf6_zebra_if_address_update_delete; - zclient->redistribute_route_add = ospf6_zebra_read_route; - zclient->redistribute_route_del = ospf6_zebra_read_route; /* Install command element for zebra node. */ install_element(VIEW_NODE, &show_ospf6_zebra_cmd); |
