예제 #1
0
파일: test_map.py 프로젝트: lfntac/vpp
    def test_map_e(self):
        """ MAP-E """

        #
        # Add a route to the MAP-BR
        #
        map_br_pfx = "2001::"
        map_br_pfx_len = 64
        map_route = VppIpRoute(self,
                               map_br_pfx,
                               map_br_pfx_len, [
                                   VppRoutePath(self.pg1.remote_ip6,
                                                self.pg1.sw_if_index,
                                                proto=DpoProto.DPO_PROTO_IP6)
                               ],
                               is_ip6=1)
        map_route.add_vpp_config()

        #
        # Add a domain that maps from pg0 to pg1
        #
        map_dst = '2001::/64'
        map_src = '3000::1/128'
        client_pfx = '192.168.0.0/16'
        self.vapi.map_add_domain(map_dst, client_pfx, map_src)

        # Enable MAP on interface.
        self.vapi.map_if_enable_disable(is_enable=1,
                                        sw_if_index=self.pg0.sw_if_index,
                                        is_translation=0)

        # Ensure MAP doesn't steal all packets!
        v4 = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
              IP(src=self.pg0.remote_ip4, dst=self.pg0.remote_ip4) /
              UDP(sport=20000, dport=10000) / Raw('\xa5' * 100))
        rx = self.send_and_expect(self.pg0, v4 * 1, self.pg0)
        v4_reply = v4[1]
        v4_reply.ttl -= 1
        for p in rx:
            self.validate(p[1], v4_reply)

        #
        # Fire in a v4 packet that will be encapped to the BR
        #
        v4 = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
              IP(src=self.pg0.remote_ip4, dst='192.168.1.1') /
              UDP(sport=20000, dport=10000) / Raw('\xa5' * 100))

        self.send_and_assert_encapped(v4, "3000::1", "2001::c0a8:0:0")

        # Enable MAP on interface.
        self.vapi.map_if_enable_disable(is_enable=1,
                                        sw_if_index=self.pg1.sw_if_index,
                                        is_translation=0)

        # Ensure MAP doesn't steal all packets
        v6 = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
              IPv6(src=self.pg1.remote_ip6, dst=self.pg1.remote_ip6) /
              UDP(sport=20000, dport=10000) / Raw('\xa5' * 100))
        rx = self.send_and_expect(self.pg1, v6 * 1, self.pg1)
        v6_reply = v6[1]
        v6_reply.hlim -= 1
        for p in rx:
            self.validate(p[1], v6_reply)

        #
        # Fire in a V6 encapped packet.
        #  expect a decapped packet on the inside ip4 link
        #
        p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
             IPv6(dst='3000::1', src="2001::1") /
             IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
             UDP(sport=20000, dport=10000) / Raw('\xa5' * 100))

        self.pg1.add_stream(p)

        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

        rx = self.pg0.get_capture(1)
        rx = rx[0]

        self.assertFalse(rx.haslayer(IPv6))
        self.assertEqual(rx[IP].src, p[IP].src)
        self.assertEqual(rx[IP].dst, p[IP].dst)

        #
        # Pre-resolve. No API for this!!
        #
        self.vapi.ppcli("map params pre-resolve ip6-nh 4001::1")

        self.send_and_assert_no_replies(self.pg0, v4,
                                        "resolved via default route")

        #
        # Add a route to 4001::1. Expect the encapped traffic to be
        # sent via that routes next-hop
        #
        pre_res_route = VppIpRoute(
            self,
            "4001::1",
            128, [
                VppRoutePath(self.pg1.remote_hosts[2].ip6,
                             self.pg1.sw_if_index,
                             proto=DpoProto.DPO_PROTO_IP6)
            ],
            is_ip6=1)
        pre_res_route.add_vpp_config()

        self.send_and_assert_encapped(v4,
                                      "3000::1",
                                      "2001::c0a8:0:0",
                                      dmac=self.pg1.remote_hosts[2].mac)

        #
        # change the route to the pre-solved next-hop
        #
        pre_res_route.modify([
            VppRoutePath(self.pg1.remote_hosts[3].ip6,
                         self.pg1.sw_if_index,
                         proto=DpoProto.DPO_PROTO_IP6)
        ])
        pre_res_route.add_vpp_config()

        self.send_and_assert_encapped(v4,
                                      "3000::1",
                                      "2001::c0a8:0:0",
                                      dmac=self.pg1.remote_hosts[3].mac)

        #
        # cleanup. The test infra's object registry will ensure
        # the route is really gone and thus that the unresolve worked.
        #
        pre_res_route.remove_vpp_config()
        self.vapi.ppcli("map params pre-resolve del ip6-nh 4001::1")
예제 #2
0
    def create_ip(self, src_ip=None, dst_ip=None, tran_l_proto="UDP", pkt_len=None, src_port=None, dst_port=None, cnt=100, inter=0.01):
        
        # If src_ip is named in machines, use that, and its mac addr
        # Else if src_ip written in octet format, use it and random addr
        # Else randomly select from machnes given along with mac
        
        #--------------------------------------
        # SRC IP, MAC, PORT
        #--------------------------------------
        if src_ip == None:
            # Select key at random
            machine_name = random.choice(list(machines.keys()))
            src = machines[machine_name]['ip']
            # Select random mac
            src_mac = self.rand_mac()
            
        elif src_ip in machines:
            src = machines[src_ip]['ip']
            src_mac = machines[src_ip]['mac']
            if src_port == None:
                src_port = machines[src_ip]['port']
        
        else:
            # Custom IP
            src = src_ip
            # Random mac
            src_mac = self.rand_mac()
        
        if src_port == None:
            src_port = self.random_port()
        else:
            src_port = int(src_port)
            
        print(src, src_mac, src_port)

        #--------------------------------------
        # DST IP, MAC, PORT
        #--------------------------------------
       
        if dst_ip == None:
            # Select key at random
            machine_name = random.choice(list(machines.keys()))
            dst = machines[machine_name]['ip']
            # Select random mac
            dst_mac = self.rand_mac()
            
        elif dst_ip in machines:
            dst = machines[dst_ip]['ip']
            dst_mac = machines[dst_ip]['mac']
            if dst_port == None:
                dst_port = machines[dst_ip]['port']
        
        else:
            # Custom IP
            dst = dst_ip
            # Random mac
            dst_mac = self.rand_mac()
        
        if dst_port == None:
            dst_port = self.random_port()
        else:
            dst_port = int(dst_port)
        print(dst, dst_mac, dst_port)
        
        #--------------------------------------
        # LENGTH, Protocol
        #--------------------------------------
        if pkt_len is None:
            pkt_len = random.randint(1, PKT_MAX_LEN)
        load = os.urandom(int(pkt_len))
        
        #--------------------------------------
        # Packet gerneration
        #--------------------------------------      
        pkt = None
        if tran_l_proto == "UDP":
            pkt = Ether(dst=dst_mac, 
                        src=src_mac,
                        type=ETHER_TYPES['IPv4'])/\
                  IP(dst=dst,
                     src=src,)/\
                  UDP(dport=dst_port,
                      sport=src_port)/\
                  Raw(load=load)
            #print(len(load))
            pkt.show2()
        
        else:
        # TCP
            pkt = Ether(dst=dst_mac, 
                        src=src_mac,
                        type=ETHER_TYPES['IPv4'])/\
                  IP(dst=dst,
                     src=src,)/\
                  TCP(dport=dst_port,
                      sport=src_port)/\
                  Raw(load=load)
            #print(len(load))
            pkt.show2()
        return pkt
예제 #3
0
    def test_fif6(self):
        """ Fragments in fragments (6o6) """
        # TODO this should be ideally in setUpClass, but then we hit a bug
        # with VppIpRoute incorrectly reporting it's present when it's not
        # so we need to manually remove the vpp config, thus we cannot have
        # it shared for multiple test cases
        self.tun_ip6 = "1002::1"

        self.gre6 = VppGre6Interface(self, self.src_if.local_ip6, self.tun_ip6)
        self.gre6.add_vpp_config()
        self.gre6.admin_up()
        self.gre6.config_ip6()

        self.vapi.ip_reassembly_enable_disable(
            sw_if_index=self.gre6.sw_if_index, enable_ip6=True)

        self.route6 = VppIpRoute(self,
                                 self.tun_ip6,
                                 128, [
                                     VppRoutePath(self.src_if.remote_ip6,
                                                  self.src_if.sw_if_index,
                                                  proto=DpoProto.DPO_PROTO_IP6)
                                 ],
                                 is_ip6=1)
        self.route6.add_vpp_config()

        self.reset_packet_infos()
        for i in range(test_packet_count):
            info = self.create_packet_info(self.src_if, self.dst_if)
            payload = self.info_to_payload(info)
            # Ethernet header here is only for size calculation, thus it
            # doesn't matter how it's initialized. This is to ensure that
            # reassembled packet is not > 9000 bytes, so that it's not dropped
            p = (Ether() /
                 IPv6(src=self.src_if.remote_ip6, dst=self.dst_if.remote_ip6) /
                 UDP(sport=1234, dport=5678) / Raw(payload))
            size = self.packet_sizes[(i // 2) % len(self.packet_sizes)]
            self.extend_packet(p, size, self.padding)
            info.data = p[IPv6]  # use only IPv6 part, without ethernet header

        fragments = [
            x for _, i in six.iteritems(self._packet_infos)
            for x in fragment_rfc8200(i.data, i.index, 400)
        ]

        encapped_fragments = \
            [Ether(dst=self.src_if.local_mac, src=self.src_if.remote_mac) /
             IPv6(src=self.tun_ip6, dst=self.src_if.local_ip6) /
                GRE() /
                p
                for p in fragments]

        fragmented_encapped_fragments = \
            [x for p in encapped_fragments for x in (
                fragment_rfc8200(
                    p,
                    2 * len(self._packet_infos) + p[IPv6ExtHdrFragment].id,
                    200)
                if IPv6ExtHdrFragment in p else [p]
            )
            ]

        self.src_if.add_stream(fragmented_encapped_fragments)

        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

        self.src_if.assert_nothing_captured()
        packets = self.dst_if.get_capture(len(self._packet_infos))
        self.verify_capture(packets, IPv6)

        # TODO remove gre vpp config by hand until VppIpRoute gets fixed
        # so that it's query_vpp_config() works as it should
        self.gre6.remove_vpp_config()
예제 #4
0
파일: test_bier.py 프로젝트: pankaj364/vpp
    def test_bier_tail_o_udp(self):
        """BIER Tail over UDP"""

        #
        # Add a BIER table for sub-domain 0, set 0, and BSL 256
        #
        bti = VppBierTableID(1, 0, BIERLength.BIER_LEN_256)
        bt = VppBierTable(self, bti, MPLS_LABEL_INVALID)
        bt.add_vpp_config()

        #
        # disposition table
        #
        bdt = VppBierDispTable(self, 8)
        bdt.add_vpp_config()

        #
        # BIER route in table that's for-us
        #
        bier_route_1 = VppBierRoute(
            self, bti, 1, [VppRoutePath("0.0.0.0", 0xffffffff, nh_table_id=8)])
        bier_route_1.add_vpp_config()

        #
        # An entry in the disposition table
        #
        bier_de_1 = VppBierDispEntry(self,
                                     bdt.id,
                                     99,
                                     BIER_HDR_PAYLOAD.BIER_HDR_PROTO_IPV4,
                                     DpoProto.DPO_PROTO_BIER,
                                     "0.0.0.0",
                                     0,
                                     rpf_id=8192)
        bier_de_1.add_vpp_config()

        #
        # A multicast route to forward post BIER disposition
        #
        route_eg_232_1_1_1 = VppIpMRoute(
            self,
            "0.0.0.0",
            "232.1.1.1",
            32,
            MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
            paths=[
                VppMRoutePath(self.pg1.sw_if_index,
                              MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)
            ])
        route_eg_232_1_1_1.add_vpp_config()
        route_eg_232_1_1_1.update_rpf_id(8192)

        #
        # A packet with all bits set gets spat out to BP:1
        #
        p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
             IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) /
             UDP(sport=333, dport=8138) / BIFT(sd=1, set=0, bsl=2, ttl=255) /
             BIER(length=BIERLength.BIER_LEN_256,
                  BitString=chr(255) * 32,
                  BFRID=99) / IP(src="1.1.1.1", dst="232.1.1.1") /
             UDP(sport=1234, dport=1234) / Raw())

        rx = self.send_and_expect(self.pg0, [p], self.pg1)
