Index: usr/src/sys/click/app/fastslb/fastslb_tcp.c
===================================================================
--- usr/src/sys/click/app/fastslb/fastslb_tcp.c	(revision 38447)
+++ usr/src/sys/click/app/fastslb/fastslb_tcp.c	(working copy)
@@ -426,6 +426,68 @@
 	}
 }
 
+#define FASTTCP_AN_MSS 1460
+#define FASTTCP_AN_LOOPBACK_MSS 16344
+
+/*
+ * Parse TCP options and replace only mss if we find it
+ */
+static void
+fasttcp_update_mss(struct fasttcp_tuples *tuples, struct mbuf *m, int flags)
+{
+    uint16_t orig_mss, new_mss = htons(FASTTCP_AN_MSS);
+    u_char *cp = NULL;
+    int cnt = 0;
+    int off;
+    int opt, optlen = 0;
+
+    /*
+     * Check that TCP offset makes sense,
+     * pull out TCP options and adjust length.
+     */
+    off = tuples->th->th_off << 2;
+    if (off > sizeof (struct tcphdr)) {
+        cnt = off - sizeof (struct tcphdr);
+        cp = (u_char *)(tuples->th + 1);
+    }
+
+    for (; cnt > 0; cnt -= optlen, cp += optlen) {
+        opt = cp[0];
+        if (opt == TCPOPT_EOL)
+            break;
+        if (opt == TCPOPT_NOP)
+            optlen = 1;
+        else {
+            if (cnt < 2)
+                break;
+            optlen = cp[1];
+            if (optlen < 2 || optlen > cnt)
+                break;
+        }
+        switch (opt) {
+        case TCPOPT_MAXSEG:
+            /* we only care about mss */
+            if (optlen != TCPOLEN_MAXSEG)
+                continue;
+            if (!(flags & TO_SYN))
+                continue;
+            orig_mss = *(uint16_t *)(((char *)cp) + 2);
+            if(orig_mss >=  htons(FASTTCP_AN_LOOPBACK_MSS)) {
+                /* this packet is from loopback change its mss to 1460 */
+                slb_vs_t *vs_p;
+                vs_p = fasttcp_is_slb(tuples);
+                if (vs_p != NULL) {
+                    new_mss = htons(vs_p->vs_mss);
+                }
+                bcopy((char *)&new_mss, (char *)cp + 2, 2);
+                if (fasttcp_debug) printf("fasttcp_update_mss: orig mss %hu, new mss %hu\n", orig_mss, new_mss);
+            }
+            break;
+        default:
+            continue;
+        }
+    }
+}
 int
 fasttcp_tcp_passive_open(struct fasttcp_tuples * tuples, struct mbuf *m, void *void_p, struct ifnet *real_ifp)
 {
@@ -438,6 +500,8 @@
 		  *reverse mode,transparent mode, only SYN packet can build fastpcb.
 		 */
 		if(tuples->th->th_flags == TH_SYN) {
+                        /* check options for mss, and change it for loopack packets */
+                        fasttcp_update_mss(tuples, m, TO_SYN);
 			return fasttcp_passive_open(tuples, m, vs_p, real_ifp, NULL);
 		} else {
 			if (cross_numa_enable && numa_dispatcher && ATCP_IS_L4() && numa_enqueue(m)) {
