diff --git a/acl_loader/main.py b/acl_loader/main.py index ec885c4bd6..16a69b7311 100644 --- a/acl_loader/main.py +++ b/acl_loader/main.py @@ -730,16 +730,17 @@ def show_session(self, session_name): if val.get("type") == "SPAN": span_data.append([key, val.get("status", ""), val.get("dst_port", ""), - val.get("src_port", ""), val.get("direction", "").lower(),val.get("queue", ""), val.get("policer", "")]) + val.get("src_port", ""), val.get("direction", "").lower(), + val.get("queue", ""), val.get("policer", "")]) else: erspan_data.append([key, val.get("status", ""), val.get("src_ip", ""), - val.get("dst_ip", ""), val.get("gre_type", ""), val.get("dscp", ""), - val.get("ttl", ""), val.get("queue", ""), val.get("policer", ""), - val.get("monitor_port", ""), val.get("src_port", ""), val.get("direction", "").lower()]) + val.get("dst_ip", ""), val.get("gre_type", ""), val.get("dscp", ""), + val.get("ttl", ""), val.get("queue", ""), val.get("policer", ""), + val.get("monitor_port", ""), val.get("src_port", ""), val.get("direction", "").lower()]) - print 'ERSPAN Sessions' + print("ERSPAN Sessions") print(tabulate.tabulate(erspan_data, headers=erspan_header, tablefmt="simple", missingval="")) - print '\nSPAN Sessions' + print("\nSPAN Sessions") print(tabulate.tabulate(span_data, headers=span_header, tablefmt="simple", missingval="")) def show_policer(self, policer_name): diff --git a/config/main.py b/config/main.py index 28f15dadd5..931f364517 100755 --- a/config/main.py +++ b/config/main.py @@ -570,33 +570,42 @@ def is_ipaddress(val): return False return True -# -# Check if an interface_name is in a vlan -# def interface_is_in_vlan(vlan_member_table, interface_name): + """ Check if an interface is in a vlan """ + for _,v in vlan_member_table.keys(): + if v == interface_name: + return True + + return False - for k,v in vlan_member_table: +def interface_is_in_portchannel(portchannel_member_table, interface_name): + """ Check if an interface is part of portchannel """ + for _,v in portchannel_member_table.keys(): if v == interface_name: return True return False +def interface_is_router_port(interface_table, interface_name): + """ Check if an interface has router config """ + for entry in interface_table.keys(): + if (interface_name == entry[0]): + return True + + return False -# -# Check if port is already configured as mirror destination port -# def interface_is_mirror_dst_port(config_db, interface_name): + """ Check if port is already configured as mirror destination port """ mirror_table = config_db.get_table('MIRROR_SESSION') - for k,v in mirror_table.items(): + for _,v in mirror_table.items(): if 'dst_port' in v and v['dst_port'] == interface_name: return True return False -# -# Check if port is already configured with mirror config -# + def interface_has_mirror_config(mirror_table, interface_name): - for k,v in mirror_table.items(): + """ Check if port is already configured with mirror config """ + for _,v in mirror_table.items(): if 'src_port' in v and v['src_port'] == interface_name: return True if 'dst_port' in v and v['dst_port'] == interface_name: @@ -608,12 +617,15 @@ def interface_has_mirror_config(mirror_table, interface_name): # Check if SPAN mirror-session config is valid. # def validate_mirror_session_config(config_db, session_name, dst_port, src_port, direction): + """ Check if SPAN mirror-session config is valid """ if len(config_db.get_entry('MIRROR_SESSION', session_name)) != 0: click.echo("Error: {} already exists".format(session_name)) return False vlan_member_table = config_db.get_table('VLAN_MEMBER') mirror_table = config_db.get_table('MIRROR_SESSION') + portchannel_member_table = config_db.get_table('PORTCHANNEL_MEMBER') + interface_table = config_db.get_table('INTERFACE') if dst_port is not None: if interface_name_is_valid(dst_port) is False: @@ -628,6 +640,14 @@ def validate_mirror_session_config(config_db, session_name, dst_port, src_port, click.echo("Error: Destination Interface {} already has mirror config".format(dst_port)) return False + if interface_is_in_portchannel(portchannel_member_table, dst_port): + click.echo("Error: Destination Interface {} has portchannel config".format(dst_port)) + return False + + if interface_is_router_port(interface_table, dst_port): + click.echo("Error: Destination Interface {} is a L3 interface".format(dst_port)) + return False + if src_port is not None: for port in src_port.split(","): if interface_name_is_valid(port) is False: @@ -1072,6 +1092,8 @@ def portchannel_member(ctx): def add_portchannel_member(ctx, portchannel_name, port_name): """Add member to port channel""" db = ctx.obj['db'] + if interface_is_mirror_dst_port(db, port_name): + ctx.fail("{} is configured as mirror destination port".format(interface_name)) db.set_entry('PORTCHANNEL_MEMBER', (portchannel_name, port_name), {'NULL': 'NULL'}) @@ -1097,17 +1119,31 @@ def mirror_session(): # 'add' subgroup ('config mirror_session add ...') # -@mirror_session.group(cls=AbbreviationGroup, name='add') +@mirror_session.command('add') +@click.argument('session_name', metavar='', required=True) +@click.argument('src_ip', metavar='', required=True) +@click.argument('dst_ip', metavar='', required=True) +@click.argument('dscp', metavar='', required=True) +@click.argument('ttl', metavar='', required=True) +@click.argument('gre_type', metavar='[gre_type]', required=False) +@click.argument('queue', metavar='[queue]', required=False) +@click.option('--policer') +def add(session_name, src_ip, dst_ip, dscp, ttl, gre_type, queue, policer): + """ Add ERSPAN mirror session.(Legacy support) """ + add_erspan(session_name, src_ip, dst_ip, dscp, ttl, gre_type, queue, policer) + +@mirror_session.group(cls=AbbreviationGroup, name='erspan') @click.pass_context -def add(ctx): - """Add mirror_session""" +def erspan(ctx): + """ ERSPAN mirror_session """ pass + # # 'add' subcommand # -@add.command('erspan') +@erspan.command('add') @click.argument('session_name', metavar='', required=True) @click.argument('src_ip', metavar='', required=True) @click.argument('dst_ip', metavar='', required=True) @@ -1118,24 +1154,14 @@ def add(ctx): @click.argument('src_port', metavar='[src_port]', required=False) @click.argument('direction', metavar='[direction]', required=False) @click.option('--policer') -def erspan(session_name, src_ip, dst_ip, dscp, ttl, gre_type, queue, policer, src_port, direction): - """ - Add ERSPAN mirror session - """ - session_info = { - "type" : "ERSPAN", - "src_ip": src_ip, - "dst_ip": dst_ip, - "dscp": dscp, - "ttl": ttl - } +def add(session_name, src_ip, dst_ip, dscp, ttl, gre_type, queue, policer, src_port, direction): + """ Add ERSPAN mirror session """ + add_erspan(session_name, src_ip, dst_ip, dscp, ttl, gre_type, queue, policer, src_port, direction) +def mirror_common_init(session_info, policer, queue, src_port, direction): if policer is not None: session_info['policer'] = policer - if gre_type is not None: - session_info['gre_type'] = gre_type - if queue is not None: session_info['queue'] = queue @@ -1152,6 +1178,21 @@ def erspan(session_name, src_ip, dst_ip, dscp, ttl, gre_type, queue, policer, sr if direction is not None: session_info['direction'] = direction.upper() + return session_info + +def add_erspan(session_name, src_ip, dst_ip, dscp, ttl, gre_type, queue, policer, src_port=None, direction=None): + session_info = { + "type" : "ERSPAN", + "src_ip": src_ip, + "dst_ip": dst_ip, + "dscp": dscp, + "ttl": ttl + } + + if gre_type is not None: + session_info['gre_type'] = gre_type + + session_info = mirror_common_init(session_info, policer, queue, src_port, direction) """ For multi-npu platforms we need to program all front asic namespaces @@ -1172,46 +1213,36 @@ def erspan(session_name, src_ip, dst_ip, dscp, ttl, gre_type, queue, policer, sr return per_npu_configdb[front_asic_namespaces].set_entry("MIRROR_SESSION", session_name, session_info) -@add.command('span') +@mirror_session.group(cls=AbbreviationGroup, name='span') +@click.pass_context +def span(ctx): + """ SPAN mirror session """ + pass + +@span.command('add') @click.argument('session_name', metavar='', required=True) @click.argument('dst_port', metavar='', required=True) @click.argument('src_port', metavar='[src_port]', required=False) @click.argument('direction', metavar='[direction]', required=False) @click.argument('queue', metavar='[queue]', required=False) @click.option('--policer') -def span(session_name, dst_port, src_port, direction, queue, policer): - """ - Add port mirror session - """ +def add(session_name, dst_port, src_port, direction, queue, policer): + """ Add SPAN mirror session """ + add_span(session_name, dst_port, src_port, direction, queue, policer) + +def add_span(session_name, dst_port, src_port, direction, queue, policer): if get_interface_naming_mode() == "alias": dst_port = interface_alias_to_name(dst_port) if dst_port is None: click.echo("Error: Destination Interface {} is invalid".format(dst_port)) return - if src_port is not None: - src_port_list = [] - for port in src_port.split(","): - src_port_list.append(interface_alias_to_name(port)) - src_port=",".join(src_port_list) session_info = { "type" : "SPAN", "dst_port": dst_port, } - if src_port is not None: - session_info['src_port'] = src_port - if direction is None: - direction = "both" - - if direction is not None: - session_info['direction'] = direction.upper() - - if policer is not None: - session_info['policer'] = policer - - if queue is not None: - session_info['queue'] = queue + session_info = mirror_common_init(session_info, policer, queue, src_port, direction) """ For multi-npu platforms we need to program all front asic namespaces @@ -1232,12 +1263,11 @@ def span(session_name, dst_port, src_port, direction, queue, policer): return per_npu_configdb[front_asic_namespaces].set_entry("MIRROR_SESSION", session_name, session_info) + @mirror_session.command() @click.argument('session_name', metavar='', required=True) def remove(session_name): - """ - Delete mirror session - """ + """ Delete mirror session """ """ For multi-npu platforms we need to program all front asic namespaces @@ -1253,6 +1283,7 @@ def remove(session_name): per_npu_configdb[front_asic_namespaces] = ConfigDBConnector(use_unix_socket_path=True, namespace=front_asic_namespaces) per_npu_configdb[front_asic_namespaces].connect() per_npu_configdb[front_asic_namespaces].set_entry("MIRROR_SESSION", session_name, None) + # # 'pfcwd' group ('config pfcwd ...') # diff --git a/doc/Command-Reference.md b/doc/Command-Reference.md index fc11a7693b..c552616f8e 100644 --- a/doc/Command-Reference.md +++ b/doc/Command-Reference.md @@ -3798,19 +3798,32 @@ While adding a new ERSPAN session, users need to configure the following fields - Usage: ``` - config mirror_session add erspan [gre_type] [queue] [policer ] [source-port-list] [direction] + config mirror_session erspan add [gre_type] [queue] [policer ] [source-port-list] [direction] + ``` + + The following command is also supported to be backward compatible. + This command will be deprecated in future releases. + ``` + config mirror_session add [gre_type] [queue] ``` - Example: ``` - root@T1-2:~# config mirror_session add erspan mrr_abcd 1.2.3.4 20.21.22.23 8 100 0x6558 0 + root@T1-2:~# config mirror_session add mrr_legacy 1.2.3.4 20.21.22.23 8 100 0x6558 0 + root@T1-2:~# show mirror_session + Name Status SRC IP DST IP GRE DSCP TTL Queue Policer Monitor Port SRC Port Direction + --------- -------- -------- ----------- ------ ------ ----- ------- --------- -------------- ---------- ----------- + mrr_legacy inactive 1.2.3.4 20.21.22.23 0x6558 8 100 0 + + + root@T1-2:~# config mirror_session erspan add mrr_abcd 1.2.3.4 20.21.22.23 8 100 0x6558 0 root@T1-2:~# show mirror_session Name Status SRC IP DST IP GRE DSCP TTL Queue Policer Monitor Port SRC Port Direction --------- -------- -------- ----------- ------ ------ ----- ------- --------- -------------- ---------- ----------- mrr_abcd inactive 1.2.3.4 20.21.22.23 0x6558 8 100 0 root@T1-2:~# - root@T1-2:~# config mirror_session add erspan mrr_port 1.2.3.4 20.21.22.23 8 100 0x6558 0 Ethernet0 both + root@T1-2:~# config mirror_session erspan add mrr_port 1.2.3.4 20.21.22.23 8 100 0x6558 0 Ethernet0 root@T1-2:~# show mirror_session Name Status SRC IP DST IP GRE DSCP TTL Queue Policer Monitor Port SRC Port Direction --------- -------- -------- ----------- ------ ------ ----- ------- --------- -------------- ---------- ----------- @@ -3827,17 +3840,18 @@ While adding a new SPAN session, users need to configure the following fields th - Usage: ``` - config mirror_session add span [source-port-list] [direction] [queue] [policer ] + config mirror_session span add [source-port-list] [direction] [queue] [policer ] ``` - Example: ``` - root@T1-2:~# config mirror_session add span port0 Ethernet0 Ethernet4,PortChannel001,Ethernet8 both + root@T1-2:~# config mirror_session span add port0 Ethernet0 Ethernet4,PortChannel001,Ethernet8 root@T1-2:~# show mirror_session Name Status DST Port SRC Port Direction ------ -------- ---------- --------------------------------- ----------- port0 active Ethernet0 Ethernet4,PortChannel10,Ethernet8 both root@T1-2:~# + ``` Go Back To [Beginning of the document](#) or [Beginning of this section](#mirroring)