예제 #5
0
async def run_test(dut):

    tb = TB(dut)

    await tb.init()

    tb.log.info("test UDP RX packet")

    payload = bytes([x % 256 for x in range(256)])
    eth = Ether(src='5a:51:52:53:54:55', dst='02:00:00:00:00:00')
    ip = IP(src='192.168.1.100', dst='192.168.1.128')
    udp = UDP(sport=5678, dport=1234)
    test_pkt = eth / ip / udp / payload

    test_frame = XgmiiFrame.from_payload(test_pkt.build())

    await tb.qsfp_0_0_source.send(test_frame)

    tb.log.info("receive ARP request")

    rx_frame = await tb.qsfp_0_0_sink.recv()

    rx_pkt = Ether(bytes(rx_frame.get_payload()))

    tb.log.info("RX packet: %s", repr(rx_pkt))

    assert rx_pkt.dst == 'ff:ff:ff:ff:ff:ff'
    assert rx_pkt.src == test_pkt.dst
    assert rx_pkt[ARP].hwtype == 1
    assert rx_pkt[ARP].ptype == 0x0800
    assert rx_pkt[ARP].hwlen == 6
    assert rx_pkt[ARP].plen == 4
    assert rx_pkt[ARP].op == 1
    assert rx_pkt[ARP].hwsrc == test_pkt.dst
    assert rx_pkt[ARP].psrc == test_pkt[IP].dst
    assert rx_pkt[ARP].hwdst == '00:00:00:00:00:00'
    assert rx_pkt[ARP].pdst == test_pkt[IP].src

    tb.log.info("send ARP response")

    eth = Ether(src=test_pkt.src, dst=test_pkt.dst)
    arp = ARP(hwtype=1,
              ptype=0x0800,
              hwlen=6,
              plen=4,
              op=2,
              hwsrc=test_pkt.src,
              psrc=test_pkt[IP].src,
              hwdst=test_pkt.dst,
              pdst=test_pkt[IP].dst)
    resp_pkt = eth / arp

    resp_frame = XgmiiFrame.from_payload(resp_pkt.build())

    await tb.qsfp_0_0_source.send(resp_frame)

    tb.log.info("receive UDP packet")

    rx_frame = await tb.qsfp_0_0_sink.recv()

    rx_pkt = Ether(bytes(rx_frame.get_payload()))

    tb.log.info("RX packet: %s", repr(rx_pkt))

    assert rx_pkt.dst == test_pkt.src
    assert rx_pkt.src == test_pkt.dst
    assert rx_pkt[IP].dst == test_pkt[IP].src
    assert rx_pkt[IP].src == test_pkt[IP].dst
    assert rx_pkt[UDP].dport == test_pkt[UDP].sport
    assert rx_pkt[UDP].sport == test_pkt[UDP].dport
    assert rx_pkt[UDP].payload == test_pkt[UDP].payload

    await RisingEdge(dut.clk)
    await RisingEdge(dut.clk)
예제 #6
0
파일: test_bier.py 프로젝트: pankaj364/vpp
    def test_bier_head(self):
        """BIER head"""

        #
        # Add a BIER table for sub-domain 0, set 0, and BSL 256
        #
        bti = VppBierTableID(0, 0, BIERLength.BIER_LEN_256)
        bt = VppBierTable(self, bti, 77)
        bt.add_vpp_config()

        #
        # 2 bit positions via two next hops
        #
        nh1 = "10.0.0.1"
        nh2 = "10.0.0.2"
        ip_route_1 = VppIpRoute(self, nh1, 32, [
            VppRoutePath(
                self.pg1.remote_ip4, self.pg1.sw_if_index, labels=[2001])
        ])
        ip_route_2 = VppIpRoute(self, nh2, 32, [
            VppRoutePath(
                self.pg1.remote_ip4, self.pg1.sw_if_index, labels=[2002])
        ])
        ip_route_1.add_vpp_config()
        ip_route_2.add_vpp_config()

        bier_route_1 = VppBierRoute(
            self, bti, 1, [VppRoutePath(nh1, 0xffffffff, labels=[101])])
        bier_route_2 = VppBierRoute(
            self, bti, 2, [VppRoutePath(nh2, 0xffffffff, labels=[102])])
        bier_route_1.add_vpp_config()
        bier_route_2.add_vpp_config()

        #
        # An imposition object with both bit-positions set
        #
        bi = VppBierImp(self, bti, 333, chr(0x3) * 32)
        bi.add_vpp_config()

        #
        # Add a multicast route that will forward into the BIER doamin
        #
        route_ing_232_1_1_1 = VppIpMRoute(
            self,
            "0.0.0.0",
            "232.1.1.1",
            32,
            MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
            paths=[
                VppMRoutePath(self.pg0.sw_if_index,
                              MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT),
                VppMRoutePath(0xffffffff,
                              MRouteItfFlags.MFIB_ITF_FLAG_FORWARD,
                              proto=DpoProto.DPO_PROTO_BIER,
                              bier_imp=bi.bi_index)
            ])
        route_ing_232_1_1_1.add_vpp_config()

        #
        # inject an IP packet. We expect it to be BIER encapped and
        # replicated.
        #
        p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
             IP(src="1.1.1.1", dst="232.1.1.1") / UDP(sport=1234, dport=1234))

        self.pg0.add_stream([p])
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

        rx = self.pg1.get_capture(2)

        #
        # Encap Stack is; eth, MPLS, MPLS, BIER
        #
        igp_mpls = rx[0][MPLS]
        self.assertEqual(igp_mpls.label, 2001)
        self.assertEqual(igp_mpls.ttl, 64)
        self.assertEqual(igp_mpls.s, 0)
        bier_mpls = igp_mpls[MPLS].payload
        self.assertEqual(bier_mpls.label, 101)
        self.assertEqual(bier_mpls.ttl, 64)
        self.assertEqual(bier_mpls.s, 1)
        self.assertEqual(rx[0][BIER].length, 2)

        igp_mpls = rx[1][MPLS]
        self.assertEqual(igp_mpls.label, 2002)
        self.assertEqual(igp_mpls.ttl, 64)
        self.assertEqual(igp_mpls.s, 0)
        bier_mpls = igp_mpls[MPLS].payload
        self.assertEqual(bier_mpls.label, 102)
        self.assertEqual(bier_mpls.ttl, 64)
        self.assertEqual(bier_mpls.s, 1)
        self.assertEqual(rx[0][BIER].length, 2)
