int spd_proc_init( void) { spd_control_file = proc_create( LINUX_SPD_PROC_FILENAME, S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, NULL, &spd_proc_fops); if (spd_control_file == NULL) { DEBUG_FAIL( proc, "Failure creating proc entry %s.", LINUX_SPD_PROC_FILENAME); return -1; } spd_proc_set_ids(spd_control_file); init_waitqueue_head(&wait_queue); rwlock_init(&spd_proc_lock); initialised = 1; DEBUG_MEDIUM( proc, "Created proc entry %s.", LINUX_SPD_PROC_FILENAME); return 0; }
void spd_proc_uninit( void) { if (initialised != 0) { DEBUG_MEDIUM( proc, "Removing proc entry %s.", LINUX_SPD_PROC_FILENAME); DEBUG_HIGH(proc, "Kernel SPD deactivated."); spd_hooks_uninit(); active = 0; spd_proc_cleanup_selectors(); remove_proc_entry(LINUX_SPD_PROC_FILENAME, NULL); if (ipsec_boundary != NULL) { vfree(ipsec_boundary); ipsec_boundary = NULL; } bypass_kuid = INVALID_UID; initialised = 0; } else { DEBUG_FAIL(proc, "Already uninitialised."); } }
// Functions of class Retinex_MSRCR Frame &Retinex_MSRCR::process_Frame(Frame &dst, const Frame &src) { PCType i, j, upper; PCType height = src.Height(); PCType width = src.Width(); PCType stride = src.Stride(); if (src.isRGB()) { const Plane &srcR = src.R(); const Plane &srcG = src.G(); const Plane &srcB = src.B(); Plane &dstR = dst.R(); Plane &dstG = dst.G(); Plane &dstB = dst.B(); DType sFloor = srcR.Floor(); DType dFloor = dstR.Floor(); FLType dRangeFL = static_cast<FLType>(dstR.ValueRange()); Plane_FL idata(srcR, false); RangeConvert(idata, srcR); Plane_FL odataR = Kernel(idata); RangeConvert(idata, srcG); Plane_FL odataG = Kernel(idata); RangeConvert(idata, srcB); Plane_FL odataB = Kernel(idata); DType Rval, Gval, Bval; FLType temp; for (j = 0; j < height; ++j) { i = j * stride; for (upper = i + width; i < upper; ++i) { Rval = srcR[i] - sFloor; Gval = srcG[i] - sFloor; Bval = srcB[i] - sFloor; temp = static_cast<FLType>(Rval + Gval + Bval); temp = temp <= 0 ? 0 : para.restore / temp; odataR[i] *= log(Rval * temp + 1); odataG[i] *= log(Gval * temp + 1); odataB[i] *= log(Bval * temp + 1); } } SimplestColorBalance(dst, odataR, odataG, odataB, para.lower_thr, para.upper_thr, para.HistBins); } else { DEBUG_FAIL("Retinex_MSRCR::process: invalid PixelType of Frame \"src\", should be RGB."); } return dst; }
static int spd_proc_open( struct inode *inode, struct file *file) { if (open != 0) { DEBUG_FAIL(proc, "Kernel SPD device already open."); return -EFAULT; } if (!try_module_get(THIS_MODULE)) { DEBUG_FAIL(proc, "Kernel module being removed."); return -EFAULT; } DEBUG_HIGH(proc, "Kernel SPD device opened."); open = 1; return 0; }
struct IPSelectorDbEntry * ip_selector_db_entry_remove( struct IPSelectorDb *db, int part, uint32_t id) { struct IPSelectorDbEntry *removed = NULL; struct IPSelectorDbEntry **loc; loc = &db->heads[part]; while (*loc != NULL) { struct IPSelectorDbEntry *tmp = *loc; if (tmp->id == id) { removed = tmp; *loc = tmp->next; break; } loc = &tmp->next; } if (removed != NULL) { DEBUG_DUMP( db, debug_dump_ip_selector_group, (struct IPSelectorGroup *)(removed + 1), ((struct IPSelectorGroup *)(removed + 1))->bytecount, "Removed from db %p part %d; Entry %d " "action %d priority %d:", db, part, removed->id, removed->action, removed->priority); } else { DEBUG_FAIL( db, "Remove failed for db part %d id %d.", part, id); } return removed; }
static int update_ipsec_boundary( const char __user *user_boundary, size_t user_boundary_bytecount) { char *new_ipsec_boundary = NULL; unsigned new_ipsec_boundary_bytecount = user_boundary_bytecount; int status; if (new_ipsec_boundary_bytecount == 0) { DEBUG_FAIL(def, "IPsec boundary needed."); return -EFAULT; } if (new_ipsec_boundary_bytecount > KERNELSPD_IPSEC_BOUNDARY_LENGTH_MAX) { DEBUG_FAIL( def, "IPsec boundary too long %u.", new_ipsec_boundary_bytecount); return -EFAULT; } new_ipsec_boundary = vmalloc(new_ipsec_boundary_bytecount + 1); if (new_ipsec_boundary == NULL) { DEBUG_FAIL(def, "vmalloc() failed."); return -EFAULT; } status = copy_from_user( new_ipsec_boundary, user_boundary, new_ipsec_boundary_bytecount); if (status != 0) { DEBUG_FAIL(def, "Copy from user failed."); vfree(new_ipsec_boundary); return -EFAULT; } new_ipsec_boundary[new_ipsec_boundary_bytecount] = '\0'; if (ipsec_boundary_is_valid_spec(new_ipsec_boundary) == false) { DEBUG_FAIL( def, "IPsec boundary '%s' invalid.", new_ipsec_boundary); vfree(new_ipsec_boundary); return -EFAULT; } { char *old_boundary; write_lock_bh(&spd_lock); old_boundary = ipsec_boundary; ipsec_boundary = new_ipsec_boundary; write_unlock_bh(&spd_lock); if (old_boundary != NULL) { vfree(old_boundary); } } return 0; }
static ssize_t spd_proc_write( struct file *file, const char __user *data, size_t data_len, loff_t *pos) { size_t bytes_read = 0; DEBUG_LOW(proc, "Write of %d bytes.", (int) data_len); while (bytes_read < data_len) { struct KernelSpdCommand command; int status; if (data_len < sizeof command) { DEBUG_FAIL( proc, "Data length %d less than sizeof command %d bytes.", (int) data_len, (int) sizeof command); bytes_read = -EFAULT; break; } status = copy_from_user(&command, data, sizeof command); if (status != 0) { DEBUG_FAIL(proc, "Copy from user failed."); bytes_read = -EFAULT; break; } if (command.bytecount < sizeof command) { DEBUG_FAIL( proc, "Command bytecount %d less than command size %d.", (int) command.bytecount, (int) sizeof command); bytes_read = -EINVAL; break; } if (command.bytecount > KERNELSPD_PROCFS_COMMAND_BYTECOUNT_MAX) { DEBUG_FAIL( proc, "Command bytecount %d bigger than max command size %d.", (int) command.bytecount, (int) KERNELSPD_PROCFS_COMMAND_BYTECOUNT_MAX); bytes_read = -EINVAL; break; } if (command.bytecount > data_len - bytes_read) { DEBUG_FAIL( proc, "Command bytecount %d bigger than data_len %d.", (int) command.bytecount, (int) data_len); bytes_read = -EINVAL; break; } bytes_read += sizeof command; status = process_command( &command, data + bytes_read, command.bytecount - sizeof command); if (status < 0) { bytes_read = status; break; } bytes_read += command.bytecount; } return bytes_read; }
int process_command( struct KernelSpdCommand *cmd, const char __user *cmd_data, size_t cmd_data_bytecount) { int status = 0; DEBUG_LOW(proc, "Processing command id %d.", cmd->command_id); switch (cmd->command_id) { case KERNEL_SPD_ACTIVATE: { int ipsec_boundary_bytecount = cmd_data_bytecount; if (active != 0) { DEBUG_FAIL(def, "Kernel SPD already active."); status = -EFAULT; } else { status = update_ipsec_boundary( cmd_data, ipsec_boundary_bytecount); if (status != 0) { break; } if (spd_hooks_init() != 0) { DEBUG_FAIL(proc, "Kernel SPD Failed activating NF Hooks."); status = -EFAULT; } active = 1; DEBUG_HIGH( kernel, "Kernel SPD activated. IPsec boundary: '%s'.", ipsec_boundary); } } break; case KERNEL_SPD_DEACTIVATE: { if (active == 0) { DEBUG_FAIL(proc, "Kernel SPD not active."); } else { DEBUG_HIGH(proc, "Kernel SPD deactivated."); spd_hooks_uninit(); bypass_kuid = INVALID_UID; } active = 0; } break; case KERNEL_SPD_INSERT_ENTRY: { struct IPSelectorDbEntry *entry; const int payload_bytecount = cmd_data_bytecount; if (!KERNEL_SPD_ID_VALID(cmd->spd_id)) { DEBUG_FAIL( proc, "Invalid SPD id %d.", cmd->spd_id); status = -EFAULT; break; } entry = vmalloc(sizeof *entry + payload_bytecount); if (entry == NULL) { DEBUG_FAIL( proc, "vmalloc(%d) failed.", (int) (sizeof *entry + payload_bytecount)); status = -EFAULT; break; } status = copy_from_user(entry + 1, cmd_data, payload_bytecount); if (status != 0) { DEBUG_FAIL(proc, "Copy from user failed."); vfree(entry); status = -EFAULT; break; } entry->action = cmd->action_id; entry->id = cmd->entry_id; entry->priority = cmd->priority; if (ip_selector_db_entry_check( entry, sizeof *entry + payload_bytecount) < 0) { DEBUG_FAIL(proc, "Selector check failed."); vfree(entry); status = -EFAULT; break; } DEBUG_DUMP( proc, debug_dump_ip_selector_group, entry + 1, payload_bytecount, "Insert entry %d to spd " "id %d action %d priority %d precedence %d:", entry->id, cmd->spd_id, entry->action, entry->priority, cmd->precedence); write_lock_bh(&spd_lock); ip_selector_db_entry_add( &spd, cmd->spd_id, entry, cmd->precedence); write_unlock_bh(&spd_lock); } break; case KERNEL_SPD_REMOVE_ENTRY: if (!KERNEL_SPD_ID_VALID(cmd->spd_id)) { DEBUG_FAIL( proc, "Invalid SPD id %d.", cmd->spd_id); status = -EFAULT; break; } { struct IPSelectorDbEntry *removed; write_lock_bh(&spd_lock); removed = ip_selector_db_entry_remove( &spd, cmd->spd_id, cmd->entry_id); write_unlock_bh(&spd_lock); if (removed != NULL) { DEBUG_DUMP( proc, debug_dump_ip_selector_group, removed + 1, -1, "Removed entry %d to spd id %d action %d " "priority %d:", removed->id, cmd->spd_id, removed->action, removed->priority); vfree(removed); } else { DEBUG_FAIL( proc, "Remove failed: Entry %d not found from spd id %d.", cmd->entry_id, cmd->spd_id); } } break; case KERNEL_SPD_UPDATE_IPSEC_BOUNDARY: { int new_ipsec_boundary_bytecount = cmd_data_bytecount; if (active == 0) { DEBUG_FAIL(def, "Kernel SPD is not active."); return -EFAULT; } status = update_ipsec_boundary( cmd_data, new_ipsec_boundary_bytecount); if (status != 0) { break; } DEBUG_HIGH( kernel, "IPsec boundary updated: '%s'.", ipsec_boundary); } break; case KERNEL_SPD_VERSION_SYNC: { int version_bytecount = cmd_data_bytecount; uint32_t version; if (version_bytecount != sizeof version) { DEBUG_FAIL( def, "Invalid version size %d; should be %d.", version_bytecount, (int) sizeof version); return -EFAULT; } status = copy_from_user( &version, cmd_data, sizeof version); if (status != 0) { DEBUG_FAIL(def, "Copy from user failed."); return -EFAULT; } if (version != KERNEL_SPD_VERSION) { DEBUG_FAIL( def, "Invalid version %d; should be %d.", version, KERNEL_SPD_VERSION); return -EINVAL; } DEBUG_HIGH( kernel, "Versions in sync: %d.", version); } break; case KERNEL_SPD_ADD_BYPASS_UID: { uint32_t uid; if (active == 0) { DEBUG_FAIL(def, "Kernel SPD is not active."); return -EFAULT; } status = copy_from_user( &uid, cmd_data, sizeof uid); if (status != 0) { DEBUG_FAIL(def, "Copy from user failed."); return -EFAULT; } write_lock_bh(&spd_lock); bypass_kuid = make_kuid(current_user_ns(), (uid_t) uid); write_unlock_bh(&spd_lock); DEBUG_HIGH( kernel, "Set bypass uid to %u.", uid); } break; default: DEBUG_FAIL(proc, "Unknown command id %d.", cmd->command_id); break; } DEBUG_LOW(proc, "Returning %d", status); return status; }
// Functions of class Retinex Plane_FL &Retinex::Kernel(Plane_FL &dst, const Plane_FL &src) { const size_t scount = para.sigmaVector.size(); size_t s; for (s = 0; s < scount; ++s) { if (para.sigmaVector[s] > 0) break; } if (s >= scount) { dst = src; return dst; } PCType i, j, upper; PCType height = src.Height(); PCType width = src.Width(); PCType stride = src.Stride(); Plane_FL gauss(src, false); if (scount == 1 && para.sigmaVector[0] > 0) // single-scale Gaussian filter { RecursiveGaussian GFilter(para.sigmaVector[0], true); Plane_FL gauss = GFilter(src); for (j = 0; j < height; ++j) { i = j * stride; for (upper = i + width; i < upper; ++i) { dst[i] = gauss[i] <= 0 ? 0 : log(src[i] / gauss[i] + 1); } } } else // multi-scale Gaussian filter { if (dst.data() == src.data()) { DEBUG_FAIL("Retinex::Kernel: Data of Plane_FL \"dst\" and Plane_FL \"src\" can not be of the same address for multi-scale."); } dst.InitValue(1); for (s = 0; s < scount; ++s) { if (para.sigmaVector[s] > 0) { RecursiveGaussian GFilter(para.sigmaVector[s], true); GFilter.Filter(gauss, src); for (j = 0; j < height; ++j) { i = j * stride; for (upper = i + width; i < upper; ++i) { if (gauss[i] > 0) { dst[i] *= src[i] / gauss[i] + 1; } } } } else { for (j = 0; j < height; ++j) { i = j * stride; for (upper = i + width; i < upper; ++i) { dst[i] *= FLType(2); } } } } FLType scountRec = 1 / static_cast<FLType>(scount); for (j = 0; j < height; ++j) { i = j * stride; for (upper = i + width; i < upper; ++i) { dst[i] = log(dst[i]) * scountRec; } } } return dst; }