diff options
author | John W. Linville <linville@tuxdriver.com> | 2010-08-16 14:40:44 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-08-16 14:40:44 -0400 |
commit | 9714d315d28aef77a097fe905b25cc273c3d72ad (patch) | |
tree | 0ae1150b0723e925785ce774c3554f29fda050f6 /net | |
parent | 84c164a34ffe67908a932a2d641ec1a80c2d5435 (diff) | |
parent | 6ccf15a1a76d2ff915cdef6ae4d12d0170087118 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6
Diffstat (limited to 'net')
-rw-r--r-- | net/9p/client.c | 393 | ||||
-rw-r--r-- | net/9p/protocol.c | 72 | ||||
-rw-r--r-- | net/atm/pppoatm.c | 2 | ||||
-rw-r--r-- | net/bluetooth/l2cap.c | 11 | ||||
-rw-r--r-- | net/core/dev.c | 7 | ||||
-rw-r--r-- | net/ipv4/tcp_input.c | 2 | ||||
-rw-r--r-- | net/ipv6/netfilter/nf_conntrack_reasm.c | 2 | ||||
-rw-r--r-- | net/irda/irnet/irnet_ppp.c | 2 | ||||
-rw-r--r-- | net/l2tp/l2tp_ppp.c | 5 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_lblc.c | 2 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_lblcr.c | 2 | ||||
-rw-r--r-- | net/rxrpc/ar-ack.c | 3 | ||||
-rw-r--r-- | net/rxrpc/ar-call.c | 6 | ||||
-rw-r--r-- | net/sched/act_nat.c | 23 | ||||
-rw-r--r-- | net/sched/cls_flow.c | 96 | ||||
-rw-r--r-- | net/sched/cls_rsvp.h | 12 | ||||
-rw-r--r-- | net/sched/sch_sfq.c | 36 | ||||
-rw-r--r-- | net/sctp/associola.c | 2 | ||||
-rw-r--r-- | net/sctp/protocol.c | 2 | ||||
-rw-r--r-- | net/sunrpc/auth.c | 2 | ||||
-rw-r--r-- | net/sunrpc/xprtsock.c | 38 | ||||
-rw-r--r-- | net/wireless/mlme.c | 8 |
22 files changed, 616 insertions, 112 deletions
diff --git a/net/9p/client.c b/net/9p/client.c index 37c8da07a80..dc6f2f26d02 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -460,7 +460,8 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req) return err; } - if (p9_is_proto_dotu(c)) + if (p9_is_proto_dotu(c) || + p9_is_proto_dotl(c)) err = -ecode; if (!err || !IS_ERR_VALUE(err)) @@ -1015,14 +1016,18 @@ int p9_client_open(struct p9_fid *fid, int mode) struct p9_qid qid; int iounit; - P9_DPRINTK(P9_DEBUG_9P, ">>> TOPEN fid %d mode %d\n", fid->fid, mode); - err = 0; clnt = fid->clnt; + P9_DPRINTK(P9_DEBUG_9P, ">>> %s fid %d mode %d\n", + p9_is_proto_dotl(clnt) ? "TLOPEN" : "TOPEN", fid->fid, mode); + err = 0; if (fid->mode != -1) return -EINVAL; - req = p9_client_rpc(clnt, P9_TOPEN, "db", fid->fid, mode); + if (p9_is_proto_dotl(clnt)) + req = p9_client_rpc(clnt, P9_TLOPEN, "dd", fid->fid, mode); + else + req = p9_client_rpc(clnt, P9_TOPEN, "db", fid->fid, mode); if (IS_ERR(req)) { err = PTR_ERR(req); goto error; @@ -1034,10 +1039,9 @@ int p9_client_open(struct p9_fid *fid, int mode) goto free_and_error; } - P9_DPRINTK(P9_DEBUG_9P, "<<< ROPEN qid %x.%llx.%x iounit %x\n", - qid.type, - (unsigned long long)qid.path, - qid.version, iounit); + P9_DPRINTK(P9_DEBUG_9P, "<<< %s qid %x.%llx.%x iounit %x\n", + p9_is_proto_dotl(clnt) ? "RLOPEN" : "ROPEN", qid.type, + (unsigned long long)qid.path, qid.version, iounit); fid->mode = mode; fid->iounit = iounit; @@ -1049,6 +1053,50 @@ error: } EXPORT_SYMBOL(p9_client_open); +int p9_client_create_dotl(struct p9_fid *ofid, char *name, u32 flags, u32 mode, + gid_t gid, struct p9_qid *qid) +{ + int err = 0; + struct p9_client *clnt; + struct p9_req_t *req; + int iounit; + + P9_DPRINTK(P9_DEBUG_9P, + ">>> TLCREATE fid %d name %s flags %d mode %d gid %d\n", + ofid->fid, name, flags, mode, gid); + clnt = ofid->clnt; + + if (ofid->mode != -1) + return -EINVAL; + + req = p9_client_rpc(clnt, P9_TLCREATE, "dsddd", ofid->fid, name, flags, + mode, gid); + if (IS_ERR(req)) { + err = PTR_ERR(req); + goto error; + } + + err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", qid, &iounit); + if (err) { + p9pdu_dump(1, req->rc); + goto free_and_error; + } + + P9_DPRINTK(P9_DEBUG_9P, "<<< RLCREATE qid %x.%llx.%x iounit %x\n", + qid->type, + (unsigned long long)qid->path, + qid->version, iounit); + + ofid->mode = mode; + ofid->iounit = iounit; + +free_and_error: + p9_free_req(clnt, req); +error: + return err; +} +EXPORT_SYMBOL(p9_client_create_dotl); + int p9_client_fcreate(struct p9_fid *fid, char *name, u32 perm, int mode, char *extension) { @@ -1094,6 +1142,59 @@ error: } EXPORT_SYMBOL(p9_client_fcreate); +int p9_client_symlink(struct p9_fid *dfid, char *name, char *symtgt, gid_t gid, + struct p9_qid *qid) +{ + int err = 0; + struct p9_client *clnt; + struct p9_req_t *req; + + P9_DPRINTK(P9_DEBUG_9P, ">>> TSYMLINK dfid %d name %s symtgt %s\n", + dfid->fid, name, symtgt); + clnt = dfid->clnt; + + req = p9_client_rpc(clnt, P9_TSYMLINK, "dssd", dfid->fid, name, symtgt, + gid); + if (IS_ERR(req)) { + err = PTR_ERR(req); + goto error; + } + + err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid); + if (err) { + p9pdu_dump(1, req->rc); + goto free_and_error; + } + + P9_DPRINTK(P9_DEBUG_9P, "<<< RSYMLINK qid %x.%llx.%x\n", + qid->type, (unsigned long long)qid->path, qid->version); + +free_and_error: + p9_free_req(clnt, req); +error: + return err; +} +EXPORT_SYMBOL(p9_client_symlink); + +int p9_client_link(struct p9_fid *dfid, struct p9_fid *oldfid, char *newname) +{ + struct p9_client *clnt; + struct p9_req_t *req; + + P9_DPRINTK(P9_DEBUG_9P, ">>> TLINK dfid %d oldfid %d newname %s\n", + dfid->fid, oldfid->fid, newname); + clnt = dfid->clnt; + req = p9_client_rpc(clnt, P9_TLINK, "dds", dfid->fid, oldfid->fid, + newname); + if (IS_ERR(req)) + return PTR_ERR(req); + + P9_DPRINTK(P9_DEBUG_9P, "<<< RLINK\n"); + p9_free_req(clnt, req); + return 0; +} +EXPORT_SYMBOL(p9_client_link); + int p9_client_clunk(struct p9_fid *fid) { int err; @@ -1139,9 +1240,8 @@ int p9_client_remove(struct p9_fid *fid) P9_DPRINTK(P9_DEBUG_9P, "<<< RREMOVE fid %d\n", fid->fid); p9_free_req(clnt, req); - p9_fid_destroy(fid); - error: + p9_fid_destroy(fid); return err; } EXPORT_SYMBOL(p9_client_remove); @@ -1302,6 +1402,65 @@ error: } EXPORT_SYMBOL(p9_client_stat); +struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid, + u64 request_mask) +{ + int err; + struct p9_client *clnt; + struct p9_stat_dotl *ret = kmalloc(sizeof(struct p9_stat_dotl), + GFP_KERNEL); + struct p9_req_t *req; + + P9_DPRINTK(P9_DEBUG_9P, ">>> TGETATTR fid %d, request_mask %lld\n", + fid->fid, request_mask); + + if (!ret) + return ERR_PTR(-ENOMEM); + + err = 0; + clnt = fid->clnt; + + req = p9_client_rpc(clnt, P9_TGETATTR, "dq", fid->fid, request_mask); + if (IS_ERR(req)) { + err = PTR_ERR(req); + goto error; + } + + err = p9pdu_readf(req->rc, clnt->proto_version, "A", ret); + if (err) { + p9pdu_dump(1, req->rc); + p9_free_req(clnt, req); + goto error; + } + + P9_DPRINTK(P9_DEBUG_9P, + "<<< RGETATTR st_result_mask=%lld\n" + "<<< qid=%x.%llx.%x\n" + "<<< st_mode=%8.8x st_nlink=%llu\n" + "<<< st_uid=%d st_gid=%d\n" + "<<< st_rdev=%llx st_size=%llx st_blksize=%llu st_blocks=%llu\n" + "<<< st_atime_sec=%lld st_atime_nsec=%lld\n" + "<<< st_mtime_sec=%lld st_mtime_nsec=%lld\n" + "<<< st_ctime_sec=%lld st_ctime_nsec=%lld\n" + "<<< st_btime_sec=%lld st_btime_nsec=%lld\n" + "<<< st_gen=%lld st_data_version=%lld", + ret->st_result_mask, ret->qid.type, ret->qid.path, + ret->qid.version, ret->st_mode, ret->st_nlink, ret->st_uid, + ret->st_gid, ret->st_rdev, ret->st_size, ret->st_blksize, + ret->st_blocks, ret->st_atime_sec, ret->st_atime_nsec, + ret->st_mtime_sec, ret->st_mtime_nsec, ret->st_ctime_sec, + ret->st_ctime_nsec, ret->st_btime_sec, ret->st_btime_nsec, + ret->st_gen, ret->st_data_version); + + p9_free_req(clnt, req); + return ret; + +error: + kfree(ret); + return ERR_PTR(err); +} +EXPORT_SYMBOL(p9_client_getattr_dotl); + static int p9_client_statsize(struct p9_wstat *wst, int proto_version) { int ret; @@ -1366,6 +1525,36 @@ error: } EXPORT_SYMBOL(p9_client_wstat); +int p9_client_setattr(struct p9_fid *fid, struct p9_iattr_dotl *p9attr) +{ + int err; + struct p9_req_t *req; + struct p9_client *clnt; + + err = 0; + clnt = fid->clnt; + P9_DPRINTK(P9_DEBUG_9P, ">>> TSETATTR fid %d\n", fid->fid); + P9_DPRINTK(P9_DEBUG_9P, + " valid=%x mode=%x uid=%d gid=%d size=%lld\n" + " atime_sec=%lld atime_nsec=%lld\n" + " mtime_sec=%lld mtime_nsec=%lld\n", + p9attr->valid, p9attr->mode, p9attr->uid, p9attr->gid, + p9attr->size, p9attr->atime_sec, p9attr->atime_nsec, + p9attr->mtime_sec, p9attr->mtime_nsec); + + req = p9_client_rpc(clnt, P9_TSETATTR, "dI", fid->fid, p9attr); + + if (IS_ERR(req)) { + err = PTR_ERR(req); + goto error; + } + P9_DPRINTK(P9_DEBUG_9P, "<<< RSETATTR fid %d\n", fid->fid); + p9_free_req(clnt, req); +error: + return err; +} +EXPORT_SYMBOL(p9_client_setattr); + int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb) { int err; @@ -1432,3 +1621,187 @@ error: } EXPORT_SYMBOL(p9_client_rename); +/* + * An xattrwalk without @attr_name gives the fid for the lisxattr namespace + */ +struct p9_fid *p9_client_xattrwalk(struct p9_fid *file_fid, + const char *attr_name, u64 *attr_size) +{ + int err; + struct p9_req_t *req; + struct p9_client *clnt; + struct p9_fid *attr_fid; + + err = 0; + clnt = file_fid->clnt; + attr_fid = p9_fid_create(clnt); + if (IS_ERR(attr_fid)) { + err = PTR_ERR(attr_fid); + attr_fid = NULL; + goto error; + } + P9_DPRINTK(P9_DEBUG_9P, + ">>> TXATTRWALK file_fid %d, attr_fid %d name %s\n", + file_fid->fid, attr_fid->fid, attr_name); + + req = p9_client_rpc(clnt, P9_TXATTRWALK, "dds", + file_fid->fid, attr_fid->fid, attr_name); + if (IS_ERR(req)) { + err = PTR_ERR(req); + goto error; + } + err = p9pdu_readf(req->rc, clnt->proto_version, "q", attr_size); + if (err) { + p9pdu_dump(1, req->rc); + p9_free_req(clnt, req); + goto clunk_fid; + } + p9_free_req(clnt, req); + P9_DPRINTK(P9_DEBUG_9P, "<<< RXATTRWALK fid %d size %llu\n", + attr_fid->fid, *attr_size); + return attr_fid; +clunk_fid: + p9_client_clunk(attr_fid); + attr_fid = NULL; +error: + if (attr_fid && (attr_fid != file_fid)) + p9_fid_destroy(attr_fid); + + return ERR_PTR(err); +} +EXPORT_SYMBOL_GPL(p9_client_xattrwalk); + +int p9_client_xattrcreate(struct p9_fid *fid, const char *name, + u64 attr_size, int flags) +{ + int err; + struct p9_req_t *req; + struct p9_client *clnt; + + P9_DPRINTK(P9_DEBUG_9P, + ">>> TXATTRCREATE fid %d name %s size %lld flag %d\n", + fid->fid, name, (long long)attr_size, flags); + err = 0; + clnt = fid->clnt; + req = p9_client_rpc(clnt, P9_TXATTRCREATE, "dsqd", + fid->fid, name, attr_size, flags); + if (IS_ERR(req)) { + err = PTR_ERR(req); + goto error; + } + P9_DPRINTK(P9_DEBUG_9P, "<<< RXATTRCREATE fid %d\n", fid->fid); + p9_free_req(clnt, req); +error: + return err; +} +EXPORT_SYMBOL_GPL(p9_client_xattrcreate); + +int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset) +{ + int err, rsize, total; + struct p9_client *clnt; + struct p9_req_t *req; + char *dataptr; + + P9_DPRINTK(P9_DEBUG_9P, ">>> TREADDIR fid %d offset %llu count %d\n", + fid->fid, (long long unsigned) offset, count); + + err = 0; + clnt = fid->clnt; + total = 0; + + rsize = fid->iounit; + if (!rsize || rsize > clnt->msize-P9_READDIRHDRSZ) + rsize = clnt->msize - P9_READDIRHDRSZ; + + if (count < rsize) + rsize = count; + + req = p9_client_rpc(clnt, P9_TREADDIR, "dqd", fid->fid, offset, rsize); + if (IS_ERR(req)) { + err = PTR_ERR(req); + goto error; + } + + err = p9pdu_readf(req->rc, clnt->proto_version, "D", &count, &dataptr); + if (err) { + p9pdu_dump(1, req->rc); + goto free_and_error; + } + + P9_DPRINTK(P9_DEBUG_9P, "<<< RREADDIR count %d\n", count); + + if (data) + memmove(data, dataptr, count); + + p9_free_req(clnt, req); + return count; + +free_and_error: + p9_free_req(clnt, req); +error: + return err; +} +EXPORT_SYMBOL(p9_client_readdir); + +int p9_client_mknod_dotl(struct p9_fid *fid, char *name, int mode, + dev_t rdev, gid_t gid, struct p9_qid *qid) +{ + int err; + struct p9_client *clnt; + struct p9_req_t *req; + + err = 0; + clnt = fid->clnt; + P9_DPRINTK(P9_DEBUG_9P, ">>> TMKNOD fid %d name %s mode %d major %d " + "minor %d\n", fid->fid, name, mode, MAJOR(rdev), MINOR(rdev)); + req = p9_client_rpc(clnt, P9_TMKNOD, "dsdddd", fid->fid, name, mode, + MAJOR(rdev), MINOR(rdev), gid); + if (IS_ERR(req)) + return PTR_ERR(req); + + err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid); + if (err) { + p9pdu_dump(1, req->rc); + goto error; + } + P9_DPRINTK(P9_DEBUG_9P, "<<< RMKNOD qid %x.%llx.%x\n", qid->type, + (unsigned long long)qid->path, qid->version); + +error: + p9_free_req(clnt, req); + return err; + +} +EXPORT_SYMBOL(p9_client_mknod_dotl); + +int p9_client_mkdir_dotl(struct p9_fid *fid, char *name, int mode, + gid_t gid, struct p9_qid *qid) +{ + int err; + struct p9_client *clnt; + struct p9_req_t *req; + + err = 0; + clnt = fid->clnt; + P9_DPRINTK(P9_DEBUG_9P, ">>> TMKDIR fid %d name %s mode %d gid %d\n", + fid->fid, name, mode, gid); + req = p9_client_rpc(clnt, P9_TMKDIR, "dsdd", fid->fid, name, mode, + gid); + if (IS_ERR(req)) + return PTR_ERR(req); + + err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid); + if (err) { + p9pdu_dump(1, req->rc); + goto error; + } + P9_DPRINTK(P9_DEBUG_9P, "<<< RMKDIR qid %x.%llx.%x\n", qid->type, + (unsigned long long)qid->path, qid->version); + +error: + p9_free_req(clnt, req); + return err; + +} +EXPORT_SYMBOL(p9_client_mkdir_dotl); diff --git a/net/9p/protocol.c b/net/9p/protocol.c index 149f8216013..3acd3afb20c 100644 --- a/net/9p/protocol.c +++ b/net/9p/protocol.c @@ -141,6 +141,7 @@ pdu_write_u(struct p9_fcall *pdu, const char __user *udata, size_t size) D - data blob (int32_t size followed by void *, results are not freed) T - array of strings (int16_t count, followed by strings) R - array of qids (int16_t count, followed by qids) + A - stat for 9p2000.L (p9_stat_dotl) ? - if optional = 1, continue parsing */ @@ -340,6 +341,33 @@ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt, } } break; + case 'A': { + struct p9_stat_dotl *stbuf = + va_arg(ap, struct p9_stat_dotl *); + + memset(stbuf, 0, sizeof(struct p9_stat_dotl)); + errcode = + p9pdu_readf(pdu, proto_version, + "qQdddqqqqqqqqqqqqqqq", + &stbuf->st_result_mask, + &stbuf->qid, + &stbuf->st_mode, + &stbuf->st_uid, &stbuf->st_gid, + &stbuf->st_nlink, + &stbuf->st_rdev, &stbuf->st_size, + &stbuf->st_blksize, &stbuf->st_blocks, + &stbuf->st_atime_sec, + &stbuf->st_atime_nsec, + &stbuf->st_mtime_sec, + &stbuf->st_mtime_nsec, + &stbuf->st_ctime_sec, + &stbuf->st_ctime_nsec, + &stbuf->st_btime_sec, + &stbuf->st_btime_nsec, + &stbuf->st_gen, + &stbuf->st_data_version); + } + break; case '?': if ((proto_version != p9_proto_2000u) && (proto_version != p9_proto_2000L)) @@ -488,6 +516,23 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt, } } break; + case 'I':{ + struct p9_iattr_dotl *p9attr = va_arg(ap, + struct p9_iattr_dotl *); + + errcode = p9pdu_writef(pdu, proto_version, + "ddddqqqqq", + p9attr->valid, + p9attr->mode, + p9attr->uid, + p9attr->gid, + p9attr->size, + p9attr->atime_sec, + p9attr->atime_nsec, + p9attr->mtime_sec, + p9attr->mtime_nsec); + } + break; case '?': if ((proto_version != p9_proto_2000u) && (proto_version != p9_proto_2000L)) @@ -580,3 +625,30 @@ void p9pdu_reset(struct p9_fcall *pdu) pdu->offset = 0; pdu->size = 0; } + +int p9dirent_read(char *buf, int len, struct p9_dirent *dirent, + int proto_version) +{ + struct p9_fcall fake_pdu; + int ret; + char *nameptr; + + fake_pdu.size = len; + fake_pdu.capacity = len; + fake_pdu.sdata = buf; + fake_pdu.offset = 0; + + ret = p9pdu_readf(&fake_pdu, proto_version, "Qqbs", &dirent->qid, + &dirent->d_off, &dirent->d_type, &nameptr); + if (ret) { + P9_DPRINTK(P9_DEBUG_9P, "<<< p9dirent_read failed: %d\n", ret); + p9pdu_dump(1, &fake_pdu); + goto out; + } + + strcpy(dirent->d_name, nameptr); + +out: + return fake_pdu.offset; +} +EXPORT_SYMBOL(p9dirent_read); diff --git a/net/atm/pppoatm.c b/net/atm/pppoatm.c index e49bb6d948a..e9aced0ec56 100644 --- a/net/atm/pppoatm.c +++ b/net/atm/pppoatm.c @@ -260,7 +260,7 @@ static int pppoatm_devppp_ioctl(struct ppp_channel *chan, unsigned int cmd, return -ENOTTY; } -static /*const*/ struct ppp_channel_ops pppoatm_ops = { +static const struct ppp_channel_ops pppoatm_ops = { .start_xmit = pppoatm_send, .ioctl = pppoatm_devppp_ioctl, }; diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 3e3cd9d4e52..fadf26b4ed7 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -2705,8 +2705,9 @@ done: case L2CAP_MODE_ERTM: pi->remote_tx_win = rfc.txwin_size; pi->remote_max_tx = rfc.max_transmit; - if (rfc.max_pdu_size > pi->conn->mtu - 10) - rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10); + + if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10) + rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10); pi->remote_mps = le16_to_cpu(rfc.max_pdu_size); @@ -2723,8 +2724,8 @@ done: break; case L2CAP_MODE_STREAMING: - if (rfc.max_pdu_size > pi->conn->mtu - 10) - rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10); + if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10) + rfc.max_pdu_size = cpu_to_le16(pi->conn->mtu - 10); pi->remote_mps = le16_to_cpu(rfc.max_pdu_size); @@ -2806,7 +2807,6 @@ static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data, if (*result == L2CAP_CONF_SUCCESS) { switch (rfc.mode) { case L2CAP_MODE_ERTM: - pi->remote_tx_win = rfc.txwin_size; pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout); pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout); pi->mps = le16_to_cpu(rfc.max_pdu_size); @@ -2862,7 +2862,6 @@ static void l2cap_conf_rfc_get(struct sock *sk, void *rsp, int len) done: switch (rfc.mode) { case L2CAP_MODE_ERTM: - pi->remote_tx_win = rfc.txwin_size; pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout); pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout); pi->mps = le16_to_cpu(rfc.max_pdu_size); diff --git a/net/core/dev.c b/net/core/dev.c index e1c1cdcc2bb..1ae65439144 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2517,6 +2517,7 @@ int netif_rx(struct sk_buff *skb) struct rps_dev_flow voidflow, *rflow = &voidflow; int cpu; + preempt_disable(); rcu_read_lock(); cpu = get_rps_cpu(skb->dev, skb, &rflow); @@ -2526,6 +2527,7 @@ int netif_rx(struct sk_buff *skb) ret = enqueue_to_backlog(skb, cpu, &rflow->last_qtail); rcu_read_unlock(); + preempt_enable(); } #else { @@ -3072,7 +3074,7 @@ enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb) int mac_len; enum gro_result ret; - if (!(skb->dev->features & NETIF_F_GRO)) + if (!(skb->dev->features & NETIF_F_GRO) || netpoll_rx_on(skb)) goto normal; if (skb_is_gso(skb) || skb_has_frags(skb)) @@ -3159,9 +3161,6 @@ __napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb) { struct sk_buff *p; - if (netpoll_rx_on(skb)) - return GRO_NORMAL; - for (p = napi->gro_list; p; p = p->next) { NAPI_GRO_CB(p)->same_flow = (p->dev == skb->dev) && diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 3c426cb318e..e663b78a2ef 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -3930,7 +3930,7 @@ u8 *tcp_parse_md5sig_option(struct tcphdr *th) if (opsize < 2 || opsize > length) return NULL; if (opcode == TCPOPT_MD5SIG) - return ptr; + return opsize == TCPOLEN_MD5SIG ? ptr : NULL; } ptr += opsize - 2; length -= opsize; diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index 098a050a20b..13ef5bc05cf 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -199,7 +199,7 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb, int offset, end; if (fq->q.last_in & INET_FRAG_COMPLETE) { - pr_debug("Allready completed\n"); + pr_debug("Already completed\n"); goto err; } diff --git a/net/irda/irnet/irnet_ppp.c b/net/irda/irnet/irnet_ppp.c index 800bc53b7f6..dfe7b38dd4a 100644 --- a/net/irda/irnet/irnet_ppp.c +++ b/net/irda/irnet/irnet_ppp.c @@ -20,7 +20,7 @@ /* Please put other headers in irnet.h - Thanks */ /* Generic PPP callbacks (to call us) */ -static struct ppp_channel_ops irnet_ppp_ops = { +static const struct ppp_channel_ops irnet_ppp_ops = { .start_xmit = ppp_irnet_send, .ioctl = ppp_irnet_ioctl }; diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c index 90d82b3f288..ff954b3e94b 100644 --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c @@ -135,7 +135,10 @@ struct pppol2tp_session { static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb); -static struct ppp_channel_ops pppol2tp_chan_ops = { pppol2tp_xmit , NULL }; +static const struct ppp_channel_ops pppol2tp_chan_ops = { + .start_xmit = pppol2tp_xmit, +}; + static const struct proto_ops pppol2tp_ops; /* Helpers to obtain tunnel/session contexts from sockets. diff --git a/net/netfilter/ipvs/ip_vs_lblc.c b/net/netfilter/ipvs/ip_vs_lblc.c index 94a45213faa..9323f894419 100644 --- a/net/netfilter/ipvs/ip_vs_lblc.c +++ b/net/netfilter/ipvs/ip_vs_lblc.c @@ -11,7 +11,7 @@ * Changes: * Martin Hamilton : fixed the terrible locking bugs * *lock(tbl->lock) ==> *lock(&tbl->lock) - * Wensong Zhang : fixed the uninitilized tbl->lock bug + * Wensong Zhang : fixed the uninitialized tbl->lock bug * Wensong Zhang : added doing full expiration check to * collect stale entries of 24+ hours when * no partial expire check in a half hour diff --git a/net/netfilter/ipvs/ip_vs_lblcr.c b/net/netfilter/ipvs/ip_vs_lblcr.c index 535dc2b419d..dbeed8ea421 100644 --- a/net/netfilter/ipvs/ip_vs_lblcr.c +++ b/net/netfilter/ipvs/ip_vs_lblcr.c @@ -386,7 +386,7 @@ ip_vs_lblcr_new(struct ip_vs_lblcr_table *tbl, const union nf_inet_addr *daddr, ip_vs_addr_copy(dest->af, &en->addr, daddr); en->lastuse = jiffies; - /* initilize its dest set */ + /* initialize its dest set */ atomic_set(&(en->set.size), 0); INIT_LIST_HEAD(&en->set.list); rwlock_init(&en->set.lock); diff --git a/net/rxrpc/ar-ack.c b/net/rxrpc/ar-ack.c index 2714da167fb..b6ffe4e1b84 100644 --- a/net/rxrpc/ar-ack.c +++ b/net/rxrpc/ar-ack.c @@ -245,6 +245,9 @@ static void rxrpc_resend_timer(struct rxrpc_call *call) _enter("%d,%d,%d", call->acks_tail, call->acks_unacked, call->acks_head); + if (call->state >= RXRPC_CALL_COMPLETE) + return; + resend = 0; resend_at = 0; diff --git a/net/rxrpc/ar-call.c b/net/rxrpc/ar-call.c index 909d092de9f..bf656c230ba 100644 --- a/net/rxrpc/ar-call.c +++ b/net/rxrpc/ar-call.c @@ -786,6 +786,7 @@ static void rxrpc_call_life_expired(unsigned long _call) /* * handle resend timer expiry + * - may not take call->state_lock as this can deadlock against del_timer_sync() */ static void rxrpc_resend_time_expired(unsigned long _call) { @@ -796,12 +797,9 @@ static void rxrpc_resend_time_expired(unsigned long _call) if (call->state >= RXRPC_CALL_COMPLETE) return; - read_lock_bh(&call->state_lock); clear_bit(RXRPC_CALL_RUN_RTIMER, &call->flags); - if (call->state < RXRPC_CALL_COMPLETE && - !test_and_set_bit(RXRPC_CALL_RESEND_TIMER, &call->events)) + if (!test_and_set_bit(RXRPC_CALL_RESEND_TIMER, &call->events)) rxrpc_queue_call(call); - read_unlock_bh(&call->state_lock); } /* diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c index d0386a413e8..509a2d53a99 100644 --- a/net/sched/act_nat.c +++ b/net/sched/act_nat.c @@ -114,6 +114,7 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, int egress; int action; int ihl; + int noff; spin_lock(&p->tcf_lock); @@ -132,7 +133,8 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, if (unlikely(action == TC_ACT_SHOT)) goto drop; - if (!pskb_may_pull(skb, sizeof(*iph))) + noff = skb_network_offset(skb); + if (!pskb_may_pull(skb, sizeof(*iph) + noff)) goto drop; iph = ip_hdr(skb); @@ -144,7 +146,7 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, if (!((old_addr ^ addr) & mask)) { if (skb_cloned(skb) && - !skb_clone_writable(skb, sizeof(*iph)) && + !skb_clone_writable(skb, sizeof(*iph) + noff) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) goto drop; @@ -172,9 +174,9 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, { struct tcphdr *tcph; - if (!pskb_may_pull(skb, ihl + sizeof(*tcph)) || + if (!pskb_may_pull(skb, ihl + sizeof(*tcph) + noff) || (skb_cloned(skb) && - !skb_clone_writable(skb, ihl + sizeof(*tcph)) && + !skb_clone_writable(skb, ihl + sizeof(*tcph) + noff) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) goto drop; @@ -186,9 +188,9 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, { struct udphdr *udph; - if (!pskb_may_pull(skb, ihl + sizeof(*udph)) || + if (!pskb_may_pull(skb, ihl + sizeof(*udph) + noff) || (skb_cloned(skb) && - !skb_clone_writable(skb, ihl + sizeof(*udph)) && + !skb_clone_writable(skb, ihl + sizeof(*udph) + noff) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) goto drop; @@ -205,7 +207,7 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, { struct icmphdr *icmph; - if (!pskb_may_pull(skb, ihl + sizeof(*icmph))) + if (!pskb_may_pull(skb, ihl + sizeof(*icmph) + noff)) goto drop; icmph = (void *)(skb_network_header(skb) + ihl); @@ -215,7 +217,8 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, (icmph->type != ICMP_PARAMETERPROB)) break; - if (!pskb_may_pull(skb, ihl + sizeof(*icmph) + sizeof(*iph))) + if (!pskb_may_pull(skb, ihl + sizeof(*icmph) + sizeof(*iph) + + noff)) goto drop; icmph = (void *)(skb_network_header(skb) + ihl); @@ -229,8 +232,8 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a, break; if (skb_cloned(skb) && - !skb_clone_writable(skb, - ihl + sizeof(*icmph) + sizeof(*iph)) && + !skb_clone_writable(skb, ihl + sizeof(*icmph) + + sizeof(*iph) + noff) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) goto drop; diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c index f73542d2cdd..e17096e3913 100644 --- a/net/sched/cls_flow.c +++ b/net/sched/cls_flow.c @@ -65,37 +65,47 @@ static inline u32 addr_fold(void *addr) return (a & 0xFFFFFFFF) ^ (BITS_PER_LONG > 32 ? a >> 32 : 0); } -static u32 flow_get_src(const struct sk_buff *skb) +static u32 flow_get_src(struct sk_buff *skb) { switch (skb->protocol) { case htons(ETH_P_IP): - return ntohl(ip_hdr(skb)->saddr); + if (pskb_network_may_pull(skb, sizeof(struct iphdr))) + return ntohl(ip_hdr(skb)->saddr); + break; case htons(ETH_P_IPV6): - return ntohl(ipv6_hdr(skb)->saddr.s6_addr32[3]); - default: - return addr_fold(skb->sk); + if (pskb_network_may_pull(skb, sizeof(struct ipv6hdr))) + return ntohl(ipv6_hdr(skb)->saddr.s6_addr32[3]); + break; } + + return addr_fold(skb->sk); } -static u32 flow_get_dst(const struct sk_buff *skb) +static u32 flow_get_dst(struct sk_buff *skb) { switch (skb->protocol) { case htons(ETH_P_IP): - return ntohl(ip_hdr(skb)->daddr); + if (pskb_network_may_pull(skb, sizeof(struct iphdr))) + return ntohl(ip_hdr(skb)->daddr); + break; case htons(ETH_P_IPV6): - return ntohl(ipv6_hdr(skb)->daddr.s6_addr32[3]); - default: - return addr_fold(skb_dst(skb)) ^ (__force u16)skb->protocol; + if (pskb_network_may_pull(skb, sizeof(struct ipv6hdr))) + return ntohl(ipv6_hdr(skb)->daddr.s6_addr32[3]); + break; } + + return addr_fold(skb_dst(skb)) ^ (__force u16)skb->protocol; } -static u32 flow_get_proto(const struct sk_buff *skb) +static u32 flow_get_proto(struct sk_buff *skb) { switch (skb->protocol) { case htons(ETH_P_IP): - return ip_hdr(skb)->protocol; + return pskb_network_may_pull(skb, sizeof(struct iphdr)) ? + ip_hdr(skb)->protocol : 0; case htons(ETH_P_IPV6): - return ipv6_hdr(skb)->nexthdr; + return pskb_network_may_pull(skb, sizeof(struct ipv6hdr)) ? + ipv6_hdr(skb)->nexthdr : 0; default: return 0; } @@ -116,58 +126,64 @@ static int has_ports(u8 protocol) } } -static u32 flow_get_proto_src(const struct sk_buff *skb) +static u32 flow_get_proto_src(struct sk_buff *skb) { - u32 res = 0; - switch (skb->protocol) { case htons(ETH_P_IP): { - struct iphdr *iph = ip_hdr(skb); + struct iphdr *iph; + if (!pskb_network_may_pull(skb, sizeof(*iph))) + break; + iph = ip_hdr(skb); if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && - has_ports(iph->protocol)) - res = ntohs(*(__be16 *)((void *)iph + iph->ihl * 4)); + has_ports(iph->protocol) && + pskb_network_may_pull(skb, iph->ihl * 4 + 2)) + return ntohs(*(__be16 *)((void *)iph + iph->ihl * 4)); break; } case htons(ETH_P_IPV6): { - struct ipv6hdr *iph = ipv6_hdr(skb); + struct ipv6hdr *iph; + if (!pskb_network_may_pull(skb, sizeof(*iph) + 2)) + break; + iph = ipv6_hdr(skb); if (has_ports(iph->nexthdr)) - res = ntohs(*(__be16 *)&iph[1]); + return ntohs(*(__be16 *)&iph[1]); break; } - default: - res = addr_fold(skb->sk); } - return res; + return addr_fold(skb->sk); } -static u32 flow_get_proto_dst(const struct sk_buff *skb) +static u32 flow_get_proto_dst(struct sk_buff *skb) { - u32 res = 0; - switch (skb->protocol) { case htons(ETH_P_IP): { - struct iphdr *iph = ip_hdr(skb); + struct iphdr *iph; + if (!pskb_network_may_pull(skb, sizeof(*iph))) + break; + iph = ip_hdr(skb); if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && - has_ports(iph->protocol)) - res = ntohs(*(__be16 *)((void *)iph + iph->ihl * 4 + 2)); + has_ports(iph->protocol) && + pskb_network_may_pull(skb, iph->ihl * 4 + 4)) + return ntohs(*(__be16 *)((void *)iph + iph->ihl * 4 + 2)); break; } case htons(ETH_P_IPV6): { - struct ipv6hdr *iph = ipv6_hdr(skb); + struct ipv6hdr *iph; + if (!pskb_network_may_pull(skb, sizeof(*iph) + 4)) + break; + iph = ipv6_hdr(skb); if (has_ports(iph->nexthdr)) - res = ntohs(*(__be16 *)((void *)&iph[1] + 2)); + return ntohs(*(__be16 *)((void *)&iph[1] + 2)); break; } - default: - res = addr_fold(skb_dst(skb)) ^ (__force u16)skb->protocol; } - return res; + return addr_fold(skb_dst(skb)) ^ (__force u16)skb->protocol; } static u32 flow_get_iif(const struct sk_buff *skb) @@ -211,7 +227,7 @@ static u32 flow_get_nfct(const struct sk_buff *skb) }) #endif -static u32 flow_get_nfct_src(const struct sk_buff *skb) +static u32 flow_get_nfct_src(struct sk_buff *skb) { switch (skb->protocol) { case htons(ETH_P_IP): @@ -223,7 +239,7 @@ fallback: return flow_get_src(skb); } -static u32 flow_get_nfct_dst(const struct sk_buff *skb) +static u32 flow_get_nfct_dst(struct sk_buff *skb) { switch (skb->protocol) { case htons(ETH_P_IP): @@ -235,14 +251,14 @@ fallback: return flow_get_dst(skb); } -static u32 flow_get_nfct_proto_src(const struct sk_buff *skb) +static u32 flow_get_nfct_proto_src(struct sk_buff *skb) { return ntohs(CTTUPLE(skb, src.u.all)); fallback: return flow_get_proto_src(skb); } -static u32 flow_get_nfct_proto_dst(const struct sk_buff *skb) +static u32 flow_get_nfct_proto_dst(struct sk_buff *skb) { return ntohs(CTTUPLE(skb, dst.u.all)); fallback: @@ -281,7 +297,7 @@ static u32 flow_get_vlan_tag(const struct sk_buff *skb) return tag & VLAN_VID_MASK; } -static u32 flow_key_get(const struct sk_buff *skb, int key) +static u32 flow_key_get(struct sk_buff *skb, int key) { switch (key) { case FLOW_KEY_SRC: diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h index dd9414e4420..425a1790b04 100644 --- a/net/sched/cls_rsvp.h +++ b/net/sched/cls_rsvp.h @@ -143,9 +143,17 @@ static int rsvp_classify(struct sk_buff *skb, struct tcf_proto *tp, u8 tunnelid = 0; u8 *xprt; #if RSVP_DST_LEN == 4 - struct ipv6hdr *nhptr = ipv6_hdr(skb); + struct ipv6hdr *nhptr; + + if (!pskb_network_may_pull(skb, sizeof(*nhptr))) + return -1; + nhptr = ipv6_hdr(skb); #else - struct iphdr *nhptr = ip_hdr(skb); + struct iphdr *nhptr; + + if (!pskb_network_may_pull(skb, sizeof(*nhptr))) + return -1; + nhptr = ip_hdr(skb); #endif restart: diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index c65762823f5..534f33231c1 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c @@ -122,7 +122,11 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb) switch (skb->protocol) { case htons(ETH_P_IP): { - const struct iphdr *iph = ip_hdr(skb); + const struct iphdr *iph; + + if (!pskb_network_may_pull(skb, sizeof(*iph))) + goto err; + iph = ip_hdr(skb); h = (__force u32)iph->daddr; h2 = (__force u32)iph->saddr ^ iph->protocol; if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && @@ -131,25 +135,32 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb) iph->protocol == IPPROTO_UDPLITE || iph->protocol == IPPROTO_SCTP || iph->protocol == IPPROTO_DCCP || - iph->protocol == IPPROTO_ESP)) + iph->protocol == IPPROTO_ESP) && + pskb_network_may_pull(skb, iph->ihl * 4 + 4)) h2 ^= *(((u32*)iph) + iph->ihl); break; } case htons(ETH_P_IPV6): { - struct ipv6hdr *iph = ipv6_hdr(skb); + struct ipv6hdr *iph; + + if (!pskb_network_may_pull(skb, sizeof(*iph))) + goto err; + iph = ipv6_hdr(skb); h = (__force u32)iph->daddr.s6_addr32[3]; h2 = (__force u32)iph->saddr.s6_addr32[3] ^ iph->nexthdr; - if (iph->nexthdr == IPPROTO_TCP || - iph->nexthdr == IPPROTO_UDP || - iph->nexthdr == IPPROTO_UDPLITE || - iph->nexthdr == IPPROTO_SCTP || - iph->nexthdr == IPPROTO_DCCP || - iph->nexthdr == IPPROTO_ESP) + if ((iph->nexthdr == IPPROTO_TCP || + iph->nexthdr == IPPROTO_UDP || + iph->nexthdr == IPPROTO_UDPLITE || + iph->nexthdr == IPPROTO_SCTP || + iph->nexthdr == IPPROTO_DCCP || + iph->nexthdr == IPPROTO_ESP) && + pskb_network_may_pull(skb, sizeof(*iph) + 4)) h2 ^= *(u32*)&iph[1]; break; } default: +err: h = (unsigned long)skb_dst(skb) ^ (__force u32)skb->protocol; h2 = (unsigned long)skb->sk; } @@ -502,6 +513,12 @@ static unsigned long sfq_get(struct Qdisc *sch, u32 classid) return 0; } +static unsigned long sfq_bind(struct Qdisc *sch, unsigned long parent, + u32 classid) +{ + return 0; +} + static struct tcf_proto **sfq_find_tcf(struct Qdisc *sch, unsigned long cl) { struct sfq_sched_data *q = qdisc_priv(sch); @@ -556,6 +573,7 @@ static void sfq_walk(struct Qdisc *sch, struct qdisc_walker *arg) static const struct Qdisc_class_ops sfq_class_ops = { .get = sfq_get, .tcf_chain = sfq_find_tcf, + .bind_tcf = sfq_bind, .dump = sfq_dump_class, .dump_stats = sfq_dump_class_stats, .walk = sfq_walk, diff --git a/net/sctp/associola.c b/net/sctp/associola.c index e41feff19e4..0b85e525643 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c @@ -172,7 +172,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = (unsigned long)sp->autoclose * HZ; - /* Initilizes the timers */ + /* Initializes the timers */ for (i = SCTP_EVENT_TIMEOUT_NONE; i < SCTP_NUM_TIMEOUT_TYPES; ++i) setup_timer(&asoc->timers[i], sctp_timer_events[i], (unsigned long)asoc); diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index c0e162aeb0b..5027b83f1cc 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -1163,7 +1163,7 @@ SCTP_STATIC __init int sctp_init(void) /* Set the pressure threshold to be a fraction of global memory that * is up to 1/2 at 256 MB, decreasing toward zero with the amount of * memory, with a floor of 128 pages. - * Note this initalizes the data in sctpv6_prot too + * Note this initializes the data in sctpv6_prot too * Unabashedly stolen from tcp_init */ nr_pages = totalram_pages - totalhigh_pages; diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index 73affb8624f..8dc47f1d000 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c @@ -267,7 +267,7 @@ rpcauth_prune_expired(struct list_head *free, int nr_to_scan) * Run memory cache shrinker. */ static int -rpcauth_cache_shrinker(int nr_to_scan, gfp_t gfp_mask) +rpcauth_cache_shrinker(struct shrinker *shrink, int nr_to_scan, gfp_t gfp_mask) { LIST_HEAD(free); int res; diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 2a9675136c6..7ca65c7005e 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -210,7 +210,8 @@ struct sock_xprt { * State of TCP reply receive */ __be32 tcp_fraghdr, - tcp_xid; + tcp_xid, + tcp_calldir; u32 tcp_offset, tcp_reclen; @@ -927,7 +928,7 @@ static inline void xs_tcp_read_calldir(struct sock_xprt *transport, { size_t len, used; u32 offset; - __be32 calldir; + char *p; /* * We want transport->tcp_offset to be 8 at the end of this routine @@ -936,26 +937,33 @@ static inline void xs_tcp_read_calldir(struct sock_xprt *transport, * transport->tcp_offset is 4 (after having already read the xid). */ offset = transport->tcp_offset - sizeof(transport->tcp_xid); - len = sizeof(calldir) - offset; + len = sizeof(transport->tcp_calldir) - offset; dprintk("RPC: reading CALL/REPLY flag (%Zu bytes)\n", len); - used = xdr_skb_read_bits(desc, &calldir, len); + p = ((char *) &transport->tcp_calldir) + offset; + used = xdr_skb_read_bits(desc, p, len); transport->tcp_offset += used; if (used != len) return; transport->tcp_flags &= ~TCP_RCV_READ_CALLDIR; - transport->tcp_flags |= TCP_RCV_COPY_CALLDIR; - transport->tcp_flags |= TCP_RCV_COPY_DATA; /* * We don't yet have the XDR buffer, so we will write the calldir * out after we get the buffer from the 'struct rpc_rqst' */ - if (ntohl(calldir) == RPC_REPLY) + switch (ntohl(transport->tcp_calldir)) { + case RPC_REPLY: + transport->tcp_flags |= TCP_RCV_COPY_CALLDIR; + transport->tcp_flags |= TCP_RCV_COPY_DATA; transport->tcp_flags |= TCP_RPC_REPLY; - else + break; + case RPC_CALL: + transport->tcp_flags |= TCP_RCV_COPY_CALLDIR; + transport->tcp_flags |= TCP_RCV_COPY_DATA; transport->tcp_flags &= ~TCP_RPC_REPLY; - dprintk("RPC: reading %s CALL/REPLY flag %08x\n", - (transport->tcp_flags & TCP_RPC_REPLY) ? - "reply for" : "request with", calldir); + break; + default: + dprintk("RPC: invalid request message type\n"); + xprt_force_disconnect(&transport->xprt); + } xs_tcp_check_fraghdr(transport); } @@ -975,12 +983,10 @@ static inline void xs_tcp_read_common(struct rpc_xprt *xprt, /* * Save the RPC direction in the XDR buffer */ - __be32 calldir = transport->tcp_flags & TCP_RPC_REPLY ? - htonl(RPC_REPLY) : 0; - memcpy(rcvbuf->head[0].iov_base + transport->tcp_copied, - &calldir, sizeof(calldir)); - transport->tcp_copied += sizeof(calldir); + &transport->tcp_calldir, + sizeof(transport->tcp_calldir)); + transport->tcp_copied += sizeof(transport->tcp_calldir); transport->tcp_flags &= ~TCP_RCV_COPY_CALLDIR; } diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index e74a1a2119d..d1a3fb99fdf 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -843,13 +843,19 @@ int cfg80211_mlme_action(struct cfg80211_registered_device *rdev, return -EINVAL; if (mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) { /* Verify that we are associated with the destination AP */ + wdev_lock(wdev); + if (!wdev->current_bss || memcmp(wdev->current_bss->pub.bssid, mgmt->bssid, ETH_ALEN) != 0 || (wdev->iftype == NL80211_IFTYPE_STATION && memcmp(wdev->current_bss->pub.bssid, mgmt->da, - ETH_ALEN) != 0)) + ETH_ALEN) != 0)) { + wdev_unlock(wdev); return -ENOTCONN; + } + + wdev_unlock(wdev); } if (memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0) |