smc_ok : 1,     /* SMC seen on SYN packet               */
                snd_wscale : 4, /* Window scaling received from sender  */
                rcv_wscale : 4; /* Window scaling to send to receiver   */
+       u8      saw_unknown:1,  /* Received unknown option              */
+               unused:7;
        u8      num_sacks;      /* Number of SACK blocks                */
        u16     user_mss;       /* mss requested by user in ioctl       */
        u16     mss_clamp;      /* Maximal mss, negotiated at connection setup */
 
        foc->exp = exp_opt;
 }
 
-static void smc_parse_options(const struct tcphdr *th,
+static bool smc_parse_options(const struct tcphdr *th,
                              struct tcp_options_received *opt_rx,
                              const unsigned char *ptr,
                              int opsize)
        if (static_branch_unlikely(&tcp_have_smc)) {
                if (th->syn && !(opsize & 1) &&
                    opsize >= TCPOLEN_EXP_SMC_BASE &&
-                   get_unaligned_be32(ptr) == TCPOPT_SMC_MAGIC)
+                   get_unaligned_be32(ptr) == TCPOPT_SMC_MAGIC) {
                        opt_rx->smc_ok = 1;
+                       return true;
+               }
        }
 #endif
+       return false;
 }
 
 /* Try to parse the MSS option from the TCP header. Return 0 on failure, clamped
 
        ptr = (const unsigned char *)(th + 1);
        opt_rx->saw_tstamp = 0;
+       opt_rx->saw_unknown = 0;
 
        while (length > 0) {
                int opcode = *ptr++;
                                 */
                                if (opsize >= TCPOLEN_EXP_FASTOPEN_BASE &&
                                    get_unaligned_be16(ptr) ==
-                                   TCPOPT_FASTOPEN_MAGIC)
+                                   TCPOPT_FASTOPEN_MAGIC) {
                                        tcp_parse_fastopen_option(opsize -
                                                TCPOLEN_EXP_FASTOPEN_BASE,
                                                ptr + 2, th->syn, foc, true);
-                               else
-                                       smc_parse_options(th, opt_rx, ptr,
-                                                         opsize);
+                                       break;
+                               }
+
+                               if (smc_parse_options(th, opt_rx, ptr, opsize))
+                                       break;
+
+                               opt_rx->saw_unknown = 1;
                                break;
 
+                       default:
+                               opt_rx->saw_unknown = 1;
                        }
                        ptr += opsize-2;
                        length -= opsize;