diff --git a/AUTHORS b/AUTHORS
index 96bca29d4a2518218c6665b9fd6fa1ae2ec916df..1556e2124915e3f73cf33d712221511986c3af12 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -169,3 +169,4 @@ Clinton Blackburn <cblackburn@edx.org>
 Dennis Jen <djen@edx.org>
 Filippo Valsorda <hi@filippo.io>
 Ivica Ceraj <ceraj@mit.edu>
+Jason Zhu <fmyzjs@gmail.com>
\ No newline at end of file
diff --git a/cms/envs/common.py b/cms/envs/common.py
index 2f39d754dcd6dec7de33ab6e2537cb1db18438ce..2f187e9f0fd84ae1ad4984b1e540978280d1d7ec 100644
--- a/cms/envs/common.py
+++ b/cms/envs/common.py
@@ -129,7 +129,7 @@ sys.path.append(COMMON_ROOT / 'lib')
 
 # For geolocation ip database
 GEOIP_PATH = REPO_ROOT / "common/static/data/geoip/GeoIP.dat"
-
+GEOIPV6_PATH = REPO_ROOT / "common/static/data/geoip/GeoIPv6.dat"
 
 ############################# WEB CONFIGURATION #############################
 # This is where we stick our compiled template files.
diff --git a/common/djangoapps/embargo/middleware.py b/common/djangoapps/embargo/middleware.py
index 052c04bdbce29eb4820b95e66484f86ccf4b1057..de962ec0eeb841472d9c513448364ca162bc258e 100644
--- a/common/djangoapps/embargo/middleware.py
+++ b/common/djangoapps/embargo/middleware.py
@@ -86,13 +86,17 @@ class EmbargoMiddleware(object):
                           (ip_addr, course_id)
                 else:
                     msg = "Embargo: Restricting IP address %s because IP is blacklisted." % ip_addr
-
                 log.info(msg)
                 return response
+            # ipv6 support
+            if ip_addr.find(':') >= 0:
+                country_code_from_ip = pygeoip.GeoIP(settings.GEOIPV6_PATH).country_code_by_addr(ip_addr)
+            else:
+                country_code_from_ip = pygeoip.GeoIP(settings.GEOIP_PATH).country_code_by_addr(ip_addr)
 
-            country_code_from_ip = pygeoip.GeoIP(settings.GEOIP_PATH).country_code_by_addr(ip_addr)
             is_embargoed = country_code_from_ip in EmbargoedState.current().embargoed_countries_list
-            # Fail if country is embargoed and the ip address isn't explicitly whitelisted
+            # Fail if country is embargoed and the ip address isn't explicitly
+            # whitelisted
             if is_embargoed and ip_addr not in IPFilter.current().whitelist_ips:
                 if course_is_embargoed:
                     msg = "Embargo: Restricting IP address %s to course %s because IP is from country %s." % \
diff --git a/common/djangoapps/embargo/tests/test_middleware.py b/common/djangoapps/embargo/tests/test_middleware.py
index 2f112ca94f90ee4ec6f59098870b71f8c23d47ac..05fd836c36145ec76ecc73398946ac146238beba 100644
--- a/common/djangoapps/embargo/tests/test_middleware.py
+++ b/common/djangoapps/embargo/tests/test_middleware.py
@@ -64,6 +64,8 @@ class EmbargoMiddlewareTests(TestCase):
             '3.0.0.0': 'SY',
             '4.0.0.0': 'SD',
             '5.0.0.0': 'AQ',  # Antartica
+            '2001:250::': 'CN',
+            '2001:1340::': 'CU',
         }
         return ip_dict.get(ip_addr, 'US')
 
@@ -93,6 +95,32 @@ class EmbargoMiddlewareTests(TestCase):
         response = self.client.get(self.regular_page, HTTP_X_FORWARDED_FOR='5.0.0.0', REMOTE_ADDR='5.0.0.0')
         self.assertEqual(response.status_code, 200)
 
+    @unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
+    def test_countries_ipv6(self):
+        # Accessing an embargoed page from a blocked IP should cause a redirect
+        response = self.client.get(self.embargoed_page, HTTP_X_FORWARDED_FOR='2001:1340::', REMOTE_ADDR='2001:1340::')
+        self.assertEqual(response.status_code, 302)
+        # Following the redirect should give us the embargo page
+        response = self.client.get(
+            self.embargoed_page,
+            HTTP_X_FORWARDED_FOR='2001:1340::',
+            REMOTE_ADDR='2001:1340::',
+            follow=True
+        )
+        self.assertIn(self.embargo_text, response.content)
+
+        # Accessing a regular page from a blocked IP should succeed
+        response = self.client.get(self.regular_page, HTTP_X_FORWARDED_FOR='2001:1340::', REMOTE_ADDR='2001:1340::')
+        self.assertEqual(response.status_code, 200)
+
+        # Accessing an embargoed page from a non-embargoed IP should succeed
+        response = self.client.get(self.embargoed_page, HTTP_X_FORWARDED_FOR='2001:250::', REMOTE_ADDR='2001:250::')
+        self.assertEqual(response.status_code, 200)
+
+        # Accessing a regular page from a non-embargoed IP should succeed
+        response = self.client.get(self.regular_page, HTTP_X_FORWARDED_FOR='2001:250::', REMOTE_ADDR='2001:250::')
+        self.assertEqual(response.status_code, 200)
+
     @unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
     def test_ip_exceptions(self):
         # Explicitly whitelist/blacklist some IPs
