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

bgp_af - Add support for 'dup-addr-detection' commands #452

Open
wants to merge 4 commits into
base: main
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
minor_changes:
- bgp_af - Add support for 'dup-addr-detection' commands (https://github.com/ansible-collections/dellemc.enterprise_sonic/pull/452).
10 changes: 10 additions & 0 deletions plugins/module_utils/network/sonic/argspec/bgp_af/bgp_af.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,16 @@ def __init__(self, **kwargs):
},
'network': {'type': 'list', 'elements': 'str'},
'dampening': {'type': 'bool'},
'dup_addr_detection': {
'options': {
'enabled': {'type': 'bool'},
'freeze': {'type': 'str'},
'max_moves': {'type': 'int'},
'time': {'type': 'int'}
},
'required_together': [['max_moves', 'time']],
'type': 'dict'
},
'redistribute': {
'elements': 'dict',
'options': {
Expand Down
82 changes: 81 additions & 1 deletion plugins/module_utils/network/sonic/config/bgp_af/bgp_af.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,12 @@ class Bgp_af(ConfigBase):
afi_safi_path = 'global/afi-safis/afi-safi'
table_connection_path = 'table-connections/table-connection'

dad_attrs = (
'enabled',
'freeze',
'max_moves',
'time'
)
advertise_attrs_map = {
'advertise_pip': 'advertise-pip',
'advertise_pip_ip': 'advertise-pip-ip',
Expand Down Expand Up @@ -588,6 +594,24 @@ def get_modify_import_request(self, vrf_name, conf_afi, conf_safi, conf_import):
request = {"path": url, "method": PATCH, "data": import_payload}
return request

def get_modify_dad_requests(self, vrf_name, conf_afi, conf_safi, conf_addr_fam):
requests = []
url = '{0}={1}/{2}/{3}={4}_{5}/l2vpn-evpn/openconfig-bgp-evpn-ext:dup-addr-detection/config'.format(self.network_instance_path, vrf_name,
self.protocol_bgp_path, self.afi_safi_path,
conf_afi.upper(), conf_safi.upper())

dad_payload = {}
conf_dad = conf_addr_fam.get('dup_addr_detection')
if conf_dad:
for attr in self.dad_attrs:
if conf_dad.get(attr) is not None:
dad_payload[attr.replace('_', '-')] = conf_dad[attr]

if dad_payload:
requests.append({"path": url, "method": PATCH, "data": {'openconfig-bgp-evpn-ext:config': dad_payload}})

return requests

def get_modify_single_af_request(self, vrf_name, conf_afi, conf_safi, conf_addr_fam):
requests = []

Expand Down Expand Up @@ -626,12 +650,15 @@ def get_modify_single_af_request(self, vrf_name, conf_afi, conf_safi, conf_addr_
cfg_req = self.get_modify_evpn_adv_cfg_request(vrf_name, conf_afi, conf_safi, conf_addr_fam)
vni_req = self.get_modify_evpn_vnis_request(vrf_name, conf_afi, conf_safi, conf_addr_fam)
rt_adv_req = self.get_modify_route_advertise_list_request(vrf_name, conf_afi, conf_safi, conf_addr_fam)
dad_reqs = self.get_modify_dad_requests(vrf_name, conf_afi, conf_safi, conf_addr_fam)
if cfg_req:
requests.append(cfg_req)
if vni_req:
requests.append(vni_req)
if rt_adv_req:
requests.append(rt_adv_req)
if dad_reqs:
requests.extend(dad_reqs)
return requests

def get_modify_all_af_requests(self, conf_addr_fams, vrf_name):
Expand Down Expand Up @@ -683,12 +710,15 @@ def get_modify_requests(self, conf, match, vrf_name):
cfg_req = self.get_modify_evpn_adv_cfg_request(vrf_name, conf_afi, conf_safi, conf_addr_fam)
vni_req = self.get_modify_evpn_vnis_request(vrf_name, conf_afi, conf_safi, conf_addr_fam)
rt_adv_req = self.get_modify_route_advertise_list_request(vrf_name, conf_afi, conf_safi, conf_addr_fam)
dad_reqs = self.get_modify_dad_requests(vrf_name, conf_afi, conf_safi, conf_addr_fam)
if cfg_req:
requests.append(cfg_req)
if vni_req:
requests.append(vni_req)
if rt_adv_req:
requests.append(rt_adv_req)
if dad_reqs:
requests.extend(dad_reqs)

elif conf_afi in ["ipv4", "ipv6"] and conf_safi == "unicast":
conf_redis_arr = conf_addr_fam.get('redistribute', [])
Expand Down Expand Up @@ -1002,6 +1032,7 @@ def get_delete_single_bgp_af_request(self, conf, is_delete_all, match=None):
conf_vnis = conf_addr_fam.get('vnis', [])
conf_import = conf_addr_fam.get('import', None)
conf_aggregate = conf_addr_fam.get('aggregate_address_config')
conf_dad = conf_addr_fam.get('dup_addr_detection')

if is_delete_all:
if conf_adv_pip_ip:
Expand Down Expand Up @@ -1038,6 +1069,8 @@ def get_delete_single_bgp_af_request(self, conf, is_delete_all, match=None):
requests.extend(self.get_delete_import_requests(vrf_name, conf_afi, conf_safi, conf_import, is_delete_all, None))
if conf_aggregate:
requests.append(self.get_delete_aggregate_attr(vrf_name, conf_afi, conf_safi, None, None))
if conf_dad:
requests.extend(self.get_delete_dad_requests(vrf_name, conf_afi, conf_safi, conf_dad, is_delete_all, None))
addr_family_del_req = self.get_delete_address_family_request(vrf_name, conf_afi, conf_safi)
if addr_family_del_req:
requests.append(addr_family_del_req)
Expand Down Expand Up @@ -1068,11 +1101,12 @@ def get_delete_single_bgp_af_request(self, conf, is_delete_all, match=None):
mat_vnis = match_addr_fam.get('vnis', [])
mat_import = match_addr_fam.get('import', None)
mat_aggregate = match_addr_fam.get('aggregate_address_config')
mat_dad = match_addr_fam.get('dup_addr_detection')

if (conf_adv_pip is None and not conf_adv_pip_ip and not conf_adv_pip_peer_ip and conf_adv_svi_ip is None and not conf_import
and conf_adv_all_vni is None and not conf_redis_arr and conf_adv_default_gw is None and not conf_max_path and conf_dampening is
None and not conf_network and not conf_route_adv_list and not conf_rd and not conf_rt_in and not conf_rt_out and not conf_vnis
and not conf_aggregate):
and not conf_aggregate and not conf_dad):
if mat_advt_pip_ip:
requests.append(self.get_delete_advertise_attribute_request(vrf_name, conf_afi, conf_safi, 'advertise-pip-ip'))
if mat_advt_pip_peer_ip:
Expand Down Expand Up @@ -1109,6 +1143,8 @@ def get_delete_single_bgp_af_request(self, conf, is_delete_all, match=None):
if mat_aggregate:
requests.extend(self.get_delete_aggregate_requests(vrf_name, conf_afi, conf_safi, mat_aggregate, is_delete_all,
mat_aggregate))
if mat_dad:
requests.extend(self.get_delete_dad_requests(vrf_name, conf_afi, conf_safi, mat_dad, is_delete_all, mat_dad))
addr_family_del_req = self.get_delete_address_family_request(vrf_name, conf_afi, conf_safi)
if addr_family_del_req:
requests.append(addr_family_del_req)
Expand Down Expand Up @@ -1154,6 +1190,8 @@ def get_delete_single_bgp_af_request(self, conf, is_delete_all, match=None):
requests.extend(self.get_delete_import_requests(vrf_name, conf_afi, conf_safi, conf_import, is_delete_all, mat_import))
if conf_aggregate and mat_aggregate:
requests.extend(self.get_delete_aggregate_requests(vrf_name, conf_afi, conf_safi, conf_aggregate, is_delete_all, mat_aggregate))
if conf_dad and mat_dad:
requests.extend(self.get_delete_dad_requests(vrf_name, conf_afi, conf_safi, conf_dad, is_delete_all, mat_dad))
break

return requests
Expand Down Expand Up @@ -1302,6 +1340,27 @@ def get_delete_import_requests(self, vrf_name, conf_afi, conf_safi, conf_import,

return requests

def get_delete_dad_requests(self, vrf_name, conf_afi, conf_safi, conf_dad, is_delete_all, mat_dad):
requests = []
url = '{0}={1}/{2}/{3}={4}_{5}/l2vpn-evpn/openconfig-bgp-evpn-ext:dup-addr-detection/config'.format(self.network_instance_path, vrf_name,
self.protocol_bgp_path, self.afi_safi_path,
conf_afi.upper(), conf_safi.upper())

# Duplicate address detection is enabled by default
# Hence, delete (set to enable) the config only when it is disabled
if conf_dad.get('enabled') is False and (is_delete_all or (conf_dad['enabled'] == mat_dad.get('enabled'))):
payload = {'openconfig-bgp-evpn-ext:enabled': True}
requests.append({'path': url + '/enabled', 'method': PATCH, 'data': payload})

for attr in self.dad_attrs:
if attr == 'enabled':
continue

if conf_dad.get(attr) is not None and (is_delete_all or (conf_dad[attr] == mat_dad.get(attr))):
requests.append({'path': '{0}/{1}'.format(url, attr.replace('_', '-')), 'method': DELETE})

return requests

def get_delete_bgp_af_requests(self, commands, have, is_delete_all):
requests = []
for cmd in commands:
Expand Down Expand Up @@ -1379,6 +1438,27 @@ def get_delete_commands_requests_for_replaced_overridden(self, want, have, state
'{0}={1}'.format(self.advertise_attrs_map[option],
quote_plus(','.join(del_rt)))))

dad_conf = afi_conf['dup_addr_detection'].copy() if afi_conf.get('dup_addr_detection') else {}
# Duplicate address detection is enabled by default
if dad_conf.get('enabled'):
dad_conf.pop('enabled')

if dad_conf:
match_dad_cfg = match_afi_cfg.get('dup_addr_detection', {})
if not match_dad_cfg:
afi_command['dup_addr_detection'] = dad_conf
requests.extend(self.get_delete_dad_requests(vrf_name, afi, safi, afi_command['dup_addr_detection'], True, None))
else:
dad_command = {}
for attr in self.dad_attrs:
if dad_conf.get(attr) is not None and match_dad_cfg.get(attr) is None:
dad_command[attr] = dad_conf[attr]

if dad_command:
afi_command['dup_addr_detection'] = dad_command
requests.extend(self.get_delete_dad_requests(vrf_name, afi, safi,
afi_command['dup_addr_detection'], False, afi_command['dup_addr_detection']))

if afi_conf.get('route_advertise_list'):
route_adv_list = []
match_route_adv_list = match_afi_cfg.get('route_advertise_list', [])
Expand Down
20 changes: 19 additions & 1 deletion plugins/module_utils/network/sonic/facts/bgp_af/bgp_af.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ class Bgp_afFacts(object):
'vnis': ['l2vpn-evpn', 'openconfig-bgp-evpn-ext:vnis', 'vni'],
'import_vrf_list': ['openconfig-bgp-ext:import-network-instance', 'config', 'name'],
'import_vrf_route_map': ['openconfig-bgp-ext:import-network-instance', 'config', 'policy-name'],
'aggregate_address_config': ['aggregate-address-config', 'aggregate-address']
'aggregate_address_config': ['aggregate-address-config', 'aggregate-address'],
'dad': ['l2vpn-evpn', 'openconfig-bgp-evpn-ext:dup-addr-detection']
}

af_redis_params_map = {
Expand Down Expand Up @@ -112,6 +113,7 @@ def populate_facts(self, connection, ansible_facts, data=None):
self.update_route_advertise_list(data)
self.update_vnis(data)
self.update_import(data)
self.update_dad(data)
bgp_redis_data = get_all_bgp_af_redistribute(self._module, vrf_list, self.af_redis_params_map)
self.update_redis_data(data, bgp_redis_data)
self.update_afis(data)
Expand Down Expand Up @@ -320,6 +322,22 @@ def update_import(self, data):
if import_vrf:
af['import'] = {'vrf': import_vrf}

def update_dad(self, data):
dad_options = ('enabled', 'freeze', 'max-moves', 'time')
for conf in data:
afs = conf.get('address_family', [])
if afs:
for af in afs:
dup_addr_detection = {}
dad_config = af.pop('dad', {})
if dad_config.get('config'):
for option in dad_options:
if option in dad_config['config']:
dup_addr_detection[option.replace('-', '_')] = dad_config['config'][option]

if dup_addr_detection:
af['dup_addr_detection'] = dup_addr_detection

def normalize_af_redis_params(self, af):
norm_af = list()
for e_af in af:
Expand Down
Loading
Loading