Обработчик управления устройством с синхронизацией интерфейсов и их индексов - версия 2

Материал из BiTel WiKi

Перейти к: навигация, поиск

Решение сделано на основе вот этого

Отличия:

1) Не нужна сторонняя библиотека у snmp4j, используется стандартная из поставки. Поэтому не нужны классы SnmpClient и SnmpDeviceManager из того решения. А класс IfaceSnmpDeviceManager немного изменен и переименован в IndexSnmpDeviceManager. Он наследуется от стандартного ru.bitel.bgbilling.modules.inet.dyn.device.snmp.SnmpDeviceManager(Описан тут: https://docs.bitel.ru/pages/viewpage.action?pageId=43385967) и используется та же самая конфигурация при получении uptime.

2) В случае если интерфейс в биллинге не найден, то создается интерфейс с номером, который считываться как group(1) из snmp.ifNameRegexpFilter=GigabitEthernet0/0/2\.(\d+). В старом решении просто присваивался (максимальный номер интерфейса) + 1.

3) На устройстве не нужно явно вбивать команду ifsync, во всплывающем меню уже есть пункт "сихронизировать интерфейсы". При перезагрузке устройства этого делать не надо - смотрим следующий пункт.

4) При перезагрузке устройства IfaceSnmpDeviceManager сам это определит и вызовет( метод onReboot).

Проверялось на сisco и juniper. Использовалось в схеме сбора статистики по snmp.

Содержание

Описание

Класс - обработчик управления устройством по SNMP (DeviceManager) взамен стандартного.

  • Умеет синхронизировать интерфейсы устройства и их snmp-индексы (нужны для учёта flow/snmp)

Как пользоваться

  • Копируем себе в динамический код класс:
ru.dsi.bgbilling.modules.inet.dyn.device.snmp.IndexSnmpDeviceManager
  • Компилируем динамический код
  • Указываем в типе устройства модуля Inet "Обработчик управления устройством: ru.dsi.bgbilling.modules.inet.dyn.device.snmp.IndexSnmpDeviceManager"
  • Настраиваем конфигурацию устройства/типа устройства/родительского устройства (по усмотрению) - см раздел "Конфигурация"
  • Перечитываем конфигурацию устройств
  • При обнаружении перезагрузки ( а access скорее всего сразу обнаружит это после перечитывания конфигурации) IndexSnmpDeviceManager сам сихронизует интерфейсы и индексы.
  • Чтобы запустить вручную заходим в устройство с нашим обработчиком, кликаем правой кнопкой, выбираем "сихронизировать интерфейсы" смотрим результат

Файл:index_command.jpg

Файл:sync_result.jpg

Файл:index_list.jpg

Принцип работы

Обработчик поддерживает команды:

  • ifsync - синхронизация интерфейсов и их ifIndex на роутере и в биллинге:
    • 1. Получаем по SNMP список соответствий: ifIndex->ifName интерфейсов на устройстве
    • 2. Для каждого полученного интерфейса проверяем, есть ли в биллинге на устройсве интерфейс с таким именем?
      • 2.1. Если нет, и он проходит через фильтр snmp.ifNameRegexpFilter - создаём с правильным ifIndex и категорией ip = snmp.ipCategory и номер интерфейса находим как group(1) у заданного snmp.ifNameRegexpFilter.
      • 2.2. Если есть, то совпадает ли ifIndex?
        • 2.2.1. Если да, то ничего не делаем, всё ок.
        • 2.2.2. Если нет, то меняем ifIndex
    • 3. Оставшиеся необработанными интерфейсы в BG: если их нет на устройстве, то помечаем как отключенный и устанавливаем ifIndex=0

Настройка

Параметры конфигурации устройства/типа устройства:

  • для SnmpDeviceManager
