diff options
author | David S. Miller <davem@davemloft.net> | 2011-05-10 18:04:35 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-05-10 18:04:35 -0400 |
commit | 9bbc052d5e63512b0ce4e201ea97e12fba9fda82 (patch) | |
tree | 30433e20961b73e571c081869d1ea52c92c7b15a /net | |
parent | 0d4420a90b51abdea71585f571bad6d789ff8eb7 (diff) | |
parent | 93bbce1ad0cd788190dd7d6c17d289f771fe3d0d (diff) |
Merge branch 'pablo/nf-2.6-updates' of git://1984.lsi.us.es/net-2.6
Diffstat (limited to 'net')
-rw-r--r-- | net/bridge/netfilter/ebtables.c | 64 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6t_REJECT.c | 4 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_app.c | 15 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_conn.c | 12 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_core.c | 103 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_ctl.c | 120 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_est.c | 14 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_proto.c | 11 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_sync.c | 65 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_netlink.c | 4 | ||||
-rw-r--r-- | net/netfilter/x_tables.c | 4 | ||||
-rw-r--r-- | net/netfilter/xt_DSCP.c | 2 | ||||
-rw-r--r-- | net/netfilter/xt_conntrack.c | 5 |
13 files changed, 262 insertions, 161 deletions
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 893669caa8de..1a92b369c820 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c | |||
@@ -1766,7 +1766,7 @@ static int compat_table_info(const struct ebt_table_info *info, | |||
1766 | 1766 | ||
1767 | newinfo->entries_size = size; | 1767 | newinfo->entries_size = size; |
1768 | 1768 | ||
1769 | xt_compat_init_offsets(AF_INET, info->nentries); | 1769 | xt_compat_init_offsets(NFPROTO_BRIDGE, info->nentries); |
1770 | return EBT_ENTRY_ITERATE(entries, size, compat_calc_entry, info, | 1770 | return EBT_ENTRY_ITERATE(entries, size, compat_calc_entry, info, |
1771 | entries, newinfo); | 1771 | entries, newinfo); |
1772 | } | 1772 | } |
@@ -1882,7 +1882,7 @@ static int compat_mtw_from_user(struct compat_ebt_entry_mwt *mwt, | |||
1882 | struct xt_match *match; | 1882 | struct xt_match *match; |
1883 | struct xt_target *wt; | 1883 | struct xt_target *wt; |
1884 | void *dst = NULL; | 1884 | void *dst = NULL; |
1885 | int off, pad = 0, ret = 0; | 1885 | int off, pad = 0; |
1886 | unsigned int size_kern, entry_offset, match_size = mwt->match_size; | 1886 | unsigned int size_kern, entry_offset, match_size = mwt->match_size; |
1887 | 1887 | ||
1888 | strlcpy(name, mwt->u.name, sizeof(name)); | 1888 | strlcpy(name, mwt->u.name, sizeof(name)); |
@@ -1935,13 +1935,6 @@ static int compat_mtw_from_user(struct compat_ebt_entry_mwt *mwt, | |||
1935 | break; | 1935 | break; |
1936 | } | 1936 | } |
1937 | 1937 | ||
1938 | if (!dst) { | ||
1939 | ret = xt_compat_add_offset(NFPROTO_BRIDGE, entry_offset, | ||
1940 | off + ebt_compat_entry_padsize()); | ||
1941 | if (ret < 0) | ||
1942 | return ret; | ||
1943 | } | ||
1944 | |||
1945 | state->buf_kern_offset += match_size + off; | 1938 | state->buf_kern_offset += match_size + off; |
1946 | state->buf_user_offset += match_size; | 1939 | state->buf_user_offset += match_size; |
1947 | pad = XT_ALIGN(size_kern) - size_kern; | 1940 | pad = XT_ALIGN(size_kern) - size_kern; |
@@ -2016,50 +2009,6 @@ static int ebt_size_mwt(struct compat_ebt_entry_mwt *match32, | |||
2016 | return growth; | 2009 | return growth; |
2017 | } | 2010 | } |
2018 | 2011 | ||
2019 | #define EBT_COMPAT_WATCHER_ITERATE(e, fn, args...) \ | ||
2020 | ({ \ | ||
2021 | unsigned int __i; \ | ||
2022 | int __ret = 0; \ | ||
2023 | struct compat_ebt_entry_mwt *__watcher; \ | ||
2024 | \ | ||
2025 | for (__i = e->watchers_offset; \ | ||
2026 | __i < (e)->target_offset; \ | ||
2027 | __i += __watcher->watcher_size + \ | ||
2028 | sizeof(struct compat_ebt_entry_mwt)) { \ | ||
2029 | __watcher = (void *)(e) + __i; \ | ||
2030 | __ret = fn(__watcher , ## args); \ | ||
2031 | if (__ret != 0) \ | ||
2032 | break; \ | ||
2033 | } \ | ||
2034 | if (__ret == 0) { \ | ||
2035 | if (__i != (e)->target_offset) \ | ||
2036 | __ret = -EINVAL; \ | ||
2037 | } \ | ||
2038 | __ret; \ | ||
2039 | }) | ||
2040 | |||
2041 | #define EBT_COMPAT_MATCH_ITERATE(e, fn, args...) \ | ||
2042 | ({ \ | ||
2043 | unsigned int __i; \ | ||
2044 | int __ret = 0; \ | ||
2045 | struct compat_ebt_entry_mwt *__match; \ | ||
2046 | \ | ||
2047 | for (__i = sizeof(struct ebt_entry); \ | ||
2048 | __i < (e)->watchers_offset; \ | ||
2049 | __i += __match->match_size + \ | ||
2050 | sizeof(struct compat_ebt_entry_mwt)) { \ | ||
2051 | __match = (void *)(e) + __i; \ | ||
2052 | __ret = fn(__match , ## args); \ | ||
2053 | if (__ret != 0) \ | ||
2054 | break; \ | ||
2055 | } \ | ||
2056 | if (__ret == 0) { \ | ||
2057 | if (__i != (e)->watchers_offset) \ | ||
2058 | __ret = -EINVAL; \ | ||
2059 | } \ | ||
2060 | __ret; \ | ||
2061 | }) | ||
2062 | |||
2063 | /* called for all ebt_entry structures. */ | 2012 | /* called for all ebt_entry structures. */ |
2064 | static int size_entry_mwt(struct ebt_entry *entry, const unsigned char *base, | 2013 | static int size_entry_mwt(struct ebt_entry *entry, const unsigned char *base, |
2065 | unsigned int *total, | 2014 | unsigned int *total, |
@@ -2132,6 +2081,14 @@ static int size_entry_mwt(struct ebt_entry *entry, const unsigned char *base, | |||
2132 | } | 2081 | } |
2133 | } | 2082 | } |
2134 | 2083 | ||
2084 | if (state->buf_kern_start == NULL) { | ||
2085 | unsigned int offset = buf_start - (char *) base; | ||
2086 | |||
2087 | ret = xt_compat_add_offset(NFPROTO_BRIDGE, offset, new_offset); | ||
2088 | if (ret < 0) | ||
2089 | return ret; | ||
2090 | } | ||
2091 | |||
2135 | startoff = state->buf_user_offset - startoff; | 2092 | startoff = state->buf_user_offset - startoff; |
2136 | 2093 | ||
2137 | BUG_ON(*total < startoff); | 2094 | BUG_ON(*total < startoff); |
@@ -2240,6 +2197,7 @@ static int compat_do_replace(struct net *net, void __user *user, | |||
2240 | 2197 | ||
2241 | xt_compat_lock(NFPROTO_BRIDGE); | 2198 | xt_compat_lock(NFPROTO_BRIDGE); |
2242 | 2199 | ||
2200 | xt_compat_init_offsets(NFPROTO_BRIDGE, tmp.nentries); | ||
2243 | ret = compat_copy_entries(entries_tmp, tmp.entries_size, &state); | 2201 | ret = compat_copy_entries(entries_tmp, tmp.entries_size, &state); |
2244 | if (ret < 0) | 2202 | if (ret < 0) |
2245 | goto out_unlock; | 2203 | goto out_unlock; |
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c index 28e74488a329..a5a4c5dd5396 100644 --- a/net/ipv6/netfilter/ip6t_REJECT.c +++ b/net/ipv6/netfilter/ip6t_REJECT.c | |||
@@ -45,6 +45,8 @@ static void send_reset(struct net *net, struct sk_buff *oldskb) | |||
45 | int tcphoff, needs_ack; | 45 | int tcphoff, needs_ack; |
46 | const struct ipv6hdr *oip6h = ipv6_hdr(oldskb); | 46 | const struct ipv6hdr *oip6h = ipv6_hdr(oldskb); |
47 | struct ipv6hdr *ip6h; | 47 | struct ipv6hdr *ip6h; |
48 | #define DEFAULT_TOS_VALUE 0x0U | ||
49 | const __u8 tclass = DEFAULT_TOS_VALUE; | ||
48 | struct dst_entry *dst = NULL; | 50 | struct dst_entry *dst = NULL; |
49 | u8 proto; | 51 | u8 proto; |
50 | struct flowi6 fl6; | 52 | struct flowi6 fl6; |
@@ -124,7 +126,7 @@ static void send_reset(struct net *net, struct sk_buff *oldskb) | |||
124 | skb_put(nskb, sizeof(struct ipv6hdr)); | 126 | skb_put(nskb, sizeof(struct ipv6hdr)); |
125 | skb_reset_network_header(nskb); | 127 | skb_reset_network_header(nskb); |
126 | ip6h = ipv6_hdr(nskb); | 128 | ip6h = ipv6_hdr(nskb); |
127 | ip6h->version = 6; | 129 | *(__be32 *)ip6h = htonl(0x60000000 | (tclass << 20)); |
128 | ip6h->hop_limit = ip6_dst_hoplimit(dst); | 130 | ip6h->hop_limit = ip6_dst_hoplimit(dst); |
129 | ip6h->nexthdr = IPPROTO_TCP; | 131 | ip6h->nexthdr = IPPROTO_TCP; |
130 | ipv6_addr_copy(&ip6h->saddr, &oip6h->daddr); | 132 | ipv6_addr_copy(&ip6h->saddr, &oip6h->daddr); |
diff --git a/net/netfilter/ipvs/ip_vs_app.c b/net/netfilter/ipvs/ip_vs_app.c index 2dc6de13ac18..51f3af7c4743 100644 --- a/net/netfilter/ipvs/ip_vs_app.c +++ b/net/netfilter/ipvs/ip_vs_app.c | |||
@@ -576,7 +576,7 @@ static const struct file_operations ip_vs_app_fops = { | |||
576 | }; | 576 | }; |
577 | #endif | 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 | struct netns_ipvs *ipvs = net_ipvs(net); | 581 | struct netns_ipvs *ipvs = net_ipvs(net); |
582 | 582 | ||
@@ -585,26 +585,17 @@ static int __net_init __ip_vs_app_init(struct net *net) | |||
585 | return 0; | 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 | proc_net_remove(net, "ip_vs_app"); | 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 | int __init ip_vs_app_init(void) | 593 | int __init ip_vs_app_init(void) |
599 | { | 594 | { |
600 | int rv; | 595 | return 0; |
601 | |||
602 | rv = register_pernet_subsys(&ip_vs_app_ops); | ||
603 | return rv; | ||
604 | } | 596 | } |
605 | 597 | ||
606 | 598 | ||
607 | void ip_vs_app_cleanup(void) | 599 | void ip_vs_app_cleanup(void) |
608 | { | 600 | { |
609 | unregister_pernet_subsys(&ip_vs_app_ops); | ||
610 | } | 601 | } |
diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c index c97bd45975be..d3fd91bbba49 100644 --- a/net/netfilter/ipvs/ip_vs_conn.c +++ b/net/netfilter/ipvs/ip_vs_conn.c | |||
@@ -1258,22 +1258,17 @@ int __net_init __ip_vs_conn_init(struct net *net) | |||
1258 | return 0; | 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 | /* flush all the connection entries first */ | 1263 | /* flush all the connection entries first */ |
1264 | ip_vs_conn_flush(net); | 1264 | ip_vs_conn_flush(net); |
1265 | proc_net_remove(net, "ip_vs_conn"); | 1265 | proc_net_remove(net, "ip_vs_conn"); |
1266 | proc_net_remove(net, "ip_vs_conn_sync"); | 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 | int __init ip_vs_conn_init(void) | 1269 | int __init ip_vs_conn_init(void) |
1274 | { | 1270 | { |
1275 | int idx; | 1271 | int idx; |
1276 | int retc; | ||
1277 | 1272 | ||
1278 | /* Compute size and mask */ | 1273 | /* Compute size and mask */ |
1279 | ip_vs_conn_tab_size = 1 << ip_vs_conn_tab_bits; | 1274 | ip_vs_conn_tab_size = 1 << ip_vs_conn_tab_bits; |
@@ -1309,17 +1304,14 @@ int __init ip_vs_conn_init(void) | |||
1309 | rwlock_init(&__ip_vs_conntbl_lock_array[idx].l); | 1304 | rwlock_init(&__ip_vs_conntbl_lock_array[idx].l); |
1310 | } | 1305 | } |
1311 | 1306 | ||
1312 | retc = register_pernet_subsys(&ipvs_conn_ops); | ||
1313 | |||
1314 | /* calculate the random value for connection hash */ | 1307 | /* calculate the random value for connection hash */ |
1315 | get_random_bytes(&ip_vs_conn_rnd, sizeof(ip_vs_conn_rnd)); | 1308 | get_random_bytes(&ip_vs_conn_rnd, sizeof(ip_vs_conn_rnd)); |
1316 | 1309 | ||
1317 | return retc; | 1310 | return 0; |
1318 | } | 1311 | } |
1319 | 1312 | ||
1320 | void ip_vs_conn_cleanup(void) | 1313 | void ip_vs_conn_cleanup(void) |
1321 | { | 1314 | { |
1322 | unregister_pernet_subsys(&ipvs_conn_ops); | ||
1323 | /* Release the empty cache */ | 1315 | /* Release the empty cache */ |
1324 | kmem_cache_destroy(ip_vs_conn_cachep); | 1316 | kmem_cache_destroy(ip_vs_conn_cachep); |
1325 | vfree(ip_vs_conn_tab); | 1317 | vfree(ip_vs_conn_tab); |
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 07accf6b2401..a74dae6c5dbc 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c | |||
@@ -1113,6 +1113,9 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, int af) | |||
1113 | return NF_ACCEPT; | 1113 | return NF_ACCEPT; |
1114 | 1114 | ||
1115 | net = skb_net(skb); | 1115 | net = skb_net(skb); |
1116 | if (!net_ipvs(net)->enable) | ||
1117 | return NF_ACCEPT; | ||
1118 | |||
1116 | ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); | 1119 | ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); |
1117 | #ifdef CONFIG_IP_VS_IPV6 | 1120 | #ifdef CONFIG_IP_VS_IPV6 |
1118 | if (af == AF_INET6) { | 1121 | if (af == AF_INET6) { |
@@ -1343,6 +1346,7 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum) | |||
1343 | return NF_ACCEPT; /* The packet looks wrong, ignore */ | 1346 | return NF_ACCEPT; /* The packet looks wrong, ignore */ |
1344 | 1347 | ||
1345 | net = skb_net(skb); | 1348 | net = skb_net(skb); |
1349 | |||
1346 | pd = ip_vs_proto_data_get(net, cih->protocol); | 1350 | pd = ip_vs_proto_data_get(net, cih->protocol); |
1347 | if (!pd) | 1351 | if (!pd) |
1348 | return NF_ACCEPT; | 1352 | return NF_ACCEPT; |
@@ -1529,6 +1533,11 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af) | |||
1529 | IP_VS_DBG_ADDR(af, &iph.daddr), hooknum); | 1533 | IP_VS_DBG_ADDR(af, &iph.daddr), hooknum); |
1530 | return NF_ACCEPT; | 1534 | return NF_ACCEPT; |
1531 | } | 1535 | } |
1536 | /* ipvs enabled in this netns ? */ | ||
1537 | net = skb_net(skb); | ||
1538 | if (!net_ipvs(net)->enable) | ||
1539 | return NF_ACCEPT; | ||
1540 | |||
1532 | ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); | 1541 | ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); |
1533 | 1542 | ||
1534 | /* Bad... Do not break raw sockets */ | 1543 | /* Bad... Do not break raw sockets */ |
@@ -1562,7 +1571,6 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af) | |||
1562 | ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); | 1571 | ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); |
1563 | } | 1572 | } |
1564 | 1573 | ||
1565 | net = skb_net(skb); | ||
1566 | /* Protocol supported? */ | 1574 | /* Protocol supported? */ |
1567 | pd = ip_vs_proto_data_get(net, iph.protocol); | 1575 | pd = ip_vs_proto_data_get(net, iph.protocol); |
1568 | if (unlikely(!pd)) | 1576 | if (unlikely(!pd)) |
@@ -1588,7 +1596,6 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af) | |||
1588 | } | 1596 | } |
1589 | 1597 | ||
1590 | IP_VS_DBG_PKT(11, af, pp, skb, 0, "Incoming packet"); | 1598 | IP_VS_DBG_PKT(11, af, pp, skb, 0, "Incoming packet"); |
1591 | net = skb_net(skb); | ||
1592 | ipvs = net_ipvs(net); | 1599 | ipvs = net_ipvs(net); |
1593 | /* Check the server status */ | 1600 | /* Check the server status */ |
1594 | if (cp->dest && !(cp->dest->flags & IP_VS_DEST_F_AVAILABLE)) { | 1601 | if (cp->dest && !(cp->dest->flags & IP_VS_DEST_F_AVAILABLE)) { |
@@ -1743,10 +1750,16 @@ ip_vs_forward_icmp(unsigned int hooknum, struct sk_buff *skb, | |||
1743 | int (*okfn)(struct sk_buff *)) | 1750 | int (*okfn)(struct sk_buff *)) |
1744 | { | 1751 | { |
1745 | int r; | 1752 | int r; |
1753 | struct net *net; | ||
1746 | 1754 | ||
1747 | if (ip_hdr(skb)->protocol != IPPROTO_ICMP) | 1755 | if (ip_hdr(skb)->protocol != IPPROTO_ICMP) |
1748 | return NF_ACCEPT; | 1756 | return NF_ACCEPT; |
1749 | 1757 | ||
1758 | /* ipvs enabled in this netns ? */ | ||
1759 | net = skb_net(skb); | ||
1760 | if (!net_ipvs(net)->enable) | ||
1761 | return NF_ACCEPT; | ||
1762 | |||
1750 | return ip_vs_in_icmp(skb, &r, hooknum); | 1763 | return ip_vs_in_icmp(skb, &r, hooknum); |
1751 | } | 1764 | } |
1752 | 1765 | ||
@@ -1757,10 +1770,16 @@ ip_vs_forward_icmp_v6(unsigned int hooknum, struct sk_buff *skb, | |||
1757 | int (*okfn)(struct sk_buff *)) | 1770 | int (*okfn)(struct sk_buff *)) |
1758 | { | 1771 | { |
1759 | int r; | 1772 | int r; |
1773 | struct net *net; | ||
1760 | 1774 | ||
1761 | if (ipv6_hdr(skb)->nexthdr != IPPROTO_ICMPV6) | 1775 | if (ipv6_hdr(skb)->nexthdr != IPPROTO_ICMPV6) |
1762 | return NF_ACCEPT; | 1776 | return NF_ACCEPT; |
1763 | 1777 | ||
1778 | /* ipvs enabled in this netns ? */ | ||
1779 | net = skb_net(skb); | ||
1780 | if (!net_ipvs(net)->enable) | ||
1781 | return NF_ACCEPT; | ||
1782 | |||
1764 | return ip_vs_in_icmp_v6(skb, &r, hooknum); | 1783 | return ip_vs_in_icmp_v6(skb, &r, hooknum); |
1765 | } | 1784 | } |
1766 | #endif | 1785 | #endif |
@@ -1884,19 +1903,70 @@ static int __net_init __ip_vs_init(struct net *net) | |||
1884 | pr_err("%s(): no memory.\n", __func__); | 1903 | pr_err("%s(): no memory.\n", __func__); |
1885 | return -ENOMEM; | 1904 | return -ENOMEM; |
1886 | } | 1905 | } |
1906 | /* Hold the beast until a service is registerd */ | ||
1907 | ipvs->enable = 0; | ||
1887 | ipvs->net = net; | 1908 | ipvs->net = net; |
1888 | /* Counters used for creating unique names */ | 1909 | /* Counters used for creating unique names */ |
1889 | ipvs->gen = atomic_read(&ipvs_netns_cnt); | 1910 | ipvs->gen = atomic_read(&ipvs_netns_cnt); |
1890 | atomic_inc(&ipvs_netns_cnt); | 1911 | atomic_inc(&ipvs_netns_cnt); |
1891 | net->ipvs = ipvs; | 1912 | net->ipvs = ipvs; |
1913 | |||
1914 | if (__ip_vs_estimator_init(net) < 0) | ||
1915 | goto estimator_fail; | ||
1916 | |||
1917 | if (__ip_vs_control_init(net) < 0) | ||
1918 | goto control_fail; | ||
1919 | |||
1920 | if (__ip_vs_protocol_init(net) < 0) | ||
1921 | goto protocol_fail; | ||
1922 | |||
1923 | if (__ip_vs_app_init(net) < 0) | ||
1924 | goto app_fail; | ||
1925 | |||
1926 | if (__ip_vs_conn_init(net) < 0) | ||
1927 | goto conn_fail; | ||
1928 | |||
1929 | if (__ip_vs_sync_init(net) < 0) | ||
1930 | goto sync_fail; | ||
1931 | |||
1892 | printk(KERN_INFO "IPVS: Creating netns size=%zu id=%d\n", | 1932 | printk(KERN_INFO "IPVS: Creating netns size=%zu id=%d\n", |
1893 | sizeof(struct netns_ipvs), ipvs->gen); | 1933 | sizeof(struct netns_ipvs), ipvs->gen); |
1894 | return 0; | 1934 | return 0; |
1935 | /* | ||
1936 | * Error handling | ||
1937 | */ | ||
1938 | |||
1939 | sync_fail: | ||
1940 | __ip_vs_conn_cleanup(net); | ||
1941 | conn_fail: | ||
1942 | __ip_vs_app_cleanup(net); | ||
1943 | app_fail: | ||
1944 | __ip_vs_protocol_cleanup(net); | ||
1945 | protocol_fail: | ||
1946 | __ip_vs_control_cleanup(net); | ||
1947 | control_fail: | ||
1948 | __ip_vs_estimator_cleanup(net); | ||
1949 | estimator_fail: | ||
1950 | return -ENOMEM; | ||
1895 | } | 1951 | } |
1896 | 1952 | ||
1897 | static void __net_exit __ip_vs_cleanup(struct net *net) | 1953 | static void __net_exit __ip_vs_cleanup(struct net *net) |
1898 | { | 1954 | { |
1899 | IP_VS_DBG(10, "ipvs netns %d released\n", net_ipvs(net)->gen); | 1955 | __ip_vs_service_cleanup(net); /* ip_vs_flush() with locks */ |
1956 | __ip_vs_conn_cleanup(net); | ||
1957 | __ip_vs_app_cleanup(net); | ||
1958 | __ip_vs_protocol_cleanup(net); | ||
1959 | __ip_vs_control_cleanup(net); | ||
1960 | __ip_vs_estimator_cleanup(net); | ||
1961 | IP_VS_DBG(2, "ipvs netns %d released\n", net_ipvs(net)->gen); | ||
1962 | } | ||
1963 | |||
1964 | static void __net_exit __ip_vs_dev_cleanup(struct net *net) | ||
1965 | { | ||
1966 | EnterFunction(2); | ||
1967 | net_ipvs(net)->enable = 0; /* Disable packet reception */ | ||
1968 | __ip_vs_sync_cleanup(net); | ||
1969 | LeaveFunction(2); | ||
1900 | } | 1970 | } |
1901 | 1971 | ||
1902 | static struct pernet_operations ipvs_core_ops = { | 1972 | static struct pernet_operations ipvs_core_ops = { |
@@ -1906,6 +1976,10 @@ static struct pernet_operations ipvs_core_ops = { | |||
1906 | .size = sizeof(struct netns_ipvs), | 1976 | .size = sizeof(struct netns_ipvs), |
1907 | }; | 1977 | }; |
1908 | 1978 | ||
1979 | static struct pernet_operations ipvs_core_dev_ops = { | ||
1980 | .exit = __ip_vs_dev_cleanup, | ||
1981 | }; | ||
1982 | |||
1909 | /* | 1983 | /* |
1910 | * Initialize IP Virtual Server | 1984 | * Initialize IP Virtual Server |
1911 | */ | 1985 | */ |
@@ -1913,10 +1987,6 @@ static int __init ip_vs_init(void) | |||
1913 | { | 1987 | { |
1914 | int ret; | 1988 | int ret; |
1915 | 1989 | ||
1916 | ret = register_pernet_subsys(&ipvs_core_ops); /* Alloc ip_vs struct */ | ||
1917 | if (ret < 0) | ||
1918 | return ret; | ||
1919 | |||
1920 | ip_vs_estimator_init(); | 1990 | ip_vs_estimator_init(); |
1921 | ret = ip_vs_control_init(); | 1991 | ret = ip_vs_control_init(); |
1922 | if (ret < 0) { | 1992 | if (ret < 0) { |
@@ -1944,15 +2014,28 @@ static int __init ip_vs_init(void) | |||
1944 | goto cleanup_conn; | 2014 | goto cleanup_conn; |
1945 | } | 2015 | } |
1946 | 2016 | ||
2017 | ret = register_pernet_subsys(&ipvs_core_ops); /* Alloc ip_vs struct */ | ||
2018 | if (ret < 0) | ||
2019 | goto cleanup_sync; | ||
2020 | |||
2021 | ret = register_pernet_device(&ipvs_core_dev_ops); | ||
2022 | if (ret < 0) | ||
2023 | goto cleanup_sub; | ||
2024 | |||
1947 | ret = nf_register_hooks(ip_vs_ops, ARRAY_SIZE(ip_vs_ops)); | 2025 | ret = nf_register_hooks(ip_vs_ops, ARRAY_SIZE(ip_vs_ops)); |
1948 | if (ret < 0) { | 2026 | if (ret < 0) { |
1949 | pr_err("can't register hooks.\n"); | 2027 | pr_err("can't register hooks.\n"); |
1950 | goto cleanup_sync; | 2028 | goto cleanup_dev; |
1951 | } | 2029 | } |
1952 | 2030 | ||
1953 | pr_info("ipvs loaded.\n"); | 2031 | pr_info("ipvs loaded.\n"); |
2032 | |||
1954 | return ret; | 2033 | return ret; |
1955 | 2034 | ||
2035 | cleanup_dev: | ||
2036 | unregister_pernet_device(&ipvs_core_dev_ops); | ||
2037 | cleanup_sub: | ||
2038 | unregister_pernet_subsys(&ipvs_core_ops); | ||
1956 | cleanup_sync: | 2039 | cleanup_sync: |
1957 | ip_vs_sync_cleanup(); | 2040 | ip_vs_sync_cleanup(); |
1958 | cleanup_conn: | 2041 | cleanup_conn: |
@@ -1964,20 +2047,20 @@ cleanup_sync: | |||
1964 | ip_vs_control_cleanup(); | 2047 | ip_vs_control_cleanup(); |
1965 | cleanup_estimator: | 2048 | cleanup_estimator: |
1966 | ip_vs_estimator_cleanup(); | 2049 | ip_vs_estimator_cleanup(); |
1967 | unregister_pernet_subsys(&ipvs_core_ops); /* free ip_vs struct */ | ||
1968 | return ret; | 2050 | return ret; |
1969 | } | 2051 | } |
1970 | 2052 | ||
1971 | static void __exit ip_vs_cleanup(void) | 2053 | static void __exit ip_vs_cleanup(void) |
1972 | { | 2054 | { |
1973 | nf_unregister_hooks(ip_vs_ops, ARRAY_SIZE(ip_vs_ops)); | 2055 | nf_unregister_hooks(ip_vs_ops, ARRAY_SIZE(ip_vs_ops)); |
2056 | unregister_pernet_device(&ipvs_core_dev_ops); | ||
2057 | unregister_pernet_subsys(&ipvs_core_ops); /* free ip_vs struct */ | ||
1974 | ip_vs_sync_cleanup(); | 2058 | ip_vs_sync_cleanup(); |
1975 | ip_vs_conn_cleanup(); | 2059 | ip_vs_conn_cleanup(); |
1976 | ip_vs_app_cleanup(); | 2060 | ip_vs_app_cleanup(); |
1977 | ip_vs_protocol_cleanup(); | 2061 | ip_vs_protocol_cleanup(); |
1978 | ip_vs_control_cleanup(); | 2062 | ip_vs_control_cleanup(); |
1979 | ip_vs_estimator_cleanup(); | 2063 | ip_vs_estimator_cleanup(); |
1980 | unregister_pernet_subsys(&ipvs_core_ops); /* free ip_vs struct */ | ||
1981 | pr_info("ipvs unloaded.\n"); | 2064 | pr_info("ipvs unloaded.\n"); |
1982 | } | 2065 | } |
1983 | 2066 | ||
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index ae47090bf45f..ea722810faf3 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c | |||
@@ -69,6 +69,11 @@ int ip_vs_get_debug_level(void) | |||
69 | } | 69 | } |
70 | #endif | 70 | #endif |
71 | 71 | ||
72 | |||
73 | /* Protos */ | ||
74 | static void __ip_vs_del_service(struct ip_vs_service *svc); | ||
75 | |||
76 | |||
72 | #ifdef CONFIG_IP_VS_IPV6 | 77 | #ifdef CONFIG_IP_VS_IPV6 |
73 | /* Taken from rt6_fill_node() in net/ipv6/route.c, is there a better way? */ | 78 | /* Taken from rt6_fill_node() in net/ipv6/route.c, is there a better way? */ |
74 | static int __ip_vs_addr_is_local_v6(struct net *net, | 79 | static int __ip_vs_addr_is_local_v6(struct net *net, |
@@ -1214,6 +1219,8 @@ ip_vs_add_service(struct net *net, struct ip_vs_service_user_kern *u, | |||
1214 | write_unlock_bh(&__ip_vs_svc_lock); | 1219 | write_unlock_bh(&__ip_vs_svc_lock); |
1215 | 1220 | ||
1216 | *svc_p = svc; | 1221 | *svc_p = svc; |
1222 | /* Now there is a service - full throttle */ | ||
1223 | ipvs->enable = 1; | ||
1217 | return 0; | 1224 | return 0; |
1218 | 1225 | ||
1219 | 1226 | ||
@@ -1472,6 +1479,84 @@ static int ip_vs_flush(struct net *net) | |||
1472 | return 0; | 1479 | return 0; |
1473 | } | 1480 | } |
1474 | 1481 | ||
1482 | /* | ||
1483 | * Delete service by {netns} in the service table. | ||
1484 | * Called by __ip_vs_cleanup() | ||
1485 | */ | ||
1486 | void __ip_vs_service_cleanup(struct net *net) | ||
1487 | { | ||
1488 | EnterFunction(2); | ||
1489 | /* Check for "full" addressed entries */ | ||
1490 | mutex_lock(&__ip_vs_mutex); | ||
1491 | ip_vs_flush(net); | ||
1492 | mutex_unlock(&__ip_vs_mutex); | ||
1493 | LeaveFunction(2); | ||
1494 | } | ||
1495 | /* | ||
1496 | * Release dst hold by dst_cache | ||
1497 | */ | ||
1498 | static inline void | ||
1499 | __ip_vs_dev_reset(struct ip_vs_dest *dest, struct net_device *dev) | ||
1500 | { | ||
1501 | spin_lock_bh(&dest->dst_lock); | ||
1502 | if (dest->dst_cache && dest->dst_cache->dev == dev) { | ||
1503 | IP_VS_DBG_BUF(3, "Reset dev:%s dest %s:%u ,dest->refcnt=%d\n", | ||
1504 | dev->name, | ||
1505 | IP_VS_DBG_ADDR(dest->af, &dest->addr), | ||
1506 | ntohs(dest->port), | ||
1507 | atomic_read(&dest->refcnt)); | ||
1508 | ip_vs_dst_reset(dest); | ||
1509 | } | ||
1510 | spin_unlock_bh(&dest->dst_lock); | ||
1511 | |||
1512 | } | ||
1513 | /* | ||
1514 | * Netdev event receiver | ||
1515 | * Currently only NETDEV_UNREGISTER is handled, i.e. if we hold a reference to | ||
1516 | * a device that is "unregister" it must be released. | ||
1517 | */ | ||
1518 | static int ip_vs_dst_event(struct notifier_block *this, unsigned long event, | ||
1519 | void *ptr) | ||
1520 | { | ||
1521 | struct net_device *dev = ptr; | ||
1522 | struct net *net = dev_net(dev); | ||
1523 | struct ip_vs_service *svc; | ||
1524 | struct ip_vs_dest *dest; | ||
1525 | unsigned int idx; | ||
1526 | |||
1527 | if (event != NETDEV_UNREGISTER) | ||
1528 | return NOTIFY_DONE; | ||
1529 | IP_VS_DBG(3, "%s() dev=%s\n", __func__, dev->name); | ||
1530 | EnterFunction(2); | ||
1531 | mutex_lock(&__ip_vs_mutex); | ||
1532 | for (idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) { | ||
1533 | list_for_each_entry(svc, &ip_vs_svc_table[idx], s_list) { | ||
1534 | if (net_eq(svc->net, net)) { | ||
1535 | list_for_each_entry(dest, &svc->destinations, | ||
1536 | n_list) { | ||
1537 | __ip_vs_dev_reset(dest, dev); | ||
1538 | } | ||
1539 | } | ||
1540 | } | ||
1541 | |||
1542 | list_for_each_entry(svc, &ip_vs_svc_fwm_table[idx], f_list) { | ||
1543 | if (net_eq(svc->net, net)) { | ||
1544 | list_for_each_entry(dest, &svc->destinations, | ||
1545 | n_list) { | ||
1546 | __ip_vs_dev_reset(dest, dev); | ||
1547 | } | ||
1548 | } | ||
1549 | |||
1550 | } | ||
1551 | } | ||
1552 | |||
1553 | list_for_each_entry(dest, &net_ipvs(net)->dest_trash, n_list) { | ||
1554 | __ip_vs_dev_reset(dest, dev); | ||
1555 | } | ||
1556 | mutex_unlock(&__ip_vs_mutex); | ||
1557 | LeaveFunction(2); | ||
1558 | return NOTIFY_DONE; | ||
1559 | } | ||
1475 | 1560 | ||
1476 | /* | 1561 | /* |
1477 | * Zero counters in a service or all services | 1562 | * Zero counters in a service or all services |
@@ -3588,6 +3673,10 @@ void __net_init __ip_vs_control_cleanup_sysctl(struct net *net) { } | |||
3588 | 3673 | ||
3589 | #endif | 3674 | #endif |
3590 | 3675 | ||
3676 | static struct notifier_block ip_vs_dst_notifier = { | ||
3677 | .notifier_call = ip_vs_dst_event, | ||
3678 | }; | ||
3679 | |||
3591 | int __net_init __ip_vs_control_init(struct net *net) | 3680 | int __net_init __ip_vs_control_init(struct net *net) |
3592 | { | 3681 | { |
3593 | int idx; | 3682 | int idx; |
@@ -3626,7 +3715,7 @@ err: | |||
3626 | return -ENOMEM; | 3715 | return -ENOMEM; |
3627 | } | 3716 | } |
3628 | 3717 | ||
3629 | static void __net_exit __ip_vs_control_cleanup(struct net *net) | 3718 | void __net_exit __ip_vs_control_cleanup(struct net *net) |
3630 | { | 3719 | { |
3631 | struct netns_ipvs *ipvs = net_ipvs(net); | 3720 | struct netns_ipvs *ipvs = net_ipvs(net); |
3632 | 3721 | ||
@@ -3639,11 +3728,6 @@ static void __net_exit __ip_vs_control_cleanup(struct net *net) | |||
3639 | free_percpu(ipvs->tot_stats.cpustats); | 3728 | free_percpu(ipvs->tot_stats.cpustats); |
3640 | } | 3729 | } |
3641 | 3730 | ||
3642 | static struct pernet_operations ipvs_control_ops = { | ||
3643 | .init = __ip_vs_control_init, | ||
3644 | .exit = __ip_vs_control_cleanup, | ||
3645 | }; | ||
3646 | |||
3647 | int __init ip_vs_control_init(void) | 3731 | int __init ip_vs_control_init(void) |
3648 | { | 3732 | { |
3649 | int idx; | 3733 | int idx; |
@@ -3657,33 +3741,32 @@ int __init ip_vs_control_init(void) | |||
3657 | INIT_LIST_HEAD(&ip_vs_svc_fwm_table[idx]); | 3741 | INIT_LIST_HEAD(&ip_vs_svc_fwm_table[idx]); |
3658 | } | 3742 | } |
3659 | 3743 | ||
3660 | ret = register_pernet_subsys(&ipvs_control_ops); | ||
3661 | if (ret) { | ||
3662 | pr_err("cannot register namespace.\n"); | ||
3663 | goto err; | ||
3664 | } | ||
3665 | |||
3666 | smp_wmb(); /* Do we really need it now ? */ | 3744 | smp_wmb(); /* Do we really need it now ? */ |
3667 | 3745 | ||
3668 | ret = nf_register_sockopt(&ip_vs_sockopts); | 3746 | ret = nf_register_sockopt(&ip_vs_sockopts); |
3669 | if (ret) { | 3747 | if (ret) { |
3670 | pr_err("cannot register sockopt.\n"); | 3748 | pr_err("cannot register sockopt.\n"); |
3671 | goto err_net; | 3749 | goto err_sock; |
3672 | } | 3750 | } |
3673 | 3751 | ||
3674 | ret = ip_vs_genl_register(); | 3752 | ret = ip_vs_genl_register(); |
3675 | if (ret) { | 3753 | if (ret) { |
3676 | pr_err("cannot register Generic Netlink interface.\n"); | 3754 | pr_err("cannot register Generic Netlink interface.\n"); |
3677 | nf_unregister_sockopt(&ip_vs_sockopts); | 3755 | goto err_genl; |
3678 | goto err_net; | ||
3679 | } | 3756 | } |
3680 | 3757 | ||
3758 | ret = register_netdevice_notifier(&ip_vs_dst_notifier); | ||
3759 | if (ret < 0) | ||
3760 | goto err_notf; | ||
3761 | |||
3681 | LeaveFunction(2); | 3762 | LeaveFunction(2); |
3682 | return 0; | 3763 | return 0; |
3683 | 3764 | ||
3684 | err_net: | 3765 | err_notf: |
3685 | unregister_pernet_subsys(&ipvs_control_ops); | 3766 | ip_vs_genl_unregister(); |
3686 | err: | 3767 | err_genl: |
3768 | nf_unregister_sockopt(&ip_vs_sockopts); | ||
3769 | err_sock: | ||
3687 | return ret; | 3770 | return ret; |
3688 | } | 3771 | } |
3689 | 3772 | ||
@@ -3691,7 +3774,6 @@ err: | |||
3691 | void ip_vs_control_cleanup(void) | 3774 | void ip_vs_control_cleanup(void) |
3692 | { | 3775 | { |
3693 | EnterFunction(2); | 3776 | EnterFunction(2); |
3694 | unregister_pernet_subsys(&ipvs_control_ops); | ||
3695 | ip_vs_genl_unregister(); | 3777 | ip_vs_genl_unregister(); |
3696 | nf_unregister_sockopt(&ip_vs_sockopts); | 3778 | nf_unregister_sockopt(&ip_vs_sockopts); |
3697 | LeaveFunction(2); | 3779 | LeaveFunction(2); |
diff --git a/net/netfilter/ipvs/ip_vs_est.c b/net/netfilter/ipvs/ip_vs_est.c index 8c8766ca56ad..508cce98777c 100644 --- a/net/netfilter/ipvs/ip_vs_est.c +++ b/net/netfilter/ipvs/ip_vs_est.c | |||
@@ -192,7 +192,7 @@ void ip_vs_read_estimator(struct ip_vs_stats_user *dst, | |||
192 | dst->outbps = (e->outbps + 0xF) >> 5; | 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 | struct netns_ipvs *ipvs = net_ipvs(net); | 197 | struct netns_ipvs *ipvs = net_ipvs(net); |
198 | 198 | ||
@@ -203,24 +203,16 @@ static int __net_init __ip_vs_estimator_init(struct net *net) | |||
203 | return 0; | 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 | del_timer_sync(&net_ipvs(net)->est_timer); | 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 | int __init ip_vs_estimator_init(void) | 211 | int __init ip_vs_estimator_init(void) |
216 | { | 212 | { |
217 | int rv; | 213 | return 0; |
218 | |||
219 | rv = register_pernet_subsys(&ip_vs_app_ops); | ||
220 | return rv; | ||
221 | } | 214 | } |
222 | 215 | ||
223 | void ip_vs_estimator_cleanup(void) | 216 | void ip_vs_estimator_cleanup(void) |
224 | { | 217 | { |
225 | unregister_pernet_subsys(&ip_vs_app_ops); | ||
226 | } | 218 | } |
diff --git a/net/netfilter/ipvs/ip_vs_proto.c b/net/netfilter/ipvs/ip_vs_proto.c index 17484a4416ef..eb86028536fc 100644 --- a/net/netfilter/ipvs/ip_vs_proto.c +++ b/net/netfilter/ipvs/ip_vs_proto.c | |||
@@ -316,7 +316,7 @@ ip_vs_tcpudp_debug_packet(int af, struct ip_vs_protocol *pp, | |||
316 | /* | 316 | /* |
317 | * per network name-space init | 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 | #ifdef CONFIG_IP_VS_PROTO_TCP | 321 | #ifdef CONFIG_IP_VS_PROTO_TCP |
322 | register_ip_vs_proto_netns(net, &ip_vs_protocol_tcp); | 322 | register_ip_vs_proto_netns(net, &ip_vs_protocol_tcp); |
@@ -336,7 +336,7 @@ static int __net_init __ip_vs_protocol_init(struct net *net) | |||
336 | return 0; | 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 | struct netns_ipvs *ipvs = net_ipvs(net); | 341 | struct netns_ipvs *ipvs = net_ipvs(net); |
342 | struct ip_vs_proto_data *pd; | 342 | struct ip_vs_proto_data *pd; |
@@ -349,11 +349,6 @@ static void __net_exit __ip_vs_protocol_cleanup(struct net *net) | |||
349 | } | 349 | } |
350 | } | 350 | } |
351 | 351 | ||
352 | static struct pernet_operations ipvs_proto_ops = { | ||
353 | .init = __ip_vs_protocol_init, | ||
354 | .exit = __ip_vs_protocol_cleanup, | ||
355 | }; | ||
356 | |||
357 | int __init ip_vs_protocol_init(void) | 352 | int __init ip_vs_protocol_init(void) |
358 | { | 353 | { |
359 | char protocols[64]; | 354 | char protocols[64]; |
@@ -382,7 +377,6 @@ int __init ip_vs_protocol_init(void) | |||
382 | REGISTER_PROTOCOL(&ip_vs_protocol_esp); | 377 | REGISTER_PROTOCOL(&ip_vs_protocol_esp); |
383 | #endif | 378 | #endif |
384 | pr_info("Registered protocols (%s)\n", &protocols[2]); | 379 | pr_info("Registered protocols (%s)\n", &protocols[2]); |
385 | return register_pernet_subsys(&ipvs_proto_ops); | ||
386 | 380 | ||
387 | return 0; | 381 | return 0; |
388 | } | 382 | } |
@@ -393,7 +387,6 @@ void ip_vs_protocol_cleanup(void) | |||
393 | struct ip_vs_protocol *pp; | 387 | struct ip_vs_protocol *pp; |
394 | int i; | 388 | int i; |
395 | 389 | ||
396 | unregister_pernet_subsys(&ipvs_proto_ops); | ||
397 | /* unregister all the ipvs protocols */ | 390 | /* unregister all the ipvs protocols */ |
398 | for (i = 0; i < IP_VS_PROTO_TAB_SIZE; i++) { | 391 | for (i = 0; i < IP_VS_PROTO_TAB_SIZE; i++) { |
399 | while ((pp = ip_vs_proto_table[i]) != NULL) | 392 | while ((pp = ip_vs_proto_table[i]) != NULL) |
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c index 3e7961e85e9c..e292e5bddc70 100644 --- a/net/netfilter/ipvs/ip_vs_sync.c +++ b/net/netfilter/ipvs/ip_vs_sync.c | |||
@@ -1303,13 +1303,18 @@ static struct socket *make_send_sock(struct net *net) | |||
1303 | struct socket *sock; | 1303 | struct socket *sock; |
1304 | int result; | 1304 | int result; |
1305 | 1305 | ||
1306 | /* First create a socket */ | 1306 | /* First create a socket move it to right name space later */ |
1307 | result = __sock_create(net, PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock, 1); | 1307 | result = sock_create_kern(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock); |
1308 | if (result < 0) { | 1308 | if (result < 0) { |
1309 | pr_err("Error during creation of socket; terminating\n"); | 1309 | pr_err("Error during creation of socket; terminating\n"); |
1310 | return ERR_PTR(result); | 1310 | return ERR_PTR(result); |
1311 | } | 1311 | } |
1312 | 1312 | /* | |
1313 | * Kernel sockets that are a part of a namespace, should not | ||
1314 | * hold a reference to a namespace in order to allow to stop it. | ||
1315 | * After sk_change_net should be released using sk_release_kernel. | ||
1316 | */ | ||
1317 | sk_change_net(sock->sk, net); | ||
1313 | result = set_mcast_if(sock->sk, ipvs->master_mcast_ifn); | 1318 | result = set_mcast_if(sock->sk, ipvs->master_mcast_ifn); |
1314 | if (result < 0) { | 1319 | if (result < 0) { |
1315 | pr_err("Error setting outbound mcast interface\n"); | 1320 | pr_err("Error setting outbound mcast interface\n"); |
@@ -1334,8 +1339,8 @@ static struct socket *make_send_sock(struct net *net) | |||
1334 | 1339 | ||
1335 | return sock; | 1340 | return sock; |
1336 | 1341 | ||
1337 | error: | 1342 | error: |
1338 | sock_release(sock); | 1343 | sk_release_kernel(sock->sk); |
1339 | return ERR_PTR(result); | 1344 | return ERR_PTR(result); |
1340 | } | 1345 | } |
1341 | 1346 | ||
@@ -1350,12 +1355,17 @@ static struct socket *make_receive_sock(struct net *net) | |||
1350 | int result; | 1355 | int result; |
1351 | 1356 | ||
1352 | /* First create a socket */ | 1357 | /* First create a socket */ |
1353 | result = __sock_create(net, PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock, 1); | 1358 | result = sock_create_kern(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock); |
1354 | if (result < 0) { | 1359 | if (result < 0) { |
1355 | pr_err("Error during creation of socket; terminating\n"); | 1360 | pr_err("Error during creation of socket; terminating\n"); |
1356 | return ERR_PTR(result); | 1361 | return ERR_PTR(result); |
1357 | } | 1362 | } |
1358 | 1363 | /* | |
1364 | * Kernel sockets that are a part of a namespace, should not | ||
1365 | * hold a reference to a namespace in order to allow to stop it. | ||
1366 | * After sk_change_net should be released using sk_release_kernel. | ||
1367 | */ | ||
1368 | sk_change_net(sock->sk, net); | ||
1359 | /* it is equivalent to the REUSEADDR option in user-space */ | 1369 | /* it is equivalent to the REUSEADDR option in user-space */ |
1360 | sock->sk->sk_reuse = 1; | 1370 | sock->sk->sk_reuse = 1; |
1361 | 1371 | ||
@@ -1377,8 +1387,8 @@ static struct socket *make_receive_sock(struct net *net) | |||
1377 | 1387 | ||
1378 | return sock; | 1388 | return sock; |
1379 | 1389 | ||
1380 | error: | 1390 | error: |
1381 | sock_release(sock); | 1391 | sk_release_kernel(sock->sk); |
1382 | return ERR_PTR(result); | 1392 | return ERR_PTR(result); |
1383 | } | 1393 | } |
1384 | 1394 | ||
@@ -1473,7 +1483,7 @@ static int sync_thread_master(void *data) | |||
1473 | ip_vs_sync_buff_release(sb); | 1483 | ip_vs_sync_buff_release(sb); |
1474 | 1484 | ||
1475 | /* release the sending multicast socket */ | 1485 | /* release the sending multicast socket */ |
1476 | sock_release(tinfo->sock); | 1486 | sk_release_kernel(tinfo->sock->sk); |
1477 | kfree(tinfo); | 1487 | kfree(tinfo); |
1478 | 1488 | ||
1479 | return 0; | 1489 | return 0; |
@@ -1513,7 +1523,7 @@ static int sync_thread_backup(void *data) | |||
1513 | } | 1523 | } |
1514 | 1524 | ||
1515 | /* release the sending multicast socket */ | 1525 | /* release the sending multicast socket */ |
1516 | sock_release(tinfo->sock); | 1526 | sk_release_kernel(tinfo->sock->sk); |
1517 | kfree(tinfo->buf); | 1527 | kfree(tinfo->buf); |
1518 | kfree(tinfo); | 1528 | kfree(tinfo); |
1519 | 1529 | ||
@@ -1601,7 +1611,7 @@ outtinfo: | |||
1601 | outbuf: | 1611 | outbuf: |
1602 | kfree(buf); | 1612 | kfree(buf); |
1603 | outsocket: | 1613 | outsocket: |
1604 | sock_release(sock); | 1614 | sk_release_kernel(sock->sk); |
1605 | out: | 1615 | out: |
1606 | return result; | 1616 | return result; |
1607 | } | 1617 | } |
@@ -1610,6 +1620,7 @@ out: | |||
1610 | int stop_sync_thread(struct net *net, int state) | 1620 | int stop_sync_thread(struct net *net, int state) |
1611 | { | 1621 | { |
1612 | struct netns_ipvs *ipvs = net_ipvs(net); | 1622 | struct netns_ipvs *ipvs = net_ipvs(net); |
1623 | int retc = -EINVAL; | ||
1613 | 1624 | ||
1614 | IP_VS_DBG(7, "%s(): pid %d\n", __func__, task_pid_nr(current)); | 1625 | IP_VS_DBG(7, "%s(): pid %d\n", __func__, task_pid_nr(current)); |
1615 | 1626 | ||
@@ -1629,7 +1640,7 @@ int stop_sync_thread(struct net *net, int state) | |||
1629 | spin_lock_bh(&ipvs->sync_lock); | 1640 | spin_lock_bh(&ipvs->sync_lock); |
1630 | ipvs->sync_state &= ~IP_VS_STATE_MASTER; | 1641 | ipvs->sync_state &= ~IP_VS_STATE_MASTER; |
1631 | spin_unlock_bh(&ipvs->sync_lock); | 1642 | spin_unlock_bh(&ipvs->sync_lock); |
1632 | kthread_stop(ipvs->master_thread); | 1643 | retc = kthread_stop(ipvs->master_thread); |
1633 | ipvs->master_thread = NULL; | 1644 | ipvs->master_thread = NULL; |
1634 | } else if (state == IP_VS_STATE_BACKUP) { | 1645 | } else if (state == IP_VS_STATE_BACKUP) { |
1635 | if (!ipvs->backup_thread) | 1646 | if (!ipvs->backup_thread) |
@@ -1639,22 +1650,20 @@ int stop_sync_thread(struct net *net, int state) | |||
1639 | task_pid_nr(ipvs->backup_thread)); | 1650 | task_pid_nr(ipvs->backup_thread)); |
1640 | 1651 | ||
1641 | ipvs->sync_state &= ~IP_VS_STATE_BACKUP; | 1652 | ipvs->sync_state &= ~IP_VS_STATE_BACKUP; |
1642 | kthread_stop(ipvs->backup_thread); | 1653 | retc = kthread_stop(ipvs->backup_thread); |
1643 | ipvs->backup_thread = NULL; | 1654 | ipvs->backup_thread = NULL; |
1644 | } else { | ||
1645 | return -EINVAL; | ||
1646 | } | 1655 | } |
1647 | 1656 | ||
1648 | /* decrease the module use count */ | 1657 | /* decrease the module use count */ |
1649 | ip_vs_use_count_dec(); | 1658 | ip_vs_use_count_dec(); |
1650 | 1659 | ||
1651 | return 0; | 1660 | return retc; |
1652 | } | 1661 | } |
1653 | 1662 | ||
1654 | /* | 1663 | /* |
1655 | * Initialize data struct for each netns | 1664 | * Initialize data struct for each netns |
1656 | */ | 1665 | */ |
1657 | static int __net_init __ip_vs_sync_init(struct net *net) | 1666 | int __net_init __ip_vs_sync_init(struct net *net) |
1658 | { | 1667 | { |
1659 | struct netns_ipvs *ipvs = net_ipvs(net); | 1668 | struct netns_ipvs *ipvs = net_ipvs(net); |
1660 | 1669 | ||
@@ -1668,24 +1677,24 @@ static int __net_init __ip_vs_sync_init(struct net *net) | |||
1668 | return 0; | 1677 | return 0; |
1669 | } | 1678 | } |
1670 | 1679 | ||
1671 | static void __ip_vs_sync_cleanup(struct net *net) | 1680 | void __ip_vs_sync_cleanup(struct net *net) |
1672 | { | 1681 | { |
1673 | stop_sync_thread(net, IP_VS_STATE_MASTER); | 1682 | int retc; |
1674 | stop_sync_thread(net, IP_VS_STATE_BACKUP); | ||
1675 | } | ||
1676 | 1683 | ||
1677 | static struct pernet_operations ipvs_sync_ops = { | 1684 | retc = stop_sync_thread(net, IP_VS_STATE_MASTER); |
1678 | .init = __ip_vs_sync_init, | 1685 | if (retc && retc != -ESRCH) |
1679 | .exit = __ip_vs_sync_cleanup, | 1686 | pr_err("Failed to stop Master Daemon\n"); |
1680 | }; | ||
1681 | 1687 | ||
1688 | retc = stop_sync_thread(net, IP_VS_STATE_BACKUP); | ||
1689 | if (retc && retc != -ESRCH) | ||
1690 | pr_err("Failed to stop Backup Daemon\n"); | ||
1691 | } | ||
1682 | 1692 | ||
1683 | int __init ip_vs_sync_init(void) | 1693 | int __init ip_vs_sync_init(void) |
1684 | { | 1694 | { |
1685 | return register_pernet_subsys(&ipvs_sync_ops); | 1695 | return 0; |
1686 | } | 1696 | } |
1687 | 1697 | ||
1688 | void ip_vs_sync_cleanup(void) | 1698 | void ip_vs_sync_cleanup(void) |
1689 | { | 1699 | { |
1690 | unregister_pernet_subsys(&ipvs_sync_ops); | ||
1691 | } | 1700 | } |
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 30bf8a167fc8..482e90c61850 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
@@ -1334,6 +1334,7 @@ ctnetlink_create_conntrack(struct net *net, u16 zone, | |||
1334 | struct nf_conn *ct; | 1334 | struct nf_conn *ct; |
1335 | int err = -EINVAL; | 1335 | int err = -EINVAL; |
1336 | struct nf_conntrack_helper *helper; | 1336 | struct nf_conntrack_helper *helper; |
1337 | struct nf_conn_tstamp *tstamp; | ||
1337 | 1338 | ||
1338 | ct = nf_conntrack_alloc(net, zone, otuple, rtuple, GFP_ATOMIC); | 1339 | ct = nf_conntrack_alloc(net, zone, otuple, rtuple, GFP_ATOMIC); |
1339 | if (IS_ERR(ct)) | 1340 | if (IS_ERR(ct)) |
@@ -1451,6 +1452,9 @@ ctnetlink_create_conntrack(struct net *net, u16 zone, | |||
1451 | __set_bit(IPS_EXPECTED_BIT, &ct->status); | 1452 | __set_bit(IPS_EXPECTED_BIT, &ct->status); |
1452 | ct->master = master_ct; | 1453 | ct->master = master_ct; |
1453 | } | 1454 | } |
1455 | tstamp = nf_conn_tstamp_find(ct); | ||
1456 | if (tstamp) | ||
1457 | tstamp->start = ktime_to_ns(ktime_get_real()); | ||
1454 | 1458 | ||
1455 | add_timer(&ct->timeout); | 1459 | add_timer(&ct->timeout); |
1456 | nf_conntrack_hash_insert(ct); | 1460 | nf_conntrack_hash_insert(ct); |
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index a9adf4c6b299..8a025a585d2f 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c | |||
@@ -455,6 +455,7 @@ void xt_compat_flush_offsets(u_int8_t af) | |||
455 | vfree(xt[af].compat_tab); | 455 | vfree(xt[af].compat_tab); |
456 | xt[af].compat_tab = NULL; | 456 | xt[af].compat_tab = NULL; |
457 | xt[af].number = 0; | 457 | xt[af].number = 0; |
458 | xt[af].cur = 0; | ||
458 | } | 459 | } |
459 | } | 460 | } |
460 | EXPORT_SYMBOL_GPL(xt_compat_flush_offsets); | 461 | EXPORT_SYMBOL_GPL(xt_compat_flush_offsets); |
@@ -473,8 +474,7 @@ int xt_compat_calc_jump(u_int8_t af, unsigned int offset) | |||
473 | else | 474 | else |
474 | return mid ? tmp[mid - 1].delta : 0; | 475 | return mid ? tmp[mid - 1].delta : 0; |
475 | } | 476 | } |
476 | WARN_ON_ONCE(1); | 477 | return left ? tmp[left - 1].delta : 0; |
477 | return 0; | ||
478 | } | 478 | } |
479 | EXPORT_SYMBOL_GPL(xt_compat_calc_jump); | 479 | EXPORT_SYMBOL_GPL(xt_compat_calc_jump); |
480 | 480 | ||
diff --git a/net/netfilter/xt_DSCP.c b/net/netfilter/xt_DSCP.c index 0a229191e55b..ae8271652efa 100644 --- a/net/netfilter/xt_DSCP.c +++ b/net/netfilter/xt_DSCP.c | |||
@@ -99,7 +99,7 @@ tos_tg6(struct sk_buff *skb, const struct xt_action_param *par) | |||
99 | u_int8_t orig, nv; | 99 | u_int8_t orig, nv; |
100 | 100 | ||
101 | orig = ipv6_get_dsfield(iph); | 101 | orig = ipv6_get_dsfield(iph); |
102 | nv = (orig & info->tos_mask) ^ info->tos_value; | 102 | nv = (orig & ~info->tos_mask) ^ info->tos_value; |
103 | 103 | ||
104 | if (orig != nv) { | 104 | if (orig != nv) { |
105 | if (!skb_make_writable(skb, sizeof(struct iphdr))) | 105 | if (!skb_make_writable(skb, sizeof(struct iphdr))) |
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c index 481a86fdc409..61805d7b38aa 100644 --- a/net/netfilter/xt_conntrack.c +++ b/net/netfilter/xt_conntrack.c | |||
@@ -272,11 +272,6 @@ static int conntrack_mt_check(const struct xt_mtchk_param *par) | |||
272 | { | 272 | { |
273 | int ret; | 273 | int ret; |
274 | 274 | ||
275 | if (strcmp(par->table, "raw") == 0) { | ||
276 | pr_info("state is undetermined at the time of raw table\n"); | ||
277 | return -EINVAL; | ||
278 | } | ||
279 | |||
280 | ret = nf_ct_l3proto_try_module_get(par->family); | 275 | ret = nf_ct_l3proto_try_module_get(par->family); |
281 | if (ret < 0) | 276 | if (ret < 0) |
282 | pr_info("cannot load conntrack support for proto=%u\n", | 277 | pr_info("cannot load conntrack support for proto=%u\n", |