Exemplo n.º 1
0
 def __add_action_to_rule(self, action, rule, rtr):
     #print "Action:", action, " Rule: ",rule
     mask = wildcard_create_bit_repeat(self.format["length"], 2)
     rewrite = wildcard_create_bit_repeat(self.format["length"], 1)
     out_ports = []
     rw = False
     push = False
     pop = False
     for operation in action.keys():
         if operation == "set_nw_src" or operation == "set_nw_dst":
             rw = True
             set_header_field(self.format, mask, operation[4:], 0, 0)
             set_header_field(self.format, rewrite, operation[4:],
                              dotted_ip_to_int(action[operation]), 0)
         elif operation == "set_dl_src" or operation == "set_dl_dst":
             rw = True
             set_header_field(self.format, mask, operation[4:], 0, 0)
             set_header_field(self.format, rewrite, operation[4:],
                              mac_to_int(action[operation]), 0)
         elif operation == "output":
             '''
             if action[operation] in self.port_members:
               out_ports = self.__encode_port_list(self.port_members[action[operation]],rtr)
             else:
             '''
             if action[operation].startswith("mport"):
                 out_ports = self.__expand_mport(rtr, action[operation])
             else:
                 out_ports = [action[operation]]
             out_ports = self.__compress_port_list(out_ports)
             out_ports = self.__encode_port_list(out_ports, rtr)
         elif operation == "push_ip":
             push = True
             rule["encap_pos"] = self.format["nw_src_pos"]
             rule["encap_len"] = 8
         elif operation == "pop_ip":
             pop = True
             rule["decap_pos"] = self.format["nw_src_pos"]
             rule["decap_len"] = 8
     rule["out_ports"] = out_ports
     if push:
         rule["action"] = "encap"
         rule["mask"] = mask
         rule["rewrite"] = rewrite
     elif pop:
         rule["action"] = "decap"
         rule["mask"] = None
         rule["rewrite"] = None
     elif rw:
         rule["action"] = "rw"
         rule["mask"] = mask
         rule["rewrite"] = rewrite
     else:
         rule["action"] = "fwd"
         rule["mask"] = None
         rule["rewrite"] = None
Exemplo n.º 2
0
    def parse_rule(self, rule):
        '''
        Parses a single rule and generate openflow entry for that rule.
        the resulting openflow entry will have this format:
        FIEDL_wc: if the field is not wildcarded (0) or wildcarded (1) for IP fields, this a number between 0-32
        counting number of wildcarded bits from right
        FIELD_match: the match value for this field, after applying appropriate wildcard.
        FIELD_new: in case of a rewrite action, the new field value to be rewritten.
        '''
        fields = [
            "mac_src", "mac_dst", "vlan", "ip_src", "ip_dst", "ip_proto",
            "transport_src", "transport_dst"
        ]
        openflow_entry = {}
        for field in fields:
            if "%s_pos" % field not in self.hs_format.keys():
                continue

            position = self.hs_format["%s_pos" % field]
            l = self.hs_format["%s_len" % field]
            wildcarded = True
            field_match = wildcard_create_bit_repeat(l, 0x1)
            field_mask = wildcard_create_bit_repeat(l, 0x1)
            field_rewrite = wildcard_create_bit_repeat(l, 0x1)
            for i in range(l):
                field_match[i] = rule["match"][position + i]
                if rule["mask"] != None:
                    field_mask[i] = rule["mask"][position + i]
                    field_rewrite[i] = rule["rewrite"][position + i]
                if field_match[i] != 0xffff:
                    wildcarded = False

            if wildcarded:
                if field == "ip_src" or field == "ip_dst":
                    openflow_entry["%s_wc" % field] = 32
                else:
                    openflow_entry["%s_wc" % field] = 1
                openflow_entry["%s_match" % field] = 0
            else:
                if field == "ip_src" or field == "ip_dst":
                    parsed = self.parse_non_wc_field(field_match, True)
                else:
                    parsed = self.parse_non_wc_field(field_match, False)
                openflow_entry["%s_wc" % field] = parsed[1]
                openflow_entry["%s_match" % field] = parsed[0]

            if (rule["mask"] != None):
                openflow_entry["%s_new"%field] = self.find_new_field(\
                                                  field_match,field_mask,field_rewrite)
            else:
                openflow_entry["%s_new" % field] = None

            openflow_entry["in_ports"] = rule["in_ports"]
            openflow_entry["out_ports"] = rule["out_ports"]

        return openflow_entry
Exemplo n.º 3
0
 def __add_action_to_rule(self,action,rule,rtr):
   #print "Action:", action, " Rule: ",rule
   mask = wildcard_create_bit_repeat(self.format["length"],2)
   rewrite = wildcard_create_bit_repeat(self.format["length"],1)
   out_ports = []
   rw = False
   push = False
   pop = False
   for operation in action.keys():
     if operation == "set_nw_src" or operation == "set_nw_dst":
       rw = True
       set_header_field(self.format, mask, operation[4:], 0, 0)
       set_header_field(self.format, rewrite, operation[4:], dotted_ip_to_int(action[operation]), 0)
     elif operation == "set_dl_src" or operation == "set_dl_dst":
       rw = True
       set_header_field(self.format, mask, operation[4:], 0, 0)
       set_header_field(self.format, rewrite, operation[4:], mac_to_int(action[operation]), 0)
     elif operation == "output":
       '''
       if action[operation] in self.port_members:
         out_ports = self.__encode_port_list(self.port_members[action[operation]],rtr)
       else:
       '''
       if action[operation].startswith("mport"):
         out_ports = self.__expand_mport(rtr, action[operation])
       else:
         out_ports = [action[operation]]
       out_ports = self.__compress_port_list(out_ports)
       out_ports = self.__encode_port_list(out_ports, rtr)
     elif operation == "push_ip":
       push = True
       rule["encap_pos"] = self.format["nw_src_pos"]
       rule["encap_len"] = 8
     elif operation == "pop_ip":
       pop = True
       rule["decap_pos"] = self.format["nw_src_pos"]
       rule["decap_len"] = 8
   rule["out_ports"] = out_ports
   if push:
     rule["action"] = "encap"
     rule["mask"] = mask
     rule["rewrite"] = rewrite
   elif pop:
     rule["action"] = "decap"
     rule["mask"] = None
     rule["rewrite"] = None
   elif rw:
     rule["action"] = "rw"
     rule["mask"] = mask
     rule["rewrite"] = rewrite
   else:
     rule["action"] = "fwd"
     rule["mask"] = None
     rule["rewrite"] = None
