当前位置:   article > 正文

sdn实验三四

sdn实验三四

sdn实验三四

实验三

创建拓扑

#!/usr/bin/env python



from mininet.net import Mininet

from mininet.node import Controller, RemoteController, OVSController

from mininet.node import CPULimitedHost, Host, Node

from mininet.node import OVSKernelSwitch, UserSwitch

from mininet.node import IVSSwitch

from mininet.cli import CLI

from mininet.log import setLogLevel, info

from mininet.link import TCLink, Intf

from subprocess import call



def myNetwork():



    net = Mininet( topo=None,

                   build=False,

                   ipBase='192.168.0.0/24')



    info( '*** Adding controller\n' )

    c0=net.addController(name='c0',

                      controller=Controller,

                      protocol='tcp',

                      port=6633)



    info( '*** Add switches\n')

    s1 = net.addSwitch('s1', cls=OVSKernelSwitch)

    s2 = net.addSwitch('s2', cls=OVSKernelSwitch)



    info( '*** Add hosts\n')

    h1 = net.addHost('h1', cls=Host, ip='192.168.0.101/24', defaultRoute=None)

    h2 = net.addHost('h2', cls=Host, ip='192.168.0.102/24', defaultRoute=None)

    h3 = net.addHost('h3', cls=Host, ip='192.168.0.103/24', defaultRoute=None)

    h4 = net.addHost('h4', cls=Host, ip='192.168.0.104/24', defaultRoute=None)



    info( '*** Add links\n')

    net.addLink(h1, s1)

    net.addLink(s1, s2)

    net.addLink(s2, h2)

    net.addLink(s2, h4)

    net.addLink(s1, h3)



    info( '*** Starting network\n')

    net.build()

    info( '*** Starting controllers\n')

    for controller in net.controllers:

        controller.start()



    info( '*** Starting switches\n')

    net.get('s1').start([c0])

    net.get('s2').start([c0])



    info( '*** Post configure switches and hosts\n')



    CLI(net)

    net.stop()



if __name__ == '__main__':

    setLogLevel( 'info' )

    myNetwork()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117

查看抓包结果,分析OpenFlow协议中交换机与控制器的消息交互过程,画出相关交互图或流程图。

在这里插入图片描述

HELLO

首先控制器和交换机互相发送HELLO报文,可以看到控制器openflow版本为1.0,交换机openflow为1.5,按照规定选择二者间较小的版本,故双方确定版本为1.0

控制器向交换价发送HELLO
在这里插入图片描述

交换机向控制器发送HELLO报文
在这里插入图片描述
miniedit导出的python文件


#!/usr/bin/env python



from mininet.net import Mininet

from mininet.node import Controller, RemoteController, OVSController

from mininet.node import CPULimitedHost, Host, Node

from mininet.node import OVSKernelSwitch, UserSwitch

from mininet.node import IVSSwitch

from mininet.cli import CLI

from mininet.log import setLogLevel, info

from mininet.link import TCLink, Intf

from subprocess import call



def myNetwork():



    net = Mininet( topo=None,

                   build=False,

                   ipBase='192.168.0.0/24')



    info( '*** Adding controller\n' )

    c0=net.addController(name='c0',

                      controller=Controller,

                      protocol='tcp',

                      port=6633)



    info( '*** Add switches\n')

    s1 = net.addSwitch('s1', cls=OVSKernelSwitch)

    s2 = net.addSwitch('s2', cls=OVSKernelSwitch)



    info( '*** Add hosts\n')

    h1 = net.addHost('h1', cls=Host, ip='192.168.0.101/24', defaultRoute=None)

    h2 = net.addHost('h2', cls=Host, ip='192.168.0.102/24', defaultRoute=None)

    h3 = net.addHost('h3', cls=Host, ip='192.168.0.103/24', defaultRoute=None)

    h4 = net.addHost('h4', cls=Host, ip='192.168.0.104/24', defaultRoute=None)



    info( '*** Add links\n')

    net.addLink(h1, s1)

    net.addLink(s1, s2)

    net.addLink(s2, h2)

    net.addLink(s2, h4)

    net.addLink(s1, h3)



    info( '*** Starting network\n')

    net.build()

    info( '*** Starting controllers\n')

    for controller in net.controllers:

        controller.start()



    info( '*** Starting switches\n')

    net.get('s1').start([c0])

    net.get('s2').start([c0])



    info( '*** Post configure switches and hosts\n')



    CLI(net)

    net.stop()



