def get_action_wc(acts): """Return a rewrite mask, rewrite HS, and the list of outports from the action list `acts` provided. For interpretation of these fields check the doctext of hsa.headerspace.tf create_standard_rule. In this function, we assume that the actions correspond to the actions of a single-stage table classifier, in addition to other restrictions. Specifically: - all non-`modify` actions are ignored - actions that do not set an output port are ignored - if there are multiple actions satisfying the above conditions, they may only simply output the packet via a port. i.e., No packet modifications. This is an artificial restriction because tf.create_standard_rule can only take a single rewrite wildcard for packet modification. """ new_acts = filter(lambda x: isinstance(x, modify) and 'port' in x.map, acts) outports = [] '''The current transfer function rule implementation can only take one new header space in rewrite rules if there are multiple outports involved. If there is only one action, multiple field rewrites are possible. A port must be set for rewrites to be active. ''' if len(new_acts) > 1: hsa_compilable = reduce(lambda acc, a: acc and a.map.keys() == ['port'], new_acts, True) outports = map(lambda x: x.map['port'], new_acts) if hsa_compilable: return (None, None, outports, False) else: raise RuntimeError("actions not HSA-compilable! %s" % acts) elif len(new_acts) == 1: mod_dict = copy.copy(new_acts[0].map) if 'port' in mod_dict: outports = [mod_dict['port']] del mod_dict['port'] else: return (None, None, [], False) if len(mod_dict.keys()) > 0: ''' There are rewritten packet header fields. ''' rw_rule = True mask = wildcard_create_bit_repeat(hsf["length"], 0x2) rewrite = wildcard_create_bit_repeat(hsf["length"], 0x1) for (field, val) in mod_dict.iteritems(): set_field_val(hsf, mask, field, 0, process_field=False) set_field_val(hsf, rewrite, field, val) return (mask, rewrite, outports, True) else: return (None, None, outports, False) else: ''' No modify actions ''' return (None, None, [], False)
def wc_header_to_parsed_string(hs_format, fields, i_wc): out_string = "" for field in fields: offset = hs_format["%s_pos" % field] len = hs_format["%s_len" % field] w = wildcard_create_bit_repeat(len, 0x1) for i in range(0, len): w[i] = i_wc[offset + i] out_string = "%s%s:%s, " % (out_string, field, w) return out_string
def wc_header_to_parsed_string(hs_format, fields, i_wc): out_string = "" for field in fields: offset = hs_format["%s_pos"%field] len = hs_format["%s_len"%field] w = wildcard_create_bit_repeat(len,0x1) for i in range(0,len): w[i] = i_wc[offset+i] out_string = "%s%s:%s, "%(out_string, field, w) return out_string
def get_match_wc(hsf, mat_map): """ Generate a wildcard from a pyretic match dictionary. """ mat = wildcard_create_bit_repeat(hsf["length"], 3) for (field, val) in mat_map.iteritems(): set_field_val(hsf, mat, field, val) return mat