validate_type('step', step, int)
assert step >= 0, 'step (%s) is negative' % step
+class CTRexVmInsFlowVarRandLimit(CTRexVmInsBase):
+ #TBD add more validation tests
+
+ VALID_SIZES =[1, 2, 4, 8]
+
+ def __init__(self, fv_name, size, limit, seed, min_value, max_value):
+ super(CTRexVmInsFlowVarRandLimit, self).__init__("flow_var_rand_limit")
+ self.name = fv_name;
+ validate_type('fv_name', fv_name, str)
+ self.size = size
+ self.limit=limit
+ validate_type('limit', limit, int)
+ assert limit >= 0, 'limit (%s) is negative' % limit
+ self.seed=seed
+ validate_type('seed', seed, int)
+ self.min_value=min_value
+ validate_type('min_value', min_value, int)
+ assert min_value >= 0, 'min_value (%s) is negative' % min_value
+ self.max_value=max_value
+ validate_type('max_value', max_value, int)
+ assert max_value >= 0, 'max_value (%s) is negative' % max_value
+
+
class CTRexVmInsWrFlowVar(CTRexVmInsBase):
def __init__(self, fv_name, pkt_offset, add_value=0, is_big_endian=True):
super(CTRexVmInsWrFlowVar, self).__init__("write_flow_var")
if not (op in CTRexVmInsFlowVar.OPERATIONS):
raise CTRexPacketBuildException(-11,("Flow var has invalid op %s ") % op );
+def get_max_by_size (size):
+ d={
+ 1:((1<<8) -1),
+ 2:((1<<16)-1),
+ 4:((1<<32)-1),
+ 8:0xffffffffffffffff
+ };
+ return d[size]
+
def convert_val (val):
if is_integer(val):
return val
class STLVmFlowVarRepetableRandom(CTRexVmDescBase):
- def __init__(self, name, size=4, limit=100, seed=None):
+ def __init__(self, name, size=4, limit=100, seed=None, min_value=0, max_value=None):
"""
Flow variable instruction for repeatable random with limit number of generating numbers. Allocates memory on a stream context.
- The size argument determines the variable size. Could be 1,2,,4 or 8
+ The size argument determines the variable size. Could be 1,2,4 or 8
:parameters:
name : string
seed : int
For deterministic result, you can set this to a uint16_t number
+ min_value : int
+ Min value
+
+ max_value : int
+ Max value
+
+
.. code-block:: python
:caption: Example1
# input , 1 byte or random with limit of 5
STLVmFlowVarRepetableRandom("var1",size=1,limit=5)
- # output 255,1,7,129,8,255,1,7,129,8
+ # output 255,1,7,129,8, ==> repeat 255,1,7,129,8
+
+ STLVmFlowVarRepetableRandom("var1",size=4,limit=100,min_value=0x12345678, max_value=0x32345678)
+
"""
- super(STLVmFlowVar, self).__init__()
+ super(STLVmFlowVarRepetableRandom, self).__init__()
self.name = name;
validate_type('name', name, str)
self.size =size
else:
self.seed = seed
- # choose default value for init val
- if init_value == None:
- init_value = max_value if op == "dec" else min_value
-
- self.init_value = convert_val (init_value)
self.min_value = convert_val (min_value);
- self.max_value = convert_val (max_value)
- self.step = convert_val (step)
+
+ if max_value == None :
+ max_value = get_max_by_size()
+
+ self.max_value = get_max_by_size (self.size)
if self.min_value > self.max_value :
raise CTRexPacketBuildException(-11,("max %d is lower than min %d ") % (self.max_value,self.min_value) );
def get_obj (self):
- return CTRexVmInsFlowVar(self.name,self.size,self.op,self.init_value,self.min_value,self.max_value,self.step);
+ return CTRexVmInsFlowVarRandLimit(self.name, self.size, self.limit, self.seed, self.min_value, self.max_value);
def get_var_name(self):
return [self.name]
));
}
+
+void
+TrexRpcCmdAddStream::check_min_max(uint8_t flow_var_size,
+ uint64_t init_value,
+ uint64_t step,
+ uint64_t min_value,
+ uint64_t max_value,
+ Json::Value &result){
+
+ if (max_value < min_value ) {
+ std::stringstream ss;
+ ss << "VM: request flow var variable '" << max_value << "' is smaller than " << min_value;
+ generate_parse_err(result, ss.str());
+ }
+
+ if (flow_var_size == 1 ) {
+ if ( (init_value > UINT8_MAX) || (min_value > UINT8_MAX) || (max_value > UINT8_MAX) || (step >UINT8_MAX) ) {
+ std::stringstream ss;
+ ss << "VM: request val is bigger than " << UINT8_MAX;
+ generate_parse_err(result, ss.str());
+ }
+ }
+
+ if (flow_var_size == 2 ) {
+ if ( (init_value > UINT16_MAX) || (min_value > UINT16_MAX) || (max_value > UINT16_MAX) || (step > UINT16_MAX) ) {
+ std::stringstream ss;
+ ss << "VM: request val is bigger than " << UINT16_MAX;
+ generate_parse_err(result, ss.str());
+ }
+ }
+
+ if (flow_var_size == 4 ) {
+ if ( (init_value > UINT32_MAX) || (min_value > UINT32_MAX) || (max_value > UINT32_MAX) || (step > UINT32_MAX) ) {
+ std::stringstream ss;
+ ss << "VM: request val is bigger than " << UINT32_MAX;
+ generate_parse_err(result, ss.str());
+ }
+ }
+}
+
void
TrexRpcCmdAddStream::parse_vm_instr_flow_var_rand_limit(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result) {
std::string flow_var_name = parse_string(inst, "name", result);
uint8_t flow_var_size = parse_choice(inst, "size", sizes, result);
uint64_t seed = parse_uint64(inst, "seed", result);
uint64_t limit = parse_uint64(inst, "limit", result);
+ uint64_t min_value = parse_uint64(inst, "min_value", result);
+ uint64_t max_value = parse_uint64(inst, "max_value", result);
if (limit < 1 ) {
std::stringstream ss;
generate_parse_err(result, ss.str());
}
+ check_min_max(flow_var_size, 0, 0, min_value, max_value, result);
+
stream->m_vm.add_instruction(new StreamVmInstructionFlowRandLimit(flow_var_name,
flow_var_size,
(int)limit,
- 0,0,
+ min_value,
+ max_value,
seed)
);
}
uint64_t max_value = parse_uint64(inst, "max_value", result);
uint64_t step = parse_uint64(inst, "step", result);
- if (max_value < min_value ) {
- std::stringstream ss;
- ss << "VM: request flow var variable '" << max_value << "' is smaller than " << min_value;
- generate_parse_err(result, ss.str());
- }
-
- if (flow_var_size == 1 ) {
- if ( (init_value > UINT8_MAX) || (min_value > UINT8_MAX) || (max_value > UINT8_MAX) || (step >UINT8_MAX) ) {
- std::stringstream ss;
- ss << "VM: request val is bigger than " << UINT8_MAX;
- generate_parse_err(result, ss.str());
- }
- }
-
- if (flow_var_size == 2 ) {
- if ( (init_value > UINT16_MAX) || (min_value > UINT16_MAX) || (max_value > UINT16_MAX) || (step > UINT16_MAX) ) {
- std::stringstream ss;
- ss << "VM: request val is bigger than " << UINT16_MAX;
- generate_parse_err(result, ss.str());
- }
- }
-
- if (flow_var_size == 4 ) {
- if ( (init_value > UINT32_MAX) || (min_value > UINT32_MAX) || (max_value > UINT32_MAX) || (step > UINT32_MAX) ) {
- std::stringstream ss;
- ss << "VM: request val is bigger than " << UINT32_MAX;
- generate_parse_err(result, ss.str());
- }
- }
-
+ check_min_max(flow_var_size, init_value, step, min_value, max_value, result);
stream->m_vm.add_instruction(new StreamVmInstructionFlowMan(flow_var_name,
flow_var_size,
for (int i = 0; i < instructions.size(); i++) {
const Json::Value & inst = parse_object(instructions, i, result);
- auto vm_types = {"fix_checksum_ipv4", "flow_var", "write_flow_var","tuple_flow_var","trim_pkt_size","write_mask_flow_var"};
+ auto vm_types = {"fix_checksum_ipv4", "flow_var", "write_flow_var","tuple_flow_var","trim_pkt_size","write_mask_flow_var","flow_var_rand_limit"};
std::string vm_type = parse_choice(inst, "type", vm_types, result);
// checksum instruction
parse_vm_instr_flow_var(inst, stream, result);
} else if (vm_type == "flow_var_rand_limit") {
- parse_vm_instr_flow_var(inst, stream, result);
+ parse_vm_instr_flow_var_rand_limit(inst, stream, result);
} else if (vm_type == "write_flow_var") {
parse_vm_instr_write_flow_var(inst, stream, result);
void parse_vm_instr_checksum(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result);
void parse_vm_instr_flow_var(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result);
void parse_vm_instr_flow_var_rand_limit(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result);
+void check_min_max(uint8_t flow_var_size, uint64_t init_value,uint64_t step,uint64_t min_value,uint64_t max_value,Json::Value &result);
+
void parse_vm_instr_tuple_flow_var(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result);
void parse_vm_instr_trim_pkt_size(const Json::Value &inst, std::unique_ptr<TrexStream> &stream, Json::Value &result);
}
void StreamDPOpFlowRandLimit64::dump(FILE *fd,std::string opt){
- fprintf(fd," %10s, flow_offset: %lu limit :%lu seed:%x \n", opt.c_str(),(ulong)m_flow_offset,(ulong)m_limit,m_seed);
+ fprintf(fd," %10s, flow_offset: %lu limit :%lu seed:%x (%lu-%lu) \n", opt.c_str(),(ulong)m_flow_offset,(ulong)m_limit,m_seed,m_min_val,m_max_val);
}