@@ -101,12 +101,14 @@ def __init__(self, common_objs, db_name, table_name, peer_type, check_neig_meta)
101101 base_template = "bgpd/templates/" + self .constants ["bgp" ]["peers" ][peer_type ]["template_dir" ] + "/"
102102 self .templates = {
103103 "add" : self .fabric .from_file (base_template + "instance.conf.j2" ),
104- "update" : self .fabric .from_file (base_template + "instance_update.conf.j2" ),
105104 "delete" : self .fabric .from_string ('no neighbor {{ neighbor_addr }}' ),
106105 "shutdown" : self .fabric .from_string ('neighbor {{ neighbor_addr }} shutdown' ),
107106 "no shutdown" : self .fabric .from_string ('no neighbor {{ neighbor_addr }} shutdown' ),
108107 }
109108
109+ if (os .path .exists (self .fabric .env .loader .searchpath [0 ] + "/" + base_template + "update.conf.j2" )):
110+ self .templates ["update" ] = self .fabric .from_file (base_template + "update.conf.j2" )
111+
110112 deps = [
111113 ("CONFIG_DB" , swsscommon .CFG_DEVICE_METADATA_TABLE_NAME , "localhost/bgp_asn" ),
112114 ("CONFIG_DB" , swsscommon .CFG_DEVICE_METADATA_TABLE_NAME , "localhost/type" ),
@@ -229,10 +231,46 @@ def add_peer(self, vrf, nbr, data):
229231 self .apply_op (cmd , vrf )
230232 key = (vrf , nbr )
231233 self .peers .add (key )
234+ self .update_state_db (vrf , nbr , data , "SET" )
232235 log_info ("Peer '(%s|%s)' has been scheduled to be added with attributes '%s'" % print_data )
233236
234237 return True
235238
239+ def update_state_db (self , vrf , nbr , data , op ):
240+ """
241+ Update the database with the new data
242+ :param vrf: vrf name. Name is equal "default" for the global vrf
243+ :param nbr: neighbor ip address (name for dynamic peer type)
244+ :param data: associated data (will be empty for deletion case)
245+ :param op: operation type. It can be "SET" or "DEL"
246+ :return: True if this adding was successful, False otherwise
247+ """
248+ if (vrf == "default" ):
249+ key = nbr
250+ else :
251+ key = vrf + "|" + nbr
252+ # Update the peer in the STATE_DB table
253+ try :
254+ state_db = swsscommon .DBConnector ("STATE_DB" , 0 )
255+ state_peer_table = swsscommon .Table (state_db , swsscommon .STATE_BGP_PEER_CONFIGURED_TABLE_NAME )
256+ if (op == "SET" ):
257+ state_peer_table .set (key , list (sorted (data .items ())))
258+ log_info ("Peer '(%s)' has been added to BGP_PEER_CONFIGURED_TABLE with attributes '%s'" % (key , data ))
259+ elif (op == "DEL" ):
260+ (status , fvs ) = state_peer_table .get (key )
261+ if status == True :
262+ state_peer_table .delete (key )
263+ log_info ("Peer '(%s)' has been deleted from BGP_PEER_CONFIGURED_TABLE" % (key ))
264+ else :
265+ log_warn ("Peer '(%s)' not found in BGP_PEER_CONFIGURED_TABLE" % (key ))
266+ else :
267+ log_err ("Update state DB called for Peer '(%s)' with unkown operation '%s'" % (key , op ))
268+ return False
269+ return True
270+ except Exception as e :
271+ log_err ("Update of state db failed for peer '(%s)' with error: %s" % (key , str (e )))
272+ return False
273+
236274 def update_peer (self , vrf , nbr , data ):
237275 """
238276 Update a peer. This is used when the peer is already in the FRR
@@ -244,11 +282,8 @@ def update_peer(self, vrf, nbr, data):
244282 """
245283 if "admin_status" in data :
246284 self .change_admin_status (vrf , nbr , data )
247- elif "ip_range" in data and self .peer_type == 'dynamic' :
248- if (os .path .exists (self .templates ["update" ])):
249- self .change_ip_range (vrf , nbr , data )
250- else :
251- log_err ("Peer '(%s|%s)': Can't update the peer. Template 'update' doesn't exist" % (vrf , nbr ))
285+ elif "update" in self .templates and "ip_range" in data and self .peer_type == 'dynamic' :
286+ self .change_ip_range (vrf , nbr , data )
252287 else :
253288 log_err ("Peer '(%s|%s)': Can't update the peer. Only 'admin_status' attribute is supported" % (vrf , nbr ))
254289
@@ -263,14 +298,14 @@ def change_admin_status(self, vrf, nbr, data):
263298 :return: True if this adding was successful, False otherwise
264299 """
265300 if data ['admin_status' ] == 'up' :
266- self .apply_admin_status (vrf , nbr , "no shutdown" , "up" )
301+ self .apply_admin_status (vrf , nbr , "no shutdown" , "up" , data )
267302 elif data ['admin_status' ] == 'down' :
268- self .apply_admin_status (vrf , nbr , "shutdown" , "down" )
303+ self .apply_admin_status (vrf , nbr , "shutdown" , "down" , data )
269304 else :
270305 print_data = vrf , nbr , data ['admin_status' ]
271306 log_err ("Peer '%s|%s': Can't update the peer. It has wrong attribute value attr['admin_status'] = '%s'" % print_data )
272307
273- def apply_admin_status (self , vrf , nbr , template_name , admin_state ):
308+ def apply_admin_status (self , vrf , nbr , template_name , admin_state , data ):
274309 """
275310 Render admin state template and apply the command to the FRR
276311 :param vrf: vrf name. Name is equal "default" for the global vrf
@@ -282,6 +317,7 @@ def apply_admin_status(self, vrf, nbr, template_name, admin_state):
282317 print_data = vrf , nbr , admin_state
283318 ret_code = self .apply_op (self .templates [template_name ].render (neighbor_addr = nbr ), vrf )
284319 if ret_code :
320+ self .update_state_db (vrf , nbr , data , "SET" )
285321 log_info ("Peer '%s|%s' admin state is set to '%s'" % print_data )
286322 else :
287323 log_err ("Can't set peer '%s|%s' admin state to '%s'." % print_data )
@@ -321,7 +357,7 @@ def get_existing_ip_ranges(self, vrf, nbr):
321357 Get existing ip range of a peer
322358 :param vrf: vrf name. Name is equal "default" for the global vrf
323359 :param nbr: neighbor ip address (name for dynamic peer type)
324- :return: existing ip range of a peer
360+ :return: existing ipv4 and ipv6 ranges of a peer if they exist.
325361 """
326362 ipv4_ranges = []
327363 ipv6_ranges = []
@@ -334,10 +370,10 @@ def get_existing_ip_ranges(self, vrf, nbr):
334370 if ret_code == 0 :
335371 js_bgp = json .loads (out )
336372 if nbr in js_bgp and 'dynamicRanges' in js_bgp [nbr ] and 'IPv4' in js_bgp [nbr ]['dynamicRanges' ] and 'ranges' in js_bgp [nbr ]['dynamicRanges' ]['IPv4' ]:
337- ipv4_ranges = js_bgp [nbr ]['dynamicRanges' ]['IPv4' ]['ranges' ]
373+ ipv4_ranges = js_bgp [nbr ]['dynamicRanges' ]['IPv4' ]['ranges' ]
338374 log_info ("Peer '(%s|%s)' already has ipV4 range: %s" % (vrf , nbr , ipv4_ranges ))
339375 if nbr in js_bgp and 'dynamicRanges' in js_bgp [nbr ] and 'IPv6' in js_bgp [nbr ]['dynamicRanges' ] and 'ranges' in js_bgp [nbr ]['dynamicRanges' ]['IPv6' ]:
340- ipv6_ranges = js_bgp [nbr ]['dynamicRanges' ]['IPv6' ]['ranges' ]
376+ ipv6_ranges = js_bgp [nbr ]['dynamicRanges' ]['IPv6' ]['ranges' ]
341377 log_info ("Peer '(%s|%s)' already has ipV6 range: %s" % (vrf , nbr , ipv6_ranges ))
342378 return ipv4_ranges , ipv6_ranges
343379 else :
@@ -357,22 +393,22 @@ def apply_range_changes(self, vrf, nbr, new_ip_range, ip_ranges_to_del, data):
357393 """
358394 print_data = vrf , nbr , data
359395 kwargs = {
360- 'operation ' : 'update' ,
396+ 'CONFIG_DB__DEVICE_METADATA ' : self . directory . get_slot ( "CONFIG_DB" , swsscommon . CFG_DEVICE_METADATA_TABLE_NAME ) ,
361397 'vrf' : vrf ,
362- 'neighbor_addr' : nbr ,
363398 'bgp_session' : data ,
364399 'delete_ranges' : ip_ranges_to_del ,
365400 'add_ranges' : new_ip_range
366401 }
367402 try :
368- cmd = self .templates ["add " ].render (** kwargs )
403+ cmd = self .templates ["update " ].render (** kwargs )
369404 except jinja2 .TemplateError as e :
370405 msg = "Peer '(%s|%s)'. Error in rendering the template for 'SET' command '%s'" % print_data
371406 log_err ("%s: %s" % (msg , str (e )))
372407 return True
373408 if cmd is not None :
374409 self .apply_op (cmd , vrf )
375- log_info ("Peer '(%s|%s)' ip range has been scheduled to be updated with new range '%s'" % (vrf , nbr , new_ip_range ))
410+ self .update_state_db (vrf , nbr , data , "SET" )
411+ log_info ("Peer '(%s|%s)' ip range has been scheduled to be updated with range '%s'" % (vrf , nbr , data ['ip_range' ]))
376412
377413 def del_handler (self , key ):
378414 """
@@ -387,6 +423,7 @@ def del_handler(self, key):
387423 cmd = self .templates ["delete" ].render (neighbor_addr = nbr )
388424 ret_code = self .apply_op (cmd , vrf )
389425 if ret_code :
426+ self .update_state_db (vrf , nbr , {}, "DEL" )
390427 log_info ("Peer '(%s|%s)' has been removed" % (vrf , nbr ))
391428 self .peers .remove (peer_key )
392429 else :
0 commit comments