예제 #7
0
파일: test_bier.py 프로젝트: pankaj364/vpp
    def bier_e2e(self, hdr_len_id, n_bytes, max_bp):
        """ BIER end-to-end"""

        #
        # Add a BIER table for sub-domain 0, set 0, and BSL 256
        #
        bti = VppBierTableID(0, 0, hdr_len_id)
        bt = VppBierTable(self, bti, 77)
        bt.add_vpp_config()

        lowest = ['\0'] * (n_bytes)
        lowest[-1] = chr(1)
        highest = ['\0'] * (n_bytes)
        highest[0] = chr(128)

        #
        # Impostion Sets bit strings
        #
        bi_low = VppBierImp(self, bti, 333, lowest)
        bi_low.add_vpp_config()
        bi_high = VppBierImp(self, bti, 334, highest)
        bi_high.add_vpp_config()

        #
        # Add a multicast route that will forward into the BIER doamin
        #
        route_ing_232_1_1_1 = VppIpMRoute(
            self,
            "0.0.0.0",
            "232.1.1.1",
            32,
            MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
            paths=[
                VppMRoutePath(self.pg0.sw_if_index,
                              MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT),
                VppMRoutePath(0xffffffff,
                              MRouteItfFlags.MFIB_ITF_FLAG_FORWARD,
                              proto=DpoProto.DPO_PROTO_BIER,
                              bier_imp=bi_low.bi_index)
            ])
        route_ing_232_1_1_1.add_vpp_config()
        route_ing_232_1_1_2 = VppIpMRoute(
            self,
            "0.0.0.0",
            "232.1.1.2",
            32,
            MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
            paths=[
                VppMRoutePath(self.pg0.sw_if_index,
                              MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT),
                VppMRoutePath(0xffffffff,
                              MRouteItfFlags.MFIB_ITF_FLAG_FORWARD,
                              proto=DpoProto.DPO_PROTO_BIER,
                              bier_imp=bi_high.bi_index)
            ])
        route_ing_232_1_1_2.add_vpp_config()

        #
        # disposition table 8
        #
        bdt = VppBierDispTable(self, 8)
        bdt.add_vpp_config()

        #
        # BIER routes in table that are for-us, resolving through
        # disp table 8.
        #
        bier_route_1 = VppBierRoute(
            self, bti, 1, [VppRoutePath("0.0.0.0", 0xffffffff, nh_table_id=8)])
        bier_route_1.add_vpp_config()
        bier_route_max = VppBierRoute(
            self, bti, max_bp,
            [VppRoutePath("0.0.0.0", 0xffffffff, nh_table_id=8)])
        bier_route_max.add_vpp_config()

        #
        # An entry in the disposition table for sender 333
        #  lookup in VRF 10
        #
        bier_de_1 = VppBierDispEntry(self,
                                     bdt.id,
                                     333,
                                     BIER_HDR_PAYLOAD.BIER_HDR_PROTO_IPV4,
                                     DpoProto.DPO_PROTO_BIER,
                                     "0.0.0.0",
                                     10,
                                     rpf_id=8192)
        bier_de_1.add_vpp_config()
        bier_de_1 = VppBierDispEntry(self,
                                     bdt.id,
                                     334,
                                     BIER_HDR_PAYLOAD.BIER_HDR_PROTO_IPV4,
                                     DpoProto.DPO_PROTO_BIER,
                                     "0.0.0.0",
                                     10,
                                     rpf_id=8193)
        bier_de_1.add_vpp_config()

        #
        # Add a multicast routes that will forward the traffic
        # post-disposition
        #
        route_eg_232_1_1_1 = VppIpMRoute(
            self,
            "0.0.0.0",
            "232.1.1.1",
            32,
            MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
            table_id=10,
            paths=[
                VppMRoutePath(self.pg1.sw_if_index,
                              MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)
            ])
        route_eg_232_1_1_1.add_vpp_config()
        route_eg_232_1_1_1.update_rpf_id(8192)
        route_eg_232_1_1_2 = VppIpMRoute(
            self,
            "0.0.0.0",
            "232.1.1.2",
            32,
            MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
            table_id=10,
            paths=[
                VppMRoutePath(self.pg1.sw_if_index,
                              MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)
            ])
        route_eg_232_1_1_2.add_vpp_config()
        route_eg_232_1_1_2.update_rpf_id(8193)

        #
        # inject a packet in VRF-0. We expect it to be BIER encapped,
        # replicated, then hit the disposition and be forwarded
        # out of VRF 10, i.e. on pg1
        #
        p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
             IP(src="1.1.1.1", dst="232.1.1.1") / UDP(sport=1234, dport=1234) /
             Raw(chr(5) * 32))

        rx = self.send_and_expect(self.pg0, p * 65, self.pg1)

        self.assertEqual(rx[0][IP].src, "1.1.1.1")
        self.assertEqual(rx[0][IP].dst, "232.1.1.1")

        p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
             IP(src="1.1.1.1", dst="232.1.1.2") / UDP(sport=1234, dport=1234) /
             Raw(chr(5) * 512))

        rx = self.send_and_expect(self.pg0, p * 65, self.pg1)
        self.assertEqual(rx[0][IP].src, "1.1.1.1")
        self.assertEqual(rx[0][IP].dst, "232.1.1.2")
예제 #8
0
    def test_wg_peer_init(self):
        """ Handoff """
        wg_output_node_name = '/err/wg-output-tun/'
        wg_input_node_name = '/err/wg-input/'

        port = 12353

        # Create interfaces
        wg0 = VppWgInterface(self, self.pg1.local_ip4, port).add_vpp_config()
        wg0.admin_up()
        wg0.config_ip4()

        peer_1 = VppWgPeer(self, wg0, self.pg1.remote_ip4, port + 1,
                           ["10.11.2.0/24", "10.11.3.0/24"]).add_vpp_config()
        self.assertEqual(len(self.vapi.wireguard_peers_dump()), 1)

        # send a valid handsake init for which we expect a response
        p = peer_1.mk_handshake(self.pg1)

        rx = self.send_and_expect(self.pg1, [p], self.pg1)

        peer_1.consume_response(rx[0])

        # send a data packet from the peer through the tunnel
        # this completes the handshake and pins the peer to worker 0
        p = (IP(src="10.11.3.1", dst=self.pg0.remote_ip4, ttl=20) /
             UDP(sport=222, dport=223) / Raw())
        d = peer_1.encrypt_transport(p)
        p = (peer_1.mk_tunnel_header(self.pg1) /
             (Wireguard(message_type=4, reserved_zero=0) /
              WireguardTransport(receiver_index=peer_1.sender,
                                 counter=0,
                                 encrypted_encapsulated_packet=d)))
        rxs = self.send_and_expect(self.pg1, [p], self.pg0, worker=0)

        for rx in rxs:
            self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
            self.assertEqual(rx[IP].ttl, 19)

        # send a packets that are routed into the tunnel
        # and pins the peer tp worker 1
        pe = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
              IP(src=self.pg0.remote_ip4, dst="10.11.3.2") /
              UDP(sport=555, dport=556) / Raw(b'\x00' * 80))
        rxs = self.send_and_expect(self.pg0, pe * 255, self.pg1, worker=1)
        peer_1.validate_encapped(rxs, pe)

        # send packets into the tunnel, from the other worker
        p = [(peer_1.mk_tunnel_header(self.pg1) /
              Wireguard(message_type=4, reserved_zero=0) / WireguardTransport(
                  receiver_index=peer_1.sender,
                  counter=ii + 1,
                  encrypted_encapsulated_packet=peer_1.encrypt_transport(
                      (IP(src="10.11.3.1", dst=self.pg0.remote_ip4, ttl=20) /
                       UDP(sport=222, dport=223) / Raw()))))
             for ii in range(255)]

        rxs = self.send_and_expect(self.pg1, p, self.pg0, worker=1)

        for rx in rxs:
            self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
            self.assertEqual(rx[IP].ttl, 19)

        # send a packets that are routed into the tunnel
        # from owrker 0
        rxs = self.send_and_expect(self.pg0, pe * 255, self.pg1, worker=0)

        peer_1.validate_encapped(rxs, pe)

        peer_1.remove_vpp_config()
        wg0.remove_vpp_config()
        for block in scanner:

            if firstBlock and isinstance(block, EnhancedPacket):
                firstBlock = False
                timestampOrigin = block.timestamp

            if isinstance(block, EnhancedPacket):
                packetId += 1

                if packetId < start_id:
                    continue

                if packetId > end_id:
                    break

                decoded = Ether(block.packet_data)
                _pl1 = decoded.payload
                _pl2 = _pl1.payload

                if isinstance(_pl1, IP) and isinstance(_pl2, TCP) and _pl1.src == src_ip and _pl1.dst == dst_ip:

                    # Skip this packet if it was sent before
                    currentSeq = _pl2.seq
                    if currentSeq in seqHistory:
                        if enabled_debug:
                            print("Skipped a redundant packet.")
                        continue
                    else:
                        seqHistory.append(currentSeq)

                    currentPacketTimestamp = block.timestamp - timestampOrigin
예제 #10
0
 def mk_tunnel_header(self, tx_itf):
     return (Ether(dst=tx_itf.local_mac, src=tx_itf.remote_mac) /
             IP(src=self.endpoint, dst=self.itf.src) /
             UDP(sport=self.port, dport=self.itf.port))
예제 #11
0
    def test_wg_peer_init(self):
        """ Send handshake init """
        wg_output_node_name = '/err/wg-output-tun/'
        wg_input_node_name = '/err/wg-input/'

        port = 12333

        # Create interfaces
        wg0 = VppWgInterface(self, self.pg1.local_ip4, port).add_vpp_config()
        wg0.admin_up()
        wg0.config_ip4()

        peer_1 = VppWgPeer(self, wg0, self.pg1.remote_ip4, port + 1,
                           ["10.11.2.0/24", "10.11.3.0/24"]).add_vpp_config()
        self.assertEqual(len(self.vapi.wireguard_peers_dump()), 1)

        # route a packet into the wg interface
        #  use the allowed-ip prefix
        #  this is dropped because the peer is not initiated
        p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
             IP(src=self.pg0.remote_ip4, dst="10.11.3.2") /
             UDP(sport=555, dport=556) / Raw())
        self.send_and_assert_no_replies(self.pg0, [p])

        kp_error = wg_output_node_name + "Keypair error"
        self.assertEqual(1, self.statistics.get_err_counter(kp_error))

        # send a handsake from the peer with an invalid MAC
        p = peer_1.mk_handshake(self.pg1)
        p[WireguardInitiation].mac1 = b'foobar'
        self.send_and_assert_no_replies(self.pg1, [p])
        self.assertEqual(
            1,
            self.statistics.get_err_counter(wg_input_node_name +
                                            "Invalid MAC handshake"))

        # send a handsake from the peer but signed by the wrong key.
        p = peer_1.mk_handshake(self.pg1,
                                X25519PrivateKey.generate().public_key())
        self.send_and_assert_no_replies(self.pg1, [p])
        self.assertEqual(
            1,
            self.statistics.get_err_counter(wg_input_node_name + "Peer error"))

        # send a valid handsake init for which we expect a response
        p = peer_1.mk_handshake(self.pg1)

        rx = self.send_and_expect(self.pg1, [p], self.pg1)

        peer_1.consume_response(rx[0])

        # route a packet into the wg interface
        #  this is dropped because the peer is still not initiated
        p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
             IP(src=self.pg0.remote_ip4, dst="10.11.3.2") /
             UDP(sport=555, dport=556) / Raw())
        self.send_and_assert_no_replies(self.pg0, [p])
        self.assertEqual(2, self.statistics.get_err_counter(kp_error))

        # send a data packet from the peer through the tunnel
        # this completes the handshake
        p = (IP(src="10.11.3.1", dst=self.pg0.remote_ip4, ttl=20) /
             UDP(sport=222, dport=223) / Raw())
        d = peer_1.encrypt_transport(p)
        p = (peer_1.mk_tunnel_header(self.pg1) /
             (Wireguard(message_type=4, reserved_zero=0) /
              WireguardTransport(receiver_index=peer_1.sender,
                                 counter=0,
                                 encrypted_encapsulated_packet=d)))
        rxs = self.send_and_expect(self.pg1, [p], self.pg0)

        for rx in rxs:
            self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
            self.assertEqual(rx[IP].ttl, 19)

        # send a packets that are routed into the tunnel
        p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
             IP(src=self.pg0.remote_ip4, dst="10.11.3.2") /
             UDP(sport=555, dport=556) / Raw(b'\x00' * 80))

        rxs = self.send_and_expect(self.pg0, p * 255, self.pg1)

        for rx in rxs:
            rx = IP(peer_1.decrypt_transport(rx))

            # chech the oringial packet is present
            self.assertEqual(rx[IP].dst, p[IP].dst)
            self.assertEqual(rx[IP].ttl, p[IP].ttl - 1)

        # send packets into the tunnel, expect to receive them on
        # the other side
        p = [(peer_1.mk_tunnel_header(self.pg1) /
              Wireguard(message_type=4, reserved_zero=0) / WireguardTransport(
                  receiver_index=peer_1.sender,
                  counter=ii + 1,
                  encrypted_encapsulated_packet=peer_1.encrypt_transport(
                      (IP(src="10.11.3.1", dst=self.pg0.remote_ip4, ttl=20) /
                       UDP(sport=222, dport=223) / Raw()))))
             for ii in range(255)]

        rxs = self.send_and_expect(self.pg1, p, self.pg0)

        for rx in rxs:
            self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
            self.assertEqual(rx[IP].ttl, 19)

        peer_1.remove_vpp_config()
        wg0.remove_vpp_config()
