Skip to content

Commit

Permalink
net ax25: Simplify and cleanup the ax25 sysctl handling.
Browse files Browse the repository at this point in the history
Don't register/unregister every ax25 table in a batch.  Instead register
and unregister per device ax25 sysctls as ax25 devices come and go.

This moves ax25 to be a completely modern sysctl user.  Registering the
sysctls in just the initial network namespace, removing the use of
.child entries that are no longer natively supported by the sysctl core
and taking advantage of the fact that there are no longer any ordering
constraints between registering and unregistering different sysctl
tables.

Signed-off-by: Eric W. Biederman <[email protected]>
Acked-by: Pavel Emelyanov <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
ebiederm authored and davem330 committed Apr 21, 2012
1 parent 4e5ca78 commit 0ca7a4c
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 69 deletions.
10 changes: 5 additions & 5 deletions include/net/ax25.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ typedef struct ax25_dev {
struct ax25_dev *next;
struct net_device *dev;
struct net_device *forward;
struct ctl_table *systable;
struct ctl_table_header *sysheader;
int values[AX25_MAX_VALUES];
#if defined(CONFIG_AX25_DAMA_SLAVE) || defined(CONFIG_AX25_DAMA_MASTER)
ax25_dama_info dama;
Expand Down Expand Up @@ -441,11 +441,11 @@ extern void ax25_uid_free(void);

/* sysctl_net_ax25.c */
#ifdef CONFIG_SYSCTL
extern void ax25_register_sysctl(void);
extern void ax25_unregister_sysctl(void);
extern int ax25_register_dev_sysctl(ax25_dev *ax25_dev);
extern void ax25_unregister_dev_sysctl(ax25_dev *ax25_dev);
#else
static inline void ax25_register_sysctl(void) {};
static inline void ax25_unregister_sysctl(void) {};
static inline int ax25_register_dev_sysctl(ax25_dev *ax25_dev) { return 0 };
static inline void ax25_unregister_dev_sysctl(ax25_dev *ax25_dev) {};
#endif /* CONFIG_SYSCTL */

#endif
2 changes: 0 additions & 2 deletions net/ax25/af_ax25.c
Original file line number Diff line number Diff line change
Expand Up @@ -1990,7 +1990,6 @@ static int __init ax25_init(void)
sock_register(&ax25_family_ops);
dev_add_pack(&ax25_packet_type);
register_netdevice_notifier(&ax25_dev_notifier);
ax25_register_sysctl();

proc_net_fops_create(&init_net, "ax25_route", S_IRUGO, &ax25_route_fops);
proc_net_fops_create(&init_net, "ax25", S_IRUGO, &ax25_info_fops);
Expand All @@ -2015,7 +2014,6 @@ static void __exit ax25_exit(void)
ax25_uid_free();
ax25_dev_free();

ax25_unregister_sysctl();
unregister_netdevice_notifier(&ax25_dev_notifier);

dev_remove_pack(&ax25_packet_type);
Expand Down
10 changes: 2 additions & 8 deletions net/ax25/ax25_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ void ax25_dev_device_up(struct net_device *dev)
return;
}

ax25_unregister_sysctl();

dev->ax25_ptr = ax25_dev;
ax25_dev->dev = dev;
dev_hold(dev);
Expand Down Expand Up @@ -90,7 +88,7 @@ void ax25_dev_device_up(struct net_device *dev)
ax25_dev_list = ax25_dev;
spin_unlock_bh(&ax25_dev_lock);

ax25_register_sysctl();
ax25_register_dev_sysctl(ax25_dev);
}

void ax25_dev_device_down(struct net_device *dev)
Expand All @@ -100,7 +98,7 @@ void ax25_dev_device_down(struct net_device *dev)
if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
return;

ax25_unregister_sysctl();
ax25_unregister_dev_sysctl(ax25_dev);

spin_lock_bh(&ax25_dev_lock);

Expand All @@ -120,7 +118,6 @@ void ax25_dev_device_down(struct net_device *dev)
spin_unlock_bh(&ax25_dev_lock);
dev_put(dev);
kfree(ax25_dev);
ax25_register_sysctl();
return;
}

