Loading include/net/inet6_connection_sock.h +2 −0 Original line number Diff line number Diff line Loading @@ -43,4 +43,6 @@ extern void inet6_csk_reqsk_queue_hash_add(struct sock *sk, extern void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr); extern int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl); extern struct dst_entry *inet6_csk_update_pmtu(struct sock *sk, u32 mtu); #endif /* _INET6_CONNECTION_SOCK_H */ net/dccp/ipv6.c +4 −31 Original line number Diff line number Diff line Loading @@ -145,39 +145,12 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, if ((1 << sk->sk_state) & (DCCPF_LISTEN | DCCPF_CLOSED)) goto out; /* icmp should have updated the destination cache entry */ dst = __sk_dst_check(sk, np->dst_cookie); if (dst == NULL) { struct inet_sock *inet = inet_sk(sk); struct flowi6 fl6; /* BUGGG_FUTURE: Again, it is not clear how to handle rthdr case. Ignore this complexity for now. */ memset(&fl6, 0, sizeof(fl6)); fl6.flowi6_proto = IPPROTO_DCCP; fl6.daddr = np->daddr; fl6.saddr = np->saddr; fl6.flowi6_oif = sk->sk_bound_dev_if; fl6.fl6_dport = inet->inet_dport; fl6.fl6_sport = inet->inet_sport; security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); dst = ip6_dst_lookup_flow(sk, &fl6, NULL, false); if (IS_ERR(dst)) { sk->sk_err_soft = -PTR_ERR(dst); dst = inet6_csk_update_pmtu(sk, ntohl(info)); if (!dst) goto out; } } else dst_hold(dst); dst->ops->update_pmtu(dst, ntohl(info)); if (inet_csk(sk)->icsk_pmtu_cookie > dst_mtu(dst)) { if (inet_csk(sk)->icsk_pmtu_cookie > dst_mtu(dst)) dccp_sync_mss(sk, dst_mtu(dst)); } /* else let the usual retransmit timer handle it */ dst_release(dst); goto out; } Loading net/ipv6/inet6_connection_sock.c +35 −14 Original line number Diff line number Diff line Loading @@ -203,15 +203,13 @@ struct dst_entry *__inet6_csk_dst_check(struct sock *sk, u32 cookie) return dst; } int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused) static struct dst_entry *inet6_csk_route_socket(struct sock *sk) { struct sock *sk = skb->sk; struct inet_sock *inet = inet_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk); struct flowi6 fl6; struct dst_entry *dst; struct in6_addr *final_p, final; int res; struct dst_entry *dst; struct flowi6 fl6; memset(&fl6, 0, sizeof(fl6)); fl6.flowi6_proto = sk->sk_protocol; Loading @@ -228,10 +226,24 @@ int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused) final_p = fl6_update_dst(&fl6, np->opt, &final); dst = __inet6_csk_dst_check(sk, np->dst_cookie); if (dst == NULL) { if (!dst) { dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false); if (!IS_ERR(dst)) __inet6_csk_dst_store(sk, dst, NULL, NULL); } return dst; } int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused) { struct sock *sk = skb->sk; struct ipv6_pinfo *np = inet6_sk(sk); struct flowi6 fl6; struct dst_entry *dst; int res; dst = inet6_csk_route_socket(sk); if (IS_ERR(dst)) { sk->sk_err_soft = -PTR_ERR(dst); sk->sk_route_caps = 0; Loading @@ -239,9 +251,6 @@ int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused) return PTR_ERR(dst); } __inet6_csk_dst_store(sk, dst, NULL, NULL); } rcu_read_lock(); skb_dst_set_noref(skb, dst); Loading @@ -253,3 +262,15 @@ int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused) return res; } EXPORT_SYMBOL_GPL(inet6_csk_xmit); struct dst_entry *inet6_csk_update_pmtu(struct sock *sk, u32 mtu) { struct dst_entry *dst = inet6_csk_route_socket(sk); if (IS_ERR(dst)) return NULL; dst->ops->update_pmtu(dst, mtu); return inet6_csk_route_socket(sk); } EXPORT_SYMBOL_GPL(inet6_csk_update_pmtu); net/ipv6/tcp_ipv6.c +4 −33 Original line number Diff line number Diff line Loading @@ -378,43 +378,14 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, if ((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE)) goto out; /* icmp should have updated the destination cache entry */ dst = __sk_dst_check(sk, np->dst_cookie); if (dst == NULL) { struct inet_sock *inet = inet_sk(sk); struct flowi6 fl6; /* BUGGG_FUTURE: Again, it is not clear how to handle rthdr case. Ignore this complexity for now. */ memset(&fl6, 0, sizeof(fl6)); fl6.flowi6_proto = IPPROTO_TCP; fl6.daddr = np->daddr; fl6.saddr = np->saddr; fl6.flowi6_oif = sk->sk_bound_dev_if; fl6.flowi6_mark = sk->sk_mark; fl6.fl6_dport = inet->inet_dport; fl6.fl6_sport = inet->inet_sport; security_skb_classify_flow(skb, flowi6_to_flowi(&fl6)); dst = ip6_dst_lookup_flow(sk, &fl6, NULL, false); if (IS_ERR(dst)) { sk->sk_err_soft = -PTR_ERR(dst); dst = inet6_csk_update_pmtu(sk, ntohl(info)); if (!dst) goto out; } } else dst_hold(dst); dst->ops->update_pmtu(dst, ntohl(info)); if (inet_csk(sk)->icsk_pmtu_cookie > dst_mtu(dst)) { tcp_sync_mss(sk, dst_mtu(dst)); tcp_simple_retransmit(sk); } /* else let the usual retransmit timer handle it */ dst_release(dst); } goto out; } Loading Loading
include/net/inet6_connection_sock.h +2 −0 Original line number Diff line number Diff line Loading @@ -43,4 +43,6 @@ extern void inet6_csk_reqsk_queue_hash_add(struct sock *sk, extern void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr); extern int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl); extern struct dst_entry *inet6_csk_update_pmtu(struct sock *sk, u32 mtu); #endif /* _INET6_CONNECTION_SOCK_H */
net/dccp/ipv6.c +4 −31 Original line number Diff line number Diff line Loading @@ -145,39 +145,12 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, if ((1 << sk->sk_state) & (DCCPF_LISTEN | DCCPF_CLOSED)) goto out; /* icmp should have updated the destination cache entry */ dst = __sk_dst_check(sk, np->dst_cookie); if (dst == NULL) { struct inet_sock *inet = inet_sk(sk); struct flowi6 fl6; /* BUGGG_FUTURE: Again, it is not clear how to handle rthdr case. Ignore this complexity for now. */ memset(&fl6, 0, sizeof(fl6)); fl6.flowi6_proto = IPPROTO_DCCP; fl6.daddr = np->daddr; fl6.saddr = np->saddr; fl6.flowi6_oif = sk->sk_bound_dev_if; fl6.fl6_dport = inet->inet_dport; fl6.fl6_sport = inet->inet_sport; security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); dst = ip6_dst_lookup_flow(sk, &fl6, NULL, false); if (IS_ERR(dst)) { sk->sk_err_soft = -PTR_ERR(dst); dst = inet6_csk_update_pmtu(sk, ntohl(info)); if (!dst) goto out; } } else dst_hold(dst); dst->ops->update_pmtu(dst, ntohl(info)); if (inet_csk(sk)->icsk_pmtu_cookie > dst_mtu(dst)) { if (inet_csk(sk)->icsk_pmtu_cookie > dst_mtu(dst)) dccp_sync_mss(sk, dst_mtu(dst)); } /* else let the usual retransmit timer handle it */ dst_release(dst); goto out; } Loading
net/ipv6/inet6_connection_sock.c +35 −14 Original line number Diff line number Diff line Loading @@ -203,15 +203,13 @@ struct dst_entry *__inet6_csk_dst_check(struct sock *sk, u32 cookie) return dst; } int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused) static struct dst_entry *inet6_csk_route_socket(struct sock *sk) { struct sock *sk = skb->sk; struct inet_sock *inet = inet_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk); struct flowi6 fl6; struct dst_entry *dst; struct in6_addr *final_p, final; int res; struct dst_entry *dst; struct flowi6 fl6; memset(&fl6, 0, sizeof(fl6)); fl6.flowi6_proto = sk->sk_protocol; Loading @@ -228,10 +226,24 @@ int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused) final_p = fl6_update_dst(&fl6, np->opt, &final); dst = __inet6_csk_dst_check(sk, np->dst_cookie); if (dst == NULL) { if (!dst) { dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false); if (!IS_ERR(dst)) __inet6_csk_dst_store(sk, dst, NULL, NULL); } return dst; } int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused) { struct sock *sk = skb->sk; struct ipv6_pinfo *np = inet6_sk(sk); struct flowi6 fl6; struct dst_entry *dst; int res; dst = inet6_csk_route_socket(sk); if (IS_ERR(dst)) { sk->sk_err_soft = -PTR_ERR(dst); sk->sk_route_caps = 0; Loading @@ -239,9 +251,6 @@ int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused) return PTR_ERR(dst); } __inet6_csk_dst_store(sk, dst, NULL, NULL); } rcu_read_lock(); skb_dst_set_noref(skb, dst); Loading @@ -253,3 +262,15 @@ int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused) return res; } EXPORT_SYMBOL_GPL(inet6_csk_xmit); struct dst_entry *inet6_csk_update_pmtu(struct sock *sk, u32 mtu) { struct dst_entry *dst = inet6_csk_route_socket(sk); if (IS_ERR(dst)) return NULL; dst->ops->update_pmtu(dst, mtu); return inet6_csk_route_socket(sk); } EXPORT_SYMBOL_GPL(inet6_csk_update_pmtu);
net/ipv6/tcp_ipv6.c +4 −33 Original line number Diff line number Diff line Loading @@ -378,43 +378,14 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, if ((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE)) goto out; /* icmp should have updated the destination cache entry */ dst = __sk_dst_check(sk, np->dst_cookie); if (dst == NULL) { struct inet_sock *inet = inet_sk(sk); struct flowi6 fl6; /* BUGGG_FUTURE: Again, it is not clear how to handle rthdr case. Ignore this complexity for now. */ memset(&fl6, 0, sizeof(fl6)); fl6.flowi6_proto = IPPROTO_TCP; fl6.daddr = np->daddr; fl6.saddr = np->saddr; fl6.flowi6_oif = sk->sk_bound_dev_if; fl6.flowi6_mark = sk->sk_mark; fl6.fl6_dport = inet->inet_dport; fl6.fl6_sport = inet->inet_sport; security_skb_classify_flow(skb, flowi6_to_flowi(&fl6)); dst = ip6_dst_lookup_flow(sk, &fl6, NULL, false); if (IS_ERR(dst)) { sk->sk_err_soft = -PTR_ERR(dst); dst = inet6_csk_update_pmtu(sk, ntohl(info)); if (!dst) goto out; } } else dst_hold(dst); dst->ops->update_pmtu(dst, ntohl(info)); if (inet_csk(sk)->icsk_pmtu_cookie > dst_mtu(dst)) { tcp_sync_mss(sk, dst_mtu(dst)); tcp_simple_retransmit(sk); } /* else let the usual retransmit timer handle it */ dst_release(dst); } goto out; } Loading