BVI Interface
a new dedicated BVI interface as opposed to [re]using a loopback. benefits: - removes ambiguity over the purpose of a loopback interface - TX node dedicated to BVI only functions. Change-Id: I749d6b38440d450ac5b909a28053c75ec9df946a Signed-off-by: Neale Ranns <nranns@cisco.com>
This commit is contained in:
@ -161,6 +161,7 @@ list(APPEND VNET_SOURCES
|
||||
l2/l2_api.c
|
||||
l2/l2_bd.c
|
||||
l2/l2_bvi.c
|
||||
l2/l2_bvi_node.c
|
||||
l2/l2_input_classify.c
|
||||
l2/l2_output_classify.c
|
||||
l2/l2_efp_filter.c
|
||||
@ -181,6 +182,7 @@ list(APPEND VNET_SOURCES
|
||||
)
|
||||
|
||||
list(APPEND VNET_MULTIARCH_SOURCES
|
||||
l2/l2_bvi_node.c
|
||||
l2/l2_fwd.c
|
||||
l2/l2_learn.c
|
||||
l2/l2_output.c
|
||||
|
@ -314,7 +314,7 @@ ethernet_interface_t *ethernet_get_interface (ethernet_main_t * em,
|
||||
clib_error_t *ethernet_register_interface (vnet_main_t * vnm,
|
||||
u32 dev_class_index,
|
||||
u32 dev_instance,
|
||||
u8 * address,
|
||||
const u8 * address,
|
||||
u32 * hw_if_index_return,
|
||||
ethernet_flag_change_function_t
|
||||
flag_change);
|
||||
|
@ -278,7 +278,7 @@ clib_error_t *
|
||||
ethernet_register_interface (vnet_main_t * vnm,
|
||||
u32 dev_class_index,
|
||||
u32 dev_instance,
|
||||
u8 * address,
|
||||
const u8 * address,
|
||||
u32 * hw_if_index_return,
|
||||
ethernet_flag_change_function_t flag_change)
|
||||
{
|
||||
|
@ -553,6 +553,44 @@ autoreply define sw_interface_set_vpath
|
||||
u8 enable;
|
||||
};
|
||||
|
||||
/** \brief Create BVI interface instance request
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@param context - sender context, to match reply w/ request
|
||||
@param mac_address - mac addr to assign to the interface if none-zero
|
||||
@param user_instance - requested instance, ~0 => dynamically allocate
|
||||
*/
|
||||
define bvi_create
|
||||
{
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
vl_api_mac_address_t mac;
|
||||
u32 user_instance;
|
||||
};
|
||||
|
||||
/** \brief Create BVI interface instance response
|
||||
@param context - sender context, to match reply w/ request
|
||||
@param sw_if_index - sw index of the interface that was created
|
||||
@param retval - return code for the request
|
||||
*/
|
||||
define bvi_create_reply
|
||||
{
|
||||
u32 context;
|
||||
i32 retval;
|
||||
u32 sw_if_index;
|
||||
};
|
||||
|
||||
/** \brief Delete BVI interface request
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@param context - sender context, to match reply w/ request
|
||||
@param sw_if_index - sw index of the interface that was created
|
||||
*/
|
||||
autoreply define bvi_delete
|
||||
{
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
u32 sw_if_index;
|
||||
};
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <vnet/l2/l2_vtr.h>
|
||||
#include <vnet/l2/l2_learn.h>
|
||||
#include <vnet/l2/l2_bd.h>
|
||||
#include <vnet/l2/l2_bvi.h>
|
||||
#include <vnet/ip/ip_types_api.h>
|
||||
#include <vnet/ethernet/ethernet_types_api.h>
|
||||
|
||||
@ -74,7 +75,9 @@ _(BRIDGE_FLAGS, bridge_flags) \
|
||||
_(L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite) \
|
||||
_(L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite) \
|
||||
_(BRIDGE_DOMAIN_SET_MAC_AGE, bridge_domain_set_mac_age) \
|
||||
_(SW_INTERFACE_SET_VPATH, sw_interface_set_vpath)
|
||||
_(SW_INTERFACE_SET_VPATH, sw_interface_set_vpath) \
|
||||
_(BVI_CREATE, bvi_create) \
|
||||
_(BVI_DELETE, bvi_delete)
|
||||
|
||||
static void
|
||||
send_l2_xconnect_details (vl_api_registration_t * reg, u32 context,
|
||||
@ -993,6 +996,37 @@ vl_api_sw_interface_set_vpath_t_handler (vl_api_sw_interface_set_vpath_t * mp)
|
||||
REPLY_MACRO (VL_API_SW_INTERFACE_SET_VPATH_REPLY);
|
||||
}
|
||||
|
||||
static void
|
||||
vl_api_bvi_create_t_handler (vl_api_bvi_create_t * mp)
|
||||
{
|
||||
vl_api_bvi_create_reply_t *rmp;
|
||||
mac_address_t mac;
|
||||
u32 sw_if_index;
|
||||
int rv;
|
||||
|
||||
mac_address_decode (mp->mac, &mac);
|
||||
|
||||
rv = l2_bvi_create (ntohl (mp->user_instance), &mac, &sw_if_index);
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
REPLY_MACRO2(VL_API_BVI_CREATE_REPLY,
|
||||
({
|
||||
rmp->sw_if_index = ntohl (sw_if_index);
|
||||
}));
|
||||
/* *INDENT-ON* */
|
||||
}
|
||||
|
||||
static void
|
||||
vl_api_bvi_delete_t_handler (vl_api_bvi_delete_t * mp)
|
||||
{
|
||||
vl_api_bvi_delete_reply_t *rmp;
|
||||
int rv;
|
||||
|
||||
rv = l2_bvi_delete (ntohl (mp->sw_if_index));
|
||||
|
||||
REPLY_MACRO (VL_API_BVI_DELETE_REPLY);
|
||||
}
|
||||
|
||||
/*
|
||||
* l2_api_hookup
|
||||
* Add vpe's API message handlers to the table.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -97,6 +97,11 @@ l2_to_bvi (vlib_main_t * vlib_main,
|
||||
void
|
||||
l2bvi_register_input_type (vlib_main_t * vm,
|
||||
ethernet_type_t type, u32 node_index);
|
||||
|
||||
extern int l2_bvi_create (u32 instance, const mac_address_t * mac,
|
||||
u32 * sw_if_index);
|
||||
extern int l2_bvi_delete (u32 sw_if_index);
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
116
src/vnet/l2/l2_bvi_node.c
Normal file
116
src/vnet/l2/l2_bvi_node.c
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* l2_bvi.c : layer 2 Bridged Virtual Interface
|
||||
*
|
||||
* Copyright (c) 2013 Cisco and/or its affiliates.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <vnet/l2/l2_bvi.h>
|
||||
|
||||
/**
|
||||
* send packets to l2-input.
|
||||
*/
|
||||
VNET_DEVICE_CLASS_TX_FN (bvi_device_class) (vlib_main_t * vm,
|
||||
vlib_node_runtime_t * node,
|
||||
vlib_frame_t * frame)
|
||||
{
|
||||
u32 sw_if_indices[VLIB_FRAME_SIZE], *sw_if_index;
|
||||
vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b;
|
||||
u16 nexts[VLIB_FRAME_SIZE];
|
||||
u32 n_left, *from;
|
||||
|
||||
n_left = frame->n_vectors;
|
||||
from = vlib_frame_vector_args (frame);
|
||||
|
||||
vlib_get_buffers (vm, from, bufs, n_left);
|
||||
|
||||
b = bufs;
|
||||
sw_if_index = sw_if_indices;
|
||||
|
||||
/* It's all going to l2-input */
|
||||
clib_memset_u16 (nexts, 0, VLIB_FRAME_SIZE);
|
||||
|
||||
/*
|
||||
* For each packet:
|
||||
* - fixup the L2 length of the packet
|
||||
* - set the RX interface (which the bridge will use) to the
|
||||
* TX interface (which routing has chosen)
|
||||
* - Set the TX interface to the special ID so the DP knows this is a BVI
|
||||
* Don't counts packets and bytes, that's done in the bviX-output node
|
||||
*/
|
||||
while (n_left >= 4)
|
||||
{
|
||||
/* Prefetch next iteration. */
|
||||
if (PREDICT_TRUE (n_left >= 8))
|
||||
{
|
||||
/* LOAD pre-fetch since meta and packet data is read */
|
||||
vlib_prefetch_buffer_header (b[4], LOAD);
|
||||
vlib_prefetch_buffer_header (b[5], LOAD);
|
||||
vlib_prefetch_buffer_header (b[6], LOAD);
|
||||
vlib_prefetch_buffer_header (b[7], LOAD);
|
||||
|
||||
vlib_prefetch_buffer_data (b[4], LOAD);
|
||||
vlib_prefetch_buffer_data (b[5], LOAD);
|
||||
vlib_prefetch_buffer_data (b[6], LOAD);
|
||||
vlib_prefetch_buffer_data (b[7], LOAD);
|
||||
}
|
||||
|
||||
vnet_update_l2_len (b[0]);
|
||||
vnet_update_l2_len (b[1]);
|
||||
vnet_update_l2_len (b[2]);
|
||||
vnet_update_l2_len (b[3]);
|
||||
|
||||
sw_if_index[0] = vnet_buffer (b[0])->sw_if_index[VLIB_TX];
|
||||
sw_if_index[1] = vnet_buffer (b[1])->sw_if_index[VLIB_TX];
|
||||
sw_if_index[2] = vnet_buffer (b[2])->sw_if_index[VLIB_TX];
|
||||
sw_if_index[3] = vnet_buffer (b[3])->sw_if_index[VLIB_TX];
|
||||
|
||||
vnet_buffer (b[0])->sw_if_index[VLIB_TX] = L2INPUT_BVI;
|
||||
vnet_buffer (b[1])->sw_if_index[VLIB_TX] = L2INPUT_BVI;
|
||||
vnet_buffer (b[2])->sw_if_index[VLIB_TX] = L2INPUT_BVI;
|
||||
vnet_buffer (b[3])->sw_if_index[VLIB_TX] = L2INPUT_BVI;
|
||||
|
||||
vnet_buffer (b[0])->sw_if_index[VLIB_RX] = sw_if_index[0];
|
||||
vnet_buffer (b[1])->sw_if_index[VLIB_RX] = sw_if_index[1];
|
||||
vnet_buffer (b[2])->sw_if_index[VLIB_RX] = sw_if_index[2];
|
||||
vnet_buffer (b[3])->sw_if_index[VLIB_RX] = sw_if_index[3];
|
||||
|
||||
b += 4;
|
||||
n_left -= 4;
|
||||
sw_if_index += 4;
|
||||
}
|
||||
while (n_left)
|
||||
{
|
||||
sw_if_index[0] = vnet_buffer (b[0])->sw_if_index[VLIB_TX];
|
||||
vnet_buffer (b[0])->sw_if_index[VLIB_TX] = L2INPUT_BVI;
|
||||
vnet_buffer (b[0])->sw_if_index[VLIB_RX] = sw_if_index[0];
|
||||
|
||||
vnet_update_l2_len (b[0]);
|
||||
|
||||
b += 1;
|
||||
n_left -= 1;
|
||||
sw_if_index += 1;
|
||||
}
|
||||
|
||||
vlib_buffer_enqueue_to_next (vm, node, from, nexts, frame->n_vectors);
|
||||
|
||||
return frame->n_vectors;
|
||||
}
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
* Local Variables:
|
||||
* eval: (c-set-style "gnu")
|
||||
* End:
|
||||
*/
|
@ -25,6 +25,7 @@ from hook import StepHook, PollHook, VppDiedError
|
||||
from vpp_pg_interface import VppPGInterface
|
||||
from vpp_sub_interface import VppSubInterface
|
||||
from vpp_lo_interface import VppLoInterface
|
||||
from vpp_bvi_interface import VppBviInterface
|
||||
from vpp_papi_provider import VppPapiProvider
|
||||
from vpp_papi.vpp_stats import VPPStats
|
||||
from log import RED, GREEN, YELLOW, double_line_delim, single_line_delim, \
|
||||
@ -690,6 +691,20 @@ class VppTestCase(unittest.TestCase):
|
||||
cls.lo_interfaces = result
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
def create_bvi_interfaces(cls, count):
|
||||
"""
|
||||
Create BVI interfaces.
|
||||
|
||||
:param count: number of interfaces created.
|
||||
:returns: List of created interfaces.
|
||||
"""
|
||||
result = [VppBviInterface(cls) for i in range(count)]
|
||||
for intf in result:
|
||||
setattr(cls, intf.name, intf)
|
||||
cls.bvi_interfaces = result
|
||||
return result
|
||||
|
||||
@staticmethod
|
||||
def extend_packet(packet, size, padding=' '):
|
||||
"""
|
||||
|
@ -42,10 +42,10 @@ class TestIpIrb(VppTestCase):
|
||||
def setUpClass(cls):
|
||||
"""
|
||||
#. Create BD with MAC learning enabled and put interfaces to this BD.
|
||||
#. Configure IPv4 addresses on loopback interface and routed interface.
|
||||
#. Configure MAC address binding to IPv4 neighbors on loop0.
|
||||
#. Configure IPv4 addresses on BVI interface and routed interface.
|
||||
#. Configure MAC address binding to IPv4 neighbors on bvi0.
|
||||
#. Configure MAC address on pg2.
|
||||
#. Loopback BVI interface has remote hosts, one half of hosts are
|
||||
#. BVI interface has remote hosts, one half of hosts are
|
||||
behind pg0 second behind pg1.
|
||||
"""
|
||||
super(TestIpIrb, cls).setUpClass()
|
||||
@ -54,40 +54,40 @@ class TestIpIrb(VppTestCase):
|
||||
cls.bd_id = 10
|
||||
cls.remote_hosts_count = 250
|
||||
|
||||
# create 3 pg interfaces, 1 loopback interface
|
||||
# create 3 pg interfaces, 1 BVI interface
|
||||
cls.create_pg_interfaces(range(3))
|
||||
cls.create_loopback_interfaces(1)
|
||||
cls.create_bvi_interfaces(1)
|
||||
|
||||
cls.interfaces = list(cls.pg_interfaces)
|
||||
cls.interfaces.extend(cls.lo_interfaces)
|
||||
cls.interfaces.extend(cls.bvi_interfaces)
|
||||
|
||||
for i in cls.interfaces:
|
||||
i.admin_up()
|
||||
|
||||
# Create BD with MAC learning enabled and put interfaces to this BD
|
||||
cls.vapi.sw_interface_set_l2_bridge(
|
||||
rx_sw_if_index=cls.loop0.sw_if_index, bd_id=cls.bd_id,
|
||||
rx_sw_if_index=cls.bvi0.sw_if_index, bd_id=cls.bd_id,
|
||||
port_type=L2_PORT_TYPE.BVI)
|
||||
cls.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=cls.pg0.sw_if_index,
|
||||
bd_id=cls.bd_id)
|
||||
cls.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=cls.pg1.sw_if_index,
|
||||
bd_id=cls.bd_id)
|
||||
|
||||
# Configure IPv4 addresses on loopback interface and routed interface
|
||||
cls.loop0.config_ip4()
|
||||
# Configure IPv4 addresses on BVI interface and routed interface
|
||||
cls.bvi0.config_ip4()
|
||||
cls.pg2.config_ip4()
|
||||
|
||||
# Configure MAC address binding to IPv4 neighbors on loop0
|
||||
cls.loop0.generate_remote_hosts(cls.remote_hosts_count)
|
||||
cls.loop0.configure_ipv4_neighbors()
|
||||
# Configure MAC address binding to IPv4 neighbors on bvi0
|
||||
cls.bvi0.generate_remote_hosts(cls.remote_hosts_count)
|
||||
cls.bvi0.configure_ipv4_neighbors()
|
||||
# configure MAC address on pg2
|
||||
cls.pg2.resolve_arp()
|
||||
|
||||
# Loopback BVI interface has remote hosts, one half of hosts are behind
|
||||
# BVI interface has remote hosts, one half of hosts are behind
|
||||
# pg0 second behind pg1
|
||||
half = cls.remote_hosts_count // 2
|
||||
cls.pg0.remote_hosts = cls.loop0.remote_hosts[:half]
|
||||
cls.pg1.remote_hosts = cls.loop0.remote_hosts[half:]
|
||||
cls.pg0.remote_hosts = cls.bvi0.remote_hosts[:half]
|
||||
cls.pg1.remote_hosts = cls.bvi0.remote_hosts[half:]
|
||||
|
||||
def tearDown(self):
|
||||
"""Run standard test teardown and log ``show l2patch``,
|
||||
@ -220,32 +220,32 @@ class TestIpIrb(VppTestCase):
|
||||
|
||||
Test scenario:
|
||||
- ip traffic from pg2 interface must ends in both pg0 and pg1
|
||||
- arp entry present in loop0 interface for destination IP
|
||||
- no l2 entree configured, pg0 and pg1 are same
|
||||
- arp entry present in bvi0 interface for destination IP
|
||||
- no l2 entry configured, pg0 and pg1 are same
|
||||
"""
|
||||
|
||||
stream = self.create_stream(
|
||||
self.pg2, self.loop0, self.pg_if_packet_sizes)
|
||||
self.pg2, self.bvi0, self.pg_if_packet_sizes)
|
||||
self.pg2.add_stream(stream)
|
||||
|
||||
self.pg_enable_capture(self.pg_interfaces)
|
||||
self.pg_start()
|
||||
|
||||
packet_count = self.get_packet_count_for_if_idx(self.loop0.sw_if_index)
|
||||
packet_count = self.get_packet_count_for_if_idx(self.bvi0.sw_if_index)
|
||||
|
||||
rcvd1 = self.pg0.get_capture(packet_count)
|
||||
rcvd2 = self.pg1.get_capture(packet_count)
|
||||
|
||||
self.verify_capture(self.loop0, self.pg2, rcvd1)
|
||||
self.verify_capture(self.loop0, self.pg2, rcvd2)
|
||||
self.verify_capture(self.bvi0, self.pg2, rcvd1)
|
||||
self.verify_capture(self.bvi0, self.pg2, rcvd2)
|
||||
|
||||
self.assertListEqual(rcvd1.res, rcvd2.res)
|
||||
|
||||
def send_and_verify_l2_to_ip(self):
|
||||
stream1 = self.create_stream_l2_to_ip(
|
||||
self.pg0, self.loop0, self.pg2, self.pg_if_packet_sizes)
|
||||
self.pg0, self.bvi0, self.pg2, self.pg_if_packet_sizes)
|
||||
stream2 = self.create_stream_l2_to_ip(
|
||||
self.pg1, self.loop0, self.pg2, self.pg_if_packet_sizes)
|
||||
self.pg1, self.bvi0, self.pg2, self.pg_if_packet_sizes)
|
||||
self.vapi.cli("clear trace")
|
||||
self.pg0.add_stream(stream1)
|
||||
self.pg1.add_stream(stream2)
|
||||
@ -254,7 +254,7 @@ class TestIpIrb(VppTestCase):
|
||||
self.pg_start()
|
||||
|
||||
rcvd = self.pg2.get_capture(514)
|
||||
self.verify_capture_l2_to_ip(self.pg2, self.loop0, rcvd)
|
||||
self.verify_capture_l2_to_ip(self.pg2, self.bvi0, rcvd)
|
||||
|
||||
def test_ip4_irb_2(self):
|
||||
""" IPv4 IRB test 2
|
||||
@ -265,7 +265,7 @@ class TestIpIrb(VppTestCase):
|
||||
self.send_and_verify_l2_to_ip()
|
||||
|
||||
# change the BVI's mac and resed traffic
|
||||
self.loop0.set_mac(MACAddress("00:00:00:11:11:33"))
|
||||
self.bvi0.set_mac(MACAddress("00:00:00:11:11:33"))
|
||||
|
||||
self.send_and_verify_l2_to_ip()
|
||||
# check it wasn't flooded
|
||||
|
@ -20,24 +20,24 @@ class TestL2Flood(VppTestCase):
|
||||
|
||||
# 12 l2 interface and one l3
|
||||
self.create_pg_interfaces(range(13))
|
||||
self.create_loopback_interfaces(1)
|
||||
self.create_bvi_interfaces(1)
|
||||
|
||||
for i in self.pg_interfaces:
|
||||
i.admin_up()
|
||||
for i in self.lo_interfaces:
|
||||
for i in self.bvi_interfaces:
|
||||
i.admin_up()
|
||||
|
||||
self.pg12.config_ip4()
|
||||
self.pg12.resolve_arp()
|
||||
self.loop0.config_ip4()
|
||||
self.bvi0.config_ip4()
|
||||
|
||||
def tearDown(self):
|
||||
self.pg12.unconfig_ip4()
|
||||
self.loop0.unconfig_ip4()
|
||||
self.bvi0.unconfig_ip4()
|
||||
|
||||
for i in self.pg_interfaces:
|
||||
i.admin_down()
|
||||
for i in self.lo_interfaces:
|
||||
for i in self.bvi_interfaces:
|
||||
i.admin_down()
|
||||
super(TestL2Flood, self).tearDown()
|
||||
|
||||
@ -61,7 +61,7 @@ class TestL2Flood(VppTestCase):
|
||||
for i in self.pg_interfaces[8:12]:
|
||||
self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
|
||||
bd_id=1, shg=2)
|
||||
for i in self.lo_interfaces:
|
||||
for i in self.bvi_interfaces:
|
||||
self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
|
||||
bd_id=1, shg=2,
|
||||
port_type=L2_PORT_TYPE.BVI)
|
||||
@ -142,7 +142,7 @@ class TestL2Flood(VppTestCase):
|
||||
for i in self.pg_interfaces[:12]:
|
||||
self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
|
||||
bd_id=1, enable=0)
|
||||
for i in self.lo_interfaces:
|
||||
for i in self.bvi_interfaces:
|
||||
self.vapi.sw_interface_set_l2_bridge(rx_sw_if_index=i.sw_if_index,
|
||||
bd_id=1, shg=2,
|
||||
port_type=L2_PORT_TYPE.BVI,
|
||||
|
22
test/vpp_bvi_interface.py
Normal file
22
test/vpp_bvi_interface.py
Normal file
@ -0,0 +1,22 @@
|
||||
from vpp_object import VppObject
|
||||
from vpp_interface import VppInterface
|
||||
|
||||
|
||||
class VppBviInterface(VppInterface, VppObject):
|
||||
"""VPP bvi interface."""
|
||||
|
||||
def __init__(self, test):
|
||||
""" Create VPP BVI interface """
|
||||
super(VppBviInterface, self).__init__(test)
|
||||
self.add_vpp_config()
|
||||
|
||||
def add_vpp_config(self):
|
||||
r = self.test.vapi.bvi_create(user_instance=0xffffffff,
|
||||
mac="00:00:00:00:00:00")
|
||||
self.set_sw_if_index(r.sw_if_index)
|
||||
|
||||
def remove_vpp_config(self):
|
||||
self.test.vapi.bvi_delete(sw_if_index=self.sw_if_index)
|
||||
|
||||
def object_id(self):
|
||||
return "bvi-%d" % self._sw_if_index
|
Reference in New Issue
Block a user