docs: def from_bytes(cls, bitstream, decode_payload=True):
          '''
          Parse the given packet and update properties accordingly
          '''
          packet = cls()
  
          # Convert to ConstBitStream (if not already provided)
          if not isinstance(bitstream, ConstBitStream):
              if isinstance(bitstream, Bits):
                  bitstream = ConstBitStream(auto=bitstream)
              else:
                  bitstream = ConstBitStream(bytes=bitstream)
  
          # Read the version
          version = bitstream.read('uint:4')
          if version != packet.version:
              raise ValueError('Provided bytes do not contain an IPv6 packet')
  
          # Read the traffic class
          packet.traffic_class = bitstream.read('uint:8')
  
          # Read the flow label
          packet.flow_label = bitstream.read('uint:20')
  
          # Read the payload length
          payload_length = bitstream.read('uint:16')
  
          # Read the next header type
          packet.next_header = bitstream.read('uint:8')
  
          # Read the hop limit
          packet.hop_limit = bitstream.read('uint:8')
  
          # Read the source and destination addresses
          packet.source = IPv6Address(bitstream.read('uint:128'))
          packet.destination = IPv6Address(bitstream.read('uint:128'))
  
          # And the rest is payload
          packet.payload = bitstream.read('bytes:%d' % payload_length)
  
          if decode_payload:
              payload_class = protocol_registry.get_type_class(packet.next_header)
              if payload_class:
                  packet.payload = payload_class.from_bytes(packet.payload)
  
          # There should be no remaining bits
          if bitstream.pos != bitstream.len:
              raise ValueError('Bits remaining after processing packet')
  
          # Verify that the properties make sense
          packet.sanitize()
  
          return packet