1/* nf_sysctl.c netfilter sysctl registration/unregistation 2 * 3 * Copyright (c) 2006 Patrick McHardy <kaber@trash.net> 4 */ 5#include <linux/module.h> 6#include <linux/sysctl.h> 7#include <linux/string.h> 8#include <linux/slab.h> 9 10static void 11path_free(struct ctl_table *path, struct ctl_table *table) 12{ 13 struct ctl_table *t, *next; 14 15 for (t = path; t != NULL && t != table; t = next) { 16 next = t->child; 17 kfree(t); 18 } 19} 20 21static struct ctl_table * 22path_dup(struct ctl_table *path, struct ctl_table *table) 23{ 24 struct ctl_table *t, *last = NULL, *tmp; 25 26 for (t = path; t != NULL; t = t->child) { 27 /* twice the size since path elements are terminated by an 28 * empty element */ 29 tmp = kmemdup(t, 2 * sizeof(*t), GFP_KERNEL); 30 if (tmp == NULL) { 31 if (last != NULL) 32 path_free(path, table); 33 return NULL; 34 } 35 36 if (last != NULL) 37 last->child = tmp; 38 else 39 path = tmp; 40 last = tmp; 41 } 42 43 if (last != NULL) 44 last->child = table; 45 else 46 path = table; 47 48 return path; 49} 50 51struct ctl_table_header * 52nf_register_sysctl_table(struct ctl_table *path, struct ctl_table *table) 53{ 54 struct ctl_table_header *header; 55 56 path = path_dup(path, table); 57 if (path == NULL) 58 return NULL; 59 header = register_sysctl_table(path); 60 if (header == NULL) 61 path_free(path, table); 62 return header; 63} 64EXPORT_SYMBOL_GPL(nf_register_sysctl_table); 65 66void 67nf_unregister_sysctl_table(struct ctl_table_header *header, 68 struct ctl_table *table) 69{ 70 struct ctl_table *path = header->ctl_table; 71 72 unregister_sysctl_table(header); 73 path_free(path, table); 74} 75EXPORT_SYMBOL_GPL(nf_unregister_sysctl_table); 76 77/* net/netfilter */ 78static struct ctl_table nf_net_netfilter_table[] = { 79 { 80 .ctl_name = NET_NETFILTER, 81 .procname = "netfilter", 82 .mode = 0555, 83 }, 84 { 85 .ctl_name = 0 86 } 87}; 88struct ctl_table nf_net_netfilter_sysctl_path[] = { 89 { 90 .ctl_name = CTL_NET, 91 .procname = "net", 92 .mode = 0555, 93 .child = nf_net_netfilter_table, 94 }, 95 { 96 .ctl_name = 0 97 } 98}; 99EXPORT_SYMBOL_GPL(nf_net_netfilter_sysctl_path); 100 101/* net/ipv4/netfilter */ 102static struct ctl_table nf_net_ipv4_netfilter_table[] = { 103 { 104 .ctl_name = NET_IPV4_NETFILTER, 105 .procname = "netfilter", 106 .mode = 0555, 107 }, 108 { 109 .ctl_name = 0 110 } 111}; 112static struct ctl_table nf_net_ipv4_table[] = { 113 { 114 .ctl_name = NET_IPV4, 115 .procname = "ipv4", 116 .mode = 0555, 117 .child = nf_net_ipv4_netfilter_table, 118 }, 119 { 120 .ctl_name = 0 121 } 122}; 123struct ctl_table nf_net_ipv4_netfilter_sysctl_path[] = { 124 { 125 .ctl_name = CTL_NET, 126 .procname = "net", 127 .mode = 0555, 128 .child = nf_net_ipv4_table, 129 }, 130 { 131 .ctl_name = 0 132 } 133}; 134EXPORT_SYMBOL_GPL(nf_net_ipv4_netfilter_sysctl_path); 135