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