SRv6项目实践(一):环境与工具介绍

在一切开始之前,首先介绍一下我们要做什么,做这个要有什么基础,以及实现的环境

1,实验目标与实验基础

我们要在图下图所示的拓扑中,完成在如以下拓扑所示的网络中,配合ONOS实现基本的L2L3转发以及SRv6,项目总体实现功能较为复杂,因此分为多张准备。

本项目要求的基础:Python、Java、P4\P4runtime、ONOS、YANG以及基本的网络协议

SRv6项目实践(一):环境与工具介绍_第1张图片

2,实验环境与工具

2.1数据平面的拓扑

首先,给大家看一下完整的代码,有几个重要的角色:

  • IPv6Host:这是一个支持IPv6的主机,主要实现了一个ip地址更新的功能,并继承了mininet的Host类,config函数主要是完成对它的超类属性的配置和额外属性的配置

  • TutorialTopo:实验拓扑图,就是如上图所示的那个图,定义了两个叶交换机和两个脊交换机,并增设链路,然后给各个主机赋予配置

  • 主函数:创建一个Mininet网络,开启它的cli

import argparse

from 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 StratumBmv2Switch

CPU_PORT = 255


class 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 offload
        for 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 = updateIP

    def 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 50001
        leaf1 = self.addSwitch('leaf1', cls=StratumBmv2Switch, cpuport=CPU_PORT)
        # gRPC port 50002
        leaf2 = self.addSwitch('leaf2', cls=StratumBmv2Switch, cpuport=CPU_PORT)

        # Spines
        # gRPC port 50003
        spine1 = self.addSwitch('spine1', cls=StratumBmv2Switch, cpuport=CPU_PORT)
        # gRPC port 50004
        spine2 = self.addSwitch('spine2', cls=StratumBmv2Switch, cpuport=CPU_PORT)

        # Switch Links
        self.addLink(spine1, leaf1)
        self.addLink(spine1, leaf2)
        self.addLink(spine2, leaf1)
        self.addLink(spine2, leaf2)

        # IPv6 hosts attached to leaf 1
        h1a = 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 3
        self.addLink(h1b, leaf1)  # port 4
        self.addLink(h1c, leaf1)  # port 5
        self.addLink(h2, leaf1)  # port 6

        # IPv6 hosts attached to leaf 2
        h3 = 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 3
        self.addLink(h4, leaf2)  # port 4


def main():
    net = Mininet(topo=TutorialTopo(), controller=None)
    net.start()
    CLI(net)
    net.stop()
    print '#' * 80
    print '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 '#' * 80


if __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 -d

start: 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_bmv2
    hostname: mininet
    container_name: mininet
    privileged: true
    tty: true
    stdin_open: true
    restart: always
    volumes:
      - ./tmp:/tmp
      - ./mininet:/mininet
    ports:
      - "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.2
    hostname: onos
    container_name: onos
    ports:
      - "8181:8181" # HTTP
      - "8101:8101" # SSH (CLI)
    volumes:
      - ./tmp/onos:/root/onos/apache-karaf-4.2.8/data/tmp
    environment:
      - ONOS_APPS=gui2,drivers.bmv2,lldpprovider,hostprovider
    links:
      - mininet

环境介绍完了,接下来开始第一个实验吧!

你可能感兴趣的:(网络,网络协议)