async def run_test(dut,
                   payload_lengths=None,
                   payload_data=None,
                   idle_inserter=None,
                   backpressure_inserter=None):

    tb = TB(dut)

    await tb.reset()

    tb.set_idle_generator(idle_inserter)
    tb.set_backpressure_generator(backpressure_inserter)

    test_pkts = []
    test_frames = []

    ip_id = 1

    for payload in [payload_data(x) for x in payload_lengths()]:
        eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5')
        ip = IP(src='192.168.1.100', dst='192.168.1.101', id=ip_id)
        udp = UDP(sport=1234, dport=4321)
        test_pkt = eth / ip / udp / payload

        ip_id = (ip_id + 1) & 0xffff

        # don't compute checksum
        test_pkts.append(test_pkt.copy())
        test_frame = AxiStreamFrame(test_pkt.build())
        test_frames.append(test_frame)

        await tb.source.send(test_frame)
        await tb.cmd_source.send(
            CsumCmdTransaction(csum_enable=0,
                               csum_start=34,
                               csum_offset=40,
                               csum_init=0))

        # inline partial checksum
        test_pkts.append(test_pkt.copy())

        pkt = test_pkt.copy()
        partial_csum = scapy.utils.checksum(bytes(pkt[UDP]))
        pkt[UDP].chksum = partial_csum

        test_frame = AxiStreamFrame(pkt.build())
        test_frames.append(test_frame)

        await tb.source.send(test_frame)
        await tb.cmd_source.send(
            CsumCmdTransaction(csum_enable=1,
                               csum_start=34,
                               csum_offset=40,
                               csum_init=0))

        # partial checksum in command
        test_pkts.append(test_pkt.copy())

        pkt = test_pkt.copy()
        partial_csum = scapy.utils.checksum(bytes(pkt[UDP]))
        pkt[UDP].chksum = 0

        test_frame = AxiStreamFrame(pkt.build())
        test_frames.append(test_frame)

        await tb.source.send(test_frame)
        await tb.cmd_source.send(
            CsumCmdTransaction(csum_enable=1,
                               csum_start=34,
                               csum_offset=40,
                               csum_init=partial_csum))

    for test_pkt, test_frame in zip(test_pkts, test_frames):
        rx_frame = await tb.sink.recv()

        rx_pkt = Ether(bytes(rx_frame))

        tb.log.info("RX packet: %s", repr(rx_pkt))

        check_pkt = Ether(test_pkt.build())

        tb.log.info("RX packet UDP checksum: 0x%04x (expected 0x%04x)",
                    rx_pkt[UDP].chksum, check_pkt[UDP].chksum)

        assert check_pkt == rx_pkt

    assert tb.sink.empty()

    await RisingEdge(dut.clk)
    await RisingEdge(dut.clk)
async def run_test_offsets(dut,
                           payload_lengths=None,
                           payload_data=None,
                           idle_inserter=None,
                           backpressure_inserter=None):

    tb = TB(dut)

    await tb.reset()

    tb.set_idle_generator(idle_inserter)
    tb.set_backpressure_generator(backpressure_inserter)

    test_pkts = []
    test_frames = []
    check_frames = []

    ip_id = 1

    for payload in [payload_data(x) for x in payload_lengths()]:
        eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5')
        test_pkt = eth / payload

        ip_id = (ip_id + 1) & 0xffff

        for start in range(0, min(len(payload) + 14, 32)):
            offset = 0
            test_pkts.append(test_pkt.copy())
            test_frame = AxiStreamFrame(test_pkt.build())
            test_frames.append(test_frame)

            await tb.source.send(test_frame)
            await tb.cmd_source.send(
                CsumCmdTransaction(csum_enable=1,
                                   csum_start=start,
                                   csum_offset=offset,
                                   csum_init=0))

            csum = scapy.utils.checksum(bytes(test_pkt)[start:])

            check_frame = bytearray(test_frame.tdata)
            struct.pack_into('>H', check_frame, offset, csum)

            check_frames.append(check_frame)

        for offset in range(0, min(len(payload) + 14, 32) - 1):
            start = 0
            test_pkts.append(test_pkt.copy())
            test_frame = AxiStreamFrame(test_pkt.build())
            test_frames.append(test_frame)

            await tb.source.send(test_frame)
            await tb.cmd_source.send(
                CsumCmdTransaction(csum_enable=1,
                                   csum_start=start,
                                   csum_offset=offset,
                                   csum_init=0))

            csum = scapy.utils.checksum(bytes(test_pkt)[start:])

            check_frame = bytearray(test_frame.tdata)
            struct.pack_into('>H', check_frame, offset, csum)

            check_frames.append(check_frame)

    for test_pkt, test_frame, check_frame in zip(test_pkts, test_frames,
                                                 check_frames):
        rx_frame = await tb.sink.recv()

        rx_pkt = Ether(bytes(rx_frame))

        tb.log.info("RX packet: %s", repr(rx_pkt))

        assert rx_frame.tdata == check_frame

    assert tb.sink.empty()

    await RisingEdge(dut.clk)
    await RisingEdge(dut.clk)
예제 #14
0
def get_mac(target):
    arp_broadcast = Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(op=ARP.who_has, pdst=target)
    answered = srp(arp_broadcast, timeout=2, verbose=False)[0]
    # Return the MAC address of the target machine that responded to our ARP broadcast
    return answered[0][1].hwsrc
예제 #15
0
async def run_test_nic(dut):

    tb = TB(dut)

    await tb.init()

    tb.log.info("Init driver")
    await tb.driver.init_dev(tb.dev.functions[0].pcie_id)
    await tb.driver.interfaces[0].open()
    # await driver.interfaces[1].open()

    # enable queues
    tb.log.info("Enable queues")
    await tb.rc.mem_write_dword(
        tb.driver.interfaces[0].ports[0].hw_addr +
        mqnic.MQNIC_PORT_REG_SCHED_ENABLE, 0x00000001)
    for k in range(tb.driver.interfaces[0].tx_queue_count):
        await tb.rc.mem_write_dword(
            tb.driver.interfaces[0].ports[0].schedulers[0].hw_addr + 4 * k,
            0x00000003)

    # wait for all writes to complete
    await tb.rc.mem_read(tb.driver.hw_addr, 4)
    tb.log.info("Init complete")

    tb.log.info("Send and receive single packet")

    data = bytearray([x % 256 for x in range(1024)])

    await tb.driver.interfaces[0].start_xmit(data, 0)

    pkt = await tb.sfp_1_sink.recv()
    tb.log.info("Packet: %s", pkt)

    await tb.sfp_1_source.send(pkt)

    pkt = await tb.driver.interfaces[0].recv()

    tb.log.info("Packet: %s", pkt)
    assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(
        pkt.data[14:])) & 0xffff

    # await tb.driver.interfaces[1].start_xmit(data, 0)

    # pkt = await tb.sfp_2_sink.recv()
    # tb.log.info("Packet: %s", pkt)

    # await tb.sfp_2_source.send(pkt)

    # pkt = await tb.driver.interfaces[1].recv()

    # tb.log.info("Packet: %s", pkt)
    # assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(pkt.data[14:])) & 0xffff

    tb.log.info("RX and TX checksum tests")

    payload = bytes([x % 256 for x in range(256)])
    eth = Ether(src='5A:51:52:53:54:55', dst='DA:D1:D2:D3:D4:D5')
    ip = IP(src='192.168.1.100', dst='192.168.1.101')
    udp = UDP(sport=1, dport=2)
    test_pkt = eth / ip / udp / payload

    test_pkt2 = test_pkt.copy()
    test_pkt2[UDP].chksum = scapy.utils.checksum(bytes(test_pkt2[UDP]))

    await tb.driver.interfaces[0].start_xmit(test_pkt2.build(), 0, 34, 6)

    pkt = await tb.sfp_1_sink.recv()
    tb.log.info("Packet: %s", pkt)

    await tb.sfp_1_source.send(pkt)

    pkt = await tb.driver.interfaces[0].recv()

    tb.log.info("Packet: %s", pkt)
    assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(
        pkt.data[14:])) & 0xffff
    assert Ether(pkt.data).build() == test_pkt.build()

    tb.log.info("Multiple small packets")

    count = 64

    pkts = [
        bytearray([(x + k) % 256 for x in range(60)]) for k in range(count)
    ]

    tb.loopback_enable = True

    for p in pkts:
        await tb.driver.interfaces[0].start_xmit(p, 0)

    for k in range(count):
        pkt = await tb.driver.interfaces[0].recv()

        tb.log.info("Packet: %s", pkt)
        assert pkt.data == pkts[k]
        assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(
            pkt.data[14:])) & 0xffff

    tb.loopback_enable = False

    tb.log.info("Multiple large packets")

    count = 64

    pkts = [
        bytearray([(x + k) % 256 for x in range(1514)]) for k in range(count)
    ]

    tb.loopback_enable = True

    for p in pkts:
        await tb.driver.interfaces[0].start_xmit(p, 0)

    for k in range(count):
        pkt = await tb.driver.interfaces[0].recv()

        tb.log.info("Packet: %s", pkt)
        assert pkt.data == pkts[k]
        assert pkt.rx_checksum == ~scapy.utils.checksum(bytes(
            pkt.data[14:])) & 0xffff

    tb.loopback_enable = False

    await RisingEdge(dut.clk_250mhz)
    await RisingEdge(dut.clk_250mhz)
