Example #1
0
 def _sequence_actions(self, a1, as2):
     from pyretic.core.language import modify, drop, identity, Controller, CountBucket, DerivedPolicy
     while isinstance(a1, DerivedPolicy):
         a1 = a1.policy
     # TODO: be uniform about returning copied or modified objects.
     new_actions = []
     if a1 == drop:
         return [drop]
     elif a1 == identity:
         return as2
     elif a1 == Controller or isinstance(a1, CountBucket):
         return [a1]
     elif isinstance(a1, modify):
         for a2 in as2:
             while isinstance(a2, DerivedPolicy):
                 a2 = a2.policy
             new_a1 = modify(**a1.map.copy())
             if a2 == drop:
                 new_actions.append(drop)
             elif a2 == Controller or isinstance(a2, CountBucket):
                 new_actions.append(a2)
             elif a2 == identity:
                 new_actions.append(new_a1)
             elif isinstance(a2, modify):
                 new_a1.map.update(a2.map)
                 new_actions.append(new_a1)
             elif isinstance(a2, fwd):
                 new_a1.map['outport'] = a2.outport
                 new_actions.append(new_a1)
             else:
                 raise TypeError
         return new_actions
     else:
         raise TypeError
Example #2
0
 def _sequence_actions(a1, as2):
     while isinstance(a1, DerivedPolicy):
         a1 = a1.policy
     # TODO: be uniform about returning copied or modified objects.
     if a1 == Controller or isinstance(a1, CountBucket):
         return {a1}
     elif a1 == identity:
         return copy.copy(as2)
     elif isinstance(a1, modify):
         new_actions = set()
         for a2 in as2:
             while isinstance(a2, DerivedPolicy):
                 a2 = a2.policy
             if a2 == Controller or isinstance(a2, CountBucket): 
                 new_actions.add(a2)
             elif a2 == identity:
                 new_actions.add(a1)
             elif isinstance(a2, modify):
                 new_a1 = modify(**a1.map.copy())
                 new_a1.map.update(a2.map)
                 new_actions.add(new_a1)
             else:
                 raise TypeError
         return new_actions
     else:
         raise TypeError
Example #3
0
    def _sequence_actions(self, a1, as2):
        from pyretic.core.language import modify, drop, identity, Controller, CountBucket, DerivedPolicy

        while isinstance(a1, DerivedPolicy):
            a1 = a1.policy
        # TODO: be uniform about returning copied or modified objects.
        new_actions = []
        if a1 == drop:
            return [drop]
        elif a1 == identity:
            return as2
        elif a1 == Controller or isinstance(a1, CountBucket):
            return [a1]
        elif isinstance(a1, modify):
            for a2 in as2:
                while isinstance(a2, DerivedPolicy):
                    a2 = a2.policy
                new_a1 = modify(**a1.map.copy())
                if a2 == drop:
                    new_actions.append(drop)
                elif a2 == Controller or isinstance(a2, CountBucket):
                    new_actions.append(a2)
                elif a2 == identity:
                    new_actions.append(new_a1)
                elif isinstance(a2, modify):
                    new_a1.map.update(a2.map)
                    new_actions.append(new_a1)
                elif isinstance(a2, fwd):
                    new_a1.map["outport"] = a2.outport
                    new_actions.append(new_a1)
                else:
                    raise TypeError
            return new_actions
        else:
            raise TypeError
Example #4
0
def adjust_vlan_fields(mat, acts):
    """Since netKAT is lazy about adding modifications whenever there is a
    match on the same value, we add the matched value again whenever exactly one
    of the vlan ID or PCP fields is missing.

    Setting both ID and PCP is required by the pox_client to ensure simple and
    correct operation of the metadata register.
    """
    from pyretic.core.language import modify
    new_acts = []
    for act in acts:
        new_act = act
        if isinstance(act, modify):
            m = copy.copy(act.map)
            if 'vlan_id' in m and not 'vlan_pcp' in m:
                assert 'vlan_pcp' in mat.map
                m['vlan_pcp'] = mat.map['vlan_pcp']
                new_act = modify(**m)
            elif 'vlan_pcp' in m and not 'vlan_id' in m:
                assert 'vlan_id' in mat.map
                m['vlan_id'] = mat.map['vlan_id']
                new_act = modify(**m)
        new_acts.append(new_act)
    return set(new_acts)
