Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Yang] [frrcfgd] Add SONiC support to enable isisd and configure ISIS #13527

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 28 additions & 2 deletions dockers/docker-fpm-frr/docker_init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ CFGGEN_PARAMS=" \

FRR_VARS=$(sonic-cfggen $CFGGEN_PARAMS)
CONFIG_TYPE=$(echo $FRR_VARS | jq -r '.docker_routing_config_mode')
CONFIG_DB_JSON=/etc/sonic/config_db.json
TMP_ISIS_COPP_CONFIG_DB_JSON=/tmp/isis_copp_config_db.json
ISIS_COPP_CONFIG_TEMPLATE=/usr/local/sonic/frrcfgd/isis_copp_trap_config.j2

update_default_gw()
{
Expand All @@ -41,6 +44,26 @@ update_default_gw()
fi
}

# Create and load requested configuration profile
load_config()
{
if [ "$1" = "isis" ]; then
DEST_FILE=${TMP_ISIS_COPP_CONFIG_DB_JSON}
rm -f ${TMP_ISIS_COPP_CONFIG_DB_JSON}
sonic-cfggen -d -t ${ISIS_COPP_CONFIG_TEMPLATE} > ${DEST_FILE}
fi

if [ -e ${DEST_FILE} ]; then
sonic-cfggen -j ${DEST_FILE} -w
config reload ${CONFIG_DB_JSON} -y -f
rm -f ${DEST_FILE}
return 0
else
echo "Failed to generate and apply ${1} configuration profile."
fi
return 1
}