#версия протокола (1 или 2 (для 2с))
snmp.version=1
#ip-адрес или hostname устройства. По-умолчанию берётся из поля "Хост" устройства в модуле Inet
snmp.host=
#порт SNMP устройства
snmp.port=161
#SNMP community. По-умолчанию - secret устройства в Inet
snmp.community=
#OID для опроса uptime устройства. По умолчанию - 1.3.6.1.2.1.1.3.0
snmp.uptimeOid=
  • для IndexSnmpDeviceManager (в дополнение к настройкам из SnmpDeviceManager):
#включает работу менеджера на этом устройстве(по умолчанию включено)
snmp.enable=1
#oid для получения списка интерфейсов устройства
snmp.ifNameOid=1.3.6.1.2.1.2.2.1.2
#regexp для фильтрации интерфейсов. Например, если нам в биллинге нужны только интерфейсы вида GigabitEthernet0/0/2.1122, 
#то указываем snmp.ifNameRegexpFilter=GigabitEthernet0/0/2\.(\d+)
#Группировку тут надо обязательно указывать, подразумевается что в ней идет номер индекса, мы его обновляем на интерфейсе.
snmp.ifNameRegexpFilter=(.*)
#id категории ресурсов, которая будет указана для создаваемых интерфейсов
snmp.ipCategory=0
#если 1, то меняем индексы не с текущего момента, а со времени старта устройства, если это произошло сегодня.
#Предполагаем, что ifIndex могут меняться только при рестарте устройства.
snmp.substractUptime=1

Код

  • IndexSnmpDeviceManager
package ru.dsi.bgbilling.modules.inet.dyn.device.snmp;
 
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.LongStream;
 
import org.apache.log4j.Logger;
 
import bitel.billing.common.TimeUtils;
import ru.bitel.bgbilling.kernel.container.managed.ServerContext;
import ru.bitel.bgbilling.modules.inet.access.manage.event.InetDeviceManageEvent;
import ru.bitel.bgbilling.modules.inet.api.common.bean.InetDevice;
import ru.bitel.bgbilling.modules.inet.api.common.bean.InetDeviceType;
import ru.bitel.bgbilling.modules.inet.dyn.device.snmp.SnmpDeviceManager;
import ru.bitel.bgbilling.server.util.Setup;
import ru.bitel.common.ParameterMap;
import ru.bitel.common.Preferences;
import ru.bitel.common.Utils;
import ru.bitel.common.worker.ThreadContext;
import ru.bitel.oss.systems.inventory.resource.common.DeviceInterfaceService;
import ru.bitel.oss.systems.inventory.resource.common.bean.Device;
import ru.bitel.oss.systems.inventory.resource.common.bean.DeviceInterface;
import ru.bitel.oss.systems.inventory.resource.common.bean.DeviceInterfaceIndex;
import ru.bitel.oss.systems.inventory.resource.common.bean.DeviceType;
import ru.bitel.oss.systems.inventory.resource.server.DeviceManager;
import ru.bitel.oss.systems.inventory.resource.server.DeviceManagerMethod;
import uk.co.westhawk.snmp.stack.AsnObjectId;
 
 
/**
 * @author cromeshnic@gmail.com 
 * patched by stark
 *
 * Класс для работы с интерфейсами их индексами по SNMP
 * <pre>
 * команды:
 *      ifsync - синхронизация интерфейсов и их ifIndex на роутере и в биллинге:
 *          1. Получаем по SNMP список соответствий: ifIndex->ifName интерфейсов на устройстве
 *          2. Для каждого полученного интерфейса проверяем,
 *              есть ли в биллинге на устройсве интерфейс с таким именем?
 *          2.1. Если нет, и он проходит через фильтр snmp.ifNameRegexpFilter - создаём с правильным ifIndex и категорией ip = snmp.ipCategory и номер интерфейса находим 
 *          как group(1) у заданного snmp.ifNameRegexpFilter.   
 *          2.2. Если есть, то совпадает ли ifIndex?
 *          2.2.1. Если да, то ничего не делаем, всё ок.
 *          2.2.2. Если нет, то меняем ifIndex
 *          3. Оставшиеся необработанными интерфейсы в BG: если их нет на устройстве, то
 *              помечаем как отключенный и устанавливаем ifIndex=0
 * параметры:
 *      snmp.ifNameOid=1.3.6.1.2.1.2.2.1.1
 *          - oid для получения списка интерфейсов устройства
 *      snmp.ifNameRegexpFilter=.*
 *          - regexp для фильтрации интерфейсов. Например, если нам в биллинге нужны только интерфейсы вида GigabitEthernet0/0/2.1122, 
 *          то указываем snmp.ifNameRegexpFilter=GigabitEthernet0/0/2\.(\d+)
 *          Группировку тут надо обязательно указывать, подразумевается что в ней идет номер индекса, мы его обновляем на интерфейсе.   
 *      snmp.ipCategory=0
 *          - id категории ресурсов, которая будет указана для создаваемых интерфейсов
 *      snmp.substractUptime=1
 *          - если 1, то меняем индексы не с текущего момента, а со времени старта устройства, если это произошло сегодня.
 *              Предполагаем, что ifIndex могут меняться только при рестарте устройства.
 *      snmp.enable=1
 *          - включает работу менеджера на этом устройстве     
 * </pre>
 * @see SnmpDeviceManager
 */