if __name__ == '__main__':

    setLogLevel( 'info' )

    myNetwork()

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119

抓取OpenFlow1.0数据包#
查看抓包结果,分析OpenFlow协议中交换机与控制器的消息交互过程,画出相关交互图或流程图。

HELLO
首先控制器和交换机互相发送HELLO报文,可以看到控制器openflow版本为1.0,交换机openflow为1.5,按照规定选择二者间较小的版本,故双方确定版本为1.0

控制器向交换价发送HELLO

在这里插入图片描述

交换机向控制器发送HELLO报文
mage-20210922175608822

FEATURES_REQUEST/FEATURES_REPLY#
控制器向交换机发送FEATURES_REQUEST询问交换机信息
在这里插入图片描述
交换机收到FEATURES_REQUEST之后随即发送FEATURES_REPLY,将自己的信息发送至控制器
在这里插入图片描述
SET_CONFIG
控制器向交换机发送发送SET_CONFIG消息以发送设置信息,也可能发送GET_CONFIG请求消息以查询OpenFlow交换机的设置状态
在这里插入图片描述
PORT_STATUS
当交换机端口发生变化时,告知控制器相应的端口状态。
在这里插入图片描述
PACKET_IN
在这里插入图片描述
PACKET_OUT
在这里插入图片描述
FLOW_MOD
在这里插入图片描述
交换机与控制器建立通信时是使用TCP协议还是UDP协议?
采用的协议是TCP

进阶

HELLO

struct ofp_header {

    uint8_t version;    /* OFP_VERSION. */

    uint8_t type;       /* One of the OFPT_ constants. */

    uint16_t length;    /* Length including this ofp_header. */

    uint32_t xid;       /* Transaction id associated with this packet.

                           Replies use the same id as was in the request

                           to facilitate pairing. */

};

struct ofp_hello {

    struct ofp_header header;

};

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

FEATURES_REQUEST FEATURES_REPLY

struct ofp_switch_features {

    struct ofp_header header;

    uint64_t datapath_id;   /* Datapath unique ID.  The lower 48-bits are for

                               a MAC address, while the upper 16-bits are

                               implementer-defined. */



    uint32_t n_buffers;     /* Max packets buffered at once. */



    uint8_t n_tables;       /* Number of tables supported by datapath. */

    uint8_t pad[3];         /* Align to 64-bits. */



    /* Features. */

    uint32_t capabilities;  /* Bitmap of support "ofp_capabilities". */

    uint32_t actions;       /* Bitmap of supported "ofp_action_type"s. */



    /* Port info.*/

    struct ofp_phy_port ports[0];  /* Port definitions.  The number of ports

                                      is inferred from the length field in

                                      the header. */

};

/* Description of a physical port */

struct ofp_phy_port {

    uint16_t port_no;

    uint8_t hw_addr[OFP_ETH_ALEN];

    char name[OFP_MAX_PORT_NAME_LEN]; /* Null-terminated */



    uint32_t config;        /* Bitmap of OFPPC_* flags. */

    uint32_t state;         /* Bitmap of OFPPS_* flags. */



    /* Bitmaps of OFPPF_* that describe features.  All bits zeroed if

     * unsupported or unavailable. */

    uint32_t curr;          /* Current features. */

    uint32_t advertised;    /* Features being advertised by the port. */

    uint32_t supported;     /* Features supported by the port. */

    uint32_t peer;          /* Features advertised by peer. */

};

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72

SET_CONFIG

/* Switch configuration. */

struct ofp_switch_config {

    struct ofp_header header;

    uint16_t flags;             /* OFPC_* flags. */

    uint16_t miss_send_len;     /* Max bytes of new flow that datapath should

                                   send to the controller. */

};

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

PORT_STATUS

/* A physical port has changed in the datapath */

struct ofp_port_status {

    struct ofp_header header;

    uint8_t reason;          /* One of OFPPR_*. */

    uint8_t pad[7];          /* Align to 64-bits. */

