Passed
Push — master ( 73e764...5e9a14 )
by Humberto
07:26 queued 43s
created

build.v0x01.utils.JSONEncoderOF10.default()   A

Complexity

Conditions 2

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 5
ccs 4
cts 4
cp 1
rs 10
c 0
b 0
f 0
cc 2
nop 2
crap 2
1
"""Utilities module for of_core OpenFlow v0x01 operations."""
2 1
import json
3
4 1
from pyof.foundation.base import UBIntBase
5 1
from pyof.v0x01.controller2switch.common import (ConfigFlag, FlowStatsRequest,
6
                                                 PortStatsRequest)
7 1
from pyof.v0x01.controller2switch.set_config import SetConfig
8 1
from pyof.v0x01.controller2switch.stats_request import StatsRequest, StatsType
9 1
from pyof.v0x01.symmetric.echo_request import EchoRequest
10 1
from pyof.v0x01.symmetric.hello import Hello
11
12 1
from kytos.core import KytosEvent
13 1
from kytos.core.interface import Interface
14 1
from napps.kytos.of_core.utils import emit_message_out
15
16
17 1
class JSONEncoderOF10(json.JSONEncoder):
18
    """Custom JSON encoder for OF 1.0 flow representation.
19
20
    Make casting from UBInt8, UBInt16, UBInt32, UBInt64 to int.
21
    """
22
23 1
    def default(self, obj):  # pylint: disable=E0202,W0221
24
        """Make casting from UBInt8, UBInt16, UBInt32, UBInt64 to int."""
25 1
        if isinstance(obj, UBIntBase):
26 1
            return int(obj)
27 1
        return json.JSONEncoder.default(self, obj)
28
29
30 1
def update_flow_list(controller, switch):
31
    """Request flow stats from switches.
32
33
    Args:
34
        controller(:class:`~kytos.core.controller.Controller`):
35
            the controller being used.
36
        switch(:class:`~kytos.core.switch.Switch`):
37
            target to send a stats request.
38
    """
39 1
    body = FlowStatsRequest()
40 1
    stats_request = StatsRequest(
41
        body_type=StatsType.OFPST_FLOW,
42
        body=body)
43
    # req.pack()
44 1
    emit_message_out(controller, switch.connection, stats_request)
45
46
47 1
def request_port_stats(controller, switch):
48
    """Request port stats from switches.
49
50
    Args:
51
        controller(:class:`~kytos.core.controller.Controller`):
52
            the controller being used.
53
        switch(:class:`~kytos.core.switch.Switch`):
54
            target to send a stats request.
55
    """
56 1
    body = PortStatsRequest()
57 1
    stats_request = StatsRequest(
58
        body_type=StatsType.OFPST_PORT,
59
        body=body)
60
    # req.pack()
61 1
    emit_message_out(controller, switch.connection, stats_request)
62
63
64 1
def send_desc_request(controller, switch):
65
    """Send a description request to the switch.
66
67
    Args:
68
        controller(:class:`~kytos.core.controller.Controller`):
69
            the controller being used.
70
        switch(:class:`~kytos.core.switch.Switch`):
71
            target to send a stats request.
72
    """
73 1
    stats_request = StatsRequest(body_type=StatsType.OFPST_DESC)
74 1
    emit_message_out(controller, switch.connection, stats_request)
75
76
77 1
def handle_features_reply(controller, event):
78
    """Handle OF v0x01 features_reply message events.
79
80
    This is the end of the Handshake workflow of the OpenFlow Protocol.
81
    Parameters:
82
        controller (Controller): Controller being used.
83
        event (KytosEvent): Event with features reply message.
84
85
    """
86 1
    connection = event.source
87 1
    features_reply = event.content['message']
88 1
    dpid = features_reply.datapath_id.value
89
90 1
    switch = controller.get_switch_or_create(dpid=dpid,
91
                                             connection=connection)
92
93 1
    for port in features_reply.ports:
94 1
        interface = switch.get_interface_by_port_no(port.port_no.value)
95 1
        if interface:
96 1
            interface.name = port.name.value
97 1
            interface.address = port.hw_addr.value
98 1
            interface.state = port.state.value
99 1
            interface.features = port.curr
100
        else:
101 1
            interface = Interface(name=port.name.value,
102
                                  address=port.hw_addr.value,
103
                                  port_number=port.port_no.value,
104
                                  switch=switch,
105
                                  state=port.state.value,
106
                                  features=port.curr)
107 1
        switch.update_interface(interface)
108 1
        port_event = KytosEvent(name='kytos/of_core.switch.port.created',
109
                                content={
110
                                    'switch': switch.id,
111
                                    'port': port.port_no.value,
112
                                    'port_description': {
113
                                        'alias': port.name.value,
114
                                        'mac': port.hw_addr.value,
115
                                        'state': port.state.value
116
                                        }
117
                                    })
118 1
        controller.buffers.app.put(port_event)
119
120 1
    switch.update_features(features_reply)
121 1
    return switch
122
123
124 1
def send_echo(controller, switch):
125
    """Send echo request to a datapath.
126
127
    Keep the connection alive through symmetric echoes.
128
    """
129 1
    echo = EchoRequest(data=b'kytosd_10')
130 1
    emit_message_out(controller, switch.connection, echo)
131
132
133 1
def send_set_config(controller, switch):
134
    """Send a SetConfig message after the OpenFlow handshake."""
135 1
    set_config = SetConfig()
136 1
    set_config.flags = ConfigFlag.OFPC_FRAG_NORMAL
137 1
    set_config.miss_send_len = 0xffff       # Send the whole packet
138 1
    emit_message_out(controller, switch.connection, set_config)
139
140
141 1
def say_hello(controller, connection):
142
    """Send back a Hello packet with the same version as the switch."""
143 1
    hello = Hello()
144
    emit_message_out(controller, connection, hello)
145