backing up
[vsorcdistro/.git] / ryu / build / lib.linux-armv7l-2.7 / ryu / lib / ofctl_utils.py
diff --git a/ryu/build/lib.linux-armv7l-2.7/ryu/lib/ofctl_utils.py b/ryu/build/lib.linux-armv7l-2.7/ryu/lib/ofctl_utils.py
new file mode 100644 (file)
index 0000000..493ca35
--- /dev/null
@@ -0,0 +1,451 @@
+# Copyright (C) 2016 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 base64
+import logging
+
+import netaddr
+import six
+
+from ryu.lib import dpid
+from ryu.lib import hub
+from ryu.ofproto import ofproto_v1_2
+
+
+LOG = logging.getLogger(__name__)
+DEFAULT_TIMEOUT = 1.0
+
+# NOTE(jkoelker) Constants for converting actions
+OUTPUT = 'OUTPUT'
+COPY_TTL_OUT = 'COPY_TTL_OUT'
+COPY_TTL_IN = 'COPY_TTL_IN'
+SET_MPLS_TTL = 'SET_MPLS_TTL'
+DEC_MPLS_TTL = 'DEC_MPLS_TTL'
+PUSH_VLAN = 'PUSH_VLAN'
+POP_VLAN = 'POP_VLAN'
+PUSH_MPLS = 'PUSH_MPLS'
+POP_MPLS = 'POP_MPLS'
+SET_QUEUE = 'SET_QUEUE'
+GROUP = 'GROUP'
+SET_NW_TTL = 'SET_NW_TTL'
+DEC_NW_TTL = 'DEC_NW_TTL'
+SET_FIELD = 'SET_FIELD'
+PUSH_PBB = 'PUSH_PBB'      # OpenFlow 1.3 or later
+POP_PBB = 'POP_PBB'        # OpenFlow 1.3 or later
+COPY_FIELD = 'COPY_FIELD'  # OpenFlow 1.5 or later
+METER = 'METER'            # OpenFlow 1.5 or later
+EXPERIMENTER = 'EXPERIMENTER'
+
+
+def get_logger(logger=None):
+    # NOTE(jkoelker) use the logger the calling code wants us to
+    if logger is not None:
+        return logger
+
+    return LOG
+
+
+def match_vid_to_str(value, mask, ofpvid_present):
+    if mask is not None:
+        return '0x%04x/0x%04x' % (value, mask)
+
+    if value & ofpvid_present:
+        return str(value & ~ofpvid_present)
+
+    return '0x%04x' % value
+
+
+def to_action(dic, ofp, parser, action_type, util):
+    actions = {COPY_TTL_OUT: parser.OFPActionCopyTtlOut,
+               COPY_TTL_IN: parser.OFPActionCopyTtlIn,
+               DEC_MPLS_TTL: parser.OFPActionDecMplsTtl,
+               POP_VLAN: parser.OFPActionPopVlan,
+               DEC_NW_TTL: parser.OFPActionDecNwTtl}
+    if ofp.OFP_VERSION > ofproto_v1_2.OFP_VERSION:
+        actions[POP_PBB] = parser.OFPActionPopPbb
+
+    need_ethertype = {PUSH_VLAN: parser.OFPActionPushVlan,
+                      PUSH_MPLS: parser.OFPActionPushMpls,
+                      POP_MPLS: parser.OFPActionPopMpls}
+    if ofp.OFP_VERSION > ofproto_v1_2.OFP_VERSION:
+        need_ethertype[PUSH_PBB] = parser.OFPActionPushPbb
+
+    if action_type in actions:
+        return actions[action_type]()
+
+    elif action_type in need_ethertype:
+        ethertype = str_to_int(dic.get('ethertype'))
+        return need_ethertype[action_type](ethertype)
+
+    elif action_type == OUTPUT:
+        out_port = util.ofp_port_from_user(dic.get('port', ofp.OFPP_ANY))
+        max_len = util.ofp_cml_from_user(dic.get('max_len', ofp.OFPCML_MAX))
+        return parser.OFPActionOutput(out_port, max_len)
+
+    elif action_type == SET_MPLS_TTL:
+        mpls_ttl = str_to_int(dic.get('mpls_ttl'))
+        return parser.OFPActionSetMplsTtl(mpls_ttl)
+
+    elif action_type == SET_QUEUE:
+        queue_id = util.ofp_queue_from_user(dic.get('queue_id'))
+        return parser.OFPActionSetQueue(queue_id)
+
+    elif action_type == GROUP:
+        group_id = util.ofp_group_from_user(dic.get('group_id'))
+        return parser.OFPActionGroup(group_id)
+
+    elif action_type == SET_NW_TTL:
+        nw_ttl = str_to_int(dic.get('nw_ttl'))
+        return parser.OFPActionSetNwTtl(nw_ttl)
+
+    elif action_type == SET_FIELD:
+        field = dic.get('field')
+        value = dic.get('value')
+        return parser.OFPActionSetField(**{field: value})
+
+    elif action_type == 'COPY_FIELD':
+        n_bits = str_to_int(dic.get('n_bits'))
+        src_offset = str_to_int(dic.get('src_offset'))
+        dst_offset = str_to_int(dic.get('dst_offset'))
+        oxm_ids = [parser.OFPOxmId(str(dic.get('src_oxm_id'))),
+                   parser.OFPOxmId(str(dic.get('dst_oxm_id')))]
+        return parser.OFPActionCopyField(
+            n_bits, src_offset, dst_offset, oxm_ids)
+
+    elif action_type == 'METER':
+        if hasattr(parser, 'OFPActionMeter'):
+            # OpenFlow 1.5 or later
+            meter_id = str_to_int(dic.get('meter_id'))
+            return parser.OFPActionMeter(meter_id)
+        else:
+            # OpenFlow 1.4 or earlier
+            return None
+
+    elif action_type == EXPERIMENTER:
+        experimenter = str_to_int(dic.get('experimenter'))
+        data_type = dic.get('data_type', 'ascii')
+
+        if data_type not in ('ascii', 'base64'):
+            LOG.error('Unknown data type: %s', data_type)
+            return None
+
+        data = dic.get('data', '')
+        if data_type == 'base64':
+            data = base64.b64decode(data)
+        return parser.OFPActionExperimenterUnknown(experimenter, data)
+
+    return None
+
+
+def to_match_eth(value):
+    if '/' in value:
+        value = value.split('/')
+        return value[0], value[1]
+
+    return value
+
+
+def to_match_ip(value):
+    if '/' in value:
+        (ip_addr, ip_mask) = value.split('/')
+
+        if ip_mask.isdigit():
+            ip = netaddr.ip.IPNetwork(value)
+            ip_addr = str(ip.ip)
+            ip_mask = str(ip.netmask)
+
+        return ip_addr, ip_mask
+
+    return value
+
+
+def to_match_vid(value, ofpvid_present):
+    # NOTE: If "vlan_id" field is described as decimal int value
+    #       (and decimal string value), it is treated as values of
+    #       VLAN tag, and OFPVID_PRESENT(0x1000) bit is automatically
+    #       applied. OTOH, If it is described as hexadecimal string,
+    #       treated as values of oxm_value (including OFPVID_PRESENT
+    #       bit), and OFPVID_PRESENT bit is NOT automatically applied
+    if isinstance(value, six.integer_types):
+        # described as decimal int value
+        return value | ofpvid_present
+
+    else:
+        if '/' in value:
+            val = value.split('/')
+            return str_to_int(val[0]), str_to_int(val[1])
+
+        else:
+            if value.isdigit():
+                # described as decimal string value
+                return int(value, 10) | ofpvid_present
+
+            return str_to_int(value)
+
+
+def to_match_masked_int(value):
+    if isinstance(value, str) and '/' in value:
+        value = value.split('/')
+        return str_to_int(value[0]), str_to_int(value[1])
+
+    return str_to_int(value)
+
+
+def to_match_packet_type(value):
+    if isinstance(value, (list, tuple)):
+        return str_to_int(value[0]) << 16 | str_to_int(value[1])
+    else:
+        return str_to_int(value)
+
+
+def send_experimenter(dp, exp, logger=None):
+    experimenter = exp.get('experimenter', 0)
+    exp_type = exp.get('exp_type', 0)
+    data_type = exp.get('data_type', 'ascii')
+
+    data = exp.get('data', '')
+    if data_type == 'base64':
+        data = base64.b64decode(data)
+    elif data_type == 'ascii':
+        data = data.encode('ascii')
+    else:
+        get_logger(logger).error('Unknown data type: %s', data_type)
+        return
+
+    expmsg = dp.ofproto_parser.OFPExperimenter(
+        dp, experimenter, exp_type, data)
+    send_msg(dp, expmsg, logger)
+
+
+def send_msg(dp, msg, logger=None):
+    if msg.xid is None:
+        dp.set_xid(msg)
+
+    log = get_logger(logger)
+    # NOTE(jkoelker) Prevent unnecessary string formating by including the
+    #                format rules in the log_msg
+    log_msg = ('Sending message with xid(%x) to '
+               'datapath(' + dpid._DPID_FMT + '): %s')
+    log.debug(log_msg, msg.xid, dp.id, msg)
+    dp.send_msg(msg)
+
+
+def send_stats_request(dp, stats, waiters, msgs, logger=None):
+    dp.set_xid(stats)
+    waiters_per_dp = waiters.setdefault(dp.id, {})
+    lock = hub.Event()
+    previous_msg_len = len(msgs)
+    waiters_per_dp[stats.xid] = (lock, msgs)
+    send_msg(dp, stats, logger)
+
+    lock.wait(timeout=DEFAULT_TIMEOUT)
+    current_msg_len = len(msgs)
+
+    while current_msg_len > previous_msg_len:
+        previous_msg_len = current_msg_len
+        lock.wait(timeout=DEFAULT_TIMEOUT)
+        current_msg_len = len(msgs)
+
+    if not lock.is_set():
+        del waiters_per_dp[stats.xid]
+
+
+def str_to_int(str_num):
+    return int(str(str_num), 0)
+
+
+def get_role(dp, waiters, to_user):
+    stats = dp.ofproto_parser.OFPRoleRequest(
+        dp, dp.ofproto.OFPCR_ROLE_NOCHANGE, generation_id=0)
+    msgs = []
+    send_stats_request(dp, stats, waiters, msgs, LOG)
+    descs = []
+
+    for msg in msgs:
+        d = msg.to_jsondict()[msg.__class__.__name__]
+        if to_user:
+            d['role'] = OFCtlUtil(dp.ofproto).ofp_role_to_user(d['role'])
+        descs.append(d)
+
+    return {str(dp.id): descs}
+
+
+class OFCtlUtil(object):
+
+    def __init__(self, ofproto):
+        self.ofproto = ofproto
+        self.deprecated_value = [
+            'OFPTFPT_EXPERIMENTER_SLAVE',
+            'OFPTFPT_EXPERIMENTER_MASTER',
+            'OFPQCFC_EPERM']
+
+    def _reserved_num_from_user(self, num, prefix):
+        try:
+            return str_to_int(num)
+        except ValueError:
+            try:
+                if num.startswith(prefix):
+                    return getattr(self.ofproto, num.upper())
+                else:
+                    return getattr(self.ofproto, prefix + num.upper())
+            except AttributeError:
+                LOG.warning(
+                    "Cannot convert argument to reserved number: %s", num)
+        return num
+
+    def _reserved_num_to_user(self, num, prefix):
+        for k, v in self.ofproto.__dict__.items():
+            if k not in self.deprecated_value and \
+               k.startswith(prefix) and v == num:
+                return k.replace(prefix, '')
+        return num
+
+    def ofp_port_features_from_user(self, act):
+        return self._reserved_num_from_user(act, 'OFPPF_')
+
+    def ofp_port_features_to_user(self, act):
+        return self._reserved_num_to_user(act, 'OFPPF_')
+
+    def ofp_port_mod_prop_type_from_user(self, act):
+        return self._reserved_num_from_user(act, 'OFPPMPT_')
+
+    def ofp_port_mod_prop_type_to_user(self, act):
+        return self._reserved_num_to_user(act, 'OFPPMPT_')
+
+    def ofp_port_desc_prop_type_from_user(self, act):
+        return self._reserved_num_from_user(act, 'OFPPDPT_')
+
+    def ofp_port_desc_prop_type_to_user(self, act):
+        return self._reserved_num_to_user(act, 'OFPPDPT_')
+
+    def ofp_action_type_from_user(self, act):
+        return self._reserved_num_from_user(act, 'OFPAT_')
+
+    def ofp_action_type_to_user(self, act):
+        return self._reserved_num_to_user(act, 'OFPAT_')
+
+    def ofp_instruction_type_from_user(self, act):
+        return self._reserved_num_from_user(act, 'OFPIT_')
+
+    def ofp_instruction_type_to_user(self, act):
+        return self._reserved_num_to_user(act, 'OFPIT_')
+
+    def ofp_group_type_from_user(self, act):
+        return self._reserved_num_from_user(act, 'OFPGT_')
+
+    def ofp_group_type_to_user(self, act):
+        return self._reserved_num_to_user(act, 'OFPGT_')
+
+    def ofp_meter_band_type_from_user(self, act):
+        return self._reserved_num_from_user(act, 'OFPMBT_')
+
+    def ofp_meter_band_type_to_user(self, act):
+        return self._reserved_num_to_user(act, 'OFPMBT_')
+
+    def ofp_table_feature_prop_type_from_user(self, act):
+        return self._reserved_num_from_user(act, 'OFPTFPT_')
+
+    def ofp_table_feature_prop_type_to_user(self, act):
+        return self._reserved_num_to_user(act, 'OFPTFPT_')
+
+    def ofp_port_stats_prop_type_from_user(self, act):
+        return self._reserved_num_from_user(act, 'OFPPSPT_')
+
+    def ofp_port_stats_prop_type_to_user(self, act):
+        return self._reserved_num_to_user(act, 'OFPPSPT_')
+
+    def ofp_queue_desc_prop_type_from_user(self, act):
+        return self._reserved_num_from_user(act, 'OFPQDPT_')
+
+    def ofp_queue_desc_prop_type_to_user(self, act):
+        return self._reserved_num_to_user(act, 'OFPQDPT_')
+
+    def ofp_queue_stats_prop_type_from_user(self, act):
+        return self._reserved_num_from_user(act, 'OFPQSPT_')
+
+    def ofp_queue_stats_prop_type_to_user(self, act):
+        return self._reserved_num_to_user(act, 'OFPQSPT_')
+
+    def ofp_meter_flags_from_user(self, act):
+        return self._reserved_num_from_user(act, 'OFPMF_')
+
+    def ofp_meter_flags_to_user(self, act):
+        return self._reserved_num_to_user(act, 'OFPMF_')
+
+    def ofp_port_from_user(self, port):
+        return self._reserved_num_from_user(port, 'OFPP_')
+
+    def ofp_port_to_user(self, port):
+        return self._reserved_num_to_user(port, 'OFPP_')
+
+    def ofp_table_from_user(self, table):
+        return self._reserved_num_from_user(table, 'OFPTT_')
+
+    def ofp_table_to_user(self, table):
+        return self._reserved_num_to_user(table, 'OFPTT_')
+
+    def ofp_cml_from_user(self, max_len):
+        return self._reserved_num_from_user(max_len, 'OFPCML_')
+
+    def ofp_cml_to_user(self, max_len):
+        return self._reserved_num_to_user(max_len, 'OFPCML_')
+
+    def ofp_group_from_user(self, group):
+        return self._reserved_num_from_user(group, 'OFPG_')
+
+    def ofp_group_to_user(self, group):
+        return self._reserved_num_to_user(group, 'OFPG_')
+
+    def ofp_group_capabilities_from_user(self, group):
+        return self._reserved_num_from_user(group, 'OFPGFC_')
+
+    def ofp_group_capabilities_to_user(self, group):
+        return self._reserved_num_to_user(group, 'OFPGFC_')
+
+    def ofp_group_bucket_prop_type_from_user(self, group):
+        return self._reserved_num_from_user(group, 'OFPGBPT_')
+
+    def ofp_group_bucket_prop_type_to_user(self, group):
+        return self._reserved_num_to_user(group, 'OFPGBPT_')
+
+    def ofp_buffer_from_user(self, buffer):
+        if buffer in ['OFP_NO_BUFFER', 'NO_BUFFER']:
+            return self.ofproto.OFP_NO_BUFFER
+        else:
+            return buffer
+
+    def ofp_buffer_to_user(self, buffer):
+        if self.ofproto.OFP_NO_BUFFER == buffer:
+            return 'NO_BUFFER'
+        else:
+            return buffer
+
+    def ofp_meter_from_user(self, meter):
+        return self._reserved_num_from_user(meter, 'OFPM_')
+
+    def ofp_meter_to_user(self, meter):
+        return self._reserved_num_to_user(meter, 'OFPM_')
+
+    def ofp_queue_from_user(self, queue):
+        return self._reserved_num_from_user(queue, 'OFPQ_')
+
+    def ofp_queue_to_user(self, queue):
+        return self._reserved_num_to_user(queue, 'OFPQ_')
+
+    def ofp_role_from_user(self, role):
+        return self._reserved_num_from_user(role, 'OFPCR_ROLE_')
+
+    def ofp_role_to_user(self, role):
+        return self._reserved_num_to_user(role, 'OFPCR_ROLE_')