public class IndexSnmpDeviceManager extends SnmpDeviceManager implements DeviceManager 
{
     protected static final Logger logger = Logger.getLogger( SnmpDeviceManager.class );
    //TODO - резервирование/закрытие датой расформированных интерфейсов : http://forum.bitel.ru/viewtopic.php?p=71924#p71924    
 
    private long[] ifNameOid;
    /**
     * Фильтр имён интерфейсов
     * Если имя не соответствует регэкспу, то не заводим его в биллинге
     */
    private Pattern ifaceNamePattern;
    private int ipCategory;
    private boolean subtractUptimeForIfIndex;
    protected int mid;
    protected int deviceId;
 
    protected boolean enabled;//Работаем?
 
 
    @Override
    public Object init(Setup setup, int moduleId, Device<?, ?> device, DeviceType deviceType, ParameterMap deviceConfig) {
        super.init(setup, moduleId, device, deviceType, deviceConfig);
        this.mid = moduleId;
        this.deviceId = device.getId();
        //1.3.6.1.2.1.2.2.1.2.56 = STRING: "GigabitEthernet0/0/2.1100"
        this.ifNameOid =  new AsnObjectId( ( deviceConfig.get( "snmp.ifNameOid", "1.3.6.1.2.1.31.1.1.1.1" ) ) ).getOid();
        this.ifaceNamePattern = Pattern.compile( deviceConfig.get("snmp.ifNameRegexpFilter", ".*") ); 
        //Категория IP, выставляемая новым интерфейсам
        this.ipCategory = deviceConfig.getInt("snmp.ipCategory", 0);
        //Вычитать ли из текущего времени uptime устройства при проставлении даты/времени для ifIndex?
        //(не дальше, чем за границу суток)
        this.subtractUptimeForIfIndex = deviceConfig.getBoolean("snmp.substractUptime", true);        
        this.enabled = deviceConfig.getBoolean("snmp.enable", true);
 
        return null;
    }
 