    struct ofp_phy_port desc;

};

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

PACKET_IN

struct ofp_packet_in {

    struct ofp_header header;

    uint32_t buffer_id;     /* ID assigned by datapath. */

    uint16_t total_len;     /* Full length of frame. */

    uint16_t in_port;       /* Port on which frame was received. */

    uint8_t reason;         /* Reason packet is being sent (one of OFPR_*) */

    uint8_t pad;

    uint8_t data[0];        /* Ethernet frame, halfway through 32-bit word,

                               so the IP header is 32-bit aligned.  The

                               amount of data is inferred from the length

                               field in the header.  Because of padding,

                               offsetof(struct ofp_packet_in, data) ==

                               sizeof(struct ofp_packet_in) - 2. */

};

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

PACKET_OUT

struct ofp_packet_out {

    struct ofp_header header;

    uint32_t buffer_id;           /* ID assigned by datapath (-1 if none). */

    uint16_t in_port;             /* Packet's input port (OFPP_NONE if none). */

    uint16_t actions_len;         /* Size of action array in bytes. */

    struct ofp_action_header actions[0]; /* Actions. */

    /* uint8_t data[0]; */        /* Packet data.  The length is inferred

                                     from the length field in the header.

                                     (Only meaningful if buffer_id == -1.) */

};

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

FLOW_MOD

struct ofp_flow_mod {

    struct ofp_header header;

    struct ofp_match match;      /* Fields to match */

    uint64_t cookie;             /* Opaque controller-issued identifier. */



    /* Flow actions. */

    uint16_t command;             /* One of OFPFC_*. */

    uint16_t idle_timeout;        /* Idle time before discarding (seconds). */

    uint16_t hard_timeout;        /* Max time before discarding (seconds). */

    uint16_t priority;            /* Priority level of flow entry. */

    uint32_t buffer_id;           /* Buffered packet to apply to (or -1).

                                     Not meaningful for OFPFC_DELETE*. */

    uint16_t out_port;            /* For OFPFC_DELETE* commands, require

                                     matching entries to include this as an

                                     output port.  A value of OFPP_NONE

                                     indicates no restriction. */

    uint16_t flags;               /* One of OFPFF_*. */

    struct ofp_action_header actions[0]; /* The action length is inferred

                                            from the length field in the

                                            header. */

};

struct ofp_action_header {

    uint16_t type;                  /* One of OFPAT_*. */

    uint16_t len;                   /* Length of action, including this

                                       header.  This is the length of action,

                                       including any padding to make it

                                       64-bit aligned. */

    uint8_t pad[4];

};

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

总结

主要在于了解OpenFlow协议在交换机和控制器间的交互过程,一开始openflow未指定,没有抓到包。以下是OpenFlow协议的交互过程:

连接建立:

首先,控制器和交换机之间建立TCP连接,通常在默认端口6633或6653上进行。握手协商:一旦连接建立,交换机和控制器会进行握手协商。在这个阶段,它们协商OpenFlow协议的版本并确认双方支持的特性。流表配置:控制器发送流表配置消息给交换机。流表是用于处理数据包的规则集合,指定了如何处理进入交换机的数据包。数据包匹配:当交换机收到数据包时,它会根据流表中的规则对数据包进行匹配。规则通常基于源MAC地址、目标MAC地址、IP地址、端口等条件。决策与行动:如果交换机找到与数据包匹配的流表规则,它将执行与该规则关联的操作,如转发、丢弃或修改数据包。如果没有匹配规则,交换机将向控制器发送一个流表未命中消息。控制器响应:控制器接收到流表未命中消息后,可以采取行动,例如创建新的流表规则以处理未匹配的流量。控制器还可以发送特定命令给交换机,以动态地配置网络行为。状态监测:OpenFlow协议还支持状态监测功能。交换机可以向控制器定期报告网络状态和统计信息,使控制器能够了解网络的实际运行情况。连接维护:在连接建立后,OpenFlow协议保持连接活动。如果连接中断,控制器和交换机将尝试重新建立连接以保持通信。

以上是总结的交互过程,剩下的就是wireshark抓包更加熟练

实验四

1.搭建拓扑

sudo mn --topo=single,3 --mac --controller=remote,ip=127.0.0.1,port=6633 --switch ovsk,protocols=OpenFlow13
  • 1