Example #5
0
def adjust_vlan_fields(mat, acts):
    """Since netKAT is lazy about adding modifications whenever there is a
    match on the same value, we add the matched value again whenever exactly one
    of the vlan ID or PCP fields is missing.

    Setting both ID and PCP is required by the pox_client to ensure simple and
    correct operation of the metadata register.
    """
    from pyretic.core.language import modify
    new_acts = []
    for act in acts:
        new_act = act
        if isinstance(act, modify):
            m = copy.copy(act.map)
            if 'vlan_id' in m and not 'vlan_pcp' in m:
                assert 'vlan_pcp' in mat.map
                m['vlan_pcp'] = mat.map['vlan_pcp']
                new_act = modify(**m)
            elif 'vlan_pcp' in m and not 'vlan_id' in m:
                assert 'vlan_id' in mat.map
                m['vlan_id'] = mat.map['vlan_id']
                new_act = modify(**m)
        new_acts.append(new_act)
    return set(new_acts)
Example #6
0
def _sequence_actions(a1, as2):
    from pyretic.core.language import (match, modify, drop, identity,
                                       Controller, CountBucket,
                                       DerivedPolicy, PathBucket)
    from pyretic.lib.netflow import NetflowBucket
    while isinstance(a1, DerivedPolicy):
        a1 = a1.policy
    # TODO: be uniform about returning copied or modified objects.
    if (a1 == Controller or isinstance(a1, CountBucket) or 
        isinstance(a1, PathBucket) or isinstance(a1, NetflowBucket)):
        return {a1}
    elif a1 == identity:
        return copy.copy(as2)
    elif isinstance(a1, modify):
        new_actions = set()
        for a2 in as2:
            while isinstance(a2, DerivedPolicy):
                a2 = a2.policy
            if (a2 == Controller or isinstance(a2, CountBucket) or
                isinstance(a2, PathBucket) or isinstance(a2, NetflowBucket)):
                new_actions.add(a2)
            elif a2 == identity:
                new_actions.add(a1)
            elif isinstance(a2, modify):
                new_a1_map = a1.map.copy()
                new_a1_map.update(a2.map)
                new_actions.add(modify(**new_a1_map))
                # TODO(ngsrinivas): remove later if no issues
                # new_a1 = modify(**a1.map.copy())
                # new_a1.map.update(a2.map)
                # new_actions.add(new_a1)
            else:
                raise TypeError
        return new_actions
    else:
        raise TypeError
Example #7
0
def create_action(action, multistage):
    from pyretic.core.language import (modify, Controller, identity)
    if len(action) == 0:
        return set()
    else:
        res = set()

        for act_list in action:
            mod_dict = {}
            for act in act_list:
                if act[0] == "Modify":
                    hdr_field = act[1][0][3:]
                    if hdr_field == "Vlan" or hdr_field == "VlanPcp":
                        hdr_field = 'dl' + hdr_field
                    else:
                        hdr_field = hdr_field[0].lower() + hdr_field[1:]
                    hdr_field = field_map[hdr_field]
                    value = act[1][1]
                    if hdr_field == 'srcmac' or hdr_field == 'dstmac':
                        value = MAC(value)
                    mod_dict[hdr_field] = value
                elif act[0] == "Output":
                    outout_seen = True
                    out_info = act[1]
                    if out_info['type'] == 'physical':
                        mod_dict['port'] = out_info['port']
                    elif out_info['type'] == 'controller':
                        res.add(Controller)
                    elif out_info['type'] == 'inport' and not multistage:
                        mod_dict['port'] = OFPP_IN_PORT
            
            if len(mod_dict) > 0:
                res.add(modify(**mod_dict))
        if len(res) == 0:
            res.add(identity)
    return res