    @DeviceManagerMethod(title = "Cинхронизировать индексы" )
    public String ifsync()
            throws Exception
    {
        if(!this.enabled){
            return "SNMP manager disabled on device";
        }
        StringBuilder result = new StringBuilder();
        ServerContext ctx = ThreadContext.get();
        DeviceInterfaceService devicePortService = ctx.getService(DeviceInterfaceService.class, this.mid);
        //Интерфейсы устройства в биллинге
        Map<String, DeviceInterface> ifaces = new HashMap<String, DeviceInterface>();
        int maxPortNumber = 0;
        for (DeviceInterface deviceInterface : devicePortService.devicePortList(this.deviceId, false)) {
            //Не дублируются ли интерфейсы по именам?
            if(ifaces.get(deviceInterface.getTitle())!=null){
                logger.error("duplicate iface names on device " + this.deviceId + ": " + deviceInterface.getTitle() +
                        " (ports:" + deviceInterface.getPort() + "," + ifaces.get(deviceInterface.getTitle()).getPort() + ")");
                result.append("! duplicate bg ifaces: ")
                        .append(deviceInterface.getTitle())
                        .append(" (ports:")
                        .append(deviceInterface.getPort())
                        .append(",")
                        .append(ifaces.get(deviceInterface.getTitle()).getPort())
                        .append(")\n");
            }
            ifaces.put(deviceInterface.getTitle(), deviceInterface);
            //Определяем максимальный номер порта
            if(deviceInterface.getPort()>maxPortNumber){
                maxPortNumber=deviceInterface.getPort();
            }
        }
 
        //Интерфейсы, полученные с устройства
        final Map<String, Integer> ifaceTitleToIfIndexMap = new HashMap<String, Integer>();
        logger.info( "ifNameOid =" + LongStream.of( ifNameOid ).boxed().collect( Collectors.toList()) );
 
        this.snmpClient.walk(this.ifNameOid, String.class, ( o, v ) -> {
            //System.out.println( new AsnObjectId( o ) + " = " + v );
            //logger.info ( "v=" + v );
            ifaceTitleToIfIndexMap.put( v ,  (int)o[ o.length - 1 ] );
        } ); 
 
        Calendar now = Calendar.getInstance();
 
        //Получаем uptime (в TimeTicks - 0.01 секунды)
        Long uptime = (long) this.uptime();
        Date start;
        Calendar cal;
        if(uptime==null || !this.subtractUptimeForIfIndex){//нет данных оп uptime, либо мы их не должны использовать
            start = (Date)now.getTime().clone();
        }else{
            cal = (Calendar)now.clone();
            cal.add(Calendar.SECOND, (int)(uptime/-1000) );
            if(TimeUtils.daysDelta(now, cal)!=0){//Девайс был рестартован не сегодня
                start = (Date)now.getTime().clone(); //Меняем индексы с текущего момента
                logger.info("device "+deviceId+" started "+TimeUtils.formatDate(cal));
            }else{
                start = (Date)cal.getTime().clone();
            }
        }
        cal = Calendar.getInstance();
        cal.setTime(start);
        cal.add(Calendar.SECOND, -1);
        Date nowMinusSecond = cal.getTime();
 
        DeviceInterface iface;
        DeviceInterfaceIndex deviceInterfaceIndex;
        Integer ifaceIndex;
        List<DeviceInterfaceIndex> indexList;
 
        int count = 0;
        //1. Перебираем все полученные интерфейсы
        for (Map.Entry<String, Integer> nameToIndex : ifaceTitleToIfIndexMap.entrySet()) 
        {                 
            //1.1 Ищем интерфейс в биллинге по его имени
            String ifName = nameToIndex.getKey();
            Integer ifIndexReal = nameToIndex.getValue();
            iface = ifaces.get( ifName );
 
            /*count ++;
            if ( count > 1000 )
            {
                break;
            }*/
 
            Matcher matcher = ifaceNamePattern.matcher( ifName );
            boolean find = matcher.find();
 
            if( iface == null )
            {
                //1.1.1 Не нашли - заводим в
                // Удовлетворяет ли интерфейс фильтру? Если нет - не заводим его
                if( !find )
                {
                    logger.info("skip snmp iface "+ifName+" on deviceId="+this.deviceId+" due to regexp "+ this.ifaceNamePattern.pattern() );
                    continue;
                }
 
                logger.info ( "ifName=" + ifName );
                int portNumber = Utils.parseInt(  matcher.group( 1 ), 0 );
                if ( portNumber == 0 )
                {
                    logger.info("portNumber is 0  for snmp iface "+ifName+" on deviceId="+this.deviceId+" due to regexp "+ this.ifaceNamePattern.pattern() );
                    continue;
                }
 
 
                iface = new DeviceInterface();
                iface.setPort( portNumber );//increment port number (port number != ifindex here !!!)
                iface.setTitle(ifName);
                iface.setComment("");
                iface.setStatus(1);//1 - Доступен, 0 - Зарезервирован
                iface.setDeviceId(this.deviceId);
                iface.setIpCategoryId(this.ipCategory);
                deviceInterfaceIndex = new DeviceInterfaceIndex();
                deviceInterfaceIndex.setId(0);//id<=0 => new
                deviceInterfaceIndex.setPort( portNumber );//вроде бы не обязательно, но пусть будет
                deviceInterfaceIndex.setDeviceId(this.deviceId);//вроде бы не обязательно, но пусть будет
 
                deviceInterfaceIndex.setIndex( ifIndexReal );
                deviceInterfaceIndex.setTimeFrom(now.getTime());
                deviceInterfaceIndex.setTimeTo(null); 
                iface.setIndexList(  Collections.singletonList(deviceInterfaceIndex) );
                devicePortService.devicePortUpdate( iface, false );
                logger.info("adding new iface "+iface.getTitle()+" with ifIndex="+ifIndexReal+" from "+ TimeUtils.formatFullDate(now.getTime()));
                result.append("+ ")
                    .append(iface.getTitle())
                    .append(" (")
                    .append(ifIndexReal)
                    .append(") from ")
                    .append(TimeUtils.formatFullDate(now.getTime()))
                    .append("\n");
            }else
            {//1.1.2 Нашли такой интерфейс, проверяем, изменился ли у него ifindex
                //Если интерфейс при этом не удовлетворяет фильтру, то пишем об этом в лог
                if( !find )
                {
                    logger.warn("existing bg iface "+ifName+" on deviceId="+this.deviceId+" doesn't match regexp "+this.ifaceNamePattern.pattern() );
                    result.append("? ")
                            .append(iface.getTitle())
                            .append(" - нестандартный интерфейс в BG\n");
                }
                indexList = iface.getIndexList();
                deviceInterfaceIndex = this.getCurrentIndex(now.getTime(), indexList);
                if( deviceInterfaceIndex!=null )
                {
                    ifaceIndex = deviceInterfaceIndex.getIndex();
                }else //По-умолчанию, индекс интерфейса - это его порт
                {
                    ifaceIndex = iface.getPort();
                }
 
                if( !ifaceIndex.equals(ifIndexReal) ){//Индекс поменялся! Нужно обновить
                    //Закрываем датой предыдущий ifIndex, если есть
                    if( deviceInterfaceIndex!=null )
                    {
                        deviceInterfaceIndex.setTimeTo(nowMinusSecond);
                    }
 
                    if(indexList==null)
                    {
                        indexList = new ArrayList<DeviceInterfaceIndex>();
                        iface.setIndexList(indexList);
                    }
                    deviceInterfaceIndex = new DeviceInterfaceIndex();
                    deviceInterfaceIndex.setId(0);//id<=0 => new
                    deviceInterfaceIndex.setPort(iface.getPort());//вроде бы не обязательно, но пусть будет
                    deviceInterfaceIndex.setDeviceId(iface.getDeviceId());//вроде бы не обязательно, но пусть будет
                    deviceInterfaceIndex.setIndex( ifIndexReal );
                    deviceInterfaceIndex.setTimeFrom(start);
                    deviceInterfaceIndex.setTimeTo(null);
                    indexList.add(deviceInterfaceIndex);
                    devicePortService.devicePortUpdate( iface, false );
                    logger.info("updating iface "+iface.getTitle()+": ifIndex="+ifIndexReal+" (was "+ifaceIndex+") from "+ TimeUtils.formatFullDate(start));
                    result.append("* ")
                        .append(iface.getTitle())
                        .append(" (")
                        .append(ifaceIndex)
                        .append("->")
                        .append(ifIndexReal)
                        .append(") from ")
                        .append(TimeUtils.formatFullDate(start))
                        .append("\n");
                }
            }
        }
       logger.info ( "other" );
 
        //2. Теперь перебираем интерфейсы в BG, чтобы обработать оставшиеся
        for(Map.Entry<String, DeviceInterface> ifaceEntry : ifaces.entrySet()) {
            iface = ifaceEntry.getValue();//iface в BG
            //2.1 Ищем индекс интерфейса в полученном по SNMP списке
            ifaceIndex = ifaceTitleToIfIndexMap.get(ifaceEntry.getKey());
            if(ifaceIndex==null){//Есть в BG, но не получен с устройства
                //зануляем ifIndex, чтобы он гарантированно ни с кем не пересекался
                indexList = iface.getIndexList();
                deviceInterfaceIndex = getCurrentIndex(now.getTime(), indexList);
                if(deviceInterfaceIndex==null){
                    ifaceIndex = iface.getPort();
                }else{
                    ifaceIndex = deviceInterfaceIndex.getIndex();
                }
                if(ifaceIndex!=0){
                    //Зануляем!
                    if(deviceInterfaceIndex!=null){
                        deviceInterfaceIndex.setTimeTo(nowMinusSecond);
                    }
                    if(indexList==null){
                        indexList = new ArrayList<DeviceInterfaceIndex>();
                        iface.setIndexList(indexList);
                    }
                    deviceInterfaceIndex = new DeviceInterfaceIndex();
                    deviceInterfaceIndex.setId(0);//id<=0 => new
                    deviceInterfaceIndex.setPort(iface.getPort());//вроде бы не обязательно, но пусть будет
                    deviceInterfaceIndex.setDeviceId(iface.getDeviceId());//вроде бы не обязательно, но пусть будет
                    deviceInterfaceIndex.setIndex(0);
                    deviceInterfaceIndex.setTimeFrom(start);
                    deviceInterfaceIndex.setTimeTo(null);
                    indexList.add(deviceInterfaceIndex);
                    iface.setComment("deleted");
                    devicePortService.devicePortUpdate( iface, false );
                    logger.info("updating iface "+iface.getTitle()+": ifIndex=0 (was "+ifaceIndex+") from "+ TimeUtils.formatFullDate(start));
                    result.append("- ")
                            .append(iface.getTitle())
                            .append(" (")
                            .append(ifaceIndex)
                            .append("->0) from ")
                            .append(TimeUtils.formatFullDate(start))
                            .append("\n");
                }
            }
        }
        if(result.length()==0){
            return "no changes";
        }
 
        return result.toString();
    }
 
