美文网首页
openflow的初步认识及RYU控制器实践

openflow的初步认识及RYU控制器实践

作者: 严炎2016 | 来源:发表于2016-04-27 21:34 被阅读0次

    拓扑图如下:

    无控制器下的openflow流表下发演示

    创建一个交换机,3台主机,无控制器,流表手工下发:

    # mn --topo single,3 --controller=none --mac

    mininet>sh ovs-ofctl add-flow s1 "table=0,dl_dst=00:00:00:00:00:01,dl_type=0x0800,actions=output:1"

    mininet>sh ovs-ofctl add-flow s1 "table=0,dl_dst=00:00:00:00:00:02,dl_type=0x0800,actions=output:2"

    mininet>sh ovs-ofctl add-flow s1 "table=0,dl_dst=00:00:00:00:00:03,dl_type=0x0800,actions=output:3"

    mininet>sh ovs-ofctl add-flow s1 "table=0,priority=100,dl_type=0x0806,actions=flood"

    有控制器下的演示:

    用RYU作控制器:

    [root@localhost~]# ryu-manager simple_controller.py

    [root@localhost~]# mn --topo single,3  --mac  --controller=remote,ip=127.0.0.1,port=6633

    mininet> h1 ping h2 -c2

    PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.

    64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.049 ms

    64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.061 ms

    --- 10.0.0.2 ping statistics ---

    2 packets transmitted, 2 received, 0% packet loss, time 1004ms

    rtt min/avg/max/mdev = 0.049/0.055/0.061/0.006 ms

    mininet>

    mininet> sh ovs-ofctl dump-flows  s1

    NXST_FLOW reply (xid=0x4):

    cookie=0x0, duration=2067.822s, table=0, n_packets=142, n_bytes=5964, idle_age=5, priority=100,arp actions=FLOOD

    cookie=0x0, duration=2066.811s, table=0, n_packets=1934, n_bytes=189532, idle_age=0, priority=10,ip,dl_dst=00:00:00:00:00:02 actions=output:2

    cookie=0x0, duration=2065.819s, table=0, n_packets=1949, n_bytes=191002, idle_age=0, priority=10,ip,dl_dst=00:00:00:00:00:01 actions=output:1

    cookie=0x0, duration=185.310s, table=0, n_packets=17, n_bytes=1666, idle_age=168, priority=10,ip,dl_dst=00:00:00:00:00:03 actions=output:3

    cookie=0x0, duration=194.586s, table=0, n_packets=10, n_bytes=756, idle_age=185, priority=0 actions=CONTROLLER:65535

    控制器代码如下:

    [root@localhost~]# cat simple_controller.py

    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.ofproto import ofproto_v1_3_parser

    from ryu.lib.packet import packet

    from ryu.lib.packet import ethernet,arp,ipv4

    from ryu.lib.packet import ether_types

    from ryu.lib.packet import ipv4

    from ryu.topology import switches

    from ryu.topology.event import EventSwitchEnter, EventSwitchLeave

    mac2port = { "00:00:00:00:00:01":1,

    "00:00:00:00:00:02":2,

    "00:00:00:00:00:03":3,

    }

    class SimpleSwitch13(app_manager.RyuApp):

    OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]

    def __init__(self, *args, **kwargs):

    super(SimpleSwitch13, self).__init__(*args, **kwargs)

    self.mac_to_port = {}

    @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)

    def switch_features_handler(self, ev):

    datapath = ev.msg.datapath

    ofproto = datapath.ofproto

    parser = datapath.ofproto_parser

    table_id = 0

    match = parser.OFPMatch()

    actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER,

    ofproto.OFPCML_NO_BUFFER)]

    self.add_flow(datapath, table_id, 0, match, actions)

    def add_flow(self, datapath, table_id ,priority, match, actions, buffer_id=None):

    ofproto = datapath.ofproto

    parser = datapath.ofproto_parser

    inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)]

    if buffer_id:

    mod = parser.OFPFlowMod(datapath=datapath, table_id = table_id, command=ofproto.OFPFC_ADD, buffer_id=buffer_id,

    priority=priority, match=match, instructions=inst)

    else:

    mod = parser.OFPFlowMod(datapath=datapath, table_id = table_id, command=ofproto.OFPFC_ADD, priority=priority,

    match=match, instructions=inst)

    datapath.send_msg(mod)

    def init_flow(self, datapath, table_id, priority, match, inst):

    """Create OFP flow mod message."""

    ofproto = datapath.ofproto

    out  = datapath.ofproto_parser.OFPFlowMod(datapath=datapath,

    table_id=table_id,

    command=ofproto.OFPFC_ADD,

    priority=priority,

    match=match,

    instructions=inst)

    datapath.send_msg(out)

    @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)

    def _packet_in_handler(self, ev):

    # If you hit this you might want to increase

    # the "miss_send_length" of your switch

    if ev.msg.msg_len < ev.msg.total_len:

    self.logger.debug("packet truncated: only %s of %s bytes",

    ev.msg.msg_len, ev.msg.total_len)

    msg = ev.msg

    datapath = msg.datapath

    ofproto = datapath.ofproto

    parser = datapath.ofproto_parser

    in_port = msg.match['in_port']

    pkt = packet.Packet(msg.data)

    eth = pkt.get_protocols(ethernet.ethernet)[0]

    dst_mac = eth.dst

    src_mac = eth.src

    dpid = datapath.id

    print eth.ethertype

    self.logger.info("packet in %s %s %s %s", dpid, src_mac, dst_mac, in_port)

    if eth.ethertype == ether_types.ETH_TYPE_ARP:

    dst_ip = pkt.get_protocol(arp.arp).dst_ip

    src_ip = pkt.get_protocol(arp.arp).src_ip

    out_port = ofproto.OFPP_FLOOD

    table_id =  0

    match = parser.OFPMatch(eth_type=0x0806)

    actions =[parser.OFPActionOutput(out_port)]

    inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,actions)]

    self.init_flow(datapath, table_id, 100, match, inst)

    if eth.ethertype == ether_types.ETH_TYPE_IP:

    out_port = mac2port[dst_mac]

    table_id = 0

    match = parser.OFPMatch(eth_type=0x0800,eth_dst = dst_mac)

    actions =[parser.OFPActionOutput(out_port)]

    inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,actions)]

    self.init_flow(datapath, table_id, 10, match, inst)

    相关文章

      网友评论

          本文标题:openflow的初步认识及RYU控制器实践

          本文链接:https://www.haomeiwen.com/subject/oxrxrttx.html