Please, ignore this. Thanks, Kirill
On 27.03.2018 14:24, Kirill Tkhai wrote: > Currenly, this parameter can be configured via sysctl > only. But sysctl is considered as depricated interface > (man 2 sysctl), and it only can applied to current's net > namespace (this requires to do setns() to change it in > not current's net ns). > > So, let's export the parameter to /proc in standard way, > and this allows to access another process namespace > via /proc/[pid]/net/ip6_nonlocal_bind. > > Signed-off-by: Kirill Tkhai <ktk...@virtuozzo.com> > --- > net/ipv6/proc.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 48 insertions(+) > > diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c > index 6e57028d2e91..2d0aa59c2d0d 100644 > --- a/net/ipv6/proc.c > +++ b/net/ipv6/proc.c > @@ -312,6 +312,47 @@ int snmp6_unregister_dev(struct inet6_dev *idev) > return 0; > } > > +static int nonlocal_bind_show(struct seq_file *seq, void *v) > +{ > + struct net *net = seq->private; > + > + seq_printf(seq, "%d\n", !!net->ipv6.sysctl.ip_nonlocal_bind); > + return 0; > +} > + > +static int open_nonlocal_bind(struct inode *inode, struct file *file) > +{ > + return single_open_net(inode, file, nonlocal_bind_show); > +} > + > +static ssize_t write_nonlocal_bind(struct file *file, const char __user > *ubuf, > + size_t count, loff_t *ppos) > +{ > + struct net *net = ((struct seq_file *)file->private_data)->private; > + char buf[3]; > + > + if (*ppos || count <= 0 || count > sizeof(buf)) > + return -EINVAL; > + > + if (copy_from_user(buf, ubuf, count)) > + return -EFAULT; > + buf[0] -= '0'; > + if ((count == 3 && buf[2] != '\0') || > + (count >= 2 && buf[1] != '\n') || > + (buf[0] != 0 && buf[0] != 1)) > + return -EINVAL; > + > + net->ipv6.sysctl.ip_nonlocal_bind = buf[0]; > + return count; > +} > + > +static const struct file_operations nonlocal_bind_ops = { > + .open = open_nonlocal_bind, > + .read = seq_read, > + .write = write_nonlocal_bind, > + .release = single_release_net, > +}; > + > static int __net_init ipv6_proc_init_net(struct net *net) > { > if (!proc_create("sockstat6", 0444, net->proc_net, > @@ -321,12 +362,18 @@ static int __net_init ipv6_proc_init_net(struct net > *net) > if (!proc_create("snmp6", 0444, net->proc_net, &snmp6_seq_fops)) > goto proc_snmp6_fail; > > + if (!proc_create_data("ip6_nonlocal_bind", 0644, > + net->proc_net, &nonlocal_bind_ops, net)) > + goto proc_bind_fail; > + > net->mib.proc_net_devsnmp6 = proc_mkdir("dev_snmp6", net->proc_net); > if (!net->mib.proc_net_devsnmp6) > goto proc_dev_snmp6_fail; > return 0; > > proc_dev_snmp6_fail: > + remove_proc_entry("ip6_nonlocal_bind", net->proc_net); > +proc_bind_fail: > remove_proc_entry("snmp6", net->proc_net); > proc_snmp6_fail: > remove_proc_entry("sockstat6", net->proc_net); > @@ -337,6 +384,7 @@ static void __net_exit ipv6_proc_exit_net(struct net *net) > { > remove_proc_entry("sockstat6", net->proc_net); > remove_proc_entry("dev_snmp6", net->proc_net); > + remove_proc_entry("ip6_nonlocal_bind", net->proc_net); > remove_proc_entry("snmp6", net->proc_net); > } > >