diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/devinet.c | 105 |
1 files changed, 96 insertions, 9 deletions
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 8b2a44c4f82a..a2d48173828a 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -62,6 +62,7 @@ | |||
62 | #include <net/route.h> | 62 | #include <net/route.h> |
63 | #include <net/ip_fib.h> | 63 | #include <net/ip_fib.h> |
64 | #include <net/rtnetlink.h> | 64 | #include <net/rtnetlink.h> |
65 | #include <net/net_namespace.h> | ||
65 | 66 | ||
66 | struct ipv4_devconf ipv4_devconf = { | 67 | struct ipv4_devconf ipv4_devconf = { |
67 | .data = { | 68 | .data = { |
@@ -1497,7 +1498,7 @@ static int __devinet_sysctl_register(struct net *net, char *dev_name, | |||
1497 | devinet_ctl_path[DEVINET_CTL_PATH_DEV].procname = t->dev_name; | 1498 | devinet_ctl_path[DEVINET_CTL_PATH_DEV].procname = t->dev_name; |
1498 | devinet_ctl_path[DEVINET_CTL_PATH_DEV].ctl_name = ctl_name; | 1499 | devinet_ctl_path[DEVINET_CTL_PATH_DEV].ctl_name = ctl_name; |
1499 | 1500 | ||
1500 | t->sysctl_header = register_sysctl_paths(devinet_ctl_path, | 1501 | t->sysctl_header = register_net_sysctl_table(net, devinet_ctl_path, |
1501 | t->devinet_vars); | 1502 | t->devinet_vars); |
1502 | if (!t->sysctl_header) | 1503 | if (!t->sysctl_header) |
1503 | goto free_procname; | 1504 | goto free_procname; |
@@ -1557,27 +1558,113 @@ static struct ctl_table ctl_forward_entry[] = { | |||
1557 | { }, | 1558 | { }, |
1558 | }; | 1559 | }; |
1559 | 1560 | ||
1560 | static __initdata struct ctl_path net_ipv4_path[] = { | 1561 | static __net_initdata struct ctl_path net_ipv4_path[] = { |
1561 | { .procname = "net", .ctl_name = CTL_NET, }, | 1562 | { .procname = "net", .ctl_name = CTL_NET, }, |
1562 | { .procname = "ipv4", .ctl_name = NET_IPV4, }, | 1563 | { .procname = "ipv4", .ctl_name = NET_IPV4, }, |
1563 | { }, | 1564 | { }, |
1564 | }; | 1565 | }; |
1565 | 1566 | ||
1567 | static __net_init int devinet_init_net(struct net *net) | ||
1568 | { | ||
1569 | int err; | ||
1570 | struct ctl_table *tbl; | ||
1571 | struct ipv4_devconf *all, *dflt; | ||
1572 | struct ctl_table_header *forw_hdr; | ||
1573 | |||
1574 | err = -ENOMEM; | ||
1575 | all = &ipv4_devconf; | ||
1576 | dflt = &ipv4_devconf_dflt; | ||
1577 | tbl = ctl_forward_entry; | ||
1578 | |||
1579 | if (net != &init_net) { | ||
1580 | all = kmemdup(all, sizeof(ipv4_devconf), GFP_KERNEL); | ||
1581 | if (all == NULL) | ||
1582 | goto err_alloc_all; | ||
1583 | |||
1584 | dflt = kmemdup(dflt, sizeof(ipv4_devconf_dflt), GFP_KERNEL); | ||
1585 | if (dflt == NULL) | ||
1586 | goto err_alloc_dflt; | ||
1587 | |||
1588 | tbl = kmemdup(tbl, sizeof(ctl_forward_entry), GFP_KERNEL); | ||
1589 | if (tbl == NULL) | ||
1590 | goto err_alloc_ctl; | ||
1591 | |||
1592 | tbl[0].data = &all->data[NET_IPV4_CONF_FORWARDING - 1]; | ||
1593 | tbl[0].extra1 = all; | ||
1594 | tbl[0].extra2 = net; | ||
1595 | } | ||
1596 | |||
1597 | #ifdef CONFIG_SYSCTL | ||
1598 | err = __devinet_sysctl_register(net, "all", | ||
1599 | NET_PROTO_CONF_ALL, all); | ||
1600 | if (err < 0) | ||
1601 | goto err_reg_all; | ||
1602 | |||
1603 | err = __devinet_sysctl_register(net, "default", | ||
1604 | NET_PROTO_CONF_DEFAULT, dflt); | ||
1605 | if (err < 0) | ||
1606 | goto err_reg_dflt; | ||
1607 | |||
1608 | err = -ENOMEM; | ||
1609 | forw_hdr = register_net_sysctl_table(net, net_ipv4_path, tbl); | ||
1610 | if (forw_hdr == NULL) | ||
1611 | goto err_reg_ctl; | ||
1612 | #endif | ||
1613 | |||
1614 | net->ipv4.forw_hdr = forw_hdr; | ||
1615 | net->ipv4.devconf_all = all; | ||
1616 | net->ipv4.devconf_dflt = dflt; | ||
1617 | return 0; | ||
1618 | |||
1619 | #ifdef CONFIG_SYSCTL | ||
1620 | err_reg_ctl: | ||
1621 | __devinet_sysctl_unregister(dflt); | ||
1622 | err_reg_dflt: | ||
1623 | __devinet_sysctl_unregister(all); | ||
1624 | err_reg_all: | ||
1625 | if (tbl != ctl_forward_entry) | ||
1626 | kfree(tbl); | ||
1627 | #endif | ||
1628 | err_alloc_ctl: | ||
1629 | if (dflt != &ipv4_devconf_dflt) | ||
1630 | kfree(dflt); | ||
1631 | err_alloc_dflt: | ||
1632 | if (all != &ipv4_devconf) | ||
1633 | kfree(all); | ||
1634 | err_alloc_all: | ||
1635 | return err; | ||
1636 | } | ||
1637 | |||
1638 | static __net_exit void devinet_exit_net(struct net *net) | ||
1639 | { | ||
1640 | struct ctl_table *tbl; | ||
1641 | |||
1642 | tbl = net->ipv4.forw_hdr->ctl_table_arg; | ||
1643 | #ifdef CONFIG_SYSCTL | ||
1644 | unregister_net_sysctl_table(net->ipv4.forw_hdr); | ||
1645 | __devinet_sysctl_unregister(net->ipv4.devconf_dflt); | ||
1646 | __devinet_sysctl_unregister(net->ipv4.devconf_all); | ||
1647 | #endif | ||
1648 | kfree(tbl); | ||
1649 | kfree(net->ipv4.devconf_dflt); | ||
1650 | kfree(net->ipv4.devconf_all); | ||
1651 | } | ||
1652 | |||
1653 | static __net_initdata struct pernet_operations devinet_ops = { | ||
1654 | .init = devinet_init_net, | ||
1655 | .exit = devinet_exit_net, | ||
1656 | }; | ||
1657 | |||
1566 | void __init devinet_init(void) | 1658 | void __init devinet_init(void) |
1567 | { | 1659 | { |
1660 | register_pernet_subsys(&devinet_ops); | ||
1661 | |||
1568 | register_gifconf(PF_INET, inet_gifconf); | 1662 | register_gifconf(PF_INET, inet_gifconf); |
1569 | register_netdevice_notifier(&ip_netdev_notifier); | 1663 | register_netdevice_notifier(&ip_netdev_notifier); |
1570 | 1664 | ||
1571 | rtnl_register(PF_INET, RTM_NEWADDR, inet_rtm_newaddr, NULL); | 1665 | rtnl_register(PF_INET, RTM_NEWADDR, inet_rtm_newaddr, NULL); |
1572 | rtnl_register(PF_INET, RTM_DELADDR, inet_rtm_deladdr, NULL); | 1666 | rtnl_register(PF_INET, RTM_DELADDR, inet_rtm_deladdr, NULL); |
1573 | rtnl_register(PF_INET, RTM_GETADDR, NULL, inet_dump_ifaddr); | 1667 | rtnl_register(PF_INET, RTM_GETADDR, NULL, inet_dump_ifaddr); |
1574 | #ifdef CONFIG_SYSCTL | ||
1575 | __devinet_sysctl_register(&init_net, "all", NET_PROTO_CONF_ALL, | ||
1576 | &ipv4_devconf); | ||
1577 | __devinet_sysctl_register(&init_net, "default", NET_PROTO_CONF_DEFAULT, | ||
1578 | &ipv4_devconf_dflt); | ||
1579 | register_sysctl_paths(net_ipv4_path, ctl_forward_entry); | ||
1580 | #endif | ||
1581 | } | 1668 | } |
1582 | 1669 | ||
1583 | EXPORT_SYMBOL(in_dev_finish_destroy); | 1670 | EXPORT_SYMBOL(in_dev_finish_destroy); |