예제 #16
0
 def gen_pkts6(self, p, sw_intf, src, dst, count=1, payload_size=54):
     return [Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) /
             IPv6(src=src, dst=dst) /
             UDP(sport=4444, dport=4444) /
             Raw(b'X' * payload_size)
             for i in range(count)]
예제 #17
0
    def test_pipe(self):
        """ Pipes """

        pipes = [VppPipe(self), VppPipe(self, 10)]

        for p in pipes:
            p.add_vpp_config()
            p.admin_up()

        #
        # L2 cross-connect pipe0 east with pg0 and west with pg1
        #
        self.vapi.sw_interface_set_l2_xconnect(self.pg0.sw_if_index,
                                               pipes[0].east,
                                               enable=1)
        self.vapi.sw_interface_set_l2_xconnect(pipes[0].east,
                                               self.pg0.sw_if_index,
                                               enable=1)
        self.vapi.sw_interface_set_l2_xconnect(self.pg1.sw_if_index,
                                               pipes[0].west,
                                               enable=1)
        self.vapi.sw_interface_set_l2_xconnect(pipes[0].west,
                                               self.pg1.sw_if_index,
                                               enable=1)

        # test bi-directional L2 flow pg0<->pg1
        p = (Ether(src=self.pg0.remote_mac, dst=self.pg1.remote_mac) /
             IP(src="1.1.1.1", dst="1.1.1.2") / UDP(sport=1234, dport=1234) /
             Raw(b'\xa5' * 100))

        self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg1)
        self.send_and_expect(self.pg1, p * NUM_PKTS, self.pg0)

        #
        # Attach ACL to ensure features are run on the pipe
        #
        rule_1 = ({
            'is_permit': 0,
            'is_ipv6': 0,
            'proto': 17,
            'srcport_or_icmptype_first': 1234,
            'srcport_or_icmptype_last': 1234,
            'src_ip_prefix_len': 32,
            'src_ip_addr': inet_pton(AF_INET, "1.1.1.1"),
            'dstport_or_icmpcode_first': 1234,
            'dstport_or_icmpcode_last': 1234,
            'dst_ip_prefix_len': 32,
            'dst_ip_addr': inet_pton(AF_INET, "1.1.1.2")
        })
        acl = self.vapi.acl_add_replace(acl_index=4294967295, r=[rule_1])

        # Apply the ACL on the pipe on output
        self.vapi.acl_interface_set_acl_list(pipes[0].east, 0, [acl.acl_index])
        self.send_and_assert_no_replies(self.pg0, p * NUM_PKTS)
        self.send_and_expect(self.pg1, p * NUM_PKTS, self.pg0)

        # remove from output and apply on input
        self.vapi.acl_interface_set_acl_list(pipes[0].east, 0, [])
        self.vapi.acl_interface_set_acl_list(pipes[0].west, 1, [acl.acl_index])
        self.send_and_assert_no_replies(self.pg0, p * NUM_PKTS)
        self.send_and_expect(self.pg1, p * NUM_PKTS, self.pg0)
        self.vapi.acl_interface_set_acl_list(pipes[0].west, 0, [])
        self.send_and_expect(self.pg0, p * NUM_PKTS, self.pg1)
        self.send_and_expect(self.pg1, p * NUM_PKTS, self.pg0)

        #
        # L3 routes in two separate tables so a pipe can be used to L3
        # x-connect
        #
        tables = []
        tables.append(VppIpTable(self, 1))
        tables.append(VppIpTable(self, 2))

        for t in tables:
            t.add_vpp_config()

        self.pg2.set_table_ip4(1)
        self.pg2.config_ip4()
        self.pg2.resolve_arp()
        self.pg3.set_table_ip4(2)
        self.pg3.config_ip4()
        self.pg3.resolve_arp()

        routes = []
        routes.append(
            VppIpRoute(
                self,
                "1.1.1.1",
                32, [VppRoutePath(self.pg3.remote_ip4, self.pg3.sw_if_index)],
                table_id=2))
        routes.append(
            VppIpRoute(self,
                       "1.1.1.1",
                       32, [VppRoutePath("0.0.0.0", pipes[1].east)],
                       table_id=1))
        routes.append(
            VppIpRoute(self,
                       "1.1.1.2",
                       32, [VppRoutePath("0.0.0.0", pipes[1].west)],
                       table_id=2))
        routes.append(
            VppIpRoute(
                self,
                "1.1.1.2",
                32, [VppRoutePath(self.pg2.remote_ip4, self.pg2.sw_if_index)],
                table_id=1))

        for r in routes:
            r.add_vpp_config()

        p_east = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) /
                  IP(src="1.1.1.2", dst="1.1.1.1") /
                  UDP(sport=1234, dport=1234) / Raw(b'\xa5' * 100))

        # bind the pipe ends to the correct tables
        self.vapi.sw_interface_set_table(pipes[1].west, 0, 2)
        self.vapi.sw_interface_set_table(pipes[1].east, 0, 1)

        # IP is not enabled on the pipes at this point
        self.send_and_assert_no_replies(self.pg2, p_east * NUM_PKTS)

        # IP enable the Pipes by making them unnumbered
        pipes[0].set_unnumbered(self.pg2.sw_if_index)
        pipes[1].set_unnumbered(self.pg3.sw_if_index)

        self.send_and_expect(self.pg2, p_east * NUM_PKTS, self.pg3)

        # and the return path
        p_west = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) /
                  IP(src="1.1.1.1", dst="1.1.1.2") /
                  UDP(sport=1234, dport=1234) / Raw(b'\xa5' * 100))
        self.send_and_expect(self.pg3, p_west * NUM_PKTS, self.pg2)

        #
        # Use ACLs to test features run on the Pipes
        #
        self.vapi.acl_interface_set_acl_list(pipes[1].east, 0, [acl.acl_index])
        self.send_and_assert_no_replies(self.pg2, p_east * NUM_PKTS)
        self.send_and_expect(self.pg3, p_west * NUM_PKTS, self.pg2)

        # remove from output and apply on input
        self.vapi.acl_interface_set_acl_list(pipes[1].east, 0, [])
        self.vapi.acl_interface_set_acl_list(pipes[1].west, 1, [acl.acl_index])
        self.send_and_assert_no_replies(self.pg2, p_east * NUM_PKTS)
        self.send_and_expect(self.pg3, p_west * NUM_PKTS, self.pg2)
        self.vapi.acl_interface_set_acl_list(pipes[1].west, 0, [])
        self.send_and_expect(self.pg2, p_east * NUM_PKTS, self.pg3)
        self.send_and_expect(self.pg3, p_west * NUM_PKTS, self.pg2)

        # cleanup (so the tables delete)
        self.pg2.unconfig_ip4()
        self.pg2.set_table_ip4(0)
        self.pg3.unconfig_ip4()
        self.pg3.set_table_ip4(0)
        self.vapi.sw_interface_set_table(pipes[1].west, 0, 0)
        self.vapi.sw_interface_set_table(pipes[1].east, 0, 0)
예제 #18
0
    def test_bier_load_balance(self):
        """BIER load-balance"""

        #
        # Add a BIER table for sub-domain 0, set 0, and BSL 256
        #
        bti = VppBierTableID(0, 0, BIERLength.BIER_LEN_64)
        bt = VppBierTable(self, bti, 77)
        bt.add_vpp_config()

        #
        # packets with varying entropy
        #
        pkts = []
        for ii in range(257):
            pkts.append(
                (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
                 MPLS(label=77, ttl=255) /
                 BIER(length=BIERLength.BIER_LEN_64,
                      entropy=ii,
                      BitString=scapy.compat.chb(255) * 16) /
                 IPv6(src=self.pg0.remote_ip6, dst=self.pg0.remote_ip6) /
                 UDP(sport=1234, dport=1234) / Raw()))

        #
        # 4 next hops
        #
        nhs = [{
            'ip': "10.0.0.1",
            'label': 201
        }, {
            'ip': "10.0.0.2",
            'label': 202
        }, {
            'ip': "10.0.0.3",
            'label': 203
        }, {
            'ip': "10.0.0.4",
            'label': 204
        }]

        for nh in nhs:
            ipr = VppIpRoute(self, nh['ip'], 32, [
                VppRoutePath(self.pg1.remote_ip4,
                             self.pg1.sw_if_index,
                             labels=[VppMplsLabel(nh['label'])])
            ])
            ipr.add_vpp_config()

        bier_route = VppBierRoute(self, bti, 1, [
            VppRoutePath(nhs[0]['ip'], 0xffffffff, labels=[VppMplsLabel(101)]),
            VppRoutePath(nhs[1]['ip'], 0xffffffff, labels=[VppMplsLabel(101)])
        ])
        bier_route.add_vpp_config()

        rx = self.send_and_expect(self.pg0, pkts, self.pg1)

        #
        # we should have recieved a packet from each neighbor
        #
        for nh in nhs[:2]:
            self.assertTrue(sum(p[MPLS].label == nh['label'] for p in rx))

        #
        # add the other paths
        #
        bier_route.update_paths([
            VppRoutePath(nhs[0]['ip'], 0xffffffff, labels=[VppMplsLabel(101)]),
            VppRoutePath(nhs[1]['ip'], 0xffffffff, labels=[VppMplsLabel(101)]),
            VppRoutePath(nhs[2]['ip'], 0xffffffff, labels=[VppMplsLabel(101)]),
            VppRoutePath(nhs[3]['ip'], 0xffffffff, labels=[VppMplsLabel(101)])
        ])

        rx = self.send_and_expect(self.pg0, pkts, self.pg1)
        for nh in nhs:
            self.assertTrue(sum(p[MPLS].label == nh['label'] for p in rx))

        #
        # remove first two paths
        #
        bier_route.remove_path(
            VppRoutePath(nhs[0]['ip'], 0xffffffff, labels=[VppMplsLabel(101)]))
        bier_route.remove_path(
            VppRoutePath(nhs[1]['ip'], 0xffffffff, labels=[VppMplsLabel(101)]))

        rx = self.send_and_expect(self.pg0, pkts, self.pg1)
        for nh in nhs[2:]:
            self.assertTrue(sum(p[MPLS].label == nh['label'] for p in rx))

        #
        # remove the last of the paths, deleteing the entry
        #
        bier_route.remove_all_paths()

        self.send_and_assert_no_replies(self.pg0, pkts)
