blob: 9b5baaea13270fba104f1b9517d77865673a33f2 [file] [log] [blame]
Pierre Pfisterf588f352016-10-07 16:31:57 +01001import socket
Pierre Pfisterf588f352016-10-07 16:31:57 +01002
Pierre Pfisterf588f352016-10-07 16:31:57 +01003from scapy.layers.inet import IP, UDP
Klement Sekera65cc8c02016-12-18 15:49:54 +01004from scapy.layers.inet6 import IPv6
Klement Sekeraf62ae122016-10-11 11:47:09 +02005from scapy.layers.l2 import Ether, GRE
6from scapy.packet import Raw
Pierre Pfisterf588f352016-10-07 16:31:57 +01007
Klement Sekeraf62ae122016-10-11 11:47:09 +02008from framework import VppTestCase
Klement Sekera7bb873a2016-11-18 07:38:42 +01009from util import ppp
Klement Sekeraf62ae122016-10-11 11:47:09 +020010
11""" TestLB is a subclass of VPPTestCase classes.
12
13 TestLB class defines Load Balancer test cases for:
14 - IP4 to GRE4 encap
15 - IP4 to GRE6 encap
16 - IP6 to GRE4 encap
17 - IP6 to GRE6 encap
18
19 As stated in comments below, GRE has issues with IPv6.
20 All test cases involving IPv6 are executed, but
21 received packets are not parsed and checked.
22
23"""
24
25
26class TestLB(VppTestCase):
Pierre Pfisterf588f352016-10-07 16:31:57 +010027 """ Load Balancer Test Case """
28
29 @classmethod
30 def setUpClass(cls):
31 super(TestLB, cls).setUpClass()
32
33 cls.ass = range(5)
34 cls.packets = range(100)
35
36 try:
Klement Sekeraf62ae122016-10-11 11:47:09 +020037 cls.create_pg_interfaces(range(2))
38 cls.interfaces = list(cls.pg_interfaces)
Pierre Pfisterf588f352016-10-07 16:31:57 +010039
Klement Sekeraf62ae122016-10-11 11:47:09 +020040 for i in cls.interfaces:
41 i.admin_up()
42 i.config_ip4()
43 i.config_ip6()
44 i.disable_ipv6_ra()
45 i.resolve_arp()
46 i.resolve_ndp()
47 dst4 = socket.inet_pton(socket.AF_INET, "10.0.0.0")
48 dst6 = socket.inet_pton(socket.AF_INET6, "2002::")
49 cls.vapi.ip_add_del_route(dst4, 24, cls.pg1.remote_ip4n)
50 cls.vapi.ip_add_del_route(dst6, 16, cls.pg1.remote_ip6n, is_ipv6=1)
51 cls.vapi.cli("lb conf ip4-src-address 39.40.41.42")
52 cls.vapi.cli("lb conf ip6-src-address 2004::1")
53 except Exception:
Pierre Pfisterf588f352016-10-07 16:31:57 +010054 super(TestLB, cls).tearDownClass()
55 raise
56
57 def tearDown(self):
Klement Sekeraf62ae122016-10-11 11:47:09 +020058 super(TestLB, self).tearDown()
59 if not self.vpp_dead:
Klement Sekera7bb873a2016-11-18 07:38:42 +010060 self.logger.info(self.vapi.cli("show lb vip verbose"))
Pierre Pfisterf588f352016-10-07 16:31:57 +010061
62 def getIPv4Flow(self, id):
63 return (IP(dst="90.0.%u.%u" % (id / 255, id % 255),
Klement Sekeraf62ae122016-10-11 11:47:09 +020064 src="40.0.%u.%u" % (id / 255, id % 255)) /
Pierre Pfisterf588f352016-10-07 16:31:57 +010065 UDP(sport=10000 + id, dport=20000 + id))
66
67 def getIPv6Flow(self, id):
68 return (IPv6(dst="2001::%u" % (id), src="fd00:f00d:ffff::%u" % (id)) /
Klement Sekeraf62ae122016-10-11 11:47:09 +020069 UDP(sport=10000 + id, dport=20000 + id))
Pierre Pfisterf588f352016-10-07 16:31:57 +010070
Klement Sekeraf62ae122016-10-11 11:47:09 +020071 def generatePackets(self, src_if, isv4):
Matej Klottond6338ab2016-11-10 15:36:19 +010072 self.packet_infos = {}
Pierre Pfisterf588f352016-10-07 16:31:57 +010073 pkts = []
74 for pktid in self.packets:
Klement Sekeraf62ae122016-10-11 11:47:09 +020075 info = self.create_packet_info(src_if.sw_if_index, pktid)
Pierre Pfisterf588f352016-10-07 16:31:57 +010076 payload = self.info_to_payload(info)
77 ip = self.getIPv4Flow(pktid) if isv4 else self.getIPv6Flow(pktid)
Klement Sekeraf62ae122016-10-11 11:47:09 +020078 packet = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
79 ip /
80 Raw(payload))
Pierre Pfisterf588f352016-10-07 16:31:57 +010081 self.extend_packet(packet, 128)
82 info.data = packet.copy()
83 pkts.append(packet)
84 return pkts
85
86 def checkInner(self, gre, isv4):
Klement Sekeraf62ae122016-10-11 11:47:09 +020087 IPver = IP if isv4 else IPv6
Pierre Pfisterf588f352016-10-07 16:31:57 +010088 self.assertEqual(gre.proto, 0x0800 if isv4 else 0x86DD)
89 self.assertEqual(gre.flags, 0)
90 self.assertEqual(gre.version, 0)
Klement Sekeraf62ae122016-10-11 11:47:09 +020091 inner = IPver(str(gre.payload))
92 payload_info = self.payload_to_info(str(inner[Raw]))
Klement Sekerad72fdf52016-11-08 08:48:30 +010093 self.info = self.get_next_packet_info_for_interface2(
94 self.pg0.sw_if_index, payload_info.dst, self.info)
Klement Sekeraf62ae122016-10-11 11:47:09 +020095 self.assertEqual(str(inner), str(self.info.data[IPver]))
Pierre Pfisterf588f352016-10-07 16:31:57 +010096
97 def checkCapture(self, gre4, isv4):
Klement Sekera65cc8c02016-12-18 15:49:54 +010098 self.pg0.assert_nothing_captured()
Klement Sekeraf62ae122016-10-11 11:47:09 +020099 out = self.pg1.get_capture()
Pierre Pfisterf588f352016-10-07 16:31:57 +0100100 self.assertEqual(len(out), len(self.packets))
101
102 load = [0] * len(self.ass)
103 self.info = None
104 for p in out:
105 try:
106 asid = 0
107 gre = None
108 if gre4:
109 ip = p[IP]
Pierre Pfisterf588f352016-10-07 16:31:57 +0100110 asid = int(ip.dst.split(".")[3])
111 self.assertEqual(ip.version, 4)
112 self.assertEqual(ip.flags, 0)
113 self.assertEqual(ip.src, "39.40.41.42")
114 self.assertEqual(ip.dst, "10.0.0.%u" % asid)
115 self.assertEqual(ip.proto, 47)
116 self.assertEqual(len(ip.options), 0)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200117 self.assertGreaterEqual(ip.ttl, 64)
118 gre = p[GRE]
Pierre Pfisterf588f352016-10-07 16:31:57 +0100119 else:
120 ip = p[IPv6]
Pierre Pfisterf588f352016-10-07 16:31:57 +0100121 asid = ip.dst.split(":")
122 asid = asid[len(asid) - 1]
Klement Sekeraf62ae122016-10-11 11:47:09 +0200123 asid = 0 if asid == "" else int(asid)
Pierre Pfisterf588f352016-10-07 16:31:57 +0100124 self.assertEqual(ip.version, 6)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200125 self.assertEqual(ip.tc, 0)
126 self.assertEqual(ip.fl, 0)
127 self.assertEqual(ip.src, "2004::1")
128 self.assertEqual(
129 socket.inet_pton(socket.AF_INET6, ip.dst),
130 socket.inet_pton(socket.AF_INET6, "2002::%u" % asid)
131 )
132 self.assertEqual(ip.nh, 47)
133 self.assertGreaterEqual(ip.hlim, 64)
134 # self.assertEqual(len(ip.options), 0)
135 gre = GRE(str(p[IPv6].payload))
Pierre Pfisterf588f352016-10-07 16:31:57 +0100136 self.checkInner(gre, isv4)
137 load[asid] += 1
138 except:
Klement Sekera7bb873a2016-11-18 07:38:42 +0100139 self.logger.error(ppp("Unexpected or invalid packet:", p))
Pierre Pfisterf588f352016-10-07 16:31:57 +0100140 raise
141
142 # This is just to roughly check that the balancing algorithm
143 # is not completly biased.
144 for asid in self.ass:
Klement Sekeraf62ae122016-10-11 11:47:09 +0200145 if load[asid] < len(self.packets) / (len(self.ass) * 2):
146 self.log(
147 "ASS is not balanced: load[%d] = %d" % (asid, load[asid]))
Pierre Pfisterf588f352016-10-07 16:31:57 +0100148 raise Exception("Load Balancer algorithm is biased")
149
Pierre Pfisterf588f352016-10-07 16:31:57 +0100150 def test_lb_ip4_gre4(self):
151 """ Load Balancer IP4 GRE4 """
Klement Sekeraf62ae122016-10-11 11:47:09 +0200152 try:
153 self.vapi.cli("lb vip 90.0.0.0/8 encap gre4")
154 for asid in self.ass:
155 self.vapi.cli("lb as 90.0.0.0/8 10.0.0.%u" % (asid))
Pierre Pfisterf588f352016-10-07 16:31:57 +0100156
Klement Sekeraf62ae122016-10-11 11:47:09 +0200157 self.pg0.add_stream(self.generatePackets(self.pg0, isv4=True))
158 self.pg_enable_capture(self.pg_interfaces)
159 self.pg_start()
160 self.checkCapture(gre4=True, isv4=True)
Pierre Pfisterf588f352016-10-07 16:31:57 +0100161
Klement Sekeraf62ae122016-10-11 11:47:09 +0200162 finally:
163 for asid in self.ass:
164 self.vapi.cli("lb as 90.0.0.0/8 10.0.0.%u del" % (asid))
165 self.vapi.cli("lb vip 90.0.0.0/8 encap gre4 del")
Pierre Pfisterf588f352016-10-07 16:31:57 +0100166
167 def test_lb_ip6_gre4(self):
168 """ Load Balancer IP6 GRE4 """
169
Klement Sekeraf62ae122016-10-11 11:47:09 +0200170 try:
171 self.vapi.cli("lb vip 2001::/16 encap gre4")
172 for asid in self.ass:
173 self.vapi.cli("lb as 2001::/16 10.0.0.%u" % (asid))
Pierre Pfisterf588f352016-10-07 16:31:57 +0100174
Klement Sekeraf62ae122016-10-11 11:47:09 +0200175 self.pg0.add_stream(self.generatePackets(self.pg0, isv4=False))
176 self.pg_enable_capture(self.pg_interfaces)
177 self.pg_start()
Pierre Pfisterf588f352016-10-07 16:31:57 +0100178
Matej Klottond6338ab2016-11-10 15:36:19 +0100179 self.checkCapture(gre4=True, isv4=False)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200180 finally:
181 for asid in self.ass:
182 self.vapi.cli("lb as 2001::/16 10.0.0.%u del" % (asid))
183 self.vapi.cli("lb vip 2001::/16 encap gre4 del")
Pierre Pfisterf588f352016-10-07 16:31:57 +0100184
185 def test_lb_ip4_gre6(self):
186 """ Load Balancer IP4 GRE6 """
Klement Sekeraf62ae122016-10-11 11:47:09 +0200187 try:
188 self.vapi.cli("lb vip 90.0.0.0/8 encap gre6")
189 for asid in self.ass:
190 self.vapi.cli("lb as 90.0.0.0/8 2002::%u" % (asid))
Pierre Pfisterf588f352016-10-07 16:31:57 +0100191
Klement Sekeraf62ae122016-10-11 11:47:09 +0200192 self.pg0.add_stream(self.generatePackets(self.pg0, isv4=True))
193 self.pg_enable_capture(self.pg_interfaces)
194 self.pg_start()
Pierre Pfisterf588f352016-10-07 16:31:57 +0100195
Matej Klottond6338ab2016-11-10 15:36:19 +0100196 self.checkCapture(gre4=False, isv4=True)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200197 finally:
198 for asid in self.ass:
199 self.vapi.cli("lb as 90.0.0.0/8 2002::%u" % (asid))
200 self.vapi.cli("lb vip 90.0.0.0/8 encap gre6 del")
Pierre Pfisterf588f352016-10-07 16:31:57 +0100201
202 def test_lb_ip6_gre6(self):
203 """ Load Balancer IP6 GRE6 """
Klement Sekeraf62ae122016-10-11 11:47:09 +0200204 try:
205 self.vapi.cli("lb vip 2001::/16 encap gre6")
206 for asid in self.ass:
207 self.vapi.cli("lb as 2001::/16 2002::%u" % (asid))
Pierre Pfisterf588f352016-10-07 16:31:57 +0100208
Klement Sekeraf62ae122016-10-11 11:47:09 +0200209 self.pg0.add_stream(self.generatePackets(self.pg0, isv4=False))
210 self.pg_enable_capture(self.pg_interfaces)
211 self.pg_start()
Pierre Pfisterf588f352016-10-07 16:31:57 +0100212
Matej Klottond6338ab2016-11-10 15:36:19 +0100213 self.checkCapture(gre4=False, isv4=False)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200214 finally:
215 for asid in self.ass:
216 self.vapi.cli("lb as 2001::/16 2002::%u del" % (asid))
217 self.vapi.cli("lb vip 2001::/16 encap gre6 del")