From fde20105f332614b23a3131d706cd90bdd7db72d Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Wed, 24 Oct 2007 10:12:09 -0200 Subject: [DCCP]: Retrieve packet sequence number for error reporting This fixes a problem when analysing erroneous packets in dccp_v{4,6}_err: * dccp_hdr_seq currently takes an skb * however, the transport headers in the skb are shifted, due to the preceding IPv4/v6 header. Fixed for v4 and v6 by changing dccp_hdr_seq to take a struct dccp_hdr as argument. Verified that the correct sequence number is now reported in the error handler. Signed-off-by: Gerrit Renker Acked-by: Ian McDonald Signed-off-by: Arnaldo Carvalho de Melo diff --git a/include/linux/dccp.h b/include/linux/dccp.h index f3fc439..55d28cb 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -270,10 +270,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 +286,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/net/dccp/ipv4.c b/net/dccp/ipv4.c index 222549a..3f1578d 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -241,7 +241,7 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info) goto out; dp = dccp_sk(sk); - seq = dccp_hdr_seq(skb); + seq = dccp_hdr_seq(dh); if (sk->sk_state != DCCP_LISTEN && !between48(seq, dp->dccps_swl, dp->dccps_swh)) { NET_INC_STATS_BH(LINUX_MIB_OUTOFWINDOWICMPS); @@ -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 bbadd66..62428ff 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)) -- cgit v0.10.2 From 1238d0873b29f7a2de75d576b4cc706c1c75ffbf Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Wed, 24 Oct 2007 10:18:06 -0200 Subject: [DCCP]: One more exemption from full sequence number checks This fixes the following problem: client connects to peer which has no DCCP enabled or loaded; ICMP error messages ("Protocol Unavailable") can be seen on the wire, but the application hangs. Reason: ICMP packets don't get through to dccp_v4_err. When reporting errors, a sequence number check is made for the DCCP packet that had caused an ICMP error to arrive. Such checks can not be made if the socket is in state LISTEN, RESPOND (which in the implementation is the same as LISTEN), or REQUEST, since update_gsr() has not been called in these states, hence the sequence window is 0..0. This patch fixes the problem by adding the REQUEST state as another exemption to the window check. The error reporting now works as expected on connecting. Signed-off-by: Gerrit Renker Acked-by: Ian McDonald Signed-off-by: Arnaldo Carvalho de Melo diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 3f1578d..01a6a80 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -242,7 +242,7 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info) dp = dccp_sk(sk); seq = dccp_hdr_seq(dh); - if (sk->sk_state != DCCP_LISTEN && + 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; -- cgit v0.10.2 From d8ef2c29a0dcfccb2d90cac990143d1a4668708a Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Wed, 24 Oct 2007 10:27:48 -0200 Subject: [DCCP]: Convert Reset code into socket error number This adds support for converting the 11 currently defined Reset codes into system error numbers, which are stored in sk_err for further interpretation. This makes the externally visible API behaviour similar to TCP, since a client connecting to a non-existing port will experience ECONNREFUSED. * Code 0, Unspecified, is interpreted as non-error (0); * Code 1, Closed (normal termination), also maps into 0; * Code 2, Aborted, maps into "Connection reset by peer" (ECONNRESET); * Code 3, No Connection and Code 7, Connection Refused, map into "Connection refused" (ECONNREFUSED); * Code 4, Packet Error, maps into "No message of desired type" (ENOMSG); * Code 5, Option Error, maps into "Illegal byte sequence" (EILSEQ); * Code 6, Mandatory Error, maps into "Operation not supported on transport endpoint" (EOPNOTSUPP); * Code 8, Bad Service Code, maps into "Invalid request code" (EBADRQC); * Code 9, Too Busy, maps into "Too many users" (EUSERS); * Code 10, Bad Init Cookie, maps into "Invalid request descriptor" (EBADR); * Code 11, Aggression Penalty, maps into "Quota exceeded" (EDQUOT) which makes sense in terms of using more than the `fair share' of bandwidth. Signed-off-by: Gerrit Renker Acked-by: Ian McDonald Signed-off-by: Arnaldo Carvalho de Melo diff --git a/include/linux/dccp.h b/include/linux/dccp.h index 55d28cb..333c3ea 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 */ diff --git a/net/dccp/input.c b/net/dccp/input.c index 3560a2a..1ce1010 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 -- cgit v0.10.2 From 76fd1e87d9456c8185b8df76ac5e533e0c8b39bb Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Wed, 24 Oct 2007 10:46:58 -0200 Subject: [DCCP]: Unaligned pointer access This fixes `unaligned (read) access' errors of the type Kernel unaligned access at TPC[100f970c] dccp_parse_options+0x4f4/0x7e0 [dccp] Kernel unaligned access at TPC[1011f2e4] ccid3_hc_tx_parse_options+0x1ac/0x380 [dccp_ccid3] Kernel unaligned access at TPC[100f9898] dccp_parse_options+0x680/0x880 [dccp] by using the get_unaligned macro for parsing options. Commiter note: Preserved the sparse __be{16,32} annotations. Signed-off-by: Gerrit Renker Signed-off-by: Ian McDonald Signed-off-by: Arnaldo Carvalho de Melo diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index 25772c3..05f263e 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 + #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); diff --git a/net/dccp/options.c b/net/dccp/options.c index d361b55..d286cff 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -59,6 +60,7 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb) unsigned char opt, len; unsigned char *value; u32 elapsed_time; + __be32 opt_val; int rc; int mandatory = 0; @@ -145,7 +147,8 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb) if (len != 4) goto out_invalid_option; - opt_recv->dccpor_timestamp = ntohl(*(__be32 *)value); + opt_val = get_unaligned((__be32 *)value); + opt_recv->dccpor_timestamp = ntohl(opt_val); dp->dccps_timestamp_echo = opt_recv->dccpor_timestamp; dp->dccps_timestamp_time = ktime_get_real(); @@ -159,7 +162,8 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb) if (len != 4 && len != 6 && len != 8) goto out_invalid_option; - opt_recv->dccpor_timestamp_echo = ntohl(*(__be32 *)value); + opt_val = get_unaligned((__be32 *)value); + opt_recv->dccpor_timestamp_echo = ntohl(opt_val); dccp_pr_debug("%s rx opt: TIMESTAMP_ECHO=%u, len=%d, " "ackno=%llu", dccp_role(sk), @@ -168,16 +172,20 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb) (unsigned long long) DCCP_SKB_CB(skb)->dccpd_ack_seq); + value += 4; - if (len == 4) { + if (len == 4) { /* no elapsed time included */ dccp_pr_debug_cat("\n"); break; } - if (len == 6) - elapsed_time = ntohs(*(__be16 *)(value + 4)); - else - elapsed_time = ntohl(*(__be32 *)(value + 4)); + if (len == 6) { /* 2-byte elapsed time */ + __be16 opt_val2 = get_unaligned((__be16 *)value); + elapsed_time = ntohs(opt_val2); + } else { /* 4-byte elapsed time */ + opt_val = get_unaligned((__be32 *)value); + elapsed_time = ntohl(opt_val); + } dccp_pr_debug_cat(", ELAPSED_TIME=%u\n", elapsed_time); @@ -192,10 +200,13 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb) if (pkt_type == DCCP_PKT_DATA) continue; - if (len == 2) - elapsed_time = ntohs(*(__be16 *)value); - else - elapsed_time = ntohl(*(__be32 *)value); + if (len == 2) { + __be16 opt_val2 = get_unaligned((__be16 *)value); + elapsed_time = ntohs(opt_val2); + } else { + opt_val = get_unaligned((__be32 *)value); + elapsed_time = ntohl(opt_val); + } if (elapsed_time > opt_recv->dccpor_elapsed_time) opt_recv->dccpor_elapsed_time = elapsed_time; -- cgit v0.10.2 From 24c667db59a9cc4caaafe4f77f6f4ef85899a454 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Wed, 24 Oct 2007 10:53:01 -0200 Subject: [CCID2/3]: Initialisation assignments of 0 are redundant Assigning initial values of `0' is redundant when loading a new CCID structure, since in net/dccp/ccid.c the entire CCID structure is zeroed out prior to initialisation in ccid_new(): struct ccid { struct ccid_operations *ccid_ops; char ccid_priv[0]; }; // ... if (rx) { memset(ccid + 1, 0, ccid_ops->ccid_hc_rx_obj_size); if (ccid->ccid_ops->ccid_hc_rx_init != NULL && ccid->ccid_ops->ccid_hc_rx_init(ccid, sk) != 0) goto out_free_ccid; } else { memset(ccid + 1, 0, ccid_ops->ccid_hc_tx_obj_size); /* analogous to the rx case */ } This patch therefore removes the redundant assignments. Thanks to Arnaldo for the inspiration. Signed-off-by: Gerrit Renker Signed-off-by: Ian McDonald Signed-off-by: Arnaldo Carvalho de Melo diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c index 426008e..d694656 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 05f263e..19b3358 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c @@ -604,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); @@ -966,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; } -- cgit v0.10.2 From 8a6911b12f7a835055f3236c6cf7073f79ba0730 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 25 Oct 2007 18:40:05 -0700 Subject: [IPV4]: Remove no longer used snmp4_icmp_list. This was obsoleted by a previous change, but the removal was forgotten. Reported by David Howells and David Stevens. Signed-off-by: David S. Miller diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index fd16cb8..9be0daa 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c @@ -121,14 +121,6 @@ static const struct snmp_mib snmp4_ipextstats_list[] = { SNMP_MIB_SENTINEL }; -static const struct snmp_mib snmp4_icmp_list[] = { - SNMP_MIB_ITEM("InMsgs", ICMP_MIB_INMSGS), - SNMP_MIB_ITEM("InErrors", ICMP_MIB_INERRORS), - SNMP_MIB_ITEM("OutMsgs", ICMP_MIB_OUTMSGS), - SNMP_MIB_ITEM("OutErrors", ICMP_MIB_OUTERRORS), - SNMP_MIB_SENTINEL -}; - static struct { char *name; int index; -- cgit v0.10.2 From 41fb285430e9cb57da624d838afef7b2fc67e276 Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Thu, 25 Oct 2007 18:46:26 -0700 Subject: [CRYPTO]: Fix hmac_digest from the SG breakage. Crypto now uses SG helper functions. Fix hmac_digest to use those functions correctly and fix the oops associated with it. Signed-off-by: Vlad Yasevich Signed-off-by: David S. Miller diff --git a/crypto/hmac.c b/crypto/hmac.c index 6691981..e3f5c0f 100644 --- a/crypto/hmac.c +++ b/crypto/hmac.c @@ -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); -- cgit v0.10.2 From fee9dee730a40f671c1972a324ed54f0d68523e1 Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Thu, 25 Oct 2007 18:54:46 -0700 Subject: [UDP]: Make use of inet_iif() when doing socket lookups. UDP currently uses skb->dev->ifindex which may provide the wrong information when the socket bound to a specific interface. This patch makes inet_iif() accessible to UDP and makes UDP use it. The scenario we are trying to fix is when a client is running on the same system and the server and both client and server bind to a non-loopback device. Signed-off-by: Vlad Yasevich Acked-by: David L Stevens Signed-off-by: David S. Miller diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h index 8228b57..4427dcd 100644 --- a/include/net/inet_hashtables.h +++ b/include/net/inet_hashtables.h @@ -26,7 +26,6 @@ #include #include -#include #include #include @@ -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 62daf21..70013c5 100644 --- a/include/net/inet_sock.h +++ b/include/net/inet_sock.h @@ -24,6 +24,7 @@ #include #include #include +#include /** 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/net/ipv4/udp.c b/net/ipv4/udp.c index 35d2b0e..4bc25b4 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1152,7 +1152,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[], return __udp4_lib_mcast_deliver(skb, uh, saddr, daddr, udptable); sk = __udp4_lib_lookup(saddr, uh->source, daddr, uh->dest, - skb->dev->ifindex, udptable ); + inet_iif(skb), udptable); if (sk != NULL) { int ret = udp_queue_rcv_skb(sk, skb); -- cgit v0.10.2 From 48225709bec68c2d8612718922f974f22214a308 Mon Sep 17 00:00:00 2001 From: Michael Wu Date: Fri, 19 Oct 2007 17:14:36 -0400 Subject: [PATCH] mac80211: Fix SSID matching in AP selection The length of the SSID desired should also be compared in addition to the memcmp of the SSIDs. Thanks to Andrea Merello for finding this issue. Signed-off-by: Michael Wu Signed-off-by: John W. Linville diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c index f7ffeec..77ef223 100644 --- a/net/mac80211/ieee80211_sta.c +++ b/net/mac80211/ieee80211_sta.c @@ -2096,7 +2096,8 @@ static int ieee80211_sta_match_ssid(struct ieee80211_if_sta *ifsta, { int tmp, hidden_ssid; - if (!memcmp(ifsta->ssid, ssid, ssid_len)) + if (ssid_len == ifsta->ssid_len && + !memcmp(ifsta->ssid, ssid, ssid_len)) return 1; if (ifsta->flags & IEEE80211_STA_AUTO_BSSID_SEL) -- cgit v0.10.2 From 31c7cecb616e499dd30703959710aebeee3f9af1 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 23 Oct 2007 17:05:25 +0200 Subject: [PATCH] add myself as mac80211 maintainer This adds myself as mac80211 maintainer and updates the git URL to point to the wireless-2.6 tree. Also move Jiri down so he isn't first in list. Signed-off-by: Johannes Berg Acked-by: Michael Wu Signed-off-by: John W. Linville diff --git a/MAINTAINERS b/MAINTAINERS index 76b8571..71badfb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2442,13 +2442,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 -- cgit v0.10.2 From ddd68587d0470498eb161de37b8f9fb5c48786a3 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 22 Oct 2007 14:51:37 +0200 Subject: [PATCH] mac80211: fix printk warning on 64-bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit My AID message patch introduced a warning on 64-bit machines because ~ extends to unsigned long: | net/mac80211/ieee80211_sta.c: In function ‘ieee80211_rx_mgmt_assoc_resp’: | net/mac80211/ieee80211_sta.c:1187: warning: format ‘%d’ expects type ‘int’, but argument 7 has type ‘long unsigned int’ This fixes it by explicitly casting the result to u16 (which 'aid' is). Signed-off-by: Johannes Berg Signed-off-by: John W. Linville diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c index 77ef223..fda0e06 100644 --- a/net/mac80211/ieee80211_sta.c +++ b/net/mac80211/ieee80211_sta.c @@ -1184,7 +1184,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev, printk(KERN_DEBUG "%s: RX %sssocResp from %s (capab=0x%x " "status=%d aid=%d)\n", dev->name, reassoc ? "Rea" : "A", print_mac(mac, mgmt->sa), - capab_info, status_code, aid & ~(BIT(15) | BIT(14))); + capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14)))); if (status_code != WLAN_STATUS_SUCCESS) { printk(KERN_DEBUG "%s: AP denied association (code=%d)\n", -- cgit v0.10.2 From 564262c1f0b0f0ce852ecd7f60672f79985595ee Mon Sep 17 00:00:00 2001 From: Ryousei Takano Date: Thu, 25 Oct 2007 23:03:52 -0700 Subject: [TCP]: Fix inconsistency of terms. Fix inconsistency of terms: 1) D-SACK 2) F-RTO Signed-off-by: Ryousei Takano Signed-off-by: David S. Miller diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 747a5d1..6f7872b 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/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 3dbbb44..47f4f35 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -103,7 +103,7 @@ int sysctl_tcp_abc __read_mostly; #define FLAG_SLOWPATH 0x100 /* Do not skip RFC checks for window update.*/ #define FLAG_ONLY_ORIG_SACKED 0x200 /* SACKs only non-rexmit sent before RTO */ #define FLAG_SND_UNA_ADVANCED 0x400 /* Snd_una was changed (!= FLAG_DATA_ACKED) */ -#define FLAG_DSACKING_ACK 0x800 /* SACK blocks contained DSACK info */ +#define FLAG_DSACKING_ACK 0x800 /* SACK blocks contained D-SACK info */ #define FLAG_NONHEAD_RETRANS_ACKED 0x1000 /* Non-head rexmitted data was ACKed */ #define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED) @@ -866,7 +866,7 @@ static void tcp_disable_fack(struct tcp_sock *tp) tp->rx_opt.sack_ok &= ~2; } -/* Take a notice that peer is sending DSACKs */ +/* Take a notice that peer is sending D-SACKs */ static void tcp_dsack_seen(struct tcp_sock *tp) { tp->rx_opt.sack_ok |= 4; @@ -1058,7 +1058,7 @@ static void tcp_update_reordering(struct sock *sk, const int metric, * * With D-SACK the lower bound is extended to cover sequence space below * SND.UNA down to undo_marker, which is the last point of interest. Yet - * again, DSACK block must not to go across snd_una (for the same reason as + * again, D-SACK block must not to go across snd_una (for the same reason as * for the normal SACK blocks, explained above). But there all simplicity * ends, TCP might receive valid D-SACKs below that. As long as they reside * fully below undo_marker they do not affect behavior in anyway and can @@ -1080,7 +1080,7 @@ static int tcp_is_sackblock_valid(struct tcp_sock *tp, int is_dsack, if (!before(start_seq, tp->snd_nxt)) return 0; - /* In outstanding window? ...This is valid exit for DSACKs too. + /* In outstanding window? ...This is valid exit for D-SACKs too. * start_seq == snd_una is non-sensical (see comments above) */ if (after(start_seq, tp->snd_una)) @@ -1615,7 +1615,7 @@ void tcp_enter_frto(struct sock *sk) !icsk->icsk_retransmits)) { tp->prior_ssthresh = tcp_current_ssthresh(sk); /* Our state is too optimistic in ssthresh() call because cwnd - * is not reduced until tcp_enter_frto_loss() when previous FRTO + * is not reduced until tcp_enter_frto_loss() when previous F-RTO * recovery has not yet completed. Pattern would be this: RTO, * Cumulative ACK, RTO (2xRTO for the same segment does not end * up here twice). @@ -1801,7 +1801,7 @@ void tcp_enter_loss(struct sock *sk, int how) tcp_set_ca_state(sk, TCP_CA_Loss); tp->high_seq = tp->snd_nxt; TCP_ECN_queue_cwr(tp); - /* Abort FRTO algorithm if one is in progress */ + /* Abort F-RTO algorithm if one is in progress */ tp->frto_counter = 0; } @@ -1946,7 +1946,7 @@ static int tcp_time_to_recover(struct sock *sk) struct tcp_sock *tp = tcp_sk(sk); __u32 packets_out; - /* Do not perform any recovery during FRTO algorithm */ + /* Do not perform any recovery during F-RTO algorithm */ if (tp->frto_counter) return 0; @@ -2962,7 +2962,7 @@ static int tcp_process_frto(struct sock *sk, int flag) } if (tp->frto_counter == 1) { - /* Sending of the next skb must be allowed or no FRTO */ + /* Sending of the next skb must be allowed or no F-RTO */ if (!tcp_send_head(sk) || after(TCP_SKB_CB(tcp_send_head(sk))->end_seq, tp->snd_una + tp->snd_wnd)) { -- cgit v0.10.2 From a6767721a563acb172c73f693fcf719b3b3d6716 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 26 Oct 2007 00:37:12 -0700 Subject: [CRYPTO]: HMAC needs some more scatterlist fixups. hmac_setkey(), hmac_init(), and hmac_final() have a singular on-stack scatterlist. Initialit is using sg_init_one() instead of using sg_set_buf(). Signed-off-by: David S. Miller diff --git a/crypto/hmac.c b/crypto/hmac.c index e3f5c0f..0f05be7 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)) -- cgit v0.10.2 From b733588559fc13547a59ccf81651c775b8f2719c Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 26 Oct 2007 00:38:10 -0700 Subject: [CRYPTO]: Initialize TCRYPT on-stack scatterlist objects correctly. Use sg_init_one() and sg_init_table() as needed. Signed-off-by: David S. Miller diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index d741c63..c457bdb 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; -- cgit v0.10.2 From ed0e7e0ca370519d6f79d1093ee2890d4cdee744 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 26 Oct 2007 00:38:39 -0700 Subject: [IPSEC]: Add missing sg_init_table() calls to ESP. Signed-off-by: David S. Miller diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 6b1a31a..ba98401 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c @@ -110,6 +110,7 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) if (!sg) goto unlock; } + sg_init_table(sg, nfrags); skb_to_sgvec(skb, sg, esph->enc_data+esp->conf.ivlen-skb->data, clen); err = crypto_blkcipher_encrypt(&desc, sg, sg, clen); if (unlikely(sg != &esp->sgbuf[0])) @@ -201,6 +202,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb) if (!sg) goto out; } + sg_init_table(sg, nfrags); skb_to_sgvec(skb, sg, sizeof(*esph) + esp->conf.ivlen, elen); err = crypto_blkcipher_decrypt(&desc, sg, sg, elen); if (unlikely(sg != &esp->sgbuf[0])) diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index 72a6598..f67d51a 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c @@ -109,6 +109,7 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) if (!sg) goto unlock; } + sg_init_table(sg, nfrags); skb_to_sgvec(skb, sg, esph->enc_data+esp->conf.ivlen-skb->data, clen); err = crypto_blkcipher_encrypt(&desc, sg, sg, clen); if (unlikely(sg != &esp->sgbuf[0])) @@ -205,6 +206,7 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb) goto out; } } + sg_init_table(sg, nfrags); skb_to_sgvec(skb, sg, sizeof(*esph) + esp->conf.ivlen, elen); ret = crypto_blkcipher_decrypt(&desc, sg, sg, elen); if (unlikely(sg != &esp->sgbuf[0])) -- cgit v0.10.2 From 0e0940d4bb9b19c0a45c844a83e1d25686aaf433 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 26 Oct 2007 00:39:27 -0700 Subject: [IPSEC]: Fix scatterlist handling in skb_icv_walk(). Use sg_init_one() and sg_init_table() as needed. Signed-off-by: David S. Miller diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c index fa45989..0426388 100644 --- a/net/xfrm/xfrm_algo.c +++ b/net/xfrm/xfrm_algo.c @@ -553,7 +553,7 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc, if (copy > len) copy = len; - sg_set_buf(&sg, skb->data + offset, copy); + sg_init_one(&sg, skb->data + offset, copy); err = icv_update(desc, &sg, copy); if (unlikely(err)) @@ -576,8 +576,9 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc, if (copy > len) copy = len; + sg_init_table(&sg, 1); sg_set_page(&sg, frag->page, copy, - frag->page_offset + offset-start); + frag->page_offset + offset-start); err = icv_update(desc, &sg, copy); if (unlikely(err)) -- cgit v0.10.2 From c7da57a183a255f53caa73b1f688a01b097fa5bc Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 26 Oct 2007 00:41:21 -0700 Subject: [TCP]: Fix scatterlist handling in MD5 signature support. Use sg_init_table() and sg_mark_end() as needed. Signed-off-by: David S. Miller diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 38cf73a..ad759f1 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1055,6 +1055,9 @@ static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, bp->pad = 0; bp->protocol = protocol; bp->len = htons(tcplen); + + sg_init_table(sg, 4); + sg_set_buf(&sg[block++], bp, sizeof(*bp)); nbytes += sizeof(*bp); @@ -1080,6 +1083,8 @@ static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, sg_set_buf(&sg[block++], key->key, key->keylen); nbytes += key->keylen; + sg_mark_end(sg, block); + /* Now store the Hash into the packet */ err = crypto_hash_init(desc); if (err) diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 737b755..32dc3297 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -757,6 +757,8 @@ static int tcp_v6_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, bp->len = htonl(tcplen); bp->protocol = htonl(protocol); + sg_init_table(sg, 4); + sg_set_buf(&sg[block++], bp, sizeof(*bp)); nbytes += sizeof(*bp); @@ -778,6 +780,8 @@ static int tcp_v6_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, sg_set_buf(&sg[block++], key->key, key->keylen); nbytes += key->keylen; + sg_mark_end(sg, block); + /* Now store the hash into the packet */ err = crypto_hash_init(desc); if (err) { -- cgit v0.10.2 From 12da81d11a34d3bdef52d731cc75f7ec72d0e815 Mon Sep 17 00:00:00 2001 From: Jamal Hadi Salim Date: Fri, 26 Oct 2007 02:47:23 -0700 Subject: [NET_CLS_ACT]: Introduce skb_act_clone Reworked skb_clone looks uglier with the single ifdef CONFIG_NET_CLS_ACT This patch introduces skb_act_clone which will replace skb_clone in tc actions Signed-off-by: Jamal Hadi Salim Signed-off-by: David S. Miller diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index a02ec9e..c926551 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 -- cgit v0.10.2 From a057ae3c104dd2c661e55d2af37e70d168c65e00 Mon Sep 17 00:00:00 2001 From: Jamal Hadi Salim Date: Fri, 26 Oct 2007 02:47:54 -0700 Subject: [NET_CLS_ACT]: Use skb_act_clone clean skb_clone of any signs of CONFIG_NET_CLS_ACT and have mirred us skb_act_clone() Signed-off-by: Jamal Hadi Salim Signed-off-by: David S. Miller diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 7b7c6c4..573e172 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/sched/act_mirred.c b/net/sched/act_mirred.c index fd7bca4..c3fde91 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -166,7 +166,7 @@ bad_mirred: return TC_ACT_SHOT; } - skb2 = skb_clone(skb, GFP_ATOMIC); + skb2 = skb_act_clone(skb, GFP_ATOMIC); if (skb2 == NULL) goto bad_mirred; if (m->tcfm_eaction != TCA_EGRESS_MIRROR && -- cgit v0.10.2 From d892afe2ca905ddb00a4f16927c8b465cdd31b20 Mon Sep 17 00:00:00 2001 From: Jamal Hadi Salim Date: Fri, 26 Oct 2007 02:49:09 -0700 Subject: [NET]: Document some simple rules for actions This patch adds documentation on what is expected of an action which branches away from the action-graph or when it needs to trample on actins. It also describes what is expected of users of such actions. Signed-off-by: Jamal Hadi Salim Signed-off-by: David S. Miller diff --git a/Documentation/networking/tc-actions-env-rules.txt b/Documentation/networking/tc-actions-env-rules.txt new file mode 100644 index 0000000..01e716d --- /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. + -- cgit v0.10.2 From c8d90dca3211966ba5189e0f3d4bccd558d9ae08 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 26 Oct 2007 03:53:42 -0700 Subject: [NET] dev_change_name: ignore changes to same name Prevent error/backtrace from dev_rename() when changing name of network device to the same name. This is a common situation with udev and other scripts that bind addr to device. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller diff --git a/net/core/dev.c b/net/core/dev.c index f1647d7..ddfef3b 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, '%')) { -- cgit v0.10.2 From 253879e62f997d0027500f4b71ef290f37e306ee Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 26 Oct 2007 03:55:44 -0700 Subject: [NET] fs/proc/proc_net.c: make a struct static Struct proc_net_ns_ops can become static. Signed-off-by: Adrian Bunk Acked-by: "Eric W. Biederman" Signed-off-by: David S. Miller diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c index 2e91fb7..4edaad0 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, }; -- cgit v0.10.2 From d76081f87548f986fd318d2b0dd7e942f93a0da4 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 26 Oct 2007 03:56:43 -0700 Subject: [IRDA]: Make ircomm_tty static. ircomm_tty can now become static. Signed-off-by: Adrian Bunk Signed-off-by: David S. Miller diff --git a/include/net/irda/ircomm_tty.h b/include/net/irda/ircomm_tty.h index 8dabdd6..eea2e61 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/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c index 3d241e4..1120b15 100644 --- a/net/irda/ircomm/ircomm_tty.c +++ b/net/irda/ircomm/ircomm_tty.c @@ -77,7 +77,7 @@ static int ircomm_tty_read_proc(char *buf, char **start, off_t offset, int len, #endif /* CONFIG_PROC_FS */ static struct tty_driver *driver; -hashbin_t *ircomm_tty = NULL; +static hashbin_t *ircomm_tty = NULL; static const struct tty_operations ops = { .open = ircomm_tty_open, -- cgit v0.10.2 From 0f79efdc23bd82035625083adf441e063a61f170 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 26 Oct 2007 03:57:36 -0700 Subject: [TCP]: Make tcp_match_skb_to_sack() static. tcp_match_skb_to_sack() can become static. Signed-off-by: Adrian Bunk Signed-off-by: David S. Miller diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 47f4f35..457697a 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -1204,8 +1204,8 @@ static int tcp_check_dsack(struct tcp_sock *tp, struct sk_buff *ack_skb, * which may fail and creates some hassle (caller must handle error case * returns). */ -int tcp_match_skb_to_sack(struct sock *sk, struct sk_buff *skb, - u32 start_seq, u32 end_seq) +static int tcp_match_skb_to_sack(struct sock *sk, struct sk_buff *skb, + u32 start_seq, u32 end_seq) { int in_sack, err; unsigned int pkt_len; -- cgit v0.10.2 From bbbb1a812de596958163779ae5b0806bc53a83f4 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 26 Oct 2007 03:59:45 -0700 Subject: [NET]: Unexport sock_enable_timestamp(). sock_enable_timestamp() no longer has any modular users. Signed-off-by: Adrian Bunk Signed-off-by: David S. Miller diff --git a/net/core/sock.c b/net/core/sock.c index febbcbc..bba9949 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. -- cgit v0.10.2 From 39296ed6699df34fdfbf1b14281c07321a079a3d Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 26 Oct 2007 04:06:08 -0700 Subject: [INET]: Unexport icmpmsg_statistics This patch removes the unused EXPORT_SYMBOL(icmpmsg_statistics). Signed-off-by: Adrian Bunk Signed-off-by: David S. Miller diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 272c69e..233de06 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -1104,5 +1104,4 @@ void __init icmp_init(struct net_proto_family *ops) EXPORT_SYMBOL(icmp_err_convert); EXPORT_SYMBOL(icmp_send); EXPORT_SYMBOL(icmp_statistics); -EXPORT_SYMBOL(icmpmsg_statistics); EXPORT_SYMBOL(xrlim_allow); -- cgit v0.10.2 From d84d64dcb3b54c900113f8dcd1240205ae164922 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 26 Oct 2007 04:07:20 -0700 Subject: [SCTP]: #if 0 sctp_update_copy_cksum() sctp_update_copy_cksum() is no longer used. Signed-off-by: Adrian Bunk Acked-by: Vlad Yasevich Signed-off-by: David S. Miller diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index 119f5a1..93eb708 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/sctp/crc32c.c b/net/sctp/crc32c.c index 59cf7b0..181edab 100644 --- a/net/sctp/crc32c.c +++ b/net/sctp/crc32c.c @@ -170,6 +170,7 @@ __u32 sctp_update_cksum(__u8 *buffer, __u16 length, __u32 crc32) return crc32; } +#if 0 __u32 sctp_update_copy_cksum(__u8 *to, __u8 *from, __u16 length, __u32 crc32) { __u32 i; @@ -186,6 +187,7 @@ __u32 sctp_update_copy_cksum(__u8 *to, __u8 *from, __u16 length, __u32 crc32) return crc32; } +#endif /* 0 */ __u32 sctp_end_cksum(__u32 crc32) { -- cgit v0.10.2 From b4caea8aa8b4caeda2af6ef6b7f0d43c516815ee Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 26 Oct 2007 04:20:13 -0700 Subject: [TCP]: Add missing I/O AT code to ipv6 side. Signed-off-by: David S. Miller diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 32dc3297..06fa4ba 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1732,6 +1732,8 @@ process: if (!sock_owned_by_user(sk)) { #ifdef CONFIG_NET_DMA struct tcp_sock *tp = tcp_sk(sk); + if (!tp->ucopy.dma_chan && tp->ucopy.pinned_list) + tp->ucopy.dma_chan = get_softnet_dma(); if (tp->ucopy.dma_chan) ret = tcp_v6_do_rcv(sk, skb); else -- cgit v0.10.2 From 8ad7c62b752483982a678c78a52a70f498b84cbb Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 26 Oct 2007 04:21:23 -0700 Subject: [SCTP] net/sctp/auth.c: make 3 functions static This patch makes three needlessly global functions static. Signed-off-by: Adrian Bunk Acked-by: Vlad Yasevich Signed-off-by: David S. Miller diff --git a/include/net/sctp/auth.h b/include/net/sctp/auth.h index 4945954..9e8f13b 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/net/sctp/auth.c b/net/sctp/auth.c index 621113a..c9dbc3a 100644 --- a/net/sctp/auth.c +++ b/net/sctp/auth.c @@ -107,7 +107,7 @@ struct sctp_shared_key *sctp_auth_shkey_create(__u16 key_id, gfp_t gfp) } /* Free the shared key stucture */ -void sctp_auth_shkey_free(struct sctp_shared_key *sh_key) +static void sctp_auth_shkey_free(struct sctp_shared_key *sh_key) { BUG_ON(!list_empty(&sh_key->key_list)); sctp_auth_key_put(sh_key->key); @@ -220,7 +220,7 @@ static struct sctp_auth_bytes *sctp_auth_make_key_vector( /* Make a key vector based on our local parameters */ -struct sctp_auth_bytes *sctp_auth_make_local_vector( +static struct sctp_auth_bytes *sctp_auth_make_local_vector( const struct sctp_association *asoc, gfp_t gfp) { @@ -232,7 +232,7 @@ struct sctp_auth_bytes *sctp_auth_make_local_vector( } /* Make a key vector based on peer's parameters */ -struct sctp_auth_bytes *sctp_auth_make_peer_vector( +static struct sctp_auth_bytes *sctp_auth_make_peer_vector( const struct sctp_association *asoc, gfp_t gfp) { -- cgit v0.10.2 From 43cc7380eced27ee9cafdf89fa32333dc3884e8b Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Fri, 26 Oct 2007 04:23:22 -0700 Subject: [NET] napi: use non-interruptible sleep in napi_disable The current napi_disable() uses msleep_interruptible() but doesn't (and can't) exit in case there's a signal, thus ending up doing a hot spin without a cpu_relax. Use uninterruptible sleep instead. Signed-off-by: Benjamin Herrenschmidt Acked-by: Jeff Garzik Signed-off-by: David S. Miller diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 811024e..9b0c8f1 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); } /** -- cgit v0.10.2 From 94d3b1e586f6d4c7150501bde284c544ce99073c Mon Sep 17 00:00:00 2001 From: Ryousei Takano Date: Fri, 26 Oct 2007 04:27:59 -0700 Subject: [TCP]: fix D-SACK cwnd handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the current net-2.6 kernel, handling FLAG_DSACKING_ACK is broken. The flag is cleared to 1 just after FLAG_DSACKING_ACK is set. if (found_dup_sack) flag |= FLAG_DSACKING_ACK; : flag = 1; To fix it, this patch introduces a part of the tcp_sacktag_state patch: http://marc.info/?l=linux-netdev&m=119210560431519&w=2 Signed-off-by: Ryousei Takano Signed-off-by: Ilpo Järvinen Signed-off-by: David S. Miller diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 457697a..69d8c38 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -1248,6 +1248,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ int cached_fack_count; int i; int first_sack_index; + int force_one_sack; if (!tp->sacked_out) { if (WARN_ON(tp->fackets_out)) @@ -1272,18 +1273,18 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ * if the only SACK change is the increase of the end_seq of * the first block then only apply that SACK block * and use retrans queue hinting otherwise slowpath */ - flag = 1; + force_one_sack = 1; for (i = 0; i < num_sacks; i++) { __be32 start_seq = sp[i].start_seq; __be32 end_seq = sp[i].end_seq; if (i == 0) { if (tp->recv_sack_cache[i].start_seq != start_seq) - flag = 0; + force_one_sack = 0; } else { if ((tp->recv_sack_cache[i].start_seq != start_seq) || (tp->recv_sack_cache[i].end_seq != end_seq)) - flag = 0; + force_one_sack = 0; } tp->recv_sack_cache[i].start_seq = start_seq; tp->recv_sack_cache[i].end_seq = end_seq; @@ -1295,7 +1296,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ } first_sack_index = 0; - if (flag) + if (force_one_sack) num_sacks = 1; else { int j; @@ -1321,9 +1322,6 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ } } - /* clear flag as used for different purpose in following code */ - flag = 0; - /* Use SACK fastpath hint if valid */ cached_skb = tp->fastpath_skb_hint; cached_fack_count = tp->fastpath_cnt_hint; -- cgit v0.10.2 From 4be2700fb7b95f2a7cef9324879cafccab8774fc Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Fri, 26 Oct 2007 04:29:08 -0700 Subject: [NetLabel]: correct usage of RCU locking This fixes some awkward, and perhaps even problematic, RCU lock usage in the NetLabel code as well as some other related trivial cleanups found when looking through the RCU locking. Most of the changes involve removing the redundant RCU read locks wrapping spinlocks in the case of a RCU writer. Signed-off-by: Paul Moore Signed-off-by: David S. Miller diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index 805a78e6..f18e88b 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c @@ -504,22 +504,16 @@ int cipso_v4_doi_add(struct cipso_v4_doi *doi_def) INIT_RCU_HEAD(&doi_def->rcu); INIT_LIST_HEAD(&doi_def->dom_list); - rcu_read_lock(); - if (cipso_v4_doi_search(doi_def->doi) != NULL) - goto doi_add_failure_rlock; spin_lock(&cipso_v4_doi_list_lock); if (cipso_v4_doi_search(doi_def->doi) != NULL) - goto doi_add_failure_slock; + goto doi_add_failure; list_add_tail_rcu(&doi_def->list, &cipso_v4_doi_list); spin_unlock(&cipso_v4_doi_list_lock); - rcu_read_unlock(); return 0; -doi_add_failure_slock: +doi_add_failure: spin_unlock(&cipso_v4_doi_list_lock); -doi_add_failure_rlock: - rcu_read_unlock(); return -EEXIST; } @@ -543,29 +537,23 @@ int cipso_v4_doi_remove(u32 doi, struct cipso_v4_doi *doi_def; struct cipso_v4_domhsh_entry *dom_iter; - rcu_read_lock(); - if (cipso_v4_doi_search(doi) != NULL) { - spin_lock(&cipso_v4_doi_list_lock); - doi_def = cipso_v4_doi_search(doi); - if (doi_def == NULL) { - spin_unlock(&cipso_v4_doi_list_lock); - rcu_read_unlock(); - return -ENOENT; - } + spin_lock(&cipso_v4_doi_list_lock); + doi_def = cipso_v4_doi_search(doi); + if (doi_def != NULL) { doi_def->valid = 0; list_del_rcu(&doi_def->list); spin_unlock(&cipso_v4_doi_list_lock); + rcu_read_lock(); list_for_each_entry_rcu(dom_iter, &doi_def->dom_list, list) if (dom_iter->valid) netlbl_domhsh_remove(dom_iter->domain, audit_info); - cipso_v4_cache_invalidate(); rcu_read_unlock(); - + cipso_v4_cache_invalidate(); call_rcu(&doi_def->rcu, callback); return 0; } - rcu_read_unlock(); + spin_unlock(&cipso_v4_doi_list_lock); return -ENOENT; } @@ -653,22 +641,19 @@ int cipso_v4_doi_domhsh_add(struct cipso_v4_doi *doi_def, const char *domain) new_dom->valid = 1; INIT_RCU_HEAD(&new_dom->rcu); - rcu_read_lock(); spin_lock(&cipso_v4_doi_list_lock); - list_for_each_entry_rcu(iter, &doi_def->dom_list, list) + list_for_each_entry(iter, &doi_def->dom_list, list) if (iter->valid && ((domain != NULL && iter->domain != NULL && strcmp(iter->domain, domain) == 0) || (domain == NULL && iter->domain == NULL))) { spin_unlock(&cipso_v4_doi_list_lock); - rcu_read_unlock(); kfree(new_dom->domain); kfree(new_dom); return -EEXIST; } list_add_tail_rcu(&new_dom->list, &doi_def->dom_list); spin_unlock(&cipso_v4_doi_list_lock); - rcu_read_unlock(); return 0; } @@ -689,9 +674,8 @@ int cipso_v4_doi_domhsh_remove(struct cipso_v4_doi *doi_def, { struct cipso_v4_domhsh_entry *iter; - rcu_read_lock(); spin_lock(&cipso_v4_doi_list_lock); - list_for_each_entry_rcu(iter, &doi_def->dom_list, list) + list_for_each_entry(iter, &doi_def->dom_list, list) if (iter->valid && ((domain != NULL && iter->domain != NULL && strcmp(iter->domain, domain) == 0) || @@ -699,13 +683,10 @@ int cipso_v4_doi_domhsh_remove(struct cipso_v4_doi *doi_def, iter->valid = 0; list_del_rcu(&iter->list); spin_unlock(&cipso_v4_doi_list_lock); - rcu_read_unlock(); call_rcu(&iter->rcu, cipso_v4_doi_domhsh_free); - return 0; } spin_unlock(&cipso_v4_doi_list_lock); - rcu_read_unlock(); return -ENOENT; } diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c index b6c844b..b3675bd 100644 --- a/net/netlabel/netlabel_domainhash.c +++ b/net/netlabel/netlabel_domainhash.c @@ -178,11 +178,9 @@ int netlbl_domhsh_init(u32 size) for (iter = 0; iter < hsh_tbl->size; iter++) INIT_LIST_HEAD(&hsh_tbl->tbl[iter]); - rcu_read_lock(); spin_lock(&netlbl_domhsh_lock); rcu_assign_pointer(netlbl_domhsh, hsh_tbl); spin_unlock(&netlbl_domhsh_lock); - rcu_read_unlock(); return 0; } @@ -222,7 +220,6 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, entry->valid = 1; INIT_RCU_HEAD(&entry->rcu); - ret_val = 0; rcu_read_lock(); if (entry->domain != NULL) { bkt = netlbl_domhsh_hash(entry->domain); @@ -233,7 +230,7 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, else ret_val = -EEXIST; spin_unlock(&netlbl_domhsh_lock); - } else if (entry->domain == NULL) { + } else { INIT_LIST_HEAD(&entry->list); spin_lock(&netlbl_domhsh_def_lock); if (rcu_dereference(netlbl_domhsh_def) == NULL) @@ -241,9 +238,7 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, else ret_val = -EEXIST; spin_unlock(&netlbl_domhsh_def_lock); - } else - ret_val = -EINVAL; - + } audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_ADD, audit_info); if (audit_buf != NULL) { audit_log_format(audit_buf, @@ -262,7 +257,6 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0); audit_log_end(audit_buf); } - rcu_read_unlock(); if (ret_val != 0) { @@ -313,38 +307,30 @@ int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info) struct audit_buffer *audit_buf; rcu_read_lock(); - if (domain != NULL) - entry = netlbl_domhsh_search(domain, 0); - else - entry = netlbl_domhsh_search(domain, 1); + entry = netlbl_domhsh_search(domain, (domain != NULL ? 0 : 1)); if (entry == NULL) goto remove_return; switch (entry->type) { - case NETLBL_NLTYPE_UNLABELED: - break; case NETLBL_NLTYPE_CIPSOV4: - ret_val = cipso_v4_doi_domhsh_remove(entry->type_def.cipsov4, - entry->domain); - if (ret_val != 0) - goto remove_return; + cipso_v4_doi_domhsh_remove(entry->type_def.cipsov4, + entry->domain); break; } - ret_val = 0; if (entry != rcu_dereference(netlbl_domhsh_def)) { spin_lock(&netlbl_domhsh_lock); if (entry->valid) { entry->valid = 0; list_del_rcu(&entry->list); - } else - ret_val = -ENOENT; + ret_val = 0; + } spin_unlock(&netlbl_domhsh_lock); } else { spin_lock(&netlbl_domhsh_def_lock); if (entry->valid) { entry->valid = 0; rcu_assign_pointer(netlbl_domhsh_def, NULL); - } else - ret_val = -ENOENT; + ret_val = 0; + } spin_unlock(&netlbl_domhsh_def_lock); } @@ -357,11 +343,10 @@ int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info) audit_log_end(audit_buf); } - if (ret_val == 0) - call_rcu(&entry->rcu, netlbl_domhsh_free_entry); - remove_return: rcu_read_unlock(); + if (ret_val == 0) + call_rcu(&entry->rcu, netlbl_domhsh_free_entry); return ret_val; } diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c index 5315dac..5648337 100644 --- a/net/netlabel/netlabel_mgmt.c +++ b/net/netlabel/netlabel_mgmt.c @@ -85,11 +85,9 @@ static const struct nla_policy netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = { */ void netlbl_mgmt_protocount_inc(void) { - rcu_read_lock(); spin_lock(&netlabel_mgmt_protocount_lock); netlabel_mgmt_protocount++; spin_unlock(&netlabel_mgmt_protocount_lock); - rcu_read_unlock(); } /** @@ -103,12 +101,10 @@ void netlbl_mgmt_protocount_inc(void) */ void netlbl_mgmt_protocount_dec(void) { - rcu_read_lock(); spin_lock(&netlabel_mgmt_protocount_lock); if (netlabel_mgmt_protocount > 0) netlabel_mgmt_protocount--; spin_unlock(&netlabel_mgmt_protocount_lock); - rcu_read_unlock(); } /** diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 5c303c68a..3482924 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -84,12 +84,10 @@ static void netlbl_unlabel_acceptflg_set(u8 value, struct audit_buffer *audit_buf; u8 old_val; - rcu_read_lock(); - old_val = netlabel_unlabel_acceptflg; spin_lock(&netlabel_unlabel_acceptflg_lock); + old_val = netlabel_unlabel_acceptflg; netlabel_unlabel_acceptflg = value; spin_unlock(&netlabel_unlabel_acceptflg_lock); - rcu_read_unlock(); audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_ALLOW, audit_info); -- cgit v0.10.2