diff --git a/common/djangoapps/geoinfo/middleware.py b/common/djangoapps/geoinfo/middleware.py
index 4779b2f63a65149a395d63c7009e3a5d24f95d71..1f648d6d2d9dd2697cb44ec15807b7a3df7c29a2 100644
--- a/common/djangoapps/geoinfo/middleware.py
+++ b/common/djangoapps/geoinfo/middleware.py
@@ -36,7 +36,10 @@ class CountryMiddleware(object):
             del request.session['ip_address']
             del request.session['country_code']
         elif new_ip_address != old_ip_address:
-            country_code = pygeoip.GeoIP(settings.GEOIP_PATH).country_code_by_addr(new_ip_address)
+            if new_ip_address.find(':') >= 0:
+                country_code = pygeoip.GeoIP(settings.GEOIPV6_PATH).country_code_by_addr(new_ip_address)
+            else:
+                country_code = pygeoip.GeoIP(settings.GEOIP_PATH).country_code_by_addr(new_ip_address)
             request.session['country_code'] = country_code
             request.session['ip_address'] = new_ip_address
             log.debug('Country code for IP: %s is set to %s', new_ip_address, country_code)
diff --git a/common/djangoapps/geoinfo/tests/test_middleware.py b/common/djangoapps/geoinfo/tests/test_middleware.py
index 05982fb98c4c9f820a4791a898f44fdfdb548663..2ef8e9fc6a31b2d02c77f545f6cda67178709140 100644
--- a/common/djangoapps/geoinfo/tests/test_middleware.py
+++ b/common/djangoapps/geoinfo/tests/test_middleware.py
@@ -41,6 +41,7 @@ class CountryMiddlewareTests(TestCase):
             '117.79.83.1': 'CN',
             '117.79.83.100': 'CN',
             '4.0.0.0': 'SD',
+            '2001:da8:20f:1502:edcf:550b:4a9c:207d': 'CN',
         }
         return ip_dict.get(ip_addr, 'US')
 
@@ -106,3 +107,19 @@ class CountryMiddlewareTests(TestCase):
         # No country code exists after request processing.
         self.assertNotIn('country_code', request.session)
         self.assertNotIn('ip_address', request.session)
+
+    def test_ip_address_is_ipv6(self):
+        request = self.request_factory.get(
+            '/somewhere',
+            HTTP_X_FORWARDED_FOR='2001:da8:20f:1502:edcf:550b:4a9c:207d'
+        )
+        request.user = self.authenticated_user
+        self.session_middleware.process_request(request)
+        # No country code exists before request.
+        self.assertNotIn('country_code', request.session)
+        self.assertNotIn('ip_address', request.session)
+        self.country_middleware.process_request(request)
+        # Country code added to session.
+        self.assertEqual('CN', request.session.get('country_code'))
+        self.assertEqual(
+            '2001:da8:20f:1502:edcf:550b:4a9c:207d', request.session.get('ip_address'))
diff --git a/common/static/data/geoip/GeoIPv6.dat b/common/static/data/geoip/GeoIPv6.dat
new file mode 100644
index 0000000000000000000000000000000000000000..c61e48c75b77467764be4c27e044ed84bbaa0df5
Binary files /dev/null and b/common/static/data/geoip/GeoIPv6.dat differ
diff --git a/lms/envs/common.py b/lms/envs/common.py
index 5ff55fbb801018564c4002fdd5b8577c27710856..82174e44ed4b3827f1c4b3a31720fe2b7ef8f85a 100644
--- a/lms/envs/common.py
+++ b/lms/envs/common.py
@@ -307,7 +307,7 @@ NODE_PATH = ':'.join(node_paths)
 
 # For geolocation ip database
 GEOIP_PATH = REPO_ROOT / "common/static/data/geoip/GeoIP.dat"
-
+GEOIPV6_PATH = REPO_ROOT / "common/static/data/geoip/GeoIPv6.dat"
 
 # Where to look for a status message
 STATUS_MESSAGE_PATH = ENV_ROOT / "status_message.json"