    protected DeviceInterfaceIndex getCurrentIndex(Date now, List<DeviceInterfaceIndex> deviceInterfaceIndexList){
        if(deviceInterfaceIndexList!=null){
            for (DeviceInterfaceIndex deviceInterfaceIndex : deviceInterfaceIndexList) {
                if(TimeUtils.timeInRange(now, deviceInterfaceIndex.getTimeFrom(), deviceInterfaceIndex.getTimeTo())){
                    return deviceInterfaceIndex;
                }
            }
        }
        return null;
    }
 
 
    public static void main( String argv[] )
    {
        try
        {
            logger.info( "hello" );
            IndexSnmpDeviceManager man = new IndexSnmpDeviceManager();
            int moduleId = 1;
            InetDevice device = new InetDevice();
            Preferences deviceConfig = new Preferences();
            /* 
            //cisco
            int deviceId = 2;            
            device.setId( deviceId );
            device.setHost( "10.10.1.42" );
 
            deviceConfig.set( "snmp.ifNameOid", "1.3.6.1.2.1.2.2.1.2" );
            deviceConfig.set( "snmp.ifNameRegexpFilter", "GigabitEthernet0/0/2\\.(\\d+)" );
 
            deviceConfig.set( "snmp.version", "2" );
            deviceConfig.set( "snmp.host", "10.10.1.42" );
            */
 
 
            //juniper
            int deviceId = 3;            
            device.setId( deviceId );
            device.setHost( "10.10.1.100" );
 
            deviceConfig.set( "snmp.ifNameOid", "1.3.6.1.2.1.2.2.1.2" );
            deviceConfig.set( "snmp.ifNameRegexpFilter", "ae0\\.(\\d+)" );
 
            deviceConfig.set( "snmp.version", "2" );
            //deviceConfig.set( "snmp.host", "10.10.1.42" );
 
 
            man.init( Setup.getSetup(), moduleId, device, new InetDeviceType(), deviceConfig );
            man.connect();      
            man.ifsync();
 
            //System.out.println ( "hello" );
 
 
        }
        catch( Exception e )
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
/**
     * Метод вызывается при обнаружении перезагрузки устройства.
     * @param e
     * @return
     * @throws Exception
     */
    public Object onReboot( InetDeviceManageEvent e ) 
        throws Exception        
    {
        logger.info( "onReboot" );
        ifsync();
        return null;
    }
}

P.S.

