SRv6项目实践(一):环境与工具介绍
在一切开始之前,首先介绍一下我们要做什么,做这个要有什么基础,以及实现的环境
1,实验目标与实验基础
我们要在图下图所示的拓扑中,完成在如以下拓扑所示的网络中,配合ONOS实现基本的L2L3转发以及SRv6,项目总体实现功能较为复杂,因此分为多张准备。
本项目要求的基础:Python、Java、P4\\P4runtime、ONOS、YANG以及基本的网络协议
2,实验环境与工具
2.1数据平面的拓扑
首先,给大家看一下完整的代码,有几个重要的角色:
-
IPv6Host:这是一个支持IPv6的主机,主要实现了一个ip地址更新的功能,并继承了mininet的Host类,config函数主要是完成对它的超类属性的配置和额外属性的配置
-
TutorialTopo:实验拓扑图,就是如上图所示的那个图,定义了两个叶交换机和两个脊交换机,并增设链路,然后给各个主机赋予配置
-
主函数:创建一个Mininet网络,开启它的cli
import argparsefrom mininet.cli import CLI
from mininet.log import setLogLevel
from mininet.net import Mininet
from mininet.node import Host
from mininet.topo import Topo
from stratum import StratumBmv2SwitchCPU_PORT = 255class IPv6Host(Host):"""Host that can be configured with an IPv6 gateway (default route)."""def config(self, ipv6, ipv6_gw=None, params):super(IPv6Host, self).config(params)self.cmd('ip -4 addr flush dev %s' % self.defaultIntf())self.cmd('ip -6 addr flush dev %s' % self.defaultIntf())self.cmd('ip -6 addr add %s dev %s' % (ipv6, self.defaultIntf()))if ipv6_gw:self.cmd('ip -6 route add default via %s' % ipv6_gw)# Disable offloadfor attr in ["rx", "tx", "sg"]:cmd = "/sbin/ethtool --offload %s %s off" % (self.defaultIntf(), attr)self.cmd(cmd)def updateIP():return ipv6.split('/')[0]self.defaultIntf().updateIP = updateIPdef terminate(self):super(IPv6Host, self).terminate()class TutorialTopo(Topo):"""2x2 fabric topology with IPv6 hosts"""def __init__(self, *args, kwargs):Topo.__init__(self, *args, kwargs)# Leaves# gRPC port 50001leaf1 = self.addSwitch('leaf1', cls=StratumBmv2Switch, cpuport=CPU_PORT)# gRPC port 50002leaf2 = self.addSwitch('leaf2', cls=StratumBmv2Switch, cpuport=CPU_PORT)# Spines# gRPC port 50003spine1 = self.addSwitch('spine1', cls=StratumBmv2Switch, cpuport=CPU_PORT)# gRPC port 50004spine2 = self.addSwitch('spine2', cls=StratumBmv2Switch, cpuport=CPU_PORT)# Switch Linksself.addLink(spine1, leaf1)self.addLink(spine1, leaf2)self.addLink(spine2, leaf1)self.addLink(spine2, leaf2)# IPv6 hosts attached to leaf 1h1a = self.addHost('h1a', cls=IPv6Host, mac="00:00:00:00:00:1A",ipv6='2001:1:1::a/64', ipv6_gw='2001:1:1::ff')h1b = self.addHost('h1b', cls=IPv6Host, mac="00:00:00:00:00:1B",ipv6='2001:1:1::b/64', ipv6_gw='2001:1:1::ff')h1c = self.addHost('h1c', cls=IPv6Host, mac="00:00:00:00:00:1C",ipv6='2001:1:1::c/64', ipv6_gw='2001:1:1::ff')h2 = self.addHost('h2', cls=IPv6Host, mac="00:00:00:00:00:20",ipv6='2001:1:2::1/64', ipv6_gw='2001:1:2::ff')self.addLink(h1a, leaf1) # port 3self.addLink(h1b, leaf1) # port 4self.addLink(h1c, leaf1) # port 5self.addLink(h2, leaf1) # port 6# IPv6 hosts attached to leaf 2h3 = self.addHost('h3', cls=IPv6Host, mac="00:00:00:00:00:30",ipv6='2001:2:3::1/64', ipv6_gw='2001:2:3::ff')h4 = self.addHost('h4', cls=IPv6Host, mac="00:00:00:00:00:40",ipv6='2001:2:4::1/64', ipv6_gw='2001:2:4::ff')self.addLink(h3, leaf2) # port 3self.addLink(h4, leaf2) # port 4def main():net = Mininet(topo=TutorialTopo(), controller=None)net.start()CLI(net)net.stop()print '#' * 80print 'ATTENTION: Mininet was stopped! Perhaps accidentally?'print 'No worries, it will restart automatically in a few seconds...'print 'To access again the Mininet CLI, use `make mn-cli`'print 'To detach from the CLI (without stopping), press Ctrl-D'print 'To permanently quit Mininet, use `make stop`'print '#' * 80if __name__ == "__main__":parser = argparse.ArgumentParser(description='Mininet topology script for 2x2 fabric with stratum_bmv2 and IPv6 hosts')args = parser.parse_args()setLogLevel('info')main()
2.2实验工具
其次介绍一下项目的工具,虽然很枯燥,但是一定要看:
M ake command |
Description |
---|---|
make deps |
build 所有需要的依赖 |
make p4-build |
build P4程序 |
make p4-test |
运用p4测试 |
make start |
主角:创建Mininet网络和创建ONOS容器 |
make stop |
关闭所有容器 |
make restart |
重新打开先前创建的容器 |
make onos-cli |
进入ONOS-cli的命令行 |
make onos-log |
显示onos的日志信息 |
make mn-cli |
进入mininet的命令行 |
make mn-log |
显示mininet的日志信息 |
make app-build |
build onos的APP |
make app-reload |
装载APP到onos上 |
make netcfg |
把网络配置文件装载到onos上 |
其中start的打开一看,实际上就是区分不同的拓扑的py脚本,然后在后台创建所有容器。
_start:$(info * Starting ONOS and Mininet (${NGSDN_TOPO_PY})... )@mkdir -p tmp/onos@NGSDN_TOPO_PY=${NGSDN_TOPO_PY} docker-compose up -dstart: NGSDN_TOPO_PY := topo-v6.py
start: _start
yml文件如下所示:
- 可以看到,两个服务的镜像分别是opennetworking/ngsdn-tutorial:stratum_bmv2,传参是刚才的拓扑文件
- 和onosproject/onos:2.2.2,有一个关键的links:- mininet,可以将mininet的ip记录到onos中,这样就可以访问到它,实际上这里的ip都是127.0.0.1
version: "3"services:mininet:image: opennetworking/ngsdn-tutorial:stratum_bmv2hostname: mininetcontainer_name: mininetprivileged: truetty: truestdin_open: truerestart: alwaysvolumes:- ./tmp:/tmp- ./mininet:/mininetports:- "50001:50001"- "50002:50002"- "50003:50003"- "50004:50004"# NGSDN_TOPO_PY is a Python-based Mininet script defining the topology. Its# value is passed to docker-compose as an environment variable, defined in# the Makefile.entrypoint: "/mininet/${NGSDN_TOPO_PY}"onos:image: onosproject/onos:2.2.2hostname: onoscontainer_name: onosports:- "8181:8181" # HTTP- "8101:8101" # SSH (CLI)volumes:- ./tmp/onos:/root/onos/apache-karaf-4.2.8/data/tmpenvironment:- ONOS_APPS=gui2,drivers.bmv2,lldpprovider,hostproviderlinks:- mininet
环境介绍完了,接下来开始第一个实验吧!