--- zzzz-none-000/linux-4.19.183/net/ipv6/tcp_ipv6.c 2021-03-24 10:07:39.000000000 +0000 +++ bcm63-7530ax-756/linux-4.19.183/net/ipv6/tcp_ipv6.c 2023-06-28 08:54:21.000000000 +0000 @@ -61,6 +61,10 @@ #include #include #include +#if defined(CONFIG_BCM_KF_MPTCP) && defined(CONFIG_BCM_MPTCP) +#include +#include +#endif #include #include @@ -70,6 +74,9 @@ #include #include +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) + +#include static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb); static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, @@ -79,6 +86,7 @@ static const struct inet_connection_sock_af_ops ipv6_mapped; static const struct inet_connection_sock_af_ops ipv6_specific; +#endif #ifdef CONFIG_TCP_MD5SIG static const struct tcp_sock_af_ops tcp_sock_ipv6_specific; static const struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific; @@ -90,7 +98,11 @@ } #endif +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) static void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb) +#else +void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb) +#endif { struct dst_entry *dst = skb_dst(skb); @@ -132,7 +144,11 @@ return BPF_CGROUP_RUN_PROG_INET6_CONNECT(sk, uaddr); } +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, +#else +int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, +#endif int addr_len) { struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; @@ -229,7 +245,16 @@ sin.sin_port = usin->sin6_port; sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3]; +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) icsk->icsk_af_ops = &ipv6_mapped; +#else +#ifdef CONFIG_MPTCP + if (sock_flag(sk, SOCK_MPTCP)) + icsk->icsk_af_ops = &mptcp_v6_mapped; + else +#endif + icsk->icsk_af_ops = &ipv6_mapped; +#endif sk->sk_backlog_rcv = tcp_v4_do_rcv; #ifdef CONFIG_TCP_MD5SIG tp->af_specific = &tcp_sock_ipv6_mapped_specific; @@ -239,7 +264,16 @@ if (err) { icsk->icsk_ext_hdr_len = exthdrlen; +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) icsk->icsk_af_ops = &ipv6_specific; +#else +#ifdef CONFIG_MPTCP + if (sock_flag(sk, SOCK_MPTCP)) + icsk->icsk_af_ops = &mptcp_v6_specific; + else +#endif + icsk->icsk_af_ops = &ipv6_specific; +#endif sk->sk_backlog_rcv = tcp_v6_do_rcv; #ifdef CONFIG_TCP_MD5SIG tp->af_specific = &tcp_sock_ipv6_specific; @@ -333,7 +367,11 @@ return err; } +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) static void tcp_v6_mtu_reduced(struct sock *sk) +#else +void tcp_v6_mtu_reduced(struct sock *sk) +#endif { struct dst_entry *dst; @@ -360,7 +398,11 @@ struct ipv6_pinfo *np; struct tcp_sock *tp; __u32 seq, snd_una; +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) struct sock *sk; +#else + struct sock *sk, *meta_sk; +#endif bool fatal; int err; @@ -384,8 +426,19 @@ if (sk->sk_state == TCP_NEW_SYN_RECV) return tcp_req_err(sk, seq, fatal); +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) bh_lock_sock(sk); if (sock_owned_by_user(sk) && type != ICMPV6_PKT_TOOBIG) +#else + tp = tcp_sk(sk); + if (mptcp(tp)) + meta_sk = mptcp_meta_sk(sk); + else + meta_sk = sk; + + bh_lock_sock(meta_sk); + if (sock_owned_by_user(meta_sk) && type != ICMPV6_PKT_TOOBIG) +#endif __NET_INC_STATS(net, LINUX_MIB_LOCKDROPPEDICMPS); if (sk->sk_state == TCP_CLOSE) @@ -396,7 +449,9 @@ goto out; } +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) tp = tcp_sk(sk); +#endif /* XXX (TFO) - tp->snd_una should be ISN (tcp_create_openreq_child() */ fastopen = tp->fastopen_rsk; snd_una = fastopen ? tcp_rsk(fastopen)->snt_isn : tp->snd_una; @@ -430,11 +485,25 @@ goto out; tp->mtu_info = ntohl(info); +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) if (!sock_owned_by_user(sk)) +#else + if (!sock_owned_by_user(meta_sk)) { +#endif tcp_v6_mtu_reduced(sk); +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) else if (!test_and_set_bit(TCP_MTU_REDUCED_DEFERRED, &sk->sk_tsq_flags)) sock_hold(sk); +#else + } else { + if (!test_and_set_bit(TCP_MTU_REDUCED_DEFERRED, + &sk->sk_tsq_flags)) + sock_hold(sk); + if (mptcp(tp)) + mptcp_tsq_flags(sk); + } +#endif goto out; } @@ -449,7 +518,11 @@ if (fastopen && !fastopen->sk) break; +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) if (!sock_owned_by_user(sk)) { +#else + if (!sock_owned_by_user(meta_sk)) { +#endif sk->sk_err = err; sk->sk_error_report(sk); /* Wake people up to see the error (see connect in sock.c) */ @@ -459,14 +532,22 @@ goto out; } +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) if (!sock_owned_by_user(sk) && np->recverr) { +#else + if (!sock_owned_by_user(meta_sk) && np->recverr) { +#endif sk->sk_err = err; sk->sk_error_report(sk); } else sk->sk_err_soft = err; out: +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) bh_unlock_sock(sk); +#else + bh_unlock_sock(meta_sk); +#endif sock_put(sk); } @@ -512,8 +593,12 @@ return err; } +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) static void tcp_v6_reqsk_destructor(struct request_sock *req) +#else +void tcp_v6_reqsk_destructor(struct request_sock *req) +#endif { kfree(inet_rsk(req)->ipv6_opt); kfree_skb(inet_rsk(req)->pktopts); @@ -731,9 +816,16 @@ return false; } +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) static void tcp_v6_init_req(struct request_sock *req, const struct sock *sk_listener, struct sk_buff *skb) +#else +static int tcp_v6_init_req(struct request_sock *req, + const struct sock *sk_listener, + struct sk_buff *skb, + bool want_cookie) +#endif { struct inet_request_sock *ireq = inet_rsk(req); const struct ipv6_pinfo *np = inet6_sk(sk_listener); @@ -754,6 +846,10 @@ refcount_inc(&skb->users); ireq->pktopts = skb; } +#if defined(CONFIG_BCM_KF_MPTCP) && defined(CONFIG_BCM_MPTCP) + + return 0; +#endif } static struct dst_entry *tcp_v6_route_req(const struct sock *sk, @@ -773,7 +869,11 @@ .syn_ack_timeout = tcp_syn_ack_timeout, }; +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) static const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = { +#else +const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = { +#endif .mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr), #ifdef CONFIG_TCP_MD5SIG @@ -791,9 +891,17 @@ }; static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32 seq, +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) u32 ack, u32 win, u32 tsval, u32 tsecr, +#else + u32 ack, u32 data_ack, u32 win, u32 tsval, u32 tsecr, +#endif int oif, struct tcp_md5sig_key *key, int rst, +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) u8 tclass, __be32 label) +#else + u8 tclass, __be32 label, int mptcp) +#endif { const struct tcphdr *th = tcp_hdr(skb); struct tcphdr *t1; @@ -812,7 +920,14 @@ if (key) tot_len += TCPOLEN_MD5SIG_ALIGNED; #endif +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) +#else +#ifdef CONFIG_MPTCP + if (mptcp) + tot_len += MPTCP_SUB_LEN_DSS + MPTCP_SUB_LEN_ACK; +#endif +#endif buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + tot_len, GFP_ATOMIC); if (!buff) @@ -850,9 +965,25 @@ tcp_v6_md5_hash_hdr((__u8 *)topt, key, &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, t1); +#if defined(CONFIG_BCM_KF_MPTCP) && defined(CONFIG_BCM_MPTCP) + topt += 4; +#endif } #endif +#if defined(CONFIG_BCM_KF_MPTCP) && defined(CONFIG_BCM_MPTCP) +#ifdef CONFIG_MPTCP + if (mptcp) { + /* Construction of 32-bit data_ack */ + *topt++ = htonl((TCPOPT_MPTCP << 24) | + ((MPTCP_SUB_LEN_DSS + MPTCP_SUB_LEN_ACK) << 16) | + (0x20 << 8) | + (0x01)); + *topt++ = htonl(data_ack); + } +#endif +#endif + memset(&fl6, 0, sizeof(fl6)); fl6.daddr = ipv6_hdr(skb)->saddr; fl6.saddr = ipv6_hdr(skb)->daddr; @@ -899,7 +1030,11 @@ kfree_skb(buff); } +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb) +#else +void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb) +#endif { const struct tcphdr *th = tcp_hdr(skb); u32 seq = 0, ack_seq = 0; @@ -967,7 +1102,11 @@ trace_tcp_send_reset(sk, skb); } +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) tcp_v6_send_response(sk, skb, seq, ack_seq, 0, 0, 0, oif, key, 1, 0, 0); +#else + tcp_v6_send_response(sk, skb, seq, ack_seq, 0, 0, 0, 0, oif, key, 1, 0, 0, 0); +#endif #ifdef CONFIG_TCP_MD5SIG out: @@ -976,30 +1115,65 @@ } static void tcp_v6_send_ack(const struct sock *sk, struct sk_buff *skb, u32 seq, +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) u32 ack, u32 win, u32 tsval, u32 tsecr, int oif, +#else + u32 ack, u32 data_ack, u32 win, u32 tsval, u32 tsecr, int oif, +#endif struct tcp_md5sig_key *key, u8 tclass, +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) __be32 label) +#else + __be32 label, int mptcp) +#endif { +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) tcp_v6_send_response(sk, skb, seq, ack, win, tsval, tsecr, oif, key, 0, tclass, label); +#else + tcp_v6_send_response(sk, skb, seq, ack, data_ack, win, tsval, tsecr, oif, + key, 0, tclass, label, mptcp); +#endif } static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb) { struct inet_timewait_sock *tw = inet_twsk(sk); struct tcp_timewait_sock *tcptw = tcp_twsk(sk); +#if defined(CONFIG_BCM_KF_MPTCP) && defined(CONFIG_BCM_MPTCP) + u32 data_ack = 0; + int mptcp = 0; +#endif +#if defined(CONFIG_BCM_KF_MPTCP) && defined(CONFIG_BCM_MPTCP) + if (tcptw->mptcp_tw) { + data_ack = (u32)tcptw->mptcp_tw->rcv_nxt; + mptcp = 1; + } +#endif tcp_v6_send_ack(sk, skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, +#if defined(CONFIG_BCM_KF_MPTCP) && defined(CONFIG_BCM_MPTCP) + data_ack, +#endif tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, tcp_time_stamp_raw() + tcptw->tw_ts_offset, tcptw->tw_ts_recent, tw->tw_bound_dev_if, tcp_twsk_md5_key(tcptw), +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) tw->tw_tclass, cpu_to_be32(tw->tw_flowlabel)); +#else + tw->tw_tclass, cpu_to_be32(tw->tw_flowlabel), mptcp); +#endif inet_twsk_put(tw); } +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, struct request_sock *req) +#else +void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, + struct request_sock *req) +#endif { /* sk->sk_state == TCP_LISTEN -> for regular TCP_SYN_RECV * sk->sk_state == TCP_SYN_RECV -> for Fast Open. @@ -1009,18 +1183,34 @@ * exception of segments, MUST be right-shifted by * Rcv.Wind.Shift bits: */ +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) tcp_v6_send_ack(sk, skb, (sk->sk_state == TCP_LISTEN) ? +#else + tcp_v6_send_ack(sk, skb, (sk->sk_state == TCP_LISTEN || is_meta_sk(sk)) ? +#endif tcp_rsk(req)->snt_isn + 1 : tcp_sk(sk)->snd_nxt, +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) tcp_rsk(req)->rcv_nxt, +#else + tcp_rsk(req)->rcv_nxt, 0, +#endif req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale, tcp_time_stamp_raw() + tcp_rsk(req)->ts_off, req->ts_recent, sk->sk_bound_dev_if, tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->saddr), +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) 0, 0); +#else + 0, 0, 0); +#endif } +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) static struct sock *tcp_v6_cookie_check(struct sock *sk, struct sk_buff *skb) +#else +struct sock *tcp_v6_cookie_check(struct sock *sk, struct sk_buff *skb) +#endif { #ifdef CONFIG_SYN_COOKIES const struct tcphdr *th = tcp_hdr(skb); @@ -1031,7 +1221,11 @@ return sk; } +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) +#else +int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) +#endif { if (skb->protocol == htons(ETH_P_IP)) return tcp_v4_conn_request(sk, skb); @@ -1057,11 +1251,19 @@ sizeof(struct inet6_skb_parm)); } +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, struct request_sock *req, struct dst_entry *dst, struct request_sock *req_unhash, bool *own_req) +#else +struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, + struct request_sock *req, + struct dst_entry *dst, + struct request_sock *req_unhash, + bool *own_req) +#endif { struct inet_request_sock *ireq; struct ipv6_pinfo *newnp; @@ -1098,7 +1300,19 @@ newnp->saddr = newsk->sk_v6_rcv_saddr; +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) inet_csk(newsk)->icsk_af_ops = &ipv6_mapped; +#else +#ifdef CONFIG_MPTCP + /* We must check on the request-socket because the listener + * socket's flag may have been changed halfway through. + */ + if (!inet_rsk(req)->saw_mpc) + inet_csk(newsk)->icsk_af_ops = &mptcp_v6_mapped; + else +#endif + inet_csk(newsk)->icsk_af_ops = &ipv6_mapped; +#endif newsk->sk_backlog_rcv = tcp_v4_do_rcv; #ifdef CONFIG_TCP_MD5SIG newtp->af_specific = &tcp_sock_ipv6_mapped_specific; @@ -1145,6 +1359,16 @@ if (!newsk) goto out_nonewsk; +#if defined(CONFIG_BCM_KF_MPTCP) && defined(CONFIG_BCM_MPTCP) +#ifdef CONFIG_MPTCP + /* If the meta_sk is v6-mapped we can end up here with the wrong af_ops. + * Just make sure that this subflow is v6. + */ + if (is_meta_sk(sk)) + inet_csk(newsk)->icsk_af_ops = &mptcp_v6_specific; +#endif + +#endif /* * No need to charge this sock to the relevant IPv6 refcnt debug socks * count here, tcp_create_openreq_child now does this for us, see the @@ -1273,7 +1497,11 @@ * This is because we cannot sleep with the original spinlock * held. */ +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) +#else +int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) +#endif { struct ipv6_pinfo *np = inet6_sk(sk); struct tcp_sock *tp; @@ -1290,6 +1518,11 @@ if (skb->protocol == htons(ETH_P_IP)) return tcp_v4_do_rcv(sk, skb); +#if defined(CONFIG_BCM_KF_MPTCP) && defined(CONFIG_BCM_MPTCP) + if (is_meta_sk(sk)) + return mptcp_v6_do_rcv(sk, skb); + +#endif /* * socket locking is here for SMP purposes as backlog rcv * is currently called with bh processing disabled. @@ -1417,6 +1650,12 @@ TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + skb->len - th->doff*4); TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); +#if defined(CONFIG_BCM_KF_MPTCP) && defined(CONFIG_BCM_MPTCP) +#ifdef CONFIG_MPTCP + TCP_SKB_CB(skb)->mptcp_flags = 0; + TCP_SKB_CB(skb)->dss_off = 0; +#endif +#endif TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th); TCP_SKB_CB(skb)->tcp_tw_isn = 0; TCP_SKB_CB(skb)->ip_dsfield = ipv6_get_dsfield(hdr); @@ -1430,8 +1669,13 @@ int sdif = inet6_sdif(skb); const struct tcphdr *th; const struct ipv6hdr *hdr; +#if defined(CONFIG_BCM_KF_MPTCP) && defined(CONFIG_BCM_MPTCP) + struct sock *sk, *meta_sk = NULL; +#endif bool refcounted; +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) struct sock *sk; +#endif int ret; struct net *net = dev_net(skb->dev); @@ -1467,6 +1711,8 @@ goto no_tcp_socket; process: + avm_pa_add_local_session(AVM_PA_NET_IP6_DEVINFO(net), skb, sk); + if (sk->sk_state == TCP_TIME_WAIT) goto do_time_wait; @@ -1485,12 +1731,23 @@ reqsk_put(req); goto csum_error; } +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) if (unlikely(sk->sk_state != TCP_LISTEN)) { +#else + if (unlikely(sk->sk_state != TCP_LISTEN && !is_meta_sk(sk))) { + inet_csk_reqsk_queue_drop_and_put(sk, req); + goto lookup; + } + if (unlikely(is_meta_sk(sk) && !mptcp_can_new_subflow(sk))) { +#endif inet_csk_reqsk_queue_drop_and_put(sk, req); goto lookup; } sock_hold(sk); refcounted = true; +#if defined(CONFIG_BCM_KF_MPTCP) && defined(CONFIG_BCM_MPTCP) + +#endif nsk = NULL; if (!tcp_filter(sk, skb)) { th = (const struct tcphdr *)skb->data; @@ -1523,6 +1780,9 @@ return 0; } } +#if defined(CONFIG_BCM_KF_MPTCP) && defined(CONFIG_BCM_MPTCP) + +#endif if (hdr->hop_limit < inet6_sk(sk)->min_hopcount) { __NET_INC_STATS(net, LINUX_MIB_TCPMINTTLDROP); goto discard_and_relse; @@ -1549,15 +1809,41 @@ sk_incoming_cpu_update(sk); +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) bh_lock_sock_nested(sk); +#else + if (mptcp(tcp_sk(sk))) { + meta_sk = mptcp_meta_sk(sk); + + bh_lock_sock_nested(meta_sk); + if (sock_owned_by_user(meta_sk)) + mptcp_prepare_for_backlog(sk, skb); + } else { + meta_sk = sk; + bh_lock_sock_nested(sk); + } +#endif tcp_segs_in(tcp_sk(sk), skb); ret = 0; +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) if (!sock_owned_by_user(sk)) { +#else + if (!sock_owned_by_user(meta_sk)) { +#endif ret = tcp_v6_do_rcv(sk, skb); +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) } else if (tcp_add_backlog(sk, skb)) { +#else + } else if (tcp_add_backlog(meta_sk, skb)) { +#endif goto discard_and_relse; } +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) bh_unlock_sock(sk); +#else + + bh_unlock_sock(meta_sk); +#endif put_and_return: if (refcounted) @@ -1570,6 +1856,21 @@ tcp_v6_fill_cb(skb, hdr, th); +#if defined(CONFIG_BCM_KF_MPTCP) && defined(CONFIG_BCM_MPTCP) +#ifdef CONFIG_MPTCP + if (!sk && th->syn && !th->ack) { + int ret = mptcp_lookup_join(skb, NULL); + + if (ret < 0) { + tcp_v6_send_reset(NULL, skb); + goto discard_it; + } else if (ret > 0) { + return 0; + } + } +#endif + +#endif if (tcp_checksum_complete(skb)) { csum_error: __TCP_INC_STATS(net, TCP_MIB_CSUMERRORS); @@ -1622,6 +1923,20 @@ refcounted = false; goto process; } +#if defined(CONFIG_BCM_KF_MPTCP) && defined(CONFIG_BCM_MPTCP) +#ifdef CONFIG_MPTCP + if (th->syn && !th->ack) { + int ret = mptcp_lookup_join(skb, inet_twsk(sk)); + + if (ret < 0) { + tcp_v6_send_reset(NULL, skb); + goto discard_it; + } else if (ret > 0) { + return 0; + } + } +#endif +#endif } /* to ACK */ /* fall through */ @@ -1676,13 +1991,21 @@ } } +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) static struct timewait_sock_ops tcp6_timewait_sock_ops = { +#else +struct timewait_sock_ops tcp6_timewait_sock_ops = { +#endif .twsk_obj_size = sizeof(struct tcp6_timewait_sock), .twsk_unique = tcp_twsk_unique, .twsk_destructor = tcp_twsk_destructor, }; +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) static const struct inet_connection_sock_af_ops ipv6_specific = { +#else +const struct inet_connection_sock_af_ops ipv6_specific = { +#endif .queue_xmit = inet6_csk_xmit, .send_check = tcp_v6_send_check, .rebuild_header = inet6_sk_rebuild_header, @@ -1713,7 +2036,11 @@ /* * TCP over IPv4 via INET6 API */ +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) static const struct inet_connection_sock_af_ops ipv6_mapped = { +#else +const struct inet_connection_sock_af_ops ipv6_mapped = { +#endif .queue_xmit = ip_queue_xmit, .send_check = tcp_v4_send_check, .rebuild_header = inet_sk_rebuild_header, @@ -1749,7 +2076,16 @@ tcp_init_sock(sk); +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) icsk->icsk_af_ops = &ipv6_specific; +#else +#ifdef CONFIG_MPTCP + if (sock_flag(sk, SOCK_MPTCP)) + icsk->icsk_af_ops = &mptcp_v6_specific; + else +#endif + icsk->icsk_af_ops = &ipv6_specific; +#endif #ifdef CONFIG_TCP_MD5SIG tcp_sk(sk)->af_specific = &tcp_sock_ipv6_specific; @@ -1758,7 +2094,11 @@ return 0; } +#if !defined(CONFIG_BCM_KF_MPTCP) || !defined(CONFIG_BCM_MPTCP) static void tcp_v6_destroy_sock(struct sock *sk) +#else +void tcp_v6_destroy_sock(struct sock *sk) +#endif { tcp_v4_destroy_sock(sk); inet6_destroy_sock(sk); @@ -1981,6 +2321,13 @@ .sysctl_rmem_offset = offsetof(struct net, ipv4.sysctl_tcp_rmem), .max_header = MAX_TCP_HEADER, .obj_size = sizeof(struct tcp6_sock), +#if defined(CONFIG_BCM_KF_MPTCP) && defined(CONFIG_BCM_MPTCP) +#ifdef CONFIG_MPTCP + .useroffset = offsetof(struct tcp_sock, mptcp_sched_name), + .usersize = sizeof_field(struct tcp_sock, mptcp_sched_name) + + sizeof_field(struct tcp_sock, mptcp_pm_name), +#endif +#endif .slab_flags = SLAB_TYPESAFE_BY_RCU, .twsk_prot = &tcp6_timewait_sock_ops, .rsk_prot = &tcp6_request_sock_ops, @@ -1991,6 +2338,11 @@ .compat_getsockopt = compat_tcp_getsockopt, #endif .diag_destroy = tcp_abort, +#if defined(CONFIG_BCM_KF_MPTCP) && defined(CONFIG_BCM_MPTCP) +#ifdef CONFIG_MPTCP + .clear_sk = mptcp_clear_sk, +#endif +#endif }; /* thinking of making this const? Don't.