diff options
Diffstat (limited to 'net')
41 files changed, 276 insertions, 197 deletions
diff --git a/net/9p/client.c b/net/9p/client.c index 48b8e084e710..77367745be9b 100644 --- a/net/9p/client.c +++ b/net/9p/client.c | |||
| @@ -929,15 +929,15 @@ error: | |||
| 929 | } | 929 | } |
| 930 | EXPORT_SYMBOL(p9_client_attach); | 930 | EXPORT_SYMBOL(p9_client_attach); |
| 931 | 931 | ||
| 932 | struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames, | 932 | struct p9_fid *p9_client_walk(struct p9_fid *oldfid, uint16_t nwname, |
| 933 | int clone) | 933 | char **wnames, int clone) |
| 934 | { | 934 | { |
| 935 | int err; | 935 | int err; |
| 936 | struct p9_client *clnt; | 936 | struct p9_client *clnt; |
| 937 | struct p9_fid *fid; | 937 | struct p9_fid *fid; |
| 938 | struct p9_qid *wqids; | 938 | struct p9_qid *wqids; |
| 939 | struct p9_req_t *req; | 939 | struct p9_req_t *req; |
| 940 | int16_t nwqids, count; | 940 | uint16_t nwqids, count; |
| 941 | 941 | ||
| 942 | err = 0; | 942 | err = 0; |
| 943 | wqids = NULL; | 943 | wqids = NULL; |
| @@ -955,7 +955,7 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames, | |||
| 955 | fid = oldfid; | 955 | fid = oldfid; |
| 956 | 956 | ||
| 957 | 957 | ||
| 958 | P9_DPRINTK(P9_DEBUG_9P, ">>> TWALK fids %d,%d nwname %d wname[0] %s\n", | 958 | P9_DPRINTK(P9_DEBUG_9P, ">>> TWALK fids %d,%d nwname %ud wname[0] %s\n", |
| 959 | oldfid->fid, fid->fid, nwname, wnames ? wnames[0] : NULL); | 959 | oldfid->fid, fid->fid, nwname, wnames ? wnames[0] : NULL); |
| 960 | 960 | ||
| 961 | req = p9_client_rpc(clnt, P9_TWALK, "ddT", oldfid->fid, fid->fid, | 961 | req = p9_client_rpc(clnt, P9_TWALK, "ddT", oldfid->fid, fid->fid, |
| @@ -1220,27 +1220,6 @@ error: | |||
| 1220 | } | 1220 | } |
| 1221 | EXPORT_SYMBOL(p9_client_fsync); | 1221 | EXPORT_SYMBOL(p9_client_fsync); |
| 1222 | 1222 | ||
| 1223 | int p9_client_sync_fs(struct p9_fid *fid) | ||
| 1224 | { | ||
| 1225 | int err = 0; | ||
| 1226 | struct p9_req_t *req; | ||
| 1227 | struct p9_client *clnt; | ||
| 1228 | |||
| 1229 | P9_DPRINTK(P9_DEBUG_9P, ">>> TSYNC_FS fid %d\n", fid->fid); | ||
| 1230 | |||
| 1231 | clnt = fid->clnt; | ||
| 1232 | req = p9_client_rpc(clnt, P9_TSYNCFS, "d", fid->fid); | ||
| 1233 | if (IS_ERR(req)) { | ||
| 1234 | err = PTR_ERR(req); | ||
| 1235 | goto error; | ||
| 1236 | } | ||
| 1237 | P9_DPRINTK(P9_DEBUG_9P, "<<< RSYNCFS fid %d\n", fid->fid); | ||
| 1238 | p9_free_req(clnt, req); | ||
| 1239 | error: | ||
| 1240 | return err; | ||
| 1241 | } | ||
| 1242 | EXPORT_SYMBOL(p9_client_sync_fs); | ||
| 1243 | |||
| 1244 | int p9_client_clunk(struct p9_fid *fid) | 1223 | int p9_client_clunk(struct p9_fid *fid) |
| 1245 | { | 1224 | { |
| 1246 | int err; | 1225 | int err; |
diff --git a/net/9p/protocol.c b/net/9p/protocol.c index 8a4084fa8b5a..b58a501cf3d1 100644 --- a/net/9p/protocol.c +++ b/net/9p/protocol.c | |||
| @@ -265,7 +265,7 @@ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt, | |||
| 265 | } | 265 | } |
| 266 | break; | 266 | break; |
| 267 | case 'T':{ | 267 | case 'T':{ |
| 268 | int16_t *nwname = va_arg(ap, int16_t *); | 268 | uint16_t *nwname = va_arg(ap, uint16_t *); |
| 269 | char ***wnames = va_arg(ap, char ***); | 269 | char ***wnames = va_arg(ap, char ***); |
| 270 | 270 | ||
| 271 | errcode = p9pdu_readf(pdu, proto_version, | 271 | errcode = p9pdu_readf(pdu, proto_version, |
| @@ -468,7 +468,8 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt, | |||
| 468 | case 'E':{ | 468 | case 'E':{ |
| 469 | int32_t cnt = va_arg(ap, int32_t); | 469 | int32_t cnt = va_arg(ap, int32_t); |
| 470 | const char *k = va_arg(ap, const void *); | 470 | const char *k = va_arg(ap, const void *); |
| 471 | const char *u = va_arg(ap, const void *); | 471 | const char __user *u = va_arg(ap, |
| 472 | const void __user *); | ||
| 472 | errcode = p9pdu_writef(pdu, proto_version, "d", | 473 | errcode = p9pdu_writef(pdu, proto_version, "d", |
| 473 | cnt); | 474 | cnt); |
| 474 | if (!errcode && pdu_write_urw(pdu, k, u, cnt)) | 475 | if (!errcode && pdu_write_urw(pdu, k, u, cnt)) |
| @@ -495,7 +496,7 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt, | |||
| 495 | } | 496 | } |
| 496 | break; | 497 | break; |
| 497 | case 'T':{ | 498 | case 'T':{ |
| 498 | int16_t nwname = va_arg(ap, int); | 499 | uint16_t nwname = va_arg(ap, int); |
| 499 | const char **wnames = va_arg(ap, const char **); | 500 | const char **wnames = va_arg(ap, const char **); |
| 500 | 501 | ||
| 501 | errcode = p9pdu_writef(pdu, proto_version, "w", | 502 | errcode = p9pdu_writef(pdu, proto_version, "w", |
diff --git a/net/9p/trans_common.c b/net/9p/trans_common.c index d47880e971dd..e883172f9aa2 100644 --- a/net/9p/trans_common.c +++ b/net/9p/trans_common.c | |||
| @@ -66,7 +66,7 @@ p9_payload_gup(struct p9_req_t *req, size_t *pdata_off, int *pdata_len, | |||
| 66 | uint32_t pdata_mapped_pages; | 66 | uint32_t pdata_mapped_pages; |
| 67 | struct trans_rpage_info *rpinfo; | 67 | struct trans_rpage_info *rpinfo; |
| 68 | 68 | ||
| 69 | *pdata_off = (size_t)req->tc->pubuf & (PAGE_SIZE-1); | 69 | *pdata_off = (__force size_t)req->tc->pubuf & (PAGE_SIZE-1); |
| 70 | 70 | ||
| 71 | if (*pdata_off) | 71 | if (*pdata_off) |
| 72 | first_page_bytes = min(((size_t)PAGE_SIZE - *pdata_off), | 72 | first_page_bytes = min(((size_t)PAGE_SIZE - *pdata_off), |
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index e8f046b07182..244e70742183 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c | |||
| @@ -326,8 +326,11 @@ req_retry_pinned: | |||
| 326 | outp = pack_sg_list_p(chan->sg, out, VIRTQUEUE_NUM, | 326 | outp = pack_sg_list_p(chan->sg, out, VIRTQUEUE_NUM, |
| 327 | pdata_off, rpinfo->rp_data, pdata_len); | 327 | pdata_off, rpinfo->rp_data, pdata_len); |
| 328 | } else { | 328 | } else { |
| 329 | char *pbuf = req->tc->pubuf ? req->tc->pubuf : | 329 | char *pbuf; |
| 330 | req->tc->pkbuf; | 330 | if (req->tc->pubuf) |
| 331 | pbuf = (__force char *) req->tc->pubuf; | ||
| 332 | else | ||
| 333 | pbuf = req->tc->pkbuf; | ||
| 331 | outp = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM, pbuf, | 334 | outp = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM, pbuf, |
| 332 | req->tc->pbuf_size); | 335 | req->tc->pbuf_size); |
| 333 | } | 336 | } |
| @@ -352,8 +355,12 @@ req_retry_pinned: | |||
| 352 | in = pack_sg_list_p(chan->sg, out+inp, VIRTQUEUE_NUM, | 355 | in = pack_sg_list_p(chan->sg, out+inp, VIRTQUEUE_NUM, |
| 353 | pdata_off, rpinfo->rp_data, pdata_len); | 356 | pdata_off, rpinfo->rp_data, pdata_len); |
| 354 | } else { | 357 | } else { |
| 355 | char *pbuf = req->tc->pubuf ? req->tc->pubuf : | 358 | char *pbuf; |
| 356 | req->tc->pkbuf; | 359 | if (req->tc->pubuf) |
| 360 | pbuf = (__force char *) req->tc->pubuf; | ||
| 361 | else | ||
| 362 | pbuf = req->tc->pkbuf; | ||
| 363 | |||
| 357 | in = pack_sg_list(chan->sg, out+inp, VIRTQUEUE_NUM, | 364 | in = pack_sg_list(chan->sg, out+inp, VIRTQUEUE_NUM, |
| 358 | pbuf, req->tc->pbuf_size); | 365 | pbuf, req->tc->pbuf_size); |
| 359 | } | 366 | } |
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 008ff6c4eecf..f3bc322c5891 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c | |||
| @@ -249,11 +249,9 @@ static int br_parse_ip_options(struct sk_buff *skb) | |||
| 249 | goto drop; | 249 | goto drop; |
| 250 | } | 250 | } |
| 251 | 251 | ||
| 252 | /* Zero out the CB buffer if no options present */ | 252 | memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); |
| 253 | if (iph->ihl == 5) { | 253 | if (iph->ihl == 5) |
| 254 | memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); | ||
| 255 | return 0; | 254 | return 0; |
| 256 | } | ||
| 257 | 255 | ||
| 258 | opt->optlen = iph->ihl*4 - sizeof(struct iphdr); | 256 | opt->optlen = iph->ihl*4 - sizeof(struct iphdr); |
| 259 | if (ip_options_compile(dev_net(dev), opt, skb)) | 257 | if (ip_options_compile(dev_net(dev), opt, skb)) |
diff --git a/net/caif/cfdgml.c b/net/caif/cfdgml.c index 27dab26ad3b8..054fdb5aeb88 100644 --- a/net/caif/cfdgml.c +++ b/net/caif/cfdgml.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <net/caif/cfsrvl.h> | 13 | #include <net/caif/cfsrvl.h> |
| 14 | #include <net/caif/cfpkt.h> | 14 | #include <net/caif/cfpkt.h> |
| 15 | 15 | ||
| 16 | |||
| 16 | #define container_obj(layr) ((struct cfsrvl *) layr) | 17 | #define container_obj(layr) ((struct cfsrvl *) layr) |
| 17 | 18 | ||
| 18 | #define DGM_CMD_BIT 0x80 | 19 | #define DGM_CMD_BIT 0x80 |
| @@ -83,6 +84,7 @@ static int cfdgml_receive(struct cflayer *layr, struct cfpkt *pkt) | |||
| 83 | 84 | ||
| 84 | static int cfdgml_transmit(struct cflayer *layr, struct cfpkt *pkt) | 85 | static int cfdgml_transmit(struct cflayer *layr, struct cfpkt *pkt) |
| 85 | { | 86 | { |
| 87 | u8 packet_type; | ||
| 86 | u32 zero = 0; | 88 | u32 zero = 0; |
| 87 | struct caif_payload_info *info; | 89 | struct caif_payload_info *info; |
| 88 | struct cfsrvl *service = container_obj(layr); | 90 | struct cfsrvl *service = container_obj(layr); |
| @@ -94,7 +96,9 @@ static int cfdgml_transmit(struct cflayer *layr, struct cfpkt *pkt) | |||
| 94 | if (cfpkt_getlen(pkt) > DGM_MTU) | 96 | if (cfpkt_getlen(pkt) > DGM_MTU) |
| 95 | return -EMSGSIZE; | 97 | return -EMSGSIZE; |
| 96 | 98 | ||
| 97 | cfpkt_add_head(pkt, &zero, 4); | 99 | cfpkt_add_head(pkt, &zero, 3); |
| 100 | packet_type = 0x08; /* B9 set - UNCLASSIFIED */ | ||
| 101 | cfpkt_add_head(pkt, &packet_type, 1); | ||
| 98 | 102 | ||
| 99 | /* Add info for MUX-layer to route the packet out. */ | 103 | /* Add info for MUX-layer to route the packet out. */ |
| 100 | info = cfpkt_info(pkt); | 104 | info = cfpkt_info(pkt); |
diff --git a/net/caif/cfmuxl.c b/net/caif/cfmuxl.c index 46f34b2e0478..24f1ffa74b06 100644 --- a/net/caif/cfmuxl.c +++ b/net/caif/cfmuxl.c | |||
| @@ -244,9 +244,9 @@ static void cfmuxl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, | |||
| 244 | int phyid) | 244 | int phyid) |
| 245 | { | 245 | { |
| 246 | struct cfmuxl *muxl = container_obj(layr); | 246 | struct cfmuxl *muxl = container_obj(layr); |
| 247 | struct list_head *node; | 247 | struct list_head *node, *next; |
| 248 | struct cflayer *layer; | 248 | struct cflayer *layer; |
| 249 | list_for_each(node, &muxl->srvl_list) { | 249 | list_for_each_safe(node, next, &muxl->srvl_list) { |
| 250 | layer = list_entry(node, struct cflayer, node); | 250 | layer = list_entry(node, struct cflayer, node); |
| 251 | if (cfsrvl_phyid_match(layer, phyid)) | 251 | if (cfsrvl_phyid_match(layer, phyid)) |
| 252 | layer->ctrlcmd(layer, ctrl, phyid); | 252 | layer->ctrlcmd(layer, ctrl, phyid); |
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 50af02737a3d..5a80f41c0cba 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c | |||
| @@ -579,9 +579,15 @@ static void __kick_osd_requests(struct ceph_osd_client *osdc, | |||
| 579 | 579 | ||
| 580 | list_for_each_entry_safe(req, nreq, &osd->o_linger_requests, | 580 | list_for_each_entry_safe(req, nreq, &osd->o_linger_requests, |
| 581 | r_linger_osd) { | 581 | r_linger_osd) { |
| 582 | __unregister_linger_request(osdc, req); | 582 | /* |
| 583 | * reregister request prior to unregistering linger so | ||
| 584 | * that r_osd is preserved. | ||
| 585 | */ | ||
| 586 | BUG_ON(!list_empty(&req->r_req_lru_item)); | ||
| 583 | __register_request(osdc, req); | 587 | __register_request(osdc, req); |
| 584 | list_move(&req->r_req_lru_item, &osdc->req_unsent); | 588 | list_add(&req->r_req_lru_item, &osdc->req_unsent); |
| 589 | list_add(&req->r_osd_item, &req->r_osd->o_requests); | ||
| 590 | __unregister_linger_request(osdc, req); | ||
| 585 | dout("requeued lingering %p tid %llu osd%d\n", req, req->r_tid, | 591 | dout("requeued lingering %p tid %llu osd%d\n", req, req->r_tid, |
| 586 | osd->o_osd); | 592 | osd->o_osd); |
| 587 | } | 593 | } |
| @@ -798,7 +804,7 @@ static void __register_request(struct ceph_osd_client *osdc, | |||
| 798 | req->r_request->hdr.tid = cpu_to_le64(req->r_tid); | 804 | req->r_request->hdr.tid = cpu_to_le64(req->r_tid); |
| 799 | INIT_LIST_HEAD(&req->r_req_lru_item); | 805 | INIT_LIST_HEAD(&req->r_req_lru_item); |
| 800 | 806 | ||
| 801 | dout("register_request %p tid %lld\n", req, req->r_tid); | 807 | dout("__register_request %p tid %lld\n", req, req->r_tid); |
| 802 | __insert_request(osdc, req); | 808 | __insert_request(osdc, req); |
| 803 | ceph_osdc_get_request(req); | 809 | ceph_osdc_get_request(req); |
| 804 | osdc->num_requests++; | 810 | osdc->num_requests++; |
diff --git a/net/core/dev.c b/net/core/dev.c index 956d3b006e8b..c2ac599fa0f6 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -5203,11 +5203,15 @@ u32 netdev_fix_features(struct net_device *dev, u32 features) | |||
| 5203 | } | 5203 | } |
| 5204 | 5204 | ||
| 5205 | /* TSO requires that SG is present as well. */ | 5205 | /* TSO requires that SG is present as well. */ |
| 5206 | if ((features & NETIF_F_TSO) && !(features & NETIF_F_SG)) { | 5206 | if ((features & NETIF_F_ALL_TSO) && !(features & NETIF_F_SG)) { |
| 5207 | netdev_info(dev, "Dropping NETIF_F_TSO since no SG feature.\n"); | 5207 | netdev_info(dev, "Dropping TSO features since no SG feature.\n"); |
| 5208 | features &= ~NETIF_F_TSO; | 5208 | features &= ~NETIF_F_ALL_TSO; |
| 5209 | } | 5209 | } |
| 5210 | 5210 | ||
| 5211 | /* TSO ECN requires that TSO is present as well. */ | ||
| 5212 | if ((features & NETIF_F_ALL_TSO) == NETIF_F_TSO_ECN) | ||
| 5213 | features &= ~NETIF_F_TSO_ECN; | ||
| 5214 | |||
| 5211 | /* Software GSO depends on SG. */ | 5215 | /* Software GSO depends on SG. */ |
| 5212 | if ((features & NETIF_F_GSO) && !(features & NETIF_F_SG)) { | 5216 | if ((features & NETIF_F_GSO) && !(features & NETIF_F_SG)) { |
| 5213 | netdev_info(dev, "Dropping NETIF_F_GSO since no SG feature.\n"); | 5217 | netdev_info(dev, "Dropping NETIF_F_GSO since no SG feature.\n"); |
diff --git a/net/dsa/mv88e6131.c b/net/dsa/mv88e6131.c index d951f93644bf..3da418894efc 100644 --- a/net/dsa/mv88e6131.c +++ b/net/dsa/mv88e6131.c | |||
| @@ -14,6 +14,13 @@ | |||
| 14 | #include "dsa_priv.h" | 14 | #include "dsa_priv.h" |
| 15 | #include "mv88e6xxx.h" | 15 | #include "mv88e6xxx.h" |
| 16 | 16 | ||
| 17 | /* | ||
| 18 | * Switch product IDs | ||
| 19 | */ | ||
| 20 | #define ID_6085 0x04a0 | ||
| 21 | #define ID_6095 0x0950 | ||
| 22 | #define ID_6131 0x1060 | ||
| 23 | |||
| 17 | static char *mv88e6131_probe(struct mii_bus *bus, int sw_addr) | 24 | static char *mv88e6131_probe(struct mii_bus *bus, int sw_addr) |
| 18 | { | 25 | { |
| 19 | int ret; | 26 | int ret; |
| @@ -21,9 +28,11 @@ static char *mv88e6131_probe(struct mii_bus *bus, int sw_addr) | |||
| 21 | ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), 0x03); | 28 | ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), 0x03); |
| 22 | if (ret >= 0) { | 29 | if (ret >= 0) { |
| 23 | ret &= 0xfff0; | 30 | ret &= 0xfff0; |
| 24 | if (ret == 0x0950) | 31 | if (ret == ID_6085) |
| 32 | return "Marvell 88E6085"; | ||
| 33 | if (ret == ID_6095) | ||
| 25 | return "Marvell 88E6095/88E6095F"; | 34 | return "Marvell 88E6095/88E6095F"; |
| 26 | if (ret == 0x1060) | 35 | if (ret == ID_6131) |
| 27 | return "Marvell 88E6131"; | 36 | return "Marvell 88E6131"; |
| 28 | } | 37 | } |
| 29 | 38 | ||
| @@ -164,6 +173,7 @@ static int mv88e6131_setup_global(struct dsa_switch *ds) | |||
| 164 | 173 | ||
| 165 | static int mv88e6131_setup_port(struct dsa_switch *ds, int p) | 174 | static int mv88e6131_setup_port(struct dsa_switch *ds, int p) |
| 166 | { | 175 | { |
| 176 | struct mv88e6xxx_priv_state *ps = (void *)(ds + 1); | ||
| 167 | int addr = REG_PORT(p); | 177 | int addr = REG_PORT(p); |
| 168 | u16 val; | 178 | u16 val; |
| 169 | 179 | ||
| @@ -171,10 +181,13 @@ static int mv88e6131_setup_port(struct dsa_switch *ds, int p) | |||
| 171 | * MAC Forcing register: don't force link, speed, duplex | 181 | * MAC Forcing register: don't force link, speed, duplex |
| 172 | * or flow control state to any particular values on physical | 182 | * or flow control state to any particular values on physical |
| 173 | * ports, but force the CPU port and all DSA ports to 1000 Mb/s | 183 | * ports, but force the CPU port and all DSA ports to 1000 Mb/s |
| 174 | * full duplex. | 184 | * (100 Mb/s on 6085) full duplex. |
| 175 | */ | 185 | */ |
| 176 | if (dsa_is_cpu_port(ds, p) || ds->dsa_port_mask & (1 << p)) | 186 | if (dsa_is_cpu_port(ds, p) || ds->dsa_port_mask & (1 << p)) |
| 177 | REG_WRITE(addr, 0x01, 0x003e); | 187 | if (ps->id == ID_6085) |
| 188 | REG_WRITE(addr, 0x01, 0x003d); /* 100 Mb/s */ | ||
| 189 | else | ||
| 190 | REG_WRITE(addr, 0x01, 0x003e); /* 1000 Mb/s */ | ||
| 178 | else | 191 | else |
| 179 | REG_WRITE(addr, 0x01, 0x0003); | 192 | REG_WRITE(addr, 0x01, 0x0003); |
| 180 | 193 | ||
| @@ -286,6 +299,8 @@ static int mv88e6131_setup(struct dsa_switch *ds) | |||
| 286 | mv88e6xxx_ppu_state_init(ds); | 299 | mv88e6xxx_ppu_state_init(ds); |
| 287 | mutex_init(&ps->stats_mutex); | 300 | mutex_init(&ps->stats_mutex); |
| 288 | 301 | ||
| 302 | ps->id = REG_READ(REG_PORT(0), 0x03) & 0xfff0; | ||
| 303 | |||
| 289 | ret = mv88e6131_switch_reset(ds); | 304 | ret = mv88e6131_switch_reset(ds); |
| 290 | if (ret < 0) | 305 | if (ret < 0) |
| 291 | return ret; | 306 | return ret; |
diff --git a/net/dsa/mv88e6xxx.h b/net/dsa/mv88e6xxx.h index eb0e0aaa9f1b..61156ca26a0d 100644 --- a/net/dsa/mv88e6xxx.h +++ b/net/dsa/mv88e6xxx.h | |||
| @@ -39,6 +39,8 @@ struct mv88e6xxx_priv_state { | |||
| 39 | * Hold this mutex over snapshot + dump sequences. | 39 | * Hold this mutex over snapshot + dump sequences. |
| 40 | */ | 40 | */ |
| 41 | struct mutex stats_mutex; | 41 | struct mutex stats_mutex; |
| 42 | |||
| 43 | int id; /* switch product id */ | ||
| 42 | }; | 44 | }; |
| 43 | 45 | ||
| 44 | struct mv88e6xxx_hw_stat { | 46 | struct mv88e6xxx_hw_stat { |
diff --git a/net/ieee802154/Makefile b/net/ieee802154/Makefile index ce2d33582859..5761185f884e 100644 --- a/net/ieee802154/Makefile +++ b/net/ieee802154/Makefile | |||
| @@ -1,5 +1,3 @@ | |||
| 1 | obj-$(CONFIG_IEEE802154) += ieee802154.o af_802154.o | 1 | obj-$(CONFIG_IEEE802154) += ieee802154.o af_802154.o |
| 2 | ieee802154-y := netlink.o nl-mac.o nl-phy.o nl_policy.o wpan-class.o | 2 | ieee802154-y := netlink.o nl-mac.o nl-phy.o nl_policy.o wpan-class.o |
| 3 | af_802154-y := af_ieee802154.o raw.o dgram.o | 3 | af_802154-y := af_ieee802154.o raw.o dgram.o |
| 4 | |||
| 5 | ccflags-y += -Wall -DDEBUG | ||
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 6c0b7f4a3d7d..38f23e721b80 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c | |||
| @@ -73,7 +73,7 @@ int inet_csk_bind_conflict(const struct sock *sk, | |||
| 73 | !sk2->sk_bound_dev_if || | 73 | !sk2->sk_bound_dev_if || |
| 74 | sk->sk_bound_dev_if == sk2->sk_bound_dev_if)) { | 74 | sk->sk_bound_dev_if == sk2->sk_bound_dev_if)) { |
| 75 | if (!reuse || !sk2->sk_reuse || | 75 | if (!reuse || !sk2->sk_reuse || |
| 76 | ((1 << sk2->sk_state) & (TCPF_LISTEN | TCPF_CLOSE))) { | 76 | sk2->sk_state == TCP_LISTEN) { |
| 77 | const __be32 sk2_rcv_saddr = sk_rcv_saddr(sk2); | 77 | const __be32 sk2_rcv_saddr = sk_rcv_saddr(sk2); |
| 78 | if (!sk2_rcv_saddr || !sk_rcv_saddr(sk) || | 78 | if (!sk2_rcv_saddr || !sk_rcv_saddr(sk) || |
| 79 | sk2_rcv_saddr == sk_rcv_saddr(sk)) | 79 | sk2_rcv_saddr == sk_rcv_saddr(sk)) |
| @@ -122,8 +122,7 @@ again: | |||
| 122 | (tb->num_owners < smallest_size || smallest_size == -1)) { | 122 | (tb->num_owners < smallest_size || smallest_size == -1)) { |
| 123 | smallest_size = tb->num_owners; | 123 | smallest_size = tb->num_owners; |
| 124 | smallest_rover = rover; | 124 | smallest_rover = rover; |
| 125 | if (atomic_read(&hashinfo->bsockets) > (high - low) + 1 && | 125 | if (atomic_read(&hashinfo->bsockets) > (high - low) + 1) { |
| 126 | !inet_csk(sk)->icsk_af_ops->bind_conflict(sk, tb)) { | ||
| 127 | spin_unlock(&head->lock); | 126 | spin_unlock(&head->lock); |
| 128 | snum = smallest_rover; | 127 | snum = smallest_rover; |
| 129 | goto have_snum; | 128 | goto have_snum; |
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index dd1b20eca1a2..9df4e635fb5f 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c | |||
| @@ -354,7 +354,8 @@ static void inetpeer_free_rcu(struct rcu_head *head) | |||
| 354 | } | 354 | } |
| 355 | 355 | ||
| 356 | /* May be called with local BH enabled. */ | 356 | /* May be called with local BH enabled. */ |
| 357 | static void unlink_from_pool(struct inet_peer *p, struct inet_peer_base *base) | 357 | static void unlink_from_pool(struct inet_peer *p, struct inet_peer_base *base, |
| 358 | struct inet_peer __rcu **stack[PEER_MAXDEPTH]) | ||
| 358 | { | 359 | { |
| 359 | int do_free; | 360 | int do_free; |
| 360 | 361 | ||
| @@ -368,7 +369,6 @@ static void unlink_from_pool(struct inet_peer *p, struct inet_peer_base *base) | |||
| 368 | * We use refcnt=-1 to alert lockless readers this entry is deleted. | 369 | * We use refcnt=-1 to alert lockless readers this entry is deleted. |
| 369 | */ | 370 | */ |
| 370 | if (atomic_cmpxchg(&p->refcnt, 1, -1) == 1) { | 371 | if (atomic_cmpxchg(&p->refcnt, 1, -1) == 1) { |
| 371 | struct inet_peer __rcu **stack[PEER_MAXDEPTH]; | ||
| 372 | struct inet_peer __rcu ***stackptr, ***delp; | 372 | struct inet_peer __rcu ***stackptr, ***delp; |
| 373 | if (lookup(&p->daddr, stack, base) != p) | 373 | if (lookup(&p->daddr, stack, base) != p) |
| 374 | BUG(); | 374 | BUG(); |
| @@ -422,7 +422,7 @@ static struct inet_peer_base *peer_to_base(struct inet_peer *p) | |||
| 422 | } | 422 | } |
| 423 | 423 | ||
| 424 | /* May be called with local BH enabled. */ | 424 | /* May be called with local BH enabled. */ |
| 425 | static int cleanup_once(unsigned long ttl) | 425 | static int cleanup_once(unsigned long ttl, struct inet_peer __rcu **stack[PEER_MAXDEPTH]) |
| 426 | { | 426 | { |
| 427 | struct inet_peer *p = NULL; | 427 | struct inet_peer *p = NULL; |
| 428 | 428 | ||
| @@ -454,7 +454,7 @@ static int cleanup_once(unsigned long ttl) | |||
| 454 | * happen because of entry limits in route cache. */ | 454 | * happen because of entry limits in route cache. */ |
| 455 | return -1; | 455 | return -1; |
| 456 | 456 | ||
| 457 | unlink_from_pool(p, peer_to_base(p)); | 457 | unlink_from_pool(p, peer_to_base(p), stack); |
| 458 | return 0; | 458 | return 0; |
| 459 | } | 459 | } |
| 460 | 460 | ||
| @@ -524,7 +524,7 @@ struct inet_peer *inet_getpeer(struct inetpeer_addr *daddr, int create) | |||
| 524 | 524 | ||
| 525 | if (base->total >= inet_peer_threshold) | 525 | if (base->total >= inet_peer_threshold) |
| 526 | /* Remove one less-recently-used entry. */ | 526 | /* Remove one less-recently-used entry. */ |
| 527 | cleanup_once(0); | 527 | cleanup_once(0, stack); |
| 528 | 528 | ||
| 529 | return p; | 529 | return p; |
| 530 | } | 530 | } |
| @@ -540,6 +540,7 @@ static void peer_check_expire(unsigned long dummy) | |||
| 540 | { | 540 | { |
| 541 | unsigned long now = jiffies; | 541 | unsigned long now = jiffies; |
| 542 | int ttl, total; | 542 | int ttl, total; |
| 543 | struct inet_peer __rcu **stack[PEER_MAXDEPTH]; | ||
| 543 | 544 | ||
| 544 | total = compute_total(); | 545 | total = compute_total(); |
| 545 | if (total >= inet_peer_threshold) | 546 | if (total >= inet_peer_threshold) |
| @@ -548,7 +549,7 @@ static void peer_check_expire(unsigned long dummy) | |||
| 548 | ttl = inet_peer_maxttl | 549 | ttl = inet_peer_maxttl |
| 549 | - (inet_peer_maxttl - inet_peer_minttl) / HZ * | 550 | - (inet_peer_maxttl - inet_peer_minttl) / HZ * |
| 550 | total / inet_peer_threshold * HZ; | 551 | total / inet_peer_threshold * HZ; |
| 551 | while (!cleanup_once(ttl)) { | 552 | while (!cleanup_once(ttl, stack)) { |
| 552 | if (jiffies != now) | 553 | if (jiffies != now) |
| 553 | break; | 554 | break; |
| 554 | } | 555 | } |
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c index 28a736f3442f..2391b24e8251 100644 --- a/net/ipv4/ip_options.c +++ b/net/ipv4/ip_options.c | |||
| @@ -329,7 +329,7 @@ int ip_options_compile(struct net *net, | |||
| 329 | pp_ptr = optptr + 2; | 329 | pp_ptr = optptr + 2; |
| 330 | goto error; | 330 | goto error; |
| 331 | } | 331 | } |
| 332 | if (skb) { | 332 | if (rt) { |
| 333 | memcpy(&optptr[optptr[2]-1], &rt->rt_spec_dst, 4); | 333 | memcpy(&optptr[optptr[2]-1], &rt->rt_spec_dst, 4); |
| 334 | opt->is_changed = 1; | 334 | opt->is_changed = 1; |
| 335 | } | 335 | } |
| @@ -371,7 +371,7 @@ int ip_options_compile(struct net *net, | |||
| 371 | goto error; | 371 | goto error; |
| 372 | } | 372 | } |
| 373 | opt->ts = optptr - iph; | 373 | opt->ts = optptr - iph; |
| 374 | if (skb) { | 374 | if (rt) { |
| 375 | memcpy(&optptr[optptr[2]-1], &rt->rt_spec_dst, 4); | 375 | memcpy(&optptr[optptr[2]-1], &rt->rt_spec_dst, 4); |
| 376 | timeptr = (__be32*)&optptr[optptr[2]+3]; | 376 | timeptr = (__be32*)&optptr[optptr[2]+3]; |
| 377 | } | 377 | } |
| @@ -603,7 +603,7 @@ int ip_options_rcv_srr(struct sk_buff *skb) | |||
| 603 | unsigned long orefdst; | 603 | unsigned long orefdst; |
| 604 | int err; | 604 | int err; |
| 605 | 605 | ||
| 606 | if (!opt->srr) | 606 | if (!opt->srr || !rt) |
| 607 | return 0; | 607 | return 0; |
| 608 | 608 | ||
| 609 | if (skb->pkt_type != PACKET_HOST) | 609 | if (skb->pkt_type != PACKET_HOST) |
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c index f3c0b549b8e1..4614babdc45f 100644 --- a/net/ipv4/netfilter.c +++ b/net/ipv4/netfilter.c | |||
| @@ -221,9 +221,10 @@ static __sum16 nf_ip_checksum_partial(struct sk_buff *skb, unsigned int hook, | |||
| 221 | return csum; | 221 | return csum; |
| 222 | } | 222 | } |
| 223 | 223 | ||
| 224 | static int nf_ip_route(struct dst_entry **dst, struct flowi *fl) | 224 | static int nf_ip_route(struct net *net, struct dst_entry **dst, |
| 225 | struct flowi *fl, bool strict __always_unused) | ||
| 225 | { | 226 | { |
| 226 | struct rtable *rt = ip_route_output_key(&init_net, &fl->u.ip4); | 227 | struct rtable *rt = ip_route_output_key(net, &fl->u.ip4); |
| 227 | if (IS_ERR(rt)) | 228 | if (IS_ERR(rt)) |
| 228 | return PTR_ERR(rt); | 229 | return PTR_ERR(rt); |
| 229 | *dst = &rt->dst; | 230 | *dst = &rt->dst; |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index ea107515c53e..c1acf69858fd 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
| @@ -1891,6 +1891,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
| 1891 | #ifdef CONFIG_IP_ROUTE_CLASSID | 1891 | #ifdef CONFIG_IP_ROUTE_CLASSID |
| 1892 | rth->dst.tclassid = itag; | 1892 | rth->dst.tclassid = itag; |
| 1893 | #endif | 1893 | #endif |
| 1894 | rth->rt_route_iif = dev->ifindex; | ||
| 1894 | rth->rt_iif = dev->ifindex; | 1895 | rth->rt_iif = dev->ifindex; |
| 1895 | rth->dst.dev = init_net.loopback_dev; | 1896 | rth->dst.dev = init_net.loopback_dev; |
| 1896 | dev_hold(rth->dst.dev); | 1897 | dev_hold(rth->dst.dev); |
| @@ -2026,6 +2027,7 @@ static int __mkroute_input(struct sk_buff *skb, | |||
| 2026 | rth->rt_key_src = saddr; | 2027 | rth->rt_key_src = saddr; |
| 2027 | rth->rt_src = saddr; | 2028 | rth->rt_src = saddr; |
| 2028 | rth->rt_gateway = daddr; | 2029 | rth->rt_gateway = daddr; |
| 2030 | rth->rt_route_iif = in_dev->dev->ifindex; | ||
| 2029 | rth->rt_iif = in_dev->dev->ifindex; | 2031 | rth->rt_iif = in_dev->dev->ifindex; |
| 2030 | rth->dst.dev = (out_dev)->dev; | 2032 | rth->dst.dev = (out_dev)->dev; |
| 2031 | dev_hold(rth->dst.dev); | 2033 | dev_hold(rth->dst.dev); |
| @@ -2202,6 +2204,7 @@ local_input: | |||
| 2202 | #ifdef CONFIG_IP_ROUTE_CLASSID | 2204 | #ifdef CONFIG_IP_ROUTE_CLASSID |
| 2203 | rth->dst.tclassid = itag; | 2205 | rth->dst.tclassid = itag; |
| 2204 | #endif | 2206 | #endif |
| 2207 | rth->rt_route_iif = dev->ifindex; | ||
| 2205 | rth->rt_iif = dev->ifindex; | 2208 | rth->rt_iif = dev->ifindex; |
| 2206 | rth->dst.dev = net->loopback_dev; | 2209 | rth->dst.dev = net->loopback_dev; |
| 2207 | dev_hold(rth->dst.dev); | 2210 | dev_hold(rth->dst.dev); |
| @@ -2401,7 +2404,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res, | |||
| 2401 | rth->rt_mark = oldflp4->flowi4_mark; | 2404 | rth->rt_mark = oldflp4->flowi4_mark; |
| 2402 | rth->rt_dst = fl4->daddr; | 2405 | rth->rt_dst = fl4->daddr; |
| 2403 | rth->rt_src = fl4->saddr; | 2406 | rth->rt_src = fl4->saddr; |
| 2404 | rth->rt_iif = 0; | 2407 | rth->rt_route_iif = 0; |
| 2408 | rth->rt_iif = oldflp4->flowi4_oif ? : dev_out->ifindex; | ||
| 2405 | /* get references to the devices that are to be hold by the routing | 2409 | /* get references to the devices that are to be hold by the routing |
| 2406 | cache entry */ | 2410 | cache entry */ |
| 2407 | rth->dst.dev = dev_out; | 2411 | rth->dst.dev = dev_out; |
| @@ -2716,6 +2720,7 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or | |||
| 2716 | rt->rt_key_dst = ort->rt_key_dst; | 2720 | rt->rt_key_dst = ort->rt_key_dst; |
| 2717 | rt->rt_key_src = ort->rt_key_src; | 2721 | rt->rt_key_src = ort->rt_key_src; |
| 2718 | rt->rt_tos = ort->rt_tos; | 2722 | rt->rt_tos = ort->rt_tos; |
| 2723 | rt->rt_route_iif = ort->rt_route_iif; | ||
| 2719 | rt->rt_iif = ort->rt_iif; | 2724 | rt->rt_iif = ort->rt_iif; |
| 2720 | rt->rt_oif = ort->rt_oif; | 2725 | rt->rt_oif = ort->rt_oif; |
| 2721 | rt->rt_mark = ort->rt_mark; | 2726 | rt->rt_mark = ort->rt_mark; |
| @@ -2725,7 +2730,6 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or | |||
| 2725 | rt->rt_type = ort->rt_type; | 2730 | rt->rt_type = ort->rt_type; |
| 2726 | rt->rt_dst = ort->rt_dst; | 2731 | rt->rt_dst = ort->rt_dst; |
| 2727 | rt->rt_src = ort->rt_src; | 2732 | rt->rt_src = ort->rt_src; |
| 2728 | rt->rt_iif = ort->rt_iif; | ||
| 2729 | rt->rt_gateway = ort->rt_gateway; | 2733 | rt->rt_gateway = ort->rt_gateway; |
| 2730 | rt->rt_spec_dst = ort->rt_spec_dst; | 2734 | rt->rt_spec_dst = ort->rt_spec_dst; |
| 2731 | rt->peer = ort->peer; | 2735 | rt->peer = ort->peer; |
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 1a456652086b..321e6e84dbcc 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c | |||
| @@ -311,7 +311,6 @@ static struct ctl_table ipv4_table[] = { | |||
| 311 | .mode = 0644, | 311 | .mode = 0644, |
| 312 | .proc_handler = proc_do_large_bitmap, | 312 | .proc_handler = proc_do_large_bitmap, |
| 313 | }, | 313 | }, |
| 314 | #ifdef CONFIG_IP_MULTICAST | ||
| 315 | { | 314 | { |
| 316 | .procname = "igmp_max_memberships", | 315 | .procname = "igmp_max_memberships", |
| 317 | .data = &sysctl_igmp_max_memberships, | 316 | .data = &sysctl_igmp_max_memberships, |
| @@ -319,8 +318,6 @@ static struct ctl_table ipv4_table[] = { | |||
| 319 | .mode = 0644, | 318 | .mode = 0644, |
| 320 | .proc_handler = proc_dointvec | 319 | .proc_handler = proc_dointvec |
| 321 | }, | 320 | }, |
| 322 | |||
| 323 | #endif | ||
| 324 | { | 321 | { |
| 325 | .procname = "igmp_max_msf", | 322 | .procname = "igmp_max_msf", |
| 326 | .data = &sysctl_igmp_max_msf, | 323 | .data = &sysctl_igmp_max_msf, |
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 13e0e7f659ff..d20a05e970d8 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c | |||
| @@ -74,6 +74,7 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, | |||
| 74 | rt->rt_key_dst = fl4->daddr; | 74 | rt->rt_key_dst = fl4->daddr; |
| 75 | rt->rt_key_src = fl4->saddr; | 75 | rt->rt_key_src = fl4->saddr; |
| 76 | rt->rt_tos = fl4->flowi4_tos; | 76 | rt->rt_tos = fl4->flowi4_tos; |
| 77 | rt->rt_route_iif = fl4->flowi4_iif; | ||
| 77 | rt->rt_iif = fl4->flowi4_iif; | 78 | rt->rt_iif = fl4->flowi4_iif; |
| 78 | rt->rt_oif = fl4->flowi4_oif; | 79 | rt->rt_oif = fl4->flowi4_oif; |
| 79 | rt->rt_mark = fl4->flowi4_mark; | 80 | rt->rt_mark = fl4->flowi4_mark; |
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index 166054650466..f2c5b0fc0f21 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c | |||
| @@ -44,7 +44,7 @@ int inet6_csk_bind_conflict(const struct sock *sk, | |||
| 44 | !sk2->sk_bound_dev_if || | 44 | !sk2->sk_bound_dev_if || |
| 45 | sk->sk_bound_dev_if == sk2->sk_bound_dev_if) && | 45 | sk->sk_bound_dev_if == sk2->sk_bound_dev_if) && |
| 46 | (!sk->sk_reuse || !sk2->sk_reuse || | 46 | (!sk->sk_reuse || !sk2->sk_reuse || |
| 47 | ((1 << sk2->sk_state) & (TCPF_LISTEN | TCPF_CLOSE))) && | 47 | sk2->sk_state == TCP_LISTEN) && |
| 48 | ipv6_rcv_saddr_equal(sk, sk2)) | 48 | ipv6_rcv_saddr_equal(sk, sk2)) |
| 49 | break; | 49 | break; |
| 50 | } | 50 | } |
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c index 39aaca2b4fd2..28bc1f644b7b 100644 --- a/net/ipv6/netfilter.c +++ b/net/ipv6/netfilter.c | |||
| @@ -90,9 +90,18 @@ static int nf_ip6_reroute(struct sk_buff *skb, | |||
| 90 | return 0; | 90 | return 0; |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | static int nf_ip6_route(struct dst_entry **dst, struct flowi *fl) | 93 | static int nf_ip6_route(struct net *net, struct dst_entry **dst, |
| 94 | struct flowi *fl, bool strict) | ||
| 94 | { | 95 | { |
| 95 | *dst = ip6_route_output(&init_net, NULL, &fl->u.ip6); | 96 | static const struct ipv6_pinfo fake_pinfo; |
| 97 | static const struct inet_sock fake_sk = { | ||
| 98 | /* makes ip6_route_output set RT6_LOOKUP_F_IFACE: */ | ||
| 99 | .sk.sk_bound_dev_if = 1, | ||
| 100 | .pinet6 = (struct ipv6_pinfo *) &fake_pinfo, | ||
| 101 | }; | ||
| 102 | const void *sk = strict ? &fake_sk : NULL; | ||
| 103 | |||
| 104 | *dst = ip6_route_output(net, sk, &fl->u.ip6); | ||
| 96 | return (*dst)->error; | 105 | return (*dst)->error; |
| 97 | } | 106 | } |
| 98 | 107 | ||
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 56fa12538d45..4f49e5dd41bb 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
| @@ -1622,6 +1622,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) | |||
| 1622 | opt_skb = skb_clone(skb, GFP_ATOMIC); | 1622 | opt_skb = skb_clone(skb, GFP_ATOMIC); |
| 1623 | 1623 | ||
| 1624 | if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */ | 1624 | if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */ |
| 1625 | sock_rps_save_rxhash(sk, skb->rxhash); | ||
| 1625 | if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len)) | 1626 | if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len)) |
| 1626 | goto reset; | 1627 | goto reset; |
| 1627 | if (opt_skb) | 1628 | if (opt_skb) |
| @@ -1649,7 +1650,8 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) | |||
| 1649 | __kfree_skb(opt_skb); | 1650 | __kfree_skb(opt_skb); |
| 1650 | return 0; | 1651 | return 0; |
| 1651 | } | 1652 | } |
| 1652 | } | 1653 | } else |
| 1654 | sock_rps_save_rxhash(sk, skb->rxhash); | ||
| 1653 | 1655 | ||
| 1654 | if (tcp_rcv_state_process(sk, skb, tcp_hdr(skb), skb->len)) | 1656 | if (tcp_rcv_state_process(sk, skb, tcp_hdr(skb), skb->len)) |
| 1655 | goto reset; | 1657 | goto reset; |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index d7037c006e13..15c37746845e 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
| @@ -505,6 +505,9 @@ int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) | |||
| 505 | int rc; | 505 | int rc; |
| 506 | int is_udplite = IS_UDPLITE(sk); | 506 | int is_udplite = IS_UDPLITE(sk); |
| 507 | 507 | ||
| 508 | if (!ipv6_addr_any(&inet6_sk(sk)->daddr)) | ||
| 509 | sock_rps_save_rxhash(sk, skb->rxhash); | ||
| 510 | |||
| 508 | if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) | 511 | if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) |
| 509 | goto drop; | 512 | goto drop; |
| 510 | 513 | ||
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index c9890e25cd4c..cc616974a447 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c | |||
| @@ -1297,8 +1297,7 @@ static int irda_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
| 1297 | /* Note : socket.c set MSG_EOR on SEQPACKET sockets */ | 1297 | /* Note : socket.c set MSG_EOR on SEQPACKET sockets */ |
| 1298 | if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_EOR | MSG_CMSG_COMPAT | | 1298 | if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_EOR | MSG_CMSG_COMPAT | |
| 1299 | MSG_NOSIGNAL)) { | 1299 | MSG_NOSIGNAL)) { |
| 1300 | err = -EINVAL; | 1300 | return -EINVAL; |
| 1301 | goto out; | ||
| 1302 | } | 1301 | } |
| 1303 | 1302 | ||
| 1304 | lock_sock(sk); | 1303 | lock_sock(sk); |
diff --git a/net/llc/llc_input.c b/net/llc/llc_input.c index 058f1e9a9128..903242111317 100644 --- a/net/llc/llc_input.c +++ b/net/llc/llc_input.c | |||
| @@ -121,8 +121,7 @@ static inline int llc_fixup_skb(struct sk_buff *skb) | |||
| 121 | s32 data_size = ntohs(pdulen) - llc_len; | 121 | s32 data_size = ntohs(pdulen) - llc_len; |
| 122 | 122 | ||
| 123 | if (data_size < 0 || | 123 | if (data_size < 0 || |
| 124 | ((skb_tail_pointer(skb) - | 124 | !pskb_may_pull(skb, data_size)) |
| 125 | (u8 *)pdu) - llc_len) < data_size) | ||
| 126 | return 0; | 125 | return 0; |
| 127 | if (unlikely(pskb_trim_rcsum(skb, data_size))) | 126 | if (unlikely(pskb_trim_rcsum(skb, data_size))) |
| 128 | return 0; | 127 | return 0; |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 9d192d665ff5..c5d4530d8284 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
| @@ -2541,7 +2541,6 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx) | |||
| 2541 | * same TID from the same station | 2541 | * same TID from the same station |
| 2542 | */ | 2542 | */ |
| 2543 | rx->skb = skb; | 2543 | rx->skb = skb; |
| 2544 | rx->flags = 0; | ||
| 2545 | 2544 | ||
| 2546 | CALL_RXH(ieee80211_rx_h_decrypt) | 2545 | CALL_RXH(ieee80211_rx_h_decrypt) |
| 2547 | CALL_RXH(ieee80211_rx_h_check_more_data) | 2546 | CALL_RXH(ieee80211_rx_h_check_more_data) |
| @@ -2612,6 +2611,7 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) | |||
| 2612 | .sdata = sta->sdata, | 2611 | .sdata = sta->sdata, |
| 2613 | .local = sta->local, | 2612 | .local = sta->local, |
| 2614 | .queue = tid, | 2613 | .queue = tid, |
| 2614 | .flags = 0, | ||
| 2615 | }; | 2615 | }; |
| 2616 | struct tid_ampdu_rx *tid_agg_rx; | 2616 | struct tid_ampdu_rx *tid_agg_rx; |
| 2617 | 2617 | ||
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index c3f988aa1152..32bff6d86cb2 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig | |||
| @@ -652,7 +652,6 @@ comment "Xtables matches" | |||
| 652 | config NETFILTER_XT_MATCH_ADDRTYPE | 652 | config NETFILTER_XT_MATCH_ADDRTYPE |
| 653 | tristate '"addrtype" address type match support' | 653 | tristate '"addrtype" address type match support' |
| 654 | depends on NETFILTER_ADVANCED | 654 | depends on NETFILTER_ADVANCED |
| 655 | depends on (IPV6 || IPV6=n) | ||
| 656 | ---help--- | 655 | ---help--- |
| 657 | This option allows you to match what routing thinks of an address, | 656 | This option allows you to match what routing thinks of an address, |
| 658 | eg. UNICAST, LOCAL, BROADCAST, ... | 657 | eg. UNICAST, LOCAL, BROADCAST, ... |
diff --git a/net/netfilter/ipset/ip_set_bitmap_ip.c b/net/netfilter/ipset/ip_set_bitmap_ip.c index bca96990218d..a113ff066928 100644 --- a/net/netfilter/ipset/ip_set_bitmap_ip.c +++ b/net/netfilter/ipset/ip_set_bitmap_ip.c | |||
| @@ -338,8 +338,7 @@ bitmap_ip_head(struct ip_set *set, struct sk_buff *skb) | |||
| 338 | NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP_TO, htonl(map->last_ip)); | 338 | NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP_TO, htonl(map->last_ip)); |
| 339 | if (map->netmask != 32) | 339 | if (map->netmask != 32) |
| 340 | NLA_PUT_U8(skb, IPSET_ATTR_NETMASK, map->netmask); | 340 | NLA_PUT_U8(skb, IPSET_ATTR_NETMASK, map->netmask); |
| 341 | NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, | 341 | NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)); |
| 342 | htonl(atomic_read(&set->ref) - 1)); | ||
| 343 | NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE, | 342 | NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE, |
| 344 | htonl(sizeof(*map) + map->memsize)); | 343 | htonl(sizeof(*map) + map->memsize)); |
| 345 | if (with_timeout(map->timeout)) | 344 | if (with_timeout(map->timeout)) |
diff --git a/net/netfilter/ipset/ip_set_bitmap_ipmac.c b/net/netfilter/ipset/ip_set_bitmap_ipmac.c index 5e790172deff..a274300b6a56 100644 --- a/net/netfilter/ipset/ip_set_bitmap_ipmac.c +++ b/net/netfilter/ipset/ip_set_bitmap_ipmac.c | |||
| @@ -343,6 +343,10 @@ bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb, | |||
| 343 | ipset_adtfn adtfn = set->variant->adt[adt]; | 343 | ipset_adtfn adtfn = set->variant->adt[adt]; |
| 344 | struct ipmac data; | 344 | struct ipmac data; |
| 345 | 345 | ||
| 346 | /* MAC can be src only */ | ||
| 347 | if (!(flags & IPSET_DIM_TWO_SRC)) | ||
| 348 | return 0; | ||
| 349 | |||
| 346 | data.id = ntohl(ip4addr(skb, flags & IPSET_DIM_ONE_SRC)); | 350 | data.id = ntohl(ip4addr(skb, flags & IPSET_DIM_ONE_SRC)); |
| 347 | if (data.id < map->first_ip || data.id > map->last_ip) | 351 | if (data.id < map->first_ip || data.id > map->last_ip) |
| 348 | return -IPSET_ERR_BITMAP_RANGE; | 352 | return -IPSET_ERR_BITMAP_RANGE; |
| @@ -434,8 +438,7 @@ bitmap_ipmac_head(struct ip_set *set, struct sk_buff *skb) | |||
| 434 | goto nla_put_failure; | 438 | goto nla_put_failure; |
| 435 | NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, htonl(map->first_ip)); | 439 | NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, htonl(map->first_ip)); |
| 436 | NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP_TO, htonl(map->last_ip)); | 440 | NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP_TO, htonl(map->last_ip)); |
| 437 | NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, | 441 | NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)); |
| 438 | htonl(atomic_read(&set->ref) - 1)); | ||
| 439 | NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE, | 442 | NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE, |
| 440 | htonl(sizeof(*map) | 443 | htonl(sizeof(*map) |
| 441 | + (map->last_ip - map->first_ip + 1) * map->dsize)); | 444 | + (map->last_ip - map->first_ip + 1) * map->dsize)); |
diff --git a/net/netfilter/ipset/ip_set_bitmap_port.c b/net/netfilter/ipset/ip_set_bitmap_port.c index 165f09b1a9cb..6b38eb8f6ed8 100644 --- a/net/netfilter/ipset/ip_set_bitmap_port.c +++ b/net/netfilter/ipset/ip_set_bitmap_port.c | |||
| @@ -320,8 +320,7 @@ bitmap_port_head(struct ip_set *set, struct sk_buff *skb) | |||
| 320 | goto nla_put_failure; | 320 | goto nla_put_failure; |
| 321 | NLA_PUT_NET16(skb, IPSET_ATTR_PORT, htons(map->first_port)); | 321 | NLA_PUT_NET16(skb, IPSET_ATTR_PORT, htons(map->first_port)); |
| 322 | NLA_PUT_NET16(skb, IPSET_ATTR_PORT_TO, htons(map->last_port)); | 322 | NLA_PUT_NET16(skb, IPSET_ATTR_PORT_TO, htons(map->last_port)); |
| 323 | NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, | 323 | NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)); |
| 324 | htonl(atomic_read(&set->ref) - 1)); | ||
| 325 | NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE, | 324 | NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE, |
| 326 | htonl(sizeof(*map) + map->memsize)); | 325 | htonl(sizeof(*map) + map->memsize)); |
| 327 | if (with_timeout(map->timeout)) | 326 | if (with_timeout(map->timeout)) |
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c index 253326e8d990..72d1ac611fdc 100644 --- a/net/netfilter/ipset/ip_set_core.c +++ b/net/netfilter/ipset/ip_set_core.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | 26 | ||
| 27 | static LIST_HEAD(ip_set_type_list); /* all registered set types */ | 27 | static LIST_HEAD(ip_set_type_list); /* all registered set types */ |
| 28 | static DEFINE_MUTEX(ip_set_type_mutex); /* protects ip_set_type_list */ | 28 | static DEFINE_MUTEX(ip_set_type_mutex); /* protects ip_set_type_list */ |
| 29 | static DEFINE_RWLOCK(ip_set_ref_lock); /* protects the set refs */ | ||
| 29 | 30 | ||
| 30 | static struct ip_set **ip_set_list; /* all individual sets */ | 31 | static struct ip_set **ip_set_list; /* all individual sets */ |
| 31 | static ip_set_id_t ip_set_max = CONFIG_IP_SET_MAX; /* max number of sets */ | 32 | static ip_set_id_t ip_set_max = CONFIG_IP_SET_MAX; /* max number of sets */ |
| @@ -301,13 +302,18 @@ EXPORT_SYMBOL_GPL(ip_set_get_ipaddr6); | |||
| 301 | static inline void | 302 | static inline void |
| 302 | __ip_set_get(ip_set_id_t index) | 303 | __ip_set_get(ip_set_id_t index) |
| 303 | { | 304 | { |
| 304 | atomic_inc(&ip_set_list[index]->ref); | 305 | write_lock_bh(&ip_set_ref_lock); |
| 306 | ip_set_list[index]->ref++; | ||
| 307 | write_unlock_bh(&ip_set_ref_lock); | ||
| 305 | } | 308 | } |
| 306 | 309 | ||
| 307 | static inline void | 310 | static inline void |
| 308 | __ip_set_put(ip_set_id_t index) | 311 | __ip_set_put(ip_set_id_t index) |
| 309 | { | 312 | { |
| 310 | atomic_dec(&ip_set_list[index]->ref); | 313 | write_lock_bh(&ip_set_ref_lock); |
| 314 | BUG_ON(ip_set_list[index]->ref == 0); | ||
| 315 | ip_set_list[index]->ref--; | ||
| 316 | write_unlock_bh(&ip_set_ref_lock); | ||
| 311 | } | 317 | } |
| 312 | 318 | ||
| 313 | /* | 319 | /* |
| @@ -324,7 +330,7 @@ ip_set_test(ip_set_id_t index, const struct sk_buff *skb, | |||
| 324 | struct ip_set *set = ip_set_list[index]; | 330 | struct ip_set *set = ip_set_list[index]; |
| 325 | int ret = 0; | 331 | int ret = 0; |
| 326 | 332 | ||
| 327 | BUG_ON(set == NULL || atomic_read(&set->ref) == 0); | 333 | BUG_ON(set == NULL); |
| 328 | pr_debug("set %s, index %u\n", set->name, index); | 334 | pr_debug("set %s, index %u\n", set->name, index); |
| 329 | 335 | ||
| 330 | if (dim < set->type->dimension || | 336 | if (dim < set->type->dimension || |
| @@ -356,7 +362,7 @@ ip_set_add(ip_set_id_t index, const struct sk_buff *skb, | |||
| 356 | struct ip_set *set = ip_set_list[index]; | 362 | struct ip_set *set = ip_set_list[index]; |
| 357 | int ret; | 363 | int ret; |
| 358 | 364 | ||
| 359 | BUG_ON(set == NULL || atomic_read(&set->ref) == 0); | 365 | BUG_ON(set == NULL); |
| 360 | pr_debug("set %s, index %u\n", set->name, index); | 366 | pr_debug("set %s, index %u\n", set->name, index); |
| 361 | 367 | ||
| 362 | if (dim < set->type->dimension || | 368 | if (dim < set->type->dimension || |
| @@ -378,7 +384,7 @@ ip_set_del(ip_set_id_t index, const struct sk_buff *skb, | |||
| 378 | struct ip_set *set = ip_set_list[index]; | 384 | struct ip_set *set = ip_set_list[index]; |
| 379 | int ret = 0; | 385 | int ret = 0; |
| 380 | 386 | ||
| 381 | BUG_ON(set == NULL || atomic_read(&set->ref) == 0); | 387 | BUG_ON(set == NULL); |
| 382 | pr_debug("set %s, index %u\n", set->name, index); | 388 | pr_debug("set %s, index %u\n", set->name, index); |
| 383 | 389 | ||
| 384 | if (dim < set->type->dimension || | 390 | if (dim < set->type->dimension || |
| @@ -397,7 +403,6 @@ EXPORT_SYMBOL_GPL(ip_set_del); | |||
| 397 | * Find set by name, reference it once. The reference makes sure the | 403 | * Find set by name, reference it once. The reference makes sure the |
| 398 | * thing pointed to, does not go away under our feet. | 404 | * thing pointed to, does not go away under our feet. |
| 399 | * | 405 | * |
| 400 | * The nfnl mutex must already be activated. | ||
| 401 | */ | 406 | */ |
| 402 | ip_set_id_t | 407 | ip_set_id_t |
| 403 | ip_set_get_byname(const char *name, struct ip_set **set) | 408 | ip_set_get_byname(const char *name, struct ip_set **set) |
| @@ -423,15 +428,12 @@ EXPORT_SYMBOL_GPL(ip_set_get_byname); | |||
| 423 | * reference count by 1. The caller shall not assume the index | 428 | * reference count by 1. The caller shall not assume the index |
| 424 | * to be valid, after calling this function. | 429 | * to be valid, after calling this function. |
| 425 | * | 430 | * |
| 426 | * The nfnl mutex must already be activated. | ||
| 427 | */ | 431 | */ |
| 428 | void | 432 | void |
| 429 | ip_set_put_byindex(ip_set_id_t index) | 433 | ip_set_put_byindex(ip_set_id_t index) |
| 430 | { | 434 | { |
| 431 | if (ip_set_list[index] != NULL) { | 435 | if (ip_set_list[index] != NULL) |
| 432 | BUG_ON(atomic_read(&ip_set_list[index]->ref) == 0); | ||
| 433 | __ip_set_put(index); | 436 | __ip_set_put(index); |
| 434 | } | ||
| 435 | } | 437 | } |
| 436 | EXPORT_SYMBOL_GPL(ip_set_put_byindex); | 438 | EXPORT_SYMBOL_GPL(ip_set_put_byindex); |
| 437 | 439 | ||
| @@ -441,7 +443,6 @@ EXPORT_SYMBOL_GPL(ip_set_put_byindex); | |||
| 441 | * can't be destroyed. The set cannot be renamed due to | 443 | * can't be destroyed. The set cannot be renamed due to |
| 442 | * the referencing either. | 444 | * the referencing either. |
| 443 | * | 445 | * |
| 444 | * The nfnl mutex must already be activated. | ||
| 445 | */ | 446 | */ |
| 446 | const char * | 447 | const char * |
| 447 | ip_set_name_byindex(ip_set_id_t index) | 448 | ip_set_name_byindex(ip_set_id_t index) |
| @@ -449,7 +450,7 @@ ip_set_name_byindex(ip_set_id_t index) | |||
| 449 | const struct ip_set *set = ip_set_list[index]; | 450 | const struct ip_set *set = ip_set_list[index]; |
| 450 | 451 | ||
| 451 | BUG_ON(set == NULL); | 452 | BUG_ON(set == NULL); |
| 452 | BUG_ON(atomic_read(&set->ref) == 0); | 453 | BUG_ON(set->ref == 0); |
| 453 | 454 | ||
| 454 | /* Referenced, so it's safe */ | 455 | /* Referenced, so it's safe */ |
| 455 | return set->name; | 456 | return set->name; |
| @@ -515,10 +516,7 @@ void | |||
| 515 | ip_set_nfnl_put(ip_set_id_t index) | 516 | ip_set_nfnl_put(ip_set_id_t index) |
| 516 | { | 517 | { |
| 517 | nfnl_lock(); | 518 | nfnl_lock(); |
| 518 | if (ip_set_list[index] != NULL) { | 519 | ip_set_put_byindex(index); |
| 519 | BUG_ON(atomic_read(&ip_set_list[index]->ref) == 0); | ||
| 520 | __ip_set_put(index); | ||
| 521 | } | ||
| 522 | nfnl_unlock(); | 520 | nfnl_unlock(); |
| 523 | } | 521 | } |
| 524 | EXPORT_SYMBOL_GPL(ip_set_nfnl_put); | 522 | EXPORT_SYMBOL_GPL(ip_set_nfnl_put); |
| @@ -526,7 +524,7 @@ EXPORT_SYMBOL_GPL(ip_set_nfnl_put); | |||
| 526 | /* | 524 | /* |
| 527 | * Communication protocol with userspace over netlink. | 525 | * Communication protocol with userspace over netlink. |
| 528 | * | 526 | * |
| 529 | * We already locked by nfnl_lock. | 527 | * The commands are serialized by the nfnl mutex. |
| 530 | */ | 528 | */ |
| 531 | 529 | ||
| 532 | static inline bool | 530 | static inline bool |
| @@ -657,7 +655,6 @@ ip_set_create(struct sock *ctnl, struct sk_buff *skb, | |||
| 657 | return -ENOMEM; | 655 | return -ENOMEM; |
| 658 | rwlock_init(&set->lock); | 656 | rwlock_init(&set->lock); |
| 659 | strlcpy(set->name, name, IPSET_MAXNAMELEN); | 657 | strlcpy(set->name, name, IPSET_MAXNAMELEN); |
| 660 | atomic_set(&set->ref, 0); | ||
| 661 | set->family = family; | 658 | set->family = family; |
| 662 | 659 | ||
| 663 | /* | 660 | /* |
| @@ -690,8 +687,8 @@ ip_set_create(struct sock *ctnl, struct sk_buff *skb, | |||
| 690 | 687 | ||
| 691 | /* | 688 | /* |
| 692 | * Here, we have a valid, constructed set and we are protected | 689 | * Here, we have a valid, constructed set and we are protected |
| 693 | * by nfnl_lock. Find the first free index in ip_set_list and | 690 | * by the nfnl mutex. Find the first free index in ip_set_list |
| 694 | * check clashing. | 691 | * and check clashing. |
| 695 | */ | 692 | */ |
| 696 | if ((ret = find_free_id(set->name, &index, &clash)) != 0) { | 693 | if ((ret = find_free_id(set->name, &index, &clash)) != 0) { |
| 697 | /* If this is the same set and requested, ignore error */ | 694 | /* If this is the same set and requested, ignore error */ |
| @@ -751,31 +748,51 @@ ip_set_destroy(struct sock *ctnl, struct sk_buff *skb, | |||
| 751 | const struct nlattr * const attr[]) | 748 | const struct nlattr * const attr[]) |
| 752 | { | 749 | { |
| 753 | ip_set_id_t i; | 750 | ip_set_id_t i; |
| 751 | int ret = 0; | ||
| 754 | 752 | ||
| 755 | if (unlikely(protocol_failed(attr))) | 753 | if (unlikely(protocol_failed(attr))) |
| 756 | return -IPSET_ERR_PROTOCOL; | 754 | return -IPSET_ERR_PROTOCOL; |
| 757 | 755 | ||
| 758 | /* References are protected by the nfnl mutex */ | 756 | /* Commands are serialized and references are |
| 757 | * protected by the ip_set_ref_lock. | ||
| 758 | * External systems (i.e. xt_set) must call | ||
| 759 | * ip_set_put|get_nfnl_* functions, that way we | ||
| 760 | * can safely check references here. | ||
| 761 | * | ||
| 762 | * list:set timer can only decrement the reference | ||
| 763 | * counter, so if it's already zero, we can proceed | ||
| 764 | * without holding the lock. | ||
| 765 | */ | ||
| 766 | read_lock_bh(&ip_set_ref_lock); | ||
| 759 | if (!attr[IPSET_ATTR_SETNAME]) { | 767 | if (!attr[IPSET_ATTR_SETNAME]) { |
| 760 | for (i = 0; i < ip_set_max; i++) { | 768 | for (i = 0; i < ip_set_max; i++) { |
| 761 | if (ip_set_list[i] != NULL && | 769 | if (ip_set_list[i] != NULL && ip_set_list[i]->ref) { |
| 762 | (atomic_read(&ip_set_list[i]->ref))) | 770 | ret = IPSET_ERR_BUSY; |
| 763 | return -IPSET_ERR_BUSY; | 771 | goto out; |
| 772 | } | ||
| 764 | } | 773 | } |
| 774 | read_unlock_bh(&ip_set_ref_lock); | ||
| 765 | for (i = 0; i < ip_set_max; i++) { | 775 | for (i = 0; i < ip_set_max; i++) { |
| 766 | if (ip_set_list[i] != NULL) | 776 | if (ip_set_list[i] != NULL) |
| 767 | ip_set_destroy_set(i); | 777 | ip_set_destroy_set(i); |
| 768 | } | 778 | } |
| 769 | } else { | 779 | } else { |
| 770 | i = find_set_id(nla_data(attr[IPSET_ATTR_SETNAME])); | 780 | i = find_set_id(nla_data(attr[IPSET_ATTR_SETNAME])); |
| 771 | if (i == IPSET_INVALID_ID) | 781 | if (i == IPSET_INVALID_ID) { |
| 772 | return -ENOENT; | 782 | ret = -ENOENT; |
| 773 | else if (atomic_read(&ip_set_list[i]->ref)) | 783 | goto out; |
| 774 | return -IPSET_ERR_BUSY; | 784 | } else if (ip_set_list[i]->ref) { |
| 785 | ret = -IPSET_ERR_BUSY; | ||
| 786 | goto out; | ||
| 787 | } | ||
| 788 | read_unlock_bh(&ip_set_ref_lock); | ||
| 775 | 789 | ||
| 776 | ip_set_destroy_set(i); | 790 | ip_set_destroy_set(i); |
| 777 | } | 791 | } |
| 778 | return 0; | 792 | return 0; |
| 793 | out: | ||
| 794 | read_unlock_bh(&ip_set_ref_lock); | ||
| 795 | return ret; | ||
| 779 | } | 796 | } |
| 780 | 797 | ||
| 781 | /* Flush sets */ | 798 | /* Flush sets */ |
| @@ -834,6 +851,7 @@ ip_set_rename(struct sock *ctnl, struct sk_buff *skb, | |||
| 834 | struct ip_set *set; | 851 | struct ip_set *set; |
| 835 | const char *name2; | 852 | const char *name2; |
| 836 | ip_set_id_t i; | 853 | ip_set_id_t i; |
| 854 | int ret = 0; | ||
| 837 | 855 | ||
| 838 | if (unlikely(protocol_failed(attr) || | 856 | if (unlikely(protocol_failed(attr) || |
| 839 | attr[IPSET_ATTR_SETNAME] == NULL || | 857 | attr[IPSET_ATTR_SETNAME] == NULL || |
| @@ -843,25 +861,33 @@ ip_set_rename(struct sock *ctnl, struct sk_buff *skb, | |||
| 843 | set = find_set(nla_data(attr[IPSET_ATTR_SETNAME])); | 861 | set = find_set(nla_data(attr[IPSET_ATTR_SETNAME])); |
| 844 | if (set == NULL) | 862 | if (set == NULL) |
| 845 | return -ENOENT; | 863 | return -ENOENT; |
| 846 | if (atomic_read(&set->ref) != 0) | 864 | |
| 847 | return -IPSET_ERR_REFERENCED; | 865 | read_lock_bh(&ip_set_ref_lock); |
| 866 | if (set->ref != 0) { | ||
| 867 | ret = -IPSET_ERR_REFERENCED; | ||
| 868 | goto out; | ||
| 869 | } | ||
| 848 | 870 | ||
| 849 | name2 = nla_data(attr[IPSET_ATTR_SETNAME2]); | 871 | name2 = nla_data(attr[IPSET_ATTR_SETNAME2]); |
| 850 | for (i = 0; i < ip_set_max; i++) { | 872 | for (i = 0; i < ip_set_max; i++) { |
| 851 | if (ip_set_list[i] != NULL && | 873 | if (ip_set_list[i] != NULL && |
| 852 | STREQ(ip_set_list[i]->name, name2)) | 874 | STREQ(ip_set_list[i]->name, name2)) { |
| 853 | return -IPSET_ERR_EXIST_SETNAME2; | 875 | ret = -IPSET_ERR_EXIST_SETNAME2; |
| 876 | goto out; | ||
| 877 | } | ||
| 854 | } | 878 | } |
| 855 | strncpy(set->name, name2, IPSET_MAXNAMELEN); | 879 | strncpy(set->name, name2, IPSET_MAXNAMELEN); |
| 856 | 880 | ||
| 857 | return 0; | 881 | out: |
| 882 | read_unlock_bh(&ip_set_ref_lock); | ||
| 883 | return ret; | ||
| 858 | } | 884 | } |
| 859 | 885 | ||
| 860 | /* Swap two sets so that name/index points to the other. | 886 | /* Swap two sets so that name/index points to the other. |
| 861 | * References and set names are also swapped. | 887 | * References and set names are also swapped. |
| 862 | * | 888 | * |
| 863 | * We are protected by the nfnl mutex and references are | 889 | * The commands are serialized by the nfnl mutex and references are |
| 864 | * manipulated only by holding the mutex. The kernel interfaces | 890 | * protected by the ip_set_ref_lock. The kernel interfaces |
| 865 | * do not hold the mutex but the pointer settings are atomic | 891 | * do not hold the mutex but the pointer settings are atomic |
| 866 | * so the ip_set_list always contains valid pointers to the sets. | 892 | * so the ip_set_list always contains valid pointers to the sets. |
| 867 | */ | 893 | */ |
| @@ -874,7 +900,6 @@ ip_set_swap(struct sock *ctnl, struct sk_buff *skb, | |||
| 874 | struct ip_set *from, *to; | 900 | struct ip_set *from, *to; |
| 875 | ip_set_id_t from_id, to_id; | 901 | ip_set_id_t from_id, to_id; |
| 876 | char from_name[IPSET_MAXNAMELEN]; | 902 | char from_name[IPSET_MAXNAMELEN]; |
| 877 | u32 from_ref; | ||
| 878 | 903 | ||
| 879 | if (unlikely(protocol_failed(attr) || | 904 | if (unlikely(protocol_failed(attr) || |
| 880 | attr[IPSET_ATTR_SETNAME] == NULL || | 905 | attr[IPSET_ATTR_SETNAME] == NULL || |
| @@ -899,17 +924,15 @@ ip_set_swap(struct sock *ctnl, struct sk_buff *skb, | |||
| 899 | from->type->family == to->type->family)) | 924 | from->type->family == to->type->family)) |
| 900 | return -IPSET_ERR_TYPE_MISMATCH; | 925 | return -IPSET_ERR_TYPE_MISMATCH; |
| 901 | 926 | ||
| 902 | /* No magic here: ref munging protected by the nfnl_lock */ | ||
| 903 | strncpy(from_name, from->name, IPSET_MAXNAMELEN); | 927 | strncpy(from_name, from->name, IPSET_MAXNAMELEN); |
| 904 | from_ref = atomic_read(&from->ref); | ||
| 905 | |||
| 906 | strncpy(from->name, to->name, IPSET_MAXNAMELEN); | 928 | strncpy(from->name, to->name, IPSET_MAXNAMELEN); |
| 907 | atomic_set(&from->ref, atomic_read(&to->ref)); | ||
| 908 | strncpy(to->name, from_name, IPSET_MAXNAMELEN); | 929 | strncpy(to->name, from_name, IPSET_MAXNAMELEN); |
| 909 | atomic_set(&to->ref, from_ref); | ||
| 910 | 930 | ||
| 931 | write_lock_bh(&ip_set_ref_lock); | ||
| 932 | swap(from->ref, to->ref); | ||
| 911 | ip_set_list[from_id] = to; | 933 | ip_set_list[from_id] = to; |
| 912 | ip_set_list[to_id] = from; | 934 | ip_set_list[to_id] = from; |
| 935 | write_unlock_bh(&ip_set_ref_lock); | ||
| 913 | 936 | ||
| 914 | return 0; | 937 | return 0; |
| 915 | } | 938 | } |
| @@ -926,7 +949,7 @@ ip_set_dump_done(struct netlink_callback *cb) | |||
| 926 | { | 949 | { |
| 927 | if (cb->args[2]) { | 950 | if (cb->args[2]) { |
| 928 | pr_debug("release set %s\n", ip_set_list[cb->args[1]]->name); | 951 | pr_debug("release set %s\n", ip_set_list[cb->args[1]]->name); |
| 929 | __ip_set_put((ip_set_id_t) cb->args[1]); | 952 | ip_set_put_byindex((ip_set_id_t) cb->args[1]); |
| 930 | } | 953 | } |
| 931 | return 0; | 954 | return 0; |
| 932 | } | 955 | } |
| @@ -999,8 +1022,9 @@ ip_set_dump_start(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 999 | if (cb->args[1] >= ip_set_max) | 1022 | if (cb->args[1] >= ip_set_max) |
| 1000 | goto out; | 1023 | goto out; |
| 1001 | 1024 | ||
| 1002 | pr_debug("args[0]: %ld args[1]: %ld\n", cb->args[0], cb->args[1]); | ||
| 1003 | max = cb->args[0] == DUMP_ONE ? cb->args[1] + 1 : ip_set_max; | 1025 | max = cb->args[0] == DUMP_ONE ? cb->args[1] + 1 : ip_set_max; |
| 1026 | dump_last: | ||
| 1027 | pr_debug("args[0]: %ld args[1]: %ld\n", cb->args[0], cb->args[1]); | ||
| 1004 | for (; cb->args[1] < max; cb->args[1]++) { | 1028 | for (; cb->args[1] < max; cb->args[1]++) { |
| 1005 | index = (ip_set_id_t) cb->args[1]; | 1029 | index = (ip_set_id_t) cb->args[1]; |
| 1006 | set = ip_set_list[index]; | 1030 | set = ip_set_list[index]; |
| @@ -1015,8 +1039,8 @@ ip_set_dump_start(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 1015 | * so that lists (unions of sets) are dumped last. | 1039 | * so that lists (unions of sets) are dumped last. |
| 1016 | */ | 1040 | */ |
| 1017 | if (cb->args[0] != DUMP_ONE && | 1041 | if (cb->args[0] != DUMP_ONE && |
| 1018 | !((cb->args[0] == DUMP_ALL) ^ | 1042 | ((cb->args[0] == DUMP_ALL) == |
| 1019 | (set->type->features & IPSET_DUMP_LAST))) | 1043 | !!(set->type->features & IPSET_DUMP_LAST))) |
| 1020 | continue; | 1044 | continue; |
| 1021 | pr_debug("List set: %s\n", set->name); | 1045 | pr_debug("List set: %s\n", set->name); |
| 1022 | if (!cb->args[2]) { | 1046 | if (!cb->args[2]) { |
| @@ -1060,6 +1084,12 @@ ip_set_dump_start(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 1060 | goto release_refcount; | 1084 | goto release_refcount; |
| 1061 | } | 1085 | } |
| 1062 | } | 1086 | } |
| 1087 | /* If we dump all sets, continue with dumping last ones */ | ||
| 1088 | if (cb->args[0] == DUMP_ALL) { | ||
| 1089 | cb->args[0] = DUMP_LAST; | ||
| 1090 | cb->args[1] = 0; | ||
| 1091 | goto dump_last; | ||
| 1092 | } | ||
| 1063 | goto out; | 1093 | goto out; |
| 1064 | 1094 | ||
| 1065 | nla_put_failure: | 1095 | nla_put_failure: |
| @@ -1068,13 +1098,8 @@ release_refcount: | |||
| 1068 | /* If there was an error or set is done, release set */ | 1098 | /* If there was an error or set is done, release set */ |
| 1069 | if (ret || !cb->args[2]) { | 1099 | if (ret || !cb->args[2]) { |
| 1070 | pr_debug("release set %s\n", ip_set_list[index]->name); | 1100 | pr_debug("release set %s\n", ip_set_list[index]->name); |
| 1071 | __ip_set_put(index); | 1101 | ip_set_put_byindex(index); |
| 1072 | } | 1102 | } |
| 1073 | |||
| 1074 | /* If we dump all sets, continue with dumping last ones */ | ||
| 1075 | if (cb->args[0] == DUMP_ALL && cb->args[1] >= max && !cb->args[2]) | ||
| 1076 | cb->args[0] = DUMP_LAST; | ||
| 1077 | |||
| 1078 | out: | 1103 | out: |
| 1079 | if (nlh) { | 1104 | if (nlh) { |
| 1080 | nlmsg_end(skb, nlh); | 1105 | nlmsg_end(skb, nlh); |
diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c index a47c32982f06..e9159e99fc4b 100644 --- a/net/netfilter/ipset/ip_set_list_set.c +++ b/net/netfilter/ipset/ip_set_list_set.c | |||
| @@ -43,14 +43,19 @@ struct list_set { | |||
| 43 | static inline struct set_elem * | 43 | static inline struct set_elem * |
| 44 | list_set_elem(const struct list_set *map, u32 id) | 44 | list_set_elem(const struct list_set *map, u32 id) |
| 45 | { | 45 | { |
| 46 | return (struct set_elem *)((char *)map->members + id * map->dsize); | 46 | return (struct set_elem *)((void *)map->members + id * map->dsize); |
| 47 | } | ||
| 48 | |||
| 49 | static inline struct set_telem * | ||
| 50 | list_set_telem(const struct list_set *map, u32 id) | ||
| 51 | { | ||
| 52 | return (struct set_telem *)((void *)map->members + id * map->dsize); | ||
| 47 | } | 53 | } |
| 48 | 54 | ||
| 49 | static inline bool | 55 | static inline bool |
| 50 | list_set_timeout(const struct list_set *map, u32 id) | 56 | list_set_timeout(const struct list_set *map, u32 id) |
| 51 | { | 57 | { |
| 52 | const struct set_telem *elem = | 58 | const struct set_telem *elem = list_set_telem(map, id); |
| 53 | (const struct set_telem *) list_set_elem(map, id); | ||
| 54 | 59 | ||
| 55 | return ip_set_timeout_test(elem->timeout); | 60 | return ip_set_timeout_test(elem->timeout); |
| 56 | } | 61 | } |
| @@ -58,19 +63,11 @@ list_set_timeout(const struct list_set *map, u32 id) | |||
| 58 | static inline bool | 63 | static inline bool |
| 59 | list_set_expired(const struct list_set *map, u32 id) | 64 | list_set_expired(const struct list_set *map, u32 id) |
| 60 | { | 65 | { |
| 61 | const struct set_telem *elem = | 66 | const struct set_telem *elem = list_set_telem(map, id); |
| 62 | (const struct set_telem *) list_set_elem(map, id); | ||
| 63 | 67 | ||
| 64 | return ip_set_timeout_expired(elem->timeout); | 68 | return ip_set_timeout_expired(elem->timeout); |
| 65 | } | 69 | } |
| 66 | 70 | ||
| 67 | static inline int | ||
| 68 | list_set_exist(const struct set_telem *elem) | ||
| 69 | { | ||
| 70 | return elem->id != IPSET_INVALID_ID && | ||
| 71 | !ip_set_timeout_expired(elem->timeout); | ||
| 72 | } | ||
| 73 | |||
| 74 | /* Set list without and with timeout */ | 71 | /* Set list without and with timeout */ |
| 75 | 72 | ||
| 76 | static int | 73 | static int |
| @@ -146,11 +143,11 @@ list_elem_tadd(struct list_set *map, u32 i, ip_set_id_t id, | |||
| 146 | struct set_telem *e; | 143 | struct set_telem *e; |
| 147 | 144 | ||
| 148 | for (; i < map->size; i++) { | 145 | for (; i < map->size; i++) { |
| 149 | e = (struct set_telem *)list_set_elem(map, i); | 146 | e = list_set_telem(map, i); |
| 150 | swap(e->id, id); | 147 | swap(e->id, id); |
| 148 | swap(e->timeout, timeout); | ||
| 151 | if (e->id == IPSET_INVALID_ID) | 149 | if (e->id == IPSET_INVALID_ID) |
| 152 | break; | 150 | break; |
| 153 | swap(e->timeout, timeout); | ||
| 154 | } | 151 | } |
| 155 | } | 152 | } |
| 156 | 153 | ||
| @@ -164,7 +161,7 @@ list_set_add(struct list_set *map, u32 i, ip_set_id_t id, | |||
| 164 | /* Last element replaced: e.g. add new,before,last */ | 161 | /* Last element replaced: e.g. add new,before,last */ |
| 165 | ip_set_put_byindex(e->id); | 162 | ip_set_put_byindex(e->id); |
| 166 | if (with_timeout(map->timeout)) | 163 | if (with_timeout(map->timeout)) |
| 167 | list_elem_tadd(map, i, id, timeout); | 164 | list_elem_tadd(map, i, id, ip_set_timeout_set(timeout)); |
| 168 | else | 165 | else |
| 169 | list_elem_add(map, i, id); | 166 | list_elem_add(map, i, id); |
| 170 | 167 | ||
| @@ -172,11 +169,11 @@ list_set_add(struct list_set *map, u32 i, ip_set_id_t id, | |||
| 172 | } | 169 | } |
| 173 | 170 | ||
| 174 | static int | 171 | static int |
| 175 | list_set_del(struct list_set *map, ip_set_id_t id, u32 i) | 172 | list_set_del(struct list_set *map, u32 i) |
| 176 | { | 173 | { |
| 177 | struct set_elem *a = list_set_elem(map, i), *b; | 174 | struct set_elem *a = list_set_elem(map, i), *b; |
| 178 | 175 | ||
| 179 | ip_set_put_byindex(id); | 176 | ip_set_put_byindex(a->id); |
| 180 | 177 | ||
| 181 | for (; i < map->size - 1; i++) { | 178 | for (; i < map->size - 1; i++) { |
| 182 | b = list_set_elem(map, i + 1); | 179 | b = list_set_elem(map, i + 1); |
| @@ -308,11 +305,11 @@ list_set_uadt(struct ip_set *set, struct nlattr *tb[], | |||
| 308 | (before == 0 || | 305 | (before == 0 || |
| 309 | (before > 0 && | 306 | (before > 0 && |
| 310 | next_id_eq(map, i, refid)))) | 307 | next_id_eq(map, i, refid)))) |
| 311 | ret = list_set_del(map, id, i); | 308 | ret = list_set_del(map, i); |
| 312 | else if (before < 0 && | 309 | else if (before < 0 && |
| 313 | elem->id == refid && | 310 | elem->id == refid && |
| 314 | next_id_eq(map, i, id)) | 311 | next_id_eq(map, i, id)) |
| 315 | ret = list_set_del(map, id, i + 1); | 312 | ret = list_set_del(map, i + 1); |
| 316 | } | 313 | } |
| 317 | break; | 314 | break; |
| 318 | default: | 315 | default: |
| @@ -369,8 +366,7 @@ list_set_head(struct ip_set *set, struct sk_buff *skb) | |||
| 369 | NLA_PUT_NET32(skb, IPSET_ATTR_SIZE, htonl(map->size)); | 366 | NLA_PUT_NET32(skb, IPSET_ATTR_SIZE, htonl(map->size)); |
| 370 | if (with_timeout(map->timeout)) | 367 | if (with_timeout(map->timeout)) |
| 371 | NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout)); | 368 | NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout)); |
| 372 | NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, | 369 | NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)); |
| 373 | htonl(atomic_read(&set->ref) - 1)); | ||
| 374 | NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE, | 370 | NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE, |
| 375 | htonl(sizeof(*map) + map->size * map->dsize)); | 371 | htonl(sizeof(*map) + map->size * map->dsize)); |
| 376 | ipset_nest_end(skb, nested); | 372 | ipset_nest_end(skb, nested); |
| @@ -461,16 +457,13 @@ list_set_gc(unsigned long ul_set) | |||
| 461 | struct set_telem *e; | 457 | struct set_telem *e; |
| 462 | u32 i; | 458 | u32 i; |
| 463 | 459 | ||
| 464 | /* We run parallel with other readers (test element) | 460 | write_lock_bh(&set->lock); |
| 465 | * but adding/deleting new entries is locked out */ | 461 | for (i = 0; i < map->size; i++) { |
| 466 | read_lock_bh(&set->lock); | 462 | e = list_set_telem(map, i); |
| 467 | for (i = map->size - 1; i >= 0; i--) { | 463 | if (e->id != IPSET_INVALID_ID && list_set_expired(map, i)) |
| 468 | e = (struct set_telem *) list_set_elem(map, i); | 464 | list_set_del(map, i); |
| 469 | if (e->id != IPSET_INVALID_ID && | ||
| 470 | list_set_expired(map, i)) | ||
| 471 | list_set_del(map, e->id, i); | ||
| 472 | } | 465 | } |
| 473 | read_unlock_bh(&set->lock); | 466 | write_unlock_bh(&set->lock); |
| 474 | 467 | ||
| 475 | map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ; | 468 | map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ; |
| 476 | add_timer(&map->gc); | 469 | add_timer(&map->gc); |
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index 33733c8872e7..ae47090bf45f 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c | |||
| @@ -3120,7 +3120,7 @@ nla_put_failure: | |||
| 3120 | static int ip_vs_genl_dump_daemons(struct sk_buff *skb, | 3120 | static int ip_vs_genl_dump_daemons(struct sk_buff *skb, |
| 3121 | struct netlink_callback *cb) | 3121 | struct netlink_callback *cb) |
| 3122 | { | 3122 | { |
| 3123 | struct net *net = skb_net(skb); | 3123 | struct net *net = skb_sknet(skb); |
| 3124 | struct netns_ipvs *ipvs = net_ipvs(net); | 3124 | struct netns_ipvs *ipvs = net_ipvs(net); |
| 3125 | 3125 | ||
| 3126 | mutex_lock(&__ip_vs_mutex); | 3126 | mutex_lock(&__ip_vs_mutex); |
diff --git a/net/netfilter/nf_conntrack_h323_asn1.c b/net/netfilter/nf_conntrack_h323_asn1.c index 867882313e49..bcd5ed6b7130 100644 --- a/net/netfilter/nf_conntrack_h323_asn1.c +++ b/net/netfilter/nf_conntrack_h323_asn1.c | |||
| @@ -631,7 +631,7 @@ static int decode_seqof(bitstr_t *bs, const struct field_t *f, | |||
| 631 | CHECK_BOUND(bs, 2); | 631 | CHECK_BOUND(bs, 2); |
| 632 | count = *bs->cur++; | 632 | count = *bs->cur++; |
| 633 | count <<= 8; | 633 | count <<= 8; |
| 634 | count = *bs->cur++; | 634 | count += *bs->cur++; |
| 635 | break; | 635 | break; |
| 636 | case SEMI: | 636 | case SEMI: |
| 637 | BYTE_ALIGN(bs); | 637 | BYTE_ALIGN(bs); |
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c index 533a183e6661..18b2ce5c8ced 100644 --- a/net/netfilter/nf_conntrack_h323_main.c +++ b/net/netfilter/nf_conntrack_h323_main.c | |||
| @@ -731,10 +731,10 @@ static int callforward_do_filter(const union nf_inet_addr *src, | |||
| 731 | 731 | ||
| 732 | memset(&fl2, 0, sizeof(fl2)); | 732 | memset(&fl2, 0, sizeof(fl2)); |
| 733 | fl2.daddr = dst->ip; | 733 | fl2.daddr = dst->ip; |
| 734 | if (!afinfo->route((struct dst_entry **)&rt1, | 734 | if (!afinfo->route(&init_net, (struct dst_entry **)&rt1, |
| 735 | flowi4_to_flowi(&fl1))) { | 735 | flowi4_to_flowi(&fl1), false)) { |
| 736 | if (!afinfo->route((struct dst_entry **)&rt2, | 736 | if (!afinfo->route(&init_net, (struct dst_entry **)&rt2, |
| 737 | flowi4_to_flowi(&fl2))) { | 737 | flowi4_to_flowi(&fl2), false)) { |
| 738 | if (rt1->rt_gateway == rt2->rt_gateway && | 738 | if (rt1->rt_gateway == rt2->rt_gateway && |
| 739 | rt1->dst.dev == rt2->dst.dev) | 739 | rt1->dst.dev == rt2->dst.dev) |
| 740 | ret = 1; | 740 | ret = 1; |
| @@ -755,10 +755,10 @@ static int callforward_do_filter(const union nf_inet_addr *src, | |||
| 755 | 755 | ||
| 756 | memset(&fl2, 0, sizeof(fl2)); | 756 | memset(&fl2, 0, sizeof(fl2)); |
| 757 | ipv6_addr_copy(&fl2.daddr, &dst->in6); | 757 | ipv6_addr_copy(&fl2.daddr, &dst->in6); |
| 758 | if (!afinfo->route((struct dst_entry **)&rt1, | 758 | if (!afinfo->route(&init_net, (struct dst_entry **)&rt1, |
| 759 | flowi6_to_flowi(&fl1))) { | 759 | flowi6_to_flowi(&fl1), false)) { |
| 760 | if (!afinfo->route((struct dst_entry **)&rt2, | 760 | if (!afinfo->route(&init_net, (struct dst_entry **)&rt2, |
| 761 | flowi6_to_flowi(&fl2))) { | 761 | flowi6_to_flowi(&fl2), false)) { |
| 762 | if (!memcmp(&rt1->rt6i_gateway, &rt2->rt6i_gateway, | 762 | if (!memcmp(&rt1->rt6i_gateway, &rt2->rt6i_gateway, |
| 763 | sizeof(rt1->rt6i_gateway)) && | 763 | sizeof(rt1->rt6i_gateway)) && |
| 764 | rt1->dst.dev == rt2->dst.dev) | 764 | rt1->dst.dev == rt2->dst.dev) |
diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c index 6e6b46cb1db9..9e63b43faeed 100644 --- a/net/netfilter/xt_TCPMSS.c +++ b/net/netfilter/xt_TCPMSS.c | |||
| @@ -166,7 +166,7 @@ static u_int32_t tcpmss_reverse_mtu(const struct sk_buff *skb, | |||
| 166 | rcu_read_lock(); | 166 | rcu_read_lock(); |
| 167 | ai = nf_get_afinfo(family); | 167 | ai = nf_get_afinfo(family); |
| 168 | if (ai != NULL) | 168 | if (ai != NULL) |
| 169 | ai->route((struct dst_entry **)&rt, &fl); | 169 | ai->route(&init_net, (struct dst_entry **)&rt, &fl, false); |
| 170 | rcu_read_unlock(); | 170 | rcu_read_unlock(); |
| 171 | 171 | ||
| 172 | if (rt != NULL) { | 172 | if (rt != NULL) { |
diff --git a/net/netfilter/xt_addrtype.c b/net/netfilter/xt_addrtype.c index 2220b85e9519..b77d383cec78 100644 --- a/net/netfilter/xt_addrtype.c +++ b/net/netfilter/xt_addrtype.c | |||
| @@ -32,11 +32,32 @@ MODULE_ALIAS("ipt_addrtype"); | |||
| 32 | MODULE_ALIAS("ip6t_addrtype"); | 32 | MODULE_ALIAS("ip6t_addrtype"); |
| 33 | 33 | ||
| 34 | #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) | 34 | #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) |
| 35 | static u32 xt_addrtype_rt6_to_type(const struct rt6_info *rt) | 35 | static u32 match_lookup_rt6(struct net *net, const struct net_device *dev, |
| 36 | const struct in6_addr *addr) | ||
| 36 | { | 37 | { |
| 38 | const struct nf_afinfo *afinfo; | ||
| 39 | struct flowi6 flow; | ||
| 40 | struct rt6_info *rt; | ||
| 37 | u32 ret; | 41 | u32 ret; |
| 42 | int route_err; | ||
| 38 | 43 | ||
| 39 | if (!rt) | 44 | memset(&flow, 0, sizeof(flow)); |
| 45 | ipv6_addr_copy(&flow.daddr, addr); | ||
| 46 | if (dev) | ||
| 47 | flow.flowi6_oif = dev->ifindex; | ||
| 48 | |||
| 49 | rcu_read_lock(); | ||
| 50 | |||
| 51 | afinfo = nf_get_afinfo(NFPROTO_IPV6); | ||
| 52 | if (afinfo != NULL) | ||
| 53 | route_err = afinfo->route(net, (struct dst_entry **)&rt, | ||
| 54 | flowi6_to_flowi(&flow), !!dev); | ||
| 55 | else | ||
| 56 | route_err = 1; | ||
| 57 | |||
| 58 | rcu_read_unlock(); | ||
| 59 | |||
| 60 | if (route_err) | ||
| 40 | return XT_ADDRTYPE_UNREACHABLE; | 61 | return XT_ADDRTYPE_UNREACHABLE; |
| 41 | 62 | ||
| 42 | if (rt->rt6i_flags & RTF_REJECT) | 63 | if (rt->rt6i_flags & RTF_REJECT) |
| @@ -48,6 +69,9 @@ static u32 xt_addrtype_rt6_to_type(const struct rt6_info *rt) | |||
| 48 | ret |= XT_ADDRTYPE_LOCAL; | 69 | ret |= XT_ADDRTYPE_LOCAL; |
| 49 | if (rt->rt6i_flags & RTF_ANYCAST) | 70 | if (rt->rt6i_flags & RTF_ANYCAST) |
| 50 | ret |= XT_ADDRTYPE_ANYCAST; | 71 | ret |= XT_ADDRTYPE_ANYCAST; |
| 72 | |||
| 73 | |||
| 74 | dst_release(&rt->dst); | ||
| 51 | return ret; | 75 | return ret; |
| 52 | } | 76 | } |
| 53 | 77 | ||
| @@ -65,18 +89,8 @@ static bool match_type6(struct net *net, const struct net_device *dev, | |||
| 65 | return false; | 89 | return false; |
| 66 | 90 | ||
| 67 | if ((XT_ADDRTYPE_LOCAL | XT_ADDRTYPE_ANYCAST | | 91 | if ((XT_ADDRTYPE_LOCAL | XT_ADDRTYPE_ANYCAST | |
| 68 | XT_ADDRTYPE_UNREACHABLE) & mask) { | 92 | XT_ADDRTYPE_UNREACHABLE) & mask) |
| 69 | struct rt6_info *rt; | 93 | return !!(mask & match_lookup_rt6(net, dev, addr)); |
| 70 | u32 type; | ||
| 71 | int ifindex = dev ? dev->ifindex : 0; | ||
| 72 | |||
| 73 | rt = rt6_lookup(net, addr, NULL, ifindex, !!dev); | ||
| 74 | |||
| 75 | type = xt_addrtype_rt6_to_type(rt); | ||
| 76 | |||
| 77 | dst_release(&rt->dst); | ||
| 78 | return !!(mask & type); | ||
| 79 | } | ||
| 80 | return true; | 94 | return true; |
| 81 | } | 95 | } |
| 82 | 96 | ||
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c index 2c0086a4751e..481a86fdc409 100644 --- a/net/netfilter/xt_conntrack.c +++ b/net/netfilter/xt_conntrack.c | |||
| @@ -195,7 +195,7 @@ conntrack_mt(const struct sk_buff *skb, struct xt_action_param *par, | |||
| 195 | return info->match_flags & XT_CONNTRACK_STATE; | 195 | return info->match_flags & XT_CONNTRACK_STATE; |
| 196 | if ((info->match_flags & XT_CONNTRACK_DIRECTION) && | 196 | if ((info->match_flags & XT_CONNTRACK_DIRECTION) && |
| 197 | (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) ^ | 197 | (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) ^ |
| 198 | !!(info->invert_flags & XT_CONNTRACK_DIRECTION)) | 198 | !(info->invert_flags & XT_CONNTRACK_DIRECTION)) |
| 199 | return false; | 199 | return false; |
| 200 | 200 | ||
| 201 | if (info->match_flags & XT_CONNTRACK_ORIGSRC) | 201 | if (info->match_flags & XT_CONNTRACK_ORIGSRC) |
diff --git a/net/netfilter/xt_set.c b/net/netfilter/xt_set.c index 061d48cec137..b3babaed7719 100644 --- a/net/netfilter/xt_set.c +++ b/net/netfilter/xt_set.c | |||
| @@ -81,6 +81,7 @@ set_match_v0_checkentry(const struct xt_mtchk_param *par) | |||
| 81 | if (info->match_set.u.flags[IPSET_DIM_MAX-1] != 0) { | 81 | if (info->match_set.u.flags[IPSET_DIM_MAX-1] != 0) { |
| 82 | pr_warning("Protocol error: set match dimension " | 82 | pr_warning("Protocol error: set match dimension " |
| 83 | "is over the limit!\n"); | 83 | "is over the limit!\n"); |
| 84 | ip_set_nfnl_put(info->match_set.index); | ||
| 84 | return -ERANGE; | 85 | return -ERANGE; |
| 85 | } | 86 | } |
| 86 | 87 | ||
| @@ -135,6 +136,8 @@ set_target_v0_checkentry(const struct xt_tgchk_param *par) | |||
| 135 | if (index == IPSET_INVALID_ID) { | 136 | if (index == IPSET_INVALID_ID) { |
| 136 | pr_warning("Cannot find del_set index %u as target\n", | 137 | pr_warning("Cannot find del_set index %u as target\n", |
| 137 | info->del_set.index); | 138 | info->del_set.index); |
| 139 | if (info->add_set.index != IPSET_INVALID_ID) | ||
| 140 | ip_set_nfnl_put(info->add_set.index); | ||
| 138 | return -ENOENT; | 141 | return -ENOENT; |
| 139 | } | 142 | } |
| 140 | } | 143 | } |
| @@ -142,6 +145,10 @@ set_target_v0_checkentry(const struct xt_tgchk_param *par) | |||
| 142 | info->del_set.u.flags[IPSET_DIM_MAX-1] != 0) { | 145 | info->del_set.u.flags[IPSET_DIM_MAX-1] != 0) { |
| 143 | pr_warning("Protocol error: SET target dimension " | 146 | pr_warning("Protocol error: SET target dimension " |
| 144 | "is over the limit!\n"); | 147 | "is over the limit!\n"); |
| 148 | if (info->add_set.index != IPSET_INVALID_ID) | ||
| 149 | ip_set_nfnl_put(info->add_set.index); | ||
| 150 | if (info->del_set.index != IPSET_INVALID_ID) | ||
| 151 | ip_set_nfnl_put(info->del_set.index); | ||
| 145 | return -ERANGE; | 152 | return -ERANGE; |
| 146 | } | 153 | } |
| 147 | 154 | ||
| @@ -192,6 +199,7 @@ set_match_checkentry(const struct xt_mtchk_param *par) | |||
| 192 | if (info->match_set.dim > IPSET_DIM_MAX) { | 199 | if (info->match_set.dim > IPSET_DIM_MAX) { |
| 193 | pr_warning("Protocol error: set match dimension " | 200 | pr_warning("Protocol error: set match dimension " |
| 194 | "is over the limit!\n"); | 201 | "is over the limit!\n"); |
| 202 | ip_set_nfnl_put(info->match_set.index); | ||
| 195 | return -ERANGE; | 203 | return -ERANGE; |
| 196 | } | 204 | } |
| 197 | 205 | ||
| @@ -219,7 +227,7 @@ set_target(struct sk_buff *skb, const struct xt_action_param *par) | |||
| 219 | if (info->del_set.index != IPSET_INVALID_ID) | 227 | if (info->del_set.index != IPSET_INVALID_ID) |
| 220 | ip_set_del(info->del_set.index, | 228 | ip_set_del(info->del_set.index, |
| 221 | skb, par->family, | 229 | skb, par->family, |
| 222 | info->add_set.dim, | 230 | info->del_set.dim, |
| 223 | info->del_set.flags); | 231 | info->del_set.flags); |
| 224 | 232 | ||
| 225 | return XT_CONTINUE; | 233 | return XT_CONTINUE; |
| @@ -245,13 +253,19 @@ set_target_checkentry(const struct xt_tgchk_param *par) | |||
| 245 | if (index == IPSET_INVALID_ID) { | 253 | if (index == IPSET_INVALID_ID) { |
| 246 | pr_warning("Cannot find del_set index %u as target\n", | 254 | pr_warning("Cannot find del_set index %u as target\n", |
| 247 | info->del_set.index); | 255 | info->del_set.index); |
| 256 | if (info->add_set.index != IPSET_INVALID_ID) | ||
| 257 | ip_set_nfnl_put(info->add_set.index); | ||
| 248 | return -ENOENT; | 258 | return -ENOENT; |
| 249 | } | 259 | } |
| 250 | } | 260 | } |
| 251 | if (info->add_set.dim > IPSET_DIM_MAX || | 261 | if (info->add_set.dim > IPSET_DIM_MAX || |
| 252 | info->del_set.flags > IPSET_DIM_MAX) { | 262 | info->del_set.dim > IPSET_DIM_MAX) { |
| 253 | pr_warning("Protocol error: SET target dimension " | 263 | pr_warning("Protocol error: SET target dimension " |
| 254 | "is over the limit!\n"); | 264 | "is over the limit!\n"); |
| 265 | if (info->add_set.index != IPSET_INVALID_ID) | ||
| 266 | ip_set_nfnl_put(info->add_set.index); | ||
| 267 | if (info->del_set.index != IPSET_INVALID_ID) | ||
| 268 | ip_set_nfnl_put(info->del_set.index); | ||
| 255 | return -ERANGE; | 269 | return -ERANGE; |
| 256 | } | 270 | } |
| 257 | 271 | ||
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 0698cad61763..1a21c571aa03 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
| @@ -569,6 +569,8 @@ void sctp_assoc_rm_peer(struct sctp_association *asoc, | |||
| 569 | sctp_assoc_set_primary(asoc, transport); | 569 | sctp_assoc_set_primary(asoc, transport); |
| 570 | if (asoc->peer.active_path == peer) | 570 | if (asoc->peer.active_path == peer) |
| 571 | asoc->peer.active_path = transport; | 571 | asoc->peer.active_path = transport; |
| 572 | if (asoc->peer.retran_path == peer) | ||
| 573 | asoc->peer.retran_path = transport; | ||
| 572 | if (asoc->peer.last_data_from == peer) | 574 | if (asoc->peer.last_data_from == peer) |
| 573 | asoc->peer.last_data_from = transport; | 575 | asoc->peer.last_data_from = transport; |
| 574 | 576 | ||
| @@ -1323,6 +1325,8 @@ void sctp_assoc_update_retran_path(struct sctp_association *asoc) | |||
| 1323 | 1325 | ||
| 1324 | if (t) | 1326 | if (t) |
| 1325 | asoc->peer.retran_path = t; | 1327 | asoc->peer.retran_path = t; |
| 1328 | else | ||
| 1329 | t = asoc->peer.retran_path; | ||
| 1326 | 1330 | ||
| 1327 | SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_update_retran_path:association" | 1331 | SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_update_retran_path:association" |
| 1328 | " %p addr: ", | 1332 | " %p addr: ", |
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 9022f0a6503e..0a9a2ec2e469 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c | |||
| @@ -427,7 +427,7 @@ static int | |||
| 427 | context_derive_keys_rc4(struct krb5_ctx *ctx) | 427 | context_derive_keys_rc4(struct krb5_ctx *ctx) |
| 428 | { | 428 | { |
| 429 | struct crypto_hash *hmac; | 429 | struct crypto_hash *hmac; |
| 430 | static const char sigkeyconstant[] = "signaturekey"; | 430 | char sigkeyconstant[] = "signaturekey"; |
| 431 | int slen = strlen(sigkeyconstant) + 1; /* include null terminator */ | 431 | int slen = strlen(sigkeyconstant) + 1; /* include null terminator */ |
| 432 | struct hash_desc desc; | 432 | struct hash_desc desc; |
| 433 | struct scatterlist sg[1]; | 433 | struct scatterlist sg[1]; |