예제 #19
0
파일: test_bier.py 프로젝트: pankaj364/vpp
    def test_bier_tail(self):
        """BIER Tail"""

        #
        # Add a BIER table for sub-domain 0, set 0, and BSL 256
        #
        bti = VppBierTableID(0, 0, BIERLength.BIER_LEN_256)
        bt = VppBierTable(self, bti, 77)
        bt.add_vpp_config()

        #
        # disposition table
        #
        bdt = VppBierDispTable(self, 8)
        bdt.add_vpp_config()

        #
        # BIER route in table that's for-us
        #
        bier_route_1 = VppBierRoute(
            self, bti, 1, [VppRoutePath("0.0.0.0", 0xffffffff, nh_table_id=8)])
        bier_route_1.add_vpp_config()

        #
        # An entry in the disposition table
        #
        bier_de_1 = VppBierDispEntry(self,
                                     bdt.id,
                                     99,
                                     BIER_HDR_PAYLOAD.BIER_HDR_PROTO_IPV4,
                                     DpoProto.DPO_PROTO_BIER,
                                     "0.0.0.0",
                                     0,
                                     rpf_id=8192)
        bier_de_1.add_vpp_config()

        #
        # A multicast route to forward post BIER disposition
        #
        route_eg_232_1_1_1 = VppIpMRoute(
            self,
            "0.0.0.0",
            "232.1.1.1",
            32,
            MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
            paths=[
                VppMRoutePath(self.pg1.sw_if_index,
                              MRouteItfFlags.MFIB_ITF_FLAG_FORWARD)
            ])
        route_eg_232_1_1_1.add_vpp_config()
        route_eg_232_1_1_1.update_rpf_id(8192)

        #
        # A packet with all bits set gets spat out to BP:1
        #
        p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
             MPLS(label=77, ttl=255) / BIER(length=BIERLength.BIER_LEN_256,
                                            BitString=chr(255) * 32,
                                            BFRID=99) /
             IP(src="1.1.1.1", dst="232.1.1.1") / UDP(sport=1234, dport=1234) /
             Raw())

        self.send_and_expect(self.pg0, [p], self.pg1)

        #
        # A packet that does not match the Disposition entry gets dropped
        #
        p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
             MPLS(label=77, ttl=255) / BIER(length=BIERLength.BIER_LEN_256,
                                            BitString=chr(255) * 32,
                                            BFRID=77) /
             IP(src="1.1.1.1", dst="232.1.1.1") / UDP(sport=1234, dport=1234) /
             Raw())
        self.send_and_assert_no_replies(self.pg0, p * 2,
                                        "no matching disposition entry")

        #
        # Add the default route to the disposition table
        #
        bier_de_2 = VppBierDispEntry(self,
                                     bdt.id,
                                     0,
                                     BIER_HDR_PAYLOAD.BIER_HDR_PROTO_IPV4,
                                     DpoProto.DPO_PROTO_BIER,
                                     "0.0.0.0",
                                     0,
                                     rpf_id=8192)
        bier_de_2.add_vpp_config()

        #
        # now the previous packet is forwarded
        #
        self.send_and_expect(self.pg0, [p], self.pg1)
예제 #20
0
def eth_head(eth_type):
    EthHead = Ether(type=eth_type)
    return EthHead
    pass
예제 #21
0
파일: test_bier.py 프로젝트: pankaj364/vpp
    def test_bier_head_o_udp(self):
        """BIER head over UDP"""

        #
        # Add a BIER table for sub-domain 1, set 0, and BSL 256
        #
        bti = VppBierTableID(1, 0, BIERLength.BIER_LEN_256)
        bt = VppBierTable(self, bti, 77)
        bt.add_vpp_config()

        #
        # 1 bit positions via 1 next hops
        #
        nh1 = "10.0.0.1"
        ip_route = VppIpRoute(self, nh1, 32, [
            VppRoutePath(
                self.pg1.remote_ip4, self.pg1.sw_if_index, labels=[2001])
        ])
        ip_route.add_vpp_config()

        udp_encap = VppUdpEncap(self, 4, self.pg0.local_ip4, nh1, 330, 8138)
        udp_encap.add_vpp_config()

        bier_route = VppBierRoute(self, bti, 1, [
            VppRoutePath("0.0.0.0", 0xFFFFFFFF, is_udp_encap=1, next_hop_id=4)
        ])
        bier_route.add_vpp_config()

        #
        # An 2 imposition objects with all bit-positions set
        # only use the second, but creating 2 tests with a non-zero
        # value index in the route add
        #
        bi = VppBierImp(self, bti, 333, chr(0xff) * 32)
        bi.add_vpp_config()
        bi2 = VppBierImp(self, bti, 334, chr(0xff) * 32)
        bi2.add_vpp_config()

        #
        # Add a multicast route that will forward into the BIER doamin
        #
        route_ing_232_1_1_1 = VppIpMRoute(
            self,
            "0.0.0.0",
            "232.1.1.1",
            32,
            MRouteEntryFlags.MFIB_ENTRY_FLAG_NONE,
            paths=[
                VppMRoutePath(self.pg0.sw_if_index,
                              MRouteItfFlags.MFIB_ITF_FLAG_ACCEPT),
                VppMRoutePath(0xffffffff,
                              MRouteItfFlags.MFIB_ITF_FLAG_FORWARD,
                              proto=DpoProto.DPO_PROTO_BIER,
                              bier_imp=bi2.bi_index)
            ])
        route_ing_232_1_1_1.add_vpp_config()

        #
        # inject a packet an IP. We expect it to be BIER and UDP encapped,
        #
        p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
             IP(src="1.1.1.1", dst="232.1.1.1") / UDP(sport=1234, dport=1234))

        self.pg0.add_stream([p])
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

        rx = self.pg1.get_capture(1)

        #
        # Encap Stack is, eth, IP, UDP, BIFT, BIER
        #
        self.assertEqual(rx[0][IP].src, self.pg0.local_ip4)
        self.assertEqual(rx[0][IP].dst, nh1)
        self.assertEqual(rx[0][UDP].sport, 330)
        self.assertEqual(rx[0][UDP].dport, 8138)
        self.assertEqual(rx[0][BIFT].bsl, 2)
        self.assertEqual(rx[0][BIFT].sd, 1)
        self.assertEqual(rx[0][BIFT].set, 0)
        self.assertEqual(rx[0][BIFT].ttl, 64)
        self.assertEqual(rx[0][BIER].length, 2)
예제 #22
0
def verify():
    """

    Retrieves rows pertaining to the given keys from the Table instance
    represented by big_table.  Silly things may happen if
    other_silly_variable is not None.

    Args: None
    Returns:
        if first lacpdu switch pass, receive lacpdu.actor.syn=true
            print pass1
            if the second lacpdu switch pass,receive lacp.actor.state=0x3d
                print PASS2
                return 2
        else not a successful switch process
            return 3 
    Raises:
        Scapy_Exception: An error occurred accessing scapy.
    """
    a=Ether(dst='01:80:c2:00:00:02', src='00:1B:21:6A:C2:6F', type=0x8809)/LACP(\
        Actor_system='00:1B:21:6A:C2:6F', \
        Actor_key=1, \
        Actor_port_priority=1, \
        Actor_port=1, \
        Actor_state=0x45, \
        Partner_system='00:00:00:00:00:00', \
        Partner_state=0x02, CollectorMaxDelay=5000)
    sendp(a, iface='xgbe0', count=1)
    #send a LACPDU with actor information and without partner information,then recv a LACPDU reply show switch syn
    ans, unans = srp(a, iface='xgbe0', timeout=60)
    for s, r in ans:
        if r.haslayer(LACP):
            r.show()
            partner_system_priority = r.sprintf('%LACP.Actor_system_priority%')
            partner_system = r.sprintf('%LACP.Actor_system%')
            partner_key = r.sprintf('%LACP.Actor_key%')
            partner_port_priority = r.sprintf('%LACP.Actor_port_priority%')
            partner_port = r.sprintf('%LACP.Actor_port%')
            partner_state_lacpdu = r.sprintf('%LACP.Actor_state%')
            if partner_state_lacpdu == 'LACP_Activity+Aggregation+Synchronization':
                print "PASS1"
                b=Ether(dst='01:80:c2:00:00:02', src='00:1B:21:6A:C2:6F', type=0x8809)/LACP(\
                        Actor_system='00:1B:21:6A:C2:6F', \
                        Actor_key=1, \
                        Actor_port_priority=1, \
                        Actor_port=1, Actor_state=0x0d, \
                        Partner_system=partner_system, \
                        Partner_system_priority=int(partner_system_priority), \
                        Partner_key=int(partner_key), \
                        Partner_port_priority=int(partner_port_priority), \
                        Partner_port=int(partner_port), \
                        Partner_state=0x0d, CollectorMaxDelay=5000)
                ans1, unans1 = srp(b, iface='xgbe0')
                for s1, r1 in ans1:
                    if r1.haslayer(LACP):
                        r1.show()
                        partner_state1_lacpdu = r1.sprintf(
                            '%LACP.Actor_state%')
                        print type(partner_state1_lacpdu)
                        if partner_state1_lacpdu == 'LACP_Activity\
        +Aggregation+Synchronization+Collecting+Distributing':
                            print "PASS2"
                            exit(2)
                        else:
                            print "switch is not lacpactive"
                            exit(3)
                    else:
                        print "recv is not LACPDU"
                        exit(3)
            else:
                print "switch is not Synchronization"
                exit(3)

        else:
            exit(3)
