Index: net/ipv6/raw.c
===================================================================
--- net/ipv6/raw.c
+++ net/ipv6/raw.c
@@ -500,9 +500,10 @@
 }
 
 static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl,
-				     struct raw6_sock *rp)
+				     struct raw6_sock *rp, struct ipv6_txoptions *opt)
 {
 	struct sk_buff *skb;
+    struct in6_addr *src = &fl->fl6_src;
 	int err = 0;
 	int offset;
 	int len;
@@ -561,9 +562,15 @@
 	if (unlikely(csum))
 		tmp_csum = csum_sub(tmp_csum, csum_unfold(csum));
 
-	csum = csum_ipv6_magic(&fl->fl6_src,
-				   &fl->fl6_dst,
-				   total_len, fl->proto, tmp_csum);
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+    if (fl->proto == IPPROTO_MH && opt && opt->dst1opt) {
+        unsigned char *pos = (unsigned char *)(opt->dst1opt + 1);
+        pos += 4;
+        struct ipv6_destopt_hao *hao = (struct ipv6_destopt_hao *)pos;
+        src = &hao->addr;
+    }
+#endif
+	csum = csum_ipv6_magic(src, &fl->fl6_dst, total_len, fl->proto, tmp_csum);
 
 	if (csum == 0 && fl->proto == IPPROTO_UDP)
 		csum = CSUM_MANGLED_0;
@@ -885,7 +892,7 @@
 		if (err)
 			ip6_flush_pending_frames(sk);
 		else if (!(msg->msg_flags & MSG_MORE))
-			err = rawv6_push_pending_frames(sk, &fl, rp);
+			err = rawv6_push_pending_frames(sk, &fl, rp, opt);
 	}
 done:
 	dst_release(dst);

