接口介绍(前言)
接口(interface)是网络设备用来处理各种连接媒介的抽象化的口,端口(port)是网络设备真实存在的物理意义上的口,端口一定是接口,接口不一定是端口。
接口是网络设备最重要的基础设施,从物理层到应用层的协议在接口中都有相关配置。可配置命令数量之多,仅次于全局配置模式。
注:由于本文章是涉及到网络工程和编程开发的跨专业文章,文章中会多次出现网络设备的接口和编程意义上的接口。为了区分,下面每当出现接口的地方会注明(网络)接口或(编程)接口以表示哪个接口。
统一的(网络)接口结构
不同厂商的(网络)接口格式是大同小异的,看一下不同的(网络)接口可以知道(网络)接口格式都是类似于“(网络)接口类型 序号/序号/序号”的形式,中间的序号可能根据设备不同和(网络)接口类型不同会多一段少一段,有时候末尾还会跟子序号。
定义一个(网络)接口结构,让这个结构所储存的(网络)接口格式在任何网络设备使用,可以表示不同类型、不同序号的(网络)接口。
class S接口:
"表示一个接口"
def __init__(self, a类型: int, a名称: str, aa序号: tuple, a子序号 = 0):
self.m类型 = int(a类型)
self.m名称 = str(a名称)
self.ma序号 = aa序号
self.m子序号 = a子序号
@staticmethod
def fc标准(a类型, *a序号, a子序号 = 0):
"(类型,*序号,子序号)"
return S接口(a类型, "", a序号, a子序号)
这里的接口类型是一个枚举,用来统一不同网络设备的接口类型。在不同的设备中,同一种接口的名称可能不相同。比如思科设备的百兆以太网口名称是“FastEthernet”,华为/华三设备的百兆以太网口名称是“Ethernet”,中兴的百兆以太网口名称是“fei_”。所以有必要用统一的枚举值来表示这些同样类型不同名称的口,有了统一枚举值,等到具体设备要用的时候再转换成具体名称。
class E接口(enum.IntEnum):
e空 = 0x00000000
e管理 = 0x00000001
e环回 = 0x00000100
e十兆以太网 = 0x00000210 #10M=10'000'000
e以太网 = e十兆以太网
e百兆以太网 = 0x00000220 #100M=100'000'000
e快速以太网 = e百兆以太网
e吉以太网 = 0x00000230 #1G=1'000M=1'000'000'000
e千兆以太网 = e吉以太网
e串行 = 0x00000400
e虚拟局域网 = 0x00000500
e隧道 = 0x00000600
我在写接口类型枚举时考虑到了别名的情况。如:百兆以太网=快速以太网、吉以太网=千兆以太网。这些别名的值是一样的,所以最后转换成设备对应的接口名称的结果也是一样。
(网络)接口配置模式(编程)接口
(网络)接口配置模式(编程)接口说明这是一个可以对(网络)接口做配置的(编程)接口
class I接口配置模式(I接口配置模式基础): #常见的接口配置
def __init__(self, a, a接口):
I接口配置模式基础.__init__(self, a, a接口)
def fs开关(self, a开关):
raise NotImplementedError()
def fs描述(self, a描述, a操作 = E操作.e设置):
raise NotImplementedError()
def fs网络地址4(self, a地址, a操作 = E操作.e设置):
raise NotImplementedError()
因为(网络)接口命令太多,这段代码只列举几个常用的。
这里有一个 I接口配置模式基础,它是所有(网络)接口配置模式(编程)接口的基类,提供了不同的(网络)接口配置模式(编程)接口都能使用的通用函数,比如进入命令。 I接口配置模式 只提供常用操作,更详细的操作分散在不同的(网络)接口配置模式(编程)接口中,所有的(网络)接口配置模式(编程)接口都要继承 I接口配置模式基础 以保证行为一致以及避免重复代码。
class I接口配置模式基础(I模式): #所有接口配置模式接口的基类
c模式名 = "接口配置模式"
def __init__(self, a设备, a接口):
I模式.__init__(self, a设备)
self.m接口 = a接口
def __eq__(self, a):
if not isinstance(a, I接口配置模式基础):
return False
return self.m接口 == a.m接口
#通用方法
def fg模式参数(self):
return (self.m接口,)
def fg进入命令(self):
return C命令("interface") + self.fg模式参数()
def fg接口(self):
return self.m接口
写完(编程)接口还要写如何创建对象。几乎所有的网络设备都是从全局配置模式进入(网络)接口配置模式,所以我习惯性地把创建(网络)接口配置模式对象的函数放在全局配置模式(编程)接口中。
class I全局配置模式(I模式):
def f模式_接口配置(self, a接口, a操作 = E操作.e设置):
raise NotImplementedError()
其中 a接口 可以是一个 S接口 值,也可以是字符串。如果传了字符串,还要解析成 S接口 值,以便于使用。具体解析过程见下面的解析(网络)接口字符串一节
统一(网络)接口类型值转换成具体(网络)接口名称
上面说到,不同设备,同一种(网络)接口的名称可能不同。生成一个具体设备的具体命令需要把(网络)接口类型值转换成一个准确的名称。这个很好实现,只要写个字典,根据类型值查字典即可。
我以思科设备的接口名称为范本写了一个接口名称字典。
ca接口名称 = {
E接口.e空: "Null",
E接口.e环回: "Loopback",
E接口.e以太网: "Ethernet",
E接口.e快速以太网: "FastEthernet",
E接口.e吉以太网: "GigabitEthernet",
E接口.e十吉以太网: "TenGigabitEthernet",
E接口.e串行: "Serial",
E接口.e虚拟局域网: "Vlan",
E接口.e隧道: "Tunnel"
}
在 S接口 中添加相关函数:
class S接口:
def __str__(self):
if self.m名称:
retu