summaryrefslogtreecommitdiffstats
path: root/build-root
diff options
context:
space:
mode:
authorDave Barach <dave@barachs.net>2016-11-08 16:47:34 -0500
committerDamjan Marion <dmarion.lists@gmail.com>2016-11-09 11:36:02 +0000
commitb7e2f3d312927f2a8f1b2c8030b2e8ffe3288bab (patch)
tree643cc5551d5e265aab996fa615a9f415de459279 /build-root
parent3a4ed3934585eb841fa36f6f062adf4dce9b4661 (diff)
Update sample plugin and plugin skeletons: use driver feature arc
Change-Id: Ic0a1479e4a0408a4b93f47e50752d07c2bdccdde Signed-off-by: Dave Barach <dave@barachs.net>
Diffstat (limited to 'build-root')
-rw-r--r--build-root/emacs-lisp/plugin-main-skel.el22
-rw-r--r--build-root/emacs-lisp/plugin-makefile-skel.el1
-rw-r--r--build-root/emacs-lisp/plugin-node-skel.el27
3 files changed, 37 insertions, 13 deletions
diff --git a/build-root/emacs-lisp/plugin-main-skel.el b/build-root/emacs-lisp/plugin-main-skel.el
index 0c9cd512e60..196f8653817 100644
--- a/build-root/emacs-lisp/plugin-main-skel.el
+++ b/build-root/emacs-lisp/plugin-main-skel.el
@@ -127,8 +127,7 @@ int " plugin-name "_enable_disable (" plugin-name "_main_t * sm, u32 sw_if_index
int enable_disable)
{
vnet_sw_interface_t * sw;
- int rv;
- u32 node_index = enable_disable ? " plugin-name "_node.index : ~0;
+ int rv = 0;
/* Utterly wrong? */
if (pool_is_free_index (sm->vnet_main->interface_main.sw_interfaces,
@@ -140,15 +139,9 @@ int " plugin-name "_enable_disable (" plugin-name "_main_t * sm, u32 sw_if_index
if (sw->type != VNET_SW_INTERFACE_TYPE_HARDWARE)
return VNET_API_ERROR_INVALID_SW_IF_INDEX;
- /*
- * Redirect pkts from the driver to the macswap node.
- * Returns VNET_API_ERROR_UNIMPLEMENTED if the h/w driver
- * doesn't implement the API.
- *
- * Node_index = ~0 => shut off redirection
- */
- rv = vnet_hw_interface_rx_redirect_to_node (sm->vnet_main, sw_if_index,
- node_index);
+ vnet_feature_enable_disable (\"device-input\", \"" plugin-name "\",
+ sw_if_index, enable_disable, 0, 0);
+
return rv;
}
@@ -258,5 +251,12 @@ static clib_error_t * " plugin-name "_init (vlib_main_t * vm)
}
VLIB_INIT_FUNCTION (" plugin-name "_init);
+
+VNET_FEATURE_INIT (" plugin-name ", static) =
+{
+ .arc_name = \"device-input\",
+ .node_name = \"" plugin-name "\",
+ .runs_before = VNET_FEATURES (\"ethernet-input\"),
+};
")
diff --git a/build-root/emacs-lisp/plugin-makefile-skel.el b/build-root/emacs-lisp/plugin-makefile-skel.el
index dc17ddb99b2..7cb6cbfd5e3 100644
--- a/build-root/emacs-lisp/plugin-makefile-skel.el
+++ b/build-root/emacs-lisp/plugin-makefile-skel.el
@@ -72,5 +72,4 @@ noinst_HEADERS = \\
install-data-hook:
@(cd $(vpppluginsdir) && $(RM) $(vppplugins_LTLIBRARIES))
@(cd $(vppapitestpluginsdir) && $(RM) $(vppapitestplugins_LTLIBRARIES))
-endif
")
diff --git a/build-root/emacs-lisp/plugin-node-skel.el b/build-root/emacs-lisp/plugin-node-skel.el
index 0d88a2efff5..ee745c35326 100644
--- a/build-root/emacs-lisp/plugin-node-skel.el
+++ b/build-root/emacs-lisp/plugin-node-skel.el
@@ -47,8 +47,18 @@ nil
typedef struct {
u32 next_index;
u32 sw_if_index;
+ u8 new_src_mac[6];
+ u8 new_dst_mac[6];
} " plugin-name "_trace_t;
+static u8 *
+format_mac_address (u8 * s, va_list * args)
+{
+ u8 *a = va_arg (*args, u8 *);
+ return format (s, \"%02x:%02x:%02x:%02x:%02x:%02x\",
+ a[0], a[1], a[2], a[3], a[4], a[5]);
+}
+
/* packet trace format function */
static u8 * format_" plugin-name "_trace (u8 * s, va_list * args)
{
@@ -56,8 +66,11 @@ static u8 * format_" plugin-name "_trace (u8 * s, va_list * args)
CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
" plugin-name "_trace_t * t = va_arg (*args, " plugin-name "_trace_t *);
- s = format (s, \"" PLUGIN-NAME ": sw_if_index %d, next index %d\",
+ s = format (s, \"" PLUGIN-NAME ": sw_if_index %d, next index %d\\n\",
t->sw_if_index, t->next_index);
+ s = format (s, \" new src %U -> new dst %U\",
+ format_mac_address, t->new_src_mac,
+ format_mac_address, t->new_dst_mac);
return s;
}
@@ -193,6 +206,10 @@ static uword
vlib_add_trace (vm, node, b0, sizeof (*t));
t->sw_if_index = sw_if_index0;
t->next_index = next0;
+ clib_memcpy (t->new_src_mac, en0->src_address,
+ sizeof (t->new_src_mac));
+ clib_memcpy (t->new_dst_mac, en0->dst_address,
+ sizeof (t->new_dst_mac));
}
if (b1->flags & VLIB_BUFFER_IS_TRACED)
{
@@ -200,6 +217,10 @@ static uword
vlib_add_trace (vm, node, b1, sizeof (*t));
t->sw_if_index = sw_if_index1;
t->next_index = next1;
+ clib_memcpy (t->new_src_mac, en1->src_address,
+ sizeof (t->new_src_mac));
+ clib_memcpy (t->new_dst_mac, en1->dst_address,
+ sizeof (t->new_dst_mac));
}
}
@@ -257,6 +278,10 @@ static uword
vlib_add_trace (vm, node, b0, sizeof (*t));
t->sw_if_index = sw_if_index0;
t->next_index = next0;
+ clib_memcpy (t->new_src_mac, en0->src_address,
+ sizeof (t->new_src_mac));
+ clib_memcpy (t->new_dst_mac, en0->dst_address,
+ sizeof (t->new_dst_mac));
}
pkts_swapped += 1;
600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */ }
#!/usr/bin/env python

