mininet(三)简单的NAT实验

mininet(一)实验环境搭建
mininet(二)简单的路由实验
mininet(三)简单的NAT实验

本次实验拓扑图如下:
这里写图片描述
假设 Openvswitch switch1是一个带有NAT功能的路由器,H1 的IP地址为 192.168.1.10,MAC地址为:00:00:00:00:00:01, H2 的IP地址为 10.0.0.1 MAC 地址为 00:00:00:00:00:02。私有网络的默认网关为: 192.168.1.1。公网默认网关为: 10.0.0.2。 在H1发送IP报文给H2的时候首先会发送ARP报文查询192.168.1.1的MAC地址,需要OpenVswitch发送 ARP回复报文给H1,H1收到网关的MAC后会将报文发送给switch。

nat.py

#!/usr/bin/python

from mininet.net import Mininet
from mininet.node import Controller, RemoteController, OVSKernelSwitch
from mininet.link import Link, TCLink
from mininet.cli import CLI
from mininet.log import setLogLevel

def topology():
    net = Mininet( controller=RemoteController, link=TCLink, switch=OVSKernelSwitch )
    print "*** Creating nodes"
    h1 = net.addHost( 'h1', mac='00:00:00:00:00:01', ip='192.168.1.10/24' )
    h2 = net.addHost( 'h2', mac='00:00:00:00:00:02', ip='10.0.0.1/24' )
    s1 = net.addSwitch( 's1', protocols='OpenFlow10', listenPort=6673)
    c1 = net.addController( 'c1', ip='127.0.0.1', port=6633 )

    print "*** Creating links"
    net.addLink(h1, s1)
    net.addLink(h2, s1)

    print "*** Starting network"
    net.build()
    c1.start()
    s1.start( [c1] )

    print "*** Running CLI"
    h1.cmd("ip route add default via 192.168.1.1 dev h1-eth0")
    h2.cmd("ip route add default via 10.0.0.2 dev h2-eth0")
    CLI( net )

    print "*** Stopping network"
    net.stop()

if __name__ == '__main__':
    setLogLevel( 'info' )
    topology()

mypox.py

#!/usr/bin/python

from pox.core import core
from pox.lib.addresses import IPAddr
from pox.lib.addresses import EthAddr
import pox.openflow.libopenflow_01 as of
from pox.lib.util import dpid_to_str, str_to_bool
from pox.lib.packet.arp import arp
from pox.lib.packet.ethernet import ethernet, ETHER_BROADCAST

log = core.getLogger()

#flow2:
switch2 = 0000000000000001
flow2msg = of.ofp_flow_mod(command=0) #add flow rules
flow2msg.cookie = 0
flow2msg.match.in_port = 1 # match in port,the index of the switch
flow2msg.match.dl_type = 0x0800 # match ipv4 protcol
flow2msg.match.nw_src = IPAddr("192.168.1.10") # match src ip 192.168.1.10

# ACTIONS---------------------------------
flow2out = of.ofp_action_output (port = 2)
flow2srcIP = of.ofp_action_nw_addr.set_src(IPAddr("10.0.0.2")) # set src ip to 10.0.0.2
flow2srcMAC = of.ofp_action_dl_addr.set_src(EthAddr("00:00:00:00:00:04")) # set src mac 00.**.04
flow2dstMAC = of.ofp_action_dl_addr.set_dst(EthAddr("00:00:00:00:00:02")) # set dst mac 00.**.01 host2
flow2msg.actions = [flow2srcIP, flow2srcMAC, flow2dstMAC, flow2out]

#flow3:
switch3 = 0000000000000001
flow3msg = of.ofp_flow_mod(command=0)#add flow rules
flow3msg.cookie = 0
flow3msg.match.in_port = 2 # match in port,the index of the switch
flow3msg.match.dl_type = 0x0800
flow3msg.match.nw_dst = IPAddr("10.0.0.2") # match dst ip 10.0.0.2

# ACTIONS---------------------------------
flow3out = of.ofp_action_output (port = 1)
flow3dstIP = of.ofp_action_nw_addr.set_dst(IPAddr("192.168.1.10")) # set dst ip to 192.168.1.10
flow3srcMAC = of.ofp_action_dl_addr.set_src(EthAddr("00:00:00:00:00:03")) # #set src mac to 00.**.03
flow3dstMAC = of.ofp_action_dl_addr.set_dst(EthAddr("00:00:00:00:00:01")) # set dst mac to 00.**.01
flow3msg.actions = [flow3dstIP, flow3srcMAC, flow3dstMAC, flow3out]



def install_flows():
        log.info("    *** Installing static flows... ***")
        # Push flows to switches
        core.openflow.sendToDPID(switch2, flow2msg)
        core.openflow.sendToDPID(switch3, flow3msg)
        log.info("    *** Static flows installed. ***")