예제 #23
0
파일: test_bier.py 프로젝트: pankaj364/vpp
    def bier_midpoint(self, hdr_len_id, n_bytes, max_bp):
        """BIER midpoint"""

        #
        # Add a BIER table for sub-domain 0, set 0, and BSL 256
        #
        bti = VppBierTableID(0, 0, hdr_len_id)
        bt = VppBierTable(self, bti, 77)
        bt.add_vpp_config()

        #
        # A packet with no bits set gets dropped
        #
        p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
             MPLS(label=77, ttl=255) / BIER(length=hdr_len_id) /
             IPv6(src=self.pg0.remote_ip6, dst=self.pg0.remote_ip6) /
             UDP(sport=1234, dport=1234) / Raw())
        pkts = [p]

        self.send_and_assert_no_replies(self.pg0, pkts, "Empty Bit-String")

        #
        # Add a BIER route for each bit-position in the table via a different
        # next-hop. Testing whether the BIER walk and replicate forwarding
        # function works for all bit posisitons.
        #
        nh_routes = []
        bier_routes = []
        for i in range(1, max_bp + 1):
            nh = "10.0.%d.%d" % (i / 255, i % 255)
            nh_routes.append(
                VppIpRoute(self, nh, 32, [
                    VppRoutePath(self.pg1.remote_ip4,
                                 self.pg1.sw_if_index,
                                 labels=[2000 + i])
                ]))
            nh_routes[-1].add_vpp_config()

            bier_routes.append(
                VppBierRoute(self, bti, i,
                             [VppRoutePath(nh, 0xffffffff, labels=[100 + i])]))
            bier_routes[-1].add_vpp_config()

        #
        # A packet with all bits set gets replicated once for each bit
        #
        pkt_sizes = [64, 1400]

        for pkt_size in pkt_sizes:
            p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
                 MPLS(label=77, ttl=255) /
                 BIER(length=hdr_len_id, BitString=chr(255) * n_bytes) /
                 IPv6(src=self.pg0.remote_ip6, dst=self.pg0.remote_ip6) /
                 UDP(sport=1234, dport=1234) / Raw(chr(5) * pkt_size))
            pkts = p

            self.pg0.add_stream(pkts)
            self.pg_enable_capture(self.pg_interfaces)
            self.pg_start()

            rx = self.pg1.get_capture(max_bp)

            for rxp in rx:
                #
                # The packets are not required to be sent in bit-position order
                # when we setup the routes above we used the bit-position to
                # construct the out-label. so use that here to determine the BP
                #
                olabel = rxp[MPLS]
                bp = olabel.label - 2000

                blabel = olabel[MPLS].payload
                self.assertEqual(blabel.label, 100 + bp)
                self.assertEqual(blabel.ttl, 254)

                bier_hdr = blabel[MPLS].payload

                self.assertEqual(bier_hdr.id, 5)
                self.assertEqual(bier_hdr.version, 0)
                self.assertEqual(bier_hdr.length, hdr_len_id)
                self.assertEqual(bier_hdr.entropy, 0)
                self.assertEqual(bier_hdr.OAM, 0)
                self.assertEqual(bier_hdr.RSV, 0)
                self.assertEqual(bier_hdr.DSCP, 0)
                self.assertEqual(bier_hdr.Proto, 5)

                # The bit-string should consist only of the BP given by i.
                byte_array = ['\0'] * (n_bytes)
                byte_val = chr(1 << (bp - 1) % 8)
                byte_pos = n_bytes - (((bp - 1) / 8) + 1)
                byte_array[byte_pos] = byte_val
                bitstring = ''.join(byte_array)

                self.assertEqual(len(bitstring), len(bier_hdr.BitString))
                self.assertEqual(bitstring, bier_hdr.BitString)

        #
        # cleanup. not strictly necessary, but it's much quicker this way
        # becuase the bier_fib_dump and ip_fib_dump will be empty when the
        # auto-cleanup kicks in
        #
        for br in bier_routes:
            br.remove_vpp_config()
        for nhr in nh_routes:
            nhr.remove_vpp_config()
예제 #24
0
 def gen_pkts(self, sw_intf, src, dst, count=1):
     return [Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) /
             IP(src=src, dst=dst) / ICMP() / self.payload
             for i in range(count)]
예제 #25
0
def main():
    """Send ICMP echo request and wait for ICMP echo reply. It ignores all other
    packets."""
    args = TrafficScriptArg(
        [u"dst_mac", u"src_mac", u"dst_ip", u"src_ip", u"timeout"])

    dst_mac = args.get_arg(u"dst_mac")
    src_mac = args.get_arg(u"src_mac")
    dst_ip = args.get_arg(u"dst_ip")
    src_ip = args.get_arg(u"src_ip")
    tx_if = args.get_arg(u"tx_if")
    rx_if = args.get_arg(u"rx_if")
    timeout = int(args.get_arg(u"timeout"))
    wait_step = 1

    rxq = RxQueue(rx_if)
    txq = TxQueue(tx_if)
    sent_packets = []

    # Create empty ip ICMP packet
    if valid_ipv4(src_ip) and valid_ipv4(dst_ip):
        ip_layer = IP
        icmp_req = ICMP
        icmp_resp = ICMP
        icmp_type = 0  # echo-reply
    elif valid_ipv6(src_ip) and valid_ipv6(dst_ip):
        ip_layer = IP
        icmp_req = ICMPv6EchoRequest
        icmp_resp = ICMPv6EchoReply
        icmp_type = 0  # Echo Reply
    else:
        raise ValueError(u"IP not in correct format")

    icmp_request = (Ether(src=src_mac, dst=dst_mac) /
                    ip_layer(src=src_ip, dst=dst_ip) / icmp_req())

    # Send created packet on the interface
    icmp_request /= Raw()
    sent_packets.append(icmp_request)
    txq.send(icmp_request)

    for _ in range(1000):
        while True:
            icmp_reply = rxq.recv(wait_step, ignore=sent_packets)
            if icmp_reply is None:
                timeout -= wait_step
                if timeout < 0:
                    raise RuntimeError(u"ICMP echo Rx timeout")

            elif icmp_reply.haslayer(ICMPv6ND_NS):
                # read another packet in the queue in case of ICMPv6ND_NS packet
                continue
            else:
                # otherwise process the current packet
                break

        if icmp_reply[ip_layer][icmp_resp].type == icmp_type:
            if icmp_reply[ip_layer].src == dst_ip and \
                    icmp_reply[ip_layer].dst == src_ip:
                break
    else:
        raise RuntimeError(u"Max packet count limit reached")

    print(u"ICMP echo reply received.")

    sys.exit(0)
예제 #26
0
 def gen_pkts6(self, sw_intf, src, dst, count=1):
     return [Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) /
             IPv6(src=src, dst=dst) /
             ICMPv6EchoRequest(id=0, seq=1, data=self.payload)
             for i in range(count)]
예제 #27
0
    def test_fif4(self):
        """ Fragments in fragments (4o4) """

        # TODO this should be ideally in setUpClass, but then we hit a bug
        # with VppIpRoute incorrectly reporting it's present when it's not
        # so we need to manually remove the vpp config, thus we cannot have
        # it shared for multiple test cases
        self.tun_ip4 = "1.1.1.2"

        self.gre4 = VppGreInterface(self, self.src_if.local_ip4, self.tun_ip4)
        self.gre4.add_vpp_config()
        self.gre4.admin_up()
        self.gre4.config_ip4()

        self.vapi.ip_reassembly_enable_disable(
            sw_if_index=self.gre4.sw_if_index, enable_ip4=True)

        self.route4 = VppIpRoute(
            self, self.tun_ip4, 32,
            [VppRoutePath(self.src_if.remote_ip4, self.src_if.sw_if_index)])
        self.route4.add_vpp_config()

        self.reset_packet_infos()
        for i in range(test_packet_count):
            info = self.create_packet_info(self.src_if, self.dst_if)
            payload = self.info_to_payload(info)
            # Ethernet header here is only for size calculation, thus it
            # doesn't matter how it's initialized. This is to ensure that
            # reassembled packet is not > 9000 bytes, so that it's not dropped
            p = (Ether() / IP(
                id=i, src=self.src_if.remote_ip4, dst=self.dst_if.remote_ip4) /
                 UDP(sport=1234, dport=5678) / Raw(payload))
            size = self.packet_sizes[(i // 2) % len(self.packet_sizes)]
            self.extend_packet(p, size, self.padding)
            info.data = p[IP]  # use only IP part, without ethernet header

        fragments = [
            x for _, p in six.iteritems(self._packet_infos)
            for x in fragment_rfc791(p.data, 400)
        ]

        encapped_fragments = \
            [Ether(dst=self.src_if.local_mac, src=self.src_if.remote_mac) /
             IP(src=self.tun_ip4, dst=self.src_if.local_ip4) /
                GRE() /
                p
                for p in fragments]

        fragmented_encapped_fragments = \
            [x for p in encapped_fragments
             for x in fragment_rfc791(p, 200)]

        self.src_if.add_stream(fragmented_encapped_fragments)

        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

        self.src_if.assert_nothing_captured()
        packets = self.dst_if.get_capture(len(self._packet_infos))
        self.verify_capture(packets, IP)

        # TODO remove gre vpp config by hand until VppIpRoute gets fixed
        # so that it's query_vpp_config() works as it should
        self.gre4.remove_vpp_config()
        self.logger.debug(self.vapi.ppcli("show interface"))
예제 #28
0
    def test_tra_anti_replay(self, count=1):
        """ ipsec v4 transport anti-reply test """
        p = self.params[socket.AF_INET]

        # fire in a packet with seq number 1
        pkt = (Ether(src=self.tra_if.remote_mac,
                     dst=self.tra_if.local_mac) /
               p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
                                         dst=self.tra_if.local_ip4) /
                                      ICMP(),
                                      seq_num=1))
        recv_pkts = self.send_and_expect(self.tra_if, [pkt], self.tra_if)

        # now move the window over to 235
        pkt = (Ether(src=self.tra_if.remote_mac,
                     dst=self.tra_if.local_mac) /
               p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
                                         dst=self.tra_if.local_ip4) /
                                      ICMP(),
                                      seq_num=235))
        recv_pkts = self.send_and_expect(self.tra_if, [pkt], self.tra_if)

        # the window size is 64 packets
        # in window are still accepted
        pkt = (Ether(src=self.tra_if.remote_mac,
                     dst=self.tra_if.local_mac) /
               p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
                                         dst=self.tra_if.local_ip4) /
                                      ICMP(),
                                      seq_num=172))
        recv_pkts = self.send_and_expect(self.tra_if, [pkt], self.tra_if)

        # out of window are dropped
        pkt = (Ether(src=self.tra_if.remote_mac,
                     dst=self.tra_if.local_mac) /
               p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
                                         dst=self.tra_if.local_ip4) /
                                      ICMP(),
                                      seq_num=17))
        self.send_and_assert_no_replies(self.tra_if, pkt * 17)

        self.assert_packet_counter_equal(
            '/err/%s/SA replayed packet' % self.tra4_decrypt_node_name, 17)

        # a packet that does not decrypt does not move the window forward
        bogus_sa = SecurityAssociation(self.encryption_type,
                                       p.vpp_tra_spi)
        pkt = (Ether(src=self.tra_if.remote_mac,
                     dst=self.tra_if.local_mac) /
               bogus_sa.encrypt(IP(src=self.tra_if.remote_ip4,
                                   dst=self.tra_if.local_ip4) /
                                ICMP(),
                                seq_num=350))
        self.send_and_assert_no_replies(self.tra_if, pkt * 17)

        self.assert_packet_counter_equal(
            '/err/%s/Integrity check failed' % self.tra4_decrypt_node_name, 17)

        # which we can determine since this packet is still in the window
        pkt = (Ether(src=self.tra_if.remote_mac,
                     dst=self.tra_if.local_mac) /
               p.scapy_tra_sa.encrypt(IP(src=self.tra_if.remote_ip4,
                                         dst=self.tra_if.local_ip4) /
                                      ICMP(),
                                      seq_num=234))
        self.send_and_expect(self.tra_if, [pkt], self.tra_if)

        # move the security-associations seq number on to the last we used
        p.scapy_tra_sa.seq_num = 351
        p.vpp_tra_sa.seq_num = 351
