tcp_ipv6.c (5800571960234f9d1f1011bf135799b2014d4268) tcp_ipv6.c (a842fe1425cb20f457abd3f8ef98b468f83ca98b)
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * TCP over IPv6
4 * Linux INET6 implementation
5 *
6 * Authors:
7 * Pedro Roque <roque@di.fc.ul.pt>
8 *

--- 869 unchanged lines hidden (view full) ---

878 fl6.flowi6_oif = tcp_v6_iif(skb);
879 else {
880 if (!oif && netif_index_is_l3_master(net, skb->skb_iif))
881 oif = skb->skb_iif;
882
883 fl6.flowi6_oif = oif;
884 }
885
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * TCP over IPv6
4 * Linux INET6 implementation
5 *
6 * Authors:
7 * Pedro Roque <roque@di.fc.ul.pt>
8 *

--- 869 unchanged lines hidden (view full) ---

878 fl6.flowi6_oif = tcp_v6_iif(skb);
879 else {
880 if (!oif && netif_index_is_l3_master(net, skb->skb_iif))
881 oif = skb->skb_iif;
882
883 fl6.flowi6_oif = oif;
884 }
885
886 if (sk)
887 mark = (sk->sk_state == TCP_TIME_WAIT) ?
888 inet_twsk(sk)->tw_mark : sk->sk_mark;
886 if (sk) {
887 if (sk->sk_state == TCP_TIME_WAIT) {
888 mark = inet_twsk(sk)->tw_mark;
889 /* autoflowlabel relies on buff->hash */
890 skb_set_hash(buff, inet_twsk(sk)->tw_txhash,
891 PKT_HASH_TYPE_L4);
892 } else {
893 mark = sk->sk_mark;
894 }
895 tcp_set_tx_time(buff, sk);
896 }
889 fl6.flowi6_mark = IP6_REPLY_MARK(net, skb->mark) ?: mark;
890 fl6.fl6_dport = t1->dest;
891 fl6.fl6_sport = t1->source;
892 fl6.flowi6_uid = sock_net_uid(net, sk && sk_fullsock(sk) ? sk : NULL);
893 security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
894
895 /* Pass a socket to ip6_dst_lookup either it is for RST
896 * Underlying function will use this to retrieve the network

--- 10 unchanged lines hidden (view full) ---

907 }
908
909 kfree_skb(buff);
910}
911
912static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb)
913{
914 const struct tcphdr *th = tcp_hdr(skb);
897 fl6.flowi6_mark = IP6_REPLY_MARK(net, skb->mark) ?: mark;
898 fl6.fl6_dport = t1->dest;
899 fl6.fl6_sport = t1->source;
900 fl6.flowi6_uid = sock_net_uid(net, sk && sk_fullsock(sk) ? sk : NULL);
901 security_skb_classify_flow(skb, flowi6_to_flowi(&fl6));
902
903 /* Pass a socket to ip6_dst_lookup either it is for RST
904 * Underlying function will use this to retrieve the network

--- 10 unchanged lines hidden (view full) ---

915 }
916
917 kfree_skb(buff);
918}
919
920static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb)
921{
922 const struct tcphdr *th = tcp_hdr(skb);
923 struct ipv6hdr *ipv6h = ipv6_hdr(skb);
915 u32 seq = 0, ack_seq = 0;
916 struct tcp_md5sig_key *key = NULL;
917#ifdef CONFIG_TCP_MD5SIG
918 const __u8 *hash_location = NULL;
924 u32 seq = 0, ack_seq = 0;
925 struct tcp_md5sig_key *key = NULL;
926#ifdef CONFIG_TCP_MD5SIG
927 const __u8 *hash_location = NULL;
919 struct ipv6hdr *ipv6h = ipv6_hdr(skb);
920 unsigned char newhash[16];
921 int genhash;
922 struct sock *sk1 = NULL;
923#endif
928 unsigned char newhash[16];
929 int genhash;
930 struct sock *sk1 = NULL;
931#endif
932 __be32 label = 0;
933 struct net *net;
924 int oif = 0;
925
926 if (th->rst)
927 return;
928
929 /* If sk not NULL, it means we did a successful lookup and incoming
930 * route had to be correct. prequeue might have dropped our dst.
931 */
932 if (!sk && !ipv6_unicast_destination(skb))
933 return;
934
934 int oif = 0;
935
936 if (th->rst)
937 return;
938
939 /* If sk not NULL, it means we did a successful lookup and incoming
940 * route had to be correct. prequeue might have dropped our dst.
941 */
942 if (!sk && !ipv6_unicast_destination(skb))
943 return;
944
945 net = sk ? sock_net(sk) : dev_net(skb_dst(skb)->dev);
935#ifdef CONFIG_TCP_MD5SIG
936 rcu_read_lock();
937 hash_location = tcp_parse_md5sig_option(th);
938 if (sk && sk_fullsock(sk)) {
939 key = tcp_v6_md5_do_lookup(sk, &ipv6h->saddr);
940 } else if (hash_location) {
941 /*
942 * active side is lost. Try to find listening socket through
943 * source port, and then find md5 key through listening socket.
944 * we are not loose security here:
945 * Incoming packet is checked with md5 hash with finding key,
946 * no RST generated if md5 hash doesn't match.
947 */
946#ifdef CONFIG_TCP_MD5SIG
947 rcu_read_lock();
948 hash_location = tcp_parse_md5sig_option(th);
949 if (sk && sk_fullsock(sk)) {
950 key = tcp_v6_md5_do_lookup(sk, &ipv6h->saddr);
951 } else if (hash_location) {
952 /*
953 * active side is lost. Try to find listening socket through
954 * source port, and then find md5 key through listening socket.
955 * we are not loose security here:
956 * Incoming packet is checked with md5 hash with finding key,
957 * no RST generated if md5 hash doesn't match.
958 */
948 sk1 = inet6_lookup_listener(dev_net(skb_dst(skb)->dev),
959 sk1 = inet6_lookup_listener(net,
949 &tcp_hashinfo, NULL, 0,
950 &ipv6h->saddr,
951 th->source, &ipv6h->daddr,
952 ntohs(th->source),
953 tcp_v6_iif_l3_slave(skb),
954 tcp_v6_sdif(skb));
955 if (!sk1)
956 goto out;

--- 13 unchanged lines hidden (view full) ---

970 else
971 ack_seq = ntohl(th->seq) + th->syn + th->fin + skb->len -
972 (th->doff << 2);
973
974 if (sk) {
975 oif = sk->sk_bound_dev_if;
976 if (sk_fullsock(sk))
977 trace_tcp_send_reset(sk, skb);
960 &tcp_hashinfo, NULL, 0,
961 &ipv6h->saddr,
962 th->source, &ipv6h->daddr,
963 ntohs(th->source),
964 tcp_v6_iif_l3_slave(skb),
965 tcp_v6_sdif(skb));
966 if (!sk1)
967 goto out;

--- 13 unchanged lines hidden (view full) ---

981 else
982 ack_seq = ntohl(th->seq) + th->syn + th->fin + skb->len -
983 (th->doff << 2);
984
985 if (sk) {
986 oif = sk->sk_bound_dev_if;
987 if (sk_fullsock(sk))
988 trace_tcp_send_reset(sk, skb);
989 if (sk->sk_state == TCP_TIME_WAIT)
990 label = cpu_to_be32(inet_twsk(sk)->tw_flowlabel);
991 } else {
992 if (net->ipv6.sysctl.flowlabel_reflect & 2)
993 label = ip6_flowlabel(ipv6h);
978 }
979
994 }
995
980 tcp_v6_send_response(sk, skb, seq, ack_seq, 0, 0, 0, oif, key, 1, 0, 0);
996 tcp_v6_send_response(sk, skb, seq, ack_seq, 0, 0, 0, oif, key, 1, 0,
997 label);
981
982#ifdef CONFIG_TCP_MD5SIG
983out:
984 rcu_read_unlock();
985#endif
986}
987
988static void tcp_v6_send_ack(const struct sock *sk, struct sk_buff *skb, u32 seq,

--- 1093 unchanged lines hidden ---
998
999#ifdef CONFIG_TCP_MD5SIG
1000out:
1001 rcu_read_unlock();
1002#endif
1003}
1004
1005static void tcp_v6_send_ack(const struct sock *sk, struct sk_buff *skb, u32 seq,

--- 1093 unchanged lines hidden ---