def _handle_ConnectionUp (event):
        log.info("*** install flows ***")
        install_flows()

def _handle_PacketIn (event):
        #log.info("*** _handle_PacketIn... ***")
        dpid = event.connection.dpid
        inport = event.port
        packet = event.parsed
        if not packet.parsed:
          log.warning("%i %i ignoring unparsed packet", dpid, inport)
          return
        a = packet.find('arp')
        if not a: return

        log.info("%s ARP %s %s => %s", dpid_to_str(dpid),
      {arp.REQUEST:"request",arp.REPLY:"reply"}.get(a.opcode,
      'op:%i' % (a.opcode,)), str(a.protosrc), str(a.protodst))

        if a.prototype == arp.PROTO_TYPE_IP and a.hwtype == arp.HW_TYPE_ETHERNET and a.opcode == arp.REQUEST:
                r = arp()
                r.hwtype = a.hwtype
                r.prototype = a.prototype
                r.hwlen = a.hwlen
                r.protolen = a.protolen
                r.opcode = arp.REPLY
                r.hwdst = a.hwsrc
                r.protodst = a.protosrc
                r.protosrc = a.protodst
                if str(a.protodst)=="192.168.1.1":
                        r.hwsrc = EthAddr("00:00:00:00:00:03")
                if str(a.protodst)=="10.0.0.2":
                   r.hwsrc = EthAddr("00:00:00:00:00:04")
                e = ethernet(type=packet.type, src=r.hwsrc,
                                                dst=a.hwsrc)
                e.payload = r
                log.info("%s answering ARP for %s" % (dpid_to_str(dpid),
                        str(r.protosrc)))
                msg = of.ofp_packet_out()
                msg.data = e.pack()
                msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT))                            
                msg.in_port = inport
                event.connection.send(msg)

def launch ():
        log.info("*** Starting... ***")
        log.info("*** Waiting for switches to connect.. ***")
        core.openflow.addListenerByName("ConnectionUp", _handle_ConnectionUp)
        core.openflow.addListenerByName("PacketIn", _handle_PacketIn)

两条规则说明
1、从交换机1口进,并且源ip为 192.168.1.10,将报文的源ip修改为10.0.0.2,源mac修改为00:00:00:00:00:04,修改目的为00:00:00:00:00:02(主机h2的mac)
2、从交换机2口进,并且目的ip为10.0.0.2,将报文的目的ip修改为192.168.1.10,源mac修改为00:00:00:00:00:03,修改目的为00:00:00:00:00:01(主机h1的mac)

实验结果:

mininet@mininet-vm:~/pox$ ./pox.py mypox
POX 0.2.0 (carp) / Copyright 2011-2013 James McCauley, et al.
INFO:mypox:*** Starting... ***
INFO:mypox:*** Waiting for switches to connect.. ***
INFO:core:POX 0.2.0 (carp) is up.
INFO:openflow.of_01:[None 1] closed
INFO:openflow.of_01:[00-00-00-00-00-01 2] connected
INFO:mypox:*** install flows ***
INFO:mypox:    *** Installing static flows... ***
INFO:mypox:    *** Static flows installed. ***
INFO:openflow.of_01:[00-00-00-00-00-02 3] connected
INFO:mypox:*** install flows ***
INFO:mypox:    *** Installing static flows... ***
INFO:mypox:    *** Static flows installed. ***
INFO:mypox:00-00-00-00-00-01 ARP request 192.168.1.10 => 192.168.1.1
INFO:mypox:00-00-00-00-00-01 answering ARP for 192.168.1.1
INFO:mypox:00-00-00-00-00-01 ARP request 10.0.0.1 => 10.0.0.2
INFO:mypox:00-00-00-00-00-01 answering ARP for 10.0.0.2
mininet@mininet-vm:~$ sudo python nat.py 
*** Creating nodes
*** Creating links
*** Starting network
*** Configuring hosts
h1 h2 
*** Running CLI
*** Starting CLI:
mininet> h1 ping h2 -c 4
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=39.6 ms
64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=0.082 ms
64 bytes from 10.0.0.1: icmp_seq=3 ttl=64 time=0.063 ms
64 bytes from 10.0.0.1: icmp_seq=4 ttl=64 time=0.055 ms

--- 10.0.0.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3074ms
rtt min/avg/max/mdev = 0.055/9.960/39.643/17.137 ms

在h1上面抓包可以看到的是192.168.1.10 -> 10.0.0.1
这里写图片描述

在h2上面抓包可以看到的是 10.0.0.2 -> 10.0.0.1
这里写图片描述

猜你喜欢

转载自blog.csdn.net/hjxzb/article/details/80299311