基于OVS的VLAN虚拟化简易实践方案

基于OVS的VLAN虚拟化简易实践方案

前言

本实验基于ovs的vlan流表匹配,根据端口进行vlan标签插入。手工配置ovs,使其具有vlan虚拟化方案。

实验拓扑

 ----                                               ----
| h1 |----    ----------         ----------    ----| h4 |
 ----    |__1|          |       |		   |1__|    ----
 ----        |			|		|          |        ----
| h2 |------2|	  s1 	|4-----4|    s2    |2------| h5 |
 ----     __3|			|		|          |3__     ----
 ----    |   |			|		|          |   |    ----
| h3 |----    ----------         ----------    ----| h6 |
 ----                                               ----

实验目标

在给定实验拓扑情况下,用vlan得到下列虚拟网段

  • h1--h4为一个vlan_id 0 网段
  • h2--h5为一个vlan_id 1 网段
  • h3--h6为一个vlan_id 2 网段

实验工具

  • mininet
  • 控制器RYU
  • OVS

实验过程

实验拓扑的搭建

from mininet.topo import Topo

class MyTopo(Topo):

    def __init__(self):

        # initilaize topology
        Topo.__init__(self)

        # add hosts and switches
        host1 = self.addHost('h1')
        host2 = self.addHost('h2')
        host3 = self.addHost('h3')
        host4 = self.addHost('h4')
        host5 = self.addHost('h5')
        host6 = self.addHost('h6')

        switch1 = self.addSwitch('s1')
        switch2 = self.addSwitch('s2')
        # add links
        self.addLink(host1, switch1, 1, 1)
        self.addLink(host2, switch1, 1, 2)
        self.addLink(host3, switch1, 1, 3)
        self.addLink(switch1, switch2, 4, 4)
        self.addLink(host4, switch2, 1, 1)
        self.addLink(host5, switch2, 1, 2)
        self.addLink(host6, switch2, 1, 3)

topos = {'mytopo': (lambda: MyTopo())}

mininet的启用

sudo mn --custom your_topo.py --topo mytopo --mac --switch ovsk,protocols=OpenFlow13 --controller remote 

ryu收集数据包的应用及启动(可以帮忙做debug)

#-*- coding: UTF-8 -*-
from ryu.base import app_manager
from ryu.controller import ofp_event
from ryu.controller.handler import CONFIG_DISPATCHER, MAIN_DISPATCHER
from ryu.controller.handler import set_ev_cls
from ryu.ofproto import ofproto_v1_3
from ryu.lib.packet import packet
from ryu.lib.packet import ethernet
from ryu.lib.packet import ether_types
import logging

class PeiQiaoWang_controller(app_manager.RyuApp):
    OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]

    def __init__(self, *args, **kwargs):
        super(PeiQiaoWang_controller, self).__init__(*args, **kwargs)

    @set_ev_cls(ofp_event.EventOFPFeaturesRequest)
    def switch_features_handle(self, ev):
        logging.debug("ing")
        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        print msg, datapath, ofproto, parser

    #handshake系列

    #OFPFeaturesRequest_由控制器发送

    #OFPSwitchFeatures
    @set_ev_cls(ofp_event.EventOFPSwitchFeatures)
    def switch_switch_feature_handle(self, ev):
        print "go"
        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        print "msg=", msg
        # print "msg.datapath_id=", msg.datapath_id
        # print "datapath=", datapath
        # print "ofproto=", ofproto
        # print "parser=", parser

    #Switch Configuration系列

    #OFPSetConfig



    @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
    def packet_in_handle(self, ev):
        logging.info("packetin")
        msg = ev.msg
        print ev.msg
        in_port = msg.match['in_port']
        pkt = packet.Packet(msg.data)
        print pkt.protocols
        print type(pkt.protocols)
        # print pkt.data
        # print type(pkt.data)
        # print pkt.ethernet.dst_ip
        print type(pkt[1])

启动:ryu-manage --obeserve-links ./your_app.py

OVS流表手动下发

s1:

sudo ovs-ofctl -O OpenFlow13 add-flow s1 priority=1,in_port=1,actions=push_vlan:0x8100,set_field:4096-\>vlan_vid,output:4
sudo ovs-ofctl -O OpenFlow13 add-flow s1 priority=1,in_port=2,actions=push_vlan:0x8100,set_field:4097-\>vlan_vid,output:4
sudo ovs-ofctl -O OpenFlow13 add-flow s1 priority=1,in_port=3,actions=push_vlan:0x8100,set_field:4098-\>vlan_vid,output:4
sudo ovs-ofctl -O OpenFlow13 add-flow s1 priority=1,dl_vlan=0,actions=pop_vlan,output:1
sudo ovs-ofctl -O OpenFlow13 add-flow s1 priority=1,dl_vlan=1,actions=pop_vlan,output:2
sudo ovs-ofctl -O OpenFlow13 add-flow s1 priority=1,dl_vlan=2,actions=pop_vlan,output:3
sudo ovs-ofctl -O OpenFlow13 add-flow s1 priority=0,actions=output:controller

s2:

sudo ovs-ofctl -O OpenFlow13 add-flow s2 priority=1,in_port=1,actions=push_vlan:0x8100,set_field:4096-\>vlan_vid,output:4
sudo ovs-ofctl -O OpenFlow13 add-flow s2 priority=1,in_port=2,actions=push_vlan:0x8100,set_field:4097-\>vlan_vid,output:4
sudo ovs-ofctl -O OpenFlow13 add-flow s2 priority=1,in_port=3,actions=push_vlan:0x8100,set_field:4098-\>vlan_vid,output:4
sudo ovs-ofctl -O OpenFlow13 add-flow s2 priority=1,dl_vlan=0,actions=pop_vlan,output:1
sudo ovs-ofctl -O OpenFlow13 add-flow s2 priority=1,dl_vlan=1,actions=pop_vlan,output:2
sudo ovs-ofctl -O OpenFlow13 add-flow s2 priority=1,dl_vlan=2,actions=pop_vlan,output:3
sudo ovs-ofctl -O OpenFlow13 add-flow s2 priority=0,actions=output:controller

tip:

上述流表有一个较坑的地方,就是下发添加vlan标签的地方。我们可以看一下vlan标签的构造:

而我们的下发的流表

sudo ovs-ofctl -O OpenFlow13 add-flow s2 priority=1,in_port=1,actions=push_vlan:0x8100,set_field:4096-\>vlan_vid,output:4set_field确是指定的4096

原因:其实这里的set_field的值是设置TCI的值,并不是VLAN ID的值,4096其实它的VLAN ID就为0,其中CFI位要置位1,这是由于OVS规定该位一定要为1,而OpenFlow标准并没有指示,其为一个保留字段,但是也有很多OpenFlow交换机指定了该位一定要为1才能生效。

实验结果

可观察得mininet中的pingall情况

ryu中收到的未匹配的包情况,收到了几个莫名其妙的ipv6包,我也迷茫

实验总结

感受到了普通网工,一台台机器配置过去的麻烦。

posted @ 2017-03-14 20:09  考拉小无  阅读(1483)  评论(0编辑  收藏  举报