summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_bmp.c9
-rw-r--r--bgpd/bgp_flowspec.c7
-rw-r--r--bgpd/bgp_route.h2
-rw-r--r--doc/user/ospfd.rst6
-rw-r--r--lib/libfrr.c2
-rw-r--r--lib/northbound.c19
-rw-r--r--lib/northbound.h22
-rw-r--r--lib/northbound_cli.c11
-rw-r--r--lib/northbound_confd.c2
-rw-r--r--lib/northbound_db.c2
-rw-r--r--lib/northbound_grpc.cpp4
-rw-r--r--lib/northbound_sysrepo.c2
-rw-r--r--lib/prefix.c17
-rw-r--r--lib/prefix.h1
-rw-r--r--lib/vty.c9
-rw-r--r--lib/vty.h2
-rw-r--r--ospfd/ospf_dump.c7
-rw-r--r--ospfd/ospf_dump.h2
-rw-r--r--ospfd/ospf_vty.c412
-rw-r--r--pimd/pim_mroute.c76
20 files changed, 361 insertions, 253 deletions
diff --git a/bgpd/bgp_bmp.c b/bgpd/bgp_bmp.c
index d89f6de649..92d92ada2b 100644
--- a/bgpd/bgp_bmp.c
+++ b/bgpd/bgp_bmp.c
@@ -2498,14 +2498,13 @@ static int bmp_config_write(struct bgp *bgp, struct vty *vty)
vty_out(vty, " bmp mirror\n");
FOREACH_AFI_SAFI (afi, safi) {
- const char *afi_str = (afi == AFI_IP) ? "ipv4" : "ipv6";
-
if (bt->afimon[afi][safi] & BMP_MON_PREPOLICY)
vty_out(vty, " bmp monitor %s %s pre-policy\n",
- afi_str, safi2str(safi));
+ afi2str_lower(afi), safi2str(safi));
if (bt->afimon[afi][safi] & BMP_MON_POSTPOLICY)
- vty_out(vty, " bmp monitor %s %s post-policy\n",
- afi_str, safi2str(safi));
+ vty_out(vty,
+ " bmp monitor %s %s post-policy\n",
+ afi2str_lower(afi), safi2str(safi));
}
frr_each (bmp_listeners, &bt->listeners, bl)
vty_out(vty, " \n bmp listener %pSU port %d\n",
diff --git a/bgpd/bgp_flowspec.c b/bgpd/bgp_flowspec.c
index 8d5ca5e777..f9debe43cd 100644
--- a/bgpd/bgp_flowspec.c
+++ b/bgpd/bgp_flowspec.c
@@ -127,6 +127,13 @@ int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr,
psize);
return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
}
+
+ if (psize == 0) {
+ flog_err(EC_BGP_FLOWSPEC_PACKET,
+ "Flowspec NLRI length 0 which makes no sense");
+ return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
+ }
+
if (bgp_fs_nlri_validate(pnt, psize, afi) < 0) {
flog_err(
EC_BGP_FLOWSPEC_PACKET,
diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h
index d0cf7e5d77..66cc62ab09 100644
--- a/bgpd/bgp_route.h
+++ b/bgpd/bgp_route.h
@@ -67,7 +67,7 @@ enum bgp_show_adj_route_type {
#define BGP_SHOW_RPKI_HEADER \
"RPKI validation codes: V valid, I invalid, N Not found\n\n"
#define BGP_SHOW_HEADER " Network Next Hop Metric LocPrf Weight Path\n"
-#define BGP_SHOW_HEADER_WIDE " Network Next Hop Metric LocPrf Weight Path\n"
+#define BGP_SHOW_HEADER_WIDE " Network Next Hop Metric LocPrf Weight Path\n"
/* Maximum number of labels we can process or send with a prefix. We
* really do only 1 for MPLS (BGP-LU) but we can do 2 for EVPN-VxLAN.
diff --git a/doc/user/ospfd.rst b/doc/user/ospfd.rst
index b69230b99d..ce3648bf6d 100644
--- a/doc/user/ospfd.rst
+++ b/doc/user/ospfd.rst
@@ -794,13 +794,13 @@ Showing Information
.. clicmd:: show ip ospf neighbor [json]
-.. clicmd:: show ip ospf neighbor INTERFACE [json]
+.. clicmd:: show ip ospf [vrf <NAME|all>] neighbor INTERFACE [json]
.. clicmd:: show ip ospf neighbor detail [json]
-.. clicmd:: show ip ospf neighbor A.B.C.D [detail] [json]
+.. clicmd:: show ip ospf [vrf <NAME|all>] neighbor A.B.C.D [detail] [json]
-.. clicmd:: show ip ospf neighbor INTERFACE detail [json]
+.. clicmd:: show ip ospf [vrf <NAME|all>] neighbor INTERFACE detail [json]
Display lsa information of LSDB.
Json o/p of this command covers base route information
diff --git a/lib/libfrr.c b/lib/libfrr.c
index 0467dc1d7e..d1b7dd133e 100644
--- a/lib/libfrr.c
+++ b/lib/libfrr.c
@@ -992,7 +992,7 @@ static void frr_config_read_in(struct thread *t)
int ret;
context.client = NB_CLIENT_CLI;
- ret = nb_candidate_commit(&context, vty_shared_candidate_config,
+ ret = nb_candidate_commit(context, vty_shared_candidate_config,
true, "Read configuration file", NULL,
errmsg, sizeof(errmsg));
if (ret != NB_OK && ret != NB_ERR_NO_CHANGES)
diff --git a/lib/northbound.c b/lib/northbound.c
index b755264be1..6f2c522a29 100644
--- a/lib/northbound.c
+++ b/lib/northbound.c
@@ -61,7 +61,7 @@ static int nb_callback_configuration(struct nb_context *context,
struct nb_config_change *change,
char *errmsg, size_t errmsg_len);
static struct nb_transaction *
-nb_transaction_new(struct nb_context *context, struct nb_config *config,
+nb_transaction_new(struct nb_context context, struct nb_config *config,
struct nb_config_cbs *changes, const char *comment,
char *errmsg, size_t errmsg_len);
static void nb_transaction_free(struct nb_transaction *transaction);
@@ -835,7 +835,7 @@ int nb_candidate_validate(struct nb_context *context,
return ret;
}
-int nb_candidate_commit_prepare(struct nb_context *context,
+int nb_candidate_commit_prepare(struct nb_context context,
struct nb_config *candidate,
const char *comment,
struct nb_transaction **transaction,
@@ -860,9 +860,8 @@ int nb_candidate_commit_prepare(struct nb_context *context,
return NB_ERR_NO_CHANGES;
}
- if (nb_candidate_validate_code(context, candidate, &changes, errmsg,
- errmsg_len)
- != NB_OK) {
+ if (nb_candidate_validate_code(&context, candidate, &changes, errmsg,
+ errmsg_len) != NB_OK) {
flog_warn(EC_LIB_NB_CANDIDATE_INVALID,
"%s: failed to validate candidate configuration",
__func__);
@@ -913,7 +912,7 @@ void nb_candidate_commit_apply(struct nb_transaction *transaction,
nb_transaction_free(transaction);
}
-int nb_candidate_commit(struct nb_context *context, struct nb_config *candidate,
+int nb_candidate_commit(struct nb_context context, struct nb_config *candidate,
bool save_transaction, const char *comment,
uint32_t *transaction_id, char *errmsg,
size_t errmsg_len)
@@ -1411,13 +1410,13 @@ static int nb_callback_configuration(struct nb_context *context,
}
static struct nb_transaction *
-nb_transaction_new(struct nb_context *context, struct nb_config *config,
+nb_transaction_new(struct nb_context context, struct nb_config *config,
struct nb_config_cbs *changes, const char *comment,
char *errmsg, size_t errmsg_len)
{
struct nb_transaction *transaction;
- if (nb_running_lock_check(context->client, context->user)) {
+ if (nb_running_lock_check(context.client, context.user)) {
strlcpy(errmsg,
"running configuration is locked by another client",
errmsg_len);
@@ -1469,7 +1468,7 @@ static int nb_transaction_process(enum nb_event event,
break;
/* Call the appropriate callback. */
- ret = nb_callback_configuration(transaction->context, event,
+ ret = nb_callback_configuration(&transaction->context, event,
change, errmsg, errmsg_len);
switch (event) {
case NB_EV_PREPARE:
@@ -1584,7 +1583,7 @@ static void nb_transaction_apply_finish(struct nb_transaction *transaction,
/* Call the 'apply_finish' callbacks, sorted by their priorities. */
RB_FOREACH (cb, nb_config_cbs, &cbs)
- nb_callback_apply_finish(transaction->context, cb->nb_node,
+ nb_callback_apply_finish(&transaction->context, cb->nb_node,
cb->dnode, errmsg, errmsg_len);
/* Release memory. */
diff --git a/lib/northbound.h b/lib/northbound.h
index c132daebdb..152810b3a9 100644
--- a/lib/northbound.h
+++ b/lib/northbound.h
@@ -622,22 +622,6 @@ struct nb_context {
/* Northbound user (can be NULL). */
const void *user;
-
- /* Client-specific data. */
-#if 0
- union {
- struct {
- } cli;
- struct {
- } confd;
- struct {
- } sysrepo;
- struct {
- } grpc;
- struct {
- } pcep;
- } client_data;
-#endif
};
/* Northbound configuration. */
@@ -666,7 +650,7 @@ struct nb_config_change {
/* Northbound configuration transaction. */
struct nb_transaction {
- struct nb_context *context;
+ struct nb_context context;
char comment[80];
struct nb_config *config;
struct nb_config_cbs changes;
@@ -927,7 +911,7 @@ extern int nb_candidate_validate(struct nb_context *context,
* the candidate configuration.
* - NB_ERR for other errors.
*/
-extern int nb_candidate_commit_prepare(struct nb_context *context,
+extern int nb_candidate_commit_prepare(struct nb_context context,
struct nb_config *candidate,
const char *comment,
struct nb_transaction **transaction,
@@ -1014,7 +998,7 @@ extern void nb_candidate_commit_apply(struct nb_transaction *transaction,
* the candidate configuration.
* - NB_ERR for other errors.
*/
-extern int nb_candidate_commit(struct nb_context *context,
+extern int nb_candidate_commit(struct nb_context context,
struct nb_config *candidate,
bool save_transaction, const char *comment,
uint32_t *transaction_id, char *errmsg,
diff --git a/lib/northbound_cli.c b/lib/northbound_cli.c
index 0dfa66b37e..fa5884fb78 100644
--- a/lib/northbound_cli.c
+++ b/lib/northbound_cli.c
@@ -46,7 +46,7 @@ static int nb_cli_classic_commit(struct vty *vty)
context.client = NB_CLIENT_CLI;
context.user = vty;
- ret = nb_candidate_commit(&context, vty->candidate_config, true, NULL,
+ ret = nb_candidate_commit(context, vty->candidate_config, true, NULL,
NULL, errmsg, sizeof(errmsg));
switch (ret) {
case NB_OK:
@@ -313,7 +313,7 @@ int nb_cli_confirmed_commit_rollback(struct vty *vty)
context.client = NB_CLIENT_CLI;
context.user = vty;
ret = nb_candidate_commit(
- &context, vty->confirmed_commit_rollback, true,
+ context, vty->confirmed_commit_rollback, true,
"Rollback to previous configuration - confirmed commit has timed out",
&transaction_id, errmsg, sizeof(errmsg));
if (ret == NB_OK) {
@@ -394,9 +394,8 @@ static int nb_cli_commit(struct vty *vty, bool force,
context.client = NB_CLIENT_CLI;
context.user = vty;
- ret = nb_candidate_commit(&context, vty->candidate_config, true,
- comment, &transaction_id, errmsg,
- sizeof(errmsg));
+ ret = nb_candidate_commit(context, vty->candidate_config, true, comment,
+ &transaction_id, errmsg, sizeof(errmsg));
/* Map northbound return code to CLI return code. */
switch (ret) {
@@ -1717,7 +1716,7 @@ static int nb_cli_rollback_configuration(struct vty *vty,
context.client = NB_CLIENT_CLI;
context.user = vty;
- ret = nb_candidate_commit(&context, candidate, true, comment, NULL,
+ ret = nb_candidate_commit(context, candidate, true, comment, NULL,
errmsg, sizeof(errmsg));
nb_config_free(candidate);
switch (ret) {
diff --git a/lib/northbound_confd.c b/lib/northbound_confd.c
index 81ba313e81..2b57ff2707 100644
--- a/lib/northbound_confd.c
+++ b/lib/northbound_confd.c
@@ -311,7 +311,7 @@ static void frr_confd_cdb_read_cb_prepare(int fd, int *subp, int reslen)
*/
transaction = NULL;
context.client = NB_CLIENT_CONFD;
- ret = nb_candidate_commit_prepare(&context, candidate, NULL,
+ ret = nb_candidate_commit_prepare(context, candidate, NULL,
&transaction, errmsg, sizeof(errmsg));
if (ret != NB_OK && ret != NB_ERR_NO_CHANGES) {
enum confd_errcode errcode;
diff --git a/lib/northbound_db.c b/lib/northbound_db.c
index cefcfbcf1f..74abcde955 100644
--- a/lib/northbound_db.c
+++ b/lib/northbound_db.c
@@ -73,7 +73,7 @@ int nb_db_transaction_save(const struct nb_transaction *transaction,
if (!ss)
goto exit;
- client_name = nb_client_name(transaction->context->client);
+ client_name = nb_client_name(transaction->context.client);
/*
* Always record configurations in the XML format, save the default
* values too, as this covers the case where defaults may change.
diff --git a/lib/northbound_grpc.cpp b/lib/northbound_grpc.cpp
index f5d59d92d6..1459146eab 100644
--- a/lib/northbound_grpc.cpp
+++ b/lib/northbound_grpc.cpp
@@ -824,7 +824,7 @@ HandleUnaryCommit(UnaryRpcState<frr::CommitRequest, frr::CommitResponse> *tag)
case frr::CommitRequest::PREPARE:
grpc_debug("`-> Performing PREPARE");
ret = nb_candidate_commit_prepare(
- &context, candidate->config, comment.c_str(),
+ context, candidate->config, comment.c_str(),
&candidate->transaction, errmsg, sizeof(errmsg));
break;
case frr::CommitRequest::ABORT:
@@ -840,7 +840,7 @@ HandleUnaryCommit(UnaryRpcState<frr::CommitRequest, frr::CommitResponse> *tag)
break;
case frr::CommitRequest::ALL:
grpc_debug("`-> Performing ALL");
- ret = nb_candidate_commit(&context, candidate->config, true,
+ ret = nb_candidate_commit(context, candidate->config, true,
comment.c_str(), &transaction_id,
errmsg, sizeof(errmsg));
break;
diff --git a/lib/northbound_sysrepo.c b/lib/northbound_sysrepo.c
index 824d81a51e..096414ff24 100644
--- a/lib/northbound_sysrepo.c
+++ b/lib/northbound_sysrepo.c
@@ -268,7 +268,7 @@ static int frr_sr_config_change_cb_prepare(sr_session_ctx_t *session,
* Validate the configuration changes and allocate all resources
* required to apply them.
*/
- ret = nb_candidate_commit_prepare(&context, candidate, NULL,
+ ret = nb_candidate_commit_prepare(context, candidate, NULL,
&transaction, errmsg, sizeof(errmsg));
if (ret != NB_OK && ret != NB_ERR_NO_CHANGES)
flog_warn(
diff --git a/lib/prefix.c b/lib/prefix.c
index b3d81aa241..a6aae08a6a 100644
--- a/lib/prefix.c
+++ b/lib/prefix.c
@@ -123,6 +123,23 @@ afi_t family2afi(int family)
return 0;
}
+const char *afi2str_lower(afi_t afi)
+{
+ switch (afi) {
+ case AFI_IP:
+ return "ipv4";
+ case AFI_IP6:
+ return "ipv6";
+ case AFI_L2VPN:
+ return "l2vpn";
+ case AFI_MAX:
+ case AFI_UNSPEC:
+ return "bad-value";
+ }
+
+ assert(!"Reached end of function we should never reach");
+}
+
const char *afi2str(afi_t afi)
{
switch (afi) {
diff --git a/lib/prefix.h b/lib/prefix.h
index a6435be1b4..9c57283706 100644
--- a/lib/prefix.h
+++ b/lib/prefix.h
@@ -383,6 +383,7 @@ extern afi_t family2afi(int);
extern const char *family2str(int family);
extern const char *safi2str(safi_t safi);
extern const char *afi2str(afi_t afi);
+extern const char *afi2str_lower(afi_t afi);
static inline afi_t prefix_afi(union prefixconstptr pu)
{
diff --git a/lib/vty.c b/lib/vty.c
index 76dfe9734e..786271abe8 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -297,6 +297,13 @@ int vty_json_no_pretty(struct vty *vty, struct json_object *json)
return vty_json_helper(vty, json, JSON_C_TO_STRING_NOSLASHESCAPE);
}
+void vty_json_empty(struct vty *vty)
+{
+ json_object *json = json_object_new_object();
+
+ vty_json(vty, json);
+}
+
/* Output current time to the vty. */
void vty_time_print(struct vty *vty, int cr)
{
@@ -2413,7 +2420,7 @@ static void vty_read_file(struct nb_config *config, FILE *confp)
context.client = NB_CLIENT_CLI;
context.user = vty;
- ret = nb_candidate_commit(&context, vty->candidate_config, true,
+ ret = nb_candidate_commit(context, vty->candidate_config, true,
"Read configuration file", NULL,
errmsg, sizeof(errmsg));
if (ret != NB_OK && ret != NB_ERR_NO_CHANGES)
diff --git a/lib/vty.h b/lib/vty.h
index b8c677e354..3cab9590f1 100644
--- a/lib/vty.h
+++ b/lib/vty.h
@@ -344,7 +344,7 @@ extern bool vty_set_include(struct vty *vty, const char *regexp);
*/
extern int vty_json(struct vty *vty, struct json_object *json);
extern int vty_json_no_pretty(struct vty *vty, struct json_object *json);
-
+extern void vty_json_empty(struct vty *vty);
/* post fd to be passed to the vtysh client
* fd is owned by the VTY code after this and will be closed when done
*/
diff --git a/ospfd/ospf_dump.c b/ospfd/ospf_dump.c
index de51500b0a..b74b84e37d 100644
--- a/ospfd/ospf_dump.c
+++ b/ospfd/ospf_dump.c
@@ -133,13 +133,6 @@ const char *ospf_if_name_string(struct ospf_interface *oi)
return buf;
}
-/* Display only the nbr state.*/
-void ospf_nbr_state_message(struct ospf_neighbor *nbr, char *buf, size_t size)
-{
- snprintf(buf, size, "%s",
- lookup_msg(ospf_nsm_state_msg, nbr->state, NULL));
-}
-
int ospf_nbr_ism_state(struct ospf_neighbor *nbr)
{
int state;
diff --git a/ospfd/ospf_dump.h b/ospfd/ospf_dump.h
index 596d49256f..0f217971ee 100644
--- a/ospfd/ospf_dump.h
+++ b/ospfd/ospf_dump.h
@@ -140,8 +140,6 @@ extern const char *ospf_area_name_string(struct ospf_area *);
extern const char *ospf_area_desc_string(struct ospf_area *);
extern const char *ospf_if_name_string(struct ospf_interface *);
extern int ospf_nbr_ism_state(struct ospf_neighbor *nbr);
-extern void ospf_nbr_state_message(struct ospf_neighbor *nbr, char *buf,
- size_t size);
extern void ospf_nbr_ism_state_message(struct ospf_neighbor *nbr, char *buf,
size_t size);
extern const char *ospf_timer_dump(struct thread *, char *, size_t);
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index 29bddb1190..eb03a9c3a7 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -4900,9 +4900,8 @@ DEFUN (show_ip_ospf_instance_neighbor_all,
}
static int show_ip_ospf_neighbor_int_common(struct vty *vty, struct ospf *ospf,
- int arg_base,
- struct cmd_token **argv,
- bool use_json, uint8_t use_vrf)
+ const char *ifname, bool use_json,
+ uint8_t use_vrf)
{
struct interface *ifp;
struct route_node *rn;
@@ -4921,7 +4920,7 @@ static int show_ip_ospf_neighbor_int_common(struct vty *vty, struct ospf *ospf,
ospf_show_vrf_name(ospf, vty, json, use_vrf);
- ifp = if_lookup_by_name(argv[arg_base]->arg, ospf->vrf_id);
+ ifp = if_lookup_by_name(ifname, ospf->vrf_id);
if (!ifp) {
if (use_json)
json_object_boolean_true_add(json, "noSuchIface");
@@ -4947,76 +4946,22 @@ static int show_ip_ospf_neighbor_int_common(struct vty *vty, struct ospf *ospf,
return CMD_SUCCESS;
}
-DEFUN (show_ip_ospf_neighbor_int,
- show_ip_ospf_neighbor_int_cmd,
- "show ip ospf [vrf <NAME>] neighbor IFNAME [json]",
- SHOW_STR
- IP_STR
- "OSPF information\n"
- VRF_CMD_HELP_STR
- "Neighbor list\n"
- "Interface name\n"
- JSON_STR)
-{
- struct ospf *ospf;
- int idx_ifname = 0;
- int idx_vrf = 0;
- bool uj = use_json(argc, argv);
- int ret = CMD_SUCCESS;
- struct interface *ifp = NULL;
- char *vrf_name = NULL;
- vrf_id_t vrf_id = VRF_DEFAULT;
- struct vrf *vrf = NULL;
-
- if (argv_find(argv, argc, "vrf", &idx_vrf))
- vrf_name = argv[idx_vrf + 1]->arg;
- if (vrf_name && strmatch(vrf_name, VRF_DEFAULT_NAME))
- vrf_name = NULL;
- if (vrf_name) {
- vrf = vrf_lookup_by_name(vrf_name);
- if (vrf)
- vrf_id = vrf->vrf_id;
- }
- ospf = ospf_lookup_by_vrf_id(vrf_id);
-
- if (!ospf || !ospf->oi_running)
- return ret;
-
- if (!uj)
- show_ip_ospf_neighbour_header(vty);
-
- argv_find(argv, argc, "IFNAME", &idx_ifname);
-
- ifp = if_lookup_by_name(argv[idx_ifname]->arg, vrf_id);
- if (!ifp)
- return ret;
-
- ret = show_ip_ospf_neighbor_int_common(vty, ospf, idx_ifname,
- argv, uj, 0);
- return ret;
-}
-
-DEFUN (show_ip_ospf_instance_neighbor_int,
- show_ip_ospf_instance_neighbor_int_cmd,
- "show ip ospf (1-65535) neighbor IFNAME [json]",
- SHOW_STR
- IP_STR
- "OSPF information\n"
- "Instance ID\n"
- "Neighbor list\n"
- "Interface name\n"
- JSON_STR)
+DEFPY(show_ip_ospf_instance_neighbor_int,
+ show_ip_ospf_instance_neighbor_int_cmd,
+ "show ip ospf (1-65535)$instance neighbor IFNAME$ifname [json$json]",
+ SHOW_STR
+ IP_STR
+ "OSPF information\n"
+ "Instance ID\n"
+ "Neighbor list\n"
+ "Interface name\n"
+ JSON_STR)
{
- int idx_number = 3;
- int idx_ifname = 5;
struct ospf *ospf;
- unsigned short instance = 0;
- bool uj = use_json(argc, argv);
- if (!uj)
+ if (!json)
show_ip_ospf_neighbour_header(vty);
- instance = strtoul(argv[idx_number]->arg, NULL, 10);
if (instance != ospf_instance)
return CMD_NOT_MY_INSTANCE;
@@ -5024,11 +4969,10 @@ DEFUN (show_ip_ospf_instance_neighbor_int,
if (!ospf || !ospf->oi_running)
return CMD_SUCCESS;
- if (!uj)
+ if (!json)
show_ip_ospf_neighbour_header(vty);
- return show_ip_ospf_neighbor_int_common(vty, ospf, idx_ifname, argv, uj,
- 0);
+ return show_ip_ospf_neighbor_int_common(vty, ospf, ifname, !!json, 0);
}
static void show_ip_ospf_nbr_nbma_detail_sub(struct vty *vty,
@@ -5168,19 +5112,36 @@ static void show_ip_ospf_neighbor_detail_sub(struct vty *vty,
json_object_string_add(json_neigh, "areaId",
ospf_area_desc_string(oi->area));
json_object_string_add(json_neigh, "ifaceName", oi->ifp->name);
- } else
- vty_out(vty, " In the area %s via interface %s\n",
+ if (oi->address)
+ json_object_string_addf(json_neigh, "localIfaceAddress",
+ "%pI4",
+ &oi->address->u.prefix4);
+ } else {
+ vty_out(vty, " In the area %s via interface %s",
ospf_area_desc_string(oi->area), oi->ifp->name);
+ if (oi->address)
+ vty_out(vty, " local interface IP %pI4\n",
+ &oi->address->u.prefix4);
+ else
+ vty_out(vty, "\n");
+ }
/* Show neighbor priority and state. */
ospf_nbr_ism_state_message(nbr, neigh_state, sizeof(neigh_state));
if (use_json) {
json_object_int_add(json_neigh, "nbrPriority", nbr->priority);
json_object_string_add(json_neigh, "nbrState", neigh_state);
- } else
- vty_out(vty, " Neighbor priority is %d, State is %s,",
- nbr->priority, neigh_state);
-
+ json_object_string_add(json_neigh, "role",
+ lookup_msg(ospf_ism_state_msg,
+ ospf_nbr_ism_state(nbr),
+ NULL));
+ } else {
+ vty_out(vty,
+ " Neighbor priority is %d, State is %s, Role is %s,",
+ nbr->priority, neigh_state,
+ lookup_msg(ospf_ism_state_msg, ospf_nbr_ism_state(nbr),
+ NULL));
+ }
/* Show state changes. */
if (use_json)
json_object_int_add(json_neigh, "stateChangeCounter",
@@ -5414,7 +5375,8 @@ static void show_ip_ospf_neighbor_detail_sub(struct vty *vty,
static int show_ip_ospf_neighbor_id_common(struct vty *vty, struct ospf *ospf,
struct in_addr *router_id,
bool use_json, uint8_t use_vrf,
- bool is_detail)
+ bool is_detail,
+ json_object *json_vrf)
{
struct listnode *node;
struct ospf_neighbor *nbr;
@@ -5448,6 +5410,14 @@ static int show_ip_ospf_neighbor_id_common(struct vty *vty, struct ospf *ospf,
use_json);
}
+ if (json_vrf && use_json) {
+ json_object_object_add(
+ json_vrf,
+ (ospf->vrf_id == VRF_DEFAULT) ? "default" : ospf->name,
+ json);
+ return CMD_SUCCESS;
+ }
+
if (use_json)
vty_json(vty, json);
else
@@ -5456,23 +5426,50 @@ static int show_ip_ospf_neighbor_id_common(struct vty *vty, struct ospf *ospf,
return CMD_SUCCESS;
}
-DEFPY(show_ip_ospf_neighbor_id, show_ip_ospf_neighbor_id_cmd,
- "show ip ospf neighbor A.B.C.D$router_id [detail$detail] [json$json]",
- SHOW_STR IP_STR
+DEFPY(show_ip_ospf_neighbor_id,
+ show_ip_ospf_neighbor_id_cmd,
+ "show ip ospf [vrf NAME$vrf_name] neighbor A.B.C.D$router_id [detail$detail] [json$json]",
+ SHOW_STR
+ IP_STR
"OSPF information\n"
+ VRF_CMD_HELP_STR
"Neighbor list\n"
"Neighbor ID\n"
- "Detailed output\n" JSON_STR)
+ "Detailed output\n"
+ JSON_STR)
{
struct ospf *ospf;
struct listnode *node;
int ret = CMD_SUCCESS;
+ int inst = 0;
- for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
- if (!ospf->oi_running)
- continue;
- ret = show_ip_ospf_neighbor_id_common(vty, ospf, &router_id,
- !!json, 0, !!detail);
+ if (vrf_name && !strmatch(vrf_name, "all")) {
+ ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+ if (ospf == NULL || !ospf->oi_running) {
+ if (!json)
+ vty_out(vty,
+ "%% OSPF is not enabled in vrf %s\n",
+ vrf_name);
+ else
+ vty_json_empty(vty);
+ return CMD_SUCCESS;
+ }
+ ret = show_ip_ospf_neighbor_id_common(
+ vty, ospf, &router_id, !!json, 0, !!detail, NULL);
+ } else {
+ json_object *json_vrf = NULL;
+
+ if (json)
+ json_vrf = json_object_new_object();
+ for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+ if (!ospf->oi_running)
+ continue;
+ ret = show_ip_ospf_neighbor_id_common(
+ vty, ospf, &router_id, !!json, 0, !!detail,
+ json_vrf);
+ }
+ if (json)
+ vty_json(vty, json_vrf);
}
return ret;
@@ -5497,7 +5494,7 @@ DEFPY(show_ip_ospf_instance_neighbor_id, show_ip_ospf_instance_neighbor_id_cmd,
return CMD_SUCCESS;
return show_ip_ospf_neighbor_id_common(vty, ospf, &router_id, !!json, 0,
- !!detail);
+ !!detail, NULL);
}
static int show_ip_ospf_neighbor_detail_common(struct vty *vty,
@@ -5562,77 +5559,71 @@ static int show_ip_ospf_neighbor_detail_common(struct vty *vty,
return CMD_SUCCESS;
}
-DEFUN (show_ip_ospf_neighbor_detail,
- show_ip_ospf_neighbor_detail_cmd,
- "show ip ospf [vrf <NAME|all>] neighbor detail [json]",
- SHOW_STR
- IP_STR
- "OSPF information\n"
- VRF_CMD_HELP_STR
- "All VRFs\n"
- "Neighbor list\n"
- "detail of all neighbors\n"
- JSON_STR)
+DEFPY(show_ip_ospf_neighbor_detail,
+ show_ip_ospf_neighbor_detail_cmd,
+ "show ip ospf [vrf <NAME|all>$vrf_name] neighbor detail [json$json]",
+ SHOW_STR
+ IP_STR
+ "OSPF information\n"
+ VRF_CMD_HELP_STR
+ "All VRFs\n"
+ "Neighbor list\n"
+ "detail of all neighbors\n"
+ JSON_STR)
{
struct ospf *ospf;
- bool uj = use_json(argc, argv);
struct listnode *node = NULL;
- char *vrf_name = NULL;
- bool all_vrf = false;
int ret = CMD_SUCCESS;
int inst = 0;
- int idx_vrf = 0;
uint8_t use_vrf = 0;
- json_object *json = NULL;
-
- OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
+ json_object *json_vrf = NULL;
- if (uj)
- json = json_object_new_object();
+ if (json)
+ json_vrf = json_object_new_object();
/* vrf input is provided could be all or specific vrf*/
if (vrf_name) {
use_vrf = 1;
- if (all_vrf) {
+ if (strmatch(vrf_name, "all")) {
for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
if (!ospf->oi_running)
continue;
ret = show_ip_ospf_neighbor_detail_common(
- vty, ospf, json, uj, use_vrf);
+ vty, ospf, json_vrf, !!json, use_vrf);
}
- if (uj)
- vty_json(vty, json);
+ if (json)
+ vty_json(vty, json_vrf);
return ret;
}
ospf = ospf_lookup_by_inst_name(inst, vrf_name);
if (ospf == NULL || !ospf->oi_running) {
- if (uj)
- json_object_free(json);
+ if (json)
+ vty_json(vty, json_vrf);
+ else
+ vty_out(vty,
+ "%% OSPF is not enabled in vrf %s\n",
+ vrf_name);
return CMD_SUCCESS;
}
} else {
/* Display default ospf (instance 0) info */
ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
if (ospf == NULL || !ospf->oi_running) {
- if (uj)
- json_object_free(json);
+ if (json)
+ vty_json(vty, json_vrf);
+ else
+ vty_out(vty, "%% OSPF is not enabled\n");
return CMD_SUCCESS;
}
}
- if (ospf) {
- ret = show_ip_ospf_neighbor_detail_common(vty, ospf, json, uj,
- use_vrf);
- if (uj) {
- vty_out(vty, "%s\n",
- json_object_to_json_string_ext(
- json, JSON_C_TO_STRING_PRETTY));
- }
- }
+ if (ospf)
+ ret = show_ip_ospf_neighbor_detail_common(vty, ospf, json_vrf,
+ !!json, use_vrf);
- if (uj)
- json_object_free(json);
+ if (json)
+ vty_json(vty, json_vrf);
return ret;
}
@@ -5861,9 +5852,9 @@ DEFUN (show_ip_ospf_instance_neighbor_detail_all,
static int show_ip_ospf_neighbor_int_detail_common(struct vty *vty,
struct ospf *ospf,
- int arg_base,
- struct cmd_token **argv,
- bool use_json)
+ const char *ifname,
+ bool use_json,
+ json_object *json_vrf)
{
struct ospf_interface *oi;
struct interface *ifp;
@@ -5871,8 +5862,15 @@ static int show_ip_ospf_neighbor_int_detail_common(struct vty *vty,
struct ospf_neighbor *nbr;
json_object *json = NULL;
- if (use_json)
+ if (use_json) {
json = json_object_new_object();
+ if (json_vrf)
+ json_object_object_add(json_vrf,
+ (ospf->vrf_id == VRF_DEFAULT)
+ ? "default"
+ : ospf->name,
+ json);
+ }
if (ospf->instance) {
if (use_json)
@@ -5882,13 +5880,13 @@ static int show_ip_ospf_neighbor_int_detail_common(struct vty *vty,
vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
}
- ifp = if_lookup_by_name(argv[arg_base]->arg, ospf->vrf_id);
+ ifp = if_lookup_by_name(ifname, ospf->vrf_id);
if (!ifp) {
- if (!use_json)
+ if (!use_json) {
vty_out(vty, "No such interface.\n");
- else {
- vty_out(vty, "{}\n");
- json_object_free(json);
+ } else {
+ if (!json_vrf)
+ vty_json(vty, json);
}
return CMD_WARNING;
}
@@ -5916,37 +5914,114 @@ static int show_ip_ospf_neighbor_int_detail_common(struct vty *vty,
}
}
- if (use_json)
- vty_json(vty, json);
- else
+ if (use_json) {
+ if (!json_vrf)
+ vty_json(vty, json);
+ } else {
vty_out(vty, "\n");
+ }
return CMD_SUCCESS;
}
-DEFUN (show_ip_ospf_neighbor_int_detail,
- show_ip_ospf_neighbor_int_detail_cmd,
- "show ip ospf neighbor IFNAME detail [json]",
- SHOW_STR
- IP_STR
- "OSPF information\n"
- "Neighbor list\n"
- "Interface name\n"
- "detail of all neighbors\n"
- JSON_STR)
+DEFPY(show_ip_ospf_neighbor_int,
+ show_ip_ospf_neighbor_int_cmd,
+ "show ip ospf [vrf NAME$vrf_name] neighbor IFNAME$ifname [json$json]",
+ SHOW_STR
+ IP_STR
+ "OSPF information\n"
+ VRF_CMD_HELP_STR
+ "Neighbor list\n"
+ "Interface name\n"
+ JSON_STR)
+{
+ struct ospf *ospf;
+ int ret = CMD_SUCCESS;
+ struct interface *ifp = NULL;
+ vrf_id_t vrf_id = VRF_DEFAULT;
+ struct vrf *vrf = NULL;
+
+ if (vrf_name && strmatch(vrf_name, VRF_DEFAULT_NAME))
+ vrf_name = NULL;
+ if (vrf_name) {
+ vrf = vrf_lookup_by_name(vrf_name);
+ if (vrf)
+ vrf_id = vrf->vrf_id;
+ }
+ ospf = ospf_lookup_by_vrf_id(vrf_id);
+
+ if (!ospf || !ospf->oi_running) {
+ if (json)
+ vty_json_empty(vty);
+ return ret;
+ }
+
+ if (!json)
+ show_ip_ospf_neighbour_header(vty);
+
+ ifp = if_lookup_by_name(ifname, vrf_id);
+ if (!ifp) {
+ if (json)
+ vty_json_empty(vty);
+ else
+ vty_out(vty, "No such interface.\n");
+ return ret;
+ }
+
+ ret = show_ip_ospf_neighbor_int_common(vty, ospf, ifname, !!json, 0);
+ return ret;
+}
+
+DEFPY(show_ip_ospf_neighbor_int_detail,
+ show_ip_ospf_neighbor_int_detail_cmd,
+ "show ip ospf [vrf NAME$vrf_name] neighbor IFNAME$ifname detail [json$json]",
+ SHOW_STR
+ IP_STR
+ "OSPF information\n"
+ VRF_CMD_HELP_STR
+ "Neighbor list\n"
+ "Interface name\n"
+ "detail of all neighbors\n"
+ JSON_STR)
{
struct ospf *ospf;
- bool uj = use_json(argc, argv);
struct listnode *node = NULL;
int ret = CMD_SUCCESS;
bool ospf_output = false;
+ if (vrf_name && !strmatch(vrf_name, "all")) {
+ int inst = 0;
+
+ ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+ if (ospf == NULL || !ospf->oi_running) {
+ if (!json)
+ vty_out(vty,
+ "%% OSPF is not enabled in vrf %s\n",
+ vrf_name);
+ else
+ vty_json_empty(vty);
+ return CMD_SUCCESS;
+ }
+ return show_ip_ospf_neighbor_int_detail_common(
+ vty, ospf, ifname, !!json, NULL);
+ }
+
+ json_object *json_vrf = NULL;
+
+ if (json)
+ json_vrf = json_object_new_object();
+
for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
if (!ospf->oi_running)
continue;
ospf_output = true;
- ret = show_ip_ospf_neighbor_int_detail_common(vty, ospf, 4,
- argv, uj);
+ ret = show_ip_ospf_neighbor_int_detail_common(vty, ospf, ifname,
+ !!json, json_vrf);
+ }
+
+ if (json) {
+ vty_json(vty, json_vrf);
+ return ret;
}
if (!ospf_output)
@@ -5955,25 +6030,20 @@ DEFUN (show_ip_ospf_neighbor_int_detail,
return ret;
}
-DEFUN (show_ip_ospf_instance_neighbor_int_detail,
- show_ip_ospf_instance_neighbor_int_detail_cmd,
- "show ip ospf (1-65535) neighbor IFNAME detail [json]",
- SHOW_STR
- IP_STR
- "OSPF information\n"
- "Instance ID\n"
- "Neighbor list\n"
- "Interface name\n"
- "detail of all neighbors\n"
- JSON_STR)
+DEFPY(show_ip_ospf_instance_neighbor_int_detail,
+ show_ip_ospf_instance_neighbor_int_detail_cmd,
+ "show ip ospf (1-65535)$instance neighbor IFNAME$ifname detail [json$json]",
+ SHOW_STR
+ IP_STR
+ "OSPF information\n"
+ "Instance ID\n"
+ "Neighbor list\n"
+ "Interface name\n"
+ "detail of all neighbors\n"
+ JSON_STR)
{
- int idx_number = 3;
- int idx_ifname = 5;
struct ospf *ospf;
- unsigned short instance = 0;
- bool uj = use_json(argc, argv);
- instance = strtoul(argv[idx_number]->arg, NULL, 10);
if (instance != ospf_instance)
return CMD_NOT_MY_INSTANCE;
@@ -5981,8 +6051,8 @@ DEFUN (show_ip_ospf_instance_neighbor_int_detail,
if (!ospf || !ospf->oi_running)
return CMD_SUCCESS;
- return show_ip_ospf_neighbor_int_detail_common(vty, ospf, idx_ifname,
- argv, uj);
+ return show_ip_ospf_neighbor_int_detail_common(vty, ospf, ifname,
+ !!json, NULL);
}
/* Show functions */
diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c
index af510ce29e..02b50c9af2 100644
--- a/pimd/pim_mroute.c
+++ b/pimd/pim_mroute.c
@@ -34,6 +34,8 @@
#include "pim_msg.h"
static void mroute_read_on(struct pim_instance *pim);
+static int pim_upstream_mroute_update(struct channel_oil *c_oil,
+ const char *name);
int pim_mroute_set(struct pim_instance *pim, int enable)
{
@@ -145,45 +147,66 @@ int pim_mroute_msg_nocache(int fd, struct interface *ifp, const kernmsg *msg)
{
struct pim_interface *pim_ifp = ifp->info;
struct pim_upstream *up;
- struct pim_rpf *rpg;
pim_sgaddr sg;
+ bool desync = false;
- rpg = pim_ifp ? RP(pim_ifp->pim, msg->msg_im_dst) : NULL;
- /*
- * If the incoming interface is unknown OR
- * the Interface type is SSM we don't need to
- * do anything here
- */
- if (!rpg || pim_rpf_addr_is_inaddr_any(rpg)) {
- if (PIM_DEBUG_MROUTE_DETAIL)
- zlog_debug(
- "%s: Interface is not configured correctly to handle incoming packet: Could be !pim_ifp, !SM, !RP",
- __func__);
+ memset(&sg, 0, sizeof(sg));
+ sg.src = msg->msg_im_src;
+ sg.grp = msg->msg_im_dst;
+ if (!pim_ifp) {
+ if (PIM_DEBUG_MROUTE)
+ zlog_debug(
+ "%s: PIM not enabled on interface, dropping packet to %pSG",
+ ifp->name, &sg);
return 0;
}
+ if (!pim_is_grp_ssm(pim_ifp->pim, sg.grp)) {
+ /* for ASM, check that we have enough information (i.e. path
+ * to RP) to make a decision on what to do with this packet.
+ *
+ * for SSM, this is meaningless, everything is join-driven,
+ * and for NOCACHE we need to install an empty OIL MFC entry
+ * so the kernel doesn't keep nagging us.
+ */
+ struct pim_rpf *rpg;
+
+ rpg = RP(pim_ifp->pim, msg->msg_im_dst);
+ if (!rpg) {
+ if (PIM_DEBUG_MROUTE)
+ zlog_debug("%s: no RPF for packet to %pSG",
+ ifp->name, &sg);
+ return 0;
+ }
+ if (pim_rpf_addr_is_inaddr_any(rpg)) {
+ if (PIM_DEBUG_MROUTE)
+ zlog_debug("%s: null RPF for packet to %pSG",
+ ifp->name, &sg);
+ return 0;
+ }
+ }
+
/*
* If we've received a multicast packet that isn't connected to
* us
*/
if (!pim_if_connected_to_source(ifp, msg->msg_im_src)) {
- if (PIM_DEBUG_MROUTE_DETAIL)
+ if (PIM_DEBUG_MROUTE)
zlog_debug(
- "%s: Received incoming packet that doesn't originate on our seg",
- __func__);
+ "%s: incoming packet to %pSG from non-connected source",
+ ifp->name, &sg);
return 0;
}
- memset(&sg, 0, sizeof(sg));
- sg.src = msg->msg_im_src;
- sg.grp = msg->msg_im_dst;
-
if (!(PIM_I_am_DR(pim_ifp))) {
+ /* unlike the other debug messages, this one is further in the
+ * "normal operation" category and thus under _DETAIL
+ */
if (PIM_DEBUG_MROUTE_DETAIL)
zlog_debug(
- "%s: Interface is not the DR blackholing incoming traffic for %pSG",
- __func__, &sg);
+ "%s: not DR on interface, not forwarding traffic for %pSG",
+ ifp->name, &sg);
/*
* We are not the DR, but we are still receiving packets
@@ -204,6 +227,12 @@ int pim_mroute_msg_nocache(int fd, struct interface *ifp, const kernmsg *msg)
up = pim_upstream_find_or_add(&sg, ifp, PIM_UPSTREAM_FLAG_MASK_FHR,
__func__);
+ if (up->channel_oil->installed) {
+ zlog_warn(
+ "%s: NOCACHE for %pSG, MFC entry disappeared - reinstalling",
+ ifp->name, &sg);
+ desync = true;
+ }
/*
* I moved this debug till after the actual add because
@@ -227,6 +256,11 @@ int pim_mroute_msg_nocache(int fd, struct interface *ifp, const kernmsg *msg)
/* if we have receiver, inherit from parent */
pim_upstream_inherited_olist_decide(pim_ifp->pim, up);
+ /* we just got NOCACHE from the kernel, so... MFC is not in the
+ * kernel for some reason or another. Try installing again.
+ */
+ if (desync)
+ pim_upstream_mroute_update(up->channel_oil, __func__);
return 0;
}