예제 #29
0
def format_packet_information(packet_data):
    decoded = Ether(packet_data)
    return format_scapy_packet(decoded)
예제 #30
0
파일: test_map.py 프로젝트: lfntac/vpp
    def test_map_t(self):
        """ MAP-T """

        #
        # Add a domain that maps from pg0 to pg1
        #
        map_dst = '2001:db8::/32'
        map_src = '1234:5678:90ab:cdef::/64'
        ip4_pfx = '192.168.0.0/24'

        self.vapi.map_add_domain(map_dst, ip4_pfx, map_src, 16, 6, 4, mtu=1500)

        # Enable MAP-T on interfaces.
        self.vapi.map_if_enable_disable(is_enable=1,
                                        sw_if_index=self.pg0.sw_if_index,
                                        is_translation=1)
        self.vapi.map_if_enable_disable(is_enable=1,
                                        sw_if_index=self.pg1.sw_if_index,
                                        is_translation=1)

        # Ensure MAP doesn't steal all packets!
        v4 = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
              IP(src=self.pg0.remote_ip4, dst=self.pg0.remote_ip4) /
              UDP(sport=20000, dport=10000) / Raw('\xa5' * 100))
        rx = self.send_and_expect(self.pg0, v4 * 1, self.pg0)
        v4_reply = v4[1]
        v4_reply.ttl -= 1
        for p in rx:
            self.validate(p[1], v4_reply)
        # Ensure MAP doesn't steal all packets
        v6 = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
              IPv6(src=self.pg1.remote_ip6, dst=self.pg1.remote_ip6) /
              UDP(sport=20000, dport=10000) / Raw('\xa5' * 100))
        rx = self.send_and_expect(self.pg1, v6 * 1, self.pg1)
        v6_reply = v6[1]
        v6_reply.hlim -= 1
        for p in rx:
            self.validate(p[1], v6_reply)

        map_route = VppIpRoute(self,
                               "2001:db8::",
                               32, [
                                   VppRoutePath(self.pg1.remote_ip6,
                                                self.pg1.sw_if_index,
                                                proto=DpoProto.DPO_PROTO_IP6)
                               ],
                               is_ip6=1)
        map_route.add_vpp_config()

        #
        # Send a v4 packet that will be translated
        #
        p_ether = Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
        p_ip4 = IP(src=self.pg0.remote_ip4, dst='192.168.0.1')
        payload = TCP(sport=0xabcd, dport=0xabcd)

        p4 = (p_ether / p_ip4 / payload)
        p6_translated = (IPv6(src="1234:5678:90ab:cdef:ac:1001:200:0",
                              dst="2001:db8:1f0::c0a8:1:f") / payload)
        p6_translated.hlim -= 1
        rx = self.send_and_expect(self.pg0, p4 * 1, self.pg1)
        for p in rx:
            self.validate(p[1], p6_translated)

        # Send back an IPv6 packet that will be "untranslated"
        p_ether6 = Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac)
        p_ip6 = IPv6(src='2001:db8:1f0::c0a8:1:f',
                     dst='1234:5678:90ab:cdef:ac:1001:200:0')
        p6 = (p_ether6 / p_ip6 / payload)
        p4_translated = (IP(src='192.168.0.1', dst=self.pg0.remote_ip4) /
                         payload)
        p4_translated.id = 0
        p4_translated.ttl -= 1
        rx = self.send_and_expect(self.pg1, p6 * 1, self.pg0)
        for p in rx:
            self.validate(p[1], p4_translated)

        # IPv4 TTL
        ip4_ttl_expired = IP(src=self.pg0.remote_ip4, dst='192.168.0.1', ttl=0)
        p4 = (p_ether / ip4_ttl_expired / payload)

        icmp4_reply = (
            IP(id=0, ttl=254, src=self.pg0.local_ip4, dst=self.pg0.remote_ip4)
            / ICMP(type='time-exceeded', code='ttl-zero-during-transit') /
            IP(src=self.pg0.remote_ip4, dst='192.168.0.1', ttl=0) / payload)
        rx = self.send_and_expect(self.pg0, p4 * 1, self.pg0)
        for p in rx:
            self.validate(p[1], icmp4_reply)
        '''
        This one is broken, cause it would require hairpinning...
        # IPv4 TTL TTL1
        ip4_ttl_expired = IP(src=self.pg0.remote_ip4, dst='192.168.0.1', ttl=1)
        p4 = (p_ether / ip4_ttl_expired / payload)

        icmp4_reply = IP(id=0, ttl=254, src=self.pg0.local_ip4,
        dst=self.pg0.remote_ip4) / \
        ICMP(type='time-exceeded', code='ttl-zero-during-transit' ) / \
        IP(src=self.pg0.remote_ip4, dst='192.168.0.1', ttl=0) / payload
        rx = self.send_and_expect(self.pg0, p4*1, self.pg0)
        for p in rx:
            self.validate(p[1], icmp4_reply)
        '''

        # IPv6 Hop limit
        ip6_hlim_expired = IPv6(hlim=0,
                                src='2001:db8:1ab::c0a8:1:ab',
                                dst='1234:5678:90ab:cdef:ac:1001:200:0')
        p6 = (p_ether6 / ip6_hlim_expired / payload)

        icmp6_reply = (IPv6(
            hlim=255, src=self.pg1.local_ip6, dst="2001:db8:1ab::c0a8:1:ab") /
                       ICMPv6TimeExceeded(code=0) /
                       IPv6(src="2001:db8:1ab::c0a8:1:ab",
                            dst='1234:5678:90ab:cdef:ac:1001:200:0',
                            hlim=0) / payload)
        rx = self.send_and_expect(self.pg1, p6 * 1, self.pg1)
        for p in rx:
            self.validate(p[1], icmp6_reply)

        # IPv4 Well-known port
        p_ip4 = IP(src=self.pg0.remote_ip4, dst='192.168.0.1')
        payload = UDP(sport=200, dport=200)
        p4 = (p_ether / p_ip4 / payload)
        self.send_and_assert_no_replies(self.pg0, p4 * 1)

        # IPv6 Well-known port
        payload = UDP(sport=200, dport=200)
        p6 = (p_ether6 / p_ip6 / payload)
        self.send_and_assert_no_replies(self.pg1, p6 * 1)

        # Packet fragmentation
        payload = UDP(sport=40000, dport=4000) / self.payload(1453)
        p4 = (p_ether / p_ip4 / payload)
        self.pg_enable_capture()
        self.pg0.add_stream(p4)
        self.pg_start()
        rx = self.pg1.get_capture(2)
        for p in rx:
            pass
            # TODO: Manual validation
            # self.validate(p[1], icmp4_reply)

        # Packet fragmentation send fragments
        payload = UDP(sport=40000, dport=4000) / self.payload(1453)
        p4 = (p_ether / p_ip4 / payload)
        frags = fragment(p4, fragsize=1000)
        self.pg_enable_capture()
        self.pg0.add_stream(frags)
        self.pg_start()
        rx = self.pg1.get_capture(2)
        for p in rx:
            pass
            # p.show2()
        # reass_pkt = reassemble(rx)
        # p4_reply.ttl -= 1
        # p4_reply.id = 256
        # self.validate(reass_pkt, p4_reply)

        # TCP MSS clamping
        self.vapi.map_param_set_tcp(1300)

        #
        # Send a v4 TCP SYN packet that will be translated and MSS clamped
        #
        p_ether = Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
        p_ip4 = IP(src=self.pg0.remote_ip4, dst='192.168.0.1')
        payload = TCP(sport=0xabcd,
                      dport=0xabcd,
                      flags="S",
                      options=[('MSS', 1460)])

        p4 = (p_ether / p_ip4 / payload)
        p6_translated = (IPv6(src="1234:5678:90ab:cdef:ac:1001:200:0",
                              dst="2001:db8:1f0::c0a8:1:f") / payload)
        p6_translated.hlim -= 1
        p6_translated[TCP].options = [('MSS', 1300)]
        rx = self.send_and_expect(self.pg0, p4 * 1, self.pg1)
        for p in rx:
            self.validate(p[1], p6_translated)

        # Send back an IPv6 packet that will be "untranslated"
        p_ether6 = Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac)
        p_ip6 = IPv6(src='2001:db8:1f0::c0a8:1:f',
                     dst='1234:5678:90ab:cdef:ac:1001:200:0')
        p6 = (p_ether6 / p_ip6 / payload)
        p4_translated = (IP(src='192.168.0.1', dst=self.pg0.remote_ip4) /
                         payload)
        p4_translated.id = 0
        p4_translated.ttl -= 1
        p4_translated[TCP].options = [('MSS', 1300)]
        rx = self.send_and_expect(self.pg1, p6 * 1, self.pg0)
        for p in rx:
            self.validate(p[1], p4_translated)