summaryrefslogtreecommitdiffstats
path: root/src/vnet/ip
AgeCommit message (Expand)AuthorFilesLines
2020-09-04ip: enhance vtep4_check of tunnel by vector wayZhiyong Yang1-0/+42
2020-09-01ip: fix ip zero checksum verificationBenoît Ganne3-8/+9
2020-09-01ip: improve ip4_header_checksum_is_validDamjan Marion1-5/+12
2020-08-31vppinfra: convert A_extend_to_B to B_from_A format of vector inlinesDamjan Marion1-8/+8
2020-08-31ip: fix compiling error with gcc-10Jieqiang Wang1-0/+12
2020-08-31cnat: Destination based NATNeale Ranns1-0/+35
2020-08-25flow: add vnet/flow formal APIChenmin Sun1-0/+12
2020-08-20ip: vnet_ip_mroute_cmd payload_proto fixElias Rudberg1-6/+6
2020-08-14ip: add VNET_IP_TABLE_ADD_DEL_FUNCTIONSteven Luong2-0/+132
2020-07-28ip: svr: improve performance for non-fragmentsKlement Sekera1-0/+206
2020-07-28ip: fix punt cli to only consumes a line of inputBenoît Ganne1-4/+25
2020-07-16ip: optimize ip4_header_checksum, take 2Damjan Marion1-32/+72
2020-07-16ip: optimize ip4_header_checksumDamjan Marion1-62/+55
2020-07-14ip: fix format_ip6_address_and_mask() bugChenmin Sun1-3/+2
2020-07-06ip: set ip4 mask for ip_copy and ip_set when dealing with ip4 typejiangxiaoming1-2/+8
2020-07-02ip: fix the order in ip4 punt redirectMohsin Kazmi1-2/+2
2020-06-26ip: fix the punt redirect for ip4Mohsin Kazmi1-6/+9
2020-06-12ip: allocate ip4 mtrie pages in htlb memoryDave Barach3-2/+48
2020-06-10ip: reassembly: LRU algorithm should eliminate the longest unused nodeszhengdelun2-2/+2
2020-06-08vxlan: Fixed checksum caclculation offsetVladimir Isaev2-14/+7
2020-06-01ip: fix IPv6 mask to prefix length conversionAndreas Schultz1-10/+5
2020-05-27ethernet: fix DMAC check and skip unnecessary ones (VPP-1868)John Lo2-0/+14
2020-05-27ip: reassembly: use correct IP header offsetKlement Sekera1-2/+7
2020-05-21ip: Dual loop error in midchain chksumNeale Ranns1-1/+1
2020-05-15misc: removed executable bits from source filesRay Kinsella1-0/+0
2020-05-14ip: fix interface ip address del sw_if_index checkyedg4-6/+27
2020-05-06docs: clean up make docs jobPaul Vinciguerra1-1/+1
2020-05-05api: ip: add IP_ROUTE_LOOKUP APIChristian Hopps2-0/+83
2020-05-04fib: midchain adjacency optimisationsNeale Ranns2-44/+79
2020-05-04misc: binary api fuzz test fixesDave Barach2-3/+4
2020-04-29ip: use thread local vm instead of thread main for vlib_time_now callsTom Seidenberg2-2/+2
2020-04-28tests: move defaults from defaultmapping to .api filesPaul Vinciguerra1-9/+9
2020-04-27ip: reassembly: fix one possible use-after-freeGao Feng2-10/+11
2020-04-24ip: reassembly: improve type safetyKlement Sekera4-30/+24
2020-04-24ip: Setting the Link-Local address from the API enables IPv6 on theNeale Ranns4-13/+18
2020-04-23ip: Replace Sematics for Interface IP addressesNeale Ranns10-293/+557
2020-04-22ip: fix format functions for u8 address_familyNeale Ranns1-1/+1
2020-04-15urpf: Allow locally generated packets on TXNeale Ranns1-4/+0
2020-04-15misc: refactor calc_checksumsDave Barach2-7/+21
2020-04-14urpf: Unicast reverse Path Forwarding (plugin)Neale Ranns7-614/+6
2020-04-09misc: fix error handling in punt_replicateDave Barach1-0/+1
2020-04-08ip: do not clear the locally-originated flagNeale Ranns2-16/+4
2020-04-07udp session: allow dgram ip fragmentationFlorin Coras1-17/+26
2020-04-06ip: reassembly: don't set error if no errorKlement Sekera4-8/+12
2020-04-01ip: Fix the AH/ESP protocol numbers on the APINeale Ranns1-2/+2
2020-03-25ip: Adding IP tables is no MP safeNeale Ranns1-2/+0
2020-03-24map: fix translation of icmp6 error messagesAlexander Chernavin1-0/+51
2020-03-20ip: provide extern declaration for ip punt nodesJawahar Santosh Gundapaneni2-0/+2
2020-03-20ip: ip API types coverity fixJakub Grajciar1-1/+0
2020-03-19ip: change ip API enums address_family and ip_proto size to u8Jakub Grajciar4-41/+51
h_to_str(), *args, **kwargs) class RemoteClass(Process): """ This class can wrap around and adapt the interface of another class, and then delegate its execution to a newly forked child process. Usage: # Create a remotely executed instance of MyClass object = RemoteClass(MyClass, arg1='foo', arg2='bar') object.start_remote() # Access the object normally as if it was an instance of your class. object.my_attribute = 20 print object.my_attribute print object.my_method(object.my_attribute) object.my_attribute.nested_attribute = 'test' # If you need the value of a remote attribute, use .get_remote_value method. This method is automatically called when needed in the context of a remotely executed class. E.g.: if (object.my_attribute.get_remote_value() > 20): object.my_attribute2 = object.my_attribute # Destroy the instance object.quit_remote() object.terminate() """ GET = 0 # Get attribute remotely CALL = 1 # Call method remotely SETATTR = 2 # Set attribute remotely REPR = 3 # Get representation of a remote object STR = 4 # Get string representation of a remote object QUIT = 5 # Quit remote execution PIPE_PARENT = 0 # Parent end of the pipe PIPE_CHILD = 1 # Child end of the pipe DEFAULT_TIMEOUT = 2 # default timeout for an operation to execute def __init__(self, cls, *args, **kwargs): super(RemoteClass, self).__init__() self._cls = cls self._args = args self._kwargs = kwargs self._timeout = RemoteClass.DEFAULT_TIMEOUT self._pipe = Pipe() # pipe for input/output arguments def __repr__(self): return moves.reprlib.repr(RemoteClassAttr(self, None)) def __str__(self): return str(RemoteClassAttr(self, None)) def __call__(self, *args, **kwargs): return self.RemoteClassAttr(self, None)() def __getattr__(self, attr): if attr[0] == '_' or not self.is_alive(): if not (attr.startswith('__') and attr.endswith('__')): if hasattr(super(RemoteClass, self), '__getattr__'): return super(RemoteClass, self).__getattr__(attr) raise AttributeError('missing: %s', attr) return RemoteClassAttr(self, attr) def __setattr__(self, attr, val): if attr[0] == '_' or not self.is_alive(): if not (attr.startswith('__') and attr.endswith('__')): super(RemoteClass, self).__setattr__(attr, val) return setattr(RemoteClassAttr(self, None), attr, val) def _remote_exec(self, op, path=None, *args, **kwargs): """ Execute given operation on a given, possibly nested, member remotely. """ # automatically resolve remote objects in the arguments mutable_args = list(args) for i, val in enumerate(mutable_args): if isinstance(val, RemoteClass) or \ isinstance(val, RemoteClassAttr): mutable_args[i] = val.get_remote_value() args = tuple(mutable_args) for key, val in six.iteritems(kwargs): if isinstance(val, RemoteClass) or \ isinstance(val, RemoteClassAttr): kwargs[key] = val.get_remote_value() # send request args = self._make_serializable(args) kwargs = self._make_serializable(kwargs) self._pipe[RemoteClass.PIPE_PARENT].send((op, path, args, kwargs)) timeout = self._timeout # adjust timeout specifically for the .sleep method if path is not None and path.split('.')[-1] == 'sleep': if args and isinstance(args[0], (long, int)): timeout += args[0] elif 'timeout' in kwargs: timeout += kwargs['timeout'] if not self._pipe[RemoteClass.PIPE_PARENT].poll(timeout): return None try: rv = self._pipe[RemoteClass.PIPE_PARENT].recv() rv = self._deserialize(rv) return rv except EOFError: return None def _get_local_object(self, path): """ Follow the path to obtain a reference on the addressed nested attribute """ obj = self._instance for attr in path: obj = getattr(obj, attr) return obj def _get_local_value(self, path): try: return self._get_local_object(path) except AttributeError: return None def _call_local_method(self, path, *args, **kwargs): try: method = self._get_local_object(path) return method(*args, **kwargs) except AttributeError: return None def _set_local_attr(self, path, value): try: obj = self._get_local_object(path[:-1]) setattr(obj, path[-1], value) except AttributeError: pass return None def _get_local_repr(self, path): try: obj = self._get_local_object(path) return moves.reprlib.repr(obj) except AttributeError: return None def _get_local_str(self, path): try: obj = self._get_local_object(path) return str(obj) except AttributeError: return None def _serializable(self, obj): """ Test if the given object is serializable """ try: dumps(obj) return True except: return False def _make_obj_serializable(self, obj): """ Make a serializable copy of an object. Members which are difficult/impossible to serialize are stripped. """ if self._serializable(obj): return obj # already serializable copy = SerializableClassCopy() """ Dictionaries can hold complex values, so we split keys and values into separate lists and serialize them individually. """ if (type(obj) is dict): copy.type = type(obj) copy.k_list = list() copy.v_list = list() for k, v in obj.items(): copy.k_list.append(self._make_serializable(k)) copy.v_list.append(self._make_serializable(v)) return copy # copy at least serializable attributes and properties for name, member in inspect.getmembers(obj): # skip private members and non-writable dunder methods. if name[0] == '_': if name in ['__weakref__']: continue if not (name.startswith('__') and name.endswith('__')): continue if callable(member) and not isinstance(member, property): continue if not self._serializable(member): continue setattr(copy, name, member) return copy def _make_serializable(self, obj): """ Make a serializable copy of an object or a list/tuple of objects. Members which are difficult/impossible to serialize are stripped. """ if (type(obj) is list) or (type(obj) is tuple): rv = [] for item in obj: rv.append(self._make_serializable(item)) if type(obj) is tuple: rv = tuple(rv) return rv elif (isinstance(obj, Enum)): return obj.value else: return self._make_obj_serializable(obj) def _deserialize_obj(self, obj): if (hasattr(obj, 'type')): if obj.type is dict: _obj = dict() for k, v in zip(obj.k_list, obj.v_list): _obj[self._deserialize(k)] = self._deserialize(v) return _obj return obj def _deserialize(self, obj): if (type(obj) is list) or (type(obj) is tuple): rv = [] for item in obj: rv.append(self._deserialize(item)) if type(obj) is tuple: rv = tuple(rv) return rv else: return self._deserialize_obj(obj) def start_remote(self): """ Start remote execution """ self.start() def quit_remote(self): """ Quit remote execution """ self._remote_exec(RemoteClass.QUIT, None) def get_remote_value(self): """ Get value of a remotely held object """ return RemoteClassAttr(self, None).get_remote_value() def set_request_timeout(self, timeout): """ Change request timeout """ self._timeout = timeout def run(self): """ Create instance of the wrapped class and execute operations on it as requested by the parent process. """ self._instance = self._cls(*self._args, **self._kwargs) while True: try: rv = None # get request from the parent process (op, path, args, kwargs) = self._pipe[RemoteClass.PIPE_CHILD].recv() args = self._deserialize(args) kwargs = self._deserialize(kwargs) path = path.split('.') if path else [] if op == RemoteClass.GET: rv = self._get_local_value(path) elif op == RemoteClass.CALL: rv = self._call_local_method(path, *args, **kwargs) elif op == RemoteClass.SETATTR and 'value' in kwargs: self._set_local_attr(path, kwargs['value']) elif op == RemoteClass.REPR: rv = self._get_local_repr(path) elif op == RemoteClass.STR: rv = self._get_local_str(path) elif op == RemoteClass.QUIT: break else: continue # send return value if not self._serializable(rv): rv = self._make_serializable(rv) self._pipe[RemoteClass.PIPE_CHILD].send(rv) except EOFError: break self._instance = None # destroy the instance @unittest.skip("Remote Vpp Test Case Class") class RemoteVppTestCase(VppTestCase): """ Re-use VppTestCase to create remote VPP segment In your test case: @classmethod def setUpClass(cls): # fork new process before client connects to VPP cls.remote_test = RemoteClass(RemoteVppTestCase) # start remote process cls.remote_test.start_remote() # set up your test case super(MyTestCase, cls).setUpClass() # set up remote test cls.remote_test.setUpClass(cls.tempdir) @classmethod def tearDownClass(cls): # tear down remote test cls.remote_test.tearDownClass() # stop remote process cls.remote_test.quit_remote() # tear down your test case super(MyTestCase, cls).tearDownClass() """ def __init__(self): super(RemoteVppTestCase, self).__init__("emptyTest") # Note: __del__ is a 'Finalizer" not a 'Destructor'. # https://docs.python.org/3/reference/datamodel.html#object.__del__ def __del__(self): if hasattr(self, "vpp"): self.vpp.poll() if self.vpp.returncode is None: self.vpp.terminate() self.vpp.communicate() @classmethod def setUpClass(cls, tempdir): # disable features unsupported in remote VPP orig_env = dict(os.environ) if 'STEP' in os.environ: del os.environ['STEP'] if 'DEBUG' in os.environ: del os.environ['DEBUG'] cls.tempdir_prefix = os.path.basename(tempdir) + "/" super(RemoteVppTestCase, cls).setUpClass() os.environ = orig_env @classmethod def tearDownClass(cls): super(RemoteVppTestCase, cls).tearDownClass() @unittest.skip("Empty test") def emptyTest(self): """ Do nothing """ pass def setTestFunctionInfo(self, name, doc): """ Store the name and documentation string of currently executed test in the main VPP for logging purposes. """ self._testMethodName = name self._testMethodDoc = doc