diff options
Diffstat (limited to 'bgpd/bgp_vty.c')
| -rw-r--r-- | bgpd/bgp_vty.c | 2000 |
1 files changed, 1463 insertions, 537 deletions
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index de781d6b1e..bcd029dcad 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -5,6 +5,10 @@ #include <zebra.h> +#ifdef GNU_LINUX +#include <linux/rtnetlink.h> //RT_TABLE_XXX +#endif + #include "command.h" #include "lib/json.h" #include "lib/sockopt.h" @@ -118,12 +122,25 @@ FRR_CFG_DEFAULT_BOOL(BGP_HARD_ADMIN_RESET, { .val_bool = false, .match_version = "< 8.3", }, { .val_bool = true }, ); +FRR_CFG_DEFAULT_BOOL(BGP_SOFT_VERSION_CAPABILITY, + { .val_bool = true, .match_profile = "datacenter", }, + { .val_bool = false }, +); +FRR_CFG_DEFAULT_BOOL(BGP_DYNAMIC_CAPABILITY, + { .val_bool = true, .match_profile = "datacenter", }, + { .val_bool = false }, +); +FRR_CFG_DEFAULT_BOOL(BGP_ENFORCE_FIRST_AS, + { .val_bool = false, .match_version = "< 9.1", }, + { .val_bool = true }, +); DEFINE_HOOK(bgp_inst_config_write, (struct bgp *bgp, struct vty *vty), (bgp, vty)); DEFINE_HOOK(bgp_snmp_update_last_changed, (struct bgp *bgp), (bgp)); DEFINE_HOOK(bgp_snmp_init_stats, (struct bgp *bgp), (bgp)); +DEFINE_HOOK(bgp_snmp_traps_config_write, (struct vty * vty), (vty)); static struct peer_group *listen_range_exists(struct bgp *bgp, struct prefix *range, int exact); @@ -306,7 +323,7 @@ static int bgp_srv6_locator_unset(struct bgp *bgp) /* refresh functions */ for (ALL_LIST_ELEMENTS(bgp->srv6_functions, node, nnode, func)) { listnode_delete(bgp->srv6_functions, func); - XFREE(MTYPE_BGP_SRV6_FUNCTION, func); + srv6_function_free(func); } /* refresh tovpn_sid */ @@ -586,7 +603,7 @@ int bgp_get_vty(struct bgp **bgp, as_t *as, const char *name, int ret = bgp_get(bgp, as, name, inst_type, as_pretty, asnotation); if (ret == BGP_CREATED) { - bgp_timers_set(*bgp, DFLT_BGP_KEEPALIVE, DFLT_BGP_HOLDTIME, + bgp_timers_set(NULL, *bgp, DFLT_BGP_KEEPALIVE, DFLT_BGP_HOLDTIME, DFLT_BGP_CONNECT_RETRY, BGP_DEFAULT_DELAYOPEN); if (DFLT_BGP_IMPORT_CHECK) @@ -607,6 +624,14 @@ int bgp_get_vty(struct bgp **bgp, as_t *as, const char *name, SET_FLAG((*bgp)->flags, BGP_FLAG_GRACEFUL_NOTIFICATION); if (DFLT_BGP_HARD_ADMIN_RESET) SET_FLAG((*bgp)->flags, BGP_FLAG_HARD_ADMIN_RESET); + if (DFLT_BGP_SOFT_VERSION_CAPABILITY) + SET_FLAG((*bgp)->flags, + BGP_FLAG_SOFT_VERSION_CAPABILITY); + if (DFLT_BGP_DYNAMIC_CAPABILITY) + SET_FLAG((*bgp)->flags, + BGP_FLAG_DYNAMIC_CAPABILITY); + if (DFLT_BGP_ENFORCE_FIRST_AS) + SET_FLAG((*bgp)->flags, BGP_FLAG_ENFORCE_FIRST_AS); ret = BGP_SUCCESS; } @@ -1584,8 +1609,9 @@ DEFUN_NOSH (router_bgp, * - update asnotation if explicitly mentioned */ if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO)) { - XFREE(MTYPE_BGP, bgp->as_pretty); - bgp->as_pretty = XSTRDUP(MTYPE_BGP, argv[idx_asn]->arg); + XFREE(MTYPE_BGP_NAME, bgp->as_pretty); + bgp->as_pretty = XSTRDUP(MTYPE_BGP_NAME, + argv[idx_asn]->arg); if (!CHECK_FLAG(bgp->config, BGP_CONFIG_ASNOTATION) && asnotation != ASNOTATION_UNDEFINED) { SET_FLAG(bgp->config, BGP_CONFIG_ASNOTATION); @@ -1994,8 +2020,8 @@ DEFUN (bgp_confederation_identifier, "bgp confederation identifier ASNUM", BGP_STR "AS confederation parameters\n" - AS_STR - "Set routing domain confederation AS\n") + "Set routing domain confederation AS\n" + AS_STR) { VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_number = 3; @@ -2017,8 +2043,8 @@ DEFUN (no_bgp_confederation_identifier, NO_STR BGP_STR "AS confederation parameters\n" - AS_STR - "Set routing domain confederation AS\n") + "Set routing domain confederation AS\n" + AS_STR) { VTY_DECLVAR_CONTEXT(bgp, bgp); bgp_confederation_id_unset(bgp); @@ -2654,7 +2680,7 @@ DEFUN (bgp_timers, return CMD_WARNING_CONFIG_FAILED; } - bgp_timers_set(bgp, keepalive, holdtime, DFLT_BGP_CONNECT_RETRY, + bgp_timers_set(vty, bgp, keepalive, holdtime, DFLT_BGP_CONNECT_RETRY, BGP_DEFAULT_DELAYOPEN); return CMD_SUCCESS; @@ -2670,7 +2696,7 @@ DEFUN (no_bgp_timers, "Holdtime\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); - bgp_timers_set(bgp, DFLT_BGP_KEEPALIVE, DFLT_BGP_HOLDTIME, + bgp_timers_set(vty, bgp, DFLT_BGP_KEEPALIVE, DFLT_BGP_HOLDTIME, DFLT_BGP_CONNECT_RETRY, BGP_DEFAULT_DELAYOPEN); return CMD_SUCCESS; @@ -2820,18 +2846,45 @@ DEFUN(no_bgp_ebgp_requires_policy, no_bgp_ebgp_requires_policy_cmd, return CMD_SUCCESS; } +DEFPY(bgp_enforce_first_as, + bgp_enforce_first_as_cmd, + "[no] bgp enforce-first-as", + NO_STR + BGP_STR + "Enforce the first AS for EBGP routes\n") +{ + VTY_DECLVAR_CONTEXT(bgp, bgp); + + if (no) + UNSET_FLAG(bgp->flags, BGP_FLAG_ENFORCE_FIRST_AS); + else + SET_FLAG(bgp->flags, BGP_FLAG_ENFORCE_FIRST_AS); + + return CMD_SUCCESS; +} + DEFPY(bgp_lu_uses_explicit_null, bgp_lu_uses_explicit_null_cmd, - "[no] bgp labeled-unicast explicit-null", + "[no] bgp labeled-unicast <explicit-null|ipv4-explicit-null|ipv6-explicit-null>$value", NO_STR BGP_STR "BGP Labeled-unicast options\n" - "Use explicit-null label values for local prefixes\n") + "Use explicit-null label values for all local prefixes\n" + "Use the IPv4 explicit-null label value for IPv4 local prefixes\n" + "Use the IPv6 explicit-null label value for IPv6 local prefixes\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); + uint64_t label_mode; + if (strmatch(value, "ipv4-explicit-null")) + label_mode = BGP_FLAG_LU_IPV4_EXPLICIT_NULL; + else if (strmatch(value, "ipv6-explicit-null")) + label_mode = BGP_FLAG_LU_IPV6_EXPLICIT_NULL; + else + label_mode = BGP_FLAG_LU_IPV4_EXPLICIT_NULL | + BGP_FLAG_LU_IPV6_EXPLICIT_NULL; if (no) - UNSET_FLAG(bgp->flags, BGP_FLAG_LU_EXPLICIT_NULL); + UNSET_FLAG(bgp->flags, label_mode); else - SET_FLAG(bgp->flags, BGP_FLAG_LU_EXPLICIT_NULL); + SET_FLAG(bgp->flags, label_mode); return CMD_SUCCESS; } @@ -2871,9 +2924,9 @@ DEFUN(bgp_reject_as_sets, bgp_reject_as_sets_cmd, * with aspath containing AS_SET or AS_CONFED_SET. */ for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) { + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { peer->last_reset = PEER_DOWN_AS_SETS_REJECT; - bgp_notify_send(peer, BGP_NOTIFY_CEASE, + bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } } @@ -2897,9 +2950,9 @@ DEFUN(no_bgp_reject_as_sets, no_bgp_reject_as_sets_cmd, * with aspath containing AS_SET or AS_CONFED_SET. */ for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) { + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { peer->last_reset = PEER_DOWN_AS_SETS_REJECT; - bgp_notify_send(peer, BGP_NOTIFY_CEASE, + bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } } @@ -3049,9 +3102,17 @@ DEFUN (bgp_graceful_restart_restart_time, VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_number = 3; uint32_t restart; + struct listnode *node, *nnode; + struct peer *peer; restart = strtoul(argv[idx_number]->arg, NULL, 10); bgp->restart_time = restart; + + for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) + bgp_capability_send(peer, AFI_IP, SAFI_UNICAST, + CAPABILITY_CODE_RESTART, + CAPABILITY_ACTION_SET); + return CMD_SUCCESS; } @@ -3102,8 +3163,16 @@ DEFUN (no_bgp_graceful_restart_restart_time, "Delay value (seconds)\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); + struct listnode *node, *nnode; + struct peer *peer; bgp->restart_time = BGP_DEFAULT_RESTART_TIME; + + for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) + bgp_capability_send(peer, AFI_IP, SAFI_UNICAST, + CAPABILITY_CODE_RESTART, + CAPABILITY_ACTION_UNSET); + return CMD_SUCCESS; } @@ -3158,12 +3227,19 @@ DEFPY (bgp_graceful_restart_notification, "Indicate Graceful Restart support for BGP NOTIFICATION messages\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); + struct listnode *node, *nnode; + struct peer *peer; if (no) UNSET_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_NOTIFICATION); else SET_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_NOTIFICATION); + for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) + bgp_capability_send(peer, AFI_IP, SAFI_UNICAST, + CAPABILITY_CODE_RESTART, + CAPABILITY_ACTION_SET); + return CMD_SUCCESS; } @@ -3191,6 +3267,8 @@ DEFUN (bgp_graceful_restart_disable, GR_DISABLE) { int ret = BGP_GR_FAILURE; + struct listnode *node, *nnode; + struct peer *peer; if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) zlog_debug( @@ -3209,6 +3287,15 @@ DEFUN (bgp_graceful_restart_disable, vty_out(vty, "Graceful restart configuration changed, reset all peers to take effect\n"); + for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { + bgp_capability_send(peer, AFI_IP, SAFI_UNICAST, + CAPABILITY_CODE_RESTART, + CAPABILITY_ACTION_UNSET); + bgp_capability_send(peer, AFI_IP, SAFI_UNICAST, + CAPABILITY_CODE_LLGR, + CAPABILITY_ACTION_UNSET); + } + return bgp_vty_return(vty, ret); } @@ -3579,10 +3666,16 @@ DEFUN(bgp_llgr_stalepath_time, bgp_llgr_stalepath_time_cmd, VTY_DECLVAR_CONTEXT(bgp, bgp); uint32_t llgr_stale_time; + struct listnode *node, *nnode; + struct peer *peer; llgr_stale_time = strtoul(argv[3]->arg, NULL, 10); bgp->llgr_stale_time = llgr_stale_time; + for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) + bgp_capability_send(peer, AFI_IP, SAFI_UNICAST, + CAPABILITY_CODE_LLGR, CAPABILITY_ACTION_SET); + return CMD_SUCCESS; } @@ -3594,9 +3687,16 @@ DEFUN(no_bgp_llgr_stalepath_time, no_bgp_llgr_stalepath_time_cmd, "Stale time value (seconds)\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); + struct listnode *node, *nnode; + struct peer *peer; bgp->llgr_stale_time = BGP_DEFAULT_LLGR_STALE_TIME; + for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) + bgp_capability_send(peer, AFI_IP, SAFI_UNICAST, + CAPABILITY_CODE_LLGR, + CAPABILITY_ACTION_UNSET); + return CMD_SUCCESS; } @@ -4187,6 +4287,42 @@ DEFUN (no_bgp_default_show_nexthop_hostname, return CMD_SUCCESS; } +DEFPY (bgp_default_software_version_capability, + bgp_default_software_version_capability_cmd, + "[no] bgp default software-version-capability", + NO_STR + BGP_STR + "Configure BGP defaults\n" + "Advertise software version capability for all neighbors\n") +{ + VTY_DECLVAR_CONTEXT(bgp, bgp); + + if (no) + UNSET_FLAG(bgp->flags, BGP_FLAG_SOFT_VERSION_CAPABILITY); + else + SET_FLAG(bgp->flags, BGP_FLAG_SOFT_VERSION_CAPABILITY); + + return CMD_SUCCESS; +} + +DEFPY (bgp_default_dynamic_capability, + bgp_default_dynamic_capability_cmd, + "[no] bgp default dynamic-capability", + NO_STR + BGP_STR + "Configure BGP defaults\n" + "Advertise dynamic capability for all neighbors\n") +{ + VTY_DECLVAR_CONTEXT(bgp, bgp); + + if (no) + UNSET_FLAG(bgp->flags, BGP_FLAG_DYNAMIC_CAPABILITY); + else + SET_FLAG(bgp->flags, BGP_FLAG_DYNAMIC_CAPABILITY); + + return CMD_SUCCESS; +} + /* "bgp network import-check" configuration. */ DEFUN (bgp_network_import_check, bgp_network_import_check_cmd, @@ -4816,9 +4952,9 @@ static int peer_conf_interface_get(struct vty *vty, const char *conf_if, peer_flag_unset(peer, PEER_FLAG_IFPEER_V6ONLY); /* v6only flag changed. Reset bgp seesion */ - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) { + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { peer->last_reset = PEER_DOWN_V6ONLY_CHANGE; - bgp_notify_send(peer, BGP_NOTIFY_CEASE, + bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } else bgp_session_reset(peer); @@ -5005,7 +5141,7 @@ DEFUN (no_neighbor, peer_notify_unconfig(peer); peer_delete(peer); - if (other && other->status != Deleted) { + if (other && other->connection->status != Deleted) { peer_notify_unconfig(other); peer_delete(other); } @@ -5635,6 +5771,37 @@ DEFUN (no_neighbor_dont_capability_negotiate, PEER_FLAG_DONT_CAPABILITY); } +/* neighbor capability fqdn */ +DEFPY (neighbor_capability_fqdn, + neighbor_capability_fqdn_cmd, + "[no$no] neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor capability fqdn", + NO_STR + NEIGHBOR_STR + NEIGHBOR_ADDR_STR2 + "Advertise capability to the peer\n" + "Advertise fqdn capability to the peer\n") +{ + struct peer *peer; + int ret; + + peer = peer_and_group_lookup_vty(vty, neighbor); + if (!peer) + return CMD_WARNING_CONFIG_FAILED; + + if (no) + ret = peer_flag_unset_vty(vty, neighbor, + PEER_FLAG_CAPABILITY_FQDN); + else + ret = peer_flag_set_vty(vty, neighbor, + PEER_FLAG_CAPABILITY_FQDN); + + bgp_capability_send(peer, AFI_IP, SAFI_UNICAST, CAPABILITY_CODE_FQDN, + no ? CAPABILITY_ACTION_UNSET + : CAPABILITY_ACTION_SET); + + return ret; +} + /* neighbor capability extended next hop encoding */ DEFUN (neighbor_capability_enhe, neighbor_capability_enhe_cmd, @@ -5690,17 +5857,25 @@ DEFPY(neighbor_capability_software_version, "Advertise Software Version capability to the peer\n") { struct peer *peer; + int ret; peer = peer_and_group_lookup_vty(vty, neighbor); - if (peer && peer->conf_if) - return CMD_SUCCESS; + if (!peer) + return CMD_WARNING_CONFIG_FAILED; if (no) - return peer_flag_unset_vty(vty, neighbor, - PEER_FLAG_CAPABILITY_SOFT_VERSION); + ret = peer_flag_unset_vty(vty, neighbor, + PEER_FLAG_CAPABILITY_SOFT_VERSION); else - return peer_flag_set_vty(vty, neighbor, - PEER_FLAG_CAPABILITY_SOFT_VERSION); + ret = peer_flag_set_vty(vty, neighbor, + PEER_FLAG_CAPABILITY_SOFT_VERSION); + + bgp_capability_send(peer, AFI_IP, SAFI_UNICAST, + CAPABILITY_CODE_SOFT_VERSION, + no ? CAPABILITY_ACTION_UNSET + : CAPABILITY_ACTION_SET); + + return ret; } static int peer_af_flag_modify_vty(struct vty *vty, const char *peer_str, @@ -5752,24 +5927,37 @@ DEFUN (neighbor_capability_orf_prefix, struct peer *peer; afi_t afi = bgp_node_afi(vty); safi_t safi = bgp_node_safi(vty); + int ret; peer = peer_and_group_lookup_vty(vty, peer_str); if (!peer) return CMD_WARNING_CONFIG_FAILED; - if (strmatch(argv[idx_send_recv]->text, "send")) - return peer_af_flag_set_vty(vty, peer_str, afi, safi, - PEER_FLAG_ORF_PREFIX_SM); + if (strmatch(argv[idx_send_recv]->text, "send")) { + ret = peer_af_flag_set_vty(vty, peer_str, afi, safi, + PEER_FLAG_ORF_PREFIX_SM); + bgp_capability_send(peer, afi, safi, CAPABILITY_CODE_ORF, + CAPABILITY_ACTION_SET); + return ret; + } - if (strmatch(argv[idx_send_recv]->text, "receive")) - return peer_af_flag_set_vty(vty, peer_str, afi, safi, - PEER_FLAG_ORF_PREFIX_RM); + if (strmatch(argv[idx_send_recv]->text, "receive")) { + ret = peer_af_flag_set_vty(vty, peer_str, afi, safi, + PEER_FLAG_ORF_PREFIX_RM); + bgp_capability_send(peer, afi, safi, CAPABILITY_CODE_ORF, + CAPABILITY_ACTION_SET); + return ret; + } - if (strmatch(argv[idx_send_recv]->text, "both")) - return peer_af_flag_set_vty(vty, peer_str, afi, safi, - PEER_FLAG_ORF_PREFIX_SM) - | peer_af_flag_set_vty(vty, peer_str, afi, safi, - PEER_FLAG_ORF_PREFIX_RM); + if (strmatch(argv[idx_send_recv]->text, "both")) { + ret = peer_af_flag_set_vty(vty, peer_str, afi, safi, + PEER_FLAG_ORF_PREFIX_SM) | + peer_af_flag_set_vty(vty, peer_str, afi, safi, + PEER_FLAG_ORF_PREFIX_RM); + bgp_capability_send(peer, afi, safi, CAPABILITY_CODE_ORF, + CAPABILITY_ACTION_SET); + return ret; + } return CMD_WARNING_CONFIG_FAILED; } @@ -5804,24 +5992,37 @@ DEFUN (no_neighbor_capability_orf_prefix, struct peer *peer; afi_t afi = bgp_node_afi(vty); safi_t safi = bgp_node_safi(vty); + int ret; peer = peer_and_group_lookup_vty(vty, peer_str); if (!peer) return CMD_WARNING_CONFIG_FAILED; - if (strmatch(argv[idx_send_recv]->text, "send")) - return peer_af_flag_unset_vty(vty, peer_str, afi, safi, - PEER_FLAG_ORF_PREFIX_SM); + if (strmatch(argv[idx_send_recv]->text, "send")) { + ret = peer_af_flag_unset_vty(vty, peer_str, afi, safi, + PEER_FLAG_ORF_PREFIX_SM); + bgp_capability_send(peer, afi, safi, CAPABILITY_CODE_ORF, + CAPABILITY_ACTION_UNSET); + return ret; + } - if (strmatch(argv[idx_send_recv]->text, "receive")) - return peer_af_flag_unset_vty(vty, peer_str, afi, safi, - PEER_FLAG_ORF_PREFIX_RM); + if (strmatch(argv[idx_send_recv]->text, "receive")) { + ret = peer_af_flag_unset_vty(vty, peer_str, afi, safi, + PEER_FLAG_ORF_PREFIX_RM); + bgp_capability_send(peer, afi, safi, CAPABILITY_CODE_ORF, + CAPABILITY_ACTION_UNSET); + return ret; + } - if (strmatch(argv[idx_send_recv]->text, "both")) - return peer_af_flag_unset_vty(vty, peer_str, afi, safi, - PEER_FLAG_ORF_PREFIX_SM) - | peer_af_flag_unset_vty(vty, peer_str, afi, safi, - PEER_FLAG_ORF_PREFIX_RM); + if (strmatch(argv[idx_send_recv]->text, "both")) { + ret = peer_af_flag_unset_vty(vty, peer_str, afi, safi, + PEER_FLAG_ORF_PREFIX_SM) | + peer_af_flag_unset_vty(vty, peer_str, afi, safi, + PEER_FLAG_ORF_PREFIX_RM); + bgp_capability_send(peer, afi, safi, CAPABILITY_CODE_ORF, + CAPABILITY_ACTION_UNSET); + return ret; + } return CMD_WARNING_CONFIG_FAILED; } @@ -6308,6 +6509,32 @@ ALIAS_HIDDEN( "Send Standard Community attributes\n" "Send Large Community attributes\n") +DEFPY (neighbor_ecommunity_rpki, + neighbor_ecommunity_rpki_cmd, + "[no$no] neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor send-community extended rpki", + NO_STR + NEIGHBOR_STR + NEIGHBOR_ADDR_STR2 + "Send Community attribute to this neighbor\n" + "Send Extended Community attributes\n" + "Send RPKI Extended Community attributes\n") +{ + struct peer *peer; + afi_t afi = bgp_node_afi(vty); + safi_t safi = bgp_node_safi(vty); + + peer = peer_and_group_lookup_vty(vty, neighbor); + if (!peer) + return CMD_WARNING_CONFIG_FAILED; + + if (no) + return peer_af_flag_unset_vty(vty, neighbor, afi, safi, + PEER_FLAG_SEND_EXT_COMMUNITY_RPKI); + else + return peer_af_flag_set_vty(vty, neighbor, afi, safi, + PEER_FLAG_SEND_EXT_COMMUNITY_RPKI); +} + /* neighbor soft-reconfig. */ DEFUN (neighbor_soft_reconfiguration, neighbor_soft_reconfiguration_cmd, @@ -6739,14 +6966,9 @@ static uint8_t get_role_by_name(const char *role_str) return ROLE_UNDEFINED; } -static int peer_role_set_vty(struct vty *vty, const char *ip_str, +static int peer_role_set_vty(struct vty *vty, struct peer *peer, const char *role_str, bool strict_mode) { - struct peer *peer; - - peer = peer_and_group_lookup_vty(vty, ip_str); - if (!peer) - return CMD_WARNING_CONFIG_FAILED; uint8_t role = get_role_by_name(role_str); if (role == ROLE_UNDEFINED) @@ -6754,50 +6976,56 @@ static int peer_role_set_vty(struct vty *vty, const char *ip_str, return bgp_vty_return(vty, peer_role_set(peer, role, strict_mode)); } -static int peer_role_unset_vty(struct vty *vty, const char *ip_str) -{ - struct peer *peer; - - peer = peer_and_group_lookup_vty(vty, ip_str); - if (!peer) - return CMD_WARNING_CONFIG_FAILED; - return bgp_vty_return(vty, peer_role_unset(peer)); -} - DEFPY(neighbor_role, neighbor_role_cmd, - "neighbor <A.B.C.D|X:X::X:X|WORD> local-role <provider|rs-server|rs-client|customer|peer>", + "neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor local-role <provider|rs-server|rs-client|customer|peer>$role", NEIGHBOR_STR NEIGHBOR_ADDR_STR2 "Set session role\n" ROLE_STR) { - int idx_peer = 1; - int idx_role = 3; + int ret; + struct peer *peer; - return peer_role_set_vty(vty, argv[idx_peer]->arg, argv[idx_role]->arg, - false); + peer = peer_and_group_lookup_vty(vty, neighbor); + if (!peer) + return CMD_WARNING_CONFIG_FAILED; + + ret = peer_role_set_vty(vty, peer, role, false); + + bgp_capability_send(peer, AFI_IP, SAFI_UNICAST, CAPABILITY_CODE_ROLE, + CAPABILITY_ACTION_SET); + + return ret; } DEFPY(neighbor_role_strict, neighbor_role_strict_cmd, - "neighbor <A.B.C.D|X:X::X:X|WORD> local-role <provider|rs-server|rs-client|customer|peer> strict-mode", + "neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor local-role <provider|rs-server|rs-client|customer|peer>$role strict-mode", NEIGHBOR_STR NEIGHBOR_ADDR_STR2 "Set session role\n" ROLE_STR "Use additional restriction on peer\n") { - int idx_peer = 1; - int idx_role = 3; + int ret; + struct peer *peer; - return peer_role_set_vty(vty, argv[idx_peer]->arg, argv[idx_role]->arg, - true); + peer = peer_and_group_lookup_vty(vty, neighbor); + if (!peer) + return CMD_WARNING_CONFIG_FAILED; + + ret = peer_role_set_vty(vty, peer, role, true); + + bgp_capability_send(peer, AFI_IP, SAFI_UNICAST, CAPABILITY_CODE_ROLE, + CAPABILITY_ACTION_SET); + + return ret; } DEFPY(no_neighbor_role, no_neighbor_role_cmd, - "no neighbor <A.B.C.D|X:X::X:X|WORD> local-role <provider|rs-server|rs-client|customer|peer> [strict-mode]", + "no neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor local-role <provider|rs-server|rs-client|customer|peer> [strict-mode]", NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2 @@ -6805,9 +7033,41 @@ DEFPY(no_neighbor_role, ROLE_STR "Use additional restriction on peer\n") { - int idx_peer = 2; + int ret; + struct peer *peer; + + peer = peer_and_group_lookup_vty(vty, neighbor); + if (!peer) + return CMD_WARNING_CONFIG_FAILED; + + ret = bgp_vty_return(vty, peer_role_unset(peer)); + + bgp_capability_send(peer, AFI_IP, SAFI_UNICAST, CAPABILITY_CODE_ROLE, + CAPABILITY_ACTION_UNSET); + + return ret; +} + +DEFPY (neighbor_oad, + neighbor_oad_cmd, + "[no$no] neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor oad", + NO_STR + NEIGHBOR_STR + NEIGHBOR_ADDR_STR2 + "Set peering session type to EBGP-OAD\n") +{ + struct peer *peer; - return peer_role_unset_vty(vty, argv[idx_peer]->arg); + peer = peer_and_group_lookup_vty(vty, neighbor); + if (!peer) + return CMD_WARNING_CONFIG_FAILED; + + if (no) + peer->sub_sort = 0; + else if (peer->sort == BGP_PEER_EBGP) + peer->sub_sort = BGP_PEER_EBGP_OAD; + + return CMD_SUCCESS; } /* disable-connected-check */ @@ -7553,7 +7813,7 @@ DEFUN (bgp_set_route_map_delay_timer, if (!rmap_delay_timer && bm->t_rmap_update) { EVENT_OFF(bm->t_rmap_update); event_execute(bm->master, bgp_route_map_update_timer, - NULL, 0); + NULL, 0, NULL); } return CMD_SUCCESS; } else { @@ -7949,6 +8209,26 @@ DEFPY (bgp_condadv_period, return CMD_SUCCESS; } +DEFPY (bgp_def_originate_eval, + bgp_def_originate_eval_cmd, + "[no$no] bgp default-originate timer (0-3600)$timer", + NO_STR + BGP_STR + "Control default-originate\n" + "Set period to rescan BGP table to check if default-originate condition is met\n" + "Period between BGP table scans, in seconds; default 5\n") +{ + VTY_DECLVAR_CONTEXT(bgp, bgp); + + bgp->rmap_def_originate_eval_timer = + no ? RMAP_DEFAULT_ORIGINATE_EVAL_TIMER : timer; + + if (bgp->t_rmap_def_originate_eval) + EVENT_OFF(bgp->t_rmap_def_originate_eval); + + return CMD_SUCCESS; +} + DEFPY (neighbor_advertise_map, neighbor_advertise_map_cmd, "[no$no] neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor advertise-map RMAP_NAME$advertise_str <exist-map|non-exist-map>$exist RMAP_NAME$condition_str", @@ -8557,6 +8837,8 @@ DEFPY (neighbor_soo, ecommunity_free(&peer->soo[afi][safi]); peer->soo[afi][safi] = ecomm_soo; peer_af_flag_unset(peer, afi, safi, PEER_FLAG_SOO); + } else { + ecommunity_free(&ecomm_soo); } return bgp_vty_return(vty, @@ -8728,13 +9010,21 @@ DEFUN(neighbor_disable_addpath_rx, struct peer *peer; afi_t afi = bgp_node_afi(vty); safi_t safi = bgp_node_safi(vty); + int ret; + int action; peer = peer_and_group_lookup_vty(vty, peer_str); if (!peer) return CMD_WARNING_CONFIG_FAILED; - return peer_af_flag_set_vty(vty, peer_str, afi, safi, - PEER_FLAG_DISABLE_ADDPATH_RX); + action = bgp_addpath_capability_action(peer->addpath_type[afi][safi], 0); + + ret = peer_af_flag_set_vty(vty, peer_str, afi, safi, + PEER_FLAG_DISABLE_ADDPATH_RX); + + bgp_capability_send(peer, afi, safi, CAPABILITY_CODE_ADDPATH, action); + + return ret; } DEFUN(no_neighbor_disable_addpath_rx, @@ -8749,13 +9039,21 @@ DEFUN(no_neighbor_disable_addpath_rx, struct peer *peer; afi_t afi = bgp_node_afi(vty); safi_t safi = bgp_node_safi(vty); + int ret; + int action; peer = peer_and_group_lookup_vty(vty, peer_str); if (!peer) return CMD_WARNING_CONFIG_FAILED; - return peer_af_flag_unset_vty(vty, peer_str, afi, safi, - PEER_FLAG_DISABLE_ADDPATH_RX); + action = bgp_addpath_capability_action(peer->addpath_type[afi][safi], 0); + + ret = peer_af_flag_unset_vty(vty, peer_str, afi, safi, + PEER_FLAG_DISABLE_ADDPATH_RX); + + bgp_capability_send(peer, afi, safi, CAPABILITY_CODE_ADDPATH, action); + + return ret; } DEFUN (neighbor_addpath_tx_all_paths, @@ -8767,13 +9065,15 @@ DEFUN (neighbor_addpath_tx_all_paths, { int idx_peer = 1; struct peer *peer; + afi_t afi = bgp_node_afi(vty); + safi_t safi = bgp_node_safi(vty); peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg); if (!peer) return CMD_WARNING_CONFIG_FAILED; - bgp_addpath_set_peer_type(peer, bgp_node_afi(vty), bgp_node_safi(vty), - BGP_ADDPATH_ALL); + bgp_addpath_set_peer_type(peer, afi, safi, BGP_ADDPATH_ALL, 0); + return CMD_SUCCESS; } @@ -8793,20 +9093,20 @@ DEFUN (no_neighbor_addpath_tx_all_paths, { int idx_peer = 2; struct peer *peer; + afi_t afi = bgp_node_afi(vty); + safi_t safi = bgp_node_safi(vty); peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg); if (!peer) return CMD_WARNING_CONFIG_FAILED; - if (peer->addpath_type[bgp_node_afi(vty)][bgp_node_safi(vty)] - != BGP_ADDPATH_ALL) { + if (peer->addpath_type[afi][safi] != BGP_ADDPATH_ALL) { vty_out(vty, "%% Peer not currently configured to transmit all paths."); return CMD_WARNING_CONFIG_FAILED; } - bgp_addpath_set_peer_type(peer, bgp_node_afi(vty), bgp_node_safi(vty), - BGP_ADDPATH_NONE); + bgp_addpath_set_peer_type(peer, afi, safi, BGP_ADDPATH_NONE, 0); return CMD_SUCCESS; } @@ -8817,6 +9117,45 @@ ALIAS_HIDDEN(no_neighbor_addpath_tx_all_paths, NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2 "Use addpath to advertise all paths to a neighbor\n") +DEFPY (neighbor_addpath_tx_best_selected_paths, + neighbor_addpath_tx_best_selected_paths_cmd, + "neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor addpath-tx-best-selected (1-6)$paths", + NEIGHBOR_STR + NEIGHBOR_ADDR_STR2 + "Use addpath to advertise best selected paths to a neighbor\n" + "The number of best paths\n") +{ + struct peer *peer; + + peer = peer_and_group_lookup_vty(vty, neighbor); + if (!peer) + return CMD_WARNING_CONFIG_FAILED; + + bgp_addpath_set_peer_type(peer, bgp_node_afi(vty), bgp_node_safi(vty), + BGP_ADDPATH_BEST_SELECTED, paths); + return CMD_SUCCESS; +} + +DEFPY (no_neighbor_addpath_tx_best_selected_paths, + no_neighbor_addpath_tx_best_selected_paths_cmd, + "no neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor addpath-tx-best-selected [(1-6)]", + NO_STR + NEIGHBOR_STR + NEIGHBOR_ADDR_STR2 + "Use addpath to advertise best selected paths to a neighbor\n" + "The number of best paths\n") +{ + struct peer *peer; + + peer = peer_and_group_lookup_vty(vty, neighbor); + if (!peer) + return CMD_WARNING_CONFIG_FAILED; + + bgp_addpath_set_peer_type(peer, bgp_node_afi(vty), bgp_node_safi(vty), + BGP_ADDPATH_BEST_SELECTED, 0); + return CMD_SUCCESS; +} + DEFUN (neighbor_addpath_tx_bestpath_per_as, neighbor_addpath_tx_bestpath_per_as_cmd, "neighbor <A.B.C.D|X:X::X:X|WORD> addpath-tx-bestpath-per-AS", @@ -8832,7 +9171,7 @@ DEFUN (neighbor_addpath_tx_bestpath_per_as, return CMD_WARNING_CONFIG_FAILED; bgp_addpath_set_peer_type(peer, bgp_node_afi(vty), bgp_node_safi(vty), - BGP_ADDPATH_BEST_PER_AS); + BGP_ADDPATH_BEST_PER_AS, 0); return CMD_SUCCESS; } @@ -8866,7 +9205,7 @@ DEFUN (no_neighbor_addpath_tx_bestpath_per_as, } bgp_addpath_set_peer_type(peer, bgp_node_afi(vty), bgp_node_safi(vty), - BGP_ADDPATH_NONE); + BGP_ADDPATH_NONE, 0); return CMD_SUCCESS; } @@ -8884,15 +9223,64 @@ DEFPY( NEIGHBOR_ADDR_STR2 "Detect AS loops before sending to neighbor\n") { + return peer_flag_set_vty(vty, neighbor, PEER_FLAG_AS_LOOP_DETECTION); +} + +DEFPY (neighbor_addpath_paths_limit, + neighbor_addpath_paths_limit_cmd, + "neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor addpath-rx-paths-limit (1-65535)$paths_limit", + NEIGHBOR_STR + NEIGHBOR_ADDR_STR2 + "Paths Limit for Addpath to receive from the peer\n" + "Maximum number of paths\n") +{ struct peer *peer; + afi_t afi = bgp_node_afi(vty); + safi_t safi = bgp_node_safi(vty); + int ret; peer = peer_and_group_lookup_vty(vty, neighbor); if (!peer) return CMD_WARNING_CONFIG_FAILED; - peer->as_path_loop_detection = true; + ret = peer_af_flag_set_vty(vty, neighbor, afi, safi, + PEER_FLAG_ADDPATH_RX_PATHS_LIMIT); - return CMD_SUCCESS; + peer->addpath_paths_limit[afi][safi].send = paths_limit; + + bgp_capability_send(peer, afi, safi, CAPABILITY_CODE_PATHS_LIMIT, + CAPABILITY_ACTION_SET); + + return ret; +} + +DEFPY (no_neighbor_addpath_paths_limit, + no_neighbor_addpath_paths_limit_cmd, + "no neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor addpath-rx-paths-limit [(1-65535)]", + NO_STR + NEIGHBOR_STR + NEIGHBOR_ADDR_STR2 + "Paths Limit for Addpath to receive from the peer\n" + "Maximum number of paths\n") +{ + struct peer *peer; + afi_t afi = bgp_node_afi(vty); + safi_t safi = bgp_node_safi(vty); + int ret; + + peer = peer_and_group_lookup_vty(vty, neighbor); + if (!peer) + return CMD_WARNING_CONFIG_FAILED; + + ret = peer_af_flag_unset_vty(vty, neighbor, afi, safi, + PEER_FLAG_ADDPATH_RX_PATHS_LIMIT); + + peer->addpath_paths_limit[afi][safi].send = 0; + + bgp_capability_send(peer, afi, safi, CAPABILITY_CODE_PATHS_LIMIT, + CAPABILITY_ACTION_SET); + + return ret; } DEFPY( @@ -8904,15 +9292,7 @@ DEFPY( NEIGHBOR_ADDR_STR2 "Detect AS loops before sending to neighbor\n") { - struct peer *peer; - - peer = peer_and_group_lookup_vty(vty, neighbor); - if (!peer) - return CMD_WARNING_CONFIG_FAILED; - - peer->as_path_loop_detection = false; - - return CMD_SUCCESS; + return peer_flag_unset_vty(vty, neighbor, PEER_FLAG_AS_LOOP_DETECTION); } DEFPY(neighbor_path_attribute_discard, @@ -9147,13 +9527,13 @@ DEFPY (af_rd_vpn_export, bgp_get_default(), bgp); if (yes) { - bgp->vpn_policy[afi].tovpn_rd_pretty = - XSTRDUP(MTYPE_BGP, rd_str); + bgp->vpn_policy[afi].tovpn_rd_pretty = XSTRDUP(MTYPE_BGP_NAME, + rd_str); bgp->vpn_policy[afi].tovpn_rd = prd; SET_FLAG(bgp->vpn_policy[afi].flags, BGP_VPN_POLICY_TOVPN_RD_SET); } else { - XFREE(MTYPE_BGP, bgp->vpn_policy[afi].tovpn_rd_pretty); + XFREE(MTYPE_BGP_NAME, bgp->vpn_policy[afi].tovpn_rd_pretty); UNSET_FLAG(bgp->vpn_policy[afi].flags, BGP_VPN_POLICY_TOVPN_RD_SET); } @@ -9173,6 +9553,65 @@ ALIAS (af_rd_vpn_export, "Between current address-family and vpn\n" "For routes leaked from current address-family to vpn\n") +DEFPY(af_label_vpn_export_allocation_mode, + af_label_vpn_export_allocation_mode_cmd, + "[no$no] label vpn export allocation-mode <per-vrf$label_per_vrf|per-nexthop$label_per_nh>", + NO_STR + "label value for VRF\n" + "Between current address-family and vpn\n" + "For routes leaked from current address-family to vpn\n" + "Label allocation mode\n" + "Allocate one label for all BGP updates of the VRF\n" + "Allocate a label per connected next-hop in the VRF\n") +{ + VTY_DECLVAR_CONTEXT(bgp, bgp); + afi_t afi; + bool old_per_nexthop, new_per_nexthop; + + afi = vpn_policy_getafi(vty, bgp, false); + if (afi == AFI_MAX) + return CMD_WARNING_CONFIG_FAILED; + + old_per_nexthop = !!CHECK_FLAG(bgp->vpn_policy[afi].flags, + BGP_VPN_POLICY_TOVPN_LABEL_PER_NEXTHOP); + if (no) { + if (old_per_nexthop == false && label_per_nh) + return CMD_ERR_NO_MATCH; + if (old_per_nexthop == true && label_per_vrf) + return CMD_ERR_NO_MATCH; + new_per_nexthop = false; + } else { + if (label_per_nh) + new_per_nexthop = true; + else + new_per_nexthop = false; + } + + /* no change */ + if (old_per_nexthop == new_per_nexthop) + return CMD_SUCCESS; + + /* + * pre-change: un-export vpn routes (vpn->vrf routes unaffected) + */ + vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp_get_default(), + bgp); + + if (new_per_nexthop) + SET_FLAG(bgp->vpn_policy[afi].flags, + BGP_VPN_POLICY_TOVPN_LABEL_PER_NEXTHOP); + else + UNSET_FLAG(bgp->vpn_policy[afi].flags, + BGP_VPN_POLICY_TOVPN_LABEL_PER_NEXTHOP); + + /* post-change: re-export vpn routes */ + vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp_get_default(), + bgp); + + hook_call(bgp_snmp_update_last_changed, bgp); + return CMD_SUCCESS; +} + DEFPY (af_label_vpn_export, af_label_vpn_export_cmd, "[no] label vpn export <(0-1048575)$label_val|auto$label_auto>", @@ -9184,7 +9623,7 @@ DEFPY (af_label_vpn_export, "Automatically assign a label\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); - mpls_label_t label = MPLS_LABEL_NONE; + mpls_label_t label = (mpls_label_t)label_val; afi_t afi; int idx = 0; bool yes = true; @@ -9192,24 +9631,28 @@ DEFPY (af_label_vpn_export, if (argv_find(argv, argc, "no", &idx)) yes = false; - /* If "no ...", squash trailing parameter */ - if (!yes) - label_auto = NULL; - - if (yes) { - if (!label_auto) - label = label_val; /* parser should force unsigned */ - } - afi = vpn_policy_getafi(vty, bgp, false); if (afi == AFI_MAX) return CMD_WARNING_CONFIG_FAILED; - - if (label_auto && CHECK_FLAG(bgp->vpn_policy[afi].flags, - BGP_VPN_POLICY_TOVPN_LABEL_AUTO)) - /* no change */ - return CMD_SUCCESS; + if (yes) { + if (label_auto && CHECK_FLAG(bgp->vpn_policy[afi].flags, + BGP_VPN_POLICY_TOVPN_LABEL_AUTO)) + /* no change */ + return CMD_SUCCESS; + if (!label_auto && label == bgp->vpn_policy[afi].tovpn_label) + /* no change */ + return CMD_SUCCESS; + } else { + if (label_auto && !CHECK_FLAG(bgp->vpn_policy[afi].flags, + BGP_VPN_POLICY_TOVPN_LABEL_AUTO)) + /* no match */ + return CMD_WARNING_CONFIG_FAILED; + if (!label_auto && label_val && + label != bgp->vpn_policy[afi].tovpn_label) + /* no change */ + return CMD_WARNING_CONFIG_FAILED; + } /* * pre-change: un-export vpn routes (vpn->vrf routes unaffected) @@ -9217,9 +9660,16 @@ DEFPY (af_label_vpn_export, vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp_get_default(), bgp); - if (!label_auto && CHECK_FLAG(bgp->vpn_policy[afi].flags, - BGP_VPN_POLICY_TOVPN_LABEL_AUTO)) { + if (CHECK_FLAG(bgp->vpn_policy[afi].flags, + BGP_VPN_POLICY_TOVPN_LABEL_MANUAL_REG)) { + bgp_zebra_release_label_range(bgp->vpn_policy[afi].tovpn_label, + bgp->vpn_policy[afi].tovpn_label); + UNSET_FLAG(bgp->vpn_policy[afi].flags, + BGP_VPN_POLICY_TOVPN_LABEL_MANUAL_REG); + } else if (CHECK_FLAG(bgp->vpn_policy[afi].flags, + BGP_VPN_POLICY_TOVPN_LABEL_AUTO)) { + /* release any previous auto label */ if (bgp->vpn_policy[afi].tovpn_label != MPLS_LABEL_NONE) { /* @@ -9236,16 +9686,32 @@ DEFPY (af_label_vpn_export, &bgp->vpn_policy[afi], bgp->vpn_policy[afi].tovpn_label); } - UNSET_FLAG(bgp->vpn_policy[afi].flags, - BGP_VPN_POLICY_TOVPN_LABEL_AUTO); } - bgp->vpn_policy[afi].tovpn_label = label; - if (label_auto) { - SET_FLAG(bgp->vpn_policy[afi].flags, - BGP_VPN_POLICY_TOVPN_LABEL_AUTO); - bgp_lp_get(LP_TYPE_VRF, &bgp->vpn_policy[afi], - vpn_leak_label_callback); + if (yes) { + if (label_auto) { + SET_FLAG(bgp->vpn_policy[afi].flags, + BGP_VPN_POLICY_TOVPN_LABEL_AUTO); + /* fetch a label */ + bgp->vpn_policy[afi].tovpn_label = MPLS_LABEL_NONE; + bgp_lp_get(LP_TYPE_VRF, &bgp->vpn_policy[afi], + vpn_leak_label_callback); + } else { + bgp->vpn_policy[afi].tovpn_label = label; + UNSET_FLAG(bgp->vpn_policy[afi].flags, + BGP_VPN_POLICY_TOVPN_LABEL_AUTO); + if (bgp->vpn_policy[afi].tovpn_label >= + MPLS_LABEL_UNRESERVED_MIN && + bgp_zebra_request_label_range(bgp->vpn_policy[afi] + .tovpn_label, + 1, false)) + SET_FLAG(bgp->vpn_policy[afi].flags, + BGP_VPN_POLICY_TOVPN_LABEL_MANUAL_REG); + } + } else { + UNSET_FLAG(bgp->vpn_policy[afi].flags, + BGP_VPN_POLICY_TOVPN_LABEL_AUTO); + bgp->vpn_policy[afi].tovpn_label = MPLS_LABEL_NONE; } /* post-change: re-export vpn routes */ @@ -9282,9 +9748,24 @@ DEFPY (af_sid_vpn_export, return CMD_WARNING_CONFIG_FAILED; if (!yes) { - /* implement me */ - vty_out(vty, "It's not implemented\n"); - return CMD_WARNING_CONFIG_FAILED; + /* when SID is not set, do nothing */ + if ((bgp->vpn_policy[afi].tovpn_sid_index == 0) && + !CHECK_FLAG(bgp->vpn_policy[afi].flags, + BGP_VPN_POLICY_TOVPN_SID_AUTO)) + return CMD_SUCCESS; + + /* pre-change */ + vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi, + bgp_get_default(), bgp); + bgp->vpn_policy[afi].tovpn_sid_index = 0; + UNSET_FLAG(bgp->vpn_policy[afi].flags, + BGP_VPN_POLICY_TOVPN_SID_AUTO); + + /* post-change */ + vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi, + bgp_get_default(), bgp); + + return CMD_SUCCESS; } if (bgp->tovpn_sid_index != 0 || @@ -9323,7 +9804,7 @@ DEFPY (af_sid_vpn_export, zlog_debug("%s: auto sid alloc.", __func__); SET_FLAG(bgp->vpn_policy[afi].flags, BGP_VPN_POLICY_TOVPN_SID_AUTO); - } else { + } else if (sid_idx != 0) { /* SID allocation index-mode */ if (debug) zlog_debug("%s: idx %ld sid alloc.", __func__, sid_idx); @@ -9850,6 +10331,7 @@ DEFPY (bgp_imexport_vpn, bool yes = true; int flag; enum vpn_policy_direction dir; + struct bgp *bgp_default = bgp_get_default(); if (argv_find(argv, argc, "no", &idx)) yes = false; @@ -9885,14 +10367,18 @@ DEFPY (bgp_imexport_vpn, SET_FLAG(bgp->af_flags[afi][safi], flag); if (!previous_state) { /* trigger export current vrf */ - vpn_leak_postchange(dir, afi, bgp_get_default(), bgp); + vpn_leak_postchange(dir, afi, bgp_default, bgp); } } else { if (previous_state) { /* trigger un-export current vrf */ - vpn_leak_prechange(dir, afi, bgp_get_default(), bgp); + vpn_leak_prechange(dir, afi, bgp_default, bgp); } UNSET_FLAG(bgp->af_flags[afi][safi], flag); + if (previous_state && bgp_default && + !CHECK_FLAG(bgp_default->af_flags[afi][SAFI_MPLS_VPN], + BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL)) + vpn_leak_no_retain(bgp, bgp_default, afi); } hook_call(bgp_snmp_init_stats, bgp); @@ -10276,7 +10762,7 @@ static int bgp_clear_prefix(struct vty *vty, const char *view_name, /* one clear bgp command to rule them all */ DEFUN (clear_ip_bgp_all, clear_ip_bgp_all_cmd, - "clear [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6|l2vpn> [<unicast|multicast|vpn|labeled-unicast|flowspec|evpn>]] <*|A.B.C.D$neighbor|X:X::X:X$neighbor|WORD$neighbor|ASNUM|external|peer-group PGNAME> [<soft [<in|out>]|in [prefix-filter]|out|message-stats>]", + "clear [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6|l2vpn> [<unicast|multicast|vpn|labeled-unicast|flowspec|evpn>]] <*|A.B.C.D$neighbor|X:X::X:X$neighbor|WORD$neighbor|ASNUM|external|peer-group PGNAME> [<soft [<in|out>]|in [prefix-filter]|out|message-stats|capabilities>]", CLEAR_STR IP_STR BGP_STR @@ -10299,7 +10785,8 @@ DEFUN (clear_ip_bgp_all, BGP_SOFT_IN_STR "Push out prefix-list ORF and do inbound soft reconfig\n" BGP_SOFT_OUT_STR - "Reset message statistics\n") + "Reset message statistics\n" + "Resend capabilities\n") { char *vrf = NULL; @@ -10356,7 +10843,7 @@ DEFUN (clear_ip_bgp_all, clr_sort = clear_external; } - /* [<soft [<in|out>]|in [prefix-filter]|out|message-stats>] */ + /* [<soft [<in|out>]|in [prefix-filter]|out|message-stats|capabilities>] */ if (argv_find(argv, argc, "soft", &idx)) { if (argv_find(argv, argc, "in", &idx) || argv_find(argv, argc, "out", &idx)) @@ -10373,6 +10860,8 @@ DEFUN (clear_ip_bgp_all, clr_type = BGP_CLEAR_SOFT_OUT; } else if (argv_find(argv, argc, "message-stats", &idx)) { clr_type = BGP_CLEAR_MESSAGE_STATS; + } else if (argv_find(argv, argc, "capabilities", &idx)) { + clr_type = BGP_CLEAR_CAPABILITIES; } else clr_type = BGP_CLEAR_SOFT_NONE; @@ -10505,7 +10994,7 @@ static inline void calc_peers_cfgd_estbd(struct bgp *bgp, int *peers_cfgd, if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE)) continue; (*peers_cfgd)++; - if (peer_established(peer)) + if (peer_established(peer->connection)) (*peers_estbd)++; } } @@ -10784,6 +11273,29 @@ DEFUN (show_bgp_memory, memstrbuf, sizeof(memstrbuf), count * sizeof(struct bgp_path_info_extra))); + count = mtype_stats_alloc(MTYPE_BGP_ROUTE_EXTRA_EVPN); + if (count) + vty_out(vty, "%ld BGP extra info for EVPN, using %s of memory\n", + count, + mtype_memstr(memstrbuf, sizeof(memstrbuf), + count * sizeof(struct bgp_path_info_extra_evpn))); + + count = mtype_stats_alloc(MTYPE_BGP_ROUTE_EXTRA_FS); + if (count) + vty_out(vty, + "%ld BGP extra info for flowspec, using %s of memory\n", + count, + mtype_memstr(memstrbuf, sizeof(memstrbuf), + count * sizeof(struct bgp_path_info_extra_fs))); + + count = mtype_stats_alloc(MTYPE_BGP_ROUTE_EXTRA_VRFLEAK); + if (count) + vty_out(vty, + "%ld BGP extra info for vrf leaking, using %s of memory\n", + count, + mtype_memstr(memstrbuf, sizeof(memstrbuf), + count * sizeof(struct bgp_path_info_extra_vrfleak))); + if ((count = mtype_stats_alloc(MTYPE_BGP_STATIC))) vty_out(vty, "%ld Static routes, using %s of memory\n", count, mtype_memstr(memstrbuf, sizeof(memstrbuf), @@ -10962,11 +11474,9 @@ static void bgp_show_peer_reset(struct vty * vty, struct peer *peer, msgbuf, sizeof(msgbuf), (uint8_t *)peer->notify.data, peer->notify.length); - if (msg_str) - json_object_string_add( - json_peer, - "lastShutdownDescription", - msg_str); + json_object_string_add(json_peer, + "lastShutdownDescription", + msg_str); } } @@ -11006,7 +11516,8 @@ static void bgp_show_peer_reset(struct vty * vty, struct peer *peer, static inline bool bgp_has_peer_failed(struct peer *peer, afi_t afi, safi_t safi) { - return ((!peer_established(peer)) || !peer->afc_recv[afi][safi]); + return ((!peer_established(peer->connection)) || + !peer->afc_recv[afi][safi]); } static void bgp_show_failed_summary(struct vty *vty, struct bgp *bgp, @@ -11033,7 +11544,7 @@ static void bgp_show_failed_summary(struct vty *vty, struct bgp *bgp, peer->dropped); peer_uptime(peer->uptime, timebuf, BGP_UPTIME_LEN, use_json, json_peer); - if (peer_established(peer)) + if (peer_established(peer->connection)) json_object_string_add(json_peer, "lastResetDueTo", "AFI/SAFI Not Negotiated"); else @@ -11056,7 +11567,7 @@ static void bgp_show_failed_summary(struct vty *vty, struct bgp *bgp, peer->dropped, peer_uptime(peer->uptime, timebuf, BGP_UPTIME_LEN, 0, NULL)); - if (peer_established(peer)) + if (peer_established(peer->connection)) vty_out(vty, " AFI/SAFI Not Negotiated\n"); else bgp_show_peer_reset(vty, peer, NULL, @@ -11282,8 +11793,9 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, : bgp->name); } else { vty_out(vty, - "BGP router identifier %pI4, local AS number %s vrf-id %d", + "BGP router identifier %pI4, local AS number %s %s vrf-id %d", &bgp->router_id, bgp->as_pretty, + bgp->name_pretty, bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id); @@ -11531,15 +12043,22 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, PEER_TOTAL_TX(peer)); atomic_size_t outq_count, inq_count; - outq_count = atomic_load_explicit( - &peer->obuf->count, - memory_order_relaxed); - inq_count = atomic_load_explicit( - &peer->ibuf->count, - memory_order_relaxed); - - json_object_int_add(json_peer, "tableVersion", - peer->version[afi][safi]); + outq_count = + atomic_load_explicit(&peer->connection + ->obuf + ->count, + memory_order_relaxed); + inq_count = + atomic_load_explicit(&peer->connection + ->ibuf + ->count, + memory_order_relaxed); + + json_object_int_add( + json_peer, "tableVersion", + (paf && PAF_SUBGRP(paf)) + ? paf->subgroup->version + : 0); json_object_int_add(json_peer, "outq", outq_count); json_object_int_add(json_peer, "inq", @@ -11569,7 +12088,8 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, json_object_string_add( json_peer, "state", lookup_msg(bgp_status_msg, - peer->status, NULL)); + peer->connection->status, + NULL)); else if (CHECK_FLAG( peer->sflags, PEER_STATUS_PREFIX_OVERFLOW)) @@ -11580,7 +12100,8 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, json_object_string_add( json_peer, "state", lookup_msg(bgp_status_msg, - peer->status, NULL)); + peer->connection->status, + NULL)); /* BGP peer state */ if (CHECK_FLAG(peer->flags, PEER_FLAG_SHUTDOWN) @@ -11634,10 +12155,10 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, if (peer->conf_if) json_object_string_add(json_peer, "idType", "interface"); - else if (peer->su.sa.sa_family == AF_INET) + else if (peer->connection->su.sa.sa_family == AF_INET) json_object_string_add(json_peer, "idType", "ipv4"); - else if (peer->su.sa.sa_family == AF_INET6) + else if (peer->connection->su.sa.sa_family == AF_INET6) json_object_string_add(json_peer, "idType", "ipv6"); json_object_object_add(json_peers, peer->host, @@ -11696,14 +12217,18 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, " "); atomic_size_t outq_count, inq_count; - outq_count = atomic_load_explicit( - &peer->obuf->count, - memory_order_relaxed); - inq_count = atomic_load_explicit( - &peer->ibuf->count, - memory_order_relaxed); - - vty_out(vty, "4 "); + outq_count = + atomic_load_explicit(&peer->connection + ->obuf + ->count, + memory_order_relaxed); + inq_count = + atomic_load_explicit(&peer->connection + ->ibuf + ->count, + memory_order_relaxed); + + vty_out(vty, "4"); vty_out(vty, ASN_FORMAT_SPACE(bgp->asnotation), &peer->as); if (show_wide) @@ -11717,12 +12242,14 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, " %9u %9u %8" PRIu64 " %4zu %4zu %8s", PEER_TOTAL_RX(peer), PEER_TOTAL_TX(peer), - peer->version[afi][safi], inq_count, - outq_count, + (paf && PAF_SUBGRP(paf)) + ? paf->subgroup->version + : 0, + inq_count, outq_count, peer_uptime(peer->uptime, timebuf, BGP_UPTIME_LEN, 0, NULL)); - if (peer_established(peer)) { + if (peer_established(peer->connection)) { if (peer->afc_recv[afi][safi]) { if (CHECK_FLAG( bgp->flags, @@ -11771,20 +12298,31 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, else vty_out(vty, " %12s", lookup_msg(bgp_status_msg, - peer->status, NULL)); + peer->connection + ->status, + NULL)); vty_out(vty, " %8u", 0); } /* Make sure `Desc` column is the lastest in * the output. + * If the description is not set, try + * to print the software version if the + * capability is enabled and received. */ if (peer->desc) vty_out(vty, " %s", bgp_peer_description_stripped( peer->desc, show_wide ? 64 : 20)); - else + else if (peer->soft_version) { + vty_out(vty, " %s", + bgp_peer_description_stripped( + peer->soft_version, + show_wide ? 64 : 20)); + } else { vty_out(vty, " N/A"); + } vty_out(vty, "\n"); } @@ -11874,12 +12412,10 @@ static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi, safi, true)); } else { - vty_out(vty, - "\n%s Summary (%s):\n", + vty_out(vty, "\n%s Summary:\n", get_afi_safi_str(afi, safi, - false), - bgp->name_pretty); + false)); } } bgp_show_summary(vty, bgp, afi, safi, fpeer, @@ -12167,9 +12703,9 @@ static void bgp_show_neighnor_graceful_restart_flags(struct vty *vty, bool rbit = false; bool nbit = false; - if (CHECK_FLAG(p->cap, PEER_CAP_RESTART_ADV) - && (CHECK_FLAG(p->cap, PEER_CAP_RESTART_RCV)) - && (peer_established(p))) { + if (CHECK_FLAG(p->cap, PEER_CAP_RESTART_ADV) && + (CHECK_FLAG(p->cap, PEER_CAP_RESTART_RCV)) && + (peer_established(p->connection))) { rbit = CHECK_FLAG(p->cap, PEER_CAP_GRACEFUL_RESTART_R_BIT_RCV); nbit = CHECK_FLAG(p->cap, PEER_CAP_GRACEFUL_RESTART_N_BIT_RCV); } @@ -12192,9 +12728,8 @@ static void bgp_show_neighbor_graceful_restart_remote_mode(struct vty *vty, if (!json) vty_out(vty, "\n Remote GR Mode: "); - if (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_ADV) - && (peer_established(peer))) { - + if (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_ADV) && + (peer_established(peer->connection))) { if ((peer->nsf_af_count == 0) && !CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV)) { @@ -12215,7 +12750,7 @@ static void bgp_show_neighbor_graceful_restart_remote_mode(struct vty *vty, if (json) json_object_string_add(json, "remoteGrMode", mode); else - vty_out(vty, "%s\n", mode); + vty_out(vty, "%s", mode); } static void bgp_show_neighbor_graceful_restart_local_mode(struct vty *vty, @@ -12247,7 +12782,7 @@ static void bgp_show_neighbor_graceful_restart_local_mode(struct vty *vty, if (json) json_object_string_add(json, "localGrMode", mode); else - vty_out(vty, "%s\n", mode); + vty_out(vty, "%s", mode); } static void bgp_show_neighbor_graceful_restart_capability_per_afi_safi( @@ -12356,12 +12891,15 @@ static void bgp_show_neighbor_graceful_restart_capability_per_afi_safi( if (json) { json_object_int_add(json_timer, "stalePathTimer", peer->bgp->stalepath_time); + json_object_int_add(json_timer, "llgrStaleTime", + peer->llgr[afi][safi].stale_time); - if (peer->t_gr_stale != NULL) { + if (peer->connection->t_gr_stale != NULL) { json_object_int_add(json_timer, "stalePathTimerRemaining", event_timer_remain_second( - peer->t_gr_stale)); + peer->connection + ->t_gr_stale)); } /* Display Configured Selection @@ -12391,11 +12929,11 @@ static void bgp_show_neighbor_graceful_restart_capability_per_afi_safi( " Configured Stale Path Time(sec): %u\n", peer->bgp->stalepath_time); - if (peer->t_gr_stale != NULL) + if (peer->connection->t_gr_stale != NULL) vty_out(vty, " Stale Path Remaining(sec): %ld\n", event_timer_remain_second( - peer->t_gr_stale)); + peer->connection->t_gr_stale)); /* Display Configured Selection * Deferral only when when * Gr mode is enabled. @@ -12405,6 +12943,9 @@ static void bgp_show_neighbor_graceful_restart_capability_per_afi_safi( " Configured Selection Deferral Time(sec): %u\n", peer->bgp->select_defer_time); + vty_out(vty, " LLGR Stale Path Time(sec): %u\n", + peer->llgr[afi][safi].stale_time); + if (peer->bgp->gr_info[afi][safi].t_select_deferral != NULL) vty_out(vty, @@ -12436,14 +12977,16 @@ static void bgp_show_neighbor_graceful_restart_time(struct vty *vty, json_object_int_add(json_timer, "configuredRestartTimer", p->bgp->restart_time); + json_object_int_add(json_timer, "configuredLlgrStaleTime", + p->bgp->llgr_stale_time); json_object_int_add(json_timer, "receivedRestartTimer", p->v_gr_restart); - if (p->t_gr_restart != NULL) - json_object_int_add( - json_timer, "restartTimerRemaining", - event_timer_remain_second(p->t_gr_restart)); + if (p->connection->t_gr_restart != NULL) + json_object_int_add(json_timer, "restartTimerRemaining", + event_timer_remain_second( + p->connection->t_gr_restart)); json_object_object_add(json, "timers", json_timer); } else { @@ -12454,12 +12997,16 @@ static void bgp_show_neighbor_graceful_restart_time(struct vty *vty, vty_out(vty, " Received Restart Time(sec): %u\n", p->v_gr_restart); - if (p->t_gr_restart != NULL) + vty_out(vty, " Configured LLGR Stale Path Time(sec): %u\n", + p->bgp->llgr_stale_time); + if (p->connection->t_gr_restart != NULL) vty_out(vty, " Restart Time Remaining(sec): %ld\n", - event_timer_remain_second(p->t_gr_restart)); - if (p->t_gr_restart != NULL) { + event_timer_remain_second( + p->connection->t_gr_restart)); + if (p->connection->t_gr_restart != NULL) { vty_out(vty, " Restart Time Remaining(sec): %ld\n", - event_timer_remain_second(p->t_gr_restart)); + event_timer_remain_second( + p->connection->t_gr_restart)); } } } @@ -12477,10 +13024,10 @@ static void bgp_show_peer_gr_status(struct vty *vty, struct peer *p, if (p->conf_if) { if (json) json_object_string_addf(json, "neighborAddr", "%pSU", - &p->su); + &p->connection->su); else vty_out(vty, "BGP neighbor on %s: %pSU\n", p->conf_if, - &p->su); + &p->connection->su); } else { snprintf(neighborAddr, sizeof(neighborAddr), "%s%s", dn_flag, p->host); @@ -12506,7 +13053,6 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi, int orf_pfx_count; json_object *json_af = NULL; json_object *json_prefA = NULL; - json_object *json_prefB = NULL; json_object *json_addr = NULL; json_object *json_advmap = NULL; @@ -12549,37 +13095,13 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi, json_prefA); } - if (CHECK_FLAG(p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV) - || CHECK_FLAG(p->af_cap[afi][safi], - PEER_CAP_ORF_PREFIX_SM_OLD_RCV) - || CHECK_FLAG(p->af_cap[afi][safi], - PEER_CAP_ORF_PREFIX_RM_ADV) - || CHECK_FLAG(p->af_cap[afi][safi], - PEER_CAP_ORF_PREFIX_RM_OLD_RCV)) { - json_object_int_add(json_af, "orfOldType", - ORF_TYPE_PREFIX_OLD); - json_prefB = json_object_new_object(); - bgp_show_peer_afi_orf_cap( - vty, p, afi, safi, PEER_CAP_ORF_PREFIX_SM_ADV, - PEER_CAP_ORF_PREFIX_RM_ADV, - PEER_CAP_ORF_PREFIX_SM_OLD_RCV, - PEER_CAP_ORF_PREFIX_RM_OLD_RCV, use_json, - json_prefB); - json_object_object_add(json_af, "orfOldPrefixList", - json_prefB); - } - - if (CHECK_FLAG(p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV) - || CHECK_FLAG(p->af_cap[afi][safi], - PEER_CAP_ORF_PREFIX_SM_RCV) - || CHECK_FLAG(p->af_cap[afi][safi], - PEER_CAP_ORF_PREFIX_SM_OLD_RCV) - || CHECK_FLAG(p->af_cap[afi][safi], - PEER_CAP_ORF_PREFIX_RM_ADV) - || CHECK_FLAG(p->af_cap[afi][safi], - PEER_CAP_ORF_PREFIX_RM_RCV) - || CHECK_FLAG(p->af_cap[afi][safi], - PEER_CAP_ORF_PREFIX_RM_OLD_RCV)) + if (CHECK_FLAG(p->af_cap[afi][safi], + PEER_CAP_ORF_PREFIX_SM_ADV) || + CHECK_FLAG(p->af_cap[afi][safi], + PEER_CAP_ORF_PREFIX_SM_RCV) || + CHECK_FLAG(p->af_cap[afi][safi], + PEER_CAP_ORF_PREFIX_RM_ADV) || + CHECK_FLAG(p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV)) json_object_object_add(json_addr, "afDependentCap", json_af); else @@ -12866,17 +13388,13 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi, } else { vty_out(vty, " Not part of any update group\n"); } - if (CHECK_FLAG(p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV) - || CHECK_FLAG(p->af_cap[afi][safi], - PEER_CAP_ORF_PREFIX_SM_RCV) - || CHECK_FLAG(p->af_cap[afi][safi], - PEER_CAP_ORF_PREFIX_SM_OLD_RCV) - || CHECK_FLAG(p->af_cap[afi][safi], - PEER_CAP_ORF_PREFIX_RM_ADV) - || CHECK_FLAG(p->af_cap[afi][safi], - PEER_CAP_ORF_PREFIX_RM_RCV) - || CHECK_FLAG(p->af_cap[afi][safi], - PEER_CAP_ORF_PREFIX_RM_OLD_RCV)) + if (CHECK_FLAG(p->af_cap[afi][safi], + PEER_CAP_ORF_PREFIX_SM_ADV) || + CHECK_FLAG(p->af_cap[afi][safi], + PEER_CAP_ORF_PREFIX_SM_RCV) || + CHECK_FLAG(p->af_cap[afi][safi], + PEER_CAP_ORF_PREFIX_RM_ADV) || + CHECK_FLAG(p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV)) vty_out(vty, " AF-dependant capabilities:\n"); if (CHECK_FLAG(p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV) @@ -12895,22 +13413,6 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi, PEER_CAP_ORF_PREFIX_SM_RCV, PEER_CAP_ORF_PREFIX_RM_RCV, use_json, NULL); } - if (CHECK_FLAG(p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV) - || CHECK_FLAG(p->af_cap[afi][safi], - PEER_CAP_ORF_PREFIX_SM_OLD_RCV) - || CHECK_FLAG(p->af_cap[afi][safi], - PEER_CAP_ORF_PREFIX_RM_ADV) - || CHECK_FLAG(p->af_cap[afi][safi], - PEER_CAP_ORF_PREFIX_RM_OLD_RCV)) { - vty_out(vty, - " Outbound Route Filter (ORF) type (%d) Prefix-list:\n", - ORF_TYPE_PREFIX_OLD); - bgp_show_peer_afi_orf_cap( - vty, p, afi, safi, PEER_CAP_ORF_PREFIX_SM_ADV, - PEER_CAP_ORF_PREFIX_RM_ADV, - PEER_CAP_ORF_PREFIX_SM_OLD_RCV, - PEER_CAP_ORF_PREFIX_RM_OLD_RCV, use_json, NULL); - } snprintf(orf_pfx_name, sizeof(orf_pfx_name), "%s.%d.%d", p->host, afi, safi); @@ -13193,19 +13695,19 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, if (!use_json) { if (p->conf_if) /* Configured interface name. */ vty_out(vty, "BGP neighbor on %s: %pSU, ", p->conf_if, - &p->su); + &p->connection->su); else /* Configured IP address. */ vty_out(vty, "BGP neighbor is %s%s, ", dn_flag, p->host); } if (use_json) { - if (p->conf_if && BGP_PEER_SU_UNSPEC(p)) + if (p->conf_if && BGP_CONNECTION_SU_UNSPEC(p->connection)) json_object_string_add(json_neigh, "bgpNeighborAddr", "none"); - else if (p->conf_if && !BGP_PEER_SU_UNSPEC(p)) + else if (p->conf_if && !BGP_CONNECTION_SU_UNSPEC(p->connection)) json_object_string_addf(json_neigh, "bgpNeighborAddr", - "%pSU", &p->su); + "%pSU", &p->connection->su); asn_asn2json(json_neigh, "remoteAs", p->as, bgp->asnotation); @@ -13334,7 +13836,8 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, if (dn_flag[0]) { struct prefix prefix, *range = NULL; - if (sockunion2hostprefix(&(p->su), &prefix)) + if (sockunion2hostprefix(&p->connection->su, + &prefix)) range = peer_group_lookup_dynamic_neighbor_range( p->group, &prefix); @@ -13353,7 +13856,8 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, if (dn_flag[0]) { struct prefix prefix, *range = NULL; - if (sockunion2hostprefix(&(p->su), &prefix)) + if (sockunion2hostprefix(&p->connection->su, + &prefix)) range = peer_group_lookup_dynamic_neighbor_range( p->group, &prefix); @@ -13387,11 +13891,11 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, "nbrCommonAdmin"); /* Status. */ - json_object_string_add( - json_neigh, "bgpState", - lookup_msg(bgp_status_msg, p->status, NULL)); + json_object_string_add(json_neigh, "bgpState", + lookup_msg(bgp_status_msg, + p->connection->status, NULL)); - if (peer_established(p)) { + if (peer_established(p->connection)) { time_t uptime; uptime = monotime(NULL); @@ -13407,9 +13911,7 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, json_object_int_add(json_neigh, "bgpTimerUpEstablishedEpoch", epoch_tbuf); - } - - else if (p->status == Active) { + } else if (p->connection->status == Active) { if (CHECK_FLAG(p->flags, PEER_FLAG_PASSIVE)) json_object_string_add(json_neigh, "bgpStateIs", "passive"); @@ -13469,13 +13971,10 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, } /* Configured and Synced tcp-mss value for peer */ - if (CHECK_FLAG(p->flags, PEER_FLAG_TCP_MSS)) { - sync_tcp_mss = sockopt_tcp_mss_get(p->fd); - json_object_int_add(json_neigh, "bgpTcpMssConfigured", - p->tcp_mss); - json_object_int_add(json_neigh, "bgpTcpMssSynced", - sync_tcp_mss); - } + sync_tcp_mss = sockopt_tcp_mss_get(p->connection->fd); + json_object_int_add(json_neigh, "bgpTcpMssConfigured", + p->tcp_mss); + json_object_int_add(json_neigh, "bgpTcpMssSynced", sync_tcp_mss); /* Extended Optional Parameters Length for BGP OPEN Message */ if (BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(p)) @@ -13515,14 +14014,13 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, /* Status. */ vty_out(vty, " BGP state = %s", - lookup_msg(bgp_status_msg, p->status, NULL)); + lookup_msg(bgp_status_msg, p->connection->status, NULL)); - if (peer_established(p)) + if (peer_established(p->connection)) vty_out(vty, ", up for %8s", peer_uptime(p->uptime, timebuf, BGP_UPTIME_LEN, 0, NULL)); - - else if (p->status == Active) { + else if (p->connection->status == Active) { if (CHECK_FLAG(p->flags, PEER_FLAG_PASSIVE)) vty_out(vty, " (passive)"); else if (CHECK_FLAG(p->sflags, PEER_STATUS_NSF_WAIT)) @@ -13556,11 +14054,9 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, p->delayopen); /* Configured and synced tcp-mss value for peer */ - if (CHECK_FLAG(p->flags, PEER_FLAG_TCP_MSS)) { - sync_tcp_mss = sockopt_tcp_mss_get(p->fd); - vty_out(vty, " Configured tcp-mss is %d", p->tcp_mss); - vty_out(vty, ", synced tcp-mss is %d\n", sync_tcp_mss); - } + sync_tcp_mss = sockopt_tcp_mss_get(p->connection->fd); + vty_out(vty, " Configured tcp-mss is %d", p->tcp_mss); + vty_out(vty, ", synced tcp-mss is %d\n", sync_tcp_mss); /* Extended Optional Parameters Length for BGP OPEN Message */ if (BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(p)) @@ -13578,7 +14074,7 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, bgp->t_condition_check)); } /* Capability. */ - if (peer_established(p) && + if (peer_established(p->connection) && (p->cap || peer_afc_advertised(p) || peer_afc_received(p))) { if (use_json) { json_object *json_cap = NULL; @@ -13640,33 +14136,28 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, CHECK_FLAG( p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_RCV)) { - if (CHECK_FLAG( - p->af_cap[afi] - [safi], - PEER_CAP_ADDPATH_AF_TX_ADV) && - CHECK_FLAG( - p->af_cap[afi] - [safi], - PEER_CAP_ADDPATH_AF_TX_RCV)) - json_object_boolean_true_add( - json_sub, - "txAdvertisedAndReceived"); - else if ( - CHECK_FLAG( - p->af_cap[afi] - [safi], - PEER_CAP_ADDPATH_AF_TX_ADV)) - json_object_boolean_true_add( - json_sub, - "txAdvertised"); - else if ( - CHECK_FLAG( - p->af_cap[afi] - [safi], - PEER_CAP_ADDPATH_AF_TX_RCV)) - json_object_boolean_true_add( - json_sub, - "txReceived"); + json_object_boolean_add( + json_sub, + "txAdvertisedAndReceived", + CHECK_FLAG(p->af_cap[afi] + [safi], + PEER_CAP_ADDPATH_AF_TX_ADV) && + CHECK_FLAG( + p->af_cap[afi] + [safi], + PEER_CAP_ADDPATH_AF_TX_RCV)); + + json_object_boolean_add( + json_sub, "txAdvertised", + CHECK_FLAG(p->af_cap[afi] + [safi], + PEER_CAP_ADDPATH_AF_TX_ADV)); + + json_object_boolean_add( + json_sub, "txReceived", + CHECK_FLAG(p->af_cap[afi] + [safi], + PEER_CAP_ADDPATH_AF_TX_RCV)); } if (CHECK_FLAG( @@ -13675,33 +14166,28 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, CHECK_FLAG( p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_RCV)) { - if (CHECK_FLAG( - p->af_cap[afi] - [safi], - PEER_CAP_ADDPATH_AF_RX_ADV) && - CHECK_FLAG( - p->af_cap[afi] - [safi], - PEER_CAP_ADDPATH_AF_RX_RCV)) - json_object_boolean_true_add( - json_sub, - "rxAdvertisedAndReceived"); - else if ( - CHECK_FLAG( - p->af_cap[afi] - [safi], - PEER_CAP_ADDPATH_AF_RX_ADV)) - json_object_boolean_true_add( - json_sub, - "rxAdvertised"); - else if ( - CHECK_FLAG( - p->af_cap[afi] - [safi], - PEER_CAP_ADDPATH_AF_RX_RCV)) - json_object_boolean_true_add( - json_sub, - "rxReceived"); + json_object_boolean_add( + json_sub, + "rxAdvertisedAndReceived", + CHECK_FLAG(p->af_cap[afi] + [safi], + PEER_CAP_ADDPATH_AF_RX_ADV) && + CHECK_FLAG( + p->af_cap[afi] + [safi], + PEER_CAP_ADDPATH_AF_RX_RCV)); + + json_object_boolean_add( + json_sub, "rxAdvertised", + CHECK_FLAG(p->af_cap[afi] + [safi], + PEER_CAP_ADDPATH_AF_RX_ADV)); + + json_object_boolean_add( + json_sub, "rxReceived", + CHECK_FLAG(p->af_cap[afi] + [safi], + PEER_CAP_ADDPATH_AF_RX_RCV)); } if (CHECK_FLAG( @@ -13727,6 +14213,86 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, json_add); } + /* Paths-Limit */ + if (CHECK_FLAG(p->cap, PEER_CAP_PATHS_LIMIT_RCV) || + CHECK_FLAG(p->cap, PEER_CAP_PATHS_LIMIT_ADV)) { + json_object *json_add = NULL; + const char *print_store; + + json_add = json_object_new_object(); + + FOREACH_AFI_SAFI (afi, safi) { + json_object *json_sub = NULL; + + json_sub = json_object_new_object(); + print_store = get_afi_safi_str(afi, safi, + true); + + if (CHECK_FLAG(p->af_cap[afi][safi], + PEER_CAP_PATHS_LIMIT_AF_ADV) || + CHECK_FLAG(p->af_cap[afi][safi], + PEER_CAP_PATHS_LIMIT_AF_RCV)) { + if (CHECK_FLAG(p->af_cap[afi][safi], + PEER_CAP_PATHS_LIMIT_AF_ADV) && + CHECK_FLAG(p->af_cap[afi][safi], + PEER_CAP_PATHS_LIMIT_AF_RCV)) { + json_object_boolean_true_add( + json_sub, + "advertisedAndReceived"); + json_object_int_add( + json_sub, + "advertisedPathsLimit", + p->addpath_paths_limit + [afi][safi] + .send); + json_object_int_add( + json_sub, + "receivedPathsLimit", + p->addpath_paths_limit + [afi][safi] + .receive); + } else if (CHECK_FLAG(p->af_cap[afi] + [safi], + PEER_CAP_PATHS_LIMIT_AF_ADV)) { + json_object_boolean_true_add( + json_sub, + "advertised"); + json_object_int_add( + json_sub, + "advertisedPathsLimit", + p->addpath_paths_limit + [afi][safi] + .send); + } else if (CHECK_FLAG(p->af_cap[afi] + [safi], + PEER_CAP_PATHS_LIMIT_AF_RCV)) { + json_object_boolean_true_add( + json_sub, + "received"); + json_object_int_add( + json_sub, + "receivedPathsLimit", + p->addpath_paths_limit + [afi][safi] + .receive); + } + } + + if (CHECK_FLAG(p->af_cap[afi][safi], + PEER_CAP_PATHS_LIMIT_AF_ADV) || + CHECK_FLAG(p->af_cap[afi][safi], + PEER_CAP_PATHS_LIMIT_AF_RCV)) + json_object_object_add(json_add, + print_store, + json_sub); + else + json_object_free(json_sub); + } + + json_object_object_add(json_cap, "pathsLimit", + json_add); + } + /* Dynamic */ if (CHECK_FLAG(p->cap, PEER_CAP_DYNAMIC_RCV) || CHECK_FLAG(p->cap, PEER_CAP_DYNAMIC_ADV)) { @@ -13862,46 +14428,19 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, /* Route Refresh */ if (CHECK_FLAG(p->cap, PEER_CAP_REFRESH_ADV) || - CHECK_FLAG(p->cap, PEER_CAP_REFRESH_NEW_RCV) || - CHECK_FLAG(p->cap, PEER_CAP_REFRESH_OLD_RCV)) { + CHECK_FLAG(p->cap, PEER_CAP_REFRESH_RCV)) { if (CHECK_FLAG(p->cap, PEER_CAP_REFRESH_ADV) && - (CHECK_FLAG(p->cap, - PEER_CAP_REFRESH_NEW_RCV) || - CHECK_FLAG(p->cap, - PEER_CAP_REFRESH_OLD_RCV))) { - if (CHECK_FLAG( - p->cap, - PEER_CAP_REFRESH_OLD_RCV) && - CHECK_FLAG( - p->cap, - PEER_CAP_REFRESH_NEW_RCV)) - json_object_string_add( - json_cap, - "routeRefresh", - "advertisedAndReceivedOldNew"); - else { - if (CHECK_FLAG( - p->cap, - PEER_CAP_REFRESH_OLD_RCV)) - json_object_string_add( - json_cap, - "routeRefresh", - "advertisedAndReceivedOld"); - else - json_object_string_add( - json_cap, - "routeRefresh", - "advertisedAndReceivedNew"); - } - } else if (CHECK_FLAG(p->cap, - PEER_CAP_REFRESH_ADV)) + CHECK_FLAG(p->cap, PEER_CAP_REFRESH_RCV)) + json_object_string_add(json_cap, + "routeRefresh", + "advertisedAndReceived"); + else if (CHECK_FLAG(p->cap, + PEER_CAP_REFRESH_ADV)) json_object_string_add(json_cap, "routeRefresh", "advertised"); else if (CHECK_FLAG(p->cap, - PEER_CAP_REFRESH_NEW_RCV) || - CHECK_FLAG(p->cap, - PEER_CAP_REFRESH_OLD_RCV)) + PEER_CAP_REFRESH_RCV)) json_object_string_add(json_cap, "routeRefresh", "received"); @@ -14207,6 +14746,47 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, } } + /* Paths-Limit */ + if (CHECK_FLAG(p->cap, PEER_CAP_PATHS_LIMIT_RCV) || + CHECK_FLAG(p->cap, PEER_CAP_PATHS_LIMIT_ADV)) { + vty_out(vty, " Paths-Limit:\n"); + + FOREACH_AFI_SAFI (afi, safi) { + if (CHECK_FLAG(p->af_cap[afi][safi], + PEER_CAP_PATHS_LIMIT_AF_ADV) || + CHECK_FLAG(p->af_cap[afi][safi], + PEER_CAP_PATHS_LIMIT_AF_RCV)) { + vty_out(vty, " %s: ", + get_afi_safi_str(afi, + safi, + false)); + + if (CHECK_FLAG(p->af_cap[afi][safi], + PEER_CAP_PATHS_LIMIT_AF_ADV)) + vty_out(vty, + "advertised (%u)", + p->addpath_paths_limit + [afi][safi] + .send); + + if (CHECK_FLAG(p->af_cap[afi][safi], + PEER_CAP_PATHS_LIMIT_AF_RCV)) + vty_out(vty, + "%sreceived (%u)", + CHECK_FLAG(p->af_cap[afi] + [safi], + PEER_CAP_PATHS_LIMIT_AF_ADV) + ? " and " + : "", + p->addpath_paths_limit + [afi][safi] + .receive); + + vty_out(vty, "\n"); + } + } + } + /* Dynamic */ if (CHECK_FLAG(p->cap, PEER_CAP_DYNAMIC_RCV) || CHECK_FLAG(p->cap, PEER_CAP_DYNAMIC_ADV)) { @@ -14303,33 +14883,16 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, /* Route Refresh */ if (CHECK_FLAG(p->cap, PEER_CAP_REFRESH_ADV) || - CHECK_FLAG(p->cap, PEER_CAP_REFRESH_NEW_RCV) || - CHECK_FLAG(p->cap, PEER_CAP_REFRESH_OLD_RCV)) { + CHECK_FLAG(p->cap, PEER_CAP_REFRESH_RCV)) { vty_out(vty, " Route refresh:"); if (CHECK_FLAG(p->cap, PEER_CAP_REFRESH_ADV)) vty_out(vty, " advertised"); - if (CHECK_FLAG(p->cap, - PEER_CAP_REFRESH_NEW_RCV) || - CHECK_FLAG(p->cap, - PEER_CAP_REFRESH_OLD_RCV)) - vty_out(vty, " %sreceived(%s)", + if (CHECK_FLAG(p->cap, PEER_CAP_REFRESH_RCV)) + vty_out(vty, " %sreceived", CHECK_FLAG(p->cap, PEER_CAP_REFRESH_ADV) ? "and " - : "", - (CHECK_FLAG( - p->cap, - PEER_CAP_REFRESH_OLD_RCV) && - CHECK_FLAG( - p->cap, - PEER_CAP_REFRESH_NEW_RCV)) - ? "old & new" - : CHECK_FLAG( - p->cap, - PEER_CAP_REFRESH_OLD_RCV) - ? "old" - : "new"); - + : ""); vty_out(vty, "\n"); } @@ -14479,7 +15042,7 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, json_grace_send = json_object_new_object(); json_grace_recv = json_object_new_object(); - if ((peer_established(p)) && + if ((peer_established(p->connection)) && CHECK_FLAG(p->cap, PEER_CAP_RESTART_RCV)) { FOREACH_AFI_SAFI (afi, safi) { if (CHECK_FLAG(p->af_sflags[afi][safi], @@ -14508,26 +15071,27 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, json_grace_recv); - if (p->t_gr_restart) - json_object_int_add( - json_grace, "gracefulRestartTimerMsecs", - event_timer_remain_second(p->t_gr_restart) * - 1000); + if (p->connection->t_gr_restart) + json_object_int_add(json_grace, + "gracefulRestartTimerMsecs", + event_timer_remain_second( + p->connection->t_gr_restart) * + 1000); - if (p->t_gr_stale) - json_object_int_add( - json_grace, "gracefulStalepathTimerMsecs", - event_timer_remain_second(p->t_gr_stale) * - 1000); + if (p->connection->t_gr_stale) + json_object_int_add(json_grace, + "gracefulStalepathTimerMsecs", + event_timer_remain_second( + p->connection->t_gr_stale) * + 1000); /* more gr info in new format */ BGP_SHOW_PEER_GR_CAPABILITY(vty, p, json_grace); json_object_object_add(json_neigh, "gracefulRestartInfo", json_grace); } else { vty_out(vty, " Graceful restart information:\n"); - if ((peer_established(p)) && + if ((peer_established(p->connection)) && CHECK_FLAG(p->cap, PEER_CAP_RESTART_RCV)) { - vty_out(vty, " End-of-RIB send: "); FOREACH_AFI_SAFI (afi, safi) { if (CHECK_FLAG(p->af_sflags[afi][safi], @@ -14555,15 +15119,17 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, vty_out(vty, "\n"); } - if (p->t_gr_restart) + if (p->connection->t_gr_restart) vty_out(vty, " The remaining time of restart timer is %ld\n", - event_timer_remain_second(p->t_gr_restart)); + event_timer_remain_second( + p->connection->t_gr_restart)); - if (p->t_gr_stale) + if (p->connection->t_gr_stale) vty_out(vty, " The remaining time of stalepath timer is %ld\n", - event_timer_remain_second(p->t_gr_stale)); + event_timer_remain_second( + p->connection->t_gr_stale)); /* more gr info in new format */ BGP_SHOW_PEER_GR_CAPABILITY(vty, p, NULL); @@ -14575,9 +15141,9 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, /* Packet counts. */ atomic_size_t outq_count, inq_count; - outq_count = atomic_load_explicit(&p->obuf->count, + outq_count = atomic_load_explicit(&p->connection->obuf->count, memory_order_relaxed); - inq_count = atomic_load_explicit(&p->ibuf->count, + inq_count = atomic_load_explicit(&p->connection->ibuf->count, memory_order_relaxed); json_object_int_add(json_stat, "depthInq", @@ -14628,9 +15194,9 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, notify_out, notify_in, update_out, update_in, keepalive_out, keepalive_in, refresh_out, refresh_in, dynamic_cap_out, dynamic_cap_in; - outq_count = atomic_load_explicit(&p->obuf->count, + outq_count = atomic_load_explicit(&p->connection->obuf->count, memory_order_relaxed); - inq_count = atomic_load_explicit(&p->ibuf->count, + inq_count = atomic_load_explicit(&p->connection->ibuf->count, memory_order_relaxed); open_out = atomic_load_explicit(&p->open_out, memory_order_relaxed); @@ -14762,15 +15328,15 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, BGP_UPTIME_LEN, 0, NULL)); bgp_show_peer_reset(vty, p, NULL, false); - if (p->last_reset_cause_size) { - msg = p->last_reset_cause; + if (p->last_reset_cause) { + msg = p->last_reset_cause->data; vty_out(vty, " Message received that caused BGP to send a NOTIFICATION:\n "); - for (i = 1; i <= p->last_reset_cause_size; + for (i = 1; i <= p->last_reset_cause->size; i++) { vty_out(vty, "%02X", *msg++); - if (i != p->last_reset_cause_size) { + if (i != p->last_reset_cause->size) { if (i % 16 == 0) { vty_out(vty, "\n "); } else if (i % 4 == 0) { @@ -14791,21 +15357,22 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, vty_out(vty, " Peer had exceeded the max. no. of prefixes configured.\n"); - if (p->t_pmax_restart) { + if (p->connection->t_pmax_restart) { if (use_json) { json_object_boolean_true_add( json_neigh, "reducePrefixNumFrom"); json_object_int_add(json_neigh, "restartInTimerMsec", event_timer_remain_second( - p->t_pmax_restart) * + p->connection + ->t_pmax_restart) * 1000); } else vty_out(vty, " Reduce the no. of prefix from %s, will restart in %ld seconds\n", p->host, event_timer_remain_second( - p->t_pmax_restart)); + p->connection->t_pmax_restart)); } else { if (use_json) json_object_boolean_true_add( @@ -14942,7 +15509,7 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, if (use_json) { json_object_int_add(json_neigh, "connectRetryTimer", p->v_connect); - if (peer_established(p)) { + if (peer_established(p->connection)) { json_object_int_add(json_neigh, "estimatedRttInMsecs", p->rtt); if (CHECK_FLAG(p->flags, PEER_FLAG_RTT_SHUTDOWN)) { @@ -14954,32 +15521,37 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, p->rtt_keepalive_rcv); } } - if (p->t_start) - json_object_int_add( - json_neigh, "nextStartTimerDueInMsecs", - event_timer_remain_second(p->t_start) * 1000); - if (p->t_connect) - json_object_int_add( - json_neigh, "nextConnectTimerDueInMsecs", - event_timer_remain_second(p->t_connect) * 1000); - if (p->t_routeadv) { + if (p->connection->t_start) + json_object_int_add(json_neigh, + "nextStartTimerDueInMsecs", + event_timer_remain_second( + p->connection->t_start) * + 1000); + if (p->connection->t_connect) + json_object_int_add(json_neigh, + "nextConnectTimerDueInMsecs", + event_timer_remain_second( + p->connection->t_connect) * + 1000); + if (p->connection->t_routeadv) { json_object_int_add(json_neigh, "mraiInterval", p->v_routeadv); - json_object_int_add( - json_neigh, "mraiTimerExpireInMsecs", - event_timer_remain_second(p->t_routeadv) * - 1000); + json_object_int_add(json_neigh, "mraiTimerExpireInMsecs", + event_timer_remain_second( + p->connection->t_routeadv) * + 1000); } if (p->password) json_object_int_add(json_neigh, "authenticationEnabled", 1); - if (p->t_read) + if (p->connection->t_read) json_object_string_add(json_neigh, "readThread", "on"); else json_object_string_add(json_neigh, "readThread", "off"); - if (CHECK_FLAG(p->thread_flags, PEER_THREAD_WRITES_ON)) + if (CHECK_FLAG(p->connection->thread_flags, + PEER_THREAD_WRITES_ON)) json_object_string_add(json_neigh, "writeThread", "on"); else json_object_string_add(json_neigh, "writeThread", @@ -14987,7 +15559,7 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, } else { vty_out(vty, "BGP Connect Retry Timer in Seconds: %d\n", p->v_connect); - if (peer_established(p)) { + if (peer_established(p->connection)) { vty_out(vty, "Estimated round trip time: %d ms\n", p->rtt); if (CHECK_FLAG(p->flags, PEER_FLAG_RTT_SHUTDOWN)) @@ -14995,25 +15567,30 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, "Shutdown when RTT > %dms, count > %u\n", p->rtt_expected, p->rtt_keepalive_rcv); } - if (p->t_start) + if (p->connection->t_start) vty_out(vty, "Next start timer due in %ld seconds\n", - event_timer_remain_second(p->t_start)); - if (p->t_connect) + event_timer_remain_second( + p->connection->t_start)); + if (p->connection->t_connect) vty_out(vty, "Next connect timer due in %ld seconds\n", - event_timer_remain_second(p->t_connect)); - if (p->t_routeadv) + event_timer_remain_second( + p->connection->t_connect)); + if (p->connection->t_routeadv) vty_out(vty, "MRAI (interval %u) timer expires in %ld seconds\n", p->v_routeadv, - event_timer_remain_second(p->t_routeadv)); + event_timer_remain_second( + p->connection->t_routeadv)); if (p->password) vty_out(vty, "Peer Authentication Enabled\n"); vty_out(vty, "Read thread: %s Write thread: %s FD used: %d\n", - p->t_read ? "on" : "off", - CHECK_FLAG(p->thread_flags, PEER_THREAD_WRITES_ON) + p->connection->t_read ? "on" : "off", + CHECK_FLAG(p->connection->thread_flags, + PEER_THREAD_WRITES_ON) ? "on" - : "off", p->fd); + : "off", + p->connection->fd); } if (p->notify.code == BGP_NOTIFY_OPEN_ERR @@ -15076,7 +15653,7 @@ static int bgp_show_neighbor_graceful_restart(struct vty *vty, struct bgp *bgp, json_neighbor); } } else { - if (sockunion_same(&peer->su, su)) { + if (sockunion_same(&peer->connection->su, su)) { found = true; bgp_show_peer_gr_status(vty, peer, json_neighbor); @@ -15146,7 +15723,7 @@ static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp, json); } } else { - if (sockunion_same(&peer->su, su)) { + if (sockunion_same(&peer->connection->su, su)) { find = 1; bgp_show_peer(vty, peer, use_json, json); @@ -15168,7 +15745,9 @@ static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp, break; } } else { - if (sockunion_same(&peer->su, su)) { + if (sockunion_same(&peer->connection + ->su, + su)) { find = 1; bgp_show_peer(vty, peer, use_json, json); @@ -16277,8 +16856,10 @@ static int bgp_show_one_peer_group(struct vty *vty, struct peer_group *group, PEER_STATUS_PREFIX_OVERFLOW)) peer_status = "Idle (PfxCt)"; else - peer_status = lookup_msg(bgp_status_msg, - peer->status, NULL); + peer_status = + lookup_msg(bgp_status_msg, + peer->connection->status, + NULL); dynamic = peer_dynamic_neighbor(peer); @@ -16568,10 +17149,11 @@ ALIAS_HIDDEN( DEFUN (bgp_redistribute_ipv4_ospf, bgp_redistribute_ipv4_ospf_cmd, - "redistribute <ospf|table> (1-65535)", + "redistribute <ospf|table|table-direct> (1-65535)", "Redistribute information from another routing protocol\n" "Open Shortest Path First (OSPFv2)\n" "Non-main Kernel Routing Table\n" + "Non-main Kernel Routing Table - Direct\n" "Instance ID/Table ID\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); @@ -16584,26 +17166,46 @@ DEFUN (bgp_redistribute_ipv4_ospf, if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0) protocol = ZEBRA_ROUTE_OSPF; - else - protocol = ZEBRA_ROUTE_TABLE; + else { + if (bgp->vrf_id != VRF_DEFAULT) { + vty_out(vty, + "%% Only default BGP instance can use '%s'\n", + argv[idx_ospf_table]->arg); + return CMD_WARNING_CONFIG_FAILED; + } + if (strncmp(argv[idx_ospf_table]->arg, "table-direct", + strlen("table-direct")) == 0) { + protocol = ZEBRA_ROUTE_TABLE_DIRECT; + if (instance == RT_TABLE_MAIN || + instance == RT_TABLE_LOCAL) { + vty_out(vty, + "%% 'table-direct', can not use %u routing table\n", + instance); + return CMD_WARNING_CONFIG_FAILED; + } + } else + protocol = ZEBRA_ROUTE_TABLE; + } bgp_redist_add(bgp, AFI_IP, protocol, instance); return bgp_redistribute_set(bgp, AFI_IP, protocol, instance, false); } ALIAS_HIDDEN(bgp_redistribute_ipv4_ospf, bgp_redistribute_ipv4_ospf_hidden_cmd, - "redistribute <ospf|table> (1-65535)", + "redistribute <ospf|table|table-direct> (1-65535)", "Redistribute information from another routing protocol\n" "Open Shortest Path First (OSPFv2)\n" "Non-main Kernel Routing Table\n" + "Non-main Kernel Routing Table - Direct\n" "Instance ID/Table ID\n") DEFUN (bgp_redistribute_ipv4_ospf_rmap, bgp_redistribute_ipv4_ospf_rmap_cmd, - "redistribute <ospf|table> (1-65535) route-map RMAP_NAME", + "redistribute <ospf|table|table-direct> (1-65535) route-map RMAP_NAME", "Redistribute information from another routing protocol\n" "Open Shortest Path First (OSPFv2)\n" "Non-main Kernel Routing Table\n" + "Non-main Kernel Routing Table - Direct\n" "Instance ID/Table ID\n" "Route map reference\n" "Pointer to route-map entries\n") @@ -16619,12 +17221,31 @@ DEFUN (bgp_redistribute_ipv4_ospf_rmap, struct route_map *route_map = route_map_lookup_warn_noexist(vty, argv[idx_word]->arg); + instance = strtoul(argv[idx_number]->arg, NULL, 10); + if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0) protocol = ZEBRA_ROUTE_OSPF; - else - protocol = ZEBRA_ROUTE_TABLE; + else { + if (bgp->vrf_id != VRF_DEFAULT) { + vty_out(vty, + "%% Only default BGP instance can use '%s'\n", + argv[idx_ospf_table]->arg); + return CMD_WARNING_CONFIG_FAILED; + } + if (strncmp(argv[idx_ospf_table]->arg, "table-direct", + strlen("table-direct")) == 0) { + protocol = ZEBRA_ROUTE_TABLE_DIRECT; + if (instance == RT_TABLE_MAIN || + instance == RT_TABLE_LOCAL) { + vty_out(vty, + "%% 'table-direct', can not use %u routing table\n", + instance); + return CMD_WARNING_CONFIG_FAILED; + } + } else + protocol = ZEBRA_ROUTE_TABLE; + } - instance = strtoul(argv[idx_number]->arg, NULL, 10); red = bgp_redist_add(bgp, AFI_IP, protocol, instance); changed = bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map); @@ -16633,20 +17254,22 @@ DEFUN (bgp_redistribute_ipv4_ospf_rmap, ALIAS_HIDDEN(bgp_redistribute_ipv4_ospf_rmap, bgp_redistribute_ipv4_ospf_rmap_hidden_cmd, - "redistribute <ospf|table> (1-65535) route-map RMAP_NAME", + "redistribute <ospf|table|table-direct> (1-65535) route-map RMAP_NAME", "Redistribute information from another routing protocol\n" "Open Shortest Path First (OSPFv2)\n" "Non-main Kernel Routing Table\n" + "Non-main Kernel Routing Table - Direct\n" "Instance ID/Table ID\n" "Route map reference\n" "Pointer to route-map entries\n") DEFUN (bgp_redistribute_ipv4_ospf_metric, bgp_redistribute_ipv4_ospf_metric_cmd, - "redistribute <ospf|table> (1-65535) metric (0-4294967295)", + "redistribute <ospf|table|table-direct> (1-65535) metric (0-4294967295)", "Redistribute information from another routing protocol\n" "Open Shortest Path First (OSPFv2)\n" "Non-main Kernel Routing Table\n" + "Non-main Kernel Routing Table - Direct\n" "Instance ID/Table ID\n" "Metric for redistributed routes\n" "Default metric\n") @@ -16661,12 +17284,31 @@ DEFUN (bgp_redistribute_ipv4_ospf_metric, int protocol; bool changed; + instance = strtoul(argv[idx_number]->arg, NULL, 10); + if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0) protocol = ZEBRA_ROUTE_OSPF; - else - protocol = ZEBRA_ROUTE_TABLE; + else { + if (bgp->vrf_id != VRF_DEFAULT) { + vty_out(vty, + "%% Only default BGP instance can use '%s'\n", + argv[idx_ospf_table]->arg); + return CMD_WARNING_CONFIG_FAILED; + } + if (strncmp(argv[idx_ospf_table]->arg, "table-direct", + strlen("table-direct")) == 0) { + protocol = ZEBRA_ROUTE_TABLE_DIRECT; + if (instance == RT_TABLE_MAIN || + instance == RT_TABLE_LOCAL) { + vty_out(vty, + "%% 'table-direct', can not use %u routing table\n", + instance); + return CMD_WARNING_CONFIG_FAILED; + } + } else + protocol = ZEBRA_ROUTE_TABLE; + } - instance = strtoul(argv[idx_number]->arg, NULL, 10); metric = strtoul(argv[idx_number_2]->arg, NULL, 10); red = bgp_redist_add(bgp, AFI_IP, protocol, instance); @@ -16677,20 +17319,22 @@ DEFUN (bgp_redistribute_ipv4_ospf_metric, ALIAS_HIDDEN(bgp_redistribute_ipv4_ospf_metric, bgp_redistribute_ipv4_ospf_metric_hidden_cmd, - "redistribute <ospf|table> (1-65535) metric (0-4294967295)", + "redistribute <ospf|table|table-direct> (1-65535) metric (0-4294967295)", "Redistribute information from another routing protocol\n" "Open Shortest Path First (OSPFv2)\n" "Non-main Kernel Routing Table\n" + "Non-main Kernel Routing Table - Direct\n" "Instance ID/Table ID\n" "Metric for redistributed routes\n" "Default metric\n") DEFUN (bgp_redistribute_ipv4_ospf_rmap_metric, bgp_redistribute_ipv4_ospf_rmap_metric_cmd, - "redistribute <ospf|table> (1-65535) route-map RMAP_NAME metric (0-4294967295)", + "redistribute <ospf|table|table-direct> (1-65535) route-map RMAP_NAME metric (0-4294967295)", "Redistribute information from another routing protocol\n" "Open Shortest Path First (OSPFv2)\n" "Non-main Kernel Routing Table\n" + "Non-main Kernel Routing Table - Direct\n" "Instance ID/Table ID\n" "Route map reference\n" "Pointer to route-map entries\n" @@ -16710,12 +17354,31 @@ DEFUN (bgp_redistribute_ipv4_ospf_rmap_metric, struct route_map *route_map = route_map_lookup_warn_noexist(vty, argv[idx_word]->arg); + instance = strtoul(argv[idx_number]->arg, NULL, 10); + if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0) protocol = ZEBRA_ROUTE_OSPF; - else - protocol = ZEBRA_ROUTE_TABLE; + else { + if (bgp->vrf_id != VRF_DEFAULT) { + vty_out(vty, + "%% Only default BGP instance can use '%s'\n", + argv[idx_ospf_table]->arg); + return CMD_WARNING_CONFIG_FAILED; + } + if (strncmp(argv[idx_ospf_table]->arg, "table-direct", + strlen("table-direct")) == 0) { + protocol = ZEBRA_ROUTE_TABLE_DIRECT; + if (instance == RT_TABLE_MAIN || + instance == RT_TABLE_LOCAL) { + vty_out(vty, + "%% 'table-direct', can not use %u routing table\n", + instance); + return CMD_WARNING_CONFIG_FAILED; + } + } else + protocol = ZEBRA_ROUTE_TABLE; + } - instance = strtoul(argv[idx_number]->arg, NULL, 10); metric = strtoul(argv[idx_number_2]->arg, NULL, 10); red = bgp_redist_add(bgp, AFI_IP, protocol, instance); @@ -16729,10 +17392,11 @@ DEFUN (bgp_redistribute_ipv4_ospf_rmap_metric, ALIAS_HIDDEN( bgp_redistribute_ipv4_ospf_rmap_metric, bgp_redistribute_ipv4_ospf_rmap_metric_hidden_cmd, - "redistribute <ospf|table> (1-65535) route-map RMAP_NAME metric (0-4294967295)", + "redistribute <ospf|table|table-direct> (1-65535) route-map RMAP_NAME metric (0-4294967295)", "Redistribute information from another routing protocol\n" "Open Shortest Path First (OSPFv2)\n" "Non-main Kernel Routing Table\n" + "Non-main Kernel Routing Table - Direct\n" "Instance ID/Table ID\n" "Route map reference\n" "Pointer to route-map entries\n" @@ -16741,10 +17405,11 @@ ALIAS_HIDDEN( DEFUN (bgp_redistribute_ipv4_ospf_metric_rmap, bgp_redistribute_ipv4_ospf_metric_rmap_cmd, - "redistribute <ospf|table> (1-65535) metric (0-4294967295) route-map RMAP_NAME", + "redistribute <ospf|table|table-direct> (1-65535) metric (0-4294967295) route-map RMAP_NAME", "Redistribute information from another routing protocol\n" "Open Shortest Path First (OSPFv2)\n" "Non-main Kernel Routing Table\n" + "Non-main Kernel Routing Table - Direct\n" "Instance ID/Table ID\n" "Metric for redistributed routes\n" "Default metric\n" @@ -16764,10 +17429,29 @@ DEFUN (bgp_redistribute_ipv4_ospf_metric_rmap, struct route_map *route_map = route_map_lookup_warn_noexist(vty, argv[idx_word]->arg); + instance = strtoul(argv[idx_number]->arg, NULL, 10); + if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0) protocol = ZEBRA_ROUTE_OSPF; - else - protocol = ZEBRA_ROUTE_TABLE; + else { + if (bgp->vrf_id != VRF_DEFAULT) { + vty_out(vty, + "%% Only default BGP instance can use '%s'\n", + argv[idx_ospf_table]->arg); + return CMD_WARNING_CONFIG_FAILED; + } else if (strncmp(argv[idx_ospf_table]->arg, "table-direct", + strlen("table-direct")) == 0) { + protocol = ZEBRA_ROUTE_TABLE_DIRECT; + if (instance == RT_TABLE_MAIN || + instance == RT_TABLE_LOCAL) { + vty_out(vty, + "%% 'table-direct', can not use %u routing table\n", + instance); + return CMD_WARNING_CONFIG_FAILED; + } + } else + protocol = ZEBRA_ROUTE_TABLE; + } instance = strtoul(argv[idx_number]->arg, NULL, 10); metric = strtoul(argv[idx_number_2]->arg, NULL, 10); @@ -16783,10 +17467,11 @@ DEFUN (bgp_redistribute_ipv4_ospf_metric_rmap, ALIAS_HIDDEN( bgp_redistribute_ipv4_ospf_metric_rmap, bgp_redistribute_ipv4_ospf_metric_rmap_hidden_cmd, - "redistribute <ospf|table> (1-65535) metric (0-4294967295) route-map RMAP_NAME", + "redistribute <ospf|table|table-direct> (1-65535) metric (0-4294967295) route-map RMAP_NAME", "Redistribute information from another routing protocol\n" "Open Shortest Path First (OSPFv2)\n" "Non-main Kernel Routing Table\n" + "Non-main Kernel Routing Table - Direct\n" "Instance ID/Table ID\n" "Metric for redistributed routes\n" "Default metric\n" @@ -16795,11 +17480,12 @@ ALIAS_HIDDEN( DEFUN (no_bgp_redistribute_ipv4_ospf, no_bgp_redistribute_ipv4_ospf_cmd, - "no redistribute <ospf|table> (1-65535) [{metric (0-4294967295)|route-map RMAP_NAME}]", + "no redistribute <ospf|table|table-direct> (1-65535) [{metric (0-4294967295)|route-map RMAP_NAME}]", NO_STR "Redistribute information from another routing protocol\n" "Open Shortest Path First (OSPFv2)\n" "Non-main Kernel Routing Table\n" + "Non-main Kernel Routing Table - Direct\n" "Instance ID/Table ID\n" "Metric for redistributed routes\n" "Default metric\n" @@ -16812,22 +17498,43 @@ DEFUN (no_bgp_redistribute_ipv4_ospf, unsigned short instance; int protocol; + instance = strtoul(argv[idx_number]->arg, NULL, 10); + if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0) protocol = ZEBRA_ROUTE_OSPF; - else - protocol = ZEBRA_ROUTE_TABLE; + else { + if (bgp->vrf_id != VRF_DEFAULT) { + vty_out(vty, + "%% Only default BGP instance can use '%s'\n", + argv[idx_ospf_table]->arg); + return CMD_WARNING_CONFIG_FAILED; + } + if (strncmp(argv[idx_ospf_table]->arg, "table-direct", + strlen("table-direct")) == 0) { + protocol = ZEBRA_ROUTE_TABLE_DIRECT; + if (instance == RT_TABLE_MAIN || + instance == RT_TABLE_LOCAL) { + vty_out(vty, + "%% 'table-direct', can not use %u routing table\n", + instance); + return CMD_WARNING_CONFIG_FAILED; + } + } else + protocol = ZEBRA_ROUTE_TABLE; + } - instance = strtoul(argv[idx_number]->arg, NULL, 10); - return bgp_redistribute_unset(bgp, AFI_IP, protocol, instance); + bgp_redistribute_unset(bgp, AFI_IP, protocol, instance); + return CMD_SUCCESS; } ALIAS_HIDDEN( no_bgp_redistribute_ipv4_ospf, no_bgp_redistribute_ipv4_ospf_hidden_cmd, - "no redistribute <ospf|table> (1-65535) [{metric (0-4294967295)|route-map RMAP_NAME}]", + "no redistribute <ospf|table|table-direct> (1-65535) [{metric (0-4294967295)|route-map RMAP_NAME}]", NO_STR "Redistribute information from another routing protocol\n" "Open Shortest Path First (OSPFv2)\n" "Non-main Kernel Routing Table\n" + "Non-main Kernel Routing Table - Direct\n" "Instance ID/Table ID\n" "Metric for redistributed routes\n" "Default metric\n" @@ -16854,7 +17561,8 @@ DEFUN (no_bgp_redistribute_ipv4, vty_out(vty, "%% Invalid route type\n"); return CMD_WARNING_CONFIG_FAILED; } - return bgp_redistribute_unset(bgp, AFI_IP, type, 0); + bgp_redistribute_unset(bgp, AFI_IP, type, 0); + return CMD_SUCCESS; } ALIAS_HIDDEN( @@ -17038,7 +17746,8 @@ DEFUN (no_bgp_redistribute_ipv6, return CMD_WARNING_CONFIG_FAILED; } - return bgp_redistribute_unset(bgp, AFI_IP6, type, 0); + bgp_redistribute_unset(bgp, AFI_IP6, type, 0); + return CMD_SUCCESS; } /* Neighbor update tcp-mss. */ @@ -17170,8 +17879,8 @@ bool peergroup_flag_check(struct peer *peer, uint64_t flag) return !!CHECK_FLAG(peer->flags_override, flag); } -static bool peergroup_af_flag_check(struct peer *peer, afi_t afi, safi_t safi, - uint64_t flag) +bool peergroup_af_flag_check(struct peer *peer, afi_t afi, safi_t safi, + uint64_t flag) { if (!peer_group_active(peer)) { if (CHECK_FLAG(peer->af_flags_invert[afi][safi], flag)) @@ -17275,6 +17984,12 @@ static void bgp_vpn_policy_config_write_afi(struct vty *vty, struct bgp *bgp, } } + if (CHECK_FLAG(bgp->vpn_policy[afi].flags, + BGP_VPN_POLICY_TOVPN_LABEL_PER_NEXTHOP)) + vty_out(vty, + "%*slabel vpn export allocation-mode per-nexthop\n", + indent, ""); + tovpn_sid_index = bgp->vpn_policy[afi].tovpn_sid_index; if (CHECK_FLAG(bgp->vpn_policy[afi].flags, BGP_VPN_POLICY_TOVPN_SID_AUTO)) { @@ -17587,8 +18302,12 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp, && !(peer->gtsm_hops != BGP_GTSM_HOPS_DISABLED && peer->ttl == MAXTTL)) { if (!peer_group_active(peer) || g_peer->ttl != peer->ttl) { - vty_out(vty, " neighbor %s ebgp-multihop %d\n", addr, - peer->ttl); + if (peer->ttl != MAXTTL) + vty_out(vty, " neighbor %s ebgp-multihop %d\n", + addr, peer->ttl); + else + vty_out(vty, " neighbor %s ebgp-multihop\n", + addr); } } @@ -17609,6 +18328,9 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp, ? " strict-mode" : ""); + if (peer->sub_sort == BGP_PEER_EBGP_OAD) + vty_out(vty, " neighbor %s oad\n", addr); + /* ttl-security hops */ if (peer->gtsm_hops != BGP_GTSM_HOPS_DISABLED) { if (!peer_group_active(peer) @@ -17633,8 +18355,13 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp, addr); /* enforce-first-as */ - if (peergroup_flag_check(peer, PEER_FLAG_ENFORCE_FIRST_AS)) - vty_out(vty, " neighbor %s enforce-first-as\n", addr); + if (CHECK_FLAG(bgp->flags, BGP_FLAG_ENFORCE_FIRST_AS)) { + if (!peergroup_flag_check(peer, PEER_FLAG_ENFORCE_FIRST_AS)) + vty_out(vty, " no neighbor %s enforce-first-as\n", addr); + } else { + if (peergroup_flag_check(peer, PEER_FLAG_ENFORCE_FIRST_AS)) + vty_out(vty, " neighbor %s enforce-first-as\n", addr); + } /* update-source */ if (peergroup_flag_check(peer, PEER_FLAG_UPDATE_SOURCE)) { @@ -17681,9 +18408,15 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp, vty_out(vty, " neighbor %s timers delayopen %u\n", addr, peer->bgp->default_delayopen); - /* capability dynamic */ - if (peergroup_flag_check(peer, PEER_FLAG_DYNAMIC_CAPABILITY)) - vty_out(vty, " neighbor %s capability dynamic\n", addr); + /* capability software-version */ + if (CHECK_FLAG(bgp->flags, BGP_FLAG_DYNAMIC_CAPABILITY)) { + if (!peergroup_flag_check(peer, PEER_FLAG_DYNAMIC_CAPABILITY)) + vty_out(vty, " no neighbor %s capability dynamic\n", + addr); + } else { + if (peergroup_flag_check(peer, PEER_FLAG_DYNAMIC_CAPABILITY)) + vty_out(vty, " neighbor %s capability dynamic\n", addr); + } /* capability extended-nexthop */ if (peergroup_flag_check(peer, PEER_FLAG_CAPABILITY_ENHE)) { @@ -17699,14 +18432,30 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp, } /* capability software-version */ - if (peergroup_flag_check(peer, PEER_FLAG_CAPABILITY_SOFT_VERSION)) - vty_out(vty, " neighbor %s capability software-version\n", - addr); + if (CHECK_FLAG(bgp->flags, BGP_FLAG_SOFT_VERSION_CAPABILITY)) { + if (!peergroup_flag_check(peer, + PEER_FLAG_CAPABILITY_SOFT_VERSION)) + vty_out(vty, + " no neighbor %s capability software-version\n", + addr); + } else { + if (peergroup_flag_check(peer, + PEER_FLAG_CAPABILITY_SOFT_VERSION)) + vty_out(vty, + " neighbor %s capability software-version\n", + addr); + } /* dont-capability-negotiation */ if (peergroup_flag_check(peer, PEER_FLAG_DONT_CAPABILITY)) vty_out(vty, " neighbor %s dont-capability-negotiate\n", addr); + /* capability fqdn */ + if (peergroup_flag_check(peer, PEER_FLAG_CAPABILITY_FQDN)) + vty_out(vty, + " no neighbor %s capability fqdn\n", + addr); + /* override-capability */ if (peergroup_flag_check(peer, PEER_FLAG_OVERRIDE_CAPABILITY)) vty_out(vty, " neighbor %s override-capability\n", addr); @@ -17716,7 +18465,7 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp, vty_out(vty, " neighbor %s strict-capability-match\n", addr); /* Sender side AS path loop detection. */ - if (peer->as_path_loop_detection) + if (peergroup_flag_check(peer, PEER_FLAG_AS_LOOP_DETECTION)) vty_out(vty, " neighbor %s sender-as-path-loop-detection\n", addr); @@ -17822,6 +18571,13 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp, " neighbor %s addpath-tx-bestpath-per-AS\n", addr); break; + case BGP_ADDPATH_BEST_SELECTED: + if (peer->addpath_best_selected[afi][safi]) + vty_out(vty, + " neighbor %s addpath-tx-best-selected %u\n", + addr, + peer->addpath_best_selected[afi][safi]); + break; case BGP_ADDPATH_MAX: case BGP_ADDPATH_NONE: break; @@ -17831,6 +18587,11 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp, if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_DISABLE_ADDPATH_RX)) vty_out(vty, " neighbor %s disable-addpath-rx\n", addr); + if (CHECK_FLAG(peer->af_flags[afi][safi], + PEER_FLAG_ADDPATH_RX_PATHS_LIMIT)) + vty_out(vty, " neighbor %s addpath-rx-paths-limit %u\n", addr, + peer->addpath_paths_limit[afi][safi].send); + /* ORF capability. */ if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_ORF_PREFIX_SM) || peergroup_af_flag_check(peer, afi, safi, @@ -17916,6 +18677,12 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp, if (flag_slcomm) vty_out(vty, " no neighbor %s send-community large\n", addr); + + if (peergroup_af_flag_check(peer, afi, safi, + PEER_FLAG_SEND_EXT_COMMUNITY_RPKI)) + vty_out(vty, + " no neighbor %s send-community extended rpki\n", + addr); } /* Default information */ @@ -18160,6 +18927,8 @@ int bgp_config_write(struct vty *vty) safi_t safi; uint32_t tovpn_sid_index = 0; + hook_call(bgp_snmp_traps_config_write, vty); + if (bm->rmap_update_timer != RMAP_DEFAULT_UPDATE_TIMER) vty_out(vty, "bgp route-map delay-timer %u\n", bm->rmap_update_timer); @@ -18250,8 +19019,26 @@ int bgp_config_write(struct vty *vty) ? "" : "no "); - if (!!CHECK_FLAG(bgp->flags, BGP_FLAG_LU_EXPLICIT_NULL)) + /* bgp enforce-first-as */ + if (!!CHECK_FLAG(bgp->flags, BGP_FLAG_ENFORCE_FIRST_AS) != + SAVE_BGP_ENFORCE_FIRST_AS) + vty_out(vty, " %sbgp enforce-first-as\n", + CHECK_FLAG(bgp->flags, + BGP_FLAG_ENFORCE_FIRST_AS) + ? "" + : "no "); + + if (!!CHECK_FLAG(bgp->flags, BGP_FLAG_LU_IPV4_EXPLICIT_NULL) && + !!CHECK_FLAG(bgp->flags, BGP_FLAG_LU_IPV6_EXPLICIT_NULL)) vty_out(vty, " bgp labeled-unicast explicit-null\n"); + else if (!!CHECK_FLAG(bgp->flags, + BGP_FLAG_LU_IPV4_EXPLICIT_NULL)) + vty_out(vty, + " bgp labeled-unicast ipv4-explicit-null\n"); + else if (!!CHECK_FLAG(bgp->flags, + BGP_FLAG_LU_IPV6_EXPLICIT_NULL)) + vty_out(vty, + " bgp labeled-unicast ipv6-explicit-null\n"); /* draft-ietf-idr-deprecate-as-set-confed-set */ if (bgp->reject_as_sets) @@ -18311,6 +19098,24 @@ int bgp_config_write(struct vty *vty) ? "" : "no "); + if (!!CHECK_FLAG(bgp->flags, BGP_FLAG_SOFT_VERSION_CAPABILITY) != + SAVE_BGP_SOFT_VERSION_CAPABILITY) + vty_out(vty, + " %sbgp default software-version-capability\n", + CHECK_FLAG(bgp->flags, + BGP_FLAG_SOFT_VERSION_CAPABILITY) + ? "" + : "no "); + + if (!!CHECK_FLAG(bgp->flags, BGP_FLAG_DYNAMIC_CAPABILITY) != + SAVE_BGP_DYNAMIC_CAPABILITY) + vty_out(vty, + " %sbgp default dynamic-capability\n", + CHECK_FLAG(bgp->flags, + BGP_FLAG_DYNAMIC_CAPABILITY) + ? "" + : "no "); + /* BGP default subgroup-pkt-queue-max. */ if (bgp->default_subgroup_pkt_queue_max != BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX) @@ -18518,6 +19323,12 @@ int bgp_config_write(struct vty *vty) " bgp conditional-advertisement timer %u\n", bgp->condition_check_period); + /* default-originate timer configuration */ + if (bgp->rmap_def_originate_eval_timer != + RMAP_DEFAULT_ORIGINATE_EVAL_TIMER) + vty_out(vty, " bgp default-originate timer %u\n", + bgp->rmap_def_originate_eval_timer); + /* peer-group */ for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) { bgp_config_write_peer_global(vty, bgp, group->conf); @@ -18804,6 +19615,9 @@ bool bgp_config_inprocess(void) return event_is_scheduled(t_bgp_cfg); } +/* Max wait time for config to load before post-config processing */ +#define BGP_PRE_CONFIG_MAX_WAIT_SECONDS 600 + static void bgp_config_finish(struct event *t) { struct listnode *node; @@ -18813,11 +19627,17 @@ static void bgp_config_finish(struct event *t) hook_call(bgp_config_end, bgp); } +static void bgp_config_end_timeout(struct event *t) +{ + zlog_err("BGP configuration end timer expired after %d seconds.", + BGP_PRE_CONFIG_MAX_WAIT_SECONDS); + bgp_config_finish(t); +} + static void bgp_config_start(void) { -#define BGP_PRE_CONFIG_MAX_WAIT_SECONDS 600 EVENT_OFF(t_bgp_cfg); - event_add_timer(bm->master, bgp_config_finish, NULL, + event_add_timer(bm->master, bgp_config_end_timeout, NULL, BGP_PRE_CONFIG_MAX_WAIT_SECONDS, &t_bgp_cfg); } @@ -18867,6 +19687,12 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf) vty_out(vty, " mpls bgp forwarding\n"); write++; } + if (CHECK_FLAG(iifp->flags, + BGP_INTERFACE_MPLS_L3VPN_SWITCHING)) { + vty_out(vty, + " mpls bgp l3vpn-multi-domain-switching\n"); + write++; + } if_vty_config_end(vty); } @@ -18917,6 +19743,35 @@ DEFPY(mpls_bgp_forwarding, mpls_bgp_forwarding_cmd, return CMD_SUCCESS; } +DEFPY(mpls_bgp_l3vpn_multi_domain_switching, + mpls_bgp_l3vpn_multi_domain_switching_cmd, + "[no$no] mpls bgp l3vpn-multi-domain-switching", + NO_STR MPLS_STR BGP_STR + "Bind a local MPLS label to incoming L3VPN updates\n") +{ + bool check; + struct bgp_interface *iifp; + + VTY_DECLVAR_CONTEXT(interface, ifp); + iifp = ifp->info; + if (!iifp) { + vty_out(vty, "Interface %s not available\n", ifp->name); + return CMD_WARNING_CONFIG_FAILED; + } + check = CHECK_FLAG(iifp->flags, BGP_INTERFACE_MPLS_L3VPN_SWITCHING); + if (check == !no) + return CMD_SUCCESS; + if (no) + UNSET_FLAG(iifp->flags, BGP_INTERFACE_MPLS_L3VPN_SWITCHING); + else + SET_FLAG(iifp->flags, BGP_INTERFACE_MPLS_L3VPN_SWITCHING); + /* trigger a nht update on eBGP sessions */ + if (if_is_operative(ifp)) + bgp_nht_ifp_up(ifp); + + return CMD_SUCCESS; +} + DEFPY (bgp_inq_limit, bgp_inq_limit_cmd, "bgp input-queue-limit (1-4294967295)$limit", @@ -18976,6 +19831,8 @@ static void bgp_vty_if_init(void) /* "mpls bgp forwarding" commands. */ install_element(INTERFACE_NODE, &mpls_bgp_forwarding_cmd); + install_element(INTERFACE_NODE, + &mpls_bgp_l3vpn_multi_domain_switching_cmd); } void bgp_vty_init(void) @@ -19099,6 +19956,9 @@ void bgp_vty_init(void) install_element(BGP_NODE, &neighbor_role_strict_cmd); install_element(BGP_NODE, &no_neighbor_role_cmd); + /* "neighbor oad" commands. */ + install_element(BGP_NODE, &neighbor_oad_cmd); + /* "neighbor aigp" commands. */ install_element(BGP_NODE, &neighbor_aigp_cmd); @@ -19172,6 +20032,9 @@ void bgp_vty_init(void) install_element(BGP_NODE, &bgp_ebgp_requires_policy_cmd); install_element(BGP_NODE, &no_bgp_ebgp_requires_policy_cmd); + /* bgp enforce-first-as */ + install_element(BGP_NODE, &bgp_enforce_first_as_cmd); + /* bgp labeled-unicast explicit-null */ install_element(BGP_NODE, &bgp_lu_uses_explicit_null_cmd); @@ -19298,6 +20161,12 @@ void bgp_vty_init(void) install_element(BGP_NODE, &bgp_default_show_nexthop_hostname_cmd); install_element(BGP_NODE, &no_bgp_default_show_nexthop_hostname_cmd); + /* bgp default software-version-capability */ + install_element(BGP_NODE, &bgp_default_software_version_capability_cmd); + + /* bgp default dynamic-capability */ + install_element(BGP_NODE, &bgp_default_dynamic_capability_cmd); + /* "bgp default subgroup-pkt-queue-max" commands. */ install_element(BGP_NODE, &bgp_default_subgroup_pkt_queue_max_cmd); install_element(BGP_NODE, &no_bgp_default_subgroup_pkt_queue_max_cmd); @@ -19711,6 +20580,15 @@ void bgp_vty_init(void) install_element(BGP_VPNV6_NODE, &neighbor_send_community_type_cmd); install_element(BGP_VPNV6_NODE, &no_neighbor_send_community_cmd); install_element(BGP_VPNV6_NODE, &no_neighbor_send_community_type_cmd); + install_element(BGP_NODE, &neighbor_ecommunity_rpki_cmd); + install_element(BGP_IPV4_NODE, &neighbor_ecommunity_rpki_cmd); + install_element(BGP_IPV4M_NODE, &neighbor_ecommunity_rpki_cmd); + install_element(BGP_IPV4L_NODE, &neighbor_ecommunity_rpki_cmd); + install_element(BGP_IPV6_NODE, &neighbor_ecommunity_rpki_cmd); + install_element(BGP_IPV6M_NODE, &neighbor_ecommunity_rpki_cmd); + install_element(BGP_IPV6L_NODE, &neighbor_ecommunity_rpki_cmd); + install_element(BGP_VPNV4_NODE, &neighbor_ecommunity_rpki_cmd); + install_element(BGP_VPNV6_NODE, &neighbor_ecommunity_rpki_cmd); /* "neighbor route-reflector" commands.*/ install_element(BGP_NODE, &neighbor_route_reflector_client_hidden_cmd); @@ -19815,6 +20693,40 @@ void bgp_vty_init(void) install_element(BGP_VPNV6_NODE, &neighbor_addpath_tx_all_paths_cmd); install_element(BGP_VPNV6_NODE, &no_neighbor_addpath_tx_all_paths_cmd); + /* "neighbor addpath-tx-best-selected" commands.*/ + install_element(BGP_IPV4_NODE, + &neighbor_addpath_tx_best_selected_paths_cmd); + install_element(BGP_IPV4_NODE, + &no_neighbor_addpath_tx_best_selected_paths_cmd); + install_element(BGP_IPV4M_NODE, + &neighbor_addpath_tx_best_selected_paths_cmd); + install_element(BGP_IPV4M_NODE, + &no_neighbor_addpath_tx_best_selected_paths_cmd); + install_element(BGP_IPV4L_NODE, + &neighbor_addpath_tx_best_selected_paths_cmd); + install_element(BGP_IPV4L_NODE, + &no_neighbor_addpath_tx_best_selected_paths_cmd); + install_element(BGP_IPV6_NODE, + &neighbor_addpath_tx_best_selected_paths_cmd); + install_element(BGP_IPV6_NODE, + &no_neighbor_addpath_tx_best_selected_paths_cmd); + install_element(BGP_IPV6M_NODE, + &neighbor_addpath_tx_best_selected_paths_cmd); + install_element(BGP_IPV6M_NODE, + &no_neighbor_addpath_tx_best_selected_paths_cmd); + install_element(BGP_IPV6L_NODE, + &neighbor_addpath_tx_best_selected_paths_cmd); + install_element(BGP_IPV6L_NODE, + &no_neighbor_addpath_tx_best_selected_paths_cmd); + install_element(BGP_VPNV4_NODE, + &neighbor_addpath_tx_best_selected_paths_cmd); + install_element(BGP_VPNV4_NODE, + &no_neighbor_addpath_tx_best_selected_paths_cmd); + install_element(BGP_VPNV6_NODE, + &neighbor_addpath_tx_best_selected_paths_cmd); + install_element(BGP_VPNV6_NODE, + &no_neighbor_addpath_tx_best_selected_paths_cmd); + /* "neighbor addpath-tx-bestpath-per-AS" commands.*/ install_element(BGP_NODE, &neighbor_addpath_tx_bestpath_per_as_hidden_cmd); @@ -19853,6 +20765,26 @@ void bgp_vty_init(void) install_element(BGP_VPNV6_NODE, &no_neighbor_addpath_tx_bestpath_per_as_cmd); + /* "neighbor addpath-rx-paths-limit" commands.*/ + install_element(BGP_NODE, &neighbor_addpath_paths_limit_cmd); + install_element(BGP_NODE, &no_neighbor_addpath_paths_limit_cmd); + install_element(BGP_IPV4_NODE, &neighbor_addpath_paths_limit_cmd); + install_element(BGP_IPV4_NODE, &no_neighbor_addpath_paths_limit_cmd); + install_element(BGP_IPV4M_NODE, &neighbor_addpath_paths_limit_cmd); + install_element(BGP_IPV4M_NODE, &no_neighbor_addpath_paths_limit_cmd); + install_element(BGP_IPV4L_NODE, &neighbor_addpath_paths_limit_cmd); + install_element(BGP_IPV4L_NODE, &no_neighbor_addpath_paths_limit_cmd); + install_element(BGP_IPV6_NODE, &neighbor_addpath_paths_limit_cmd); + install_element(BGP_IPV6_NODE, &no_neighbor_addpath_paths_limit_cmd); + install_element(BGP_IPV6M_NODE, &neighbor_addpath_paths_limit_cmd); + install_element(BGP_IPV6M_NODE, &no_neighbor_addpath_paths_limit_cmd); + install_element(BGP_IPV6L_NODE, &neighbor_addpath_paths_limit_cmd); + install_element(BGP_IPV6L_NODE, &no_neighbor_addpath_paths_limit_cmd); + install_element(BGP_VPNV4_NODE, &neighbor_addpath_paths_limit_cmd); + install_element(BGP_VPNV4_NODE, &no_neighbor_addpath_paths_limit_cmd); + install_element(BGP_VPNV6_NODE, &neighbor_addpath_paths_limit_cmd); + install_element(BGP_VPNV6_NODE, &no_neighbor_addpath_paths_limit_cmd); + /* "neighbor sender-as-path-loop-detection" commands. */ install_element(BGP_NODE, &neighbor_aspath_loop_detection_cmd); install_element(BGP_NODE, &no_neighbor_aspath_loop_detection_cmd); @@ -19912,6 +20844,9 @@ void bgp_vty_init(void) install_element(BGP_NODE, &neighbor_dont_capability_negotiate_cmd); install_element(BGP_NODE, &no_neighbor_dont_capability_negotiate_cmd); + /* "neighbor capability fqdn" command. */ + install_element(BGP_NODE, &neighbor_capability_fqdn_cmd); + /* "neighbor ebgp-multihop" commands. */ install_element(BGP_NODE, &neighbor_ebgp_multihop_cmd); install_element(BGP_NODE, &neighbor_ebgp_multihop_ttl_cmd); @@ -20146,6 +21081,9 @@ void bgp_vty_init(void) install_element(BGP_VPNV4_NODE, &neighbor_advertise_map_cmd); install_element(BGP_VPNV6_NODE, &neighbor_advertise_map_cmd); + /* bgp default-originate timer */ + install_element(BGP_NODE, &bgp_def_originate_eval_cmd); + /* neighbor maximum-prefix-out commands. */ install_element(BGP_NODE, &neighbor_maximum_prefix_out_cmd); install_element(BGP_NODE, &no_neighbor_maximum_prefix_out_cmd); @@ -20439,6 +21377,10 @@ void bgp_vty_init(void) install_element(BGP_IPV6_NODE, &af_rd_vpn_export_cmd); install_element(BGP_IPV4_NODE, &af_label_vpn_export_cmd); install_element(BGP_IPV6_NODE, &af_label_vpn_export_cmd); + install_element(BGP_IPV4_NODE, + &af_label_vpn_export_allocation_mode_cmd); + install_element(BGP_IPV6_NODE, + &af_label_vpn_export_allocation_mode_cmd); install_element(BGP_IPV4_NODE, &af_nexthop_vpn_export_cmd); install_element(BGP_IPV6_NODE, &af_nexthop_vpn_export_cmd); install_element(BGP_IPV4_NODE, &af_rt_vpn_imexport_cmd); @@ -20557,6 +21499,7 @@ DEFUN (community_list_standard, argv_find(argv, argc, "AA:NN", &idx); char *str = argv_concat(argv, argc, idx); + assert(str); int ret = community_list_set(bgp_clist, cl_name_or_number, str, seq, direct, style); @@ -20669,6 +21612,7 @@ DEFUN (community_list_expanded_all, argv_find(argv, argc, "AA:NN", &idx); char *str = argv_concat(argv, argc, idx); + assert(str); int ret = community_list_set(bgp_clist, cl_name_or_number, str, seq, direct, style); @@ -20753,16 +21697,13 @@ static const char *community_list_config_str(struct community_entry *entry) { const char *str; - if (entry->any) - str = ""; - else { - if (entry->style == COMMUNITY_LIST_STANDARD) - str = community_str(entry->u.com, false, false); - else if (entry->style == LARGE_COMMUNITY_LIST_STANDARD) - str = lcommunity_str(entry->u.lcom, false, false); - else - str = entry->config; - } + if (entry->style == COMMUNITY_LIST_STANDARD) + str = community_str(entry->u.com, false, false); + else if (entry->style == LARGE_COMMUNITY_LIST_STANDARD) + str = lcommunity_str(entry->u.lcom, false, false); + else + str = entry->config; + return str; } @@ -20785,13 +21726,8 @@ static void community_list_show(struct vty *vty, struct community_list *list) : "expanded", list->name); } - if (entry->any) - vty_out(vty, " %s\n", - community_direct_str(entry->direct)); - else - vty_out(vty, " %s %s\n", - community_direct_str(entry->direct), - community_list_config_str(entry)); + vty_out(vty, " %s %s\n", community_direct_str(entry->direct), + community_list_config_str(entry)); } } @@ -21150,13 +22086,8 @@ static void lcommunity_list_show(struct vty *vty, struct community_list *list) : "expanded", list->name); } - if (entry->any) - vty_out(vty, " %s\n", - community_direct_str(entry->direct)); - else - vty_out(vty, " %s %s\n", - community_direct_str(entry->direct), - community_list_config_str(entry)); + vty_out(vty, " %s %s\n", community_direct_str(entry->direct), + community_list_config_str(entry)); } } @@ -21452,13 +22383,8 @@ static void extcommunity_list_show(struct vty *vty, struct community_list *list) : "expanded", list->name); } - if (entry->any) - vty_out(vty, " %s\n", - community_direct_str(entry->direct)); - else - vty_out(vty, " %s %s\n", - community_direct_str(entry->direct), - community_list_config_str(entry)); + vty_out(vty, " %s %s\n", community_direct_str(entry->direct), + community_list_config_str(entry)); } } |
