]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - net/ipv4/devinet.c
net: fix netlink address dumping in IPv4/IPv6
[net-next-2.6.git] / net / ipv4 / devinet.c
index 040c4f05b65321b6b2c6023bb0eba66eecb7c26a..3feb2b39030838ca08fb02e0b0063711b34e76b2 100644 (file)
 
 static struct ipv4_devconf ipv4_devconf = {
        .data = {
-               [NET_IPV4_CONF_ACCEPT_REDIRECTS - 1] = 1,
-               [NET_IPV4_CONF_SEND_REDIRECTS - 1] = 1,
-               [NET_IPV4_CONF_SECURE_REDIRECTS - 1] = 1,
-               [NET_IPV4_CONF_SHARED_MEDIA - 1] = 1,
+               [IPV4_DEVCONF_ACCEPT_REDIRECTS - 1] = 1,
+               [IPV4_DEVCONF_SEND_REDIRECTS - 1] = 1,
+               [IPV4_DEVCONF_SECURE_REDIRECTS - 1] = 1,
+               [IPV4_DEVCONF_SHARED_MEDIA - 1] = 1,
        },
 };
 
 static struct ipv4_devconf ipv4_devconf_dflt = {
        .data = {
-               [NET_IPV4_CONF_ACCEPT_REDIRECTS - 1] = 1,
-               [NET_IPV4_CONF_SEND_REDIRECTS - 1] = 1,
-               [NET_IPV4_CONF_SECURE_REDIRECTS - 1] = 1,
-               [NET_IPV4_CONF_SHARED_MEDIA - 1] = 1,
-               [NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE - 1] = 1,
+               [IPV4_DEVCONF_ACCEPT_REDIRECTS - 1] = 1,
+               [IPV4_DEVCONF_SEND_REDIRECTS - 1] = 1,
+               [IPV4_DEVCONF_SECURE_REDIRECTS - 1] = 1,
+               [IPV4_DEVCONF_SHARED_MEDIA - 1] = 1,
+               [IPV4_DEVCONF_ACCEPT_SOURCE_ROUTE - 1] = 1,
        },
 };
 
@@ -1194,7 +1194,7 @@ static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
                hlist_for_each_entry_rcu(dev, node, head, index_hlist) {
                        if (idx < s_idx)
                                goto cont;
-                       if (idx > s_idx)
+                       if (h > s_h || idx > s_idx)
                                s_ip_idx = 0;
                        in_dev = __in_dev_get_rcu(dev);
                        if (!in_dev)
@@ -1317,14 +1317,19 @@ static int devinet_sysctl_forward(ctl_table *ctl, int write,
 {
        int *valp = ctl->data;
        int val = *valp;
+       loff_t pos = *ppos;
        int ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
 
        if (write && *valp != val) {
                struct net *net = ctl->extra2;
 
                if (valp != &IPV4_DEVCONF_DFLT(net, FORWARDING)) {
-                       if (!rtnl_trylock())
+                       if (!rtnl_trylock()) {
+                               /* Restore the original values before restarting */
+                               *valp = val;
+                               *ppos = pos;
                                return restart_syscall();
+                       }
                        if (valp == &IPV4_DEVCONF_ALL(net, FORWARDING)) {
                                inet_forward_change(net);
                        } else if (*valp) {
@@ -1360,7 +1365,7 @@ int ipv4_doint_and_flush(ctl_table *ctl, int write,
        { \
                .procname       = name, \
                .data           = ipv4_devconf.data + \
-                                 NET_IPV4_CONF_ ## attr - 1, \
+                                 IPV4_DEVCONF_ ## attr - 1, \
                .maxlen         = sizeof(int), \
                .mode           = mval, \
                .proc_handler   = proc, \
@@ -1381,7 +1386,7 @@ int ipv4_doint_and_flush(ctl_table *ctl, int write,
 
 static struct devinet_sysctl_table {
        struct ctl_table_header *sysctl_header;
-       struct ctl_table devinet_vars[__NET_IPV4_CONF_MAX];
+       struct ctl_table devinet_vars[__IPV4_DEVCONF_MAX];
        char *dev_name;
 } devinet_sysctl = {
        .devinet_vars = {
@@ -1408,6 +1413,7 @@ static struct devinet_sysctl_table {
                DEVINET_SYSCTL_RW_ENTRY(ARP_IGNORE, "arp_ignore"),
                DEVINET_SYSCTL_RW_ENTRY(ARP_ACCEPT, "arp_accept"),
                DEVINET_SYSCTL_RW_ENTRY(ARP_NOTIFY, "arp_notify"),
+               DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP_PVLAN, "proxy_arp_pvlan"),
 
                DEVINET_SYSCTL_FLUSHING_ENTRY(NOXFRM, "disable_xfrm"),
                DEVINET_SYSCTL_FLUSHING_ENTRY(NOPOLICY, "disable_policy"),
@@ -1486,8 +1492,7 @@ static void __devinet_sysctl_unregister(struct ipv4_devconf *cnf)
 
 static void devinet_sysctl_register(struct in_device *idev)
 {
-       neigh_sysctl_register(idev->dev, idev->arp_parms, NET_IPV4,
-                       NET_IPV4_NEIGH, "ipv4", NULL);
+       neigh_sysctl_register(idev->dev, idev->arp_parms, "ipv4", NULL);
        __devinet_sysctl_register(dev_net(idev->dev), idev->dev->name,
                                        &idev->cnf);
 }
@@ -1502,7 +1507,7 @@ static struct ctl_table ctl_forward_entry[] = {
        {
                .procname       = "ip_forward",
                .data           = &ipv4_devconf.data[
-                                       NET_IPV4_CONF_FORWARDING - 1],
+                                       IPV4_DEVCONF_FORWARDING - 1],
                .maxlen         = sizeof(int),
                .mode           = 0644,
                .proc_handler   = devinet_sysctl_forward,
@@ -1546,7 +1551,7 @@ static __net_init int devinet_init_net(struct net *net)
                if (tbl == NULL)
                        goto err_alloc_ctl;
 
-               tbl[0].data = &all->data[NET_IPV4_CONF_FORWARDING - 1];
+               tbl[0].data = &all->data[IPV4_DEVCONF_FORWARDING - 1];
                tbl[0].extra1 = all;
                tbl[0].extra2 = net;
 #endif