使用mininet快速入门ONOS路由交换技术与原理-路由篇

上篇文章 《使用mininet快速入门ONOS路由交换技术与原理-交换篇》
使用mininet搭建了一个简单的网络拓扑,并实现了同一交换机下同网段多主机的通信,其中涉及到的通信知识主要以二层mac地址通信为主。

但在芸芸网络的世界中,主机间的通信除了二层域外更多的还是纷繁复杂的三层ip路由通信。

路由协议可分为静态路由协议和动态路由协议,在动态路由协议中,根据路由协议的作用范围主要又分为IGP与EGP。
route-igp-egp

其中EGP中的BGP协议根据其强悍的设计可支撑起各数以亿记的路由条目,同是也是动态路由协议中最为复杂的一个。

本文将结合BGP路由协议,通过onos官方的一个sdnip小示例实现SDN下不同网段多主机的通信。

环境说明

linux系统主机一台(可虚拟机,笔者使用的是ubuntu)

拓扑如下:
top

拓扑说明

  • 一个onos
  • 6个ovs交换机
  • 其中5台交换机各自连一个路由器,且其4台路由器上各自连接一个主机,另一台路由器与onos连通
  • 4个主机处于不同的网段

quagga安装与操作

quagga介绍

由于后续需要模拟外部路由器,这里使用quagga进行模拟。
qugga是一个实现了常用路由协议的软件套件,在进行网络设备模拟时非常有用,其官网地址为:https://www.nongnu.org/quagga
quagga

同时它也是一个开源软件,源码源码地址为:https://github.com/Quagga/quagga

quagga安装

选择一个系统对应的安装方式进行安装,如ubuntu执行下命令直接安装即可:

sudo apt install bridge-utils
#quagga 1.2.4
sudo apt-get install quagga

可选项:

sudo cp /usr/share/doc/quagga-core/examples/zebra.conf.sample /etc/quagga/zebra.conf
sudo cp /usr/share/doc/quagga-core/examples/ospfd.conf.sample /etc/quagga/ospfd.conf
sudo cp /usr/share/doc/quagga-core/examples/zebra.conf.sample /etc/quagga/r1zebra.conf
sudo cp /usr/share/doc/quagga-core/examples/zebra.conf.sample /etc/quagga/r2zebra.conf
sudo cp /usr/share/doc/quagga-core/examples/ospfd.conf.sample /etc/quagga/r1ospfd.conf
sudo cp /usr/share/doc/quagga-core/examples/ospfd.conf.sample /etc/quagga/r2ospfd.conf

可选项:

sudo cp /usr/lib/quagga/* /lib

quagga操作

quagga提供了丰富的配置选项以支持对模拟的路由器进行相应的配置,对应的操作手册地址为:
https://www.nongnu.org/quagga/docs/quagga.html

如要查看bgp路由列表,在进入控制台后输入以下命令查看即可

telnet localhost 2605
show ip bgp

另,为了后续在mininet中可正确使用xterm命令,需要确保已安装xterm工具

sudo apt install xterm

拓扑创建

quagga仿真软件安装就绪后,接下来便可以对整个拓扑创建就可以了。

onos仍然使用docker运行,其余交换机、路由器、主机的创建创建使用自定义的mininet脚本进行创建。

onos与网桥创建

#启动onos,并映射端口(验证:访问8181web界面)
docker run -d -e TZ=Asia/Shanghai -p 6653:6653 -p 8101:8101 -p 8181:8181 --name onos onosproject/onos:2.7.0

创建docker网桥,并指定10.10.10网段

docker network create --subnet 10.10.10.0/24 --ip-range 10.10.10.0/24 --gateway 10.10.10.2 sdnip

让onos容器与docker网桥连接,并分配10.10.10.3地址(验证:主机ping通10.10.10.3)

docker network connect --ip 10.10.10.3 sdnip onos

启动openflow应用

app activate org.onosproject.openflow

定义拓扑脚本

#!/usr/bin/python3

from mininet.cli import CLI
from mininet.log import setLogLevel, info, debug
from mininet.net import Mininet
from mininet.node import Host, RemoteController
from mininet.topo import Topo

QUAGGA_DIR = '/usr/lib/quagga'
# Must exist and be owned by quagga user (quagga:quagga by default on Ubuntu)
# QUAGGA_RUN_DIR = '/var/run/quagga'
QUAGGA_RUN_DIR = '/tmp'
CONFIG_DIR = 'configs'


class SdnIpHost(Host):
    def __init__(self, name, ip, route, *args, **kwargs):
        Host.__init__(self, name, ip=ip, *args, **kwargs)

        self.route = route

    def config(self, **kwargs):
        Host.config(self, **kwargs)

        debug("configuring route %s" % self.route)

        self.cmd('ip route add default via %s' % self.route)


class Router(Host):
    def __init__(self, name, quaggaConfFile, zebraConfFile, intfDict, *args, **kwargs):
        Host.__init__(self, name, *args, **kwargs)

        self.quaggaConfFile = quaggaConfFile
        self.zebraConfFile = zebraConfFile
        self.intfDict = intfDict

    def config(self, **kwargs):
        Host.config(self, **kwargs)
        self.cmd('sysctl net.ipv4.ip_forward=1')

        for intf, attrs in self.intfDict.items():
            self.cmd('ip addr flush dev %s' % intf)
            if 'mac' in attrs:
                self.cmd('ip link set %s down' % intf)
                self.cmd('ip link set %s address %s' % (intf, attrs['mac']))
                self.cmd('ip link set %s up ' % intf)
            for addr in attrs['ipAddrs']:
                self.cmd('ip addr add %s dev %s' % (addr, intf))

        # self.cmd('/usr/lib/quagga/zebra -d -f %s -z %s/zebra%s.api -i %s/zebra%s.pid' % (
        self.cmd('zebra -d -f %s -z %s/zebra%s.api -i %s/zebra%s.pid' % (
        self.zebraConfFile, QUAGGA_RUN_DIR, self.name, QUAGGA_RUN_DIR, self.name))
        # self.cmd('/usr/lib/quagga/bgpd -d -f %s -z %s/zebra%s.api -i %s/bgpd%s.pid' % (
        self.cmd('bgpd -d -f %s -z %s/zebra%s.api -i %s/bgpd%s.pid' % (
        self.quaggaConfFile, QUAGGA_RUN_DIR, self.name, QUAGGA_RUN_DIR, self.name))

    def terminate(self):
        self.cmd("ps ax | egrep 'bgpd%s.pid|zebra%s.pid' | awk '{print $1}' | xargs kill" % (self.name, self.name))

        Host.terminate(self)


class SdnIpTopo(Topo):
    "SDN-IP tutorial topology"

    def build(self):
        s1 = self.addSwitch('s1', dpid='00000000000000a1')
        s2 = self.addSwitch('s2', dpid='00000000000000a2')
        s3 = self.addSwitch('s3', dpid='00000000000000a3')
        s4 = self.addSwitch('s4', dpid='00000000000000a4')
        s5 = self.addSwitch('s5', dpid='00000000000000a5')
        s6 = self.addSwitch('s6', dpid='00000000000000a6')

        zebraConf = '%s/zebra.conf' % CONFIG_DIR

        # Switches we want to attach our routers to, in the correct order
        attachmentSwitches = [s1, s2, s5, s6]

        for i in range(1, 4 + 1):
            name = 'r%s' % i

            eth0 = {'mac': '00:00:00:00:0%s:01' % i,
                    'ipAddrs': ['10.0.%s.1/24' % i]}
            eth1 = {'ipAddrs': ['192.168.%s.254/24' % i]}
            intfs = {'%s-eth0' % name: eth0,
                     '%s-eth1' % name: eth1}

            quaggaConf = '%s/quagga%s.conf' % (CONFIG_DIR, i)

            router = self.addHost(name, cls=Router, quaggaConfFile=quaggaConf,
                                  zebraConfFile=zebraConf, intfDict=intfs)

            host = self.addHost('h%s' % i, cls=SdnIpHost,
                                ip='192.168.%s.1/24' % i,
                                route='192.168.%s.254' % i)

            self.addLink(router, attachmentSwitches[i - 1])
            self.addLink(router, host)

        # Set up the internal BGP speaker
        bgpEth0 = {'mac': '00:00:00:00:00:01',
                   'ipAddrs': ['10.0.1.101/24',
                               '10.0.2.101/24',
                               '10.0.3.101/24',
                               '10.0.4.101/24', ]}
        bgpEth1 = {'ipAddrs': ['10.10.10.1/24']}
        bgpIntfs = {'bgp-eth0': bgpEth0,
                    'bgp-eth1': bgpEth1}

        bgp = self.addHost("bgp", cls=Router,
                           quaggaConfFile='%s/quagga-sdn.conf' % CONFIG_DIR,
                           zebraConfFile=zebraConf,
                           intfDict=bgpIntfs)

        self.addLink(bgp, s3)

        # Connect BGP speaker to the root namespace so it can peer with ONOS
        root = self.addHost('root', inNamespace=False, ip='10.10.10.2/24')
        self.addLink(root, bgp)

        # Wire up the switches in the topology
        self.addLink(s1, s2)
        self.addLink(s1, s3)
        self.addLink(s2, s4)
        self.addLink(s3, s4)
        self.addLink(s3, s5)
        self.addLink(s4, s6)
        self.addLink(s5, s6)


topos = {'sdnip': SdnIpTopo}

if __name__ == '__main__':
    setLogLevel('debug')
    topo = SdnIpTopo()

    net = Mininet(topo=topo, controller=RemoteController)

    net.start()

    CLI(net)

    net.stop()

    info("done\n")

定义一个python3的拓扑,名为tutorial-py3.py。其中定义了所需要的交换机、主机、路由器的link关系。

bgp路由器配置文件

如上面拓扑定义python脚本所示,各bgp路由器还需要读取对应的quagga配置文件,其中描述的对应bgp路由器的bgp配置信息。

quagga1.conf

! BGP configuration for r1
!
hostname r1
password sdnip
!
router bgp 65001
  bgp router-id 10.0.1.1
  timers bgp 3 9
  neighbor 10.0.1.101 remote-as 65000
  neighbor 10.0.1.101 ebgp-multihop
  neighbor 10.0.1.101 timers connect 5
  neighbor 10.0.1.101 advertisement-interval 5
  network 192.168.1.0/24
!
log stdout

quagga2.conf

! BGP configuration for r2
!
hostname r2
password sdnip
!
router bgp 65002
  bgp router-id 10.0.2.1
  timers bgp 3 9
  neighbor 10.0.2.101 remote-as 65000
  neighbor 10.0.2.101 ebgp-multihop
  neighbor 10.0.2.101 timers connect 5
  neighbor 10.0.2.101 advertisement-interval 5
  network 192.168.2.0/24
!
log stdout

quagga3.conf

! BGP configuration for r3
!
hostname r3
password sdnip
!
router bgp 65003
  bgp router-id 10.0.3.1
  timers bgp 3 9
  neighbor 10.0.3.101 remote-as 65000
  neighbor 10.0.3.101 ebgp-multihop
  neighbor 10.0.3.101 timers connect 5
  neighbor 10.0.3.101 advertisement-interval 5
  network 192.168.3.0/24
!
log stdout

quagga4.conf

! BGP configuration for r4
!
hostname r4
password sdnip
!
router bgp 65004
  bgp router-id 10.0.4.1
  timers bgp 3 9
  neighbor 10.0.4.101 remote-as 65000
  neighbor 10.0.4.101 ebgp-multihop
  neighbor 10.0.4.101 timers connect 5
  neighbor 10.0.4.101 advertisement-interval 5
  !network 192.168.4.0/24
!
log stdout

注意,这里的quagga4.conf中并未并192.168.4.0/24网段进行公告

quagga-sdn.conf

!
hostname bgp
password sdnip
!
!
router bgp 65000
  bgp router-id 10.10.10.1
  timers bgp 3 9
  !
  neighbor 10.0.1.1 remote-as 65001
  neighbor 10.0.1.1 ebgp-multihop
  neighbor 10.0.1.1 timers connect 5
  neighbor 10.0.1.1 advertisement-interval 5
  !
  neighbor 10.0.2.1 remote-as 65002
  neighbor 10.0.2.1 ebgp-multihop
  neighbor 10.0.2.1 timers connect 5
  neighbor 10.0.2.1 advertisement-interval 5
  !
  neighbor 10.0.3.1 remote-as 65003
  neighbor 10.0.3.1 ebgp-multihop
  neighbor 10.0.3.1 timers connect 5
  neighbor 10.0.3.1 advertisement-interval 5
  !
  neighbor 10.0.4.1 remote-as 65004
  neighbor 10.0.4.1 ebgp-multihop
  neighbor 10.0.4.1 timers connect 5
  neighbor 10.0.4.1 advertisement-interval 5
  !
  ! ONOS
  neighbor 10.10.10.3 remote-as 65000
  neighbor 10.10.10.3 port 2000
  neighbor 10.10.10.3 timers connect 5
!
log stdout

quagga-sdn.conf为bgp反射器那个路由器的配置,与r1-r4属于ebgp关系,与onos属于ibgp关系。

mininet模拟交换机、路由器、主机

拓扑描述脚本与quagga配置文件准备好后便可启动拓扑了

#启动mininet,连接指定控制器(验证:onos中查看设备是否上线)
sudo mn --custom tutorial-py3.py --topo sdnip --controller remote,172.17.0.2 --nolistenport

拓扑中的设备创建好后,为了能让ibgp通信正常,还需要让bgp-router与onos连通。

找到docker容器10.10.10.3对应的网桥,将root-eth0加入到其中

brctl show
#sdnip网桥中添加root-eth0(验证:bgp与onos能ping通)
sudo brctl addif br-baab72ffcdfc root-eth0

测试连通性,此时是不通的

h1 ping h2

sdn-ip应用与配置

前面的步骤仅完成了拓扑的搭建,拓扑中的节点间还是处于无法通信的状态。
如想要拓扑中的各节点进行正常通信,需要onos下发流表到交换机指导数据包的转发。

此刻sdn-ip的作用便可以发挥出来了,在sdn-ip应用中实现了bgp的协议与路由储存的基本功能,并能通过所学到的route下发对应的intent,最后下发flowRule到交换机中。细节部分此处不详细展开。

sdnip应用启动

#onos集群下需要先启动confgi
app activate org.onosproject.config
#启动sdnip应用
app activate org.onosproject.sdnip

sdnip
待sdnip应用启动后便可以使用routes命令,此时onos中的route列表仍然是空的

sdnIp应用配置

访问onos的http接口,找到network配置项注入配置信息。如访问地址为:
http://172.17.0.2:8181/onos/v1/docs/#!/network47configuration/post_network_configuration

也可使用curl进行更新,如:

curl --user onos:rocks -X POST -H “Content-Type: application/json” http://172.17.0.2:8181/onos/v1/network/configuration/ -d @/home/sdn/sdnip/configs/network-cfg.json

其中传入的配置信息内容如下:

{
    "ports" : {
        "of:00000000000000a1/1" : {
            "interfaces" : [
                {
                    "name" : "sw1-1",
                    "ips"  : [ "10.0.1.101/24" ],
                    "mac"  : "00:00:00:00:00:01"
                }
            ]
        },
        "of:00000000000000a2/1" : {
            "interfaces" : [
                {
                    "name" : "sw2-1",
                    "ips"  : [ "10.0.2.101/24" ],
                    "mac"  : "00:00:00:00:00:01"
                }
            ]
        },
        "of:00000000000000a5/1" : {
            "interfaces" : [
                {
                    "name" : "sw5-1",
                    "ips"  : [ "10.0.3.101/24" ],
                    "mac"  : "00:00:00:00:00:01"
                }
            ]
        },
        "of:00000000000000a6/1" : {
            "interfaces" : [
                {
                    "name" : "sw6-1",
                    "ips"  : [ "10.0.4.101/24" ],
                    "mac"  : "00:00:00:00:00:01"
                }
            ]
        }
    },
    "apps" : {
        "org.onosproject.router" : {
            "bgp" : {
                "bgpSpeakers" : [
                    {
                        "name" : "speaker1",
                        "connectPoint" : "of:00000000000000a3/1",
                        "peers" : [
                            "10.0.1.1",
                            "10.0.2.1",
                            "10.0.3.1",
                            "10.0.4.1"
                        ]
                    }
                ]
            }
        }
    }
}

配置成功后使用interfaces和bgp-speakers命令验证一下
bgp-speakers

连通验证

当sdn-ip应用启动成功后,并且配置了对应的信息后,sdn-ip会执行一系列的操作最终会下发所学到的路由记录到交换机中
intents-s

此时再查看routes信息,发现也学到了路由记录
routes

查看flows信息也可看到由intent所下发的流表项,片段如下:

deviceId=of:00000000000000a1, flowRuleCount=17
    ADDED, bytes=65330, packets=470, table=0, priority=40000, selector=[ETH_TYPE:lldp], treatment=[immediate=[OUTPUT:CONTROLLER], clearDeferred]
    ADDED, bytes=65330, packets=470, table=0, priority=40000, selector=[ETH_TYPE:bddp], treatment=[immediate=[OUTPUT:CONTROLLER], clearDeferred]
    ADDED, bytes=84, packets=2, table=0, priority=40000, selector=[ETH_TYPE:arp], treatment=[immediate=[OUTPUT:CONTROLLER], clearDeferred]
    ADDED, bytes=29699, packets=378, table=0, priority=1000, selector=[IN_PORT:1, ETH_TYPE:ipv4, IP_PROTO:6, IPV4_SRC:10.0.1.1/32, IPV4_DST:10.0.1.101/32, TCP_DST:179], treatment=[immediate=[OUTPUT:3]]
    ADDED, bytes=0, packets=0, table=0, priority=1000, selector=[IN_PORT:1, ETH_TYPE:ipv4, IP_PROTO:1, IPV4_SRC:10.0.1.1/32, IPV4_DST:10.0.1.101/32], treatment=[immediate=[OUTPUT:3]]
    ADDED, bytes=0, packets=0, table=0, priority=1000, selector=[IN_PORT:2, ETH_TYPE:ipv4, IP_PROTO:6, IPV4_SRC:10.0.2.1/32, IPV4_DST:10.0.2.101/32, TCP_SRC:179], treatment=[immediate=[OUTPUT:3]]
    ADDED, bytes=0, packets=0, table=0, priority=1000, selector=[IN_PORT:1, ETH_TYPE:ipv4, IP_PROTO:6, IPV4_SRC:10.0.1.1/32, IPV4_DST:10.0.1.101/32, TCP_SRC:179], treatment=[immediate=[OUTPUT:3]]
    ADDED, bytes=36604, packets=482, table=0, priority=1000, selector=[IN_PORT:3, ETH_TYPE:ipv4, IP_PROTO:6, IPV4_SRC:10.0.1.101/32, IPV4_DST:10.0.1.1/32, TCP_SRC:179], treatment=[immediate=[OUTPUT:1]]
    ADDED, bytes=0, packets=0, table=0, priority=1000, selector=[IN_PORT:2, ETH_TYPE:ipv4, IP_PROTO:1, IPV4_SRC:10.0.2.1/32, IPV4_DST:10.0.2.101/32], treatment=[immediate=[OUTPUT:3]]
    ADDED, bytes=33197, packets=431, table=0, priority=1000, selector=[IN_PORT:2, ETH_TYPE:ipv4, IP_PROTO:6, IPV4_SRC:10.0.2.1/32, IPV4_DST:10.0.2.101/32, TCP_DST:179], treatment=[immediate=[OUTPUT:3]]
    ADDED, bytes=0, packets=0, table=0, priority=1000, selector=[IN_PORT:3, ETH_TYPE:ipv4, IP_PROTO:6, IPV4_SRC:10.0.1.101/32, IPV4_DST:10.0.1.1/32, TCP_DST:179], treatment=[immediate=[OUTPUT:1]]
    ADDED, bytes=0, packets=0, table=0, priority=1000, selector=[IN_PORT:3, ETH_TYPE:ipv4, IP_PROTO:1, IPV4_SRC:10.0.1.101/32, IPV4_DST:10.0.1.1/32], treatment=[immediate=[OUTPUT:1]]
    ADDED, bytes=98, packets=1, table=0, priority=220, selector=[IN_PORT:1, ETH_TYPE:ipv4, IPV4_DST:192.168.3.0/24], treatment=[immediate=[ETH_DST:00:00:00:00:03:01, OUTPUT:3]]
    ADDED, bytes=98, packets=1, table=0, priority=220, selector=[IN_PORT:3, ETH_DST:00:00:00:00:01:01], treatment=[immediate=[OUTPUT:1]]
    ADDED, bytes=196, packets=2, table=0, priority=220, selector=[IN_PORT:2, ETH_DST:00:00:00:00:01:01], treatment=[immediate=[OUTPUT:1]]
    ADDED, bytes=196, packets=2, table=0, priority=220, selector=[IN_PORT:1, ETH_TYPE:ipv4, IPV4_DST:192.168.2.0/24], treatment=[immediate=[ETH_DST:00:00:00:00:02:01, OUTPUT:2]]
    ADDED, bytes=0, packets=0, table=0, priority=220, selector=[IN_PORT:3, ETH_DST:00:00:00:00:02:01], treatment=[immediate=[OUTPUT:2]]
deviceId=of:00000000000000a2, flowRuleCount=14
    ADDED, bytes=65052, packets=468, table=0, priority=40000, selector=[ETH_TYPE:bddp], treatment=[immediate=[OUTPUT:CONTROLLER], clearDeferred]
    ADDED, bytes=84, packets=2, table=0, priority=40000, selector=[ETH_TYPE:arp], treatment=[immediate=[OUTPUT:CONTROLLER], clearDeferred]
    ADDED, bytes=65052, packets=468, table=0, priority=40000, selector=[ETH_TYPE:lldp], treatment=[immediate=[OUTPUT:CONTROLLER], clearDeferred]
    ADDED, bytes=33197, packets=431, table=0, priority=1000, selector=[IN_PORT:1, ETH_TYPE:ipv4, IP_PROTO:6, IPV4_SRC:10.0.2.1/32, IPV4_DST:10.0.2.101/32, TCP_DST:179], treatment=[immediate=[OUTPUT:2]]
    ADDED, bytes=0, packets=0, table=0, priority=1000, selector=[IN_PORT:1, ETH_TYPE:ipv4, IP_PROTO:6, IPV4_SRC:10.0.2.1/32, IPV4_DST:10.0.2.101/32, TCP_SRC:179], treatment=[immediate=[OUTPUT:2]]
    ADDED, bytes=0, packets=0, table=0, priority=1000, selector=[IN_PORT:3, ETH_TYPE:ipv4, IP_PROTO:6, IPV4_SRC:10.0.2.101/32, IPV4_DST:10.0.2.1/32, TCP_DST:179], treatment=[immediate=[OUTPUT:1]]
    ADDED, bytes=0, packets=0, table=0, priority=1000, selector=[IN_PORT:1, ETH_TYPE:ipv4, IP_PROTO:1, IPV4_SRC:10.0.2.1/32, IPV4_DST:10.0.2.101/32], treatment=[immediate=[OUTPUT:2]]
    ADDED, bytes=34822, packets=455, table=0, priority=1000, selector=[IN_PORT:3, ETH_TYPE:ipv4, IP_PROTO:6, IPV4_SRC:10.0.2.101/32, IPV4_DST:10.0.2.1/32, TCP_SRC:179], treatment=[immediate=[OUTPUT:1]]
    ADDED, bytes=0, packets=0, table=0, priority=1000, selector=[IN_PORT:3, ETH_TYPE:ipv4, IP_PROTO:1, IPV4_SRC:10.0.2.101/32, IPV4_DST:10.0.2.1/32], treatment=[immediate=[OUTPUT:1]]
    ADDED, bytes=0, packets=0, table=0, priority=220, selector=[IN_PORT:3, ETH_DST:00:00:00:00:02:01], treatment=[immediate=[OUTPUT:1]]
    ADDED, bytes=196, packets=2, table=0, priority=220, selector=[IN_PORT:1, ETH_TYPE:ipv4, IPV4_DST:192.168.1.0/24], treatment=[immediate=[ETH_DST:00:00:00:00:01:01, OUTPUT:2]]
    ADDED, bytes=196, packets=2, table=0, priority=220, selector=[IN_PORT:2, ETH_DST:00:00:00:00:02:01], treatment=[immediate=[OUTPUT:1]]
    ADDED, bytes=0, packets=0, table=0, priority=220, selector=[IN_PORT:3, ETH_DST:00:00:00:00:01:01], treatment=[immediate=[OUTPUT:2]]
    ADDED, bytes=0, packets=0, table=0, priority=220, selector=[IN_PORT:1, ETH_TYPE:ipv4, IPV4_DST:192.168.3.0/24], treatment=[immediate=[ETH_DST:00:00:00:00:03:01, OUTPUT:3]]
……

此时再在mininet中进行h1 ping h2便会发现可以ping通了,且ttl值也作了对应的减少
pingok

通信过程原理

sdnip可以让以上拓扑通信成功的过程内容稍微有点多,这里从onos官网中拷贝出几张有价值的图例可参考一下:
sdnip1
上图描述了BGP路由记录由routes转为intents,再由intents转为flowRule流表项的大体流程
sdnip-2
上图描述了在BGP网络中,路由传递到SDN-IP的大体过程,主要为由EBGP进行路由汇总。
sdnip-3
以上图描述了在由BGP反射器学到了EBGP的路由后,再由IBGP传递给onos应用sdn-ip的过程。

再总结一下:

通信成功的原理可以参考onos官方wiki中sdnip应用的架构描述部分,主要为在onos配置了bgp信息和interface后下发了
Single-point to single-point intents,实现了bgp各节点的通信;随后在onos学到了bgp路由信息后向交换机下发了
Multi-point to single-point intents,实现了各主机间的通信。

新增ebgp节点路由公告

上面实现了h1、h2、h3这3个主机间的互相通信,但h4还没有通,这是因为在r4路由器的bgp配置中未将192.168.4.0/24网段公告出去,也就导致onos不能通过ibgp学到r4路由器的主机路由信息。
此时想要让r4能通在r4的路由器修改配置使其生效即可。

操作如下:

xterm r4
在弹出的r4界面中登录bgp路由器cli

#login bgp router,passwd: sdnip
telnet localhost 2605

并配置如下:

r4> enable
r4# configure terminal
r4(config)# router bgp 65004
r4(config-router)# network 192.168.4.0/24
r4(config-router)# exit
r4(config)# exit
r4# exit
Connection closed by foreign host.

quagga-cli

之后再ping就可以通了
pingh4ok

最终的路由记录与intent信息如下:
routes-intents

最后再来个拓扑图回忆一下:

onos-top

参考资料

  • https://wiki.onosproject.org/display/ONOS/Basic+ONOS+Tutorial#BasicONOSTutorial-Introduction
  • https://wiki.onosproject.org/display/ONOS/SDN-IP+Architecture
  • quagga+mininet ospf
  • https://medium.com/@sreejithkj52/onos-tutorial-with-mininet-part-2-ed1b30582da0
  • https://wiki.onosproject.org/display/ONOS/SDN-IP+Reactive+Routing
  • https://wiki.onosproject.org/display/ONOS/vRouter
  • https://github.com/ralvarep/ONOS-SDN-IP/blob/master/scenario_1/README.md
  • https://wiki.onosproject.org/display/ONOS/Intent+Framework
  • https://wiki.onosproject.org/display/ONOS/SDN-IP+Deployment+Guidelines

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/418713.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Education Codeforces Round 162(Div.2) A~E

A.Moving Chips (思维) 题意: 给一个长度为 n n n的数组 a a a, a i 1 a_i1 ai​1或者 a i 0 a_i0 ai​0,现在可以选择一个 1 1 1,然后将其与左侧最近的 0 0 0交换。询问使得所有的 1 1 1连在一起,中间没有 0 0 0…

Vue+SpringBoot打造不良邮件过滤系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统用户模块2.2 收件箱模块2.3 发件箱模块2.4 垃圾箱模块2.5 回收站模块2.6 邮箱过滤设置模块 三、实体类设计3.1 系统用户3.2 邮件3.3 其他实体 四、系统展示五、核心代码5.1 查询收件箱档案5.2 查询回收站档案5.3 新…

js 面试 1判断变量是否是数组 2 检测数据类型方法

1 是否是数组 1) typeof 检测数据类型运算符 优点:使用简单 缺点:只能检测基本类型(除null外) console.log(typeof(10)) //Number console.log(typeof(false)) //boolean console.log(typeof(hello)) //string console.log(typeof…

LeetCode 刷题 [C++] 第236题.二叉树的最近公共祖先

题目描述 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以…

【网络编程】理解客户端和服务器并使用Java提供的api实现回显服务器

目录 一、网络编程 二、客户端和服务器 三、客户端和服务器的交互模式 四、TCP 和 UDP UDP socket api 的使用 1、DatagramSoket 2、DatagramPacket TCP socket api 的使用 1、ServerSocket 2、Socket 一、网络编程 本质上就是学习传输层给应用层提供的 api&#x…

MySQL之事务详解

华子目录 什么是事务银行转账案例方式1方式2具体操作 事务的四大特性并发事务问题脏读不可重复读幻读 事务的隔离级别查看事务隔离级别设置事务隔离级别 session与global的区别 什么是事务 事务(transaction),一个最小的不可再分的工作单元&…

实例:NX二次开发抽取平面以及标准柱面中心线

一、概述 最近体验许多外挂,包括胡波外挂、星空外挂及模圣等都有抽取面的中心线,由于刚刚学习,我尝试看看能不能做出来,本博客代码没有封装函数,代码有待改进,但基本可以实现相应的功能。 二、案例实现的功…

Sora 原理与技术实战笔记一

b 站视频合集 【AIX组队学习】Sora原理与技术实战:Sora技术路径详解 Sora 技术报告(OpenAI) huggingsd 文生图视频系列的一个开源项目 最强视频生成模型Sora相关技术解析 https://github.com/lichao-sun/SoraReview 惊艳效果: 长…

Ps:路径面板

Ps菜单:窗口/路径 Window/Paths “路径”面板 Paths Panel提供了一系列功能,使用户能够创建、编辑、保存和利用路径。 ◆ ◆ ◆ 路径分类 在“路径”面板上的路径可分为五大类。 常规路径 Saved Path 也称“已保存的路径”,指的是已经存储在…

Python进阶学习:Pandas--DataFrame--如何把几列数据合并成新的一列

Python进阶学习:Pandas–DataFrame–如何把几列数据合并成新的一列 🌈 个人主页:高斯小哥 🔥 高质量专栏:Matplotlib之旅:零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1…

SpringMVC的配置2种(本质上还是一样的,实现的接口不同)

第一种SpringInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer 看第一种配置 package com.xxx.config; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; public class SpringInitConfig ext…

减少页面加载时间:提升用户体验的关键

✨✨ 祝屏幕前的您天天开心,每天都有好运相伴。我们一起加油!✨✨ 🎈🎈作者主页: 喔的嘛呀🎈🎈 目录 引言 一、为什么页面加载时间重要? 二、如何减少页面加载时间? …

Google发布Genie硬杠Sora:通过大量无监督视频训练最终生成可交互虚拟世界

前言 Sora 问世才不到两个星期,谷歌的世界模型也来了,能力看似更强大(嗯,看似):它生成的虚拟世界自主可控 第一部分 首个基础世界模型Genie 1.1 Genie是什么 Genie是第一个以无监督方式从未标记的互联网视频中训练的生成式交互…

UDP数据报套接字编程入门

目录 1.TCP和UDP的特点及区别 1.1TCP的特点 1.2UDP的特点 1.3区别 2.UDP Socket的api的介绍 2.1DatagramSocket API 2.2DatagramPacket API 3.回显客户端与服务器 3.1回显服务器 3.1.1UdpEchoServer类的创建 3.1.2服务器的运行方法start() 3.1.3main部分 3.1.4.完整…

nginx反向代理之缓存 客户端IP透传 负载均衡

一 缓存功能 缓存功能可以加速访问,如果没有缓存关闭后端服务器后,图片将无法访问,缓存功能默认关闭,需要开启。 相关选项: ​ proxy_cache zone_name | off; 默认off #指明调用的缓存,或关闭缓存机制;C…

【C++初阶】第四站:类和对象(下)(理解+详解)

前言: 本篇知识点:初始化列表、explicit关键字、static成员、友元、内部类、匿名对象、编译器的优化 专栏:C初阶 目录 再谈构造函数 1️⃣构造函数体赋值 2️⃣初始化列表 explicit关键字 static成员 1.static概念 2.static特性 面试…

Docker技术概论(4):Docker CLI 基本用法解析

Docker技术概论(4) Docker CLI 基本用法解析 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at: https://jclee95.blog.csdn.netMy WebSite:http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:http…

NC65 零预算控制规则 数据库表关系

NC65 零预算控制规则 数据库表关系 SELECT t1.createdby, t1.objname, t2.ctrlname, t2.pk_parent, t3.billtype, t3.nameidx, t3.pk_obj FROM tb_rule_formula t1 left join tb_ctrlformula t2 on t1.pk_obj t2.pk_parent left join tb_ctrlscheme t3 on t3.pk_ctrlformula …

Mysql安装教程

一、下载 点开下面的链接:https://dev.mysql.com/downloads/mysql/ 点击Download 就可以下载对应的安装包了, 安装包如下: 二、解压 下载完成后我们得到的是一个压缩包,将其解压,我们就可以得到MySQL 8.0.31 的软件本体了(就是一个文件夹…

Tomcat布署及优化-----JDK和Tomcat

1.Tomcat简介 Tomcat 是 Java 语言开发的,Tomcat 服务器是一个免费的开放源代码的 Web 应用服务器,Tomcat 属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试 JSP 程序的首选。一般来说&…