查看拓扑
在这里插入图片描述

Postman下发流表

url:http://127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/flow-node-inventory:table/0/flow/1

{
    "flow": [
        {
            "id": "1",
            "match": {
                "in-port": "1",
                "ethernet-match": {
                    "ethernet-type": {
                        "type": "0x0800"
                    }
                },
                "ipv4-destination": "10.0.0.3/32"
            },
            "instructions": {
                "instruction": [
                    {
                        "order": "0",
                        "apply-actions": {
                            "action": [
                                {
                                    "order": "0",
                                    "drop-action": {}
                                }
                            ]
                        }
                    }
                ]
            },
            "flow-name": "flow1",
            "priority": "65535",
            "hard-timeout": "10",
            "cookie": "2",
            "table_id": "0"
        }
    ]
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

检查h1和h3连通性:
请添加图片描述
整理文档
获取拓扑的交换机#
url:http://127.0.0.1:8181/apidoc/explorer/index.html#!/network-topology(2013-10-21)/GET_network_topology_get_183
在这里插入图片描述
image-20210929200849402
Postman下发流表#
通过Postman请求Restful API,进行流表下发

url:http://127.0.0.1:8181/restconf/config/opendaylight-

json:

{
    "flow": [
        {
            "id": "1",
            "match": {
                "in-port": "1",
                "ethernet-match": {
                    "ethernet-type": {
                        "type": "0x0800"
                    }
                },
                "ipv4-destination": "10.0.0.3/32"
            },
            "instructions": {
                "instruction": [
                    {
                        "order": "0",
                        "apply-actions": {
                            "action": [
                                {
                                    "order": "0",
                                    "drop-action": {}
                                }
                            ]
                        }
                    }
                ]
            },
            "flow-name": "flow1",
            "priority": "65535",
            "hard-timeout": "10",
            "cookie": "2",
            "table_id": "0"
        }
    ]
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

检查h1和h3连通性,截图如下:
请添加图片描述

整理和记录主要API文档#
获取拓扑的交换机#
url:http://127.0.0.1:8181/apidoc/explorer/index.html#!/network-topology(2013-10-21)/GET_network_topology_get_183
在这里插入图片描述

流表 增删改查#
url:http://127.0.0.1:8181/apidoc/explorer/index.html#!/opendaylight-inventory(2013-08-19)/GET_flow_get_204
在这里插入图片描述
获取特定交换机端口的状态#
url:http://127.0.0.1:8181/apidoc/explorer/index.html#!/opendaylight-port-statistics(2013-12-14)/get_node_connector_statistics_post_0
在这里插入图片描述
获取指定交换机信息#
url:http://127.0.0.1:8181/apidoc/explorer/index.html#!/opendaylight-inventory(2013-08-19)/GET_node_get_5
在这里插入图片描述

总结

在安装OpenDaylight(ODL)环境时,遇到各种常见问题。以下是我遇到的问题以及解决方法:

Java版本问题:

问题:ODL通常需要特定版本的Java。如果你的Java版本不兼容,可能会导致安装失败。
解决方法:确保安装了ODL所需版本的Java,并设置了正确的JAVA_HOME环境变量。

网络连接问题:
问题:如果网络连接不稳定或速度较慢,可能会导致下载ODL组件的过程中失败。
解决方法:检查你的网络连接,确保它稳定。可以尝试使用国内镜像源或VPN来解决网络问题。

端口冲突问题:
问题:如果其他应用程序正在使用ODL所需的端口(如TCP 8181和TCP 6633),安装可能会失败。
解决方法:关闭占用这些端口的应用程序或者在ODL配置中更改端口。

在解决OpenDaylight环境安装问题时,得到以下一些感悟:

解决问题需要仔细观察和耐心。阅读错误是找到解决方案的关键步骤。

了解依赖关系:了解软件的依赖关系非常重要。确保所有必需的软件包和库都已正确安装和配置,以确保系统的完整性。

网络管理:网络连接的稳定性对于从网络上下载ODL组件至关重要。了解如何在网络问题出现时切换到备用镜像源或VPN等工具是有益的。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/991821
推荐阅读
相关标签
  

闽ICP备14008679号