arping: add arping command
Add linux similar arping command to VPP. syntax: arping [gratuitous] <address> <interface> [repeat <count>] [interval <secs>] Type: feature Signed-off-by: Steven Luong <sluong@cisco.com> Change-Id: I9267c054235207b8fae8e3f159246777eb0340dd
This commit is contained in:

committed by
Beno�t Ganne

parent
19be32876f
commit
a77ae47089
@ -340,6 +340,11 @@ M: Dave Barach <vpp@barachs.net>
|
|||||||
M: Neale Ranns <neale@graphiant.com>
|
M: Neale Ranns <neale@graphiant.com>
|
||||||
F: src/plugins/arp/
|
F: src/plugins/arp/
|
||||||
|
|
||||||
|
Plugin - ARPing CLI
|
||||||
|
I: arping
|
||||||
|
M: Steven Luong <sluong@cisco.com>
|
||||||
|
F: src/plugins/arping/
|
||||||
|
|
||||||
Plugin - IP6 Neighbor Discovery
|
Plugin - IP6 Neighbor Discovery
|
||||||
I: ip6-nd
|
I: ip6-nd
|
||||||
M: Dave Barach <vpp@barachs.net>
|
M: Dave Barach <vpp@barachs.net>
|
||||||
|
24
src/plugins/arping/CMakeLists.txt
Normal file
24
src/plugins/arping/CMakeLists.txt
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# Copyright (c) 2021 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.
|
||||||
|
|
||||||
|
add_vpp_plugin(arping
|
||||||
|
SOURCES
|
||||||
|
arping.c
|
||||||
|
arping_api.c
|
||||||
|
|
||||||
|
API_FILES
|
||||||
|
arping.api
|
||||||
|
|
||||||
|
API_TEST_SOURCES
|
||||||
|
arping_test.c
|
||||||
|
)
|
9
src/plugins/arping/FEATURE.yaml
Normal file
9
src/plugins/arping/FEATURE.yaml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
name: arping command
|
||||||
|
maintainer: Steven Luong <sluong@cisco.com>
|
||||||
|
features:
|
||||||
|
- arping command to send either gratuitous or ARP request to the remote
|
||||||
|
- support both IPv4 and IPv6
|
||||||
|
description: "arping command"
|
||||||
|
state: production
|
||||||
|
properties: [API, CLI, STATS, MULTITHREAD]
|
61
src/plugins/arping/arping.api
Normal file
61
src/plugins/arping/arping.api
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
*------------------------------------------------------------------
|
||||||
|
* Copyright (c) 2021 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.
|
||||||
|
*------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
option version = "1.0.0";
|
||||||
|
import "vnet/interface_types.api";
|
||||||
|
import "vnet/ip/ip_types.api";
|
||||||
|
|
||||||
|
/** \brief
|
||||||
|
@param client_index - opaque cookie to identify the sender
|
||||||
|
@param context - sender context, to match reply w/ request
|
||||||
|
@param address - address to send arp request or gratuitous arp.
|
||||||
|
@param sw_if_index - interface to send
|
||||||
|
@param repeat - number of packets to send
|
||||||
|
@param interval - if more than 1 packet is sent, the delay between send
|
||||||
|
@param is_garp - is garp or arp request
|
||||||
|
*/
|
||||||
|
|
||||||
|
define arping
|
||||||
|
{
|
||||||
|
u32 client_index;
|
||||||
|
u32 context;
|
||||||
|
vl_api_address_t address;
|
||||||
|
vl_api_interface_index_t sw_if_index;
|
||||||
|
bool is_garp;
|
||||||
|
u32 repeat [default=1];
|
||||||
|
f64 interval [default=1.0];
|
||||||
|
option vat_help = "<address> <interface> [gratuitouss] [repeat <count>] [interval <sec>]";
|
||||||
|
};
|
||||||
|
|
||||||
|
/** \brief
|
||||||
|
@param context - sender context, to match reply w/ request
|
||||||
|
@param retval - return value for request
|
||||||
|
@reply_count - return value for reply count
|
||||||
|
*/
|
||||||
|
|
||||||
|
define arping_reply
|
||||||
|
{
|
||||||
|
u32 context;
|
||||||
|
i32 retval;
|
||||||
|
u32 reply_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Local Variables:
|
||||||
|
* eval: (c-set-style "gnu")
|
||||||
|
* End:
|
||||||
|
*/
|
797
src/plugins/arping/arping.c
Normal file
797
src/plugins/arping/arping.c
Normal file
File diff suppressed because it is too large
Load Diff
74
src/plugins/arping/arping.h
Normal file
74
src/plugins/arping/arping.h
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2021 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.
|
||||||
|
*/
|
||||||
|
#ifndef included_arping_arping_h
|
||||||
|
#define included_arping_arping_h
|
||||||
|
|
||||||
|
#include <vnet/ip/ip_types.h>
|
||||||
|
#include <vnet/ethernet/arp_packet.h>
|
||||||
|
|
||||||
|
#define ARPING_DEFAULT_INTERVAL 1.0
|
||||||
|
#define ARPING_DEFAULT_REPEAT 1
|
||||||
|
|
||||||
|
typedef struct arping6_ip6_reply_t
|
||||||
|
{
|
||||||
|
mac_address_t mac;
|
||||||
|
ip6_address_t ip6;
|
||||||
|
} arping6_ip6_reply_t;
|
||||||
|
|
||||||
|
typedef CLIB_PACKED (union arping46_reply_ {
|
||||||
|
ethernet_arp_ip4_over_ethernet_address_t from4;
|
||||||
|
arping6_ip6_reply_t from6;
|
||||||
|
}) arping46_reply_t;
|
||||||
|
|
||||||
|
typedef struct arping_intf_t
|
||||||
|
{
|
||||||
|
CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
|
||||||
|
f64 interval;
|
||||||
|
u32 repeat;
|
||||||
|
ip_address_t address;
|
||||||
|
|
||||||
|
arping46_reply_t recv;
|
||||||
|
u32 reply_count;
|
||||||
|
} arping_intf_t;
|
||||||
|
|
||||||
|
typedef struct arping_main_t
|
||||||
|
{
|
||||||
|
arping_intf_t *arping_interfaces;
|
||||||
|
arping_intf_t **interfaces;
|
||||||
|
u16 msg_id_base;
|
||||||
|
} arping_main_t;
|
||||||
|
|
||||||
|
typedef struct arping_args_t
|
||||||
|
{
|
||||||
|
ip_address_t address;
|
||||||
|
u32 sw_if_index;
|
||||||
|
u32 repeat;
|
||||||
|
f64 interval;
|
||||||
|
u8 is_garp;
|
||||||
|
u8 silence;
|
||||||
|
|
||||||
|
/* reply */
|
||||||
|
i32 rv;
|
||||||
|
u32 reply_count;
|
||||||
|
arping46_reply_t recv;
|
||||||
|
clib_error_t *error;
|
||||||
|
} arping_args_t;
|
||||||
|
|
||||||
|
extern arping_main_t arping_main;
|
||||||
|
|
||||||
|
extern clib_error_t *arping_plugin_api_hookup (vlib_main_t *vm);
|
||||||
|
extern void arping_run_command (vlib_main_t *vm, arping_args_t *args);
|
||||||
|
|
||||||
|
#endif /* included_arping_arping_h */
|
87
src/plugins/arping/arping_api.c
Normal file
87
src/plugins/arping/arping_api.c
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
*------------------------------------------------------------------
|
||||||
|
* Copyright (c) 2021 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 <vlib/vlib.h>
|
||||||
|
#include <vlib/unix/unix.h>
|
||||||
|
#include <vlib/pci/pci.h>
|
||||||
|
#include <vnet/ethernet/ethernet.h>
|
||||||
|
#include <vnet/format_fns.h>
|
||||||
|
#include <vnet/ip/ip_types_api.h>
|
||||||
|
|
||||||
|
#include <arping/arping.h>
|
||||||
|
|
||||||
|
#include <vlibapi/api.h>
|
||||||
|
#include <vlibmemory/api.h>
|
||||||
|
|
||||||
|
/* define message IDs */
|
||||||
|
#include <arping/arping.api_enum.h>
|
||||||
|
#include <arping/arping.api_types.h>
|
||||||
|
|
||||||
|
#include <vlibapi/api_helper_macros.h>
|
||||||
|
|
||||||
|
static void
|
||||||
|
vl_api_arping_t_handler (vl_api_arping_t *mp)
|
||||||
|
{
|
||||||
|
vlib_main_t *vm = vlib_get_main ();
|
||||||
|
arping_main_t *am = &arping_main;
|
||||||
|
vl_api_arping_reply_t *rmp;
|
||||||
|
arping_args_t args = { 0 };
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
if (mp->sw_if_index != ~0)
|
||||||
|
VALIDATE_SW_IF_INDEX (mp);
|
||||||
|
|
||||||
|
ip_address_decode2 (&mp->address, &args.address);
|
||||||
|
args.interval = clib_net_to_host_f64 (mp->interval);
|
||||||
|
args.repeat = ntohl (mp->repeat);
|
||||||
|
args.is_garp = mp->is_garp;
|
||||||
|
args.sw_if_index = ntohl (mp->sw_if_index);
|
||||||
|
args.silence = 1;
|
||||||
|
|
||||||
|
arping_run_command (vm, &args);
|
||||||
|
rv = args.rv;
|
||||||
|
|
||||||
|
BAD_SW_IF_INDEX_LABEL;
|
||||||
|
|
||||||
|
REPLY_MACRO2 (VL_API_ARPING_REPLY + am->msg_id_base,
|
||||||
|
({ rmp->reply_count = ntohl (args.reply_count); }));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set tup the API message handling tables */
|
||||||
|
#include <arping/arping.api.c>
|
||||||
|
clib_error_t *
|
||||||
|
arping_plugin_api_hookup (vlib_main_t *vm)
|
||||||
|
{
|
||||||
|
arping_main_t *am = &arping_main;
|
||||||
|
api_main_t *vam = vlibapi_get_main ();
|
||||||
|
|
||||||
|
/* ask for a correctly-sized block of API message decode slots */
|
||||||
|
am->msg_id_base = setup_message_id_table ();
|
||||||
|
|
||||||
|
/* Mark API as mp safe */
|
||||||
|
vam->is_mp_safe[am->msg_id_base + VL_API_ARPING] = 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fd.io coding-style-patch-verification: ON
|
||||||
|
*
|
||||||
|
* Local Variables:
|
||||||
|
* eval: (c-set-style "gnu")
|
||||||
|
* End:
|
||||||
|
*/
|
167
src/plugins/arping/arping_test.c
Normal file
167
src/plugins/arping/arping_test.c
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
/*
|
||||||
|
* arping VAT support
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 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 <inttypes.h>
|
||||||
|
|
||||||
|
#include <vat/vat.h>
|
||||||
|
#include <vlibapi/api.h>
|
||||||
|
#include <vlibmemory/api.h>
|
||||||
|
|
||||||
|
#include <vppinfra/error.h>
|
||||||
|
#include <arping/arping.h>
|
||||||
|
|
||||||
|
#define __plugin_msg_base arping_test_main.msg_id_base
|
||||||
|
#include <vlibapi/vat_helper_macros.h>
|
||||||
|
|
||||||
|
/* declare message IDs */
|
||||||
|
#include <vnet/format_fns.h>
|
||||||
|
#include <arping/arping.api_enum.h>
|
||||||
|
#include <arping/arping.api_types.h>
|
||||||
|
#include <vpp/api/vpe.api_types.h>
|
||||||
|
#include <vnet/ip/ip_types_api.h>
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
/* API message ID base */
|
||||||
|
u16 msg_id_base;
|
||||||
|
u32 ping_id;
|
||||||
|
vat_main_t *vat_main;
|
||||||
|
} arping_test_main_t;
|
||||||
|
|
||||||
|
arping_test_main_t arping_test_main;
|
||||||
|
|
||||||
|
/* arping request API */
|
||||||
|
static int
|
||||||
|
api_arping (vat_main_t *vam)
|
||||||
|
{
|
||||||
|
vl_api_arping_t *mp;
|
||||||
|
arping_args_t args = { 0 };
|
||||||
|
int ret;
|
||||||
|
unformat_input_t *input = vam->input;
|
||||||
|
vnet_main_t *vnm = vnet_get_main ();
|
||||||
|
f64 interval = ARPING_DEFAULT_INTERVAL;
|
||||||
|
vl_api_control_ping_t *mp_ping;
|
||||||
|
arping_test_main_t *atm = &arping_test_main;
|
||||||
|
|
||||||
|
args.repeat = ARPING_DEFAULT_REPEAT;
|
||||||
|
args.interval = ARPING_DEFAULT_INTERVAL;
|
||||||
|
args.sw_if_index = ~0;
|
||||||
|
|
||||||
|
if (unformat (input, "gratuitous"))
|
||||||
|
args.is_garp = 1;
|
||||||
|
|
||||||
|
if (unformat (input, "%U", unformat_ip4_address, &args.address.ip.ip4))
|
||||||
|
args.address.version = AF_IP4;
|
||||||
|
else if (unformat (input, "%U", unformat_ip6_address, &args.address.ip.ip6))
|
||||||
|
args.address.version = AF_IP6;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
errmsg ("expecting IP4/IP6 address `%U'. Usage: arping [gratuitous] "
|
||||||
|
"<addr> <intf> [repeat <count>] [interval <secs>]",
|
||||||
|
format_unformat_error, input);
|
||||||
|
return -99;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!unformat_user (input, unformat_vnet_sw_interface, vnm,
|
||||||
|
&args.sw_if_index))
|
||||||
|
{
|
||||||
|
errmsg ("unknown interface `%U'", format_unformat_error, input);
|
||||||
|
return -99;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* parse the rest of the parameters in a cycle */
|
||||||
|
while (!unformat_eof (input, NULL))
|
||||||
|
{
|
||||||
|
if (unformat (input, "interval"))
|
||||||
|
{
|
||||||
|
if (!unformat (input, "%f", &interval))
|
||||||
|
{
|
||||||
|
errmsg ("expecting interval (floating point number) got `%U'",
|
||||||
|
format_unformat_error, input);
|
||||||
|
return -99;
|
||||||
|
}
|
||||||
|
args.interval = interval;
|
||||||
|
}
|
||||||
|
else if (unformat (input, "repeat"))
|
||||||
|
{
|
||||||
|
if (!unformat (input, "%u", &args.repeat))
|
||||||
|
{
|
||||||
|
errmsg ("expecting repeat count but got `%U'",
|
||||||
|
format_unformat_error, input);
|
||||||
|
return -99;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
errmsg ("unknown input `%U'", format_unformat_error, input);
|
||||||
|
return -99;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
M (ARPING, mp);
|
||||||
|
|
||||||
|
mp->interval = clib_host_to_net_f64 (args.interval);
|
||||||
|
mp->repeat = clib_host_to_net_u32 (args.repeat);
|
||||||
|
mp->is_garp = args.is_garp;
|
||||||
|
mp->sw_if_index = clib_host_to_net_u32 (args.sw_if_index);
|
||||||
|
ip_address_encode2 (&args.address, &mp->address);
|
||||||
|
|
||||||
|
S (mp);
|
||||||
|
|
||||||
|
/* Use a control ping for synchronization */
|
||||||
|
if (!atm->ping_id)
|
||||||
|
atm->ping_id = vl_msg_api_get_msg_index ((u8 *) (VL_API_CONTROL_PING_CRC));
|
||||||
|
mp_ping = vl_msg_api_alloc_as_if_client (sizeof (*mp_ping));
|
||||||
|
mp_ping->_vl_msg_id = htons (atm->ping_id);
|
||||||
|
mp_ping->client_index = vam->my_client_index;
|
||||||
|
|
||||||
|
fformat (vam->ofp, "Sending ping id=%d\n", atm->ping_id);
|
||||||
|
|
||||||
|
vam->result_ready = 0;
|
||||||
|
S (mp_ping);
|
||||||
|
|
||||||
|
W (ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* arping-create reply handler */
|
||||||
|
static void
|
||||||
|
vl_api_arping_reply_t_handler (vl_api_arping_reply_t *mp)
|
||||||
|
{
|
||||||
|
vat_main_t *vam = arping_test_main.vat_main;
|
||||||
|
i32 retval = ntohl (mp->retval);
|
||||||
|
|
||||||
|
if (retval == 0)
|
||||||
|
{
|
||||||
|
fformat (vam->ofp, "arping request reply count = %d\n",
|
||||||
|
ntohl (mp->reply_count));
|
||||||
|
}
|
||||||
|
|
||||||
|
vam->retval = retval;
|
||||||
|
vam->result_ready = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <arping/arping.api_test.c>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fd.io coding-style-patch-verification: ON
|
||||||
|
*
|
||||||
|
* Local Variables:
|
||||||
|
* eval: (c-set-style "gnu")
|
||||||
|
* End:
|
||||||
|
*/
|
251
src/plugins/arping/test/test_arping.py
Normal file
251
src/plugins/arping/test/test_arping.py
Normal file
@ -0,0 +1,251 @@
|
|||||||
|
from scapy.layers.l2 import ARP
|
||||||
|
from scapy.layers.inet6 import ICMPv6ND_NS, ICMPv6ND_NA, IPv6
|
||||||
|
|
||||||
|
from framework import VppTestCase
|
||||||
|
|
||||||
|
""" TestArping is a subclass of VPPTestCase classes.
|
||||||
|
|
||||||
|
Basic test for sanity check of arping.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class TestArping(VppTestCase):
|
||||||
|
""" Arping Test Case """
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
super(TestArping, cls).setUpClass()
|
||||||
|
try:
|
||||||
|
cls.create_pg_interfaces(range(2))
|
||||||
|
cls.interfaces = list(cls.pg_interfaces)
|
||||||
|
|
||||||
|
for i in cls.interfaces:
|
||||||
|
i.admin_up()
|
||||||
|
i.config_ip4()
|
||||||
|
i.config_ip6()
|
||||||
|
i.disable_ipv6_ra()
|
||||||
|
i.resolve_arp()
|
||||||
|
i.resolve_ndp()
|
||||||
|
except Exception:
|
||||||
|
super(TestArping, cls).tearDownClass()
|
||||||
|
raise
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def tearDownClass(cls):
|
||||||
|
super(TestArping, cls).tearDownClass()
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
super(TestArping, self).tearDown()
|
||||||
|
|
||||||
|
def show_commands_at_teardown(self):
|
||||||
|
self.logger.info(self.vapi.cli("show hardware"))
|
||||||
|
|
||||||
|
def verify_arping_request(self, p, src, dst):
|
||||||
|
arp = p[ARP]
|
||||||
|
self.assertEqual(arp.hwtype, 0x0001)
|
||||||
|
self.assertEqual(arp.ptype, 0x0800)
|
||||||
|
self.assertEqual(arp.hwlen, 6)
|
||||||
|
self.assertEqual(arp.op, 1)
|
||||||
|
self.assertEqual(arp.psrc, src)
|
||||||
|
self.assertEqual(arp.pdst, dst)
|
||||||
|
|
||||||
|
def verify_arping_ip6_ns(self, p, src, dst):
|
||||||
|
icmpv6 = p[ICMPv6ND_NS]
|
||||||
|
self.assertEqual(icmpv6.type, 135)
|
||||||
|
self.assertEqual(icmpv6.tgt, dst)
|
||||||
|
ipv6 = p[IPv6]
|
||||||
|
self.assertEqual(src, ipv6.src)
|
||||||
|
|
||||||
|
def verify_arping_ip6_na(self, p, src, dst):
|
||||||
|
icmpv6 = p[ICMPv6ND_NA]
|
||||||
|
self.assertEqual(icmpv6.type, 136)
|
||||||
|
self.assertEqual(icmpv6.tgt, dst)
|
||||||
|
ipv6 = p[IPv6]
|
||||||
|
self.assertEqual(src, ipv6.src)
|
||||||
|
|
||||||
|
def test_arping_ip4_arp_request_cli(self):
|
||||||
|
""" arping IP4 arp request CLI test """
|
||||||
|
try:
|
||||||
|
self.pg_enable_capture(self.pg_interfaces)
|
||||||
|
self.pg_start()
|
||||||
|
remote_ip4 = self.pg1.remote_ip4
|
||||||
|
|
||||||
|
ping_cmd = "arping " + remote_ip4 + "pg1 repeat 5 interval 0.1"
|
||||||
|
ret = self.vapi.cli(ping_cmd)
|
||||||
|
self.logger.info(ret)
|
||||||
|
|
||||||
|
ping_cmd = "arping " + remote_ip4 + "pg1"
|
||||||
|
ret = self.vapi.cli(ping_cmd)
|
||||||
|
self.logger.info(ret)
|
||||||
|
|
||||||
|
out = self.pg1.get_capture(6)
|
||||||
|
for p in out:
|
||||||
|
self.verify_arping_request(p, self.pg1.local_ip4,
|
||||||
|
self.pg1.remote_ip4)
|
||||||
|
finally:
|
||||||
|
self.vapi.cli("show error")
|
||||||
|
|
||||||
|
def test_arping_ip4_garp_cli(self):
|
||||||
|
""" arping ip4 gratuitous arp CLI test """
|
||||||
|
try:
|
||||||
|
self.pg_enable_capture(self.pg_interfaces)
|
||||||
|
self.pg_start()
|
||||||
|
|
||||||
|
ping_cmd = ("arping gratuitous" + self.pg1.local_ip4 +
|
||||||
|
"pg1 repeat 5 interval 0.1")
|
||||||
|
ret = self.vapi.cli(ping_cmd)
|
||||||
|
self.logger.info(ret)
|
||||||
|
|
||||||
|
ping_cmd = "arping gratuitous" + self.pg1.local_ip4 + "pg1"
|
||||||
|
ret = self.vapi.cli(ping_cmd)
|
||||||
|
self.logger.info(ret)
|
||||||
|
|
||||||
|
out = self.pg1.get_capture(6)
|
||||||
|
for p in out:
|
||||||
|
self.verify_arping_request(p, self.pg1.local_ip4,
|
||||||
|
self.pg1.local_ip4)
|
||||||
|
finally:
|
||||||
|
self.vapi.cli("show error")
|
||||||
|
|
||||||
|
def test_arping_ip4_arp_request_api(self):
|
||||||
|
""" arping ip4 arp request API test """
|
||||||
|
try:
|
||||||
|
self.pg_enable_capture(self.pg_interfaces)
|
||||||
|
self.pg_start()
|
||||||
|
remote_ip4 = self.pg1.remote_ip4
|
||||||
|
|
||||||
|
ret = self.vapi.arping(address=remote_ip4,
|
||||||
|
sw_if_index=self.pg1.sw_if_index,
|
||||||
|
is_garp=0, repeat=5, interval=0.1)
|
||||||
|
self.logger.info(ret)
|
||||||
|
|
||||||
|
ret = self.vapi.arping(address=remote_ip4,
|
||||||
|
sw_if_index=self.pg1.sw_if_index,
|
||||||
|
is_garp=0)
|
||||||
|
self.logger.info(ret)
|
||||||
|
|
||||||
|
out = self.pg1.get_capture(6)
|
||||||
|
for p in out:
|
||||||
|
self.verify_arping_request(p, self.pg1.local_ip4,
|
||||||
|
self.pg1.remote_ip4)
|
||||||
|
finally:
|
||||||
|
self.vapi.cli("show error")
|
||||||
|
|
||||||
|
def test_arping_ip4_garp_api(self):
|
||||||
|
""" arping ip4 gratuitous arp API test """
|
||||||
|
try:
|
||||||
|
self.pg_enable_capture(self.pg_interfaces)
|
||||||
|
self.pg_start()
|
||||||
|
|
||||||
|
ret = self.vapi.arping(address=self.pg1.local_ip4,
|
||||||
|
sw_if_index=self.pg1.sw_if_index,
|
||||||
|
is_garp=1, repeat=5, interval=0.1)
|
||||||
|
self.logger.info(ret)
|
||||||
|
|
||||||
|
ret = self.vapi.arping(address=self.pg1.local_ip4,
|
||||||
|
sw_if_index=self.pg1.sw_if_index,
|
||||||
|
is_garp=1)
|
||||||
|
self.logger.info(ret)
|
||||||
|
|
||||||
|
out = self.pg1.get_capture(6)
|
||||||
|
for p in out:
|
||||||
|
self.verify_arping_request(p, self.pg1.local_ip4,
|
||||||
|
self.pg1.local_ip4)
|
||||||
|
finally:
|
||||||
|
self.vapi.cli("show error")
|
||||||
|
|
||||||
|
def test_arping_ip6_ns_cli(self):
|
||||||
|
""" arping IP6 neighbor solicitation CLI test """
|
||||||
|
try:
|
||||||
|
self.pg_enable_capture(self.pg_interfaces)
|
||||||
|
self.pg_start()
|
||||||
|
remote_ip6 = self.pg1.remote_ip6
|
||||||
|
|
||||||
|
ping_cmd = "arping " + remote_ip6 + "pg1 repeat 5 interval 0.1"
|
||||||
|
ret = self.vapi.cli(ping_cmd)
|
||||||
|
self.logger.info(ret)
|
||||||
|
|
||||||
|
ping_cmd = "arping " + remote_ip6 + "pg1"
|
||||||
|
ret = self.vapi.cli(ping_cmd)
|
||||||
|
self.logger.info(ret)
|
||||||
|
|
||||||
|
out = self.pg1.get_capture(6)
|
||||||
|
for p in out:
|
||||||
|
self.verify_arping_ip6_ns(p, self.pg1.local_ip6,
|
||||||
|
self.pg1.remote_ip6)
|
||||||
|
finally:
|
||||||
|
self.vapi.cli("show error")
|
||||||
|
|
||||||
|
def test_arping_ip6_ns_api(self):
|
||||||
|
""" arping ip6 neighbor solicitation API test """
|
||||||
|
try:
|
||||||
|
self.pg_enable_capture(self.pg_interfaces)
|
||||||
|
self.pg_start()
|
||||||
|
remote_ip6 = self.pg1.remote_ip6
|
||||||
|
|
||||||
|
ret = self.vapi.arping(address=remote_ip6,
|
||||||
|
sw_if_index=self.pg1.sw_if_index,
|
||||||
|
is_garp=0, repeat=5, interval=0.1)
|
||||||
|
self.logger.info(ret)
|
||||||
|
|
||||||
|
ret = self.vapi.arping(address=remote_ip6,
|
||||||
|
sw_if_index=self.pg1.sw_if_index,
|
||||||
|
is_garp=0)
|
||||||
|
self.logger.info(ret)
|
||||||
|
|
||||||
|
out = self.pg1.get_capture(6)
|
||||||
|
for p in out:
|
||||||
|
self.verify_arping_ip6_ns(p, self.pg1.local_ip6,
|
||||||
|
self.pg1.remote_ip6)
|
||||||
|
finally:
|
||||||
|
self.vapi.cli("show error")
|
||||||
|
|
||||||
|
def test_arping_ip6_na_cli(self):
|
||||||
|
""" arping ip6 neighbor advertisement CLI test """
|
||||||
|
try:
|
||||||
|
self.pg_enable_capture(self.pg_interfaces)
|
||||||
|
self.pg_start()
|
||||||
|
|
||||||
|
ping_cmd = ("arping gratuitous" + self.pg1.local_ip6 +
|
||||||
|
"pg1 repeat 5 interval 0.1")
|
||||||
|
ret = self.vapi.cli(ping_cmd)
|
||||||
|
self.logger.info(ret)
|
||||||
|
|
||||||
|
ping_cmd = "arping gratuitous" + self.pg1.local_ip6 + "pg1"
|
||||||
|
ret = self.vapi.cli(ping_cmd)
|
||||||
|
self.logger.info(ret)
|
||||||
|
|
||||||
|
out = self.pg1.get_capture(6)
|
||||||
|
for p in out:
|
||||||
|
self.verify_arping_ip6_na(p, self.pg1.local_ip6,
|
||||||
|
self.pg1.local_ip6)
|
||||||
|
finally:
|
||||||
|
self.vapi.cli("show error")
|
||||||
|
|
||||||
|
def test_arping_ip6_na_api(self):
|
||||||
|
""" arping ip6 neighbor advertisement API test """
|
||||||
|
try:
|
||||||
|
self.pg_enable_capture(self.pg_interfaces)
|
||||||
|
self.pg_start()
|
||||||
|
|
||||||
|
ret = self.vapi.arping(address=self.pg1.local_ip6,
|
||||||
|
sw_if_index=self.pg1.sw_if_index,
|
||||||
|
is_garp=1, repeat=5, interval=0.1)
|
||||||
|
self.logger.info(ret)
|
||||||
|
|
||||||
|
ret = self.vapi.arping(address=self.pg1.local_ip6,
|
||||||
|
sw_if_index=self.pg1.sw_if_index,
|
||||||
|
is_garp=1)
|
||||||
|
self.logger.info(ret)
|
||||||
|
|
||||||
|
out = self.pg1.get_capture(6)
|
||||||
|
for p in out:
|
||||||
|
self.verify_arping_ip6_na(p, self.pg1.local_ip6,
|
||||||
|
self.pg1.local_ip6)
|
||||||
|
finally:
|
||||||
|
self.vapi.cli("show error")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main(testRunner=VppTestRunner)
|
Reference in New Issue
Block a user