Exemplo n.º 4
0
 def __init__(self, name, hs, ports, length):
     '''
     @name: a unique name for this source node
     '''
     Node.__init__(self)
     self.node_id = name
     self.output_ports = ports
     self.input_ports = []
     hs.push_applied_tf_rule(None, self.node_id, None)
     self.source_flow.append((hs, None))
     self.match = wildcard_create_bit_repeat(length, 0x3)
     self.inverse_match = wildcard_create_bit_repeat(length, 0x3)
  def parse_rule(self,rule):
    '''
    Parses a single rule and generate openflow entry for that rule.
    the resulting openflow entry will have this format:
    FIEDL_wc: if the field is not wildcarded (0) or wildcarded (1) for IP fields, this a number between 0-32
    counting number of wildcarded bits from right
    FIELD_match: the match value for this field, after applying appropriate wildcard.
    FIELD_new: in case of a rewrite action, the new field value to be rewritten.
    '''
    fields = ["mac_src", "mac_dst", "vlan", "ip_src", "ip_dst", "ip_proto", "transport_src", "transport_dst"]
    openflow_entry = {}
    for field in fields:
      if "%s_pos"%field not in self.hs_format.keys():
        continue
      
      position = self.hs_format["%s_pos"%field]
      l = self.hs_format["%s_len"%field]
      wildcarded = True
      field_match = wildcard_create_bit_repeat(l,0x1)
      field_mask = wildcard_create_bit_repeat(l,0x1)
      field_rewrite = wildcard_create_bit_repeat(l,0x1)
      for i in range(l):
        field_match[i] = rule["match"][position+i]
        if rule["mask"] != None:
          field_mask[i] = rule["mask"][position+i]
          field_rewrite[i] = rule["rewrite"][position+i]
        if field_match[i] != 0xffff:
          wildcarded = False

      if wildcarded:
        if field == "ip_src" or field == "ip_dst":
          openflow_entry["%s_wc"%field] = 32
        else:
          openflow_entry["%s_wc"%field] = 1
        openflow_entry["%s_match"%field] = 0
      else:
        if field == "ip_src" or field == "ip_dst":
          parsed = self.parse_non_wc_field(field_match, True)
        else:
          parsed = self.parse_non_wc_field(field_match, False)
        openflow_entry["%s_wc"%field] = parsed[1]
        openflow_entry["%s_match"%field] = parsed[0]
        
      if (rule["mask"] != None):
        openflow_entry["%s_new"%field] = self.find_new_field(\
                                          field_match,field_mask,field_rewrite)
      else:
        openflow_entry["%s_new"%field] = None
        
      openflow_entry["in_ports"] = rule["in_ports"]
      openflow_entry["out_ports"] = rule["out_ports"]
    
    return openflow_entry
Exemplo n.º 6
0
 def __init__(self,name,hs,ports,length):
     '''
     @name: a unique name for this source node
     '''
     Node.__init__(self)
     self.node_id = name
     self.output_ports = ports
     self.input_ports = []
     hs.push_applied_tf_rule(None, self.node_id, None)
     self.source_flow.append((hs,None))
     self.match = wildcard_create_bit_repeat(length,0x3)
     self.inverse_match = wildcard_create_bit_repeat(length,0x3)
Exemplo n.º 7
0
 def acl_dict_entry_to_wc(self,dic_entry):
     result = []
     result.append(wildcard_create_bit_repeat(self.hs_format["length"],0x3))
     if (dic_entry["ip_protocol"] != 0):
         self.set_field(result[0], "ip_proto", dic_entry["ip_protocol"], 0)
     self.set_field(result[0], "ip_src", dic_entry["src_ip"], find_num_mask_bits_right_mak(dic_entry["src_ip_mask"]))
     self.set_field(result[0], "ip_dst", dic_entry["dst_ip"], find_num_mask_bits_right_mak(dic_entry["dst_ip_mask"]))
     tp_src_matches = range_to_wildcard(dic_entry["transport_src_begin"],dic_entry["transport_src_end"],16)
     tmp = []
     for tp_src_match in tp_src_matches:
         w = wildcard_copy(result[0])
         self.set_field(w, "tcp_src", tp_src_match[0], tp_src_match[1])
         tmp.append(w)
     result = tmp
     tp_dst_matches = range_to_wildcard(dic_entry["transport_dst_begin"],dic_entry["transport_dst_end"],16)
     tmp = []
     for tp_dst_match in tp_dst_matches:
         for r in result:
             w = wildcard_copy(r)
             self.set_field(w, "tcp_dst", tp_dst_match[0], tp_dst_match[1])
             tmp.append(w)
     result = tmp
     tp_ctrl_matches = range_to_wildcard(dic_entry["tcp_ctrl_begin"],dic_entry["tcp_ctrl_end"],8)
     tmp = []
     for tp_ctrl_matche in tp_ctrl_matches:
         for r in result:
             w = wildcard_copy(r)
             self.set_field(w, "tcp_ctrl", tp_ctrl_matche[0], tp_ctrl_matche[1])
             tmp.append(w)
     result = tmp
     return result
Exemplo n.º 8
0
    def find_entries(self,wildcard_search,port):
        m = wildcard_create_bit_repeat(len(self.match_indices),1)
        for i in range(len(self.match_indices)):
            m[i] = wildcard_search[self.match_indices[i]]
        match_key_string = "%s"%m
        index = match_key_string.find('x')
        if index != -1:
            match_key_string = match_key_string[:index]
        elif index == 0:
            return None
        rule_set = []
        try:
            if len(match_key_string) == len(self.exact_match_indices) * 8:
                #full match
                rule_set = self.inport_to_table["%d"%port][match_key_string] \
                    + self.inport_to_table["%d"%port]["default"]
            else:
                #partial match
                for key in self.exact_match_hash["%d"%port].keys():
                    if key.startswith(match_key_string):
                        rule_set += self.inport_to_table["%d"%port][key]
                rule_set += self.inport_to_table["%d"%port]["default"]
        except:
            rule_set = self.exact_match_hash["%d"%port]["default"]

        return rule_set
Exemplo n.º 9
0
 def __parse_flow_match(self,flow_match):
   parts = flow_match.split(" ")
   match = wildcard_create_bit_repeat(self.format["length"],3)
   num_fields = 0
   for part in parts:
     if not part.startswith("priority") and part != "":
       fv = part.split("=")
       field = fv[0]
       value = fv[1]
       if field == "dl_src" or field=="dl_dst":
         '''
         m = mac_to_int(value)
         if m != 0:
           set_header_field(self.format, match, field, m, 0)
         '''
         pass
       elif field == "nw_src" or field == "nw_dst":
         num_fields += 1
         (ip,subnet) = dotted_subnet_to_int(value)
         set_header_field(self.format, match, field, ip, 32-subnet)
       elif field == "nw_tos":
         num_fields += 1
         set_header_field(self.format, match, field, int(value), 0)
       elif field == "dl_type":
         num_fields += 1
         set_header_field(self.format, match, field, l2_proto_to_int(value), 0)
   if num_fields > 0:
     return match
   else:
     return None
