|
20 | 20 | from portconfig import get_child_ports
|
21 | 21 | from socket import AF_INET, AF_INET6
|
22 | 22 | from sonic_py_common import device_info, multi_asic
|
23 |
| -from sonic_py_common.interface import get_interface_table_name, get_port_table_name |
| 23 | +from sonic_py_common.interface import get_interface_table_name, get_port_table_name, intf_get_longname |
24 | 24 | from utilities_common import util_base
|
25 | 25 | from swsscommon.swsscommon import SonicV2Connector, ConfigDBConnector
|
26 | 26 | from utilities_common.db import Db
|
@@ -5846,6 +5846,125 @@ def smoothing_interval(interval, rates_type):
|
5846 | 5846 | for plugin in helper.load_plugins(plugins):
|
5847 | 5847 | helper.register_plugin(plugin, config)
|
5848 | 5848 |
|
| 5849 | +# |
| 5850 | +# 'subinterface' group ('config subinterface ...') |
| 5851 | +# |
| 5852 | +@config.group() |
| 5853 | +@click.pass_context |
| 5854 | +@click.option('-s', '--redis-unix-socket-path', help='unix socket path for redis connection') |
| 5855 | +def subinterface(ctx, redis_unix_socket_path): |
| 5856 | + """subinterface-related configuration tasks""" |
| 5857 | + kwargs = {} |
| 5858 | + if redis_unix_socket_path: |
| 5859 | + kwargs['unix_socket_path'] = redis_unix_socket_path |
| 5860 | + config_db = ConfigDBConnector(**kwargs) |
| 5861 | + config_db.connect(wait_for_init=False) |
| 5862 | + ctx.obj = {'db': config_db} |
| 5863 | + pass |
| 5864 | + |
| 5865 | +def subintf_vlan_check(config_db, parent_intf, vlan): |
| 5866 | + subintf_db = config_db.get_table('VLAN_SUB_INTERFACE') |
| 5867 | + subintf_names = [k for k in subintf_db if type(k) != tuple] |
| 5868 | + for subintf in subintf_names: |
| 5869 | + sub_intf_sep_idx = subintf.find(VLAN_SUB_INTERFACE_SEPARATOR) |
| 5870 | + if sub_intf_sep_idx == -1: |
| 5871 | + continue |
| 5872 | + if parent_intf == subintf[:sub_intf_sep_idx]: |
| 5873 | + if 'vlan' in subintf_db[subintf]: |
| 5874 | + if str(vlan) == subintf_db[subintf]['vlan']: |
| 5875 | + return True |
| 5876 | + else: |
| 5877 | + vlan_id = subintf[sub_intf_sep_idx + 1:] |
| 5878 | + if str(vlan) == vlan_id: |
| 5879 | + return True |
| 5880 | + return False |
| 5881 | + |
| 5882 | +@subinterface.command('add') |
| 5883 | +@click.argument('subinterface_name', metavar='<subinterface_name>', required=True) |
| 5884 | +@click.argument('vid', metavar='<vid>', required=False, type=click.IntRange(1,4094)) |
| 5885 | +@click.pass_context |
| 5886 | +def add_subinterface(ctx, subinterface_name, vid): |
| 5887 | + sub_intf_sep_idx = subinterface_name.find(VLAN_SUB_INTERFACE_SEPARATOR) |
| 5888 | + if sub_intf_sep_idx == -1: |
| 5889 | + ctx.fail("{} is invalid vlan subinterface".format(subinterface_name)) |
| 5890 | + |
| 5891 | + interface_alias = subinterface_name[:sub_intf_sep_idx] |
| 5892 | + vlan_id = subinterface_name[sub_intf_sep_idx + 1:] |
| 5893 | + if interface_alias is None: |
| 5894 | + ctx.fail("{} invalid subinterface".format(interface_alias)) |
| 5895 | + |
| 5896 | + if interface_alias.startswith("Po") is True: |
| 5897 | + intf_table_name = CFG_PORTCHANNEL_PREFIX |
| 5898 | + elif interface_alias.startswith("Eth") is True: |
| 5899 | + intf_table_name = 'PORT' |
| 5900 | + |
| 5901 | + config_db = ctx.obj['db'] |
| 5902 | + port_dict = config_db.get_table(intf_table_name) |
| 5903 | + if interface_alias is not None: |
| 5904 | + if not port_dict: |
| 5905 | + ctx.fail("{} parent interface not found. {} table none".format(interface_alias, intf_table_name)) |
| 5906 | + if intf_get_longname(interface_alias) not in port_dict.keys(): |
| 5907 | + ctx.fail("{} parent interface not found".format(subinterface_name)) |
| 5908 | + |
| 5909 | + # Validate if parent is portchannel member |
| 5910 | + portchannel_member_table = config_db.get_table('PORTCHANNEL_MEMBER') |
| 5911 | + if interface_is_in_portchannel(portchannel_member_table, interface_alias): |
| 5912 | + ctx.fail("{} is configured as a member of portchannel. Cannot configure subinterface" |
| 5913 | + .format(interface_alias)) |
| 5914 | + |
| 5915 | + # Validate if parent is vlan member |
| 5916 | + vlan_member_table = config_db.get_table('VLAN_MEMBER') |
| 5917 | + if interface_is_in_vlan(vlan_member_table, interface_alias): |
| 5918 | + ctx.fail("{} is configured as a member of vlan. Cannot configure subinterface" |
| 5919 | + .format(interface_alias)) |
| 5920 | + |
| 5921 | + sub_intfs = [k for k,v in config_db.get_table('VLAN_SUB_INTERFACE').items() if type(k) != tuple] |
| 5922 | + if subinterface_name in sub_intfs: |
| 5923 | + ctx.fail("{} already exists".format(subinterface_name)) |
| 5924 | + |
| 5925 | + subintf_dict = {} |
| 5926 | + if vid is not None: |
| 5927 | + subintf_dict.update({"vlan" : vid}) |
| 5928 | + |
| 5929 | + if subintf_vlan_check(config_db, intf_get_longname(interface_alias), vid) is True: |
| 5930 | + ctx.fail("Vlan {} encap already configured on other subinterface on {}".format(vid, interface_alias)) |
| 5931 | + |
| 5932 | + subintf_dict.update({"admin_status" : "up"}) |
| 5933 | + config_db.set_entry('VLAN_SUB_INTERFACE', subinterface_name, subintf_dict) |
| 5934 | + |
| 5935 | +@subinterface.command('del') |
| 5936 | +@click.argument('subinterface_name', metavar='<subinterface_name>', required=True) |
| 5937 | +@click.pass_context |
| 5938 | +def del_subinterface(ctx, subinterface_name): |
| 5939 | + sub_intf_sep_idx = subinterface_name.find(VLAN_SUB_INTERFACE_SEPARATOR) |
| 5940 | + if sub_intf_sep_idx == -1: |
| 5941 | + ctx.fail("{} is invalid vlan subinterface".format(subinterface_name)) |
| 5942 | + |
| 5943 | + config_db = ctx.obj['db'] |
| 5944 | + #subinterface_name = subintf_get_shortname(subinterface_name) |
| 5945 | + if interface_name_is_valid(config_db, subinterface_name) is False: |
| 5946 | + ctx.fail("{} is invalid ".format(subinterface_name)) |
| 5947 | + |
| 5948 | + subintf_config_db = config_db.get_table('VLAN_SUB_INTERFACE') |
| 5949 | + sub_intfs = [k for k,v in subintf_config_db.items() if type(k) != tuple] |
| 5950 | + if subinterface_name not in sub_intfs: |
| 5951 | + ctx.fail("{} does not exists".format(subinterface_name)) |
| 5952 | + |
| 5953 | + ips = {} |
| 5954 | + ips = [ k[1] for k in config_db.get_table('VLAN_SUB_INTERFACE') if type(k) == tuple and k[0] == subinterface_name ] |
| 5955 | + for ip in ips: |
| 5956 | + try: |
| 5957 | + ipaddress.ip_network(ip, strict=False) |
| 5958 | + config_db.set_entry('VLAN_SUB_INTERFACE', (subinterface_name, ip), None) |
| 5959 | + except ValueError: |
| 5960 | + ctx.fail("Invalid ip {} found on interface {}".format(ip, subinterface_name)) |
| 5961 | + |
| 5962 | + subintf_config_db = config_db.get_table('INTERFACE') |
| 5963 | + ips = [ k[1] for k in subintf_config_db if type(k) == tuple and k[0] == subinterface_name ] |
| 5964 | + for ip in ips: |
| 5965 | + config_db.set_entry('INTERFACE', (subinterface_name, ip), None) |
| 5966 | + |
| 5967 | + config_db.set_entry('VLAN_SUB_INTERFACE', subinterface_name, None) |
5849 | 5968 |
|
5850 | 5969 | if __name__ == '__main__':
|
5851 | 5970 | config()
|
0 commit comments