#define CONFIG_NO 1
#define CONFIG_YES 2
-/* babeld interface informations */
+/* babeld interface information */
struct babel_interface {
unsigned short flags; /* see below */
unsigned short cost;
vty_out (vty,
"state file = %s\n"
"configuration file = %s\n"
- "protocol informations:\n"
+ "protocol information:\n"
" multicast address = %s\n"
" port = %d\n"
"vty address = %s\n"
* - for consistency in rx processing
*
* The following comment is to signal GCC this intention
- * and supress the warning
+ * and suppress the warning
*/
/* FALLTHRU */
case BGP_ATTR_NHLEN_IPV4:
return ret;
}
- /* If hard error occured immediately return to the caller. */
+ /* If hard error occurred immediately return to the caller. */
if (ret == BGP_ATTR_PARSE_ERROR) {
flog_warn(EC_BGP_ATTRIBUTE_PARSE_ERROR,
"%s: Attribute %s, parse error", peer->host,
vty_out(vty, "Suppress penalty: %d\n", damp->suppress_value);
vty_out(vty, "Max suppress time: %lld min\n",
(long long)damp->max_suppress_time / 60);
- vty_out(vty, "Max supress penalty: %u\n", damp->ceiling);
+ vty_out(vty, "Max suppress penalty: %u\n", damp->ceiling);
vty_out(vty, "\n");
} else
vty_out(vty, "dampening not enabled for %s\n",
},
{
.code = EC_BGP_CAPABILITY_VENDOR,
- .title = "BGP has recieved capability data specific to a particular vendor",
+ .title = "BGP has received capability data specific to a particular vendor",
.description = "BGP has received a capability that is vendor specific and as such we have no knowledge of how to use this capability in FRR",
.suggestion = "On peer turn off this feature"
},
.code = EC_BGP_ATTR_FLAG,
.title = "BGP attribute flag is incorrect",
.description = "BGP attribute flag is set to the wrong value (Optional/Transitive/Partial)",
- .suggestion = "Determine the soure of the attribute and determine why the attribute flag has been set incorrectly"
+ .suggestion = "Determine the source of the attribute and determine why the attribute flag has been set incorrectly"
},
{
.code = EC_BGP_ATTR_LEN,
.title = "BGP attribute length is incorrect",
.description = "BGP attribute length is incorrect",
- .suggestion = "Determine the soure of the attribute and determine why the attribute length has been set incorrectly"
+ .suggestion = "Determine the source of the attribute and determine why the attribute length has been set incorrectly"
},
{
.code = EC_BGP_ATTR_ORIGIN,
.title = "BGP attribute origin value invalid",
.description = "BGP attribute origin value is invalid",
- .suggestion = "Determine the soure of the attribute and determine why the origin attribute has been set incorrectly"
+ .suggestion = "Determine the source of the attribute and determine why the origin attribute has been set incorrectly"
},
{
.code = EC_BGP_ATTR_MAL_AS_PATH,
.title = "BGP as path is invalid",
.description = "BGP as path has been malformed",
- .suggestion = "Determine the soure of the update and determine why the as path has been set incorrectly"
+ .suggestion = "Determine the source of the update and determine why the as path has been set incorrectly"
},
{
.code = EC_BGP_ATTR_FIRST_AS,
.title = "BGP as path first as is invalid",
.description = "BGP update has invalid first as in as path",
- .suggestion = "Determine the soure of the update and determine why the as path first as value has been set incorrectly"
+ .suggestion = "Determine the source of the update and determine why the as path first as value has been set incorrectly"
},
{
.code = EC_BGP_ATTR_PMSI_TYPE,
.title = "BGP PMSI tunnel attribute type is invalid",
.description = "BGP update has invalid type for PMSI tunnel",
- .suggestion = "Determine the soure of the update and determine why the PMSI tunnel attribute type has been set incorrectly"
+ .suggestion = "Determine the source of the update and determine why the PMSI tunnel attribute type has been set incorrectly"
},
{
.code = EC_BGP_ATTR_PMSI_LEN,
.title = "BGP PMSI tunnel attribute length is invalid",
.description = "BGP update has invalid length for PMSI tunnel",
- .suggestion = "Determine the soure of the update and determine why the PMSI tunnel attribute length has been set incorrectly"
+ .suggestion = "Determine the source of the update and determine why the PMSI tunnel attribute length has been set incorrectly"
},
{
.code = EC_BGP_PEER_GROUP,
.code = EC_BGP_JSON_MEM_ERROR,
.title = "BGP unable to allocate memory for JSON output",
.description = "BGP attempted to generate JSON output and was unable to allocate the memory required",
- .suggestion = "Ensure that the device has adequate memory to suport the required functions"
+ .suggestion = "Ensure that the device has adequate memory to support the required functions"
},
{
.code = EC_BGP_UPDGRP_ATTR_LEN,
}
/*
- * create a new route entry if one doesnt exist.
+ * create a new route entry if one doesn't exist.
* Otherwise see if route attr has changed
*/
if (!local_pi) {
}
as = bgp_def->as;
- /* if the BGP vrf instance doesnt exist - create one */
+ /* if the BGP vrf instance doesn't exist - create one */
bgp_vrf = bgp_lookup_by_name(vrf_id_to_name(vrf_id));
if (!bgp_vrf) {
}
if (!bgp->peer_self) {
- vty_out(vty, "%%BGP instance doesnt have self peer\n");
+ vty_out(vty, "%%BGP instance doesn't have self peer\n");
return CMD_WARNING;
}
}
}
-/* Called after event occured, this function change status and reset
+/* Called after event occurred, this function change status and reset
read/write and timer thread. */
void bgp_fsm_change_status(struct peer *peer, int status)
{
PEER_STATUS_EOR_RECEIVED)) {
if (bgp_debug_neighbor_events(peer))
zlog_debug(
- " afi %d safi %d didnt receive EOR",
+ " afi %d safi %d didn't receive EOR",
afi, safi);
return;
}
unsigned long output_count = 0;
unsigned long total_count = 0;
struct prefix *p;
- char buf[BUFSIZ];
char buf2[BUFSIZ];
json_object *json_paths = NULL;
int first = 1;
continue;
p = &rn->p;
- sprintf(buf2, "%s/%d",
- inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
- p->prefixlen);
- if (first)
- vty_out(vty, "\"%s\": ", buf2);
- else
- vty_out(vty, ",\"%s\": ", buf2);
-
+ /* encode prefix */
+ if (p->family == AF_FLOWSPEC) {
+ char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
+
+ bgp_fs_nlri_get_string((unsigned char *)
+ p->u.prefix_flowspec.ptr,
+ p->u.prefix_flowspec
+ .prefixlen,
+ retstr,
+ NLRI_STRING_FORMAT_MIN,
+ NULL);
+ if (first)
+ vty_out(vty, "\"%s/%d\": ",
+ retstr,
+ p->u.prefix_flowspec.prefixlen);
+ else
+ vty_out(vty, ",\"%s/%d\": ",
+ retstr,
+ p->u.prefix_flowspec.prefixlen);
+ } else {
+ prefix2str(p, buf2, sizeof(buf2));
+ if (first)
+ vty_out(vty, "\"%s\": ", buf2);
+ else
+ vty_out(vty, ",\"%s\": ", buf2);
+ }
vty_out(vty, "%s",
json_object_to_json_string(json_paths));
json_object_free(json_paths);
{
struct bgp *bgp;
struct attr attr;
- struct bgp_path_info *info, init_info, tmp_info;
+ struct aspath *aspath;
+ struct bgp_path_info tmp_info;
struct prefix p;
struct peer *from;
struct bgp_node *rn;
from = bgp->peer_self;
bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
+ aspath = attr.aspath;
+
attr.local_pref = bgp->default_local_pref;
+ memset(&p, 0, sizeof(p));
+ p.family = afi2family(afi);
+ p.prefixlen = 0;
+
if ((afi == AFI_IP6) || peer_cap_enhe(peer, afi, safi)) {
- /* IPv6 global nexthop must be included.
- */
+ /* IPv6 global nexthop must be included. */
attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
- /* If the peer is on shared nextwork and
- * we have link-local nexthop set it. */
+ /* If the peer is on shared nextwork and we have link-local
+ nexthop set it. */
if (peer->shared_network
&& !IN6_IS_ADDR_UNSPECIFIED(&peer->nexthop.v6_local))
attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
}
- init_info.attr = &attr;
- info = &init_info;
- bgp_attr_intern(info->attr);
-
- memset(&p, 0, sizeof(p));
- p.family = afi2family(afi);
- p.prefixlen = 0;
if (peer->default_rmap[afi][safi].name) {
SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_DEFAULT);
for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
rn = bgp_route_next(rn)) {
for (ri = rn->info; ri; ri = ri->next) {
+ struct attr dummy_attr;
+
+ /* Provide dummy so the route-map can't modify
+ * the attributes */
+ bgp_attr_dup(&dummy_attr, ri->attr);
tmp_info.peer = ri->peer;
- tmp_info.attr = ri->attr;
-
- /* Reset attributes every time to avoid \
- * unexpected as-path prepends */
- bgp_attr_default_set(tmp_info.attr,
- BGP_ORIGIN_IGP);
-
- if ((afi == AFI_IP6)
- || peer_cap_enhe(peer, afi, safi)) {
- tmp_info.attr->mp_nexthop_len =
- BGP_ATTR_NHLEN_IPV6_GLOBAL;
-
- if (peer->shared_network
- && !IN6_IS_ADDR_UNSPECIFIED(
- &peer->nexthop.v6_local))
- tmp_info.attr->mp_nexthop_len =
- BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
- }
+ tmp_info.attr = &dummy_attr;
ret = route_map_apply(
peer->default_rmap[afi][safi].map,
&rn->p, RMAP_BGP, &tmp_info);
- info = &tmp_info;
- bgp_attr_intern(info->attr);
-
+ /* The route map might have set attributes. If
+ * we don't flush them
+ * here, they will be leaked. */
+ bgp_attr_flush(&dummy_attr);
if (ret != RMAP_DENYMATCH)
break;
}
SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
- bgp_attr_add_gshut_community(info->attr);
+ bgp_attr_add_gshut_community(&attr);
}
SET_FLAG(subgrp->sflags,
SUBGRP_STATUS_DEFAULT_ORIGINATE);
- subgroup_default_update_packet(subgrp, info->attr,
- from);
+ subgroup_default_update_packet(subgrp, &attr, from);
/* The 'neighbor x.x.x.x default-originate' default will
* act as an
BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE);
}
}
- aspath_unintern(&info->attr->aspath);
+
+ aspath_unintern(&aspath);
}
/*
snprintf(tx_id_buf, sizeof(tx_id_buf),
" with addpath ID %u",
BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE);
+ else
+ tx_id_buf[0] = '\0';
zlog_debug("u%" PRIu64 ":s%" PRIu64 " send UPDATE %s%s %s",
(SUBGRP_UPDGRP(subgrp))->id, subgrp->id,
"bgp default show-hostname",
"BGP specific commands\n"
"Configure BGP defaults\n"
- "Show hostname in certain command ouputs\n")
+ "Show hostname in certain command outputs\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_set(bgp, BGP_FLAG_SHOW_HOSTNAME);
NO_STR
"BGP specific commands\n"
"Configure BGP defaults\n"
- "Show hostname in certain command ouputs\n")
+ "Show hostname in certain command outputs\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_unset(bgp, BGP_FLAG_SHOW_HOSTNAME);
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"Accept as-path with my AS present in it\n"
- "Number of occurances of AS number\n"
+ "Number of occurences of AS number\n"
"Only accept my AS in the as-path if the route was originated in my AS\n")
{
int idx_peer = 1;
"neighbor <A.B.C.D|X:X::X:X|WORD> allowas-in [<(1-10)|origin>]",
NEIGHBOR_STR NEIGHBOR_ADDR_STR2
"Accept as-path with my AS present in it\n"
- "Number of occurances of AS number\n"
+ "Number of occurences of AS number\n"
"Only accept my AS in the as-path if the route was originated in my AS\n")
DEFUN (no_neighbor_allowas_in,
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
"allow local ASN appears in aspath attribute\n"
- "Number of occurances of AS number\n"
+ "Number of occurences of AS number\n"
"Only accept my AS in the as-path if the route was originated in my AS\n")
{
int idx_peer = 2;
"no neighbor <A.B.C.D|X:X::X:X|WORD> allowas-in [<(1-10)|origin>]",
NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
"allow local ASN appears in aspath attribute\n"
- "Number of occurances of AS number\n"
+ "Number of occurences of AS number\n"
"Only accept my AS in the as-path if the route was originated in my AS\n")
DEFUN (neighbor_ttl_security,
json_object_string_add(
json_nxt,
print_store,
- "recieved");
+ "received");
}
}
json_object_object_add(
json_object_object_add(
json_neigh, "gracefulRestartInfo", json_grace);
} else {
- vty_out(vty, " Graceful restart informations:\n");
+ vty_out(vty, " Graceful restart information:\n");
if (p->status == Established) {
vty_out(vty, " End-of-RIB send: ");
FOREACH_AFI_SAFI (afi, safi) {
# open, as well as the daemons, so always signal the daemons.
# It's safe, a NOP if (only) syslog is being used.
for i in babeld bgpd eigrpd isisd ldpd nhrpd ospf6d ospfd \
- pimd ripd ripngd zebra staticd ; do
+ pimd ripd ripngd zebra staticd fabricd; do
if [ -e /var/run/frr/$i.pid ] ; then
pids="$pids $(cat /var/run/frr/$i.pid)"
fi
doc/manpages/_build/man/isisd.8
doc/manpages/_build/man/watchfrr.8
doc/manpages/_build/man/mtracebis.8
+doc/manpages/_build/man/fabricd.8
# modify config file to enable all daemons and copy config files
CONFIG_FILE=/etc/frr/daemons
-DAEMONS=("zebra" "bgpd" "ospfd" "ospf6d" "ripd" "ripngd" "isisd" "pimd")
+DAEMONS=("zebra" "bgpd" "ospfd" "ospf6d" "ripd" "ripngd" "isisd" "pimd" "fabricd")
for daemon in "${DAEMONS[@]}"
do
NB: Unlike the other options, this option specifies a directory, not a full path.
- This option is primarily used by the SNAP packaging system, its semantics may change. It should not be neccessary in most other scenarios.
+ This option is primarily used by the SNAP packaging system, its semantics may change. It should not be necessary in most other scenarios.
MODULE LOADING
--------------
Set netlink receive buffer size. There are cases where zebra daemon can't handle flood of netlink messages from kernel. If you ever see "recvmsg overrun" messages in zebra log, you are in trouble.
- Solution is to increase receive buffer of netlink socket. Note that kernel < 2.6.14 doesn't allow to increase it over maximum value defined in /proc/sys/net/core/rmem_max. If you want to do it, you have to increase maximum before starting zebra.
+ Solution is to increase receive buffer of netlink socket. Note that kernel < 2.6.14 doesn't allow increasing it over maximum value defined in /proc/sys/net/core/rmem_max. If you want to do it, you have to increase maximum before starting zebra.
Note that this affects Linux only.
enum eigrp_fsm_events {
/*
* Input event other than query from succ,
- * FC is not satisified
+ * FC is not satisfied
*/
EIGRP_FSM_EVENT_NQ_FCN,
/* Query from succ while in active state */
EIGRP_FSM_EVENT_QACT,
- /* last reply, FC not satisified */
+ /* last reply, FC not satisfied */
EIGRP_FSM_EVENT_LR_FCN,
/*
"Un/reliable mcasts: ", 0, "/", 0, "Un/reliable ucasts: ", 0,
"/", 0);
vty_out(vty, "%-2s %s %d %s %d %s %d \n", "", "Mcast exceptions: ", 0,
- " CR packets: ", 0, " ACKs supressed: ", 0);
+ " CR packets: ", 0, " ACKs suppressed: ", 0);
vty_out(vty, "%-2s %s %d %s %d \n", "", "Retransmissions sent: ", 0,
"Out-of-sequence rcvd: ", 0);
vty_out(vty, "%-2s %s %s %s \n", "", "Authentication mode is ", "not",
case EIGRP_FSM_EVENT_LR:
return "Last Reply Event";
case EIGRP_FSM_EVENT_Q_FCN:
- return "Query Event Feasability not satisified";
+ return "Query Event Feasability not satisfied";
case EIGRP_FSM_EVENT_LR_FCS:
- return "Last Reply Event Feasability satisified";
+ return "Last Reply Event Feasability satisfied";
case EIGRP_FSM_EVENT_DINC:
return "Distance Increase Event";
case EIGRP_FSM_EVENT_QACT:
#include "isisd/fabricd.h"
#include "isisd/isis_tx_queue.h"
-static int lsp_l1_refresh(struct thread *thread);
-static int lsp_l2_refresh(struct thread *thread);
+static int lsp_refresh(struct thread *thread);
static int lsp_l1_refresh_pseudo(struct thread *thread);
static int lsp_l2_refresh_pseudo(struct thread *thread);
THREAD_TIMER_OFF(area->t_lsp_refresh[level - 1]);
area->lsp_regenerate_pending[level - 1] = 0;
- if (level == IS_LEVEL_1)
- thread_add_timer(master, lsp_l1_refresh, area, refresh_time,
- &area->t_lsp_refresh[level - 1]);
- else if (level == IS_LEVEL_2)
- thread_add_timer(master, lsp_l2_refresh, area, refresh_time,
- &area->t_lsp_refresh[level - 1]);
+ thread_add_timer(master, lsp_refresh,
+ &area->lsp_refresh_arg[level - 1], refresh_time,
+ &area->t_lsp_refresh[level - 1]);
if (isis->debugs & DEBUG_UPDATE_PACKETS) {
zlog_debug("ISIS-Upd (%s): Building L%d LSP %s, len %" PRIu16
lsp_seqno_update(lsp);
refresh_time = lsp_refresh_time(lsp, rem_lifetime);
- if (level == IS_LEVEL_1)
- thread_add_timer(master, lsp_l1_refresh, area, refresh_time,
- &area->t_lsp_refresh[level - 1]);
- else if (level == IS_LEVEL_2)
- thread_add_timer(master, lsp_l2_refresh, area, refresh_time,
- &area->t_lsp_refresh[level - 1]);
+ thread_add_timer(master, lsp_refresh,
+ &area->lsp_refresh_arg[level - 1], refresh_time,
+ &area->t_lsp_refresh[level - 1]);
area->lsp_regenerate_pending[level - 1] = 0;
if (isis->debugs & DEBUG_UPDATE_PACKETS) {
/*
* Something has changed or periodic refresh -> regenerate LSP
*/
-static int lsp_l1_refresh(struct thread *thread)
+static int lsp_refresh(struct thread *thread)
{
- struct isis_area *area;
+ struct lsp_refresh_arg *arg = THREAD_ARG(thread);
- area = THREAD_ARG(thread);
- assert(area);
-
- area->t_lsp_refresh[0] = NULL;
- area->lsp_regenerate_pending[0] = 0;
-
- if ((area->is_type & IS_LEVEL_1) == 0)
- return ISIS_ERROR;
-
- sched_debug(
- "ISIS (%s): LSP L1 refresh timer expired. Refreshing LSP...",
- area->area_tag);
- return lsp_regenerate(area, IS_LEVEL_1);
-}
+ assert(arg);
-static int lsp_l2_refresh(struct thread *thread)
-{
- struct isis_area *area;
+ struct isis_area *area = arg->area;
- area = THREAD_ARG(thread);
assert(area);
- area->t_lsp_refresh[1] = NULL;
- area->lsp_regenerate_pending[1] = 0;
+ int level = arg->level;
- if ((area->is_type & IS_LEVEL_2) == 0)
+ area->t_lsp_refresh[level - 1] = NULL;
+ area->lsp_regenerate_pending[level - 1] = 0;
+
+ if ((area->is_type & level) == 0)
return ISIS_ERROR;
+ if (monotime_since(&area->last_lsp_refresh_event[level - 1], NULL) < 50000L) {
+ sched_debug("ISIS (%s): Still unstable, postpone LSP L%d refresh",
+ area->area_tag, level);
+ _lsp_regenerate_schedule(area, level, 0, false,
+ __func__, __FILE__, __LINE__);
+ return 0;
+ }
+
sched_debug(
- "ISIS (%s): LSP L2 refresh timer expired. Refreshing LSP...",
- area->area_tag);
- return lsp_regenerate(area, IS_LEVEL_2);
+ "ISIS (%s): LSP L%d refresh timer expired. Refreshing LSP...",
+ area->area_tag, level);
+ return lsp_regenerate(area, level);
}
-int lsp_regenerate_schedule(struct isis_area *area, int level, int all_pseudo)
+int _lsp_regenerate_schedule(struct isis_area *area, int level,
+ int all_pseudo, bool postpone,
+ const char *func, const char *file,
+ int line)
{
struct isis_lsp *lsp;
uint8_t id[ISIS_SYS_ID_LEN + 2];
return ISIS_ERROR;
sched_debug(
- "ISIS (%s): Scheduling regeneration of %s LSPs, %sincluding PSNs",
+ "ISIS (%s): Scheduling regeneration of %s LSPs, %sincluding PSNs"
+ " Caller: %s %s:%d",
area->area_tag, circuit_t2string(level),
- all_pseudo ? "" : "not ");
+ all_pseudo ? "" : "not ",
+ func, file, line);
memcpy(id, isis->sysid, ISIS_SYS_ID_LEN);
LSP_PSEUDO_ID(id) = LSP_FRAGMENT(id) = 0;
if (!((level & lvl) && (area->is_type & lvl)))
continue;
+ if (postpone) {
+ monotime(&area->last_lsp_refresh_event[lvl - 1]);
+ }
+
sched_debug(
"ISIS (%s): Checking whether L%d needs to be scheduled",
area->area_tag, lvl);
}
area->lsp_regenerate_pending[lvl - 1] = 1;
- if (lvl == IS_LEVEL_1) {
- thread_add_timer_msec(master, lsp_l1_refresh, area,
- timeout,
- &area->t_lsp_refresh[lvl - 1]);
- } else if (lvl == IS_LEVEL_2) {
- thread_add_timer_msec(master, lsp_l2_refresh, area,
- timeout,
- &area->t_lsp_refresh[lvl - 1]);
- }
+ thread_add_timer_msec(master, lsp_refresh,
+ &area->lsp_refresh_arg[lvl - 1],
+ timeout,
+ &area->t_lsp_refresh[lvl - 1]);
}
if (all_pseudo) {
int lsp_tick(struct thread *thread);
int lsp_generate(struct isis_area *area, int level);
-int lsp_regenerate_schedule(struct isis_area *area, int level, int all_pseudo);
+#define lsp_regenerate_schedule(area, level, all_pseudo) \
+ _lsp_regenerate_schedule((area), (level), (all_pseudo), true, \
+ __func__, __FILE__, __LINE__)
+int _lsp_regenerate_schedule(struct isis_area *area, int level,
+ int all_pseudo, bool postpone,
+ const char *func, const char *file, int line);
int lsp_generate_pseudo(struct isis_circuit *circuit, int level);
int lsp_regenerate_schedule_pseudo(struct isis_circuit *circuit, int level);
case ISIS_SYSTYPE_UNKNOWN:
default:
zlog_warn(
- "isis_spf_preload_tent unknow adj type");
+ "isis_spf_preload_tent unknown adj type");
}
}
list_delete(&adj_list);
return run;
}
-int isis_spf_schedule(struct isis_area *area, int level)
+int _isis_spf_schedule(struct isis_area *area, int level,
+ const char *func, const char *file, int line)
{
struct isis_spftree *spftree = area->spftree[SPFTREE_IPV4][level - 1];
time_t now = monotime(NULL);
assert(diff >= 0);
assert(area->is_type & level);
- if (isis->debugs & DEBUG_SPF_EVENTS)
+ if (isis->debugs & DEBUG_SPF_EVENTS) {
zlog_debug(
- "ISIS-Spf (%s) L%d SPF schedule called, lastrun %d sec ago",
- area->area_tag, level, diff);
+ "ISIS-Spf (%s) L%d SPF schedule called, lastrun %d sec ago"
+ " Caller: %s %s:%d",
+ area->area_tag, level, diff, func, file, line);
+ }
if (area->spf_delay_ietf[level - 1]) {
/* Need to call schedule function also if spf delay is running
void spftree_area_init(struct isis_area *area);
void spftree_area_del(struct isis_area *area);
void spftree_area_adj_del(struct isis_area *area, struct isis_adjacency *adj);
-int isis_spf_schedule(struct isis_area *area, int level);
+#define isis_spf_schedule(area, level) \
+ _isis_spf_schedule((area), (level), __func__, \
+ __FILE__, __LINE__)
+int _isis_spf_schedule(struct isis_area *area, int level,
+ const char *func, const char *file, int line);
void isis_spf_cmds_init(void);
void isis_spf_print(struct isis_spftree *spftree, struct vty *vty);
struct isis_spftree *isis_run_hopcount_spf(struct isis_area *area,
if (fabricd)
area->fabricd = fabricd_new(area);
+
+ area->lsp_refresh_arg[0].area = area;
+ area->lsp_refresh_arg[0].level = IS_LEVEL_1;
+ area->lsp_refresh_arg[1].area = area;
+ area->lsp_refresh_arg[1].level = IS_LEVEL_2;
+
+
QOBJ_REG(area, isis_area);
return area;
SPFTREE_COUNT
};
+struct lsp_refresh_arg {
+ struct isis_area *area;
+ int level;
+};
+
struct isis_area {
struct isis *isis; /* back pointer */
dict_t *lspdb[ISIS_LEVELS]; /* link-state dbs */
struct flags flags;
struct thread *t_tick; /* LSP walker */
struct thread *t_lsp_refresh[ISIS_LEVELS];
+ struct timeval last_lsp_refresh_event[ISIS_LEVELS];
/* t_lsp_refresh is used in two ways:
* a) regular refresh of LSPs
* b) (possibly throttled) updates to LSPs
parameters*/
struct thread *spf_timer[ISIS_LEVELS];
+ struct lsp_refresh_arg lsp_refresh_arg[ISIS_LEVELS];
+
QOBJ_FIELDS
};
DECLARE_QOBJ_TYPE(isis_area)
NO_STR
"Configure dual stack parameters\n"
"Configure TCP transport parameters\n"
- "Configure prefered address family for TCP transport connection with neighbor\n"
+ "Configure preferred address family for TCP transport connection with neighbor\n"
"IPv4\n")
{
return (ldp_vty_trans_pref_ipv4(vty, no));
if (IN6_IS_SCOPE_EMBED(&sin6->sin6_addr)) {
memcpy(&tmp16, &sin6->sin6_addr.s6_addr[2], sizeof(tmp16));
if (tmp16 != 0) {
- log_warnx("%s: address %s already has embeded scope %u",
+ log_warnx("%s: address %s already has embedded scope %u",
__func__, log_sockaddr(sin6), ntohs(tmp16));
}
tmp16 = htons(sin6->sin6_scope_id);
int ret;
int len;
- /* Individual reg/dereg messages are supressed during shutdown. */
+ /* Individual reg/dereg messages are suppressed during shutdown. */
if (CHECK_FLAG(bfd_gbl.flags, BFD_GBL_FLAG_IN_SHUTDOWN)) {
if (bfd_debug)
zlog_debug(
}
}
- if (ret != CMD_SUCCESS && ret != CMD_WARNING) {
+ if (ret != CMD_SUCCESS &&
+ ret != CMD_WARNING &&
+ ret != CMD_SUCCESS_DAEMON) {
struct vty_error *ve = XCALLOC(MTYPE_TMP, sizeof(*ve));
memcpy(ve->error_buf, vty->buf, VTY_BUFSIZ);
#define IN_STR "Filter incoming routing updates\n"
#define V4NOTATION_STR "specify by IPv4 address notation(e.g. 0.0.0.0)\n"
#define OSPF6_NUMBER_STR "Specify by number\n"
-#define INTERFACE_STR "Interface infomation\n"
+#define INTERFACE_STR "Interface information\n"
#define IFNAME_STR "Interface name(e.g. ep0)\n"
#define IP6_STR "IPv6 Information\n"
#define OSPF6_STR "Open Shortest Path First (OSPF) for IPv6\n"
{
.code = EC_LIB_SOCKET,
.title = "Socket Error",
- .description = "When attempting to access a socket a system error has occured and we were unable to properly complete the request",
- .suggestion = "Ensure that there are sufficient system resources available and ensure that the frr user has sufficient permisions to work. If necessary open an Issue",
+ .description = "When attempting to access a socket a system error has occurred and we were unable to properly complete the request",
+ .suggestion = "Ensure that there are sufficient system resources available and ensure that the frr user has sufficient permissions to work. If necessary open an Issue",
},
{
.code = EC_LIB_ZAPI_MISSMATCH,
strlcpy(buf, "Router Alert", len);
return (buf);
case MPLS_LABEL_IPV6_EXPLICIT_NULL:
- strlcpy(buf, "IPv6 Explict Null", len);
+ strlcpy(buf, "IPv6 Explicit Null", len);
return (buf);
case MPLS_LABEL_IMPLICIT_NULL:
strlcpy(buf, "implicit-null", len);
* Which on linux is a no-op since it is enabled by
* default and on BSD it uses TCP_NOPUSH to do
* the same thing( which it was not configured to
- * use). This cleanup of the api occured on 8/1/17
+ * use). This cleanup of the api occurred on 8/1/17
* I imagine if after more than 1 year of no-one
* complaining, and a major upgrade release we
* can deprecate and remove this function call
# another object file.
#
# There are four known schemes of declaring weak symbols; each scheme is
-# checked in turn, and the first one found is prefered. Note that only one
+# checked in turn, and the first one found is preferred. Note that only one
# of the mentioned preprocessor macros will be defined!
#
# 1. Function attributes
/* if this is a route to ASBR */
if (route->type == OSPF6_DEST_TYPE_ROUTER) {
- /* Only the prefered best path is considered */
+ /* Only the preferred best path is considered */
if (!CHECK_FLAG(route->flag, OSPF6_ROUTE_BEST)) {
if (is_debug)
zlog_debug(
SHOW_STR
IP6_STR
OSPF6_STR
- "Shortest Path First caculation\n"
+ "Shortest Path First calculation\n"
"Show SPF tree\n")
{
struct listnode *node;
OSPF6_STR
OSPF6_AREA_STR
OSPF6_AREA_ID_STR
- "Shortest Path First caculation\n"
+ "Shortest Path First calculation\n"
"Show SPF tree\n")
{
int idx_ipv4 = 4;
return 0;
}
-/* Hook function called after ospf ISM event is occured. And vty's
+/* Hook function called after ospf ISM event is occurred. And vty's
network command invoke this function after making interface
structure. */
static void ism_timer_set(struct ospf_interface *oi)
return 0;
}
-/* Hook function called after ospf NSM event is occured.
+/* Hook function called after ospf NSM event is occurred.
*
* Set/clear any timers whose condition is implicit to the neighbour
* state. There may be other timers which are set/unset according to other
/* Collection of callback functions for this opaque-type. */
struct ospf_opaque_functab *functab;
- /* List of Opaque-LSA control informations per opaque-id. */
+ /* List of Opaque-LSA control information per opaque-id. */
struct list *id_list;
};
if (IS_OPAQUE_LSA(lsa->data->type)
&& (!CHECK_FLAG(options, OSPF_OPTION_O))) {
/* Suppress advertising
- * opaque-informations. */
+ * opaque-information. */
/* Remove LSA from DB summary list. */
ospf_lsdb_delete(lsdb, lsa);
continue;
* @param enable To activate or not Segment Routing router Information flooding
* @param size Size of Label Range i.e. SRGB size
* @param lower Lower bound of the Label Range i.e. SRGB first label
- * @param msd Maximum label Stack Depth suported by the router
+ * @param msd Maximum label Stack Depth supported by the router
*
* @return none
*/
ospf_mpls_te_lsa_schedule(lp, FLUSH_THIS_LSA);
}
- /* Deregister the Callbacks for Inter-AS suport */
+ /* Deregister the Callbacks for Inter-AS support */
ospf_mpls_te_unregister();
return CMD_SUCCESS;
/* Flush (inline) all external LSAs which now match the new
router-id,
- need to adjust the OSPF_LSA_SELF flag, so the flush doesnt
+ need to adjust the OSPF_LSA_SELF flag, so the flush doesn't
hit
asserts in ospf_refresher_unregister_lsa(). This step is
needed
switch (note) {
case ZAPI_RULE_FAIL_INSTALL:
- DEBUGD(&pbr_dbg_zebra, "%s: Recieved RULE_FAIL_INSTALL",
+ DEBUGD(&pbr_dbg_zebra, "%s: Received RULE_FAIL_INSTALL",
__PRETTY_FUNCTION__);
pbrms->installed &= ~installed;
break;
case ZAPI_RULE_INSTALLED:
pbrms->installed |= installed;
- DEBUGD(&pbr_dbg_zebra, "%s: Recived RULE_INSTALLED",
+ DEBUGD(&pbr_dbg_zebra, "%s: Received RULE_INSTALLED",
__PRETTY_FUNCTION__);
break;
case ZAPI_RULE_FAIL_REMOVE:
pim_global_config_write_worker(pim, vty);
if (vrf->vrf_id != VRF_DEFAULT)
- vty_endframe(vty, "!\n");
+ vty_endframe(vty, " exit-vrf\n!\n");
}
return 0;
struct pim_instance *pim = THREAD_ARG(t);
if (PIM_DEBUG_MSDP_EVENTS) {
- zlog_debug("MSDP SA advertisment timer expired");
+ zlog_debug("MSDP SA advertisement timer expired");
}
pim_msdp_sa_adv_timer_setup(pim, true /* start */);
return 0;
}
-/* Source registration is supressed for SSM groups. When the SSM range changes
+/* Source registration is suppressed for SSM groups. When the SSM range changes
* we re-revaluate register setup for existing upstream entries */
void pim_upstream_register_reevaluate(struct pim_instance *pim)
{
Ciscos before the 'ip subnet zero' option, it would be almost
right too :-)
- Cisco summarize ripv1 advertisments to the classful boundary
+ Cisco summarize ripv1 advertisements to the classful boundary
(/16 for class B's) except when the RIP packet does to inside
the classful network in question. */
VRF_DEFAULT);
if (!connected) {
zlog_warn(
- "Neighbor %s doesnt have connected interface!",
+ "Neighbor %s doesn't have connected interface!",
inet_ntoa(p->u.prefix4));
continue;
}
&& rinfo->suppress == 0) {
/* If no route-map are applied, the RTE will be these
* following
- * informations.
+ * information.
*/
p = (struct prefix_ipv6 *)&rp->p;
rinfo->metric_out = rinfo->metric;
&& aggregate->suppress == 0) {
/* If no route-map are applied, the RTE will be these
* following
- * informations.
+ * information.
*/
p = (struct prefix_ipv6 *)&rp->p;
aggregate->metric_set = 0;
SAFI_UNICAST, "ipv6 route");
if (vrf->vrf_id != VRF_DEFAULT)
- vty_endframe(vty, "!\n");
+ vty_endframe(vty, " exit-vrf\n!\n");
}
return 0;
const char *dest_str, const char *mask_str, const char *src_str,
const char *gate_str, const char *ifname, const char *flag_str,
const char *tag_str, const char *distance_str, const char *label_str,
- const char *table_str)
+ const char *table_str, bool onlink)
{
struct static_hold_route *shr, *lookup;
struct listnode *node;
shr->nhvrf_name = XSTRDUP(MTYPE_STATIC_ROUTE, nh_svrf->vrf->name);
shr->afi = afi;
shr->safi = safi;
+ shr->onlink = onlink;
if (dest)
prefix_copy(&shr->dest, dest);
if (dest_str)
return zebra_static_route_holdem(
svrf, nh_svrf, afi, safi, negate, &p, dest_str,
mask_str, src_str, gate_str, ifname, flag_str, tag_str,
- distance_str, label_str, table_str);
+ distance_str, label_str, table_str, onlink);
}
if (table_str) {
if (shr->table_str)
vty_out(vty, "table %s", shr->table_str);
if (strcmp(shr->vrf_name, shr->nhvrf_name) != 0)
- vty_out(vty, "nexthop-vrf %s", shr->nhvrf_name);
+ vty_out(vty, "nexthop-vrf %s ", shr->nhvrf_name);
+ if (shr->onlink)
+ vty_out(vty, "onlink");
vty_out(vty, "\n");
}
svrf->vrf->data.l.table_id == RT_TABLE_MAIN)
vty_out(vty, " table %u", si->table_id);
+ if (si->onlink)
+ vty_out(vty, " onlink");
+
vty_out(vty, "\n");
write = 1;
sharpd=no
pbrd=no
bfdd=no
+fabricd=no
pbrd_options=" --daemon -A 127.0.0.1"
staticd_options=" --daemon -A 127.0.0.1"
bfdd_options=" --daemon -A 127.0.0.1"
+fabricd_options=" --daemon -A 127.0.0.1"
# The list of daemons to watch is automatically generated by the init script.
watchfrr_enable=yes
$programname == 'eigrpd' or
$programname == 'frr' or
$programname == 'isisd' or
+ $programname == 'fabricd' or
$programname == 'ldpd' or
$programname == 'nhrpd' or
$programname == 'ospf6d' or
$programname == 'eigrpd' or
$programname == 'frr' or
$programname == 'isisd' or
+ $programname == 'fabricd' or
$programname == 'ldpd' or
$programname == 'nhrpd' or
$programname == 'ospf6d' or
# Local Daemon selection may be done by using /etc/frr/daemons.
# See /usr/share/doc/frr/README.Debian.gz for further information.
# Keep zebra first and do not list watchfrr!
-DAEMONS="zebra bgpd ripd ripngd ospfd ospf6d isisd babeld pimd ldpd nhrpd eigrpd sharpd pbrd staticd bfdd"
+DAEMONS="zebra bgpd ripd ripngd ospfd ospf6d isisd babeld pimd ldpd nhrpd eigrpd sharpd pbrd staticd bfdd fabricd"
MAX_INSTANCES=5
RELOAD_SCRIPT="$D_PATH/frr-reload.py"
if (background) { /* ok, we need to detach this process */
int i, fd;
if (quietmode < 0)
- printf("Detatching to start %s...", startas);
+ printf("Detaching to start %s...", startas);
i = fork();
if (i < 0) {
fatal("Unable to fork.\n");
}
/*
- * I want to explicitly move this command to the end of the line
+ * Add a line that should only be shown once, and always show at the end of the
+ * config block.
+ *
+ * If the line already exists, it will be moved to the end of the block. If it
+ * does not exist, it will be added at the end of the block.
+ *
+ * Note that this only makes sense when there is just one such line that should
+ * show up at the very end of a config block. Furthermore, if the same block
+ * can show up from multiple daemons, all of them must make sure to print the
+ * line at the end of their config, otherwise the line will show at the end of
+ * the config for the last daemon that printed it.
+ *
+ * Here is a motivating example with the 'exit-vrf' command. Suppose we receive
+ * a config from Zebra like so:
+ *
+ * vrf BLUE
+ * ip route A
+ * ip route B
+ * exit-vrf
+ *
+ * Then suppose we later receive this config from PIM:
+ *
+ * vrf BLUE
+ * ip msdp mesh-group MyGroup member 1.2.3.4
+ * exit-vrf
+ *
+ * Then we will combine them into one config block like so:
+ *
+ * vrf BLUE
+ * ip route A
+ * ip route B
+ * ip msdp mesh-group MyGroup member 1.2.3.4
+ * exit-vrf
+ *
+ * Because PIM also sent us an 'exit-vrf', we noticed that we already had one
+ * under the 'vrf BLUE' config block and so we moved it to the end of the
+ * config block again. If PIM had neglected to send us 'exit-vrf', the result
+ * would be this:
+ *
+ * vrf BLUE
+ * ip route A
+ * ip route B
+ * exit-vrf
+ * ip msdp mesh-group MyGroup member 1.2.3.4
+ *
+ * Therefore, daemons that share config blocks must take care to consistently
+ * print the same block terminators.
+ *
+ * Ideally this would be solved by adding a string to struct config that is
+ * always printed at the end when dumping a config. However, this would only
+ * work when the user is using integrated config. In the non-integrated config
+ * case, daemons are responsible for writing their own config files, and so the
+ * must be able to print these blocks correctly independently of vtysh, which
+ * means they are the ones that need to handle printing the block terminators
+ * and VTYSH needs to be smart enough to combine them properly.
+ *
+ * ---
+ *
+ * config
+ * The config to add the line to
+ *
+ * line
+ * The line to add to the end of the config
*/
-static void config_add_line_end(struct list *config, const char *line)
+static void config_add_line_uniq_end(struct list *config, const char *line)
{
struct listnode *node;
- void *item = XSTRDUP(MTYPE_VTYSH_CONFIG_LINE, line);
+ char *pnt;
- listnode_add(config, item);
- node = listnode_lookup(config, item);
- if (node)
+ for (ALL_LIST_ELEMENTS_RO(config, node, pnt)) {
+ if (strcmp(pnt, line) == 0)
+ break;
+ }
+
+ if (!node)
+ config_add_line(config, line);
+ else
listnode_move_to_tail(config, node);
}
if (c == '\0')
return;
- /* printf ("[%s]\n", line); */
-
switch (c) {
/* Suppress exclamation points ! and commented lines. The !s are
* generated
} else if (strncmp(line, " ip multicast boundary",
strlen(" ip multicast boundary"))
== 0) {
- config_add_line_end(config->line, line);
+ config_add_line_uniq_end(config->line, line);
} else if (strncmp(line, " ip igmp query-interval",
strlen(" ip igmp query-interval")) == 0) {
- config_add_line_end(config->line, line);
+ config_add_line_uniq_end(config->line, line);
} else if (config->index == LINK_PARAMS_NODE
&& strncmp(line, " exit-link-params",
strlen(" exit"))
&& strncmp(line, " exit-vrf",
strlen(" exit-vrf"))
== 0) {
- config_add_line(config->line, line);
- config->index = CONFIG_NODE;
+ config_add_line_uniq_end(config->line, line);
} else if (config->index == RMAP_NODE
|| config->index == INTERFACE_NODE
|| config->index == LOGICALROUTER_NODE
/* We free this memory at the end of this function. */
ref = buf = XMALLOC(MTYPE_TMP, bufsiz);
- /* Fetch interface informations into allocated buffer. */
+ /* Fetch interface information into allocated buffer. */
if (sysctl(mib, MIBSIZ, buf, &bufsiz, NULL, 0) < 0) {
flog_warn(EC_ZEBRA_SYSCTL_FAILED, "sysctl error by %s",
safe_strerror(errno));
/* We free this memory at the end of this function. */
ref = buf = XMALLOC(MTYPE_TMP, bufsiz);
- /* Fetch interface informations into allocated buffer. */
+ /* Fetch interface information into allocated buffer. */
if (sysctl(mib, MIBSIZ, buf, &bufsiz, NULL, 0) < 0) {
flog_err_sys(EC_ZEBRA_IFLIST_FAILED,
"Could not enumerate interfaces: %s",
if (len != iplen) {
flog_err(EC_ZEBRA_IRDP_LEN_MISMATCH,
- "IRDP: RX length doesnt match IP length");
+ "IRDP: RX length doesn't match IP length");
return;
}
return;
}
- /* XXX: RAW doesnt receive link-layer, surely? ??? */
+ /* XXX: RAW doesn't receive link-layer, surely? ??? */
/* Check so we don't checksum packets longer than oure RX_BUF - (ethlen
+
len of IP-header) 14+20 */
if (ifnlen && (strncmp(ifp->name, ifname, IFNAMSIZ) != 0)) {
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug(
- "%s: ifp name %s doesnt match sdl name %s",
+ "%s: ifp name %s doesn't match sdl name %s",
__func__, ifp->name, ifname);
ifp = NULL;
}
} /* for (ALL_NEXTHOPS(...))*/
/* If there was no useful nexthop, then complain. */
- if (nexthop_num == 0 && IS_ZEBRA_DEBUG_KERNEL)
- zlog_debug("%s: No useful nexthops were found in RIB entry %p",
- __func__, re);
+ if (nexthop_num == 0) {
+ if (IS_ZEBRA_DEBUG_KERNEL)
+ zlog_debug("%s: No useful nexthops were found in RIB entry %p",
+ __func__, re);
+ return 1;
+ }
return 0; /*XXX*/
}
if (nexthop_num == 0) {
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug("kernel_rtm_ipv6(): No useful nexthop.");
- return 0;
+ return 1;
}
return 0; /*XXX*/
if (vrf)
vty_out(vty, "(vrf %s)", vrf->name);
else
- vty_out(vty, "(vrf UKNOWN)");
+ vty_out(vty, "(vrf UNKNOWN)");
}
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
if (vrf)
vty_out(vty, "(vrf %s)", vrf->name);
else
- vty_out(vty, "(vrf UKNOWN)");
+ vty_out(vty, "(vrf UNKNOWN)");
}
if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
/* mac entry should be present */
mac = zvni_mac_lookup(zvni, &n->emac);
if (!mac) {
- zlog_debug("MAC %s doesnt exists for neigh %s on VNI %u",
+ zlog_debug("MAC %s doesn't exist for neigh %s on VNI %u",
prefix_mac2str(&n->emac, buf1, sizeof(buf1)),
ipaddr2str(ip, buf2, sizeof(buf2)), zvni->vni);
return -1;
if (use_json)
vty_out(vty, "{}\n");
else
- vty_out(vty, "%% L3-VNI %u doesnt exist\n", l3vni);
+ vty_out(vty, "%% L3-VNI %u doesn't exist\n", l3vni);
return;
}
vty_out(vty, "{}\n");
else
vty_out(vty,
- "%% Requested RMAC doesnt exist in L3-VNI %u",
+ "%% Requested RMAC doesn't exist in L3-VNI %u",
l3vni);
return;
}