static void bgp_aggr_aspath_prepare(struct hash_backet *hb, void *arg)
{
- struct aspath *asmerge = NULL;
struct aspath *hb_aspath = hb->data;
struct aspath **aggr_aspath = arg;
- if (*aggr_aspath) {
- asmerge = aspath_aggregate(*aggr_aspath, hb_aspath);
- aspath_free(*aggr_aspath);
- *aggr_aspath = asmerge;
- } else
+ if (*aggr_aspath)
+ *aggr_aspath = aspath_aggregate(*aggr_aspath, hb_aspath);
+ else
*aggr_aspath = aspath_dup(hb_aspath);
}
void bgp_compute_aggregate_aspath(struct bgp_aggregate *aggregate,
struct aspath *aspath)
+{
+ bgp_compute_aggregate_aspath_hash(aggregate, aspath);
+
+ bgp_compute_aggregate_aspath_val(aggregate);
+
+}
+
+void bgp_compute_aggregate_aspath_hash(struct bgp_aggregate *aggregate,
+ struct aspath *aspath)
{
struct aspath *aggr_aspath = NULL;
*/
aggr_aspath = hash_get(aggregate->aspath_hash, aspath,
bgp_aggr_aspath_hash_alloc);
+ }
- /* Compute aggregate's as-path.
- */
+ /* Increment reference counter.
+ */
+ aggr_aspath->refcnt++;
+}
+
+void bgp_compute_aggregate_aspath_val(struct bgp_aggregate *aggregate)
+{
+ if (aggregate == NULL)
+ return;
+ /* Re-compute aggregate's as-path.
+ */
+ if (aggregate->aspath) {
+ aspath_free(aggregate->aspath);
+ aggregate->aspath = NULL;
+ }
+ if (aggregate->aspath_hash
+ && aggregate->aspath_hash->count) {
hash_iterate(aggregate->aspath_hash,
bgp_aggr_aspath_prepare,
&aggregate->aspath);
}
-
- /* Increment refernce counter.
- */
- aggr_aspath->refcnt++;
}
void bgp_remove_aspath_from_aggregate(struct bgp_aggregate *aggregate,
struct aspath *aggr_aspath = NULL;
struct aspath *ret_aspath = NULL;
- if ((aggregate == NULL) || (aspath == NULL))
- return;
-
- if (aggregate->aspath_hash == NULL)
+ if ((!aggregate)
+ || (!aggregate->aspath_hash)
+ || (!aspath))
return;
/* Look-up the aspath in the hash.
ret_aspath = hash_release(aggregate->aspath_hash,
aggr_aspath);
aspath_free(ret_aspath);
+ ret_aspath = NULL;
/* Remove aggregate's old as-path.
*/
aspath_free(aggregate->aspath);
aggregate->aspath = NULL;
- /* Compute aggregate's as-path.
- */
- hash_iterate(aggregate->aspath_hash,
- bgp_aggr_aspath_prepare,
- &aggregate->aspath);
+ bgp_compute_aggregate_aspath_val(aggregate);
}
}
}
+
+void bgp_remove_aspath_from_aggregate_hash(struct bgp_aggregate *aggregate,
+ struct aspath *aspath)
+{
+ struct aspath *aggr_aspath = NULL;
+ struct aspath *ret_aspath = NULL;
+
+ if ((!aggregate)
+ || (!aggregate->aspath_hash)
+ || (!aspath))
+ return;
+
+ /* Look-up the aspath in the hash.
+ */
+ aggr_aspath = bgp_aggr_aspath_lookup(aggregate, aspath);
+ if (aggr_aspath) {
+ aggr_aspath->refcnt--;
+
+ if (aggr_aspath->refcnt == 0) {
+ ret_aspath = hash_release(aggregate->aspath_hash,
+ aggr_aspath);
+ aspath_free(ret_aspath);
+ ret_aspath = NULL;
+ }
+ }
+}
+
extern void bgp_compute_aggregate_aspath(struct bgp_aggregate *aggregate,
struct aspath *aspath);
+
+extern void bgp_compute_aggregate_aspath_hash(struct bgp_aggregate *aggregate,
+ struct aspath *aspath);
+extern void bgp_compute_aggregate_aspath_val(struct bgp_aggregate *aggregate);
extern void bgp_remove_aspath_from_aggregate(struct bgp_aggregate *aggregate,
struct aspath *aspath);
+extern void bgp_remove_aspath_from_aggregate_hash(
+ struct bgp_aggregate *aggregate,
+ struct aspath *aspath);
+
extern void bgp_aggr_aspath_remove(void *arg);
#endif /* _QUAGGA_BGP_ASPATH_H */
static void bgp_aggr_community_prepare(struct hash_backet *hb, void *arg)
{
- struct community *commerge = NULL;
struct community *hb_community = hb->data;
struct community **aggr_community = arg;
- if (*aggr_community) {
- commerge = community_merge(*aggr_community, hb_community);
- *aggr_community = community_uniq_sort(commerge);
- community_free(&commerge);
- } else
+ if (*aggr_community)
+ *aggr_community = community_merge(*aggr_community,
+ hb_community);
+ else
*aggr_community = community_dup(hb_community);
}
void bgp_compute_aggregate_community(struct bgp_aggregate *aggregate,
struct community *community)
+{
+ bgp_compute_aggregate_community_hash(aggregate, community);
+ bgp_compute_aggregate_community_val(aggregate);
+}
+
+
+void bgp_compute_aggregate_community_hash(struct bgp_aggregate *aggregate,
+ struct community *community)
{
struct community *aggr_community = NULL;
*/
aggr_community = hash_get(aggregate->community_hash, community,
bgp_aggr_communty_hash_alloc);
+ }
- /* Re-compute aggregate's community.
- */
- if (aggregate->community)
- community_free(&aggregate->community);
+ /* Increment reference counter.
+ */
+ aggr_community->refcnt++;
+}
+void bgp_compute_aggregate_community_val(struct bgp_aggregate *aggregate)
+{
+ struct community *commerge = NULL;
+
+ if (aggregate == NULL)
+ return;
+
+ /* Re-compute aggregate's community.
+ */
+ if (aggregate->community)
+ community_free(&aggregate->community);
+ if (aggregate->community_hash &&
+ aggregate->community_hash->count) {
hash_iterate(aggregate->community_hash,
bgp_aggr_community_prepare,
&aggregate->community);
+ commerge = aggregate->community;
+ aggregate->community = community_uniq_sort(commerge);
+ if (commerge)
+ community_free(&commerge);
}
-
- /* Increment refernce counter.
- */
- aggr_community->refcnt++;
}
+
+
void bgp_remove_community_from_aggregate(struct bgp_aggregate *aggregate,
struct community *community)
{
struct community *aggr_community = NULL;
struct community *ret_comm = NULL;
- if ((aggregate == NULL) || (community == NULL))
- return;
-
- if (aggregate->community_hash == NULL)
+ if ((!aggregate)
+ || (!aggregate->community_hash)
+ || (!community))
return;
/* Look-up the community in the hash.
aggr_community);
community_free(&ret_comm);
- community_free(&aggregate->community);
+ bgp_compute_aggregate_community_val(aggregate);
+ }
+ }
+}
+
+void bgp_remove_comm_from_aggregate_hash(struct bgp_aggregate *aggregate,
+ struct community *community)
+{
+
+ struct community *aggr_community = NULL;
+ struct community *ret_comm = NULL;
- /* Compute aggregate's community.
- */
- hash_iterate(aggregate->community_hash,
- bgp_aggr_community_prepare,
- &aggregate->community);
+ if ((!aggregate)
+ || (!aggregate->community_hash)
+ || (!community))
+ return;
+
+ /* Look-up the community in the hash.
+ */
+ aggr_community = bgp_aggr_community_lookup(aggregate, community);
+ if (aggr_community) {
+ aggr_community->refcnt--;
+
+ if (aggr_community->refcnt == 0) {
+ ret_comm = hash_release(aggregate->community_hash,
+ aggr_community);
+ community_free(&ret_comm);
}
}
}
extern uint32_t community_val_get(struct community *com, int i);
extern void bgp_compute_aggregate_community(struct bgp_aggregate *aggregate,
struct community *community);
+
+extern void bgp_compute_aggregate_community_val(
+ struct bgp_aggregate *aggregate);
+extern void bgp_compute_aggregate_community_hash(
+ struct bgp_aggregate *aggregate,
+ struct community *community);
extern void bgp_remove_community_from_aggregate(struct bgp_aggregate *aggregate,
struct community *community);
+extern void bgp_remove_comm_from_aggregate_hash(struct bgp_aggregate *aggregate,
+ struct community *community);
extern void bgp_aggr_community_remove(void *arg);
#endif /* _QUAGGA_BGP_COMMUNITY_H */
static void bgp_aggr_ecommunity_prepare(struct hash_backet *hb, void *arg)
{
- struct ecommunity *ecommerge = NULL;
struct ecommunity *hb_ecommunity = hb->data;
struct ecommunity **aggr_ecommunity = arg;
- if (*aggr_ecommunity) {
- ecommerge = ecommunity_merge(*aggr_ecommunity, hb_ecommunity);
- *aggr_ecommunity = ecommunity_uniq_sort(ecommerge);
- ecommunity_free(&ecommerge);
- } else
+ if (*aggr_ecommunity)
+ *aggr_ecommunity = ecommunity_merge(*aggr_ecommunity,
+ hb_ecommunity);
+ else
*aggr_ecommunity = ecommunity_dup(hb_ecommunity);
}
void bgp_compute_aggregate_ecommunity(struct bgp_aggregate *aggregate,
struct ecommunity *ecommunity)
+{
+ bgp_compute_aggregate_ecommunity_hash(aggregate, ecommunity);
+ bgp_compute_aggregate_ecommunity_val(aggregate);
+}
+
+
+void bgp_compute_aggregate_ecommunity_hash(struct bgp_aggregate *aggregate,
+ struct ecommunity *ecommunity)
{
struct ecommunity *aggr_ecommunity = NULL;
aggr_ecommunity = hash_get(aggregate->ecommunity_hash,
ecommunity,
bgp_aggr_ecommunty_hash_alloc);
+ }
- /* Re-compute aggregate's ecommunity.
- */
- if (aggregate->ecommunity)
- ecommunity_free(&aggregate->ecommunity);
+ /* Increment reference counter.
+ */
+ aggr_ecommunity->refcnt++;
+}
+void bgp_compute_aggregate_ecommunity_val(struct bgp_aggregate *aggregate)
+{
+ struct ecommunity *ecommerge = NULL;
+
+ if (aggregate == NULL)
+ return;
+
+ /* Re-compute aggregate's ecommunity.
+ */
+ if (aggregate->ecommunity)
+ ecommunity_free(&aggregate->ecommunity);
+ if (aggregate->ecommunity_hash
+ && aggregate->ecommunity_hash->count) {
hash_iterate(aggregate->ecommunity_hash,
bgp_aggr_ecommunity_prepare,
&aggregate->ecommunity);
+ ecommerge = aggregate->ecommunity;
+ aggregate->ecommunity = ecommunity_uniq_sort(ecommerge);
+ if (ecommerge)
+ ecommunity_free(&ecommerge);
}
-
- /* Increment refernce counter.
- */
- aggr_ecommunity->refcnt++;
}
void bgp_remove_ecommunity_from_aggregate(struct bgp_aggregate *aggregate,
struct ecommunity *aggr_ecommunity = NULL;
struct ecommunity *ret_ecomm = NULL;
- if ((aggregate == NULL) || (ecommunity == NULL))
- return;
-
- if (aggregate->ecommunity_hash == NULL)
+ if ((!aggregate)
+ || (!aggregate->ecommunity_hash)
+ || (!ecommunity))
return;
/* Look-up the ecommunity in the hash.
ret_ecomm = hash_release(aggregate->ecommunity_hash,
aggr_ecommunity);
ecommunity_free(&ret_ecomm);
+ bgp_compute_aggregate_ecommunity_val(aggregate);
+ }
+ }
+}
+
+void bgp_remove_ecomm_from_aggregate_hash(struct bgp_aggregate *aggregate,
+ struct ecommunity *ecommunity)
+{
+
+ struct ecommunity *aggr_ecommunity = NULL;
+ struct ecommunity *ret_ecomm = NULL;
- ecommunity_free(&aggregate->ecommunity);
+ if ((!aggregate)
+ || (!aggregate->ecommunity_hash)
+ || (!ecommunity))
+ return;
- /* Compute aggregate's ecommunity.
- */
- hash_iterate(aggregate->ecommunity_hash,
- bgp_aggr_ecommunity_prepare,
- &aggregate->ecommunity);
+ /* Look-up the ecommunity in the hash.
+ */
+ aggr_ecommunity = bgp_aggr_ecommunity_lookup(aggregate, ecommunity);
+ if (aggr_ecommunity) {
+ aggr_ecommunity->refcnt--;
+
+ if (aggr_ecommunity->refcnt == 0) {
+ ret_ecomm = hash_release(aggregate->ecommunity_hash,
+ aggr_ecommunity);
+ ecommunity_free(&ret_ecomm);
}
}
}
extern void bgp_compute_aggregate_ecommunity(
struct bgp_aggregate *aggregate,
struct ecommunity *ecommunity);
+
+extern void bgp_compute_aggregate_ecommunity_hash(
+ struct bgp_aggregate *aggregate,
+ struct ecommunity *ecommunity);
+extern void bgp_compute_aggregate_ecommunity_val(
+ struct bgp_aggregate *aggregate);
extern void bgp_remove_ecommunity_from_aggregate(
struct bgp_aggregate *aggregate,
struct ecommunity *ecommunity);
+extern void bgp_remove_ecomm_from_aggregate_hash(
+ struct bgp_aggregate *aggregate,
+ struct ecommunity *ecommunity);
extern void bgp_aggr_ecommunity_remove(void *arg);
#endif /* _QUAGGA_BGP_ECOMMUNITY_H */
static void bgp_aggr_lcommunity_prepare(struct hash_backet *hb, void *arg)
{
- struct lcommunity *lcommerge = NULL;
struct lcommunity *hb_lcommunity = hb->data;
struct lcommunity **aggr_lcommunity = arg;
- if (*aggr_lcommunity) {
- lcommerge = lcommunity_merge(*aggr_lcommunity, hb_lcommunity);
- *aggr_lcommunity = lcommunity_uniq_sort(lcommerge);
- lcommunity_free(&lcommerge);
- } else
+ if (*aggr_lcommunity)
+ *aggr_lcommunity = lcommunity_merge(*aggr_lcommunity,
+ hb_lcommunity);
+ else
*aggr_lcommunity = lcommunity_dup(hb_lcommunity);
}
void bgp_compute_aggregate_lcommunity(struct bgp_aggregate *aggregate,
struct lcommunity *lcommunity)
{
+
+ bgp_compute_aggregate_lcommunity_hash(aggregate, lcommunity);
+ bgp_compute_aggregate_lcommunity_val(aggregate);
+}
+
+void bgp_compute_aggregate_lcommunity_hash(struct bgp_aggregate *aggregate,
+ struct lcommunity *lcommunity)
+{
+
struct lcommunity *aggr_lcommunity = NULL;
if ((aggregate == NULL) || (lcommunity == NULL))
aggr_lcommunity = hash_get(aggregate->lcommunity_hash,
lcommunity,
bgp_aggr_lcommunty_hash_alloc);
+ }
- /* Re-compute aggregate's lcommunity.
- */
- if (aggregate->lcommunity)
- lcommunity_free(&aggregate->lcommunity);
+ /* Increment reference counter.
+ */
+ aggr_lcommunity->refcnt++;
+}
+
+void bgp_compute_aggregate_lcommunity_val(struct bgp_aggregate *aggregate)
+{
+ struct lcommunity *lcommerge = NULL;
+
+ if (aggregate == NULL)
+ return;
+ /* Re-compute aggregate's lcommunity.
+ */
+ if (aggregate->lcommunity)
+ lcommunity_free(&aggregate->lcommunity);
+ if (aggregate->lcommunity_hash &&
+ aggregate->lcommunity_hash->count) {
hash_iterate(aggregate->lcommunity_hash,
bgp_aggr_lcommunity_prepare,
&aggregate->lcommunity);
+ lcommerge = aggregate->lcommunity;
+ aggregate->lcommunity = lcommunity_uniq_sort(lcommerge);
+ if (lcommerge)
+ lcommunity_free(&lcommerge);
}
-
- /* Increment refernce counter.
- */
- aggr_lcommunity->refcnt++;
}
void bgp_remove_lcommunity_from_aggregate(struct bgp_aggregate *aggregate,
struct lcommunity *aggr_lcommunity = NULL;
struct lcommunity *ret_lcomm = NULL;
- if ((aggregate == NULL) || (lcommunity == NULL))
- return;
-
- if (aggregate->lcommunity_hash == NULL)
+ if ((!aggregate)
+ || (!aggregate->lcommunity_hash)
+ || (!lcommunity))
return;
/* Look-up the lcommunity in the hash.
aggr_lcommunity);
lcommunity_free(&ret_lcomm);
- lcommunity_free(&aggregate->lcommunity);
+ bgp_compute_aggregate_lcommunity_val(aggregate);
+
+ }
+ }
+}
+
+void bgp_remove_lcomm_from_aggregate_hash(struct bgp_aggregate *aggregate,
+ struct lcommunity *lcommunity)
+{
+ struct lcommunity *aggr_lcommunity = NULL;
+ struct lcommunity *ret_lcomm = NULL;
- /* Compute aggregate's lcommunity.
- */
- hash_iterate(aggregate->lcommunity_hash,
- bgp_aggr_lcommunity_prepare,
- &aggregate->lcommunity);
+ if ((!aggregate)
+ || (!aggregate->lcommunity_hash)
+ || (!lcommunity))
+ return;
+
+ /* Look-up the lcommunity in the hash.
+ */
+ aggr_lcommunity = bgp_aggr_lcommunity_lookup(aggregate, lcommunity);
+ if (aggr_lcommunity) {
+ aggr_lcommunity->refcnt--;
+
+ if (aggr_lcommunity->refcnt == 0) {
+ ret_lcomm = hash_release(aggregate->lcommunity_hash,
+ aggr_lcommunity);
+ lcommunity_free(&ret_lcomm);
}
}
}
extern void bgp_compute_aggregate_lcommunity(
struct bgp_aggregate *aggregate,
struct lcommunity *lcommunity);
+
+extern void bgp_compute_aggregate_lcommunity_hash(
+ struct bgp_aggregate *aggregate,
+ struct lcommunity *lcommunity);
+extern void bgp_compute_aggregate_lcommunity_val(
+ struct bgp_aggregate *aggregate);
+
extern void bgp_remove_lcommunity_from_aggregate(
struct bgp_aggregate *aggregate,
struct lcommunity *lcommunity);
+extern void bgp_remove_lcomm_from_aggregate_hash(
+ struct bgp_aggregate *aggregate,
+ struct lcommunity *lcommunity);
extern void bgp_aggr_lcommunity_remove(void *arg);
#endif /* _QUAGGA_BGP_LCOMMUNITY_H */
*/
/* Compute aggregate route's as-path.
*/
- bgp_compute_aggregate_aspath(aggregate,
- pi->attr->aspath);
+ bgp_compute_aggregate_aspath_hash(aggregate,
+ pi->attr->aspath);
/* Compute aggregate route's community.
*/
if (pi->attr->community)
- bgp_compute_aggregate_community(
+ bgp_compute_aggregate_community_hash(
aggregate,
pi->attr->community);
/* Compute aggregate route's extended community.
*/
if (pi->attr->ecommunity)
- bgp_compute_aggregate_ecommunity(
+ bgp_compute_aggregate_ecommunity_hash(
aggregate,
pi->attr->ecommunity);
/* Compute aggregate route's large community.
*/
if (pi->attr->lcommunity)
- bgp_compute_aggregate_lcommunity(
+ bgp_compute_aggregate_lcommunity_hash(
aggregate,
pi->attr->lcommunity);
}
if (match)
bgp_process(bgp, rn, afi, safi);
}
+ if (aggregate->as_set) {
+ bgp_compute_aggregate_aspath_val(aggregate);
+ bgp_compute_aggregate_community_val(aggregate);
+ bgp_compute_aggregate_ecommunity_val(aggregate);
+ bgp_compute_aggregate_lcommunity_val(aggregate);
+ }
+
+
bgp_unlock_node(top);
if (aggregate->as_set) {
/* Remove as-path from aggregate.
*/
- bgp_remove_aspath_from_aggregate(
+ bgp_remove_aspath_from_aggregate_hash(
aggregate,
pi->attr->aspath);
if (pi->attr->community)
/* Remove community from aggregate.
*/
- bgp_remove_community_from_aggregate(
+ bgp_remove_comm_from_aggregate_hash(
aggregate,
pi->attr->community);
if (pi->attr->ecommunity)
/* Remove ecommunity from aggregate.
*/
- bgp_remove_ecommunity_from_aggregate(
+ bgp_remove_ecomm_from_aggregate_hash(
aggregate,
pi->attr->ecommunity);
if (pi->attr->lcommunity)
/* Remove lcommunity from aggregate.
*/
- bgp_remove_lcommunity_from_aggregate(
+ bgp_remove_lcomm_from_aggregate_hash(
aggregate,
pi->attr->lcommunity);
}
if (match)
bgp_process(bgp, rn, afi, safi);
}
+ if (aggregate->as_set) {
+ aspath_free(aggregate->aspath);
+ aggregate->aspath = NULL;
+ if (aggregate->community)
+ community_free(&aggregate->community);
+ if (aggregate->ecommunity)
+ ecommunity_free(&aggregate->ecommunity);
+ if (aggregate->lcommunity)
+ lcommunity_free(&aggregate->lcommunity);
+ }
+
bgp_unlock_node(top);
}
vty_out(vty, " Created: %s", timestamp_string(updgrp->uptime));
filter = &updgrp->conf->filter[updgrp->afi][updgrp->safi];
if (filter->map[RMAP_OUT].name)
- vty_out(vty, " Outgoing route map: %s%s\n",
- filter->map[RMAP_OUT].map ? "X" : "",
+ vty_out(vty, " Outgoing route map: %s\n",
filter->map[RMAP_OUT].name);
vty_out(vty, " MRAI value (seconds): %d\n", updgrp->conf->v_routeadv);
if (updgrp->conf->change_local_as)
subgrp->peer_refreshes_combined);
vty_out(vty, " Merge checks triggered: %u\n",
subgrp->merge_checks_triggered);
+ vty_out(vty, " Coalesce Time: %u%s\n",
+ (UPDGRP_INST(subgrp->update_group))->coalesce_time,
+ subgrp->t_coalesce ? "(Running)" : "");
vty_out(vty, " Version: %" PRIu64 "\n", subgrp->version);
vty_out(vty, " Packet queue length: %d\n",
bpacket_queue_length(SUBGRP_PKTQ(subgrp)));
subgrp = THREAD_ARG(thread);
if (bgp_debug_update(NULL, NULL, subgrp->update_group, 0))
zlog_debug("u%" PRIu64 ":s%" PRIu64
- " announcing routes upon coalesce timer expiry",
- (SUBGRP_UPDGRP(subgrp))->id, subgrp->id);
+ " announcing routes upon coalesce timer expiry(%u ms)",
+ (SUBGRP_UPDGRP(subgrp))->id, subgrp->id,
+ subgrp->v_coalesce),
subgrp->t_coalesce = NULL;
subgrp->v_coalesce = 0;
subgroup_announce_route(subgrp);
uint8_t last_reset_cause[BGP_MAX_PACKET_SIZE];
/* The kind of route-map Flags.*/
- uint8_t rmap_type;
+ uint16_t rmap_type;
#define PEER_RMAP_TYPE_IN (1 << 0) /* neighbor route-map in */
#define PEER_RMAP_TYPE_OUT (1 << 1) /* neighbor route-map out */
#define PEER_RMAP_TYPE_NETWORK (1 << 2) /* network route-map */
fi
AC_SUBST([HAVE_LIBPCREPOSIX])
+dnl ##########################################################################
+dnl test "${enable_clippy_only}" != "yes"
+fi
+dnl END OF LARGE if block
+dnl ##########################################################################
+
dnl ------------------
dnl check C-Ares library
dnl ------------------
])
AM_CONDITIONAL([CARES], [$c_ares_found])
-dnl ##########################################################################
-dnl test "${enable_clippy_only}" != "yes"
-fi
-dnl END OF LARGE if block
-dnl ##########################################################################
-
dnl ----------------------------------------------------------------------------
dnl figure out if domainname is available in the utsname struct (GNU extension).
no)
;;
yes)
+ if test "${enable_clippy_only}" != "yes"; then
if test "$c_ares_found" != "true" ; then
AC_MSG_ERROR([nhrpd requires libcares. Please install c-ares and its -dev headers.])
fi
+ fi
NHRPD="nhrpd"
;;
*)
case "$host_os" in
linux*)
+ if test "${enable_clippy_only}" != "yes"; then
if test "$frr_ac_lcaps" != "yes"; then
AC_MSG_ERROR([libcap and/or its headers were not found. Running FRR without libcap support built in causes a huge performance penalty.])
fi
+ fi
;;
esac
else
Print a summary of neighbor connections for the specified AFI/SAFI combination.
+Displaying Update Group Information
+-----------------------------------
+
+..index:: show bgp update-groups SUBGROUP-ID [advertise-queue|advertised-routes|packet-queue]
+..clicmd:: show bgp update-groups [advertise-queue|advertised-routes|packet-queue]
+
+ Display Information about each individual update-group being used.
+ If SUBGROUP-ID is specified only display about that particular group. If
+ advertise-queue is specified the list of routes that need to be sent
+ to the peers in the update-group is displayed, advertised-routes means
+ the list of routes we have sent to the peers in the update-group and
+ packet-queue specifies the list of packets in the queue to be sent.
+
+..index:: show bgp update-groups statistics
+..clicmd:: show bgp update-groups statistics
+
+ Display Information about update-group events in FRR.
.. _bgp-route-reflector:
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef __LINUX_FIB_RULES_H
#define __LINUX_FIB_RULES_H
__u8 tos;
__u8 table;
- __u8 res1; /* reserved */
+ __u8 res1; /* reserved */
__u8 res2; /* reserved */
__u8 action;
__u32 flags;
};
+struct fib_rule_uid_range {
+ __u32 start;
+ __u32 end;
+};
+
+struct fib_rule_port_range {
+ __u16 start;
+ __u16 end;
+};
+
enum {
FRA_UNSPEC,
FRA_DST, /* destination address */
FRA_UNUSED5,
FRA_FWMARK, /* mark */
FRA_FLOW, /* flow/class id */
- FRA_UNUSED6,
+ FRA_TUN_ID,
FRA_SUPPRESS_IFGROUP,
FRA_SUPPRESS_PREFIXLEN,
FRA_TABLE, /* Extended table id */
FRA_OIFNAME,
FRA_PAD,
FRA_L3MDEV, /* iif or oif is l3mdev goto its table */
+ FRA_UID_RANGE, /* UID range */
+ FRA_PROTOCOL, /* Originator of the rule */
+ FRA_IP_PROTO, /* ip proto */
+ FRA_SPORT_RANGE, /* sport */
+ FRA_DPORT_RANGE, /* dport */
__FRA_MAX
};
IFA_MULTICAST,
IFA_FLAGS,
IFA_RT_PRIORITY, /* u32, priority/metric for prefix route */
+ IFA_TARGET_NETNSID,
__IFA_MAX,
};
};
/* backwards compatibility for userspace */
+#ifndef __KERNEL__
#define IFA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))))
#define IFA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifaddrmsg))
+#endif
#endif
+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
/*
* Linux ethernet bridge
*
* 2 of the License, or (at your option) any later version.
*/
-#ifndef _LINUX_IF_BRIDGE_H
-#define _LINUX_IF_BRIDGE_H
+#ifndef _UAPI_LINUX_IF_BRIDGE_H
+#define _UAPI_LINUX_IF_BRIDGE_H
#include <linux/types.h>
#include <linux/if_ether.h>
__u32 ageing_timer_value;
__u8 port_hi;
__u8 pad0;
- __u16 unused;
+ __u16 vlan;
};
/* Bridge Flags */
#define MDB_PERMANENT 1
__u8 state;
#define MDB_FLAGS_OFFLOAD (1 << 0)
+#define MDB_FLAGS_FAST_LEAVE (1 << 1)
__u8 flags;
__u16 vid;
struct {
__u64 mcast_bytes[BR_MCAST_DIR_SIZE];
__u64 mcast_packets[BR_MCAST_DIR_SIZE];
};
-#endif /* _LINUX_IF_BRIDGE_H */
+#endif /* _UAPI_LINUX_IF_BRIDGE_H */
-#ifndef _LINUX_IF_LINK_H
-#define _LINUX_IF_LINK_H
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _UAPI_LINUX_IF_LINK_H
+#define _UAPI_LINUX_IF_LINK_H
#include <linux/types.h>
#include <linux/netlink.h>
IFLA_PAD,
IFLA_XDP,
IFLA_EVENT,
+ IFLA_NEW_NETNSID,
+ IFLA_IF_NETNSID,
+ IFLA_TARGET_NETNSID = IFLA_IF_NETNSID, /* new alias */
+ IFLA_CARRIER_UP_COUNT,
+ IFLA_CARRIER_DOWN_COUNT,
+ IFLA_NEW_IFINDEX,
+ IFLA_MIN_MTU,
+ IFLA_MAX_MTU,
__IFLA_MAX
};
#define IFLA_MAX (__IFLA_MAX - 1)
/* backwards compatibility for userspace */
+#ifndef __KERNEL__
#define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
#define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg))
+#endif
enum {
IFLA_INET_UNSPEC,
IFLA_BR_MCAST_STATS_ENABLED,
IFLA_BR_MCAST_IGMP_VERSION,
IFLA_BR_MCAST_MLD_VERSION,
+ IFLA_BR_VLAN_STATS_PER_PORT,
__IFLA_BR_MAX,
};
IFLA_BRPORT_MCAST_TO_UCAST,
IFLA_BRPORT_VLAN_TUNNEL,
IFLA_BRPORT_BCAST_FLOOD,
+ IFLA_BRPORT_GROUP_FWD_MASK,
+ IFLA_BRPORT_NEIGH_SUPPRESS,
+ IFLA_BRPORT_ISOLATED,
+ IFLA_BRPORT_BACKUP_PORT,
+ IFLA_BRPORT_PEER_LINK = 60, /* MLAG peer link */
+ IFLA_BRPORT_DUAL_LINK, /* MLAG Dual Connected link */
+ IFLA_BRPORT_GROUP_FWD_MASKHI,
+ IFLA_BRPORT_DUAL_LINK_READY,
__IFLA_BRPORT_MAX
};
#define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
#define IFLA_MACSEC_MAX (__IFLA_MACSEC_MAX - 1)
+/* XFRM section */
+enum {
+ IFLA_XFRM_UNSPEC,
+ IFLA_XFRM_LINK,
+ IFLA_XFRM_IF_ID,
+ __IFLA_XFRM_MAX
+};
+
+#define IFLA_XFRM_MAX (__IFLA_XFRM_MAX - 1)
+
enum macsec_validation_type {
MACSEC_VALIDATE_DISABLED = 0,
MACSEC_VALIDATE_CHECK = 1,
enum {
IFLA_IPVLAN_UNSPEC,
IFLA_IPVLAN_MODE,
+ IFLA_IPVLAN_FLAGS,
__IFLA_IPVLAN_MAX
};
IPVLAN_MODE_MAX
};
+#define IPVLAN_F_PRIVATE 0x01
+#define IPVLAN_F_VEPA 0x02
+
/* VXLAN section */
enum {
IFLA_VXLAN_UNSPEC,
IFLA_VXLAN_COLLECT_METADATA,
IFLA_VXLAN_LABEL,
IFLA_VXLAN_GPE,
+ IFLA_VXLAN_TTL_INHERIT,
__IFLA_VXLAN_MAX
};
#define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)
IFLA_BOND_AD_USER_PORT_KEY,
IFLA_BOND_AD_ACTOR_SYSTEM,
IFLA_BOND_TLB_DYNAMIC_LB,
+ IFLA_BOND_CL_START = 60,
+ IFLA_BOND_AD_LACP_BYPASS = IFLA_BOND_CL_START,
__IFLA_BOND_MAX,
};
IFLA_BOND_SLAVE_AD_AGGREGATOR_ID,
IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE,
IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE,
+
+ IFLA_BOND_SLAVE_CL_START = 50,
+ IFLA_BOND_SLAVE_AD_RX_BYPASS = IFLA_BOND_SLAVE_CL_START,
__IFLA_BOND_SLAVE_MAX,
};
IFLA_VF_STATS_BROADCAST,
IFLA_VF_STATS_MULTICAST,
IFLA_VF_STATS_PAD,
+ IFLA_VF_STATS_RX_DROPPED,
+ IFLA_VF_STATS_TX_DROPPED,
__IFLA_VF_STATS_MAX,
};
enum {
LINK_XSTATS_TYPE_UNSPEC,
LINK_XSTATS_TYPE_BRIDGE,
+ LINK_XSTATS_TYPE_BOND,
__LINK_XSTATS_TYPE_MAX
};
#define LINK_XSTATS_TYPE_MAX (__LINK_XSTATS_TYPE_MAX - 1)
XDP_ATTACHED_DRV,
XDP_ATTACHED_SKB,
XDP_ATTACHED_HW,
+ XDP_ATTACHED_MULTI,
};
enum {
IFLA_XDP_ATTACHED,
IFLA_XDP_FLAGS,
IFLA_XDP_PROG_ID,
+ IFLA_XDP_DRV_PROG_ID,
+ IFLA_XDP_SKB_PROG_ID,
+ IFLA_XDP_HW_PROG_ID,
__IFLA_XDP_MAX,
};
IFLA_EVENT_BONDING_OPTIONS, /* change in bonding options */
};
-#endif /* _LINUX_IF_LINK_H */
+/* tun section */
+
+enum {
+ IFLA_TUN_UNSPEC,
+ IFLA_TUN_OWNER,
+ IFLA_TUN_GROUP,
+ IFLA_TUN_TYPE,
+ IFLA_TUN_PI,
+ IFLA_TUN_VNET_HDR,
+ IFLA_TUN_PERSIST,
+ IFLA_TUN_MULTI_QUEUE,
+ IFLA_TUN_NUM_QUEUES,
+ IFLA_TUN_NUM_DISABLED_QUEUES,
+ __IFLA_TUN_MAX,
+};
+
+#define IFLA_TUN_MAX (__IFLA_TUN_MAX - 1)
+
+/* rmnet section */
+
+#define RMNET_FLAGS_INGRESS_DEAGGREGATION (1U << 0)
+#define RMNET_FLAGS_INGRESS_MAP_COMMANDS (1U << 1)
+#define RMNET_FLAGS_INGRESS_MAP_CKSUMV4 (1U << 2)
+#define RMNET_FLAGS_EGRESS_MAP_CKSUMV4 (1U << 3)
+
+enum {
+ IFLA_RMNET_UNSPEC,
+ IFLA_RMNET_MUX_ID,
+ IFLA_RMNET_FLAGS,
+ __IFLA_RMNET_MAX,
+};
+
+#define IFLA_RMNET_MAX (__IFLA_RMNET_MAX - 1)
+
+struct ifla_rmnet_flags {
+ __u32 flags;
+ __u32 mask;
+};
+
+#endif /* _UAPI_LINUX_IF_LINK_H */
-#ifndef _LWTUNNEL_H_
-#define _LWTUNNEL_H_
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _UAPI_LWTUNNEL_H_
+#define _UAPI_LWTUNNEL_H_
#include <linux/types.h>
#define LWT_BPF_MAX_HEADROOM 256
-#endif /* _LWTUNNEL_H_ */
+#endif /* _UAPI_LWTUNNEL_H_ */
+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
/*
* mpls tunnel api
*
* 2 of the License, or (at your option) any later version.
*/
-#ifndef _LINUX_MPLS_IPTUNNEL_H
-#define _LINUX_MPLS_IPTUNNEL_H
+#ifndef _UAPI_LINUX_MPLS_IPTUNNEL_H
+#define _UAPI_LINUX_MPLS_IPTUNNEL_H
/* MPLS tunnel attributes
* [RTA_ENCAP] = {
};
#define MPLS_IPTUNNEL_MAX (__MPLS_IPTUNNEL_MAX - 1)
-#endif /* _LINUX_MPLS_IPTUNNEL_H */
+#endif /* _UAPI_LINUX_MPLS_IPTUNNEL_H */
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef __LINUX_NEIGHBOUR_H
#define __LINUX_NEIGHBOUR_H
NDA_MASTER,
NDA_LINK_NETNSID,
NDA_SRC_VNI,
+ NDA_PROTOCOL, /* Originator of entry */
__NDA_MAX
};
#define NTF_PROXY 0x08 /* == ATF_PUBL */
#define NTF_EXT_LEARNED 0x10
#define NTF_OFFLOADED 0x20
+#define NTF_STICKY 0x40
#define NTF_ROUTER 0x80
/*
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/* Copyright (c) 2015 6WIND S.A.
* Author: Nicolas Dichtel <nicolas.dichtel@6wind.com>
*
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*/
-#ifndef _LINUX_NET_NAMESPACE_H_
-#define _LINUX_NET_NAMESPACE_H_
+#ifndef _UAPI_LINUX_NET_NAMESPACE_H_
+#define _UAPI_LINUX_NET_NAMESPACE_H_
/* Attributes of RTM_NEWNSID/RTM_GETNSID messages */
enum {
#define NETNSA_MAX (__NETNSA_MAX - 1)
-#endif /* _LINUX_NET_NAMESPACE_H_ */
+#endif /* _UAPI_LINUX_NET_NAMESPACE_H_ */
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-#ifndef __LINUX_NETLINK_H
-#define __LINUX_NETLINK_H
+#ifndef _UAPI__LINUX_NETLINK_H
+#define _UAPI__LINUX_NETLINK_H
#include <linux/kernel.h>
#include <linux/socket.h> /* for __kernel_sa_family_t */
#define NETLINK_PKTINFO 3
#define NETLINK_BROADCAST_ERROR 4
#define NETLINK_NO_ENOBUFS 5
+#ifndef __KERNEL__
#define NETLINK_RX_RING 6
#define NETLINK_TX_RING 7
+#endif
#define NETLINK_LISTEN_ALL_NSID 8
#define NETLINK_LIST_MEMBERSHIPS 9
#define NETLINK_CAP_ACK 10
#define NETLINK_EXT_ACK 11
+#define NETLINK_GET_STRICT_CHK 12
struct nl_pktinfo {
__u32 group;
__u32 nm_gid;
};
+#ifndef __KERNEL__
enum nl_mmap_status {
NL_MMAP_STATUS_UNUSED,
NL_MMAP_STATUS_RESERVED,
#define NL_MMAP_MSG_ALIGNMENT NLMSG_ALIGNTO
#define NL_MMAP_MSG_ALIGN(sz) __ALIGN_KERNEL(sz, NL_MMAP_MSG_ALIGNMENT)
#define NL_MMAP_HDRLEN NL_MMAP_MSG_ALIGN(sizeof(struct nl_mmap_hdr))
+#endif
#define NET_MAJOR 36 /* Major 36 is reserved for networking */
__u32 selector;
};
-#endif /* __LINUX_NETLINK_H */
+#endif /* _UAPI__LINUX_NETLINK_H */
-#ifndef __LINUX_RTNETLINK_H
-#define __LINUX_RTNETLINK_H
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _UAPI__LINUX_RTNETLINK_H
+#define _UAPI__LINUX_RTNETLINK_H
#include <linux/types.h>
#include <linux/netlink.h>
RTM_NEWCACHEREPORT = 96,
#define RTM_NEWCACHEREPORT RTM_NEWCACHEREPORT
+ RTM_NEWCHAIN = 100,
+#define RTM_NEWCHAIN RTM_NEWCHAIN
+ RTM_DELCHAIN,
+#define RTM_DELCHAIN RTM_DELCHAIN
+ RTM_GETCHAIN,
+#define RTM_GETCHAIN RTM_GETCHAIN
+
+ RTM_NEWNEXTHOP = 104,
+#define RTM_NEWNEXTHOP RTM_NEWNEXTHOP
+ RTM_DELNEXTHOP,
+#define RTM_DELNEXTHOP RTM_DELNEXTHOP
+ RTM_GETNEXTHOP,
+#define RTM_GETNEXTHOP RTM_GETNEXTHOP
+
__RTM_MAX,
#define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1)
};
#define RTPROT_DHCP 16 /* DHCP client */
#define RTPROT_MROUTED 17 /* Multicast daemon */
#define RTPROT_BABEL 42 /* Babel daemon */
+#define RTPROT_BGP 186 /* BGP Routes */
+#define RTPROT_ISIS 187 /* ISIS Routes */
+#define RTPROT_OSPF 188 /* OSPF Routes */
+#define RTPROT_RIP 189 /* RIP Routes */
+#define RTPROT_EIGRP 192 /* EIGRP Routes */
/* rtm_scope
RTA_PAD,
RTA_UID,
RTA_TTL_PROPAGATE,
+ RTA_IP_PROTO,
+ RTA_SPORT,
+ RTA_DPORT,
+ RTA_NH_ID,
__RTA_MAX
};
#define RTAX_QUICKACK RTAX_QUICKACK
RTAX_CC_ALGO,
#define RTAX_CC_ALGO RTAX_CC_ALGO
+ RTAX_FASTOPEN_NO_COOKIE,
+#define RTAX_FASTOPEN_NO_COOKIE RTAX_FASTOPEN_NO_COOKIE
__RTAX_MAX
};
int tcm_ifindex;
__u32 tcm_handle;
__u32 tcm_parent;
+/* tcm_block_index is used instead of tcm_parent
+ * in case tcm_ifindex == TCM_IFINDEX_MAGIC_BLOCK
+ */
+#define tcm_block_index tcm_parent
__u32 tcm_info;
};
+/* For manipulation of filters in shared block, tcm_ifindex is set to
+ * TCM_IFINDEX_MAGIC_BLOCK, and tcm_parent is aliased to tcm_block_index
+ * which is the block index.
+ */
+#define TCM_IFINDEX_MAGIC_BLOCK (0xFFFFFFFFU)
+
enum {
TCA_UNSPEC,
TCA_KIND,
TCA_PAD,
TCA_DUMP_INVISIBLE,
TCA_CHAIN,
+ TCA_HW_OFFLOAD,
+ TCA_INGRESS_BLOCK,
+ TCA_EGRESS_BLOCK,
__TCA_MAX
};
#define NDUSEROPT_MAX (__NDUSEROPT_MAX - 1)
+#ifndef __KERNEL__
/* RTnetlink multicast groups - backwards compatibility for userspace */
#define RTMGRP_LINK 1
#define RTMGRP_NOTIFY 2
#define RTMGRP_DECnet_ROUTE 0x4000
#define RTMGRP_IPV6_PREFIX 0x20000
+#endif
/* RTnetlink multicast groups */
enum rtnetlink_groups {
#define RTNLGRP_IPV4_MROUTE_R RTNLGRP_IPV4_MROUTE_R
RTNLGRP_IPV6_MROUTE_R,
#define RTNLGRP_IPV6_MROUTE_R RTNLGRP_IPV6_MROUTE_R
+ RTNLGRP_NEXTHOP,
+#define RTNLGRP_NEXTHOP RTNLGRP_NEXTHOP
__RTNLGRP_MAX
};
#define RTNLGRP_MAX (__RTNLGRP_MAX - 1)
-#endif /* __LINUX_RTNETLINK_H */
+#endif /* _UAPI__LINUX_RTNETLINK_H */
-#ifndef _LINUX_SOCKET_H
-#define _LINUX_SOCKET_H
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _UAPI_LINUX_SOCKET_H
+#define _UAPI_LINUX_SOCKET_H
/*
* Desired design of maximum size and alignment (see RFC2553)
/* _SS_MAXSIZE value minus size of ss_family */
} __attribute__ ((aligned(_K_SS_ALIGNSIZE))); /* force desired alignment */
-#endif /* _LINUX_SOCKET_H */
+#endif /* _UAPI_LINUX_SOCKET_H */
reason ? reason : "unspecified");
}
+ circuit->adj_state_changes++;
#ifndef FABRICD
/* send northbound notification */
isis_notif_adj_state_change(adj, new_state, reason);
uint32_t
desig_changes[2]; /* lanLxDesignatedIntermediateSystemChanges */
uint32_t rej_adjacencies; /* rejectedAdjacencies */
+ /*
+ * Counters as in ietf-isis@2019-09-09.yang
+ */
+ uint32_t id_len_mismatches; /* id-len-mismatch */
+ uint32_t max_area_addr_mismatches; /* max-area-addresses-mismatch */
+ uint32_t auth_type_failures; /*authentication-type-fails */
+ uint32_t auth_failures; /* authentication-fails */
QOBJ_FIELDS
};
#include "lib/lib_errors.h"
#include "lib/vrf.h"
+/*
+ * Helper functions.
+ */
+static const char *isis_yang_adj_state(enum isis_adj_state state)
+{
+ switch (state) {
+ case ISIS_ADJ_DOWN:
+ return "down";
+ case ISIS_ADJ_UP:
+ return "up";
+ case ISIS_ADJ_INITIALIZING:
+ return "init";
+ default:
+ return "failed";
+ }
+}
+
/*
* XPath: /frr-isisd:isis/instance
*/
/* check if interface mtu is sufficient. If the area has not
* been created yet, assume default MTU for the area
*/
- ifp = nb_running_get_entry(dnode, NULL, true);
+ ifp = nb_running_get_entry(dnode, NULL, false);
/* zebra might not know yet about the MTU - nothing we can do */
- if (ifp->mtu == 0)
+ if (!ifp || ifp->mtu == 0)
break;
actual_mtu =
if_is_broadcast(ifp) ? ifp->mtu - LLC_LEN : ifp->mtu;
ISIS_MT_IPV6_DSTSRC);
}
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency
+ */
+static const void *
+lib_interface_isis_adjacencies_adjacency_get_next(const void *parent_list_entry,
+ const void *list_entry)
+{
+ struct interface *ifp;
+ struct isis_circuit *circuit;
+ struct isis_adjacency *adj, *adj_next = NULL;
+ struct list *list;
+ struct listnode *node, *node_next;
+
+ /* Get first adjacency. */
+ if (list_entry == NULL) {
+ ifp = (struct interface *)parent_list_entry;
+ if (!ifp)
+ return NULL;
+
+ circuit = circuit_scan_by_ifp(ifp);
+ if (!circuit)
+ return NULL;
+
+ switch (circuit->circ_type) {
+ case CIRCUIT_T_BROADCAST:
+ for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS;
+ level++) {
+ adj = listnode_head(
+ circuit->u.bc.adjdb[level - 1]);
+ if (adj)
+ break;
+ }
+ break;
+ case CIRCUIT_T_P2P:
+ adj = circuit->u.p2p.neighbor;
+ break;
+ default:
+ adj = NULL;
+ break;
+ }
+
+ return adj;
+ }
+
+ /* Get next adjacency. */
+ adj = (struct isis_adjacency *)list_entry;
+ circuit = adj->circuit;
+ switch (circuit->circ_type) {
+ case CIRCUIT_T_BROADCAST:
+ list = circuit->u.bc.adjdb[adj->level - 1];
+ node = listnode_lookup(list, adj);
+ node_next = listnextnode(node);
+ if (node_next)
+ adj_next = listgetdata(node_next);
+ else if (adj->level == ISIS_LEVEL1) {
+ /*
+ * Once we finish the L1 adjacencies, move to the L2
+ * adjacencies list.
+ */
+ list = circuit->u.bc.adjdb[ISIS_LEVEL2 - 1];
+ adj_next = listnode_head(list);
+ }
+ break;
+ case CIRCUIT_T_P2P:
+ /* P2P circuits have at most one adjacency. */
+ default:
+ break;
+ }
+
+ return adj_next;
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/neighbor-sys-type
+ */
+static struct yang_data *
+lib_interface_isis_adjacencies_adjacency_neighbor_sys_type_get_elem(
+ const char *xpath, const void *list_entry)
+{
+ const struct isis_adjacency *adj = list_entry;
+
+ return yang_data_new_enum(xpath, adj->level);
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/neighbor-sysid
+ */
+static struct yang_data *
+lib_interface_isis_adjacencies_adjacency_neighbor_sysid_get_elem(
+ const char *xpath, const void *list_entry)
+{
+ const struct isis_adjacency *adj = list_entry;
+
+ return yang_data_new_string(xpath, sysid_print(adj->sysid));
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/neighbor-extended-circuit-id
+ */
+static struct yang_data *
+lib_interface_isis_adjacencies_adjacency_neighbor_extended_circuit_id_get_elem(
+ const char *xpath, const void *list_entry)
+{
+ const struct isis_adjacency *adj = list_entry;
+
+ return yang_data_new_uint32(xpath, adj->circuit->circuit_id);
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/neighbor-snpa
+ */
+static struct yang_data *
+lib_interface_isis_adjacencies_adjacency_neighbor_snpa_get_elem(
+ const char *xpath, const void *list_entry)
+{
+ const struct isis_adjacency *adj = list_entry;
+
+ return yang_data_new_string(xpath, snpa_print(adj->snpa));
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/hold-timer
+ */
+static struct yang_data *
+lib_interface_isis_adjacencies_adjacency_hold_timer_get_elem(
+ const char *xpath, const void *list_entry)
+{
+ const struct isis_adjacency *adj = list_entry;
+
+ return yang_data_new_uint16(xpath, adj->hold_time);
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/neighbor-priority
+ */
+static struct yang_data *
+lib_interface_isis_adjacencies_adjacency_neighbor_priority_get_elem(
+ const char *xpath, const void *list_entry)
+{
+ const struct isis_adjacency *adj = list_entry;
+
+ return yang_data_new_uint8(xpath, adj->prio[adj->level - 1]);
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/state
+ */
+static struct yang_data *
+lib_interface_isis_adjacencies_adjacency_state_get_elem(const char *xpath,
+ const void *list_entry)
+{
+ const struct isis_adjacency *adj = list_entry;
+
+ return yang_data_new_string(xpath, isis_yang_adj_state(adj->adj_state));
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/event-counters/adjacency-changes
+ */
+static struct yang_data *
+lib_interface_isis_event_counters_adjacency_changes_get_elem(
+ const char *xpath, const void *list_entry)
+{
+ struct interface *ifp;
+ struct isis_circuit *circuit;
+
+ ifp = (struct interface *)list_entry;
+ if (!ifp)
+ return NULL;
+
+ circuit = circuit_scan_by_ifp(ifp);
+ if (!circuit)
+ return NULL;
+
+ return yang_data_new_uint32(xpath, circuit->adj_state_changes);
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/event-counters/adjacency-number
+ */
+static struct yang_data *
+lib_interface_isis_event_counters_adjacency_number_get_elem(
+ const char *xpath, const void *list_entry)
+{
+ struct interface *ifp;
+ struct isis_circuit *circuit;
+ struct isis_adjacency *adj;
+ struct listnode *node;
+ uint32_t total = 0;
+
+ ifp = (struct interface *)list_entry;
+ if (!ifp)
+ return NULL;
+
+ circuit = circuit_scan_by_ifp(ifp);
+ if (!circuit)
+ return NULL;
+
+ /*
+ * TODO: keep track of the number of adjacencies instead of calculating
+ * it on demand.
+ */
+ switch (circuit->circ_type) {
+ case CIRCUIT_T_BROADCAST:
+ for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) {
+ for (ALL_LIST_ELEMENTS_RO(
+ circuit->u.bc.adjdb[level - 1], node, adj))
+ total++;
+ }
+ break;
+ case CIRCUIT_T_P2P:
+ adj = circuit->u.p2p.neighbor;
+ if (adj)
+ total = 1;
+ break;
+ default:
+ break;
+ }
+
+ return yang_data_new_uint32(xpath, total);
+}
+
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/event-counters/init-fails
+ */
+static struct yang_data *
+lib_interface_isis_event_counters_init_fails_get_elem(const char *xpath,
+ const void *list_entry)
+{
+ struct interface *ifp;
+ struct isis_circuit *circuit;
+
+ ifp = (struct interface *)list_entry;
+ if (!ifp)
+ return NULL;
+
+ circuit = circuit_scan_by_ifp(ifp);
+ if (!circuit)
+ return NULL;
+
+ return yang_data_new_uint32(xpath, circuit->init_failures);
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/event-counters/adjacency-rejects
+ */
+static struct yang_data *
+lib_interface_isis_event_counters_adjacency_rejects_get_elem(
+ const char *xpath, const void *list_entry)
+{
+ struct interface *ifp;
+ struct isis_circuit *circuit;
+
+ ifp = (struct interface *)list_entry;
+ if (!ifp)
+ return NULL;
+
+ circuit = circuit_scan_by_ifp(ifp);
+ if (!circuit)
+ return NULL;
+
+ return yang_data_new_uint32(xpath, circuit->rej_adjacencies);
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/event-counters/id-len-mismatch
+ */
+static struct yang_data *
+lib_interface_isis_event_counters_id_len_mismatch_get_elem(
+ const char *xpath, const void *list_entry)
+{
+ struct interface *ifp;
+ struct isis_circuit *circuit;
+
+ ifp = (struct interface *)list_entry;
+ if (!ifp)
+ return NULL;
+
+ circuit = circuit_scan_by_ifp(ifp);
+ if (!circuit)
+ return NULL;
+
+ return yang_data_new_uint32(xpath, circuit->id_len_mismatches);
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/event-counters/max-area-addresses-mismatch
+ */
+static struct yang_data *
+lib_interface_isis_event_counters_max_area_addresses_mismatch_get_elem(
+ const char *xpath, const void *list_entry)
+{
+ struct interface *ifp;
+ struct isis_circuit *circuit;
+
+ ifp = (struct interface *)list_entry;
+ if (!ifp)
+ return NULL;
+
+ circuit = circuit_scan_by_ifp(ifp);
+ if (!circuit)
+ return NULL;
+
+ return yang_data_new_uint32(xpath, circuit->max_area_addr_mismatches);
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/event-counters/authentication-type-fails
+ */
+static struct yang_data *
+lib_interface_isis_event_counters_authentication_type_fails_get_elem(
+ const char *xpath, const void *list_entry)
+{
+ struct interface *ifp;
+ struct isis_circuit *circuit;
+
+ ifp = (struct interface *)list_entry;
+ if (!ifp)
+ return NULL;
+
+ circuit = circuit_scan_by_ifp(ifp);
+ if (!circuit)
+ return NULL;
+
+ return yang_data_new_uint32(xpath, circuit->auth_type_failures);
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/event-counters/authentication-fails
+ */
+static struct yang_data *
+lib_interface_isis_event_counters_authentication_fails_get_elem(
+ const char *xpath, const void *list_entry)
+{
+ struct interface *ifp;
+ struct isis_circuit *circuit;
+
+ ifp = (struct interface *)list_entry;
+ if (!ifp)
+ return NULL;
+
+ circuit = circuit_scan_by_ifp(ifp);
+ if (!circuit)
+ return NULL;
+
+ return yang_data_new_uint32(xpath, circuit->auth_failures);
+}
+
/*
* NOTIFICATIONS
*/
listnode_add(arguments, data);
snprintf(xpath_arg, sizeof(xpath_arg), "%s/state", xpath);
- switch (new_state) {
- case ISIS_ADJ_DOWN:
- data = yang_data_new_string(xpath_arg, "down");
- break;
- case ISIS_ADJ_UP:
- data = yang_data_new_string(xpath_arg, "up");
- break;
- case ISIS_ADJ_INITIALIZING:
- data = yang_data_new_string(xpath_arg, "init");
- break;
- default:
- data = yang_data_new_string(xpath_arg, "failed");
- }
+ data = yang_data_new_string(xpath_arg, isis_yang_adj_state(new_state));
listnode_add(arguments, data);
if (new_state == ISIS_ADJ_DOWN) {
snprintf(xpath_arg, sizeof(xpath_arg), "%s/reason", xpath);
.modify = lib_interface_isis_multi_topology_ipv6_dstsrc_modify,
},
},
+ {
+ .xpath = "/frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency",
+ .cbs = {
+ .get_next = lib_interface_isis_adjacencies_adjacency_get_next,
+ }
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/neighbor-sys-type",
+ .cbs = {
+ .get_elem = lib_interface_isis_adjacencies_adjacency_neighbor_sys_type_get_elem,
+ }
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/neighbor-sysid",
+ .cbs = {
+ .get_elem = lib_interface_isis_adjacencies_adjacency_neighbor_sysid_get_elem,
+ }
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/neighbor-extended-circuit-id",
+ .cbs = {
+ .get_elem = lib_interface_isis_adjacencies_adjacency_neighbor_extended_circuit_id_get_elem,
+ }
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/neighbor-snpa",
+ .cbs = {
+ .get_elem = lib_interface_isis_adjacencies_adjacency_neighbor_snpa_get_elem,
+ }
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/hold-timer",
+ .cbs = {
+ .get_elem = lib_interface_isis_adjacencies_adjacency_hold_timer_get_elem,
+ }
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/neighbor-priority",
+ .cbs = {
+ .get_elem = lib_interface_isis_adjacencies_adjacency_neighbor_priority_get_elem,
+ }
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/state",
+ .cbs = {
+ .get_elem = lib_interface_isis_adjacencies_adjacency_state_get_elem,
+ }
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/frr-isisd:isis/event-counters/adjacency-changes",
+ .cbs = {
+ .get_elem = lib_interface_isis_event_counters_adjacency_changes_get_elem,
+ }
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/frr-isisd:isis/event-counters/adjacency-number",
+ .cbs = {
+ .get_elem = lib_interface_isis_event_counters_adjacency_number_get_elem,
+ }
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/frr-isisd:isis/event-counters/init-fails",
+ .cbs = {
+ .get_elem = lib_interface_isis_event_counters_init_fails_get_elem,
+ }
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/frr-isisd:isis/event-counters/adjacency-rejects",
+ .cbs = {
+ .get_elem = lib_interface_isis_event_counters_adjacency_rejects_get_elem,
+ }
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/frr-isisd:isis/event-counters/id-len-mismatch",
+ .cbs = {
+ .get_elem = lib_interface_isis_event_counters_id_len_mismatch_get_elem,
+ }
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/frr-isisd:isis/event-counters/max-area-addresses-mismatch",
+ .cbs = {
+ .get_elem = lib_interface_isis_event_counters_max_area_addresses_mismatch_get_elem,
+ }
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/frr-isisd:isis/event-counters/authentication-type-fails",
+ .cbs = {
+ .get_elem = lib_interface_isis_event_counters_authentication_type_fails_get_elem,
+ }
+ },
+ {
+ .xpath = "/frr-interface:lib/interface/frr-isisd:isis/event-counters/authentication-fails",
+ .cbs = {
+ .get_elem = lib_interface_isis_event_counters_authentication_fails_get_elem,
+ }
+ },
{
.xpath = NULL,
},
if (p2p_hello) {
if (circuit->circ_type != CIRCUIT_T_P2P) {
zlog_warn("p2p hello on non p2p circuit");
+ circuit->rej_adjacencies++;
#ifndef FABRICD
isis_notif_reject_adjacency(
circuit, "p2p hello on non p2p circuit",
} else {
if (circuit->circ_type != CIRCUIT_T_BROADCAST) {
zlog_warn("lan hello on non broadcast circuit");
+ circuit->rej_adjacencies++;
#ifndef FABRICD
isis_notif_reject_adjacency(
circuit, "lan hello on non broadcast circuit",
zlog_debug(
"level %d LAN Hello received over circuit with externalDomain = true",
level);
+ circuit->rej_adjacencies++;
#ifndef FABRICD
isis_notif_reject_adjacency(
circuit,
circuit->area->area_tag,
circuit->interface->name);
}
+ circuit->rej_adjacencies++;
#ifndef FABRICD
isis_notif_reject_adjacency(
circuit, "Interface level mismatch", raw_pdu);
"ISIS-Adj (%s): Rcvd %s from (%s) with invalid pdu length %" PRIu16,
circuit->area->area_tag, pdu_name,
circuit->interface->name, iih.pdu_len);
+ circuit->rej_adjacencies++;
#ifndef FABRICD
isis_notif_reject_adjacency(circuit, "Invalid PDU length",
raw_pdu);
flog_err(EC_ISIS_PACKET,
"Level %d LAN Hello with Circuit Type %d", level,
iih.circ_type);
+ circuit->rej_adjacencies++;
#ifndef FABRICD
isis_notif_reject_adjacency(
circuit, "LAN Hello with wrong IS-level", raw_pdu);
if (isis_unpack_tlvs(STREAM_READABLE(circuit->rcv_stream),
circuit->rcv_stream, &iih.tlvs, &error_log)) {
zlog_warn("isis_unpack_tlvs() failed: %s", error_log);
+ circuit->rej_adjacencies++;
#ifndef FABRICD
isis_notif_reject_adjacency(circuit, "Failed to unpack TLVs",
raw_pdu);
if (!iih.tlvs->protocols_supported.count) {
zlog_warn("No supported protocols TLV in %s", pdu_name);
+ circuit->rej_adjacencies++;
#ifndef FABRICD
isis_notif_reject_adjacency(
circuit, "No supported protocols TLV", raw_pdu);
/* send northbound notification */
stream_get_from(raw_pdu, circuit->rcv_stream, pdu_start,
pdu_end - pdu_start);
- if (auth_code == ISIS_AUTH_FAILURE)
+ if (auth_code == ISIS_AUTH_FAILURE) {
+ circuit->auth_failures++;
isis_notif_authentication_failure(circuit, raw_pdu);
- else /* AUTH_TYPE_FAILURE or NO_VALIDATOR */
+ } else { /* AUTH_TYPE_FAILURE or NO_VALIDATOR */
+ circuit->auth_type_failures++;
isis_notif_authentication_type_failure(circuit,
raw_pdu);
+ }
#endif /* ifndef FABRICD */
goto out;
}
zlog_warn(
"ISIS-Adj (%s): Received IIH with own sysid - discard",
circuit->area->area_tag);
+ circuit->rej_adjacencies++;
#ifndef FABRICD
isis_notif_reject_adjacency(
circuit, "Received IIH with our own sysid", raw_pdu);
"ISIS-Adj (%s): Neither IPv4 nor IPv6 considered usable. Ignoring IIH",
circuit->area->area_tag);
}
+ circuit->rej_adjacencies++;
#ifndef FABRICD
isis_notif_reject_adjacency(
circuit, "Neither IPv4 not IPv6 considered usable",
hdr.lsp_id);
#ifndef FABRICD
/* send northbound notification */
- if (auth_code == ISIS_AUTH_FAILURE)
+ if (auth_code == ISIS_AUTH_FAILURE) {
+ circuit->auth_failures++;
isis_notif_authentication_failure(circuit, raw_pdu);
- else /* AUTH_TYPE_FAILURE or NO_VALIDATOR */
+ } else { /* AUTH_TYPE_FAILURE or NO_VALIDATOR */
+ circuit->auth_type_failures++;
isis_notif_authentication_type_failure(circuit,
raw_pdu);
+ }
#endif /* ifndef FABRICD */
goto out;
}
/* send northbound notification */
stream_get_from(raw_pdu, circuit->rcv_stream, pdu_start,
pdu_end - pdu_start);
- if (auth_code == ISIS_AUTH_FAILURE)
+ if (auth_code == ISIS_AUTH_FAILURE) {
+ circuit->auth_failures++;
isis_notif_authentication_failure(circuit,
raw_pdu);
- else /* AUTH_TYPE_FAILURE or NO_VALIDATOR */
+ } else { /* AUTH_TYPE_FAILURE or NO_VALIDATOR */
+ circuit->auth_type_failures++;
isis_notif_authentication_type_failure(circuit,
raw_pdu);
+ }
#endif /* ifndef FABRICD */
goto out;
}
"IDFieldLengthMismatch: ID Length field in a received PDU %" PRIu8
", while the parameter for this IS is %u",
id_len, ISIS_SYS_ID_LEN);
+ circuit->id_len_mismatches++;
#ifndef FABRICD
/* send northbound notification */
isis_notif_id_len_mismatch(circuit, id_len, raw_pdu);
"maximumAreaAddressesMismatch: maximumAreaAdresses in a received PDU %" PRIu8
" while the parameter for this IS is %u",
max_area_addrs, isis->max_area_addrs);
+ circuit->max_area_addr_mismatches++;
#ifndef FABRICD
/* send northbound notification */
isis_notif_max_area_addr_mismatch(circuit, max_area_addrs,
oi = (struct ospf6_interface *)ifp->info;
if (oi == NULL)
return;
- if (oi->area == NULL)
- return;
if (CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE))
return;
oi = (struct ospf6_interface *)THREAD_ARG(thread);
assert(oi && oi->interface);
+ if (!oi->type_cfg)
+ oi->type = ospf6_default_iftype(oi->interface);
+
/*
* Remove old pointer. If this thread wasn't a timer this
* operation won't make a difference, because it is already NULL.
}
/* decide next interface state */
- if ((if_is_pointopoint(oi->interface))
- || (oi->type == OSPF_IFTYPE_POINTOPOINT)) {
+ if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
ospf6_interface_state_change(OSPF6_INTERFACE_POINTTOPOINT, oi);
} else if (oi->priority == 0)
ospf6_interface_state_change(OSPF6_INTERFACE_DROTHER, oi);
}
+static const char *ospf6_iftype_str(uint8_t iftype)
+{
+ switch (iftype) {
+ case OSPF_IFTYPE_LOOPBACK:
+ return "LOOPBACK";
+ case OSPF_IFTYPE_BROADCAST:
+ return "BROADCAST";
+ case OSPF_IFTYPE_POINTOPOINT:
+ return "POINTOPOINT";
+ }
+ return "UNKNOWN";
+}
+
/* show specified interface structure */
static int ospf6_interface_show(struct vty *vty, struct interface *ifp)
{
struct prefix *p;
struct listnode *i;
char strbuf[PREFIX2STR_BUFFER], drouter[32], bdrouter[32];
- const char *type;
+ uint8_t default_iftype;
struct timeval res, now;
char duration[32];
struct ospf6_lsa *lsa;
- /* check physical interface type */
- if (if_is_loopback(ifp))
- type = "LOOPBACK";
- else if (if_is_broadcast(ifp))
- type = "BROADCAST";
- else if (if_is_pointopoint(ifp))
- type = "POINTOPOINT";
- else
- type = "UNKNOWN";
+ default_iftype = ospf6_default_iftype(ifp);
vty_out(vty, "%s is %s, type %s\n", ifp->name,
- (if_is_operative(ifp) ? "up" : "down"), type);
+ (if_is_operative(ifp) ? "up" : "down"),
+ ospf6_iftype_str(default_iftype));
vty_out(vty, " Interface ID: %d\n", ifp->ifindex);
if (ifp->info == NULL) {
} else
oi = (struct ospf6_interface *)ifp->info;
+ if (if_is_operative(ifp) && oi->type != default_iftype)
+ vty_out(vty, " Operating as type %s\n",
+ ospf6_iftype_str(oi->type));
+
vty_out(vty, " Internet Address:\n");
for (ALL_LIST_ELEMENTS_RO(ifp->connected, i, c)) {
}
assert(oi);
+ oi->type_cfg = true;
+
if (strncmp(argv[idx_network]->arg, "b", 1) == 0) {
if (oi->type == OSPF_IFTYPE_BROADCAST)
return CMD_SUCCESS;
return CMD_SUCCESS;
}
+ oi->type_cfg = false;
+
type = ospf6_default_iftype(ifp);
if (oi->type == type) {
return CMD_SUCCESS;
if (oi->mtu_ignore)
vty_out(vty, " ipv6 ospf6 mtu-ignore\n");
- if (oi->type != ospf6_default_iftype(ifp)) {
- if (oi->type == OSPF_IFTYPE_POINTOPOINT)
- vty_out(vty,
- " ipv6 ospf6 network point-to-point\n");
- else if (oi->type == OSPF_IFTYPE_BROADCAST)
- vty_out(vty, " ipv6 ospf6 network broadcast\n");
- }
+ if (oi->type_cfg && oi->type == OSPF_IFTYPE_POINTOPOINT)
+ vty_out(vty, " ipv6 ospf6 network point-to-point\n");
+ else if (oi->type_cfg && oi->type == OSPF_IFTYPE_BROADCAST)
+ vty_out(vty, " ipv6 ospf6 network broadcast\n");
ospf6_bfd_write_config(vty, oi);
/* Network Type */
uint8_t type;
+ bool type_cfg;
/* Router Priority */
uint8_t priority;
snprintf(deadtime, sizeof(deadtime), "%02ld:%02ld:%02ld", h, m, s);
/* Neighbor State */
- if (if_is_pointopoint(on->ospf6_if->interface))
+ if (on->ospf6_if->type == OSPF_IFTYPE_POINTOPOINT)
snprintf(nstate, sizeof(nstate), "PointToPoint");
else {
if (on->router_id == on->drouter)
return SNMP_INTEGER(ntohl(oi->area->area_id));
break;
case OSPFv3IFTYPE:
- if (if_is_broadcast(oi->interface))
+ if (oi->type == OSPF_IFTYPE_BROADCAST)
return SNMP_INTEGER(1);
- else if (if_is_pointopoint(oi->interface))
+ else if (oi->type == OSPF_IFTYPE_POINTOPOINT)
return SNMP_INTEGER(3);
else
break; /* Unknown, don't put anything */
}
if (pnhc->nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX
- || pnhc->nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) {
+ || pnhc->nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) {
/* GATEWAY_IFINDEX type shouldn't resolve to group */
if (pnhi->nhr->nexthop_num > 1) {
ip->ip_id = htons(++ip_id);
ip->ip_hl = 5;
ip->ip_v = 4;
+ ip->ip_tos = IPTOS_PREC_INTERNETCONTROL;
ip->ip_p = PIM_IP_PROTO_PIM;
ip->ip_src = src;
ip->ip_dst = dst;
}
}
+ /* Set Tx socket DSCP byte */
+ if (setsockopt_ipv4_tos(fd, IPTOS_PREC_INTERNETCONTROL)) {
+ zlog_warn("can't set sockopt IP_TOS to PIM/IGMP socket %d: %s",
+ fd, safe_strerror(errno));
+ }
+
return fd;
}
rtrs = ['r1', 'r3', 'r4']
for rtr in rtrs:
- luCommand(rtr, 'ip link show type vrf {}-cust1'.format(rtr),'cust1: .*UP,LOWER_UP','pass','VRF cust1 up')
- luCommand(rtr, 'ip add show vrf {}-cust1'.format(rtr),'r..eth4: .*UP,LOWER_UP.* 192.168','pass','VRF cust1 IP config')
+ luCommand(rtr, 'ip link show type vrf {}-cust1'.format(rtr),'cust1: .*UP','pass','VRF cust1 intf up')
+ luCommand(rtr, 'ip add show vrf {}-cust1'.format(rtr),'r..eth4.*UP','pass','VRF cust1 IP intf up')
+ luCommand(rtr, 'ip add show vrf {}-cust1'.format(rtr),'192.168','pass','VRF cust1 IP config')
luCommand(rtr, 'ip route show vrf {}-cust1'.format(rtr),'192.168...0/24 dev r.-eth','pass','VRF cust1 interface route')
-luCommand('r4', 'ip link show type vrf r4-cust2','cust2: .*UP,LOWER_UP','pass','VRF cust2 up')
-luCommand('r4', 'ip add show vrf r4-cust2','r..eth5.*UP,LOWER_UP.* 192.168','pass','VRF cust1 IP config')
+luCommand('r4', 'ip link show type vrf r4-cust2','cust2: .*UP','pass','VRF cust2 up')
+luCommand('r4', 'ip add show vrf r4-cust2','r..eth5.*UP.* 192.168','pass','VRF cust1 IP config')
luCommand(rtr, 'ip route show vrf r4-cust2'.format(rtr),'192.168...0/24 dev r.-eth','pass','VRF cust2 interface route')
rtrs = ['ce1', 'ce2', 'ce3']
for rtr in rtrs:
luCommand(rtr, 'ip route show','192.168...0/24 dev ce.-eth0','pass','CE interface route')
luCommand(rtr,'ping 192.168.1.1 -c 1',' 0. packet loss','wait','CE->PE ping')
-luCommand('ce4', 'ip link show type vrf ce4-cust2','cust2: .*UP,LOWER_UP','pass','VRF cust2 up')
+luCommand('ce4', 'ip link show type vrf ce4-cust2','cust2: .*UP','pass','VRF cust2 up')
luCommand('ce4', 'ip route show vrf ce4-cust2','192.168...0/24 dev ce.-eth0','pass','CE interface route')
luCommand('ce4','ping 192.168.2.1 -c 1 -I ce4-cust2',' 0. packet loss','wait','CE4->PE4 ping')
+++ /dev/null
-{
- "neighbors":[
- {
- "2.2.2.2":[
- {
- "priority":1,
- "state":"Full/DR",
- "address":"10.0.1.2",
- "ifaceName":"r1-eth1:10.0.1.1",
- "retransmitCounter":0,
- "requestCounter":0,
- "dbSummaryCounter":0
- }
- ]
- },
- {
- "3.3.3.3":[
- {
- "priority":1,
- "state":"Full/DR",
- "address":"10.0.2.3",
- "ifaceName":"r1-eth2:10.0.2.1",
- "retransmitCounter":0,
- "requestCounter":0,
- "dbSummaryCounter":0
- }
- ]
- }
- ]
-}
-
+++ /dev/null
-{
- "2.2.2.2":[
- {
- "priority":1,
- "state":"Full/DR",
- "address":"10.0.1.2",
- "ifaceName":"r1-eth1:10.0.1.1"
- }
- ],
- "3.3.3.3":[
- {
- "priority":1,
- "state":"Full/DR",
- "address":"10.0.2.3",
- "ifaceName":"r1-eth2:10.0.2.1"
- }
- ]
-}
+++ /dev/null
-{
- "2.2.2.2":{
- "priority":1,
- "state":"Full/DR",
- "address":"10.0.1.2",
- "ifaceName":"r1-eth1:10.0.1.1"
- },
- "3.3.3.3":{
- "priority":1,
- "state":"Full/DR",
- "address":"10.0.2.3",
- "ifaceName":"r1-eth2:10.0.2.1"
- }
-}
+++ /dev/null
-{
- "neighbors":[
- {
- "1.1.1.1":[
- {
- "priority":1,
- "state":"Full/Backup",
- "address":"10.0.1.1",
- "ifaceName":"r2-eth1:10.0.1.2",
- "retransmitCounter":0,
- "requestCounter":0,
- "dbSummaryCounter":0
- }
- ]
- },
- {
- "3.3.3.3":[
- {
- "priority":1,
- "state":"Full/DR",
- "address":"10.0.3.3",
- "ifaceName":"r2-eth2:10.0.3.2",
- "retransmitCounter":0,
- "requestCounter":0,
- "dbSummaryCounter":0
- }
- ]
- }
- ]
-}
+++ /dev/null
-{
- "1.1.1.1":[
- {
- "priority":1,
- "state":"Full/Backup",
- "address":"10.0.1.1",
- "ifaceName":"r2-eth1:10.0.1.2"
- }
- ],
- "3.3.3.3":[
- {
- "priority":1,
- "state":"Full/DR",
- "address":"10.0.3.3",
- "ifaceName":"r2-eth2:10.0.3.2"
- }
- ]
-}
+++ /dev/null
-{
- "1.1.1.1":{
- "priority":1,
- "state":"Full/Backup",
- "address":"10.0.1.1",
- "ifaceName":"r2-eth1:10.0.1.2"
- },
- "3.3.3.3":{
- "priority":1,
- "state":"Full/DR",
- "address":"10.0.3.3",
- "ifaceName":"r2-eth2:10.0.3.2"
- }
-}
+++ /dev/null
-{
- "neighbors":[
- {
- "1.1.1.1":[
- {
- "priority":1,
- "state":"Full/Backup",
- "address":"10.0.2.1",
- "ifaceName":"r3-eth1:10.0.2.3",
- "retransmitCounter":0,
- "requestCounter":0,
- "dbSummaryCounter":0
- }
- ]
- },
- {
- "2.2.2.2":[
- {
- "priority":1,
- "state":"Full/Backup",
- "address":"10.0.3.2",
- "ifaceName":"r3-eth2:10.0.3.3",
- "retransmitCounter":0,
- "requestCounter":0,
- "dbSummaryCounter":0
- }
- ]
- }
- ]
-}
+++ /dev/null
-{
- "1.1.1.1":[
- {
- "priority":1,
- "state":"Full/Backup",
- "address":"10.0.2.1",
- "ifaceName":"r3-eth1:10.0.2.3"
- }
- ],
- "2.2.2.2":[
- {
- "priority":1,
- "state":"Full/Backup",
- "address":"10.0.3.2",
- "ifaceName":"r3-eth2:10.0.3.3"
- }
- ]
-}
+++ /dev/null
-{
- "1.1.1.1":{
- "priority":1,
- "state":"Full/Backup",
- "address":"10.0.2.1",
- "ifaceName":"r3-eth1:10.0.2.3"
- },
- "2.2.2.2":{
- "priority":1,
- "state":"Full/Backup",
- "address":"10.0.3.2",
- "ifaceName":"r3-eth2:10.0.3.3"
- }
-}
)
tgen.start_router()
- for router in router_list.values():
- if router.has_version('<', '3'):
- tgen.set_error('unsupported version')
def teardown_module(mod):
"Teardown the pytest environment"
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
- # Old output (before FRR PR1383) didn't show a list of neighbors.
- # Check for dict object and compare to old output if this is the case
- tgen = get_topogen()
- router = tgen.gears['r1']
- output = router.vtysh_cmd("show ip ospf neighbor json", isjson=True)
-
- # We could have either old format (without "neighbors" and direct list
- # of IP's or new format from PR1659 with "neighbors".
- # Trying old formats first and fall back to new format
- #
- # New format: neighbors have dict instead of list of dicts (PR1723).
- if output.has_key('neighbors'):
- if isinstance(output['neighbors'], dict):
- reffile = "show_ip_ospf_neighbor.json"
- else:
- reffile = "show_ip_ospf_neighbor.ref"
- else:
- if isinstance(output["2.2.2.2"], dict):
- reffile = "show_ip_ospf_neighbor.ref-old-nolist"
- else:
- reffile = "show_ip_ospf_neighbor.ref-no-neigh"
-
for rname in ['r1', 'r2', 'r3']:
- router_compare_json_output(rname, "show ip ospf neighbor json", reffile)
+ router_compare_json_output(rname, "show ip ospf neighbor json", "show_ip_ospf_neighbor.json")
def test_rib():
logger.info("Test: verify RIB")
return CMD_SUCCESS;
}
+/* Northbound. */
+DEFUN (show_yang_operational_data,
+ show_yang_operational_data_cmd,
+ "show yang operational-data XPATH$xpath\
+ [{\
+ format <json$json|xml$xml>\
+ |translate WORD$translator_family\
+ }]" DAEMONS_LIST,
+ SHOW_STR
+ "YANG information\n"
+ "Show YANG operational data\n"
+ "XPath expression specifying the YANG data path\n"
+ "Set the output format\n"
+ "JavaScript Object Notation\n"
+ "Extensible Markup Language\n"
+ "Translate operational data\n"
+ "YANG module translator\n"
+ DAEMONS_STR)
+{
+ int idx_protocol = argc - 1;
+ char *fcmd = argv_concat(argv, argc - 1, 0);
+ int ret = vtysh_client_execute_name(argv[idx_protocol]->text, fcmd);
+ XFREE(MTYPE_TMP, fcmd);
+ return ret;
+}
+
+DEFUNSH(VTYSH_ALL, debug_nb,
+ debug_nb_cmd,
+ "[no] debug northbound\
+ [<\
+ callbacks$cbs [{configuration$cbs_cfg|state$cbs_state|rpc$cbs_rpc}]\
+ |notifications$notifications\
+ |events$events\
+ >]",
+ NO_STR
+ DEBUG_STR
+ "Northbound debugging\n"
+ "Callbacks\n"
+ "Configuration\n"
+ "State\n"
+ "RPC\n"
+ "Notifications\n"
+ "Events\n")
+{
+ return CMD_SUCCESS;
+}
+
/* Memory */
DEFUN (vtysh_show_memory,
vtysh_show_memory_cmd,
}
DEFUNSH(VTYSH_ALL, no_vtysh_log_facility, no_vtysh_log_facility_cmd,
- "no log facility [FACILITY]", NO_STR
+ "no log facility [<kern|user|mail|daemon|auth|syslog|lpr|news|uucp|cron|local0|local1|local2|local3|local4|local5|local6|local7>]",
+ NO_STR
"Logging control\n"
"Reset syslog facility to default (daemon)\n"
- "Syslog facility\n")
+ LOG_FACILITY_DESC)
{
return CMD_SUCCESS;
}
install_element(ENABLE_NODE, &vtysh_debug_memstats_cmd);
install_element(CONFIG_NODE, &vtysh_debug_memstats_cmd);
+ /* northbound */
+ install_element(VIEW_NODE, &show_yang_operational_data_cmd);
+ install_element(ENABLE_NODE, &debug_nb_cmd);
+ install_element(CONFIG_NODE, &debug_nb_cmd);
+
/* misc lib show commands */
install_element(VIEW_NODE, &vtysh_show_memory_cmd);
install_element(VIEW_NODE, &vtysh_show_modules_cmd);
"This type defines IS-IS level of an object.";
}
+ typedef extended-circuit-id {
+ type uint32;
+ description
+ "This type defines the extended circuit ID
+ associated with an interface.";
+ }
+
typedef network-type {
type enumeration {
enum "unknown" {
pattern, An example LSP ID is 0143.0438.AeF0.02-01";
}
+ typedef snpa {
+ type string {
+ length "0 .. 20";
+ }
+ description
+ "This type defines the Subnetwork Point
+ of Attachment (SNPA) format.
+ The SNPA should be encoded according to the rules
+ specified for the particular type of subnetwork
+ being used. As an example, for an ethernet subnetwork,
+ the SNPA is encoded as a MAC address like
+ '00aa.bbcc.ddee'.";
+ }
+
typedef system-id {
type string {
pattern "[0-9A-Fa-f]{4}\\.[0-9A-Fa-f]{4}\\.[0-9A-Fa-f]{4}";
}
}
+ grouping interface-config {
+ description "Interface configuration grouping";
+
+ leaf area-tag {
+ type string;
+ mandatory true;
+ description
+ "Area-tag associated to this circuit.";
+ }
+
+ leaf ipv4-routing {
+ type boolean;
+ default "false";
+ description
+ "Routing IS-IS IPv4 traffic over this circuit.";
+ }
+
+ leaf ipv6-routing {
+ type boolean;
+ default "false";
+ description
+ "Routing IS-IS IPv6 traffic over this circuit.";
+ }
+
+ leaf circuit-type {
+ type level;
+ default "level-1-2";
+ description
+ "IS-type of this circuit.";
+ }
+
+ leaf bfd-monitoring {
+ type boolean;
+ default false;
+ description "Monitor IS-IS peers on this circuit.";
+ }
+
+ container csnp-interval {
+ description
+ "Complete Sequence Number PDU (CSNP) generation interval.";
+ leaf level-1 {
+ type uint16 {
+ range "1..600";
+ }
+ units "seconds";
+ default "10";
+ description
+ "CNSP interval for level-1";
+ }
+
+ leaf level-2 {
+ type uint16 {
+ range "1..600";
+ }
+ units "seconds";
+ default "10";
+ description
+ "CNSP interval for level-2";
+ }
+ }
+
+ container psnp-interval {
+ description
+ "Partial Sequence Number PDU (PSNP) generation interval.";
+ leaf level-1 {
+ type uint16 {
+ range "1..120";
+ }
+ units "seconds";
+ default "2";
+ description
+ "PNSP interval for level-1";
+ }
+
+ leaf level-2 {
+ type uint16 {
+ range "1..120";
+ }
+ units "seconds";
+ default "2";
+ description
+ "PCNSP interval for level-2";
+ }
+ }
+
+ container hello {
+ description
+ "Parameters related to IS-IS hello PDUs.";
+ leaf padding {
+ type boolean;
+ default "true";
+ description
+ "Add padding to IS-IS hello PDUs.";
+ }
+
+ container interval {
+ description
+ "Interval between consecutive hello messages.";
+ leaf level-1 {
+ type uint32 {
+ range "1..600";
+ }
+ units "seconds";
+ default "3";
+ description
+ "Holding time for level-1; interval will depend on multiplier.";
+ }
+
+ leaf level-2 {
+ type uint32 {
+ range "1..600";
+ }
+ units "seconds";
+ default "3";
+ description
+ "Holding time for level-2; interval will depend on multiplier.";
+ }
+ }
+
+ container multiplier {
+ description
+ "Multiplier for the hello messages holding time.";
+ leaf level-1 {
+ type uint16 {
+ range "2..100";
+ }
+ default "10";
+ description
+ "Multiplier for the hello holding time.";
+ }
+
+ leaf level-2 {
+ type uint16 {
+ range "2..100";
+ }
+ default "10";
+ description
+ "Multiplier for the hello holding time.";
+ }
+ }
+ }
+
+ container metric {
+ description
+ "Default metric for this IS-IS circuit.";
+ leaf level-1 {
+ type uint32 {
+ range "0..16777215";
+ }
+ must ". < 64 or /frr-isisd:isis/instance[area-tag = current()/../../area-tag]/metric-style = 'wide'";
+ default "10";
+ description
+ "Default level-1 metric for this IS-IS circuit.";
+ }
+
+ leaf level-2 {
+ type uint32 {
+ range "0..16777215";
+ }
+ must ". < 64 or /frr-isisd:isis/instance[area-tag = current()/../../area-tag]/metric-style = 'wide'";
+ default "10";
+ description
+ "Default level-2 metric for this IS-IS circuit.";
+ }
+ }
+
+ container priority {
+ description
+ "Priority for Designated Router election.";
+ leaf level-1 {
+ type uint8 {
+ range "0..127";
+ }
+ default "64";
+ description
+ "Level-1 priority for this IS-IS circuit.";
+ }
+
+ leaf level-2 {
+ type uint8 {
+ range "0..127";
+ }
+ default "64";
+ description
+ "Level-2 priority for this IS-IS circuit.";
+ }
+ }
+
+ leaf network-type {
+ type network-type;
+ default "broadcast";
+ must "(. = \"point-to-point\") or (. = \"broadcast\")";
+ description
+ "Explicitly configured type of IS-IS circuit (broadcast or point-to-point).";
+ }
+
+ leaf passive {
+ type boolean;
+ default "false";
+ description
+ "Interface is in passive mode.";
+ }
+
+ container password {
+ presence "Present if a password is set for this IS interface.";
+ uses isis-password;
+ }
+
+ leaf disable-three-way-handshake {
+ type boolean;
+ default "false";
+ description
+ "Disables three-way handshake when creating new adjacencies.";
+ }
+
+ container multi-topology {
+ description
+ "IS-IS topologies configured on this circuit.";
+ leaf ipv4-unicast {
+ type boolean;
+ default "true";
+ description
+ "IPv4 unicast topology.";
+ }
+
+ leaf ipv4-multicast {
+ type boolean;
+ default "true";
+ description
+ "IPv4 multicast topology.";
+ }
+
+ leaf ipv4-management {
+ type boolean;
+ default "true";
+ description
+ "IPv4 management topology.";
+ }
+
+ leaf ipv6-unicast {
+ type boolean;
+ default "true";
+ description
+ "IPv6 unicast topology.";
+ }
+
+ leaf ipv6-multicast {
+ type boolean;
+ default "true";
+ description
+ "IPv6 multicast topology.";
+ }
+
+ leaf ipv6-management {
+ type boolean;
+ default "true";
+ description
+ "IPv6 management topology.";
+ }
+
+ leaf ipv6-dstsrc {
+ type boolean;
+ default "true";
+ description
+ "IPv6 destination-source topology.";
+ }
+ }
+ }
+
+ grouping adjacency-state {
+ container adjacencies {
+ config false;
+ list adjacency {
+ leaf neighbor-sys-type {
+ type level;
+ description
+ "Level capability of neighboring system";
+ }
+ leaf neighbor-sysid {
+ type system-id;
+ description
+ "The system-id of the neighbor";
+ }
+ leaf neighbor-extended-circuit-id {
+ type extended-circuit-id;
+ description
+ "Circuit ID of the neighbor";
+ }
+ leaf neighbor-snpa {
+ type snpa;
+ description
+ "SNPA of the neighbor";
+ }
+ leaf hold-timer {
+ type uint16;
+ units seconds;
+ description
+ "The holding time in seconds for this
+ adjacency. This value is based on
+ received hello PDUs and the elapsed
+ time since receipt.";
+ }
+ leaf neighbor-priority {
+ type uint8 {
+ range "0 .. 127";
+ }
+ description
+ "Priority of the neighboring IS for becoming
+ the DIS.";
+ }
+ leaf state {
+ type adj-state-type;
+ description
+ "This leaf describes the state of the interface.";
+ }
+
+ description
+ "List of operational adjacencies.";
+ }
+ description
+ "This container lists the adjacencies of
+ the local node.";
+ }
+ description
+ "Adjacency state";
+ }
+
+ grouping event-counters {
+ container event-counters {
+ config false;
+ leaf adjacency-changes {
+ type uint32;
+ description
+ "The number of times an adjacency state change has
+ occurred on this interface.";
+ }
+ leaf adjacency-number {
+ type uint32;
+ description
+ "The number of adjacencies on this interface.";
+ }
+ leaf init-fails {
+ type uint32;
+ description
+ "The number of times initialization of this
+ interface has failed. This counts events such
+ as PPP NCP failures. Failures to form an
+ adjacency are counted by adjacency-rejects.";
+ }
+ leaf adjacency-rejects {
+ type uint32;
+ description
+ "The number of times an adjacency has been
+ rejected on this interface.";
+ }
+ leaf id-len-mismatch {
+ type uint32;
+ description
+ "The number of times an IS-IS PDU with an ID
+ field length different from that for this
+ system has been received on this interface.";
+ }
+ leaf max-area-addresses-mismatch {
+ type uint32;
+ description
+ "The number of times an IS-IS PDU has been
+ received on this interface with the
+ max area address field differing from that of
+ this system.";
+ }
+ leaf authentication-type-fails {
+ type uint32;
+ description
+ "Number of authentication type mismatches.";
+ }
+ leaf authentication-fails {
+ type uint32;
+ description
+ "Number of authentication key failures.";
+ }
+ description "IS-IS interface event counters.";
+ }
+ description
+ "Grouping for IS-IS interface event counters";
+ }
+
+ grouping interface-state {
+ description
+ "IS-IS interface operational state.";
+ uses adjacency-state;
+ uses event-counters;
+ }
+
grouping notification-instance-hdr {
description
"Instance specific IS-IS notification data grouping";
}
leaf extended-circuit-id {
- type uint32;
+ type extended-circuit-id;
description
"Eextended circuit-id of the interface.";
}
presence "Present if an IS-IS circuit is defined for this interface.";
description
"IS-IS interface parameters.";
- leaf area-tag {
- type string;
- mandatory true;
- description
- "Area-tag associated to this circuit.";
- }
-
- leaf ipv4-routing {
- type boolean;
- default "false";
- description
- "Routing IS-IS IPv4 traffic over this circuit.";
- }
-
- leaf ipv6-routing {
- type boolean;
- default "false";
- description
- "Routing IS-IS IPv6 traffic over this circuit.";
- }
-
- leaf circuit-type {
- type level;
- default "level-1-2";
- description
- "IS-type of this circuit.";
- }
-
- leaf bfd-monitoring {
- type boolean;
- default false;
- description "Monitor IS-IS peers on this circuit.";
- }
-
- container csnp-interval {
- description
- "Complete Sequence Number PDU (CSNP) generation interval.";
- leaf level-1 {
- type uint16 {
- range "1..600";
- }
- units "seconds";
- default "10";
- description
- "CNSP interval for level-1";
- }
-
- leaf level-2 {
- type uint16 {
- range "1..600";
- }
- units "seconds";
- default "10";
- description
- "CNSP interval for level-2";
- }
- }
-
- container psnp-interval {
- description
- "Partial Sequence Number PDU (PSNP) generation interval.";
- leaf level-1 {
- type uint16 {
- range "1..120";
- }
- units "seconds";
- default "2";
- description
- "PNSP interval for level-1";
- }
-
- leaf level-2 {
- type uint16 {
- range "1..120";
- }
- units "seconds";
- default "2";
- description
- "PCNSP interval for level-2";
- }
- }
-
- container hello {
- description
- "Parameters related to IS-IS hello PDUs.";
- leaf padding {
- type boolean;
- default "true";
- description
- "Add padding to IS-IS hello PDUs.";
- }
-
- container interval {
- description
- "Interval between consecutive hello messages.";
- leaf level-1 {
- type uint32 {
- range "1..600";
- }
- units "seconds";
- default "3";
- description
- "Holding time for level-1; interval will depend on multiplier.";
- }
-
- leaf level-2 {
- type uint32 {
- range "1..600";
- }
- units "seconds";
- default "3";
- description
- "Holding time for level-2; interval will depend on multiplier.";
- }
- }
-
- container multiplier {
- description
- "Multiplier for the hello messages holding time.";
- leaf level-1 {
- type uint16 {
- range "2..100";
- }
- default "10";
- description
- "Multiplier for the hello holding time.";
- }
-
- leaf level-2 {
- type uint16 {
- range "2..100";
- }
- default "10";
- description
- "Multiplier for the hello holding time.";
- }
- }
- }
-
- container metric {
- description
- "Default metric for this IS-IS circuit.";
- leaf level-1 {
- type uint32 {
- range "0..16777215";
- }
- must ". < 64 or /frr-isisd:isis/instance[area-tag = current()/../../area-tag]/metric-style = 'wide'";
- default "10";
- description
- "Default level-1 metric for this IS-IS circuit.";
- }
-
- leaf level-2 {
- type uint32 {
- range "0..16777215";
- }
- must ". < 64 or /frr-isisd:isis/instance[area-tag = current()/../../area-tag]/metric-style = 'wide'";
- default "10";
- description
- "Default level-2 metric for this IS-IS circuit.";
- }
- }
-
- container priority {
- description
- "Priority for Designated Router election.";
- leaf level-1 {
- type uint8 {
- range "0..127";
- }
- default "64";
- description
- "Level-1 priority for this IS-IS circuit.";
- }
-
- leaf level-2 {
- type uint8 {
- range "0..127";
- }
- default "64";
- description
- "Level-2 priority for this IS-IS circuit.";
- }
- }
-
- leaf network-type {
- type network-type;
- default "broadcast";
- must "(. = \"point-to-point\") or (. = \"broadcast\")";
- description
- "Explicitly configured type of IS-IS circuit (broadcast or point-to-point).";
- }
-
- leaf passive {
- type boolean;
- default "false";
- description
- "Interface is in passive mode.";
- }
-
- container password {
- presence "Present if a password is set for this IS interface.";
- uses isis-password;
- }
-
- leaf disable-three-way-handshake {
- type boolean;
- default "false";
- description
- "Disables three-way handshake when creating new adjacencies.";
- }
-
- container multi-topology {
- description
- "IS-IS topologies configured on this circuit.";
- leaf ipv4-unicast {
- type boolean;
- default "true";
- description
- "IPv4 unicast topology.";
- }
-
- leaf ipv4-multicast {
- type boolean;
- default "true";
- description
- "IPv4 multicast topology.";
- }
-
- leaf ipv4-management {
- type boolean;
- default "true";
- description
- "IPv4 management topology.";
- }
-
- leaf ipv6-unicast {
- type boolean;
- default "true";
- description
- "IPv6 unicast topology.";
- }
-
- leaf ipv6-multicast {
- type boolean;
- default "true";
- description
- "IPv6 multicast topology.";
- }
-
- leaf ipv6-management {
- type boolean;
- default "true";
- description
- "IPv6 management topology.";
- }
-
- leaf ipv6-dstsrc {
- type boolean;
- default "true";
- description
- "IPv6 destination-source topology.";
- }
- }
+ uses interface-config;
+ uses interface-state;
}
}
}
}
-static int get_iflink_speed(struct interface *interface)
+static int get_iflink_speed(struct interface *interface, int *error)
{
struct ifreq ifdata;
struct ethtool_cmd ecmd;
int rc;
const char *ifname = interface->name;
+ if (error)
+ *error = 0;
/* initialize struct */
memset(&ifdata, 0, sizeof(ifdata));
if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug("Failure to read interface %s speed: %d %s",
ifname, errno, safe_strerror(errno));
+ /* no vrf socket creation may probably mean vrf issue */
+ if (error)
+ *error = -1;
return 0;
}
/* Get the current link state for the interface */
zlog_debug(
"IOCTL failure to read interface %s speed: %d %s",
ifname, errno, safe_strerror(errno));
+ /* no device means interface unreachable */
+ if (errno == ENODEV && error)
+ *error = -1;
ecmd.speed_hi = 0;
ecmd.speed = 0;
}
return (ecmd.speed_hi << 16) | ecmd.speed;
}
-uint32_t kernel_get_speed(struct interface *ifp)
+uint32_t kernel_get_speed(struct interface *ifp, int *error)
{
- return get_iflink_speed(ifp);
+ return get_iflink_speed(ifp, error);
}
static int netlink_extract_bridge_info(struct rtattr *link_data,
ifp->flags = ifi->ifi_flags & 0x0000fffff;
ifp->mtu6 = ifp->mtu = *(uint32_t *)RTA_DATA(tb[IFLA_MTU]);
ifp->metric = 0;
- ifp->speed = get_iflink_speed(ifp);
+ ifp->speed = get_iflink_speed(ifp, NULL);
ifp->ptm_status = ZEBRA_PTM_STATUS_UNKNOWN;
/* Set zebra interface type */
struct zebra_if *zif = ifp->info;
uint32_t new_speed;
bool changed = false;
+ int error = 0;
zif->speed_update = NULL;
- new_speed = kernel_get_speed(ifp);
+ new_speed = kernel_get_speed(ifp, &error);
+
+ /* error may indicate vrf not available or
+ * interfaces not available.
+ * note that loopback & virtual interfaces can return 0 as speed
+ */
+ if (error < 0)
+ return 1;
+
if (new_speed != ifp->speed) {
zlog_info("%s: %s old speed: %u new speed: %u",
__PRETTY_FUNCTION__, ifp->name, ifp->speed,
extern int mpls_kernel_init(void);
-extern uint32_t kernel_get_speed(struct interface *ifp);
+extern uint32_t kernel_get_speed(struct interface *ifp, int *error);
extern int kernel_get_ipmr_sg_stats(struct zebra_vrf *zvrf, void *mroute);
/*
static int netlink_neigh_update(int cmd, int ifindex, uint32_t addr, char *lla,
int llalen, ns_id_t ns_id)
{
+ uint8_t protocol = RTPROT_ZEBRA;
struct {
struct nlmsghdr n;
struct ndmsg ndm;
req.ndm.ndm_ifindex = ifindex;
req.ndm.ndm_type = RTN_UNICAST;
+ addattr_l(&req.n, sizeof(req),
+ NDA_PROTOCOL, &protocol, sizeof(protocol));
addattr_l(&req.n, sizeof(req), NDA_DST, &addr, 4);
addattr_l(&req.n, sizeof(req), NDA_LLADDR, lla, llalen);
static int netlink_vxlan_flood_update_ctx(const struct zebra_dplane_ctx *ctx,
int cmd)
{
+ uint8_t protocol = RTPROT_ZEBRA;
struct {
struct nlmsghdr n;
struct ndmsg ndm;
req.ndm.ndm_flags |= NTF_SELF; // Handle by "self", not "master"
+ addattr_l(&req.n, sizeof(req),
+ NDA_PROTOCOL, &protocol, sizeof(protocol));
addattr_l(&req.n, sizeof(req), NDA_LLADDR, &dst_mac, 6);
req.ndm.ndm_ifindex = dplane_ctx_get_ifindex(ctx);
static enum zebra_dplane_result
netlink_macfdb_update_ctx(struct zebra_dplane_ctx *ctx)
{
+ uint8_t protocol = RTPROT_ZEBRA;
struct {
struct nlmsghdr n;
struct ndmsg ndm;
else
req.ndm.ndm_flags |= NTF_EXT_LEARNED;
+ addattr_l(&req.n, sizeof(req),
+ NDA_PROTOCOL, &protocol, sizeof(protocol));
addattr_l(&req.n, sizeof(req), NDA_LLADDR,
dplane_ctx_mac_get_addr(ctx), 6);
req.ndm.ndm_ifindex = dplane_ctx_get_ifindex(ctx);
static int netlink_neigh_update_ctx(const struct zebra_dplane_ctx *ctx,
int cmd)
{
+ uint8_t protocol = RTPROT_ZEBRA;
struct {
struct nlmsghdr n;
struct ndmsg ndm;
req.ndm.ndm_type = RTN_UNICAST;
req.ndm.ndm_flags = flags;
+ addattr_l(&req.n, sizeof(req),
+ NDA_PROTOCOL, &protocol, sizeof(protocol));
ipa_len = IS_IPADDR_V4(ip) ? IPV4_MAX_BYTELEN : IPV6_MAX_BYTELEN;
addattr_l(&req.n, sizeof(req), NDA_DST, &ip->ip.addr, ipa_len);
if (mac)
return 0;
}
-uint32_t kernel_get_speed(struct interface *ifp)
+uint32_t kernel_get_speed(struct interface *ifp, int *error)
{
return ifp->speed;
}
*/
static int netlink_rule_update(int cmd, struct zebra_pbr_rule *rule)
{
+ uint8_t protocol = RTPROT_ZEBRA;
int family;
int bytelen;
struct {
req.frh.family = family;
req.frh.action = FR_ACT_TO_TBL;
+ addattr_l(&req.n, sizeof(req),
+ FRA_PROTOCOL, &protocol, sizeof(protocol));
+
/* rule's pref # */
addattr32(&req.n, sizeof(req), FRA_PRIORITY, rule->rule.priority);
changed_p = true;
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
- break;
+
+ /* Keep checking nexthops */
+ continue;
}
if (CHECK_FLAG(ctx_nexthop->flags, NEXTHOP_FLAG_FIB)) {
* not-installed; or not-installed to installed.
*/
if (start_count > 0 && end_count > 0) {
+ if (debug_p)
+ zlog_debug("%u:%s applied nexthop changes from dplane notification",
+ dplane_ctx_get_vrf(ctx), dest_str);
/* Changed nexthops - update kernel/others */
dplane_route_notif_update(rn, re,
if (zvni->advertise_svi_macip == advertise)
return;
+ /* Store flag even though SVI is not present.
+ * Once SVI comes up triggers self MAC-IP route add.
+ */
+ zvni->advertise_svi_macip = advertise;
+
ifp = zvni->vxlan_if;
if (!ifp)
return;
return;
zl2_info = zif->l2info.vxl;
-
vlan_if = zvni_map_to_svi(zl2_info.access_vlan,
zif->brslave_info.br_if);
if (!vlan_if)
return;
if (advertise) {
- zvni->advertise_svi_macip = advertise;
/* Add primary SVI MAC-IP */
zvni_add_macip_for_intf(vlan_if, zvni);
} else {
- /* Del primary MAC-IP */
+ /* Del primary SVI MAC-IP */
zvni_del_macip_for_intf(vlan_if, zvni);
- zvni->advertise_svi_macip = advertise;
}
}