Passed
Push — master ( 667973...d237fc )
by Beraldo
01:46
created

build.v0x04.utils   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 129
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
eloc 69
dl 0
loc 129
ccs 0
cts 54
cp 0
rs 10
c 0
b 0
f 0
wmc 10

8 Functions

Rating   Name   Duplication   Size   Complexity  
A send_echo() 0 7 1
A say_hello() 0 4 1
A send_set_config() 0 6 1
A send_port_request() 0 5 1
A update_flow_list() 0 18 1
A handle_port_desc() 0 28 3
A handle_features_reply() 0 21 1
A send_desc_request() 0 12 1
1
"""Utilities module for of_core OpenFlow v0x04 operations"""
2
from kytos.core.events import KytosEvent
3
from kytos.core.interface import Interface
4
5
from napps.kytos.of_core.utils import emit_message_out
6
7
from pyof.v0x04.symmetric.echo_request import EchoRequest
8
from pyof.v0x04.controller2switch.common import ConfigFlag, MultipartType
9
from pyof.v0x04.controller2switch.multipart_request import (FlowStatsRequest,
10
                                                            MultipartRequest)
11
from pyof.v0x04.controller2switch.set_config import SetConfig
12
from pyof.v0x04.common.action import ControllerMaxLen
13
from pyof.v0x04.symmetric.hello import Hello
14
15
16
def update_flow_list(controller, switch):
17
    """Method responsible for request stats of flow to switches.
18
19
    Args:
20
        controller(:class:`~kytos.core.controller.Controller`):
21
            the controller being used.
22
        switch(:class:`~kytos.core.switch.Switch`):
23
            target to send a stats request.
24
25
    Returns:
26
        int: multipart request xid
27
28
    """
29
    multipart_request = MultipartRequest()
30
    multipart_request.multipart_type = MultipartType.OFPMP_FLOW
31
    multipart_request.body = FlowStatsRequest()
32
    emit_message_out(controller, switch.connection, multipart_request)
33
    return multipart_request.header.xid
34
35
36
def send_desc_request(controller, switch):
37
    """Method responsible for request stats of flow to switches.
38
39
    Args:
40
        controller(:class:`~kytos.core.controller.Controller`):
41
            the controller being used.
42
        switch(:class:`~kytos.core.switch.Switch`):
43
            target to send a stats request.
44
    """
45
    multipart_request = MultipartRequest()
46
    multipart_request.multipart_type = MultipartType.OFPMP_DESC
47
    emit_message_out(controller, switch.connection, multipart_request)
48
49
def send_port_request(controller, connection):
50
    """Send a Port Description Request after the Features Reply."""
51
    port_request = MultipartRequest()
52
    port_request.multipart_type = MultipartType.OFPMP_PORT_DESC
53
    emit_message_out(controller, connection, port_request)
54
55
56
def handle_features_reply(controller, event):
57
    """Handle OF v0x04 features_reply message events.
58
59
    This is the end of the Handshake workflow of the OpenFlow Protocol.
60
61
    Parameters:
62
        controller (Controller): Controller being used.
63
        event (KytosEvent): Event with features reply message.
64
    """
65
66
    connection = event.source
67
    features_reply = event.content['message']
68
    dpid = features_reply.datapath_id.value
69
70
    switch = controller.get_switch_or_create(dpid=dpid,
71
                                             connection=connection)
72
    send_port_request(controller, connection)
73
74
    switch.update_features(features_reply)
75
76
    return switch
77
78
79
def handle_port_desc(controller, switch, port_list):
80
    """Update interfaces on switch based on port_list information."""
81
    for port in port_list:
82
        interface = switch.get_interface_by_port_no(port.port_no.value)
83
        if interface:
84
            interface.name = port.name.value
85
            interface.address = port.hw_addr.value
86
            interface.state = port.state.value
87
            interface.features = port.curr
88
        else:
89
            interface = Interface(name=port.name.value,
90
                                  address=port.hw_addr.value,
91
                                  port_number=port.port_no.value,
92
                                  switch=switch,
93
                                  state=port.state.value,
94
                                  features=port.curr)
95
        switch.update_interface(interface)
96
        port_event = KytosEvent(name='kytos/of_core.switch.port.created',
97
                                content={
98
                                    'switch': switch.id,
99
                                    'port': port.port_no.value,
100
                                    'port_description': {
101
                                        'alias': port.name.value,
102
                                        'mac': port.hw_addr.value,
103
                                        'state': port.state.value
104
                                        }
105
                                    })
106
        controller.buffers.app.put(port_event)
107
108
def send_echo(controller, switch):
109
    """Send echo request to a datapath.
110
111
    Keep the connection alive through symmetric echoes.
112
    """
113
    echo = EchoRequest(data=b'kytosd_13')
114
    emit_message_out(controller, switch.connection, echo)
115
116
117
def send_set_config(controller, switch):
118
    """Send a SetConfig message after the OpenFlow handshake."""
119
    set_config = SetConfig()
120
    set_config.flags = ConfigFlag.OFPC_FRAG_NORMAL
121
    set_config.miss_send_len = ControllerMaxLen.OFPCML_NO_BUFFER
122
    emit_message_out(controller, switch.connection, set_config)
123
124
125
def say_hello(controller, connection):
126
    """Send back a Hello packet with the same version as the switch."""
127
    hello = Hello()
128
    emit_message_out(controller, connection, hello)
129