IS-IS Protocol คืออะไรและใช้ที่ไหน
IS-IS (Intermediate System to Intermediate System) เป็น link-state routing protocol ที่ใช้ SPF (Shortest Path First) algorithm เหมือน OSPF แต่ทำงานบน OSI Layer 2 โดยตรง (CLNP) ไม่ต้องพึ่ง IP IS-IS ถูกออกแบบมาตาม ISO 10589 standard และถูกขยายให้รองรับ IPv4/IPv6 ผ่าน Multi-Topology extensions
IS-IS ถูกใช้อย่างแพร่หลายใน ISP (Internet Service Providers) และ large-scale data center networks เนื่องจากข้อดีหลายประการ รองรับ MPLS และ Segment Routing ได้ดี Convergence เร็ว Scale ได้ดีกว่า OSPF ใน large networks เพราะไม่มี area 0 backbone requirement และมี TLV (Type-Length-Value) extensible format ที่เพิ่ม features ใหม่ได้ง่าย
บริษัทที่ใช้ IS-IS ได้แก่ Google, Facebook (Meta), Amazon, Microsoft สำหรับ data center fabrics และ ISPs ขนาดใหญ่เช่น Level 3, NTT, Telia สำหรับ backbone networks
IS-IS แบ่ง routing domain เป็น Level 1 (intra-area) และ Level 2 (inter-area) routers สามารถเป็น L1, L2 หรือ L1/L2 โดย L2 routers สร้าง backbone ที่เชื่อม areas เข้าด้วยกัน ต่างจาก OSPF ที่ต้องมี Area 0
สถาปัตยกรรมและหลักการทำงานของ IS-IS
รายละเอียดทางเทคนิคของ IS-IS architecture
# IS-IS Architecture Overview
#
# === IS-IS Levels ===
# Level 1 (L1): Intra-area routing
# - Routers ภายใน area เดียวกัน
# - คล้าย OSPF non-backbone areas
# - มี L1 LSDB (Link State Database) แยกกัน
#
# Level 2 (L2): Inter-area routing (backbone)
# - เชื่อม areas เข้าด้วยกัน
# - คล้าย OSPF Area 0
# - มี L2 LSDB แยกจาก L1
#
# L1/L2 Router: ทำหน้าที่ทั้ง L1 และ L2
# - เป็น border router ระหว่าง areas
# - มีทั้ง L1 และ L2 LSDB
#
# === Network Entity Title (NET) ===
# Format: AFI.Area-ID.System-ID.SEL
# ตัวอย่าง: 49.0001.1921.6800.1001.00
# 49 = AFI (Authority and Format Identifier)
# 0001 = Area ID
# 1921.6800.1001 = System ID (unique per router)
# 00 = SEL (N-Selector, always 00 for routers)
#
# System ID มาจาก Loopback IP:
# 192.168.1.1 -> 1921.6800.1001
# 10.0.0.1 -> 0100.0000.0001
#
# === PDU Types ===
# IIH (IS-IS Hello): neighbor discovery
# - L1 LAN IIH, L2 LAN IIH, P2P IIH
# LSP (Link State PDU): routing information
# - L1 LSP, L2 LSP
# CSNP (Complete Sequence Number PDU): database sync
# PSNP (Partial Sequence Number PDU): request/acknowledge LSPs
#
# === Metrics ===
# Default metric: 10 per interface (range 1-63 for narrow, 1-16777215 for wide)
# Wide metrics: ใช้ 24-bit metric (extended IS reachability TLV 22)
# แนะนำใช้ wide metrics เสมอใน production
#
# === DIS (Designated IS) ===
# คล้าย DR ใน OSPF แต่:
# - ไม่มี BDR (Backup DIS)
# - DIS election ทำใหม่ได้ทันทีเมื่อ priority เปลี่ยน (preemptive)
# - DIS ส่ง CSNP ทุก 10 วินาที
# - ทุก router มี adjacency กับทุก router (full mesh)
#
# === Adjacency Formation ===
# 1. Router ส่ง IIH packets
# 2. Neighbor ตอบ IIH กลับ
# 3. Three-way handshake (P2P) หรือ two-way (LAN)
# 4. Exchange LSPs ผ่าน CSNP/PSNP
# 5. SPF calculation
# 6. Routing table update
ตั้งค่า IS-IS บน Cisco IOS Router
Configuration สำหรับ production IS-IS deployment
! === Cisco IOS IS-IS Configuration ===
! Router R1 (L1/L2, Area 49.0001)
! Enable IS-IS process
router isis CORE
net 49.0001.1921.6800.1001.00
is-type level-1-2
metric-style wide
log-adjacency-changes
!
! Authentication (recommended for production)
authentication mode md5 level-1
authentication mode md5 level-2
authentication key-chain ISIS-KEY level-1
authentication key-chain ISIS-KEY level-2
!
! Fast convergence
spf-interval 5 50 200
prc-interval 5 50 200
lsp-gen-interval 5 50 200
!
! Overload bit (use during maintenance)
! set-overload-bit on-startup wait-for-bgp
!
! Address family for IPv4
address-family ipv4 unicast
metric-style wide
segment-routing mpls
exit-address-family
!
! Address family for IPv6
address-family ipv6 unicast
multi-topology
exit-address-family
! Interface configuration
interface Loopback0
ip address 192.168.1.1 255.255.255.255
ip router isis CORE
isis circuit-type level-2-only
interface GigabitEthernet0/0
description To R2 - P2P Link
ip address 10.0.12.1 255.255.255.252
ip router isis CORE
isis circuit-type level-2-only
isis network point-to-point
isis metric 100
! BFD for fast failure detection
bfd interval 100 min_rx 100 multiplier 3
isis bfd
interface GigabitEthernet0/1
description To LAN Segment
ip address 10.0.1.1 255.255.255.0
ip router isis CORE
isis circuit-type level-1
isis priority 127
isis metric 1000
! Key chain for authentication
key chain ISIS-KEY
key 1
key-string MySecretISISKey2024!
accept-lifetime 00:00:00 Jan 1 2024 infinite
send-lifetime 00:00:00 Jan 1 2024 infinite
! === Router R2 (L2 only, Area 49.0002) ===
router isis CORE
net 49.0002.1921.6800.2001.00
is-type level-2-only
metric-style wide
log-adjacency-changes
authentication mode md5 level-2
authentication key-chain ISIS-KEY level-2
interface Loopback0
ip address 192.168.2.1 255.255.255.255
ip router isis CORE
interface GigabitEthernet0/0
description To R1 - P2P Link
ip address 10.0.12.2 255.255.255.252
ip router isis CORE
isis network point-to-point
isis metric 100
isis bfd
! Verification commands
! show isis neighbors
! show isis database
! show isis topology
! show isis route
! show isis interface
! show isis spf-log
IS-IS บน Linux ด้วย FRRouting
ตั้งค่า IS-IS บน Linux server ด้วย FRRouting
# ติดตั้ง FRRouting บน Ubuntu/Debian
sudo apt-get update
sudo apt-get install -y frr frr-pythontools
# เปิด IS-IS daemon
sudo sed -i 's/isisd=no/isisd=yes/' /etc/frr/daemons
sudo systemctl restart frr
# ตั้งค่า IS-IS ผ่าน vtysh
sudo vtysh
# IS-IS Configuration
configure terminal
! Router configuration
router isis FABRIC
net 49.0001.0100.0000.0001.00
is-type level-1
metric-style wide
log-adjacency-changes
lsp-gen-interval 5
spf-interval 50
!
! Segment Routing
segment-routing on
segment-routing prefix 10.0.0.1/32 index 1001
! Interface configuration
interface eth0
ip router isis FABRIC
isis circuit-type level-1
isis network point-to-point
isis metric 100
isis hello-interval 1
isis hello-multiplier 3
interface lo
ip router isis FABRIC
isis passive
end
write memory
# === FRRouting Configuration File ===
# /etc/frr/isisd.conf
#
# router isis FABRIC
# net 49.0001.0100.0000.0001.00
# is-type level-1
# metric-style wide
# log-adjacency-changes
# !
# interface eth0
# ip router isis FABRIC
# isis circuit-type level-1
# isis network point-to-point
# isis metric 100
# !
# interface lo
# ip router isis FABRIC
# isis passive
# Verification
sudo vtysh -c "show isis neighbor"
sudo vtysh -c "show isis database"
sudo vtysh -c "show isis route"
sudo vtysh -c "show isis topology"
sudo vtysh -c "show isis interface"
# sysctl settings สำหรับ routing
# /etc/sysctl.d/99-frr.conf
# net.ipv4.ip_forward = 1
# net.ipv6.conf.all.forwarding = 1
# net.ipv4.conf.all.rp_filter = 0
sudo sysctl -p /etc/sysctl.d/99-frr.conf
Monitoring และ Troubleshooting IS-IS
วิธีตรวจสอบและแก้ปัญหา IS-IS
#!/bin/bash
# isis_monitor.sh — IS-IS Health Monitor
set -euo pipefail
VTYSH="sudo vtysh -c"
LOG="/var/log/isis_monitor.log"
ALERT_WEBHOOK=""
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG"; }
alert() {
log "ALERT: $1"
[ -n "$ALERT_WEBHOOK" ] && curl -s -X POST "$ALERT_WEBHOOK" \
-H "Content-Type: application/json" \
-d "{\"text\":\"[IS-IS] $1\"}" > /dev/null 2>&1 || true
}
ISSUES=0
# 1. Check IS-IS Process
log "Checking IS-IS process..."
if ! $VTYSH "show isis summary" > /dev/null 2>&1; then
alert "IS-IS process is NOT running"
ISSUES=$((ISSUES + 1))
fi
# 2. Check Neighbors
log "Checking IS-IS neighbors..."
EXPECTED_NEIGHBORS=""
NEIGHBOR_COUNT=$($VTYSH "show isis neighbor" | grep -c "Up" || echo 0)
if [ "$NEIGHBOR_COUNT" -lt "$EXPECTED_NEIGHBORS" ]; then
alert "IS-IS neighbors: $NEIGHBOR_COUNT/$EXPECTED_NEIGHBORS (some DOWN)"
# Show which neighbors are down
$VTYSH "show isis neighbor" | while read -r line; do
if echo "$line" | grep -q "Down\|Init"; then
alert "Neighbor issue: $line"
fi
done
ISSUES=$((ISSUES + 1))
fi
# 3. Check LSDB
log "Checking IS-IS database..."
LSP_COUNT=$($VTYSH "show isis database" | grep -c "LSP" || echo 0)
if [ "$LSP_COUNT" -eq 0 ]; then
alert "IS-IS database is EMPTY"
ISSUES=$((ISSUES + 1))
fi
# Check for LSP overload bit
if $VTYSH "show isis database detail" | grep -q "Overload bit set"; then
alert "IS-IS: Overload bit is SET on some LSPs"
fi
# 4. Check SPF runs
log "Checking SPF statistics..."
SPF_RUNS=$($VTYSH "show isis spf-log" | tail -5)
# Check if SPF is running too frequently (possible flapping)
RECENT_SPF=$($VTYSH "show isis spf-log" | grep "$(date '+%H:%M')" | wc -l)
if [ "$RECENT_SPF" -gt 10 ]; then
alert "IS-IS: Excessive SPF runs ($RECENT_SPF in last minute) — possible flapping"
ISSUES=$((ISSUES + 1))
fi
# 5. Check interface status
log "Checking IS-IS interfaces..."
$VTYSH "show isis interface" | while read -r line; do
if echo "$line" | grep -q "Down"; then
IFACE=$(echo "$line" | awk '{print $1}')
alert "IS-IS interface DOWN: $IFACE"
ISSUES=$((ISSUES + 1))
fi
done
# 6. Check route count
log "Checking IS-IS routes..."
ROUTE_COUNT=$($VTYSH "show isis route" | grep -c "^[0-9]" || echo 0)
EXPECTED_ROUTES=""
if [ "$ROUTE_COUNT" -lt "$EXPECTED_ROUTES" ]; then
alert "IS-IS routes: $ROUTE_COUNT (expected >= $EXPECTED_ROUTES)"
ISSUES=$((ISSUES + 1))
fi
# Summary
if [ "$ISSUES" -eq 0 ]; then
log "IS-IS health: OK (neighbors=$NEIGHBOR_COUNT, LSPs=$LSP_COUNT, routes=$ROUTE_COUNT)"
else
log "IS-IS health: $ISSUES issue(s) found"
fi
# Cron: ทุก 2 นาที
# */2 * * * * /opt/scripts/isis_monitor.sh
IS-IS Automation ด้วย Python และ Netmiko
Automate IS-IS configuration และ monitoring
#!/usr/bin/env python3
# isis_automation.py — IS-IS Network Automation
from netmiko import ConnectHandler
import json
import re
from datetime import datetime
class ISISAutomation:
def __init__(self, devices_file="devices.json"):
with open(devices_file) as f:
self.devices = json.load(f)
def connect(self, device_name):
device = self.devices[device_name]
return ConnectHandler(**device)
def get_isis_neighbors(self, device_name):
conn = self.connect(device_name)
output = conn.send_command("show isis neighbors", use_textfsm=True)
conn.disconnect()
return output
def get_isis_database(self, device_name):
conn = self.connect(device_name)
output = conn.send_command("show isis database")
conn.disconnect()
return output
def deploy_isis_config(self, device_name, config_commands):
conn = self.connect(device_name)
output = conn.send_config_set(config_commands)
conn.save_config()
conn.disconnect()
return output
def check_all_neighbors(self):
results = {}
for name in self.devices:
try:
neighbors = self.get_isis_neighbors(name)
up_count = sum(1 for n in neighbors if n.get("state") == "Up")
results[name] = {
"status": "OK" if up_count > 0 else "WARN",
"neighbors_up": up_count,
"total": len(neighbors),
"details": neighbors,
}
except Exception as e:
results[name] = {"status": "ERROR", "error": str(e)}
return results
def rolling_metric_change(self, interface, new_metric):
"""Change IS-IS metric with rolling update to avoid traffic black-holes"""
for name in self.devices:
config = [
f"interface {interface}",
f" isis metric {new_metric}",
]
print(f"Updating {name}: {interface} metric={new_metric}")
self.deploy_isis_config(name, config)
# Wait for convergence
import time
time.sleep(10)
# Verify neighbors still up
neighbors = self.get_isis_neighbors(name)
up = sum(1 for n in neighbors if n.get("state") == "Up")
if up == 0:
print(f"WARNING: No neighbors up on {name} after metric change!")
# Rollback
config = [f"interface {interface}", f" no isis metric"]
self.deploy_isis_config(name, config)
return False
print("Rolling metric change complete")
return True
def generate_report(self):
report = {
"timestamp": datetime.now().isoformat(),
"devices": {},
}
for name in self.devices:
try:
neighbors = self.get_isis_neighbors(name)
report["devices"][name] = {
"neighbors": len(neighbors),
"neighbors_up": sum(1 for n in neighbors if n.get("state") == "Up"),
}
except Exception as e:
report["devices"][name] = {"error": str(e)}
with open(f"isis_report_{datetime.now().strftime('%Y%m%d')}.json", "w") as f:
json.dump(report, f, indent=2)
return report
# devices.json example:
# {
# "r1": {
# "device_type": "cisco_ios",
# "host": "10.0.0.1",
# "username": "admin",
# "password": "secure_pass",
# "secret": "enable_pass"
# },
# "r2": {
# "device_type": "cisco_ios",
# "host": "10.0.0.2",
# "username": "admin",
# "password": "secure_pass"
# }
# }
if __name__ == "__main__":
auto = ISISAutomation()
results = auto.check_all_neighbors()
for device, status in results.items():
print(f"{device}: {status['status']} ({status.get('neighbors_up', 0)} neighbors up)")
FAQ คำถามที่พบบ่อย
Q: IS-IS กับ OSPF ใช้อันไหนดีกว่า?
A: สำหรับ enterprise networks ขนาดเล็กถึงกลาง OSPF เหมาะกว่าเพราะผู้ดูแลส่วนใหญ่คุ้นเคย สำหรับ ISP, large data centers หรือ networks ที่ต้องการ Segment Routing IS-IS เหมาะกว่าเพราะ scale ได้ดีกว่า extensible ผ่าน TLV และไม่มี area 0 constraint Google, Meta, Amazon ใช้ IS-IS สำหรับ data center fabrics
Q: NET address ตั้งยังไง?
A: NET format คือ AFI.AreaID.SystemID.SEL โดย AFI ใช้ 49 สำหรับ private addressing, Area ID ใช้เลขที่ไม่ซ้ำกันต่อ area (เช่น 0001, 0002), System ID ใช้ 6 bytes ที่ unique ต่อ router (แปลงจาก loopback IP เช่น 192.168.1.1 เป็น 1921.6800.1001) และ SEL ใช้ 00 สำหรับ router เสมอ
Q: IS-IS convergence เร็วแค่ไหน?
A: ด้วย tuning ที่เหมาะสม IS-IS convergence อยู่ที่ 50-200ms โดยใช้ BFD สำหรับ fast failure detection (50ms), IS-IS hello interval 1 วินาที, SPF delay 50ms และ wide metrics การใช้ Prefix-SID (Segment Routing) ช่วยให้ traffic สลับเส้นทางได้เร็วยิ่งขึ้นผ่าน TI-LFA (Topology Independent Loop-Free Alternate)
Q: IS-IS รองรับ IPv6 อย่างไร?
A: IS-IS รองรับ IPv6 ผ่าน Multi-Topology IS-IS (RFC 5120) ที่แยก topology สำหรับ IPv4 และ IPv6 หรือใช้ Single Topology ที่ IPv4 และ IPv6 ใช้ topology เดียวกัน Multi-Topology ยืดหยุ่นกว่าเพราะ IPv6 routes สามารถใช้เส้นทางต่างจาก IPv4 ได้ แต่ใช้ memory มากกว่า