Exemplo n.º 10
0
 def __generate_mp_tf_rules(self, rtr):
   result_rules = []
   for mp in self.multipath[rtr]:
     group_rule = {"action":"multipath","rules":[]}
     rule = {}
     rule["in_ports"] = [self.get_port_id(rtr, mp)+self.PORT_TYPE_MULTIPLIER]
     rule["match"] = wildcard_create_bit_repeat(self.format["length"],3)
     is_fwd_action = True
     for single_action in self.multipath[rtr][mp]:
       rule_copy = rule.copy()
       self.__add_action_to_rule(single_action,rule_copy,rtr)
       if (rule_copy["action"] != "fwd"):
         is_fwd_action = False
       group_rule["rules"].append(rule_copy)
     if (is_fwd_action):
       all_out_ports = []
       for g_rule in group_rule["rules"]:
         all_out_ports.extend(g_rule["out_ports"])
       s = set(all_out_ports)
       rule["out_ports"] = self.__compress_port_list(list(s))
       rule["action"] = "fwd"
       rule["mask"] = None
       rule["rewrite"] = None
       group_rule["rules"] = [rule]
       result_rules.append(group_rule)
     else:
       result_rules.append(group_rule)
   return result_rules
Exemplo n.º 11
0
 def __generate_mp_tf_rules(self, rtr):
     result_rules = []
     for mp in self.multipath[rtr]:
         group_rule = {"action": "multipath", "rules": []}
         rule = {}
         rule["in_ports"] = [
             self.get_port_id(rtr, mp) + self.PORT_TYPE_MULTIPLIER
         ]
         rule["match"] = wildcard_create_bit_repeat(self.format["length"],
                                                    3)
         is_fwd_action = True
         for single_action in self.multipath[rtr][mp]:
             rule_copy = rule.copy()
             self.__add_action_to_rule(single_action, rule_copy, rtr)
             if (rule_copy["action"] != "fwd"):
                 is_fwd_action = False
             group_rule["rules"].append(rule_copy)
         if (is_fwd_action):
             all_out_ports = []
             for g_rule in group_rule["rules"]:
                 all_out_ports.extend(g_rule["out_ports"])
             s = set(all_out_ports)
             rule["out_ports"] = self.__compress_port_list(list(s))
             rule["action"] = "fwd"
             rule["mask"] = None
             rule["rewrite"] = None
             group_rule["rules"] = [rule]
             result_rules.append(group_rule)
         else:
             result_rules.append(group_rule)
     return result_rules
Exemplo n.º 12
0
 def __parse_flow_match(self, flow_match):
     parts = flow_match.split(" ")
     match = wildcard_create_bit_repeat(self.format["length"], 3)
     num_fields = 0
     for part in parts:
         if not part.startswith("priority") and part != "":
             fv = part.split("=")
             field = fv[0]
             value = fv[1]
             if field == "dl_src" or field == "dl_dst":
                 '''
                 m = mac_to_int(value)
                 if m != 0:
                   set_header_field(self.format, match, field, m, 0)
                 '''
                 pass
             elif field == "nw_src" or field == "nw_dst":
                 num_fields += 1
                 (ip, subnet) = dotted_subnet_to_int(value)
                 set_header_field(self.format, match, field, ip,
                                  32 - subnet)
             elif field == "nw_tos":
                 num_fields += 1
                 set_header_field(self.format, match, field, int(value), 0)
             elif field == "dl_type":
                 num_fields += 1
                 set_header_field(self.format, match, field,
                                  l2_proto_to_int(value), 0)
     if num_fields > 0:
         return match
     else:
         return None
Exemplo n.º 13
0
    def find_entries(self, wildcard_search, port):
        m = wildcard_create_bit_repeat(len(self.match_indices), 1)
        for i in range(len(self.match_indices)):
            m[i] = wildcard_search[self.match_indices[i]]
        match_key_string = "%s" % m
        index = match_key_string.find('x')
        if index != -1:
            match_key_string = match_key_string[:index]
        elif index == 0:
            return None
        rule_set = []
        try:
            if len(match_key_string) == len(self.exact_match_indices) * 8:
                #full match
                rule_set = self.inport_to_table["%d"%port][match_key_string] \
                    + self.inport_to_table["%d"%port]["default"]
            else:
                #partial match
                for key in self.exact_match_hash["%d" % port].keys():
                    if key.startswith(match_key_string):
                        rule_set += self.inport_to_table["%d" % port][key]
                rule_set += self.inport_to_table["%d" % port]["default"]
        except:
            rule_set = self.exact_match_hash["%d" % port]["default"]

        return rule_set
Exemplo n.º 14
0
def parse_new_rule_tokens(tokens, mapf, rtr):
    in_ports = []
    out_ports = []
    match = wildcard_create_bit_repeat(HS_FORMAT["length"], 0x3)
    mask = None
    rw = None
    for token in tokens:
        parts = token.split("=")
        field_name = parts[0]
        if field_name.startswith("new"):
            if mask == None:
                mask = wildcard_create_bit_repeat(HS_FORMAT["length"], 0x2)
                rw = wildcard_create_bit_repeat(HS_FORMAT["length"], 0x1)
            field_name = field_name[4:]
            if field_name in ["ip_src", "ip_dst"]:
                [value, left_mask] = dotted_subnet_to_int(parts[1])
                right_mask = 32 - left_mask
            else:
                value = int(parts[1])
                right_mask = 0
                set_header_field(cisco_router.HS_FORMAT(), mask, field_name, 0,
                                 right_mask)
                set_header_field(cisco_router.HS_FORMAT(), rw, field_name,
                                 value, right_mask)
        else:
            if field_name in ["in_ports", "out_ports"]:
                ports = parts[1].split(",")
                ports_int = []
                for port in ports:
                    ports_int.append(int(mapf[rtr][port]))
                if field_name == "in_ports":
                    in_ports = ports_int
                else:
                    out_ports = ports_int
            else:
                if field_name in ["ip_src", "ip_dst"]:
                    [value, left_mask] = dotted_subnet_to_int(parts[1])
                    right_mask = 32 - left_mask
                else:
                    value = int(parts[1])
                    right_mask = 0
                set_header_field(cisco_router.HS_FORMAT(), match, field_name,
                                 value, right_mask)
    rule = TF.create_standard_rule(in_ports, match, out_ports, mask, rw, "",
                                   [])
    return rule
Exemplo n.º 15
0
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
Exemplo n.º 16
0
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
Exemplo n.º 17
0
def parse_new_rule_tokens(tokens,mapf,rtr):
    in_ports = []
    out_ports = []
    match = wildcard_create_bit_repeat(HS_FORMAT["length"],0x3)
    mask = None
    rw = None
    for token in tokens:
        parts = token.split("=")
        field_name = parts[0]
        if field_name.startswith("new"):
            if mask == None:
                mask = wildcard_create_bit_repeat(HS_FORMAT["length"],0x2)
                rw = wildcard_create_bit_repeat(HS_FORMAT["length"],0x1)
            field_name = field_name[4:]
            if field_name in ["ip_src","ip_dst"]:
                [value,left_mask] = dotted_subnet_to_int(parts[1])
                right_mask = 32 - left_mask
            else:
                value = int(parts[1])
                right_mask = 0
                set_header_field(cisco_router.HS_FORMAT(), mask, field_name, 0, right_mask)
                set_header_field(cisco_router.HS_FORMAT(), rw, field_name, value, right_mask)
        else:
            if field_name in ["in_ports","out_ports"]:
                ports = parts[1].split(",")
                ports_int = []
                for port in ports:
                    ports_int.append(int(mapf[rtr][port]))
                if field_name == "in_ports":
                    in_ports = ports_int
                else:
                    out_ports = ports_int
            else:
                if field_name in ["ip_src","ip_dst"]:
                    [value,left_mask] = dotted_subnet_to_int(parts[1])
                    right_mask = 32 - left_mask
                else:
                    value = int(parts[1])
                    right_mask = 0
                set_header_field(cisco_router.HS_FORMAT(), match, field_name, value, right_mask)
    rule = TF.create_standard_rule(in_ports, match, out_ports, mask, rw, "", [])
    return rule