  • Проверка доступности устройства по SNMP:
# snmpwalk -c public -v 2c 10.10.1.42  1.3.6.1.2.1.2.2.1.2
iso.3.6.1.2.1.2.2.1.2.1 = STRING: "GigabitEthernet0/0/0"
iso.3.6.1.2.1.2.2.1.2.2 = STRING: "GigabitEthernet0/0/1"
iso.3.6.1.2.1.2.2.1.2.3 = STRING: "GigabitEthernet0/0/2"
iso.3.6.1.2.1.2.2.1.2.4 = STRING: "GigabitEthernet0/0/3"
iso.3.6.1.2.1.2.2.1.2.5 = STRING: "TenGigabitEthernet0/2/0"
iso.3.6.1.2.1.2.2.1.2.6 = STRING: "GigabitEthernet0"
iso.3.6.1.2.1.2.2.1.2.7 = STRING: "VoIP-Null0"
iso.3.6.1.2.1.2.2.1.2.8 = STRING: "Null0"
iso.3.6.1.2.1.2.2.1.2.9 = STRING: "Loopback0"
iso.3.6.1.2.1.2.2.1.2.10 = STRING: "Loopback1"
iso.3.6.1.2.1.2.2.1.2.11 = STRING: "Port-channel1"
iso.3.6.1.2.1.2.2.1.2.12 = STRING: "Port-channel1.2"
iso.3.6.1.2.1.2.2.1.2.13 = STRING: "Port-channel1.6"
iso.3.6.1.2.1.2.2.1.2.14 = STRING: "Port-channel1.7"
iso.3.6.1.2.1.2.2.1.2.15 = STRING: "Port-channel1.8"
iso.3.6.1.2.1.2.2.1.2.16 = STRING: "Port-channel1.9"
iso.3.6.1.2.1.2.2.1.2.17 = STRING: "Port-channel1.15"
iso.3.6.1.2.1.2.2.1.2.18 = STRING: "Port-channel1.16"
iso.3.6.1.2.1.2.2.1.2.19 = STRING: "Port-channel1.17"
iso.3.6.1.2.1.2.2.1.2.20 = STRING: "Port-channel1.18"
iso.3.6.1.2.1.2.2.1.2.21 = STRING: "Port-channel1.19"
iso.3.6.1.2.1.2.2.1.2.22 = STRING: "Port-channel1.20"
iso.3.6.1.2.1.2.2.1.2.23 = STRING: "Port-channel1.21"
...

--Cromeshnic 08:16, 23 декабря 2013 (UTC)

--stark 13:23, 10 октября 2017 (UTC)

Личные инструменты