aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlpo Järvinen <ilpo.jarvinen@helsinki.fi>2008-01-03 23:39:01 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:00:34 -0500
commite870a8efcddaaa3da7e180b6ae21239fb96aa2bb (patch)
treed7e5930e78eb1c81ac10c59e0f74b89188e8abf7
parent19773b4923ed0e21e3289361dba5e69e1ce6e00b (diff)
[TCP]: Perform setting of common control fields in one place
In case of segments which are purely for control without any data (SYN/ACK/FIN/RST), many fields are set to common values in multiple places. i386 results: $ gcc --version gcc (GCC) 4.1.2 20070626 (Red Hat 4.1.2-13) $ codiff tcp_output.o.old tcp_output.o.new net/ipv4/tcp_output.c: tcp_xmit_probe_skb | -48 tcp_send_ack | -56 tcp_retransmit_skb | -79 tcp_connect | -43 tcp_send_active_reset | -35 tcp_make_synack | -42 tcp_send_fin | -48 7 functions changed, 351 bytes removed net/ipv4/tcp_output.c: tcp_init_nondata_skb | +90 1 function changed, 90 bytes added tcp_output.o.mid: 8 functions changed, 90 bytes added, 351 bytes removed, diff: -261 Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/ipv4/tcp_output.c91
1 files changed, 36 insertions, 55 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 6c7cd0a9098a..89f0188885c7 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -327,6 +327,26 @@ static inline void TCP_ECN_send(struct sock *sk, struct sk_buff *skb,
327 } 327 }
328} 328}
329 329
330/* Constructs common control bits of non-data skb. If SYN/FIN is present,
331 * auto increment end seqno.
332 */
333static void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags)
334{
335 skb->csum = 0;
336
337 TCP_SKB_CB(skb)->flags = flags;
338 TCP_SKB_CB(skb)->sacked = 0;
339
340 skb_shinfo(skb)->gso_segs = 1;
341 skb_shinfo(skb)->gso_size = 0;
342 skb_shinfo(skb)->gso_type = 0;
343
344 TCP_SKB_CB(skb)->seq = seq;
345 if (flags & (TCPCB_FLAG_SYN | TCPCB_FLAG_FIN))
346 seq++;
347 TCP_SKB_CB(skb)->end_seq = seq;
348}
349
330static void tcp_build_and_update_options(__be32 *ptr, struct tcp_sock *tp, 350static void tcp_build_and_update_options(__be32 *ptr, struct tcp_sock *tp,
331 __u32 tstamp, __u8 **md5_hash) 351 __u32 tstamp, __u8 **md5_hash)
332{ 352{
@@ -1864,12 +1884,10 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
1864 (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) && 1884 (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) &&
1865 tp->snd_una == (TCP_SKB_CB(skb)->end_seq - 1)) { 1885 tp->snd_una == (TCP_SKB_CB(skb)->end_seq - 1)) {
1866 if (!pskb_trim(skb, 0)) { 1886 if (!pskb_trim(skb, 0)) {
1867 TCP_SKB_CB(skb)->seq = TCP_SKB_CB(skb)->end_seq - 1; 1887 /* Reuse, even though it does some unnecessary work */
1868 skb_shinfo(skb)->gso_segs = 1; 1888 tcp_init_nondata_skb(skb, TCP_SKB_CB(skb)->end_seq - 1,
1869 skb_shinfo(skb)->gso_size = 0; 1889 TCP_SKB_CB(skb)->flags);
1870 skb_shinfo(skb)->gso_type = 0;
1871 skb->ip_summed = CHECKSUM_NONE; 1890 skb->ip_summed = CHECKSUM_NONE;
1872 skb->csum = 0;
1873 } 1891 }
1874 } 1892 }
1875 1893
@@ -2068,16 +2086,9 @@ void tcp_send_fin(struct sock *sk)
2068 2086
2069 /* Reserve space for headers and prepare control bits. */ 2087 /* Reserve space for headers and prepare control bits. */
2070 skb_reserve(skb, MAX_TCP_HEADER); 2088 skb_reserve(skb, MAX_TCP_HEADER);
2071 skb->csum = 0;
2072 TCP_SKB_CB(skb)->flags = (TCPCB_FLAG_ACK | TCPCB_FLAG_FIN);
2073 TCP_SKB_CB(skb)->sacked = 0;
2074 skb_shinfo(skb)->gso_segs = 1;
2075 skb_shinfo(skb)->gso_size = 0;
2076 skb_shinfo(skb)->gso_type = 0;
2077
2078 /* FIN eats a sequence byte, write_seq advanced by tcp_queue_skb(). */ 2089 /* FIN eats a sequence byte, write_seq advanced by tcp_queue_skb(). */
2079 TCP_SKB_CB(skb)->seq = tp->write_seq; 2090 tcp_init_nondata_skb(skb, tp->write_seq,
2080 TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + 1; 2091 TCPCB_FLAG_ACK | TCPCB_FLAG_FIN);
2081 tcp_queue_skb(sk, skb); 2092 tcp_queue_skb(sk, skb);
2082 } 2093 }
2083 __tcp_push_pending_frames(sk, mss_now, TCP_NAGLE_OFF); 2094 __tcp_push_pending_frames(sk, mss_now, TCP_NAGLE_OFF);
@@ -2101,16 +2112,9 @@ void tcp_send_active_reset(struct sock *sk, gfp_t priority)
2101 2112
2102 /* Reserve space for headers and prepare control bits. */ 2113 /* Reserve space for headers and prepare control bits. */
2103 skb_reserve(skb, MAX_TCP_HEADER); 2114 skb_reserve(skb, MAX_TCP_HEADER);
2104 skb->csum = 0; 2115 tcp_init_nondata_skb(skb, tcp_acceptable_seq(sk),
2105 TCP_SKB_CB(skb)->flags = (TCPCB_FLAG_ACK | TCPCB_FLAG_RST); 2116 TCPCB_FLAG_ACK | TCPCB_FLAG_RST);
2106 TCP_SKB_CB(skb)->sacked = 0;
2107 skb_shinfo(skb)->gso_segs = 1;
2108 skb_shinfo(skb)->gso_size = 0;
2109 skb_shinfo(skb)->gso_type = 0;
2110
2111 /* Send it off. */ 2117 /* Send it off. */
2112 TCP_SKB_CB(skb)->seq = tcp_acceptable_seq(sk);
2113 TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq;
2114 TCP_SKB_CB(skb)->when = tcp_time_stamp; 2118 TCP_SKB_CB(skb)->when = tcp_time_stamp;
2115 if (tcp_transmit_skb(sk, skb, 0, priority)) 2119 if (tcp_transmit_skb(sk, skb, 0, priority))
2116 NET_INC_STATS(LINUX_MIB_TCPABORTFAILED); 2120 NET_INC_STATS(LINUX_MIB_TCPABORTFAILED);
@@ -2198,12 +2202,11 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
2198 TCP_ECN_make_synack(req, th); 2202 TCP_ECN_make_synack(req, th);
2199 th->source = inet_sk(sk)->sport; 2203 th->source = inet_sk(sk)->sport;
2200 th->dest = ireq->rmt_port; 2204 th->dest = ireq->rmt_port;
2201 TCP_SKB_CB(skb)->seq = tcp_rsk(req)->snt_isn; 2205 /* Setting of flags are superfluous here for callers (and ECE is
2202 TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + 1; 2206 * not even correctly set)
2203 TCP_SKB_CB(skb)->sacked = 0; 2207 */
2204 skb_shinfo(skb)->gso_segs = 1; 2208 tcp_init_nondata_skb(skb, tcp_rsk(req)->snt_isn,
2205 skb_shinfo(skb)->gso_size = 0; 2209 TCPCB_FLAG_SYN | TCPCB_FLAG_ACK);
2206 skb_shinfo(skb)->gso_type = 0;
2207 th->seq = htonl(TCP_SKB_CB(skb)->seq); 2210 th->seq = htonl(TCP_SKB_CB(skb)->seq);
2208 th->ack_seq = htonl(tcp_rsk(req)->rcv_isn + 1); 2211 th->ack_seq = htonl(tcp_rsk(req)->rcv_isn + 1);
2209 if (req->rcv_wnd == 0) { /* ignored for retransmitted syns */ 2212 if (req->rcv_wnd == 0) { /* ignored for retransmitted syns */
@@ -2235,7 +2238,6 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
2235 NULL) 2238 NULL)
2236 ); 2239 );
2237 2240
2238 skb->csum = 0;
2239 th->doff = (tcp_header_size >> 2); 2241 th->doff = (tcp_header_size >> 2);
2240 TCP_INC_STATS(TCP_MIB_OUTSEGS); 2242 TCP_INC_STATS(TCP_MIB_OUTSEGS);
2241 2243
@@ -2327,16 +2329,9 @@ int tcp_connect(struct sock *sk)
2327 /* Reserve space for headers. */ 2329 /* Reserve space for headers. */
2328 skb_reserve(buff, MAX_TCP_HEADER); 2330 skb_reserve(buff, MAX_TCP_HEADER);
2329 2331
2330 TCP_SKB_CB(buff)->flags = TCPCB_FLAG_SYN;
2331 TCP_ECN_send_syn(sk, buff);
2332 TCP_SKB_CB(buff)->sacked = 0;
2333 skb_shinfo(buff)->gso_segs = 1;
2334 skb_shinfo(buff)->gso_size = 0;
2335 skb_shinfo(buff)->gso_type = 0;
2336 buff->csum = 0;
2337 tp->snd_nxt = tp->write_seq; 2332 tp->snd_nxt = tp->write_seq;
2338 TCP_SKB_CB(buff)->seq = tp->write_seq++; 2333 tcp_init_nondata_skb(buff, tp->write_seq++, TCPCB_FLAG_SYN);
2339 TCP_SKB_CB(buff)->end_seq = tp->write_seq; 2334 TCP_ECN_send_syn(sk, buff);
2340 2335
2341 /* Send it off. */ 2336 /* Send it off. */
2342 TCP_SKB_CB(buff)->when = tcp_time_stamp; 2337 TCP_SKB_CB(buff)->when = tcp_time_stamp;
@@ -2441,15 +2436,9 @@ void tcp_send_ack(struct sock *sk)
2441 2436
2442 /* Reserve space for headers and prepare control bits. */ 2437 /* Reserve space for headers and prepare control bits. */
2443 skb_reserve(buff, MAX_TCP_HEADER); 2438 skb_reserve(buff, MAX_TCP_HEADER);
2444 buff->csum = 0; 2439 tcp_init_nondata_skb(buff, tcp_acceptable_seq(sk), TCPCB_FLAG_ACK);
2445 TCP_SKB_CB(buff)->flags = TCPCB_FLAG_ACK;
2446 TCP_SKB_CB(buff)->sacked = 0;
2447 skb_shinfo(buff)->gso_segs = 1;
2448 skb_shinfo(buff)->gso_size = 0;
2449 skb_shinfo(buff)->gso_type = 0;
2450 2440
2451 /* Send it off, this clears delayed acks for us. */ 2441 /* Send it off, this clears delayed acks for us. */
2452 TCP_SKB_CB(buff)->seq = TCP_SKB_CB(buff)->end_seq = tcp_acceptable_seq(sk);
2453 TCP_SKB_CB(buff)->when = tcp_time_stamp; 2442 TCP_SKB_CB(buff)->when = tcp_time_stamp;
2454 tcp_transmit_skb(sk, buff, 0, GFP_ATOMIC); 2443 tcp_transmit_skb(sk, buff, 0, GFP_ATOMIC);
2455} 2444}
@@ -2477,19 +2466,11 @@ static int tcp_xmit_probe_skb(struct sock *sk, int urgent)
2477 2466
2478 /* Reserve space for headers and set control bits. */ 2467 /* Reserve space for headers and set control bits. */
2479 skb_reserve(skb, MAX_TCP_HEADER); 2468 skb_reserve(skb, MAX_TCP_HEADER);
2480 skb->csum = 0;
2481 TCP_SKB_CB(skb)->flags = TCPCB_FLAG_ACK;
2482 TCP_SKB_CB(skb)->sacked = 0;
2483 skb_shinfo(skb)->gso_segs = 1;
2484 skb_shinfo(skb)->gso_size = 0;
2485 skb_shinfo(skb)->gso_type = 0;
2486
2487 /* Use a previous sequence. This should cause the other 2469 /* Use a previous sequence. This should cause the other
2488 * end to send an ack. Don't queue or clone SKB, just 2470 * end to send an ack. Don't queue or clone SKB, just
2489 * send it. 2471 * send it.
2490 */ 2472 */
2491 TCP_SKB_CB(skb)->seq = tp->snd_una - !urgent; 2473 tcp_init_nondata_skb(skb, tp->snd_una - !urgent, TCPCB_FLAG_ACK);
2492 TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq;
2493 TCP_SKB_CB(skb)->when = tcp_time_stamp; 2474 TCP_SKB_CB(skb)->when = tcp_time_stamp;
2494 return tcp_transmit_skb(sk, skb, 0, GFP_ATOMIC); 2475 return tcp_transmit_skb(sk, skb, 0, GFP_ATOMIC);
2495} 2476}