def __call__(self, message): global dispQ LOG.info("Inside Handle commit notifications") LOG.info("Received message: %s" % str(message)) config_dict = message['commit-patch'] print config_dict try: sw_present = False for keys in config_dict: if keys.endswith('softwire-config'): sw_present = True break if sw_present: purge_request = True # Push all the configuration into a new file stub = openconfig_service_pb2.beta_create_OpenconfigRpcApi_stub( self._dev.getChannel()) get_request = openconfig_service_pb2.GetRequestList( operation_id="1001", operation=1, path="/configuration/ietf-softwire:softwire-config") request = openconfig_service_pb2.GetRequest( request_id=1002, encoding=1, get_request=[get_request]) response = stub.Get(request, common.app_globals.RPC_TIMEOUT_SECONDS) for rsp in response.response: print rsp.value if rsp.response_code == openconfig_service_pb2.OK and rsp.value != "": print rsp LOG.info( "Invoked the getRequest for snabb configuration") config_dict = json.loads( rsp.value)["ietf-softwire:softwire-config"] LOG.debug( "Notification message contains the config %s" % (str(config_dict))) purge_request = False dispQ.put(config_dict) if purge_request: LOG.info("Softwire-config deleted in the config") config_dict['purge'] = True dispQ.put(config_dict) else: LOG.info("Softwire-config not present in the config") except Exception as e: LOG.critical("Exception: %s" % e.message) LOG.info('Exiting the JET app') os._exit(1) return
def parse_snabb_config(self, config_dict): if config_dict.get('purge', None) is not None: # Call the confAction to kill all the Snabb applications after # deleting the cfg/conf/binding files self.old_cfg = [] self.old_conf = [] self.old_binding_filename = None self.instances = {} LOG.info("Purging the snabb configuration files and terminating instances") ca = ConfAction() ca.deleteAction() return LOG.info("entered parse_snabb_config") # At first lets clear the present flag in all the instances for keys in self.instances: self.instances[keys] = 0 # Action handler to commit actions for conf/cfg/binding changes action_handler = ConfAction() # First the binding entry changes self.binding_changed = self.parse_for_binding(config_dict) # description is same for all the instances in the YANG schema cfg_dict = {} conf_dict = {} # Parse the config and cfg changes descr = self.myget(config_dict,'description') new_instance_list = config_dict['binding']['br']['br-instances']['br-instance'] for instances in new_instance_list: # TODO try except loop has to be implemented instance_id = self.myget(instances,'id') # Verify that the old config contains this instance, if not then we # need to delete this instance self.instances[instance_id] = 1 cfg_dict['id'] = instance_id cfg_dict['cnf_file_name'] = SNABB_FILENAME + str(instance_id) + '.conf' cfg_dict['ipv4_address'] = self.myget(instances,'ipv4_address') cfg_dict['ipv4_desc'] = descr cfg_dict['ipv4_cache_rate'] = self.myget(instances,'cache_refresh_interval') cfg_dict['ipv4_ingress_filter'] = self.myget(instances, 'ipv4_ingress_filter') cfg_dict['ipv4_egress_filter'] = self.myget(instances, 'ipv4_egress_filter') cfg_dict['fragmentation'] = self.myget(instances, 'fragmentation') cfg_dict['ipv6_address'] = self.myget(instances,'ipv6_address') cfg_dict['ipv6_desc'] = descr cfg_dict['ipv6_cache_rate'] = self.myget(instances,'cache_refresh_interval') cfg_dict['ipv6_ingress_filter'] = self.myget(instances, 'ipv6_ingress_filter') cfg_dict['ipv6_egress_filter'] = self.myget(instances, 'ipv6_egress_filter') cfg_dict['fragmentation'] = self.myget(instances, 'fragmentation') cfg_dict['ingress_drop_interval'] = self.myget(instances,'ingress_drop_interval') cfg_dict['ingress_drop_monitor'] = self.myget(instances,'ingress_drop_monitor') cfg_dict['ingress_drop_threshold'] = self.myget(instances, 'ingress_drop_threshold') cfg_dict['ingress_drop_wait'] = self.myget(instances,'ingress_drop_wait') cfg_dict['ring_buffer_size'] = None # Parse the conf file attributes conf_dict['id'] = instance_id if self.old_binding_filename is not None: conf_dict['binding_table'] = str(self.old_binding_filename) else: conf_dict['binding_table'] = None mac_path = SNABB_MAC_PATH + str(instance_id) # Read the files mac_id = "00:00:00:00:00:00" try: with open(mac_path) as f: mac_id = f.read().strip() except Exception as e: LOG.info('Failed to read the file %s due to exception: %s' % (mac_path, e.message)) conf_dict['v4_vlan_tag'] = self.myget(instances,'v4_vlan_tag') conf_dict['v6_vlan_tag'] = self.myget(instances, 'v6_vlan_tag') if self.myget(instances,'v4_vlan_tag') is not None or self.myget(instances, 'v6_vlan_tag') is not None: conf_dict['vlan_tagging'] = 'true' else: conf_dict['vlan_tagging'] = 'false' conf_dict['policy_icmpv4_incoming'] = self.myget(instances, 'policy_icmpv4_incoming') conf_dict['policy_icmpv4_outgoing'] = self.myget(instances, 'policy_icmpv4_outgoing') conf_dict['policy_icmpv6_incoming'] = self.myget(instances,'policy_icmpv6_incoming') conf_dict['policy_icmpv6_outgoing'] = self.myget(instances, 'policy_icmpv6_outgoing') conf_dict['max_fragments_per_reassembly_packet'] = self.myget(instances, 'max_fragments_per_reassembly_packet') conf_dict['max_ipv4_reassembly_packets'] = self.myget(instances, 'max_ipv4_reassembly_packets') conf_dict['max_ipv6_reassembly_packets'] = self.myget(instances, 'max_ipv6_reassembly_packets') conf_dict['icmpv6_rate_limiter_n_packets'] = self.myget(instances, 'icmpv6_rate_limiter_n_packets') conf_dict['icmpv6_rate_limiter_n_seconds'] = self.myget(instances, 'icmpv6_rate_limiter_n_seconds') conf_dict['ipv4_address'] = self.myget(instances, 'ipv4_address') conf_dict['ipv6_mtu'] = self.myget(instances,"tunnel-path-mru") conf_dict['ipv4_mtu'] = self.myget(instances,"tunnel-payload-mtu") conf_dict['hairpinning'] = self.myget(instances,"hairpinning") #TODO Why are the following values hardcoded conf_dict['ipv6_address'] = '2001:db8::1' conf_dict['inet_mac'] = '02:02:02:02:02:02' conf_dict['next_hop6_mac'] = '02:02:02:02:02:02' # TODO these parameters are not defined conf_dict['aftr_mac_inet_side'] = mac_id conf_dict['aftr_mac_b4_side'] = mac_id # Take action based on whether the cfg or conf files have changed # or not ret_cfg, ret_conf = False, False new_cfg_id_present = False new_conf_id_present = False cnt = 0 cfg_changed = False LOG.debug('New cfg dict = %s' % str(cfg_dict)) if self.old_cfg is None: ret_cfg = self.write_snabb_cfg_file(cfg_dict, instance_id) self.old_cfg.append(cfg_dict) if not ret_cfg: LOG.critical("Failed to write the cfg file") return else: # Add the new cfg to the old_cfg dictionary cnt = 0 for cfg_instance in self.old_cfg: if cfg_instance['id'] == cfg_dict['id']: # Check if the configuration has changed for this new instance if cmp(cfg_instance, cfg_dict) != 0: cfg_changed = True self.old_cfg[cnt] = cfg_dict new_cfg_id_present = True LOG.info("Cfg dictionary has changed") break else: new_cfg_id_present = True cfg_changed = False LOG.info("Cfg dictionary has not changed") break cnt += 1 # New cfg is not in the existing dict, add it if not new_cfg_id_present: self.old_cfg.append(cfg_dict) cfg_changed = True if (cfg_changed): ret_cfg = self.write_snabb_cfg_file(cfg_dict, instance_id) if not ret_cfg: LOG.critical("Failed to write the cfg file") return if self.old_conf is None: ret_conf = self.write_snabb_conf_file(conf_dict, instance_id) self.old_conf.append(conf_dict) if not ret_conf: LOG.critical("Failed to write the conf file") return else: cnt = 0 conf_changed = False new_conf_id_present = False for conf_instance in self.old_conf: if (conf_instance['id'] == conf_dict['id']): if cmp(conf_instance, conf_dict) != 0: conf_changed = True self.old_conf[cnt] = conf_dict new_conf_id_present = True LOG.info("Conf dictionary has changed") break else: new_conf_id_present = True conf_changed = False LOG.info("Conf dictionary has not changed") cnt = + 1 if not new_conf_id_present: self.old_conf.append(conf_dict) conf_changed = True if (conf_changed): ret_conf = self.write_snabb_conf_file( conf_dict, instance_id) if not ret_conf: LOG.critical("Failed to write the conf file") return if ret_conf or ret_cfg: # Assume that the instances list is populated here if not new_cfg_id_present and not new_conf_id_present: # It is a new instance, so start it LOG.info("New id added, starting new instance") ret = action_handler.start_snabb_instance(instance_id) else: LOG.info("The configuration changed, restarting the snabb instance id %s" %instance_id) ret = action_handler.cfgAction(instance_id) if not ret: LOG.critical("Failed to restart the Snabb instance") elif self.binding_changed: # Only the binding table has changed. # Send SIGHUP to the instances LOG.info("Only binding table has changed, sending SIGHUP") ret = action_handler.bindAction(self.old_binding_filename) if not ret: LOG.critical("Failed to reload the binding tables") self.binding_changed = False else: LOG.info("No config change hence did not restart Snabb instance %s id" %instance_id) # Few of the instances might have been deleted, we need to kill those # instances for keys in self.instances: if self.instances[keys] == 0: # Remove the old_cfg item which is for this id cnt = 0 for cfg_instance in self.old_cfg: if cfg_instance['id'] == keys: del self.old_cfg[cnt] break cnt += 1 cnt = 0 for conf_instance in self.old_conf: if conf_instance['id'] == keys: del self.old_conf[cnt] break cnt += 1 # Purge the files needed for this instance LOG.info( "Instance id %d is not present, need to kill it" % int(keys)) ret = action_handler.cfgAction(keys, False) if not ret: LOG.critical( "Failed to kill the Snabb instance %d" % int(keys)) return