|
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, get_intf_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
|
@@ -5971,6 +5971,123 @@ def smoothing_interval(interval, rates_type):
|
5971 | 5971 | helper = util_base.UtilHelper()
|
5972 | 5972 | helper.load_and_register_plugins(plugins, config)
|
5973 | 5973 |
|
| 5974 | +# |
| 5975 | +# 'subinterface' group ('config subinterface ...') |
| 5976 | +# |
| 5977 | +@config.group() |
| 5978 | +@click.pass_context |
| 5979 | +@click.option('-s', '--redis-unix-socket-path', help='unix socket path for redis connection') |
| 5980 | +def subinterface(ctx, redis_unix_socket_path): |
| 5981 | + """subinterface-related configuration tasks""" |
| 5982 | + kwargs = {} |
| 5983 | + if redis_unix_socket_path: |
| 5984 | + kwargs['unix_socket_path'] = redis_unix_socket_path |
| 5985 | + config_db = ConfigDBConnector(**kwargs) |
| 5986 | + config_db.connect(wait_for_init=False) |
| 5987 | + ctx.obj = {'db': config_db} |
| 5988 | + |
| 5989 | +def subintf_vlan_check(config_db, parent_intf, vlan): |
| 5990 | + subintf_db = config_db.get_table('VLAN_SUB_INTERFACE') |
| 5991 | + subintf_names = [k for k in subintf_db if type(k) != tuple] |
| 5992 | + for subintf in subintf_names: |
| 5993 | + sub_intf_sep_idx = subintf.find(VLAN_SUB_INTERFACE_SEPARATOR) |
| 5994 | + if sub_intf_sep_idx == -1: |
| 5995 | + continue |
| 5996 | + if parent_intf == subintf[:sub_intf_sep_idx]: |
| 5997 | + if 'vlan' in subintf_db[subintf]: |
| 5998 | + if str(vlan) == subintf_db[subintf]['vlan']: |
| 5999 | + return True |
| 6000 | + else: |
| 6001 | + vlan_id = subintf[sub_intf_sep_idx + 1:] |
| 6002 | + if str(vlan) == vlan_id: |
| 6003 | + return True |
| 6004 | + return False |
| 6005 | + |
| 6006 | +@subinterface.command('add') |
| 6007 | +@click.argument('subinterface_name', metavar='<subinterface_name>', required=True) |
| 6008 | +@click.argument('vid', metavar='<vid>', required=False, type=click.IntRange(1,4094)) |
| 6009 | +@click.pass_context |
| 6010 | +def add_subinterface(ctx, subinterface_name, vid): |
| 6011 | + sub_intf_sep_idx = subinterface_name.find(VLAN_SUB_INTERFACE_SEPARATOR) |
| 6012 | + if sub_intf_sep_idx == -1: |
| 6013 | + ctx.fail("{} is invalid vlan subinterface".format(subinterface_name)) |
| 6014 | + |
| 6015 | + interface_alias = subinterface_name[:sub_intf_sep_idx] |
| 6016 | + if interface_alias is None: |
| 6017 | + ctx.fail("{} invalid subinterface".format(interface_alias)) |
| 6018 | + |
| 6019 | + if interface_alias.startswith("Po") is True: |
| 6020 | + intf_table_name = CFG_PORTCHANNEL_PREFIX |
| 6021 | + elif interface_alias.startswith("Eth") is True: |
| 6022 | + intf_table_name = 'PORT' |
| 6023 | + |
| 6024 | + config_db = ctx.obj['db'] |
| 6025 | + port_dict = config_db.get_table(intf_table_name) |
| 6026 | + if interface_alias is not None: |
| 6027 | + if not port_dict: |
| 6028 | + ctx.fail("{} parent interface not found. {} table none".format(interface_alias, intf_table_name)) |
| 6029 | + if get_intf_longname(interface_alias) not in port_dict.keys(): |
| 6030 | + ctx.fail("{} parent interface not found".format(subinterface_name)) |
| 6031 | + |
| 6032 | + # Validate if parent is portchannel member |
| 6033 | + portchannel_member_table = config_db.get_table('PORTCHANNEL_MEMBER') |
| 6034 | + if interface_is_in_portchannel(portchannel_member_table, interface_alias): |
| 6035 | + ctx.fail("{} is configured as a member of portchannel. Cannot configure subinterface" |
| 6036 | + .format(interface_alias)) |
| 6037 | + |
| 6038 | + # Validate if parent is vlan member |
| 6039 | + vlan_member_table = config_db.get_table('VLAN_MEMBER') |
| 6040 | + if interface_is_in_vlan(vlan_member_table, interface_alias): |
| 6041 | + ctx.fail("{} is configured as a member of vlan. Cannot configure subinterface" |
| 6042 | + .format(interface_alias)) |
| 6043 | + |
| 6044 | + sub_intfs = [k for k,v in config_db.get_table('VLAN_SUB_INTERFACE').items() if type(k) != tuple] |
| 6045 | + if subinterface_name in sub_intfs: |
| 6046 | + ctx.fail("{} already exists".format(subinterface_name)) |
| 6047 | + |
| 6048 | + subintf_dict = {} |
| 6049 | + if vid is not None: |
| 6050 | + subintf_dict.update({"vlan" : vid}) |
| 6051 | + |
| 6052 | + if subintf_vlan_check(config_db, get_intf_longname(interface_alias), vid) is True: |
| 6053 | + ctx.fail("Vlan {} encap already configured on other subinterface on {}".format(vid, interface_alias)) |
| 6054 | + |
| 6055 | + subintf_dict.update({"admin_status" : "up"}) |
| 6056 | + config_db.set_entry('VLAN_SUB_INTERFACE', subinterface_name, subintf_dict) |
| 6057 | + |
| 6058 | +@subinterface.command('del') |
| 6059 | +@click.argument('subinterface_name', metavar='<subinterface_name>', required=True) |
| 6060 | +@click.pass_context |
| 6061 | +def del_subinterface(ctx, subinterface_name): |
| 6062 | + sub_intf_sep_idx = subinterface_name.find(VLAN_SUB_INTERFACE_SEPARATOR) |
| 6063 | + if sub_intf_sep_idx == -1: |
| 6064 | + ctx.fail("{} is invalid vlan subinterface".format(subinterface_name)) |
| 6065 | + |
| 6066 | + config_db = ctx.obj['db'] |
| 6067 | + #subinterface_name = subintf_get_shortname(subinterface_name) |
| 6068 | + if interface_name_is_valid(config_db, subinterface_name) is False: |
| 6069 | + ctx.fail("{} is invalid ".format(subinterface_name)) |
| 6070 | + |
| 6071 | + subintf_config_db = config_db.get_table('VLAN_SUB_INTERFACE') |
| 6072 | + sub_intfs = [k for k,v in subintf_config_db.items() if type(k) != tuple] |
| 6073 | + if subinterface_name not in sub_intfs: |
| 6074 | + ctx.fail("{} does not exists".format(subinterface_name)) |
| 6075 | + |
| 6076 | + ips = {} |
| 6077 | + ips = [ k[1] for k in config_db.get_table('VLAN_SUB_INTERFACE') if type(k) == tuple and k[0] == subinterface_name ] |
| 6078 | + for ip in ips: |
| 6079 | + try: |
| 6080 | + ipaddress.ip_network(ip, strict=False) |
| 6081 | + config_db.set_entry('VLAN_SUB_INTERFACE', (subinterface_name, ip), None) |
| 6082 | + except ValueError: |
| 6083 | + ctx.fail("Invalid ip {} found on interface {}".format(ip, subinterface_name)) |
| 6084 | + |
| 6085 | + subintf_config_db = config_db.get_table('INTERFACE') |
| 6086 | + ips = [ k[1] for k in subintf_config_db if type(k) == tuple and k[0] == subinterface_name ] |
| 6087 | + for ip in ips: |
| 6088 | + config_db.set_entry('INTERFACE', (subinterface_name, ip), None) |
| 6089 | + |
| 6090 | + config_db.set_entry('VLAN_SUB_INTERFACE', subinterface_name, None) |
5974 | 6091 |
|
5975 | 6092 | if __name__ == '__main__':
|
5976 | 6093 | config()
|
0 commit comments