def send_hping3_traffic(self, sender_vm_fix, dest_ip, srcport, destport, count=1, interval='u100', *args, **kwargs): ''' Sends unidirectional traffic from sender_vm_fix to dest_ip using hping3 util, where as destination will send icmp error if no process is running on port destport ''' hping_h = Hping3(sender_vm_fix, dest_ip, destport=destport, baseport=srcport, count=count, interval=interval, *args, **kwargs) hping_h.start(wait=False) (stats, hping_log) = hping_h.stop() self.logger.debug('Hping3 log : %s' % (hping_log)) return (stats, hping_log)
def test_hping3_tcp_traffic_for_eviction(self): ''' Between two VMs, have a large number of hping3-based tcp sessions which are setup and teared down quickly. Validate that hping3 does not report any loss and the corresponding flows are evicted Repeat this a few times so that the same flow indices are used ''' count = 1000 # Set flow table size to 2M self.vn1_vm1_vrouter_fixture.setup_vrouter_module_params( {'vr_flow_entries': str(2 * 1024 * 1024)}) self.vn1_vm1_fixture.wait_till_vm_is_up() self.vn1_vm2_fixture.wait_till_vm_is_up() destport = '22' baseport = '1000' interval = 'u10000' # Create flows using hping hping_h = Hping3(self.vn1_vm1_fixture, self.vn1_vm2_fixture.vm_ip, syn=True, destport=destport, baseport=baseport, count=count, interval=interval) for i in range(0, 5): self.logger.info('Iteration : %s' % (i)) hping_h.start(wait=True) time.sleep(5) (stats, hping_log) = hping_h.stop() time.sleep(5) self.logger.debug('Hping3 log : %s' % (hping_log)) assert stats['loss'] == '0', ('Some loss seen in hping3 session' 'Stats : %s, Check logs..' % (stats)) self.logger.info('No packet loss seen with hping traffic') time.sleep(5) # Check if these flows got evicted flow_table = self.vn1_vm1_vrouter_fixture.get_flow_table() (ff_count, rf_count) = self.vn1_vm1_vrouter_fixture.get_flow_count( flow_table=flow_table, show_evicted=False, source_ip=self.vn1_vm1_fixture.vm_ip, dest_ip=self.vn1_vm2_fixture.vm_ip, proto='tcp', dest_port='22', vrf_id=self.vn1_vm1_vrouter_fixture.get_vrf_id( self.vn1_fixture.vn_fq_name)) if ff_count or rf_count: self.logger.debug('Flow table : %s' % (flow_table.get_as_table)) assert ff_count == 0, 'One or more flows not evicted yet. Check logs' assert rf_count == 0, 'One or more flows not evicted yet. Check logs' self.logger.info('Validated that all hping flows got evicted')
def _test_flow_export(self, sender_vm_fixture, dest_vm_fixture, sender_compute, dest_compute, baseport, destport, interval, count, export_rate, threshold=20): ''' Common internal method Measure flow export rate for tcp syn traffic over 1m ''' result = True if export_rate == 0: threshold = 0 else: threshold = threshold # Create flows using hping hping_h = Hping3(sender_vm_fixture, dest_vm_fixture.vm_ip, syn=True, destport=destport, baseport=baseport, count=count, interval=interval) hping_h.start(wait=False) self.sleep(65) # Check for no. of sessions exported in last 1 min for both source and # dest vrouter end_time = self.analytics_obj.getstarttime(self.inputs.collector_ip) start_time = str(int(end_time) - (60 * 1000000)) vrouter1_flows_exported = self.get_sessions_exported( self.vn1_vm1_vrouter_fixture.ip, start_time, end_time) vrouter2_flows_exported = self.get_sessions_exported( self.vn1_vm2_vrouter_fixture.ip, start_time, end_time) self.sleep(40) (stats, hping_log) = hping_h.stop() vrouter1_flows_expected = 60 * export_rate vrouter2_flows_expected = 60 * export_rate self.logger.info('Flows exported by VR %s is %s, Expected : %s ' % (self.vn1_vm1_vrouter_fixture.ip, vrouter1_flows_exported, vrouter1_flows_expected)) # Let threshold of deviation be 20% if not is_almost_same(vrouter1_flows_expected, vrouter1_flows_exported, threshold): self.logger.debug('Difference greater than percent threshold %s' % (threshold)) result = result and False self.logger.info('Flows exported by VR %s is %s, Expected : %s ' % (self.vn1_vm2_vrouter_fixture.ip, vrouter2_flows_exported, vrouter2_flows_expected)) if not is_almost_same(vrouter2_flows_expected, vrouter2_flows_exported, threshold): self.logger.debug('Difference greater than percent threshold %s' % (threshold)) result = result and False if result: self.logger.info('Validated that expected flow export rate is ' 'maintained') return result
def test_max_vm_flows(self): ''' Test to validate setting up of the max_vm_flows parameter in agent config file has expected effect on the flows in the system. 1. Set VM flow cache time and max_vm_flows to 0.1% of max system flows(512K) i.e about 500 flows 2. Create 2 VN's and connect them using a policy. 3. Launch 2 VM's in the respective VN's. 4. Start traffic with connections exceeding the VM flow limit 5. Check the flows are limited to about 500 flows ''' result = True # Set VM flow cache time to 20 and max_vm_flows to 0.1% of max system # flows(512K). comp_node_fixt = {} flow_cache_timeout = 20 max_system_flows = 0 max_vm_flows = 0.1 compute_ips = [self.inputs.compute_ips[0], self.inputs.compute_ips[0]] if len(self.inputs.compute_ips) > 1: compute_ips[1] = self.inputs.compute_ips[1] for cmp_node in compute_ips: comp_node_fixt[cmp_node] = self.useFixture( ComputeNodeFixture(self.connections, cmp_node)) comp_node_fixt[cmp_node].set_flow_aging_time(flow_cache_timeout) comp_node_fixt[cmp_node].get_config_per_vm_flow_limit() comp_node_fixt[cmp_node].set_per_vm_flow_limit(max_vm_flows) comp_node_fixt[cmp_node].sup_vrouter_process_restart() if max_system_flows < comp_node_fixt[cmp_node].max_system_flows: max_system_flows = comp_node_fixt[cmp_node].max_system_flows self.addCleanup(self.cleanup_test_max_vm_flows_vrouter_config, compute_ips, comp_node_fixt) # Define resources for this test. vn1_name = get_random_name('VN1') vn1_subnets = ['10.1.1.0/24'] vn2_name = get_random_name('VN2') vn2_subnets = ['10.2.1.0/24'] vn1_vm1_name = get_random_name('VM1') vn2_vm2_name = get_random_name('VM2') policy1_name = 'policy1' policy2_name = 'policy2' rules = [ { 'direction': '<>', 'simple_action': 'pass', 'protocol': 'any', 'source_network': vn1_name, 'dest_network': vn2_name, }, ] rev_rules = [ { 'direction': '<>', 'simple_action': 'pass', 'protocol': 'any', 'source_network': vn2_name, 'dest_network': vn1_name, }, ] # Create 2 VN's and connect them using a policy. vn1_fixture = self.create_vn(vn1_name, vn1_subnets) assert vn1_fixture.verify_on_setup() vn2_fixture = self.create_vn(vn2_name, vn2_subnets) assert vn2_fixture.verify_on_setup() policy1_fixture = self.useFixture( PolicyFixture(policy_name=policy1_name, rules_list=rules, inputs=self.inputs, connections=self.connections)) policy2_fixture = self.useFixture( PolicyFixture(policy_name=policy2_name, rules_list=rev_rules, inputs=self.inputs, connections=self.connections)) vn1_fixture.bind_policies([policy1_fixture.policy_fq_name], vn1_fixture.vn_id) self.addCleanup(vn1_fixture.unbind_policies, vn1_fixture.vn_id, [policy1_fixture.policy_fq_name]) vn2_fixture.bind_policies([policy2_fixture.policy_fq_name], vn2_fixture.vn_id) self.addCleanup(vn2_fixture.unbind_policies, vn2_fixture.vn_id, [policy2_fixture.policy_fq_name]) # Launch 2 VM's in the respective VN's. vm1_fixture = self.create_vm(vn1_fixture, vm_name=vn1_vm1_name, flavor='contrail_flavor_small', image_name='ubuntu-traffic', node_name=self.inputs.compute_names[0]) vm2_fixture = self.create_vm(vn2_fixture, vm_name=vn2_vm2_name, flavor='contrail_flavor_small', image_name='ubuntu-traffic', node_name=self.inputs.compute_names[1]) assert vm1_fixture.wait_till_vm_is_up(), 'VM1 does not seem to be up' assert vm2_fixture.wait_till_vm_is_up(), 'VM2 does not seem to be up' assert vm1_fixture.ping_with_certainty(vm2_fixture.vm_ip, count=1), \ 'Ping from VM1 to VM2 FAILED' # Set num_flows to fixed, smaller value but > 1% of # system max flows max_system_flows = max_system_flows vm_flow_limit = int((max_vm_flows / 100.0) * max_system_flows) num_flows = vm_flow_limit + 30 interval = 'u10000' proto = 'udp' # Try UDP echo dest_port = 7 hping_h = Hping3(vm1_fixture, vm2_fixture.vm_ip, destport=dest_port, count=num_flows, interval=interval, udp=True) self.sleep(flow_cache_timeout * 2) # No need to stop hping hping_h.start(wait=False) self.sleep(5) computes = [ comp_node_fixt[vm1_fixture.vm_node_ip], comp_node_fixt[vm2_fixture.vm_node_ip] ] for compute in computes: (fwd_flow_cnt, rev_flow_cnt) = compute.get_flow_count( source_ip=vm1_fixture.vm_ip, dest_ip=vm2_fixture.vm_ip, dest_port=dest_port, proto=proto) current_flow_cnt = fwd_flow_cnt + rev_flow_cnt msg = 'VM flow count : Expected:%s, Seen: %s' % (vm_flow_limit, current_flow_cnt) assert is_almost_same(current_flow_cnt, vm_flow_limit, 25), msg self.logger.info('On compute %s, %s..OK' % (compute.ip, msg))
def _generate_hping_traffic(self, src_vm_fixture, src_compute_fixture, interface, dest_ip=None, src_port=None, dest_port=None, encap=None, username=None, password=None, interval=1, count=1, vrf_id=None, proto=None, **kwargs): udp = kwargs.get('udp', False) tos = kwargs.get('tos', None) username = username or self.inputs.host_data[ src_compute_fixture.ip]['username'] password = password or self.inputs.host_data[ src_compute_fixture.ip]['password'] src_ip = src_vm_fixture.vm_ip hping_obj = Hping3(src_vm_fixture, dest_ip, destport=dest_port, baseport=src_port, count=count, interval=interval, udp=udp, tos=tos, keep=True, numeric=True) hping_obj.start(wait=kwargs.get('wait', False)) sleep(5) if encap == "MPLSoGRE": traffic_obj = TrafficAnalyzer(interface, src_compute_fixture, username, password, src_ip=src_ip, dest_ip=dest_ip, logger=self.logger, encap_type=encap) else: fwd_flow, rev_flow = src_compute_fixture.get_flow_entry( source_ip=src_ip, dest_ip=dest_ip, proto=proto, source_port=src_port, dest_port=dest_port, vrf_id=vrf_id) if not fwd_flow or not rev_flow: self.logger.error( 'Flow not created. Cannot proceed with analysis') return False src_port1 = fwd_flow.dump()['underlay_udp_sport'] if src_port1 == '0': self.logger.error('Flow does not seem active..something is ' 'wrong. Cannot proceed') self.logger.debug('Fwd flow :%s, Rev flow: %s' % (fwd_flow.dump(), rev_flow.dump())) return False traffic_obj = TrafficAnalyzer(interface, src_compute_fixture, username, password, src_port=src_port1, protocol='udp', logger=self.logger, encap_type=encap) return traffic_obj, hping_obj