This is a openflow v1.2 control library.

Signed-off-by: WATANABE Fumitaka <[email protected]>
---
 ryu/lib/ofctl_v1_2.py |  255 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 255 insertions(+)
 create mode 100755 ryu/lib/ofctl_v1_2.py

diff --git a/ryu/lib/ofctl_v1_2.py b/ryu/lib/ofctl_v1_2.py
new file mode 100755
index 0000000..17b880f
--- /dev/null
+++ b/ryu/lib/ofctl_v1_2.py
@@ -0,0 +1,255 @@
+# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import struct
+import socket
+import logging
+import gevent
+
+from ryu.ofproto import inet
+from ryu.ofproto import ofproto_v1_2
+from ryu.ofproto import ofproto_v1_2_parser
+from ryu.lib import mac
+
+
+LOG = logging.getLogger('ryu.lib.ofctl_v1_2')
+
+DEFAULT_TIMEOUT = 1.0
+
+
+def to_actions(dp, acts):
+    inst = []
+    for a in acts:
+        action_type = a.get('type')
+        if action_type == 'OUTPUT':
+            out_port = int(a.get('port', ofproto_v1_2.OFPP_ANY))
+            actions = [dp.ofproto_parser.OFPActionOutput(out_port, 0)]
+            inst_type = dp.ofproto.OFPIT_APPLY_ACTIONS
+            inst = [dp.ofproto_parser.OFPInstructionActions(
+                    inst_type, actions)]
+        else:
+            LOG.debug('Unknown action type')
+
+    return inst
+
+
+def actions_to_str(instructions):
+    actions = []
+
+    for instruction in instructions:
+        for a in instruction.actions:
+            action_type = a.cls_action_type
+
+            if action_type == ofproto_v1_2.OFPAT_OUTPUT:
+                buf = 'OUTPUT:' + str(a.port)
+            else:
+                buf = 'UNKNOWN'
+            actions.append(buf)
+
+    return actions
+
+
+def to_match(dp, attrs):
+    match = dp.ofproto_parser.OFPMatch()
+
+    convert = {'in_port': int,
+               'dl_src': mac.haddr_to_bin,
+               'dl_dst': mac.haddr_to_bin,
+               'dl_type': int,
+               'nw_src': to_match_ip,
+               'nw_dst': to_match_ip,
+               'nw_proto': int,
+               'tp_src': int,
+               'tp_dst': int,
+              }
+    match_append = {'in_port': match.set_in_port,
+                    'dl_src': match.set_dl_src,
+                    'dl_dst': match.set_dl_dst,
+                    'dl_type': match.set_dl_type,
+                    'nw_src': match.set_ipv4_src_masked,
+                    'nw_dst': match.set_ipv4_dst_masked,
+                    'nw_proto': match.set_ip_proto,
+                    'tp_src': to_match_tpsrc,
+                    'tp_dst': to_match_tpdst,
+                   }
+    for key, value in attrs.items():
+        if key in convert:
+            value = convert[key](value)
+        if key in match_append:
+            if key == 'nw_src' or key == 'nw_dst':
+                # IP address
+                ip = value[0]
+                mask = value[1]
+                match_append[key](ip, mask)
+            elif key == 'tp_src' or key == 'tp_dst':
+                # tp_src/dst
+                match = match_append[key](value, match, attrs)
+            else:
+                # others
+                match_append[key](value)
+
+    return match
+
+
+def to_match_tpsrc(value, match, rest):
+    match_append = {inet.IPPROTO_TCP: match.set_tcp_src,
+                    inet.IPPROTO_UDP: match.set_udp_src,
+                   }
+    nw_proto = rest.get('nw_proto', 0)
+    if nw_proto in match_append:
+        match_append[nw_proto](value)
+
+    return match
+
+
+def to_match_tpdst(value, match, rest):
+    match_append = {inet.IPPROTO_TCP: match.set_tcp_dst,
+                    inet.IPPROTO_UDP: match.set_udp_dst,
+                   }
+    nw_proto = rest.get('nw_proto', 0)
+    if nw_proto in match_append:
+        match_append[nw_proto](value)
+
+    return match
+
+
+def to_match_ip(value):
+    ip_mask = value.split('/')
+    # ip
+    ipv4 = struct.unpack('!I', socket.inet_aton(ip_mask[0]))[0]
+    # netmask
+    mask = 32
+    if len(ip_mask) == 2:
+        mask = int(ip_mask[1])
+    netmask = ofproto_v1_2_parser.UINT32_MAX << 32 - mask\
+              & ofproto_v1_2_parser.UINT32_MAX
+
+    return ipv4, netmask
+
+
+def match_to_str(ofmatch):
+
+    keys = {ofproto_v1_2.OXM_OF_IN_PORT: 'in_port',
+            ofproto_v1_2.OXM_OF_ETH_SRC: 'dl_src',
+            ofproto_v1_2.OXM_OF_ETH_DST: 'dl_dst',
+            ofproto_v1_2.OXM_OF_ETH_TYPE: 'dl_type',
+            ofproto_v1_2.OXM_OF_IPV4_SRC: 'nw_src',
+            ofproto_v1_2.OXM_OF_IPV4_DST: 'nw_dst',
+            ofproto_v1_2.OXM_OF_IPV4_SRC_W: 'nw_src',
+            ofproto_v1_2.OXM_OF_IPV4_DST_W: 'nw_dst',
+            ofproto_v1_2.OXM_OF_IP_PROTO: 'nw_proto',
+            ofproto_v1_2.OXM_OF_TCP_SRC: 'tp_src',
+            ofproto_v1_2.OXM_OF_TCP_DST: 'tp_dst',
+            ofproto_v1_2.OXM_OF_UDP_SRC: 'tp_src',
+            ofproto_v1_2.OXM_OF_UDP_DST: 'tp_dst',
+           }
+
+    match = {}
+    for match_field in ofmatch.fields:
+        key = keys[match_field.header]
+        if key == 'dl_src' or key == 'dl_dst':
+            value = mac.haddr_to_str(match_field.value)
+        elif key == 'nw_src' or key == 'nw_dst':
+            value = match_ip_to_str(match_field.value, match_field.mask)
+        else:
+            value = match_field.value
+        match.setdefault(key, value)
+
+    return match
+
+
+def match_ip_to_str(value, mask):
+    ip = socket.inet_ntoa(struct.pack('!I', value))
+
+    if mask is not None and mask != 0:
+        binary_str = bin(mask)[2:].zfill(8)
+        netmask = '/%d' % len(binary_str.rstrip('0'))
+    else:
+        netmask = ''
+
+    return ip + netmask
+
+
+def send_stats_request(dp, stats, waiters, msgs):
+    dp.set_xid(stats)
+    waiters_per_dp = waiters.setdefault(dp.id, {})
+    lock = gevent.event.AsyncResult()
+    waiters_per_dp[stats.xid] = (lock, msgs)
+    dp.send_msg(stats)
+
+    try:
+        lock.get(timeout=DEFAULT_TIMEOUT)
+    except gevent.Timeout:
+        del waiters_per_dp[stats.xid]
+
+
+def get_flow_stats(dp, waiters):
+
+    table_id = 0
+    out_port = dp.ofproto.OFPP_ANY
+    out_group = dp.ofproto.OFPG_ANY
+    cookie = 0
+    cookie_mask = 0
+    match = dp.ofproto_parser.OFPMatch()
+
+    stats = dp.ofproto_parser.OFPFlowStatsRequest(
+        dp, table_id, out_port, out_group, cookie, cookie_mask, match)
+
+    msgs = []
+    send_stats_request(dp, stats, waiters, msgs)
+
+    flows = []
+    for msg in msgs:
+        for stats in msg.body:
+            actions = actions_to_str(stats.instructions)
+            match = match_to_str(stats.match)
+
+            s = {'priority': stats.priority,
+                 'cookie': stats.cookie,
+                 'idle_timeout': stats.idle_timeout,
+                 'hard_timeout': stats.hard_timeout,
+                 'actions': actions,
+                 'match': match,
+                 'byte_count': stats.byte_count,
+                 'duration_sec': stats.duration_sec,
+                 'duration_nsec': stats.duration_nsec,
+                 'packet_count': stats.packet_count,
+                 'table_id': stats.table_id}
+            flows.append(s)
+    flows = {str(dp.id): flows}
+    return flows
+
+
+def mod_flow_entry(dp, flow, cmd):
+
+    cookie = int(flow.get('cookie', 0))
+    cookie_mask = int(flow.get('cookie_mask', 0))
+    table_id = int(flow.get('table_id', 0))
+    idle_timeout = int(flow.get('idle_timeout', 0))
+    hard_timeout = int(flow.get('hard_timeout', 0))
+    priority = int(flow.get('priority', 0))
+    buffer_id = int(flow.get('buffer_id', 0xffffffff))
+    out_port = int(flow.get('out_port', dp.ofproto.OFPP_ANY))
+    out_group = int(flow.get('out_group', dp.ofproto.OFPG_ANY))
+    flags = int(flow.get('flags', 0))
+    match = to_match(dp, flow.get('match', {}))
+    inst = to_actions(dp, flow.get('actions', {}))
+
+    flow_mod = dp.ofproto_parser.OFPFlowMod(
+        dp, cookie, cookie_mask, table_id, cmd, idle_timeout,
+        hard_timeout, priority, buffer_id, out_port, out_group,
+        flags, match, inst)
+
+    dp.send_msg(flow_mod)
-- 
1.7.10.4

------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_mar
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to