On Wed, 18 Dec 2013 16:18:07 +0900
"watanabe.fumitaka" <[email protected]> wrote:

> Support metadata in FlowMod instructions and match.
> 
> 
> Please specify mod_flow_entry IF parameter as follows.
> 
>  flow = {'match': {'metadata': '12345/fff'},
>          'actions': [ {'type': 'WRITE_METADATA',
>                        'metadata': '12345',
>                        'metadata_mask': 'fff'}]}

Thanks.

I think that explicitly using the hex would be less confusing for the
mask like 0xfff.


> 
> Signed-off-by: WATANABE Fumitaka <[email protected]>
> ---
>  ryu/lib/ofctl_v1_3.py |  140 
> ++++++++++++++++++++++++++++++++-----------------
>  1 file changed, 91 insertions(+), 49 deletions(-)
> 
> diff --git a/ryu/lib/ofctl_v1_3.py b/ryu/lib/ofctl_v1_3.py
> index 752d518..c23ea81 100644
> --- a/ryu/lib/ofctl_v1_3.py
> +++ b/ryu/lib/ofctl_v1_3.py
> @@ -29,7 +29,7 @@ LOG = logging.getLogger('ryu.lib.ofctl_v1_3')
>  DEFAULT_TIMEOUT = 1.0
> 
> 
> -def to_actions(dp, acts):
> +def to_instructions(dp, acts):
>      inst = []
>      actions = []
>      ofp = dp.ofproto
> @@ -100,6 +100,13 @@ def to_actions(dp, acts):
>          elif action_type == 'GOTO_TABLE':
>              table_id = int(a.get('table_id'))
>              inst.append(parser.OFPInstructionGotoTable(table_id))
> +        elif action_type == 'WRITE_METADATA':
> +            metadata = int(a.get('metadata'))
> +            metadata_mask = (int(a['metadata_mask'], 16)
> +                             if 'metadata_mask' in a
> +                             else ofproto_v1_3_parser.UINT64_MAX)
> +            inst.append(
> +                parser.OFPInstructionWriteMetadata(metadata, metadata_mask))
>          else:
>              LOG.debug('Unknown action type: %s' % action_type)
> 
> @@ -108,53 +115,68 @@ def to_actions(dp, acts):
>      return inst
> 
> 
> -def actions_to_str(instructions):
> -    actions = []
> +def instructions_to_str(instructions):
> +    inst = []
> 
>      for instruction in instructions:
> -        if not isinstance(instruction,
> -                          ofproto_v1_3_parser.OFPInstructionActions):
> +        if isinstance(instruction,
> +                       ofproto_v1_3_parser.OFPInstructionActions):
> +            for a in instruction.actions:
> +                action_type = a.cls_action_type
> +
> +                if action_type == ofproto_v1_3.OFPAT_OUTPUT:
> +                    buf = 'OUTPUT:' + str(a.port)
> +                elif action_type == ofproto_v1_3.OFPAT_COPY_TTL_OUT:
> +                    buf = 'COPY_TTL_OUT'
> +                elif action_type == ofproto_v1_3.OFPAT_COPY_TTL_IN:
> +                    buf = 'COPY_TTL_IN'
> +                elif action_type == ofproto_v1_3.OFPAT_SET_MPLS_TTL:
> +                    buf = 'SET_MPLS_TTL:' + str(a.mpls_ttl)
> +                elif action_type == ofproto_v1_3.OFPAT_DEC_MPLS_TTL:
> +                    buf = 'DEC_MPLS_TTL'
> +                elif action_type == ofproto_v1_3.OFPAT_PUSH_VLAN:
> +                    buf = 'PUSH_VLAN:' + str(a.ethertype)
> +                elif action_type == ofproto_v1_3.OFPAT_POP_VLAN:
> +                    buf = 'POP_VLAN'
> +                elif action_type == ofproto_v1_3.OFPAT_PUSH_MPLS:
> +                    buf = 'PUSH_MPLS:' + str(a.ethertype)
> +                elif action_type == ofproto_v1_3.OFPAT_POP_MPLS:
> +                    buf = 'POP_MPLS'
> +                elif action_type == ofproto_v1_3.OFPAT_OFPAT_SET_QUEUE:
> +                    buf = 'SET_QUEUE:' + str(a.queue_id)
> +                elif action_type == ofproto_v1_3.OFPAT_GROUP:
> +                    pass
> +                elif action_type == ofproto_v1_3.OFPAT_SET_NW_TTL:
> +                    buf = 'SET_NW_TTL:' + str(a.nw_ttl)
> +                elif action_type == ofproto_v1_3.OFPAT_DEC_NW_TTL:
> +                    buf = 'DEC_NW_TTL'
> +                elif action_type == ofproto_v1_3.OFPAT_SET_FIELD:
> +                    buf = 'SET_FIELD: {%s:%s}' % (a.field, a.value)
> +                elif action_type == ofproto_v1_3.OFPAT_PUSH_PBB:
> +                    buf = 'PUSH_PBB:' + str(a.ethertype)
> +                elif action_type == ofproto_v1_3.OFPAT_POP_PBB:
> +                    buf = 'POP_PBB'
> +                else:
> +                    buf = 'UNKNOWN'
> +                inst.append(buf)
> +
> +        elif isinstance(instruction,
> +                          ofproto_v1_3_parser.OFPInstructionGotoTable):
> +            buf = 'GOTO_TABLE:' + str(instruction.table_id)
> +            inst.append(buf)
> +
> +        elif isinstance(instruction,
> +                          ofproto_v1_3_parser.OFPInstructionWriteMetadata):
> +            buf = ('WRITE_METADATA:%d/0x%x' % (instruction.metadata,
> +                                             instruction.metadata_mask)
> +                   if instruction.metadata_mask
> +                   else 'WRITE_METADATA:%d' % instruction.metadata)
> +            inst.append(buf)
> +
> +        else:
>              continue
> -        for a in instruction.actions:
> -            action_type = a.cls_action_type
> -
> -            if action_type == ofproto_v1_3.OFPAT_OUTPUT:
> -                buf = 'OUTPUT:' + str(a.port)
> -            elif action_type == ofproto_v1_3.OFPAT_COPY_TTL_OUT:
> -                buf = 'COPY_TTL_OUT'
> -            elif action_type == ofproto_v1_3.OFPAT_COPY_TTL_IN:
> -                buf = 'COPY_TTL_IN'
> -            elif action_type == ofproto_v1_3.OFPAT_SET_MPLS_TTL:
> -                buf = 'SET_MPLS_TTL:' + str(a.mpls_ttl)
> -            elif action_type == ofproto_v1_3.OFPAT_DEC_MPLS_TTL:
> -                buf = 'DEC_MPLS_TTL'
> -            elif action_type == ofproto_v1_3.OFPAT_PUSH_VLAN:
> -                buf = 'PUSH_VLAN:' + str(a.ethertype)
> -            elif action_type == ofproto_v1_3.OFPAT_POP_VLAN:
> -                buf = 'POP_VLAN'
> -            elif action_type == ofproto_v1_3.OFPAT_PUSH_MPLS:
> -                buf = 'PUSH_MPLS:' + str(a.ethertype)
> -            elif action_type == ofproto_v1_3.OFPAT_POP_MPLS:
> -                buf = 'POP_MPLS'
> -            elif action_type == ofproto_v1_3.OFPAT_OFPAT_SET_QUEUE:
> -                buf = 'SET_QUEUE:' + str(a.queue_id)
> -            elif action_type == ofproto_v1_3.OFPAT_GROUP:
> -                pass
> -            elif action_type == ofproto_v1_3.OFPAT_SET_NW_TTL:
> -                buf = 'SET_NW_TTL:' + str(a.nw_ttl)
> -            elif action_type == ofproto_v1_3.OFPAT_DEC_NW_TTL:
> -                buf = 'DEC_NW_TTL'
> -            elif action_type == ofproto_v1_3.OFPAT_SET_FIELD:
> -                buf = 'SET_FIELD: {%s:%s}' % (a.field, a.value)
> -            elif action_type == ofproto_v1_3.OFPAT_PUSH_PBB:
> -                buf = 'PUSH_PBB:' + str(a.ethertype)
> -            elif action_type == ofproto_v1_3.OFPAT_POP_PBB:
> -                buf = 'POP_PBB'
> -            else:
> -                buf = 'UNKNOWN'
> -            actions.append(buf)
> 
> -    return actions
> +    return inst
> 
> 
>  def to_match(dp, attrs):
> @@ -170,7 +192,8 @@ def to_match(dp, attrs):
>                 'nw_proto': int,
>                 'tp_src': int,
>                 'tp_dst': int,
> -               'mpls_label': int}
> +               'mpls_label': int,
> +               'metadata': to_match_metadata}
> 
>      match_append = {'in_port': match.set_in_port,
>                      'dl_src': match.set_dl_src,
> @@ -182,7 +205,8 @@ def to_match(dp, attrs):
>                      'nw_proto': match.set_ip_proto,
>                      'tp_src': to_match_tpsrc,
>                      'tp_dst': to_match_tpdst,
> -                    'mpls_label': match.set_mpls_label}
> +                    'mpls_label': match.set_mpls_label,
> +                    'metadata': match.set_metadata_masked}
> 
>      for key, value in attrs.items():
>          if key in convert:
> @@ -196,6 +220,11 @@ def to_match(dp, attrs):
>              elif key == 'tp_src' or key == 'tp_dst':
>                  # tp_src/dst
>                  match = match_append[key](value, match, attrs)
> +            elif key == 'metadata':
> +                # metadata
> +                metadata = value[0]
> +                metadata_mask = value[1]
> +                match_append[key](metadata, metadata_mask)
>              else:
>                  # others
>                  match_append[key](value)
> @@ -239,6 +268,14 @@ def to_match_ip(value):
>      return ipv4, netmask
> 
> 
> +def to_match_metadata(value):
> +    if '/'in value:
> +        metadata = value.split('/')
> +        return int(metadata[0]), int(metadata[1], 16)
> +    else:
> +        return int(value), ofproto_v1_3_parser.UINT64_MAX
> +
> +
>  def match_to_str(ofmatch):
>      keys = {ofproto_v1_3.OXM_OF_IN_PORT: 'in_port',
>              ofproto_v1_3.OXM_OF_ETH_SRC: 'dl_src',
> @@ -253,7 +290,9 @@ def match_to_str(ofmatch):
>              ofproto_v1_3.OXM_OF_TCP_SRC: 'tp_src',
>              ofproto_v1_3.OXM_OF_TCP_DST: 'tp_dst',
>              ofproto_v1_3.OXM_OF_UDP_SRC: 'tp_src',
> -            ofproto_v1_3.OXM_OF_UDP_DST: 'tp_dst'}
> +            ofproto_v1_3.OXM_OF_UDP_DST: 'tp_dst',
> +            ofproto_v1_3.OXM_OF_METADATA: 'metadata',
> +            ofproto_v1_3.OXM_OF_METADATA_W: 'metadata'}
> 
>      match = {}
>      for match_field in ofmatch.fields:
> @@ -262,6 +301,9 @@ def match_to_str(ofmatch):
>              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)
> +        elif key == 'metadata':
> +            value = ('%d/0x%x' % (match_field.value, match_field.mask)
> +                     if match_field.mask else '%d' % match_field.value)
>          else:
>              value = match_field.value
>          match.setdefault(key, value)
> @@ -329,7 +371,7 @@ def get_flow_stats(dp, waiters):
>      flows = []
>      for msg in msgs:
>          for stats in msg.body:
> -            actions = actions_to_str(stats.instructions)
> +            actions = instructions_to_str(stats.instructions)
>              match = match_to_str(stats.match)
> 
>              s = {'priority': stats.priority,
> @@ -388,7 +430,7 @@ def mod_flow_entry(dp, flow, cmd):
>      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', []))
> +    inst = to_instructions(dp, flow.get('actions', []))
> 
>      flow_mod = dp.ofproto_parser.OFPFlowMod(
>          dp, cookie, cookie_mask, table_id, cmd, idle_timeout,
> -- 1.7.10.4
> 
> 
> 
> ------------------------------------------------------------------------------
> Rapidly troubleshoot problems before they affect your business. Most IT 
> organizations don't have a clear picture of how application performance 
> affects their revenue. With AppDynamics, you get 100% visibility into your 
> Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro!
> http://pubads.g.doubleclick.net/gampad/clk?id=84349831&iu=/4140/ostg.clktrk
> _______________________________________________
> Ryu-devel mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/ryu-devel

------------------------------------------------------------------------------
Rapidly troubleshoot problems before they affect your business. Most IT 
organizations don't have a clear picture of how application performance 
affects their revenue. With AppDynamics, you get 100% visibility into your 
Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro!
http://pubads.g.doubleclick.net/gampad/clk?id=84349831&iu=/4140/ostg.clktrk
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to