Damjan Marion | f56b77a | 2016-10-03 19:44:57 +0200 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | |
| 3 | import unittest |
| 4 | from framework import VppTestCase, VppTestRunner |
| 5 | from util import Util |
| 6 | from template_bd import BridgeDomain |
| 7 | |
| 8 | from scapy.layers.l2 import Ether |
| 9 | from scapy.layers.inet import IP, UDP |
| 10 | from scapy_handlers.vxlan import VXLAN |
| 11 | |
| 12 | |
| 13 | ## TestVxlan is a subclass of BridgeDomain, Util, VppTestCase classes. |
| 14 | # |
| 15 | # TestVxlan class defines VXLAN test cases for VXLAN encapsulation, |
| 16 | # decapsulation and VXLAN tunnel termination in L2 bridge-domain. |
| 17 | class TestVxlan(BridgeDomain, Util, VppTestCase): |
| 18 | """ VXLAN Test Case """ |
| 19 | |
| 20 | ## Method to initialize all parent classes. |
| 21 | # |
| 22 | # Initialize BridgeDomain objects, set documentation string for inherited |
| 23 | # tests and initialize VppTestCase object which must be called after |
| 24 | # doc strings are set. |
| 25 | def __init__(self, *args): |
| 26 | BridgeDomain.__init__(self) |
| 27 | self.test_decap.__func__.__doc__ = ' VXLAN BD decapsulation ' |
| 28 | self.test_encap.__func__.__doc__ = ' VXLAN BD encapsulation ' |
| 29 | VppTestCase.__init__(self, *args) |
| 30 | |
| 31 | ## Method for VXLAN encapsulate function. |
| 32 | # |
| 33 | # Encapsulate the original payload frame by adding VXLAN header with its |
| 34 | # UDP, IP and Ethernet fields. |
| 35 | def encapsulate(self, pkt): |
| 36 | return (Ether(src=self.MY_MACS[0], dst=self.VPP_MACS[0]) / |
| 37 | IP(src=self.MY_IP4S[0], dst=self.VPP_IP4S[0]) / |
| 38 | UDP(sport=4789, dport=4789, chksum=0) / |
| 39 | VXLAN(vni=1) / |
| 40 | pkt) |
| 41 | |
| 42 | ## Method for VXLAN decapsulate function. |
| 43 | # |
| 44 | # Decapsulate the original payload frame by removing VXLAN header with |
| 45 | # its UDP, IP and Ethernet fields. |
| 46 | def decapsulate(self, pkt): |
| 47 | return pkt[VXLAN].payload |
| 48 | |
| 49 | ## Method for checking VXLAN encapsulation. |
| 50 | # |
| 51 | def check_encapsulation(self, pkt): |
| 52 | # TODO: add error messages |
| 53 | ## Verify source MAC is VPP_MAC and destination MAC is MY_MAC resolved |
| 54 | # by VPP using ARP. |
| 55 | self.assertEqual(pkt[Ether].src, self.VPP_MACS[0]) |
| 56 | self.assertEqual(pkt[Ether].dst, self.MY_MACS[0]) |
| 57 | ## Verify VXLAN tunnel source IP is VPP_IP and destination IP is MY_IP. |
| 58 | self.assertEqual(pkt[IP].src, self.VPP_IP4S[0]) |
| 59 | self.assertEqual(pkt[IP].dst, self.MY_IP4S[0]) |
| 60 | ## Verify UDP destination port is VXLAN 4789, source UDP port could be |
| 61 | # arbitrary. |
| 62 | self.assertEqual(pkt[UDP].dport, 4789) |
| 63 | # TODO: checksum check |
| 64 | ## Verify VNI, based on configuration it must be 1. |
| 65 | self.assertEqual(pkt[VXLAN].vni, 1) |
| 66 | |
| 67 | ## Class method to start the VXLAN test case. |
| 68 | # Overrides setUpClass method in VppTestCase class. |
| 69 | # Python try..except statement is used to ensure that the tear down of |
| 70 | # the class will be executed even if exception is raised. |
| 71 | # @param cls The class pointer. |
| 72 | @classmethod |
| 73 | def setUpClass(cls): |
| 74 | super(TestVxlan, cls).setUpClass() |
| 75 | try: |
| 76 | ## Create 2 pg interfaces. |
| 77 | cls.create_interfaces(range(2)) |
| 78 | ## Configure IPv4 addresses on VPP pg0. |
| 79 | cls.config_ip4([0]) |
| 80 | ## Resolve MAC address for VPP's IP address on pg0. |
| 81 | cls.resolve_arp([0]) |
| 82 | |
| 83 | ## Create VXLAN VTEP on VPP pg0, and put vxlan_tunnel0 and pg1 |
| 84 | # into BD. |
| 85 | cls.api("vxlan_add_del_tunnel src %s dst %s vni 1" % |
| 86 | (cls.VPP_IP4S[0], cls.MY_IP4S[0])) |
| 87 | cls.api("sw_interface_set_l2_bridge vxlan_tunnel0 bd_id 1") |
| 88 | cls.api("sw_interface_set_l2_bridge pg1 bd_id 1") |
| 89 | except: |
| 90 | ## In case setUpClass fails run tear down. |
| 91 | cls.tearDownClass() |
| 92 | raise |
| 93 | |
| 94 | ## Method to define VPP actions before tear down of the test case. |
| 95 | # Overrides tearDown method in VppTestCase class. |
| 96 | # @param self The object pointer. |
| 97 | def tearDown(self): |
| 98 | super(TestVxlan, self).tearDown() |
| 99 | self.cli(2, "show bridge-domain 1 detail") |
| 100 | |
| 101 | if __name__ == '__main__': |
| 102 | unittest.main(testRunner=VppTestRunner) |