Example #8
0
def create_action(action, multistage, vlan_offset_nbits):
    """ Return value: (action list, suspicious_vlan_bool) """
    from pyretic.core.language import (modify, Controller, identity)
    if len(action) == 0:
        return (set(), False)
    else:
        res = set()
        suspicious_vlan = False

        for act_list in action:
            mod_dict = {}
            vlan_processed = False
            vlans_processed = False
            for act in act_list:
                if act[0] == "Modify":
                    hdr_field = act[1][0][3:]
                    if hdr_field == "Vlan" or hdr_field == "VlanPcp":
                        hdr_field = 'dl' + hdr_field
                    else:
                        hdr_field = hdr_field[0].lower() + hdr_field[1:]
                    hdr_field = field_map[hdr_field]
                    value = act[1][1]
                    if hdr_field == 'srcmac' or hdr_field == 'dstmac':
                        value = MAC(value)
                        mod_dict[hdr_field] = value
                    elif hdr_field == 'vlan_id' or hdr_field == 'vlan_pcp':
                        mod_dict[hdr_field] = value
                        if vlan_processed:
                            """ Only write both values to None if *both* vlan id and
                            pcp fields contain respective None values. """
                            if (mod_dict['vlan_pcp'] == VLAN_PCP_NONE_VALUE and
                                    mod_dict['vlan_id'] == VLAN_NONE_VALUE):
                                mod_dict['vlan_pcp'] = None
                                mod_dict['vlan_id'] = None
                            vlans_processed = True
                        vlan_processed = True
                    else:
                        mod_dict[hdr_field] = value
                    # Add auxiliary information for VLAN modifications
                    if hdr_field == 'vlan_id' or hdr_field == 'vlan_pcp':
                        mod_dict['vlan_offset'] = vlan_offset_nbits[
                            'vlan_offset']
                        mod_dict['vlan_nbits'] = vlan_offset_nbits[
                            'vlan_nbits']
                        mod_dict['vlan_total_stages'] = vlan_offset_nbits[
                            'vlan_total_stages']
                elif act[0] == "Output":
                    outout_seen = True
                    out_info = act[1]
                    if out_info['type'] == 'physical':
                        mod_dict['port'] = out_info['port']
                    elif out_info['type'] == 'controller':
                        res.add(Controller)
                    elif out_info['type'] == 'inport' and not multistage:
                        mod_dict['port'] = OFPP_IN_PORT

            if len(mod_dict) > 0:
                if (((not 'vlan_id' in mod_dict) and 'vlan_pcp' in mod_dict) or
                    ((not 'vlan_pcp' in mod_dict) and 'vlan_id' in mod_dict)):
                    suspicious_vlan = True
                res.add(modify(**mod_dict))
        if len(res) == 0:
            res.add(identity)
    return (res, suspicious_vlan)
Example #9
0
def create_action(action, multistage, vlan_offset_nbits):
    """ Return value: (action list, suspicious_vlan_bool) """
    from pyretic.core.language import (modify, Controller, identity)
    if len(action) == 0:
        return (set(), False)
    else:
        res = set()
        suspicious_vlan = False

        for act_list in action:
            mod_dict = {}
            vlan_processed = False
            vlans_processed = False
            for act in act_list:
                if act[0] == "Modify":
                    hdr_field = act[1][0][3:]
                    if hdr_field == "Vlan" or hdr_field == "VlanPcp":
                        hdr_field = 'dl' + hdr_field
                    else:
                        hdr_field = hdr_field[0].lower() + hdr_field[1:]
                    hdr_field = field_map[hdr_field]
                    value = act[1][1]
                    if hdr_field == 'srcmac' or hdr_field == 'dstmac':
                        value = MAC(value)
                        mod_dict[hdr_field] = value
                    elif hdr_field == 'vlan_id' or hdr_field == 'vlan_pcp':
                        mod_dict[hdr_field] = value
                        if vlan_processed:
                            """ Only write both values to None if *both* vlan id and
                            pcp fields contain respective None values. """
                            if (mod_dict['vlan_pcp'] == VLAN_PCP_NONE_VALUE and
                                mod_dict['vlan_id'] == VLAN_NONE_VALUE):
                                mod_dict['vlan_pcp'] = None
                                mod_dict['vlan_id'] = None
                            vlans_processed = True
                        vlan_processed = True
                    else:
                        mod_dict[hdr_field] = value
                    # Add auxiliary information for VLAN modifications
                    if hdr_field == 'vlan_id' or hdr_field == 'vlan_pcp':
                        mod_dict['vlan_offset'] = vlan_offset_nbits['vlan_offset']
                        mod_dict['vlan_nbits'] = vlan_offset_nbits['vlan_nbits']
                        mod_dict['vlan_total_stages'] = vlan_offset_nbits['vlan_total_stages']
                elif act[0] == "Output":
                    outout_seen = True
                    out_info = act[1]
                    if out_info['type'] == 'physical':
                        mod_dict['port'] = out_info['port']
                    elif out_info['type'] == 'controller':
                        res.add(Controller)
                    elif out_info['type'] == 'inport' and not multistage:
                        mod_dict['port'] = OFPP_IN_PORT
            
            if len(mod_dict) > 0:
                if (((not 'vlan_id' in mod_dict) and 'vlan_pcp' in mod_dict) or
                    ((not 'vlan_pcp' in mod_dict) and 'vlan_id' in mod_dict)):
                    suspicious_vlan = True
                res.add(modify(**mod_dict))
        if len(res) == 0:
            res.add(identity)
    return (res, suspicious_vlan)