write_default_zebra_config()
{
FILE_NAME=${1}
Expand All @@ -55,6 +78,8 @@ if [[ ! -z "$NAMESPACE_ID" ]]; then
update_default_gw 6
fi

load_config isis

if [ -z "$CONFIG_TYPE" ] || [ "$CONFIG_TYPE" == "separated" ]; then
CFGGEN_PARAMS=" \
-d \
Expand All @@ -68,9 +93,10 @@ if [ -z "$CONFIG_TYPE" ] || [ "$CONFIG_TYPE" == "separated" ]; then
CFGGEN_PARAMS="$CFGGEN_PARAMS \
-t /usr/local/sonic/frrcfgd/bfdd.conf.j2,/etc/frr/bfdd.conf \
-t /usr/local/sonic/frrcfgd/ospfd.conf.j2,/etc/frr/ospfd.conf \
-t /usr/local/sonic/frrcfgd/isisd.conf.j2,/etc/frr/isisd.conf \
"
else
rm -f /etc/frr/bfdd.conf /etc/frr/ospfd.conf
rm -f /etc/frr/bfdd.conf /etc/frr/ospfd.conf /etc/frr/isisd.conf
fi
sonic-cfggen $CFGGEN_PARAMS
echo "no service integrated-vtysh-config" > /etc/frr/vtysh.conf
Expand All @@ -92,7 +118,7 @@ elif [ "$CONFIG_TYPE" == "unified" ]; then
sonic-cfggen $CFGGEN_PARAMS
echo "service integrated-vtysh-config" > /etc/frr/vtysh.conf
rm -f /etc/frr/bgpd.conf /etc/frr/zebra.conf /etc/frr/staticd.conf \
/etc/frr/bfdd.conf /etc/frr/ospfd.conf /etc/frr/pimd.conf
/etc/frr/bfdd.conf /etc/frr/ospfd.conf /etc/frr/pimd.conf /etc/frr/isisd.conf
fi

chown -R frr:frr /etc/frr/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ program:staticd
program:bgpd
program:fpmsyncd
{% if DEVICE_METADATA.localhost.frr_mgmt_framework_config is defined and DEVICE_METADATA.localhost.frr_mgmt_framework_config == "true" %}
program:isisd
program:bfdd
program:ospfd
program:pimd
Expand Down
12 changes: 12 additions & 0 deletions dockers/docker-fpm-frr/frr/supervisord/supervisord.conf.j2
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,18 @@ dependent_startup=true
dependent_startup_wait_for=zsocket:exited

{% if DEVICE_METADATA.localhost.frr_mgmt_framework_config is defined and DEVICE_METADATA.localhost.frr_mgmt_framework_config == "true" %}
[program:isisd]
command=/usr/lib/frr/isisd -A 127.0.0.1 -M snmp
priority=5
stopsignal=KILL
autostart=false
autorestart=false
startsecs=0
stdout_logfile=syslog
stderr_logfile=syslog
dependent_startup=true
dependent_startup_wait_for=zsocket:exited

[program:ospfd]
command=/usr/lib/frr/ospfd -A 127.0.0.1 -M snmp
priority=5
Expand Down
303 changes: 294 additions & 9 deletions src/sonic-frr-mgmt-framework/frrcfgd/frrcfgd.py

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion src/sonic-frr-mgmt-framework/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@
'templates/staticd/staticd.conf.j2',
'templates/staticd/staticd.db.conf.j2',
'templates/staticd/staticd.db.default_route.conf.j2',
'templates/frr/frr.conf.j2'])
'templates/frr/frr.conf.j2',
'templates/isisd/isisd.conf.j2',
'templates/isisd/isisd.conf.db.j2',
'templates/isisd/isis_copp_trap_config.j2'])
]
)
2 changes: 2 additions & 0 deletions src/sonic-frr-mgmt-framework/templates/frr/frr.conf.j2
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,5 @@ agentx
!
{% include "bfdd.conf.j2" %}
!
{% include "isisd.conf.j2" %}
!
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"COPP_TRAP": {
"bgp": {
{% if DEVICE_METADATA.localhost.frr_mgmt_framework_config is defined and DEVICE_METADATA.localhost.frr_mgmt_framework_config == "true" %}

"trap_ids": "bgp,bgpv6,isis"
{% else %}
"trap_ids": "bgp,bgpv6"
{% endif %}
}
}
}
168 changes: 168 additions & 0 deletions src/sonic-frr-mgmt-framework/templates/isisd/isisd.conf.db.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
! template: isisd/isisd.conf.db.j2
!
! ISIS configuration
!
{% if ISIS_GLOBAL is defined and ISIS_GLOBAL|length > 0 %}
{% for keys, isis_instance in ISIS_GLOBAL.items() %}
{% set vrf = keys[0] %}
{% set instance = keys[1] %}
{% if instance and instance.lower() != 'null' and vrf and vrf.lower() != 'null' %}
router isis {{ instance }} vrf {{vrf}}
{% if 'net' in isis_instance and isis_instance['net'] != 'None' %}
net {{ isis_instance['net'] }}
{% endif %}
{% if 'level_capability' in isis_instance %}
{% if isis_instance['level_capability'] == 'LEVEL_1' %}
is-type level-1
{% elif isis_instance['level_capability'] == 'LEVEL_2' %}
is-type level-2-only
{% elif isis_instance['level_capability'] == 'LEVEL_1_2' %}
is-type level-1-2
{% endif %}
{% endif %}
{% if 'dynamic_hostname' in isis_instance %}
{% if isis_instance['dynamic_hostname'] == 'true' %}
hostname dynamic
{% elif isis_instance['dynamic_hostname'] == 'false' %}
no hostname dynamic
{% endif %}
{% endif %}
{% if 'attach_send' in isis_instance %}
{% if isis_instance['attach_send'] == 'true' %}
attached-bit send
{% elif isis_instance['attach_send'] == 'false' %}
no attached-bit send
{% endif %}
{% endif %}
{% if 'attach_receive_ignore' in isis_instance %}
{% if isis_instance['attach_receive_ignore'] == 'true' %}
attached-bit receive ignore
{% elif isis_instance['attach_receive_ignore'] == 'false' %}
no attached-bit receive ignore
{% endif %}
{% endif %}
{% if 'set_overload_bit' in isis_instance %}
{% if isis_instance['set_overload_bit'] == 'true' %}
set-overload-bit
{% elif isis_instance['set_overload_bit'] == 'false' %}
no set-overload-bit
{% endif %}
{% endif %}
{% if 'lsp_mtu_size' in isis_instance %}
lsp-mtu {{ isis_instance['lsp_mtu_size'] }}
{% endif %}
{% if 'spf_init_delay' in isis_instance and 'spf_short_delay' in isis_instance and 'spf_long_delay' in isis_instance and 'spf_hold_down' in isis_instance and 'spf_time_to_learn' in isis_instance %}
spf-delay-ietf init-delay {{ isis_instance['spf_init_delay'] }} short-delay {{ isis_instance['spf_short_delay'] }} long-delay {{ isis_instance['spf_long_delay'] }} holddown {{ isis_instance['spf_hold_down'] }} time-to-learn {{ isis_instance['spf_time_to_learn'] }}
{% endif %}
{% if 'log_adjacency_changes' in isis_instance %}
{% if isis_instance['log_adjacency_changes'] == 'true' %}
log-adjacency-changes
{% elif isis_instance['log_adjacency_changes'] == 'false' %}
no log-adjacency-changes
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
!
{% if ISIS_LEVELS is defined and ISIS_LEVELS|length > 0 %}
{% for keys, isis_level_data in ISIS_LEVELS.items() %}
{% set vrf = keys[0] %}
{% set instance = keys[1] %}
{% set level_number = keys[2] %}
{% if instance and instance.lower() != 'null' and vrf and vrf.lower() != 'null' and level_number and (level_number == '1' or level_number == '2') %}
router isis {{ instance }} vrf {{vrf}}
{% if level_number == '1' %}
{% set level = 'level-1' %}
{% elif level_number == '2' %}
{% set level = 'level-2' %}
{% endif %}
{% if 'lsp_refresh_interval' in isis_level_data %}
lsp-refresh-interval {{ level }} {{ isis_level_data['lsp_refresh_interval'] }}
{% endif %}
{% if 'lsp_maximum_lifetime' in isis_level_data %}
max-lsp-lifetime {{ level }} {{ isis_level_data['lsp_maximum_lifetime'] }}
{% endif %}
{% if 'lsp_generation_interval' in isis_level_data %}
lsp-gen-interval {{ level }} {{ isis_level_data['lsp_generation_interval'] }}
{% endif %}
{% if 'spf_minimum_interval' in isis_level_data %}
spf-interval {{ level }} {{ isis_level_data['spf_minimum_interval'] }}
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
!
{% if ISIS_INTERFACE is defined and ISIS_INTERFACE|length > 0 %}
{% for keys, isis_interface_data in ISIS_INTERFACE.items() %}
{% set instance = keys[0] %}
{% set interface = keys[1] %}
{% if instance and instance.lower() != 'null' and interface and interface.lower() != 'null' %}
interface {{ interface }}
{% if (('ipv4_routing_instance' in isis_interface_data and not (isis_interface_data['ipv4_routing_instance'] == 'None' or isis_interface_data['ipv4_routing_instance'].lower() == 'null' )) or
('ipv6_routing_instance' in isis_interface_data and not (isis_interface_data['ipv6_routing_instance'] == 'None' or isis_interface_data['ipv6_routing_instance'].lower() == 'null'))) %}
{% if 'ipv4_routing_instance' in isis_interface_data and not (isis_interface_data['ipv4_routing_instance'] == 'None' or isis_interface_data['ipv4_routing_instance'].lower() == 'null' ) %}
ip router isis {{ isis_interface_data['ipv4_routing_instance'] }}
{% endif %}
{% if 'ipv6_routing_instance' in isis_interface_data and not (isis_interface_data['ipv6_routing_instance'] == 'None' or isis_interface_data['ipv6_routing_instance'].lower() == 'null') %}
ipv6 router isis {{ isis_interface_data['ipv6_routing_instance'] }}
{% endif %}
{% if 'passive' in isis_interface_data %}
{% if isis_interface_data['passive'] == 'true' %}
isis passive
{% elif isis_interface_data['passive'] == 'false' %}
no isis passive
{% endif %}
{% endif %}
{% if 'hello_padding' in isis_interface_data %}
{% if isis_interface_data['hello_padding'] == 'true' %}
isis hello padding
{% elif isis_interface_data['hello_padding'] == 'false' %}
no isis hello padding
{% endif %}
{% endif %}
{% if 'network_type' in isis_interface_data %}
{% if isis_interface_data['network_type'] == 'POINT_TO_POINT' %}
isis network point-to-point
{% endif %}
{% endif %}
{% if 'authentication_key' in isis_interface_data and 'authentication_type' in isis_interface_data and not
(isis_interface_data['authentication_key'] == 'None' or isis_interface_data['authentication_key'].lower() == 'null') %}
{% if isis_interface_data['authentication_type'] == 'TEXT' %}
isis password clear {{ isis_interface_data['authentication_key'] }}
{% elif isis_interface_data['authentication_type'] == 'MD5' %}
isis password md5 {{ isis_interface_data['authentication_key'] }}
{% endif %}
{% endif %}
{% if 'enable_bfd' in isis_interface_data %}
{% if isis_interface_data['enable_bfd'] == 'true' %}
isis bfd
{% elif isis_interface_data['enable_bfd'] == 'false' %}
no isis bfd
{% endif %}
{% endif %}
{% if 'bfd_profile' in isis_interface_data and not (isis_interface_data['bfd_profile'] == 'None' or isis_interface_data['bfd_profile'].lower() == 'null') %}
isis bfd profile {{ isis_interface_data['bfd_profile'] }}
{% endif %}
{% if 'metric' in isis_interface_data %}
isis metric {{ isis_interface_data['metric'] }}
{% endif %}
{% if 'csnp_interval' in isis_interface_data %}
isis csnp-interval {{ isis_interface_data['csnp_interval'] }}
{% endif %}
{% if 'psnp_interval' in isis_interface_data %}
isis psnp-interval {{ isis_interface_data['psnp_interval'] }}
{% endif %}
{% if 'hello_interval' in isis_interface_data %}
isis hello-interval {{ isis_interface_data['hello_interval'] }}
{% endif %}
{% if 'hello_multiplier' in isis_interface_data %}
isis hello-multiplier {{ isis_interface_data['hello_multiplier'] }}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
!
! end of template: isisd/isisd.conf.db.j2
!
10 changes: 10 additions & 0 deletions src/sonic-frr-mgmt-framework/templates/isisd/isisd.conf.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
! template: isisd/isisd.conf.j2
!
! ISIS configuration using config DB ISIS instance tables
!
{% include "common/daemons.common.conf.j2" %}
!
{% include "isisd.conf.db.j2" %}
!
! end of template: isisd/isisd.conf.j2
!
77 changes: 77 additions & 0 deletions src/sonic-frr-mgmt-framework/tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,82 @@ def hdl_confed_peers_cmd(is_del, cmd_list, chk_data):
conf_bgp_af_cmd('Vrf_red', 200, 'ipv6') + ['{}import vrf route-map test_map']),
]

