+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2020 NetDEF, Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; see the file COPYING; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <zebra.h>
#include "lib_errors.h"
#include "network.h"
#include "libfrr.h"
+#include <debug.h>
+#include <hook.h>
#include "pathd/pathd.h"
#include "pathd/path_zebra.h"
DEFINE_HOOK(pathd_candidate_removed, (struct srte_candidate * candidate),
(candidate));
+struct debug path_policy_debug;
+
+#define PATH_POLICY_DEBUG(fmt, ...) \
+ do { \
+ if (DEBUG_FLAGS_CHECK(&path_policy_debug, \
+ PATH_POLICY_DEBUG_BASIC)) \
+ DEBUGD(&path_policy_debug, "policy: " fmt, \
+ ##__VA_ARGS__); \
+ } while (0)
+
+
static void trigger_pathd_candidate_created(struct srte_candidate *candidate);
-static void trigger_pathd_candidate_created_timer(struct thread *thread);
+static void trigger_pathd_candidate_created_timer(struct event *thread);
static void trigger_pathd_candidate_updated(struct srte_candidate *candidate);
-static void trigger_pathd_candidate_updated_timer(struct thread *thread);
+static void trigger_pathd_candidate_updated_timer(struct event *thread);
static void trigger_pathd_candidate_removed(struct srte_candidate *candidate);
static const char *
srte_candidate_metric_name(enum srte_candidate_metric_type type);
struct srte_policy_head srte_policies = RB_INITIALIZER(&srte_policies);
+static void srte_policy_status_log(struct srte_policy *policy)
+{
+ char endpoint[ENDPOINT_STR_LENGTH];
+
+ ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint));
+ if (policy->status == SRTE_POLICY_STATUS_DOWN) {
+ PATH_POLICY_DEBUG("SR-TE(%s, %u): policy is DOWN", endpoint,
+ policy->color);
+ } else if (policy->status == SRTE_POLICY_STATUS_UP) {
+ PATH_POLICY_DEBUG("SR-TE(%s, %u): policy is UP", endpoint,
+ policy->color);
+ }
+}
+
/**
* Adds a segment list to pathd.
*
segment->nai_local_iface = local_iface;
status = srte_ted_do_query_type_e(segment, &pre, local_iface);
break;
- default:
+ case SRTE_SEGMENT_NAI_TYPE_NONE:
+ case SRTE_SEGMENT_NAI_TYPE_IPV6_ADJACENCY_LINK_LOCAL_ADDRESSES:
segment->nai_local_addr.ipa_type = IPADDR_NONE;
segment->nai_local_iface = 0;
segment->nai_remote_addr.ipa_type = IPADDR_NONE;
s_entry, &prefix_cli,
s_entry->nai_algorithm);
break;
- default:
+ case SRTE_SEGMENT_NAI_TYPE_NONE:
+ case SRTE_SEGMENT_NAI_TYPE_IPV4_NODE:
+ case SRTE_SEGMENT_NAI_TYPE_IPV6_NODE:
+ case SRTE_SEGMENT_NAI_TYPE_IPV4_UNNUMBERED_ADJACENCY:
+ case SRTE_SEGMENT_NAI_TYPE_IPV6_ADJACENCY_LINK_LOCAL_ADDRESSES:
break;
}
}
RB_FOREACH_SAFE (policy, srte_policy_head, &srte_policies, safe_pol)
srte_policy_del(policy);
+
+ path_zebra_stop();
}
/**
RB_FOREACH_SAFE (policy, srte_policy_head, &srte_policies, safe_pol) {
if (CHECK_FLAG(policy->flags, F_POLICY_DELETED)) {
+ if (policy->status != SRTE_POLICY_STATUS_DOWN) {
+ policy->status = SRTE_POLICY_STATUS_DOWN;
+ srte_policy_status_log(policy);
+ }
srte_policy_del(policy);
continue;
}
struct srte_candidate *candidate, *safe;
struct srte_candidate *old_best_candidate;
struct srte_candidate *new_best_candidate;
- char endpoint[46];
+ char endpoint[ENDPOINT_STR_LENGTH];
ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint));
new_best_candidate = srte_policy_best_candidate(policy);
if (new_best_candidate != old_best_candidate) {
- /* TODO: add debug guard. */
- zlog_debug(
+ PATH_POLICY_DEBUG(
"SR-TE(%s, %u): best candidate changed from %s to %s",
endpoint, policy->color,
old_best_candidate ? old_best_candidate->name : "none",
F_SEGMENT_LIST_MODIFIED);
if (candidate_changed || segment_list_changed) {
- /* TODO: add debug guard. */
- zlog_debug("SR-TE(%s, %u): best candidate %s changed",
- endpoint, policy->color,
- new_best_candidate->name);
+ PATH_POLICY_DEBUG(
+ "SR-TE(%s, %u): best candidate %s changed",
+ endpoint, policy->color,
+ new_best_candidate->name);
path_zebra_add_sr_policy(
policy, new_best_candidate->lsp->segment_list);
float bandwidth, bool required)
{
struct srte_policy *policy = candidate->policy;
- char endpoint[46];
+ char endpoint[ENDPOINT_STR_LENGTH];
ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint));
- zlog_debug(
+ PATH_POLICY_DEBUG(
"SR-TE(%s, %u): candidate %s %sconfig bandwidth set to %f B/s",
endpoint, policy->color, candidate->name,
required ? "required " : "", bandwidth);
{
struct srte_candidate *candidate = lsp->candidate;
struct srte_policy *policy = candidate->policy;
- char endpoint[46];
+ char endpoint[ENDPOINT_STR_LENGTH];
+
ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint));
- zlog_debug("SR-TE(%s, %u): candidate %s %slsp bandwidth set to %f B/s",
- endpoint, policy->color, candidate->name,
- required ? "required" : "", bandwidth);
+ PATH_POLICY_DEBUG(
+ "SR-TE(%s, %u): candidate %s %slsp bandwidth set to %f B/s",
+ endpoint, policy->color, candidate->name,
+ required ? "required" : "", bandwidth);
SET_FLAG(lsp->flags, F_CANDIDATE_HAS_BANDWIDTH);
COND_FLAG(lsp->flags, F_CANDIDATE_REQUIRED_BANDWIDTH, required);
lsp->bandwidth = bandwidth;
void srte_candidate_unset_bandwidth(struct srte_candidate *candidate)
{
struct srte_policy *policy = candidate->policy;
- char endpoint[46];
+ char endpoint[ENDPOINT_STR_LENGTH];
+
ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint));
- zlog_debug("SR-TE(%s, %u): candidate %s config bandwidth unset",
- endpoint, policy->color, candidate->name);
+ PATH_POLICY_DEBUG("SR-TE(%s, %u): candidate %s config bandwidth unset",
+ endpoint, policy->color, candidate->name);
UNSET_FLAG(candidate->flags, F_CANDIDATE_HAS_BANDWIDTH);
UNSET_FLAG(candidate->flags, F_CANDIDATE_REQUIRED_BANDWIDTH);
candidate->bandwidth = 0;
{
struct srte_candidate *candidate = lsp->candidate;
struct srte_policy *policy = candidate->policy;
- char endpoint[46];
+ char endpoint[ENDPOINT_STR_LENGTH];
+
ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint));
- zlog_debug("SR-TE(%s, %u): candidate %s lsp bandwidth unset", endpoint,
- policy->color, candidate->name);
+ PATH_POLICY_DEBUG("SR-TE(%s, %u): candidate %s lsp bandwidth unset",
+ endpoint, policy->color, candidate->name);
UNSET_FLAG(lsp->flags, F_CANDIDATE_HAS_BANDWIDTH);
UNSET_FLAG(lsp->flags, F_CANDIDATE_REQUIRED_BANDWIDTH);
SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED);
bool is_computed)
{
struct srte_policy *policy = candidate->policy;
- char endpoint[46];
+ char endpoint[ENDPOINT_STR_LENGTH];
+
ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint));
- zlog_debug(
+ PATH_POLICY_DEBUG(
"SR-TE(%s, %u): candidate %s %sconfig metric %s (%u) set to %f (is-bound: %s; is_computed: %s)",
endpoint, policy->color, candidate->name,
required ? "required " : "", srte_candidate_metric_name(type),
{
struct srte_candidate *candidate = lsp->candidate;
struct srte_policy *policy = candidate->policy;
- char endpoint[46];
+ char endpoint[ENDPOINT_STR_LENGTH];
+
ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint));
- zlog_debug(
+ PATH_POLICY_DEBUG(
"SR-TE(%s, %u): candidate %s %slsp metric %s (%u) set to %f (is-bound: %s; is_computed: %s)",
endpoint, policy->color, candidate->name,
required ? "required " : "", srte_candidate_metric_name(type),
enum srte_candidate_metric_type type)
{
struct srte_policy *policy = candidate->policy;
- char endpoint[46];
+ char endpoint[ENDPOINT_STR_LENGTH];
+
ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint));
- zlog_debug("SR-TE(%s, %u): candidate %s config metric %s (%u) unset",
- endpoint, policy->color, candidate->name,
- srte_candidate_metric_name(type), type);
+ PATH_POLICY_DEBUG(
+ "SR-TE(%s, %u): candidate %s config metric %s (%u) unset",
+ endpoint, policy->color, candidate->name,
+ srte_candidate_metric_name(type), type);
assert((type > 0) && (type <= MAX_METRIC_TYPE));
srte_unset_metric(&candidate->metrics[type - 1]);
srte_lsp_unset_metric(candidate->lsp, type);
{
struct srte_candidate *candidate = lsp->candidate;
struct srte_policy *policy = candidate->policy;
- char endpoint[46];
+ char endpoint[ENDPOINT_STR_LENGTH];
+
ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint));
- zlog_debug("SR-TE(%s, %u): candidate %s lsp metric %s (%u) unset",
- endpoint, policy->color, candidate->name,
- srte_candidate_metric_name(type), type);
+ PATH_POLICY_DEBUG(
+ "SR-TE(%s, %u): candidate %s lsp metric %s (%u) unset",
+ endpoint, policy->color, candidate->name,
+ srte_candidate_metric_name(type), type);
assert((type > 0) && (type <= MAX_METRIC_TYPE));
srte_unset_metric(&lsp->metrics[type - 1]);
}
enum objfun_type type)
{
struct srte_policy *policy = candidate->policy;
- char endpoint[46];
+ char endpoint[ENDPOINT_STR_LENGTH];
+
ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint));
candidate->objfun = type;
SET_FLAG(candidate->flags, F_CANDIDATE_HAS_OBJFUN);
COND_FLAG(candidate->flags, F_CANDIDATE_REQUIRED_OBJFUN, required);
SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED);
- zlog_debug("SR-TE(%s, %u): candidate %s %sobjective function set to %s",
- endpoint, policy->color, candidate->name,
- required ? "required " : "", objfun_type_name(type));
+ PATH_POLICY_DEBUG(
+ "SR-TE(%s, %u): candidate %s %sobjective function set to %s",
+ endpoint, policy->color, candidate->name,
+ required ? "required " : "", objfun_type_name(type));
}
/**
void srte_candidate_unset_objfun(struct srte_candidate *candidate)
{
struct srte_policy *policy = candidate->policy;
- char endpoint[46];
+ char endpoint[ENDPOINT_STR_LENGTH];
+
ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint));
UNSET_FLAG(candidate->flags, F_CANDIDATE_HAS_OBJFUN);
UNSET_FLAG(candidate->flags, F_CANDIDATE_REQUIRED_OBJFUN);
SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED);
candidate->objfun = OBJFUN_UNDEFINED;
- zlog_debug(
+ PATH_POLICY_DEBUG(
"SR-TE(%s, %u): candidate %s objective functions preferences unset",
endpoint, policy->color, candidate->name);
}
return F_CANDIDATE_HAS_INCLUDE_ANY;
case AFFINITY_FILTER_INCLUDE_ALL:
return F_CANDIDATE_HAS_INCLUDE_ALL;
- default:
+ case AFFINITY_FILTER_UNDEFINED:
return 0;
}
+
+ assert(!"Reached end of function we should never hit");
}
static const char *filter_type_name(enum affinity_filter_type type)
return "include-any";
case AFFINITY_FILTER_INCLUDE_ALL:
return "include-all";
- default:
+ case AFFINITY_FILTER_UNDEFINED:
return "unknown";
}
+
+ assert(!"Reached end of function we should never hit");
}
/**
uint32_t filter)
{
struct srte_policy *policy = candidate->policy;
- char endpoint[46];
+ char endpoint[ENDPOINT_STR_LENGTH];
+
ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint));
assert(type > AFFINITY_FILTER_UNDEFINED);
SET_FLAG(candidate->flags, filter_type_to_flag(type));
SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED);
candidate->affinity_filters[type - 1] = filter;
- zlog_debug(
+ PATH_POLICY_DEBUG(
"SR-TE(%s, %u): candidate %s affinity filter %s set to 0x%08x",
endpoint, policy->color, candidate->name,
filter_type_name(type), filter);
enum affinity_filter_type type)
{
struct srte_policy *policy = candidate->policy;
- char endpoint[46];
+ char endpoint[ENDPOINT_STR_LENGTH];
+
ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint));
assert(type > AFFINITY_FILTER_UNDEFINED);
UNSET_FLAG(candidate->flags, filter_type_to_flag(type));
SET_FLAG(candidate->flags, F_CANDIDATE_MODIFIED);
candidate->affinity_filters[type - 1] = 0;
- zlog_debug("SR-TE(%s, %u): candidate %s affinity filter %s unset",
- endpoint, policy->color, candidate->name,
- filter_type_name(type));
+ PATH_POLICY_DEBUG(
+ "SR-TE(%s, %u): candidate %s affinity filter %s unset",
+ endpoint, policy->color, candidate->name,
+ filter_type_name(type));
}
/**
void srte_candidate_status_update(struct srte_candidate *candidate, int status)
{
struct srte_policy *policy = candidate->policy;
- char endpoint[46];
+ char endpoint[ENDPOINT_STR_LENGTH];
+
ipaddr2str(&policy->endpoint, endpoint, sizeof(endpoint));
- zlog_debug("SR-TE(%s, %u): zebra updated status to %d", endpoint,
- policy->color, status);
+ PATH_POLICY_DEBUG("SR-TE(%s, %u): zebra updated status to %d", endpoint,
+ policy->color, status);
switch (status) {
case ZEBRA_SR_POLICY_DOWN:
switch (policy->status) {
case SRTE_POLICY_STATUS_GOING_UP:
case SRTE_POLICY_STATUS_DOWN:
return;
- default:
- zlog_debug("SR-TE(%s, %u): policy is DOWN", endpoint,
- policy->color);
+ case SRTE_POLICY_STATUS_UNKNOWN:
+ case SRTE_POLICY_STATUS_UP:
+ case SRTE_POLICY_STATUS_GOING_DOWN:
policy->status = SRTE_POLICY_STATUS_DOWN;
+ srte_policy_status_log(policy);
break;
}
break;
switch (policy->status) {
case SRTE_POLICY_STATUS_UP:
return;
- default:
- zlog_debug("SR-TE(%s, %u): policy is UP", endpoint,
- policy->color);
+ case SRTE_POLICY_STATUS_UNKNOWN:
+ case SRTE_POLICY_STATUS_DOWN:
+ case SRTE_POLICY_STATUS_GOING_DOWN:
+ case SRTE_POLICY_STATUS_GOING_UP:
policy->status = SRTE_POLICY_STATUS_UP;
+ srte_policy_status_log(policy);
break;
}
break;
return;
}
- zlog_debug("Unset segment lists for originator %s", originator);
+ PATH_POLICY_DEBUG("Unset segment lists for originator %s", originator);
/* Iterate the policies, then iterate each policy's candidate path
* to check the candidate path's segment list originator */
struct srte_policy *policy;
RB_FOREACH (policy, srte_policy_head, &srte_policies) {
- zlog_debug("Unset segment lists checking policy %s",
- policy->name);
+ PATH_POLICY_DEBUG("Unset segment lists checking policy %s",
+ policy->name);
struct srte_candidate *candidate;
RB_FOREACH (candidate, srte_candidate_head,
&policy->candidate_paths) {
- zlog_debug("Unset segment lists checking candidate %s",
- candidate->name);
+ PATH_POLICY_DEBUG(
+ "Unset segment lists checking candidate %s",
+ candidate->name);
if (candidate->lsp == NULL) {
continue;
}
sizeof(segment_list->originator))
== 0
|| force) {
- zlog_debug("Unset segment list %s",
- segment_list->name);
+ PATH_POLICY_DEBUG("Unset segment list %s",
+ segment_list->name);
SET_FLAG(segment_list->flags,
F_SEGMENT_LIST_DELETED);
SET_FLAG(candidate->flags,
return "BGP";
case SRTE_ORIGIN_LOCAL:
return "Local";
- default:
+ case SRTE_ORIGIN_UNDEFINED:
return "Unknown";
}
+
+ assert(!"Reached end of function we should never hit");
+}
+
+void path_policy_show_debugging(struct vty *vty)
+{
+ if (DEBUG_FLAGS_CHECK(&path_policy_debug, PATH_POLICY_DEBUG_BASIC))
+ vty_out(vty, " Path policy debugging is on\n");
}
void pathd_shutdown(void)
from changing the candidate by hand with the console */
if (candidate->hook_timer != NULL)
return;
- thread_add_timer(master, trigger_pathd_candidate_created_timer,
- (void *)candidate, HOOK_DELAY, &candidate->hook_timer);
+ event_add_timer(master, trigger_pathd_candidate_created_timer,
+ (void *)candidate, HOOK_DELAY, &candidate->hook_timer);
}
-void trigger_pathd_candidate_created_timer(struct thread *thread)
+void trigger_pathd_candidate_created_timer(struct event *thread)
{
struct srte_candidate *candidate = THREAD_ARG(thread);
candidate->hook_timer = NULL;
from changing the candidate by hand with the console */
if (candidate->hook_timer != NULL)
return;
- thread_add_timer(master, trigger_pathd_candidate_updated_timer,
- (void *)candidate, HOOK_DELAY, &candidate->hook_timer);
+ event_add_timer(master, trigger_pathd_candidate_updated_timer,
+ (void *)candidate, HOOK_DELAY, &candidate->hook_timer);
}
-void trigger_pathd_candidate_updated_timer(struct thread *thread)
+void trigger_pathd_candidate_updated_timer(struct event *thread)
{
struct srte_candidate *candidate = THREAD_ARG(thread);
candidate->hook_timer = NULL;
/* The hook needs to be call synchronously, otherwise the candidate
path will be already deleted when the handler is called */
if (candidate->hook_timer != NULL) {
- thread_cancel(&candidate->hook_timer);
+ event_cancel(&candidate->hook_timer);
candidate->hook_timer = NULL;
}
hook_call(pathd_candidate_removed, candidate);
zlog_warn(" %s: PATHD-TED: SL: ERROR query C : ted-sid (%d)",
__func__, ted_sid);
} else {
- zlog_debug("%s: PATHD-TED: SL: Success query C : ted-sid (%d)",
- __func__, ted_sid);
+ PATH_TED_DEBUG(
+ "%s: PATHD-TED: SL: Success query C : ted-sid (%d)",
+ __func__, ted_sid);
}
if (CHECK_SID(entry->segment_list->protocol_origin, ted_sid,
entry->sid_value)) {
zlog_warn(" %s: PATHD-TED: SL: ERROR query E : ted-sid (%d)",
__func__, ted_sid);
} else {
- zlog_debug("%s: PATHD-TED: SL: Success query E : ted-sid (%d)",
- __func__, ted_sid);
+ PATH_TED_DEBUG(
+ "%s: PATHD-TED: SL: Success query E : ted-sid (%d)",
+ __func__, ted_sid);
}
if (CHECK_SID(entry->segment_list->protocol_origin, ted_sid,
entry->sid_value)) {
zlog_warn("%s:SL: ERROR query F : ted-sid (%d)", __func__,
ted_sid);
} else {
- zlog_debug("%s:SL: Success query F : ted-sid (%d)", __func__,
- ted_sid);
+ PATH_TED_DEBUG("%s:SL: Success query F : ted-sid (%d)",
+ __func__, ted_sid);
}
if (CHECK_SID(entry->segment_list->protocol_origin, ted_sid,
entry->sid_value)) {