Hi Hanoh,
thanks alot. This was fun. Think I got it working:
// enum for m_service_mask
enum service_filter {
SERVICE_OFF = 0,
NO_TCP_UDP = 1,
BGP = 1 << 1,
DHCP = 1 << 2, /* both for v4 and v6 */
TRANSPORT = 1 << 3, /* TCP & UDP with source (port& 0xff00 == 0xff00) generated by EMU */
MDNS = 1 << 4, /* mDNS - multicast DNS - EMU */
BFD = 1 << 5 /* all BFD ports */ #### Added BFD as 6th bit (32) };
Some v.3.05 testing on i40e SRIOV - """./t-rex-64 -i -c 2 --software --bird-server"""
c.set_service_mode(ports = [0], enabled = False, filtered = True, mask = 1)Works as expected - OSPF comes up but BFD stays Down:bird> show pro
Name Proto Table State Since Info
device1 Device --- up 11:20:51.049
my_bfd1 BFD --- up 11:20:51.049
my_ospfv4 OSPF master4 up 11:20:51.049 Running
my_ospfv6 OSPF master6 up 11:20:51.049 Running
bird_cfg_routes Static master4 up 11:20:51.049
bird> show bfd session
my_bfd1:
IP address Interface State Since Interval Timeout
fe80::250:56ff:fe30:309 bird-0-2-L Down 11:31:33.454 1.000 0.000
### IPv6 BFD Down as filer is now only for OSPF172.80.39.50 bird-0-2-L Down 11:31:21.625 1.000 0.000
### IPv4 BFD Down as filer is now only for OSPFc.set_service_mode(ports = [0], enabled = False, filtered = True, mask = 32) Allows BFD ports 3784, 3784 & 4784Not sure why OSPFv3 (IPv6) get OSPF connected but might be due to IPv6 mcast different from IPv4 somehow. Looks probably kind of expected.bird> show pro
Name Proto Table State Since Info
device1 Device --- up 11:20:51.049
my_bfd1 BFD --- up 11:20:51.049
my_ospfv4 OSPF master4 up 11:20:51.049 Alone
my_ospfv6 OSPF master6 up 11:20:51.049 Running
bird_cfg_routes Static master4 up 11:20:51.049
bird> show bfd session
my_bfd1:
IP address Interface State Since Interval Timeout
fe80::250:56ff:fe30:309 bird-0-3-L Up 11:36:54.391 1.000 3.000
172.80.39.50 bird-0-3-L Init 11:37:12.577 1.000 3.000
bird>
bird> show ospf neig
my_ospfv4:
Router ID Pri State DTime Interface Router IP
172.80.39.50 1 ExStart/BDR 38.584 bird-0-3-L 172.80.39.50
my_ospfv6:
Router ID Pri State DTime Interface Router IP
172.80.39.50 1 Full/DR 37.851 bird-0-3-L fe80::250:56ff:fe30:309
bird>
c.set_service_mode(ports = [0], enabled = False, filtered = True, mask = 33) ### This mask is for OSPF with BFDWith this filter all works as expected:[root@trex-intel-trex-bfd-1-1 bird]# ./birdcl -s /tmp/trex-bird/bird.ctl
BIRD 2.0.8 ready.
bird> show pro
Name Proto Table State Since Info
device1 Device --- up 11:20:51.049
my_bfd1 BFD --- up 11:20:51.049
my_ospfv4 OSPF master4 up 11:20:51.049 Running
my_ospfv6 OSPF master6 up 11:20:51.049 Running
bird_cfg_routes Static master4 up 11:20:51.049
bird> show ospf neig
my_ospfv4:
Router ID Pri State DTime Interface Router IP
172.80.39.50 1 Full/DR 35.613 bird-0-4-L 172.80.39.50
my_ospfv6:
Router ID Pri State DTime Interface Router IP
172.80.39.50 1 Full/DR 37.581 bird-0-4-L fe80::250:56ff:fe30:309
bird> show bfd session
my_bfd1:
IP address Interface State Since Interval Timeout
172.80.39.50 bird-0-4-L Up 11:49:02.041 1.000 3.000
fe80::250:56ff:fe30:309 bird-0-4-L Up 11:49:04.266 1.000 3.000
bird>
Added stuff in following files (not sure that would be enough for all cases but worked for my purpose):
src/stx/common/trex_port.h
src/common/Network/Packet/TcpHeader.h ### Even if UDP ports i put it here as DHCP (also UDP) was in same
src/44bsd/flow_table.cpp
src/stx/stl/trex_stl_dp_core.cpp
scripts/automation/trex_control_plane/interactive/trex/common/trex_client.py
scripts/automation/trex_control_plane/interactive/trex/utils/parsing_opts.py
Below is what was added:
// enum for m_service_mask
enum service_filter {
SERVICE_OFF = 0,
NO_TCP_UDP = 1,
BGP = 1 << 1,
DHCP = 1 << 2, /* both for v4 and v6 */
TRANSPORT = 1 << 3, /* TCP & UDP with source (port& 0xff00 == 0xff00) generated by EMU */
MDNS = 1 << 4, /* mDNS - multicast DNS - EMU */
BFD = 1 << 5 /* all BFD ports */
};
src/common/Network/Packet/TcpHeader.h
#define BGP_PORT 179
#define DHCPv4_PORT 67
#define DHCPv6_PORT 546
#define MDNS_PORT 5353
#define BFDc_PORT 3784
#define BFDe_PORT 3785
#define mBFDc_PORT 4784
vi ./src/44bsd/flow_table.cpp
void CFlowTable::check_service_filter(CSimplePacketParser & parser, tcp_rx_pkt_action_t & action) {
if ( (get_astf_object()->get_state() == AstfProfileState::STATE_IDLE) && (m_service_status == SERVICE_ON) ) {
action = tREDIRECT_RX_CORE;
return;
}
if ( m_service_status == SERVICE_ON ){
action = tREDIRECT_RX_CORE;
return;
}
if (m_service_filtered_mask & TrexPort::BGP) {
if ( parser.m_protocol == IPPROTO_TCP ) {
TCPHeader *l4_header = (TCPHeader *)parser.m_l4;
uint16_t src_port = l4_header->getSourcePort();
uint16_t dst_port = l4_header->getDestPort();
if ( src_port == BGP_PORT || dst_port == BGP_PORT ) {
action = tREDIRECT_RX_CORE;
return;
}
}
}
if (m_service_filtered_mask & TrexPort::DHCP) {
if ( parser.m_protocol == IPPROTO_UDP ) {
UDPHeader *l4_header = (UDPHeader *)parser.m_l4;
uint16_t src_port = l4_header->getSourcePort();
uint16_t dst_port = l4_header->getDestPort();
if ( (( src_port == DHCPv4_PORT || dst_port == DHCPv4_PORT )) ||
(( src_port == DHCPv6_PORT || dst_port == DHCPv6_PORT ))) {
action = tREDIRECT_RX_CORE;
return;
}
}
}
if (m_service_filtered_mask & TrexPort::BFD) {
if ( parser.m_protocol == IPPROTO_UDP ) {
UDPHeader *l4_header = (UDPHeader *)parser.m_l4;
uint16_t src_port = l4_header->getSourcePort();
uint16_t dst_port = l4_header->getDestPort();
if ( (( src_port == BFDc_PORT || dst_port == BFDc_PORT )) ||
(( src_port == BFDe_PORT || dst_port == BFDe_PORT )) ||
(( src_port == mBFDc_PORT || dst_port == mBFDc_PORT ))) {
action = tREDIRECT_RX_CORE;
return;
}
}
}
if ( (m_service_filtered_mask & TrexPort::TRANSPORT) &&
((parser.m_protocol == IPPROTO_UDP) || (parser.m_protocol == IPPROTO_TCP)) ) {
UDPHeader *l4_header = (UDPHeader *)parser.m_l4;
uint16_t src_port = l4_header->getSourcePort();
uint16_t dst_port = l4_header->getDestPort();
if ( (dst_port & 0xff00) == 0xff00 || (src_port & 0xff00) == 0xff00 ) {
action = tREDIRECT_RX_CORE;
return;
}
}
vi ./src/stx/stl/trex_stl_dp_core.cpp
/* return true if packet passed through service filter */
COLD_FUNC bool TrexStatelessDpCore::check_service_filter(bool &drop) {
uint8_t proto = m_parser->get_protocol();
// BGP check
if ( (m_service_mask & TrexPort::BGP) && (proto == IPPROTO_TCP) ) {
TCPHeader *l4_header = (TCPHeader *)m_parser->get_l4();
uint16_t src_port = l4_header->getSourcePort();
uint16_t dst_port = l4_header->getDestPort();
if ( src_port == BGP_PORT || dst_port == BGP_PORT ) {
drop = false;
return true;
}
}
if ( (m_service_mask & TrexPort::DHCP) && (proto == IPPROTO_UDP) ) {
UDPHeader *l4_header = (UDPHeader *)m_parser->get_l4();
uint16_t src_port = l4_header->getSourcePort();
uint16_t dst_port = l4_header->getDestPort();
if ( (( src_port == DHCPv4_PORT || dst_port == DHCPv4_PORT )) ||
(( src_port == DHCPv6_PORT || dst_port == DHCPv6_PORT ))) {
drop = false;
return true;
}
}
if ( (m_service_mask & TrexPort::BFD) && (proto == IPPROTO_UDP) ) {
UDPHeader *l4_header = (UDPHeader *)m_parser->get_l4();
uint16_t src_port = l4_header->getSourcePort();
uint16_t dst_port = l4_header->getDestPort();
if ( (( src_port == BFDc_PORT || dst_port == BFDc_PORT )) ||
(( src_port == BFDe_PORT || dst_port == BFDe_PORT )) ||
(( src_port == mBFDc_PORT || dst_port == mBFDc_PORT ))) {
drop = false;
return true;
}
}
if ( (m_service_mask & TrexPort::TRANSPORT) && ((proto == IPPROTO_UDP)
|| (proto == IPPROTO_TCP)) ) {
UDPHeader *l4_header = (UDPHeader *)m_parser->get_l4();
uint16_t src_port = l4_header->getSourcePort();
uint16_t dst_port = l4_header->getDestPort();
if ( (dst_port&0xff00) == 0xff00 || (src_port&0xff00) == 0xff00 ) {
drop = false;
return true;
}
}
vi scripts/automation/trex_control_plane/interactive/trex/common/trex_client.py
## Filtered Service Mode Mask ##
## IMPORTANT - UPDATE ALSO in set_service_mode() docstring! ##
NO_MASK = 0
NO_TCP_UDP_MASK = 1
BGP_MASK = 2
DHCP_MASK = 4
TRANSPORT_MASK = 8
MDNS_MASK = 16
BFD_MASK = 32
ALL_MASK = 255 # all bits are on
.
.
.
def set_service_mode_base (self, ports = None, enabled = True, filtered = False, mask = None):
"""
Set service mode for port(s)
In service mode ports will respond to ARP, PING and etc. "enable" and "filtered" are mutual exclusive,
choose 1 of them or none
:parameters:
ports: list
For which ports to configure service mode on/off
enabled: bool
True for activating service mode, False for disabling. Mutual exclusive with "filtered"
filtered: bool
True for activating service filtered mode, False for disabling. Mutual exclusive with "enabled"
mask: int
Mask to apply on each port in ports while filtered mode is on. Only packets that are correspond
to the port mask will be transferred.
Masks flags:
NO_MASK = 0
NO_TCP_UDP_MASK = 1
BGP_MASK = 2
DHCP_MASK = 4
TRANSPORT = 8
MDNS = 16
BFD_MASK = 32
ALL_MASK = 255
.
.
.
def _get_service_params(self, opts):
"""
Common function, creates 3 arguments for set_service_mode
:parameters:
opts: argparse
The result of: parser.parse_args(line.split()).
:return:
3 arguments: enable, filtered & mask to use in set_service_mode
"""
filtered = opts.allow_no_tcp_udp or opts.allow_bgp or opts.allow_all or opts.allow_emu or opts.allow_dhcp or opts.allow_transport or opts.allow_bfd
mask = 0
if filtered:
if opts.allow_dhcp:
mask |= DHCP_MASK
if opts.allow_mdns:
mask |= MDNS_MASK
if opts.allow_emu:
mask |= ( DHCP_MASK | MDNS_MASK | NO_TCP_UDP_MASK | TRANSPORT_MASK )
if opts.allow_all:
mask = ALL_MASK
if opts.allow_bgp:
mask |= BGP_MASK
if opts.allow_no_tcp_udp:
mask |= NO_TCP_UDP_MASK
if opts.allow_transport:
mask |= TRANSPORT_MASK
if opts.allow_bfd:
mask |= BFD_MASK
else:
mask = None
enabled = False if filtered else opts.enabled
return enabled, filtered, mask
scripts/automation/trex_control_plane/interactive/trex/utils/parsing_opts.py
SERVICE_BGP_FILTERED = ArgumentPack(
['--bgp'],
{'action': 'store_true',
'default': False,
'dest': 'allow_bgp',
'help': 'filter mode with bgp packets forward to rx'})
SERVICE_BFD_FILTERED = ArgumentPack(
['--bfd'],
{'action': 'store_true',
'default': False,
'dest': 'allow_bfd',
'help': 'filter mode with bfd packets forward to rx'})
.
.
.
SERVICE_GROUP = ArgumentGroup(
NON_MUTEX,
[
SERVICE_BGP_FILTERED,
SERVICE_BFD_FILTERED,
SERVICE_DHCP_FILTERED,
SERVICE_MDNS_FILTERED,
SERVICE_EMU_FILTERED,
SERVICE_TRAN_FILTERED,
SERVICE_NO_TCP_UDP_FILTERED,
SERVICE_ALL_FILTERED,
SERVICE_OFF
],{})
Thanks//Håkan