FILE
ip_vs_pe.c
File preview with syntax highlighting.
linux-6.19.14/net/netfilter/ipvs/ip_vs_pe.c
1// SPDX-License-Identifier: GPL-2.0-only 2#define pr_fmt(fmt) "IPVS: " fmt 3 4#include <linux/module.h> 5#include <linux/spinlock.h> 6#include <linux/interrupt.h> 7#include <asm/string.h> 8#include <linux/kmod.h> 9#include <linux/sysctl.h> 10 11#include <net/ip_vs.h> 12 13/* IPVS pe list */ 14static LIST_HEAD(ip_vs_pe); 15 16/* semaphore for IPVS PEs. */ 17static DEFINE_MUTEX(ip_vs_pe_mutex); 18 19/* Get pe in the pe list by name */ 20struct ip_vs_pe *__ip_vs_pe_getbyname(const char *pe_name) 21{ 22 struct ip_vs_pe *pe; 23 24 IP_VS_DBG(10, "%s(): pe_name \"%s\"\n", __func__, 25 pe_name); 26 27 rcu_read_lock(); 28 list_for_each_entry_rcu(pe, &ip_vs_pe, n_list) { 29 /* Test and get the modules atomically */ 30 if (pe->module && 31 !try_module_get(pe->module)) { 32 /* This pe is just deleted */ 33 continue; 34 } 35 if (strcmp(pe_name, pe->name)==0) { 36 /* HIT */ 37 rcu_read_unlock(); 38 return pe; 39 } 40 module_put(pe->module); 41 } 42 rcu_read_unlock(); 43 44 return NULL; 45} 46 47/* Lookup pe and try to load it if it doesn't exist */ 48struct ip_vs_pe *ip_vs_pe_getbyname(const char *name) 49{ 50 struct ip_vs_pe *pe; 51 52 /* Search for the pe by name */ 53 pe = __ip_vs_pe_getbyname(name); 54 55 /* If pe not found, load the module and search again */ 56 if (!pe) { 57 request_module("ip_vs_pe_%s", name); 58 pe = __ip_vs_pe_getbyname(name); 59 } 60 61 return pe; 62} 63 64/* Register a pe in the pe list */ 65int register_ip_vs_pe(struct ip_vs_pe *pe) 66{ 67 struct ip_vs_pe *tmp; 68 69 /* increase the module use count */ 70 if (!ip_vs_use_count_inc()) 71 return -ENOENT; 72 73 mutex_lock(&ip_vs_pe_mutex); 74 /* Make sure that the pe with this name doesn't exist 75 * in the pe list. 76 */ 77 list_for_each_entry(tmp, &ip_vs_pe, n_list) { 78 if (strcmp(tmp->name, pe->name) == 0) { 79 mutex_unlock(&ip_vs_pe_mutex); 80 ip_vs_use_count_dec(); 81 pr_err("%s(): [%s] pe already existed " 82 "in the system\n", __func__, pe->name); 83 return -EINVAL; 84 } 85 } 86 /* Add it into the d-linked pe list */ 87 list_add_rcu(&pe->n_list, &ip_vs_pe); 88 mutex_unlock(&ip_vs_pe_mutex); 89 90 pr_info("[%s] pe registered.\n", pe->name); 91 92 return 0; 93} 94EXPORT_SYMBOL_GPL(register_ip_vs_pe); 95 96/* Unregister a pe from the pe list */ 97int unregister_ip_vs_pe(struct ip_vs_pe *pe) 98{ 99 mutex_lock(&ip_vs_pe_mutex); 100 /* Remove it from the d-linked pe list */ 101 list_del_rcu(&pe->n_list); 102 mutex_unlock(&ip_vs_pe_mutex); 103 104 /* decrease the module use count */ 105 ip_vs_use_count_dec(); 106 107 pr_info("[%s] pe unregistered.\n", pe->name); 108 109 return 0; 110} 111EXPORT_SYMBOL_GPL(unregister_ip_vs_pe);
~/
Read-only file preview.