ipv6: tcp: fix TCLASS value in ACK messages sent from TIME_WAIT
commit 66b13d99d9
(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 <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
138c4ae9cf
Коммит
b903d324be
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче