# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
-#
 
-from __future__ import absolute_import
+import ipaddress
 
-import unittest
 import mock
+import six
+import unittest
 
 from tests.unit import STL_MOCKS
+from yardstick.common import exceptions as y_exc
 
 STLClient = mock.MagicMock()
 stl_patch = mock.patch.dict("sys.modules", STL_MOCKS)
             TrexProfile(TrafficProfile)
         self.assertEqual({}, trex_profile.generate_imix_data(False))
 
-    def test__get_start_end_ipv6(self):
-        trex_profile = \
-            TrexProfile(TrafficProfile)
-        self.assertRaises(SystemExit, trex_profile._get_start_end_ipv6,
-                          "1.1.1.3", "1.1.1.1")
+    def test__count_ip_ipv4(self):
+        start, end, count = TrexProfile._count_ip('1.1.1.1', '1.2.3.4')
+        self.assertEqual('1.1.1.1', str(start))
+        self.assertEqual('1.2.3.4', str(end))
+        diff = (int(ipaddress.IPv4Address(six.u('1.2.3.4'))) -
+                int(ipaddress.IPv4Address(six.u('1.1.1.1'))))
+        self.assertEqual(diff, count)
+
+    def test__count_ip_ipv6(self):
+        start_ip = '0064:ff9b:0:0:0:0:9810:6414'
+        end_ip = '0064:ff9b:0:0:0:0:9810:6420'
+        start, end, count = TrexProfile._count_ip(start_ip, end_ip)
+        self.assertEqual(0x98106414, start)
+        self.assertEqual(0x98106420, end)
+        self.assertEqual(0x98106420 - 0x98106414, count)
+
+    def test__count_ip_ipv6_exception(self):
+        start_ip = '0064:ff9b:0:0:0:0:9810:6420'
+        end_ip = '0064:ff9b:0:0:0:0:9810:6414'
+        with self.assertRaises(y_exc.IPv6RangeError):
+            TrexProfile._count_ip(start_ip, end_ip)
 
     def test__dscp_range_action_partial_actual_count_zero(self):
         traffic_profile = TrexProfile(TrafficProfile)
     def test__general_single_action_partial(self):
         trex_profile = TrexProfile(TrafficProfile)
 
-        trex_profile._general_single_action_partial(ETHERNET)(SRC)(self.EXAMPLE_ETHERNET_ADDR)
-        self.assertEqual(self.EXAMPLE_ETHERNET_ADDR, trex_profile.ether_packet.src)
+        trex_profile._general_single_action_partial(ETHERNET)(SRC)(
+            self.EXAMPLE_ETHERNET_ADDR)
+        self.assertEqual(self.EXAMPLE_ETHERNET_ADDR,
+                         trex_profile.ether_packet.src)
 
-        trex_profile._general_single_action_partial(IP)(DST)(self.EXAMPLE_IP_ADDR)
+        trex_profile._general_single_action_partial(IP)(DST)(
+            self.EXAMPLE_IP_ADDR)
         self.assertEqual(self.EXAMPLE_IP_ADDR, trex_profile.ip_packet.dst)
 
-        trex_profile._general_single_action_partial(IPv6)(DST)(self.EXAMPLE_IPv6_ADDR)
+        trex_profile._general_single_action_partial(IPv6)(DST)(
+            self.EXAMPLE_IPv6_ADDR)
         self.assertEqual(self.EXAMPLE_IPv6_ADDR, trex_profile.ip6_packet.dst)
 
         trex_profile._general_single_action_partial(UDP)(SRC_PORT)(5060)
 
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
-""" Trex Traffic Profile definitions """
 
-from __future__ import absolute_import
 import struct
 import socket
 import logging
 from random import SystemRandom
-import six
 import ipaddress
 
+import six
+
+from yardstick.common import exceptions as y_exc
 from yardstick.network_services.traffic_profile.base import TrafficProfile
 from trex_stl_lib.trex_stl_client import STLStream
 from trex_stl_lib.trex_stl_streams import STLFlowLatencyStats
                                            op='inc',
                                            step=1)
             self.vm_flow_vars.append(stl_vm_flow_var)
-            stl_vm_wr_flow_var = STLVmWrFlowVar(fv_name='mac_{}'.format(direction),
-                                                pkt_offset='Ether.{}'.format(direction))
+            stl_vm_wr_flow_var = STLVmWrFlowVar(
+                fv_name='mac_{}'.format(direction),
+                pkt_offset='Ether.{}'.format(direction))
             self.vm_flow_vars.append(stl_vm_wr_flow_var)
         return partial
 
     def _ip_range_action_partial(self, direction, count=1):
         # pylint: disable=unused-argument
         def partial(min_value, max_value, count):
-            ip1 = int(ipaddress.IPv4Address(min_value))
-            ip2 = int(ipaddress.IPv4Address(max_value))
-            actual_count = (ip2 - ip1)
+            _, _, actual_count = self._count_ip(min_value, max_value)
             if not actual_count:
                 count = 1
             elif actual_count < int(count):
                 count = actual_count
 
-            stl_vm_flow_var = STLVmFlowVarRepeatableRandom(name="ip4_{}".format(direction),
-                                                           min_value=min_value,
-                                                           max_value=max_value,
-                                                           size=4,
-                                                           limit=int(count),
-                                                           seed=0x1235)
+            stl_vm_flow_var = STLVmFlowVarRepeatableRandom(
+                name="ip4_{}".format(direction),
+                min_value=min_value,
+                max_value=max_value,
+                size=4,
+                limit=int(count),
+                seed=0x1235)
             self.vm_flow_vars.append(stl_vm_flow_var)
-            stl_vm_wr_flow_var = STLVmWrFlowVar(fv_name='ip4_{}'.format(direction),
-                                                pkt_offset='IP.{}'.format(direction))
+            stl_vm_wr_flow_var = STLVmWrFlowVar(
+                fv_name='ip4_{}'.format(direction),
+                pkt_offset='IP.{}'.format(direction))
             self.vm_flow_vars.append(stl_vm_wr_flow_var)
             stl_vm_fix_ipv4 = STLVmFixIpv4(offset="IP")
             self.vm_flow_vars.append(stl_vm_fix_ipv4)
     def _ip6_range_action_partial(self, direction, _):
         def partial(min_value, max_value, count):
             # pylint: disable=unused-argument
-            min_value, max_value = self._get_start_end_ipv6(min_value, max_value)
+            min_value, max_value, _ = self._count_ip(min_value, max_value)
             stl_vm_flow_var = STLVmFlowVar(name="ip6_{}".format(direction),
                                            min_value=min_value,
                                            max_value=max_value,
                                            op='random',
                                            step=1)
             self.vm_flow_vars.append(stl_vm_flow_var)
-            stl_vm_wr_flow_var = STLVmWrFlowVar(fv_name='ip6_{}'.format(direction),
-                                                pkt_offset='IPv6.{}'.format(direction),
-                                                offset_fixup=8)
+            stl_vm_wr_flow_var = STLVmWrFlowVar(
+                fv_name='ip6_{}'.format(direction),
+                pkt_offset='IPv6.{}'.format(direction),
+                offset_fixup=8)
             self.vm_flow_vars.append(stl_vm_wr_flow_var)
         return partial
 
             elif int(count) > actual_count:
                 count = actual_count
 
-            stl_vm_flow_var = STLVmFlowVarRepeatableRandom(name="port_{}".format(field),
-                                                           min_value=min_value,
-                                                           max_value=max_value,
-                                                           size=2,
-                                                           limit=int(count),
-                                                           seed=0x1235)
+            stl_vm_flow_var = STLVmFlowVarRepeatableRandom(
+                name="port_{}".format(field),
+                min_value=min_value,
+                max_value=max_value,
+                size=2,
+                limit=int(count),
+                seed=0x1235)
             self.vm_flow_vars.append(stl_vm_flow_var)
-            stl_vm_wr_flow_var = STLVmWrFlowVar(fv_name='port_{}'.format(field),
-                                                pkt_offset=self.udp[field])
+            stl_vm_wr_flow_var = STLVmWrFlowVar(
+                fv_name='port_{}'.format(field),
+                pkt_offset=self.udp[field])
             self.vm_flow_vars.append(stl_vm_wr_flow_var)
         return partial
 
         self.profile = STLProfile(self.streams)
 
     @classmethod
-    def _get_start_end_ipv6(cls, start_ip, end_ip):
-        try:
-            ip1 = socket.inet_pton(socket.AF_INET6, start_ip)
-            ip2 = socket.inet_pton(socket.AF_INET6, end_ip)
-            hi1, lo1 = struct.unpack('!QQ', ip1)
-            hi2, lo2 = struct.unpack('!QQ', ip2)
-            if ((hi1 << 64) | lo1) > ((hi2 << 64) | lo2):
-                raise SystemExit("IPv6: start_ip is greater then end_ip")
-            max_p1 = abs(int(lo1) - int(lo2))
-            base_p1 = lo1
-        except Exception as ex_error:
-            raise SystemExit(ex_error)
-        else:
-            return base_p1, max_p1 + base_p1
+    def _count_ip(cls, start_ip, end_ip):
+        start = ipaddress.ip_address(six.u(start_ip))
+        end = ipaddress.ip_address(six.u(end_ip))
+        if start.version == 4:
+            return start, end, int(end) - int(start)
+        elif start.version == 6:
+            if int(start) > int(end):
+                raise y_exc.IPv6RangeError(start_ip=str(start),
+                                           end_ip=str(end))
+            _, lo1 = struct.unpack('!QQ', start.packed)
+            _, lo2 = struct.unpack('!QQ', end.packed)
+            return lo1, lo2, lo2 - lo1
 
     @classmethod
     def _get_random_value(cls, min_port, max_port):