Expand All @@ -130,16 +127,13 @@ void ax25_dev_device_down(struct net_device *dev)
spin_unlock_bh(&ax25_dev_lock);
dev_put(dev);
kfree(ax25_dev);
ax25_register_sysctl();
return;
}

s = s->next;
}
spin_unlock_bh(&ax25_dev_lock);
dev->ax25_ptr = NULL;

ax25_register_sysctl();
}

int ax25_fwd_ioctl(unsigned int cmd, struct ax25_fwd_struct *fwd)
Expand Down
82 changes: 28 additions & 54 deletions net/ax25/sysctl_net_ax25.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,6 @@ static int min_proto[1], max_proto[] = { AX25_PROTO_MAX };
static int min_ds_timeout[1], max_ds_timeout[] = {65535000};
#endif

static struct ctl_table_header *ax25_table_header;

static ctl_table *ax25_table;
static int ax25_table_size;

static struct ctl_path ax25_path[] = {
{ .procname = "net", },
{ .procname = "ax25", },
{ }
};

static const ctl_table ax25_param_table[] = {
{
.procname = "ip_default_mode",
Expand Down Expand Up @@ -159,52 +148,37 @@ static const ctl_table ax25_param_table[] = {
{ } /* that's all, folks! */
};

void ax25_register_sysctl(void)
int ax25_register_dev_sysctl(ax25_dev *ax25_dev)
{
ax25_dev *ax25_dev;
int n, k;

spin_lock_bh(&ax25_dev_lock);
for (ax25_table_size = sizeof(ctl_table), ax25_dev = ax25_dev_list; ax25_dev != NULL; ax25_dev = ax25_dev->next)
ax25_table_size += sizeof(ctl_table);

if ((ax25_table = kzalloc(ax25_table_size, GFP_ATOMIC)) == NULL) {
spin_unlock_bh(&ax25_dev_lock);
return;
}

for (n = 0, ax25_dev = ax25_dev_list; ax25_dev != NULL; ax25_dev = ax25_dev->next) {
struct ctl_table *child = kmemdup(ax25_param_table,
sizeof(ax25_param_table),
GFP_ATOMIC);
if (!child) {
while (n--)
kfree(ax25_table[n].child);
kfree(ax25_table);
spin_unlock_bh(&ax25_dev_lock);
return;
}
ax25_table[n].child = ax25_dev->systable = child;
ax25_table[n].procname = ax25_dev->dev->name;
ax25_table[n].mode = 0555;


for (k = 0; k < AX25_MAX_VALUES; k++)
child[k].data = &ax25_dev->values[k];

n++;
char path[sizeof("net/ax25/") + IFNAMSIZ];
int k;
struct ctl_table *table;

table = kmemdup(ax25_param_table, sizeof(ax25_param_table), GFP_KERNEL);
if (!table)
return -ENOMEM;

for (k = 0; k < AX25_MAX_VALUES; k++)
table[k].data = &ax25_dev->values[k];

snprintf(path, sizeof(path), "net/ax25/%s", ax25_dev->dev->name);
ax25_dev->sysheader = register_net_sysctl(&init_net, path, table);
if (!ax25_dev->sysheader) {
kfree(table);
return -ENOMEM;
}
spin_unlock_bh(&ax25_dev_lock);

ax25_table_header = register_net_sysctl_table(&init_net, ax25_path, ax25_table);
return 0;
}

void ax25_unregister_sysctl(void)
void ax25_unregister_dev_sysctl(ax25_dev *ax25_dev)
{
ctl_table *p;
unregister_net_sysctl_table(ax25_table_header);

for (p = ax25_table; p->procname; p++)
kfree(p->child);
kfree(ax25_table);
struct ctl_table_header *header = ax25_dev->sysheader;
struct ctl_table *table;

if (header) {
ax25_dev->sysheader = NULL;
table = header->ctl_table_arg;
unregister_net_sysctl_table(header);
kfree(table);
}
}

0 comments on commit 0ca7a4c

Please sign in to comment.