diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-26 08:43:05 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-26 08:43:05 -0700 |
commit | ec3b67c11df42362ccda81261d62829042f223f0 (patch) | |
tree | ab66bc43d98e38eda7162f76208993b2280f88f3 | |
parent | e868171a94b637158a3930c9adfb448d0df163cd (diff) | |
parent | 4be2700fb7b95f2a7cef9324879cafccab8774fc (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (32 commits)
[NetLabel]: correct usage of RCU locking
[TCP]: fix D-SACK cwnd handling
[NET] napi: use non-interruptible sleep in napi_disable
[SCTP] net/sctp/auth.c: make 3 functions static
[TCP]: Add missing I/O AT code to ipv6 side.
[SCTP]: #if 0 sctp_update_copy_cksum()
[INET]: Unexport icmpmsg_statistics
[NET]: Unexport sock_enable_timestamp().
[TCP]: Make tcp_match_skb_to_sack() static.
[IRDA]: Make ircomm_tty static.
[NET] fs/proc/proc_net.c: make a struct static
[NET] dev_change_name: ignore changes to same name
[NET]: Document some simple rules for actions
[NET_CLS_ACT]: Use skb_act_clone
[NET_CLS_ACT]: Introduce skb_act_clone
[TCP]: Fix scatterlist handling in MD5 signature support.
[IPSEC]: Fix scatterlist handling in skb_icv_walk().
[IPSEC]: Add missing sg_init_table() calls to ESP.
[CRYPTO]: Initialize TCRYPT on-stack scatterlist objects correctly.
[CRYPTO]: HMAC needs some more scatterlist fixups.
...
41 files changed, 228 insertions, 181 deletions
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 747a5d15d52..6f7872ba1de 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -184,14 +184,14 @@ tcp_frto - INTEGER F-RTO is an enhanced recovery algorithm for TCP retransmission timeouts. It is particularly beneficial in wireless environments where packet loss is typically due to random radio interference - rather than intermediate router congestion. FRTO is sender-side + rather than intermediate router congestion. F-RTO is sender-side only modification. Therefore it does not require any support from the peer, but in a typical case, however, where wireless link is the local access link and most of the data flows downlink, the - faraway servers should have FRTO enabled to take advantage of it. + faraway servers should have F-RTO enabled to take advantage of it. If set to 1, basic version is enabled. 2 enables SACK enhanced F-RTO if flow uses SACK. The basic version can be used also when - SACK is in use though scenario(s) with it exists where FRTO + SACK is in use though scenario(s) with it exists where F-RTO interacts badly with the packet counting of the SACK enabled TCP flow. diff --git a/Documentation/networking/tc-actions-env-rules.txt b/Documentation/networking/tc-actions-env-rules.txt new file mode 100644 index 00000000000..01e716d185f --- /dev/null +++ b/Documentation/networking/tc-actions-env-rules.txt @@ -0,0 +1,29 @@ + +The "enviromental" rules for authors of any new tc actions are: + +1) If you stealeth or borroweth any packet thou shalt be branching +from the righteous path and thou shalt cloneth. + +For example if your action queues a packet to be processed later +or intentionaly branches by redirecting a packet then you need to +clone the packet. +There are certain fields in the skb tc_verd that need to be reset so we +avoid loops etc. A few are generic enough so much so that skb_act_clone() +resets them for you. So invoke skb_act_clone() rather than skb_clone() + +2) If you munge any packet thou shalt call pskb_expand_head in the case +someone else is referencing the skb. After that you "own" the skb. +You must also tell us if it is ok to munge the packet (TC_OK2MUNGE), +this way any action downstream can stomp on the packet. + +3) dropping packets you dont own is a nono. You simply return +TC_ACT_SHOT to the caller and they will drop it. + +The "enviromental" rules for callers of actions (qdiscs etc) are: + +*) thou art responsible for freeing anything returned as being +TC_ACT_SHOT/STOLEN/QUEUED. If none of TC_ACT_SHOT/STOLEN/QUEUED is +returned then all is great and you dont need to do anything. + +Post on netdev if something is unclear. + diff --git a/MAINTAINERS b/MAINTAINERS index f985dfa5941..5b454627f21 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2449,13 +2449,15 @@ W: http://www.tazenda.demon.co.uk/phil/linux-hp S: Maintained MAC80211 -P: Jiri Benc -M: jbenc@suse.cz P: Michael Wu M: flamingice@sourmilk.net +P: Johannes Berg +M: johannes@sipsolutions.net +P: Jiri Benc +M: jbenc@suse.cz L: linux-wireless@vger.kernel.org W: http://linuxwireless.org/ -T: git kernel.org:/pub/scm/linux/kernel/git/jbenc/mac80211.git +T: git kernel.org:/pub/scm/linux/kernel/git/linville/wireless-2.6.git S: Maintained MACVLAN DRIVER diff --git a/crypto/hmac.c b/crypto/hmac.c index 6691981bda1..0f05be769c3 100644 --- a/crypto/hmac.c +++ b/crypto/hmac.c @@ -61,7 +61,7 @@ static int hmac_setkey(struct crypto_hash *parent, desc.tfm = tfm; desc.flags = crypto_hash_get_flags(parent); desc.flags &= CRYPTO_TFM_REQ_MAY_SLEEP; - sg_set_buf(&tmp, inkey, keylen); + sg_init_one(&tmp, inkey, keylen); err = crypto_hash_digest(&desc, &tmp, keylen, digest); if (err) @@ -96,7 +96,7 @@ static int hmac_init(struct hash_desc *pdesc) desc.tfm = ctx->child; desc.flags = pdesc->flags & CRYPTO_TFM_REQ_MAY_SLEEP; - sg_set_buf(&tmp, ipad, bs); + sg_init_one(&tmp, ipad, bs); err = crypto_hash_init(&desc); if (unlikely(err)) @@ -131,7 +131,7 @@ static int hmac_final(struct hash_desc *pdesc, u8 *out) desc.tfm = ctx->child; desc.flags = pdesc->flags & CRYPTO_TFM_REQ_MAY_SLEEP; - sg_set_buf(&tmp, opad, bs + ds); + sg_init_one(&tmp, opad, bs + ds); err = crypto_hash_final(&desc, digest); if (unlikely(err)) @@ -158,9 +158,11 @@ static int hmac_digest(struct hash_desc *pdesc, struct scatterlist *sg, desc.tfm = ctx->child; desc.flags = pdesc->flags & CRYPTO_TFM_REQ_MAY_SLEEP; + sg_init_table(sg1, 2); sg_set_buf(sg1, ipad, bs); + sg_set_page(&sg1[1], (void *) sg, 0, 0); - sg_set_page(&sg[1], (void *) sg, 0, 0); + sg_init_table(sg2, 1); sg_set_buf(sg2, opad, bs + ds); err = crypto_hash_digest(&desc, sg1, nbytes + bs, digest); diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index d741c63af42..c457bdb2a42 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -139,7 +139,7 @@ static void test_hash(char *algo, struct hash_testvec *template, printk("test %u:\n", i + 1); memset(result, 0, 64); - sg_set_buf(&sg[0], hash_tv[i].plaintext, hash_tv[i].psize); + sg_init_one(&sg[0], hash_tv[i].plaintext, hash_tv[i].psize); if (hash_tv[i].ksize) { ret = crypto_hash_setkey(tfm, hash_tv[i].key, @@ -176,6 +176,7 @@ static void test_hash(char *algo, struct hash_testvec *template, memset(result, 0, 64); temp = 0; + sg_init_table(sg, hash_tv[i].np); for (k = 0; k < hash_tv[i].np; k++) { memcpy(&xbuf[IDX[k]], hash_tv[i].plaintext + temp, @@ -289,8 +290,8 @@ static void test_cipher(char *algo, int enc, goto out; } - sg_set_buf(&sg[0], cipher_tv[i].input, - cipher_tv[i].ilen); + sg_init_one(&sg[0], cipher_tv[i].input, + cipher_tv[i].ilen); ablkcipher_request_set_crypt(req, sg, sg, cipher_tv[i].ilen, @@ -353,6 +354,7 @@ static void test_cipher(char *algo, int enc, } temp = 0; + sg_init_table(sg, cipher_tv[i].np); for (k = 0; k < cipher_tv[i].np; k++) { memcpy(&xbuf[IDX[k]], cipher_tv[i].input + temp, @@ -414,7 +416,7 @@ static int test_cipher_jiffies(struct blkcipher_desc *desc, int enc, char *p, int bcount; int ret; - sg_set_buf(sg, p, blen); + sg_init_one(sg, p, blen); for (start = jiffies, end = start + sec * HZ, bcount = 0; time_before(jiffies, end); bcount++) { @@ -440,7 +442,7 @@ static int test_cipher_cycles(struct blkcipher_desc *desc, int enc, char *p, int ret = 0; int i; - sg_set_buf(sg, p, blen); + sg_init_one(sg, p, blen); local_bh_disable(); local_irq_disable(); @@ -572,7 +574,7 @@ static int test_hash_jiffies_digest(struct hash_desc *desc, char *p, int blen, for (start = jiffies, end = start + sec * HZ, bcount = 0; time_before(jiffies, end); bcount++) { - sg_set_buf(sg, p, blen); + sg_init_one(sg, p, blen); ret = crypto_hash_digest(desc, sg, blen, out); if (ret) return ret; @@ -601,7 +603,7 @@ static int test_hash_jiffies(struct hash_desc *desc, char *p, int blen, if (ret) return ret; for (pcount = 0; pcount < blen; pcount += plen) { - sg_set_buf(sg, p + pcount, plen); + sg_init_one(sg, p + pcount, plen); ret = crypto_hash_update(desc, sg, plen); if (ret) return ret; @@ -631,7 +633,7 @@ static int test_hash_cycles_digest(struct hash_desc *desc, char *p, int blen, /* Warm-up run. */ for (i = 0; i < 4; i++) { - sg_set_buf(sg, p, blen); + sg_init_one(sg, p, blen); ret = crypto_hash_digest(desc, sg, blen, out); if (ret) goto out; @@ -643,7 +645,7 @@ static int test_hash_cycles_digest(struct hash_desc *desc, char *p, int blen, start = get_cycles(); - sg_set_buf(sg, p, blen); + sg_init_one(sg, p, blen); ret = crypto_hash_digest(desc, sg, blen, out); if (ret) goto out; @@ -686,7 +688,7 @@ static int test_hash_cycles(struct hash_desc *desc, char *p, int blen, if (ret) goto out; for (pcount = 0; pcount < blen; pcount += plen) { - sg_set_buf(sg, p + pcount, plen); + sg_init_one(sg, p + pcount, plen); ret = crypto_hash_update(desc, sg, plen); if (ret) goto out; @@ -706,7 +708,7 @@ static int test_hash_cycles(struct hash_desc *desc, char *p, int blen, if (ret) goto out; for (pcount = 0; pcount < blen; pcount += plen) { - sg_set_buf(sg, p + pcount, plen); + sg_init_one(sg, p + pcount, plen); ret = crypto_hash_update(desc, sg, plen); if (ret) goto out; diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c index 2e91fb756e9..4edaad0d995 100644 --- a/fs/proc/proc_net.c +++ b/fs/proc/proc_net.c @@ -185,7 +185,7 @@ static __net_exit void proc_net_ns_exit(struct net *net) kfree(net->proc_net_root); } -struct pernet_operations __net_initdata proc_net_ns_ops = { +static struct pernet_operations __net_initdata proc_net_ns_ops = { .init = proc_net_ns_init, .exit = proc_net_ns_exit, }; diff --git a/include/linux/dccp.h b/include/linux/dccp.h index f3fc4392e93..333c3ea82a5 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -144,6 +144,8 @@ enum dccp_reset_codes { DCCP_RESET_CODE_TOO_BUSY, DCCP_RESET_CODE_BAD_INIT_COOKIE, DCCP_RESET_CODE_AGGRESSION_PENALTY, + + DCCP_MAX_RESET_CODES /* Leave at the end! */ }; /* DCCP options */ @@ -270,10 +272,9 @@ static inline struct dccp_hdr *dccp_zeroed_hdr(struct sk_buff *skb, int headlen) return memset(skb_transport_header(skb), 0, headlen); } -static inline struct dccp_hdr_ext *dccp_hdrx(const struct sk_buff *skb) +static inline struct dccp_hdr_ext *dccp_hdrx(const struct dccp_hdr *dh) { - return (struct dccp_hdr_ext *)(skb_transport_header(skb) + - sizeof(struct dccp_hdr)); + return (struct dccp_hdr_ext *)((unsigned char *)dh + sizeof(*dh)); } static inline unsigned int __dccp_basic_hdr_len(const struct dccp_hdr *dh) @@ -287,13 +288,12 @@ static inline unsigned int dccp_basic_hdr_len(const struct sk_buff *skb) return __dccp_basic_hdr_len(dh); } -static inline __u64 dccp_hdr_seq(const struct sk_buff *skb) +static inline __u64 dccp_hdr_seq(const struct dccp_hdr *dh) { - const struct dccp_hdr *dh = dccp_hdr(skb); __u64 seq_nr = ntohs(dh->dccph_seq); if (dh->dccph_x != 0) - seq_nr = (seq_nr << 32) + ntohl(dccp_hdrx(skb)->dccph_seq_low); + seq_nr = (seq_nr << 32) + ntohl(dccp_hdrx(dh)->dccph_seq_low); else seq_nr += (u32)dh->dccph_seq2 << 16; diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 811024e311b..9b0c8f12373 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -390,7 +390,7 @@ static inline void napi_complete(struct napi_struct *n) static inline void napi_disable(struct napi_struct *n) { while (test_and_set_bit(NAPI_STATE_SCHED, &n->state)) - msleep_interruptible(1); + msleep(1); } /** diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h index 8228b57eb18..4427dcd1e53 100644 --- a/include/net/inet_hashtables.h +++ b/include/net/inet_hashtables.h @@ -26,7 +26,6 @@ #include <net/inet_connection_sock.h> #include <net/inet_sock.h> -#include <net/route.h> #include <net/sock.h> #include <net/tcp_states.h> @@ -266,11 +265,6 @@ out: wake_up(&hashinfo->lhash_wait); } -static inline int inet_iif(const struct sk_buff *skb) -{ - return ((struct rtable *)skb->dst)->rt_iif; -} - extern struct sock *__inet_lookup_listener(struct inet_hashinfo *hashinfo, const __be32 daddr, const unsigned short hnum, diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h index 62daf214931..70013c5f4e5 100644 --- a/include/net/inet_sock.h +++ b/include/net/inet_sock.h @@ -24,6 +24,7 @@ #include <net/flow.h> #include <net/sock.h> #include <net/request_sock.h> +#include <net/route.h> /** struct ip_options - IP Options * @@ -190,4 +191,10 @@ static inline int inet_sk_ehashfn(const struct sock *sk) return inet_ehashfn(laddr, lport, faddr, fport); } + +static inline int inet_iif(const struct sk_buff *skb) +{ + return ((struct rtable *)skb->dst)->rt_iif; +} + #endif /* _INET_SOCK_H */ diff --git a/include/net/irda/ircomm_tty.h b/include/net/irda/ircomm_tty.h index 8dabdd603fe..eea2e615238 100644 --- a/include/net/irda/ircomm_tty.h +++ b/include/net/irda/ircomm_tty.h @@ -127,7 +127,6 @@ extern int ircomm_tty_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); extern void ircomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old_termios); -extern hashbin_t *ircomm_tty; #endif diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index a02ec9e5fea..c9265518a37 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -316,4 +316,19 @@ static inline u32 qdisc_l2t(struct qdisc_rate_table* rtab, unsigned int pktlen) return rtab->data[slot]; } +#ifdef CONFIG_NET_CLS_ACT +static inline struct sk_buff *skb_act_clone(struct sk_buff *skb, gfp_t gfp_mask) +{ + struct sk_buff *n = skb_clone(skb, gfp_mask); + + if (n) { + n->tc_verd = SET_TC_VERD(n->tc_verd, 0); + n->tc_verd = CLR_TC_OK2MUNGE(n->tc_verd); + n->tc_verd = CLR_TC_MUNGED(n->tc_verd); + n->iif = skb->iif; + } + return n; +} +#endif + #endif diff --git a/include/net/sctp/auth.h b/include/net/sctp/auth.h index 4945954a16a..9e8f13b7da5 100644 --- a/include/net/sctp/auth.h +++ b/include/net/sctp/auth.h @@ -88,7 +88,6 @@ static inline void sctp_auth_key_hold(struct sctp_auth_bytes *key) void sctp_auth_key_put(struct sctp_auth_bytes *key); struct sctp_shared_key *sctp_auth_shkey_create(__u16 key_id, gfp_t gfp); -void sctp_auth_shkey_free(struct sctp_shared_key *sh_key); void sctp_auth_destroy_keys(struct list_head *keys); int sctp_auth_asoc_init_active_key(struct sctp_association *asoc, gfp_t gfp); struct sctp_shared_key *sctp_auth_get_shkey( diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index 119f5a1ed49..93eb708609e 100644 --- a/include/net/sctp/sctp.h +++ b/include/net/sctp/sctp.h @@ -156,7 +156,6 @@ int sctp_primitive_ASCONF(struct sctp_association *, void *arg); __u32 sctp_start_cksum(__u8 *ptr, __u16 count); __u32 sctp_update_cksum(__u8 *ptr, __u16 count, __u32 cksum); __u32 sctp_end_cksum(__u32 cksum); -__u32 sctp_update_copy_cksum(__u8 *, __u8 *, __u16 count, __u32 cksum); /* * sctp/input.c diff --git a/net/core/dev.c b/net/core/dev.c index f1647d7dd14..ddfef3b45ba 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -883,6 +883,9 @@ int dev_change_name(struct net_device *dev, char *newname) if (!dev_valid_name(newname)) return -EINVAL; + if (strncmp(newname, dev->name, IFNAMSIZ) == 0) + return 0; + memcpy(oldname, dev->name, IFNAMSIZ); if (strchr(newname, '%')) { diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 7b7c6c44c2d..573e1724019 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -415,13 +415,6 @@ static struct sk_buff *__skb_clone(struct sk_buff *n, struct sk_buff *skb) n->hdr_len = skb->nohdr ? skb_headroom(skb) : skb->hdr_len; n->nohdr = 0; n->destructor = NULL; -#ifdef CONFIG_NET_CLS_ACT - /* FIXME What is this and why don't we do it in copy_skb_header? */ - n->tc_verd = SET_TC_VERD(n->tc_verd,0); - n->tc_verd = CLR_TC_OK2MUNGE(n->tc_verd); - n->tc_verd = CLR_TC_MUNGED(n->tc_verd); - C(iif); -#endif C(truesize); atomic_set(&n->users, 1); C(head); diff --git a/net/core/sock.c b/net/core/sock.c index febbcbcf802..bba9949681f 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1649,7 +1649,6 @@ void sock_enable_timestamp(struct sock *sk) net_enable_timestamp(); } } -EXPORT_SYMBOL(sock_enable_timestamp); /* * Get a socket option on an socket. diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c index 426008e3b7e..d694656b880 100644 --- a/net/dccp/ccids/ccid2.c +++ b/net/dccp/ccids/ccid2.c @@ -750,20 +750,16 @@ static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk) */ hctx->ccid2hctx_ssthresh = ~0; hctx->ccid2hctx_numdupack = 3; - hctx->ccid2hctx_seqbufc = 0; /* XXX init ~ to window size... */ if (ccid2_hc_tx_alloc_seq(hctx)) return -ENOMEM; - hctx->ccid2hctx_sent = 0; hctx->ccid2hctx_rto = 3 * HZ; ccid2_change_srtt(hctx, -1); hctx->ccid2hctx_rttvar = -1; - hctx->ccid2hctx_lastrtt = 0; hctx->ccid2hctx_rpdupack = -1; hctx->ccid2hctx_last_cong = jiffies; - hctx->ccid2hctx_high_ack = 0; hctx->ccid2hctx_rtotimer.function = &ccid2_hc_tx_rto_expire; hctx->ccid2hctx_rtotimer.data = (unsigned long)sk; diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index 25772c32617..19b33586333 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c @@ -40,6 +40,8 @@ #include "lib/tfrc.h" #include "ccid3.h" +#include <asm/unaligned.h> + #ifdef CONFIG_IP_DCCP_CCID3_DEBUG static int ccid3_debug; #define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a) @@ -544,6 +546,7 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, const struct dccp_sock *dp = dccp_sk(sk); struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); struct ccid3_options_received *opt_recv; + __be32 opt_val; opt_recv = &hctx->ccid3hctx_options_received; @@ -563,8 +566,8 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, dccp_role(sk), sk, len); rc = -EINVAL; } else { - opt_recv->ccid3or_loss_event_rate = - ntohl(*(__be32 *)value); + opt_val = get_unaligned((__be32 *)value); + opt_recv->ccid3or_loss_event_rate = ntohl(opt_val); ccid3_pr_debug("%s(%p), LOSS_EVENT_RATE=%u\n", dccp_role(sk), sk, opt_recv->ccid3or_loss_event_rate); @@ -585,8 +588,8 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, dccp_role(sk), sk, len); rc = -EINVAL; } else { - opt_recv->ccid3or_receive_rate = - ntohl(*(__be32 *)value); + opt_val = get_unaligned((__be32 *)value); + opt_recv->ccid3or_receive_rate = ntohl(opt_val); ccid3_pr_debug("%s(%p), RECEIVE_RATE=%u\n", dccp_role(sk), sk, opt_recv->ccid3or_receive_rate); @@ -601,8 +604,6 @@ static int ccid3_hc_tx_init(struct ccid *ccid, struct sock *sk) { struct ccid3_hc_tx_sock *hctx = ccid_priv(ccid); - hctx->ccid3hctx_s = 0; - hctx->ccid3hctx_rtt = 0; hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT; INIT_LIST_HEAD(&hctx->ccid3hctx_hist); @@ -963,8 +964,6 @@ static int ccid3_hc_rx_init(struct ccid *ccid, struct sock *sk) INIT_LIST_HEAD(&hcrx->ccid3hcrx_li_hist); hcrx->ccid3hcrx_tstamp_last_feedback = hcrx->ccid3hcrx_tstamp_last_ack = ktime_get_real(); - hcrx->ccid3hcrx_s = 0; - hcrx->ccid3hcrx_rtt = 0; return 0; } diff --git a/net/dccp/input.c b/net/dccp/input.c index 3560a2a875a..1ce10106282 100644 --- a/net/dccp/input.c +++ b/net/dccp/input.c @@ -58,6 +58,42 @@ static void dccp_rcv_closereq(struct sock *sk, struct sk_buff *skb) dccp_send_close(sk, 0); } +static u8 dccp_reset_code_convert(const u8 code) +{ + const u8 error_code[] = { + [DCCP_RESET_CODE_CLOSED] = 0, /* normal termination */ + [DCCP_RESET_CODE_UNSPECIFIED] = 0, /* nothing known */ + [DCCP_RESET_CODE_ABORTED] = ECONNRESET, + + [DCCP_RESET_CODE_NO_CONNECTION] = ECONNREFUSED, + [DCCP_RESET_CODE_CONNECTION_REFUSED] = ECONNREFUSED, + [DCCP_RESET_CODE_TOO_BUSY] = EUSERS, + [DCCP_RESET_CODE_AGGRESSION_PENALTY] = EDQUOT, + + [DCCP_RESET_CODE_PACKET_ERROR] = ENOMSG, + [DCCP_RESET_CODE_BAD_INIT_COOKIE] = EBADR, + [DCCP_RESET_CODE_BAD_SERVICE_CODE] = EBADRQC, + [DCCP_RESET_CODE_OPTION_ERROR] = EILSEQ, + [DCCP_RESET_CODE_MANDATORY_ERROR] = EOPNOTSUPP, + }; + + return code >= DCCP_MAX_RESET_CODES ? 0 : error_code[code]; +} + +static void dccp_rcv_reset(struct sock *sk, struct sk_buff *skb) +{ + u8 err = dccp_reset_code_convert(dccp_hdr_reset(skb)->dccph_reset_code); + + sk->sk_err = err; + + /* Queue the equivalent of TCP fin so that dccp_recvmsg exits the loop */ + dccp_fin(sk, skb); + + if (err && !sock_flag(sk, SOCK_DEAD)) + sk_wake_async(sk, 0, POLL_ERR); + dccp_time_wait(sk, DCCP_TIME_WAIT, 0); +} + static void dccp_event_ack_recv(struct sock *sk, struct sk_buff *skb) { struct dccp_sock *dp = dccp_sk(sk); @@ -191,9 +227,8 @@ static int __dccp_rcv_established(struct sock *sk, struct sk_buff *skb, * S.state := TIMEWAIT * Set TIMEWAIT timer * Drop packet and return - */ - dccp_fin(sk, skb); - dccp_time_wait(sk, DCCP_TIME_WAIT, 0); + */ + dccp_rcv_reset(sk, skb); return 0; case DCCP_PKT_CLOSEREQ: dccp_rcv_closereq(sk, skb); @@ -521,12 +556,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb, * Drop packet and return */ if (dh->dccph_type == DCCP_PKT_RESET) { - /* - * Queue the equivalent of TCP fin so that dccp_recvmsg - * exits the loop - */ - dccp_fin(sk, skb); - dccp_time_wait(sk, DCCP_TIME_WAIT, 0); + dccp_rcv_reset(sk, skb); return 0; /* * Step 7: Check for unexpected packet types diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 222549ab274..01a6a808bdb 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -241,8 +241,8 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info) goto out; dp = dccp_sk(sk); - seq = dccp_hdr_seq(skb); - if (sk->sk_state != DCCP_LISTEN && + seq = dccp_hdr_seq(dh); + if ((1 << sk->sk_state) & ~(DCCPF_REQUESTING | DCCPF_LISTEN) && !between48(seq, dp->dccps_swl, dp->dccps_swh)) { NET_INC_STATS_BH(LINUX_MIB_OUTOFWINDOWICMPS); goto out; @@ -795,7 +795,7 @@ static int dccp_v4_rcv(struct sk_buff *skb) dh = dccp_hdr(skb); - DCCP_SKB_CB(skb)->dccpd_seq = dccp_hdr_seq(skb); + DCCP_SKB_CB(skb)->dccpd_seq = dccp_hdr_seq(dh); DCCP_SKB_CB(skb)->dccpd_type = dh->dccph_type; dccp_pr_debug("%8.8s " diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index bbadd6681b8..62428ff137d 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c @@ -173,7 +173,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, icmpv6_err_convert(type, code, &err); - seq = DCCP_SKB_CB(skb)->dccpd_seq; + seq = dccp_hdr_seq(dh); /* Might be for an request_sock */ switch (sk->sk_state) { struct request_sock *req, **prev; @@ -787,7 +787,7 @@ static int dccp_v6_rcv(struct sk_buff *skb) dh = dccp_hdr(skb); - DCCP_SKB_CB(skb)->dccpd_seq = dccp_hdr_seq(skb); + DCCP_SKB_CB(skb)->dccpd_seq = dccp_hdr_seq(dh); DCCP_SKB_CB(skb)->dccpd_type = dh->dccph_type; if (dccp_packet_without_ack(skb)) diff --git a/net/dccp/options.c b/net/dccp/options.c index d361b553330..d286cffe2c4 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c @@ -14,6 +14,7 @@ #include <linux/dccp.h> #include <linux/module.h> #include <linux/types.h> +#include <asm/unaligned.h> #include <linux/kernel.h> #include <linux/skbuff.h> @@ -59,6 +60,7 @@ int dccp_parse_options(struct sock *sk, struct sk_b |