conf_isis_cmd = lambda vrf, instance: [conf_cmd, 'router isis %s vrf %s' % (instance, vrf)]
conf_isis_if_cmd = lambda instance, ifname: [conf_cmd, 'interface %s' % (ifname)]
conf_isis_level_cmd = lambda vrf, instance, level: conf_isis_cmd(vrf, instance)

isis_data = [
CmdMapTestInfo('ISIS_GLOBAL', 'default|100', {'net': '49.0001.1040.4400.0249.00'},
conf_isis_cmd('default', 100) + ['{}net 49.0001.1040.4400.0249.00']),
CmdMapTestInfo('ISIS_GLOBAL', 'default|100', {'level_capability': 'LEVEL_2'},
conf_isis_cmd('default', 100) + ['{}is-type level-2']),
CmdMapTestInfo('ISIS_GLOBAL', 'default|100', {'dynamic_hostname': 'true'},
conf_isis_cmd('default', 100) + ['{}hostname dynamic'], True),
CmdMapTestInfo('ISIS_GLOBAL', 'default|100', {'dynamic_hostname': 'None'},
conf_isis_cmd('default', 100) + ['{}hostname dynamic'], True),
CmdMapTestInfo('ISIS_GLOBAL', 'default|100', {'attach_send': 'true'},
conf_isis_cmd('default', 100) + ['{}attached-bit send'], True),
CmdMapTestInfo('ISIS_GLOBAL', 'default|100', {'attach_send': 'None'},
conf_isis_cmd('default', 100) + ['{}attached-bit send'], True),
CmdMapTestInfo('ISIS_GLOBAL', 'default|100', {'attach_receive_ignore': 'true'},
conf_isis_cmd('default', 100) + ['{}attached-bit receive ignore'], True),
CmdMapTestInfo('ISIS_GLOBAL', 'default|100', {'attach_receive_ignore': 'None'},
conf_isis_cmd('default', 100) + ['no attached-bit receive ignore'], True),
CmdMapTestInfo('ISIS_GLOBAL', 'default|100', {'set_overload_bit': 'true'},
conf_isis_cmd('default', 100) + ['{}set-overload-bit']),
CmdMapTestInfo('ISIS_GLOBAL', 'default|100', {'lsp_mtu_size': '1500'},
conf_isis_cmd('default', 100) + ['{}lsp-mtu 1500']),
CmdMapTestInfo('ISIS_GLOBAL', 'default|100', {'log_adjacency_changes': 'true'},
conf_isis_cmd('default', 100) + ['{}log-adjacency-changes']),
CmdMapTestInfo('ISIS_GLOBAL', 'default|100', {'spf_init_delay': 15,
'spf_short_delay': 15,
'spf_long_delay': 5,
'spf_hold_down': 15,
'spf_time_to_learn': 5},
conf_isis_cmd('default', 100) + ['{}spf-delay-ietf init-delay 15 short-delay 15 long-delay 5 holddown 15 time-to-learn 5']),

CmdMapTestInfo('ISIS_LEVELS', 'default|100|2', {'lsp_refresh_interval': '4'},
conf_isis_level_cmd('default', 100, '2') + ['{}lsp-refresh-interval level-2 4']),
CmdMapTestInfo('ISIS_LEVELS', 'default|100|2', {'lsp_maximum_lifetime': '4'},
conf_isis_level_cmd('default', 100, '2') + ['{}max-lsp-lifetime level-2 4']),
CmdMapTestInfo('ISIS_LEVELS', 'default|100|2', {'lsp_generation_interval': '4'},
conf_isis_level_cmd('default', 100, '2') + ['{}lsp-gen-interval level-2 4']),
CmdMapTestInfo('ISIS_LEVELS', 'default|100|2', {'spf_minimum_interval': '4'},
conf_isis_level_cmd('default', 100, '2') + ['{}spf-interval level-2 4']),

CmdMapTestInfo('ISIS_INTERFACE', '100|ethernet2', {'ipv4_routing_instance': '100'},
conf_isis_if_cmd(100, 'ethernet2') + ['{}ip router isis 100']),
CmdMapTestInfo('ISIS_INTERFACE', '100|ethernet2', {'ipv6_routing_instance': '100'},
conf_isis_if_cmd(100, 'ethernet2') + ['{}ipv6 router isis 100']),
CmdMapTestInfo('ISIS_INTERFACE', '100|ethernet2', {'passive': 'true'},
conf_isis_if_cmd(100, 'ethernet2') + ['{}isis passive']),
CmdMapTestInfo('ISIS_INTERFACE', '100|ethernet2', {'hello_padding': 'true'},
conf_isis_if_cmd(100, 'ethernet2') + ['{}isis hello padding'], True),
CmdMapTestInfo('ISIS_INTERFACE', '100|ethernet2', {'hello_padding': 'None'},
conf_isis_if_cmd(100, 'ethernet2') + ['{}isis hello padding'], True),
CmdMapTestInfo('ISIS_INTERFACE', '100|ethernet2', {'network_type': 'POINT_TO_POINT'},
conf_isis_if_cmd(100, 'ethernet2') + ['{}isis network point-to-point']),
CmdMapTestInfo('ISIS_INTERFACE', '100|ethernet2', {'authentication_type': 'TEXT',
'authentication_key': 'password'},
conf_isis_if_cmd(100, 'ethernet2') + ['{}isis password clear password']),
CmdMapTestInfo('ISIS_INTERFACE', '100|ethernet2', {'enable_bfd': 'true'},
conf_isis_if_cmd(100, 'ethernet2') + ['{}isis bfd'], True),
CmdMapTestInfo('ISIS_INTERFACE', '100|ethernet2', {'enable_bfd': 'None'},
conf_isis_if_cmd(100, 'ethernet2') + ['no isis bfd'], True),
CmdMapTestInfo('ISIS_INTERFACE', '100|ethernet2', {'bfd_profile': 'PROFILE'},
conf_isis_if_cmd(100, 'ethernet2') + ['{}isis bfd profile PROFILE']),
CmdMapTestInfo('ISIS_INTERFACE', '100|ethernet2', {'metric': '500'},
conf_isis_if_cmd(100, 'ethernet2') + ['{}isis metric 500']),
CmdMapTestInfo('ISIS_INTERFACE', '100|ethernet2', {'csnp_interval': '4'},
conf_isis_if_cmd(100, 'ethernet2') + ['{}isis csnp-interval 4']),
CmdMapTestInfo('ISIS_INTERFACE', '100|ethernet2', {'psnp_interval': '4'},
conf_isis_if_cmd(100, 'ethernet2') + ['{}isis psnp-interval 4']),
CmdMapTestInfo('ISIS_INTERFACE', '100|ethernet2', {'hello_interval': '4'},
conf_isis_if_cmd(100, 'ethernet2') + ['{}isis hello-interval 4']),
CmdMapTestInfo('ISIS_INTERFACE', '100|ethernet2', {'hello_multiplier': '4'},
conf_isis_if_cmd(100, 'ethernet2') + ['{}isis hello-multiplier 4'])
]

@patch.dict('sys.modules', **mockmapping)
@patch('frrcfgd.frrcfgd.g_run_command')
def data_set_del_test(test_data, run_cmd):
Expand Down Expand Up @@ -176,3 +252,4 @@ def data_set_del_test(test_data, run_cmd):

def test_bgp_globals():
data_set_del_test(bgp_globals_data)
data_set_del_test(isis_data)
Loading