Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

IPVS: init and cleanup restructuring

DESCRIPTION
This patch tries to restore the initial init and cleanup
sequences that was before namspace patch.
Netns also requires action when net devices unregister
which has never been implemented. I.e this patch also
covers when a device moves into a network namespace,
and has to be released.

IMPLEMENTATION
The number of calls to register_pernet_device have been
reduced to one for the ip_vs.ko
Schedulers still have their own calls.

This patch adds a function __ip_vs_service_cleanup()
and an enable flag for the netfilter hooks.

The nf hooks will be enabled when the first service is loaded
and never disabled again, except when a namespace exit starts.

Signed-off-by: Hans Schillstrom <hans@schillstrom.com>
Acked-by: Julian Anastasov <ja@ssi.bg>
[horms@verge.net.au: minor edit to changelog]
Signed-off-by: Simon Horman <horms@verge.net.au>

authored by

Hans Schillstrom and committed by
Pablo Neira Ayuso
7a4f0761 1ae132b0

+223 -80
+17
include/net/ip_vs.h
··· 791 791 /* IPVS in network namespace */ 792 792 struct netns_ipvs { 793 793 int gen; /* Generation */ 794 + int enable; /* enable like nf_hooks do */ 794 795 /* 795 796 * Hash table: for real service lookups 796 797 */ ··· 1090 1089 atomic_inc(&ctl_cp->n_control); 1091 1090 } 1092 1091 1092 + /* 1093 + * IPVS netns init & cleanup functions 1094 + */ 1095 + extern int __ip_vs_estimator_init(struct net *net); 1096 + extern int __ip_vs_control_init(struct net *net); 1097 + extern int __ip_vs_protocol_init(struct net *net); 1098 + extern int __ip_vs_app_init(struct net *net); 1099 + extern int __ip_vs_conn_init(struct net *net); 1100 + extern int __ip_vs_sync_init(struct net *net); 1101 + extern void __ip_vs_conn_cleanup(struct net *net); 1102 + extern void __ip_vs_app_cleanup(struct net *net); 1103 + extern void __ip_vs_protocol_cleanup(struct net *net); 1104 + extern void __ip_vs_control_cleanup(struct net *net); 1105 + extern void __ip_vs_estimator_cleanup(struct net *net); 1106 + extern void __ip_vs_sync_cleanup(struct net *net); 1107 + extern void __ip_vs_service_cleanup(struct net *net); 1093 1108 1094 1109 /* 1095 1110 * IPVS application functions
+3 -12
net/netfilter/ipvs/ip_vs_app.c
··· 576 576 }; 577 577 #endif 578 578 579 - static int __net_init __ip_vs_app_init(struct net *net) 579 + int __net_init __ip_vs_app_init(struct net *net) 580 580 { 581 581 struct netns_ipvs *ipvs = net_ipvs(net); 582 582 ··· 585 585 return 0; 586 586 } 587 587 588 - static void __net_exit __ip_vs_app_cleanup(struct net *net) 588 + void __net_exit __ip_vs_app_cleanup(struct net *net) 589 589 { 590 590 proc_net_remove(net, "ip_vs_app"); 591 591 } 592 592 593 - static struct pernet_operations ip_vs_app_ops = { 594 - .init = __ip_vs_app_init, 595 - .exit = __ip_vs_app_cleanup, 596 - }; 597 - 598 593 int __init ip_vs_app_init(void) 599 594 { 600 - int rv; 601 - 602 - rv = register_pernet_subsys(&ip_vs_app_ops); 603 - return rv; 595 + return 0; 604 596 } 605 597 606 598 607 599 void ip_vs_app_cleanup(void) 608 600 { 609 - unregister_pernet_subsys(&ip_vs_app_ops); 610 601 }
+2 -10
net/netfilter/ipvs/ip_vs_conn.c
··· 1258 1258 return 0; 1259 1259 } 1260 1260 1261 - static void __net_exit __ip_vs_conn_cleanup(struct net *net) 1261 + void __net_exit __ip_vs_conn_cleanup(struct net *net) 1262 1262 { 1263 1263 /* flush all the connection entries first */ 1264 1264 ip_vs_conn_flush(net); 1265 1265 proc_net_remove(net, "ip_vs_conn"); 1266 1266 proc_net_remove(net, "ip_vs_conn_sync"); 1267 1267 } 1268 - static struct pernet_operations ipvs_conn_ops = { 1269 - .init = __ip_vs_conn_init, 1270 - .exit = __ip_vs_conn_cleanup, 1271 - }; 1272 1268 1273 1269 int __init ip_vs_conn_init(void) 1274 1270 { 1275 1271 int idx; 1276 - int retc; 1277 1272 1278 1273 /* Compute size and mask */ 1279 1274 ip_vs_conn_tab_size = 1 << ip_vs_conn_tab_bits; ··· 1304 1309 rwlock_init(&__ip_vs_conntbl_lock_array[idx].l); 1305 1310 } 1306 1311 1307 - retc = register_pernet_subsys(&ipvs_conn_ops); 1308 - 1309 1312 /* calculate the random value for connection hash */ 1310 1313 get_random_bytes(&ip_vs_conn_rnd, sizeof(ip_vs_conn_rnd)); 1311 1314 1312 - return retc; 1315 + return 0; 1313 1316 } 1314 1317 1315 1318 void ip_vs_conn_cleanup(void) 1316 1319 { 1317 - unregister_pernet_subsys(&ipvs_conn_ops); 1318 1320 /* Release the empty cache */ 1319 1321 kmem_cache_destroy(ip_vs_conn_cachep); 1320 1322 vfree(ip_vs_conn_tab);
+92 -9
net/netfilter/ipvs/ip_vs_core.c
··· 1113 1113 return NF_ACCEPT; 1114 1114 1115 1115 net = skb_net(skb); 1116 + if (!net_ipvs(net)->enable) 1117 + return NF_ACCEPT; 1118 + 1116 1119 ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); 1117 1120 #ifdef CONFIG_IP_VS_IPV6 1118 1121 if (af == AF_INET6) { ··· 1346 1343 return NF_ACCEPT; /* The packet looks wrong, ignore */ 1347 1344 1348 1345 net = skb_net(skb); 1346 + 1349 1347 pd = ip_vs_proto_data_get(net, cih->protocol); 1350 1348 if (!pd) 1351 1349 return NF_ACCEPT; ··· 1533 1529 IP_VS_DBG_ADDR(af, &iph.daddr), hooknum); 1534 1530 return NF_ACCEPT; 1535 1531 } 1532 + /* ipvs enabled in this netns ? */ 1533 + net = skb_net(skb); 1534 + if (!net_ipvs(net)->enable) 1535 + return NF_ACCEPT; 1536 + 1536 1537 ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); 1537 1538 1538 1539 /* Bad... Do not break raw sockets */ ··· 1571 1562 ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); 1572 1563 } 1573 1564 1574 - net = skb_net(skb); 1575 1565 /* Protocol supported? */ 1576 1566 pd = ip_vs_proto_data_get(net, iph.protocol); 1577 1567 if (unlikely(!pd)) ··· 1596 1588 } 1597 1589 1598 1590 IP_VS_DBG_PKT(11, af, pp, skb, 0, "Incoming packet"); 1599 - net = skb_net(skb); 1600 1591 ipvs = net_ipvs(net); 1601 1592 /* Check the server status */ 1602 1593 if (cp->dest && !(cp->dest->flags & IP_VS_DEST_F_AVAILABLE)) { ··· 1750 1743 int (*okfn)(struct sk_buff *)) 1751 1744 { 1752 1745 int r; 1746 + struct net *net; 1753 1747 1754 1748 if (ip_hdr(skb)->protocol != IPPROTO_ICMP) 1749 + return NF_ACCEPT; 1750 + 1751 + /* ipvs enabled in this netns ? */ 1752 + net = skb_net(skb); 1753 + if (!net_ipvs(net)->enable) 1755 1754 return NF_ACCEPT; 1756 1755 1757 1756 return ip_vs_in_icmp(skb, &r, hooknum); ··· 1770 1757 int (*okfn)(struct sk_buff *)) 1771 1758 { 1772 1759 int r; 1760 + struct net *net; 1773 1761 1774 1762 if (ipv6_hdr(skb)->nexthdr != IPPROTO_ICMPV6) 1763 + return NF_ACCEPT; 1764 + 1765 + /* ipvs enabled in this netns ? */ 1766 + net = skb_net(skb); 1767 + if (!net_ipvs(net)->enable) 1775 1768 return NF_ACCEPT; 1776 1769 1777 1770 return ip_vs_in_icmp_v6(skb, &r, hooknum); ··· 1903 1884 pr_err("%s(): no memory.\n", __func__); 1904 1885 return -ENOMEM; 1905 1886 } 1887 + /* Hold the beast until a service is registerd */ 1888 + ipvs->enable = 0; 1906 1889 ipvs->net = net; 1907 1890 /* Counters used for creating unique names */ 1908 1891 ipvs->gen = atomic_read(&ipvs_netns_cnt); 1909 1892 atomic_inc(&ipvs_netns_cnt); 1910 1893 net->ipvs = ipvs; 1894 + 1895 + if (__ip_vs_estimator_init(net) < 0) 1896 + goto estimator_fail; 1897 + 1898 + if (__ip_vs_control_init(net) < 0) 1899 + goto control_fail; 1900 + 1901 + if (__ip_vs_protocol_init(net) < 0) 1902 + goto protocol_fail; 1903 + 1904 + if (__ip_vs_app_init(net) < 0) 1905 + goto app_fail; 1906 + 1907 + if (__ip_vs_conn_init(net) < 0) 1908 + goto conn_fail; 1909 + 1910 + if (__ip_vs_sync_init(net) < 0) 1911 + goto sync_fail; 1912 + 1911 1913 printk(KERN_INFO "IPVS: Creating netns size=%zu id=%d\n", 1912 1914 sizeof(struct netns_ipvs), ipvs->gen); 1913 1915 return 0; 1916 + /* 1917 + * Error handling 1918 + */ 1919 + 1920 + sync_fail: 1921 + __ip_vs_conn_cleanup(net); 1922 + conn_fail: 1923 + __ip_vs_app_cleanup(net); 1924 + app_fail: 1925 + __ip_vs_protocol_cleanup(net); 1926 + protocol_fail: 1927 + __ip_vs_control_cleanup(net); 1928 + control_fail: 1929 + __ip_vs_estimator_cleanup(net); 1930 + estimator_fail: 1931 + return -ENOMEM; 1914 1932 } 1915 1933 1916 1934 static void __net_exit __ip_vs_cleanup(struct net *net) 1917 1935 { 1936 + __ip_vs_service_cleanup(net); /* ip_vs_flush() with locks */ 1937 + __ip_vs_conn_cleanup(net); 1938 + __ip_vs_app_cleanup(net); 1939 + __ip_vs_protocol_cleanup(net); 1940 + __ip_vs_control_cleanup(net); 1941 + __ip_vs_estimator_cleanup(net); 1918 1942 IP_VS_DBG(2, "ipvs netns %d released\n", net_ipvs(net)->gen); 1943 + } 1944 + 1945 + static void __net_exit __ip_vs_dev_cleanup(struct net *net) 1946 + { 1947 + EnterFunction(2); 1948 + net_ipvs(net)->enable = 0; /* Disable packet reception */ 1949 + __ip_vs_sync_cleanup(net); 1950 + LeaveFunction(2); 1919 1951 } 1920 1952 1921 1953 static struct pernet_operations ipvs_core_ops = { ··· 1976 1906 .size = sizeof(struct netns_ipvs), 1977 1907 }; 1978 1908 1909 + static struct pernet_operations ipvs_core_dev_ops = { 1910 + .exit = __ip_vs_dev_cleanup, 1911 + }; 1912 + 1979 1913 /* 1980 1914 * Initialize IP Virtual Server 1981 1915 */ 1982 1916 static int __init ip_vs_init(void) 1983 1917 { 1984 1918 int ret; 1985 - 1986 - ret = register_pernet_subsys(&ipvs_core_ops); /* Alloc ip_vs struct */ 1987 - if (ret < 0) 1988 - return ret; 1989 1919 1990 1920 ip_vs_estimator_init(); 1991 1921 ret = ip_vs_control_init(); ··· 2014 1944 goto cleanup_conn; 2015 1945 } 2016 1946 1947 + ret = register_pernet_subsys(&ipvs_core_ops); /* Alloc ip_vs struct */ 1948 + if (ret < 0) 1949 + goto cleanup_sync; 1950 + 1951 + ret = register_pernet_device(&ipvs_core_dev_ops); 1952 + if (ret < 0) 1953 + goto cleanup_sub; 1954 + 2017 1955 ret = nf_register_hooks(ip_vs_ops, ARRAY_SIZE(ip_vs_ops)); 2018 1956 if (ret < 0) { 2019 1957 pr_err("can't register hooks.\n"); 2020 - goto cleanup_sync; 1958 + goto cleanup_dev; 2021 1959 } 2022 1960 2023 1961 pr_info("ipvs loaded.\n"); 1962 + 2024 1963 return ret; 2025 1964 1965 + cleanup_dev: 1966 + unregister_pernet_device(&ipvs_core_dev_ops); 1967 + cleanup_sub: 1968 + unregister_pernet_subsys(&ipvs_core_ops); 2026 1969 cleanup_sync: 2027 1970 ip_vs_sync_cleanup(); 2028 1971 cleanup_conn: ··· 2047 1964 ip_vs_control_cleanup(); 2048 1965 cleanup_estimator: 2049 1966 ip_vs_estimator_cleanup(); 2050 - unregister_pernet_subsys(&ipvs_core_ops); /* free ip_vs struct */ 2051 1967 return ret; 2052 1968 } 2053 1969 2054 1970 static void __exit ip_vs_cleanup(void) 2055 1971 { 2056 1972 nf_unregister_hooks(ip_vs_ops, ARRAY_SIZE(ip_vs_ops)); 1973 + unregister_pernet_device(&ipvs_core_dev_ops); 1974 + unregister_pernet_subsys(&ipvs_core_ops); /* free ip_vs struct */ 2057 1975 ip_vs_sync_cleanup(); 2058 1976 ip_vs_conn_cleanup(); 2059 1977 ip_vs_app_cleanup(); 2060 1978 ip_vs_protocol_cleanup(); 2061 1979 ip_vs_control_cleanup(); 2062 1980 ip_vs_estimator_cleanup(); 2063 - unregister_pernet_subsys(&ipvs_core_ops); /* free ip_vs struct */ 2064 1981 pr_info("ipvs unloaded.\n"); 2065 1982 } 2066 1983
+101 -19
net/netfilter/ipvs/ip_vs_ctl.c
··· 69 69 } 70 70 #endif 71 71 72 + 73 + /* Protos */ 74 + static void __ip_vs_del_service(struct ip_vs_service *svc); 75 + 76 + 72 77 #ifdef CONFIG_IP_VS_IPV6 73 78 /* Taken from rt6_fill_node() in net/ipv6/route.c, is there a better way? */ 74 79 static int __ip_vs_addr_is_local_v6(struct net *net, ··· 1219 1214 write_unlock_bh(&__ip_vs_svc_lock); 1220 1215 1221 1216 *svc_p = svc; 1217 + /* Now there is a service - full throttle */ 1218 + ipvs->enable = 1; 1222 1219 return 0; 1223 1220 1224 1221 ··· 1479 1472 return 0; 1480 1473 } 1481 1474 1475 + /* 1476 + * Delete service by {netns} in the service table. 1477 + * Called by __ip_vs_cleanup() 1478 + */ 1479 + void __ip_vs_service_cleanup(struct net *net) 1480 + { 1481 + EnterFunction(2); 1482 + /* Check for "full" addressed entries */ 1483 + mutex_lock(&__ip_vs_mutex); 1484 + ip_vs_flush(net); 1485 + mutex_unlock(&__ip_vs_mutex); 1486 + LeaveFunction(2); 1487 + } 1488 + /* 1489 + * Release dst hold by dst_cache 1490 + */ 1491 + static inline void 1492 + __ip_vs_dev_reset(struct ip_vs_dest *dest, struct net_device *dev) 1493 + { 1494 + spin_lock_bh(&dest->dst_lock); 1495 + if (dest->dst_cache && dest->dst_cache->dev == dev) { 1496 + IP_VS_DBG_BUF(3, "Reset dev:%s dest %s:%u ,dest->refcnt=%d\n", 1497 + dev->name, 1498 + IP_VS_DBG_ADDR(dest->af, &dest->addr), 1499 + ntohs(dest->port), 1500 + atomic_read(&dest->refcnt)); 1501 + ip_vs_dst_reset(dest); 1502 + } 1503 + spin_unlock_bh(&dest->dst_lock); 1504 + 1505 + } 1506 + /* 1507 + * Netdev event receiver 1508 + * Currently only NETDEV_UNREGISTER is handled, i.e. if we hold a reference to 1509 + * a device that is "unregister" it must be released. 1510 + */ 1511 + static int ip_vs_dst_event(struct notifier_block *this, unsigned long event, 1512 + void *ptr) 1513 + { 1514 + struct net_device *dev = ptr; 1515 + struct net *net = dev_net(dev); 1516 + struct ip_vs_service *svc; 1517 + struct ip_vs_dest *dest; 1518 + unsigned int idx; 1519 + 1520 + if (event != NETDEV_UNREGISTER) 1521 + return NOTIFY_DONE; 1522 + IP_VS_DBG(3, "%s() dev=%s\n", __func__, dev->name); 1523 + EnterFunction(2); 1524 + mutex_lock(&__ip_vs_mutex); 1525 + for (idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) { 1526 + list_for_each_entry(svc, &ip_vs_svc_table[idx], s_list) { 1527 + if (net_eq(svc->net, net)) { 1528 + list_for_each_entry(dest, &svc->destinations, 1529 + n_list) { 1530 + __ip_vs_dev_reset(dest, dev); 1531 + } 1532 + } 1533 + } 1534 + 1535 + list_for_each_entry(svc, &ip_vs_svc_fwm_table[idx], f_list) { 1536 + if (net_eq(svc->net, net)) { 1537 + list_for_each_entry(dest, &svc->destinations, 1538 + n_list) { 1539 + __ip_vs_dev_reset(dest, dev); 1540 + } 1541 + } 1542 + 1543 + } 1544 + } 1545 + 1546 + list_for_each_entry(dest, &net_ipvs(net)->dest_trash, n_list) { 1547 + __ip_vs_dev_reset(dest, dev); 1548 + } 1549 + mutex_unlock(&__ip_vs_mutex); 1550 + LeaveFunction(2); 1551 + return NOTIFY_DONE; 1552 + } 1482 1553 1483 1554 /* 1484 1555 * Zero counters in a service or all services ··· 3673 3588 3674 3589 #endif 3675 3590 3591 + static struct notifier_block ip_vs_dst_notifier = { 3592 + .notifier_call = ip_vs_dst_event, 3593 + }; 3594 + 3676 3595 int __net_init __ip_vs_control_init(struct net *net) 3677 3596 { 3678 3597 int idx; ··· 3715 3626 return -ENOMEM; 3716 3627 } 3717 3628 3718 - static void __net_exit __ip_vs_control_cleanup(struct net *net) 3629 + void __net_exit __ip_vs_control_cleanup(struct net *net) 3719 3630 { 3720 3631 struct netns_ipvs *ipvs = net_ipvs(net); 3721 3632 ··· 3727 3638 proc_net_remove(net, "ip_vs"); 3728 3639 free_percpu(ipvs->tot_stats.cpustats); 3729 3640 } 3730 - 3731 - static struct pernet_operations ipvs_control_ops = { 3732 - .init = __ip_vs_control_init, 3733 - .exit = __ip_vs_control_cleanup, 3734 - }; 3735 3641 3736 3642 int __init ip_vs_control_init(void) 3737 3643 { ··· 3741 3657 INIT_LIST_HEAD(&ip_vs_svc_fwm_table[idx]); 3742 3658 } 3743 3659 3744 - ret = register_pernet_subsys(&ipvs_control_ops); 3745 - if (ret) { 3746 - pr_err("cannot register namespace.\n"); 3747 - goto err; 3748 - } 3749 - 3750 3660 smp_wmb(); /* Do we really need it now ? */ 3751 3661 3752 3662 ret = nf_register_sockopt(&ip_vs_sockopts); 3753 3663 if (ret) { 3754 3664 pr_err("cannot register sockopt.\n"); 3755 - goto err_net; 3665 + goto err_sock; 3756 3666 } 3757 3667 3758 3668 ret = ip_vs_genl_register(); 3759 3669 if (ret) { 3760 3670 pr_err("cannot register Generic Netlink interface.\n"); 3761 - nf_unregister_sockopt(&ip_vs_sockopts); 3762 - goto err_net; 3671 + goto err_genl; 3763 3672 } 3673 + 3674 + ret = register_netdevice_notifier(&ip_vs_dst_notifier); 3675 + if (ret < 0) 3676 + goto err_notf; 3764 3677 3765 3678 LeaveFunction(2); 3766 3679 return 0; 3767 3680 3768 - err_net: 3769 - unregister_pernet_subsys(&ipvs_control_ops); 3770 - err: 3681 + err_notf: 3682 + ip_vs_genl_unregister(); 3683 + err_genl: 3684 + nf_unregister_sockopt(&ip_vs_sockopts); 3685 + err_sock: 3771 3686 return ret; 3772 3687 } 3773 3688 ··· 3774 3691 void ip_vs_control_cleanup(void) 3775 3692 { 3776 3693 EnterFunction(2); 3777 - unregister_pernet_subsys(&ipvs_control_ops); 3778 3694 ip_vs_genl_unregister(); 3779 3695 nf_unregister_sockopt(&ip_vs_sockopts); 3780 3696 LeaveFunction(2);
+3 -11
net/netfilter/ipvs/ip_vs_est.c
··· 192 192 dst->outbps = (e->outbps + 0xF) >> 5; 193 193 } 194 194 195 - static int __net_init __ip_vs_estimator_init(struct net *net) 195 + int __net_init __ip_vs_estimator_init(struct net *net) 196 196 { 197 197 struct netns_ipvs *ipvs = net_ipvs(net); 198 198 ··· 203 203 return 0; 204 204 } 205 205 206 - static void __net_exit __ip_vs_estimator_exit(struct net *net) 206 + void __net_exit __ip_vs_estimator_cleanup(struct net *net) 207 207 { 208 208 del_timer_sync(&net_ipvs(net)->est_timer); 209 209 } 210 - static struct pernet_operations ip_vs_app_ops = { 211 - .init = __ip_vs_estimator_init, 212 - .exit = __ip_vs_estimator_exit, 213 - }; 214 210 215 211 int __init ip_vs_estimator_init(void) 216 212 { 217 - int rv; 218 - 219 - rv = register_pernet_subsys(&ip_vs_app_ops); 220 - return rv; 213 + return 0; 221 214 } 222 215 223 216 void ip_vs_estimator_cleanup(void) 224 217 { 225 - unregister_pernet_subsys(&ip_vs_app_ops); 226 218 }
+2 -9
net/netfilter/ipvs/ip_vs_proto.c
··· 316 316 /* 317 317 * per network name-space init 318 318 */ 319 - static int __net_init __ip_vs_protocol_init(struct net *net) 319 + int __net_init __ip_vs_protocol_init(struct net *net) 320 320 { 321 321 #ifdef CONFIG_IP_VS_PROTO_TCP 322 322 register_ip_vs_proto_netns(net, &ip_vs_protocol_tcp); ··· 336 336 return 0; 337 337 } 338 338 339 - static void __net_exit __ip_vs_protocol_cleanup(struct net *net) 339 + void __net_exit __ip_vs_protocol_cleanup(struct net *net) 340 340 { 341 341 struct netns_ipvs *ipvs = net_ipvs(net); 342 342 struct ip_vs_proto_data *pd; ··· 348 348 unregister_ip_vs_proto_netns(net, pd); 349 349 } 350 350 } 351 - 352 - static struct pernet_operations ipvs_proto_ops = { 353 - .init = __ip_vs_protocol_init, 354 - .exit = __ip_vs_protocol_cleanup, 355 - }; 356 351 357 352 int __init ip_vs_protocol_init(void) 358 353 { ··· 377 382 REGISTER_PROTOCOL(&ip_vs_protocol_esp); 378 383 #endif 379 384 pr_info("Registered protocols (%s)\n", &protocols[2]); 380 - return register_pernet_subsys(&ipvs_proto_ops); 381 385 382 386 return 0; 383 387 } ··· 387 393 struct ip_vs_protocol *pp; 388 394 int i; 389 395 390 - unregister_pernet_subsys(&ipvs_proto_ops); 391 396 /* unregister all the ipvs protocols */ 392 397 for (i = 0; i < IP_VS_PROTO_TAB_SIZE; i++) { 393 398 while ((pp = ip_vs_proto_table[i]) != NULL)
+3 -10
net/netfilter/ipvs/ip_vs_sync.c
··· 1663 1663 /* 1664 1664 * Initialize data struct for each netns 1665 1665 */ 1666 - static int __net_init __ip_vs_sync_init(struct net *net) 1666 + int __net_init __ip_vs_sync_init(struct net *net) 1667 1667 { 1668 1668 struct netns_ipvs *ipvs = net_ipvs(net); 1669 1669 ··· 1677 1677 return 0; 1678 1678 } 1679 1679 1680 - static void __ip_vs_sync_cleanup(struct net *net) 1680 + void __ip_vs_sync_cleanup(struct net *net) 1681 1681 { 1682 1682 int retc; 1683 1683 ··· 1690 1690 pr_err("Failed to stop Backup Daemon\n"); 1691 1691 } 1692 1692 1693 - static struct pernet_operations ipvs_sync_ops = { 1694 - .init = __ip_vs_sync_init, 1695 - .exit = __ip_vs_sync_cleanup, 1696 - }; 1697 - 1698 - 1699 1693 int __init ip_vs_sync_init(void) 1700 1694 { 1701 - return register_pernet_device(&ipvs_sync_ops); 1695 + return 0; 1702 1696 } 1703 1697 1704 1698 void ip_vs_sync_cleanup(void) 1705 1699 { 1706 - unregister_pernet_device(&ipvs_sync_ops); 1707 1700 }