diff options
| -rw-r--r-- | bgpd/bgp_bmp.c | 9 | ||||
| -rw-r--r-- | bgpd/bgp_flowspec.c | 7 | ||||
| -rw-r--r-- | bgpd/bgp_route.h | 2 | ||||
| -rw-r--r-- | doc/user/ospfd.rst | 6 | ||||
| -rw-r--r-- | lib/libfrr.c | 2 | ||||
| -rw-r--r-- | lib/northbound.c | 19 | ||||
| -rw-r--r-- | lib/northbound.h | 22 | ||||
| -rw-r--r-- | lib/northbound_cli.c | 11 | ||||
| -rw-r--r-- | lib/northbound_confd.c | 2 | ||||
| -rw-r--r-- | lib/northbound_db.c | 2 | ||||
| -rw-r--r-- | lib/northbound_grpc.cpp | 4 | ||||
| -rw-r--r-- | lib/northbound_sysrepo.c | 2 | ||||
| -rw-r--r-- | lib/prefix.c | 17 | ||||
| -rw-r--r-- | lib/prefix.h | 1 | ||||
| -rw-r--r-- | lib/vty.c | 9 | ||||
| -rw-r--r-- | lib/vty.h | 2 | ||||
| -rw-r--r-- | ospfd/ospf_dump.c | 7 | ||||
| -rw-r--r-- | ospfd/ospf_dump.h | 2 | ||||
| -rw-r--r-- | ospfd/ospf_vty.c | 412 | ||||
| -rw-r--r-- | pimd/pim_mroute.c | 76 |
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) { @@ -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) @@ -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; } |