Exemplo n.º 18
0
def detect_loop(NTF, TTF, ports, test_packet=None, out_port_offset=0):
    loops = []
    for port in ports:
        print "port %d is being checked" % port
        propagation = []

        # put all-x test packet in propagation graph
        test_pkt = test_packet
        if test_pkt == None:
            all_x = wildcard_create_bit_repeat(NTF.length, 0x3)
            test_pkt = headerspace(NTF.length)
            test_pkt.add_hs(all_x)

        p_node = {}
        p_node["hdr"] = test_pkt
        p_node["port"] = port
        p_node["visits"] = []
        p_node["hs_history"] = []

        propagation.append(p_node)
        while len(propagation) > 0:
            # get the next node in propagation graph and apply it to NTF and TTF
            print "Propagation has length: %d" % len(propagation)
            tmp_propag = []
            for p_node in propagation:
                next_hp = NTF.T(p_node["hdr"], p_node["port"])
                for (next_h, next_ps) in next_hp:
                    for next_p in next_ps:
                        linked = TTF.T(next_h, next_p)
                        for (linked_h, linked_ports) in linked:
                            for linked_p in linked_ports:
                                new_p_node = {}
                                new_p_node["hdr"] = linked_h
                                new_p_node["port"] = linked_p
                                new_p_node["visits"] = list(p_node["visits"])
                                new_p_node["visits"].append(p_node["port"])
                                # new_p_node["visits"].append(next_p)
                                new_p_node["hs_history"] = list(p_node["hs_history"])
                                new_p_node["hs_history"].append(p_node["hdr"])
                                # print new_p_node
                                if len(new_p_node["visits"]) > 0 and new_p_node["visits"][0] == linked_p:
                                    loops.append(new_p_node)
                                    print "loop detected"
                                elif (
                                    linked_p in new_p_node["visits"]
                                    or (linked_p + out_port_offset) in new_p_node["visits"]
                                ):
                                    pass
                                else:
                                    tmp_propag.append(new_p_node)
            propagation = tmp_propag
    return loops
Exemplo n.º 19
0
 def add_entry(self,wildcard_match,ports,obj):
     m = wildcard_create_bit_repeat(len(self.match_indices),1)
     for i in range(len(self.match_indices)):
         m[i] = wildcard_match[self.match_indices[i]]
     match_key_string = "%s"%m
     if 'x' in match_key_string:
         match_key_string = "default"
     for port in ports:
         if str(port) not in self.inport_to_table.keys():
             self.inport_to_table[str(port)] = {}
         if match_key_string not in self.inport_to_table[str(port)].keys():
             self.inport_to_table[str(port)][match_key_string] = []
         self.inport_to_table[str(port)][match_key_string].append(obj)
Exemplo n.º 20
0
 def add_entry(self, wildcard_match, ports, obj):
     m = wildcard_create_bit_repeat(len(self.match_indices), 1)
     for i in range(len(self.match_indices)):
         m[i] = wildcard_match[self.match_indices[i]]
     match_key_string = "%s" % m
     if 'x' in match_key_string:
         match_key_string = "default"
     for port in ports:
         if str(port) not in self.inport_to_table.keys():
             self.inport_to_table[str(port)] = {}
         if match_key_string not in self.inport_to_table[str(port)].keys():
             self.inport_to_table[str(port)][match_key_string] = []
         self.inport_to_table[str(port)][match_key_string].append(obj)
Exemplo n.º 21
0
def make_header(h_desc):
  all_x = wildcard_create_bit_repeat(cisco_router.HS_FORMAT()["length"],0x3)
  parts = h_desc.split(",")
  fields = ["vlan", "ip_src", "ip_dst", "ip_proto", "transport_src", "transport_dst"]
  for part in parts:
    tmp = part.split("=")
    field = tmp[0]
    value = tmp[1]
    if field in ["ip_src","ip_dst"]:
      (ip,sub) = dotted_subnet_to_int(value)
      set_header_field(cisco_router.HS_FORMAT(), all_x, field, ip, 32-sub)
    else:
      set_header_field(cisco_router.HS_FORMAT(), all_x, field, int(value), 0)
  return all_x 
Exemplo n.º 22
0
def make_header(h_desc):
  all_x = wildcard_create_bit_repeat(cisco_router.HS_FORMAT()["length"],0x3)
  parts = h_desc.split(",")
  fields = ["vlan", "ip_src", "ip_dst", "ip_proto", "transport_src", "transport_dst"]
  for part in parts:
    tmp = part.split("=")
    field = tmp[0]
    value = tmp[1]
    if field in ["ip_src","ip_dst"]:
      (ip,sub) = dotted_subnet_to_int(value)
      set_header_field(cisco_router.HS_FORMAT(), all_x, field, ip, 32-sub)
    else:
      set_header_field(cisco_router.HS_FORMAT(), all_x, field, int(value), 0)
  return all_x 
Exemplo n.º 23
0
def detect_loop(NTF, TTF, ports, test_packet = None, out_port_offset = 0):
    loops = []
    for port in ports:
        print "port %d is being checked"%port
        propagation = []

        # put all-x test packet in propagation graph
        test_pkt = test_packet
        if test_pkt == None:
            all_x = wildcard_create_bit_repeat(NTF.length,0x3)
            test_pkt = headerspace(NTF.length)
            test_pkt.add_hs(all_x)

        p_node = {}
        p_node["hdr"] = test_pkt
        p_node["port"] = port
        p_node["visits"] = []
        p_node["hs_history"] = []

        propagation.append(p_node)
        while len(propagation)>0:
            #get the next node in propagation graph and apply it to NTF and TTF
            print "Propagation has length: %d"%len(propagation)
            tmp_propag = []
            for p_node in propagation:
                next_hp = NTF.T(p_node["hdr"],p_node["port"])
                for (next_h,next_ps) in next_hp:
                    for next_p in next_ps:
                        linked = TTF.T(next_h,next_p)
                        for (linked_h,linked_ports) in linked:
                            for linked_p in linked_ports:
                                new_p_node = {}
                                new_p_node["hdr"] = linked_h
                                new_p_node["port"] = linked_p
                                new_p_node["visits"] = list(p_node["visits"])
                                new_p_node["visits"].append(p_node["port"])
                                #new_p_node["visits"].append(next_p)
                                new_p_node["hs_history"] = list(p_node["hs_history"])
                                new_p_node["hs_history"].append(p_node["hdr"])
                                #print new_p_node
                                if len(new_p_node["visits"]) > 0 and new_p_node["visits"][0] == linked_p:
                                    loops.append(new_p_node)
                                    print "loop detected"
                                elif linked_p in new_p_node["visits"] or (linked_p + out_port_offset) in new_p_node["visits"]:
                                    pass
                                else:
                                    tmp_propag.append(new_p_node)
            propagation = tmp_propag
    return loops
