diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index ecb45ff6973f..e86d1dc65612 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -18732,7 +18732,7 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp, } /* TCP max segment size */ - if (CHECK_FLAG(peer->flags, PEER_FLAG_TCP_MSS)) + if (peergroup_flag_check(peer, PEER_FLAG_TCP_MSS)) vty_out(vty, " neighbor %s tcp-mss %d\n", addr, peer->tcp_mss); /* passive */ diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 22f1cf841426..d175a1f60fed 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -3031,6 +3031,10 @@ static void peer_group2peer_config_copy(struct peer_group *group, bgp_peer_configure_bfd(peer, false); bgp_peer_config_apply(peer, group); } + /* peer tcp-mss */ + if (!CHECK_FLAG(peer->flags_override, PEER_FLAG_TCP_MSS)) { + PEER_ATTR_INHERIT(peer, group, tcp_mss); + } } /* Peer group's remote AS configuration. */ @@ -4763,40 +4767,42 @@ struct peer_flag_action { }; static const struct peer_flag_action peer_flag_action_list[] = { - {PEER_FLAG_PASSIVE, 0, peer_change_reset}, - {PEER_FLAG_SHUTDOWN, 0, peer_change_reset}, - {PEER_FLAG_RTT_SHUTDOWN, 0, peer_change_none}, - {PEER_FLAG_DONT_CAPABILITY, 0, peer_change_none}, - {PEER_FLAG_OVERRIDE_CAPABILITY, 0, peer_change_none}, - {PEER_FLAG_STRICT_CAP_MATCH, 0, peer_change_none}, - {PEER_FLAG_DYNAMIC_CAPABILITY, 0, peer_change_none}, - {PEER_FLAG_DISABLE_CONNECTED_CHECK, 0, peer_change_reset}, - {PEER_FLAG_CAPABILITY_ENHE, 0, peer_change_reset}, - {PEER_FLAG_ENFORCE_FIRST_AS, 0, peer_change_reset_in}, - {PEER_FLAG_IFPEER_V6ONLY, 0, peer_change_reset}, - {PEER_FLAG_ROUTEADV, 0, peer_change_none}, - {PEER_FLAG_TIMER, 0, peer_change_none}, - {PEER_FLAG_TIMER_CONNECT, 0, peer_change_none}, - {PEER_FLAG_TIMER_DELAYOPEN, 0, peer_change_none}, - {PEER_FLAG_PASSWORD, 0, peer_change_none}, - {PEER_FLAG_LOCAL_AS, 0, peer_change_reset}, - {PEER_FLAG_LOCAL_AS_NO_PREPEND, 0, peer_change_reset}, - {PEER_FLAG_LOCAL_AS_REPLACE_AS, 0, peer_change_reset}, - {PEER_FLAG_DUAL_AS, 0, peer_change_reset}, - {PEER_FLAG_UPDATE_SOURCE, 0, peer_change_none}, - {PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE, 0, peer_change_none}, - {PEER_FLAG_EXTENDED_OPT_PARAMS, 0, peer_change_reset}, - {PEER_FLAG_ROLE_STRICT_MODE, 0, peer_change_none}, - {PEER_FLAG_ROLE, 0, peer_change_none}, - {PEER_FLAG_PORT, 0, peer_change_reset}, - {PEER_FLAG_AIGP, 0, peer_change_none}, - {PEER_FLAG_GRACEFUL_SHUTDOWN, 0, peer_change_none}, - {PEER_FLAG_CAPABILITY_SOFT_VERSION, 0, peer_change_none}, - {PEER_FLAG_CAPABILITY_FQDN, 0, peer_change_none}, - {PEER_FLAG_AS_LOOP_DETECTION, 0, peer_change_none}, - {PEER_FLAG_EXTENDED_LINK_BANDWIDTH, 0, peer_change_none}, - {PEER_FLAG_LONESOUL, 0, peer_change_reset_out}, - {0, 0, 0}}; + { PEER_FLAG_PASSIVE, 0, peer_change_reset }, + { PEER_FLAG_SHUTDOWN, 0, peer_change_reset }, + { PEER_FLAG_RTT_SHUTDOWN, 0, peer_change_none }, + { PEER_FLAG_DONT_CAPABILITY, 0, peer_change_none }, + { PEER_FLAG_OVERRIDE_CAPABILITY, 0, peer_change_none }, + { PEER_FLAG_STRICT_CAP_MATCH, 0, peer_change_none }, + { PEER_FLAG_DYNAMIC_CAPABILITY, 0, peer_change_none }, + { PEER_FLAG_DISABLE_CONNECTED_CHECK, 0, peer_change_reset }, + { PEER_FLAG_CAPABILITY_ENHE, 0, peer_change_reset }, + { PEER_FLAG_ENFORCE_FIRST_AS, 0, peer_change_reset_in }, + { PEER_FLAG_IFPEER_V6ONLY, 0, peer_change_reset }, + { PEER_FLAG_ROUTEADV, 0, peer_change_none }, + { PEER_FLAG_TIMER, 0, peer_change_none }, + { PEER_FLAG_TIMER_CONNECT, 0, peer_change_none }, + { PEER_FLAG_TIMER_DELAYOPEN, 0, peer_change_none }, + { PEER_FLAG_PASSWORD, 0, peer_change_none }, + { PEER_FLAG_LOCAL_AS, 0, peer_change_reset }, + { PEER_FLAG_LOCAL_AS_NO_PREPEND, 0, peer_change_reset }, + { PEER_FLAG_LOCAL_AS_REPLACE_AS, 0, peer_change_reset }, + { PEER_FLAG_DUAL_AS, 0, peer_change_reset }, + { PEER_FLAG_UPDATE_SOURCE, 0, peer_change_none }, + { PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE, 0, peer_change_none }, + { PEER_FLAG_EXTENDED_OPT_PARAMS, 0, peer_change_reset }, + { PEER_FLAG_ROLE_STRICT_MODE, 0, peer_change_none }, + { PEER_FLAG_ROLE, 0, peer_change_none }, + { PEER_FLAG_PORT, 0, peer_change_reset }, + { PEER_FLAG_AIGP, 0, peer_change_none }, + { PEER_FLAG_GRACEFUL_SHUTDOWN, 0, peer_change_none }, + { PEER_FLAG_CAPABILITY_SOFT_VERSION, 0, peer_change_none }, + { PEER_FLAG_CAPABILITY_FQDN, 0, peer_change_none }, + { PEER_FLAG_AS_LOOP_DETECTION, 0, peer_change_none }, + { PEER_FLAG_EXTENDED_LINK_BANDWIDTH, 0, peer_change_none }, + { PEER_FLAG_LONESOUL, 0, peer_change_reset_out }, + { PEER_FLAG_TCP_MSS, 0, peer_change_none }, + { 0, 0, 0 } +}; static const struct peer_flag_action peer_af_flag_action_list[] = { {PEER_FLAG_SEND_COMMUNITY, 1, peer_change_reset_out}, @@ -6097,8 +6103,24 @@ void peer_port_unset(struct peer *peer) */ void peer_tcp_mss_set(struct peer *peer, uint32_t tcp_mss) { + struct peer *member; + struct listnode *node, *nnode; + + peer_flag_set(peer, PEER_FLAG_TCP_MSS); peer->tcp_mss = tcp_mss; - SET_FLAG(peer->flags, PEER_FLAG_TCP_MSS); + + if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) + return; + + for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) { + /* Skip peers with overridden configuration. */ + if (CHECK_FLAG(member->flags_override, PEER_FLAG_TCP_MSS)) + continue; + + /* Set flag and configuration on peer-group member. */ + SET_FLAG(member->flags, PEER_FLAG_TCP_MSS); + PEER_ATTR_INHERIT(member, peer->group, tcp_mss); + } bgp_tcp_mss_set(peer); } @@ -6108,8 +6130,37 @@ void peer_tcp_mss_set(struct peer *peer, uint32_t tcp_mss) */ void peer_tcp_mss_unset(struct peer *peer) { - UNSET_FLAG(peer->flags, PEER_FLAG_TCP_MSS); - peer->tcp_mss = 0; + struct peer *member; + struct listnode *node, *nnode; + + /* Inherit configuration from peer-group if peer is member. */ + if (peer_group_active(peer)) { + peer_flag_inherit(peer, PEER_FLAG_TCP_MSS); + PEER_ATTR_INHERIT(peer, peer->group, tcp_mss); + } else { + /* Otherwise remove flag and configuration from peer. */ + peer_flag_unset(peer, PEER_FLAG_TCP_MSS); + peer->tcp_mss = 0; + } + + /* Skip peer-group mechanics for regular peers. */ + if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { + return; + } + + /* + * Remove flag and configuration from all peer-group members, unless + * they are explicitely overriding peer-group configuration. + */ + for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) { + /* Skip peers with overridden configuration. */ + if (CHECK_FLAG(member->flags_override, PEER_FLAG_TCP_MSS)) + continue; + + /* Remove flag and configuration on peer-group member. */ + UNSET_FLAG(member->flags, PEER_FLAG_TCP_MSS); + member->tcp_mss = 0; + } bgp_tcp_mss_set(peer); }