import unittest
import socket

from framework import VppTestCase, VppTestRunner
from vpp_ip_route import VppIpRoute, VppRoutePath

from scapy.layers.l2 import Ether, Raw
from scapy.layers.inet import IP, UDP, ICMP
from scapy.layers.inet6 import IPv6


class TestMAP(VppTestCase):
    """ MAP Test Case """

    def setUp(self):
        super(TestMAP, self).setUp()

        # create 2 pg interfaces
        self.create_pg_interfaces(range(4))

        # pg0 is 'inside' IPv4
        self.pg0.admin_up()
        self.pg0.config_ip4()
        self.pg0.resolve_arp()

        # pg1 is 'outside' IPv6
        self.pg1.admin_up()
        self.pg1.config_ip6()
        self.pg1.generate_remote_hosts(4)
        self.pg1.configure_ipv6_neighbors()

    def tearDown(self):
        super(TestMAP, self).tearDown()
        for i in self.pg_interfaces:
            i.unconfig_ip4()
            i.unconfig_ip6()
            i.admin_down()

    def send_and_assert_no_replies(self, intf, pkts, remark):
        intf.add_stream(pkts)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        for i in self.pg_interfaces:
            i.assert_nothing_captured(remark=remark)

    def send_and_assert_encapped(self, tx, ip6_src, ip6_dst, dmac=None):
        if not dmac:
            dmac = self.pg1.remote_mac

        self.pg0.add_stream(tx)

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

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

        self.assertEqual(rx[Ether].dst, dmac)
        self.assertEqual(rx[IP].src, tx[IP].src)
        self.assertEqual(rx[IPv6].src, ip6_src)
        self.assertEqual(rx[IPv6].dst, ip6_dst)

    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,
                                             is_ip6=1)],
                               is_ip6=1)
        map_route.add_vpp_config()

        #
        # Add a domain that maps from pg0 to pg1
        #
        map_dst = socket.inet_pton(socket.AF_INET6, map_br_pfx)
        map_src = "3001::1"
        map_src_n = socket.inet_pton(socket.AF_INET6, map_src)
        client_pfx = socket.inet_pton(socket.AF_INET, "192.168.0.0")

        self.vapi.map_add_domain(map_dst,
                                 map_br_pfx_len,
                                 map_src_n,
                                 128,
                                 client_pfx,
                                 16)

        #
        # 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, map_src, "2001::c0a8:0:0")

        #
        # 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=map_src, 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,
                                        "resovled 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,
                                                 is_ip6=1)],
                                   is_ip6=1)
        pre_res_route.add_vpp_config()

        self.send_and_assert_encapped(v4, map_src,
                                      "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,
                                           is_ip6=1)])
        pre_res_route.add_vpp_config()

        self.send_and_assert_encapped(v4, map_src,
                                      "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")

if __name__ == '__main__':
    unittest.main(testRunner=VppTestRunner)