Exemplo n.º 24
0
 def acl_dict_entry_to_wc(self, dic_entry):
     result = []
     result.append(wildcard_create_bit_repeat(self.hs_format["length"],
                                              0x3))
     if (dic_entry["ip_protocol"] != 0):
         self.set_field(result[0], "ip_proto", dic_entry["ip_protocol"], 0)
     self.set_field(result[0], "ip_src", dic_entry["src_ip"],
                    find_num_mask_bits_right_mak(dic_entry["src_ip_mask"]))
     self.set_field(result[0], "ip_dst", dic_entry["dst_ip"],
                    find_num_mask_bits_right_mak(dic_entry["dst_ip_mask"]))
     tp_src_matches = range_to_wildcard(dic_entry["transport_src_begin"],
                                        dic_entry["transport_src_end"], 16)
     tmp = []
     for tp_src_match in tp_src_matches:
         w = wildcard_copy(result[0])
         self.set_field(w, "tcp_src", tp_src_match[0], tp_src_match[1])
         tmp.append(w)
     result = tmp
     tp_dst_matches = range_to_wildcard(dic_entry["transport_dst_begin"],
                                        dic_entry["transport_dst_end"], 16)
     tmp = []
     for tp_dst_match in tp_dst_matches:
         for r in result:
             w = wildcard_copy(r)
             self.set_field(w, "tcp_dst", tp_dst_match[0], tp_dst_match[1])
             tmp.append(w)
     result = tmp
     tp_ctrl_matches = range_to_wildcard(dic_entry["tcp_ctrl_begin"],
                                         dic_entry["tcp_ctrl_end"], 8)
     tmp = []
     for tp_ctrl_matche in tp_ctrl_matches:
         for r in result:
             w = wildcard_copy(r)
             self.set_field(w, "tcp_ctrl", tp_ctrl_matche[0],
                            tp_ctrl_matche[1])
             tmp.append(w)
     result = tmp
     return result
Exemplo n.º 25
0
g.read_nodes_xml("path_to_nodes.xml")

settings = {"rtr_names":g.generate_node_names(),
            "num_layers":3,
            "fwd_engine_layer":2,
            "input_path":"tf_files",
            "switch_id_multiplier":cisco_router.SWITCH_ID_MULTIPLIER,
            "port_type_multiplier":cisco_router.PORT_TYPE_MULTIPLIER,
            "out_port_type_const":cisco_router.OUTPUT_PORT_TYPE_CONST,
            "remove_duplicates":True,
            }

(ntf,ttf,name_to_id,id_to_name) = load_network(settings)

# create all-x packet as input headerspace.
all_x = wildcard_create_bit_repeat(ntf.length,0x3)
# uncomment to set some field
#set_header_field(cisco_router.HS_FORMAT(), all_x, "field", value, right_mask)
#set_header_field(cisco_router.HS_FORMAT(), all_x, "vlan", 92, 0)
test_pkt = headerspace(ntf.length)
test_pkt.add_hs(all_x)

#set some input/output ports
output_port_addition = cisco_router.PORT_TYPE_MULTIPLIER * \
cisco_router.OUTPUT_PORT_TYPE_CONST
#TODO: CHANGE THIS IF YOU WANT TO RUN IT FROM/TO DIFFERENT PORTS
src_port_id = name_to_id["ROUTER NAME"]["PORT NAME"]
dst_port_ids = [name_to_id["ROUTER NAME"]["PORT NAME"]+output_port_addition]

#start reachability test and print results
st = time()
Exemplo n.º 26
0
g.read_nodes_xml("path_to_nodes.xml")

settings = {"rtr_names":g.generate_node_names(),
            "num_layers":3,
            "fwd_engine_layer":2,
            "input_path":"tf_files",
            "switch_id_multiplier":cisco_router.SWITCH_ID_MULTIPLIER,
            "port_type_multiplier":cisco_router.PORT_TYPE_MULTIPLIER,
            "out_port_type_const":cisco_router.OUTPUT_PORT_TYPE_CONST,
            "remove_duplicates":True,
            }

(ntf,ttf,name_to_id,id_to_name) = load_network(settings)

# create all-x packet as input headerspace.
all_x = wildcard_create_bit_repeat(ntf.length,0x3)
# uncomment to set some field
#set_header_field(cisco_router.HS_FORMAT(), all_x, "field", value, right_mask)
#set_header_field(cisco_router.HS_FORMAT(), all_x, "vlan", 92, 0)
test_pkt = headerspace(ntf.length)
test_pkt.add_hs(all_x)

#set some input/output ports
output_port_addition = cisco_router.PORT_TYPE_MULTIPLIER * \
cisco_router.OUTPUT_PORT_TYPE_CONST
#TODO: CHANGE THIS IF YOU WANT TO RUN IT FROM/TO DIFFERENT PORTS
src_port_id = name_to_id["ROUTER NAME"]["PORT NAME"]
dst_port_ids = [name_to_id["ROUTER NAME"]["PORT NAME"]+output_port_addition]

#start reachability test and print results
st = time()
Exemplo n.º 27
0
    if (not line.startswith("$")) and line != "":
        tokens = line.strip().split(":")
        port = int(tokens[1]) + settings["port_type_multiplier"] * \
        settings["mid_port_type_const"]
        N.add_link(port,port)

# add link for forward engine port
for i in range(len(settings["rtr_names"])):
    fwd_link = (i+1) * settings["switch_id_multiplier"]
    N.add_link(fwd_link,fwd_link)

# add a source node at yoza-te1/4
src_port_id = map["yoza_rtr"]["te1/4"]
N.add_link(1,src_port_id)
hs = headerspace(N.length)
hs.add_hs(wildcard_create_bit_repeat(N.length,0x3))
N.add_source("yoza-source", hs, [1])

