diff options
Diffstat (limited to 'net')
57 files changed, 719 insertions, 331 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index b50dabb3f86a..faff6247ac8f 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -589,6 +589,14 @@ EXPORT_SYMBOL(hci_get_route); | |||
589 | void hci_le_conn_failed(struct hci_conn *conn, u8 status) | 589 | void hci_le_conn_failed(struct hci_conn *conn, u8 status) |
590 | { | 590 | { |
591 | struct hci_dev *hdev = conn->hdev; | 591 | struct hci_dev *hdev = conn->hdev; |
592 | struct hci_conn_params *params; | ||
593 | |||
594 | params = hci_pend_le_action_lookup(&hdev->pend_le_conns, &conn->dst, | ||
595 | conn->dst_type); | ||
596 | if (params && params->conn) { | ||
597 | hci_conn_drop(params->conn); | ||
598 | params->conn = NULL; | ||
599 | } | ||
592 | 600 | ||
593 | conn->state = BT_CLOSED; | 601 | conn->state = BT_CLOSED; |
594 | 602 | ||
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index c32d361c0cf7..1d9c29a00568 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -2536,8 +2536,13 @@ static void hci_pend_le_actions_clear(struct hci_dev *hdev) | |||
2536 | { | 2536 | { |
2537 | struct hci_conn_params *p; | 2537 | struct hci_conn_params *p; |
2538 | 2538 | ||
2539 | list_for_each_entry(p, &hdev->le_conn_params, list) | 2539 | list_for_each_entry(p, &hdev->le_conn_params, list) { |
2540 | if (p->conn) { | ||
2541 | hci_conn_drop(p->conn); | ||
2542 | p->conn = NULL; | ||
2543 | } | ||
2540 | list_del_init(&p->action); | 2544 | list_del_init(&p->action); |
2545 | } | ||
2541 | 2546 | ||
2542 | BT_DBG("All LE pending actions cleared"); | 2547 | BT_DBG("All LE pending actions cleared"); |
2543 | } | 2548 | } |
@@ -2578,8 +2583,8 @@ static int hci_dev_do_close(struct hci_dev *hdev) | |||
2578 | 2583 | ||
2579 | hci_dev_lock(hdev); | 2584 | hci_dev_lock(hdev); |
2580 | hci_inquiry_cache_flush(hdev); | 2585 | hci_inquiry_cache_flush(hdev); |
2581 | hci_conn_hash_flush(hdev); | ||
2582 | hci_pend_le_actions_clear(hdev); | 2586 | hci_pend_le_actions_clear(hdev); |
2587 | hci_conn_hash_flush(hdev); | ||
2583 | hci_dev_unlock(hdev); | 2588 | hci_dev_unlock(hdev); |
2584 | 2589 | ||
2585 | hci_notify(hdev, HCI_DEV_DOWN); | 2590 | hci_notify(hdev, HCI_DEV_DOWN); |
@@ -3727,6 +3732,9 @@ void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type) | |||
3727 | if (!params) | 3732 | if (!params) |
3728 | return; | 3733 | return; |
3729 | 3734 | ||
3735 | if (params->conn) | ||
3736 | hci_conn_drop(params->conn); | ||
3737 | |||
3730 | list_del(¶ms->action); | 3738 | list_del(¶ms->action); |
3731 | list_del(¶ms->list); | 3739 | list_del(¶ms->list); |
3732 | kfree(params); | 3740 | kfree(params); |
@@ -3757,6 +3765,8 @@ void hci_conn_params_clear_all(struct hci_dev *hdev) | |||
3757 | struct hci_conn_params *params, *tmp; | 3765 | struct hci_conn_params *params, *tmp; |
3758 | 3766 | ||
3759 | list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) { | 3767 | list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) { |
3768 | if (params->conn) | ||
3769 | hci_conn_drop(params->conn); | ||
3760 | list_del(¶ms->action); | 3770 | list_del(¶ms->action); |
3761 | list_del(¶ms->list); | 3771 | list_del(¶ms->list); |
3762 | kfree(params); | 3772 | kfree(params); |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index be35598984d9..a6000823f0ff 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -4221,8 +4221,13 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
4221 | hci_proto_connect_cfm(conn, ev->status); | 4221 | hci_proto_connect_cfm(conn, ev->status); |
4222 | 4222 | ||
4223 | params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type); | 4223 | params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type); |
4224 | if (params) | 4224 | if (params) { |
4225 | list_del_init(¶ms->action); | 4225 | list_del_init(¶ms->action); |
4226 | if (params->conn) { | ||
4227 | hci_conn_drop(params->conn); | ||
4228 | params->conn = NULL; | ||
4229 | } | ||
4230 | } | ||
4226 | 4231 | ||
4227 | unlock: | 4232 | unlock: |
4228 | hci_update_background_scan(hdev); | 4233 | hci_update_background_scan(hdev); |
@@ -4304,8 +4309,16 @@ static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr, | |||
4304 | 4309 | ||
4305 | conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW, | 4310 | conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW, |
4306 | HCI_LE_AUTOCONN_TIMEOUT, HCI_ROLE_MASTER); | 4311 | HCI_LE_AUTOCONN_TIMEOUT, HCI_ROLE_MASTER); |
4307 | if (!IS_ERR(conn)) | 4312 | if (!IS_ERR(conn)) { |
4313 | /* Store the pointer since we don't really have any | ||
4314 | * other owner of the object besides the params that | ||
4315 | * triggered it. This way we can abort the connection if | ||
4316 | * the parameters get removed and keep the reference | ||
4317 | * count consistent once the connection is established. | ||
4318 | */ | ||
4319 | params->conn = conn; | ||
4308 | return; | 4320 | return; |
4321 | } | ||
4309 | 4322 | ||
4310 | switch (PTR_ERR(conn)) { | 4323 | switch (PTR_ERR(conn)) { |
4311 | case -EBUSY: | 4324 | case -EBUSY: |
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 62a7fa2e3569..b6c04cbcfdc5 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
@@ -309,6 +309,9 @@ struct br_input_skb_cb { | |||
309 | int igmp; | 309 | int igmp; |
310 | int mrouters_only; | 310 | int mrouters_only; |
311 | #endif | 311 | #endif |
312 | #ifdef CONFIG_BRIDGE_VLAN_FILTERING | ||
313 | bool vlan_filtered; | ||
314 | #endif | ||
312 | }; | 315 | }; |
313 | 316 | ||
314 | #define BR_INPUT_SKB_CB(__skb) ((struct br_input_skb_cb *)(__skb)->cb) | 317 | #define BR_INPUT_SKB_CB(__skb) ((struct br_input_skb_cb *)(__skb)->cb) |
diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c index e1bcd653899b..3ba57fcdcd13 100644 --- a/net/bridge/br_vlan.c +++ b/net/bridge/br_vlan.c | |||
@@ -27,9 +27,13 @@ static void __vlan_add_flags(struct net_port_vlans *v, u16 vid, u16 flags) | |||
27 | { | 27 | { |
28 | if (flags & BRIDGE_VLAN_INFO_PVID) | 28 | if (flags & BRIDGE_VLAN_INFO_PVID) |
29 | __vlan_add_pvid(v, vid); | 29 | __vlan_add_pvid(v, vid); |
30 | else | ||
31 | __vlan_delete_pvid(v, vid); | ||
30 | 32 | ||
31 | if (flags & BRIDGE_VLAN_INFO_UNTAGGED) | 33 | if (flags & BRIDGE_VLAN_INFO_UNTAGGED) |
32 | set_bit(vid, v->untagged_bitmap); | 34 | set_bit(vid, v->untagged_bitmap); |
35 | else | ||
36 | clear_bit(vid, v->untagged_bitmap); | ||
33 | } | 37 | } |
34 | 38 | ||
35 | static int __vlan_add(struct net_port_vlans *v, u16 vid, u16 flags) | 39 | static int __vlan_add(struct net_port_vlans *v, u16 vid, u16 flags) |
@@ -125,7 +129,8 @@ struct sk_buff *br_handle_vlan(struct net_bridge *br, | |||
125 | { | 129 | { |
126 | u16 vid; | 130 | u16 vid; |
127 | 131 | ||
128 | if (!br->vlan_enabled) | 132 | /* If this packet was not filtered at input, let it pass */ |
133 | if (!BR_INPUT_SKB_CB(skb)->vlan_filtered) | ||
129 | goto out; | 134 | goto out; |
130 | 135 | ||
131 | /* Vlan filter table must be configured at this point. The | 136 | /* Vlan filter table must be configured at this point. The |
@@ -164,8 +169,10 @@ bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v, | |||
164 | /* If VLAN filtering is disabled on the bridge, all packets are | 169 | /* If VLAN filtering is disabled on the bridge, all packets are |
165 | * permitted. | 170 | * permitted. |
166 | */ | 171 | */ |
167 | if (!br->vlan_enabled) | 172 | if (!br->vlan_enabled) { |
173 | BR_INPUT_SKB_CB(skb)->vlan_filtered = false; | ||
168 | return true; | 174 | return true; |
175 | } | ||
169 | 176 | ||
170 | /* If there are no vlan in the permitted list, all packets are | 177 | /* If there are no vlan in the permitted list, all packets are |
171 | * rejected. | 178 | * rejected. |
@@ -173,6 +180,7 @@ bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v, | |||
173 | if (!v) | 180 | if (!v) |
174 | goto drop; | 181 | goto drop; |
175 | 182 | ||
183 | BR_INPUT_SKB_CB(skb)->vlan_filtered = true; | ||
176 | proto = br->vlan_proto; | 184 | proto = br->vlan_proto; |
177 | 185 | ||
178 | /* If vlan tx offload is disabled on bridge device and frame was | 186 | /* If vlan tx offload is disabled on bridge device and frame was |
@@ -251,7 +259,8 @@ bool br_allowed_egress(struct net_bridge *br, | |||
251 | { | 259 | { |
252 | u16 vid; | 260 | u16 vid; |
253 | 261 | ||
254 | if (!br->vlan_enabled) | 262 | /* If this packet was not filtered at input, let it pass */ |
263 | if (!BR_INPUT_SKB_CB(skb)->vlan_filtered) | ||
255 | return true; | 264 | return true; |
256 | 265 | ||
257 | if (!v) | 266 | if (!v) |
@@ -270,6 +279,7 @@ bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid) | |||
270 | struct net_bridge *br = p->br; | 279 | struct net_bridge *br = p->br; |
271 | struct net_port_vlans *v; | 280 | struct net_port_vlans *v; |
272 | 281 | ||
282 | /* If filtering was disabled at input, let it pass. */ | ||
273 | if (!br->vlan_enabled) | 283 | if (!br->vlan_enabled) |
274 | return true; | 284 | return true; |
275 | 285 | ||
diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c index 96238ba95f2b..de6662b14e1f 100644 --- a/net/ceph/auth_x.c +++ b/net/ceph/auth_x.c | |||
@@ -13,8 +13,6 @@ | |||
13 | #include "auth_x.h" | 13 | #include "auth_x.h" |
14 | #include "auth_x_protocol.h" | 14 | #include "auth_x_protocol.h" |
15 | 15 | ||
16 | #define TEMP_TICKET_BUF_LEN 256 | ||
17 | |||
18 | static void ceph_x_validate_tickets(struct ceph_auth_client *ac, int *pneed); | 16 | static void ceph_x_validate_tickets(struct ceph_auth_client *ac, int *pneed); |
19 | 17 | ||
20 | static int ceph_x_is_authenticated(struct ceph_auth_client *ac) | 18 | static int ceph_x_is_authenticated(struct ceph_auth_client *ac) |
@@ -64,7 +62,7 @@ static int ceph_x_encrypt(struct ceph_crypto_key *secret, | |||
64 | } | 62 | } |
65 | 63 | ||
66 | static int ceph_x_decrypt(struct ceph_crypto_key *secret, | 64 | static int ceph_x_decrypt(struct ceph_crypto_key *secret, |
67 | void **p, void *end, void *obuf, size_t olen) | 65 | void **p, void *end, void **obuf, size_t olen) |
68 | { | 66 | { |
69 | struct ceph_x_encrypt_header head; | 67 | struct ceph_x_encrypt_header head; |
70 | size_t head_len = sizeof(head); | 68 | size_t head_len = sizeof(head); |
@@ -75,8 +73,14 @@ static int ceph_x_decrypt(struct ceph_crypto_key *secret, | |||
75 | return -EINVAL; | 73 | return -EINVAL; |
76 | 74 | ||
77 | dout("ceph_x_decrypt len %d\n", len); | 75 | dout("ceph_x_decrypt len %d\n", len); |
78 | ret = ceph_decrypt2(secret, &head, &head_len, obuf, &olen, | 76 | if (*obuf == NULL) { |
79 | *p, len); | 77 | *obuf = kmalloc(len, GFP_NOFS); |
78 | if (!*obuf) | ||
79 | return -ENOMEM; | ||
80 | olen = len; | ||
81 | } | ||
82 | |||
83 | ret = ceph_decrypt2(secret, &head, &head_len, *obuf, &olen, *p, len); | ||
80 | if (ret) | 84 | if (ret) |
81 | return ret; | 85 | return ret; |
82 | if (head.struct_v != 1 || le64_to_cpu(head.magic) != CEPHX_ENC_MAGIC) | 86 | if (head.struct_v != 1 || le64_to_cpu(head.magic) != CEPHX_ENC_MAGIC) |
@@ -129,139 +133,120 @@ static void remove_ticket_handler(struct ceph_auth_client *ac, | |||
129 | kfree(th); | 133 | kfree(th); |
130 | } | 134 | } |
131 | 135 | ||
132 | static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac, | 136 | static int process_one_ticket(struct ceph_auth_client *ac, |
133 | struct ceph_crypto_key *secret, | 137 | struct ceph_crypto_key *secret, |
134 | void *buf, void *end) | 138 | void **p, void *end) |
135 | { | 139 | { |
136 | struct ceph_x_info *xi = ac->private; | 140 | struct ceph_x_info *xi = ac->private; |
137 | int num; | 141 | int type; |
138 | void *p = buf; | 142 | u8 tkt_struct_v, blob_struct_v; |
143 | struct ceph_x_ticket_handler *th; | ||
144 | void *dbuf = NULL; | ||
145 | void *dp, *dend; | ||
146 | int dlen; | ||
147 | char is_enc; | ||
148 | struct timespec validity; | ||
149 | struct ceph_crypto_key old_key; | ||
150 | void *ticket_buf = NULL; | ||
151 | void *tp, *tpend; | ||
152 | struct ceph_timespec new_validity; | ||
153 | struct ceph_crypto_key new_session_key; | ||
154 | struct ceph_buffer *new_ticket_blob; | ||
155 | unsigned long new_expires, new_renew_after; | ||
156 | u64 new_secret_id; | ||
139 | int ret; | 157 | int ret; |
140 | char *dbuf; | ||
141 | char *ticket_buf; | ||
142 | u8 reply_struct_v; | ||
143 | 158 | ||
144 | dbuf = kmalloc(TEMP_TICKET_BUF_LEN, GFP_NOFS); | 159 | ceph_decode_need(p, end, sizeof(u32) + 1, bad); |
145 | if (!dbuf) | ||
146 | return -ENOMEM; | ||
147 | 160 | ||
148 | ret = -ENOMEM; | 161 | type = ceph_decode_32(p); |
149 | ticket_buf = kmalloc(TEMP_TICKET_BUF_LEN, GFP_NOFS); | 162 | dout(" ticket type %d %s\n", type, ceph_entity_type_name(type)); |
150 | if (!ticket_buf) | ||
151 | goto out_dbuf; | ||
152 | 163 | ||
153 | ceph_decode_need(&p, end, 1 + sizeof(u32), bad); | 164 | tkt_struct_v = ceph_decode_8(p); |
154 | reply_struct_v = ceph_decode_8(&p); | 165 | if (tkt_struct_v != 1) |
155 | if (reply_struct_v != 1) | ||
156 | goto bad; | 166 | goto bad; |
157 | num = ceph_decode_32(&p); | ||
158 | dout("%d tickets\n", num); | ||
159 | while (num--) { | ||
160 | int type; | ||
161 | u8 tkt_struct_v, blob_struct_v; | ||
162 | struct ceph_x_ticket_handler *th; | ||
163 | void *dp, *dend; | ||
164 | int dlen; | ||
165 | char is_enc; | ||
166 | struct timespec validity; | ||
167 | struct ceph_crypto_key old_key; | ||
168 | void *tp, *tpend; | ||
169 | struct ceph_timespec new_validity; | ||
170 | struct ceph_crypto_key new_session_key; | ||
171 | struct ceph_buffer *new_ticket_blob; | ||
172 | unsigned long new_expires, new_renew_after; | ||
173 | u64 new_secret_id; | ||
174 | |||
175 | ceph_decode_need(&p, end, sizeof(u32) + 1, bad); | ||
176 | |||
177 | type = ceph_decode_32(&p); | ||
178 | dout(" ticket type %d %s\n", type, ceph_entity_type_name(type)); | ||
179 | |||
180 | tkt_struct_v = ceph_decode_8(&p); | ||
181 | if (tkt_struct_v != 1) | ||
182 | goto bad; | ||
183 | |||
184 | th = get_ticket_handler(ac, type); | ||
185 | if (IS_ERR(th)) { | ||
186 | ret = PTR_ERR(th); | ||
187 | goto out; | ||
188 | } | ||
189 | 167 | ||
190 | /* blob for me */ | 168 | th = get_ticket_handler(ac, type); |
191 | dlen = ceph_x_decrypt(secret, &p, end, dbuf, | 169 | if (IS_ERR(th)) { |
192 | TEMP_TICKET_BUF_LEN); | 170 | ret = PTR_ERR(th); |
193 | if (dlen <= 0) { | 171 | goto out; |
194 | ret = dlen; | 172 | } |
195 | goto out; | ||
196 | } | ||
197 | dout(" decrypted %d bytes\n", dlen); | ||
198 | dend = dbuf + dlen; | ||
199 | dp = dbuf; | ||
200 | 173 | ||
201 | tkt_struct_v = ceph_decode_8(&dp); | 174 | /* blob for me */ |
202 | if (tkt_struct_v != 1) | 175 | dlen = ceph_x_decrypt(secret, p, end, &dbuf, 0); |
203 | goto bad; | 176 | if (dlen <= 0) { |
177 | ret = dlen; | ||
178 | goto out; | ||
179 | } | ||
180 | dout(" decrypted %d bytes\n", dlen); | ||
181 | dp = dbuf; | ||
182 | dend = dp + dlen; | ||
204 | 183 | ||
205 | memcpy(&old_key, &th->session_key, sizeof(old_key)); | 184 | tkt_struct_v = ceph_decode_8(&dp); |
206 | ret = ceph_crypto_key_decode(&new_session_key, &dp, dend); | 185 | if (tkt_struct_v != 1) |
207 | if (ret) | 186 | goto bad; |
208 | goto out; | ||
209 | 187 | ||
210 | ceph_decode_copy(&dp, &new_validity, sizeof(new_validity)); | 188 | memcpy(&old_key, &th->session_key, sizeof(old_key)); |
211 | ceph_decode_timespec(&validity, &new_validity); | 189 | ret = ceph_crypto_key_decode(&new_session_key, &dp, dend); |
212 | new_expires = get_seconds() + validity.tv_sec; | 190 | if (ret) |
213 | new_renew_after = new_expires - (validity.tv_sec / 4); | 191 | goto out; |
214 | dout(" expires=%lu renew_after=%lu\n", new_expires, | ||
215 | new_renew_after); | ||
216 | 192 | ||
217 | /* ticket blob for service */ | 193 | ceph_decode_copy(&dp, &new_validity, sizeof(new_validity)); |
218 | ceph_decode_8_safe(&p, end, is_enc, bad); | 194 | ceph_decode_timespec(&validity, &new_validity); |
219 | tp = ticket_buf; | 195 | new_expires = get_seconds() + validity.tv_sec; |
220 | if (is_enc) { | 196 | new_renew_after = new_expires - (validity.tv_sec / 4); |
221 | /* encrypted */ | 197 | dout(" expires=%lu renew_after=%lu\n", new_expires, |
222 | dout(" encrypted ticket\n"); | 198 | new_renew_after); |
223 | dlen = ceph_x_decrypt(&old_key, &p, end, ticket_buf, | 199 | |
224 | TEMP_TICKET_BUF_LEN); | 200 | /* ticket blob for service */ |
225 | if (dlen < 0) { | 201 | ceph_decode_8_safe(p, end, is_enc, bad); |
226 | ret = dlen; | 202 | if (is_enc) { |
227 | goto out; | 203 | /* encrypted */ |
228 | } | 204 | dout(" encrypted ticket\n"); |
229 | dlen = ceph_decode_32(&tp); | 205 | dlen = ceph_x_decrypt(&old_key, p, end, &ticket_buf, 0); |
230 | } else { | 206 | if (dlen < 0) { |
231 | /* unencrypted */ | 207 | ret = dlen; |
232 | ceph_decode_32_safe(&p, end, dlen, bad); | 208 | goto out; |
233 | ceph_decode_need(&p, end, dlen, bad); | ||
234 | ceph_decode_copy(&p, ticket_buf, dlen); | ||
235 | } | 209 | } |
236 | tpend = tp + dlen; | 210 | tp = ticket_buf; |
237 | dout(" ticket blob is %d bytes\n", dlen); | 211 | dlen = ceph_decode_32(&tp); |
238 | ceph_decode_need(&tp, tpend, 1 + sizeof(u64), bad); | 212 | } else { |
239 | blob_struct_v = ceph_decode_8(&tp); | 213 | /* unencrypted */ |
240 | new_secret_id = ceph_decode_64(&tp); | 214 | ceph_decode_32_safe(p, end, dlen, bad); |
241 | ret = ceph_decode_buffer(&new_ticket_blob, &tp, tpend); | 215 | ticket_buf = kmalloc(dlen, GFP_NOFS); |
242 | if (ret) | 216 | if (!ticket_buf) { |
217 | ret = -ENOMEM; | ||
243 | goto out; | 218 | goto out; |
244 | 219 | } | |
245 | /* all is well, update our ticket */ | 220 | tp = ticket_buf; |
246 | ceph_crypto_key_destroy(&th->session_key); | 221 | ceph_decode_need(p, end, dlen, bad); |
247 | if (th->ticket_blob) | 222 | ceph_decode_copy(p, ticket_buf, dlen); |
248 | ceph_buffer_put(th->ticket_blob); | ||
249 | th->session_key = new_session_key; | ||
250 | th->ticket_blob = new_ticket_blob; | ||
251 | th->validity = new_validity; | ||
252 | th->secret_id = new_secret_id; | ||
253 | th->expires = new_expires; | ||
254 | th->renew_after = new_renew_after; | ||
255 | dout(" got ticket service %d (%s) secret_id %lld len %d\n", | ||
256 | type, ceph_entity_type_name(type), th->secret_id, | ||
257 | (int)th->ticket_blob->vec.iov_len); | ||
258 | xi->have_keys |= th->service; | ||
259 | } | 223 | } |
224 | tpend = tp + dlen; | ||
225 | dout(" ticket blob is %d bytes\n", dlen); | ||
226 | ceph_decode_need(&tp, tpend, 1 + sizeof(u64), bad); | ||
227 | blob_struct_v = ceph_decode_8(&tp); | ||
228 | new_secret_id = ceph_decode_64(&tp); | ||
229 | ret = ceph_decode_buffer(&new_ticket_blob, &tp, tpend); | ||
230 | if (ret) | ||
231 | goto out; | ||
232 | |||
233 | /* all is well, update our ticket */ | ||
234 | ceph_crypto_key_destroy(&th->session_key); | ||
235 | if (th->ticket_blob) | ||
236 | ceph_buffer_put(th->ticket_blob); | ||
237 | th->session_key = new_session_key; | ||
238 | th->ticket_blob = new_ticket_blob; | ||
239 | th->validity = new_validity; | ||
240 | th->secret_id = new_secret_id; | ||
241 | th->expires = new_expires; | ||
242 | th->renew_after = new_renew_after; | ||
243 | dout(" got ticket service %d (%s) secret_id %lld len %d\n", | ||
244 | type, ceph_entity_type_name(type), th->secret_id, | ||
245 | (int)th->ticket_blob->vec.iov_len); | ||
246 | xi->have_keys |= th->service; | ||
260 | 247 | ||
261 | ret = 0; | ||
262 | out: | 248 | out: |
263 | kfree(ticket_buf); | 249 | kfree(ticket_buf); |
264 | out_dbuf: | ||
265 | kfree(dbuf); | 250 | kfree(dbuf); |
266 | return ret; | 251 | return ret; |
267 | 252 | ||
@@ -270,6 +255,34 @@ bad: | |||
270 | goto out; | 255 | goto out; |
271 | } | 256 | } |
272 | 257 | ||
258 | static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac, | ||
259 | struct ceph_crypto_key *secret, | ||
260 | void *buf, void *end) | ||
261 | { | ||
262 | void *p = buf; | ||
263 | u8 reply_struct_v; | ||
264 | u32 num; | ||
265 | int ret; | ||
266 | |||
267 | ceph_decode_8_safe(&p, end, reply_struct_v, bad); | ||
268 | if (reply_struct_v != 1) | ||
269 | return -EINVAL; | ||
270 | |||
271 | ceph_decode_32_safe(&p, end, num, bad); | ||
272 | dout("%d tickets\n", num); | ||
273 | |||
274 | while (num--) { | ||
275 | ret = process_one_ticket(ac, secret, &p, end); | ||
276 | if (ret) | ||
277 | return ret; | ||
278 | } | ||
279 | |||
280 | return 0; | ||
281 | |||
282 | bad: | ||
283 | return -EINVAL; | ||
284 | } | ||
285 | |||
273 | static int ceph_x_build_authorizer(struct ceph_auth_client *ac, | 286 | static int ceph_x_build_authorizer(struct ceph_auth_client *ac, |
274 | struct ceph_x_ticket_handler *th, | 287 | struct ceph_x_ticket_handler *th, |
275 | struct ceph_x_authorizer *au) | 288 | struct ceph_x_authorizer *au) |
@@ -583,13 +596,14 @@ static int ceph_x_verify_authorizer_reply(struct ceph_auth_client *ac, | |||
583 | struct ceph_x_ticket_handler *th; | 596 | struct ceph_x_ticket_handler *th; |
584 | int ret = 0; | 597 | int ret = 0; |
585 | struct ceph_x_authorize_reply reply; | 598 | struct ceph_x_authorize_reply reply; |
599 | void *preply = &reply; | ||
586 | void *p = au->reply_buf; | 600 | void *p = au->reply_buf; |
587 | void *end = p + sizeof(au->reply_buf); | 601 | void *end = p + sizeof(au->reply_buf); |
588 | 602 | ||
589 | th = get_ticket_handler(ac, au->service); | 603 | th = get_ticket_handler(ac, au->service); |
590 | if (IS_ERR(th)) | 604 | if (IS_ERR(th)) |
591 | return PTR_ERR(th); | 605 | return PTR_ERR(th); |
592 | ret = ceph_x_decrypt(&th->session_key, &p, end, &reply, sizeof(reply)); | 606 | ret = ceph_x_decrypt(&th->session_key, &p, end, &preply, sizeof(reply)); |
593 | if (ret < 0) | 607 | if (ret < 0) |
594 | return ret; | 608 | return ret; |
595 | if (ret != sizeof(reply)) | 609 | if (ret != sizeof(reply)) |
diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c index 067d3af2eaf6..61fcfc304f68 100644 --- a/net/ceph/mon_client.c +++ b/net/ceph/mon_client.c | |||
@@ -1181,7 +1181,15 @@ static struct ceph_msg *mon_alloc_msg(struct ceph_connection *con, | |||
1181 | if (!m) { | 1181 | if (!m) { |
1182 | pr_info("alloc_msg unknown type %d\n", type); | 1182 | pr_info("alloc_msg unknown type %d\n", type); |
1183 | *skip = 1; | 1183 | *skip = 1; |
1184 | } else if (front_len > m->front_alloc_len) { | ||
1185 | pr_warning("mon_alloc_msg front %d > prealloc %d (%u#%llu)\n", | ||
1186 | front_len, m->front_alloc_len, | ||
1187 | (unsigned int)con->peer_name.type, | ||
1188 | le64_to_cpu(con->peer_name.num)); | ||
1189 | ceph_msg_put(m); | ||
1190 | m = ceph_msg_new(type, front_len, GFP_NOFS, false); | ||
1184 | } | 1191 | } |
1192 | |||
1185 | return m; | 1193 | return m; |
1186 | } | 1194 | } |
1187 | 1195 | ||
diff --git a/net/core/datagram.c b/net/core/datagram.c index 488dd1a825c0..fdbc9a81d4c2 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c | |||
@@ -775,7 +775,7 @@ __sum16 __skb_checksum_complete(struct sk_buff *skb) | |||
775 | EXPORT_SYMBOL(__skb_checksum_complete); | 775 | EXPORT_SYMBOL(__skb_checksum_complete); |
776 | 776 | ||
777 | /** | 777 | /** |
778 | * skb_copy_and_csum_datagram_iovec - Copy and checkum skb to user iovec. | 778 | * skb_copy_and_csum_datagram_iovec - Copy and checksum skb to user iovec. |
779 | * @skb: skbuff | 779 | * @skb: skbuff |
780 | * @hlen: hardware length | 780 | * @hlen: hardware length |
781 | * @iov: io vector | 781 | * @iov: io vector |
diff --git a/net/core/dev.c b/net/core/dev.c index b65a5051361f..cf8a95f48cff 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2587,13 +2587,19 @@ netdev_features_t netif_skb_features(struct sk_buff *skb) | |||
2587 | return harmonize_features(skb, features); | 2587 | return harmonize_features(skb, features); |
2588 | } | 2588 | } |
2589 | 2589 | ||
2590 | features &= (skb->dev->vlan_features | NETIF_F_HW_VLAN_CTAG_TX | | 2590 | features = netdev_intersect_features(features, |
2591 | NETIF_F_HW_VLAN_STAG_TX); | 2591 | skb->dev->vlan_features | |
2592 | NETIF_F_HW_VLAN_CTAG_TX | | ||
2593 | NETIF_F_HW_VLAN_STAG_TX); | ||
2592 | 2594 | ||
2593 | if (protocol == htons(ETH_P_8021Q) || protocol == htons(ETH_P_8021AD)) | 2595 | if (protocol == htons(ETH_P_8021Q) || protocol == htons(ETH_P_8021AD)) |
2594 | features &= NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | | 2596 | features = netdev_intersect_features(features, |
2595 | NETIF_F_GEN_CSUM | NETIF_F_HW_VLAN_CTAG_TX | | 2597 | NETIF_F_SG | |
2596 | NETIF_F_HW_VLAN_STAG_TX; | 2598 | NETIF_F_HIGHDMA | |
2599 | NETIF_F_FRAGLIST | | ||
2600 | NETIF_F_GEN_CSUM | | ||
2601 | NETIF_F_HW_VLAN_CTAG_TX | | ||
2602 | NETIF_F_HW_VLAN_STAG_TX); | ||
2597 | 2603 | ||
2598 | return harmonize_features(skb, features); | 2604 | return harmonize_features(skb, features); |
2599 | } | 2605 | } |
@@ -4803,9 +4809,14 @@ static void netdev_adjacent_sysfs_del(struct net_device *dev, | |||
4803 | sysfs_remove_link(&(dev->dev.kobj), linkname); | 4809 | sysfs_remove_link(&(dev->dev.kobj), linkname); |
4804 | } | 4810 | } |
4805 | 4811 | ||
4806 | #define netdev_adjacent_is_neigh_list(dev, dev_list) \ | 4812 | static inline bool netdev_adjacent_is_neigh_list(struct net_device *dev, |
4807 | (dev_list == &dev->adj_list.upper || \ | 4813 | struct net_device *adj_dev, |
4808 | dev_list == &dev->adj_list.lower) | 4814 | struct list_head *dev_list) |
4815 | { | ||
4816 | return (dev_list == &dev->adj_list.upper || | ||
4817 | dev_list == &dev->adj_list.lower) && | ||
4818 | net_eq(dev_net(dev), dev_net(adj_dev)); | ||
4819 | } | ||
4809 | 4820 | ||
4810 | static int __netdev_adjacent_dev_insert(struct net_device *dev, | 4821 | static int __netdev_adjacent_dev_insert(struct net_device *dev, |
4811 | struct net_device *adj_dev, | 4822 | struct net_device *adj_dev, |
@@ -4835,7 +4846,7 @@ static int __netdev_adjacent_dev_insert(struct net_device *dev, | |||
4835 | pr_debug("dev_hold for %s, because of link added from %s to %s\n", | 4846 | pr_debug("dev_hold for %s, because of link added from %s to %s\n", |
4836 | adj_dev->name, dev->name, adj_dev->name); | 4847 | adj_dev->name, dev->name, adj_dev->name); |
4837 | 4848 | ||
4838 | if (netdev_adjacent_is_neigh_list(dev, dev_list)) { | 4849 | if (netdev_adjacent_is_neigh_list(dev, adj_dev, dev_list)) { |
4839 | ret = netdev_adjacent_sysfs_add(dev, adj_dev, dev_list); | 4850 | ret = netdev_adjacent_sysfs_add(dev, adj_dev, dev_list); |
4840 | if (ret) | 4851 | if (ret) |
4841 | goto free_adj; | 4852 | goto free_adj; |
@@ -4856,7 +4867,7 @@ static int __netdev_adjacent_dev_insert(struct net_device *dev, | |||
4856 | return 0; | 4867 | return 0; |
4857 | 4868 | ||
4858 | remove_symlinks: | 4869 | remove_symlinks: |
4859 | if (netdev_adjacent_is_neigh_list(dev, dev_list)) | 4870 | if (netdev_adjacent_is_neigh_list(dev, adj_dev, dev_list)) |
4860 | netdev_adjacent_sysfs_del(dev, adj_dev->name, dev_list); | 4871 | netdev_adjacent_sysfs_del(dev, adj_dev->name, dev_list); |
4861 | free_adj: | 4872 | free_adj: |
4862 | kfree(adj); | 4873 | kfree(adj); |
@@ -4889,7 +4900,7 @@ static void __netdev_adjacent_dev_remove(struct net_device *dev, | |||
4889 | if (adj->master) | 4900 | if (adj->master) |
4890 | sysfs_remove_link(&(dev->dev.kobj), "master"); | 4901 | sysfs_remove_link(&(dev->dev.kobj), "master"); |
4891 | 4902 | ||
4892 | if (netdev_adjacent_is_neigh_list(dev, dev_list)) | 4903 | if (netdev_adjacent_is_neigh_list(dev, adj_dev, dev_list)) |
4893 | netdev_adjacent_sysfs_del(dev, adj_dev->name, dev_list); | 4904 | netdev_adjacent_sysfs_del(dev, adj_dev->name, dev_list); |
4894 | 4905 | ||
4895 | list_del_rcu(&adj->list); | 4906 | list_del_rcu(&adj->list); |
@@ -5159,11 +5170,65 @@ void netdev_upper_dev_unlink(struct net_device *dev, | |||
5159 | } | 5170 | } |
5160 | EXPORT_SYMBOL(netdev_upper_dev_unlink); | 5171 | EXPORT_SYMBOL(netdev_upper_dev_unlink); |
5161 | 5172 | ||
5173 | void netdev_adjacent_add_links(struct net_device *dev) | ||
5174 | { | ||
5175 | struct netdev_adjacent *iter; | ||
5176 | |||
5177 | struct net *net = dev_net(dev); | ||
5178 | |||
5179 | list_for_each_entry(iter, &dev->adj_list.upper, list) { | ||
5180 | if (!net_eq(net,dev_net(iter->dev))) | ||
5181 | continue; | ||
5182 | netdev_adjacent_sysfs_add(iter->dev, dev, | ||
5183 | &iter->dev->adj_list.lower); | ||
5184 | netdev_adjacent_sysfs_add(dev, iter->dev, | ||
5185 | &dev->adj_list.upper); | ||
5186 | } | ||
5187 | |||
5188 | list_for_each_entry(iter, &dev->adj_list.lower, list) { | ||
5189 | if (!net_eq(net,dev_net(iter->dev))) | ||
5190 | continue; | ||
5191 | netdev_adjacent_sysfs_add(iter->dev, dev, | ||
5192 | &iter->dev->adj_list.upper); | ||
5193 | netdev_adjacent_sysfs_add(dev, iter->dev, | ||
5194 | &dev->adj_list.lower); | ||
5195 | } | ||
5196 | } | ||
5197 | |||
5198 | void netdev_adjacent_del_links(struct net_device *dev) | ||
5199 | { | ||
5200 | struct netdev_adjacent *iter; | ||
5201 | |||
5202 | struct net *net = dev_net(dev); | ||
5203 | |||
5204 | list_for_each_entry(iter, &dev->adj_list.upper, list) { | ||
5205 | if (!net_eq(net,dev_net(iter->dev))) | ||
5206 | continue; | ||
5207 | netdev_adjacent_sysfs_del(iter->dev, dev->name, | ||
5208 | &iter->dev->adj_list.lower); | ||
5209 | netdev_adjacent_sysfs_del(dev, iter->dev->name, | ||
5210 | &dev->adj_list.upper); | ||
5211 | } | ||
5212 | |||
5213 | list_for_each_entry(iter, &dev->adj_list.lower, list) { | ||
5214 | if (!net_eq(net,dev_net(iter->dev))) | ||
5215 | continue; | ||
5216 | netdev_adjacent_sysfs_del(iter->dev, dev->name, | ||
5217 | &iter->dev->adj_list.upper); | ||
5218 | netdev_adjacent_sysfs_del(dev, iter->dev->name, | ||
5219 | &dev->adj_list.lower); | ||
5220 | } | ||
5221 | } | ||
5222 | |||
5162 | void netdev_adjacent_rename_links(struct net_device *dev, char *oldname) | 5223 | void netdev_adjacent_rename_links(struct net_device *dev, char *oldname) |
5163 | { | 5224 | { |
5164 | struct netdev_adjacent *iter; | 5225 | struct netdev_adjacent *iter; |
5165 | 5226 | ||
5227 | struct net *net = dev_net(dev); | ||
5228 | |||
5166 | list_for_each_entry(iter, &dev->adj_list.upper, list) { | 5229 | list_for_each_entry(iter, &dev->adj_list.upper, list) { |
5230 | if (!net_eq(net,dev_net(iter->dev))) | ||
5231 | continue; | ||
5167 | netdev_adjacent_sysfs_del(iter->dev, oldname, | 5232 | netdev_adjacent_sysfs_del(iter->dev, oldname, |
5168 | &iter->dev->adj_list.lower); | 5233 | &iter->dev->adj_list.lower); |
5169 | netdev_adjacent_sysfs_add(iter->dev, dev, | 5234 | netdev_adjacent_sysfs_add(iter->dev, dev, |
@@ -5171,6 +5236,8 @@ void netdev_adjacent_rename_links(struct net_device *dev, char *oldname) | |||
5171 | } | 5236 | } |
5172 | 5237 | ||
5173 | list_for_each_entry(iter, &dev->adj_list.lower, list) { | 5238 | list_for_each_entry(iter, &dev->adj_list.lower, list) { |
5239 | if (!net_eq(net,dev_net(iter->dev))) | ||
5240 | continue; | ||
5174 | netdev_adjacent_sysfs_del(iter->dev, oldname, | 5241 | netdev_adjacent_sysfs_del(iter->dev, oldname, |
5175 | &iter->dev->adj_list.upper); | 5242 | &iter->dev->adj_list.upper); |
5176 | netdev_adjacent_sysfs_add(iter->dev, dev, | 5243 | netdev_adjacent_sysfs_add(iter->dev, dev, |
@@ -6773,6 +6840,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char | |||
6773 | 6840 | ||
6774 | /* Send a netdev-removed uevent to the old namespace */ | 6841 | /* Send a netdev-removed uevent to the old namespace */ |
6775 | kobject_uevent(&dev->dev.kobj, KOBJ_REMOVE); | 6842 | kobject_uevent(&dev->dev.kobj, KOBJ_REMOVE); |
6843 | netdev_adjacent_del_links(dev); | ||
6776 | 6844 | ||
6777 | /* Actually switch the network namespace */ | 6845 | /* Actually switch the network namespace */ |
6778 | dev_net_set(dev, net); | 6846 | dev_net_set(dev, net); |
@@ -6787,6 +6855,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char | |||
6787 | 6855 | ||
6788 | /* Send a netdev-add uevent to the new namespace */ | 6856 | /* Send a netdev-add uevent to the new namespace */ |
6789 | kobject_uevent(&dev->dev.kobj, KOBJ_ADD); | 6857 | kobject_uevent(&dev->dev.kobj, KOBJ_ADD); |
6858 | netdev_adjacent_add_links(dev); | ||
6790 | 6859 | ||
6791 | /* Fixup kobjects */ | 6860 | /* Fixup kobjects */ |
6792 | err = device_rename(&dev->dev, dev->name); | 6861 | err = device_rename(&dev->dev, dev->name); |
diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c index 6b5b6e7013ca..9d33dfffca19 100644 --- a/net/core/gen_estimator.c +++ b/net/core/gen_estimator.c | |||
@@ -197,7 +197,7 @@ struct gen_estimator *gen_find_node(const struct gnet_stats_basic_packed *bstats | |||
197 | * as destination. A new timer with the interval specified in the | 197 | * as destination. A new timer with the interval specified in the |
198 | * configuration TLV is created. Upon each interval, the latest statistics | 198 | * configuration TLV is created. Upon each interval, the latest statistics |
199 | * will be read from &bstats and the estimated rate will be stored in | 199 | * will be read from &bstats and the estimated rate will be stored in |
200 | * &rate_est with the statistics lock grabed during this period. | 200 | * &rate_est with the statistics lock grabbed during this period. |
201 | * | 201 | * |
202 | * Returns 0 on success or a negative error code. | 202 | * Returns 0 on success or a negative error code. |
203 | * | 203 | * |
diff --git a/net/core/gen_stats.c b/net/core/gen_stats.c index 9d3d9e78397b..2ddbce4cce14 100644 --- a/net/core/gen_stats.c +++ b/net/core/gen_stats.c | |||
@@ -206,7 +206,7 @@ EXPORT_SYMBOL(gnet_stats_copy_queue); | |||
206 | * @st: application specific statistics data | 206 | * @st: application specific statistics data |
207 | * @len: length of data | 207 | * @len: length of data |
208 | * | 208 | * |
209 | * Appends the application sepecific statistics to the top level TLV created by | 209 | * Appends the application specific statistics to the top level TLV created by |
210 | * gnet_stats_start_copy() and remembers the data for XSTATS if the dumping | 210 | * gnet_stats_start_copy() and remembers the data for XSTATS if the dumping |
211 | * handle is in backward compatibility mode. | 211 | * handle is in backward compatibility mode. |
212 | * | 212 | * |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 163b673f9e62..8d289697cc7a 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -2647,7 +2647,7 @@ EXPORT_SYMBOL(skb_prepare_seq_read); | |||
2647 | * skb_seq_read() will return the remaining part of the block. | 2647 | * skb_seq_read() will return the remaining part of the block. |
2648 | * | 2648 | * |
2649 | * Note 1: The size of each block of data returned can be arbitrary, | 2649 | * Note 1: The size of each block of data returned can be arbitrary, |
2650 | * this limitation is the cost for zerocopy seqeuental | 2650 | * this limitation is the cost for zerocopy sequential |
2651 | * reads of potentially non linear data. | 2651 | * reads of potentially non linear data. |
2652 | * | 2652 | * |
2653 | * Note 2: Fragment lists within fragments are not implemented | 2653 | * Note 2: Fragment lists within fragments are not implemented |
@@ -2781,7 +2781,7 @@ EXPORT_SYMBOL(skb_find_text); | |||
2781 | /** | 2781 | /** |
2782 | * skb_append_datato_frags - append the user data to a skb | 2782 | * skb_append_datato_frags - append the user data to a skb |
2783 | * @sk: sock structure | 2783 | * @sk: sock structure |
2784 | * @skb: skb structure to be appened with user data. | 2784 | * @skb: skb structure to be appended with user data. |
2785 | * @getfrag: call back function to be used for getting the user data | 2785 | * @getfrag: call back function to be used for getting the user data |
2786 | * @from: pointer to user message iov | 2786 | * @from: pointer to user message iov |
2787 | * @length: length of the iov message | 2787 | * @length: length of the iov message |
@@ -3152,6 +3152,9 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb) | |||
3152 | NAPI_GRO_CB(skb)->free = NAPI_GRO_FREE_STOLEN_HEAD; | 3152 | NAPI_GRO_CB(skb)->free = NAPI_GRO_FREE_STOLEN_HEAD; |
3153 | goto done; | 3153 | goto done; |
3154 | } | 3154 | } |
3155 | /* switch back to head shinfo */ | ||
3156 | pinfo = skb_shinfo(p); | ||
3157 | |||
3155 | if (pinfo->frag_list) | 3158 | if (pinfo->frag_list) |
3156 | goto merge; | 3159 | goto merge; |
3157 | if (skb_gro_len(p) != pinfo->gso_size) | 3160 | if (skb_gro_len(p) != pinfo->gso_size) |
diff --git a/net/core/sock.c b/net/core/sock.c index 2714811afbd8..9c3f823e76a9 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -166,7 +166,7 @@ EXPORT_SYMBOL(sk_ns_capable); | |||
166 | /** | 166 | /** |
167 | * sk_capable - Socket global capability test | 167 | * sk_capable - Socket global capability test |
168 | * @sk: Socket to use a capability on or through | 168 | * @sk: Socket to use a capability on or through |
169 | * @cap: The global capbility to use | 169 | * @cap: The global capability to use |
170 | * | 170 | * |
171 | * Test to see if the opener of the socket had when the socket was | 171 | * Test to see if the opener of the socket had when the socket was |
172 | * created and the current process has the capability @cap in all user | 172 | * created and the current process has the capability @cap in all user |
@@ -183,7 +183,7 @@ EXPORT_SYMBOL(sk_capable); | |||
183 | * @sk: Socket to use a capability on or through | 183 | * @sk: Socket to use a capability on or through |
184 | * @cap: The capability to use | 184 | * @cap: The capability to use |
185 | * | 185 | * |
186 | * Test to see if the opener of the socket had when the socke was created | 186 | * Test to see if the opener of the socket had when the socket was created |
187 | * and the current process has the capability @cap over the network namespace | 187 | * and the current process has the capability @cap over the network namespace |
188 | * the socket is a member of. | 188 | * the socket is a member of. |
189 | */ | 189 | */ |
@@ -1822,6 +1822,9 @@ struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len, | |||
1822 | order); | 1822 | order); |
1823 | if (page) | 1823 | if (page) |
1824 | goto fill_page; | 1824 | goto fill_page; |
1825 | /* Do not retry other high order allocations */ | ||
1826 | order = 1; | ||
1827 | max_page_order = 0; | ||
1825 | } | 1828 | } |
1826 | order--; | 1829 | order--; |
1827 | } | 1830 | } |
@@ -1863,16 +1866,14 @@ EXPORT_SYMBOL(sock_alloc_send_skb); | |||
1863 | * skb_page_frag_refill - check that a page_frag contains enough room | 1866 | * skb_page_frag_refill - check that a page_frag contains enough room |
1864 | * @sz: minimum size of the fragment we want to get | 1867 | * @sz: minimum size of the fragment we want to get |
1865 | * @pfrag: pointer to page_frag | 1868 | * @pfrag: pointer to page_frag |
1866 | * @prio: priority for memory allocation | 1869 | * @gfp: priority for memory allocation |
1867 | * | 1870 | * |
1868 | * Note: While this allocator tries to use high order pages, there is | 1871 | * Note: While this allocator tries to use high order pages, there is |
1869 | * no guarantee that allocations succeed. Therefore, @sz MUST be | 1872 | * no guarantee that allocations succeed. Therefore, @sz MUST be |
1870 | * less or equal than PAGE_SIZE. | 1873 | * less or equal than PAGE_SIZE. |
1871 | */ | 1874 | */ |
1872 | bool skb_page_frag_refill(unsigned int sz, struct page_frag *pfrag, gfp_t prio) | 1875 | bool skb_page_frag_refill(unsigned int sz, struct page_frag *pfrag, gfp_t gfp) |
1873 | { | 1876 | { |
1874 | int order; | ||
1875 | |||
1876 | if (pfrag->page) { | 1877 | if (pfrag->page) { |
1877 | if (atomic_read(&pfrag->page->_count) == 1) { | 1878 | if (atomic_read(&pfrag->page->_count) == 1) { |
1878 | pfrag->offset = 0; | 1879 | pfrag->offset = 0; |
@@ -1883,20 +1884,21 @@ bool skb_page_frag_refill(unsigned int sz, struct page_frag *pfrag, gfp_t prio) | |||
1883 | put_page(pfrag->page); | 1884 | put_page(pfrag->page); |
1884 | } | 1885 | } |
1885 | 1886 | ||
1886 | order = SKB_FRAG_PAGE_ORDER; | 1887 | pfrag->offset = 0; |
1887 | do { | 1888 | if (SKB_FRAG_PAGE_ORDER) { |
1888 | gfp_t gfp = prio; | 1889 | pfrag->page = alloc_pages(gfp | __GFP_COMP | |
1889 | 1890 | __GFP_NOWARN | __GFP_NORETRY, | |
1890 | if (order) | 1891 | SKB_FRAG_PAGE_ORDER); |
1891 | gfp |= __GFP_COMP | __GFP_NOWARN | __GFP_NORETRY; | ||
1892 | pfrag->page = alloc_pages(gfp, order); | ||
1893 | if (likely(pfrag->page)) { | 1892 | if (likely(pfrag->page)) { |
1894 | pfrag->offset = 0; | 1893 | pfrag->size = PAGE_SIZE << SKB_FRAG_PAGE_ORDER; |
1895 | pfrag->size = PAGE_SIZE << order; | ||
1896 | return true; | 1894 | return true; |
1897 | } | 1895 | } |
1898 | } while (--order >= 0); | 1896 | } |
1899 | 1897 | pfrag->page = alloc_page(gfp); | |
1898 | if (likely(pfrag->page)) { | ||
1899 | pfrag->size = PAGE_SIZE; | ||
1900 | return true; | ||
1901 | } | ||
1900 | return false; | 1902 | return false; |
1901 | } | 1903 | } |
1902 | EXPORT_SYMBOL(skb_page_frag_refill); | 1904 | EXPORT_SYMBOL(skb_page_frag_refill); |
diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c index 016b77ee88f0..6591d27e53a4 100644 --- a/net/ieee802154/6lowpan_rtnl.c +++ b/net/ieee802154/6lowpan_rtnl.c | |||
@@ -246,7 +246,7 @@ lowpan_alloc_frag(struct sk_buff *skb, int size, | |||
246 | return ERR_PTR(-rc); | 246 | return ERR_PTR(-rc); |
247 | } | 247 | } |
248 | } else { | 248 | } else { |
249 | frag = ERR_PTR(ENOMEM); | 249 | frag = ERR_PTR(-ENOMEM); |
250 | } | 250 | } |
251 | 251 | ||
252 | return frag; | 252 | return frag; |
@@ -437,7 +437,7 @@ static void lowpan_setup(struct net_device *dev) | |||
437 | /* Frame Control + Sequence Number + Address fields + Security Header */ | 437 | /* Frame Control + Sequence Number + Address fields + Security Header */ |
438 | dev->hard_header_len = 2 + 1 + 20 + 14; | 438 | dev->hard_header_len = 2 + 1 + 20 + 14; |
439 | dev->needed_tailroom = 2; /* FCS */ | 439 | dev->needed_tailroom = 2; /* FCS */ |
440 | dev->mtu = 1281; | 440 | dev->mtu = IPV6_MIN_MTU; |
441 | dev->tx_queue_len = 0; | 441 | dev->tx_queue_len = 0; |
442 | dev->flags = IFF_BROADCAST | IFF_MULTICAST; | 442 | dev->flags = IFF_BROADCAST | IFF_MULTICAST; |
443 | dev->watchdog_timeo = 0; | 443 | dev->watchdog_timeo = 0; |
diff --git a/net/ieee802154/reassembly.c b/net/ieee802154/reassembly.c index ffec6ce51005..32755cb7e64e 100644 --- a/net/ieee802154/reassembly.c +++ b/net/ieee802154/reassembly.c | |||
@@ -355,8 +355,6 @@ int lowpan_frag_rcv(struct sk_buff *skb, const u8 frag_type) | |||
355 | struct net *net = dev_net(skb->dev); | 355 | struct net *net = dev_net(skb->dev); |
356 | struct lowpan_frag_info *frag_info = lowpan_cb(skb); | 356 | struct lowpan_frag_info *frag_info = lowpan_cb(skb); |
357 | struct ieee802154_addr source, dest; | 357 | struct ieee802154_addr source, dest; |
358 | struct netns_ieee802154_lowpan *ieee802154_lowpan = | ||
359 | net_ieee802154_lowpan(net); | ||
360 | int err; | 358 | int err; |
361 | 359 | ||
362 | source = mac_cb(skb)->source; | 360 | source = mac_cb(skb)->source; |
@@ -366,8 +364,10 @@ int lowpan_frag_rcv(struct sk_buff *skb, const u8 frag_type) | |||
366 | if (err < 0) | 364 | if (err < 0) |
367 | goto err; | 365 | goto err; |
368 | 366 | ||
369 | if (frag_info->d_size > ieee802154_lowpan->max_dsize) | 367 | if (frag_info->d_size > IPV6_MIN_MTU) { |
368 | net_warn_ratelimited("lowpan_frag_rcv: datagram size exceeds MTU\n"); | ||
370 | goto err; | 369 | goto err; |
370 | } | ||
371 | 371 | ||
372 | fq = fq_find(net, frag_info, &source, &dest); | 372 | fq = fq_find(net, frag_info, &source, &dest); |
373 | if (fq != NULL) { | 373 | if (fq != NULL) { |
@@ -415,13 +415,6 @@ static struct ctl_table lowpan_frags_ns_ctl_table[] = { | |||
415 | .mode = 0644, | 415 | .mode = 0644, |
416 | .proc_handler = proc_dointvec_jiffies, | 416 | .proc_handler = proc_dointvec_jiffies, |
417 | }, | 417 | }, |
418 | { | ||
419 | .procname = "6lowpanfrag_max_datagram_size", | ||
420 | .data = &init_net.ieee802154_lowpan.max_dsize, | ||
421 | .maxlen = sizeof(int), | ||
422 | .mode = 0644, | ||
423 | .proc_handler = proc_dointvec | ||
424 | }, | ||
425 | { } | 418 | { } |
426 | }; | 419 | }; |
427 | 420 | ||
@@ -458,7 +451,6 @@ static int __net_init lowpan_frags_ns_sysctl_register(struct net *net) | |||
458 | table[1].data = &ieee802154_lowpan->frags.low_thresh; | 451 | table[1].data = &ieee802154_lowpan->frags.low_thresh; |
459 | table[1].extra2 = &ieee802154_lowpan->frags.high_thresh; | 452 | table[1].extra2 = &ieee802154_lowpan->frags.high_thresh; |
460 | table[2].data = &ieee802154_lowpan->frags.timeout; | 453 | table[2].data = &ieee802154_lowpan->frags.timeout; |
461 | table[3].data = &ieee802154_lowpan->max_dsize; | ||
462 | 454 | ||
463 | /* Don't export sysctls to unprivileged users */ | 455 | /* Don't export sysctls to unprivileged users */ |
464 | if (net->user_ns != &init_user_ns) | 456 | if (net->user_ns != &init_user_ns) |
@@ -533,7 +525,6 @@ static int __net_init lowpan_frags_init_net(struct net *net) | |||
533 | ieee802154_lowpan->frags.high_thresh = IPV6_FRAG_HIGH_THRESH; | 525 | ieee802154_lowpan->frags.high_thresh = IPV6_FRAG_HIGH_THRESH; |
534 | ieee802154_lowpan->frags.low_thresh = IPV6_FRAG_LOW_THRESH; | 526 | ieee802154_lowpan->frags.low_thresh = IPV6_FRAG_LOW_THRESH; |
535 | ieee802154_lowpan->frags.timeout = IPV6_FRAG_TIMEOUT; | 527 | ieee802154_lowpan->frags.timeout = IPV6_FRAG_TIMEOUT; |
536 | ieee802154_lowpan->max_dsize = 0xFFFF; | ||
537 | 528 | ||
538 | inet_frags_init_net(&ieee802154_lowpan->frags); | 529 | inet_frags_init_net(&ieee802154_lowpan->frags); |
539 | 530 | ||
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index afed1aac2638..bda4bb8ae260 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c | |||
@@ -79,10 +79,10 @@ static void __tunnel_dst_set(struct ip_tunnel_dst *idst, | |||
79 | idst->saddr = saddr; | 79 | idst->saddr = saddr; |
80 | } | 80 | } |
81 | 81 | ||
82 | static void tunnel_dst_set(struct ip_tunnel *t, | 82 | static noinline void tunnel_dst_set(struct ip_tunnel *t, |
83 | struct dst_entry *dst, __be32 saddr) | 83 | struct dst_entry *dst, __be32 saddr) |
84 | { | 84 | { |
85 | __tunnel_dst_set(this_cpu_ptr(t->dst_cache), dst, saddr); | 85 | __tunnel_dst_set(raw_cpu_ptr(t->dst_cache), dst, saddr); |
86 | } | 86 | } |
87 | 87 | ||
88 | static void tunnel_dst_reset(struct ip_tunnel *t) | 88 | static void tunnel_dst_reset(struct ip_tunnel *t) |
@@ -106,7 +106,7 @@ static struct rtable *tunnel_rtable_get(struct ip_tunnel *t, | |||
106 | struct dst_entry *dst; | 106 | struct dst_entry *dst; |
107 | 107 | ||
108 | rcu_read_lock(); | 108 | rcu_read_lock(); |
109 | idst = this_cpu_ptr(t->dst_cache); | 109 | idst = raw_cpu_ptr(t->dst_cache); |
110 | dst = rcu_dereference(idst->dst); | 110 | dst = rcu_dereference(idst->dst); |
111 | if (dst && !atomic_inc_not_zero(&dst->__refcnt)) | 111 | if (dst && !atomic_inc_not_zero(&dst->__refcnt)) |
112 | dst = NULL; | 112 | dst = NULL; |
@@ -764,9 +764,14 @@ int ip_tunnel_ioctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd) | |||
764 | 764 | ||
765 | t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type); | 765 | t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type); |
766 | 766 | ||
767 | if (!t && (cmd == SIOCADDTUNNEL)) { | 767 | if (cmd == SIOCADDTUNNEL) { |
768 | t = ip_tunnel_create(net, itn, p); | 768 | if (!t) { |
769 | err = PTR_ERR_OR_ZERO(t); | 769 | t = ip_tunnel_create(net, itn, p); |
770 | err = PTR_ERR_OR_ZERO(t); | ||
771 | break; | ||
772 | } | ||
773 | |||
774 | err = -EEXIST; | ||
770 | break; | 775 | break; |
771 | } | 776 | } |
772 | if (dev != itn->fb_tunnel_dev && cmd == SIOCCHGTUNNEL) { | 777 | if (dev != itn->fb_tunnel_dev && cmd == SIOCCHGTUNNEL) { |
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index fb173126f03d..7cbcaf4f0194 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig | |||
@@ -82,6 +82,52 @@ config NF_TABLES_ARP | |||
82 | help | 82 | help |
83 | This option enables the ARP support for nf_tables. | 83 | This option enables the ARP support for nf_tables. |
84 | 84 | ||
85 | config NF_NAT_IPV4 | ||
86 | tristate "IPv4 NAT" | ||
87 | depends on NF_CONNTRACK_IPV4 | ||
88 | default m if NETFILTER_ADVANCED=n | ||
89 | select NF_NAT | ||
90 | help | ||
91 | The IPv4 NAT option allows masquerading, port forwarding and other | ||
92 | forms of full Network Address Port Translation. This can be | ||
93 | controlled by iptables or nft. | ||
94 | |||
95 | if NF_NAT_IPV4 | ||
96 | |||
97 | config NF_NAT_SNMP_BASIC | ||
98 | tristate "Basic SNMP-ALG support" | ||
99 | depends on NF_CONNTRACK_SNMP | ||
100 | depends on NETFILTER_ADVANCED | ||
101 | default NF_NAT && NF_CONNTRACK_SNMP | ||
102 | ---help--- | ||
103 | |||
104 | This module implements an Application Layer Gateway (ALG) for | ||
105 | SNMP payloads. In conjunction with NAT, it allows a network | ||
106 | management system to access multiple private networks with | ||
107 | conflicting addresses. It works by modifying IP addresses | ||
108 | inside SNMP payloads to match IP-layer NAT mapping. | ||
109 | |||
110 | This is the "basic" form of SNMP-ALG, as described in RFC 2962 | ||
111 | |||
112 | To compile it as a module, choose M here. If unsure, say N. | ||
113 | |||
114 | config NF_NAT_PROTO_GRE | ||
115 | tristate | ||
116 | depends on NF_CT_PROTO_GRE | ||
117 | |||
118 | config NF_NAT_PPTP | ||
119 | tristate | ||
120 | depends on NF_CONNTRACK | ||
121 | default NF_CONNTRACK_PPTP | ||
122 | select NF_NAT_PROTO_GRE | ||
123 | |||
124 | config NF_NAT_H323 | ||
125 | tristate | ||
126 | depends on NF_CONNTRACK | ||
127 | default NF_CONNTRACK_H323 | ||
128 | |||
129 | endif # NF_NAT_IPV4 | ||
130 | |||
85 | config IP_NF_IPTABLES | 131 | config IP_NF_IPTABLES |
86 | tristate "IP tables support (required for filtering/masq/NAT)" | 132 | tristate "IP tables support (required for filtering/masq/NAT)" |
87 | default m if NETFILTER_ADVANCED=n | 133 | default m if NETFILTER_ADVANCED=n |
@@ -170,19 +216,21 @@ config IP_NF_TARGET_SYNPROXY | |||
170 | To compile it as a module, choose M here. If unsure, say N. | 216 | To compile it as a module, choose M here. If unsure, say N. |
171 | 217 | ||
172 | # NAT + specific targets: nf_conntrack | 218 | # NAT + specific targets: nf_conntrack |
173 | config NF_NAT_IPV4 | 219 | config IP_NF_NAT |
174 | tristate "IPv4 NAT" | 220 | tristate "iptables NAT support" |
175 | depends on NF_CONNTRACK_IPV4 | 221 | depends on NF_CONNTRACK_IPV4 |
176 | default m if NETFILTER_ADVANCED=n | 222 | default m if NETFILTER_ADVANCED=n |
177 | select NF_NAT | 223 | select NF_NAT |
224 | select NF_NAT_IPV4 | ||
225 | select NETFILTER_XT_NAT | ||
178 | help | 226 | help |
179 | The IPv4 NAT option allows masquerading, port forwarding and other | 227 | This enables the `nat' table in iptables. This allows masquerading, |
180 | forms of full Network Address Port Translation. It is controlled by | 228 | port forwarding and other forms of full Network Address Port |
181 | the `nat' table in iptables: see the man page for iptables(8). | 229 | Translation. |
182 | 230 | ||
183 | To compile it as a module, choose M here. If unsure, say N. | 231 | To compile it as a module, choose M here. If unsure, say N. |
184 | 232 | ||
185 | if NF_NAT_IPV4 | 233 | if IP_NF_NAT |
186 | 234 | ||
187 | config IP_NF_TARGET_MASQUERADE | 235 | config IP_NF_TARGET_MASQUERADE |
188 | tristate "MASQUERADE target support" | 236 | tristate "MASQUERADE target support" |
@@ -214,47 +262,7 @@ config IP_NF_TARGET_REDIRECT | |||
214 | (e.g. when running oldconfig). It selects | 262 | (e.g. when running oldconfig). It selects |
215 | CONFIG_NETFILTER_XT_TARGET_REDIRECT. | 263 | CONFIG_NETFILTER_XT_TARGET_REDIRECT. |
216 | 264 | ||
217 | endif | 265 | endif # IP_NF_NAT |
218 | |||
219 | config NF_NAT_SNMP_BASIC | ||
220 | tristate "Basic SNMP-ALG support" | ||
221 | depends on NF_CONNTRACK_SNMP && NF_NAT_IPV4 | ||
222 | depends on NETFILTER_ADVANCED | ||
223 | default NF_NAT && NF_CONNTRACK_SNMP | ||
224 | ---help--- | ||
225 | |||
226 | This module implements an Application Layer Gateway (ALG) for | ||
227 | SNMP payloads. In conjunction with NAT, it allows a network | ||
228 | management system to access multiple private networks with | ||
229 | conflicting addresses. It works by modifying IP addresses | ||
230 | inside SNMP payloads to match IP-layer NAT mapping. | ||
231 | |||
232 | This is the "basic" form of SNMP-ALG, as described in RFC 2962 | ||
233 | |||
234 | To compile it as a module, choose M here. If unsure, say N. | ||
235 | |||
236 | # If they want FTP, set to $CONFIG_IP_NF_NAT (m or y), | ||
237 | # or $CONFIG_IP_NF_FTP (m or y), whichever is weaker. | ||
238 | # From kconfig-language.txt: | ||
239 | # | ||
240 | # <expr> '&&' <expr> (6) | ||
241 | # | ||
242 | # (6) Returns the result of min(/expr/, /expr/). | ||
243 | |||
244 | config NF_NAT_PROTO_GRE | ||
245 | tristate | ||
246 | depends on NF_NAT_IPV4 && NF_CT_PROTO_GRE | ||
247 | |||
248 | config NF_NAT_PPTP | ||
249 | tristate | ||
250 | depends on NF_CONNTRACK && NF_NAT_IPV4 | ||
251 | default NF_NAT_IPV4 && NF_CONNTRACK_PPTP | ||
252 | select NF_NAT_PROTO_GRE | ||
253 | |||
254 | config NF_NAT_H323 | ||
255 | tristate | ||
256 | depends on NF_CONNTRACK && NF_NAT_IPV4 | ||
257 | default NF_NAT_IPV4 && NF_CONNTRACK_H323 | ||
258 | 266 | ||
259 | # mangle + specific targets | 267 | # mangle + specific targets |
260 | config IP_NF_MANGLE | 268 | config IP_NF_MANGLE |
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile index 33001621465b..edf4af32e9f2 100644 --- a/net/ipv4/netfilter/Makefile +++ b/net/ipv4/netfilter/Makefile | |||
@@ -43,7 +43,7 @@ obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o | |||
43 | # the three instances of ip_tables | 43 | # the three instances of ip_tables |
44 | obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o | 44 | obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o |
45 | obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o | 45 | obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o |
46 | obj-$(CONFIG_NF_NAT_IPV4) += iptable_nat.o | 46 | obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o |
47 | obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o | 47 | obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o |
48 | obj-$(CONFIG_IP_NF_SECURITY) += iptable_security.o | 48 | obj-$(CONFIG_IP_NF_SECURITY) += iptable_security.o |
49 | 49 | ||
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index eaa4b000c7b4..cbadb942c332 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -746,7 +746,7 @@ static void __ip_do_redirect(struct rtable *rt, struct sk_buff *skb, struct flow | |||
746 | } | 746 | } |
747 | 747 | ||
748 | n = ipv4_neigh_lookup(&rt->dst, NULL, &new_gw); | 748 | n = ipv4_neigh_lookup(&rt->dst, NULL, &new_gw); |
749 | if (n) { | 749 | if (!IS_ERR(n)) { |
750 | if (!(n->nud_state & NUD_VALID)) { | 750 | if (!(n->nud_state & NUD_VALID)) { |
751 | neigh_event_send(n, NULL); | 751 | neigh_event_send(n, NULL); |
752 | } else { | 752 | } else { |
@@ -2265,9 +2265,9 @@ struct rtable *ip_route_output_flow(struct net *net, struct flowi4 *flp4, | |||
2265 | return rt; | 2265 | return rt; |
2266 | 2266 | ||
2267 | if (flp4->flowi4_proto) | 2267 | if (flp4->flowi4_proto) |
2268 | rt = (struct rtable *) xfrm_lookup(net, &rt->dst, | 2268 | rt = (struct rtable *)xfrm_lookup_route(net, &rt->dst, |
2269 | flowi4_to_flowi(flp4), | 2269 | flowi4_to_flowi(flp4), |
2270 | sk, 0); | 2270 | sk, 0); |
2271 | 2271 | ||
2272 | return rt; | 2272 | return rt; |
2273 | } | 2273 | } |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 0b239fc1816e..3e118dfddd02 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -1690,14 +1690,12 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp) | |||
1690 | addrconf_mod_dad_work(ifp, 0); | 1690 | addrconf_mod_dad_work(ifp, 0); |
1691 | } | 1691 | } |
1692 | 1692 | ||
1693 | /* Join to solicited addr multicast group. */ | 1693 | /* Join to solicited addr multicast group. |
1694 | 1694 | * caller must hold RTNL */ | |
1695 | void addrconf_join_solict(struct net_device *dev, const struct in6_addr *addr) | 1695 | void addrconf_join_solict(struct net_device *dev, const struct in6_addr *addr) |
1696 | { | 1696 | { |
1697 | struct in6_addr maddr; | 1697 | struct in6_addr maddr; |
1698 | 1698 | ||
1699 | ASSERT_RTNL(); | ||
1700 | |||
1701 | if (dev->flags&(IFF_LOOPBACK|IFF_NOARP)) | 1699 | if (dev->flags&(IFF_LOOPBACK|IFF_NOARP)) |
1702 | return; | 1700 | return; |
1703 | 1701 | ||
@@ -1705,12 +1703,11 @@ void addrconf_join_solict(struct net_device *dev, const struct in6_addr *addr) | |||
1705 | ipv6_dev_mc_inc(dev, &maddr); | 1703 | ipv6_dev_mc_inc(dev, &maddr); |
1706 | } | 1704 | } |
1707 | 1705 | ||
1706 | /* caller must hold RTNL */ | ||
1708 | void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr) | 1707 | void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr) |
1709 | { | 1708 | { |
1710 | struct in6_addr maddr; | 1709 | struct in6_addr maddr; |
1711 | 1710 | ||
1712 | ASSERT_RTNL(); | ||
1713 | |||
1714 | if (idev->dev->flags&(IFF_LOOPBACK|IFF_NOARP)) | 1711 | if (idev->dev->flags&(IFF_LOOPBACK|IFF_NOARP)) |
1715 | return; | 1712 | return; |
1716 | 1713 | ||
@@ -1718,12 +1715,11 @@ void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr) | |||
1718 | __ipv6_dev_mc_dec(idev, &maddr); | 1715 | __ipv6_dev_mc_dec(idev, &maddr); |
1719 | } | 1716 | } |
1720 | 1717 | ||
1718 | /* caller must hold RTNL */ | ||
1721 | static void addrconf_join_anycast(struct inet6_ifaddr *ifp) | 1719 | static void addrconf_join_anycast(struct inet6_ifaddr *ifp) |
1722 | { | 1720 | { |
1723 | struct in6_addr addr; | 1721 | struct in6_addr addr; |
1724 | 1722 | ||
1725 | ASSERT_RTNL(); | ||
1726 | |||
1727 | if (ifp->prefix_len >= 127) /* RFC 6164 */ | 1723 | if (ifp->prefix_len >= 127) /* RFC 6164 */ |
1728 | return; | 1724 | return; |
1729 | ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); | 1725 | ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); |
@@ -1732,12 +1728,11 @@ static void addrconf_join_anycast(struct inet6_ifaddr *ifp) | |||
1732 | ipv6_dev_ac_inc(ifp->idev->dev, &addr); | 1728 | ipv6_dev_ac_inc(ifp->idev->dev, &addr); |
1733 | } | 1729 | } |
1734 | 1730 | ||
1731 | /* caller must hold RTNL */ | ||
1735 | static void addrconf_leave_anycast(struct inet6_ifaddr *ifp) | 1732 | static void addrconf_leave_anycast(struct inet6_ifaddr *ifp) |
1736 | { | 1733 | { |
1737 | struct in6_addr addr; | 1734 | struct in6_addr addr; |
1738 | 1735 | ||
1739 | ASSERT_RTNL(); | ||
1740 | |||
1741 | if (ifp->prefix_len >= 127) /* RFC 6164 */ | 1736 | if (ifp->prefix_len >= 127) /* RFC 6164 */ |
1742 | return; | 1737 | return; |
1743 | ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); | 1738 | ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); |
@@ -3099,11 +3094,13 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
3099 | 3094 | ||
3100 | write_unlock_bh(&idev->lock); | 3095 | write_unlock_bh(&idev->lock); |
3101 | 3096 | ||
3102 | /* Step 5: Discard multicast list */ | 3097 | /* Step 5: Discard anycast and multicast list */ |
3103 | if (how) | 3098 | if (how) { |
3099 | ipv6_ac_destroy_dev(idev); | ||
3104 | ipv6_mc_destroy_dev(idev); | 3100 | ipv6_mc_destroy_dev(idev); |
3105 | else | 3101 | } else { |
3106 | ipv6_mc_down(idev); | 3102 | ipv6_mc_down(idev); |
3103 | } | ||
3107 | 3104 | ||
3108 | idev->tstamp = jiffies; | 3105 | idev->tstamp = jiffies; |
3109 | 3106 | ||
@@ -4773,24 +4770,21 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) | |||
4773 | addrconf_leave_solict(ifp->idev, &ifp->addr); | 4770 | addrconf_leave_solict(ifp->idev, &ifp->addr); |
4774 | if (!ipv6_addr_any(&ifp->peer_addr)) { | 4771 | if (!ipv6_addr_any(&ifp->peer_addr)) { |
4775 | struct rt6_info *rt; | 4772 | struct rt6_info *rt; |
4776 | struct net_device *dev = ifp->idev->dev; | 4773 | |
4777 | 4774 | rt = addrconf_get_prefix_route(&ifp->peer_addr, 128, | |
4778 | rt = rt6_lookup(dev_net(dev), &ifp->peer_addr, NULL, | 4775 | ifp->idev->dev, 0, 0); |
4779 | dev->ifindex, 1); | 4776 | if (rt && ip6_del_rt(rt)) |
4780 | if (rt) { | 4777 | dst_free(&rt->dst); |
4781 | dst_hold(&rt->dst); | ||
4782 | if (ip6_del_rt(rt)) | ||
4783 | dst_free(&rt->dst); | ||
4784 | } | ||
4785 | } | 4778 | } |
4786 | dst_hold(&ifp->rt->dst); | 4779 | dst_hold(&ifp->rt->dst); |
4787 | 4780 | ||
4788 | if (ip6_del_rt(ifp->rt)) | 4781 | if (ip6_del_rt(ifp->rt)) |
4789 | dst_free(&ifp->rt->dst); | 4782 | dst_free(&ifp->rt->dst); |
4783 | |||
4784 | rt_genid_bump_ipv6(net); | ||
4790 | break; | 4785 | break; |
4791 | } | 4786 | } |
4792 | atomic_inc(&net->ipv6.dev_addr_genid); | 4787 | atomic_inc(&net->ipv6.dev_addr_genid); |
4793 | rt_genid_bump_ipv6(net); | ||
4794 | } | 4788 | } |
4795 | 4789 | ||
4796 | static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) | 4790 | static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) |
diff --git a/net/ipv6/addrconf_core.c b/net/ipv6/addrconf_core.c index e6960457f625..98cc4cd570e2 100644 --- a/net/ipv6/addrconf_core.c +++ b/net/ipv6/addrconf_core.c | |||
@@ -8,6 +8,13 @@ | |||
8 | #include <net/addrconf.h> | 8 | #include <net/addrconf.h> |
9 | #include <net/ip.h> | 9 | #include <net/ip.h> |
10 | 10 | ||
11 | /* if ipv6 module registers this function is used by xfrm to force all | ||
12 | * sockets to relookup their nodes - this is fairly expensive, be | ||
13 | * careful | ||
14 | */ | ||
15 | void (*__fib6_flush_trees)(struct net *); | ||
16 | EXPORT_SYMBOL(__fib6_flush_trees); | ||
17 | |||
11 | #define IPV6_ADDR_SCOPE_TYPE(scope) ((scope) << 16) | 18 | #define IPV6_ADDR_SCOPE_TYPE(scope) ((scope) << 16) |
12 | 19 | ||
13 | static inline unsigned int ipv6_addr_scope2type(unsigned int scope) | 20 | static inline unsigned int ipv6_addr_scope2type(unsigned int scope) |
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c index 210183244689..9a386842fd62 100644 --- a/net/ipv6/anycast.c +++ b/net/ipv6/anycast.c | |||
@@ -77,6 +77,7 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, const struct in6_addr *addr) | |||
77 | pac->acl_next = NULL; | 77 | pac->acl_next = NULL; |
78 | pac->acl_addr = *addr; | 78 | pac->acl_addr = *addr; |
79 | 79 | ||
80 | rtnl_lock(); | ||
80 | rcu_read_lock(); | 81 | rcu_read_lock(); |
81 | if (ifindex == 0) { | 82 | if (ifindex == 0) { |
82 | struct rt6_info *rt; | 83 | struct rt6_info *rt; |
@@ -137,6 +138,7 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, const struct in6_addr *addr) | |||
137 | 138 | ||
138 | error: | 139 | error: |
139 | rcu_read_unlock(); | 140 | rcu_read_unlock(); |
141 | rtnl_unlock(); | ||
140 | if (pac) | 142 | if (pac) |
141 | sock_kfree_s(sk, pac, sizeof(*pac)); | 143 | sock_kfree_s(sk, pac, sizeof(*pac)); |
142 | return err; | 144 | return err; |
@@ -171,11 +173,13 @@ int ipv6_sock_ac_drop(struct sock *sk, int ifindex, const struct in6_addr *addr) | |||
171 | 173 | ||
172 | spin_unlock_bh(&ipv6_sk_ac_lock); | 174 | spin_unlock_bh(&ipv6_sk_ac_lock); |
173 | 175 | ||
176 | rtnl_lock(); | ||
174 | rcu_read_lock(); | 177 | rcu_read_lock(); |
175 | dev = dev_get_by_index_rcu(net, pac->acl_ifindex); | 178 | dev = dev_get_by_index_rcu(net, pac->acl_ifindex); |
176 | if (dev) | 179 | if (dev) |
177 | ipv6_dev_ac_dec(dev, &pac->acl_addr); | 180 | ipv6_dev_ac_dec(dev, &pac->acl_addr); |
178 | rcu_read_unlock(); | 181 | rcu_read_unlock(); |
182 | rtnl_unlock(); | ||
179 | 183 | ||
180 | sock_kfree_s(sk, pac, sizeof(*pac)); | 184 | sock_kfree_s(sk, pac, sizeof(*pac)); |
181 | return 0; | 185 | return 0; |
@@ -198,6 +202,7 @@ void ipv6_sock_ac_close(struct sock *sk) | |||
198 | spin_unlock_bh(&ipv6_sk_ac_lock); | 202 | spin_unlock_bh(&ipv6_sk_ac_lock); |
199 | 203 | ||
200 | prev_index = 0; | 204 | prev_index = 0; |
205 | rtnl_lock(); | ||
201 | rcu_read_lock(); | 206 | rcu_read_lock(); |
202 | while (pac) { | 207 | while (pac) { |
203 | struct ipv6_ac_socklist *next = pac->acl_next; | 208 | struct ipv6_ac_socklist *next = pac->acl_next; |
@@ -212,6 +217,7 @@ void ipv6_sock_ac_close(struct sock *sk) | |||
212 | pac = next; | 217 | pac = next; |
213 | } | 218 | } |
214 | rcu_read_unlock(); | 219 | rcu_read_unlock(); |
220 | rtnl_unlock(); | ||
215 | } | 221 | } |
216 | 222 | ||
217 | static void aca_put(struct ifacaddr6 *ac) | 223 | static void aca_put(struct ifacaddr6 *ac) |
@@ -233,6 +239,8 @@ int ipv6_dev_ac_inc(struct net_device *dev, const struct in6_addr *addr) | |||
233 | struct rt6_info *rt; | 239 | struct rt6_info *rt; |
234 | int err; | 240 | int err; |
235 | 241 | ||
242 | ASSERT_RTNL(); | ||
243 | |||
236 | idev = in6_dev_get(dev); | 244 | idev = in6_dev_get(dev); |
237 | 245 | ||
238 | if (idev == NULL) | 246 | if (idev == NULL) |
@@ -302,6 +310,8 @@ int __ipv6_dev_ac_dec(struct inet6_dev *idev, const struct in6_addr *addr) | |||
302 | { | 310 | { |
303 | struct ifacaddr6 *aca, *prev_aca; | 311 | struct ifacaddr6 *aca, *prev_aca; |
304 | 312 | ||
313 | ASSERT_RTNL(); | ||
314 | |||
305 | write_lock_bh(&idev->lock); | 315 | write_lock_bh(&idev->lock); |
306 | prev_aca = NULL; | 316 | prev_aca = NULL; |
307 | for (aca = idev->ac_list; aca; aca = aca->aca_next) { | 317 | for (aca = idev->ac_list; aca; aca = aca->aca_next) { |
@@ -341,6 +351,27 @@ static int ipv6_dev_ac_dec(struct net_device *dev, const struct in6_addr *addr) | |||
341 | return __ipv6_dev_ac_dec(idev, addr); | 351 | return __ipv6_dev_ac_dec(idev, addr); |
342 | } | 352 | } |
343 | 353 | ||
354 | void ipv6_ac_destroy_dev(struct inet6_dev *idev) | ||
355 | { | ||
356 | struct ifacaddr6 *aca; | ||
357 | |||
358 | write_lock_bh(&idev->lock); | ||
359 | while ((aca = idev->ac_list) != NULL) { | ||
360 | idev->ac_list = aca->aca_next; | ||
361 | write_unlock_bh(&idev->lock); | ||
362 | |||
363 | addrconf_leave_solict(idev, &aca->aca_addr); | ||
364 | |||
365 | dst_hold(&aca->aca_rt->dst); | ||
366 | ip6_del_rt(aca->aca_rt); | ||
367 | |||
368 | aca_put(aca); | ||
369 | |||
370 | write_lock_bh(&idev->lock); | ||
371 | } | ||
372 | write_unlock_bh(&idev->lock); | ||
373 | } | ||
374 | |||
344 | /* | 375 | /* |
345 | * check if the interface has this anycast address | 376 | * check if the interface has this anycast address |
346 | * called with rcu_read_lock() | 377 | * called with rcu_read_lock() |
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 76b7f5ee8f4c..97b9fa8de377 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
@@ -1605,6 +1605,24 @@ static void fib6_prune_clones(struct net *net, struct fib6_node *fn) | |||
1605 | fib6_clean_tree(net, fn, fib6_prune_clone, 1, NULL); | 1605 | fib6_clean_tree(net, fn, fib6_prune_clone, 1, NULL); |
1606 | } | 1606 | } |
1607 | 1607 | ||
1608 | static int fib6_update_sernum(struct rt6_info *rt, void *arg) | ||
1609 | { | ||
1610 | __u32 sernum = *(__u32 *)arg; | ||
1611 | |||
1612 | if (rt->rt6i_node && | ||
1613 | rt->rt6i_node->fn_sernum != sernum) | ||
1614 | rt->rt6i_node->fn_sernum = sernum; | ||
1615 | |||
1616 | return 0; | ||
1617 | } | ||
1618 | |||
1619 | static void fib6_flush_trees(struct net *net) | ||
1620 | { | ||
1621 | __u32 new_sernum = fib6_new_sernum(); | ||
1622 | |||
1623 | fib6_clean_all(net, fib6_update_sernum, &new_sernum); | ||
1624 | } | ||
1625 | |||
1608 | /* | 1626 | /* |
1609 | * Garbage collection | 1627 | * Garbage collection |
1610 | */ | 1628 | */ |
@@ -1788,6 +1806,8 @@ int __init fib6_init(void) | |||
1788 | NULL); | 1806 | NULL); |
1789 | if (ret) | 1807 | if (ret) |
1790 | goto out_unregister_subsys; | 1808 | goto out_unregister_subsys; |
1809 | |||
1810 | __fib6_flush_trees = fib6_flush_trees; | ||
1791 | out: | 1811 | out: |
1792 | return ret; | 1812 | return ret; |
1793 | 1813 | ||
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 5f19dfbc4c6a..f304471477dc 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c | |||
@@ -314,6 +314,8 @@ static struct ip6_tnl *ip6gre_tunnel_locate(struct net *net, | |||
314 | struct ip6gre_net *ign = net_generic(net, ip6gre_net_id); | 314 | struct ip6gre_net *ign = net_generic(net, ip6gre_net_id); |
315 | 315 | ||
316 | t = ip6gre_tunnel_find(net, parms, ARPHRD_IP6GRE); | 316 | t = ip6gre_tunnel_find(net, parms, ARPHRD_IP6GRE); |
317 | if (t && create) | ||
318 | return NULL; | ||
317 | if (t || !create) | 319 | if (t || !create) |
318 | return t; | 320 | return t; |
319 | 321 | ||
@@ -1724,4 +1726,5 @@ MODULE_LICENSE("GPL"); | |||
1724 | MODULE_AUTHOR("D. Kozlov (xeb@mail.ru)"); | 1726 | MODULE_AUTHOR("D. Kozlov (xeb@mail.ru)"); |
1725 | MODULE_DESCRIPTION("GRE over IPv6 tunneling device"); | 1727 | MODULE_DESCRIPTION("GRE over IPv6 tunneling device"); |
1726 | MODULE_ALIAS_RTNL_LINK("ip6gre"); | 1728 | MODULE_ALIAS_RTNL_LINK("ip6gre"); |
1729 | MODULE_ALIAS_RTNL_LINK("ip6gretap"); | ||
1727 | MODULE_ALIAS_NETDEV("ip6gre0"); | 1730 | MODULE_ALIAS_NETDEV("ip6gre0"); |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 315a55d66079..0a3448b2888f 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -1009,7 +1009,7 @@ struct dst_entry *ip6_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6, | |||
1009 | if (final_dst) | 1009 | if (final_dst) |
1010 | fl6->daddr = *final_dst; | 1010 | fl6->daddr = *final_dst; |
1011 | 1011 | ||
1012 | return xfrm_lookup(sock_net(sk), dst, flowi6_to_flowi(fl6), sk, 0); | 1012 | return xfrm_lookup_route(sock_net(sk), dst, flowi6_to_flowi(fl6), sk, 0); |
1013 | } | 1013 | } |
1014 | EXPORT_SYMBOL_GPL(ip6_dst_lookup_flow); | 1014 | EXPORT_SYMBOL_GPL(ip6_dst_lookup_flow); |
1015 | 1015 | ||
@@ -1041,7 +1041,7 @@ struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6, | |||
1041 | if (final_dst) | 1041 | if (final_dst) |
1042 | fl6->daddr = *final_dst; | 1042 | fl6->daddr = *final_dst; |
1043 | 1043 | ||
1044 | return xfrm_lookup(sock_net(sk), dst, flowi6_to_flowi(fl6), sk, 0); | 1044 | return xfrm_lookup_route(sock_net(sk), dst, flowi6_to_flowi(fl6), sk, 0); |
1045 | } | 1045 | } |
1046 | EXPORT_SYMBOL_GPL(ip6_sk_dst_lookup_flow); | 1046 | EXPORT_SYMBOL_GPL(ip6_sk_dst_lookup_flow); |
1047 | 1047 | ||
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index f9de5a695072..69a84b464009 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -364,8 +364,12 @@ static struct ip6_tnl *ip6_tnl_locate(struct net *net, | |||
364 | (t = rtnl_dereference(*tp)) != NULL; | 364 | (t = rtnl_dereference(*tp)) != NULL; |
365 | tp = &t->next) { | 365 | tp = &t->next) { |
366 | if (ipv6_addr_equal(local, &t->parms.laddr) && | 366 | if (ipv6_addr_equal(local, &t->parms.laddr) && |
367 | ipv6_addr_equal(remote, &t->parms.raddr)) | 367 | ipv6_addr_equal(remote, &t->parms.raddr)) { |
368 | if (create) | ||
369 | return NULL; | ||
370 | |||
368 | return t; | 371 | return t; |
372 | } | ||
369 | } | 373 | } |
370 | if (!create) | 374 | if (!create) |
371 | return NULL; | 375 | return NULL; |
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index 7f52fd9fa7b0..5833a2244467 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c | |||
@@ -253,8 +253,12 @@ static struct ip6_tnl *vti6_locate(struct net *net, struct __ip6_tnl_parm *p, | |||
253 | (t = rtnl_dereference(*tp)) != NULL; | 253 | (t = rtnl_dereference(*tp)) != NULL; |
254 | tp = &t->next) { | 254 | tp = &t->next) { |
255 | if (ipv6_addr_equal(local, &t->parms.laddr) && | 255 | if (ipv6_addr_equal(local, &t->parms.laddr) && |
256 | ipv6_addr_equal(remote, &t->parms.raddr)) | 256 | ipv6_addr_equal(remote, &t->parms.raddr)) { |
257 | if (create) | ||
258 | return NULL; | ||
259 | |||
257 | return t; | 260 | return t; |
261 | } | ||
258 | } | 262 | } |
259 | if (!create) | 263 | if (!create) |
260 | return NULL; | 264 | return NULL; |
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 617f0958e164..a23b655a7627 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
@@ -172,6 +172,7 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr) | |||
172 | mc_lst->next = NULL; | 172 | mc_lst->next = NULL; |
173 | mc_lst->addr = *addr; | 173 | mc_lst->addr = *addr; |
174 | 174 | ||
175 | rtnl_lock(); | ||
175 | rcu_read_lock(); | 176 | rcu_read_lock(); |
176 | if (ifindex == 0) { | 177 | if (ifindex == 0) { |
177 | struct rt6_info *rt; | 178 | struct rt6_info *rt; |
@@ -185,6 +186,7 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr) | |||
185 | 186 | ||
186 | if (dev == NULL) { | 187 | if (dev == NULL) { |
187 | rcu_read_unlock(); | 188 | rcu_read_unlock(); |
189 | rtnl_unlock(); | ||
188 | sock_kfree_s(sk, mc_lst, sizeof(*mc_lst)); | 190 | sock_kfree_s(sk, mc_lst, sizeof(*mc_lst)); |
189 | return -ENODEV; | 191 | return -ENODEV; |
190 | } | 192 | } |
@@ -202,6 +204,7 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr) | |||
202 | 204 | ||
203 | if (err) { | 205 | if (err) { |
204 | rcu_read_unlock(); | 206 | rcu_read_unlock(); |
207 | rtnl_unlock(); | ||
205 | sock_kfree_s(sk, mc_lst, sizeof(*mc_lst)); | 208 | sock_kfree_s(sk, mc_lst, sizeof(*mc_lst)); |
206 | return err; | 209 | return err; |
207 | } | 210 | } |
@@ -212,6 +215,7 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr) | |||
212 | spin_unlock(&ipv6_sk_mc_lock); | 215 | spin_unlock(&ipv6_sk_mc_lock); |
213 | 216 | ||
214 | rcu_read_unlock(); | 217 | rcu_read_unlock(); |
218 | rtnl_unlock(); | ||
215 | 219 | ||
216 | return 0; | 220 | return 0; |
217 | } | 221 | } |
@@ -229,6 +233,7 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr) | |||
229 | if (!ipv6_addr_is_multicast(addr)) | 233 | if (!ipv6_addr_is_multicast(addr)) |
230 | return -EINVAL; | 234 | return -EINVAL; |
231 | 235 | ||
236 | rtnl_lock(); | ||
232 | spin_lock(&ipv6_sk_mc_lock); | 237 | spin_lock(&ipv6_sk_mc_lock); |
233 | for (lnk = &np->ipv6_mc_list; | 238 | for (lnk = &np->ipv6_mc_list; |
234 | (mc_lst = rcu_dereference_protected(*lnk, | 239 | (mc_lst = rcu_dereference_protected(*lnk, |
@@ -252,12 +257,15 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr) | |||
252 | } else | 257 | } else |
253 | (void) ip6_mc_leave_src(sk, mc_lst, NULL); | 258 | (void) ip6_mc_leave_src(sk, mc_lst, NULL); |
254 | rcu_read_unlock(); | 259 | rcu_read_unlock(); |
260 | rtnl_unlock(); | ||
261 | |||
255 | atomic_sub(sizeof(*mc_lst), &sk->sk_omem_alloc); | 262 | atomic_sub(sizeof(*mc_lst), &sk->sk_omem_alloc); |
256 | kfree_rcu(mc_lst, rcu); | 263 | kfree_rcu(mc_lst, rcu); |
257 | return 0; | 264 | return 0; |
258 | } | 265 | } |
259 | } | 266 | } |
260 | spin_unlock(&ipv6_sk_mc_lock); | 267 | spin_unlock(&ipv6_sk_mc_lock); |
268 | rtnl_unlock(); | ||
261 | 269 | ||
262 | return -EADDRNOTAVAIL; | 270 | return -EADDRNOTAVAIL; |
263 | } | 271 | } |
@@ -302,6 +310,7 @@ void ipv6_sock_mc_close(struct sock *sk) | |||
302 | if (!rcu_access_pointer(np->ipv6_mc_list)) | 310 | if (!rcu_access_pointer(np->ipv6_mc_list)) |
303 | return; | 311 | return; |
304 | 312 | ||
313 | rtnl_lock(); | ||
305 | spin_lock(&ipv6_sk_mc_lock); | 314 | spin_lock(&ipv6_sk_mc_lock); |
306 | while ((mc_lst = rcu_dereference_protected(np->ipv6_mc_list, | 315 | while ((mc_lst = rcu_dereference_protected(np->ipv6_mc_list, |
307 | lockdep_is_held(&ipv6_sk_mc_lock))) != NULL) { | 316 | lockdep_is_held(&ipv6_sk_mc_lock))) != NULL) { |
@@ -328,6 +337,7 @@ void ipv6_sock_mc_close(struct sock *sk) | |||
328 | spin_lock(&ipv6_sk_mc_lock); | 337 | spin_lock(&ipv6_sk_mc_lock); |
329 | } | 338 | } |
330 | spin_unlock(&ipv6_sk_mc_lock); | 339 | spin_unlock(&ipv6_sk_mc_lock); |
340 | rtnl_unlock(); | ||
331 | } | 341 | } |
332 | 342 | ||
333 | int ip6_mc_source(int add, int omode, struct sock *sk, | 343 | int ip6_mc_source(int add, int omode, struct sock *sk, |
@@ -845,6 +855,8 @@ int ipv6_dev_mc_inc(struct net_device *dev, const struct in6_addr *addr) | |||
845 | struct ifmcaddr6 *mc; | 855 | struct ifmcaddr6 *mc; |
846 | struct inet6_dev *idev; | 856 | struct inet6_dev *idev; |
847 | 857 | ||
858 | ASSERT_RTNL(); | ||
859 | |||
848 | /* we need to take a reference on idev */ | 860 | /* we need to take a reference on idev */ |
849 | idev = in6_dev_get(dev); | 861 | idev = in6_dev_get(dev); |
850 | 862 | ||
@@ -916,6 +928,8 @@ int __ipv6_dev_mc_dec(struct inet6_dev *idev, const struct in6_addr *addr) | |||
916 | { | 928 | { |
917 | struct ifmcaddr6 *ma, **map; | 929 | struct ifmcaddr6 *ma, **map; |
918 | 930 | ||
931 | ASSERT_RTNL(); | ||
932 | |||
919 | write_lock_bh(&idev->lock); | 933 | write_lock_bh(&idev->lock); |
920 | for (map = &idev->mc_list; (ma=*map) != NULL; map = &ma->next) { | 934 | for (map = &idev->mc_list; (ma=*map) != NULL; map = &ma->next) { |
921 | if (ipv6_addr_equal(&ma->mca_addr, addr)) { | 935 | if (ipv6_addr_equal(&ma->mca_addr, addr)) { |
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig index ac93df16f5af..2812816aabdc 100644 --- a/net/ipv6/netfilter/Kconfig +++ b/net/ipv6/netfilter/Kconfig | |||
@@ -57,9 +57,19 @@ config NFT_REJECT_IPV6 | |||
57 | 57 | ||
58 | config NF_LOG_IPV6 | 58 | config NF_LOG_IPV6 |
59 | tristate "IPv6 packet logging" | 59 | tristate "IPv6 packet logging" |
60 | depends on NETFILTER_ADVANCED | 60 | default m if NETFILTER_ADVANCED=n |
61 | select NF_LOG_COMMON | 61 | select NF_LOG_COMMON |
62 | 62 | ||
63 | config NF_NAT_IPV6 | ||
64 | tristate "IPv6 NAT" | ||
65 | depends on NF_CONNTRACK_IPV6 | ||
66 | depends on NETFILTER_ADVANCED | ||
67 | select NF_NAT | ||
68 | help | ||
69 | The IPv6 NAT option allows masquerading, port forwarding and other | ||
70 | forms of full Network Address Port Translation. This can be | ||
71 | controlled by iptables or nft. | ||
72 | |||
63 | config IP6_NF_IPTABLES | 73 | config IP6_NF_IPTABLES |
64 | tristate "IP6 tables support (required for filtering)" | 74 | tristate "IP6 tables support (required for filtering)" |
65 | depends on INET && IPV6 | 75 | depends on INET && IPV6 |
@@ -232,19 +242,21 @@ config IP6_NF_SECURITY | |||
232 | 242 | ||
233 | If unsure, say N. | 243 | If unsure, say N. |
234 | 244 | ||
235 | config NF_NAT_IPV6 | 245 | config IP6_NF_NAT |
236 | tristate "IPv6 NAT" | 246 | tristate "ip6tables NAT support" |
237 | depends on NF_CONNTRACK_IPV6 | 247 | depends on NF_CONNTRACK_IPV6 |
238 | depends on NETFILTER_ADVANCED | 248 | depends on NETFILTER_ADVANCED |
239 | select NF_NAT | 249 | select NF_NAT |
250 | select NF_NAT_IPV6 | ||
251 | select NETFILTER_XT_NAT | ||
240 | help | 252 | help |
241 | The IPv6 NAT option allows masquerading, port forwarding and other | 253 | This enables the `nat' table in ip6tables. This allows masquerading, |
242 | forms of full Network Address Port Translation. It is controlled by | 254 | port forwarding and other forms of full Network Address Port |
243 | the `nat' table in ip6tables, see the man page for ip6tables(8). | 255 | Translation. |
244 | 256 | ||
245 | To compile it as a module, choose M here. If unsure, say N. | 257 | To compile it as a module, choose M here. If unsure, say N. |
246 | 258 | ||
247 | if NF_NAT_IPV6 | 259 | if IP6_NF_NAT |
248 | 260 | ||
249 | config IP6_NF_TARGET_MASQUERADE | 261 | config IP6_NF_TARGET_MASQUERADE |
250 | tristate "MASQUERADE target support" | 262 | tristate "MASQUERADE target support" |
@@ -265,7 +277,7 @@ config IP6_NF_TARGET_NPT | |||
265 | 277 | ||
266 | To compile it as a module, choose M here. If unsure, say N. | 278 | To compile it as a module, choose M here. If unsure, say N. |
267 | 279 | ||
268 | endif # NF_NAT_IPV6 | 280 | endif # IP6_NF_NAT |
269 | 281 | ||
270 | endif # IP6_NF_IPTABLES | 282 | endif # IP6_NF_IPTABLES |
271 | 283 | ||
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile index c0b263104ed2..c3d3286db4bb 100644 --- a/net/ipv6/netfilter/Makefile +++ b/net/ipv6/netfilter/Makefile | |||
@@ -8,7 +8,7 @@ obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o | |||
8 | obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o | 8 | obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o |
9 | obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o | 9 | obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o |
10 | obj-$(CONFIG_IP6_NF_SECURITY) += ip6table_security.o | 10 | obj-$(CONFIG_IP6_NF_SECURITY) += ip6table_security.o |
11 | obj-$(CONFIG_NF_NAT_IPV6) += ip6table_nat.o | 11 | obj-$(CONFIG_IP6_NF_NAT) += ip6table_nat.o |
12 | 12 | ||
13 | # objects for l3 independent conntrack | 13 | # objects for l3 independent conntrack |
14 | nf_conntrack_ipv6-y := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o | 14 | nf_conntrack_ipv6-y := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index f23fbd28a501..bafde82324c5 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -314,7 +314,6 @@ static inline struct rt6_info *ip6_dst_alloc(struct net *net, | |||
314 | 314 | ||
315 | memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst)); | 315 | memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst)); |
316 | rt6_init_peer(rt, table ? &table->tb6_peers : net->ipv6.peers); | 316 | rt6_init_peer(rt, table ? &table->tb6_peers : net->ipv6.peers); |
317 | rt->rt6i_genid = rt_genid_ipv6(net); | ||
318 | INIT_LIST_HEAD(&rt->rt6i_siblings); | 317 | INIT_LIST_HEAD(&rt->rt6i_siblings); |
319 | } | 318 | } |
320 | return rt; | 319 | return rt; |
@@ -1098,9 +1097,6 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie) | |||
1098 | * DST_OBSOLETE_FORCE_CHK which forces validation calls down | 1097 | * DST_OBSOLETE_FORCE_CHK which forces validation calls down |
1099 | * into this function always. | 1098 | * into this function always. |
1100 | */ | 1099 | */ |
1101 | if (rt->rt6i_genid != rt_genid_ipv6(dev_net(rt->dst.dev))) | ||
1102 | return NULL; | ||
1103 | |||
1104 | if (!rt->rt6i_node || (rt->rt6i_node->fn_sernum != cookie)) | 1100 | if (!rt->rt6i_node || (rt->rt6i_node->fn_sernum != cookie)) |
1105 | return NULL; | 1101 | return NULL; |
1106 | 1102 | ||
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c index 13752d96275e..b704a9356208 100644 --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c | |||
@@ -755,7 +755,8 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, | |||
755 | /* If PMTU discovery was enabled, use the MTU that was discovered */ | 755 | /* If PMTU discovery was enabled, use the MTU that was discovered */ |
756 | dst = sk_dst_get(tunnel->sock); | 756 | dst = sk_dst_get(tunnel->sock); |
757 | if (dst != NULL) { | 757 | if (dst != NULL) { |
758 | u32 pmtu = dst_mtu(__sk_dst_get(tunnel->sock)); | 758 | u32 pmtu = dst_mtu(dst); |
759 | |||
759 | if (pmtu != 0) | 760 | if (pmtu != 0) |
760 | session->mtu = session->mru = pmtu - | 761 | session->mtu = session->mru = pmtu - |
761 | PPPOL2TP_HEADER_OVERHEAD; | 762 | PPPOL2TP_HEADER_OVERHEAD; |
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 0375009ddc0d..399ad82c997f 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c | |||
@@ -541,6 +541,8 @@ static void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local, | |||
541 | continue; | 541 | continue; |
542 | if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf) | 542 | if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf) |
543 | continue; | 543 | continue; |
544 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | ||
545 | continue; | ||
544 | 546 | ||
545 | if (!compat) | 547 | if (!compat) |
546 | compat = &sdata->vif.bss_conf.chandef; | 548 | compat = &sdata->vif.bss_conf.chandef; |
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 3db96648b45a..86173c0de40e 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c | |||
@@ -167,7 +167,7 @@ static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf, | |||
167 | p += scnprintf(p, sizeof(buf) + buf - p, "next dialog_token: %#02x\n", | 167 | p += scnprintf(p, sizeof(buf) + buf - p, "next dialog_token: %#02x\n", |
168 | sta->ampdu_mlme.dialog_token_allocator + 1); | 168 | sta->ampdu_mlme.dialog_token_allocator + 1); |
169 | p += scnprintf(p, sizeof(buf) + buf - p, | 169 | p += scnprintf(p, sizeof(buf) + buf - p, |
170 | "TID\t\tRX active\tDTKN\tSSN\t\tTX\tDTKN\tpending\n"); | 170 | "TID\t\tRX\tDTKN\tSSN\t\tTX\tDTKN\tpending\n"); |
171 | 171 | ||
172 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) { | 172 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) { |
173 | tid_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[i]); | 173 | tid_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[i]); |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 01eede7406a5..f75e5f132c5a 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -1175,8 +1175,8 @@ static void ieee80211_iface_work(struct work_struct *work) | |||
1175 | if (sta) { | 1175 | if (sta) { |
1176 | u16 last_seq; | 1176 | u16 last_seq; |
1177 | 1177 | ||
1178 | last_seq = le16_to_cpu( | 1178 | last_seq = IEEE80211_SEQ_TO_SN(le16_to_cpu( |
1179 | sta->last_seq_ctrl[rx_agg->tid]); | 1179 | sta->last_seq_ctrl[rx_agg->tid])); |
1180 | 1180 | ||
1181 | __ieee80211_start_rx_ba_session(sta, | 1181 | __ieee80211_start_rx_ba_session(sta, |
1182 | 0, 0, | 1182 | 0, 0, |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 63b874101b27..c47194d27149 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
@@ -959,7 +959,8 @@ mesh_plink_get_event(struct ieee80211_sub_if_data *sdata, | |||
959 | if (!matches_local) | 959 | if (!matches_local) |
960 | event = CNF_RJCT; | 960 | event = CNF_RJCT; |
961 | if (!mesh_plink_free_count(sdata) || | 961 | if (!mesh_plink_free_count(sdata) || |
962 | (sta->llid != llid || sta->plid != plid)) | 962 | sta->llid != llid || |
963 | (sta->plid && sta->plid != plid)) | ||
963 | event = CNF_IGNR; | 964 | event = CNF_IGNR; |
964 | else | 965 | else |
965 | event = CNF_ACPT; | 966 | event = CNF_ACPT; |
@@ -1080,6 +1081,10 @@ mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata, | |||
1080 | goto unlock_rcu; | 1081 | goto unlock_rcu; |
1081 | } | 1082 | } |
1082 | 1083 | ||
1084 | /* 802.11-2012 13.3.7.2 - update plid on CNF if not set */ | ||
1085 | if (!sta->plid && event == CNF_ACPT) | ||
1086 | sta->plid = plid; | ||
1087 | |||
1083 | changed |= mesh_plink_fsm(sdata, sta, event); | 1088 | changed |= mesh_plink_fsm(sdata, sta, event); |
1084 | 1089 | ||
1085 | unlock_rcu: | 1090 | unlock_rcu: |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 31a8afaf7332..b82a12a9f0f1 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -4376,8 +4376,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
4376 | rcu_read_unlock(); | 4376 | rcu_read_unlock(); |
4377 | 4377 | ||
4378 | if (bss->wmm_used && bss->uapsd_supported && | 4378 | if (bss->wmm_used && bss->uapsd_supported && |
4379 | (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD) && | 4379 | (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) { |
4380 | sdata->wmm_acm != 0xff) { | ||
4381 | assoc_data->uapsd = true; | 4380 | assoc_data->uapsd = true; |
4382 | ifmgd->flags |= IEEE80211_STA_UAPSD_ENABLED; | 4381 | ifmgd->flags |= IEEE80211_STA_UAPSD_ENABLED; |
4383 | } else { | 4382 | } else { |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index c6ee2139fbc5..a1e433b88c66 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -1094,8 +1094,11 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) | |||
1094 | unsigned long flags; | 1094 | unsigned long flags; |
1095 | struct ps_data *ps; | 1095 | struct ps_data *ps; |
1096 | 1096 | ||
1097 | if (sdata->vif.type == NL80211_IFTYPE_AP || | 1097 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) |
1098 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | 1098 | sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, |
1099 | u.ap); | ||
1100 | |||
1101 | if (sdata->vif.type == NL80211_IFTYPE_AP) | ||
1099 | ps = &sdata->bss->ps; | 1102 | ps = &sdata->bss->ps; |
1100 | else if (ieee80211_vif_is_mesh(&sdata->vif)) | 1103 | else if (ieee80211_vif_is_mesh(&sdata->vif)) |
1101 | ps = &sdata->u.mesh.ps; | 1104 | ps = &sdata->u.mesh.ps; |
@@ -1819,7 +1822,7 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
1819 | sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE; | 1822 | sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE; |
1820 | if (sdata->vif.bss_conf.use_short_slot) | 1823 | if (sdata->vif.bss_conf.use_short_slot) |
1821 | sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME; | 1824 | sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME; |
1822 | sinfo->bss_param.dtim_period = sdata->local->hw.conf.ps_dtim_period; | 1825 | sinfo->bss_param.dtim_period = sdata->vif.bss_conf.dtim_period; |
1823 | sinfo->bss_param.beacon_interval = sdata->vif.bss_conf.beacon_int; | 1826 | sinfo->bss_param.beacon_interval = sdata->vif.bss_conf.beacon_int; |
1824 | 1827 | ||
1825 | sinfo->sta_flags.set = 0; | 1828 | sinfo->sta_flags.set = 0; |
diff --git a/net/mac802154/wpan.c b/net/mac802154/wpan.c index 3c3069fd6971..547838822d5e 100644 --- a/net/mac802154/wpan.c +++ b/net/mac802154/wpan.c | |||
@@ -462,7 +462,10 @@ mac802154_subif_frame(struct mac802154_sub_if_data *sdata, struct sk_buff *skb, | |||
462 | skb->pkt_type = PACKET_OTHERHOST; | 462 | skb->pkt_type = PACKET_OTHERHOST; |
463 | break; | 463 | break; |
464 | default: | 464 | default: |
465 | break; | 465 | spin_unlock_bh(&sdata->mib_lock); |
466 | pr_debug("invalid dest mode\n"); | ||
467 | kfree_skb(skb); | ||
468 | return NET_RX_DROP; | ||
466 | } | 469 | } |
467 | 470 | ||
468 | spin_unlock_bh(&sdata->mib_lock); | 471 | spin_unlock_bh(&sdata->mib_lock); |
@@ -573,6 +576,7 @@ void mac802154_wpans_rx(struct mac802154_priv *priv, struct sk_buff *skb) | |||
573 | ret = mac802154_parse_frame_start(skb, &hdr); | 576 | ret = mac802154_parse_frame_start(skb, &hdr); |
574 | if (ret) { | 577 | if (ret) { |
575 | pr_debug("got invalid frame\n"); | 578 | pr_debug("got invalid frame\n"); |
579 | kfree_skb(skb); | ||
576 | return; | 580 | return; |
577 | } | 581 | } |
578 | 582 | ||
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index ad751fe2e82b..6d77cce481d5 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig | |||
@@ -499,7 +499,7 @@ config NFT_LIMIT | |||
499 | config NFT_NAT | 499 | config NFT_NAT |
500 | depends on NF_TABLES | 500 | depends on NF_TABLES |
501 | depends on NF_CONNTRACK | 501 | depends on NF_CONNTRACK |
502 | depends on NF_NAT | 502 | select NF_NAT |
503 | tristate "Netfilter nf_tables nat module" | 503 | tristate "Netfilter nf_tables nat module" |
504 | help | 504 | help |
505 | This option adds the "nat" expression that you can use to perform | 505 | This option adds the "nat" expression that you can use to perform |
@@ -747,7 +747,9 @@ config NETFILTER_XT_TARGET_LED | |||
747 | 747 | ||
748 | config NETFILTER_XT_TARGET_LOG | 748 | config NETFILTER_XT_TARGET_LOG |
749 | tristate "LOG target support" | 749 | tristate "LOG target support" |
750 | depends on NF_LOG_IPV4 && NF_LOG_IPV6 | 750 | select NF_LOG_COMMON |
751 | select NF_LOG_IPV4 | ||
752 | select NF_LOG_IPV6 if IPV6 | ||
751 | default m if NETFILTER_ADVANCED=n | 753 | default m if NETFILTER_ADVANCED=n |
752 | help | 754 | help |
753 | This option adds a `LOG' target, which allows you to create rules in | 755 | This option adds a `LOG' target, which allows you to create rules in |
@@ -764,6 +766,14 @@ config NETFILTER_XT_TARGET_MARK | |||
764 | (e.g. when running oldconfig). It selects | 766 | (e.g. when running oldconfig). It selects |
765 | CONFIG_NETFILTER_XT_MARK (combined mark/MARK module). | 767 | CONFIG_NETFILTER_XT_MARK (combined mark/MARK module). |
766 | 768 | ||
769 | config NETFILTER_XT_NAT | ||
770 | tristate '"SNAT and DNAT" targets support' | ||
771 | depends on NF_NAT | ||
772 | ---help--- | ||
773 | This option enables the SNAT and DNAT targets. | ||
774 | |||
775 | To compile it as a module, choose M here. If unsure, say N. | ||
776 | |||
767 | config NETFILTER_XT_TARGET_NETMAP | 777 | config NETFILTER_XT_TARGET_NETMAP |
768 | tristate '"NETMAP" target support' | 778 | tristate '"NETMAP" target support' |
769 | depends on NF_NAT | 779 | depends on NF_NAT |
@@ -837,6 +847,7 @@ config NETFILTER_XT_TARGET_TPROXY | |||
837 | tristate '"TPROXY" target transparent proxying support' | 847 | tristate '"TPROXY" target transparent proxying support' |
838 | depends on NETFILTER_XTABLES | 848 | depends on NETFILTER_XTABLES |
839 | depends on NETFILTER_ADVANCED | 849 | depends on NETFILTER_ADVANCED |
850 | depends on (IPV6 || IPV6=n) | ||
840 | depends on IP_NF_MANGLE | 851 | depends on IP_NF_MANGLE |
841 | select NF_DEFRAG_IPV4 | 852 | select NF_DEFRAG_IPV4 |
842 | select NF_DEFRAG_IPV6 if IP6_NF_IPTABLES | 853 | select NF_DEFRAG_IPV6 if IP6_NF_IPTABLES |
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile index 8308624a406a..fad5fdba34e5 100644 --- a/net/netfilter/Makefile +++ b/net/netfilter/Makefile | |||
@@ -95,7 +95,7 @@ obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o | |||
95 | obj-$(CONFIG_NETFILTER_XT_MARK) += xt_mark.o | 95 | obj-$(CONFIG_NETFILTER_XT_MARK) += xt_mark.o |
96 | obj-$(CONFIG_NETFILTER_XT_CONNMARK) += xt_connmark.o | 96 | obj-$(CONFIG_NETFILTER_XT_CONNMARK) += xt_connmark.o |
97 | obj-$(CONFIG_NETFILTER_XT_SET) += xt_set.o | 97 | obj-$(CONFIG_NETFILTER_XT_SET) += xt_set.o |
98 | obj-$(CONFIG_NF_NAT) += xt_nat.o | 98 | obj-$(CONFIG_NETFILTER_XT_NAT) += xt_nat.o |
99 | 99 | ||
100 | # targets | 100 | # targets |
101 | obj-$(CONFIG_NETFILTER_XT_TARGET_AUDIT) += xt_AUDIT.o | 101 | obj-$(CONFIG_NETFILTER_XT_TARGET_AUDIT) += xt_AUDIT.o |
diff --git a/net/netfilter/core.c b/net/netfilter/core.c index a93c97f106d4..024a2e25c8a4 100644 --- a/net/netfilter/core.c +++ b/net/netfilter/core.c | |||
@@ -54,7 +54,7 @@ EXPORT_SYMBOL_GPL(nf_unregister_afinfo); | |||
54 | struct list_head nf_hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS] __read_mostly; | 54 | struct list_head nf_hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS] __read_mostly; |
55 | EXPORT_SYMBOL(nf_hooks); | 55 | EXPORT_SYMBOL(nf_hooks); |
56 | 56 | ||
57 | #if defined(CONFIG_JUMP_LABEL) | 57 | #ifdef HAVE_JUMP_LABEL |
58 | struct static_key nf_hooks_needed[NFPROTO_NUMPROTO][NF_MAX_HOOKS]; | 58 | struct static_key nf_hooks_needed[NFPROTO_NUMPROTO][NF_MAX_HOOKS]; |
59 | EXPORT_SYMBOL(nf_hooks_needed); | 59 | EXPORT_SYMBOL(nf_hooks_needed); |
60 | #endif | 60 | #endif |
@@ -72,7 +72,7 @@ int nf_register_hook(struct nf_hook_ops *reg) | |||
72 | } | 72 | } |
73 | list_add_rcu(®->list, elem->list.prev); | 73 | list_add_rcu(®->list, elem->list.prev); |
74 | mutex_unlock(&nf_hook_mutex); | 74 | mutex_unlock(&nf_hook_mutex); |
75 | #if defined(CONFIG_JUMP_LABEL) | 75 | #ifdef HAVE_JUMP_LABEL |
76 | static_key_slow_inc(&nf_hooks_needed[reg->pf][reg->hooknum]); | 76 | static_key_slow_inc(&nf_hooks_needed[reg->pf][reg->hooknum]); |
77 | #endif | 77 | #endif |
78 | return 0; | 78 | return 0; |
@@ -84,7 +84,7 @@ void nf_unregister_hook(struct nf_hook_ops *reg) | |||
84 | mutex_lock(&nf_hook_mutex); | 84 | mutex_lock(&nf_hook_mutex); |
85 | list_del_rcu(®->list); | 85 | list_del_rcu(®->list); |
86 | mutex_unlock(&nf_hook_mutex); | 86 | mutex_unlock(&nf_hook_mutex); |
87 | #if defined(CONFIG_JUMP_LABEL) | 87 | #ifdef HAVE_JUMP_LABEL |
88 | static_key_slow_dec(&nf_hooks_needed[reg->pf][reg->hooknum]); | 88 | static_key_slow_dec(&nf_hooks_needed[reg->pf][reg->hooknum]); |
89 | #endif | 89 | #endif |
90 | synchronize_net(); | 90 | synchronize_net(); |
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index e6836755c45d..5c34e8d42e01 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c | |||
@@ -1906,7 +1906,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { | |||
1906 | { | 1906 | { |
1907 | .hook = ip_vs_local_reply6, | 1907 | .hook = ip_vs_local_reply6, |
1908 | .owner = THIS_MODULE, | 1908 | .owner = THIS_MODULE, |
1909 | .pf = NFPROTO_IPV4, | 1909 | .pf = NFPROTO_IPV6, |
1910 | .hooknum = NF_INET_LOCAL_OUT, | 1910 | .hooknum = NF_INET_LOCAL_OUT, |
1911 | .priority = NF_IP6_PRI_NAT_DST + 1, | 1911 | .priority = NF_IP6_PRI_NAT_DST + 1, |
1912 | }, | 1912 | }, |
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index 6f70bdd3a90a..56896a412bce 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <net/route.h> /* for ip_route_output */ | 38 | #include <net/route.h> /* for ip_route_output */ |
39 | #include <net/ipv6.h> | 39 | #include <net/ipv6.h> |
40 | #include <net/ip6_route.h> | 40 | #include <net/ip6_route.h> |
41 | #include <net/ip_tunnels.h> | ||
41 | #include <net/addrconf.h> | 42 | #include <net/addrconf.h> |
42 | #include <linux/icmpv6.h> | 43 | #include <linux/icmpv6.h> |
43 | #include <linux/netfilter.h> | 44 | #include <linux/netfilter.h> |
@@ -862,11 +863,15 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
862 | old_iph = ip_hdr(skb); | 863 | old_iph = ip_hdr(skb); |
863 | } | 864 | } |
864 | 865 | ||
865 | skb->transport_header = skb->network_header; | ||
866 | |||
867 | /* fix old IP header checksum */ | 866 | /* fix old IP header checksum */ |
868 | ip_send_check(old_iph); | 867 | ip_send_check(old_iph); |
869 | 868 | ||
869 | skb = iptunnel_handle_offloads(skb, false, SKB_GSO_IPIP); | ||
870 | if (IS_ERR(skb)) | ||
871 | goto tx_error; | ||
872 | |||
873 | skb->transport_header = skb->network_header; | ||
874 | |||
870 | skb_push(skb, sizeof(struct iphdr)); | 875 | skb_push(skb, sizeof(struct iphdr)); |
871 | skb_reset_network_header(skb); | 876 | skb_reset_network_header(skb); |
872 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); | 877 | memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); |
@@ -900,7 +905,8 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
900 | return NF_STOLEN; | 905 | return NF_STOLEN; |
901 | 906 | ||
902 | tx_error: | 907 | tx_error: |
903 | kfree_skb(skb); | 908 | if (!IS_ERR(skb)) |
909 | kfree_skb(skb); | ||
904 | rcu_read_unlock(); | 910 | rcu_read_unlock(); |
905 | LeaveFunction(10); | 911 | LeaveFunction(10); |
906 | return NF_STOLEN; | 912 | return NF_STOLEN; |
@@ -953,6 +959,11 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
953 | old_iph = ipv6_hdr(skb); | 959 | old_iph = ipv6_hdr(skb); |
954 | } | 960 | } |
955 | 961 | ||
962 | /* GSO: we need to provide proper SKB_GSO_ value for IPv6 */ | ||
963 | skb = iptunnel_handle_offloads(skb, false, 0); /* SKB_GSO_SIT/IPV6 */ | ||
964 | if (IS_ERR(skb)) | ||
965 | goto tx_error; | ||
966 | |||
956 | skb->transport_header = skb->network_header; | 967 | skb->transport_header = skb->network_header; |
957 | 968 | ||
958 | skb_push(skb, sizeof(struct ipv6hdr)); | 969 | skb_push(skb, sizeof(struct ipv6hdr)); |
@@ -988,7 +999,8 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
988 | return NF_STOLEN; | 999 | return NF_STOLEN; |
989 | 1000 | ||
990 | tx_error: | 1001 | tx_error: |
991 | kfree_skb(skb); | 1002 | if (!IS_ERR(skb)) |
1003 | kfree_skb(skb); | ||
992 | rcu_read_unlock(); | 1004 | rcu_read_unlock(); |
993 | LeaveFunction(10); | 1005 | LeaveFunction(10); |
994 | return NF_STOLEN; | 1006 | return NF_STOLEN; |
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index c138b8fbe280..f37f0716a9fc 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c | |||
@@ -222,6 +222,51 @@ replay: | |||
222 | } | 222 | } |
223 | } | 223 | } |
224 | 224 | ||
225 | struct nfnl_err { | ||
226 | struct list_head head; | ||
227 | struct nlmsghdr *nlh; | ||
228 | int err; | ||
229 | }; | ||
230 | |||
231 | static int nfnl_err_add(struct list_head *list, struct nlmsghdr *nlh, int err) | ||
232 | { | ||
233 | struct nfnl_err *nfnl_err; | ||
234 | |||
235 | nfnl_err = kmalloc(sizeof(struct nfnl_err), GFP_KERNEL); | ||
236 | if (nfnl_err == NULL) | ||
237 | return -ENOMEM; | ||
238 | |||
239 | nfnl_err->nlh = nlh; | ||
240 | nfnl_err->err = err; | ||
241 | list_add_tail(&nfnl_err->head, list); | ||
242 | |||
243 | return 0; | ||
244 | } | ||
245 | |||
246 | static void nfnl_err_del(struct nfnl_err *nfnl_err) | ||
247 | { | ||
248 | list_del(&nfnl_err->head); | ||
249 | kfree(nfnl_err); | ||
250 | } | ||
251 | |||
252 | static void nfnl_err_reset(struct list_head *err_list) | ||
253 | { | ||
254 | struct nfnl_err *nfnl_err, *next; | ||
255 | |||
256 | list_for_each_entry_safe(nfnl_err, next, err_list, head) | ||
257 | nfnl_err_del(nfnl_err); | ||
258 | } | ||
259 | |||
260 | static void nfnl_err_deliver(struct list_head *err_list, struct sk_buff *skb) | ||
261 | { | ||
262 | struct nfnl_err *nfnl_err, *next; | ||
263 | |||
264 | list_for_each_entry_safe(nfnl_err, next, err_list, head) { | ||
265 | netlink_ack(skb, nfnl_err->nlh, nfnl_err->err); | ||
266 | nfnl_err_del(nfnl_err); | ||
267 | } | ||
268 | } | ||
269 | |||
225 | static void nfnetlink_rcv_batch(struct sk_buff *skb, struct nlmsghdr *nlh, | 270 | static void nfnetlink_rcv_batch(struct sk_buff *skb, struct nlmsghdr *nlh, |
226 | u_int16_t subsys_id) | 271 | u_int16_t subsys_id) |
227 | { | 272 | { |
@@ -230,6 +275,7 @@ static void nfnetlink_rcv_batch(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
230 | const struct nfnetlink_subsystem *ss; | 275 | const struct nfnetlink_subsystem *ss; |
231 | const struct nfnl_callback *nc; | 276 | const struct nfnl_callback *nc; |
232 | bool success = true, done = false; | 277 | bool success = true, done = false; |
278 | static LIST_HEAD(err_list); | ||
233 | int err; | 279 | int err; |
234 | 280 | ||
235 | if (subsys_id >= NFNL_SUBSYS_COUNT) | 281 | if (subsys_id >= NFNL_SUBSYS_COUNT) |
@@ -287,6 +333,7 @@ replay: | |||
287 | type = nlh->nlmsg_type; | 333 | type = nlh->nlmsg_type; |
288 | if (type == NFNL_MSG_BATCH_BEGIN) { | 334 | if (type == NFNL_MSG_BATCH_BEGIN) { |
289 | /* Malformed: Batch begin twice */ | 335 | /* Malformed: Batch begin twice */ |
336 | nfnl_err_reset(&err_list); | ||
290 | success = false; | 337 | success = false; |
291 | goto done; | 338 | goto done; |
292 | } else if (type == NFNL_MSG_BATCH_END) { | 339 | } else if (type == NFNL_MSG_BATCH_END) { |
@@ -333,6 +380,7 @@ replay: | |||
333 | * original skb. | 380 | * original skb. |
334 | */ | 381 | */ |
335 | if (err == -EAGAIN) { | 382 | if (err == -EAGAIN) { |
383 | nfnl_err_reset(&err_list); | ||
336 | ss->abort(skb); | 384 | ss->abort(skb); |
337 | nfnl_unlock(subsys_id); | 385 | nfnl_unlock(subsys_id); |
338 | kfree_skb(nskb); | 386 | kfree_skb(nskb); |
@@ -341,11 +389,24 @@ replay: | |||
341 | } | 389 | } |
342 | ack: | 390 | ack: |
343 | if (nlh->nlmsg_flags & NLM_F_ACK || err) { | 391 | if (nlh->nlmsg_flags & NLM_F_ACK || err) { |
392 | /* Errors are delivered once the full batch has been | ||
393 | * processed, this avoids that the same error is | ||
394 | * reported several times when replaying the batch. | ||
395 | */ | ||
396 | if (nfnl_err_add(&err_list, nlh, err) < 0) { | ||
397 | /* We failed to enqueue an error, reset the | ||
398 | * list of errors and send OOM to userspace | ||
399 | * pointing to the batch header. | ||
400 | */ | ||
401 | nfnl_err_reset(&err_list); | ||
402 | netlink_ack(skb, nlmsg_hdr(oskb), -ENOMEM); | ||
403 | success = false; | ||
404 | goto done; | ||
405 | } | ||
344 | /* We don't stop processing the batch on errors, thus, | 406 | /* We don't stop processing the batch on errors, thus, |
345 | * userspace gets all the errors that the batch | 407 | * userspace gets all the errors that the batch |
346 | * triggers. | 408 | * triggers. |
347 | */ | 409 | */ |
348 | netlink_ack(skb, nlh, err); | ||
349 | if (err) | 410 | if (err) |
350 | success = false; | 411 | success = false; |
351 | } | 412 | } |
@@ -361,6 +422,7 @@ done: | |||
361 | else | 422 | else |
362 | ss->abort(skb); | 423 | ss->abort(skb); |
363 | 424 | ||
425 | nfnl_err_deliver(&err_list, oskb); | ||
364 | nfnl_unlock(subsys_id); | 426 | nfnl_unlock(subsys_id); |
365 | kfree_skb(nskb); | 427 | kfree_skb(nskb); |
366 | } | 428 | } |
diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c index 28fb8f38e6ba..8892b7b6184a 100644 --- a/net/netfilter/nft_hash.c +++ b/net/netfilter/nft_hash.c | |||
@@ -180,15 +180,17 @@ static int nft_hash_init(const struct nft_set *set, | |||
180 | static void nft_hash_destroy(const struct nft_set *set) | 180 | static void nft_hash_destroy(const struct nft_set *set) |
181 | { | 181 | { |
182 | const struct rhashtable *priv = nft_set_priv(set); | 182 | const struct rhashtable *priv = nft_set_priv(set); |
183 | const struct bucket_table *tbl; | 183 | const struct bucket_table *tbl = priv->tbl; |
184 | struct nft_hash_elem *he, *next; | 184 | struct nft_hash_elem *he, *next; |
185 | unsigned int i; | 185 | unsigned int i; |
186 | 186 | ||
187 | tbl = rht_dereference(priv->tbl, priv); | 187 | for (i = 0; i < tbl->size; i++) { |
188 | for (i = 0; i < tbl->size; i++) | 188 | for (he = rht_entry(tbl->buckets[i], struct nft_hash_elem, node); |
189 | rht_for_each_entry_safe(he, next, tbl->buckets[i], priv, node) | 189 | he != NULL; he = next) { |
190 | next = rht_entry(he->node.next, struct nft_hash_elem, node); | ||
190 | nft_hash_elem_destroy(set, he); | 191 | nft_hash_elem_destroy(set, he); |
191 | 192 | } | |
193 | } | ||
192 | rhashtable_destroy(priv); | 194 | rhashtable_destroy(priv); |
193 | } | 195 | } |
194 | 196 | ||
diff --git a/net/netfilter/nft_rbtree.c b/net/netfilter/nft_rbtree.c index e1836ff88199..46214f245665 100644 --- a/net/netfilter/nft_rbtree.c +++ b/net/netfilter/nft_rbtree.c | |||
@@ -234,13 +234,11 @@ static void nft_rbtree_destroy(const struct nft_set *set) | |||
234 | struct nft_rbtree_elem *rbe; | 234 | struct nft_rbtree_elem *rbe; |
235 | struct rb_node *node; | 235 | struct rb_node *node; |
236 | 236 | ||
237 | spin_lock_bh(&nft_rbtree_lock); | ||
238 | while ((node = priv->root.rb_node) != NULL) { | 237 | while ((node = priv->root.rb_node) != NULL) { |
239 | rb_erase(node, &priv->root); | 238 | rb_erase(node, &priv->root); |
240 | rbe = rb_entry(node, struct nft_rbtree_elem, node); | 239 | rbe = rb_entry(node, struct nft_rbtree_elem, node); |
241 | nft_rbtree_elem_destroy(set, rbe); | 240 | nft_rbtree_elem_destroy(set, rbe); |
242 | } | 241 | } |
243 | spin_unlock_bh(&nft_rbtree_lock); | ||
244 | } | 242 | } |
245 | 243 | ||
246 | static bool nft_rbtree_estimate(const struct nft_set_desc *desc, u32 features, | 244 | static bool nft_rbtree_estimate(const struct nft_set_desc *desc, u32 features, |
diff --git a/net/netfilter/xt_cgroup.c b/net/netfilter/xt_cgroup.c index f4e833005320..7198d660b4de 100644 --- a/net/netfilter/xt_cgroup.c +++ b/net/netfilter/xt_cgroup.c | |||
@@ -31,7 +31,7 @@ static int cgroup_mt_check(const struct xt_mtchk_param *par) | |||
31 | if (info->invert & ~1) | 31 | if (info->invert & ~1) |
32 | return -EINVAL; | 32 | return -EINVAL; |
33 | 33 | ||
34 | return info->id ? 0 : -EINVAL; | 34 | return 0; |
35 | } | 35 | } |
36 | 36 | ||
37 | static bool | 37 | static bool |
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 7228ec3faf19..64dc864a417f 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c | |||
@@ -78,11 +78,12 @@ static const struct genl_multicast_group ovs_dp_vport_multicast_group = { | |||
78 | 78 | ||
79 | /* Check if need to build a reply message. | 79 | /* Check if need to build a reply message. |
80 | * OVS userspace sets the NLM_F_ECHO flag if it needs the reply. */ | 80 | * OVS userspace sets the NLM_F_ECHO flag if it needs the reply. */ |
81 | static bool ovs_must_notify(struct genl_info *info, | 81 | static bool ovs_must_notify(struct genl_family *family, struct genl_info *info, |
82 | const struct genl_multicast_group *grp) | 82 | unsigned int group) |
83 | { | 83 | { |
84 | return info->nlhdr->nlmsg_flags & NLM_F_ECHO || | 84 | return info->nlhdr->nlmsg_flags & NLM_F_ECHO || |
85 | netlink_has_listeners(genl_info_net(info)->genl_sock, 0); | 85 | genl_has_listeners(family, genl_info_net(info)->genl_sock, |
86 | group); | ||
86 | } | 87 | } |
87 | 88 | ||
88 | static void ovs_notify(struct genl_family *family, | 89 | static void ovs_notify(struct genl_family *family, |
@@ -265,8 +266,11 @@ void ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb) | |||
265 | upcall.key = &key; | 266 | upcall.key = &key; |
266 | upcall.userdata = NULL; | 267 | upcall.userdata = NULL; |
267 | upcall.portid = ovs_vport_find_upcall_portid(p, skb); | 268 | upcall.portid = ovs_vport_find_upcall_portid(p, skb); |
268 | ovs_dp_upcall(dp, skb, &upcall); | 269 | error = ovs_dp_upcall(dp, skb, &upcall); |
269 | consume_skb(skb); | 270 | if (unlikely(error)) |
271 | kfree_skb(skb); | ||
272 | else | ||
273 | consume_skb(skb); | ||
270 | stats_counter = &stats->n_missed; | 274 | stats_counter = &stats->n_missed; |
271 | goto out; | 275 | goto out; |
272 | } | 276 | } |
@@ -404,7 +408,7 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb, | |||
404 | { | 408 | { |
405 | struct ovs_header *upcall; | 409 | struct ovs_header *upcall; |
406 | struct sk_buff *nskb = NULL; | 410 | struct sk_buff *nskb = NULL; |
407 | struct sk_buff *user_skb; /* to be queued to userspace */ | 411 | struct sk_buff *user_skb = NULL; /* to be queued to userspace */ |
408 | struct nlattr *nla; | 412 | struct nlattr *nla; |
409 | struct genl_info info = { | 413 | struct genl_info info = { |
410 | .dst_sk = ovs_dp_get_net(dp)->genl_sock, | 414 | .dst_sk = ovs_dp_get_net(dp)->genl_sock, |
@@ -494,9 +498,11 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb, | |||
494 | ((struct nlmsghdr *) user_skb->data)->nlmsg_len = user_skb->len; | 498 | ((struct nlmsghdr *) user_skb->data)->nlmsg_len = user_skb->len; |
495 | 499 | ||
496 | err = genlmsg_unicast(ovs_dp_get_net(dp), user_skb, upcall_info->portid); | 500 | err = genlmsg_unicast(ovs_dp_get_net(dp), user_skb, upcall_info->portid); |
501 | user_skb = NULL; | ||
497 | out: | 502 | out: |
498 | if (err) | 503 | if (err) |
499 | skb_tx_error(skb); | 504 | skb_tx_error(skb); |
505 | kfree_skb(user_skb); | ||
500 | kfree_skb(nskb); | 506 | kfree_skb(nskb); |
501 | return err; | 507 | return err; |
502 | } | 508 | } |
@@ -758,7 +764,7 @@ static struct sk_buff *ovs_flow_cmd_alloc_info(const struct sw_flow_actions *act | |||
758 | { | 764 | { |
759 | struct sk_buff *skb; | 765 | struct sk_buff *skb; |
760 | 766 | ||
761 | if (!always && !ovs_must_notify(info, &ovs_dp_flow_multicast_group)) | 767 | if (!always && !ovs_must_notify(&dp_flow_genl_family, info, 0)) |
762 | return NULL; | 768 | return NULL; |
763 | 769 | ||
764 | skb = genlmsg_new_unicast(ovs_flow_cmd_msg_size(acts), info, GFP_KERNEL); | 770 | skb = genlmsg_new_unicast(ovs_flow_cmd_msg_size(acts), info, GFP_KERNEL); |
diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c index 14c98e48f261..0f62326c0f5e 100644 --- a/net/rfkill/rfkill-gpio.c +++ b/net/rfkill/rfkill-gpio.c | |||
@@ -54,7 +54,7 @@ static int rfkill_gpio_set_power(void *data, bool blocked) | |||
54 | if (blocked && !IS_ERR(rfkill->clk) && rfkill->clk_enabled) | 54 | if (blocked && !IS_ERR(rfkill->clk) && rfkill->clk_enabled) |
55 | clk_disable(rfkill->clk); | 55 | clk_disable(rfkill->clk); |
56 | 56 | ||
57 | rfkill->clk_enabled = blocked; | 57 | rfkill->clk_enabled = !blocked; |
58 | 58 | ||
59 | return 0; | 59 | return 0; |
60 | } | 60 | } |
@@ -158,10 +158,12 @@ static const struct acpi_device_id rfkill_acpi_match[] = { | |||
158 | { "BCM2E1A", RFKILL_TYPE_BLUETOOTH }, | 158 | { "BCM2E1A", RFKILL_TYPE_BLUETOOTH }, |
159 | { "BCM2E39", RFKILL_TYPE_BLUETOOTH }, | 159 | { "BCM2E39", RFKILL_TYPE_BLUETOOTH }, |
160 | { "BCM2E3D", RFKILL_TYPE_BLUETOOTH }, | 160 | { "BCM2E3D", RFKILL_TYPE_BLUETOOTH }, |
161 | { "BCM2E64", RFKILL_TYPE_BLUETOOTH }, | ||
161 | { "BCM4752", RFKILL_TYPE_GPS }, | 162 | { "BCM4752", RFKILL_TYPE_GPS }, |
162 | { "LNV4752", RFKILL_TYPE_GPS }, | 163 | { "LNV4752", RFKILL_TYPE_GPS }, |
163 | { }, | 164 | { }, |
164 | }; | 165 | }; |
166 | MODULE_DEVICE_TABLE(acpi, rfkill_acpi_match); | ||
165 | #endif | 167 | #endif |
166 | 168 | ||
167 | static struct platform_driver rfkill_gpio_driver = { | 169 | static struct platform_driver rfkill_gpio_driver = { |
diff --git a/net/rxrpc/ar-key.c b/net/rxrpc/ar-key.c index b45d080e64a7..1b24191167f1 100644 --- a/net/rxrpc/ar-key.c +++ b/net/rxrpc/ar-key.c | |||
@@ -1143,7 +1143,7 @@ static long rxrpc_read(const struct key *key, | |||
1143 | if (copy_to_user(xdr, (s), _l) != 0) \ | 1143 | if (copy_to_user(xdr, (s), _l) != 0) \ |
1144 | goto fault; \ | 1144 | goto fault; \ |
1145 | if (_l & 3 && \ | 1145 | if (_l & 3 && \ |
1146 | copy_to_user((u8 *)xdr + _l, &zero, 4 - (_l & 3)) != 0) \ | 1146 | copy_to_user((u8 __user *)xdr + _l, &zero, 4 - (_l & 3)) != 0) \ |
1147 | goto fault; \ | 1147 | goto fault; \ |
1148 | xdr += (_l + 3) >> 2; \ | 1148 | xdr += (_l + 3) >> 2; \ |
1149 | } while(0) | 1149 | } while(0) |
diff --git a/net/sched/ematch.c b/net/sched/ematch.c index 3a633debb6df..ad57f4444b9c 100644 --- a/net/sched/ematch.c +++ b/net/sched/ematch.c | |||
@@ -526,9 +526,11 @@ pop_stack: | |||
526 | match_idx = stack[--stackp]; | 526 | match_idx = stack[--stackp]; |
527 | cur_match = tcf_em_get_match(tree, match_idx); | 527 | cur_match = tcf_em_get_match(tree, match_idx); |
528 | 528 | ||
529 | if (tcf_em_early_end(cur_match, res)) | 529 | if (tcf_em_early_end(cur_match, res)) { |
530 | if (tcf_em_is_inverted(cur_match)) | ||
531 | res = !res; | ||
530 | goto pop_stack; | 532 | goto pop_stack; |
531 | else { | 533 | } else { |
532 | match_idx++; | 534 | match_idx++; |
533 | goto proceed; | 535 | goto proceed; |
534 | } | 536 | } |
diff --git a/net/sched/sch_choke.c b/net/sched/sch_choke.c index ed30e436128b..fb666d1e4de3 100644 --- a/net/sched/sch_choke.c +++ b/net/sched/sch_choke.c | |||
@@ -133,10 +133,16 @@ static void choke_drop_by_idx(struct Qdisc *sch, unsigned int idx) | |||
133 | --sch->q.qlen; | 133 | --sch->q.qlen; |
134 | } | 134 | } |
135 | 135 | ||
136 | /* private part of skb->cb[] that a qdisc is allowed to use | ||
137 | * is limited to QDISC_CB_PRIV_LEN bytes. | ||
138 | * As a flow key might be too large, we store a part of it only. | ||
139 | */ | ||
140 | #define CHOKE_K_LEN min_t(u32, sizeof(struct flow_keys), QDISC_CB_PRIV_LEN - 3) | ||
141 | |||
136 | struct choke_skb_cb { | 142 | struct choke_skb_cb { |
137 | u16 classid; | 143 | u16 classid; |
138 | u8 keys_valid; | 144 | u8 keys_valid; |
139 | struct flow_keys keys; | 145 | u8 keys[QDISC_CB_PRIV_LEN - 3]; |
140 | }; | 146 | }; |
141 | 147 | ||
142 | static inline struct choke_skb_cb *choke_skb_cb(const struct sk_buff *skb) | 148 | static inline struct choke_skb_cb *choke_skb_cb(const struct sk_buff *skb) |
@@ -163,22 +169,26 @@ static u16 choke_get_classid(const struct sk_buff *skb) | |||
163 | static bool choke_match_flow(struct sk_buff *skb1, | 169 | static bool choke_match_flow(struct sk_buff *skb1, |
164 | struct sk_buff *skb2) | 170 | struct sk_buff *skb2) |
165 | { | 171 | { |
172 | struct flow_keys temp; | ||
173 | |||
166 | if (skb1->protocol != skb2->protocol) | 174 | if (skb1->protocol != skb2->protocol) |
167 | return false; | 175 | return false; |
168 | 176 | ||
169 | if (!choke_skb_cb(skb1)->keys_valid) { | 177 | if (!choke_skb_cb(skb1)->keys_valid) { |
170 | choke_skb_cb(skb1)->keys_valid = 1; | 178 | choke_skb_cb(skb1)->keys_valid = 1; |
171 | skb_flow_dissect(skb1, &choke_skb_cb(skb1)->keys); | 179 | skb_flow_dissect(skb1, &temp); |
180 | memcpy(&choke_skb_cb(skb1)->keys, &temp, CHOKE_K_LEN); | ||
172 | } | 181 | } |
173 | 182 | ||
174 | if (!choke_skb_cb(skb2)->keys_valid) { | 183 | if (!choke_skb_cb(skb2)->keys_valid) { |
175 | choke_skb_cb(skb2)->keys_valid = 1; | 184 | choke_skb_cb(skb2)->keys_valid = 1; |
176 | skb_flow_dissect(skb2, &choke_skb_cb(skb2)->keys); | 185 | skb_flow_dissect(skb2, &temp); |
186 | memcpy(&choke_skb_cb(skb2)->keys, &temp, CHOKE_K_LEN); | ||
177 | } | 187 | } |
178 | 188 | ||
179 | return !memcmp(&choke_skb_cb(skb1)->keys, | 189 | return !memcmp(&choke_skb_cb(skb1)->keys, |
180 | &choke_skb_cb(skb2)->keys, | 190 | &choke_skb_cb(skb2)->keys, |
181 | sizeof(struct flow_keys)); | 191 | CHOKE_K_LEN); |
182 | } | 192 | } |
183 | 193 | ||
184 | /* | 194 | /* |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index eb71d49e7653..634a2abb5f3a 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -4243,7 +4243,7 @@ static int sctp_getsockopt_sctp_status(struct sock *sk, int len, | |||
4243 | transport = asoc->peer.primary_path; | 4243 | transport = asoc->peer.primary_path; |
4244 | 4244 | ||
4245 | status.sstat_assoc_id = sctp_assoc2id(asoc); | 4245 | status.sstat_assoc_id = sctp_assoc2id(asoc); |
4246 | status.sstat_state = asoc->state; | 4246 | status.sstat_state = sctp_assoc_to_state(asoc); |
4247 | status.sstat_rwnd = asoc->peer.rwnd; | 4247 | status.sstat_rwnd = asoc->peer.rwnd; |
4248 | status.sstat_unackdata = asoc->unack_data; | 4248 | status.sstat_unackdata = asoc->unack_data; |
4249 | 4249 | ||
diff --git a/net/socket.c b/net/socket.c index 95ee7d8682e7..4cdbc107606f 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -734,8 +734,7 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, | |||
734 | } | 734 | } |
735 | 735 | ||
736 | memset(&tss, 0, sizeof(tss)); | 736 | memset(&tss, 0, sizeof(tss)); |
737 | if ((sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE || | 737 | if ((sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE) && |
738 | skb_shinfo(skb)->tx_flags & SKBTX_ANY_SW_TSTAMP) && | ||
739 | ktime_to_timespec_cond(skb->tstamp, tss.ts + 0)) | 738 | ktime_to_timespec_cond(skb->tstamp, tss.ts + 0)) |
740 | empty = 0; | 739 | empty = 0; |
741 | if (shhwtstamps && | 740 | if (shhwtstamps && |
@@ -1997,6 +1996,9 @@ static int copy_msghdr_from_user(struct msghdr *kmsg, | |||
1997 | if (copy_from_user(kmsg, umsg, sizeof(struct msghdr))) | 1996 | if (copy_from_user(kmsg, umsg, sizeof(struct msghdr))) |
1998 | return -EFAULT; | 1997 | return -EFAULT; |
1999 | 1998 | ||
1999 | if (kmsg->msg_name == NULL) | ||
2000 | kmsg->msg_namelen = 0; | ||
2001 | |||
2000 | if (kmsg->msg_namelen < 0) | 2002 | if (kmsg->msg_namelen < 0) |
2001 | return -EINVAL; | 2003 | return -EINVAL; |
2002 | 2004 | ||
@@ -2602,7 +2604,7 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) | |||
2602 | * | 2604 | * |
2603 | * This function is called by a protocol handler that wants to | 2605 | * This function is called by a protocol handler that wants to |
2604 | * advertise its address family, and have it linked into the | 2606 | * advertise its address family, and have it linked into the |
2605 | * socket interface. The value ops->family coresponds to the | 2607 | * socket interface. The value ops->family corresponds to the |
2606 | * socket system call protocol family. | 2608 | * socket system call protocol family. |
2607 | */ | 2609 | */ |
2608 | int sock_register(const struct net_proto_family *ops) | 2610 | int sock_register(const struct net_proto_family *ops) |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index df7b1332a1ec..7257164af91b 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -6969,6 +6969,9 @@ void __cfg80211_send_event_skb(struct sk_buff *skb, gfp_t gfp) | |||
6969 | struct nlattr *data = ((void **)skb->cb)[2]; | 6969 | struct nlattr *data = ((void **)skb->cb)[2]; |
6970 | enum nl80211_multicast_groups mcgrp = NL80211_MCGRP_TESTMODE; | 6970 | enum nl80211_multicast_groups mcgrp = NL80211_MCGRP_TESTMODE; |
6971 | 6971 | ||
6972 | /* clear CB data for netlink core to own from now on */ | ||
6973 | memset(skb->cb, 0, sizeof(skb->cb)); | ||
6974 | |||
6972 | nla_nest_end(skb, data); | 6975 | nla_nest_end(skb, data); |
6973 | genlmsg_end(skb, hdr); | 6976 | genlmsg_end(skb, hdr); |
6974 | 6977 | ||
@@ -9294,6 +9297,9 @@ int cfg80211_vendor_cmd_reply(struct sk_buff *skb) | |||
9294 | void *hdr = ((void **)skb->cb)[1]; | 9297 | void *hdr = ((void **)skb->cb)[1]; |
9295 | struct nlattr *data = ((void **)skb->cb)[2]; | 9298 | struct nlattr *data = ((void **)skb->cb)[2]; |
9296 | 9299 | ||
9300 | /* clear CB data for netlink core to own from now on */ | ||
9301 | memset(skb->cb, 0, sizeof(skb->cb)); | ||
9302 | |||
9297 | if (WARN_ON(!rdev->cur_cmd_info)) { | 9303 | if (WARN_ON(!rdev->cur_cmd_info)) { |
9298 | kfree_skb(skb); | 9304 | kfree_skb(skb); |
9299 | return -EINVAL; | 9305 | return -EINVAL; |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index beeed602aeb3..fdde51f4271a 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -39,6 +39,11 @@ | |||
39 | #define XFRM_QUEUE_TMO_MAX ((unsigned)(60*HZ)) | 39 | #define XFRM_QUEUE_TMO_MAX ((unsigned)(60*HZ)) |
40 | #define XFRM_MAX_QUEUE_LEN 100 | 40 | #define XFRM_MAX_QUEUE_LEN 100 |
41 | 41 | ||
42 | struct xfrm_flo { | ||
43 | struct dst_entry *dst_orig; | ||
44 | u8 flags; | ||
45 | }; | ||
46 | |||
42 | static DEFINE_SPINLOCK(xfrm_policy_afinfo_lock); | 47 | static DEFINE_SPINLOCK(xfrm_policy_afinfo_lock); |
43 | static struct xfrm_policy_afinfo __rcu *xfrm_policy_afinfo[NPROTO] | 48 | static struct xfrm_policy_afinfo __rcu *xfrm_policy_afinfo[NPROTO] |
44 | __read_mostly; | 49 | __read_mostly; |
@@ -1877,13 +1882,14 @@ static int xdst_queue_output(struct sock *sk, struct sk_buff *skb) | |||
1877 | } | 1882 | } |
1878 | 1883 | ||
1879 | static struct xfrm_dst *xfrm_create_dummy_bundle(struct net *net, | 1884 | static struct xfrm_dst *xfrm_create_dummy_bundle(struct net *net, |
1880 | struct dst_entry *dst, | 1885 | struct xfrm_flo *xflo, |
1881 | const struct flowi *fl, | 1886 | const struct flowi *fl, |
1882 | int num_xfrms, | 1887 | int num_xfrms, |
1883 | u16 family) | 1888 | u16 family) |
1884 | { | 1889 | { |
1885 | int err; | 1890 | int err; |
1886 | struct net_device *dev; | 1891 | struct net_device *dev; |
1892 | struct dst_entry *dst; | ||
1887 | struct dst_entry *dst1; | 1893 | struct dst_entry *dst1; |
1888 | struct xfrm_dst *xdst; | 1894 | struct xfrm_dst *xdst; |
1889 | 1895 | ||
@@ -1891,9 +1897,12 @@ static struct xfrm_dst *xfrm_create_dummy_bundle(struct net *net, | |||
1891 | if (IS_ERR(xdst)) | 1897 | if (IS_ERR(xdst)) |
1892 | return xdst; | 1898 | return xdst; |
1893 | 1899 | ||
1894 | if (net->xfrm.sysctl_larval_drop || num_xfrms <= 0) | 1900 | if (!(xflo->flags & XFRM_LOOKUP_QUEUE) || |
1901 | net->xfrm.sysctl_larval_drop || | ||
1902 | num_xfrms <= 0) | ||
1895 | return xdst; | 1903 | return xdst; |
1896 | 1904 | ||
1905 | dst = xflo->dst_orig; | ||
1897 | dst1 = &xdst->u.dst; | 1906 | dst1 = &xdst->u.dst; |
1898 | dst_hold(dst); | 1907 | dst_hold(dst); |
1899 | xdst->route = dst; | 1908 | xdst->route = dst; |
@@ -1935,7 +1944,7 @@ static struct flow_cache_object * | |||
1935 | xfrm_bundle_lookup(struct net *net, const struct flowi *fl, u16 family, u8 dir, | 1944 | xfrm_bundle_lookup(struct net *net, const struct flowi *fl, u16 family, u8 dir, |
1936 | struct flow_cache_object *oldflo, void *ctx) | 1945 | struct flow_cache_object *oldflo, void *ctx) |
1937 | { | 1946 | { |
1938 | struct dst_entry *dst_orig = (struct dst_entry *)ctx; | 1947 | struct xfrm_flo *xflo = (struct xfrm_flo *)ctx; |
1939 | struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX]; | 1948 | struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX]; |
1940 | struct xfrm_dst *xdst, *new_xdst; | 1949 | struct xfrm_dst *xdst, *new_xdst; |
1941 | int num_pols = 0, num_xfrms = 0, i, err, pol_dead; | 1950 | int num_pols = 0, num_xfrms = 0, i, err, pol_dead; |
@@ -1976,7 +1985,8 @@ xfrm_bundle_lookup(struct net *net, const struct flowi *fl, u16 family, u8 dir, | |||
1976 | goto make_dummy_bundle; | 1985 | goto make_dummy_bundle; |
1977 | } | 1986 | } |
1978 | 1987 | ||
1979 | new_xdst = xfrm_resolve_and_create_bundle(pols, num_pols, fl, family, dst_orig); | 1988 | new_xdst = xfrm_resolve_and_create_bundle(pols, num_pols, fl, family, |
1989 | xflo->dst_orig); | ||
1980 | if (IS_ERR(new_xdst)) { | 1990 | if (IS_ERR(new_xdst)) { |
1981 | err = PTR_ERR(new_xdst); | 1991 | err = PTR_ERR(new_xdst); |
1982 | if (err != -EAGAIN) | 1992 | if (err != -EAGAIN) |
@@ -2010,7 +2020,7 @@ make_dummy_bundle: | |||
2010 | /* We found policies, but there's no bundles to instantiate: | 2020 | /* We found policies, but there's no bundles to instantiate: |
2011 | * either because the policy blocks, has no transformations or | 2021 | * either because the policy blocks, has no transformations or |
2012 | * we could not build template (no xfrm_states).*/ | 2022 | * we could not build template (no xfrm_states).*/ |
2013 | xdst = xfrm_create_dummy_bundle(net, dst_orig, fl, num_xfrms, family); | 2023 | xdst = xfrm_create_dummy_bundle(net, xflo, fl, num_xfrms, family); |
2014 | if (IS_ERR(xdst)) { | 2024 | if (IS_ERR(xdst)) { |
2015 | xfrm_pols_put(pols, num_pols); | 2025 | xfrm_pols_put(pols, num_pols); |
2016 | return ERR_CAST(xdst); | 2026 | return ERR_CAST(xdst); |
@@ -2104,13 +2114,18 @@ struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig, | |||
2104 | } | 2114 | } |
2105 | 2115 | ||
2106 | if (xdst == NULL) { | 2116 | if (xdst == NULL) { |
2117 | struct xfrm_flo xflo; | ||
2118 | |||
2119 | xflo.dst_orig = dst_orig; | ||
2120 | xflo.flags = flags; | ||
2121 | |||
2107 | /* To accelerate a bit... */ | 2122 | /* To accelerate a bit... */ |
2108 | if ((dst_orig->flags & DST_NOXFRM) || | 2123 | if ((dst_orig->flags & DST_NOXFRM) || |
2109 | !net->xfrm.policy_count[XFRM_POLICY_OUT]) | 2124 | !net->xfrm.policy_count[XFRM_POLICY_OUT]) |
2110 | goto nopol; | 2125 | goto nopol; |
2111 | 2126 | ||
2112 | flo = flow_cache_lookup(net, fl, family, dir, | 2127 | flo = flow_cache_lookup(net, fl, family, dir, |
2113 | xfrm_bundle_lookup, dst_orig); | 2128 | xfrm_bundle_lookup, &xflo); |
2114 | if (flo == NULL) | 2129 | if (flo == NULL) |
2115 | goto nopol; | 2130 | goto nopol; |
2116 | if (IS_ERR(flo)) { | 2131 | if (IS_ERR(flo)) { |
@@ -2138,7 +2153,7 @@ struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig, | |||
2138 | xfrm_pols_put(pols, drop_pols); | 2153 | xfrm_pols_put(pols, drop_pols); |
2139 | XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTNOSTATES); | 2154 | XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTNOSTATES); |
2140 | 2155 | ||
2141 | return make_blackhole(net, family, dst_orig); | 2156 | return ERR_PTR(-EREMOTE); |
2142 | } | 2157 | } |
2143 | 2158 | ||
2144 | err = -EAGAIN; | 2159 | err = -EAGAIN; |
@@ -2195,6 +2210,23 @@ dropdst: | |||
2195 | } | 2210 | } |
2196 | EXPORT_SYMBOL(xfrm_lookup); | 2211 | EXPORT_SYMBOL(xfrm_lookup); |
2197 | 2212 | ||
2213 | /* Callers of xfrm_lookup_route() must ensure a call to dst_output(). | ||
2214 | * Otherwise we may send out blackholed packets. | ||
2215 | */ | ||
2216 | struct dst_entry *xfrm_lookup_route(struct net *net, struct dst_entry *dst_orig, | ||
2217 | const struct flowi *fl, | ||
2218 | struct sock *sk, int flags) | ||
2219 | { | ||
2220 | struct dst_entry *dst = xfrm_lookup(net, dst_orig, fl, sk, | ||
2221 | flags | XFRM_LOOKUP_QUEUE); | ||
2222 | |||
2223 | if (IS_ERR(dst) && PTR_ERR(dst) == -EREMOTE) | ||
2224 | return make_blackhole(net, dst_orig->ops->family, dst_orig); | ||
2225 | |||
2226 | return dst; | ||
2227 | } | ||
2228 | EXPORT_SYMBOL(xfrm_lookup_route); | ||
2229 | |||
2198 | static inline int | 2230 | static inline int |
2199 | xfrm_secpath_reject(int idx, struct sk_buff *skb, const struct flowi *fl) | 2231 | xfrm_secpath_reject(int idx, struct sk_buff *skb, const struct flowi *fl) |
2200 | { | 2232 | { |
@@ -2460,7 +2492,7 @@ int __xfrm_route_forward(struct sk_buff *skb, unsigned short family) | |||
2460 | 2492 | ||
2461 | skb_dst_force(skb); | 2493 | skb_dst_force(skb); |
2462 | 2494 | ||
2463 | dst = xfrm_lookup(net, skb_dst(skb), &fl, NULL, 0); | 2495 | dst = xfrm_lookup(net, skb_dst(skb), &fl, NULL, XFRM_LOOKUP_QUEUE); |
2464 | if (IS_ERR(dst)) { | 2496 | if (IS_ERR(dst)) { |
2465 | res = 0; | 2497 | res = 0; |
2466 | dst = NULL; | 2498 | dst = NULL; |