123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- #define KMSG_COMPONENT "IPVS"
- #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
- #include <linux/module.h>
- #include <linux/spinlock.h>
- #include <linux/interrupt.h>
- #include <asm/string.h>
- #include <linux/kmod.h>
- #include <linux/sysctl.h>
- #include <net/ip_vs.h>
- /* IPVS pe list */
- static LIST_HEAD(ip_vs_pe);
- /* semaphore for IPVS PEs. */
- static DEFINE_MUTEX(ip_vs_pe_mutex);
- /* Get pe in the pe list by name */
- struct ip_vs_pe *__ip_vs_pe_getbyname(const char *pe_name)
- {
- struct ip_vs_pe *pe;
- IP_VS_DBG(10, "%s(): pe_name \"%s\"\n", __func__,
- pe_name);
- rcu_read_lock();
- list_for_each_entry_rcu(pe, &ip_vs_pe, n_list) {
- /* Test and get the modules atomically */
- if (pe->module &&
- !try_module_get(pe->module)) {
- /* This pe is just deleted */
- continue;
- }
- if (strcmp(pe_name, pe->name)==0) {
- /* HIT */
- rcu_read_unlock();
- return pe;
- }
- module_put(pe->module);
- }
- rcu_read_unlock();
- return NULL;
- }
- /* Lookup pe and try to load it if it doesn't exist */
- struct ip_vs_pe *ip_vs_pe_getbyname(const char *name)
- {
- struct ip_vs_pe *pe;
- /* Search for the pe by name */
- pe = __ip_vs_pe_getbyname(name);
- /* If pe not found, load the module and search again */
- if (!pe) {
- request_module("ip_vs_pe_%s", name);
- pe = __ip_vs_pe_getbyname(name);
- }
- return pe;
- }
- /* Register a pe in the pe list */
- int register_ip_vs_pe(struct ip_vs_pe *pe)
- {
- struct ip_vs_pe *tmp;
- /* increase the module use count */
- ip_vs_use_count_inc();
- mutex_lock(&ip_vs_pe_mutex);
- /* Make sure that the pe with this name doesn't exist
- * in the pe list.
- */
- list_for_each_entry(tmp, &ip_vs_pe, n_list) {
- if (strcmp(tmp->name, pe->name) == 0) {
- mutex_unlock(&ip_vs_pe_mutex);
- ip_vs_use_count_dec();
- pr_err("%s(): [%s] pe already existed "
- "in the system\n", __func__, pe->name);
- return -EINVAL;
- }
- }
- /* Add it into the d-linked pe list */
- list_add_rcu(&pe->n_list, &ip_vs_pe);
- mutex_unlock(&ip_vs_pe_mutex);
- pr_info("[%s] pe registered.\n", pe->name);
- return 0;
- }
- EXPORT_SYMBOL_GPL(register_ip_vs_pe);
- /* Unregister a pe from the pe list */
- int unregister_ip_vs_pe(struct ip_vs_pe *pe)
- {
- mutex_lock(&ip_vs_pe_mutex);
- /* Remove it from the d-linked pe list */
- list_del_rcu(&pe->n_list);
- mutex_unlock(&ip_vs_pe_mutex);
- /* decrease the module use count */
- ip_vs_use_count_dec();
- pr_info("[%s] pe unregistered.\n", pe->name);
- return 0;
- }
- EXPORT_SYMBOL_GPL(unregister_ip_vs_pe);
|