rule_ids = []
for rtr_name in settings["rtr_names"]:
    f = TF(1)
    f.load_object_from_file("%s/%s.tf"%(settings["input_path"],rtr_name))
    for rule in f.rules:
        in_ports = rule["in_ports"]
        out_ports = rule["out_ports"]
        match = rule["match"]
        mask = rule["mask"]
        rewrite = rule["rewrite"]
        st = time()
        rule_ids.append(\
                N.add_rule(rtr_name, -1, in_ports, out_ports, match, mask, rewrite)\
Exemplo n.º 28
0
    def generate_transfer_function(self, tf):
        '''
        After calling read_config_file(), read_spanning_tree_file() and read_route_file(),
        generate_port_ids(), and optionally optimize_forwarding_table(),
        this method may be called to generate transfer function rules corresponding to this box.
        The rules will be added to transfer function tf passed to the function.
        '''
        print "=== Generating Transfer Function ==="
        # generate the input part of tranfer function from in_port to fwd_port
        # and output part from intermedite ports to output ports
        print " * Generating ACL transfer function * "
        for acl in self.acl_iface.keys():
            if acl not in self.acl.keys():
                continue
            for acl_instance in self.acl_iface[acl]:
                file_name = acl_instance[3]
                specified_ports = []
                vlan = acl_instance[2]
                if acl_instance[0].startswith("vlan"):
                    for p in self.vlan_ports[acl_instance[0]]:
                        specified_ports.append(self.port_to_id[p])
                else:
                    specified_ports = [self.port_to_id(acl_instance[0])]
                for acl_dic_entry in self.acl[acl]:
                    matches = self.acl_dict_entry_to_wc(acl_dic_entry)
                    lines = acl_instance[4]
                    lines.extend(acl_dic_entry["line"])
                    # in acl entry
                    if acl_instance[1] == "in":
                        in_ports = specified_ports
                        out_ports = []
                        if (acl_dic_entry["action"]):
                            out_ports = [self.switch_id * self.SWITCH_ID_MULTIPLIER]
                        for match in matches:
                            self.set_field(match, "vlan", vlan, 0)
                            next_rule = TF.create_standard_rule(in_ports, match, out_ports, None, None, file_name, lines)
                            tf.add_fwd_rule(next_rule)
                    # out acl entry
                    else:
                        for match in matches:
                            self.set_field(match, "vlan", vlan, 0)
                            if (not acl_dic_entry["action"]):
                                out_ports = []
                                in_ports = []
                                for port in specified_ports:
                                    in_ports.append(port+self.PORT_TYPE_MULTIPLIER * self.INTERMEDIATE_PORT_TYPE_CONST)
                                next_rule = TF.create_standard_rule(in_ports, match, out_ports, None, None, file_name, lines)
                                tf.add_fwd_rule(next_rule)
                            else:
                                for port in specified_ports:
                                    in_ports = [port+self.PORT_TYPE_MULTIPLIER * self.INTERMEDIATE_PORT_TYPE_CONST]
                                    out_ports = [port+self.PORT_TYPE_MULTIPLIER * self.OUTPUT_PORT_TYPE_CONST]
                                    next_rule = TF.create_standard_rule(in_ports, match, out_ports, None, None, file_name, lines)
                                    tf.add_fwd_rule(next_rule)

        # default rule for all vlans configured on this switch and un-vlan-tagged ports
        intermediate_port = [self.switch_id * self.SWITCH_ID_MULTIPLIER]
        for cnf_vlan in self.config_vlans:
            if self.vlan_ports.has_key("vlan%d"%cnf_vlan):
                match = wildcard_create_bit_repeat(self.hs_format["length"],0x3)
                self.set_field(match, "vlan", cnf_vlan, 0)
                all_in_ports = []
                for port in self.vlan_ports["vlan%d"%cnf_vlan]:
                    all_in_ports.append(self.port_to_id[port])
                def_rule = TF.create_standard_rule(all_in_ports, match, intermediate_port, None, None, "", [])
                tf.add_fwd_rule(def_rule)
        # ... un-vlan-tagged port
        all_in_ports = []
        for port in self.port_to_id.keys():
            if port != "self":
                all_in_ports.append(self.port_to_id[port])
#        match = byte_array_get_all_x(self.hs_format["length"]*2)
#        self.set_field(match, "vlan", 0, 0)
#        def_rule = TF.create_standard_rule(all_in_ports, match, intermediate_port, None, None, "", [])
#        tf.add_fwd_rule(def_rule)

        # default rule from intermediate port to outut port
        match = wildcard_create_bit_repeat(self.hs_format["length"],0x3)
        for port_id in all_in_ports:
            before_out_port = [port_id+self.PORT_TYPE_MULTIPLIER * self.INTERMEDIATE_PORT_TYPE_CONST]
            after_out_port = [port_id+self.PORT_TYPE_MULTIPLIER * self.OUTPUT_PORT_TYPE_CONST]
            def_rule = TF.create_standard_rule(before_out_port, match, after_out_port , None, None, "", [])
            # James: No default output ACL
            #tf.add_fwd_rule(def_rule)

        ##################################
#        print " * Generating VLAN forwarding transfer function... * "
#        # generate VLAN forwarding entries
#        for vlan_num in self.port_subnets.keys():
#            #James: if VLAN has only one port, don't worry about forwarding!
#            vlan = int(vlan_num)
#            if "vlan%d"%vlan in self.vlan_ports.keys():
#                if(len(self.vlan_ports["vlan%d"%vlan]) == 1):
#                    #print "Found orphant VLAN %s on port %s" %(vlan_num, self.vlan_ports["vlan%d"%int(vlan_num)])
#                    continue
#            #end of James' magic :P
#            for (ip_addr,subnet_mask,file_name,lines,port) in self.port_subnets[vlan_num]:
#                match = byte_array_get_all_x(self.hs_format["length"]*2)
#                in_port = [self.switch_id * self.SWITCH_ID_MULTIPLIER]
#                vlan = int(vlan_num)
#                out_ports = []
#                if ip_addr == None:
#                    self.set_field(match, "vlan", vlan, 0)
#                else:
#                    self.set_field(match, "ip_dst", ip_addr, subnet_mask)
#                    self.set_field(match, "vlan", vlan, 0)
#                if not port.startswith("vlan"):
#                    out_ports.append(self.port_to_id[port]+self.PORT_TYPE_MULTIPLIER * self.INTERMEDIATE_PORT_TYPE_CONST)
#                elif "vlan%d"%vlan in self.vlan_ports.keys():
#                    port_list = self.vlan_ports["vlan%d"%vlan]
#                    for p in port_list:
#                        out_ports.append(self.port_to_id[p]+self.PORT_TYPE_MULTIPLIER * self.INTERMEDIATE_PORT_TYPE_CONST)
#                tf_rule = TF.create_standard_rule(in_port, match, out_ports, None, None,file_name,lines)
#                tf.add_fwd_rule(tf_rule)

        ###################################
        print " * Generating IP forwarding transfer function... * "
        self.fwd_table.sort(key=lambda fwd_rule: fwd_rule[1], reverse=True)

        # generate the forwarding part of transfer fucntion, from the fwd_prt, to pre-output ports
        for subnet in range(32,-1,-1):

            while [] in self.fwd_table:
                self.fwd_table.remove([])

            for fwd_rule in self.fwd_table:
                index = self.fwd_table.index(fwd_rule)

                if fwd_rule[1] != subnet:
                    break

                else:

                    #in -ports and match bytearray
                    match = wildcard_create_bit_repeat(self.hs_format["length"],0x3)
                    self.set_field(match, "ip_dst", int(fwd_rule[0]), 32-subnet)
                    in_port = [self.switch_id * self.SWITCH_ID_MULTIPLIER]
                    # mask, rewrite
                    mask = wildcard_create_bit_repeat(self.hs_format["length"],0x2)
                    rewrite = wildcard_create_bit_repeat(self.hs_format["length"],0x1)
                    # find out the file-line it represents:
                    lines = []
                    file_name = ""
                    if len(fwd_rule) == 4:
                        for c_rule in fwd_rule[3]:
                            file_name = c_rule[3]
                            lines.extend(c_rule[4])
                    else:
                        file_name = fwd_rule[3]
                        lines.extend(fwd_rule[4])
                    # set up out_ports
                    out_ports = []

                    # fwd_rule[2] is a list, thanks to LAG
                    for output_port in fwd_rule[2]:
                        vlan = 0
                        m = re.split('\.',output_port)
                        # drop rules:
                        if output_port == "self":
                            self_rule = TF.create_standard_rule(in_port,match,[],None,None,file_name,lines)
                            tf.add_fwd_rule(self_rule)
                        # non drop rules
                        else:
                            # sub-ports: port.vlan
                            if len(m) > 1:
                                if m[0] in self.port_to_id.keys():
                                    out_ports.append(self.port_to_id[m[0]]+self.PORT_TYPE_MULTIPLIER * self.OUTPUT_PORT_TYPE_CONST)
                                    vlan = int(m[1])
                                else:
                                    print "ERROR: unrecognized port %s"%m[0]
                                    return -1
                            # vlan outputs
                            elif output_port.startswith('vlan'):
                                if output_port in self.vlan_ports.keys():
                                    port_list = self.vlan_ports[output_port]
                                    for p in port_list:
                                        out_ports.append(self.port_to_id[p]+self.PORT_TYPE_MULTIPLIER * self.OUTPUT_PORT_TYPE_CONST)
                                    vlan = int(output_port[4:])
                                else:
                                    print "ERROR: unrecognized vlan %s"%output_port
                                    return -1
                            # physical ports - no vlan taging
                            else:
                                if output_port in self.port_to_id.keys():
                                    out_ports.append(self.port_to_id[output_port] + self.PORT_TYPE_MULTIPLIER * self.OUTPUT_PORT_TYPE_CONST)
                                    vlan = 0
                                else:
                                    print "ERROR: unrecognized port %s"%output_port
                                    return -1

                        # now set the fields
                        self.set_field(mask, 'vlan', 0, 0)
                        self.set_field(rewrite, 'vlan', vlan, 0)
                        tf_rule = TF.create_standard_rule(in_port, match, out_ports, mask, rewrite,file_name,lines)
                        tf.add_rewrite_rule(tf_rule)

                self.fwd_table[index] = []
                #Invalidate fwd_rule
        print "=== Successfully Generated Transfer function ==="
        #print tf
        return 0
Exemplo n.º 29
0
    if (not line.startswith("$")) and line != "":
        tokens = line.strip().split(":")
        port = int(tokens[1]) + settings["port_type_multiplier"] * \
        settings["mid_port_type_const"]
        N.add_link(port, port)

# add link for forward engine port
for i in range(len(settings["rtr_names"])):
    fwd_link = (i + 1) * settings["switch_id_multiplier"]
    N.add_link(fwd_link, fwd_link)

# add a source node at yoza-te1/4
src_port_id = map["yoza_rtr"]["te1/4"]
N.add_link(1, src_port_id)
hs = headerspace(N.length)
hs.add_hs(wildcard_create_bit_repeat(N.length, 0x3))
N.add_source("yoza-source", hs, [1])

rule_ids = []
for rtr_name in settings["rtr_names"]:
    f = TF(1)
    f.load_object_from_file("%s/%s.tf" % (settings["input_path"], rtr_name))
    for rule in f.rules:
        in_ports = rule["in_ports"]
        out_ports = rule["out_ports"]
        match = rule["match"]
        mask = rule["mask"]
        rewrite = rule["rewrite"]
        st = time()
        rule_ids.append(\
                N.add_rule(rtr_name, -1, in_ports, out_ports, match, mask, rewrite)\
Exemplo n.º 30
0
    def generate_transfer_function(self, tf):
        '''
        After calling read_config_file(), read_spanning_tree_file() and read_route_file(),
        generate_port_ids(), and optionally optimize_forwarding_table(),
        this method may be called to generate transfer function rules corresponding to this box.
        The rules will be added to transfer function tf passed to the function.
        '''
        print "=== Generating Transfer Function ==="
        # generate the input part of tranfer function from in_port to fwd_port
        # and output part from intermedite ports to output ports
        print " * Generating ACL transfer function * "
        for acl in self.acl_iface.keys():
            if acl not in self.acl.keys():
                continue
            for acl_instance in self.acl_iface[acl]:
                file_name = acl_instance[3]
                specified_ports = []
                vlan = acl_instance[2]
                if acl_instance[0].startswith("vlan"):
                    for p in self.vlan_ports[acl_instance[0]]:
                        specified_ports.append(self.port_to_id[p])
                else:
                    specified_ports = [self.port_to_id(acl_instance[0])]
                for acl_dic_entry in self.acl[acl]:
                    matches = self.acl_dict_entry_to_wc(acl_dic_entry)
                    lines = acl_instance[4]
                    lines.extend(acl_dic_entry["line"])
                    # in acl entry
                    if acl_instance[1] == "in":
                        in_ports = specified_ports
                        out_ports = []
                        if (acl_dic_entry["action"]):
                            out_ports = [
                                self.switch_id * self.SWITCH_ID_MULTIPLIER
                            ]
                        for match in matches:
                            self.set_field(match, "vlan", vlan, 0)
                            next_rule = TF.create_standard_rule(
                                in_ports, match, out_ports, None, None,
                                file_name, lines)
                            tf.add_fwd_rule(next_rule)
                    # out acl entry
                    else:
                        for match in matches:
                            self.set_field(match, "vlan", vlan, 0)
                            if (not acl_dic_entry["action"]):
                                out_ports = []
                                in_ports = []
                                for port in specified_ports:
                                    in_ports.append(
                                        port + self.PORT_TYPE_MULTIPLIER *
                                        self.INTERMEDIATE_PORT_TYPE_CONST)
                                next_rule = TF.create_standard_rule(
                                    in_ports, match, out_ports, None, None,
                                    file_name, lines)
                                tf.add_fwd_rule(next_rule)
                            else:
                                for port in specified_ports:
                                    in_ports = [
                                        port + self.PORT_TYPE_MULTIPLIER *
                                        self.INTERMEDIATE_PORT_TYPE_CONST
                                    ]
                                    out_ports = [
                                        port + self.PORT_TYPE_MULTIPLIER *
                                        self.OUTPUT_PORT_TYPE_CONST
                                    ]
                                    next_rule = TF.create_standard_rule(
                                        in_ports, match, out_ports, None, None,
                                        file_name, lines)
                                    tf.add_fwd_rule(next_rule)

        # default rule for all vlans configured on this switch and un-vlan-tagged ports
        intermediate_port = [self.switch_id * self.SWITCH_ID_MULTIPLIER]
        for cnf_vlan in self.config_vlans:
            if self.vlan_ports.has_key("vlan%d" % cnf_vlan):
                match = wildcard_create_bit_repeat(self.hs_format["length"],
                                                   0x3)
                self.set_field(match, "vlan", cnf_vlan, 0)
                all_in_ports = []
                for port in self.vlan_ports["vlan%d" % cnf_vlan]:
                    all_in_ports.append(self.port_to_id[port])
                def_rule = TF.create_standard_rule(all_in_ports, match,
                                                   intermediate_port, None,
                                                   None, "", [])
                tf.add_fwd_rule(def_rule)
        # ... un-vlan-tagged port
        all_in_ports = []
        for port in self.port_to_id.keys():
            if port != "self":
                all_in_ports.append(self.port_to_id[port])
#        match = byte_array_get_all_x(self.hs_format["length"]*2)
#        self.set_field(match, "vlan", 0, 0)
#        def_rule = TF.create_standard_rule(all_in_ports, match, intermediate_port, None, None, "", [])
#        tf.add_fwd_rule(def_rule)

# default rule from intermediate port to outut port
        match = wildcard_create_bit_repeat(self.hs_format["length"], 0x3)
        for port_id in all_in_ports:
            before_out_port = [
                port_id +
                self.PORT_TYPE_MULTIPLIER * self.INTERMEDIATE_PORT_TYPE_CONST
            ]
            after_out_port = [
                port_id +
                self.PORT_TYPE_MULTIPLIER * self.OUTPUT_PORT_TYPE_CONST
            ]
            def_rule = TF.create_standard_rule(before_out_port, match,
                                               after_out_port, None, None, "",
                                               [])
            # James: No default output ACL
            #tf.add_fwd_rule(def_rule)

        ##################################
#        print " * Generating VLAN forwarding transfer function... * "
#        # generate VLAN forwarding entries
#        for vlan_num in self.port_subnets.keys():
#            #James: if VLAN has only one port, don't worry about forwarding!
#            vlan = int(vlan_num)
#            if "vlan%d"%vlan in self.vlan_ports.keys():
#                if(len(self.vlan_ports["vlan%d"%vlan]) == 1):
#                    #print "Found orphant VLAN %s on port %s" %(vlan_num, self.vlan_ports["vlan%d"%int(vlan_num)])
#                    continue
#            #end of James' magic :P
#            for (ip_addr,subnet_mask,file_name,lines,port) in self.port_subnets[vlan_num]:
#                match = byte_array_get_all_x(self.hs_format["length"]*2)
#                in_port = [self.switch_id * self.SWITCH_ID_MULTIPLIER]
#                vlan = int(vlan_num)
#                out_ports = []
#                if ip_addr == None:
#                    self.set_field(match, "vlan", vlan, 0)
#                else:
#                    self.set_field(match, "ip_dst", ip_addr, subnet_mask)
#                    self.set_field(match, "vlan", vlan, 0)
#                if not port.startswith("vlan"):
#                    out_ports.append(self.port_to_id[port]+self.PORT_TYPE_MULTIPLIER * self.INTERMEDIATE_PORT_TYPE_CONST)
#                elif "vlan%d"%vlan in self.vlan_ports.keys():
#                    port_list = self.vlan_ports["vlan%d"%vlan]
#                    for p in port_list:
#                        out_ports.append(self.port_to_id[p]+self.PORT_TYPE_MULTIPLIER * self.INTERMEDIATE_PORT_TYPE_CONST)
#                tf_rule = TF.create_standard_rule(in_port, match, out_ports, None, None,file_name,lines)
#                tf.add_fwd_rule(tf_rule)

###################################
        print " * Generating IP forwarding transfer function... * "
        self.fwd_table.sort(key=lambda fwd_rule: fwd_rule[1], reverse=True)

        # generate the forwarding part of transfer fucntion, from the fwd_prt, to pre-output ports
        for subnet in range(32, -1, -1):

            while [] in self.fwd_table:
                self.fwd_table.remove([])

            for fwd_rule in self.fwd_table:
                index = self.fwd_table.index(fwd_rule)

                if fwd_rule[1] != subnet:
                    break

                else:

                    #in -ports and match bytearray
                    match = wildcard_create_bit_repeat(
                        self.hs_format["length"], 0x3)
                    self.set_field(match, "ip_dst", int(fwd_rule[0]),
                                   32 - subnet)
                    in_port = [self.switch_id * self.SWITCH_ID_MULTIPLIER]
                    # mask, rewrite
                    mask = wildcard_create_bit_repeat(self.hs_format["length"],
                                                      0x2)
                    rewrite = wildcard_create_bit_repeat(
                        self.hs_format["length"], 0x1)
                    # find out the file-line it represents:
                    lines = []
                    file_name = ""
                    if len(fwd_rule) == 4:
                        for c_rule in fwd_rule[3]:
                            file_name = c_rule[3]
                            lines.extend(c_rule[4])
                    else:
                        file_name = fwd_rule[3]
                        lines.extend(fwd_rule[4])
                    # set up out_ports
                    out_ports = []

                    # fwd_rule[2] is a list, thanks to LAG
                    for output_port in fwd_rule[2]:
                        vlan = 0
                        m = re.split('\.', output_port)
                        # drop rules:
                        if output_port == "self":
                            self_rule = TF.create_standard_rule(
                                in_port, match, [], None, None, file_name,
                                lines)
                            tf.add_fwd_rule(self_rule)
                        # non drop rules
                        else:
                            # sub-ports: port.vlan
                            if len(m) > 1:
                                if m[0] in self.port_to_id.keys():
                                    out_ports.append(
                                        self.port_to_id[m[0]] +
                                        self.PORT_TYPE_MULTIPLIER *
                                        self.OUTPUT_PORT_TYPE_CONST)
                                    vlan = int(m[1])
                                else:
                                    print "ERROR: unrecognized port %s" % m[0]
                                    return -1
                            # vlan outputs
                            elif output_port.startswith('vlan'):
                                if output_port in self.vlan_ports.keys():
                                    port_list = self.vlan_ports[output_port]
                                    for p in port_list:
                                        out_ports.append(
                                            self.port_to_id[p] +
                                            self.PORT_TYPE_MULTIPLIER *
                                            self.OUTPUT_PORT_TYPE_CONST)
                                    vlan = int(output_port[4:])
                                else:
                                    print "ERROR: unrecognized vlan %s" % output_port
                                    return -1
                            # physical ports - no vlan taging
                            else:
                                if output_port in self.port_to_id.keys():
                                    out_ports.append(
                                        self.port_to_id[output_port] +
                                        self.PORT_TYPE_MULTIPLIER *
                                        self.OUTPUT_PORT_TYPE_CONST)
                                    vlan = 0
                                else:
                                    print "ERROR: unrecognized port %s" % output_port
                                    return -1

                        # now set the fields
                        self.set_field(mask, 'vlan', 0, 0)
                        self.set_field(rewrite, 'vlan', vlan, 0)
                        tf_rule = TF.create_standard_rule(
                            in_port, match, out_ports, mask, rewrite,
                            file_name, lines)
                        tf.add_rewrite_rule(tf_rule)

                self.fwd_table[index] = []
                #Invalidate fwd_rule
        print "=== Successfully Generated Transfer function ==="
        #print tf
        return 0