mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-07 18:37:06 +00:00
tools: frr-reload combine "'router bgp' and line" checks
Signed-off-by: Daniel Walton <dwalton@cumulusnetworks.com> We had multiple places checking for if ctx_keys[0].startswith('router bgp') and line Combine these into a single check
This commit is contained in:
parent
c755f5c434
commit
028bcc883f
@ -623,152 +623,154 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del):
|
|||||||
for (ctx_keys, line) in lines_to_del:
|
for (ctx_keys, line) in lines_to_del:
|
||||||
deleted = False
|
deleted = False
|
||||||
|
|
||||||
if ctx_keys[0].startswith('router bgp') and line and line.startswith('neighbor '):
|
if ctx_keys[0].startswith('router bgp') and line:
|
||||||
"""
|
|
||||||
BGP changed how it displays swpX peers that are part of peer-group. Older
|
|
||||||
versions of frr would display these on separate lines:
|
|
||||||
neighbor swp1 interface
|
|
||||||
neighbor swp1 peer-group FOO
|
|
||||||
|
|
||||||
but today we display via a single line
|
if line.startswith('neighbor '):
|
||||||
neighbor swp1 interface peer-group FOO
|
'''
|
||||||
|
BGP changed how it displays swpX peers that are part of peer-group. Older
|
||||||
|
versions of frr would display these on separate lines:
|
||||||
|
neighbor swp1 interface
|
||||||
|
neighbor swp1 peer-group FOO
|
||||||
|
|
||||||
This change confuses frr-reload.py so check to see if we are deleting
|
but today we display via a single line
|
||||||
neighbor swp1 interface peer-group FOO
|
neighbor swp1 interface peer-group FOO
|
||||||
|
|
||||||
and adding
|
This change confuses frr-reload.py so check to see if we are deleting
|
||||||
neighbor swp1 interface
|
neighbor swp1 interface peer-group FOO
|
||||||
neighbor swp1 peer-group FOO
|
|
||||||
|
|
||||||
If so then chop the del line and the corresponding add lines
|
and adding
|
||||||
"""
|
neighbor swp1 interface
|
||||||
|
neighbor swp1 peer-group FOO
|
||||||
|
|
||||||
re_swpx_int_peergroup = re.search('neighbor (\S+) interface peer-group (\S+)', line)
|
If so then chop the del line and the corresponding add lines
|
||||||
re_swpx_int_v6only_peergroup = re.search('neighbor (\S+) interface v6only peer-group (\S+)', line)
|
'''
|
||||||
|
|
||||||
if re_swpx_int_peergroup or re_swpx_int_v6only_peergroup:
|
re_swpx_int_peergroup = re.search('neighbor (\S+) interface peer-group (\S+)', line)
|
||||||
swpx_interface = None
|
re_swpx_int_v6only_peergroup = re.search('neighbor (\S+) interface v6only peer-group (\S+)', line)
|
||||||
swpx_peergroup = None
|
|
||||||
|
|
||||||
if re_swpx_int_peergroup:
|
if re_swpx_int_peergroup or re_swpx_int_v6only_peergroup:
|
||||||
swpx = re_swpx_int_peergroup.group(1)
|
swpx_interface = None
|
||||||
peergroup = re_swpx_int_peergroup.group(2)
|
swpx_peergroup = None
|
||||||
swpx_interface = "neighbor %s interface" % swpx
|
|
||||||
elif re_swpx_int_v6only_peergroup:
|
|
||||||
swpx = re_swpx_int_v6only_peergroup.group(1)
|
|
||||||
peergroup = re_swpx_int_v6only_peergroup.group(2)
|
|
||||||
swpx_interface = "neighbor %s interface v6only" % swpx
|
|
||||||
|
|
||||||
swpx_peergroup = "neighbor %s peer-group %s" % (swpx, peergroup)
|
if re_swpx_int_peergroup:
|
||||||
found_add_swpx_interface = line_exist(lines_to_add, ctx_keys, swpx_interface)
|
swpx = re_swpx_int_peergroup.group(1)
|
||||||
found_add_swpx_peergroup = line_exist(lines_to_add, ctx_keys, swpx_peergroup)
|
peergroup = re_swpx_int_peergroup.group(2)
|
||||||
tmp_ctx_keys = tuple(list(ctx_keys))
|
swpx_interface = "neighbor %s interface" % swpx
|
||||||
|
elif re_swpx_int_v6only_peergroup:
|
||||||
|
swpx = re_swpx_int_v6only_peergroup.group(1)
|
||||||
|
peergroup = re_swpx_int_v6only_peergroup.group(2)
|
||||||
|
swpx_interface = "neighbor %s interface v6only" % swpx
|
||||||
|
|
||||||
if not found_add_swpx_peergroup:
|
swpx_peergroup = "neighbor %s peer-group %s" % (swpx, peergroup)
|
||||||
tmp_ctx_keys = list(ctx_keys)
|
found_add_swpx_interface = line_exist(lines_to_add, ctx_keys, swpx_interface)
|
||||||
tmp_ctx_keys.append('address-family ipv4 unicast')
|
found_add_swpx_peergroup = line_exist(lines_to_add, ctx_keys, swpx_peergroup)
|
||||||
tmp_ctx_keys = tuple(tmp_ctx_keys)
|
tmp_ctx_keys = tuple(list(ctx_keys))
|
||||||
found_add_swpx_peergroup = line_exist(lines_to_add, tmp_ctx_keys, swpx_peergroup)
|
|
||||||
|
|
||||||
if not found_add_swpx_peergroup:
|
if not found_add_swpx_peergroup:
|
||||||
tmp_ctx_keys = list(ctx_keys)
|
tmp_ctx_keys = list(ctx_keys)
|
||||||
tmp_ctx_keys.append('address-family ipv6 unicast')
|
tmp_ctx_keys.append('address-family ipv4 unicast')
|
||||||
tmp_ctx_keys = tuple(tmp_ctx_keys)
|
tmp_ctx_keys = tuple(tmp_ctx_keys)
|
||||||
found_add_swpx_peergroup = line_exist(lines_to_add, tmp_ctx_keys, swpx_peergroup)
|
found_add_swpx_peergroup = line_exist(lines_to_add, tmp_ctx_keys, swpx_peergroup)
|
||||||
|
|
||||||
if found_add_swpx_interface and found_add_swpx_peergroup:
|
if not found_add_swpx_peergroup:
|
||||||
|
tmp_ctx_keys = list(ctx_keys)
|
||||||
|
tmp_ctx_keys.append('address-family ipv6 unicast')
|
||||||
|
tmp_ctx_keys = tuple(tmp_ctx_keys)
|
||||||
|
found_add_swpx_peergroup = line_exist(lines_to_add, tmp_ctx_keys, swpx_peergroup)
|
||||||
|
|
||||||
|
if found_add_swpx_interface and found_add_swpx_peergroup:
|
||||||
|
deleted = True
|
||||||
|
lines_to_del_to_del.append((ctx_keys, line))
|
||||||
|
lines_to_add_to_del.append((ctx_keys, swpx_interface))
|
||||||
|
lines_to_add_to_del.append((tmp_ctx_keys, swpx_peergroup))
|
||||||
|
|
||||||
|
'''
|
||||||
|
In 3.0.1 we changed how we display neighbor interface command. Older
|
||||||
|
versions of frr would display the following:
|
||||||
|
neighbor swp1 interface
|
||||||
|
neighbor swp1 remote-as external
|
||||||
|
neighbor swp1 capability extended-nexthop
|
||||||
|
|
||||||
|
but today we display via a single line
|
||||||
|
neighbor swp1 interface remote-as external
|
||||||
|
|
||||||
|
and capability extended-nexthop is no longer needed because we
|
||||||
|
automatically enable it when the neighbor is of type interface.
|
||||||
|
|
||||||
|
This change confuses frr-reload.py so check to see if we are deleting
|
||||||
|
neighbor swp1 interface remote-as (external|internal|ASNUM)
|
||||||
|
|
||||||
|
and adding
|
||||||
|
neighbor swp1 interface
|
||||||
|
neighbor swp1 remote-as (external|internal|ASNUM)
|
||||||
|
neighbor swp1 capability extended-nexthop
|
||||||
|
|
||||||
|
If so then chop the del line and the corresponding add lines
|
||||||
|
'''
|
||||||
|
re_swpx_int_remoteas = re.search('neighbor (\S+) interface remote-as (\S+)', line)
|
||||||
|
re_swpx_int_v6only_remoteas = re.search('neighbor (\S+) interface v6only remote-as (\S+)', line)
|
||||||
|
|
||||||
|
if re_swpx_int_remoteas or re_swpx_int_v6only_remoteas:
|
||||||
|
swpx_interface = None
|
||||||
|
swpx_remoteas = None
|
||||||
|
|
||||||
|
if re_swpx_int_remoteas:
|
||||||
|
swpx = re_swpx_int_remoteas.group(1)
|
||||||
|
remoteas = re_swpx_int_remoteas.group(2)
|
||||||
|
swpx_interface = "neighbor %s interface" % swpx
|
||||||
|
elif re_swpx_int_v6only_remoteas:
|
||||||
|
swpx = re_swpx_int_v6only_remoteas.group(1)
|
||||||
|
remoteas = re_swpx_int_v6only_remoteas.group(2)
|
||||||
|
swpx_interface = "neighbor %s interface v6only" % swpx
|
||||||
|
|
||||||
|
swpx_remoteas = "neighbor %s remote-as %s" % (swpx, remoteas)
|
||||||
|
found_add_swpx_interface = line_exist(lines_to_add, ctx_keys, swpx_interface)
|
||||||
|
found_add_swpx_remoteas = line_exist(lines_to_add, ctx_keys, swpx_remoteas)
|
||||||
|
tmp_ctx_keys = tuple(list(ctx_keys))
|
||||||
|
|
||||||
|
if found_add_swpx_interface and found_add_swpx_remoteas:
|
||||||
|
deleted = True
|
||||||
|
lines_to_del_to_del.append((ctx_keys, line))
|
||||||
|
lines_to_add_to_del.append((ctx_keys, swpx_interface))
|
||||||
|
lines_to_add_to_del.append((tmp_ctx_keys, swpx_remoteas))
|
||||||
|
|
||||||
|
'''
|
||||||
|
In 3.0, we made bgp bestpath multipath as-relax command
|
||||||
|
automatically assume no-as-set since the lack of this option caused
|
||||||
|
weird routing problems and this problem was peculiar to this
|
||||||
|
implementation. When the running config is shown in relases after
|
||||||
|
3.0, the no-as-set is not shown as its the default. This causes
|
||||||
|
reload to unnecessarily unapply this option to only apply it back
|
||||||
|
again, causing unnecessary session resets. Handle this.
|
||||||
|
'''
|
||||||
|
if 'multipath-relax' in line:
|
||||||
|
re_asrelax_new = re.search('^bgp\s+bestpath\s+as-path\s+multipath-relax$', line)
|
||||||
|
old_asrelax_cmd = 'bgp bestpath as-path multipath-relax no-as-set'
|
||||||
|
found_asrelax_old = line_exist(lines_to_add, ctx_keys, old_asrelax_cmd)
|
||||||
|
|
||||||
|
if re_asrelax_new and found_asrelax_old:
|
||||||
deleted = True
|
deleted = True
|
||||||
lines_to_del_to_del.append((ctx_keys, line))
|
lines_to_del_to_del.append((ctx_keys, line))
|
||||||
lines_to_add_to_del.append((ctx_keys, swpx_interface))
|
lines_to_add_to_del.append((ctx_keys, old_asrelax_cmd))
|
||||||
lines_to_add_to_del.append((tmp_ctx_keys, swpx_peergroup))
|
|
||||||
|
|
||||||
"""
|
'''
|
||||||
In 3.0.1 we changed how we display neighbor interface command. Older
|
If we are modifying the BGP table-map we need to avoid a del/add and
|
||||||
versions of frr would display the following:
|
instead modify the table-map in place via an add. This is needed to
|
||||||
neighbor swp1 interface
|
avoid installing all routes in the RIB the second the 'no table-map'
|
||||||
neighbor swp1 remote-as external
|
is issued.
|
||||||
neighbor swp1 capability extended-nexthop
|
'''
|
||||||
|
if line.startswith('table-map'):
|
||||||
|
found_table_map = line_exist(lines_to_add, ctx_keys, 'table-map', False)
|
||||||
|
|
||||||
but today we display via a single line
|
if found_table_map:
|
||||||
neighbor swp1 interface remote-as external
|
|
||||||
|
|
||||||
and capability extended-nexthop is no longer needed because we
|
|
||||||
automatically enable it when the neighbor is of type interface.
|
|
||||||
|
|
||||||
This change confuses frr-reload.py so check to see if we are deleting
|
|
||||||
neighbor swp1 interface remote-as (external|internal|ASNUM)
|
|
||||||
|
|
||||||
and adding
|
|
||||||
neighbor swp1 interface
|
|
||||||
neighbor swp1 remote-as (external|internal|ASNUM)
|
|
||||||
neighbor swp1 capability extended-nexthop
|
|
||||||
|
|
||||||
If so then chop the del line and the corresponding add lines
|
|
||||||
"""
|
|
||||||
re_swpx_int_remoteas = re.search('neighbor (\S+) interface remote-as (\S+)', line)
|
|
||||||
re_swpx_int_v6only_remoteas = re.search('neighbor (\S+) interface v6only remote-as (\S+)', line)
|
|
||||||
|
|
||||||
if re_swpx_int_remoteas or re_swpx_int_v6only_remoteas:
|
|
||||||
swpx_interface = None
|
|
||||||
swpx_remoteas = None
|
|
||||||
|
|
||||||
if re_swpx_int_remoteas:
|
|
||||||
swpx = re_swpx_int_remoteas.group(1)
|
|
||||||
remoteas = re_swpx_int_remoteas.group(2)
|
|
||||||
swpx_interface = "neighbor %s interface" % swpx
|
|
||||||
elif re_swpx_int_v6only_remoteas:
|
|
||||||
swpx = re_swpx_int_v6only_remoteas.group(1)
|
|
||||||
remoteas = re_swpx_int_v6only_remoteas.group(2)
|
|
||||||
swpx_interface = "neighbor %s interface v6only" % swpx
|
|
||||||
|
|
||||||
swpx_remoteas = "neighbor %s remote-as %s" % (swpx, remoteas)
|
|
||||||
found_add_swpx_interface = line_exist(lines_to_add, ctx_keys, swpx_interface)
|
|
||||||
found_add_swpx_remoteas = line_exist(lines_to_add, ctx_keys, swpx_remoteas)
|
|
||||||
tmp_ctx_keys = tuple(list(ctx_keys))
|
|
||||||
|
|
||||||
if found_add_swpx_interface and found_add_swpx_remoteas:
|
|
||||||
deleted = True
|
|
||||||
lines_to_del_to_del.append((ctx_keys, line))
|
lines_to_del_to_del.append((ctx_keys, line))
|
||||||
lines_to_add_to_del.append((ctx_keys, swpx_interface))
|
|
||||||
lines_to_add_to_del.append((tmp_ctx_keys, swpx_remoteas))
|
|
||||||
|
|
||||||
'''
|
'''
|
||||||
In 3.0, we made bgp bestpath multipath as-relax command
|
More old-to-new config handling. ip import-table no longer accepts
|
||||||
automatically assume no-as-set since the lack of this option caused
|
distance, but we honor the old syntax. But 'show running' shows only
|
||||||
weird routing problems and this problem was peculiar to this
|
the new syntax. This causes an unnecessary 'no import-table' followed
|
||||||
implementation. When the running config is shown in relases after
|
by the same old 'ip import-table' which causes perturbations in
|
||||||
3.0, the no-as-set is not shown as its the default. This causes
|
announced routes leading to traffic blackholes. Fix this issue.
|
||||||
reload to unnecessarily unapply this option to only apply it back
|
|
||||||
again, causing unnecessary session resets. Handle this.
|
|
||||||
'''
|
|
||||||
if ctx_keys[0].startswith('router bgp') and line and 'multipath-relax' in line:
|
|
||||||
re_asrelax_new = re.search('^bgp\s+bestpath\s+as-path\s+multipath-relax$', line)
|
|
||||||
old_asrelax_cmd = 'bgp bestpath as-path multipath-relax no-as-set'
|
|
||||||
found_asrelax_old = line_exist(lines_to_add, ctx_keys, old_asrelax_cmd)
|
|
||||||
|
|
||||||
if re_asrelax_new and found_asrelax_old:
|
|
||||||
deleted = True
|
|
||||||
lines_to_del_to_del.append((ctx_keys, line))
|
|
||||||
lines_to_add_to_del.append((ctx_keys, old_asrelax_cmd))
|
|
||||||
|
|
||||||
'''
|
|
||||||
If we are modifying the BGP table-map we need to avoid a del/add and
|
|
||||||
instead modify the table-map in place via an add. This is needed to
|
|
||||||
avoid installing all routes in the RIB the second the 'no table-map'
|
|
||||||
is issued.
|
|
||||||
'''
|
|
||||||
if ctx_keys[0].startswith('router bgp') and line and line.startswith('table-map'):
|
|
||||||
found_table_map = line_exist(lines_to_add, ctx_keys, 'table-map', False)
|
|
||||||
|
|
||||||
if found_table_map:
|
|
||||||
lines_to_del_to_del.append((ctx_keys, line))
|
|
||||||
|
|
||||||
'''
|
|
||||||
More old-to-new config handling. ip import-table no longer accepts
|
|
||||||
distance, but we honor the old syntax. But 'show running' shows only
|
|
||||||
the new syntax. This causes an unnecessary 'no import-table' followed
|
|
||||||
by the same old 'ip import-table' which causes perturbations in
|
|
||||||
announced routes leading to traffic blackholes. Fix this issue.
|
|
||||||
'''
|
'''
|
||||||
re_importtbl = re.search('^ip\s+import-table\s+(\d+)$', ctx_keys[0])
|
re_importtbl = re.search('^ip\s+import-table\s+(\d+)$', ctx_keys[0])
|
||||||
if re_importtbl:
|
if re_importtbl:
|
||||||
|
Loading…
Reference in New Issue
Block a user