Merge tag 'usb-serial-5.15-rc1-2' of https://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-microblaze.git] / net / mptcp / pm.c
index 0ed3e56..6ab386f 100644 (file)
@@ -20,23 +20,23 @@ int mptcp_pm_announce_addr(struct mptcp_sock *msk,
 {
        u8 add_addr = READ_ONCE(msk->pm.addr_signal);
 
-       pr_debug("msk=%p, local_id=%d", msk, addr->id);
+       pr_debug("msk=%p, local_id=%d, echo=%d", msk, addr->id, echo);
 
        lockdep_assert_held(&msk->pm.lock);
 
-       if (add_addr) {
-               pr_warn("addr_signal error, add_addr=%d", add_addr);
+       if (add_addr &
+           (echo ? BIT(MPTCP_ADD_ADDR_ECHO) : BIT(MPTCP_ADD_ADDR_SIGNAL))) {
+               pr_warn("addr_signal error, add_addr=%d, echo=%d", add_addr, echo);
                return -EINVAL;
        }
 
-       msk->pm.local = *addr;
-       add_addr |= BIT(MPTCP_ADD_ADDR_SIGNAL);
-       if (echo)
+       if (echo) {
+               msk->pm.remote = *addr;
                add_addr |= BIT(MPTCP_ADD_ADDR_ECHO);
-       if (addr->family == AF_INET6)
-               add_addr |= BIT(MPTCP_ADD_ADDR_IPV6);
-       if (addr->port)
-               add_addr |= BIT(MPTCP_ADD_ADDR_PORT);
+       } else {
+               msk->pm.local = *addr;
+               add_addr |= BIT(MPTCP_ADD_ADDR_SIGNAL);
+       }
        WRITE_ONCE(msk->pm.addr_signal, add_addr);
        return 0;
 }
@@ -249,12 +249,21 @@ void mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup)
        mptcp_event(MPTCP_EVENT_SUB_PRIORITY, mptcp_sk(subflow->conn), sk, GFP_ATOMIC);
 }
 
+void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq)
+{
+       pr_debug("fail_seq=%llu", fail_seq);
+}
+
 /* path manager helpers */
 
-bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
-                             struct mptcp_addr_info *saddr, bool *echo, bool *port)
+bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, struct sk_buff *skb,
+                             unsigned int opt_size, unsigned int remaining,
+                             struct mptcp_addr_info *addr, bool *echo,
+                             bool *port, bool *drop_other_suboptions)
 {
        int ret = false;
+       u8 add_addr;
+       u8 family;
 
        spin_lock_bh(&msk->pm.lock);
 
@@ -262,14 +271,30 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
        if (!mptcp_pm_should_add_signal(msk))
                goto out_unlock;
 
+       /* always drop every other options for pure ack ADD_ADDR; this is a
+        * plain dup-ack from TCP perspective. The other MPTCP-relevant info,
+        * if any, will be carried by the 'original' TCP ack
+        */
+       if (skb && skb_is_tcp_pure_ack(skb)) {
+               remaining += opt_size;
+               *drop_other_suboptions = true;
+       }
+
        *echo = mptcp_pm_should_add_signal_echo(msk);
-       *port = mptcp_pm_should_add_signal_port(msk);
+       *port = !!(*echo ? msk->pm.remote.port : msk->pm.local.port);
 
-       if (remaining < mptcp_add_addr_len(msk->pm.local.family, *echo, *port))
+       family = *echo ? msk->pm.remote.family : msk->pm.local.family;
+       if (remaining < mptcp_add_addr_len(family, *echo, *port))
                goto out_unlock;
 
-       *saddr = msk->pm.local;
-       WRITE_ONCE(msk->pm.addr_signal, 0);
+       if (*echo) {
+               *addr = msk->pm.remote;
+               add_addr = msk->pm.addr_signal & ~BIT(MPTCP_ADD_ADDR_ECHO);
+       } else {
+               *addr = msk->pm.local;
+               add_addr = msk->pm.addr_signal & ~BIT(MPTCP_ADD_ADDR_SIGNAL);
+       }
+       WRITE_ONCE(msk->pm.addr_signal, add_addr);
        ret = true;
 
 out_unlock:
@@ -281,6 +306,7 @@ bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
                             struct mptcp_rm_list *rm_list)
 {
        int ret = false, len;
+       u8 rm_addr;
 
        spin_lock_bh(&msk->pm.lock);
 
@@ -288,16 +314,17 @@ bool mptcp_pm_rm_addr_signal(struct mptcp_sock *msk, unsigned int remaining,
        if (!mptcp_pm_should_rm_signal(msk))
                goto out_unlock;
 
+       rm_addr = msk->pm.addr_signal & ~BIT(MPTCP_RM_ADDR_SIGNAL);
        len = mptcp_rm_addr_len(&msk->pm.rm_list_tx);
        if (len < 0) {
-               WRITE_ONCE(msk->pm.addr_signal, 0);
+               WRITE_ONCE(msk->pm.addr_signal, rm_addr);
                goto out_unlock;
        }
        if (remaining < len)
                goto out_unlock;
 
        *rm_list = msk->pm.rm_list_tx;
-       WRITE_ONCE(msk->pm.addr_signal, 0);
+       WRITE_ONCE(msk->pm.addr_signal, rm_addr);
        ret = true;
 
 out_unlock: