diff options
Diffstat (limited to 'ospfd/ospf_zebra.c')
| -rw-r--r-- | ospfd/ospf_zebra.c | 178 |
1 files changed, 173 insertions, 5 deletions
diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index 2b8769a4a8..0487ace301 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -51,6 +51,7 @@ #include "ospfd/ospf_zebra.h" #include "ospfd/ospf_te.h" #include "ospfd/ospf_sr.h" +#include "ospfd/ospf_ldp_sync.h" DEFINE_MTYPE_STATIC(OSPFD, OSPF_EXTERNAL, "OSPF External route table") DEFINE_MTYPE_STATIC(OSPFD, OSPF_REDISTRIBUTE, "OSPF Redistriute") @@ -59,6 +60,8 @@ DEFINE_MTYPE_STATIC(OSPFD, OSPF_DIST_ARGS, "OSPF Distribute arguments") /* Zebra structure to hold current status. */ struct zclient *zclient = NULL; +/* and for the Synchronous connection to the Label Manager */ +static struct zclient *zclient_sync; /* For registering threads. */ extern struct thread_master *master; @@ -1351,11 +1354,18 @@ static int ospf_distribute_list_update_timer(struct thread *thread) default_refresh = 1; else if ( (lsa = ospf_external_info_find_lsa( - ospf, &ei->p))) - ospf_external_lsa_refresh( - ospf, lsa, ei, - LSA_REFRESH_IF_CHANGED); - else + ospf, &ei->p))) { + if (!CHECK_FLAG( + lsa->flags, + OSPF_LSA_IN_MAXAGE)) + ospf_external_lsa_refresh( + ospf, lsa, ei, + LSA_REFRESH_IF_CHANGED); + else + ospf_external_lsa_refresh( + ospf, lsa, ei, + LSA_REFRESH_FORCE); + } else ospf_external_lsa_originate( ospf, ei); } @@ -1713,6 +1723,109 @@ void ospf_zebra_vrf_deregister(struct ospf *ospf) } } +/* Label Manager Functions */ + +/** + * Check if Label Manager is Ready or not. + * + * @return True if Label Manager is ready, False otherwise + */ +bool ospf_zebra_label_manager_ready(void) +{ + return (zclient_sync->sock > 0); +} + +/** + * Request Label Range to the Label Manager. + * + * @param base base label of the label range to request + * @param chunk_size size of the label range to request + * + * @return 0 on success, -1 on failure + */ +int ospf_zebra_request_label_range(uint32_t base, uint32_t chunk_size) +{ + int ret; + uint32_t start, end; + + if (zclient_sync->sock < 0) + return -1; + + ret = lm_get_label_chunk(zclient_sync, 0, base, chunk_size, &start, + &end); + if (ret < 0) { + zlog_warn("%s: error getting label range!", __func__); + return -1; + } + + return 0; +} + +/** + * Release Label Range to the Label Manager. + * + * @param start start of label range to release + * @param end end of label range to release + * + * @return 0 on success, -1 otherwise + */ +int ospf_zebra_release_label_range(uint32_t start, uint32_t end) +{ + int ret; + + if (zclient_sync->sock < 0) + return -1; + + ret = lm_release_label_chunk(zclient_sync, start, end); + if (ret < 0) { + zlog_warn("%s: error releasing label range!", __func__); + return -1; + } + + return 0; +} + +/** + * Connect to the Label Manager. + * + * @return 0 on success, -1 otherwise + */ +int ospf_zebra_label_manager_connect(void) +{ + /* Connect to label manager. */ + if (zclient_socket_connect(zclient_sync) < 0) { + zlog_warn("%s: failed connecting synchronous zclient!", + __func__); + return -1; + } + /* make socket non-blocking */ + set_nonblocking(zclient_sync->sock); + + /* Send hello to notify zebra this is a synchronous client */ + if (zclient_send_hello(zclient_sync) < 0) { + zlog_warn("%s: failed sending hello for synchronous zclient!", + __func__); + close(zclient_sync->sock); + zclient_sync->sock = -1; + return -1; + } + + /* Connect to label manager */ + if (lm_label_manager_connect(zclient_sync, 0) != 0) { + zlog_warn("%s: failed connecting to label manager!", __func__); + if (zclient_sync->sock > 0) { + close(zclient_sync->sock); + zclient_sync->sock = -1; + } + return -1; + } + + osr_debug("SR (%s): Successfully connected to the Label Manager", + __func__); + + return 0; +} + static void ospf_zebra_connected(struct zclient *zclient) { /* Send the client registration */ @@ -1721,6 +1834,45 @@ static void ospf_zebra_connected(struct zclient *zclient) zclient_send_reg_requests(zclient, VRF_DEFAULT); } +/* + * opaque messages between processes + */ +static int ospf_opaque_msg_handler(ZAPI_CALLBACK_ARGS) +{ + struct stream *s; + struct zapi_opaque_msg info; + struct ldp_igp_sync_if_state state; + struct ldp_igp_sync_announce announce; + struct ldp_igp_sync_hello hello; + int ret = 0; + + s = zclient->ibuf; + + if (zclient_opaque_decode(s, &info) != 0) + return -1; + + switch (info.type) { + case LDP_IGP_SYNC_IF_STATE_UPDATE: + STREAM_GET(&state, s, sizeof(state)); + ret = ospf_ldp_sync_state_update(state); + break; + case LDP_IGP_SYNC_ANNOUNCE_UPDATE: + STREAM_GET(&announce, s, sizeof(announce)); + ret = ospf_ldp_sync_announce_update(announce); + break; + case LDP_IGP_SYNC_HELLO_UPDATE: + STREAM_GET(&hello, s, sizeof(hello)); + ret = ospf_ldp_sync_hello_update(hello); + break; + default: + break; + } + +stream_failure: + + return ret; +} + void ospf_zebra_init(struct thread_master *master, unsigned short instance) { /* Allocate zebra structure. */ @@ -1736,10 +1888,26 @@ void ospf_zebra_init(struct thread_master *master, unsigned short instance) zclient->redistribute_route_add = ospf_zebra_read_route; zclient->redistribute_route_del = ospf_zebra_read_route; + /* Initialize special zclient for synchronous message exchanges. */ + struct zclient_options options = zclient_options_default; + options.synchronous = true; + zclient_sync = zclient_new(master, &options); + zclient_sync->sock = -1; + zclient_sync->redist_default = ZEBRA_ROUTE_OSPF; + zclient_sync->instance = instance; + /* + * session_id must be different from default value (0) to distinguish + * the asynchronous socket from the synchronous one + */ + zclient_sync->session_id = 1; + zclient_sync->privs = &ospfd_privs; + access_list_add_hook(ospf_filter_update); access_list_delete_hook(ospf_filter_update); prefix_list_add_hook(ospf_prefix_list_update); prefix_list_delete_hook(ospf_prefix_list_update); + + zclient->opaque_msg_handler = ospf_opaque_msg_handler; } void ospf_zebra_send_arp(const struct interface *ifp, const struct prefix *p) |
