in src/sonic-frr-mgmt-framework/frrcfgd/frrcfgd.py [0:0]
def __update_bgp(self, data_list):
while not self.bgp_message.empty():
key, del_table, table, data = self.bgp_message.get()
if table == 'STATIC_ROUTE' and len(key.split('|')) == 1:
key = self.DEFAULT_VRF + '|' + key
key_list = key.split('|', 1)
if table == 'BGP_NEIGHBOR' and len(key_list) == 1:
# bypass non-compatible neighbor table
continue
data_list.append((table, key, data))
if len(key_list) > 1:
key = key_list[1]
else:
key = None
prefix = key_list[0]
syslog.syslog(syslog.LOG_INFO, 'value for table {} prefix {} key {} changed to {}'.format(table, prefix, key, data))
if self.__vrf_based_table(table):
vrf = prefix
local_asn = self.__get_vrf_asn(vrf)
if local_asn is None and (table != 'BGP_GLOBALS' or 'local_asn' not in data):
syslog.syslog(syslog.LOG_DEBUG, 'ignore table {} update because local_asn for VRF {} was not configured'.\
format(table, vrf))
continue
if table in self.tbl_to_key_map:
tbl_key = None
if table == 'BGP_NEIGHBOR_AF' or table == 'BGP_PEER_GROUP_AF' and key is not None:
_, af_ip_type = key.split('|')
tbl_key, _ = af_ip_type.lower().split('_')
tbl_key = {'admin_status': tbl_key}
elif table == 'ROUTE_MAP':
tbl_key = {}
for attr_name, table_name in {'match_prefix_set': 'PREFIX', 'match_next_hop_set': 'PREFIX'}.items():
if attr_name in data:
pfx_set_name = self.get_prefix_set_name(data[attr_name].data, table_name)
if pfx_set_name in self.prefix_set_list:
af_mode = self.prefix_set_list[pfx_set_name].af
tbl_key[attr_name] = 'ipv4' if af_mode == socket.AF_INET else 'ipv6'
elif table == 'STATIC_ROUTE':
af_id, new_key = IpNextHopSet.get_af_norm_prefix(key)
if new_key is not None:
key = new_key
tbl_key = {'ip_prefix': ('ipv4' if af_id == socket.AF_INET else 'ipv6')}
key_map = BGPKeyMapList(self.tbl_to_key_map[table], table, tbl_key)
else:
key_map = None
if table == 'BGP_GLOBALS':
if not del_table:
if 'local_asn' in data:
dval = data['local_asn']
if dval.op == CachedDataWithOp.OP_DELETE:
# delete local_asn will delete whole VRF instance
self.__delete_vrf_asn(vrf, table, data)
continue
prog_asn = True
if dval.op == CachedDataWithOp.OP_UPDATE:
syslog.syslog(syslog.LOG_ERR, 'local_asn could not be modified')
prog_asn = False
if dval.op == CachedDataWithOp.OP_NONE:
prog_asn = False
if prog_asn:
command = "vtysh -c 'configure terminal' -c 'router bgp {} vrf {}' -c 'no bgp default ipv4-unicast'".format(dval.data, vrf)
if self.__run_command(table, command):
syslog.syslog(syslog.LOG_DEBUG, 'set local_asn %s to VRF %s, re-apply all VRF related tables' % (dval.data, vrf))
self.bgp_asn[vrf] = dval.data
self.__apply_dep_vrf_table(vrf, 'ROUTE_REDISTRIBUTE')
dval.status = CachedDataWithOp.STAT_SUCC
else:
syslog.syslog(syslog.LOG_ERR, 'failed to set local_asn %s to VRF %s' % (dval.data, vrf))
else:
dval.status = CachedDataWithOp.STAT_SUCC
if 'confed_peers' in data:
self.upd_confed_peers = copy.copy(self.bgp_confed_peers.get(vrf, set()))
local_asn = self.__get_vrf_asn(vrf)
if local_asn is None:
syslog.syslog(syslog.LOG_ERR, 'local ASN for VRF %s was not configured' % vrf)
continue
cmd_prefix = ['configure terminal', 'router bgp {} vrf {}'.format(local_asn, vrf)]
if not key_map.run_command(self, table, data, cmd_prefix):
syslog.syslog(syslog.LOG_ERR, 'failed running BGP global config command')
continue
if 'confed_peers' in data:
self.bgp_confed_peers[vrf] = copy.copy(self.upd_confed_peers)
else:
self.__delete_vrf_asn(vrf, table, data)
elif table == 'BGP_GLOBALS_AF':
af, ip_type = key.lower().split('_')
#this is to temporarily make table cache key accessible to key_map handler function
self.tmp_cache_key = 'BGP_GLOBALS_AF&&{}|{}'.format(vrf, key.lower())
syslog.syslog(syslog.LOG_INFO, 'Set address family global to {} {} cache-key to {}'.format(af, ip_type, self.tmp_cache_key))
cmd_prefix = ['configure terminal',
'router bgp {} vrf {}'.format(local_asn, vrf),
'address-family {} {}'.format(af, ip_type)]
if not key_map.run_command(self, table, data, cmd_prefix):
syslog.syslog(syslog.LOG_ERR, 'failed running BGP global AF config command')
continue
self.tmp_cache_key = ''
elif table == 'BGP_GLOBALS_LISTEN_PREFIX':
syslog.syslog(syslog.LOG_INFO, 'Set BGP listen prefix {}'.format(key))
cmd_prefix = ['configure terminal',
'router bgp {} vrf {}'.format(local_asn, vrf)]
if not key_map.run_command(self, table, data, cmd_prefix, key):
syslog.syslog(syslog.LOG_ERR, 'failed running BGP global listen prefix config command')
continue
elif table == 'BGP_NEIGHBOR' or table == 'BGP_PEER_GROUP':
is_peer_group = table == 'BGP_PEER_GROUP'
if not del_table:
if is_peer_group:
# if peer group is not created, create it before setting other attributes
if key not in self.bgp_peer_group.setdefault(vrf, {}):
command = "vtysh -c 'configure terminal' -c 'router bgp {} vrf {}' ".format(local_asn, vrf)
command += "-c 'neighbor {} peer-group'".format(key)
if not self.__run_command(table, command):
syslog.syslog(syslog.LOG_ERR, 'failed to create peer-group %s for VRF %s' % (key, vrf))
continue
self.bgp_peer_group[vrf][key] = BGPPeerGroup(vrf)
elif not self.__peer_is_ip(key):
if key not in self.bgp_intf_nbr.setdefault(vrf, set()):
command = "vtysh -c 'configure terminal' -c 'router bgp {} vrf {}' ".format(local_asn, vrf)
command += "-c 'neighbor {} interface'".format(key)
if not self.__run_command(table, command):
syslog.syslog(syslog.LOG_ERR, 'failed to create neighbor of interface %s for VRF %s' % (key, vrf))
continue
self.bgp_intf_nbr[vrf].add(key)
bfd_val = data.get('bfd', None)
if (bfd_val is not None and (bfd_val.op == CachedDataWithOp.OP_ADD or bfd_val.op == CachedDataWithOp.OP_UPDATE) and
bfd_val.data == 'true'):
cp_chk_val = data.get('bfd_check_ctrl_plane_failure', None)
if cp_chk_val is not None and cp_chk_val.op == CachedDataWithOp.OP_NONE and cp_chk_val.data == 'true':
cp_chk_val.op = CachedDataWithOp.OP_ADD
cmd_prefix = ['configure terminal', 'router bgp {} vrf {}'.format(local_asn, vrf)]
if not key_map.run_command(self, table, data, cmd_prefix, key):
syslog.syslog(syslog.LOG_ERR, 'failed running BGP neighbor config command')
continue
if ('peer_group_name' in data and
(data['peer_group_name'].op == CachedDataWithOp.OP_ADD or
data['peer_group_name'].op == CachedDataWithOp.OP_DELETE)):
dval = data['peer_group_name']
if vrf not in self.bgp_peer_group or dval.data not in self.bgp_peer_group[vrf]:
# should not happen because vtysh command will fail if peer_group not exists
syslog.syslog(syslog.LOG_ERR, 'invalid peer-group %s was referenced' % dval.data)
continue
peer_grp = self.bgp_peer_group[vrf][dval.data]
if dval.op == CachedDataWithOp.OP_ADD:
peer_grp.ref_nbrs.add(key)
else:
peer_grp.ref_nbrs.discard(key)
nbr_action = self.__nbr_impl_action(data, key, is_peer_group)
if nbr_action == 'delete':
if not is_peer_group and self.__peer_is_ip(key):
# delete asn or peer_group will delete all neighbor
self.__delete_vrf_neighbor(vrf, key, data, False)
elif is_peer_group:
# clear associated neighbor list in cache
self.__delete_pg_neighbors(vrf, key)
elif nbr_action == 'apply':
if is_peer_group:
syslog.syslog(syslog.LOG_DEBUG, 'apply attributes to FRR for vrf %s peer_group %s' % (vrf, key))
match_pg = lambda data: data.get('peer_group', None) == key
self.__apply_dep_vrf_table(vrf, 'BGP_GLOBALS_LISTEN_PREFIX', match = match_pg)
match_nbr = lambda data: data.get('peer_group_name', None) == key
self.__apply_dep_vrf_table(vrf, 'BGP_NEIGHBOR', match = match_nbr)
else:
for af in ['ipv4_unicast', 'ipv6_unicast']:
syslog.syslog(syslog.LOG_DEBUG, 'apply attributes to FRR for vrf %s neighbor %s af %s' % (vrf, key, af))
self.__apply_dep_vrf_table(vrf, 'BGP_NEIGHBOR_AF', key, af)
else:
# Neighbor is deleted
if is_peer_group:
# clear associated neighbor list in cache
self.__delete_pg_neighbors(vrf, key)
command = "vtysh -c 'configure terminal' -c 'router bgp {} vrf {}' -c 'no neighbor {}'".\
format(local_asn, vrf, key)
if not self.__run_command(table, command):
syslog.syslog(syslog.LOG_ERR, 'failed to delete VRF %s bgp neigbor %s' % (vrf, key))
self.__delete_vrf_neighbor(vrf, key, data, is_peer_group)
elif table == 'BGP_NEIGHBOR_AF' or table == 'BGP_PEER_GROUP_AF':
nbr, af_type = key.split('|')
af, ip_type = af_type.lower().split('_')
syslog.syslog(syslog.LOG_INFO, 'Set address family for neighbor {} to {} {}'.format(nbr, af, ip_type))
cmd_prefix = ['configure terminal',
'router bgp {} vrf {}'.format(local_asn, vrf),
'address-family {} {}'.format(af, ip_type)]
if not key_map.run_command(self, table, data, cmd_prefix, nbr):
syslog.syslog(syslog.LOG_ERR, 'failed running BGP neighbor AF config command')
continue
elif table == 'COMMUNITY_SET' or table == 'EXTENDED_COMMUNITY_SET':
comm_set_name = prefix
syslog.syslog(syslog.LOG_INFO, 'Set community set {} for table {}'.format(comm_set_name, table))
cmd_prefix = ['configure terminal']
if not key_map.run_command(self, table, data, cmd_prefix, comm_set_name):
syslog.syslog(syslog.LOG_ERR, 'failed running BGP community config command')
continue
extended = (table != 'COMMUNITY_SET')
comm_set = (self.comm_set_list if not extended else self.extcomm_set_list).setdefault(comm_set_name,
CommunityList(comm_set_name, extended))
if del_table:
del((self.comm_set_list if not extended else self.extcomm_set_list)[comm_set_name])
else:
for dkey, dval in data.items():
if dval.op == CachedDataWithOp.OP_DELETE:
upd_val = None
else:
upd_val = dval.data
comm_set.db_data_to_attr(dkey, upd_val)
elif table == 'PREFIX_SET':
pfx_set_name = prefix
if not del_table:
if pfx_set_name in self.prefix_set_list:
syslog.syslog(syslog.LOG_DEBUG, 'prefix-set %s exists with af %d' %
(pfx_set_name, self.prefix_set_list[pfx_set_name].af))
continue
if 'mode' not in data:
syslog.syslog(syslog.LOG_ERR, 'no mode given for prefix-set %s' % pfx_set_name)
continue
set_mode = data['mode'].data.lower()
self.prefix_set_list[pfx_set_name] = MatchPrefixList(set_mode)
else:
if pfx_set_name in self.prefix_set_list:
del(self.prefix_set_list[pfx_set_name])
for _, dval in data.items():
dval.status = CachedDataWithOp.STAT_SUCC
elif table == 'PREFIX' or table == 'NEIGHBOR_SET' or table == 'NEXTHOP_SET':
pfx_set_name = self.get_prefix_set_name(prefix, table)
if table == 'PREFIX':
if pfx_set_name not in self.prefix_set_list:
syslog.syslog(syslog.LOG_ERR, 'could not find prefix-set %s from cache' % pfx_set_name)
continue
ip_pfx, len_range = key.split('|')
if len_range == 'exact':
len_range = None
pfx_action = data.get('action', None)
if pfx_action is None or pfx_action.op == CachedDataWithOp.OP_NONE:
continue
af = self.prefix_set_list[pfx_set_name].af
if af == socket.AF_INET:
# use table daemons setting
daemons = None
else:
daemons = ['bgpd', 'zebra']
if pfx_action.op == CachedDataWithOp.OP_DELETE or pfx_action.op == CachedDataWithOp.OP_UPDATE:
del_pfx, pfx_idx = self.prefix_set_list[pfx_set_name].get_prefix(ip_pfx, len_range)
if del_pfx is None:
syslog.syslog(syslog.LOG_ERR, 'prefix of {} with range {} not found from prefix-set {}'.\
format(ip_pfx, len_range, pfx_set_name))
continue
command = "vtysh -c 'configure terminal' -c 'no {} prefix-list {} {}'".\
format(('ip' if af == socket.AF_INET else 'ipv6'), pfx_set_name, str(del_pfx))
if not self.__run_command(table, command, daemons):
syslog.syslog(syslog.LOG_ERR, 'failed to delete prefix %s with range %s from set %s' %
(ip_pfx, len_range, pfx_set_name))
continue
del(self.prefix_set_list[pfx_set_name][pfx_idx])
if pfx_action.op == CachedDataWithOp.OP_ADD or pfx_action.op == CachedDataWithOp.OP_UPDATE:
try:
add_pfx = self.prefix_set_list[pfx_set_name].add_prefix(ip_pfx, len_range, pfx_action.data)
except ValueError:
syslog.syslog(syslog.LOG_ERR, 'failed to update prefix-set %s in cache with prefix %s range %s' %
(pfx_set_name, ip_pfx, len_range))
continue
command = "vtysh -c 'configure terminal' -c '{} prefix-list {} {}'".\
format(('ip' if af == socket.AF_INET else 'ipv6'), pfx_set_name, str(add_pfx))
if not self.__run_command(table, command, daemons):
syslog.syslog(syslog.LOG_ERR, 'failed to add prefix %s with range %s to set %s' %
(ip_pfx, len_range, pfx_set_name))
# revert cached update on failure
del_pfx, pfx_idx = self.prefix_set_list[pfx_set_name].get_prefix(ip_pfx, len_range)
if del_pfx is not None:
del(self.prefix_set_list[pfx_set_name][pfx_idx])
continue
else:
if 'address' not in data or data['address'].op == CachedDataWithOp.OP_NONE:
continue
ip_addr_list = data['address'].data
if pfx_set_name in self.prefix_set_list:
af = self.prefix_set_list[pfx_set_name].af
command = "vtysh -c 'configure terminal' -c 'no {} prefix-list {}'".\
format(('ip' if af == socket.AF_INET else 'ipv6'), pfx_set_name)
if not self.__run_command(table, command):
syslog.syslog(syslog.LOG_ERR, 'failed to delete existing prefix-set {}'.format(pfx_set_name))
continue
del(self.prefix_set_list[pfx_set_name])
if not del_table:
prefix_set = MatchPrefixList()
for ip_addr in ip_addr_list:
try:
prefix_set.add_prefix(ip_addr)
except ValueError:
continue
for prefix in prefix_set:
command = "vtysh -c 'configure terminal' -c '{} prefix-list {} {}'".\
format(('ip' if prefix_set.af == socket.AF_INET else 'ipv6'), pfx_set_name, str(prefix))
if not self.__run_command(table, command):
syslog.syslog(syslog.LOG_ERR, 'failed to delete existing prefix-set {}'.format(pfx_set_name))
continue
self.prefix_set_list[pfx_set_name] = prefix_set
for _, dval in data.items():
dval.status = CachedDataWithOp.STAT_SUCC
elif table == 'AS_PATH_SET':
as_set_name = prefix
syslog.syslog(syslog.LOG_INFO, 'Set AS path set {} for table {}'.format(as_set_name, table))
cmd_prefix = ['configure terminal']
if not key_map.run_command(self, table, data, cmd_prefix, as_set_name):
syslog.syslog(syslog.LOG_ERR, 'failed running BGP AS path set config command')
continue
as_set_data = data.get('as_path_set_member', None)
if as_set_data is not None and (as_set_data.op == CachedDataWithOp.OP_DELETE or len(as_set_data.data) == 0):
del_table = True
if del_table:
self.as_path_set_list.pop(as_set_name, None)
elif as_set_data is not None:
self.as_path_set_list[as_set_name] = as_set_data.data[:]
elif table == 'TAG_SET':
tag_set_name = prefix
if not del_table and 'tag_value' not in data:
continue
tag_set_data = data.get('tag_value', None)
if tag_set_data is not None and (tag_set_data.op == CachedDataWithOp.OP_DELETE or len(tag_set_data.data) == 0):
del_table = True
if not del_table:
self.tag_set_list[tag_set_name] = set(tag_set_data.data)
else:
self.tag_set_list.pop(tag_set_name, None)
for _, dval in data.items():
dval.status = CachedDataWithOp.STAT_SUCC
elif table == 'BGP_GLOBALS_EVPN_VNI':
af_type, vni = key.split('|')
af, ip_type = af_type.lower().split('_')
#this is to temporarily make table cache key accessible to key_map handler function
self.tmp_cache_key = 'BGP_GLOBALS_EVPN_VNI&&{}|{}|{}'.format(vrf, af_type, vni)
syslog.syslog(syslog.LOG_INFO, 'Set address family for VNI {} to {} {} cache-key to {}'.format(vni, af, ip_type, self.tmp_cache_key))
cmd_prefix = ['configure terminal',
'router bgp {} vrf {}'.format(local_asn, vrf),
'address-family {} {}'.format(af, ip_type),
'vni {}'.format(vni)]
if not key_map.run_command(self, table, data, cmd_prefix):
syslog.syslog(syslog.LOG_ERR, 'failed running BGP L2VPN_EVPN VNI config command')
continue
self.tmp_cache_key = ''
if del_table:
cmd = "vtysh -c 'configure terminal'"
cmd += " -c 'router bgp {} vrf {}'".format(local_asn, vrf)
cmd += " -c 'address-family {} {}'".format(af, ip_type)
cmd += " -c 'no vni {}'".format(vni)
if not self.__run_command(table, cmd):
syslog.syslog(syslog.LOG_ERR, 'failed running BGP L2VPN_EVPN VNI unconfig command')
continue
else:
if not data:
cmd = "vtysh -c 'configure terminal'"
cmd += " -c 'router bgp {} vrf {}'".format(local_asn, vrf)
cmd += " -c 'address-family {} {}'".format(af, ip_type)
cmd += " -c 'vni {}'".format(vni)
if not self.__run_command(table, cmd):
syslog.syslog(syslog.LOG_ERR, 'failed running BGP L2VPN_EVPN VNI config command')
continue
elif table == 'BGP_GLOBALS_EVPN_RT':
af_type, rt = key.split('|')
af, ip_type = af_type.lower().split('_')
nostr = "no " if del_table else ""
syslog.syslog(syslog.LOG_INFO, 'Set address family for RT {} to {} {}'.format(rt, af, ip_type))
cmd = "vtysh -c 'configure terminal'"
cmd += " -c 'router bgp {} vrf {}'".format(local_asn, vrf)
cmd += " -c 'address-family {} {}'".format(af, ip_type)
cmd += " -c '{}route-target {} {}'".format(nostr,data['route-target-type'].data, rt)
cache_tbl_key = 'BGP_GLOBALS_EVPN_RT&&{}|L2VPN_EVPN|{}'.format(vrf, rt)
if not del_table and cache_tbl_key in self.table_data_cache.keys():
new_rttype = data['route-target-type'].data
cache_tbl_data = self.table_data_cache[cache_tbl_key]
if 'route-target-type' in cache_tbl_data:
old_rttype = cache_tbl_data['route-target-type']
if new_rttype == "export":
if old_rttype == "import" or old_rttype == "both":
cmd += " -c 'no route-target import {}'".format(rt)
if new_rttype == "import":
if old_rttype == "export" or old_rttype == "both":
cmd += " -c 'no route-target export {}'".format(rt)
if not self.__run_command(table, cmd):
syslog.syslog(syslog.LOG_ERR, 'failed running BGP L2VPN_EVPN RT config command')
continue
else:
data['route-target-type'].status = CachedDataWithOp.STAT_SUCC
elif table == 'BGP_GLOBALS_EVPN_VNI_RT':
af_type, vni, rt = key.split('|')
af, ip_type = af_type.lower().split('_')
nostr = "no " if del_table else ""
syslog.syslog(syslog.LOG_INFO, 'Set address family for VNI {} RT {} to {} {}'.format(vni, rt, af, ip_type))
cmd = "vtysh -c 'configure terminal'"
cmd += " -c 'router bgp {} vrf {}'".format(local_asn, vrf)
cmd += " -c 'address-family {} {}'".format(af, ip_type)
cmd += " -c 'vni {}'".format(vni)
cmd += " -c '{}route-target {} {}'".format(nostr,data['route-target-type'].data, rt)
cache_tbl_key = 'BGP_GLOBALS_EVPN_VNI_RT&&{}|L2VPN_EVPN|{}|{}'.format(vrf, vni, rt)
if not del_table and cache_tbl_key in self.table_data_cache.keys():
new_rttype = data['route-target-type'].data
cache_tbl_data = self.table_data_cache[cache_tbl_key]
if 'route-target-type' in cache_tbl_data:
old_rttype = cache_tbl_data['route-target-type']
if new_rttype == "export":
if old_rttype == "import" or old_rttype == "both":
cmd += " -c 'no route-target import {}'".format(rt)
if new_rttype == "import":
if old_rttype == "export" or old_rttype == "both":
cmd += " -c 'no route-target export {}'".format(rt)
if not self.__run_command(table, cmd):
syslog.syslog(syslog.LOG_ERR, 'failed running BGP L2VPN_EVPN VNI RT config command')
continue
else:
data['route-target-type'].status = CachedDataWithOp.STAT_SUCC
elif table == 'ROUTE_MAP':
map_name = prefix
seq_no = key
if not del_table:
if 'route_operation' in data:
dval = data['route_operation']
if dval.op != CachedDataWithOp.OP_NONE:
enable = (dval.op != CachedDataWithOp.OP_DELETE)
no_arg = CommandArgument(self, enable)
command = "vtysh -c 'configure terminal' -c '{:no-prefix}route-map {} {} {}'".\
format(no_arg, map_name, dval.data, seq_no)
if not self.__run_command(table, command):
syslog.syslog(syslog.LOG_ERR, 'failed to configure route-map {} seq {}'.format(map_name, seq_no))
continue
if dval.op == CachedDataWithOp.OP_DELETE:
self.__delete_route_map(map_name, seq_no, data)
continue
self.route_map.setdefault(map_name, {})[seq_no] = dval.data
for k, v in data.items():
if v.op == CachedDataWithOp.OP_NONE:
v.op = CachedDataWithOp.OP_UPDATE
dval.status = CachedDataWithOp.STAT_SUCC
if map_name not in self.route_map or seq_no not in self.route_map[map_name]:
syslog.syslog(syslog.LOG_ERR, 'route-map {} seq {} not found for update'.format(map_name, seq_no))
continue
cmd_prefix = ['configure terminal',
'route-map {} {} {}'.format(map_name, self.route_map[map_name][seq_no], seq_no)]
if not key_map.run_command(self, table, data, cmd_prefix):
syslog.syslog(syslog.LOG_ERR, 'failed running route-map config command')
continue
else:
if map_name not in self.route_map or seq_no not in self.route_map[map_name]:
syslog.syslog(syslog.LOG_ERR, 'route-map {} seq {} not found for delete'.format(map_name, seq_no))
continue
command = "vtysh -c 'configure terminal' -c 'no route-map {} {} {}'".\
format(map_name, self.route_map[map_name][seq_no], seq_no)
if not self.__run_command(table, command):
syslog.syslog(syslog.LOG_ERR, 'failed running route-map delete command')
continue
self.__delete_route_map(map_name, seq_no, data)
elif table == 'ROUTE_REDISTRIBUTE':
src_proto, dst_proto, af = key.split('|')
if af == 'ipv6' and src_proto == 'ospf3':
src_proto = 'ospf6'
ip_type = 'unicast'
syslog.syslog(syslog.LOG_INFO, 'Set route distribute for src_proto {} dst_proto {} {}'.\
format(src_proto, dst_proto, af, ip_type))
if dst_proto != 'bgp':
syslog.syslog(syslog.LOG_ERR, 'only bgp could be used as dst protocol, but {} was given'.format(dst_proto))
continue
op = CachedDataWithOp.OP_DELETE if del_table else CachedDataWithOp.OP_UPDATE
data['protocol'] = CachedDataWithOp(src_proto, op)
cmd_prefix = ['configure terminal',
'router bgp {} vrf {}'.format(local_asn, vrf),
'address-family {} {}'.format(af, ip_type)]
ret_val = key_map.run_command(self, table, data, cmd_prefix)
del(data['protocol'])
if not ret_val:
syslog.syslog(syslog.LOG_ERR, 'failed running BGP route redistribute config command')
continue
elif table == 'BGP_GLOBALS_AF_AGGREGATE_ADDR' or table == 'BGP_GLOBALS_AF_NETWORK':
af_type, ip_prefix = key.split('|')
af, ip_type = af_type.lower().split('_')
norm_ip_prefix = MatchPrefix.normalize_ip_prefix((socket.AF_INET if af == 'ipv4' else socket.AF_INET6), ip_prefix)
if norm_ip_prefix is None:
syslog.syslog(syslog.LOG_ERR, 'invalid IP prefix format %s for af %s' % (ip_prefix, af))
continue
syslog.syslog(syslog.LOG_INFO, 'Set address family for IP prefix {} to {} {}'.format(norm_ip_prefix, af, ip_type))
op = CachedDataWithOp.OP_DELETE if del_table else CachedDataWithOp.OP_UPDATE
data['ip_prefix'] = CachedDataWithOp(norm_ip_prefix, op)
cmd_prefix = ['configure terminal',
'router bgp {} vrf {}'.format(local_asn, vrf),
'address-family {} {}'.format(af, ip_type)]
ret_val = key_map.run_command(self, table, data, cmd_prefix, vrf, af)
del(data['ip_prefix'])
if not ret_val:
syslog.syslog(syslog.LOG_ERR, 'failed running BGP IP prefix AF config command')
continue
if table == 'BGP_GLOBALS_AF_AGGREGATE_ADDR':
if not del_table:
aggr_obj = AggregateAddr()
for attr in ['as_set', 'summary_only']:
if attr in data and data[attr].op != CachedDataWithOp.OP_DELETE and data[attr].data == 'true':
setattr(aggr_obj, attr, True)
self.af_aggr_list.setdefault(vrf, {})[norm_ip_prefix] = aggr_obj
else:
if vrf in self.af_aggr_list:
self.af_aggr_list[vrf].pop(norm_ip_prefix, None)
elif table == 'BFD_PEER_SINGLE_HOP':
key = prefix + '|' + key
remoteaddr, interface, vrf, localaddr = key.split('|')
if not del_table:
if not 'null' in localaddr:
syslog.syslog(syslog.LOG_INFO, 'Set BFD single hop peer {} {} {} {}'.format(remoteaddr, vrf, interface, localaddr))
suffix_cmd, oper = self.__bfd_handle_delete (data)
if suffix_cmd and oper == CachedDataWithOp.OP_DELETE:
command = "vtysh -c 'configure terminal' -c 'bfd' -c 'peer {} local-address {} vrf {} interface {}' -c '{}'".\
format(remoteaddr, localaddr, vrf, interface, suffix_cmd)
if not self.__run_command(table, command):
syslog.syslog(syslog.LOG_ERR, 'failed to delete single-hop peer {}'.format(key))
continue
else:
cmd_prefix = ['configure terminal',
'bfd',
'peer {} local-address {} vrf {} interface {}'.format(remoteaddr, localaddr, vrf, interface)]
if not key_map.run_command(self, table, data, cmd_prefix):
syslog.syslog(syslog.LOG_ERR, 'failed running BFD single-hop config command')
continue
else:
syslog.syslog(syslog.LOG_INFO, 'Set BFD single hop peer {} {} {}'.format(remoteaddr, vrf, interface))
suffix_cmd, oper = self.__bfd_handle_delete (data)
if suffix_cmd and oper == CachedDataWithOp.OP_DELETE:
command = "vtysh -c 'configure terminal' -c 'bfd' -c 'peer {} vrf {} interface {}' -c '{}'".\
format(remoteaddr, vrf, interface, suffix_cmd)
if not self.__run_command(table, command):
syslog.syslog(syslog.LOG_ERR, 'failed to delete single-hop peer {}'.format(key))
continue
else:
syslog.syslog(syslog.LOG_INFO, 'Set BFD single hop peer {} {} {}'.format(remoteaddr, vrf, interface))
cmd_prefix = ['configure terminal',
'bfd',
'peer {} vrf {} interface {}'.format(remoteaddr, vrf, interface)]
if not key_map.run_command(self, table, data, cmd_prefix):
syslog.syslog(syslog.LOG_ERR, 'failed running BFD single-hop config command')
continue
else:
if 'local-address' in data:
dval = data['local-address']
localaddr = dval.data
syslog.syslog(syslog.LOG_INFO, 'Delete BFD single hop to {} {} {}'.format(remoteaddr, vrf, interface, localaddr))
command = "vtysh -c 'configure terminal' -c 'bfd' -c 'no peer {} local-address {} vrf {} interface {}'".\
format(remoteaddr, localaddr, vrf, interface)
else:
syslog.syslog(syslog.LOG_INFO, 'Delete BFD single hop to {} {} {}'.format(remoteaddr, vrf, interface))
command = "vtysh -c 'configure terminal' -c 'bfd' -c 'no peer {} vrf {} interface {}'".\
format(remoteaddr, vrf, interface)
if not self.__run_command(table, command):
syslog.syslog(syslog.LOG_ERR, 'failed to delete single-hop peer {}'.format(key))
continue
self.__delete_bfd_peer(data)
elif table == 'BFD_PEER_MULTI_HOP':
key = prefix + '|' + key
remoteaddr, interface, vrf, localaddr = key.split('|')
if not del_table:
syslog.syslog(syslog.LOG_INFO, 'Set BFD multi hop to {} {} {} {}'.format(remoteaddr, interface, vrf, localaddr))
suffix_cmd, oper = self.__bfd_handle_delete (data)
if suffix_cmd and oper == CachedDataWithOp.OP_DELETE:
if not 'null' in interface:
command = "vtysh -c 'configure terminal' -c 'bfd' -c 'peer {} local-address {} vrf {} interface {}' -c '{}'".\
format(remoteaddr, localaddr, vrf, interface, suffix_cmd)
else:
command = "vtysh -c 'configure terminal' -c 'bfd' -c 'peer {} local-address {} vrf {}' -c '{}'".\
format(remoteaddr, localaddr, vrf, suffix_cmd)
if not self.__run_command(table, command):
syslog.syslog(syslog.LOG_ERR, 'failed to delete single-hop peer {}'.format(key))
continue
else:
if not 'null' in interface:
cmd_prefix = ['configure terminal',
'bfd',
'peer {} vrf {} multihop local-address {} interface {}'.format(remoteaddr, vrf, localaddr, interface)]
else:
cmd_prefix = ['configure terminal',
'bfd',
'peer {} vrf {} multihop local-address {}'.format(remoteaddr, vrf, localaddr)]
if not key_map.run_command(self, table, data, cmd_prefix):
syslog.syslog(syslog.LOG_ERR, 'failed running BFD multi-hop config command')
continue
else:
syslog.syslog(syslog.LOG_INFO, 'Delete BFD multi hop to {} {} {} {}'.format(remoteaddr, vrf, localaddr, interface))
if not 'null' in interface:
command = "vtysh -c 'configure terminal' -c 'bfd' -c 'no peer {} vrf {} multihop local-address {} interface {}'".\
format(remoteaddr, vrf, localaddr, interface)
else:
command = "vtysh -c 'configure terminal' -c 'bfd' -c 'no peer {} vrf {} multihop local-address {}'".\
format(remoteaddr, vrf, localaddr)
if not self.__run_command(table, command):
syslog.syslog(syslog.LOG_ERR, 'failed to delete multihop peer {}'.format(key))
continue
self.__delete_bfd_peer(data)
elif table == 'IP_SLA':
sla_id = prefix
icmp_config = False
tcp_config = False
cmd_prefix = ['configure terminal']
ipsla_table = self.config_db.get_table('IP_SLA')
syslog.syslog(syslog.LOG_INFO, 'Config ip sla data {}'.format(data))
found_in_configdb = False
for key, entry in ipsla_table.items():
ipsla_id = key
if sla_id == ipsla_id:
found_in_configdb = True
break
syslog.syslog(syslog.LOG_INFO, 'Config ip sla found_in_configdb {}'.format(found_in_configdb))
if 'icmp_source_interface' in data or 'icmp_source_ip' in data or 'icmp_size' in data or 'icmp_dst_ip' in data or 'icmp_vrf' in data or 'icmp_ttl' in data or 'icmp_tos' in data:
cmd_prefix = ['configure terminal','ip sla {}'.format(sla_id)]
icmp_config = True
for key, entry in ipsla_table.items():
ipsla_id = key
if sla_id == ipsla_id:
if 'icmp_dst_ip' in entry:
icmp_cmd = ("icmp", "echo")
icmp_cmd_str = "-".join(icmp_cmd)
icmp_cmd_mode = icmp_cmd_str + " " + entry['icmp_dst_ip']
syslog.syslog(syslog.LOG_INFO, 'Data: icmp_cmd_str %s icmp_cmd_mode %s' % (icmp_cmd_str, icmp_cmd_mode))
cmd_prefix = ['configure terminal','ip sla {}'.format(sla_id), icmp_cmd_mode]
chk_icmp_attrs = ['icmp_source_interface', 'icmp_source_ip', 'icmp_size', 'icmp_vrf', 'icmp_tos', 'icmp_ttl']
chk_icmp_attrs_dict = {'icmp_source_interface':'source-interface ', 'icmp_source_ip':'source-address ', 'icmp_size':'request-data-size ', 'icmp_vrf':'source-vrf ', 'icmp_tos':'tos ', 'icmp_ttl':'ttl '}
for attr in chk_icmp_attrs:
if attr in data and data[attr].op != CachedDataWithOp.OP_DELETE:
command = "vtysh -c 'configure terminal' -c 'ip sla {}' -c '{}' -c '{} {}'".\
format(sla_id, icmp_cmd_mode, chk_icmp_attrs_dict[attr], data[attr].data)
syslog.syslog(syslog.LOG_INFO, 'Execute Icmp Cmd {}'.format(command))
if not self.__run_command(table, command):
syslog.syslog(syslog.LOG_ERR, 'failed to add icmp config for ip sla {}'.format(sla_id))
continue
syslog.syslog(syslog.LOG_INFO, 'Done with Icmp {}'.format(sla_id))
if not key_map.run_command(self, table, data, cmd_prefix, sla_id):
syslog.syslog(syslog.LOG_ERR, 'failed running ip sla command')
continue
if 'tcp_source_interface' in data or 'tcp_source_port' in data or 'tcp_source_ip' in data or 'tcp_dst_ip' in data or 'tcp_dst_port' in data or 'tcp_vrf' in data or 'tcp_ttl' in data or 'tcp_tos' in data:
cmd_prefix = ['configure terminal','ip sla {}'.format(sla_id)]
tcp_config = True
for key, entry in ipsla_table.items():
ipsla_id = key
if sla_id == ipsla_id:
if 'tcp_dst_ip' in entry and 'tcp_dst_port' in entry:
tcp_cmd = ("tcp", "connect")
tcp_cmd_str = "-".join(tcp_cmd)
tcp_cmd_mode = tcp_cmd_str + " " + entry['tcp_dst_ip'] + " port " + entry['tcp_dst_port']
syslog.syslog(syslog.LOG_INFO, 'Init Config DB Data: tcp_cmd_str %s tcp_cmd_mode %s' % (tcp_cmd_str, tcp_cmd_mode))
cmd_prefix = ['configure terminal','ip sla {}'.format(sla_id), tcp_cmd_mode]
chk_tcp_attrs = ['tcp_source_interface', 'tcp_source_ip', 'tcp_source_port', 'tcp_vrf', 'tcp_tos', 'tcp_ttl']
chk_tcp_attrs_dict = {'tcp_source_interface':'source-interface ', 'tcp_source_ip':'source-address ', 'tcp_source_port':'source-port ', 'tcp_vrf':'source-vrf ', 'tcp_tos':'tos ', 'tcp_ttl':'ttl '}
for attr in chk_tcp_attrs:
if attr in data and data[attr].op != CachedDataWithOp.OP_DELETE:
command = "vtysh -c 'configure terminal' -c 'ip sla {}' -c '{}' -c '{} {}'".\
format(sla_id, tcp_cmd_mode, chk_tcp_attrs_dict[attr], data[attr].data)
syslog.syslog(syslog.LOG_INFO, 'Execute Tcp Cmd {}'.format(command))
if not self.__run_command(table, command):
syslog.syslog(syslog.LOG_ERR, 'failed to add Tcp config for ip sla {}'.format(sla_id))
continue
syslog.syslog(syslog.LOG_INFO, 'Done with Tcp {}'.format(sla_id))
if not key_map.run_command(self, table, data, cmd_prefix, sla_id):
syslog.syslog(syslog.LOG_ERR, 'failed running ip sla command')
continue
if 'frequency' in data or 'threshold' in data or 'timeout' in data:
syslog.syslog(syslog.LOG_INFO, 'ip sla mode Configure freq/thresh/timeout for sla {}'.format(sla_id))
cmd_prefix = ['configure terminal','ip sla {}'.format(sla_id)]
if not key_map.run_command(self, table, data, cmd_prefix, sla_id):
syslog.syslog(syslog.LOG_ERR, 'failed running ip sla command')
continue
elif icmp_config == False or tcp_config == False:
syslog.syslog(syslog.LOG_INFO, 'Basic mode Configure for ip sla {}'.format(sla_id))
cmd_prefix = ['configure terminal']
# Always delete ip sla if it is not found in configdb
if not found_in_configdb:
command = "vtysh -c 'configure terminal' -c 'no ip sla {}'".format(sla_id)
syslog.syslog(syslog.LOG_ERR, 'Entry deleted in ip sla config db')
if not self.__run_command(table, command):
syslog.syslog(syslog.LOG_ERR, 'failed to delete router ip sla {}'.format(sla_id))
continue
elif not key_map.run_command(self, table, data, cmd_prefix, sla_id):
syslog.syslog(syslog.LOG_ERR, 'failed running ip sla command')
continue
elif table == 'OSPFV2_ROUTER':
vrf = prefix
if not del_table:
syslog.syslog(syslog.LOG_INFO, 'Create router ospf vrf {}'.format(vrf))
cmd_prefix = ['configure terminal',
'router ospf vrf {}'.format(vrf)]
if not key_map.run_command(self, table, data, cmd_prefix):
syslog.syslog(syslog.LOG_ERR, 'failed running ospf config command')
continue
else:
command = "vtysh -c 'configure terminal' -c 'no router ospf vrf {}'".format(vrf)
if not self.__run_command(table, command):
syslog.syslog(syslog.LOG_ERR, 'failed to delete router ospf vrf {}'.format(vrf))
continue
else:
self.__ospf_delete(data)
elif table == 'OSPFV2_ROUTER_AREA':
vrf = prefix
syslog.syslog(syslog.LOG_INFO, 'Create router ospf vrf {}'.format(vrf))
cmd_prefix = ['configure terminal',
'router ospf vrf {}'.format(vrf)]
if not key_map.run_command(self, table, data, cmd_prefix, key):
syslog.syslog(syslog.LOG_ERR, 'failed running ospf config command')
continue
elif table == 'OSPFV2_ROUTER_AREA_VIRTUAL_LINK':
vrf = prefix
keyvals = key.split('|')
area = keyvals[0]
vlinkid = keyvals[1]
syslog.syslog(syslog.LOG_INFO, 'Create router ospf vrf {}, Vlink: {}, tableop {}'.format(vrf, data, del_table))
if data == {}:
command = "vtysh -c 'configure terminal' -c 'router ospf vrf {}' -c 'no area {} virtual-link {}'".\
format(vrf, area, vlinkid)
if not self.__run_command(table, command):
syslog.syslog(syslog.LOG_ERR, 'failed to delete vlink {} {}'.format(area, vlinkid))
continue
else:
self.__ospf_delete(data)
else:
cmd_prefix = ['configure terminal',
'router ospf vrf {}'.format(vrf)]
if not key_map.run_command(self, table, data, cmd_prefix, area, vlinkid):
syslog.syslog(syslog.LOG_ERR, 'failed running ospf config command')
continue
if del_table:
command = "vtysh -c 'configure terminal' -c 'router ospf vrf {}' -c 'no area {} virtual-link {}'".\
format(vrf, area, vlinkid)
if not self.__run_command(table, command):
syslog.syslog(syslog.LOG_ERR, 'failed to delete vlink {} {}'.format(area, vlinkid))
continue
else:
self.__ospf_delete(data)
elif table == 'OSPFV2_ROUTER_AREA_NETWORK':
vrf = prefix
syslog.syslog(syslog.LOG_INFO, 'Create router ospf vrf {}'.format(vrf))
keyvals = key.split('|')
area = keyvals[0]
network = keyvals[1]
if not del_table:
command = "vtysh -c 'configure terminal' -c 'router ospf vrf {}' -c 'network {} area {}'".\
format(vrf, network, area)
if not self.__run_command(table, command):
syslog.syslog(syslog.LOG_ERR, 'failed to create network {} {}'.format(area, network))
continue
else:
command = "vtysh -c 'configure terminal' -c 'router ospf vrf {}' -c 'no network {} area {}'".\
format(vrf, network, area)
if not self.__run_command(table, command):
syslog.syslog(syslog.LOG_ERR, 'failed to delete network {} {}'.format(area, network))
continue
else:
self.__ospf_delete(data)
elif table == 'OSPFV2_ROUTER_AREA_POLICY_ADDRESS_RANGE':
vrf = prefix
keyvals = key.split('|')
area = keyvals[0]
range = keyvals[1]
syslog.syslog(syslog.LOG_INFO, 'Create router ospf vrf {}'.format(vrf))
if data == {}:
if not del_table:
command = "vtysh -c 'configure terminal' -c 'router ospf vrf {}' -c 'area {} range {}'".\
format(vrf, area, range)
if not self.__run_command(table, command):
syslog.syslog(syslog.LOG_ERR, 'failed to create range {} {}'.format(area, range))
continue
else:
command = "vtysh -c 'configure terminal' -c 'router ospf vrf {}' -c 'no area {} range {}'".\
format(vrf, area, range)
if not self.__run_command(table, command):
syslog.syslog(syslog.LOG_ERR, 'failed to delete range {} {}'.format(area, range))
continue
else:
self.__ospf_delete(data)
else:
cmd_prefix = ['configure terminal',
'router ospf vrf {}'.format(vrf)]
if not key_map.run_command(self, table, data, cmd_prefix, area, range):
syslog.syslog(syslog.LOG_ERR, 'failed running ospf config command')
continue
elif table == 'OSPFV2_ROUTER_DISTRIBUTE_ROUTE':
vrf = prefix
keyvals = key.split('|')
protocol = keyvals[0]
direction = keyvals[1]
if (protocol == "DIRECTLY_CONNECTED"):
protocol = "CONNECTED"
syslog.syslog(syslog.LOG_INFO, 'Create redistribute-list {} {}'.format(protocol, direction))
cmd_suffix = ""
del_cmd_suffix = ""
cmd_oper = ""
rmapcmd = ""
metriccmd = ""
metrictypecmd = ""
alwayscmd = ""
acclistname = ""
rmapoper = ""
metricoper = ""
metrictypeoper = ""
alwaysoper = ""
acclistoper = ""
if 'route-map' in data:
dval = data['route-map']
rmapoper = dval.op
rmapcmd = " route-map {}".format(dval.data)
if 'access-list' in data:
dval = data['access-list']
acclistoper = dval.op
acclistname = dval.data
if 'metric' in data:
dval = data['metric']
metricoper = dval.op
metriccmd = " metric {}".format(dval.data)
if 'metric-type' in data:
dval = data['metric-type']
metrictypeoper = dval.op
if dval.data == "TYPE_1":
metrictypecmd = " metric-type 1"
else:
metrictypecmd = " metric-type 2"
if 'always' in data:
dval = data['always']
alwaysoper = dval.op
alwayscmd = " always"
if not del_table:
if ((rmapoper == CachedDataWithOp.OP_DELETE) or
(metricoper == CachedDataWithOp.OP_DELETE) or
(metrictypeoper == CachedDataWithOp.OP_DELETE) or
(alwaysoper == CachedDataWithOp.OP_DELETE) or
(acclistoper == CachedDataWithOp.OP_DELETE)):
cmd_oper = "no"
if (alwaysoper == CachedDataWithOp.OP_DELETE):
del_cmd_suffix = alwayscmd
if (rmapoper == CachedDataWithOp.OP_DELETE):
del_cmd_suffix = rmapcmd
if (metricoper == CachedDataWithOp.OP_DELETE):
del_cmd_suffix = metriccmd
if (metrictypeoper == CachedDataWithOp.OP_DELETE):
del_cmd_suffix = metrictypecmd
if (direction == "EXPORT"):
if (cmd_oper != "no"):
cmd_suffix = "distribute-list {} out {}".format(acclistname, protocol.lower())
else:
cmd_suffix = "no distribute-list {} out {}".format(acclistname, protocol.lower())
command = "vtysh -c 'configure terminal' -c 'router ospf vrf {}' -c '{}'".\
format(vrf, cmd_suffix)
if not self.__run_command(table, command):
syslog.syslog(syslog.LOG_ERR, 'failed to create distribute-list {} {}'.format(protocol, direction))
continue
else:
self.__ospf_apply_config(data, rmapoper, metricoper, metrictypeoper, alwaysoper, acclistoper)
elif (direction == "IMPORT"):
if (cmd_oper != "no"):
if (protocol == "DEFAULT_ROUTE"):
cmd_suffix = cmd_suffix + "default-information originate" + alwayscmd + rmapcmd + metriccmd + metrictypecmd
else:
cmd_suffix = cmd_suffix + "redistribute {}".format(protocol.lower()) + rmapcmd + metriccmd + metrictypecmd
else:
if (protocol == "DEFAULT_ROUTE"):
cmd_suffix = "no default-information originate" + del_cmd_suffix
else:
cmd_suffix = "no redistribute {}".format(protocol.lower()) + del_cmd_suffix
command = "vtysh -c 'configure terminal' -c 'router ospf vrf {}' -c '{}'".\
format(vrf, cmd_suffix)
if not self.__run_command(table, command):
syslog.syslog(syslog.LOG_ERR, 'failed to create default-info/redistribute {} {}'.format(protocol, direction))
continue
else:
self.__ospf_apply_config(data, rmapoper, metricoper, metrictypeoper, alwaysoper, acclistoper)
else:
if (direction == "IMPORT"):
command = ""
if (protocol == "DEFAULT_ROUTE"):
command = "vtysh -c 'configure terminal' -c 'router ospf vrf {}' -c 'no default-information originate'".\
format(vrf)
else:
command = "vtysh -c 'configure terminal' -c 'router ospf vrf {}' -c 'no redistribute {}'".\
format(vrf, protocol.lower())
if (command != ""):
if not self.__run_command(table, command):
syslog.syslog(syslog.LOG_ERR, 'failed to delete default-info/redistribute {}'.format(protocol.lower()))
continue
else:
self.__ospf_delete(data)
else:
if (acclistname != ""):
command = "vtysh -c 'configure terminal' -c 'router ospf vrf {}' -c 'no distribute-list {} out {}'".\
format(vrf, acclistname, protocol.lower())
if not self.__run_command(table, command):
syslog.syslog(syslog.LOG_ERR, 'failed to delete distribute-list {} {}'.format(protocol, direction))
continue
self.__ospf_delete(data)
elif table == 'OSPFV2_INTERFACE':
key = prefix + '|' + key
if_name, if_addr = key.split('|')
vrf = ""
if 'vrf_name' in data :
vrf = 'vrf {}'.format(data['vrf_name'].data)
cmd_prefix = ['configure terminal',
'interface {} {}'.format(if_name, vrf) ]
if del_table and len(data) == 0:
syslog.syslog(syslog.LOG_INFO, 'Delete table {} {} data {}'.format(key, vrf, data))
cmd_data = {}
cache_tbl_key = 'OSPFV2_INTERFACE&&{}|{}'.format(if_name, if_addr)
syslog.syslog(syslog.LOG_INFO, 'Row delete key {}'.format(cache_tbl_key))
if cache_tbl_key in self.table_data_cache.keys():
cache_tbl_data = self.table_data_cache[cache_tbl_key]
syslog.syslog(syslog.LOG_INFO, 'Row delete cached data {} '.format(cache_tbl_data))
for key, data in cache_tbl_data.items() :
cached_op_data = CachedDataWithOp(data, CachedDataWithOp.OP_DELETE)
cmd_data.update({ key : cached_op_data } )
syslog.syslog(syslog.LOG_INFO, 'Row delete cmd data {} '.format(cmd_data))
if len(cmd_data) :
if not key_map.run_command(self, table, cmd_data, cmd_prefix, if_name, if_addr):
syslog.syslog(syslog.LOG_INFO, 'failed running interface no ip ospf config command')
self.__apply_config_delete_success(cmd_data)
continue
else :
self.__apply_config_delete_success(cmd_data)
else :
syslog.syslog(syslog.LOG_INFO, 'Create/update ospf {} interface {} in {}'.format(key, if_name, vrf))
#Work arround for router area config fail, update area every time
if 'area-id' in data.keys():
dval = data['area-id']
if dval.op == CachedDataWithOp.OP_NONE :
dval.op = CachedDataWithOp.OP_ADD
if not key_map.run_command(self, table, data, cmd_prefix, if_name, if_addr):
syslog.syslog(syslog.LOG_ERR, 'failed running interface ip ospf config command')
if 'area-id' in data.keys():
dval = data['area-id']
if dval.op == CachedDataWithOp.OP_DELETE:
#Work arround for router area config delete fail
self.__apply_config_op_success(data, {'area-id': dval.op } )
syslog.syslog(syslog.LOG_INFO, 'area-id delete enforced')
continue
else :
self.__apply_config_op_success(data)
elif table == 'OSPFV2_ROUTER_PASSIVE_INTERFACE':
syslog.syslog(syslog.LOG_INFO, 'Create passive interface')
vrf = prefix
keyvals = key.split('|')
if_name = keyvals[0]
if_addr = keyvals[1]
syslog.syslog(syslog.LOG_INFO, 'Create passive interface vrf {}'.format(vrf))
if (if_addr == "0.0.0.0"):
if_addr = ""
if data == {}:
if not del_table:
command = "vtysh -c 'configure terminal' -c 'router ospf vrf {}' -c 'passive-interface {} {}'".\
format(vrf, if_name, if_addr)
if not self.__run_command(table, command):
syslog.syslog(syslog.LOG_ERR, 'failed to create passive interface {} {}'.format(if_name, if_addr))
continue
else:
command = "vtysh -c 'configure terminal' -c 'router ospf vrf {}' -c 'no passive-interface {} {}'".\
format(vrf, if_name, if_addr)
if not self.__run_command(table, command):
syslog.syslog(syslog.LOG_ERR, 'failed to delete passive interface {} {}'.format(if_name, if_addr))
continue
elif table == 'STATIC_ROUTE':
vrf = prefix
syslog.syslog(syslog.LOG_INFO, 'Set static IP route for vrf {} prefix {}'.format(vrf, key))
op = CachedDataWithOp.OP_DELETE if del_table else CachedDataWithOp.OP_UPDATE
data['ip_prefix'] = CachedDataWithOp(key, op)
cmd_prefix = ['configure terminal', 'vrf {}'.format(vrf)]
ret_val = key_map.run_command(self, table, data, cmd_prefix, vrf)
del(data['ip_prefix'])
if not ret_val:
syslog.syslog(syslog.LOG_ERR, 'failed running static route config command')
continue
self.static_route_list.setdefault(vrf, {})[key] = self.upd_nh_set
elif table == 'PIM_INTERFACE':
vrf = prefix
af, if_name = key.split('|')
syslog.syslog(syslog.LOG_INFO,
'PIM interface update for vrf {}, af: {}, interface {}'.format(vrf, af, if_name))
cmd_prefix = ['configure terminal',
'interface {}'.format(if_name)]
syslog.syslog(syslog.LOG_INFO,
'Create/update PIM interface: key {} interface {} in {}'.format(key, if_name, vrf))
# If sparse-mode has been disabled, clear other interface
# entries in cache so that they will be re-programmed in FRR
# on re-enabling of sparse-mode.
if 'mode' in data:
modeval = data['mode']
modeval_pim_mode = modeval.data
modeval_op = modeval.op
if (modeval_op == CachedDataWithOp.OP_DELETE):
syslog.syslog(syslog.LOG_INFO,
"Flushing PIM interface cache for deletion "
"of PIM sparse-mode")
for dkey, dval in data.items():
dval.status = CachedDataWithOp.STAT_SUCC
dval.op = CachedDataWithOp.OP_DELETE
# Only send the VTYSH command to FRR if the PIM interface mode
# is present in the update.
if not key_map.run_command(self, table, data, cmd_prefix):
syslog.syslog(syslog.LOG_ERR, 'failed running PIM config command')
continue
elif table == 'PIM_GLOBALS':
vrf = prefix
af = key.split('|')
syslog.syslog(syslog.LOG_INFO,
'PIM global update for vrf {}, af: {}'.format(vrf, af))
cmd_prefix = ['configure terminal',
'vrf {}'.format(vrf)]
syslog.syslog(syslog.LOG_INFO,
'Create/update PIM global {} af {} in {}'.format(key, af, vrf))
# if not key_map.run_command(self, table, data, cmd_prefix, vrf, af):
if not key_map.run_command(self, table, data, cmd_prefix):
syslog.syslog(syslog.LOG_ERR, 'failed running PIM config command')
continue
elif table == 'IGMP_INTERFACE':
ifname = prefix
syslog.syslog(syslog.LOG_INFO, 'IGMP Interface MCast Grp ifname {} prefix {}'.format(ifname, key))
keyvals = key.split('|')
mcast_grp = keyvals[0]
source_ip = keyvals[1]
syslog.syslog(syslog.LOG_INFO, 'Configure ip igmp join interface {}, mcast_grp {}, source_ip {}'.format(ifname, mcast_grp, source_ip))
cmd_prefix = ['configure terminal',
'interface {}'.format(ifname)]
if not key_map.run_command(self, table, data, cmd_prefix, mcast_grp, source_ip):
syslog.syslog(syslog.LOG_ERR, 'failed running ip igmp join config command')
continue
elif table == 'IGMP_INTERFACE_QUERY':
ifname = prefix
syslog.syslog(syslog.LOG_INFO, 'IGMP Interface {} Config prefix {}'.format(ifname, key))
cmd_prefix = ['configure terminal',
'interface {}'.format(ifname)]
if not key_map.run_command(self, table, data, cmd_prefix):
syslog.syslog(syslog.LOG_ERR, 'failed running ip igmp interface config command')
continue