linux-cp: Complete interface creation logic
Linux Control Plane interface creation logic is currently only able to create untagged interfaces, and dot1q VLAN sub-interfaces. This change makes it possible to create dot1ad VLAN sub-ints, and Q-in-AD as well as Q-in-Q sub-interfaces as well. It makes the plugin a bit more robust by catching a few common errors, such as creating an lcp on a sub-interface without its parent having one, and creating an lcp on a sub-interface that is not exact-match. This change has a bunch of smaller improvemnets as well. I documented my work in this post: https://ipng.ch/s/articles/2021/08/12/vpp-1.html It shows that after the change is merged, all VPP interface types now create and operate cleanly as LCP interfaces as well. Type: improvement Signed-off-by: Pim van Pelt <pim@ipng.nl> Change-Id: I322669f7316d44c227090b83d6a574fb9c00e76a
This commit is contained in:
committed by
Matthew Smith
parent
7b46e4bc57
commit
b89c1ddcb3
@@ -28,8 +28,9 @@ lcp_get_default_ns (void)
|
||||
{
|
||||
lcp_main_t *lcpm = &lcp_main;
|
||||
|
||||
if (lcpm->default_namespace[0] == 0)
|
||||
return 0;
|
||||
if (!lcpm->default_namespace || lcpm->default_namespace[0] == 0)
|
||||
return NULL;
|
||||
|
||||
return lcpm->default_namespace;
|
||||
}
|
||||
|
||||
@@ -59,16 +60,15 @@ lcp_set_default_ns (u8 *ns)
|
||||
|
||||
if (!p || *p == 0)
|
||||
{
|
||||
clib_memset (lcpm->default_namespace, 0,
|
||||
sizeof (lcpm->default_namespace));
|
||||
lcpm->default_namespace = NULL;
|
||||
if (lcpm->default_ns_fd > 0)
|
||||
close (lcpm->default_ns_fd);
|
||||
lcpm->default_ns_fd = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
clib_strncpy ((char *) lcpm->default_namespace, p, LCP_NS_LEN - 1);
|
||||
|
||||
vec_validate_init_c_string (lcpm->default_namespace, p,
|
||||
clib_strnlen (p, LCP_NS_LEN));
|
||||
s = format (0, "/var/run/netns/%s%c", (char *) lcpm->default_namespace, 0);
|
||||
lcpm->default_ns_fd = open ((char *) s, O_RDONLY);
|
||||
vec_free (s);
|
||||
|
||||
@@ -22,9 +22,8 @@
|
||||
typedef struct lcp_main_s
|
||||
{
|
||||
u16 msg_id_base; /* API message ID base */
|
||||
u8 default_namespace[LCP_NS_LEN]; /* default namespace if set */
|
||||
u8 *default_namespace; /* default namespace if set */
|
||||
int default_ns_fd;
|
||||
u8 auto_intf;
|
||||
/* Set when Unit testing */
|
||||
u8 test_mode;
|
||||
} lcp_main_t;
|
||||
|
||||
@@ -8,9 +8,9 @@ Linux Control Plane Integration
|
||||
Overview
|
||||
________
|
||||
|
||||
This plugin allows VPP to integrate with the Linux. The
|
||||
This plugin allows VPP to integrate with the Linux kernel. The
|
||||
general model is that Linux is the network stack, i.e. it has the
|
||||
control plane protocols, like ARP, IPv6 ND/MLD, Ping, etc, and VPP
|
||||
control plane protocols, like ARP, IPv6 ND/MLD, ping, etc, and VPP
|
||||
provides a SW based ASIC for forwarding.
|
||||
|
||||
Interfaces
|
||||
@@ -20,16 +20,17 @@ VPP owns the interfaces in the system; physical (.e.g PCI), quasi
|
||||
physical (e.g. vhost), or virtual (e.g. tunnel). However,
|
||||
for the Linux networking stack to function it needs a representation
|
||||
of these interfaces; it needs a mirror image in the kernel. For this
|
||||
mirror we use a Tap interface, if the VPP interface is multi-point, a
|
||||
Tun if it's point-to-point. A physical and its mirror form an
|
||||
mirror we use a TAP interface, if the VPP interface is multi-point, a
|
||||
TUN if it's point-to-point. A physical and its mirror form an
|
||||
interface 'pair'.
|
||||
|
||||
The host interface has two identities; the sw_if_index of the Tap and
|
||||
the virtual interface index in the kernel. It may be in a Linux namespace.
|
||||
The host interface has two identities; the sw_if_index of the TAP and
|
||||
the virtual interface index in the kernel. It may be in a Linux network
|
||||
namespace.
|
||||
|
||||
The creation of the interface pairs is required from the control
|
||||
plane. It can be statically configured in the VPP startup
|
||||
configuration file. The intent here was to make the pair creation
|
||||
configuration file. The intent here is to make the pair creation
|
||||
explicit, rather than have VPP guess which of the interfaces it owns
|
||||
require a mirror.
|
||||
|
||||
@@ -46,22 +47,21 @@ achieved in various ways, for example by listening to the netlink
|
||||
messages and applying the config. As a result all e.g. routes
|
||||
programmed in Linux, will also be present in VPP's FIB.
|
||||
|
||||
Linux will own the [ARP/ND] nieghbor tables (which will be copied via
|
||||
Linux will own the [ARP/ND] neighbor tables (which will be copied via
|
||||
netlink to VPP also). This means that Linux will send packets with the
|
||||
peer's MAC address in the rewrite to VPP. The receiving TAP interface
|
||||
must therefore be in promiscuous mode.
|
||||
|
||||
|
||||
Forwarding
|
||||
__________
|
||||
|
||||
The basic principle is to x-connect traffic from a Linux host interface
|
||||
(received on the Tap/Tun) to its paired the physical, and vice-versa.
|
||||
(received on the tap/tun) to its paired the physical, and vice-versa.
|
||||
|
||||
Host to Physical
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
All packets sent by the host, and received by VPP on a Tap/Tun should
|
||||
All packets sent by the host, and received by VPP on a tap/tun should
|
||||
be sent to its paired physical interface. However, they should be sent
|
||||
with the same consequences as if they had originated from VPP,
|
||||
i.e. they should be subject to all output features on the physical
|
||||
@@ -73,17 +73,18 @@ adjacency that VPP would have used to send this packet; this adjacency
|
||||
is stored in the buffer's meta data so that it is available to all
|
||||
output features. Then the packet is sent through the physical
|
||||
interface's IP output feature arc.
|
||||
|
||||
All ARP packets are x-connected from the tap to the physical.
|
||||
|
||||
Physical to Host
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
All ARP packets received on the physical are sent to the paired
|
||||
Tap. This allows the Linux network stack to build the nieghbour table.
|
||||
tap. This allows the Linux network stack to build the neighbor table.
|
||||
|
||||
IP packets that are punted are sent to the host. They are sent on the
|
||||
tap that is paired with the physical on which they were originally
|
||||
received. The packet is sent on the Tap/Tun 'exactly' as it was
|
||||
received. The packet is sent on the tap/tun 'exactly' as it was
|
||||
received (i.e. with the L2 rewrite) but post any translations that
|
||||
input features may have made.
|
||||
|
||||
@@ -92,5 +93,4 @@ Recommendations
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
When using this plugin disable the ARP, ND, IGMP plugins; this is the
|
||||
task for Linux.
|
||||
Disable ping plugin, since Linux will now respond.
|
||||
task for Linux. Disable ping plugin, since Linux will now respond.
|
||||
|
||||
@@ -185,8 +185,8 @@ lcp_adj_show_cmd (vlib_main_t *vm, unformat_input_t *input,
|
||||
if (unformat (input, "verbose"))
|
||||
verbose = 1;
|
||||
|
||||
vlib_cli_output (vm, "Linux-CP Adjs:\n%U", BV (format_bihash), &lcp_adj_tbl,
|
||||
verbose);
|
||||
vlib_cli_output (vm, "linux-cp adjacencies:\n%U", BV (format_bihash),
|
||||
&lcp_adj_tbl, verbose);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -210,7 +210,7 @@ lcp_adj_init (vlib_main_t *vm)
|
||||
{
|
||||
adj_type = adj_delegate_register_new_type (&lcp_adj_vft);
|
||||
|
||||
BV (clib_bihash_init) (&lcp_adj_tbl, "linux-cp ADJ table", 1024, 1 << 24);
|
||||
BV (clib_bihash_init) (&lcp_adj_tbl, "linux-cp adjacencies", 1024, 1 << 24);
|
||||
BV (clib_bihash_set_kvp_format_fn) (&lcp_adj_tbl, format_lcp_adj_kvp);
|
||||
|
||||
return (NULL);
|
||||
|
||||
@@ -41,22 +41,6 @@ api_encode_host_type (lip_host_type_t type)
|
||||
return LCP_API_ITF_HOST_TAP;
|
||||
}
|
||||
|
||||
void
|
||||
lcp_set_auto_intf (u8 is_auto)
|
||||
{
|
||||
lcp_main_t *lcpm = &lcp_main;
|
||||
|
||||
lcpm->auto_intf = (is_auto != 0);
|
||||
}
|
||||
|
||||
int
|
||||
lcp_auto_intf (void)
|
||||
{
|
||||
lcp_main_t *lcpm = &lcp_main;
|
||||
|
||||
return lcpm->auto_intf;
|
||||
}
|
||||
|
||||
static int
|
||||
vl_api_lcp_itf_pair_add (u32 phy_sw_if_index, lip_host_type_t lip_host_type,
|
||||
u8 *mp_host_if_name, size_t sizeof_host_if_name,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user