/* * Hook inserted to be called before each receive packet. * Note: arguments must match tcp_rcv_established()! */ static int jtcp_rcv_established(struct sock *sk, struct sk_buff *skb, struct tcphdr *th, unsigned len) { const struct tcp_sock *tp = tcp_sk(sk); const struct inet_sock *inet = inet_sk(sk); /* Only update if port matches */ if ((port == 0 || ntohs(inet->dport) == port || ntohs(inet->sport) == port) && (full || tp->snd_cwnd != tcp_probe.lastcwnd)) { spin_lock(&tcp_probe.lock); /* If log fills, just silently drop */ if (tcp_probe_avail() > 1) { struct tcp_log *p = tcp_probe.log + tcp_probe.head; p->tstamp = ktime_get(); p->saddr = inet->saddr; p->sport = inet->sport; p->daddr = inet->daddr; p->dport = inet->dport; p->length = skb->len; p->snd_nxt = tp->snd_nxt; p->snd_una = tp->snd_una; p->snd_cwnd = tp->snd_cwnd; p->snd_wnd = tp->snd_wnd; p->ssthresh = tcp_current_ssthresh(sk); p->srtt = tp->srtt >> 3; tcp_probe.head = (tcp_probe.head + 1) % bufsize; } tcp_probe.lastcwnd = tp->snd_cwnd; spin_unlock(&tcp_probe.lock); wake_up(&tcp_probe.wait); }
/* * Hook inserted to be called before each receive packet. * Note: arguments must match tcp_rcv_established()! */ static void jtcp_rcv_established(struct sock *sk, struct sk_buff *skb, const struct tcphdr *th, unsigned int len) { const struct tcp_sock *tp = tcp_sk(sk); const struct inet_sock *inet = inet_sk(sk); /* Only update if port or skb mark matches */ if (((port == 0 && fwmark == 0) || ntohs(inet->inet_dport) == port || ntohs(inet->inet_sport) == port || (fwmark > 0 && skb->mark == fwmark)) && (full || tp->snd_cwnd != tcp_probe.lastcwnd)) { spin_lock(&tcp_probe.lock); /* If log fills, just silently drop */ if (tcp_probe_avail() > 1) { struct tcp_log *p = tcp_probe.log + tcp_probe.head; p->tstamp = ktime_get(); switch (sk->sk_family) { case AF_INET: tcp_probe_copy_fl_to_si4(inet, p->src.v4, s); tcp_probe_copy_fl_to_si4(inet, p->dst.v4, d); break; case AF_INET6: memset(&p->src.v6, 0, sizeof(p->src.v6)); memset(&p->dst.v6, 0, sizeof(p->dst.v6)); #if IS_ENABLED(CONFIG_IPV6) p->src.v6.sin6_family = AF_INET6; p->src.v6.sin6_port = inet->inet_sport; p->src.v6.sin6_addr = inet6_sk(sk)->saddr; p->dst.v6.sin6_family = AF_INET6; p->dst.v6.sin6_port = inet->inet_dport; p->dst.v6.sin6_addr = sk->sk_v6_daddr; #endif break; default: BUG(); } p->length = skb->len; p->snd_nxt = tp->snd_nxt; p->snd_una = tp->snd_una; p->snd_cwnd = tp->snd_cwnd; p->snd_wnd = tp->snd_wnd; p->rcv_wnd = tp->rcv_wnd; p->ssthresh = tcp_current_ssthresh(sk); p->srtt = tp->srtt_us >> 3; tcp_probe.head = (tcp_probe.head + 1) & (bufsize - 1); } tcp_probe.lastcwnd = tp->snd_cwnd; spin_unlock(&tcp_probe.lock); wake_up(&tcp_probe.wait); }