diff options
Diffstat (limited to 'net')
31 files changed, 346 insertions, 231 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 7850412f52b7..0eb1a886b370 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c | |||
| @@ -124,6 +124,9 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head) | |||
| 124 | 124 | ||
| 125 | grp->nr_vlans--; | 125 | grp->nr_vlans--; |
| 126 | 126 | ||
| 127 | if (vlan->flags & VLAN_FLAG_GVRP) | ||
| 128 | vlan_gvrp_request_leave(dev); | ||
| 129 | |||
| 127 | vlan_group_set_device(grp, vlan_id, NULL); | 130 | vlan_group_set_device(grp, vlan_id, NULL); |
| 128 | if (!grp->killall) | 131 | if (!grp->killall) |
| 129 | synchronize_net(); | 132 | synchronize_net(); |
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index e34ea9e5e28b..b2ff6c8d3603 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
| @@ -487,9 +487,6 @@ static int vlan_dev_stop(struct net_device *dev) | |||
| 487 | struct vlan_dev_info *vlan = vlan_dev_info(dev); | 487 | struct vlan_dev_info *vlan = vlan_dev_info(dev); |
| 488 | struct net_device *real_dev = vlan->real_dev; | 488 | struct net_device *real_dev = vlan->real_dev; |
| 489 | 489 | ||
| 490 | if (vlan->flags & VLAN_FLAG_GVRP) | ||
| 491 | vlan_gvrp_request_leave(dev); | ||
| 492 | |||
| 493 | dev_mc_unsync(real_dev, dev); | 490 | dev_mc_unsync(real_dev, dev); |
| 494 | dev_uc_unsync(real_dev, dev); | 491 | dev_uc_unsync(real_dev, dev); |
| 495 | if (dev->flags & IFF_ALLMULTI) | 492 | if (dev->flags & IFF_ALLMULTI) |
diff --git a/net/9p/client.c b/net/9p/client.c index 77367745be9b..a9aa2dd66482 100644 --- a/net/9p/client.c +++ b/net/9p/client.c | |||
| @@ -614,7 +614,7 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...) | |||
| 614 | 614 | ||
| 615 | err = c->trans_mod->request(c, req); | 615 | err = c->trans_mod->request(c, req); |
| 616 | if (err < 0) { | 616 | if (err < 0) { |
| 617 | if (err != -ERESTARTSYS) | 617 | if (err != -ERESTARTSYS && err != -EFAULT) |
| 618 | c->status = Disconnected; | 618 | c->status = Disconnected; |
| 619 | goto reterr; | 619 | goto reterr; |
| 620 | } | 620 | } |
diff --git a/net/9p/protocol.c b/net/9p/protocol.c index b58a501cf3d1..a873277cb996 100644 --- a/net/9p/protocol.c +++ b/net/9p/protocol.c | |||
| @@ -674,6 +674,7 @@ int p9dirent_read(char *buf, int len, struct p9_dirent *dirent, | |||
| 674 | } | 674 | } |
| 675 | 675 | ||
| 676 | strcpy(dirent->d_name, nameptr); | 676 | strcpy(dirent->d_name, nameptr); |
| 677 | kfree(nameptr); | ||
| 677 | 678 | ||
| 678 | out: | 679 | out: |
| 679 | return fake_pdu.offset; | 680 | return fake_pdu.offset; |
diff --git a/net/9p/trans_common.c b/net/9p/trans_common.c index e883172f9aa2..9a70ebdec56e 100644 --- a/net/9p/trans_common.c +++ b/net/9p/trans_common.c | |||
| @@ -63,7 +63,7 @@ p9_payload_gup(struct p9_req_t *req, size_t *pdata_off, int *pdata_len, | |||
| 63 | int nr_pages, u8 rw) | 63 | int nr_pages, u8 rw) |
| 64 | { | 64 | { |
| 65 | uint32_t first_page_bytes = 0; | 65 | uint32_t first_page_bytes = 0; |
| 66 | uint32_t pdata_mapped_pages; | 66 | int32_t pdata_mapped_pages; |
| 67 | struct trans_rpage_info *rpinfo; | 67 | struct trans_rpage_info *rpinfo; |
| 68 | 68 | ||
| 69 | *pdata_off = (__force size_t)req->tc->pubuf & (PAGE_SIZE-1); | 69 | *pdata_off = (__force size_t)req->tc->pubuf & (PAGE_SIZE-1); |
| @@ -75,14 +75,9 @@ p9_payload_gup(struct p9_req_t *req, size_t *pdata_off, int *pdata_len, | |||
| 75 | rpinfo = req->tc->private; | 75 | rpinfo = req->tc->private; |
| 76 | pdata_mapped_pages = get_user_pages_fast((unsigned long)req->tc->pubuf, | 76 | pdata_mapped_pages = get_user_pages_fast((unsigned long)req->tc->pubuf, |
| 77 | nr_pages, rw, &rpinfo->rp_data[0]); | 77 | nr_pages, rw, &rpinfo->rp_data[0]); |
| 78 | if (pdata_mapped_pages <= 0) | ||
| 79 | return pdata_mapped_pages; | ||
| 78 | 80 | ||
| 79 | if (pdata_mapped_pages < 0) { | ||
| 80 | printk(KERN_ERR "get_user_pages_fast failed:%d udata:%p" | ||
| 81 | "nr_pages:%d\n", pdata_mapped_pages, | ||
| 82 | req->tc->pubuf, nr_pages); | ||
| 83 | pdata_mapped_pages = 0; | ||
| 84 | return -EIO; | ||
| 85 | } | ||
| 86 | rpinfo->rp_nr_pages = pdata_mapped_pages; | 81 | rpinfo->rp_nr_pages = pdata_mapped_pages; |
| 87 | if (*pdata_off) { | 82 | if (*pdata_off) { |
| 88 | *pdata_len = first_page_bytes; | 83 | *pdata_len = first_page_bytes; |
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 94954c74f6ae..42fdffd1d76c 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
| @@ -369,15 +369,6 @@ static void __sco_sock_close(struct sock *sk) | |||
| 369 | 369 | ||
| 370 | case BT_CONNECTED: | 370 | case BT_CONNECTED: |
| 371 | case BT_CONFIG: | 371 | case BT_CONFIG: |
| 372 | if (sco_pi(sk)->conn) { | ||
| 373 | sk->sk_state = BT_DISCONN; | ||
| 374 | sco_sock_set_timer(sk, SCO_DISCONN_TIMEOUT); | ||
| 375 | hci_conn_put(sco_pi(sk)->conn->hcon); | ||
| 376 | sco_pi(sk)->conn = NULL; | ||
| 377 | } else | ||
| 378 | sco_chan_del(sk, ECONNRESET); | ||
| 379 | break; | ||
| 380 | |||
| 381 | case BT_CONNECT: | 372 | case BT_CONNECT: |
| 382 | case BT_DISCONN: | 373 | case BT_DISCONN: |
| 383 | sco_chan_del(sk, ECONNRESET); | 374 | sco_chan_del(sk, ECONNRESET); |
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index f3bc322c5891..74ef4d4846a4 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c | |||
| @@ -737,7 +737,7 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb, | |||
| 737 | nf_bridge->mask |= BRNF_PKT_TYPE; | 737 | nf_bridge->mask |= BRNF_PKT_TYPE; |
| 738 | } | 738 | } |
| 739 | 739 | ||
| 740 | if (br_parse_ip_options(skb)) | 740 | if (pf == PF_INET && br_parse_ip_options(skb)) |
| 741 | return NF_DROP; | 741 | return NF_DROP; |
| 742 | 742 | ||
| 743 | /* The physdev module checks on this */ | 743 | /* The physdev module checks on this */ |
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/core/dev.c b/net/core/dev.c index 856b6ee9a1d5..b624fe4d9bd7 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -1284,11 +1284,13 @@ static int dev_close_many(struct list_head *head) | |||
| 1284 | */ | 1284 | */ |
| 1285 | int dev_close(struct net_device *dev) | 1285 | int dev_close(struct net_device *dev) |
| 1286 | { | 1286 | { |
| 1287 | LIST_HEAD(single); | 1287 | if (dev->flags & IFF_UP) { |
| 1288 | LIST_HEAD(single); | ||
| 1288 | 1289 | ||
| 1289 | list_add(&dev->unreg_list, &single); | 1290 | list_add(&dev->unreg_list, &single); |
| 1290 | dev_close_many(&single); | 1291 | dev_close_many(&single); |
| 1291 | list_del(&single); | 1292 | list_del(&single); |
| 1293 | } | ||
| 1292 | return 0; | 1294 | return 0; |
| 1293 | } | 1295 | } |
| 1294 | EXPORT_SYMBOL(dev_close); | 1296 | EXPORT_SYMBOL(dev_close); |
| @@ -5184,27 +5186,27 @@ u32 netdev_fix_features(struct net_device *dev, u32 features) | |||
| 5184 | /* Fix illegal checksum combinations */ | 5186 | /* Fix illegal checksum combinations */ |
| 5185 | if ((features & NETIF_F_HW_CSUM) && | 5187 | if ((features & NETIF_F_HW_CSUM) && |
| 5186 | (features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) { | 5188 | (features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) { |
| 5187 | netdev_info(dev, "mixed HW and IP checksum settings.\n"); | 5189 | netdev_warn(dev, "mixed HW and IP checksum settings.\n"); |
| 5188 | features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM); | 5190 | features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM); |
| 5189 | } | 5191 | } |
| 5190 | 5192 | ||
| 5191 | if ((features & NETIF_F_NO_CSUM) && | 5193 | if ((features & NETIF_F_NO_CSUM) && |
| 5192 | (features & (NETIF_F_HW_CSUM|NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) { | 5194 | (features & (NETIF_F_HW_CSUM|NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) { |
| 5193 | netdev_info(dev, "mixed no checksumming and other settings.\n"); | 5195 | netdev_warn(dev, "mixed no checksumming and other settings.\n"); |
| 5194 | features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM|NETIF_F_HW_CSUM); | 5196 | features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM|NETIF_F_HW_CSUM); |
| 5195 | } | 5197 | } |
| 5196 | 5198 | ||
| 5197 | /* Fix illegal SG+CSUM combinations. */ | 5199 | /* Fix illegal SG+CSUM combinations. */ |
| 5198 | if ((features & NETIF_F_SG) && | 5200 | if ((features & NETIF_F_SG) && |
| 5199 | !(features & NETIF_F_ALL_CSUM)) { | 5201 | !(features & NETIF_F_ALL_CSUM)) { |
| 5200 | netdev_info(dev, | 5202 | netdev_dbg(dev, |
| 5201 | "Dropping NETIF_F_SG since no checksum feature.\n"); | 5203 | "Dropping NETIF_F_SG since no checksum feature.\n"); |
| 5202 | features &= ~NETIF_F_SG; | 5204 | features &= ~NETIF_F_SG; |
| 5203 | } | 5205 | } |
| 5204 | 5206 | ||
| 5205 | /* TSO requires that SG is present as well. */ | 5207 | /* TSO requires that SG is present as well. */ |
| 5206 | if ((features & NETIF_F_ALL_TSO) && !(features & NETIF_F_SG)) { | 5208 | if ((features & NETIF_F_ALL_TSO) && !(features & NETIF_F_SG)) { |
| 5207 | netdev_info(dev, "Dropping TSO features since no SG feature.\n"); | 5209 | netdev_dbg(dev, "Dropping TSO features since no SG feature.\n"); |
| 5208 | features &= ~NETIF_F_ALL_TSO; | 5210 | features &= ~NETIF_F_ALL_TSO; |
| 5209 | } | 5211 | } |
| 5210 | 5212 | ||
| @@ -5214,7 +5216,7 @@ u32 netdev_fix_features(struct net_device *dev, u32 features) | |||
| 5214 | 5216 | ||
| 5215 | /* Software GSO depends on SG. */ | 5217 | /* Software GSO depends on SG. */ |
| 5216 | if ((features & NETIF_F_GSO) && !(features & NETIF_F_SG)) { | 5218 | if ((features & NETIF_F_GSO) && !(features & NETIF_F_SG)) { |
| 5217 | netdev_info(dev, "Dropping NETIF_F_GSO since no SG feature.\n"); | 5219 | netdev_dbg(dev, "Dropping NETIF_F_GSO since no SG feature.\n"); |
| 5218 | features &= ~NETIF_F_GSO; | 5220 | features &= ~NETIF_F_GSO; |
| 5219 | } | 5221 | } |
| 5220 | 5222 | ||
| @@ -5224,13 +5226,13 @@ u32 netdev_fix_features(struct net_device *dev, u32 features) | |||
| 5224 | if (!((features & NETIF_F_GEN_CSUM) || | 5226 | if (!((features & NETIF_F_GEN_CSUM) || |
| 5225 | (features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM)) | 5227 | (features & (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM)) |
| 5226 | == (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) { | 5228 | == (NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM))) { |
| 5227 | netdev_info(dev, | 5229 | netdev_dbg(dev, |
| 5228 | "Dropping NETIF_F_UFO since no checksum offload features.\n"); | 5230 | "Dropping NETIF_F_UFO since no checksum offload features.\n"); |
| 5229 | features &= ~NETIF_F_UFO; | 5231 | features &= ~NETIF_F_UFO; |
| 5230 | } | 5232 | } |
| 5231 | 5233 | ||
| 5232 | if (!(features & NETIF_F_SG)) { | 5234 | if (!(features & NETIF_F_SG)) { |
| 5233 | netdev_info(dev, | 5235 | netdev_dbg(dev, |
| 5234 | "Dropping NETIF_F_UFO since no NETIF_F_SG feature.\n"); | 5236 | "Dropping NETIF_F_UFO since no NETIF_F_SG feature.\n"); |
| 5235 | features &= ~NETIF_F_UFO; | 5237 | features &= ~NETIF_F_UFO; |
| 5236 | } | 5238 | } |
| @@ -5412,12 +5414,6 @@ int register_netdevice(struct net_device *dev) | |||
| 5412 | dev->features |= NETIF_F_SOFT_FEATURES; | 5414 | dev->features |= NETIF_F_SOFT_FEATURES; |
| 5413 | dev->wanted_features = dev->features & dev->hw_features; | 5415 | dev->wanted_features = dev->features & dev->hw_features; |
| 5414 | 5416 | ||
| 5415 | /* Avoid warning from netdev_fix_features() for GSO without SG */ | ||
| 5416 | if (!(dev->wanted_features & NETIF_F_SG)) { | ||
| 5417 | dev->wanted_features &= ~NETIF_F_GSO; | ||
| 5418 | dev->features &= ~NETIF_F_GSO; | ||
| 5419 | } | ||
| 5420 | |||
| 5421 | /* Enable GRO and NETIF_F_HIGHDMA for vlans by default, | 5417 | /* Enable GRO and NETIF_F_HIGHDMA for vlans by default, |
| 5422 | * vlan_dev_init() will do the dev->features check, so these features | 5418 | * vlan_dev_init() will do the dev->features check, so these features |
| 5423 | * are enabled only if supported by underlying device. | 5419 | * are enabled only if supported by underlying device. |
diff --git a/net/dccp/options.c b/net/dccp/options.c index f06ffcfc8d71..4b2ab657ac8e 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c | |||
| @@ -123,6 +123,8 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq, | |||
| 123 | case DCCPO_CHANGE_L ... DCCPO_CONFIRM_R: | 123 | case DCCPO_CHANGE_L ... DCCPO_CONFIRM_R: |
| 124 | if (pkt_type == DCCP_PKT_DATA) /* RFC 4340, 6 */ | 124 | if (pkt_type == DCCP_PKT_DATA) /* RFC 4340, 6 */ |
| 125 | break; | 125 | break; |
| 126 | if (len == 0) | ||
| 127 | goto out_invalid_option; | ||
| 126 | rc = dccp_feat_parse_options(sk, dreq, mandatory, opt, | 128 | rc = dccp_feat_parse_options(sk, dreq, mandatory, opt, |
| 127 | *value, value + 1, len - 1); | 129 | *value, value + 1, len - 1); |
| 128 | if (rc) | 130 | if (rc) |
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index a1151b8adf3c..b1d282f11be7 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c | |||
| @@ -223,31 +223,30 @@ static void ip_expire(unsigned long arg) | |||
| 223 | 223 | ||
| 224 | if ((qp->q.last_in & INET_FRAG_FIRST_IN) && qp->q.fragments != NULL) { | 224 | if ((qp->q.last_in & INET_FRAG_FIRST_IN) && qp->q.fragments != NULL) { |
| 225 | struct sk_buff *head = qp->q.fragments; | 225 | struct sk_buff *head = qp->q.fragments; |
| 226 | const struct iphdr *iph; | ||
| 227 | int err; | ||
| 226 | 228 | ||
| 227 | rcu_read_lock(); | 229 | rcu_read_lock(); |
| 228 | head->dev = dev_get_by_index_rcu(net, qp->iif); | 230 | head->dev = dev_get_by_index_rcu(net, qp->iif); |
| 229 | if (!head->dev) | 231 | if (!head->dev) |
| 230 | goto out_rcu_unlock; | 232 | goto out_rcu_unlock; |
| 231 | 233 | ||
| 234 | /* skb dst is stale, drop it, and perform route lookup again */ | ||
| 235 | skb_dst_drop(head); | ||
| 236 | iph = ip_hdr(head); | ||
| 237 | err = ip_route_input_noref(head, iph->daddr, iph->saddr, | ||
| 238 | iph->tos, head->dev); | ||
| 239 | if (err) | ||
| 240 | goto out_rcu_unlock; | ||
| 241 | |||
| 232 | /* | 242 | /* |
| 233 | * Only search router table for the head fragment, | 243 | * Only an end host needs to send an ICMP |
| 234 | * when defraging timeout at PRE_ROUTING HOOK. | 244 | * "Fragment Reassembly Timeout" message, per RFC792. |
| 235 | */ | 245 | */ |
| 236 | if (qp->user == IP_DEFRAG_CONNTRACK_IN && !skb_dst(head)) { | 246 | if (qp->user == IP_DEFRAG_CONNTRACK_IN && |
| 237 | const struct iphdr *iph = ip_hdr(head); | 247 | skb_rtable(head)->rt_type != RTN_LOCAL) |
| 238 | int err = ip_route_input(head, iph->daddr, iph->saddr, | 248 | goto out_rcu_unlock; |
| 239 | iph->tos, head->dev); | ||
| 240 | if (unlikely(err)) | ||
| 241 | goto out_rcu_unlock; | ||
| 242 | |||
| 243 | /* | ||
| 244 | * Only an end host needs to send an ICMP | ||
| 245 | * "Fragment Reassembly Timeout" message, per RFC792. | ||
| 246 | */ | ||
| 247 | if (skb_rtable(head)->rt_type != RTN_LOCAL) | ||
| 248 | goto out_rcu_unlock; | ||
| 249 | 249 | ||
| 250 | } | ||
| 251 | 250 | ||
| 252 | /* Send an ICMP "Fragment Reassembly Timeout" message. */ | 251 | /* Send an ICMP "Fragment Reassembly Timeout" message. */ |
| 253 | icmp_send(head, ICMP_TIME_EXCEEDED, ICMP_EXC_FRAGTIME, 0); | 252 | icmp_send(head, ICMP_TIME_EXCEEDED, ICMP_EXC_FRAGTIME, 0); |
diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c index 34340c9c95fa..f376b05cca81 100644 --- a/net/ipv4/tcp_cubic.c +++ b/net/ipv4/tcp_cubic.c | |||
| @@ -93,6 +93,7 @@ struct bictcp { | |||
| 93 | u32 ack_cnt; /* number of acks */ | 93 | u32 ack_cnt; /* number of acks */ |
| 94 | u32 tcp_cwnd; /* estimated tcp cwnd */ | 94 | u32 tcp_cwnd; /* estimated tcp cwnd */ |
| 95 | #define ACK_RATIO_SHIFT 4 | 95 | #define ACK_RATIO_SHIFT 4 |
| 96 | #define ACK_RATIO_LIMIT (32u << ACK_RATIO_SHIFT) | ||
| 96 | u16 delayed_ack; /* estimate the ratio of Packets/ACKs << 4 */ | 97 | u16 delayed_ack; /* estimate the ratio of Packets/ACKs << 4 */ |
| 97 | u8 sample_cnt; /* number of samples to decide curr_rtt */ | 98 | u8 sample_cnt; /* number of samples to decide curr_rtt */ |
| 98 | u8 found; /* the exit point is found? */ | 99 | u8 found; /* the exit point is found? */ |
| @@ -398,8 +399,12 @@ static void bictcp_acked(struct sock *sk, u32 cnt, s32 rtt_us) | |||
| 398 | u32 delay; | 399 | u32 delay; |
| 399 | 400 | ||
| 400 | if (icsk->icsk_ca_state == TCP_CA_Open) { | 401 | if (icsk->icsk_ca_state == TCP_CA_Open) { |
| 401 | cnt -= ca->delayed_ack >> ACK_RATIO_SHIFT; | 402 | u32 ratio = ca->delayed_ack; |
| 402 | ca->delayed_ack += cnt; | 403 | |
| 404 | ratio -= ca->delayed_ack >> ACK_RATIO_SHIFT; | ||
| 405 | ratio += cnt; | ||
| 406 | |||
| 407 | ca->delayed_ack = min(ratio, ACK_RATIO_LIMIT); | ||
| 403 | } | 408 | } |
| 404 | 409 | ||
| 405 | /* Some calls are for duplicates without timetamps */ | 410 | /* Some calls are for duplicates without timetamps */ |
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c index 571aa96a175c..2d51840e53a1 100644 --- a/net/ipv4/xfrm4_output.c +++ b/net/ipv4/xfrm4_output.c | |||
| @@ -69,7 +69,7 @@ int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb) | |||
| 69 | } | 69 | } |
| 70 | EXPORT_SYMBOL(xfrm4_prepare_output); | 70 | EXPORT_SYMBOL(xfrm4_prepare_output); |
| 71 | 71 | ||
| 72 | static int xfrm4_output_finish(struct sk_buff *skb) | 72 | int xfrm4_output_finish(struct sk_buff *skb) |
| 73 | { | 73 | { |
| 74 | #ifdef CONFIG_NETFILTER | 74 | #ifdef CONFIG_NETFILTER |
| 75 | if (!skb_dst(skb)->xfrm) { | 75 | if (!skb_dst(skb)->xfrm) { |
| @@ -86,7 +86,11 @@ static int xfrm4_output_finish(struct sk_buff *skb) | |||
| 86 | 86 | ||
| 87 | int xfrm4_output(struct sk_buff *skb) | 87 | int xfrm4_output(struct sk_buff *skb) |
| 88 | { | 88 | { |
| 89 | struct dst_entry *dst = skb_dst(skb); | ||
| 90 | struct xfrm_state *x = dst->xfrm; | ||
| 91 | |||
| 89 | return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, skb, | 92 | return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, skb, |
| 90 | NULL, skb_dst(skb)->dev, xfrm4_output_finish, | 93 | NULL, dst->dev, |
| 94 | x->outer_mode->afinfo->output_finish, | ||
| 91 | !(IPCB(skb)->flags & IPSKB_REROUTED)); | 95 | !(IPCB(skb)->flags & IPSKB_REROUTED)); |
| 92 | } | 96 | } |
diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c index 1717c64628d1..805d63ef4340 100644 --- a/net/ipv4/xfrm4_state.c +++ b/net/ipv4/xfrm4_state.c | |||
| @@ -78,6 +78,7 @@ static struct xfrm_state_afinfo xfrm4_state_afinfo = { | |||
| 78 | .init_tempsel = __xfrm4_init_tempsel, | 78 | .init_tempsel = __xfrm4_init_tempsel, |
| 79 | .init_temprop = xfrm4_init_temprop, | 79 | .init_temprop = xfrm4_init_temprop, |
| 80 | .output = xfrm4_output, | 80 | .output = xfrm4_output, |
| 81 | .output_finish = xfrm4_output_finish, | ||
| 81 | .extract_input = xfrm4_extract_input, | 82 | .extract_input = xfrm4_extract_input, |
| 82 | .extract_output = xfrm4_extract_output, | 83 | .extract_output = xfrm4_extract_output, |
| 83 | .transport_finish = xfrm4_transport_finish, | 84 | .transport_finish = xfrm4_transport_finish, |
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/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c index 8e688b3de9ab..49a91c5f5623 100644 --- a/net/ipv6/xfrm6_output.c +++ b/net/ipv6/xfrm6_output.c | |||
| @@ -79,7 +79,7 @@ int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb) | |||
| 79 | } | 79 | } |
| 80 | EXPORT_SYMBOL(xfrm6_prepare_output); | 80 | EXPORT_SYMBOL(xfrm6_prepare_output); |
| 81 | 81 | ||
| 82 | static int xfrm6_output_finish(struct sk_buff *skb) | 82 | int xfrm6_output_finish(struct sk_buff *skb) |
| 83 | { | 83 | { |
| 84 | #ifdef CONFIG_NETFILTER | 84 | #ifdef CONFIG_NETFILTER |
| 85 | IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED; | 85 | IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED; |
| @@ -97,9 +97,9 @@ static int __xfrm6_output(struct sk_buff *skb) | |||
| 97 | if ((x && x->props.mode == XFRM_MODE_TUNNEL) && | 97 | if ((x && x->props.mode == XFRM_MODE_TUNNEL) && |
| 98 | ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) || | 98 | ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) || |
| 99 | dst_allfrag(skb_dst(skb)))) { | 99 | dst_allfrag(skb_dst(skb)))) { |
| 100 | return ip6_fragment(skb, xfrm6_output_finish); | 100 | return ip6_fragment(skb, x->outer_mode->afinfo->output_finish); |
| 101 | } | 101 | } |
| 102 | return xfrm6_output_finish(skb); | 102 | return x->outer_mode->afinfo->output_finish(skb); |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | int xfrm6_output(struct sk_buff *skb) | 105 | int xfrm6_output(struct sk_buff *skb) |
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c index afe941e9415c..248f0b2a7ee9 100644 --- a/net/ipv6/xfrm6_state.c +++ b/net/ipv6/xfrm6_state.c | |||
| @@ -178,6 +178,7 @@ static struct xfrm_state_afinfo xfrm6_state_afinfo = { | |||
| 178 | .tmpl_sort = __xfrm6_tmpl_sort, | 178 | .tmpl_sort = __xfrm6_tmpl_sort, |
| 179 | .state_sort = __xfrm6_state_sort, | 179 | .state_sort = __xfrm6_state_sort, |
| 180 | .output = xfrm6_output, | 180 | .output = xfrm6_output, |
| 181 | .output_finish = xfrm6_output_finish, | ||
| 181 | .extract_input = xfrm6_extract_input, | 182 | .extract_input = xfrm6_extract_input, |
| 182 | .extract_output = xfrm6_extract_output, | 183 | .extract_output = xfrm6_extract_output, |
| 183 | .transport_finish = xfrm6_transport_finish, | 184 | .transport_finish = xfrm6_transport_finish, |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index ce4596ed1268..bd1224fd216a 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
| @@ -237,6 +237,10 @@ ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx) | |||
| 237 | &local->dynamic_ps_disable_work); | 237 | &local->dynamic_ps_disable_work); |
| 238 | } | 238 | } |
| 239 | 239 | ||
| 240 | /* Don't restart the timer if we're not disassociated */ | ||
| 241 | if (!ifmgd->associated) | ||
| 242 | return TX_CONTINUE; | ||
| 243 | |||
| 240 | mod_timer(&local->dynamic_ps_timer, jiffies + | 244 | mod_timer(&local->dynamic_ps_timer, jiffies + |
| 241 | msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout)); | 245 | msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout)); |
| 242 | 246 | ||
diff --git a/net/netfilter/ipvs/ip_vs_app.c b/net/netfilter/ipvs/ip_vs_app.c index 2dc6de13ac18..059af3120be7 100644 --- a/net/netfilter/ipvs/ip_vs_app.c +++ b/net/netfilter/ipvs/ip_vs_app.c | |||
| @@ -572,11 +572,11 @@ static const struct file_operations ip_vs_app_fops = { | |||
| 572 | .open = ip_vs_app_open, | 572 | .open = ip_vs_app_open, |
| 573 | .read = seq_read, | 573 | .read = seq_read, |
| 574 | .llseek = seq_lseek, | 574 | .llseek = seq_lseek, |
| 575 | .release = seq_release, | 575 | .release = seq_release_net, |
| 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..bf28ac2fc99b 100644 --- a/net/netfilter/ipvs/ip_vs_conn.c +++ b/net/netfilter/ipvs/ip_vs_conn.c | |||
| @@ -1046,7 +1046,7 @@ static const struct file_operations ip_vs_conn_fops = { | |||
| 1046 | .open = ip_vs_conn_open, | 1046 | .open = ip_vs_conn_open, |
| 1047 | .read = seq_read, | 1047 | .read = seq_read, |
| 1048 | .llseek = seq_lseek, | 1048 | .llseek = seq_lseek, |
| 1049 | .release = seq_release, | 1049 | .release = seq_release_net, |
| 1050 | }; | 1050 | }; |
| 1051 | 1051 | ||
| 1052 | static const char *ip_vs_origin_name(unsigned flags) | 1052 | static const char *ip_vs_origin_name(unsigned flags) |
| @@ -1114,7 +1114,7 @@ static const struct file_operations ip_vs_conn_sync_fops = { | |||
| 1114 | .open = ip_vs_conn_sync_open, | 1114 | .open = ip_vs_conn_sync_open, |
| 1115 | .read = seq_read, | 1115 | .read = seq_read, |
| 1116 | .llseek = seq_lseek, | 1116 | .llseek = seq_lseek, |
| 1117 | .release = seq_release, | 1117 | .release = seq_release_net, |
| 1118 | }; | 1118 | }; |
| 1119 | 1119 | ||
| 1120 | #endif | 1120 | #endif |
| @@ -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..37890f228b19 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 |
| @@ -1981,7 +2066,7 @@ static const struct file_operations ip_vs_info_fops = { | |||
| 1981 | .open = ip_vs_info_open, | 2066 | .open = ip_vs_info_open, |
| 1982 | .read = seq_read, | 2067 | .read = seq_read, |
| 1983 | .llseek = seq_lseek, | 2068 | .llseek = seq_lseek, |
| 1984 | .release = seq_release_private, | 2069 | .release = seq_release_net, |
| 1985 | }; | 2070 | }; |
| 1986 | 2071 | ||
| 1987 | #endif | 2072 | #endif |
| @@ -2024,7 +2109,7 @@ static const struct file_operations ip_vs_stats_fops = { | |||
| 2024 | .open = ip_vs_stats_seq_open, | 2109 | .open = ip_vs_stats_seq_open, |
| 2025 | .read = seq_read, | 2110 | .read = seq_read, |
| 2026 | .llseek = seq_lseek, | 2111 | .llseek = seq_lseek, |
| 2027 | .release = single_release, | 2112 | .release = single_release_net, |
| 2028 | }; | 2113 | }; |
| 2029 | 2114 | ||
| 2030 | static int ip_vs_stats_percpu_show(struct seq_file *seq, void *v) | 2115 | static int ip_vs_stats_percpu_show(struct seq_file *seq, void *v) |
| @@ -2093,7 +2178,7 @@ static const struct file_operations ip_vs_stats_percpu_fops = { | |||
| 2093 | .open = ip_vs_stats_percpu_seq_open, | 2178 | .open = ip_vs_stats_percpu_seq_open, |
| 2094 | .read = seq_read, | 2179 | .read = seq_read, |
| 2095 | .llseek = seq_lseek, | 2180 | .llseek = seq_lseek, |
| 2096 | .release = single_release, | 2181 | .release = single_release_net, |
| 2097 | }; | 2182 | }; |
| 2098 | #endif | 2183 | #endif |
| 2099 | 2184 | ||
| @@ -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", |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 15792d8b6272..b4d745ea8ee1 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
| @@ -1406,6 +1406,7 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy, | |||
| 1406 | struct net *net = xp_net(policy); | 1406 | struct net *net = xp_net(policy); |
| 1407 | unsigned long now = jiffies; | 1407 | unsigned long now = jiffies; |
| 1408 | struct net_device *dev; | 1408 | struct net_device *dev; |
| 1409 | struct xfrm_mode *inner_mode; | ||
| 1409 | struct dst_entry *dst_prev = NULL; | 1410 | struct dst_entry *dst_prev = NULL; |
| 1410 | struct dst_entry *dst0 = NULL; | 1411 | struct dst_entry *dst0 = NULL; |
| 1411 | int i = 0; | 1412 | int i = 0; |
| @@ -1436,6 +1437,17 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy, | |||
| 1436 | goto put_states; | 1437 | goto put_states; |
| 1437 | } | 1438 | } |
| 1438 | 1439 | ||
| 1440 | if (xfrm[i]->sel.family == AF_UNSPEC) { | ||
| 1441 | inner_mode = xfrm_ip2inner_mode(xfrm[i], | ||
| 1442 | xfrm_af2proto(family)); | ||
| 1443 | if (!inner_mode) { | ||
| 1444 | err = -EAFNOSUPPORT; | ||
| 1445 | dst_release(dst); | ||
| 1446 | goto put_states; | ||
| 1447 | } | ||
| 1448 | } else | ||
| 1449 | inner_mode = xfrm[i]->inner_mode; | ||
| 1450 | |||
| 1439 | if (!dst_prev) | 1451 | if (!dst_prev) |
| 1440 | dst0 = dst1; | 1452 | dst0 = dst1; |
| 1441 | else { | 1453 | else { |
| @@ -1464,7 +1476,7 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy, | |||
| 1464 | dst1->lastuse = now; | 1476 | dst1->lastuse = now; |
| 1465 | 1477 | ||
| 1466 | dst1->input = dst_discard; | 1478 | dst1->input = dst_discard; |
| 1467 | dst1->output = xfrm[i]->outer_mode->afinfo->output; | 1479 | dst1->output = inner_mode->afinfo->output; |
| 1468 | 1480 | ||
| 1469 | dst1->next = dst_prev; | 1481 | dst1->next = dst_prev; |
| 1470 | dst_prev = dst1; | 1482 | dst_prev = dst1; |
diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c index e8a781422feb..47f1b8638df9 100644 --- a/net/xfrm/xfrm_replay.c +++ b/net/xfrm/xfrm_replay.c | |||
| @@ -535,6 +535,9 @@ int xfrm_init_replay(struct xfrm_state *x) | |||
| 535 | replay_esn->bmp_len * sizeof(__u32) * 8) | 535 | replay_esn->bmp_len * sizeof(__u32) * 8) |
| 536 | return -EINVAL; | 536 | return -EINVAL; |
| 537 | 537 | ||
| 538 | if ((x->props.flags & XFRM_STATE_ESN) && replay_esn->replay_window == 0) | ||
| 539 | return -EINVAL; | ||
| 540 | |||
| 538 | if ((x->props.flags & XFRM_STATE_ESN) && x->replay_esn) | 541 | if ((x->props.flags & XFRM_STATE_ESN) && x->replay_esn) |
| 539 | x->repl = &xfrm_replay_esn; | 542 | x->repl = &xfrm_replay_esn; |
| 540 | else | 543 | else |
