Skip to content

Commit

Permalink
ipv6: tcp: fix TCLASS value in ACK messages sent from TIME_WAIT
Browse files Browse the repository at this point in the history
commit 66b13d9 (ipv4: tcp: fix TOS value in ACK messages sent from
TIME_WAIT) fixed IPv4 only.

This part is for the IPv6 side, adding a tclass param to ip6_xmit()

We alias tw_tclass and tw_tos, if socket family is INET6.

[ if sockets is ipv4-mapped, only IP_TOS socket option is used to fill
TOS field, TCLASS is not taken into account ]

Signed-off-by: Eric Dumazet <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
Eric Dumazet authored and davem330 committed Oct 27, 2011
1 parent 138c4ae commit b903d32
Show file tree
Hide file tree
Showing 8 changed files with 19 additions and 18 deletions.
1 change: 1 addition & 0 deletions include/net/inet_timewait_sock.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ struct inet_timewait_sock {
struct inet_bind_bucket *tw_tb;
struct hlist_node tw_death_node;
};
#define tw_tclass tw_tos

static inline void inet_twsk_add_node_rcu(struct inet_timewait_sock *tw,
struct hlist_nulls_head *list)
Expand Down
3 changes: 2 additions & 1 deletion include/net/ipv6.h
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,8 @@ extern int ip6_rcv_finish(struct sk_buff *skb);
extern int ip6_xmit(struct sock *sk,
struct sk_buff *skb,
struct flowi6 *fl6,
struct ipv6_txoptions *opt);
struct ipv6_txoptions *opt,
int tclass);

extern int ip6_nd_hdr(struct sock *sk,
struct sk_buff *skb,
Expand Down
4 changes: 2 additions & 2 deletions net/dccp/ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req,
&ireq6->loc_addr,
&ireq6->rmt_addr);
ipv6_addr_copy(&fl6.daddr, &ireq6->rmt_addr);
err = ip6_xmit(sk, skb, &fl6, opt);
err = ip6_xmit(sk, skb, &fl6, opt, np->tclass);
err = net_xmit_eval(err);
}

Expand Down Expand Up @@ -326,7 +326,7 @@ static void dccp_v6_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb)
dst = ip6_dst_lookup_flow(ctl_sk, &fl6, NULL, false);
if (!IS_ERR(dst)) {
skb_dst_set(skb, dst);
ip6_xmit(ctl_sk, skb, &fl6, NULL);
ip6_xmit(ctl_sk, skb, &fl6, NULL, 0);
DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS);
DCCP_INC_STATS_BH(DCCP_MIB_OUTRSTS);
return;
Expand Down
1 change: 1 addition & 0 deletions net/ipv4/tcp_minisocks.c
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo)
tw6 = inet6_twsk((struct sock *)tw);
ipv6_addr_copy(&tw6->tw_v6_daddr, &np->daddr);
ipv6_addr_copy(&tw6->tw_v6_rcv_saddr, &np->rcv_saddr);
tw->tw_tclass = np->tclass;
tw->tw_ipv6only = np->ipv6only;
}
#endif
Expand Down
2 changes: 1 addition & 1 deletion net/ipv6/inet6_connection_sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused)
/* Restore final destination back after routing done */
ipv6_addr_copy(&fl6.daddr, &np->daddr);

res = ip6_xmit(sk, skb, &fl6, np->opt);
res = ip6_xmit(sk, skb, &fl6, np->opt, np->tclass);
rcu_read_unlock();
return res;
}
Expand Down
7 changes: 2 additions & 5 deletions net/ipv6/ip6_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ int ip6_output(struct sk_buff *skb)
*/

int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6,
struct ipv6_txoptions *opt)
struct ipv6_txoptions *opt, int tclass)
{
struct net *net = sock_net(sk);
struct ipv6_pinfo *np = inet6_sk(sk);
Expand All @@ -190,7 +190,6 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6,
u8 proto = fl6->flowi6_proto;
int seg_len = skb->len;
int hlimit = -1;
int tclass = 0;
u32 mtu;

if (opt) {
Expand Down Expand Up @@ -228,10 +227,8 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6,
/*
* Fill in the IPv6 header
*/
if (np) {
tclass = np->tclass;
if (np)
hlimit = np->hop_limit;
}
if (hlimit < 0)
hlimit = ip6_dst_hoplimit(dst);

Expand Down
17 changes: 9 additions & 8 deletions net/ipv6/tcp_ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
__tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr);

ipv6_addr_copy(&fl6.daddr, &treq->rmt_addr);
err = ip6_xmit(sk, skb, &fl6, opt);
err = ip6_xmit(sk, skb, &fl6, opt, np->tclass);
err = net_xmit_eval(err);
}

Expand Down Expand Up @@ -979,7 +979,7 @@ static int tcp6_gro_complete(struct sk_buff *skb)
}

static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
u32 ts, struct tcp_md5sig_key *key, int rst)
u32 ts, struct tcp_md5sig_key *key, int rst, u8 tclass)
{
const struct tcphdr *th = tcp_hdr(skb);
struct tcphdr *t1;
Expand Down Expand Up @@ -1060,7 +1060,7 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
dst = ip6_dst_lookup_flow(ctl_sk, &fl6, NULL, false);
if (!IS_ERR(dst)) {
skb_dst_set(buff, dst);
ip6_xmit(ctl_sk, buff, &fl6, NULL);
ip6_xmit(ctl_sk, buff, &fl6, NULL, tclass);
TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS);
if (rst)
TCP_INC_STATS_BH(net, TCP_MIB_OUTRSTS);
Expand Down Expand Up @@ -1093,13 +1093,13 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb)
ack_seq = ntohl(th->seq) + th->syn + th->fin + skb->len -
(th->doff << 2);

tcp_v6_send_response(skb, seq, ack_seq, 0, 0, key, 1);
tcp_v6_send_response(skb, seq, ack_seq, 0, 0, key, 1, 0);
}

static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts,
struct tcp_md5sig_key *key)
struct tcp_md5sig_key *key, u8 tclass)
{
tcp_v6_send_response(skb, seq, ack, win, ts, key, 0);
tcp_v6_send_response(skb, seq, ack, win, ts, key, 0, tclass);
}

static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)
Expand All @@ -1109,7 +1109,8 @@ static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)

tcp_v6_send_ack(skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
tcptw->tw_ts_recent, tcp_twsk_md5_key(tcptw));
tcptw->tw_ts_recent, tcp_twsk_md5_key(tcptw),
tw->tw_tclass);

inet_twsk_put(tw);
}
Expand All @@ -1118,7 +1119,7 @@ static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
struct request_sock *req)
{
tcp_v6_send_ack(skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent,
tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr));
tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr), 0);
}


Expand Down
2 changes: 1 addition & 1 deletion net/sctp/ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport)
if (!(transport->param_flags & SPP_PMTUD_ENABLE))
skb->local_df = 1;

return ip6_xmit(sk, skb, &fl6, np->opt);
return ip6_xmit(sk, skb, &fl6, np->opt, np->tclass);
}

/* Returns the dst cache entry for the given source and destination ip
Expand Down

0 comments on commit b903d32

Please sign in to comment.